diff --git a/.changeset/dull-taxis-carry.md b/.changeset/dull-taxis-carry.md new file mode 100644 index 0000000000..1466f1246a --- /dev/null +++ b/.changeset/dull-taxis-carry.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-adr': minor +'@backstage/plugin-adr-backend': patch +--- + +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. diff --git a/.changeset/eighty-forks-pull.md b/.changeset/eighty-forks-pull.md new file mode 100644 index 0000000000..f5bf555317 --- /dev/null +++ b/.changeset/eighty-forks-pull.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-git-release-manager': patch +--- + +add exports to clear api-report messages diff --git a/.changeset/fair-ants-work.md b/.changeset/fair-ants-work.md new file mode 100644 index 0000000000..4cf3c80488 --- /dev/null +++ b/.changeset/fair-ants-work.md @@ -0,0 +1,7 @@ +--- +'@backstage/backend-app-api': minor +--- + +**BREAKING**: The `httpRouterFactory` now accepts a `getPath` option rather than `indexPlugin`. To set up custom index path, configure the new `rootHttpRouterFactory` with a custom `indexPath` instead. + +Added an implementation for the new `rootHttpRouterServiceRef`. diff --git a/.changeset/fair-falcons-lie.md b/.changeset/fair-falcons-lie.md new file mode 100644 index 0000000000..ba39d51241 --- /dev/null +++ b/.changeset/fair-falcons-lie.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Render the scaffolder action description using the `MarkdownContent` component. This will allow the page to show richer content to describe scaffolder actions. diff --git a/.changeset/few-mice-study.md b/.changeset/few-mice-study.md new file mode 100644 index 0000000000..57a89cc547 --- /dev/null +++ b/.changeset/few-mice-study.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +Added `loggerToWinstonLogger`, which was moved from `@backstage/backend-plugin-api`. diff --git a/.changeset/few-penguins-admire.md b/.changeset/few-penguins-admire.md new file mode 100644 index 0000000000..170b4aa606 --- /dev/null +++ b/.changeset/few-penguins-admire.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder-backend-module-rails': patch +'@backstage/plugin-scaffolder-backend': patch +--- + +Change scaffolder task actions to include markdown to demonstrate the new `ActionsPage` markdown feature. diff --git a/.changeset/forty-mangos-fail.md b/.changeset/forty-mangos-fail.md new file mode 100644 index 0000000000..d86d9c0e56 --- /dev/null +++ b/.changeset/forty-mangos-fail.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Slightly improve readability of "base URL conflict" error handling code diff --git a/.changeset/gorgeous-days-applaud.md b/.changeset/gorgeous-days-applaud.md new file mode 100644 index 0000000000..a34307d720 --- /dev/null +++ b/.changeset/gorgeous-days-applaud.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-plugin-api': patch +--- + +Added a new `rootHttpRouterServiceRef` and `RootHttpRouterService` interface. diff --git a/.changeset/little-beans-hammer.md b/.changeset/little-beans-hammer.md new file mode 100644 index 0000000000..d998f5f5ba --- /dev/null +++ b/.changeset/little-beans-hammer.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-test-utils': patch +--- + +The `startTestBackend` setup now includes default implementations for all core services. diff --git a/.changeset/long-owls-raise.md b/.changeset/long-owls-raise.md new file mode 100644 index 0000000000..9021e4031a --- /dev/null +++ b/.changeset/long-owls-raise.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-adr-backend': patch +'@backstage/plugin-adr': patch +--- + +Clarify that default ADR parsers support MADR specification v2.x diff --git a/.changeset/loud-beds-occur.md b/.changeset/loud-beds-occur.md new file mode 100644 index 0000000000..546805e592 --- /dev/null +++ b/.changeset/loud-beds-occur.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-user-settings': patch +--- + +Refactor for the feature flag filter functionality diff --git a/.changeset/mean-moles-relate.md b/.changeset/mean-moles-relate.md new file mode 100644 index 0000000000..1b3d01dd96 --- /dev/null +++ b/.changeset/mean-moles-relate.md @@ -0,0 +1,31 @@ +--- +'@backstage/plugin-search-react': minor +--- + +Allow customizing empty state component through `noResultsComponent` property. + +Example: + +```jsx +No results were found}> + {({ results }) => ( + + {results.map(({ type, document }) => { + switch (type) { + case 'custom-result-item': + return ( + + ); + default: + return ( + + ); + } + })} + + )} + +``` diff --git a/.changeset/nasty-pumas-kneel.md b/.changeset/nasty-pumas-kneel.md new file mode 100644 index 0000000000..cdfda89868 --- /dev/null +++ b/.changeset/nasty-pumas-kneel.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-plugin-api': patch +'@backstage/backend-common': patch +--- + +Migrated types related to `TokenManagerService`, `CacheService` and `DatabaseService` into backend-plugin-api. diff --git a/.changeset/ninety-bags-turn.md b/.changeset/ninety-bags-turn.md new file mode 100644 index 0000000000..27b9a94ad2 --- /dev/null +++ b/.changeset/ninety-bags-turn.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-lighthouse': patch +--- + +Fixed bug in Lighthouse Plugin where audit list item and create audit button navigated to a wrong URL. diff --git a/.changeset/poor-crews-battle.md b/.changeset/poor-crews-battle.md new file mode 100644 index 0000000000..e05391ef5e --- /dev/null +++ b/.changeset/poor-crews-battle.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-plugin-api': minor +--- + +Moved `loggerToWinstonLogger` to `@backstage/backend-common`. diff --git a/.changeset/popular-boxes-think.md b/.changeset/popular-boxes-think.md new file mode 100644 index 0000000000..91ac649643 --- /dev/null +++ b/.changeset/popular-boxes-think.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Removed unused package `type-fest` diff --git a/.changeset/popular-cameras-worry.md b/.changeset/popular-cameras-worry.md new file mode 100644 index 0000000000..a5cbd6562b --- /dev/null +++ b/.changeset/popular-cameras-worry.md @@ -0,0 +1,6 @@ +--- +'@backstage/catalog-client': patch +'@backstage/plugin-catalog-backend': patch +--- + +Enable the `by-refs` endpoint to receive `fields` through the POST body as well as through query parameters. diff --git a/.changeset/red-tables-train.md b/.changeset/red-tables-train.md new file mode 100644 index 0000000000..031d3720fc --- /dev/null +++ b/.changeset/red-tables-train.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Add a reusable pop over `EntityPeekAheadPopover` component. It shows more details about the associated entity. See the playbook here https://backstage.io/storybook/?path=/story/catalog-entitypeekaheadpopover--default diff --git a/.changeset/renovate-0783312.md b/.changeset/renovate-0783312.md new file mode 100644 index 0000000000..ef3a1c0bfa --- /dev/null +++ b/.changeset/renovate-0783312.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Updated dependency `use-immer` to `^0.8.0`. diff --git a/.changeset/renovate-492e599.md b/.changeset/renovate-492e599.md new file mode 100644 index 0000000000..7c98b20f8d --- /dev/null +++ b/.changeset/renovate-492e599.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-bitbucket-cloud-common': patch +--- + +Updated dependency `ts-morph` to `^17.0.0`. diff --git a/.changeset/renovate-a3feeae.md b/.changeset/renovate-a3feeae.md new file mode 100644 index 0000000000..c5aa58d5f2 --- /dev/null +++ b/.changeset/renovate-a3feeae.md @@ -0,0 +1,7 @@ +--- +'@backstage/backend-common': patch +'@backstage/backend-test-utils': patch +'@backstage/plugin-catalog-backend': patch +--- + +Updated dependency `better-sqlite3` to `^8.0.0`. diff --git a/.changeset/renovate-e7f8e3a.md b/.changeset/renovate-e7f8e3a.md new file mode 100644 index 0000000000..6947a05d2d --- /dev/null +++ b/.changeset/renovate-e7f8e3a.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-permission-react': patch +'@backstage/plugin-playlist': patch +--- + +Updated dependency `swr` to `^2.0.0`. diff --git a/.changeset/sharp-icons-obey.md b/.changeset/sharp-icons-obey.md new file mode 100644 index 0000000000..2620dd9a07 --- /dev/null +++ b/.changeset/sharp-icons-obey.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-techdocs-react': patch +'@backstage/plugin-scaffolder': patch +--- + +Explicitly declaring children as optional props to facilitate react 18 changes diff --git a/.changeset/spotty-numbers-dream.md b/.changeset/spotty-numbers-dream.md new file mode 100644 index 0000000000..a40aa1e781 --- /dev/null +++ b/.changeset/spotty-numbers-dream.md @@ -0,0 +1,5 @@ +--- +'@backstage/repo-tools': patch +--- + +Updates Api-extractor and api-documenter version diff --git a/.changeset/ten-peas-grab.md b/.changeset/ten-peas-grab.md new file mode 100644 index 0000000000..c3022bb627 --- /dev/null +++ b/.changeset/ten-peas-grab.md @@ -0,0 +1,19 @@ +--- +'@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-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-catalog-backend-module-aws': patch +'@backstage/plugin-scaffolder-backend': patch +'@backstage/backend-app-api': patch +'@backstage/plugin-catalog-backend': patch +'@backstage/plugin-events-backend': patch +'@backstage/plugin-app-backend': patch +--- + +Switched imports of `loggerToWinstonLogger` to `@backstage/backend-common`. diff --git a/.changeset/tiny-cooks-hide.md b/.changeset/tiny-cooks-hide.md new file mode 100644 index 0000000000..feab4b65d2 --- /dev/null +++ b/.changeset/tiny-cooks-hide.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +The new root HTTP router service is now installed by default. diff --git a/.github/uffizzi/uffizzi.production.app-config.yaml b/.github/uffizzi/uffizzi.production.app-config.yaml index 56055c8342..2e45740875 100644 --- a/.github/uffizzi/uffizzi.production.app-config.yaml +++ b/.github/uffizzi/uffizzi.production.app-config.yaml @@ -36,6 +36,16 @@ catalog: - type: url target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/all.yaml + - type: url + target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/acme-corp.yaml + rules: + - allow: [User, Group] + + - type: url + target: https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend/sample-templates/all-templates.yaml + rules: + - allow: [Template] + proxy: '/circleci/api': target: https://circleci.com/api/v1.1 diff --git a/.github/vale/config.ini b/.github/vale/config.ini deleted file mode 100644 index 36acb2c058..0000000000 --- a/.github/vale/config.ini +++ /dev/null @@ -1,6 +0,0 @@ -StylesPath = . -Vocab = Backstage - -[*.md] -BasedOnStyles = Vale -Vale.Terms = NO diff --git a/.github/workflows/automate_stale.yml b/.github/workflows/automate_stale.yml index 1d8aa525a9..452ecc48d6 100644 --- a/.github/workflows/automate_stale.yml +++ b/.github/workflows/automate_stale.yml @@ -8,7 +8,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v6 + - uses: actions/stale@v7 id: stale with: stale-issue-message: > diff --git a/.github/workflows/uffizzi-build.yml b/.github/workflows/uffizzi-build.yml index 1a86f8de71..00b7d6d38d 100644 --- a/.github/workflows/uffizzi-build.yml +++ b/.github/workflows/uffizzi-build.yml @@ -52,7 +52,7 @@ jobs: - name: Docker metadata id: meta - uses: docker/metadata-action@v3 + uses: docker/metadata-action@v4 with: images: registry.uffizzi.com/${{ env.UUID_TAG_APP }} tags: type=raw,value=60d diff --git a/.vale.ini b/.vale.ini index fd1ea53b0d..fa7864a878 100644 --- a/.vale.ini +++ b/.vale.ini @@ -1,4 +1,7 @@ -StylesPath = .github/styles +StylesPath = .github/vale + +Vocab = Backstage [*.md] BasedOnStyles = Vale +Vale.Terms = NO diff --git a/docs/features/software-catalog/api.md b/docs/features/software-catalog/api.md index afd9a0af93..3ca7e5ef49 100644 --- a/docs/features/software-catalog/api.md +++ b/docs/features/software-catalog/api.md @@ -246,6 +246,37 @@ value. These are special in that they form the entity's unique The return type is JSON, as a single [`Entity`](descriptor-format.md), or a 404 error if there was no entity with that reference triplet. +### `POST /entities/by-refs` + +Gets a batch of entities by their entity refs. This is useful in contexts where +you want to fetch a large number of specific entities efficiently, for example +in GraphQL resolvers. + +The request body is JSON, on the form + +```json +{ + "entityRefs": ["component:default/foo", "api:default/bar"], + "fields": ["kind", "metadata.name"] +} +``` + +where each `entityRefs` entry is an entity ref that you want to fetch. The +`fields` array is optional and works the same way as the `GET /entities` fields +above, e.g. it's used to fetch only certain slices of each entity. + +The return type is JSON, on the form + +```json +{ + "items": [{ "kind": "Component", "metadata": { "name": "foo" } }, null] +} +``` + +where the `items` array has _the same length_ and _the same order_ as the input +`entityRefs` array. Each element contains the corresponding entity data, or +`null` if no entity existed in the catalog with that ref. + ## Locations TODO diff --git a/docs/getting-started/keeping-backstage-updated.md b/docs/getting-started/keeping-backstage-updated.md index 8e130e7094..e7324f4603 100644 --- a/docs/getting-started/keeping-backstage-updated.md +++ b/docs/getting-started/keeping-backstage-updated.md @@ -47,7 +47,7 @@ For this reason, any changes made to the template are documented along with upgrade instructions in the [changelog](https://github.com/backstage/backstage/blob/master/packages/create-app/CHANGELOG.md) of the `@backstage/create-app` package. We recommend peeking at this changelog --for any applicable updates when upgrading packages. As an alternative, the +for any applicable updates when upgrading packages. As an alternative, the [Backstage Upgrade Helper](https://backstage.github.io/upgrade-helper/) provides a consolidated view of all the changes between two versions of Backstage. You can find the current version of your Backstage installation in `backstage.json`. diff --git a/microsite/yarn.lock b/microsite/yarn.lock index e86a400340..3bc81619e3 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -5506,13 +5506,13 @@ __metadata: linkType: hard "json5@npm:^1.0.1": - version: 1.0.1 - resolution: "json5@npm:1.0.1" + version: 1.0.2 + resolution: "json5@npm:1.0.2" dependencies: minimist: ^1.2.0 bin: json5: lib/cli.js - checksum: e76ea23dbb8fc1348c143da628134a98adf4c5a4e8ea2adaa74a80c455fc2cdf0e2e13e6398ef819bfe92306b610ebb2002668ed9fc1af386d593691ef346fc3 + checksum: 866458a8c58a95a49bef3adba929c625e82532bcff1fe93f01d29cb02cac7c3fe1f4b79951b7792c2da9de0b32871a8401a6e3c5b36778ad852bf5b8a61165d7 languageName: node linkType: hard diff --git a/package.json b/package.json index f87d4ae1f4..4f89135a26 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)'", + "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-docs": "LANG=en_EN yarn build:api-reports --docs", "tsc": "tsc", "tsc:full": "backstage-cli repo clean && tsc --skipLibCheck false --incremental false", diff --git a/packages/backend-app-api/api-report.md b/packages/backend-app-api/api-report.md index fa3f3bec2e..1ff40c8b5d 100644 --- a/packages/backend-app-api/api-report.md +++ b/packages/backend-app-api/api-report.md @@ -4,15 +4,17 @@ ```ts import { BackendFeature } from '@backstage/backend-plugin-api'; -import { CacheService } from '@backstage/backend-plugin-api'; import { ConfigService } from '@backstage/backend-plugin-api'; -import { DatabaseService } from '@backstage/backend-plugin-api'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; +import { Handler } from 'express'; import { HttpRouterService } from '@backstage/backend-plugin-api'; import { LifecycleService } from '@backstage/backend-plugin-api'; import { LoggerService } from '@backstage/backend-plugin-api'; import { PermissionsService } from '@backstage/backend-plugin-api'; +import { PluginCacheManager } from '@backstage/backend-common'; +import { PluginDatabaseManager } from '@backstage/backend-common'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; +import { RootHttpRouterService } from '@backstage/backend-plugin-api'; import { RootLifecycleService } from '@backstage/backend-plugin-api'; import { RootLoggerService } from '@backstage/backend-plugin-api'; import { SchedulerService } from '@backstage/backend-plugin-api'; @@ -34,7 +36,7 @@ export interface Backend { // @public (undocumented) export const cacheFactory: ( options?: undefined, -) => ServiceFactory; +) => ServiceFactory; // @public (undocumented) export const configFactory: ( @@ -55,7 +57,7 @@ export interface CreateSpecializedBackendOptions { // @public (undocumented) export const databaseFactory: ( options?: undefined, -) => ServiceFactory; +) => ServiceFactory; // @public (undocumented) export const discoveryFactory: ( @@ -69,7 +71,7 @@ export const httpRouterFactory: ( // @public (undocumented) export type HttpRouterFactoryOptions = { - indexPlugin?: string; + getPath(pluginId: string): string; }; // @public @@ -87,6 +89,17 @@ export const permissionsFactory: ( options?: undefined, ) => ServiceFactory; +// @public (undocumented) +export const rootHttpRouterFactory: ( + options?: RootHttpRouterFactoryOptions | undefined, +) => ServiceFactory; + +// @public (undocumented) +export type RootHttpRouterFactoryOptions = { + indexPath?: string | false; + middleware?: Handler[]; +}; + // @public export const rootLifecycleFactory: ( options?: undefined, diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index 93230341df..80598ec93d 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -38,6 +38,7 @@ "@backstage/backend-tasks": "workspace:^", "@backstage/errors": "workspace:^", "@backstage/plugin-permission-node": "workspace:^", + "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", "winston": "^3.2.1" diff --git a/packages/backend-app-api/src/services/implementations/configService.ts b/packages/backend-app-api/src/services/implementations/configService.ts index f58a756c64..6bb84aa5a1 100644 --- a/packages/backend-app-api/src/services/implementations/configService.ts +++ b/packages/backend-app-api/src/services/implementations/configService.ts @@ -14,11 +14,13 @@ * limitations under the License. */ -import { loadBackendConfig } from '@backstage/backend-common'; +import { + loadBackendConfig, + loggerToWinstonLogger, +} from '@backstage/backend-common'; import { coreServices, createServiceFactory, - loggerToWinstonLogger, } from '@backstage/backend-plugin-api'; /** @public */ diff --git a/packages/backend-app-api/src/services/implementations/httpRouterService.test.ts b/packages/backend-app-api/src/services/implementations/httpRouterService.test.ts new file mode 100644 index 0000000000..89f6db2ac8 --- /dev/null +++ b/packages/backend-app-api/src/services/implementations/httpRouterService.test.ts @@ -0,0 +1,70 @@ +/* + * 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 { + HttpRouterService, + ServiceFactory, +} from '@backstage/backend-plugin-api'; +import { httpRouterFactory } from './httpRouterService'; + +describe('httpRouterFactory', () => { + it('should register plugin paths', async () => { + const rootHttpRouter = { use: jest.fn() }; + const factory = httpRouterFactory() as Exclude< + ServiceFactory, + { scope: 'root' } + >; + const innerFactory = await factory.factory({ rootHttpRouter }); + + const handler1 = () => {}; + const router1 = await innerFactory({ plugin: { getId: () => 'test1' } }); + router1.use(handler1); + expect(rootHttpRouter.use).toHaveBeenCalledTimes(1); + expect(rootHttpRouter.use).toHaveBeenCalledWith('/api/test1', handler1); + + const handler2 = () => {}; + const router2 = await innerFactory({ plugin: { getId: () => 'test2' } }); + router2.use(handler2); + expect(rootHttpRouter.use).toHaveBeenCalledTimes(2); + expect(rootHttpRouter.use).toHaveBeenCalledWith('/api/test2', handler2); + }); + + it('should use custom path generator', async () => { + const rootHttpRouter = { use: jest.fn() }; + const factory = httpRouterFactory({ + getPath: id => `/some/${id}/path`, + }) as Exclude, { scope: 'root' }>; + const innerFactory = await factory.factory({ rootHttpRouter }); + + const handler1 = () => {}; + const router1 = await innerFactory({ plugin: { getId: () => 'test1' } }); + router1.use(handler1); + expect(rootHttpRouter.use).toHaveBeenCalledTimes(1); + expect(rootHttpRouter.use).toHaveBeenCalledWith( + '/some/test1/path', + handler1, + ); + + const handler2 = () => {}; + const router2 = await innerFactory({ plugin: { getId: () => 'test2' } }); + router2.use(handler2); + expect(rootHttpRouter.use).toHaveBeenCalledTimes(2); + expect(rootHttpRouter.use).toHaveBeenCalledWith( + '/some/test2/path', + handler2, + ); + }); +}); diff --git a/packages/backend-app-api/src/services/implementations/httpRouterService.ts b/packages/backend-app-api/src/services/implementations/httpRouterService.ts index 2021589a50..f1fc089ea3 100644 --- a/packages/backend-app-api/src/services/implementations/httpRouterService.ts +++ b/packages/backend-app-api/src/services/implementations/httpRouterService.ts @@ -18,49 +18,33 @@ import { createServiceFactory, coreServices, } from '@backstage/backend-plugin-api'; -import Router from 'express-promise-router'; import { Handler } from 'express'; -import { createServiceBuilder } from '@backstage/backend-common'; /** * @public */ export type HttpRouterFactoryOptions = { /** - * The plugin ID used for the index route. Defaults to 'app' + * A callback used to generate the path for each plugin, defaults to `/api/{pluginId}`. */ - indexPlugin?: string; + getPath(pluginId: string): string; }; /** @public */ export const httpRouterFactory = createServiceFactory({ service: coreServices.httpRouter, deps: { - config: coreServices.config, plugin: coreServices.pluginMetadata, + rootHttpRouter: coreServices.rootHttpRouter, }, - async factory({ config }, options?: HttpRouterFactoryOptions) { - const defaultPluginId = options?.indexPlugin ?? 'app'; - - const apiRouter = Router(); - const rootRouter = Router(); - - const service = createServiceBuilder(module) - .loadConfig(config) - .addRouter('/api', apiRouter) - .addRouter('', rootRouter); - - await service.start(); + async factory({ rootHttpRouter }, options?: HttpRouterFactoryOptions) { + const getPath = options?.getPath ?? (id => `/api/${id}`); return async ({ plugin }) => { - const pluginId = plugin.getId(); + const path = getPath(plugin.getId()); return { use(handler: Handler) { - if (pluginId === defaultPluginId) { - rootRouter.use(handler); - } else { - apiRouter.use(`/${pluginId}`, handler); - } + rootHttpRouter.use(path, handler); }, }; }; diff --git a/packages/backend-app-api/src/services/implementations/index.ts b/packages/backend-app-api/src/services/implementations/index.ts index c87011d570..2365ff36f4 100644 --- a/packages/backend-app-api/src/services/implementations/index.ts +++ b/packages/backend-app-api/src/services/implementations/index.ts @@ -25,6 +25,8 @@ export { schedulerFactory } from './schedulerService'; export { tokenManagerFactory } from './tokenManagerService'; export { urlReaderFactory } from './urlReaderService'; export { httpRouterFactory } from './httpRouterService'; +export { rootHttpRouterFactory } from './rootHttpRouterService'; export { lifecycleFactory } from './lifecycleService'; export { rootLifecycleFactory } from './rootLifecycleService'; export type { HttpRouterFactoryOptions } from './httpRouterService'; +export type { RootHttpRouterFactoryOptions } from './rootHttpRouterService'; diff --git a/packages/backend-app-api/src/services/implementations/rootHttpRouterService.test.ts b/packages/backend-app-api/src/services/implementations/rootHttpRouterService.test.ts new file mode 100644 index 0000000000..fea99b0df9 --- /dev/null +++ b/packages/backend-app-api/src/services/implementations/rootHttpRouterService.test.ts @@ -0,0 +1,31 @@ +/* + * 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 { findConflictingPath } from './rootHttpRouterService'; + +describe('findConflictingPath', () => { + it('finds conflicts when present', () => { + expect(findConflictingPath(['/a'], '/a')).toBe('/a'); + expect(findConflictingPath(['/b'], '/a')).toBe(undefined); + expect(findConflictingPath(['/a'], '/a/b')).toBe('/a'); + expect(findConflictingPath(['/a'], '/aa/b')).toBe(undefined); + expect(findConflictingPath(['/aa'], '/a/b')).toBe(undefined); + expect(findConflictingPath(['/a/b'], '/a')).toBe('/a/b'); + expect(findConflictingPath(['/a/b'], '/aa')).toBe(undefined); + expect(findConflictingPath(['/b/a'], '/a')).toBe(undefined); + expect(findConflictingPath(['/a'], '/aa')).toBe(undefined); + }); +}); diff --git a/packages/backend-app-api/src/services/implementations/rootHttpRouterService.ts b/packages/backend-app-api/src/services/implementations/rootHttpRouterService.ts new file mode 100644 index 0000000000..dae7474793 --- /dev/null +++ b/packages/backend-app-api/src/services/implementations/rootHttpRouterService.ts @@ -0,0 +1,125 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createServiceFactory, + coreServices, +} from '@backstage/backend-plugin-api'; +import Router from 'express-promise-router'; +import { Handler } from 'express'; +import { createServiceBuilder } from '@backstage/backend-common'; + +/** + * @public + */ +export type RootHttpRouterFactoryOptions = { + /** + * The path to forward all unmatched requests to. Defaults to '/api/app' + */ + indexPath?: string | false; + + /** + * Middlewares that are added before all other routes. + */ + middleware?: Handler[]; +}; + +/** @public */ +export const rootHttpRouterFactory = createServiceFactory({ + service: coreServices.rootHttpRouter, + deps: { + config: coreServices.config, + lifecycle: coreServices.rootLifecycle, + }, + async factory({ config, lifecycle }, options?: RootHttpRouterFactoryOptions) { + const indexPath = options?.indexPath ?? '/api/app'; + + const namedRouter = Router(); + const indexRouter = Router(); + + const service = createServiceBuilder(module).loadConfig(config); + + for (const middleware of options?.middleware ?? []) { + service.addRouter('', middleware); + } + + service.addRouter('', namedRouter).addRouter('', indexRouter); + + const server = await service.start(); + // Stop method isn't part of the public API, let's fix that once we move the implementation here. + const stoppableServer = server as typeof server & { + stop: (cb: (error?: Error) => void) => void; + }; + + lifecycle.addShutdownHook({ + async fn() { + await new Promise((resolve, reject) => { + stoppableServer.stop((error?: Error) => { + if (error) { + reject(error); + } else { + resolve(); + } + }); + }); + }, + labels: { service: 'rootHttpRouter' }, + }); + + const existingPaths = new Array(); + + return { + use: (path: string, handler: Handler) => { + if (path.match(/^[/\s]*$/)) { + throw new Error(`Root router path may not be empty`); + } + const conflictingPath = findConflictingPath(existingPaths, path); + if (conflictingPath) { + throw new Error( + `Path ${path} conflicts with the existing path ${conflictingPath}`, + ); + } + existingPaths.push(path); + namedRouter.use(path, handler); + + if (indexPath === path) { + indexRouter.use(handler); + } + }, + }; + }, +}); + +function normalizePath(path: string): string { + return path.replace(/\/*$/, '/'); +} + +export function findConflictingPath( + paths: string[], + newPath: string, +): string | undefined { + const normalizedNewPath = normalizePath(newPath); + for (const path of paths) { + const normalizedPath = normalizePath(path); + if (normalizedPath.startsWith(normalizedNewPath)) { + return path; + } + if (normalizedNewPath.startsWith(normalizedPath)) { + return path; + } + } + return undefined; +} diff --git a/packages/backend-app-api/src/services/implementations/rootLifecycleService.ts b/packages/backend-app-api/src/services/implementations/rootLifecycleService.ts index c4ad4678ba..3797e6ffc5 100644 --- a/packages/backend-app-api/src/services/implementations/rootLifecycleService.ts +++ b/packages/backend-app-api/src/services/implementations/rootLifecycleService.ts @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { loggerToWinstonLogger } from '@backstage/backend-common'; import { createServiceFactory, coreServices, - loggerToWinstonLogger, LifecycleServiceShutdownHook, RootLifecycleService, } from '@backstage/backend-plugin-api'; diff --git a/packages/backend-app-api/src/services/implementations/tokenManagerService.ts b/packages/backend-app-api/src/services/implementations/tokenManagerService.ts index 6a2d47ae14..025830afc7 100644 --- a/packages/backend-app-api/src/services/implementations/tokenManagerService.ts +++ b/packages/backend-app-api/src/services/implementations/tokenManagerService.ts @@ -17,9 +17,11 @@ import { coreServices, createServiceFactory, - loggerToWinstonLogger, } from '@backstage/backend-plugin-api'; -import { ServerTokenManager } from '@backstage/backend-common'; +import { + loggerToWinstonLogger, + ServerTokenManager, +} from '@backstage/backend-common'; /** @public */ export const tokenManagerFactory = createServiceFactory({ diff --git a/packages/backend-app-api/src/services/implementations/urlReaderService.ts b/packages/backend-app-api/src/services/implementations/urlReaderService.ts index b68be74d8c..758b555d66 100644 --- a/packages/backend-app-api/src/services/implementations/urlReaderService.ts +++ b/packages/backend-app-api/src/services/implementations/urlReaderService.ts @@ -14,11 +14,10 @@ * limitations under the License. */ -import { UrlReaders } from '@backstage/backend-common'; +import { loggerToWinstonLogger, UrlReaders } from '@backstage/backend-common'; import { coreServices, createServiceFactory, - loggerToWinstonLogger, } from '@backstage/backend-plugin-api'; /** @public */ diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index e8b41e21bb..43260c2a64 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -12,6 +12,9 @@ import { AzureIntegration } from '@backstage/integration'; import { BitbucketCloudIntegration } from '@backstage/integration'; import { BitbucketIntegration } from '@backstage/integration'; import { BitbucketServerIntegration } from '@backstage/integration'; +import { CacheClient } from '@backstage/backend-plugin-api'; +import { CacheClientOptions } from '@backstage/backend-plugin-api'; +import { CacheClientSetOptions } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import cors from 'cors'; import Docker from 'dockerode'; @@ -24,12 +27,14 @@ import { GithubCredentialsProvider } from '@backstage/integration'; import { GithubIntegration } from '@backstage/integration'; import { GitLabIntegration } from '@backstage/integration'; import { isChildPath } from '@backstage/cli-common'; -import { JsonValue } from '@backstage/types'; import { Knex } from 'knex'; import { KubeConfig } from '@kubernetes/client-node'; import { LoadConfigOptionsRemote } from '@backstage/config-loader'; import { Logger } from 'winston'; +import { LoggerService } from '@backstage/backend-plugin-api'; import { MergeResult } from 'isomorphic-git'; +import { CacheService as PluginCacheManager } from '@backstage/backend-plugin-api'; +import { DatabaseService as PluginDatabaseManager } from '@backstage/backend-plugin-api'; import { DiscoveryService as PluginEndpointDiscovery } from '@backstage/backend-plugin-api'; import { PushResult } from 'isomorphic-git'; import { Readable } from 'stream'; @@ -46,6 +51,8 @@ import { SearchOptions } from '@backstage/backend-plugin-api'; import { SearchResponse } from '@backstage/backend-plugin-api'; import { SearchResponseFile } from '@backstage/backend-plugin-api'; import { Server } from 'http'; +import { TokenManagerService as TokenManager } from '@backstage/backend-plugin-api'; +import { TransportStreamOptions } from 'winston-transport'; import { UrlReaderService as UrlReader } from '@backstage/backend-plugin-api'; import { V1PodTemplateSpec } from '@kubernetes/client-node'; import * as winston from 'winston'; @@ -163,26 +170,11 @@ export class BitbucketUrlReader implements UrlReader { toString(): string; } -// @public -export interface CacheClient { - delete(key: string): Promise; - get(key: string): Promise; - set( - key: string, - value: JsonValue, - options?: CacheClientSetOptions, - ): Promise; -} +export { CacheClient }; -// @public -export type CacheClientOptions = { - defaultTtl?: number; -}; +export { CacheClientOptions }; -// @public -export type CacheClientSetOptions = { - ttl?: number; -}; +export { CacheClientSetOptions }; // @public export class CacheManager { @@ -515,21 +507,18 @@ export function loadBackendConfig(options: { argv: string[]; }): Promise; +// @public (undocumented) +export function loggerToWinstonLogger( + logger: LoggerService, + opts?: TransportStreamOptions, +): Logger; + // @public export function notFoundHandler(): RequestHandler; -// @public -export type PluginCacheManager = { - getClient: (options?: CacheClientOptions) => CacheClient; -}; +export { PluginCacheManager }; -// @public -export interface PluginDatabaseManager { - getClient(): Promise; - migrations?: { - skip?: boolean; - }; -} +export { PluginDatabaseManager }; export { PluginEndpointDiscovery }; @@ -710,13 +699,7 @@ export interface StatusCheckHandlerOptions { statusCheck?: StatusCheck; } -// @public -export interface TokenManager { - authenticate(token: string): Promise; - getToken(): Promise<{ - token: string; - }>; -} +export { TokenManager }; export { UrlReader }; diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index fc131723a7..aff5e56abb 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -83,6 +83,7 @@ "tar": "^6.1.12", "uuid": "^8.3.2", "winston": "^3.2.1", + "winston-transport": "^4.5.0", "yauzl": "^2.10.0", "yn": "^4.0.0" }, @@ -114,7 +115,7 @@ "@types/webpack-env": "^1.15.2", "@types/yauzl": "^2.10.0", "aws-sdk-mock": "^5.2.1", - "better-sqlite3": "^7.5.0", + "better-sqlite3": "^8.0.0", "http-errors": "^2.0.0", "mock-fs": "^5.1.0", "msw": "^0.49.0", diff --git a/packages/backend-common/src/cache/CacheClient.ts b/packages/backend-common/src/cache/CacheClient.ts index 96982edeaa..47cb786f14 100644 --- a/packages/backend-common/src/cache/CacheClient.ts +++ b/packages/backend-common/src/cache/CacheClient.ts @@ -14,57 +14,23 @@ * limitations under the License. */ +import { + CacheClient, + CacheClientSetOptions, +} from '@backstage/backend-plugin-api'; import { JsonValue } from '@backstage/types'; import { createHash } from 'crypto'; import Keyv from 'keyv'; +export type { + CacheClient, + CacheClientSetOptions, +} from '@backstage/backend-plugin-api'; + type CacheClientArgs = { client: Keyv; }; -/** - * Options passed to {@link CacheClient.set}. - * - * @public - */ -export type CacheClientSetOptions = { - /** - * Optional TTL in milliseconds. Defaults to the TTL provided when the client - * was set up (or no TTL if none are provided). - */ - ttl?: number; -}; - -/** - * A pre-configured, storage agnostic cache client suitable for use by - * Backstage plugins. - * - * @public - */ -export interface CacheClient { - /** - * Reads data from a cache store for the given key. If no data was found, - * returns undefined. - */ - get(key: string): Promise; - - /** - * Writes the given data to a cache store, associated with the given key. An - * optional TTL may also be provided, otherwise it defaults to the TTL that - * was provided when the client was instantiated. - */ - set( - key: string, - value: JsonValue, - options?: CacheClientSetOptions, - ): Promise; - - /** - * Removes the given key from the cache store. - */ - delete(key: string): Promise; -} - /** * A basic, concrete implementation of the CacheClient, suitable for almost * all uses in Backstage. diff --git a/packages/backend-common/src/cache/types.ts b/packages/backend-common/src/cache/types.ts index 5cf8323c52..40e30b1059 100644 --- a/packages/backend-common/src/cache/types.ts +++ b/packages/backend-common/src/cache/types.ts @@ -15,21 +15,11 @@ */ import { Logger } from 'winston'; -import { CacheClient } from './CacheClient'; -/** - * Options given when constructing a {@link CacheClient}. - * - * @public - */ -export type CacheClientOptions = { - /** - * An optional default TTL (in milliseconds) to be set when getting a client - * instance. If not provided, data will persist indefinitely by default (or - * can be configured per entry at set-time). - */ - defaultTtl?: number; -}; +export type { + CacheService as PluginCacheManager, + CacheClientOptions, +} from '@backstage/backend-plugin-api'; /** * Options given when constructing a {@link CacheManager}. @@ -48,21 +38,3 @@ export type CacheManagerOptions = { */ onError?: (err: Error) => void; }; - -/** - * Manages access to cache stores that plugins get. - * - * @public - */ -export type PluginCacheManager = { - /** - * Provides backend plugins cache connections for themselves. - * - * @remarks - * - * The purpose of this method is to allow plugins to get isolated data stores - * so that plugins are discouraged from cache-level integration and/or cache - * key collisions. - */ - getClient: (options?: CacheClientOptions) => CacheClient; -}; diff --git a/packages/backend-common/src/database/types.ts b/packages/backend-common/src/database/types.ts index 2fa8b749a8..2d59cf636e 100644 --- a/packages/backend-common/src/database/types.ts +++ b/packages/backend-common/src/database/types.ts @@ -17,32 +17,7 @@ import { Config } from '@backstage/config'; import { Knex } from 'knex'; -/** - * The PluginDatabaseManager manages access to databases that Plugins get. - * - * @public - */ -export interface PluginDatabaseManager { - /** - * getClient provides backend plugins database connections for itself. - * - * The purpose of this method is to allow plugins to get isolated data - * stores so that plugins are discouraged from database integration. - */ - getClient(): Promise; - - /** - * This property is used to control the behavior of database migrations. - */ - migrations?: { - /** - * skip database migrations. Useful if connecting to a read-only database. - * - * @defaultValue false - */ - skip?: boolean; - }; -} +export type { DatabaseService as PluginDatabaseManager } from '@backstage/backend-plugin-api'; /** * DatabaseConnector manages an underlying Knex database driver. diff --git a/packages/backend-common/src/logging/index.ts b/packages/backend-common/src/logging/index.ts index 4657dd4101..ff2315c51b 100644 --- a/packages/backend-common/src/logging/index.ts +++ b/packages/backend-common/src/logging/index.ts @@ -22,3 +22,4 @@ export { redactWinstonLogLine, } from './rootLogger'; export * from './voidLogger'; +export { loggerToWinstonLogger } from './loggerToWinstonLogger'; diff --git a/packages/backend-plugin-api/src/services/helpers/loggerToWinstonLogger.ts b/packages/backend-common/src/logging/loggerToWinstonLogger.ts similarity index 96% rename from packages/backend-plugin-api/src/services/helpers/loggerToWinstonLogger.ts rename to packages/backend-common/src/logging/loggerToWinstonLogger.ts index 6f435a250a..f15bd5be81 100644 --- a/packages/backend-plugin-api/src/services/helpers/loggerToWinstonLogger.ts +++ b/packages/backend-common/src/logging/loggerToWinstonLogger.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { LoggerService } from '../definitions'; +import { LoggerService } from '@backstage/backend-plugin-api'; import { Logger as WinstonLogger, createLogger } from 'winston'; import Transport, { TransportStreamOptions } from 'winston-transport'; diff --git a/packages/backend-common/src/tokens/types.ts b/packages/backend-common/src/tokens/types.ts index 2fa771b7e2..4e0fd698df 100644 --- a/packages/backend-common/src/tokens/types.ts +++ b/packages/backend-common/src/tokens/types.ts @@ -14,26 +14,4 @@ * limitations under the License. */ -/** - * Interface for creating and validating tokens. - * - * @public - */ -export interface TokenManager { - /** - * Fetches a valid token. - * - * @remarks - * - * Tokens are valid for roughly one hour; the actual deadline is set in the - * payload `exp` claim. Never hold on to tokens for reuse; always ask for a - * new one for each outgoing request. This ensures that you always get a - * valid, fresh one. - */ - getToken(): Promise<{ token: string }>; - - /** - * Validates a given token. - */ - authenticate(token: string): Promise; -} +export type { TokenManagerService as TokenManager } from '@backstage/backend-plugin-api'; diff --git a/packages/backend-defaults/src/CreateBackend.ts b/packages/backend-defaults/src/CreateBackend.ts index a37a8c32b2..20edfc85a8 100644 --- a/packages/backend-defaults/src/CreateBackend.ts +++ b/packages/backend-defaults/src/CreateBackend.ts @@ -22,6 +22,7 @@ import { databaseFactory, discoveryFactory, httpRouterFactory, + rootHttpRouterFactory, lifecycleFactory, rootLifecycleFactory, loggerFactory, @@ -45,6 +46,7 @@ export const defaultServiceFactories = [ tokenManagerFactory, urlReaderFactory, httpRouterFactory, + rootHttpRouterFactory, lifecycleFactory, rootLifecycleFactory, ]; diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index 9c6ffe6dd5..a829f6200c 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -7,14 +7,11 @@ import { Config } from '@backstage/config'; import { Handler } from 'express'; -import { Logger } from 'winston'; +import { JsonValue } from '@backstage/types'; +import { Knex } from 'knex'; import { PermissionEvaluator } from '@backstage/plugin-permission-common'; -import { PluginCacheManager } from '@backstage/backend-common'; -import { PluginDatabaseManager } from '@backstage/backend-common'; import { PluginTaskScheduler } from '@backstage/backend-tasks'; import { Readable } from 'stream'; -import { TokenManager } from '@backstage/backend-common'; -import { TransportStreamOptions } from 'winston-transport'; // @public (undocumented) export interface BackendFeature { @@ -65,8 +62,31 @@ export interface BackendRegistrationPoints { }): void; } -// @public (undocumented) -export interface CacheService extends PluginCacheManager {} +// @public +export interface CacheClient { + delete(key: string): Promise; + get(key: string): Promise; + set( + key: string, + value: JsonValue, + options?: CacheClientSetOptions, + ): Promise; +} + +// @public +export type CacheClientOptions = { + defaultTtl?: number; +}; + +// @public +export type CacheClientSetOptions = { + ttl?: number; +}; + +// @public +export interface CacheService { + getClient: (options?: CacheClientOptions) => CacheClient; +} // @public (undocumented) export interface ConfigService extends Config {} @@ -82,6 +102,7 @@ export namespace coreServices { const logger: ServiceRef; const permissions: ServiceRef; const pluginMetadata: ServiceRef; + const rootHttpRouter: ServiceRef; const rootLifecycle: ServiceRef; const rootLogger: ServiceRef; const scheduler: ServiceRef; @@ -153,8 +174,13 @@ export function createServiceRef(options: { ) => Promise | (() => ServiceFactory)>; }): ServiceRef; -// @public (undocumented) -export interface DatabaseService extends PluginDatabaseManager {} +// @public +export interface DatabaseService { + getClient(): Promise; + migrations?: { + skip?: boolean; + }; +} // @public export interface DiscoveryService { @@ -201,12 +227,6 @@ export interface LoggerService { warn(message: string, meta?: Error | LogMeta): void; } -// @public (undocumented) -export function loggerToWinstonLogger( - logger: LoggerService, - opts?: TransportStreamOptions, -): Logger; - // @public (undocumented) export type LogMeta = { [name: string]: unknown; @@ -265,6 +285,11 @@ export type ReadUrlResponse = { etag?: string; }; +// @public (undocumented) +export interface RootHttpRouterService { + use(path: string, handler: Handler): void; +} + // @public (undocumented) export interface RootLifecycleService extends LifecycleService {} @@ -331,8 +356,13 @@ export type ServiceRef< $$ref: 'service'; }; -// @public (undocumented) -export interface TokenManagerService extends TokenManager {} +// @public +export interface TokenManagerService { + authenticate(token: string): Promise; + getToken(): Promise<{ + token: string; + }>; +} // @public (undocumented) export type TypesToServiceRef = { diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index 732cfa3858..dc484a33b0 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -33,14 +33,13 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "workspace:^", "@backstage/backend-tasks": "workspace:^", "@backstage/config": "workspace:^", "@backstage/plugin-permission-common": "workspace:^", + "@backstage/types": "workspace:^", "@types/express": "^4.17.6", "express": "^4.17.1", - "winston": "^3.2.1", - "winston-transport": "^4.5.0" + "knex": "^2.0.0" }, "devDependencies": { "@backstage/cli": "workspace:^" diff --git a/packages/backend-plugin-api/src/services/definitions/CacheService.ts b/packages/backend-plugin-api/src/services/definitions/CacheService.ts index 79c930f435..2702fdac6d 100644 --- a/packages/backend-plugin-api/src/services/definitions/CacheService.ts +++ b/packages/backend-plugin-api/src/services/definitions/CacheService.ts @@ -14,7 +14,79 @@ * limitations under the License. */ -import { PluginCacheManager } from '@backstage/backend-common'; +import { JsonValue } from '@backstage/types'; -/** @public */ -export interface CacheService extends PluginCacheManager {} +/** + * Manages access to cache stores that plugins get. + * + * @public + */ +export interface CacheService { + /** + * Provides backend plugins cache connections for themselves. + * + * @remarks + * + * The purpose of this method is to allow plugins to get isolated data stores + * so that plugins are discouraged from cache-level integration and/or cache + * key collisions. + */ + getClient: (options?: CacheClientOptions) => CacheClient; +} + +/** + * Options passed to {@link CacheClient.set}. + * + * @public + */ +export type CacheClientSetOptions = { + /** + * Optional TTL in milliseconds. Defaults to the TTL provided when the client + * was set up (or no TTL if none are provided). + */ + ttl?: number; +}; + +/** + * A pre-configured, storage agnostic cache client suitable for use by + * Backstage plugins. + * + * @public + */ +export interface CacheClient { + /** + * Reads data from a cache store for the given key. If no data was found, + * returns undefined. + */ + get(key: string): Promise; + + /** + * Writes the given data to a cache store, associated with the given key. An + * optional TTL may also be provided, otherwise it defaults to the TTL that + * was provided when the client was instantiated. + */ + set( + key: string, + value: JsonValue, + options?: CacheClientSetOptions, + ): Promise; + + /** + * Removes the given key from the cache store. + */ + delete(key: string): Promise; +} + +/** + * Options given when constructing a {@link CacheClient}. + * + * @public + */ +export type CacheClientOptions = { + /** + * An optional default TTL (in milliseconds) to be set when getting a client + * instance. If not provided, data will persist indefinitely by default (or + * can be configured per entry at set-time). + */ + defaultTtl?: number; +}; diff --git a/packages/backend-plugin-api/src/services/definitions/DatabaseService.ts b/packages/backend-plugin-api/src/services/definitions/DatabaseService.ts index 30f1f574f2..583dfe8b8f 100644 --- a/packages/backend-plugin-api/src/services/definitions/DatabaseService.ts +++ b/packages/backend-plugin-api/src/services/definitions/DatabaseService.ts @@ -14,7 +14,31 @@ * limitations under the License. */ -import { PluginDatabaseManager } from '@backstage/backend-common'; +import { Knex } from 'knex'; -/** @public */ -export interface DatabaseService extends PluginDatabaseManager {} +/** + * The DatabaseService manages access to databases that Plugins get. + *gs + * @public + */ +export interface DatabaseService { + /** + * getClient provides backend plugins database connections for itself. + * + * The purpose of this method is to allow plugins to get isolated data + * stores so that plugins are discouraged from database integration. + */ + getClient(): Promise; + + /** + * This property is used to control the behavior of database migrations. + */ + migrations?: { + /** + * skip database migrations. Useful if connecting to a read-only database. + * + * @defaultValue false + */ + skip?: boolean; + }; +} diff --git a/packages/backend-plugin-api/src/services/definitions/RootHttpRouterService.ts b/packages/backend-plugin-api/src/services/definitions/RootHttpRouterService.ts new file mode 100644 index 0000000000..e583e978fa --- /dev/null +++ b/packages/backend-plugin-api/src/services/definitions/RootHttpRouterService.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Handler } from 'express'; + +/** + * @public + */ +export interface RootHttpRouterService { + /** + * Registers a handler at the root of the backend router. + * The path is required and may not be empty. + */ + use(path: string, handler: Handler): void; +} diff --git a/packages/backend-plugin-api/src/services/definitions/TokenManagerService.ts b/packages/backend-plugin-api/src/services/definitions/TokenManagerService.ts index 7fccb60c7a..c9d7edcaef 100644 --- a/packages/backend-plugin-api/src/services/definitions/TokenManagerService.ts +++ b/packages/backend-plugin-api/src/services/definitions/TokenManagerService.ts @@ -14,7 +14,26 @@ * limitations under the License. */ -import { TokenManager } from '@backstage/backend-common'; +/** + * Interface for creating and validating tokens. + * + * @public + */ +export interface TokenManagerService { + /** + * Fetches a valid token. + * + * @remarks + * + * Tokens are valid for roughly one hour; the actual deadline is set in the + * payload `exp` claim. Never hold on to tokens for reuse; always ask for a + * new one for each outgoing request. This ensures that you always get a + * valid, fresh one. + */ + getToken(): Promise<{ token: string }>; -/** @public */ -export interface TokenManagerService extends TokenManager {} + /** + * Validates a given token. + */ + authenticate(token: string): Promise; +} diff --git a/packages/backend-plugin-api/src/services/definitions/coreServices.ts b/packages/backend-plugin-api/src/services/definitions/coreServices.ts index fc96ec8be9..7de92d6d01 100644 --- a/packages/backend-plugin-api/src/services/definitions/coreServices.ts +++ b/packages/backend-plugin-api/src/services/definitions/coreServices.ts @@ -103,6 +103,15 @@ export namespace coreServices { import('./PluginMetadataService').PluginMetadataService >({ id: 'core.pluginMetadata' }); + /** + * The service reference for the root scoped {@link RootHttpRouterService}. + * + * @public + */ + export const rootHttpRouter = createServiceRef< + import('./RootHttpRouterService').RootHttpRouterService + >({ id: 'core.rootHttpRouter', scope: 'root' }); + /** * The service reference for the root scoped {@link RootLifecycleService}. * diff --git a/packages/backend-plugin-api/src/services/definitions/index.ts b/packages/backend-plugin-api/src/services/definitions/index.ts index dedfd6223e..99b3cbd06d 100644 --- a/packages/backend-plugin-api/src/services/definitions/index.ts +++ b/packages/backend-plugin-api/src/services/definitions/index.ts @@ -15,7 +15,12 @@ */ export { coreServices } from './coreServices'; -export type { CacheService } from './CacheService'; +export type { + CacheService, + CacheClient, + CacheClientOptions, + CacheClientSetOptions, +} from './CacheService'; export type { ConfigService } from './ConfigService'; export type { DatabaseService } from './DatabaseService'; export type { DiscoveryService } from './DiscoveryService'; @@ -27,6 +32,7 @@ export type { export type { LoggerService, LogMeta } from './LoggerService'; export type { PermissionsService } from './PermissionsService'; export type { PluginMetadataService } from './PluginMetadataService'; +export type { RootHttpRouterService } from './RootHttpRouterService'; export type { RootLifecycleService } from './RootLifecycleService'; export type { RootLoggerService } from './RootLoggerService'; export type { SchedulerService } from './SchedulerService'; diff --git a/packages/backend-plugin-api/src/services/index.ts b/packages/backend-plugin-api/src/services/index.ts index 96bd3d320a..dd24127b88 100644 --- a/packages/backend-plugin-api/src/services/index.ts +++ b/packages/backend-plugin-api/src/services/index.ts @@ -15,5 +15,4 @@ */ export * from './definitions'; -export * from './helpers'; export * from './system'; diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 337c8e1adf..b1b4ee2d0c 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -39,7 +39,7 @@ "@backstage/backend-plugin-api": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/config": "workspace:^", - "better-sqlite3": "^7.5.0", + "better-sqlite3": "^8.0.0", "knex": "^2.0.0", "msw": "^0.49.0", "mysql2": "^2.2.5", diff --git a/packages/backend/package.json b/packages/backend/package.json index b38fafa8f2..085eec665b 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -32,6 +32,7 @@ "@backstage/catalog-model": "workspace:^", "@backstage/config": "workspace:^", "@backstage/integration": "workspace:^", + "@backstage/plugin-adr-backend": "workspace:^", "@backstage/plugin-app-backend": "workspace:^", "@backstage/plugin-auth-backend": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", @@ -69,7 +70,7 @@ "@gitbeaker/node": "^35.1.0", "@octokit/rest": "^19.0.3", "azure-devops-node-api": "^11.0.1", - "better-sqlite3": "^7.5.0", + "better-sqlite3": "^8.0.0", "dockerode": "^3.3.1", "example-app": "link:../app", "express": "^4.17.1", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 371ce40358..a721c443d6 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Backstage Authors + * 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. @@ -61,6 +61,7 @@ import badges from './plugins/badges'; import jenkins from './plugins/jenkins'; import permission from './plugins/permission'; import playlist from './plugins/playlist'; +import adr from './plugins/adr'; import { PluginEnvironment } from './types'; import { ServerPermissionClient } from '@backstage/plugin-permission-node'; import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; @@ -139,6 +140,7 @@ async function main() { const appEnv = useHotMemoize(module, () => createEnv('app')); const badgesEnv = useHotMemoize(module, () => createEnv('badges')); const jenkinsEnv = useHotMemoize(module, () => createEnv('jenkins')); + const adrEnv = useHotMemoize(module, () => createEnv('adr')); const techInsightsEnv = useHotMemoize(module, () => createEnv('tech-insights'), ); @@ -175,6 +177,7 @@ async function main() { apiRouter.use('/permission', await permission(permissionEnv)); apiRouter.use('/playlist', await playlist(playlistEnv)); apiRouter.use('/explore', await explore(exploreEnv)); + apiRouter.use('/adr', await adr(adrEnv)); apiRouter.use(notFoundHandler()); const service = createServiceBuilder(module) diff --git a/packages/backend/src/plugins/adr.ts b/packages/backend/src/plugins/adr.ts new file mode 100644 index 0000000000..6fa0d72969 --- /dev/null +++ b/packages/backend/src/plugins/adr.ts @@ -0,0 +1,29 @@ +/* + * 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 { createRouter } from '@backstage/plugin-adr-backend'; +import { Router } from 'express'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + return await createRouter({ + reader: env.reader, + cacheClient: env.cache.getClient(), + logger: env.logger, + }); +} diff --git a/packages/catalog-client/src/CatalogClient.test.ts b/packages/catalog-client/src/CatalogClient.test.ts index 8587a5a2e1..2e9d2a0679 100644 --- a/packages/catalog-client/src/CatalogClient.test.ts +++ b/packages/catalog-client/src/CatalogClient.test.ts @@ -232,9 +232,9 @@ describe('CatalogClient', () => { }; server.use( rest.post(`${mockBaseUrl}/entities/by-refs`, async (req, res, ctx) => { - expect(req.url.searchParams.get('fields')).toBe('a,b'); await expect(req.json()).resolves.toEqual({ entityRefs: ['k:n/a', 'k:n/b'], + fields: ['a', 'b'], }); return res(ctx.json({ items: [entity, null] })); }), diff --git a/packages/catalog-client/src/CatalogClient.ts b/packages/catalog-client/src/CatalogClient.ts index 81f7343555..af4262b842 100644 --- a/packages/catalog-client/src/CatalogClient.ts +++ b/packages/catalog-client/src/CatalogClient.ts @@ -197,14 +197,13 @@ export class CatalogClient implements CatalogApi { request: GetEntitiesByRefsRequest, options?: CatalogRequestOptions, ): Promise { - const params: string[] = []; + const body: any = { entityRefs: request.entityRefs }; if (request.fields?.length) { - params.push(`fields=${request.fields.map(encodeURIComponent).join(',')}`); + body.fields = request.fields; } const baseUrl = await this.discoveryApi.getBaseUrl('catalog'); - const query = params.length ? `?${params.join('&')}` : ''; - const url = `${baseUrl}/entities/by-refs${query}`; + const url = `${baseUrl}/entities/by-refs`; const response = await this.fetchApi.fetch(url, { headers: { @@ -212,7 +211,7 @@ export class CatalogClient implements CatalogApi { ...(options?.token && { Authorization: `Bearer ${options?.token}` }), }, method: 'POST', - body: JSON.stringify({ entityRefs: request.entityRefs }), + body: JSON.stringify(body), }); if (!response.ok) { diff --git a/packages/cli/package.json b/packages/cli/package.json index 76d9717759..119f08d338 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -156,8 +156,7 @@ "mock-fs": "^5.1.0", "msw": "^0.49.0", "nodemon": "^2.0.2", - "ts-node": "^10.0.0", - "type-fest": "^2.0.0" + "ts-node": "^10.0.0" }, "peerDependencies": { "@microsoft/api-extractor": "^7.21.2" diff --git a/packages/cli/src/commands/start/startFrontend.ts b/packages/cli/src/commands/start/startFrontend.ts index b7b81e6bff..991439c010 100644 --- a/packages/cli/src/commands/start/startFrontend.ts +++ b/packages/cli/src/commands/start/startFrontend.ts @@ -80,7 +80,7 @@ export async function startFrontend(options: StartAppOptions) { `⚠️ Conflict between app baseUrl and backend baseUrl: app.baseUrl: ${appBaseUrl} - backend.baseUrl: ${appBaseUrl} + backend.baseUrl: ${backendBaseUrl} Must have unique hostname and/or ports. diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md index c46b3637cb..4cdc42ee79 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/api-report.md @@ -113,7 +113,7 @@ export type BottomLinkProps = { onClick?: (event: React_2.MouseEvent) => void; }; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "Props_19" needs to be exported by the entry point index.d.ts // // @public export function Breadcrumbs(props: Props_19): JSX.Element; @@ -168,7 +168,7 @@ export interface CodeSnippetProps { text: string; } -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "Props_13" needs to be exported by the entry point index.d.ts // // @public export function Content(props: PropsWithChildren): JSX.Element; @@ -320,7 +320,7 @@ export function DocsIcon(props: IconComponentProps): JSX.Element; // @public (undocumented) export function EmailIcon(props: IconComponentProps): JSX.Element; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "Props_2" needs to be exported by the entry point index.d.ts // // @public export function EmptyState(props: Props_2): JSX.Element; @@ -375,7 +375,7 @@ export type FeatureCalloutCircleClassKey = | 'pulseCircle' | 'text'; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "Props_4" needs to be exported by the entry point index.d.ts // // @public export function FeatureCalloutCircular( @@ -388,7 +388,7 @@ export type FiltersContainerClassKey = 'root' | 'title'; // @public export function Gauge(props: GaugeProps): JSX.Element; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "Props_10" needs to be exported by the entry point index.d.ts // // @public export function GaugeCard(props: Props_10): JSX.Element; @@ -432,7 +432,7 @@ export function GitHubIcon(props: IconComponentProps): JSX.Element; // @public (undocumented) export function GroupIcon(props: IconComponentProps): JSX.Element; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "Props_14" needs to be exported by the entry point index.d.ts // // @public export function Header(props: PropsWithChildren): JSX.Element; @@ -466,7 +466,7 @@ export type HeaderClassKey = | 'breadcrumbType' | 'breadcrumbTitle'; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "Props_5" needs to be exported by the entry point index.d.ts // // @public export function HeaderIconLinkRow(props: Props_5): JSX.Element; @@ -497,7 +497,7 @@ export type HeaderTabsClassKey = // @public (undocumented) export function HelpIcon(props: IconComponentProps): JSX.Element; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "Props_6" needs to be exported by the entry point index.d.ts // // @public export function HorizontalScrollGrid( @@ -524,7 +524,7 @@ export type IconLinkVerticalClassKey = | 'secondary' | 'label'; -// Warning: (ae-missing-release-tag) "IconLinkVerticalProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "IconLinkVerticalProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type IconLinkVerticalProps = { @@ -540,7 +540,7 @@ export type IconLinkVerticalProps = { // @public (undocumented) export type IdentityProviders = ('guest' | 'custom' | SignInProviderConfig)[]; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "Props_15" needs to be exported by the entry point index.d.ts // // @public export function InfoCard(props: Props_15): JSX.Element; @@ -564,7 +564,7 @@ export type InfoCardVariants = 'flex' | 'fullHeight' | 'gridItem'; export function IntroCard(props: IntroCardProps): JSX.Element; // Warning: (ae-forgotten-export) The symbol "ItemCardProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ItemCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "ItemCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @deprecated export function ItemCard(props: ItemCardProps): JSX.Element; @@ -588,7 +588,7 @@ export function ItemCardHeader(props: ItemCardHeaderProps): JSX.Element; // @public (undocumented) export type ItemCardHeaderClassKey = 'root'; -// Warning: (ae-forgotten-export) The symbol "styles" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "styles_2" needs to be exported by the entry point index.d.ts // // @public (undocumented) export type ItemCardHeaderProps = Partial> & { @@ -607,29 +607,29 @@ enum LabelPosition { RIGHT = 'r', } -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "Lifecycle" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-forgotten-export) The symbol "Props_7" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "Lifecycle" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function Lifecycle(props: Props_7): JSX.Element; -// Warning: (ae-missing-release-tag) "LifecycleClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "LifecycleClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type LifecycleClassKey = 'alpha' | 'beta'; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "LinearGauge" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-forgotten-export) The symbol "Props_11" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "LinearGauge" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function LinearGauge(props: Props_11): JSX.Element | null; -// Warning: (ae-missing-release-tag) "Link" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "Link" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public export const Link: (props: LinkProps) => JSX.Element; -// Warning: (ae-missing-release-tag) "LinkProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "LinkProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type LinkProps = Omit & @@ -639,7 +639,7 @@ export type LinkProps = Omit & noTrack?: boolean; }; -// Warning: (ae-missing-release-tag) "LoginRequestListItemClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "LoginRequestListItemClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type LoginRequestListItemClassKey = 'root'; @@ -688,49 +688,49 @@ export interface LogViewerProps { text: string; } -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "MarkdownContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-forgotten-export) The symbol "Props_8" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "MarkdownContent" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public export function MarkdownContent(props: Props_8): JSX.Element; -// Warning: (ae-missing-release-tag) "MarkdownContentClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "MarkdownContentClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type MarkdownContentClassKey = 'markdown'; -// Warning: (ae-missing-release-tag) "MetadataTableCellClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "MetadataTableCellClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type MetadataTableCellClassKey = 'root'; -// Warning: (ae-missing-release-tag) "MetadataTableListClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "MetadataTableListClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type MetadataTableListClassKey = 'root'; -// Warning: (ae-missing-release-tag) "MetadataTableListItemClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "MetadataTableListItemClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type MetadataTableListItemClassKey = 'root' | 'random'; -// Warning: (ae-missing-release-tag) "MetadataTableTitleCellClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "MetadataTableTitleCellClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type MetadataTableTitleCellClassKey = 'root'; -// Warning: (ae-missing-release-tag) "MicDropClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "MicDropClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type MicDropClassKey = 'micDrop'; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "MissingAnnotationEmptyState" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-forgotten-export) The symbol "Props_3" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "MissingAnnotationEmptyState" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function MissingAnnotationEmptyState(props: Props_3): JSX.Element; -// Warning: (ae-missing-release-tag) "MissingAnnotationEmptyStateClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "MissingAnnotationEmptyStateClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type MissingAnnotationEmptyStateClassKey = 'code'; @@ -743,12 +743,12 @@ export type MobileSidebarProps = { children?: React_2.ReactNode; }; -// Warning: (ae-missing-release-tag) "OAuthRequestDialog" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "OAuthRequestDialog" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function OAuthRequestDialog(_props: {}): JSX.Element; -// Warning: (ae-missing-release-tag) "OAuthRequestDialogClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "OAuthRequestDialogClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type OAuthRequestDialogClassKey = @@ -757,42 +757,42 @@ export type OAuthRequestDialogClassKey = | 'contentList' | 'actionButtons'; -// Warning: (ae-missing-release-tag) "OpenedDropdownClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "OpenedDropdownClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type OpenedDropdownClassKey = 'icon'; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "OverflowTooltip" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-forgotten-export) The symbol "Props_9" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "OverflowTooltip" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function OverflowTooltip(props: Props_9): JSX.Element; -// Warning: (ae-missing-release-tag) "OverflowTooltipClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "OverflowTooltipClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type OverflowTooltipClassKey = 'container'; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "Page" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-forgotten-export) The symbol "Props_16" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "Page" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function Page(props: Props_16): JSX.Element; -// Warning: (ae-missing-release-tag) "PageClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "PageClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type PageClassKey = 'root'; // Warning: (ae-forgotten-export) The symbol "PageWithHeaderProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "PageWithHeader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "PageWithHeader" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function PageWithHeader( props: PropsWithChildren, ): JSX.Element; -// Warning: (ae-missing-release-tag) "Progress" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "Progress" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function Progress( @@ -810,7 +810,7 @@ export type ProxiedSignInPageProps = SignInPageProps & { headers?: HeadersInit | (() => HeadersInit) | (() => Promise); }; -// Warning: (ae-missing-release-tag) "Ranker" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "Ranker" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public enum Ranker { @@ -819,14 +819,14 @@ enum Ranker { TIGHT_TREE = 'tight-tree', } -// Warning: (ae-missing-release-tag) "RenderLabelFunction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "RenderLabelFunction" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public type RenderLabelFunction = ( props: RenderLabelProps, ) => React_2.ReactNode; -// Warning: (ae-missing-release-tag) "RenderLabelProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "RenderLabelProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // Warning: (ae-unresolved-link) The @link reference could not be resolved: This type of declaration is not supported yet by the resolver // Warning: (ae-unresolved-link) The @link reference could not be resolved: This type of declaration is not supported yet by the resolver // @@ -835,7 +835,7 @@ type RenderLabelProps = { edge: DependencyEdge; }; -// Warning: (ae-missing-release-tag) "RenderNodeFunction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "RenderNodeFunction" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // Warning: (ae-unresolved-link) The @link reference could not be resolved: This type of declaration is not supported yet by the resolver // // @public @@ -843,7 +843,7 @@ type RenderNodeFunction = ( props: RenderNodeProps, ) => React_2.ReactNode; -// Warning: (ae-missing-release-tag) "RenderNodeProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "RenderNodeProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // Warning: (ae-unresolved-link) The @link reference could not be resolved: This type of declaration is not supported yet by the resolver // Warning: (ae-unresolved-link) The @link reference could not be resolved: This type of declaration is not supported yet by the resolver // @@ -852,17 +852,17 @@ type RenderNodeProps = { node: DependencyNode; }; -// Warning: (ae-missing-release-tag) "ResponseErrorPanel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "ResponseErrorPanel" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public export function ResponseErrorPanel(props: ErrorPanelProps): JSX.Element; -// Warning: (ae-missing-release-tag) "ResponseErrorPanelClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "ResponseErrorPanelClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type ResponseErrorPanelClassKey = 'text' | 'divider'; -// Warning: (ae-missing-release-tag) "RoutedTabs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "RoutedTabs" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function RoutedTabs(props: { routes: SubRoute_2[] }): JSX.Element; @@ -896,7 +896,7 @@ export type SelectItem = { // @public export const Sidebar: (props: SidebarProps) => JSX.Element; -// Warning: (ae-missing-release-tag) "SIDEBAR_INTRO_LOCAL_STORAGE" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SIDEBAR_INTRO_LOCAL_STORAGE" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const SIDEBAR_INTRO_LOCAL_STORAGE = @@ -905,7 +905,7 @@ export const SIDEBAR_INTRO_LOCAL_STORAGE = // @public (undocumented) export type SidebarClassKey = 'drawer' | 'drawerOpen'; -// Warning: (ae-missing-release-tag) "sidebarConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "sidebarConfig" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const sidebarConfig: { @@ -933,7 +933,7 @@ export type SidebarContextType = { setOpen: (open: boolean) => void; }; -// Warning: (ae-missing-release-tag) "SidebarDivider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SidebarDivider" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const SidebarDivider: React_2.ComponentType< @@ -942,7 +942,7 @@ export const SidebarDivider: React_2.ComponentType< StyledComponentProps<'root'> >; -// Warning: (ae-missing-release-tag) "SidebarDividerClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SidebarDividerClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type SidebarDividerClassKey = 'root'; @@ -960,7 +960,7 @@ export interface SidebarGroupProps extends BottomNavigationActionProps { to?: string; } -// Warning: (ae-missing-release-tag) "SidebarIntro" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SidebarIntro" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function SidebarIntro(_props: {}): JSX.Element | null; @@ -974,7 +974,7 @@ export type SidebarIntroClassKey = | 'introDismissIcon'; // Warning: (ae-forgotten-export) The symbol "SidebarItemProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "SidebarItem" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SidebarItem" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public export const SidebarItem: (props: SidebarItemProps) => JSX.Element; @@ -1018,12 +1018,12 @@ export type SidebarOptions = { drawerWidthOpen?: number; }; -// Warning: (ae-missing-release-tag) "SidebarPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SidebarPage" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function SidebarPage(props: SidebarPageProps): JSX.Element; -// Warning: (ae-missing-release-tag) "SidebarPageClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SidebarPageClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type SidebarPageClassKey = 'root'; @@ -1066,7 +1066,7 @@ export type SidebarProps = { children?: React_2.ReactNode; }; -// Warning: (ae-missing-release-tag) "SidebarScrollWrapper" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SidebarScrollWrapper" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const SidebarScrollWrapper: React_2.ComponentType< @@ -1076,12 +1076,12 @@ export const SidebarScrollWrapper: React_2.ComponentType< >; // Warning: (ae-forgotten-export) The symbol "SidebarSearchFieldProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "SidebarSearchField" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SidebarSearchField" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function SidebarSearchField(props: SidebarSearchFieldProps): JSX.Element; -// Warning: (ae-missing-release-tag) "SidebarSpace" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SidebarSpace" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const SidebarSpace: React_2.ComponentType< @@ -1090,12 +1090,12 @@ export const SidebarSpace: React_2.ComponentType< StyledComponentProps<'root'> >; -// Warning: (ae-missing-release-tag) "SidebarSpaceClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SidebarSpaceClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type SidebarSpaceClassKey = 'root'; -// Warning: (ae-missing-release-tag) "SidebarSpacer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SidebarSpacer" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const SidebarSpacer: React_2.ComponentType< @@ -1104,7 +1104,7 @@ export const SidebarSpacer: React_2.ComponentType< StyledComponentProps<'root'> >; -// Warning: (ae-missing-release-tag) "SidebarSpacerClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SidebarSpacerClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type SidebarSpacerClassKey = 'root'; @@ -1138,18 +1138,18 @@ export type SidebarSubmenuProps = { children: ReactNode; }; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "SignInPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-forgotten-export) The symbol "Props_17" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "SignInPage" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function SignInPage(props: Props_17): JSX.Element; -// Warning: (ae-missing-release-tag) "SignInPageClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SignInPageClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type SignInPageClassKey = 'container' | 'item'; -// Warning: (ae-missing-release-tag) "SignInProviderConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SignInProviderConfig" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type SignInProviderConfig = { @@ -1160,37 +1160,37 @@ export type SignInProviderConfig = { }; // Warning: (ae-forgotten-export) The symbol "StepperProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "SimpleStepper" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SimpleStepper" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function SimpleStepper( props: PropsWithChildren, ): JSX.Element; -// Warning: (ae-missing-release-tag) "SimpleStepperFooterClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SimpleStepperFooterClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type SimpleStepperFooterClassKey = 'root'; // Warning: (ae-forgotten-export) The symbol "StepProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "SimpleStepperStep" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SimpleStepperStep" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function SimpleStepperStep( props: PropsWithChildren, ): JSX.Element; -// Warning: (ae-missing-release-tag) "SimpleStepperStepClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SimpleStepperStepClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type SimpleStepperStepClassKey = 'end'; -// Warning: (ae-missing-release-tag) "StatusAborted" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "StatusAborted" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function StatusAborted(props: PropsWithChildren<{}>): JSX.Element; -// Warning: (ae-missing-release-tag) "StatusClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "StatusClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type StatusClassKey = @@ -1202,43 +1202,43 @@ export type StatusClassKey = | 'running' | 'aborted'; -// Warning: (ae-missing-release-tag) "StatusError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "StatusError" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function StatusError(props: PropsWithChildren<{}>): JSX.Element; -// Warning: (ae-missing-release-tag) "StatusOK" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "StatusOK" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function StatusOK(props: PropsWithChildren<{}>): JSX.Element; -// Warning: (ae-missing-release-tag) "StatusPending" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "StatusPending" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function StatusPending(props: PropsWithChildren<{}>): JSX.Element; -// Warning: (ae-missing-release-tag) "StatusRunning" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "StatusRunning" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function StatusRunning(props: PropsWithChildren<{}>): JSX.Element; -// Warning: (ae-missing-release-tag) "StatusWarning" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "StatusWarning" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function StatusWarning(props: PropsWithChildren<{}>): JSX.Element; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "StructuredMetadataTable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-forgotten-export) The symbol "Props_12" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "StructuredMetadataTable" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function StructuredMetadataTable(props: Props_12): JSX.Element; -// Warning: (ae-missing-release-tag) "StructuredMetadataTableListClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "StructuredMetadataTableListClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type StructuredMetadataTableListClassKey = 'root'; -// Warning: (ae-missing-release-tag) "StructuredMetadataTableNestedListClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "StructuredMetadataTableNestedListClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type StructuredMetadataTableNestedListClassKey = 'root'; @@ -1250,28 +1250,28 @@ export type SubmenuOptions = { }; // Warning: (ae-forgotten-export) The symbol "SubvalueCellProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "SubvalueCell" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SubvalueCell" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function SubvalueCell(props: SubvalueCellProps): JSX.Element; -// Warning: (ae-missing-release-tag) "SubvalueCellClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SubvalueCellClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type SubvalueCellClassKey = 'value' | 'subvalue'; // Warning: (ae-forgotten-export) The symbol "SupportButtonProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "SupportButton" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SupportButton" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function SupportButton(props: SupportButtonProps): JSX.Element; -// Warning: (ae-missing-release-tag) "SupportButtonClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SupportButtonClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type SupportButtonClassKey = 'popoverList'; -// Warning: (ae-missing-release-tag) "SupportConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SupportConfig" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type SupportConfig = { @@ -1279,7 +1279,7 @@ export type SupportConfig = { items: SupportItem[]; }; -// Warning: (ae-missing-release-tag) "SupportItem" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SupportItem" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type SupportItem = { @@ -1288,7 +1288,7 @@ export type SupportItem = { links: SupportItemLink[]; }; -// Warning: (ae-missing-release-tag) "SupportItemLink" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SupportItemLink" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type SupportItemLink = { @@ -1296,7 +1296,7 @@ export type SupportItemLink = { title: string; }; -// Warning: (ae-missing-release-tag) "Tab" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "Tab" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type Tab = { @@ -1310,24 +1310,24 @@ export type Tab = { >; }; -// Warning: (ae-missing-release-tag) "TabBarClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "TabBarClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type TabBarClassKey = 'indicator' | 'flexContainer' | 'root'; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "TabbedCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-forgotten-export) The symbol "Props_18" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "TabbedCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function TabbedCard(props: PropsWithChildren): JSX.Element; -// Warning: (ae-missing-release-tag) "TabbedCardClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "TabbedCardClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type TabbedCardClassKey = 'root' | 'indicator'; -// Warning: (ae-missing-release-tag) "TabbedLayout" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-missing-release-tag) "TabbedLayout" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "TabbedLayout" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "TabbedLayout" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public export function TabbedLayout(props: PropsWithChildren<{}>): JSX.Element; @@ -1343,12 +1343,12 @@ export namespace TabbedLayout { // @public (undocumented) export type TabClassKey = 'root' | 'selected'; -// Warning: (ae-missing-release-tag) "TabIconClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "TabIconClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type TabIconClassKey = 'root'; -// Warning: (ae-missing-release-tag) "Table" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "Table" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function Table(props: TableProps): JSX.Element; @@ -1359,12 +1359,12 @@ export namespace Table { icons: Readonly; } -// Warning: (ae-missing-release-tag) "TableClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "TableClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type TableClassKey = 'root'; -// Warning: (ae-missing-release-tag) "TableColumn" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "TableColumn" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export interface TableColumn extends Column { @@ -1374,7 +1374,7 @@ export interface TableColumn extends Column { width?: string; } -// Warning: (ae-missing-release-tag) "TableFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "TableFilter" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type TableFilter = { @@ -1382,17 +1382,17 @@ export type TableFilter = { type: 'select' | 'multiple-select'; }; -// Warning: (ae-missing-release-tag) "TableFiltersClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "TableFiltersClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type TableFiltersClassKey = 'root' | 'value' | 'heder' | 'filters'; -// Warning: (ae-missing-release-tag) "TableHeaderClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "TableHeaderClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type TableHeaderClassKey = 'header'; -// Warning: (ae-missing-release-tag) "TableProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "TableProps" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export interface TableProps @@ -1411,7 +1411,7 @@ export interface TableProps subtitle?: string; } -// Warning: (ae-missing-release-tag) "TableState" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "TableState" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type TableState = { @@ -1420,23 +1420,23 @@ export type TableState = { filters?: SelectedFilters; }; -// Warning: (ae-missing-release-tag) "TableToolbarClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "TableToolbarClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type TableToolbarClassKey = 'root' | 'title' | 'searchField'; // Warning: (ae-forgotten-export) The symbol "TabsProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "Tabs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "Tabs" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function Tabs(props: TabsProps): JSX.Element; -// Warning: (ae-missing-release-tag) "TabsClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "TabsClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type TabsClassKey = 'root' | 'styledTabs' | 'appbar'; -// Warning: (ae-missing-release-tag) "TrendLine" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "TrendLine" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function TrendLine( @@ -1453,7 +1453,7 @@ export function useContent(): { }; // Warning: (ae-forgotten-export) The symbol "SetQueryParams" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "useQueryParamState" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "useQueryParamState" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function useQueryParamState( @@ -1502,7 +1502,7 @@ export const useSidebarOpenState: () => SidebarOpenState; // @public export const useSidebarPinState: () => SidebarPinState; -// Warning: (ae-missing-release-tag) "useSupportConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "useSupportConfig" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function useSupportConfig(): SupportConfig; @@ -1511,12 +1511,12 @@ export function useSupportConfig(): SupportConfig; export function WarningIcon(props: IconComponentProps): JSX.Element; // Warning: (ae-forgotten-export) The symbol "WarningProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "WarningPanel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "WarningPanel" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public export function WarningPanel(props: WarningProps): JSX.Element; -// Warning: (ae-missing-release-tag) "WarningPanelClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "WarningPanelClassKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type WarningPanelClassKey = @@ -1530,7 +1530,7 @@ export type WarningPanelClassKey = // // src/components/DependencyGraph/types.d.ts:16:5 - (ae-unresolved-link) The @link reference could not be resolved: The package "@backstage/core-components" does not have an export "DependencyNode" // src/components/DependencyGraph/types.d.ts:20:5 - (ae-unresolved-link) The @link reference could not be resolved: The package "@backstage/core-components" does not have an export "DependencyNode" -// src/components/TabbedLayout/RoutedTabs.d.ts:9:5 - (ae-forgotten-export) The symbol "SubRoute" needs to be exported by the entry point index.d.ts +// src/components/TabbedLayout/RoutedTabs.d.ts:9:5 - (ae-forgotten-export) The symbol "SubRoute_2" needs to be exported by the entry point index.d.ts // src/components/Table/Table.d.ts:20:5 - (ae-forgotten-export) The symbol "SelectedFilters" needs to be exported by the entry point index.d.ts // src/layout/ErrorBoundary/ErrorBoundary.d.ts:8:5 - (ae-forgotten-export) The symbol "SlackChannel" needs to be exported by the entry point index.d.ts ``` diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index 374eaa6d18..6bef34d633 100644 --- a/packages/e2e-test/package.json +++ b/packages/e2e-test/package.json @@ -40,7 +40,7 @@ "handlebars": "^4.7.3", "nodemon": "^2.0.2", "pgtools": "^0.3.0", - "puppeteer": "^17.0.0", + "puppeteer": "^19.0.0", "tree-kill": "^1.2.2", "ts-node": "^10.0.0" }, diff --git a/packages/e2e-test/src/lib/helpers.ts b/packages/e2e-test/src/lib/helpers.ts index b3fd665fd2..2e9b355f4c 100644 --- a/packages/e2e-test/src/lib/helpers.ts +++ b/packages/e2e-test/src/lib/helpers.ts @@ -22,7 +22,7 @@ import { ChildProcess, } from 'child_process'; import { promisify } from 'util'; -import puppeteer from 'puppeteer'; +import * as puppeteer from 'puppeteer'; const execFile = promisify(execFileCb); diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json index cb0378363a..6d401366c4 100644 --- a/packages/repo-tools/package.json +++ b/packages/repo-tools/package.json @@ -33,8 +33,8 @@ "@backstage/cli-common": "workspace:^", "@backstage/errors": "workspace:^", "@manypkg/get-packages": "^1.1.3", - "@microsoft/api-documenter": "^7.17.11", - "@microsoft/api-extractor": "^7.23.0", + "@microsoft/api-documenter": "^7.19.27", + "@microsoft/api-extractor": "^7.33.7", "chalk": "^4.0.0", "commander": "^9.1.0", "fs-extra": "10.1.0", @@ -53,7 +53,6 @@ "@microsoft/api-extractor-model": "*", "@microsoft/tsdoc": "*", "@microsoft/tsdoc-config": "*", - "@rushstack/node-core-library": "*", "prettier": "^2.8.1", "typescript": "> 3.0.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 9e844d97c8..b037f40be6 100644 --- a/packages/repo-tools/src/commands/api-reports/api-extractor.ts +++ b/packages/repo-tools/src/commands/api-reports/api-extractor.ts @@ -18,11 +18,9 @@ import { resolve as resolvePath, relative as relativePath, basename, - dirname, join, } from 'path'; import { execFile } from 'child_process'; -import type prettierType from 'prettier'; import fs from 'fs-extra'; import { Extractor, @@ -70,32 +68,7 @@ const tmpDir = cliPaths.resolveTargetRoot( ); /** - * All of this monkey patching below is because MUI has these bare package.json file as a method - * for making TypeScript accept imports like `@material-ui/core/Button`, and improve tree-shaking - * by declaring them side effect free. - * - * The package.json lookup logic in api-extractor really doesn't like that though, as it enforces - * that the 'name' field exists in all package.json files that it discovers. This below is just - * making sure that we ignore those file package.json files instead of crashing. - */ -const { - PackageJsonLookup, -} = require('@rushstack/node-core-library/lib/PackageJsonLookup'); - -const old = PackageJsonLookup.prototype.tryGetPackageJsonFilePathFor; -PackageJsonLookup.prototype.tryGetPackageJsonFilePathFor = - function tryGetPackageJsonFilePathForPatch(path: string) { - if ( - path.includes('@material-ui') && - !dirname(path).endsWith('@material-ui') - ) { - return undefined; - } - return old.call(this, path); - }; - -/** - * Another monkey patch where we apply prettier to the API reports. This has to be patched into + * All of this monkey patching below is for apply prettier to the API reports. This has to be patched into * the middle of the process as API Extractor does a comparison of the contents of the old * and new files during generation. This inserts the formatting just before that comparison. */ @@ -134,7 +107,6 @@ ApiReportGenerator.generateReviewFileContent = ...moreArgs: any[] ) { const program = collector.program as Program; - // The purpose of this override is to allow the @ignore tag to be used to ignore warnings // of the form "Warning: (ae-forgotten-export) The symbol "FooBar" needs to be exported by the entry point index.d.ts" patchFileMessageFetcher( @@ -166,7 +138,16 @@ ApiReportGenerator.generateReviewFileContent = } // The local name of the symbol within the file, rather than the exported name - const localName = (sourceFile as any).identifiers?.get(symbolName); + let localName = (sourceFile as any).identifiers?.get(symbolName); + + if (!localName) { + // Sometimes the symbol name is suffixed with a number to disambiguate, + // e.g. "Props_14" instead of "Props" if there are multiple Props interfaces + // so we tyry to strip that suffix and look up the symbol again. + const [, trimmedSymbolName] = symbolName.match(/(.*)_\d+/) || []; + localName = (sourceFile as any).identifiers?.get(trimmedSymbolName); + } + if (!localName) { throw new Error( `Unable to find local name of "${symbolName}" in ${sourceFile.fileName}`, @@ -213,7 +194,7 @@ ApiReportGenerator.generateReviewFileContent = ); try { - const prettier = require('prettier') as typeof prettierType; + const prettier = require('prettier') as typeof import('prettier'); const config = prettier.resolveConfig.sync(cliPaths.targetRoot) ?? {}; return prettier.format(content, { @@ -221,7 +202,6 @@ ApiReportGenerator.generateReviewFileContent = parser: 'markdown', }); } catch (e) { - // console.warn('Failed to format API report with prettier', e); return content; } }; @@ -434,6 +414,7 @@ export async function runApiExtraction({ configObjectFullPath: projectFolder, packageJsonFullPath: resolvePath(projectFolder, 'package.json'), tsdocConfigFile: await getTsDocConfig(), + ignoreMissingEntryPoint: true, }); // The `packageFolder` needs to point to the location within `dist-types` in order for relative diff --git a/plugins/adr-backend/README.md b/plugins/adr-backend/README.md index 79b5fe13ed..225f07fdf7 100644 --- a/plugins/adr-backend/README.md +++ b/plugins/adr-backend/README.md @@ -4,6 +4,8 @@ This ADR backend plugin is primarily responsible for the following: - Provides a `DefaultAdrCollatorFactory`, which can be used in the search backend to index ADR documents associated with entities to your Backstage Search. +- Provides endpoints that use UrlReaders for getting ADR documents (used in the [ADR frontend plugin](../adr/README.md)). + ## Indexing ADR documents for search Before you are able to start indexing ADR documents to search, you need to go through the [search getting started guide](https://backstage.io/docs/features/search/getting-started). @@ -35,7 +37,7 @@ indexBuilder.addCollator({ ### Parsing custom ADR document formats -By default, the `DefaultAdrCollatorFactory` will parse and index documents that follow the [MADR](https://adr.github.io/madr/) standard file name and template format. If you use a different ADR format and file name convention, you can configure `DefaultAdrCollatorFactory` with custom `adrFilePathFilterFn` and `parser` options (see type definitions for details): +By default, the `DefaultAdrCollatorFactory` will parse and index documents that follow the [MADR v2.x standard file name and template format](https://github.com/adr/madr/tree/2.1.2). If you use a different ADR format and file name convention, you can configure `DefaultAdrCollatorFactory` with custom `adrFilePathFilterFn` and `parser` options (see type definitions for details): ```ts DefaultAdrCollatorFactory.fromConfig({ diff --git a/plugins/adr-backend/api-report.md b/plugins/adr-backend/api-report.md index 5a671e9c8f..d5645ad3a7 100644 --- a/plugins/adr-backend/api-report.md +++ b/plugins/adr-backend/api-report.md @@ -7,10 +7,12 @@ import { AdrDocument } from '@backstage/plugin-adr-common'; import { AdrFilePathFilterFn } from '@backstage/plugin-adr-common'; +import { CacheClient } from '@backstage/backend-common'; import { CatalogApi } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; import { Entity } from '@backstage/catalog-model'; +import express from 'express'; import { Logger } from 'winston'; import { PluginCacheManager } from '@backstage/backend-common'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; @@ -41,9 +43,21 @@ export type AdrParserContext = { path: string; }; +// @public (undocumented) +export type AdrRouterOptions = { + reader: UrlReader; + cacheClient: CacheClient; + logger: Logger; +}; + // @public export const createMadrParser: (options?: MadrParserOptions) => AdrParser; +// @public (undocumented) +export function createRouter( + options: AdrRouterOptions, +): Promise; + // @public export class DefaultAdrCollatorFactory implements DocumentCollatorFactory { // (undocumented) diff --git a/plugins/adr-backend/package.json b/plugins/adr-backend/package.json index 73f9309972..033441372a 100644 --- a/plugins/adr-backend/package.json +++ b/plugins/adr-backend/package.json @@ -36,6 +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", "luxon": "^3.0.0", "marked": "^4.0.14", "node-fetch": "^2.6.5", diff --git a/plugins/adr-backend/src/index.ts b/plugins/adr-backend/src/index.ts index 86e07943df..5cc8f50b72 100644 --- a/plugins/adr-backend/src/index.ts +++ b/plugins/adr-backend/src/index.ts @@ -21,3 +21,4 @@ */ export * from './search'; +export * from './service'; diff --git a/packages/backend-plugin-api/src/services/helpers/index.ts b/plugins/adr-backend/src/service/index.ts similarity index 86% rename from packages/backend-plugin-api/src/services/helpers/index.ts rename to plugins/adr-backend/src/service/index.ts index 24336c1af2..3736acb188 100644 --- a/packages/backend-plugin-api/src/services/helpers/index.ts +++ b/plugins/adr-backend/src/service/index.ts @@ -14,4 +14,5 @@ * limitations under the License. */ -export { loggerToWinstonLogger } from './loggerToWinstonLogger'; +export { createRouter } from './router'; +export type { AdrRouterOptions } from './router'; diff --git a/plugins/adr-backend/src/service/router.test.ts b/plugins/adr-backend/src/service/router.test.ts new file mode 100644 index 0000000000..fbbd6e8532 --- /dev/null +++ b/plugins/adr-backend/src/service/router.test.ts @@ -0,0 +1,229 @@ +/* + * 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 { + CacheClient, + ReadTreeResponse, + ReadTreeResponseFile, + ReadUrlResponse, + UrlReader, +} from '@backstage/backend-common'; +import express from 'express'; +import request from 'supertest'; +import { createRouter } from './router'; +import { Logger } from 'winston'; + +const listEndpointName = '/list'; +const fileEndpointName = '/file'; + +const makeBufferFromString = (string: string) => async () => + Buffer.from(string); + +const testingUrlFakeFileTree: ReadTreeResponseFile[] = [ + { + path: 'folder/testFile001.txt', + content: makeBufferFromString('folder/testFile001.txt content'), + }, + { + path: 'testFile001.txt', + content: makeBufferFromString('testFile002.txt content'), + }, + { + path: 'testFile002.txt', + content: makeBufferFromString('testFile001.txt content'), + }, +]; + +const makeFileContent = async (fileContent: string) => { + const result: ReadUrlResponse = { + buffer: makeBufferFromString(fileContent), + }; + return result; +}; + +const testFileOneContent = 'testFileOne content'; +const testFileTwoContent = 'testFileTwo content'; +const genericFileContent = 'file content'; + +const mockUrlReader: UrlReader = { + readUrl(url: string) { + switch (url) { + case 'testFileOne': + return makeFileContent(testFileOneContent); + case 'testFileTwo': + return makeFileContent(testFileTwoContent); + default: + return makeFileContent(genericFileContent); + } + }, + readTree() { + const result: ReadTreeResponse = { + files: async () => testingUrlFakeFileTree, + archive() { + throw new Error('Function not implemented.'); + }, + dir() { + throw new Error('Function not implemented.'); + }, + etag: '', + }; + + const resultPromise = async () => result; + return resultPromise(); + }, + search() { + throw new Error('search not implemented.'); + }, +}; + +class MockCacheClient implements CacheClient { + private itemRegistry: { [key: string]: any }; + + constructor() { + this.itemRegistry = {}; + } + + async get(key: string) { + return this.itemRegistry[key]; + } + + async set(key: string, value: any) { + this.itemRegistry[key] = value; + } + + async delete(key: string) { + delete this.itemRegistry[key]; + } +} + +describe('createRouter', () => { + let app: express.Express; + + beforeEach(async () => { + jest.resetAllMocks(); + + const router = await createRouter({ + reader: mockUrlReader, + cacheClient: new MockCacheClient(), + logger: { + error: (message: any) => message, + } as Logger, + }); + app = express().use(router); + }); + + describe(`GET ${listEndpointName}`, () => { + it('returns bad request (400) when no url is provided', async () => { + const urlNotSpecifiedRequest = await request(app).get(listEndpointName); + const urlNotSpecifiedStatus = urlNotSpecifiedRequest.status; + const urlNotSpecifiedMessage = urlNotSpecifiedRequest.body.message; + + const urlNotFilledRequest = await request(app).get( + `${listEndpointName}?url=`, + ); + const urlNotFilledStatus = urlNotFilledRequest.status; + const urlNotFilledMessage = urlNotFilledRequest.body.message; + + const expectedStatusCode = 400; + const expectedErrorMessage = 'No URL provided'; + + expect(urlNotSpecifiedStatus).toBe(expectedStatusCode); + expect(urlNotSpecifiedMessage).toBe(expectedErrorMessage); + + expect(urlNotFilledStatus).toBe(expectedStatusCode); + expect(urlNotFilledMessage).toBe(expectedErrorMessage); + }); + + it('returns the correct listing when reading a url', async () => { + const result = await request(app).get(`${listEndpointName}?url=testing`); + const { status, body, error } = result; + + const expectedStatusCode = 200; + const expectedBody = { + data: [ + { + type: 'file', + name: 'testFile001.txt', + path: 'folder/testFile001.txt', + }, + { + type: 'file', + name: 'testFile001.txt', + path: 'testFile001.txt', + }, + { + type: 'file', + name: 'testFile002.txt', + path: 'testFile002.txt', + }, + ], + }; + + expect(error).toBeFalsy(); + expect(status).toBe(expectedStatusCode); + expect(body).toEqual(expectedBody); + }); + }); + + describe(`GET ${fileEndpointName}`, () => { + it('returns bad request (400) when no url is provided', async () => { + const urlNotSpecifiedRequest = await request(app).get(fileEndpointName); + const urlNotSpecifiedStatus = urlNotSpecifiedRequest.status; + const urlNotSpecifiedMessage = urlNotSpecifiedRequest.body.message; + + const urlNotFilledRequest = await request(app).get( + `${fileEndpointName}?url=`, + ); + const urlNotFilledStatus = urlNotFilledRequest.status; + const urlNotFilledMessage = urlNotFilledRequest.body.message; + + const expectedStatusCode = 400; + const expectedErrorMessage = 'No URL provided'; + + expect(urlNotSpecifiedStatus).toBe(expectedStatusCode); + expect(urlNotSpecifiedMessage).toBe(expectedErrorMessage); + + expect(urlNotFilledStatus).toBe(expectedStatusCode); + expect(urlNotFilledMessage).toBe(expectedErrorMessage); + }); + + it('returns the correct file contents when reading a url', async () => { + const fileOneResponse = await request(app).get( + `${fileEndpointName}?url=testFileOne`, + ); + const fileOneStatus = fileOneResponse.status; + const fileOneBody = fileOneResponse.body; + const fileOneError = fileOneResponse.error; + + const fileTwoResponse = await request(app).get( + `${fileEndpointName}?url=testFileTwo`, + ); + const fileTwoStatus = fileTwoResponse.status; + const fileTwoBody = fileTwoResponse.body; + const fileTwoError = fileTwoResponse.error; + + const expectedStatusCode = 200; + + expect(fileOneError).toBeFalsy(); + expect(fileOneStatus).toBe(expectedStatusCode); + expect(fileOneBody.data).toBe(testFileOneContent); + + expect(fileTwoError).toBeFalsy(); + expect(fileTwoStatus).toBe(expectedStatusCode); + expect(fileTwoBody.data).toBe(testFileTwoContent); + }); + }); +}); diff --git a/plugins/adr-backend/src/service/router.ts b/plugins/adr-backend/src/service/router.ts new file mode 100644 index 0000000000..e6603ab346 --- /dev/null +++ b/plugins/adr-backend/src/service/router.ts @@ -0,0 +1,129 @@ +/* + * 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 { CacheClient, UrlReader } from '@backstage/backend-common'; +import { NotModifiedError, stringifyError } from '@backstage/errors'; +import { Logger } from 'winston'; +import express from 'express'; +import Router from 'express-promise-router'; + +/** @public */ +export type AdrRouterOptions = { + reader: UrlReader; + cacheClient: CacheClient; + logger: Logger; +}; + +/** @public */ +export async function createRouter( + options: AdrRouterOptions, +): Promise { + const { reader, cacheClient, logger } = options; + + const router = Router(); + router.use(express.json()); + + router.get('/list', async (req, res) => { + const urlToProcess = req.query.url as string; + if (!urlToProcess) { + res.statusCode = 400; + res.json({ message: 'No URL provided' }); + return; + } + + const cachedTree = (await cacheClient.get(urlToProcess)) as { + data: { + type: string; + name: string; + path: string; + }[]; + etag: string; + }; + const cachedData = cachedTree?.data; + + try { + const treeGetResponse = await reader.readTree(urlToProcess, { + 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, + }; + }); + + await cacheClient.set(urlToProcess, { + data, + etag: treeGetResponse.etag, + }); + + res.json({ data }); + } catch (error: any) { + if (cachedData && error.name === NotModifiedError.name) { + res.json({ data: cachedData }); + return; + } + + const message = stringifyError(error); + logger.error(`Unable to fetch ADRs from ${urlToProcess}: ${message}`); + res.statusCode = 500; + res.json({ message }); + } + }); + + router.get('/file', async (req, res) => { + const urlToProcess = req.query.url as string; + if (!urlToProcess) { + res.statusCode = 400; + res.json({ message: 'No URL provided' }); + return; + } + + const cachedFileContent = (await cacheClient.get(urlToProcess)) as { + data: string; + etag: string; + }; + + try { + const fileGetResponse = await reader.readUrl(urlToProcess, { + etag: cachedFileContent?.etag, + }); + const fileBuffer = await fileGetResponse.buffer(); + const data = fileBuffer.toString(); + + await cacheClient.set(urlToProcess, { + data, + etag: fileGetResponse.etag, + }); + + res.json({ data }); + } catch (error) { + if (cachedFileContent && error.name === NotModifiedError.name) { + res.json({ data: cachedFileContent.data }); + return; + } + + const message = stringifyError(error); + logger.error(`Unable to fetch ADRs from ${urlToProcess}: ${message}`); + res.statusCode = 500; + res.json({ message }); + } + }); + + return router; +} diff --git a/plugins/adr/README.md b/plugins/adr/README.md index 2888ff2f07..b9cc5d84ba 100644 --- a/plugins/adr/README.md +++ b/plugins/adr/README.md @@ -4,17 +4,19 @@ 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. -NOTE: This plugin currently only supports entities/ADRs registered via GitHub integration. - ## Setup -Install this plugin: +1. Install this plugin: ```bash # From your Backstage root directory yarn --cwd packages/app add @backstage/plugin-adr ``` +2. Make sure the [ADR backend plugin](../adr-backend/README.md) is installed. + +3. [Configure integrations](https://backstage.io/docs/integrations/) for all sites you would like to pull ADRs from. + ### Entity Pages 1. Add the plugin as a tab to your Entity pages: @@ -79,7 +81,7 @@ case 'adr': ## Custom ADR formats -By default, this plugin will parse ADRs according to the format specified by the [Markdown Architecture Decision Record (MADR)](https://adr.github.io/madr/) template. If your ADRs are written using a different format, you can apply the following customizations to correctly identify and parse your documents: +By default, this plugin will parse ADRs according to the format specified by the [Markdown Architecture Decision Record (MADR) v2.x template](https://github.com/adr/madr/tree/2.1.2). If your ADRs are written using a different format, you can apply the following customizations to correctly identify and parse your documents: ### Custom Filename/Path Format diff --git a/plugins/adr/api-report.md b/plugins/adr/api-report.md index ecec0c0dd5..d6480cd090 100644 --- a/plugins/adr/api-report.md +++ b/plugins/adr/api-report.md @@ -7,11 +7,37 @@ import { AdrDocument } from '@backstage/plugin-adr-common'; import { AdrFilePathFilterFn } from '@backstage/plugin-adr-common'; +import { ApiRef } from '@backstage/core-plugin-api'; import { BackstagePlugin } from '@backstage/core-plugin-api'; +import { DiscoveryApi } from '@backstage/core-plugin-api'; import { isAdrAvailable } from '@backstage/plugin-adr-common'; import { ResultHighlight } from '@backstage/plugin-search-common'; import { RouteRef } from '@backstage/core-plugin-api'; +// @public +export interface AdrApi { + listAdrs(url: string): Promise; + readAdr(url: string): Promise; +} + +// @public +export const adrApiRef: ApiRef; + +// @public +export class AdrClient implements AdrApi { + constructor(options: AdrClientOptions); + // (undocumented) + listAdrs(url: string): Promise; + // (undocumented) + readAdr(url: string): Promise; +} + +// @public +export interface AdrClientOptions { + // (undocumented) + discoveryApi: DiscoveryApi; +} + // @public export type AdrContentDecorator = (adrInfo: { baseUrl: string; @@ -20,6 +46,18 @@ export type AdrContentDecorator = (adrInfo: { content: string; }; +// @public +export type AdrFileInfo = { + type: string; + path: string; + name: string; +}; + +// @public +export type AdrListResult = { + data: AdrFileInfo[]; +}; + // @public export const adrPlugin: BackstagePlugin< { @@ -38,6 +76,11 @@ export const AdrReader: { }>; }; +// @public +export type AdrReadResult = { + data: string; +}; + // @public export function AdrSearchResultListItem(props: { lineClamp?: number; diff --git a/plugins/adr/package.json b/plugins/adr/package.json index 00cf052365..30d0b846a3 100644 --- a/plugins/adr/package.json +++ b/plugins/adr/package.json @@ -34,8 +34,6 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", - "git-url-parse": "^13.0.0", - "octokit": "^2.0.0", "react-markdown": "^8.0.0", "react-use": "^17.2.4", "remark-gfm": "^3.0.1" diff --git a/plugins/adr/src/api/AdrClient.ts b/plugins/adr/src/api/AdrClient.ts new file mode 100644 index 0000000000..da1adc04e4 --- /dev/null +++ b/plugins/adr/src/api/AdrClient.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 { DiscoveryApi } from '@backstage/core-plugin-api'; +import { AdrApi, AdrListResult, AdrReadResult } from './types'; + +/** + * Options for creating an AdrClient. + * + * @public + */ +export interface AdrClientOptions { + discoveryApi: DiscoveryApi; +} + +const readEndpoint = 'file'; +const listEndpoint = 'list'; + +/** + * An implementation of the AdrApi that communicates with the ADR backend plugin. + * + * @public + */ +export class AdrClient implements AdrApi { + private readonly discoveryApi: DiscoveryApi; + + constructor(options: AdrClientOptions) { + this.discoveryApi = options.discoveryApi; + } + + private async fetchAdrApi(endpoint: string, fileUrl: string): Promise { + const baseUrl = await this.discoveryApi.getBaseUrl('adr'); + const targetUrl = `${baseUrl}/${endpoint}?url=${encodeURIComponent( + fileUrl, + )}`; + + const result = await fetch(targetUrl); + const data = await result.json(); + + if (!result.ok) { + throw new Error(`${data.message}`); + } + return data; + } + + async listAdrs(url: string): Promise { + return this.fetchAdrApi(listEndpoint, url); + } + + async readAdr(url: string): Promise { + return this.fetchAdrApi(readEndpoint, url); + } +} diff --git a/plugins/adr/src/api/index.ts b/plugins/adr/src/api/index.ts new file mode 100644 index 0000000000..095da3519d --- /dev/null +++ b/plugins/adr/src/api/index.ts @@ -0,0 +1,25 @@ +/* + * 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 { AdrClient } from './AdrClient'; +export type { AdrClientOptions } from './AdrClient'; +export { adrApiRef } from './types'; +export type { + AdrApi, + AdrFileInfo, + AdrListResult, + AdrReadResult, +} from './types'; diff --git a/plugins/adr/src/api/types.ts b/plugins/adr/src/api/types.ts new file mode 100644 index 0000000000..e4632e171a --- /dev/null +++ b/plugins/adr/src/api/types.ts @@ -0,0 +1,74 @@ +/* + * 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'; + +/** + * Contains information about an ADR file. + * + * @public + */ +export type AdrFileInfo = { + /** The file type. */ + type: string; + + /** The relative path of the ADR file. */ + path: string; + + /** The name of the ADR file. */ + name: string; +}; + +/** + * The result of listing ADRs. + * + * @public + */ +export type AdrListResult = { + data: AdrFileInfo[]; +}; + +/** + * The result of reading an ADR. + * + * @public + */ +export type AdrReadResult = { + /** The contents of the read ADR file. */ + data: string; +}; + +/** + * The API used by the adr plugin to list and read ADRs. + * + * @public + */ +export interface AdrApi { + /** Lists the ADRs at the provided url. */ + listAdrs(url: string): Promise; + + /** Reads the contents of the ADR at the provided url. */ + readAdr(url: string): Promise; +} + +/** + * ApiRef for the AdrApi. + * + * @public + */ +export const adrApiRef = createApiRef({ + id: 'plugin.adr.api', +}); diff --git a/plugins/adr/src/components/AdrReader/AdrReader.tsx b/plugins/adr/src/components/AdrReader/AdrReader.tsx index 971dae0949..ad99ce3a5a 100644 --- a/plugins/adr/src/components/AdrReader/AdrReader.tsx +++ b/plugins/adr/src/components/AdrReader/AdrReader.tsx @@ -26,9 +26,10 @@ import { scmIntegrationsApiRef } from '@backstage/integration-react'; import { getAdrLocationUrl } from '@backstage/plugin-adr-common'; import { useEntity } from '@backstage/plugin-catalog-react'; -import { useOctokitRequest } from '../../hooks'; import { adrDecoratorFactories } from './decorators'; import { AdrContentDecorator } from './types'; +import { adrApiRef } from '../../api'; +import useAsync from 'react-use/lib/useAsync'; /** * Component to fetch and render an ADR. @@ -42,10 +43,13 @@ export const AdrReader = (props: { const { adr, decorators } = props; const { entity } = useEntity(); const scmIntegrations = useApi(scmIntegrationsApiRef); + const adrApi = useApi(adrApiRef); const adrLocationUrl = getAdrLocationUrl(entity, scmIntegrations); - const { value, loading, error } = useOctokitRequest( - `${adrLocationUrl.replace(/\/$/, '')}/${adr}`, + const url = `${adrLocationUrl.replace(/\/$/, '')}/${adr}`; + const { value, loading, error } = useAsync( + async () => adrApi.readAdr(url), + [url], ); const adrContent = useMemo(() => { diff --git a/plugins/adr/src/components/EntityAdrContent/EntityAdrContent.tsx b/plugins/adr/src/components/EntityAdrContent/EntityAdrContent.tsx index 37344cecca..a698cffd26 100644 --- a/plugins/adr/src/components/EntityAdrContent/EntityAdrContent.tsx +++ b/plugins/adr/src/components/EntityAdrContent/EntityAdrContent.tsx @@ -44,9 +44,10 @@ import { Typography, } from '@material-ui/core'; -import { useOctokitRequest } from '../../hooks'; import { rootRouteRef } from '../../routes'; import { AdrContentDecorator, AdrReader } from '../AdrReader'; +import { adrApiRef } from '../../api'; +import useAsync from 'react-use/lib/useAsync'; const useStyles = makeStyles((theme: Theme) => ({ adrMenu: { @@ -69,10 +70,13 @@ export const EntityAdrContent = (props: { const [adrList, setAdrList] = useState([]); const [searchParams, setSearchParams] = useSearchParams(); const scmIntegrations = useApi(scmIntegrationsApiRef); + const adrApi = useApi(adrApiRef); const entityHasAdrs = isAdrAvailable(entity); - const { value, loading, error } = useOctokitRequest( - getAdrLocationUrl(entity, scmIntegrations), + const url = getAdrLocationUrl(entity, scmIntegrations); + const { value, loading, error } = useAsync( + async () => adrApi.listAdrs(url), + [url], ); const selectedAdr = diff --git a/plugins/adr/src/hooks/useOctokitRequest.ts b/plugins/adr/src/hooks/useOctokitRequest.ts deleted file mode 100644 index f160651169..0000000000 --- a/plugins/adr/src/hooks/useOctokitRequest.ts +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import parseGitUrl from 'git-url-parse'; -import useAsync from 'react-use/lib/useAsync'; -import { Octokit } from 'octokit'; -import { useApi } from '@backstage/core-plugin-api'; -import { - scmAuthApiRef, - scmIntegrationsApiRef, -} from '@backstage/integration-react'; - -/** - * Hook for triggering authenticated Octokit requests against the GitHub Content API - * @public - */ -export const useOctokitRequest = (request: string): any => { - const authApi = useApi(scmAuthApiRef); - const scmIntegrations = useApi(scmIntegrationsApiRef); - - const { owner, name, ref, filepath } = parseGitUrl(request); - const path = filepath.replace(/^\//, ''); - const baseUrl = scmIntegrations.github.byUrl(request)?.config.apiBaseUrl; - - return useAsync(async () => { - const { token } = await authApi.getCredentials({ - url: request, - additionalScope: { - customScopes: { - github: ['repo'], - }, - }, - }); - const octokit = new Octokit({ - auth: token, - baseUrl, - }); - - return octokit.request( - `GET /repos/${owner}/${name}/contents/${path}?ref=${ref}`, - { - headers: { Accept: 'application/vnd.github.v3.raw' }, - }, - ); - }, [request]); -}; diff --git a/plugins/adr/src/index.ts b/plugins/adr/src/index.ts index 84012ccb7a..2ec76b0fd6 100644 --- a/plugins/adr/src/index.ts +++ b/plugins/adr/src/index.ts @@ -13,11 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + /** * ADR frontend plugin * * @packageDocumentation */ + +export { adrApiRef, AdrClient } from './api'; +export type { + AdrApi, + AdrClientOptions, + AdrFileInfo, + AdrListResult, + AdrReadResult, +} from './api'; export { isAdrAvailable } from '@backstage/plugin-adr-common'; export * from './components/AdrReader'; export { adrPlugin, EntityAdrContent } from './plugin'; diff --git a/plugins/adr/src/plugin.ts b/plugins/adr/src/plugin.ts index 03437b1f0b..f23df826cd 100644 --- a/plugins/adr/src/plugin.ts +++ b/plugins/adr/src/plugin.ts @@ -14,11 +14,13 @@ * limitations under the License. */ +import { adrApiRef, AdrClient } from './api'; import { + createApiFactory, createPlugin, createRoutableExtension, + discoveryApiRef, } from '@backstage/core-plugin-api'; - import { rootRouteRef } from './routes'; /** @@ -27,6 +29,17 @@ import { rootRouteRef } from './routes'; */ export const adrPlugin = createPlugin({ id: 'adr', + apis: [ + createApiFactory({ + api: adrApiRef, + deps: { + discoveryApi: discoveryApiRef, + }, + factory({ discoveryApi }) { + return new AdrClient({ discoveryApi }); + }, + }), + ], routes: { root: rootRouteRef, }, diff --git a/plugins/app-backend/src/service/appPlugin.test.ts b/plugins/app-backend/src/service/appPlugin.test.ts index 14921622c9..80408694d6 100644 --- a/plugins/app-backend/src/service/appPlugin.test.ts +++ b/plugins/app-backend/src/service/appPlugin.test.ts @@ -23,6 +23,7 @@ import { appPlugin } from './appPlugin'; import { databaseFactory, httpRouterFactory, + rootHttpRouterFactory, loggerFactory, rootLoggerFactory, } from '@backstage/backend-app-api'; @@ -63,6 +64,7 @@ describe('appPlugin', () => { rootLoggerFactory(), databaseFactory(), httpRouterFactory(), + rootHttpRouterFactory(), ], features: [ appPlugin({ diff --git a/plugins/app-backend/src/service/appPlugin.ts b/plugins/app-backend/src/service/appPlugin.ts index bfccf3cc02..2c0c73c71b 100644 --- a/plugins/app-backend/src/service/appPlugin.ts +++ b/plugins/app-backend/src/service/appPlugin.ts @@ -18,9 +18,9 @@ import express from 'express'; import { coreServices, createBackendPlugin, - loggerToWinstonLogger, } from '@backstage/backend-plugin-api'; import { createRouter } from './router'; +import { loggerToWinstonLogger } from '@backstage/backend-common'; /** @alpha */ export type AppPluginOptions = { diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index cec3422d9c..88cb33863e 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -7,7 +7,7 @@ import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; import { BackstageSignInResult } from '@backstage/plugin-auth-node'; -import { CacheClient } from '@backstage/backend-common'; +import { CacheClient } from '@backstage/backend-plugin-api'; import { CatalogApi } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; import { Entity } from '@backstage/catalog-model'; diff --git a/plugins/bitbucket-cloud-common/package.json b/plugins/bitbucket-cloud-common/package.json index 1ea48b000e..985949c836 100644 --- a/plugins/bitbucket-cloud-common/package.json +++ b/plugins/bitbucket-cloud-common/package.json @@ -34,7 +34,7 @@ "@backstage/cli": "workspace:^", "@openapitools/openapi-generator-cli": "^2.4.26", "msw": "^0.49.0", - "ts-morph": "^15.0.0" + "ts-morph": "^17.0.0" }, "files": [ "dist" diff --git a/plugins/catalog-backend-module-aws/src/service/AwsS3EntityProviderCatalogModule.ts b/plugins/catalog-backend-module-aws/src/service/AwsS3EntityProviderCatalogModule.ts index fa49d1e4c7..cbc137ab40 100644 --- a/plugins/catalog-backend-module-aws/src/service/AwsS3EntityProviderCatalogModule.ts +++ b/plugins/catalog-backend-module-aws/src/service/AwsS3EntityProviderCatalogModule.ts @@ -14,10 +14,10 @@ * limitations under the License. */ +import { loggerToWinstonLogger } from '@backstage/backend-common'; import { coreServices, createBackendModule, - loggerToWinstonLogger, } from '@backstage/backend-plugin-api'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; import { AwsS3EntityProvider } 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 0d0ebdb591..bd59cec29b 100644 --- a/plugins/catalog-backend-module-azure/src/service/AzureDevOpsEntityProviderCatalogModule.ts +++ b/plugins/catalog-backend-module-azure/src/service/AzureDevOpsEntityProviderCatalogModule.ts @@ -14,9 +14,9 @@ * limitations under the License. */ +import { loggerToWinstonLogger } from '@backstage/backend-common'; import { createBackendModule, - loggerToWinstonLogger, coreServices, } from '@backstage/backend-plugin-api'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; 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 19b83b92b6..d17656a473 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.ts +++ b/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.ts @@ -14,10 +14,10 @@ * limitations under the License. */ +import { loggerToWinstonLogger } from '@backstage/backend-common'; import { coreServices, createBackendModule, - loggerToWinstonLogger, } from '@backstage/backend-plugin-api'; import { catalogProcessingExtensionPoint, 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 e0f5a21ff9..46712d29dd 100644 --- a/plugins/catalog-backend-module-bitbucket-server/src/service/BitbucketServerEntityProviderCatalogModule.ts +++ b/plugins/catalog-backend-module-bitbucket-server/src/service/BitbucketServerEntityProviderCatalogModule.ts @@ -14,10 +14,10 @@ * limitations under the License. */ +import { loggerToWinstonLogger } from '@backstage/backend-common'; import { coreServices, createBackendModule, - loggerToWinstonLogger, } from '@backstage/backend-plugin-api'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; import { BitbucketServerEntityProvider } from '../providers'; diff --git a/plugins/catalog-backend-module-gerrit/src/service/GerritEntityProviderCatalogModule.ts b/plugins/catalog-backend-module-gerrit/src/service/GerritEntityProviderCatalogModule.ts index 674845862f..8c61038c8f 100644 --- a/plugins/catalog-backend-module-gerrit/src/service/GerritEntityProviderCatalogModule.ts +++ b/plugins/catalog-backend-module-gerrit/src/service/GerritEntityProviderCatalogModule.ts @@ -14,10 +14,10 @@ * limitations under the License. */ +import { loggerToWinstonLogger } from '@backstage/backend-common'; import { coreServices, createBackendModule, - loggerToWinstonLogger, } from '@backstage/backend-plugin-api'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; import { GerritEntityProvider } from '../providers/GerritEntityProvider'; diff --git a/plugins/catalog-backend-module-github/src/service/GithubEntityProviderCatalogModule.ts b/plugins/catalog-backend-module-github/src/service/GithubEntityProviderCatalogModule.ts index e61543ea13..d9dc0a12aa 100644 --- a/plugins/catalog-backend-module-github/src/service/GithubEntityProviderCatalogModule.ts +++ b/plugins/catalog-backend-module-github/src/service/GithubEntityProviderCatalogModule.ts @@ -16,9 +16,9 @@ import { createBackendModule, - loggerToWinstonLogger, coreServices, } from '@backstage/backend-plugin-api'; +import { loggerToWinstonLogger } from '@backstage/backend-common'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; import { GithubEntityProvider } from '../providers/GithubEntityProvider'; diff --git a/plugins/catalog-backend-module-gitlab/src/service/GitlabDiscoveryEntityProviderCatalogModule.ts b/plugins/catalog-backend-module-gitlab/src/service/GitlabDiscoveryEntityProviderCatalogModule.ts index 75a8de263f..bb4fb656a8 100644 --- a/plugins/catalog-backend-module-gitlab/src/service/GitlabDiscoveryEntityProviderCatalogModule.ts +++ b/plugins/catalog-backend-module-gitlab/src/service/GitlabDiscoveryEntityProviderCatalogModule.ts @@ -16,9 +16,9 @@ import { createBackendModule, - loggerToWinstonLogger, coreServices, } from '@backstage/backend-plugin-api'; +import { loggerToWinstonLogger } from '@backstage/backend-common'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; import { GitlabDiscoveryEntityProvider } from '../providers'; diff --git a/plugins/catalog-backend-module-incremental-ingestion/src/module/WrapperProviders.ts b/plugins/catalog-backend-module-incremental-ingestion/src/module/WrapperProviders.ts index a6cfe14df2..abe4cdb951 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/src/module/WrapperProviders.ts +++ b/plugins/catalog-backend-module-incremental-ingestion/src/module/WrapperProviders.ts @@ -18,8 +18,8 @@ import { ConfigService, LoggerService, SchedulerService, - loggerToWinstonLogger, } from '@backstage/backend-plugin-api'; +import { loggerToWinstonLogger } from '@backstage/backend-common'; import { stringifyError } from '@backstage/errors'; import { EntityProvider, diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index 5bfe4e35ea..4ff9952bc5 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -34,6 +34,7 @@ }, "dependencies": { "@azure/identity": "^2.1.0", + "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/backend-tasks": "workspace:^", "@backstage/catalog-model": "workspace:^", diff --git a/plugins/catalog-backend-module-msgraph/src/service/MicrosoftGraphOrgEntityProviderCatalogModule.ts b/plugins/catalog-backend-module-msgraph/src/service/MicrosoftGraphOrgEntityProviderCatalogModule.ts index 2643e6e937..fc63867a23 100644 --- a/plugins/catalog-backend-module-msgraph/src/service/MicrosoftGraphOrgEntityProviderCatalogModule.ts +++ b/plugins/catalog-backend-module-msgraph/src/service/MicrosoftGraphOrgEntityProviderCatalogModule.ts @@ -17,8 +17,8 @@ import { coreServices, createBackendModule, - loggerToWinstonLogger, } from '@backstage/backend-plugin-api'; +import { loggerToWinstonLogger } from '@backstage/backend-common'; import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; import { GroupTransformer, diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index b45918dc43..93a5846bbf 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -80,7 +80,7 @@ "@types/lodash": "^4.14.151", "@types/supertest": "^2.0.8", "@types/uuid": "^8.0.0", - "better-sqlite3": "^7.5.0", + "better-sqlite3": "^8.0.0", "luxon": "^3.0.0", "msw": "^0.49.0", "supertest": "^6.1.3", diff --git a/plugins/catalog-backend/src/service/CatalogPlugin.ts b/plugins/catalog-backend/src/service/CatalogPlugin.ts index 6db54ed4fa..effed7f8f1 100644 --- a/plugins/catalog-backend/src/service/CatalogPlugin.ts +++ b/plugins/catalog-backend/src/service/CatalogPlugin.ts @@ -16,7 +16,6 @@ import { createBackendPlugin, coreServices, - loggerToWinstonLogger, } from '@backstage/backend-plugin-api'; import { CatalogBuilder } from './CatalogBuilder'; import { @@ -25,6 +24,7 @@ import { catalogProcessingExtensionPoint, EntityProvider, } from '@backstage/plugin-catalog-node'; +import { loggerToWinstonLogger } from '@backstage/backend-common'; class CatalogExtensionPointImpl implements CatalogProcessingExtensionPoint { #processors = new Array(); diff --git a/plugins/catalog-backend/src/service/createRouter.test.ts b/plugins/catalog-backend/src/service/createRouter.test.ts index 541359feb6..6379d65043 100644 --- a/plugins/catalog-backend/src/service/createRouter.test.ts +++ b/plugins/catalog-backend/src/service/createRouter.test.ts @@ -268,6 +268,8 @@ describe('createRouter readonly disabled', () => { '{"unknown":7}', '{"entityRefs":7}', '{"entityRefs":[7]}', + '{"entityRefs":[7],"fields":7}', + '{"entityRefs":[7],"fields":[7]}', ])('properly rejects malformed request body, %p', async p => { await expect( request(app) @@ -283,8 +285,12 @@ describe('createRouter readonly disabled', () => { const response = await request(app) .post('/entities/by-refs') .set('Content-Type', 'application/json') - .send('{"entityRefs":["a"]}'); + .send('{"entityRefs":["a"],"fields":["b"]}'); expect(entitiesCatalog.entitiesBatch).toHaveBeenCalledTimes(1); + expect(entitiesCatalog.entitiesBatch).toHaveBeenCalledWith({ + entityRefs: ['a'], + fields: expect.any(Function), + }); expect(response.status).toEqual(200); expect(response.body).toEqual({ items: [entity] }); }); diff --git a/plugins/catalog-backend/src/service/createRouter.ts b/plugins/catalog-backend/src/service/createRouter.ts index 6a31fcd0b6..62a0f970c9 100644 --- a/plugins/catalog-backend/src/service/createRouter.ts +++ b/plugins/catalog-backend/src/service/createRouter.ts @@ -181,7 +181,7 @@ export async function createRouter( const token = getBearerToken(req.header('authorization')); const response = await entitiesCatalog.entitiesBatch({ entityRefs: request.entityRefs, - fields: parseEntityTransformParams(req.query), + fields: parseEntityTransformParams(req.query, request.fields), authorizationToken: token, }); res.status(200).json(response); diff --git a/plugins/catalog-backend/src/service/request/entitiesBatchRequest.ts b/plugins/catalog-backend/src/service/request/entitiesBatchRequest.ts index b3a91f9491..d5469315be 100644 --- a/plugins/catalog-backend/src/service/request/entitiesBatchRequest.ts +++ b/plugins/catalog-backend/src/service/request/entitiesBatchRequest.ts @@ -20,9 +20,10 @@ import { z } from 'zod'; const schema = z.object({ entityRefs: z.array(z.string()), + fields: z.array(z.string()).optional(), }); -export function entitiesBatchRequest(req: Request) { +export function entitiesBatchRequest(req: Request): z.infer { try { return schema.parse(req.body); } catch (error) { diff --git a/plugins/catalog-backend/src/service/request/parseEntityTransformParams.test.ts b/plugins/catalog-backend/src/service/request/parseEntityTransformParams.test.ts index 3dce579ae5..16141e401c 100644 --- a/plugins/catalog-backend/src/service/request/parseEntityTransformParams.test.ts +++ b/plugins/catalog-backend/src/service/request/parseEntityTransformParams.test.ts @@ -18,22 +18,26 @@ import { Entity } from '@backstage/catalog-model'; import { parseEntityTransformParams } from './parseEntityTransformParams'; describe('parseEntityTransformParams', () => { - const entity: Entity = { - apiVersion: 'av', - kind: 'k', - metadata: { - name: 'n', - tags: ['t1', 't2'], - annotations: { - 'example.test/url-like-key': 'ul1', - 'example.com/other-url-like-key': 'ul2', - 'other-example.test/next-url-like-key': 'ul3', + let entity: Entity; + + beforeEach(() => { + entity = { + apiVersion: 'av', + kind: 'k', + metadata: { + name: 'n', + tags: ['t1', 't2'], + annotations: { + 'example.test/url-like-key': 'ul1', + 'example.com/other-url-like-key': 'ul2', + 'other-example.test/next-url-like-key': 'ul3', + }, }, - }, - spec: { - type: 't', - }, - }; + spec: { + type: 't', + }, + }; + }); it('returns undefined when no fields given', () => { expect(parseEntityTransformParams({})).toBeUndefined(); @@ -46,7 +50,9 @@ describe('parseEntityTransformParams', () => { it('rejects attempts at array filtering', () => { expect(() => parseEntityTransformParams({ fields: 'metadata.tags[0]' })!(entity), - ).toThrow(/invalid fields, array type fields are not supported/i); + ).toThrow( + 'Invalid field "metadata.tags[0]", array type fields are not supported', + ); }); it('accepts both strings and arrays of strings as input', () => { @@ -177,4 +183,18 @@ describe('parseEntityTransformParams', () => { ), ).toEqual({ kind: 'k' }); }); + + it('handles both query params and extras, dealing with overlaps', () => { + expect( + parseEntityTransformParams({ fields: 'kind' }, [ + 'kind', + 'metadata.name', + ])!(entity), + ).toEqual({ + kind: 'k', + metadata: { + name: 'n', + }, + }); + }); }); diff --git a/plugins/catalog-backend/src/service/request/parseEntityTransformParams.ts b/plugins/catalog-backend/src/service/request/parseEntityTransformParams.ts index cef6e5ef64..e203450103 100644 --- a/plugins/catalog-backend/src/service/request/parseEntityTransformParams.ts +++ b/plugins/catalog-backend/src/service/request/parseEntityTransformParams.ts @@ -38,24 +38,28 @@ function getPathArrayAndValue(input: Entity, field: string) { export function parseEntityTransformParams( params: Record, + extra?: string[], ): ((entity: Entity) => Entity) | undefined { - const fieldsStrings = parseStringsParam(params.fields, 'fields'); - if (!fieldsStrings) { - return undefined; - } + const queryFields = parseStringsParam(params.fields, 'fields'); - const fields = fieldsStrings - .map(s => s.split(',')) - .flat() - .map(s => s.trim()) - .filter(Boolean); + const fields = Array.from( + new Set( + [...(extra ?? []), ...(queryFields?.map(s => s.split(',')) ?? [])] + .flat() + .map(s => s.trim()) + .filter(Boolean), + ), + ); if (!fields.length) { return undefined; } - if (fields.some(f => f.includes('['))) { - throw new InputError('invalid fields, array type fields are not supported'); + const arrayTypeField = fields.find(f => f.includes('[')); + if (arrayTypeField) { + throw new InputError( + `Invalid field "${arrayTypeField}", array type fields are not supported`, + ); } return input => { diff --git a/plugins/catalog-import/api-report.md b/plugins/catalog-import/api-report.md index 90c01255b0..b4c8e854aa 100644 --- a/plugins/catalog-import/api-report.md +++ b/plugins/catalog-import/api-report.md @@ -193,7 +193,7 @@ export interface ImportInfoCardProps { } // Warning: (ae-forgotten-export) The symbol "State" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ImportState" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "ImportState" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type ImportState = State & { @@ -346,7 +346,7 @@ export interface StepPrepareCreatePullRequestProps { notRepeatable?: boolean; }, ) => void; - // Warning: (ae-forgotten-export) The symbol "FormData" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "FormData_2" needs to be exported by the entry point index.d.ts // // (undocumented) renderFormFields: ( diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md index 92bfc4de96..9528c55326 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/api-report.md @@ -254,6 +254,17 @@ export class EntityOwnerFilter implements EntityFilter { // @public (undocumented) export const EntityOwnerPicker: () => JSX.Element | null; +// @public +export const EntityPeekAheadPopover: ( + props: EntityPeekAheadPopoverProps, +) => JSX.Element; + +// @public +export type EntityPeekAheadPopoverProps = PropsWithChildren<{ + entityRef: string; + delayTime?: number; +}>; + // @public (undocumented) export const EntityProcessingStatusPicker: () => JSX.Element; diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index 9c9757f161..14a3ce8df5 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -51,6 +51,7 @@ "classnames": "^2.2.6", "jwt-decode": "^3.1.0", "lodash": "^4.17.21", + "material-ui-popup-state": "^1.9.3", "qs": "^6.9.4", "react-use": "^17.2.4", "yaml": "^2.0.0", diff --git a/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/EmailCardAction.tsx b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/EmailCardAction.tsx new file mode 100644 index 0000000000..2fcb89eed1 --- /dev/null +++ b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/EmailCardAction.tsx @@ -0,0 +1,38 @@ +/* + * 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 { IconButton } from '@material-ui/core'; +import EmailIcon from '@material-ui/icons/Email'; +import React from 'react'; +import { Link } from '@backstage/core-components'; + +/** + * Email Card action link + * + * @private + */ +export const EmailCardAction = ({ email }: { email: string }) => { + return ( + + + + ); +}; diff --git a/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/EntityCardActions.tsx b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/EntityCardActions.tsx new file mode 100644 index 0000000000..fc8b5f4007 --- /dev/null +++ b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/EntityCardActions.tsx @@ -0,0 +1,46 @@ +/* + * 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 { entityRouteRef } from '../../../routes'; +import { IconButton } from '@material-ui/core'; +import InfoIcon from '@material-ui/icons/Info'; +import React from 'react'; +import { useRouteRef } from '@backstage/core-plugin-api'; +import { Entity } from '@backstage/catalog-model'; +import { Link } from '@backstage/core-components'; + +/** + * Card actions that show for all entities + * + * @private + */ +export const EntityCardActions = ({ entity }: { entity: Entity }) => { + const entityRoute = useRouteRef(entityRouteRef); + + return ( + + + + ); +}; diff --git a/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/GroupCardActions.tsx b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/GroupCardActions.tsx new file mode 100644 index 0000000000..fca0763703 --- /dev/null +++ b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/GroupCardActions.tsx @@ -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 { EmailCardAction } from './EmailCardAction'; +import React from 'react'; +import { GroupEntity } from '@backstage/catalog-model'; + +/** + * Card actions that show for a group + * + * @private + */ +export const GroupCardActions = ({ entity }: { entity: GroupEntity }) => { + return ( + <> + {entity.spec.profile?.email && ( + + )} + + ); +}; diff --git a/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/UserCardActions.tsx b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/UserCardActions.tsx new file mode 100644 index 0000000000..57801497f6 --- /dev/null +++ b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/UserCardActions.tsx @@ -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 { EmailCardAction } from './EmailCardAction'; +import React from 'react'; +import { UserEntity } from '@backstage/catalog-model'; + +/** + * Card actions that show for a user + * + * @private + */ +export const UserCardActions = ({ entity }: { entity: UserEntity }) => { + return ( + <> + {entity.spec.profile?.email && ( + + )} + + ); +}; diff --git a/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/index.ts b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/index.ts new file mode 100644 index 0000000000..75959026f7 --- /dev/null +++ b/plugins/catalog-react/src/components/EntityPeekAheadPopover/CardActionComponents/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 { EntityCardActions } from './EntityCardActions'; +export { GroupCardActions } from './GroupCardActions'; +export { UserCardActions } from './UserCardActions'; diff --git a/plugins/catalog-react/src/components/EntityPeekAheadPopover/EntityPeekAheadPopover.stories.tsx b/plugins/catalog-react/src/components/EntityPeekAheadPopover/EntityPeekAheadPopover.stories.tsx new file mode 100644 index 0000000000..132042452b --- /dev/null +++ b/plugins/catalog-react/src/components/EntityPeekAheadPopover/EntityPeekAheadPopover.stories.tsx @@ -0,0 +1,197 @@ +/* + * 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, { ComponentType } from 'react'; +import { + EntityPeekAheadPopover, + EntityPeekAheadPopoverProps, +} from './EntityPeekAheadPopover'; +import Button from '@material-ui/core/Button'; +import { wrapInTestApp, TestApiProvider } from '@backstage/test-utils'; +import { catalogApiRef } from '../../api'; +import { + CompoundEntityRef, + parseEntityRef, + stringifyEntityRef, +} from '@backstage/catalog-model'; +import { entityRouteRef } from '../../routes'; +import { CatalogApi } from '@backstage/catalog-client'; +import { Table, TableColumn } from '@backstage/core-components'; +import { EntityRefLink } from '../EntityRefLink'; + +const mockCatalogApi = { + getEntityByRef: async (entityRef: CompoundEntityRef) => { + if ( + entityRef.namespace === 'default' && + entityRef.name === 'playback' && + entityRef.kind === 'component' + ) { + return { + kind: 'Component', + metadata: { + name: 'playback', + namespace: 'default', + description: 'Details about the playback service', + }, + }; + } + if ( + entityRef.namespace === 'default' && + entityRef.name === 'fname.lname' && + entityRef.kind === 'user' + ) { + return { + kind: 'User', + metadata: { + name: 'fname.lname', + namespace: 'default', + }, + spec: { + profile: { + email: 'fname.lname@example.com', + }, + }, + }; + } + if ( + entityRef.namespace === 'default' && + entityRef.name === 'slow.catalog.item' && + entityRef.kind === 'component' + ) { + await new Promise(resolve => setTimeout(resolve, 3000)); + return { + kind: 'Component', + metadata: { + name: 'slow.catalog.item', + namespace: 'default', + description: 'Details about the slow.catalog.item service', + }, + }; + } + return undefined; + }, +}; + +const defaultArgs = { + entityRef: 'component:default/playback', +}; + +export default { + title: 'Catalog /PeekAheadPopover', + decorators: [ + (Story: ComponentType<{}>) => + wrapInTestApp( + <> + + + + , + { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }, + ), + ], +}; + +export const Default = (args: EntityPeekAheadPopoverProps) => ( + + + +); +Default.args = defaultArgs; + +export const User = (args: EntityPeekAheadPopoverProps) => ( + + + +); +User.args = { + entityRef: 'user:default/fname.lname', +}; + +export const NotFound = (args: EntityPeekAheadPopoverProps) => ( + + + +); +NotFound.args = { + entityRef: 'user:default/doesnt.exist', +}; + +export const SlowCatalogItem = (args: EntityPeekAheadPopoverProps) => ( + + + +); +SlowCatalogItem.args = { + entityRef: 'component:default/slow.catalog.item', +}; + +const columns: TableColumn[] = [ + { + title: 'entity', + render: entityRef => { + return ( + + + + ); + }, + }, + { + title: 'owner', + render: () => { + return ( + + + + ); + }, + }, + { + title: 'name', + render: entityRef => stringifyEntityRef(entityRef), + }, +]; +export const TableOfItems = (args: { data: CompoundEntityRef[] }) => ( + +); + +TableOfItems.args = { + data: [ + { + name: 'playback', + kind: 'component', + namespace: 'default', + }, + { + name: 'playback', + kind: 'component', + namespace: 'default', + }, + { + name: 'playback', + kind: 'component', + namespace: 'default', + }, + ], +}; diff --git a/plugins/catalog-react/src/components/EntityPeekAheadPopover/EntityPeekAheadPopover.test.tsx b/plugins/catalog-react/src/components/EntityPeekAheadPopover/EntityPeekAheadPopover.test.tsx new file mode 100644 index 0000000000..2fc630313f --- /dev/null +++ b/plugins/catalog-react/src/components/EntityPeekAheadPopover/EntityPeekAheadPopover.test.tsx @@ -0,0 +1,84 @@ +/* + * 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, screen } from '@testing-library/react'; +import React from 'react'; +import { EntityPeekAheadPopover } from './EntityPeekAheadPopover'; +import { ApiProvider } from '@backstage/core-app-api'; +import { TestApiRegistry, renderInTestApp } from '@backstage/test-utils'; +import { catalogApiRef } from '../../api'; +import { CompoundEntityRef, Entity } from '@backstage/catalog-model'; +import { CatalogApi } from '@backstage/catalog-client'; +import { Button } from '@material-ui/core'; +import { entityRouteRef } from '../../routes'; + +const catalogApi: Partial = { + getEntityByRef: async ( + entityRef: CompoundEntityRef, + ): Promise => { + if ( + entityRef.name === 'service1' && + entityRef.namespace === 'default' && + entityRef.kind === 'component' + ) { + return { + apiVersion: '', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'service1', + }, + spec: { + tags: ['java'], + }, + }; + } + return undefined; + }, +}; + +const apis = TestApiRegistry.from([catalogApiRef, catalogApi]); + +describe('', () => { + it('renders all owners', async () => { + renderInTestApp( + + + + + + + + , + { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }, + ); + expect(screen.getByText('s1')).toBeInTheDocument(); + expect(screen.queryByText('service1')).toBeNull(); + fireEvent.mouseOver(screen.getByTestId('popover1')); + expect(await screen.findByText('service1')).toBeInTheDocument(); + + expect(screen.getByText('s2')).toBeInTheDocument(); + expect(screen.queryByText('service2')).toBeNull(); + fireEvent.mouseOver(screen.getByTestId('popover2')); + expect( + await screen.findByText('Error: service2 was not found'), + ).toBeInTheDocument(); + }); +}); diff --git a/plugins/catalog-react/src/components/EntityPeekAheadPopover/EntityPeekAheadPopover.tsx b/plugins/catalog-react/src/components/EntityPeekAheadPopover/EntityPeekAheadPopover.tsx new file mode 100644 index 0000000000..05a818fa1f --- /dev/null +++ b/plugins/catalog-react/src/components/EntityPeekAheadPopover/EntityPeekAheadPopover.tsx @@ -0,0 +1,208 @@ +/* + * 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 useAsyncFn from 'react-use/lib/useAsyncFn'; +import { catalogApiRef } from '../../api'; +import React, { PropsWithChildren, useEffect, useState } from 'react'; +import HoverPopover from 'material-ui-popup-state/HoverPopover'; +import { + bindHover, + bindPopover, + usePopupState, +} from 'material-ui-popup-state/hooks'; +import { + Box, + Card, + CardActions, + CardContent, + Chip, + makeStyles, + Tooltip, + Typography, +} from '@material-ui/core'; +import { useApiHolder } from '@backstage/core-plugin-api'; +import { + isGroupEntity, + isUserEntity, + parseEntityRef, +} from '@backstage/catalog-model'; +import { Progress, ResponseErrorPanel } from '@backstage/core-components'; +import { + EntityCardActions, + UserCardActions, + GroupCardActions, +} from './CardActionComponents'; +import { debounce } from 'lodash'; + +/** + * Properties for an entity popover on hover of a component. + * + * @public + */ +export type EntityPeekAheadPopoverProps = PropsWithChildren<{ + entityRef: string; + delayTime?: number; +}>; + +const useStyles = makeStyles(() => { + return { + trigger: { + display: 'inline-block', + }, + popoverPaper: { + width: '30em', + }, + descriptionTypography: { + overflow: 'hidden', + textOverflow: 'ellipsis', + display: '-webkit-box', + WebkitLineClamp: 2, + WebkitBoxOrient: 'vertical', + }, + }; +}); + +const maxTagChips = 4; + +/** + * Shows an entity popover on hover of a component. + * + * @public + */ +export const EntityPeekAheadPopover = (props: EntityPeekAheadPopoverProps) => { + const { entityRef, children, delayTime = 500 } = props; + + const classes = useStyles(); + const apiHolder = useApiHolder(); + const popupState = usePopupState({ + variant: 'popover', + popupId: 'entity-peek-ahead', + }); + const compoundEntityRef = parseEntityRef(entityRef); + const [isHovered, setIsHovered] = useState(false); + + const debouncedHandleMouseEnter = debounce( + () => setIsHovered(true), + delayTime, + ); + + const [{ loading, error, value: entity }, load] = useAsyncFn(async () => { + const catalogApi = apiHolder.get(catalogApiRef); + if (catalogApi) { + const retrievedEntity = await catalogApi.getEntityByRef( + compoundEntityRef, + ); + if (!retrievedEntity) { + throw new Error(`${compoundEntityRef.name} was not found`); + } + return retrievedEntity; + } + return undefined; + }, [apiHolder, compoundEntityRef]); + + const handleOnMouseLeave = () => { + setIsHovered(false); + debouncedHandleMouseEnter.cancel(); + }; + + useEffect(() => { + if (popupState.isOpen && !entity && !error && !loading) { + load(); + } + }, [popupState.isOpen, load, entity, error, loading]); + + return ( + <> + + + {children} + + + {isHovered && ( + + <> + {error && } + + {loading && } + + + {entity && ( + <> + + {compoundEntityRef.namespace} + + + {compoundEntityRef.name} + + {entity.kind} + + {entity.metadata.description} + + {entity.spec?.type} + + {(entity.metadata.tags || []) + .slice(0, maxTagChips) + .map(tag => { + return ; + })} + {entity.metadata.tags?.length && + entity.metadata.tags?.length > maxTagChips && ( + + + + )} + + + )} + + {!error && ( + + {entity && ( + <> + {isUserEntity(entity) && ( + + )} + {isGroupEntity(entity) && ( + + )} + + + )} + + )} + + + + )} + + ); +}; diff --git a/plugins/adr/src/hooks/index.ts b/plugins/catalog-react/src/components/EntityPeekAheadPopover/index.ts similarity index 93% rename from plugins/adr/src/hooks/index.ts rename to plugins/catalog-react/src/components/EntityPeekAheadPopover/index.ts index d5aa102fb8..6630f6f555 100644 --- a/plugins/adr/src/hooks/index.ts +++ b/plugins/catalog-react/src/components/EntityPeekAheadPopover/index.ts @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export * from './useOctokitRequest'; +export * from './EntityPeekAheadPopover'; diff --git a/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.stories.tsx b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.stories.tsx new file mode 100644 index 0000000000..e82c4ab963 --- /dev/null +++ b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.stories.tsx @@ -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 React, { ComponentType } from 'react'; +import { EntityRefLink, EntityRefLinkProps } from './EntityRefLink'; +import { wrapInTestApp } from '@backstage/test-utils'; +import { entityRouteRef } from '../../routes'; + +const defaultArgs = { + entityRef: 'component:default/playback', +}; + +export default { + title: 'Catalog /EntityRefLink', + decorators: [ + (Story: ComponentType<{}>) => + wrapInTestApp(, { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }), + ], +}; + +export const Default = (args: EntityRefLinkProps) => ( + +); +Default.args = defaultArgs; diff --git a/plugins/catalog-react/src/components/EntityRefLink/EntityRefLinks.stories.tsx b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLinks.stories.tsx new file mode 100644 index 0000000000..176dd24530 --- /dev/null +++ b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLinks.stories.tsx @@ -0,0 +1,42 @@ +/* + * 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, { ComponentType } from 'react'; +import { EntityRefLinks, EntityRefLinksProps } from './EntityRefLinks'; +import { wrapInTestApp } from '@backstage/test-utils'; +import { CompoundEntityRef } from '@backstage/catalog-model'; +import { entityRouteRef } from '../../routes'; + +const defaultArgs = { + entityRefs: ['component:default/playback', 'user:default/fname.lname'], +}; + +export default { + title: 'Catalog /EntityRefLinks', + decorators: [ + (Story: ComponentType<{}>) => + wrapInTestApp(, { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }), + ], +}; + +export const Default = ( + args: EntityRefLinksProps, +) => ; +Default.args = defaultArgs; diff --git a/plugins/catalog-react/src/components/index.ts b/plugins/catalog-react/src/components/index.ts index c604306ead..a4380ddef0 100644 --- a/plugins/catalog-react/src/components/index.ts +++ b/plugins/catalog-react/src/components/index.ts @@ -19,6 +19,7 @@ export * from './EntityKindPicker'; export * from './EntityLifecyclePicker'; export * from './EntityOwnerPicker'; export * from './EntityRefLink'; +export * from './EntityPeekAheadPopover'; export * from './EntitySearchBar'; export * from './EntityTable'; export * from './EntityTagPicker'; diff --git a/plugins/events-backend-module-aws-sqs/package.json b/plugins/events-backend-module-aws-sqs/package.json index 62e897a42e..c01c706f67 100644 --- a/plugins/events-backend-module-aws-sqs/package.json +++ b/plugins/events-backend-module-aws-sqs/package.json @@ -24,6 +24,7 @@ }, "dependencies": { "@aws-sdk/client-sqs": "^3.208.0", + "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/backend-tasks": "workspace:^", "@backstage/config": "workspace:^", 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 a6c43d4046..50812f321b 100644 --- a/plugins/events-backend-module-aws-sqs/src/service/AwsSqsConsumingEventPublisherEventsModule.ts +++ b/plugins/events-backend-module-aws-sqs/src/service/AwsSqsConsumingEventPublisherEventsModule.ts @@ -17,8 +17,8 @@ import { coreServices, createBackendModule, - loggerToWinstonLogger, } from '@backstage/backend-plugin-api'; +import { loggerToWinstonLogger } from '@backstage/backend-common'; import { eventsExtensionPoint } from '@backstage/plugin-events-node'; import { AwsSqsConsumingEventPublisher } from '../publisher/AwsSqsConsumingEventPublisher'; diff --git a/plugins/events-backend/src/service/EventsPlugin.ts b/plugins/events-backend/src/service/EventsPlugin.ts index 63d0d0b02a..29456d71f7 100644 --- a/plugins/events-backend/src/service/EventsPlugin.ts +++ b/plugins/events-backend/src/service/EventsPlugin.ts @@ -17,8 +17,8 @@ import { createBackendPlugin, coreServices, - loggerToWinstonLogger, } from '@backstage/backend-plugin-api'; +import { loggerToWinstonLogger } from '@backstage/backend-common'; import { EventBroker, EventPublisher, diff --git a/plugins/git-release-manager/api-report.md b/plugins/git-release-manager/api-report.md index d34b6c07fb..edc2e56ad9 100644 --- a/plugins/git-release-manager/api-report.md +++ b/plugins/git-release-manager/api-report.md @@ -12,23 +12,72 @@ import { default as React_2 } from 'react'; import { ReactNode } from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; -// Warning: (ae-missing-release-tag) "A_CALVER_VERSION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "A_CALVER_VERSION" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const A_CALVER_VERSION = '2020.01.01_1'; -// Warning: (ae-missing-release-tag) "A_SEMVER_VERSION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "A_SEMVER_VERSION" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const A_SEMVER_VERSION = '1.2.3'; -// Warning: (ae-missing-release-tag) "calverRegexp" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "AlertError" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface AlertError { + // (undocumented) + subtitle: string; + // (undocumented) + title?: string; +} + +// Warning: (ae-missing-release-tag) "calverRegexp" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const calverRegexp: RegExp; +// Warning: (ae-missing-release-tag) "CalverTagParts" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +type CalverTagParts = { + prefix: string; + calver: string; + patch: number; +}; + +// Warning: (ae-missing-release-tag) "ComponentConfig" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ComponentConfig = { + omit?: boolean; + onSuccess?: (args: OnSuccessArgs) => Promise | void; +}; + +declare namespace components { + export { + Differ, + Divider, + InfoCardPlus, + LinearProgressWithLabel, + NoLatestRelease, + ResponseStepDialog, + ResponseStepList, + ResponseStepListItem, + }; +} + +declare namespace constants { + export { + SEMVER_PARTS, + DISABLE_CACHE, + VERSIONING_STRATEGIES, + TAG_OBJECT_MESSAGE, + }; +} + // Warning: (ae-forgotten-export) The symbol "GetBranchResult" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createMockBranch" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "createMockBranch" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public const createMockBranch: ({ @@ -36,7 +85,7 @@ const createMockBranch: ({ }?: Partial) => GetBranchResult['branch']; // Warning: (ae-forgotten-export) The symbol "GetCommitResult" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createMockCommit" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "createMockCommit" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const createMockCommit: ( @@ -44,7 +93,7 @@ const createMockCommit: ( ) => GetCommitResult; // Warning: (ae-forgotten-export) The symbol "GetRecentCommitsResultSingle" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createMockRecentCommit" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "createMockRecentCommit" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public const createMockRecentCommit: ({ @@ -52,7 +101,7 @@ const createMockRecentCommit: ({ }: Partial) => GetRecentCommitsResultSingle; // Warning: (ae-forgotten-export) The symbol "GetLatestReleaseResult" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createMockRelease" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "createMockRelease" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public const createMockRelease: ({ @@ -64,18 +113,38 @@ const createMockRelease: ({ >) => NonNullable; // Warning: (ae-forgotten-export) The symbol "GetTagResult" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createMockTag" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "createMockTag" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const createMockTag: (overrides: Partial) => GetTagResult; +// Warning: (ae-missing-release-tag) "CreateRcOnSuccessArgs" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface CreateRcOnSuccessArgs { + // (undocumented) + comparisonUrl: string; + // (undocumented) + createdTag: string; + // (undocumented) + gitReleaseName: string | null; + // (undocumented) + gitReleaseUrl: string; + // Warning: (ae-forgotten-export) The symbol "UseCreateReleaseCandidate" needs to be exported by the entry point index.d.ts + // + // (undocumented) + input: Omit; + // (undocumented) + previousTag?: string; +} + // Warning: (ae-forgotten-export) The symbol "DifferProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "Differ" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "Differ" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const Differ: ({ current, next, icon }: DifferProps) => JSX.Element; -// Warning: (ae-missing-release-tag) "DISABLE_CACHE" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "DISABLE_CACHE" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const DISABLE_CACHE: { @@ -84,7 +153,7 @@ const DISABLE_CACHE: { }; }; -// Warning: (ae-missing-release-tag) "Divider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "Divider" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const Divider: () => JSX.Element; @@ -129,7 +198,7 @@ function getBumpedTag(options: { error: AlertError; }; -// Warning: (ae-missing-release-tag) "getCalverTagParts" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "getCalverTagParts" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) function getCalverTagParts(tag: string): @@ -142,7 +211,7 @@ function getCalverTagParts(tag: string): error?: undefined; }; -// Warning: (ae-missing-release-tag) "getSemverTagParts" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "getSemverTagParts" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) function getSemverTagParts(tag: string): @@ -155,7 +224,7 @@ function getSemverTagParts(tag: string): error?: undefined; }; -// Warning: (ae-missing-release-tag) "getShortCommitHash" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "getShortCommitHash" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) function getShortCommitHash(hash: string): string; @@ -176,18 +245,18 @@ function getTagParts(options: { project: Project; tag: string }): }; // Warning: (ae-forgotten-export) The symbol "GitReleaseApi" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "gitReleaseManagerApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "gitReleaseManagerApiRef" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const gitReleaseManagerApiRef: ApiRef; // Warning: (ae-forgotten-export) The symbol "GitReleaseManager" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "GitReleaseManagerPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "GitReleaseManagerPage" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const GitReleaseManagerPage: GitReleaseManager; -// Warning: (ae-missing-release-tag) "gitReleaseManagerPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "gitReleaseManagerPlugin" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const gitReleaseManagerPlugin: BackstagePlugin< @@ -198,20 +267,32 @@ export const gitReleaseManagerPlugin: BackstagePlugin< {} >; +declare namespace helpers { + export { + calverRegexp, + getCalverTagParts, + CalverTagParts, + getBumpedSemverTagParts, + getBumpedTag, + getSemverTagParts, + semverRegexp, + getShortCommitHash, + getTagParts, + isCalverTagParts, + isProjectValid, + validateTagName, + }; +} + // @public (undocumented) const InfoCardPlus: (props: { children?: React_2.ReactNode }) => JSX.Element; -// Warning: (ae-missing-release-tag) "internals" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const internals: { - components: typeof components; - constants: typeof constants; - helpers: typeof helpers; - testHelpers: typeof testHelpers; -}; +declare namespace internals { + export { components, constants, helpers, testHelpers }; +} +export { internals }; -// Warning: (ae-missing-release-tag) "isCalverTagParts" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "isCalverTagParts" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) function isCalverTagParts( @@ -219,12 +300,12 @@ function isCalverTagParts( _tagParts: unknown, ): _tagParts is CalverTagParts; -// Warning: (ae-missing-release-tag) "isProjectValid" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "isProjectValid" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) function isProjectValid(project: any): project is Project; -// Warning: (ae-missing-release-tag) "LinearProgressWithLabel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "LinearProgressWithLabel" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) function LinearProgressWithLabel(props: { @@ -232,88 +313,88 @@ function LinearProgressWithLabel(props: { responseSteps: ResponseStep[]; }): JSX.Element; -// Warning: (ae-missing-release-tag) "MOCK_RELEASE_BRANCH_NAME_CALVER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "MOCK_RELEASE_BRANCH_NAME_CALVER" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const MOCK_RELEASE_BRANCH_NAME_CALVER: string; -// Warning: (ae-missing-release-tag) "MOCK_RELEASE_BRANCH_NAME_SEMVER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "MOCK_RELEASE_BRANCH_NAME_SEMVER" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const MOCK_RELEASE_BRANCH_NAME_SEMVER: string; -// Warning: (ae-missing-release-tag) "MOCK_RELEASE_CANDIDATE_TAG_NAME_CALVER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "MOCK_RELEASE_CANDIDATE_TAG_NAME_CALVER" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const MOCK_RELEASE_CANDIDATE_TAG_NAME_CALVER: string; -// Warning: (ae-missing-release-tag) "MOCK_RELEASE_CANDIDATE_TAG_NAME_SEMVER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "MOCK_RELEASE_CANDIDATE_TAG_NAME_SEMVER" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const MOCK_RELEASE_CANDIDATE_TAG_NAME_SEMVER: string; -// Warning: (ae-missing-release-tag) "MOCK_RELEASE_NAME_CALVER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "MOCK_RELEASE_NAME_CALVER" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const MOCK_RELEASE_NAME_CALVER: string; -// Warning: (ae-missing-release-tag) "MOCK_RELEASE_NAME_SEMVER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "MOCK_RELEASE_NAME_SEMVER" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const MOCK_RELEASE_NAME_SEMVER: string; -// Warning: (ae-missing-release-tag) "MOCK_RELEASE_VERSION_TAG_NAME_CALVER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "MOCK_RELEASE_VERSION_TAG_NAME_CALVER" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const MOCK_RELEASE_VERSION_TAG_NAME_CALVER: string; -// Warning: (ae-missing-release-tag) "MOCK_RELEASE_VERSION_TAG_NAME_SEMVER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "MOCK_RELEASE_VERSION_TAG_NAME_SEMVER" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const MOCK_RELEASE_VERSION_TAG_NAME_SEMVER: string; -// Warning: (ae-missing-release-tag) "mockBumpedTag" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockBumpedTag" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockBumpedTag = 'rc-2020.01.01_1337'; -// Warning: (ae-missing-release-tag) "mockCalverProject" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockCalverProject" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockCalverProject: Project; -// Warning: (ae-missing-release-tag) "mockCtaMessage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockCtaMessage" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockCtaMessage = 'Patch Release Candidate'; -// Warning: (ae-missing-release-tag) "mockDefaultBranch" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockDefaultBranch" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockDefaultBranch = 'mock_defaultBranch'; -// Warning: (ae-missing-release-tag) "mockEmail" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockEmail" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockEmail = 'mock_email'; // Warning: (ae-forgotten-export) The symbol "getReleaseCandidateGitInfo" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "mockNextGitInfoCalver" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockNextGitInfoCalver" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockNextGitInfoCalver: ReturnType; -// Warning: (ae-missing-release-tag) "mockNextGitInfoSemver" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockNextGitInfoSemver" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockNextGitInfoSemver: ReturnType; -// Warning: (ae-missing-release-tag) "mockOwner" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockOwner" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockOwner = 'mock_owner'; -// Warning: (ae-missing-release-tag) "mockReleaseBranch" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockReleaseBranch" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockReleaseBranch: { @@ -331,7 +412,7 @@ const mockReleaseBranch: { }; }; -// Warning: (ae-missing-release-tag) "mockReleaseCandidateCalver" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockReleaseCandidateCalver" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockReleaseCandidateCalver: { @@ -343,7 +424,7 @@ const mockReleaseCandidateCalver: { body?: string | null | undefined; }; -// Warning: (ae-missing-release-tag) "mockReleaseCandidateSemver" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockReleaseCandidateSemver" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockReleaseCandidateSemver: { @@ -356,12 +437,12 @@ const mockReleaseCandidateSemver: { }; // Warning: (ae-forgotten-export) The symbol "ReleaseStats" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "mockReleaseStats" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockReleaseStats" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockReleaseStats: ReleaseStats; -// Warning: (ae-missing-release-tag) "mockReleaseVersionCalver" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockReleaseVersionCalver" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockReleaseVersionCalver: { @@ -373,7 +454,7 @@ const mockReleaseVersionCalver: { body?: string | null | undefined; }; -// Warning: (ae-missing-release-tag) "mockReleaseVersionSemver" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockReleaseVersionSemver" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockReleaseVersionSemver: { @@ -385,22 +466,22 @@ const mockReleaseVersionSemver: { body?: string | null | undefined; }; -// Warning: (ae-missing-release-tag) "mockRepo" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockRepo" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockRepo = 'mock_repo'; -// Warning: (ae-missing-release-tag) "mockSearchCalver" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockSearchCalver" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockSearchCalver: string; -// Warning: (ae-missing-release-tag) "mockSearchSemver" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockSearchSemver" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockSearchSemver: string; -// Warning: (ae-missing-release-tag) "mockSelectedPatchCommit" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockSelectedPatchCommit" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockSelectedPatchCommit: { @@ -416,17 +497,17 @@ const mockSelectedPatchCommit: { firstParentSha?: string | undefined; }; -// Warning: (ae-missing-release-tag) "mockSemverProject" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockSemverProject" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockSemverProject: Project; -// Warning: (ae-missing-release-tag) "mockTagParts" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockTagParts" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockTagParts: CalverTagParts; -// Warning: (ae-missing-release-tag) "mockUser" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockUser" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockUser: { @@ -434,18 +515,86 @@ const mockUser: { email: string; }; -// Warning: (ae-missing-release-tag) "mockUsername" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "mockUsername" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const mockUsername = 'mock_username'; -// Warning: (ae-missing-release-tag) "NoLatestRelease" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "NoLatestRelease" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const NoLatestRelease: () => JSX.Element; +// Warning: (ae-missing-release-tag) "PatchOnSuccessArgs" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface PatchOnSuccessArgs { + // Warning: (ae-forgotten-export) The symbol "UsePatch" needs to be exported by the entry point index.d.ts + // + // (undocumented) + input: Omit; + // (undocumented) + patchCommitMessage: string; + // (undocumented) + patchCommitUrl: string; + // (undocumented) + patchedTag: string; + // (undocumented) + previousTag: string; + // (undocumented) + updatedReleaseName: string | null; + // (undocumented) + updatedReleaseUrl: string; +} + +// Warning: (ae-missing-release-tag) "Project" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface Project { + isProvidedViaProps: boolean; + owner: string; + repo: string; + versioningStrategy: keyof typeof VERSIONING_STRATEGIES; +} + +// Warning: (ae-missing-release-tag) "PromoteRcOnSuccessArgs" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface PromoteRcOnSuccessArgs { + // (undocumented) + gitReleaseName: string | null; + // (undocumented) + gitReleaseUrl: string; + // Warning: (ae-forgotten-export) The symbol "UsePromoteRc" needs to be exported by the entry point index.d.ts + // + // (undocumented) + input: Omit; + // (undocumented) + previousTag: string; + // (undocumented) + previousTagUrl: string; + // (undocumented) + updatedTag: string; + // (undocumented) + updatedTagUrl: string; +} + +// Warning: (ae-missing-release-tag) "ResponseStep" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ResponseStep { + // (undocumented) + icon?: 'success' | 'failure'; + // (undocumented) + link?: string; + // (undocumented) + message: React.ReactNode; + // (undocumented) + secondaryMessage?: string | React.ReactNode; +} + // Warning: (ae-forgotten-export) The symbol "DialogProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ResponseStepDialog" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "ResponseStepDialog" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const ResponseStepDialog: ({ @@ -455,7 +604,7 @@ const ResponseStepDialog: ({ }: DialogProps) => JSX.Element; // Warning: (ae-forgotten-export) The symbol "ResponseStepListProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ResponseStepList" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "ResponseStepList" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const ResponseStepList: ({ @@ -467,7 +616,7 @@ const ResponseStepList: ({ }: PropsWithChildren) => JSX.Element; // Warning: (ae-forgotten-export) The symbol "ResponseStepListItemProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ResponseStepListItem" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "ResponseStepListItem" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const ResponseStepListItem: ({ @@ -475,7 +624,7 @@ const ResponseStepListItem: ({ animationDelay, }: ResponseStepListItemProps) => JSX.Element; -// Warning: (ae-missing-release-tag) "SEMVER_PARTS" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "SEMVER_PARTS" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const SEMVER_PARTS: { @@ -484,7 +633,7 @@ const SEMVER_PARTS: { patch: 'patch'; }; -// Warning: (ae-missing-release-tag) "semverRegexp" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "semverRegexp" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const semverRegexp: RegExp; @@ -493,13 +642,13 @@ declare namespace stats { export { mockReleaseStats }; } -// Warning: (ae-missing-release-tag) "TAG_OBJECT_MESSAGE" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "TAG_OBJECT_MESSAGE" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const TAG_OBJECT_MESSAGE = 'Tag generated by your friendly neighborhood Backstage Release Manager'; -// Warning: (ae-missing-release-tag) "TEST_IDS" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "TEST_IDS" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const TEST_IDS: { @@ -565,6 +714,10 @@ const TEST_IDS: { }; }; +declare namespace testHelpers { + export { stats, testHelpers_2 as testHelpers, testIds }; +} + declare namespace testHelpers_2 { export { mockUsername, @@ -619,22 +772,11 @@ const validateTagName: (options: { project: Project; tagName?: string }) => tagNameError: AlertError | undefined; }; -// Warning: (ae-missing-release-tag) "VERSIONING_STRATEGIES" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "VERSIONING_STRATEGIES" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const VERSIONING_STRATEGIES: { semver: 'semver'; calver: 'calver'; }; - -// Warnings were encountered during analysis: -// -// src/components/ResponseStepDialog/LinearProgressWithLabel.d.ts:5:5 - (ae-forgotten-export) The symbol "ResponseStep" needs to be exported by the entry point index.d.ts -// src/helpers/getBumpedTag.d.ts:16:5 - (ae-forgotten-export) The symbol "Project" needs to be exported by the entry point index.d.ts -// src/helpers/getBumpedTag.d.ts:21:5 - (ae-forgotten-export) The symbol "CalverTagParts" needs to be exported by the entry point index.d.ts -// src/helpers/getBumpedTag.d.ts:33:5 - (ae-forgotten-export) The symbol "AlertError" needs to be exported by the entry point index.d.ts -// src/index.d.ts:9:5 - (ae-forgotten-export) The symbol "components" needs to be exported by the entry point index.d.ts -// src/index.d.ts:10:5 - (ae-forgotten-export) The symbol "constants" needs to be exported by the entry point index.d.ts -// src/index.d.ts:11:5 - (ae-forgotten-export) The symbol "helpers" needs to be exported by the entry point index.d.ts -// src/index.d.ts:12:5 - (ae-forgotten-export) The symbol "testHelpers" needs to be exported by the entry point index.d.ts ``` diff --git a/plugins/git-release-manager/src/helpers/index.tsx b/plugins/git-release-manager/src/helpers/index.tsx index 1516e192a1..6589596114 100644 --- a/plugins/git-release-manager/src/helpers/index.tsx +++ b/plugins/git-release-manager/src/helpers/index.tsx @@ -15,6 +15,7 @@ */ export { calverRegexp, getCalverTagParts } from './tagParts/getCalverTagParts'; +export type { CalverTagParts } from './tagParts/getCalverTagParts'; export { getBumpedSemverTagParts, getBumpedTag } from './getBumpedTag'; export { getSemverTagParts, semverRegexp } from './tagParts/getSemverTagParts'; export { getShortCommitHash } from './getShortCommitHash'; diff --git a/plugins/git-release-manager/src/index.ts b/plugins/git-release-manager/src/index.ts index ac6b294cbc..e8fa661c21 100644 --- a/plugins/git-release-manager/src/index.ts +++ b/plugins/git-release-manager/src/index.ts @@ -26,11 +26,17 @@ export { gitReleaseManagerApiRef, } from './plugin'; -import { components, constants, helpers, testHelpers } from './plugin'; +import * as internals from './internals'; -export const internals = { - components, - constants, - helpers, - testHelpers, -}; +export { internals }; + +export type { + ComponentConfig, + CreateRcOnSuccessArgs, + PatchOnSuccessArgs, + PromoteRcOnSuccessArgs, + ResponseStep, + AlertError, +} from './types/types'; + +export type { Project } from './contexts/ProjectContext'; diff --git a/plugins/git-release-manager/src/internals.ts b/plugins/git-release-manager/src/internals.ts new file mode 100644 index 0000000000..2cd7863bac --- /dev/null +++ b/plugins/git-release-manager/src/internals.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 { components, constants, helpers, testHelpers } from './plugin'; diff --git a/plugins/jenkins/api-report.md b/plugins/jenkins/api-report.md index 59e3dc636e..a2ae16988b 100644 --- a/plugins/jenkins/api-report.md +++ b/plugins/jenkins/api-report.md @@ -28,12 +28,12 @@ const isJenkinsAvailable: (entity: Entity) => boolean; export { isJenkinsAvailable }; export { isJenkinsAvailable as isPluginApplicableToEntity }; -// Warning: (ae-missing-release-tag) "JENKINS_ANNOTATION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "JENKINS_ANNOTATION" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const JENKINS_ANNOTATION = 'jenkins.io/job-full-name'; -// Warning: (ae-missing-release-tag) "JenkinsApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "JenkinsApi" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export interface JenkinsApi { @@ -58,12 +58,12 @@ export interface JenkinsApi { }): Promise; } -// Warning: (ae-missing-release-tag) "jenkinsApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "jenkinsApiRef" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const jenkinsApiRef: ApiRef; -// Warning: (ae-missing-release-tag) "JenkinsClient" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "JenkinsClient" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export class JenkinsClient implements JenkinsApi { @@ -103,7 +103,7 @@ const jenkinsPlugin: BackstagePlugin< export { jenkinsPlugin }; export { jenkinsPlugin as plugin }; -// Warning: (ae-missing-release-tag) "LatestRunCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "LatestRunCard" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const LatestRunCard: (props: { @@ -111,12 +111,12 @@ export const LatestRunCard: (props: { variant?: InfoCardVariants; }) => JSX.Element; -// Warning: (ae-missing-release-tag) "LEGACY_JENKINS_ANNOTATION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "LEGACY_JENKINS_ANNOTATION" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const LEGACY_JENKINS_ANNOTATION = 'jenkins.io/github-folder'; -// Warning: (ae-missing-release-tag) "Router" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "Router" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const Router: () => JSX.Element; diff --git a/plugins/kubernetes/api-report.md b/plugins/kubernetes/api-report.md index 3e1b2f0198..463b4126eb 100644 --- a/plugins/kubernetes/api-report.md +++ b/plugins/kubernetes/api-report.md @@ -36,7 +36,7 @@ import { V1StatefulSet } from '@kubernetes/client-node'; import { WorkloadsByEntityRequest } from '@backstage/plugin-kubernetes-common'; // Warning: (ae-forgotten-export) The symbol "ClusterProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "Cluster" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "Cluster" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const Cluster: ({ @@ -44,19 +44,19 @@ export const Cluster: ({ podsWithErrors, }: ClusterProps) => JSX.Element; -// Warning: (ae-missing-release-tag) "ClusterContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "ClusterContext" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const ClusterContext: React_2.Context; -// Warning: (ae-missing-release-tag) "ClusterLinksFormatter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "ClusterLinksFormatter" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type ClusterLinksFormatter = ( options: ClusterLinksFormatterOptions, ) => URL; -// Warning: (ae-missing-release-tag) "ClusterLinksFormatterOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "ClusterLinksFormatterOptions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export interface ClusterLinksFormatterOptions { @@ -70,24 +70,24 @@ export interface ClusterLinksFormatterOptions { object: any; } -// Warning: (ae-missing-release-tag) "clusterLinksFormatters" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "clusterLinksFormatters" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const clusterLinksFormatters: Record; // Warning: (ae-forgotten-export) The symbol "CronJobsAccordionsProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "CronJobsAccordions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "CronJobsAccordions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const CronJobsAccordions: ({}: CronJobsAccordionsProps) => JSX.Element; // Warning: (ae-forgotten-export) The symbol "CustomResourcesProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "CustomResources" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "CustomResources" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const CustomResources: ({}: CustomResourcesProps) => JSX.Element; -// Warning: (ae-missing-release-tag) "DeploymentResources" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "DeploymentResources" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export interface DeploymentResources { @@ -125,7 +125,7 @@ export const detectErrors: ( objects: ObjectsByEntityResponse, ) => DetectedErrorsByCluster; -// Warning: (ae-missing-release-tag) "EntityKubernetesContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "EntityKubernetesContent" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const EntityKubernetesContent: ( @@ -144,7 +144,7 @@ export type ErrorDetectableKind = | 'HorizontalPodAutoscaler'; // Warning: (ae-forgotten-export) The symbol "ErrorPanelProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ErrorPanel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "ErrorPanel" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const ErrorPanel: ({ @@ -154,7 +154,7 @@ export const ErrorPanel: ({ }: ErrorPanelProps) => JSX.Element; // Warning: (ae-forgotten-export) The symbol "ErrorReportingProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ErrorReporting" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "ErrorReporting" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const ErrorReporting: ({ @@ -165,7 +165,7 @@ export const ErrorReporting: ({ 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 -// Warning: (ae-missing-release-tag) "formatClusterLink" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "formatClusterLink" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function formatClusterLink( @@ -173,7 +173,7 @@ export function formatClusterLink( ): string | undefined; // Warning: (ae-forgotten-export) The symbol "KubernetesAuthProvider" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "GoogleKubernetesAuthProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "GoogleKubernetesAuthProvider" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export class GoogleKubernetesAuthProvider implements KubernetesAuthProvider { @@ -186,7 +186,7 @@ export class GoogleKubernetesAuthProvider implements KubernetesAuthProvider { ): Promise; } -// Warning: (ae-missing-release-tag) "GroupedResponses" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "GroupedResponses" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export interface GroupedResponses extends DeploymentResources { @@ -206,7 +206,7 @@ export interface GroupedResponses extends DeploymentResources { statefulsets: V1StatefulSet[]; } -// Warning: (ae-missing-release-tag) "GroupedResponsesContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "GroupedResponsesContext" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const GroupedResponsesContext: React_2.Context; @@ -219,23 +219,23 @@ export const HorizontalPodAutoscalerDrawer: (props: { }) => JSX.Element; // Warning: (ae-forgotten-export) The symbol "IngressesAccordionsProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "IngressesAccordions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "IngressesAccordions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const IngressesAccordions: ({}: IngressesAccordionsProps) => JSX.Element; -// Warning: (ae-missing-release-tag) "isKubernetesAvailable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "isKubernetesAvailable" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const isKubernetesAvailable: (entity: Entity) => boolean; // Warning: (ae-forgotten-export) The symbol "JobsAccordionsProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "JobsAccordions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "JobsAccordions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const JobsAccordions: ({ jobs }: JobsAccordionsProps) => JSX.Element; -// Warning: (ae-missing-release-tag) "KubernetesApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "KubernetesApi" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export interface KubernetesApi { @@ -261,12 +261,12 @@ export interface KubernetesApi { ): Promise; } -// Warning: (ae-missing-release-tag) "kubernetesApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "kubernetesApiRef" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const kubernetesApiRef: ApiRef; -// Warning: (ae-missing-release-tag) "KubernetesAuthProviders" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "KubernetesAuthProviders" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export class KubernetesAuthProviders implements KubernetesAuthProvidersApi { @@ -283,7 +283,7 @@ export class KubernetesAuthProviders implements KubernetesAuthProvidersApi { ): Promise; } -// Warning: (ae-missing-release-tag) "KubernetesAuthProvidersApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "KubernetesAuthProvidersApi" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export interface KubernetesAuthProvidersApi { @@ -294,12 +294,12 @@ export interface KubernetesAuthProvidersApi { ): Promise; } -// Warning: (ae-missing-release-tag) "kubernetesAuthProvidersApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "kubernetesAuthProvidersApiRef" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const kubernetesAuthProvidersApiRef: ApiRef; -// Warning: (ae-missing-release-tag) "KubernetesBackendClient" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "KubernetesBackendClient" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export class KubernetesBackendClient implements KubernetesApi { @@ -329,7 +329,7 @@ export class KubernetesBackendClient implements KubernetesApi { } // Warning: (ae-forgotten-export) The symbol "KubernetesContentProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "KubernetesContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "KubernetesContent" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const KubernetesContent: ({ @@ -339,7 +339,7 @@ export const KubernetesContent: ({ // Warning: (ae-forgotten-export) The symbol "KubernetesDrawerable" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "KubernetesDrawerProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "KubernetesDrawer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "KubernetesDrawer" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const KubernetesDrawer: ({ @@ -351,7 +351,7 @@ export const KubernetesDrawer: ({ children, }: KubernetesDrawerProps) => JSX.Element; -// Warning: (ae-missing-release-tag) "KubernetesObjects" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "KubernetesObjects" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export interface KubernetesObjects { @@ -363,7 +363,7 @@ export interface KubernetesObjects { loading: boolean; } -// Warning: (ae-missing-release-tag) "kubernetesPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "kubernetesPlugin" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) const kubernetesPlugin: BackstagePlugin< @@ -382,12 +382,12 @@ export const PodDrawer: (props: { expanded?: boolean; }) => JSX.Element; -// Warning: (ae-missing-release-tag) "PodNamesWithErrorsContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "PodNamesWithErrorsContext" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const PodNamesWithErrorsContext: React_2.Context>; -// Warning: (ae-missing-release-tag) "PodNamesWithMetricsContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "PodNamesWithMetricsContext" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const PodNamesWithMetricsContext: React_2.Context< @@ -395,7 +395,7 @@ export const PodNamesWithMetricsContext: React_2.Context< >; // Warning: (ae-forgotten-export) The symbol "PodsTablesProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "PodsTable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "PodsTable" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const PodsTable: ({ @@ -403,7 +403,7 @@ export const PodsTable: ({ extraColumns, }: PodsTablesProps) => JSX.Element; -// Warning: (ae-missing-release-tag) "Router" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "Router" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const Router: (props: { refreshIntervalMs?: number }) => JSX.Element; @@ -419,7 +419,7 @@ export class ServerSideKubernetesAuthProvider } // Warning: (ae-forgotten-export) The symbol "ServicesAccordionsProps" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ServicesAccordions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "ServicesAccordions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const ServicesAccordions: ({}: ServicesAccordionsProps) => JSX.Element; @@ -431,7 +431,7 @@ export const useCustomResources: ( intervalMs?: number, ) => KubernetesObjects; -// Warning: (ae-missing-release-tag) "useKubernetesObjects" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "useKubernetesObjects" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const useKubernetesObjects: ( diff --git a/plugins/lighthouse/src/components/AuditView/index.test.tsx b/plugins/lighthouse/src/components/AuditView/index.test.tsx index c68daddc67..d555133f3e 100644 --- a/plugins/lighthouse/src/components/AuditView/index.test.tsx +++ b/plugins/lighthouse/src/components/AuditView/index.test.tsx @@ -16,6 +16,8 @@ /* eslint-disable jest/no-disabled-tests */ +import { configApiRef } from '@backstage/core-plugin-api'; + jest.mock('react-router-dom', () => { const actual = jest.requireActual('react-router-dom'); const mockNavigation = jest.fn(); @@ -28,6 +30,7 @@ jest.mock('react-router-dom', () => { import { setupRequestMockHandlers, + TestApiProvider, TestApiRegistry, wrapInTestApp, } from '@backstage/test-utils'; @@ -39,13 +42,18 @@ import { Audit, lighthouseApiRef, LighthouseRestApi, Website } from '../../api'; import { formatTime } from '../../utils'; import * as data from '../../__fixtures__/website-response.json'; import AuditView from './index'; -import { ApiProvider } from '@backstage/core-app-api'; +import { ApiProvider, ConfigReader } from '@backstage/core-app-api'; +import { rootRouteRef } from '../../plugin'; const { useParams }: { useParams: jest.Mock } = jest.requireMock('react-router-dom'); const websiteResponse = data as Website; describe('AuditView', () => { + const lighthouseRestApiMock = new LighthouseRestApi('https://lighthouse'); + const testAppOptions = { + mountedRoutes: { '/': rootRouteRef }, + }; let apis: TestApiRegistry; let id: string; @@ -59,10 +67,7 @@ describe('AuditView', () => { ), ); - apis = TestApiRegistry.from([ - lighthouseApiRef, - new LighthouseRestApi('https://lighthouse'), - ]); + apis = TestApiRegistry.from([lighthouseApiRef, lighthouseRestApiMock]); id = websiteResponse.audits.find(a => a.status === 'COMPLETED') ?.id as string; useParams.mockReturnValue({ id }); @@ -74,6 +79,7 @@ describe('AuditView', () => { , + testAppOptions, ), ); @@ -91,6 +97,7 @@ describe('AuditView', () => { , + testAppOptions, ), ); @@ -109,6 +116,7 @@ describe('AuditView', () => { , + testAppOptions, ), ); @@ -137,6 +145,7 @@ describe('AuditView', () => { , + testAppOptions, ), ); @@ -149,6 +158,36 @@ describe('AuditView', () => { ).toHaveAttribute('href', `/audit/${a.id}`); }); }); + + it('navigates to the next report with respect to the base path', async () => { + const configApiMock = new ConfigReader({ + app: { baseUrl: `http://localhost:3000/example` }, + }); + const rendered = render( + wrapInTestApp( + + + , + { + mountedRoutes: { [`/example/lighthouse`]: rootRouteRef }, + }, + ), + ); + + await rendered.findByTestId('audit-sidebar'); + + websiteResponse.audits.forEach(a => { + expect( + rendered.getByText(formatTime(a.timeCreated)).parentElement + ?.parentElement, + ).toHaveAttribute('href', `/example/lighthouse/audit/${a.id}`); + }); + }); }); describe('when the request for the website by id is pending', () => { @@ -159,6 +198,7 @@ describe('AuditView', () => { , + testAppOptions, ), ); expect(await rendered.findByTestId('progress')).toBeInTheDocument(); @@ -177,6 +217,7 @@ describe('AuditView', () => { , + testAppOptions, ), ); expect(await rendered.findByText(/failed to fetch/)).toBeInTheDocument(); @@ -194,6 +235,7 @@ describe('AuditView', () => { , + testAppOptions, ), ); @@ -214,6 +256,7 @@ describe('AuditView', () => { , + testAppOptions, ), ); diff --git a/plugins/lighthouse/src/components/AuditView/index.tsx b/plugins/lighthouse/src/components/AuditView/index.tsx index e377894c90..ade485b09a 100644 --- a/plugins/lighthouse/src/components/AuditView/index.tsx +++ b/plugins/lighthouse/src/components/AuditView/index.tsx @@ -47,7 +47,8 @@ import { Page, Progress, } from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; +import { useApi, useRouteRef } from '@backstage/core-plugin-api'; +import { rootRouteRef } from '../../plugin'; // TODO(freben): move all of this out of index @@ -67,29 +68,35 @@ interface AuditLinkListProps { audits?: Audit[]; selectedId: string; } -const AuditLinkList = ({ audits = [], selectedId }: AuditLinkListProps) => ( - - {audits.map(audit => ( - - - - - - - ))} - -); +const AuditLinkList = ({ audits = [], selectedId }: AuditLinkListProps) => { + const fromPath = useRouteRef(rootRouteRef)?.() ?? '../'; + return ( + + {audits.map(audit => ( + + + + + + + ))} + + ); +}; const AuditView = ({ audit }: { audit?: Audit }) => { const classes = useStyles(); @@ -119,6 +126,7 @@ const AuditView = ({ audit }: { audit?: Audit }) => { export const AuditViewContent = () => { const lighthouseApi = useApi(lighthouseApiRef); + const fromPath = useRouteRef(rootRouteRef)?.() ?? '../'; const params = useParams() as { id: string }; const classes = useStyles(); const navigate = useNavigate(); @@ -178,7 +186,7 @@ export const AuditViewContent = () => { diff --git a/plugins/permission-react/package.json b/plugins/permission-react/package.json index 7801bcbbba..ca23474ba3 100644 --- a/plugins/permission-react/package.json +++ b/plugins/permission-react/package.json @@ -36,7 +36,7 @@ "@backstage/plugin-permission-common": "workspace:^", "cross-fetch": "^3.1.5", "react-use": "^17.2.4", - "swr": "^1.1.2" + "swr": "^2.0.0" }, "peerDependencies": { "@types/react": "^16.13.1 || ^17.0.0", diff --git a/plugins/permission-react/src/hooks/usePermission.test.tsx b/plugins/permission-react/src/hooks/usePermission.test.tsx index cbf3b22ae7..1987382f47 100644 --- a/plugins/permission-react/src/hooks/usePermission.test.tsx +++ b/plugins/permission-react/src/hooks/usePermission.test.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { FC } from 'react'; +import React from 'react'; import { render } from '@testing-library/react'; import { usePermission } from './usePermission'; import { @@ -30,7 +30,7 @@ const permission = createPermission({ attributes: { action: 'read' }, }); -const TestComponent: FC = () => { +const TestComponent = () => { const { loading, allowed, error } = usePermission({ permission }); return (
@@ -47,7 +47,6 @@ function renderComponent(mockApi: PermissionApi) { - , , ); } diff --git a/plugins/playlist/package.json b/plugins/playlist/package.json index 359883a05e..b494e416f6 100644 --- a/plugins/playlist/package.json +++ b/plugins/playlist/package.json @@ -62,7 +62,7 @@ "@types/node": "*", "cross-fetch": "^3.1.5", "msw": "^0.49.0", - "swr": "^1.1.2" + "swr": "^2.0.0" }, "files": [ "dist" diff --git a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.ts b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.ts index 49b7ac100b..7a77470e9b 100644 --- a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.ts +++ b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.ts @@ -54,7 +54,7 @@ export function createFetchRailsAction(options: { }>({ id: 'fetch:rails', description: - 'Downloads a template from the given URL into the workspace, and runs a rails new generator on it.', + 'Downloads a template from the given `url` into the workspace, and runs a rails new generator on it.', schema: { input: { type: 'object', diff --git a/plugins/scaffolder-backend/src/ScaffolderPlugin.ts b/plugins/scaffolder-backend/src/ScaffolderPlugin.ts index 8a9da38bf2..5d4c16e2dc 100644 --- a/plugins/scaffolder-backend/src/ScaffolderPlugin.ts +++ b/plugins/scaffolder-backend/src/ScaffolderPlugin.ts @@ -16,9 +16,9 @@ import { createBackendPlugin, coreServices, - loggerToWinstonLogger, createExtensionPoint, } from '@backstage/backend-plugin-api'; +import { loggerToWinstonLogger } from '@backstage/backend-common'; import { ScmIntegrations } from '@backstage/integration'; import { catalogServiceRef } from '@backstage/plugin-catalog-node'; import { TemplateFilter, TemplateGlobal } from './lib'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plain.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plain.ts index 9dc82068c0..b3b984f544 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plain.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plain.ts @@ -33,7 +33,7 @@ export function createFetchPlainAction(options: { return createTemplateAction<{ url: string; targetPath?: string }>({ id: 'fetch:plain', description: - "Downloads content and places it in the workspace, or optionally in a subdirectory specified by the 'targetPath' input option.", + 'Downloads content and places it in the workspace, or optionally in a subdirectory specified by the `targetPath` input option.', schema: { input: { type: 'object', diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts index d71997d496..10a9d0c055 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts @@ -65,7 +65,7 @@ export function createFetchTemplateAction(options: { }>({ id: 'fetch:template', description: - "Downloads a skeleton, templates variables into file and directory names and content, and places the result in the workspace, or optionally in a subdirectory specified by the 'targetPath' input option.", + 'Downloads a skeleton, templates variables into file and directory names and content, and places the result in the workspace, or optionally in a subdirectory specified by the `targetPath` input option.', schema: { input: { type: 'object', diff --git a/plugins/scaffolder/api-report.md b/plugins/scaffolder/api-report.md index 1b1cfb80bc..0a881b4519 100644 --- a/plugins/scaffolder/api-report.md +++ b/plugins/scaffolder/api-report.md @@ -562,7 +562,9 @@ export interface ScaffolderDryRunResponse { } // @public -export const ScaffolderFieldExtensions: React_2.ComponentType; +export const ScaffolderFieldExtensions: React_2.ComponentType< + React_2.PropsWithChildren<{}> +>; // @public export interface ScaffolderGetIntegrationsListOptions { diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index f9666f4218..fd463c5d33 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -72,7 +72,7 @@ "luxon": "^3.0.0", "qs": "^6.9.4", "react-use": "^17.2.4", - "use-immer": "^0.7.0", + "use-immer": "^0.8.0", "yaml": "^2.0.0", "zen-observable": "^0.10.0", "zod": "~3.18.0", diff --git a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.tsx b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.tsx index 7d0137c9bc..80ac519ca6 100644 --- a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.tsx +++ b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.tsx @@ -45,6 +45,7 @@ import { Page, ErrorPage, CodeSnippet, + MarkdownContent, } from '@backstage/core-components'; import { ActionExample } from '../../types'; @@ -201,7 +202,7 @@ export const ActionsPage = () => { {action.id} - {action.description} + {action.description && } {action.schema?.input && ( Input diff --git a/plugins/scaffolder/src/extensions/index.tsx b/plugins/scaffolder/src/extensions/index.tsx index a3a4fdf57b..2b3126ac58 100644 --- a/plugins/scaffolder/src/extensions/index.tsx +++ b/plugins/scaffolder/src/extensions/index.tsx @@ -94,8 +94,9 @@ export function createNextScaffolderFieldExtension< * * @public */ -export const ScaffolderFieldExtensions: React.ComponentType = - (): JSX.Element | null => null; +export const ScaffolderFieldExtensions: React.ComponentType< + React.PropsWithChildren<{}> +> = (): JSX.Element | null => null; attachComponentData( ScaffolderFieldExtensions, diff --git a/plugins/search-react/api-report.md b/plugins/search-react/api-report.md index ef3e8b19bd..3d1e4091ea 100644 --- a/plugins/search-react/api-report.md +++ b/plugins/search-react/api-report.md @@ -402,6 +402,7 @@ export const SearchResultPager: () => JSX.Element; // @public export type SearchResultProps = Pick & { children: (resultSet: SearchResultSet) => JSX.Element; + noResultsComponent?: JSX.Element; }; // @public diff --git a/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx b/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx index 6f536510e8..ef9b0d6b5c 100644 --- a/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx +++ b/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx @@ -218,3 +218,32 @@ export const GroupLayout = () => { ); }; + +export const WithCustomNoResultsComponent = () => { + return ( + No results were found}> + {({ results }) => ( + + {results.map(({ type, document }) => { + switch (type) { + case 'custom-result-item': + return ( + + ); + default: + return ( + + ); + } + })} + + )} + + ); +}; diff --git a/plugins/search-react/src/components/SearchResult/SearchResult.test.tsx b/plugins/search-react/src/components/SearchResult/SearchResult.test.tsx index 988d59d7cf..5972eaa891 100644 --- a/plugins/search-react/src/components/SearchResult/SearchResult.test.tsx +++ b/plugins/search-react/src/components/SearchResult/SearchResult.test.tsx @@ -93,6 +93,22 @@ describe('SearchResult', () => { }); }); + it('On empty result value state with custom component', async () => { + (useSearch as jest.Mock).mockReturnValueOnce({ + result: { loading: false, error: '', value: { results: [] } }, + }); + + const { getByText } = await renderInTestApp( + No results found}> + {() => <>} + , + ); + + await waitFor(() => { + expect(getByText('No results found')).toBeInTheDocument(); + }); + }); + it('Calls children with results set to result.value', async () => { (useSearch as jest.Mock).mockReturnValueOnce({ result: { diff --git a/plugins/search-react/src/components/SearchResult/SearchResult.tsx b/plugins/search-react/src/components/SearchResult/SearchResult.tsx index dd11f42903..333156aab9 100644 --- a/plugins/search-react/src/components/SearchResult/SearchResult.tsx +++ b/plugins/search-react/src/components/SearchResult/SearchResult.tsx @@ -167,6 +167,7 @@ export const SearchResultState = (props: SearchResultStateProps) => { */ export type SearchResultProps = Pick & { children: (resultSet: SearchResultSet) => JSX.Element; + noResultsComponent?: JSX.Element; }; /** @@ -176,7 +177,13 @@ export type SearchResultProps = Pick & { * @public */ export const SearchResultComponent = (props: SearchResultProps) => { - const { query, children } = props; + const { + query, + children, + noResultsComponent = ( + + ), + } = props; return ( @@ -195,9 +202,7 @@ export const SearchResultComponent = (props: SearchResultProps) => { } if (!value?.results.length) { - return ( - - ); + return noResultsComponent; } return children(value); diff --git a/plugins/techdocs-react/api-report.md b/plugins/techdocs-react/api-report.md index f1d6d3f177..cf64762fda 100644 --- a/plugins/techdocs-react/api-report.md +++ b/plugins/techdocs-react/api-report.md @@ -56,7 +56,9 @@ export type TechDocsAddonOptions = { }; // @public -export const TechDocsAddons: React_2.ComponentType; +export const TechDocsAddons: React_2.ComponentType< + React_2.PropsWithChildren<{}> +>; // @public export interface TechDocsApi { diff --git a/plugins/techdocs-react/src/addons.tsx b/plugins/techdocs-react/src/addons.tsx index d77f53a426..54aea0352d 100644 --- a/plugins/techdocs-react/src/addons.tsx +++ b/plugins/techdocs-react/src/addons.tsx @@ -43,7 +43,9 @@ export const TECHDOCS_ADDONS_WRAPPER_KEY = 'techdocs.addons.wrapper.v1'; * TechDocs Addon registry. * @public */ -export const TechDocsAddons: React.ComponentType = () => null; +export const TechDocsAddons: React.ComponentType< + React.PropsWithChildren<{}> +> = () => null; attachComponentData(TechDocsAddons, TECHDOCS_ADDONS_WRAPPER_KEY, true); @@ -71,7 +73,9 @@ export function createTechDocsAddonExtension( * Create a TechDocs addon implementation. * @public */ -export function createTechDocsAddonExtension( +export function createTechDocsAddonExtension< + TComponentProps extends React.PropsWithChildren<{}>, +>( options: TechDocsAddonOptions, ): Extension<(props: TComponentProps) => JSX.Element | null> { const { name, component: TechDocsAddon } = options; diff --git a/plugins/user-settings/src/components/FeatureFlags/UserSettingsFeatureFlags.tsx b/plugins/user-settings/src/components/FeatureFlags/UserSettingsFeatureFlags.tsx index 21aafc089e..a3b5f593ae 100644 --- a/plugins/user-settings/src/components/FeatureFlags/UserSettingsFeatureFlags.tsx +++ b/plugins/user-settings/src/components/FeatureFlags/UserSettingsFeatureFlags.tsx @@ -73,18 +73,10 @@ export const UserSettingsFeatureFlags = () => { inputRef?.current?.focus(); }; - let filteredFeatureFlags = Array.from(featureFlags); - - const filterInputParts = filterInput - .split(/\s/) - .map(part => part.trim().toLocaleLowerCase('en-US')); - - filterInputParts.forEach( - part => - (filteredFeatureFlags = filteredFeatureFlags.filter(featureFlag => - featureFlag.name.toLocaleLowerCase('en-US').includes(part), - )), - ); + const filteredFeatureFlags = featureFlags.filter(featureFlag => { + const featureFlagName = featureFlag.name.toLocaleLowerCase('en-US'); + return featureFlagName.includes(filterInput.toLocaleLowerCase('en-US')); + }); const Header = () => ( diff --git a/scripts/check-docs-quality.js b/scripts/check-docs-quality.js index ac9db65b40..10c4b99976 100755 --- a/scripts/check-docs-quality.js +++ b/scripts/check-docs-quality.js @@ -23,6 +23,7 @@ const IGNORED = [ /^.*[/\\]CHANGELOG\.md$/, /^.*[/\\]api-report\.md$/, /^docs[/\\]releases[/\\].*-changelog\.md$/, + /^docs[/\\]reference[/\\]/, ]; const rootDir = resolvePath(__dirname, '..'); @@ -55,6 +56,7 @@ async function listFiles(dir = '') { // caused by the script. In CI, we want to ensure vale linter is run. async function exitIfMissingVale() { try { + // eslint-disable-next-line import/no-extraneous-dependencies await require('command-exists')('vale'); } catch (e) { if (process.env.CI) { @@ -72,7 +74,7 @@ async function exitIfMissingVale() { async function runVale(files) { const result = spawnSync( 'vale', - ['--config', resolvePath(rootDir, '.github/vale/config.ini'), ...files], + ['--config', resolvePath(rootDir, '.vale.ini'), ...files], { stdio: 'inherit', }, @@ -97,7 +99,7 @@ async function main() { if (process.argv.includes('--ci-args')) { process.stdout.write( // Workaround for not being able to pass arguments to the vale action - JSON.stringify(['--config=.github/vale/config.ini', ...files]), + JSON.stringify([...files]), ); return; } diff --git a/storybook/.storybook/main.js b/storybook/.storybook/main.js index e523b68337..3d92237438 100644 --- a/storybook/.storybook/main.js +++ b/storybook/.storybook/main.js @@ -12,6 +12,7 @@ const BACKSTAGE_CORE_STORIES = [ 'plugins/search-react', 'plugins/home', 'plugins/stack-overflow', + 'plugins/catalog-react', ]; // Some configuration needs to be available directly on the exported object diff --git a/storybook/yarn.lock b/storybook/yarn.lock index 2d785e97be..42c2bf1ad0 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -7598,13 +7598,13 @@ __metadata: linkType: hard "json5@npm:^1.0.1": - version: 1.0.1 - resolution: "json5@npm:1.0.1" + version: 1.0.2 + resolution: "json5@npm:1.0.2" dependencies: minimist: ^1.2.0 bin: json5: lib/cli.js - checksum: e76ea23dbb8fc1348c143da628134a98adf4c5a4e8ea2adaa74a80c455fc2cdf0e2e13e6398ef819bfe92306b610ebb2002668ed9fc1af386d593691ef346fc3 + checksum: 866458a8c58a95a49bef3adba929c625e82532bcff1fe93f01d29cb02cac7c3fe1f4b79951b7792c2da9de0b32871a8401a6e3c5b36778ad852bf5b8a61165d7 languageName: node linkType: hard diff --git a/yarn.lock b/yarn.lock index 5dc2e699bc..a47f5bad21 100644 --- a/yarn.lock +++ b/yarn.lock @@ -408,15 +408,15 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-cognito-identity@npm:3.236.0": - version: 3.236.0 - resolution: "@aws-sdk/client-cognito-identity@npm:3.236.0" +"@aws-sdk/client-cognito-identity@npm:3.238.0": + version: 3.238.0 + resolution: "@aws-sdk/client-cognito-identity@npm:3.238.0" dependencies: "@aws-crypto/sha256-browser": 2.0.0 "@aws-crypto/sha256-js": 2.0.0 - "@aws-sdk/client-sts": 3.236.0 + "@aws-sdk/client-sts": 3.238.0 "@aws-sdk/config-resolver": 3.234.0 - "@aws-sdk/credential-provider-node": 3.236.0 + "@aws-sdk/credential-provider-node": 3.238.0 "@aws-sdk/fetch-http-handler": 3.226.0 "@aws-sdk/hash-node": 3.226.0 "@aws-sdk/invalid-dependency": 3.226.0 @@ -448,20 +448,20 @@ __metadata: "@aws-sdk/util-utf8-browser": 3.188.0 "@aws-sdk/util-utf8-node": 3.208.0 tslib: ^2.3.1 - checksum: 808339bd0113f65674dea0d65af25c350ff5a8f2595f9dd11215b6e457df5d243db156042dc4bfbb39b302d6f871a71fbbed20f403207fb6e4c9e444eb802bf1 + checksum: 7068b6d82d6053ac7f9baefad610b7b9972763bed4bb5f61ec9d5504501fb5d54e573efe5735f4746393f2098d1a20b9991b0f398081a19f3671fbe7be398c84 languageName: node linkType: hard "@aws-sdk/client-s3@npm:^3.208.0": - version: 3.236.0 - resolution: "@aws-sdk/client-s3@npm:3.236.0" + version: 3.238.0 + resolution: "@aws-sdk/client-s3@npm:3.238.0" dependencies: "@aws-crypto/sha1-browser": 2.0.0 "@aws-crypto/sha256-browser": 2.0.0 "@aws-crypto/sha256-js": 2.0.0 - "@aws-sdk/client-sts": 3.236.0 + "@aws-sdk/client-sts": 3.238.0 "@aws-sdk/config-resolver": 3.234.0 - "@aws-sdk/credential-provider-node": 3.236.0 + "@aws-sdk/credential-provider-node": 3.238.0 "@aws-sdk/eventstream-serde-browser": 3.226.0 "@aws-sdk/eventstream-serde-config-resolver": 3.226.0 "@aws-sdk/eventstream-serde-node": 3.226.0 @@ -511,19 +511,19 @@ __metadata: "@aws-sdk/xml-builder": 3.201.0 fast-xml-parser: 4.0.11 tslib: ^2.3.1 - checksum: 6a8953c229a1824bf1639dfa1a593bff3419c2c338da8df956d5cd3098dc3c1236ee63564347a22f40dc5947322b3f315ae7e39dd9c115ccf8a28199168c6d3b + checksum: f066ad581bdbcd9595ff9226c81b59876b833d6e07dc755b6f70ec0c2c5eab909c9d009ec8faa45a60d650d553ca965f271d244d870f4a938751e65e6d521d6e languageName: node linkType: hard "@aws-sdk/client-sqs@npm:^3.208.0": - version: 3.236.0 - resolution: "@aws-sdk/client-sqs@npm:3.236.0" + version: 3.238.0 + resolution: "@aws-sdk/client-sqs@npm:3.238.0" dependencies: "@aws-crypto/sha256-browser": 2.0.0 "@aws-crypto/sha256-js": 2.0.0 - "@aws-sdk/client-sts": 3.236.0 + "@aws-sdk/client-sts": 3.238.0 "@aws-sdk/config-resolver": 3.234.0 - "@aws-sdk/credential-provider-node": 3.236.0 + "@aws-sdk/credential-provider-node": 3.238.0 "@aws-sdk/fetch-http-handler": 3.226.0 "@aws-sdk/hash-node": 3.226.0 "@aws-sdk/invalid-dependency": 3.226.0 @@ -558,13 +558,13 @@ __metadata: "@aws-sdk/util-utf8-node": 3.208.0 fast-xml-parser: 4.0.11 tslib: ^2.3.1 - checksum: c1d3eb3886d8d799afd081cf76822627e359495daa94edb615a001704933b31d276249828c5e5823af49ba08826875a4c768d8e6b4493abe9b65583a585839b7 + checksum: 5ffd1393aabbcc2aa799d823ae9cca154c432cb926eae05d7f41ef6074a6e95083906744c509c2cf4bc65a5029b14552296bf97c6f8976ad92d72c28980fbbb6 languageName: node linkType: hard -"@aws-sdk/client-sso-oidc@npm:3.236.0": - version: 3.236.0 - resolution: "@aws-sdk/client-sso-oidc@npm:3.236.0" +"@aws-sdk/client-sso-oidc@npm:3.238.0": + version: 3.238.0 + resolution: "@aws-sdk/client-sso-oidc@npm:3.238.0" dependencies: "@aws-crypto/sha256-browser": 2.0.0 "@aws-crypto/sha256-js": 2.0.0 @@ -599,13 +599,13 @@ __metadata: "@aws-sdk/util-utf8-browser": 3.188.0 "@aws-sdk/util-utf8-node": 3.208.0 tslib: ^2.3.1 - checksum: 6fbbebb37547bafc9345c1fd03692728d6b6015f7583f22b2542beaac7f395ab29af884f1a353e78dd147ebf8b109b1d6678f9d1ae18c2b70739e9ceee6781ef + checksum: b2f0df1168d2e20ccf1d598b76be4141b6a27068ad9dea74570aa3ab8c94c103537463c58d8296e76d2457f5afb5253cbf2b1f665411981f5939c85667dd1aff languageName: node linkType: hard -"@aws-sdk/client-sso@npm:3.236.0": - version: 3.236.0 - resolution: "@aws-sdk/client-sso@npm:3.236.0" +"@aws-sdk/client-sso@npm:3.238.0": + version: 3.238.0 + resolution: "@aws-sdk/client-sso@npm:3.238.0" dependencies: "@aws-crypto/sha256-browser": 2.0.0 "@aws-crypto/sha256-js": 2.0.0 @@ -640,18 +640,18 @@ __metadata: "@aws-sdk/util-utf8-browser": 3.188.0 "@aws-sdk/util-utf8-node": 3.208.0 tslib: ^2.3.1 - checksum: 15cb25a3c12fe0f11ed320c8f02f72ee0d43291a14c06fce81f608fbc75a85785698fbffc3112e7e92ece25460d24670ba345535b43003b20798a0fcc8a7b31d + checksum: dbd993e569a3858fd80222cd61e5df5813b3ef6579cfd393925679f71af57f3d9277f470d868f93dbda2f797a8e0be7da9f0678ee80a97103ea2612e2e1ef793 languageName: node linkType: hard -"@aws-sdk/client-sts@npm:3.236.0, @aws-sdk/client-sts@npm:^3.208.0": - version: 3.236.0 - resolution: "@aws-sdk/client-sts@npm:3.236.0" +"@aws-sdk/client-sts@npm:3.238.0, @aws-sdk/client-sts@npm:^3.208.0": + version: 3.238.0 + resolution: "@aws-sdk/client-sts@npm:3.238.0" dependencies: "@aws-crypto/sha256-browser": 2.0.0 "@aws-crypto/sha256-js": 2.0.0 "@aws-sdk/config-resolver": 3.234.0 - "@aws-sdk/credential-provider-node": 3.236.0 + "@aws-sdk/credential-provider-node": 3.238.0 "@aws-sdk/fetch-http-handler": 3.226.0 "@aws-sdk/hash-node": 3.226.0 "@aws-sdk/invalid-dependency": 3.226.0 @@ -685,7 +685,7 @@ __metadata: "@aws-sdk/util-utf8-node": 3.208.0 fast-xml-parser: 4.0.11 tslib: ^2.3.1 - checksum: 98463fe50a588032b82be5289445c6e7250bd947076e5981ba7c126386d567f3b1ea9a9652c032da919503cdba2c3b517061911ddffae0c91f880f7eabaeaa08 + checksum: 323677f17a1cfec54022a7af941db636ed9201d0a188b10e367663c422d931508728705633d01943d8bd0439edc20b39b619a8dd87d2ee55f3ca2df923e4c0dc languageName: node linkType: hard @@ -702,15 +702,15 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-cognito-identity@npm:3.236.0": - version: 3.236.0 - resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.236.0" +"@aws-sdk/credential-provider-cognito-identity@npm:3.238.0": + version: 3.238.0 + resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.238.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.236.0 + "@aws-sdk/client-cognito-identity": 3.238.0 "@aws-sdk/property-provider": 3.226.0 "@aws-sdk/types": 3.226.0 tslib: ^2.3.1 - checksum: 29d3178f490cbb711553103c0fb544604c5e70e36395f1edc6b9bd2ee0e928160b911b4893fe89418c182548d0dddfbd44e9ef629ad690ab1724a2a693368c16 + checksum: f885ba267deacec45e1fb59e46ec225b7dcd53c863a0236272948820afe15ed036ea3b039bdfbf6ae7d05054a50582366fa0b258eb8eed1364fca6fad206a63e languageName: node linkType: hard @@ -738,38 +738,38 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:3.236.0": - version: 3.236.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.236.0" +"@aws-sdk/credential-provider-ini@npm:3.238.0": + version: 3.238.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.238.0" dependencies: "@aws-sdk/credential-provider-env": 3.226.0 "@aws-sdk/credential-provider-imds": 3.226.0 "@aws-sdk/credential-provider-process": 3.226.0 - "@aws-sdk/credential-provider-sso": 3.236.0 + "@aws-sdk/credential-provider-sso": 3.238.0 "@aws-sdk/credential-provider-web-identity": 3.226.0 "@aws-sdk/property-provider": 3.226.0 "@aws-sdk/shared-ini-file-loader": 3.226.0 "@aws-sdk/types": 3.226.0 tslib: ^2.3.1 - checksum: e748aba37dab11ed395fa60c7eee119b997e4c64b1a838c93258cfe6a6e289dfa0aa20d292b94d06da8148b7cb32604b24f84aadc2a389bf8248c64d80ef44d5 + checksum: bf792096935a915ff1bf26c53408d7265d2dd5cb2093d5b51862cf21a1418801454362842cd7c59a8738af1bb12713afb354e55d3057e92f30f2caa327ff3eb9 languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:3.236.0, @aws-sdk/credential-provider-node@npm:^3.208.0": - version: 3.236.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.236.0" +"@aws-sdk/credential-provider-node@npm:3.238.0, @aws-sdk/credential-provider-node@npm:^3.208.0": + version: 3.238.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.238.0" dependencies: "@aws-sdk/credential-provider-env": 3.226.0 "@aws-sdk/credential-provider-imds": 3.226.0 - "@aws-sdk/credential-provider-ini": 3.236.0 + "@aws-sdk/credential-provider-ini": 3.238.0 "@aws-sdk/credential-provider-process": 3.226.0 - "@aws-sdk/credential-provider-sso": 3.236.0 + "@aws-sdk/credential-provider-sso": 3.238.0 "@aws-sdk/credential-provider-web-identity": 3.226.0 "@aws-sdk/property-provider": 3.226.0 "@aws-sdk/shared-ini-file-loader": 3.226.0 "@aws-sdk/types": 3.226.0 tslib: ^2.3.1 - checksum: d5a26b40a985edfef5006efde921d58b78829b67eed9fea56e108b99eec437a02721b93ef0e2dcd9a4739716c85d8db75935a71d2afa1190b0f1d0010511f649 + checksum: 7d9e56dd53db5ef1d5600502a407a81500b0dde6c2c6164c88f88dffb20a24b9e256ebd329b2afb3992fa16514173bb8509ab410d651b0e6fb6f4cb713e22d11 languageName: node linkType: hard @@ -785,17 +785,17 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:3.236.0": - version: 3.236.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.236.0" +"@aws-sdk/credential-provider-sso@npm:3.238.0": + version: 3.238.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.238.0" dependencies: - "@aws-sdk/client-sso": 3.236.0 + "@aws-sdk/client-sso": 3.238.0 "@aws-sdk/property-provider": 3.226.0 "@aws-sdk/shared-ini-file-loader": 3.226.0 - "@aws-sdk/token-providers": 3.236.0 + "@aws-sdk/token-providers": 3.238.0 "@aws-sdk/types": 3.226.0 tslib: ^2.3.1 - checksum: 215e0cd08c4dca453a80ce695bf4dddb94ce7562100bfa64e2ba5406ab3aeb6cf92882bd714b6ee95d3f13c45f3286eb616d32e1ffc58728f1e21e7eb171b301 + checksum: 4ac0451f85eb34eba78f4462daace270f0ff3d0d536a5093621923fc4391e9196cb500ffa382b5e4730f9562f005fb01d3cc2364dcfc9e04ce5e9715a151ce96 languageName: node linkType: hard @@ -811,25 +811,25 @@ __metadata: linkType: hard "@aws-sdk/credential-providers@npm:^3.208.0": - version: 3.236.0 - resolution: "@aws-sdk/credential-providers@npm:3.236.0" + version: 3.238.0 + resolution: "@aws-sdk/credential-providers@npm:3.238.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.236.0 - "@aws-sdk/client-sso": 3.236.0 - "@aws-sdk/client-sts": 3.236.0 - "@aws-sdk/credential-provider-cognito-identity": 3.236.0 + "@aws-sdk/client-cognito-identity": 3.238.0 + "@aws-sdk/client-sso": 3.238.0 + "@aws-sdk/client-sts": 3.238.0 + "@aws-sdk/credential-provider-cognito-identity": 3.238.0 "@aws-sdk/credential-provider-env": 3.226.0 "@aws-sdk/credential-provider-imds": 3.226.0 - "@aws-sdk/credential-provider-ini": 3.236.0 - "@aws-sdk/credential-provider-node": 3.236.0 + "@aws-sdk/credential-provider-ini": 3.238.0 + "@aws-sdk/credential-provider-node": 3.238.0 "@aws-sdk/credential-provider-process": 3.226.0 - "@aws-sdk/credential-provider-sso": 3.236.0 + "@aws-sdk/credential-provider-sso": 3.238.0 "@aws-sdk/credential-provider-web-identity": 3.226.0 "@aws-sdk/property-provider": 3.226.0 "@aws-sdk/shared-ini-file-loader": 3.226.0 "@aws-sdk/types": 3.226.0 tslib: ^2.3.1 - checksum: 3105661946fa12322b18a2227f26a8b734072850882e771493b398e714b433c024873a4495a18d55a4213022b07c658cb7ed38859b5fa152fc2ce1e02b408ca1 + checksum: f5767eafd9ce88a6085f05847d6b99a49d56974d903050957bffd5fb0afcfa39f82fe3d507cf482d23b30f1976a0d8430793e6cd0d8f843b7571f300ce5a12ca languageName: node linkType: hard @@ -967,8 +967,8 @@ __metadata: linkType: hard "@aws-sdk/lib-storage@npm:^3.208.0": - version: 3.236.0 - resolution: "@aws-sdk/lib-storage@npm:3.236.0" + version: 3.238.0 + resolution: "@aws-sdk/lib-storage@npm:3.238.0" dependencies: "@aws-sdk/middleware-endpoint": 3.226.0 "@aws-sdk/smithy-client": 3.234.0 @@ -979,7 +979,7 @@ __metadata: peerDependencies: "@aws-sdk/abort-controller": ^3.0.0 "@aws-sdk/client-s3": ^3.0.0 - checksum: 783b67c4605a4f7d4072ce38b2b2416a0a6771784f9ba5b1608be3777e7d21a18c820fff94218856607f984c453376e25e80393ef233365476850e354f8e15f8 + checksum: 97336b3911c0803bbe5dfbbc96d950e3e38c65007a0b76971748a8d10bd34137eeaae2c986eca4c54a2b7ab7cc791bbd40a3175e76ee583abc5c26cc7959ecd9 languageName: node linkType: hard @@ -1355,16 +1355,16 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/token-providers@npm:3.236.0": - version: 3.236.0 - resolution: "@aws-sdk/token-providers@npm:3.236.0" +"@aws-sdk/token-providers@npm:3.238.0": + version: 3.238.0 + resolution: "@aws-sdk/token-providers@npm:3.238.0" dependencies: - "@aws-sdk/client-sso-oidc": 3.236.0 + "@aws-sdk/client-sso-oidc": 3.238.0 "@aws-sdk/property-provider": 3.226.0 "@aws-sdk/shared-ini-file-loader": 3.226.0 "@aws-sdk/types": 3.226.0 tslib: ^2.3.1 - checksum: c5e6c88f22d35002f2d575d23ba5a530ee195b7220d7c0c58603bc2fafb6632a6755bc863cb7519eadda110d2f3193a144f34cc0236df285fcde40c980ba653a + checksum: 5627cda5accc45efb50636d839ed3e6d820a139495fdc03f95cb49267d2c67182fa88d6e46a70fe9ccf34cc8a30df390ded8e94af9daeb3581c22ab0d4940ec5 languageName: node linkType: hard @@ -3382,6 +3382,7 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/plugin-permission-node": "workspace:^" + "@types/express": ^4.17.6 express: ^4.17.1 express-promise-router: ^4.1.0 winston: ^3.2.1 @@ -3431,7 +3432,7 @@ __metadata: aws-sdk: ^2.840.0 aws-sdk-mock: ^5.2.1 base64-stream: ^1.0.0 - better-sqlite3: ^7.5.0 + better-sqlite3: ^8.0.0 compression: ^1.7.4 concat-stream: ^2.0.0 cors: ^2.8.5 @@ -3466,6 +3467,7 @@ __metadata: tar: ^6.1.12 uuid: ^8.3.2 winston: ^3.2.1 + winston-transport: ^4.5.0 yauzl: ^2.10.0 yn: ^4.0.0 peerDependencies: @@ -3490,15 +3492,14 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/backend-plugin-api@workspace:packages/backend-plugin-api" dependencies: - "@backstage/backend-common": "workspace:^" "@backstage/backend-tasks": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" + "@backstage/types": "workspace:^" "@types/express": ^4.17.6 express: ^4.17.1 - winston: ^3.2.1 - winston-transport: ^4.5.0 + knex: ^2.0.0 languageName: unknown linkType: soft @@ -3534,7 +3535,7 @@ __metadata: "@backstage/backend-plugin-api": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" - better-sqlite3: ^7.5.0 + better-sqlite3: ^8.0.0 knex: ^2.0.0 msw: ^0.49.0 mysql2: ^2.2.5 @@ -3567,7 +3568,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-model@npm:^1.1.2, @backstage/catalog-model@npm:^1.1.3, @backstage/catalog-model@npm:^1.1.4": +"@backstage/catalog-model@npm:^1.1.2, @backstage/catalog-model@npm:^1.1.4": version: 1.1.4 resolution: "@backstage/catalog-model@npm:1.1.4" dependencies: @@ -3729,7 +3730,6 @@ __metadata: tar: ^6.1.12 terser-webpack-plugin: ^5.1.3 ts-node: ^10.0.0 - type-fest: ^2.0.0 util: ^0.12.3 webpack: ^5.70.0 webpack-dev-server: ^4.7.3 @@ -3902,7 +3902,7 @@ __metadata: languageName: node linkType: hard -"@backstage/core-components@npm:^0.12.0, @backstage/core-components@npm:^0.12.2": +"@backstage/core-components@npm:^0.12.2": version: 0.12.2 resolution: "@backstage/core-components@npm:0.12.2" dependencies: @@ -4023,7 +4023,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-plugin-api@npm:^1.0.7, @backstage/core-plugin-api@npm:^1.1.0, @backstage/core-plugin-api@npm:^1.2.0": +"@backstage/core-plugin-api@npm:^1.0.7, @backstage/core-plugin-api@npm:^1.2.0": version: 1.2.0 resolution: "@backstage/core-plugin-api@npm:1.2.0" dependencies: @@ -4156,7 +4156,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/integration-react@npm:^1.1.6": +"@backstage/integration-react@npm:^1.1.8": version: 1.1.8 resolution: "@backstage/integration-react@npm:1.1.8" dependencies: @@ -4238,7 +4238,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-adr-backend@workspace:plugins/adr-backend": +"@backstage/plugin-adr-backend@workspace:^, @backstage/plugin-adr-backend@workspace:plugins/adr-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-adr-backend@workspace:plugins/adr-backend" dependencies: @@ -4251,8 +4251,11 @@ __metadata: "@backstage/integration": "workspace:^" "@backstage/plugin-adr-common": "workspace:^" "@backstage/plugin-search-common": "workspace:^" + "@types/express": ^4.17.15 "@types/marked": ^4.0.0 "@types/supertest": ^2.0.8 + express: ^4.18.2 + express-promise-router: ^4.1.1 luxon: ^3.0.0 marked: ^4.0.14 msw: ^0.49.0 @@ -4300,9 +4303,7 @@ __metadata: "@types/git-url-parse": ^9.0.0 "@types/node": "*" cross-fetch: ^3.1.5 - git-url-parse: ^13.0.0 msw: ^0.49.0 - octokit: ^2.0.0 react-markdown: ^8.0.0 react-use: ^17.2.4 remark-gfm: ^3.0.1 @@ -4872,7 +4873,7 @@ __metadata: "@openapitools/openapi-generator-cli": ^2.4.26 cross-fetch: ^3.1.5 msw: ^0.49.0 - ts-morph: ^15.0.0 + ts-morph: ^17.0.0 languageName: unknown linkType: soft @@ -5243,7 +5244,7 @@ __metadata: "@types/lodash": ^4.14.151 "@types/supertest": ^2.0.8 "@types/uuid": ^8.0.0 - better-sqlite3: ^7.5.0 + better-sqlite3: ^8.0.0 codeowners-utils: ^1.0.2 core-js: ^3.6.5 express: ^4.17.1 @@ -5409,7 +5410,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@npm:^1.2.0, @backstage/plugin-catalog-react@npm:^1.2.1, @backstage/plugin-catalog-react@npm:^1.2.3": +"@backstage/plugin-catalog-react@npm:^1.2.0, @backstage/plugin-catalog-react@npm:^1.2.3": version: 1.2.3 resolution: "@backstage/plugin-catalog-react@npm:1.2.3" dependencies: @@ -5476,6 +5477,7 @@ __metadata: cross-fetch: ^3.1.5 jwt-decode: ^3.1.0 lodash: ^4.17.21 + material-ui-popup-state: ^1.9.3 qs: ^6.9.4 react-test-renderer: ^16.13.1 react-use: ^17.2.4 @@ -6497,7 +6499,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-home@npm:^0.4.27, @backstage/plugin-home@npm:^0.4.29": +"@backstage/plugin-home@npm:^0.4.29": version: 0.4.29 resolution: "@backstage/plugin-home@npm:0.4.29" dependencies: @@ -7138,7 +7140,7 @@ __metadata: "@testing-library/react": ^12.1.3 cross-fetch: ^3.1.5 react-use: ^17.2.4 - swr: ^1.1.2 + swr: ^2.0.0 peerDependencies: "@types/react": ^16.13.1 || ^17.0.0 react: ^16.13.1 || ^17.0.0 @@ -7218,7 +7220,7 @@ __metadata: qs: ^6.9.4 react-hook-form: ^7.13.0 react-use: ^17.2.4 - swr: ^1.1.2 + swr: ^2.0.0 peerDependencies: react: ^16.13.1 || ^17.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 @@ -7503,7 +7505,7 @@ __metadata: msw: ^0.49.0 qs: ^6.9.4 react-use: ^17.2.4 - use-immer: ^0.7.0 + use-immer: ^0.8.0 yaml: ^2.0.0 zen-observable: ^0.10.0 zod: ~3.18.0 @@ -8530,8 +8532,8 @@ __metadata: "@backstage/cli-common": "workspace:^" "@backstage/errors": "workspace:^" "@manypkg/get-packages": ^1.1.3 - "@microsoft/api-documenter": ^7.17.11 - "@microsoft/api-extractor": ^7.23.0 + "@microsoft/api-documenter": ^7.19.27 + "@microsoft/api-extractor": ^7.33.7 "@types/is-glob": ^4.0.2 "@types/mock-fs": ^4.13.0 chalk: ^4.0.0 @@ -8546,7 +8548,6 @@ __metadata: "@microsoft/api-extractor-model": "*" "@microsoft/tsdoc": "*" "@microsoft/tsdoc-config": "*" - "@rushstack/node-core-library": "*" prettier: ^2.8.1 typescript: "> 3.0.0" peerDependenciesMeta: @@ -8971,13 +8972,13 @@ __metadata: linkType: hard "@codemirror/view@npm:^6.0.0": - version: 6.7.1 - resolution: "@codemirror/view@npm:6.7.1" + version: 6.7.2 + resolution: "@codemirror/view@npm:6.7.2" dependencies: "@codemirror/state": ^6.1.4 style-mod: ^4.0.0 w3c-keyname: ^2.2.4 - checksum: 75a5846d61e63027e9bf1dfd0b507932934cb7650b7959c1191e68b161eb1756e9773f964c4331970b51864aef8f7954bc5cc8fdb51b0f6533de6c20568833ed + checksum: ad08a4a0a50e2b34c0141311e7db9f045a2186b81ae28271318374b5b9964435267ec0af210b5d061cb84bc8fdca6dabc1919eb7fe05837d931038b9095c3f8c languageName: node linkType: hard @@ -9152,9 +9153,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/android-arm64@npm:0.16.12" +"@esbuild/android-arm64@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/android-arm64@npm:0.16.14" conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -9166,65 +9167,65 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/android-arm@npm:0.16.12" +"@esbuild/android-arm@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/android-arm@npm:0.16.14" conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/android-x64@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/android-x64@npm:0.16.12" +"@esbuild/android-x64@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/android-x64@npm:0.16.14" conditions: os=android & cpu=x64 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/darwin-arm64@npm:0.16.12" +"@esbuild/darwin-arm64@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/darwin-arm64@npm:0.16.14" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/darwin-x64@npm:0.16.12" +"@esbuild/darwin-x64@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/darwin-x64@npm:0.16.14" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/freebsd-arm64@npm:0.16.12" +"@esbuild/freebsd-arm64@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/freebsd-arm64@npm:0.16.14" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/freebsd-x64@npm:0.16.12" +"@esbuild/freebsd-x64@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/freebsd-x64@npm:0.16.14" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/linux-arm64@npm:0.16.12" +"@esbuild/linux-arm64@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/linux-arm64@npm:0.16.14" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/linux-arm@npm:0.16.12" +"@esbuild/linux-arm@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/linux-arm@npm:0.16.14" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/linux-ia32@npm:0.16.12" +"@esbuild/linux-ia32@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/linux-ia32@npm:0.16.14" conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -9236,86 +9237,86 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/linux-loong64@npm:0.16.12" +"@esbuild/linux-loong64@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/linux-loong64@npm:0.16.14" conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/linux-mips64el@npm:0.16.12" +"@esbuild/linux-mips64el@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/linux-mips64el@npm:0.16.14" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/linux-ppc64@npm:0.16.12" +"@esbuild/linux-ppc64@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/linux-ppc64@npm:0.16.14" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/linux-riscv64@npm:0.16.12" +"@esbuild/linux-riscv64@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/linux-riscv64@npm:0.16.14" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/linux-s390x@npm:0.16.12" +"@esbuild/linux-s390x@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/linux-s390x@npm:0.16.14" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/linux-x64@npm:0.16.12" +"@esbuild/linux-x64@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/linux-x64@npm:0.16.14" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/netbsd-x64@npm:0.16.12" +"@esbuild/netbsd-x64@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/netbsd-x64@npm:0.16.14" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/openbsd-x64@npm:0.16.12" +"@esbuild/openbsd-x64@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/openbsd-x64@npm:0.16.14" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/sunos-x64@npm:0.16.12" +"@esbuild/sunos-x64@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/sunos-x64@npm:0.16.14" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/win32-arm64@npm:0.16.12" +"@esbuild/win32-arm64@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/win32-arm64@npm:0.16.14" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/win32-ia32@npm:0.16.12" +"@esbuild/win32-ia32@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/win32-ia32@npm:0.16.14" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.16.12": - version: 0.16.12 - resolution: "@esbuild/win32-x64@npm:0.16.12" +"@esbuild/win32-x64@npm:0.16.14": + version: 0.16.14 + resolution: "@esbuild/win32-x64@npm:0.16.14" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -9449,8 +9450,8 @@ __metadata: linkType: hard "@google-cloud/storage@npm:^6.0.0": - version: 6.8.0 - resolution: "@google-cloud/storage@npm:6.8.0" + version: 6.9.0 + resolution: "@google-cloud/storage@npm:6.9.0" dependencies: "@google-cloud/paginator": ^3.0.7 "@google-cloud/projectify": ^3.0.0 @@ -9469,7 +9470,7 @@ __metadata: retry-request: ^5.0.0 teeny-request: ^8.0.0 uuid: ^8.0.0 - checksum: c0b9eae1eae4aadd22b4ea7699345790adcc063874c5f08477425840001f6822091bdb8db7b67f2a9bb77acbbc4257ed40c14ba5cb2ab91addf2902d56714ddf + checksum: 886b9aad6bd44901b22a6e77c6430bae0effc2137e6c18196d151db8b9690d80726ecc4b60ac1ba315372305010282de6b9845ef23eaa7351449d0193aac62cc languageName: node linkType: hard @@ -9507,8 +9508,8 @@ __metadata: linkType: hard "@graphql-codegen/cli@npm:^2.3.1": - version: 2.16.2 - resolution: "@graphql-codegen/cli@npm:2.16.2" + version: 2.16.3 + resolution: "@graphql-codegen/cli@npm:2.16.3" dependencies: "@babel/generator": ^7.18.13 "@babel/template": ^7.18.10 @@ -9546,12 +9547,13 @@ __metadata: yargs: ^17.0.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 + ts-node: ">=10" bin: gql-gen: cjs/bin.js graphql-code-generator: cjs/bin.js graphql-codegen: cjs/bin.js graphql-codegen-esm: esm/bin.js - checksum: b44a89ba8c536adccc4fe23446df593b3e5a33d7cefb1602c61a714288e0a8d69cd69fcf8543a59edd6023d8cb0e9ab87fe64e418c2ffb5c45d0e57e17ded06a + checksum: 2ad79b30bace5bfe6f7cdc907fee26e1544000e621f2217417358be2e37322bacc684e98cb629d0a61d63df8e7f8aa365d1ef01c9e3173dce516c028b1bb9ee5 languageName: node linkType: hard @@ -9570,18 +9572,18 @@ __metadata: linkType: hard "@graphql-codegen/graphql-modules-preset@npm:^2.3.2": - version: 2.5.10 - resolution: "@graphql-codegen/graphql-modules-preset@npm:2.5.10" + version: 2.5.11 + resolution: "@graphql-codegen/graphql-modules-preset@npm:2.5.11" dependencies: "@graphql-codegen/plugin-helpers": ^3.1.2 - "@graphql-codegen/visitor-plugin-common": 2.13.6 + "@graphql-codegen/visitor-plugin-common": 2.13.7 "@graphql-tools/utils": ^9.0.0 change-case-all: 1.0.15 parse-filepath: ^1.0.2 tslib: ~2.4.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: 559b8cc0c837394d0c972d72656e8ea48c04c542885d55fc66471f6fa968cc314f6f6f57576685c0ea0d8072f3f5752ab98ef758b3406bee1915c06e74093c4b + checksum: c77f05964ff1253ee522ee43ef19e939933b3162150da0d6c0c9fb243020f058af1146160aba307427f0ecf6dfafaa16935fc8fe57cb74f94fb784671bb31f6b languageName: node linkType: hard @@ -9615,39 +9617,39 @@ __metadata: linkType: hard "@graphql-codegen/typescript-resolvers@npm:^2.4.3": - version: 2.7.11 - resolution: "@graphql-codegen/typescript-resolvers@npm:2.7.11" + version: 2.7.12 + resolution: "@graphql-codegen/typescript-resolvers@npm:2.7.12" dependencies: "@graphql-codegen/plugin-helpers": ^3.1.2 - "@graphql-codegen/typescript": ^2.8.6 - "@graphql-codegen/visitor-plugin-common": 2.13.6 + "@graphql-codegen/typescript": ^2.8.7 + "@graphql-codegen/visitor-plugin-common": 2.13.7 "@graphql-tools/utils": ^9.0.0 auto-bind: ~4.0.0 tslib: ~2.4.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: 0954d98f88814dd545cb50cf93d6a6d8616ff6bb999570bd965c177e665a4ff4ed33cf68576c932fd8d630ee0bbcd6888e41801f751f5386286046608167d8ce + checksum: f8f60d972720f42f7407d91febfa4ae91f4e6cc2bd990babe85f8d1c77a3fa8dcc4ac85d8267ce24942703fc28ff6f38f4d8215e098f34fe1b35063aa08ef5a0 languageName: node linkType: hard -"@graphql-codegen/typescript@npm:^2.4.2, @graphql-codegen/typescript@npm:^2.8.6": - version: 2.8.6 - resolution: "@graphql-codegen/typescript@npm:2.8.6" +"@graphql-codegen/typescript@npm:^2.4.2, @graphql-codegen/typescript@npm:^2.8.7": + version: 2.8.7 + resolution: "@graphql-codegen/typescript@npm:2.8.7" dependencies: "@graphql-codegen/plugin-helpers": ^3.1.2 "@graphql-codegen/schema-ast": ^2.6.1 - "@graphql-codegen/visitor-plugin-common": 2.13.6 + "@graphql-codegen/visitor-plugin-common": 2.13.7 auto-bind: ~4.0.0 tslib: ~2.4.0 peerDependencies: graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 15f75f1cfea8d632d05a0836cfe657f580d7a49bfafe9b8a143b32f71985b09773dbc45e1e09010654789ea4dba15952767bc3dc412bda16b90eb57a3657f328 + checksum: 67cbafc0dc8695222fd3b2db26c3fcd91148a1dba7bb5dcf71eaf6425dadbaa378c5703f2844e34718954aa283aa95919d8d4650bd1d0b85b22b404ffc3436fa languageName: node linkType: hard -"@graphql-codegen/visitor-plugin-common@npm:2.13.6": - version: 2.13.6 - resolution: "@graphql-codegen/visitor-plugin-common@npm:2.13.6" +"@graphql-codegen/visitor-plugin-common@npm:2.13.7": + version: 2.13.7 + resolution: "@graphql-codegen/visitor-plugin-common@npm:2.13.7" dependencies: "@graphql-codegen/plugin-helpers": ^3.1.2 "@graphql-tools/optimize": ^1.3.0 @@ -9661,7 +9663,7 @@ __metadata: tslib: ~2.4.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: 3e3bcbe6c7f3fa665b53f35016bce4385fd045ef54b1a986add0b86a14abec6c5b30201496b210ab493afe6bb89bed80f81d164efd643155621fd7bf7fbafec7 + checksum: 4218af8b1542789d9c8c614ccb4362a2b4944d5c3a4a59909844fe9f1f8672825adb28deeb1b9a4d45410e1ae94cde9bd1f5c5d888ae53469260d6668814732e languageName: node linkType: hard @@ -11628,53 +11630,53 @@ __metadata: languageName: node linkType: hard -"@microsoft/api-documenter@npm:^7.17.11": - version: 7.17.11 - resolution: "@microsoft/api-documenter@npm:7.17.11" +"@microsoft/api-documenter@npm:^7.19.27": + version: 7.19.27 + resolution: "@microsoft/api-documenter@npm:7.19.27" dependencies: - "@microsoft/api-extractor-model": 7.17.2 - "@microsoft/tsdoc": 0.14.1 - "@rushstack/node-core-library": 3.45.4 - "@rushstack/ts-command-line": 4.10.10 + "@microsoft/api-extractor-model": 7.25.3 + "@microsoft/tsdoc": 0.14.2 + "@rushstack/node-core-library": 3.53.3 + "@rushstack/ts-command-line": 4.13.1 colors: ~1.2.1 js-yaml: ~3.13.1 - resolve: ~1.17.0 + resolve: ~1.22.1 bin: api-documenter: bin/api-documenter - checksum: 55f5c5d15dc8d97fc0582dc501e84f4ef9b9cbff71e9bf662d6262751ed38e691907f34ab4d57785cf2f03acf82c4957def804f77d1c85383ff2a80da51c7a60 + checksum: f243f473e1fe58e1cd6e32aad223724b6b621f569276415380abc4845859bf5c23fbe0e370be2a218f362a6c85b01b44b5427336f55800f2ea8bf3f398b0ee41 languageName: node linkType: hard -"@microsoft/api-extractor-model@npm:7.17.2": - version: 7.17.2 - resolution: "@microsoft/api-extractor-model@npm:7.17.2" +"@microsoft/api-extractor-model@npm:7.25.3": + version: 7.25.3 + resolution: "@microsoft/api-extractor-model@npm:7.25.3" dependencies: - "@microsoft/tsdoc": 0.14.1 + "@microsoft/tsdoc": 0.14.2 "@microsoft/tsdoc-config": ~0.16.1 - "@rushstack/node-core-library": 3.45.4 - checksum: 94c1c63674d85bf69cff9abbf94a1b2d2f5b6e3b651b8483d8949e39424cb29df156b589a297ca19f85ad1ff6380389e58a03198e7fe1ec34b59d5cae2166de7 + "@rushstack/node-core-library": 3.53.3 + checksum: 532ca30606b5649e90035ef70ff46868f6ccc63181e10b783bc5092e580bcb133112b300799b8f71a19da2b79f685a55f7ddbe84c8fe7ad93d71359c1763c521 languageName: node linkType: hard -"@microsoft/api-extractor@npm:^7.23.0": - version: 7.23.0 - resolution: "@microsoft/api-extractor@npm:7.23.0" +"@microsoft/api-extractor@npm:^7.33.7": + version: 7.33.7 + resolution: "@microsoft/api-extractor@npm:7.33.7" dependencies: - "@microsoft/api-extractor-model": 7.17.2 - "@microsoft/tsdoc": 0.14.1 + "@microsoft/api-extractor-model": 7.25.3 + "@microsoft/tsdoc": 0.14.2 "@microsoft/tsdoc-config": ~0.16.1 - "@rushstack/node-core-library": 3.45.4 - "@rushstack/rig-package": 0.3.11 - "@rushstack/ts-command-line": 4.10.10 + "@rushstack/node-core-library": 3.53.3 + "@rushstack/rig-package": 0.3.17 + "@rushstack/ts-command-line": 4.13.1 colors: ~1.2.1 lodash: ~4.17.15 resolve: ~1.17.0 semver: ~7.3.0 source-map: ~0.6.1 - typescript: ~4.6.3 + typescript: ~4.8.4 bin: api-extractor: bin/api-extractor - checksum: 61d3609d7aa76bece292551eb9c7a1c04c2fa304962c8b7e97aa3b3add0431a225c022e32993e384a51290e121542c6a6b3ad4be24f5315a4c1501cf821018a2 + checksum: 3f9034ca8e7bc7a6622cb8ac1f53f7f265ebca529e17f4abb2bef0ca297011cfa0927c0703a819607d974ca79b8f5307371491cfb192788e723cfd316250f9a6 languageName: node linkType: hard @@ -11697,13 +11699,6 @@ __metadata: languageName: node linkType: hard -"@microsoft/tsdoc@npm:0.14.1": - version: 0.14.1 - resolution: "@microsoft/tsdoc@npm:0.14.1" - checksum: e4ad038ccff2cd96e0d53ee42e2136f0f5a925b16cfda14261f1c2eb55ba0088a0e3b08ff819b476ddc69b2242a391925fab7f6ae2afabb19b96f87e19c114fc - languageName: node - linkType: hard - "@microsoft/tsdoc@npm:0.14.2": version: 0.14.2 resolution: "@microsoft/tsdoc@npm:0.14.2" @@ -12523,14 +12518,14 @@ __metadata: linkType: hard "@octokit/webhooks@npm:^10.0.0": - version: 10.4.0 - resolution: "@octokit/webhooks@npm:10.4.0" + version: 10.5.0 + resolution: "@octokit/webhooks@npm:10.5.0" dependencies: "@octokit/request-error": ^3.0.0 "@octokit/webhooks-methods": ^3.0.0 "@octokit/webhooks-types": 6.7.0 aggregate-error: ^3.1.0 - checksum: 418de82c4840024d608bb523ffc6c98f07179a40096a9970d9ac2e09bc98e99a25c035d57038c992b3c764ae085a62befbc0165ebacda8963aa513aa72330f74 + checksum: eb1ff2cc8f14537e619d2502d0d281920e11cc68f96d587a3a38fecf7d4453cc3dac567f532a2252f067dec7044a1b53e7c043d8be4732f3c0a8b1b0b8ddee8b languageName: node linkType: hard @@ -12789,8 +12784,8 @@ __metadata: linkType: hard "@react-hookz/web@npm:^20.0.0": - version: 20.0.3 - resolution: "@react-hookz/web@npm:20.0.3" + version: 20.1.0 + resolution: "@react-hookz/web@npm:20.1.0" dependencies: "@react-hookz/deep-equal": ^1.0.4 peerDependencies: @@ -12800,7 +12795,7 @@ __metadata: peerDependenciesMeta: js-cookie: optional: true - checksum: b4942f422fc36c93138b9735ee9ef768214f9f32fca73e4b3d545e490bd043e92f2ee0ce65c0ffc57f7c47a8cec9742e6f80e9e06bf875a805ba606dffa06f3d + checksum: bb393f892c2c81deff37d5f18faf8ec17431a24994d72d88ec390dcc1579b27318a7c8c6260070c87b66e8c635e4daec4436c33abf2622f842d1567235ed457d languageName: node linkType: hard @@ -12906,13 +12901,13 @@ __metadata: linkType: hard "@roadiehq/backstage-plugin-buildkite@npm:^2.0.8": - version: 2.1.1 - resolution: "@roadiehq/backstage-plugin-buildkite@npm:2.1.1" + version: 2.1.2 + resolution: "@roadiehq/backstage-plugin-buildkite@npm:2.1.2" dependencies: - "@backstage/catalog-model": ^1.1.3 - "@backstage/core-components": ^0.12.0 - "@backstage/core-plugin-api": ^1.1.0 - "@backstage/plugin-catalog-react": ^1.2.1 + "@backstage/catalog-model": ^1.1.4 + "@backstage/core-components": ^0.12.2 + "@backstage/core-plugin-api": ^1.2.0 + "@backstage/plugin-catalog-react": ^1.2.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.12.1 "@material-ui/icons": ^4.11.2 @@ -12925,19 +12920,19 @@ __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: 04121a556d6745cef4db0f2bc60218e0774056f26c09c195e4cf7ba29d8c7a601c24d13c8e077c904df312a1f6464942467c29be796b49156774af4029b7ec7b + checksum: fc607c7eac3a680db9ecc4c33bc65e84cdff432dc1079343f6e1ce66459324eba31a16a647b669c163e87c8b1794a01e66b4ba4f9fd77611d3081a0317cf68ac languageName: node linkType: hard "@roadiehq/backstage-plugin-github-insights@npm:^2.0.5": - version: 2.3.0 - resolution: "@roadiehq/backstage-plugin-github-insights@npm:2.3.0" + version: 2.3.2 + resolution: "@roadiehq/backstage-plugin-github-insights@npm:2.3.2" dependencies: - "@backstage/catalog-model": ^1.1.3 - "@backstage/core-components": ^0.12.0 - "@backstage/core-plugin-api": ^1.1.0 - "@backstage/integration-react": ^1.1.6 - "@backstage/plugin-catalog-react": ^1.2.1 + "@backstage/catalog-model": ^1.1.4 + "@backstage/core-components": ^0.12.2 + "@backstage/core-plugin-api": ^1.2.0 + "@backstage/integration-react": ^1.1.8 + "@backstage/plugin-catalog-react": ^1.2.3 "@backstage/theme": ^0.2.16 "@date-io/core": 2.10.7 "@material-ui/core": ^4.11.0 @@ -12953,19 +12948,19 @@ __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: 874fc76baf02ac6568f150aaf14ef4a35ddbffca410a44350c2cd4f47c900e28aa6d7d82ddfc0dd3065fc6764abd16af2a802d303f9af47ff296006cd14afe2a + checksum: 9c38cb944a9f37c3a0836dd4d5b41bc8329f124a026ce5f0c5ea467477ae87e6f699669c1c0873a9d29d791f6f870279bc7e83bc426111f540f8f6f54aad6f8a languageName: node linkType: hard "@roadiehq/backstage-plugin-github-pull-requests@npm:^2.2.7": - version: 2.4.1 - resolution: "@roadiehq/backstage-plugin-github-pull-requests@npm:2.4.1" + version: 2.4.2 + resolution: "@roadiehq/backstage-plugin-github-pull-requests@npm:2.4.2" dependencies: - "@backstage/catalog-model": ^1.1.3 - "@backstage/core-components": ^0.12.0 - "@backstage/core-plugin-api": ^1.1.0 - "@backstage/plugin-catalog-react": ^1.2.1 - "@backstage/plugin-home": ^0.4.27 + "@backstage/catalog-model": ^1.1.4 + "@backstage/core-components": ^0.12.2 + "@backstage/core-plugin-api": ^1.2.0 + "@backstage/plugin-catalog-react": ^1.2.3 + "@backstage/plugin-home": ^0.4.29 "@material-ui/core": ^4.11.0 "@material-ui/icons": ^4.9.1 "@material-ui/lab": ^4.0.0-alpha.60 @@ -12982,18 +12977,18 @@ __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: 41fa25e70fbe01bd26ea97cfd98fcff6c32771f437a28a3ed37078906290daf5d52ec0f0613caa559a09b6f8cacb923c0b6522d78de488909911f46433e189ee + checksum: d2b80b4c25a0bdca2e6dcd8ddf2fc26aa75374d5278fc235551fb213f3c0269e81cb141afd98c3a2a3073c39cfe35db69b1c265a615dd880777ab2e6c6a69d22 languageName: node linkType: hard "@roadiehq/backstage-plugin-travis-ci@npm:^2.0.5": - version: 2.1.1 - resolution: "@roadiehq/backstage-plugin-travis-ci@npm:2.1.1" + version: 2.1.2 + resolution: "@roadiehq/backstage-plugin-travis-ci@npm:2.1.2" dependencies: - "@backstage/catalog-model": ^1.1.3 - "@backstage/core-components": ^0.12.0 - "@backstage/core-plugin-api": ^1.1.0 - "@backstage/plugin-catalog-react": ^1.2.1 + "@backstage/catalog-model": ^1.1.4 + "@backstage/core-components": ^0.12.2 + "@backstage/core-plugin-api": ^1.2.0 + "@backstage/plugin-catalog-react": ^1.2.3 "@backstage/theme": ^0.2.16 "@material-ui/core": ^4.11.3 "@material-ui/icons": ^4.11.2 @@ -13008,7 +13003,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: 23cb8760c6d140052fcdc22007b59349332afd565ee2b65e8bba4a1b5c5d409ef6505f292d1e5c62d3c281898b65eb83397aa790480e9e1becda3452ef6d086c + checksum: 64e2878fd517e63eb765a65c60f1276cc6a12e4abb128001ed92a1e634546c0ec9236cbb67c6b534ece126fe64b5fb251e985fe3e5f42ce4500b6108b9f7f889 languageName: node linkType: hard @@ -13116,9 +13111,9 @@ __metadata: languageName: node linkType: hard -"@rushstack/node-core-library@npm:3.45.4": - version: 3.45.4 - resolution: "@rushstack/node-core-library@npm:3.45.4" +"@rushstack/node-core-library@npm:3.53.3": + version: 3.53.3 + resolution: "@rushstack/node-core-library@npm:3.53.3" dependencies: "@types/node": 12.20.24 colors: ~1.2.1 @@ -13127,31 +13122,30 @@ __metadata: jju: ~1.4.0 resolve: ~1.17.0 semver: ~7.3.0 - timsort: ~0.3.0 z-schema: ~5.0.2 - checksum: f7049be8c145ef1d1ee2ee29b917440a3c88a5e4906c5b6bebe0d4c7854c93b759b7563475be383a4cedf8afd3914b34a6b988fe67b8dfce33545223b2a46cca + checksum: 265d18e176079b8e90cd507e5d4d45f3afb1f811efdf491ea26f25f0397b77c0e9d42065166bf79a04503426c844ea92034cd3f8d5961b2a116de82e45cf6d6a languageName: node linkType: hard -"@rushstack/rig-package@npm:0.3.11": - version: 0.3.11 - resolution: "@rushstack/rig-package@npm:0.3.11" +"@rushstack/rig-package@npm:0.3.17": + version: 0.3.17 + resolution: "@rushstack/rig-package@npm:0.3.17" dependencies: resolve: ~1.17.0 strip-json-comments: ~3.1.1 - checksum: a6354152a9ac7503a217e7903d2739d35f305b2331f880fca94e6f309ba78e86b58fa8eda888238429bc4203a5cef4df4218f80e636fa75290e68875b971697a + checksum: 54eeea471c85b547575d7efc84fad3c9588f10106e2bfd8cd022bccb02c2fb0bf8ff597fab9114450b3c262abab0f0a4e52dd074bfd120e850b95037cd7b3102 languageName: node linkType: hard -"@rushstack/ts-command-line@npm:4.10.10": - version: 4.10.10 - resolution: "@rushstack/ts-command-line@npm:4.10.10" +"@rushstack/ts-command-line@npm:4.13.1": + version: 4.13.1 + resolution: "@rushstack/ts-command-line@npm:4.13.1" dependencies: "@types/argparse": 1.0.38 argparse: ~1.0.9 colors: ~1.2.1 string-argv: ~0.3.1 - checksum: e2d47cbe6df4c47e297ef84b83f1f6f2306ae14cd765066ea966f3e6ed48e1382d20c942a324ff9e389f5e673a9e1ba477f5b9514303709fcf85f28e14cdd26c + checksum: fea24b2549ecb7d3409b6b485d7c58bf8af8f8d1dd19c43a6b3532c45579ffc546bc4533b5db29c91ae1716581fdee4cb725f6a81ecb300e902ef06600e59f1d languageName: node linkType: hard @@ -13650,18 +13644,18 @@ __metadata: languageName: node linkType: hard -"@tanstack/query-core@npm:4.20.4": - version: 4.20.4 - resolution: "@tanstack/query-core@npm:4.20.4" - checksum: bdb652296e4093d8cb042a67b9c035bc0a756e09a3b12aeb070068b07adc1c71174c2e6108f2a8c3322a26cb73ba57f431326aa0b813c81621674b9cc208cd93 +"@tanstack/query-core@npm:4.20.9": + version: 4.20.9 + resolution: "@tanstack/query-core@npm:4.20.9" + checksum: 679551353e6d5adcae771bc78b64959a6ecf4f85c1f74952b38b18a7425374cf84dc2e461cf6048be206d8bbac265468d36231f7f9d0b6689504a0e069dd5ac6 languageName: node linkType: hard "@tanstack/react-query@npm:^4.1.3": - version: 4.20.4 - resolution: "@tanstack/react-query@npm:4.20.4" + version: 4.20.9 + resolution: "@tanstack/react-query@npm:4.20.9" dependencies: - "@tanstack/query-core": 4.20.4 + "@tanstack/query-core": 4.20.9 use-sync-external-store: ^1.2.0 peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -13672,7 +13666,7 @@ __metadata: optional: true react-native: optional: true - checksum: ba9e2f175c58bde592c0ad14285f289585474763f8d68072d651fa75263a3a7f75eead5b62aa3140db133b95468498bc58817d07513f6f857be2bd8031b491da + checksum: 4fc953d774c5c0f7f332f014dfb2fb9865387ae6e849fdf551e2ad70f07d55fbdbc4c6afb27a1f90bce3a2348bd1adf67ab78a4bc2cdf8d3e5ff90128730b467 languageName: node linkType: hard @@ -13841,15 +13835,15 @@ __metadata: languageName: node linkType: hard -"@ts-morph/common@npm:~0.16.0": - version: 0.16.0 - resolution: "@ts-morph/common@npm:0.16.0" +"@ts-morph/common@npm:~0.18.0": + version: 0.18.1 + resolution: "@ts-morph/common@npm:0.18.1" dependencies: - fast-glob: ^3.2.11 + fast-glob: ^3.2.12 minimatch: ^5.1.0 mkdirp: ^1.0.4 path-browserify: ^1.0.1 - checksum: 0ef97330a164a42b81b0499b042e91db8e39d705bb983ef83cbc80cc32ab36123e26baefb78203953d1a0c6e3b92cad9bc7a5e0ea409623a5e7db90cb3742112 + checksum: 848fff5f7a6428d7c2f055de20cf8df864a967aac0cc03adc558d853442085a8fd9dec70429da24d67d263794b315edb0791c46d23ad9ae513251a7702df8031 languageName: node linkType: hard @@ -14412,7 +14406,7 @@ __metadata: languageName: node linkType: hard -"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.18, @types/express-serve-static-core@npm:^4.17.5": +"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.18, @types/express-serve-static-core@npm:^4.17.31, @types/express-serve-static-core@npm:^4.17.5": version: 4.17.32 resolution: "@types/express-serve-static-core@npm:4.17.32" dependencies: @@ -14453,7 +14447,19 @@ __metadata: languageName: node linkType: hard -"@types/express@npm:*, @types/express@npm:4.17.14, @types/express@npm:^4.17.13, @types/express@npm:^4.17.6": +"@types/express@npm:*, @types/express@npm:^4.17.13, @types/express@npm:^4.17.15, @types/express@npm:^4.17.6": + version: 4.17.15 + resolution: "@types/express@npm:4.17.15" + dependencies: + "@types/body-parser": "*" + "@types/express-serve-static-core": ^4.17.31 + "@types/qs": "*" + "@types/serve-static": "*" + checksum: b4acd8a836d4f6409cdf79b12d6e660485249b62500cccd61e7997d2f520093edf77d7f8498ca79d64a112c6434b6de5ca48039b8fde2c881679eced7e96979b + languageName: node + linkType: hard + +"@types/express@npm:4.17.14": version: 4.17.14 resolution: "@types/express@npm:4.17.14" dependencies: @@ -16401,14 +16407,14 @@ __metadata: linkType: hard "ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.8.0": - version: 8.11.2 - resolution: "ajv@npm:8.11.2" + version: 8.12.0 + resolution: "ajv@npm:8.12.0" dependencies: fast-deep-equal: ^3.1.1 json-schema-traverse: ^1.0.0 require-from-string: ^2.0.2 uri-js: ^4.2.2 - checksum: 53435bf79ee7d1eabba8085962dba4c08d08593334b304db7772887f0b7beebc1b3d957432f7437ed4b60e53b5d966a57b439869890209c50fed610459999e3e + checksum: 4dc13714e316e67537c8b31bc063f99a1d9d9a497eb4bbd55191ac0dcd5e4985bbb71570352ad6f1e76684fb6d790928f96ba3b2d4fd6e10024be9612fe3f001 languageName: node linkType: hard @@ -17598,14 +17604,14 @@ __metadata: languageName: node linkType: hard -"better-sqlite3@npm:^7.5.0": - version: 7.6.2 - resolution: "better-sqlite3@npm:7.6.2" +"better-sqlite3@npm:^8.0.0": + version: 8.0.1 + resolution: "better-sqlite3@npm:8.0.1" dependencies: bindings: ^1.5.0 node-gyp: latest prebuild-install: ^7.1.0 - checksum: 45159e535d2c4f81456f85adcfef82e8a49025ca3e70a79bb8c0a47c13e4d822633a51b457cc37b986c42f8912344152091c91cab485048a187900aab7e7d619 + checksum: 533b2cc32bd54e2a943a4f63e079f8cc8945879b7a0ebd2085b948824ea067792f6f903ab75ba75d7cafc5f8f973354cdf9a042fa6216e077925d07a8df1bead languageName: node linkType: hard @@ -18787,12 +18793,10 @@ __metadata: languageName: node linkType: hard -"code-block-writer@npm:^11.0.0": - version: 11.0.0 - resolution: "code-block-writer@npm:11.0.0" - dependencies: - tslib: 2.3.1 - checksum: d3d92a06f762d5926ecdb2033e4f30eb4c51aca365ea69ef424afbce7cc2b1518a50deff2645cc17b6fa53f234d664631f2268a4caf91af6a1fd696aa0b2fefb +"code-block-writer@npm:^11.0.3": + version: 11.0.3 + resolution: "code-block-writer@npm:11.0.3" + checksum: f0a2605f19963d7087267c9b0fd0b05a6638a50e7b29b70f97aa01a514f59475b0626f8aa092188df853ee6d96745426dfa132d6a677795df462c6ce32c21639 languageName: node linkType: hard @@ -19491,6 +19495,18 @@ __metadata: languageName: node linkType: hard +"cosmiconfig@npm:8.0.0": + version: 8.0.0 + resolution: "cosmiconfig@npm:8.0.0" + dependencies: + import-fresh: ^3.2.1 + js-yaml: ^4.1.0 + parse-json: ^5.0.0 + path-type: ^4.0.0 + checksum: ff4cdf89ac1ae52e7520816622c21a9e04380d04b82d653f5139ec581aa4f7f29e096d46770bc76c4a63c225367e88a1dfa233ea791669a35101f5f9b972c7d1 + languageName: node + linkType: hard + "cosmiconfig@npm:^6.0.0": version: 6.0.0 resolution: "cosmiconfig@npm:6.0.0" @@ -20673,10 +20689,10 @@ __metadata: languageName: node linkType: hard -"devtools-protocol@npm:0.0.1036444": - version: 0.0.1036444 - resolution: "devtools-protocol@npm:0.0.1036444" - checksum: 6975c8def95a5e1a4207d6deb05322e335d6a37bdaa3e589cbd5bde40fbbe3ab0df2cfedb1b3ad2785401f208c150fd489a6a065a4624b56e4c0c4c1bfd89172 +"devtools-protocol@npm:0.0.1068969": + version: 0.0.1068969 + resolution: "devtools-protocol@npm:0.0.1068969" + checksum: 53b9c8d661e4148eaf8e990f03902fb3a2cceb06044f661013b6c92dd48ece397ef49fd18401775823c9a33069b4b535502f2559d4f99c74a6bdcb71582b6c8a languageName: node linkType: hard @@ -21056,7 +21072,7 @@ __metadata: handlebars: ^4.7.3 nodemon: ^2.0.2 pgtools: ^0.3.0 - puppeteer: ^17.0.0 + puppeteer: ^19.0.0 tree-kill: ^1.2.2 ts-node: ^10.0.0 bin: @@ -21666,31 +21682,31 @@ __metadata: linkType: hard "esbuild@npm:^0.16.0": - version: 0.16.12 - resolution: "esbuild@npm:0.16.12" + version: 0.16.14 + resolution: "esbuild@npm:0.16.14" dependencies: - "@esbuild/android-arm": 0.16.12 - "@esbuild/android-arm64": 0.16.12 - "@esbuild/android-x64": 0.16.12 - "@esbuild/darwin-arm64": 0.16.12 - "@esbuild/darwin-x64": 0.16.12 - "@esbuild/freebsd-arm64": 0.16.12 - "@esbuild/freebsd-x64": 0.16.12 - "@esbuild/linux-arm": 0.16.12 - "@esbuild/linux-arm64": 0.16.12 - "@esbuild/linux-ia32": 0.16.12 - "@esbuild/linux-loong64": 0.16.12 - "@esbuild/linux-mips64el": 0.16.12 - "@esbuild/linux-ppc64": 0.16.12 - "@esbuild/linux-riscv64": 0.16.12 - "@esbuild/linux-s390x": 0.16.12 - "@esbuild/linux-x64": 0.16.12 - "@esbuild/netbsd-x64": 0.16.12 - "@esbuild/openbsd-x64": 0.16.12 - "@esbuild/sunos-x64": 0.16.12 - "@esbuild/win32-arm64": 0.16.12 - "@esbuild/win32-ia32": 0.16.12 - "@esbuild/win32-x64": 0.16.12 + "@esbuild/android-arm": 0.16.14 + "@esbuild/android-arm64": 0.16.14 + "@esbuild/android-x64": 0.16.14 + "@esbuild/darwin-arm64": 0.16.14 + "@esbuild/darwin-x64": 0.16.14 + "@esbuild/freebsd-arm64": 0.16.14 + "@esbuild/freebsd-x64": 0.16.14 + "@esbuild/linux-arm": 0.16.14 + "@esbuild/linux-arm64": 0.16.14 + "@esbuild/linux-ia32": 0.16.14 + "@esbuild/linux-loong64": 0.16.14 + "@esbuild/linux-mips64el": 0.16.14 + "@esbuild/linux-ppc64": 0.16.14 + "@esbuild/linux-riscv64": 0.16.14 + "@esbuild/linux-s390x": 0.16.14 + "@esbuild/linux-x64": 0.16.14 + "@esbuild/netbsd-x64": 0.16.14 + "@esbuild/openbsd-x64": 0.16.14 + "@esbuild/sunos-x64": 0.16.14 + "@esbuild/win32-arm64": 0.16.14 + "@esbuild/win32-ia32": 0.16.14 + "@esbuild/win32-x64": 0.16.14 dependenciesMeta: "@esbuild/android-arm": optional: true @@ -21738,7 +21754,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 608faf85bcc6d970e4a3261c2a15dfe7e72b850a9115e90b22f2ab89b4adb2a9e281ef3dec8450ae4c4a5c4fab192b0e6cda468f08390e59bc230b7a5e5f5b5c + checksum: befe262cce76f30518834a385922984a363c9223e8c4c03afc9b54fa43376cc47cadf526a335e97794c824bff395f303f1d51334dbea5e1923a361ee39267cf3 languageName: node linkType: hard @@ -22437,6 +22453,7 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/integration": "workspace:^" + "@backstage/plugin-adr-backend": "workspace:^" "@backstage/plugin-app-backend": "workspace:^" "@backstage/plugin-auth-backend": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" @@ -22478,7 +22495,7 @@ __metadata: "@types/express-serve-static-core": ^4.17.5 "@types/luxon": ^3.0.0 azure-devops-node-api: ^11.0.1 - better-sqlite3: ^7.5.0 + better-sqlite3: ^8.0.0 dockerode: ^3.3.1 example-app: "link:../app" express: ^4.17.1 @@ -22635,7 +22652,7 @@ __metadata: languageName: node linkType: hard -"express-promise-router@npm:^4.1.0": +"express-promise-router@npm:^4.1.0, express-promise-router@npm:^4.1.1": version: 4.1.1 resolution: "express-promise-router@npm:4.1.1" dependencies: @@ -22677,7 +22694,7 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.17.1, express@npm:^4.17.3, express@npm:^4.18.1": +"express@npm:^4.17.1, express@npm:^4.17.3, express@npm:^4.18.1, express@npm:^4.18.2": version: 4.18.2 resolution: "express@npm:4.18.2" dependencies: @@ -22807,16 +22824,16 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.9": - version: 3.2.11 - resolution: "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: "@nodelib/fs.stat": ^2.0.2 "@nodelib/fs.walk": ^1.2.3 glob-parent: ^5.1.2 merge2: ^1.3.0 micromatch: ^4.0.4 - checksum: f473105324a7780a20c06de842e15ddbb41d3cb7e71d1e4fe6e8373204f22245d54f5ab9e2061e6a1c613047345954d29b022e0e76f5c28b1df9858179a0e6d7 + checksum: 0b1990f6ce831c7e28c4d505edcdaad8e27e88ab9fa65eedadb730438cfc7cde4910d6c975d6b7b8dc8a73da4773702ebcfcd6e3518e73938bb1383badfe01c2 languageName: node linkType: hard @@ -24849,11 +24866,11 @@ __metadata: linkType: hard "husky@npm:^8.0.0": - version: 8.0.2 - resolution: "husky@npm:8.0.2" + version: 8.0.3 + resolution: "husky@npm:8.0.3" bin: husky: lib/bin.js - checksum: e101656fcb56163d610488f186448c78b132626aa427094489d886ce9374955a90274912b0f3a34af3326eaa74977883b032e5f701d7aaf4554daa5a7931be43 + checksum: 837bc7e4413e58c1f2946d38fb050f5d7324c6f16b0fd66411ffce5703b294bd21429e8ba58711cd331951ee86ed529c5be4f76805959ff668a337dbfa82a1b0 languageName: node linkType: hard @@ -24977,9 +24994,9 @@ __metadata: linkType: hard "immer@npm:^9.0.1, immer@npm:^9.0.7": - version: 9.0.16 - resolution: "immer@npm:9.0.16" - checksum: e9a5ca65c929b329da7a3b7beccf7984271cda7bdd47b2cab619eac3277dcd56598c211b55cc340786b6eff0c06652ac018808d9fd744443f06882364dece6bc + version: 9.0.17 + resolution: "immer@npm:9.0.17" + checksum: 046d562b74f050632d2861042dbcad49a5e86ffe5bb9b8bff6e699b1c7d8478019d9a3be61e72117cecc29826d2caa4fa927a7e10262381144dd33c735b9531c languageName: node linkType: hard @@ -28408,9 +28425,9 @@ __metadata: linkType: hard "luxon@npm:^3.0.0": - version: 3.2.0 - resolution: "luxon@npm:3.2.0" - checksum: 9a54fc68f1735259095299616c7d01967fb52a9c3500c6b31f97c477574122c62dc0f119d13abc04daaf545e1b8f37a63642b45cd04a240ff59987ceb6ec02c0 + version: 3.2.1 + resolution: "luxon@npm:3.2.1" + checksum: 3fa3def2c5f5d3032b4c46220c4da8aeb467ac979888fc9d2557adcd22195f93516b4ad5909a75862bec8dc6ddc0953b0f38e6d2f4a8ab8450ddc531a83cf20d languageName: node linkType: hard @@ -32787,22 +32804,34 @@ __metadata: languageName: node linkType: hard -"puppeteer@npm:^17.0.0": - version: 17.1.3 - resolution: "puppeteer@npm:17.1.3" +"puppeteer-core@npm:19.4.1": + version: 19.4.1 + resolution: "puppeteer-core@npm:19.4.1" dependencies: cross-fetch: 3.1.5 debug: 4.3.4 - devtools-protocol: 0.0.1036444 + devtools-protocol: 0.0.1068969 extract-zip: 2.0.1 https-proxy-agent: 5.0.1 - progress: 2.0.3 proxy-from-env: 1.1.0 rimraf: 3.0.2 tar-fs: 2.1.1 unbzip2-stream: 1.4.3 - ws: 8.8.1 - checksum: b4518956c661df4c37690d46b9c6744d42d59d01fe3764938b4b3af8de4c94ef11a9dfa6bc261798f5e5490c6dce4d4f555f05d42c735249683da3017faf4585 + ws: 8.11.0 + checksum: f4db1aa1d1e642356744bed2dc49ff7960a8b530d147ace1fe067937433ae40234ea973260b9b264d53a2f2297f53df796d008d4756f735b3f0a64a69724eaba + languageName: node + linkType: hard + +"puppeteer@npm:^19.0.0": + version: 19.4.1 + resolution: "puppeteer@npm:19.4.1" + dependencies: + cosmiconfig: 8.0.0 + https-proxy-agent: 5.0.1 + progress: 2.0.3 + proxy-from-env: 1.1.0 + puppeteer-core: 19.4.1 + checksum: 14b6bd8d5f73f389e5bf424df6a89c346b7a8a8d0326b6aa3670e447a98b638b9091f46b6980515d56152b916a4e7be49c21f25fe7bb5c66828e02466a891f57 languageName: node linkType: hard @@ -34208,7 +34237,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.1.6, resolve@npm:^1.10.0, resolve@npm:^1.14.2, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.0": +"resolve@npm:^1.1.6, resolve@npm:^1.10.0, resolve@npm:^1.14.2, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.0, resolve@npm:~1.22.1": version: 1.22.1 resolution: "resolve@npm:1.22.1" dependencies: @@ -34250,7 +34279,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.0#~builtin": +"resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.0#~builtin, resolve@patch:resolve@~1.22.1#~builtin": version: 1.22.1 resolution: "resolve@patch:resolve@npm%3A1.22.1#~builtin::version=1.22.1&hash=07638b" dependencies: @@ -36488,6 +36517,17 @@ __metadata: languageName: node linkType: hard +"swr@npm:^2.0.0": + version: 2.0.0 + resolution: "swr@npm:2.0.0" + dependencies: + use-sync-external-store: ^1.2.0 + peerDependencies: + react: ^16.11.0 || ^17.0.0 || ^18.0.0 + checksum: 4852d8318ed022a681b40a384e675f65e211104d62075c1250b02f47cc8b739cb9138a954e2191c700e2de22b010b9bd05a113c71b193abe0c351d3c4f4646d8 + languageName: node + linkType: hard + "symbol-observable@npm:1.2.0, symbol-observable@npm:^1.0.4": version: 1.2.0 resolution: "symbol-observable@npm:1.2.0" @@ -36834,7 +36874,7 @@ __metadata: languageName: node linkType: hard -"timsort@npm:^0.3.0, timsort@npm:~0.3.0": +"timsort@npm:^0.3.0": version: 0.3.0 resolution: "timsort@npm:0.3.0" checksum: 1a66cb897dacabd7dd7c91b7e2301498ca9e224de2edb9e42d19f5b17c4b6dc62a8d4cbc64f28be82aaf1541cb5a78ab49aa818f42a2989ebe049a64af731e2a @@ -37129,13 +37169,13 @@ __metadata: languageName: node linkType: hard -"ts-morph@npm:^15.0.0": - version: 15.1.0 - resolution: "ts-morph@npm:15.1.0" +"ts-morph@npm:^17.0.0": + version: 17.0.1 + resolution: "ts-morph@npm:17.0.1" dependencies: - "@ts-morph/common": ~0.16.0 - code-block-writer: ^11.0.0 - checksum: 95e026214282850f08d1d4de673e969cdc166cb6d9366e455e1ea0251a204f80cffcb958c8ed7b1f351e56b972c4244e0dc7be0b13df3c4a6f22abdd4d4608e4 + "@ts-morph/common": ~0.18.0 + code-block-writer: ^11.0.3 + checksum: 4748ab45d0fb0be235f69399ea217cf1c5984ad2ef3ff9eba5a417571f73098c6f1f765fc011eaadc48179471b977f1e44f72eb993932e5c74c5031ab6c60f3a languageName: node linkType: hard @@ -37342,7 +37382,7 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^2.0.0, type-fest@npm:^2.19.0": +"type-fest@npm:^2.19.0": version: 2.19.0 resolution: "type-fest@npm:2.19.0" checksum: a4ef07ece297c9fba78fc1bd6d85dff4472fe043ede98bd4710d2615d15776902b595abf62bd78339ed6278f021235fb28a96361f8be86ed754f778973a0d278 @@ -37395,16 +37435,6 @@ __metadata: languageName: node linkType: hard -"typescript@npm:~4.6.3": - version: 4.6.4 - resolution: "typescript@npm:4.6.4" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: e7bfcc39cd4571a63a54e5ea21f16b8445268b9900bf55aee0e02ad981be576acc140eba24f1af5e3c1457767c96cea6d12861768fb386cf3ffb34013718631a - languageName: node - linkType: hard - "typescript@npm:~4.7.0": version: 4.7.4 resolution: "typescript@npm:4.7.4" @@ -37415,7 +37445,7 @@ __metadata: languageName: node linkType: hard -"typescript@npm:~4.8.2": +"typescript@npm:~4.8.2, typescript@npm:~4.8.4": version: 4.8.4 resolution: "typescript@npm:4.8.4" bin: @@ -37425,16 +37455,6 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@~4.6.3#~builtin": - version: 4.6.4 - resolution: "typescript@patch:typescript@npm%3A4.6.4#~builtin::version=4.6.4&hash=a1c5e5" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 1cb434fbc637d347be90e3a0c6cd05e33c38f941713c8786d3031faf1842c2c148ba91d2fac01e7276b0ae3249b8633f1660e32686cc7a8c6a8fd5361dc52c66 - languageName: node - linkType: hard - "typescript@patch:typescript@~4.7.0#~builtin": version: 4.7.4 resolution: "typescript@patch:typescript@npm%3A4.7.4#~builtin::version=4.7.4&hash=a1c5e5" @@ -37445,7 +37465,7 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@~4.8.2#~builtin": +"typescript@patch:typescript@~4.8.2#~builtin, typescript@patch:typescript@~4.8.4#~builtin": version: 4.8.4 resolution: "typescript@patch:typescript@npm%3A4.8.4#~builtin::version=4.8.4&hash=a1c5e5" bin: @@ -37851,13 +37871,13 @@ __metadata: languageName: node linkType: hard -"use-immer@npm:^0.7.0": - version: 0.7.0 - resolution: "use-immer@npm:0.7.0" +"use-immer@npm:^0.8.0": + version: 0.8.1 + resolution: "use-immer@npm:0.8.1" peerDependencies: immer: ">=2.0.0" react: ^16.8.0 || ^17.0.1 || ^18.0.0 - checksum: 4711403fa2c3648c06b8e6795433eb43adb2c6e9bd00f45971ce6948ba8fc1c3e3cf73820a8d597b22979caa6445d0b791508e147975c3cc435a1ec1e5ce47db + checksum: 9ffc1a201a92b6b026c420718e6a00e72ba48b62420bb515927b379bb1d791b5b4766b57c755b4851c0e1f80000e639bc1cf8e73424e44466741c159391d35dd languageName: node linkType: hard @@ -38796,21 +38816,6 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.8.1": - version: 8.8.1 - resolution: "ws@npm:8.8.1" - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: 2152cf862cae0693f3775bc688a6afb2e989d19d626d215e70f5fcd8eb55b1c3b0d3a6a4052905ec320e2d7734e20aeedbf9744496d62f15a26ad79cf4cf7dae - languageName: node - linkType: hard - "ws@npm:^5.2.0 || ^6.0.0 || ^7.0.0, ws@npm:^7.3.1, ws@npm:^7.4.6": version: 7.5.9 resolution: "ws@npm:7.5.9"