Merge branch 'master' into scalable-sidebar-new-implementation

This commit is contained in:
hiba-aldalaty
2021-10-28 10:04:25 +01:00
207 changed files with 1690 additions and 1175 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
Update usage of msw in default plugin template
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/config': patch
---
Minor exports cleanup
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/theme': patch
---
More theme API cleanup
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli-common': patch
---
Add docs to the last export of cli-common
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
bump `@spotify/eslint-config-base` from 9.0.2 to 12.0.0
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/errors': patch
'@backstage/integration': patch
'@backstage/theme': patch
---
More API fixes: mark things public, add docs, fix exports
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-common': patch
---
Adjusted some API exports
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/cli': patch
'@backstage/test-utils': patch
---
Bump `msw` to `v0.35.0` to resolve [CVE-2021-32796](https://github.com/advisories/GHSA-5fg8-2547-mr8q).
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-components': patch
---
Updates the d3 dependencies
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/integration-react': patch
---
Clean up the API exports
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-react': patch
---
EntityTypePicker can be hidden and have an initial filter value set, similar to EntityKindPicker
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-app-api': patch
---
Api cleanup, adding `@public` where necessary and tweaking some comments
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
Fixed bug where the mode of an executable file was ignored
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/config-loader': patch
---
bump `typescript-json-schema` from 0.50.1 to 0.51.0
+4 -2
View File
@@ -7,7 +7,7 @@ on:
paths:
- '.github/workflows/e2e-win.yml'
- 'packages/cli/**'
- 'packages/e2e/**'
- 'packages/e2e-test/**'
- 'packages/create-app/**'
jobs:
@@ -21,7 +21,7 @@ jobs:
env:
CI: true
NODE_OPTIONS: --max-old-space-size=4096
NODE_OPTIONS: --max-old-space-size=8192
name: Node ${{ matrix.node-version }} on ${{ matrix.os }}
steps:
@@ -48,3 +48,5 @@ jobs:
run: yarn build --ignore example-app --ignore example-backend --ignore @techdocs/cli
- name: run E2E test
run: yarn e2e-test run
env:
DEBUG: zombie
+3
View File
@@ -59,3 +59,6 @@
| [Box](https://www.box.com) | [@kielosz](https://github.com/kielosz), [@jluk-box](https://github.com/jluk-box), [@ptychu](https://github.com/ptychu), [@alexrybch](https://github.com/alexrybch), [@szubster](https://github.com/szubster) | Developer portal for service catalog, integration with internal systems, new service onboarding. |
| [Bazaarvoice](https://www.bazaarvoice.com) | [@niallmccullagh](https://github.com/niallmccullagh) | Developer portal for service catalog and scaffolds, publishing Github docs and API documentation, visualising our internal tech radar and our product engineering org structure. |
| [Krateo PlatformOps](https://www.krateo.io) | [@projectkerberus](https://github.com/projectkerberus) | A multi-cloud control plane to create, manage and deploy any kind of resource easily and centrally via a Developer Portal that centralizes via a self-service catalog the templating and ownership of services, the available documentation, the overview of the components that compose an entire domain and all the data of the service lifecycle. |
| [Adevinta](https://www.adevinta.com) | [Ray Sinnema](https://github.com/RemonSinnema) | Showcase shared services to our internal customers. |
| [Splunk](https://www.splunk.com) | [@tonytamsf](https://github.com/tonytamsf) | Developer portal as a centralized place to find people, services, documentation, escalation policies and give bravos. This portal is also being used as a centralized search engine for engineering specific documentation.|
| [SoundCloud](https://www.soundcloud.com) | [Julio Zynger](https://github.com/julioz) | Developer portal as a [humane registry](https://martinfowler.com/bliki/HumaneRegistry.html) for the organization: catalog of people, services, documentation, feature toggles, escalation policies, etc.|
@@ -156,4 +156,16 @@ return await createRouter({
});
```
### List of custom action packages
Here is a list of Open Source custom actions that you can add to your Backstage
scaffolder backend:
| Name | Package | Owner |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- |
| Yeoman | [plugin-scaffolder-backend-module-yeoman](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend-module-yeoman) | [Backstage](https://backstage.io) |
| Cookiecutter | [plugin-scaffolder-backend-module-cookiecutter](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend-module-cookiecutter) | [Backstage](https://backstage.io) |
| Rails | [plugin-scaffolder-backend-module-rails](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend-module-rails) | [Backstage](https://backstage.io) |
| HTTP requests | [scaffolder-backend-module-http-request](https://www.npmjs.com/package/@roadiehq/scaffolder-backend-module-http-request) | [Roadie](https://roadie.io) |
Have fun! 🚀
-1
View File
@@ -45,7 +45,6 @@
},
"resolutions": {
"**/@graphql-codegen/cli/**/ws": "^7.4.6",
"**/@roadiehq/**/@backstage/core": "*",
"**/@roadiehq/**/@backstage/plugin-catalog": "*",
"**/@roadiehq/**/@backstage/catalog-model": "*",
"graphql-language-service-interface": "2.8.2",
+9 -5
View File
@@ -211,6 +211,12 @@ export type ErrorHandlerOptions = {
logClientErrors?: boolean;
};
// @public
export type FromReadableArrayOptions = Array<{
data: Readable;
path: string;
}>;
// @public (undocumented)
export function getRootLogger(): winston.Logger;
@@ -419,15 +425,13 @@ export type ReadTreeResponse = {
etag: string;
};
// @public (undocumented)
// @public
export type ReadTreeResponseDirOptions = {
targetDir?: string;
};
// @public (undocumented)
export interface ReadTreeResponseFactory {
// Warning: (ae-forgotten-export) The symbol "FromReadableArrayOptions" needs to be exported by the entry point index.d.ts
//
// (undocumented)
fromReadableArray(
options: FromReadableArrayOptions,
@@ -442,7 +446,7 @@ export interface ReadTreeResponseFactory {
): Promise<ReadTreeResponse>;
}
// @public (undocumented)
// @public
export type ReadTreeResponseFactoryOptions = {
stream: Readable;
subpath?: string;
@@ -580,7 +584,7 @@ export type UrlReader = {
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
};
// @public (undocumented)
// @public
export type UrlReaderPredicateTuple = {
predicate: (url: URL) => boolean;
reader: UrlReader;
+1 -1
View File
@@ -99,7 +99,7 @@
"http-errors": "^1.7.3",
"jest": "^26.0.1",
"mock-fs": "^5.1.0",
"msw": "^0.29.0",
"msw": "^0.35.0",
"mysql2": "^2.2.5",
"recursive-readdir": "^2.2.2",
"supertest": "^6.1.3"
@@ -19,7 +19,7 @@ import {
AzureIntegration,
readAzureIntegrationConfig,
} from '@backstage/integration';
import { msw } from '@backstage/test-utils';
import { setupRequestMockHandlers } from '@backstage/test-utils';
import fs from 'fs-extra';
import mockFs from 'mock-fs';
import { rest } from 'msw';
@@ -51,7 +51,7 @@ describe('AzureUrlReader', () => {
});
const worker = setupServer();
msw.setupDefaultHandlers(worker);
setupRequestMockHandlers(worker);
describe('read', () => {
beforeEach(() => {
@@ -19,7 +19,7 @@ import {
BitbucketIntegration,
readBitbucketIntegrationConfig,
} from '@backstage/integration';
import { msw } from '@backstage/test-utils';
import { setupRequestMockHandlers } from '@backstage/test-utils';
import fs from 'fs-extra';
import mockFs from 'mock-fs';
import { rest } from 'msw';
@@ -72,7 +72,7 @@ describe('BitbucketUrlReader', () => {
});
const worker = setupServer();
msw.setupDefaultHandlers(worker);
setupRequestMockHandlers(worker);
describe('readUrl', () => {
worker.use(
@@ -16,7 +16,7 @@
import { ConfigReader } from '@backstage/config';
import { NotFoundError, NotModifiedError } from '@backstage/errors';
import { msw } from '@backstage/test-utils';
import { setupRequestMockHandlers } from '@backstage/test-utils';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import { getVoidLogger } from '../logging';
@@ -28,7 +28,7 @@ const fetchUrlReader = new FetchUrlReader();
describe('FetchUrlReader', () => {
const worker = setupServer();
msw.setupDefaultHandlers(worker);
setupRequestMockHandlers(worker);
beforeEach(() => {
jest.clearAllMocks();
@@ -20,7 +20,7 @@ import {
GitHubIntegration,
readGitHubIntegrationConfig,
} from '@backstage/integration';
import { msw } from '@backstage/test-utils';
import { setupRequestMockHandlers } from '@backstage/test-utils';
import fs from 'fs-extra';
import mockFs from 'mock-fs';
import { rest } from 'msw';
@@ -73,7 +73,7 @@ const tmpDir = os.platform() === 'win32' ? 'C:\\tmp' : '/tmp';
describe('GithubUrlReader', () => {
const worker = setupServer();
msw.setupDefaultHandlers(worker);
setupRequestMockHandlers(worker);
beforeEach(() => {
mockFs({
@@ -15,7 +15,7 @@
*/
import { ConfigReader } from '@backstage/config';
import { msw } from '@backstage/test-utils';
import { setupRequestMockHandlers } from '@backstage/test-utils';
import fs from 'fs-extra';
import mockFs from 'mock-fs';
import { rest } from 'msw';
@@ -77,7 +77,7 @@ describe('GitlabUrlReader', () => {
});
const worker = setupServer();
msw.setupDefaultHandlers(worker);
setupRequestMockHandlers(worker);
describe('read', () => {
beforeEach(() => {
@@ -20,6 +20,7 @@ export { GithubUrlReader } from './GithubUrlReader';
export { GitlabUrlReader } from './GitlabUrlReader';
export { AwsS3UrlReader } from './AwsS3UrlReader';
export type {
FromReadableArrayOptions,
ReaderFactory,
ReadTreeOptions,
ReadTreeResponse,
+106 -37
View File
@@ -24,24 +24,41 @@ import { Config } from '@backstage/config';
* @public
*/
export type UrlReader = {
/* Used to read a single file and return its content. */
/**
* Reads a single file and return its content.
*/
read(url: string): Promise<Buffer>;
/**
* A replacement for the read method that supports options and complex responses.
* Reads a single file and return its content.
*
* Use this whenever it is available, as the read method will be deprecated and
* eventually removed in the future.
* @remarks
*
* This is a replacement for the read method that supports options and
* complex responses.
*
* Use this whenever it is available, as the read method will be
* deprecated and eventually removed in a future release.
*/
readUrl?(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
/* Used to read a file tree and download as a directory. */
/**
* Reads a full or partial file tree.
*/
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
/* Used to search a file in a tree using a glob pattern. */
/**
* Searches for a file in a tree using a glob pattern.
*/
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
};
/** @public */
/**
* A predicate that decides whether a specific {@link UrlReader} can handle a
* given URL.
*
* @public
*/
export type UrlReaderPredicateTuple = {
predicate: (url: URL) => boolean;
reader: UrlReader;
@@ -49,7 +66,7 @@ export type UrlReaderPredicateTuple = {
/**
* A factory function that can read config to construct zero or more
* UrlReaders along with a predicate for when it should be used.
* {@link UrlReader}s along with a predicate for when it should be used.
*
* @public
*/
@@ -66,21 +83,28 @@ export type ReaderFactory = (options: {
*/
export type ReadUrlOptions = {
/**
* An etag can be provided to check whether readUrl's response has changed from a previous execution.
* An ETag which can be provided to check whether a
* {@link UrlReader.readUrl} response has changed from a previous execution.
*
* In the readUrl() response, an etag is returned along with the data. The etag is a unique identifer
* of the data, usually the commit SHA or etag from the target.
* @remarks
*
* When an etag is given in ReadUrlOptions, readUrl will first compare the etag against the etag
* on the target. If they match, readUrl will throw a NotModifiedError indicating that the readUrl
* response will not differ from the previous response which included this particular etag. If they
* do not match, readUrl will return the rest of ReadUrlResponse along with a new etag.
* In the {@link UrlReader.readUrl} response, an ETag is returned along with
* the data. The ETag is a unique identifier of the data, usually the commit
* SHA or ETag from the target.
*
* When an ETag is given in ReadUrlOptions, {@link UrlReader.readUrl} will
* first compare the ETag against the ETag of the target. If they match,
* {@link UrlReader.readUrl} will throw a
* {@link @backstage/errors#NotModifiedError} indicating that the response
* will not differ from the previous response which included this particular
* ETag. If they do not match, {@link UrlReader.readUrl} will return the rest
* of the response along with a new ETag.
*/
etag?: string;
};
/**
* A response object for readUrl operations.
* A response object for {@link UrlReader.readUrl} operations.
*
* @public
*/
@@ -92,13 +116,16 @@ export type ReadUrlResponse = {
/**
* Etag returned by content provider.
*
* @remarks
*
* Can be used to compare and cache responses when doing subsequent calls.
*/
etag?: string;
};
/**
* An options object for readTree operations.
* An options object for {@link UrlReader.readTree} operations.
*
* @public
*/
@@ -106,6 +133,8 @@ export type ReadTreeOptions = {
/**
* A filter that can be used to select which files should be included.
*
* @remarks
*
* The path passed to the filter function is the relative path from the URL
* that the file tree is fetched from, without any leading '/'.
*
@@ -113,56 +142,82 @@ export type ReadTreeOptions = {
* at https://github.com/my/repo/blob/master/my-dir/my-subdir/my-file.txt will
* be represented as my-subdir/my-file.txt
*
* If no filter is provided all files are extracted.
* If no filter is provided, all files are extracted.
*/
filter?(path: string, info?: { size: number }): boolean;
/**
* An etag can be provided to check whether readTree's response has changed from a previous execution.
* An ETag which can be provided to check whether a
* {@link UrlReader.readTree} response has changed from a previous execution.
*
* In the readTree() response, an etag is returned along with the tree blob. The etag is a unique identifer
* of the tree blob, usually the commit SHA or etag from the target.
* @remarks
*
* When an etag is given in ReadTreeOptions, readTree will first compare the etag against the etag
* on the target branch. If they match, readTree will throw a NotModifiedError indicating that the readTree
* response will not differ from the previous response which included this particular etag. If they
* do not match, readTree will return the rest of ReadTreeResponse along with a new etag.
* In the {@link UrlReader.readTree} response, an ETag is returned along with
* the tree blob. The ETag is a unique identifier of the tree blob, usually
* the commit SHA or ETag from the target.
*
* When an ETag is given as a request option, {@link UrlReader.readTree} will
* first compare the ETag against the ETag on the target branch. If they
* match, {@link UrlReader.readTree} will throw a
* {@link @backstage/errors#NotModifiedError} indicating that the response
* will not differ from the previous response which included this particular
* ETag. If they do not match, {@link UrlReader.readTree} will return the
* rest of the response along with a new ETag.
*/
etag?: string;
};
/** @public */
/**
* Options that control {@link ReadTreeResponse.dir} execution.
*
* @public
*/
export type ReadTreeResponseDirOptions = {
/** The directory to write files to. Defaults to the OS tmpdir or `backend.workingDirectory` if set in config */
/**
* The directory to write files to.
*
* @remarks
*
* Defaults to the OS tmpdir, or `backend.workingDirectory` if set in config.
*/
targetDir?: string;
};
/**
* A response object for readTree operations.
* A response object for {@link UrlReader.readTree} operations.
*
* @public
*/
export type ReadTreeResponse = {
/**
* files() returns an array of all the files inside the tree and corresponding functions to read their content.
* Returns an array of all the files inside the tree, and corresponding
* functions to read their content.
*/
files(): Promise<ReadTreeResponseFile[]>;
/**
* Returns the tree contents as a binary archive, using a stream.
*/
archive(): Promise<NodeJS.ReadableStream>;
/**
* dir() extracts the tree response into a directory and returns the path of the directory.
* Extracts the tree response into a directory and returns the path of the
* directory.
*/
dir(options?: ReadTreeResponseDirOptions): Promise<string>;
/**
* Etag returned by content provider.
*
* @remarks
*
* Can be used to compare and cache responses when doing subsequent calls.
*/
etag: string;
};
/**
* Represents a single file in a readTree response.
* Represents a single file in a {@link UrlReader.readTree} response.
*
* @public
*/
@@ -171,7 +226,11 @@ export type ReadTreeResponseFile = {
content(): Promise<Buffer>;
};
/** @public */
/**
* Options that control execution of {@link ReadTreeResponseFactory} methods.
*
* @public
*/
export type ReadTreeResponseFactoryOptions = {
// A binary stream of a tar archive.
stream: Readable;
@@ -183,11 +242,21 @@ export type ReadTreeResponseFactoryOptions = {
// Filter passed on from the ReadTreeOptions
filter?: (path: string, info?: { size: number }) => boolean;
};
/** @public */
/**
* Options that control {@link ReadTreeResponseFactory.fromReadableArray}
* execution.
*
* @public
*/
export type FromReadableArrayOptions = Array<{
// Data in the form of a readable
/**
* The raw data itself.
*/
data: Readable;
// A string containing the filepath of the data
/**
* The filepath of the data.
*/
path: string;
}>;
@@ -213,7 +282,7 @@ export type SearchOptions = {
/**
* An etag can be provided to check whether the search response has changed from a previous execution.
*
* In the search() response, an etag is returned along with the files. The etag is a unique identifer
* In the search() response, an etag is returned along with the files. The etag is a unique identifier
* of the current tree, usually the commit SHA or etag from the target.
*
* When an etag is given in SearchOptions, search will first compare the etag against the etag
@@ -236,7 +305,7 @@ export type SearchResponse = {
files: SearchResponseFile[];
/**
* A unique identifer of the current remote tree, usually the commit SHA or etag from the target.
* A unique identifier of the current remote tree, usually the commit SHA or etag from the target.
*/
etag: string;
};
+1 -1
View File
@@ -37,7 +37,7 @@
"devDependencies": {
"@backstage/cli": "^0.8.0",
"@types/jest": "^26.0.7",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -21,6 +21,6 @@ export type Paths = {
resolveTargetRoot: ResolveFunc;
};
// @public (undocumented)
// @public
export type ResolveFunc = (...paths: string[]) => string;
```
+6 -1
View File
@@ -17,7 +17,12 @@
import fs from 'fs';
import { dirname, resolve as resolvePath } from 'path';
/** @public */
/**
* A function that takes a set of path fragments and resolves them into a
* single complete path, relative to some root.
*
* @public
*/
export type ResolveFunc = (...paths: string[]) => string;
/**
+2 -2
View File
@@ -41,7 +41,7 @@
"@rollup/plugin-json": "^4.0.2",
"@rollup/plugin-node-resolve": "^13.0.0",
"@rollup/plugin-yaml": "^3.0.0",
"@spotify/eslint-config-base": "^9.0.0",
"@spotify/eslint-config-base": "^12.0.0",
"@spotify/eslint-config-react": "^10.0.0",
"@spotify/eslint-config-typescript": "^10.0.0",
"@sucrase/jest-plugin": "^2.1.1",
@@ -110,7 +110,7 @@
"typescript": "^4.0.3",
"util": "^0.12.3",
"webpack": "^5.48.0",
"webpack-dev-server": "4.0.0-rc.0",
"webpack-dev-server": "4.3.1",
"webpack-node-externals": "^3.0.0",
"yaml": "^1.10.0",
"yml-loader": "^2.1.0",
@@ -36,7 +36,7 @@
"@backstage/cli": "{{versionQuery '@backstage/cli'}}",
"@types/supertest": "{{versionQuery '@types/supertest' '2.0.8'}}",
"supertest": "{{versionQuery 'supertest' '4.0.2'}}",
"msw": "{{versionQuery 'msw' '0.29.0'}}"
"msw": "{{versionQuery 'msw' '0.35.0'}}"
},
"files": [
"dist"
@@ -44,7 +44,7 @@
"@testing-library/user-event": "{{versionQuery '@testing-library/user-event' '13.1.8'}}",
"@types/jest": "{{versionQuery '@types/jest' '26.0.7'}}",
"@types/node": "{{versionQuery '@types/node' '14.14.32'}}",
"msw": "{{versionQuery 'msw' '0.29.0'}}",
"msw": "{{versionQuery 'msw' '0.35.0'}}",
"cross-fetch": "{{versionQuery 'cross-fetch' '3.0.6'}}"
},
"files": [
@@ -4,12 +4,15 @@ import { ThemeProvider } from '@material-ui/core';
import { lightTheme } from '@backstage/theme';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import { msw, renderInTestApp } from '@backstage/test-utils';
import {
setupRequestMockHandlers,
renderInTestApp,
} from "@backstage/test-utils";
describe('ExampleComponent', () => {
const server = setupServer();
// Enable sane handlers for network requests
msw.setupDefaultHandlers(server);
setupRequestMockHandlers(server);
// setup mock response
beforeEach(() => {
@@ -3,12 +3,12 @@ import { render } from '@testing-library/react';
import { ExampleFetchComponent } from './ExampleFetchComponent';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import { msw } from '@backstage/test-utils';
import { setupRequestMockHandlers } from '@backstage/test-utils';
describe('ExampleFetchComponent', () => {
const server = setupServer();
// Enable sane handlers for network requests
msw.setupDefaultHandlers(server);
setupRequestMockHandlers(server);
// setup mock response
beforeEach(() => {
+1 -1
View File
@@ -41,7 +41,7 @@
"json-schema": "^0.3.0",
"json-schema-merge-allof": "^0.8.1",
"json-schema-traverse": "^1.0.0",
"typescript-json-schema": "^0.50.1",
"typescript-json-schema": "^0.51.0",
"yaml": "^1.9.2",
"yup": "^0.32.9"
},
-17
View File
@@ -46,39 +46,22 @@ export class ConfigReader implements Config {
fallback?: ConfigReader | undefined,
prefix?: string,
);
// (undocumented)
static fromConfigs(configs: AppConfig[]): ConfigReader;
// (undocumented)
get<T = JsonValue_2>(key?: string): T;
// (undocumented)
getBoolean(key: string): boolean;
// (undocumented)
getConfig(key: string): ConfigReader;
// (undocumented)
getConfigArray(key: string): ConfigReader[];
// (undocumented)
getNumber(key: string): number;
// (undocumented)
getOptional<T = JsonValue_2>(key?: string): T | undefined;
// (undocumented)
getOptionalBoolean(key: string): boolean | undefined;
// (undocumented)
getOptionalConfig(key: string): ConfigReader | undefined;
// (undocumented)
getOptionalConfigArray(key: string): ConfigReader[] | undefined;
// (undocumented)
getOptionalNumber(key: string): number | undefined;
// (undocumented)
getOptionalString(key: string): string | undefined;
// (undocumented)
getOptionalStringArray(key: string): string[] | undefined;
// (undocumented)
getString(key: string): string;
// (undocumented)
getStringArray(key: string): string[];
// (undocumented)
has(key: string): boolean;
// (undocumented)
keys(): string[];
}
+19
View File
@@ -72,6 +72,9 @@ export class ConfigReader implements Config {
private filteredKeys?: string[];
private notifiedFilteredKeys = new Set<string>();
/**
* Instantiates the config reader from a list of application config objects.
*/
static fromConfigs(configs: AppConfig[]): ConfigReader {
if (configs.length === 0) {
return new ConfigReader(undefined);
@@ -96,6 +99,7 @@ export class ConfigReader implements Config {
private readonly prefix: string = '',
) {}
/** {@inheritdoc Config.has} */
has(key: string): boolean {
const value = this.readValue(key);
if (value !== undefined) {
@@ -104,12 +108,14 @@ export class ConfigReader implements Config {
return this.fallback?.has(key) ?? false;
}
/** {@inheritdoc Config.keys} */
keys(): string[] {
const localKeys = this.data ? Object.keys(this.data) : [];
const fallbackKeys = this.fallback?.keys() ?? [];
return [...new Set([...localKeys, ...fallbackKeys])];
}
/** {@inheritdoc Config.get} */
get<T = JsonValue>(key?: string): T {
const value = this.getOptional(key);
if (value === undefined) {
@@ -118,6 +124,7 @@ export class ConfigReader implements Config {
return value as T;
}
/** {@inheritdoc Config.getOptional} */
getOptional<T = JsonValue>(key?: string): T | undefined {
const value = this.readValue(key);
const fallbackValue = this.fallback?.getOptional<T>(key);
@@ -154,6 +161,7 @@ export class ConfigReader implements Config {
).value as T;
}
/** {@inheritdoc Config.getConfig} */
getConfig(key: string): ConfigReader {
const value = this.getOptionalConfig(key);
if (value === undefined) {
@@ -162,6 +170,7 @@ export class ConfigReader implements Config {
return value;
}
/** {@inheritdoc Config.getOptionalConfig} */
getOptionalConfig(key: string): ConfigReader | undefined {
const value = this.readValue(key);
const fallbackConfig = this.fallback?.getOptionalConfig(key);
@@ -177,6 +186,7 @@ export class ConfigReader implements Config {
return fallbackConfig;
}
/** {@inheritdoc Config.getConfigArray} */
getConfigArray(key: string): ConfigReader[] {
const value = this.getOptionalConfigArray(key);
if (value === undefined) {
@@ -185,6 +195,7 @@ export class ConfigReader implements Config {
return value;
}
/** {@inheritdoc Config.getOptionalConfigArray} */
getOptionalConfigArray(key: string): ConfigReader[] | undefined {
const configs = this.readConfigValue<JsonObject[]>(key, values => {
if (!Array.isArray(values)) {
@@ -220,6 +231,7 @@ export class ConfigReader implements Config {
return configs.map((obj, index) => this.copy(obj, `${key}[${index}]`));
}
/** {@inheritdoc Config.getNumber} */
getNumber(key: string): number {
const value = this.getOptionalNumber(key);
if (value === undefined) {
@@ -228,6 +240,7 @@ export class ConfigReader implements Config {
return value;
}
/** {@inheritdoc Config.getOptionalNumber} */
getOptionalNumber(key: string): number | undefined {
const value = this.readConfigValue<string | number>(
key,
@@ -247,6 +260,7 @@ export class ConfigReader implements Config {
return number;
}
/** {@inheritdoc Config.getBoolean} */
getBoolean(key: string): boolean {
const value = this.getOptionalBoolean(key);
if (value === undefined) {
@@ -255,6 +269,7 @@ export class ConfigReader implements Config {
return value;
}
/** {@inheritdoc Config.getOptionalBoolean} */
getOptionalBoolean(key: string): boolean | undefined {
return this.readConfigValue(
key,
@@ -262,6 +277,7 @@ export class ConfigReader implements Config {
);
}
/** {@inheritdoc Config.getString} */
getString(key: string): string {
const value = this.getOptionalString(key);
if (value === undefined) {
@@ -270,6 +286,7 @@ export class ConfigReader implements Config {
return value;
}
/** {@inheritdoc Config.getOptionalString} */
getOptionalString(key: string): string | undefined {
return this.readConfigValue(
key,
@@ -278,6 +295,7 @@ export class ConfigReader implements Config {
);
}
/** {@inheritdoc Config.getStringArray} */
getStringArray(key: string): string[] {
const value = this.getOptionalStringArray(key);
if (value === undefined) {
@@ -286,6 +304,7 @@ export class ConfigReader implements Config {
return value;
}
/** {@inheritdoc Config.getOptionalStringArray} */
getOptionalStringArray(key: string): string[] | undefined {
return this.readConfigValue(key, values => {
if (!Array.isArray(values)) {
+55 -138
View File
@@ -58,8 +58,6 @@ import { StorageApi } from '@backstage/core-plugin-api';
import { StorageValueChange } from '@backstage/core-plugin-api';
import { SubRouteRef } from '@backstage/core-plugin-api';
// Warning: (ae-missing-release-tag) "AlertApiForwarder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export class AlertApiForwarder implements AlertApi {
// (undocumented)
@@ -68,8 +66,6 @@ export class AlertApiForwarder implements AlertApi {
post(alert: AlertMessage): void;
}
// Warning: (ae-missing-release-tag) "ApiFactoryHolder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export type ApiFactoryHolder = {
get<T>(api: ApiRef<T>):
@@ -83,8 +79,6 @@ export type ApiFactoryHolder = {
| undefined;
};
// Warning: (ae-missing-release-tag) "ApiFactoryRegistry" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export class ApiFactoryRegistry implements ApiFactoryHolder {
// (undocumented)
@@ -109,11 +103,9 @@ export class ApiFactoryRegistry implements ApiFactoryHolder {
>(scope: ApiFactoryScope, factory: ApiFactory<Api, Impl, Deps>): boolean;
}
// Warning: (ae-missing-release-tag) "ApiProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export const ApiProvider: {
({ apis, children }: PropsWithChildren<ApiProviderProps>): JSX.Element;
(props: PropsWithChildren<ApiProviderProps>): JSX.Element;
propTypes: {
apis: PropTypes.Validator<
PropTypes.InferProps<{
@@ -124,9 +116,7 @@ export const ApiProvider: {
};
};
// Warning: (ae-missing-release-tag) "ApiRegistry" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class ApiRegistry implements ApiHolder {
constructor(apis: Map<string, unknown>);
// Warning: (ae-forgotten-export) The symbol "ApiRegistryBuilder" needs to be exported by the entry point index.d.ts
@@ -134,22 +124,14 @@ export class ApiRegistry implements ApiHolder {
// (undocumented)
static builder(): ApiRegistryBuilder;
// Warning: (ae-forgotten-export) The symbol "ApiImpl" needs to be exported by the entry point index.d.ts
//
// (undocumented)
static from(apis: ApiImpl[]): ApiRegistry;
// (undocumented)
get<T>(api: ApiRef<T>): T | undefined;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
static with<T>(api: ApiRef<T>, impl: T): ApiRegistry;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
with<T>(api: ApiRef<T>, impl: T): ApiRegistry;
}
// Warning: (ae-missing-release-tag) "ApiResolver" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class ApiResolver implements ApiHolder {
constructor(factories: ApiFactoryHolder);
// (undocumented)
@@ -160,9 +142,7 @@ export class ApiResolver implements ApiHolder {
): void;
}
// Warning: (ae-missing-release-tag) "AppComponents" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type AppComponents = {
NotFoundErrorPage: ComponentType<{}>;
BootErrorPage: ComponentType<BootErrorPageProps>;
@@ -173,23 +153,17 @@ export type AppComponents = {
SignInPage?: ComponentType<SignInPageProps>;
};
// Warning: (ae-missing-release-tag) "AppConfigLoader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export type AppConfigLoader = () => Promise<AppConfig[]>;
// Warning: (ae-missing-release-tag) "AppContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type AppContext = {
getPlugins(): BackstagePlugin<any, any>[];
getSystemIcon(key: string): IconComponent | undefined;
getComponents(): AppComponents;
};
// Warning: (ae-missing-release-tag) "AppOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type AppOptions = {
apis?: Iterable<AnyApiFactory>;
icons?: Partial<AppIcons> & {
@@ -205,9 +179,8 @@ export type AppOptions = {
// Warning: (ae-forgotten-export) The symbol "PartialKeys" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "TargetRouteMap" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "KeysWithType" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "AppRouteBinder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type AppRouteBinder = <
ExternalRoutes extends {
[name: string]: ExternalRouteRef;
@@ -220,9 +193,7 @@ export type AppRouteBinder = <
>,
) => void;
// Warning: (ae-missing-release-tag) "AppThemeSelector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class AppThemeSelector implements AppThemeApi {
constructor(themes: AppTheme[]);
// (undocumented)
@@ -237,9 +208,7 @@ export class AppThemeSelector implements AppThemeApi {
setActiveThemeId(themeId?: string): void;
}
// Warning: (ae-missing-release-tag) "AtlassianAuth" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class AtlassianAuth {
// Warning: (ae-forgotten-export) The symbol "OAuthApiCreateOptions" needs to be exported by the entry point index.d.ts
//
@@ -252,9 +221,7 @@ export class AtlassianAuth {
}: OAuthApiCreateOptions): typeof atlassianAuthApiRef.T;
}
// Warning: (ae-missing-release-tag) "Auth0Auth" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class Auth0Auth {
// (undocumented)
static create({
@@ -266,9 +233,7 @@ export class Auth0Auth {
}: OAuthApiCreateOptions): typeof auth0AuthApiRef.T;
}
// Warning: (ae-missing-release-tag) "BackstageApp" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type BackstageApp = {
getPlugins(): BackstagePlugin<any, any>[];
getSystemIcon(key: string): IconComponent | undefined;
@@ -276,19 +241,20 @@ export type BackstageApp = {
getRouter(): ComponentType<{}>;
};
// Warning: (ae-missing-release-tag) "BackstagePluginWithAnyOutput" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type BackstagePluginWithAnyOutput = Omit<
BackstagePlugin<any, any>,
'output'
> & {
output(): (PluginOutput | UnknownPluginOutput)[];
output(): (
| PluginOutput
| {
type: string;
}
)[];
};
// Warning: (ae-missing-release-tag) "BitbucketAuth" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class BitbucketAuth {
// (undocumented)
static create({
@@ -300,9 +266,7 @@ export class BitbucketAuth {
}: OAuthApiCreateOptions): typeof bitbucketAuthApiRef.T;
}
// Warning: (ae-missing-release-tag) "BitbucketSession" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type BitbucketSession = {
providerInfo: {
accessToken: string;
@@ -313,9 +277,7 @@ export type BitbucketSession = {
backstageIdentity: BackstageIdentity;
};
// Warning: (ae-missing-release-tag) "BootErrorPageProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type BootErrorPageProps = {
step: 'load-config' | 'load-chunk';
error: Error;
@@ -324,18 +286,13 @@ export type BootErrorPageProps = {
export { ConfigReader };
// Warning: (ae-forgotten-export) The symbol "PrivateAppImpl" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "createApp" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function createApp(options?: AppOptions): PrivateAppImpl;
// Warning: (ae-missing-release-tag) "defaultConfigLoader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export const defaultConfigLoader: AppConfigLoader;
// Warning: (ae-missing-release-tag) "ErrorAlerter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export class ErrorAlerter implements ErrorApi {
constructor(alertApi: AlertApi, errorApi: ErrorApi);
@@ -352,8 +309,6 @@ export class ErrorAlerter implements ErrorApi {
post(error: Error, context?: ErrorContext): void;
}
// Warning: (ae-missing-release-tag) "ErrorApiForwarder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export class ErrorApiForwarder implements ErrorApi {
// (undocumented)
@@ -365,23 +320,17 @@ export class ErrorApiForwarder implements ErrorApi {
post(error: Error, context?: ErrorContext): void;
}
// Warning: (ae-missing-release-tag) "ErrorBoundaryFallbackProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type ErrorBoundaryFallbackProps = {
plugin?: BackstagePlugin;
error: Error;
resetError: () => void;
};
// Warning: (ae-missing-release-tag) "FeatureFlagged" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export const FeatureFlagged: (props: FeatureFlaggedProps) => JSX.Element;
// Warning: (ae-missing-release-tag) "FeatureFlaggedProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type FeatureFlaggedProps = {
children: ReactNode;
} & (
@@ -393,15 +342,15 @@ export type FeatureFlaggedProps = {
}
);
// Warning: (ae-forgotten-export) The symbol "FlatRoutesProps" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "FlatRoutes" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export const FlatRoutes: (props: FlatRoutesProps) => JSX.Element | null;
// Warning: (ae-missing-release-tag) "GithubAuth" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type FlatRoutesProps = {
children: ReactNode;
};
// @public
export class GithubAuth implements OAuthApi, SessionApi {
// Warning: (ae-forgotten-export) The symbol "SessionManager" needs to be exported by the entry point index.d.ts
constructor(sessionManager: SessionManager<GithubSession>);
@@ -431,9 +380,7 @@ export class GithubAuth implements OAuthApi, SessionApi {
signOut(): Promise<void>;
}
// Warning: (ae-missing-release-tag) "GithubSession" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type GithubSession = {
providerInfo: {
accessToken: string;
@@ -444,9 +391,7 @@ export type GithubSession = {
backstageIdentity: BackstageIdentity;
};
// Warning: (ae-missing-release-tag) "GitlabAuth" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class GitlabAuth {
// (undocumented)
static create({
@@ -458,9 +403,7 @@ export class GitlabAuth {
}: OAuthApiCreateOptions): typeof gitlabAuthApiRef.T;
}
// Warning: (ae-missing-release-tag) "GoogleAuth" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class GoogleAuth {
// (undocumented)
static create({
@@ -472,8 +415,6 @@ export class GoogleAuth {
}: OAuthApiCreateOptions): typeof googleAuthApiRef.T;
}
// Warning: (ae-missing-release-tag) "LocalStorageFeatureFlags" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export class LocalStorageFeatureFlags implements FeatureFlagsApi {
// (undocumented)
@@ -486,9 +427,7 @@ export class LocalStorageFeatureFlags implements FeatureFlagsApi {
save(options: FeatureFlagsSaveOptions): void;
}
// Warning: (ae-missing-release-tag) "MicrosoftAuth" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class MicrosoftAuth {
// (undocumented)
static create({
@@ -500,17 +439,13 @@ export class MicrosoftAuth {
}: OAuthApiCreateOptions): typeof microsoftAuthApiRef.T;
}
// Warning: (ae-missing-release-tag) "NoOpAnalyticsApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export class NoOpAnalyticsApi implements AnalyticsApi {
// (undocumented)
captureEvent(_event: AnalyticsEvent): void;
}
// Warning: (ae-missing-release-tag) "OAuth2" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class OAuth2
implements
OAuthApi,
@@ -519,8 +454,10 @@ export class OAuth2
BackstageIdentityApi,
SessionApi
{
// Warning: (ae-forgotten-export) The symbol "Options" needs to be exported by the entry point index.d.ts
constructor(options: Options);
constructor(options: {
sessionManager: SessionManager<OAuth2Session>;
scopeTransform: (scopes: string[]) => string[];
});
// Warning: (ae-forgotten-export) The symbol "CreateOptions" needs to be exported by the entry point index.d.ts
//
// (undocumented)
@@ -553,9 +490,7 @@ export class OAuth2
signOut(): Promise<void>;
}
// Warning: (ae-missing-release-tag) "OAuth2Session" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type OAuth2Session = {
providerInfo: {
idToken: string;
@@ -567,8 +502,6 @@ export type OAuth2Session = {
backstageIdentity: BackstageIdentity;
};
// Warning: (ae-missing-release-tag) "OAuthRequestManager" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export class OAuthRequestManager implements OAuthRequestApi {
// (undocumented)
@@ -577,9 +510,7 @@ export class OAuthRequestManager implements OAuthRequestApi {
createAuthRequester<T>(options: AuthRequesterOptions<T>): AuthRequester<T>;
}
// Warning: (ae-missing-release-tag) "OktaAuth" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class OktaAuth {
// (undocumented)
static create({
@@ -591,9 +522,7 @@ export class OktaAuth {
}: OAuthApiCreateOptions): typeof oktaAuthApiRef.T;
}
// Warning: (ae-missing-release-tag) "OneLoginAuth" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class OneLoginAuth {
// Warning: (ae-forgotten-export) The symbol "CreateOptions" needs to be exported by the entry point index.d.ts
//
@@ -606,9 +535,7 @@ export class OneLoginAuth {
}: CreateOptions_2): typeof oneloginAuthApiRef.T;
}
// Warning: (ae-missing-release-tag) "SamlAuth" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class SamlAuth
implements ProfileInfoApi, BackstageIdentityApi, SessionApi
{
@@ -636,16 +563,12 @@ export class SamlAuth
signOut(): Promise<void>;
}
// Warning: (ae-missing-release-tag) "SignInPageProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type SignInPageProps = {
onResult(result: SignInResult): void;
};
// Warning: (ae-missing-release-tag) "SignInResult" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type SignInResult = {
userId: string;
profile: ProfileInfo;
@@ -653,15 +576,11 @@ export type SignInResult = {
signOut?: () => Promise<void>;
};
// Warning: (ae-missing-release-tag) "UnhandledErrorForwarder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class UnhandledErrorForwarder {
static forward(errorApi: ErrorApi, errorContext: ErrorContext): void;
}
// Warning: (ae-missing-release-tag) "UrlPatternDiscovery" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export class UrlPatternDiscovery implements DiscoveryApi {
static compile(pattern: string): UrlPatternDiscovery;
@@ -669,15 +588,14 @@ export class UrlPatternDiscovery implements DiscoveryApi {
getBaseUrl(pluginId: string): Promise<string>;
}
// Warning: (ae-missing-release-tag) "WebStorage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class WebStorage implements StorageApi {
constructor(namespace: string, errorApi: ErrorApi);
// Warning: (ae-forgotten-export) The symbol "CreateStorageApiOptions" needs to be exported by the entry point index.d.ts
//
// (undocumented)
static create(options: CreateStorageApiOptions): WebStorage;
static create(options: {
errorApi: ErrorApi;
namespace?: string;
}): WebStorage;
// (undocumented)
forBucket(name: string): WebStorage;
// (undocumented)
@@ -692,7 +610,6 @@ export class WebStorage implements StorageApi {
// Warnings were encountered during analysis:
//
// src/apis/system/ApiProvider.d.ts:9:5 - (ae-forgotten-export) The symbol "ApiProviderProps" needs to be exported by the entry point index.d.ts
// src/app/types.d.ts:89:5 - (ae-forgotten-export) The symbol "UnknownPluginOutput" needs to be exported by the entry point index.d.ts
// src/app/types.d.ts:100:5 - (ae-forgotten-export) The symbol "AppIcons" needs to be exported by the entry point index.d.ts
// src/apis/system/ApiProvider.d.ts:15:5 - (ae-forgotten-export) The symbol "ApiProviderProps" needs to be exported by the entry point index.d.ts
// src/app/types.d.ts:152:5 - (ae-forgotten-export) The symbol "AppIcons" needs to be exported by the entry point index.d.ts
```
+1 -1
View File
@@ -56,7 +56,7 @@
"@types/node": "^14.14.32",
"@types/zen-observable": "^0.8.0",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist",
@@ -20,6 +20,8 @@ import { PublishSubject } from '../../../lib/subjects';
/**
* Base implementation for the AlertApi that simply forwards alerts to consumers.
*
* @public
*/
export class AlertApiForwarder implements AlertApi {
private readonly subject = new PublishSubject<AlertMessage>();
@@ -17,6 +17,8 @@ import { AnalyticsApi, AnalyticsEvent } from '@backstage/core-plugin-api';
/**
* Base implementation for the AnalyticsApi that does nothing.
*
* @public
*/
export class NoOpAnalyticsApi implements AnalyticsApi {
captureEvent(_event: AnalyticsEvent): void {}
@@ -20,6 +20,12 @@ import { BehaviorSubject } from '../../../lib/subjects';
const STORAGE_KEY = 'theme';
/**
* Exposes the themes installed in the app, and permits switching the currently
* active theme.
*
* @public
*/
export class AppThemeSelector implements AppThemeApi {
static createWithStorage(themes: AppTheme[]) {
const selector = new AppThemeSelector(themes);
@@ -21,6 +21,8 @@ const ERROR_PREFIX = 'Invalid discovery URL pattern,';
/**
* UrlPatternDiscovery is a lightweight DiscoveryApi implementation.
* It uses a single template string to construct URLs for each plugin.
*
* @public
*/
export class UrlPatternDiscovery implements DiscoveryApi {
/**
@@ -18,6 +18,8 @@ import { ErrorApi, ErrorContext, AlertApi } from '@backstage/core-plugin-api';
/**
* Decorates an ErrorApi by also forwarding error messages
* to the alertApi with an 'error' severity.
*
* @public
*/
export class ErrorAlerter implements ErrorApi {
constructor(
@@ -20,6 +20,8 @@ import { PublishSubject } from '../../../lib/subjects';
/**
* Base implementation for the ErrorApi that simply forwards errors to consumers.
*
* @public
*/
export class ErrorApiForwarder implements ErrorApi {
private readonly subject = new PublishSubject<{
@@ -16,6 +16,11 @@ import { ErrorApi, ErrorContext } from '@backstage/core-plugin-api';
* limitations under the License.
*/
/**
* Utility class that helps with error forwarding.
*
* @public
*/
export class UnhandledErrorForwarder {
/**
* Add event listener, such that unhandled errors can be forwarded using an given `ErrorApi` instance
@@ -43,7 +43,10 @@ export function validateFlagName(name: string): void {
}
/**
* Create the FeatureFlags implementation based on the API.
* A feature flags implementation that stores the flags in the browser's local
* storage.
*
* @public
*/
export class LocalStorageFeatureFlags implements FeatureFlagsApi {
private registeredFeatureFlags: FeatureFlag[] = [];
@@ -30,6 +30,8 @@ import { BehaviorSubject } from '../../../lib/subjects';
* The purpose of this class and the API is to read a stream of incoming requests
* of OAuth access tokens from different providers with varying scope, and funnel
* them all together into a single request for each OAuth provider.
*
* @public
*/
export class OAuthRequestManager implements OAuthRequestApi {
private readonly subject = new BehaviorSubject<PendingAuthRequest[]>([]);
@@ -13,13 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CreateStorageApiOptions, WebStorage } from './WebStorage';
import { StorageApi } from '@backstage/core-plugin-api';
import { WebStorage } from './WebStorage';
import { ErrorApi, StorageApi } from '@backstage/core-plugin-api';
describe('WebStorage Storage API', () => {
const mockErrorApi = { post: jest.fn(), error$: jest.fn() };
const createWebStorage = (
args?: Partial<CreateStorageApiOptions>,
args?: Partial<{
errorApi: ErrorApi;
namespace?: string;
}>,
): StorageApi => {
return WebStorage.create({
errorApi: mockErrorApi,
@@ -24,18 +24,21 @@ import ObservableImpl from 'zen-observable';
const buckets = new Map<string, WebStorage>();
export type CreateStorageApiOptions = {
errorApi: ErrorApi;
namespace?: string;
};
/**
* An implementation of the storage API, that uses the browser's local storage.
*
* @public
*/
export class WebStorage implements StorageApi {
constructor(
private readonly namespace: string,
private readonly errorApi: ErrorApi,
) {}
static create(options: CreateStorageApiOptions): WebStorage {
static create(options: {
errorApi: ErrorApi;
namespace?: string;
}): WebStorage {
return new WebStorage(options.namespace ?? '', options.errorApi);
}
@@ -25,7 +25,12 @@ const DEFAULT_PROVIDER = {
icon: AtlassianIcon,
};
class AtlassianAuth {
/**
* Implements the OAuth flow to Atlassian products.
*
* @public
*/
export default class AtlassianAuth {
static create({
discoveryApi,
environment = 'development',
@@ -40,5 +45,3 @@ class AtlassianAuth {
});
}
}
export default AtlassianAuth;
@@ -25,7 +25,12 @@ const DEFAULT_PROVIDER = {
icon: Auth0Icon,
};
class Auth0Auth {
/**
* Implements the OAuth flow to Auth0 products.
*
* @public
*/
export default class Auth0Auth {
static create({
discoveryApi,
environment = 'development',
@@ -42,5 +47,3 @@ class Auth0Auth {
});
}
}
export default Auth0Auth;
@@ -40,7 +40,12 @@ const DEFAULT_PROVIDER = {
icon: BitbucketIcon,
};
class BitbucketAuth {
/**
* Implements the OAuth flow to Bitbucket products.
*
* @public
*/
export default class BitbucketAuth {
static create({
discoveryApi,
environment = 'development',
@@ -57,5 +62,3 @@ class BitbucketAuth {
});
}
}
export default BitbucketAuth;
@@ -16,6 +16,11 @@
import { ProfileInfo, BackstageIdentity } from '@backstage/core-plugin-api';
/**
* Session information for Bitbucket auth.
*
* @public
*/
export type BitbucketSession = {
providerInfo: {
accessToken: string;
@@ -51,7 +51,12 @@ const DEFAULT_PROVIDER = {
icon: GithubIcon,
};
class GithubAuth implements OAuthApi, SessionApi {
/**
* Implements the OAuth flow to GitHub products.
*
* @public
*/
export default class GithubAuth implements OAuthApi, SessionApi {
static create({
discoveryApi,
environment = 'development',
@@ -158,4 +163,3 @@ class GithubAuth implements OAuthApi, SessionApi {
return new Set(scopeList);
}
}
export default GithubAuth;
@@ -16,6 +16,11 @@
import { ProfileInfo, BackstageIdentity } from '@backstage/core-plugin-api';
/**
* Session information for GitHub auth.
*
* @public
*/
export type GithubSession = {
providerInfo: {
accessToken: string;
@@ -25,7 +25,12 @@ const DEFAULT_PROVIDER = {
icon: GitlabIcon,
};
class GitlabAuth {
/**
* Implements the OAuth flow to GitLab products.
*
* @public
*/
export default class GitlabAuth {
static create({
discoveryApi,
environment = 'development',
@@ -42,4 +47,3 @@ class GitlabAuth {
});
}
}
export default GitlabAuth;
@@ -27,7 +27,12 @@ const DEFAULT_PROVIDER = {
const SCOPE_PREFIX = 'https://www.googleapis.com/auth/';
class GoogleAuth {
/**
* Implements the OAuth flow to Google products.
*
* @public
*/
export default class GoogleAuth {
static create({
discoveryApi,
oauthRequestApi,
@@ -65,4 +70,3 @@ class GoogleAuth {
});
}
}
export default GoogleAuth;
@@ -25,7 +25,12 @@ const DEFAULT_PROVIDER = {
icon: MicrosoftIcon,
};
class MicrosoftAuth {
/**
* Implements the OAuth flow to Microsoft products.
*
* @public
*/
export default class MicrosoftAuth {
static create({
environment = 'development',
provider = DEFAULT_PROVIDER,
@@ -48,5 +53,3 @@ class MicrosoftAuth {
});
}
}
export default MicrosoftAuth;
@@ -33,11 +33,6 @@ import { Observable } from '@backstage/types';
import { OAuth2Session } from './types';
import { OAuthApiCreateOptions } from '../types';
type Options = {
sessionManager: SessionManager<OAuth2Session>;
scopeTransform: (scopes: string[]) => string[];
};
type CreateOptions = OAuthApiCreateOptions & {
scopeTransform?: (scopes: string[]) => string[];
};
@@ -59,7 +54,12 @@ const DEFAULT_PROVIDER = {
icon: OAuth2Icon,
};
class OAuth2
/**
* Implements a generic OAuth2 flow for auth.
*
* @public
*/
export default class OAuth2
implements
OAuthApi,
OpenIdConnectApi,
@@ -115,7 +115,10 @@ class OAuth2
private readonly sessionManager: SessionManager<OAuth2Session>;
private readonly scopeTransform: (scopes: string[]) => string[];
constructor(options: Options) {
constructor(options: {
sessionManager: SessionManager<OAuth2Session>;
scopeTransform: (scopes: string[]) => string[];
}) {
this.sessionManager = options.sessionManager;
this.scopeTransform = options.scopeTransform;
}
@@ -176,5 +179,3 @@ class OAuth2
return new Set(scopeTransform(scopeList));
}
}
export default OAuth2;
@@ -16,6 +16,11 @@
import { ProfileInfo, BackstageIdentity } from '@backstage/core-plugin-api';
/**
* Session information for generic OAuth2 auth.
*
* @public
*/
export type OAuth2Session = {
providerInfo: {
idToken: string;
@@ -37,7 +37,12 @@ const OKTA_OIDC_SCOPES: Set<String> = new Set([
const OKTA_SCOPE_PREFIX: string = 'okta.';
class OktaAuth {
/**
* Implements the OAuth flow to Okta products.
*
* @public
*/
export default class OktaAuth {
static create({
discoveryApi,
environment = 'development',
@@ -67,5 +72,3 @@ class OktaAuth {
});
}
}
export default OktaAuth;
@@ -26,7 +26,6 @@ import { OAuth2 } from '../oauth2';
type CreateOptions = {
discoveryApi: DiscoveryApi;
oauthRequestApi: OAuthRequestApi;
environment?: string;
provider?: AuthProvider & { id: string };
};
@@ -49,7 +48,12 @@ const OIDC_SCOPES: Set<String> = new Set([
const SCOPE_PREFIX: string = 'onelogin.';
class OneLoginAuth {
/**
* Implements a OneLogin OAuth flow.
*
* @public
*/
export default class OneLoginAuth {
static create({
discoveryApi,
environment = 'development',
@@ -78,5 +82,3 @@ class OneLoginAuth {
});
}
}
export default OneLoginAuth;
@@ -45,7 +45,14 @@ const DEFAULT_PROVIDER = {
icon: SamlIcon,
};
class SamlAuth implements ProfileInfoApi, BackstageIdentityApi, SessionApi {
/**
* Implements a general SAML based auth flow.
*
* @public
*/
export default class SamlAuth
implements ProfileInfoApi, BackstageIdentityApi, SessionApi
{
static create({
discoveryApi,
environment = 'development',
@@ -94,5 +101,3 @@ class SamlAuth implements ProfileInfoApi, BackstageIdentityApi, SessionApi {
return session?.profile;
}
}
export default SamlAuth;
@@ -15,6 +15,11 @@
*/
import { ProfileInfo, BackstageIdentity } from '@backstage/core-plugin-api';
/**
* Session information for SAML auth.
*
* @public
*/
export type SamlSession = {
userId: string;
profile: ProfileInfo;
@@ -44,6 +44,8 @@ type FactoryTuple = {
*
* Each scope has an assigned priority, where factories registered with
* higher priority scopes override ones with lower priority.
*
* @public
*/
export class ApiFactoryRegistry implements ApiFactoryHolder {
private readonly factories = new Map<string, FactoryTuple>();
@@ -30,10 +30,14 @@ type ApiProviderProps = {
const ApiContext = createVersionedContext<{ 1: ApiHolder }>('api-context');
export const ApiProvider = ({
apis,
children,
}: PropsWithChildren<ApiProviderProps>) => {
/**
* Provides an {@link @backstage/core-plugin-api#ApiHolder} for consumption in
* the React tree.
*
* @public
*/
export const ApiProvider = (props: PropsWithChildren<ApiProviderProps>) => {
const { apis, children } = props;
const parentHolder = useContext(ApiContext)?.atVersion(1);
const holder = parentHolder ? new ApiAggregator(apis, parentHolder) : apis;
@@ -32,11 +32,21 @@ class ApiRegistryBuilder {
}
}
/**
* A registry for utility APIs.
*
* @public
*/
export class ApiRegistry implements ApiHolder {
static builder() {
return new ApiRegistryBuilder();
}
/**
* Creates a new ApiRegistry with a list of API implementations.
*
* @param apis - A list of pairs mapping an ApiRef to its respective implementation
*/
static from(apis: ApiImpl[]) {
return new ApiRegistry(new Map(apis.map(([api, impl]) => [api.id, impl])));
}
@@ -44,8 +54,8 @@ export class ApiRegistry implements ApiHolder {
/**
* Creates a new ApiRegistry with a single API implementation.
*
* @param api ApiRef for the API to add
* @param impl Implementation of the API to add
* @param api - ApiRef for the API to add
* @param impl - Implementation of the API to add
*/
static with<T>(api: ApiRef<T>, impl: T): ApiRegistry {
return new ApiRegistry(new Map([[api.id, impl]]));
@@ -56,8 +66,8 @@ export class ApiRegistry implements ApiHolder {
/**
* Returns a new ApiRegistry with the provided API added to the existing ones.
*
* @param api ApiRef for the API to add
* @param impl Implementation of the API to add
* @param api - ApiRef for the API to add
* @param impl - Implementation of the API to add
*/
with<T>(api: ApiRef<T>, impl: T): ApiRegistry {
return new ApiRegistry(new Map([...this.apis, [api.id, impl]]));
@@ -22,6 +22,12 @@ import {
} from '@backstage/core-plugin-api';
import { ApiFactoryHolder } from './types';
/**
* Handles the actual on-demand instantiation and memoization of APIs out of
* an {@link ApiFactoryHolder}.
*
* @public
*/
export class ApiResolver implements ApiHolder {
/**
* Validate factories by making sure that each of the apis can be created
@@ -16,6 +16,9 @@
import { ApiFactory, ApiRef } from '@backstage/core-plugin-api';
/**
* @public
*/
export type ApiFactoryHolder = {
get<T>(
api: ApiRef<T>,
@@ -48,6 +48,8 @@ import { BackstagePlugin } from '@backstage/core-plugin-api';
* which can be rewritten at runtime to contain an additional JSON config object.
* If runtime config is present, it will be placed first in the config array, overriding
* other config values.
*
* @public
*/
export const defaultConfigLoader: AppConfigLoader = async (
// This string may be replaced at runtime to provide additional config.
@@ -100,6 +102,8 @@ export function OptionallyWrapInRouter({ children }: PropsWithChildren<{}>) {
/**
* Creates a new Backstage App.
*
* @public
*/
export function createApp(options?: AppOptions) {
const DefaultNotFoundPage = () => (
+65 -9
View File
@@ -29,11 +29,21 @@ import {
import { AppConfig } from '@backstage/config';
import { AppIcons } from './icons';
/**
* Props for the `BootErrorPage` component of {@link AppComponents}.
*
* @public
*/
export type BootErrorPageProps = {
step: 'load-config' | 'load-chunk';
error: Error;
};
/**
* The outcome of signing in on the sign-in page.
*
* @public
*/
export type SignInResult = {
/**
* User ID that will be returned by the IdentityApi
@@ -53,6 +63,11 @@ export type SignInResult = {
signOut?: () => Promise<void>;
};
/**
* Props for the `SignInPage` component of {@link AppComponents}.
*
* @public
*/
export type SignInPageProps = {
/**
* Set the sign-in result for the app. This should only be called once.
@@ -60,12 +75,22 @@ export type SignInPageProps = {
onResult(result: SignInResult): void;
};
/**
* Props for the fallback error boundary.
*
* @public
*/
export type ErrorBoundaryFallbackProps = {
plugin?: BackstagePlugin;
error: Error;
resetError: () => void;
};
/**
* A set of replaceable core components that are part of every Backstage app.
*
* @public
*/
export type AppComponents = {
NotFoundErrorPage: ComponentType<{}>;
BootErrorPage: ComponentType<BootErrorPageProps>;
@@ -91,6 +116,8 @@ export type AppComponents = {
*
* If multiple config objects are returned in the array, values in the earlier configs
* will override later ones.
*
* @public
*/
export type AppConfigLoader = () => Promise<AppConfig[]>;
@@ -123,6 +150,12 @@ type TargetRouteMap<
: never;
};
/**
* A function that can bind from external routes of a given plugin, to concrete
* routes of other plugins. See {@link createApp}.
*
* @public
*/
export type AppRouteBinder = <
ExternalRoutes extends { [name: string]: ExternalRouteRef },
>(
@@ -133,21 +166,33 @@ export type AppRouteBinder = <
>,
) => void;
// Output from newer or older plugin API versions that might not be supported by
// this version of the app API, but we don't want to break at the type checking level.
// We only use this more permissive type for the `createApp` options, as we otherwise
// want to stick to using the type for the outputs that we know about in this version
// of the app api.
type UnknownPluginOutput = {
type: string;
};
/**
* Internal helper type that represents a plugin with any type of output.
*
* @public
* @remarks
*
* The `type: string` type is there to handle output from newer or older plugin
* API versions that might not be supported by this version of the app API, but
* we don't want to break at the type checking level. We only use this more
* permissive type for the `createApp` options, as we otherwise want to stick
* to using the type for the outputs that we know about in this version of the
* app api.
*
* TODO(freben): This should be marked internal but that's not supported by the api report generation tools yet
*/
export type BackstagePluginWithAnyOutput = Omit<
BackstagePlugin<any, any>,
'output'
> & {
output(): (PluginOutput | UnknownPluginOutput)[];
output(): (PluginOutput | { type: string })[];
};
/**
* The options accepted by {@link createApp}.
*
* @public
*/
export type AppOptions = {
/**
* A collection of ApiFactories to register in the application to either
@@ -226,6 +271,11 @@ export type AppOptions = {
bindRoutes?(context: { bind: AppRouteBinder }): void;
};
/**
* The public API of the output of {@link createApp}.
*
* @public
*/
export type BackstageApp = {
/**
* Returns all plugins registered for the app.
@@ -250,6 +300,12 @@ export type BackstageApp = {
getRouter(): ComponentType<{}>;
};
/**
* The central context providing runtime app specific state that plugin views
* want to consume.
*
* @public
*/
export type AppContext = {
/**
* Get a list of all plugins that are installed in the app.
@@ -19,7 +19,7 @@ import { DefaultAuthConnector } from './DefaultAuthConnector';
import MockOAuthApi from '../../apis/implementations/OAuthRequestApi/MockOAuthApi';
import * as loginPopup from '../loginPopup';
import { UrlPatternDiscovery } from '../../apis';
import { msw } from '@backstage/test-utils';
import { setupRequestMockHandlers } from '@backstage/test-utils';
import { setupServer } from 'msw/node';
import { rest } from 'msw';
@@ -41,7 +41,7 @@ const defaultOptions = {
describe('DefaultAuthConnector', () => {
const server = setupServer();
msw.setupDefaultHandlers(server);
setupRequestMockHandlers(server);
afterEach(() => {
jest.resetAllMocks();
@@ -21,11 +21,22 @@ import {
} from '@backstage/core-plugin-api';
import React, { ReactNode } from 'react';
/**
* Props for the {@link FeatureFlagged} component.
*
* @public
*/
export type FeatureFlaggedProps = { children: ReactNode } & (
| { with: string }
| { without: string }
);
/**
* Enables or disables rendering of its children based on the state of a given
* feature flag.
*
* @public
*/
export const FeatureFlagged = (props: FeatureFlaggedProps) => {
const { children } = props;
const featureFlagApi = useApi(featureFlagsApiRef);
@@ -24,10 +24,26 @@ type RouteObject = {
children?: RouteObject[];
};
type FlatRoutesProps = {
/**
* Props for the {@link FlatRoutes} component.
*
* @public
*/
export type FlatRoutesProps = {
children: ReactNode;
};
/**
* A wrapper around a set of routes.
*
* @remarks
*
* The root of the routing hierarchy in your app should use this component,
* instead of the one from `react-router-dom`. This ensures that all of the
* plugin route and utility API wiring happens under the hood.
*
* @public
*/
export const FlatRoutes = (props: FlatRoutesProps): JSX.Element | null => {
const app = useApp();
const { NotFoundErrorPage } = app.getComponents();
@@ -15,5 +15,6 @@
*/
export { FlatRoutes } from './FlatRoutes';
export type { FlatRoutesProps } from './FlatRoutes';
export { FeatureFlagged } from './FeatureFlagged';
export type { FeatureFlaggedProps } from './FeatureFlagged';
+5 -5
View File
@@ -42,9 +42,9 @@
"@types/react-text-truncate": "^0.14.0",
"classnames": "^2.2.6",
"clsx": "^1.1.0",
"d3-selection": "^2.0.0",
"d3-shape": "^2.0.0",
"d3-zoom": "^2.0.0",
"d3-selection": "^3.0.0",
"d3-shape": "^3.0.0",
"d3-zoom": "^3.0.0",
"dagre": "^0.8.5",
"immer": "^9.0.1",
"lodash": "^4.17.21",
@@ -75,9 +75,9 @@
"@testing-library/react-hooks": "^7.0.2",
"@testing-library/user-event": "^13.1.8",
"@types/classnames": "^2.2.9",
"@types/d3-selection": "^2.0.0",
"@types/d3-selection": "^3.0.1",
"@types/d3-shape": "^3.0.1",
"@types/d3-zoom": "^2.0.0",
"@types/d3-zoom": "^3.0.1",
"@types/dagre": "^0.7.44",
"@types/google-protobuf": "^3.7.2",
"@types/jest": "^26.0.7",
+1 -1
View File
@@ -55,7 +55,7 @@
"@types/prop-types": "^15.7.3",
"@types/zen-observable": "^0.8.0",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -369,7 +369,7 @@ async function testAppServe(pluginName: string, appDir: string) {
successful = true;
break;
} catch (error) {
if (attempts >= 5) {
if (attempts >= 20) {
throw new Error(`App serve test failed, ${error}`);
}
console.log(`App serve failed, trying again, ${error}`);
+12 -15
View File
@@ -25,9 +25,6 @@ import { promisify } from 'util';
const execFile = promisify(execFileCb);
const EXPECTED_LOAD_ERRORS =
/ECONNREFUSED|ECONNRESET|did not get to load all resources/;
export function spawnPiped(cmd: string[], options?: SpawnOptions) {
function pipeWithPrefix(stream: NodeJS.WriteStream, prefix = '') {
return (data: Buffer) => {
@@ -131,16 +128,19 @@ export async function waitForPageWithText(
browser: any,
path: string,
text: string,
{ intervalMs = 1000, maxLoadAttempts = 50 } = {},
{ intervalMs = 1000, maxFindAttempts = 50 } = {},
) {
let loadAttempts = 0;
let findAttempts = 0;
for (;;) {
try {
const waitTimeMs = intervalMs * (Math.log10(loadAttempts + 1) + 1);
const waitTimeMs = intervalMs * (findAttempts + 1);
console.log(`Attempting to load page at ${path}, waiting ${waitTimeMs}`);
await new Promise(resolve => setTimeout(resolve, waitTimeMs));
await browser.visit(path);
await new Promise(resolve => setTimeout(resolve, waitTimeMs));
const escapedText = text.replace(/"|\\/g, '\\$&');
browser.assert.evaluate(
`Array.from(document.querySelectorAll("*")).some(el => el.textContent === "${escapedText}")`,
@@ -150,15 +150,12 @@ export async function waitForPageWithText(
break;
} catch (error) {
assertError(error);
if (error.message.match(EXPECTED_LOAD_ERRORS)) {
loadAttempts++;
if (loadAttempts >= maxLoadAttempts) {
throw new Error(
`Failed to load page '${path}', max number of attempts reached`,
);
}
} else {
throw error;
findAttempts++;
if (findAttempts >= maxFindAttempts) {
throw new Error(
`Failed to load page '${path}', max number of attempts reached`,
);
}
}
}
-1
View File
@@ -17,7 +17,6 @@ export class ConflictError extends CustomErrorBase {}
// @public
export class CustomErrorBase extends Error {
constructor(message?: string, cause?: Error | unknown);
// (undocumented)
readonly cause?: Error | undefined;
}
@@ -33,6 +33,9 @@ import { isError } from './assertion';
* ```
*/
export class CustomErrorBase extends Error {
/**
* An inner error that caused this error to be thrown, if any.
*/
readonly cause?: Error | undefined;
constructor(message?: string, cause?: Error | unknown) {
+13 -18
View File
@@ -65,7 +65,6 @@ export class ScmAuth implements ScmAuthApi {
host?: string;
},
): ScmAuth;
// (undocumented)
getCredentials(options: ScmAuthTokenOptions): Promise<ScmAuthTokenResponse>;
isUrlSupported(url: URL): boolean;
static merge(...providers: ScmAuth[]): ScmAuthApi;
@@ -79,7 +78,7 @@ export interface ScmAuthApi {
// @public
export const scmAuthApiRef: ApiRef<ScmAuthApi>;
// @public (undocumented)
// @public
export interface ScmAuthTokenOptions extends AuthRequestOptions {
additionalScope?: {
repoWrite?: boolean;
@@ -87,7 +86,7 @@ export interface ScmAuthTokenOptions extends AuthRequestOptions {
url: string;
}
// @public (undocumented)
// @public
export interface ScmAuthTokenResponse {
headers: {
[name: string]: string;
@@ -95,25 +94,21 @@ export interface ScmAuthTokenResponse {
token: string;
}
// Warning: (ae-missing-release-tag) "ScmIntegrationIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const ScmIntegrationIcon: ({
type,
}: {
type?: string | undefined;
}) => JSX.Element;
// @public
export const ScmIntegrationIcon: (
props: ScmIntegrationIconProps,
) => JSX.Element;
// Warning: (ae-missing-release-tag) "ScmIntegrationsApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type ScmIntegrationIconProps = {
type?: string;
};
// @public
export class ScmIntegrationsApi {
// (undocumented)
static fromConfig(config: Config): ScmIntegrationRegistry;
}
// Warning: (ae-missing-release-tag) "scmIntegrationsApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export const scmIntegrationsApiRef: ApiRef<ScmIntegrationRegistry>;
```
+1 -1
View File
@@ -42,7 +42,7 @@
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"msw": "^0.29.0",
"msw": "^0.35.0",
"cross-fetch": "^3.0.6"
},
"files": [
@@ -254,6 +254,9 @@ export class ScmAuth implements ScmAuthApi {
return url.host === this.#host;
}
/**
* Fetches credentials for the given resource.
*/
async getCredentials(
options: ScmAuthTokenOptions,
): Promise<ScmAuthTokenResponse> {
@@ -20,7 +20,11 @@ import {
AuthRequestOptions,
} from '@backstage/core-plugin-api';
/** @public */
/**
* The options that control a {@link ScmAuthApi.getCredentials} call.
*
* @public
*/
export interface ScmAuthTokenOptions extends AuthRequestOptions {
/**
* The URL of the SCM resource to be accessed.
@@ -43,7 +47,11 @@ export interface ScmAuthTokenOptions extends AuthRequestOptions {
};
}
/** @public */
/**
* The response from a {@link ScmAuthApi.getCredentials} call.
*
* @public
*/
export interface ScmAuthTokenResponse {
/**
* An authorization token that can be used to authenticate requests.
@@ -21,12 +21,27 @@ import {
} from '@backstage/integration';
import { ApiRef, createApiRef } from '@backstage/core-plugin-api';
/**
* Factory class for creating {@link @backstage/integration#ScmIntegrationRegistry} instances.
*
* @public
*/
export class ScmIntegrationsApi {
/**
* Instantiates an {@link @backstage/integration#ScmIntegrationRegistry}.
*
* @param config - The root of the config hierarchy.
*/
static fromConfig(config: Config): ScmIntegrationRegistry {
return ScmIntegrations.fromConfig(config);
}
}
/**
* The API that holds all configured SCM integrations.
*
* @public
*/
export const scmIntegrationsApiRef: ApiRef<ScmIntegrationRegistry> =
createApiRef({
id: 'integration.scmintegrations',
@@ -17,7 +17,25 @@ import CodeIcon from '@material-ui/icons/Code';
import React from 'react';
import { useApp } from '@backstage/core-plugin-api';
export const ScmIntegrationIcon = ({ type }: { type?: string }) => {
/**
* Props for {@link ScmIntegrationIcon}.
*
* @public
*/
export type ScmIntegrationIconProps = {
/**
* The integration type, e.g. "github".
*/
type?: string;
};
/**
* An icon that represents a certain SCM integration.
*
* @public
*/
export const ScmIntegrationIcon = (props: ScmIntegrationIconProps) => {
const { type } = props;
const app = useApp();
const DefaultIcon = CodeIcon;
const Icon = type ? app.getSystemIcon(type) ?? DefaultIcon : DefaultIcon;
@@ -15,3 +15,4 @@
*/
export { ScmIntegrationIcon } from './ScmIntegrationIcon';
export type { ScmIntegrationIconProps } from './ScmIntegrationIcon';
+51 -167
View File
@@ -6,15 +6,11 @@
import { Config } from '@backstage/config';
import { RestEndpointMethodTypes } from '@octokit/rest';
// Warning: (ae-missing-release-tag) "AwsS3Integration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class AwsS3Integration implements ScmIntegration {
constructor(integrationConfig: AwsS3IntegrationConfig);
// (undocumented)
get config(): AwsS3IntegrationConfig;
// Warning: (ae-forgotten-export) The symbol "ScmIntegrationsFactory" needs to be exported by the entry point index.d.ts
//
// (undocumented)
static factory: ScmIntegrationsFactory<AwsS3Integration>;
// (undocumented)
@@ -31,8 +27,6 @@ export class AwsS3Integration implements ScmIntegration {
get type(): string;
}
// Warning: (ae-missing-release-tag) "AwsS3IntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export type AwsS3IntegrationConfig = {
host: string;
@@ -41,9 +35,7 @@ export type AwsS3IntegrationConfig = {
roleArn?: string;
};
// Warning: (ae-missing-release-tag) "AzureIntegration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class AzureIntegration implements ScmIntegration {
constructor(integrationConfig: AzureIntegrationConfig);
// (undocumented)
@@ -64,17 +56,13 @@ export class AzureIntegration implements ScmIntegration {
get type(): string;
}
// Warning: (ae-missing-release-tag) "AzureIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export type AzureIntegrationConfig = {
host: string;
token?: string;
};
// Warning: (ae-missing-release-tag) "BitbucketIntegration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class BitbucketIntegration implements ScmIntegration {
constructor(integrationConfig: BitbucketIntegrationConfig);
// (undocumented)
@@ -95,8 +83,6 @@ export class BitbucketIntegration implements ScmIntegration {
get type(): string;
}
// Warning: (ae-missing-release-tag) "BitbucketIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export type BitbucketIntegrationConfig = {
host: string;
@@ -106,8 +92,6 @@ export type BitbucketIntegrationConfig = {
appPassword?: string;
};
// Warning: (ae-missing-release-tag) "defaultScmResolveUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function defaultScmResolveUrl(options: {
url: string;
@@ -115,92 +99,44 @@ export function defaultScmResolveUrl(options: {
lineNumber?: number;
}): string;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "getAzureCommitsUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function getAzureCommitsUrl(url: string): string;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "getAzureDownloadUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function getAzureDownloadUrl(url: string): string;
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "getAzureFileFetchUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function getAzureFileFetchUrl(url: string): string;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "getAzureRequestOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function getAzureRequestOptions(
config: AzureIntegrationConfig,
additionalHeaders?: Record<string, string>,
): RequestInit;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "getBitbucketDefaultBranch" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function getBitbucketDefaultBranch(
url: string,
config: BitbucketIntegrationConfig,
): Promise<string>;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "getBitbucketDownloadUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function getBitbucketDownloadUrl(
url: string,
config: BitbucketIntegrationConfig,
): Promise<string>;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "getBitbucketFileFetchUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function getBitbucketFileFetchUrl(
url: string,
config: BitbucketIntegrationConfig,
): string;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "getBitbucketRequestOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function getBitbucketRequestOptions(
config: BitbucketIntegrationConfig,
): RequestInit;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-forgotten-export) The symbol "GithubCredentials" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "getGitHubFileFetchUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function getGitHubFileFetchUrl(
url: string,
@@ -208,36 +144,34 @@ export function getGitHubFileFetchUrl(
credentials: GithubCredentials,
): string;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "getGitHubRequestOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public @deprecated
export function getGitHubRequestOptions(
config: GitHubIntegrationConfig,
credentials: GithubCredentials,
): RequestInit;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "getGitLabFileFetchUrl" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function getGitLabFileFetchUrl(
url: string,
config: GitLabIntegrationConfig,
): Promise<string>;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "getGitLabRequestOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function getGitLabRequestOptions(
config: GitLabIntegrationConfig,
): RequestInit;
// Warning: (ae-missing-release-tag) "GithubAppCredentialsMux" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type GithubAppConfig = {
appId: number;
privateKey: string;
webhookSecret: string;
clientId: string;
clientSecret: string;
allowedInstallationOwners?: string[];
};
// @public
export class GithubAppCredentialsMux {
constructor(config: GitHubIntegrationConfig);
// (undocumented)
@@ -248,33 +182,26 @@ export class GithubAppCredentialsMux {
getAppToken(owner: string, repo?: string): Promise<string | undefined>;
}
// Warning: (ae-missing-release-tag) "GithubCredentialsProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type GithubCredentials = {
headers?: {
[name: string]: string;
};
token?: string;
type: GithubCredentialType;
};
// @public
export class GithubCredentialsProvider {
// (undocumented)
static create(config: GitHubIntegrationConfig): GithubCredentialsProvider;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
// Warning: (tsdoc-undefined-tag) The TSDoc tag "@type" is not defined in this configuration
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
getCredentials(opts: { url: string }): Promise<GithubCredentials>;
}
// Warning: (ae-missing-release-tag) "GithubCredentialType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type GithubCredentialType = 'app' | 'token';
// Warning: (ae-missing-release-tag) "GitHubIntegration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class GitHubIntegration implements ScmIntegration {
constructor(integrationConfig: GitHubIntegrationConfig);
// (undocumented)
@@ -295,8 +222,6 @@ export class GitHubIntegration implements ScmIntegration {
get type(): string;
}
// Warning: (ae-missing-release-tag) "GitHubIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export type GitHubIntegrationConfig = {
host: string;
@@ -306,9 +231,7 @@ export type GitHubIntegrationConfig = {
apps?: GithubAppConfig[];
};
// Warning: (ae-missing-release-tag) "GitLabIntegration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class GitLabIntegration implements ScmIntegration {
constructor(integrationConfig: GitLabIntegrationConfig);
// (undocumented)
@@ -329,8 +252,6 @@ export class GitLabIntegration implements ScmIntegration {
get type(): string;
}
// Warning: (ae-missing-release-tag) "GitLabIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export type GitLabIntegrationConfig = {
host: string;
@@ -339,118 +260,90 @@ export type GitLabIntegrationConfig = {
baseUrl: string;
};
// Warning: (ae-missing-release-tag) "GoogleGcsIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export type GoogleGcsIntegrationConfig = {
clientEmail?: string;
privateKey?: string;
};
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "readAwsS3IntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export interface IntegrationsByType {
// (undocumented)
awsS3: ScmIntegrationsGroup<AwsS3Integration>;
// (undocumented)
azure: ScmIntegrationsGroup<AzureIntegration>;
// (undocumented)
bitbucket: ScmIntegrationsGroup<BitbucketIntegration>;
// (undocumented)
github: ScmIntegrationsGroup<GitHubIntegration>;
// (undocumented)
gitlab: ScmIntegrationsGroup<GitLabIntegration>;
}
// @public
export function readAwsS3IntegrationConfig(
config: Config,
): AwsS3IntegrationConfig;
// Warning: (ae-missing-release-tag) "readAwsS3IntegrationConfigs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export function readAwsS3IntegrationConfigs(
configs: Config[],
): AwsS3IntegrationConfig[];
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "readAzureIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function readAzureIntegrationConfig(
config: Config,
): AzureIntegrationConfig;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "readAzureIntegrationConfigs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function readAzureIntegrationConfigs(
configs: Config[],
): AzureIntegrationConfig[];
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "readBitbucketIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function readBitbucketIntegrationConfig(
config: Config,
): BitbucketIntegrationConfig;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "readBitbucketIntegrationConfigs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function readBitbucketIntegrationConfigs(
configs: Config[],
): BitbucketIntegrationConfig[];
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "readGitHubIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function readGitHubIntegrationConfig(
config: Config,
): GitHubIntegrationConfig;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "readGitHubIntegrationConfigs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function readGitHubIntegrationConfigs(
configs: Config[],
): GitHubIntegrationConfig[];
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "readGitLabIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function readGitLabIntegrationConfig(
config: Config,
): GitLabIntegrationConfig;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "readGitLabIntegrationConfigs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function readGitLabIntegrationConfigs(
configs: Config[],
): GitLabIntegrationConfig[];
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (ae-missing-release-tag) "readGoogleGcsIntegrationConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function readGoogleGcsIntegrationConfig(
config: Config,
): GoogleGcsIntegrationConfig;
// Warning: (ae-missing-release-tag) "replaceUrlType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export function replaceGitHubUrlType(
url: string,
type: 'blob' | 'tree' | 'edit',
): string;
// Warning: (ae-missing-release-tag) "ScmIntegration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export interface ScmIntegration {
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
resolveEditUrl(url: string): string;
// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters
// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters
// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters
resolveUrl(options: {
url: string;
base: string;
@@ -460,8 +353,6 @@ export interface ScmIntegration {
type: string;
}
// Warning: (ae-missing-release-tag) "ScmIntegrationRegistry" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export interface ScmIntegrationRegistry
extends ScmIntegrationsGroup<ScmIntegration> {
@@ -475,11 +366,7 @@ export interface ScmIntegrationRegistry
github: ScmIntegrationsGroup<GitHubIntegration>;
// (undocumented)
gitlab: ScmIntegrationsGroup<GitLabIntegration>;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
resolveEditUrl(url: string): string;
// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters
// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters
// Warning: (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters
resolveUrl(options: {
url: string;
base: string;
@@ -487,11 +374,8 @@ export interface ScmIntegrationRegistry
}): string;
}
// Warning: (ae-missing-release-tag) "ScmIntegrations" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export class ScmIntegrations implements ScmIntegrationRegistry {
// Warning: (ae-forgotten-export) The symbol "IntegrationsByType" needs to be exported by the entry point index.d.ts
constructor(integrationsByType: IntegrationsByType);
// (undocumented)
get awsS3(): ScmIntegrationsGroup<AwsS3Integration>;
@@ -521,20 +405,20 @@ export class ScmIntegrations implements ScmIntegrationRegistry {
}): string;
}
// Warning: (ae-missing-release-tag) "ScmIntegrationsGroup" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export type ScmIntegrationsFactory<T extends ScmIntegration> = (options: {
config: Config;
}) => ScmIntegrationsGroup<T>;
// @public
export interface ScmIntegrationsGroup<T extends ScmIntegration> {
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
byHost(host: string): T | undefined;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
byUrl(url: string | URL): T | undefined;
list(): T[];
}
// Warnings were encountered during analysis:
//
// src/github/config.d.ts:41:5 - (ae-forgotten-export) The symbol "GithubAppConfig" needs to be exported by the entry point index.d.ts
// src/gitlab/config.d.ts:27:68 - (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// src/gitlab/config.d.ts:27:63 - (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
// src/gitlab/config.d.ts:29:68 - (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// src/gitlab/config.d.ts:29:63 - (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
```
+1 -1
View File
@@ -44,7 +44,7 @@
"@backstage/test-utils": "^0.1.19",
"@types/jest": "^26.0.7",
"@types/luxon": "^2.0.4",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist",
+12 -2
View File
@@ -24,14 +24,24 @@ import { defaultScmResolveUrl } from './helpers';
import { ScmIntegration, ScmIntegrationsGroup } from './types';
import { ScmIntegrationRegistry } from './registry';
type IntegrationsByType = {
/**
* The set of supported integrations.
*
* @public
*/
export interface IntegrationsByType {
awsS3: ScmIntegrationsGroup<AwsS3Integration>;
azure: ScmIntegrationsGroup<AzureIntegration>;
bitbucket: ScmIntegrationsGroup<BitbucketIntegration>;
github: ScmIntegrationsGroup<GitHubIntegration>;
gitlab: ScmIntegrationsGroup<GitLabIntegration>;
};
}
/**
* Exposes the set of supported integrations.
*
* @public
*/
export class ScmIntegrations implements ScmIntegrationRegistry {
private readonly byType: IntegrationsByType;
@@ -18,6 +18,11 @@ import { basicIntegrations, defaultScmResolveUrl } from '../helpers';
import { ScmIntegration, ScmIntegrationsFactory } from '../types';
import { AwsS3IntegrationConfig, readAwsS3IntegrationConfigs } from './config';
/**
* Integrates with AWS S3 or compatible solutions.
*
* @public
*/
export class AwsS3Integration implements ScmIntegration {
static factory: ScmIntegrationsFactory<AwsS3Integration> = ({ config }) => {
const configs = readAwsS3IntegrationConfigs(
@@ -42,6 +47,7 @@ export class AwsS3Integration implements ScmIntegration {
}
constructor(private readonly integrationConfig: AwsS3IntegrationConfig) {}
resolveUrl(options: {
url: string;
base: string;
+11 -2
View File
@@ -21,8 +21,9 @@ const AMAZON_AWS_HOST = 'amazonaws.com';
/**
* The configuration parameters for a single AWS S3 provider.
*
* @public
*/
export type AwsS3IntegrationConfig = {
/**
* The host of the target that this matches on, e.g. "amazonaws.com"
@@ -50,7 +51,8 @@ export type AwsS3IntegrationConfig = {
/**
* Reads a single Aws S3 integration config.
*
* @param config The config object of a single integration
* @param config - The config object of a single integration
* @public
*/
export function readAwsS3IntegrationConfig(
@@ -70,6 +72,13 @@ export function readAwsS3IntegrationConfig(
return { host, accessKeyId, secretAccessKey, roleArn };
}
/**
* Reads a set of AWS S3 integration configs, and inserts some defaults for
* public Amazon AWS if not specified.
*
* @param configs - The config objects of the integrations
* @public
*/
export function readAwsS3IntegrationConfigs(
configs: Config[],
): AwsS3IntegrationConfig[] {
@@ -19,6 +19,11 @@ import { ScmIntegration, ScmIntegrationsFactory } from '../types';
import { AzureUrl } from './AzureUrl';
import { AzureIntegrationConfig, readAzureIntegrationConfigs } from './config';
/**
* Microsoft Azure based integration.
*
* @public
*/
export class AzureIntegration implements ScmIntegration {
static factory: ScmIntegrationsFactory<AzureIntegration> = ({ config }) => {
const configs = readAzureIntegrationConfigs(
+6 -2
View File
@@ -21,6 +21,8 @@ const AZURE_HOST = 'dev.azure.com';
/**
* The configuration parameters for a single Azure provider.
*
* @public
*/
export type AzureIntegrationConfig = {
/**
@@ -41,7 +43,8 @@ export type AzureIntegrationConfig = {
/**
* Reads a single Azure integration config.
*
* @param config The config object of a single integration
* @param config - The config object of a single integration
* @public
*/
export function readAzureIntegrationConfig(
config: Config,
@@ -62,7 +65,8 @@ export function readAzureIntegrationConfig(
* Reads a set of Azure integration configs, and inserts some defaults for
* public Azure if not specified.
*
* @param configs All of the integration config objects
* @param configs - All of the integration config objects
* @public
*/
export function readAzureIntegrationConfigs(
configs: Config[],
+13 -7
View File
@@ -21,11 +21,14 @@ import { AzureIntegrationConfig } from './config';
* Given a URL pointing to a file on a provider, returns a URL that is suitable
* for fetching the contents of the data.
*
* Converts
* from: https://dev.azure.com/{organization}/{project}/_git/reponame?path={path}&version=GB{commitOrBranch}&_a=contents
* to: https://dev.azure.com/{organization}/{project}/_apis/git/repositories/reponame/items?path={path}&version={commitOrBranch}
* @remarks
*
* @param url A URL pointing to a file
* Converts
* - from: `https://dev.azure.com/{organization}/{project}/_git/reponame?path={path}&version=GB{commitOrBranch}&_a=contents`
* - to: `https://dev.azure.com/{organization}/{project}/_apis/git/repositories/reponame/items?path={path}&version={commitOrBranch}`
*
* @param url - A URL pointing to a file
* @public
*/
export function getAzureFileFetchUrl(url: string): string {
return AzureUrl.fromRepoUrl(url).toFileUrl();
@@ -35,7 +38,8 @@ export function getAzureFileFetchUrl(url: string): string {
* Given a URL pointing to a path on a provider, returns a URL that is suitable
* for downloading the subtree.
*
* @param url A URL pointing to a path
* @param url - A URL pointing to a path
* @public
*/
export function getAzureDownloadUrl(url: string): string {
return AzureUrl.fromRepoUrl(url).toArchiveUrl();
@@ -44,7 +48,8 @@ export function getAzureDownloadUrl(url: string): string {
/**
* Given a URL, return the API URL to fetch commits on the branch.
*
* @param url A URL pointing to a repository or a sub-path
* @param url - A URL pointing to a repository or a sub-path
* @public
*/
export function getAzureCommitsUrl(url: string): string {
return AzureUrl.fromRepoUrl(url).toCommitsUrl();
@@ -53,7 +58,8 @@ export function getAzureCommitsUrl(url: string): string {
/**
* Gets the request options necessary to make requests to a given provider.
*
* @param config The relevant provider config
* @param config - The relevant provider config
* @public
*/
export function getAzureRequestOptions(
config: AzureIntegrationConfig,
@@ -22,6 +22,11 @@ import {
readBitbucketIntegrationConfigs,
} from './config';
/**
* A Bitbucket based integration.
*
* @public
*/
export class BitbucketIntegration implements ScmIntegration {
static factory: ScmIntegrationsFactory<BitbucketIntegration> = ({
config,
+6 -2
View File
@@ -23,6 +23,8 @@ const BITBUCKET_API_BASE_URL = 'https://api.bitbucket.org/2.0';
/**
* The configuration parameters for a single Bitbucket API provider.
*
* @public
*/
export type BitbucketIntegrationConfig = {
/**
@@ -66,7 +68,8 @@ export type BitbucketIntegrationConfig = {
/**
* Reads a single Bitbucket integration config.
*
* @param config The config object of a single integration
* @param config - The config object of a single integration
* @public
*/
export function readBitbucketIntegrationConfig(
config: Config,
@@ -102,7 +105,8 @@ export function readBitbucketIntegrationConfig(
* Reads a set of Bitbucket integration configs, and inserts some defaults for
* public Bitbucket if not specified.
*
* @param configs All of the integration config objects
* @param configs - All of the integration config objects
* @public
*/
export function readBitbucketIntegrationConfigs(
configs: Config[],

Some files were not shown because too many files have changed in this diff Show More