From 8f253285a1b37db4e253fe6f8a16259e596075a9 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 8 Dec 2021 15:56:36 +0100 Subject: [PATCH 01/20] chore(deps-dev): bump @types/tar from 4.0.5 to 6.1.1 Signed-off-by: Johan Haals --- packages/backend-common/package.json | 2 +- packages/cli/package.json | 2 +- yarn.lock | 8 ++++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index e46d659175..8296f59ef5 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -94,7 +94,7 @@ "@types/recursive-readdir": "^2.2.0", "@types/stoppable": "^1.1.0", "@types/supertest": "^2.0.8", - "@types/tar": "^4.0.3", + "@types/tar": "^6.1.1", "@types/unzipper": "^0.10.3", "@types/webpack-env": "^1.15.2", "aws-sdk-mock": "^5.2.1", diff --git a/packages/cli/package.json b/packages/cli/package.json index 0a6b2b934a..7804623b50 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -134,7 +134,7 @@ "@types/recursive-readdir": "^2.2.0", "@types/rollup-plugin-peer-deps-external": "^2.2.0", "@types/rollup-plugin-postcss": "^2.0.0", - "@types/tar": "^4.0.3", + "@types/tar": "^6.1.1", "@types/terser-webpack-plugin": "^5.0.4", "@types/webpack": "^5.28.0", "@types/webpack-dev-server": "^3.11.5", diff --git a/yarn.lock b/yarn.lock index f1c17c0022..6f4aab1631 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8330,6 +8330,14 @@ "@types/minipass" "*" "@types/node" "*" +"@types/tar@^6.1.1": + version "6.1.1" + resolved "https://registry.npmjs.org/@types/tar/-/tar-6.1.1.tgz#ab341ec1f149d7eb2a4f4ded56ff85f0d4fe7cb5" + integrity sha512-8mto3YZfVpqB1CHMaYz1TUYIQfZFbh/QbEq5Hsn6D0ilCfqRVCdalmc89B7vi3jhl9UYIk+dWDABShNfOkv5HA== + dependencies: + "@types/minipass" "*" + "@types/node" "*" + "@types/tern@*": version "0.23.3" resolved "https://registry.npmjs.org/@types/tern/-/tern-0.23.3.tgz#4b54538f04a88c9ff79de1f6f94f575a7f339460" From c7930a7330bec25540642227e662de845d75831c Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 8 Dec 2021 16:00:00 +0100 Subject: [PATCH 02/20] add changeset Signed-off-by: Johan Haals --- .changeset/cold-otters-prove.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/cold-otters-prove.md diff --git a/.changeset/cold-otters-prove.md b/.changeset/cold-otters-prove.md new file mode 100644 index 0000000000..5b41f8906c --- /dev/null +++ b/.changeset/cold-otters-prove.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-common': patch +'@backstage/cli': patch +--- + +chore(deps-dev): bump @types/tar from 4.0.5 to 6.1.1 From 9b093a488adf4e9b556c9f0503c7642e1eef5cf1 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 8 Dec 2021 16:15:41 +0100 Subject: [PATCH 03/20] Update .changeset/cold-otters-prove.md Signed-off-by: Johan Haals Co-authored-by: Ben Lambert --- .changeset/cold-otters-prove.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/cold-otters-prove.md b/.changeset/cold-otters-prove.md index 5b41f8906c..37438b333e 100644 --- a/.changeset/cold-otters-prove.md +++ b/.changeset/cold-otters-prove.md @@ -3,4 +3,4 @@ '@backstage/cli': patch --- -chore(deps-dev): bump @types/tar from 4.0.5 to 6.1.1 +chore(deps-dev): bump `@types/tar` from 4.0.5 to 6.1.1 From 189ba4c340a910e127345e01b3221b6d1e7eaf77 Mon Sep 17 00:00:00 2001 From: Joe Porpeglia Date: Fri, 3 Dec 2021 15:50:09 -0500 Subject: [PATCH 04/20] Overwrite sqlite filepath per plugin Signed-off-by: Joe Porpeglia --- .../src/database/DatabaseManager.test.ts | 5 ++++- .../src/database/DatabaseManager.ts | 12 +++++++--- .../src/database/connectors/sqlite3.test.ts | 22 ------------------- .../src/database/connectors/sqlite3.ts | 13 ----------- 4 files changed, 13 insertions(+), 39 deletions(-) diff --git a/packages/backend-common/src/database/DatabaseManager.test.ts b/packages/backend-common/src/database/DatabaseManager.test.ts index bd2e7b9f71..d5271bc2b5 100644 --- a/packages/backend-common/src/database/DatabaseManager.test.ts +++ b/packages/backend-common/src/database/DatabaseManager.test.ts @@ -282,7 +282,10 @@ describe('DatabaseManager', () => { expect(baseConfig.get().client).toEqual('sqlite3'); // sqlite3 uses 'filename' instead of 'database' - expect(overrides).toHaveProperty('connection.filename'); + expect(overrides).toHaveProperty( + 'connection.filename', + `plugin_with_different_client/${pluginId}`, + ); }); it('provides database client specific base from plugin connection string when client set under plugin', async () => { diff --git a/packages/backend-common/src/database/DatabaseManager.ts b/packages/backend-common/src/database/DatabaseManager.ts index 8e23a219ec..977516a18b 100644 --- a/packages/backend-common/src/database/DatabaseManager.ts +++ b/packages/backend-common/src/database/DatabaseManager.ts @@ -114,10 +114,16 @@ export class DatabaseManager { const connection = this.getConnectionConfig(pluginId); if (this.getClientType(pluginId).client === 'sqlite3') { + const sqliteFilename = (connection as Knex.Sqlite3ConnectionConfig) + ?.filename; + + // if persisting to a file, create separate files per plugin to avoid db migration issues. + if (sqliteFilename !== ':memory:') { + return `${sqliteFilename}/${pluginId}`; + } + // sqlite database name should fallback to ':memory:' as a special case - return ( - (connection as Knex.Sqlite3ConnectionConfig)?.filename ?? ':memory:' - ); + return ':memory:'; } const databaseName = (connection as Knex.ConnectionConfig)?.database; diff --git a/packages/backend-common/src/database/connectors/sqlite3.test.ts b/packages/backend-common/src/database/connectors/sqlite3.test.ts index b9da19d247..cfc9f61527 100644 --- a/packages/backend-common/src/database/connectors/sqlite3.test.ts +++ b/packages/backend-common/src/database/connectors/sqlite3.test.ts @@ -73,28 +73,6 @@ describe('sqlite3', () => { }); }); - it('builds a persistent connection per database', () => { - expect( - buildSqliteDatabaseConfig( - createConfig({ - filename: path.join('path', 'to', 'foo'), - }), - { - connection: { - database: 'my-database', - }, - }, - ), - ).toEqual({ - client: 'sqlite3', - connection: { - filename: path.join('path', 'to', 'foo', 'my-database.sqlite'), - database: 'my-database', - }, - useNullAsDefault: true, - }); - }); - it('replaces the connection with an override', () => { expect( buildSqliteDatabaseConfig(createConfig(':memory:'), { diff --git a/packages/backend-common/src/database/connectors/sqlite3.ts b/packages/backend-common/src/database/connectors/sqlite3.ts index 3dfecd7e6b..41f80ed293 100644 --- a/packages/backend-common/src/database/connectors/sqlite3.ts +++ b/packages/backend-common/src/database/connectors/sqlite3.ts @@ -86,19 +86,6 @@ export function buildSqliteDatabaseConfig( overrides, ); - // If we don't create an in-memory database, interpret the connection string - // as a directory that contains multiple sqlite files based on the database - // name. - const database = (config.connection as Knex.ConnectionConfig).database; - const sqliteConnection = config.connection as Knex.Sqlite3ConnectionConfig; - - if (database && sqliteConnection.filename !== ':memory:') { - sqliteConnection.filename = path.join( - sqliteConnection.filename, - `${database}.sqlite`, - ); - } - return config; } From e51369952ed91364d217ca560e113fe4b559a993 Mon Sep 17 00:00:00 2001 From: Joe Porpeglia Date: Fri, 3 Dec 2021 16:07:30 -0500 Subject: [PATCH 05/20] Add suffix to plugin sqlite db file Signed-off-by: Joe Porpeglia --- packages/backend-common/src/database/DatabaseManager.test.ts | 2 +- packages/backend-common/src/database/DatabaseManager.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend-common/src/database/DatabaseManager.test.ts b/packages/backend-common/src/database/DatabaseManager.test.ts index d5271bc2b5..2587a70423 100644 --- a/packages/backend-common/src/database/DatabaseManager.test.ts +++ b/packages/backend-common/src/database/DatabaseManager.test.ts @@ -284,7 +284,7 @@ describe('DatabaseManager', () => { // sqlite3 uses 'filename' instead of 'database' expect(overrides).toHaveProperty( 'connection.filename', - `plugin_with_different_client/${pluginId}`, + `plugin_with_different_client/${pluginId}.sqlite`, ); }); diff --git a/packages/backend-common/src/database/DatabaseManager.ts b/packages/backend-common/src/database/DatabaseManager.ts index 977516a18b..aee47aedc1 100644 --- a/packages/backend-common/src/database/DatabaseManager.ts +++ b/packages/backend-common/src/database/DatabaseManager.ts @@ -119,7 +119,7 @@ export class DatabaseManager { // if persisting to a file, create separate files per plugin to avoid db migration issues. if (sqliteFilename !== ':memory:') { - return `${sqliteFilename}/${pluginId}`; + return `${sqliteFilename}/${pluginId}.sqlite`; } // sqlite database name should fallback to ':memory:' as a special case From fe24bc9a323afd69fb44ab410b910ea84a1be057 Mon Sep 17 00:00:00 2001 From: Joe Porpeglia Date: Fri, 3 Dec 2021 16:14:55 -0500 Subject: [PATCH 06/20] Add changeset Signed-off-by: Joe Porpeglia --- .changeset/pink-ladybugs-share.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/pink-ladybugs-share.md diff --git a/.changeset/pink-ladybugs-share.md b/.changeset/pink-ladybugs-share.md new file mode 100644 index 0000000000..c8f2e8f206 --- /dev/null +++ b/.changeset/pink-ladybugs-share.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': minor +--- + +Each plugin now saves to a separate sqlite database file when `connection.filename` is provided in the sqlite config. From ef8392dab249014fe7a51e152bde8d4dc2e42e43 Mon Sep 17 00:00:00 2001 From: Joe Porpeglia Date: Mon, 6 Dec 2021 11:24:09 -0500 Subject: [PATCH 07/20] Use path.join Signed-off-by: Joe Porpeglia --- packages/backend-common/src/database/DatabaseManager.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/backend-common/src/database/DatabaseManager.ts b/packages/backend-common/src/database/DatabaseManager.ts index aee47aedc1..b026e83b4e 100644 --- a/packages/backend-common/src/database/DatabaseManager.ts +++ b/packages/backend-common/src/database/DatabaseManager.ts @@ -28,6 +28,7 @@ import { normalizeConnection, } from './connection'; import { PluginDatabaseManager } from './types'; +import path from 'path'; /** * Provides a config lookup path for a plugin's config block. @@ -119,7 +120,7 @@ export class DatabaseManager { // if persisting to a file, create separate files per plugin to avoid db migration issues. if (sqliteFilename !== ':memory:') { - return `${sqliteFilename}/${pluginId}.sqlite`; + return path.join(sqliteFilename, `${pluginId}.sqlite`); } // sqlite database name should fallback to ':memory:' as a special case From c2a478d7f948c63db8b2e3dc23e64090048eca4b Mon Sep 17 00:00:00 2001 From: Joe Porpeglia Date: Mon, 6 Dec 2021 11:26:10 -0500 Subject: [PATCH 08/20] Update changeset Signed-off-by: Joe Porpeglia --- .changeset/pink-ladybugs-share.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.changeset/pink-ladybugs-share.md b/.changeset/pink-ladybugs-share.md index c8f2e8f206..7edeb12f6a 100644 --- a/.changeset/pink-ladybugs-share.md +++ b/.changeset/pink-ladybugs-share.md @@ -1,5 +1,6 @@ --- -'@backstage/backend-common': minor +'@backstage/backend-common': path --- Each plugin now saves to a separate sqlite database file when `connection.filename` is provided in the sqlite config. +Any existing sqlite database files will be ignored. From e081edc783bd9da4594ae3619d2f5ad50ee0c4da Mon Sep 17 00:00:00 2001 From: Joe Porpeglia Date: Mon, 6 Dec 2021 11:34:31 -0500 Subject: [PATCH 09/20] Fix changset typo Signed-off-by: Joe Porpeglia --- .changeset/pink-ladybugs-share.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/pink-ladybugs-share.md b/.changeset/pink-ladybugs-share.md index 7edeb12f6a..83f5b8b78a 100644 --- a/.changeset/pink-ladybugs-share.md +++ b/.changeset/pink-ladybugs-share.md @@ -1,5 +1,5 @@ --- -'@backstage/backend-common': path +'@backstage/backend-common': patch --- Each plugin now saves to a separate sqlite database file when `connection.filename` is provided in the sqlite config. From cf192e1a724368230f97d4fa1a6b98cac6266638 Mon Sep 17 00:00:00 2001 From: Joe Porpeglia Date: Mon, 6 Dec 2021 12:18:50 -0500 Subject: [PATCH 10/20] Check if sqlite filename was provided before making plugin-specific filename Signed-off-by: Joe Porpeglia --- packages/backend-common/src/database/DatabaseManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend-common/src/database/DatabaseManager.ts b/packages/backend-common/src/database/DatabaseManager.ts index b026e83b4e..a00a4991cb 100644 --- a/packages/backend-common/src/database/DatabaseManager.ts +++ b/packages/backend-common/src/database/DatabaseManager.ts @@ -119,7 +119,7 @@ export class DatabaseManager { ?.filename; // if persisting to a file, create separate files per plugin to avoid db migration issues. - if (sqliteFilename !== ':memory:') { + if (sqliteFilename && sqliteFilename !== ':memory:') { return path.join(sqliteFilename, `${pluginId}.sqlite`); } From d9a286bd56e3dd15b27f0b44daa148746ce3eea3 Mon Sep 17 00:00:00 2001 From: Joe Porpeglia Date: Wed, 8 Dec 2021 13:49:26 -0500 Subject: [PATCH 11/20] Use path.join for tests Signed-off-by: Joe Porpeglia --- packages/backend-common/src/database/DatabaseManager.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/backend-common/src/database/DatabaseManager.test.ts b/packages/backend-common/src/database/DatabaseManager.test.ts index 2587a70423..c72c740765 100644 --- a/packages/backend-common/src/database/DatabaseManager.test.ts +++ b/packages/backend-common/src/database/DatabaseManager.test.ts @@ -15,6 +15,7 @@ */ import { ConfigReader } from '@backstage/config'; import { omit } from 'lodash'; +import path from 'path'; import { createDatabaseClient, ensureDatabaseExists, @@ -284,7 +285,7 @@ describe('DatabaseManager', () => { // sqlite3 uses 'filename' instead of 'database' expect(overrides).toHaveProperty( 'connection.filename', - `plugin_with_different_client/${pluginId}.sqlite`, + path.join('plugin_with_different_client', `${pluginId}.sqlite`), ); }); From 63f5bc5f2cf699b0a479237331ad823dadd54ff5 Mon Sep 17 00:00:00 2001 From: Joe Porpeglia Date: Thu, 9 Dec 2021 17:59:56 -0500 Subject: [PATCH 12/20] Add connection.directory support for sqlite Signed-off-by: Joe Porpeglia --- .../src/database/DatabaseManager.test.ts | 128 ++++++++++++++---- .../src/database/DatabaseManager.ts | 27 +++- 2 files changed, 125 insertions(+), 30 deletions(-) diff --git a/packages/backend-common/src/database/DatabaseManager.test.ts b/packages/backend-common/src/database/DatabaseManager.test.ts index c72c740765..a48b1584aa 100644 --- a/packages/backend-common/src/database/DatabaseManager.test.ts +++ b/packages/backend-common/src/database/DatabaseManager.test.ts @@ -171,28 +171,6 @@ describe('DatabaseManager', () => { ); }); - it('uses top level sqlite database filename if plugin config is not present', async () => { - const testManager = DatabaseManager.fromConfig( - new ConfigReader({ - backend: { - database: { - client: 'sqlite3', - connection: 'some-file-path', - }, - }, - }), - ); - - await testManager.forPlugin('pluginwithoutconfig').getClient(); - const mockCalls = mocked(createDatabaseClient).mock.calls.splice(-1); - const [_, overrides] = mockCalls[0]; - - expect(overrides).toHaveProperty( - 'connection.filename', - expect.stringContaining('some-file-path'), - ); - }); - it('provides an inmemory sqlite database if top level is also inmemory and plugin config is not present', async () => { const testManager = DatabaseManager.fromConfig( new ConfigReader({ @@ -215,6 +193,110 @@ describe('DatabaseManager', () => { ); }); + it('throws if top level sqlite filename is provided', async () => { + const testManager = DatabaseManager.fromConfig( + new ConfigReader({ + backend: { + database: { + client: 'sqlite3', + connection: 'some-file-path', + }, + }, + }), + ); + + await expect( + testManager.forPlugin('pluginwithoutconfig').getClient(), + ).rejects.toBeInstanceOf(Error); + }); + + it('creates plugin-specific sqlite files when plugin config is not present', async () => { + const testManager = DatabaseManager.fromConfig( + new ConfigReader({ + backend: { + database: { + client: 'sqlite3', + connection: { + directory: 'sqlite-files', + }, + }, + }, + }), + ); + + await testManager.forPlugin('pluginwithoutconfig').getClient(); + const mockCalls = mocked(createDatabaseClient).mock.calls.splice(-1); + const [_, overrides] = mockCalls[0]; + + expect(overrides).toHaveProperty( + 'connection.filename', + path.join('sqlite-files', 'pluginwithoutconfig.sqlite'), + ); + }); + + it('uses sqlite directory from top level config and filename from plugin config', async () => { + const testManager = DatabaseManager.fromConfig( + new ConfigReader({ + backend: { + database: { + client: 'sqlite3', + connection: { + directory: 'sqlite-files', + }, + plugin: { + test: { + connection: { + filename: 'other.sqlite', + }, + }, + }, + }, + }, + }), + ); + + await testManager.forPlugin('test').getClient(); + const mockCalls = mocked(createDatabaseClient).mock.calls.splice(-1); + const [_, overrides] = mockCalls[0]; + + expect(overrides).toHaveProperty( + 'connection.filename', + path.join('sqlite-files', 'other.sqlite'), + ); + }); + + it('uses sqlite directory and filename from plugin config', async () => { + const testManager = DatabaseManager.fromConfig( + new ConfigReader({ + backend: { + database: { + client: 'sqlite3', + connection: { + directory: 'sqlite-files', + }, + plugin: { + test: { + connection: { + directory: 'custom-sqlite-files', + filename: 'other.sqlite', + }, + }, + }, + }, + }, + }), + ); + + await testManager.forPlugin('test').getClient(); + const mockCalls = mocked(createDatabaseClient).mock.calls.splice(-1); + const [_, overrides] = mockCalls[0]; + + expect(overrides).toHaveProperty( + 'connection.filename', + path.join('custom-sqlite-files', 'other.sqlite'), + ); + }); + it('connects to a plugin database using a specific database name', async () => { // testdbname.connection.database is set in config await manager.forPlugin('testdbname').getClient(); @@ -285,7 +367,7 @@ describe('DatabaseManager', () => { // sqlite3 uses 'filename' instead of 'database' expect(overrides).toHaveProperty( 'connection.filename', - path.join('plugin_with_different_client', `${pluginId}.sqlite`), + 'plugin_with_different_client', ); }); diff --git a/packages/backend-common/src/database/DatabaseManager.ts b/packages/backend-common/src/database/DatabaseManager.ts index a00a4991cb..5959c60c83 100644 --- a/packages/backend-common/src/database/DatabaseManager.ts +++ b/packages/backend-common/src/database/DatabaseManager.ts @@ -115,16 +115,18 @@ export class DatabaseManager { const connection = this.getConnectionConfig(pluginId); if (this.getClientType(pluginId).client === 'sqlite3') { - const sqliteFilename = (connection as Knex.Sqlite3ConnectionConfig) - ?.filename; + const sqliteFilename: string | undefined = ( + connection as Knex.Sqlite3ConnectionConfig + ).filename; - // if persisting to a file, create separate files per plugin to avoid db migration issues. - if (sqliteFilename && sqliteFilename !== ':memory:') { - return path.join(sqliteFilename, `${pluginId}.sqlite`); + if (sqliteFilename === ':memory:') { + return sqliteFilename; } - // sqlite database name should fallback to ':memory:' as a special case - return ':memory:'; + const sqliteDirectory = + (connection as { directory?: string }).directory ?? '.'; + + return path.join(sqliteDirectory, sqliteFilename ?? `${pluginId}.sqlite`); } const databaseName = (connection as Knex.ConnectionConfig)?.database; @@ -212,6 +214,17 @@ export class DatabaseManager { this.config.get('connection'), this.config.getString('client'), ); + + if ( + client === 'sqlite3' && + 'filename' in baseConnection && + baseConnection.filename !== ':memory:' + ) { + throw new Error( + '`connection.filename` is not supported for the base sqlite connection. Prefer `connection.directory` or provide a filename for the plugin connection instead.', + ); + } + // Databases cannot be shared unless the `pluginDivisionMode` is set to `schema`. The // `database` property from the base connection is omitted unless `pluginDivisionMode` // is set to `schema`. SQLite3's `filename` property is an exception as this is used as a From 760791a642e6f3b57ac6ef4dd3d43891633f0fa2 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 13 Dec 2021 14:54:27 +0100 Subject: [PATCH 13/20] core-plugin-api: auth request type renames and deprecations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Johan Haals Signed-off-by: Patrik Oldsberg --- .changeset/young-students-applaud.md | 11 +++ .../OAuthRequestApi/OAuthRequestManager.ts | 6 ++ packages/core-plugin-api/api-report.md | 49 ++++++++----- .../src/apis/definitions/OAuthRequestApi.ts | 68 ++++++++++--------- .../src/apis/definitions/auth.ts | 28 ++++++++ 5 files changed, 115 insertions(+), 47 deletions(-) create mode 100644 .changeset/young-students-applaud.md diff --git a/.changeset/young-students-applaud.md b/.changeset/young-students-applaud.md new file mode 100644 index 0000000000..bbd825cf00 --- /dev/null +++ b/.changeset/young-students-applaud.md @@ -0,0 +1,11 @@ +--- +'@backstage/core-plugin-api': patch +--- + +Renamed `AuthProvider` to `AuthProviderInfo` and add a required 'id' property to match the majority of usage. The `AuthProvider` type without the `id` property still exists but is deprecated, and all usage of it without an `id` is deprecated as well. For example, calling `createAuthRequest` without a `provider.id` is deprecated and it will be required in the future. + +The following types have been renamed. The old names are still exported but deprecated, and are scheduled for removal in a future release. + +- Renamed `AuthRequesterOptions` to `OAuthRequesterOptions` +- Renamed `AuthRequester` to `OAuthRequester` +- Renamed `PendingAuthRequest` to `PendingOAuthRequest` diff --git a/packages/core-app-api/src/apis/implementations/OAuthRequestApi/OAuthRequestManager.ts b/packages/core-app-api/src/apis/implementations/OAuthRequestApi/OAuthRequestManager.ts index 7e7f3c2507..a6b33f85d5 100644 --- a/packages/core-app-api/src/apis/implementations/OAuthRequestApi/OAuthRequestManager.ts +++ b/packages/core-app-api/src/apis/implementations/OAuthRequestApi/OAuthRequestManager.ts @@ -39,6 +39,12 @@ export class OAuthRequestManager implements OAuthRequestApi { private handlerCount = 0; createAuthRequester(options: AuthRequesterOptions): AuthRequester { + if (!options.provider.id) { + // eslint-disable-next-line no-console + console.warn( + 'DEPRECATION WARNING: Not passing a provider id to createAuthRequester is deprecated, it will be required in the future', + ); + } const handler = new OAuthPendingRequests(); const index = this.handlerCount; diff --git a/packages/core-plugin-api/api-report.md b/packages/core-plugin-api/api-report.md index d0ac0b5352..65fbbb7ed1 100644 --- a/packages/core-plugin-api/api-report.md +++ b/packages/core-plugin-api/api-report.md @@ -211,22 +211,21 @@ export const auth0AuthApiRef: ApiRef< OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi >; +// @public @deprecated (undocumented) +export type AuthProvider = Omit; + // @public -export type AuthProvider = { +export type AuthProviderInfo = { + id: string; title: string; icon: IconComponent; }; -// @public -export type AuthRequester = ( - scopes: Set, -) => Promise; +// @public @deprecated (undocumented) +export type AuthRequester = OAuthRequester; -// @public -export type AuthRequesterOptions = { - provider: AuthProvider; - onAuthRequest(scopes: Set): Promise; -}; +// @public @deprecated (undocumented) +export type AuthRequesterOptions = OAuthRequesterOptions; // @public export type AuthRequestOptions = { @@ -598,15 +597,28 @@ export type OAuthApi = { // @public export type OAuthRequestApi = { - createAuthRequester( - options: AuthRequesterOptions, - ): AuthRequester; + createAuthRequester( + options: OAuthRequesterOptions, + ): OAuthRequester; authRequest$(): Observable_2; }; // @public export const oauthRequestApiRef: ApiRef; +// @public +export type OAuthRequester = ( + scopes: Set, +) => Promise; + +// @public +export type OAuthRequesterOptions = { + provider: Omit & { + id?: string; + }; + onAuthRequest(scopes: Set): Promise; +}; + // @public export type OAuthScope = string | string[]; @@ -679,10 +691,15 @@ export type PathParams = { [name in ParamNames]: string; }; +// @public @deprecated (undocumented) +export type PendingAuthRequest = PendingOAuthRequest; + // @public -export type PendingAuthRequest = { - provider: AuthProvider; - reject: () => void; +export type PendingOAuthRequest = { + provider: Omit & { + id?: string; + }; + reject(): void; trigger(): Promise; }; diff --git a/packages/core-plugin-api/src/apis/definitions/OAuthRequestApi.ts b/packages/core-plugin-api/src/apis/definitions/OAuthRequestApi.ts index 03e129ef6a..b78cc310c3 100644 --- a/packages/core-plugin-api/src/apis/definitions/OAuthRequestApi.ts +++ b/packages/core-plugin-api/src/apis/definitions/OAuthRequestApi.ts @@ -14,31 +14,15 @@ * limitations under the License. */ -import { IconComponent } from '../../icons/types'; import { Observable } from '@backstage/types'; import { ApiRef, createApiRef } from '../system'; +import { AuthProviderInfo } from './auth'; /** - * 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 + * @deprecated Use AuthProviderInfo instead */ -export type AuthProvider = { - /** - * Title for the auth provider, for example "GitHub" - */ - title: string; - - /** - * Icon for the auth provider. - */ - icon: IconComponent; -}; +export type AuthProvider = Omit; /** * Describes how to handle auth requests. Both how to show them to the user, and what to do when @@ -46,26 +30,34 @@ export type AuthProvider = { * * @public */ -export type AuthRequesterOptions = { +export type OAuthRequesterOptions = { /** * Information about the auth provider, which will be forwarded to auth requests. + * + * Not passing in an `id` is deprecated, and it will be required in the future. */ - provider: AuthProvider; + provider: Omit & { id?: string }; /** * Implementation of the auth flow, which will be called synchronously when * trigger() is called on an auth requests. */ - onAuthRequest(scopes: Set): Promise; + onAuthRequest(scopes: Set): Promise; }; +/** + * @public + * @deprecated Use OAuthRequesterOptions instead + */ +export type AuthRequesterOptions = OAuthRequesterOptions; + /** * 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 - * {@link AuthRequesterOptions}. Or rejected, if the request is rejected. + * {@link OAuthRequesterOptions}. 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 @@ -73,9 +65,15 @@ export type AuthRequesterOptions = { * * @public */ -export type AuthRequester = ( +export type OAuthRequester = ( scopes: Set, -) => Promise; +) => Promise; + +/** + * @public + * @deprecated Use OAuthRequester instead + */ +export type AuthRequester = OAuthRequester; /** * An pending auth request for a single auth provider. The request will remain in this pending @@ -88,16 +86,18 @@ export type AuthRequester = ( * * @public */ -export type PendingAuthRequest = { +export type PendingOAuthRequest = { /** * Information about the auth provider, as given in the AuthRequesterOptions + * + * Not passing in an `id` is deprecated, and it will be required in the future. */ - provider: AuthProvider; + provider: Omit & { id?: string }; /** * Rejects the request, causing all pending AuthRequester calls to fail with "RejectedError". */ - reject: () => void; + reject(): void; /** * Trigger the auth request to continue the auth flow, by for example showing a popup. @@ -107,6 +107,12 @@ export type PendingAuthRequest = { trigger(): Promise; }; +/** + * @public + * @deprecated Use PendingOAuthRequest instead + */ +export type PendingAuthRequest = PendingOAuthRequest; + /** * Provides helpers for implemented OAuth login flows within Backstage. * @@ -125,9 +131,9 @@ export type OAuthRequestApi = { * * See AuthRequesterOptions, AuthRequester, and handleAuthRequests for more info. */ - createAuthRequester( - options: AuthRequesterOptions, - ): AuthRequester; + createAuthRequester( + options: OAuthRequesterOptions, + ): OAuthRequester; /** * Observers pending auth requests. The returned observable will emit all diff --git a/packages/core-plugin-api/src/apis/definitions/auth.ts b/packages/core-plugin-api/src/apis/definitions/auth.ts index 37308ec29b..fad759dde8 100644 --- a/packages/core-plugin-api/src/apis/definitions/auth.ts +++ b/packages/core-plugin-api/src/apis/definitions/auth.ts @@ -15,6 +15,7 @@ */ import { ApiRef, createApiRef } from '../system'; +import { IconComponent } from '../../icons/types'; import { Observable } from '@backstage/types'; /** @@ -28,6 +29,33 @@ import { Observable } from '@backstage/types'; * const googleAuthApiRef = createApiRef({ ... }) */ +/** + * Information about the auth provider. + * + * @remarks + * + * This information is used both to connect the correct auth provider in the backend, as + * well as displaying the provider to the user. + * + * @public + */ +export type AuthProviderInfo = { + /** + * The ID of the auth provider. This should match with ID of the provider in the `@backstage/auth-backend`. + */ + id: string; + + /** + * Title for the auth provider, for example "GitHub" + */ + title: string; + + /** + * Icon for the auth provider. + */ + icon: IconComponent; +}; + /** * An array of scopes, or a scope string formatted according to the * auth provider, which is typically a space separated list. From 2771d9016ed983ee38c822f3932db3d596b34dd9 Mon Sep 17 00:00:00 2001 From: Adam Harvey Date: Mon, 13 Dec 2021 09:28:56 -0500 Subject: [PATCH 14/20] Bump checkout action to newest major release Signed-off-by: Adam Harvey --- .github/workflows/changeset.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/changeset.yml b/.github/workflows/changeset.yml index 70afd15eee..a649904a01 100644 --- a/.github/workflows/changeset.yml +++ b/.github/workflows/changeset.yml @@ -10,7 +10,7 @@ jobs: name: Create Changeset PR runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - name: Install Dependencies run: yarn --frozen-lockfile - name: Create Release Pull Request From 4f1a7d57df38af0ba8c07e023c511d5246d7bfd3 Mon Sep 17 00:00:00 2001 From: Adam Harvey Date: Mon, 13 Dec 2021 09:29:30 -0500 Subject: [PATCH 15/20] Remove specific pin versioning Signed-off-by: Adam Harvey --- .github/workflows/fossa.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fossa.yml b/.github/workflows/fossa.yml index 9d054ff6df..3d0832f958 100644 --- a/.github/workflows/fossa.yml +++ b/.github/workflows/fossa.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2.3.4 + uses: actions/checkout@v2 - name: Install Fossa run: "curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/fossa-cli/master/install.sh | bash" From 9d6503e86c6e9cf07e79da82bf8f39bd141e7595 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 13 Dec 2021 15:21:09 +0100 Subject: [PATCH 16/20] core-*: update usage of deprecated auth types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Johan Haals Signed-off-by: Patrik Oldsberg --- .changeset/shaggy-bears-remember.md | 6 ++++++ packages/core-app-api/api-report.md | 20 ++++++++----------- .../OAuthRequestApi/MockOAuthApi.ts | 4 ++-- .../OAuthRequestApi/OAuthRequestManager.ts | 18 ++++++++--------- .../auth/onelogin/OneLoginAuth.ts | 4 ++-- .../src/apis/implementations/auth/types.ts | 4 ++-- .../lib/AuthConnector/DefaultAuthConnector.ts | 10 +++++----- .../lib/AuthConnector/DirectAuthConnector.ts | 6 +++--- .../LoginRequestListItem.tsx | 4 ++-- packages/core-plugin-api/api-report.md | 2 +- .../src/apis/definitions/OAuthRequestApi.ts | 2 +- 11 files changed, 41 insertions(+), 39 deletions(-) create mode 100644 .changeset/shaggy-bears-remember.md diff --git a/.changeset/shaggy-bears-remember.md b/.changeset/shaggy-bears-remember.md new file mode 100644 index 0000000000..d041abb3d1 --- /dev/null +++ b/.changeset/shaggy-bears-remember.md @@ -0,0 +1,6 @@ +--- +'@backstage/core-app-api': patch +'@backstage/core-components': patch +--- + +Switched out usage of deprecated `OAuthRequestApi` types from `@backstage/core-plugin-api`. diff --git a/packages/core-app-api/api-report.md b/packages/core-app-api/api-report.md index 51fd6bd06f..a6c44f2b52 100644 --- a/packages/core-app-api/api-report.md +++ b/packages/core-app-api/api-report.md @@ -17,9 +17,7 @@ import { AppTheme } from '@backstage/core-plugin-api'; import { AppThemeApi } from '@backstage/core-plugin-api'; import { atlassianAuthApiRef } from '@backstage/core-plugin-api'; import { auth0AuthApiRef } from '@backstage/core-plugin-api'; -import { AuthProvider } from '@backstage/core-plugin-api'; -import { AuthRequester } from '@backstage/core-plugin-api'; -import { AuthRequesterOptions } from '@backstage/core-plugin-api'; +import { AuthProviderInfo } from '@backstage/core-plugin-api'; import { AuthRequestOptions } from '@backstage/core-plugin-api'; import { BackstageIdentity } from '@backstage/core-plugin-api'; import { BackstageIdentityApi } from '@backstage/core-plugin-api'; @@ -43,11 +41,13 @@ import { IdentityApi } from '@backstage/core-plugin-api'; import { microsoftAuthApiRef } from '@backstage/core-plugin-api'; import { OAuthApi } from '@backstage/core-plugin-api'; import { OAuthRequestApi } from '@backstage/core-plugin-api'; +import { OAuthRequester } from '@backstage/core-plugin-api'; +import { OAuthRequesterOptions } from '@backstage/core-plugin-api'; import { Observable } from '@backstage/types'; import { oktaAuthApiRef } from '@backstage/core-plugin-api'; import { oneloginAuthApiRef } from '@backstage/core-plugin-api'; import { OpenIdConnectApi } from '@backstage/core-plugin-api'; -import { PendingAuthRequest } from '@backstage/core-plugin-api'; +import { PendingOAuthRequest } from '@backstage/core-plugin-api'; import { PluginOutput } from '@backstage/core-plugin-api'; import { ProfileInfo } from '@backstage/core-plugin-api'; import { ProfileInfoApi } from '@backstage/core-plugin-api'; @@ -264,9 +264,7 @@ export class Auth0Auth { export type AuthApiCreateOptions = { discoveryApi: DiscoveryApi; environment?: string; - provider?: AuthProvider & { - id: string; - }; + provider?: AuthProviderInfo; }; // @public @@ -515,9 +513,9 @@ export type OAuthApiCreateOptions = AuthApiCreateOptions & { // @public export class OAuthRequestManager implements OAuthRequestApi { // (undocumented) - authRequest$(): Observable; + authRequest$(): Observable; // (undocumented) - createAuthRequester(options: AuthRequesterOptions): AuthRequester; + createAuthRequester(options: OAuthRequesterOptions): OAuthRequester; } // @public @@ -539,9 +537,7 @@ export type OneLoginAuthCreateOptions = { discoveryApi: DiscoveryApi; oauthRequestApi: OAuthRequestApi; environment?: string; - provider?: AuthProvider & { - id: string; - }; + provider?: AuthProviderInfo; }; // @public diff --git a/packages/core-app-api/src/apis/implementations/OAuthRequestApi/MockOAuthApi.ts b/packages/core-app-api/src/apis/implementations/OAuthRequestApi/MockOAuthApi.ts index 4a0a07ef34..193c474361 100644 --- a/packages/core-app-api/src/apis/implementations/OAuthRequestApi/MockOAuthApi.ts +++ b/packages/core-app-api/src/apis/implementations/OAuthRequestApi/MockOAuthApi.ts @@ -16,14 +16,14 @@ import { OAuthRequestApi, - AuthRequesterOptions, + OAuthRequesterOptions, } from '@backstage/core-plugin-api'; import { OAuthRequestManager } from './OAuthRequestManager'; export default class MockOAuthApi implements OAuthRequestApi { private readonly real = new OAuthRequestManager(); - createAuthRequester(options: AuthRequesterOptions) { + createAuthRequester(options: OAuthRequesterOptions) { return this.real.createAuthRequester(options); } diff --git a/packages/core-app-api/src/apis/implementations/OAuthRequestApi/OAuthRequestManager.ts b/packages/core-app-api/src/apis/implementations/OAuthRequestApi/OAuthRequestManager.ts index a6b33f85d5..f9d9270b2a 100644 --- a/packages/core-app-api/src/apis/implementations/OAuthRequestApi/OAuthRequestManager.ts +++ b/packages/core-app-api/src/apis/implementations/OAuthRequestApi/OAuthRequestManager.ts @@ -16,9 +16,9 @@ import { OAuthRequestApi, - PendingAuthRequest, - AuthRequester, - AuthRequesterOptions, + PendingOAuthRequest, + OAuthRequester, + OAuthRequesterOptions, } from '@backstage/core-plugin-api'; import { Observable } from '@backstage/types'; import { OAuthPendingRequests, PendingRequest } from './OAuthPendingRequests'; @@ -34,11 +34,11 @@ import { BehaviorSubject } from '../../../lib/subjects'; * @public */ export class OAuthRequestManager implements OAuthRequestApi { - private readonly subject = new BehaviorSubject([]); - private currentRequests: PendingAuthRequest[] = []; + private readonly subject = new BehaviorSubject([]); + private currentRequests: PendingOAuthRequest[] = []; private handlerCount = 0; - createAuthRequester(options: AuthRequesterOptions): AuthRequester { + createAuthRequester(options: OAuthRequesterOptions): OAuthRequester { if (!options.provider.id) { // eslint-disable-next-line no-console console.warn( @@ -73,8 +73,8 @@ export class OAuthRequestManager implements OAuthRequestApi { // Converts the pending request and popup options into a popup request that we can forward to subscribers. private makeAuthRequest( request: PendingRequest, - options: AuthRequesterOptions, - ): PendingAuthRequest | undefined { + options: OAuthRequesterOptions, + ): PendingOAuthRequest | undefined { const { scopes } = request; if (!scopes) { return undefined; @@ -94,7 +94,7 @@ export class OAuthRequestManager implements OAuthRequestApi { }; } - authRequest$(): Observable { + authRequest$(): Observable { return this.subject; } } diff --git a/packages/core-app-api/src/apis/implementations/auth/onelogin/OneLoginAuth.ts b/packages/core-app-api/src/apis/implementations/auth/onelogin/OneLoginAuth.ts index 9493d0809e..ea9e2cad28 100644 --- a/packages/core-app-api/src/apis/implementations/auth/onelogin/OneLoginAuth.ts +++ b/packages/core-app-api/src/apis/implementations/auth/onelogin/OneLoginAuth.ts @@ -17,7 +17,7 @@ import { oneloginAuthApiRef, OAuthRequestApi, - AuthProvider, + AuthProviderInfo, DiscoveryApi, } from '@backstage/core-plugin-api'; import { OAuth2 } from '../oauth2'; @@ -30,7 +30,7 @@ export type OneLoginAuthCreateOptions = { discoveryApi: DiscoveryApi; oauthRequestApi: OAuthRequestApi; environment?: string; - provider?: AuthProvider & { id: string }; + provider?: AuthProviderInfo; }; const DEFAULT_PROVIDER = { diff --git a/packages/core-app-api/src/apis/implementations/auth/types.ts b/packages/core-app-api/src/apis/implementations/auth/types.ts index 825f433cec..55d6c19098 100644 --- a/packages/core-app-api/src/apis/implementations/auth/types.ts +++ b/packages/core-app-api/src/apis/implementations/auth/types.ts @@ -15,7 +15,7 @@ */ import { - AuthProvider, + AuthProviderInfo, DiscoveryApi, OAuthRequestApi, } from '@backstage/core-plugin-api'; @@ -36,5 +36,5 @@ export type OAuthApiCreateOptions = AuthApiCreateOptions & { export type AuthApiCreateOptions = { discoveryApi: DiscoveryApi; environment?: string; - provider?: AuthProvider & { id: string }; + provider?: AuthProviderInfo; }; diff --git a/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.ts b/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.ts index 261a008d4b..a467957063 100644 --- a/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.ts +++ b/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.ts @@ -15,9 +15,9 @@ */ import { - AuthRequester, + OAuthRequester, OAuthRequestApi, - AuthProvider, + AuthProviderInfo, DiscoveryApi, } from '@backstage/core-plugin-api'; import { showLoginPopup } from '../loginPopup'; @@ -36,7 +36,7 @@ type Options = { * Information about the auth provider to be shown to the user. * The ID Must match the backend auth plugin configuration, for example 'google'. */ - provider: AuthProvider & { id: string }; + provider: AuthProviderInfo; /** * API used to instantiate an auth requester. */ @@ -65,9 +65,9 @@ export class DefaultAuthConnector { private readonly discoveryApi: DiscoveryApi; private readonly environment: string; - private readonly provider: AuthProvider & { id: string }; + private readonly provider: AuthProviderInfo; private readonly joinScopesFunc: (scopes: Set) => string; - private readonly authRequester: AuthRequester; + private readonly authRequester: OAuthRequester; private readonly sessionTransform: (response: any) => Promise; constructor(options: Options) { diff --git a/packages/core-app-api/src/lib/AuthConnector/DirectAuthConnector.ts b/packages/core-app-api/src/lib/AuthConnector/DirectAuthConnector.ts index 61fdd825a2..200ba755ac 100644 --- a/packages/core-app-api/src/lib/AuthConnector/DirectAuthConnector.ts +++ b/packages/core-app-api/src/lib/AuthConnector/DirectAuthConnector.ts @@ -13,18 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { AuthProvider, DiscoveryApi } from '@backstage/core-plugin-api'; +import { AuthProviderInfo, DiscoveryApi } from '@backstage/core-plugin-api'; import { showLoginPopup } from '../loginPopup'; type Options = { discoveryApi: DiscoveryApi; environment?: string; - provider: AuthProvider & { id: string }; + provider: AuthProviderInfo; }; export class DirectAuthConnector { private readonly discoveryApi: DiscoveryApi; private readonly environment: string | undefined; - private readonly provider: AuthProvider & { id: string }; + private readonly provider: AuthProviderInfo; constructor(options: Options) { const { discoveryApi, environment, provider } = options; diff --git a/packages/core-components/src/components/OAuthRequestDialog/LoginRequestListItem.tsx b/packages/core-components/src/components/OAuthRequestDialog/LoginRequestListItem.tsx index ef0d2373e4..0c6bd62bcb 100644 --- a/packages/core-components/src/components/OAuthRequestDialog/LoginRequestListItem.tsx +++ b/packages/core-components/src/components/OAuthRequestDialog/LoginRequestListItem.tsx @@ -22,7 +22,7 @@ import Typography from '@material-ui/core/Typography'; import Button from '@material-ui/core/Button'; import React, { useState } from 'react'; import { isError } from '@backstage/errors'; -import { PendingAuthRequest } from '@backstage/core-plugin-api'; +import { PendingOAuthRequest } from '@backstage/core-plugin-api'; export type LoginRequestListItemClassKey = 'root'; @@ -36,7 +36,7 @@ const useItemStyles = makeStyles( ); type RowProps = { - request: PendingAuthRequest; + request: PendingOAuthRequest; busy: boolean; setBusy: (busy: boolean) => void; }; diff --git a/packages/core-plugin-api/api-report.md b/packages/core-plugin-api/api-report.md index 65fbbb7ed1..2f40a02253 100644 --- a/packages/core-plugin-api/api-report.md +++ b/packages/core-plugin-api/api-report.md @@ -600,7 +600,7 @@ export type OAuthRequestApi = { createAuthRequester( options: OAuthRequesterOptions, ): OAuthRequester; - authRequest$(): Observable_2; + authRequest$(): Observable_2; }; // @public diff --git a/packages/core-plugin-api/src/apis/definitions/OAuthRequestApi.ts b/packages/core-plugin-api/src/apis/definitions/OAuthRequestApi.ts index b78cc310c3..5b8dab29f7 100644 --- a/packages/core-plugin-api/src/apis/definitions/OAuthRequestApi.ts +++ b/packages/core-plugin-api/src/apis/definitions/OAuthRequestApi.ts @@ -146,7 +146,7 @@ export type OAuthRequestApi = { * If a auth is triggered, and the auth handler resolves successfully, then all currently pending * AuthRequester calls will resolve to the value returned by the onAuthRequest call. */ - authRequest$(): Observable; + authRequest$(): Observable; }; /** From e7cce2b60385a09a57caaaae1f355cc967a7b01e Mon Sep 17 00:00:00 2001 From: Phil Kuang Date: Fri, 3 Dec 2021 15:49:52 -0500 Subject: [PATCH 17/20] fix(techdocsStorageClient): properly construct baseUrls Signed-off-by: Phil Kuang --- .changeset/techdocs-forty-pumas-compete.md | 5 +++++ plugins/techdocs/src/client.test.ts | 6 ++++++ plugins/techdocs/src/client.ts | 4 +++- 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 .changeset/techdocs-forty-pumas-compete.md diff --git a/.changeset/techdocs-forty-pumas-compete.md b/.changeset/techdocs-forty-pumas-compete.md new file mode 100644 index 0000000000..929ce3e2c9 --- /dev/null +++ b/.changeset/techdocs-forty-pumas-compete.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Fix issue where assets weren't being fetched from the correct URL path for doc URLs without trailing slashes diff --git a/plugins/techdocs/src/client.test.ts b/plugins/techdocs/src/client.test.ts index 7624f250d9..c05d0cc324 100644 --- a/plugins/techdocs/src/client.test.ts +++ b/plugins/techdocs/src/client.test.ts @@ -59,6 +59,12 @@ describe('TechDocsStorageClient', () => { ).resolves.toEqual( `${mockBaseUrl}/static/docs/${mockEntity.namespace}/${mockEntity.kind}/${mockEntity.name}/test.js`, ); + + await expect( + storageApi.getBaseUrl('../test.js', mockEntity, 'some-docs-path'), + ).resolves.toEqual( + `${mockBaseUrl}/static/docs/${mockEntity.namespace}/${mockEntity.kind}/${mockEntity.name}/test.js`, + ); }); it('should return base url with correct entity structure', async () => { diff --git a/plugins/techdocs/src/client.ts b/plugins/techdocs/src/client.ts index 8a3ad59c03..f965cd7ced 100644 --- a/plugins/techdocs/src/client.ts +++ b/plugins/techdocs/src/client.ts @@ -263,9 +263,11 @@ export class TechDocsStorageClient implements TechDocsStorageApi { const { kind, namespace, name } = entityId; const apiOrigin = await this.getApiOrigin(); + const newBaseUrl = `${apiOrigin}/static/docs/${namespace}/${kind}/${name}/${path}`; + return new URL( oldBaseUrl, - `${apiOrigin}/static/docs/${namespace}/${kind}/${name}/${path}`, + newBaseUrl.endsWith('/') ? newBaseUrl : `${newBaseUrl}/`, ).toString(); } } From fd9c1abd2c76e5a54dcaf63c25aa2604dc0d67a9 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 13 Dec 2021 16:41:49 +0100 Subject: [PATCH 18/20] Delete cold-otters-prove.md Signed-off-by: Patrik Oldsberg --- .changeset/cold-otters-prove.md | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .changeset/cold-otters-prove.md diff --git a/.changeset/cold-otters-prove.md b/.changeset/cold-otters-prove.md deleted file mode 100644 index 37438b333e..0000000000 --- a/.changeset/cold-otters-prove.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-common': patch -'@backstage/cli': patch ---- - -chore(deps-dev): bump `@types/tar` from 4.0.5 to 6.1.1 From 4594ea2dab62f033d288e7e8f7279438795adbdd Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 13 Dec 2021 18:24:46 +0100 Subject: [PATCH 19/20] catalog-react: weird api-report reordering Signed-off-by: Patrik Oldsberg --- plugins/catalog-react/api-report.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md index c4aa254226..c95a8dc508 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/api-report.md @@ -271,14 +271,13 @@ export const EntityRefLink: React_2.ForwardRefExoticComponent< | 'children' | 'key' | 'id' - | 'className' | 'classes' - | 'innerRef' | 'defaultChecked' | 'defaultValue' | 'suppressContentEditableWarning' | 'suppressHydrationWarning' | 'accessKey' + | 'className' | 'contentEditable' | 'contextMenu' | 'draggable' @@ -519,6 +518,7 @@ export const EntityRefLink: React_2.ForwardRefExoticComponent< | 'onTransitionEndCapture' | 'component' | 'variant' + | 'innerRef' | 'download' | 'href' | 'hrefLang' From 2c9001fef1866365e3ef040ee672280cc8bf52e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Dec 2021 04:20:37 +0000 Subject: [PATCH 20/20] build(deps): bump humanize-duration from 3.27.0 to 3.27.1 Bumps [humanize-duration](https://github.com/EvanHahn/HumanizeDuration.js) from 3.27.0 to 3.27.1. - [Release notes](https://github.com/EvanHahn/HumanizeDuration.js/releases) - [Changelog](https://github.com/EvanHahn/HumanizeDuration.js/blob/main/HISTORY.md) - [Commits](https://github.com/EvanHahn/HumanizeDuration.js/commits) --- updated-dependencies: - dependency-name: humanize-duration dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 19f6ad2b27..c10a3d9afb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16999,9 +16999,9 @@ human-signals@^2.1.0: integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== humanize-duration@^3.25.1, humanize-duration@^3.26.0, humanize-duration@^3.27.0: - version "3.27.0" - resolved "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.27.0.tgz#3f781b7cf8022ad587f76b9839b60bc2b29636b2" - integrity sha512-qLo/08cNc3Tb0uD7jK0jAcU5cnqCM0n568918E7R2XhMr/+7F37p4EY062W/stg7tmzvknNn9b/1+UhVRzsYrQ== + version "3.27.1" + resolved "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.27.1.tgz#2cd4ea4b03bd92184aee6d90d77a8f3d7628df69" + integrity sha512-jCVkMl+EaM80rrMrAPl96SGG4NRac53UyI1o/yAzebDntEY6K6/Fj2HOjdPg8omTqIe5Y0wPBai2q5xXrIbarA== humanize-ms@^1.2.1: version "1.2.1"