Signed-off-by: Ray Sinnema <rsinnema@ebay.com>
This commit is contained in:
Ray Sinnema
2021-10-27 18:35:20 +02:00
120 changed files with 935 additions and 503 deletions
+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': 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
+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/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/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
@@ -58,5 +58,7 @@
| [GoCardless](https://gocardless.com/) | [James Turley](https://github.com/tragiclifestories) | Developer portal: documentation, service templates, org structure, service catalog, plugins for integration with internal systems. |
| [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 internal customers. |
| [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 -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"
+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
@@ -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",
@@ -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": [
+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)) {
+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",
+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
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) {
+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": [
+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[],
+13 -7
View File
@@ -21,8 +21,9 @@ import { BitbucketIntegrationConfig } from './config';
/**
* Given a URL pointing to a path on a provider, returns the default branch.
*
* @param url A URL pointing to a path
* @param config The relevant provider config
* @param url - A URL pointing to a path
* @param config - The relevant provider config
* @public
*/
export async function getBitbucketDefaultBranch(
url: string,
@@ -71,8 +72,9 @@ export async function getBitbucketDefaultBranch(
* 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 config The relevant provider config
* @param url - A URL pointing to a path
* @param config - The relevant provider config
* @public
*/
export async function getBitbucketDownloadUrl(
url: string,
@@ -108,12 +110,15 @@ export async function getBitbucketDownloadUrl(
* Given a URL pointing to a file on a provider, returns a URL that is suitable
* for fetching the contents of the data.
*
* @remarks
*
* Converts
* from: https://bitbucket.org/orgname/reponame/src/master/file.yaml
* to: https://api.bitbucket.org/2.0/repositories/orgname/reponame/src/master/file.yaml
*
* @param url A URL pointing to a file
* @param config The relevant provider config
* @param url - A URL pointing to a file
* @param config - The relevant provider config
* @public
*/
export function getBitbucketFileFetchUrl(
url: string,
@@ -148,7 +153,8 @@ export function getBitbucketFileFetchUrl(
/**
* 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 getBitbucketRequestOptions(
config: BitbucketIntegrationConfig,
@@ -15,7 +15,7 @@
*/
import { ConfigReader } from '@backstage/config';
import { GitHubIntegration, replaceUrlType } from './GitHubIntegration';
import { GitHubIntegration, replaceGitHubUrlType } from './GitHubIntegration';
describe('GitHubIntegration', () => {
it('has a working factory', () => {
@@ -80,25 +80,28 @@ describe('GitHubIntegration', () => {
});
});
describe('replaceUrlType', () => {
describe('replaceGitHubUrlType', () => {
it('should replace with expected type', () => {
expect(
replaceUrlType(
replaceGitHubUrlType(
'https://github.com/backstage/backstage/blob/master/README.md',
'edit',
),
).toBe('https://github.com/backstage/backstage/edit/master/README.md');
expect(
replaceUrlType(
replaceGitHubUrlType(
'https://github.com/webmodules/blob/blob/master/test',
'tree',
),
).toBe('https://github.com/webmodules/blob/tree/master/test');
expect(
replaceUrlType('https://github.com/blob/blob/blob/master/test', 'tree'),
replaceGitHubUrlType(
'https://github.com/blob/blob/blob/master/test',
'tree',
),
).toBe('https://github.com/blob/blob/tree/master/test');
expect(
replaceUrlType(
replaceGitHubUrlType(
'https://github.com/backstage/backstage/edit/tree/README.md',
'blob',
),
@@ -21,6 +21,11 @@ import {
readGitHubIntegrationConfigs,
} from './config';
/**
* A GitHub based integration.
*
* @public
*/
export class GitHubIntegration implements ScmIntegration {
static factory: ScmIntegrationsFactory<GitHubIntegration> = ({ config }) => {
const configs = readGitHubIntegrationConfigs(
@@ -54,15 +59,22 @@ export class GitHubIntegration implements ScmIntegration {
// GitHub uses blob URLs for files and tree urls for directory listings. But
// there is a redirect from tree to blob for files, so we can always return
// tree urls here.
return replaceUrlType(defaultScmResolveUrl(options), 'tree');
return replaceGitHubUrlType(defaultScmResolveUrl(options), 'tree');
}
resolveEditUrl(url: string): string {
return replaceUrlType(url, 'edit');
return replaceGitHubUrlType(url, 'edit');
}
}
export function replaceUrlType(
/**
* Takes a GitHub URL and replaces the type part (blob, tree etc).
*
* @param url - The original URL
* @param type - The desired type, e.g. "blob"
* @public
*/
export function replaceGitHubUrlType(
url: string,
type: 'blob' | 'tree' | 'edit',
): string {
@@ -159,7 +159,11 @@ class GithubAppManager {
}
}
// GithubAppCredentialsMux corresponds to a Github installation which internally could hold several GitHub Apps.
/**
* Corresponds to a Github installation which internally could hold several GitHub Apps.
*
* @public
*/
export class GithubAppCredentialsMux {
private readonly apps: GithubAppManager[];
@@ -211,15 +215,32 @@ export class GithubAppCredentialsMux {
}
}
/**
* The type of credentials produced by the credential provider.
*
* @public
*/
export type GithubCredentialType = 'app' | 'token';
/**
* A set of credentials information for a GitHub integration.
*
* @public
*/
export type GithubCredentials = {
headers?: { [name: string]: string };
token?: string;
type: GithubCredentialType;
};
// TODO: Possibly move this to a backend only package so that it's not used in the frontend by mistake
/**
* Handles the creation and caching of credentials for GitHub integrations.
*
* @public
* @remarks
*
* TODO: Possibly move this to a backend only package so that it's not used in the frontend by mistake
*/
export class GithubCredentialsProvider {
static create(config: GitHubIntegrationConfig): GithubCredentialsProvider {
return new GithubCredentialsProvider(
@@ -234,13 +255,24 @@ export class GithubCredentialsProvider {
) {}
/**
* Returns GithubCredentials for requested url.
* Consecutive calls to this method with the same url will return cached credentials.
* Returns {@link GithubCredentials} for a given URL.
*
* @remarks
*
* Consecutive calls to this method with the same URL will return cached
* credentials.
*
* The shortest lifetime for a token returned is 10 minutes.
* @param opts containing the organization or repository url
* @returns {Promise} of @type {GithubCredentials}.
*
* @example
* const { token, headers } = await getCredentials({url: 'github.com/backstage/foobar'})
* ```ts
* const { token, headers } = await getCredentials({
* url: 'github.com/backstage/foobar'
* })
* ```
*
* @param opts - The organization or repository URL
* @returns A promise of {@link GithubCredentials}.
*/
async getCredentials(opts: { url: string }): Promise<GithubCredentials> {
const parsed = parseGitUrl(opts.url);
+12 -3
View File
@@ -24,6 +24,8 @@ const GITHUB_RAW_BASE_URL = 'https://raw.githubusercontent.com';
/**
* The configuration parameters for a single GitHub integration.
*
* @public
*/
export type GitHubIntegrationConfig = {
/**
@@ -70,7 +72,12 @@ export type GitHubIntegrationConfig = {
/**
* The configuration parameters for authenticating a GitHub Application.
* A Github Apps configuration can be generated using the `backstage-cli create-github-app` command.
*
* @remarks
*
* A GitHub Apps configuration can be generated using the `backstage-cli create-github-app` command.
*
* @public
*/
export type GithubAppConfig = {
/**
@@ -107,7 +114,8 @@ export type GithubAppConfig = {
/**
* Reads a single GitHub integration config.
*
* @param config The config object of a single integration
* @param config - The config object of a single integration
* @public
*/
export function readGitHubIntegrationConfig(
config: Config,
@@ -152,7 +160,8 @@ export function readGitHubIntegrationConfig(
* Reads a set of GitHub integration configs, and inserts some defaults for
* public GitHub if not specified.
*
* @param configs All of the integration config objects
* @param configs - All of the integration config objects
* @public
*/
export function readGitHubIntegrationConfigs(
configs: Config[],
+7 -3
View File
@@ -22,13 +22,16 @@ import { GithubCredentials } from './GithubCredentialsProvider';
* Given a URL pointing to a file on a provider, returns a URL that is suitable
* for fetching the contents of the data.
*
* @remarks
*
* Converts
* from: https://github.com/a/b/blob/branchname/path/to/c.yaml
* to: https://api.github.com/repos/a/b/contents/path/to/c.yaml?ref=branchname
* or: https://raw.githubusercontent.com/a/b/branchname/c.yaml
*
* @param url A URL pointing to a file
* @param config The relevant provider config
* @param url - A URL pointing to a file
* @param config - The relevant provider config
* @public
*/
export function getGitHubFileFetchUrl(
url: string,
@@ -64,7 +67,8 @@ export function getGitHubFileFetchUrl(
* Gets the request options necessary to make requests to a given provider.
*
* @deprecated This function is no longer used internally
* @param config The relevant provider config
* @param config - The relevant provider config
* @public
*/
export function getGitHubRequestOptions(
config: GitHubIntegrationConfig,
+6 -6
View File
@@ -18,14 +18,14 @@ export {
readGitHubIntegrationConfig,
readGitHubIntegrationConfigs,
} from './config';
export type { GitHubIntegrationConfig } from './config';
export type { GithubAppConfig, GitHubIntegrationConfig } from './config';
export { getGitHubFileFetchUrl, getGitHubRequestOptions } from './core';
export {
GithubAppCredentialsMux,
GithubCredentialsProvider,
} from './GithubCredentialsProvider';
export type { GithubCredentialType } from './GithubCredentialsProvider';
export {
GitHubIntegration,
replaceUrlType as replaceGitHubUrlType,
} from './GitHubIntegration';
export type {
GithubCredentials,
GithubCredentialType,
} from './GithubCredentialsProvider';
export { GitHubIntegration, replaceGitHubUrlType } from './GitHubIntegration';
@@ -21,6 +21,11 @@ import {
readGitLabIntegrationConfigs,
} from './config';
/**
* A GitLab based integration.
*
* @public
*/
export class GitLabIntegration implements ScmIntegration {
static factory: ScmIntegrationsFactory<GitLabIntegration> = ({ config }) => {
const configs = readGitLabIntegrationConfigs(
+6 -2
View File
@@ -23,6 +23,8 @@ const GITLAB_API_BASE_URL = 'https://gitlab.com/api/v4';
/**
* The configuration parameters for a single GitLab integration.
*
* @public
*/
export type GitLabIntegrationConfig = {
/**
@@ -57,7 +59,8 @@ export type GitLabIntegrationConfig = {
/**
* Reads a single GitLab integration config.
*
* @param config The config object of a single integration
* @param config - The config object of a single integration
* @public
*/
export function readGitLabIntegrationConfig(
config: Config,
@@ -104,7 +107,8 @@ export function readGitLabIntegrationConfig(
* Reads a set of GitLab integration configs, and inserts some defaults for
* public GitLab if not specified.
*
* @param configs All of the integration config objects
* @param configs - All of the integration config objects
* @public
*/
export function readGitLabIntegrationConfigs(
configs: Config[],
+7 -3
View File
@@ -21,6 +21,8 @@ import fetch from 'cross-fetch';
* Given a URL pointing to a file on a provider, returns a URL that is suitable
* for fetching the contents of the data.
*
* @remarks
*
* Converts
* from: https://gitlab.example.com/a/b/blob/master/c.yaml
* to: https://gitlab.example.com/a/b/raw/master/c.yaml
@@ -28,8 +30,9 @@ import fetch from 'cross-fetch';
* from: https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/filepath
* to: https://gitlab.com/api/v4/projects/projectId/repository/files/filepath?ref=branch
*
* @param url A URL pointing to a file
* @param config The relevant provider config
* @param url - A URL pointing to a file
* @param config - The relevant provider config
* @public
*/
export async function getGitLabFileFetchUrl(
url: string,
@@ -48,7 +51,8 @@ export async function getGitLabFileFetchUrl(
/**
* 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 getGitLabRequestOptions(
config: GitLabIntegrationConfig,
+4 -1
View File
@@ -18,6 +18,8 @@ import { Config } from '@backstage/config';
/**
* The configuration parameters for a single Google Cloud Storage provider.
*
* @public
*/
export type GoogleGcsIntegrationConfig = {
/**
@@ -33,7 +35,8 @@ export type GoogleGcsIntegrationConfig = {
/**
* Reads a single Google GCS integration config.
*
* @param config The config object of a single integration
* @param config - The config object of a single integration
* @public
*/
export function readGoogleGcsIntegrationConfig(
config: Config,
+4 -2
View File
@@ -59,8 +59,10 @@ export function basicIntegrations<T extends ScmIntegration>(
}
/**
* Default implementation of ScmIntegration.resolveUrl, that only works with
* URL pathname based providers.
* Default implementation of {@link ScmIntegration} `resolveUrl`, that only
* works with URL pathname based providers.
*
* @public
*/
export function defaultScmResolveUrl(options: {
url: string;
+6 -1
View File
@@ -28,5 +28,10 @@ export * from './googleGcs';
export * from './awsS3';
export { defaultScmResolveUrl } from './helpers';
export { ScmIntegrations } from './ScmIntegrations';
export type { ScmIntegration, ScmIntegrationsGroup } from './types';
export type { IntegrationsByType } from './ScmIntegrations';
export type {
ScmIntegration,
ScmIntegrationsFactory,
ScmIntegrationsGroup,
} from './types';
export type { ScmIntegrationRegistry } from './registry';
+12 -5
View File
@@ -23,6 +23,8 @@ import { GitLabIntegration } from './gitlab/GitLabIntegration';
/**
* Holds all registered SCM integrations, of all types.
*
* @public
*/
export interface ScmIntegrationRegistry
extends ScmIntegrationsGroup<ScmIntegration> {
@@ -43,14 +45,19 @@ export interface ScmIntegrationRegistry
* within the file tree of a certain repo, an absolute path of `/b.yaml` does
* not resolve to `https://hostname/b.yaml` but rather to
* `<repo root url>/b.yaml` inside the file tree of that same repo.
*
* @param options.url The (absolute or relative) URL or path to resolve
* @param options.base The base URL onto which this resolution happens
* @param options.lineNumber The line number in the target file to link to, starting with 1. Only applicable when linking to files.
*/
resolveUrl(options: {
/**
* The (absolute or relative) URL or path to resolve.
*/
url: string;
/**
* The base URL onto which this resolution happens
*/
base: string;
/**
* The line number in the target file to link to, starting with 1. Only applicable when linking to files.
*/
lineNumber?: number;
}): string;
@@ -63,7 +70,7 @@ export interface ScmIntegrationRegistry
* If this is not possible, the integration can fall back to a URL to view
* the file in the web interface.
*
* @param url The absolute URL to the file that should be edited.
* @param url - The absolute URL to the file that should be edited.
*/
resolveEditUrl(url: string): string;
}
+21 -7
View File
@@ -18,6 +18,8 @@ import { Config } from '@backstage/config';
/**
* Encapsulates a single SCM integration.
*
* @public
*/
export interface ScmIntegration {
/**
@@ -42,14 +44,19 @@ export interface ScmIntegration {
* within the file tree of a certain repo, an absolute path of `/b.yaml` does
* not resolve to `https://hostname/b.yaml` but rather to
* `<repo root url>/b.yaml` inside the file tree of that same repo.
*
* @param options.url The (absolute or relative) URL or path to resolve
* @param options.base The base URL onto which this resolution happens
* @param options.lineNumber The line number in the target file to link to, starting with 1. Only applicable when linking to files.
*/
resolveUrl(options: {
/**
* The (absolute or relative) URL or path to resolve
*/
url: string;
/**
* The base URL onto which this resolution happens
*/
base: string;
/**
* The line number in the target file to link to, starting with 1. Only applicable when linking to files.
*/
lineNumber?: number;
}): string;
@@ -62,13 +69,15 @@ export interface ScmIntegration {
* If this is not possible, the integration can fall back to a URL to view
* the file in the web interface.
*
* @param url The absolute URL to the file that should be edited.
* @param url - The absolute URL to the file that should be edited.
*/
resolveEditUrl(url: string): string;
}
/**
* Encapsulates several integrations, that are all of the same type.
*
* @public
*/
export interface ScmIntegrationsGroup<T extends ScmIntegration> {
/**
@@ -79,18 +88,23 @@ export interface ScmIntegrationsGroup<T extends ScmIntegration> {
/**
* Fetches an integration of this type by URL.
*
* @param url A URL that matches a registered integration of this type
* @param url - A URL that matches a registered integration of this type
*/
byUrl(url: string | URL): T | undefined;
/**
* Fetches an integration of this type by host name.
*
* @param url A host name that matches a registered integration of this type
* @param host - A host name that matches a registered integration of this type
*/
byHost(host: string): T | undefined;
}
/**
* A factory function that creates an integration group based on configuration.
*
* @public
*/
export type ScmIntegrationsFactory<T extends ScmIntegration> = (options: {
config: Config;
}) => ScmIntegrationsGroup<T>;
@@ -334,15 +334,12 @@ describe('AwsS3Publish', () => {
name: 'path',
};
const techDocsMetadaFilePath = path.posix.join(
...Object.values(invalidEntityName),
'techdocs_metadata.json',
);
const fails = publisher.fetchTechDocsMetadata(invalidEntityName);
await expect(fails).rejects.toMatchObject({
message: `TechDocs metadata fetch failed; caused by Error: The file ${techDocsMetadaFilePath} does not exist!`,
message: expect.stringMatching(
/TechDocs metadata fetch failed; caused by Error: The file .* does not exist/i,
),
});
});
});
@@ -332,15 +332,10 @@ describe('GoogleGCSPublish', () => {
name: 'path',
};
const techDocsMetadaFilePath = path.posix.join(
...Object.values(invalidEntityName),
'techdocs_metadata.json',
);
const fails = publisher.fetchTechDocsMetadata(invalidEntityName);
await expect(fails).rejects.toMatchObject({
message: `The file ${techDocsMetadaFilePath} does not exist!`,
message: expect.stringMatching(/The file .* does not exist/i),
});
});
});
@@ -198,10 +198,12 @@ export const getCloudPathForLocalPath = (
? relativeFilePathTriplet
: lowerCaseEntityTriplet(relativeFilePathTriplet);
const destinationWithRoot = path.join(
...externalStorageRootPath.split(path.posix.sep),
// Again, the / delimiter is intentional, as it represents remote storage.
const destinationWithRoot = [
// The extra filter prevents unintended double slashes and prefixes.
...externalStorageRootPath.split(path.posix.sep).filter(s => s !== ''),
destination,
);
].join('/');
return destinationWithRoot; // Remote storage file relative path
};
-1
View File
@@ -38,7 +38,6 @@
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
"@types/react": "*",
"msw": "^0.29.0",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-router": "6.0.0-beta.0",
+75 -52
View File
@@ -9,106 +9,129 @@ import { PaletteOptions } from '@material-ui/core/styles/createPalette';
import { Theme } from '@material-ui/core';
import { ThemeOptions } from '@material-ui/core';
// Warning: (ae-forgotten-export) The symbol "PaletteAdditions" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "BackstagePalette" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export type BackstagePalette = Palette & PaletteAdditions;
// @public
export type BackstagePalette = Palette & BackstagePaletteAdditions;
// Warning: (ae-missing-release-tag) "BackstagePaletteOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export type BackstagePaletteOptions = PaletteOptions & PaletteAdditions;
// @public
export type BackstagePaletteAdditions = {
status: {
ok: string;
warning: string;
error: string;
pending: string;
running: string;
aborted: string;
};
border: string;
textContrast: string;
textVerySubtle: string;
textSubtle: string;
highlight: string;
errorBackground: string;
warningBackground: string;
infoBackground: string;
errorText: string;
infoText: string;
warningText: string;
linkHover: string;
link: string;
gold: string;
navigation: {
background: string;
indicator: string;
color: string;
selectedColor: string;
};
tabbar: {
indicator: string;
};
bursts: {
fontColor: string;
slackChannelText: string;
backgroundColor: {
default: string;
};
gradient: {
linear: string;
};
};
pinSidebarButton: {
icon: string;
background: string;
};
banner: {
info: string;
error: string;
text: string;
link: string;
};
};
// Warning: (ae-missing-release-tag) "BackstageTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type BackstagePaletteOptions = PaletteOptions &
BackstagePaletteAdditions;
// @public
export interface BackstageTheme extends Theme {
// (undocumented)
getPageTheme: ({ themeId }: PageThemeSelector) => PageTheme;
getPageTheme: (selector: PageThemeSelector) => PageTheme;
// (undocumented)
page: PageTheme;
// (undocumented)
palette: BackstagePalette;
}
// Warning: (ae-missing-release-tag) "BackstageThemeOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export interface BackstageThemeOptions extends ThemeOptions {
// (undocumented)
getPageTheme: ({ themeId }: PageThemeSelector) => PageTheme;
getPageTheme: (selector: PageThemeSelector) => PageTheme;
// (undocumented)
page: PageTheme;
// (undocumented)
palette: BackstagePaletteOptions;
}
// Warning: (ae-missing-release-tag) "colorVariants" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export const colorVariants: Record<string, string[]>;
// Warning: (ae-missing-release-tag) "createTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export function createTheme(options: SimpleThemeOptions): BackstageTheme;
// Warning: (ae-missing-release-tag) "createThemeOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export function createThemeOptions(
options: SimpleThemeOptions,
): BackstageThemeOptions;
// Warning: (ae-missing-release-tag) "createThemeOverrides" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export function createThemeOverrides(theme: BackstageTheme): Overrides;
// Warning: (ae-missing-release-tag) "darkTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export const darkTheme: BackstageTheme;
// Warning: (ae-missing-release-tag) "genPageTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export function genPageTheme(colors: string[], shape: string): PageTheme;
// Warning: (ae-missing-release-tag) "lightTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export const lightTheme: BackstageTheme;
// Warning: (ae-missing-release-tag) "PageTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type PageTheme = {
colors: string[];
shape: string;
backgroundImage: string;
};
// Warning: (ae-missing-release-tag) "pageTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export const pageTheme: Record<string, PageTheme>;
// Warning: (ae-missing-release-tag) "PageThemeSelector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export type PageThemeSelector = {
themeId: string;
};
// Warning: (ae-missing-release-tag) "shapes" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export const shapes: Record<string, string>;
// Warning: (ae-missing-release-tag) "SimpleThemeOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export type SimpleThemeOptions = {
palette: BackstagePaletteOptions;
+16 -3
View File
@@ -17,7 +17,6 @@
import { createTheme as createMuiTheme } from '@material-ui/core/styles';
import { darken, lighten } from '@material-ui/core/styles/colorManipulator';
import { Overrides } from '@material-ui/core/styles/overrides';
import {
BackstageTheme,
BackstageThemeOptions,
@@ -28,6 +27,11 @@ import { pageTheme as defaultPageThemes } from './pageTheme';
const DEFAULT_FONT_FAMILY =
'"Helvetica Neue", Helvetica, Roboto, Arial, sans-serif';
/**
* A helper for creating theme options.
*
* @public
*/
export function createThemeOptions(
options: SimpleThemeOptions,
): BackstageThemeOptions {
@@ -84,6 +88,11 @@ export function createThemeOptions(
};
}
/**
* A helper for creating theme overrides.
*
* @public
*/
export function createThemeOverrides(theme: BackstageTheme): Overrides {
return {
MuiCssBaseline: {
@@ -271,8 +280,12 @@ export function createThemeOverrides(theme: BackstageTheme): Overrides {
};
}
// Creates a Backstage MUI theme using a palette.
// The theme is created with the common Backstage options and component styles.
/**
* Creates a Backstage MUI theme using a palette. The theme is created with the
* common Backstage options and component styles.
*
* @public
*/
export function createTheme(options: SimpleThemeOptions): BackstageTheme {
const themeOptions = createThemeOptions(options);
const baseTheme = createMuiTheme(themeOptions) as BackstageTheme;
+35 -13
View File
@@ -15,22 +15,33 @@
*/
import { PageTheme } from './types';
/*
# How to add a shape
1. Get the svg shape from figma, should be ~1400 wide, ~400 high
and only the white->transparent mask, no colors.
2. Run it through https://jakearchibald.github.io/svgomg/
3. Run that through https://github.com/tigt/mini-svg-data-uri
with something like https://npm.runkit.com/mini-svg-data-uri
4. Wrap the output in `url("")`
5. Give it a name and paste it into the `shapes` object below.
*/
/**
* The default predefined burst shapes.
*
* @public
* @remarks
*
* How to add a shape:
*
* 1. Get the svg shape from figma, should be ~1400 wide, ~400 high
* and only the white-to-transparent mask, no colors.
* 2. Run it through https://jakearchibald.github.io/svgomg/
* 3. Run that through https://github.com/tigt/mini-svg-data-uri
* with something like https://npm.runkit.com/mini-svg-data-uri
* 4. Wrap the output in `url("")`
* 5. Give it a name and paste it into the `shapes` object below.
*/
export const shapes: Record<string, string> = {
wave: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='1368' height='400' fill='none'%3e%3cmask id='a' width='1368' height='401' x='0' y='0' maskUnits='userSpaceOnUse'%3e%3cpath fill='url(%23paint0_linear)' d='M437 116C223 116 112 0 112 0h1256v400c-82 0-225-21-282-109-112-175-436-175-649-175z'/%3e%3cpath fill='url(%23paint1_linear)' d='M1368 400V282C891-29 788 40 711 161 608 324 121 372 0 361v39h1368z'/%3e%3cpath fill='url(%23paint2_linear)' d='M1368 244v156H0V94c92-24 198-46 375 0l135 41c176 51 195 109 858 109z'/%3e%3cpath fill='url(%23paint3_linear)' d='M1252 400h116c-14-7-35-14-116-16-663-14-837-128-1013-258l-85-61C98 28 46 8 0 0v400h1252z'/%3e%3c/mask%3e%3cg mask='url(%23a)'%3e%3cpath fill='white' d='M-172-98h1671v601H-172z'/%3e%3c/g%3e%3cdefs%3e%3clinearGradient id='paint0_linear' x1='602' x2='1093.5' y1='-960.5' y2='272' gradientUnits='userSpaceOnUse'%3e%3cstop stop-color='white'/%3e%3cstop offset='1' stop-color='white' stop-opacity='0'/%3e%3c/linearGradient%3e%3clinearGradient id='paint1_linear' x1='482' x2='480' y1='1058.5' y2='70.5' gradientUnits='userSpaceOnUse'%3e%3cstop stop-color='white'/%3e%3cstop offset='1' stop-color='white' stop-opacity='0'/%3e%3c/linearGradient%3e%3clinearGradient id='paint2_linear' x1='424' x2='446.1' y1='-587.5' y2='274.6' gradientUnits='userSpaceOnUse'%3e%3cstop stop-color='white'/%3e%3cstop offset='1' stop-color='white' stop-opacity='0'/%3e%3c/linearGradient%3e%3clinearGradient id='paint3_linear' x1='587' x2='349' y1='-1120.5' y2='341' gradientUnits='userSpaceOnUse'%3e%3cstop stop-color='white'/%3e%3cstop offset='1' stop-color='white' stop-opacity='0'/%3e%3c/linearGradient%3e%3c/defs%3e%3c/svg%3e")`,
wave2: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='1368' height='400' fill='none'%3e%3cmask id='a' width='1764' height='479' x='-229' y='-6' maskUnits='userSpaceOnUse'%3e%3cpath fill='url(%23paint0_linear)' d='M0 400h1350C1321 336 525 33 179-2c-345-34-395 236-408 402H0z'/%3e%3cpath fill='url(%23paint1_linear)' d='M1378 177v223H0V217s219 75 327 52C436 246 717-35 965 45s254 144 413 132z'/%3e%3cpath fill='url(%23paint2_linear)' d='M26 400l-78-16c-170 205-44-6-137-30l-4-1 4 1 137 30c37-45 89-110 159-201 399-514-45 238 1176-50 275-65 354-39 91 267H26z'/%3e%3c/mask%3e%3cg mask='url(%23a)'%3e%3cpath fill='white' d='M0 0h1368v400H0z'/%3e%3c/g%3e%3cdefs%3e%3clinearGradient id='paint0_linear' x1='431' x2='397.3' y1='-599' y2='372.8' gradientUnits='userSpaceOnUse'%3e%3cstop stop-color='white'/%3e%3cstop offset='1' stop-color='white' stop-opacity='0'/%3e%3c/linearGradient%3e%3clinearGradient id='paint1_linear' x1='236.5' x2='446.6' y1='-586' y2='381.5' gradientUnits='userSpaceOnUse'%3e%3cstop stop-color='white'/%3e%3cstop offset='1' stop-color='white' stop-opacity='0'/%3e%3c/linearGradient%3e%3clinearGradient id='paint2_linear' x1='851.8' x2='640.4' y1='-867.2' y2='363.7' gradientUnits='userSpaceOnUse'%3e%3cstop stop-color='white'/%3e%3cstop offset='1' stop-color='white' stop-opacity='0'/%3e%3c/linearGradient%3e%3c/defs%3e%3c/svg%3e")`,
round: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='1368' height='400' fill='none'%3e%3cmask id='a' width='2269' height='1408' x='-610' y='-509' maskUnits='userSpaceOnUse'%3e%3ccircle cx='1212.8' cy='74.8' r='317.5' fill='url(%23paint0_linear)' transform='rotate(-52 1213 75)'/%3e%3ccircle cx='737.8' cy='445.8' r='317.5' fill='url(%23paint1_linear)' transform='rotate(-116 738 446)'/%3e%3ccircle cx='601.8' cy='52.8' r='418.6' fill='url(%23paint2_linear)' transform='rotate(-117 602 53)'/%3e%3ccircle cx='999.8' cy='364' r='389.1' fill='url(%23paint3_linear)' transform='rotate(31 1000 364)'/%3e%3cellipse cx='-109.2' cy='263.5' fill='url(%23paint4_linear)' rx='429.2' ry='465.8' transform='rotate(-85 -109 264)'/%3e%3c/mask%3e%3cg mask='url(%23a)'%3e%3cpath fill='white' d='M0 0h1368v400H0z'/%3e%3c/g%3e%3cdefs%3e%3clinearGradient id='paint0_linear' x1='1301.2' x2='161.4' y1='-1879.7' y2='-969.6' gradientUnits='userSpaceOnUse'%3e%3cstop stop-color='white'/%3e%3cstop offset='1' stop-color='white' stop-opacity='0'/%3e%3c/linearGradient%3e%3clinearGradient id='paint1_linear' x1='826.2' x2='-313.6' y1='-1508.7' y2='-598.6' gradientUnits='userSpaceOnUse'%3e%3cstop stop-color='white'/%3e%3cstop offset='1' stop-color='white' stop-opacity='0'/%3e%3c/linearGradient%3e%3clinearGradient id='paint2_linear' x1='718.4' x2='-784.3' y1='-2524' y2='-1324.2' gradientUnits='userSpaceOnUse'%3e%3cstop stop-color='white'/%3e%3cstop offset='1' stop-color='white' stop-opacity='0'/%3e%3c/linearGradient%3e%3clinearGradient id='paint3_linear' x1='1108.2' x2='-288.6' y1='-2031.1' y2='-915.9' gradientUnits='userSpaceOnUse'%3e%3cstop stop-color='white'/%3e%3cstop offset='1' stop-color='white' stop-opacity='0'/%3e%3c/linearGradient%3e%3clinearGradient id='paint4_linear' x1='10.4' x2='-1626.5' y1='-2603.8' y2='-1399.5' gradientUnits='userSpaceOnUse'%3e%3cstop stop-color='white'/%3e%3cstop offset='1' stop-color='white' stop-opacity='0'/%3e%3c/linearGradient%3e%3c/defs%3e%3c/svg%3e")`,
};
/**
* The color range variants that are used in e.g. colorful bursts.
*
* @public
*/
export const colorVariants: Record<string, string[]> = {
darkGrey: ['#171717', '#383838'],
marineBlue: ['#006D8F', '#0049A1'],
@@ -43,9 +54,15 @@ export const colorVariants: Record<string, string[]> = {
pinkSea: ['#C8077A', '#C2297D'],
};
// As the background shapes and colors are decorative, we place them onto
// the page as a css background-image instead of an html element of its own.
// Utility to not have to write colors and shapes twice.
/**
* Utility to not have to write colors and shapes twice.
*
* @public
* @remarks
*
* As the background shapes and colors are decorative, we place them onto the
* page as a css background-image instead of an html element of its own.
*/
export function genPageTheme(colors: string[], shape: string): PageTheme {
const gradientColors = colors.length === 1 ? [colors[0], colors[0]] : colors;
const gradient = `linear-gradient(90deg, ${gradientColors.join(', ')})`;
@@ -54,6 +71,11 @@ export function genPageTheme(colors: string[], shape: string): PageTheme {
return { colors, shape, backgroundImage };
}
/**
* All of the builtin page themes.
*
* @public
*/
export const pageTheme: Record<string, PageTheme> = {
home: genPageTheme(colorVariants.teal, shapes.wave),
documentation: genPageTheme(colorVariants.pinkSea, shapes.wave2),
+10
View File
@@ -18,6 +18,11 @@ import { createTheme } from './baseTheme';
import { pageTheme } from './pageTheme';
import { yellow } from '@material-ui/core/colors';
/**
* The default Backstage light theme.
*
* @public
*/
export const lightTheme = createTheme({
palette: {
type: 'light',
@@ -83,6 +88,11 @@ export const lightTheme = createTheme({
pageTheme,
});
/**
* The default Backstage dark theme.
*
* @public
*/
export const darkTheme = createTheme({
palette: {
type: 'dark',
+57 -11
View File
@@ -20,7 +20,12 @@ import {
Palette,
} from '@material-ui/core/styles/createPalette';
type PaletteAdditions = {
/**
* Backstage specific additions to the material-ui palette.
*
* @public
*/
export type BackstagePaletteAdditions = {
status: {
ok: string;
warning: string;
@@ -74,27 +79,63 @@ type PaletteAdditions = {
};
};
export type BackstagePalette = Palette & PaletteAdditions;
export type BackstagePaletteOptions = PaletteOptions & PaletteAdditions;
/**
* The full Backstage palette.
*
* @public
*/
export type BackstagePalette = Palette & BackstagePaletteAdditions;
/**
* The full Backstage palette options.
*
* @public
*/
export type BackstagePaletteOptions = PaletteOptions &
BackstagePaletteAdditions;
/**
* Selector for what page theme to use.
*
* @public
*/
export type PageThemeSelector = {
themeId: string;
};
/**
* A Backstage theme.
*
* @public
*/
export interface BackstageTheme extends Theme {
palette: BackstagePalette;
page: PageTheme;
getPageTheme: ({ themeId }: PageThemeSelector) => PageTheme;
}
export interface BackstageThemeOptions extends ThemeOptions {
palette: BackstagePaletteOptions;
page: PageTheme;
getPageTheme: ({ themeId }: PageThemeSelector) => PageTheme;
getPageTheme: (selector: PageThemeSelector) => PageTheme;
}
/**
* A simpler configuration for creating a new theme that just tweaks some parts of the backstage one.
* Backstage theme options.
*
* @public
* @remarks
*
* This is essentially a partial theme definition made by the user, that then
* gets merged together with defaults and other values to form the final
* {@link BackstageTheme}.
*
*/
export interface BackstageThemeOptions extends ThemeOptions {
palette: BackstagePaletteOptions;
page: PageTheme;
getPageTheme: (selector: PageThemeSelector) => PageTheme;
}
/**
* A simpler configuration for creating a new theme that just tweaks some parts
* of the backstage one.
*
* @public
*/
export type SimpleThemeOptions = {
palette: BackstagePaletteOptions;
@@ -103,6 +144,11 @@ export type SimpleThemeOptions = {
fontFamily?: string;
};
/**
* The theme definitions for a given layout page.
*
* @public
*/
export type PageTheme = {
colors: string[];
shape: string;
+1 -1
View File
@@ -46,7 +46,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -44,7 +44,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist",
+1 -1
View File
@@ -64,7 +64,7 @@
"@types/node": "^14.14.32",
"@types/swagger-ui-react": "^3.23.3",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -45,7 +45,7 @@
"@backstage/cli": "^0.8.0",
"@backstage/types": "^0.1.1",
"@types/supertest": "^2.0.8",
"msw": "^0.29.0",
"msw": "^0.35.0",
"supertest": "^6.1.3"
},
"files": [
+1 -1
View File
@@ -84,7 +84,7 @@
"@types/passport-saml": "^1.1.3",
"@types/passport-strategy": "^0.2.35",
"@types/xml2js": "^0.4.7",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist",
+1 -1
View File
@@ -33,7 +33,7 @@
"@backstage/cli": "^0.8.0",
"@types/supertest": "^2.0.8",
"supertest": "^4.0.2",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist",
+1 -1
View File
@@ -54,7 +54,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -52,7 +52,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -50,7 +50,7 @@
"@types/node": "^14.14.32",
"@types/recharts": "^1.8.15",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
@@ -45,7 +45,7 @@
"@backstage/cli": "^0.8.0",
"@backstage/test-utils": "^0.1.19",
"@types/lodash": "^4.14.151",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist",
+1 -1
View File
@@ -72,7 +72,7 @@
"@types/uuid": "^8.0.0",
"@types/yup": "^0.29.13",
"aws-sdk-mock": "^5.2.1",
"msw": "^0.29.0",
"msw": "^0.35.0",
"sqlite3": "^5.0.1",
"supertest": "^6.1.3",
"wait-for-expect": "^3.0.2",
+1 -1
View File
@@ -49,7 +49,7 @@
"@graphql-codegen/typescript": "^1.17.7",
"@graphql-codegen/typescript-resolvers": "^1.17.7",
"eslint-plugin-graphql": "^4.0.0",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -65,7 +65,7 @@
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.7",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+11 -1
View File
@@ -658,10 +658,20 @@ export class EntityTypeFilter implements EntityFilter {
readonly value: string | string[];
}
// Warning: (ae-missing-release-tag) "EntityTypeFilterProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export type EntityTypeFilterProps = {
initialFilter?: string;
hidden?: boolean;
};
// Warning: (ae-missing-release-tag) "EntityTypePicker" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const EntityTypePicker: () => JSX.Element | null;
export const EntityTypePicker: (
props: EntityTypeFilterProps,
) => JSX.Element | null;
// 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 "Props" needs to be exported by the entry point index.d.ts
@@ -121,4 +121,26 @@ describe('<EntityTypePicker/>', () => {
expect(updateFilters).toHaveBeenLastCalledWith({ type: undefined });
});
it('respects the query parameter filter value', async () => {
const updateFilters = jest.fn();
const queryParameters = { type: 'tool' };
await renderWithEffects(
<ApiProvider apis={apis}>
<MockEntityListContextProvider
value={{
updateFilters,
queryParameters,
}}
>
<EntityTypePicker initialFilter="tool" hidden />
</MockEntityListContextProvider>
,
</ApiProvider>,
);
expect(updateFilters).toHaveBeenLastCalledWith({
type: new EntityTypeFilter(['tool']),
});
});
});
@@ -22,7 +22,13 @@ import { useEntityTypeFilter } from '../../hooks/useEntityTypeFilter';
import { alertApiRef, useApi } from '@backstage/core-plugin-api';
import { Select } from '@backstage/core-components';
export const EntityTypePicker = () => {
export type EntityTypeFilterProps = {
initialFilter?: string;
hidden?: boolean;
};
export const EntityTypePicker = (props: EntityTypeFilterProps) => {
const { hidden, initialFilter } = props;
const alertApi = useApi(alertApiRef);
const { error, availableTypes, selectedTypes, setSelectedTypes } =
useEntityTypeFilter();
@@ -34,7 +40,10 @@ export const EntityTypePicker = () => {
severity: 'error',
});
}
}, [error, alertApi]);
if (initialFilter) {
setSelectedTypes([initialFilter]);
}
}, [error, alertApi, initialFilter, setSelectedTypes]);
if (availableTypes.length === 0 || error) return null;
@@ -46,7 +55,7 @@ export const EntityTypePicker = () => {
})),
];
return (
return hidden ? null : (
<Box pb={1} pt={1}>
<Select
label="Type"
@@ -15,3 +15,4 @@
*/
export { EntityTypePicker } from './EntityTypePicker';
export type { EntityTypeFilterProps } from './EntityTypePicker';
+1 -1
View File
@@ -64,7 +64,7 @@
"@types/node": "^14.14.32",
"@types/react-lazylog": "^4.5.0",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -59,7 +59,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -40,7 +40,7 @@
"@backstage/cli": "^0.8.0",
"@types/express-xml-bodyparser": "^0.3.2",
"@types/supertest": "^2.0.8",
"msw": "^0.29.0",
"msw": "^0.35.0",
"supertest": "^4.0.2",
"xml2js": "^0.4.23"
},
+1 -1
View File
@@ -53,7 +53,7 @@
"@types/node": "^14.14.32",
"@types/recharts": "^1.8.15",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -47,7 +47,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -70,7 +70,7 @@
"@types/yup": "^0.29.13",
"canvas": "^2.6.1",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist",
+1 -1
View File
@@ -41,7 +41,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -59,7 +59,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -45,7 +45,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -59,7 +59,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist",
+1 -1
View File
@@ -53,7 +53,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -51,7 +51,7 @@
"@types/node": "^14.14.32",
"@types/recharts": "^1.8.15",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -62,7 +62,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -49,7 +49,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -54,7 +54,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -55,7 +55,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0",
"msw": "^0.35.0",
"react-router-dom": "6.0.0-beta.0"
},
"files": [
+1 -1
View File
@@ -50,7 +50,7 @@
"@backstage/cli": "^0.8.0",
"@types/supertest": "^2.0.8",
"eslint-plugin-graphql": "^4.0.0",
"msw": "^0.29.0",
"msw": "^0.35.0",
"supertest": "^6.1.3"
},
"files": [
+1 -1
View File
@@ -45,7 +45,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -49,7 +49,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist",
+1 -1
View File
@@ -38,7 +38,7 @@
"@backstage/cli": "^0.8.0",
"@types/jenkins": "^0.23.1",
"@types/supertest": "^2.0.8",
"msw": "^0.29.0",
"msw": "^0.35.0",
"supertest": "^4.0.2"
},
"files": [
+1 -1
View File
@@ -59,7 +59,7 @@
"@types/node": "^14.14.32",
"@types/testing-library__jest-dom": "^5.9.1",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -47,7 +47,7 @@
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"jest-when": "^3.1.0",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -62,7 +62,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -59,7 +59,7 @@
"@types/node": "^14.14.32",
"@types/react": "*",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -53,7 +53,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"
+1 -1
View File
@@ -47,7 +47,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32",
"cross-fetch": "^3.0.6",
"msw": "^0.29.0"
"msw": "^0.35.0"
},
"files": [
"dist"

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