From 9c0d5a607d59d71dfe0bba313d7be5de83c6d125 Mon Sep 17 00:00:00 2001 From: Marley Powell Date: Tue, 19 Oct 2021 10:19:48 +0100 Subject: [PATCH 01/25] refactor(`@backstage/plugin-azure-devops`): Consume re-exported types from `@backstage/plugin-azure-devops-backend`. Signed-off-by: Marley Powell --- plugins/azure-devops/package.json | 2 +- plugins/azure-devops/src/api/types.ts | 2 +- .../src/components/BuildTable/BuildTable.tsx | 33 ++++++++++--------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index c4aea032d2..f9dff7229c 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -31,12 +31,12 @@ "@backstage/core-components": "^0.7.0", "@backstage/core-plugin-api": "^0.1.10", "@backstage/errors": "^0.1.2", + "@backstage/plugin-azure-devops-backend": "^0.1.2", "@backstage/plugin-catalog-react": "^0.6.0", "@backstage/theme": "^0.2.11", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", - "azure-devops-node-api": "^11.0.1", "luxon": "^2.0.2", "react": "^16.13.1", "react-dom": "^16.13.1", diff --git a/plugins/azure-devops/src/api/types.ts b/plugins/azure-devops/src/api/types.ts index 1fbc34231e..46a9212aca 100644 --- a/plugins/azure-devops/src/api/types.ts +++ b/plugins/azure-devops/src/api/types.ts @@ -17,7 +17,7 @@ import { BuildResult, BuildStatus, -} from 'azure-devops-node-api/interfaces/BuildInterfaces'; +} from '@backstage/plugin-azure-devops-backend'; export type RepoBuild = { id?: number; diff --git a/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx b/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx index bead424ffb..72aa2acda7 100644 --- a/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx +++ b/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx @@ -14,26 +14,27 @@ * limitations under the License. */ -import React from 'react'; -import { DateTime } from 'luxon'; -import { - Link, - Table, - TableColumn, - StatusError, - StatusOK, - StatusWarning, - StatusAborted, - StatusRunning, - StatusPending, - ResponseErrorPanel, -} from '@backstage/core-components'; import { Box, Typography } from '@material-ui/core'; -import { RepoBuild } from '../../api/types'; import { BuildResult, BuildStatus, -} from 'azure-devops-node-api/interfaces/BuildInterfaces'; +} from '@backstage/plugin-azure-devops-backend'; +import { + Link, + ResponseErrorPanel, + StatusAborted, + StatusError, + StatusOK, + StatusPending, + StatusRunning, + StatusWarning, + Table, + TableColumn, +} from '@backstage/core-components'; + +import { DateTime } from 'luxon'; +import React from 'react'; +import { RepoBuild } from '../../api/types'; const getBuildResultComponent = (result: number | undefined) => { switch (result) { From b85acc8c3539777d73501ec922e65bbf8dbadfe3 Mon Sep 17 00:00:00 2001 From: Marley Powell Date: Tue, 19 Oct 2021 10:21:21 +0100 Subject: [PATCH 02/25] chore: Created changeset. Signed-off-by: Marley Powell --- .changeset/many-mayflies-notice.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/many-mayflies-notice.md diff --git a/.changeset/many-mayflies-notice.md b/.changeset/many-mayflies-notice.md new file mode 100644 index 0000000000..db058b909a --- /dev/null +++ b/.changeset/many-mayflies-notice.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-azure-devops': minor +--- + +refactor(`@backstage/plugin-azure-devops`): Consume re-exported types from `@backstage/plugin-azure-devops-backend`. From b23f048545e442ef8ddcf7bda230cca7048f3ff0 Mon Sep 17 00:00:00 2001 From: Marley Powell Date: Thu, 21 Oct 2021 13:09:57 +0100 Subject: [PATCH 03/25] chore: Updated changeset Signed-off-by: Marley Powell --- .changeset/many-mayflies-notice.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/many-mayflies-notice.md b/.changeset/many-mayflies-notice.md index db058b909a..b8d551f4fb 100644 --- a/.changeset/many-mayflies-notice.md +++ b/.changeset/many-mayflies-notice.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-azure-devops': minor +'@backstage/plugin-azure-devops': patch --- refactor(`@backstage/plugin-azure-devops`): Consume re-exported types from `@backstage/plugin-azure-devops-backend`. From 39e92897e4de9ff3c89276ebeda138241f8f0bae Mon Sep 17 00:00:00 2001 From: alexcurtin Date: Thu, 28 Oct 2021 12:14:45 -0700 Subject: [PATCH 04/25] Adding API documentation for catalog-client Signed-off-by: alexcurtin --- .changeset/mean-cars-wash.md | 5 + packages/catalog-client/api-report.md | 40 ++---- packages/catalog-client/src/CatalogClient.ts | 100 +++++++++++++- packages/catalog-client/src/types/api.ts | 133 +++++++++++++++++-- 4 files changed, 237 insertions(+), 41 deletions(-) create mode 100644 .changeset/mean-cars-wash.md diff --git a/.changeset/mean-cars-wash.md b/.changeset/mean-cars-wash.md new file mode 100644 index 0000000000..187f5d7e21 --- /dev/null +++ b/.changeset/mean-cars-wash.md @@ -0,0 +1,5 @@ +--- +'@backstage/catalog-client': patch +--- + +Improved API documentation for catalog-client. diff --git a/packages/catalog-client/api-report.md b/packages/catalog-client/api-report.md index b7bb713957..e16ca740f6 100644 --- a/packages/catalog-client/api-report.md +++ b/packages/catalog-client/api-report.md @@ -7,7 +7,7 @@ import { Entity } from '@backstage/catalog-model'; import { EntityName } from '@backstage/catalog-model'; import { Location as Location_2 } from '@backstage/catalog-model'; -// @public (undocumented) +// @public export type AddLocationRequest = { type?: string; target: string; @@ -15,126 +15,106 @@ export type AddLocationRequest = { presence?: 'optional' | 'required'; }; -// @public (undocumented) +// @public export type AddLocationResponse = { location: Location_2; entities: Entity[]; exists?: boolean; }; -// @public (undocumented) +// @public export const CATALOG_FILTER_EXISTS: unique symbol; -// @public (undocumented) +// @public export interface CatalogApi { - // (undocumented) addLocation( location: AddLocationRequest, options?: CatalogRequestOptions, ): Promise; - // (undocumented) getEntities( request?: CatalogEntitiesRequest, options?: CatalogRequestOptions, ): Promise>; - // (undocumented) getEntityAncestors( request: CatalogEntityAncestorsRequest, options?: CatalogRequestOptions, ): Promise; - // (undocumented) getEntityByName( name: EntityName, options?: CatalogRequestOptions, ): Promise; - // (undocumented) getLocationByEntity( entity: Entity, options?: CatalogRequestOptions, ): Promise; - // (undocumented) getLocationById( id: string, options?: CatalogRequestOptions, ): Promise; - // (undocumented) getOriginLocationByEntity( entity: Entity, options?: CatalogRequestOptions, ): Promise; - // (undocumented) refreshEntity( entityRef: string, options?: CatalogRequestOptions, ): Promise; - // (undocumented) removeEntityByUid( uid: string, options?: CatalogRequestOptions, ): Promise; - // (undocumented) removeLocationById( id: string, options?: CatalogRequestOptions, ): Promise; } -// @public (undocumented) +// @public export class CatalogClient implements CatalogApi { constructor(options: { discoveryApi: DiscoveryApi }); - // (undocumented) addLocation( { type, target, dryRun, presence }: AddLocationRequest, options?: CatalogRequestOptions, ): Promise; - // (undocumented) getEntities( request?: CatalogEntitiesRequest, options?: CatalogRequestOptions, ): Promise>; - // (undocumented) getEntityAncestors( request: CatalogEntityAncestorsRequest, options?: CatalogRequestOptions, ): Promise; - // (undocumented) getEntityByName( compoundName: EntityName, options?: CatalogRequestOptions, ): Promise; - // (undocumented) getLocationByEntity( entity: Entity, options?: CatalogRequestOptions, ): Promise; - // (undocumented) getLocationById( id: string, options?: CatalogRequestOptions, ): Promise; - // (undocumented) getOriginLocationByEntity( entity: Entity, options?: CatalogRequestOptions, ): Promise; - // (undocumented) refreshEntity( entityRef: string, options?: CatalogRequestOptions, ): Promise; - // (undocumented) removeEntityByUid( uid: string, options?: CatalogRequestOptions, ): Promise; - // (undocumented) removeLocationById( id: string, options?: CatalogRequestOptions, ): Promise; } -// @public (undocumented) +// @public export type CatalogEntitiesRequest = { filter?: | Record[] @@ -143,12 +123,12 @@ export type CatalogEntitiesRequest = { fields?: string[] | undefined; }; -// @public (undocumented) +// @public export type CatalogEntityAncestorsRequest = { entityRef: string; }; -// @public (undocumented) +// @public export type CatalogEntityAncestorsResponse = { root: EntityName; items: { @@ -157,12 +137,12 @@ export type CatalogEntityAncestorsResponse = { }[]; }; -// @public (undocumented) +// @public export type CatalogListResponse = { items: T[]; }; -// @public (undocumented) +// @public export type CatalogRequestOptions = { token?: string; }; diff --git a/packages/catalog-client/src/CatalogClient.ts b/packages/catalog-client/src/CatalogClient.ts index 75944467d8..29d01fbe5c 100644 --- a/packages/catalog-client/src/CatalogClient.ts +++ b/packages/catalog-client/src/CatalogClient.ts @@ -39,7 +39,11 @@ import { } from './types/api'; import { DiscoveryApi } from './types/discovery'; -/** @public */ +/** + * A frontend and backend compatible client for communicating with the Backstage Catalog. + * + * @public + * */ export class CatalogClient implements CatalogApi { private readonly discoveryApi: DiscoveryApi; @@ -47,6 +51,16 @@ export class CatalogClient implements CatalogApi { this.discoveryApi = options.discoveryApi; } + /** + * Gets the Ancestors of an Entity. + * + * @param request - A request type for retrieving Entity ancestors. + * @param options - An object with your preferred options. + * + * @returns A CatalogEntityAncestorsResponse. + * + * @public + */ async getEntityAncestors( request: CatalogEntityAncestorsRequest, options?: CatalogRequestOptions, @@ -61,6 +75,16 @@ export class CatalogClient implements CatalogApi { ); } + /** + * Gets a Location by Id. + * + * @param id - A string containing the Id. + * @param options - An object with your preferred options. + * + * @returns A {@link catalog-model#Location_2}. + * + * @public + */ async getLocationById( id: string, options?: CatalogRequestOptions, @@ -72,6 +96,16 @@ export class CatalogClient implements CatalogApi { ); } + /** + * Gets a set of Entities. + * + * @param request - A request type for retrieving an Entity. + * @param options - An object with your preferred options. + * + * @returns A CatalogListResponse. + * + * @public + */ async getEntities( request?: CatalogEntitiesRequest, options?: CatalogRequestOptions, @@ -139,6 +173,16 @@ export class CatalogClient implements CatalogApi { return { items: entities.sort(refCompare) }; } + /** + * Gets a given Entity based on a provided name. + * + * @param compoundName - A string containing the name. + * @param options - An object with your preferred options. + * + * @returns An {@link catalog-model#Entity}. + * + * @public + */ async getEntityByName( compoundName: EntityName, options?: CatalogRequestOptions, @@ -153,6 +197,14 @@ export class CatalogClient implements CatalogApi { ); } + /** + * Refreshes an Entity. + * + * @param entityRef - A string containing the entityREf + * @param options - An object with your preferred options. + * + * @public + */ async refreshEntity(entityRef: string, options?: CatalogRequestOptions) { const response = await fetch( `${await this.discoveryApi.getBaseUrl('catalog')}/refresh`, @@ -171,6 +223,16 @@ export class CatalogClient implements CatalogApi { } } + /** + * Adds a location. + * + * @param options - An object with your preferred options. + * @param AddLocationRequest - A request object for adding locations. + * + * @returns An AddLocationResponse + * + * @public + */ async addLocation( { type = 'url', target, dryRun, presence }: AddLocationRequest, options?: CatalogRequestOptions, @@ -206,6 +268,16 @@ export class CatalogClient implements CatalogApi { }; } + /** + * Gets an origin Location By Entity. + * + * @param entity - An Entity + * @param options - An object with your preferred options. + * + * @returns A {@link catalog-model#Location_2}. + * + * @public + */ async getOriginLocationByEntity( entity: Entity, options?: CatalogRequestOptions, @@ -225,6 +297,16 @@ export class CatalogClient implements CatalogApi { .find(l => locationCompound === stringifyLocationReference(l)); } + /** + * Gets a Location by Entity. + * + * @param entity - An Entity + * @param options - An object with your preferred options. + * + * @returns A {@link catalog-model#Location_2}. + * + * @public + */ async getLocationByEntity( entity: Entity, options?: CatalogRequestOptions, @@ -243,6 +325,14 @@ export class CatalogClient implements CatalogApi { .find(l => locationCompound === stringifyLocationReference(l)); } + /** + * Removes a location as identified by Id. + * + * @param id - A string containing the Id + * @param options - An object with your preferred options. + * + * @public + */ async removeLocationById( id: string, options?: CatalogRequestOptions, @@ -254,6 +344,14 @@ export class CatalogClient implements CatalogApi { ); } + /** + * Removes an Entity as identified by Uid. + * + * @param uid - A string containing the Uid + * @param options - An object with your preferred options. + * + * @public + */ async removeEntityByUid( uid: string, options?: CatalogRequestOptions, diff --git a/packages/catalog-client/src/types/api.ts b/packages/catalog-client/src/types/api.ts index c7025e9452..6344caff7c 100644 --- a/packages/catalog-client/src/types/api.ts +++ b/packages/catalog-client/src/types/api.ts @@ -16,10 +16,18 @@ import { Entity, EntityName, Location } from '@backstage/catalog-model'; -/** @public */ +/** + * A Symbol to define if a catalog filter exists or not. + * + * @public + */ export const CATALOG_FILTER_EXISTS = Symbol('CATALOG_FILTER_EXISTS'); -/** @public */ +/** + * A request type for retrieving catalog Entities. + * + * @public + */ export type CatalogEntitiesRequest = { filter?: | Record[] @@ -28,75 +36,176 @@ export type CatalogEntitiesRequest = { fields?: string[] | undefined; }; -/** @public */ +/** + * A request type for Catalog Entity Ancestor information. + * + * @public + */ export type CatalogEntityAncestorsRequest = { entityRef: string; }; -/** @public */ +/** + * A response type for Catalog Entity Ancestor information. + * + * @public + */ export type CatalogEntityAncestorsResponse = { root: EntityName; items: { entity: Entity; parents: EntityName[] }[]; }; -/** @public */ +/** + * A response type for the result of a catalog operation in list form. + * + * @public + */ export type CatalogListResponse = { items: T[]; }; -/** @public */ +/** + * Options you can pass into a catalog request for additional information. + * + * @public + */ export type CatalogRequestOptions = { token?: string; }; -/** @public */ +/** + * Public functions for interacting with the Catalog API. + * + * @public + */ export interface CatalogApi { - // Entities + /** + * Gets the Entities from the catalog based on your request and options. + * + * @param request - An object with your filters and fields. + * @param options - An object with your preferred options. + * + * @returns A CatalogListResponse with items typed Catalog Model Entity. + * + */ getEntities( request?: CatalogEntitiesRequest, options?: CatalogRequestOptions, ): Promise>; + /** + * Gets the Entity ancestor information from the catalog based on your request and options. + * + * @param request - An object with your filters and fields. + * @param options - An object with your preferred options. + * + * @returns A CatalogEntityAncestorsResponse. + */ getEntityAncestors( request: CatalogEntityAncestorsRequest, options?: CatalogRequestOptions, ): Promise; + /** + * Gets a single Entity from the catalog by Entity name. + * + * @param name - A complete Entity name, with the full kind-namespace-name triplet. + * @param options - An object with your preferred options. + * + * @returns A {@link catalog-model#Entity}. + */ getEntityByName( name: EntityName, options?: CatalogRequestOptions, ): Promise; + /** + * Removes a single Entity from the catalog by Entity UID. + * + * @param uid - A string of the Entity UID. + * @param options - An object with your preferred options. + * + */ removeEntityByUid( uid: string, options?: CatalogRequestOptions, ): Promise; + /** + * Refreshes an Entity in the catalog. + * + * @param entityRef - A string in the form of 'Kind/default:foo'. + * @param options - An object with your preferred options. + * + */ refreshEntity( entityRef: string, options?: CatalogRequestOptions, ): Promise; // Locations + /** + * Gets a Location object by ID from the catalog. + * + * @param id - A string in of the Location Id. + * @param options - An object with your preferred options. + * + * @returns A {@link catalog-model#Location_2}. + */ getLocationById( id: string, options?: CatalogRequestOptions, ): Promise; + /** + * Gets origin location by Entity. + * + * @param entity - An {@link catalog-model#Entity}. + * @param options - An object with your preferred options. + * + * @returns A {@link catalog-model#Location_2}. + */ getOriginLocationByEntity( entity: Entity, options?: CatalogRequestOptions, ): Promise; + /** + * Gets Location by Entity. + * + * @param entity - An {@link catalog-model#Entity}. + * @param options - An object with your preferred options. + * + * @returns A {@link catalog-model#Location_2}. + */ getLocationByEntity( entity: Entity, options?: CatalogRequestOptions, ): Promise; + /** + * Adds a Location. + * + * @param location - A request type for adding a Location to the catalog. + * @param options - An object with your preferred options. + * + * @returns A AddLocationResponse. + */ addLocation( location: AddLocationRequest, options?: CatalogRequestOptions, ): Promise; + /** + * Removes a Location by Id. + * + * @param id - A string in of the Location Id. + * @param options - An object with your preferred options. + * + */ removeLocationById( id: string, options?: CatalogRequestOptions, ): Promise; } -/** @public */ +/** + * A request type for adding a Location to the catalog. + * + * @public + */ export type AddLocationRequest = { type?: string; target: string; @@ -104,7 +213,11 @@ export type AddLocationRequest = { presence?: 'optional' | 'required'; }; -/** @public */ +/** + * A response type for adding a Location to the catalog. + * + * @public + */ export type AddLocationResponse = { location: Location; entities: Entity[]; From 83e462c0be0c43179cfb17e07b8361b5cbce5909 Mon Sep 17 00:00:00 2001 From: Kenneth Feng Date: Thu, 28 Oct 2021 21:39:43 -0400 Subject: [PATCH 05/25] plugins/scaffolder-backend: Fix a bug where only file mode 775 is considered executable. Due to the default umask 002 on Ubuntu, the executable files checked out by Git have file mode 100775 (33277), which by mistake, was assumed to be the only possible file mode produced by Git. This bug was introduced in https://github.com/backstage/backstage/pull/7738. There are other possible file modes, such as 100700, 100755, which should be considered executable. This behavior is consistent with how Git behaves. Git only tracks whether a file is executable. This pull request considers a file to be executable as long as there is an execute bit in owner, group, or everyone. Signed-off-by: Kenneth Feng --- .../builtin/publish/githubPullRequest.test.ts | 80 +++++++++++++++++-- .../builtin/publish/githubPullRequest.ts | 7 +- .../actions/builtin/publish/util.test.ts | 32 +++++++- .../actions/builtin/publish/util.ts | 5 ++ 4 files changed, 114 insertions(+), 10 deletions(-) diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.test.ts index 27c6f1e59d..0d4deb87e0 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.test.ts @@ -254,7 +254,7 @@ describe('createPublishGithubPullRequestAction', () => { }); }); - describe('with executable file', () => { + describe('with executable file mode 755', () => { let input: GithubPullRequestActionInput; let ctx: ActionContext; @@ -268,9 +268,9 @@ describe('createPublishGithubPullRequestAction', () => { mockFs({ [workspacePath]: { - 'file.txt': mockFs.file({ - content: 'Hello there!', - mode: 33277, // File mode: 100755 + 'hello.sh': mockFs.file({ + content: 'echo Hello there!', + mode: 0o100755, }), }, }); @@ -297,8 +297,76 @@ describe('createPublishGithubPullRequestAction', () => { { commit: 'Create my new app', files: { - 'file.txt': { - content: Buffer.from('Hello there!').toString('base64'), + 'hello.sh': { + content: Buffer.from('echo Hello there!').toString('base64'), + encoding: 'base64', + mode: '100755', + }, + }, + }, + ], + }); + }); + + it('creates outputs for the url', async () => { + await instance.handler(ctx); + + expect(ctx.output).toHaveBeenCalledWith( + 'remoteUrl', + 'https://github.com/myorg/myrepo/pull/123', + ); + }); + afterEach(() => { + mockFs.restore(); + jest.resetAllMocks(); + }); + }); + + describe('with executable file mode 775', () => { + let input: GithubPullRequestActionInput; + let ctx: ActionContext; + + beforeEach(() => { + input = { + repoUrl: 'github.com?owner=myorg&repo=myrepo', + title: 'Create my new app', + branchName: 'new-app', + description: 'This PR is really good', + }; + + mockFs({ + [workspacePath]: { + 'hello.sh': mockFs.file({ + content: 'echo Hello there!', + mode: 0o100775, + }), + }, + }); + + ctx = { + createTemporaryDirectory: jest.fn(), + output: jest.fn(), + logger: getRootLogger(), + logStream: new Writable(), + input, + workspacePath, + }; + }); + it('creates a pull request', async () => { + await instance.handler(ctx); + + expect(fakeClient.createPullRequest).toHaveBeenCalledWith({ + owner: 'myorg', + repo: 'myrepo', + title: 'Create my new app', + head: 'new-app', + body: 'This PR is really good', + changes: [ + { + commit: 'Create my new app', + files: { + 'hello.sh': { + content: Buffer.from('echo Hello there!').toString('base64'), encoding: 'base64', mode: '100755', }, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts index e147f49b23..0cceb47d71 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts @@ -16,7 +16,7 @@ import fs from 'fs-extra'; import path from 'path'; -import { parseRepoUrl } from './util'; +import { parseRepoUrl, isExecutable } from './util'; import { GithubCredentialsProvider, @@ -202,10 +202,11 @@ export const createPublishGithubPullRequestAction = ({ .readFileSync(absPath) .toString('base64'); const fileStat = fs.statSync(absPath); - const isExecutable = fileStat.mode === 33277; // aka. 100755 // See the properties of tree items // in https://docs.github.com/en/rest/reference/git#trees - const githubTreeItemMode = isExecutable ? '100755' : '100644'; + const githubTreeItemMode = isExecutable(fileStat.mode) + ? '100755' + : '100644'; // Always use base64 encoding to avoid doubling a binary file in size // due to interpreting a binary file as utf-8 and sending github // the utf-8 encoded content. diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.test.ts index f179289624..cc879d4f55 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.test.ts @@ -15,7 +15,7 @@ */ import path from 'path'; -import { getRepoSourceDirectory } from './util'; +import { getRepoSourceDirectory, isExecutable } from './util'; describe('getRepoSourceDirectory', () => { it('should return workspace root if no sub folder is given', () => { @@ -55,3 +55,33 @@ describe('getRepoSourceDirectory', () => { ).toEqual(path.join('/', 'var', 'workspace', 'absolute', 'secret')); }); }); + +describe('isExecutable', () => { + it('should return true for file mode 777', () => { + expect(isExecutable(0o100777)).toBe(true); + }); + it('should return true for file mode 775', () => { + expect(isExecutable(0o100775)).toBe(true); + }); + it('should return true for file mode 755', () => { + expect(isExecutable(0o100755)).toBe(true); + }); + it('should return true for file mode 700', () => { + expect(isExecutable(0o100700)).toBe(true); + }); + it('should return true for file mode 770', () => { + expect(isExecutable(0o100770)).toBe(true); + }); + it('should return true for file mode 670', () => { + expect(isExecutable(0o100670)).toBe(true); + }); + it('should return false for file mode 644', () => { + expect(isExecutable(0o100644)).toBe(false); + }); + it('should return false for file mode 600', () => { + expect(isExecutable(0o100600)).toBe(false); + }); + it('should return false for file mode 640', () => { + expect(isExecutable(0o100640)).toBe(false); + }); +}); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.ts index 58ba5bfdd1..49156e7d97 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/util.ts @@ -101,3 +101,8 @@ export const parseRepoUrl = ( return { host, owner, repo, organization, workspace, project }; }; +export const isExecutable = (fileMode: number) => { + const executeBitMask = 0o000111; + const res = fileMode & executeBitMask; + return res > 0; +}; From a794c341ca7f9207affccd06d75f7d530fa27c30 Mon Sep 17 00:00:00 2001 From: Kenneth Feng Date: Thu, 28 Oct 2021 22:20:34 -0400 Subject: [PATCH 06/25] add changeset Signed-off-by: Kenneth Feng --- .changeset/wet-pears-thank.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/wet-pears-thank.md diff --git a/.changeset/wet-pears-thank.md b/.changeset/wet-pears-thank.md new file mode 100644 index 0000000000..f9b5576fb3 --- /dev/null +++ b/.changeset/wet-pears-thank.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Fix a bug where only file mode 775 is considered an executable From 8b4284cd5cb1bf071a07d3247e529e12787fbde7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jarek=20=C5=81ukow?= Date: Mon, 1 Nov 2021 10:16:54 +0100 Subject: [PATCH 07/25] Improve API documentation for @backstage/core-plugin-api MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jarek Łukow --- .changeset/tender-chefs-approve.md | 6 + packages/core-app-api/api-report.md | 7 +- packages/core-plugin-api/api-report.md | 476 ++++++------------ .../src/analytics/AnalyticsContext.tsx | 8 +- .../core-plugin-api/src/analytics/types.ts | 8 +- .../src/analytics/useAnalytics.tsx | 4 +- .../src/apis/definitions/AlertApi.ts | 13 +- .../src/apis/definitions/AnalyticsApi.ts | 15 + .../src/apis/definitions/AppThemeApi.ts | 9 + .../src/apis/definitions/ConfigApi.ts | 7 + .../src/apis/definitions/DiscoveryApi.ts | 9 + .../src/apis/definitions/ErrorApi.ts | 15 +- .../src/apis/definitions/FeatureFlagsApi.ts | 49 +- .../src/apis/definitions/IdentityApi.ts | 7 + .../src/apis/definitions/OAuthRequestApi.ts | 23 +- .../src/apis/definitions/StorageApi.ts | 30 +- .../src/apis/definitions/auth.ts | 111 +++- .../core-plugin-api/src/apis/system/ApiRef.ts | 12 + .../src/apis/system/helpers.ts | 27 +- .../core-plugin-api/src/apis/system/index.ts | 1 + .../core-plugin-api/src/apis/system/types.ts | 42 ++ .../src/apis/system/useApi.tsx | 17 + packages/core-plugin-api/src/app/types.ts | 30 ++ packages/core-plugin-api/src/app/useApp.tsx | 5 + .../core-plugin-api/src/deprecatedTypes.ts | 3 +- .../src/extensions/componentData.tsx | 24 + .../src/extensions/extensions.tsx | 55 +- .../core-plugin-api/src/extensions/index.ts | 1 + .../src/extensions/useElementFilter.tsx | 18 +- packages/core-plugin-api/src/icons/index.ts | 2 +- packages/core-plugin-api/src/icons/types.ts | 6 + .../core-plugin-api/src/plugin/Plugin.tsx | 9 + packages/core-plugin-api/src/plugin/index.ts | 2 + packages/core-plugin-api/src/plugin/types.ts | 60 ++- .../src/routing/ExternalRouteRef.ts | 13 + .../core-plugin-api/src/routing/RouteRef.ts | 13 + .../src/routing/SubRouteRef.ts | 47 +- packages/core-plugin-api/src/routing/index.ts | 17 +- packages/core-plugin-api/src/routing/types.ts | 99 +++- .../src/routing/useRouteRef.tsx | 38 ++ .../src/routing/useRouteRefParams.ts | 5 + 41 files changed, 939 insertions(+), 404 deletions(-) create mode 100644 .changeset/tender-chefs-approve.md diff --git a/.changeset/tender-chefs-approve.md b/.changeset/tender-chefs-approve.md new file mode 100644 index 0000000000..1cc618507c --- /dev/null +++ b/.changeset/tender-chefs-approve.md @@ -0,0 +1,6 @@ +--- +'@backstage/core-app-api': patch +'@backstage/core-plugin-api': patch +--- + +Improve API documentation for @backstage/core-plugin-api diff --git a/packages/core-app-api/api-report.md b/packages/core-app-api/api-report.md index 09d3313c84..8fb3d5c788 100644 --- a/packages/core-app-api/api-report.md +++ b/packages/core-app-api/api-report.md @@ -28,6 +28,7 @@ import { bitbucketAuthApiRef } from '@backstage/core-plugin-api'; import { ComponentType } from 'react'; import { ConfigReader } from '@backstage/config'; import { DiscoveryApi } from '@backstage/core-plugin-api'; +import { Error as Error_2 } from '@backstage/core-plugin-api'; import { ErrorApi } from '@backstage/core-plugin-api'; import { ErrorContext } from '@backstage/core-plugin-api'; import { ExternalRouteRef } from '@backstage/core-plugin-api'; @@ -298,11 +299,7 @@ export class ErrorAlerter implements ErrorApi { constructor(alertApi: AlertApi, errorApi: ErrorApi); // (undocumented) error$(): Observable<{ - error: { - name: string; - message: string; - stack?: string | undefined; - }; + error: Error_2; context?: ErrorContext | undefined; }>; // (undocumented) diff --git a/packages/core-plugin-api/api-report.md b/packages/core-plugin-api/api-report.md index 88afc0e8e6..3225c1a28f 100644 --- a/packages/core-plugin-api/api-report.md +++ b/packages/core-plugin-api/api-report.md @@ -16,41 +16,29 @@ import { ReactNode } from 'react'; import { Subscription as Subscription_2 } from '@backstage/types'; import { SvgIconProps } from '@material-ui/core'; -// Warning: (ae-missing-release-tag) "AlertApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type AlertApi = { post(alert: AlertMessage): void; alert$(): Observable_2; }; -// Warning: (ae-missing-release-tag) "alertApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const alertApiRef: ApiRef; -// Warning: (ae-missing-release-tag) "AlertMessage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type AlertMessage = { message: string; severity?: 'success' | 'info' | 'warning' | 'error'; }; -// Warning: (ae-missing-release-tag) "AnalyticsApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type AnalyticsApi = { captureEvent(event: AnalyticsEvent): void; }; -// Warning: (ae-missing-release-tag) "analyticsApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const analyticsApiRef: ApiRef; -// Warning: (ae-missing-release-tag) "AnalyticsContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const AnalyticsContext: ({ attributes, @@ -60,14 +48,10 @@ export const AnalyticsContext: ({ children: ReactNode; }) => JSX.Element; -// Warning: (ae-missing-release-tag) "AnalyticsContextValue" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type AnalyticsContextValue = CommonAnalyticsContext & AnyAnalyticsContext; -// Warning: (ae-missing-release-tag) "AnalyticsEvent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type AnalyticsEvent = { action: string; @@ -77,15 +61,11 @@ export type AnalyticsEvent = { context: AnalyticsContextValue; }; -// Warning: (ae-missing-release-tag) "AnalyticsEventAttributes" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type AnalyticsEventAttributes = { [attribute in string]: string | boolean | number; }; -// Warning: (ae-missing-release-tag) "AnalyticsTracker" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type AnalyticsTracker = { captureEvent: ( @@ -98,16 +78,12 @@ export type AnalyticsTracker = { ) => void; }; -// Warning: (ae-missing-release-tag) "AnyAnalyticsContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type AnyAnalyticsContext = { [param in string]: string | boolean | number | undefined; }; -// Warning: (ae-missing-release-tag) "AnyApiFactory" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type AnyApiFactory = ApiFactory< unknown, unknown, @@ -116,14 +92,27 @@ export type AnyApiFactory = ApiFactory< } >; -// Warning: (ae-missing-release-tag) "AnyApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type AnyApiRef = ApiRef; -// Warning: (ae-missing-release-tag) "ApiFactory" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export type AnyExternalRoutes = { + [name: string]: ExternalRouteRef; +}; + +// @public +export type AnyParams = + | { + [param in string]: string; + } + | undefined; + +// @public +export type AnyRoutes = { + [name: string]: RouteRef | SubRouteRef; +}; + +// @public export type ApiFactory< Api, Impl extends Api, @@ -136,24 +125,24 @@ export type ApiFactory< factory(deps: Deps): Impl; }; -// Warning: (ae-missing-release-tag) "ApiHolder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type ApiHolder = { get(api: ApiRef): T | undefined; }; -// Warning: (ae-missing-release-tag) "ApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type ApiRef = { id: string; T: T; }; -// Warning: (ae-missing-release-tag) "ApiRefsToTypes" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export type ApiRefConfig = { + id: string; + description?: string; +}; + +// @public export type ApiRefsToTypes< T extends { [key in string]: ApiRef; @@ -162,14 +151,10 @@ export type ApiRefsToTypes< [key in keyof T]: ApiRefType; }; -// Warning: (ae-missing-release-tag) "ApiRefType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type ApiRefType = T extends ApiRef ? U : never; -// 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; @@ -179,17 +164,13 @@ export type AppComponents = { SignInPage?: ComponentType; }; -// 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[]; getSystemIcon(key: string): IconComponent | undefined; getComponents(): AppComponents; }; -// Warning: (ae-missing-release-tag) "AppTheme" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type AppTheme = { id: string; @@ -199,8 +180,6 @@ export type AppTheme = { icon?: React.ReactElement; }; -// Warning: (ae-missing-release-tag) "AppThemeApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type AppThemeApi = { getInstalledThemes(): AppTheme[]; @@ -209,77 +188,56 @@ export type AppThemeApi = { setActiveThemeId(themeId?: string): void; }; -// Warning: (ae-missing-release-tag) "appThemeApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const appThemeApiRef: ApiRef; -// Warning: (ae-missing-release-tag) "atlassianAuthApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const atlassianAuthApiRef: ApiRef< OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi >; -// Warning: (ae-missing-release-tag) "attachComponentData" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function attachComponentData

