Merge branch 'master' of github.com:backstage/backstage into scaffolder-examples
This commit is contained in:
@@ -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.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-git-release-manager': patch
|
||||
---
|
||||
|
||||
add exports to clear api-report messages
|
||||
@@ -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`.
|
||||
@@ -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.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
---
|
||||
|
||||
Added `loggerToWinstonLogger`, which was moved from `@backstage/backend-plugin-api`.
|
||||
@@ -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.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Slightly improve readability of "base URL conflict" error handling code
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-plugin-api': patch
|
||||
---
|
||||
|
||||
Added a new `rootHttpRouterServiceRef` and `RootHttpRouterService` interface.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-test-utils': patch
|
||||
---
|
||||
|
||||
The `startTestBackend` setup now includes default implementations for all core services.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-adr-backend': patch
|
||||
'@backstage/plugin-adr': patch
|
||||
---
|
||||
|
||||
Clarify that default ADR parsers support MADR specification v2.x
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-user-settings': patch
|
||||
---
|
||||
|
||||
Refactor for the feature flag filter functionality
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
'@backstage/plugin-search-react': minor
|
||||
---
|
||||
|
||||
Allow customizing empty state component through `noResultsComponent` property.
|
||||
|
||||
Example:
|
||||
|
||||
```jsx
|
||||
<SearchResult noResultsComponent={<>No results were found</>}>
|
||||
{({ results }) => (
|
||||
<List>
|
||||
{results.map(({ type, document }) => {
|
||||
switch (type) {
|
||||
case 'custom-result-item':
|
||||
return (
|
||||
<CustomResultListItem key={document.location} result={document} />
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<DefaultResultListItem
|
||||
key={document.location}
|
||||
result={document}
|
||||
/>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</List>
|
||||
)}
|
||||
</SearchResult>
|
||||
```
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-plugin-api': minor
|
||||
---
|
||||
|
||||
Moved `loggerToWinstonLogger` to `@backstage/backend-common`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Removed unused package `type-fest`
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
---
|
||||
|
||||
Updated dependency `use-immer` to `^0.8.0`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-bitbucket-cloud-common': patch
|
||||
---
|
||||
|
||||
Updated dependency `ts-morph` to `^17.0.0`.
|
||||
@@ -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`.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-permission-react': patch
|
||||
'@backstage/plugin-playlist': patch
|
||||
---
|
||||
|
||||
Updated dependency `swr` to `^2.0.0`.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-react': patch
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
---
|
||||
|
||||
Explicitly declaring children as optional props to facilitate react 18 changes
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/repo-tools': patch
|
||||
---
|
||||
|
||||
Updates Api-extractor and api-documenter version
|
||||
@@ -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`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-defaults': patch
|
||||
---
|
||||
|
||||
The new root HTTP router service is now installed by default.
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
StylesPath = .
|
||||
Vocab = Backstage
|
||||
|
||||
[*.md]
|
||||
BasedOnStyles = Vale
|
||||
Vale.Terms = NO
|
||||
@@ -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: >
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
StylesPath = .github/styles
|
||||
StylesPath = .github/vale
|
||||
|
||||
Vocab = Backstage
|
||||
|
||||
[*.md]
|
||||
BasedOnStyles = Vale
|
||||
Vale.Terms = NO
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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`.
|
||||
|
||||
+3
-3
@@ -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
|
||||
|
||||
|
||||
+1
-1
@@ -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",
|
||||
|
||||
@@ -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<CacheService>;
|
||||
) => ServiceFactory<PluginCacheManager>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const configFactory: (
|
||||
@@ -55,7 +57,7 @@ export interface CreateSpecializedBackendOptions {
|
||||
// @public (undocumented)
|
||||
export const databaseFactory: (
|
||||
options?: undefined,
|
||||
) => ServiceFactory<DatabaseService>;
|
||||
) => ServiceFactory<PluginDatabaseManager>;
|
||||
|
||||
// @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<PermissionsService>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const rootHttpRouterFactory: (
|
||||
options?: RootHttpRouterFactoryOptions | undefined,
|
||||
) => ServiceFactory<RootHttpRouterService>;
|
||||
|
||||
// @public (undocumented)
|
||||
export type RootHttpRouterFactoryOptions = {
|
||||
indexPath?: string | false;
|
||||
middleware?: Handler[];
|
||||
};
|
||||
|
||||
// @public
|
||||
export const rootLifecycleFactory: (
|
||||
options?: undefined,
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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<HttpRouterService>,
|
||||
{ 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<ServiceFactory<HttpRouterService>, { 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,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
@@ -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<void>((resolve, reject) => {
|
||||
stoppableServer.stop((error?: Error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
labels: { service: 'rootHttpRouter' },
|
||||
});
|
||||
|
||||
const existingPaths = new Array<string>();
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -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';
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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<void>;
|
||||
get(key: string): Promise<JsonValue | undefined>;
|
||||
set(
|
||||
key: string,
|
||||
value: JsonValue,
|
||||
options?: CacheClientSetOptions,
|
||||
): Promise<void>;
|
||||
}
|
||||
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<Config>;
|
||||
|
||||
// @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<Knex>;
|
||||
migrations?: {
|
||||
skip?: boolean;
|
||||
};
|
||||
}
|
||||
export { PluginDatabaseManager };
|
||||
|
||||
export { PluginEndpointDiscovery };
|
||||
|
||||
@@ -710,13 +699,7 @@ export interface StatusCheckHandlerOptions {
|
||||
statusCheck?: StatusCheck;
|
||||
}
|
||||
|
||||
// @public
|
||||
export interface TokenManager {
|
||||
authenticate(token: string): Promise<void>;
|
||||
getToken(): Promise<{
|
||||
token: string;
|
||||
}>;
|
||||
}
|
||||
export { TokenManager };
|
||||
|
||||
export { UrlReader };
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
+9
-43
@@ -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<JsonValue | undefined>;
|
||||
|
||||
/**
|
||||
* 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<void>;
|
||||
|
||||
/**
|
||||
* Removes the given key from the cache store.
|
||||
*/
|
||||
delete(key: string): Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A basic, concrete implementation of the CacheClient, suitable for almost
|
||||
* all uses in Backstage.
|
||||
|
||||
+4
-32
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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<Knex>;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
||||
@@ -22,3 +22,4 @@ export {
|
||||
redactWinstonLogLine,
|
||||
} from './rootLogger';
|
||||
export * from './voidLogger';
|
||||
export { loggerToWinstonLogger } from './loggerToWinstonLogger';
|
||||
|
||||
+1
-1
@@ -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';
|
||||
|
||||
@@ -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<void>;
|
||||
}
|
||||
export type { TokenManagerService as TokenManager } from '@backstage/backend-plugin-api';
|
||||
|
||||
@@ -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,
|
||||
];
|
||||
|
||||
@@ -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<void>;
|
||||
get(key: string): Promise<JsonValue | undefined>;
|
||||
set(
|
||||
key: string,
|
||||
value: JsonValue,
|
||||
options?: CacheClientSetOptions,
|
||||
): Promise<void>;
|
||||
}
|
||||
|
||||
// @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<LoggerService, 'plugin'>;
|
||||
const permissions: ServiceRef<PermissionsService, 'plugin'>;
|
||||
const pluginMetadata: ServiceRef<PluginMetadataService, 'plugin'>;
|
||||
const rootHttpRouter: ServiceRef<RootHttpRouterService, 'root'>;
|
||||
const rootLifecycle: ServiceRef<RootLifecycleService, 'root'>;
|
||||
const rootLogger: ServiceRef<RootLoggerService, 'root'>;
|
||||
const scheduler: ServiceRef<SchedulerService, 'plugin'>;
|
||||
@@ -153,8 +174,13 @@ export function createServiceRef<T>(options: {
|
||||
) => Promise<ServiceFactory<T> | (() => ServiceFactory<T>)>;
|
||||
}): ServiceRef<T, 'root'>;
|
||||
|
||||
// @public (undocumented)
|
||||
export interface DatabaseService extends PluginDatabaseManager {}
|
||||
// @public
|
||||
export interface DatabaseService {
|
||||
getClient(): Promise<Knex>;
|
||||
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<void>;
|
||||
getToken(): Promise<{
|
||||
token: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export type TypesToServiceRef<T> = {
|
||||
|
||||
@@ -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:^"
|
||||
|
||||
@@ -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<JsonValue | undefined>;
|
||||
|
||||
/**
|
||||
* 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<void>;
|
||||
|
||||
/**
|
||||
* Removes the given key from the cache store.
|
||||
*/
|
||||
delete(key: string): Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
|
||||
@@ -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<Knex>;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<void>;
|
||||
}
|
||||
|
||||
@@ -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}.
|
||||
*
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -15,5 +15,4 @@
|
||||
*/
|
||||
|
||||
export * from './definitions';
|
||||
export * from './helpers';
|
||||
export * from './system';
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<Router> {
|
||||
return await createRouter({
|
||||
reader: env.reader,
|
||||
cacheClient: env.cache.getClient(),
|
||||
logger: env.logger,
|
||||
});
|
||||
}
|
||||
@@ -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] }));
|
||||
}),
|
||||
|
||||
@@ -197,14 +197,13 @@ export class CatalogClient implements CatalogApi {
|
||||
request: GetEntitiesByRefsRequest,
|
||||
options?: CatalogRequestOptions,
|
||||
): Promise<GetEntitiesByRefsResponse> {
|
||||
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) {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ export type BottomLinkProps = {
|
||||
onClick?: (event: React_2.MouseEvent<HTMLAnchorElement>) => 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<Props_13>): 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<Props_14>): 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<WithStyles<typeof styles_2>> & {
|
||||
@@ -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<LinkProps_2, 'to'> &
|
||||
@@ -639,7 +639,7 @@ export type LinkProps = Omit<LinkProps_2, 'to'> &
|
||||
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<PageWithHeaderProps>,
|
||||
): 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<HeadersInit>);
|
||||
};
|
||||
|
||||
// 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<T = {}> = (
|
||||
props: RenderLabelProps<T>,
|
||||
) => 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<T = unknown> = {
|
||||
edge: DependencyEdge<T>;
|
||||
};
|
||||
|
||||
// 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<T = {}> = (
|
||||
props: RenderNodeProps<T>,
|
||||
) => 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<T = unknown> = {
|
||||
node: DependencyNode<T>;
|
||||
};
|
||||
|
||||
// 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<StepperProps>,
|
||||
): 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<StepProps>,
|
||||
): 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<Props_18>): 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<T extends object = {}>(props: TableProps<T>): JSX.Element;
|
||||
@@ -1359,12 +1359,12 @@ export namespace Table {
|
||||
icons: Readonly<Icons>;
|
||||
}
|
||||
|
||||
// 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<T extends object = {}> extends Column<T> {
|
||||
@@ -1374,7 +1374,7 @@ export interface TableColumn<T extends object = {}> extends Column<T> {
|
||||
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<T extends object = {}>
|
||||
@@ -1411,7 +1411,7 @@ export interface TableProps<T extends object = {}>
|
||||
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<T>(
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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<express.Router>;
|
||||
|
||||
// @public
|
||||
export class DefaultAdrCollatorFactory implements DocumentCollatorFactory {
|
||||
// (undocumented)
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -21,3 +21,4 @@
|
||||
*/
|
||||
|
||||
export * from './search';
|
||||
export * from './service';
|
||||
|
||||
+2
-1
@@ -14,4 +14,5 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { loggerToWinstonLogger } from './loggerToWinstonLogger';
|
||||
export { createRouter } from './router';
|
||||
export type { AdrRouterOptions } from './router';
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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<express.Router> {
|
||||
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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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<AdrListResult>;
|
||||
readAdr(url: string): Promise<AdrReadResult>;
|
||||
}
|
||||
|
||||
// @public
|
||||
export const adrApiRef: ApiRef<AdrApi>;
|
||||
|
||||
// @public
|
||||
export class AdrClient implements AdrApi {
|
||||
constructor(options: AdrClientOptions);
|
||||
// (undocumented)
|
||||
listAdrs(url: string): Promise<AdrListResult>;
|
||||
// (undocumented)
|
||||
readAdr(url: string): Promise<AdrReadResult>;
|
||||
}
|
||||
|
||||
// @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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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<T>(endpoint: string, fileUrl: string): Promise<T> {
|
||||
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<AdrListResult> {
|
||||
return this.fetchAdrApi<AdrListResult>(listEndpoint, url);
|
||||
}
|
||||
|
||||
async readAdr(url: string): Promise<AdrReadResult> {
|
||||
return this.fetchAdrApi<AdrReadResult>(readEndpoint, url);
|
||||
}
|
||||
}
|
||||
@@ -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';
|
||||
@@ -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<AdrListResult>;
|
||||
|
||||
/** Reads the contents of the ADR at the provided url. */
|
||||
readAdr(url: string): Promise<AdrReadResult>;
|
||||
}
|
||||
|
||||
/**
|
||||
* ApiRef for the AdrApi.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const adrApiRef = createApiRef<AdrApi>({
|
||||
id: 'plugin.adr.api',
|
||||
});
|
||||
@@ -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(() => {
|
||||
|
||||
@@ -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<string[]>([]);
|
||||
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 =
|
||||
|
||||
@@ -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<any>(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]);
|
||||
};
|
||||
@@ -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';
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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';
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user