( component: ComponentType

, type: string, data: unknown, ): void; -// Warning: (ae-missing-release-tag) "auth0AuthApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const auth0AuthApiRef: ApiRef< OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi >; -// Warning: (ae-missing-release-tag) "AuthProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type AuthProvider = { title: string; icon: IconComponent; }; -// Warning: (ae-missing-release-tag) "AuthRequester" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type AuthRequester = ( scopes: Set, ) => Promise; -// Warning: (ae-missing-release-tag) "AuthRequesterOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type AuthRequesterOptions = { provider: AuthProvider; onAuthRequest(scopes: Set): Promise; }; -// Warning: (ae-missing-release-tag) "AuthRequestOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type AuthRequestOptions = { optional?: boolean; instantPopup?: boolean; }; -// Warning: (ae-missing-release-tag) "BackstageIdentity" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type BackstageIdentity = { id: string; idToken: string; token: string; }; -// Warning: (tsdoc-undefined-tag) The TSDoc tag "@IdentityApi" is not defined in this configuration -// Warning: (ae-missing-release-tag) "BackstageIdentityApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type BackstageIdentityApi = { getBackstageIdentity( @@ -287,11 +245,7 @@ export type BackstageIdentityApi = { ): Promise; }; -// Warning: (ae-forgotten-export) The symbol "AnyRoutes" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "AnyExternalRoutes" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "BackstagePlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type BackstagePlugin< Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}, @@ -304,23 +258,17 @@ export type BackstagePlugin< externalRoutes: ExternalRoutes; }; -// Warning: (ae-missing-release-tag) "bitbucketAuthApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const bitbucketAuthApiRef: ApiRef< OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi >; -// 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; }; -// Warning: (ae-missing-release-tag) "CommonAnalyticsContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type CommonAnalyticsContext = { pluginId: string; @@ -328,19 +276,21 @@ export type CommonAnalyticsContext = { extension: string; }; -// Warning: (ae-missing-release-tag) "ConfigApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// +// @public +export type ComponentLoader = + | { + lazy: () => Promise; + } + | { + sync: T; + }; + // @public export type ConfigApi = Config; -// Warning: (ae-missing-release-tag) "configApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const configApiRef: ApiRef; -// Warning: (ae-missing-release-tag) "createApiFactory" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-missing-release-tag) "createApiFactory" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function createApiFactory< Api, @@ -350,29 +300,21 @@ export function createApiFactory< }, >(factory: ApiFactory): ApiFactory; -// @public (undocumented) +// @public export function createApiFactory( api: ApiRef, instance: Impl, ): ApiFactory; -// Warning: (ae-forgotten-export) The symbol "ApiRefConfig" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function createApiRef(config: ApiRefConfig): ApiRef; -// Warning: (ae-missing-release-tag) "createComponentExtension" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function createComponentExtension< T extends (props: any) => JSX.Element | null, >(options: { component: ComponentLoader; name?: string }): Extension; -// Warning: (ae-forgotten-export) The symbol "OptionalParams" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createExternalRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function createExternalRouteRef< Params extends { [param in ParamKey]: string; @@ -385,9 +327,7 @@ export function createExternalRouteRef< optional?: Optional; }): ExternalRouteRef, Optional>; -// Warning: (ae-missing-release-tag) "createPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function createPlugin< Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}, @@ -395,9 +335,7 @@ export function createPlugin< config: PluginConfig, ): BackstagePlugin; -// Warning: (ae-missing-release-tag) "createReactExtension" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function createReactExtension< T extends (props: any) => JSX.Element | null, >(options: { @@ -406,9 +344,7 @@ export function createReactExtension< name?: string; }): Extension; -// Warning: (ae-missing-release-tag) "createRoutableExtension" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function createRoutableExtension< T extends (props: any) => JSX.Element | null, >(options: { @@ -417,9 +353,7 @@ export function createRoutableExtension< name?: string; }): Extension; -// Warning: (ae-missing-release-tag) "createRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function createRouteRef< Params extends { [param in ParamKey]: string; @@ -433,12 +367,7 @@ export function createRouteRef< title?: string; }): RouteRef>; -// Warning: (ae-forgotten-export) The symbol "AnyParams" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "MakeSubRouteRef" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "PathParams" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createSubRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function createSubRouteRef< Path extends string, ParentParams extends AnyParams = never, @@ -448,20 +377,14 @@ export function createSubRouteRef< parent: RouteRef; }): MakeSubRouteRef, ParentParams>; -// Warning: (ae-missing-release-tag) "DiscoveryApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type DiscoveryApi = { getBaseUrl(pluginId: string): Promise; }; -// Warning: (ae-missing-release-tag) "discoveryApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const discoveryApiRef: ApiRef; -// Warning: (ae-missing-release-tag) "ElementCollection" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export interface ElementCollection { findComponentData(query: { key: string }): T[]; @@ -476,8 +399,14 @@ export interface ElementCollection { }): ElementCollection; } -// Warning: (ae-missing-release-tag) "ErrorApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// +// @public +type Error_2 = { + name: string; + message: string; + stack?: string; +}; +export { Error_2 as Error }; + // @public export type ErrorApi = { post(error: Error_2, context?: ErrorContext): void; @@ -487,37 +416,27 @@ export type ErrorApi = { }>; }; -// Warning: (ae-missing-release-tag) "errorApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const errorApiRef: ApiRef; -// 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) "ErrorContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type ErrorContext = { hidden?: boolean; }; -// Warning: (ae-missing-release-tag) "Extension" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type Extension = { expose(plugin: BackstagePlugin): T; }; -// Warning: (ae-missing-release-tag) "ExternalRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type ExternalRouteRef< Params extends AnyParams = any, Optional extends boolean = any, @@ -527,25 +446,19 @@ export type ExternalRouteRef< optional?: Optional; }; -// Warning: (ae-missing-release-tag) "FeatureFlag" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type FeatureFlag = { name: string; pluginId: string; }; -// Warning: (ae-missing-release-tag) "FeatureFlagOutput" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type FeatureFlagOutput = { type: 'feature-flag'; name: string; }; -// Warning: (ae-missing-release-tag) "FeatureFlagsApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface FeatureFlagsApi { getRegisteredFlags(): FeatureFlag[]; isActive(name: string): boolean; @@ -553,60 +466,42 @@ export interface FeatureFlagsApi { save(options: FeatureFlagsSaveOptions): void; } -// Warning: (ae-missing-release-tag) "featureFlagsApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const featureFlagsApiRef: ApiRef; -// Warning: (ae-missing-release-tag) "FeatureFlagsHooks" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type FeatureFlagsHooks = { register(name: string): void; }; -// Warning: (ae-missing-release-tag) "FeatureFlagsSaveOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type FeatureFlagsSaveOptions = { states: Record; merge?: boolean; }; -// Warning: (ae-missing-release-tag) "FeatureFlagState" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export enum FeatureFlagState { - // (undocumented) Active = 1, - // (undocumented) None = 0, } -// Warning: (ae-missing-release-tag) "getComponentData" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function getComponentData( node: ReactNode, type: string, ): T | undefined; -// Warning: (ae-missing-release-tag) "githubAuthApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const githubAuthApiRef: ApiRef< OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi >; -// Warning: (ae-missing-release-tag) "gitlabAuthApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const gitlabAuthApiRef: ApiRef< OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi >; -// Warning: (ae-missing-release-tag) "googleAuthApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const googleAuthApiRef: ApiRef< OAuthApi & @@ -616,15 +511,11 @@ export const googleAuthApiRef: ApiRef< SessionApi >; -// Warning: (ae-missing-release-tag) "IconComponent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type IconComponent = ComponentType<{ fontSize?: 'default' | 'small' | 'large'; }>; -// Warning: (ae-missing-release-tag) "IdentityApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type IdentityApi = { getUserId(): string; @@ -633,13 +524,27 @@ export type IdentityApi = { signOut(): Promise; }; -// Warning: (ae-missing-release-tag) "identityApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const identityApiRef: ApiRef; -// Warning: (ae-missing-release-tag) "microsoftAuthApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// +// @public +export type MakeSubRouteRef< + Params extends { + [param in string]: string; + }, + ParentParams extends AnyParams, +> = keyof Params & keyof ParentParams extends never + ? SubRouteRef>> + : never; + +// @public +export type MergeParams< + P1 extends { + [param in string]: string; + }, + P2 extends AnyParams, +> = (P1[keyof P1] extends never ? {} : P1) & (P2 extends undefined ? {} : P2); + // @public export const microsoftAuthApiRef: ApiRef< OAuthApi & @@ -649,8 +554,6 @@ export const microsoftAuthApiRef: ApiRef< SessionApi >; -// Warning: (ae-missing-release-tag) "oauth2ApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const oauth2ApiRef: ApiRef< OAuthApi & @@ -660,8 +563,6 @@ export const oauth2ApiRef: ApiRef< SessionApi >; -// Warning: (ae-missing-release-tag) "OAuthApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type OAuthApi = { getAccessToken( @@ -670,8 +571,6 @@ export type OAuthApi = { ): Promise; }; -// Warning: (ae-missing-release-tag) "OAuthRequestApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type OAuthRequestApi = { createAuthRequester( @@ -680,13 +579,9 @@ export type OAuthRequestApi = { authRequest$(): Observable_2; }; -// Warning: (ae-missing-release-tag) "oauthRequestApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const oauthRequestApiRef: ApiRef; -// Warning: (ae-missing-release-tag) "OAuthScope" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type OAuthScope = string | string[]; @@ -696,8 +591,6 @@ export type Observable = Observable_2; // @public @deprecated export type Observer = Observer_2; -// Warning: (ae-missing-release-tag) "oidcAuthApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const oidcAuthApiRef: ApiRef< OAuthApi & @@ -707,8 +600,6 @@ export const oidcAuthApiRef: ApiRef< SessionApi >; -// Warning: (ae-missing-release-tag) "oktaAuthApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const oktaAuthApiRef: ApiRef< OAuthApi & @@ -718,9 +609,10 @@ export const oktaAuthApiRef: ApiRef< SessionApi >; -// Warning: (ae-missing-release-tag) "oneloginAuthApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export type OldIconComponent = ComponentType; + +// @public export const oneloginAuthApiRef: ApiRef< OAuthApi & OpenIdConnectApi & @@ -729,15 +621,39 @@ export const oneloginAuthApiRef: ApiRef< SessionApi >; -// Warning: (ae-missing-release-tag) "OpenIdConnectApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type OpenIdConnectApi = { getIdToken(options?: AuthRequestOptions): Promise; }; -// Warning: (ae-missing-release-tag) "PendingAuthRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// +// @public +export type OptionalParams< + Params extends { + [param in string]: string; + }, +> = Params[keyof Params] extends never ? undefined : Params; + +// @public +export type ParamKeys = keyof Params extends never + ? [] + : (keyof Params)[]; + +// @public +export type ParamNames = + S extends `${infer Part}/${infer Rest}` + ? ParamPart | ParamNames + : ParamPart; + +// @public +export type ParamPart = S extends `:${infer Param}` + ? Param + : never; + +// @public +export type PathParams = { + [name in ParamNames]: string; +}; + // @public export type PendingAuthRequest = { provider: AuthProvider; @@ -745,9 +661,7 @@ export type PendingAuthRequest = { trigger(): Promise; }; -// Warning: (ae-missing-release-tag) "PluginConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type PluginConfig< Routes extends AnyRoutes, ExternalRoutes extends AnyExternalRoutes, @@ -759,20 +673,14 @@ export type PluginConfig< externalRoutes?: ExternalRoutes; }; -// Warning: (ae-missing-release-tag) "PluginHooks" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type PluginHooks = { featureFlags: FeatureFlagsHooks; }; -// Warning: (ae-missing-release-tag) "PluginOutput" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type PluginOutput = FeatureFlagOutput; -// Warning: (ae-missing-release-tag) "ProfileInfo" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type ProfileInfo = { email?: string; @@ -780,28 +688,25 @@ export type ProfileInfo = { picture?: string; }; -// Warning: (ae-missing-release-tag) "ProfileInfoApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type ProfileInfoApi = { getProfile(options?: AuthRequestOptions): Promise; }; -// Warning: (ae-missing-release-tag) "RouteOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export type RouteFunc = ( + ...[params]: Params extends undefined ? readonly [] : readonly [Params] +) => string; + +// @public export type RouteOptions = { exact?: boolean; }; -// Warning: (ae-missing-release-tag) "RoutePath" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type RoutePath = string; -// Warning: (ae-missing-release-tag) "RouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type RouteRef = { $$routeRefType: 'absolute'; params: ParamKeys; @@ -810,15 +715,11 @@ export type RouteRef = { title?: string; }; -// Warning: (ae-missing-release-tag) "samlAuthApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const samlAuthApiRef: ApiRef< ProfileInfoApi & BackstageIdentityApi & SessionApi >; -// Warning: (ae-missing-release-tag) "SessionApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type SessionApi = { signIn(): Promise; @@ -826,26 +727,18 @@ export type SessionApi = { sessionState$(): Observable_2; }; -// Warning: (ae-missing-release-tag) "SessionState" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export enum SessionState { - // (undocumented) SignedIn = 'SignedIn', - // (undocumented) SignedOut = 'SignedOut', } -// 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; @@ -853,46 +746,25 @@ export type SignInResult = { signOut?: () => Promise; }; -// Warning: (ae-missing-release-tag) "StorageApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface StorageApi { - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen - // Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}' forBucket(name: string): StorageApi; - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen - // Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}' - // 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-undefined-tag) The TSDoc tag "@return" is not defined in this configuration get(key: string): 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-with-invalid-type) The @param block should not include a JSDoc-style '{type}' observe$(key: string): Observable_2>; - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen - // Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}' remove(key: string): Promise; - // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen - // Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}' set(key: string, data: any): Promise; } -// Warning: (ae-missing-release-tag) "storageApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const storageApiRef: ApiRef; -// Warning: (ae-missing-release-tag) "StorageValueChange" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type StorageValueChange = { key: string; newValue?: T; }; -// Warning: (ae-missing-release-tag) "SubRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type SubRouteRef = { $$routeRefType: 'sub'; parent: RouteRef; @@ -903,35 +775,23 @@ export type SubRouteRef = { // @public @deprecated export type Subscription = Subscription_2; -// Warning: (ae-missing-release-tag) "TypesToApiRefs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type TypesToApiRefs = { [key in keyof T]: ApiRef; }; -// Warning: (ae-missing-release-tag) "useAnalytics" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function useAnalytics(): AnalyticsTracker; -// Warning: (ae-missing-release-tag) "useApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function useApi(apiRef: ApiRef): T; -// Warning: (ae-missing-release-tag) "useApiHolder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function useApiHolder(): ApiHolder; -// Warning: (ae-missing-release-tag) "useApp" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const useApp: () => AppContext; -// Warning: (ae-missing-release-tag) "useElementFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function useElementFilter( node: ReactNode, @@ -939,51 +799,29 @@ export function useElementFilter( dependencies?: any[], ): T; -// Warning: (ae-missing-release-tag) "UserFlags" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type UserFlags = {}; -// Warning: (ae-forgotten-export) The symbol "RouteFunc" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "useRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-missing-release-tag) "useRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function useRouteRef( routeRef: ExternalRouteRef, ): Optional extends true ? RouteFunc | undefined : RouteFunc; -// @public (undocumented) +// @public export function useRouteRef( routeRef: RouteRef | SubRouteRef, ): RouteFunc; -// Warning: (ae-missing-release-tag) "useRouteRefParams" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function useRouteRefParams( _routeRef: RouteRef | SubRouteRef, ): Params; -// Warning: (ae-missing-release-tag) "withApis" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function withApis(apis: TypesToApiRefs):

( WrappedComponent: React_2.ComponentType

, ) => { (props: React_2.PropsWithChildren>): JSX.Element; displayName: string; }; - -// Warnings were encountered during analysis: -// -// src/apis/definitions/ErrorApi.d.ts:37:5 - (ae-forgotten-export) The symbol "Error" needs to be exported by the entry point index.d.ts -// src/apis/definitions/auth.d.ts:29:8 - (tsdoc-undefined-tag) The TSDoc tag "@default" is not defined in this configuration -// src/apis/definitions/auth.d.ts:38:8 - (tsdoc-undefined-tag) The TSDoc tag "@default" is not defined in this configuration -// src/apis/definitions/auth.d.ts:96:68 - (tsdoc-undefined-tag) The TSDoc tag "@AuthRequestOptions" is not defined in this configuration -// src/apis/definitions/auth.d.ts:110:16 - (tsdoc-undefined-tag) The TSDoc tag "@IdentityApi" is not defined in this configuration -// src/apis/definitions/auth.d.ts:113:68 - (tsdoc-undefined-tag) The TSDoc tag "@AuthRequestOptions" is not defined in this configuration -// src/extensions/extensions.d.ts:15:5 - (ae-forgotten-export) The symbol "ComponentLoader" needs to be exported by the entry point index.d.ts -// src/routing/RouteRef.d.ts:35:5 - (ae-forgotten-export) The symbol "OldIconComponent" needs to be exported by the entry point index.d.ts -// src/routing/types.d.ts:30:5 - (ae-forgotten-export) The symbol "ParamKeys" needs to be exported by the entry point index.d.ts ``` diff --git a/packages/core-plugin-api/src/analytics/AnalyticsContext.tsx b/packages/core-plugin-api/src/analytics/AnalyticsContext.tsx index adbd9be6f3..bb2141d47f 100644 --- a/packages/core-plugin-api/src/analytics/AnalyticsContext.tsx +++ b/packages/core-plugin-api/src/analytics/AnalyticsContext.tsx @@ -27,7 +27,8 @@ const AnalyticsReactContext = /** * A "private" (to this package) hook that enables context inheritance and a * way to read Analytics Context values at event capture-time. - * @private + * + * @internal */ export const useAnalyticsContext = (): AnalyticsContextValue => { const theContext = useContext(AnalyticsReactContext); @@ -54,8 +55,12 @@ export const useAnalyticsContext = (): AnalyticsContextValue => { * Provides components in the child react tree an Analytics Context, ensuring * all analytics events captured within the context have relevant attributes. * + * @remarks + * * Analytics contexts are additive, meaning the context ultimately emitted with * an event is the combination of all contexts in the parent tree. + * + * @public */ export const AnalyticsContext = ({ attributes, @@ -84,6 +89,7 @@ export const AnalyticsContext = ({ * * @param Component - Component to be wrapped with analytics context attributes * @param values - Analytics context key/value pairs. + * @internal */ export function withAnalyticsContext

( Component: React.ComponentType

, diff --git a/packages/core-plugin-api/src/analytics/types.ts b/packages/core-plugin-api/src/analytics/types.ts index ea6c3b030b..d001c38d3e 100644 --- a/packages/core-plugin-api/src/analytics/types.ts +++ b/packages/core-plugin-api/src/analytics/types.ts @@ -16,6 +16,8 @@ /** * Common analytics context attributes. + * + * @public */ export type CommonAnalyticsContext = { /** @@ -35,7 +37,9 @@ export type CommonAnalyticsContext = { }; /** - * Allow arbitrary scalar values as context attributes too. + * Allows arbitrary scalar values as context attributes too. + * + * @public */ export type AnyAnalyticsContext = { [param in string]: string | boolean | number | undefined; @@ -43,6 +47,8 @@ export type AnyAnalyticsContext = { /** * Analytics context envelope. + * + * @public */ export type AnalyticsContextValue = CommonAnalyticsContext & AnyAnalyticsContext; diff --git a/packages/core-plugin-api/src/analytics/useAnalytics.tsx b/packages/core-plugin-api/src/analytics/useAnalytics.tsx index 02d1ecc3c3..5a047e5a63 100644 --- a/packages/core-plugin-api/src/analytics/useAnalytics.tsx +++ b/packages/core-plugin-api/src/analytics/useAnalytics.tsx @@ -33,7 +33,9 @@ function useAnalyticsApi(): AnalyticsApi { } /** - * Get a pre-configured analytics tracker. + * Gets a pre-configured analytics tracker. + * + * @public */ export function useAnalytics(): AnalyticsTracker { const trackerRef = useRef(null); diff --git a/packages/core-plugin-api/src/apis/definitions/AlertApi.ts b/packages/core-plugin-api/src/apis/definitions/AlertApi.ts index 7110c1d9f8..0c84f7c975 100644 --- a/packages/core-plugin-api/src/apis/definitions/AlertApi.ts +++ b/packages/core-plugin-api/src/apis/definitions/AlertApi.ts @@ -17,6 +17,11 @@ import { createApiRef, ApiRef } from '../system'; import { Observable } from '@backstage/types'; +/** + * Message handled by the {@link AlertApi}. + * + * @public + */ export type AlertMessage = { message: string; // Severity will default to success since that is what material ui defaults the value to. @@ -25,8 +30,9 @@ export type AlertMessage = { /** * The alert API is used to report alerts to the app, and display them to the user. + * + * @public */ - export type AlertApi = { /** * Post an alert for handling by the application. @@ -39,6 +45,11 @@ export type AlertApi = { alert$(): Observable; }; +/** + * The {@link ApiRef} of {@link AlertApi}. + * + * @public + */ export const alertApiRef: ApiRef = createApiRef({ id: 'core.alert', }); diff --git a/packages/core-plugin-api/src/apis/definitions/AnalyticsApi.ts b/packages/core-plugin-api/src/apis/definitions/AnalyticsApi.ts index 43e35607a3..ef190d6c21 100644 --- a/packages/core-plugin-api/src/apis/definitions/AnalyticsApi.ts +++ b/packages/core-plugin-api/src/apis/definitions/AnalyticsApi.ts @@ -20,6 +20,8 @@ import { AnalyticsContextValue } from '../../analytics/types'; /** * Represents an event worth tracking in an analytics system that could inform * how users of a Backstage instance are using its features. + * + * @public */ export type AnalyticsEvent = { /** @@ -76,6 +78,8 @@ export type AnalyticsEvent = { /** * A structure allowing other arbitrary metadata to be provided by analytics * event emitters. + * + * @public */ export type AnalyticsEventAttributes = { [attribute in string]: string | boolean | number; @@ -84,6 +88,8 @@ export type AnalyticsEventAttributes = { /** * Represents a tracker with methods that can be called to track events in a * configured analytics service. + * + * @public */ export type AnalyticsTracker = { captureEvent: ( @@ -99,9 +105,13 @@ export type AnalyticsTracker = { /** * The Analytics API is used to track user behavior in a Backstage instance. * + * @remarks + * * To instrument your App or Plugin, retrieve an analytics tracker using the * useAnalytics() hook. This will return a pre-configured AnalyticsTracker * with relevant methods for instrumentation. + * + * @public */ export type AnalyticsApi = { /** @@ -111,6 +121,11 @@ export type AnalyticsApi = { captureEvent(event: AnalyticsEvent): void; }; +/** + * The {@link ApiRef} of {@link AnalyticsApi}. + * + * @public + */ export const analyticsApiRef: ApiRef = createApiRef({ id: 'core.analytics', }); diff --git a/packages/core-plugin-api/src/apis/definitions/AppThemeApi.ts b/packages/core-plugin-api/src/apis/definitions/AppThemeApi.ts index 5ac16f83fd..de523663f2 100644 --- a/packages/core-plugin-api/src/apis/definitions/AppThemeApi.ts +++ b/packages/core-plugin-api/src/apis/definitions/AppThemeApi.ts @@ -20,6 +20,8 @@ import { Observable } from '@backstage/types'; /** * Describes a theme provided by the app. + * + * @public */ export type AppTheme = { /** @@ -51,6 +53,8 @@ export type AppTheme = { /** * The AppThemeApi gives access to the current app theme, and allows switching * to other options that have been registered as a part of the App. + * + * @public */ export type AppThemeApi = { /** @@ -76,6 +80,11 @@ export type AppThemeApi = { setActiveThemeId(themeId?: string): void; }; +/** + * The {@link ApiRef} of {@link AppThemeApi}. + * + * @public + */ export const appThemeApiRef: ApiRef = createApiRef({ id: 'core.apptheme', }); diff --git a/packages/core-plugin-api/src/apis/definitions/ConfigApi.ts b/packages/core-plugin-api/src/apis/definitions/ConfigApi.ts index 08b9f91f57..d3bada9e46 100644 --- a/packages/core-plugin-api/src/apis/definitions/ConfigApi.ts +++ b/packages/core-plugin-api/src/apis/definitions/ConfigApi.ts @@ -19,9 +19,16 @@ import { Config } from '@backstage/config'; /** * The Config API is used to provide a mechanism to access the * runtime configuration of the system. + * + * @public */ export type ConfigApi = Config; +/** + * The {@link ApiRef} of {@link ConfigApi}. + * + * @public + */ export const configApiRef: ApiRef = createApiRef({ id: 'core.config', }); diff --git a/packages/core-plugin-api/src/apis/definitions/DiscoveryApi.ts b/packages/core-plugin-api/src/apis/definitions/DiscoveryApi.ts index 7082cda9dc..d23fe3db6c 100644 --- a/packages/core-plugin-api/src/apis/definitions/DiscoveryApi.ts +++ b/packages/core-plugin-api/src/apis/definitions/DiscoveryApi.ts @@ -19,6 +19,8 @@ import { ApiRef, createApiRef } from '../system'; * The discovery API is used to provide a mechanism for plugins to * discover the endpoint to use to talk to their backend counterpart. * + * @remarks + * * The purpose of the discovery API is to allow for many different deployment * setups and routing methods through a central configuration, instead * of letting each individual plugin manage that configuration. @@ -26,6 +28,8 @@ import { ApiRef, createApiRef } from '../system'; * Implementations of the discovery API can be a simple as a URL pattern * using the pluginId, but could also have overrides for individual plugins, * or query a separate discovery service. + * + * @public */ export type DiscoveryApi = { /** @@ -41,6 +45,11 @@ export type DiscoveryApi = { getBaseUrl(pluginId: string): Promise; }; +/** + * The {@link ApiRef} of {@link DiscoveryApi}. + * + * @public + */ export const discoveryApiRef: ApiRef = createApiRef({ id: 'core.discovery', }); diff --git a/packages/core-plugin-api/src/apis/definitions/ErrorApi.ts b/packages/core-plugin-api/src/apis/definitions/ErrorApi.ts index 69c331bc06..820660ac52 100644 --- a/packages/core-plugin-api/src/apis/definitions/ErrorApi.ts +++ b/packages/core-plugin-api/src/apis/definitions/ErrorApi.ts @@ -20,8 +20,10 @@ import { Observable } from '@backstage/types'; /** * Mirrors the JavaScript Error class, for the purpose of * providing documentation and optional fields. + * + * @public */ -type Error = { +export type Error = { name: string; message: string; stack?: string; @@ -29,6 +31,8 @@ type Error = { /** * Provides additional information about an error that was posted to the application. + * + * @public */ export type ErrorContext = { // If set to true, this error should not be displayed to the user. Defaults to false. @@ -38,6 +42,8 @@ export type ErrorContext = { /** * The error API is used to report errors to the app, and display them to the user. * + * @remarks + * * Plugins can use this API as a method of displaying errors to the user, but also * to report errors for collection by error reporting services. * @@ -49,6 +55,8 @@ export type ErrorContext = { * if it would be useful to collect or log it for debugging purposes, but with * the hidden flag set. For example, an error arising from form field validation * should probably not be reported, while a failed REST call would be useful to report. + * + * @public */ export type ErrorApi = { /** @@ -62,6 +70,11 @@ export type ErrorApi = { error$(): Observable<{ error: Error; context?: ErrorContext }>; }; +/** + * The {@link ApiRef} of {@link ErrorApi}. + * + * @public + */ export const errorApiRef: ApiRef = createApiRef({ id: 'core.error', }); diff --git a/packages/core-plugin-api/src/apis/definitions/FeatureFlagsApi.ts b/packages/core-plugin-api/src/apis/definitions/FeatureFlagsApi.ts index 07797bf3f1..c669710895 100644 --- a/packages/core-plugin-api/src/apis/definitions/FeatureFlagsApi.ts +++ b/packages/core-plugin-api/src/apis/definitions/FeatureFlagsApi.ts @@ -17,29 +17,35 @@ import { ApiRef, createApiRef } from '../system'; /** - * The feature flags API is used to toggle functionality to users across plugins and Backstage. + * Fetaure flag descriptor. * - * Plugins can use this API to register feature flags that they have available - * for users to enable/disable, and this API will centralize the current user's - * state of which feature flags they would like to enable. - * - * This is ideal for Backstage plugins, as well as your own App, to trial incomplete - * or unstable upcoming features. Although there will be a common interface for users - * to enable and disable feature flags, this API acts as another way to enable/disable. + * @public */ - export type FeatureFlag = { name: string; pluginId: string; }; +/** + * Enum representing the state of a feature flag (inactive/active). + * + * @public + */ export enum FeatureFlagState { + /** + * Feature flag inactive (disabled). + */ None = 0, + /** + * Feature flag active (enabled). + */ Active = 1, } /** * Options to use when saving feature flags. + * + * @public */ export type FeatureFlagsSaveOptions = { /** @@ -55,8 +61,28 @@ export type FeatureFlagsSaveOptions = { merge?: boolean; }; +/** + * User flags alias. + * + * @public + */ export type UserFlags = {}; +/** + * The feature flags API is used to toggle functionality to users across plugins and Backstage. + * + * @remarks + * + * Plugins can use this API to register feature flags that they have available + * for users to enable/disable, and this API will centralize the current user's + * state of which feature flags they would like to enable. + * + * This is ideal for Backstage plugins, as well as your own App, to trial incomplete + * or unstable upcoming features. Although there will be a common interface for users + * to enable and disable feature flags, this API acts as another way to enable/disable. + * + * @public + */ export interface FeatureFlagsApi { /** * Registers a new feature flag. Once a feature flag has been registered it @@ -80,6 +106,11 @@ export interface FeatureFlagsApi { save(options: FeatureFlagsSaveOptions): void; } +/** + * The {@link ApiRef} of {@link FeatureFlagsApi}. + * + * @public + */ export const featureFlagsApiRef: ApiRef = createApiRef({ id: 'core.featureflags', }); diff --git a/packages/core-plugin-api/src/apis/definitions/IdentityApi.ts b/packages/core-plugin-api/src/apis/definitions/IdentityApi.ts index 9d7131fed6..9f68a8b2cc 100644 --- a/packages/core-plugin-api/src/apis/definitions/IdentityApi.ts +++ b/packages/core-plugin-api/src/apis/definitions/IdentityApi.ts @@ -18,6 +18,8 @@ import { ProfileInfo } from './auth'; /** * The Identity API used to identify and get information about the signed in user. + * + * @public */ export type IdentityApi = { /** @@ -49,6 +51,11 @@ export type IdentityApi = { signOut(): Promise; }; +/** + * The {@link ApiRef} of {@link IdentityApi}. + * + * @public + */ export const identityApiRef: ApiRef = createApiRef({ id: 'core.identity', }); diff --git a/packages/core-plugin-api/src/apis/definitions/OAuthRequestApi.ts b/packages/core-plugin-api/src/apis/definitions/OAuthRequestApi.ts index 14609f5b3a..03e129ef6a 100644 --- a/packages/core-plugin-api/src/apis/definitions/OAuthRequestApi.ts +++ b/packages/core-plugin-api/src/apis/definitions/OAuthRequestApi.ts @@ -21,8 +21,12 @@ import { ApiRef, createApiRef } from '../system'; /** * Information about the auth provider that we're requesting a login towards. * + * @remarks + * * This should be shown to the user so that they can be informed about what login is being requested * before a popup is shown. + * + * @public */ export type AuthProvider = { /** @@ -39,6 +43,8 @@ export type AuthProvider = { /** * Describes how to handle auth requests. Both how to show them to the user, and what to do when * the user accesses the auth request. + * + * @public */ export type AuthRequesterOptions = { /** @@ -56,12 +62,16 @@ export type AuthRequesterOptions = { /** * Function used to trigger new auth requests for a set of scopes. * + * @remarks + * * The returned promise will resolve to the same value returned by the onAuthRequest in the - * AuthRequesterOptions. Or rejected, if the request is rejected. + * {@link AuthRequesterOptions}. Or rejected, if the request is rejected. * * This function can be called multiple times before the promise resolves. All calls * will be merged into one request, and the scopes forwarded to the onAuthRequest will be the * union of all requested scopes. + * + * @public */ export type AuthRequester = ( scopes: Set, @@ -71,8 +81,12 @@ export type AuthRequester = ( * An pending auth request for a single auth provider. The request will remain in this pending * state until either reject() or trigger() is called. * + * @remarks + * * Any new requests for the same provider are merged into the existing pending request, meaning * there will only ever be a single pending request for a given provider. + * + * @public */ export type PendingAuthRequest = { /** @@ -95,6 +109,8 @@ export type PendingAuthRequest = { /** * Provides helpers for implemented OAuth login flows within Backstage. + * + * @public */ export type OAuthRequestApi = { /** @@ -127,6 +143,11 @@ export type OAuthRequestApi = { authRequest$(): Observable; }; +/** + * The {@link ApiRef} of {@link OAuthRequestApi}. + * + * @public + */ export const oauthRequestApiRef: ApiRef = createApiRef({ id: 'core.oauthrequest', }); diff --git a/packages/core-plugin-api/src/apis/definitions/StorageApi.ts b/packages/core-plugin-api/src/apis/definitions/StorageApi.ts index f9a52a0bf4..73a19a1ceb 100644 --- a/packages/core-plugin-api/src/apis/definitions/StorageApi.ts +++ b/packages/core-plugin-api/src/apis/definitions/StorageApi.ts @@ -17,48 +17,60 @@ import { ApiRef, createApiRef } from '../system'; import { Observable } from '@backstage/types'; +/** + * Describes a value change event. + * + * @public + */ export type StorageValueChange = { key: string; newValue?: T; }; +/** + * Provides key-value persistence API. + * + * @public + */ export interface StorageApi { /** * Create a bucket to store data in. - * @param {String} name Namespace for the storage to be stored under, + * @param name - Namespace for the storage to be stored under, * will inherit previous namespaces too */ forBucket(name: string): StorageApi; /** * Get the current value for persistent data, use observe$ to be notified of updates. - * - * @param {String} key Unique key associated with the data. - * @return {Object} data The data that should is stored. + * @param key - Unique key associated with the data. */ get(key: string): T | undefined; /** * Remove persistent data. - * - * @param {String} key Unique key associated with the data. + * @param key - Unique key associated with the data. */ remove(key: string): Promise; /** * Save persistent data, and emit messages to anyone that is using observe$ for this key - * - * @param {String} key Unique key associated with the data. + * @param key - Unique key associated with the data. + * @param data - The data to be stored under the key. */ set(key: string, data: any): Promise; /** * Observe changes on a particular key in the bucket - * @param {String} key Unique key associated with the data + * @param key - Unique key associated with the data */ observe$(key: string): Observable>; } +/** + * The {@link ApiRef} of {@link StorageApi}. + * + * @public + */ export const storageApiRef: ApiRef = createApiRef({ id: 'core.storage', }); diff --git a/packages/core-plugin-api/src/apis/definitions/auth.ts b/packages/core-plugin-api/src/apis/definitions/auth.ts index 41c918fa6c..8fe532f3a6 100644 --- a/packages/core-plugin-api/src/apis/definitions/auth.ts +++ b/packages/core-plugin-api/src/apis/definitions/auth.ts @@ -32,11 +32,20 @@ import { Observable } from '@backstage/types'; * An array of scopes, or a scope string formatted according to the * auth provider, which is typically a space separated list. * + * @remarks + * * See the documentation for each auth provider for the list of scopes * supported by each provider. + * + * @public */ export type OAuthScope = string | string[]; +/** + * Configuration of an authentication request. + * + * @public + */ export type AuthRequestOptions = { /** * If this is set to true, the user will not be prompted to log in, @@ -45,7 +54,7 @@ export type AuthRequestOptions = { * This can be used to perform a check whether the user is logged in, or if you don't * want to force a user to be logged in, but provide functionality if they already are. * - * @default false + * @defaultValue false */ optional?: boolean; @@ -55,7 +64,7 @@ export type AuthRequestOptions = { * * The method must be called synchronously from a user action for this to work in all browsers. * - * @default false + * @defaultValue false */ instantPopup?: boolean; }; @@ -63,6 +72,8 @@ export type AuthRequestOptions = { /** * This API provides access to OAuth 2 credentials. It lets you request access tokens, * which can be used to act on behalf of the user when talking to APIs. + * + * @public */ export type OAuthApi = { /** @@ -95,6 +106,8 @@ export type OAuthApi = { /** * This API provides access to OpenID Connect credentials. It lets you request ID tokens, * which can be passed to backend services to prove the user's identity. + * + * @public */ export type OpenIdConnectApi = { /** @@ -113,13 +126,15 @@ export type OpenIdConnectApi = { /** * This API provides access to profile information of the user from an auth provider. + * + * @public */ export type ProfileInfoApi = { /** * Get profile information for the user as supplied by this auth provider. * * If the optional flag is not set, a session is guaranteed to be returned, while if - * the optional flag is set, the session may be undefined. See @AuthRequestOptions for more details. + * the optional flag is set, the session may be undefined. See {@link AuthRequestOptions} for more details. */ getProfile(options?: AuthRequestOptions): Promise; }; @@ -127,23 +142,32 @@ export type ProfileInfoApi = { /** * This API provides access to the user's identity within Backstage. * + * @remarks + * * An auth provider that implements this interface can be used to sign-in to backstage. It is * not intended to be used directly from a plugin, but instead serves as a connection between - * this authentication method and the app's @IdentityApi + * this authentication method and the app's {@link IdentityApi} + * + * @public */ export type BackstageIdentityApi = { /** * Get the user's identity within Backstage. This should normally not be called directly, - * use the @IdentityApi instead. + * use the {@link IdentityApi} instead. * * If the optional flag is not set, a session is guaranteed to be returned, while if - * the optional flag is set, the session may be undefined. See @AuthRequestOptions for more details. + * the optional flag is set, the session may be undefined. See {@link AuthRequestOptions} for more details. */ getBackstageIdentity( options?: AuthRequestOptions, ): Promise; }; +/** + * A (user id, token) pair. + * + * @public + */ export type BackstageIdentity = { /** * The backstage user ID. @@ -163,6 +187,8 @@ export type BackstageIdentity = { /** * Profile information of the user. + * + * @public */ export type ProfileInfo = { /** @@ -183,14 +209,24 @@ export type ProfileInfo = { /** * Session state values passed to subscribers of the SessionApi. + * + * @public */ export enum SessionState { + /** + * User signed in. + */ SignedIn = 'SignedIn', + /** + * User not signed in. + */ SignedOut = 'SignedOut', } /** * The SessionApi provides basic controls for any auth provider that is tied to a persistent session. + * + * @public */ export type SessionApi = { /** @@ -212,10 +248,14 @@ export type SessionApi = { /** * Provides authentication towards Google APIs and identities. * - * See https://developers.google.com/identity/protocols/googlescopes for a full list of supported scopes. + * @remarks + * + * See {@link https://developers.google.com/identity/protocols/googlescopes} for a full list of supported scopes. * * Note that the ID token payload is only guaranteed to contain the user's numerical Google ID, * email and expiration information. Do not rely on any other fields, as they might not be present. + * + * @public */ export const googleAuthApiRef: ApiRef< OAuthApi & @@ -230,8 +270,12 @@ export const googleAuthApiRef: ApiRef< /** * Provides authentication towards GitHub APIs. * - * See https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/ + * @remarks + * + * See {@link https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/} * for a full list of supported scopes. + * + * @public */ export const githubAuthApiRef: ApiRef< OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi @@ -242,8 +286,12 @@ export const githubAuthApiRef: ApiRef< /** * Provides authentication towards Okta APIs. * - * See https://developer.okta.com/docs/guides/implement-oauth-for-okta/scopes/ + * @remarks + * + * See {@link https://developer.okta.com/docs/guides/implement-oauth-for-okta/scopes/} * for a full list of supported scopes. + * + * @public */ export const oktaAuthApiRef: ApiRef< OAuthApi & @@ -258,8 +306,12 @@ export const oktaAuthApiRef: ApiRef< /** * Provides authentication towards GitLab APIs. * - * See https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#limiting-scopes-of-a-personal-access-token + * @remarks + * + * See {@link https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#limiting-scopes-of-a-personal-access-token} * for a full list of supported scopes. + * + * @public */ export const gitlabAuthApiRef: ApiRef< OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi @@ -270,8 +322,12 @@ export const gitlabAuthApiRef: ApiRef< /** * Provides authentication towards Auth0 APIs. * - * See https://auth0.com/docs/scopes/current/oidc-scopes + * @remarks + * + * See {@link https://auth0.com/docs/scopes/current/oidc-scopes} * for a full list of supported scopes. + * + * @public */ export const auth0AuthApiRef: ApiRef< OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi @@ -282,9 +338,13 @@ export const auth0AuthApiRef: ApiRef< /** * Provides authentication towards Microsoft APIs and identities. * + * @remarks + * * For more info and a full list of supported scopes, see: - * - https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent - * - https://docs.microsoft.com/en-us/graph/permissions-reference + * - {@link https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent} + * - {@link https://docs.microsoft.com/en-us/graph/permissions-reference} + * + * @public */ export const microsoftAuthApiRef: ApiRef< OAuthApi & @@ -298,6 +358,8 @@ export const microsoftAuthApiRef: ApiRef< /** * Provides authentication for custom identity providers. + * + * @public */ export const oauth2ApiRef: ApiRef< OAuthApi & @@ -311,6 +373,8 @@ export const oauth2ApiRef: ApiRef< /** * Provides authentication for custom OpenID Connect identity providers. + * + * @public */ export const oidcAuthApiRef: ApiRef< OAuthApi & @@ -323,7 +387,9 @@ export const oidcAuthApiRef: ApiRef< }); /** - * Provides authentication for saml based identity providers + * Provides authentication for SAML-based identity providers. + * + * @public */ export const samlAuthApiRef: ApiRef< ProfileInfoApi & BackstageIdentityApi & SessionApi @@ -331,6 +397,11 @@ export const samlAuthApiRef: ApiRef< id: 'core.auth.saml', }); +/** + * Provides authentication towards OneLogin APIs. + * + * @public + */ export const oneloginAuthApiRef: ApiRef< OAuthApi & OpenIdConnectApi & @@ -344,8 +415,12 @@ export const oneloginAuthApiRef: ApiRef< /** * Provides authentication towards Bitbucket APIs. * - * See https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/ + * @remarks + * + * See {@link https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/} * for a full list of supported scopes. + * + * @public */ export const bitbucketAuthApiRef: ApiRef< OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi @@ -356,8 +431,12 @@ export const bitbucketAuthApiRef: ApiRef< /** * Provides authentication towards Atlassian APIs. * - * See https://developer.atlassian.com/cloud/jira/platform/scopes-for-connect-and-oauth-2-3LO-apps/ + * @remarks + * + * See {@link https://developer.atlassian.com/cloud/jira/platform/scopes-for-connect-and-oauth-2-3LO-apps/} * for a full list of supported scopes. + * + * @public */ export const atlassianAuthApiRef: ApiRef< OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi diff --git a/packages/core-plugin-api/src/apis/system/ApiRef.ts b/packages/core-plugin-api/src/apis/system/ApiRef.ts index 37678ed079..7e13a1963f 100644 --- a/packages/core-plugin-api/src/apis/system/ApiRef.ts +++ b/packages/core-plugin-api/src/apis/system/ApiRef.ts @@ -16,6 +16,11 @@ import type { ApiRef } from './types'; +/** + * API reference configuration - holds an ID of the referenced API. + * + * @public + */ export type ApiRefConfig = { id: string; /** @@ -57,6 +62,13 @@ class ApiRefImpl implements ApiRef { } } +/** + * Creates a reference to an API. + * + * @param config - The descriptor of the API to reference. + * @returns An API reference. + * @public + */ export function createApiRef(config: ApiRefConfig): ApiRef { return new ApiRefImpl(config); } diff --git a/packages/core-plugin-api/src/apis/system/helpers.ts b/packages/core-plugin-api/src/apis/system/helpers.ts index 547d583482..eaffed3003 100644 --- a/packages/core-plugin-api/src/apis/system/helpers.ts +++ b/packages/core-plugin-api/src/apis/system/helpers.ts @@ -17,19 +17,44 @@ import { ApiRef, ApiFactory, TypesToApiRefs } from './types'; /** - * Used to infer types for a standalone ApiFactory that isn't immediately passed + * Used to infer types for a standalone {@link ApiFactory} that isn't immediately passed * to another function. + * + * @remarks + * * This function doesn't actually do anything, it's only used to infer types. + * + * @public */ export function createApiFactory< Api, Impl extends Api, Deps extends { [name in string]: unknown }, >(factory: ApiFactory): ApiFactory; +/** + * Used to infer types for a standalone {@link ApiFactory} that isn't immediately passed + * to another function. + * + * @param api - Ref of the API that will be produced by the factory. + * @param instance - Implementation of the API to use. + * @public + */ export function createApiFactory( api: ApiRef, instance: Impl, ): ApiFactory; +/** + * Used to infer types for a standalone {@link ApiFactory} that isn't immediately passed + * to another function. + * + * @remarks + * + * Creates factory from {@link ApiRef} or returns the factory itself if provided. + * + * @param factory - Existing factory or {@link ApiRef}. + * @param instance - The instance to be returned by the factory. + * @public + */ export function createApiFactory< Api, Impl extends Api, diff --git a/packages/core-plugin-api/src/apis/system/index.ts b/packages/core-plugin-api/src/apis/system/index.ts index ceada1ebd7..964750474e 100644 --- a/packages/core-plugin-api/src/apis/system/index.ts +++ b/packages/core-plugin-api/src/apis/system/index.ts @@ -16,5 +16,6 @@ export { useApi, useApiHolder, withApis } from './useApi'; export { createApiRef } from './ApiRef'; +export type { ApiRefConfig } from './ApiRef'; export * from './types'; export * from './helpers'; diff --git a/packages/core-plugin-api/src/apis/system/types.ts b/packages/core-plugin-api/src/apis/system/types.ts index a97d29fdaa..d7801ea5c1 100644 --- a/packages/core-plugin-api/src/apis/system/types.ts +++ b/packages/core-plugin-api/src/apis/system/types.ts @@ -14,25 +14,62 @@ * limitations under the License. */ +/** + * API reference. + * + * @public + */ export type ApiRef = { id: string; T: T; }; +/** + * Catch-all {@link ApiRef} type. + * + * @public + */ export type AnyApiRef = ApiRef; +/** + * Transforms ApiRef type into its inner API type. + * + * @public + */ export type ApiRefType = T extends ApiRef ? U : never; +/** + * Wraps a type with API properties into a type holding their respective {@link ApiRef}s. + * Reverse type transform of {@link ApiRefsToTypes}. + * + * @public + */ export type TypesToApiRefs = { [key in keyof T]: ApiRef }; +/** + * Unwraps type with {@link ApiRef} properties into a type holding their respective API types. + * Reverse type transform of {@link TypesToApiRefs}. + * + * @public + */ export type ApiRefsToTypes }> = { [key in keyof T]: ApiRefType; }; +/** + * Provides lookup of APIs through their {@link ApiRef}s. + * + * @public + */ export type ApiHolder = { get(api: ApiRef): T | undefined; }; +/** + * Describes type returning API implementations. + * + * @public + */ export type ApiFactory< Api, Impl extends Api, @@ -43,6 +80,11 @@ export type ApiFactory< factory(deps: Deps): Impl; }; +/** + * Catch-all {@link ApiFactory} type. + * + * @public + */ export type AnyApiFactory = ApiFactory< unknown, unknown, diff --git a/packages/core-plugin-api/src/apis/system/useApi.tsx b/packages/core-plugin-api/src/apis/system/useApi.tsx index ef598a4c0e..465a39cff4 100644 --- a/packages/core-plugin-api/src/apis/system/useApi.tsx +++ b/packages/core-plugin-api/src/apis/system/useApi.tsx @@ -18,6 +18,11 @@ import React, { PropsWithChildren } from 'react'; import { ApiRef, ApiHolder, TypesToApiRefs } from './types'; import { useVersionedContext } from '@backstage/version-bridge'; +/** + * React hook for retrieving {@link ApiHolder}, an API catalog. + * + * @public + */ export function useApiHolder(): ApiHolder { const versionedHolder = useVersionedContext<{ 1: ApiHolder }>('api-context'); if (!versionedHolder) { @@ -31,6 +36,12 @@ export function useApiHolder(): ApiHolder { return apiHolder; } +/** + * React hook for retrieving APIs. + * + * @param apiRef - Reference of the API to use. + * @public + */ export function useApi(apiRef: ApiRef): T { const apiHolder = useApiHolder(); @@ -41,6 +52,12 @@ export function useApi(apiRef: ApiRef): T { return api; } +/** + * Wrapper for giving component an API context. + * + * @param apis - APIs for the context. + * @public + */ export function withApis(apis: TypesToApiRefs) { return function withApisWrapper

( WrappedComponent: React.ComponentType

, diff --git a/packages/core-plugin-api/src/app/types.ts b/packages/core-plugin-api/src/app/types.ts index 8b07d699ee..d072f0a2e6 100644 --- a/packages/core-plugin-api/src/app/types.ts +++ b/packages/core-plugin-api/src/app/types.ts @@ -19,11 +19,21 @@ import { ProfileInfo } from '../apis/definitions'; import { IconComponent } from '../icons'; import { BackstagePlugin } from '../plugin/types'; +/** + * Props for the BootErrorPage. + * + * @public + */ export type BootErrorPageProps = { step: 'load-config' | 'load-chunk'; error: Error; }; +/** + * Data and handlers associated with the user sign in event. + * + * @public + */ export type SignInResult = { /** * User ID that will be returned by the IdentityApi @@ -43,6 +53,11 @@ export type SignInResult = { signOut?: () => Promise; }; +/** + * Props for the SignInPage. + * + * @public + */ export type SignInPageProps = { /** * Set the sign-in result for the app. This should only be called once. @@ -50,12 +65,22 @@ export type SignInPageProps = { onResult(result: SignInResult): void; }; +/** + * Props for the ErrorBoundaryFallback. + * + * @public + */ export type ErrorBoundaryFallbackProps = { plugin?: BackstagePlugin; error: Error; resetError: () => void; }; +/** + * Basic app components. + * + * @public + */ export type AppComponents = { NotFoundErrorPage: ComponentType<{}>; BootErrorPage: ComponentType; @@ -75,6 +100,11 @@ export type AppComponents = { SignInPage?: ComponentType; }; +/** + * Provides plugins and components registered in the app. + * + * @public + */ export type AppContext = { /** * Get a list of all plugins that are installed in the app. diff --git a/packages/core-plugin-api/src/app/useApp.tsx b/packages/core-plugin-api/src/app/useApp.tsx index 05d2e1c5c0..f2175a0969 100644 --- a/packages/core-plugin-api/src/app/useApp.tsx +++ b/packages/core-plugin-api/src/app/useApp.tsx @@ -17,6 +17,11 @@ import { useVersionedContext } from '@backstage/version-bridge'; import { AppContext as AppContextV1 } from './types'; +/** + * React hook providing {@link AppContext}. + * + * @public + */ export const useApp = (): AppContextV1 => { const versionedContext = useVersionedContext<{ 1: AppContextV1 }>('app-context'); diff --git a/packages/core-plugin-api/src/deprecatedTypes.ts b/packages/core-plugin-api/src/deprecatedTypes.ts index 4b24614e17..5596ff9f46 100644 --- a/packages/core-plugin-api/src/deprecatedTypes.ts +++ b/packages/core-plugin-api/src/deprecatedTypes.ts @@ -39,8 +39,9 @@ export type Subscription = CoreSubscription; /** * Observable sequence of values and errors, see TC39. * - * https://github.com/tc39/proposal-observable + * @remarks * + * {@link https://github.com/tc39/proposal-observable} * This is used as a common return type for observable values and can be created * using many different observable implementations, such as zen-observable or RxJS 5. * diff --git a/packages/core-plugin-api/src/extensions/componentData.tsx b/packages/core-plugin-api/src/extensions/componentData.tsx index 97a0b74e5b..1f7ef7f06a 100644 --- a/packages/core-plugin-api/src/extensions/componentData.tsx +++ b/packages/core-plugin-api/src/extensions/componentData.tsx @@ -41,6 +41,18 @@ type MaybeComponentNode = ReactNode & { type?: ComponentWithData; }; +/** + * Stores data related to a component in a global store. + * + * @remarks + * + * See {@link https://backstage.io/docs/plugins/composability#component-data}. + * + * @param component - The component to attach the data to. + * @param type - The key under which the data will be stored. + * @param data - Arbitrary value. + * @public + */ export function attachComponentData

( component: ComponentType

, type: string, @@ -70,6 +82,18 @@ export function attachComponentData

( container.map.set(type, data); } +/** + * Retrieves data attached to a component. + * + * @remarks + * + * See {@link https://backstage.io/docs/plugins/composability#component-data}. + * + * @param node - React component to look up. + * @param type - Key of the data to retrieve. + * @returns Data stored using {@link attachComponentData}. + * @public + */ export function getComponentData( node: ReactNode, type: string, diff --git a/packages/core-plugin-api/src/extensions/extensions.tsx b/packages/core-plugin-api/src/extensions/extensions.tsx index 2eb5275c66..f85570a35b 100644 --- a/packages/core-plugin-api/src/extensions/extensions.tsx +++ b/packages/core-plugin-api/src/extensions/extensions.tsx @@ -22,7 +22,12 @@ import { attachComponentData } from './componentData'; import { Extension, BackstagePlugin } from '../plugin/types'; import { PluginErrorBoundary } from './PluginErrorBoundary'; -type ComponentLoader = +/** + * Lazy or synchronous retrieving of extension components. + * + * @public + */ +export type ComponentLoader = | { lazy: () => Promise; } @@ -30,9 +35,19 @@ type ComponentLoader = sync: T; }; -// We do not use ComponentType as the return type, since it doesn't let us convey the children prop. -// ComponentType inserts children as an optional prop whether the inner component accepts it or not, -// making it impossible to make the usage of children type safe. +/** + * Extension for components that can have its own URL route (top-level pages, tabs etc.). + * + * @remarks + * + * We do not use ComponentType as the return type, since it doesn't let us convey the children prop. + * ComponentType inserts children as an optional prop whether the inner component accepts it or not, + * making it impossible to make the usage of children type safe. + * + * See {@link https://backstage.io/docs/plugins/composability#extensions}. + * + * @public + */ export function createRoutableExtension< T extends (props: any) => JSX.Element | null, >(options: { @@ -97,9 +112,19 @@ export function createRoutableExtension< }); } -// We do not use ComponentType as the return type, since it doesn't let us convey the children prop. -// ComponentType inserts children as an optional prop whether the inner component accepts it or not, -// making it impossible to make the usage of children type safe. +/** + * Plain React component extension. + * + * @remarks + * + * We do not use ComponentType as the return type, since it doesn't let us convey the children prop. + * ComponentType inserts children as an optional prop whether the inner component accepts it or not, + * making it impossible to make the usage of children type safe. + * + * See {@link https://backstage.io/docs/plugins/composability#extensions}. + * + * @public + */ export function createComponentExtension< T extends (props: any) => JSX.Element | null, >(options: { component: ComponentLoader; name?: string }): Extension { @@ -107,9 +132,19 @@ export function createComponentExtension< return createReactExtension({ component, name }); } -// We do not use ComponentType as the return type, since it doesn't let us convey the children prop. -// ComponentType inserts children as an optional prop whether the inner component accepts it or not, -// making it impossible to make the usage of children type safe. +/** + * Used by {@link createComponentExtension} and {@link createRoutableExtension}. + * + * @remarks + * + * We do not use ComponentType as the return type, since it doesn't let us convey the children prop. + * ComponentType inserts children as an optional prop whether the inner component accepts it or not, + * making it impossible to make the usage of children type safe. + * + * See {@link https://backstage.io/docs/plugins/composability#extensions}. + * + * @public + */ export function createReactExtension< T extends (props: any) => JSX.Element | null, >(options: { diff --git a/packages/core-plugin-api/src/extensions/index.ts b/packages/core-plugin-api/src/extensions/index.ts index 39db17311a..35803bdeee 100644 --- a/packages/core-plugin-api/src/extensions/index.ts +++ b/packages/core-plugin-api/src/extensions/index.ts @@ -20,5 +20,6 @@ export { createRoutableExtension, createComponentExtension, } from './extensions'; +export type { ComponentLoader } from './extensions'; export { useElementFilter } from './useElementFilter'; export type { ElementCollection } from './useElementFilter'; diff --git a/packages/core-plugin-api/src/extensions/useElementFilter.tsx b/packages/core-plugin-api/src/extensions/useElementFilter.tsx index 7efdd949b2..fa04e7c2c6 100644 --- a/packages/core-plugin-api/src/extensions/useElementFilter.tsx +++ b/packages/core-plugin-api/src/extensions/useElementFilter.tsx @@ -82,17 +82,23 @@ function selectChildren( * A querying interface tailored to traversing a set of selected React elements * and extracting data. * + * @remarks + * * Methods prefixed with `selectBy` are used to narrow the set of selected elements. * * Methods prefixed with `find` return concrete data using a deep traversal of the set. * * Methods prefixed with `get` return concrete data using a shallow traversal of the set. + * + * @public */ export interface ElementCollection { /** * Narrows the set of selected components by doing a deep traversal and * only including those that have defined component data for the given `key`. * + * @remarks + * * Whether an element in the tree has component data set for the given key * is determined by whether `getComponentData` returns undefined. * @@ -104,6 +110,8 @@ export interface ElementCollection { * If `withStrictError` is set, the resulting selection must be a full match, meaning * there may be no elements that were excluded in the selection. If the selection * is not a clean match, an error will be throw with `withStrictError` as the message. + * + * @param query - Filtering query. */ selectByComponentData(query: { key: string; @@ -113,6 +121,8 @@ export interface ElementCollection { /** * Finds all elements using the same criteria as `selectByComponentData`, but * returns the actual component data of each of those elements instead. + * + * @param query - Lookup query. */ findComponentData(query: { key: string }): T[]; @@ -163,7 +173,11 @@ class Collection implements ElementCollection { /** * useElementFilter is a utility that helps you narrow down and retrieve data * from a React element tree, typically operating on the `children` property - * passed in to a component. A common use-case is to construct declarative APIs + * passed in to a component. + * + * @remarks + * + * A common use-case is to construct declarative APIs * where a React component defines its behavior based on its children, such as * the relationship between `Routes` and `Route` in `react-router`. * @@ -175,6 +189,8 @@ class Collection implements ElementCollection { * with added memoization based on the input `node`. If further memoization * dependencies are used in the filter function, they should be added to the * third `dependencies` argument, just like `useMemo`, `useEffect`, etc. + * + * @public */ export function useElementFilter( node: ReactNode, diff --git a/packages/core-plugin-api/src/icons/index.ts b/packages/core-plugin-api/src/icons/index.ts index 9c9e45e54c..de79dd08d3 100644 --- a/packages/core-plugin-api/src/icons/index.ts +++ b/packages/core-plugin-api/src/icons/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export type { IconComponent } from './types'; +export type { IconComponent, OldIconComponent } from './types'; diff --git a/packages/core-plugin-api/src/icons/types.ts b/packages/core-plugin-api/src/icons/types.ts index ccc1c337e7..5648261f3c 100644 --- a/packages/core-plugin-api/src/icons/types.ts +++ b/packages/core-plugin-api/src/icons/types.ts @@ -21,6 +21,8 @@ import { SvgIconProps } from '@material-ui/core'; * IconComponent is the common icon type used throughout Backstage when * working with and rendering generic icons, including the app system icons. * + * @remarks + * * The type is based on SvgIcon from MUI, but both do not what the plugin-api * package to have a dependency on MUI, nor do we want the props to be as broad * as the SvgIconProps interface. @@ -28,6 +30,8 @@ import { SvgIconProps } from '@material-ui/core'; * If you have the need to forward additional props from SvgIconProps, you can * open an issue or submit a PR to the main Backstage repo. When doing so please * also describe your use-case and reasoning of the addition. + * + * @public */ export type IconComponent = ComponentType<{ fontSize?: 'default' | 'small' | 'large'; @@ -37,5 +41,7 @@ export type IconComponent = ComponentType<{ * This exists for backwards compatibility with the old core package. * It's used in some parts of this package in order to smooth out the * migration, but it is not exported. + * + * @public */ export type OldIconComponent = ComponentType; diff --git a/packages/core-plugin-api/src/plugin/Plugin.tsx b/packages/core-plugin-api/src/plugin/Plugin.tsx index 53a53b76d0..52ca0e76e3 100644 --- a/packages/core-plugin-api/src/plugin/Plugin.tsx +++ b/packages/core-plugin-api/src/plugin/Plugin.tsx @@ -24,6 +24,9 @@ import { } from './types'; import { AnyApiFactory } from '../apis'; +/** + * @internal + */ export class PluginImpl< Routes extends AnyRoutes, ExternalRoutes extends AnyExternalRoutes, @@ -80,6 +83,12 @@ export class PluginImpl< } } +/** + * Creates Backstage Plugin from config. + * + * @param config - Plugin configuration. + * @public + */ export function createPlugin< Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}, diff --git a/packages/core-plugin-api/src/plugin/index.ts b/packages/core-plugin-api/src/plugin/index.ts index 321ae6998a..0cb9a2aede 100644 --- a/packages/core-plugin-api/src/plugin/index.ts +++ b/packages/core-plugin-api/src/plugin/index.ts @@ -16,6 +16,8 @@ export { createPlugin } from './Plugin'; export type { + AnyExternalRoutes, + AnyRoutes, BackstagePlugin, Extension, FeatureFlagOutput, diff --git a/packages/core-plugin-api/src/plugin/types.ts b/packages/core-plugin-api/src/plugin/types.ts index b3e1043efd..192e771092 100644 --- a/packages/core-plugin-api/src/plugin/types.ts +++ b/packages/core-plugin-api/src/plugin/types.ts @@ -17,29 +17,72 @@ import { RouteRef, SubRouteRef, ExternalRouteRef } from '../routing'; import { AnyApiFactory } from '../apis/system'; +/** + * Route configuration. + * + * @public + */ export type RouteOptions = { // Whether the route path must match exactly, defaults to true. exact?: boolean; }; +/** + * Type alias for paths. + * + * @public + */ export type RoutePath = string; -// Replace with using RouteRefs +/** + * Replace with using {@link RouteRef}s. + * + * @public + */ export type FeatureFlagOutput = { type: 'feature-flag'; name: string; }; +/** + * {@link FeatureFlagOutput} type. + * + * @public + */ export type PluginOutput = FeatureFlagOutput; +/** + * Plugin extension type. + * + * @remarks + * + * See {@link https://backstage.io/docs/plugins/composability#extensions}. + * + * @public + */ export type Extension = { expose(plugin: BackstagePlugin): T; }; +/** + * Catch-all route type. + * + * @public + */ export type AnyRoutes = { [name: string]: RouteRef | SubRouteRef }; +/** + * Catch-all type for {@link ExternalRouteRef}s. + * + * @public + */ export type AnyExternalRoutes = { [name: string]: ExternalRouteRef }; +/** + * Plugin type. + * + * @public + */ export type BackstagePlugin< Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}, @@ -52,6 +95,11 @@ export type BackstagePlugin< externalRoutes: ExternalRoutes; }; +/** + * Plugin descriptor type. + * + * @public + */ export type PluginConfig< Routes extends AnyRoutes, ExternalRoutes extends AnyExternalRoutes, @@ -63,10 +111,20 @@ export type PluginConfig< externalRoutes?: ExternalRoutes; }; +/** + * Holds hooks registered by the plugin. + * + * @public + */ export type PluginHooks = { featureFlags: FeatureFlagsHooks; }; +/** + * Interface for registering feature flags hooks. + * + * @public + */ export type FeatureFlagsHooks = { register(name: string): void; }; diff --git a/packages/core-plugin-api/src/routing/ExternalRouteRef.ts b/packages/core-plugin-api/src/routing/ExternalRouteRef.ts index c1c17c86df..2ebb81dbfb 100644 --- a/packages/core-plugin-api/src/routing/ExternalRouteRef.ts +++ b/packages/core-plugin-api/src/routing/ExternalRouteRef.ts @@ -22,6 +22,9 @@ import { OptionalParams, } from './types'; +/** + * @internal + */ export class ExternalRouteRefImpl< Params extends AnyParams, Optional extends boolean, @@ -42,6 +45,16 @@ export class ExternalRouteRefImpl< } } +/** + * Creates a route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references. + * + * @remarks + * + * See {@link https://backstage.io/docs/plugins/composability#routing-system}. + * + * @param options - Description of the route reference to be created. + * @public + */ export function createExternalRouteRef< Params extends { [param in ParamKey]: string }, Optional extends boolean = false, diff --git a/packages/core-plugin-api/src/routing/RouteRef.ts b/packages/core-plugin-api/src/routing/RouteRef.ts index 78211e29c6..a926b775e6 100644 --- a/packages/core-plugin-api/src/routing/RouteRef.ts +++ b/packages/core-plugin-api/src/routing/RouteRef.ts @@ -24,6 +24,10 @@ import { import { OldIconComponent } from '../icons/types'; // TODO(Rugvip): Remove this in the next breaking release, it's exported but unused +/** + * @deprecated + * @internal + */ export type RouteRefConfig = { params?: ParamKeys; path?: string; @@ -31,6 +35,9 @@ export type RouteRefConfig = { title: string; }; +/** + * @internal + */ export class RouteRefImpl implements RouteRef { @@ -66,6 +73,12 @@ export class RouteRefImpl } } +/** + * Create a {@link RouteRef} from a route descriptor. + * + * @param config - Description of the route reference to be created. + * @public + */ export function createRouteRef< // Params is the type that we care about and the one to be embedded in the route ref. // For example, given the params ['name', 'kind'], Params will be {name: string, kind: string} diff --git a/packages/core-plugin-api/src/routing/SubRouteRef.ts b/packages/core-plugin-api/src/routing/SubRouteRef.ts index be30d56096..61d89fcbdb 100644 --- a/packages/core-plugin-api/src/routing/SubRouteRef.ts +++ b/packages/core-plugin-api/src/routing/SubRouteRef.ts @@ -26,6 +26,9 @@ import { // Should match the pattern in react-router const PARAM_PATTERN = /^\w+$/; +/** + * @internal + */ export class SubRouteRefImpl implements SubRouteRef { @@ -45,18 +48,34 @@ export class SubRouteRefImpl } } -// These utility types help us infer a Param object type from a string path -// For example, `/foo/:bar/:baz` inferred to `{ bar: string, baz: string }` -type ParamPart = S extends `:${infer Param}` ? Param : never; -type ParamNames = S extends `${infer Part}/${infer Rest}` - ? ParamPart | ParamNames - : ParamPart; -type PathParams = { [name in ParamNames]: string }; +/** + * Used in {@link PathParams} type declaration. + * @public + */ +export type ParamPart = S extends `:${infer Param}` + ? Param + : never; /** - * Merges a param object type with with an optional params type into a params object + * Used in {@link PathParams} type declaration. + * @public */ -type MergeParams< +export type ParamNames = + S extends `${infer Part}/${infer Rest}` + ? ParamPart | ParamNames + : ParamPart; +/** + * This utility type helps us infer a Param object type from a string path + * For example, `/foo/:bar/:baz` inferred to `{ bar: string, baz: string }` + * @public + */ +export type PathParams = { [name in ParamNames]: string }; + +/** + * Merges a param object type with with an optional params type into a params object. + * @public + */ +export type MergeParams< P1 extends { [param in string]: string }, P2 extends AnyParams, > = (P1[keyof P1] extends never ? {} : P1) & (P2 extends undefined ? {} : P2); @@ -64,14 +83,22 @@ type MergeParams< /** * Creates a SubRouteRef type given the desired parameters and parent route parameters. * The parameters types are merged together while ensuring that there is no overlap between the two. + * + * @public */ -type MakeSubRouteRef< +export type MakeSubRouteRef< Params extends { [param in string]: string }, ParentParams extends AnyParams, > = keyof Params & keyof ParentParams extends never ? SubRouteRef>> : never; +/** + * Create a {@link SubRouteRef} from a route descriptor. + * + * @param config - Description of the route reference to be created. + * @public + */ export function createSubRouteRef< Path extends string, ParentParams extends AnyParams = never, diff --git a/packages/core-plugin-api/src/routing/index.ts b/packages/core-plugin-api/src/routing/index.ts index 79158d2cdc..01d69cd4b0 100644 --- a/packages/core-plugin-api/src/routing/index.ts +++ b/packages/core-plugin-api/src/routing/index.ts @@ -14,9 +14,24 @@ * limitations under the License. */ -export type { RouteRef, SubRouteRef, ExternalRouteRef } from './types'; +export type { + AnyParams, + RouteRef, + SubRouteRef, + ExternalRouteRef, + OptionalParams, + ParamKeys, + RouteFunc, +} from './types'; export { createRouteRef } from './RouteRef'; export { createSubRouteRef } from './SubRouteRef'; +export type { + MakeSubRouteRef, + MergeParams, + ParamNames, + ParamPart, + PathParams, +} from './SubRouteRef'; export { createExternalRouteRef } from './ExternalRouteRef'; export { useRouteRef } from './useRouteRef'; export { useRouteRefParams } from './useRouteRefParams'; diff --git a/packages/core-plugin-api/src/routing/types.ts b/packages/core-plugin-api/src/routing/types.ts index 7e20d1ff67..bd419abb76 100644 --- a/packages/core-plugin-api/src/routing/types.ts +++ b/packages/core-plugin-api/src/routing/types.ts @@ -17,32 +17,70 @@ import { OldIconComponent } from '../icons/types'; import { getOrCreateGlobalSingleton } from '@backstage/version-bridge'; +/** + * Catch-all type for route params. + * + * @public + */ export type AnyParams = { [param in string]: string } | undefined; + +/** + * Type describing the key type of a route parameter mapping. + * + * @public + */ export type ParamKeys = keyof Params extends never ? [] : (keyof Params)[]; + +/** + * Optional route params. + * + * @public + */ export type OptionalParams = Params[keyof Params] extends never ? undefined : Params; -// The extra TS magic here is to require a single params argument if the RouteRef -// had at least one param defined, but require 0 arguments if there are no params defined. -// Without this we'd have to pass in empty object to all parameter-less RouteRefs -// just to make TypeScript happy, or we would have to make the argument optional in -// which case you might forget to pass it in when it is actually required. +/** + * TS magic for handling route parameters. + * + * @remarks + * + * The extra TS magic here is to require a single params argument if the RouteRef + * had at least one param defined, but require 0 arguments if there are no params defined. + * Without this we'd have to pass in empty object to all parameter-less RouteRefs + * just to make TypeScript happy, or we would have to make the argument optional in + * which case you might forget to pass it in when it is actually required. + * + * @public + */ export type RouteFunc = ( ...[params]: Params extends undefined ? readonly [] : readonly [Params] ) => string; -// This symbol is what we use at runtime to determine whether a given object -// is a type of RouteRef or not. It doesn't work well in TypeScript though since -// the `unique symbol` will refer to different values between package versions. -// For that reason we use the marker $$routeRefType to represent the symbol at -// compile-time instead of using the symbol directly. +/** + * This symbol is what we use at runtime to determine whether a given object + * is a type of RouteRef or not. It doesn't work well in TypeScript though since + * the `unique symbol` will refer to different values between package versions. + * For that reason we use the marker $$routeRefType to represent the symbol at + * compile-time instead of using the symbol directly. + * + * @internal + */ export const routeRefType: unique symbol = getOrCreateGlobalSingleton( 'route-ref-type', () => Symbol('route-ref-type'), ); +/** + * Absolute route reference. + * + * @remarks + * + * See {@link https://backstage.io/docs/plugins/composability#routing-system}. + * + * @public + */ export type RouteRef = { $$routeRefType: 'absolute'; // See routeRefType above @@ -57,6 +95,15 @@ export type RouteRef = { title?: string; }; +/** + * Descriptor of a route relative to an absolute {@link RouteRef}. + * + * @remarks + * + * See {@link https://backstage.io/docs/plugins/composability#routing-system}. + * + * @public + */ export type SubRouteRef = { $$routeRefType: 'sub'; // See routeRefType above @@ -67,6 +114,15 @@ export type SubRouteRef = { params: ParamKeys; }; +/** + * Route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references. + * + * @remarks + * + * See {@link https://backstage.io/docs/plugins/composability#routing-system}. + * + * @public + */ export type ExternalRouteRef< Params extends AnyParams = any, Optional extends boolean = any, @@ -78,20 +134,35 @@ export type ExternalRouteRef< optional?: Optional; }; +/** + * @internal + */ export type AnyRouteRef = | RouteRef | SubRouteRef | ExternalRouteRef; // TODO(Rugvip): None of these should be found in the wild anymore, remove in next minor release -/** @deprecated */ +/** + * @deprecated + * @internal + */ export type ConcreteRoute = {}; -/** @deprecated */ +/** + * @deprecated + * @internal + */ export type AbsoluteRouteRef = RouteRef<{}>; -/** @deprecated */ +/** + * @deprecated + * @internal + */ export type MutableRouteRef = RouteRef<{}>; -// A duplicate of the react-router RouteObject, but with routeRef added +/** + * A duplicate of the react-router RouteObject, but with routeRef added + * @internal + */ export interface BackstageRouteObject { caseSensitive: boolean; children?: BackstageRouteObject[]; diff --git a/packages/core-plugin-api/src/routing/useRouteRef.tsx b/packages/core-plugin-api/src/routing/useRouteRef.tsx index ea05cc14fd..50cfb3bdfb 100644 --- a/packages/core-plugin-api/src/routing/useRouteRef.tsx +++ b/packages/core-plugin-api/src/routing/useRouteRef.tsx @@ -25,6 +25,9 @@ import { SubRouteRef, } from './types'; +/** + * @internal + */ export interface RouteResolver { resolve( anyRouteRef: @@ -35,12 +38,47 @@ export interface RouteResolver { ): RouteFunc | undefined; } +/** + * React hook for constructing URLs to routes. + * + * @remarks + * + * See {@link https://backstage.io/docs/plugins/composability#routing-system} + * + * @param routeRef - The ref to route that should be converted to URL. + * @returns A function that will in turn return the concrete URL of the `routeRef`. + * @public + */ export function useRouteRef( routeRef: ExternalRouteRef, ): Optional extends true ? RouteFunc | undefined : RouteFunc; + +/** + * React hook for constructing URLs to routes. + * + * @remarks + * + * See {@link https://backstage.io/docs/plugins/composability#routing-system} + * + * @param routeRef - The ref to route that should be converted to URL. + * @returns A function that will in turn return the concrete URL of the `routeRef`. + * @public + */ export function useRouteRef( routeRef: RouteRef | SubRouteRef, ): RouteFunc; + +/** + * React hook for constructing URLs to routes. + * + * @remarks + * + * See {@link https://backstage.io/docs/plugins/composability#routing-system} + * + * @param routeRef - The ref to route that should be converted to URL. + * @returns A function that will in turn return the concrete URL of the `routeRef`. + * @public + */ export function useRouteRef( routeRef: | RouteRef diff --git a/packages/core-plugin-api/src/routing/useRouteRefParams.ts b/packages/core-plugin-api/src/routing/useRouteRefParams.ts index a61df97cf5..e24576372b 100644 --- a/packages/core-plugin-api/src/routing/useRouteRefParams.ts +++ b/packages/core-plugin-api/src/routing/useRouteRefParams.ts @@ -17,6 +17,11 @@ import { useParams } from 'react-router-dom'; import { RouteRef, AnyParams, SubRouteRef } from './types'; +/** + * React hook for retrieving dynamic params from the current URL. + * @param _routeRef - Ref of the current route. + * @public + */ export function useRouteRefParams( _routeRef: RouteRef | SubRouteRef, ): Params { From 236756d0f204eb55cd3fd4e40a480e38f720ca99 Mon Sep 17 00:00:00 2001 From: Marley Powell Date: Mon, 8 Nov 2021 14:21:39 +0000 Subject: [PATCH 08/25] refactor: Consume types from `@backstage/plugin-azure-devops-common`. Signed-off-by: Marley Powell --- .changeset/many-mayflies-notice.md | 2 +- plugins/azure-devops/package.json | 2 +- .../azure-devops/src/api/AzureDevOpsApi.ts | 6 +++- .../azure-devops/src/api/AzureDevOpsClient.ts | 8 +++-- plugins/azure-devops/src/api/types.ts | 34 ------------------- .../components/BuildTable/BuildTable.test.ts | 2 +- .../src/components/BuildTable/BuildTable.tsx | 4 +-- 7 files changed, 16 insertions(+), 42 deletions(-) delete mode 100644 plugins/azure-devops/src/api/types.ts diff --git a/.changeset/many-mayflies-notice.md b/.changeset/many-mayflies-notice.md index b8d551f4fb..b3d3b3adcd 100644 --- a/.changeset/many-mayflies-notice.md +++ b/.changeset/many-mayflies-notice.md @@ -2,4 +2,4 @@ '@backstage/plugin-azure-devops': patch --- -refactor(`@backstage/plugin-azure-devops`): Consume re-exported types from `@backstage/plugin-azure-devops-backend`. +refactor(`@backstage/plugin-azure-devops`): Consume types from `@backstage/plugin-azure-devops-common`. diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index 5bde285aa0..5c08f998fb 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -37,7 +37,7 @@ "@backstage/core-components": "^0.7.2", "@backstage/core-plugin-api": "^0.1.12", "@backstage/errors": "^0.1.4", - "@backstage/plugin-azure-devops-backend": "^0.1.4", + "@backstage/plugin-azure-devops-common": "^0.0.1", "@backstage/plugin-catalog-react": "^0.6.2", "@backstage/theme": "^0.2.12", "@material-ui/core": "^4.12.2", diff --git a/plugins/azure-devops/src/api/AzureDevOpsApi.ts b/plugins/azure-devops/src/api/AzureDevOpsApi.ts index f0bad53b43..05377b0b7b 100644 --- a/plugins/azure-devops/src/api/AzureDevOpsApi.ts +++ b/plugins/azure-devops/src/api/AzureDevOpsApi.ts @@ -14,7 +14,11 @@ * limitations under the License. */ -import { RepoBuild, RepoBuildOptions } from './types'; +import { + RepoBuild, + RepoBuildOptions, +} from '@backstage/plugin-azure-devops-common'; + import { createApiRef } from '@backstage/core-plugin-api'; export const azureDevOpsApiRef = createApiRef({ diff --git a/plugins/azure-devops/src/api/AzureDevOpsClient.ts b/plugins/azure-devops/src/api/AzureDevOpsClient.ts index e03428e511..4fd4e781c4 100644 --- a/plugins/azure-devops/src/api/AzureDevOpsClient.ts +++ b/plugins/azure-devops/src/api/AzureDevOpsClient.ts @@ -14,9 +14,13 @@ * limitations under the License. */ -import { AzureDevOpsApi } from './AzureDevOpsApi'; -import { RepoBuild, RepoBuildOptions } from './types'; import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; +import { + RepoBuild, + RepoBuildOptions, +} from '@backstage/plugin-azure-devops-common'; + +import { AzureDevOpsApi } from './AzureDevOpsApi'; import { ResponseError } from '@backstage/errors'; export class AzureDevOpsClient implements AzureDevOpsApi { diff --git a/plugins/azure-devops/src/api/types.ts b/plugins/azure-devops/src/api/types.ts deleted file mode 100644 index 46a9212aca..0000000000 --- a/plugins/azure-devops/src/api/types.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - BuildResult, - BuildStatus, -} from '@backstage/plugin-azure-devops-backend'; - -export type RepoBuild = { - id?: number; - title: string; - link?: string; - status?: BuildStatus; - result?: BuildResult; - queueTime?: Date; - source: string; -}; - -export type RepoBuildOptions = { - top?: number; -}; diff --git a/plugins/azure-devops/src/components/BuildTable/BuildTable.test.ts b/plugins/azure-devops/src/components/BuildTable/BuildTable.test.ts index 81942b72ec..cb240aef42 100644 --- a/plugins/azure-devops/src/components/BuildTable/BuildTable.test.ts +++ b/plugins/azure-devops/src/components/BuildTable/BuildTable.test.ts @@ -17,7 +17,7 @@ import { BuildResult, BuildStatus, -} from '@backstage/plugin-azure-devops-backend'; +} from '@backstage/plugin-azure-devops-common'; import { getBuildResultComponent, getBuildStateComponent } from './BuildTable'; import { renderInTestApp } from '@backstage/test-utils'; diff --git a/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx b/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx index 4833370cf6..7e260be6e9 100644 --- a/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx +++ b/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx @@ -18,7 +18,8 @@ import { Box, Typography } from '@material-ui/core'; import { BuildResult, BuildStatus, -} from '@backstage/plugin-azure-devops-backend'; + RepoBuild, +} from '@backstage/plugin-azure-devops-common'; import { Link, ResponseErrorPanel, @@ -34,7 +35,6 @@ import { import { DateTime } from 'luxon'; import React from 'react'; -import { RepoBuild } from '../../api/types'; export const getBuildResultComponent = (result: number | undefined) => { switch (result) { From b4ab81cad9ed51d6fe5f985c3a467b5312374c6a Mon Sep 17 00:00:00 2001 From: Marley Powell Date: Mon, 8 Nov 2021 14:55:07 +0000 Subject: [PATCH 09/25] refactor: Stop re-exporting types from `@backstage/plugin-azure-devops-backend`. Signed-off-by: Marley Powell --- .changeset/many-mayflies-notice.md | 3 +- plugins/azure-devops-backend/api-report.md | 45 +------------ plugins/azure-devops-backend/package.json | 1 + .../src/api/AzureDevOpsApi.test.ts | 12 ++-- .../src/api/AzureDevOpsApi.ts | 12 ++-- plugins/azure-devops-backend/src/api/index.ts | 2 - plugins/azure-devops-backend/src/api/types.ts | 67 ------------------- plugins/azure-devops-backend/src/index.ts | 3 +- .../src/service/router.test.ts | 26 +++---- .../src/service/router.ts | 5 +- .../azure-devops/src/hooks/useRepoBuilds.ts | 5 +- 11 files changed, 43 insertions(+), 138 deletions(-) delete mode 100644 plugins/azure-devops-backend/src/api/types.ts diff --git a/.changeset/many-mayflies-notice.md b/.changeset/many-mayflies-notice.md index b3d3b3adcd..cd4f91fa93 100644 --- a/.changeset/many-mayflies-notice.md +++ b/.changeset/many-mayflies-notice.md @@ -1,5 +1,6 @@ --- '@backstage/plugin-azure-devops': patch +'@backstage/plugin-azure-devops-backend': minor --- -refactor(`@backstage/plugin-azure-devops`): Consume types from `@backstage/plugin-azure-devops-common`. +refactor(`@backstage/plugin-azure-devops`): Consume types from `@backstage/plugin-azure-devops-common`. Stop re-exporting types from `@backstage/plugin-azure-devops-backend`. diff --git a/plugins/azure-devops-backend/api-report.md b/plugins/azure-devops-backend/api-report.md index fac6261a39..1eabccc720 100644 --- a/plugins/azure-devops-backend/api-report.md +++ b/plugins/azure-devops-backend/api-report.md @@ -4,13 +4,13 @@ ```ts import { Build } from 'azure-devops-node-api/interfaces/BuildInterfaces'; -import { BuildResult } from 'azure-devops-node-api/interfaces/BuildInterfaces'; -import { BuildStatus } from 'azure-devops-node-api/interfaces/BuildInterfaces'; import { Config } from '@backstage/config'; import express from 'express'; import { GitRepository } from 'azure-devops-node-api/interfaces/GitInterfaces'; import { Logger as Logger_2 } from 'winston'; -import { PullRequestStatus } from 'azure-devops-node-api/interfaces/GitInterfaces'; +import { PullRequest } from '@backstage/plugin-azure-devops-common'; +import { PullRequestOptions } from '@backstage/plugin-azure-devops-common'; +import { RepoBuild } from '@backstage/plugin-azure-devops-common'; import { WebApi } from 'azure-devops-node-api'; // Warning: (ae-missing-release-tag) "AzureDevOpsApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -29,8 +29,6 @@ export class AzureDevOpsApi { projectName: string, repoName: string, ): Promise; - // Warning: (ae-forgotten-export) The symbol "PullRequestOptions" needs to be exported by the entry point index.d.ts - // // (undocumented) getPullRequests( projectName: string, @@ -45,48 +43,11 @@ export class AzureDevOpsApi { ): Promise; } -export { BuildResult }; - -export { BuildStatus }; - // Warning: (ae-missing-release-tag) "createRouter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function createRouter(options: RouterOptions): Promise; -// Warning: (ae-missing-release-tag) "PullRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type PullRequest = { - pullRequestId?: number; - repoName?: string; - title?: string; - uniqueName?: string; - createdBy?: string; - creationDate?: Date; - sourceRefName?: string; - targetRefName?: string; - status?: PullRequestStatus; - isDraft?: boolean; - link: string; -}; - -// Warning: (ae-missing-release-tag) "RepoBuild" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type RepoBuild = { - id?: number; - title: string; - link?: string; - status?: BuildStatus; - result?: BuildResult; - queueTime?: Date; - startTime?: Date; - finishTime?: Date; - source: string; - uniqueName?: string; -}; - // Warning: (ae-missing-release-tag) "RouterOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) diff --git a/plugins/azure-devops-backend/package.json b/plugins/azure-devops-backend/package.json index 8a468b0cc9..9dd79e9f8e 100644 --- a/plugins/azure-devops-backend/package.json +++ b/plugins/azure-devops-backend/package.json @@ -22,6 +22,7 @@ "dependencies": { "@backstage/backend-common": "^0.9.8", "@backstage/config": "^0.1.11", + "@backstage/plugin-azure-devops-common": "^0.0.1", "@types/express": "^4.17.6", "azure-devops-node-api": "^11.0.1", "express": "^4.17.1", diff --git a/plugins/azure-devops-backend/src/api/AzureDevOpsApi.test.ts b/plugins/azure-devops-backend/src/api/AzureDevOpsApi.test.ts index fdd49c0440..429d608bd6 100644 --- a/plugins/azure-devops-backend/src/api/AzureDevOpsApi.test.ts +++ b/plugins/azure-devops-backend/src/api/AzureDevOpsApi.test.ts @@ -16,17 +16,21 @@ import { Build, + DefinitionReference, +} from 'azure-devops-node-api/interfaces/BuildInterfaces'; +import { BuildResult, BuildStatus, - GitPullRequest, - GitRepository, PullRequest, PullRequestStatus, RepoBuild, -} from './types'; +} from '@backstage/plugin-azure-devops-common'; +import { + GitPullRequest, + GitRepository, +} from 'azure-devops-node-api/interfaces/GitInterfaces'; import { mappedPullRequest, mappedRepoBuild } from './AzureDevOpsApi'; -import { DefinitionReference } from 'azure-devops-node-api/interfaces/BuildInterfaces'; import { IdentityRef } from 'azure-devops-node-api/interfaces/common/VSSInterfaces'; describe('AzureDevOpsApi', () => { diff --git a/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts b/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts index 26378496ea..1ed1f1d5f5 100644 --- a/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts +++ b/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts @@ -15,17 +15,19 @@ */ import { - Build, BuildResult, BuildStatus, - GitPullRequest, - GitPullRequestSearchCriteria, - GitRepository, PullRequest, PullRequestOptions, RepoBuild, -} from './types'; +} from '@backstage/plugin-azure-devops-common'; +import { + GitPullRequest, + GitPullRequestSearchCriteria, + GitRepository, +} from 'azure-devops-node-api/interfaces/GitInterfaces'; +import { Build } from 'azure-devops-node-api/interfaces/BuildInterfaces'; import { Logger } from 'winston'; import { WebApi } from 'azure-devops-node-api'; diff --git a/plugins/azure-devops-backend/src/api/index.ts b/plugins/azure-devops-backend/src/api/index.ts index 97c48cb0bf..903c1bdb6a 100644 --- a/plugins/azure-devops-backend/src/api/index.ts +++ b/plugins/azure-devops-backend/src/api/index.ts @@ -15,5 +15,3 @@ */ export { AzureDevOpsApi } from './AzureDevOpsApi'; -export { BuildResult, BuildStatus } from './types'; -export type { RepoBuild, PullRequest } from './types'; diff --git a/plugins/azure-devops-backend/src/api/types.ts b/plugins/azure-devops-backend/src/api/types.ts deleted file mode 100644 index fab61d26c9..0000000000 --- a/plugins/azure-devops-backend/src/api/types.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - Build, - BuildResult, - BuildStatus, -} from 'azure-devops-node-api/interfaces/BuildInterfaces'; -import { - GitPullRequest, - GitPullRequestSearchCriteria, - GitRepository, - PullRequestStatus, -} from 'azure-devops-node-api/interfaces/GitInterfaces'; - -export { BuildResult, BuildStatus, PullRequestStatus }; -export type { - Build, - GitPullRequest, - GitPullRequestSearchCriteria, - GitRepository, -}; - -export type RepoBuild = { - id?: number; - title: string; - link?: string; - status?: BuildStatus; - result?: BuildResult; - queueTime?: Date; - startTime?: Date; - finishTime?: Date; - source: string; - uniqueName?: string; -}; - -export type PullRequest = { - pullRequestId?: number; - repoName?: string; - title?: string; - uniqueName?: string; - createdBy?: string; - creationDate?: Date; - sourceRefName?: string; - targetRefName?: string; - status?: PullRequestStatus; - isDraft?: boolean; - link: string; -}; - -export type PullRequestOptions = { - top: number; - status: PullRequestStatus; -}; diff --git a/plugins/azure-devops-backend/src/index.ts b/plugins/azure-devops-backend/src/index.ts index 7a2a347b65..6977d3580f 100644 --- a/plugins/azure-devops-backend/src/index.ts +++ b/plugins/azure-devops-backend/src/index.ts @@ -13,6 +13,5 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { AzureDevOpsApi, BuildResult, BuildStatus } from './api'; -export type { RepoBuild, PullRequest } from './api'; +export { AzureDevOpsApi } from './api'; export * from './service/router'; diff --git a/plugins/azure-devops-backend/src/service/router.test.ts b/plugins/azure-devops-backend/src/service/router.test.ts index 4143291409..f5d533d2d8 100644 --- a/plugins/azure-devops-backend/src/service/router.test.ts +++ b/plugins/azure-devops-backend/src/service/router.test.ts @@ -14,22 +14,22 @@ * limitations under the License. */ -import { getVoidLogger } from '@backstage/backend-common'; -import { ConfigReader } from '@backstage/config'; -import express from 'express'; -import request from 'supertest'; -import { AzureDevOpsApi } from '../api'; -import { createRouter } from './router'; -import { PullRequest, RepoBuild } from '../api/types'; import { - GitRepository, - PullRequestStatus, -} from 'azure-devops-node-api/interfaces/GitInterfaces'; -import { - Build, BuildResult, BuildStatus, -} from 'azure-devops-node-api/interfaces/BuildInterfaces'; + PullRequest, + PullRequestStatus, + RepoBuild, +} from '@backstage/plugin-azure-devops-common'; + +import { AzureDevOpsApi } from '../api'; +import { Build } from 'azure-devops-node-api/interfaces/BuildInterfaces'; +import { ConfigReader } from '@backstage/config'; +import { GitRepository } from 'azure-devops-node-api/interfaces/GitInterfaces'; +import { createRouter } from './router'; +import express from 'express'; +import { getVoidLogger } from '@backstage/backend-common'; +import request from 'supertest'; describe('createRouter', () => { let azureDevOpsApi: jest.Mocked; diff --git a/plugins/azure-devops-backend/src/service/router.ts b/plugins/azure-devops-backend/src/service/router.ts index b3505eae1c..d61148b4ff 100644 --- a/plugins/azure-devops-backend/src/service/router.ts +++ b/plugins/azure-devops-backend/src/service/router.ts @@ -14,7 +14,10 @@ * limitations under the License. */ -import { PullRequestOptions, PullRequestStatus } from '../api/types'; +import { + PullRequestOptions, + PullRequestStatus, +} from '@backstage/plugin-azure-devops-common'; import { WebApi, getPersonalAccessTokenHandler } from 'azure-devops-node-api'; import { AzureDevOpsApi } from '../api'; diff --git a/plugins/azure-devops/src/hooks/useRepoBuilds.ts b/plugins/azure-devops/src/hooks/useRepoBuilds.ts index df4f76c57e..af2d181c34 100644 --- a/plugins/azure-devops/src/hooks/useRepoBuilds.ts +++ b/plugins/azure-devops/src/hooks/useRepoBuilds.ts @@ -14,7 +14,10 @@ * limitations under the License. */ -import { RepoBuild, RepoBuildOptions } from '../api/types'; +import { + RepoBuild, + RepoBuildOptions, +} from '@backstage/plugin-azure-devops-common'; import { AZURE_DEVOPS_DEFAULT_TOP } from '../constants'; import { Entity } from '@backstage/catalog-model'; From 18b6c1543ce003d5e3839374b12706370df0323e Mon Sep 17 00:00:00 2001 From: Marley Powell Date: Mon, 8 Nov 2021 14:58:31 +0000 Subject: [PATCH 10/25] fix: Fixed merge issue in `package.json`. Signed-off-by: Marley Powell --- plugins/azure-devops/package.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index 5c08f998fb..25328d9e81 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -27,12 +27,6 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-model": "^0.9.3", - "@backstage/core-components": "^0.7.0", - "@backstage/core-plugin-api": "^0.1.10", - "@backstage/errors": "^0.1.2", - "@backstage/plugin-catalog-react": "^0.6.0", - "@backstage/theme": "^0.2.11", "@backstage/catalog-model": "^0.9.6", "@backstage/core-components": "^0.7.2", "@backstage/core-plugin-api": "^0.1.12", From 5725f87e4c7a138e95758ee913f12f3db623759c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 8 Nov 2021 20:56:03 +0100 Subject: [PATCH 11/25] create-app: default to making new plugins private Signed-off-by: Patrik Oldsberg --- .changeset/nine-dots-suffer.md | 14 ++++++++++++++ .../templates/default-app/package.json.hbs | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 .changeset/nine-dots-suffer.md diff --git a/.changeset/nine-dots-suffer.md b/.changeset/nine-dots-suffer.md new file mode 100644 index 0000000000..3efd307a10 --- /dev/null +++ b/.changeset/nine-dots-suffer.md @@ -0,0 +1,14 @@ +--- +'@backstage/create-app': patch +--- + +Updated the app template to no longer include the `--no-private` flag for the `create-plugin` command. + +To apply this change to an existing application, remove the `--no-private` flag from the `create-plugin` command in the root `package.json`: + +```diff + "prettier:check": "prettier --check .", +- "create-plugin": "backstage-cli create-plugin --scope internal --no-private", ++ "create-plugin": "backstage-cli create-plugin --scope internal", + "remove-plugin": "backstage-cli remove-plugin" +``` diff --git a/packages/create-app/templates/default-app/package.json.hbs b/packages/create-app/templates/default-app/package.json.hbs index 5ed066a30b..1db9a98c41 100644 --- a/packages/create-app/templates/default-app/package.json.hbs +++ b/packages/create-app/templates/default-app/package.json.hbs @@ -20,7 +20,7 @@ "lint": "lerna run lint --since origin/master --", "lint:all": "lerna run lint --", "prettier:check": "prettier --check .", - "create-plugin": "backstage-cli create-plugin --scope internal --no-private", + "create-plugin": "backstage-cli create-plugin --scope internal", "remove-plugin": "backstage-cli remove-plugin" }, "resolutions": { From d393a3bd2a190daba0dedc7c4c62beba961a6646 Mon Sep 17 00:00:00 2001 From: Jason Nguyen Date: Wed, 3 Nov 2021 14:16:19 -0600 Subject: [PATCH 12/25] [docs] clarify example showing that parameters types propagate Signed-off-by: Jason Nguyen --- .../software-templates/migrating-from-v1beta2-to-v1beta3.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3.md b/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3.md index 280eab083d..4cc9a6a8e6 100644 --- a/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3.md +++ b/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3.md @@ -125,8 +125,8 @@ input schema. input: - address: '{{ json parameters.address }}' + address: ${{ parameters.address }} -- number: '{{ parameters.number }}' -+ number: ${{ parameters.number }} # this will now make sure that the type of number is a number 🙏 +- test: '{{ parameters.test }}' ++ test: ${{ parameters.test }} # this will now make sure that the type of test is a number 🙏 ``` ## `parseRepoUrl` is now a `filter` From d44f3414e8a876af2f07f350107dda79417b6ef6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Nov 2021 21:51:52 +0000 Subject: [PATCH 13/25] build(deps): bump apollo-server from 2.21.0 to 2.25.3 Bumps [apollo-server](https://github.com/apollographql/apollo-server/tree/HEAD/packages/apollo-server) from 2.21.0 to 2.25.3. - [Release notes](https://github.com/apollographql/apollo-server/releases) - [Changelog](https://github.com/apollographql/apollo-server/blob/main/CHANGELOG.md) - [Commits](https://github.com/apollographql/apollo-server/commits/apollo-server@2.25.3/packages/apollo-server) --- updated-dependencies: - dependency-name: apollo-server dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yarn.lock | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/yarn.lock b/yarn.lock index b5786626dd..98e8a242cb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9011,10 +9011,10 @@ apollo-server-caching@^0.7.0: dependencies: lru-cache "^6.0.0" -apollo-server-core@^2.21.0, apollo-server-core@^2.25.2: - version "2.25.2" - resolved "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.25.2.tgz#ff65da5e512d9b5ca54c8e5e8c78ee28b5987247" - integrity sha512-lrohEjde2TmmDTO7FlOs8x5QQbAS0Sd3/t0TaK2TWaodfzi92QAvIsq321Mol6p6oEqmjm8POIDHW1EuJd7XMA== +apollo-server-core@^2.25.3: + version "2.25.3" + resolved "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.25.3.tgz#1a649fd14b3928f5b6e65f0002b380fcfde56862" + integrity sha512-Midow3uZoJ9TjFNeCNSiWElTVZlvmB7G7tG6PPoxIR9Px90/v16Q6EzunDIO0rTJHRC3+yCwZkwtf8w2AcP0sA== dependencies: "@apollographql/apollo-tools" "^0.5.0" "@apollographql/graphql-playground-html" "1.6.27" @@ -9055,10 +9055,10 @@ apollo-server-errors@^2.5.0: resolved "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.5.0.tgz#5d1024117c7496a2979e3e34908b5685fe112b68" integrity sha512-lO5oTjgiC3vlVg2RKr3RiXIIQ5pGXBFxYGGUkKDhTud3jMIhs+gel8L8zsEjKaKxkjHhCQAA/bcEfYiKkGQIvA== -apollo-server-express@^2.16.1, apollo-server-express@^2.21.0: - version "2.25.2" - resolved "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.25.2.tgz#58cd819694ff4c2dec6945a95c5dff6aa2719ef6" - integrity sha512-A2gF2e85vvDugPlajbhr0A14cDFDIGX0mteNOJ8P3Z3cIM0D4hwrWxJidI+SzobefDIyIHu1dynFedJVhV0euQ== +apollo-server-express@^2.16.1, apollo-server-express@^2.25.3: + version "2.25.3" + resolved "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.25.3.tgz#33fe0dae27fa71c8710e714efd93451bf2eb105f" + integrity sha512-tTFYn0oKH2qqLwVj7Ez2+MiKleXACODiGh5IxsB7VuYCPMAi9Yl8iUSlwTjQUvgCWfReZjnf0vFL2k5YhDlrtQ== dependencies: "@apollographql/graphql-playground-html" "1.6.27" "@types/accepts" "^1.3.5" @@ -9067,7 +9067,7 @@ apollo-server-express@^2.16.1, apollo-server-express@^2.21.0: "@types/express" "^4.17.12" "@types/express-serve-static-core" "^4.17.21" accepts "^1.3.5" - apollo-server-core "^2.25.2" + apollo-server-core "^2.25.3" apollo-server-types "^0.9.0" body-parser "^1.18.3" cors "^2.8.5" @@ -9095,12 +9095,12 @@ apollo-server-types@^0.9.0: apollo-server-env "^3.1.0" apollo-server@^2.16.1: - version "2.21.0" - resolved "https://registry.npmjs.org/apollo-server/-/apollo-server-2.21.0.tgz#4e62131885b4a8a26bb8b5e77177bd0d4d210852" - integrity sha512-OqngjOSB0MEH6VKGWHcrqt4y39HlhYh9CrMvn4PhadTt53IPYRmBglk5qSRA8xMorGqy60iKrOReqj5YfCjTOg== + version "2.25.3" + resolved "https://registry.npmjs.org/apollo-server/-/apollo-server-2.25.3.tgz#2e5db9ce5217389625ac5014551dcbdeeedcd1d8" + integrity sha512-+eUY2//DLkU7RkJLn6CTl1P89/ZMHuUQnWqv8La2iJ2hLT7Me+nMx+hgHl3LqlT/qDstQ8qA45T85FuCayplmQ== dependencies: - apollo-server-core "^2.21.0" - apollo-server-express "^2.21.0" + apollo-server-core "^2.25.3" + apollo-server-express "^2.25.3" express "^4.0.0" graphql-subscriptions "^1.0.0" graphql-tools "^4.0.8" From 5a85b802f33c5575453cf3fd1740102bc8d114b7 Mon Sep 17 00:00:00 2001 From: Jeremy Guarini Date: Mon, 8 Nov 2021 15:18:32 -0800 Subject: [PATCH 14/25] display X-axis in ascending order Signed-off-by: Jeremy Guarini --- .changeset/perfect-avocados-mate.md | 5 +++++ .../CoverageHistoryChart/CoverageHistoryChart.tsx | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 .changeset/perfect-avocados-mate.md diff --git a/.changeset/perfect-avocados-mate.md b/.changeset/perfect-avocados-mate.md new file mode 100644 index 0000000000..9394b57449 --- /dev/null +++ b/.changeset/perfect-avocados-mate.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-code-coverage': patch +--- + +Make dates in X-Axis sort in ascending order diff --git a/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx b/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx index 4291599098..e713eb7c6e 100644 --- a/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx +++ b/plugins/code-coverage/src/components/CoverageHistoryChart/CoverageHistoryChart.tsx @@ -158,7 +158,11 @@ export const CoverageHistoryChart = () => { margin={{ right: 48, top: 32 }} > - + From 910a6a435e4226474fab557120e8c70b06281aef Mon Sep 17 00:00:00 2001 From: Marley Powell Date: Tue, 9 Nov 2021 08:04:51 +0000 Subject: [PATCH 15/25] feat: Added new types to `@backstage/plugin-azure-devops-common`. Signed-off-by: Marley Powell --- .changeset/many-mayflies-notice.md | 5 ++- plugins/azure-devops-common/api-report.md | 43 +++++++++++++++++++++ plugins/azure-devops-common/src/types.ts | 46 +++++++++++++++++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) diff --git a/.changeset/many-mayflies-notice.md b/.changeset/many-mayflies-notice.md index cd4f91fa93..a96d1fcce5 100644 --- a/.changeset/many-mayflies-notice.md +++ b/.changeset/many-mayflies-notice.md @@ -1,6 +1,9 @@ --- '@backstage/plugin-azure-devops': patch '@backstage/plugin-azure-devops-backend': minor +'@backstage/plugin-azure-devops-common': patch --- -refactor(`@backstage/plugin-azure-devops`): Consume types from `@backstage/plugin-azure-devops-common`. Stop re-exporting types from `@backstage/plugin-azure-devops-backend`. +refactor(`@backstage/plugin-azure-devops`): Consume types from `@backstage/plugin-azure-devops-common`. +Stop re-exporting types from `@backstage/plugin-azure-devops-backend`. +Added new types to `@backstage/plugin-azure-devops-common`. diff --git a/plugins/azure-devops-common/api-report.md b/plugins/azure-devops-common/api-report.md index 0bc6568189..f03c0b4059 100644 --- a/plugins/azure-devops-common/api-report.md +++ b/plugins/azure-devops-common/api-report.md @@ -27,6 +27,42 @@ export enum BuildStatus { Postponed = 8, } +// Warning: (ae-missing-release-tag) "PullRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type PullRequest = { + pullRequestId?: number; + repoName?: string; + title?: string; + uniqueName?: string; + createdBy?: string; + creationDate?: Date; + sourceRefName?: string; + targetRefName?: string; + status?: PullRequestStatus; + isDraft?: boolean; + link: string; +}; + +// Warning: (ae-missing-release-tag) "PullRequestOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type PullRequestOptions = { + top: number; + status: PullRequestStatus; +}; + +// Warning: (ae-missing-release-tag) "PullRequestStatus" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export enum PullRequestStatus { + Abandoned = 2, + Active = 1, + All = 4, + Completed = 3, + NotSet = 0, +} + // Warning: (ae-missing-release-tag) "RepoBuild" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -43,5 +79,12 @@ export type RepoBuild = { uniqueName?: string; }; +// Warning: (ae-missing-release-tag) "RepoBuildOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type RepoBuildOptions = { + top?: number; +}; + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/azure-devops-common/src/types.ts b/plugins/azure-devops-common/src/types.ts index d7736d03e1..eacc2af30d 100644 --- a/plugins/azure-devops-common/src/types.ts +++ b/plugins/azure-devops-common/src/types.ts @@ -80,3 +80,49 @@ export type RepoBuild = { source: string; uniqueName?: string; }; + +export type RepoBuildOptions = { + top?: number; +}; + +export enum PullRequestStatus { + /** + * Status not set. Default state. + */ + NotSet = 0, + /** + * Pull request is active. + */ + Active = 1, + /** + * Pull request is abandoned. + */ + Abandoned = 2, + /** + * Pull request is completed. + */ + Completed = 3, + /** + * Used in pull request search criteria to include all statuses. + */ + All = 4, +} + +export type PullRequest = { + pullRequestId?: number; + repoName?: string; + title?: string; + uniqueName?: string; + createdBy?: string; + creationDate?: Date; + sourceRefName?: string; + targetRefName?: string; + status?: PullRequestStatus; + isDraft?: boolean; + link: string; +}; + +export type PullRequestOptions = { + top: number; + status: PullRequestStatus; +}; From e059aea7b9b5a93616b35216cefadfb7f35e5c79 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 9 Nov 2021 09:36:42 +0100 Subject: [PATCH 16/25] core-plugin-api: Deprecate unused types Signed-off-by: Johan Haals --- .changeset/young-steaks-punch.md | 5 +++++ packages/core-plugin-api/src/apis/system/types.ts | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 .changeset/young-steaks-punch.md diff --git a/.changeset/young-steaks-punch.md b/.changeset/young-steaks-punch.md new file mode 100644 index 0000000000..55997af565 --- /dev/null +++ b/.changeset/young-steaks-punch.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-plugin-api': patch +--- + +Deprecate unused ApiRef types diff --git a/packages/core-plugin-api/src/apis/system/types.ts b/packages/core-plugin-api/src/apis/system/types.ts index d7801ea5c1..a449e83450 100644 --- a/packages/core-plugin-api/src/apis/system/types.ts +++ b/packages/core-plugin-api/src/apis/system/types.ts @@ -35,6 +35,7 @@ export type AnyApiRef = ApiRef; * Transforms ApiRef type into its inner API type. * * @public + * @deprecated unused type. */ export type ApiRefType = T extends ApiRef ? U : never; @@ -51,6 +52,7 @@ export type TypesToApiRefs = { [key in keyof T]: ApiRef }; * Reverse type transform of {@link TypesToApiRefs}. * * @public + * @deprecated unused type. */ export type ApiRefsToTypes }> = { [key in keyof T]: ApiRefType; From de527c6e33f1a7ddb9d12a3c280fdbf62c86c48e Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 9 Nov 2021 09:49:55 +0100 Subject: [PATCH 17/25] api report Signed-off-by: Johan Haals --- packages/core-plugin-api/api-report.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core-plugin-api/api-report.md b/packages/core-plugin-api/api-report.md index 3225c1a28f..acfc8d4a45 100644 --- a/packages/core-plugin-api/api-report.md +++ b/packages/core-plugin-api/api-report.md @@ -142,7 +142,7 @@ export type ApiRefConfig = { description?: string; }; -// @public +// @public @deprecated export type ApiRefsToTypes< T extends { [key in string]: ApiRef; @@ -151,7 +151,7 @@ export type ApiRefsToTypes< [key in keyof T]: ApiRefType; }; -// @public +// @public @deprecated export type ApiRefType = T extends ApiRef ? U : never; // @public From 6160f89865d19005b6a59531c0e8b098b1f69300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 9 Nov 2021 10:10:13 +0100 Subject: [PATCH 18/25] fake the test config to get rid of the timeouts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- plugins/proxy-backend/src/service/router.test.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/plugins/proxy-backend/src/service/router.test.ts b/plugins/proxy-backend/src/service/router.test.ts index 11a1068b68..df999dbe2a 100644 --- a/plugins/proxy-backend/src/service/router.test.ts +++ b/plugins/proxy-backend/src/service/router.test.ts @@ -14,11 +14,8 @@ * limitations under the License. */ -import { - getVoidLogger, - loadBackendConfig, - SingleHostDiscovery, -} from '@backstage/backend-common'; +import { getVoidLogger, SingleHostDiscovery } from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; import { Request, Response } from 'express'; import * as http from 'http'; import { createProxyMiddleware, Options } from 'http-proxy-middleware'; @@ -35,7 +32,14 @@ const mockCreateProxyMiddleware = createProxyMiddleware as jest.MockedFunction< describe('createRouter', () => { it('works', async () => { const logger = getVoidLogger(); - const config = await loadBackendConfig({ logger, argv: [] }); + const config = new ConfigReader({ + backend: { + baseUrl: 'https://example.com:7000', + listen: { + port: 7000, + }, + }, + }); const discovery = SingleHostDiscovery.fromConfig(config); const router = await createRouter({ config, From afe864b872f3d93654639b44d2f1a652e001c843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 9 Nov 2021 10:35:13 +0100 Subject: [PATCH 19/25] get rid of config loading here too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../src/service/KubernetesBuilder.test.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts index 1b90e65fd7..de0dcdf373 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts @@ -14,11 +14,11 @@ * limitations under the License. */ -import { Config } from '@backstage/config'; -import { getVoidLogger, loadBackendConfig } from '@backstage/backend-common'; +import { getVoidLogger } from '@backstage/backend-common'; +import { Config, ConfigReader } from '@backstage/config'; +import { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common'; import express from 'express'; import request from 'supertest'; -import { KubernetesFanOutHandler } from './KubernetesFanOutHandler'; import { ClusterDetails, FetchResponseWrapper, @@ -27,8 +27,8 @@ import { KubernetesServiceLocator, ObjectFetchParams, } from '../types/types'; -import { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common'; import { KubernetesBuilder } from './KubernetesBuilder'; +import { KubernetesFanOutHandler } from './KubernetesFanOutHandler'; describe('KubernetesBuilder', () => { let app: express.Express; @@ -37,7 +37,12 @@ describe('KubernetesBuilder', () => { beforeAll(async () => { const logger = getVoidLogger(); - config = await loadBackendConfig({ logger, argv: [] }); + config = new ConfigReader({ + kubernetes: { + serviceLocatorMethod: { type: 'multiTenant' }, + clusterLocatorMethods: [{ type: 'config', clusters: [] }], + }, + }); const clusters: ClusterDetails[] = [ { From 00af71a8fc924d603b93ce91387e53cbc1cffff9 Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Tue, 9 Nov 2021 10:42:21 +0100 Subject: [PATCH 20/25] Filter out undefined keys from settings Signed-off-by: Marcus Eide --- .../auth-backend/src/identity/KeyStores.ts | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/plugins/auth-backend/src/identity/KeyStores.ts b/plugins/auth-backend/src/identity/KeyStores.ts index 74e60a0502..3d238adba9 100644 --- a/plugins/auth-backend/src/identity/KeyStores.ts +++ b/plugins/auth-backend/src/identity/KeyStores.ts @@ -15,6 +15,7 @@ */ import { Logger } from 'winston'; +import { pickBy } from 'lodash'; import { PluginDatabaseManager } from '@backstage/backend-common'; import { Config } from '@backstage/config'; @@ -64,16 +65,20 @@ export class KeyStores { if (provider === 'firestore') { const settings = ks?.getConfig(provider); - const keyStore = await FirestoreKeyStore.create({ - projectId: settings?.getOptionalString('projectId'), - keyFilename: settings?.getOptionalString('keyFilename'), - host: settings?.getOptionalString('host'), - port: settings?.getOptionalNumber('port'), - ssl: settings?.getOptionalBoolean('ssl'), - path: settings?.getOptionalString('path'), - timeout: settings?.getOptionalNumber('timeout'), - }); - + const keyStore = await FirestoreKeyStore.create( + pickBy( + { + projectId: settings?.getOptionalString('projectId'), + keyFilename: settings?.getOptionalString('keyFilename'), + host: settings?.getOptionalString('host'), + port: settings?.getOptionalNumber('port'), + ssl: settings?.getOptionalBoolean('ssl'), + path: settings?.getOptionalString('path'), + timeout: settings?.getOptionalNumber('timeout'), + }, + value => value !== undefined, + ), + ); await FirestoreKeyStore.verifyConnection(keyStore, logger); return keyStore; From 5ee31f860b412566ffaddd1c49115cb47ffe34ff Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Tue, 9 Nov 2021 10:44:26 +0100 Subject: [PATCH 21/25] Add changeset Signed-off-by: Marcus Eide --- .changeset/modern-beers-tickle.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/modern-beers-tickle.md diff --git a/.changeset/modern-beers-tickle.md b/.changeset/modern-beers-tickle.md new file mode 100644 index 0000000000..6ad9cc872d --- /dev/null +++ b/.changeset/modern-beers-tickle.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Only use settings that have a value when creating a new FirestoreKeyStore instance From 4fa7934710a162b24e730a2655d60fee52c4418e Mon Sep 17 00:00:00 2001 From: Harry Hogg Date: Tue, 9 Nov 2021 10:02:36 +0000 Subject: [PATCH 22/25] Added runson command to fix the workflow config Signed-off-by: Harry Hogg --- .github/workflows/snyk-github-issue-sync.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/snyk-github-issue-sync.yml b/.github/workflows/snyk-github-issue-sync.yml index 34eb5c1ca4..4f29e43215 100644 --- a/.github/workflows/snyk-github-issue-sync.yml +++ b/.github/workflows/snyk-github-issue-sync.yml @@ -6,6 +6,7 @@ on: jobs: sync: + runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Create Snyk report From ce4457bb305088eca9700c03bb4fd04cfcbbc93d Mon Sep 17 00:00:00 2001 From: Harry Hogg Date: Tue, 9 Nov 2021 12:36:01 +0000 Subject: [PATCH 23/25] Fixes the Snyk github issue workflow to continue when the Snyk CLI exits with an error Signed-off-by: Harry Hogg --- .github/workflows/snyk-github-issue-sync.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/snyk-github-issue-sync.yml b/.github/workflows/snyk-github-issue-sync.yml index 4f29e43215..5f49be4e1a 100644 --- a/.github/workflows/snyk-github-issue-sync.yml +++ b/.github/workflows/snyk-github-issue-sync.yml @@ -11,6 +11,7 @@ jobs: - uses: actions/checkout@v2 - name: Create Snyk report uses: snyk/actions/node@master + continue-on-error: true # Snyk CLI exits with error when vulnerabilities are found with: args: > --yarn-workspaces From 1921f70aa744b386b45eb53862f21efbe2c222cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 9 Nov 2021 14:50:21 +0100 Subject: [PATCH 24/25] revert the graphql package pinning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/seven-zoos-sparkle.md | 14 +++++++ package.json | 4 +- .../templates/default-app/package.json.hbs | 4 -- yarn.lock | 41 +++++++++++-------- 4 files changed, 38 insertions(+), 25 deletions(-) create mode 100644 .changeset/seven-zoos-sparkle.md diff --git a/.changeset/seven-zoos-sparkle.md b/.changeset/seven-zoos-sparkle.md new file mode 100644 index 0000000000..1399c3254e --- /dev/null +++ b/.changeset/seven-zoos-sparkle.md @@ -0,0 +1,14 @@ +--- +'@backstage/create-app': patch +--- + +Removed the version pinning of the packages `graphql-language-service-interface` and `graphql-language-service-parser`. This should no longer be necessary. + +You can apply the same change in your repository by ensuring that the following does _NOT_ appear in your root `package.json`. + +```json +"resolutions": { + "graphql-language-service-interface": "2.8.2", + "graphql-language-service-parser": "1.9.0" + }, +``` diff --git a/package.json b/package.json index 62a8a0924e..03dd289653 100644 --- a/package.json +++ b/package.json @@ -46,9 +46,7 @@ "resolutions": { "**/@graphql-codegen/cli/**/ws": "^7.4.6", "**/@roadiehq/**/@backstage/plugin-catalog": "*", - "**/@roadiehq/**/@backstage/catalog-model": "*", - "graphql-language-service-interface": "2.8.2", - "graphql-language-service-parser": "1.9.0" + "**/@roadiehq/**/@backstage/catalog-model": "*" }, "version": "1.0.0", "dependencies": { diff --git a/packages/create-app/templates/default-app/package.json.hbs b/packages/create-app/templates/default-app/package.json.hbs index 5ed066a30b..638caf6a2f 100644 --- a/packages/create-app/templates/default-app/package.json.hbs +++ b/packages/create-app/templates/default-app/package.json.hbs @@ -23,10 +23,6 @@ "create-plugin": "backstage-cli create-plugin --scope internal --no-private", "remove-plugin": "backstage-cli remove-plugin" }, - "resolutions": { - "graphql-language-service-interface": "2.8.2", - "graphql-language-service-parser": "1.9.0" - }, "workspaces": { "packages": [ "packages/*", diff --git a/yarn.lock b/yarn.lock index b5786626dd..34421fdae7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15591,20 +15591,20 @@ graphql-extensions@^0.15.0: apollo-server-env "^3.1.0" apollo-server-types "^0.9.0" -graphql-language-service-interface@2.8.2, graphql-language-service-interface@^2.9.0: - version "2.8.2" - resolved "https://registry.npmjs.org/graphql-language-service-interface/-/graphql-language-service-interface-2.8.2.tgz#b3bb2aef7eaf0dff0b4ea419fa412c5f66fa268b" - integrity sha512-otbOQmhgkAJU1QJgQkMztNku6SbJLu/uodoFOYOOtJsizTjrMs93vkYaHCcYnLA3oi1Goj27XcHjMnRCYQOZXQ== +graphql-language-service-interface@^2.9.0: + version "2.9.1" + resolved "https://registry.npmjs.org/graphql-language-service-interface/-/graphql-language-service-interface-2.9.1.tgz#be0b11b06b78730ea9d250e0e2290e7ed9c8d283" + integrity sha512-yGsE67fxJBXxY82+rLDMvUpmzpOUM8XFB+k+xOTUyABWs27osKaoGiuDDXAVGg1adhm+cpunWbipe763ZJkAVA== dependencies: - graphql-language-service-parser "^1.9.0" - graphql-language-service-types "^1.8.0" - graphql-language-service-utils "^2.5.1" + graphql-language-service-parser "^1.10.0" + graphql-language-service-types "^1.8.3" + graphql-language-service-utils "^2.6.0" vscode-languageserver-types "^3.15.1" -graphql-language-service-parser@1.9.0, graphql-language-service-parser@^1.10.0, graphql-language-service-parser@^1.9.0: - version "1.9.0" - resolved "https://registry.npmjs.org/graphql-language-service-parser/-/graphql-language-service-parser-1.9.0.tgz#79af21294119a0a7e81b6b994a1af36833bab724" - integrity sha512-B5xPZLbBmIp0kHvpY1Z35I5DtPoDK9wGxQVRDIzcBaiIvAmlTrDvjo3bu7vKREdjFbYKvWNgrEWENuprMbF17Q== +graphql-language-service-parser@^1.10.0: + version "1.10.0" + resolved "https://registry.npmjs.org/graphql-language-service-parser/-/graphql-language-service-parser-1.10.0.tgz#116f4be849754f6afb4c196421a43fe96d87b278" + integrity sha512-cLExv0EjqT2hsKdwVTPmKU6eMfjZAjxqywgCPnWD48eJn6tyuePMyG7ye+jpX1PRPPx/cDHfFJGf8sUclchvng== dependencies: graphql-language-service-types "^1.8.0" @@ -15618,13 +15618,10 @@ graphql-language-service-types@^1.8.2: resolved "https://registry.npmjs.org/graphql-language-service-types/-/graphql-language-service-types-1.8.2.tgz#50ae56f69cc24fcfc3daa129b68b0eb9421e8578" integrity sha512-Sj07RHnMwAhEvAt7Jdt1l/x56ZpoNh+V6g+T58CF6GiYqI5l4vXqqRB4d4xHDcNQX98GpJfnf3o8BqPgP3C5Sw== -graphql-language-service-utils@^2.5.1: - version "2.5.1" - resolved "https://registry.npmjs.org/graphql-language-service-utils/-/graphql-language-service-utils-2.5.1.tgz#832ad4b0a9da03fdded756932c27e057ccf71302" - integrity sha512-Lzz723cYrYlVN4WVzIyFGg3ogoe+QYAIBfdtDboiIILoy0FTmqbyC2TOErqbmWKqO4NK9xDA95cSRFbWiHYj0g== - dependencies: - graphql-language-service-types "^1.8.0" - nullthrows "^1.0.0" +graphql-language-service-types@^1.8.3: + version "1.8.3" + resolved "https://registry.npmjs.org/graphql-language-service-types/-/graphql-language-service-types-1.8.3.tgz#d7d688d74c122c4d9cc4cceae761a1f2a3c396a1" + integrity sha512-m+RHnlGkKDcesW/gC4M7I2pSmWJB84uWS6LtnjplO/07JN312nJCJYCwV/DBny2m1fmSOxN7H/o+JW0l56KwBA== graphql-language-service-utils@^2.5.3: version "2.5.3" @@ -15634,6 +15631,14 @@ graphql-language-service-utils@^2.5.3: graphql-language-service-types "^1.8.0" nullthrows "^1.0.0" +graphql-language-service-utils@^2.6.0: + version "2.6.0" + resolved "https://registry.npmjs.org/graphql-language-service-utils/-/graphql-language-service-utils-2.6.0.tgz#d04904641248167ccbb381d8705ba97daa784954" + integrity sha512-idqwmbREixhDuQMcYp8WH0btQT02xZny8MO/HduNTVjnPrmTYnZUbpZ9AejdflmaKoS0o8nNvgXQ0GpIOzbG5g== + dependencies: + graphql-language-service-types "^1.8.3" + nullthrows "^1.0.0" + graphql-language-service@^3.1.6: version "3.2.0" resolved "https://registry.npmjs.org/graphql-language-service/-/graphql-language-service-3.2.0.tgz#e0eb6d5dea2cab92549a253d7a6b4fa0cce178b7" From b152c2a1e4233a2f1ddc1ad7fef0f7f1c6fe29d9 Mon Sep 17 00:00:00 2001 From: Jonas Thomsen Date: Tue, 9 Nov 2021 15:25:48 +0100 Subject: [PATCH 25/25] Update ADOPTERS.md --- ADOPTERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ADOPTERS.md b/ADOPTERS.md index f0b2fa16f6..6736538fa0 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -64,3 +64,4 @@ | [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. | | [Volvofinans Bank](https://www.volvofinans.se) | [Johan Hammar](https://github.com/johanhammar) | Developer portal enabling engineers to manage and explore software and documentation. | | [Palo Alto Networks](https://www.paloaltonetworks.com) | [Jeremy Guarini](https://github.com/jeremyguarini), [Brian Lomeland](https://github.com/bbbmmmlll), [Palo Alto Networks](https://github.com/PaloAltoNetworks) | Developer portal, service catalog, documentation and tooling | +| [Signal Iduna Group](https://www.signal-iduna.de/) | [Jonas Thomsen](https://github.com/JoThomsen) | Developer Portal, documentation, monitoring, service catalog for our insurance ecosystem