From 35725e2b83c47a2590297d4a41e5c2f585dd1630 Mon Sep 17 00:00:00 2001 From: Philipp Hugenroth Date: Thu, 9 Nov 2023 12:03:39 +0100 Subject: [PATCH 001/283] Update dependencies in frontend plugin templates Signed-off-by: Philipp Hugenroth --- .changeset/tiny-kiwis-know.md | 5 +++++ packages/cli/templates/default-plugin/package.json.hbs | 4 ++-- .../templates/default-react-plugin-package/package.json.hbs | 4 ++-- packages/cli/templates/web-library-package/package.json.hbs | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 .changeset/tiny-kiwis-know.md diff --git a/.changeset/tiny-kiwis-know.md b/.changeset/tiny-kiwis-know.md new file mode 100644 index 0000000000..b0de24ce0a --- /dev/null +++ b/.changeset/tiny-kiwis-know.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Update dependencies in `defaul-plugin` template diff --git a/packages/cli/templates/default-plugin/package.json.hbs b/packages/cli/templates/default-plugin/package.json.hbs index 011a50ba37..15b22bc8e1 100644 --- a/packages/cli/templates/default-plugin/package.json.hbs +++ b/packages/cli/templates/default-plugin/package.json.hbs @@ -45,8 +45,8 @@ "@backstage/core-app-api": "{{versionQuery '@backstage/core-app-api'}}", "@backstage/dev-utils": "{{versionQuery '@backstage/dev-utils'}}", "@backstage/test-utils": "{{versionQuery '@backstage/test-utils'}}", - "@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '5.10.1'}}", - "@testing-library/react": "{{versionQuery '@testing-library/react' '12.1.3'}}", + "@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '6.0.0'}}", + "@testing-library/react": "{{versionQuery '@testing-library/react' '14.0.0'}}", "@testing-library/user-event": "{{versionQuery '@testing-library/user-event' '14.0.0'}}", "msw": "{{versionQuery 'msw' '1.0.0'}}" }, diff --git a/packages/cli/templates/default-react-plugin-package/package.json.hbs b/packages/cli/templates/default-react-plugin-package/package.json.hbs index 230ecc5f03..f68bd14a1d 100644 --- a/packages/cli/templates/default-react-plugin-package/package.json.hbs +++ b/packages/cli/templates/default-react-plugin-package/package.json.hbs @@ -39,8 +39,8 @@ "devDependencies": { "@backstage/cli": "{{versionQuery '@backstage/cli'}}", "@backstage/test-utils": "{{versionQuery '@backstage/test-utils'}}", - "@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '5.10.1'}}", - "@testing-library/react": "{{versionQuery '@testing-library/react' '12.1.3'}}" + "@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '6.0.0'}}", + "@testing-library/react": "{{versionQuery '@testing-library/react' '14.0.0'}}" }, "files": [ "dist" diff --git a/packages/cli/templates/web-library-package/package.json.hbs b/packages/cli/templates/web-library-package/package.json.hbs index f9f703f523..271417a525 100644 --- a/packages/cli/templates/web-library-package/package.json.hbs +++ b/packages/cli/templates/web-library-package/package.json.hbs @@ -30,7 +30,7 @@ }, "devDependencies": { "@backstage/cli": "{{versionQuery '@backstage/cli'}}", - "@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '5.10.1'}}" + "@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '6.0.0'}}" }, "files": [ "dist" From cbc6157d486f3d1cf046a0fd000942ab6930c9bd Mon Sep 17 00:00:00 2001 From: Philipp Hugenroth Date: Thu, 9 Nov 2023 12:03:52 +0100 Subject: [PATCH 002/283] Add changeset Signed-off-by: Philipp Hugenroth --- .changeset/tiny-kiwis-know.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/tiny-kiwis-know.md b/.changeset/tiny-kiwis-know.md index b0de24ce0a..add4736527 100644 --- a/.changeset/tiny-kiwis-know.md +++ b/.changeset/tiny-kiwis-know.md @@ -2,4 +2,4 @@ '@backstage/cli': patch --- -Update dependencies in `defaul-plugin` template +Updated dependencies in frontend plugin templates From 9c20b935bc0c778e906e1cbe932313fd47a9ef73 Mon Sep 17 00:00:00 2001 From: David Martin Date: Fri, 15 Dec 2023 12:08:58 +0000 Subject: [PATCH 003/283] Update configuration.md The wording for the default behaviour reads a little odd. I think this clears it up Signed-off-by: David Martin --- docs/features/kubernetes/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md index 494e51320a..4ca59f1a94 100644 --- a/docs/features/kubernetes/configuration.md +++ b/docs/features/kubernetes/configuration.md @@ -593,7 +593,7 @@ SingleTenant Cluster: In the example above, we configured the "backstage.io/kubernetes-cluster" annotation on the entity `catalog-info.yaml` file to specify that the current component is running in a single cluster called "dice-cluster", so this cluster must have been specified in the `app-config.yaml`, under the Kubernetes clusters configuration (for more details, see [`Configuring Kubernetes clusters`](#configuring-kubernetes-clusters)). -If you do not specify the annotation by `default Backstage fetches all` defined Kubernetes cluster. +If you do not specify the annotation, by default Backstage fetches from all defined Kubernetes clusters. [1]: https://cloud.google.com/kubernetes-engine [2]: https://cloud.google.com/docs/authentication/production#linux-or-macos From 60e4c2a86d0b67ca47c1c7d2e6d17da7fbb0a235 Mon Sep 17 00:00:00 2001 From: Markus Date: Mon, 18 Dec 2023 07:48:43 +0100 Subject: [PATCH 004/283] feat: add callback transformers to GitlabOrgDiscoveryEntityProvider Signed-off-by: Markus --- .changeset/neat-hotels-wink.md | 5 + .../src/lib/defaultTransformers.ts | 125 +++++++++++++++ .../src/lib/types.ts | 39 +++++ .../GitlabOrgDiscoveryEntityProvider.ts | 142 ++++++------------ 4 files changed, 211 insertions(+), 100 deletions(-) create mode 100644 .changeset/neat-hotels-wink.md create mode 100644 plugins/catalog-backend-module-gitlab/src/lib/defaultTransformers.ts diff --git a/.changeset/neat-hotels-wink.md b/.changeset/neat-hotels-wink.md new file mode 100644 index 0000000000..a37d282578 --- /dev/null +++ b/.changeset/neat-hotels-wink.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-gitlab': patch +--- + +add `groupTransformer`, `userTransformer` and `groupNameTransformer` to allow custom transformations when groups and users are created diff --git a/plugins/catalog-backend-module-gitlab/src/lib/defaultTransformers.ts b/plugins/catalog-backend-module-gitlab/src/lib/defaultTransformers.ts new file mode 100644 index 0000000000..6612086dab --- /dev/null +++ b/plugins/catalog-backend-module-gitlab/src/lib/defaultTransformers.ts @@ -0,0 +1,125 @@ +/* + * Copyright 2023 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 { GroupEntity, UserEntity } from '@backstage/catalog-model'; +import { + GitLabGroup, + GitLabUser, + GitlabProviderConfig, + GroupNameTransformer, +} from './types'; +import { GitLabIntegrationConfig } from '@backstage/integration'; + +export function defaultGroupNameTransformer( + group: GitLabGroup, + config: GitlabProviderConfig, +): string { + if (config.group && group.full_path.startsWith(`${config.group}/`)) { + return group.full_path.replace(`${config.group}/`, '').replaceAll('/', '-'); + } + return group.full_path.replaceAll('/', '-'); +} + +export function defaultGroupTransformer( + group: GitLabGroup, + provConfig: GitlabProviderConfig, + groupNameTransformer: GroupNameTransformer, +): GroupEntity { + const annotations: { [annotationName: string]: string } = {}; + + annotations[`${provConfig.host}/team-path`] = group.full_path; + + const entity: GroupEntity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + name: groupNameTransformer(group, provConfig), + annotations: annotations, + }, + spec: { + type: 'team', + children: [], + profile: { + displayName: group.name, + }, + }, + }; + + if (group.description) { + entity.metadata.description = group.description; + } + + return entity; +} + +/** + * The default implementation of the transformation from a graph user entry to + * a User entity. + * + * @public + */ +export function defaultUserTransformer( + user: GitLabUser, + intConfig: GitLabIntegrationConfig, + provConfig: GitlabProviderConfig, + groupNameTransformer: GroupNameTransformer, +): UserEntity { + const annotations: { [annotationName: string]: string } = {}; + + annotations[`${intConfig.host}/user-login`] = user.web_url; + if (user?.group_saml_identity?.extern_uid) { + annotations[`${intConfig.host}/saml-external-uid`] = + user.group_saml_identity.extern_uid; + } + + const entity: UserEntity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + name: user.username, + annotations: annotations, + }, + spec: { + profile: { + displayName: user.name || undefined, + picture: user.avatar_url || undefined, + }, + memberOf: [], + }, + }; + + if (user.email) { + if (!entity.spec) { + entity.spec = {}; + } + + if (!entity.spec.profile) { + entity.spec.profile = {}; + } + + entity.spec.profile.email = user.email; + } + + if (user.groups) { + for (const group of user.groups) { + if (!entity.spec.memberOf) { + entity.spec.memberOf = []; + } + entity.spec.memberOf.push(groupNameTransformer(group, provConfig)); + } + } + + return entity; +} diff --git a/plugins/catalog-backend-module-gitlab/src/lib/types.ts b/plugins/catalog-backend-module-gitlab/src/lib/types.ts index fa2eb73da6..1ecd186a59 100644 --- a/plugins/catalog-backend-module-gitlab/src/lib/types.ts +++ b/plugins/catalog-backend-module-gitlab/src/lib/types.ts @@ -14,6 +14,8 @@ * limitations under the License. */ import { TaskScheduleDefinition } from '@backstage/backend-tasks'; +import { GroupEntity, UserEntity } from '@backstage/catalog-model'; +import { GitLabIntegrationConfig } from '@backstage/integration'; export type PagedResponse = { items: T[]; @@ -116,6 +118,10 @@ export type GitLabDescendantGroupsResponse = { export type GitlabProviderConfig = { host: string; + /** + * Group and subgroup (if needed) to look for repositories. If not present the whole instance will be scanned. + * If present this if present, the discovered groups won't contain this prefix + */ group: string; id: string; /** @@ -136,3 +142,36 @@ export type GitlabProviderConfig = { schedule?: TaskScheduleDefinition; skipForkedRepos?: boolean; }; + +/** + * Customize how group names are generated + * + * @public + */ +export type GroupNameTransformer = ( + group: GitLabGroup, + config: GitlabProviderConfig, +) => string; + +/** + * Customize the ingested User entity + * + * @public + */ +export type UserTransformer = ( + user: GitLabUser, + intConfig: GitLabIntegrationConfig, + provConfig: GitlabProviderConfig, + groupNameTransformer: GroupNameTransformer, +) => UserEntity; + +/** + * Customize the ingested Group entity + * + * @public + */ +export type GroupTransformer = ( + group: GitLabGroup, + provConfig: GitlabProviderConfig, + groupNameTransformer: GroupNameTransformer, +) => GroupEntity; diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts index affa8a41cf..16b1c326f3 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts @@ -19,7 +19,6 @@ import { ANNOTATION_ORIGIN_LOCATION, Entity, GroupEntity, - UserEntity, } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; import { GitLabIntegration, ScmIntegrations } from '@backstage/integration'; @@ -37,7 +36,19 @@ import { paginated, readGitlabConfigs, } from '../lib'; -import { GitLabGroup, GitLabUser, PagedResponse } from '../lib/types'; +import { + GitLabGroup, + GitLabUser, + PagedResponse, + UserTransformer, + GroupTransformer, + GroupNameTransformer, +} from '../lib/types'; +import { + defaultGroupNameTransformer, + defaultGroupTransformer, + defaultUserTransformer, +} from '../lib/defaultTransformers'; type Result = { scanned: number; @@ -59,6 +70,9 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { private readonly logger: Logger; private readonly scheduleFn: () => Promise; private connection?: EntityProviderConnection; + private userTransformer: UserTransformer; + private groupTransformer: GroupTransformer; + private groupNameTransformer: GroupNameTransformer; static fromConfig( config: Config, @@ -66,6 +80,9 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { logger: Logger; schedule?: TaskRunner; scheduler?: PluginTaskScheduler; + userTransformer?: UserTransformer; + groupTransformer?: GroupTransformer; + groupNameTransformer?: GroupNameTransformer; }, ): GitlabOrgDiscoveryEntityProvider[] { if (!options.schedule && !options.scheduler) { @@ -122,6 +139,9 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { integration: GitLabIntegration; logger: Logger; taskRunner: TaskRunner; + userTransformer?: UserTransformer; + groupTransformer?: GroupTransformer; + groupNameTransformer?: GroupNameTransformer; }) { this.config = options.config; this.integration = options.integration; @@ -129,6 +149,10 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { target: this.getProviderName(), }); this.scheduleFn = this.createScheduleFn(options.taskRunner); + this.userTransformer = options.userTransformer ?? defaultUserTransformer; + this.groupTransformer = options.groupTransformer ?? defaultGroupTransformer; + this.groupNameTransformer = + options.groupNameTransformer ?? defaultGroupNameTransformer; } getProviderName(): string { @@ -271,12 +295,14 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { }); const userEntities = res.matches.map(p => - this.createUserEntity(p, this.integration.config.host), - ); - const groupEntities = this.createGroupEntities( - groupsWithUsers, - this.integration.config.host, + this.userTransformer( + p, + this.integration.config, + this.config, + this.groupNameTransformer, + ), ); + const groupEntities = this.createGroupEntities(groupsWithUsers); await this.connection.applyMutation({ type: 'full', @@ -291,10 +317,7 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { }); } - private createGroupEntities( - groupResult: GitLabGroup[], - host: string, - ): GroupEntity[] { + private createGroupEntities(groupResult: GitLabGroup[]): GroupEntity[] { const idMapped: { [groupId: number]: GitLabGroup } = {}; const entities: GroupEntity[] = []; @@ -303,11 +326,16 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { } for (const group of groupResult) { - const entity = this.createGroupEntity(group, host); + const entity = this.groupTransformer( + group, + this.config, + this.groupNameTransformer, + ); if (group.parent_id && idMapped.hasOwnProperty(group.parent_id)) { - entity.spec.parent = this.groupName( - idMapped[group.parent_id].full_path, + entity.spec.parent = this.groupNameTransformer( + idMapped[group.parent_id], + this.config, ); } @@ -334,90 +362,4 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { entity, ) as Entity; } - - private createUserEntity(user: GitLabUser, host: string): UserEntity { - const annotations: { [annotationName: string]: string } = {}; - - annotations[`${host}/user-login`] = user.web_url; - if (user?.group_saml_identity?.extern_uid) { - annotations[`${host}/saml-external-uid`] = - user.group_saml_identity.extern_uid; - } - - const entity: UserEntity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'User', - metadata: { - name: user.username, - annotations: annotations, - }, - spec: { - profile: { - displayName: user.name || undefined, - picture: user.avatar_url || undefined, - }, - memberOf: [], - }, - }; - - if (user.email) { - if (!entity.spec) { - entity.spec = {}; - } - - if (!entity.spec.profile) { - entity.spec.profile = {}; - } - - entity.spec.profile.email = user.email; - } - - if (user.groups) { - for (const group of user.groups) { - if (!entity.spec.memberOf) { - entity.spec.memberOf = []; - } - entity.spec.memberOf.push(this.groupName(group.full_path)); - } - } - - return entity; - } - - private groupName(full_path: string): string { - if (this.config.group && full_path.startsWith(`${this.config.group}/`)) { - return full_path - .replace(`${this.config.group}/`, '') - .replaceAll('/', '-'); - } - return full_path.replaceAll('/', '-'); - } - - private createGroupEntity(group: GitLabGroup, host: string): GroupEntity { - const annotations: { [annotationName: string]: string } = {}; - - annotations[`${host}/team-path`] = group.full_path; - - const entity: GroupEntity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Group', - metadata: { - name: this.groupName(group.full_path), - annotations: annotations, - }, - spec: { - type: 'team', - children: [], - profile: { - displayName: group.name, - }, - }, - }; - - if (group.description) { - entity.metadata.description = group.description; - } - - return entity; - } } From 1228c1d584366f4cb9f59a8bd581f6881d2f7e47 Mon Sep 17 00:00:00 2001 From: Markus Date: Mon, 18 Dec 2023 17:45:33 +0100 Subject: [PATCH 005/283] chore: rename variables Signed-off-by: Markus --- .../src/lib/defaultTransformers.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/catalog-backend-module-gitlab/src/lib/defaultTransformers.ts b/plugins/catalog-backend-module-gitlab/src/lib/defaultTransformers.ts index 6612086dab..1fbe60ebe7 100644 --- a/plugins/catalog-backend-module-gitlab/src/lib/defaultTransformers.ts +++ b/plugins/catalog-backend-module-gitlab/src/lib/defaultTransformers.ts @@ -34,18 +34,18 @@ export function defaultGroupNameTransformer( export function defaultGroupTransformer( group: GitLabGroup, - provConfig: GitlabProviderConfig, + providerConfig: GitlabProviderConfig, groupNameTransformer: GroupNameTransformer, ): GroupEntity { const annotations: { [annotationName: string]: string } = {}; - annotations[`${provConfig.host}/team-path`] = group.full_path; + annotations[`${providerConfig.host}/team-path`] = group.full_path; const entity: GroupEntity = { apiVersion: 'backstage.io/v1alpha1', kind: 'Group', metadata: { - name: groupNameTransformer(group, provConfig), + name: groupNameTransformer(group, providerConfig), annotations: annotations, }, spec: { @@ -72,15 +72,15 @@ export function defaultGroupTransformer( */ export function defaultUserTransformer( user: GitLabUser, - intConfig: GitLabIntegrationConfig, - provConfig: GitlabProviderConfig, + integrationConfig: GitLabIntegrationConfig, + providerConfig: GitlabProviderConfig, groupNameTransformer: GroupNameTransformer, ): UserEntity { const annotations: { [annotationName: string]: string } = {}; - annotations[`${intConfig.host}/user-login`] = user.web_url; + annotations[`${integrationConfig.host}/user-login`] = user.web_url; if (user?.group_saml_identity?.extern_uid) { - annotations[`${intConfig.host}/saml-external-uid`] = + annotations[`${integrationConfig.host}/saml-external-uid`] = user.group_saml_identity.extern_uid; } @@ -117,7 +117,7 @@ export function defaultUserTransformer( if (!entity.spec.memberOf) { entity.spec.memberOf = []; } - entity.spec.memberOf.push(groupNameTransformer(group, provConfig)); + entity.spec.memberOf.push(groupNameTransformer(group, providerConfig)); } } From 198ef79ee4123fd297f534f673f00e951fd30ab8 Mon Sep 17 00:00:00 2001 From: Markus Date: Mon, 18 Dec 2023 18:27:30 +0100 Subject: [PATCH 006/283] chore: refactor function inputs Signed-off-by: Markus --- .../src/lib/defaultTransformers.ts | 129 +++++++++++------- .../src/lib/types.ts | 31 +++-- .../GitlabOrgDiscoveryEntityProvider.ts | 61 +++------ 3 files changed, 115 insertions(+), 106 deletions(-) diff --git a/plugins/catalog-backend-module-gitlab/src/lib/defaultTransformers.ts b/plugins/catalog-backend-module-gitlab/src/lib/defaultTransformers.ts index 1fbe60ebe7..d7a6bf76e9 100644 --- a/plugins/catalog-backend-module-gitlab/src/lib/defaultTransformers.ts +++ b/plugins/catalog-backend-module-gitlab/src/lib/defaultTransformers.ts @@ -16,52 +16,74 @@ import { GroupEntity, UserEntity } from '@backstage/catalog-model'; import { GitLabGroup, - GitLabUser, - GitlabProviderConfig, - GroupNameTransformer, + GroupNameTransformerOptions, + GroupTransformerOptions, + UserTransformerOptions, } from './types'; -import { GitLabIntegrationConfig } from '@backstage/integration'; export function defaultGroupNameTransformer( - group: GitLabGroup, - config: GitlabProviderConfig, + options: GroupNameTransformerOptions, ): string { - if (config.group && group.full_path.startsWith(`${config.group}/`)) { - return group.full_path.replace(`${config.group}/`, '').replaceAll('/', '-'); + if ( + options.providerConfig.group && + options.group.full_path.startsWith(`${options.providerConfig.group}/`) + ) { + return options.group.full_path + .replace(`${options.providerConfig.group}/`, '') + .replaceAll('/', '-'); } - return group.full_path.replaceAll('/', '-'); + return options.group.full_path.replaceAll('/', '-'); } -export function defaultGroupTransformer( - group: GitLabGroup, - providerConfig: GitlabProviderConfig, - groupNameTransformer: GroupNameTransformer, -): GroupEntity { - const annotations: { [annotationName: string]: string } = {}; +export function defaultGroupEntitiesTransformer( + options: GroupTransformerOptions, +): GroupEntity[] { + const idMapped: { [groupId: number]: GitLabGroup } = {}; + const entities: GroupEntity[] = []; - annotations[`${providerConfig.host}/team-path`] = group.full_path; - - const entity: GroupEntity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Group', - metadata: { - name: groupNameTransformer(group, providerConfig), - annotations: annotations, - }, - spec: { - type: 'team', - children: [], - profile: { - displayName: group.name, - }, - }, - }; - - if (group.description) { - entity.metadata.description = group.description; + for (const group of options.groups) { + idMapped[group.id] = group; } - return entity; + for (const group of options.groups) { + const annotations: { [annotationName: string]: string } = {}; + + annotations[`${options.providerConfig.host}/team-path`] = group.full_path; + + const entity: GroupEntity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + name: options.groupNameTransformer({ + group, + providerConfig: options.providerConfig, + }), + annotations: annotations, + }, + spec: { + type: 'team', + children: [], + profile: { + displayName: group.name, + }, + }, + }; + + if (group.description) { + entity.metadata.description = group.description; + } + + if (group.parent_id && idMapped.hasOwnProperty(group.parent_id)) { + entity.spec.parent = options.groupNameTransformer({ + group: idMapped[group.parent_id], + providerConfig: options.providerConfig, + }); + } + + entities.push(entity); + } + + return entities; } /** @@ -71,36 +93,34 @@ export function defaultGroupTransformer( * @public */ export function defaultUserTransformer( - user: GitLabUser, - integrationConfig: GitLabIntegrationConfig, - providerConfig: GitlabProviderConfig, - groupNameTransformer: GroupNameTransformer, + options: UserTransformerOptions, ): UserEntity { const annotations: { [annotationName: string]: string } = {}; - annotations[`${integrationConfig.host}/user-login`] = user.web_url; - if (user?.group_saml_identity?.extern_uid) { - annotations[`${integrationConfig.host}/saml-external-uid`] = - user.group_saml_identity.extern_uid; + annotations[`${options.integrationConfig.host}/user-login`] = + options.user.web_url; + if (options.user?.group_saml_identity?.extern_uid) { + annotations[`${options.integrationConfig.host}/saml-external-uid`] = + options.user.group_saml_identity.extern_uid; } const entity: UserEntity = { apiVersion: 'backstage.io/v1alpha1', kind: 'User', metadata: { - name: user.username, + name: options.user.username, annotations: annotations, }, spec: { profile: { - displayName: user.name || undefined, - picture: user.avatar_url || undefined, + displayName: options.user.name || undefined, + picture: options.user.avatar_url || undefined, }, memberOf: [], }, }; - if (user.email) { + if (options.user.email) { if (!entity.spec) { entity.spec = {}; } @@ -109,15 +129,20 @@ export function defaultUserTransformer( entity.spec.profile = {}; } - entity.spec.profile.email = user.email; + entity.spec.profile.email = options.user.email; } - if (user.groups) { - for (const group of user.groups) { + if (options.user.groups) { + for (const group of options.user.groups) { if (!entity.spec.memberOf) { entity.spec.memberOf = []; } - entity.spec.memberOf.push(groupNameTransformer(group, providerConfig)); + entity.spec.memberOf.push( + options.groupNameTransformer({ + group, + providerConfig: options.providerConfig, + }), + ); } } diff --git a/plugins/catalog-backend-module-gitlab/src/lib/types.ts b/plugins/catalog-backend-module-gitlab/src/lib/types.ts index 1ecd186a59..4a15d44d04 100644 --- a/plugins/catalog-backend-module-gitlab/src/lib/types.ts +++ b/plugins/catalog-backend-module-gitlab/src/lib/types.ts @@ -149,21 +149,25 @@ export type GitlabProviderConfig = { * @public */ export type GroupNameTransformer = ( - group: GitLabGroup, - config: GitlabProviderConfig, + options: GroupNameTransformerOptions, ) => string; +export interface GroupNameTransformerOptions { + group: GitLabGroup; + providerConfig: GitlabProviderConfig; +} /** * Customize the ingested User entity * * @public */ -export type UserTransformer = ( - user: GitLabUser, - intConfig: GitLabIntegrationConfig, - provConfig: GitlabProviderConfig, - groupNameTransformer: GroupNameTransformer, -) => UserEntity; +export type UserTransformer = (options: UserTransformerOptions) => UserEntity; +export interface UserTransformerOptions { + user: GitLabUser; + integrationConfig: GitLabIntegrationConfig; + providerConfig: GitlabProviderConfig; + groupNameTransformer: GroupNameTransformer; +} /** * Customize the ingested Group entity @@ -171,7 +175,10 @@ export type UserTransformer = ( * @public */ export type GroupTransformer = ( - group: GitLabGroup, - provConfig: GitlabProviderConfig, - groupNameTransformer: GroupNameTransformer, -) => GroupEntity; + options: GroupTransformerOptions, +) => GroupEntity[]; +export interface GroupTransformerOptions { + groups: GitLabGroup[]; + providerConfig: GitlabProviderConfig; + groupNameTransformer: GroupNameTransformer; +} diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts index 16b1c326f3..1157a2f1f3 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts @@ -18,7 +18,6 @@ import { ANNOTATION_LOCATION, ANNOTATION_ORIGIN_LOCATION, Entity, - GroupEntity, } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; import { GitLabIntegration, ScmIntegrations } from '@backstage/integration'; @@ -41,12 +40,12 @@ import { GitLabUser, PagedResponse, UserTransformer, - GroupTransformer, + GroupTransformer as GroupEntitiesTransformer, GroupNameTransformer, } from '../lib/types'; import { defaultGroupNameTransformer, - defaultGroupTransformer, + defaultGroupEntitiesTransformer, defaultUserTransformer, } from '../lib/defaultTransformers'; @@ -71,7 +70,7 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { private readonly scheduleFn: () => Promise; private connection?: EntityProviderConnection; private userTransformer: UserTransformer; - private groupTransformer: GroupTransformer; + private groupEntitiesTransformer: GroupEntitiesTransformer; private groupNameTransformer: GroupNameTransformer; static fromConfig( @@ -81,7 +80,7 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { schedule?: TaskRunner; scheduler?: PluginTaskScheduler; userTransformer?: UserTransformer; - groupTransformer?: GroupTransformer; + groupEntitiesTransformer?: GroupEntitiesTransformer; groupNameTransformer?: GroupNameTransformer; }, ): GitlabOrgDiscoveryEntityProvider[] { @@ -140,7 +139,7 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { logger: Logger; taskRunner: TaskRunner; userTransformer?: UserTransformer; - groupTransformer?: GroupTransformer; + groupEntitiesTransformer?: GroupEntitiesTransformer; groupNameTransformer?: GroupNameTransformer; }) { this.config = options.config; @@ -150,7 +149,8 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { }); this.scheduleFn = this.createScheduleFn(options.taskRunner); this.userTransformer = options.userTransformer ?? defaultUserTransformer; - this.groupTransformer = options.groupTransformer ?? defaultGroupTransformer; + this.groupEntitiesTransformer = + options.groupEntitiesTransformer ?? defaultGroupEntitiesTransformer; this.groupNameTransformer = options.groupNameTransformer ?? defaultGroupNameTransformer; } @@ -295,14 +295,19 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { }); const userEntities = res.matches.map(p => - this.userTransformer( - p, - this.integration.config, - this.config, - this.groupNameTransformer, - ), + this.userTransformer({ + user: p, + integrationConfig: this.integration.config, + providerConfig: this.config, + groupNameTransformer: this.groupNameTransformer, + }), ); - const groupEntities = this.createGroupEntities(groupsWithUsers); + + const groupEntities = this.groupEntitiesTransformer({ + groups: groupsWithUsers, + providerConfig: this.config, + groupNameTransformer: this.groupNameTransformer, + }); await this.connection.applyMutation({ type: 'full', @@ -317,34 +322,6 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { }); } - private createGroupEntities(groupResult: GitLabGroup[]): GroupEntity[] { - const idMapped: { [groupId: number]: GitLabGroup } = {}; - const entities: GroupEntity[] = []; - - for (const group of groupResult) { - idMapped[group.id] = group; - } - - for (const group of groupResult) { - const entity = this.groupTransformer( - group, - this.config, - this.groupNameTransformer, - ); - - if (group.parent_id && idMapped.hasOwnProperty(group.parent_id)) { - entity.spec.parent = this.groupNameTransformer( - idMapped[group.parent_id], - this.config, - ); - } - - entities.push(entity); - } - - return entities; - } - private withLocations(host: string, baseUrl: string, entity: Entity): Entity { const location = entity.kind === 'Group' From 08e2eb67b2270a9d2b9be5c7ec541bc0b9de26a6 Mon Sep 17 00:00:00 2001 From: Markus Date: Mon, 18 Dec 2023 18:30:57 +0100 Subject: [PATCH 007/283] chore: update api report Signed-off-by: Markus --- plugins/catalog-backend-module-gitlab/api-report.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/plugins/catalog-backend-module-gitlab/api-report.md b/plugins/catalog-backend-module-gitlab/api-report.md index 6620f6445f..eeab252b59 100644 --- a/plugins/catalog-backend-module-gitlab/api-report.md +++ b/plugins/catalog-backend-module-gitlab/api-report.md @@ -8,10 +8,14 @@ import { CatalogProcessorEmit } from '@backstage/plugin-catalog-node'; import { Config } from '@backstage/config'; import { EntityProvider } from '@backstage/plugin-catalog-node'; import { EntityProviderConnection } from '@backstage/plugin-catalog-node'; +import { GitLabIntegrationConfig } from '@backstage/integration'; +import { GroupEntity } from '@backstage/catalog-model'; import { LocationSpec } from '@backstage/plugin-catalog-node'; import { Logger } from 'winston'; import { PluginTaskScheduler } from '@backstage/backend-tasks'; import { TaskRunner } from '@backstage/backend-tasks'; +import { TaskScheduleDefinition } from '@backstage/backend-tasks'; +import { UserEntity } from '@backstage/catalog-model'; // @public export class GitlabDiscoveryEntityProvider implements EntityProvider { @@ -64,9 +68,18 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { logger: Logger; schedule?: TaskRunner; scheduler?: PluginTaskScheduler; + userTransformer?: UserTransformer; + groupEntitiesTransformer?: GroupTransformer; + groupNameTransformer?: GroupNameTransformer; }, ): GitlabOrgDiscoveryEntityProvider[]; // (undocumented) getProviderName(): string; } + +// Warnings were encountered during analysis: +// +// src/providers/GitlabOrgDiscoveryEntityProvider.d.ts:23:9 - (ae-forgotten-export) The symbol "UserTransformer" needs to be exported by the entry point index.d.ts +// src/providers/GitlabOrgDiscoveryEntityProvider.d.ts:24:9 - (ae-forgotten-export) The symbol "GroupTransformer" needs to be exported by the entry point index.d.ts +// src/providers/GitlabOrgDiscoveryEntityProvider.d.ts:25:9 - (ae-forgotten-export) The symbol "GroupNameTransformer" needs to be exported by the entry point index.d.ts ``` From 926abed8507cae629560b5503ed232bfc7840342 Mon Sep 17 00:00:00 2001 From: Markus Date: Mon, 18 Dec 2023 22:06:51 +0100 Subject: [PATCH 008/283] chore: api report Signed-off-by: Markus --- .../api-report.md | 90 +++++++++++++++++-- .../src/index.ts | 12 +++ .../src/lib/index.ts | 9 ++ .../src/lib/types.ts | 64 ++++++++++++- 4 files changed, 167 insertions(+), 8 deletions(-) diff --git a/plugins/catalog-backend-module-gitlab/api-report.md b/plugins/catalog-backend-module-gitlab/api-report.md index eeab252b59..bb52d8908a 100644 --- a/plugins/catalog-backend-module-gitlab/api-report.md +++ b/plugins/catalog-backend-module-gitlab/api-report.md @@ -57,6 +57,20 @@ export class GitLabDiscoveryProcessor implements CatalogProcessor { ): Promise; } +// @public +export type GitLabGroup = { + id: number; + name: string; + full_path: string; + description?: string; + parent_id?: number; +}; + +// @public (undocumented) +export type GitLabGroupSamlIdentity = { + extern_uid: string; +}; + // @public export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { // (undocumented) @@ -77,9 +91,75 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { getProviderName(): string; } -// Warnings were encountered during analysis: -// -// src/providers/GitlabOrgDiscoveryEntityProvider.d.ts:23:9 - (ae-forgotten-export) The symbol "UserTransformer" needs to be exported by the entry point index.d.ts -// src/providers/GitlabOrgDiscoveryEntityProvider.d.ts:24:9 - (ae-forgotten-export) The symbol "GroupTransformer" needs to be exported by the entry point index.d.ts -// src/providers/GitlabOrgDiscoveryEntityProvider.d.ts:25:9 - (ae-forgotten-export) The symbol "GroupNameTransformer" needs to be exported by the entry point index.d.ts +// @public +export type GitlabProviderConfig = { + host: string; + group: string; + id: string; + branch?: string; + fallbackBranch: string; + catalogFile: string; + projectPattern: RegExp; + userPattern: RegExp; + groupPattern: RegExp; + orgEnabled?: boolean; + schedule?: TaskScheduleDefinition; + skipForkedRepos?: boolean; +}; + +// @public +export type GitLabUser = { + id: number; + username: string; + email?: string; + name: string; + state: string; + web_url: string; + avatar_url: string; + groups?: GitLabGroup[]; + group_saml_identity?: GitLabGroupSamlIdentity; +}; + +// @public +export type GroupNameTransformer = ( + options: GroupNameTransformerOptions, +) => string; + +// @public +export interface GroupNameTransformerOptions { + // (undocumented) + group: GitLabGroup; + // (undocumented) + providerConfig: GitlabProviderConfig; +} + +// @public +export type GroupTransformer = ( + options: GroupTransformerOptions, +) => GroupEntity[]; + +// @public +export interface GroupTransformerOptions { + // (undocumented) + groupNameTransformer: GroupNameTransformer; + // (undocumented) + groups: GitLabGroup[]; + // (undocumented) + providerConfig: GitlabProviderConfig; +} + +// @public +export type UserTransformer = (options: UserTransformerOptions) => UserEntity; + +// @public +export interface UserTransformerOptions { + // (undocumented) + groupNameTransformer: GroupNameTransformer; + // (undocumented) + integrationConfig: GitLabIntegrationConfig; + // (undocumented) + providerConfig: GitlabProviderConfig; + // (undocumented) + user: GitLabUser; +} ``` diff --git a/plugins/catalog-backend-module-gitlab/src/index.ts b/plugins/catalog-backend-module-gitlab/src/index.ts index 2dd19c041d..cedcb828d6 100644 --- a/plugins/catalog-backend-module-gitlab/src/index.ts +++ b/plugins/catalog-backend-module-gitlab/src/index.ts @@ -25,3 +25,15 @@ export { GitlabDiscoveryEntityProvider, GitlabOrgDiscoveryEntityProvider, } from './providers'; +export type { + GitLabUser, + GitLabGroup, + GitlabProviderConfig, + GitLabGroupSamlIdentity, + GroupNameTransformer, + GroupNameTransformerOptions, + GroupTransformer, + GroupTransformerOptions, + UserTransformer, + UserTransformerOptions, +} from './lib'; diff --git a/plugins/catalog-backend-module-gitlab/src/lib/index.ts b/plugins/catalog-backend-module-gitlab/src/lib/index.ts index 53fad07994..1eee268862 100644 --- a/plugins/catalog-backend-module-gitlab/src/lib/index.ts +++ b/plugins/catalog-backend-module-gitlab/src/lib/index.ts @@ -16,8 +16,17 @@ export { GitLabClient, paginated } from './client'; export type { + GitLabUser, + GitLabGroup, + GitLabGroupSamlIdentity, GitLabProject, GitlabProviderConfig, GitlabGroupDescription, + GroupNameTransformer, + GroupNameTransformerOptions, + GroupTransformer, + GroupTransformerOptions, + UserTransformer, + UserTransformerOptions, } from './types'; export { readGitlabConfigs } from '../providers/config'; diff --git a/plugins/catalog-backend-module-gitlab/src/lib/types.ts b/plugins/catalog-backend-module-gitlab/src/lib/types.ts index 4a15d44d04..25c9a4a232 100644 --- a/plugins/catalog-backend-module-gitlab/src/lib/types.ts +++ b/plugins/catalog-backend-module-gitlab/src/lib/types.ts @@ -42,6 +42,11 @@ export type GitLabProject = { forked_from_project?: GitlabProjectForkedFrom; }; +/** + * Representation of a GitLab user in the GitLab API + * + * @public + */ export type GitLabUser = { id: number; username: string; @@ -54,10 +59,18 @@ export type GitLabUser = { group_saml_identity?: GitLabGroupSamlIdentity; }; +/** + * @public + */ export type GitLabGroupSamlIdentity = { extern_uid: string; }; +/** + * Representation of a GitLab group in the GitLab API + * + * @public + */ export type GitLabGroup = { id: number; name: string; @@ -115,14 +128,25 @@ export type GitLabDescendantGroupsResponse = { }; }; }; - +/** + * The configuration parameters for the GitlabProvider + * + * @public + */ export type GitlabProviderConfig = { + /** + * Identifies one of the hosts set up in the integrations + */ host: string; /** - * Group and subgroup (if needed) to look for repositories. If not present the whole instance will be scanned. - * If present this if present, the discovered groups won't contain this prefix + * Required for gitlab.com when `orgEnabled: true`. + * Optional for self managed. Must not end with slash. + * Accepts only groups under the provided path (which will be stripped) */ group: string; + /** + * ??? + */ id: string; /** * The name of the branch to be used, to discover catalog files. @@ -134,12 +158,31 @@ export type GitlabProviderConfig = { * Defaults to: `master` */ fallbackBranch: string; + /** + * Defaults to `catalog-info.yaml` + */ catalogFile: string; + /** + * Filters found projects based on provided patter. + * Defaults to `[\s\S]*`, which means to not filter anything + */ projectPattern: RegExp; + /** + * Filters found users based on provided patter. + * Defaults to `[\s\S]*`, which means to not filter anything + */ userPattern: RegExp; + /** + * Filters found groups based on provided patter. + * Defaults to `[\s\S]*`, which means to not filter anything + */ groupPattern: RegExp; + orgEnabled?: boolean; schedule?: TaskScheduleDefinition; + /** + * If the project is a fork, skip repository + */ skipForkedRepos?: boolean; }; @@ -152,6 +195,11 @@ export type GroupNameTransformer = ( options: GroupNameTransformerOptions, ) => string; +/** + * The GroupTransformerOptions + * + * @public + */ export interface GroupNameTransformerOptions { group: GitLabGroup; providerConfig: GitlabProviderConfig; @@ -162,6 +210,11 @@ export interface GroupNameTransformerOptions { * @public */ export type UserTransformer = (options: UserTransformerOptions) => UserEntity; +/** + * The UserTransformerOptions + * + * @public + */ export interface UserTransformerOptions { user: GitLabUser; integrationConfig: GitLabIntegrationConfig; @@ -177,6 +230,11 @@ export interface UserTransformerOptions { export type GroupTransformer = ( options: GroupTransformerOptions, ) => GroupEntity[]; +/** + * The GroupTransformer options + * + * @public + */ export interface GroupTransformerOptions { groups: GitLabGroup[]; providerConfig: GitlabProviderConfig; From 1f70e46680b82ea9ae0c2a68788fbe33127bab7d Mon Sep 17 00:00:00 2001 From: Samuel Stadler Date: Wed, 22 Nov 2023 18:51:32 +0100 Subject: [PATCH 009/283] improves EntityValidationPage UX Signed-off-by: Samuel Stadler --- .changeset/metal-students-drive.md | 5 + .../EntityValidationPage.test.tsx | 91 +++++++++++++++++++ .../EntityValidationPage.tsx | 81 +++++++++++------ 3 files changed, 148 insertions(+), 29 deletions(-) create mode 100644 .changeset/metal-students-drive.md create mode 100644 plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.test.tsx diff --git a/.changeset/metal-students-drive.md b/.changeset/metal-students-drive.md new file mode 100644 index 0000000000..5ba8f4ee3d --- /dev/null +++ b/.changeset/metal-students-drive.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-entity-validation': minor +--- + +Improves UX of the EntityValidationPage: Moves the validate button below the EntityTextArea which is actually validated, the location TextField can now be hidden to prevent confusion about what is validated and additional content can be added to the top of the validation page. diff --git a/plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.test.tsx b/plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.test.tsx new file mode 100644 index 0000000000..c8827ffc13 --- /dev/null +++ b/plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.test.tsx @@ -0,0 +1,91 @@ +/* + * 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 React from 'react'; +import { TestApiProvider, renderInTestApp } from '@backstage/test-utils'; +import { EntityValidationPage } from './EntityValidationPage'; +import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react'; +import { MarkdownContent } from '@backstage/core-components'; + +describe('EntityValidatorPage', () => { + const catalogApi: Partial = { + getEntities: () => + Promise.resolve({ + items: [ + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'API', + metadata: { + name: 'Entity1', + annotations: { + 'backstage.io/view-url': 'viewurl', + 'backstage.io/edit-url': 'editurl', + }, + }, + spec: { type: 'openapi' }, + }, + ], + }), + }; + + const contentHead = ; + + it('should show loation text field', async () => { + const { getByText, getByTestId } = await renderInTestApp( + + + , + ); + const mainGrid = getByTestId('main-grid'); + + expect(mainGrid.children.length).toBe(2); + expect(getByText('File Location')).toBeInTheDocument(); + }); + + it('should not show loation text field', async () => { + const { queryByText, getByTestId } = await renderInTestApp( + + + , + ); + const mainGrid = getByTestId('main-grid'); + + expect(mainGrid.children.length).toBe(1); + expect(queryByText('File Location')).not.toBeInTheDocument(); + }); + + it('should not show content head', async () => { + const { getByTestId } = await renderInTestApp( + + + , + ); + const mainGrid = getByTestId('main-grid'); + + expect(mainGrid.children.length).toBe(2); + }); + + it('should show content head', async () => { + const { getByTestId } = await renderInTestApp( + + + , + ); + const mainGrid = getByTestId('main-grid'); + + expect(mainGrid.children.length).toBe(3); + }); +}); diff --git a/plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.tsx b/plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.tsx index 0f0e60366b..c3e6386a37 100644 --- a/plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.tsx +++ b/plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.tsx @@ -15,9 +15,9 @@ */ import React, { useState } from 'react'; -import { Content, Header, LinkButton, Page } from '@backstage/core-components'; +import { Content, Header, Page } from '@backstage/core-components'; import { EntityTextArea } from '../EntityTextArea'; -import { Grid, TextField } from '@material-ui/core'; +import { Button, Grid, TextField } from '@material-ui/core'; import { CatalogProcessorResult } from '../../types'; import { parseEntityYaml } from '../../utils'; import { EntityValidationOutput } from '../EntityValidationOutput'; @@ -40,10 +40,14 @@ spec: export const EntityValidationPage = (props: { defaultYaml?: string; defaultLocation?: string; + hideFileLocationField?: boolean; + contentHead?: React.ReactNode; }) => { const { defaultYaml = EXAMPLE_CATALOG_INFO_YAML, defaultLocation = 'https://github.com/backstage/backstage/blob/master/catalog-info.yaml', + hideFileLocationField = false, + contentHead, } = props; const [catalogYaml, setCatalogYaml] = useState(defaultYaml); @@ -67,8 +71,16 @@ export const EntityValidationPage = (props: { subtitle="Tool to validate catalog-info.yaml files" /> - - + + {contentHead} + + {!hideFileLocationField && ( setLocationUrl(e.target.value)} /> - - - - - - Validate - + )} + + + + + + setCatalogYaml(value)} + catalogYaml={catalogYaml} + /> + + + + - - - - - setCatalogYaml(value)} - catalogYaml={catalogYaml} - /> - - - - - + + + + + From 8edf7a9d0198ce3cecf2b601fd7261489ab8d1b0 Mon Sep 17 00:00:00 2001 From: Samuel Stadler Date: Thu, 23 Nov 2023 09:02:27 +0100 Subject: [PATCH 010/283] update api-report.md Signed-off-by: Samuel Stadler --- plugins/entity-validation/api-report.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/entity-validation/api-report.md b/plugins/entity-validation/api-report.md index 9d69458ed0..95fdfaf42c 100644 --- a/plugins/entity-validation/api-report.md +++ b/plugins/entity-validation/api-report.md @@ -7,12 +7,15 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; import { JSX as JSX_2 } from 'react'; +import { ReactNode } from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; // @public (undocumented) export const EntityValidationPage: (props: { defaultYaml?: string | undefined; defaultLocation?: string | undefined; + hideFileLocationField?: boolean | undefined; + contentHead?: ReactNode; }) => JSX_2.Element; // @public (undocumented) From 84ca0aef20329ba9d3f6130fdd96fec661042dc8 Mon Sep 17 00:00:00 2001 From: Samuel Stadler Date: Tue, 12 Dec 2023 09:42:01 +0100 Subject: [PATCH 011/283] use patch impact for changeset Signed-off-by: Samuel Stadler --- .changeset/metal-students-drive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/metal-students-drive.md b/.changeset/metal-students-drive.md index 5ba8f4ee3d..04f338c64e 100644 --- a/.changeset/metal-students-drive.md +++ b/.changeset/metal-students-drive.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-entity-validation': minor +'@backstage/plugin-entity-validation': patch --- Improves UX of the EntityValidationPage: Moves the validate button below the EntityTextArea which is actually validated, the location TextField can now be hidden to prevent confusion about what is validated and additional content can be added to the top of the validation page. From 14e40441790cf37029db328d3574d7769d98ecb6 Mon Sep 17 00:00:00 2001 From: Samuel Stadler Date: Fri, 22 Dec 2023 12:20:04 +0100 Subject: [PATCH 012/283] add @backstage/test-utils as devDependency Signed-off-by: Samuel Stadler --- plugins/entity-validation/package.json | 1 + yarn.lock | 1 + 2 files changed, 2 insertions(+) diff --git a/plugins/entity-validation/package.json b/plugins/entity-validation/package.json index 76decd04f6..052835c061 100644 --- a/plugins/entity-validation/package.json +++ b/plugins/entity-validation/package.json @@ -57,6 +57,7 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", + "@backstage/test-utils": "workspace:^", "@testing-library/dom": "^9.0.0", "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0" diff --git a/yarn.lock b/yarn.lock index 45162812d9..fa2180a957 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6241,6 +6241,7 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/plugin-catalog-common": "workspace:^" "@backstage/plugin-catalog-react": "workspace:^" + "@backstage/test-utils": "workspace:^" "@codemirror/language": ^6.0.0 "@codemirror/legacy-modes": ^6.1.0 "@codemirror/view": ^6.0.0 From b17facf2f7c874b28d26c69f4a35bcf027609c2c Mon Sep 17 00:00:00 2001 From: Markus Siebert Date: Sat, 23 Dec 2023 08:46:33 +0100 Subject: [PATCH 013/283] neat-hotels-wink.md aktualisieren Co-authored-by: Vincenzo Scamporlino Signed-off-by: Markus Siebert --- .changeset/neat-hotels-wink.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/neat-hotels-wink.md b/.changeset/neat-hotels-wink.md index a37d282578..fca82e38fa 100644 --- a/.changeset/neat-hotels-wink.md +++ b/.changeset/neat-hotels-wink.md @@ -2,4 +2,4 @@ '@backstage/plugin-catalog-backend-module-gitlab': patch --- -add `groupTransformer`, `userTransformer` and `groupNameTransformer` to allow custom transformations when groups and users are created +Added the option to provide custom `groupTransformer`, `userTransformer` and `groupNameTransformer` to allow custom transformations of groups and users From 797a32953b68191e0882d0cac1cc721739277a15 Mon Sep 17 00:00:00 2001 From: Aizat Faiz Date: Sun, 24 Dec 2023 17:51:24 +0800 Subject: [PATCH 014/283] ux: use consistent icons for sytem and template Signed-off-by: Aizat Faiz --- .changeset/loud-walls-compare.md | 5 +++++ packages/app-defaults/src/defaults/icons.tsx | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 .changeset/loud-walls-compare.md diff --git a/.changeset/loud-walls-compare.md b/.changeset/loud-walls-compare.md new file mode 100644 index 0000000000..3616006675 --- /dev/null +++ b/.changeset/loud-walls-compare.md @@ -0,0 +1,5 @@ +--- +'@backstage/app-defaults': patch +--- + +Fixed inconsistencies in icons used for System and Template diff --git a/packages/app-defaults/src/defaults/icons.tsx b/packages/app-defaults/src/defaults/icons.tsx index fbdfb14e5b..9f83b01988 100644 --- a/packages/app-defaults/src/defaults/icons.tsx +++ b/packages/app-defaults/src/defaults/icons.tsx @@ -17,7 +17,7 @@ import { IconComponent } from '@backstage/core-plugin-api'; import MuiApartmentIcon from '@material-ui/icons/Apartment'; import MuiBrokenImageIcon from '@material-ui/icons/BrokenImage'; -import MuiCategoryIcon from '@material-ui/icons/Category'; +import MuiBusinessIcon from '@material-ui/icons/Business'; import MuiCreateNewFolderIcon from '@material-ui/icons/CreateNewFolder'; import MuiSubjectIcon from '@material-ui/icons/Subject'; import MuiSearchIcon from '@material-ui/icons/Search'; @@ -35,7 +35,7 @@ import MuiPeopleIcon from '@material-ui/icons/People'; import MuiPersonIcon from '@material-ui/icons/Person'; import MuiWarningIcon from '@material-ui/icons/Warning'; import MuiWorkIcon from '@material-ui/icons/Work'; -import MuiFeaturedPlayListIcon from '@material-ui/icons/FeaturedPlayList'; +import MuiLibraryAddIcon from '@material-ui/icons/LibraryAdd'; export const icons = { brokenImage: MuiBrokenImageIcon as IconComponent, @@ -56,10 +56,10 @@ export const icons = { 'kind:domain': MuiApartmentIcon as IconComponent, 'kind:group': MuiPeopleIcon as IconComponent, 'kind:location': MuiLocationOnIcon as IconComponent, - 'kind:system': MuiCategoryIcon as IconComponent, + 'kind:system': MuiBusinessIcon as IconComponent, 'kind:user': MuiPersonIcon as IconComponent, 'kind:resource': MuiWorkIcon as IconComponent, - 'kind:template': MuiFeaturedPlayListIcon as IconComponent, + 'kind:template': MuiLibraryAddIcon as IconComponent, user: MuiPersonIcon as IconComponent, warning: MuiWarningIcon as IconComponent, }; From b37b31ec8a4358ee3d3741226fffa842b1da9e23 Mon Sep 17 00:00:00 2001 From: Aizat Faiz Date: Mon, 25 Dec 2023 08:18:52 +0800 Subject: [PATCH 015/283] switch icons Signed-off-by: Aizat Faiz --- packages/app-defaults/src/defaults/icons.tsx | 8 ++++---- .../catalog/src/apis/EntityPresentationApi/defaults.tsx | 8 ++++---- plugins/catalog/src/components/AboutCard/AboutCard.tsx | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/app-defaults/src/defaults/icons.tsx b/packages/app-defaults/src/defaults/icons.tsx index 9f83b01988..fbdfb14e5b 100644 --- a/packages/app-defaults/src/defaults/icons.tsx +++ b/packages/app-defaults/src/defaults/icons.tsx @@ -17,7 +17,7 @@ import { IconComponent } from '@backstage/core-plugin-api'; import MuiApartmentIcon from '@material-ui/icons/Apartment'; import MuiBrokenImageIcon from '@material-ui/icons/BrokenImage'; -import MuiBusinessIcon from '@material-ui/icons/Business'; +import MuiCategoryIcon from '@material-ui/icons/Category'; import MuiCreateNewFolderIcon from '@material-ui/icons/CreateNewFolder'; import MuiSubjectIcon from '@material-ui/icons/Subject'; import MuiSearchIcon from '@material-ui/icons/Search'; @@ -35,7 +35,7 @@ import MuiPeopleIcon from '@material-ui/icons/People'; import MuiPersonIcon from '@material-ui/icons/Person'; import MuiWarningIcon from '@material-ui/icons/Warning'; import MuiWorkIcon from '@material-ui/icons/Work'; -import MuiLibraryAddIcon from '@material-ui/icons/LibraryAdd'; +import MuiFeaturedPlayListIcon from '@material-ui/icons/FeaturedPlayList'; export const icons = { brokenImage: MuiBrokenImageIcon as IconComponent, @@ -56,10 +56,10 @@ export const icons = { 'kind:domain': MuiApartmentIcon as IconComponent, 'kind:group': MuiPeopleIcon as IconComponent, 'kind:location': MuiLocationOnIcon as IconComponent, - 'kind:system': MuiBusinessIcon as IconComponent, + 'kind:system': MuiCategoryIcon as IconComponent, 'kind:user': MuiPersonIcon as IconComponent, 'kind:resource': MuiWorkIcon as IconComponent, - 'kind:template': MuiLibraryAddIcon as IconComponent, + 'kind:template': MuiFeaturedPlayListIcon as IconComponent, user: MuiPersonIcon as IconComponent, warning: MuiWarningIcon as IconComponent, }; diff --git a/plugins/catalog/src/apis/EntityPresentationApi/defaults.tsx b/plugins/catalog/src/apis/EntityPresentationApi/defaults.tsx index 84f04c6f83..c2abeb5e6a 100644 --- a/plugins/catalog/src/apis/EntityPresentationApi/defaults.tsx +++ b/plugins/catalog/src/apis/EntityPresentationApi/defaults.tsx @@ -18,10 +18,10 @@ import { IconComponent } from '@backstage/core-plugin-api'; import { defaultEntityPresentation } from '@backstage/plugin-catalog-react'; import { HumanDuration } from '@backstage/types'; import ApartmentIcon from '@material-ui/icons/Apartment'; -import BusinessIcon from '@material-ui/icons/Business'; +import CategoryIcon from '@material-ui/icons/Category'; import ExtensionIcon from '@material-ui/icons/Extension'; import HelpIcon from '@material-ui/icons/Help'; -import LibraryAddIcon from '@material-ui/icons/LibraryAdd'; +import FeaturedPlayListIcon from '@material-ui/icons/FeaturedPlayList'; import LocationOnIcon from '@material-ui/icons/LocationOn'; import MemoryIcon from '@material-ui/icons/Memory'; import PeopleIcon from '@material-ui/icons/People'; @@ -38,13 +38,13 @@ export const UNKNOWN_KIND_ICON: IconComponent = HelpIcon; export const DEFAULT_ICONS: Record = { api: ExtensionIcon, component: MemoryIcon, - system: BusinessIcon, + system: CategoryIcon, resource: WorkIcon, domain: ApartmentIcon, location: LocationOnIcon, user: PersonIcon, group: PeopleIcon, - template: LibraryAddIcon, + template: FeaturedPlayListIcon, }; export function createDefaultRenderer(options: { diff --git a/plugins/catalog/src/components/AboutCard/AboutCard.tsx b/plugins/catalog/src/components/AboutCard/AboutCard.tsx index 763f6fc094..2bbbc20760 100644 --- a/plugins/catalog/src/components/AboutCard/AboutCard.tsx +++ b/plugins/catalog/src/components/AboutCard/AboutCard.tsx @@ -166,7 +166,7 @@ export function AboutCard(props: AboutCardProps) { const subHeaderLinks = [viewInSource, viewInTechDocs]; if (isTemplateEntityV1beta3(entity)) { - const Icon = app.getSystemIcon('scaffolder') ?? CreateComponentIcon; + const Icon = app.getSystemIcon('kind:template') ?? CreateComponentIcon; const launchTemplate: IconLinkVerticalProps = { label: 'Launch Template', From 976612c68af75ac445143b3056660a183f0607bf Mon Sep 17 00:00:00 2001 From: Aizat Faiz Date: Wed, 27 Dec 2023 10:20:05 +0800 Subject: [PATCH 016/283] change impacted package Signed-off-by: Aizat Faiz --- .changeset/loud-walls-compare.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/loud-walls-compare.md b/.changeset/loud-walls-compare.md index 3616006675..495ad933d9 100644 --- a/.changeset/loud-walls-compare.md +++ b/.changeset/loud-walls-compare.md @@ -1,5 +1,5 @@ --- -'@backstage/app-defaults': patch +'@backstage/plugin-catalog': patch --- Fixed inconsistencies in icons used for System and Template From f180cba319a13f2ee013920dced6d58786e6dcb5 Mon Sep 17 00:00:00 2001 From: Andres Mauricio Gomez P Date: Wed, 13 Dec 2023 10:21:56 -0500 Subject: [PATCH 017/283] Enabling authentication to kubernetes clusters with mTLS x509 client certs Signed-off-by: Andres Mauricio Gomez P --- .changeset/tame-numbers-smile.md | 6 +++ .../src/service/KubernetesFetcher.test.ts | 2 +- .../src/service/KubernetesFetcher.ts | 7 ++- .../src/service/KubernetesProxy.ts | 43 +++++++++++-------- plugins/kubernetes-node/api-report.md | 5 +++ plugins/kubernetes-node/src/types/types.ts | 1 + 6 files changed, 43 insertions(+), 21 deletions(-) create mode 100644 .changeset/tame-numbers-smile.md diff --git a/.changeset/tame-numbers-smile.md b/.changeset/tame-numbers-smile.md new file mode 100644 index 0000000000..1d675f8c9c --- /dev/null +++ b/.changeset/tame-numbers-smile.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +'@backstage/plugin-kubernetes-node': patch +--- + +Enabling authentication to kubernetes clusters with mTLS x509 client certs diff --git a/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts b/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts index e388589e74..0d9f067707 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts @@ -895,7 +895,7 @@ describe('KubernetesFetcher', () => { customResources: [], }); return expect(result).rejects.toThrow( - "no bearer token for cluster 'unauthenticated-cluster' and not running in Kubernetes", + "no bearer token or client cert for cluster 'unauthenticated-cluster' and not running in Kubernetes", ); }); }); diff --git a/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts b/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts index 99501c48c6..4daf3e80f6 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts @@ -224,13 +224,14 @@ export class KubernetesClientBasedFetcher implements KubernetesFetcher { [url, requestInit] = this.fetchArgsInCluster(credential); } else if ( credential.type === 'bearer token' || + credential.type === 'x509 client certificate' || authProvider === 'localKubectlProxy' ) { [url, requestInit] = this.fetchArgs(clusterDetails, credential); } else { return Promise.reject( new Error( - `no bearer token for cluster '${clusterDetails.name}' and not running in Kubernetes`, + `no bearer token or client cert for cluster '${clusterDetails.name}' and not running in Kubernetes`, ), ); } @@ -272,6 +273,10 @@ export class KubernetesClientBasedFetcher implements KubernetesFetcher { clusterDetails.caData, ) ?? undefined, rejectUnauthorized: !clusterDetails.skipTLSVerify, + ...(credential.type === 'x509 client certificate' && { + cert: credential.cert, + key: credential.key, + }), }); } return [url, requestInit]; diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts index 8a07267cde..209d01b703 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts @@ -113,24 +113,6 @@ export class KubernetesProxy { return; } - const authHeader = req.header(HEADER_KUBERNETES_AUTH); - if (authHeader) { - req.headers.authorization = authHeader; - } else { - // Map Backstage-Kubernetes-Authorization-X-X headers to a KubernetesRequestAuth object - const authObj = KubernetesProxy.authHeadersToKubernetesRequestAuth( - req.headers, - ); - - const credential = await this.getClusterForRequest(req).then(cd => { - return this.authStrategy.getCredential(cd, authObj); - }); - - if (credential.type === 'bearer token') { - req.headers.authorization = `Bearer ${credential.token}`; - } - } - const middleware = await this.getMiddleware(req); // If req is an upgrade handshake, use middleware upgrade instead of http request handler https://github.com/chimurai/http-proxy-middleware#external-websocket-upgrade @@ -173,7 +155,7 @@ export class KubernetesProxy { const cluster = await this.getClusterForRequest(req); const url = new URL(cluster.url); - return { + const target: any = { protocol: url.protocol, host: url.hostname, port: url.port, @@ -182,6 +164,29 @@ export class KubernetesProxy { cluster.caData, )?.toString(), }; + + const authHeader = req.header(HEADER_KUBERNETES_AUTH); + if (authHeader) { + req.headers.authorization = authHeader; + } else { + // Map Backstage-Kubernetes-Authorization-X-X headers to a KubernetesRequestAuth object + const authObj = KubernetesProxy.authHeadersToKubernetesRequestAuth( + req.headers, + ); + + const credential = await this.getClusterForRequest(req).then(cd => { + return this.authStrategy.getCredential(cd, authObj); + }); + + if (credential.type === 'bearer token') { + req.headers.authorization = `Bearer ${credential.token}`; + } else if (credential.type === 'x509 client certificate') { + target.key = credential.key; + target.cert = credential.cert; + } + } + + return target; }, onError: (error, req, res) => { const wrappedError = new ForwardedError( diff --git a/plugins/kubernetes-node/api-report.md b/plugins/kubernetes-node/api-report.md index 2272035742..4c858ec969 100644 --- a/plugins/kubernetes-node/api-report.md +++ b/plugins/kubernetes-node/api-report.md @@ -100,6 +100,11 @@ export type KubernetesCredential = type: 'bearer token'; token: string; } + | { + type: 'x509 client certificate'; + cert: string; + key: string; + } | { type: 'anonymous'; }; diff --git a/plugins/kubernetes-node/src/types/types.ts b/plugins/kubernetes-node/src/types/types.ts index a0f48d0c26..036b54ed98 100644 --- a/plugins/kubernetes-node/src/types/types.ts +++ b/plugins/kubernetes-node/src/types/types.ts @@ -139,6 +139,7 @@ export interface KubernetesClustersSupplier { */ export type KubernetesCredential = | { type: 'bearer token'; token: string } + | { type: 'x509 client certificate'; cert: string; key: string } | { type: 'anonymous' }; /** From 3cc0d262066b83c8ae5f100af6a271ed27d6cdd7 Mon Sep 17 00:00:00 2001 From: Andres Mauricio Gomez P Date: Thu, 14 Dec 2023 14:19:24 -0500 Subject: [PATCH 018/283] Adding tests on KubernetesFetcher and KubernetesProxy for x509 client cert authentication Signed-off-by: Andres Mauricio Gomez P --- .../src/service/KubernetesFetcher.test.ts | 123 ++++++++++++++++++ .../src/service/KubernetesFetcher.ts | 33 +++-- .../src/service/KubernetesProxy.test.ts | 61 +++++++++ 3 files changed, 209 insertions(+), 8 deletions(-) diff --git a/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts b/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts index 0d9f067707..966fda7ce5 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts @@ -812,6 +812,129 @@ describe('KubernetesFetcher', () => { const [[{ agent }]] = httpsRequest.mock.calls; expect(agent.options.rejectUnauthorized).toBe(false); }); + + it('should use a x509 client cert authentication strategy to consume kubeapi when backstage-kubernetes-auth field is not provided and the authStrategy enables x509 client cert authentication - fetchObjectsForService', async () => { + worker.use( + rest.get('https://localhost:9999/api/v1/pods', (req, res, ctx) => + res( + checkToken(req, ctx, 'token'), + withLabels(req, ctx, { + items: [{ metadata: { name: 'pod-name' } }], + }), + ), + ), + ); + + const myCert = 'MOCKCert'; + const myKey = 'MOCKKey'; + + const result = sut.fetchObjectsForService({ + serviceId: 'some-service', + clusterDetails: { + name: 'cluster1', + url: 'https://localhost:9999', + authMetadata: {}, + caData: 'MOCKCA', + }, + credential: { + type: 'x509 client certificate', + cert: myCert, + key: myKey, + }, + objectTypesToFetch: new Set([ + { + group: '', + apiVersion: 'v1', + plural: 'pods', + objectType: 'pods', + }, + ]), + labelSelector: '', + customResources: [], + }); + + await expect(result).rejects.toThrow(/PEM/); + + expect(httpsRequest).toHaveBeenCalledTimes(1); + const [[{ agent }]] = httpsRequest.mock.calls; + expect(agent.options.ca.toString('base64')).toMatch('MOCKCA'); + expect(agent.options.cert).toEqual(myCert); + expect(agent.options.key).toEqual(myKey); + }); + + it('should use a x509 client cert authentication strategy to consume kubeapi when backstage-kubernetes-auth field is not provided and the authStrategy enables x509 client cert authentication - fetchPodMetricsByNamespaces', async () => { + worker.use( + rest.get( + 'https://localhost:9999/api/v1/namespaces/:namespace/pods', + (req, res, ctx) => + res( + withLabels(req, ctx, { + items: [ + { + metadata: { name: 'pod-name' }, + spec: { + containers: [ + { + name: 'container-name', + resources: { + requests: { cpu: '500m', memory: '512M' }, + limits: { cpu: '1000m', memory: '1G' }, + }, + }, + ], + }, + }, + ], + }), + ), + ), + rest.get( + 'https://localhost:9999/apis/metrics.k8s.io/v1beta1/namespaces/:namespace/pods', + (req, res, ctx) => + res( + withLabels(req, ctx, { + items: [ + { + metadata: { name: 'pod-name' }, + containers: [ + { + name: 'container-name', + usage: { cpu: '0', memory: '0' }, + }, + ], + }, + ], + }), + ), + ), + ); + + const myCert = 'MOCKCert'; + const myKey = 'MOCKKey'; + + const result = sut.fetchPodMetricsByNamespaces( + { + name: 'cluster1', + url: 'https://localhost:9999', + authMetadata: {}, + caData: 'MOCKCA', + }, + { + type: 'x509 client certificate', + cert: myCert, + key: myKey, + }, + new Set(['ns-a']), + ); + + await expect(result).rejects.toThrow(/PEM/); + + expect(httpsRequest).toHaveBeenCalledTimes(2); + const [[{ agent }]] = httpsRequest.mock.calls; + expect(agent.options.ca.toString('base64')).toMatch('MOCKCA'); + expect(agent.options.cert).toEqual(myCert); + expect(agent.options.key).toEqual(myKey); + }); }); it('should use namespace if provided', async () => { diff --git a/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts b/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts index 4daf3e80f6..cf4e3f9440 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts @@ -216,16 +216,11 @@ export class KubernetesClientBasedFetcher implements KubernetesFetcher { let requestInit: RequestInit; const authProvider = clusterDetails.authMetadata[ANNOTATION_KUBERNETES_AUTH_PROVIDER]; - if ( - authProvider === 'serviceAccount' && - !clusterDetails.authMetadata.serviceAccountToken && - fs.pathExistsSync(Config.SERVICEACCOUNT_CA_PATH) - ) { + + if (this.isServiceAccountAuthentication(authProvider, clusterDetails)) { [url, requestInit] = this.fetchArgsInCluster(credential); } else if ( - credential.type === 'bearer token' || - credential.type === 'x509 client certificate' || - authProvider === 'localKubectlProxy' + this.isTokenOrClientCertificateAuthentication(authProvider, credential) ) { [url, requestInit] = this.fetchArgs(clusterDetails, credential); } else { @@ -249,6 +244,28 @@ export class KubernetesClientBasedFetcher implements KubernetesFetcher { return fetch(url, requestInit); } + private isServiceAccountAuthentication( + authProvider: string, + clusterDetails: ClusterDetails, + ) { + return ( + authProvider === 'serviceAccount' && + !clusterDetails.authMetadata.serviceAccountToken && + fs.pathExistsSync(Config.SERVICEACCOUNT_CA_PATH) + ); + } + + private isTokenOrClientCertificateAuthentication( + authProvider: string, + credential: KubernetesCredential, + ) { + return ( + credential.type === 'bearer token' || + credential.type === 'x509 client certificate' || + authProvider === 'localKubectlProxy' + ); + } + private fetchArgs( clusterDetails: ClusterDetails, credential: KubernetesCredential, diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts index 9bee21867d..94a8b2918e 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts @@ -820,6 +820,67 @@ describe('KubernetesProxy', () => { expect(ca).toMatch('MOCKCA'); }); }); + + it('should use a x509 client cert authentication strategy to consume kubeapi when backstage-kubernetes-auth field is not provided and the authStrategy enables x509 client cert authentication', async () => { + worker.use( + rest.get( + 'https://localhost:9999/api/v1/namespaces', + (req: any, res: any, ctx: any) => { + if (req.headers.get('Authorization')) { + return res(ctx.status(403)); + } + + return res( + ctx.status(200), + ctx.json({ + kind: 'NamespaceList', + apiVersion: 'v1', + items: [], + }), + ); + }, + ), + ); + + clusterSupplier.getClusters.mockResolvedValue([ + { + name: 'cluster1', + url: 'https://localhost:9999', + authMetadata: {}, + }, + ]); + + const myCert = 'MOCKCert'; + const myKey = 'MOCKKey'; + + authStrategy.getCredential.mockResolvedValue({ + type: 'x509 client certificate', + cert: myCert, + key: myKey, + }); + + const requestPromise = setupProxyPromise({ + proxyPath: '/mountpath', + requestPath: '/api/v1/namespaces', + + headers: { [HEADER_KUBERNETES_CLUSTER]: 'cluster1' }, + }); + + const response = await requestPromise; + + expect(authStrategy.getCredential).toHaveBeenCalledTimes(1); + expect(authStrategy.getCredential).toHaveBeenCalledWith( + expect.anything(), + {}, + ); + + const [[{ key, cert }]] = httpsRequest.mock.calls; + expect(cert).toEqual(myCert); + expect(key).toEqual(myKey); + + // 500 Since the key and cert are fake + expect(response.status).toEqual(500); + }); }); describe('WebSocket', () => { From 618ed7830f85479ec09cb40f399fe2adf51057e5 Mon Sep 17 00:00:00 2001 From: Mayaw Power Date: Mon, 1 Jan 2024 16:15:45 +0800 Subject: [PATCH 019/283] Update README-zh_Hans.md fix typo error Signed-off-by: Mayaw Power --- README-zh_Hans.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README-zh_Hans.md b/README-zh_Hans.md index bf96eea389..b1e5a16add 100644 --- a/README-zh_Hans.md +++ b/README-zh_Hans.md @@ -57,7 +57,7 @@ Backstage 的文档包括: - [参与贡献 Backstage](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md) - 如果您想做出贡献,请从这里开始 - [RFCs](https://github.com/backstage/backstage/labels/rfc) - 帮助制定技术方向 - [FAQ](https://backstage.io/docs/FAQ) - n.: 常问问题 -- [行为准则](CODE_OF_CONDUCT.md) - 这是我们的刑事方式 +- [行为准则](CODE_OF_CONDUCT.md) - 这是我们的行事方式 - [采纳者](ADOPTERS.md) - 已经在使用 Backstage 的公司 - [博客](https://backstage.io/blog/) - 公告和更新 - [通讯](https://spoti.fi/backstagenewsletter) - 订阅我们的电子邮件通讯 From 047beadd9ddebbf2b9b44d27055d1b30a8af3e7b Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Mon, 4 Dec 2023 12:36:50 +0200 Subject: [PATCH 020/283] feat: signals plugins next try after #18153 without any external dependencies and only supporting websocket. missing tests and necessary documentation but will work on those after initial comments if this would be proper way to go forward. already planning for the notification plugins on top of this. Signed-off-by: Heikki Hellgren --- .changeset/real-eggs-sip.md | 7 + packages/backend/package.json | 2 + packages/backend/src/index.ts | 11 +- packages/backend/src/plugins/signals.ts | 39 +++ .../Content/InfoContent/InfoContent.tsx | 13 + plugins/signals-backend/.eslintrc.js | 1 + plugins/signals-backend/README.md | 31 +++ plugins/signals-backend/api-report.md | 22 ++ plugins/signals-backend/catalog-info.yaml | 9 + plugins/signals-backend/package.json | 50 ++++ plugins/signals-backend/src/index.ts | 16 ++ plugins/signals-backend/src/run.ts | 32 +++ .../src/service/router.test.ts | 48 ++++ plugins/signals-backend/src/service/router.ts | 57 +++++ .../src/service/standaloneServer.ts | 69 ++++++ plugins/signals-backend/src/setupTests.ts | 16 ++ plugins/signals-node/.eslintrc.js | 1 + plugins/signals-node/README.md | 5 + plugins/signals-node/api-report.md | 47 ++++ plugins/signals-node/catalog-info.yaml | 10 + plugins/signals-node/package.json | 42 ++++ plugins/signals-node/src/SignalsService.ts | 226 ++++++++++++++++++ plugins/signals-node/src/index.ts | 18 ++ plugins/signals-node/src/setupTests.ts | 16 ++ plugins/signals-node/src/types.ts | 39 +++ plugins/signals-react/.eslintrc.js | 1 + plugins/signals-react/README.md | 5 + plugins/signals-react/api-report.md | 45 ++++ plugins/signals-react/catalog-info.yaml | 10 + plugins/signals-react/package.json | 43 ++++ plugins/signals-react/src/api/SignalsApi.ts | 32 +++ .../signals-react/src/api/SignalsClient.ts | 133 +++++++++++ plugins/signals-react/src/api/index.ts | 17 ++ plugins/signals-react/src/hooks/index.ts | 16 ++ .../signals-react/src/hooks/useSignalsApi.ts | 37 +++ plugins/signals-react/src/index.ts | 18 ++ plugins/signals-react/src/setupTests.ts | 16 ++ yarn.lock | 115 ++++++++- 38 files changed, 1308 insertions(+), 7 deletions(-) create mode 100644 .changeset/real-eggs-sip.md create mode 100644 packages/backend/src/plugins/signals.ts create mode 100644 plugins/signals-backend/.eslintrc.js create mode 100644 plugins/signals-backend/README.md create mode 100644 plugins/signals-backend/api-report.md create mode 100644 plugins/signals-backend/catalog-info.yaml create mode 100644 plugins/signals-backend/package.json create mode 100644 plugins/signals-backend/src/index.ts create mode 100644 plugins/signals-backend/src/run.ts create mode 100644 plugins/signals-backend/src/service/router.test.ts create mode 100644 plugins/signals-backend/src/service/router.ts create mode 100644 plugins/signals-backend/src/service/standaloneServer.ts create mode 100644 plugins/signals-backend/src/setupTests.ts create mode 100644 plugins/signals-node/.eslintrc.js create mode 100644 plugins/signals-node/README.md create mode 100644 plugins/signals-node/api-report.md create mode 100644 plugins/signals-node/catalog-info.yaml create mode 100644 plugins/signals-node/package.json create mode 100644 plugins/signals-node/src/SignalsService.ts create mode 100644 plugins/signals-node/src/index.ts create mode 100644 plugins/signals-node/src/setupTests.ts create mode 100644 plugins/signals-node/src/types.ts create mode 100644 plugins/signals-react/.eslintrc.js create mode 100644 plugins/signals-react/README.md create mode 100644 plugins/signals-react/api-report.md create mode 100644 plugins/signals-react/catalog-info.yaml create mode 100644 plugins/signals-react/package.json create mode 100644 plugins/signals-react/src/api/SignalsApi.ts create mode 100644 plugins/signals-react/src/api/SignalsClient.ts create mode 100644 plugins/signals-react/src/api/index.ts create mode 100644 plugins/signals-react/src/hooks/index.ts create mode 100644 plugins/signals-react/src/hooks/useSignalsApi.ts create mode 100644 plugins/signals-react/src/index.ts create mode 100644 plugins/signals-react/src/setupTests.ts diff --git a/.changeset/real-eggs-sip.md b/.changeset/real-eggs-sip.md new file mode 100644 index 0000000000..ca05205083 --- /dev/null +++ b/.changeset/real-eggs-sip.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-signals-backend': patch +'@backstage/plugin-signals-react': patch +'@backstage/plugin-signals-node': patch +--- + +Add support to subscribe and publish messages through signals plugins diff --git a/packages/backend/package.json b/packages/backend/package.json index a70e5b5d3b..8899115c17 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -72,6 +72,8 @@ "@backstage/plugin-search-backend-module-techdocs": "workspace:^", "@backstage/plugin-search-backend-node": "workspace:^", "@backstage/plugin-search-common": "workspace:^", + "@backstage/plugin-signals-backend": "workspace:^", + "@backstage/plugin-signals-node": "workspace:^", "@backstage/plugin-tech-insights-backend": "workspace:^", "@backstage/plugin-tech-insights-backend-module-jsonfc": "workspace:^", "@backstage/plugin-tech-insights-node": "workspace:^", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 8df01b050e..cefc272aa7 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -26,19 +26,19 @@ import Router from 'express-promise-router'; import { CacheManager, createServiceBuilder, + DatabaseManager, getRootLogger, + HostDiscovery, loadBackendConfig, notFoundHandler, - DatabaseManager, - HostDiscovery, + ServerTokenManager, UrlReaders, useHotMemoize, - ServerTokenManager, } from '@backstage/backend-common'; import { TaskScheduler } from '@backstage/backend-tasks'; import { Config } from '@backstage/config'; import healthcheck from './plugins/healthcheck'; -import { metricsInit, metricsHandler } from './metrics'; +import { metricsHandler, metricsInit } from './metrics'; import auth from './plugins/auth'; import azureDevOps from './plugins/azure-devops'; import catalog from './plugins/catalog'; @@ -65,6 +65,7 @@ import lighthouse from './plugins/lighthouse'; import linguist from './plugins/linguist'; import devTools from './plugins/devtools'; import nomad from './plugins/nomad'; +import signals from './plugins/signals'; import { PluginEnvironment } from './types'; import { ServerPermissionClient } from '@backstage/plugin-permission-node'; import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; @@ -172,6 +173,7 @@ async function main() { const linguistEnv = useHotMemoize(module, () => createEnv('linguist')); const devToolsEnv = useHotMemoize(module, () => createEnv('devtools')); const nomadEnv = useHotMemoize(module, () => createEnv('nomad')); + const signalsEnv = useHotMemoize(module, () => createEnv('signals')); const apiRouter = Router(); apiRouter.use('/catalog', await catalog(catalogEnv)); @@ -198,6 +200,7 @@ async function main() { apiRouter.use('/linguist', await linguist(linguistEnv)); apiRouter.use('/devtools', await devTools(devToolsEnv)); apiRouter.use('/nomad', await nomad(nomadEnv)); + apiRouter.use('/signals', await signals(signalsEnv)); apiRouter.use(notFoundHandler()); await lighthouse(lighthouseEnv); diff --git a/packages/backend/src/plugins/signals.ts b/packages/backend/src/plugins/signals.ts new file mode 100644 index 0000000000..8e2d0b2d3f --- /dev/null +++ b/packages/backend/src/plugins/signals.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2023 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 { Router } from 'express'; +import { createRouter } from '@backstage/plugin-signals-backend'; +import { SignalsService } from '@backstage/plugin-signals-node'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + const service = SignalsService.create({ + logger: env.logger, + identity: env.identity, + eventBroker: env.eventBroker, + }); + + setInterval(() => { + console.log('publishing'); + service.publish('*', { hello: 'world' }); + }, 5000); + + return await createRouter({ + logger: env.logger, + service, + }); +} diff --git a/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx b/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx index 0ed43d2fee..810a823027 100644 --- a/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx +++ b/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx @@ -27,6 +27,7 @@ import { makeStyles, Paper, Theme, + Typography, } from '@material-ui/core'; import { Alert } from '@material-ui/lab'; import React from 'react'; @@ -38,6 +39,7 @@ import DeveloperBoardIcon from '@material-ui/icons/DeveloperBoard'; import { BackstageLogoIcon } from './BackstageLogoIcon'; import FileCopyIcon from '@material-ui/icons/FileCopy'; import { DevToolsInfo } from '@backstage/plugin-devtools-common'; +import { useSignalsApi } from '@backstage/plugin-signals-react'; const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -73,6 +75,12 @@ const copyToClipboard = ({ about }: { about: DevToolsInfo | undefined }) => { export const InfoContent = () => { const classes = useStyles(); const { about, loading, error } = useInfo(); + // Just testing for signals + const [messages, setMessages] = React.useState([]); + useSignalsApi(message => { + messages.push(JSON.stringify(message)); + setMessages([...messages]); + }); if (loading) { return ; @@ -81,6 +89,11 @@ export const InfoContent = () => { } return ( + + {messages.map((msg, i) => { + return {msg}; + })} + diff --git a/plugins/signals-backend/.eslintrc.js b/plugins/signals-backend/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/signals-backend/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/signals-backend/README.md b/plugins/signals-backend/README.md new file mode 100644 index 0000000000..d194b852f2 --- /dev/null +++ b/plugins/signals-backend/README.md @@ -0,0 +1,31 @@ +# signals + +Welcome to the signals backend plugin! + +Signals plugin allows backend plugins to publish messages to frontend plugins. + +## Getting started + +Add Signals router to your backend in `packages/backend/src/plugins/signals.ts`: + +```ts +import { Router } from 'express'; +import { createRouter } from '@backstage/plugin-signals-backend'; +import { SignalsService } from '@backstage/plugin-signals-node'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + const service = SignalsService.create({ + logger: env.logger, + identity: env.identity, + eventBroker: env.eventBroker, + }); + + return await createRouter({ + logger: env.logger, + service, + }); +} +``` diff --git a/plugins/signals-backend/api-report.md b/plugins/signals-backend/api-report.md new file mode 100644 index 0000000000..0ea56c707a --- /dev/null +++ b/plugins/signals-backend/api-report.md @@ -0,0 +1,22 @@ +## API Report File for "@backstage/plugin-signals-backend" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import express from 'express'; +import { Logger } from 'winston'; +import { SignalsService } from '@backstage/plugin-signals-node'; + +// @public (undocumented) +export function createRouter(options: RouterOptions): Promise; + +// @public (undocumented) +export interface RouterOptions { + // (undocumented) + logger: Logger; + // (undocumented) + service: SignalsService; +} + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/signals-backend/catalog-info.yaml b/plugins/signals-backend/catalog-info.yaml new file mode 100644 index 0000000000..0a025b77b5 --- /dev/null +++ b/plugins/signals-backend/catalog-info.yaml @@ -0,0 +1,9 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-signals-backend + title: '@backstage/plugin-signals-backend' +spec: + lifecycle: experimental + type: backstage-backend-plugin + owner: maintainers diff --git a/plugins/signals-backend/package.json b/plugins/signals-backend/package.json new file mode 100644 index 0000000000..ee303cdf3b --- /dev/null +++ b/plugins/signals-backend/package.json @@ -0,0 +1,50 @@ +{ + "name": "@backstage/plugin-signals-backend", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/backend-common": "workspace:^", + "@backstage/config": "workspace:^", + "@backstage/plugin-auth-node": "workspace:^", + "@backstage/plugin-events-node": "workspace:^", + "@backstage/plugin-signals-node": "workspace:^", + "@backstage/types": "workspace:^", + "@types/express": "*", + "express": "^4.17.1", + "express-promise-router": "^4.1.0", + "http-proxy-middleware": "^2.0.0", + "node-fetch": "^2.6.7", + "uuid": "^8.0.0", + "winston": "^3.2.1", + "ws": "^8.14.2", + "yn": "^4.0.0" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@types/supertest": "^2.0.8", + "msw": "^1.0.0", + "supertest": "^6.2.4" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/signals-backend/src/index.ts b/plugins/signals-backend/src/index.ts new file mode 100644 index 0000000000..d2e8d61bad --- /dev/null +++ b/plugins/signals-backend/src/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './service/router'; diff --git a/plugins/signals-backend/src/run.ts b/plugins/signals-backend/src/run.ts new file mode 100644 index 0000000000..d299ed23e9 --- /dev/null +++ b/plugins/signals-backend/src/run.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2023 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 { getRootLogger } from '@backstage/backend-common'; +import yn from 'yn'; +import { startStandaloneServer } from './service/standaloneServer'; + +const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007; +const enableCors = yn(process.env.PLUGIN_CORS, { default: false }); +const logger = getRootLogger(); + +startStandaloneServer({ port, enableCors, logger }).catch(err => { + logger.error(err); + process.exit(1); +}); + +process.on('SIGINT', () => { + logger.info('CTRL+C pressed; exiting.'); + process.exit(0); +}); diff --git a/plugins/signals-backend/src/service/router.test.ts b/plugins/signals-backend/src/service/router.test.ts new file mode 100644 index 0000000000..d7091827f9 --- /dev/null +++ b/plugins/signals-backend/src/service/router.test.ts @@ -0,0 +1,48 @@ +/* + * Copyright 2023 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 { getVoidLogger } from '@backstage/backend-common'; +import express from 'express'; +import request from 'supertest'; + +import { createRouter } from './router'; +import { SignalsService } from '@backstage/plugin-signals-node'; + +const signalsServiceMock: jest.Mocked = {} as any; + +describe('createRouter', () => { + let app: express.Express; + + beforeAll(async () => { + const router = await createRouter({ + logger: getVoidLogger(), + service: signalsServiceMock, + }); + app = express().use(router); + }); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + describe('GET /health', () => { + it('returns ok', async () => { + const response = await request(app).get('/health'); + + expect(response.status).toEqual(200); + expect(response.body).toEqual({ status: 'ok' }); + }); + }); +}); diff --git a/plugins/signals-backend/src/service/router.ts b/plugins/signals-backend/src/service/router.ts new file mode 100644 index 0000000000..0027acef30 --- /dev/null +++ b/plugins/signals-backend/src/service/router.ts @@ -0,0 +1,57 @@ +/* + * Copyright 2023 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 { errorHandler } from '@backstage/backend-common'; +import express from 'express'; +import Router from 'express-promise-router'; +import { Logger } from 'winston'; +import { SignalsService } from '@backstage/plugin-signals-node'; + +/** @public */ +export interface RouterOptions { + logger: Logger; + service: SignalsService; +} + +/** @public */ +export async function createRouter( + options: RouterOptions, +): Promise { + const { logger, service } = options; + + const router = Router(); + router.use(express.json()); + + router.get('/health', (_, response) => { + logger.info('PONG!'); + response.json({ status: 'ok' }); + }); + + router.get('/', async (req, _, next) => { + if ( + !req.headers || + req.headers.upgrade === undefined || + req.headers.upgrade.toLowerCase() !== 'websocket' + ) { + next(); + return; + } + + await service.handleUpgrade(req); + }); + + router.use(errorHandler()); + return router; +} diff --git a/plugins/signals-backend/src/service/standaloneServer.ts b/plugins/signals-backend/src/service/standaloneServer.ts new file mode 100644 index 0000000000..c13d718734 --- /dev/null +++ b/plugins/signals-backend/src/service/standaloneServer.ts @@ -0,0 +1,69 @@ +/* + * Copyright 2023 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 { + createServiceBuilder, + HostDiscovery, + loadBackendConfig, +} from '@backstage/backend-common'; +import { Server } from 'http'; +import { Logger } from 'winston'; +import { createRouter } from './router'; +import { SignalsService } from '@backstage/plugin-signals-node'; +import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; + +export interface ServerOptions { + port: number; + enableCors: boolean; + logger: Logger; +} + +export async function startStandaloneServer( + options: ServerOptions, +): Promise { + const logger = options.logger.child({ service: 'signals-backend' }); + logger.debug('Starting application server...'); + const config = await loadBackendConfig({ logger, argv: process.argv }); + const discovery = HostDiscovery.fromConfig(config); + + const identity = DefaultIdentityClient.create({ + discovery, + issuer: await discovery.getExternalBaseUrl('auth'), + }); + + const signals = SignalsService.create({ + logger: logger, + identity, + }); + + const router = await createRouter({ + logger, + service: signals, + }); + + let service = createServiceBuilder(module) + .setPort(options.port) + .addRouter('/signals', router); + if (options.enableCors) { + service = service.enableCors({ origin: 'http://localhost:3000' }); + } + + return await service.start().catch(err => { + logger.error(err); + process.exit(1); + }); +} + +module.hot?.accept(); diff --git a/plugins/signals-backend/src/setupTests.ts b/plugins/signals-backend/src/setupTests.ts new file mode 100644 index 0000000000..4b9026cde5 --- /dev/null +++ b/plugins/signals-backend/src/setupTests.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export {}; diff --git a/plugins/signals-node/.eslintrc.js b/plugins/signals-node/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/signals-node/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/signals-node/README.md b/plugins/signals-node/README.md new file mode 100644 index 0000000000..55d766f9e0 --- /dev/null +++ b/plugins/signals-node/README.md @@ -0,0 +1,5 @@ +# @backstage/plugin-signals-node + +Welcome to the Node.js library package for the signals plugin! + +_This plugin was created through the Backstage CLI_ diff --git a/plugins/signals-node/api-report.md b/plugins/signals-node/api-report.md new file mode 100644 index 0000000000..e8c9900908 --- /dev/null +++ b/plugins/signals-node/api-report.md @@ -0,0 +1,47 @@ +## API Report File for "@backstage/plugin-signals-node" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { EventBroker } from '@backstage/plugin-events-node'; +import { EventParams } from '@backstage/plugin-events-node'; +import { EventSubscriber } from '@backstage/plugin-events-node'; +import { IdentityApi } from '@backstage/plugin-auth-node'; +import { JsonObject } from '@backstage/types'; +import { Logger } from 'winston'; +import { Request as Request_2 } from 'express'; + +// @public (undocumented) +export type ServiceOptions = { + eventBroker?: EventBroker; + logger: Logger; + identity: IdentityApi; +}; + +// @public (undocumented) +export type SignalsEventBrokerPayload = { + recipients?: string[]; + topic?: string; + message?: JsonObject; +}; + +// @public (undocumented) +export class SignalsService implements EventSubscriber { + // (undocumented) + static create(options: ServiceOptions): SignalsService; + // (undocumented) + handleUpgrade: (req: Request_2) => Promise; + // (undocumented) + onEvent(params: EventParams): Promise; + // (undocumented) + publish( + to: string | string[], + message: JsonObject, + topic?: string, + ): Promise; + // (undocumented) + supportsEventTopics(): string[]; +} + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/signals-node/catalog-info.yaml b/plugins/signals-node/catalog-info.yaml new file mode 100644 index 0000000000..5e3af0acde --- /dev/null +++ b/plugins/signals-node/catalog-info.yaml @@ -0,0 +1,10 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-signals-node + title: '@backstage/plugin-signals-node' + description: Node.js library for the signals plugin +spec: + lifecycle: experimental + type: backstage-node-library + owner: maintainers diff --git a/plugins/signals-node/package.json b/plugins/signals-node/package.json new file mode 100644 index 0000000000..66e4528678 --- /dev/null +++ b/plugins/signals-node/package.json @@ -0,0 +1,42 @@ +{ + "name": "@backstage/plugin-signals-node", + "description": "Node.js library for the signals plugin", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "node-library" + }, + "scripts": { + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@types/express": "^4.17.21" + }, + "files": [ + "dist" + ], + "dependencies": { + "@backstage/backend-common": "workspace:^", + "@backstage/config": "workspace:^", + "@backstage/plugin-auth-node": "workspace:^", + "@backstage/plugin-events-node": "workspace:^", + "@backstage/types": "workspace:^", + "express": "^4.17.1", + "uuid": "^8.0.0", + "winston": "^3.2.1", + "ws": "^8.14.2" + } +} diff --git a/plugins/signals-node/src/SignalsService.ts b/plugins/signals-node/src/SignalsService.ts new file mode 100644 index 0000000000..6404386129 --- /dev/null +++ b/plugins/signals-node/src/SignalsService.ts @@ -0,0 +1,226 @@ +/* + * Copyright 2023 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 { + EventBroker, + EventParams, + EventSubscriber, +} from '@backstage/plugin-events-node'; +import { Logger } from 'winston'; +import { ServiceOptions, SignalConnection } from './types'; +import { RawData, WebSocket, WebSocketServer } from 'ws'; +import { IncomingMessage } from 'http'; +import { v4 as uuid } from 'uuid'; +import { Request } from 'express'; +import { JsonObject } from '@backstage/types'; +import { + BackstageIdentityResponse, + IdentityApi, +} from '@backstage/plugin-auth-node'; + +/** @public */ +export type SignalsEventBrokerPayload = { + recipients?: string[]; + topic?: string; + message?: JsonObject; +}; + +/** @public */ +export class SignalsService implements EventSubscriber { + private readonly serverId: string; + private connections: Map = new Map< + string, + SignalConnection + >(); + private eventBroker?: EventBroker; + private logger: Logger; + private identity: IdentityApi; + private server: WebSocketServer; + + static create(options: ServiceOptions) { + return new SignalsService(options); + } + + private constructor(options: ServiceOptions) { + ({ + eventBroker: this.eventBroker, + logger: this.logger, + identity: this.identity, + } = options); + + this.serverId = uuid(); + this.server = new WebSocketServer({ + noServer: true, + }); + + this.server.on('close', () => { + this.logger.info('Closing signals server'); + this.connections.forEach(conn => { + conn.ws.close(); + }); + this.connections = new Map(); + }); + + this.eventBroker?.subscribe(this); + } + + handleUpgrade = async (req: Request) => { + const identity = await this.identity.getIdentity({ + request: req, + }); + + this.server.handleUpgrade( + req, + req.socket, + Buffer.from(''), + (ws: WebSocket, __: IncomingMessage) => { + this.addConnection(ws, identity); + }, + ); + }; + + private addConnection(ws: WebSocket, identity?: BackstageIdentityResponse) { + const id = uuid(); + + const conn = { + id, + user: identity?.identity.userEntityRef ?? 'user:default/guest', + ws, + ownershipEntityRefs: identity?.identity.ownershipEntityRefs ?? [], + subscriptions: new Set(), + }; + + this.connections.set(id, conn); + + ws.on('error', (err: Error) => { + this.logger.info( + `Error occurred with connection ${id}: ${err}, closing connection`, + ); + ws.close(); + this.connections.delete(id); + }); + + ws.on('close', (code: number, reason: Buffer) => { + this.logger.info( + `Connection ${id} closed with code ${code}, reason: ${reason}`, + ); + this.connections.delete(id); + }); + + ws.on('ping', () => { + this.logger.debug(`Ping from connection ${id}`); + ws.pong(); + }); + + ws.on('message', (data: RawData, isBinary: boolean) => { + this.logger.debug(`Received message from connection ${id}: ${data}`); + if (isBinary) { + return; + } + + try { + const json = JSON.parse(data.toString()) as JsonObject; + this.handleMessage(conn, json); + } catch (err: any) { + this.logger.error( + `Invalid message received from connection ${id}: ${err}`, + ); + } + }); + } + + private handleMessage(connection: SignalConnection, message: JsonObject) { + if (message.action === 'subscribe' && message.topic) { + this.logger.info( + `Connection ${connection.id} subscribed to ${message.topic}`, + ); + connection.subscriptions.add(message.topic as string); + } + + if (message.action === 'unsubscribe' && message.topic) { + this.logger.info( + `Connection ${connection.id} unsubscribed from ${message.topic}`, + ); + connection.subscriptions.delete(message.topic as string); + } + } + + async publish(to: string | string[], message: JsonObject, topic?: string) { + await this.publishInternal( + Array.isArray(to) ? to : [to], + message, + false, + topic, + ); + } + + private async publishInternal( + recipients: string[], + message: JsonObject, + brokedEvent: boolean, + topic?: string, + ) { + this.connections.forEach(conn => { + if (topic && !conn.subscriptions.has(topic)) { + return; + } + // Sending to all users can be done with '*' + if ( + !recipients.includes('*') && + !conn.ownershipEntityRefs.some(ref => recipients.includes(ref)) + ) { + return; + } + conn.ws.send(JSON.stringify({ topic, message })); + }); + + // If this event has not been broadcasted to all servers, then use + // EventBroker to do that + if (this.eventBroker && !brokedEvent) { + await this.eventBroker.publish({ + topic: 'signals', + eventPayload: { + recipients, + message, + topic, + }, + metadata: { server: this.serverId }, + }); + } + } + + async onEvent(params: EventParams): Promise { + const { eventPayload, metadata } = params; + // Discard message from same server to prevent duplicate messages + if (!metadata?.server || metadata.server === this.serverId) { + return; + } + + if (!eventPayload?.recipients || !eventPayload.message) { + return; + } + + await this.publishInternal( + eventPayload.recipients, + eventPayload.message, + true, + eventPayload.topic, + ); + } + + supportsEventTopics(): string[] { + return ['signals']; + } +} diff --git a/plugins/signals-node/src/index.ts b/plugins/signals-node/src/index.ts new file mode 100644 index 0000000000..5427711cbe --- /dev/null +++ b/plugins/signals-node/src/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './SignalsService'; +export * from './types'; diff --git a/plugins/signals-node/src/setupTests.ts b/plugins/signals-node/src/setupTests.ts new file mode 100644 index 0000000000..4b9026cde5 --- /dev/null +++ b/plugins/signals-node/src/setupTests.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export {}; diff --git a/plugins/signals-node/src/types.ts b/plugins/signals-node/src/types.ts new file mode 100644 index 0000000000..c53bfdb20e --- /dev/null +++ b/plugins/signals-node/src/types.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2023 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 { IdentityApi } from '@backstage/plugin-auth-node'; +import { EventBroker } from '@backstage/plugin-events-node'; +import { Logger } from 'winston'; +import { WebSocket } from 'ws'; + +/** + * @public + */ +export type ServiceOptions = { + eventBroker?: EventBroker; + logger: Logger; + identity: IdentityApi; +}; + +/** + * @internal + */ +export type SignalConnection = { + id: string; + user: string; + ws: WebSocket; + ownershipEntityRefs: string[]; + subscriptions: Set; +}; diff --git a/plugins/signals-react/.eslintrc.js b/plugins/signals-react/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/signals-react/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/signals-react/README.md b/plugins/signals-react/README.md new file mode 100644 index 0000000000..4b6b4e00bc --- /dev/null +++ b/plugins/signals-react/README.md @@ -0,0 +1,5 @@ +# @backstage/plugin-signals-react + +Welcome to the web library package for the signals plugin! + +_This plugin was created through the Backstage CLI_ diff --git a/plugins/signals-react/api-report.md b/plugins/signals-react/api-report.md new file mode 100644 index 0000000000..14d78d4517 --- /dev/null +++ b/plugins/signals-react/api-report.md @@ -0,0 +1,45 @@ +## API Report File for "@backstage/plugin-signals-react" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { ApiRef } from '@backstage/core-plugin-api'; +import { DiscoveryApi } from '@backstage/core-plugin-api'; +import { JSONObject } from '@apollo/explorer/src/helpers/types'; +import { JsonObject } from '@backstage/types'; + +// @public (undocumented) +export type SignalsApi = { + subscribe( + onMessage: (message: JsonObject, topic?: string) => void, + topic?: string, + ): void; + unsubscribe(topic?: string): void; +}; + +// @public (undocumented) +export const signalsApiRef: ApiRef; + +// @public (undocumented) +export class SignalsClient implements SignalsApi { + // (undocumented) + static create(options: { discoveryApi: DiscoveryApi }): SignalsClient; + // (undocumented) + static instance: SignalsClient | null; + // (undocumented) + subscribe( + onMessage: (message: JsonObject, topic?: string) => void, + topic?: string, + ): void; + // (undocumented) + unsubscribe(topic?: string): void; +} + +// @public (undocumented) +export const useSignalsApi: ( + onMessage: (message: JSONObject) => void, + topic?: string, +) => void; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/signals-react/catalog-info.yaml b/plugins/signals-react/catalog-info.yaml new file mode 100644 index 0000000000..ac8093ed0c --- /dev/null +++ b/plugins/signals-react/catalog-info.yaml @@ -0,0 +1,10 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-signals-react + title: '@backstage/plugin-signals-react' + description: Web library for the signals plugin +spec: + lifecycle: experimental + type: backstage-web-library + owner: maintainers diff --git a/plugins/signals-react/package.json b/plugins/signals-react/package.json new file mode 100644 index 0000000000..148bc27cb3 --- /dev/null +++ b/plugins/signals-react/package.json @@ -0,0 +1,43 @@ +{ + "name": "@backstage/plugin-signals-react", + "description": "Web library for the signals plugin", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "web-library" + }, + "sideEffects": false, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/core-plugin-api": "workspace:^", + "@backstage/types": "workspace:^", + "@material-ui/core": "^4.9.13" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@backstage/test-utils": "workspace:^", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^12.1.3" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/signals-react/src/api/SignalsApi.ts b/plugins/signals-react/src/api/SignalsApi.ts new file mode 100644 index 0000000000..685cd560aa --- /dev/null +++ b/plugins/signals-react/src/api/SignalsApi.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createApiRef } from '@backstage/core-plugin-api'; +import { JsonObject } from '@backstage/types'; + +/** @public */ +export const signalsApiRef = createApiRef({ + id: 'plugin.signals.service', +}); + +/** @public */ +export type SignalsApi = { + subscribe( + onMessage: (message: JsonObject, topic?: string) => void, + topic?: string, + ): void; + + unsubscribe(topic?: string): void; +}; diff --git a/plugins/signals-react/src/api/SignalsClient.ts b/plugins/signals-react/src/api/SignalsClient.ts new file mode 100644 index 0000000000..71984a5c23 --- /dev/null +++ b/plugins/signals-react/src/api/SignalsClient.ts @@ -0,0 +1,133 @@ +/* + * Copyright 2023 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 { SignalsApi } from './SignalsApi'; +import { JsonObject } from '@backstage/types'; +import { DiscoveryApi } from '@backstage/core-plugin-api'; + +/** @public */ +export class SignalsClient implements SignalsApi { + static instance: SignalsClient | null = null; + private ws: WebSocket | null = null; + private discoveryApi: DiscoveryApi; + private cbs: Map void> = + new Map(); + private queue: JsonObject[] = []; + private reconnectTimeout: any; + + static create(options: { discoveryApi: DiscoveryApi }) { + if (!SignalsClient.instance) { + SignalsClient.instance = new SignalsClient(options); + } + return SignalsClient.instance; + } + + private constructor(options: { discoveryApi: DiscoveryApi }) { + this.discoveryApi = options.discoveryApi; + } + + subscribe( + onMessage: (message: JsonObject, topic?: string) => void, + topic?: string, + ): void { + const subscriptionTopic = topic ?? '*'; + // Do not allow to subscribe to same topic multiple times + if (this.cbs.has(subscriptionTopic)) { + return; + } + + this.cbs.set(subscriptionTopic, onMessage); + this.connect().then(() => { + this.send({ action: 'subscribe', topic }); + }); + } + + unsubscribe(topic?: string): void { + const subscriptionTopic = topic ?? '*'; + this.cbs.delete(subscriptionTopic); + this.send({ action: 'unsubscribe', topic }); + } + + private send(data?: JsonObject): void { + if (!this.ws || this.ws.readyState !== WebSocket.OPEN) { + if (data) { + this.queue.push(data); + } + return; + } + + // First send queue + for (const msg of this.queue) { + this.ws!.send(JSON.stringify(msg)); + } + this.queue = []; + if (data) { + this.ws!.send(JSON.stringify(data)); + } + } + + private async connect() { + if (this.ws) { + return; + } + + const apiUrl = `${await this.discoveryApi.getBaseUrl('signals')}`; + const url = new URL(apiUrl); + url.protocol = url.protocol === 'http:' ? 'ws' : 'wss'; + this.ws = new WebSocket(url.toString()); + + this.ws.onmessage = (data: MessageEvent) => { + try { + const json = JSON.parse(data.data) as JsonObject; + let cb = this.cbs.get('*'); + if (json.topic) { + cb = this.cbs.get(json.topic as string); + } + if (cb) { + cb(json.message as JsonObject, json.topic as string); + } + } catch (e) { + // NOOP + } + }; + + this.ws.onerror = () => { + this.reconnect(); + }; + + this.ws.onclose = () => { + this.reconnect(); + }; + + while (this.ws.readyState !== WebSocket.OPEN) { + await new Promise(r => setTimeout(r, 10)); + } + this.send(); + } + + private reconnect() { + if (this.reconnectTimeout) { + clearTimeout(this.reconnectTimeout); + } + + this.reconnectTimeout = setTimeout(() => { + if (this.ws) { + this.ws.close(); + } + this.ws = null; + this.connect(); + }, 5000); + } +} diff --git a/plugins/signals-react/src/api/index.ts b/plugins/signals-react/src/api/index.ts new file mode 100644 index 0000000000..b8dea2af34 --- /dev/null +++ b/plugins/signals-react/src/api/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './SignalsApi'; +export * from './SignalsClient'; diff --git a/plugins/signals-react/src/hooks/index.ts b/plugins/signals-react/src/hooks/index.ts new file mode 100644 index 0000000000..0d5967f9eb --- /dev/null +++ b/plugins/signals-react/src/hooks/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './useSignalsApi'; diff --git a/plugins/signals-react/src/hooks/useSignalsApi.ts b/plugins/signals-react/src/hooks/useSignalsApi.ts new file mode 100644 index 0000000000..3bfbba5d71 --- /dev/null +++ b/plugins/signals-react/src/hooks/useSignalsApi.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2023 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 { SignalsClient } from '../api'; +import { discoveryApiRef, useApi } from '@backstage/core-plugin-api'; +import { JSONObject } from '@apollo/explorer/src/helpers/types'; +import { useEffect } from 'react'; + +/** @public */ +export const useSignalsApi = ( + onMessage: (message: JSONObject) => void, + topic?: string, +) => { + const discovery = useApi(discoveryApiRef); + const signals = SignalsClient.create({ discoveryApi: discovery }); + useEffect(() => { + signals.subscribe(onMessage, topic); + }, [signals, onMessage, topic]); + + useEffect(() => { + return () => { + signals.unsubscribe(topic); + }; + }, [signals, topic]); +}; diff --git a/plugins/signals-react/src/index.ts b/plugins/signals-react/src/index.ts new file mode 100644 index 0000000000..0f44901352 --- /dev/null +++ b/plugins/signals-react/src/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './api'; +export * from './hooks'; diff --git a/plugins/signals-react/src/setupTests.ts b/plugins/signals-react/src/setupTests.ts new file mode 100644 index 0000000000..865308e634 --- /dev/null +++ b/plugins/signals-react/src/setupTests.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 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 '@testing-library/jest-dom'; diff --git a/yarn.lock b/yarn.lock index 2d59eecaac..cdd232b103 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,7 +12,7 @@ __metadata: languageName: node linkType: hard -"@adobe/css-tools@npm:^4.3.2": +"@adobe/css-tools@npm:^4.0.1, @adobe/css-tools@npm:^4.3.2": version: 4.3.2 resolution: "@adobe/css-tools@npm:4.3.2" checksum: 9667d61d55dc3b0a315c530ae84e016ce5267c4dd8ac00abb40108dc98e07b98e3090ce8b87acd51a41a68d9e84dcccb08cdf21c902572a9cf9dcaf830da4ae3 @@ -8833,6 +8833,66 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-signals-backend@workspace:^, @backstage/plugin-signals-backend@workspace:plugins/signals-backend": + version: 0.0.0-use.local + resolution: "@backstage/plugin-signals-backend@workspace:plugins/signals-backend" + dependencies: + "@backstage/backend-common": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" + "@backstage/plugin-auth-node": "workspace:^" + "@backstage/plugin-events-node": "workspace:^" + "@backstage/plugin-signals-node": "workspace:^" + "@backstage/types": "workspace:^" + "@types/express": "*" + "@types/supertest": ^2.0.8 + express: ^4.17.1 + express-promise-router: ^4.1.0 + http-proxy-middleware: ^2.0.0 + msw: ^1.0.0 + node-fetch: ^2.6.7 + supertest: ^6.2.4 + uuid: ^8.0.0 + winston: ^3.2.1 + ws: ^8.14.2 + yn: ^4.0.0 + languageName: unknown + linkType: soft + +"@backstage/plugin-signals-node@workspace:^, @backstage/plugin-signals-node@workspace:plugins/signals-node": + version: 0.0.0-use.local + resolution: "@backstage/plugin-signals-node@workspace:plugins/signals-node" + dependencies: + "@backstage/backend-common": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" + "@backstage/plugin-auth-node": "workspace:^" + "@backstage/plugin-events-node": "workspace:^" + "@backstage/types": "workspace:^" + "@types/express": ^4.17.21 + express: ^4.17.1 + uuid: ^8.0.0 + winston: ^3.2.1 + ws: ^8.14.2 + languageName: unknown + linkType: soft + +"@backstage/plugin-signals-react@workspace:plugins/signals-react": + version: 0.0.0-use.local + resolution: "@backstage/plugin-signals-react@workspace:plugins/signals-react" + dependencies: + "@backstage/cli": "workspace:^" + "@backstage/core-plugin-api": "workspace:^" + "@backstage/test-utils": "workspace:^" + "@backstage/types": "workspace:^" + "@material-ui/core": ^4.9.13 + "@testing-library/jest-dom": ^5.10.1 + "@testing-library/react": ^12.1.3 + peerDependencies: + react: ^16.13.1 || ^17.0.0 + languageName: unknown + linkType: soft + "@backstage/plugin-sonarqube-backend@workspace:^, @backstage/plugin-sonarqube-backend@workspace:plugins/sonarqube-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-sonarqube-backend@workspace:plugins/sonarqube-backend" @@ -17125,6 +17185,22 @@ __metadata: languageName: unknown linkType: soft +"@testing-library/dom@npm:^8.0.0": + version: 8.20.1 + resolution: "@testing-library/dom@npm:8.20.1" + dependencies: + "@babel/code-frame": ^7.10.4 + "@babel/runtime": ^7.12.5 + "@types/aria-query": ^5.0.1 + aria-query: 5.1.3 + chalk: ^4.1.0 + dom-accessibility-api: ^0.5.9 + lz-string: ^1.5.0 + pretty-format: ^27.0.2 + checksum: 06fc8dc67849aadb726cbbad0e7546afdf8923bd39acb64c576d706249bd7d0d05f08e08a31913fb621162e3b9c2bd0dce15964437f030f9fa4476326fdd3007 + languageName: node + linkType: hard + "@testing-library/dom@npm:^9.0.0": version: 9.3.3 resolution: "@testing-library/dom@npm:9.3.3" @@ -17141,6 +17217,23 @@ __metadata: languageName: node linkType: hard +"@testing-library/jest-dom@npm:^5.10.1": + version: 5.17.0 + resolution: "@testing-library/jest-dom@npm:5.17.0" + dependencies: + "@adobe/css-tools": ^4.0.1 + "@babel/runtime": ^7.9.2 + "@types/testing-library__jest-dom": ^5.9.1 + aria-query: ^5.0.0 + chalk: ^3.0.0 + css.escape: ^1.5.1 + dom-accessibility-api: ^0.5.6 + lodash: ^4.17.15 + redent: ^3.0.0 + checksum: 9f28dbca8b50d7c306aae40c3aa8e06f0e115f740360004bd87d57f95acf7ab4b4f4122a7399a76dbf2bdaaafb15c99cc137fdcb0ae457a92e2de0f3fbf9b03b + languageName: node + linkType: hard + "@testing-library/jest-dom@npm:^6.0.0": version: 6.1.6 resolution: "@testing-library/jest-dom@npm:6.1.6" @@ -17193,6 +17286,20 @@ __metadata: languageName: node linkType: hard +"@testing-library/react@npm:^12.1.3": + version: 12.1.5 + resolution: "@testing-library/react@npm:12.1.5" + dependencies: + "@babel/runtime": ^7.12.5 + "@testing-library/dom": ^8.0.0 + "@types/react-dom": <18.0.0 + peerDependencies: + react: <18.0.0 + react-dom: <18.0.0 + checksum: 4abd0490405e709a7df584a0db604e508a4612398bb1326e8fa32dd9393b15badc826dcf6d2f7525437886d507871f719f127b9860ed69ddd204d1fa834f576a + languageName: node + linkType: hard + "@testing-library/react@npm:^14.0.0": version: 14.1.2 resolution: "@testing-library/react@npm:14.1.2" @@ -17884,7 +17991,7 @@ __metadata: languageName: node linkType: hard -"@types/express@npm:*, @types/express@npm:^4.17.13, @types/express@npm:^4.17.17, @types/express@npm:^4.17.6": +"@types/express@npm:*, @types/express@npm:^4.17.13, @types/express@npm:^4.17.17, @types/express@npm:^4.17.21, @types/express@npm:^4.17.6": version: 4.17.21 resolution: "@types/express@npm:4.17.21" dependencies: @@ -26588,6 +26695,8 @@ __metadata: "@backstage/plugin-search-backend-module-techdocs": "workspace:^" "@backstage/plugin-search-backend-node": "workspace:^" "@backstage/plugin-search-common": "workspace:^" + "@backstage/plugin-signals-backend": "workspace:^" + "@backstage/plugin-signals-node": "workspace:^" "@backstage/plugin-tech-insights-backend": "workspace:^" "@backstage/plugin-tech-insights-backend-module-jsonfc": "workspace:^" "@backstage/plugin-tech-insights-node": "workspace:^" @@ -44545,7 +44654,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:*, ws@npm:8.14.2, ws@npm:^8.11.0, ws@npm:^8.12.0, ws@npm:^8.13.0, ws@npm:^8.8.0": +"ws@npm:*, ws@npm:8.14.2, ws@npm:^8.11.0, ws@npm:^8.12.0, ws@npm:^8.13.0, ws@npm:^8.14.2, ws@npm:^8.8.0": version: 8.14.2 resolution: "ws@npm:8.14.2" peerDependencies: From 01d02b0d3b08f28fe69bfbe6b77a46cc234e24a3 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Mon, 4 Dec 2023 14:21:40 +0200 Subject: [PATCH 021/283] chore: make topic mandatory for signals Signed-off-by: Heikki Hellgren --- packages/backend/src/plugins/signals.ts | 2 +- .../Content/InfoContent/InfoContent.tsx | 2 +- plugins/signals-node/api-report.md | 4 +-- plugins/signals-node/src/SignalsService.ts | 27 +++++++++++---- plugins/signals-react/api-report.md | 13 +++---- plugins/signals-react/src/api/SignalsApi.ts | 4 +-- .../signals-react/src/api/SignalsClient.ts | 34 +++++++++---------- .../signals-react/src/hooks/useSignalsApi.ts | 2 +- 8 files changed, 48 insertions(+), 40 deletions(-) diff --git a/packages/backend/src/plugins/signals.ts b/packages/backend/src/plugins/signals.ts index 8e2d0b2d3f..dae2731c52 100644 --- a/packages/backend/src/plugins/signals.ts +++ b/packages/backend/src/plugins/signals.ts @@ -29,7 +29,7 @@ export default async function createPlugin( setInterval(() => { console.log('publishing'); - service.publish('*', { hello: 'world' }); + service.publish('*', 'devtools:info', { now: new Date().toISOString() }); }, 5000); return await createRouter({ diff --git a/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx b/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx index 810a823027..adca500fad 100644 --- a/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx +++ b/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx @@ -77,7 +77,7 @@ export const InfoContent = () => { const { about, loading, error } = useInfo(); // Just testing for signals const [messages, setMessages] = React.useState([]); - useSignalsApi(message => { + useSignalsApi('devtools:info', message => { messages.push(JSON.stringify(message)); setMessages([...messages]); }); diff --git a/plugins/signals-node/api-report.md b/plugins/signals-node/api-report.md index e8c9900908..15a6f67d87 100644 --- a/plugins/signals-node/api-report.md +++ b/plugins/signals-node/api-report.md @@ -29,15 +29,13 @@ export type SignalsEventBrokerPayload = { export class SignalsService implements EventSubscriber { // (undocumented) static create(options: ServiceOptions): SignalsService; - // (undocumented) handleUpgrade: (req: Request_2) => Promise; // (undocumented) onEvent(params: EventParams): Promise; - // (undocumented) publish( to: string | string[], + topic: string, message: JsonObject, - topic?: string, ): Promise; // (undocumented) supportsEventTopics(): string[]; diff --git a/plugins/signals-node/src/SignalsService.ts b/plugins/signals-node/src/SignalsService.ts index 6404386129..15a63e15d7 100644 --- a/plugins/signals-node/src/SignalsService.ts +++ b/plugins/signals-node/src/SignalsService.ts @@ -76,6 +76,11 @@ export class SignalsService implements EventSubscriber { this.eventBroker?.subscribe(this); } + /** + * Handles request upgradce to websocket and adds the connection to internal + * list for publish/subscribe functionality + * @param req - Request + */ handleUpgrade = async (req: Request) => { const identity = await this.identity.getIdentity({ request: req, @@ -157,23 +162,29 @@ export class SignalsService implements EventSubscriber { } } - async publish(to: string | string[], message: JsonObject, topic?: string) { + /** + * Publishes a message to user refs to specific topic + * @param to - string or array of user ref strings to publish message to + * @param topic - message topic + * @param message - message to publish + */ + async publish(to: string | string[], topic: string, message: JsonObject) { await this.publishInternal( Array.isArray(to) ? to : [to], + topic, message, false, - topic, ); } private async publishInternal( recipients: string[], + topic: string, message: JsonObject, brokedEvent: boolean, - topic?: string, ) { this.connections.forEach(conn => { - if (topic && !conn.subscriptions.has(topic)) { + if (!conn.subscriptions.has(topic)) { return; } // Sending to all users can be done with '*' @@ -208,15 +219,19 @@ export class SignalsService implements EventSubscriber { return; } - if (!eventPayload?.recipients || !eventPayload.message) { + if ( + !eventPayload?.recipients || + !eventPayload.topic || + !eventPayload.message + ) { return; } await this.publishInternal( eventPayload.recipients, + eventPayload.topic, eventPayload.message, true, - eventPayload.topic, ); } diff --git a/plugins/signals-react/api-report.md b/plugins/signals-react/api-report.md index 14d78d4517..22e9306c14 100644 --- a/plugins/signals-react/api-report.md +++ b/plugins/signals-react/api-report.md @@ -12,9 +12,9 @@ import { JsonObject } from '@backstage/types'; export type SignalsApi = { subscribe( onMessage: (message: JsonObject, topic?: string) => void, - topic?: string, + topic: string, ): void; - unsubscribe(topic?: string): void; + unsubscribe(topic: string): void; }; // @public (undocumented) @@ -27,18 +27,15 @@ export class SignalsClient implements SignalsApi { // (undocumented) static instance: SignalsClient | null; // (undocumented) - subscribe( - onMessage: (message: JsonObject, topic?: string) => void, - topic?: string, - ): void; + subscribe(onMessage: (message: JsonObject) => void, topic: string): void; // (undocumented) - unsubscribe(topic?: string): void; + unsubscribe(topic: string): void; } // @public (undocumented) export const useSignalsApi: ( + topic: string, onMessage: (message: JSONObject) => void, - topic?: string, ) => void; // (No @packageDocumentation comment for this package) diff --git a/plugins/signals-react/src/api/SignalsApi.ts b/plugins/signals-react/src/api/SignalsApi.ts index 685cd560aa..28f9da39dc 100644 --- a/plugins/signals-react/src/api/SignalsApi.ts +++ b/plugins/signals-react/src/api/SignalsApi.ts @@ -25,8 +25,8 @@ export const signalsApiRef = createApiRef({ export type SignalsApi = { subscribe( onMessage: (message: JsonObject, topic?: string) => void, - topic?: string, + topic: string, ): void; - unsubscribe(topic?: string): void; + unsubscribe(topic: string): void; }; diff --git a/plugins/signals-react/src/api/SignalsClient.ts b/plugins/signals-react/src/api/SignalsClient.ts index 71984a5c23..cdfa7e5606 100644 --- a/plugins/signals-react/src/api/SignalsClient.ts +++ b/plugins/signals-react/src/api/SignalsClient.ts @@ -22,8 +22,7 @@ export class SignalsClient implements SignalsApi { static instance: SignalsClient | null = null; private ws: WebSocket | null = null; private discoveryApi: DiscoveryApi; - private cbs: Map void> = - new Map(); + private cbs: Map void> = new Map(); private queue: JsonObject[] = []; private reconnectTimeout: any; @@ -38,25 +37,20 @@ export class SignalsClient implements SignalsApi { this.discoveryApi = options.discoveryApi; } - subscribe( - onMessage: (message: JsonObject, topic?: string) => void, - topic?: string, - ): void { - const subscriptionTopic = topic ?? '*'; + subscribe(onMessage: (message: JsonObject) => void, topic: string): void { // Do not allow to subscribe to same topic multiple times - if (this.cbs.has(subscriptionTopic)) { + if (this.cbs.has(topic)) { return; } - this.cbs.set(subscriptionTopic, onMessage); + this.cbs.set(topic, onMessage); this.connect().then(() => { this.send({ action: 'subscribe', topic }); }); } - unsubscribe(topic?: string): void { - const subscriptionTopic = topic ?? '*'; - this.cbs.delete(subscriptionTopic); + unsubscribe(topic: string): void { + this.cbs.delete(topic); this.send({ action: 'unsubscribe', topic }); } @@ -91,12 +85,11 @@ export class SignalsClient implements SignalsApi { this.ws.onmessage = (data: MessageEvent) => { try { const json = JSON.parse(data.data) as JsonObject; - let cb = this.cbs.get('*'); if (json.topic) { - cb = this.cbs.get(json.topic as string); - } - if (cb) { - cb(json.message as JsonObject, json.topic as string); + const cb = this.cbs.get(json.topic as string); + if (cb) { + cb(json.message as JsonObject); + } } } catch (e) { // NOOP @@ -127,7 +120,12 @@ export class SignalsClient implements SignalsApi { this.ws.close(); } this.ws = null; - this.connect(); + this.connect().then(() => { + // Resubscribe to existing topics in case we lost connection + for (const topic of this.cbs.keys()) { + this.send({ action: 'subscribe', topic }); + } + }); }, 5000); } } diff --git a/plugins/signals-react/src/hooks/useSignalsApi.ts b/plugins/signals-react/src/hooks/useSignalsApi.ts index 3bfbba5d71..88112cebc7 100644 --- a/plugins/signals-react/src/hooks/useSignalsApi.ts +++ b/plugins/signals-react/src/hooks/useSignalsApi.ts @@ -20,8 +20,8 @@ import { useEffect } from 'react'; /** @public */ export const useSignalsApi = ( + topic: string, onMessage: (message: JSONObject) => void, - topic?: string, ) => { const discovery = useApi(discoveryApiRef); const signals = SignalsClient.create({ discoveryApi: discovery }); From 5e1a90daa2175e2ff44518b4bb8185c889f5563e Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Mon, 4 Dec 2023 15:00:02 +0200 Subject: [PATCH 022/283] chore: move signals client to fronend plugin Signed-off-by: Heikki Hellgren --- .changeset/real-eggs-sip.md | 1 + packages/app/package.json | 1 + packages/app/src/plugins.ts | 1 + plugins/signals-node/package.json | 4 +- plugins/signals-react/api-report.md | 16 +----- plugins/signals-react/src/api/index.ts | 1 - .../signals-react/src/hooks/useSignalsApi.ts | 11 ++-- plugins/signals/.eslintrc.js | 1 + plugins/signals/README.md | 13 +++++ plugins/signals/api-report.md | 27 ++++++++++ plugins/signals/catalog-info.yaml | 9 ++++ plugins/signals/dev/index.tsx | 35 +++++++++++++ plugins/signals/package.json | 52 +++++++++++++++++++ .../src/api/SignalsClient.ts | 2 +- plugins/signals/src/api/index.ts | 16 ++++++ plugins/signals/src/index.ts | 17 ++++++ plugins/signals/src/plugin.test.ts | 22 ++++++++ plugins/signals/src/plugin.ts | 39 ++++++++++++++ plugins/signals/src/setupTests.ts | 16 ++++++ yarn.lock | 27 ++++++++++ 20 files changed, 286 insertions(+), 25 deletions(-) create mode 100644 plugins/signals/.eslintrc.js create mode 100644 plugins/signals/README.md create mode 100644 plugins/signals/api-report.md create mode 100644 plugins/signals/catalog-info.yaml create mode 100644 plugins/signals/dev/index.tsx create mode 100644 plugins/signals/package.json rename plugins/{signals-react => signals}/src/api/SignalsClient.ts (98%) create mode 100644 plugins/signals/src/api/index.ts create mode 100644 plugins/signals/src/index.ts create mode 100644 plugins/signals/src/plugin.test.ts create mode 100644 plugins/signals/src/plugin.ts create mode 100644 plugins/signals/src/setupTests.ts diff --git a/.changeset/real-eggs-sip.md b/.changeset/real-eggs-sip.md index ca05205083..ca23d792f8 100644 --- a/.changeset/real-eggs-sip.md +++ b/.changeset/real-eggs-sip.md @@ -1,5 +1,6 @@ --- '@backstage/plugin-signals-backend': patch +'@backstage/plugin-signals': patch '@backstage/plugin-signals-react': patch '@backstage/plugin-signals-node': patch --- diff --git a/packages/app/package.json b/packages/app/package.json index c6ceafcf04..53a2b60a52 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -73,6 +73,7 @@ "@backstage/plugin-search-react": "workspace:^", "@backstage/plugin-sentry": "workspace:^", "@backstage/plugin-shortcuts": "workspace:^", + "@backstage/plugin-signals": "workspace:^", "@backstage/plugin-stack-overflow": "workspace:^", "@backstage/plugin-stackstorm": "workspace:^", "@backstage/plugin-tech-insights": "workspace:^", diff --git a/packages/app/src/plugins.ts b/packages/app/src/plugins.ts index 36f7a86acc..ddd12bea2c 100644 --- a/packages/app/src/plugins.ts +++ b/packages/app/src/plugins.ts @@ -19,3 +19,4 @@ export { badgesPlugin } from '@backstage/plugin-badges'; export { shortcutsPlugin } from '@backstage/plugin-shortcuts'; export { homePlugin } from '@backstage/plugin-home'; +export { signalsPlugin } from '@backstage/plugin-signals'; diff --git a/plugins/signals-node/package.json b/plugins/signals-node/package.json index 66e4528678..2dc17f5e54 100644 --- a/plugins/signals-node/package.json +++ b/plugins/signals-node/package.json @@ -22,8 +22,7 @@ "postpack": "backstage-cli package postpack" }, "devDependencies": { - "@backstage/cli": "workspace:^", - "@types/express": "^4.17.21" + "@backstage/cli": "workspace:^" }, "files": [ "dist" @@ -34,6 +33,7 @@ "@backstage/plugin-auth-node": "workspace:^", "@backstage/plugin-events-node": "workspace:^", "@backstage/types": "workspace:^", + "@types/express": "^4.17.21", "express": "^4.17.1", "uuid": "^8.0.0", "winston": "^3.2.1", diff --git a/plugins/signals-react/api-report.md b/plugins/signals-react/api-report.md index 22e9306c14..0ab752be60 100644 --- a/plugins/signals-react/api-report.md +++ b/plugins/signals-react/api-report.md @@ -4,8 +4,6 @@ ```ts import { ApiRef } from '@backstage/core-plugin-api'; -import { DiscoveryApi } from '@backstage/core-plugin-api'; -import { JSONObject } from '@apollo/explorer/src/helpers/types'; import { JsonObject } from '@backstage/types'; // @public (undocumented) @@ -20,22 +18,10 @@ export type SignalsApi = { // @public (undocumented) export const signalsApiRef: ApiRef; -// @public (undocumented) -export class SignalsClient implements SignalsApi { - // (undocumented) - static create(options: { discoveryApi: DiscoveryApi }): SignalsClient; - // (undocumented) - static instance: SignalsClient | null; - // (undocumented) - subscribe(onMessage: (message: JsonObject) => void, topic: string): void; - // (undocumented) - unsubscribe(topic: string): void; -} - // @public (undocumented) export const useSignalsApi: ( topic: string, - onMessage: (message: JSONObject) => void, + onMessage: (message: JsonObject) => void, ) => void; // (No @packageDocumentation comment for this package) diff --git a/plugins/signals-react/src/api/index.ts b/plugins/signals-react/src/api/index.ts index b8dea2af34..9d5c4c5656 100644 --- a/plugins/signals-react/src/api/index.ts +++ b/plugins/signals-react/src/api/index.ts @@ -14,4 +14,3 @@ * limitations under the License. */ export * from './SignalsApi'; -export * from './SignalsClient'; diff --git a/plugins/signals-react/src/hooks/useSignalsApi.ts b/plugins/signals-react/src/hooks/useSignalsApi.ts index 88112cebc7..d97d80ed76 100644 --- a/plugins/signals-react/src/hooks/useSignalsApi.ts +++ b/plugins/signals-react/src/hooks/useSignalsApi.ts @@ -13,18 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { SignalsClient } from '../api'; -import { discoveryApiRef, useApi } from '@backstage/core-plugin-api'; -import { JSONObject } from '@apollo/explorer/src/helpers/types'; +import { signalsApiRef } from '../api'; +import { useApi } from '@backstage/core-plugin-api'; +import { JsonObject } from '@backstage/types'; import { useEffect } from 'react'; /** @public */ export const useSignalsApi = ( topic: string, - onMessage: (message: JSONObject) => void, + onMessage: (message: JsonObject) => void, ) => { - const discovery = useApi(discoveryApiRef); - const signals = SignalsClient.create({ discoveryApi: discovery }); + const signals = useApi(signalsApiRef); useEffect(() => { signals.subscribe(onMessage, topic); }, [signals, onMessage, topic]); diff --git a/plugins/signals/.eslintrc.js b/plugins/signals/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/signals/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/signals/README.md b/plugins/signals/README.md new file mode 100644 index 0000000000..604fa98a33 --- /dev/null +++ b/plugins/signals/README.md @@ -0,0 +1,13 @@ +# signals + +Welcome to the signals plugin! + +_This plugin was created through the Backstage CLI_ + +## Getting started + +Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/signals](http://localhost:3000/signals). + +You can also serve the plugin in isolation by running `yarn start` in the plugin directory. +This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads. +It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory. diff --git a/plugins/signals/api-report.md b/plugins/signals/api-report.md new file mode 100644 index 0000000000..d2dd111fe6 --- /dev/null +++ b/plugins/signals/api-report.md @@ -0,0 +1,27 @@ +## API Report File for "@backstage/plugin-signals" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackstagePlugin } from '@backstage/core-plugin-api'; +import { DiscoveryApi } from '@backstage/core-plugin-api'; +import { JsonObject } from '@backstage/types'; +import { SignalsApi } from '@backstage/plugin-signals-react'; + +// @public (undocumented) +export class SignalsClient implements SignalsApi { + // (undocumented) + static create(options: { discoveryApi: DiscoveryApi }): SignalsClient; + // (undocumented) + static instance: SignalsClient | null; + // (undocumented) + subscribe(onMessage: (message: JsonObject) => void, topic: string): void; + // (undocumented) + unsubscribe(topic: string): void; +} + +// @public (undocumented) +export const signalsPlugin: BackstagePlugin<{}, {}>; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/signals/catalog-info.yaml b/plugins/signals/catalog-info.yaml new file mode 100644 index 0000000000..ab52477147 --- /dev/null +++ b/plugins/signals/catalog-info.yaml @@ -0,0 +1,9 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-signals + title: '@backstage/plugin-signals' +spec: + lifecycle: experimental + type: backstage-frontend-plugin + owner: maintainers diff --git a/plugins/signals/dev/index.tsx b/plugins/signals/dev/index.tsx new file mode 100644 index 0000000000..e8c7928f57 --- /dev/null +++ b/plugins/signals/dev/index.tsx @@ -0,0 +1,35 @@ +/* + * Copyright 2023 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 React from 'react'; +import { createDevApp } from '@backstage/dev-utils'; +import { signalsPlugin } from '../src/plugin'; +import { Content, Header, Page } from '@backstage/core-components'; +import { Typography } from '@material-ui/core'; + +createDevApp() + .registerPlugin(signalsPlugin) + .addPage({ + title: 'Debug', + element: ( + +
+ + TODO + + + ), + }) + .render(); diff --git a/plugins/signals/package.json b/plugins/signals/package.json new file mode 100644 index 0000000000..9c0bcb5c13 --- /dev/null +++ b/plugins/signals/package.json @@ -0,0 +1,52 @@ +{ + "name": "@backstage/plugin-signals", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "frontend-plugin" + }, + "sideEffects": false, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/core-components": "workspace:^", + "@backstage/core-plugin-api": "workspace:^", + "@backstage/plugin-signals-react": "workspace:^", + "@backstage/theme": "workspace:^", + "@backstage/types": "workspace:^", + "@material-ui/core": "^4.9.13", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "^4.0.0-alpha.61", + "react-use": "^17.2.4" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@backstage/core-app-api": "workspace:^", + "@backstage/dev-utils": "workspace:^", + "@backstage/test-utils": "workspace:^", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^12.1.3", + "@testing-library/user-event": "^14.0.0", + "msw": "^1.0.0" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/signals-react/src/api/SignalsClient.ts b/plugins/signals/src/api/SignalsClient.ts similarity index 98% rename from plugins/signals-react/src/api/SignalsClient.ts rename to plugins/signals/src/api/SignalsClient.ts index cdfa7e5606..34ef557f31 100644 --- a/plugins/signals-react/src/api/SignalsClient.ts +++ b/plugins/signals/src/api/SignalsClient.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { SignalsApi } from './SignalsApi'; +import { SignalsApi } from '@backstage/plugin-signals-react'; import { JsonObject } from '@backstage/types'; import { DiscoveryApi } from '@backstage/core-plugin-api'; diff --git a/plugins/signals/src/api/index.ts b/plugins/signals/src/api/index.ts new file mode 100644 index 0000000000..80e69259af --- /dev/null +++ b/plugins/signals/src/api/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './SignalsClient'; diff --git a/plugins/signals/src/index.ts b/plugins/signals/src/index.ts new file mode 100644 index 0000000000..ddf8afb9c6 --- /dev/null +++ b/plugins/signals/src/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { signalsPlugin } from './plugin'; +export * from './api'; diff --git a/plugins/signals/src/plugin.test.ts b/plugins/signals/src/plugin.test.ts new file mode 100644 index 0000000000..cc8ecf44ed --- /dev/null +++ b/plugins/signals/src/plugin.test.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2023 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 { signalsPlugin } from './plugin'; + +describe('signals', () => { + it('should export plugin', () => { + expect(signalsPlugin).toBeDefined(); + }); +}); diff --git a/plugins/signals/src/plugin.ts b/plugins/signals/src/plugin.ts new file mode 100644 index 0000000000..457b3d9925 --- /dev/null +++ b/plugins/signals/src/plugin.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2023 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 { + createApiFactory, + createPlugin, + discoveryApiRef, +} from '@backstage/core-plugin-api'; +import { signalsApiRef } from '@backstage/plugin-signals-react'; +import { SignalsClient } from './api/SignalsClient'; + +/** @public */ +export const signalsPlugin = createPlugin({ + id: 'signals', + apis: [ + createApiFactory({ + api: signalsApiRef, + deps: { + discoveryApi: discoveryApiRef, + }, + factory: ({ discoveryApi }) => + SignalsClient.create({ + discoveryApi, + }), + }), + ], +}); diff --git a/plugins/signals/src/setupTests.ts b/plugins/signals/src/setupTests.ts new file mode 100644 index 0000000000..865308e634 --- /dev/null +++ b/plugins/signals/src/setupTests.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 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 '@testing-library/jest-dom'; diff --git a/yarn.lock b/yarn.lock index cdd232b103..a6e69edc89 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8893,6 +8893,32 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-signals@workspace:^, @backstage/plugin-signals@workspace:plugins/signals": + version: 0.0.0-use.local + resolution: "@backstage/plugin-signals@workspace:plugins/signals" + dependencies: + "@backstage/cli": "workspace:^" + "@backstage/core-app-api": "workspace:^" + "@backstage/core-components": "workspace:^" + "@backstage/core-plugin-api": "workspace:^" + "@backstage/dev-utils": "workspace:^" + "@backstage/plugin-signals-react": "workspace:^" + "@backstage/test-utils": "workspace:^" + "@backstage/theme": "workspace:^" + "@backstage/types": "workspace:^" + "@material-ui/core": ^4.9.13 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": ^4.0.0-alpha.61 + "@testing-library/jest-dom": ^5.10.1 + "@testing-library/react": ^12.1.3 + "@testing-library/user-event": ^14.0.0 + msw: ^1.0.0 + react-use: ^17.2.4 + peerDependencies: + react: ^16.13.1 || ^17.0.0 + languageName: unknown + linkType: soft + "@backstage/plugin-sonarqube-backend@workspace:^, @backstage/plugin-sonarqube-backend@workspace:plugins/sonarqube-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-sonarqube-backend@workspace:plugins/sonarqube-backend" @@ -26556,6 +26582,7 @@ __metadata: "@backstage/plugin-search-react": "workspace:^" "@backstage/plugin-sentry": "workspace:^" "@backstage/plugin-shortcuts": "workspace:^" + "@backstage/plugin-signals": "workspace:^" "@backstage/plugin-stack-overflow": "workspace:^" "@backstage/plugin-stackstorm": "workspace:^" "@backstage/plugin-tech-insights": "workspace:^" From d05a6f566fde13de901659ffdcc232ce15bde3ef Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Tue, 5 Dec 2023 09:01:37 +0200 Subject: [PATCH 023/283] feat: allow multiple subscriptions to single topic + auth Signed-off-by: Heikki Hellgren --- plugins/signals-node/src/SignalsService.ts | 25 ++- plugins/signals-react/api-report.md | 4 +- plugins/signals-react/src/api/SignalsApi.ts | 4 +- .../signals-react/src/hooks/useSignalsApi.ts | 16 +- plugins/signals/api-report.md | 14 +- plugins/signals/package.json | 3 +- plugins/signals/src/api/SignalsClient.ts | 183 +++++++++++++----- plugins/signals/src/plugin.ts | 5 +- yarn.lock | 1 + 9 files changed, 187 insertions(+), 68 deletions(-) diff --git a/plugins/signals-node/src/SignalsService.ts b/plugins/signals-node/src/SignalsService.ts index 15a63e15d7..9cbe4b1565 100644 --- a/plugins/signals-node/src/SignalsService.ts +++ b/plugins/signals-node/src/SignalsService.ts @@ -28,6 +28,7 @@ import { JsonObject } from '@backstage/types'; import { BackstageIdentityResponse, IdentityApi, + IdentityApiGetIdentityRequest, } from '@backstage/plugin-auth-node'; /** @public */ @@ -160,6 +161,23 @@ export class SignalsService implements EventSubscriber { ); connection.subscriptions.delete(message.topic as string); } + + if (message.action === 'authenticate' && message.token) { + this.logger.info(`Connection ${connection.id} authenticated`); + this.identity + .getIdentity({ + request: { + headers: { authorization: message.token }, + }, + } as IdentityApiGetIdentityRequest) + .then(identity => { + if (identity) { + connection.user = identity.identity.userEntityRef; + connection.ownershipEntityRefs = + identity.identity.ownershipEntityRefs; + } + }); + } } /** @@ -183,6 +201,11 @@ export class SignalsService implements EventSubscriber { message: JsonObject, brokedEvent: boolean, ) { + const jsonMessage = JSON.stringify({ topic, message }); + if (jsonMessage.length === 0) { + return; + } + this.connections.forEach(conn => { if (!conn.subscriptions.has(topic)) { return; @@ -194,7 +217,7 @@ export class SignalsService implements EventSubscriber { ) { return; } - conn.ws.send(JSON.stringify({ topic, message })); + conn.ws.send(jsonMessage); }); // If this event has not been broadcasted to all servers, then use diff --git a/plugins/signals-react/api-report.md b/plugins/signals-react/api-report.md index 0ab752be60..75aeb5d77d 100644 --- a/plugins/signals-react/api-report.md +++ b/plugins/signals-react/api-report.md @@ -11,8 +11,8 @@ export type SignalsApi = { subscribe( onMessage: (message: JsonObject, topic?: string) => void, topic: string, - ): void; - unsubscribe(topic: string): void; + ): string; + unsubscribe(subscription: string): void; }; // @public (undocumented) diff --git a/plugins/signals-react/src/api/SignalsApi.ts b/plugins/signals-react/src/api/SignalsApi.ts index 28f9da39dc..e592b56df0 100644 --- a/plugins/signals-react/src/api/SignalsApi.ts +++ b/plugins/signals-react/src/api/SignalsApi.ts @@ -26,7 +26,7 @@ export type SignalsApi = { subscribe( onMessage: (message: JsonObject, topic?: string) => void, topic: string, - ): void; + ): string; - unsubscribe(topic: string): void; + unsubscribe(subscription: string): void; }; diff --git a/plugins/signals-react/src/hooks/useSignalsApi.ts b/plugins/signals-react/src/hooks/useSignalsApi.ts index d97d80ed76..327ca08ff9 100644 --- a/plugins/signals-react/src/hooks/useSignalsApi.ts +++ b/plugins/signals-react/src/hooks/useSignalsApi.ts @@ -16,7 +16,7 @@ import { signalsApiRef } from '../api'; import { useApi } from '@backstage/core-plugin-api'; import { JsonObject } from '@backstage/types'; -import { useEffect } from 'react'; +import { useEffect, useState } from 'react'; /** @public */ export const useSignalsApi = ( @@ -24,13 +24,19 @@ export const useSignalsApi = ( onMessage: (message: JsonObject) => void, ) => { const signals = useApi(signalsApiRef); + const [subscription, setSubscription] = useState(null); useEffect(() => { - signals.subscribe(onMessage, topic); - }, [signals, onMessage, topic]); + if (!subscription) { + const sub = signals.subscribe(onMessage, topic); + setSubscription(sub); + } + }, [subscription, signals, onMessage, topic]); useEffect(() => { return () => { - signals.unsubscribe(topic); + if (subscription) { + signals.unsubscribe(subscription); + } }; - }, [signals, topic]); + }, [subscription, signals, topic]); }; diff --git a/plugins/signals/api-report.md b/plugins/signals/api-report.md index d2dd111fe6..2c9777a5c0 100644 --- a/plugins/signals/api-report.md +++ b/plugins/signals/api-report.md @@ -5,19 +5,25 @@ ```ts import { BackstagePlugin } from '@backstage/core-plugin-api'; import { DiscoveryApi } from '@backstage/core-plugin-api'; +import { IdentityApi } from '@backstage/core-plugin-api'; import { JsonObject } from '@backstage/types'; import { SignalsApi } from '@backstage/plugin-signals-react'; // @public (undocumented) export class SignalsClient implements SignalsApi { // (undocumented) - static create(options: { discoveryApi: DiscoveryApi }): SignalsClient; + static readonly CONNECT_TIMEOUT_MS: number; // (undocumented) - static instance: SignalsClient | null; + static create(options: { + identity: IdentityApi; + discoveryApi: DiscoveryApi; + }): SignalsClient; // (undocumented) - subscribe(onMessage: (message: JsonObject) => void, topic: string): void; + static readonly RECONNECT_TIMEOUT_MS: number; // (undocumented) - unsubscribe(topic: string): void; + subscribe(onMessage: (message: JsonObject) => void, topic: string): string; + // (undocumented) + unsubscribe(subscription: string): void; } // @public (undocumented) diff --git a/plugins/signals/package.json b/plugins/signals/package.json index 9c0bcb5c13..35ffc8e212 100644 --- a/plugins/signals/package.json +++ b/plugins/signals/package.json @@ -31,7 +31,8 @@ "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.61", - "react-use": "^17.2.4" + "react-use": "^17.2.4", + "uuid": "^8.0.0" }, "peerDependencies": { "react": "^16.13.1 || ^17.0.0" diff --git a/plugins/signals/src/api/SignalsClient.ts b/plugins/signals/src/api/SignalsClient.ts index 34ef557f31..cc1254578f 100644 --- a/plugins/signals/src/api/SignalsClient.ts +++ b/plugins/signals/src/api/SignalsClient.ts @@ -15,60 +15,105 @@ */ import { SignalsApi } from '@backstage/plugin-signals-react'; import { JsonObject } from '@backstage/types'; -import { DiscoveryApi } from '@backstage/core-plugin-api'; +import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; +import { v4 as uuid } from 'uuid'; + +/** @internal */ +type Subscription = { + topic: string; + callback: (message: JsonObject) => void; +}; + +/** @internal */ +const WS_CLOSE_NORMAL = 1000; +/** @internal */ +const WS_CLOSE_GOING_AWAY = 1001; /** @public */ export class SignalsClient implements SignalsApi { - static instance: SignalsClient | null = null; + static readonly CONNECT_TIMEOUT_MS: number = 1000; + static readonly RECONNECT_TIMEOUT_MS: number = 5000; private ws: WebSocket | null = null; - private discoveryApi: DiscoveryApi; - private cbs: Map void> = new Map(); - private queue: JsonObject[] = []; + private subscriptions: Map = new Map(); + private messageQueue: string[] = []; private reconnectTimeout: any; - static create(options: { discoveryApi: DiscoveryApi }) { - if (!SignalsClient.instance) { - SignalsClient.instance = new SignalsClient(options); - } - return SignalsClient.instance; + static create(options: { + identity: IdentityApi; + discoveryApi: DiscoveryApi; + }) { + const { identity, discoveryApi } = options; + return new SignalsClient(identity, discoveryApi); } - private constructor(options: { discoveryApi: DiscoveryApi }) { - this.discoveryApi = options.discoveryApi; + private constructor( + private identity: IdentityApi, + private discoveryApi: DiscoveryApi, + ) {} + + subscribe(onMessage: (message: JsonObject) => void, topic: string): string { + const subscriptionId = uuid(); + const exists = [...this.subscriptions.values()].find( + sub => sub.topic === topic, + ); + this.subscriptions.set(subscriptionId, { topic, callback: onMessage }); + + this.connect() + .then(() => { + // Do not subscribe twice to same topic even there is multiple callbacks + if (!exists) { + this.send({ action: 'subscribe', topic }); + } + }) + .catch(() => { + this.reconnect(); + }); + return subscriptionId; } - subscribe(onMessage: (message: JsonObject) => void, topic: string): void { - // Do not allow to subscribe to same topic multiple times - if (this.cbs.has(topic)) { + unsubscribe(subscription: string): void { + const sub = this.subscriptions.get(subscription); + if (!sub) { return; } + const topic = sub.topic; + this.subscriptions.delete(subscription); + const exists = [...this.subscriptions.values()].find( + s => s.topic === topic, + ); + // If there are subscriptions still listening to this topic, do not + // unsubscribe from the server + if (!exists) { + this.send({ action: 'unsubscribe', topic: sub.topic }); + } - this.cbs.set(topic, onMessage); - this.connect().then(() => { - this.send({ action: 'subscribe', topic }); - }); - } - - unsubscribe(topic: string): void { - this.cbs.delete(topic); - this.send({ action: 'unsubscribe', topic }); + // If there are no subscriptions, close the connection + if (this.subscriptions.size === 0) { + this.ws?.close(WS_CLOSE_NORMAL); + this.ws = null; + } } private send(data?: JsonObject): void { + const jsonMessage = JSON.stringify(data); + if (jsonMessage.length === 0) { + return; + } + if (!this.ws || this.ws.readyState !== WebSocket.OPEN) { if (data) { - this.queue.push(data); + this.messageQueue.unshift(jsonMessage); } return; } // First send queue - for (const msg of this.queue) { - this.ws!.send(JSON.stringify(msg)); + for (const msg of this.messageQueue) { + this.ws!.send(msg); } - this.queue = []; + this.messageQueue = []; if (data) { - this.ws!.send(JSON.stringify(data)); + this.ws!.send(jsonMessage); } } @@ -83,31 +128,60 @@ export class SignalsClient implements SignalsApi { this.ws = new WebSocket(url.toString()); this.ws.onmessage = (data: MessageEvent) => { - try { - const json = JSON.parse(data.data) as JsonObject; - if (json.topic) { - const cb = this.cbs.get(json.topic as string); - if (cb) { - cb(json.message as JsonObject); - } - } - } catch (e) { - // NOOP - } + this.handleMessage(data); }; this.ws.onerror = () => { this.reconnect(); }; - this.ws.onclose = () => { - this.reconnect(); + this.ws.onclose = (ev: CloseEvent) => { + if (ev.code !== WS_CLOSE_NORMAL && ev.code !== WS_CLOSE_GOING_AWAY) { + this.reconnect(); + } }; - while (this.ws.readyState !== WebSocket.OPEN) { - await new Promise(r => setTimeout(r, 10)); + // Wait until connection is open + let connectSleep = 0; + while ( + this.ws && + this.ws.readyState !== WebSocket.OPEN && + connectSleep < SignalsClient.CONNECT_TIMEOUT_MS + ) { + await new Promise(r => setTimeout(r, 100)); + connectSleep += 100; + } + + if (!this.ws || this.ws.readyState !== WebSocket.OPEN) { + throw new Error('Connect timeout'); + } + + // Authenticate + await this.authenticate(); + } + + private handleMessage(data: MessageEvent) { + try { + const json = JSON.parse(data.data) as JsonObject; + if (json.topic) { + for (const sub of this.subscriptions.values()) { + if (sub.topic === json.topic) { + sub.callback(json.message as JsonObject); + } + } + } + } catch (e) { + // NOOP + } + } + + private async authenticate() { + const { token } = await this.identity.getCredentials(); + if (token) { + // Authentication is done with websocket message to server as the plain + // websocket does not allow sending headers during connection upgrade + this.send({ action: 'authenticate', token: token }); } - this.send(); } private reconnect() { @@ -116,16 +190,21 @@ export class SignalsClient implements SignalsApi { } this.reconnectTimeout = setTimeout(() => { + this.reconnectTimeout = null; if (this.ws) { this.ws.close(); } this.ws = null; - this.connect().then(() => { - // Resubscribe to existing topics in case we lost connection - for (const topic of this.cbs.keys()) { - this.send({ action: 'subscribe', topic }); - } - }); - }, 5000); + this.connect() + .then(() => { + // Resubscribe to existing topics in case we lost connection + for (const topic of this.subscriptions.keys()) { + this.send({ action: 'subscribe', topic }); + } + }) + .catch(() => { + this.reconnect(); + }); + }, SignalsClient.RECONNECT_TIMEOUT_MS); } } diff --git a/plugins/signals/src/plugin.ts b/plugins/signals/src/plugin.ts index 457b3d9925..d1b0311116 100644 --- a/plugins/signals/src/plugin.ts +++ b/plugins/signals/src/plugin.ts @@ -17,6 +17,7 @@ import { createApiFactory, createPlugin, discoveryApiRef, + identityApiRef, } from '@backstage/core-plugin-api'; import { signalsApiRef } from '@backstage/plugin-signals-react'; import { SignalsClient } from './api/SignalsClient'; @@ -28,10 +29,12 @@ export const signalsPlugin = createPlugin({ createApiFactory({ api: signalsApiRef, deps: { + identity: identityApiRef, discoveryApi: discoveryApiRef, }, - factory: ({ discoveryApi }) => + factory: ({ identity, discoveryApi }) => SignalsClient.create({ + identity, discoveryApi, }), }), diff --git a/yarn.lock b/yarn.lock index a6e69edc89..c89f106c57 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8914,6 +8914,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 msw: ^1.0.0 react-use: ^17.2.4 + uuid: ^8.0.0 peerDependencies: react: ^16.13.1 || ^17.0.0 languageName: unknown From 7af9750ea8f9d7bf815ffe21565f50f993700368 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Tue, 5 Dec 2023 09:19:50 +0200 Subject: [PATCH 024/283] feat: use websocket header to pass the auth token Signed-off-by: Heikki Hellgren --- plugins/signals-node/src/SignalsService.ts | 45 ++++++++-------------- plugins/signals-node/src/types.ts | 8 ++++ plugins/signals/src/api/SignalsClient.ts | 16 ++------ 3 files changed, 28 insertions(+), 41 deletions(-) diff --git a/plugins/signals-node/src/SignalsService.ts b/plugins/signals-node/src/SignalsService.ts index 9cbe4b1565..6a1547a6bb 100644 --- a/plugins/signals-node/src/SignalsService.ts +++ b/plugins/signals-node/src/SignalsService.ts @@ -19,7 +19,11 @@ import { EventSubscriber, } from '@backstage/plugin-events-node'; import { Logger } from 'winston'; -import { ServiceOptions, SignalConnection } from './types'; +import { + ServiceOptions, + SignalConnection, + SignalsEventBrokerPayload, +} from './types'; import { RawData, WebSocket, WebSocketServer } from 'ws'; import { IncomingMessage } from 'http'; import { v4 as uuid } from 'uuid'; @@ -31,13 +35,6 @@ import { IdentityApiGetIdentityRequest, } from '@backstage/plugin-auth-node'; -/** @public */ -export type SignalsEventBrokerPayload = { - recipients?: string[]; - topic?: string; - message?: JsonObject; -}; - /** @public */ export class SignalsService implements EventSubscriber { private readonly serverId: string; @@ -83,9 +80,18 @@ export class SignalsService implements EventSubscriber { * @param req - Request */ handleUpgrade = async (req: Request) => { - const identity = await this.identity.getIdentity({ - request: req, - }); + let identity: BackstageIdentityResponse | undefined = undefined; + + // Authentication token is passed in Sec-WebSocket-Protocol header as there + // is no other way to pass the token with plain websockets + const token = req.headers['sec-websocket-protocol']; + if (token) { + identity = await this.identity.getIdentity({ + request: { + headers: { authorization: token }, + }, + } as IdentityApiGetIdentityRequest); + } this.server.handleUpgrade( req, @@ -161,23 +167,6 @@ export class SignalsService implements EventSubscriber { ); connection.subscriptions.delete(message.topic as string); } - - if (message.action === 'authenticate' && message.token) { - this.logger.info(`Connection ${connection.id} authenticated`); - this.identity - .getIdentity({ - request: { - headers: { authorization: message.token }, - }, - } as IdentityApiGetIdentityRequest) - .then(identity => { - if (identity) { - connection.user = identity.identity.userEntityRef; - connection.ownershipEntityRefs = - identity.identity.ownershipEntityRefs; - } - }); - } } /** diff --git a/plugins/signals-node/src/types.ts b/plugins/signals-node/src/types.ts index c53bfdb20e..090e4b2ff1 100644 --- a/plugins/signals-node/src/types.ts +++ b/plugins/signals-node/src/types.ts @@ -17,6 +17,7 @@ import { IdentityApi } from '@backstage/plugin-auth-node'; import { EventBroker } from '@backstage/plugin-events-node'; import { Logger } from 'winston'; import { WebSocket } from 'ws'; +import { JsonObject } from '@backstage/types'; /** * @public @@ -27,6 +28,13 @@ export type ServiceOptions = { identity: IdentityApi; }; +/** @public */ +export type SignalsEventBrokerPayload = { + recipients?: string[]; + topic?: string; + message?: JsonObject; +}; + /** * @internal */ diff --git a/plugins/signals/src/api/SignalsClient.ts b/plugins/signals/src/api/SignalsClient.ts index cc1254578f..d8d3328411 100644 --- a/plugins/signals/src/api/SignalsClient.ts +++ b/plugins/signals/src/api/SignalsClient.ts @@ -123,9 +123,11 @@ export class SignalsClient implements SignalsApi { } const apiUrl = `${await this.discoveryApi.getBaseUrl('signals')}`; + const { token } = await this.identity.getCredentials(); + const url = new URL(apiUrl); url.protocol = url.protocol === 'http:' ? 'ws' : 'wss'; - this.ws = new WebSocket(url.toString()); + this.ws = new WebSocket(url.toString(), token); this.ws.onmessage = (data: MessageEvent) => { this.handleMessage(data); @@ -155,9 +157,6 @@ export class SignalsClient implements SignalsApi { if (!this.ws || this.ws.readyState !== WebSocket.OPEN) { throw new Error('Connect timeout'); } - - // Authenticate - await this.authenticate(); } private handleMessage(data: MessageEvent) { @@ -175,15 +174,6 @@ export class SignalsClient implements SignalsApi { } } - private async authenticate() { - const { token } = await this.identity.getCredentials(); - if (token) { - // Authentication is done with websocket message to server as the plain - // websocket does not allow sending headers during connection upgrade - this.send({ action: 'authenticate', token: token }); - } - } - private reconnect() { if (this.reconnectTimeout) { clearTimeout(this.reconnectTimeout); From 8fbabdc2cbb5cfe5c0777fb8d9cac9e9739f00f8 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Tue, 5 Dec 2023 09:31:46 +0200 Subject: [PATCH 025/283] chore: add check for connection status before sending Signed-off-by: Heikki Hellgren --- plugins/signals-node/src/SignalsService.ts | 5 +++++ plugins/signals/src/api/SignalsClient.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/signals-node/src/SignalsService.ts b/plugins/signals-node/src/SignalsService.ts index 6a1547a6bb..c743c958dd 100644 --- a/plugins/signals-node/src/SignalsService.ts +++ b/plugins/signals-node/src/SignalsService.ts @@ -206,6 +206,11 @@ export class SignalsService implements EventSubscriber { ) { return; } + + if (conn.ws.readyState !== WebSocket.OPEN) { + return; + } + conn.ws.send(jsonMessage); }); diff --git a/plugins/signals/src/api/SignalsClient.ts b/plugins/signals/src/api/SignalsClient.ts index d8d3328411..1fbe374ad9 100644 --- a/plugins/signals/src/api/SignalsClient.ts +++ b/plugins/signals/src/api/SignalsClient.ts @@ -126,7 +126,7 @@ export class SignalsClient implements SignalsApi { const { token } = await this.identity.getCredentials(); const url = new URL(apiUrl); - url.protocol = url.protocol === 'http:' ? 'ws' : 'wss'; + url.protocol = url.protocol === 'http:' ? 'ws:' : 'wss:'; this.ws = new WebSocket(url.toString(), token); this.ws.onmessage = (data: MessageEvent) => { From db84649e81ce0b6e8128314afcca6435d0b69d97 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Tue, 5 Dec 2023 10:40:48 +0200 Subject: [PATCH 026/283] test: add tests for signals client Signed-off-by: Heikki Hellgren --- plugins/signals-react/api-report.md | 5 +- plugins/signals-react/src/api/SignalsApi.ts | 5 +- .../signals-react/src/hooks/useSignalsApi.ts | 2 +- plugins/signals/api-report.md | 10 +- plugins/signals/package.json | 1 + plugins/signals/src/api/SignalsClient.test.ts | 119 ++++++++++++++++++ plugins/signals/src/api/SignalsClient.ts | 46 ++++--- yarn.lock | 1 + 8 files changed, 160 insertions(+), 29 deletions(-) create mode 100644 plugins/signals/src/api/SignalsClient.test.ts diff --git a/plugins/signals-react/api-report.md b/plugins/signals-react/api-report.md index 75aeb5d77d..21f070c35d 100644 --- a/plugins/signals-react/api-report.md +++ b/plugins/signals-react/api-report.md @@ -8,10 +8,7 @@ import { JsonObject } from '@backstage/types'; // @public (undocumented) export type SignalsApi = { - subscribe( - onMessage: (message: JsonObject, topic?: string) => void, - topic: string, - ): string; + subscribe(topic: string, onMessage: (message: JsonObject) => void): string; unsubscribe(subscription: string): void; }; diff --git a/plugins/signals-react/src/api/SignalsApi.ts b/plugins/signals-react/src/api/SignalsApi.ts index e592b56df0..2aefa5d166 100644 --- a/plugins/signals-react/src/api/SignalsApi.ts +++ b/plugins/signals-react/src/api/SignalsApi.ts @@ -23,10 +23,7 @@ export const signalsApiRef = createApiRef({ /** @public */ export type SignalsApi = { - subscribe( - onMessage: (message: JsonObject, topic?: string) => void, - topic: string, - ): string; + subscribe(topic: string, onMessage: (message: JsonObject) => void): string; unsubscribe(subscription: string): void; }; diff --git a/plugins/signals-react/src/hooks/useSignalsApi.ts b/plugins/signals-react/src/hooks/useSignalsApi.ts index 327ca08ff9..0fcc69efed 100644 --- a/plugins/signals-react/src/hooks/useSignalsApi.ts +++ b/plugins/signals-react/src/hooks/useSignalsApi.ts @@ -27,7 +27,7 @@ export const useSignalsApi = ( const [subscription, setSubscription] = useState(null); useEffect(() => { if (!subscription) { - const sub = signals.subscribe(onMessage, topic); + const sub = signals.subscribe(topic, onMessage); setSubscription(sub); } }, [subscription, signals, onMessage, topic]); diff --git a/plugins/signals/api-report.md b/plugins/signals/api-report.md index 2c9777a5c0..08c52ef418 100644 --- a/plugins/signals/api-report.md +++ b/plugins/signals/api-report.md @@ -11,17 +11,19 @@ import { SignalsApi } from '@backstage/plugin-signals-react'; // @public (undocumented) export class SignalsClient implements SignalsApi { - // (undocumented) - static readonly CONNECT_TIMEOUT_MS: number; // (undocumented) static create(options: { identity: IdentityApi; discoveryApi: DiscoveryApi; + connectTimeout?: number; + reconnectTimeout?: number; }): SignalsClient; // (undocumented) - static readonly RECONNECT_TIMEOUT_MS: number; + static readonly DEFAULT_CONNECT_TIMEOUT_MS: number; // (undocumented) - subscribe(onMessage: (message: JsonObject) => void, topic: string): string; + static readonly DEFAULT_RECONNECT_TIMEOUT_MS: number; + // (undocumented) + subscribe(topic: string, onMessage: (message: JsonObject) => void): string; // (undocumented) unsubscribe(subscription: string): void; } diff --git a/plugins/signals/package.json b/plugins/signals/package.json index 35ffc8e212..e708d46329 100644 --- a/plugins/signals/package.json +++ b/plugins/signals/package.json @@ -45,6 +45,7 @@ "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", + "jest-websocket-mock": "^2.5.0", "msw": "^1.0.0" }, "files": [ diff --git a/plugins/signals/src/api/SignalsClient.test.ts b/plugins/signals/src/api/SignalsClient.test.ts new file mode 100644 index 0000000000..03b25d580d --- /dev/null +++ b/plugins/signals/src/api/SignalsClient.test.ts @@ -0,0 +1,119 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; +import WS from 'jest-websocket-mock'; +import { SignalsClient } from './SignalsClient'; + +describe('SignalsClient', () => { + const tokenFunction = jest.fn(); + const baseUrlFunction = jest.fn(); + const identity = { + getCredentials: tokenFunction, + } as unknown as IdentityApi; + const discoveryApi = { + getBaseUrl: baseUrlFunction, + } as unknown as DiscoveryApi; + + let server: WS; + + beforeEach(async () => { + jest.resetAllMocks(); + tokenFunction.mockResolvedValue({ token: '12345' }); + baseUrlFunction.mockResolvedValue('http://localhost:1234'); + server = new WS('ws://localhost:1234', { jsonProtocol: true }); + }); + + afterEach(() => { + WS.clean(); + }); + + it('should handle single subscription correctly', async () => { + const messageMock = jest.fn(); + const client = SignalsClient.create({ discoveryApi, identity }); + const sub = client.subscribe('topic', messageMock); + await server.connected; + + await expect(server).toReceiveMessage({ + action: 'subscribe', + topic: 'topic', + }); + server.send({ topic: 'topic', message: { hello: 'world' } }); + expect(messageMock).toHaveBeenCalledWith({ hello: 'world' }); + + client.unsubscribe(sub); + await expect(server).toReceiveMessage({ + action: 'unsubscribe', + topic: 'topic', + }); + }); + + it('should handle multiple subscription correctly', async () => { + const messageMock1 = jest.fn(); + const messageMock2 = jest.fn(); + const client1 = SignalsClient.create({ discoveryApi, identity }); + const client2 = SignalsClient.create({ discoveryApi, identity }); + const sub1 = client1.subscribe('topic', messageMock1); + const sub2 = client2.subscribe('topic', messageMock2); + + await server.connected; + + await expect(server).toReceiveMessage({ + action: 'subscribe', + topic: 'topic', + }); + server.send({ topic: 'topic', message: { hello: 'world' } }); + expect(messageMock1).toHaveBeenCalledWith({ hello: 'world' }); + expect(messageMock2).toHaveBeenCalledWith({ hello: 'world' }); + + client1.unsubscribe(sub1); + await expect(server).not.toReceiveMessage({ + action: 'unsubscribe', + topic: 'topic', + }); + + client2.unsubscribe(sub2); + await expect(server).toReceiveMessage({ + action: 'unsubscribe', + topic: 'topic', + }); + }); + + it('should reconnect on error', async () => { + const messageMock = jest.fn(); + const client = SignalsClient.create({ + discoveryApi, + identity, + reconnectTimeout: 10, + connectTimeout: 100, + }); + + client.subscribe('topic', messageMock); + await server.connected; + await expect(server).toReceiveMessage({ + action: 'subscribe', + topic: 'topic', + }); + + await server.server.emit('error', null); + + await new Promise(r => setTimeout(r, 50)); + await expect(server).toReceiveMessage({ + action: 'subscribe', + topic: 'topic', + }); + }); +}); diff --git a/plugins/signals/src/api/SignalsClient.ts b/plugins/signals/src/api/SignalsClient.ts index 1fbe374ad9..4051468a9e 100644 --- a/plugins/signals/src/api/SignalsClient.ts +++ b/plugins/signals/src/api/SignalsClient.ts @@ -31,27 +31,41 @@ const WS_CLOSE_GOING_AWAY = 1001; /** @public */ export class SignalsClient implements SignalsApi { - static readonly CONNECT_TIMEOUT_MS: number = 1000; - static readonly RECONNECT_TIMEOUT_MS: number = 5000; + static readonly DEFAULT_CONNECT_TIMEOUT_MS: number = 1000; + static readonly DEFAULT_RECONNECT_TIMEOUT_MS: number = 5000; private ws: WebSocket | null = null; private subscriptions: Map = new Map(); private messageQueue: string[] = []; - private reconnectTimeout: any; + private reconnectTo: any; static create(options: { identity: IdentityApi; discoveryApi: DiscoveryApi; + connectTimeout?: number; + reconnectTimeout?: number; }) { - const { identity, discoveryApi } = options; - return new SignalsClient(identity, discoveryApi); + const { + identity, + discoveryApi, + connectTimeout = SignalsClient.DEFAULT_CONNECT_TIMEOUT_MS, + reconnectTimeout = SignalsClient.DEFAULT_RECONNECT_TIMEOUT_MS, + } = options; + return new SignalsClient( + identity, + discoveryApi, + connectTimeout, + reconnectTimeout, + ); } private constructor( private identity: IdentityApi, private discoveryApi: DiscoveryApi, + private connectTimeout: number, + private reconnectTimeout: number, ) {} - subscribe(onMessage: (message: JsonObject) => void, topic: string): string { + subscribe(topic: string, onMessage: (message: JsonObject) => void): string { const subscriptionId = uuid(); const exists = [...this.subscriptions.values()].find( sub => sub.topic === topic, @@ -118,11 +132,11 @@ export class SignalsClient implements SignalsApi { } private async connect() { - if (this.ws) { + if (this.ws && this.ws.readyState === WebSocket.OPEN) { return; } - const apiUrl = `${await this.discoveryApi.getBaseUrl('signals')}`; + const apiUrl = await this.discoveryApi.getBaseUrl('signals'); const { token } = await this.identity.getCredentials(); const url = new URL(apiUrl); @@ -148,7 +162,7 @@ export class SignalsClient implements SignalsApi { while ( this.ws && this.ws.readyState !== WebSocket.OPEN && - connectSleep < SignalsClient.CONNECT_TIMEOUT_MS + connectSleep < this.connectTimeout ) { await new Promise(r => setTimeout(r, 100)); connectSleep += 100; @@ -175,12 +189,12 @@ export class SignalsClient implements SignalsApi { } private reconnect() { - if (this.reconnectTimeout) { - clearTimeout(this.reconnectTimeout); + if (this.reconnectTo) { + clearTimeout(this.reconnectTo); } - this.reconnectTimeout = setTimeout(() => { - this.reconnectTimeout = null; + this.reconnectTo = setTimeout(() => { + this.reconnectTo = null; if (this.ws) { this.ws.close(); } @@ -188,13 +202,13 @@ export class SignalsClient implements SignalsApi { this.connect() .then(() => { // Resubscribe to existing topics in case we lost connection - for (const topic of this.subscriptions.keys()) { - this.send({ action: 'subscribe', topic }); + for (const sub of this.subscriptions.values()) { + this.send({ action: 'subscribe', topic: sub.topic }); } }) .catch(() => { this.reconnect(); }); - }, SignalsClient.RECONNECT_TIMEOUT_MS); + }, this.reconnectTimeout); } } diff --git a/yarn.lock b/yarn.lock index c89f106c57..d44cfeab72 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8912,6 +8912,7 @@ __metadata: "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 + jest-websocket-mock: ^2.5.0 msw: ^1.0.0 react-use: ^17.2.4 uuid: ^8.0.0 From 59a4508efeceed5f3e821053a1305b60ea725328 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Tue, 5 Dec 2023 15:35:36 +0200 Subject: [PATCH 027/283] feat: update devtools almost real time using signals Signed-off-by: Heikki Hellgren --- .changeset/poor-sheep-tease.md | 6 ++++ packages/backend/src/index.ts | 7 ++++ packages/backend/src/plugins/devtools.ts | 1 + packages/backend/src/plugins/signals.ts | 14 +------- packages/backend/src/types.ts | 2 ++ plugins/devtools-backend/api-report.md | 3 ++ plugins/devtools-backend/package.json | 1 + .../devtools-backend/src/service/router.ts | 14 +++++++- .../Content/InfoContent/InfoContent.tsx | 36 +++++++++---------- plugins/signals-backend/api-report.md | 4 +-- .../src/service/router.test.ts | 4 +-- plugins/signals-backend/src/service/router.ts | 4 +-- .../src/service/standaloneServer.ts | 4 +-- plugins/signals-node/api-report.md | 9 ++--- .../{SignalsService.ts => SignalService.ts} | 23 +++++++++--- plugins/signals-node/src/index.ts | 2 +- plugins/signals-node/src/types.ts | 2 +- plugins/signals-react/api-report.md | 6 ++-- .../src/api/{SignalsApi.ts => SignalApi.ts} | 6 ++-- plugins/signals-react/src/api/index.ts | 2 +- plugins/signals-react/src/hooks/index.ts | 2 +- .../{useSignalsApi.ts => useSignalApi.ts} | 6 ++-- plugins/signals/api-report.md | 6 ++-- .../api/{SignalsClient.ts => SignalClient.ts} | 13 +++---- plugins/signals/src/api/SignalsClient.test.ts | 10 +++--- plugins/signals/src/api/index.ts | 2 +- plugins/signals/src/plugin.ts | 8 ++--- yarn.lock | 1 + 28 files changed, 114 insertions(+), 84 deletions(-) create mode 100644 .changeset/poor-sheep-tease.md rename plugins/signals-node/src/{SignalsService.ts => SignalService.ts} (90%) rename plugins/signals-react/src/api/{SignalsApi.ts => SignalApi.ts} (88%) rename plugins/signals-react/src/hooks/{useSignalsApi.ts => useSignalApi.ts} (91%) rename plugins/signals/src/api/{SignalsClient.ts => SignalClient.ts} (94%) diff --git a/.changeset/poor-sheep-tease.md b/.changeset/poor-sheep-tease.md new file mode 100644 index 0000000000..fa89ac4749 --- /dev/null +++ b/.changeset/poor-sheep-tease.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-devtools-backend': patch +'@backstage/plugin-devtools': patch +--- + +Update devtools information almost real time using signals plugin diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index cefc272aa7..fc6b814c00 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -73,6 +73,7 @@ import { DefaultEventBroker } from '@backstage/plugin-events-backend'; import { PrometheusExporter } from '@opentelemetry/exporter-prometheus'; import { MeterProvider } from '@opentelemetry/sdk-metrics'; import { metrics } from '@opentelemetry/api'; +import { SignalService } from '@backstage/plugin-signals-node'; // Expose opentelemetry metrics using a Prometheus exporter on // http://localhost:9464/metrics . See prometheus.yml in packages/backend for @@ -99,6 +100,11 @@ function makeCreateEnv(config: Config) { }); const eventBroker = new DefaultEventBroker(root.child({ type: 'plugin' })); + const signalService = SignalService.create({ + logger: root, + eventBroker, + identity, + }); root.info(`Created UrlReader ${reader}`); @@ -120,6 +126,7 @@ function makeCreateEnv(config: Config) { permissions, scheduler, identity, + signalService, }; }; } diff --git a/packages/backend/src/plugins/devtools.ts b/packages/backend/src/plugins/devtools.ts index 8e1767ddb1..5488033682 100644 --- a/packages/backend/src/plugins/devtools.ts +++ b/packages/backend/src/plugins/devtools.ts @@ -25,5 +25,6 @@ export default async function createPlugin( logger: env.logger, config: env.config, permissions: env.permissions, + signalService: env.signalService, }); } diff --git a/packages/backend/src/plugins/signals.ts b/packages/backend/src/plugins/signals.ts index dae2731c52..687fcfaa33 100644 --- a/packages/backend/src/plugins/signals.ts +++ b/packages/backend/src/plugins/signals.ts @@ -15,25 +15,13 @@ */ import { Router } from 'express'; import { createRouter } from '@backstage/plugin-signals-backend'; -import { SignalsService } from '@backstage/plugin-signals-node'; import { PluginEnvironment } from '../types'; export default async function createPlugin( env: PluginEnvironment, ): Promise { - const service = SignalsService.create({ - logger: env.logger, - identity: env.identity, - eventBroker: env.eventBroker, - }); - - setInterval(() => { - console.log('publishing'); - service.publish('*', 'devtools:info', { now: new Date().toISOString() }); - }, 5000); - return await createRouter({ logger: env.logger, - service, + service: env.signalService, }); } diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts index ab1baf0c95..d76e68c1c9 100644 --- a/packages/backend/src/types.ts +++ b/packages/backend/src/types.ts @@ -27,6 +27,7 @@ import { PluginTaskScheduler } from '@backstage/backend-tasks'; import { IdentityApi } from '@backstage/plugin-auth-node'; import { PermissionEvaluator } from '@backstage/plugin-permission-common'; import { EventBroker } from '@backstage/plugin-events-node'; +import { SignalService } from '@backstage/plugin-signals-node'; export type PluginEnvironment = { logger: Logger; @@ -40,4 +41,5 @@ export type PluginEnvironment = { scheduler: PluginTaskScheduler; identity: IdentityApi; eventBroker: EventBroker; + signalService: SignalService; }; diff --git a/plugins/devtools-backend/api-report.md b/plugins/devtools-backend/api-report.md index b9eb7b5a0c..85b2bf6efa 100644 --- a/plugins/devtools-backend/api-report.md +++ b/plugins/devtools-backend/api-report.md @@ -11,6 +11,7 @@ import express from 'express'; import { ExternalDependency } from '@backstage/plugin-devtools-common'; import { Logger } from 'winston'; import { PermissionEvaluator } from '@backstage/plugin-permission-common'; +import { SignalService } from '@backstage/plugin-signals-node'; // @public (undocumented) export function createRouter(options: RouterOptions): Promise; @@ -40,5 +41,7 @@ export interface RouterOptions { logger: Logger; // (undocumented) permissions: PermissionEvaluator; + // (undocumented) + signalService?: SignalService; } ``` diff --git a/plugins/devtools-backend/package.json b/plugins/devtools-backend/package.json index 18013bc52f..8de7da1b39 100644 --- a/plugins/devtools-backend/package.json +++ b/plugins/devtools-backend/package.json @@ -38,6 +38,7 @@ "@backstage/plugin-devtools-common": "workspace:^", "@backstage/plugin-permission-common": "workspace:^", "@backstage/plugin-permission-node": "workspace:^", + "@backstage/plugin-signals-node": "workspace:^", "@backstage/types": "workspace:^", "@manypkg/get-packages": "^1.1.3", "@types/express": "*", diff --git a/plugins/devtools-backend/src/service/router.ts b/plugins/devtools-backend/src/service/router.ts index fbeeb5af84..fb8b106337 100644 --- a/plugins/devtools-backend/src/service/router.ts +++ b/plugins/devtools-backend/src/service/router.ts @@ -33,6 +33,7 @@ import { errorHandler } from '@backstage/backend-common'; import express from 'express'; import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; import { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node'; +import { SignalService } from '@backstage/plugin-signals-node'; /** @public */ export interface RouterOptions { @@ -40,17 +41,28 @@ export interface RouterOptions { logger: Logger; config: Config; permissions: PermissionEvaluator; + signalService?: SignalService; } /** @public */ export async function createRouter( options: RouterOptions, ): Promise { - const { logger, config, permissions } = options; + const { logger, config, permissions, signalService } = options; const devToolsBackendApi = options.devToolsBackendApi || new DevToolsBackendApi(logger, config); + if (signalService) { + // Publish info periodically using the signal service + setInterval(async () => { + if (signalService.hasSubscribers('devtools:info')) { + const info = await devToolsBackendApi.listInfo(); + await signalService.publish('*', 'devtools:info', info); + } + }, 5000); + } + const router = Router(); router.use(express.json()); router.use( diff --git a/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx b/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx index adca500fad..74587d3e57 100644 --- a/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx +++ b/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx @@ -27,10 +27,9 @@ import { makeStyles, Paper, Theme, - Typography, } from '@material-ui/core'; import { Alert } from '@material-ui/lab'; -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { useInfo } from '../../../hooks'; import { InfoDependenciesTable } from './InfoDependenciesTable'; import DescriptionIcon from '@material-ui/icons/Description'; @@ -39,7 +38,7 @@ import DeveloperBoardIcon from '@material-ui/icons/DeveloperBoard'; import { BackstageLogoIcon } from './BackstageLogoIcon'; import FileCopyIcon from '@material-ui/icons/FileCopy'; import { DevToolsInfo } from '@backstage/plugin-devtools-common'; -import { useSignalsApi } from '@backstage/plugin-signals-react'; +import { useSignalApi } from '@backstage/plugin-signals-react'; const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -74,14 +73,18 @@ const copyToClipboard = ({ about }: { about: DevToolsInfo | undefined }) => { /** @public */ export const InfoContent = () => { const classes = useStyles(); + const [info, setInfo] = useState(undefined); const { about, loading, error } = useInfo(); - // Just testing for signals - const [messages, setMessages] = React.useState([]); - useSignalsApi('devtools:info', message => { - messages.push(JSON.stringify(message)); - setMessages([...messages]); + useSignalApi('devtools:info', message => { + setInfo(message as DevToolsInfo); }); + useEffect(() => { + if (!loading && !error && about) { + setInfo(about); + } + }, [about, loading, error]); + if (loading) { return ; } else if (error) { @@ -89,11 +92,6 @@ export const InfoContent = () => { } return ( - - {messages.map((msg, i) => { - return {msg}; - })} - @@ -104,7 +102,7 @@ export const InfoContent = () => { @@ -115,7 +113,7 @@ export const InfoContent = () => { @@ -126,7 +124,7 @@ export const InfoContent = () => { @@ -137,14 +135,14 @@ export const InfoContent = () => { { - copyToClipboard({ about }); + copyToClipboard({ about: info }); }} className={classes.copyButton} > @@ -157,7 +155,7 @@ export const InfoContent = () => { - + ); }; diff --git a/plugins/signals-backend/api-report.md b/plugins/signals-backend/api-report.md index 0ea56c707a..309bd22ce3 100644 --- a/plugins/signals-backend/api-report.md +++ b/plugins/signals-backend/api-report.md @@ -5,7 +5,7 @@ ```ts import express from 'express'; import { Logger } from 'winston'; -import { SignalsService } from '@backstage/plugin-signals-node'; +import { SignalService } from '@backstage/plugin-signals-node'; // @public (undocumented) export function createRouter(options: RouterOptions): Promise; @@ -15,7 +15,7 @@ export interface RouterOptions { // (undocumented) logger: Logger; // (undocumented) - service: SignalsService; + service: SignalService; } // (No @packageDocumentation comment for this package) diff --git a/plugins/signals-backend/src/service/router.test.ts b/plugins/signals-backend/src/service/router.test.ts index d7091827f9..b41704e008 100644 --- a/plugins/signals-backend/src/service/router.test.ts +++ b/plugins/signals-backend/src/service/router.test.ts @@ -18,9 +18,9 @@ import express from 'express'; import request from 'supertest'; import { createRouter } from './router'; -import { SignalsService } from '@backstage/plugin-signals-node'; +import { SignalService } from '@backstage/plugin-signals-node'; -const signalsServiceMock: jest.Mocked = {} as any; +const signalsServiceMock: jest.Mocked = {} as any; describe('createRouter', () => { let app: express.Express; diff --git a/plugins/signals-backend/src/service/router.ts b/plugins/signals-backend/src/service/router.ts index 0027acef30..c47517e06c 100644 --- a/plugins/signals-backend/src/service/router.ts +++ b/plugins/signals-backend/src/service/router.ts @@ -17,12 +17,12 @@ import { errorHandler } from '@backstage/backend-common'; import express from 'express'; import Router from 'express-promise-router'; import { Logger } from 'winston'; -import { SignalsService } from '@backstage/plugin-signals-node'; +import { SignalService } from '@backstage/plugin-signals-node'; /** @public */ export interface RouterOptions { logger: Logger; - service: SignalsService; + service: SignalService; } /** @public */ diff --git a/plugins/signals-backend/src/service/standaloneServer.ts b/plugins/signals-backend/src/service/standaloneServer.ts index c13d718734..0728b2fde5 100644 --- a/plugins/signals-backend/src/service/standaloneServer.ts +++ b/plugins/signals-backend/src/service/standaloneServer.ts @@ -21,7 +21,7 @@ import { import { Server } from 'http'; import { Logger } from 'winston'; import { createRouter } from './router'; -import { SignalsService } from '@backstage/plugin-signals-node'; +import { SignalService } from '@backstage/plugin-signals-node'; import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; export interface ServerOptions { @@ -43,7 +43,7 @@ export async function startStandaloneServer( issuer: await discovery.getExternalBaseUrl('auth'), }); - const signals = SignalsService.create({ + const signals = SignalService.create({ logger: logger, identity, }); diff --git a/plugins/signals-node/api-report.md b/plugins/signals-node/api-report.md index 15a6f67d87..5c9f2fad54 100644 --- a/plugins/signals-node/api-report.md +++ b/plugins/signals-node/api-report.md @@ -19,19 +19,20 @@ export type ServiceOptions = { }; // @public (undocumented) -export type SignalsEventBrokerPayload = { +export type SignalEventBrokerPayload = { recipients?: string[]; topic?: string; message?: JsonObject; }; // @public (undocumented) -export class SignalsService implements EventSubscriber { +export class SignalService implements EventSubscriber { // (undocumented) - static create(options: ServiceOptions): SignalsService; + static create(options: ServiceOptions): SignalService; handleUpgrade: (req: Request_2) => Promise; + hasSubscribers(topic: string): boolean; // (undocumented) - onEvent(params: EventParams): Promise; + onEvent(params: EventParams): Promise; publish( to: string | string[], topic: string, diff --git a/plugins/signals-node/src/SignalsService.ts b/plugins/signals-node/src/SignalService.ts similarity index 90% rename from plugins/signals-node/src/SignalsService.ts rename to plugins/signals-node/src/SignalService.ts index c743c958dd..4846fe7b6f 100644 --- a/plugins/signals-node/src/SignalsService.ts +++ b/plugins/signals-node/src/SignalService.ts @@ -22,7 +22,7 @@ import { Logger } from 'winston'; import { ServiceOptions, SignalConnection, - SignalsEventBrokerPayload, + SignalEventBrokerPayload, } from './types'; import { RawData, WebSocket, WebSocketServer } from 'ws'; import { IncomingMessage } from 'http'; @@ -36,7 +36,7 @@ import { } from '@backstage/plugin-auth-node'; /** @public */ -export class SignalsService implements EventSubscriber { +export class SignalService implements EventSubscriber { private readonly serverId: string; private connections: Map = new Map< string, @@ -48,7 +48,7 @@ export class SignalsService implements EventSubscriber { private server: WebSocketServer; static create(options: ServiceOptions) { - return new SignalsService(options); + return new SignalService(options); } private constructor(options: ServiceOptions) { @@ -75,7 +75,7 @@ export class SignalsService implements EventSubscriber { } /** - * Handles request upgradce to websocket and adds the connection to internal + * Handles request upgrade to websocket and adds the connection to internal * list for publish/subscribe functionality * @param req - Request */ @@ -184,6 +184,19 @@ export class SignalsService implements EventSubscriber { ); } + /** + * Checks if there is active subscriptions to specific topic. + * This can be useful to skip heavy processing before publishing messages if there are no subscriptions. + * @param topic - topic to check for subscriptions + */ + hasSubscribers(topic: string): boolean { + return ( + [...this.connections.values()].find(conn => + conn.subscriptions.has(topic), + ) !== undefined + ); + } + private async publishInternal( recipients: string[], topic: string, @@ -229,7 +242,7 @@ export class SignalsService implements EventSubscriber { } } - async onEvent(params: EventParams): Promise { + async onEvent(params: EventParams): Promise { const { eventPayload, metadata } = params; // Discard message from same server to prevent duplicate messages if (!metadata?.server || metadata.server === this.serverId) { diff --git a/plugins/signals-node/src/index.ts b/plugins/signals-node/src/index.ts index 5427711cbe..289efade07 100644 --- a/plugins/signals-node/src/index.ts +++ b/plugins/signals-node/src/index.ts @@ -14,5 +14,5 @@ * limitations under the License. */ -export * from './SignalsService'; +export * from './SignalService'; export * from './types'; diff --git a/plugins/signals-node/src/types.ts b/plugins/signals-node/src/types.ts index 090e4b2ff1..99821f641d 100644 --- a/plugins/signals-node/src/types.ts +++ b/plugins/signals-node/src/types.ts @@ -29,7 +29,7 @@ export type ServiceOptions = { }; /** @public */ -export type SignalsEventBrokerPayload = { +export type SignalEventBrokerPayload = { recipients?: string[]; topic?: string; message?: JsonObject; diff --git a/plugins/signals-react/api-report.md b/plugins/signals-react/api-report.md index 21f070c35d..d28b806103 100644 --- a/plugins/signals-react/api-report.md +++ b/plugins/signals-react/api-report.md @@ -7,16 +7,16 @@ import { ApiRef } from '@backstage/core-plugin-api'; import { JsonObject } from '@backstage/types'; // @public (undocumented) -export type SignalsApi = { +export type SignalApi = { subscribe(topic: string, onMessage: (message: JsonObject) => void): string; unsubscribe(subscription: string): void; }; // @public (undocumented) -export const signalsApiRef: ApiRef; +export const signalApiRef: ApiRef; // @public (undocumented) -export const useSignalsApi: ( +export const useSignalApi: ( topic: string, onMessage: (message: JsonObject) => void, ) => void; diff --git a/plugins/signals-react/src/api/SignalsApi.ts b/plugins/signals-react/src/api/SignalApi.ts similarity index 88% rename from plugins/signals-react/src/api/SignalsApi.ts rename to plugins/signals-react/src/api/SignalApi.ts index 2aefa5d166..f63023bf5f 100644 --- a/plugins/signals-react/src/api/SignalsApi.ts +++ b/plugins/signals-react/src/api/SignalApi.ts @@ -17,12 +17,12 @@ import { createApiRef } from '@backstage/core-plugin-api'; import { JsonObject } from '@backstage/types'; /** @public */ -export const signalsApiRef = createApiRef({ - id: 'plugin.signals.service', +export const signalApiRef = createApiRef({ + id: 'plugin.signal.service', }); /** @public */ -export type SignalsApi = { +export type SignalApi = { subscribe(topic: string, onMessage: (message: JsonObject) => void): string; unsubscribe(subscription: string): void; diff --git a/plugins/signals-react/src/api/index.ts b/plugins/signals-react/src/api/index.ts index 9d5c4c5656..8d728dbd0f 100644 --- a/plugins/signals-react/src/api/index.ts +++ b/plugins/signals-react/src/api/index.ts @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export * from './SignalsApi'; +export * from './SignalApi'; diff --git a/plugins/signals-react/src/hooks/index.ts b/plugins/signals-react/src/hooks/index.ts index 0d5967f9eb..921eca8d30 100644 --- a/plugins/signals-react/src/hooks/index.ts +++ b/plugins/signals-react/src/hooks/index.ts @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export * from './useSignalsApi'; +export * from './useSignalApi'; diff --git a/plugins/signals-react/src/hooks/useSignalsApi.ts b/plugins/signals-react/src/hooks/useSignalApi.ts similarity index 91% rename from plugins/signals-react/src/hooks/useSignalsApi.ts rename to plugins/signals-react/src/hooks/useSignalApi.ts index 0fcc69efed..bb6f47a5fe 100644 --- a/plugins/signals-react/src/hooks/useSignalsApi.ts +++ b/plugins/signals-react/src/hooks/useSignalApi.ts @@ -13,17 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { signalsApiRef } from '../api'; +import { signalApiRef } from '../api'; import { useApi } from '@backstage/core-plugin-api'; import { JsonObject } from '@backstage/types'; import { useEffect, useState } from 'react'; /** @public */ -export const useSignalsApi = ( +export const useSignalApi = ( topic: string, onMessage: (message: JsonObject) => void, ) => { - const signals = useApi(signalsApiRef); + const signals = useApi(signalApiRef); const [subscription, setSubscription] = useState(null); useEffect(() => { if (!subscription) { diff --git a/plugins/signals/api-report.md b/plugins/signals/api-report.md index 08c52ef418..28a70a339c 100644 --- a/plugins/signals/api-report.md +++ b/plugins/signals/api-report.md @@ -7,17 +7,17 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; import { DiscoveryApi } from '@backstage/core-plugin-api'; import { IdentityApi } from '@backstage/core-plugin-api'; import { JsonObject } from '@backstage/types'; -import { SignalsApi } from '@backstage/plugin-signals-react'; +import { SignalApi } from '@backstage/plugin-signals-react'; // @public (undocumented) -export class SignalsClient implements SignalsApi { +export class SignalClient implements SignalApi { // (undocumented) static create(options: { identity: IdentityApi; discoveryApi: DiscoveryApi; connectTimeout?: number; reconnectTimeout?: number; - }): SignalsClient; + }): SignalClient; // (undocumented) static readonly DEFAULT_CONNECT_TIMEOUT_MS: number; // (undocumented) diff --git a/plugins/signals/src/api/SignalsClient.ts b/plugins/signals/src/api/SignalClient.ts similarity index 94% rename from plugins/signals/src/api/SignalsClient.ts rename to plugins/signals/src/api/SignalClient.ts index 4051468a9e..64c1866fab 100644 --- a/plugins/signals/src/api/SignalsClient.ts +++ b/plugins/signals/src/api/SignalClient.ts @@ -13,24 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { SignalsApi } from '@backstage/plugin-signals-react'; +import { SignalApi } from '@backstage/plugin-signals-react'; import { JsonObject } from '@backstage/types'; import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; import { v4 as uuid } from 'uuid'; -/** @internal */ type Subscription = { topic: string; callback: (message: JsonObject) => void; }; -/** @internal */ const WS_CLOSE_NORMAL = 1000; -/** @internal */ const WS_CLOSE_GOING_AWAY = 1001; /** @public */ -export class SignalsClient implements SignalsApi { +export class SignalClient implements SignalApi { static readonly DEFAULT_CONNECT_TIMEOUT_MS: number = 1000; static readonly DEFAULT_RECONNECT_TIMEOUT_MS: number = 5000; private ws: WebSocket | null = null; @@ -47,10 +44,10 @@ export class SignalsClient implements SignalsApi { const { identity, discoveryApi, - connectTimeout = SignalsClient.DEFAULT_CONNECT_TIMEOUT_MS, - reconnectTimeout = SignalsClient.DEFAULT_RECONNECT_TIMEOUT_MS, + connectTimeout = SignalClient.DEFAULT_CONNECT_TIMEOUT_MS, + reconnectTimeout = SignalClient.DEFAULT_RECONNECT_TIMEOUT_MS, } = options; - return new SignalsClient( + return new SignalClient( identity, discoveryApi, connectTimeout, diff --git a/plugins/signals/src/api/SignalsClient.test.ts b/plugins/signals/src/api/SignalsClient.test.ts index 03b25d580d..60d67e6c4b 100644 --- a/plugins/signals/src/api/SignalsClient.test.ts +++ b/plugins/signals/src/api/SignalsClient.test.ts @@ -16,7 +16,7 @@ import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; import WS from 'jest-websocket-mock'; -import { SignalsClient } from './SignalsClient'; +import { SignalClient } from './SignalClient'; describe('SignalsClient', () => { const tokenFunction = jest.fn(); @@ -43,7 +43,7 @@ describe('SignalsClient', () => { it('should handle single subscription correctly', async () => { const messageMock = jest.fn(); - const client = SignalsClient.create({ discoveryApi, identity }); + const client = SignalClient.create({ discoveryApi, identity }); const sub = client.subscribe('topic', messageMock); await server.connected; @@ -64,8 +64,8 @@ describe('SignalsClient', () => { it('should handle multiple subscription correctly', async () => { const messageMock1 = jest.fn(); const messageMock2 = jest.fn(); - const client1 = SignalsClient.create({ discoveryApi, identity }); - const client2 = SignalsClient.create({ discoveryApi, identity }); + const client1 = SignalClient.create({ discoveryApi, identity }); + const client2 = SignalClient.create({ discoveryApi, identity }); const sub1 = client1.subscribe('topic', messageMock1); const sub2 = client2.subscribe('topic', messageMock2); @@ -94,7 +94,7 @@ describe('SignalsClient', () => { it('should reconnect on error', async () => { const messageMock = jest.fn(); - const client = SignalsClient.create({ + const client = SignalClient.create({ discoveryApi, identity, reconnectTimeout: 10, diff --git a/plugins/signals/src/api/index.ts b/plugins/signals/src/api/index.ts index 80e69259af..c76ae196ed 100644 --- a/plugins/signals/src/api/index.ts +++ b/plugins/signals/src/api/index.ts @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export * from './SignalsClient'; +export * from './SignalClient'; diff --git a/plugins/signals/src/plugin.ts b/plugins/signals/src/plugin.ts index d1b0311116..946e9aaa71 100644 --- a/plugins/signals/src/plugin.ts +++ b/plugins/signals/src/plugin.ts @@ -19,21 +19,21 @@ import { discoveryApiRef, identityApiRef, } from '@backstage/core-plugin-api'; -import { signalsApiRef } from '@backstage/plugin-signals-react'; -import { SignalsClient } from './api/SignalsClient'; +import { signalApiRef } from '@backstage/plugin-signals-react'; +import { SignalClient } from './api/SignalClient'; /** @public */ export const signalsPlugin = createPlugin({ id: 'signals', apis: [ createApiFactory({ - api: signalsApiRef, + api: signalApiRef, deps: { identity: identityApiRef, discoveryApi: discoveryApiRef, }, factory: ({ identity, discoveryApi }) => - SignalsClient.create({ + SignalClient.create({ identity, discoveryApi, }), diff --git a/yarn.lock b/yarn.lock index d44cfeab72..de28fd808d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6203,6 +6203,7 @@ __metadata: "@backstage/plugin-devtools-common": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" "@backstage/plugin-permission-node": "workspace:^" + "@backstage/plugin-signals-node": "workspace:^" "@backstage/types": "workspace:^" "@manypkg/get-packages": ^1.1.3 "@types/express": "*" From a219469cf33391312dc26a23291c782f3bd1e5ab Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Tue, 5 Dec 2023 16:03:41 +0200 Subject: [PATCH 028/283] docs: add signals plugin docs Signed-off-by: Heikki Hellgren --- plugins/signals-backend/README.md | 13 ++---- plugins/signals-node/README.md | 67 ++++++++++++++++++++++++++++++- plugins/signals-react/README.md | 44 +++++++++++++++++++- plugins/signals/README.md | 38 +++++++++++++++--- 4 files changed, 146 insertions(+), 16 deletions(-) diff --git a/plugins/signals-backend/README.md b/plugins/signals-backend/README.md index d194b852f2..1f58c1195a 100644 --- a/plugins/signals-backend/README.md +++ b/plugins/signals-backend/README.md @@ -6,26 +6,21 @@ Signals plugin allows backend plugins to publish messages to frontend plugins. ## Getting started -Add Signals router to your backend in `packages/backend/src/plugins/signals.ts`: +First install the `@backstage/plugin-signals-node` plugin to get the `SignalService` set up. + +Next, add Signals router to your backend in `packages/backend/src/plugins/signals.ts`: ```ts import { Router } from 'express'; import { createRouter } from '@backstage/plugin-signals-backend'; -import { SignalsService } from '@backstage/plugin-signals-node'; import { PluginEnvironment } from '../types'; export default async function createPlugin( env: PluginEnvironment, ): Promise { - const service = SignalsService.create({ - logger: env.logger, - identity: env.identity, - eventBroker: env.eventBroker, - }); - return await createRouter({ logger: env.logger, - service, + service: env.signalsService, }); } ``` diff --git a/plugins/signals-node/README.md b/plugins/signals-node/README.md index 55d766f9e0..abea6c6d22 100644 --- a/plugins/signals-node/README.md +++ b/plugins/signals-node/README.md @@ -2,4 +2,69 @@ Welcome to the Node.js library package for the signals plugin! -_This plugin was created through the Backstage CLI_ +Signals plugin allows backend plugins to publish messages to frontend plugins. + +## Getting started + +Add SignalService to your plugin environment in `packages/backend/src/types.ts`: + +```ts +import { SignalService } from '@backstage/plugin-signals-node'; + +export type PluginEnvironment = { + // ... + signalService: SignalService; +}; +``` + +Add it also to your `makeCreateEnv` to allow access from the other plugins: + +```ts +import { SignalService } from '@backstage/plugin-signals-node'; +import { DefaultEventBroker } from '@backstage/plugin-events-backend'; + +function makeCreateEnv(config: Config) { + // ... + + const eventBroker = new DefaultEventBroker(root.child({ type: 'plugin' })); + const signalService = SignalService.create({ + logger: root, + eventBroker, // EventBroker is optional + identity, + }); + + return (plugin: string): PluginEnvironment => { + const logger = root.child({ type: 'plugin', plugin }); + return { + logger, + eventBroker, + signalService, + // ... + }; + }; +} +``` + +To allow connections from the frontend, you should also install the `@backstage/plugin-signals-backend`. + +## Using the service + +Once you have both of the backend plugins installed, you can utilize the signal service by calling the +`publish` method. This will publish the message to all subscribers in the frontend. To send message to +all subscribers, you can use `*` as `to` parameter. + +```ts +// Periodic sending example +setInterval(async () => { + // You can use hasSubscribers to check if the message will be sent to anyone + // in case you need some heavy processing before that + if (signalService.hasSubscribers('plugin:topic')) { + await signalService.publish('*', 'plugin:topic', { + message: 'hello world', + }); + } +}, 5000); +``` + +To receive this message in the frontend, check the documentation of `@backstage/plugin-signals` and +`@backstage/plugin-signals-react`. diff --git a/plugins/signals-react/README.md b/plugins/signals-react/README.md index 4b6b4e00bc..9bdf5e964f 100644 --- a/plugins/signals-react/README.md +++ b/plugins/signals-react/README.md @@ -2,4 +2,46 @@ Welcome to the web library package for the signals plugin! -_This plugin was created through the Backstage CLI_ +Signals plugin allows backend plugins to publish messages to frontend plugins. + +## Getting started + +This plugin contains functionalities that help utilize the signals plugin. To get started, +see installation instructions from `@backstage/plugin-signals-node`, `@backstage/plugin-signals-backend`, and +`@backstage/plugin-signals`. + +There are two ways to utilize the signals plugin; either by using the hook or by directly using the API. + +## Using the hook + +By using the hook, unsubscribe is automatically taken care of. This helps to maintain only necessary amount +of connections to the backend and also to allow multiple subscriptions using the same connection. + +Example of using the hook: + +```ts +import { useSignalApi } from '@backstage/plugin-signals-react'; + +const [message, setMessage] = useState(undefined); +useSignalApi('myplugin:topic', message => { + setMessage(message); +}); +``` + +Whenever backend publishes new message to the topic `myplugin:topic`, the state of this component is changed. + +## Using API directly + +You can also use the signal API directly. This allows more fine-grained control over the state of the connections and +subscriptions. + +```ts +import { signalsApiRef } from '@backstage/plugin-signals-react'; + +const signals = useApi(signalsApiRef); +signals.subscribe('myplugin:topic', (message: JsonObject) => { + console.log(message); +}); +// Remember to unsubscribe +signals.unsubscribe('myplugin:topic'); +``` diff --git a/plugins/signals/README.md b/plugins/signals/README.md index 604fa98a33..e70c1ef7d8 100644 --- a/plugins/signals/README.md +++ b/plugins/signals/README.md @@ -2,12 +2,40 @@ Welcome to the signals plugin! -_This plugin was created through the Backstage CLI_ +Signals plugin allows backend plugins to publish messages to frontend plugins. ## Getting started -Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/signals](http://localhost:3000/signals). +This plugin contains client that can receive messages from the backend. To get started, +see installation instructions from `@backstage/plugin-signals-node`, `@backstage/plugin-signals-backend`. -You can also serve the plugin in isolation by running `yarn start` in the plugin directory. -This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads. -It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory. +To install the plugin, you have to add the following to your `packages/app/src/plugins.ts`: + +```ts +export { signalsPlugin } from '@backstage/plugin-signals'; +``` + +And make sure that your `packages/app/src/App.tsx` contains: + +```ts +import * as plugins from './plugins'; + +const app = createApp({ + // ... + plugins: Object.values(plugins), + // ... +}); +``` + +Now you can utilize the API from other plugins using the `@backstage/plugin-signals-react` package or simply by: + +```ts +import { signalsApiRef } from '@backstage/plugin-signals-react'; + +const signals = useApi(signalsApiRef); +signals.subscribe('myplugin:topic', (message: JsonObject) => { + console.log(message); +}); +// Remember to unsubscribe +signals.unsubscribe('myplugin:topic'); +``` From 6a730a43104dff559ca1535957edf2c80c60dcaa Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Fri, 8 Dec 2023 14:28:22 +0200 Subject: [PATCH 029/283] fix: handle upgrade properly in signal router Signed-off-by: Heikki Hellgren --- plugins/devtools-backend/api-report.md | 2 ++ .../src/api/DevToolsBackendApi.ts | 16 +++++---- .../devtools-backend/src/service/router.ts | 8 +++-- .../Content/InfoContent/InfoContent.tsx | 20 +++++------ plugins/signals-backend/src/service/router.ts | 35 +++++++++++++------ plugins/signals-node/api-report.md | 11 ++++-- plugins/signals-node/src/SignalService.ts | 27 +++++--------- 7 files changed, 69 insertions(+), 50 deletions(-) diff --git a/plugins/devtools-backend/api-report.md b/plugins/devtools-backend/api-report.md index 85b2bf6efa..7049285c02 100644 --- a/plugins/devtools-backend/api-report.md +++ b/plugins/devtools-backend/api-report.md @@ -25,6 +25,8 @@ export class DevToolsBackendApi { listExternalDependencyDetails(): Promise; // (undocumented) listInfo(): Promise; + // (undocumented) + listResourceUtilization(): Promise; } // @public diff --git a/plugins/devtools-backend/src/api/DevToolsBackendApi.ts b/plugins/devtools-backend/src/api/DevToolsBackendApi.ts index b71edb3391..da9a1ca0dd 100644 --- a/plugins/devtools-backend/src/api/DevToolsBackendApi.ts +++ b/plugins/devtools-backend/src/api/DevToolsBackendApi.ts @@ -203,17 +203,21 @@ export class DevToolsBackendApi { return configInfo; } - public async listInfo(): Promise { - const operatingSystem = `${os.hostname()}: ${os.type} ${os.release} - ${ - os.platform - }/${os.arch}`; + public async listResourceUtilization(): Promise { const usedMem = Math.floor((os.totalmem() - os.freemem()) / (1024 * 1024)); - const resources = `Memory: ${usedMem}/${Math.floor( + return `Memory: ${usedMem}/${Math.floor( os.totalmem() / (1024 * 1024), )}MB - Load: ${os .loadavg() .map(v => v.toFixed(2)) .join('/')}`; + } + + public async listInfo(): Promise { + const operatingSystem = `${os.hostname()}: ${os.type} ${os.release} - ${ + os.platform + }/${os.arch}`; + const nodeJsVersion = process.version; /* eslint-disable-next-line no-restricted-syntax */ @@ -247,7 +251,7 @@ export class DevToolsBackendApi { const info: DevToolsInfo = { operatingSystem: operatingSystem ?? 'N/A', - resourceUtilization: resources ?? 'N/A', + resourceUtilization: (await this.listResourceUtilization()) ?? 'N/A', nodeJsVersion: nodeJsVersion ?? 'N/A', backstageVersion: backstageJson && backstageJson.version ? backstageJson.version : 'N/A', diff --git a/plugins/devtools-backend/src/service/router.ts b/plugins/devtools-backend/src/service/router.ts index fb8b106337..106eb44309 100644 --- a/plugins/devtools-backend/src/service/router.ts +++ b/plugins/devtools-backend/src/service/router.ts @@ -56,9 +56,11 @@ export async function createRouter( if (signalService) { // Publish info periodically using the signal service setInterval(async () => { - if (signalService.hasSubscribers('devtools:info')) { - const info = await devToolsBackendApi.listInfo(); - await signalService.publish('*', 'devtools:info', info); + if (signalService.hasSubscribers('devtools:resources')) { + const info = await devToolsBackendApi.listResourceUtilization(); + await signalService.publish('*', 'devtools:resources', { + resources: info, + }); } }, 5000); } diff --git a/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx b/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx index 74587d3e57..2480bf5233 100644 --- a/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx +++ b/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx @@ -73,15 +73,15 @@ const copyToClipboard = ({ about }: { about: DevToolsInfo | undefined }) => { /** @public */ export const InfoContent = () => { const classes = useStyles(); - const [info, setInfo] = useState(undefined); + const [resources, setResources] = useState(undefined); const { about, loading, error } = useInfo(); - useSignalApi('devtools:info', message => { - setInfo(message as DevToolsInfo); + useSignalApi('devtools:resources', message => { + setResources(message.resources as string); }); useEffect(() => { if (!loading && !error && about) { - setInfo(about); + setResources(about.resourceUtilization); } }, [about, loading, error]); @@ -102,7 +102,7 @@ export const InfoContent = () => { @@ -113,7 +113,7 @@ export const InfoContent = () => { @@ -124,7 +124,7 @@ export const InfoContent = () => { @@ -135,14 +135,14 @@ export const InfoContent = () => { { - copyToClipboard({ about: info }); + copyToClipboard({ about }); }} className={classes.copyButton} > @@ -155,7 +155,7 @@ export const InfoContent = () => { - + ); }; diff --git a/plugins/signals-backend/src/service/router.ts b/plugins/signals-backend/src/service/router.ts index c47517e06c..acffde19c7 100644 --- a/plugins/signals-backend/src/service/router.ts +++ b/plugins/signals-backend/src/service/router.ts @@ -14,10 +14,12 @@ * limitations under the License. */ import { errorHandler } from '@backstage/backend-common'; -import express from 'express'; +import express, { NextFunction, Request, Response } from 'express'; import Router from 'express-promise-router'; import { Logger } from 'winston'; import { SignalService } from '@backstage/plugin-signals-node'; +import * as https from 'https'; +import http from 'http'; /** @public */ export interface RouterOptions { @@ -30,17 +32,14 @@ export async function createRouter( options: RouterOptions, ): Promise { const { logger, service } = options; + let subscribed = false; - const router = Router(); - router.use(express.json()); - - router.get('/health', (_, response) => { - logger.info('PONG!'); - response.json({ status: 'ok' }); - }); - - router.get('/', async (req, _, next) => { + const upgradeMiddleware = (req: Request, _: Response, next: NextFunction) => { + const server: https.Server | http.Server = ( + (req.socket ?? req.connection) as any + )?.server; if ( + !server || !req.headers || req.headers.upgrade === undefined || req.headers.upgrade.toLowerCase() !== 'websocket' @@ -49,7 +48,21 @@ export async function createRouter( return; } - await service.handleUpgrade(req); + if (!subscribed) { + server.on('upgrade', async (request, socket, head) => { + await service.handleUpgrade(request, socket, head); + }); + subscribed = true; + } + }; + + const router = Router(); + router.use(express.json()); + router.use(upgradeMiddleware); + + router.get('/health', (_, response) => { + logger.info('PONG!'); + response.json({ status: 'ok' }); }); router.use(errorHandler()); diff --git a/plugins/signals-node/api-report.md b/plugins/signals-node/api-report.md index 5c9f2fad54..3ad4da11ee 100644 --- a/plugins/signals-node/api-report.md +++ b/plugins/signals-node/api-report.md @@ -3,13 +3,16 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +/// + +import { Duplex } from 'stream'; import { EventBroker } from '@backstage/plugin-events-node'; import { EventParams } from '@backstage/plugin-events-node'; import { EventSubscriber } from '@backstage/plugin-events-node'; import { IdentityApi } from '@backstage/plugin-auth-node'; +import { IncomingMessage } from 'http'; import { JsonObject } from '@backstage/types'; import { Logger } from 'winston'; -import { Request as Request_2 } from 'express'; // @public (undocumented) export type ServiceOptions = { @@ -29,7 +32,11 @@ export type SignalEventBrokerPayload = { export class SignalService implements EventSubscriber { // (undocumented) static create(options: ServiceOptions): SignalService; - handleUpgrade: (req: Request_2) => Promise; + handleUpgrade: ( + req: IncomingMessage, + socket: Duplex, + head: Buffer, + ) => Promise; hasSubscribers(topic: string): boolean; // (undocumented) onEvent(params: EventParams): Promise; diff --git a/plugins/signals-node/src/SignalService.ts b/plugins/signals-node/src/SignalService.ts index 4846fe7b6f..5ae7b63deb 100644 --- a/plugins/signals-node/src/SignalService.ts +++ b/plugins/signals-node/src/SignalService.ts @@ -27,13 +27,13 @@ import { import { RawData, WebSocket, WebSocketServer } from 'ws'; import { IncomingMessage } from 'http'; import { v4 as uuid } from 'uuid'; -import { Request } from 'express'; import { JsonObject } from '@backstage/types'; import { BackstageIdentityResponse, IdentityApi, IdentityApiGetIdentityRequest, } from '@backstage/plugin-auth-node'; +import { Duplex } from 'stream'; /** @public */ export class SignalService implements EventSubscriber { @@ -61,14 +61,7 @@ export class SignalService implements EventSubscriber { this.serverId = uuid(); this.server = new WebSocketServer({ noServer: true, - }); - - this.server.on('close', () => { - this.logger.info('Closing signals server'); - this.connections.forEach(conn => { - conn.ws.close(); - }); - this.connections = new Map(); + clientTracking: false, }); this.eventBroker?.subscribe(this); @@ -79,7 +72,11 @@ export class SignalService implements EventSubscriber { * list for publish/subscribe functionality * @param req - Request */ - handleUpgrade = async (req: Request) => { + handleUpgrade = async ( + req: IncomingMessage, + socket: Duplex, + head: Buffer, + ) => { let identity: BackstageIdentityResponse | undefined = undefined; // Authentication token is passed in Sec-WebSocket-Protocol header as there @@ -95,8 +92,8 @@ export class SignalService implements EventSubscriber { this.server.handleUpgrade( req, - req.socket, - Buffer.from(''), + socket, + head, (ws: WebSocket, __: IncomingMessage) => { this.addConnection(ws, identity); }, @@ -131,17 +128,11 @@ export class SignalService implements EventSubscriber { this.connections.delete(id); }); - ws.on('ping', () => { - this.logger.debug(`Ping from connection ${id}`); - ws.pong(); - }); - ws.on('message', (data: RawData, isBinary: boolean) => { this.logger.debug(`Received message from connection ${id}: ${data}`); if (isBinary) { return; } - try { const json = JSON.parse(data.toString()) as JsonObject; this.handleMessage(conn, json); From ec8c5fcb707164b6269d221beee09a321b023273 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Fri, 8 Dec 2023 14:38:34 +0200 Subject: [PATCH 030/283] fix: only allow one signal client instance at once Signed-off-by: Heikki Hellgren --- plugins/signals/src/plugin.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/plugins/signals/src/plugin.ts b/plugins/signals/src/plugin.ts index 946e9aaa71..1482d7dae1 100644 --- a/plugins/signals/src/plugin.ts +++ b/plugins/signals/src/plugin.ts @@ -22,6 +22,8 @@ import { import { signalApiRef } from '@backstage/plugin-signals-react'; import { SignalClient } from './api/SignalClient'; +let clientInstance: SignalClient | undefined = undefined; + /** @public */ export const signalsPlugin = createPlugin({ id: 'signals', @@ -32,11 +34,15 @@ export const signalsPlugin = createPlugin({ identity: identityApiRef, discoveryApi: discoveryApiRef, }, - factory: ({ identity, discoveryApi }) => - SignalClient.create({ - identity, - discoveryApi, - }), + factory: ({ identity, discoveryApi }) => { + if (!clientInstance) { + clientInstance = SignalClient.create({ + identity, + discoveryApi, + }); + } + return clientInstance; + }, }), ], }); From aaa4e910e29e9cdc30df26d988d7db54e29ff678 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Fri, 8 Dec 2023 14:53:46 +0200 Subject: [PATCH 031/283] deps: move express types to dev deps Signed-off-by: Heikki Hellgren --- plugins/signals-node/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/signals-node/package.json b/plugins/signals-node/package.json index 2dc17f5e54..66e4528678 100644 --- a/plugins/signals-node/package.json +++ b/plugins/signals-node/package.json @@ -22,7 +22,8 @@ "postpack": "backstage-cli package postpack" }, "devDependencies": { - "@backstage/cli": "workspace:^" + "@backstage/cli": "workspace:^", + "@types/express": "^4.17.21" }, "files": [ "dist" @@ -33,7 +34,6 @@ "@backstage/plugin-auth-node": "workspace:^", "@backstage/plugin-events-node": "workspace:^", "@backstage/types": "workspace:^", - "@types/express": "^4.17.21", "express": "^4.17.1", "uuid": "^8.0.0", "winston": "^3.2.1", From f3575bc34c2f53fb20362ca7e871dfd6c7cd0fcb Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Fri, 8 Dec 2023 15:33:42 +0200 Subject: [PATCH 032/283] fix: initial review finding fixes Signed-off-by: Heikki Hellgren --- plugins/devtools-backend/src/plugin.ts | 5 +- plugins/signals-backend/README.md | 18 +++++++ plugins/signals-backend/api-report.md | 5 ++ plugins/signals-backend/package.json | 1 + plugins/signals-backend/src/index.ts | 1 + plugins/signals-backend/src/plugin.ts | 48 +++++++++++++++++++ plugins/signals-backend/src/service/router.ts | 3 +- plugins/signals-node/api-report.md | 4 ++ plugins/signals-node/package.json | 1 + plugins/signals-node/src/index.ts | 1 + plugins/signals-node/src/lib.ts | 21 ++++++++ yarn.lock | 2 + 12 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 plugins/signals-backend/src/plugin.ts create mode 100644 plugins/signals-node/src/lib.ts diff --git a/plugins/devtools-backend/src/plugin.ts b/plugins/devtools-backend/src/plugin.ts index 685522557e..02c3831128 100644 --- a/plugins/devtools-backend/src/plugin.ts +++ b/plugins/devtools-backend/src/plugin.ts @@ -20,6 +20,7 @@ import { createBackendPlugin, } from '@backstage/backend-plugin-api'; import { createRouter } from './service/router'; +import { signalService } from '@backstage/plugin-signals-node'; /** * DevTools backend plugin @@ -35,13 +36,15 @@ export const devtoolsPlugin = createBackendPlugin({ logger: coreServices.logger, permissions: coreServices.permissions, httpRouter: coreServices.httpRouter, + signals: signalService, }, - async init({ config, logger, permissions, httpRouter }) { + async init({ config, logger, permissions, httpRouter, signals }) { httpRouter.use( await createRouter({ config, logger: loggerToWinstonLogger(logger), permissions, + signalService: signals, }), ); }, diff --git a/plugins/signals-backend/README.md b/plugins/signals-backend/README.md index 1f58c1195a..f9ebfb80c7 100644 --- a/plugins/signals-backend/README.md +++ b/plugins/signals-backend/README.md @@ -24,3 +24,21 @@ export default async function createPlugin( }); } ``` + +Now add the signals to `packages/backend/src/index.ts`: + +```ts +// ... +import signals from './plugins/sonarqube'; + +async function main() { + // ... + const signalsEnv = useHotMemoize(module, () => createEnv('signals')); + + const apiRouter = Router(); + // ... + apiRouter.use('/signals', await signals(signalsEnv)); + apiRouter.use(notFoundHandler()); + // ... +} +``` diff --git a/plugins/signals-backend/api-report.md b/plugins/signals-backend/api-report.md index 309bd22ce3..afbc63abf2 100644 --- a/plugins/signals-backend/api-report.md +++ b/plugins/signals-backend/api-report.md @@ -3,6 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; import express from 'express'; import { Logger } from 'winston'; import { SignalService } from '@backstage/plugin-signals-node'; @@ -18,5 +19,9 @@ export interface RouterOptions { service: SignalService; } +// @public +const signalsPlugin: () => BackendFeature; +export default signalsPlugin; + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/signals-backend/package.json b/plugins/signals-backend/package.json index ee303cdf3b..2fe6d86480 100644 --- a/plugins/signals-backend/package.json +++ b/plugins/signals-backend/package.json @@ -23,6 +23,7 @@ }, "dependencies": { "@backstage/backend-common": "workspace:^", + "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", "@backstage/plugin-events-node": "workspace:^", diff --git a/plugins/signals-backend/src/index.ts b/plugins/signals-backend/src/index.ts index d2e8d61bad..05e1f941b2 100644 --- a/plugins/signals-backend/src/index.ts +++ b/plugins/signals-backend/src/index.ts @@ -14,3 +14,4 @@ * limitations under the License. */ export * from './service/router'; +export { signalsPlugin as default } from './plugin'; diff --git a/plugins/signals-backend/src/plugin.ts b/plugins/signals-backend/src/plugin.ts new file mode 100644 index 0000000000..b4a0a3e095 --- /dev/null +++ b/plugins/signals-backend/src/plugin.ts @@ -0,0 +1,48 @@ +/* + * Copyright 2023 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 { loggerToWinstonLogger } from '@backstage/backend-common'; +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { createRouter } from './service/router'; +import { signalService } from '@backstage/plugin-signals-node'; + +/** + * Signals backend plugin + * + * @public + */ +export const signalsPlugin = createBackendPlugin({ + pluginId: 'devtools', + register(env) { + env.registerInit({ + deps: { + httpRouter: coreServices.httpRouter, + logger: coreServices.logger, + service: signalService, + }, + async init({ httpRouter, logger, service }) { + httpRouter.use( + await createRouter({ + logger: loggerToWinstonLogger(logger), + service, + }), + ); + }, + }); + }, +}); diff --git a/plugins/signals-backend/src/service/router.ts b/plugins/signals-backend/src/service/router.ts index acffde19c7..7b0cc02a1d 100644 --- a/plugins/signals-backend/src/service/router.ts +++ b/plugins/signals-backend/src/service/router.ts @@ -33,7 +33,6 @@ export async function createRouter( ): Promise { const { logger, service } = options; let subscribed = false; - const upgradeMiddleware = (req: Request, _: Response, next: NextFunction) => { const server: https.Server | http.Server = ( (req.socket ?? req.connection) as any @@ -49,10 +48,10 @@ export async function createRouter( } if (!subscribed) { + subscribed = true; server.on('upgrade', async (request, socket, head) => { await service.handleUpgrade(request, socket, head); }); - subscribed = true; } }; diff --git a/plugins/signals-node/api-report.md b/plugins/signals-node/api-report.md index 3ad4da11ee..750dd1774a 100644 --- a/plugins/signals-node/api-report.md +++ b/plugins/signals-node/api-report.md @@ -13,6 +13,7 @@ import { IdentityApi } from '@backstage/plugin-auth-node'; import { IncomingMessage } from 'http'; import { JsonObject } from '@backstage/types'; import { Logger } from 'winston'; +import { ServiceRef } from '@backstage/backend-plugin-api'; // @public (undocumented) export type ServiceOptions = { @@ -49,5 +50,8 @@ export class SignalService implements EventSubscriber { supportsEventTopics(): string[]; } +// @public (undocumented) +export const signalService: ServiceRef; + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/signals-node/package.json b/plugins/signals-node/package.json index 66e4528678..d5e980d857 100644 --- a/plugins/signals-node/package.json +++ b/plugins/signals-node/package.json @@ -30,6 +30,7 @@ ], "dependencies": { "@backstage/backend-common": "workspace:^", + "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", "@backstage/plugin-events-node": "workspace:^", diff --git a/plugins/signals-node/src/index.ts b/plugins/signals-node/src/index.ts index 289efade07..43a3a88ac0 100644 --- a/plugins/signals-node/src/index.ts +++ b/plugins/signals-node/src/index.ts @@ -14,5 +14,6 @@ * limitations under the License. */ +export * from './lib'; export * from './SignalService'; export * from './types'; diff --git a/plugins/signals-node/src/lib.ts b/plugins/signals-node/src/lib.ts new file mode 100644 index 0000000000..d303b4d3cc --- /dev/null +++ b/plugins/signals-node/src/lib.ts @@ -0,0 +1,21 @@ +/* + * Copyright 2023 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 { createServiceRef } from '@backstage/backend-plugin-api'; + +/** @public */ +export const signalService = createServiceRef< + import('./SignalService').SignalService +>({ id: 'signals.service', scope: 'plugin' }); diff --git a/yarn.lock b/yarn.lock index de28fd808d..7a3fbb3902 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8839,6 +8839,7 @@ __metadata: resolution: "@backstage/plugin-signals-backend@workspace:plugins/signals-backend" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" @@ -8865,6 +8866,7 @@ __metadata: resolution: "@backstage/plugin-signals-node@workspace:plugins/signals-node" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" From 5368d38e9d0dbfb03745db0de44277a9bae2a219 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Fri, 8 Dec 2023 15:50:41 +0200 Subject: [PATCH 033/283] fix: add check for request path to upgrade Signed-off-by: Heikki Hellgren --- plugins/signals-backend/src/service/router.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/signals-backend/src/service/router.ts b/plugins/signals-backend/src/service/router.ts index 7b0cc02a1d..8926910544 100644 --- a/plugins/signals-backend/src/service/router.ts +++ b/plugins/signals-backend/src/service/router.ts @@ -34,9 +34,7 @@ export async function createRouter( const { logger, service } = options; let subscribed = false; const upgradeMiddleware = (req: Request, _: Response, next: NextFunction) => { - const server: https.Server | http.Server = ( - (req.socket ?? req.connection) as any - )?.server; + const server: https.Server | http.Server = (req.socket as any)?.server; if ( !server || !req.headers || @@ -50,7 +48,10 @@ export async function createRouter( if (!subscribed) { subscribed = true; server.on('upgrade', async (request, socket, head) => { - await service.handleUpgrade(request, socket, head); + // Only upgrade if request to root of the signals plugin + if (request.url === '/api/signals') { + await service.handleUpgrade(request, socket, head); + } }); } }; From 3b6b645d93125a1a88dfe6edc973047f2f44353a Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Fri, 8 Dec 2023 16:42:16 +0200 Subject: [PATCH 034/283] feat: add service factory for signal service Signed-off-by: Heikki Hellgren --- plugins/signals-backend/src/plugin.ts | 2 +- plugins/signals-node/api-report.md | 4 ++-- plugins/signals-node/src/SignalService.ts | 4 ++-- plugins/signals-node/src/lib.ts | 26 +++++++++++++++++++---- plugins/signals-node/src/types.ts | 4 ++-- 5 files changed, 29 insertions(+), 11 deletions(-) diff --git a/plugins/signals-backend/src/plugin.ts b/plugins/signals-backend/src/plugin.ts index b4a0a3e095..8ade4e85b5 100644 --- a/plugins/signals-backend/src/plugin.ts +++ b/plugins/signals-backend/src/plugin.ts @@ -27,7 +27,7 @@ import { signalService } from '@backstage/plugin-signals-node'; * @public */ export const signalsPlugin = createBackendPlugin({ - pluginId: 'devtools', + pluginId: 'signals', register(env) { env.registerInit({ deps: { diff --git a/plugins/signals-node/api-report.md b/plugins/signals-node/api-report.md index 750dd1774a..7bfffc2540 100644 --- a/plugins/signals-node/api-report.md +++ b/plugins/signals-node/api-report.md @@ -12,13 +12,13 @@ import { EventSubscriber } from '@backstage/plugin-events-node'; import { IdentityApi } from '@backstage/plugin-auth-node'; import { IncomingMessage } from 'http'; import { JsonObject } from '@backstage/types'; -import { Logger } from 'winston'; +import { LoggerService } from '@backstage/backend-plugin-api'; import { ServiceRef } from '@backstage/backend-plugin-api'; // @public (undocumented) export type ServiceOptions = { eventBroker?: EventBroker; - logger: Logger; + logger: LoggerService; identity: IdentityApi; }; diff --git a/plugins/signals-node/src/SignalService.ts b/plugins/signals-node/src/SignalService.ts index 5ae7b63deb..54f09f583a 100644 --- a/plugins/signals-node/src/SignalService.ts +++ b/plugins/signals-node/src/SignalService.ts @@ -18,7 +18,6 @@ import { EventParams, EventSubscriber, } from '@backstage/plugin-events-node'; -import { Logger } from 'winston'; import { ServiceOptions, SignalConnection, @@ -34,6 +33,7 @@ import { IdentityApiGetIdentityRequest, } from '@backstage/plugin-auth-node'; import { Duplex } from 'stream'; +import { LoggerService } from '@backstage/backend-plugin-api'; /** @public */ export class SignalService implements EventSubscriber { @@ -43,7 +43,7 @@ export class SignalService implements EventSubscriber { SignalConnection >(); private eventBroker?: EventBroker; - private logger: Logger; + private logger: LoggerService; private identity: IdentityApi; private server: WebSocketServer; diff --git a/plugins/signals-node/src/lib.ts b/plugins/signals-node/src/lib.ts index d303b4d3cc..b95d4a9231 100644 --- a/plugins/signals-node/src/lib.ts +++ b/plugins/signals-node/src/lib.ts @@ -13,9 +13,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { createServiceRef } from '@backstage/backend-plugin-api'; +import { + coreServices, + createServiceFactory, + createServiceRef, +} from '@backstage/backend-plugin-api'; +import { SignalService } from './SignalService'; /** @public */ -export const signalService = createServiceRef< - import('./SignalService').SignalService ->({ id: 'signals.service', scope: 'plugin' }); +export const signalService = createServiceRef({ + id: 'signals.service', + scope: 'plugin', + defaultFactory: async service => + createServiceFactory({ + service, + deps: { + logger: coreServices.logger, + identity: coreServices.identity, + // TODO: EventBroker + }, + factory({ logger, identity }) { + return SignalService.create({ identity, logger }); + }, + }), +}); diff --git a/plugins/signals-node/src/types.ts b/plugins/signals-node/src/types.ts index 99821f641d..6bfafae0b2 100644 --- a/plugins/signals-node/src/types.ts +++ b/plugins/signals-node/src/types.ts @@ -15,16 +15,16 @@ */ import { IdentityApi } from '@backstage/plugin-auth-node'; import { EventBroker } from '@backstage/plugin-events-node'; -import { Logger } from 'winston'; import { WebSocket } from 'ws'; import { JsonObject } from '@backstage/types'; +import { LoggerService } from '@backstage/backend-plugin-api'; /** * @public */ export type ServiceOptions = { eventBroker?: EventBroker; - logger: Logger; + logger: LoggerService; identity: IdentityApi; }; From 0b2142260417015d1865f4381e0057e9827b6cad Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Thu, 14 Dec 2023 15:47:29 +0200 Subject: [PATCH 035/283] chore: simplify events backend and signal hook Signed-off-by: Heikki Hellgren --- plugins/signals-node/src/SignalService.ts | 38 ++++++++----------- .../signals-react/src/hooks/useSignalApi.ts | 11 ++++-- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/plugins/signals-node/src/SignalService.ts b/plugins/signals-node/src/SignalService.ts index 54f09f583a..9c621d5cbd 100644 --- a/plugins/signals-node/src/SignalService.ts +++ b/plugins/signals-node/src/SignalService.ts @@ -37,7 +37,6 @@ import { LoggerService } from '@backstage/backend-plugin-api'; /** @public */ export class SignalService implements EventSubscriber { - private readonly serverId: string; private connections: Map = new Map< string, SignalConnection @@ -58,7 +57,6 @@ export class SignalService implements EventSubscriber { identity: this.identity, } = options); - this.serverId = uuid(); this.server = new WebSocketServer({ noServer: true, clientTracking: false, @@ -199,6 +197,21 @@ export class SignalService implements EventSubscriber { return; } + // If there is event broker, use that to publish the message to + // all signal services, including this one. + if (this.eventBroker && !brokedEvent) { + await this.eventBroker.publish({ + topic: 'signals', + eventPayload: { + recipients, + message, + topic, + }, + }); + return; + } + + // Actual websocket message sending this.connections.forEach(conn => { if (!conn.subscriptions.has(topic)) { return; @@ -217,29 +230,10 @@ export class SignalService implements EventSubscriber { conn.ws.send(jsonMessage); }); - - // If this event has not been broadcasted to all servers, then use - // EventBroker to do that - if (this.eventBroker && !brokedEvent) { - await this.eventBroker.publish({ - topic: 'signals', - eventPayload: { - recipients, - message, - topic, - }, - metadata: { server: this.serverId }, - }); - } } async onEvent(params: EventParams): Promise { - const { eventPayload, metadata } = params; - // Discard message from same server to prevent duplicate messages - if (!metadata?.server || metadata.server === this.serverId) { - return; - } - + const { eventPayload } = params; if ( !eventPayload?.recipients || !eventPayload.topic || diff --git a/plugins/signals-react/src/hooks/useSignalApi.ts b/plugins/signals-react/src/hooks/useSignalApi.ts index bb6f47a5fe..8534732264 100644 --- a/plugins/signals-react/src/hooks/useSignalApi.ts +++ b/plugins/signals-react/src/hooks/useSignalApi.ts @@ -14,7 +14,7 @@ * limitations under the License. */ import { signalApiRef } from '../api'; -import { useApi } from '@backstage/core-plugin-api'; +import { useApiHolder } from '@backstage/core-plugin-api'; import { JsonObject } from '@backstage/types'; import { useEffect, useState } from 'react'; @@ -23,10 +23,13 @@ export const useSignalApi = ( topic: string, onMessage: (message: JsonObject) => void, ) => { - const signals = useApi(signalApiRef); + const apiHolder = useApiHolder(); + // Use apiHolder instead useApi in case signalApi is not available in the + // backstage instance this is used + const signals = apiHolder.get(signalApiRef); const [subscription, setSubscription] = useState(null); useEffect(() => { - if (!subscription) { + if (signals && !subscription) { const sub = signals.subscribe(topic, onMessage); setSubscription(sub); } @@ -34,7 +37,7 @@ export const useSignalApi = ( useEffect(() => { return () => { - if (subscription) { + if (signals && subscription) { signals.unsubscribe(subscription); } }; From da5c3fb8188051edd4069ee24520865737b10f3e Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Tue, 2 Jan 2024 09:57:19 +0200 Subject: [PATCH 036/283] fix: address review comments Signed-off-by: Heikki Hellgren --- .changeset/poor-sheep-tease.md | 6 - packages/backend/src/index.ts | 4 +- packages/backend/src/plugins/devtools.ts | 1 - packages/backend/src/types.ts | 4 +- plugins/devtools-backend/api-report.md | 5 - plugins/devtools-backend/package.json | 1 - .../src/api/DevToolsBackendApi.ts | 16 +- plugins/devtools-backend/src/plugin.ts | 5 +- .../devtools-backend/src/service/router.ts | 16 +- .../Content/InfoContent/InfoContent.tsx | 15 +- plugins/signals-backend/api-report.md | 4 +- plugins/signals-backend/src/plugin.ts | 3 +- .../src/service/router.test.ts | 4 +- plugins/signals-backend/src/service/router.ts | 8 +- .../src/service/standaloneServer.ts | 4 +- plugins/signals-node/README.md | 10 +- plugins/signals-node/api-report.md | 41 +-- plugins/signals-node/package.json | 1 - .../signals-node/src/DefaultSignalService.ts | 238 +++++++++++++++++ plugins/signals-node/src/SignalService.ts | 250 ++---------------- plugins/signals-node/src/index.ts | 1 + plugins/signals-node/src/lib.ts | 3 +- plugins/signals-react/README.md | 20 +- plugins/signals-react/api-report.md | 15 +- plugins/signals-react/package.json | 6 +- plugins/signals-react/src/api/SignalApi.ts | 7 +- plugins/signals-react/src/hooks/index.ts | 2 +- .../hooks/{useSignalApi.ts => useSignal.ts} | 27 +- plugins/signals/api-report.md | 9 +- plugins/signals/package.json | 6 +- plugins/signals/src/api/SignalClient.ts | 49 ++-- plugins/signals/src/api/SignalsClient.test.ts | 19 +- plugins/signals/src/plugin.ts | 13 +- yarn.lock | 65 +---- 34 files changed, 413 insertions(+), 465 deletions(-) delete mode 100644 .changeset/poor-sheep-tease.md create mode 100644 plugins/signals-node/src/DefaultSignalService.ts rename plugins/signals-react/src/hooks/{useSignalApi.ts => useSignal.ts} (69%) diff --git a/.changeset/poor-sheep-tease.md b/.changeset/poor-sheep-tease.md deleted file mode 100644 index fa89ac4749..0000000000 --- a/.changeset/poor-sheep-tease.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-devtools-backend': patch -'@backstage/plugin-devtools': patch ---- - -Update devtools information almost real time using signals plugin diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index fc6b814c00..0e92698230 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -73,7 +73,7 @@ import { DefaultEventBroker } from '@backstage/plugin-events-backend'; import { PrometheusExporter } from '@opentelemetry/exporter-prometheus'; import { MeterProvider } from '@opentelemetry/sdk-metrics'; import { metrics } from '@opentelemetry/api'; -import { SignalService } from '@backstage/plugin-signals-node'; +import { DefaultSignalService } from '@backstage/plugin-signals-node'; // Expose opentelemetry metrics using a Prometheus exporter on // http://localhost:9464/metrics . See prometheus.yml in packages/backend for @@ -100,7 +100,7 @@ function makeCreateEnv(config: Config) { }); const eventBroker = new DefaultEventBroker(root.child({ type: 'plugin' })); - const signalService = SignalService.create({ + const signalService = DefaultSignalService.create({ logger: root, eventBroker, identity, diff --git a/packages/backend/src/plugins/devtools.ts b/packages/backend/src/plugins/devtools.ts index 5488033682..8e1767ddb1 100644 --- a/packages/backend/src/plugins/devtools.ts +++ b/packages/backend/src/plugins/devtools.ts @@ -25,6 +25,5 @@ export default async function createPlugin( logger: env.logger, config: env.config, permissions: env.permissions, - signalService: env.signalService, }); } diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts index d76e68c1c9..3dad2f739b 100644 --- a/packages/backend/src/types.ts +++ b/packages/backend/src/types.ts @@ -27,7 +27,7 @@ import { PluginTaskScheduler } from '@backstage/backend-tasks'; import { IdentityApi } from '@backstage/plugin-auth-node'; import { PermissionEvaluator } from '@backstage/plugin-permission-common'; import { EventBroker } from '@backstage/plugin-events-node'; -import { SignalService } from '@backstage/plugin-signals-node'; +import { DefaultSignalService } from '@backstage/plugin-signals-node'; export type PluginEnvironment = { logger: Logger; @@ -41,5 +41,5 @@ export type PluginEnvironment = { scheduler: PluginTaskScheduler; identity: IdentityApi; eventBroker: EventBroker; - signalService: SignalService; + signalService: DefaultSignalService; }; diff --git a/plugins/devtools-backend/api-report.md b/plugins/devtools-backend/api-report.md index 7049285c02..b9eb7b5a0c 100644 --- a/plugins/devtools-backend/api-report.md +++ b/plugins/devtools-backend/api-report.md @@ -11,7 +11,6 @@ import express from 'express'; import { ExternalDependency } from '@backstage/plugin-devtools-common'; import { Logger } from 'winston'; import { PermissionEvaluator } from '@backstage/plugin-permission-common'; -import { SignalService } from '@backstage/plugin-signals-node'; // @public (undocumented) export function createRouter(options: RouterOptions): Promise; @@ -25,8 +24,6 @@ export class DevToolsBackendApi { listExternalDependencyDetails(): Promise; // (undocumented) listInfo(): Promise; - // (undocumented) - listResourceUtilization(): Promise; } // @public @@ -43,7 +40,5 @@ export interface RouterOptions { logger: Logger; // (undocumented) permissions: PermissionEvaluator; - // (undocumented) - signalService?: SignalService; } ``` diff --git a/plugins/devtools-backend/package.json b/plugins/devtools-backend/package.json index 8de7da1b39..18013bc52f 100644 --- a/plugins/devtools-backend/package.json +++ b/plugins/devtools-backend/package.json @@ -38,7 +38,6 @@ "@backstage/plugin-devtools-common": "workspace:^", "@backstage/plugin-permission-common": "workspace:^", "@backstage/plugin-permission-node": "workspace:^", - "@backstage/plugin-signals-node": "workspace:^", "@backstage/types": "workspace:^", "@manypkg/get-packages": "^1.1.3", "@types/express": "*", diff --git a/plugins/devtools-backend/src/api/DevToolsBackendApi.ts b/plugins/devtools-backend/src/api/DevToolsBackendApi.ts index da9a1ca0dd..b71edb3391 100644 --- a/plugins/devtools-backend/src/api/DevToolsBackendApi.ts +++ b/plugins/devtools-backend/src/api/DevToolsBackendApi.ts @@ -203,21 +203,17 @@ export class DevToolsBackendApi { return configInfo; } - public async listResourceUtilization(): Promise { + public async listInfo(): Promise { + const operatingSystem = `${os.hostname()}: ${os.type} ${os.release} - ${ + os.platform + }/${os.arch}`; const usedMem = Math.floor((os.totalmem() - os.freemem()) / (1024 * 1024)); - return `Memory: ${usedMem}/${Math.floor( + const resources = `Memory: ${usedMem}/${Math.floor( os.totalmem() / (1024 * 1024), )}MB - Load: ${os .loadavg() .map(v => v.toFixed(2)) .join('/')}`; - } - - public async listInfo(): Promise { - const operatingSystem = `${os.hostname()}: ${os.type} ${os.release} - ${ - os.platform - }/${os.arch}`; - const nodeJsVersion = process.version; /* eslint-disable-next-line no-restricted-syntax */ @@ -251,7 +247,7 @@ export class DevToolsBackendApi { const info: DevToolsInfo = { operatingSystem: operatingSystem ?? 'N/A', - resourceUtilization: (await this.listResourceUtilization()) ?? 'N/A', + resourceUtilization: resources ?? 'N/A', nodeJsVersion: nodeJsVersion ?? 'N/A', backstageVersion: backstageJson && backstageJson.version ? backstageJson.version : 'N/A', diff --git a/plugins/devtools-backend/src/plugin.ts b/plugins/devtools-backend/src/plugin.ts index 02c3831128..685522557e 100644 --- a/plugins/devtools-backend/src/plugin.ts +++ b/plugins/devtools-backend/src/plugin.ts @@ -20,7 +20,6 @@ import { createBackendPlugin, } from '@backstage/backend-plugin-api'; import { createRouter } from './service/router'; -import { signalService } from '@backstage/plugin-signals-node'; /** * DevTools backend plugin @@ -36,15 +35,13 @@ export const devtoolsPlugin = createBackendPlugin({ logger: coreServices.logger, permissions: coreServices.permissions, httpRouter: coreServices.httpRouter, - signals: signalService, }, - async init({ config, logger, permissions, httpRouter, signals }) { + async init({ config, logger, permissions, httpRouter }) { httpRouter.use( await createRouter({ config, logger: loggerToWinstonLogger(logger), permissions, - signalService: signals, }), ); }, diff --git a/plugins/devtools-backend/src/service/router.ts b/plugins/devtools-backend/src/service/router.ts index 106eb44309..fbeeb5af84 100644 --- a/plugins/devtools-backend/src/service/router.ts +++ b/plugins/devtools-backend/src/service/router.ts @@ -33,7 +33,6 @@ import { errorHandler } from '@backstage/backend-common'; import express from 'express'; import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; import { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node'; -import { SignalService } from '@backstage/plugin-signals-node'; /** @public */ export interface RouterOptions { @@ -41,30 +40,17 @@ export interface RouterOptions { logger: Logger; config: Config; permissions: PermissionEvaluator; - signalService?: SignalService; } /** @public */ export async function createRouter( options: RouterOptions, ): Promise { - const { logger, config, permissions, signalService } = options; + const { logger, config, permissions } = options; const devToolsBackendApi = options.devToolsBackendApi || new DevToolsBackendApi(logger, config); - if (signalService) { - // Publish info periodically using the signal service - setInterval(async () => { - if (signalService.hasSubscribers('devtools:resources')) { - const info = await devToolsBackendApi.listResourceUtilization(); - await signalService.publish('*', 'devtools:resources', { - resources: info, - }); - } - }, 5000); - } - const router = Router(); router.use(express.json()); router.use( diff --git a/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx b/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx index 2480bf5233..0ed43d2fee 100644 --- a/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx +++ b/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx @@ -29,7 +29,7 @@ import { Theme, } from '@material-ui/core'; import { Alert } from '@material-ui/lab'; -import React, { useEffect, useState } from 'react'; +import React from 'react'; import { useInfo } from '../../../hooks'; import { InfoDependenciesTable } from './InfoDependenciesTable'; import DescriptionIcon from '@material-ui/icons/Description'; @@ -38,7 +38,6 @@ import DeveloperBoardIcon from '@material-ui/icons/DeveloperBoard'; import { BackstageLogoIcon } from './BackstageLogoIcon'; import FileCopyIcon from '@material-ui/icons/FileCopy'; import { DevToolsInfo } from '@backstage/plugin-devtools-common'; -import { useSignalApi } from '@backstage/plugin-signals-react'; const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -73,17 +72,7 @@ const copyToClipboard = ({ about }: { about: DevToolsInfo | undefined }) => { /** @public */ export const InfoContent = () => { const classes = useStyles(); - const [resources, setResources] = useState(undefined); const { about, loading, error } = useInfo(); - useSignalApi('devtools:resources', message => { - setResources(message.resources as string); - }); - - useEffect(() => { - if (!loading && !error && about) { - setResources(about.resourceUtilization); - } - }, [about, loading, error]); if (loading) { return ; @@ -113,7 +102,7 @@ export const InfoContent = () => { diff --git a/plugins/signals-backend/api-report.md b/plugins/signals-backend/api-report.md index afbc63abf2..e96dd2e09c 100644 --- a/plugins/signals-backend/api-report.md +++ b/plugins/signals-backend/api-report.md @@ -5,7 +5,7 @@ ```ts import { BackendFeature } from '@backstage/backend-plugin-api'; import express from 'express'; -import { Logger } from 'winston'; +import { LoggerService } from '@backstage/backend-plugin-api'; import { SignalService } from '@backstage/plugin-signals-node'; // @public (undocumented) @@ -14,7 +14,7 @@ export function createRouter(options: RouterOptions): Promise; // @public (undocumented) export interface RouterOptions { // (undocumented) - logger: Logger; + logger: LoggerService; // (undocumented) service: SignalService; } diff --git a/plugins/signals-backend/src/plugin.ts b/plugins/signals-backend/src/plugin.ts index 8ade4e85b5..68bbf27377 100644 --- a/plugins/signals-backend/src/plugin.ts +++ b/plugins/signals-backend/src/plugin.ts @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { loggerToWinstonLogger } from '@backstage/backend-common'; import { coreServices, createBackendPlugin, @@ -38,7 +37,7 @@ export const signalsPlugin = createBackendPlugin({ async init({ httpRouter, logger, service }) { httpRouter.use( await createRouter({ - logger: loggerToWinstonLogger(logger), + logger, service, }), ); diff --git a/plugins/signals-backend/src/service/router.test.ts b/plugins/signals-backend/src/service/router.test.ts index b41704e008..281d6ed4a5 100644 --- a/plugins/signals-backend/src/service/router.test.ts +++ b/plugins/signals-backend/src/service/router.test.ts @@ -18,9 +18,9 @@ import express from 'express'; import request from 'supertest'; import { createRouter } from './router'; -import { SignalService } from '@backstage/plugin-signals-node'; +import { DefaultSignalService } from '@backstage/plugin-signals-node'; -const signalsServiceMock: jest.Mocked = {} as any; +const signalsServiceMock: jest.Mocked = {} as any; describe('createRouter', () => { let app: express.Express; diff --git a/plugins/signals-backend/src/service/router.ts b/plugins/signals-backend/src/service/router.ts index 8926910544..28bafce14a 100644 --- a/plugins/signals-backend/src/service/router.ts +++ b/plugins/signals-backend/src/service/router.ts @@ -16,14 +16,14 @@ import { errorHandler } from '@backstage/backend-common'; import express, { NextFunction, Request, Response } from 'express'; import Router from 'express-promise-router'; -import { Logger } from 'winston'; +import { LoggerService } from '@backstage/backend-plugin-api'; import { SignalService } from '@backstage/plugin-signals-node'; import * as https from 'https'; import http from 'http'; /** @public */ export interface RouterOptions { - logger: Logger; + logger: LoggerService; service: SignalService; } @@ -48,9 +48,9 @@ export async function createRouter( if (!subscribed) { subscribed = true; server.on('upgrade', async (request, socket, head) => { - // Only upgrade if request to root of the signals plugin + // TODO: Find a way to make this more generic if (request.url === '/api/signals') { - await service.handleUpgrade(request, socket, head); + await service.handleUpgrade({ server, request, socket, head }); } }); } diff --git a/plugins/signals-backend/src/service/standaloneServer.ts b/plugins/signals-backend/src/service/standaloneServer.ts index 0728b2fde5..e1ce27aee4 100644 --- a/plugins/signals-backend/src/service/standaloneServer.ts +++ b/plugins/signals-backend/src/service/standaloneServer.ts @@ -21,7 +21,7 @@ import { import { Server } from 'http'; import { Logger } from 'winston'; import { createRouter } from './router'; -import { SignalService } from '@backstage/plugin-signals-node'; +import { DefaultSignalService } from '@backstage/plugin-signals-node'; import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; export interface ServerOptions { @@ -43,7 +43,7 @@ export async function startStandaloneServer( issuer: await discovery.getExternalBaseUrl('auth'), }); - const signals = SignalService.create({ + const signals = DefaultSignalService.create({ logger: logger, identity, }); diff --git a/plugins/signals-node/README.md b/plugins/signals-node/README.md index abea6c6d22..14c9332dc1 100644 --- a/plugins/signals-node/README.md +++ b/plugins/signals-node/README.md @@ -56,13 +56,9 @@ all subscribers, you can use `*` as `to` parameter. ```ts // Periodic sending example setInterval(async () => { - // You can use hasSubscribers to check if the message will be sent to anyone - // in case you need some heavy processing before that - if (signalService.hasSubscribers('plugin:topic')) { - await signalService.publish('*', 'plugin:topic', { - message: 'hello world', - }); - } + await signalService.publish('*', 'plugin:topic', { + message: 'hello world', + }); }, 5000); ``` diff --git a/plugins/signals-node/api-report.md b/plugins/signals-node/api-report.md index 7bfffc2540..d85163040b 100644 --- a/plugins/signals-node/api-report.md +++ b/plugins/signals-node/api-report.md @@ -7,14 +7,26 @@ import { Duplex } from 'stream'; import { EventBroker } from '@backstage/plugin-events-node'; -import { EventParams } from '@backstage/plugin-events-node'; -import { EventSubscriber } from '@backstage/plugin-events-node'; +import http from 'http'; +import https from 'https'; import { IdentityApi } from '@backstage/plugin-auth-node'; import { IncomingMessage } from 'http'; import { JsonObject } from '@backstage/types'; import { LoggerService } from '@backstage/backend-plugin-api'; import { ServiceRef } from '@backstage/backend-plugin-api'; +// @public (undocumented) +export class DefaultSignalService implements SignalService { + // (undocumented) + static create(options: ServiceOptions): DefaultSignalService; + handleUpgrade(options: SignalServiceUpgradeOptions): Promise; + publish( + to: string | string[], + topic: string, + message: JsonObject, + ): Promise; +} + // @public (undocumented) export type ServiceOptions = { eventBroker?: EventBroker; @@ -30,28 +42,25 @@ export type SignalEventBrokerPayload = { }; // @public (undocumented) -export class SignalService implements EventSubscriber { - // (undocumented) - static create(options: ServiceOptions): SignalService; - handleUpgrade: ( - req: IncomingMessage, - socket: Duplex, - head: Buffer, - ) => Promise; - hasSubscribers(topic: string): boolean; - // (undocumented) - onEvent(params: EventParams): Promise; +export type SignalService = { publish( to: string | string[], topic: string, message: JsonObject, ): Promise; - // (undocumented) - supportsEventTopics(): string[]; -} + handleUpgrade(options: SignalServiceUpgradeOptions): Promise; +}; // @public (undocumented) export const signalService: ServiceRef; +// @public (undocumented) +export type SignalServiceUpgradeOptions = { + server: https.Server | http.Server; + request: IncomingMessage; + socket: Duplex; + head: Buffer; +}; + // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/signals-node/package.json b/plugins/signals-node/package.json index d5e980d857..d3230432f1 100644 --- a/plugins/signals-node/package.json +++ b/plugins/signals-node/package.json @@ -37,7 +37,6 @@ "@backstage/types": "workspace:^", "express": "^4.17.1", "uuid": "^8.0.0", - "winston": "^3.2.1", "ws": "^8.14.2" } } diff --git a/plugins/signals-node/src/DefaultSignalService.ts b/plugins/signals-node/src/DefaultSignalService.ts new file mode 100644 index 0000000000..cab6e83c81 --- /dev/null +++ b/plugins/signals-node/src/DefaultSignalService.ts @@ -0,0 +1,238 @@ +/* + * Copyright 2023 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 { EventBroker, EventParams } from '@backstage/plugin-events-node'; +import { + ServiceOptions, + SignalConnection, + SignalEventBrokerPayload, +} from './types'; +import { RawData, WebSocket, WebSocketServer } from 'ws'; +import { IncomingMessage } from 'http'; +import { v4 as uuid } from 'uuid'; +import { JsonObject } from '@backstage/types'; +import { + BackstageIdentityResponse, + IdentityApi, + IdentityApiGetIdentityRequest, +} from '@backstage/plugin-auth-node'; +import { LoggerService } from '@backstage/backend-plugin-api'; +import { SignalService, SignalServiceUpgradeOptions } from './SignalService'; + +/** @public */ +export class DefaultSignalService implements SignalService { + private connections: Map = new Map< + string, + SignalConnection + >(); + private eventBroker?: EventBroker; + private logger: LoggerService; + private identity: IdentityApi; + private server: WebSocketServer; + + static create(options: ServiceOptions) { + return new DefaultSignalService(options); + } + + private constructor(options: ServiceOptions) { + ({ + eventBroker: this.eventBroker, + logger: this.logger, + identity: this.identity, + } = options); + + this.server = new WebSocketServer({ + noServer: true, + clientTracking: false, + }); + + this.eventBroker?.subscribe({ + supportsEventTopics: () => ['signals'], + onEvent: (params: EventParams) => + this.onEventBrokerEvent(params), + }); + } + + /** + * Handles request upgrade to websocket and adds the connection to internal + * list for publish/subscribe functionality + * @param req - Request + */ + async handleUpgrade(options: SignalServiceUpgradeOptions) { + const { request, socket, head } = options; + let identity: BackstageIdentityResponse | undefined = undefined; + + // Authentication token is passed in Sec-WebSocket-Protocol header as there + // is no other way to pass the token with plain websockets + const token = request.headers['sec-websocket-protocol']; + if (token) { + identity = await this.identity.getIdentity({ + request: { + headers: { authorization: token }, + }, + } as IdentityApiGetIdentityRequest); + } + + this.server.handleUpgrade( + request, + socket, + head, + (ws: WebSocket, __: IncomingMessage) => { + this.addConnection(ws, identity); + }, + ); + } + + private addConnection(ws: WebSocket, identity?: BackstageIdentityResponse) { + const id = uuid(); + + const conn = { + id, + user: identity?.identity.userEntityRef ?? 'user:default/guest', + ws, + ownershipEntityRefs: identity?.identity.ownershipEntityRefs ?? [], + subscriptions: new Set(), + }; + + this.connections.set(id, conn); + + ws.on('error', (err: Error) => { + this.logger.info( + `Error occurred with connection ${id}: ${err}, closing connection`, + ); + ws.close(); + this.connections.delete(id); + }); + + ws.on('close', (code: number, reason: Buffer) => { + this.logger.info( + `Connection ${id} closed with code ${code}, reason: ${reason}`, + ); + this.connections.delete(id); + }); + + ws.on('message', (data: RawData, isBinary: boolean) => { + this.logger.debug(`Received message from connection ${id}: ${data}`); + if (isBinary) { + return; + } + try { + const json = JSON.parse(data.toString()) as JsonObject; + this.handleMessage(conn, json); + } catch (err: any) { + this.logger.error( + `Invalid message received from connection ${id}: ${err}`, + ); + } + }); + } + + private handleMessage(connection: SignalConnection, message: JsonObject) { + if (message.action === 'subscribe' && message.topic) { + this.logger.info( + `Connection ${connection.id} subscribed to ${message.topic}`, + ); + connection.subscriptions.add(message.topic as string); + } + + if (message.action === 'unsubscribe' && message.topic) { + this.logger.info( + `Connection ${connection.id} unsubscribed from ${message.topic}`, + ); + connection.subscriptions.delete(message.topic as string); + } + } + + /** + * Publishes a message to user refs to specific topic + * @param to - string or array of user ref strings to publish message to + * @param topic - message topic + * @param message - message to publish + */ + async publish(to: string | string[], topic: string, message: JsonObject) { + await this.publishInternal( + Array.isArray(to) ? to : [to], + topic, + message, + false, + ); + } + + private async publishInternal( + recipients: string[], + topic: string, + message: JsonObject, + brokedEvent: boolean, + ) { + const jsonMessage = JSON.stringify({ topic, message }); + if (jsonMessage.length === 0) { + return; + } + + // If there is event broker, use that to publish the message to + // all signal services, including this one. + if (this.eventBroker && !brokedEvent) { + await this.eventBroker.publish({ + topic: 'signals', + eventPayload: { + recipients, + message, + topic, + }, + }); + return; + } + + // Actual websocket message sending + this.connections.forEach(conn => { + if (!conn.subscriptions.has(topic)) { + return; + } + // Sending to all users can be done with '*' + if ( + !recipients.includes('*') && + !conn.ownershipEntityRefs.some(ref => recipients.includes(ref)) + ) { + return; + } + + if (conn.ws.readyState !== WebSocket.OPEN) { + return; + } + + conn.ws.send(jsonMessage); + }); + } + + private async onEventBrokerEvent( + params: EventParams, + ): Promise { + const { eventPayload } = params; + if ( + !eventPayload?.recipients || + !eventPayload.topic || + !eventPayload.message + ) { + return; + } + + await this.publishInternal( + eventPayload.recipients, + eventPayload.topic, + eventPayload.message, + true, + ); + } +} diff --git a/plugins/signals-node/src/SignalService.ts b/plugins/signals-node/src/SignalService.ts index 9c621d5cbd..7095c29858 100644 --- a/plugins/signals-node/src/SignalService.ts +++ b/plugins/signals-node/src/SignalService.ts @@ -1,5 +1,5 @@ /* - * Copyright 2023 The Backstage Authors + * Copyright 2024 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. @@ -13,244 +13,32 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { - EventBroker, - EventParams, - EventSubscriber, -} from '@backstage/plugin-events-node'; -import { - ServiceOptions, - SignalConnection, - SignalEventBrokerPayload, -} from './types'; -import { RawData, WebSocket, WebSocketServer } from 'ws'; -import { IncomingMessage } from 'http'; -import { v4 as uuid } from 'uuid'; import { JsonObject } from '@backstage/types'; -import { - BackstageIdentityResponse, - IdentityApi, - IdentityApiGetIdentityRequest, -} from '@backstage/plugin-auth-node'; +import http, { IncomingMessage } from 'http'; import { Duplex } from 'stream'; -import { LoggerService } from '@backstage/backend-plugin-api'; +import https from 'https'; /** @public */ -export class SignalService implements EventSubscriber { - private connections: Map = new Map< - string, - SignalConnection - >(); - private eventBroker?: EventBroker; - private logger: LoggerService; - private identity: IdentityApi; - private server: WebSocketServer; - - static create(options: ServiceOptions) { - return new SignalService(options); - } - - private constructor(options: ServiceOptions) { - ({ - eventBroker: this.eventBroker, - logger: this.logger, - identity: this.identity, - } = options); - - this.server = new WebSocketServer({ - noServer: true, - clientTracking: false, - }); - - this.eventBroker?.subscribe(this); - } - - /** - * Handles request upgrade to websocket and adds the connection to internal - * list for publish/subscribe functionality - * @param req - Request - */ - handleUpgrade = async ( - req: IncomingMessage, - socket: Duplex, - head: Buffer, - ) => { - let identity: BackstageIdentityResponse | undefined = undefined; - - // Authentication token is passed in Sec-WebSocket-Protocol header as there - // is no other way to pass the token with plain websockets - const token = req.headers['sec-websocket-protocol']; - if (token) { - identity = await this.identity.getIdentity({ - request: { - headers: { authorization: token }, - }, - } as IdentityApiGetIdentityRequest); - } - - this.server.handleUpgrade( - req, - socket, - head, - (ws: WebSocket, __: IncomingMessage) => { - this.addConnection(ws, identity); - }, - ); - }; - - private addConnection(ws: WebSocket, identity?: BackstageIdentityResponse) { - const id = uuid(); - - const conn = { - id, - user: identity?.identity.userEntityRef ?? 'user:default/guest', - ws, - ownershipEntityRefs: identity?.identity.ownershipEntityRefs ?? [], - subscriptions: new Set(), - }; - - this.connections.set(id, conn); - - ws.on('error', (err: Error) => { - this.logger.info( - `Error occurred with connection ${id}: ${err}, closing connection`, - ); - ws.close(); - this.connections.delete(id); - }); - - ws.on('close', (code: number, reason: Buffer) => { - this.logger.info( - `Connection ${id} closed with code ${code}, reason: ${reason}`, - ); - this.connections.delete(id); - }); - - ws.on('message', (data: RawData, isBinary: boolean) => { - this.logger.debug(`Received message from connection ${id}: ${data}`); - if (isBinary) { - return; - } - try { - const json = JSON.parse(data.toString()) as JsonObject; - this.handleMessage(conn, json); - } catch (err: any) { - this.logger.error( - `Invalid message received from connection ${id}: ${err}`, - ); - } - }); - } - - private handleMessage(connection: SignalConnection, message: JsonObject) { - if (message.action === 'subscribe' && message.topic) { - this.logger.info( - `Connection ${connection.id} subscribed to ${message.topic}`, - ); - connection.subscriptions.add(message.topic as string); - } - - if (message.action === 'unsubscribe' && message.topic) { - this.logger.info( - `Connection ${connection.id} unsubscribed from ${message.topic}`, - ); - connection.subscriptions.delete(message.topic as string); - } - } +export type SignalServiceUpgradeOptions = { + server: https.Server | http.Server; + request: IncomingMessage; + socket: Duplex; + head: Buffer; +}; +/** @public */ +export type SignalService = { /** * Publishes a message to user refs to specific topic - * @param to - string or array of user ref strings to publish message to - * @param topic - message topic - * @param message - message to publish */ - async publish(to: string | string[], topic: string, message: JsonObject) { - await this.publishInternal( - Array.isArray(to) ? to : [to], - topic, - message, - false, - ); - } - - /** - * Checks if there is active subscriptions to specific topic. - * This can be useful to skip heavy processing before publishing messages if there are no subscriptions. - * @param topic - topic to check for subscriptions - */ - hasSubscribers(topic: string): boolean { - return ( - [...this.connections.values()].find(conn => - conn.subscriptions.has(topic), - ) !== undefined - ); - } - - private async publishInternal( - recipients: string[], + publish( + to: string | string[], topic: string, message: JsonObject, - brokedEvent: boolean, - ) { - const jsonMessage = JSON.stringify({ topic, message }); - if (jsonMessage.length === 0) { - return; - } + ): Promise; - // If there is event broker, use that to publish the message to - // all signal services, including this one. - if (this.eventBroker && !brokedEvent) { - await this.eventBroker.publish({ - topic: 'signals', - eventPayload: { - recipients, - message, - topic, - }, - }); - return; - } - - // Actual websocket message sending - this.connections.forEach(conn => { - if (!conn.subscriptions.has(topic)) { - return; - } - // Sending to all users can be done with '*' - if ( - !recipients.includes('*') && - !conn.ownershipEntityRefs.some(ref => recipients.includes(ref)) - ) { - return; - } - - if (conn.ws.readyState !== WebSocket.OPEN) { - return; - } - - conn.ws.send(jsonMessage); - }); - } - - async onEvent(params: EventParams): Promise { - const { eventPayload } = params; - if ( - !eventPayload?.recipients || - !eventPayload.topic || - !eventPayload.message - ) { - return; - } - - await this.publishInternal( - eventPayload.recipients, - eventPayload.topic, - eventPayload.message, - true, - ); - } - - supportsEventTopics(): string[] { - return ['signals']; - } -} + /** + * Handles request upgrade + */ + handleUpgrade(options: SignalServiceUpgradeOptions): Promise; +}; diff --git a/plugins/signals-node/src/index.ts b/plugins/signals-node/src/index.ts index 43a3a88ac0..f9c220b1e9 100644 --- a/plugins/signals-node/src/index.ts +++ b/plugins/signals-node/src/index.ts @@ -15,5 +15,6 @@ */ export * from './lib'; +export * from './DefaultSignalService'; export * from './SignalService'; export * from './types'; diff --git a/plugins/signals-node/src/lib.ts b/plugins/signals-node/src/lib.ts index b95d4a9231..c7e7c4a6ae 100644 --- a/plugins/signals-node/src/lib.ts +++ b/plugins/signals-node/src/lib.ts @@ -18,6 +18,7 @@ import { createServiceFactory, createServiceRef, } from '@backstage/backend-plugin-api'; +import { DefaultSignalService } from './DefaultSignalService'; import { SignalService } from './SignalService'; /** @public */ @@ -33,7 +34,7 @@ export const signalService = createServiceRef({ // TODO: EventBroker }, factory({ logger, identity }) { - return SignalService.create({ identity, logger }); + return DefaultSignalService.create({ identity, logger }); }, }), }); diff --git a/plugins/signals-react/README.md b/plugins/signals-react/README.md index 9bdf5e964f..244a4ec43d 100644 --- a/plugins/signals-react/README.md +++ b/plugins/signals-react/README.md @@ -20,15 +20,12 @@ of connections to the backend and also to allow multiple subscriptions using the Example of using the hook: ```ts -import { useSignalApi } from '@backstage/plugin-signals-react'; +import { useSignal } from '@backstage/plugin-signals-react'; -const [message, setMessage] = useState(undefined); -useSignalApi('myplugin:topic', message => { - setMessage(message); -}); +const { lastSignal } = useSignal('myplugin:topic'); ``` -Whenever backend publishes new message to the topic `myplugin:topic`, the state of this component is changed. +Whenever backend publishes new message to the topic `myplugin:topic`, the lastSignal is changed. ## Using API directly @@ -39,9 +36,12 @@ subscriptions. import { signalsApiRef } from '@backstage/plugin-signals-react'; const signals = useApi(signalsApiRef); -signals.subscribe('myplugin:topic', (message: JsonObject) => { - console.log(message); -}); +const { unsubscribe } = signals.subscribe( + 'myplugin:topic', + (message: JsonObject) => { + console.log(message); + }, +); // Remember to unsubscribe -signals.unsubscribe('myplugin:topic'); +unsubscribe(); ``` diff --git a/plugins/signals-react/api-report.md b/plugins/signals-react/api-report.md index d28b806103..8ad0c06fbe 100644 --- a/plugins/signals-react/api-report.md +++ b/plugins/signals-react/api-report.md @@ -8,18 +8,21 @@ import { JsonObject } from '@backstage/types'; // @public (undocumented) export type SignalApi = { - subscribe(topic: string, onMessage: (message: JsonObject) => void): string; - unsubscribe(subscription: string): void; + subscribe( + topic: string, + onMessage: (message: JsonObject) => void, + ): { + unsubscribe: () => void; + }; }; // @public (undocumented) export const signalApiRef: ApiRef; // @public (undocumented) -export const useSignalApi: ( - topic: string, - onMessage: (message: JsonObject) => void, -) => void; +export const useSignal: (topic: string) => { + lastSignal: JsonObject | null; +}; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/signals-react/package.json b/plugins/signals-react/package.json index 148bc27cb3..06df050ccd 100644 --- a/plugins/signals-react/package.json +++ b/plugins/signals-react/package.json @@ -26,7 +26,7 @@ "dependencies": { "@backstage/core-plugin-api": "workspace:^", "@backstage/types": "workspace:^", - "@material-ui/core": "^4.9.13" + "@material-ui/core": "^4.12.4" }, "peerDependencies": { "react": "^16.13.1 || ^17.0.0" @@ -34,8 +34,8 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", - "@testing-library/jest-dom": "^5.10.1", - "@testing-library/react": "^12.1.3" + "@testing-library/jest-dom": "^6.0.0", + "@testing-library/react": "^14.0.0" }, "files": [ "dist" diff --git a/plugins/signals-react/src/api/SignalApi.ts b/plugins/signals-react/src/api/SignalApi.ts index f63023bf5f..09eacafa4d 100644 --- a/plugins/signals-react/src/api/SignalApi.ts +++ b/plugins/signals-react/src/api/SignalApi.ts @@ -23,7 +23,8 @@ export const signalApiRef = createApiRef({ /** @public */ export type SignalApi = { - subscribe(topic: string, onMessage: (message: JsonObject) => void): string; - - unsubscribe(subscription: string): void; + subscribe( + topic: string, + onMessage: (message: JsonObject) => void, + ): { unsubscribe: () => void }; }; diff --git a/plugins/signals-react/src/hooks/index.ts b/plugins/signals-react/src/hooks/index.ts index 921eca8d30..a7bf7ebad2 100644 --- a/plugins/signals-react/src/hooks/index.ts +++ b/plugins/signals-react/src/hooks/index.ts @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export * from './useSignalApi'; +export * from './useSignal'; diff --git a/plugins/signals-react/src/hooks/useSignalApi.ts b/plugins/signals-react/src/hooks/useSignal.ts similarity index 69% rename from plugins/signals-react/src/hooks/useSignalApi.ts rename to plugins/signals-react/src/hooks/useSignal.ts index 8534732264..1176769a06 100644 --- a/plugins/signals-react/src/hooks/useSignalApi.ts +++ b/plugins/signals-react/src/hooks/useSignal.ts @@ -19,27 +19,26 @@ import { JsonObject } from '@backstage/types'; import { useEffect, useState } from 'react'; /** @public */ -export const useSignalApi = ( - topic: string, - onMessage: (message: JsonObject) => void, -) => { +export const useSignal = (topic: string) => { const apiHolder = useApiHolder(); // Use apiHolder instead useApi in case signalApi is not available in the // backstage instance this is used const signals = apiHolder.get(signalApiRef); - const [subscription, setSubscription] = useState(null); + const [lastSignal, setLastSignal] = useState(null); useEffect(() => { - if (signals && !subscription) { - const sub = signals.subscribe(topic, onMessage); - setSubscription(sub); + let unsub: null | (() => void) = null; + if (signals) { + const { unsubscribe } = signals.subscribe(topic, (msg: JsonObject) => { + setLastSignal(msg); + }); + unsub = unsubscribe; } - }, [subscription, signals, onMessage, topic]); - - useEffect(() => { return () => { - if (signals && subscription) { - signals.unsubscribe(subscription); + if (signals && unsub) { + unsub(); } }; - }, [subscription, signals, topic]); + }, [signals, topic]); + + return { lastSignal }; }; diff --git a/plugins/signals/api-report.md b/plugins/signals/api-report.md index 28a70a339c..97c882dda4 100644 --- a/plugins/signals/api-report.md +++ b/plugins/signals/api-report.md @@ -23,9 +23,12 @@ export class SignalClient implements SignalApi { // (undocumented) static readonly DEFAULT_RECONNECT_TIMEOUT_MS: number; // (undocumented) - subscribe(topic: string, onMessage: (message: JsonObject) => void): string; - // (undocumented) - unsubscribe(subscription: string): void; + subscribe( + topic: string, + onMessage: (message: JsonObject) => void, + ): { + unsubscribe: () => void; + }; } // @public (undocumented) diff --git a/plugins/signals/package.json b/plugins/signals/package.json index e708d46329..cec95280c1 100644 --- a/plugins/signals/package.json +++ b/plugins/signals/package.json @@ -28,7 +28,7 @@ "@backstage/plugin-signals-react": "workspace:^", "@backstage/theme": "workspace:^", "@backstage/types": "workspace:^", - "@material-ui/core": "^4.9.13", + "@material-ui/core": "^4.12.4", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.61", "react-use": "^17.2.4", @@ -42,8 +42,8 @@ "@backstage/core-app-api": "workspace:^", "@backstage/dev-utils": "workspace:^", "@backstage/test-utils": "workspace:^", - "@testing-library/jest-dom": "^5.10.1", - "@testing-library/react": "^12.1.3", + "@testing-library/jest-dom": "^6.0.0", + "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.0.0", "jest-websocket-mock": "^2.5.0", "msw": "^1.0.0" diff --git a/plugins/signals/src/api/SignalClient.ts b/plugins/signals/src/api/SignalClient.ts index 64c1866fab..24a38a49e3 100644 --- a/plugins/signals/src/api/SignalClient.ts +++ b/plugins/signals/src/api/SignalClient.ts @@ -62,7 +62,10 @@ export class SignalClient implements SignalApi { private reconnectTimeout: number, ) {} - subscribe(topic: string, onMessage: (message: JsonObject) => void): string { + subscribe( + topic: string, + onMessage: (message: JsonObject) => void, + ): { unsubscribe: () => void } { const subscriptionId = uuid(); const exists = [...this.subscriptions.values()].find( sub => sub.topic === topic, @@ -79,30 +82,30 @@ export class SignalClient implements SignalApi { .catch(() => { this.reconnect(); }); - return subscriptionId; - } - unsubscribe(subscription: string): void { - const sub = this.subscriptions.get(subscription); - if (!sub) { - return; - } - const topic = sub.topic; - this.subscriptions.delete(subscription); - const exists = [...this.subscriptions.values()].find( - s => s.topic === topic, - ); - // If there are subscriptions still listening to this topic, do not - // unsubscribe from the server - if (!exists) { - this.send({ action: 'unsubscribe', topic: sub.topic }); - } + const unsubscribe = () => { + const sub = this.subscriptions.get(subscriptionId); + if (!sub) { + return; + } + this.subscriptions.delete(subscriptionId); + const multipleExists = [...this.subscriptions.values()].find( + s => s.topic === topic, + ); + // If there are subscriptions still listening to this topic, do not + // unsubscribe from the server + if (!multipleExists) { + this.send({ action: 'unsubscribe', topic: sub.topic }); + } - // If there are no subscriptions, close the connection - if (this.subscriptions.size === 0) { - this.ws?.close(WS_CLOSE_NORMAL); - this.ws = null; - } + // If there are no subscriptions, close the connection + if (this.subscriptions.size === 0) { + this.ws?.close(WS_CLOSE_NORMAL); + this.ws = null; + } + }; + + return { unsubscribe }; } private send(data?: JsonObject): void { diff --git a/plugins/signals/src/api/SignalsClient.test.ts b/plugins/signals/src/api/SignalsClient.test.ts index 60d67e6c4b..ec202e2703 100644 --- a/plugins/signals/src/api/SignalsClient.test.ts +++ b/plugins/signals/src/api/SignalsClient.test.ts @@ -44,7 +44,7 @@ describe('SignalsClient', () => { it('should handle single subscription correctly', async () => { const messageMock = jest.fn(); const client = SignalClient.create({ discoveryApi, identity }); - const sub = client.subscribe('topic', messageMock); + const { unsubscribe } = client.subscribe('topic', messageMock); await server.connected; await expect(server).toReceiveMessage({ @@ -54,7 +54,8 @@ describe('SignalsClient', () => { server.send({ topic: 'topic', message: { hello: 'world' } }); expect(messageMock).toHaveBeenCalledWith({ hello: 'world' }); - client.unsubscribe(sub); + await unsubscribe(); + await expect(server).toReceiveMessage({ action: 'unsubscribe', topic: 'topic', @@ -66,8 +67,14 @@ describe('SignalsClient', () => { const messageMock2 = jest.fn(); const client1 = SignalClient.create({ discoveryApi, identity }); const client2 = SignalClient.create({ discoveryApi, identity }); - const sub1 = client1.subscribe('topic', messageMock1); - const sub2 = client2.subscribe('topic', messageMock2); + const { unsubscribe: unsubscribe1 } = client1.subscribe( + 'topic', + messageMock1, + ); + const { unsubscribe: unsubscribe2 } = client2.subscribe( + 'topic', + messageMock2, + ); await server.connected; @@ -79,13 +86,13 @@ describe('SignalsClient', () => { expect(messageMock1).toHaveBeenCalledWith({ hello: 'world' }); expect(messageMock2).toHaveBeenCalledWith({ hello: 'world' }); - client1.unsubscribe(sub1); + await unsubscribe1(); await expect(server).not.toReceiveMessage({ action: 'unsubscribe', topic: 'topic', }); - client2.unsubscribe(sub2); + await unsubscribe2(); await expect(server).toReceiveMessage({ action: 'unsubscribe', topic: 'topic', diff --git a/plugins/signals/src/plugin.ts b/plugins/signals/src/plugin.ts index 1482d7dae1..eb3f9126e2 100644 --- a/plugins/signals/src/plugin.ts +++ b/plugins/signals/src/plugin.ts @@ -22,8 +22,6 @@ import { import { signalApiRef } from '@backstage/plugin-signals-react'; import { SignalClient } from './api/SignalClient'; -let clientInstance: SignalClient | undefined = undefined; - /** @public */ export const signalsPlugin = createPlugin({ id: 'signals', @@ -35,13 +33,10 @@ export const signalsPlugin = createPlugin({ discoveryApi: discoveryApiRef, }, factory: ({ identity, discoveryApi }) => { - if (!clientInstance) { - clientInstance = SignalClient.create({ - identity, - discoveryApi, - }); - } - return clientInstance; + return SignalClient.create({ + identity, + discoveryApi, + }); }, }), ], diff --git a/yarn.lock b/yarn.lock index 7a3fbb3902..72e4e43d02 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,7 +12,7 @@ __metadata: languageName: node linkType: hard -"@adobe/css-tools@npm:^4.0.1, @adobe/css-tools@npm:^4.3.2": +"@adobe/css-tools@npm:^4.3.2": version: 4.3.2 resolution: "@adobe/css-tools@npm:4.3.2" checksum: 9667d61d55dc3b0a315c530ae84e016ce5267c4dd8ac00abb40108dc98e07b98e3090ce8b87acd51a41a68d9e84dcccb08cdf21c902572a9cf9dcaf830da4ae3 @@ -6203,7 +6203,6 @@ __metadata: "@backstage/plugin-devtools-common": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" "@backstage/plugin-permission-node": "workspace:^" - "@backstage/plugin-signals-node": "workspace:^" "@backstage/types": "workspace:^" "@manypkg/get-packages": ^1.1.3 "@types/express": "*" @@ -8875,12 +8874,11 @@ __metadata: "@types/express": ^4.17.21 express: ^4.17.1 uuid: ^8.0.0 - winston: ^3.2.1 ws: ^8.14.2 languageName: unknown linkType: soft -"@backstage/plugin-signals-react@workspace:plugins/signals-react": +"@backstage/plugin-signals-react@workspace:^, @backstage/plugin-signals-react@workspace:plugins/signals-react": version: 0.0.0-use.local resolution: "@backstage/plugin-signals-react@workspace:plugins/signals-react" dependencies: @@ -8888,9 +8886,9 @@ __metadata: "@backstage/core-plugin-api": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/types": "workspace:^" - "@material-ui/core": ^4.9.13 - "@testing-library/jest-dom": ^5.10.1 - "@testing-library/react": ^12.1.3 + "@material-ui/core": ^4.12.4 + "@testing-library/jest-dom": ^6.0.0 + "@testing-library/react": ^14.0.0 peerDependencies: react: ^16.13.1 || ^17.0.0 languageName: unknown @@ -8909,11 +8907,11 @@ __metadata: "@backstage/test-utils": "workspace:^" "@backstage/theme": "workspace:^" "@backstage/types": "workspace:^" - "@material-ui/core": ^4.9.13 + "@material-ui/core": ^4.12.4 "@material-ui/icons": ^4.9.1 "@material-ui/lab": ^4.0.0-alpha.61 - "@testing-library/jest-dom": ^5.10.1 - "@testing-library/react": ^12.1.3 + "@testing-library/jest-dom": ^6.0.0 + "@testing-library/react": ^14.0.0 "@testing-library/user-event": ^14.0.0 jest-websocket-mock: ^2.5.0 msw: ^1.0.0 @@ -17216,22 +17214,6 @@ __metadata: languageName: unknown linkType: soft -"@testing-library/dom@npm:^8.0.0": - version: 8.20.1 - resolution: "@testing-library/dom@npm:8.20.1" - dependencies: - "@babel/code-frame": ^7.10.4 - "@babel/runtime": ^7.12.5 - "@types/aria-query": ^5.0.1 - aria-query: 5.1.3 - chalk: ^4.1.0 - dom-accessibility-api: ^0.5.9 - lz-string: ^1.5.0 - pretty-format: ^27.0.2 - checksum: 06fc8dc67849aadb726cbbad0e7546afdf8923bd39acb64c576d706249bd7d0d05f08e08a31913fb621162e3b9c2bd0dce15964437f030f9fa4476326fdd3007 - languageName: node - linkType: hard - "@testing-library/dom@npm:^9.0.0": version: 9.3.3 resolution: "@testing-library/dom@npm:9.3.3" @@ -17248,23 +17230,6 @@ __metadata: languageName: node linkType: hard -"@testing-library/jest-dom@npm:^5.10.1": - version: 5.17.0 - resolution: "@testing-library/jest-dom@npm:5.17.0" - dependencies: - "@adobe/css-tools": ^4.0.1 - "@babel/runtime": ^7.9.2 - "@types/testing-library__jest-dom": ^5.9.1 - aria-query: ^5.0.0 - chalk: ^3.0.0 - css.escape: ^1.5.1 - dom-accessibility-api: ^0.5.6 - lodash: ^4.17.15 - redent: ^3.0.0 - checksum: 9f28dbca8b50d7c306aae40c3aa8e06f0e115f740360004bd87d57f95acf7ab4b4f4122a7399a76dbf2bdaaafb15c99cc137fdcb0ae457a92e2de0f3fbf9b03b - languageName: node - linkType: hard - "@testing-library/jest-dom@npm:^6.0.0": version: 6.1.6 resolution: "@testing-library/jest-dom@npm:6.1.6" @@ -17317,20 +17282,6 @@ __metadata: languageName: node linkType: hard -"@testing-library/react@npm:^12.1.3": - version: 12.1.5 - resolution: "@testing-library/react@npm:12.1.5" - dependencies: - "@babel/runtime": ^7.12.5 - "@testing-library/dom": ^8.0.0 - "@types/react-dom": <18.0.0 - peerDependencies: - react: <18.0.0 - react-dom: <18.0.0 - checksum: 4abd0490405e709a7df584a0db604e508a4612398bb1326e8fa32dd9393b15badc826dcf6d2f7525437886d507871f719f127b9860ed69ddd204d1fa834f576a - languageName: node - linkType: hard - "@testing-library/react@npm:^14.0.0": version: 14.1.2 resolution: "@testing-library/react@npm:14.1.2" From e85aa989defcf5bd93c787e2f79c39d0ab321c48 Mon Sep 17 00:00:00 2001 From: zcmander Date: Fri, 22 Dec 2023 10:02:39 +0200 Subject: [PATCH 037/283] backend-test-utils: drop database in shutdown Signed-off-by: zcmander --- .changeset/fifty-files-argue.md | 6 ++ packages/backend-common/api-report.md | 6 ++ .../src/database/connection.test.ts | 78 ++++++++++++++++++- .../backend-common/src/database/connection.ts | 16 ++++ .../src/database/connectors/mysql.ts | 35 +++++++++ .../src/database/connectors/postgres.ts | 19 +++++ packages/backend-common/src/database/index.ts | 6 +- packages/backend-common/src/database/types.ts | 2 + .../src/database/TestDatabases.ts | 60 ++++++++++---- .../backend-test-utils/src/database/types.ts | 2 + 10 files changed, 211 insertions(+), 19 deletions(-) create mode 100644 .changeset/fifty-files-argue.md diff --git a/.changeset/fifty-files-argue.md b/.changeset/fifty-files-argue.md new file mode 100644 index 0000000000..b80b2989af --- /dev/null +++ b/.changeset/fifty-files-argue.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-test-utils': minor +'@backstage/backend-common': minor +--- + +drop databases after unit tests if the database instance is not running in docker diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index e7d89c2aa5..2255513d91 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -276,6 +276,12 @@ export class DockerContainerRunner implements ContainerRunner { runContainer(options: RunContainerOptions): Promise; } +// @public +export function dropDatabase( + dbConfig: Config, + ...databases: Array +): Promise; + // @public export function ensureDatabaseExists( dbConfig: Config, diff --git a/packages/backend-common/src/database/connection.test.ts b/packages/backend-common/src/database/connection.test.ts index caf2fccc30..3028d46cae 100644 --- a/packages/backend-common/src/database/connection.test.ts +++ b/packages/backend-common/src/database/connection.test.ts @@ -19,10 +19,11 @@ import { createDatabaseClient, createNameOverride, createSchemaOverride, + dropDatabase, ensureSchemaExists, parseConnectionString, } from './connection'; -import { pgConnector } from './connectors'; +import { mysqlConnector, pgConnector } from './connectors'; const mocked = (f: Function) => f as jest.Mock; @@ -30,8 +31,13 @@ jest.mock('./connectors', () => { const connectors = jest.requireActual('./connectors'); return { ...connectors, + mysqlConnector: { + ...connectors.mysqlConnector, + dropDatabase: jest.fn(), + }, pgConnector: { ...connectors.pgConnector, + dropDatabase: jest.fn(), ensureSchemaExists: jest.fn(), }, }; @@ -229,4 +235,74 @@ describe('database connection', () => { ).resolves.toBeUndefined(); }); }); + + describe('dropDatabase', () => { + it('returns successfully with pg client', async () => { + await dropDatabase( + new ConfigReader({ + client: 'pg', + schema: 'catalog', + connection: 'postgresql://testuser:testpass@acme:5432/userdbname', + }), + 'backstage_plugin_foobar', + ); + + const mockCalls = mocked( + pgConnector.dropDatabase as Function, + ).mock.calls.splice(-1); + const [baseConfig, databaseName] = mockCalls[0]; + + expect(baseConfig.get()).toMatchObject({ + client: 'pg', + connection: 'postgresql://testuser:testpass@acme:5432/userdbname', + }); + + expect(databaseName).toEqual('backstage_plugin_foobar'); + }); + + it('returns successfully with mysql client', async () => { + await dropDatabase( + new ConfigReader({ + client: 'mysql2', + connection: { + host: '127.0.0.1', + user: 'foo', + password: 'bar', + database: 'dbname', + }, + }), + 'backstage_plugin_foobar', + ); + + const mockCalls = mocked( + mysqlConnector.dropDatabase as Function, + ).mock.calls.splice(-1); + const [baseConfig, databaseName] = mockCalls[0]; + + expect(baseConfig.get()).toMatchObject({ + client: 'mysql2', + connection: { + host: '127.0.0.1', + user: 'foo', + password: 'bar', + database: 'dbname', + }, + }); + + expect(databaseName).toEqual('backstage_plugin_foobar'); + }); + + it('does nothing in other database drivers', () => { + return expect( + dropDatabase( + new ConfigReader({ + client: 'better-sqlite3', + schema: 'catalog', + connection: ':memory:', + }), + 'catalog', + ), + ).resolves.toBeUndefined(); + }); + }); }); diff --git a/packages/backend-common/src/database/connection.ts b/packages/backend-common/src/database/connection.ts index e369323e04..c0e031516f 100644 --- a/packages/backend-common/src/database/connection.ts +++ b/packages/backend-common/src/database/connection.ts @@ -95,6 +95,22 @@ export async function ensureDatabaseExists( ); } +/** + * Drops the given databases. + * + * @public + */ +export async function dropDatabase( + dbConfig: Config, + ...databases: Array +): Promise { + const client: DatabaseClient = dbConfig.getString('client'); + + return await ddlLimiter(() => + ConnectorMapping[client]?.dropDatabase?.(dbConfig, ...databases), + ); +} + /** * Ensures that the given schemas all exist, creating them if they do not. * diff --git a/packages/backend-common/src/database/connectors/mysql.ts b/packages/backend-common/src/database/connectors/mysql.ts index 16610dd920..a4bac3f7e1 100644 --- a/packages/backend-common/src/database/connectors/mysql.ts +++ b/packages/backend-common/src/database/connectors/mysql.ts @@ -183,6 +183,40 @@ export async function ensureMysqlDatabaseExists( } } +/** + * Drops the given mysql databases. + * + * @param dbConfig - The database config + * @param databases - The names of the databases to create + */ +export async function dropMysqlDatabase( + dbConfig: Config, + ...databases: Array +) { + const admin = createMysqlDatabaseClient(dbConfig, { + connection: { + database: null as unknown as string, + }, + pool: { + min: 0, + acquireTimeoutMillis: 10000, + }, + }); + + try { + const dropDatabase = async (database: string) => { + await admin.raw(`DROP DATABASE ??`, [database]); + }; + await Promise.all( + databases.map(async database => { + return await dropDatabase(database); + }), + ); + } finally { + await admin.destroy(); + } +} + /** * MySQL database connector. * @@ -193,4 +227,5 @@ export const mysqlConnector: DatabaseConnector = Object.freeze({ ensureDatabaseExists: ensureMysqlDatabaseExists, createNameOverride: defaultNameOverride, parseConnectionString: parseMysqlConnectionString, + dropDatabase: dropMysqlDatabase, }); diff --git a/packages/backend-common/src/database/connectors/postgres.ts b/packages/backend-common/src/database/connectors/postgres.ts index f132488e29..dc9b19f6ad 100644 --- a/packages/backend-common/src/database/connectors/postgres.ts +++ b/packages/backend-common/src/database/connectors/postgres.ts @@ -199,6 +199,24 @@ export async function ensurePgSchemaExists( } } +/** + * Drops the Postgres databases. + * + * @param dbConfig - The database config + * @param databases - The name of the databases to drop + */ +export async function dropPgDatabase( + dbConfig: Config, + ...databases: Array +) { + const admin = createPgDatabaseClient(dbConfig); + await Promise.all( + databases.map(async database => { + await admin.raw(`DROP DATABASE ??`, [database]); + }), + ); +} + /** * PostgreSQL database connector. * @@ -211,4 +229,5 @@ export const pgConnector: DatabaseConnector = Object.freeze({ createNameOverride: defaultNameOverride, createSchemaOverride: defaultSchemaOverride, parseConnectionString: parsePgConnectionString, + dropDatabase: dropPgDatabase, }); diff --git a/packages/backend-common/src/database/index.ts b/packages/backend-common/src/database/index.ts index 0dde1ec239..330429f0ef 100644 --- a/packages/backend-common/src/database/index.ts +++ b/packages/backend-common/src/database/index.ts @@ -20,7 +20,11 @@ export * from './DatabaseManager'; * Undocumented API surface from connection is being reduced for future deprecation. * Avoid exporting additional symbols. */ -export { createDatabaseClient, ensureDatabaseExists } from './connection'; +export { + createDatabaseClient, + ensureDatabaseExists, + dropDatabase, +} from './connection'; export type { PluginDatabaseManager } from './types'; export { isDatabaseConflictError } from './util'; diff --git a/packages/backend-common/src/database/types.ts b/packages/backend-common/src/database/types.ts index 621bcc676b..3e9832aec5 100644 --- a/packages/backend-common/src/database/types.ts +++ b/packages/backend-common/src/database/types.ts @@ -79,4 +79,6 @@ export interface DatabaseConnector { dbConfig: Config, ...schemas: Array ): Promise; + + dropDatabase?(dbConfig: Config, ...databases: Array): Promise; } diff --git a/packages/backend-test-utils/src/database/TestDatabases.ts b/packages/backend-test-utils/src/database/TestDatabases.ts index 1913075b1f..4ea8fe05d7 100644 --- a/packages/backend-test-utils/src/database/TestDatabases.ts +++ b/packages/backend-test-utils/src/database/TestDatabases.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { DatabaseManager } from '@backstage/backend-common'; +import { DatabaseManager, dropDatabase } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { randomBytes } from 'crypto'; import { Knex } from 'knex'; @@ -157,11 +157,13 @@ export class TestDatabases { } // Ensure that a unique logical database is created in the instance + const databaseName = `db${randomBytes(16).toString('hex')}`; const connection = await instance.databaseManager - .forPlugin(`db${randomBytes(16).toString('hex')}`) + .forPlugin(databaseName) .getClient(); instance.connections.push(connection); + instance.databaseNames.push(databaseName); return connection; } @@ -173,21 +175,30 @@ export class TestDatabases { if (envVarName) { const connectionString = process.env[envVarName]; if (connectionString) { - const databaseManager = DatabaseManager.fromConfig( - new ConfigReader({ - backend: { - database: { - knexConfig: properties.driver.includes('sqlite') - ? {} - : LARGER_POOL_CONFIG, - client: properties.driver, - connection: connectionString, - }, + const config = new ConfigReader({ + backend: { + database: { + knexConfig: properties.driver.includes('sqlite') + ? {} + : LARGER_POOL_CONFIG, + client: properties.driver, + connection: connectionString, }, - }), - ); + }, + }); + const databaseManager = DatabaseManager.fromConfig(config); + const databaseNames: Array = []; return { + dropDatabases: async () => { + await dropDatabase( + config.getConfig('backend.database'), + ...databaseNames.map( + databaseName => `backstage_plugin_${databaseName}`, + ), + ); + }, databaseManager, + databaseNames, connections: [], }; } @@ -226,10 +237,10 @@ export class TestDatabases { }, }), ); - return { stopContainer: stop, databaseManager, + databaseNames: [], connections: [], }; } @@ -256,6 +267,7 @@ export class TestDatabases { return { stopContainer: stop, databaseManager, + databaseNames: [], connections: [], }; } @@ -273,9 +285,9 @@ export class TestDatabases { }, }), ); - return { databaseManager, + databaseNames: [], connections: [], }; } @@ -284,7 +296,12 @@ export class TestDatabases { const instances = [...this.instanceById.values()]; this.instanceById.clear(); - for (const { stopContainer, connections, databaseManager } of instances) { + for (const { + stopContainer, + dropDatabases, + connections, + databaseManager, + } of instances) { for (const connection of connections) { try { await connection.destroy(); @@ -296,6 +313,15 @@ export class TestDatabases { } } + // If the database is not running in docker then drop the databases + try { + await dropDatabases?.(); + } catch (error) { + console.warn(`TestDatabases: Failed to drop databases`, { + error, + }); + } + try { await stopContainer?.(); } catch (error) { diff --git a/packages/backend-test-utils/src/database/types.ts b/packages/backend-test-utils/src/database/types.ts index 75c24dc725..77a0c4e960 100644 --- a/packages/backend-test-utils/src/database/types.ts +++ b/packages/backend-test-utils/src/database/types.ts @@ -43,8 +43,10 @@ export type TestDatabaseProperties = { export type Instance = { stopContainer?: () => Promise; + dropDatabases?: () => Promise; databaseManager: DatabaseManager; connections: Array; + databaseNames: Array; }; export const allDatabases: Record = From 71c6d7a0de7e50fa047ffae6942abc6b984ed798 Mon Sep 17 00:00:00 2001 From: Navya Govind Date: Tue, 2 Jan 2024 13:30:47 +0100 Subject: [PATCH 038/283] Add a fix for overflowing labels in owner picker in catalog + hover feature Signed-off-by: Navya Govind --- .changeset/empty-ligers-hang.md | 5 +++ .../EntityOwnerPicker/EntityOwnerPicker.tsx | 37 ++++++++++++------- 2 files changed, 29 insertions(+), 13 deletions(-) create mode 100644 .changeset/empty-ligers-hang.md diff --git a/.changeset/empty-ligers-hang.md b/.changeset/empty-ligers-hang.md new file mode 100644 index 0000000000..c17609712a --- /dev/null +++ b/.changeset/empty-ligers-hang.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Overflowing labels in OwnerPicker (Catalog) are now truncated. Hovering over them shows the full label diff --git a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx index ed22e126c5..1b6773662e 100644 --- a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx +++ b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx @@ -26,6 +26,7 @@ import { TextField, Typography, makeStyles, + Tooltip, } from '@material-ui/core'; import CheckBoxIcon from '@material-ui/icons/CheckBox'; import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank'; @@ -161,7 +162,10 @@ export const EntityOwnerPicker = (props?: EntityOwnerPickerProps) => { filterOptions={x => x} renderOption={(entity, { selected }) => { const isGroup = entity.kind.toLocaleLowerCase('en-US') === 'group'; - + const humanizedName = humanizeEntity( + entity, + humanizeEntityRef(entity, { defaultKind: entity.kind }), + ); return ( { } onClick={event => event.preventDefault()} label={ - - {isGroup ? ( - - ) : ( - - )} -   - {humanizeEntity( - entity, - humanizeEntityRef(entity, { defaultKind: entity.kind }), - )} - + + + {isGroup ? ( + + ) : ( + + )} +   + + {humanizedName} + + + } /> ); From 67ddf8d6d79e2d2e214411f2be8f2b2114039b02 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Wed, 3 Jan 2024 13:03:53 +0200 Subject: [PATCH 039/283] docs: fix example of signal api in README Signed-off-by: Heikki Hellgren --- plugins/signals/README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/plugins/signals/README.md b/plugins/signals/README.md index e70c1ef7d8..7b96da32f1 100644 --- a/plugins/signals/README.md +++ b/plugins/signals/README.md @@ -33,9 +33,12 @@ Now you can utilize the API from other plugins using the `@backstage/plugin-sign import { signalsApiRef } from '@backstage/plugin-signals-react'; const signals = useApi(signalsApiRef); -signals.subscribe('myplugin:topic', (message: JsonObject) => { - console.log(message); -}); +const { unsubscribe } = signals.subscribe( + 'myplugin:topic', + (message: JsonObject) => { + console.log(message); + }, +); // Remember to unsubscribe -signals.unsubscribe('myplugin:topic'); +unsubscribe(); ``` From 7bb31d5455c335a79f2190820b776a6e56da8952 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 15:11:04 +0000 Subject: [PATCH 040/283] chore(deps): update dependency aws-sdk-client-mock-jest to v3.0.1 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index 954435a662..0d21078b4c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20881,14 +20881,14 @@ __metadata: linkType: hard "aws-sdk-client-mock-jest@npm:^3.0.0": - version: 3.0.0 - resolution: "aws-sdk-client-mock-jest@npm:3.0.0" + version: 3.0.1 + resolution: "aws-sdk-client-mock-jest@npm:3.0.1" dependencies: "@types/jest": ^28.1.3 tslib: ^2.1.0 peerDependencies: - aws-sdk-client-mock: 3.0.0 - checksum: 83f49e1d048bf32bb88b6a2ac8b3d14761a14dd699adc7c0e4bd9397b4771dd3e23779ec180bf63c03be7e85b2322840373a4c4d9840722ab15d409d6f4e8bd1 + aws-sdk-client-mock: 3.0.1 + checksum: c5c72ae63c9d3862636b833c66ebc708a1c170ba1159508f9a1e56c8e71ba82f7f85a00e68148b72cc699ab3e7ce6945d29bfd23151ae62c3f78133d56585ddd languageName: node linkType: hard From 3a7deeef9208a776d70693c72518fea79f4647d4 Mon Sep 17 00:00:00 2001 From: Tommy Le Date: Thu, 4 Jan 2024 10:35:27 +0100 Subject: [PATCH 041/283] fix: api returns questions with relevant tags Signed-off-by: Tommy Le --- plugins/stack-overflow/src/api/StackOverflowClient.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/stack-overflow/src/api/StackOverflowClient.ts b/plugins/stack-overflow/src/api/StackOverflowClient.ts index f598f912bd..d2f95c5236 100644 --- a/plugins/stack-overflow/src/api/StackOverflowClient.ts +++ b/plugins/stack-overflow/src/api/StackOverflowClient.ts @@ -46,6 +46,7 @@ export class StackOverflowClient implements StackOverflowApi { }): Promise { const params = qs.stringify(options.requestParams, { addQueryPrefix: true, + arrayFormat: 'repeat', }); const response = await fetch(`${this.baseUrl}/questions${params}`); const data = await response.json(); From c1bc3318b48d43e1d39af72044cee488b83c5cf4 Mon Sep 17 00:00:00 2001 From: Tommy Le Date: Thu, 4 Jan 2024 10:41:33 +0100 Subject: [PATCH 042/283] add changeset Signed-off-by: Tommy Le --- .changeset/polite-meals-hug.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/polite-meals-hug.md diff --git a/.changeset/polite-meals-hug.md b/.changeset/polite-meals-hug.md new file mode 100644 index 0000000000..664f450c6d --- /dev/null +++ b/.changeset/polite-meals-hug.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-stack-overflow': patch +--- + +Fixes a bug that made the API return questions not related to the tags provided From 15b8c1c48dae385d2602bacd75e43d025f570581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Mauricio=20G=C3=B3mez=20P?= Date: Thu, 4 Jan 2024 08:09:17 -0500 Subject: [PATCH 043/283] Update plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jamie Klassen Signed-off-by: Andrés Mauricio Gómez P --- .../kubernetes-backend/src/service/KubernetesFetcher.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts b/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts index 966fda7ce5..04b3d098ca 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts @@ -813,7 +813,7 @@ describe('KubernetesFetcher', () => { expect(agent.options.rejectUnauthorized).toBe(false); }); - it('should use a x509 client cert authentication strategy to consume kubeapi when backstage-kubernetes-auth field is not provided and the authStrategy enables x509 client cert authentication - fetchObjectsForService', async () => { + it('fetchObjectsForService authenticates with k8s using x509 client cert from authentication strategy', async () => { worker.use( rest.get('https://localhost:9999/api/v1/pods', (req, res, ctx) => res( From 77c8c4ecfc445eb8813c30095da87fa43a00cc04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Mauricio=20G=C3=B3mez=20P?= Date: Thu, 4 Jan 2024 08:09:30 -0500 Subject: [PATCH 044/283] Update plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jamie Klassen Signed-off-by: Andrés Mauricio Gómez P --- .../kubernetes-backend/src/service/KubernetesFetcher.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts b/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts index 04b3d098ca..3b435fad74 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFetcher.test.ts @@ -862,7 +862,7 @@ describe('KubernetesFetcher', () => { expect(agent.options.key).toEqual(myKey); }); - it('should use a x509 client cert authentication strategy to consume kubeapi when backstage-kubernetes-auth field is not provided and the authStrategy enables x509 client cert authentication - fetchPodMetricsByNamespaces', async () => { + it('fetchPodMetricsByNamespaces authenticates with k8s using x509 client cert from authentication strategy', async () => { worker.use( rest.get( 'https://localhost:9999/api/v1/namespaces/:namespace/pods', From 73a5e1b0c563c9fac5ac066b20a5a73ca01c8146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Mauricio=20G=C3=B3mez=20P?= Date: Thu, 4 Jan 2024 08:18:07 -0500 Subject: [PATCH 045/283] Update plugins/kubernetes-backend/src/service/KubernetesFetcher.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jamie Klassen Signed-off-by: Andrés Mauricio Gómez P --- plugins/kubernetes-backend/src/service/KubernetesFetcher.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts b/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts index cf4e3f9440..8d8e8f4d97 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts @@ -220,7 +220,7 @@ export class KubernetesClientBasedFetcher implements KubernetesFetcher { if (this.isServiceAccountAuthentication(authProvider, clusterDetails)) { [url, requestInit] = this.fetchArgsInCluster(credential); } else if ( - this.isTokenOrClientCertificateAuthentication(authProvider, credential) + !this.isCredentialMissing(authProvider, credential) ) { [url, requestInit] = this.fetchArgs(clusterDetails, credential); } else { From 5e6f1706c1b8147b544e11073dd6e51b0deeda7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Mauricio=20G=C3=B3mez=20P?= Date: Thu, 4 Jan 2024 08:18:18 -0500 Subject: [PATCH 046/283] Update plugins/kubernetes-backend/src/service/KubernetesFetcher.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jamie Klassen Signed-off-by: Andrés Mauricio Gómez P Signed-off-by: Andres Mauricio Gomez P --- .../src/service/KubernetesFetcher.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts b/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts index 8d8e8f4d97..b7354d54d4 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFetcher.ts @@ -219,9 +219,7 @@ export class KubernetesClientBasedFetcher implements KubernetesFetcher { if (this.isServiceAccountAuthentication(authProvider, clusterDetails)) { [url, requestInit] = this.fetchArgsInCluster(credential); - } else if ( - !this.isCredentialMissing(authProvider, credential) - ) { + } else if (!this.isCredentialMissing(authProvider, credential)) { [url, requestInit] = this.fetchArgs(clusterDetails, credential); } else { return Promise.reject( @@ -255,14 +253,12 @@ export class KubernetesClientBasedFetcher implements KubernetesFetcher { ); } - private isTokenOrClientCertificateAuthentication( + private isCredentialMissing( authProvider: string, credential: KubernetesCredential, ) { return ( - credential.type === 'bearer token' || - credential.type === 'x509 client certificate' || - authProvider === 'localKubectlProxy' + authProvider !== 'localKubectlProxy' && credential.type === 'anonymous' ); } From db1054bb92eda59e50f47ea8dce05f015cc1b28b Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Thu, 4 Jan 2024 09:35:43 -0500 Subject: [PATCH 047/283] fix invocation of kubernetesAuthProvidersApi Pass token provider when authenticating via openID tokens. Signed-off-by: Jamie Klassen --- .changeset/six-melons-end.md | 5 +++ .../src/api/KubernetesBackendClient.test.ts | 39 +++++++++++++++++++ .../src/api/KubernetesBackendClient.ts | 12 +++++- 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 .changeset/six-melons-end.md diff --git a/.changeset/six-melons-end.md b/.changeset/six-melons-end.md new file mode 100644 index 0000000000..f139e49887 --- /dev/null +++ b/.changeset/six-melons-end.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-react': patch +--- + +Fixed a bug where the logs dialog and any other functionality depending on the proxy endpoint would fail for clusters configured with the OIDC auth provider. diff --git a/plugins/kubernetes-react/src/api/KubernetesBackendClient.test.ts b/plugins/kubernetes-react/src/api/KubernetesBackendClient.test.ts index fd999ab335..0535e404f6 100644 --- a/plugins/kubernetes-react/src/api/KubernetesBackendClient.test.ts +++ b/plugins/kubernetes-react/src/api/KubernetesBackendClient.test.ts @@ -448,6 +448,9 @@ describe('KubernetesBackendClient', () => { const response = await backendClient.proxy(request); await expect(response.json()).resolves.toStrictEqual(nsResponse); + expect(kubernetesAuthProvidersApi.getCredentials).toHaveBeenCalledWith( + 'oidc.okta', + ); }); it('hits the /proxy API with serviceAccount as auth provider', async () => { @@ -495,6 +498,42 @@ describe('KubernetesBackendClient', () => { const response = await backendClient.proxy(request); await expect(response.json()).resolves.toStrictEqual(nsResponse); + expect(kubernetesAuthProvidersApi.getCredentials).toHaveBeenCalledWith( + 'serviceAccount', + ); + }); + + it('ignores oidcTokenProvider for non-oidc auth provider', async () => { + worker.use( + rest.get( + 'http://localhost:1234/api/kubernetes/clusters', + (_, res, ctx) => + res( + ctx.json({ + items: [ + { + name: 'cluster-a', + authProvider: 'not oidc', + oidcTokenProvider: 'should be ignored', + }, + ], + }), + ), + ), + rest.get( + 'http://localhost:1234/api/kubernetes/proxy/api/v1/namespaces', + (_, res, ctx) => res(ctx.json([])), + ), + ); + + await backendClient.proxy({ + clusterName: 'cluster-a', + path: '/api/v1/namespaces', + }); + + expect(kubernetesAuthProvidersApi.getCredentials).toHaveBeenCalledWith( + 'not oidc', + ); }); it('hits /proxy api when signed in as a guest', async () => { diff --git a/plugins/kubernetes-react/src/api/KubernetesBackendClient.ts b/plugins/kubernetes-react/src/api/KubernetesBackendClient.ts index a769eb088d..461b1d1ffe 100644 --- a/plugins/kubernetes-react/src/api/KubernetesBackendClient.ts +++ b/plugins/kubernetes-react/src/api/KubernetesBackendClient.ts @@ -92,8 +92,13 @@ export class KubernetesBackendClient implements KubernetesApi { private async getCredentials( authProvider: string, + oidcTokenProvider?: string, ): Promise<{ token?: string }> { - return await this.kubernetesAuthProvidersApi.getCredentials(authProvider); + return await this.kubernetesAuthProvidersApi.getCredentials( + authProvider === 'oidc' + ? `${authProvider}.${oidcTokenProvider}` + : authProvider, + ); } async getObjectsByEntity( @@ -145,7 +150,10 @@ export class KubernetesBackendClient implements KubernetesApi { const { authProvider, oidcTokenProvider } = await this.getCluster( options.clusterName, ); - const kubernetesCredentials = await this.getCredentials(authProvider); + const kubernetesCredentials = await this.getCredentials( + authProvider, + oidcTokenProvider, + ); const url = `${await this.discoveryApi.getBaseUrl('kubernetes')}/proxy${ options.path }`; From 4d1ebeff985eda0ab0cae4728ce047eb26ff3284 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 5 Jan 2024 19:23:58 +0000 Subject: [PATCH 048/283] fix(deps): update dependency postcss to v8.4.33 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 15212e967e..5e3c2e4879 100644 --- a/yarn.lock +++ b/yarn.lock @@ -37330,13 +37330,13 @@ __metadata: linkType: hard "postcss@npm:^8.1.0, postcss@npm:^8.4.21, postcss@npm:^8.4.27": - version: 8.4.32 - resolution: "postcss@npm:8.4.32" + version: 8.4.33 + resolution: "postcss@npm:8.4.33" dependencies: nanoid: ^3.3.7 picocolors: ^1.0.0 source-map-js: ^1.0.2 - checksum: 220d9d0bf5d65be7ed31006c523bfb11619461d296245c1231831f90150aeb4a31eab9983ac9c5c89759a3ca8b60b3e0d098574964e1691673c3ce5c494305ae + checksum: 6f98b2af4b76632a3de20c4f47bf0e984a1ce1a531cf11adcb0b1d63a6cbda0aae4165e578b66c32ca4879038e3eaad386a6be725a8fb4429c78e3c1ab858fe9 languageName: node linkType: hard From bbea3b24177556b193c7734e2834567885ac2487 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 6 Jan 2024 10:31:35 +0000 Subject: [PATCH 049/283] fix(deps): update dependency openid-client to v5.6.4 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 15212e967e..60f6701715 100644 --- a/yarn.lock +++ b/yarn.lock @@ -35689,14 +35689,14 @@ __metadata: linkType: hard "openid-client@npm:^5.2.1, openid-client@npm:^5.3.0, openid-client@npm:^5.4.3": - version: 5.6.2 - resolution: "openid-client@npm:5.6.2" + version: 5.6.4 + resolution: "openid-client@npm:5.6.4" dependencies: jose: ^4.15.4 lru-cache: ^6.0.0 object-hash: ^2.2.0 oidc-token-hash: ^5.0.3 - checksum: e61bc7170bb53d9b50098476b68b72e07f93769caae8ae12ffb885c2dac5fb2fdf6de437a9eb29c5501f52b296f01c083de8d6f3500f2999fc863c9f9f5142fa + checksum: 69843f078dacbbc6bad6d65ca6689414ac73f095dfe2f8e606822e6cfc9d9cd7d0dfaf2649352eda604653806f0ea65326ad2d6266da897e4740ec93d26d21f6 languageName: node linkType: hard From 7233f57136e6b4445945a691e829c5271d052085 Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Fri, 15 Dec 2023 13:12:58 -0500 Subject: [PATCH 050/283] fix error message for unsupported serviceLocator Signed-off-by: Jamie Klassen --- .changeset/friendly-cheetahs-rescue.md | 6 ++++++ .../src/service/KubernetesBuilder.test.ts | 21 +++++++++++++++++++ .../src/service/KubernetesBuilder.ts | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 .changeset/friendly-cheetahs-rescue.md diff --git a/.changeset/friendly-cheetahs-rescue.md b/.changeset/friendly-cheetahs-rescue.md new file mode 100644 index 0000000000..4f54a022af --- /dev/null +++ b/.changeset/friendly-cheetahs-rescue.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +--- + +Fixed an issue where a misleading error message would be logged when an +unsupported service locator method was specified. diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts index 77d02a032a..5719a9392a 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts @@ -206,6 +206,7 @@ describe('KubernetesBuilder', () => { }); }); }); + describe('post /services/:serviceId', () => { it('happy path: lists kubernetes objects without auth in request body', async () => { const response = await request(app).post( @@ -780,4 +781,24 @@ metadata: }); }); }); + + it('fails when an unsupported serviceLocator type is specified', () => { + return expect(() => + startTestBackend({ + features: [ + mockServices.rootConfig.factory({ + data: { + kubernetes: { + serviceLocatorMethod: { type: 'unsupported' }, + clusterLocatorMethods: [{ type: 'config', clusters: [] }], + }, + }, + }), + import('@backstage/plugin-kubernetes-backend/alpha'), + ], + }), + ).rejects.toThrow( + 'Unsupported kubernetes.serviceLocatorMethod "unsupported"', + ); + }); }); diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts index c1ff4688e7..a4a577db85 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts @@ -288,7 +288,7 @@ export class KubernetesBuilder { break; default: throw new Error( - `Unsupported kubernetes.clusterLocatorMethod "${method}"`, + `Unsupported kubernetes.serviceLocatorMethod "${method}"`, ); } From d458e043c6210b3cd958fddfb4f22efd2b955c6f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 08:14:37 +0000 Subject: [PATCH 051/283] fix(deps): update dependency @keyv/redis to v2.8.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 53d8974d6c..da3995976a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12155,11 +12155,11 @@ __metadata: linkType: hard "@keyv/redis@npm:^2.5.3": - version: 2.8.0 - resolution: "@keyv/redis@npm:2.8.0" + version: 2.8.3 + resolution: "@keyv/redis@npm:2.8.3" dependencies: ioredis: ^5.3.2 - checksum: 753e18897bf8e1fed585357d85749c7a1689f5efc1eb7114e790bf760460f7f510d5e76da5cc742269949205c18aad3c58ce4f8ceef5db0ace4ee108833632ba + checksum: 4b8fa4baeab75aace0a8c5d02e30dfb87fa2e27236d8ce3577ff862c4efa2ae2f6d4c14b4933e08fd24fd2719a01d17ac596e20792a1d3c0c2af51a46ba48936 languageName: node linkType: hard From 108c28f5ba2fdc2539decc23e7cf21a36ea5ca0b Mon Sep 17 00:00:00 2001 From: Tommy Le Date: Tue, 9 Jan 2024 10:40:25 +0100 Subject: [PATCH 052/283] add test Signed-off-by: Tommy Le --- .../src/api/StackOverflowClient.test.ts | 46 +++++++++++++------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/plugins/stack-overflow/src/api/StackOverflowClient.test.ts b/plugins/stack-overflow/src/api/StackOverflowClient.test.ts index 6574771350..e5967b6d45 100644 --- a/plugins/stack-overflow/src/api/StackOverflowClient.test.ts +++ b/plugins/stack-overflow/src/api/StackOverflowClient.test.ts @@ -27,19 +27,34 @@ const backstageQuestions: StackOverflowQuestion[] = [ { title: 'What is it?', link: 'https://example.com:9191/questions/1', - tags: ['asdf'], + tags: ['backstage'], owner: { who: 'me' }, answer_count: 3, }, { title: 'Is it?', link: 'https://example.com:9191/questions/2', - tags: ['asdf'], + tags: ['backstage'], owner: { who: 'me' }, answer_count: 4, }, ]; +const vimQuestions: StackOverflowQuestion[] = [ + { + title: 'How do I exit vim?', + link: 'https://example.com:9191/questions/3', + tags: ['vim'], + owner: { who: 'me' }, + answer_count: 5, + }, +]; + +const questionMap: Record = { + backstage: backstageQuestions, + vim: vimQuestions, +}; + describe('StackOverflowClient', () => { setupRequestMockHandlers(server); @@ -48,19 +63,15 @@ describe('StackOverflowClient', () => { const setupHandlers = () => { server.use( rest.get(`${mockBaseUrl}/questions`, (req, res, ctx) => { - return res( - ctx.json({ - items: - req.url.searchParams.get('tagged') === 'backstage' - ? backstageQuestions - : [], - }), - ); + const taggedParam = req.url.searchParams.get('tagged'); + const questions = taggedParam ? questionMap[taggedParam] || [] : []; + + return res(ctx.json({ items: questions })); }), ); }; - it('list questions should return all questions', async () => { + it('list questions should return all questions with the provided tag', async () => { setupHandlers(); const client = StackOverflowClient.fromConfig( new ConfigReader({ @@ -70,10 +81,17 @@ describe('StackOverflowClient', () => { }), ); - const responseQuestions = await client.listQuestions({ + const bsQuestions = await client.listQuestions({ requestParams: { tagged: 'backstage' }, }); - expect(responseQuestions.length).toEqual(2); - expect(responseQuestions).toEqual(backstageQuestions); + + const vQuestions = await client.listQuestions({ + requestParams: { tagged: 'vim' }, + }); + + expect(bsQuestions.length).toEqual(2); + expect(bsQuestions).toEqual(backstageQuestions); + expect(vQuestions.length).toEqual(1); + expect(vQuestions).toEqual(vimQuestions); }); }); From cb0afaad2b30e4dbbe98a3317a9fe051f24b8908 Mon Sep 17 00:00:00 2001 From: R-Beck-2020 <78100403+R-Beck-2020@users.noreply.github.com> Date: Tue, 9 Jan 2024 12:31:41 +0000 Subject: [PATCH 053/283] Improved Azure DevOps support for mono-repos Signed-off-by: R-Beck-2020 <78100403+R-Beck-2020@users.noreply.github.com> --- .changeset/wicked-elephants-scream.md | 5 ++ .../src/hooks/useBuildRuns.test.tsx | 2 +- .../src/hooks/useGitTags.test.tsx | 2 +- .../src/hooks/usePullRequests.test.tsx | 2 +- .../azure-devops/src/hooks/useReadme.test.tsx | 2 +- .../getAnnotationValuesFromEntity.test.ts | 55 +++++++++++++++++- .../utils/getAnnotationValuesFromEntity.ts | 57 ++++++++++++------- 7 files changed, 98 insertions(+), 27 deletions(-) create mode 100644 .changeset/wicked-elephants-scream.md diff --git a/.changeset/wicked-elephants-scream.md b/.changeset/wicked-elephants-scream.md new file mode 100644 index 0000000000..ab3918afba --- /dev/null +++ b/.changeset/wicked-elephants-scream.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-azure-devops': minor +--- + +Prefer dev.azure.com/build-definition annotation when it is provided, as it is more specific than dev.azure.com/project-repo diff --git a/plugins/azure-devops/src/hooks/useBuildRuns.test.tsx b/plugins/azure-devops/src/hooks/useBuildRuns.test.tsx index 409602eec4..f9415aea55 100644 --- a/plugins/azure-devops/src/hooks/useBuildRuns.test.tsx +++ b/plugins/azure-devops/src/hooks/useBuildRuns.test.tsx @@ -99,7 +99,7 @@ describe('useBuildRuns', () => { renderHook(() => useBuildRuns(entity), { wrapper: Wrapper, }), - ).toThrow('Value for annotation "dev.azure.com/project" was not found'); + ).toThrow('"dev.azure.com" annotations are missing'); }); it('should return throw when annotation invalid', async () => { diff --git a/plugins/azure-devops/src/hooks/useGitTags.test.tsx b/plugins/azure-devops/src/hooks/useGitTags.test.tsx index 1a5620e16e..fc385697ea 100644 --- a/plugins/azure-devops/src/hooks/useGitTags.test.tsx +++ b/plugins/azure-devops/src/hooks/useGitTags.test.tsx @@ -103,7 +103,7 @@ describe('useGitTags', () => { renderHook(() => useGitTags(entity), { wrapper: Wrapper, }), - ).toThrow('Value for annotation "dev.azure.com/project" was not found'); + ).toThrow('"dev.azure.com" annotations are missing'); }); it('should return throw when annotation invalid', async () => { diff --git a/plugins/azure-devops/src/hooks/usePullRequests.test.tsx b/plugins/azure-devops/src/hooks/usePullRequests.test.tsx index 3e51c003e6..8fe6c6b312 100644 --- a/plugins/azure-devops/src/hooks/usePullRequests.test.tsx +++ b/plugins/azure-devops/src/hooks/usePullRequests.test.tsx @@ -102,7 +102,7 @@ describe('usePullRequests', () => { renderHook(() => usePullRequests(entity), { wrapper: Wrapper, }), - ).toThrow('Value for annotation "dev.azure.com/project" was not found'); + ).toThrow('"dev.azure.com" annotations are missing'); }); it('should return throw when annotation invalid', async () => { diff --git a/plugins/azure-devops/src/hooks/useReadme.test.tsx b/plugins/azure-devops/src/hooks/useReadme.test.tsx index ffc33c136b..76cf2cf0cf 100644 --- a/plugins/azure-devops/src/hooks/useReadme.test.tsx +++ b/plugins/azure-devops/src/hooks/useReadme.test.tsx @@ -81,7 +81,7 @@ describe('useReadme', () => { renderHook(() => useReadme(entity), { wrapper: Wrapper, }), - ).toThrow('Value for annotation "dev.azure.com/project" was not found'); + ).toThrow('"dev.azure.com" annotations are missing'); }); it('should return throw when annotation invalid', async () => { diff --git a/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.test.ts b/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.test.ts index c13dc526d8..58481ec388 100644 --- a/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.test.ts +++ b/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.test.ts @@ -140,7 +140,7 @@ describe('getAnnotationValuesFromEntity', () => { }); describe('with only project annotation', () => { - it('should should throw annotation not found error', () => { + it('should throw annotation not found error', () => { const entity: Entity = { apiVersion: 'backstage.io/v1alpha1', kind: 'Component', @@ -163,7 +163,7 @@ describe('getAnnotationValuesFromEntity', () => { }); describe('with only build-definition annotation', () => { - it('should should throw annotation not found error', () => { + it('should throw annotation not found error', () => { const entity: Entity = { apiVersion: 'backstage.io/v1alpha1', kind: 'Component', @@ -381,4 +381,55 @@ describe('getAnnotationValuesFromEntity', () => { ); }); }); + + describe('projectRepo and buildDefinition are provided', () => { + it('should return project, repo and buildDefinition', () => { + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'project-repo', + annotations: { + 'dev.azure.com/build-definition': 'buildDefinitionName', + 'dev.azure.com/project-repo': 'projectName/repoName', + }, + }, + }; + const values = getAnnotationValuesFromEntity(entity); + expect(values).toEqual({ + project: 'projectName', + repo: 'repoName', + definition: 'buildDefinitionName', + host: undefined, + org: undefined, + }); + }); + }); + + describe('project, projectRepo and buildDefinition are provided', () => { + it('should prefer project over project-repo.project and return no repo', () => { + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'project-repo', + annotations: { + 'dev.azure.com/project': 'projectName', + 'dev.azure.com/build-definition': 'buildDefinitionName', + 'dev.azure.com/project-repo': 'ignoredProject/repoName', + }, + }, + }; + const values = getAnnotationValuesFromEntity(entity); + expect(values).toEqual({ + project: 'projectName', + repo: undefined, + definition: 'buildDefinitionName', + host: undefined, + org: undefined, + }); + }); + }); }); diff --git a/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.ts b/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.ts index 83091fb155..66a9753da4 100644 --- a/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.ts +++ b/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.ts @@ -29,34 +29,49 @@ export function getAnnotationValuesFromEntity(entity: Entity): { host?: string; org?: string; } { - const { host, org } = getHostOrg(entity.metadata.annotations); - - const projectRepoValues = getProjectRepo(entity.metadata.annotations); - if (projectRepoValues.project && projectRepoValues.repo) { - return { - project: projectRepoValues.project, - repo: projectRepoValues.repo, - host, - org, - }; - } - + const hostOrg = getHostOrg(entity.metadata.annotations); + const projectRepo = getProjectRepo(entity.metadata.annotations); const project = entity.metadata.annotations?.[AZURE_DEVOPS_PROJECT_ANNOTATION]; - if (!project) { + const definition = + entity.metadata.annotations?.[AZURE_DEVOPS_BUILD_DEFINITION_ANNOTATION]; + + if (definition) { + if (project) { + return { + project, + definition, + ...hostOrg, + }; + } + if (projectRepo.project) { + return { + project: projectRepo.project, + repo: projectRepo.repo, + definition, + ...hostOrg, + }; + } throw new Error( `Value for annotation "${AZURE_DEVOPS_PROJECT_ANNOTATION}" was not found`, ); + } else { + if (projectRepo.project) { + return { + project: projectRepo.project, + repo: projectRepo.repo, + ...hostOrg, + }; + } + + if (project) { + throw new Error( + `Value for annotation "${AZURE_DEVOPS_BUILD_DEFINITION_ANNOTATION}" was not found`, + ); + } } - const definition = - entity.metadata.annotations?.[AZURE_DEVOPS_BUILD_DEFINITION_ANNOTATION]; - if (!definition) { - throw new Error( - `Value for annotation "${AZURE_DEVOPS_BUILD_DEFINITION_ANNOTATION}" was not found`, - ); - } - return { project, definition, host, org }; + throw new Error('"dev.azure.com" annotations are missing'); } function getProjectRepo(annotations?: Record): { From fe84198f47ef1e96043feac0f5c44fc7773dda80 Mon Sep 17 00:00:00 2001 From: AmbrishRamachandiran Date: Wed, 10 Jan 2024 17:57:33 +0530 Subject: [PATCH 054/283] Plugins page dropdown filter Signed-off-by: AmbrishRamachandiran --- microsite/src/pages/plugins/plugins.module.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsite/src/pages/plugins/plugins.module.scss b/microsite/src/pages/plugins/plugins.module.scss index 80ac60cf98..b0427c8f5c 100644 --- a/microsite/src/pages/plugins/plugins.module.scss +++ b/microsite/src/pages/plugins/plugins.module.scss @@ -100,7 +100,7 @@ } :global(.dropdown__label) { - font-size: 15px; + font-size: 14px; cursor: pointer; } From 8f90d69b3ba73ad5203357d7b4533afcbab74f7e Mon Sep 17 00:00:00 2001 From: AmbrishRamachandiran Date: Wed, 10 Jan 2024 18:20:49 +0530 Subject: [PATCH 055/283] Fixing frontend system docs Signed-off-by: AmbrishRamachandiran --- docs/frontend-system/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/index.md b/docs/frontend-system/index.md index 0dda44555c..201718f6d3 100644 --- a/docs/frontend-system/index.md +++ b/docs/frontend-system/index.md @@ -12,4 +12,4 @@ description: The Frontend System The new frontend system is in alpha, and only a few plugins support the system so far. We do not yet recommend migrating any apps to the new system. If you add support for the new system to your plugin, please do so under a `/alpha` sub-path export. -You can find an example app setup in [the `app-next` package](https://github.com/backstage/backstage/tree/master/packages/app-next). +You can find an example app setup in the [`app-next` package](https://github.com/backstage/backstage/tree/master/packages/app-next). From 8c9f3a1e19a8f2837875e0947e4e1eee4b1ec436 Mon Sep 17 00:00:00 2001 From: R-Beck-2020 <78100403+R-Beck-2020@users.noreply.github.com> Date: Wed, 10 Jan 2024 14:11:32 +0000 Subject: [PATCH 056/283] Add additional tests around isAzurePipelinesAvailable Signed-off-by: R-Beck-2020 <78100403+R-Beck-2020@users.noreply.github.com> --- plugins/azure-devops/src/plugin.test.ts | 82 ++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/plugins/azure-devops/src/plugin.test.ts b/plugins/azure-devops/src/plugin.test.ts index f23639798f..398b19700c 100644 --- a/plugins/azure-devops/src/plugin.test.ts +++ b/plugins/azure-devops/src/plugin.test.ts @@ -13,10 +13,90 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { azureDevOpsPlugin } from './plugin'; +import { Entity } from '@backstage/catalog-model'; +import { azureDevOpsPlugin, isAzurePipelinesAvailable } from './plugin'; describe('azure-devops', () => { it('should export plugin', () => { expect(azureDevOpsPlugin).toBeDefined(); }); + + describe('isAzurePipelinesAvailable', () => { + it('should be true when project-repo annotation is present', () => { + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'sample', + annotations: { + 'dev.azure.com/project-repo': 'projectName/repoName', + }, + }, + }; + expect(isAzurePipelinesAvailable(entity)).toBe(true); + }); + + it('should be true when project and build-definition annotation is present', () => { + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'sample', + annotations: { + 'dev.azure.com/project': 'projectName', + 'dev.azure.com/build-definition': 'buildDefinitionName', + }, + }, + }; + expect(isAzurePipelinesAvailable(entity)).toBe(true); + }); + + it('should be true when project-repo and build-definition annotation is present', () => { + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'sample', + annotations: { + 'dev.azure.com/project-repo': 'projectName/repoName', + 'dev.azure.com/build-definition': 'buildDefinitionName', + }, + }, + }; + expect(isAzurePipelinesAvailable(entity)).toBe(true); + }); + + it('should be false when only project annotation is present', () => { + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'sample', + annotations: { + 'dev.azure.com/project': 'projectName', + }, + }, + }; + expect(isAzurePipelinesAvailable(entity)).toBe(false); + }); + + it('should be false when only build-definition annotation is present', () => { + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'sample', + annotations: { + 'dev.azure.com/build-definition': 'buildDefinitionName', + }, + }, + }; + expect(isAzurePipelinesAvailable(entity)).toBe(false); + }); + }); }); From 353244d8399b16439f0614c0731bd1b44767a024 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 22 Dec 2023 13:22:32 -0600 Subject: [PATCH 057/283] Added note about Service Principals Signed-off-by: Andre Wanlin --- .changeset/cyan-bats-lick.md | 5 +++++ plugins/azure-devops-backend/README.md | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .changeset/cyan-bats-lick.md diff --git a/.changeset/cyan-bats-lick.md b/.changeset/cyan-bats-lick.md new file mode 100644 index 0000000000..0683d806b0 --- /dev/null +++ b/.changeset/cyan-bats-lick.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-azure-devops-backend': patch +--- + +Added a note about Service Principles diff --git a/plugins/azure-devops-backend/README.md b/plugins/azure-devops-backend/README.md index 2fe62c90eb..b529faf8a6 100644 --- a/plugins/azure-devops-backend/README.md +++ b/plugins/azure-devops-backend/README.md @@ -23,9 +23,9 @@ Configuration Details: - `AZURE_TOKEN` environment variable must be set to a [Personal Access Token](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=preview-page) with read access to both Code and Build - `organization` is your Azure DevOps Services (cloud) Organization name or for Azure DevOps Server (on-premise) this will be your Collection name -#### Multi Organization +#### Multi Organization & Service Principles -To support cases where you have multiple Azure DevOps organizations you will want to make sure to configure them in the `integrations.azure` section of your `app-config.yaml` as detailed in the [Azure DevOps Locations](https://backstage.io/docs/integrations/azure/locations) documentation. +To support cases where you have multiple Azure DevOps organizations and/or you want to use a Service Principle you will want to make sure to configure them in the `integrations.azure` section of your `app-config.yaml` as detailed in the [Azure DevOps Locations](https://backstage.io/docs/integrations/azure/locations) documentation. **Note:** You will still need to define the [configuration above](#configuration). From f7f61eb0ecd76c6305c079e5b504e1aebf1e6268 Mon Sep 17 00:00:00 2001 From: Peter Macdonald Date: Thu, 11 Jan 2024 13:04:47 +0100 Subject: [PATCH 058/283] added friendly warning under community contributed plugins Signed-off-by: Peter Macdonald --- microsite/src/pages/plugins/index.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/microsite/src/pages/plugins/index.tsx b/microsite/src/pages/plugins/index.tsx index 006b7d4807..54f0b3514e 100644 --- a/microsite/src/pages/plugins/index.tsx +++ b/microsite/src/pages/plugins/index.tsx @@ -151,6 +151,9 @@ const Plugins = () => { {showOtherPlugins && (

All Plugins

+

+ Friendly reminder: While we love the variety and contributions of our open source plugins, they haven't been fully vetted by the core Backstage team. We encourage you to exercise caution and do your due diligence before installing. Happy exploring! +

{plugins.otherPlugins .filter( From 732813fb634357367f09bcd894caf61d24265e6d Mon Sep 17 00:00:00 2001 From: Peter Macdonald Date: Thu, 11 Jan 2024 13:22:45 +0100 Subject: [PATCH 059/283] forgot to run prettier Signed-off-by: Peter Macdonald --- microsite/src/pages/plugins/index.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/microsite/src/pages/plugins/index.tsx b/microsite/src/pages/plugins/index.tsx index 54f0b3514e..2abdbabf4b 100644 --- a/microsite/src/pages/plugins/index.tsx +++ b/microsite/src/pages/plugins/index.tsx @@ -152,7 +152,10 @@ const Plugins = () => {

All Plugins

- Friendly reminder: While we love the variety and contributions of our open source plugins, they haven't been fully vetted by the core Backstage team. We encourage you to exercise caution and do your due diligence before installing. Happy exploring! + Friendly reminder: While we love the variety and contributions of + our open source plugins, they haven't been fully vetted by the + core Backstage team. We encourage you to exercise caution and do + your due diligence before installing. Happy exploring!

{plugins.otherPlugins From c4f43d5cc8996b0f8f884ace0682d1fa3158ff86 Mon Sep 17 00:00:00 2001 From: R-Beck-2020 <78100403+R-Beck-2020@users.noreply.github.com> Date: Thu, 11 Jan 2024 16:06:53 +0000 Subject: [PATCH 060/283] PR Feedback Signed-off-by: R-Beck-2020 <78100403+R-Beck-2020@users.noreply.github.com> --- .changeset/wicked-elephants-scream.md | 2 +- plugins/azure-devops/README.md | 19 +++++++++++++++++++ .../src/hooks/useBuildRuns.test.tsx | 2 +- .../src/hooks/useGitTags.test.tsx | 2 +- .../src/hooks/usePullRequests.test.tsx | 2 +- .../azure-devops/src/hooks/useReadme.test.tsx | 2 +- plugins/azure-devops/src/plugin.test.ts | 12 ++++++++++++ .../utils/getAnnotationValuesFromEntity.ts | 2 +- 8 files changed, 37 insertions(+), 6 deletions(-) diff --git a/.changeset/wicked-elephants-scream.md b/.changeset/wicked-elephants-scream.md index ab3918afba..820c8b5d97 100644 --- a/.changeset/wicked-elephants-scream.md +++ b/.changeset/wicked-elephants-scream.md @@ -2,4 +2,4 @@ '@backstage/plugin-azure-devops': minor --- -Prefer dev.azure.com/build-definition annotation when it is provided, as it is more specific than dev.azure.com/project-repo +Prefer `dev.azure.com/build-definition` annotation when it is provided, as it is more specific than `dev.azure.com/project-repo`. This can also be used as a filter for mono-repos. diff --git a/plugins/azure-devops/README.md b/plugins/azure-devops/README.md index d7335e54c8..f867fcfe75 100644 --- a/plugins/azure-devops/README.md +++ b/plugins/azure-devops/README.md @@ -61,6 +61,25 @@ spec: # ... ``` +#### Mono repos + +If you have multiple entities within a single repo, you will need to specify which pipelines belong to each entity. + +```yaml +dev.azure.com/project-repo: / +dev.azure.com/build-definition: +``` + +#### Pipeline in different project to repo + +If your pipeline is in a different project to the source code, you will need to specify this in the project annotation. + +```yaml +dev.azure.com/project-repo: / +dev.azure.com/build-definition: +dev.azure.com/project: +``` + #### Azure Pipelines Only If you are only using Azure Pipelines along with a different SCM tool then you can use the following two annotations to see Builds: diff --git a/plugins/azure-devops/src/hooks/useBuildRuns.test.tsx b/plugins/azure-devops/src/hooks/useBuildRuns.test.tsx index f9415aea55..e165236fe8 100644 --- a/plugins/azure-devops/src/hooks/useBuildRuns.test.tsx +++ b/plugins/azure-devops/src/hooks/useBuildRuns.test.tsx @@ -99,7 +99,7 @@ describe('useBuildRuns', () => { renderHook(() => useBuildRuns(entity), { wrapper: Wrapper, }), - ).toThrow('"dev.azure.com" annotations are missing'); + ).toThrow('Expected "dev.azure.com" annotations were not found'); }); it('should return throw when annotation invalid', async () => { diff --git a/plugins/azure-devops/src/hooks/useGitTags.test.tsx b/plugins/azure-devops/src/hooks/useGitTags.test.tsx index fc385697ea..1c07b8868e 100644 --- a/plugins/azure-devops/src/hooks/useGitTags.test.tsx +++ b/plugins/azure-devops/src/hooks/useGitTags.test.tsx @@ -103,7 +103,7 @@ describe('useGitTags', () => { renderHook(() => useGitTags(entity), { wrapper: Wrapper, }), - ).toThrow('"dev.azure.com" annotations are missing'); + ).toThrow('Expected "dev.azure.com" annotations were not found'); }); it('should return throw when annotation invalid', async () => { diff --git a/plugins/azure-devops/src/hooks/usePullRequests.test.tsx b/plugins/azure-devops/src/hooks/usePullRequests.test.tsx index 8fe6c6b312..65579a2adf 100644 --- a/plugins/azure-devops/src/hooks/usePullRequests.test.tsx +++ b/plugins/azure-devops/src/hooks/usePullRequests.test.tsx @@ -102,7 +102,7 @@ describe('usePullRequests', () => { renderHook(() => usePullRequests(entity), { wrapper: Wrapper, }), - ).toThrow('"dev.azure.com" annotations are missing'); + ).toThrow('Expected "dev.azure.com" annotations were not found'); }); it('should return throw when annotation invalid', async () => { diff --git a/plugins/azure-devops/src/hooks/useReadme.test.tsx b/plugins/azure-devops/src/hooks/useReadme.test.tsx index 76cf2cf0cf..fdb9080bba 100644 --- a/plugins/azure-devops/src/hooks/useReadme.test.tsx +++ b/plugins/azure-devops/src/hooks/useReadme.test.tsx @@ -81,7 +81,7 @@ describe('useReadme', () => { renderHook(() => useReadme(entity), { wrapper: Wrapper, }), - ).toThrow('"dev.azure.com" annotations are missing'); + ).toThrow('Expected "dev.azure.com" annotations were not found'); }); it('should return throw when annotation invalid', async () => { diff --git a/plugins/azure-devops/src/plugin.test.ts b/plugins/azure-devops/src/plugin.test.ts index 398b19700c..d69fed6bab 100644 --- a/plugins/azure-devops/src/plugin.test.ts +++ b/plugins/azure-devops/src/plugin.test.ts @@ -69,6 +69,18 @@ describe('azure-devops', () => { expect(isAzurePipelinesAvailable(entity)).toBe(true); }); + it('should be false when no annotations are present', () => { + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'sample', + }, + }; + expect(isAzurePipelinesAvailable(entity)).toBe(false); + }); + it('should be false when only project annotation is present', () => { const entity: Entity = { apiVersion: 'backstage.io/v1alpha1', diff --git a/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.ts b/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.ts index 66a9753da4..7533c473ed 100644 --- a/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.ts +++ b/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.ts @@ -71,7 +71,7 @@ export function getAnnotationValuesFromEntity(entity: Entity): { } } - throw new Error('"dev.azure.com" annotations are missing'); + throw new Error('Expected "dev.azure.com" annotations were not found'); } function getProjectRepo(annotations?: Record): { From f5c0586b44b1993c2a29585b183f8470898d0ffb Mon Sep 17 00:00:00 2001 From: R-Beck-2020 <78100403+R-Beck-2020@users.noreply.github.com> Date: Thu, 11 Jan 2024 20:13:52 +0000 Subject: [PATCH 061/283] Update .changeset/wicked-elephants-scream.md Co-authored-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com> Signed-off-by: R-Beck-2020 <78100403+R-Beck-2020@users.noreply.github.com> --- .changeset/wicked-elephants-scream.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/wicked-elephants-scream.md b/.changeset/wicked-elephants-scream.md index 820c8b5d97..f002a48ba8 100644 --- a/.changeset/wicked-elephants-scream.md +++ b/.changeset/wicked-elephants-scream.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-azure-devops': minor +'@backstage/plugin-azure-devops': patch --- Prefer `dev.azure.com/build-definition` annotation when it is provided, as it is more specific than `dev.azure.com/project-repo`. This can also be used as a filter for mono-repos. From 169e3ffc1fcdec3d2eef1b5f84cf488db814c4cc Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Fri, 12 Jan 2024 13:38:34 +0200 Subject: [PATCH 062/283] feat: move all signal handling to backend plugin Signed-off-by: Heikki Hellgren --- packages/backend/src/index.ts | 2 - packages/backend/src/plugins/signals.ts | 3 +- plugins/signals-backend/README.md | 5 +- plugins/signals-backend/api-report.md | 9 +- plugins/signals-backend/src/plugin.ts | 9 +- .../src/service/SignalManager.ts | 213 +++++++++++++++++ .../src/service/router.test.ts | 15 +- plugins/signals-backend/src/service/router.ts | 13 +- .../src/service/standaloneServer.ts | 39 ++- plugins/signals-node/README.md | 34 ++- plugins/signals-node/api-report.md | 46 +--- .../signals-node/src/DefaultSignalService.ts | 222 ++---------------- plugins/signals-node/src/SignalService.ts | 24 +- plugins/signals-node/src/lib.ts | 10 +- plugins/signals-node/src/types.ts | 26 +- plugins/signals-react/README.md | 11 +- plugins/signals-react/api-report.md | 4 +- plugins/signals-react/src/api/SignalApi.ts | 2 +- plugins/signals-react/src/hooks/useSignal.ts | 6 +- plugins/signals/api-report.md | 2 +- plugins/signals/src/api/SignalClient.ts | 29 ++- plugins/signals/src/api/SignalsClient.test.ts | 26 +- 22 files changed, 392 insertions(+), 358 deletions(-) create mode 100644 plugins/signals-backend/src/service/SignalManager.ts diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 0e92698230..bade028597 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -101,9 +101,7 @@ function makeCreateEnv(config: Config) { const eventBroker = new DefaultEventBroker(root.child({ type: 'plugin' })); const signalService = DefaultSignalService.create({ - logger: root, eventBroker, - identity, }); root.info(`Created UrlReader ${reader}`); diff --git a/packages/backend/src/plugins/signals.ts b/packages/backend/src/plugins/signals.ts index 687fcfaa33..477cea1938 100644 --- a/packages/backend/src/plugins/signals.ts +++ b/packages/backend/src/plugins/signals.ts @@ -22,6 +22,7 @@ export default async function createPlugin( ): Promise { return await createRouter({ logger: env.logger, - service: env.signalService, + eventBroker: env.eventBroker, + identity: env.identity, }); } diff --git a/plugins/signals-backend/README.md b/plugins/signals-backend/README.md index f9ebfb80c7..e30a0836e0 100644 --- a/plugins/signals-backend/README.md +++ b/plugins/signals-backend/README.md @@ -20,7 +20,8 @@ export default async function createPlugin( ): Promise { return await createRouter({ logger: env.logger, - service: env.signalsService, + eventBroker: env.eventBroker, + identity: env.identity, }); } ``` @@ -29,7 +30,7 @@ Now add the signals to `packages/backend/src/index.ts`: ```ts // ... -import signals from './plugins/sonarqube'; +import signals from './plugins/signals'; async function main() { // ... diff --git a/plugins/signals-backend/api-report.md b/plugins/signals-backend/api-report.md index e96dd2e09c..dd46778e5d 100644 --- a/plugins/signals-backend/api-report.md +++ b/plugins/signals-backend/api-report.md @@ -4,9 +4,10 @@ ```ts import { BackendFeature } from '@backstage/backend-plugin-api'; +import { EventBroker } from '@backstage/plugin-events-node'; import express from 'express'; +import { IdentityApi } from '@backstage/plugin-auth-node'; import { LoggerService } from '@backstage/backend-plugin-api'; -import { SignalService } from '@backstage/plugin-signals-node'; // @public (undocumented) export function createRouter(options: RouterOptions): Promise; @@ -14,9 +15,11 @@ export function createRouter(options: RouterOptions): Promise; // @public (undocumented) export interface RouterOptions { // (undocumented) - logger: LoggerService; + eventBroker?: EventBroker; // (undocumented) - service: SignalService; + identity: IdentityApi; + // (undocumented) + logger: LoggerService; } // @public diff --git a/plugins/signals-backend/src/plugin.ts b/plugins/signals-backend/src/plugin.ts index 68bbf27377..4a9cef028f 100644 --- a/plugins/signals-backend/src/plugin.ts +++ b/plugins/signals-backend/src/plugin.ts @@ -18,7 +18,6 @@ import { createBackendPlugin, } from '@backstage/backend-plugin-api'; import { createRouter } from './service/router'; -import { signalService } from '@backstage/plugin-signals-node'; /** * Signals backend plugin @@ -32,13 +31,15 @@ export const signalsPlugin = createBackendPlugin({ deps: { httpRouter: coreServices.httpRouter, logger: coreServices.logger, - service: signalService, + identity: coreServices.identity, + // TODO: EventBroker. It is optional for now but it's actually required so waiting for the new backend system + // for the events-backend for this to work. }, - async init({ httpRouter, logger, service }) { + async init({ httpRouter, logger, identity }) { httpRouter.use( await createRouter({ logger, - service, + identity, }), ); }, diff --git a/plugins/signals-backend/src/service/SignalManager.ts b/plugins/signals-backend/src/service/SignalManager.ts new file mode 100644 index 0000000000..988db47465 --- /dev/null +++ b/plugins/signals-backend/src/service/SignalManager.ts @@ -0,0 +1,213 @@ +/* + * Copyright 2023 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 { EventBroker, EventParams } from '@backstage/plugin-events-node'; +import { SignalPayload } from '@backstage/plugin-signals-node'; +import { RawData, WebSocket, WebSocketServer } from 'ws'; +import { IncomingMessage } from 'http'; +import { v4 as uuid } from 'uuid'; +import { JsonObject } from '@backstage/types'; +import { + BackstageIdentityResponse, + IdentityApi, + IdentityApiGetIdentityRequest, +} from '@backstage/plugin-auth-node'; +import { LoggerService } from '@backstage/backend-plugin-api'; +import { Duplex } from 'stream'; + +/** @internal */ +export type ConnectionUpgradeOptions = { + request: IncomingMessage; + socket: Duplex; + head: Buffer; +}; + +/** + * @internal + */ +export type SignalConnection = { + id: string; + user: string; + ws: WebSocket; + ownershipEntityRefs: string[]; + subscriptions: Set; +}; + +/** + * @internal + */ +export type SignalManagerOptions = { + // TODO: Remove optional when events-backend can offer this service + eventBroker?: EventBroker; + logger: LoggerService; + identity: IdentityApi; +}; + +/** @internal */ +export class SignalManager { + private connections: Map = new Map< + string, + SignalConnection + >(); + private eventBroker?: EventBroker; + private logger: LoggerService; + private identity: IdentityApi; + private server: WebSocketServer; + + static create(options: SignalManagerOptions) { + return new SignalManager(options); + } + + private constructor(options: SignalManagerOptions) { + ({ + eventBroker: this.eventBroker, + logger: this.logger, + identity: this.identity, + } = options); + + this.server = new WebSocketServer({ + noServer: true, + clientTracking: false, + }); + + this.eventBroker?.subscribe({ + supportsEventTopics: () => ['signals'], + onEvent: (params: EventParams) => + this.onEventBrokerEvent(params), + }); + } + + /** + * Handles request upgrade to websocket and adds the connection to internal + * list for publish/subscribe functionality + * @param req - Request + */ + async handleUpgrade(options: ConnectionUpgradeOptions) { + const { request, socket, head } = options; + let identity: BackstageIdentityResponse | undefined = undefined; + + // Authentication token is passed in Sec-WebSocket-Protocol header as there + // is no other way to pass the token with plain websockets + const token = request.headers['sec-websocket-protocol']; + if (token) { + identity = await this.identity.getIdentity({ + request: { + headers: { authorization: token }, + }, + } as IdentityApiGetIdentityRequest); + } + + this.server.handleUpgrade( + request, + socket, + head, + (ws: WebSocket, __: IncomingMessage) => { + this.addConnection(ws, identity); + }, + ); + } + + private addConnection(ws: WebSocket, identity?: BackstageIdentityResponse) { + const id = uuid(); + + const conn = { + id, + user: identity?.identity.userEntityRef ?? 'user:default/guest', + ws, + ownershipEntityRefs: identity?.identity.ownershipEntityRefs ?? [], + subscriptions: new Set(), + }; + + this.connections.set(id, conn); + + ws.on('error', (err: Error) => { + this.logger.info( + `Error occurred with connection ${id}: ${err}, closing connection`, + ); + ws.close(); + this.connections.delete(id); + }); + + ws.on('close', (code: number, reason: Buffer) => { + this.logger.info( + `Connection ${id} closed with code ${code}, reason: ${reason}`, + ); + this.connections.delete(id); + }); + + ws.on('message', (data: RawData, isBinary: boolean) => { + this.logger.debug(`Received message from connection ${id}: ${data}`); + if (isBinary) { + return; + } + try { + const json = JSON.parse(data.toString()) as JsonObject; + this.handleMessage(conn, json); + } catch (err: any) { + this.logger.error( + `Invalid message received from connection ${id}: ${err}`, + ); + } + }); + } + + private handleMessage(connection: SignalConnection, message: JsonObject) { + if (message.action === 'subscribe' && message.channel) { + this.logger.info( + `Connection ${connection.id} subscribed to ${message.channel}`, + ); + connection.subscriptions.add(message.channel as string); + } else if (message.action === 'unsubscribe' && message.channel) { + this.logger.info( + `Connection ${connection.id} unsubscribed from ${message.channel}`, + ); + connection.subscriptions.delete(message.channel as string); + } + } + + private async onEventBrokerEvent( + params: EventParams, + ): Promise { + const { eventPayload } = params; + if (!eventPayload.channel || !eventPayload.message) { + return; + } + + const { channel, recipients, message } = eventPayload; + const jsonMessage = JSON.stringify({ channel, message }); + + // Actual websocket message sending + this.connections.forEach(conn => { + if (!conn.subscriptions.has(channel)) { + return; + } + // Sending to all users can be done with null + if ( + recipients !== null && + !conn.ownershipEntityRefs.some((ref: string) => + recipients.includes(ref), + ) + ) { + return; + } + + if (conn.ws.readyState !== WebSocket.OPEN) { + return; + } + + conn.ws.send(jsonMessage); + }); + } +} diff --git a/plugins/signals-backend/src/service/router.test.ts b/plugins/signals-backend/src/service/router.test.ts index 281d6ed4a5..ecf2ad4aa6 100644 --- a/plugins/signals-backend/src/service/router.test.ts +++ b/plugins/signals-backend/src/service/router.test.ts @@ -18,9 +18,17 @@ import express from 'express'; import request from 'supertest'; import { createRouter } from './router'; -import { DefaultSignalService } from '@backstage/plugin-signals-node'; +import { EventBroker } from '@backstage/plugin-events-node'; +import { IdentityApi } from '@backstage/plugin-auth-node'; -const signalsServiceMock: jest.Mocked = {} as any; +const eventBrokerMock: jest.Mocked = { + subscribe: jest.fn(), + publish: jest.fn(), +}; + +const identityApiMock: jest.Mocked = { + getIdentity: jest.fn(), +}; describe('createRouter', () => { let app: express.Express; @@ -28,7 +36,8 @@ describe('createRouter', () => { beforeAll(async () => { const router = await createRouter({ logger: getVoidLogger(), - service: signalsServiceMock, + identity: identityApiMock, + eventBroker: eventBrokerMock, }); app = express().use(router); }); diff --git a/plugins/signals-backend/src/service/router.ts b/plugins/signals-backend/src/service/router.ts index 28bafce14a..ec56860bf3 100644 --- a/plugins/signals-backend/src/service/router.ts +++ b/plugins/signals-backend/src/service/router.ts @@ -17,22 +17,27 @@ import { errorHandler } from '@backstage/backend-common'; import express, { NextFunction, Request, Response } from 'express'; import Router from 'express-promise-router'; import { LoggerService } from '@backstage/backend-plugin-api'; -import { SignalService } from '@backstage/plugin-signals-node'; import * as https from 'https'; import http from 'http'; +import { SignalManager } from './SignalManager'; +import { IdentityApi } from '@backstage/plugin-auth-node'; +import { EventBroker } from '@backstage/plugin-events-node'; /** @public */ export interface RouterOptions { logger: LoggerService; - service: SignalService; + eventBroker?: EventBroker; + identity: IdentityApi; } /** @public */ export async function createRouter( options: RouterOptions, ): Promise { - const { logger, service } = options; + const { logger } = options; + const manager = SignalManager.create(options); let subscribed = false; + const upgradeMiddleware = (req: Request, _: Response, next: NextFunction) => { const server: https.Server | http.Server = (req.socket as any)?.server; if ( @@ -50,7 +55,7 @@ export async function createRouter( server.on('upgrade', async (request, socket, head) => { // TODO: Find a way to make this more generic if (request.url === '/api/signals') { - await service.handleUpgrade({ server, request, socket, head }); + await manager.handleUpgrade({ request, socket, head }); } }); } diff --git a/plugins/signals-backend/src/service/standaloneServer.ts b/plugins/signals-backend/src/service/standaloneServer.ts index e1ce27aee4..278de8621e 100644 --- a/plugins/signals-backend/src/service/standaloneServer.ts +++ b/plugins/signals-backend/src/service/standaloneServer.ts @@ -23,6 +23,11 @@ import { Logger } from 'winston'; import { createRouter } from './router'; import { DefaultSignalService } from '@backstage/plugin-signals-node'; import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; +import { + EventBroker, + EventParams, + EventSubscriber, +} from '@backstage/plugin-events-node'; export interface ServerOptions { port: number; @@ -43,14 +48,26 @@ export async function startStandaloneServer( issuer: await discovery.getExternalBaseUrl('auth'), }); + const mockSubscribers: EventSubscriber[] = []; + const eventBroker: EventBroker = { + async publish(params: EventParams): Promise { + mockSubscribers.forEach(sub => sub.onEvent(params)); + }, + subscribe(...subscribers: EventSubscriber[]) { + subscribers.flat().forEach(subscriber => { + mockSubscribers.push(subscriber); + }); + }, + }; + const signals = DefaultSignalService.create({ - logger: logger, - identity, + eventBroker, }); const router = await createRouter({ logger, - service: signals, + identity, + eventBroker, }); let service = createServiceBuilder(module) @@ -60,10 +77,22 @@ export async function startStandaloneServer( service = service.enableCors({ origin: 'http://localhost:3000' }); } - return await service.start().catch(err => { + let server: Promise; + try { + server = service.start(); + + setInterval(() => { + signals.publish({ + recipients: null, + channel: 'test', + message: { hello: 'world' }, + }); + }, 5000); + } catch (err) { logger.error(err); process.exit(1); - }); + } + return server; } module.hot?.accept(); diff --git a/plugins/signals-node/README.md b/plugins/signals-node/README.md index 14c9332dc1..5e738a849d 100644 --- a/plugins/signals-node/README.md +++ b/plugins/signals-node/README.md @@ -27,10 +27,8 @@ function makeCreateEnv(config: Config) { // ... const eventBroker = new DefaultEventBroker(root.child({ type: 'plugin' })); - const signalService = SignalService.create({ - logger: root, - eventBroker, // EventBroker is optional - identity, + const signalService = DefaultSignalService.create({ + eventBroker, }); return (plugin: string): PluginEnvironment => { @@ -51,16 +49,38 @@ To allow connections from the frontend, you should also install the `@backstage/ Once you have both of the backend plugins installed, you can utilize the signal service by calling the `publish` method. This will publish the message to all subscribers in the frontend. To send message to -all subscribers, you can use `*` as `to` parameter. +all subscribers, you can use `null` as `recipients` parameter. ```ts // Periodic sending example setInterval(async () => { - await signalService.publish('*', 'plugin:topic', { - message: 'hello world', + await signalService.publish({ + recipients: null, + channel: 'my_plugin', + message: { + message: 'hello world', + }, }); }, 5000); ``` To receive this message in the frontend, check the documentation of `@backstage/plugin-signals` and `@backstage/plugin-signals-react`. + +## Using event broker directly + +Other way to send signals is to utilize the `EventBroker` directly. This requires that the payload is correct for it +to work: + +```ts +eventBroker.publish({ + topic: 'signals', + eventPayload: { + recipients: ['user:default/user1'], + message: { + message: 'hello world', + }, + channel: 'my_plugin', + }, +}); +``` diff --git a/plugins/signals-node/api-report.md b/plugins/signals-node/api-report.md index d85163040b..00d099f7db 100644 --- a/plugins/signals-node/api-report.md +++ b/plugins/signals-node/api-report.md @@ -3,63 +3,35 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -/// - -import { Duplex } from 'stream'; import { EventBroker } from '@backstage/plugin-events-node'; -import http from 'http'; -import https from 'https'; -import { IdentityApi } from '@backstage/plugin-auth-node'; -import { IncomingMessage } from 'http'; import { JsonObject } from '@backstage/types'; -import { LoggerService } from '@backstage/backend-plugin-api'; import { ServiceRef } from '@backstage/backend-plugin-api'; // @public (undocumented) export class DefaultSignalService implements SignalService { // (undocumented) - static create(options: ServiceOptions): DefaultSignalService; - handleUpgrade(options: SignalServiceUpgradeOptions): Promise; - publish( - to: string | string[], - topic: string, - message: JsonObject, - ): Promise; + static create(options: SignalServiceOptions): DefaultSignalService; + publish(signal: SignalPayload): Promise; } // @public (undocumented) -export type ServiceOptions = { - eventBroker?: EventBroker; - logger: LoggerService; - identity: IdentityApi; -}; - -// @public (undocumented) -export type SignalEventBrokerPayload = { - recipients?: string[]; - topic?: string; - message?: JsonObject; +export type SignalPayload = { + recipients: string[] | null; + channel: string; + message: JsonObject; }; // @public (undocumented) export type SignalService = { - publish( - to: string | string[], - topic: string, - message: JsonObject, - ): Promise; - handleUpgrade(options: SignalServiceUpgradeOptions): Promise; + publish(signal: SignalPayload): Promise; }; // @public (undocumented) export const signalService: ServiceRef; // @public (undocumented) -export type SignalServiceUpgradeOptions = { - server: https.Server | http.Server; - request: IncomingMessage; - socket: Duplex; - head: Buffer; +export type SignalServiceOptions = { + eventBroker?: EventBroker; }; // (No @packageDocumentation comment for this package) diff --git a/plugins/signals-node/src/DefaultSignalService.ts b/plugins/signals-node/src/DefaultSignalService.ts index cab6e83c81..1fba96b8bc 100644 --- a/plugins/signals-node/src/DefaultSignalService.ts +++ b/plugins/signals-node/src/DefaultSignalService.ts @@ -13,226 +13,38 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { EventBroker, EventParams } from '@backstage/plugin-events-node'; -import { - ServiceOptions, - SignalConnection, - SignalEventBrokerPayload, -} from './types'; -import { RawData, WebSocket, WebSocketServer } from 'ws'; -import { IncomingMessage } from 'http'; -import { v4 as uuid } from 'uuid'; -import { JsonObject } from '@backstage/types'; -import { - BackstageIdentityResponse, - IdentityApi, - IdentityApiGetIdentityRequest, -} from '@backstage/plugin-auth-node'; -import { LoggerService } from '@backstage/backend-plugin-api'; -import { SignalService, SignalServiceUpgradeOptions } from './SignalService'; +import { EventBroker } from '@backstage/plugin-events-node'; +import { SignalPayload, SignalServiceOptions } from './types'; +import { SignalService } from './SignalService'; /** @public */ export class DefaultSignalService implements SignalService { - private connections: Map = new Map< - string, - SignalConnection - >(); + // TODO: Remove this to be optional when events-backend has eventBroker as service private eventBroker?: EventBroker; - private logger: LoggerService; - private identity: IdentityApi; - private server: WebSocketServer; - static create(options: ServiceOptions) { + static create(options: SignalServiceOptions) { return new DefaultSignalService(options); } - private constructor(options: ServiceOptions) { - ({ - eventBroker: this.eventBroker, - logger: this.logger, - identity: this.identity, - } = options); - - this.server = new WebSocketServer({ - noServer: true, - clientTracking: false, - }); - - this.eventBroker?.subscribe({ - supportsEventTopics: () => ['signals'], - onEvent: (params: EventParams) => - this.onEventBrokerEvent(params), - }); - } - - /** - * Handles request upgrade to websocket and adds the connection to internal - * list for publish/subscribe functionality - * @param req - Request - */ - async handleUpgrade(options: SignalServiceUpgradeOptions) { - const { request, socket, head } = options; - let identity: BackstageIdentityResponse | undefined = undefined; - - // Authentication token is passed in Sec-WebSocket-Protocol header as there - // is no other way to pass the token with plain websockets - const token = request.headers['sec-websocket-protocol']; - if (token) { - identity = await this.identity.getIdentity({ - request: { - headers: { authorization: token }, - }, - } as IdentityApiGetIdentityRequest); - } - - this.server.handleUpgrade( - request, - socket, - head, - (ws: WebSocket, __: IncomingMessage) => { - this.addConnection(ws, identity); - }, - ); - } - - private addConnection(ws: WebSocket, identity?: BackstageIdentityResponse) { - const id = uuid(); - - const conn = { - id, - user: identity?.identity.userEntityRef ?? 'user:default/guest', - ws, - ownershipEntityRefs: identity?.identity.ownershipEntityRefs ?? [], - subscriptions: new Set(), - }; - - this.connections.set(id, conn); - - ws.on('error', (err: Error) => { - this.logger.info( - `Error occurred with connection ${id}: ${err}, closing connection`, - ); - ws.close(); - this.connections.delete(id); - }); - - ws.on('close', (code: number, reason: Buffer) => { - this.logger.info( - `Connection ${id} closed with code ${code}, reason: ${reason}`, - ); - this.connections.delete(id); - }); - - ws.on('message', (data: RawData, isBinary: boolean) => { - this.logger.debug(`Received message from connection ${id}: ${data}`); - if (isBinary) { - return; - } - try { - const json = JSON.parse(data.toString()) as JsonObject; - this.handleMessage(conn, json); - } catch (err: any) { - this.logger.error( - `Invalid message received from connection ${id}: ${err}`, - ); - } - }); - } - - private handleMessage(connection: SignalConnection, message: JsonObject) { - if (message.action === 'subscribe' && message.topic) { - this.logger.info( - `Connection ${connection.id} subscribed to ${message.topic}`, - ); - connection.subscriptions.add(message.topic as string); - } - - if (message.action === 'unsubscribe' && message.topic) { - this.logger.info( - `Connection ${connection.id} unsubscribed from ${message.topic}`, - ); - connection.subscriptions.delete(message.topic as string); - } + private constructor(options: SignalServiceOptions) { + ({ eventBroker: this.eventBroker } = options); } /** * Publishes a message to user refs to specific topic - * @param to - string or array of user ref strings to publish message to + * @param recipients - string or array of user ref strings to publish message to * @param topic - message topic * @param message - message to publish */ - async publish(to: string | string[], topic: string, message: JsonObject) { - await this.publishInternal( - Array.isArray(to) ? to : [to], - topic, - message, - false, - ); - } - - private async publishInternal( - recipients: string[], - topic: string, - message: JsonObject, - brokedEvent: boolean, - ) { - const jsonMessage = JSON.stringify({ topic, message }); - if (jsonMessage.length === 0) { - return; - } - - // If there is event broker, use that to publish the message to - // all signal services, including this one. - if (this.eventBroker && !brokedEvent) { - await this.eventBroker.publish({ - topic: 'signals', - eventPayload: { - recipients, - message, - topic, - }, - }); - return; - } - - // Actual websocket message sending - this.connections.forEach(conn => { - if (!conn.subscriptions.has(topic)) { - return; - } - // Sending to all users can be done with '*' - if ( - !recipients.includes('*') && - !conn.ownershipEntityRefs.some(ref => recipients.includes(ref)) - ) { - return; - } - - if (conn.ws.readyState !== WebSocket.OPEN) { - return; - } - - conn.ws.send(jsonMessage); + async publish(signal: SignalPayload) { + const { recipients, channel, message } = signal; + await this.eventBroker?.publish({ + topic: 'signals', + eventPayload: { + recipients, + message, + channel, + }, }); } - - private async onEventBrokerEvent( - params: EventParams, - ): Promise { - const { eventPayload } = params; - if ( - !eventPayload?.recipients || - !eventPayload.topic || - !eventPayload.message - ) { - return; - } - - await this.publishInternal( - eventPayload.recipients, - eventPayload.topic, - eventPayload.message, - true, - ); - } } diff --git a/plugins/signals-node/src/SignalService.ts b/plugins/signals-node/src/SignalService.ts index 7095c29858..f08a12661f 100644 --- a/plugins/signals-node/src/SignalService.ts +++ b/plugins/signals-node/src/SignalService.ts @@ -13,32 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { JsonObject } from '@backstage/types'; -import http, { IncomingMessage } from 'http'; -import { Duplex } from 'stream'; -import https from 'https'; - -/** @public */ -export type SignalServiceUpgradeOptions = { - server: https.Server | http.Server; - request: IncomingMessage; - socket: Duplex; - head: Buffer; -}; +import { SignalPayload } from './types'; /** @public */ export type SignalService = { /** * Publishes a message to user refs to specific topic */ - publish( - to: string | string[], - topic: string, - message: JsonObject, - ): Promise; - - /** - * Handles request upgrade - */ - handleUpgrade(options: SignalServiceUpgradeOptions): Promise; + publish(signal: SignalPayload): Promise; }; diff --git a/plugins/signals-node/src/lib.ts b/plugins/signals-node/src/lib.ts index c7e7c4a6ae..095a2f085d 100644 --- a/plugins/signals-node/src/lib.ts +++ b/plugins/signals-node/src/lib.ts @@ -14,7 +14,6 @@ * limitations under the License. */ import { - coreServices, createServiceFactory, createServiceRef, } from '@backstage/backend-plugin-api'; @@ -29,12 +28,11 @@ export const signalService = createServiceRef({ createServiceFactory({ service, deps: { - logger: coreServices.logger, - identity: coreServices.identity, - // TODO: EventBroker + // TODO: EventBroker. It is optional for now but it's actually required so waiting for the new backend system + // for the events-backend for this to work. }, - factory({ logger, identity }) { - return DefaultSignalService.create({ identity, logger }); + factory({}) { + return DefaultSignalService.create({}); }, }), }); diff --git a/plugins/signals-node/src/types.ts b/plugins/signals-node/src/types.ts index 6bfafae0b2..0220a196aa 100644 --- a/plugins/signals-node/src/types.ts +++ b/plugins/signals-node/src/types.ts @@ -13,35 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { IdentityApi } from '@backstage/plugin-auth-node'; import { EventBroker } from '@backstage/plugin-events-node'; -import { WebSocket } from 'ws'; import { JsonObject } from '@backstage/types'; -import { LoggerService } from '@backstage/backend-plugin-api'; /** * @public */ -export type ServiceOptions = { +export type SignalServiceOptions = { eventBroker?: EventBroker; - logger: LoggerService; - identity: IdentityApi; }; /** @public */ -export type SignalEventBrokerPayload = { - recipients?: string[]; - topic?: string; - message?: JsonObject; -}; - -/** - * @internal - */ -export type SignalConnection = { - id: string; - user: string; - ws: WebSocket; - ownershipEntityRefs: string[]; - subscriptions: Set; +export type SignalPayload = { + recipients: string[] | null; + channel: string; + message: JsonObject; }; diff --git a/plugins/signals-react/README.md b/plugins/signals-react/README.md index 244a4ec43d..4da9338866 100644 --- a/plugins/signals-react/README.md +++ b/plugins/signals-react/README.md @@ -22,10 +22,15 @@ Example of using the hook: ```ts import { useSignal } from '@backstage/plugin-signals-react'; -const { lastSignal } = useSignal('myplugin:topic'); +const { lastSignal } = useSignal('myplugin:channel'); + +useEffect(() => { + console.log(lastSignal); +}, [lastSignal]); ``` -Whenever backend publishes new message to the topic `myplugin:topic`, the lastSignal is changed. +Whenever backend publishes new message to the channel `myplugin:channel`, the `lastSignal` is changed. The `lastSignal` +is always initiated with null value before any messages are received from the backend. ## Using API directly @@ -37,7 +42,7 @@ import { signalsApiRef } from '@backstage/plugin-signals-react'; const signals = useApi(signalsApiRef); const { unsubscribe } = signals.subscribe( - 'myplugin:topic', + 'myplugin:channel', (message: JsonObject) => { console.log(message); }, diff --git a/plugins/signals-react/api-report.md b/plugins/signals-react/api-report.md index 8ad0c06fbe..2df2e4f1ce 100644 --- a/plugins/signals-react/api-report.md +++ b/plugins/signals-react/api-report.md @@ -9,7 +9,7 @@ import { JsonObject } from '@backstage/types'; // @public (undocumented) export type SignalApi = { subscribe( - topic: string, + channel: string, onMessage: (message: JsonObject) => void, ): { unsubscribe: () => void; @@ -20,7 +20,7 @@ export type SignalApi = { export const signalApiRef: ApiRef; // @public (undocumented) -export const useSignal: (topic: string) => { +export const useSignal: (channel: string) => { lastSignal: JsonObject | null; }; diff --git a/plugins/signals-react/src/api/SignalApi.ts b/plugins/signals-react/src/api/SignalApi.ts index 09eacafa4d..b37b3ae2f5 100644 --- a/plugins/signals-react/src/api/SignalApi.ts +++ b/plugins/signals-react/src/api/SignalApi.ts @@ -24,7 +24,7 @@ export const signalApiRef = createApiRef({ /** @public */ export type SignalApi = { subscribe( - topic: string, + channel: string, onMessage: (message: JsonObject) => void, ): { unsubscribe: () => void }; }; diff --git a/plugins/signals-react/src/hooks/useSignal.ts b/plugins/signals-react/src/hooks/useSignal.ts index 1176769a06..a7d50fbe3b 100644 --- a/plugins/signals-react/src/hooks/useSignal.ts +++ b/plugins/signals-react/src/hooks/useSignal.ts @@ -19,7 +19,7 @@ import { JsonObject } from '@backstage/types'; import { useEffect, useState } from 'react'; /** @public */ -export const useSignal = (topic: string) => { +export const useSignal = (channel: string) => { const apiHolder = useApiHolder(); // Use apiHolder instead useApi in case signalApi is not available in the // backstage instance this is used @@ -28,7 +28,7 @@ export const useSignal = (topic: string) => { useEffect(() => { let unsub: null | (() => void) = null; if (signals) { - const { unsubscribe } = signals.subscribe(topic, (msg: JsonObject) => { + const { unsubscribe } = signals.subscribe(channel, (msg: JsonObject) => { setLastSignal(msg); }); unsub = unsubscribe; @@ -38,7 +38,7 @@ export const useSignal = (topic: string) => { unsub(); } }; - }, [signals, topic]); + }, [signals, channel]); return { lastSignal }; }; diff --git a/plugins/signals/api-report.md b/plugins/signals/api-report.md index 97c882dda4..398d5fbfe6 100644 --- a/plugins/signals/api-report.md +++ b/plugins/signals/api-report.md @@ -24,7 +24,7 @@ export class SignalClient implements SignalApi { static readonly DEFAULT_RECONNECT_TIMEOUT_MS: number; // (undocumented) subscribe( - topic: string, + channel: string, onMessage: (message: JsonObject) => void, ): { unsubscribe: () => void; diff --git a/plugins/signals/src/api/SignalClient.ts b/plugins/signals/src/api/SignalClient.ts index 24a38a49e3..ee4ed8756b 100644 --- a/plugins/signals/src/api/SignalClient.ts +++ b/plugins/signals/src/api/SignalClient.ts @@ -19,7 +19,7 @@ import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; import { v4 as uuid } from 'uuid'; type Subscription = { - topic: string; + channel: string; callback: (message: JsonObject) => void; }; @@ -63,20 +63,23 @@ export class SignalClient implements SignalApi { ) {} subscribe( - topic: string, + channel: string, onMessage: (message: JsonObject) => void, ): { unsubscribe: () => void } { const subscriptionId = uuid(); const exists = [...this.subscriptions.values()].find( - sub => sub.topic === topic, + sub => sub.channel === channel, ); - this.subscriptions.set(subscriptionId, { topic, callback: onMessage }); + this.subscriptions.set(subscriptionId, { + channel: channel, + callback: onMessage, + }); this.connect() .then(() => { - // Do not subscribe twice to same topic even there is multiple callbacks + // Do not subscribe twice to same channel even there is multiple callbacks if (!exists) { - this.send({ action: 'subscribe', topic }); + this.send({ action: 'subscribe', channel }); } }) .catch(() => { @@ -90,12 +93,12 @@ export class SignalClient implements SignalApi { } this.subscriptions.delete(subscriptionId); const multipleExists = [...this.subscriptions.values()].find( - s => s.topic === topic, + s => s.channel === channel, ); - // If there are subscriptions still listening to this topic, do not + // If there are subscriptions still listening to this channel, do not // unsubscribe from the server if (!multipleExists) { - this.send({ action: 'unsubscribe', topic: sub.topic }); + this.send({ action: 'unsubscribe', channel: sub.channel }); } // If there are no subscriptions, close the connection @@ -176,9 +179,9 @@ export class SignalClient implements SignalApi { private handleMessage(data: MessageEvent) { try { const json = JSON.parse(data.data) as JsonObject; - if (json.topic) { + if (json.channel) { for (const sub of this.subscriptions.values()) { - if (sub.topic === json.topic) { + if (sub.channel === json.channel) { sub.callback(json.message as JsonObject); } } @@ -201,9 +204,9 @@ export class SignalClient implements SignalApi { this.ws = null; this.connect() .then(() => { - // Resubscribe to existing topics in case we lost connection + // Resubscribe to existing channels in case we lost connection for (const sub of this.subscriptions.values()) { - this.send({ action: 'subscribe', topic: sub.topic }); + this.send({ action: 'subscribe', channel: sub.channel }); } }) .catch(() => { diff --git a/plugins/signals/src/api/SignalsClient.test.ts b/plugins/signals/src/api/SignalsClient.test.ts index ec202e2703..2e93cd69f1 100644 --- a/plugins/signals/src/api/SignalsClient.test.ts +++ b/plugins/signals/src/api/SignalsClient.test.ts @@ -44,21 +44,21 @@ describe('SignalsClient', () => { it('should handle single subscription correctly', async () => { const messageMock = jest.fn(); const client = SignalClient.create({ discoveryApi, identity }); - const { unsubscribe } = client.subscribe('topic', messageMock); + const { unsubscribe } = client.subscribe('channel', messageMock); await server.connected; await expect(server).toReceiveMessage({ action: 'subscribe', - topic: 'topic', + channel: 'channel', }); - server.send({ topic: 'topic', message: { hello: 'world' } }); + server.send({ channel: 'channel', message: { hello: 'world' } }); expect(messageMock).toHaveBeenCalledWith({ hello: 'world' }); await unsubscribe(); await expect(server).toReceiveMessage({ action: 'unsubscribe', - topic: 'topic', + channel: 'channel', }); }); @@ -68,11 +68,11 @@ describe('SignalsClient', () => { const client1 = SignalClient.create({ discoveryApi, identity }); const client2 = SignalClient.create({ discoveryApi, identity }); const { unsubscribe: unsubscribe1 } = client1.subscribe( - 'topic', + 'channel', messageMock1, ); const { unsubscribe: unsubscribe2 } = client2.subscribe( - 'topic', + 'channel', messageMock2, ); @@ -80,22 +80,22 @@ describe('SignalsClient', () => { await expect(server).toReceiveMessage({ action: 'subscribe', - topic: 'topic', + channel: 'channel', }); - server.send({ topic: 'topic', message: { hello: 'world' } }); + server.send({ channel: 'channel', message: { hello: 'world' } }); expect(messageMock1).toHaveBeenCalledWith({ hello: 'world' }); expect(messageMock2).toHaveBeenCalledWith({ hello: 'world' }); await unsubscribe1(); await expect(server).not.toReceiveMessage({ action: 'unsubscribe', - topic: 'topic', + channel: 'channel', }); await unsubscribe2(); await expect(server).toReceiveMessage({ action: 'unsubscribe', - topic: 'topic', + channel: 'channel', }); }); @@ -108,11 +108,11 @@ describe('SignalsClient', () => { connectTimeout: 100, }); - client.subscribe('topic', messageMock); + client.subscribe('channel', messageMock); await server.connected; await expect(server).toReceiveMessage({ action: 'subscribe', - topic: 'topic', + channel: 'channel', }); await server.server.emit('error', null); @@ -120,7 +120,7 @@ describe('SignalsClient', () => { await new Promise(r => setTimeout(r, 50)); await expect(server).toReceiveMessage({ action: 'subscribe', - topic: 'topic', + channel: 'channel', }); }); }); From bb4089890b08acdfac308ccd1568d740b947160b Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 10 Jan 2024 19:27:34 +0100 Subject: [PATCH 063/283] core-components: add test for ProxiedSignInPage Signed-off-by: Patrik Oldsberg --- .changeset/strange-parents-hammer.md | 5 + packages/core-components/package.json | 1 + .../ProxiedSignInPage.test.tsx | 103 ++++++++++++++++++ packages/test-utils/api-report.md | 2 + .../test-utils/src/testUtils/appWrappers.tsx | 7 ++ yarn.lock | 1 + 6 files changed, 119 insertions(+) create mode 100644 .changeset/strange-parents-hammer.md create mode 100644 packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.test.tsx diff --git a/.changeset/strange-parents-hammer.md b/.changeset/strange-parents-hammer.md new file mode 100644 index 0000000000..57d5eeb83d --- /dev/null +++ b/.changeset/strange-parents-hammer.md @@ -0,0 +1,5 @@ +--- +'@backstage/test-utils': minor +--- + +Added `components` option to `TestAppOptions`, which will be forwarded as the `components` option to `createApp`. diff --git a/packages/core-components/package.json b/packages/core-components/package.json index 25d7fe111c..4c635b184c 100644 --- a/packages/core-components/package.json +++ b/packages/core-components/package.json @@ -92,6 +92,7 @@ "react-router-dom": "6.0.0-beta.0 || ^6.3.0" }, "devDependencies": { + "@backstage/app-defaults": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", "@backstage/test-utils": "workspace:^", diff --git a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.test.tsx b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.test.tsx new file mode 100644 index 0000000000..3f0c01b56b --- /dev/null +++ b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.test.tsx @@ -0,0 +1,103 @@ +/* + * 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 React from 'react'; +import { render, screen } from '@testing-library/react'; +import { rest } from 'msw'; +import { setupServer } from 'msw/node'; +import { + TestApiProvider, + setupRequestMockHandlers, + wrapInTestApp, +} from '@backstage/test-utils'; +import { ProxiedSignInPage } from './ProxiedSignInPage'; +import { discoveryApiRef } from '@backstage/core-plugin-api'; + +describe('ProxiedSignInPage', () => { + const worker = setupServer(); + setupRequestMockHandlers(worker); + + const Subject = wrapInTestApp(
authenticated
, { + components: { + SignInPage: props => ( + 'http://example.com/api/auth', + }, + ], + ]} + > + + + ), + }, + }); + + it('should sign in a user', async () => { + worker.use( + rest.get('http://example.com/api/auth/test/refresh', (_, res, ctx) => + res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + profile: { + email: 'e', + displayName: 'd', + picture: 'p', + }, + backstageIdentity: { + token: 'a.e30.c', + identity: { + type: 'user', + userEntityRef: 'k:ns/ue', + ownershipEntityRefs: ['k:ns/oe'], + }, + }, + }), + ), + ), + ); + + render(Subject); + + await expect( + screen.findByText('authenticated'), + ).resolves.toBeInTheDocument(); + }); + + it('should forward error', async () => { + worker.use( + rest.get('http://example.com/api/auth/test/refresh', (_, res, ctx) => + res( + ctx.status(401), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + error: { name: 'Error', message: 'not-displayed' }, + }), + ), + ), + ); + + render(Subject); + + await expect( + screen.findByText('Request failed with 401 Error'), + ).resolves.toBeInTheDocument(); + }); +}); diff --git a/packages/test-utils/api-report.md b/packages/test-utils/api-report.md index 913413acd1..e31a820a1c 100644 --- a/packages/test-utils/api-report.md +++ b/packages/test-utils/api-report.md @@ -7,6 +7,7 @@ import { AnalyticsApi } from '@backstage/core-plugin-api'; import { AnalyticsEvent } from '@backstage/core-plugin-api'; import { ApiHolder } from '@backstage/core-plugin-api'; import { ApiRef } from '@backstage/core-plugin-api'; +import { AppComponents } from '@backstage/core-plugin-api'; import { AuthorizeResult } from '@backstage/plugin-permission-common'; import { ComponentType } from 'react'; import { Config } from '@backstage/config'; @@ -243,6 +244,7 @@ export type TestAppOptions = { mountedRoutes?: { [path: string]: RouteRef | ExternalRouteRef; }; + components?: Partial; }; // @public diff --git a/packages/test-utils/src/testUtils/appWrappers.tsx b/packages/test-utils/src/testUtils/appWrappers.tsx index 8bc69e184a..f2c1ff592e 100644 --- a/packages/test-utils/src/testUtils/appWrappers.tsx +++ b/packages/test-utils/src/testUtils/appWrappers.tsx @@ -25,6 +25,7 @@ import { themes, UnifiedThemeProvider } from '@backstage/theme'; import MockIcon from '@material-ui/icons/AcUnit'; import { createSpecializedApp } from '@backstage/core-app-api'; import { + AppComponents, attachComponentData, BootErrorPageProps, createRouteRef, @@ -101,6 +102,11 @@ export type TestAppOptions = { * const link = useRouteRef(myRouteRef) */ mountedRoutes?: { [path: string]: RouteRef | ExternalRouteRef }; + + /** + * Components to be forwarded to the `components` option of `createApp`. + */ + components?: Partial; }; function isExternalRouteRef( @@ -137,6 +143,7 @@ export function createTestAppWrapper( Router: ({ children }) => ( ), + ...options.components, }, icons: mockIcons, plugins: [], diff --git a/yarn.lock b/yarn.lock index 6be53d3402..ba784c04d7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3921,6 +3921,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/core-components@workspace:packages/core-components" dependencies: + "@backstage/app-defaults": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/core-app-api": "workspace:^" From 187b30b1ce7e6610ba0816dc9839bb0f6c54d32a Mon Sep 17 00:00:00 2001 From: R-Beck-2020 <78100403+R-Beck-2020@users.noreply.github.com> Date: Fri, 12 Jan 2024 13:43:38 +0000 Subject: [PATCH 064/283] Additional review comments Signed-off-by: R-Beck-2020 <78100403+R-Beck-2020@users.noreply.github.com> --- plugins/azure-devops/README.md | 4 ++-- .../utils/getAnnotationValuesFromEntity.test.ts | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/plugins/azure-devops/README.md b/plugins/azure-devops/README.md index f867fcfe75..7119cb0980 100644 --- a/plugins/azure-devops/README.md +++ b/plugins/azure-devops/README.md @@ -75,9 +75,9 @@ dev.azure.com/build-definition: If your pipeline is in a different project to the source code, you will need to specify this in the project annotation. ```yaml -dev.azure.com/project-repo: / +dev.azure.com/project-repo: / dev.azure.com/build-definition: -dev.azure.com/project: +dev.azure.com/project: ``` #### Azure Pipelines Only diff --git a/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.test.ts b/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.test.ts index 58481ec388..94f179e8fb 100644 --- a/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.test.ts +++ b/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.test.ts @@ -18,6 +18,22 @@ import { Entity } from '@backstage/catalog-model'; import { getAnnotationValuesFromEntity } from './getAnnotationValuesFromEntity'; describe('getAnnotationValuesFromEntity', () => { + describe('without any annotations', () => { + it('should return ???', () => { + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'project-repo', + }, + }; + expect(() => getAnnotationValuesFromEntity(entity)).toThrow( + 'Expected "dev.azure.com" annotations were not found', + ); + }); + }); + describe('with valid project-repo annotation', () => { it('should return project and repo', () => { const entity: Entity = { From 9da4c78e628de0918682271f81c348dd408af787 Mon Sep 17 00:00:00 2001 From: R-Beck-2020 <78100403+R-Beck-2020@users.noreply.github.com> Date: Fri, 12 Jan 2024 13:48:42 +0000 Subject: [PATCH 065/283] Add missed file Signed-off-by: R-Beck-2020 <78100403+R-Beck-2020@users.noreply.github.com> --- .../src/utils/getAnnotationValuesFromEntity.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.test.ts b/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.test.ts index 94f179e8fb..9325a79039 100644 --- a/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.test.ts +++ b/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.test.ts @@ -19,7 +19,7 @@ import { getAnnotationValuesFromEntity } from './getAnnotationValuesFromEntity'; describe('getAnnotationValuesFromEntity', () => { describe('without any annotations', () => { - it('should return ???', () => { + it('should throw annotations not found', () => { const entity: Entity = { apiVersion: 'backstage.io/v1alpha1', kind: 'Component', From 87737a8155075a1bf4e31a9c340c3d26b042dec0 Mon Sep 17 00:00:00 2001 From: armandocomellas1 Date: Fri, 12 Jan 2024 16:09:42 -0600 Subject: [PATCH 066/283] Added config.getString() method to check if kubernetes.config has googleServiceAccount property Signed-off-by: armandocomellas1 --- docs/features/kubernetes/configuration.md | 13 +++++++++++++ .../src/cluster-locator/GkeClusterLocator.ts | 17 ++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md index 494e51320a..dc135b995d 100644 --- a/docs/features/kubernetes/configuration.md +++ b/docs/features/kubernetes/configuration.md @@ -341,6 +341,7 @@ For example: - type: 'gke' projectId: 'gke-clusters' region: 'europe-west1' # optional + authProvider: 'google' # optional skipTLSVerify: false # optional skipMetricsLookup: false # optional exposeDashboard: false # optional @@ -365,6 +366,18 @@ The Google Cloud project to look for Kubernetes clusters in. The Google Cloud region to look for Kubernetes clusters in. Defaults to all regions. +##### `authProvider` (optional) + +Set the authentication method for discovering clusters and gathering information +about resources. + +Defaults to `google` which leverages the logged in user's Google OAuth credentials. + +Set to `googleServiceAccount` to leverage +Application Default Credentials (https://cloud.google.com/docs/authentication/application-default-credentials). +To use a service account JSON key (not recommended), set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable +on the Backstage backend to the path of the service account key file. + ##### `skipTLSVerify` (optional) This determines whether the Kubernetes client verifies the TLS certificate diff --git a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts index 74e7ebc9af..a3b39f2b08 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts @@ -29,6 +29,7 @@ interface MatchResourceLabelEntry { type GkeClusterLocatorOptions = { projectId: string; + authProvider: string; region?: string; skipTLSVerify?: boolean; skipMetricsLookup?: boolean; @@ -54,8 +55,21 @@ export class GkeClusterLocator implements KubernetesClustersSupplier { return { key: mrl.getString('key'), value: mrl.getString('value') }; }) ?? []; + let storeAuthProviderString: string; + let getGkeProperty; + try { + getGkeProperty = config.getString('authProvider'); + } catch (err) { + getGkeProperty = 'google'; + } + if (getGkeProperty === 'googleServiceAccount') { + storeAuthProviderString = 'googleServiceAccount'; + } else { + storeAuthProviderString = 'google'; + } const options = { projectId: config.getString('projectId'), + authProvider: storeAuthProviderString, region: config.getOptionalString('region') ?? '-', skipTLSVerify: config.getOptionalBoolean('skipTLSVerify') ?? false, skipMetricsLookup: @@ -97,6 +111,7 @@ export class GkeClusterLocator implements KubernetesClustersSupplier { const { projectId, region, + authProvider, skipTLSVerify, skipMetricsLookup, exposeDashboard, @@ -121,7 +136,7 @@ export class GkeClusterLocator implements KubernetesClustersSupplier { // TODO filter out clusters which don't have name or endpoint name: r.name ?? 'unknown', url: `https://${r.endpoint ?? ''}`, - authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'google' }, + authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: authProvider }, skipTLSVerify, skipMetricsLookup, ...(exposeDashboard From 7278d80169bb9e9bf4f4c0491275b95a00bbe909 Mon Sep 17 00:00:00 2001 From: armandocomellas1 Date: Fri, 12 Jan 2024 18:53:19 -0600 Subject: [PATCH 067/283] Change add some lines in the script GkeClusterLocator.ts to make available login with googleServiceAccount Signed-off-by: armandocomellas1 --- .changeset/many-pugs-change.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/many-pugs-change.md diff --git a/.changeset/many-pugs-change.md b/.changeset/many-pugs-change.md new file mode 100644 index 0000000000..f16efb85aa --- /dev/null +++ b/.changeset/many-pugs-change.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +--- + +Change add some lines in the script GkeClusterLocator.ts, the implementation consist in adding a piece of code starts in 58 adding some config.getString() method to find out if the app-config.yaml kubernetes config includes the type of Auth as googleServiceAccount From 995d2809b818d34ddea8e30e717cedf979e99053 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Thu, 21 Dec 2023 20:08:08 -0600 Subject: [PATCH 068/283] Added new @backstage/no-top-level-mui4-imports rule Signed-off-by: Andre Wanlin --- .changeset/warm-maps-scream.md | 7 + .changeset/young-rules-repeat.md | 5 + docs/tutorials/migrate-to-mui5.md | 2 +- packages/eslint-plugin/README.md | 1 + .../docs/rules/no-top-level-mui4-imports.md | 43 ++++++ packages/eslint-plugin/index.js | 1 + .../rules/no-top-level-mui4-imports.js | 129 ++++++++++++++++++ .../src/no-top-level-mui4-imports.test.ts | 100 ++++++++++++++ plugins/azure-devops/.eslintrc.js | 6 +- .../AzureGitTagsIcon/AzureGitTagsIcon.tsx | 2 +- .../AzurePipelinesIcon/AzurePipelinesIcon.tsx | 2 +- .../AzurePullRequestsIcon.tsx | 2 +- .../src/components/BuildTable/BuildTable.tsx | 3 +- .../components/GitTagTable/GitTagTable.tsx | 2 +- .../PullRequestStatusButtonGroup.tsx | 3 +- .../PullRequestTable/PullRequestTable.tsx | 3 +- .../lib/PullRequestCard/PullRequestCard.tsx | 4 +- .../lib/PullRequestGrid/PullRequestGrid.tsx | 2 +- .../PullRequestGridColumn.tsx | 4 +- .../src/components/ReadmeCard/ReadmeCard.tsx | 4 +- plugins/devtools/.eslintrc.js | 6 +- .../Content/ConfigContent/ConfigContent.tsx | 10 +- .../ExternalDependenciesContent.tsx | 16 +-- .../Content/InfoContent/BackstageLogoIcon.tsx | 2 +- .../Content/InfoContent/InfoContent.tsx | 24 ++-- .../DevToolsLayout/DevToolsLayout.tsx | 2 +- plugins/linguist/.eslintrc.js | 6 +- .../components/LinguistCard/LinguistCard.tsx | 15 +- 28 files changed, 351 insertions(+), 55 deletions(-) create mode 100644 .changeset/warm-maps-scream.md create mode 100644 .changeset/young-rules-repeat.md create mode 100644 packages/eslint-plugin/docs/rules/no-top-level-mui4-imports.md create mode 100644 packages/eslint-plugin/rules/no-top-level-mui4-imports.js create mode 100644 packages/eslint-plugin/src/no-top-level-mui4-imports.test.ts diff --git a/.changeset/warm-maps-scream.md b/.changeset/warm-maps-scream.md new file mode 100644 index 0000000000..3ea5d93b03 --- /dev/null +++ b/.changeset/warm-maps-scream.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-azure-devops': patch +'@backstage/plugin-devtools': patch +'@backstage/plugin-linguist': patch +--- + +Updated imports from named to default imports to help with the Material UI v4 to v5 migration diff --git a/.changeset/young-rules-repeat.md b/.changeset/young-rules-repeat.md new file mode 100644 index 0000000000..5c9d790214 --- /dev/null +++ b/.changeset/young-rules-repeat.md @@ -0,0 +1,5 @@ +--- +'@backstage/eslint-plugin': patch +--- + +Added new `@backstage/no-top-level-mui4-imports` rule that forbids top level imports from Material UI v4 packages diff --git a/docs/tutorials/migrate-to-mui5.md b/docs/tutorials/migrate-to-mui5.md index 96129ceb8a..1b21c8b419 100644 --- a/docs/tutorials/migrate-to-mui5.md +++ b/docs/tutorials/migrate-to-mui5.md @@ -56,7 +56,7 @@ For current known issues with the Material UI v5 migration, follow our [Mileston To migrate your plugin to Material UI v5, you can build on the resources available. -1. Manually fix the imports from named to default imports to match the new [linting rules for minimizing bundle size](https://mui.com/material-ui/guides/minimizing-bundle-size). +1. Manually fix the imports from named to default imports to match the new [linting rules for minimizing bundle size](https://mui.com/material-ui/guides/minimizing-bundle-size). Note: you can use the [new `@backstage/no-top-level-mui4-imports` ESLint](https://github.com/backstage/backstage/blob/master/packages/eslint-plugin/docs/rules/no-top-level-mui4-imports.md) rule to help with this. 2. Run the migration `codemod` for the path of the specific plugin: `npx @mui/codemod v5.0.0/preset-safe plugins/`. 3. Take a look at possible `TODO:` items the `codemod` could not fix. 4. Remove types & methods from `@backstage/theme` which are marked as `@deprecated`. diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index c311670603..1304239caf 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -40,3 +40,4 @@ The following rules are provided by this plugin: | [@backstage/no-forbidden-package-imports](./docs/rules/no-forbidden-package-imports.md) | Disallow internal monorepo imports from package subpaths that are not exported. | | [@backstage/no-relative-monorepo-imports](./docs/rules/no-relative-monorepo-imports.md) | Forbid relative imports that reach outside of the package in a monorepo. | | [@backstage/no-undeclared-imports](./docs/rules/no-undeclared-imports.md) | Forbid imports of external packages that have not been declared in the appropriate dependencies field in `package.json`. | +| [@backstage/no-top-level-mui4-imports](./docs/rules/no-top-level-mui4-imports.md) | Forbid top level import from Material UI v4 packages. | diff --git a/packages/eslint-plugin/docs/rules/no-top-level-mui4-imports.md b/packages/eslint-plugin/docs/rules/no-top-level-mui4-imports.md new file mode 100644 index 0000000000..85f5821b01 --- /dev/null +++ b/packages/eslint-plugin/docs/rules/no-top-level-mui4-imports.md @@ -0,0 +1,43 @@ +# @backstage/no-top-level-mui4-imports + +Forbid top level import from Material UI v4 packages. + +## Usage + +Add the rules as follows, it has no options: + +```js +"@backstage/no-top-level-mui4-imports": ["error"] +``` + +## Rule Details + +TBD - Not sure what should go here + +### Fail + +```tsx +import { Box, Typography } from '@material-ui/core'; +``` + +```tsx +import Box from '@material-ui/core'; +``` + +```tsx +import { + Box, + DialogActions, + DialogContent, + DialogTitle, + Grid, + makeStyles, +} from '@material-ui/core'; +``` + +### Pass + +```tsx +import Typography from '@material-ui/core/Typography'; +import Box from '@material-ui/core/Box'; +``` diff --git a/packages/eslint-plugin/index.js b/packages/eslint-plugin/index.js index 20a0ff2d18..6fdc4f89fb 100644 --- a/packages/eslint-plugin/index.js +++ b/packages/eslint-plugin/index.js @@ -29,5 +29,6 @@ module.exports = { 'no-forbidden-package-imports': require('./rules/no-forbidden-package-imports'), 'no-relative-monorepo-imports': require('./rules/no-relative-monorepo-imports'), 'no-undeclared-imports': require('./rules/no-undeclared-imports'), + 'no-top-level-mui4-imports': require('./rules/no-top-level-mui4-imports'), }, }; diff --git a/packages/eslint-plugin/rules/no-top-level-mui4-imports.js b/packages/eslint-plugin/rules/no-top-level-mui4-imports.js new file mode 100644 index 0000000000..c3367a2346 --- /dev/null +++ b/packages/eslint-plugin/rules/no-top-level-mui4-imports.js @@ -0,0 +1,129 @@ +/* + * Copyright 2023 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. + */ + +// @ts-check + +const KNOWN_STYLES = [ + 'makeStyles', + 'withStyles', + 'createStyles', + 'styled', + 'useTheme', + 'Theme', +]; + +/** @type {import('eslint').Rule.RuleModule} */ +module.exports = { + meta: { + type: 'problem', + fixable: 'code', + messages: { + topLevelImport: 'Top level imports for Material UI are not allowed', + thirdLevelImport: + 'Third level or deeper imports for Material UI are not allowed', + }, + docs: { + description: 'Forbid top level import from Material UI v4 packages.', + url: 'https://github.com/backstage/backstage/blob/master/packages/eslint-plugin/docs/rules/no-top-level-mui4-imports.md', + }, + }, + create: context => ({ + ImportDeclaration: node => { + // Return if empty import + if (node.specifiers.length === 0) return; + // Return if empty source value + if (!node.source.value) return; + // Return if source value not a string + if (typeof node.source.value !== 'string') return; + // Return if import does not start with '@material-ui/' + if (!node.source.value.startsWith('@material-ui/')) return; + // Return if import is from '@material-ui/core/styles', as it's valid already + if (node.source.value === '@material-ui/core/styles') return; + // Return if import is from '@material-ui/core/SvgIcon', as it's valid already + if (node.source.value === '@material-ui/core/SvgIcon') return; + // Return if proper import eg. `import Box from '@material-ui/core/Box'` + if ( + node.specifiers.length === 1 && + node.source.value?.split('/').length === 3 + ) + return; + + // Report third level or deeper imports + if ( + node.specifiers.length === 1 && + node.source.value.split('/').length > 3 + ) { + context.report({ + node, + messageId: 'thirdLevelImport', + }); + return; + } + + // Report all other imports + context.report({ + node, + messageId: 'topLevelImport', + fix: fixer => { + const replacements = []; + const styles = []; + const svgIcon = []; + + const specifiers = node.specifiers.filter( + s => s.type === 'ImportSpecifier', + ); + + for (const specifier of specifiers) { + if (specifier.local.name === 'TabProps') { + replacements.push( + `import { TabProps } from '@material-ui/core/Tab';`, + ); + } else if ( + specifier.local.name === 'SvgIcon' || + specifier.local.name === 'SvgIconProps' + ) { + svgIcon.push(specifier.local.name); + } else if (KNOWN_STYLES.includes(specifier.local.name)) { + styles.push(specifier.local.name); + } else { + const replacement = `import ${specifier.local.name} from '${node.source.value}/${specifier.local.name}';`; + replacements.push(replacement); + } + } + + if (svgIcon.length > 0) { + if (svgIcon.every(s => ['SvgIcon', 'SvgIconProps'].includes(s))) { + replacements.push( + `import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';`, + ); + } + } + + if (styles.length > 0) { + const stylesReplacement = `import { ${styles.join( + ', ', + )} } from '@material-ui/core/styles';`; + replacements.push(stylesReplacement); + } + + const result = fixer.replaceText(node, replacements.join('\n')); + + return result; + }, + }); + }, + }), +}; diff --git a/packages/eslint-plugin/src/no-top-level-mui4-imports.test.ts b/packages/eslint-plugin/src/no-top-level-mui4-imports.test.ts new file mode 100644 index 0000000000..16605aa46f --- /dev/null +++ b/packages/eslint-plugin/src/no-top-level-mui4-imports.test.ts @@ -0,0 +1,100 @@ +/* + * Copyright 2023 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 { RuleTester } from 'eslint'; +import rule from '../rules/no-top-level-mui4-imports'; + +const ruleTester = new RuleTester({ + parserOptions: { + sourceType: 'module', + ecmaVersion: 2021, + }, +}); + +ruleTester.run('path-imports-rule', rule, { + valid: [ + { + code: `import Typography from '@material-ui/core/Typography';`, + }, + { + code: `import Box from '@material-ui/core/Box'`, + }, + { + code: `import { styled, withStyles } from '@material-ui/core/styles';`, + }, + { + code: `import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';`, + }, + ], + invalid: [ + { + code: `import { Box, Typography } from '@material-ui/core';`, + errors: [{ messageId: 'topLevelImport' }], + output: `import Box from '@material-ui/core/Box'; +import Typography from '@material-ui/core/Typography';`, + }, + { + code: `import { Box } from '@material-ui/core';`, + errors: [{ messageId: 'topLevelImport' }], + output: `import Box from '@material-ui/core/Box';`, + }, + { + code: `import { + Box, + DialogActions, + DialogContent, + DialogTitle, + Grid, + makeStyles, + } from '@material-ui/core';`, + errors: [{ messageId: 'topLevelImport' }], + output: `import Box from '@material-ui/core/Box'; +import DialogActions from '@material-ui/core/DialogActions'; +import DialogContent from '@material-ui/core/DialogContent'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import Grid from '@material-ui/core/Grid'; +import { makeStyles } from '@material-ui/core/styles';`, + }, + { + code: `import { TabIndicator } from '@material-ui/core/Tabs/TabIndicator';`, + errors: [{ messageId: 'thirdLevelImport' }], + }, + { + code: `import { Box, Button, makeStyles } from '@material-ui/core';`, + errors: [{ messageId: 'topLevelImport' }], + output: `import Box from '@material-ui/core/Box'; +import Button from '@material-ui/core/Button'; +import { makeStyles } from '@material-ui/core/styles';`, + }, + { + code: `import { Paper, Typography, styled, withStyles } from '@material-ui/core';`, + errors: [{ messageId: 'topLevelImport' }], + output: `import Paper from '@material-ui/core/Paper'; +import Typography from '@material-ui/core/Typography'; +import { styled, withStyles } from '@material-ui/core/styles';`, + }, + { + code: `import { styled } from '@material-ui/core';`, + errors: [{ messageId: 'topLevelImport' }], + output: `import { styled } from '@material-ui/core/styles';`, + }, + { + code: `import { TabProps } from '@material-ui/core';`, + errors: [{ messageId: 'topLevelImport' }], + output: `import { TabProps } from '@material-ui/core/Tab';`, + }, + ], +}); diff --git a/plugins/azure-devops/.eslintrc.js b/plugins/azure-devops/.eslintrc.js index e2a53a6ad2..9932358b45 100644 --- a/plugins/azure-devops/.eslintrc.js +++ b/plugins/azure-devops/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-mui4-imports': 'error', + }, +}); diff --git a/plugins/azure-devops/src/components/AzureGitTagsIcon/AzureGitTagsIcon.tsx b/plugins/azure-devops/src/components/AzureGitTagsIcon/AzureGitTagsIcon.tsx index c8b63e3259..0d317e3ce1 100644 --- a/plugins/azure-devops/src/components/AzureGitTagsIcon/AzureGitTagsIcon.tsx +++ b/plugins/azure-devops/src/components/AzureGitTagsIcon/AzureGitTagsIcon.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { SvgIcon, SvgIconProps } from '@material-ui/core'; +import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon'; import React from 'react'; diff --git a/plugins/azure-devops/src/components/AzurePipelinesIcon/AzurePipelinesIcon.tsx b/plugins/azure-devops/src/components/AzurePipelinesIcon/AzurePipelinesIcon.tsx index bd19331f6e..10cdb3a905 100644 --- a/plugins/azure-devops/src/components/AzurePipelinesIcon/AzurePipelinesIcon.tsx +++ b/plugins/azure-devops/src/components/AzurePipelinesIcon/AzurePipelinesIcon.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { SvgIcon, SvgIconProps } from '@material-ui/core'; +import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon'; import React from 'react'; diff --git a/plugins/azure-devops/src/components/AzurePullRequestsIcon/AzurePullRequestsIcon.tsx b/plugins/azure-devops/src/components/AzurePullRequestsIcon/AzurePullRequestsIcon.tsx index 99e3f74e90..e298f8bc25 100644 --- a/plugins/azure-devops/src/components/AzurePullRequestsIcon/AzurePullRequestsIcon.tsx +++ b/plugins/azure-devops/src/components/AzurePullRequestsIcon/AzurePullRequestsIcon.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { SvgIcon, SvgIconProps } from '@material-ui/core'; +import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon'; /** @public */ export const AzurePullRequestsIcon = (props: SvgIconProps) => ( diff --git a/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx b/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx index 6707929a6c..09eba5f5a2 100644 --- a/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx +++ b/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx @@ -14,7 +14,8 @@ * limitations under the License. */ -import { Box, Typography } from '@material-ui/core'; +import Box from '@material-ui/core/Box'; +import Typography from '@material-ui/core/Typography'; import { BuildResult, BuildRun, diff --git a/plugins/azure-devops/src/components/GitTagTable/GitTagTable.tsx b/plugins/azure-devops/src/components/GitTagTable/GitTagTable.tsx index c6abba55e1..f34a1929fe 100644 --- a/plugins/azure-devops/src/components/GitTagTable/GitTagTable.tsx +++ b/plugins/azure-devops/src/components/GitTagTable/GitTagTable.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { Box } from '@material-ui/core'; +import Box from '@material-ui/core/Box'; import { Link, ResponseErrorPanel, diff --git a/plugins/azure-devops/src/components/PullRequestStatusButtonGroup/PullRequestStatusButtonGroup.tsx b/plugins/azure-devops/src/components/PullRequestStatusButtonGroup/PullRequestStatusButtonGroup.tsx index f516bfb0e5..1b0b9a8afe 100644 --- a/plugins/azure-devops/src/components/PullRequestStatusButtonGroup/PullRequestStatusButtonGroup.tsx +++ b/plugins/azure-devops/src/components/PullRequestStatusButtonGroup/PullRequestStatusButtonGroup.tsx @@ -14,7 +14,8 @@ * limitations under the License. */ -import { Button, ButtonGroup } from '@material-ui/core'; +import Button from '@material-ui/core/Button'; +import ButtonGroup from '@material-ui/core/ButtonGroup'; import { PullRequestStatus } from '@backstage/plugin-azure-devops-common'; import React from 'react'; diff --git a/plugins/azure-devops/src/components/PullRequestTable/PullRequestTable.tsx b/plugins/azure-devops/src/components/PullRequestTable/PullRequestTable.tsx index b37ba6e73c..d672102945 100644 --- a/plugins/azure-devops/src/components/PullRequestTable/PullRequestTable.tsx +++ b/plugins/azure-devops/src/components/PullRequestTable/PullRequestTable.tsx @@ -14,7 +14,8 @@ * limitations under the License. */ -import { Box, Chip } from '@material-ui/core'; +import Box from '@material-ui/core/Box'; +import Chip from '@material-ui/core/Chip'; import { Link, ResponseErrorPanel, diff --git a/plugins/azure-devops/src/components/PullRequestsPage/lib/PullRequestCard/PullRequestCard.tsx b/plugins/azure-devops/src/components/PullRequestsPage/lib/PullRequestCard/PullRequestCard.tsx index 98237cb2a3..dd9fff86b5 100644 --- a/plugins/azure-devops/src/components/PullRequestsPage/lib/PullRequestCard/PullRequestCard.tsx +++ b/plugins/azure-devops/src/components/PullRequestsPage/lib/PullRequestCard/PullRequestCard.tsx @@ -15,7 +15,9 @@ */ import { Avatar, Link } from '@backstage/core-components'; -import { Card, CardContent, CardHeader } from '@material-ui/core'; +import Card from '@material-ui/core/Card'; +import CardContent from '@material-ui/core/CardContent'; +import CardHeader from '@material-ui/core/CardHeader'; import Typography from '@material-ui/core/Typography'; import { AutoCompleteIcon } from '../AutoCompleteIcon'; diff --git a/plugins/azure-devops/src/components/PullRequestsPage/lib/PullRequestGrid/PullRequestGrid.tsx b/plugins/azure-devops/src/components/PullRequestsPage/lib/PullRequestGrid/PullRequestGrid.tsx index 8b9c49beb4..0244ea3bb1 100644 --- a/plugins/azure-devops/src/components/PullRequestsPage/lib/PullRequestGrid/PullRequestGrid.tsx +++ b/plugins/azure-devops/src/components/PullRequestsPage/lib/PullRequestGrid/PullRequestGrid.tsx @@ -17,7 +17,7 @@ import { PullRequestGridColumn } from '../PullRequestGridColumn'; import { PullRequestGroup } from '../types'; import React from 'react'; -import { styled } from '@material-ui/core'; +import { styled } from '@material-ui/core/styles'; const GridDiv = styled('div')(({ theme }) => ({ display: 'flex', diff --git a/plugins/azure-devops/src/components/PullRequestsPage/lib/PullRequestGridColumn/PullRequestGridColumn.tsx b/plugins/azure-devops/src/components/PullRequestsPage/lib/PullRequestGridColumn/PullRequestGridColumn.tsx index 94a648188d..f06216ac76 100644 --- a/plugins/azure-devops/src/components/PullRequestsPage/lib/PullRequestGridColumn/PullRequestGridColumn.tsx +++ b/plugins/azure-devops/src/components/PullRequestsPage/lib/PullRequestGridColumn/PullRequestGridColumn.tsx @@ -14,7 +14,9 @@ * limitations under the License. */ -import { Paper, Typography, styled, withStyles } from '@material-ui/core'; +import Paper from '@material-ui/core/Paper'; +import Typography from '@material-ui/core/Typography'; +import { styled, withStyles } from '@material-ui/core/styles'; import { PullRequestCard } from '../PullRequestCard'; import { PullRequestGroup } from '../types'; diff --git a/plugins/azure-devops/src/components/ReadmeCard/ReadmeCard.tsx b/plugins/azure-devops/src/components/ReadmeCard/ReadmeCard.tsx index 420fe6ecf4..300c9e0d7c 100644 --- a/plugins/azure-devops/src/components/ReadmeCard/ReadmeCard.tsx +++ b/plugins/azure-devops/src/components/ReadmeCard/ReadmeCard.tsx @@ -14,7 +14,9 @@ * limitations under the License. */ -import { Box, Button, makeStyles } from '@material-ui/core'; +import Box from '@material-ui/core/Box'; +import Button from '@material-ui/core/Button'; +import { makeStyles } from '@material-ui/core/styles'; import { InfoCard, Progress, diff --git a/plugins/devtools/.eslintrc.js b/plugins/devtools/.eslintrc.js index e2a53a6ad2..9932358b45 100644 --- a/plugins/devtools/.eslintrc.js +++ b/plugins/devtools/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-mui4-imports': 'error', + }, +}); diff --git a/plugins/devtools/src/components/Content/ConfigContent/ConfigContent.tsx b/plugins/devtools/src/components/Content/ConfigContent/ConfigContent.tsx index 66129b5dae..aba46f85b7 100644 --- a/plugins/devtools/src/components/Content/ConfigContent/ConfigContent.tsx +++ b/plugins/devtools/src/components/Content/ConfigContent/ConfigContent.tsx @@ -15,16 +15,16 @@ */ import { Progress, WarningPanel } from '@backstage/core-components'; +import Box from '@material-ui/core/Box'; +import Paper from '@material-ui/core/Paper'; +import Typography from '@material-ui/core/Typography'; import { - Box, createStyles, makeStyles, - Paper, Theme, - Typography, useTheme, -} from '@material-ui/core'; -import { Alert } from '@material-ui/lab'; +} from '@material-ui/core/styles'; +import Alert from '@material-ui/lab/Alert'; import React from 'react'; import ReactJson from 'react-json-view'; import { useConfig } from '../../../hooks'; diff --git a/plugins/devtools/src/components/Content/ExternalDependenciesContent/ExternalDependenciesContent.tsx b/plugins/devtools/src/components/Content/ExternalDependenciesContent/ExternalDependenciesContent.tsx index a5dd825fe5..c6a46ea8fb 100644 --- a/plugins/devtools/src/components/Content/ExternalDependenciesContent/ExternalDependenciesContent.tsx +++ b/plugins/devtools/src/components/Content/ExternalDependenciesContent/ExternalDependenciesContent.tsx @@ -23,16 +23,12 @@ import { TableColumn, } from '@backstage/core-components'; import { ExternalDependency } from '@backstage/plugin-devtools-common'; -import { - Box, - createStyles, - Grid, - makeStyles, - Paper, - Theme, - Typography, -} from '@material-ui/core'; -import { Alert } from '@material-ui/lab'; +import Box from '@material-ui/core/Box'; +import Grid from '@material-ui/core/Grid'; +import Paper from '@material-ui/core/Paper'; +import Typography from '@material-ui/core/Typography'; +import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'; +import Alert from '@material-ui/lab/Alert'; import React from 'react'; import { useExternalDependencies } from '../../../hooks'; diff --git a/plugins/devtools/src/components/Content/InfoContent/BackstageLogoIcon.tsx b/plugins/devtools/src/components/Content/InfoContent/BackstageLogoIcon.tsx index 32f35600f2..8a9df77546 100644 --- a/plugins/devtools/src/components/Content/InfoContent/BackstageLogoIcon.tsx +++ b/plugins/devtools/src/components/Content/InfoContent/BackstageLogoIcon.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { SvgIcon, SvgIconProps } from '@material-ui/core'; +import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon'; import React from 'react'; diff --git a/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx b/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx index 0ed43d2fee..fcbea53603 100644 --- a/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx +++ b/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx @@ -15,20 +15,16 @@ */ import { Progress } from '@backstage/core-components'; -import { - Avatar, - Box, - createStyles, - Divider, - List, - ListItem, - ListItemAvatar, - ListItemText, - makeStyles, - Paper, - Theme, -} from '@material-ui/core'; -import { Alert } from '@material-ui/lab'; +import Avatar from '@material-ui/core/Avatar'; +import Box from '@material-ui/core/Box'; +import Divider from '@material-ui/core/Divider'; +import List from '@material-ui/core/List'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemAvatar from '@material-ui/core/ListItemAvatar'; +import ListItemText from '@material-ui/core/ListItemText'; +import Paper from '@material-ui/core/Paper'; +import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'; +import Alert from '@material-ui/lab/Alert'; import React from 'react'; import { useInfo } from '../../../hooks'; import { InfoDependenciesTable } from './InfoDependenciesTable'; diff --git a/plugins/devtools/src/components/DevToolsLayout/DevToolsLayout.tsx b/plugins/devtools/src/components/DevToolsLayout/DevToolsLayout.tsx index ae9a337ced..bce0837ef1 100644 --- a/plugins/devtools/src/components/DevToolsLayout/DevToolsLayout.tsx +++ b/plugins/devtools/src/components/DevToolsLayout/DevToolsLayout.tsx @@ -19,7 +19,7 @@ import { attachComponentData, useElementFilter, } from '@backstage/core-plugin-api'; -import { TabProps } from '@material-ui/core'; +import { TabProps } from '@material-ui/core/Tab'; import { default as React } from 'react'; /** @public */ diff --git a/plugins/linguist/.eslintrc.js b/plugins/linguist/.eslintrc.js index e2a53a6ad2..9932358b45 100644 --- a/plugins/linguist/.eslintrc.js +++ b/plugins/linguist/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-mui4-imports': 'error', + }, +}); diff --git a/plugins/linguist/src/components/LinguistCard/LinguistCard.tsx b/plugins/linguist/src/components/LinguistCard/LinguistCard.tsx index 6014487d30..6a07a958c2 100644 --- a/plugins/linguist/src/components/LinguistCard/LinguistCard.tsx +++ b/plugins/linguist/src/components/LinguistCard/LinguistCard.tsx @@ -14,15 +14,12 @@ * limitations under the License. */ -import { - Box, - Chip, - Tooltip, - Typography, - makeStyles, - Grid, - useTheme, -} from '@material-ui/core'; +import Box from '@material-ui/core/Box'; +import Chip from '@material-ui/core/Chip'; +import Tooltip from '@material-ui/core/Tooltip'; +import Typography from '@material-ui/core/Typography'; +import Grid from '@material-ui/core/Grid'; +import { makeStyles, useTheme } from '@material-ui/core/styles'; import { InfoCard, Progress } from '@backstage/core-components'; import Alert from '@material-ui/lab/Alert'; import { DateTime } from 'luxon'; From 37867e0c2c17540ea97f158d89a03908d3d7a789 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 22 Dec 2023 06:56:15 -0600 Subject: [PATCH 069/283] Renamed based on feedback Signed-off-by: Andre Wanlin --- .changeset/young-rules-repeat.md | 2 +- docs/tutorials/migrate-to-mui5.md | 2 +- packages/eslint-plugin/README.md | 12 ++++++------ ...orts.md => no-top-level-material-ui-4-imports.md} | 4 ++-- packages/eslint-plugin/index.js | 2 +- ...orts.js => no-top-level-material-ui-4-imports.js} | 2 +- ...ts => no-top-level-material-ui-4-imports.test.ts} | 2 +- plugins/azure-devops/.eslintrc.js | 2 +- plugins/devtools/.eslintrc.js | 2 +- plugins/linguist/.eslintrc.js | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-) rename packages/eslint-plugin/docs/rules/{no-top-level-mui4-imports.md => no-top-level-material-ui-4-imports.md} (83%) rename packages/eslint-plugin/rules/{no-top-level-mui4-imports.js => no-top-level-material-ui-4-imports.js} (98%) rename packages/eslint-plugin/src/{no-top-level-mui4-imports.test.ts => no-top-level-material-ui-4-imports.test.ts} (98%) diff --git a/.changeset/young-rules-repeat.md b/.changeset/young-rules-repeat.md index 5c9d790214..6fb17f0608 100644 --- a/.changeset/young-rules-repeat.md +++ b/.changeset/young-rules-repeat.md @@ -2,4 +2,4 @@ '@backstage/eslint-plugin': patch --- -Added new `@backstage/no-top-level-mui4-imports` rule that forbids top level imports from Material UI v4 packages +Added new `@backstage/no-top-level-material-ui-4-imports` rule that forbids top level imports from Material UI v4 packages diff --git a/docs/tutorials/migrate-to-mui5.md b/docs/tutorials/migrate-to-mui5.md index 1b21c8b419..aaf8cff7f5 100644 --- a/docs/tutorials/migrate-to-mui5.md +++ b/docs/tutorials/migrate-to-mui5.md @@ -56,7 +56,7 @@ For current known issues with the Material UI v5 migration, follow our [Mileston To migrate your plugin to Material UI v5, you can build on the resources available. -1. Manually fix the imports from named to default imports to match the new [linting rules for minimizing bundle size](https://mui.com/material-ui/guides/minimizing-bundle-size). Note: you can use the [new `@backstage/no-top-level-mui4-imports` ESLint](https://github.com/backstage/backstage/blob/master/packages/eslint-plugin/docs/rules/no-top-level-mui4-imports.md) rule to help with this. +1. Manually fix the imports from named to default imports to match the new [linting rules for minimizing bundle size](https://mui.com/material-ui/guides/minimizing-bundle-size). Note: you can use the [new `@backstage/no-top-level-material-ui-4-imports` ESLint](https://github.com/backstage/backstage/blob/master/packages/eslint-plugin/docs/rules/no-top-level-material-ui-4-imports.md) rule to help with this. 2. Run the migration `codemod` for the path of the specific plugin: `npx @mui/codemod v5.0.0/preset-safe plugins/`. 3. Take a look at possible `TODO:` items the `codemod` could not fix. 4. Remove types & methods from `@backstage/theme` which are marked as `@deprecated`. diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index 1304239caf..600b3268e1 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -35,9 +35,9 @@ rules: { The following rules are provided by this plugin: -| Rule | Description | -| --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | -| [@backstage/no-forbidden-package-imports](./docs/rules/no-forbidden-package-imports.md) | Disallow internal monorepo imports from package subpaths that are not exported. | -| [@backstage/no-relative-monorepo-imports](./docs/rules/no-relative-monorepo-imports.md) | Forbid relative imports that reach outside of the package in a monorepo. | -| [@backstage/no-undeclared-imports](./docs/rules/no-undeclared-imports.md) | Forbid imports of external packages that have not been declared in the appropriate dependencies field in `package.json`. | -| [@backstage/no-top-level-mui4-imports](./docs/rules/no-top-level-mui4-imports.md) | Forbid top level import from Material UI v4 packages. | +| Rule | Description | +| --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | +| [@backstage/no-forbidden-package-imports](./docs/rules/no-forbidden-package-imports.md) | Disallow internal monorepo imports from package subpaths that are not exported. | +| [@backstage/no-relative-monorepo-imports](./docs/rules/no-relative-monorepo-imports.md) | Forbid relative imports that reach outside of the package in a monorepo. | +| [@backstage/no-undeclared-imports](./docs/rules/no-undeclared-imports.md) | Forbid imports of external packages that have not been declared in the appropriate dependencies field in `package.json`. | +| [@backstage/no-top-level-material-ui-4-imports](./docs/rules/no-top-level-material-ui-4-imports.md) | Forbid top level import from Material UI v4 packages. | diff --git a/packages/eslint-plugin/docs/rules/no-top-level-mui4-imports.md b/packages/eslint-plugin/docs/rules/no-top-level-material-ui-4-imports.md similarity index 83% rename from packages/eslint-plugin/docs/rules/no-top-level-mui4-imports.md rename to packages/eslint-plugin/docs/rules/no-top-level-material-ui-4-imports.md index 85f5821b01..a00eb73ffd 100644 --- a/packages/eslint-plugin/docs/rules/no-top-level-mui4-imports.md +++ b/packages/eslint-plugin/docs/rules/no-top-level-material-ui-4-imports.md @@ -1,4 +1,4 @@ -# @backstage/no-top-level-mui4-imports +# @backstage/no-top-level-material-ui-4-imports Forbid top level import from Material UI v4 packages. @@ -7,7 +7,7 @@ Forbid top level import from Material UI v4 packages. Add the rules as follows, it has no options: ```js -"@backstage/no-top-level-mui4-imports": ["error"] +"@backstage/no-top-level-material-ui-4-imports": ["error"] ``` ## Rule Details diff --git a/packages/eslint-plugin/index.js b/packages/eslint-plugin/index.js index 6fdc4f89fb..af1a8891c3 100644 --- a/packages/eslint-plugin/index.js +++ b/packages/eslint-plugin/index.js @@ -29,6 +29,6 @@ module.exports = { 'no-forbidden-package-imports': require('./rules/no-forbidden-package-imports'), 'no-relative-monorepo-imports': require('./rules/no-relative-monorepo-imports'), 'no-undeclared-imports': require('./rules/no-undeclared-imports'), - 'no-top-level-mui4-imports': require('./rules/no-top-level-mui4-imports'), + 'no-top-level-material-ui-4-imports': require('./rules/no-top-level-material-ui-4-imports'), }, }; diff --git a/packages/eslint-plugin/rules/no-top-level-mui4-imports.js b/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js similarity index 98% rename from packages/eslint-plugin/rules/no-top-level-mui4-imports.js rename to packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js index c3367a2346..dad034e6f2 100644 --- a/packages/eslint-plugin/rules/no-top-level-mui4-imports.js +++ b/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js @@ -37,7 +37,7 @@ module.exports = { }, docs: { description: 'Forbid top level import from Material UI v4 packages.', - url: 'https://github.com/backstage/backstage/blob/master/packages/eslint-plugin/docs/rules/no-top-level-mui4-imports.md', + url: 'https://github.com/backstage/backstage/blob/master/packages/eslint-plugin/docs/rules/no-top-level-material-ui-4-imports.md', }, }, create: context => ({ diff --git a/packages/eslint-plugin/src/no-top-level-mui4-imports.test.ts b/packages/eslint-plugin/src/no-top-level-material-ui-4-imports.test.ts similarity index 98% rename from packages/eslint-plugin/src/no-top-level-mui4-imports.test.ts rename to packages/eslint-plugin/src/no-top-level-material-ui-4-imports.test.ts index 16605aa46f..cb68a529e9 100644 --- a/packages/eslint-plugin/src/no-top-level-mui4-imports.test.ts +++ b/packages/eslint-plugin/src/no-top-level-material-ui-4-imports.test.ts @@ -15,7 +15,7 @@ */ import { RuleTester } from 'eslint'; -import rule from '../rules/no-top-level-mui4-imports'; +import rule from '../rules/no-top-level-material-ui-4-imports'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/plugins/azure-devops/.eslintrc.js b/plugins/azure-devops/.eslintrc.js index 9932358b45..e487f765b2 100644 --- a/plugins/azure-devops/.eslintrc.js +++ b/plugins/azure-devops/.eslintrc.js @@ -1,5 +1,5 @@ module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { rules: { - '@backstage/no-top-level-mui4-imports': 'error', + '@backstage/no-top-level-material-ui-4-imports': 'error', }, }); diff --git a/plugins/devtools/.eslintrc.js b/plugins/devtools/.eslintrc.js index 9932358b45..e487f765b2 100644 --- a/plugins/devtools/.eslintrc.js +++ b/plugins/devtools/.eslintrc.js @@ -1,5 +1,5 @@ module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { rules: { - '@backstage/no-top-level-mui4-imports': 'error', + '@backstage/no-top-level-material-ui-4-imports': 'error', }, }); diff --git a/plugins/linguist/.eslintrc.js b/plugins/linguist/.eslintrc.js index 9932358b45..e487f765b2 100644 --- a/plugins/linguist/.eslintrc.js +++ b/plugins/linguist/.eslintrc.js @@ -1,5 +1,5 @@ module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { rules: { - '@backstage/no-top-level-mui4-imports': 'error', + '@backstage/no-top-level-material-ui-4-imports': 'error', }, }); From 74f57943876fc780d25c813e717e9167cc5f37a9 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 22 Dec 2023 07:24:54 -0600 Subject: [PATCH 070/283] Pair of adjustment based on feedback Signed-off-by: Andre Wanlin --- .../rules/no-top-level-material-ui-4-imports.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js b/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js index dad034e6f2..1cbc56cf9b 100644 --- a/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js +++ b/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js @@ -42,6 +42,12 @@ module.exports = { }, create: context => ({ ImportDeclaration: node => { + // Anatomy of a Node + // Example: import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon'; + // Specifiers are the part between the `import` and `from`, in the example that would be `SvgIcon, { SvgIconProps }` + // Source is the part after the `from`, in the example that would be `'@material-ui/core/SvgIcon'` + // Source value gets you `@material-ui/core/SvgIcon` without the quotes, where as Source raw gets it as is + // Return if empty import if (node.specifiers.length === 0) return; // Return if empty source value @@ -52,11 +58,9 @@ module.exports = { if (!node.source.value.startsWith('@material-ui/')) return; // Return if import is from '@material-ui/core/styles', as it's valid already if (node.source.value === '@material-ui/core/styles') return; - // Return if import is from '@material-ui/core/SvgIcon', as it's valid already - if (node.source.value === '@material-ui/core/SvgIcon') return; // Return if proper import eg. `import Box from '@material-ui/core/Box'` if ( - node.specifiers.length === 1 && + node.specifiers.length >= 1 && node.source.value?.split('/').length === 3 ) return; @@ -87,9 +91,10 @@ module.exports = { ); for (const specifier of specifiers) { - if (specifier.local.name === 'TabProps') { + const propsMatch = /^([A-Z]\w+)Props$/.exec(specifier.local.name); + if (propsMatch) { replacements.push( - `import { TabProps } from '@material-ui/core/Tab';`, + `import { ${specifier.local.name} } from '@material-ui/core/${propsMatch[1]}';`, ); } else if ( specifier.local.name === 'SvgIcon' || From 834d2f530eb818a8134569cff611ded32bbb1fec Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 22 Dec 2023 11:41:47 -0600 Subject: [PATCH 071/283] Applied a map to avoid hard coded cases Signed-off-by: Andre Wanlin --- .../no-top-level-material-ui-4-imports.js | 87 ++++++++++++++----- ...no-top-level-material-ui-4-imports.test.ts | 5 ++ 2 files changed, 70 insertions(+), 22 deletions(-) diff --git a/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js b/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js index 1cbc56cf9b..76a928a5e5 100644 --- a/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js +++ b/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js @@ -84,37 +84,80 @@ module.exports = { fix: fixer => { const replacements = []; const styles = []; - const svgIcon = []; const specifiers = node.specifiers.filter( s => s.type === 'ImportSpecifier', ); - for (const specifier of specifiers) { - const propsMatch = /^([A-Z]\w+)Props$/.exec(specifier.local.name); + const specifiersMap = specifiers.map(s => { + const propsTest = /^([A-Z]\w+)Props$/.test(s.local.name); + const propsMatch = /^([A-Z]\w+)Props$/.exec(s.local.name); + let propValue; if (propsMatch) { - replacements.push( - `import { ${specifier.local.name} } from '@material-ui/core/${propsMatch[1]}';`, - ); - } else if ( - specifier.local.name === 'SvgIcon' || - specifier.local.name === 'SvgIconProps' - ) { - svgIcon.push(specifier.local.name); - } else if (KNOWN_STYLES.includes(specifier.local.name)) { - styles.push(specifier.local.name); - } else { - const replacement = `import ${specifier.local.name} from '${node.source.value}/${specifier.local.name}';`; - replacements.push(replacement); + propValue = propsMatch[1]; } - } + return { + emitComponent: !propsTest, + emitProp: propsTest, + value: s.local.name, + propValue, + }; + }); - if (svgIcon.length > 0) { - if (svgIcon.every(s => ['SvgIcon', 'SvgIconProps'].includes(s))) { - replacements.push( - `import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';`, - ); + // We have 3 cases: + // 1 - Just Prop: import { TabProps } from '@material-ui/core'; + // 2 - Just Component: import { Box } from '@material-ui/core'; + // 3 - Component and Prop: import { SvgIcon, SvgIconProps } from '@material-ui/core'; + + const components = specifiersMap + .filter(f => { + return f.emitComponent; + }) + .map(m => m.value); + const props = specifiersMap + .filter(f => { + return f.emitProp; + }) + .map(m => m.value); + + if ( + specifiersMap.some(s => s.emitProp) && + !specifiersMap.some(s => s.emitComponent) + ) { + // 1 - Just Prop + const propValue = specifiersMap + .filter(f => { + return f.emitProp; + }) + .map(m => m.propValue); + replacements.push( + `import { ${props.join(', ')} } from '@material-ui/core/${ + propValue[0] + }';`, + ); + } else if ( + !specifiersMap.some(s => s.emitProp) && + specifiersMap.some(s => s.emitComponent) + ) { + // 2 - Just Component + for (const specifier of specifiers) { + if (KNOWN_STYLES.includes(specifier.local.name)) { + styles.push(specifier.local.name); + } else { + const replacement = `import ${specifier.local.name} from '${node.source.value}/${specifier.local.name}';`; + replacements.push(replacement); + } } + } else if ( + specifiersMap.some(s => s.emitProp) && + specifiersMap.some(s => s.emitComponent) + ) { + // 3 - Component and Prop + replacements.push( + `import ${components[0]}, { ${props.join( + ', ', + )} } from '@material-ui/core/${components[0]}';`, + ); } if (styles.length > 0) { diff --git a/packages/eslint-plugin/src/no-top-level-material-ui-4-imports.test.ts b/packages/eslint-plugin/src/no-top-level-material-ui-4-imports.test.ts index cb68a529e9..ac0b3770e0 100644 --- a/packages/eslint-plugin/src/no-top-level-material-ui-4-imports.test.ts +++ b/packages/eslint-plugin/src/no-top-level-material-ui-4-imports.test.ts @@ -91,6 +91,11 @@ import { styled, withStyles } from '@material-ui/core/styles';`, errors: [{ messageId: 'topLevelImport' }], output: `import { styled } from '@material-ui/core/styles';`, }, + { + code: `import { SvgIcon, SvgIconProps } from '@material-ui/core';`, + errors: [{ messageId: 'topLevelImport' }], + output: `import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';`, + }, { code: `import { TabProps } from '@material-ui/core';`, errors: [{ messageId: 'topLevelImport' }], From 7965c57e86b1afeaffbcd33dfed3f0efa61d98c9 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 22 Dec 2023 12:56:47 -0600 Subject: [PATCH 072/283] Removed third level or deeper reporting Signed-off-by: Andre Wanlin --- .../rules/no-top-level-material-ui-4-imports.js | 10 ++-------- .../src/no-top-level-material-ui-4-imports.test.ts | 10 ++++++---- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js b/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js index 76a928a5e5..dc2a555e24 100644 --- a/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js +++ b/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js @@ -32,8 +32,6 @@ module.exports = { fixable: 'code', messages: { topLevelImport: 'Top level imports for Material UI are not allowed', - thirdLevelImport: - 'Third level or deeper imports for Material UI are not allowed', }, docs: { description: 'Forbid top level import from Material UI v4 packages.', @@ -65,15 +63,11 @@ module.exports = { ) return; - // Report third level or deeper imports + // Return if third level or deeper imports if ( - node.specifiers.length === 1 && + node.specifiers.length >= 1 && node.source.value.split('/').length > 3 ) { - context.report({ - node, - messageId: 'thirdLevelImport', - }); return; } diff --git a/packages/eslint-plugin/src/no-top-level-material-ui-4-imports.test.ts b/packages/eslint-plugin/src/no-top-level-material-ui-4-imports.test.ts index ac0b3770e0..568bdb8cc8 100644 --- a/packages/eslint-plugin/src/no-top-level-material-ui-4-imports.test.ts +++ b/packages/eslint-plugin/src/no-top-level-material-ui-4-imports.test.ts @@ -38,6 +38,12 @@ ruleTester.run('path-imports-rule', rule, { { code: `import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';`, }, + { + code: `import { StyleRules } from '@material-ui/core/styles/withStyles';`, + }, + { + code: `import { CreateCSSProperties, StyledComponentProps } from '@material-ui/core/styles/withStyles';`, + }, ], invalid: [ { @@ -68,10 +74,6 @@ import DialogTitle from '@material-ui/core/DialogTitle'; import Grid from '@material-ui/core/Grid'; import { makeStyles } from '@material-ui/core/styles';`, }, - { - code: `import { TabIndicator } from '@material-ui/core/Tabs/TabIndicator';`, - errors: [{ messageId: 'thirdLevelImport' }], - }, { code: `import { Box, Button, makeStyles } from '@material-ui/core';`, errors: [{ messageId: 'topLevelImport' }], From aeed5347e1da9813aa3149011a364a0d5ce5038e Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 22 Dec 2023 13:05:08 -0600 Subject: [PATCH 073/283] Updated API Reports Signed-off-by: Andre Wanlin --- plugins/azure-devops/api-report.md | 2 +- plugins/devtools/api-report.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/azure-devops/api-report.md b/plugins/azure-devops/api-report.md index 38c1eed279..cfff4348ee 100644 --- a/plugins/azure-devops/api-report.md +++ b/plugins/azure-devops/api-report.md @@ -22,7 +22,7 @@ import { Readme } from '@backstage/plugin-azure-devops-common'; import { ReadmeConfig } from '@backstage/plugin-azure-devops-common'; import { RepoBuild } from '@backstage/plugin-azure-devops-common'; import { RepoBuildOptions } from '@backstage/plugin-azure-devops-common'; -import { SvgIconProps } from '@material-ui/core'; +import { SvgIconProps } from '@material-ui/core/SvgIcon'; import { Team } from '@backstage/plugin-azure-devops-common'; // @public (undocumented) diff --git a/plugins/devtools/api-report.md b/plugins/devtools/api-report.md index 21754d7c1e..bba36a5a9a 100644 --- a/plugins/devtools/api-report.md +++ b/plugins/devtools/api-report.md @@ -10,7 +10,7 @@ import { default as default_2 } from 'react'; import { JSX as JSX_2 } from 'react'; import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; -import { TabProps } from '@material-ui/core'; +import { TabProps } from '@material-ui/core/Tab'; // @public (undocumented) export const ConfigContent: () => React_2.JSX.Element; From b07ff647d6b2b972e4dbbb0f3cc3f103849faebd Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Sat, 13 Jan 2024 15:05:12 -0600 Subject: [PATCH 074/283] Clean-up based on feedback Signed-off-by: Andre Wanlin --- .../no-top-level-material-ui-4-imports.md | 4 +-- .../no-top-level-material-ui-4-imports.js | 27 +++++-------------- 2 files changed, 8 insertions(+), 23 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/no-top-level-material-ui-4-imports.md b/packages/eslint-plugin/docs/rules/no-top-level-material-ui-4-imports.md index a00eb73ffd..a105014abc 100644 --- a/packages/eslint-plugin/docs/rules/no-top-level-material-ui-4-imports.md +++ b/packages/eslint-plugin/docs/rules/no-top-level-material-ui-4-imports.md @@ -7,12 +7,12 @@ Forbid top level import from Material UI v4 packages. Add the rules as follows, it has no options: ```js -"@backstage/no-top-level-material-ui-4-imports": ["error"] +'@backstage/no-top-level-material-ui-4-imports': 'error' ``` ## Rule Details -TBD - Not sure what should go here +Automatically fixes imports from named to default imports. This will help you comply with [Material UI recommendations](https://mui.com/material-ui/guides/minimizing-bundle-size/) and make migrating to Material UI v5 easier. ### Fail diff --git a/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js b/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js index dc2a555e24..6a726545fc 100644 --- a/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js +++ b/packages/eslint-plugin/rules/no-top-level-material-ui-4-imports.js @@ -57,19 +57,8 @@ module.exports = { // Return if import is from '@material-ui/core/styles', as it's valid already if (node.source.value === '@material-ui/core/styles') return; // Return if proper import eg. `import Box from '@material-ui/core/Box'` - if ( - node.specifiers.length >= 1 && - node.source.value?.split('/').length === 3 - ) - return; - - // Return if third level or deeper imports - if ( - node.specifiers.length >= 1 && - node.source.value.split('/').length > 3 - ) { - return; - } + // Or if third level or deeper imports + if (node.source.value?.split('/').length >= 3) return; // Report all other imports context.report({ @@ -84,17 +73,13 @@ module.exports = { ); const specifiersMap = specifiers.map(s => { - const propsTest = /^([A-Z]\w+)Props$/.test(s.local.name); const propsMatch = /^([A-Z]\w+)Props$/.exec(s.local.name); - let propValue; - if (propsMatch) { - propValue = propsMatch[1]; - } + return { - emitComponent: !propsTest, - emitProp: propsTest, + emitComponent: !(propsMatch !== null), + emitProp: propsMatch !== null, value: s.local.name, - propValue, + propValue: propsMatch ? propsMatch[1] : undefined, }; }); From 9ac1ceb4b68bb2f5b9b50522f4ce281d424ec401 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Mon, 15 Jan 2024 09:16:28 +0200 Subject: [PATCH 075/283] chore: move connection upgrade to router, add tests for manager Signed-off-by: Heikki Hellgren --- .../src/service/SignalManager.test.ts | 178 ++++++++++++++++++ .../src/service/SignalManager.ts | 69 +------ plugins/signals-backend/src/service/router.ts | 63 +++++-- 3 files changed, 236 insertions(+), 74 deletions(-) create mode 100644 plugins/signals-backend/src/service/SignalManager.test.ts diff --git a/plugins/signals-backend/src/service/SignalManager.test.ts b/plugins/signals-backend/src/service/SignalManager.test.ts new file mode 100644 index 0000000000..5720d1ff52 --- /dev/null +++ b/plugins/signals-backend/src/service/SignalManager.test.ts @@ -0,0 +1,178 @@ +/* + * Copyright 2024 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 { WebSocket } from 'ws'; +import { EventSubscriber } from '@backstage/plugin-events-node'; +import { SignalManager } from './SignalManager'; +import { getVoidLogger } from '@backstage/backend-common'; + +class MockWebSocket { + closed: boolean = false; + readyState: number = WebSocket.OPEN; + callbacks: Map void> = + new Map(); + data: any[] = []; + + close(_: number, __: string | Buffer): void { + this.readyState = WebSocket.CLOSED; + this.closed = true; + } + + on( + event: string | symbol, + listener: (this: WebSocket, ...args: any[]) => void, + ) { + this.callbacks.set(event, listener); + return this; + } + + // @ts-ignore + send(data: any, _?: (err?: Error) => void): void { + this.data.push(data); + } + + trigger(event: string | symbol, ...args: any[]): void { + const cb = this.callbacks.get(event); + if (!cb) { + throw new Error(`No callback for ${event.toString()}`); + } + // @ts-ignore + cb(...args); + } +} + +describe('SignalManager', () => { + let onEvent: Function; + + const mockEventBroker = { + publish: async () => {}, + subscribe: (subscriber: EventSubscriber) => { + onEvent = subscriber.onEvent; + }, + }; + + const manager = SignalManager.create({ + eventBroker: mockEventBroker, + logger: getVoidLogger(), + }); + + it('should close connection on error', () => { + const ws = new MockWebSocket(); + manager.addConnection(ws as unknown as WebSocket); + + ws.trigger('error', new Error('error')); + expect(ws.closed).toBeTruthy(); + }); + + it('should allow subscribing and unsubscribing to events', async () => { + const ws = new MockWebSocket(); + manager.addConnection(ws as unknown as WebSocket); + + ws.trigger( + 'message', + JSON.stringify({ action: 'subscribe', channel: 'test' }), + false, + ); + + await onEvent({ + topic: 'signals', + eventPayload: { + recipients: null, + channel: 'test', + message: { msg: 'test' }, + }, + }); + + expect(ws.data.length).toEqual(1); + expect(ws.data[0]).toEqual( + JSON.stringify({ channel: 'test', message: { msg: 'test' } }), + ); + + ws.trigger( + 'message', + JSON.stringify({ action: 'unsubscribe', channel: 'test' }), + false, + ); + + await onEvent({ + topic: 'signals', + eventPayload: { + recipients: null, + channel: 'test', + message: { msg: 'test' }, + }, + }); + + expect(ws.data.length).toEqual(1); + }); + + it('should only send to users from identity', async () => { + // Connection without identity + const ws1 = new MockWebSocket(); + manager.addConnection(ws1 as unknown as WebSocket); + + // Connection with identity and subscription + const ws2 = new MockWebSocket(); + manager.addConnection(ws2 as unknown as WebSocket, { + identity: { + type: 'user', + ownershipEntityRefs: ['user:default/john.doe'], + userEntityRef: 'user:default/john.doe', + }, + expiresInSeconds: 3600, + token: '1234', + }); + + // Connection without subscription + const ws3 = new MockWebSocket(); + manager.addConnection(ws3 as unknown as WebSocket, { + identity: { + type: 'user', + ownershipEntityRefs: ['user:default/john.doe'], + userEntityRef: 'user:default/john.doe', + }, + expiresInSeconds: 3600, + token: '1234', + }); + + ws1.trigger( + 'message', + JSON.stringify({ action: 'subscribe', channel: 'test' }), + false, + ); + + ws2.trigger( + 'message', + JSON.stringify({ action: 'subscribe', channel: 'test' }), + false, + ); + + await onEvent({ + topic: 'signals', + eventPayload: { + recipients: 'user:default/john.doe', + channel: 'test', + message: { msg: 'test' }, + }, + }); + + expect(ws1.data.length).toEqual(0); + expect(ws3.data.length).toEqual(0); + expect(ws2.data.length).toEqual(1); + expect(ws2.data[0]).toEqual( + JSON.stringify({ channel: 'test', message: { msg: 'test' } }), + ); + }); +}); diff --git a/plugins/signals-backend/src/service/SignalManager.ts b/plugins/signals-backend/src/service/SignalManager.ts index 988db47465..983496b96b 100644 --- a/plugins/signals-backend/src/service/SignalManager.ts +++ b/plugins/signals-backend/src/service/SignalManager.ts @@ -15,24 +15,11 @@ */ import { EventBroker, EventParams } from '@backstage/plugin-events-node'; import { SignalPayload } from '@backstage/plugin-signals-node'; -import { RawData, WebSocket, WebSocketServer } from 'ws'; -import { IncomingMessage } from 'http'; +import { RawData, WebSocket } from 'ws'; import { v4 as uuid } from 'uuid'; import { JsonObject } from '@backstage/types'; -import { - BackstageIdentityResponse, - IdentityApi, - IdentityApiGetIdentityRequest, -} from '@backstage/plugin-auth-node'; +import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; import { LoggerService } from '@backstage/backend-plugin-api'; -import { Duplex } from 'stream'; - -/** @internal */ -export type ConnectionUpgradeOptions = { - request: IncomingMessage; - socket: Duplex; - head: Buffer; -}; /** * @internal @@ -52,7 +39,6 @@ export type SignalManagerOptions = { // TODO: Remove optional when events-backend can offer this service eventBroker?: EventBroker; logger: LoggerService; - identity: IdentityApi; }; /** @internal */ @@ -63,24 +49,13 @@ export class SignalManager { >(); private eventBroker?: EventBroker; private logger: LoggerService; - private identity: IdentityApi; - private server: WebSocketServer; static create(options: SignalManagerOptions) { return new SignalManager(options); } private constructor(options: SignalManagerOptions) { - ({ - eventBroker: this.eventBroker, - logger: this.logger, - identity: this.identity, - } = options); - - this.server = new WebSocketServer({ - noServer: true, - clientTracking: false, - }); + ({ eventBroker: this.eventBroker, logger: this.logger } = options); this.eventBroker?.subscribe({ supportsEventTopics: () => ['signals'], @@ -89,37 +64,7 @@ export class SignalManager { }); } - /** - * Handles request upgrade to websocket and adds the connection to internal - * list for publish/subscribe functionality - * @param req - Request - */ - async handleUpgrade(options: ConnectionUpgradeOptions) { - const { request, socket, head } = options; - let identity: BackstageIdentityResponse | undefined = undefined; - - // Authentication token is passed in Sec-WebSocket-Protocol header as there - // is no other way to pass the token with plain websockets - const token = request.headers['sec-websocket-protocol']; - if (token) { - identity = await this.identity.getIdentity({ - request: { - headers: { authorization: token }, - }, - } as IdentityApiGetIdentityRequest); - } - - this.server.handleUpgrade( - request, - socket, - head, - (ws: WebSocket, __: IncomingMessage) => { - this.addConnection(ws, identity); - }, - ); - } - - private addConnection(ws: WebSocket, identity?: BackstageIdentityResponse) { + addConnection(ws: WebSocket, identity?: BackstageIdentityResponse) { const id = uuid(); const conn = { @@ -207,7 +152,11 @@ export class SignalManager { return; } - conn.ws.send(jsonMessage); + conn.ws.send(jsonMessage, err => { + if (err) { + this.logger.error(`Failed to send message to ${conn.id}: ${err}`); + } + }); }); } } diff --git a/plugins/signals-backend/src/service/router.ts b/plugins/signals-backend/src/service/router.ts index ec56860bf3..4394a9f480 100644 --- a/plugins/signals-backend/src/service/router.ts +++ b/plugins/signals-backend/src/service/router.ts @@ -18,10 +18,15 @@ import express, { NextFunction, Request, Response } from 'express'; import Router from 'express-promise-router'; import { LoggerService } from '@backstage/backend-plugin-api'; import * as https from 'https'; -import http from 'http'; +import http, { IncomingMessage } from 'http'; import { SignalManager } from './SignalManager'; -import { IdentityApi } from '@backstage/plugin-auth-node'; +import { + BackstageIdentityResponse, + IdentityApi, + IdentityApiGetIdentityRequest, +} from '@backstage/plugin-auth-node'; import { EventBroker } from '@backstage/plugin-events-node'; +import { WebSocket, WebSocketServer } from 'ws'; /** @public */ export interface RouterOptions { @@ -34,13 +39,23 @@ export interface RouterOptions { export async function createRouter( options: RouterOptions, ): Promise { - const { logger } = options; + const { logger, identity } = options; const manager = SignalManager.create(options); - let subscribed = false; + let subscribedToUpgradeRequests = false; - const upgradeMiddleware = (req: Request, _: Response, next: NextFunction) => { + const webSocketServer = new WebSocketServer({ + noServer: true, + clientTracking: false, + }); + + const upgradeMiddleware = async ( + req: Request, + _: Response, + next: NextFunction, + ) => { const server: https.Server | http.Server = (req.socket as any)?.server; if ( + subscribedToUpgradeRequests || !server || !req.headers || req.headers.upgrade === undefined || @@ -50,15 +65,35 @@ export async function createRouter( return; } - if (!subscribed) { - subscribed = true; - server.on('upgrade', async (request, socket, head) => { - // TODO: Find a way to make this more generic - if (request.url === '/api/signals') { - await manager.handleUpgrade({ request, socket, head }); - } - }); - } + subscribedToUpgradeRequests = true; + server.on('upgrade', async (request, socket, head) => { + // TODO: Find a way to make this more generic + if (request.url !== '/api/signals') { + return; + } + + let userIdentity: BackstageIdentityResponse | undefined = undefined; + + // Authentication token is passed in Sec-WebSocket-Protocol header as there + // is no other way to pass the token with plain websockets + const token = req.headers['sec-websocket-protocol']; + if (token) { + userIdentity = await identity.getIdentity({ + request: { + headers: { authorization: token }, + }, + } as IdentityApiGetIdentityRequest); + } + + webSocketServer.handleUpgrade( + request, + socket, + head, + (ws: WebSocket, __: IncomingMessage) => { + manager.addConnection(ws, userIdentity); + }, + ); + }); }; const router = Router(); From b2d71c2bd3a2fd3eeb57541c89aae0502b14eef7 Mon Sep 17 00:00:00 2001 From: Navya Govind Date: Mon, 15 Jan 2024 10:53:04 +0100 Subject: [PATCH 076/283] Make overflow dynamic Signed-off-by: Navya Govind --- .../EntityOwnerPicker/EntityOwnerPicker.tsx | 80 ++++++++++++------- 1 file changed, 49 insertions(+), 31 deletions(-) diff --git a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx index 1b6773662e..c4311ce896 100644 --- a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx +++ b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx @@ -40,6 +40,7 @@ import PersonIcon from '@material-ui/icons/Person'; import GroupIcon from '@material-ui/icons/Group'; import { humanizeEntity, humanizeEntityRef } from '../EntityRefLink/humanize'; import { useFetchEntities } from './useFetchEntities'; +import { withStyles } from '@material-ui/core/styles'; /** @public */ export type CatalogReactEntityOwnerPickerClassKey = 'input'; @@ -53,6 +54,21 @@ const useStyles = makeStyles( }, ); +const FixedWidthFormControlLabel = withStyles( + _theme => ({ + root: { + width: '100%', + }, + label: { + root: { + width: '100%', + }, + width: '100%', + }, + }), + { name: 'FixedWidthFormControlLabel' }, +)(FormControlLabel); + const icon = ; const checkedIcon = ; @@ -154,7 +170,6 @@ export const EntityOwnerPicker = (props?: EntityOwnerPickerProps) => { if (typeof e !== 'string') { cache.setEntity(e); } - return entityRef; }), ); @@ -167,37 +182,40 @@ export const EntityOwnerPicker = (props?: EntityOwnerPickerProps) => { humanizeEntityRef(entity, { defaultKind: entity.kind }), ); return ( - - } - onClick={event => event.preventDefault()} - label={ - - - {isGroup ? ( - - ) : ( - - )} -   - - {humanizedName} + + + } + onClick={event => event.preventDefault()} + label={ + + + {isGroup ? ( + + ) : ( + + )} +   + + {humanizedName} + - - - } - /> + + } + /> + ); }} size="small" From ce9dd1460f5e702a25d8129436e32ef2025765d8 Mon Sep 17 00:00:00 2001 From: Navya Govind Date: Mon, 15 Jan 2024 11:30:34 +0100 Subject: [PATCH 077/283] refactor css stuff Signed-off-by: Navya Govind --- .../EntityOwnerPicker/EntityOwnerPicker.tsx | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx index c4311ce896..685279b83e 100644 --- a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx +++ b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx @@ -48,6 +48,12 @@ export type CatalogReactEntityOwnerPickerClassKey = 'input'; const useStyles = makeStyles( { input: {}, + fullWidth: { width: '100%' }, + boxLabel: { + width: '100%', + textOverflow: 'ellipsis', + overflow: 'hidden', + }, }, { name: 'CatalogReactEntityOwnerPicker', @@ -56,13 +62,7 @@ const useStyles = makeStyles( const FixedWidthFormControlLabel = withStyles( _theme => ({ - root: { - width: '100%', - }, label: { - root: { - width: '100%', - }, width: '100%', }, }), @@ -182,9 +182,9 @@ export const EntityOwnerPicker = (props?: EntityOwnerPickerProps) => { humanizeEntityRef(entity, { defaultKind: entity.kind }), ); return ( - + { )}   - + {humanizedName} From d3be2dac94877c98998ddbb21faea5d8d6333da7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 11:57:44 +0000 Subject: [PATCH 078/283] chore(deps): update helm release postgresql to v13.2.30 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- contrib/chart/backstage/Chart.lock | 6 +++--- contrib/chart/backstage/Chart.yaml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/chart/backstage/Chart.lock b/contrib/chart/backstage/Chart.lock index 542f9d592e..bd909c1071 100644 --- a/contrib/chart/backstage/Chart.lock +++ b/contrib/chart/backstage/Chart.lock @@ -1,6 +1,6 @@ dependencies: - name: postgresql repository: https://charts.bitnami.com/bitnami - version: 13.2.27 -digest: sha256:c2272865ffe4c805153440d8fc6af84945d4ce566b14d0fa8698d75382ada06c -generated: "2023-12-31T14:23:23.75461574Z" + version: 13.2.30 +digest: sha256:7b558cf1628b8cce366c980f20bd80a3cd7685fe419e43ee9d6df75bc577ec20 +generated: "2024-01-15T11:57:35.306830879Z" diff --git a/contrib/chart/backstage/Chart.yaml b/contrib/chart/backstage/Chart.yaml index a152ac49ac..f926c1b0d7 100644 --- a/contrib/chart/backstage/Chart.yaml +++ b/contrib/chart/backstage/Chart.yaml @@ -18,7 +18,7 @@ sources: dependencies: - name: postgresql condition: postgresql.enabled - version: 13.2.27 + version: 13.2.30 repository: https://charts.bitnami.com/bitnami maintainers: From 87ca41827b954ccd9ba3dc1d61bd22663b846737 Mon Sep 17 00:00:00 2001 From: Navya Govind Date: Mon, 15 Jan 2024 13:18:22 +0100 Subject: [PATCH 079/283] use presentation api Signed-off-by: Navya Govind --- .../EntityOwnerPicker/EntityOwnerPicker.tsx | 73 ++++++++++--------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx index 685279b83e..6a4a6d2dd0 100644 --- a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx +++ b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx @@ -41,6 +41,7 @@ import GroupIcon from '@material-ui/icons/Group'; import { humanizeEntity, humanizeEntityRef } from '../EntityRefLink/humanize'; import { useFetchEntities } from './useFetchEntities'; import { withStyles } from '@material-ui/core/styles'; +import { useEntityPresentation } from '../../apis'; /** @public */ export type CatalogReactEntityOwnerPickerClassKey = 'input'; @@ -79,6 +80,42 @@ export type EntityOwnerPickerProps = { mode?: 'owners-only' | 'all'; }; +function WrappedOption(props: { entity: Entity; isSelected: boolean }) { + const classes = useStyles(); + const isGroup = props.entity.kind.toLocaleLowerCase('en-US') === 'group'; + const { primaryTitle } = useEntityPresentation(props.entity); + return ( + + + } + onClick={event => event.preventDefault()} + label={ + + + {isGroup ? ( + + ) : ( + + )} +   + + {primaryTitle} + + + + } + /> + + ); +} + /** @public */ export const EntityOwnerPicker = (props?: EntityOwnerPickerProps) => { const classes = useStyles(); @@ -176,41 +213,7 @@ export const EntityOwnerPicker = (props?: EntityOwnerPickerProps) => { }} filterOptions={x => x} renderOption={(entity, { selected }) => { - const isGroup = entity.kind.toLocaleLowerCase('en-US') === 'group'; - const humanizedName = humanizeEntity( - entity, - humanizeEntityRef(entity, { defaultKind: entity.kind }), - ); - return ( - - - } - onClick={event => event.preventDefault()} - label={ - - - {isGroup ? ( - - ) : ( - - )} -   - - {humanizedName} - - - - } - /> - - ); + return ; }} size="small" popupIcon={} From 983a93fc4a6317f730e5c0e5a3cdf7adbb1114e6 Mon Sep 17 00:00:00 2001 From: Navya Govind Date: Mon, 15 Jan 2024 13:26:47 +0100 Subject: [PATCH 080/283] better naming Signed-off-by: Navya Govind --- .../components/EntityOwnerPicker/EntityOwnerPicker.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx index 6a4a6d2dd0..8876266db2 100644 --- a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx +++ b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx @@ -80,10 +80,10 @@ export type EntityOwnerPickerProps = { mode?: 'owners-only' | 'all'; }; -function WrappedOption(props: { entity: Entity; isSelected: boolean }) { +function RenderOptionLabel(props: { entity: Entity; isSelected: boolean }) { const classes = useStyles(); const isGroup = props.entity.kind.toLocaleLowerCase('en-US') === 'group'; - const { primaryTitle } = useEntityPresentation(props.entity); + const { primaryTitle: title } = useEntityPresentation(props.entity); return ( event.preventDefault()} label={ - + {isGroup ? ( @@ -106,7 +106,7 @@ function WrappedOption(props: { entity: Entity; isSelected: boolean }) { )}   - {primaryTitle} + {title} @@ -213,7 +213,7 @@ export const EntityOwnerPicker = (props?: EntityOwnerPickerProps) => { }} filterOptions={x => x} renderOption={(entity, { selected }) => { - return ; + return ; }} size="small" popupIcon={} From c3ae0d47da05c5aca0c3c1f3e4329d1b40627748 Mon Sep 17 00:00:00 2001 From: AmbrishRamachandiran Date: Mon, 15 Jan 2024 19:03:56 +0530 Subject: [PATCH 081/283] Changes is style Signed-off-by: AmbrishRamachandiran --- microsite/src/pages/plugins/plugins.module.scss | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/microsite/src/pages/plugins/plugins.module.scss b/microsite/src/pages/plugins/plugins.module.scss index b0427c8f5c..dbd0c62c75 100644 --- a/microsite/src/pages/plugins/plugins.module.scss +++ b/microsite/src/pages/plugins/plugins.module.scss @@ -78,6 +78,8 @@ :global(.dropdown) { float: right; margin-bottom: 1rem; + text-overflow: ellipsis; + white-space: nowrap; } :global(.button--info) { @@ -100,7 +102,7 @@ } :global(.dropdown__label) { - font-size: 14px; + font-size: 15px; cursor: pointer; } From 5d06333af2899e3057d2b9909704afbc06ed8d54 Mon Sep 17 00:00:00 2001 From: armandocomellas1 Date: Mon, 15 Jan 2024 19:27:09 -0600 Subject: [PATCH 082/283] Add a descriptive description at the changeset and add some unit test for three different scenarios Signed-off-by: armandocomellas1 --- .changeset/many-pugs-change.md | 2 +- .../cluster-locator/GkeClusterLocator.test.ts | 103 ++++++++++++++++++ .../src/cluster-locator/GkeClusterLocator.ts | 17 +-- 3 files changed, 109 insertions(+), 13 deletions(-) diff --git a/.changeset/many-pugs-change.md b/.changeset/many-pugs-change.md index f16efb85aa..318c571891 100644 --- a/.changeset/many-pugs-change.md +++ b/.changeset/many-pugs-change.md @@ -2,4 +2,4 @@ '@backstage/plugin-kubernetes-backend': patch --- -Change add some lines in the script GkeClusterLocator.ts, the implementation consist in adding a piece of code starts in 58 adding some config.getString() method to find out if the app-config.yaml kubernetes config includes the type of Auth as googleServiceAccount +The purpose of this patch is to add a new login method which is `googleServiceAccount` configuring the kubernetes properties in the app-config.yaml file with authProvider key diff --git a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.test.ts b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.test.ts index f919561490..849a7839e2 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.test.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.test.ts @@ -382,5 +382,108 @@ describe('GkeClusterLocator', () => { parent: 'projects/some-project/locations/some-region', }); }); + it('return google login when no authProvider is specified', async () => { + mockedListClusters.mockReturnValueOnce([ + { + clusters: [ + { + name: 'some-cluster', + endpoint: '1.2.3.4', + }, + ], + }, + ]); + + const config: Config = new ConfigReader({ + type: 'gke', + projectId: 'some-project', + }); + + const sut = GkeClusterLocator.fromConfigWithClient(config, { + listClusters: mockedListClusters, + } as any); + + const result = await sut.getClusters(); + + expect(result).toStrictEqual([ + { + name: 'some-cluster', + url: 'https://1.2.3.4', + authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'google' }, + skipTLSVerify: false, + skipMetricsLookup: false, + }, + ]); + }); + it('return googleServiceAccount login when authProvider is specified', async () => { + mockedListClusters.mockReturnValueOnce([ + { + clusters: [ + { + name: 'some-cluster', + endpoint: '1.2.3.4', + }, + ], + }, + ]); + + const config: Config = new ConfigReader({ + type: 'gke', + projectId: 'some-project', + authProvider: 'googleServiceAccount', + }); + + const sut = GkeClusterLocator.fromConfigWithClient(config, { + listClusters: mockedListClusters, + } as any); + + const result = await sut.getClusters(); + + expect(result).toStrictEqual([ + { + name: 'some-cluster', + url: 'https://1.2.3.4', + authMetadata: { + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'googleServiceAccount', + }, + skipTLSVerify: false, + skipMetricsLookup: false, + }, + ]); + }); + it('return google login when authProvider property has invalid value', async () => { + mockedListClusters.mockReturnValueOnce([ + { + clusters: [ + { + name: 'some-cluster', + endpoint: '1.2.3.4', + }, + ], + }, + ]); + + const config: Config = new ConfigReader({ + type: 'gke', + projectId: 'some-project', + authProvider: 'differentValue', + }); + + const sut = GkeClusterLocator.fromConfigWithClient(config, { + listClusters: mockedListClusters, + } as any); + + const result = await sut.getClusters(); + + expect(result).toStrictEqual([ + { + name: 'some-cluster', + url: 'https://1.2.3.4', + authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'google' }, + skipTLSVerify: false, + skipMetricsLookup: false, + }, + ]); + }); }); }); diff --git a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts index a3b39f2b08..03f5bda103 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/GkeClusterLocator.ts @@ -55,18 +55,11 @@ export class GkeClusterLocator implements KubernetesClustersSupplier { return { key: mrl.getString('key'), value: mrl.getString('value') }; }) ?? []; - let storeAuthProviderString: string; - let getGkeProperty; - try { - getGkeProperty = config.getString('authProvider'); - } catch (err) { - getGkeProperty = 'google'; - } - if (getGkeProperty === 'googleServiceAccount') { - storeAuthProviderString = 'googleServiceAccount'; - } else { - storeAuthProviderString = 'google'; - } + const storeAuthProviderString = + config.getOptionalString('authProvider') === 'googleServiceAccount' + ? 'googleServiceAccount' + : 'google'; + const options = { projectId: config.getString('projectId'), authProvider: storeAuthProviderString, From 0b0396257632d38de2f000673cba73451ebeb4f9 Mon Sep 17 00:00:00 2001 From: AmbrishRamachandiran Date: Tue, 16 Jan 2024 10:21:27 +0530 Subject: [PATCH 083/283] Updated readme document of adr plugin Signed-off-by: AmbrishRamachandiran --- .changeset/curvy-ladybugs-impress.md | 5 +++++ plugins/adr/README.md | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/curvy-ladybugs-impress.md diff --git a/.changeset/curvy-ladybugs-impress.md b/.changeset/curvy-ladybugs-impress.md new file mode 100644 index 0000000000..ffeb76399a --- /dev/null +++ b/.changeset/curvy-ladybugs-impress.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-adr': patch +--- + +Updated Readme document in adr plugin diff --git a/plugins/adr/README.md b/plugins/adr/README.md index e6178f003b..4a1f3a7552 100644 --- a/plugins/adr/README.md +++ b/plugins/adr/README.md @@ -2,7 +2,7 @@ Welcome to the ADR plugin! -This plugin allows you to browse ADRs associated with your entities as well as a way to discover ADRs across others entities via Backstage Search. Use this to learn from the past experience of other projects to guide your own architecture decisions. +This plugin allows you to explore ADRs connected with your entities, as well as discover ADRs across other entities using Backstage Search. Use this to inform your own architectural decisions based on the experiences of previous projects. ![ADR tab](./docs/adr-tab.png) From 1ab53d0f09d3e4ba27a6c48e97e941561195aca1 Mon Sep 17 00:00:00 2001 From: Philipp Hugenroth Date: Tue, 16 Jan 2024 10:56:13 +0100 Subject: [PATCH 084/283] Add release notes for 1.22.0 Signed-off-by: Philipp Hugenroth --- docs/releases/v1.22.0.md | 69 ++++++++++++++++++++++++++++++++++ microsite/docusaurus.config.js | 2 +- microsite/sidebars.json | 1 + 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 docs/releases/v1.22.0.md diff --git a/docs/releases/v1.22.0.md b/docs/releases/v1.22.0.md new file mode 100644 index 0000000000..e5ce345ccc --- /dev/null +++ b/docs/releases/v1.22.0.md @@ -0,0 +1,69 @@ +--- +id: v1.22.0 +title: v1.22.0 +description: Backstage Release v1.22.0 +--- + +These are the release notes for the v1.22.0 release of [Backstage](https://backstage.io/). + +A huge thanks to the whole team of maintainers and contributors as well as the amazing Backstage Community for the hard work in getting this release developed and done. + +## Highlights + +### Updates to new frontend system + +There have been several updates to alpha packages in the new frontend system including a breaking change where the `app/router` extension was renamed to `app/root`. Furthermore `elements`, `wrappers`, and `router` were added as inputs to `app/root` making it possible to pass extensions into the root of the app. + +### Plugins and modules migrated to the New Backend System + +Some more features have been migrated to the new backend system: + +- `@backstage/plugin-auth-backend-module-microsoft-provider` +- `@backstage/plugin-auth-backend-module-pinniped-provider` +- `@backstage/plugin-catalog-backend-module-openapi` +- `@backstage/plugin-events-backend-module-azure` +- `@backstage/plugin-events-backend-module-bitbucket-cloud` +- `@backstage/plugin-events-backend-module-gerrit` +- `@backstage/plugin-linguist` + +### New plugin: App Visualizer + +This release includes the new `@backstage/plugin-app-visualizer` package. This plugin for the new frontend system lets you browse and view the extension structure of your app as a graph, detailed list, or in text form. + +### New feature: Dynamic Feature Service + +This release includes the new `@backstage/backend-dynamic-feature-service` package. +It is a new and experimental service that lets you dynamically detect and load local plugins and modules in your Backstage instance. + +Contributed by [@davidfestal](https://github.com/davidfestal) in [#18862](https://github.com/backstage/backstage/pull/18862) + +### New Scaffolder action `gitlab:issues:create` + +You can now create GitHub issues in your scaffolder flows! Contributed by [@elaine-mattos](https://github.com/elaine-mattos) in [#21929](https://github.com/backstage/backstage/pull/21929) + +### New Scaffolder action `gitlab:repo:push` + +You can now push raw branches to GitLab in your scaffolder flows! Contributed by [@gavlyukovskiy](https://github.com/gavlyukovskiy) in [#21977](https://github.com/backstage/backstage/pull/21977) + +## Security Fixes + +This release does not contain any security fixes. + +However, some updates were made to the build facilities in the CLI and the caches in the backend system, such that you can now perform builds on FIPS compliant systems. This may lead to some internal cache invalidation happening, since the hashing algorithms used were updated. This should not pose a problem unless caches were being used as reliable persistent storage systems. Please let us know if you encounter any issues that may be related to this. + +## Upgrade path + +We recommend that you keep your Backstage project up to date with this latest release. For more guidance on how to upgrade, check out the documentation for [keeping Backstage updated](https://backstage.io/docs/getting-started/keeping-backstage-updated). + +## Links and References + +Below you can find a list of links and references to help you learn about and start using this new release. + +- [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) +- [GitHub repository](https://github.com/backstage/backstage) +- Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support +- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.22.0-changelog.md) +- Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) + +Sign up for our [newsletter](https://info.backstage.spotify.com/newsletter_subscribe) if you want to be informed about what is happening in the world of Backstage. diff --git a/microsite/docusaurus.config.js b/microsite/docusaurus.config.js index 85ffacd39d..f2e44aa0d2 100644 --- a/microsite/docusaurus.config.js +++ b/microsite/docusaurus.config.js @@ -182,7 +182,7 @@ module.exports = { position: 'left', }, { - to: 'docs/releases/v1.21.0', + to: 'docs/releases/v1.22.0', label: 'Releases', position: 'left', }, diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 5dd5ce93f8..c54e59f45c 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -1,6 +1,7 @@ { "releases": { "Release Notes": [ + "releases/v1.22.0", "releases/v1.21.0", "releases/v1.20.0", "releases/v1.19.0", From 41dc09ccb7867a00074a0a4843aa655607c1cfa9 Mon Sep 17 00:00:00 2001 From: AmbrishRamachandiran Date: Tue, 16 Jan 2024 16:43:15 +0530 Subject: [PATCH 085/283] changes done as per review Signed-off-by: AmbrishRamachandiran --- .changeset/curvy-ladybugs-impress.md | 2 +- plugins/adr/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/curvy-ladybugs-impress.md b/.changeset/curvy-ladybugs-impress.md index ffeb76399a..3ea90f513a 100644 --- a/.changeset/curvy-ladybugs-impress.md +++ b/.changeset/curvy-ladybugs-impress.md @@ -2,4 +2,4 @@ '@backstage/plugin-adr': patch --- -Updated Readme document in adr plugin +Updated README document in adr plugin diff --git a/plugins/adr/README.md b/plugins/adr/README.md index 4a1f3a7552..3e8647a8fa 100644 --- a/plugins/adr/README.md +++ b/plugins/adr/README.md @@ -2,7 +2,7 @@ Welcome to the ADR plugin! -This plugin allows you to explore ADRs connected with your entities, as well as discover ADRs across other entities using Backstage Search. Use this to inform your own architectural decisions based on the experiences of previous projects. +This plugin allows you to explore ADRs (Architecture Decision Records) associated with your entities, as well as discover ADRs across other entities using Backstage Search. Use this to inform your own architectural decisions based on the experiences of previous projects. ![ADR tab](./docs/adr-tab.png) From 8070f67dc46b6006ab9f034e1c8e85e522f9538a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 16 Jan 2024 11:44:56 +0000 Subject: [PATCH 086/283] Version Packages --- .changeset/afraid-mice-give.md | 5 - .changeset/beige-pillows-repeat.md | 5 - .changeset/blue-hats-admire.md | 5 - .changeset/brave-ghosts-pay.md | 5 - .changeset/brave-queens-crash.md | 5 - .changeset/brave-shirts-hang.md | 5 - .changeset/brown-planes-sort.md | 5 - .changeset/calm-grapes-remember.md | 5 - .changeset/chatty-rivers-hope.md | 5 - .changeset/chilled-seahorses-clean.md | 5 - .changeset/chilled-zebras-wash.md | 5 - .changeset/clean-mails-bathe.md | 5 - .changeset/clever-meals-drop.md | 5 - .changeset/create-app-1703547661.md | 5 - .changeset/create-app-1704804195.md | 5 - .changeset/curvy-dingos-jump.md | 5 - .changeset/eight-rice-cross.md | 5 - .changeset/fair-spies-rescue.md | 5 - .changeset/fast-tables-hammer.md | 7 - .changeset/flat-terms-provide.md | 5 - .changeset/fresh-mirrors-shake.md | 5 - .changeset/friendly-horses-kneel.md | 5 - .changeset/funny-rings-fry.md | 8 - .changeset/giant-fans-type.md | 5 - .changeset/gold-pianos-worry.md | 5 - .changeset/great-adults-begin.md | 14 - .changeset/green-dolphins-cover.md | 6 - .changeset/happy-forks-jam.md | 5 - .changeset/heavy-moose-reflect.md | 5 - .changeset/hip-dancers-pay.md | 5 - .changeset/large-pens-cough.md | 6 - .changeset/large-poets-buy.md | 5 - .changeset/lazy-teachers-walk.md | 5 - .changeset/many-peaches-dress.md | 9 - .changeset/new-plants-sort.md | 8 - .changeset/ninety-impalas-knock.md | 5 - .changeset/odd-ligers-return.md | 7 - .changeset/olive-walls-wonder.md | 6 - .changeset/olive-walls-wonder2.md | 5 - .changeset/orange-planets-suffer.md | 8 - .changeset/pre.json | 297 -- .changeset/quiet-oranges-bake.md | 11 - .changeset/renovate-126fde4.md | 6 - .changeset/renovate-91133b2.md | 11 - .changeset/renovate-9647667.md | 6 - .changeset/rich-poets-stare.md | 6 - .changeset/rotten-tools-clean.md | 145 - .changeset/shaggy-coins-happen.md | 8 - .changeset/silent-horses-raise.md | 7 - .changeset/silver-countries-notice.md | 5 - .changeset/sixty-plums-switch.md | 5 - .changeset/smooth-pumas-fold.md | 5 - .changeset/sour-taxis-rush.md | 5 - .changeset/stale-cars-attack.md | 6 - .changeset/stale-hairs-sparkle.md | 5 - .changeset/tender-roses-teach.md | 8 - .changeset/thirty-cats-help.md | 5 - .changeset/tricky-pans-explain.md | 5 - .changeset/unlucky-bottles-run.md | 5 - .changeset/weak-pans-accept.md | 5 - docs/releases/v1.22.0-changelog.md | 3239 +++++++++++++++++ package.json | 2 +- packages/app-defaults/CHANGELOG.md | 11 + packages/app-defaults/package.json | 2 +- packages/app-next-example-plugin/CHANGELOG.md | 8 + packages/app-next-example-plugin/package.json | 2 +- packages/app-next/CHANGELOG.md | 76 + packages/app-next/package.json | 2 +- packages/app/CHANGELOG.md | 76 + packages/app/package.json | 2 +- packages/backend-app-api/CHANGELOG.md | 18 + packages/backend-app-api/package.json | 2 +- packages/backend-common/CHANGELOG.md | 23 + packages/backend-common/package.json | 2 +- packages/backend-defaults/CHANGELOG.md | 10 + packages/backend-defaults/package.json | 2 +- packages/backend-dev-utils/CHANGELOG.md | 6 + packages/backend-dev-utils/package.json | 2 +- .../CHANGELOG.md | 27 + .../package.json | 2 +- packages/backend-next/CHANGELOG.md | 41 + packages/backend-next/package.json | 2 +- packages/backend-openapi-utils/CHANGELOG.md | 9 + packages/backend-openapi-utils/package.json | 2 +- packages/backend-plugin-api/CHANGELOG.md | 12 + packages/backend-plugin-api/package.json | 2 +- packages/backend-tasks/CHANGELOG.md | 10 + packages/backend-tasks/package.json | 2 +- packages/backend-test-utils/CHANGELOG.md | 13 + packages/backend-test-utils/package.json | 2 +- packages/backend/CHANGELOG.md | 58 + packages/backend/package.json | 2 +- packages/catalog-client/CHANGELOG.md | 9 + packages/catalog-client/package.json | 2 +- packages/cli-node/CHANGELOG.md | 10 + packages/cli-node/package.json | 2 +- packages/cli/CHANGELOG.md | 20 + packages/cli/package.json | 2 +- packages/config-loader/CHANGELOG.md | 11 + packages/config-loader/package.json | 2 +- packages/core-app-api/CHANGELOG.md | 10 + packages/core-app-api/package.json | 2 +- packages/core-compat-api/CHANGELOG.md | 11 + packages/core-compat-api/package.json | 2 +- packages/core-components/CHANGELOG.md | 13 + packages/core-components/package.json | 2 +- packages/core-plugin-api/CHANGELOG.md | 10 + packages/core-plugin-api/package.json | 2 +- packages/create-app/CHANGELOG.md | 10 + packages/create-app/package.json | 2 +- packages/dev-utils/CHANGELOG.md | 14 + packages/dev-utils/package.json | 2 +- packages/e2e-test/CHANGELOG.md | 9 + packages/e2e-test/package.json | 2 +- packages/frontend-app-api/CHANGELOG.md | 24 + packages/frontend-app-api/package.json | 2 +- packages/frontend-plugin-api/CHANGELOG.md | 19 + packages/frontend-plugin-api/package.json | 2 +- packages/frontend-test-utils/CHANGELOG.md | 13 + packages/frontend-test-utils/package.json | 2 +- packages/integration-react/CHANGELOG.md | 9 + packages/integration-react/package.json | 2 +- packages/repo-tools/CHANGELOG.md | 13 + packages/repo-tools/package.json | 2 +- .../techdocs-cli-embedded-app/CHANGELOG.md | 19 + .../techdocs-cli-embedded-app/package.json | 2 +- packages/techdocs-cli/CHANGELOG.md | 11 + packages/techdocs-cli/package.json | 2 +- packages/test-utils/CHANGELOG.md | 13 + packages/test-utils/package.json | 2 +- plugins/adr-backend/CHANGELOG.md | 16 + plugins/adr-backend/package.json | 2 +- plugins/adr-common/CHANGELOG.md | 9 + plugins/adr-common/package.json | 2 +- plugins/adr/CHANGELOG.md | 16 + plugins/adr/package.json | 2 +- plugins/airbrake-backend/CHANGELOG.md | 10 + plugins/airbrake-backend/package.json | 2 +- plugins/airbrake/CHANGELOG.md | 13 + plugins/airbrake/package.json | 2 +- plugins/allure/CHANGELOG.md | 11 + plugins/allure/package.json | 2 +- plugins/analytics-module-ga/CHANGELOG.md | 10 + plugins/analytics-module-ga/package.json | 2 +- plugins/analytics-module-ga4/CHANGELOG.md | 10 + plugins/analytics-module-ga4/package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- plugins/apache-airflow/CHANGELOG.md | 9 + plugins/apache-airflow/package.json | 2 +- plugins/api-docs/CHANGELOG.md | 16 + plugins/api-docs/package.json | 2 +- plugins/apollo-explorer/CHANGELOG.md | 9 + plugins/apollo-explorer/package.json | 2 +- plugins/app-backend/CHANGELOG.md | 13 + plugins/app-backend/package.json | 2 +- plugins/app-node/CHANGELOG.md | 7 + plugins/app-node/package.json | 2 +- plugins/app-visualizer/CHANGELOG.md | 14 + plugins/app-visualizer/package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- plugins/auth-backend/CHANGELOG.md | 24 + plugins/auth-backend/package.json | 2 +- plugins/auth-node/CHANGELOG.md | 13 + plugins/auth-node/package.json | 2 +- plugins/azure-devops-backend/CHANGELOG.md | 16 + plugins/azure-devops-backend/package.json | 2 +- plugins/azure-devops/CHANGELOG.md | 13 + plugins/azure-devops/package.json | 2 +- plugins/azure-sites-backend/CHANGELOG.md | 10 + plugins/azure-sites-backend/package.json | 2 +- plugins/azure-sites/CHANGELOG.md | 13 + plugins/azure-sites/package.json | 2 +- plugins/badges-backend/CHANGELOG.md | 14 + plugins/badges-backend/package.json | 2 +- plugins/badges/CHANGELOG.md | 12 + plugins/badges/package.json | 2 +- plugins/bazaar-backend/CHANGELOG.md | 11 + plugins/bazaar-backend/package.json | 2 +- plugins/bazaar/CHANGELOG.md | 13 + plugins/bazaar/package.json | 2 +- plugins/bitrise/CHANGELOG.md | 11 + plugins/bitrise/package.json | 2 +- .../catalog-backend-module-aws/CHANGELOG.md | 19 + .../catalog-backend-module-aws/package.json | 2 +- .../catalog-backend-module-azure/CHANGELOG.md | 14 + .../catalog-backend-module-azure/package.json | 2 +- .../CHANGELOG.md | 15 + .../package.json | 2 +- .../CHANGELOG.md | 17 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../catalog-backend-module-gcp/CHANGELOG.md | 13 + .../catalog-backend-module-gcp/package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 17 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 16 + .../package.json | 2 +- .../catalog-backend-module-ldap/CHANGELOG.md | 13 + .../catalog-backend-module-ldap/package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 26 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/catalog-backend/CHANGELOG.md | 24 + plugins/catalog-backend/package.json | 2 +- plugins/catalog-common/CHANGELOG.md | 9 + plugins/catalog-common/package.json | 2 +- plugins/catalog-graph/CHANGELOG.md | 13 + plugins/catalog-graph/package.json | 2 +- plugins/catalog-import/CHANGELOG.md | 18 + plugins/catalog-import/package.json | 2 +- plugins/catalog-node/CHANGELOG.md | 15 + plugins/catalog-node/package.json | 2 +- plugins/catalog-react/CHANGELOG.md | 19 + plugins/catalog-react/package.json | 2 +- .../catalog-unprocessed-entities/CHANGELOG.md | 11 + .../catalog-unprocessed-entities/package.json | 2 +- plugins/catalog/CHANGELOG.md | 22 + plugins/catalog/package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/cicd-statistics/CHANGELOG.md | 9 + plugins/cicd-statistics/package.json | 2 +- plugins/circleci/CHANGELOG.md | 11 + plugins/circleci/package.json | 2 +- plugins/cloudbuild/CHANGELOG.md | 11 + plugins/cloudbuild/package.json | 2 +- plugins/code-climate/CHANGELOG.md | 11 + plugins/code-climate/package.json | 2 +- plugins/code-coverage-backend/CHANGELOG.md | 15 + plugins/code-coverage-backend/package.json | 2 +- plugins/code-coverage/CHANGELOG.md | 12 + plugins/code-coverage/package.json | 2 +- plugins/codescene/CHANGELOG.md | 12 + plugins/codescene/package.json | 2 +- plugins/config-schema/CHANGELOG.md | 11 + plugins/config-schema/package.json | 2 +- plugins/cost-insights/CHANGELOG.md | 14 + plugins/cost-insights/package.json | 2 +- plugins/devtools-backend/CHANGELOG.md | 18 + plugins/devtools-backend/package.json | 2 +- plugins/devtools-common/CHANGELOG.md | 8 + plugins/devtools-common/package.json | 2 +- plugins/devtools/CHANGELOG.md | 12 + plugins/devtools/package.json | 2 +- plugins/dynatrace/CHANGELOG.md | 11 + plugins/dynatrace/package.json | 2 +- plugins/entity-feedback-backend/CHANGELOG.md | 14 + plugins/entity-feedback-backend/package.json | 2 +- plugins/entity-feedback/CHANGELOG.md | 13 + plugins/entity-feedback/package.json | 2 +- plugins/entity-validation/CHANGELOG.md | 14 + plugins/entity-validation/package.json | 2 +- .../CHANGELOG.md | 18 + .../package.json | 2 +- .../events-backend-module-azure/CHANGELOG.md | 10 + .../events-backend-module-azure/package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../events-backend-module-gerrit/CHANGELOG.md | 10 + .../events-backend-module-gerrit/package.json | 2 +- .../events-backend-module-github/CHANGELOG.md | 10 + .../events-backend-module-github/package.json | 2 +- .../events-backend-module-gitlab/CHANGELOG.md | 10 + .../events-backend-module-gitlab/package.json | 2 +- .../events-backend-test-utils/CHANGELOG.md | 7 + .../events-backend-test-utils/package.json | 2 +- plugins/events-backend/CHANGELOG.md | 12 + plugins/events-backend/package.json | 2 +- plugins/events-node/CHANGELOG.md | 7 + plugins/events-node/package.json | 2 +- .../example-todo-list-backend/CHANGELOG.md | 10 + .../example-todo-list-backend/package.json | 2 +- plugins/example-todo-list-common/CHANGELOG.md | 7 + plugins/example-todo-list-common/package.json | 2 +- plugins/example-todo-list/CHANGELOG.md | 8 + plugins/example-todo-list/package.json | 2 +- plugins/explore-backend/CHANGELOG.md | 12 + plugins/explore-backend/package.json | 2 +- plugins/explore-react/CHANGELOG.md | 9 + plugins/explore-react/package.json | 2 +- plugins/explore/CHANGELOG.md | 17 + plugins/explore/package.json | 2 +- plugins/firehydrant/CHANGELOG.md | 11 + plugins/firehydrant/package.json | 2 +- plugins/fossa/CHANGELOG.md | 12 + plugins/fossa/package.json | 2 +- plugins/gcalendar/CHANGELOG.md | 10 + plugins/gcalendar/package.json | 2 +- plugins/gcp-projects/CHANGELOG.md | 9 + plugins/gcp-projects/package.json | 2 +- plugins/git-release-manager/CHANGELOG.md | 10 + plugins/git-release-manager/package.json | 2 +- plugins/github-actions/CHANGELOG.md | 13 + plugins/github-actions/package.json | 2 +- plugins/github-deployments/CHANGELOG.md | 14 + plugins/github-deployments/package.json | 2 +- plugins/github-issues/CHANGELOG.md | 14 + plugins/github-issues/package.json | 2 +- .../github-pull-requests-board/CHANGELOG.md | 12 + .../github-pull-requests-board/package.json | 2 +- plugins/gitops-profiles/CHANGELOG.md | 9 + plugins/gitops-profiles/package.json | 2 +- plugins/gocd/CHANGELOG.md | 12 + plugins/gocd/package.json | 2 +- plugins/graphiql/CHANGELOG.md | 11 + plugins/graphiql/package.json | 2 +- plugins/graphql-voyager/CHANGELOG.md | 9 + plugins/graphql-voyager/package.json | 2 +- plugins/home-react/CHANGELOG.md | 13 + plugins/home-react/package.json | 2 +- plugins/home/CHANGELOG.md | 21 + plugins/home/package.json | 2 +- plugins/ilert/CHANGELOG.md | 12 + plugins/ilert/package.json | 2 +- plugins/jenkins-backend/CHANGELOG.md | 18 + plugins/jenkins-backend/package.json | 2 +- plugins/jenkins-common/CHANGELOG.md | 8 + plugins/jenkins-common/package.json | 2 +- plugins/jenkins/CHANGELOG.md | 13 + plugins/jenkins/package.json | 2 +- plugins/kafka-backend/CHANGELOG.md | 11 + plugins/kafka-backend/package.json | 2 +- plugins/kafka/CHANGELOG.md | 11 + plugins/kafka/package.json | 2 +- plugins/kubernetes-backend/CHANGELOG.md | 20 + plugins/kubernetes-backend/package.json | 2 +- plugins/kubernetes-cluster/CHANGELOG.md | 13 + plugins/kubernetes-cluster/package.json | 2 +- plugins/kubernetes-common/CHANGELOG.md | 10 + plugins/kubernetes-common/package.json | 2 +- plugins/kubernetes-node/CHANGELOG.md | 10 + plugins/kubernetes-node/package.json | 2 +- plugins/kubernetes-react/CHANGELOG.md | 16 + plugins/kubernetes-react/package.json | 2 +- plugins/kubernetes/CHANGELOG.md | 17 + plugins/kubernetes/package.json | 2 +- plugins/lighthouse-backend/CHANGELOG.md | 15 + plugins/lighthouse-backend/package.json | 2 +- plugins/lighthouse/CHANGELOG.md | 12 + plugins/lighthouse/package.json | 2 +- plugins/linguist-backend/CHANGELOG.md | 18 + plugins/linguist-backend/package.json | 2 +- plugins/linguist/CHANGELOG.md | 16 + plugins/linguist/package.json | 2 +- plugins/microsoft-calendar/CHANGELOG.md | 10 + plugins/microsoft-calendar/package.json | 2 +- plugins/newrelic-dashboard/CHANGELOG.md | 12 + plugins/newrelic-dashboard/package.json | 2 +- plugins/newrelic/CHANGELOG.md | 9 + plugins/newrelic/package.json | 2 +- plugins/nomad-backend/CHANGELOG.md | 11 + plugins/nomad-backend/package.json | 2 +- plugins/nomad/CHANGELOG.md | 11 + plugins/nomad/package.json | 2 +- plugins/octopus-deploy/CHANGELOG.md | 12 + plugins/octopus-deploy/package.json | 2 +- plugins/opencost/CHANGELOG.md | 9 + plugins/opencost/package.json | 2 +- plugins/org-react/CHANGELOG.md | 12 + plugins/org-react/package.json | 2 +- plugins/org/CHANGELOG.md | 12 + plugins/org/package.json | 2 +- plugins/pagerduty/CHANGELOG.md | 13 + plugins/pagerduty/package.json | 2 +- plugins/periskop-backend/CHANGELOG.md | 10 + plugins/periskop-backend/package.json | 2 +- plugins/periskop/CHANGELOG.md | 12 + plugins/periskop/package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- plugins/permission-backend/CHANGELOG.md | 14 + plugins/permission-backend/package.json | 2 +- plugins/permission-common/CHANGELOG.md | 10 + plugins/permission-common/package.json | 2 +- plugins/permission-node/CHANGELOG.md | 13 + plugins/permission-node/package.json | 2 +- plugins/permission-react/CHANGELOG.md | 11 + plugins/permission-react/package.json | 2 +- plugins/playlist-backend/CHANGELOG.md | 17 + plugins/playlist-backend/package.json | 2 +- plugins/playlist-common/CHANGELOG.md | 7 + plugins/playlist-common/package.json | 2 +- plugins/playlist/CHANGELOG.md | 17 + plugins/playlist/package.json | 2 +- plugins/proxy-backend/CHANGELOG.md | 9 + plugins/proxy-backend/package.json | 2 +- plugins/puppetdb/CHANGELOG.md | 12 + plugins/puppetdb/package.json | 2 +- plugins/rollbar-backend/CHANGELOG.md | 8 + plugins/rollbar-backend/package.json | 2 +- plugins/rollbar/CHANGELOG.md | 11 + plugins/rollbar/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 10 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- .../CHANGELOG.md | 9 + .../package.json | 2 +- plugins/scaffolder-backend/CHANGELOG.md | 33 + plugins/scaffolder-backend/package.json | 2 +- plugins/scaffolder-common/CHANGELOG.md | 10 + plugins/scaffolder-common/package.json | 2 +- plugins/scaffolder-node/CHANGELOG.md | 13 + plugins/scaffolder-node/package.json | 2 +- plugins/scaffolder-react/CHANGELOG.md | 23 + plugins/scaffolder-react/package.json | 2 +- plugins/scaffolder/CHANGELOG.md | 25 + plugins/scaffolder/package.json | 2 +- .../CHANGELOG.md | 19 + .../package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- .../CHANGELOG.md | 14 + .../package.json | 2 +- plugins/search-backend-module-pg/CHANGELOG.md | 11 + plugins/search-backend-module-pg/package.json | 2 +- .../CHANGELOG.md | 13 + .../package.json | 2 +- .../CHANGELOG.md | 19 + .../package.json | 2 +- plugins/search-backend-node/CHANGELOG.md | 13 + plugins/search-backend-node/package.json | 2 +- plugins/search-backend/CHANGELOG.md | 18 + plugins/search-backend/package.json | 2 +- plugins/search-common/CHANGELOG.md | 8 + plugins/search-common/package.json | 2 +- plugins/search-react/CHANGELOG.md | 13 + plugins/search-react/package.json | 2 +- plugins/search/CHANGELOG.md | 17 + plugins/search/package.json | 2 +- plugins/sentry/CHANGELOG.md | 11 + plugins/sentry/package.json | 2 +- plugins/shortcuts/CHANGELOG.md | 11 + plugins/shortcuts/package.json | 2 +- plugins/sonarqube-backend/CHANGELOG.md | 11 + plugins/sonarqube-backend/package.json | 2 +- plugins/sonarqube-react/CHANGELOG.md | 8 + plugins/sonarqube-react/package.json | 2 +- plugins/sonarqube/CHANGELOG.md | 12 + plugins/sonarqube/package.json | 2 +- plugins/splunk-on-call/CHANGELOG.md | 11 + plugins/splunk-on-call/package.json | 2 +- plugins/stack-overflow-backend/CHANGELOG.md | 8 + plugins/stack-overflow-backend/package.json | 2 +- plugins/stack-overflow/CHANGELOG.md | 14 + plugins/stack-overflow/package.json | 2 +- plugins/stackstorm/CHANGELOG.md | 10 + plugins/stackstorm/package.json | 2 +- .../CHANGELOG.md | 11 + .../package.json | 2 +- plugins/tech-insights-backend/CHANGELOG.md | 15 + plugins/tech-insights-backend/package.json | 2 +- plugins/tech-insights-node/CHANGELOG.md | 11 + plugins/tech-insights-node/package.json | 2 +- plugins/tech-insights/CHANGELOG.md | 14 + plugins/tech-insights/package.json | 2 +- plugins/tech-radar/CHANGELOG.md | 11 + plugins/tech-radar/package.json | 2 +- .../techdocs-addons-test-utils/CHANGELOG.md | 16 + .../techdocs-addons-test-utils/package.json | 2 +- plugins/techdocs-backend/CHANGELOG.md | 18 + plugins/techdocs-backend/package.json | 2 +- .../CHANGELOG.md | 12 + .../package.json | 2 +- plugins/techdocs-node/CHANGELOG.md | 14 + plugins/techdocs-node/package.json | 2 +- plugins/techdocs-react/CHANGELOG.md | 12 + plugins/techdocs-react/package.json | 2 +- plugins/techdocs/CHANGELOG.md | 21 + plugins/techdocs/package.json | 2 +- plugins/todo-backend/CHANGELOG.md | 16 + plugins/todo-backend/package.json | 2 +- plugins/todo/CHANGELOG.md | 12 + plugins/todo/package.json | 2 +- plugins/user-settings-backend/CHANGELOG.md | 13 + plugins/user-settings-backend/package.json | 2 +- plugins/user-settings/CHANGELOG.md | 21 + plugins/user-settings/package.json | 2 +- plugins/vault-backend/CHANGELOG.md | 12 + plugins/vault-backend/package.json | 2 +- plugins/vault-node/CHANGELOG.md | 7 + plugins/vault-node/package.json | 2 +- plugins/vault/CHANGELOG.md | 12 + plugins/vault/package.json | 2 +- plugins/xcmetrics/CHANGELOG.md | 10 + plugins/xcmetrics/package.json | 2 +- yarn.lock | 361 +- 539 files changed, 6788 insertions(+), 1310 deletions(-) delete mode 100644 .changeset/afraid-mice-give.md delete mode 100644 .changeset/beige-pillows-repeat.md delete mode 100644 .changeset/blue-hats-admire.md delete mode 100644 .changeset/brave-ghosts-pay.md delete mode 100644 .changeset/brave-queens-crash.md delete mode 100644 .changeset/brave-shirts-hang.md delete mode 100644 .changeset/brown-planes-sort.md delete mode 100644 .changeset/calm-grapes-remember.md delete mode 100644 .changeset/chatty-rivers-hope.md delete mode 100644 .changeset/chilled-seahorses-clean.md delete mode 100644 .changeset/chilled-zebras-wash.md delete mode 100644 .changeset/clean-mails-bathe.md delete mode 100644 .changeset/clever-meals-drop.md delete mode 100644 .changeset/create-app-1703547661.md delete mode 100644 .changeset/create-app-1704804195.md delete mode 100644 .changeset/curvy-dingos-jump.md delete mode 100644 .changeset/eight-rice-cross.md delete mode 100644 .changeset/fair-spies-rescue.md delete mode 100644 .changeset/fast-tables-hammer.md delete mode 100644 .changeset/flat-terms-provide.md delete mode 100644 .changeset/fresh-mirrors-shake.md delete mode 100644 .changeset/friendly-horses-kneel.md delete mode 100644 .changeset/funny-rings-fry.md delete mode 100644 .changeset/giant-fans-type.md delete mode 100644 .changeset/gold-pianos-worry.md delete mode 100644 .changeset/great-adults-begin.md delete mode 100644 .changeset/green-dolphins-cover.md delete mode 100644 .changeset/happy-forks-jam.md delete mode 100644 .changeset/heavy-moose-reflect.md delete mode 100644 .changeset/hip-dancers-pay.md delete mode 100644 .changeset/large-pens-cough.md delete mode 100644 .changeset/large-poets-buy.md delete mode 100644 .changeset/lazy-teachers-walk.md delete mode 100644 .changeset/many-peaches-dress.md delete mode 100644 .changeset/new-plants-sort.md delete mode 100644 .changeset/ninety-impalas-knock.md delete mode 100644 .changeset/odd-ligers-return.md delete mode 100644 .changeset/olive-walls-wonder.md delete mode 100644 .changeset/olive-walls-wonder2.md delete mode 100644 .changeset/orange-planets-suffer.md delete mode 100644 .changeset/pre.json delete mode 100644 .changeset/quiet-oranges-bake.md delete mode 100644 .changeset/renovate-126fde4.md delete mode 100644 .changeset/renovate-91133b2.md delete mode 100644 .changeset/renovate-9647667.md delete mode 100644 .changeset/rich-poets-stare.md delete mode 100644 .changeset/rotten-tools-clean.md delete mode 100644 .changeset/shaggy-coins-happen.md delete mode 100644 .changeset/silent-horses-raise.md delete mode 100644 .changeset/silver-countries-notice.md delete mode 100644 .changeset/sixty-plums-switch.md delete mode 100644 .changeset/smooth-pumas-fold.md delete mode 100644 .changeset/sour-taxis-rush.md delete mode 100644 .changeset/stale-cars-attack.md delete mode 100644 .changeset/stale-hairs-sparkle.md delete mode 100644 .changeset/tender-roses-teach.md delete mode 100644 .changeset/thirty-cats-help.md delete mode 100644 .changeset/tricky-pans-explain.md delete mode 100644 .changeset/unlucky-bottles-run.md delete mode 100644 .changeset/weak-pans-accept.md create mode 100644 docs/releases/v1.22.0-changelog.md create mode 100644 plugins/app-visualizer/CHANGELOG.md diff --git a/.changeset/afraid-mice-give.md b/.changeset/afraid-mice-give.md deleted file mode 100644 index 8d6424f536..0000000000 --- a/.changeset/afraid-mice-give.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend': patch ---- - -Fixed an issue where some Okta's resolvers were missing diff --git a/.changeset/beige-pillows-repeat.md b/.changeset/beige-pillows-repeat.md deleted file mode 100644 index 0c0eb3f4fa..0000000000 --- a/.changeset/beige-pillows-repeat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-codescene': patch ---- - -Updated Readme document in codescene plugin diff --git a/.changeset/blue-hats-admire.md b/.changeset/blue-hats-admire.md deleted file mode 100644 index 0be0c7d25f..0000000000 --- a/.changeset/blue-hats-admire.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-api-docs': patch ---- - -Fix custom http resolvers for AsyncAPI widget. diff --git a/.changeset/brave-ghosts-pay.md b/.changeset/brave-ghosts-pay.md deleted file mode 100644 index d8981fa53b..0000000000 --- a/.changeset/brave-ghosts-pay.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend-module-pinniped-provider': patch ---- - -Deprecated the `authModulePinnipedProvider` export. A default export is now available and should be used like this in your backend: `backend.add(import('@backstage/plugin-auth-backend-module-pinniped-provider'));` diff --git a/.changeset/brave-queens-crash.md b/.changeset/brave-queens-crash.md deleted file mode 100644 index c28e5975f3..0000000000 --- a/.changeset/brave-queens-crash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-compat-api': patch ---- - -Make `convertLegacyApp` wrap discovered routes with `compatWrapper`. diff --git a/.changeset/brave-shirts-hang.md b/.changeset/brave-shirts-hang.md deleted file mode 100644 index 4fa7e4ef77..0000000000 --- a/.changeset/brave-shirts-hang.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Adding support for removing file from git index diff --git a/.changeset/brown-planes-sort.md b/.changeset/brown-planes-sort.md deleted file mode 100644 index 2291f950c0..0000000000 --- a/.changeset/brown-planes-sort.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': patch ---- - -Scaffolder form now shows a list of errors at the top of the form. diff --git a/.changeset/calm-grapes-remember.md b/.changeset/calm-grapes-remember.md deleted file mode 100644 index f21a074c74..0000000000 --- a/.changeset/calm-grapes-remember.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-plugin-api': patch ---- - -Exposed `createComponentRef`, and ensured that produced refs and feature bits have a `toString` for easier debugging diff --git a/.changeset/chatty-rivers-hope.md b/.changeset/chatty-rivers-hope.md deleted file mode 100644 index 97fdd644fe..0000000000 --- a/.changeset/chatty-rivers-hope.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-sonarqube-backend': patch ---- - -Updated README diff --git a/.changeset/chilled-seahorses-clean.md b/.changeset/chilled-seahorses-clean.md deleted file mode 100644 index aa3ae4d062..0000000000 --- a/.changeset/chilled-seahorses-clean.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Fixed bug in Link where it was possible to select and copy a hidden element into clipboard diff --git a/.changeset/chilled-zebras-wash.md b/.changeset/chilled-zebras-wash.md deleted file mode 100644 index 9597915ce5..0000000000 --- a/.changeset/chilled-zebras-wash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-user-settings': patch ---- - -add user-settings declarative integration core nav item diff --git a/.changeset/clean-mails-bathe.md b/.changeset/clean-mails-bathe.md deleted file mode 100644 index c9afc34f90..0000000000 --- a/.changeset/clean-mails-bathe.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-dynamic-feature-service': minor ---- - -New `backend-dynamic-feature-service` package, for the discovery of dynamic frontend and backend plugins (and modules) and the loading of the backend ones inside the backend application. diff --git a/.changeset/clever-meals-drop.md b/.changeset/clever-meals-drop.md deleted file mode 100644 index 63ceb1a4d3..0000000000 --- a/.changeset/clever-meals-drop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-api-docs': patch ---- - -Add permission check to Register Existing API button diff --git a/.changeset/create-app-1703547661.md b/.changeset/create-app-1703547661.md deleted file mode 100644 index b50d431d4b..0000000000 --- a/.changeset/create-app-1703547661.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Bumped create-app version. diff --git a/.changeset/create-app-1704804195.md b/.changeset/create-app-1704804195.md deleted file mode 100644 index b50d431d4b..0000000000 --- a/.changeset/create-app-1704804195.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Bumped create-app version. diff --git a/.changeset/curvy-dingos-jump.md b/.changeset/curvy-dingos-jump.md deleted file mode 100644 index 6b1c827e88..0000000000 --- a/.changeset/curvy-dingos-jump.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-azure-sites': patch ---- - -Show Azure site tags in `EntityAzureSitesOverviewWidget`. diff --git a/.changeset/eight-rice-cross.md b/.changeset/eight-rice-cross.md deleted file mode 100644 index 1628276817..0000000000 --- a/.changeset/eight-rice-cross.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Do not call fetch directly but rather use `fetchResponse` facility diff --git a/.changeset/fair-spies-rescue.md b/.changeset/fair-spies-rescue.md deleted file mode 100644 index d7f1ea5275..0000000000 --- a/.changeset/fair-spies-rescue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-github': patch ---- - -Ensure `teamReviewers` list is unique before calling API diff --git a/.changeset/fast-tables-hammer.md b/.changeset/fast-tables-hammer.md deleted file mode 100644 index 9ed5915073..0000000000 --- a/.changeset/fast-tables-hammer.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Use sha256 instead of md5 in build script cache key calculation - -Makes it possible to build on FIPS nodejs. diff --git a/.changeset/flat-terms-provide.md b/.changeset/flat-terms-provide.md deleted file mode 100644 index f7a22fa7ea..0000000000 --- a/.changeset/flat-terms-provide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-gitlab': patch ---- - -Add Scaffolder custom action that creates GitLab issues called `gitlab:issues:create` diff --git a/.changeset/fresh-mirrors-shake.md b/.changeset/fresh-mirrors-shake.md deleted file mode 100644 index a722182986..0000000000 --- a/.changeset/fresh-mirrors-shake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-common': patch ---- - -Updated Template.v1beta3.schema.json, added a missing "presentation" field diff --git a/.changeset/friendly-horses-kneel.md b/.changeset/friendly-horses-kneel.md deleted file mode 100644 index ebc11a7deb..0000000000 --- a/.changeset/friendly-horses-kneel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-plugin-api': patch ---- - -Removed unnecessary `i18next` dependency. diff --git a/.changeset/funny-rings-fry.md b/.changeset/funny-rings-fry.md deleted file mode 100644 index 66daec0ffb..0000000000 --- a/.changeset/funny-rings-fry.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Use sha256 instead of md5 for hash key calculation in caches - -This can have a side effect of invalidating caches (when cache key was >250 characters) -This improves compliance with FIPS nodejs diff --git a/.changeset/giant-fans-type.md b/.changeset/giant-fans-type.md deleted file mode 100644 index 64f32423d5..0000000000 --- a/.changeset/giant-fans-type.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': patch ---- - -Fix for a step with no properties diff --git a/.changeset/gold-pianos-worry.md b/.changeset/gold-pianos-worry.md deleted file mode 100644 index 39095dbbd7..0000000000 --- a/.changeset/gold-pianos-worry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Fixed an issue where not passing a `value` to any of the action's permission conditions caused an error. diff --git a/.changeset/great-adults-begin.md b/.changeset/great-adults-begin.md deleted file mode 100644 index 697613afc0..0000000000 --- a/.changeset/great-adults-begin.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-openapi': patch ---- - -Add support for the new backend system. - -A new backend module for the catalog backend -was added and exported as `default`. - -You can use it with the new backend system like - -```ts title="packages/backend/src/index.ts" -backend.add(import('@backstage/plugin-catalog-backend-module-openapi')); -``` diff --git a/.changeset/green-dolphins-cover.md b/.changeset/green-dolphins-cover.md deleted file mode 100644 index 77c90e72f5..0000000000 --- a/.changeset/green-dolphins-cover.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-bitbucket': patch -'@backstage/plugin-scaffolder-backend': minor ---- - -The Scaffolder builtin actions now contains an action for running pipelines from Bitbucket Cloud Rest API diff --git a/.changeset/happy-forks-jam.md b/.changeset/happy-forks-jam.md deleted file mode 100644 index 3f48853311..0000000000 --- a/.changeset/happy-forks-jam.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-user-settings': minor ---- - -Updated the user settings selector to use a select component that displays native language names instead of language codes if possible. diff --git a/.changeset/heavy-moose-reflect.md b/.changeset/heavy-moose-reflect.md deleted file mode 100644 index 011d3fc023..0000000000 --- a/.changeset/heavy-moose-reflect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend-module-microsoft-provider': patch ---- - -Deprecated the `authModuleMicrosoftProvider` export. A default export is now available and should be used like this in your backend: `backend.add(import('@backstage/plugin-auth-backend-module-microsoft-provider'));` diff --git a/.changeset/hip-dancers-pay.md b/.changeset/hip-dancers-pay.md deleted file mode 100644 index b05a291f85..0000000000 --- a/.changeset/hip-dancers-pay.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-octopus-deploy': patch ---- - -added install path and fixed import on plugin-octopus-deploy diff --git a/.changeset/large-pens-cough.md b/.changeset/large-pens-cough.md deleted file mode 100644 index 631a20aee2..0000000000 --- a/.changeset/large-pens-cough.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/frontend-plugin-api': patch -'@backstage/frontend-app-api': patch ---- - -Accepts sub route refs on the new `createPlugin` routes map. diff --git a/.changeset/large-poets-buy.md b/.changeset/large-poets-buy.md deleted file mode 100644 index f22ca7c6b8..0000000000 --- a/.changeset/large-poets-buy.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/catalog-client': patch ---- - -Fix a bug in `getLocationByRef` that led to invalid backend calls diff --git a/.changeset/lazy-teachers-walk.md b/.changeset/lazy-teachers-walk.md deleted file mode 100644 index 92f9a63d1e..0000000000 --- a/.changeset/lazy-teachers-walk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/repo-tools': patch ---- - -Updated the OpenAPI template to export the `TypedResponse` interface so that client code can leverage it diff --git a/.changeset/many-peaches-dress.md b/.changeset/many-peaches-dress.md deleted file mode 100644 index 42a4d86b68..0000000000 --- a/.changeset/many-peaches-dress.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch -'@backstage/config-loader': patch -'@backstage/create-app': patch -'@backstage/repo-tools': patch -'@backstage/cli-node': patch ---- - -Removed `mock-fs` dev dependency. diff --git a/.changeset/new-plants-sort.md b/.changeset/new-plants-sort.md deleted file mode 100644 index 16521df3c9..0000000000 --- a/.changeset/new-plants-sort.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-kubernetes-react': patch -'@backstage/plugin-kubernetes': patch ---- - -Add `authuser` search parameter to GKE cluster link formatter in k8s plugin - -Thanks to this, people with multiple simultaneously logged-in accounts in their GCP console will automatically view objects with the same email as the one signed in to the Google auth provider in Backstage. diff --git a/.changeset/ninety-impalas-knock.md b/.changeset/ninety-impalas-knock.md deleted file mode 100644 index 78bd55dc1c..0000000000 --- a/.changeset/ninety-impalas-knock.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-events-backend': patch ---- - -Update `README.md` diff --git a/.changeset/odd-ligers-return.md b/.changeset/odd-ligers-return.md deleted file mode 100644 index 6b7cdff593..0000000000 --- a/.changeset/odd-ligers-return.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-events-backend-module-bitbucket-cloud': patch -'@backstage/plugin-events-backend-module-gerrit': patch -'@backstage/plugin-events-backend-module-azure': patch ---- - -Add default exports for the new backend system and documentation. diff --git a/.changeset/olive-walls-wonder.md b/.changeset/olive-walls-wonder.md deleted file mode 100644 index db67697567..0000000000 --- a/.changeset/olive-walls-wonder.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/frontend-app-api': minor -'@backstage/frontend-plugin-api': minor ---- - -**BREAKING**: Renamed the `app/router` extension to `app/root`. diff --git a/.changeset/olive-walls-wonder2.md b/.changeset/olive-walls-wonder2.md deleted file mode 100644 index 6b1c447b94..0000000000 --- a/.changeset/olive-walls-wonder2.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-test-utils': patch ---- - -Updates to reflect the `app/router` extension having been renamed to `app/root`. diff --git a/.changeset/orange-planets-suffer.md b/.changeset/orange-planets-suffer.md deleted file mode 100644 index bc14a8cf8f..0000000000 --- a/.changeset/orange-planets-suffer.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-search-backend-module-stack-overflow-collator': patch -'@backstage/plugin-search-backend-module-techdocs': patch -'@backstage/plugin-search-backend-module-catalog': patch -'@backstage/plugin-search-backend-module-explore': patch ---- - -Update wording to show that the backend system no longer is in alpha diff --git a/.changeset/pre.json b/.changeset/pre.json deleted file mode 100644 index 2ca69b284d..0000000000 --- a/.changeset/pre.json +++ /dev/null @@ -1,297 +0,0 @@ -{ - "mode": "exit", - "tag": "next", - "initialVersions": { - "example-app": "0.2.90", - "@backstage/app-defaults": "1.4.6", - "example-app-next": "0.0.4", - "app-next-example-plugin": "0.0.4", - "example-backend": "0.2.90", - "@backstage/backend-app-api": "0.5.9", - "@backstage/backend-common": "0.20.0", - "@backstage/backend-defaults": "0.2.8", - "@backstage/backend-dev-utils": "0.1.2", - "example-backend-next": "0.0.18", - "@backstage/backend-openapi-utils": "0.1.1", - "@backstage/backend-plugin-api": "0.6.8", - "@backstage/backend-plugin-manager": "0.0.4", - "@backstage/backend-tasks": "0.5.13", - "@backstage/backend-test-utils": "0.2.9", - "@backstage/catalog-client": "1.5.0", - "@backstage/catalog-model": "1.4.3", - "@backstage/cli": "0.25.0", - "@backstage/cli-common": "0.1.13", - "@backstage/cli-node": "0.2.1", - "@backstage/codemods": "0.1.46", - "@backstage/config": "1.1.1", - "@backstage/config-loader": "1.6.0", - "@backstage/core-app-api": "1.11.2", - "@backstage/core-compat-api": "0.1.0", - "@backstage/core-components": "0.13.9", - "@backstage/core-plugin-api": "1.8.1", - "@backstage/create-app": "0.5.8", - "@backstage/dev-utils": "1.0.25", - "e2e-test": "0.2.10", - "@backstage/e2e-test-utils": "0.1.0", - "@backstage/errors": "1.2.3", - "@backstage/eslint-plugin": "0.1.4", - "@backstage/frontend-app-api": "0.4.0", - "@backstage/frontend-plugin-api": "0.4.0", - "@backstage/frontend-test-utils": "0.1.0", - "@backstage/integration": "1.8.0", - "@backstage/integration-aws-node": "0.1.8", - "@backstage/integration-react": "1.1.22", - "@backstage/release-manifests": "0.0.11", - "@backstage/repo-tools": "0.5.0", - "@techdocs/cli": "1.8.0", - "techdocs-cli-embedded-app": "0.2.89", - "@backstage/test-utils": "1.4.6", - "@backstage/theme": "0.5.0", - "@backstage/types": "1.1.1", - "@backstage/version-bridge": "1.0.7", - "@backstage/plugin-adr": "0.6.11", - "@backstage/plugin-adr-backend": "0.4.5", - "@backstage/plugin-adr-common": "0.2.18", - "@backstage/plugin-airbrake": "0.3.28", - "@backstage/plugin-airbrake-backend": "0.3.5", - "@backstage/plugin-allure": "0.1.44", - "@backstage/plugin-analytics-module-ga": "0.1.36", - "@backstage/plugin-analytics-module-ga4": "0.1.7", - "@backstage/plugin-analytics-module-newrelic-browser": "0.0.5", - "@backstage/plugin-apache-airflow": "0.2.18", - "@backstage/plugin-api-docs": "0.10.2", - "@backstage/plugin-api-docs-module-protoc-gen-doc": "0.1.5", - "@backstage/plugin-apollo-explorer": "0.1.18", - "@backstage/plugin-app-backend": "0.3.56", - "@backstage/plugin-app-node": "0.1.8", - "@backstage/plugin-auth-backend": "0.20.1", - "@backstage/plugin-auth-backend-module-atlassian-provider": "0.1.0", - "@backstage/plugin-auth-backend-module-gcp-iap-provider": "0.2.2", - "@backstage/plugin-auth-backend-module-github-provider": "0.1.5", - "@backstage/plugin-auth-backend-module-gitlab-provider": "0.1.5", - "@backstage/plugin-auth-backend-module-google-provider": "0.1.5", - "@backstage/plugin-auth-backend-module-microsoft-provider": "0.1.3", - "@backstage/plugin-auth-backend-module-oauth2-provider": "0.1.5", - "@backstage/plugin-auth-backend-module-oauth2-proxy-provider": "0.1.0", - "@backstage/plugin-auth-backend-module-okta-provider": "0.0.1", - "@backstage/plugin-auth-backend-module-pinniped-provider": "0.1.2", - "@backstage/plugin-auth-backend-module-vmware-cloud-provider": "0.1.0", - "@backstage/plugin-auth-node": "0.4.2", - "@backstage/plugin-azure-devops": "0.3.10", - "@backstage/plugin-azure-devops-backend": "0.5.0", - "@backstage/plugin-azure-devops-common": "0.3.2", - "@backstage/plugin-azure-sites": "0.1.17", - "@backstage/plugin-azure-sites-backend": "0.1.18", - "@backstage/plugin-azure-sites-common": "0.1.1", - "@backstage/plugin-badges": "0.2.52", - "@backstage/plugin-badges-backend": "0.3.5", - "@backstage/plugin-bazaar": "0.2.20", - "@backstage/plugin-bazaar-backend": "0.3.6", - "@backstage/plugin-bitbucket-cloud-common": "0.2.15", - "@backstage/plugin-bitrise": "0.1.55", - "@backstage/plugin-catalog": "1.16.0", - "@backstage/plugin-catalog-backend": "1.16.0", - "@backstage/plugin-catalog-backend-module-aws": "0.3.2", - "@backstage/plugin-catalog-backend-module-azure": "0.1.27", - "@backstage/plugin-catalog-backend-module-backstage-openapi": "0.1.1", - "@backstage/plugin-catalog-backend-module-bitbucket": "0.2.23", - "@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.1.23", - "@backstage/plugin-catalog-backend-module-bitbucket-server": "0.1.21", - "@backstage/plugin-catalog-backend-module-gcp": "0.1.8", - "@backstage/plugin-catalog-backend-module-gerrit": "0.1.24", - "@backstage/plugin-catalog-backend-module-github": "0.4.6", - "@backstage/plugin-catalog-backend-module-github-org": "0.1.2", - "@backstage/plugin-catalog-backend-module-gitlab": "0.3.5", - "@backstage/plugin-catalog-backend-module-incremental-ingestion": "0.4.12", - "@backstage/plugin-catalog-backend-module-ldap": "0.5.23", - "@backstage/plugin-catalog-backend-module-msgraph": "0.5.15", - "@backstage/plugin-catalog-backend-module-openapi": "0.1.25", - "@backstage/plugin-catalog-backend-module-puppetdb": "0.1.13", - "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "0.1.5", - "@backstage/plugin-catalog-backend-module-unprocessed": "0.3.5", - "@backstage/plugin-catalog-common": "1.0.19", - "@backstage/plugin-catalog-graph": "0.3.2", - "@backstage/plugin-catalog-import": "0.10.4", - "@backstage/plugin-catalog-node": "1.6.0", - "@backstage/plugin-catalog-react": "1.9.2", - "@backstage/plugin-catalog-unprocessed-entities": "0.1.6", - "@backstage/plugin-cicd-statistics": "0.1.30", - "@backstage/plugin-cicd-statistics-module-gitlab": "0.1.24", - "@backstage/plugin-circleci": "0.3.28", - "@backstage/plugin-cloudbuild": "0.3.28", - "@backstage/plugin-code-climate": "0.1.28", - "@backstage/plugin-code-coverage": "0.2.21", - "@backstage/plugin-code-coverage-backend": "0.2.22", - "@backstage/plugin-codescene": "0.1.20", - "@backstage/plugin-config-schema": "0.1.48", - "@backstage/plugin-cost-insights": "0.12.17", - "@backstage/plugin-cost-insights-common": "0.1.2", - "@backstage/plugin-devtools": "0.1.7", - "@backstage/plugin-devtools-backend": "0.2.5", - "@backstage/plugin-devtools-common": "0.1.7", - "@backstage/plugin-dynatrace": "8.0.2", - "@backstage/plugin-entity-feedback": "0.2.11", - "@backstage/plugin-entity-feedback-backend": "0.2.5", - "@backstage/plugin-entity-feedback-common": "0.1.3", - "@backstage/plugin-entity-validation": "0.1.13", - "@backstage/plugin-events-backend": "0.2.17", - "@backstage/plugin-events-backend-module-aws-sqs": "0.2.11", - "@backstage/plugin-events-backend-module-azure": "0.1.18", - "@backstage/plugin-events-backend-module-bitbucket-cloud": "0.1.18", - "@backstage/plugin-events-backend-module-gerrit": "0.1.18", - "@backstage/plugin-events-backend-module-github": "0.1.18", - "@backstage/plugin-events-backend-module-gitlab": "0.1.18", - "@backstage/plugin-events-backend-test-utils": "0.1.18", - "@backstage/plugin-events-node": "0.2.17", - "@internal/plugin-todo-list": "1.0.20", - "@internal/plugin-todo-list-backend": "1.0.20", - "@internal/plugin-todo-list-common": "1.0.16", - "@backstage/plugin-explore": "0.4.14", - "@backstage/plugin-explore-backend": "0.0.18", - "@backstage/plugin-explore-common": "0.0.2", - "@backstage/plugin-explore-react": "0.0.34", - "@backstage/plugin-firehydrant": "0.2.12", - "@backstage/plugin-fossa": "0.2.60", - "@backstage/plugin-gcalendar": "0.3.21", - "@backstage/plugin-gcp-projects": "0.3.44", - "@backstage/plugin-git-release-manager": "0.3.40", - "@backstage/plugin-github-actions": "0.6.9", - "@backstage/plugin-github-deployments": "0.1.59", - "@backstage/plugin-github-issues": "0.2.17", - "@backstage/plugin-github-pull-requests-board": "0.1.22", - "@backstage/plugin-gitops-profiles": "0.3.43", - "@backstage/plugin-gocd": "0.1.34", - "@backstage/plugin-graphiql": "0.3.1", - "@backstage/plugin-graphql-voyager": "0.1.10", - "@backstage/plugin-home": "0.6.0", - "@backstage/plugin-home-react": "0.1.6", - "@backstage/plugin-ilert": "0.2.17", - "@backstage/plugin-jenkins": "0.9.3", - "@backstage/plugin-jenkins-backend": "0.3.2", - "@backstage/plugin-jenkins-common": "0.1.22", - "@backstage/plugin-kafka": "0.3.28", - "@backstage/plugin-kafka-backend": "0.3.6", - "@backstage/plugin-kubernetes": "0.11.3", - "@backstage/plugin-kubernetes-backend": "0.14.0", - "@backstage/plugin-kubernetes-cluster": "0.0.4", - "@backstage/plugin-kubernetes-common": "0.7.2", - "@backstage/plugin-kubernetes-node": "0.1.2", - "@backstage/plugin-kubernetes-react": "0.2.0", - "@backstage/plugin-lighthouse": "0.4.13", - "@backstage/plugin-lighthouse-backend": "0.4.0", - "@backstage/plugin-lighthouse-common": "0.1.4", - "@backstage/plugin-linguist": "0.1.13", - "@backstage/plugin-linguist-backend": "0.5.5", - "@backstage/plugin-linguist-common": "0.1.2", - "@backstage/plugin-microsoft-calendar": "0.1.10", - "@backstage/plugin-newrelic": "0.3.43", - "@backstage/plugin-newrelic-dashboard": "0.3.3", - "@backstage/plugin-nomad": "0.1.9", - "@backstage/plugin-nomad-backend": "0.1.10", - "@backstage/plugin-octopus-deploy": "0.2.10", - "@backstage/plugin-opencost": "0.2.3", - "@backstage/plugin-org": "0.6.18", - "@backstage/plugin-org-react": "0.1.17", - "@backstage/plugin-pagerduty": "0.7.0", - "@backstage/plugin-periskop": "0.1.26", - "@backstage/plugin-periskop-backend": "0.2.6", - "@backstage/plugin-permission-backend": "0.5.31", - "@backstage/plugin-permission-backend-module-allow-all-policy": "0.1.5", - "@backstage/plugin-permission-common": "0.7.11", - "@backstage/plugin-permission-node": "0.7.19", - "@backstage/plugin-permission-react": "0.4.18", - "@backstage/plugin-playlist": "0.2.2", - "@backstage/plugin-playlist-backend": "0.3.12", - "@backstage/plugin-playlist-common": "0.1.13", - "@backstage/plugin-proxy-backend": "0.4.6", - "@backstage/plugin-puppetdb": "0.1.11", - "@backstage/plugin-rollbar": "0.4.28", - "@backstage/plugin-rollbar-backend": "0.1.53", - "@backstage/plugin-scaffolder": "1.17.0", - "@backstage/plugin-scaffolder-backend": "1.19.2", - "@backstage/plugin-scaffolder-backend-module-azure": "0.1.0", - "@backstage/plugin-scaffolder-backend-module-bitbucket": "0.1.0", - "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown": "0.2.9", - "@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.2.32", - "@backstage/plugin-scaffolder-backend-module-gerrit": "0.1.0", - "@backstage/plugin-scaffolder-backend-module-github": "0.1.0", - "@backstage/plugin-scaffolder-backend-module-gitlab": "0.2.11", - "@backstage/plugin-scaffolder-backend-module-rails": "0.4.25", - "@backstage/plugin-scaffolder-backend-module-sentry": "0.1.16", - "@backstage/plugin-scaffolder-backend-module-yeoman": "0.2.29", - "@backstage/plugin-scaffolder-common": "1.4.4", - "@backstage/plugin-scaffolder-node": "0.2.9", - "@backstage/plugin-scaffolder-react": "1.7.0", - "@backstage/plugin-search": "1.4.4", - "@backstage/plugin-search-backend": "1.4.8", - "@backstage/plugin-search-backend-module-catalog": "0.1.12", - "@backstage/plugin-search-backend-module-elasticsearch": "1.3.11", - "@backstage/plugin-search-backend-module-explore": "0.1.12", - "@backstage/plugin-search-backend-module-pg": "0.5.17", - "@backstage/plugin-search-backend-module-stack-overflow-collator": "0.1.1", - "@backstage/plugin-search-backend-module-techdocs": "0.1.12", - "@backstage/plugin-search-backend-node": "1.2.12", - "@backstage/plugin-search-common": "1.2.9", - "@backstage/plugin-search-react": "1.7.4", - "@backstage/plugin-sentry": "0.5.13", - "@backstage/plugin-shortcuts": "0.3.17", - "@backstage/plugin-sonarqube": "0.7.10", - "@backstage/plugin-sonarqube-backend": "0.2.10", - "@backstage/plugin-sonarqube-react": "0.1.11", - "@backstage/plugin-splunk-on-call": "0.4.17", - "@backstage/plugin-stack-overflow": "0.1.23", - "@backstage/plugin-stack-overflow-backend": "0.2.12", - "@backstage/plugin-stackstorm": "0.1.9", - "@backstage/plugin-tech-insights": "0.3.20", - "@backstage/plugin-tech-insights-backend": "0.5.22", - "@backstage/plugin-tech-insights-backend-module-jsonfc": "0.1.40", - "@backstage/plugin-tech-insights-common": "0.2.12", - "@backstage/plugin-tech-insights-node": "0.4.14", - "@backstage/plugin-tech-radar": "0.6.11", - "@backstage/plugin-techdocs": "1.9.2", - "@backstage/plugin-techdocs-addons-test-utils": "1.0.25", - "@backstage/plugin-techdocs-backend": "1.9.1", - "@backstage/plugin-techdocs-module-addons-contrib": "1.1.3", - "@backstage/plugin-techdocs-node": "1.11.0", - "@backstage/plugin-techdocs-react": "1.1.14", - "@backstage/plugin-todo": "0.2.32", - "@backstage/plugin-todo-backend": "0.3.6", - "@backstage/plugin-user-settings": "0.7.14", - "@backstage/plugin-user-settings-backend": "0.2.7", - "@backstage/plugin-vault": "0.1.23", - "@backstage/plugin-vault-backend": "0.4.1", - "@backstage/plugin-vault-node": "0.1.1", - "@backstage/plugin-visualizer": "0.0.1", - "@backstage/plugin-xcmetrics": "0.2.46" - }, - "changesets": [ - "afraid-mice-give", - "brave-queens-crash", - "brown-planes-sort", - "chatty-rivers-hope", - "chilled-seahorses-clean", - "chilled-zebras-wash", - "create-app-1703547661", - "create-app-1704804195", - "curvy-dingos-jump", - "fast-tables-hammer", - "friendly-horses-kneel", - "funny-rings-fry", - "gold-pianos-worry", - "happy-forks-jam", - "hip-dancers-pay", - "large-poets-buy", - "lazy-teachers-walk", - "many-peaches-dress", - "new-plants-sort", - "orange-planets-suffer", - "quiet-oranges-bake", - "renovate-126fde4", - "renovate-91133b2", - "renovate-9647667", - "rotten-tools-clean", - "sour-taxis-rush", - "stale-hairs-sparkle", - "tricky-pans-explain" - ] -} diff --git a/.changeset/quiet-oranges-bake.md b/.changeset/quiet-oranges-bake.md deleted file mode 100644 index a7360c9e4a..0000000000 --- a/.changeset/quiet-oranges-bake.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/frontend-plugin-api': patch -'@backstage/frontend-test-utils': patch -'@backstage/backend-plugin-api': patch -'@backstage/backend-dev-utils': patch -'@backstage/backend-defaults': patch -'@backstage/frontend-app-api': patch -'@backstage/backend-app-api': patch ---- - -Updated README to reflect release status diff --git a/.changeset/renovate-126fde4.md b/.changeset/renovate-126fde4.md deleted file mode 100644 index 409d509e8b..0000000000 --- a/.changeset/renovate-126fde4.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-github-issues': patch -'@backstage/plugin-scaffolder-backend-module-github': patch ---- - -Updated dependency `octokit` to `^3.0.0`. diff --git a/.changeset/renovate-91133b2.md b/.changeset/renovate-91133b2.md deleted file mode 100644 index 6f5b1b1bee..0000000000 --- a/.changeset/renovate-91133b2.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/plugin-home-react': patch -'@backstage/plugin-home': patch -'@backstage/plugin-scaffolder-react': patch -'@backstage/plugin-scaffolder': patch ---- - -Updated dependency `@rjsf/utils` to `5.15.1`. -Updated dependency `@rjsf/core` to `5.15.1`. -Updated dependency `@rjsf/material-ui` to `5.15.1`. -Updated dependency `@rjsf/validator-ajv8` to `5.15.1`. diff --git a/.changeset/renovate-9647667.md b/.changeset/renovate-9647667.md deleted file mode 100644 index 7d13035ecb..0000000000 --- a/.changeset/renovate-9647667.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-azure-devops-backend': patch -'@backstage/plugin-scaffolder-backend-module-azure': patch ---- - -Updated dependency `azure-devops-node-api` to `^12.0.0`. diff --git a/.changeset/rich-poets-stare.md b/.changeset/rich-poets-stare.md deleted file mode 100644 index 3c6f9a5035..0000000000 --- a/.changeset/rich-poets-stare.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-gitlab': patch -'@backstage/plugin-scaffolder-backend': minor ---- - -Add `gitlab:repo:push` scaffolder action to push files to arbitrary branch without creating a Merge Request diff --git a/.changeset/rotten-tools-clean.md b/.changeset/rotten-tools-clean.md deleted file mode 100644 index 192c3a057b..0000000000 --- a/.changeset/rotten-tools-clean.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch -'@backstage/plugin-catalog-backend-module-scaffolder-entity-model': patch -'@backstage/plugin-permission-backend-module-allow-all-policy': patch -'@backstage/plugin-auth-backend-module-oauth2-proxy-provider': patch -'@backstage/plugin-auth-backend-module-vmware-cloud-provider': patch -'@backstage/plugin-catalog-backend-module-backstage-openapi': patch -'@backstage/plugin-auth-backend-module-atlassian-provider': patch -'@backstage/plugin-auth-backend-module-microsoft-provider': patch -'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch -'@backstage/plugin-auth-backend-module-pinniped-provider': patch -'@backstage/plugin-events-backend-module-bitbucket-cloud': patch -'@backstage/plugin-auth-backend-module-gcp-iap-provider': patch -'@backstage/plugin-auth-backend-module-github-provider': patch -'@backstage/plugin-auth-backend-module-gitlab-provider': patch -'@backstage/plugin-auth-backend-module-google-provider': patch -'@backstage/plugin-auth-backend-module-oauth2-provider': patch -'@backstage/plugin-tech-insights-backend-module-jsonfc': patch -'@backstage/plugin-analytics-module-newrelic-browser': patch -'@backstage/plugin-auth-backend-module-okta-provider': patch -'@backstage/plugin-catalog-backend-module-bitbucket': patch -'@backstage/plugin-scaffolder-backend-module-yeoman': patch -'@backstage/plugin-techdocs-module-addons-contrib': patch -'@backstage/plugin-catalog-backend-module-gerrit': patch -'@backstage/plugin-catalog-backend-module-azure': patch -'@backstage/plugin-catalog-unprocessed-entities': patch -'@backstage/plugin-events-backend-module-gerrit': patch -'@backstage/plugin-events-backend-module-github': patch -'@backstage/plugin-events-backend-module-gitlab': patch -'@backstage/plugin-events-backend-module-azure': patch -'@backstage/plugin-catalog-backend-module-aws': patch -'@backstage/plugin-github-pull-requests-board': patch -'@backstage/plugin-techdocs-addons-test-utils': patch -'@backstage/plugin-entity-feedback-backend': patch -'@backstage/backend-openapi-utils': patch -'@backstage/plugin-stack-overflow-backend': patch -'@backstage/plugin-code-coverage-backend': patch -'@backstage/plugin-user-settings-backend': patch -'@backstage/frontend-plugin-api': patch -'@backstage/plugin-analytics-module-ga4': patch -'@backstage/plugin-azure-devops-backend': patch -'@backstage/plugin-analytics-module-ga': patch -'@backstage/plugin-azure-sites-backend': patch -'@backstage/plugin-git-release-manager': patch -'@backstage/plugin-github-deployments': patch -'@backstage/plugin-kubernetes-cluster': patch -'@backstage/plugin-microsoft-calendar': patch -'@backstage/plugin-newrelic-dashboard': patch -'@backstage/plugin-tech-insights-node': patch -'@backstage/plugin-entity-validation': patch -'@backstage/plugin-kubernetes-common': patch -'@backstage/plugin-airbrake-backend': patch -'@backstage/plugin-devtools-backend': patch -'@backstage/plugin-linguist-backend': patch -'@backstage/plugin-periskop-backend': patch -'@backstage/plugin-permission-react': patch -'@backstage/plugin-playlist-backend': patch -'@backstage/plugin-scaffolder-react': patch -'@backstage/plugin-techdocs-backend': patch -'@backstage/plugin-apollo-explorer': patch -'@backstage/plugin-entity-feedback': patch -'@backstage/plugin-explore-backend': patch -'@backstage/plugin-gitops-profiles': patch -'@backstage/plugin-graphql-voyager': patch -'@backstage/plugin-jenkins-backend': patch -'@backstage/plugin-apache-airflow': patch -'@backstage/plugin-badges-backend': patch -'@backstage/plugin-bazaar-backend': patch -'@backstage/plugin-github-actions': patch -'@backstage/plugin-octopus-deploy': patch -'@backstage/plugin-search-backend': patch -'@backstage/plugin-splunk-on-call': patch -'@backstage/plugin-stack-overflow': patch -'@backstage/plugin-techdocs-react': patch -'@backstage/plugin-catalog-graph': patch -'@backstage/plugin-catalog-react': patch -'@backstage/plugin-code-coverage': patch -'@backstage/plugin-config-schema': patch -'@backstage/plugin-cost-insights': patch -'@backstage/plugin-explore-react': patch -'@backstage/plugin-github-issues': patch -'@backstage/plugin-kafka-backend': patch -'@backstage/plugin-nomad-backend': patch -'@backstage/plugin-tech-insights': patch -'@backstage/plugin-user-settings': patch -'@backstage/plugin-auth-backend': patch -'@backstage/plugin-azure-devops': patch -'@backstage/plugin-catalog-node': patch -'@backstage/plugin-code-climate': patch -'@backstage/plugin-gcp-projects': patch -'@backstage/plugin-todo-backend': patch -'@backstage/plugin-adr-backend': patch -'@backstage/plugin-app-backend': patch -'@backstage/plugin-azure-sites': patch -'@backstage/plugin-firehydrant': patch -'@backstage/plugin-cloudbuild': patch -'@backstage/plugin-home-react': patch -'@backstage/plugin-kubernetes': patch -'@backstage/plugin-lighthouse': patch -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-stackstorm': patch -'@backstage/plugin-tech-radar': patch -'@backstage/plugin-codescene': patch -'@backstage/plugin-dynatrace': patch -'@backstage/plugin-gcalendar': patch -'@backstage/plugin-org-react': patch -'@backstage/plugin-pagerduty': patch -'@backstage/plugin-shortcuts': patch -'@backstage/plugin-sonarqube': patch -'@backstage/plugin-xcmetrics': patch -'@backstage/plugin-airbrake': patch -'@backstage/plugin-api-docs': patch -'@backstage/plugin-circleci': patch -'@backstage/plugin-devtools': patch -'@backstage/plugin-graphiql': patch -'@backstage/plugin-linguist': patch -'@backstage/plugin-newrelic': patch -'@backstage/plugin-opencost': patch -'@backstage/plugin-periskop': patch -'@backstage/plugin-playlist': patch -'@backstage/plugin-puppetdb': patch -'@backstage/plugin-techdocs': patch -'@backstage/plugin-bitrise': patch -'@backstage/plugin-catalog': patch -'@backstage/plugin-explore': patch -'@backstage/plugin-jenkins': patch -'@backstage/plugin-rollbar': patch -'@backstage/plugin-allure': patch -'@backstage/plugin-badges': patch -'@backstage/plugin-bazaar': patch -'@backstage/plugin-search': patch -'@backstage/plugin-sentry': patch -'@backstage/plugin-fossa': patch -'@backstage/plugin-ilert': patch -'@backstage/plugin-kafka': patch -'@backstage/plugin-nomad': patch -'@backstage/plugin-vault': patch -'@backstage/plugin-gocd': patch -'@backstage/plugin-home': patch -'@backstage/plugin-todo': patch -'@backstage/plugin-adr': patch -'@backstage/plugin-org': patch ---- - -Remove some unused dependencies diff --git a/.changeset/shaggy-coins-happen.md b/.changeset/shaggy-coins-happen.md deleted file mode 100644 index c20a8e0cb2..0000000000 --- a/.changeset/shaggy-coins-happen.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-events-backend-module-aws-sqs': patch ---- - -Fix errors when deleting SQS messages: - -- If zero messages were received, skip deletion to avoid `EmptyBatchRequest` error from the SQS client. -- If zero failures were returned from the SQS client during deletion, skip error logging. diff --git a/.changeset/silent-horses-raise.md b/.changeset/silent-horses-raise.md deleted file mode 100644 index a03d662b03..0000000000 --- a/.changeset/silent-horses-raise.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/frontend-plugin-api': patch -'@backstage/frontend-test-utils': patch -'@backstage/frontend-app-api': patch ---- - -Added `elements`, `wrappers`, and `router` inputs to `app/root`, that let you add things to the root of the React tree above the layout. You can use the `createAppRootElementExtension`, `createAppRootWrapperExtension`, and `createRouterExtension` extension creator, respectively, to conveniently create such extensions. These are all optional, and if you do not supply a router a default one will be used (`BrowserRouter` in regular runs, `MemoryRouter` in tests/CI). diff --git a/.changeset/silver-countries-notice.md b/.changeset/silver-countries-notice.md deleted file mode 100644 index 457042487b..0000000000 --- a/.changeset/silver-countries-notice.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-app-api': minor ---- - -Attaching extensions to an input that does not exist is now a warning rather than an error. diff --git a/.changeset/sixty-plums-switch.md b/.changeset/sixty-plums-switch.md deleted file mode 100644 index 8da07609c6..0000000000 --- a/.changeset/sixty-plums-switch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': patch ---- - -Show first scaffolder output text by default diff --git a/.changeset/smooth-pumas-fold.md b/.changeset/smooth-pumas-fold.md deleted file mode 100644 index 4a3540460b..0000000000 --- a/.changeset/smooth-pumas-fold.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Minor internal refactor diff --git a/.changeset/sour-taxis-rush.md b/.changeset/sour-taxis-rush.md deleted file mode 100644 index 1241cf3e8c..0000000000 --- a/.changeset/sour-taxis-rush.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Removed unnecessary `history` and `immer` dependencies. diff --git a/.changeset/stale-cars-attack.md b/.changeset/stale-cars-attack.md deleted file mode 100644 index 431cc9232c..0000000000 --- a/.changeset/stale-cars-attack.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-events-backend-module-aws-sqs': patch -'@backstage/plugin-events-backend': patch ---- - -Add documentation on how to install the plugins with the new backend system. diff --git a/.changeset/stale-hairs-sparkle.md b/.changeset/stale-hairs-sparkle.md deleted file mode 100644 index 3db8e974ec..0000000000 --- a/.changeset/stale-hairs-sparkle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-aws': patch ---- - -Added status and e-mail as labels to the AWS Account Resource diff --git a/.changeset/tender-roses-teach.md b/.changeset/tender-roses-teach.md deleted file mode 100644 index 4d569917fb..0000000000 --- a/.changeset/tender-roses-teach.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-permission-backend': patch -'@backstage/plugin-permission-common': patch -'@backstage/plugin-permission-react': patch -'@backstage/plugin-permission-node': patch ---- - -Updated README diff --git a/.changeset/thirty-cats-help.md b/.changeset/thirty-cats-help.md deleted file mode 100644 index 9c5d24180d..0000000000 --- a/.changeset/thirty-cats-help.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Parse the URL using a different method rather than `git-url-parse` to support wildcards for URLs which are not VCS providers diff --git a/.changeset/tricky-pans-explain.md b/.changeset/tricky-pans-explain.md deleted file mode 100644 index 64b2bda1fe..0000000000 --- a/.changeset/tricky-pans-explain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-linguist': patch ---- - -Added alpha support for the New Frontend System (Declarative Integration) diff --git a/.changeset/unlucky-bottles-run.md b/.changeset/unlucky-bottles-run.md deleted file mode 100644 index 63c6ff1249..0000000000 --- a/.changeset/unlucky-bottles-run.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-app-visualizer': minor ---- - -Initial release of the app visualizer plugin. diff --git a/.changeset/weak-pans-accept.md b/.changeset/weak-pans-accept.md deleted file mode 100644 index 5e75f52058..0000000000 --- a/.changeset/weak-pans-accept.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-app-api': patch ---- - -add oauth dialog and alert display to the root elements diff --git a/docs/releases/v1.22.0-changelog.md b/docs/releases/v1.22.0-changelog.md new file mode 100644 index 0000000000..399d7e7016 --- /dev/null +++ b/docs/releases/v1.22.0-changelog.md @@ -0,0 +1,3239 @@ +# Release v1.22.0 + +## @backstage/backend-dynamic-feature-service@0.1.0 + +### Minor Changes + +- eb81f42: New `backend-dynamic-feature-service` package, for the discovery of dynamic frontend and backend plugins (and modules) and the loading of the backend ones inside the backend application. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/cli-node@0.2.2 + - @backstage/plugin-events-backend@0.2.18 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-catalog-backend@1.16.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.2.18 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/frontend-app-api@0.5.0 + +### Minor Changes + +- d4149bf: **BREAKING**: Renamed the `app/router` extension to `app/root`. +- 074dfe3: Attaching extensions to an input that does not exist is now a warning rather than an error. + +### Patch Changes + +- 7d63b32: Accepts sub route refs on the new `createPlugin` routes map. +- 516fd3e: Updated README to reflect release status +- c97fa1c: Added `elements`, `wrappers`, and `router` inputs to `app/root`, that let you add things to the root of the React tree above the layout. You can use the `createAppRootElementExtension`, `createAppRootWrapperExtension`, and `createRouterExtension` extension creator, respectively, to conveniently create such extensions. These are all optional, and if you do not supply a router a default one will be used (`BrowserRouter` in regular runs, `MemoryRouter` in tests/CI). +- 5fe6600: add oauth dialog and alert display to the root elements +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.3 + - @backstage/errors@1.2.3 + - @backstage/theme@0.5.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-plugin-api@0.5.0 + +### Minor Changes + +- d4149bf: **BREAKING**: Renamed the `app/router` extension to `app/root`. + +### Patch Changes + +- b2d370e: Exposed `createComponentRef`, and ensured that produced refs and feature bits have a `toString` for easier debugging +- 7d63b32: Accepts sub route refs on the new `createPlugin` routes map. +- 516fd3e: Updated README to reflect release status +- 4016f21: Remove some unused dependencies +- c97fa1c: Added `elements`, `wrappers`, and `router` inputs to `app/root`, that let you add things to the root of the React tree above the layout. You can use the `createAppRootElementExtension`, `createAppRootWrapperExtension`, and `createRouterExtension` extension creator, respectively, to conveniently create such extensions. These are all optional, and if you do not supply a router a default one will be used (`BrowserRouter` in regular runs, `MemoryRouter` in tests/CI). +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/plugin-app-visualizer@0.1.0 + +### Minor Changes + +- e57cc9f: Initial release of the app visualizer plugin. + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + +## @backstage/plugin-scaffolder-backend@1.20.0 + +### Minor Changes + +- a694f71: The Scaffolder builtin actions now contains an action for running pipelines from Bitbucket Cloud Rest API +- 7c522c5: Add `gitlab:repo:push` scaffolder action to push files to arbitrary branch without creating a Merge Request + +### Patch Changes + +- e9ab1c4: Fixed an issue where not passing a `value` to any of the action's permission conditions caused an error. +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-backend-module-github@0.1.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.2.12 + - @backstage/plugin-scaffolder-common@1.4.5 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.1.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.6 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.1 + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-user-settings@0.8.0 + +### Minor Changes + +- 56b2fb0: Updated the user settings selector to use a select component that displays native language names instead of language codes if possible. + +### Patch Changes + +- eea0849: add user-settings declarative integration core nav item +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/core-app-api@1.11.3 + - @backstage/errors@1.2.3 + - @backstage/theme@0.5.0 + - @backstage/types@1.1.1 + +## @backstage/app-defaults@1.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/core-app-api@1.11.3 + - @backstage/theme@0.5.0 + +## @backstage/backend-app-api@0.5.10 + +### Patch Changes + +- 516fd3e: Updated README to reflect release status +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/config-loader@1.6.1 + - @backstage/cli-node@0.2.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/backend-common@0.20.1 + +### Patch Changes + +- 3b24eae: Adding support for removing file from git index + +- 454d17c: Do not call fetch directly but rather use `fetchResponse` facility + +- b6b15b2: Use sha256 instead of md5 for hash key calculation in caches + + This can have a side effect of invalidating caches (when cache key was >250 characters) + This improves compliance with FIPS nodejs + +- Updated dependencies + - @backstage/config-loader@1.6.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-dev-utils@0.1.3 + - @backstage/backend-app-api@0.5.10 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/integration-aws-node@0.1.8 + - @backstage/types@1.1.1 + +## @backstage/backend-defaults@0.2.9 + +### Patch Changes + +- 516fd3e: Updated README to reflect release status +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-app-api@0.5.10 + +## @backstage/backend-dev-utils@0.1.3 + +### Patch Changes + +- 516fd3e: Updated README to reflect release status + +## @backstage/backend-openapi-utils@0.1.2 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/errors@1.2.3 + +## @backstage/backend-plugin-api@0.6.9 + +### Patch Changes + +- 516fd3e: Updated README to reflect release status +- Updated dependencies + - @backstage/plugin-permission-common@0.7.12 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + +## @backstage/backend-tasks@0.5.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/backend-test-utils@0.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-app-api@0.5.10 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/catalog-client@1.5.2 + +### Patch Changes + +- 883782e: Fix a bug in `getLocationByRef` that led to invalid backend calls +- Updated dependencies + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + +## @backstage/cli@0.25.1 + +### Patch Changes + +- b6b15b2: Use sha256 instead of md5 in build script cache key calculation + + Makes it possible to build on FIPS nodejs. + +- Updated dependencies + - @backstage/config-loader@1.6.1 + - @backstage/cli-node@0.2.2 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/eslint-plugin@0.1.4 + - @backstage/integration@1.8.0 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/cli-node@0.2.2 + +### Patch Changes + +- 7acbb5a: Removed `mock-fs` dev dependency. +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/config-loader@1.6.1 + +### Patch Changes + +- 7acbb5a: Removed `mock-fs` dev dependency. +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/core-app-api@1.11.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-compat-api@0.1.1 + +### Patch Changes + +- 4c1f50c: Make `convertLegacyApp` wrap discovered routes with `compatWrapper`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-plugin-api@1.8.2 + - @backstage/core-app-api@1.11.3 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-components@0.13.10 + +### Patch Changes + +- d625f66: Fixed bug in Link where it was possible to select and copy a hidden element into clipboard +- 6878b1d: Removed unnecessary `history` and `immer` dependencies. +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/theme@0.5.0 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-plugin-api@1.8.2 + +### Patch Changes + +- 6878b1d: Removed unnecessary `i18next` dependency. +- Updated dependencies + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/create-app@0.5.9 + +### Patch Changes + +- c9f71fb: Bumped create-app version. +- ac277f3: Bumped create-app version. +- 7acbb5a: Removed `mock-fs` dev dependency. +- Updated dependencies + - @backstage/cli-common@0.1.13 + +## @backstage/dev-utils@1.0.26 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/app-defaults@1.4.7 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/core-app-api@1.11.3 + - @backstage/theme@0.5.0 + +## @backstage/frontend-test-utils@0.1.1 + +### Patch Changes + +- f7566f9: Updates to reflect the `app/router` extension having been renamed to `app/root`. +- 516fd3e: Updated README to reflect release status +- c97fa1c: Added `elements`, `wrappers`, and `router` inputs to `app/root`, that let you add things to the root of the React tree above the layout. You can use the `createAppRootElementExtension`, `createAppRootWrapperExtension`, and `createRouterExtension` extension creator, respectively, to conveniently create such extensions. These are all optional, and if you do not supply a router a default one will be used (`BrowserRouter` in regular runs, `MemoryRouter` in tests/CI). +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/frontend-app-api@0.5.0 + - @backstage/test-utils@1.4.7 + - @backstage/types@1.1.1 + +## @backstage/integration-react@1.1.23 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0 + +## @backstage/repo-tools@0.5.2 + +### Patch Changes + +- 883782e: Updated the OpenAPI template to export the `TypedResponse` interface so that client code can leverage it +- 7acbb5a: Removed `mock-fs` dev dependency. +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/cli-node@0.2.2 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.3 + +## @techdocs/cli@1.8.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-techdocs-node@1.11.1 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## @backstage/test-utils@1.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.3 + - @backstage/theme@0.5.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-adr@0.6.12 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-search-react@1.7.5 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-adr-common@0.2.19 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-adr-backend@0.4.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/plugin-adr-common@0.2.19 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-adr-common@0.2.19 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.3 + - @backstage/integration@1.8.0 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-airbrake@0.3.29 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/dev-utils@1.0.26 + - @backstage/catalog-model@1.4.3 + - @backstage/test-utils@1.4.7 + +## @backstage/plugin-airbrake-backend@0.3.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + +## @backstage/plugin-allure@0.1.45 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-analytics-module-ga@0.1.37 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/config@1.1.1 + +## @backstage/plugin-analytics-module-ga4@0.1.8 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/config@1.1.1 + +## @backstage/plugin-analytics-module-newrelic-browser@0.0.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/config@1.1.1 + +## @backstage/plugin-apache-airflow@0.2.19 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + +## @backstage/plugin-api-docs@0.10.3 + +### Patch Changes + +- 8a69cc9: Fix custom http resolvers for AsyncAPI widget. +- 062b8f2: Add permission check to Register Existing API button +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-catalog@1.16.1 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-catalog-common@1.0.20 + +## @backstage/plugin-apollo-explorer@0.1.19 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + +## @backstage/plugin-app-backend@0.3.57 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/config-loader@1.6.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.9 + +## @backstage/plugin-app-node@0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + +## @backstage/plugin-auth-backend@0.20.3 + +### Patch Changes + +- 004499c: Fixed an issue where some Okta's resolvers were missing +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.1 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.1.1 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.3 + - @backstage/plugin-auth-backend-module-github-provider@0.1.6 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.6 + - @backstage/plugin-auth-backend-module-google-provider@0.1.6 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.1.6 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.2 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.1.1 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.1.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.1.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + +## @backstage/plugin-auth-backend-module-google-provider@0.1.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.1.4 + +### Patch Changes + +- 928efbc: Deprecated the `authModuleMicrosoftProvider` export. A default export is now available and should be used like this in your backend: `backend.add(import('@backstage/plugin-auth-backend-module-microsoft-provider'));` +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.1.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.1 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/errors@1.2.3 + +## @backstage/plugin-auth-backend-module-okta-provider@0.0.2 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.1.3 + +### Patch Changes + +- 928efbc: Deprecated the `authModulePinnipedProvider` export. A default export is now available and should be used like this in your backend: `backend.add(import('@backstage/plugin-auth-backend-module-pinniped-provider'));` +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/config@1.1.1 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.1.1 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-auth-node@0.4.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-azure-devops@0.3.11 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/plugin-azure-devops-common@0.3.2 + +## @backstage/plugin-azure-devops-backend@0.5.1 + +### Patch Changes + +- d076ee4: Updated dependency `azure-devops-node-api` to `^12.0.0`. +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0 + - @backstage/plugin-azure-devops-common@0.3.2 + - @backstage/plugin-catalog-common@1.0.20 + +## @backstage/plugin-azure-sites@0.1.18 + +### Patch Changes + +- a31f688: Show Azure site tags in `EntityAzureSitesOverviewWidget`. +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-azure-sites-common@0.1.1 + +## @backstage/plugin-azure-sites-backend@0.1.19 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/config@1.1.1 + - @backstage/plugin-azure-sites-common@0.1.1 + +## @backstage/plugin-badges@0.2.53 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + +## @backstage/plugin-badges-backend@0.3.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-bazaar@0.2.21 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + +## @backstage/plugin-bazaar-backend@0.3.7 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/config@1.1.1 + +## @backstage/plugin-bitrise@0.1.56 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-catalog@1.16.1 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/plugin-scaffolder-common@1.4.5 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-search-react@1.7.5 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.20 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-catalog-backend@1.16.1 + +### Patch Changes + +- c3249d6: Parse the URL using a different method rather than `git-url-parse` to support wildcards for URLs which are not VCS providers +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-search-backend-module-catalog@0.1.13 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-openapi-utils@0.1.2 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.20 + - @backstage/plugin-events-node@0.2.18 + +## @backstage/plugin-catalog-backend-module-aws@0.3.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- 22e88d0: Added status and e-mail as labels to the AWS Account Resource +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-kubernetes-common@0.7.3 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/integration-aws-node@0.1.8 + - @backstage/plugin-catalog-common@1.0.20 + +## @backstage/plugin-catalog-backend-module-azure@0.1.28 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0 + - @backstage/plugin-catalog-common@1.0.20 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.2 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-openapi-utils@0.1.2 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-catalog-backend-module-bitbucket@0.2.24 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.15 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.1.24 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.15 + - @backstage/plugin-catalog-common@1.0.20 + - @backstage/plugin-events-node@0.2.18 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.22 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + +## @backstage/plugin-catalog-backend-module-gcp@0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-kubernetes-common@0.7.3 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.25 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + +## @backstage/plugin-catalog-backend-module-github@0.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-catalog-backend@1.16.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0 + - @backstage/plugin-catalog-common@1.0.20 + - @backstage/plugin-events-node@0.2.18 + +## @backstage/plugin-catalog-backend-module-github-org@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-catalog-backend-module-github@0.4.7 + - @backstage/config@1.1.1 + +## @backstage/plugin-catalog-backend-module-gitlab@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.4.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-catalog-backend@1.16.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-events-node@0.2.18 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.24 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.20 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.16 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/plugin-catalog-common@1.0.20 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.26 + +### Patch Changes + +- 4ebf99b: Add support for the new backend system. + + A new backend module for the catalog backend + was added and exported as `default`. + + You can use it with the new backend system like + + ```ts title="packages/backend/src/index.ts" + backend.add(import('@backstage/plugin-catalog-backend-module-openapi')); + ``` + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-catalog-backend@1.16.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.20 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.4.5 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-catalog-common@1.0.20 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-catalog-common@1.0.20 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.12 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-catalog-graph@0.3.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.10.5 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/plugin-catalog-common@1.0.20 + +## @backstage/plugin-catalog-node@1.6.1 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.20 + +## @backstage/plugin-catalog-react@1.9.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-common@1.0.20 + +## @backstage/plugin-catalog-unprocessed-entities@0.1.7 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + +## @backstage/plugin-cicd-statistics@0.1.31 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.25 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-cicd-statistics@0.1.31 + +## @backstage/plugin-circleci@0.3.29 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-cloudbuild@0.3.29 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-code-climate@0.1.29 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-code-coverage@0.2.22 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + +## @backstage/plugin-code-coverage-backend@0.2.23 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + +## @backstage/plugin-codescene@0.1.21 + +### Patch Changes + +- d5eda61: Updated Readme document in codescene plugin +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-config-schema@0.1.49 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-cost-insights@0.12.18 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/theme@0.5.0 + - @backstage/plugin-cost-insights-common@0.1.2 + +## @backstage/plugin-devtools@0.1.8 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/errors@1.2.3 + - @backstage/plugin-devtools-common@0.1.8 + +## @backstage/plugin-devtools-backend@0.2.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/config-loader@1.6.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.8 + +## @backstage/plugin-devtools-common@0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.12 + - @backstage/types@1.1.1 + +## @backstage/plugin-dynatrace@8.0.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-entity-feedback@0.2.12 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-feedback-backend@0.2.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-validation@0.1.14 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.20 + +## @backstage/plugin-events-backend@0.2.18 + +### Patch Changes + +- 92ea615: Update `README.md` +- d5ddc4e: Add documentation on how to install the plugins with the new backend system. +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + - @backstage/plugin-events-node@0.2.18 + +## @backstage/plugin-events-backend-module-aws-sqs@0.2.12 + +### Patch Changes + +- 7b8e551: Fix errors when deleting SQS messages: + + - If zero messages were received, skip deletion to avoid `EmptyBatchRequest` error from the SQS client. + - If zero failures were returned from the SQS client during deletion, skip error logging. + +- d5ddc4e: Add documentation on how to install the plugins with the new backend system. + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-tasks@0.5.14 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.2.18 + +## @backstage/plugin-events-backend-module-azure@0.1.19 + +### Patch Changes + +- af76a95: Add default exports for the new backend system and documentation. +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-events-node@0.2.18 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.1.19 + +### Patch Changes + +- af76a95: Add default exports for the new backend system and documentation. +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-events-node@0.2.18 + +## @backstage/plugin-events-backend-module-gerrit@0.1.19 + +### Patch Changes + +- af76a95: Add default exports for the new backend system and documentation. +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-events-node@0.2.18 + +## @backstage/plugin-events-backend-module-github@0.1.19 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + - @backstage/plugin-events-node@0.2.18 + +## @backstage/plugin-events-backend-module-gitlab@0.1.19 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + - @backstage/plugin-events-node@0.2.18 + +## @backstage/plugin-events-backend-test-utils@0.1.19 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.18 + +## @backstage/plugin-events-node@0.2.18 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + +## @backstage/plugin-explore@0.4.15 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-explore-react@0.0.35 + - @backstage/plugin-search-react@1.7.5 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-explore-backend@0.0.19 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-search-backend-module-explore@0.1.13 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + +## @backstage/plugin-explore-react@0.0.35 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-explore-common@0.0.2 + +## @backstage/plugin-firehydrant@0.2.13 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-fossa@0.2.61 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + +## @backstage/plugin-gcalendar@0.3.22 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/errors@1.2.3 + +## @backstage/plugin-gcp-projects@0.3.45 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + +## @backstage/plugin-git-release-manager@0.3.41 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/integration@1.8.0 + +## @backstage/plugin-github-actions@0.6.10 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/integration@1.8.0 + +## @backstage/plugin-github-deployments@0.1.60 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + +## @backstage/plugin-github-issues@0.2.18 + +### Patch Changes + +- bf92ae3: Updated dependency `octokit` to `^3.0.0`. +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + +## @backstage/plugin-github-pull-requests-board@0.1.23 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/integration@1.8.0 + +## @backstage/plugin-gitops-profiles@0.3.44 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + +## @backstage/plugin-gocd@0.1.35 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + +## @backstage/plugin-graphiql@0.3.2 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + +## @backstage/plugin-graphql-voyager@0.1.11 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + +## @backstage/plugin-home@0.6.1 + +### Patch Changes + +- 98ac5ab: Updated dependency `@rjsf/utils` to `5.15.1`. + Updated dependency `@rjsf/core` to `5.15.1`. + Updated dependency `@rjsf/material-ui` to `5.15.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.15.1`. +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-home-react@0.1.7 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/core-app-api@1.11.3 + - @backstage/theme@0.5.0 + +## @backstage/plugin-home-react@0.1.7 + +### Patch Changes + +- 98ac5ab: Updated dependency `@rjsf/utils` to `5.15.1`. + Updated dependency `@rjsf/core` to `5.15.1`. + Updated dependency `@rjsf/material-ui` to `5.15.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.15.1`. +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + +## @backstage/plugin-ilert@0.2.18 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + +## @backstage/plugin-jenkins@0.9.4 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/plugin-jenkins-common@0.1.23 + +## @backstage/plugin-jenkins-backend@0.3.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-jenkins-common@0.1.23 + +## @backstage/plugin-jenkins-common@0.1.23 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-catalog-common@1.0.20 + +## @backstage/plugin-kafka@0.3.29 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-kafka-backend@0.3.7 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-kubernetes@0.11.4 + +### Patch Changes + +- d5d2c67: Add `authuser` search parameter to GKE cluster link formatter in k8s plugin + + Thanks to this, people with multiple simultaneously logged-in accounts in their GCP console will automatically view objects with the same email as the one signed in to the Google auth provider in Backstage. + +- 4016f21: Remove some unused dependencies + +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-kubernetes-react@0.2.1 + - @backstage/plugin-kubernetes-common@0.7.3 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-kubernetes-backend@0.14.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-kubernetes-common@0.7.3 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration-aws-node@0.1.8 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-node@0.1.3 + +## @backstage/plugin-kubernetes-cluster@0.0.5 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-kubernetes-react@0.2.1 + - @backstage/plugin-kubernetes-common@0.7.3 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-kubernetes-common@0.7.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/plugin-permission-common@0.7.12 + - @backstage/catalog-model@1.4.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-kubernetes-node@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-kubernetes-common@0.7.3 + - @backstage/catalog-model@1.4.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-kubernetes-react@0.2.1 + +### Patch Changes + +- d5d2c67: Add `authuser` search parameter to GKE cluster link formatter in k8s plugin + + Thanks to this, people with multiple simultaneously logged-in accounts in their GCP console will automatically view objects with the same email as the one signed in to the Google auth provider in Backstage. + +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-kubernetes-common@0.7.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-lighthouse@0.4.14 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-lighthouse-common@0.1.4 + +## @backstage/plugin-lighthouse-backend@0.4.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-lighthouse-common@0.1.4 + +## @backstage/plugin-linguist@0.1.14 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- 4f42918: Added alpha support for the New Frontend System (Declarative Integration) +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-linguist-backend@0.5.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-microsoft-calendar@0.1.11 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/errors@1.2.3 + +## @backstage/plugin-newrelic@0.3.44 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + +## @backstage/plugin-newrelic-dashboard@0.3.4 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + +## @backstage/plugin-nomad@0.1.10 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-nomad-backend@0.1.11 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-octopus-deploy@0.2.11 + +### Patch Changes + +- 7d96ba8: added install path and fixed import on plugin-octopus-deploy +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-opencost@0.2.4 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + +## @backstage/plugin-org@0.6.19 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-catalog-common@1.0.20 + +## @backstage/plugin-org-react@0.1.18 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-pagerduty@0.7.1 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-home-react@0.1.7 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + +## @backstage/plugin-periskop@0.1.27 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + +## @backstage/plugin-periskop-backend@0.2.7 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + +## @backstage/plugin-permission-backend@0.5.32 + +### Patch Changes + +- b1acd9b: Updated README +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.1.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-auth-node@0.4.3 + +## @backstage/plugin-permission-common@0.7.12 + +### Patch Changes + +- b1acd9b: Updated README +- Updated dependencies + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-permission-node@0.7.20 + +### Patch Changes + +- b1acd9b: Updated README +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-permission-react@0.4.19 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- b1acd9b: Updated README +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/config@1.1.1 + +## @backstage/plugin-playlist@0.2.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-search-react@1.7.5 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.20 + - @backstage/plugin-playlist-common@0.1.14 + +## @backstage/plugin-playlist-backend@0.3.13 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-playlist-common@0.1.14 + +## @backstage/plugin-playlist-common@0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-proxy-backend@0.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + +## @backstage/plugin-puppetdb@0.1.12 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + +## @backstage/plugin-rollbar@0.4.29 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-rollbar-backend@0.1.54 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/config@1.1.1 + +## @backstage/plugin-scaffolder@1.17.1 + +### Patch Changes + +- 98ac5ab: Updated dependency `@rjsf/utils` to `5.15.1`. + Updated dependency `@rjsf/core` to `5.15.1`. + Updated dependency `@rjsf/material-ui` to `5.15.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.15.1`. +- 4016f21: Remove some unused dependencies +- df4bc9d: Minor internal refactor +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.7.1 + - @backstage/core-components@0.13.10 + - @backstage/plugin-scaffolder-common@1.4.5 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.20 + +## @backstage/plugin-scaffolder-backend-module-azure@0.1.1 + +### Patch Changes + +- d076ee4: Updated dependency `azure-devops-node-api` to `^12.0.0`. +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.1.1 + +### Patch Changes + +- a694f71: The Scaffolder builtin actions now contains an action for running pipelines from Bitbucket Cloud Rest API +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.10 + +### Patch Changes + +- 7acbb5a: Removed `mock-fs` dev dependency. +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.33 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + +## @backstage/plugin-scaffolder-backend-module-github@0.1.1 + +### Patch Changes + +- 5470300: Ensure `teamReviewers` list is unique before calling API +- bf92ae3: Updated dependency `octokit` to `^3.0.0`. +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.2.12 + +### Patch Changes + +- 604c9dd: Add Scaffolder custom action that creates GitLab issues called `gitlab:issues:create` +- 7c522c5: Add `gitlab:repo:push` scaffolder action to push files to arbitrary branch without creating a Merge Request +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.26 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.17 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.30 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-common@1.4.5 + +### Patch Changes + +- 178b8d8: Updated Template.v1beta3.schema.json, added a missing "presentation" field +- Updated dependencies + - @backstage/plugin-permission-common@0.7.12 + - @backstage/catalog-model@1.4.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-node@0.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-common@1.4.5 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-react@1.7.1 + +### Patch Changes + +- c28f281: Scaffolder form now shows a list of errors at the top of the form. +- 0b9ce2b: Fix for a step with no properties +- 98ac5ab: Updated dependency `@rjsf/utils` to `5.15.1`. + Updated dependency `@rjsf/core` to `5.15.1`. + Updated dependency `@rjsf/material-ui` to `5.15.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.15.1`. +- 4016f21: Remove some unused dependencies +- d16f85f: Show first scaffolder output text by default +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/plugin-scaffolder-common@1.4.5 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/theme@0.5.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/plugin-search@1.4.5 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-search-react@1.7.5 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-search-backend@1.4.9 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-openapi-utils@0.1.2 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-search-backend-module-catalog@0.1.13 + +### Patch Changes + +- 2e6c56b: Update wording to show that the backend system no longer is in alpha +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.20 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-search-backend-module-elasticsearch@1.3.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/config@1.1.1 + - @backstage/integration-aws-node@0.1.8 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-search-backend-module-explore@0.1.13 + +### Patch Changes + +- 2e6c56b: Update wording to show that the backend system no longer is in alpha +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/config@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-search-backend-module-pg@0.5.18 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/config@1.1.1 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.2 + +### Patch Changes + +- 2e6c56b: Update wording to show that the backend system no longer is in alpha +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/config@1.1.1 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-search-backend-module-techdocs@0.1.13 + +### Patch Changes + +- 2e6c56b: Update wording to show that the backend system no longer is in alpha +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/plugin-techdocs-node@1.11.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/plugin-catalog-common@1.0.20 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-search-backend-node@1.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/backend-tasks@0.5.14 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-search-common@1.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.12 + - @backstage/types@1.1.1 + +## @backstage/plugin-search-react@1.7.5 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/theme@0.5.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-sentry@0.5.14 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-shortcuts@0.3.18 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/theme@0.5.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-sonarqube@0.7.11 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-sonarqube-react@0.1.12 + +## @backstage/plugin-sonarqube-backend@0.2.11 + +### Patch Changes + +- 53445cd: Updated README +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-sonarqube-react@0.1.12 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-splunk-on-call@0.4.18 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + +## @backstage/plugin-stack-overflow@0.1.24 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-home-react@0.1.7 + - @backstage/plugin-search-react@1.7.5 + - @backstage/config@1.1.1 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-stack-overflow-backend@0.2.13 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.2 + +## @backstage/plugin-stackstorm@0.1.10 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/errors@1.2.3 + +## @backstage/plugin-tech-insights@0.3.21 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend@0.5.23 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-tech-insights-node@0.4.15 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.41 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-tech-insights-node@0.4.15 + - @backstage/errors@1.2.3 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-node@0.4.15 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-radar@0.6.12 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + +## @backstage/plugin-techdocs@1.9.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-techdocs-react@1.1.15 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-search-react@1.7.5 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/theme@0.5.0 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.26 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-techdocs-react@1.1.15 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-techdocs@1.9.3 + - @backstage/plugin-catalog@1.16.1 + - @backstage/plugin-search-react@1.7.5 + - @backstage/integration-react@1.1.23 + - @backstage/core-app-api@1.11.3 + - @backstage/test-utils@1.4.7 + +## @backstage/plugin-techdocs-backend@1.9.2 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-search-backend-module-techdocs@0.1.13 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-techdocs-node@1.11.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/plugin-catalog-common@1.0.20 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.4 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-techdocs-react@1.1.15 + - @backstage/integration-react@1.1.23 + - @backstage/integration@1.8.0 + +## @backstage/plugin-techdocs-node@1.11.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/integration-aws-node@0.1.8 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-techdocs-react@1.1.15 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/plugin-todo@0.2.33 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + +## @backstage/plugin-todo-backend@0.3.7 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-openapi-utils@0.1.2 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + +## @backstage/plugin-user-settings-backend@0.2.8 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-vault@0.1.24 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + +## @backstage/plugin-vault-backend@0.4.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-tasks@0.5.14 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-vault-node@0.1.2 + +## @backstage/plugin-vault-node@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + +## @backstage/plugin-xcmetrics@0.2.47 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/errors@1.2.3 + +## example-app@0.2.91 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-api-docs@0.10.3 + - @backstage/plugin-scaffolder-react@1.7.1 + - @backstage/core-components@0.13.10 + - @backstage/plugin-user-settings@0.8.0 + - @backstage/plugin-azure-sites@0.1.18 + - @backstage/cli@0.25.1 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-octopus-deploy@0.2.11 + - @backstage/frontend-app-api@0.5.0 + - @backstage/plugin-kubernetes@0.11.4 + - @backstage/plugin-home@0.6.1 + - @backstage/plugin-scaffolder@1.17.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.4 + - @backstage/plugin-catalog-unprocessed-entities@0.1.7 + - @backstage/plugin-kubernetes-cluster@0.0.5 + - @backstage/plugin-microsoft-calendar@0.1.11 + - @backstage/plugin-newrelic-dashboard@0.3.4 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/plugin-entity-feedback@0.2.12 + - @backstage/plugin-apache-airflow@0.2.19 + - @backstage/plugin-github-actions@0.6.10 + - @backstage/plugin-stack-overflow@0.1.24 + - @backstage/plugin-techdocs-react@1.1.15 + - @backstage/plugin-catalog-graph@0.3.3 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-code-coverage@0.2.22 + - @backstage/plugin-cost-insights@0.12.18 + - @backstage/plugin-tech-insights@0.3.21 + - @backstage/plugin-azure-devops@0.3.11 + - @backstage/plugin-gcp-projects@0.3.45 + - @backstage/plugin-cloudbuild@0.3.29 + - @backstage/plugin-lighthouse@0.4.14 + - @backstage/plugin-stackstorm@0.1.10 + - @backstage/plugin-tech-radar@0.6.12 + - @backstage/plugin-dynatrace@8.0.3 + - @backstage/plugin-gcalendar@0.3.22 + - @backstage/plugin-pagerduty@0.7.1 + - @backstage/plugin-shortcuts@0.3.18 + - @backstage/plugin-airbrake@0.3.29 + - @backstage/plugin-devtools@0.1.8 + - @backstage/plugin-graphiql@0.3.2 + - @backstage/plugin-linguist@0.1.14 + - @backstage/plugin-newrelic@0.3.44 + - @backstage/plugin-playlist@0.2.3 + - @backstage/plugin-puppetdb@0.1.12 + - @backstage/plugin-techdocs@1.9.3 + - @backstage/plugin-catalog@1.16.1 + - @backstage/plugin-explore@0.4.15 + - @backstage/plugin-jenkins@0.9.4 + - @backstage/plugin-rollbar@0.4.29 + - @backstage/plugin-badges@0.2.53 + - @backstage/plugin-search@1.4.5 + - @backstage/plugin-sentry@0.5.14 + - @backstage/plugin-kafka@0.3.29 + - @backstage/plugin-nomad@0.1.10 + - @backstage/plugin-gocd@0.1.35 + - @backstage/plugin-todo@0.2.33 + - @backstage/plugin-adr@0.6.12 + - @backstage/plugin-org@0.6.19 + - @backstage/plugin-catalog-import@0.10.5 + - @backstage/plugin-search-react@1.7.5 + - @backstage/app-defaults@1.4.7 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.3 + - @backstage/theme@0.5.0 + - @backstage/plugin-catalog-common@1.0.20 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-search-common@1.2.10 + +## example-app-next@0.0.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-api-docs@0.10.3 + - @backstage/core-compat-api@0.1.1 + - @backstage/plugin-scaffolder-react@1.7.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/plugin-user-settings@0.8.0 + - @backstage/plugin-azure-sites@0.1.18 + - @backstage/cli@0.25.1 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-octopus-deploy@0.2.11 + - @backstage/frontend-app-api@0.5.0 + - @backstage/plugin-kubernetes@0.11.4 + - @backstage/plugin-home@0.6.1 + - @backstage/plugin-scaffolder@1.17.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.4 + - @backstage/plugin-catalog-unprocessed-entities@0.1.7 + - @backstage/plugin-microsoft-calendar@0.1.11 + - @backstage/plugin-newrelic-dashboard@0.3.4 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/plugin-entity-feedback@0.2.12 + - @backstage/plugin-apache-airflow@0.2.19 + - @backstage/plugin-github-actions@0.6.10 + - @backstage/plugin-techdocs-react@1.1.15 + - @backstage/plugin-catalog-graph@0.3.3 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-code-coverage@0.2.22 + - @backstage/plugin-cost-insights@0.12.18 + - @backstage/plugin-tech-insights@0.3.21 + - @backstage/plugin-azure-devops@0.3.11 + - @backstage/plugin-gcp-projects@0.3.45 + - @backstage/plugin-cloudbuild@0.3.29 + - @backstage/plugin-lighthouse@0.4.14 + - @backstage/plugin-stackstorm@0.1.10 + - @backstage/plugin-tech-radar@0.6.12 + - @backstage/plugin-dynatrace@8.0.3 + - @backstage/plugin-gcalendar@0.3.22 + - @backstage/plugin-pagerduty@0.7.1 + - @backstage/plugin-shortcuts@0.3.18 + - @backstage/plugin-airbrake@0.3.29 + - @backstage/plugin-devtools@0.1.8 + - @backstage/plugin-graphiql@0.3.2 + - @backstage/plugin-linguist@0.1.14 + - @backstage/plugin-newrelic@0.3.44 + - @backstage/plugin-playlist@0.2.3 + - @backstage/plugin-puppetdb@0.1.12 + - @backstage/plugin-techdocs@1.9.3 + - @backstage/plugin-catalog@1.16.1 + - @backstage/plugin-explore@0.4.15 + - @backstage/plugin-jenkins@0.9.4 + - @backstage/plugin-rollbar@0.4.29 + - @backstage/plugin-badges@0.2.53 + - @backstage/plugin-search@1.4.5 + - @backstage/plugin-sentry@0.5.14 + - @backstage/plugin-kafka@0.3.29 + - @backstage/plugin-gocd@0.1.35 + - @backstage/plugin-todo@0.2.33 + - @backstage/plugin-adr@0.6.12 + - @backstage/plugin-org@0.6.19 + - @backstage/plugin-app-visualizer@0.1.0 + - @backstage/plugin-catalog-import@0.10.5 + - app-next-example-plugin@0.0.5 + - @backstage/plugin-search-react@1.7.5 + - @backstage/app-defaults@1.4.7 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/core-app-api@1.11.3 + - @backstage/theme@0.5.0 + - @backstage/plugin-catalog-common@1.0.20 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-search-common@1.2.10 + +## app-next-example-plugin@0.0.5 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + +## example-backend@0.2.91 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.20.3 + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-backend@1.20.0 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.10 + - @backstage/plugin-events-backend@0.2.18 + - @backstage/plugin-search-backend-module-techdocs@0.1.13 + - @backstage/plugin-search-backend-module-catalog@0.1.13 + - @backstage/plugin-search-backend-module-explore@0.1.13 + - @backstage/plugin-azure-devops-backend@0.5.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.6 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.41 + - @backstage/plugin-entity-feedback-backend@0.2.6 + - @backstage/plugin-code-coverage-backend@0.2.23 + - @backstage/plugin-azure-sites-backend@0.1.19 + - @backstage/plugin-tech-insights-node@0.4.15 + - @backstage/plugin-devtools-backend@0.2.6 + - @backstage/plugin-linguist-backend@0.5.6 + - @backstage/plugin-playlist-backend@0.3.13 + - @backstage/plugin-techdocs-backend@1.9.2 + - @backstage/plugin-explore-backend@0.0.19 + - @backstage/plugin-jenkins-backend@0.3.3 + - @backstage/plugin-badges-backend@0.3.6 + - @backstage/plugin-search-backend@1.4.9 + - @backstage/plugin-kafka-backend@0.3.7 + - @backstage/plugin-nomad-backend@0.1.11 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-todo-backend@0.3.7 + - @backstage/plugin-adr-backend@0.4.6 + - @backstage/plugin-app-backend@0.3.57 + - @backstage/plugin-permission-backend@0.5.32 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-catalog-backend@1.16.1 + - example-app@0.2.91 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/plugin-kubernetes-backend@0.14.1 + - @backstage/plugin-lighthouse-backend@0.4.1 + - @backstage/plugin-proxy-backend@0.4.7 + - @backstage/plugin-rollbar-backend@0.1.54 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.26 + - @backstage/plugin-search-backend-module-elasticsearch@1.3.12 + - @backstage/plugin-search-backend-module-pg@0.5.18 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/plugin-tech-insights-backend@0.5.23 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.6 + - @backstage/plugin-events-node@0.2.18 + - @backstage/plugin-search-common@1.2.10 + +## example-backend-next@0.0.19 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-sonarqube-backend@0.2.11 + - @backstage/plugin-scaffolder-backend@1.20.0 + - @backstage/plugin-catalog-backend-module-openapi@0.1.26 + - @backstage/plugin-search-backend-module-techdocs@0.1.13 + - @backstage/plugin-search-backend-module-catalog@0.1.13 + - @backstage/plugin-search-backend-module-explore@0.1.13 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-defaults@0.2.9 + - @backstage/plugin-azure-devops-backend@0.5.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.6 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.6 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.2 + - @backstage/plugin-entity-feedback-backend@0.2.6 + - @backstage/plugin-devtools-backend@0.2.6 + - @backstage/plugin-linguist-backend@0.5.6 + - @backstage/plugin-playlist-backend@0.3.13 + - @backstage/plugin-techdocs-backend@1.9.2 + - @backstage/plugin-jenkins-backend@0.3.3 + - @backstage/plugin-badges-backend@0.3.6 + - @backstage/plugin-search-backend@1.4.9 + - @backstage/plugin-nomad-backend@0.1.11 + - @backstage/plugin-todo-backend@0.3.7 + - @backstage/plugin-adr-backend@0.4.6 + - @backstage/plugin-app-backend@0.3.57 + - @backstage/plugin-permission-backend@0.5.32 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-catalog-backend@1.16.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/plugin-kubernetes-backend@0.14.1 + - @backstage/plugin-lighthouse-backend@0.4.1 + - @backstage/plugin-proxy-backend@0.4.7 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.6 + +## e2e-test@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.9 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.3 + +## techdocs-cli-embedded-app@0.2.90 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/cli@0.25.1 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-techdocs-react@1.1.15 + - @backstage/plugin-techdocs@1.9.3 + - @backstage/plugin-catalog@1.16.1 + - @backstage/app-defaults@1.4.7 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.3 + - @backstage/test-utils@1.4.7 + - @backstage/theme@0.5.0 + +## @internal/plugin-todo-list@1.0.21 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + +## @internal/plugin-todo-list-backend@1.0.21 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/errors@1.2.3 + +## @internal/plugin-todo-list-common@1.0.17 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.12 diff --git a/package.json b/package.json index 4d052f2ec5..483e02fdb5 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "@material-ui/pickers@^3.3.10": "patch:@material-ui/pickers@npm%3A3.3.11#./.yarn/patches/@material-ui-pickers-npm-3.3.11-1c8f68ea20.patch", "@material-ui/pickers@^3.2.10": "patch:@material-ui/pickers@npm%3A3.3.11#./.yarn/patches/@material-ui-pickers-npm-3.3.11-1c8f68ea20.patch" }, - "version": "1.22.0-next.2", + "version": "1.22.0", "dependencies": { "@backstage/errors": "workspace:^", "@manypkg/get-packages": "^1.1.3", diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index 443c5fe4c6..5f815f4b0e 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/app-defaults +## 1.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/core-app-api@1.11.3 + - @backstage/theme@0.5.0 + ## 1.4.7-next.1 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index 8634a73d47..bf7b56f8c2 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/app-defaults", "description": "Provides the default wiring of a Backstage App", - "version": "1.4.7-next.1", + "version": "1.4.7", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/app-next-example-plugin/CHANGELOG.md b/packages/app-next-example-plugin/CHANGELOG.md index a3c3157139..6f0545a801 100644 --- a/packages/app-next-example-plugin/CHANGELOG.md +++ b/packages/app-next-example-plugin/CHANGELOG.md @@ -1,5 +1,13 @@ # app-next-example-plugin +## 0.0.5 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + ## 0.0.5-next.2 ### Patch Changes diff --git a/packages/app-next-example-plugin/package.json b/packages/app-next-example-plugin/package.json index 3e7f665b77..c7669d93cb 100644 --- a/packages/app-next-example-plugin/package.json +++ b/packages/app-next-example-plugin/package.json @@ -1,7 +1,7 @@ { "name": "app-next-example-plugin", "description": "Backstage internal example plugin", - "version": "0.0.5-next.2", + "version": "0.0.5", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/app-next/CHANGELOG.md b/packages/app-next/CHANGELOG.md index 3a4b1a2369..6272ef11df 100644 --- a/packages/app-next/CHANGELOG.md +++ b/packages/app-next/CHANGELOG.md @@ -1,5 +1,81 @@ # example-app-next +## 0.0.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-api-docs@0.10.3 + - @backstage/core-compat-api@0.1.1 + - @backstage/plugin-scaffolder-react@1.7.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/plugin-user-settings@0.8.0 + - @backstage/plugin-azure-sites@0.1.18 + - @backstage/cli@0.25.1 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-octopus-deploy@0.2.11 + - @backstage/frontend-app-api@0.5.0 + - @backstage/plugin-kubernetes@0.11.4 + - @backstage/plugin-home@0.6.1 + - @backstage/plugin-scaffolder@1.17.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.4 + - @backstage/plugin-catalog-unprocessed-entities@0.1.7 + - @backstage/plugin-microsoft-calendar@0.1.11 + - @backstage/plugin-newrelic-dashboard@0.3.4 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/plugin-entity-feedback@0.2.12 + - @backstage/plugin-apache-airflow@0.2.19 + - @backstage/plugin-github-actions@0.6.10 + - @backstage/plugin-techdocs-react@1.1.15 + - @backstage/plugin-catalog-graph@0.3.3 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-code-coverage@0.2.22 + - @backstage/plugin-cost-insights@0.12.18 + - @backstage/plugin-tech-insights@0.3.21 + - @backstage/plugin-azure-devops@0.3.11 + - @backstage/plugin-gcp-projects@0.3.45 + - @backstage/plugin-cloudbuild@0.3.29 + - @backstage/plugin-lighthouse@0.4.14 + - @backstage/plugin-stackstorm@0.1.10 + - @backstage/plugin-tech-radar@0.6.12 + - @backstage/plugin-dynatrace@8.0.3 + - @backstage/plugin-gcalendar@0.3.22 + - @backstage/plugin-pagerduty@0.7.1 + - @backstage/plugin-shortcuts@0.3.18 + - @backstage/plugin-airbrake@0.3.29 + - @backstage/plugin-devtools@0.1.8 + - @backstage/plugin-graphiql@0.3.2 + - @backstage/plugin-linguist@0.1.14 + - @backstage/plugin-newrelic@0.3.44 + - @backstage/plugin-playlist@0.2.3 + - @backstage/plugin-puppetdb@0.1.12 + - @backstage/plugin-techdocs@1.9.3 + - @backstage/plugin-catalog@1.16.1 + - @backstage/plugin-explore@0.4.15 + - @backstage/plugin-jenkins@0.9.4 + - @backstage/plugin-rollbar@0.4.29 + - @backstage/plugin-badges@0.2.53 + - @backstage/plugin-search@1.4.5 + - @backstage/plugin-sentry@0.5.14 + - @backstage/plugin-kafka@0.3.29 + - @backstage/plugin-gocd@0.1.35 + - @backstage/plugin-todo@0.2.33 + - @backstage/plugin-adr@0.6.12 + - @backstage/plugin-org@0.6.19 + - @backstage/plugin-app-visualizer@0.1.0 + - @backstage/plugin-catalog-import@0.10.5 + - app-next-example-plugin@0.0.5 + - @backstage/plugin-search-react@1.7.5 + - @backstage/app-defaults@1.4.7 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/core-app-api@1.11.3 + - @backstage/theme@0.5.0 + - @backstage/plugin-catalog-common@1.0.20 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-search-common@1.2.10 + ## 0.0.5-next.2 ### Patch Changes diff --git a/packages/app-next/package.json b/packages/app-next/package.json index fe9b81f6db..c51631aaa3 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -1,6 +1,6 @@ { "name": "example-app-next", - "version": "0.0.5-next.2", + "version": "0.0.5", "private": true, "backstage": { "role": "frontend" diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index 5cb183211c..6cf62774c1 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,81 @@ # example-app +## 0.2.91 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-api-docs@0.10.3 + - @backstage/plugin-scaffolder-react@1.7.1 + - @backstage/core-components@0.13.10 + - @backstage/plugin-user-settings@0.8.0 + - @backstage/plugin-azure-sites@0.1.18 + - @backstage/cli@0.25.1 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-octopus-deploy@0.2.11 + - @backstage/frontend-app-api@0.5.0 + - @backstage/plugin-kubernetes@0.11.4 + - @backstage/plugin-home@0.6.1 + - @backstage/plugin-scaffolder@1.17.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.4 + - @backstage/plugin-catalog-unprocessed-entities@0.1.7 + - @backstage/plugin-kubernetes-cluster@0.0.5 + - @backstage/plugin-microsoft-calendar@0.1.11 + - @backstage/plugin-newrelic-dashboard@0.3.4 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/plugin-entity-feedback@0.2.12 + - @backstage/plugin-apache-airflow@0.2.19 + - @backstage/plugin-github-actions@0.6.10 + - @backstage/plugin-stack-overflow@0.1.24 + - @backstage/plugin-techdocs-react@1.1.15 + - @backstage/plugin-catalog-graph@0.3.3 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-code-coverage@0.2.22 + - @backstage/plugin-cost-insights@0.12.18 + - @backstage/plugin-tech-insights@0.3.21 + - @backstage/plugin-azure-devops@0.3.11 + - @backstage/plugin-gcp-projects@0.3.45 + - @backstage/plugin-cloudbuild@0.3.29 + - @backstage/plugin-lighthouse@0.4.14 + - @backstage/plugin-stackstorm@0.1.10 + - @backstage/plugin-tech-radar@0.6.12 + - @backstage/plugin-dynatrace@8.0.3 + - @backstage/plugin-gcalendar@0.3.22 + - @backstage/plugin-pagerduty@0.7.1 + - @backstage/plugin-shortcuts@0.3.18 + - @backstage/plugin-airbrake@0.3.29 + - @backstage/plugin-devtools@0.1.8 + - @backstage/plugin-graphiql@0.3.2 + - @backstage/plugin-linguist@0.1.14 + - @backstage/plugin-newrelic@0.3.44 + - @backstage/plugin-playlist@0.2.3 + - @backstage/plugin-puppetdb@0.1.12 + - @backstage/plugin-techdocs@1.9.3 + - @backstage/plugin-catalog@1.16.1 + - @backstage/plugin-explore@0.4.15 + - @backstage/plugin-jenkins@0.9.4 + - @backstage/plugin-rollbar@0.4.29 + - @backstage/plugin-badges@0.2.53 + - @backstage/plugin-search@1.4.5 + - @backstage/plugin-sentry@0.5.14 + - @backstage/plugin-kafka@0.3.29 + - @backstage/plugin-nomad@0.1.10 + - @backstage/plugin-gocd@0.1.35 + - @backstage/plugin-todo@0.2.33 + - @backstage/plugin-adr@0.6.12 + - @backstage/plugin-org@0.6.19 + - @backstage/plugin-catalog-import@0.10.5 + - @backstage/plugin-search-react@1.7.5 + - @backstage/app-defaults@1.4.7 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.3 + - @backstage/theme@0.5.0 + - @backstage/plugin-catalog-common@1.0.20 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-search-common@1.2.10 + ## 0.2.91-next.2 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index 1d5ac94352..fbbe6ce09d 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.91-next.2", + "version": "0.2.91", "private": true, "backstage": { "role": "frontend" diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index 5790b020fb..16106ee354 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/backend-app-api +## 0.5.10 + +### Patch Changes + +- 516fd3e: Updated README to reflect release status +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/config-loader@1.6.1 + - @backstage/cli-node@0.2.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.5.10-next.2 ### Patch Changes diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index 246da2e6a4..37fa2c5258 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-app-api", "description": "Core API used by Backstage backend apps", - "version": "0.5.10-next.2", + "version": "0.5.10", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index b9a80e3841..de955b7ca1 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/backend-common +## 0.20.1 + +### Patch Changes + +- 3b24eae: Adding support for removing file from git index +- 454d17c: Do not call fetch directly but rather use `fetchResponse` facility +- b6b15b2: Use sha256 instead of md5 for hash key calculation in caches + + This can have a side effect of invalidating caches (when cache key was >250 characters) + This improves compliance with FIPS nodejs + +- Updated dependencies + - @backstage/config-loader@1.6.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-dev-utils@0.1.3 + - @backstage/backend-app-api@0.5.10 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/integration-aws-node@0.1.8 + - @backstage/types@1.1.1 + ## 0.20.1-next.2 ### Patch Changes diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 14670e42f8..3d746044b0 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-common", "description": "Common functionality library for Backstage backends", - "version": "0.20.1-next.2", + "version": "0.20.1", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index 7f8f81d706..b8bacd3732 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/backend-defaults +## 0.2.9 + +### Patch Changes + +- 516fd3e: Updated README to reflect release status +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-app-api@0.5.10 + ## 0.2.9-next.2 ### Patch Changes diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index 6315f2615a..73a54720f5 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-defaults", "description": "Backend defaults used by Backstage backend apps", - "version": "0.2.9-next.2", + "version": "0.2.9", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-dev-utils/CHANGELOG.md b/packages/backend-dev-utils/CHANGELOG.md index 0ff2ed6442..1c4deba50a 100644 --- a/packages/backend-dev-utils/CHANGELOG.md +++ b/packages/backend-dev-utils/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/backend-dev-utils +## 0.1.3 + +### Patch Changes + +- 516fd3e: Updated README to reflect release status + ## 0.1.3-next.0 ### Patch Changes diff --git a/packages/backend-dev-utils/package.json b/packages/backend-dev-utils/package.json index a58c3ef6bd..67fd763dcd 100644 --- a/packages/backend-dev-utils/package.json +++ b/packages/backend-dev-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-dev-utils", - "version": "0.1.3-next.0", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/backend-dynamic-feature-service/CHANGELOG.md b/packages/backend-dynamic-feature-service/CHANGELOG.md index 07b118e771..4b80750865 100644 --- a/packages/backend-dynamic-feature-service/CHANGELOG.md +++ b/packages/backend-dynamic-feature-service/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/backend-dynamic-feature-service +## 0.1.0 + +### Minor Changes + +- eb81f42: New `backend-dynamic-feature-service` package, for the discovery of dynamic frontend and backend plugins (and modules) and the loading of the backend ones inside the backend application. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/cli-node@0.2.2 + - @backstage/plugin-events-backend@0.2.18 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-catalog-backend@1.16.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.2.18 + - @backstage/plugin-search-common@1.2.10 + ## 0.0.5-next.2 ### Patch Changes diff --git a/packages/backend-dynamic-feature-service/package.json b/packages/backend-dynamic-feature-service/package.json index cd95d6a5ae..18bbd58550 100644 --- a/packages/backend-dynamic-feature-service/package.json +++ b/packages/backend-dynamic-feature-service/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-dynamic-feature-service", "description": "Backstage dynamic feature service", - "version": "0.0.0", + "version": "0.1.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-next/CHANGELOG.md b/packages/backend-next/CHANGELOG.md index 0cf0e0ec5c..96cb73808f 100644 --- a/packages/backend-next/CHANGELOG.md +++ b/packages/backend-next/CHANGELOG.md @@ -1,5 +1,46 @@ # example-backend-next +## 0.0.19 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-sonarqube-backend@0.2.11 + - @backstage/plugin-scaffolder-backend@1.20.0 + - @backstage/plugin-catalog-backend-module-openapi@0.1.26 + - @backstage/plugin-search-backend-module-techdocs@0.1.13 + - @backstage/plugin-search-backend-module-catalog@0.1.13 + - @backstage/plugin-search-backend-module-explore@0.1.13 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-defaults@0.2.9 + - @backstage/plugin-azure-devops-backend@0.5.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.6 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.6 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.2 + - @backstage/plugin-entity-feedback-backend@0.2.6 + - @backstage/plugin-devtools-backend@0.2.6 + - @backstage/plugin-linguist-backend@0.5.6 + - @backstage/plugin-playlist-backend@0.3.13 + - @backstage/plugin-techdocs-backend@1.9.2 + - @backstage/plugin-jenkins-backend@0.3.3 + - @backstage/plugin-badges-backend@0.3.6 + - @backstage/plugin-search-backend@1.4.9 + - @backstage/plugin-nomad-backend@0.1.11 + - @backstage/plugin-todo-backend@0.3.7 + - @backstage/plugin-adr-backend@0.4.6 + - @backstage/plugin-app-backend@0.3.57 + - @backstage/plugin-permission-backend@0.5.32 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-catalog-backend@1.16.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/plugin-kubernetes-backend@0.14.1 + - @backstage/plugin-lighthouse-backend@0.4.1 + - @backstage/plugin-proxy-backend@0.4.7 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.6 + ## 0.0.19-next.2 ### Patch Changes diff --git a/packages/backend-next/package.json b/packages/backend-next/package.json index a7bb842d76..d6908f6e78 100644 --- a/packages/backend-next/package.json +++ b/packages/backend-next/package.json @@ -1,6 +1,6 @@ { "name": "example-backend-next", - "version": "0.0.19-next.2", + "version": "0.0.19", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/backend-openapi-utils/CHANGELOG.md b/packages/backend-openapi-utils/CHANGELOG.md index ab7900200a..9cbaa84947 100644 --- a/packages/backend-openapi-utils/CHANGELOG.md +++ b/packages/backend-openapi-utils/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/backend-openapi-utils +## 0.1.2 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/errors@1.2.3 + ## 0.1.2-next.2 ### Patch Changes diff --git a/packages/backend-openapi-utils/package.json b/packages/backend-openapi-utils/package.json index 79c5d47bbd..2ca6c3b716 100644 --- a/packages/backend-openapi-utils/package.json +++ b/packages/backend-openapi-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-openapi-utils", "description": "OpenAPI typescript support.", - "version": "0.1.2-next.2", + "version": "0.1.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/backend-plugin-api/CHANGELOG.md b/packages/backend-plugin-api/CHANGELOG.md index ff61277e52..80f9026e21 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/backend-plugin-api +## 0.6.9 + +### Patch Changes + +- 516fd3e: Updated README to reflect release status +- Updated dependencies + - @backstage/plugin-permission-common@0.7.12 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + ## 0.6.9-next.2 ### Patch Changes diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index 52ed558974..618a537bf5 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-plugin-api", "description": "Core API used by Backstage backend plugins", - "version": "0.6.9-next.2", + "version": "0.6.9", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-tasks/CHANGELOG.md b/packages/backend-tasks/CHANGELOG.md index 8cf0bf8f5b..d107e5b51d 100644 --- a/packages/backend-tasks/CHANGELOG.md +++ b/packages/backend-tasks/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/backend-tasks +## 0.5.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.5.14-next.2 ### Patch Changes diff --git a/packages/backend-tasks/package.json b/packages/backend-tasks/package.json index 139c160bbf..4af6a3462a 100644 --- a/packages/backend-tasks/package.json +++ b/packages/backend-tasks/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-tasks", "description": "Common distributed task management library for Backstage backends", - "version": "0.5.14-next.2", + "version": "0.5.14", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md index e9dbbaa15a..66870f7f01 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/backend-test-utils +## 0.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-app-api@0.5.10 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.2.10-next.2 ### Patch Changes diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 00d4a98d40..8fcaff66ae 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-test-utils", "description": "Test helpers library for Backstage backends", - "version": "0.2.10-next.2", + "version": "0.2.10", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index f333e0ee04..838b69f5ab 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,63 @@ # example-backend +## 0.2.91 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.20.3 + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-backend@1.20.0 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.10 + - @backstage/plugin-events-backend@0.2.18 + - @backstage/plugin-search-backend-module-techdocs@0.1.13 + - @backstage/plugin-search-backend-module-catalog@0.1.13 + - @backstage/plugin-search-backend-module-explore@0.1.13 + - @backstage/plugin-azure-devops-backend@0.5.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.6 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.41 + - @backstage/plugin-entity-feedback-backend@0.2.6 + - @backstage/plugin-code-coverage-backend@0.2.23 + - @backstage/plugin-azure-sites-backend@0.1.19 + - @backstage/plugin-tech-insights-node@0.4.15 + - @backstage/plugin-devtools-backend@0.2.6 + - @backstage/plugin-linguist-backend@0.5.6 + - @backstage/plugin-playlist-backend@0.3.13 + - @backstage/plugin-techdocs-backend@1.9.2 + - @backstage/plugin-explore-backend@0.0.19 + - @backstage/plugin-jenkins-backend@0.3.3 + - @backstage/plugin-badges-backend@0.3.6 + - @backstage/plugin-search-backend@1.4.9 + - @backstage/plugin-kafka-backend@0.3.7 + - @backstage/plugin-nomad-backend@0.1.11 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-todo-backend@0.3.7 + - @backstage/plugin-adr-backend@0.4.6 + - @backstage/plugin-app-backend@0.3.57 + - @backstage/plugin-permission-backend@0.5.32 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-catalog-backend@1.16.1 + - example-app@0.2.91 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/plugin-kubernetes-backend@0.14.1 + - @backstage/plugin-lighthouse-backend@0.4.1 + - @backstage/plugin-proxy-backend@0.4.7 + - @backstage/plugin-rollbar-backend@0.1.54 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.26 + - @backstage/plugin-search-backend-module-elasticsearch@1.3.12 + - @backstage/plugin-search-backend-module-pg@0.5.18 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/plugin-tech-insights-backend@0.5.23 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.6 + - @backstage/plugin-events-node@0.2.18 + - @backstage/plugin-search-common@1.2.10 + ## 0.2.91-next.2 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index b5518dde56..4bcf627366 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.2.91-next.2", + "version": "0.2.91", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/catalog-client/CHANGELOG.md b/packages/catalog-client/CHANGELOG.md index b3e04958f9..78d126445e 100644 --- a/packages/catalog-client/CHANGELOG.md +++ b/packages/catalog-client/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/catalog-client +## 1.5.2 + +### Patch Changes + +- 883782e: Fix a bug in `getLocationByRef` that led to invalid backend calls +- Updated dependencies + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + ## 1.5.2-next.0 ### Patch Changes diff --git a/packages/catalog-client/package.json b/packages/catalog-client/package.json index f87d5aa221..cfa9399d97 100644 --- a/packages/catalog-client/package.json +++ b/packages/catalog-client/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/catalog-client", "description": "An isomorphic client for the catalog backend", - "version": "1.5.2-next.0", + "version": "1.5.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/cli-node/CHANGELOG.md b/packages/cli-node/CHANGELOG.md index e7a70042c1..176785b2db 100644 --- a/packages/cli-node/CHANGELOG.md +++ b/packages/cli-node/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/cli-node +## 0.2.2 + +### Patch Changes + +- 7acbb5a: Removed `mock-fs` dev dependency. +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.2.2-next.0 ### Patch Changes diff --git a/packages/cli-node/package.json b/packages/cli-node/package.json index 5d3fde9839..60ba687ddc 100644 --- a/packages/cli-node/package.json +++ b/packages/cli-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli-node", "description": "Node.js library for Backstage CLIs", - "version": "0.2.2-next.0", + "version": "0.2.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 13aa1c9a97..0c686ea8c4 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/cli +## 0.25.1 + +### Patch Changes + +- b6b15b2: Use sha256 instead of md5 in build script cache key calculation + + Makes it possible to build on FIPS nodejs. + +- Updated dependencies + - @backstage/config-loader@1.6.1 + - @backstage/cli-node@0.2.2 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/eslint-plugin@0.1.4 + - @backstage/integration@1.8.0 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + ## 0.25.1-next.1 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 85de89c92a..a02e7474ff 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli", "description": "CLI for developing Backstage plugins and apps", - "version": "0.25.1-next.1", + "version": "0.25.1", "publishConfig": { "access": "public" }, diff --git a/packages/config-loader/CHANGELOG.md b/packages/config-loader/CHANGELOG.md index 7e2228f5a5..24f7a3addc 100644 --- a/packages/config-loader/CHANGELOG.md +++ b/packages/config-loader/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/config-loader +## 1.6.1 + +### Patch Changes + +- 7acbb5a: Removed `mock-fs` dev dependency. +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 1.6.1-next.0 ### Patch Changes diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index 17df3b1357..e26a54559c 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/config-loader", "description": "Config loading functionality used by Backstage backend, and CLI", - "version": "1.6.1-next.0", + "version": "1.6.1", "publishConfig": { "access": "public", "main": "dist/index.cjs.js", diff --git a/packages/core-app-api/CHANGELOG.md b/packages/core-app-api/CHANGELOG.md index 7341335318..9e32db5016 100644 --- a/packages/core-app-api/CHANGELOG.md +++ b/packages/core-app-api/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/core-app-api +## 1.11.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + ## 1.11.3-next.0 ### Patch Changes diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index 05770f3eee..f0654f7596 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-app-api", "description": "Core app API used by Backstage apps", - "version": "1.11.3-next.0", + "version": "1.11.3", "publishConfig": { "access": "public" }, diff --git a/packages/core-compat-api/CHANGELOG.md b/packages/core-compat-api/CHANGELOG.md index 50604d27db..21c7782627 100644 --- a/packages/core-compat-api/CHANGELOG.md +++ b/packages/core-compat-api/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/core-compat-api +## 0.1.1 + +### Patch Changes + +- 4c1f50c: Make `convertLegacyApp` wrap discovered routes with `compatWrapper`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-plugin-api@1.8.2 + - @backstage/core-app-api@1.11.3 + - @backstage/version-bridge@1.0.7 + ## 0.1.1-next.2 ### Patch Changes diff --git a/packages/core-compat-api/package.json b/packages/core-compat-api/package.json index 9869de1e60..99b705bfcf 100644 --- a/packages/core-compat-api/package.json +++ b/packages/core-compat-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/core-compat-api", - "version": "0.1.1-next.2", + "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index 2a84f778cb..c6ffec5679 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/core-components +## 0.13.10 + +### Patch Changes + +- d625f66: Fixed bug in Link where it was possible to select and copy a hidden element into clipboard +- 6878b1d: Removed unnecessary `history` and `immer` dependencies. +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/theme@0.5.0 + - @backstage/version-bridge@1.0.7 + ## 0.13.10-next.1 ### Patch Changes diff --git a/packages/core-components/package.json b/packages/core-components/package.json index 25d7fe111c..70afda8983 100644 --- a/packages/core-components/package.json +++ b/packages/core-components/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-components", "description": "Core components used by Backstage plugins and apps", - "version": "0.13.10-next.1", + "version": "0.13.10", "publishConfig": { "access": "public" }, diff --git a/packages/core-plugin-api/CHANGELOG.md b/packages/core-plugin-api/CHANGELOG.md index bdc94c0f1e..4cb681e4aa 100644 --- a/packages/core-plugin-api/CHANGELOG.md +++ b/packages/core-plugin-api/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/core-plugin-api +## 1.8.2 + +### Patch Changes + +- 6878b1d: Removed unnecessary `i18next` dependency. +- Updated dependencies + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + ## 1.8.2-next.0 ### Patch Changes diff --git a/packages/core-plugin-api/package.json b/packages/core-plugin-api/package.json index b61bf9991d..d676260227 100644 --- a/packages/core-plugin-api/package.json +++ b/packages/core-plugin-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-plugin-api", "description": "Core API used by Backstage plugins", - "version": "1.8.2-next.0", + "version": "1.8.2", "publishConfig": { "access": "public" }, diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index 1c77f14254..3008a3a03d 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/create-app +## 0.5.9 + +### Patch Changes + +- c9f71fb: Bumped create-app version. +- ac277f3: Bumped create-app version. +- 7acbb5a: Removed `mock-fs` dev dependency. +- Updated dependencies + - @backstage/cli-common@0.1.13 + ## 0.5.9-next.2 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index e68dea26f5..e9f73d6e1f 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/create-app", "description": "A CLI that helps you create your own Backstage app", - "version": "0.5.9-next.2", + "version": "0.5.9", "publishConfig": { "access": "public" }, diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index cbbd849093..602f2b563e 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/dev-utils +## 1.0.26 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/app-defaults@1.4.7 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/core-app-api@1.11.3 + - @backstage/theme@0.5.0 + ## 1.0.26-next.2 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 74c548a5a4..40537c1a98 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/dev-utils", "description": "Utilities for developing Backstage plugins.", - "version": "1.0.26-next.2", + "version": "1.0.26", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/e2e-test/CHANGELOG.md b/packages/e2e-test/CHANGELOG.md index ef58183440..f130de43d4 100644 --- a/packages/e2e-test/CHANGELOG.md +++ b/packages/e2e-test/CHANGELOG.md @@ -1,5 +1,14 @@ # e2e-test +## 0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.9 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.3 + ## 0.2.11-next.2 ### Patch Changes diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index 8999c53daa..40699588e2 100644 --- a/packages/e2e-test/package.json +++ b/packages/e2e-test/package.json @@ -1,7 +1,7 @@ { "name": "e2e-test", "description": "E2E test for verifying Backstage packages", - "version": "0.2.11-next.2", + "version": "0.2.11", "private": true, "backstage": { "role": "cli" diff --git a/packages/frontend-app-api/CHANGELOG.md b/packages/frontend-app-api/CHANGELOG.md index f6d98b7845..d7c7816449 100644 --- a/packages/frontend-app-api/CHANGELOG.md +++ b/packages/frontend-app-api/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/frontend-app-api +## 0.5.0 + +### Minor Changes + +- d4149bf: **BREAKING**: Renamed the `app/router` extension to `app/root`. +- 074dfe3: Attaching extensions to an input that does not exist is now a warning rather than an error. + +### Patch Changes + +- 7d63b32: Accepts sub route refs on the new `createPlugin` routes map. +- 516fd3e: Updated README to reflect release status +- c97fa1c: Added `elements`, `wrappers`, and `router` inputs to `app/root`, that let you add things to the root of the React tree above the layout. You can use the `createAppRootElementExtension`, `createAppRootWrapperExtension`, and `createRouterExtension` extension creator, respectively, to conveniently create such extensions. These are all optional, and if you do not supply a router a default one will be used (`BrowserRouter` in regular runs, `MemoryRouter` in tests/CI). +- 5fe6600: add oauth dialog and alert display to the root elements +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.3 + - @backstage/errors@1.2.3 + - @backstage/theme@0.5.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + ## 0.4.1-next.2 ### Patch Changes diff --git a/packages/frontend-app-api/package.json b/packages/frontend-app-api/package.json index 25ab827d4a..440f0cdb3f 100644 --- a/packages/frontend-app-api/package.json +++ b/packages/frontend-app-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/frontend-app-api", - "version": "0.4.1-next.2", + "version": "0.5.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/frontend-plugin-api/CHANGELOG.md b/packages/frontend-plugin-api/CHANGELOG.md index c02760f4e1..c6ae8056ec 100644 --- a/packages/frontend-plugin-api/CHANGELOG.md +++ b/packages/frontend-plugin-api/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/frontend-plugin-api +## 0.5.0 + +### Minor Changes + +- d4149bf: **BREAKING**: Renamed the `app/router` extension to `app/root`. + +### Patch Changes + +- b2d370e: Exposed `createComponentRef`, and ensured that produced refs and feature bits have a `toString` for easier debugging +- 7d63b32: Accepts sub route refs on the new `createPlugin` routes map. +- 516fd3e: Updated README to reflect release status +- 4016f21: Remove some unused dependencies +- c97fa1c: Added `elements`, `wrappers`, and `router` inputs to `app/root`, that let you add things to the root of the React tree above the layout. You can use the `createAppRootElementExtension`, `createAppRootWrapperExtension`, and `createRouterExtension` extension creator, respectively, to conveniently create such extensions. These are all optional, and if you do not supply a router a default one will be used (`BrowserRouter` in regular runs, `MemoryRouter` in tests/CI). +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + ## 0.4.1-next.2 ### Patch Changes diff --git a/packages/frontend-plugin-api/package.json b/packages/frontend-plugin-api/package.json index 007d76764b..bc92f6f632 100644 --- a/packages/frontend-plugin-api/package.json +++ b/packages/frontend-plugin-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/frontend-plugin-api", - "version": "0.4.1-next.2", + "version": "0.5.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/frontend-test-utils/CHANGELOG.md b/packages/frontend-test-utils/CHANGELOG.md index 0d119d72fa..dc3555499e 100644 --- a/packages/frontend-test-utils/CHANGELOG.md +++ b/packages/frontend-test-utils/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/frontend-test-utils +## 0.1.1 + +### Patch Changes + +- f7566f9: Updates to reflect the `app/router` extension having been renamed to `app/root`. +- 516fd3e: Updated README to reflect release status +- c97fa1c: Added `elements`, `wrappers`, and `router` inputs to `app/root`, that let you add things to the root of the React tree above the layout. You can use the `createAppRootElementExtension`, `createAppRootWrapperExtension`, and `createRouterExtension` extension creator, respectively, to conveniently create such extensions. These are all optional, and if you do not supply a router a default one will be used (`BrowserRouter` in regular runs, `MemoryRouter` in tests/CI). +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/frontend-app-api@0.5.0 + - @backstage/test-utils@1.4.7 + - @backstage/types@1.1.1 + ## 0.1.1-next.2 ### Patch Changes diff --git a/packages/frontend-test-utils/package.json b/packages/frontend-test-utils/package.json index 141ce93e34..fbe9e3dec6 100644 --- a/packages/frontend-test-utils/package.json +++ b/packages/frontend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/frontend-test-utils", - "version": "0.1.1-next.2", + "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/integration-react/CHANGELOG.md b/packages/integration-react/CHANGELOG.md index cc58b79619..fd6a47e4e7 100644 --- a/packages/integration-react/CHANGELOG.md +++ b/packages/integration-react/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/integration-react +## 1.1.23 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0 + ## 1.1.23-next.0 ### Patch Changes diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json index e916c24ed4..f1592628ab 100644 --- a/packages/integration-react/package.json +++ b/packages/integration-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/integration-react", "description": "Frontend package for managing integrations towards external systems", - "version": "1.1.23-next.0", + "version": "1.1.23", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/repo-tools/CHANGELOG.md b/packages/repo-tools/CHANGELOG.md index a968648f1c..02ecf90bdc 100644 --- a/packages/repo-tools/CHANGELOG.md +++ b/packages/repo-tools/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/repo-tools +## 0.5.2 + +### Patch Changes + +- 883782e: Updated the OpenAPI template to export the `TypedResponse` interface so that client code can leverage it +- 7acbb5a: Removed `mock-fs` dev dependency. +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/cli-node@0.2.2 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.3 + ## 0.5.2-next.2 ### Patch Changes diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json index 1f46d1fe65..c8f832af01 100644 --- a/packages/repo-tools/package.json +++ b/packages/repo-tools/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/repo-tools", "description": "CLI for Backstage repo tooling ", - "version": "0.5.2-next.2", + "version": "0.5.2", "publishConfig": { "access": "public" }, diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index ceacc30019..0e6163e1b7 100644 --- a/packages/techdocs-cli-embedded-app/CHANGELOG.md +++ b/packages/techdocs-cli-embedded-app/CHANGELOG.md @@ -1,5 +1,24 @@ # techdocs-cli-embedded-app +## 0.2.90 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/cli@0.25.1 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-techdocs-react@1.1.15 + - @backstage/plugin-techdocs@1.9.3 + - @backstage/plugin-catalog@1.16.1 + - @backstage/app-defaults@1.4.7 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.3 + - @backstage/test-utils@1.4.7 + - @backstage/theme@0.5.0 + ## 0.2.90-next.2 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index 2fb78763ac..8e30395052 100644 --- a/packages/techdocs-cli-embedded-app/package.json +++ b/packages/techdocs-cli-embedded-app/package.json @@ -1,6 +1,6 @@ { "name": "techdocs-cli-embedded-app", - "version": "0.2.90-next.2", + "version": "0.2.90", "private": true, "backstage": { "role": "frontend" diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md index d0eddde367..f65ed4bd46 100644 --- a/packages/techdocs-cli/CHANGELOG.md +++ b/packages/techdocs-cli/CHANGELOG.md @@ -1,5 +1,16 @@ # @techdocs/cli +## 1.8.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-techdocs-node@1.11.1 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + ## 1.8.1-next.2 ### Patch Changes diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index 67d9de2012..4d4fc997b6 100644 --- a/packages/techdocs-cli/package.json +++ b/packages/techdocs-cli/package.json @@ -1,7 +1,7 @@ { "name": "@techdocs/cli", "description": "Utility CLI for managing TechDocs sites in Backstage.", - "version": "1.8.1-next.2", + "version": "1.8.1", "publishConfig": { "access": "public" }, diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index 9ab9643131..c4f342b554 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/test-utils +## 1.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/config@1.1.1 + - @backstage/core-app-api@1.11.3 + - @backstage/theme@0.5.0 + - @backstage/types@1.1.1 + ## 1.4.7-next.1 ### Patch Changes diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 5d3bb2ab4e..43b9c29a10 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/test-utils", "description": "Utilities to test Backstage plugins and apps.", - "version": "1.4.7-next.1", + "version": "1.4.7", "publishConfig": { "access": "public" }, diff --git a/plugins/adr-backend/CHANGELOG.md b/plugins/adr-backend/CHANGELOG.md index 81c3f3bce6..adc0cf284f 100644 --- a/plugins/adr-backend/CHANGELOG.md +++ b/plugins/adr-backend/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-adr-backend +## 0.4.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/plugin-adr-common@0.2.19 + - @backstage/plugin-search-common@1.2.10 + ## 0.4.6-next.2 ### Patch Changes diff --git a/plugins/adr-backend/package.json b/plugins/adr-backend/package.json index cbd535acc0..24cebdff04 100644 --- a/plugins/adr-backend/package.json +++ b/plugins/adr-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-adr-backend", - "version": "0.4.6-next.2", + "version": "0.4.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/adr-common/CHANGELOG.md b/plugins/adr-common/CHANGELOG.md index 6f85feed2a..84c285a1a8 100644 --- a/plugins/adr-common/CHANGELOG.md +++ b/plugins/adr-common/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-adr-common +## 0.2.19 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.3 + - @backstage/integration@1.8.0 + - @backstage/plugin-search-common@1.2.10 + ## 0.2.18 ### Patch Changes diff --git a/plugins/adr-common/package.json b/plugins/adr-common/package.json index 4e345cf19b..d05b585c7d 100644 --- a/plugins/adr-common/package.json +++ b/plugins/adr-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-adr-common", "description": "Common functionalities for the adr plugin", - "version": "0.2.18", + "version": "0.2.19", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/adr/CHANGELOG.md b/plugins/adr/CHANGELOG.md index 2d33b2db7c..8cf8b2c28e 100644 --- a/plugins/adr/CHANGELOG.md +++ b/plugins/adr/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-adr +## 0.6.12 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-search-react@1.7.5 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-adr-common@0.2.19 + - @backstage/plugin-search-common@1.2.10 + ## 0.6.12-next.2 ### Patch Changes diff --git a/plugins/adr/package.json b/plugins/adr/package.json index 6760c7b3a2..35c89ce255 100644 --- a/plugins/adr/package.json +++ b/plugins/adr/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-adr", - "version": "0.6.12-next.2", + "version": "0.6.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/airbrake-backend/CHANGELOG.md b/plugins/airbrake-backend/CHANGELOG.md index ccad48c17e..2a7c655a2d 100644 --- a/plugins/airbrake-backend/CHANGELOG.md +++ b/plugins/airbrake-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-airbrake-backend +## 0.3.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + ## 0.3.6-next.2 ### Patch Changes diff --git a/plugins/airbrake-backend/package.json b/plugins/airbrake-backend/package.json index a505c3d493..f424ba8ce7 100644 --- a/plugins/airbrake-backend/package.json +++ b/plugins/airbrake-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake-backend", - "version": "0.3.6-next.2", + "version": "0.3.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/airbrake/CHANGELOG.md b/plugins/airbrake/CHANGELOG.md index 9df64be9aa..4636c27068 100644 --- a/plugins/airbrake/CHANGELOG.md +++ b/plugins/airbrake/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-airbrake +## 0.3.29 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/dev-utils@1.0.26 + - @backstage/catalog-model@1.4.3 + - @backstage/test-utils@1.4.7 + ## 0.3.29-next.2 ### Patch Changes diff --git a/plugins/airbrake/package.json b/plugins/airbrake/package.json index 4d33c28633..3cf1107fe0 100644 --- a/plugins/airbrake/package.json +++ b/plugins/airbrake/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake", - "version": "0.3.29-next.2", + "version": "0.3.29", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/allure/CHANGELOG.md b/plugins/allure/CHANGELOG.md index 554839eb83..bf9aaa61df 100644 --- a/plugins/allure/CHANGELOG.md +++ b/plugins/allure/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-allure +## 0.1.45 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + ## 0.1.45-next.2 ### Patch Changes diff --git a/plugins/allure/package.json b/plugins/allure/package.json index 6d8817def9..991c2a8944 100644 --- a/plugins/allure/package.json +++ b/plugins/allure/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-allure", "description": "A Backstage plugin that integrates with Allure", - "version": "0.1.45-next.2", + "version": "0.1.45", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/analytics-module-ga/CHANGELOG.md b/plugins/analytics-module-ga/CHANGELOG.md index c77afd0bf4..5135b15ac1 100644 --- a/plugins/analytics-module-ga/CHANGELOG.md +++ b/plugins/analytics-module-ga/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-analytics-module-ga +## 0.1.37 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/config@1.1.1 + ## 0.1.37-next.1 ### Patch Changes diff --git a/plugins/analytics-module-ga/package.json b/plugins/analytics-module-ga/package.json index 1995731b01..3d367a5889 100644 --- a/plugins/analytics-module-ga/package.json +++ b/plugins/analytics-module-ga/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-analytics-module-ga", - "version": "0.1.37-next.1", + "version": "0.1.37", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/analytics-module-ga4/CHANGELOG.md b/plugins/analytics-module-ga4/CHANGELOG.md index cc177dc290..6529fc3711 100644 --- a/plugins/analytics-module-ga4/CHANGELOG.md +++ b/plugins/analytics-module-ga4/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-analytics-module-ga4 +## 0.1.8 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/config@1.1.1 + ## 0.1.8-next.1 ### Patch Changes diff --git a/plugins/analytics-module-ga4/package.json b/plugins/analytics-module-ga4/package.json index a4b459ba5b..97b610c2bf 100644 --- a/plugins/analytics-module-ga4/package.json +++ b/plugins/analytics-module-ga4/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-analytics-module-ga4", - "version": "0.1.8-next.1", + "version": "0.1.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/analytics-module-newrelic-browser/CHANGELOG.md b/plugins/analytics-module-newrelic-browser/CHANGELOG.md index c687761295..0f9b210d9a 100644 --- a/plugins/analytics-module-newrelic-browser/CHANGELOG.md +++ b/plugins/analytics-module-newrelic-browser/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-analytics-module-newrelic-browser +## 0.0.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/config@1.1.1 + ## 0.0.6-next.1 ### Patch Changes diff --git a/plugins/analytics-module-newrelic-browser/package.json b/plugins/analytics-module-newrelic-browser/package.json index 1448b1923a..0815b62b6c 100644 --- a/plugins/analytics-module-newrelic-browser/package.json +++ b/plugins/analytics-module-newrelic-browser/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-analytics-module-newrelic-browser", - "version": "0.0.6-next.1", + "version": "0.0.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/apache-airflow/CHANGELOG.md b/plugins/apache-airflow/CHANGELOG.md index ddd38838ba..9c2a434030 100644 --- a/plugins/apache-airflow/CHANGELOG.md +++ b/plugins/apache-airflow/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-apache-airflow +## 0.2.19 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + ## 0.2.19-next.1 ### Patch Changes diff --git a/plugins/apache-airflow/package.json b/plugins/apache-airflow/package.json index d2241c820b..489fcde5e8 100644 --- a/plugins/apache-airflow/package.json +++ b/plugins/apache-airflow/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-apache-airflow", - "version": "0.2.19-next.1", + "version": "0.2.19", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md index a8e4e81997..f801bf9ba2 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-api-docs +## 0.10.3 + +### Patch Changes + +- 8a69cc9: Fix custom http resolvers for AsyncAPI widget. +- 062b8f2: Add permission check to Register Existing API button +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-catalog@1.16.1 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-catalog-common@1.0.20 + ## 0.10.3-next.2 ### Patch Changes diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 8f4db504f6..1819d80208 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-api-docs", "description": "A Backstage plugin that helps represent API entities in the frontend", - "version": "0.10.3-next.2", + "version": "0.10.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/apollo-explorer/CHANGELOG.md b/plugins/apollo-explorer/CHANGELOG.md index 77a44cd37d..1523721718 100644 --- a/plugins/apollo-explorer/CHANGELOG.md +++ b/plugins/apollo-explorer/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-apollo-explorer +## 0.1.19 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + ## 0.1.19-next.1 ### Patch Changes diff --git a/plugins/apollo-explorer/package.json b/plugins/apollo-explorer/package.json index 2b9fe695f5..37895e3343 100644 --- a/plugins/apollo-explorer/package.json +++ b/plugins/apollo-explorer/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-apollo-explorer", - "version": "0.1.19-next.1", + "version": "0.1.19", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md index 8d66e21c5c..8550264a15 100644 --- a/plugins/app-backend/CHANGELOG.md +++ b/plugins/app-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-app-backend +## 0.3.57 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/config-loader@1.6.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.9 + ## 0.3.57-next.2 ### Patch Changes diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index ec9fd3c805..0aecbec7f0 100644 --- a/plugins/app-backend/package.json +++ b/plugins/app-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-app-backend", "description": "A Backstage backend plugin that serves the Backstage frontend app", - "version": "0.3.57-next.2", + "version": "0.3.57", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/app-node/CHANGELOG.md b/plugins/app-node/CHANGELOG.md index 9739a86adb..d396e40aba 100644 --- a/plugins/app-node/CHANGELOG.md +++ b/plugins/app-node/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-app-node +## 0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + ## 0.1.9-next.2 ### Patch Changes diff --git a/plugins/app-node/package.json b/plugins/app-node/package.json index 772b7634cc..38c5eadacf 100644 --- a/plugins/app-node/package.json +++ b/plugins/app-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-app-node", "description": "Node.js library for the app plugin", - "version": "0.1.9-next.2", + "version": "0.1.9", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/app-visualizer/CHANGELOG.md b/plugins/app-visualizer/CHANGELOG.md new file mode 100644 index 0000000000..a4ddea2590 --- /dev/null +++ b/plugins/app-visualizer/CHANGELOG.md @@ -0,0 +1,14 @@ +# @backstage/plugin-app-visualizer + +## 0.1.0 + +### Minor Changes + +- e57cc9f: Initial release of the app visualizer plugin. + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 diff --git a/plugins/app-visualizer/package.json b/plugins/app-visualizer/package.json index 2d220e7633..197e97c464 100644 --- a/plugins/app-visualizer/package.json +++ b/plugins/app-visualizer/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-app-visualizer", "description": "Visualizes the Backstage app structure", - "version": "0.0.0", + "version": "0.1.0", "publishConfig": { "access": "public" }, diff --git a/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md b/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md index 53cb34d82c..22f61ff088 100644 --- a/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-atlassian-provider +## 0.1.1 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + ## 0.1.1-next.2 ### Patch Changes diff --git a/plugins/auth-backend-module-atlassian-provider/package.json b/plugins/auth-backend-module-atlassian-provider/package.json index 1b23ec5b86..3d73de88fc 100644 --- a/plugins/auth-backend-module-atlassian-provider/package.json +++ b/plugins/auth-backend-module-atlassian-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-atlassian-provider", "description": "The atlassian-provider backend module for the auth plugin.", - "version": "0.1.1-next.2", + "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md b/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md index 506bd36057..e9e5d99224 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-auth-backend-module-gcp-iap-provider +## 0.2.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.2.3-next.2 ### Patch Changes diff --git a/plugins/auth-backend-module-gcp-iap-provider/package.json b/plugins/auth-backend-module-gcp-iap-provider/package.json index 21eb4fc51e..d167389b20 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/package.json +++ b/plugins/auth-backend-module-gcp-iap-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-gcp-iap-provider", "description": "A GCP IAP auth provider module for the Backstage auth backend", - "version": "0.2.3-next.2", + "version": "0.2.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-github-provider/CHANGELOG.md b/plugins/auth-backend-module-github-provider/CHANGELOG.md index cdfc128d85..ee59a1e269 100644 --- a/plugins/auth-backend-module-github-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-github-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-github-provider +## 0.1.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + ## 0.1.6-next.2 ### Patch Changes diff --git a/plugins/auth-backend-module-github-provider/package.json b/plugins/auth-backend-module-github-provider/package.json index 7cd95fe0a0..bf84dc5ec7 100644 --- a/plugins/auth-backend-module-github-provider/package.json +++ b/plugins/auth-backend-module-github-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-github-provider", "description": "The github-provider backend module for the auth plugin.", - "version": "0.1.6-next.2", + "version": "0.1.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md b/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md index 9222ec93be..92acc636c1 100644 --- a/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-gitlab-provider +## 0.1.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + ## 0.1.6-next.2 ### Patch Changes diff --git a/plugins/auth-backend-module-gitlab-provider/package.json b/plugins/auth-backend-module-gitlab-provider/package.json index bdf17c3c07..c7f4d5ef04 100644 --- a/plugins/auth-backend-module-gitlab-provider/package.json +++ b/plugins/auth-backend-module-gitlab-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-gitlab-provider", "description": "The gitlab-provider backend module for the auth plugin.", - "version": "0.1.6-next.2", + "version": "0.1.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-google-provider/CHANGELOG.md b/plugins/auth-backend-module-google-provider/CHANGELOG.md index 57127a7aea..b43722644b 100644 --- a/plugins/auth-backend-module-google-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-google-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-google-provider +## 0.1.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + ## 0.1.6-next.2 ### Patch Changes diff --git a/plugins/auth-backend-module-google-provider/package.json b/plugins/auth-backend-module-google-provider/package.json index eb8191090a..7528d9f8b6 100644 --- a/plugins/auth-backend-module-google-provider/package.json +++ b/plugins/auth-backend-module-google-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-google-provider", "description": "A Google auth provider module for the Backstage auth backend", - "version": "0.1.6-next.2", + "version": "0.1.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md b/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md index 61a4b756ab..496538fdf0 100644 --- a/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-microsoft-provider +## 0.1.4 + +### Patch Changes + +- 928efbc: Deprecated the `authModuleMicrosoftProvider` export. A default export is now available and should be used like this in your backend: `backend.add(import('@backstage/plugin-auth-backend-module-microsoft-provider'));` +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + ## 0.1.4-next.2 ### Patch Changes diff --git a/plugins/auth-backend-module-microsoft-provider/package.json b/plugins/auth-backend-module-microsoft-provider/package.json index 99e85bd8d8..9412575200 100644 --- a/plugins/auth-backend-module-microsoft-provider/package.json +++ b/plugins/auth-backend-module-microsoft-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-microsoft-provider", "description": "The microsoft-provider backend module for the auth plugin.", - "version": "0.1.4-next.2", + "version": "0.1.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md b/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md index 46cee9f112..44cb96b97d 100644 --- a/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-oauth2-provider +## 0.1.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + ## 0.1.6-next.2 ### Patch Changes diff --git a/plugins/auth-backend-module-oauth2-provider/package.json b/plugins/auth-backend-module-oauth2-provider/package.json index cf385237e5..5edc0be4b8 100644 --- a/plugins/auth-backend-module-oauth2-provider/package.json +++ b/plugins/auth-backend-module-oauth2-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-oauth2-provider", "description": "The oauth2-provider backend module for the auth plugin.", - "version": "0.1.6-next.2", + "version": "0.1.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md b/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md index 7ecac42625..71c14a75e2 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-oauth2-proxy-provider +## 0.1.1 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/errors@1.2.3 + ## 0.1.1-next.2 ### Patch Changes diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/package.json b/plugins/auth-backend-module-oauth2-proxy-provider/package.json index 7ed983ce0e..c3d49bfcd0 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/package.json +++ b/plugins/auth-backend-module-oauth2-proxy-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-oauth2-proxy-provider", "description": "The oauth2-proxy-provider backend module for the auth plugin.", - "version": "0.1.1-next.2", + "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-okta-provider/CHANGELOG.md b/plugins/auth-backend-module-okta-provider/CHANGELOG.md index 5834ce13de..b059fa0bb4 100644 --- a/plugins/auth-backend-module-okta-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-okta-provider/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-backend-module-okta-provider +## 0.0.2 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + ## 0.0.2-next.2 ### Patch Changes diff --git a/plugins/auth-backend-module-okta-provider/package.json b/plugins/auth-backend-module-okta-provider/package.json index 68fa330c3c..7159ab1292 100644 --- a/plugins/auth-backend-module-okta-provider/package.json +++ b/plugins/auth-backend-module-okta-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-okta-provider", "description": "The okta-provider backend module for the auth plugin.", - "version": "0.0.2-next.2", + "version": "0.0.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md b/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md index 29f61ec259..147a13b97d 100644 --- a/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-auth-backend-module-pinniped-provider +## 0.1.3 + +### Patch Changes + +- 928efbc: Deprecated the `authModulePinnipedProvider` export. A default export is now available and should be used like this in your backend: `backend.add(import('@backstage/plugin-auth-backend-module-pinniped-provider'));` +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/config@1.1.1 + ## 0.1.3-next.2 ### Patch Changes diff --git a/plugins/auth-backend-module-pinniped-provider/package.json b/plugins/auth-backend-module-pinniped-provider/package.json index 6160708204..bda4cd9751 100644 --- a/plugins/auth-backend-module-pinniped-provider/package.json +++ b/plugins/auth-backend-module-pinniped-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-pinniped-provider", "description": "The pinniped-provider backend module for the auth plugin.", - "version": "0.1.3-next.2", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md b/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md index c2f21ade42..8beb4ed11c 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-auth-backend-module-vmware-cloud-provider +## 0.1.1 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + ## 0.1.1-next.2 ### Patch Changes diff --git a/plugins/auth-backend-module-vmware-cloud-provider/package.json b/plugins/auth-backend-module-vmware-cloud-provider/package.json index 0d353a6b84..b9b6a3cdaf 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/package.json +++ b/plugins/auth-backend-module-vmware-cloud-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-vmware-cloud-provider", "description": "The vmware-cloud-provider backend module for the auth plugin.", - "version": "0.1.1-next.2", + "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index 964b2e05e8..a65f0bdb61 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-auth-backend +## 0.20.3 + +### Patch Changes + +- 004499c: Fixed an issue where some Okta's resolvers were missing +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.1 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.1.1 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.3 + - @backstage/plugin-auth-backend-module-github-provider@0.1.6 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.6 + - @backstage/plugin-auth-backend-module-google-provider@0.1.6 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.1.6 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.2 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.20.3-next.2 ### Patch Changes diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index f05551736a..a2b4d01b6c 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend", "description": "A Backstage backend plugin that handles authentication", - "version": "0.20.3-next.2", + "version": "0.20.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-node/CHANGELOG.md b/plugins/auth-node/CHANGELOG.md index f2bbe106a3..36d65e9fa3 100644 --- a/plugins/auth-node/CHANGELOG.md +++ b/plugins/auth-node/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-auth-node +## 0.4.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.4.3-next.2 ### Patch Changes diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index 1f11c7d0a7..fc8fb5b25c 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-node", - "version": "0.4.3-next.2", + "version": "0.4.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-devops-backend/CHANGELOG.md b/plugins/azure-devops-backend/CHANGELOG.md index e63fd49793..7b0a081b34 100644 --- a/plugins/azure-devops-backend/CHANGELOG.md +++ b/plugins/azure-devops-backend/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-azure-devops-backend +## 0.5.1 + +### Patch Changes + +- d076ee4: Updated dependency `azure-devops-node-api` to `^12.0.0`. +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0 + - @backstage/plugin-azure-devops-common@0.3.2 + - @backstage/plugin-catalog-common@1.0.20 + ## 0.5.1-next.2 ### Patch Changes diff --git a/plugins/azure-devops-backend/package.json b/plugins/azure-devops-backend/package.json index e0e3074701..12b598f7e9 100644 --- a/plugins/azure-devops-backend/package.json +++ b/plugins/azure-devops-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops-backend", - "version": "0.5.1-next.2", + "version": "0.5.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-devops/CHANGELOG.md b/plugins/azure-devops/CHANGELOG.md index c4f5208d26..8d851523f6 100644 --- a/plugins/azure-devops/CHANGELOG.md +++ b/plugins/azure-devops/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-azure-devops +## 0.3.11 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/plugin-azure-devops-common@0.3.2 + ## 0.3.11-next.2 ### Patch Changes diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index c394bd8597..db744139ee 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops", - "version": "0.3.11-next.2", + "version": "0.3.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-sites-backend/CHANGELOG.md b/plugins/azure-sites-backend/CHANGELOG.md index 2d7744f9d9..c806c46925 100644 --- a/plugins/azure-sites-backend/CHANGELOG.md +++ b/plugins/azure-sites-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-azure-sites-backend +## 0.1.19 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/config@1.1.1 + - @backstage/plugin-azure-sites-common@0.1.1 + ## 0.1.19-next.2 ### Patch Changes diff --git a/plugins/azure-sites-backend/package.json b/plugins/azure-sites-backend/package.json index be5f7f47c9..ae3a849810 100644 --- a/plugins/azure-sites-backend/package.json +++ b/plugins/azure-sites-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-sites-backend", - "version": "0.1.19-next.2", + "version": "0.1.19", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-sites/CHANGELOG.md b/plugins/azure-sites/CHANGELOG.md index fa99632e82..dd706132a6 100644 --- a/plugins/azure-sites/CHANGELOG.md +++ b/plugins/azure-sites/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-azure-sites +## 0.1.18 + +### Patch Changes + +- a31f688: Show Azure site tags in `EntityAzureSitesOverviewWidget`. +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-azure-sites-common@0.1.1 + ## 0.1.18-next.2 ### Patch Changes diff --git a/plugins/azure-sites/package.json b/plugins/azure-sites/package.json index 3ca64a04e8..cc16ab9e47 100644 --- a/plugins/azure-sites/package.json +++ b/plugins/azure-sites/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-sites", - "version": "0.1.18-next.2", + "version": "0.1.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/badges-backend/CHANGELOG.md b/plugins/badges-backend/CHANGELOG.md index ff7908984b..c0135f7ee8 100644 --- a/plugins/badges-backend/CHANGELOG.md +++ b/plugins/badges-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-badges-backend +## 0.3.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.3.6-next.2 ### Patch Changes diff --git a/plugins/badges-backend/package.json b/plugins/badges-backend/package.json index 3a3c229e7b..893a5b6969 100644 --- a/plugins/badges-backend/package.json +++ b/plugins/badges-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-badges-backend", "description": "A Backstage backend plugin that generates README badges for your entities", - "version": "0.3.6-next.2", + "version": "0.3.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/badges/CHANGELOG.md b/plugins/badges/CHANGELOG.md index 2dd15e3d78..0897cf4caf 100644 --- a/plugins/badges/CHANGELOG.md +++ b/plugins/badges/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-badges +## 0.2.53 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + ## 0.2.53-next.2 ### Patch Changes diff --git a/plugins/badges/package.json b/plugins/badges/package.json index 4ca01e0312..688536d260 100644 --- a/plugins/badges/package.json +++ b/plugins/badges/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-badges", "description": "A Backstage plugin that generates README badges for your entities", - "version": "0.2.53-next.2", + "version": "0.2.53", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bazaar-backend/CHANGELOG.md b/plugins/bazaar-backend/CHANGELOG.md index c476a90394..51dac2f648 100644 --- a/plugins/bazaar-backend/CHANGELOG.md +++ b/plugins/bazaar-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-bazaar-backend +## 0.3.7 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/config@1.1.1 + ## 0.3.7-next.2 ### Patch Changes diff --git a/plugins/bazaar-backend/package.json b/plugins/bazaar-backend/package.json index 5d650ab325..82f4c66a76 100644 --- a/plugins/bazaar-backend/package.json +++ b/plugins/bazaar-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar-backend", - "version": "0.3.7-next.2", + "version": "0.3.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bazaar/CHANGELOG.md b/plugins/bazaar/CHANGELOG.md index df27712931..5e048efb1b 100644 --- a/plugins/bazaar/CHANGELOG.md +++ b/plugins/bazaar/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-bazaar +## 0.2.21 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + ## 0.2.21-next.2 ### Patch Changes diff --git a/plugins/bazaar/package.json b/plugins/bazaar/package.json index d00b018041..058ead5ca3 100644 --- a/plugins/bazaar/package.json +++ b/plugins/bazaar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar", - "version": "0.2.21-next.2", + "version": "0.2.21", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bitrise/CHANGELOG.md b/plugins/bitrise/CHANGELOG.md index bc60cb7323..efc87f6839 100644 --- a/plugins/bitrise/CHANGELOG.md +++ b/plugins/bitrise/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-bitrise +## 0.1.56 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + ## 0.1.56-next.2 ### Patch Changes diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json index dad18f8c8d..2dd804f746 100644 --- a/plugins/bitrise/package.json +++ b/plugins/bitrise/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-bitrise", "description": "A Backstage plugin that integrates towards Bitrise", - "version": "0.1.56-next.2", + "version": "0.1.56", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-aws/CHANGELOG.md b/plugins/catalog-backend-module-aws/CHANGELOG.md index 4b74bd929e..ff0c82bcc4 100644 --- a/plugins/catalog-backend-module-aws/CHANGELOG.md +++ b/plugins/catalog-backend-module-aws/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-catalog-backend-module-aws +## 0.3.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- 22e88d0: Added status and e-mail as labels to the AWS Account Resource +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-kubernetes-common@0.7.3 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/integration-aws-node@0.1.8 + - @backstage/plugin-catalog-common@1.0.20 + ## 0.3.3-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-aws/package.json b/plugins/catalog-backend-module-aws/package.json index b134e0ac63..af507e3c68 100644 --- a/plugins/catalog-backend-module-aws/package.json +++ b/plugins/catalog-backend-module-aws/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-aws", "description": "A Backstage catalog backend module that helps integrate towards AWS", - "version": "0.3.3-next.2", + "version": "0.3.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-azure/CHANGELOG.md b/plugins/catalog-backend-module-azure/CHANGELOG.md index 41a3530478..e33d32aa36 100644 --- a/plugins/catalog-backend-module-azure/CHANGELOG.md +++ b/plugins/catalog-backend-module-azure/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-azure +## 0.1.28 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0 + - @backstage/plugin-catalog-common@1.0.20 + ## 0.1.28-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index 7729541f81..05d2587746 100644 --- a/plugins/catalog-backend-module-azure/package.json +++ b/plugins/catalog-backend-module-azure/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-azure", "description": "A Backstage catalog backend module that helps integrate towards Azure", - "version": "0.1.28-next.2", + "version": "0.1.28", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md b/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md index f85f00add2..28d4c10240 100644 --- a/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-backend-module-backstage-openapi +## 0.1.2 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-openapi-utils@0.1.2 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.1.2-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-backstage-openapi/package.json b/plugins/catalog-backend-module-backstage-openapi/package.json index 728ff04920..ff331aeca5 100644 --- a/plugins/catalog-backend-module-backstage-openapi/package.json +++ b/plugins/catalog-backend-module-backstage-openapi/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-backstage-openapi", - "version": "0.1.2-next.2", + "version": "0.1.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md index 7e28d5e4d8..0fb20563d0 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-backend-module-bitbucket-cloud +## 0.1.24 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.15 + - @backstage/plugin-catalog-common@1.0.20 + - @backstage/plugin-events-node@0.2.18 + ## 0.1.24-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-cloud/package.json b/plugins/catalog-backend-module-bitbucket-cloud/package.json index ba3b165d31..e1352c6363 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/package.json +++ b/plugins/catalog-backend-module-bitbucket-cloud/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-cloud", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket Cloud", - "version": "0.1.24-next.2", + "version": "0.1.24", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md index 3111f2cef3..d3abaf1608 100644 --- a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-bitbucket-server +## 0.1.22 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + ## 0.1.22-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-server/package.json b/plugins/catalog-backend-module-bitbucket-server/package.json index 4e75fd71a7..00f8c6572f 100644 --- a/plugins/catalog-backend-module-bitbucket-server/package.json +++ b/plugins/catalog-backend-module-bitbucket-server/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-server", - "version": "0.1.22-next.2", + "version": "0.1.22", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md index 37ea4f7179..b39778b2fb 100644 --- a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-catalog-backend-module-bitbucket +## 0.2.24 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.15 + ## 0.2.24-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket/package.json b/plugins/catalog-backend-module-bitbucket/package.json index 2241bcfeb0..2625835a5b 100644 --- a/plugins/catalog-backend-module-bitbucket/package.json +++ b/plugins/catalog-backend-module-bitbucket/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket", - "version": "0.2.24-next.2", + "version": "0.2.24", "deprecated": true, "main": "src/index.ts", "types": "src/index.ts", diff --git a/plugins/catalog-backend-module-gcp/CHANGELOG.md b/plugins/catalog-backend-module-gcp/CHANGELOG.md index 737676e11d..aef3c0c14a 100644 --- a/plugins/catalog-backend-module-gcp/CHANGELOG.md +++ b/plugins/catalog-backend-module-gcp/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-gcp +## 0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-kubernetes-common@0.7.3 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + ## 0.1.9-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-gcp/package.json b/plugins/catalog-backend-module-gcp/package.json index 4d03df555e..5515feeb5b 100644 --- a/plugins/catalog-backend-module-gcp/package.json +++ b/plugins/catalog-backend-module-gcp/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-gcp", "description": "A Backstage catalog backend module that helps integrate towards GCP", - "version": "0.1.9-next.2", + "version": "0.1.9", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-gerrit/CHANGELOG.md b/plugins/catalog-backend-module-gerrit/CHANGELOG.md index ae9f0ac4e5..f43a1a7550 100644 --- a/plugins/catalog-backend-module-gerrit/CHANGELOG.md +++ b/plugins/catalog-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-gerrit +## 0.1.25 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + ## 0.1.25-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index 41786609c5..95f90287c3 100644 --- a/plugins/catalog-backend-module-gerrit/package.json +++ b/plugins/catalog-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gerrit", - "version": "0.1.25-next.2", + "version": "0.1.25", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-github-org/CHANGELOG.md b/plugins/catalog-backend-module-github-org/CHANGELOG.md index 18ef030f1e..2dac3fa910 100644 --- a/plugins/catalog-backend-module-github-org/CHANGELOG.md +++ b/plugins/catalog-backend-module-github-org/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-catalog-backend-module-github-org +## 0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-catalog-backend-module-github@0.4.7 + - @backstage/config@1.1.1 + ## 0.1.3-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-github-org/package.json b/plugins/catalog-backend-module-github-org/package.json index e817e33ffe..bd7e23f90d 100644 --- a/plugins/catalog-backend-module-github-org/package.json +++ b/plugins/catalog-backend-module-github-org/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-github-org", "description": "The github-org backend module for the catalog plugin.", - "version": "0.1.3-next.2", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-github/CHANGELOG.md b/plugins/catalog-backend-module-github/CHANGELOG.md index 88840caf17..6ea0c50666 100644 --- a/plugins/catalog-backend-module-github/CHANGELOG.md +++ b/plugins/catalog-backend-module-github/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-backend-module-github +## 0.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-catalog-backend@1.16.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0 + - @backstage/plugin-catalog-common@1.0.20 + - @backstage/plugin-events-node@0.2.18 + ## 0.4.7-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index fbca514b3e..9231a0cd69 100644 --- a/plugins/catalog-backend-module-github/package.json +++ b/plugins/catalog-backend-module-github/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-github", "description": "A Backstage catalog backend module that helps integrate towards GitHub", - "version": "0.4.7-next.2", + "version": "0.4.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-gitlab/CHANGELOG.md b/plugins/catalog-backend-module-gitlab/CHANGELOG.md index eb0177d7b5..138796de12 100644 --- a/plugins/catalog-backend-module-gitlab/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-gitlab +## 0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0 + ## 0.3.6-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json index cf54123207..4092a1dab2 100644 --- a/plugins/catalog-backend-module-gitlab/package.json +++ b/plugins/catalog-backend-module-gitlab/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab", "description": "A Backstage catalog backend module that helps integrate towards GitLab", - "version": "0.3.6-next.2", + "version": "0.3.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md index d66c32a438..24fd6a0b30 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md +++ b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-backend-module-incremental-ingestion +## 0.4.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-catalog-backend@1.16.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-events-node@0.2.18 + ## 0.4.13-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-incremental-ingestion/package.json b/plugins/catalog-backend-module-incremental-ingestion/package.json index 95d4b3563a..41c0abd811 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/package.json +++ b/plugins/catalog-backend-module-incremental-ingestion/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-incremental-ingestion", "description": "An entity provider for streaming large asset sources into the catalog", - "version": "0.4.13-next.2", + "version": "0.4.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-ldap/CHANGELOG.md b/plugins/catalog-backend-module-ldap/CHANGELOG.md index e862e66a3b..5e01cf2f97 100644 --- a/plugins/catalog-backend-module-ldap/CHANGELOG.md +++ b/plugins/catalog-backend-module-ldap/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-ldap +## 0.5.24 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.20 + ## 0.5.24-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json index c82c45545d..6a16e89ff1 100644 --- a/plugins/catalog-backend-module-ldap/package.json +++ b/plugins/catalog-backend-module-ldap/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-ldap", "description": "A Backstage catalog backend module that helps integrate towards LDAP", - "version": "0.5.24-next.2", + "version": "0.5.24", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-msgraph/CHANGELOG.md b/plugins/catalog-backend-module-msgraph/CHANGELOG.md index dbb12e9ecc..8ea92b99b9 100644 --- a/plugins/catalog-backend-module-msgraph/CHANGELOG.md +++ b/plugins/catalog-backend-module-msgraph/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-msgraph +## 0.5.16 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/plugin-catalog-common@1.0.20 + ## 0.5.16-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index 779550f849..1187c93262 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-msgraph", "description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph", - "version": "0.5.16-next.2", + "version": "0.5.16", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-openapi/CHANGELOG.md b/plugins/catalog-backend-module-openapi/CHANGELOG.md index cb12054932..ff1f865a28 100644 --- a/plugins/catalog-backend-module-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-openapi/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-catalog-backend-module-openapi +## 0.1.26 + +### Patch Changes + +- 4ebf99b: Add support for the new backend system. + + A new backend module for the catalog backend + was added and exported as `default`. + + You can use it with the new backend system like + + ```ts title="packages/backend/src/index.ts" + backend.add(import('@backstage/plugin-catalog-backend-module-openapi')); + ``` + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-catalog-backend@1.16.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/integration@1.8.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.20 + ## 0.1.26-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-openapi/package.json b/plugins/catalog-backend-module-openapi/package.json index b021ae11e2..1b3a2e46a0 100644 --- a/plugins/catalog-backend-module-openapi/package.json +++ b/plugins/catalog-backend-module-openapi/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-openapi", "description": "A Backstage catalog backend module that helps with OpenAPI specifications", - "version": "0.1.26-next.2", + "version": "0.1.26", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md index 63c288768e..dbc84f46f7 100644 --- a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md +++ b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-puppetdb +## 0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.1.14-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-puppetdb/package.json b/plugins/catalog-backend-module-puppetdb/package.json index 41cc2a0cc1..d9bdb74b16 100644 --- a/plugins/catalog-backend-module-puppetdb/package.json +++ b/plugins/catalog-backend-module-puppetdb/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-puppetdb", "description": "A Backstage catalog backend module that helps integrate towards PuppetDB", - "version": "0.1.14-next.2", + "version": "0.1.14", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md b/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md index 93fbd3ee37..4901341e46 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md +++ b/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-catalog-backend-module-scaffolder-entity-model +## 0.1.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.4.5 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-catalog-common@1.0.20 + ## 0.1.6-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-scaffolder-entity-model/package.json b/plugins/catalog-backend-module-scaffolder-entity-model/package.json index 7be1fb1ffc..3dc896f7c7 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/package.json +++ b/plugins/catalog-backend-module-scaffolder-entity-model/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-scaffolder-entity-model", "description": "Adds support for the scaffolder specific entity model (e.g. the Template kind) to the catalog backend plugin.", - "version": "0.1.6-next.2", + "version": "0.1.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-unprocessed/CHANGELOG.md b/plugins/catalog-backend-module-unprocessed/CHANGELOG.md index 9c90b67b9f..947fdb5914 100644 --- a/plugins/catalog-backend-module-unprocessed/CHANGELOG.md +++ b/plugins/catalog-backend-module-unprocessed/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-catalog-backend-module-unprocessed +## 0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + ## 0.3.6-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-unprocessed/package.json b/plugins/catalog-backend-module-unprocessed/package.json index 92b5755d07..4412c4ef7c 100644 --- a/plugins/catalog-backend-module-unprocessed/package.json +++ b/plugins/catalog-backend-module-unprocessed/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-unprocessed", "description": "Backstage Catalog module to view unprocessed entities", - "version": "0.3.6-next.2", + "version": "0.3.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index 45b11bba63..3330de7fd3 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-catalog-backend +## 1.16.1 + +### Patch Changes + +- c3249d6: Parse the URL using a different method rather than `git-url-parse` to support wildcards for URLs which are not VCS providers +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-search-backend-module-catalog@0.1.13 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-openapi-utils@0.1.2 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.20 + - @backstage/plugin-events-node@0.2.18 + ## 1.16.1-next.2 ### Patch Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index ad0ddcf767..42f40cccd2 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend", "description": "The Backstage backend plugin that provides the Backstage catalog", - "version": "1.16.1-next.2", + "version": "1.16.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-common/CHANGELOG.md b/plugins/catalog-common/CHANGELOG.md index 92415ecff9..9f2b511676 100644 --- a/plugins/catalog-common/CHANGELOG.md +++ b/plugins/catalog-common/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-catalog-common +## 1.0.20 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.12 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-search-common@1.2.10 + ## 1.0.19 ### Patch Changes diff --git a/plugins/catalog-common/package.json b/plugins/catalog-common/package.json index 3c4bc34997..9642746fd7 100644 --- a/plugins/catalog-common/package.json +++ b/plugins/catalog-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-common", "description": "Common functionalities for the catalog plugin", - "version": "1.0.19", + "version": "1.0.20", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md index 1523fa602b..235e5c25fb 100644 --- a/plugins/catalog-graph/CHANGELOG.md +++ b/plugins/catalog-graph/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-graph +## 0.3.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/types@1.1.1 + ## 0.3.3-next.2 ### Patch Changes diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index c19131325b..a38f1a4480 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-graph", - "version": "0.3.3-next.2", + "version": "0.3.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index 7b60edc160..ea9d4cb61e 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-catalog-import +## 0.10.5 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/plugin-catalog-common@1.0.20 + ## 0.10.5-next.2 ### Patch Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index 7f48d59f91..865f60a842 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-import", "description": "A Backstage plugin the helps you import entities into your catalog", - "version": "0.10.5-next.2", + "version": "0.10.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-node/CHANGELOG.md b/plugins/catalog-node/CHANGELOG.md index 8da663cfa0..cda3c22b0f 100644 --- a/plugins/catalog-node/CHANGELOG.md +++ b/plugins/catalog-node/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-node +## 1.6.1 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.20 + ## 1.6.1-next.2 ### Patch Changes diff --git a/plugins/catalog-node/package.json b/plugins/catalog-node/package.json index e09509d2b5..013577d0b9 100644 --- a/plugins/catalog-node/package.json +++ b/plugins/catalog-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-node", "description": "The plugin-catalog-node module for @backstage/plugin-catalog-backend", - "version": "1.6.1-next.2", + "version": "1.6.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index 62ce5b8337..9bd729a8e6 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-catalog-react +## 1.9.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-common@1.0.20 + ## 1.9.3-next.2 ### Patch Changes diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index 9ad06a3c98..93486c64db 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-react", "description": "A frontend library that helps other Backstage plugins interact with the catalog", - "version": "1.9.3-next.2", + "version": "1.9.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-unprocessed-entities/CHANGELOG.md b/plugins/catalog-unprocessed-entities/CHANGELOG.md index 7a45d8de79..9a2be34228 100644 --- a/plugins/catalog-unprocessed-entities/CHANGELOG.md +++ b/plugins/catalog-unprocessed-entities/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-catalog-unprocessed-entities +## 0.1.7 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + ## 0.1.7-next.1 ### Patch Changes diff --git a/plugins/catalog-unprocessed-entities/package.json b/plugins/catalog-unprocessed-entities/package.json index 0312b589dc..d3b037788a 100644 --- a/plugins/catalog-unprocessed-entities/package.json +++ b/plugins/catalog-unprocessed-entities/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-unprocessed-entities", - "version": "0.1.7-next.1", + "version": "0.1.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index 3f3996bc30..a34341d585 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-catalog +## 1.16.1 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/plugin-scaffolder-common@1.4.5 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-search-react@1.7.5 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.20 + - @backstage/plugin-search-common@1.2.10 + ## 1.16.1-next.2 ### Patch Changes diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index fc097efc4f..4654a831f9 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog", "description": "The Backstage plugin for browsing the Backstage catalog", - "version": "1.16.1-next.2", + "version": "1.16.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cicd-statistics-module-gitlab/CHANGELOG.md b/plugins/cicd-statistics-module-gitlab/CHANGELOG.md index 22482f3fe7..79d8cda7bf 100644 --- a/plugins/cicd-statistics-module-gitlab/CHANGELOG.md +++ b/plugins/cicd-statistics-module-gitlab/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-cicd-statistics-module-gitlab +## 0.1.25 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-cicd-statistics@0.1.31 + ## 0.1.25-next.2 ### Patch Changes diff --git a/plugins/cicd-statistics-module-gitlab/package.json b/plugins/cicd-statistics-module-gitlab/package.json index 285dfb76a0..f84457a781 100644 --- a/plugins/cicd-statistics-module-gitlab/package.json +++ b/plugins/cicd-statistics-module-gitlab/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cicd-statistics-module-gitlab", "description": "CI/CD Statistics plugin module; Gitlab CICD", - "version": "0.1.25-next.2", + "version": "0.1.25", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cicd-statistics/CHANGELOG.md b/plugins/cicd-statistics/CHANGELOG.md index c5d6328c08..e80e9d5d68 100644 --- a/plugins/cicd-statistics/CHANGELOG.md +++ b/plugins/cicd-statistics/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-cicd-statistics +## 0.1.31 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + ## 0.1.31-next.2 ### Patch Changes diff --git a/plugins/cicd-statistics/package.json b/plugins/cicd-statistics/package.json index 6e52536878..aaa271baa7 100644 --- a/plugins/cicd-statistics/package.json +++ b/plugins/cicd-statistics/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cicd-statistics", "description": "A frontend plugin visualizing CI/CD pipeline statistics (build time)", - "version": "0.1.31-next.2", + "version": "0.1.31", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/circleci/CHANGELOG.md b/plugins/circleci/CHANGELOG.md index 6e1310932c..baabcaa66f 100644 --- a/plugins/circleci/CHANGELOG.md +++ b/plugins/circleci/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-circleci +## 0.3.29 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + ## 0.3.29-next.2 ### Patch Changes diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index 92daf3e741..174dbda8d1 100644 --- a/plugins/circleci/package.json +++ b/plugins/circleci/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-circleci", "description": "A Backstage plugin that integrates towards Circle CI", - "version": "0.3.29-next.2", + "version": "0.3.29", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cloudbuild/CHANGELOG.md b/plugins/cloudbuild/CHANGELOG.md index 7e21005cf8..84cd321643 100644 --- a/plugins/cloudbuild/CHANGELOG.md +++ b/plugins/cloudbuild/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-cloudbuild +## 0.3.29 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + ## 0.3.29-next.2 ### Patch Changes diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index 16ede212f9..8d7c9a3282 100644 --- a/plugins/cloudbuild/package.json +++ b/plugins/cloudbuild/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cloudbuild", "description": "A Backstage plugin that integrates towards Google Cloud Build", - "version": "0.3.29-next.2", + "version": "0.3.29", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/code-climate/CHANGELOG.md b/plugins/code-climate/CHANGELOG.md index c845623759..551e4fb262 100644 --- a/plugins/code-climate/CHANGELOG.md +++ b/plugins/code-climate/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-code-climate +## 0.1.29 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + ## 0.1.29-next.2 ### Patch Changes diff --git a/plugins/code-climate/package.json b/plugins/code-climate/package.json index 02ef329e2f..1c9971f476 100644 --- a/plugins/code-climate/package.json +++ b/plugins/code-climate/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-code-climate", - "version": "0.1.29-next.2", + "version": "0.1.29", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/code-coverage-backend/CHANGELOG.md b/plugins/code-coverage-backend/CHANGELOG.md index 8244c65125..e55df807d1 100644 --- a/plugins/code-coverage-backend/CHANGELOG.md +++ b/plugins/code-coverage-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-code-coverage-backend +## 0.2.23 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + ## 0.2.23-next.2 ### Patch Changes diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json index 3c214effce..4fa0a8e6ec 100644 --- a/plugins/code-coverage-backend/package.json +++ b/plugins/code-coverage-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-code-coverage-backend", "description": "A Backstage backend plugin that helps you keep track of your code coverage", - "version": "0.2.23-next.2", + "version": "0.2.23", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/code-coverage/CHANGELOG.md b/plugins/code-coverage/CHANGELOG.md index 36d0cdf180..5155660c36 100644 --- a/plugins/code-coverage/CHANGELOG.md +++ b/plugins/code-coverage/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-code-coverage +## 0.2.22 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + ## 0.2.22-next.2 ### Patch Changes diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index 1dd4adda0c..c37036f1ff 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-code-coverage", "description": "A Backstage plugin that helps you keep track of your code coverage", - "version": "0.2.22-next.2", + "version": "0.2.22", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/codescene/CHANGELOG.md b/plugins/codescene/CHANGELOG.md index 16665e7bcf..df9ed3199f 100644 --- a/plugins/codescene/CHANGELOG.md +++ b/plugins/codescene/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-codescene +## 0.1.21 + +### Patch Changes + +- d5eda61: Updated Readme document in codescene plugin +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.1.21-next.1 ### Patch Changes diff --git a/plugins/codescene/package.json b/plugins/codescene/package.json index 2727a055a8..f0dfd20394 100644 --- a/plugins/codescene/package.json +++ b/plugins/codescene/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-codescene", - "version": "0.1.21-next.1", + "version": "0.1.21", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/config-schema/CHANGELOG.md b/plugins/config-schema/CHANGELOG.md index 3f5050932e..0ed7d3afd5 100644 --- a/plugins/config-schema/CHANGELOG.md +++ b/plugins/config-schema/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-config-schema +## 0.1.49 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.1.49-next.1 ### Patch Changes diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index 5f9b696f14..15860d4e89 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-config-schema", "description": "A Backstage plugin that lets you browse the configuration schema of your app", - "version": "0.1.49-next.1", + "version": "0.1.49", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cost-insights/CHANGELOG.md b/plugins/cost-insights/CHANGELOG.md index 3d62339bc8..cd0c31e2f1 100644 --- a/plugins/cost-insights/CHANGELOG.md +++ b/plugins/cost-insights/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-cost-insights +## 0.12.18 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/theme@0.5.0 + - @backstage/plugin-cost-insights-common@0.1.2 + ## 0.12.18-next.2 ### Patch Changes diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index bf8f5ff02a..2db994d466 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cost-insights", "description": "A Backstage plugin that helps you keep track of your cloud spend", - "version": "0.12.18-next.2", + "version": "0.12.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/devtools-backend/CHANGELOG.md b/plugins/devtools-backend/CHANGELOG.md index 29ed53fae6..62e91cc50c 100644 --- a/plugins/devtools-backend/CHANGELOG.md +++ b/plugins/devtools-backend/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-devtools-backend +## 0.2.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/config-loader@1.6.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.8 + ## 0.2.6-next.2 ### Patch Changes diff --git a/plugins/devtools-backend/package.json b/plugins/devtools-backend/package.json index d81b4538cf..4d56c3e9dd 100644 --- a/plugins/devtools-backend/package.json +++ b/plugins/devtools-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools-backend", - "version": "0.2.6-next.2", + "version": "0.2.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/devtools-common/CHANGELOG.md b/plugins/devtools-common/CHANGELOG.md index 9ede428d75..3bbc48a585 100644 --- a/plugins/devtools-common/CHANGELOG.md +++ b/plugins/devtools-common/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-devtools-common +## 0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.12 + - @backstage/types@1.1.1 + ## 0.1.7 ### Patch Changes diff --git a/plugins/devtools-common/package.json b/plugins/devtools-common/package.json index 24884efed2..a488e997a1 100644 --- a/plugins/devtools-common/package.json +++ b/plugins/devtools-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-devtools-common", "description": "Common functionalities for the devtools plugin", - "version": "0.1.7", + "version": "0.1.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/devtools/CHANGELOG.md b/plugins/devtools/CHANGELOG.md index 8b7a4376f3..4237bd149a 100644 --- a/plugins/devtools/CHANGELOG.md +++ b/plugins/devtools/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-devtools +## 0.1.8 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/errors@1.2.3 + - @backstage/plugin-devtools-common@0.1.8 + ## 0.1.8-next.1 ### Patch Changes diff --git a/plugins/devtools/package.json b/plugins/devtools/package.json index 34ce5d7091..ece8fe89e3 100644 --- a/plugins/devtools/package.json +++ b/plugins/devtools/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools", - "version": "0.1.8-next.1", + "version": "0.1.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/dynatrace/CHANGELOG.md b/plugins/dynatrace/CHANGELOG.md index 7e2ad6ab27..1cff141762 100644 --- a/plugins/dynatrace/CHANGELOG.md +++ b/plugins/dynatrace/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-dynatrace +## 8.0.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + ## 8.0.3-next.2 ### Patch Changes diff --git a/plugins/dynatrace/package.json b/plugins/dynatrace/package.json index a14915cebb..c82b8a4d5b 100644 --- a/plugins/dynatrace/package.json +++ b/plugins/dynatrace/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-dynatrace", - "version": "8.0.3-next.2", + "version": "8.0.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/entity-feedback-backend/CHANGELOG.md b/plugins/entity-feedback-backend/CHANGELOG.md index ccaeaf63eb..e9eec4b8f2 100644 --- a/plugins/entity-feedback-backend/CHANGELOG.md +++ b/plugins/entity-feedback-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-entity-feedback-backend +## 0.2.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/plugin-entity-feedback-common@0.1.3 + ## 0.2.6-next.2 ### Patch Changes diff --git a/plugins/entity-feedback-backend/package.json b/plugins/entity-feedback-backend/package.json index 54cf74aa55..8e5deafdf1 100644 --- a/plugins/entity-feedback-backend/package.json +++ b/plugins/entity-feedback-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-entity-feedback-backend", - "version": "0.2.6-next.2", + "version": "0.2.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/entity-feedback/CHANGELOG.md b/plugins/entity-feedback/CHANGELOG.md index 2d9bb0b57a..5cc2ae9468 100644 --- a/plugins/entity-feedback/CHANGELOG.md +++ b/plugins/entity-feedback/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-entity-feedback +## 0.2.12 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/plugin-entity-feedback-common@0.1.3 + ## 0.2.12-next.2 ### Patch Changes diff --git a/plugins/entity-feedback/package.json b/plugins/entity-feedback/package.json index 8d2b01dcfb..226c76c106 100644 --- a/plugins/entity-feedback/package.json +++ b/plugins/entity-feedback/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-entity-feedback", - "version": "0.2.12-next.2", + "version": "0.2.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/entity-validation/CHANGELOG.md b/plugins/entity-validation/CHANGELOG.md index 183cba125f..f1070960c8 100644 --- a/plugins/entity-validation/CHANGELOG.md +++ b/plugins/entity-validation/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-entity-validation +## 0.1.14 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.20 + ## 0.1.14-next.2 ### Patch Changes diff --git a/plugins/entity-validation/package.json b/plugins/entity-validation/package.json index bd3f6a1e38..316c9ec97f 100644 --- a/plugins/entity-validation/package.json +++ b/plugins/entity-validation/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-entity-validation", - "version": "0.1.14-next.2", + "version": "0.1.14", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-aws-sqs/CHANGELOG.md b/plugins/events-backend-module-aws-sqs/CHANGELOG.md index fe483744a7..b77a2912ca 100644 --- a/plugins/events-backend-module-aws-sqs/CHANGELOG.md +++ b/plugins/events-backend-module-aws-sqs/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-events-backend-module-aws-sqs +## 0.2.12 + +### Patch Changes + +- 7b8e551: Fix errors when deleting SQS messages: + + - If zero messages were received, skip deletion to avoid `EmptyBatchRequest` error from the SQS client. + - If zero failures were returned from the SQS client during deletion, skip error logging. + +- d5ddc4e: Add documentation on how to install the plugins with the new backend system. +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-tasks@0.5.14 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.2.18 + ## 0.2.12-next.2 ### Patch Changes diff --git a/plugins/events-backend-module-aws-sqs/package.json b/plugins/events-backend-module-aws-sqs/package.json index 041647f503..6e0c986554 100644 --- a/plugins/events-backend-module-aws-sqs/package.json +++ b/plugins/events-backend-module-aws-sqs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-aws-sqs", - "version": "0.2.12-next.2", + "version": "0.2.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-azure/CHANGELOG.md b/plugins/events-backend-module-azure/CHANGELOG.md index 9f590d48eb..233d9f6eb5 100644 --- a/plugins/events-backend-module-azure/CHANGELOG.md +++ b/plugins/events-backend-module-azure/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-events-backend-module-azure +## 0.1.19 + +### Patch Changes + +- af76a95: Add default exports for the new backend system and documentation. +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-events-node@0.2.18 + ## 0.1.19-next.2 ### Patch Changes diff --git a/plugins/events-backend-module-azure/package.json b/plugins/events-backend-module-azure/package.json index 56ffec5737..2530e2dfd9 100644 --- a/plugins/events-backend-module-azure/package.json +++ b/plugins/events-backend-module-azure/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-azure", - "version": "0.1.19-next.2", + "version": "0.1.19", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md index 584963ce76..ae4db7e0fa 100644 --- a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-events-backend-module-bitbucket-cloud +## 0.1.19 + +### Patch Changes + +- af76a95: Add default exports for the new backend system and documentation. +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-events-node@0.2.18 + ## 0.1.19-next.2 ### Patch Changes diff --git a/plugins/events-backend-module-bitbucket-cloud/package.json b/plugins/events-backend-module-bitbucket-cloud/package.json index db5343536b..5dd1e3e00c 100644 --- a/plugins/events-backend-module-bitbucket-cloud/package.json +++ b/plugins/events-backend-module-bitbucket-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-bitbucket-cloud", - "version": "0.1.19-next.2", + "version": "0.1.19", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-gerrit/CHANGELOG.md b/plugins/events-backend-module-gerrit/CHANGELOG.md index 8770dcf0a2..6af1070a1f 100644 --- a/plugins/events-backend-module-gerrit/CHANGELOG.md +++ b/plugins/events-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-events-backend-module-gerrit +## 0.1.19 + +### Patch Changes + +- af76a95: Add default exports for the new backend system and documentation. +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-events-node@0.2.18 + ## 0.1.19-next.2 ### Patch Changes diff --git a/plugins/events-backend-module-gerrit/package.json b/plugins/events-backend-module-gerrit/package.json index 80d6e5b6b2..0593cd8664 100644 --- a/plugins/events-backend-module-gerrit/package.json +++ b/plugins/events-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-gerrit", - "version": "0.1.19-next.2", + "version": "0.1.19", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-github/CHANGELOG.md b/plugins/events-backend-module-github/CHANGELOG.md index 41d718d9fb..bff2a53470 100644 --- a/plugins/events-backend-module-github/CHANGELOG.md +++ b/plugins/events-backend-module-github/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-events-backend-module-github +## 0.1.19 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + - @backstage/plugin-events-node@0.2.18 + ## 0.1.19-next.2 ### Patch Changes diff --git a/plugins/events-backend-module-github/package.json b/plugins/events-backend-module-github/package.json index c43468b8bf..97bd7b7cc6 100644 --- a/plugins/events-backend-module-github/package.json +++ b/plugins/events-backend-module-github/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-github", - "version": "0.1.19-next.2", + "version": "0.1.19", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-gitlab/CHANGELOG.md b/plugins/events-backend-module-gitlab/CHANGELOG.md index 9858bfb44e..de697ee02c 100644 --- a/plugins/events-backend-module-gitlab/CHANGELOG.md +++ b/plugins/events-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-events-backend-module-gitlab +## 0.1.19 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + - @backstage/plugin-events-node@0.2.18 + ## 0.1.19-next.2 ### Patch Changes diff --git a/plugins/events-backend-module-gitlab/package.json b/plugins/events-backend-module-gitlab/package.json index cf5c9ff9d6..7eacb91a61 100644 --- a/plugins/events-backend-module-gitlab/package.json +++ b/plugins/events-backend-module-gitlab/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-gitlab", - "version": "0.1.19-next.2", + "version": "0.1.19", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-test-utils/CHANGELOG.md b/plugins/events-backend-test-utils/CHANGELOG.md index 6cf527b228..2651cbeffe 100644 --- a/plugins/events-backend-test-utils/CHANGELOG.md +++ b/plugins/events-backend-test-utils/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-events-backend-test-utils +## 0.1.19 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.18 + ## 0.1.19-next.2 ### Patch Changes diff --git a/plugins/events-backend-test-utils/package.json b/plugins/events-backend-test-utils/package.json index cb9ec93a3d..aabd16558d 100644 --- a/plugins/events-backend-test-utils/package.json +++ b/plugins/events-backend-test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-events-backend-test-utils", "description": "The plugin-events-backend-test-utils for @backstage/plugin-events-node", - "version": "0.1.19-next.2", + "version": "0.1.19", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend/CHANGELOG.md b/plugins/events-backend/CHANGELOG.md index 560ca79197..fb7607f8b1 100644 --- a/plugins/events-backend/CHANGELOG.md +++ b/plugins/events-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-events-backend +## 0.2.18 + +### Patch Changes + +- 92ea615: Update `README.md` +- d5ddc4e: Add documentation on how to install the plugins with the new backend system. +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + - @backstage/plugin-events-node@0.2.18 + ## 0.2.18-next.2 ### Patch Changes diff --git a/plugins/events-backend/package.json b/plugins/events-backend/package.json index 8c94fe5056..ec4a59f4e9 100644 --- a/plugins/events-backend/package.json +++ b/plugins/events-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend", - "version": "0.2.18-next.2", + "version": "0.2.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-node/CHANGELOG.md b/plugins/events-node/CHANGELOG.md index 095fe394e9..dd9844430c 100644 --- a/plugins/events-node/CHANGELOG.md +++ b/plugins/events-node/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-events-node +## 0.2.18 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + ## 0.2.18-next.2 ### Patch Changes diff --git a/plugins/events-node/package.json b/plugins/events-node/package.json index 76cb9f731c..d2a9e5424d 100644 --- a/plugins/events-node/package.json +++ b/plugins/events-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-events-node", "description": "The plugin-events-node module for @backstage/plugin-events-backend", - "version": "0.2.18-next.2", + "version": "0.2.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/example-todo-list-backend/CHANGELOG.md b/plugins/example-todo-list-backend/CHANGELOG.md index 587238bf93..2f4a7fb873 100644 --- a/plugins/example-todo-list-backend/CHANGELOG.md +++ b/plugins/example-todo-list-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @internal/plugin-todo-list-backend +## 1.0.21 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/errors@1.2.3 + ## 1.0.21-next.2 ### Patch Changes diff --git a/plugins/example-todo-list-backend/package.json b/plugins/example-todo-list-backend/package.json index 091caf3c68..65241fd128 100644 --- a/plugins/example-todo-list-backend/package.json +++ b/plugins/example-todo-list-backend/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list-backend", - "version": "1.0.21-next.2", + "version": "1.0.21", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/example-todo-list-common/CHANGELOG.md b/plugins/example-todo-list-common/CHANGELOG.md index bef3cf1d40..98d6bafa7f 100644 --- a/plugins/example-todo-list-common/CHANGELOG.md +++ b/plugins/example-todo-list-common/CHANGELOG.md @@ -1,5 +1,12 @@ # @internal/plugin-todo-list-common +## 1.0.17 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.12 + ## 1.0.16 ### Patch Changes diff --git a/plugins/example-todo-list-common/package.json b/plugins/example-todo-list-common/package.json index 6a3b2897eb..1d984812f9 100644 --- a/plugins/example-todo-list-common/package.json +++ b/plugins/example-todo-list-common/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list-common", - "version": "1.0.16", + "version": "1.0.17", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/example-todo-list/CHANGELOG.md b/plugins/example-todo-list/CHANGELOG.md index eae25f89bd..8dfacdd105 100644 --- a/plugins/example-todo-list/CHANGELOG.md +++ b/plugins/example-todo-list/CHANGELOG.md @@ -1,5 +1,13 @@ # @internal/plugin-todo-list +## 1.0.21 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + ## 1.0.21-next.1 ### Patch Changes diff --git a/plugins/example-todo-list/package.json b/plugins/example-todo-list/package.json index f38ba69a06..63634879df 100644 --- a/plugins/example-todo-list/package.json +++ b/plugins/example-todo-list/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list", - "version": "1.0.21-next.1", + "version": "1.0.21", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/explore-backend/CHANGELOG.md b/plugins/explore-backend/CHANGELOG.md index 0049c74da3..292a14f652 100644 --- a/plugins/explore-backend/CHANGELOG.md +++ b/plugins/explore-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-explore-backend +## 0.0.19 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-search-backend-module-explore@0.1.13 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + ## 0.0.19-next.2 ### Patch Changes diff --git a/plugins/explore-backend/package.json b/plugins/explore-backend/package.json index 7a1adfdd19..5af891fb02 100644 --- a/plugins/explore-backend/package.json +++ b/plugins/explore-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-explore-backend", - "version": "0.0.19-next.2", + "version": "0.0.19", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/explore-react/CHANGELOG.md b/plugins/explore-react/CHANGELOG.md index 87fa9eb1d7..d9668070c2 100644 --- a/plugins/explore-react/CHANGELOG.md +++ b/plugins/explore-react/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-explore-react +## 0.0.35 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-explore-common@0.0.2 + ## 0.0.35-next.1 ### Patch Changes diff --git a/plugins/explore-react/package.json b/plugins/explore-react/package.json index 4774eec397..a3128511ac 100644 --- a/plugins/explore-react/package.json +++ b/plugins/explore-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-explore-react", "description": "A frontend library for Backstage plugins that want to interact with the explore plugin", - "version": "0.0.35-next.1", + "version": "0.0.35", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/explore/CHANGELOG.md b/plugins/explore/CHANGELOG.md index bb83d2b568..b1cdac03d7 100644 --- a/plugins/explore/CHANGELOG.md +++ b/plugins/explore/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-explore +## 0.4.15 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-explore-react@0.0.35 + - @backstage/plugin-search-react@1.7.5 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.10 + ## 0.4.15-next.2 ### Patch Changes diff --git a/plugins/explore/package.json b/plugins/explore/package.json index be2d997932..500480c1ad 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-explore", "description": "A Backstage plugin for building an exploration page of your software ecosystem", - "version": "0.4.15-next.2", + "version": "0.4.15", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/firehydrant/CHANGELOG.md b/plugins/firehydrant/CHANGELOG.md index fdcd23958e..5272139970 100644 --- a/plugins/firehydrant/CHANGELOG.md +++ b/plugins/firehydrant/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-firehydrant +## 0.2.13 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + ## 0.2.13-next.2 ### Patch Changes diff --git a/plugins/firehydrant/package.json b/plugins/firehydrant/package.json index be9f9e1165..9747592e0c 100644 --- a/plugins/firehydrant/package.json +++ b/plugins/firehydrant/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-firehydrant", "description": "A Backstage plugin that integrates towards FireHydrant", - "version": "0.2.13-next.2", + "version": "0.2.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/fossa/CHANGELOG.md b/plugins/fossa/CHANGELOG.md index a369cd3122..61721a6600 100644 --- a/plugins/fossa/CHANGELOG.md +++ b/plugins/fossa/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-fossa +## 0.2.61 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + ## 0.2.61-next.2 ### Patch Changes diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index 2aa82f79dd..83af637994 100644 --- a/plugins/fossa/package.json +++ b/plugins/fossa/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-fossa", "description": "A Backstage plugin that integrates towards FOSSA", - "version": "0.2.61-next.2", + "version": "0.2.61", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gcalendar/CHANGELOG.md b/plugins/gcalendar/CHANGELOG.md index afb7239eeb..cb9865d96c 100644 --- a/plugins/gcalendar/CHANGELOG.md +++ b/plugins/gcalendar/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-gcalendar +## 0.3.22 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/errors@1.2.3 + ## 0.3.22-next.1 ### Patch Changes diff --git a/plugins/gcalendar/package.json b/plugins/gcalendar/package.json index 0e22947f8d..c8a5b0bd0a 100644 --- a/plugins/gcalendar/package.json +++ b/plugins/gcalendar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-gcalendar", - "version": "0.3.22-next.1", + "version": "0.3.22", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gcp-projects/CHANGELOG.md b/plugins/gcp-projects/CHANGELOG.md index 1fdd0d9246..bcdc653349 100644 --- a/plugins/gcp-projects/CHANGELOG.md +++ b/plugins/gcp-projects/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-gcp-projects +## 0.3.45 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + ## 0.3.45-next.1 ### Patch Changes diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json index 28f6fc0b72..571267216c 100644 --- a/plugins/gcp-projects/package.json +++ b/plugins/gcp-projects/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gcp-projects", "description": "A Backstage plugin that helps you manage projects in GCP", - "version": "0.3.45-next.1", + "version": "0.3.45", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/git-release-manager/CHANGELOG.md b/plugins/git-release-manager/CHANGELOG.md index 9d181b17ab..2ce671930b 100644 --- a/plugins/git-release-manager/CHANGELOG.md +++ b/plugins/git-release-manager/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-git-release-manager +## 0.3.41 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/integration@1.8.0 + ## 0.3.41-next.1 ### Patch Changes diff --git a/plugins/git-release-manager/package.json b/plugins/git-release-manager/package.json index 11e1b03c51..7fc2a142ab 100644 --- a/plugins/git-release-manager/package.json +++ b/plugins/git-release-manager/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-git-release-manager", "description": "A Backstage plugin that helps you manage releases in git", - "version": "0.3.41-next.1", + "version": "0.3.41", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-actions/CHANGELOG.md b/plugins/github-actions/CHANGELOG.md index 9655ee39d4..89807a9f29 100644 --- a/plugins/github-actions/CHANGELOG.md +++ b/plugins/github-actions/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-github-actions +## 0.6.10 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/integration@1.8.0 + ## 0.6.10-next.2 ### Patch Changes diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index e8d93e7caf..b675315dae 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-actions", "description": "A Backstage plugin that integrates towards GitHub Actions", - "version": "0.6.10-next.2", + "version": "0.6.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-deployments/CHANGELOG.md b/plugins/github-deployments/CHANGELOG.md index 26b7d7f041..b09bb8d5db 100644 --- a/plugins/github-deployments/CHANGELOG.md +++ b/plugins/github-deployments/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-github-deployments +## 0.1.60 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + ## 0.1.60-next.2 ### Patch Changes diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index d29e1b9a9f..1869e04595 100644 --- a/plugins/github-deployments/package.json +++ b/plugins/github-deployments/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-deployments", "description": "A Backstage plugin that integrates towards GitHub Deployments", - "version": "0.1.60-next.2", + "version": "0.1.60", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-issues/CHANGELOG.md b/plugins/github-issues/CHANGELOG.md index 193b5d240f..3d15c6b6a9 100644 --- a/plugins/github-issues/CHANGELOG.md +++ b/plugins/github-issues/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-github-issues +## 0.2.18 + +### Patch Changes + +- bf92ae3: Updated dependency `octokit` to `^3.0.0`. +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + ## 0.2.18-next.2 ### Patch Changes diff --git a/plugins/github-issues/package.json b/plugins/github-issues/package.json index 9fb11fc9b9..de3b02f53b 100644 --- a/plugins/github-issues/package.json +++ b/plugins/github-issues/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-github-issues", - "version": "0.2.18-next.2", + "version": "0.2.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-pull-requests-board/CHANGELOG.md b/plugins/github-pull-requests-board/CHANGELOG.md index e6985932f4..8fc568d310 100644 --- a/plugins/github-pull-requests-board/CHANGELOG.md +++ b/plugins/github-pull-requests-board/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-github-pull-requests-board +## 0.1.23 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/integration@1.8.0 + ## 0.1.23-next.2 ### Patch Changes diff --git a/plugins/github-pull-requests-board/package.json b/plugins/github-pull-requests-board/package.json index e2fc39e328..aa086c0848 100644 --- a/plugins/github-pull-requests-board/package.json +++ b/plugins/github-pull-requests-board/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-pull-requests-board", "description": "A Backstage plugin that allows you to see all open Pull Requests for all the repositories owned by your team", - "version": "0.1.23-next.2", + "version": "0.1.23", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gitops-profiles/CHANGELOG.md b/plugins/gitops-profiles/CHANGELOG.md index 1a3372089c..cd312c04bf 100644 --- a/plugins/gitops-profiles/CHANGELOG.md +++ b/plugins/gitops-profiles/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-gitops-profiles +## 0.3.44 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + ## 0.3.44-next.1 ### Patch Changes diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index dc999ea645..d9e509a49b 100644 --- a/plugins/gitops-profiles/package.json +++ b/plugins/gitops-profiles/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gitops-profiles", "description": "A Backstage plugin that helps you manage GitOps profiles", - "version": "0.3.44-next.1", + "version": "0.3.44", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gocd/CHANGELOG.md b/plugins/gocd/CHANGELOG.md index ebe8301a7e..884a6fc295 100644 --- a/plugins/gocd/CHANGELOG.md +++ b/plugins/gocd/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-gocd +## 0.1.35 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + ## 0.1.35-next.2 ### Patch Changes diff --git a/plugins/gocd/package.json b/plugins/gocd/package.json index f35ab50eaa..ec25c9f7e0 100644 --- a/plugins/gocd/package.json +++ b/plugins/gocd/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gocd", "description": "A Backstage plugin that integrates towards GoCD", - "version": "0.1.35-next.2", + "version": "0.1.35", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/graphiql/CHANGELOG.md b/plugins/graphiql/CHANGELOG.md index aaf0d835c5..14ce2b20fb 100644 --- a/plugins/graphiql/CHANGELOG.md +++ b/plugins/graphiql/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-graphiql +## 0.3.2 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + ## 0.3.2-next.2 ### Patch Changes diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index 5db5a189cd..254356550f 100644 --- a/plugins/graphiql/package.json +++ b/plugins/graphiql/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphiql", "description": "Backstage plugin for browsing GraphQL APIs", - "version": "0.3.2-next.2", + "version": "0.3.2", "publishConfig": { "access": "public" }, diff --git a/plugins/graphql-voyager/CHANGELOG.md b/plugins/graphql-voyager/CHANGELOG.md index ee57db87f6..f65e23b8bb 100644 --- a/plugins/graphql-voyager/CHANGELOG.md +++ b/plugins/graphql-voyager/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-graphql-voyager +## 0.1.11 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + ## 0.1.11-next.1 ### Patch Changes diff --git a/plugins/graphql-voyager/package.json b/plugins/graphql-voyager/package.json index 7e18c7a486..2a2941b033 100644 --- a/plugins/graphql-voyager/package.json +++ b/plugins/graphql-voyager/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphql-voyager", "description": "Backstage plugin for GraphQL Voyager", - "version": "0.1.11-next.1", + "version": "0.1.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/home-react/CHANGELOG.md b/plugins/home-react/CHANGELOG.md index 883f847698..3e877e8a5d 100644 --- a/plugins/home-react/CHANGELOG.md +++ b/plugins/home-react/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-home-react +## 0.1.7 + +### Patch Changes + +- 98ac5ab: Updated dependency `@rjsf/utils` to `5.15.1`. + Updated dependency `@rjsf/core` to `5.15.1`. + Updated dependency `@rjsf/material-ui` to `5.15.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.15.1`. +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + ## 0.1.7-next.2 ### Patch Changes diff --git a/plugins/home-react/package.json b/plugins/home-react/package.json index eb4609c45f..896d9e46f2 100644 --- a/plugins/home-react/package.json +++ b/plugins/home-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-home-react", "description": "A Backstage plugin that contains react components helps you build a home page", - "version": "0.1.7-next.2", + "version": "0.1.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/home/CHANGELOG.md b/plugins/home/CHANGELOG.md index fc4cb2c393..200ccd0aca 100644 --- a/plugins/home/CHANGELOG.md +++ b/plugins/home/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-home +## 0.6.1 + +### Patch Changes + +- 98ac5ab: Updated dependency `@rjsf/utils` to `5.15.1`. + Updated dependency `@rjsf/core` to `5.15.1`. + Updated dependency `@rjsf/material-ui` to `5.15.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.15.1`. +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-home-react@0.1.7 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/core-app-api@1.11.3 + - @backstage/theme@0.5.0 + ## 0.6.1-next.2 ### Patch Changes diff --git a/plugins/home/package.json b/plugins/home/package.json index 0e14c193c9..9eff9d6110 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-home", "description": "A Backstage plugin that helps you build a home page", - "version": "0.6.1-next.2", + "version": "0.6.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/ilert/CHANGELOG.md b/plugins/ilert/CHANGELOG.md index 2dace2438d..e2a55dbc2a 100644 --- a/plugins/ilert/CHANGELOG.md +++ b/plugins/ilert/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-ilert +## 0.2.18 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + ## 0.2.18-next.2 ### Patch Changes diff --git a/plugins/ilert/package.json b/plugins/ilert/package.json index 66d98511c3..7ef998cc64 100644 --- a/plugins/ilert/package.json +++ b/plugins/ilert/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-ilert", "description": "A Backstage plugin that integrates towards iLert", - "version": "0.2.18-next.2", + "version": "0.2.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/jenkins-backend/CHANGELOG.md b/plugins/jenkins-backend/CHANGELOG.md index 919d116b6b..04645c8b31 100644 --- a/plugins/jenkins-backend/CHANGELOG.md +++ b/plugins/jenkins-backend/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-jenkins-backend +## 0.3.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-jenkins-common@0.1.23 + ## 0.3.3-next.2 ### Patch Changes diff --git a/plugins/jenkins-backend/package.json b/plugins/jenkins-backend/package.json index 59a794f2be..0310169606 100644 --- a/plugins/jenkins-backend/package.json +++ b/plugins/jenkins-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-jenkins-backend", "description": "A Backstage backend plugin that integrates towards Jenkins", - "version": "0.3.3-next.2", + "version": "0.3.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/jenkins-common/CHANGELOG.md b/plugins/jenkins-common/CHANGELOG.md index 04fa14fedc..6d364dc40b 100644 --- a/plugins/jenkins-common/CHANGELOG.md +++ b/plugins/jenkins-common/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-jenkins-common +## 0.1.23 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-catalog-common@1.0.20 + ## 0.1.22 ### Patch Changes diff --git a/plugins/jenkins-common/package.json b/plugins/jenkins-common/package.json index 5c2d576e90..d61bd6cede 100644 --- a/plugins/jenkins-common/package.json +++ b/plugins/jenkins-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-jenkins-common", - "version": "0.1.22", + "version": "0.1.23", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/jenkins/CHANGELOG.md b/plugins/jenkins/CHANGELOG.md index 0e2d3c9e31..f69387fbdf 100644 --- a/plugins/jenkins/CHANGELOG.md +++ b/plugins/jenkins/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-jenkins +## 0.9.4 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/plugin-jenkins-common@0.1.23 + ## 0.9.4-next.2 ### Patch Changes diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index e3463a840e..87181ac37c 100644 --- a/plugins/jenkins/package.json +++ b/plugins/jenkins/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-jenkins", "description": "A Backstage plugin that integrates towards Jenkins", - "version": "0.9.4-next.2", + "version": "0.9.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kafka-backend/CHANGELOG.md b/plugins/kafka-backend/CHANGELOG.md index b3a33d7a1a..17a3a277e9 100644 --- a/plugins/kafka-backend/CHANGELOG.md +++ b/plugins/kafka-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-kafka-backend +## 0.3.7 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.3.7-next.2 ### Patch Changes diff --git a/plugins/kafka-backend/package.json b/plugins/kafka-backend/package.json index ec5112cfc5..5b8130fa91 100644 --- a/plugins/kafka-backend/package.json +++ b/plugins/kafka-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kafka-backend", "description": "A Backstage backend plugin that integrates towards Kafka", - "version": "0.3.7-next.2", + "version": "0.3.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kafka/CHANGELOG.md b/plugins/kafka/CHANGELOG.md index 92d2f5d429..4b6a8eda9b 100644 --- a/plugins/kafka/CHANGELOG.md +++ b/plugins/kafka/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-kafka +## 0.3.29 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + ## 0.3.29-next.2 ### Patch Changes diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index fc237fab6a..ffbeb1c761 100644 --- a/plugins/kafka/package.json +++ b/plugins/kafka/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kafka", "description": "A Backstage plugin that integrates towards Kafka", - "version": "0.3.29-next.2", + "version": "0.3.29", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes-backend/CHANGELOG.md b/plugins/kubernetes-backend/CHANGELOG.md index 0ecf5b915b..d19054eb6b 100644 --- a/plugins/kubernetes-backend/CHANGELOG.md +++ b/plugins/kubernetes-backend/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-kubernetes-backend +## 0.14.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-kubernetes-common@0.7.3 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration-aws-node@0.1.8 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-node@0.1.3 + ## 0.14.1-next.2 ### Patch Changes diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index 3e78f6c4e3..6e80fef004 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-backend", "description": "A Backstage backend plugin that integrates towards Kubernetes", - "version": "0.14.1-next.2", + "version": "0.14.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes-cluster/CHANGELOG.md b/plugins/kubernetes-cluster/CHANGELOG.md index 57453f97ec..e24b987e07 100644 --- a/plugins/kubernetes-cluster/CHANGELOG.md +++ b/plugins/kubernetes-cluster/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-kubernetes-cluster +## 0.0.5 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-kubernetes-react@0.2.1 + - @backstage/plugin-kubernetes-common@0.7.3 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + ## 0.0.5-next.2 ### Patch Changes diff --git a/plugins/kubernetes-cluster/package.json b/plugins/kubernetes-cluster/package.json index 49e5efc969..cf4d5abdea 100644 --- a/plugins/kubernetes-cluster/package.json +++ b/plugins/kubernetes-cluster/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-cluster", "description": "A Backstage plugin that shows details of Kubernetes clusters", - "version": "0.0.5-next.2", + "version": "0.0.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes-common/CHANGELOG.md b/plugins/kubernetes-common/CHANGELOG.md index 725c5f7887..c49d14f2a8 100644 --- a/plugins/kubernetes-common/CHANGELOG.md +++ b/plugins/kubernetes-common/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-kubernetes-common +## 0.7.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/plugin-permission-common@0.7.12 + - @backstage/catalog-model@1.4.3 + - @backstage/types@1.1.1 + ## 0.7.3-next.0 ### Patch Changes diff --git a/plugins/kubernetes-common/package.json b/plugins/kubernetes-common/package.json index e9f746f41a..994c8e3f88 100644 --- a/plugins/kubernetes-common/package.json +++ b/plugins/kubernetes-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-common", "description": "Common functionalities for kubernetes, to be shared between kubernetes and kubernetes-backend plugin", - "version": "0.7.3-next.0", + "version": "0.7.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes-node/CHANGELOG.md b/plugins/kubernetes-node/CHANGELOG.md index a3e83a30cc..1de200a3f3 100644 --- a/plugins/kubernetes-node/CHANGELOG.md +++ b/plugins/kubernetes-node/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-kubernetes-node +## 0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-kubernetes-common@0.7.3 + - @backstage/catalog-model@1.4.3 + - @backstage/types@1.1.1 + ## 0.1.3-next.2 ### Patch Changes diff --git a/plugins/kubernetes-node/package.json b/plugins/kubernetes-node/package.json index 73e9b661f2..317f75063d 100644 --- a/plugins/kubernetes-node/package.json +++ b/plugins/kubernetes-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-node", "description": "Node.js library for the kubernetes plugin", - "version": "0.1.3-next.2", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes-react/CHANGELOG.md b/plugins/kubernetes-react/CHANGELOG.md index 17f96217c4..12e4f42147 100644 --- a/plugins/kubernetes-react/CHANGELOG.md +++ b/plugins/kubernetes-react/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-kubernetes-react +## 0.2.1 + +### Patch Changes + +- d5d2c67: Add `authuser` search parameter to GKE cluster link formatter in k8s plugin + + Thanks to this, people with multiple simultaneously logged-in accounts in their GCP console will automatically view objects with the same email as the one signed in to the Google auth provider in Backstage. + +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-kubernetes-common@0.7.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.2.1-next.1 ### Patch Changes diff --git a/plugins/kubernetes-react/package.json b/plugins/kubernetes-react/package.json index 75a832876b..8389b4d2a9 100644 --- a/plugins/kubernetes-react/package.json +++ b/plugins/kubernetes-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-react", "description": "Web library for the kubernetes-react plugin", - "version": "0.2.1-next.1", + "version": "0.2.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index 9a147ee6a5..6f2cc8a23d 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-kubernetes +## 0.11.4 + +### Patch Changes + +- d5d2c67: Add `authuser` search parameter to GKE cluster link formatter in k8s plugin + + Thanks to this, people with multiple simultaneously logged-in accounts in their GCP console will automatically view objects with the same email as the one signed in to the Google auth provider in Backstage. + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-kubernetes-react@0.2.1 + - @backstage/plugin-kubernetes-common@0.7.3 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + ## 0.11.4-next.2 ### Patch Changes diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 9ba26362fb..858cc7a3c4 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes", "description": "A Backstage plugin that integrates towards Kubernetes", - "version": "0.11.4-next.2", + "version": "0.11.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/lighthouse-backend/CHANGELOG.md b/plugins/lighthouse-backend/CHANGELOG.md index 055c008062..c41667aab4 100644 --- a/plugins/lighthouse-backend/CHANGELOG.md +++ b/plugins/lighthouse-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-lighthouse-backend +## 0.4.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-lighthouse-common@0.1.4 + ## 0.4.1-next.2 ### Patch Changes diff --git a/plugins/lighthouse-backend/package.json b/plugins/lighthouse-backend/package.json index 101fc79c21..ac9c844456 100644 --- a/plugins/lighthouse-backend/package.json +++ b/plugins/lighthouse-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-lighthouse-backend", "description": "Backend functionalities for lighthouse", - "version": "0.4.1-next.2", + "version": "0.4.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/lighthouse/CHANGELOG.md b/plugins/lighthouse/CHANGELOG.md index 335e0190e4..92d919b657 100644 --- a/plugins/lighthouse/CHANGELOG.md +++ b/plugins/lighthouse/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-lighthouse +## 0.4.14 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-lighthouse-common@0.1.4 + ## 0.4.14-next.2 ### Patch Changes diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index 08bbf3b9b0..b71039ce2e 100644 --- a/plugins/lighthouse/package.json +++ b/plugins/lighthouse/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-lighthouse", "description": "A Backstage plugin that integrates towards Lighthouse", - "version": "0.4.14-next.2", + "version": "0.4.14", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/linguist-backend/CHANGELOG.md b/plugins/linguist-backend/CHANGELOG.md index ef82a7802f..439c15066a 100644 --- a/plugins/linguist-backend/CHANGELOG.md +++ b/plugins/linguist-backend/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-linguist-backend +## 0.5.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-linguist-common@0.1.2 + ## 0.5.6-next.2 ### Patch Changes diff --git a/plugins/linguist-backend/package.json b/plugins/linguist-backend/package.json index fef88b342a..6f137ad5f6 100644 --- a/plugins/linguist-backend/package.json +++ b/plugins/linguist-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-linguist-backend", - "version": "0.5.6-next.2", + "version": "0.5.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/linguist/CHANGELOG.md b/plugins/linguist/CHANGELOG.md index ff4532678c..7e96d237e6 100644 --- a/plugins/linguist/CHANGELOG.md +++ b/plugins/linguist/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-linguist +## 0.1.14 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- 4f42918: Added alpha support for the New Frontend System (Declarative Integration) +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/plugin-linguist-common@0.1.2 + ## 0.1.14-next.2 ### Patch Changes diff --git a/plugins/linguist/package.json b/plugins/linguist/package.json index d3dc972c24..ed38f881de 100644 --- a/plugins/linguist/package.json +++ b/plugins/linguist/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-linguist", - "version": "0.1.14-next.2", + "version": "0.1.14", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/microsoft-calendar/CHANGELOG.md b/plugins/microsoft-calendar/CHANGELOG.md index f8c0239398..86ea39fcff 100644 --- a/plugins/microsoft-calendar/CHANGELOG.md +++ b/plugins/microsoft-calendar/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-microsoft-calendar +## 0.1.11 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/errors@1.2.3 + ## 0.1.11-next.1 ### Patch Changes diff --git a/plugins/microsoft-calendar/package.json b/plugins/microsoft-calendar/package.json index 8ccff05f5b..aec094c029 100644 --- a/plugins/microsoft-calendar/package.json +++ b/plugins/microsoft-calendar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-microsoft-calendar", - "version": "0.1.11-next.1", + "version": "0.1.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/newrelic-dashboard/CHANGELOG.md b/plugins/newrelic-dashboard/CHANGELOG.md index 4a1895ccb5..8b5a6e560a 100644 --- a/plugins/newrelic-dashboard/CHANGELOG.md +++ b/plugins/newrelic-dashboard/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-newrelic-dashboard +## 0.3.4 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + ## 0.3.4-next.2 ### Patch Changes diff --git a/plugins/newrelic-dashboard/package.json b/plugins/newrelic-dashboard/package.json index ec8d4ce758..981441b479 100644 --- a/plugins/newrelic-dashboard/package.json +++ b/plugins/newrelic-dashboard/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-newrelic-dashboard", - "version": "0.3.4-next.2", + "version": "0.3.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/newrelic/CHANGELOG.md b/plugins/newrelic/CHANGELOG.md index dfe4f86fb9..8935f6c619 100644 --- a/plugins/newrelic/CHANGELOG.md +++ b/plugins/newrelic/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-newrelic +## 0.3.44 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + ## 0.3.44-next.1 ### Patch Changes diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index 28c7b48870..a67a2203d5 100644 --- a/plugins/newrelic/package.json +++ b/plugins/newrelic/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-newrelic", "description": "A Backstage plugin that integrates towards New Relic", - "version": "0.3.44-next.1", + "version": "0.3.44", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/nomad-backend/CHANGELOG.md b/plugins/nomad-backend/CHANGELOG.md index 18758dda2f..786da63c37 100644 --- a/plugins/nomad-backend/CHANGELOG.md +++ b/plugins/nomad-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-nomad-backend +## 0.1.11 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.1.11-next.2 ### Patch Changes diff --git a/plugins/nomad-backend/package.json b/plugins/nomad-backend/package.json index 79938f713b..d206b12398 100644 --- a/plugins/nomad-backend/package.json +++ b/plugins/nomad-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-nomad-backend", - "version": "0.1.11-next.2", + "version": "0.1.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/nomad/CHANGELOG.md b/plugins/nomad/CHANGELOG.md index c947027f20..2640dca7bc 100644 --- a/plugins/nomad/CHANGELOG.md +++ b/plugins/nomad/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-nomad +## 0.1.10 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + ## 0.1.10-next.2 ### Patch Changes diff --git a/plugins/nomad/package.json b/plugins/nomad/package.json index b92d593c0e..90df893a93 100644 --- a/plugins/nomad/package.json +++ b/plugins/nomad/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-nomad", - "version": "0.1.10-next.2", + "version": "0.1.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/octopus-deploy/CHANGELOG.md b/plugins/octopus-deploy/CHANGELOG.md index 51a4c3a1f7..2acdc81710 100644 --- a/plugins/octopus-deploy/CHANGELOG.md +++ b/plugins/octopus-deploy/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-octopus-deploy +## 0.2.11 + +### Patch Changes + +- 7d96ba8: added install path and fixed import on plugin-octopus-deploy +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + ## 0.2.11-next.2 ### Patch Changes diff --git a/plugins/octopus-deploy/package.json b/plugins/octopus-deploy/package.json index e232e608d9..03dd65d5e8 100644 --- a/plugins/octopus-deploy/package.json +++ b/plugins/octopus-deploy/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-octopus-deploy", - "version": "0.2.11-next.2", + "version": "0.2.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/opencost/CHANGELOG.md b/plugins/opencost/CHANGELOG.md index 01938b2d63..16d73b63d2 100644 --- a/plugins/opencost/CHANGELOG.md +++ b/plugins/opencost/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-opencost +## 0.2.4 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + ## 0.2.4-next.1 ### Patch Changes diff --git a/plugins/opencost/package.json b/plugins/opencost/package.json index e6ab5dd553..1e1b4fb674 100644 --- a/plugins/opencost/package.json +++ b/plugins/opencost/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-opencost", - "version": "0.2.4-next.1", + "version": "0.2.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/org-react/CHANGELOG.md b/plugins/org-react/CHANGELOG.md index d1e3e44c0e..b56074f2cd 100644 --- a/plugins/org-react/CHANGELOG.md +++ b/plugins/org-react/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-org-react +## 0.1.18 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + ## 0.1.18-next.2 ### Patch Changes diff --git a/plugins/org-react/package.json b/plugins/org-react/package.json index ae3fb70ea8..07ae6b82b0 100644 --- a/plugins/org-react/package.json +++ b/plugins/org-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-org-react", - "version": "0.1.18-next.2", + "version": "0.1.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/org/CHANGELOG.md b/plugins/org/CHANGELOG.md index 6c1706c46f..c36bf88714 100644 --- a/plugins/org/CHANGELOG.md +++ b/plugins/org/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-org +## 0.6.19 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-catalog-common@1.0.20 + ## 0.6.19-next.2 ### Patch Changes diff --git a/plugins/org/package.json b/plugins/org/package.json index a3494f1b8b..c4035a8498 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-org", "description": "A Backstage plugin that helps you create entity pages for your organization", - "version": "0.6.19-next.2", + "version": "0.6.19", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/pagerduty/CHANGELOG.md b/plugins/pagerduty/CHANGELOG.md index db12245793..8e48fcf210 100644 --- a/plugins/pagerduty/CHANGELOG.md +++ b/plugins/pagerduty/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-pagerduty +## 0.7.1 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-home-react@0.1.7 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + ## 0.7.1-next.2 ### Patch Changes diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json index 6b6c921da6..2526d7ca99 100644 --- a/plugins/pagerduty/package.json +++ b/plugins/pagerduty/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-pagerduty", "description": "This plugin has been deprecated, consider using [@pagerduty/backstage-plugin](https://github.com/pagerduty/backstage-plugin) instead.", - "version": "0.7.1-next.2", + "version": "0.7.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/periskop-backend/CHANGELOG.md b/plugins/periskop-backend/CHANGELOG.md index f22b5a12c7..2a94efd57e 100644 --- a/plugins/periskop-backend/CHANGELOG.md +++ b/plugins/periskop-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-periskop-backend +## 0.2.7 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + ## 0.2.7-next.2 ### Patch Changes diff --git a/plugins/periskop-backend/package.json b/plugins/periskop-backend/package.json index bb19ff995f..992e047346 100644 --- a/plugins/periskop-backend/package.json +++ b/plugins/periskop-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-periskop-backend", - "version": "0.2.7-next.2", + "version": "0.2.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/periskop/CHANGELOG.md b/plugins/periskop/CHANGELOG.md index 719ac2023d..b29b672e96 100644 --- a/plugins/periskop/CHANGELOG.md +++ b/plugins/periskop/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-periskop +## 0.1.27 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + ## 0.1.27-next.2 ### Patch Changes diff --git a/plugins/periskop/package.json b/plugins/periskop/package.json index 7a96359c86..acb7a68241 100644 --- a/plugins/periskop/package.json +++ b/plugins/periskop/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-periskop", - "version": "0.1.27-next.2", + "version": "0.1.27", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md b/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md index df80176895..e5e4d93fa3 100644 --- a/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md +++ b/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-permission-backend-module-allow-all-policy +## 0.1.6 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-auth-node@0.4.3 + ## 0.1.6-next.2 ### Patch Changes diff --git a/plugins/permission-backend-module-policy-allow-all/package.json b/plugins/permission-backend-module-policy-allow-all/package.json index 74a0ca58d2..f03a5481d3 100644 --- a/plugins/permission-backend-module-policy-allow-all/package.json +++ b/plugins/permission-backend-module-policy-allow-all/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-permission-backend-module-allow-all-policy", "description": "Allow all policy backend module for the permission plugin.", - "version": "0.1.6-next.2", + "version": "0.1.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/permission-backend/CHANGELOG.md b/plugins/permission-backend/CHANGELOG.md index fdf78f2004..43c5e85b4f 100644 --- a/plugins/permission-backend/CHANGELOG.md +++ b/plugins/permission-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-permission-backend +## 0.5.32 + +### Patch Changes + +- b1acd9b: Updated README +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.5.32-next.2 ### Patch Changes diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index e867a4a69e..c8c908eccb 100644 --- a/plugins/permission-backend/package.json +++ b/plugins/permission-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-backend", - "version": "0.5.32-next.2", + "version": "0.5.32", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/permission-common/CHANGELOG.md b/plugins/permission-common/CHANGELOG.md index 862e8db4a5..74bd6db59b 100644 --- a/plugins/permission-common/CHANGELOG.md +++ b/plugins/permission-common/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-permission-common +## 0.7.12 + +### Patch Changes + +- b1acd9b: Updated README +- Updated dependencies + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.7.11 ### Patch Changes diff --git a/plugins/permission-common/package.json b/plugins/permission-common/package.json index 2907347889..b0ca7d74bf 100644 --- a/plugins/permission-common/package.json +++ b/plugins/permission-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-permission-common", "description": "Isomorphic types and client for Backstage permissions and authorization", - "version": "0.7.11", + "version": "0.7.12", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/plugins/permission-node/CHANGELOG.md b/plugins/permission-node/CHANGELOG.md index b063aad38c..5f66d4a337 100644 --- a/plugins/permission-node/CHANGELOG.md +++ b/plugins/permission-node/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-permission-node +## 0.7.20 + +### Patch Changes + +- b1acd9b: Updated README +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.7.20-next.2 ### Patch Changes diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json index 6742a43968..5ce7217d6c 100644 --- a/plugins/permission-node/package.json +++ b/plugins/permission-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-permission-node", "description": "Common permission and authorization utilities for backend plugins", - "version": "0.7.20-next.2", + "version": "0.7.20", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/permission-react/CHANGELOG.md b/plugins/permission-react/CHANGELOG.md index 81be97c58f..a432970e3f 100644 --- a/plugins/permission-react/CHANGELOG.md +++ b/plugins/permission-react/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-permission-react +## 0.4.19 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- b1acd9b: Updated README +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/config@1.1.1 + ## 0.4.19-next.1 ### Patch Changes diff --git a/plugins/permission-react/package.json b/plugins/permission-react/package.json index 10d0a8d3ae..7949433aa9 100644 --- a/plugins/permission-react/package.json +++ b/plugins/permission-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-react", - "version": "0.4.19-next.1", + "version": "0.4.19", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/playlist-backend/CHANGELOG.md b/plugins/playlist-backend/CHANGELOG.md index 86dc5201a0..00e1c5be53 100644 --- a/plugins/playlist-backend/CHANGELOG.md +++ b/plugins/playlist-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-playlist-backend +## 0.3.13 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-playlist-common@0.1.14 + ## 0.3.13-next.2 ### Patch Changes diff --git a/plugins/playlist-backend/package.json b/plugins/playlist-backend/package.json index 3d13d3049d..8b872b6e67 100644 --- a/plugins/playlist-backend/package.json +++ b/plugins/playlist-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-playlist-backend", - "version": "0.3.13-next.2", + "version": "0.3.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/playlist-common/CHANGELOG.md b/plugins/playlist-common/CHANGELOG.md index 3fcdbfc5bc..0b65ee551f 100644 --- a/plugins/playlist-common/CHANGELOG.md +++ b/plugins/playlist-common/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-playlist-common +## 0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.12 + ## 0.1.13 ### Patch Changes diff --git a/plugins/playlist-common/package.json b/plugins/playlist-common/package.json index 7d42844986..9ab95c4c8a 100644 --- a/plugins/playlist-common/package.json +++ b/plugins/playlist-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-playlist-common", "description": "Common functionalities for the playlist plugin", - "version": "0.1.13", + "version": "0.1.14", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/playlist/CHANGELOG.md b/plugins/playlist/CHANGELOG.md index f28d63c4fb..f35b2a149a 100644 --- a/plugins/playlist/CHANGELOG.md +++ b/plugins/playlist/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-playlist +## 0.2.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-search-react@1.7.5 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.20 + - @backstage/plugin-playlist-common@0.1.14 + ## 0.2.3-next.2 ### Patch Changes diff --git a/plugins/playlist/package.json b/plugins/playlist/package.json index 622dab7346..34d2911685 100644 --- a/plugins/playlist/package.json +++ b/plugins/playlist/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-playlist", - "version": "0.2.3-next.2", + "version": "0.2.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/proxy-backend/CHANGELOG.md b/plugins/proxy-backend/CHANGELOG.md index 6bfdbbe9fc..e6649758f7 100644 --- a/plugins/proxy-backend/CHANGELOG.md +++ b/plugins/proxy-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-proxy-backend +## 0.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + ## 0.4.7-next.2 ### Patch Changes diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index 5cc5f67973..1e042a1bdc 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-proxy-backend", "description": "A Backstage backend plugin that helps you set up proxy endpoints in the backend", - "version": "0.4.7-next.2", + "version": "0.4.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/puppetdb/CHANGELOG.md b/plugins/puppetdb/CHANGELOG.md index 808df46247..9e8b991e02 100644 --- a/plugins/puppetdb/CHANGELOG.md +++ b/plugins/puppetdb/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-puppetdb +## 0.1.12 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + ## 0.1.12-next.2 ### Patch Changes diff --git a/plugins/puppetdb/package.json b/plugins/puppetdb/package.json index e1423121f8..0d1cc3d44e 100644 --- a/plugins/puppetdb/package.json +++ b/plugins/puppetdb/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-puppetdb", "description": "Backstage plugin to visualize resource information and Puppet facts from PuppetDB.", - "version": "0.1.12-next.2", + "version": "0.1.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/rollbar-backend/CHANGELOG.md b/plugins/rollbar-backend/CHANGELOG.md index c836e5f15d..4c14f2c9f9 100644 --- a/plugins/rollbar-backend/CHANGELOG.md +++ b/plugins/rollbar-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-rollbar-backend +## 0.1.54 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/config@1.1.1 + ## 0.1.54-next.2 ### Patch Changes diff --git a/plugins/rollbar-backend/package.json b/plugins/rollbar-backend/package.json index 19b6177f15..730bc3e6f3 100644 --- a/plugins/rollbar-backend/package.json +++ b/plugins/rollbar-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-rollbar-backend", "description": "A Backstage backend plugin that integrates towards Rollbar", - "version": "0.1.54-next.2", + "version": "0.1.54", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/rollbar/CHANGELOG.md b/plugins/rollbar/CHANGELOG.md index 3400094c23..494dce0fe9 100644 --- a/plugins/rollbar/CHANGELOG.md +++ b/plugins/rollbar/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-rollbar +## 0.4.29 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + ## 0.4.29-next.2 ### Patch Changes diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index 4836a9d894..a49254e366 100644 --- a/plugins/rollbar/package.json +++ b/plugins/rollbar/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-rollbar", "description": "A Backstage plugin that integrates towards Rollbar", - "version": "0.4.29-next.2", + "version": "0.4.29", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-azure/CHANGELOG.md b/plugins/scaffolder-backend-module-azure/CHANGELOG.md index 05bbe1446e..3f56f61339 100644 --- a/plugins/scaffolder-backend-module-azure/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-azure/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-azure +## 0.1.1 + +### Patch Changes + +- d076ee4: Updated dependency `azure-devops-node-api` to `^12.0.0`. +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + ## 0.1.1-next.2 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-azure/package.json b/plugins/scaffolder-backend-module-azure/package.json index f7a8e022f9..ce53811f15 100644 --- a/plugins/scaffolder-backend-module-azure/package.json +++ b/plugins/scaffolder-backend-module-azure/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-azure", "description": "The azure module for @backstage/plugin-scaffolder-backend", - "version": "0.1.1-next.2", + "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md index 1207c09620..c94898c953 100644 --- a/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket +## 0.1.1 + +### Patch Changes + +- a694f71: The Scaffolder builtin actions now contains an action for running pipelines from Bitbucket Cloud Rest API +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + ## 0.1.1-next.2 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket/package.json b/plugins/scaffolder-backend-module-bitbucket/package.json index 358f95b740..03ebab43fc 100644 --- a/plugins/scaffolder-backend-module-bitbucket/package.json +++ b/plugins/scaffolder-backend-module-bitbucket/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket", "description": "The bitbucket module for @backstage/plugin-scaffolder-backend", - "version": "0.1.1-next.2", + "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md b/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md index 648bdddb61..075d8db3b9 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend-module-confluence-to-markdown +## 0.2.10 + +### Patch Changes + +- 7acbb5a: Removed `mock-fs` dev dependency. +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + ## 0.2.10-next.2 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/package.json b/plugins/scaffolder-backend-module-confluence-to-markdown/package.json index e429e615f1..2f0bd5188c 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/package.json +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown", "description": "The confluence-to-markdown module for @backstage/plugin-scaffolder-backend", - "version": "0.2.10-next.2", + "version": "0.2.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md index 322004c912..541255a2d0 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend-module-cookiecutter +## 0.2.33 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/types@1.1.1 + ## 0.2.33-next.2 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json index dd3f1555cc..98e96a491d 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/package.json +++ b/plugins/scaffolder-backend-module-cookiecutter/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-cookiecutter", "description": "A module for the scaffolder backend that lets you template projects using cookiecutter", - "version": "0.2.33-next.2", + "version": "0.2.33", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md b/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md index aba1547066..361549275a 100644 --- a/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-scaffolder-backend-module-gerrit +## 0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + ## 0.1.1-next.2 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gerrit/package.json b/plugins/scaffolder-backend-module-gerrit/package.json index 1ac8d71c3e..59159560b5 100644 --- a/plugins/scaffolder-backend-module-gerrit/package.json +++ b/plugins/scaffolder-backend-module-gerrit/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gerrit", "description": "The gerrit module for @backstage/plugin-scaffolder-backend", - "version": "0.1.1-next.2", + "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-github/CHANGELOG.md b/plugins/scaffolder-backend-module-github/CHANGELOG.md index 9f63b4ffae..0f0ce0a045 100644 --- a/plugins/scaffolder-backend-module-github/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-github/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend-module-github +## 0.1.1 + +### Patch Changes + +- 5470300: Ensure `teamReviewers` list is unique before calling API +- bf92ae3: Updated dependency `octokit` to `^3.0.0`. +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + ## 0.1.1-next.2 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-github/package.json b/plugins/scaffolder-backend-module-github/package.json index 3231536901..b035096dad 100644 --- a/plugins/scaffolder-backend-module-github/package.json +++ b/plugins/scaffolder-backend-module-github/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-github", "description": "The github module for @backstage/plugin-scaffolder-backend", - "version": "0.1.1-next.2", + "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md index 3968582cc5..9c7d462cda 100644 --- a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-backend-module-gitlab +## 0.2.12 + +### Patch Changes + +- 604c9dd: Add Scaffolder custom action that creates GitLab issues called `gitlab:issues:create` +- 7c522c5: Add `gitlab:repo:push` scaffolder action to push files to arbitrary branch without creating a Merge Request +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + ## 0.2.12-next.2 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gitlab/package.json b/plugins/scaffolder-backend-module-gitlab/package.json index f6a15afa1a..ca7e90f8c8 100644 --- a/plugins/scaffolder-backend-module-gitlab/package.json +++ b/plugins/scaffolder-backend-module-gitlab/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gitlab", - "version": "0.2.12-next.2", + "version": "0.2.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-rails/CHANGELOG.md b/plugins/scaffolder-backend-module-rails/CHANGELOG.md index 476b7338fc..a923feec27 100644 --- a/plugins/scaffolder-backend-module-rails/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-rails/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-scaffolder-backend-module-rails +## 0.4.26 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/types@1.1.1 + ## 0.4.26-next.2 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-rails/package.json b/plugins/scaffolder-backend-module-rails/package.json index 44aa369aab..65969643c1 100644 --- a/plugins/scaffolder-backend-module-rails/package.json +++ b/plugins/scaffolder-backend-module-rails/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-rails", "description": "A module for the scaffolder backend that lets you template projects using Rails", - "version": "0.4.26-next.2", + "version": "0.4.26", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md index 39579fd6f2..5ba8dd0f05 100644 --- a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-scaffolder-backend-module-sentry +## 0.1.17 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.1.17-next.2 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-sentry/package.json b/plugins/scaffolder-backend-module-sentry/package.json index 62c38fc5ca..7828713d08 100644 --- a/plugins/scaffolder-backend-module-sentry/package.json +++ b/plugins/scaffolder-backend-module-sentry/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-sentry", - "version": "0.1.17-next.2", + "version": "0.1.17", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md index a4236219e2..1b4858dec9 100644 --- a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-scaffolder-backend-module-yeoman +## 0.2.30 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/types@1.1.1 + ## 0.2.30-next.2 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-yeoman/package.json b/plugins/scaffolder-backend-module-yeoman/package.json index c230a97881..94883084e4 100644 --- a/plugins/scaffolder-backend-module-yeoman/package.json +++ b/plugins/scaffolder-backend-module-yeoman/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-yeoman", - "version": "0.2.30-next.2", + "version": "0.2.30", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index 2b62c627c2..2fb35e3d24 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,38 @@ # @backstage/plugin-scaffolder-backend +## 1.20.0 + +### Minor Changes + +- a694f71: The Scaffolder builtin actions now contains an action for running pipelines from Bitbucket Cloud Rest API +- 7c522c5: Add `gitlab:repo:push` scaffolder action to push files to arbitrary branch without creating a Merge Request + +### Patch Changes + +- e9ab1c4: Fixed an issue where not passing a `value` to any of the action's permission conditions caused an error. +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-backend-module-github@0.1.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.2.12 + - @backstage/plugin-scaffolder-common@1.4.5 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.1.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.6 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.1 + - @backstage/plugin-scaffolder-node@0.2.10 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/types@1.1.1 + ## 1.19.3-next.2 ### Patch Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 55640ceff4..24325449b3 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend", "description": "The Backstage backend plugin that helps you create new things", - "version": "1.19.3-next.2", + "version": "1.20.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-common/CHANGELOG.md b/plugins/scaffolder-common/CHANGELOG.md index 35d5782df7..dfc6b310ed 100644 --- a/plugins/scaffolder-common/CHANGELOG.md +++ b/plugins/scaffolder-common/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-scaffolder-common +## 1.4.5 + +### Patch Changes + +- 178b8d8: Updated Template.v1beta3.schema.json, added a missing "presentation" field +- Updated dependencies + - @backstage/plugin-permission-common@0.7.12 + - @backstage/catalog-model@1.4.3 + - @backstage/types@1.1.1 + ## 1.4.4 ### Patch Changes diff --git a/plugins/scaffolder-common/package.json b/plugins/scaffolder-common/package.json index 73fa8e760e..699867fbb1 100644 --- a/plugins/scaffolder-common/package.json +++ b/plugins/scaffolder-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-common", "description": "Common functionalities for the scaffolder, to be shared between scaffolder and scaffolder-backend plugin", - "version": "1.4.4", + "version": "1.4.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-node/CHANGELOG.md b/plugins/scaffolder-node/CHANGELOG.md index 0ca6a7b633..49ea604b11 100644 --- a/plugins/scaffolder-node/CHANGELOG.md +++ b/plugins/scaffolder-node/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder-node +## 0.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-scaffolder-common@1.4.5 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/types@1.1.1 + ## 0.2.10-next.2 ### Patch Changes diff --git a/plugins/scaffolder-node/package.json b/plugins/scaffolder-node/package.json index e21f5d5214..b4c843ce65 100644 --- a/plugins/scaffolder-node/package.json +++ b/plugins/scaffolder-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-node", "description": "The plugin-scaffolder-node module for @backstage/plugin-scaffolder-backend", - "version": "0.2.10-next.2", + "version": "0.2.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-react/CHANGELOG.md b/plugins/scaffolder-react/CHANGELOG.md index ce01b049e2..89468800e8 100644 --- a/plugins/scaffolder-react/CHANGELOG.md +++ b/plugins/scaffolder-react/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-scaffolder-react +## 1.7.1 + +### Patch Changes + +- c28f281: Scaffolder form now shows a list of errors at the top of the form. +- 0b9ce2b: Fix for a step with no properties +- 98ac5ab: Updated dependency `@rjsf/utils` to `5.15.1`. + Updated dependency `@rjsf/core` to `5.15.1`. + Updated dependency `@rjsf/material-ui` to `5.15.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.15.1`. +- 4016f21: Remove some unused dependencies +- d16f85f: Show first scaffolder output text by default +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/plugin-scaffolder-common@1.4.5 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/theme@0.5.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + ## 1.7.1-next.2 ### Patch Changes diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index dee80c50c3..f8390667be 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-react", "description": "A frontend library that helps other Backstage plugins interact with the Scaffolder", - "version": "1.7.1-next.2", + "version": "1.7.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index 77aa66190f..8482d41538 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-scaffolder +## 1.17.1 + +### Patch Changes + +- 98ac5ab: Updated dependency `@rjsf/utils` to `5.15.1`. + Updated dependency `@rjsf/core` to `5.15.1`. + Updated dependency `@rjsf/material-ui` to `5.15.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.15.1`. +- 4016f21: Remove some unused dependencies +- df4bc9d: Minor internal refactor +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.7.1 + - @backstage/core-components@0.13.10 + - @backstage/plugin-scaffolder-common@1.4.5 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-permission-react@0.4.19 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.20 + ## 1.17.1-next.2 ### Patch Changes diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index d6fd2b3f85..690af2f971 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder", "description": "The Backstage plugin that helps you create new things", - "version": "1.17.1-next.2", + "version": "1.17.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-catalog/CHANGELOG.md b/plugins/search-backend-module-catalog/CHANGELOG.md index 4af9c4d5a3..23827255ac 100644 --- a/plugins/search-backend-module-catalog/CHANGELOG.md +++ b/plugins/search-backend-module-catalog/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-search-backend-module-catalog +## 0.1.13 + +### Patch Changes + +- 2e6c56b: Update wording to show that the backend system no longer is in alpha +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.20 + - @backstage/plugin-search-common@1.2.10 + ## 0.1.13-next.2 ### Patch Changes diff --git a/plugins/search-backend-module-catalog/package.json b/plugins/search-backend-module-catalog/package.json index 90c469e31d..0b70450eb3 100644 --- a/plugins/search-backend-module-catalog/package.json +++ b/plugins/search-backend-module-catalog/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-catalog", "description": "A module for the search backend that exports catalog modules", - "version": "0.1.13-next.2", + "version": "0.1.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-elasticsearch/CHANGELOG.md b/plugins/search-backend-module-elasticsearch/CHANGELOG.md index 67c32fd11b..6fd51ed2c3 100644 --- a/plugins/search-backend-module-elasticsearch/CHANGELOG.md +++ b/plugins/search-backend-module-elasticsearch/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-search-backend-module-elasticsearch +## 1.3.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/config@1.1.1 + - @backstage/integration-aws-node@0.1.8 + - @backstage/plugin-search-common@1.2.10 + ## 1.3.12-next.2 ### Patch Changes diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json index 35cb46d9ef..3a902ef255 100644 --- a/plugins/search-backend-module-elasticsearch/package.json +++ b/plugins/search-backend-module-elasticsearch/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-elasticsearch", "description": "A module for the search backend that implements search using ElasticSearch", - "version": "1.3.12-next.2", + "version": "1.3.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-explore/CHANGELOG.md b/plugins/search-backend-module-explore/CHANGELOG.md index 8af09c36b8..42465f4002 100644 --- a/plugins/search-backend-module-explore/CHANGELOG.md +++ b/plugins/search-backend-module-explore/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-search-backend-module-explore +## 0.1.13 + +### Patch Changes + +- 2e6c56b: Update wording to show that the backend system no longer is in alpha +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/config@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.10 + ## 0.1.13-next.2 ### Patch Changes diff --git a/plugins/search-backend-module-explore/package.json b/plugins/search-backend-module-explore/package.json index 348c525b90..d238ca0c68 100644 --- a/plugins/search-backend-module-explore/package.json +++ b/plugins/search-backend-module-explore/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-explore", "description": "A module for the search backend that exports explore modules", - "version": "0.1.13-next.2", + "version": "0.1.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-pg/CHANGELOG.md b/plugins/search-backend-module-pg/CHANGELOG.md index e3b518242e..b186b5f409 100644 --- a/plugins/search-backend-module-pg/CHANGELOG.md +++ b/plugins/search-backend-module-pg/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-search-backend-module-pg +## 0.5.18 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/config@1.1.1 + - @backstage/plugin-search-common@1.2.10 + ## 0.5.18-next.2 ### Patch Changes diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index ca6e7fc4f0..17db1d9e38 100644 --- a/plugins/search-backend-module-pg/package.json +++ b/plugins/search-backend-module-pg/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-pg", "description": "A module for the search backend that implements search using PostgreSQL", - "version": "0.5.18-next.2", + "version": "0.5.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md index ed8740b1c0..49ddce1d45 100644 --- a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md +++ b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-search-backend-module-stack-overflow-collator +## 0.1.2 + +### Patch Changes + +- 2e6c56b: Update wording to show that the backend system no longer is in alpha +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/config@1.1.1 + - @backstage/plugin-search-common@1.2.10 + ## 0.1.2-next.2 ### Patch Changes diff --git a/plugins/search-backend-module-stack-overflow-collator/package.json b/plugins/search-backend-module-stack-overflow-collator/package.json index 9d523451e0..2c5508384c 100644 --- a/plugins/search-backend-module-stack-overflow-collator/package.json +++ b/plugins/search-backend-module-stack-overflow-collator/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-stack-overflow-collator", "description": "A module for the search backend that exports stack overflow modules", - "version": "0.1.2-next.2", + "version": "0.1.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-techdocs/CHANGELOG.md b/plugins/search-backend-module-techdocs/CHANGELOG.md index 69654e06f6..48ca80346c 100644 --- a/plugins/search-backend-module-techdocs/CHANGELOG.md +++ b/plugins/search-backend-module-techdocs/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-search-backend-module-techdocs +## 0.1.13 + +### Patch Changes + +- 2e6c56b: Update wording to show that the backend system no longer is in alpha +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/backend-tasks@0.5.14 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/plugin-techdocs-node@1.11.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/plugin-catalog-common@1.0.20 + - @backstage/plugin-search-common@1.2.10 + ## 0.1.13-next.2 ### Patch Changes diff --git a/plugins/search-backend-module-techdocs/package.json b/plugins/search-backend-module-techdocs/package.json index 11f588842f..7db87300cf 100644 --- a/plugins/search-backend-module-techdocs/package.json +++ b/plugins/search-backend-module-techdocs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-techdocs", "description": "A module for the search backend that exports techdocs modules", - "version": "0.1.13-next.2", + "version": "0.1.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-node/CHANGELOG.md b/plugins/search-backend-node/CHANGELOG.md index 47ff37deb5..d9ada5e4ed 100644 --- a/plugins/search-backend-node/CHANGELOG.md +++ b/plugins/search-backend-node/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-search-backend-node +## 1.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/backend-tasks@0.5.14 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-search-common@1.2.10 + ## 1.2.13-next.2 ### Patch Changes diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index 8f3e736e37..b598793b88 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-node", "description": "A library for Backstage backend plugins that want to interact with the search backend plugin", - "version": "1.2.13-next.2", + "version": "1.2.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend/CHANGELOG.md b/plugins/search-backend/CHANGELOG.md index b63256ad36..334c303d03 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-search-backend +## 1.4.9 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-openapi-utils@0.1.2 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-permission-node@0.7.20 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/plugin-search-backend-node@1.2.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-search-common@1.2.10 + ## 1.4.9-next.2 ### Patch Changes diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index 4b169aeaea..bea288f6b2 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend", "description": "The Backstage backend plugin that provides your backstage app with search", - "version": "1.4.9-next.2", + "version": "1.4.9", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-common/CHANGELOG.md b/plugins/search-common/CHANGELOG.md index 3263e8305c..d14a8e37b3 100644 --- a/plugins/search-common/CHANGELOG.md +++ b/plugins/search-common/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-search-common +## 1.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.12 + - @backstage/types@1.1.1 + ## 1.2.9 ### Patch Changes diff --git a/plugins/search-common/package.json b/plugins/search-common/package.json index 7f02f8a359..e753ea764c 100644 --- a/plugins/search-common/package.json +++ b/plugins/search-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-common", "description": "Common functionalities for Search, to be shared between various search-enabled plugins", - "version": "1.2.9", + "version": "1.2.10", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/plugins/search-react/CHANGELOG.md b/plugins/search-react/CHANGELOG.md index 7a10ac97c3..08cb2bee1e 100644 --- a/plugins/search-react/CHANGELOG.md +++ b/plugins/search-react/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-search-react +## 1.7.5 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/theme@0.5.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.10 + ## 1.7.5-next.2 ### Patch Changes diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index a2e8f4a1e9..c62e5e19b9 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-react", - "version": "1.7.5-next.2", + "version": "1.7.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index a733ec9a46..5acf5eea57 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-search +## 1.4.5 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-search-react@1.7.5 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.10 + ## 1.4.5-next.2 ### Patch Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index 26f112a4fc..20ad8319e8 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search", "description": "The Backstage plugin that provides your backstage app with search", - "version": "1.4.5-next.2", + "version": "1.4.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/sentry/CHANGELOG.md b/plugins/sentry/CHANGELOG.md index 20368e375b..2ed4f848cf 100644 --- a/plugins/sentry/CHANGELOG.md +++ b/plugins/sentry/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-sentry +## 0.5.14 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + ## 0.5.14-next.2 ### Patch Changes diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index 2c1392df7a..f6bf651f69 100644 --- a/plugins/sentry/package.json +++ b/plugins/sentry/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-sentry", "description": "A Backstage plugin that integrates towards Sentry", - "version": "0.5.14-next.2", + "version": "0.5.14", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/shortcuts/CHANGELOG.md b/plugins/shortcuts/CHANGELOG.md index b8bf81789c..d819ae5921 100644 --- a/plugins/shortcuts/CHANGELOG.md +++ b/plugins/shortcuts/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-shortcuts +## 0.3.18 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/theme@0.5.0 + - @backstage/types@1.1.1 + ## 0.3.18-next.1 ### Patch Changes diff --git a/plugins/shortcuts/package.json b/plugins/shortcuts/package.json index a1abfccc3c..867e28dfa4 100644 --- a/plugins/shortcuts/package.json +++ b/plugins/shortcuts/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-shortcuts", "description": "A Backstage plugin that provides a shortcuts feature to the sidebar", - "version": "0.3.18-next.1", + "version": "0.3.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/sonarqube-backend/CHANGELOG.md b/plugins/sonarqube-backend/CHANGELOG.md index 8a1b277e4c..87231ab9af 100644 --- a/plugins/sonarqube-backend/CHANGELOG.md +++ b/plugins/sonarqube-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-sonarqube-backend +## 0.2.11 + +### Patch Changes + +- 53445cd: Updated README +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.2.11-next.2 ### Patch Changes diff --git a/plugins/sonarqube-backend/package.json b/plugins/sonarqube-backend/package.json index c151767bab..91f11aabfb 100644 --- a/plugins/sonarqube-backend/package.json +++ b/plugins/sonarqube-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-sonarqube-backend", - "version": "0.2.11-next.2", + "version": "0.2.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/sonarqube-react/CHANGELOG.md b/plugins/sonarqube-react/CHANGELOG.md index aa62e7d7bf..b011d429fd 100644 --- a/plugins/sonarqube-react/CHANGELOG.md +++ b/plugins/sonarqube-react/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-sonarqube-react +## 0.1.12 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-model@1.4.3 + ## 0.1.12-next.0 ### Patch Changes diff --git a/plugins/sonarqube-react/package.json b/plugins/sonarqube-react/package.json index 7ed2bd32f4..a2c3b8268d 100644 --- a/plugins/sonarqube-react/package.json +++ b/plugins/sonarqube-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-sonarqube-react", - "version": "0.1.12-next.0", + "version": "0.1.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/sonarqube/CHANGELOG.md b/plugins/sonarqube/CHANGELOG.md index 8d16295cc9..36734946b6 100644 --- a/plugins/sonarqube/CHANGELOG.md +++ b/plugins/sonarqube/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-sonarqube +## 0.7.11 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/plugin-sonarqube-react@0.1.12 + ## 0.7.11-next.2 ### Patch Changes diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index 473a543b0e..9d91262e01 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-sonarqube", "description": "", - "version": "0.7.11-next.2", + "version": "0.7.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/splunk-on-call/CHANGELOG.md b/plugins/splunk-on-call/CHANGELOG.md index 979e99cba2..ae6eba08f7 100644 --- a/plugins/splunk-on-call/CHANGELOG.md +++ b/plugins/splunk-on-call/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-splunk-on-call +## 0.4.18 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + ## 0.4.18-next.2 ### Patch Changes diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index cc4da14a72..ee5b1b17cd 100644 --- a/plugins/splunk-on-call/package.json +++ b/plugins/splunk-on-call/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-splunk-on-call", "description": "A Backstage plugin that integrates towards Splunk On-Call", - "version": "0.4.18-next.2", + "version": "0.4.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/stack-overflow-backend/CHANGELOG.md b/plugins/stack-overflow-backend/CHANGELOG.md index 9695482f01..ac375db564 100644 --- a/plugins/stack-overflow-backend/CHANGELOG.md +++ b/plugins/stack-overflow-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-stack-overflow-backend +## 0.2.13 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.2 + ## 0.2.13-next.2 ### Patch Changes diff --git a/plugins/stack-overflow-backend/package.json b/plugins/stack-overflow-backend/package.json index 77a1072150..9356be7bd2 100644 --- a/plugins/stack-overflow-backend/package.json +++ b/plugins/stack-overflow-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-stack-overflow-backend", "description": "Deprecated, consider using @backstage/plugin-search-backend-module-stack-overflow-collator instead", - "version": "0.2.13-next.2", + "version": "0.2.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/stack-overflow/CHANGELOG.md b/plugins/stack-overflow/CHANGELOG.md index 7bef72cc3a..f13fefd91a 100644 --- a/plugins/stack-overflow/CHANGELOG.md +++ b/plugins/stack-overflow/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-stack-overflow +## 0.1.24 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-home-react@0.1.7 + - @backstage/plugin-search-react@1.7.5 + - @backstage/config@1.1.1 + - @backstage/plugin-search-common@1.2.10 + ## 0.1.24-next.2 ### Patch Changes diff --git a/plugins/stack-overflow/package.json b/plugins/stack-overflow/package.json index 1b5da9ae13..dcce8e793f 100644 --- a/plugins/stack-overflow/package.json +++ b/plugins/stack-overflow/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-stack-overflow", - "version": "0.1.24-next.2", + "version": "0.1.24", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/stackstorm/CHANGELOG.md b/plugins/stackstorm/CHANGELOG.md index be02933ca6..dcade807b8 100644 --- a/plugins/stackstorm/CHANGELOG.md +++ b/plugins/stackstorm/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-stackstorm +## 0.1.10 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/errors@1.2.3 + ## 0.1.10-next.1 ### Patch Changes diff --git a/plugins/stackstorm/package.json b/plugins/stackstorm/package.json index f2c85ed5b9..d22b17be40 100644 --- a/plugins/stackstorm/package.json +++ b/plugins/stackstorm/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-stackstorm", "description": "A Backstage plugin that integrates towards StackStorm", - "version": "0.1.10-next.1", + "version": "0.1.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md index cc9313e90a..d90a7f158a 100644 --- a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md +++ b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-tech-insights-backend-module-jsonfc +## 0.1.41 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-tech-insights-node@0.4.15 + - @backstage/errors@1.2.3 + - @backstage/plugin-tech-insights-common@0.2.12 + ## 0.1.41-next.2 ### Patch Changes diff --git a/plugins/tech-insights-backend-module-jsonfc/package.json b/plugins/tech-insights-backend-module-jsonfc/package.json index 89cc4031d8..3a17a952d8 100644 --- a/plugins/tech-insights-backend-module-jsonfc/package.json +++ b/plugins/tech-insights-backend-module-jsonfc/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-backend-module-jsonfc", - "version": "0.1.41-next.2", + "version": "0.1.41", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-backend/CHANGELOG.md b/plugins/tech-insights-backend/CHANGELOG.md index c9b59e5ad8..3812ef6d91 100644 --- a/plugins/tech-insights-backend/CHANGELOG.md +++ b/plugins/tech-insights-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-tech-insights-backend +## 0.5.23 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-tech-insights-node@0.4.15 + - @backstage/backend-tasks@0.5.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + ## 0.5.23-next.2 ### Patch Changes diff --git a/plugins/tech-insights-backend/package.json b/plugins/tech-insights-backend/package.json index 307e97c1ab..92a3399683 100644 --- a/plugins/tech-insights-backend/package.json +++ b/plugins/tech-insights-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-backend", - "version": "0.5.23-next.2", + "version": "0.5.23", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-node/CHANGELOG.md b/plugins/tech-insights-node/CHANGELOG.md index 6a877f1177..a93118ad6a 100644 --- a/plugins/tech-insights-node/CHANGELOG.md +++ b/plugins/tech-insights-node/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-tech-insights-node +## 0.4.15 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + ## 0.4.15-next.2 ### Patch Changes diff --git a/plugins/tech-insights-node/package.json b/plugins/tech-insights-node/package.json index 469bfb5601..824b4cb752 100644 --- a/plugins/tech-insights-node/package.json +++ b/plugins/tech-insights-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-node", - "version": "0.4.15-next.2", + "version": "0.4.15", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights/CHANGELOG.md b/plugins/tech-insights/CHANGELOG.md index afe3a21dec..81349dfe8f 100644 --- a/plugins/tech-insights/CHANGELOG.md +++ b/plugins/tech-insights/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-tech-insights +## 0.3.21 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + ## 0.3.21-next.2 ### Patch Changes diff --git a/plugins/tech-insights/package.json b/plugins/tech-insights/package.json index 236ebd6b12..c37d516e06 100644 --- a/plugins/tech-insights/package.json +++ b/plugins/tech-insights/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights", - "version": "0.3.21-next.2", + "version": "0.3.21", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-radar/CHANGELOG.md b/plugins/tech-radar/CHANGELOG.md index 366ef940f6..073fe92739 100644 --- a/plugins/tech-radar/CHANGELOG.md +++ b/plugins/tech-radar/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-tech-radar +## 0.6.12 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + ## 0.6.12-next.2 ### Patch Changes diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index 0536114019..b94382a239 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-tech-radar", "description": "A Backstage plugin that lets you display a Tech Radar for your organization", - "version": "0.6.12-next.2", + "version": "0.6.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index 2689d6ef64..9ceb5d0a09 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.26 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-techdocs-react@1.1.15 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-techdocs@1.9.3 + - @backstage/plugin-catalog@1.16.1 + - @backstage/plugin-search-react@1.7.5 + - @backstage/integration-react@1.1.23 + - @backstage/core-app-api@1.11.3 + - @backstage/test-utils@1.4.7 + ## 1.0.26-next.2 ### Patch Changes diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index c46e3e679f..bd150c9326 100644 --- a/plugins/techdocs-addons-test-utils/package.json +++ b/plugins/techdocs-addons-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-addons-test-utils", - "version": "1.0.26-next.2", + "version": "1.0.26", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index 0f1e623fa9..25116c2810 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-techdocs-backend +## 1.9.2 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/plugin-search-backend-module-techdocs@0.1.13 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-techdocs-node@1.11.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/plugin-catalog-common@1.0.20 + ## 1.9.2-next.2 ### Patch Changes diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index bcaf6ba079..1f13ed3d5c 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-backend", "description": "The Backstage backend plugin that renders technical documentation for your components", - "version": "1.9.2-next.2", + "version": "1.9.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-module-addons-contrib/CHANGELOG.md b/plugins/techdocs-module-addons-contrib/CHANGELOG.md index 7aa5393113..c6c4070487 100644 --- a/plugins/techdocs-module-addons-contrib/CHANGELOG.md +++ b/plugins/techdocs-module-addons-contrib/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-techdocs-module-addons-contrib +## 1.1.4 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-techdocs-react@1.1.15 + - @backstage/integration-react@1.1.23 + - @backstage/integration@1.8.0 + ## 1.1.4-next.1 ### Patch Changes diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index f29baf4c05..1d296eb158 100644 --- a/plugins/techdocs-module-addons-contrib/package.json +++ b/plugins/techdocs-module-addons-contrib/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-module-addons-contrib", "description": "Plugin module for contributed TechDocs Addons", - "version": "1.1.4-next.1", + "version": "1.1.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-node/CHANGELOG.md b/plugins/techdocs-node/CHANGELOG.md index 770292f8c6..c4aeb5c4d7 100644 --- a/plugins/techdocs-node/CHANGELOG.md +++ b/plugins/techdocs-node/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-techdocs-node +## 1.11.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/integration-aws-node@0.1.8 + - @backstage/plugin-search-common@1.2.10 + ## 1.11.1-next.2 ### Patch Changes diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index e983e235c4..592ae94151 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-node", "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", - "version": "1.11.1-next.2", + "version": "1.11.1", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/plugins/techdocs-react/CHANGELOG.md b/plugins/techdocs-react/CHANGELOG.md index a6273af03c..7017882a65 100644 --- a/plugins/techdocs-react/CHANGELOG.md +++ b/plugins/techdocs-react/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-techdocs-react +## 1.1.15 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/version-bridge@1.0.7 + ## 1.1.15-next.1 ### Patch Changes diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index 3be8499a2d..1bdb2a29c8 100644 --- a/plugins/techdocs-react/package.json +++ b/plugins/techdocs-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-react", "description": "Shared frontend utilities for TechDocs and Addons", - "version": "1.1.15-next.1", + "version": "1.1.15", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index 0410402b8d..9a982a80f5 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-techdocs +## 1.9.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-techdocs-react@1.1.15 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-search-react@1.7.5 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/theme@0.5.0 + - @backstage/plugin-search-common@1.2.10 + ## 1.9.3-next.2 ### Patch Changes diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 1ea3cd3e5d..51c631e8ec 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs", "description": "The Backstage plugin that renders technical documentation for your components", - "version": "1.9.3-next.2", + "version": "1.9.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/todo-backend/CHANGELOG.md b/plugins/todo-backend/CHANGELOG.md index 8fba287cb4..bbda40e0a7 100644 --- a/plugins/todo-backend/CHANGELOG.md +++ b/plugins/todo-backend/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-todo-backend +## 0.3.7 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/catalog-client@1.5.2 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-openapi-utils@0.1.2 + - @backstage/plugin-catalog-node@1.6.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + ## 0.3.7-next.2 ### Patch Changes diff --git a/plugins/todo-backend/package.json b/plugins/todo-backend/package.json index ed08369624..ddf3baac3d 100644 --- a/plugins/todo-backend/package.json +++ b/plugins/todo-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-todo-backend", "description": "A Backstage backend plugin that lets you browse TODO comments in your source code", - "version": "0.3.7-next.2", + "version": "0.3.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/todo/CHANGELOG.md b/plugins/todo/CHANGELOG.md index c477dd098f..bc736a73fc 100644 --- a/plugins/todo/CHANGELOG.md +++ b/plugins/todo/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-todo +## 0.2.33 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + ## 0.2.33-next.2 ### Patch Changes diff --git a/plugins/todo/package.json b/plugins/todo/package.json index b06baf040b..d7ee6b83c0 100644 --- a/plugins/todo/package.json +++ b/plugins/todo/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-todo", "description": "A Backstage plugin that lets you browse TODO comments in your source code", - "version": "0.2.33-next.2", + "version": "0.2.33", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/user-settings-backend/CHANGELOG.md b/plugins/user-settings-backend/CHANGELOG.md index 3b1d01c240..c9ab9a3263 100644 --- a/plugins/user-settings-backend/CHANGELOG.md +++ b/plugins/user-settings-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-user-settings-backend +## 0.2.8 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/plugin-auth-node@0.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.2.8-next.2 ### Patch Changes diff --git a/plugins/user-settings-backend/package.json b/plugins/user-settings-backend/package.json index 276a6eaa4a..d3c3abca49 100644 --- a/plugins/user-settings-backend/package.json +++ b/plugins/user-settings-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-user-settings-backend", "description": "The Backstage backend plugin to manage user settings", - "version": "0.2.8-next.2", + "version": "0.2.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index 333f0f334c..e733ca5372 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-user-settings +## 0.8.0 + +### Minor Changes + +- 56b2fb0: Updated the user settings selector to use a select component that displays native language names instead of language codes if possible. + +### Patch Changes + +- eea0849: add user-settings declarative integration core nav item +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/core-app-api@1.11.3 + - @backstage/errors@1.2.3 + - @backstage/theme@0.5.0 + - @backstage/types@1.1.1 + ## 0.8.0-next.2 ### Patch Changes diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 7f98fa8de9..c873786874 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-user-settings", "description": "A Backstage plugin that provides a settings page", - "version": "0.8.0-next.2", + "version": "0.8.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/vault-backend/CHANGELOG.md b/plugins/vault-backend/CHANGELOG.md index 8fd4b0e95f..efc029a962 100644 --- a/plugins/vault-backend/CHANGELOG.md +++ b/plugins/vault-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-vault-backend +## 0.4.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/backend-plugin-api@0.6.9 + - @backstage/backend-tasks@0.5.14 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-vault-node@0.1.2 + ## 0.4.2-next.2 ### Patch Changes diff --git a/plugins/vault-backend/package.json b/plugins/vault-backend/package.json index e262825a48..ed98b0f441 100644 --- a/plugins/vault-backend/package.json +++ b/plugins/vault-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-vault-backend", "description": "A Backstage backend plugin that integrates towards Vault", - "version": "0.4.2-next.2", + "version": "0.4.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/vault-node/CHANGELOG.md b/plugins/vault-node/CHANGELOG.md index 901b22a638..7b7c8e0d6e 100644 --- a/plugins/vault-node/CHANGELOG.md +++ b/plugins/vault-node/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-vault-node +## 0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.9 + ## 0.1.2-next.2 ### Patch Changes diff --git a/plugins/vault-node/package.json b/plugins/vault-node/package.json index 780d5ff5bb..b3977cf3a5 100644 --- a/plugins/vault-node/package.json +++ b/plugins/vault-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-vault-node", "description": "Node.js library for the vault plugin", - "version": "0.1.2-next.2", + "version": "0.1.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/vault/CHANGELOG.md b/plugins/vault/CHANGELOG.md index 93a69e5e76..bb5e881c8f 100644 --- a/plugins/vault/CHANGELOG.md +++ b/plugins/vault/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-vault +## 0.1.24 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + ## 0.1.24-next.2 ### Patch Changes diff --git a/plugins/vault/package.json b/plugins/vault/package.json index ce7b7a0dcb..2ad4f60d66 100644 --- a/plugins/vault/package.json +++ b/plugins/vault/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-vault", "description": "A Backstage plugin that integrates towards Vault", - "version": "0.1.24-next.2", + "version": "0.1.24", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/xcmetrics/CHANGELOG.md b/plugins/xcmetrics/CHANGELOG.md index 2a24ea4d43..1fc98ffa8b 100644 --- a/plugins/xcmetrics/CHANGELOG.md +++ b/plugins/xcmetrics/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-xcmetrics +## 0.2.47 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/errors@1.2.3 + ## 0.2.47-next.1 ### Patch Changes diff --git a/plugins/xcmetrics/package.json b/plugins/xcmetrics/package.json index 538ed5f993..9ee51bb5c5 100644 --- a/plugins/xcmetrics/package.json +++ b/plugins/xcmetrics/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-xcmetrics", "description": "A Backstage plugin that shows XCode build metrics for your components", - "version": "0.2.47-next.1", + "version": "0.2.47", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/yarn.lock b/yarn.lock index 662c9000a6..30474455e6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3467,18 +3467,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-client@npm:^1.5.0": - version: 1.5.1 - resolution: "@backstage/catalog-client@npm:1.5.1" - dependencies: - "@backstage/catalog-model": ^1.4.3 - "@backstage/errors": ^1.2.3 - cross-fetch: ^4.0.0 - uri-template: ^2.0.0 - checksum: 786fa1bafba3d44d88855d8479879577e33816f1f9d2e110b275fc22ca4348f8dce0ebe789d580786a38e9986989c98172f7a07c1e2145b8da689608a2aa4ec2 - languageName: node - linkType: hard - "@backstage/catalog-client@workspace:^, @backstage/catalog-client@workspace:packages/catalog-client": version: 0.0.0-use.local resolution: "@backstage/catalog-client@workspace:packages/catalog-client" @@ -3741,7 +3729,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/config@^1.0.6, @backstage/config@^1.0.7, @backstage/config@^1.1.1, @backstage/config@workspace:^, @backstage/config@workspace:packages/config": +"@backstage/config@^1.0.6, @backstage/config@^1.0.7, @backstage/config@workspace:^, @backstage/config@workspace:packages/config": version: 0.0.0-use.local resolution: "@backstage/config@workspace:packages/config" dependencies: @@ -3814,110 +3802,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-components@npm:^0.12.3": - version: 0.12.5 - resolution: "@backstage/core-components@npm:0.12.5" - dependencies: - "@backstage/config": ^1.0.7 - "@backstage/core-plugin-api": ^1.5.0 - "@backstage/errors": ^1.1.5 - "@backstage/theme": ^0.2.18 - "@backstage/version-bridge": ^1.0.3 - "@material-table/core": ^3.1.0 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.57 - "@react-hookz/web": ^20.0.0 - "@types/react-sparklines": ^1.7.0 - "@types/react-text-truncate": ^0.14.0 - ansi-regex: ^6.0.1 - classnames: ^2.2.6 - d3-selection: ^3.0.0 - d3-shape: ^3.0.0 - d3-zoom: ^3.0.0 - dagre: ^0.8.5 - history: ^5.0.0 - immer: ^9.0.1 - lodash: ^4.17.21 - pluralize: ^8.0.0 - prop-types: ^15.7.2 - qs: ^6.9.4 - rc-progress: 3.4.1 - react-helmet: 6.1.0 - react-hook-form: ^7.12.2 - react-markdown: ^8.0.0 - react-sparklines: ^1.7.0 - react-syntax-highlighter: ^15.4.5 - react-text-truncate: ^0.19.0 - react-use: ^17.3.2 - react-virtualized-auto-sizer: ^1.0.6 - react-window: ^1.8.6 - remark-gfm: ^3.0.1 - zen-observable: ^0.10.0 - zod: ~3.18.0 - peerDependencies: - "@types/react": ^16.13.1 || ^17.0.0 - react: ^16.13.1 || ^17.0.0 - react-dom: ^16.13.1 || ^17.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 8308c1b90247911f6cf22963b530cef169287f508ff29d159d0c83758134dd43bd5acd2113350690a46a02246bc05dca975bcc38325000aefb1c93c80e2f19c7 - languageName: node - linkType: hard - -"@backstage/core-components@npm:^0.13.8, @backstage/core-components@npm:^0.13.9": - version: 0.13.9 - resolution: "@backstage/core-components@npm:0.13.9" - dependencies: - "@backstage/config": ^1.1.1 - "@backstage/core-plugin-api": ^1.8.1 - "@backstage/errors": ^1.2.3 - "@backstage/theme": ^0.5.0 - "@backstage/version-bridge": ^1.0.7 - "@date-io/core": ^1.3.13 - "@material-table/core": ^3.1.0 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@react-hookz/web": ^23.0.0 - "@types/react": ^16.13.1 || ^17.0.0 - "@types/react-sparklines": ^1.7.0 - "@types/react-text-truncate": ^0.14.0 - ansi-regex: ^6.0.1 - classnames: ^2.2.6 - d3-selection: ^3.0.0 - d3-shape: ^3.0.0 - d3-zoom: ^3.0.0 - dagre: ^0.8.5 - history: ^5.0.0 - immer: ^9.0.1 - linkify-react: 4.1.3 - linkifyjs: 4.1.3 - lodash: ^4.17.21 - pluralize: ^8.0.0 - qs: ^6.9.4 - rc-progress: 3.5.1 - react-helmet: 6.1.0 - react-hook-form: ^7.12.2 - react-idle-timer: 5.6.2 - react-markdown: ^8.0.0 - react-sparklines: ^1.7.0 - react-syntax-highlighter: ^15.4.5 - react-text-truncate: ^0.19.0 - react-use: ^17.3.2 - react-virtualized-auto-sizer: ^1.0.11 - react-window: ^1.8.6 - remark-gfm: ^3.0.1 - zen-observable: ^0.10.0 - zod: ^3.22.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 6674d70f5043cf2a6bca0097ce5fa2d1cb6594a4870c3c64e357ac9cc54b85e33502e9257918c9eebb3e87249d798ee9e223eacc5b02014b4196bd0f9804c2ac - languageName: node - linkType: hard - -"@backstage/core-components@workspace:^, @backstage/core-components@workspace:packages/core-components": +"@backstage/core-components@^0.13.8, @backstage/core-components@workspace:^, @backstage/core-components@workspace:packages/core-components": version: 0.0.0-use.local resolution: "@backstage/core-components@workspace:packages/core-components" dependencies: @@ -3989,25 +3874,57 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-plugin-api@npm:^1.3.0, @backstage/core-plugin-api@npm:^1.5.0, @backstage/core-plugin-api@npm:^1.8.0, @backstage/core-plugin-api@npm:^1.8.1": - version: 1.8.1 - resolution: "@backstage/core-plugin-api@npm:1.8.1" +"@backstage/core-components@npm:^0.12.3": + version: 0.12.5 + resolution: "@backstage/core-components@npm:0.12.5" dependencies: - "@backstage/config": ^1.1.1 - "@backstage/types": ^1.1.1 - "@backstage/version-bridge": ^1.0.7 - "@types/react": ^16.13.1 || ^17.0.0 + "@backstage/config": ^1.0.7 + "@backstage/core-plugin-api": ^1.5.0 + "@backstage/errors": ^1.1.5 + "@backstage/theme": ^0.2.18 + "@backstage/version-bridge": ^1.0.3 + "@material-table/core": ^3.1.0 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": 4.0.0-alpha.57 + "@react-hookz/web": ^20.0.0 + "@types/react-sparklines": ^1.7.0 + "@types/react-text-truncate": ^0.14.0 + ansi-regex: ^6.0.1 + classnames: ^2.2.6 + d3-selection: ^3.0.0 + d3-shape: ^3.0.0 + d3-zoom: ^3.0.0 + dagre: ^0.8.5 history: ^5.0.0 - i18next: ^22.4.15 + immer: ^9.0.1 + lodash: ^4.17.21 + pluralize: ^8.0.0 + prop-types: ^15.7.2 + qs: ^6.9.4 + rc-progress: 3.4.1 + react-helmet: 6.1.0 + react-hook-form: ^7.12.2 + react-markdown: ^8.0.0 + react-sparklines: ^1.7.0 + react-syntax-highlighter: ^15.4.5 + react-text-truncate: ^0.19.0 + react-use: ^17.3.2 + react-virtualized-auto-sizer: ^1.0.6 + react-window: ^1.8.6 + remark-gfm: ^3.0.1 + zen-observable: ^0.10.0 + zod: ~3.18.0 peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react": ^16.13.1 || ^17.0.0 + react: ^16.13.1 || ^17.0.0 + react-dom: ^16.13.1 || ^17.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 8fa85beb719f65b2dc2ab69df7e7354d280ce63ca163ce820dec43ac7ffe95ce1c3ae1175774f034ea3787cb997e0bc630f42b644b166b7f9929f6166e7c2607 + checksum: 8308c1b90247911f6cf22963b530cef169287f508ff29d159d0c83758134dd43bd5acd2113350690a46a02246bc05dca975bcc38325000aefb1c93c80e2f19c7 languageName: node linkType: hard -"@backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": +"@backstage/core-plugin-api@^1.3.0, @backstage/core-plugin-api@^1.5.0, @backstage/core-plugin-api@^1.8.0, @backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": version: 0.0.0-use.local resolution: "@backstage/core-plugin-api@workspace:packages/core-plugin-api" dependencies: @@ -4103,7 +4020,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/errors@^1.1.5, @backstage/errors@^1.2.3, @backstage/errors@workspace:^, @backstage/errors@workspace:packages/errors": +"@backstage/errors@^1.1.5, @backstage/errors@workspace:^, @backstage/errors@workspace:packages/errors": version: 0.0.0-use.local resolution: "@backstage/errors@workspace:packages/errors" dependencies: @@ -4151,27 +4068,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/frontend-plugin-api@npm:^0.4.0": - version: 0.4.0 - resolution: "@backstage/frontend-plugin-api@npm:0.4.0" - dependencies: - "@backstage/config": ^1.1.1 - "@backstage/core-components": ^0.13.9 - "@backstage/core-plugin-api": ^1.8.1 - "@backstage/types": ^1.1.1 - "@backstage/version-bridge": ^1.0.7 - "@material-ui/core": ^4.12.4 - "@types/react": ^16.13.1 || ^17.0.0 - lodash: ^4.17.21 - zod: ^3.22.4 - zod-to-json-schema: ^3.21.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 6b19944a070b8e0c0d9a33c39d50f0bf1a3dfb5884833bd96286508573528a4b254660f0044eeeeecf4f7d392b71a95e3b9665903d83cb27aa04625155284b2b - languageName: node - linkType: hard - "@backstage/frontend-plugin-api@workspace:^, @backstage/frontend-plugin-api@workspace:packages/frontend-plugin-api": version: 0.0.0-use.local resolution: "@backstage/frontend-plugin-api@workspace:packages/frontend-plugin-api" @@ -4235,25 +4131,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/integration-react@npm:^1.1.21, @backstage/integration-react@npm:^1.1.22": - version: 1.1.22 - resolution: "@backstage/integration-react@npm:1.1.22" - dependencies: - "@backstage/config": ^1.1.1 - "@backstage/core-plugin-api": ^1.8.1 - "@backstage/integration": ^1.8.0 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@types/react": ^16.13.1 || ^17.0.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 76fb82f1f947574259d393406bdc30919636e451dbbab357b640f70b2b8b869564fad10da74088f12b497996b84b8e3f55ddea355a9ee61c27f549a2805773a5 - languageName: node - linkType: hard - -"@backstage/integration-react@workspace:^, @backstage/integration-react@workspace:packages/integration-react": +"@backstage/integration-react@^1.1.21, @backstage/integration-react@workspace:^, @backstage/integration-react@workspace:packages/integration-react": version: 0.0.0-use.local resolution: "@backstage/integration-react@workspace:packages/integration-react" dependencies: @@ -4277,7 +4155,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/integration@^1.8.0, @backstage/integration@workspace:^, @backstage/integration@workspace:packages/integration": +"@backstage/integration@workspace:^, @backstage/integration@workspace:packages/integration": version: 0.0.0-use.local resolution: "@backstage/integration@workspace:packages/integration" dependencies: @@ -5689,7 +5567,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-common@^1.0.10, @backstage/plugin-catalog-common@^1.0.19, @backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": +"@backstage/plugin-catalog-common@^1.0.10, @backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-common@workspace:plugins/catalog-common" dependencies: @@ -5795,44 +5673,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@npm:^1.2.4, @backstage/plugin-catalog-react@npm:^1.9.1": - version: 1.9.2 - resolution: "@backstage/plugin-catalog-react@npm:1.9.2" - dependencies: - "@backstage/catalog-client": ^1.5.0 - "@backstage/catalog-model": ^1.4.3 - "@backstage/core-components": ^0.13.9 - "@backstage/core-plugin-api": ^1.8.1 - "@backstage/errors": ^1.2.3 - "@backstage/frontend-plugin-api": ^0.4.0 - "@backstage/integration-react": ^1.1.22 - "@backstage/plugin-catalog-common": ^1.0.19 - "@backstage/plugin-permission-common": ^0.7.11 - "@backstage/plugin-permission-react": ^0.4.18 - "@backstage/theme": ^0.5.0 - "@backstage/types": ^1.1.1 - "@backstage/version-bridge": ^1.0.7 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@react-hookz/web": ^23.0.0 - "@types/react": ^16.13.1 || ^17.0.0 - classnames: ^2.2.6 - lodash: ^4.17.21 - material-ui-popup-state: ^1.9.3 - qs: ^6.9.4 - react-use: ^17.2.4 - yaml: ^2.0.0 - zen-observable: ^0.10.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: e363db83bb85a6dac23616104aa52b019c4f32341fb757c40cf0321ad12427ffcad647b54b38d2d47a7299571e95c2cd226e01c6f9dde585d5377a4dc95a1df6 - languageName: node - linkType: hard - -"@backstage/plugin-catalog-react@workspace:^, @backstage/plugin-catalog-react@workspace:plugins/catalog-react": +"@backstage/plugin-catalog-react@^1.2.4, @backstage/plugin-catalog-react@^1.9.1, @backstage/plugin-catalog-react@workspace:^, @backstage/plugin-catalog-react@workspace:plugins/catalog-react": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-react@workspace:plugins/catalog-react" dependencies: @@ -7023,25 +6864,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-home-react@npm:^0.1.5": - version: 0.1.6 - resolution: "@backstage/plugin-home-react@npm:0.1.6" - dependencies: - "@backstage/core-components": ^0.13.9 - "@backstage/core-plugin-api": ^1.8.1 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@rjsf/utils": 5.15.0 - "@types/react": ^16.13.1 || ^17.0.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: ecd2d6d6b2f0793bb0180b07ec7559230361eb3174d7a962bc08fabc2c29bf21f9705ae5b9a6977005ecac4009dc5806b0d8ecac67eecb6507141764a96d1def - languageName: node - linkType: hard - -"@backstage/plugin-home-react@workspace:^, @backstage/plugin-home-react@workspace:plugins/home-react": +"@backstage/plugin-home-react@^0.1.5, @backstage/plugin-home-react@workspace:^, @backstage/plugin-home-react@workspace:plugins/home-react": version: 0.0.0-use.local resolution: "@backstage/plugin-home-react@workspace:plugins/home-react" dependencies: @@ -7919,7 +7742,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-common@^0.7.11, @backstage/plugin-permission-common@workspace:^, @backstage/plugin-permission-common@workspace:plugins/permission-common": +"@backstage/plugin-permission-common@workspace:^, @backstage/plugin-permission-common@workspace:plugins/permission-common": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-common@workspace:plugins/permission-common" dependencies: @@ -7957,25 +7780,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-react@npm:^0.4.18": - version: 0.4.18 - resolution: "@backstage/plugin-permission-react@npm:0.4.18" - dependencies: - "@backstage/config": ^1.1.1 - "@backstage/core-plugin-api": ^1.8.1 - "@backstage/plugin-permission-common": ^0.7.11 - "@types/react": ^16.13.1 || ^17.0.0 - cross-fetch: ^4.0.0 - react-use: ^17.2.4 - swr: ^2.0.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: da1386b814fcb0b7350cebc1975d88cdf4c97a474f292a56d4e15ce63bb25a54d34d17067865363fa051983d9fa5170afce6a38299bc7c3ab82f1e44c708b13b - languageName: node - linkType: hard - "@backstage/plugin-permission-react@workspace:^, @backstage/plugin-permission-react@workspace:plugins/permission-react": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-react@workspace:plugins/permission-react" @@ -9706,26 +9510,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/theme@^0.5.0, @backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": - version: 0.0.0-use.local - resolution: "@backstage/theme@workspace:packages/theme" - dependencies: - "@backstage/cli": "workspace:^" - "@emotion/react": ^11.10.5 - "@emotion/styled": ^11.10.5 - "@mui/material": ^5.12.2 - "@mui/styles": ^5.14.18 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 - peerDependencies: - "@material-ui/core": ^4.12.2 - "@types/react": ^16.13.1 || ^17.0.0 - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - languageName: unknown - linkType: soft - "@backstage/theme@npm:^0.2.16, @backstage/theme@npm:^0.2.18": version: 0.2.19 resolution: "@backstage/theme@npm:0.2.19" @@ -9754,7 +9538,27 @@ __metadata: languageName: node linkType: hard -"@backstage/types@^1.0.2, @backstage/types@^1.1.1, @backstage/types@workspace:^, @backstage/types@workspace:packages/types": +"@backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": + version: 0.0.0-use.local + resolution: "@backstage/theme@workspace:packages/theme" + dependencies: + "@backstage/cli": "workspace:^" + "@emotion/react": ^11.10.5 + "@emotion/styled": ^11.10.5 + "@mui/material": ^5.12.2 + "@mui/styles": ^5.14.18 + "@testing-library/jest-dom": ^6.0.0 + "@testing-library/react": ^14.0.0 + "@types/react": ^16.13.1 || ^17.0.0 + peerDependencies: + "@material-ui/core": ^4.12.2 + "@types/react": ^16.13.1 || ^17.0.0 + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + languageName: unknown + linkType: soft + +"@backstage/types@^1.0.2, @backstage/types@workspace:^, @backstage/types@workspace:packages/types": version: 0.0.0-use.local resolution: "@backstage/types@workspace:packages/types" dependencies: @@ -9765,7 +9569,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/version-bridge@^1.0.3, @backstage/version-bridge@^1.0.7, @backstage/version-bridge@workspace:^, @backstage/version-bridge@workspace:packages/version-bridge": +"@backstage/version-bridge@^1.0.3, @backstage/version-bridge@workspace:^, @backstage/version-bridge@workspace:packages/version-bridge": version: 0.0.0-use.local resolution: "@backstage/version-bridge@workspace:packages/version-bridge" dependencies: @@ -14994,21 +14798,6 @@ __metadata: languageName: node linkType: hard -"@rjsf/utils@npm:5.15.0": - version: 5.15.0 - resolution: "@rjsf/utils@npm:5.15.0" - dependencies: - json-schema-merge-allof: ^0.8.1 - jsonpointer: ^5.0.1 - lodash: ^4.17.21 - lodash-es: ^4.17.21 - react-is: ^18.2.0 - peerDependencies: - react: ^16.14.0 || >=17 - checksum: 369de8620fdbd26aea074e0a33d5ea3b1bb89e3389d826a70612dbec8881617bb0dc8403ca6774d0def332ffe15d26bed133d6ff7361ff2978a4b024cea829c3 - languageName: node - linkType: hard - "@rjsf/utils@npm:5.15.1": version: 5.15.1 resolution: "@rjsf/utils@npm:5.15.1" From 172eda2d719d6390461bab49593ffc864ff52244 Mon Sep 17 00:00:00 2001 From: Philipp Hugenroth Date: Tue, 16 Jan 2024 14:35:44 +0100 Subject: [PATCH 087/283] Update publishing.md Signed-off-by: Philipp Hugenroth --- docs/publishing.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/publishing.md b/docs/publishing.md index 48e044d68c..15813275de 100644 --- a/docs/publishing.md +++ b/docs/publishing.md @@ -53,6 +53,7 @@ Additional steps for the main line release - Add the release note file as [`/docs/releases/vx.y.0.md`](./releases) - Add an entry to [`/microsite/sidebar.json`](https://github.com/backstage/backstage/blob/master/microsite/sidebars.json) for the release note - Update the navigation bar item in [`/microsite/docusaurus.config.js`](https://github.com/backstage/backstage/blob/master/microsite/docusaurus.config.js) to point to the new release note + - Finally copy the content, without the metadata header, into the description of the [`Version Packages` Pull Request](https://github.com/backstage/backstage/pulls?q=is%3Aopen+is%3Apr+in%3Atitle+%22Version+Packages) Once the release has been published edit the newly created release in the [GitHub repository](https://github.com/backstage/backstage/releases) and replace the text content with the release notes. From 80e3cbb266ef4f86115c6cc52d56d9d22f76155c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 15:11:32 +0000 Subject: [PATCH 088/283] chore(deps): update chromaui/action digest to 722516a Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/verify_storybook.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/verify_storybook.yml b/.github/workflows/verify_storybook.yml index 6219faf616..d7f90118de 100644 --- a/.github/workflows/verify_storybook.yml +++ b/.github/workflows/verify_storybook.yml @@ -51,7 +51,7 @@ jobs: - run: yarn build-storybook - - uses: chromaui/action@80bf5911f28005ed208f15b7268843b79ca0e23a # v1 + - uses: chromaui/action@722516a3934360dac82cdef8dbab38e824fc6fa1 # v1 with: token: ${{ secrets.GITHUB_TOKEN }} # projectToken intentionally shared to allow collaborators to run Chromatic on forks From 2f6300ba3a2b4d210bb1c5936d04f40f1396e588 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 15:11:40 +0000 Subject: [PATCH 089/283] chore(deps): update actions/cache action to v3.3.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/uffizzi-preview.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/uffizzi-preview.yaml b/.github/workflows/uffizzi-preview.yaml index c1659097a7..9591af3a23 100644 --- a/.github/workflows/uffizzi-preview.yaml +++ b/.github/workflows/uffizzi-preview.yaml @@ -76,7 +76,7 @@ jobs: - name: Cache Manifests File if: ${{ steps.event.outputs.ACTION != 'closed' }} - uses: actions/cache@v3.3.2 + uses: actions/cache@v3.3.3 with: path: manifests.rendered.yml key: ${{ steps.hash.outputs.MANIFESTS_FILE_HASH }} From d6415acbaa6be9d6cb04b21368b9e698c3aefb27 Mon Sep 17 00:00:00 2001 From: Gauri Maheshwari <100439627+gauriimaheshwarii@users.noreply.github.com> Date: Tue, 16 Jan 2024 21:38:25 +0530 Subject: [PATCH 090/283] [fix]: export module as a default Signed-off-by: Gauri Maheshwari <100439627+gauriimaheshwarii@users.noreply.github.com> --- packages/cli/templates/default-backend-module/src/index.ts.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/templates/default-backend-module/src/index.ts.hbs b/packages/cli/templates/default-backend-module/src/index.ts.hbs index 0cf1f00d42..7075598e13 100644 --- a/packages/cli/templates/default-backend-module/src/index.ts.hbs +++ b/packages/cli/templates/default-backend-module/src/index.ts.hbs @@ -5,4 +5,4 @@ * @packageDocumentation */ -export { {{moduleVar}} } from './module'; +export { {{moduleVar}} as default } from './module'; From 23604434c15cb09067c8a92144dfa97e15290c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 16 Jan 2024 19:41:15 +0100 Subject: [PATCH 091/283] make vale happy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- docs/backend-system/building-backends/08-migrating.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/backend-system/building-backends/08-migrating.md b/docs/backend-system/building-backends/08-migrating.md index 2514f0925e..45478d632e 100644 --- a/docs/backend-system/building-backends/08-migrating.md +++ b/docs/backend-system/building-backends/08-migrating.md @@ -757,7 +757,7 @@ implementations that they represent, and being exported from there. ### The Auth Plugin -A basic installation of the auth plugin with a microsoft provider will look as follows. +A basic installation of the auth plugin with a Microsoft provider will look as follows. ```ts title="packages/backend/src/index.ts" const backend = createBackend(); From 53f0404a319248ac591530a076f13f1e6cb02c47 Mon Sep 17 00:00:00 2001 From: Jake Taylor <147415933+jrtaylorJH@users.noreply.github.com> Date: Tue, 16 Jan 2024 15:44:40 -0600 Subject: [PATCH 092/283] Update debugging.md to include debugging information for webstorm Signed-off-by: Jake Taylor <147415933+jrtaylorJH@users.noreply.github.com> --- docs/local-dev/debugging.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/local-dev/debugging.md b/docs/local-dev/debugging.md index 17a98b1c1c..3de09b0108 100644 --- a/docs/local-dev/debugging.md +++ b/docs/local-dev/debugging.md @@ -71,3 +71,20 @@ In your `launch.json`, add a new entry with the following, "console": "integratedTerminal" }, ``` + +### WebStorm + +This section describes the process for enabling run configurations for Backstage in WebStorm. +Run configurations enable the use of debugging functionality such as steppers and breakpoints. + +1. Select `Edit Configurations` in the `Run` dropdown menu. Click the plus sign to add a new + configuration, then select `Node.js`. +3. In `Working directory`, input `{PROJECT_DIR}/packages/backend`. + Replace `{PROJECT_DIR}` with the path to your Backstage repo. +4. In `JavaScript file`, input `{PROJECT_DIR}/node_modules/@backstage/cli/bin/backstage-cli`. + Replace `{PROJECT_DIR}` with the path to your Backstage repo. +5. In `Application parameters`, input `package start`. +6. Optionally, for `Environment Variables`, input `LOG_LEVEL=debug`. +7. Click `Apply` to save the changes. +8. With the newly-created configuration selected, use the `Run` or `Debug` icons on the + toolbar to execute the newly created configuration. From e0c18ef3b7fdef42f22ba73ec5c6b3ea5e9f4873 Mon Sep 17 00:00:00 2001 From: Patrick Jungermann Date: Tue, 16 Jan 2024 16:21:50 +0100 Subject: [PATCH 093/283] chore: improve backend init error message Include extension point ID and module ID in backend init error message. Signed-off-by: Patrick Jungermann --- .changeset/gorgeous-bobcats-press.md | 5 +++++ .../backend-app-api/src/wiring/BackendInitializer.test.ts | 2 +- packages/backend-app-api/src/wiring/BackendInitializer.ts | 4 +++- .../backend-test-utils/src/next/wiring/TestBackend.test.ts | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 .changeset/gorgeous-bobcats-press.md diff --git a/.changeset/gorgeous-bobcats-press.md b/.changeset/gorgeous-bobcats-press.md new file mode 100644 index 0000000000..6193918cb7 --- /dev/null +++ b/.changeset/gorgeous-bobcats-press.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': patch +--- + +Include the extension point ID and the module ID in the backend init error message. diff --git a/packages/backend-app-api/src/wiring/BackendInitializer.test.ts b/packages/backend-app-api/src/wiring/BackendInitializer.test.ts index b5b53083a9..c025d19fa7 100644 --- a/packages/backend-app-api/src/wiring/BackendInitializer.test.ts +++ b/packages/backend-app-api/src/wiring/BackendInitializer.test.ts @@ -321,7 +321,7 @@ describe('BackendInitializer', () => { })(), ); await expect(init.start()).rejects.toThrow( - "Extension point registered for plugin 'test-a' may not be used by module for plugin 'test-b'", + "Illegal dependency: Module 'mod' for plugin 'test-b' attempted to depend on extension point 'a' for plugin 'test-a'. Extension points can only be used within their plugin's scope.", ); }); }); diff --git a/packages/backend-app-api/src/wiring/BackendInitializer.ts b/packages/backend-app-api/src/wiring/BackendInitializer.ts index 4969f82176..2da3a5a226 100644 --- a/packages/backend-app-api/src/wiring/BackendInitializer.ts +++ b/packages/backend-app-api/src/wiring/BackendInitializer.ts @@ -55,6 +55,7 @@ export class BackendInitializer { async #getInitDeps( deps: { [name: string]: ServiceOrExtensionPoint }, pluginId: string, + moduleId?: string, ) { const result = new Map(); const missingRefs = new Set(); @@ -64,7 +65,7 @@ export class BackendInitializer { if (ep) { if (ep.pluginId !== pluginId) { throw new Error( - `Extension point registered for plugin '${ep.pluginId}' may not be used by module for plugin '${pluginId}'`, + `Illegal dependency: Module '${moduleId}' for plugin '${pluginId}' attempted to depend on extension point '${ref.id}' for plugin '${ep.pluginId}'. Extension points can only be used within their plugin's scope.`, ); } result.set(name, ep.impl); @@ -260,6 +261,7 @@ export class BackendInitializer { const moduleDeps = await this.#getInitDeps( moduleInit.init.deps, pluginId, + moduleId, ); await moduleInit.init.func(moduleDeps).catch(error => { throw new ForwardedError( diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts b/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts index d71c774dd9..968237f11d 100644 --- a/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts +++ b/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts @@ -307,7 +307,7 @@ describe('TestBackend', () => { ], }), ).rejects.toThrow( - "Extension point registered for plugin 'testA' may not be used by module for plugin 'testB'", + "Illegal dependency: Module 'test' for plugin 'testB' attempted to depend on extension point 'a' for plugin 'testA'. Extension points can only be used within their plugin's scope.", ); }); From 356707690b391c4133906a2a0238b498bad8349c Mon Sep 17 00:00:00 2001 From: AmbrishRamachandiran Date: Wed, 17 Jan 2024 10:28:30 +0530 Subject: [PATCH 094/283] Updated readme Signed-off-by: AmbrishRamachandiran --- .changeset/curvy-ladybugs-impress.md | 2 +- docs/backend-system/building-backends/08-migrating.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/curvy-ladybugs-impress.md b/.changeset/curvy-ladybugs-impress.md index 3ea90f513a..ab799e4888 100644 --- a/.changeset/curvy-ladybugs-impress.md +++ b/.changeset/curvy-ladybugs-impress.md @@ -2,4 +2,4 @@ '@backstage/plugin-adr': patch --- -Updated README document in adr plugin +Updated README diff --git a/docs/backend-system/building-backends/08-migrating.md b/docs/backend-system/building-backends/08-migrating.md index 2514f0925e..45478d632e 100644 --- a/docs/backend-system/building-backends/08-migrating.md +++ b/docs/backend-system/building-backends/08-migrating.md @@ -757,7 +757,7 @@ implementations that they represent, and being exported from there. ### The Auth Plugin -A basic installation of the auth plugin with a microsoft provider will look as follows. +A basic installation of the auth plugin with a Microsoft provider will look as follows. ```ts title="packages/backend/src/index.ts" const backend = createBackend(); From de155ac19ede57ca46e2c7d8abacbd8dc3e92737 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 08:20:34 +0000 Subject: [PATCH 095/283] chore(deps): update dependency @types/node to v18.19.8 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/yarn.lock b/yarn.lock index 30474455e6..187fb120c0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18243,11 +18243,11 @@ __metadata: linkType: hard "@types/node@npm:*, @types/node@npm:>=12.12.47, @types/node@npm:>=13.7.0, @types/node@npm:^20.1.1": - version: 20.10.6 - resolution: "@types/node@npm:20.10.6" + version: 20.11.5 + resolution: "@types/node@npm:20.11.5" dependencies: undici-types: ~5.26.4 - checksum: ada40e4ccbda3697dca88f8d13f4c996c493be6fbc15f5f5d3b91096d56bd700786a2c148a92a2b4c5d1f133379e63f754a786b3aebfc6a7d09fc7ea16dc017b + checksum: a542727de1334ae20a3ca034b0ecf4b464a57ca01efc4f9cf43bd9ab93896125ab3c2de060ecd8f6ae23b86c6bf3463f681b643e69c032c6a662d376c98a6092 languageName: node linkType: hard @@ -18266,9 +18266,9 @@ __metadata: linkType: hard "@types/node@npm:^16.11.26, @types/node@npm:^16.7.10, @types/node@npm:^16.9.2": - version: 16.18.69 - resolution: "@types/node@npm:16.18.69" - checksum: ac7076062e59169ac1907e9347d939ed5f79c6a3ec2a531fe7186caf2fcf8d66de9b87ad42d92c4dfa6cb44b1018ab89fef1e054a82af36deea04ba32a5a670a + version: 16.18.71 + resolution: "@types/node@npm:16.18.71" + checksum: 7b61ec0abd2a298518b562618ddbcc1704a6427c666c9512a0b12700a2b26cad151ccfd3c147c9ab77ac5e0bcb62bfbf67c48fa0ef812a00859a1e33368e8802 languageName: node linkType: hard @@ -18280,11 +18280,11 @@ __metadata: linkType: hard "@types/node@npm:^18.17.8": - version: 18.19.4 - resolution: "@types/node@npm:18.19.4" + version: 18.19.8 + resolution: "@types/node@npm:18.19.8" dependencies: undici-types: ~5.26.4 - checksum: 3a32a31b2df85d4bebb5e3c91ec1a0908d587a2a2fd31ab4eeebd609d1c04bbcc9ba97e290e3230f843c9f43f17efb9f5cde56412b4b0f5acbfe5577179b23c8 + checksum: fa291495d6157a9d9393b4c3bdbf1ce12a8f661dc9da6a4fa19bcdb19af1c62bb8dbf7fb66ae135f29cd788b618e9845b83e9c47edcf39f0953a8561fdacd9a3 languageName: node linkType: hard From 463cfa120bcbc74194937e4ce9ccf1ebdeeab416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 17 Jan 2024 10:17:13 +0100 Subject: [PATCH 096/283] enter pre mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/pre.json | 268 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 .changeset/pre.json diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 0000000000..1e62c27268 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,268 @@ +{ + "mode": "pre", + "tag": "next", + "initialVersions": { + "example-app": "0.2.91", + "@backstage/app-defaults": "1.4.7", + "example-app-next": "0.0.5", + "app-next-example-plugin": "0.0.5", + "example-backend": "0.2.91", + "@backstage/backend-app-api": "0.5.10", + "@backstage/backend-common": "0.20.1", + "@backstage/backend-defaults": "0.2.9", + "@backstage/backend-dev-utils": "0.1.3", + "@backstage/backend-dynamic-feature-service": "0.1.0", + "example-backend-next": "0.0.19", + "@backstage/backend-openapi-utils": "0.1.2", + "@backstage/backend-plugin-api": "0.6.9", + "@backstage/backend-tasks": "0.5.14", + "@backstage/backend-test-utils": "0.2.10", + "@backstage/catalog-client": "1.5.2", + "@backstage/catalog-model": "1.4.3", + "@backstage/cli": "0.25.1", + "@backstage/cli-common": "0.1.13", + "@backstage/cli-node": "0.2.2", + "@backstage/codemods": "0.1.46", + "@backstage/config": "1.1.1", + "@backstage/config-loader": "1.6.1", + "@backstage/core-app-api": "1.11.3", + "@backstage/core-compat-api": "0.1.1", + "@backstage/core-components": "0.13.10", + "@backstage/core-plugin-api": "1.8.2", + "@backstage/create-app": "0.5.9", + "@backstage/dev-utils": "1.0.26", + "e2e-test": "0.2.11", + "@backstage/e2e-test-utils": "0.1.0", + "@backstage/errors": "1.2.3", + "@backstage/eslint-plugin": "0.1.4", + "@backstage/frontend-app-api": "0.5.0", + "@backstage/frontend-plugin-api": "0.5.0", + "@backstage/frontend-test-utils": "0.1.1", + "@backstage/integration": "1.8.0", + "@backstage/integration-aws-node": "0.1.8", + "@backstage/integration-react": "1.1.23", + "@backstage/release-manifests": "0.0.11", + "@backstage/repo-tools": "0.5.2", + "@techdocs/cli": "1.8.1", + "techdocs-cli-embedded-app": "0.2.90", + "@backstage/test-utils": "1.4.7", + "@backstage/theme": "0.5.0", + "@backstage/types": "1.1.1", + "@backstage/version-bridge": "1.0.7", + "@backstage/plugin-adr": "0.6.12", + "@backstage/plugin-adr-backend": "0.4.6", + "@backstage/plugin-adr-common": "0.2.19", + "@backstage/plugin-airbrake": "0.3.29", + "@backstage/plugin-airbrake-backend": "0.3.6", + "@backstage/plugin-allure": "0.1.45", + "@backstage/plugin-analytics-module-ga": "0.1.37", + "@backstage/plugin-analytics-module-ga4": "0.1.8", + "@backstage/plugin-analytics-module-newrelic-browser": "0.0.6", + "@backstage/plugin-apache-airflow": "0.2.19", + "@backstage/plugin-api-docs": "0.10.3", + "@backstage/plugin-api-docs-module-protoc-gen-doc": "0.1.5", + "@backstage/plugin-apollo-explorer": "0.1.19", + "@backstage/plugin-app-backend": "0.3.57", + "@backstage/plugin-app-node": "0.1.9", + "@backstage/plugin-app-visualizer": "0.1.0", + "@backstage/plugin-auth-backend": "0.20.3", + "@backstage/plugin-auth-backend-module-atlassian-provider": "0.1.1", + "@backstage/plugin-auth-backend-module-gcp-iap-provider": "0.2.3", + "@backstage/plugin-auth-backend-module-github-provider": "0.1.6", + "@backstage/plugin-auth-backend-module-gitlab-provider": "0.1.6", + "@backstage/plugin-auth-backend-module-google-provider": "0.1.6", + "@backstage/plugin-auth-backend-module-microsoft-provider": "0.1.4", + "@backstage/plugin-auth-backend-module-oauth2-provider": "0.1.6", + "@backstage/plugin-auth-backend-module-oauth2-proxy-provider": "0.1.1", + "@backstage/plugin-auth-backend-module-okta-provider": "0.0.2", + "@backstage/plugin-auth-backend-module-pinniped-provider": "0.1.3", + "@backstage/plugin-auth-backend-module-vmware-cloud-provider": "0.1.1", + "@backstage/plugin-auth-node": "0.4.3", + "@backstage/plugin-azure-devops": "0.3.11", + "@backstage/plugin-azure-devops-backend": "0.5.1", + "@backstage/plugin-azure-devops-common": "0.3.2", + "@backstage/plugin-azure-sites": "0.1.18", + "@backstage/plugin-azure-sites-backend": "0.1.19", + "@backstage/plugin-azure-sites-common": "0.1.1", + "@backstage/plugin-badges": "0.2.53", + "@backstage/plugin-badges-backend": "0.3.6", + "@backstage/plugin-bazaar": "0.2.21", + "@backstage/plugin-bazaar-backend": "0.3.7", + "@backstage/plugin-bitbucket-cloud-common": "0.2.15", + "@backstage/plugin-bitrise": "0.1.56", + "@backstage/plugin-catalog": "1.16.1", + "@backstage/plugin-catalog-backend": "1.16.1", + "@backstage/plugin-catalog-backend-module-aws": "0.3.3", + "@backstage/plugin-catalog-backend-module-azure": "0.1.28", + "@backstage/plugin-catalog-backend-module-backstage-openapi": "0.1.2", + "@backstage/plugin-catalog-backend-module-bitbucket": "0.2.24", + "@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.1.24", + "@backstage/plugin-catalog-backend-module-bitbucket-server": "0.1.22", + "@backstage/plugin-catalog-backend-module-gcp": "0.1.9", + "@backstage/plugin-catalog-backend-module-gerrit": "0.1.25", + "@backstage/plugin-catalog-backend-module-github": "0.4.7", + "@backstage/plugin-catalog-backend-module-github-org": "0.1.3", + "@backstage/plugin-catalog-backend-module-gitlab": "0.3.6", + "@backstage/plugin-catalog-backend-module-incremental-ingestion": "0.4.13", + "@backstage/plugin-catalog-backend-module-ldap": "0.5.24", + "@backstage/plugin-catalog-backend-module-msgraph": "0.5.16", + "@backstage/plugin-catalog-backend-module-openapi": "0.1.26", + "@backstage/plugin-catalog-backend-module-puppetdb": "0.1.14", + "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "0.1.6", + "@backstage/plugin-catalog-backend-module-unprocessed": "0.3.6", + "@backstage/plugin-catalog-common": "1.0.20", + "@backstage/plugin-catalog-graph": "0.3.3", + "@backstage/plugin-catalog-import": "0.10.5", + "@backstage/plugin-catalog-node": "1.6.1", + "@backstage/plugin-catalog-react": "1.9.3", + "@backstage/plugin-catalog-unprocessed-entities": "0.1.7", + "@backstage/plugin-cicd-statistics": "0.1.31", + "@backstage/plugin-cicd-statistics-module-gitlab": "0.1.25", + "@backstage/plugin-circleci": "0.3.29", + "@backstage/plugin-cloudbuild": "0.3.29", + "@backstage/plugin-code-climate": "0.1.29", + "@backstage/plugin-code-coverage": "0.2.22", + "@backstage/plugin-code-coverage-backend": "0.2.23", + "@backstage/plugin-codescene": "0.1.21", + "@backstage/plugin-config-schema": "0.1.49", + "@backstage/plugin-cost-insights": "0.12.18", + "@backstage/plugin-cost-insights-common": "0.1.2", + "@backstage/plugin-devtools": "0.1.8", + "@backstage/plugin-devtools-backend": "0.2.6", + "@backstage/plugin-devtools-common": "0.1.8", + "@backstage/plugin-dynatrace": "8.0.3", + "@backstage/plugin-entity-feedback": "0.2.12", + "@backstage/plugin-entity-feedback-backend": "0.2.6", + "@backstage/plugin-entity-feedback-common": "0.1.3", + "@backstage/plugin-entity-validation": "0.1.14", + "@backstage/plugin-events-backend": "0.2.18", + "@backstage/plugin-events-backend-module-aws-sqs": "0.2.12", + "@backstage/plugin-events-backend-module-azure": "0.1.19", + "@backstage/plugin-events-backend-module-bitbucket-cloud": "0.1.19", + "@backstage/plugin-events-backend-module-gerrit": "0.1.19", + "@backstage/plugin-events-backend-module-github": "0.1.19", + "@backstage/plugin-events-backend-module-gitlab": "0.1.19", + "@backstage/plugin-events-backend-test-utils": "0.1.19", + "@backstage/plugin-events-node": "0.2.18", + "@internal/plugin-todo-list": "1.0.21", + "@internal/plugin-todo-list-backend": "1.0.21", + "@internal/plugin-todo-list-common": "1.0.17", + "@backstage/plugin-explore": "0.4.15", + "@backstage/plugin-explore-backend": "0.0.19", + "@backstage/plugin-explore-common": "0.0.2", + "@backstage/plugin-explore-react": "0.0.35", + "@backstage/plugin-firehydrant": "0.2.13", + "@backstage/plugin-fossa": "0.2.61", + "@backstage/plugin-gcalendar": "0.3.22", + "@backstage/plugin-gcp-projects": "0.3.45", + "@backstage/plugin-git-release-manager": "0.3.41", + "@backstage/plugin-github-actions": "0.6.10", + "@backstage/plugin-github-deployments": "0.1.60", + "@backstage/plugin-github-issues": "0.2.18", + "@backstage/plugin-github-pull-requests-board": "0.1.23", + "@backstage/plugin-gitops-profiles": "0.3.44", + "@backstage/plugin-gocd": "0.1.35", + "@backstage/plugin-graphiql": "0.3.2", + "@backstage/plugin-graphql-voyager": "0.1.11", + "@backstage/plugin-home": "0.6.1", + "@backstage/plugin-home-react": "0.1.7", + "@backstage/plugin-ilert": "0.2.18", + "@backstage/plugin-jenkins": "0.9.4", + "@backstage/plugin-jenkins-backend": "0.3.3", + "@backstage/plugin-jenkins-common": "0.1.23", + "@backstage/plugin-kafka": "0.3.29", + "@backstage/plugin-kafka-backend": "0.3.7", + "@backstage/plugin-kubernetes": "0.11.4", + "@backstage/plugin-kubernetes-backend": "0.14.1", + "@backstage/plugin-kubernetes-cluster": "0.0.5", + "@backstage/plugin-kubernetes-common": "0.7.3", + "@backstage/plugin-kubernetes-node": "0.1.3", + "@backstage/plugin-kubernetes-react": "0.2.1", + "@backstage/plugin-lighthouse": "0.4.14", + "@backstage/plugin-lighthouse-backend": "0.4.1", + "@backstage/plugin-lighthouse-common": "0.1.4", + "@backstage/plugin-linguist": "0.1.14", + "@backstage/plugin-linguist-backend": "0.5.6", + "@backstage/plugin-linguist-common": "0.1.2", + "@backstage/plugin-microsoft-calendar": "0.1.11", + "@backstage/plugin-newrelic": "0.3.44", + "@backstage/plugin-newrelic-dashboard": "0.3.4", + "@backstage/plugin-nomad": "0.1.10", + "@backstage/plugin-nomad-backend": "0.1.11", + "@backstage/plugin-octopus-deploy": "0.2.11", + "@backstage/plugin-opencost": "0.2.4", + "@backstage/plugin-org": "0.6.19", + "@backstage/plugin-org-react": "0.1.18", + "@backstage/plugin-pagerduty": "0.7.1", + "@backstage/plugin-periskop": "0.1.27", + "@backstage/plugin-periskop-backend": "0.2.7", + "@backstage/plugin-permission-backend": "0.5.32", + "@backstage/plugin-permission-backend-module-allow-all-policy": "0.1.6", + "@backstage/plugin-permission-common": "0.7.12", + "@backstage/plugin-permission-node": "0.7.20", + "@backstage/plugin-permission-react": "0.4.19", + "@backstage/plugin-playlist": "0.2.3", + "@backstage/plugin-playlist-backend": "0.3.13", + "@backstage/plugin-playlist-common": "0.1.14", + "@backstage/plugin-proxy-backend": "0.4.7", + "@backstage/plugin-puppetdb": "0.1.12", + "@backstage/plugin-rollbar": "0.4.29", + "@backstage/plugin-rollbar-backend": "0.1.54", + "@backstage/plugin-scaffolder": "1.17.1", + "@backstage/plugin-scaffolder-backend": "1.20.0", + "@backstage/plugin-scaffolder-backend-module-azure": "0.1.1", + "@backstage/plugin-scaffolder-backend-module-bitbucket": "0.1.1", + "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown": "0.2.10", + "@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.2.33", + "@backstage/plugin-scaffolder-backend-module-gerrit": "0.1.1", + "@backstage/plugin-scaffolder-backend-module-github": "0.1.1", + "@backstage/plugin-scaffolder-backend-module-gitlab": "0.2.12", + "@backstage/plugin-scaffolder-backend-module-rails": "0.4.26", + "@backstage/plugin-scaffolder-backend-module-sentry": "0.1.17", + "@backstage/plugin-scaffolder-backend-module-yeoman": "0.2.30", + "@backstage/plugin-scaffolder-common": "1.4.5", + "@backstage/plugin-scaffolder-node": "0.2.10", + "@backstage/plugin-scaffolder-react": "1.7.1", + "@backstage/plugin-search": "1.4.5", + "@backstage/plugin-search-backend": "1.4.9", + "@backstage/plugin-search-backend-module-catalog": "0.1.13", + "@backstage/plugin-search-backend-module-elasticsearch": "1.3.12", + "@backstage/plugin-search-backend-module-explore": "0.1.13", + "@backstage/plugin-search-backend-module-pg": "0.5.18", + "@backstage/plugin-search-backend-module-stack-overflow-collator": "0.1.2", + "@backstage/plugin-search-backend-module-techdocs": "0.1.13", + "@backstage/plugin-search-backend-node": "1.2.13", + "@backstage/plugin-search-common": "1.2.10", + "@backstage/plugin-search-react": "1.7.5", + "@backstage/plugin-sentry": "0.5.14", + "@backstage/plugin-shortcuts": "0.3.18", + "@backstage/plugin-sonarqube": "0.7.11", + "@backstage/plugin-sonarqube-backend": "0.2.11", + "@backstage/plugin-sonarqube-react": "0.1.12", + "@backstage/plugin-splunk-on-call": "0.4.18", + "@backstage/plugin-stack-overflow": "0.1.24", + "@backstage/plugin-stack-overflow-backend": "0.2.13", + "@backstage/plugin-stackstorm": "0.1.10", + "@backstage/plugin-tech-insights": "0.3.21", + "@backstage/plugin-tech-insights-backend": "0.5.23", + "@backstage/plugin-tech-insights-backend-module-jsonfc": "0.1.41", + "@backstage/plugin-tech-insights-common": "0.2.12", + "@backstage/plugin-tech-insights-node": "0.4.15", + "@backstage/plugin-tech-radar": "0.6.12", + "@backstage/plugin-techdocs": "1.9.3", + "@backstage/plugin-techdocs-addons-test-utils": "1.0.26", + "@backstage/plugin-techdocs-backend": "1.9.2", + "@backstage/plugin-techdocs-module-addons-contrib": "1.1.4", + "@backstage/plugin-techdocs-node": "1.11.1", + "@backstage/plugin-techdocs-react": "1.1.15", + "@backstage/plugin-todo": "0.2.33", + "@backstage/plugin-todo-backend": "0.3.7", + "@backstage/plugin-user-settings": "0.8.0", + "@backstage/plugin-user-settings-backend": "0.2.8", + "@backstage/plugin-vault": "0.1.24", + "@backstage/plugin-vault-backend": "0.4.2", + "@backstage/plugin-vault-node": "0.1.2", + "@backstage/plugin-xcmetrics": "0.2.47" + }, + "changesets": [] +} From 477e98bbb693d2bbdb7408282ec3a4f83fb60842 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 10:38:06 +0000 Subject: [PATCH 097/283] chore(deps): update dependency @types/react to v18.2.48 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4776685b58..fa2e9a3850 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18596,13 +18596,13 @@ __metadata: linkType: hard "@types/react@npm:^18": - version: 18.2.46 - resolution: "@types/react@npm:18.2.46" + version: 18.2.48 + resolution: "@types/react@npm:18.2.48" dependencies: "@types/prop-types": "*" "@types/scheduler": "*" csstype: ^3.0.2 - checksum: cb0e4dc7f41988a059e1246a19ec377101f5b16097ec4bf7000ef3c431ec0c8c873f40e95075821f908db1f4e3352775f0f18cea53dcad14dce67c0f5110f2bd + checksum: c9ca43ed2995389b7e09492c24e6f911a8439bb8276dd17cc66a2fbebbf0b42daf7b2ad177043256533607c2ca644d7d928fdfce37a67af1f8646d2bac988900 languageName: node linkType: hard From c1831807c26f8c0a852ea0bdde29b31de8de8f5f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 10:38:38 +0000 Subject: [PATCH 098/283] chore(deps): update dependency nodemon to v3.0.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4776685b58..418240b1a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34936,8 +34936,8 @@ __metadata: linkType: hard "nodemon@npm:^3.0.1": - version: 3.0.2 - resolution: "nodemon@npm:3.0.2" + version: 3.0.3 + resolution: "nodemon@npm:3.0.3" dependencies: chokidar: ^3.5.2 debug: ^4 @@ -34951,7 +34951,7 @@ __metadata: undefsafe: ^2.0.5 bin: nodemon: bin/nodemon.js - checksum: 61f3dd207ad444f4a7a2f1aa44adc886605c96c7bc6286291c2360e5e2cd26c3828c90a1418a60783a9da2463593383149135a5a4c099918c54d34a611745499 + checksum: 121ebb6349167d87cefd5767ec453ceb49ec5a8d50146134a54b0e25502c29ad01caaa41460e303b35728439012564782d278b3fef3c615f3c278979c2b7d586 languageName: node linkType: hard From adca7294f29b823aa713667fbdd7787b62fb1885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 17 Jan 2024 12:06:41 +0100 Subject: [PATCH 099/283] Update plugins/azure-devops-backend/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- plugins/azure-devops-backend/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/azure-devops-backend/README.md b/plugins/azure-devops-backend/README.md index b529faf8a6..bc23c58871 100644 --- a/plugins/azure-devops-backend/README.md +++ b/plugins/azure-devops-backend/README.md @@ -23,7 +23,7 @@ Configuration Details: - `AZURE_TOKEN` environment variable must be set to a [Personal Access Token](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=preview-page) with read access to both Code and Build - `organization` is your Azure DevOps Services (cloud) Organization name or for Azure DevOps Server (on-premise) this will be your Collection name -#### Multi Organization & Service Principles +#### Multi Organization & Service Principals To support cases where you have multiple Azure DevOps organizations and/or you want to use a Service Principle you will want to make sure to configure them in the `integrations.azure` section of your `app-config.yaml` as detailed in the [Azure DevOps Locations](https://backstage.io/docs/integrations/azure/locations) documentation. From 3603867fdbb8d9f2c93f1f7e2a092d75ae8923d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 17 Jan 2024 12:06:46 +0100 Subject: [PATCH 100/283] Update plugins/azure-devops-backend/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- plugins/azure-devops-backend/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/azure-devops-backend/README.md b/plugins/azure-devops-backend/README.md index bc23c58871..0066e43856 100644 --- a/plugins/azure-devops-backend/README.md +++ b/plugins/azure-devops-backend/README.md @@ -25,7 +25,7 @@ Configuration Details: #### Multi Organization & Service Principals -To support cases where you have multiple Azure DevOps organizations and/or you want to use a Service Principle you will want to make sure to configure them in the `integrations.azure` section of your `app-config.yaml` as detailed in the [Azure DevOps Locations](https://backstage.io/docs/integrations/azure/locations) documentation. +To support cases where you have multiple Azure DevOps organizations and/or you want to use a Service Principal you will want to make sure to configure them in the `integrations.azure` section of your `app-config.yaml` as detailed in the [Azure DevOps Locations](https://backstage.io/docs/integrations/azure/locations) documentation. **Note:** You will still need to define the [configuration above](#configuration). From 69cc5b113734faab53325743ace0cd6d71c1dc34 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 11:16:07 +0000 Subject: [PATCH 101/283] chore(deps): update dependency supertest to v6.3.4 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4776685b58..9f1e0f35eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -41540,9 +41540,9 @@ __metadata: languageName: node linkType: hard -"superagent@npm:^8.0.5": - version: 8.0.9 - resolution: "superagent@npm:8.0.9" +"superagent@npm:^8.1.2": + version: 8.1.2 + resolution: "superagent@npm:8.1.2" dependencies: component-emitter: ^1.3.0 cookiejar: ^2.1.4 @@ -41554,17 +41554,17 @@ __metadata: mime: 2.6.0 qs: ^6.11.0 semver: ^7.3.8 - checksum: 5d00cdc7ceb5570663da80604965750e6b1b8d7d7442b7791e285c62bcd8d578a8ead0242a2426432b59a255fb42eb3a196d636157538a1392e7b6c5f1624810 + checksum: f3601c5ccae34d5ba684a03703394b5d25931f4ae2e1e31a1de809f88a9400e997ece037f9accf148a21c408f950dc829db1e4e23576a7f9fe0efa79fd5c9d2f languageName: node linkType: hard "supertest@npm:^6.1.3, supertest@npm:^6.1.6, supertest@npm:^6.2.4, supertest@npm:^6.3.3": - version: 6.3.3 - resolution: "supertest@npm:6.3.3" + version: 6.3.4 + resolution: "supertest@npm:6.3.4" dependencies: methods: ^1.1.2 - superagent: ^8.0.5 - checksum: 38239e517f7ba62b7a139a79c5c48d55f8d67b5ff4b6e51d5b07732ca8bbc4a28ffa1b10916fbb403dd013a054dbf028edc5850057d9a43aecbff439d494673e + superagent: ^8.1.2 + checksum: 875c6fa7940f21e5be9bb646579cdb030d4057bf2da643e125e1f0480add1200395d2b17e10b8e54e1009efc63e047422501e9eb30e12828668498c0910f295f languageName: node linkType: hard From e6a349c5796cc811d45e5a8573805cba83eff5ef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 11:16:43 +0000 Subject: [PATCH 102/283] fix(deps): update dependency @google-cloud/container to v5.4.1 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4776685b58..c895431c7a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10982,11 +10982,11 @@ __metadata: linkType: hard "@google-cloud/container@npm:^5.0.0": - version: 5.4.0 - resolution: "@google-cloud/container@npm:5.4.0" + version: 5.4.1 + resolution: "@google-cloud/container@npm:5.4.1" dependencies: google-gax: ^4.0.3 - checksum: ab6a6f0d6e6dc7feb30c848f40109ada5464c2594d9bbb467dbd522e097f0dc1108d366becfae268831d0ca203fa06dcedf28014d4d9161838bb2bb550162465 + checksum: 93f06b3171805c85d2ec8fa959e3caa147f1560da5c90082e23e1ccbd6ef88756e3271dbf3db139fefaa48874222f7e9e4a7dc5fb7da54a2e7ecd80db472ecf7 languageName: node linkType: hard From a7e2ec8752d2ef638e17164f89d92826a757bf07 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 12:14:21 +0000 Subject: [PATCH 103/283] fix(deps): update dependency @swc/core to v1.3.104 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- microsite/yarn.lock | 86 ++++++++++++++++++++++----------------------- storybook/yarn.lock | 86 ++++++++++++++++++++++----------------------- yarn.lock | 86 ++++++++++++++++++++++----------------------- 3 files changed, 129 insertions(+), 129 deletions(-) diff --git a/microsite/yarn.lock b/microsite/yarn.lock index 36c4f4bdac..5e976cce69 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -2701,90 +2701,90 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-darwin-arm64@npm:1.3.102" +"@swc/core-darwin-arm64@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-darwin-arm64@npm:1.3.104" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-darwin-x64@npm:1.3.102" +"@swc/core-darwin-x64@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-darwin-x64@npm:1.3.104" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.102" +"@swc/core-linux-arm-gnueabihf@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.104" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-linux-arm64-gnu@npm:1.3.102" +"@swc/core-linux-arm64-gnu@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.104" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-linux-arm64-musl@npm:1.3.102" +"@swc/core-linux-arm64-musl@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.104" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-linux-x64-gnu@npm:1.3.102" +"@swc/core-linux-x64-gnu@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.104" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-linux-x64-musl@npm:1.3.102" +"@swc/core-linux-x64-musl@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-linux-x64-musl@npm:1.3.104" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-win32-arm64-msvc@npm:1.3.102" +"@swc/core-win32-arm64-msvc@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.104" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-win32-ia32-msvc@npm:1.3.102" +"@swc/core-win32-ia32-msvc@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.104" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-win32-x64-msvc@npm:1.3.102" +"@swc/core-win32-x64-msvc@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.104" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.3.102 - resolution: "@swc/core@npm:1.3.102" + version: 1.3.104 + resolution: "@swc/core@npm:1.3.104" dependencies: - "@swc/core-darwin-arm64": 1.3.102 - "@swc/core-darwin-x64": 1.3.102 - "@swc/core-linux-arm-gnueabihf": 1.3.102 - "@swc/core-linux-arm64-gnu": 1.3.102 - "@swc/core-linux-arm64-musl": 1.3.102 - "@swc/core-linux-x64-gnu": 1.3.102 - "@swc/core-linux-x64-musl": 1.3.102 - "@swc/core-win32-arm64-msvc": 1.3.102 - "@swc/core-win32-ia32-msvc": 1.3.102 - "@swc/core-win32-x64-msvc": 1.3.102 + "@swc/core-darwin-arm64": 1.3.104 + "@swc/core-darwin-x64": 1.3.104 + "@swc/core-linux-arm-gnueabihf": 1.3.104 + "@swc/core-linux-arm64-gnu": 1.3.104 + "@swc/core-linux-arm64-musl": 1.3.104 + "@swc/core-linux-x64-gnu": 1.3.104 + "@swc/core-linux-x64-musl": 1.3.104 + "@swc/core-win32-arm64-msvc": 1.3.104 + "@swc/core-win32-ia32-msvc": 1.3.104 + "@swc/core-win32-x64-msvc": 1.3.104 "@swc/counter": ^0.1.1 "@swc/types": ^0.1.5 peerDependencies: @@ -2813,7 +2813,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: 45c0edb06f87a811e28fb3ed587fbe6b7ca67ff2440fe15666d43729788903a4af61e3b57842aecc0b2b70e3c9981b698d8233746ba94dfb5a19e1c62eea33ad + checksum: 95fbf1412c8685d311cf2d7efbfa43e082d2d9e84ece48c4d8d96d6c67c5923569bfb26352451eb3e4d98adcb556dcfac65271c0fba77f078bb755fe2f64b295 languageName: node linkType: hard diff --git a/storybook/yarn.lock b/storybook/yarn.lock index 5c3f333454..0be4de1f7f 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -2842,90 +2842,90 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-darwin-arm64@npm:1.3.102" +"@swc/core-darwin-arm64@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-darwin-arm64@npm:1.3.104" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-darwin-x64@npm:1.3.102" +"@swc/core-darwin-x64@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-darwin-x64@npm:1.3.104" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.102" +"@swc/core-linux-arm-gnueabihf@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.104" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-linux-arm64-gnu@npm:1.3.102" +"@swc/core-linux-arm64-gnu@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.104" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-linux-arm64-musl@npm:1.3.102" +"@swc/core-linux-arm64-musl@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.104" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-linux-x64-gnu@npm:1.3.102" +"@swc/core-linux-x64-gnu@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.104" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-linux-x64-musl@npm:1.3.102" +"@swc/core-linux-x64-musl@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-linux-x64-musl@npm:1.3.104" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-win32-arm64-msvc@npm:1.3.102" +"@swc/core-win32-arm64-msvc@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.104" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-win32-ia32-msvc@npm:1.3.102" +"@swc/core-win32-ia32-msvc@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.104" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-win32-x64-msvc@npm:1.3.102" +"@swc/core-win32-x64-msvc@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.104" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.3.102 - resolution: "@swc/core@npm:1.3.102" + version: 1.3.104 + resolution: "@swc/core@npm:1.3.104" dependencies: - "@swc/core-darwin-arm64": 1.3.102 - "@swc/core-darwin-x64": 1.3.102 - "@swc/core-linux-arm-gnueabihf": 1.3.102 - "@swc/core-linux-arm64-gnu": 1.3.102 - "@swc/core-linux-arm64-musl": 1.3.102 - "@swc/core-linux-x64-gnu": 1.3.102 - "@swc/core-linux-x64-musl": 1.3.102 - "@swc/core-win32-arm64-msvc": 1.3.102 - "@swc/core-win32-ia32-msvc": 1.3.102 - "@swc/core-win32-x64-msvc": 1.3.102 + "@swc/core-darwin-arm64": 1.3.104 + "@swc/core-darwin-x64": 1.3.104 + "@swc/core-linux-arm-gnueabihf": 1.3.104 + "@swc/core-linux-arm64-gnu": 1.3.104 + "@swc/core-linux-arm64-musl": 1.3.104 + "@swc/core-linux-x64-gnu": 1.3.104 + "@swc/core-linux-x64-musl": 1.3.104 + "@swc/core-win32-arm64-msvc": 1.3.104 + "@swc/core-win32-ia32-msvc": 1.3.104 + "@swc/core-win32-x64-msvc": 1.3.104 "@swc/counter": ^0.1.1 "@swc/types": ^0.1.5 peerDependencies: @@ -2954,7 +2954,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: 45c0edb06f87a811e28fb3ed587fbe6b7ca67ff2440fe15666d43729788903a4af61e3b57842aecc0b2b70e3c9981b698d8233746ba94dfb5a19e1c62eea33ad + checksum: 95fbf1412c8685d311cf2d7efbfa43e082d2d9e84ece48c4d8d96d6c67c5923569bfb26352451eb3e4d98adcb556dcfac65271c0fba77f078bb755fe2f64b295 languageName: node linkType: hard diff --git a/yarn.lock b/yarn.lock index 4776685b58..5c78ed8aa6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16769,90 +16769,90 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-darwin-arm64@npm:1.3.102" +"@swc/core-darwin-arm64@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-darwin-arm64@npm:1.3.104" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-darwin-x64@npm:1.3.102" +"@swc/core-darwin-x64@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-darwin-x64@npm:1.3.104" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.102" +"@swc/core-linux-arm-gnueabihf@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.104" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-linux-arm64-gnu@npm:1.3.102" +"@swc/core-linux-arm64-gnu@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.104" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-linux-arm64-musl@npm:1.3.102" +"@swc/core-linux-arm64-musl@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.104" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-linux-x64-gnu@npm:1.3.102" +"@swc/core-linux-x64-gnu@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.104" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-linux-x64-musl@npm:1.3.102" +"@swc/core-linux-x64-musl@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-linux-x64-musl@npm:1.3.104" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-win32-arm64-msvc@npm:1.3.102" +"@swc/core-win32-arm64-msvc@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.104" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-win32-ia32-msvc@npm:1.3.102" +"@swc/core-win32-ia32-msvc@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.104" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.3.102": - version: 1.3.102 - resolution: "@swc/core-win32-x64-msvc@npm:1.3.102" +"@swc/core-win32-x64-msvc@npm:1.3.104": + version: 1.3.104 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.104" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.3.102 - resolution: "@swc/core@npm:1.3.102" + version: 1.3.104 + resolution: "@swc/core@npm:1.3.104" dependencies: - "@swc/core-darwin-arm64": 1.3.102 - "@swc/core-darwin-x64": 1.3.102 - "@swc/core-linux-arm-gnueabihf": 1.3.102 - "@swc/core-linux-arm64-gnu": 1.3.102 - "@swc/core-linux-arm64-musl": 1.3.102 - "@swc/core-linux-x64-gnu": 1.3.102 - "@swc/core-linux-x64-musl": 1.3.102 - "@swc/core-win32-arm64-msvc": 1.3.102 - "@swc/core-win32-ia32-msvc": 1.3.102 - "@swc/core-win32-x64-msvc": 1.3.102 + "@swc/core-darwin-arm64": 1.3.104 + "@swc/core-darwin-x64": 1.3.104 + "@swc/core-linux-arm-gnueabihf": 1.3.104 + "@swc/core-linux-arm64-gnu": 1.3.104 + "@swc/core-linux-arm64-musl": 1.3.104 + "@swc/core-linux-x64-gnu": 1.3.104 + "@swc/core-linux-x64-musl": 1.3.104 + "@swc/core-win32-arm64-msvc": 1.3.104 + "@swc/core-win32-ia32-msvc": 1.3.104 + "@swc/core-win32-x64-msvc": 1.3.104 "@swc/counter": ^0.1.1 "@swc/types": ^0.1.5 peerDependencies: @@ -16881,7 +16881,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: 45c0edb06f87a811e28fb3ed587fbe6b7ca67ff2440fe15666d43729788903a4af61e3b57842aecc0b2b70e3c9981b698d8233746ba94dfb5a19e1c62eea33ad + checksum: 95fbf1412c8685d311cf2d7efbfa43e082d2d9e84ece48c4d8d96d6c67c5923569bfb26352451eb3e4d98adcb556dcfac65271c0fba77f078bb755fe2f64b295 languageName: node linkType: hard From e7d516ef375314f7b9d022658cb0c8c816e1482c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 12:15:20 +0000 Subject: [PATCH 104/283] fix(deps): update dependency @types/node-fetch to v2.6.11 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4776685b58..b4e20d6361 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18224,12 +18224,12 @@ __metadata: linkType: hard "@types/node-fetch@npm:^2.5.0, @types/node-fetch@npm:^2.5.12, @types/node-fetch@npm:^2.5.7": - version: 2.6.10 - resolution: "@types/node-fetch@npm:2.6.10" + version: 2.6.11 + resolution: "@types/node-fetch@npm:2.6.11" dependencies: "@types/node": "*" form-data: ^4.0.0 - checksum: e0c9a6023752ff6c744a33a3045b9adb11fd1882997ef891bf7ce91f937ddab91c0acee4c8e806a8a5aec0e8d8c132709141e8512fec28030d7cc9ef92c7ff1e + checksum: 180e4d44c432839bdf8a25251ef8c47d51e37355ddd78c64695225de8bc5dc2b50b7bb855956d471c026bb84bd7295688a0960085e7158cbbba803053492568b languageName: node linkType: hard From 60d459822d327ac2ea95d3155c2e6cadb94b939c Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 17 Jan 2024 13:19:30 +0100 Subject: [PATCH 105/283] chore: fix prettier Signed-off-by: blam --- docs/local-dev/debugging.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/local-dev/debugging.md b/docs/local-dev/debugging.md index 3de09b0108..39981f2e54 100644 --- a/docs/local-dev/debugging.md +++ b/docs/local-dev/debugging.md @@ -79,12 +79,12 @@ Run configurations enable the use of debugging functionality such as steppers an 1. Select `Edit Configurations` in the `Run` dropdown menu. Click the plus sign to add a new configuration, then select `Node.js`. -3. In `Working directory`, input `{PROJECT_DIR}/packages/backend`. +2. In `Working directory`, input `{PROJECT_DIR}/packages/backend`. Replace `{PROJECT_DIR}` with the path to your Backstage repo. -4. In `JavaScript file`, input `{PROJECT_DIR}/node_modules/@backstage/cli/bin/backstage-cli`. +3. In `JavaScript file`, input `{PROJECT_DIR}/node_modules/@backstage/cli/bin/backstage-cli`. Replace `{PROJECT_DIR}` with the path to your Backstage repo. -5. In `Application parameters`, input `package start`. -6. Optionally, for `Environment Variables`, input `LOG_LEVEL=debug`. -7. Click `Apply` to save the changes. -8. With the newly-created configuration selected, use the `Run` or `Debug` icons on the +4. In `Application parameters`, input `package start`. +5. Optionally, for `Environment Variables`, input `LOG_LEVEL=debug`. +6. Click `Apply` to save the changes. +7. With the newly-created configuration selected, use the `Run` or `Debug` icons on the toolbar to execute the newly created configuration. From 545f90747fd13a2614042f6a3bea67a023e29719 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 13:11:42 +0000 Subject: [PATCH 106/283] fix(deps): update dependency axios to v1.6.5 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index b9ab306f65..05651b3509 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20812,13 +20812,13 @@ __metadata: linkType: hard "axios@npm:^1.4.0, axios@npm:^1.6.0": - version: 1.6.4 - resolution: "axios@npm:1.6.4" + version: 1.6.5 + resolution: "axios@npm:1.6.5" dependencies: follow-redirects: ^1.15.4 form-data: ^4.0.0 proxy-from-env: ^1.1.0 - checksum: 48d8af8488ac7402fae312437c0189b3b609a472fca2f7fc796129c804d98520589b6317096eba8509711d49f855a3f620b6a24ff23acd73ac26433d0383b8f9 + checksum: e28d67b2d9134cb4608c44d8068b0678cfdccc652742e619006f27264a30c7aba13b2cd19c6f1f52ae195b5232734925928fb192d5c85feea7edd2f273df206d languageName: node linkType: hard From b738048bb52ce8a731edd6504c6483568edb14df Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 13:12:16 +0000 Subject: [PATCH 107/283] fix(deps): update dependency eslint-plugin-jest to v27.6.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index b9ab306f65..350a7b6305 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25765,8 +25765,8 @@ __metadata: linkType: hard "eslint-plugin-jest@npm:^27.0.0": - version: 27.6.1 - resolution: "eslint-plugin-jest@npm:27.6.1" + version: 27.6.3 + resolution: "eslint-plugin-jest@npm:27.6.3" dependencies: "@typescript-eslint/utils": ^5.10.0 peerDependencies: @@ -25778,7 +25778,7 @@ __metadata: optional: true jest: optional: true - checksum: 03dc4784119a06504718b3ec1a5944c8d41fe73669d23433fa794e4059be857ec463da6d5982dcd2920da091fe7c5c033fa69a91f4dfbe3f41aac6db99b8c3d0 + checksum: e22e8dbd941b34bb95958f035ffabb94114506b294e74d6e411bc85bc9dc57888ffd3ebb5c28316a8b7cc9d391cca35557acc64bf815f48d1dcc5ea3d28fa43a languageName: node linkType: hard From f369994ef6569d05d790d9164da28d0cf2d9fc25 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 14 Dec 2023 16:12:18 +0100 Subject: [PATCH 108/283] docs: start drafting new route system Signed-off-by: Camila Belo --- .../frontend-system/architecture/07-routes.md | 457 ++++++++++++++---- 1 file changed, 367 insertions(+), 90 deletions(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 1402796077..b38ef9016c 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -8,143 +8,420 @@ description: Frontend routes > **NOTE: The new frontend system is in alpha and is only supported by a small number of plugins.** -See [routing system docs](../../plugins/composability.md#routing-system) - ## Introduction - +The composability system isn't a single API surface. It is a collection of patterns, primitives, and APIs. At the core is the concept of extensions, which are exported by plugins for use in the app. One of the concepts is `RouteRef` which enables us route between pages in a flexible way, and it is especially important when bringing together different open source plugins. ## Route References - +There are 3 types of route references: regular route, sub route, and external route, and we will cover both the concept and code definition for each. Keep reading 🙂! ### Creating a Route Reference - +```tsx +// plugins/catalog/src/routes.ts +import { createRouteRef } from '@backstage/frontend-plugin-api'; -### Using a Route Reference +export const rootRouteRef = createRouteRef(); +``` - +Note that you almost always want to create the route references themselves in a different file than the one that creates the plugin instance, for example a top-level routes.ts. This is to avoid circular imports when you use the route references from other parts of the same plugin. ### Route Path Parameters - +The referenced route can also accepts `params`. Here is how you create a reference for a route that requires a kind, namespace and name `params`, like in this path `/entities/:name/:namespace/:kind`: + +```tsx +// plugins/catalog/src/routes.ts +import { createRouteRef } from '@backstage/frontend-plugin-api'; + +type DetailsRouteParams = { namespace: string; name: string; kind: string }; + +export const detailsRouteRef = createRouteRef({ + // A list of parameter names that the path that this route ref is bound to must contain + params: ['namespace', 'name', 'kind'], +}); +``` ### Providing Route References to Plugins - +Route refs do not have any behavior, in other words, they are an opaque type that represents route targets in an app, which are bound to specific paths at runtime, but they provide a level of indirection to help mix together different plugins that otherwise wouldn't know how to route to each other. + +The code snippet of the previous section does not indicate which plugin the route belongs to. To do so, we have to extend Backstage with a new page extension associated with the newly created `RouteRef` and provide the extension through our plugin. Here's what we need to do: + +```tsx +// plugins/catalog/src/routes.ts +import { createRouteRef } from '@backstage/frontend-plugin-api'; + +const rootRouteRef = createRouteRef(); // [1] + +// plugins/catalog/src/plugin.tsx +import { createPlugin, createPageExtension } from '@backstage/frontend-plugin-api'; +import { rootRouteRef } from './routes'; + +const rootPage = createPageExtension({ // [2] + // Ommiting name since it is the root page + defaultPath: '/' + routeRef: rootRouteRef, + loader: async () => Root Page +}); + +export default const createPlugin({ // [3] + id: 'catalog', + routes: { + root: rootRouteRef, + }, + extensions: [rootPage] +}); + +// plugins/catalog/src/index.ts +export { default } from './plugin' +``` + +We have completed our journey of creating a plugin page route. This is what the code does: + +- [1] The line 1 creates a route reference, which is not yet associated with any plugin page; +- [2] A route that renders nothing makes no sense, does it? So we are creating a page extension that associates a path and a component with the newly created route ref; +- [3] Finally, our plugin provides both routes and extensions. + +It's a smart question, and the answer can be found in the (Binding External Route References)[#building-external-route-references] section, wait a bit, keep reading and you'll understand why. + +### Using a Route Reference + +You can link to the routes from other pages in the same plugin or you can also link between different plugins pages. In this section we will cover the first scenario, if you are interested in link to a page of a plugin that isn't yours, please go to the [external routes](#external-router-references) section below. + +Alright, let's presume that we have a plugin that renders tow different pages, and these pages links to each other. + +First lets create the routes references: + +```tsx +// plugins/catalog/src/routes.ts +import { createRouteRef } from '@backstage/frontend-plugin-api'; + +const rootRouteRef = createRouteRef(); + +type DetailsRouteParams = { + namespace: string; + name: string; + kind: string; +}; + +export const detailsRouteRef = createRouteRef({ + // A list of parameter names that the path that this route ref is bound to must contain + params: ['namespace', 'name', 'kind'], +}); +``` + +Now we are ready to provide these routes via plugin extensions and link between pages: + +```tsx +// plugins/catalog/src/plugin.tsx +import { createPlugin, createPageExtension, useRouteRef } from '@backstage/frontend-plugin-api'; +import { rootRouteRef, detailsRouteRef } from './routes'; + +const rootPage = createPageExtension({ + // Ommiting name since it is the root page + defaultPath: '/' + routeRef: rootRouteRef, + loader: async () => { + const href = useRouteRef(catalogEntityDetailsRouteRef)({ + kind: 'Component', + namespace: 'Default', + name: 'foo' + }); + + return ( +
+

Index Page

+ Entity Foo +
+ ); + } +}); + +const detailsPage = createPageExtension({ + name: 'details', + defaultPath: '/entities/:namespace/:kind/:name' + routeRef: detailsRouteRef, + loader: async () => ( +
+

Catalog Entities

+
+ ) +}); + +export default const createPlugin({ + id: 'catalog', + routes: { + list: catalogEntityListRouteRef, + details: catalogEntityDetailsRouteRef, + }, + extensions: [rootPage, detailsPage] +}); + +// plugins/catalog/src/index.ts +export { default } from './plugin' +``` + +During runtime, we used a hook `useRouteRef` to get the path to the details page. Because we are linking to pages of the same plugin, we are currently accessing the reference directly, but in the following sections, you will see how to link to pages of different plugins. ## External Router References - +```tsx +// plugins/catalog/src/routes.ts +import { + createRouteRef, + createExternalRouteRef, +} from '@backstage/frontend-plugin-api'; + +const rootRouteRef = createRouteRef(); +const createComponentRouteRef = createExternalRouteRef(); + +// plugins/catalog/src/plugin.tsx +import { createPlugin, createPageExtension, useRouteRef } from '@backstage/frontend-plugin-api'; +import { rootRouteRef, createComponentRouteRef } from './routes'; + +const rootPage = createPageExtension({ + // Ommiting name since it is the root page + defaultPath: '/' + routeRef: rootRouteRef, + loader: async () => { + const href = useRouteRef(catalogCreateComponentRouteRef)(); + + return ( +
+

Catalog Entities

+ {/* Linking to a create component page without direct reference */} + Create Component +
+ ); + } +}); + +export default const createPlugin({ + id: 'catalog', + routes: { + entityList: entityListRouteRef + } + externalRoutes: { + createComponent: createComponentRouteRef, + }, + extensions: [rootPage] +}); + +// plugins/catalog/src/index.ts +export { default } from './plugin'; +``` + +```tsx +// plugins/scaffolder/src/routes.ts +import { createRouteRef } from '@backstage/frontend-plugin-api'; + +const createComponentRouteRef = createRouteRef(); + +// plugins/scaffolder/src/plugin.tsx +import { createPlugin, createPageExtension } from '@backstage/frontend-plugin-api'; +import { createComponentRouteRef } from './routes'; + +const createComponentPage = createPageExtension({ + defaultPath: '/' + routeRef: createComponentRouteRef, + loader: async () => ( +
+

Create Component

+
+ ) +}); + +export default const createPlugin({ + id: 'scaffolder', + routes: { + createComponent: createComponentRouteRef, + }, + extensions: [createComponentPage] +}); + +// plugins/scaffolder/src/index.ts +export { default } from './plugin'; +``` + +On important thing to highlight is that it is currently not possible to have parameterized `ExternalRouteRefs`, or to bind an external route to a parameterized route, although this may be added in the future if needed. + +Now let's move on and configure the app to point to the Scaffolder create component page when the catalog create component ref be used. ### Binding External Route References - +```yaml +# app-config.yaml +app: + routes: + bindings: + plugin.catalog.externalRoutes.createComponent: plugin.scaffolfer.routes.createComponent +``` + +Or via code, in the file where the app is created: + +```tsx +// packages/app/src/App.tsx +import { createApp } from '@backstage/frontend-app-api'; +import catalog from '@backstage/plugin-catalog'; +import scaffolder from '@backstage/plugin-scaffolder'; + +const app = createApp({ + bindRoutes({ bind }) { + bind(catalog.externalRoutes, { + createComponent: scaffolder.routes.createComponent, + }); + }, +}); + +export default app.createRoot(); + +// packages/app/src/index.ts +import ReactDOM from 'react-dom/client'; +import app from './App'; + +ReactDOM.createRoot(document.getElementById('root')!).render(app); +``` + +Given the above binding, using `useRouteRef(createComponentRouteRef)` within the Catalog plugin will let us create a link to whatever path the Scaffolder create component page is mounted at. + +Note that we are not importing and using the RouteRefs directly in the app, and instead rely on the plugin instance to access routes of the plugins. This is a new convention that was introduced to provide better namespacing and discoverability of routes, as well as reduce the number of separate exports from each plugin package. this his indirection in the routing is particularly useful for open source plugins that need to leave flexibility in how they are integrated. + +Another thing to note is that this indirection in the routing is particularly useful for open source plugins that need to leave flexibility in how they are integrated. For plugins that you build internally for your own Backstage application, you can choose to go the route of direct imports or even use concrete routes directly. Although there can be some benefits to using the full routing system even in internal plugins. It can help you structure your routes, and as you will see further down it also helps you manage route parameters.parameters. ### Optional External Route References - +```tsx +// plugins/catalog/src/routes.ts +import { + createRouteRef, + createExternalRouteRef, +} from '@backstage/frontend-plugin-api'; + +const rootRouteRef = createRouteRef(); +const createComponentRouteRef = createExternalRouteRef({ + optional: true, +}); +``` + +An external route that is marked as optional is not required to be bound in the app, allowing it to be used as a switch for whether a particular link should be displayed or action should be taken. + +When calling useRouteRef with an optional external route, its return signature is changed to RouteFunc | undefined, allowing for logic like this: + +```tsx +// plugins/catalog/src/plugin.tsx +import { createPlugin, createPageExtension, useRouteRef } from '@backstage/frontend-plugin-api'; +import { rootRouteRef, createComponentRouteRef } from './routes'; + +const catalogEntityListPage = createPageExtension({ + defaultPath: '/' + routeRef: rootRouteRef, + loader: async () => { + const href = useRouteRef(catalogCreateComponentRouteRef)(); + + return ( +
+

Catalog Entities

+ {/* Since the route is optional, rendering the link only if the href is defined */} + {href && Create Component +
+ ); + } +}); + +export default const createPlugin({ + id: 'catalog', + routes: { + entityList: rootRouteRef + } + externalRoutes: { + createComponent: createComponentRouteRef, + }, + extensions: [catalogEntityListPage] +}); + +// index.ts +export { default } from './plugin'; +``` ## Sub Route References - +const rootRouteRef = createRouteRef(); +const detailsRouteRef = createSubRouteRef({ + parent: rootRouteRef, + path: '/details', +}); -```ts -/* +// plugins/catalog/src/plugin.ts +import { createPlugin, createPageExtension, useRouteRef } from '@backstage/frontend-plugin-api'; +import { rootRouteRef, detailsRouteRef } from './routes.ts'; -Some examples +const DetailsPage = () => ( +
+

Entity Details

+
+); -export const indexPageRouteRef = createRouteRef() +const rootPage = createPageExtension({ + defaultPath: '/' + routeRef: rootRouteRef, + loader: async () => { + const { path } = useRouteRef(detailsRouteRef)(); -export const catalogPlugin = createPlugin({ - id: 'catalog, + return ( +
+

Index Page

+ + } /> + +
+ ); + } +}); + +export default createPlugin({ + id: 'catalog', routes: { - index: indexPageRouteRef, + root: rootRouteRef, + details: detailsRouteRef, }, -}) + extensions: [rootPage] +}); -// in catalog plugin - -import {indexPageRouteRef} from '../../routes - -const link = useRouteRef(indexPageRouteRef) - -// scaffolder - -export const catalogIndexPageRouteRef = createExternalRouteRef({ - defaultTarget: 'catalog/index', -}) - -export const scaffolderPlugin = createPlugin({ - id: 'scaffolder, - externalRoutes: { - catalogIndex: catalogIndexPageRouteRef, - }, -}) - - -import {catalogIndexPageRouteRef} from '../../routes - -const link = useRouteRef(catalogIndexPageRouteRef) - -// app - -import {catalogPlugin} from '@backstage/plugin-catalog' - -const app = createApp({ - bindRoutes({bind}) { - bind(scaffolderPlugin, { - catalogIndex: catalogPlugin.routes.index, - }) - }, -}) -*/ +// plugins/catalog/src/index.ts +export { default } from './plugin'; ``` From 21170a170969630b4be5aab671633ae832737516 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 9 Jan 2024 09:46:16 +0100 Subject: [PATCH 109/283] docs(frontend-system): apply routes introduction suggestions Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index b38ef9016c..2280baba27 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -18,7 +18,7 @@ The composability system isn't a single API surface. It is a collection of patte ## Route References -In order to address the problem outlined above, we introduced the `RouteRefs` concept. `RouteRefs` abstract paths in a the Backstage app, and these paths can be configured both at the plugin level (by plugin developers) and at the instance level (by application integrators). +In order to address the problem outlined above, we introduced the concept of route references. A `RouteRef` is an abstract paths in a the Backstage app, and these paths can be configured both at the plugin level (by plugin developers) and at the instance level (by application integrators). Plugin developers create a `RouteRef` to expose a path in Backstage's routing system. You will see below how routes are defined programmatically, but before diving into code, let us explain how to configure them at the app level. In spite of the fact that plugin developers choose a default route path for the routes their plugin provides, all that path can be changed, so app integrators can set a custom path to a route whenever they like to (more information in the following sessions). From 324cfdce7d6cec371f846b38d1fe8bc397db7a51 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 9 Jan 2024 09:46:47 +0100 Subject: [PATCH 110/283] docs(frontend-system): apply external routes suggestions Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 2280baba27..8a33fb0f15 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -59,7 +59,7 @@ export const detailsRouteRef = createRouteRef({ Route refs do not have any behavior, in other words, they are an opaque type that represents route targets in an app, which are bound to specific paths at runtime, but they provide a level of indirection to help mix together different plugins that otherwise wouldn't know how to route to each other. -The code snippet of the previous section does not indicate which plugin the route belongs to. To do so, we have to extend Backstage with a new page extension associated with the newly created `RouteRef` and provide the extension through our plugin. Here's what we need to do: +The code snippet of the previous section does not indicate which plugin the route belongs to. To do so, you have to use it in the creation of any kind of routable extension, such as a page extension. When this extension is installed in the app it will become associated with the newly created `RouteRef`, making it possible to use the route ref to navigate the the extension. Here's what we need to do: ```tsx // plugins/catalog/src/routes.ts From 103d2e11d1575f95a674b81b2de6bf0f10a9627b Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 9 Jan 2024 09:47:20 +0100 Subject: [PATCH 111/283] docs(frontend-system): apply binding routes suggestions Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 8a33fb0f15..c8db088ed6 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -72,7 +72,7 @@ import { createPlugin, createPageExtension } from '@backstage/frontend-plugin-ap import { rootRouteRef } from './routes'; const rootPage = createPageExtension({ // [2] - // Ommiting name since it is the root page + // The `name` option is omitted since this is the root page defaultPath: '/' routeRef: rootRouteRef, loader: async () => Root Page From 4143a4d8452bc4b83e5b4e87820637aa16aac876 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 9 Jan 2024 09:48:21 +0100 Subject: [PATCH 112/283] docs(frontend-system): replace page with div in route examples Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index c8db088ed6..fca9f35704 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -75,7 +75,7 @@ const rootPage = createPageExtension({ // [2] // The `name` option is omitted since this is the root page defaultPath: '/' routeRef: rootRouteRef, - loader: async () => Root Page + loader: async () =>
Root Page
}); export default const createPlugin({ // [3] From 1bb3addf16a3078fc12a30a29ca14372dd41e5d6 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 9 Jan 2024 09:50:03 +0100 Subject: [PATCH 113/283] docs(frontend-system): fix using external route refs example Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index fca9f35704..0b08975ada 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -340,7 +340,7 @@ const catalogEntityListPage = createPageExtension({ defaultPath: '/' routeRef: rootRouteRef, loader: async () => { - const href = useRouteRef(catalogCreateComponentRouteRef)(); + const href = useRouteRef(catalogCreateComponentRouteRef); return (
From 76cbd8a54b098bce22c6bb7ccf97857bd2b46626 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 9 Jan 2024 09:51:39 +0100 Subject: [PATCH 114/283] docs(frontend-system): fix route subpaths example Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 0b08975ada..422cecdf4d 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -400,13 +400,13 @@ const rootPage = createPageExtension({ defaultPath: '/' routeRef: rootRouteRef, loader: async () => { - const { path } = useRouteRef(detailsRouteRef)(); + const detailsRouteRef = useRouteRef(detailsRouteRef)(); return (

Index Page

- } /> + } />
); From 8a42e2248763019e11b0c0d0b881f67757989aad Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 9 Jan 2024 09:54:20 +0100 Subject: [PATCH 115/283] docs(frontend-system): adjust subroute refs description Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 422cecdf4d..59785e1dfe 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -369,7 +369,7 @@ export { default } from './plugin'; ## Sub Route References -The last kind of route refs that can be created are `SubRouteRefs`, which can be used to create a route ref with a fixed path relative to an absolute `RouteRef`. They are useful if you have a page that internally is mounted at a sub route of a page extension component, and you want other plugins to be able to route to that page. +The last kind of route refs that can be created are `SubRouteRef`s, which can be used to create a route ref with a fixed path relative to an absolute `RouteRef`. They are useful if you have a page that internally is mounted at a sub route of a page extension component, and you want other plugins to be able to route to that page. And they can be a useful utility to handle routing within a plugin itself as well. For example: From 144f94ecbe14b2ee9687e9c7effb369d4396df6e Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 9 Jan 2024 09:56:44 +0100 Subject: [PATCH 116/283] docs(frontend-system): replace routes composability with frontend system Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 59785e1dfe..ccc44967d2 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -10,11 +10,11 @@ description: Frontend routes ## Introduction -This page describes the composability system that helps bring together content from a multitude of plugins into one Backstage application. +This page describes the frontend system that helps bring together content from a multitude of plugins into one Backstage application. -The core principle of the composability system is that plugins should have clear boundaries and connections. It should isolate crashes within a plugin, but allow navigation between them. It should allow for plugins to be loaded only when needed, and enable plugins to provide extension points for other plugins to build upon. The composability system is also built with an app-first mindset, prioritizing simplicity and clarity in the app over that in the plugins and core APIs. +The core principle of the frontend system is that plugins should have clear boundaries and connections. It should isolate crashes within a plugin, but allow navigation between them. It should allow for plugins to be loaded only when needed, and enable plugins to provide extension points for other plugins to build upon. The frontend system is also built with an app-first mindset, prioritizing simplicity and clarity in the app over that in the plugins and core APIs. -The composability system isn't a single API surface. It is a collection of patterns, primitives, and APIs. At the core is the concept of extensions, which are exported by plugins for use in the app. One of the concepts is `RouteRef` which enables us route between pages in a flexible way, and it is especially important when bringing together different open source plugins. +The frontend system isn't a single API surface. It is a collection of patterns, primitives, and APIs. At the core is the concept of extensions, which are exported by plugins for use in the app. One of the concepts is `RouteRef` which enables us route between pages in a flexible way, and it is especially important when bringing together different open source plugins. ## Route References From 16a04419d2e6a24133b10354f5c182030c0a3bdd Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 9 Jan 2024 13:02:16 +0100 Subject: [PATCH 117/283] docs(frontend-system): combine optional external routes code snippets Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index ccc44967d2..1639c8ece9 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -312,7 +312,7 @@ Another thing to note is that this indirection in the routing is particularly us ### Optional External Route References -When creating an ExternalRouteRef it is possible to mark it as optional: +It is possible to define an `ExternalRouteRef` as optional, so it is not required to bind it in the app. When calling `useRouteRef` with an optional external route, its return signature is changed to `RouteFunc | undefined`, and the returned value can be used used to decide whether a certain link should be displayed or if an action should be taken: ```tsx // plugins/catalog/src/routes.ts @@ -325,13 +325,7 @@ const rootRouteRef = createRouteRef(); const createComponentRouteRef = createExternalRouteRef({ optional: true, }); -``` -An external route that is marked as optional is not required to be bound in the app, allowing it to be used as a switch for whether a particular link should be displayed or action should be taken. - -When calling useRouteRef with an optional external route, its return signature is changed to RouteFunc | undefined, allowing for logic like this: - -```tsx // plugins/catalog/src/plugin.tsx import { createPlugin, createPageExtension, useRouteRef } from '@backstage/frontend-plugin-api'; import { rootRouteRef, createComponentRouteRef } from './routes'; From bba9de8e5cc2404bfb7c3cd268fd8aad45e8a58a Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 11 Jan 2024 15:16:28 +0100 Subject: [PATCH 118/283] docs(frontend-system): add subroutes with params example Signed-off-by: Camila Belo --- .../frontend-system/architecture/07-routes.md | 104 ++++++++++++++++-- 1 file changed, 94 insertions(+), 10 deletions(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 1639c8ece9..1e81b8485f 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -381,6 +381,8 @@ const detailsRouteRef = createSubRouteRef({ }); // plugins/catalog/src/plugin.ts +import React from 'react'; +import { Routes, Route, Link } from 'react-router-dom'; import { createPlugin, createPageExtension, useRouteRef } from '@backstage/frontend-plugin-api'; import { rootRouteRef, detailsRouteRef } from './routes.ts'; @@ -391,19 +393,27 @@ const DetailsPage = () => ( ); const rootPage = createPageExtension({ - defaultPath: '/' + defaultPath: '/', routeRef: rootRouteRef, loader: async () => { - const detailsRouteRef = useRouteRef(detailsRouteRef)(); + const Component = () => { + const to = useRouteRef(detailsRouteRef)(); - return ( -
-

Index Page

- - } /> - -
- ); + return ( +
+

Index Page

+ {/* Registering the details subroute */} + + } /> + + {/* Linking to the details subroute */} + Details Subpage +
+ ); + }; + + return ; + }, } }); @@ -419,3 +429,77 @@ export default createPlugin({ // plugins/catalog/src/index.ts export { default } from './plugin'; ``` + +Subroutes can also receive parameters, here is an example: + +```tsx +// plugins/catalog/src/routes.ts +import { + createRouteRef, + createSubRouteRef, +} from '@backstage/frontend-plugin-api'; + +const rootRouteRef = createRouteRef(); +const detailsRouteRef = createSubRouteRef({ + parent: rootRouteRef, + path: '/details/:name/:namespace/:kind', +}); + +// plugins/catalog/src/plugin.ts +import React from 'react'; +import { Routes, Route, Link } from 'react-router-dom'; +import { + createPlugin, + createPageExtension, + useRouteRef, +} from '@backstage/frontend-plugin-api'; +import { rootRouteRef, detailsRouteRef } from './routes.ts'; + +const DetailsPage = () => ( +
+

Entity Details

+ {/* can get the entity ref from URL and load the entity data here */} +
+); + +const rootPage = createPageExtension({ + defaultPath: '/subroutes', + routeRef: rootRouteRef, + loader: async () => { + const Component = () => { + const detailsRoutePath = useRouteRef(detailsRouteRef)({ + // Setting the details subroute params + name: 'entity1', + namespace: 'default', + kind: 'component', + }); + + return ( +
+

Index Page

+ {/* Registering the details subroute */} + + } /> + + {/* Linking to the details subroute */} + Entity 1 Details Subpage +
+ ); + }; + + return ; + }, +}); + +export default createPlugin({ + id: 'catalog', + routes: { + root: rootRouteRef, + details: detailsRouteRef, + }, + extensions: [rootPage], +}); + +// plugins/catalog/src/index.ts +export { default } from './plugin'; +``` From c0a0452bb81ab7d28f5d86624472077cb4d78202 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 11 Jan 2024 16:45:52 +0100 Subject: [PATCH 119/283] docs(frontend-system): improve optional external route explanation Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 1e81b8485f..2eb10b7fc9 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -93,7 +93,7 @@ export { default } from './plugin' We have completed our journey of creating a plugin page route. This is what the code does: - [1] The line 1 creates a route reference, which is not yet associated with any plugin page; -- [2] A route that renders nothing makes no sense, does it? So we are creating a page extension that associates a path and a component with the newly created route ref; +- [2] We associate our route reference with our page by providing it as an option during creation of the page extension. - [3] Finally, our plugin provides both routes and extensions. It's a smart question, and the answer can be found in the (Binding External Route References)[#building-external-route-references] section, wait a bit, keep reading and you'll understand why. From 70fdbad26a1aa79378804706309b0fa821719f92 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 11 Jan 2024 17:40:06 +0100 Subject: [PATCH 120/283] docs(frontend-system): export route when providing refs Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 2eb10b7fc9..52edea5de9 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -65,7 +65,7 @@ The code snippet of the previous section does not indicate which plugin the rout // plugins/catalog/src/routes.ts import { createRouteRef } from '@backstage/frontend-plugin-api'; -const rootRouteRef = createRouteRef(); // [1] +export const rootRouteRef = createRouteRef(); // [1] // plugins/catalog/src/plugin.tsx import { createPlugin, createPageExtension } from '@backstage/frontend-plugin-api'; From 2ae04c3c1d8d139dc8f964fb26cf52c037bc84c6 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 11 Jan 2024 17:46:00 +0100 Subject: [PATCH 121/283] docs(frontend-system): fix dialogue on external routes binding Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 52edea5de9..2bc2792e89 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -96,7 +96,7 @@ We have completed our journey of creating a plugin page route. This is what the - [2] We associate our route reference with our page by providing it as an option during creation of the page extension. - [3] Finally, our plugin provides both routes and extensions. -It's a smart question, and the answer can be found in the (Binding External Route References)[#building-external-route-references] section, wait a bit, keep reading and you'll understand why. +It may be unclear why we need to pass the route to the plugin once it has already been passed to the extension. It's a good point, and the explanation can be found in the (Binding External Route References)[#building-external-route-references] section, wait a bit, keep reading and you'll understand why. ### Using a Route Reference From b0ee827e0068704722b049107495da5693c52b0e Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 11 Jan 2024 17:51:06 +0100 Subject: [PATCH 122/283] docs(frontend-system): remove duplicated binding routes explanation Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 2bc2792e89..b76619f9c3 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -306,7 +306,7 @@ ReactDOM.createRoot(document.getElementById('root')!).render(app); Given the above binding, using `useRouteRef(createComponentRouteRef)` within the Catalog plugin will let us create a link to whatever path the Scaffolder create component page is mounted at. -Note that we are not importing and using the RouteRefs directly in the app, and instead rely on the plugin instance to access routes of the plugins. This is a new convention that was introduced to provide better namespacing and discoverability of routes, as well as reduce the number of separate exports from each plugin package. this his indirection in the routing is particularly useful for open source plugins that need to leave flexibility in how they are integrated. +Note that we are not importing and using the `RouteRef`s directly in the app, and instead rely on the plugin instance to access routes of the plugins. This is a new convention that was introduced to provide better namespacing and discoverability of routes, as well as reduce the number of separate exports from each plugin package. Another thing to note is that this indirection in the routing is particularly useful for open source plugins that need to leave flexibility in how they are integrated. For plugins that you build internally for your own Backstage application, you can choose to go the route of direct imports or even use concrete routes directly. Although there can be some benefits to using the full routing system even in internal plugins. It can help you structure your routes, and as you will see further down it also helps you manage route parameters.parameters. From d0fda6d3e6959d97cb9c92bda9542cb1ed1e7521 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 11 Jan 2024 17:52:04 +0100 Subject: [PATCH 123/283] docs(frontend-system): rephrase external routes description Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index b76619f9c3..04f6341e70 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -100,7 +100,7 @@ It may be unclear why we need to pass the route to the plugin once it has alread ### Using a Route Reference -You can link to the routes from other pages in the same plugin or you can also link between different plugins pages. In this section we will cover the first scenario, if you are interested in link to a page of a plugin that isn't yours, please go to the [external routes](#external-router-references) section below. +You can link to the routes from other pages in the same plugin or you can also link between different plugins pages. In this section we will cover the first scenario, if you are interested in link to a page of a different plugin, please go to the [external routes](#external-router-references) section below. Alright, let's presume that we have a plugin that renders tow different pages, and these pages links to each other. From 137c73ca535cc317db7836672ea5b599c4972661 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 11 Jan 2024 18:00:09 +0100 Subject: [PATCH 124/283] docs(frontend-system): apply more routes suggestions Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 04f6341e70..0acbebb106 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -102,7 +102,7 @@ It may be unclear why we need to pass the route to the plugin once it has alread You can link to the routes from other pages in the same plugin or you can also link between different plugins pages. In this section we will cover the first scenario, if you are interested in link to a page of a different plugin, please go to the [external routes](#external-router-references) section below. -Alright, let's presume that we have a plugin that renders tow different pages, and these pages links to each other. +Alright, let's presume that we have a plugin that renders two different pages, and these pages link to each other. First lets create the routes references: @@ -110,7 +110,7 @@ First lets create the routes references: // plugins/catalog/src/routes.ts import { createRouteRef } from '@backstage/frontend-plugin-api'; -const rootRouteRef = createRouteRef(); +export const rootRouteRef = createRouteRef(); type DetailsRouteParams = { namespace: string; @@ -136,7 +136,7 @@ const rootPage = createPageExtension({ defaultPath: '/' routeRef: rootRouteRef, loader: async () => { - const href = useRouteRef(catalogEntityDetailsRouteRef)({ + const href = useRouteRef(detailsRouteRef)({ kind: 'Component', namespace: 'Default', name: 'foo' @@ -165,8 +165,8 @@ const detailsPage = createPageExtension({ export default const createPlugin({ id: 'catalog', routes: { - list: catalogEntityListRouteRef, - details: catalogEntityDetailsRouteRef, + root: rootRouteRef + details: detailsRouteRef, }, extensions: [rootPage, detailsPage] }); @@ -179,9 +179,9 @@ During runtime, we used a hook `useRouteRef` to get the path to the details page ## External Router References -Now let's assume that we want to link from the Catalog entity list page to the Scaffolder create component page. We don't want to reference the Scaffolder plugin directly, since that would create an unnecessary dependency. It would also provided little flexibility in allowing the app to tie plugins together, with the links instead being dictated by the plugins themselves. To solve this, we use ExternalRouteRefs. Much like regular route references, they can be passed to `useRouteRef` to create concrete URLs, but they can not be used in page extensions and instead have to be associated with a target route using route bindings in the app. +Now let's assume that we want to link from the Catalog entity list page to the Scaffolder create component page. We don't want to reference the Scaffolder plugin directly, since that would create an unnecessary dependency. It would also provided little flexibility in allowing the app to tie plugins together, with the links instead being dictated by the plugins themselves. To solve this, we use an `ExternalRouteRef`. Much like regular route references, they can be passed to `useRouteRef` to create concrete URLs, but they can not be used in page extensions and instead have to be associated with a target route using route bindings in the app. -We create a new ExternalRouteRef inside the Scaffolder plugin, using a neutral name that describes its role in the plugin rather than a specific plugin page that it might be linking to, allowing the app to decide the final target. If the Catalog entity list page for example wants to link the Scaffolder create component page in the header, it might declare an ExternalRouteRef similar to this: +We create a new `RouteRef` inside the Scaffolder plugin, using a neutral name that describes its role in the plugin rather than a specific plugin page that it might be linking to, allowing the app to decide the final target. If the Catalog entity list page for example wants to link the Scaffolder create component page in the header, it might declare an `ExternalRouteRef` similar to this: ```tsx // plugins/catalog/src/routes.ts @@ -217,7 +217,7 @@ const rootPage = createPageExtension({ export default const createPlugin({ id: 'catalog', routes: { - entityList: entityListRouteRef + root: rootRouteRef, } externalRoutes: { createComponent: createComponentRouteRef, From 472a39e1092026181daaa15329050ff908487e39 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 11 Jan 2024 19:26:02 +0100 Subject: [PATCH 125/283] docs(frontend-system): more code snippet fixes Signed-off-by: Camila Belo --- .../frontend-system/architecture/07-routes.md | 341 +++++++++++------- 1 file changed, 202 insertions(+), 139 deletions(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 0acbebb106..f4cebe3dd1 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -26,15 +26,13 @@ There are 3 types of route references: regular route, sub route, and external ro ### Creating a Route Reference -Route references, also known as root plugin pages, are created as follows: - -_Catalog Plugin_ +Route references, also known as plugins' index pages, are created as follows: ```tsx // plugins/catalog/src/routes.ts import { createRouteRef } from '@backstage/frontend-plugin-api'; -export const rootRouteRef = createRouteRef(); +export const indexRouteRef = createRouteRef(); ``` Note that you almost always want to create the route references themselves in a different file than the one that creates the plugin instance, for example a top-level routes.ts. This is to avoid circular imports when you use the route references from other parts of the same plugin. @@ -47,10 +45,8 @@ The referenced route can also accepts `params`. Here is how you create a referen // plugins/catalog/src/routes.ts import { createRouteRef } from '@backstage/frontend-plugin-api'; -type DetailsRouteParams = { namespace: string; name: string; kind: string }; - -export const detailsRouteRef = createRouteRef({ - // A list of parameter names that the path that this route ref is bound to must contain +export const detailsRouteRef = createRouteRef({ + // The parameters that must be included in the path of this route reference params: ['namespace', 'name', 'kind'], }); ``` @@ -65,29 +61,35 @@ The code snippet of the previous section does not indicate which plugin the rout // plugins/catalog/src/routes.ts import { createRouteRef } from '@backstage/frontend-plugin-api'; -export const rootRouteRef = createRouteRef(); // [1] +export const indexRouteRef = createRouteRef(); // [1] // plugins/catalog/src/plugin.tsx -import { createPlugin, createPageExtension } from '@backstage/frontend-plugin-api'; -import { rootRouteRef } from './routes'; +import React from 'react'; +import { + createPlugin, + createPageExtension, +} from '@backstage/frontend-plugin-api'; +import { indexRouteRef } from './routes'; -const rootPage = createPageExtension({ // [2] - // The `name` option is omitted since this is the root page - defaultPath: '/' - routeRef: rootRouteRef, - loader: async () =>
Root Page
+const indexPage = createPageExtension({ + // [2] + // The `name` option is omitted since this is the index page + defaultPath: '/entities', + routeRef: indexRouteRef, + loader: async () =>
Root Page
, }); -export default const createPlugin({ // [3] +export default createPlugin({ + // [3] id: 'catalog', routes: { - root: rootRouteRef, + index: indexRouteRef, }, - extensions: [rootPage] + extensions: [indexPage], }); // plugins/catalog/src/index.ts -export { default } from './plugin' +export { default } from './plugin'; ``` We have completed our journey of creating a plugin page route. This is what the code does: @@ -110,16 +112,10 @@ First lets create the routes references: // plugins/catalog/src/routes.ts import { createRouteRef } from '@backstage/frontend-plugin-api'; -export const rootRouteRef = createRouteRef(); +export const indexRouteRef = createRouteRef(); -type DetailsRouteParams = { - namespace: string; - name: string; - kind: string; -}; - -export const detailsRouteRef = createRouteRef({ - // A list of parameter names that the path that this route ref is bound to must contain +export const detailsRouteRef = createRouteRef({ + // The parameters that must be included in the path of this route reference params: ['namespace', 'name', 'kind'], }); ``` @@ -128,51 +124,73 @@ Now we are ready to provide these routes via plugin extensions and link between ```tsx // plugins/catalog/src/plugin.tsx -import { createPlugin, createPageExtension, useRouteRef } from '@backstage/frontend-plugin-api'; +import React from 'react'; +import { useParams } from 'react-router'; +import { + createPlugin, + createPageExtension, + useRouteRef, +} from '@backstage/frontend-plugin-api'; import { rootRouteRef, detailsRouteRef } from './routes'; -const rootPage = createPageExtension({ +const indexPage = createPageExtension({ // Ommiting name since it is the root page - defaultPath: '/' - routeRef: rootRouteRef, + defaultPath: '/entities', + routeRef: indexRouteRef, loader: async () => { - const href = useRouteRef(detailsRouteRef)({ - kind: 'Component', - namespace: 'Default', - name: 'foo' - }); + const Component = () => { + const href = useRouteRef(detailsRouteRef)({ + kind: 'component', + namespace: 'default', + name: 'foo', + }); - return ( -
-

Index Page

- Entity Foo -
- ); - } + return ( +
+

Index Page

+ Entity Foo +
+ ); + }; + + return ; + }, }); const detailsPage = createPageExtension({ name: 'details', - defaultPath: '/entities/:namespace/:kind/:name' + defaultPath: '/entities/:namespace/:kind/:name', routeRef: detailsRouteRef, - loader: async () => ( -
-

Catalog Entities

-
- ) + loader: async () => { + const Component = () => { + // Getting the parameters from the URL + const params = useParams(); + return ( +
+

Details Page

+
    +
  • Kind: {params.kind}
  • +
  • Namespace: {params.namespace}
  • +
  • Name: {params.name}
  • +
+
+ ); + }; + return ; + }, }); -export default const createPlugin({ +export default createPlugin({ id: 'catalog', routes: { - root: rootRouteRef + index: indexRouteRef, details: detailsRouteRef, }, - extensions: [rootPage, detailsPage] + extensions: [indexPage, detailsPage], }); // plugins/catalog/src/index.ts -export { default } from './plugin' +export { default } from './plugin'; ``` During runtime, we used a hook `useRouteRef` to get the path to the details page. Because we are linking to pages of the same plugin, we are currently accessing the reference directly, but in the following sections, you will see how to link to pages of different plugins. @@ -183,6 +201,8 @@ Now let's assume that we want to link from the Catalog entity list page to the S We create a new `RouteRef` inside the Scaffolder plugin, using a neutral name that describes its role in the plugin rather than a specific plugin page that it might be linking to, allowing the app to decide the final target. If the Catalog entity list page for example wants to link the Scaffolder create component page in the header, it might declare an `ExternalRouteRef` similar to this: +_Catalog Plugin_ + ```tsx // plugins/catalog/src/routes.ts import { @@ -190,19 +210,19 @@ import { createExternalRouteRef, } from '@backstage/frontend-plugin-api'; -const rootRouteRef = createRouteRef(); +const indexRouteRef = createRouteRef(); const createComponentRouteRef = createExternalRouteRef(); // plugins/catalog/src/plugin.tsx +import React from 'react'; import { createPlugin, createPageExtension, useRouteRef } from '@backstage/frontend-plugin-api'; -import { rootRouteRef, createComponentRouteRef } from './routes'; +import { indexRouteRef, createComponentRouteRef } from './routes'; -const rootPage = createPageExtension({ - // Ommiting name since it is the root page - defaultPath: '/' - routeRef: rootRouteRef, +const indexPage = createPageExtension({ + defaultPath: '/entities', + routeRef: indexRouteRef, loader: async () => { - const href = useRouteRef(catalogCreateComponentRouteRef)(); + const href = useRouteRef(createComponentRouteRef)(); return (
@@ -214,47 +234,53 @@ const rootPage = createPageExtension({ } }); -export default const createPlugin({ +export default createPlugin({ id: 'catalog', routes: { - root: rootRouteRef, + index: indexRouteRef, } externalRoutes: { createComponent: createComponentRouteRef, }, - extensions: [rootPage] + extensions: [indexPage] }); // plugins/catalog/src/index.ts export { default } from './plugin'; ``` +_Scaffolder Plugin_ + ```tsx // plugins/scaffolder/src/routes.ts import { createRouteRef } from '@backstage/frontend-plugin-api'; -const createComponentRouteRef = createRouteRef(); +const indexRouteRef = createRouteRef(); // plugins/scaffolder/src/plugin.tsx -import { createPlugin, createPageExtension } from '@backstage/frontend-plugin-api'; -import { createComponentRouteRef } from './routes'; +import React from 'react'; +import { + createPlugin, + createPageExtension, +} from '@backstage/frontend-plugin-api'; +import { indexRouteRef } from './routes'; -const createComponentPage = createPageExtension({ - defaultPath: '/' - routeRef: createComponentRouteRef, +const indexPage = createPageExtension({ + defaultPath: '/create', + routeRef: indexRouteRef, loader: async () => (

Create Component

- ) + ), }); -export default const createPlugin({ +export default createPlugin({ id: 'scaffolder', routes: { - createComponent: createComponentRouteRef, + index: indexRouteRef, }, - extensions: [createComponentPage] + extensions: [indexPage], }); // plugins/scaffolder/src/index.ts @@ -276,7 +302,7 @@ Using the above example of the Catalog entities list page to the Scaffolder crea app: routes: bindings: - plugin.catalog.externalRoutes.createComponent: plugin.scaffolfer.routes.createComponent + plugin.catalog.externalRoutes.createComponent: plugin.scaffolder.routes.index ``` Or via code, in the file where the app is created: @@ -296,12 +322,6 @@ const app = createApp({ }); export default app.createRoot(); - -// packages/app/src/index.ts -import ReactDOM from 'react-dom/client'; -import app from './App'; - -ReactDOM.createRoot(document.getElementById('root')!).render(app); ``` Given the above binding, using `useRouteRef(createComponentRouteRef)` within the Catalog plugin will let us create a link to whatever path the Scaffolder create component page is mounted at. @@ -321,40 +341,45 @@ import { createExternalRouteRef, } from '@backstage/frontend-plugin-api'; -const rootRouteRef = createRouteRef(); +const indexRouteRef = createRouteRef(); const createComponentRouteRef = createExternalRouteRef({ optional: true, }); // plugins/catalog/src/plugin.tsx -import { createPlugin, createPageExtension, useRouteRef } from '@backstage/frontend-plugin-api'; -import { rootRouteRef, createComponentRouteRef } from './routes'; +import React from 'react'; +import { + createPlugin, + createPageExtension, + useRouteRef, +} from '@backstage/frontend-plugin-api'; +import { indexRouteRef, createComponentRouteRef } from './routes'; -const catalogEntityListPage = createPageExtension({ - defaultPath: '/' - routeRef: rootRouteRef, +const indexPage = createPageExtension({ + defaultPath: '/entities', + routeRef: indexRouteRef, loader: async () => { - const href = useRouteRef(catalogCreateComponentRouteRef); + const link = useRouteRef(createComponentRouteRef); return (

Catalog Entities

{/* Since the route is optional, rendering the link only if the href is defined */} - {href && Create Component + {link && Create Component}
); - } + }, }); -export default const createPlugin({ +export default createPlugin({ id: 'catalog', routes: { - entityList: rootRouteRef - } + index: indexRouteRef, + }, externalRoutes: { createComponent: createComponentRouteRef, }, - extensions: [catalogEntityListPage] + extensions: [indexPage], }); // index.ts @@ -371,59 +396,66 @@ For example: // plugins/catalog/src/routes.ts import { createRouteRef, - createSubRouteRef + createSubRouteRef, } from '@backstage/frontend-plugin-api'; -const rootRouteRef = createRouteRef(); -const detailsRouteRef = createSubRouteRef({ - parent: rootRouteRef, +const indexRouteRef = createRouteRef(); +const detailsSubRouteRef = createSubRouteRef({ + parent: indexRouteRef, path: '/details', }); // plugins/catalog/src/plugin.ts import React from 'react'; -import { Routes, Route, Link } from 'react-router-dom'; -import { createPlugin, createPageExtension, useRouteRef } from '@backstage/frontend-plugin-api'; -import { rootRouteRef, detailsRouteRef } from './routes.ts'; +import { Routes, Route, useLocation } from 'react-router-dom'; +import { + createPlugin, + createPageExtension, + useRouteRef, +} from '@backstage/frontend-plugin-api'; +import { indexRouteRef, detailsSubRouteRef } from './routes.ts'; const DetailsPage = () => (
-

Entity Details

+

Details Sub Page

); -const rootPage = createPageExtension({ - defaultPath: '/', - routeRef: rootRouteRef, +const indexPage = createPageExtension({ + defaultPath: '/entities', + routeRef: indexRouteRef, loader: async () => { const Component = () => { - const to = useRouteRef(detailsRouteRef)(); + const { pathname } = useLocation(); + const indexPath = useRouteRef(indexRouteRef)(); + const detailsPath = useRouteRef(detailsSubRouteRef)(); return (

Index Page

- {/* Registering the details subroute */} + {/* Linking to the index route */} + {pathname === detailsPath && Hide details} + {/* Linking to the details sub route */} + {pathname === indexPath && Show details} + {/* Registering the details sub route */} - } /> + } /> - {/* Linking to the details subroute */} - Details Subpage
); }; return ; }, - } }); export default createPlugin({ id: 'catalog', routes: { - root: rootRouteRef, - details: detailsRouteRef, + index: indexRouteRef, + details: detailsSubRouteRef, }, - extensions: [rootPage] + extensions: [indexPage], }); // plugins/catalog/src/index.ts @@ -439,50 +471,81 @@ import { createSubRouteRef, } from '@backstage/frontend-plugin-api'; -const rootRouteRef = createRouteRef(); -const detailsRouteRef = createSubRouteRef({ - parent: rootRouteRef, - path: '/details/:name/:namespace/:kind', +const indexRouteRef = createRouteRef(); +const detailsSubRouteRef = createSubRouteRef({ + parent: indexRouteRef, + path: '/:name/:namespace/:kind', }); // plugins/catalog/src/plugin.ts import React from 'react'; -import { Routes, Route, Link } from 'react-router-dom'; +import { Routes, Route, Link, useParams, useLocation } from 'react-router-dom'; import { createPlugin, createPageExtension, useRouteRef, } from '@backstage/frontend-plugin-api'; -import { rootRouteRef, detailsRouteRef } from './routes.ts'; +import { indexRouteRef, detailsSubRouteRef } from './routes.ts'; -const DetailsPage = () => ( -
-

Entity Details

- {/* can get the entity ref from URL and load the entity data here */} -
-); +const DetailsPage = () => { + // Getting the parameters from the URL + const params = useParams(); + return ( +
+

Details Sub Page

+
    +
  • Kind: {params.kind}
  • +
  • Namespace: {params.namespace}
  • +
  • Name: {params.name}
  • +
+
+ ); +}; -const rootPage = createPageExtension({ - defaultPath: '/subroutes', - routeRef: rootRouteRef, +const indexPage = createPageExtension({ + defaultPath: '/entities', + routeRef: indexRouteRef, loader: async () => { const Component = () => { - const detailsRoutePath = useRouteRef(detailsRouteRef)({ + const { pathname } = useLocation(); + const indexPath = useRouteRef(indexRouteRef)(); + const detailsPath = useRouteRef(detailsSubRouteRef)({ // Setting the details subroute params - name: 'entity1', - namespace: 'default', kind: 'component', + namespace: 'default', + name: 'foo', }); return (

Index Page

+ + + + + + + + + + + + + +
NameDetails
Foo + {/* Linking to the index route */} + {pathname === detailsPath && ( + Hide details + )} + {/* Linking to the details sub route */} + {pathname === indexPath && ( + Show details + )} +
{/* Registering the details subroute */} - } /> + } /> - {/* Linking to the details subroute */} - Entity 1 Details Subpage
); }; @@ -494,10 +557,10 @@ const rootPage = createPageExtension({ export default createPlugin({ id: 'catalog', routes: { - root: rootRouteRef, - details: detailsRouteRef, + index: indexRouteRef, + details: detailsSubRouteRef, }, - extensions: [rootPage], + extensions: [indexPage], }); // plugins/catalog/src/index.ts From 394b286aa56cd6c9262d5fc47dec5b83abd918ce Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 11 Jan 2024 19:33:44 +0100 Subject: [PATCH 126/283] docs(frontend-system): remove parameterised external route note Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index f4cebe3dd1..8ffecaa827 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -287,7 +287,6 @@ export default createPlugin({ export { default } from './plugin'; ``` -On important thing to highlight is that it is currently not possible to have parameterized `ExternalRouteRefs`, or to bind an external route to a parameterized route, although this may be added in the future if needed. Now let's move on and configure the app to point to the Scaffolder create component page when the catalog create component ref be used. From 007003719a1bc82452744d6c38bf6e92627a01f3 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 11 Jan 2024 19:36:30 +0100 Subject: [PATCH 127/283] docs(frontend-system): remove redundant page name comment Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 8ffecaa827..caa93eaf67 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -134,7 +134,6 @@ import { import { rootRouteRef, detailsRouteRef } from './routes'; const indexPage = createPageExtension({ - // Ommiting name since it is the root page defaultPath: '/entities', routeRef: indexRouteRef, loader: async () => { @@ -287,7 +286,6 @@ export default createPlugin({ export { default } from './plugin'; ``` - Now let's move on and configure the app to point to the Scaffolder create component page when the catalog create component ref be used. ### Binding External Route References From 6f1016a126cf7fff8b33341421eb9813b09f182c Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 11 Jan 2024 19:55:46 +0100 Subject: [PATCH 128/283] docs(frontend-system): more routes adjustments Signed-off-by: Camila Belo --- .../frontend-system/architecture/07-routes.md | 216 ++++++++++++------ 1 file changed, 151 insertions(+), 65 deletions(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index caa93eaf67..0fe2a8cc85 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -18,15 +18,15 @@ The frontend system isn't a single API surface. It is a collection of patterns, ## Route References -In order to address the problem outlined above, we introduced the concept of route references. A `RouteRef` is an abstract paths in a the Backstage app, and these paths can be configured both at the plugin level (by plugin developers) and at the instance level (by application integrators). +In order to address the problem outlined above, we introduced the concept of route references. A `RouteRef` is an abstract path in a Backstage app, and these paths can be configured both at plugin level (by plugin developers) and at instance level (by application integrators). -Plugin developers create a `RouteRef` to expose a path in Backstage's routing system. You will see below how routes are defined programmatically, but before diving into code, let us explain how to configure them at the app level. In spite of the fact that plugin developers choose a default route path for the routes their plugin provides, all that path can be changed, so app integrators can set a custom path to a route whenever they like to (more information in the following sessions). +Plugin developers create a `RouteRef` to expose a path in Backstage's routing system. You will see below how routes are defined programmatically, but before diving into code, let us explain how to configure them at app level. In spite of the fact that plugin developers choose a default route path for the routes their plugin provides, paths are configurable, so app integrators can set a custom path to a route whenever they like to (more information in the following sessions). There are 3 types of route references: regular route, sub route, and external route, and we will cover both the concept and code definition for each. Keep reading 🙂! ### Creating a Route Reference -Route references, also known as plugins' index pages, are created as follows: +Route references, also known as plugins' index pages or regular routes, are created as follows: ```tsx // plugins/catalog/src/routes.ts @@ -37,20 +37,6 @@ export const indexRouteRef = createRouteRef(); Note that you almost always want to create the route references themselves in a different file than the one that creates the plugin instance, for example a top-level routes.ts. This is to avoid circular imports when you use the route references from other parts of the same plugin. -### Route Path Parameters - -The referenced route can also accepts `params`. Here is how you create a reference for a route that requires a kind, namespace and name `params`, like in this path `/entities/:name/:namespace/:kind`: - -```tsx -// plugins/catalog/src/routes.ts -import { createRouteRef } from '@backstage/frontend-plugin-api'; - -export const detailsRouteRef = createRouteRef({ - // The parameters that must be included in the path of this route reference - params: ['namespace', 'name', 'kind'], -}); -``` - ### Providing Route References to Plugins Route refs do not have any behavior, in other words, they are an opaque type that represents route targets in an app, which are bound to specific paths at runtime, but they provide a level of indirection to help mix together different plugins that otherwise wouldn't know how to route to each other. @@ -71,12 +57,12 @@ import { } from '@backstage/frontend-plugin-api'; import { indexRouteRef } from './routes'; -const indexPage = createPageExtension({ +// The `name` option is omitted since this is the index page +const catalogIndexPage = createPageExtension({ // [2] - // The `name` option is omitted since this is the index page defaultPath: '/entities', routeRef: indexRouteRef, - loader: async () =>
Root Page
, + loader: async () =>
Index Page
, }); export default createPlugin({ @@ -85,7 +71,7 @@ export default createPlugin({ routes: { index: indexRouteRef, }, - extensions: [indexPage], + extensions: [catalogIndexPage], }); // plugins/catalog/src/index.ts @@ -98,7 +84,21 @@ We have completed our journey of creating a plugin page route. This is what the - [2] We associate our route reference with our page by providing it as an option during creation of the page extension. - [3] Finally, our plugin provides both routes and extensions. -It may be unclear why we need to pass the route to the plugin once it has already been passed to the extension. It's a good point, and the explanation can be found in the (Binding External Route References)[#building-external-route-references] section, wait a bit, keep reading and you'll understand why. +It may be unclear why we need to pass the route to the plugin once it has already been passed to the extension, but the explanation can be found in the (Binding External Route References)[#building-external-route-references] section, wait a bit, keep reading and you'll understand why. + +### Route Path Parameters + +The referenced route can also accepts `params`. Here is how you create a reference for a route that requires a `kind`, `namespace` and `name` params, like in this path `/entities/:kind/:namespace/:name`: + +```tsx +// plugins/catalog/src/routes.ts +import { createRouteRef } from '@backstage/frontend-plugin-api'; + +export const detailsRouteRef = createRouteRef({ + // The parameters that must be included in the path of this route reference + params: ['kind', 'namespace', 'name'], +}); +``` ### Using a Route Reference @@ -116,7 +116,7 @@ export const indexRouteRef = createRouteRef(); export const detailsRouteRef = createRouteRef({ // The parameters that must be included in the path of this route reference - params: ['namespace', 'name', 'kind'], + params: ['kind', 'namespace', 'name'], }); ``` @@ -133,12 +133,13 @@ import { } from '@backstage/frontend-plugin-api'; import { rootRouteRef, detailsRouteRef } from './routes'; -const indexPage = createPageExtension({ +const catalogIndexPage = createPageExtension({ defaultPath: '/entities', routeRef: indexRouteRef, loader: async () => { const Component = () => { - const href = useRouteRef(detailsRouteRef)({ + const detailsLink = useRouteRef(detailsRouteRef); + const detailsPath = detailsLink({ kind: 'component', namespace: 'default', name: 'foo', @@ -147,7 +148,7 @@ const indexPage = createPageExtension({ return (

Index Page

- Entity Foo + See details
); }; @@ -156,8 +157,10 @@ const indexPage = createPageExtension({ }, }); -const detailsPage = createPageExtension({ +const catalogDetailsPage = createPageExtension({ name: 'details', + // It is important to mention here if an integrator configures a different path for this page via config file + // It will be their responsibility to make sure that it contains the same parameters, although they don't necessarily need to be in the same order. defaultPath: '/entities/:namespace/:kind/:name', routeRef: detailsRouteRef, loader: async () => { @@ -185,18 +188,18 @@ export default createPlugin({ index: indexRouteRef, details: detailsRouteRef, }, - extensions: [indexPage, detailsPage], + extensions: [catalogIndexPage, catalogDetailsPage], }); // plugins/catalog/src/index.ts export { default } from './plugin'; ``` -During runtime, we used a hook `useRouteRef` to get the path to the details page. Because we are linking to pages of the same plugin, we are currently accessing the reference directly, but in the following sections, you will see how to link to pages of different plugins. +During runtime, in the index page, we used a hook `useRouteRef` to get the path to the details page. Because we are linking to pages of the same plugin, we are currently accessing the reference directly, but in the following sections, you will see how to link to pages of different plugins. ## External Router References -Now let's assume that we want to link from the Catalog entity list page to the Scaffolder create component page. We don't want to reference the Scaffolder plugin directly, since that would create an unnecessary dependency. It would also provided little flexibility in allowing the app to tie plugins together, with the links instead being dictated by the plugins themselves. To solve this, we use an `ExternalRouteRef`. Much like regular route references, they can be passed to `useRouteRef` to create concrete URLs, but they can not be used in page extensions and instead have to be associated with a target route using route bindings in the app. +Now let's assume that we want to link from the Catalog entities list page to the Scaffolder create component page. We don't want to reference the Scaffolder plugin directly, since that would create an unnecessary dependency. It would also provided little flexibility in allowing the app to tie plugins together, with the links instead being dictated by the plugins themselves. To solve this, we use an `ExternalRouteRef`. Much like regular route references, they can be passed to `useRouteRef` to create concrete URLs, but they can not be used in page extensions and instead have to be associated with a target route using route bindings in the app. We create a new `RouteRef` inside the Scaffolder plugin, using a neutral name that describes its role in the plugin rather than a specific plugin page that it might be linking to, allowing the app to decide the final target. If the Catalog entity list page for example wants to link the Scaffolder create component page in the header, it might declare an `ExternalRouteRef` similar to this: @@ -209,39 +212,67 @@ import { createExternalRouteRef, } from '@backstage/frontend-plugin-api'; -const indexRouteRef = createRouteRef(); -const createComponentRouteRef = createExternalRouteRef(); +export const indexRouteRef = createRouteRef(); +export const detailsRouteRef = createRouteRef({ + // The parameters that must be included in the path of this route reference + params: ['kind', 'namespace', 'name'], +}); +export const createComponentRouteRef = createExternalRouteRef(); // plugins/catalog/src/plugin.tsx import React from 'react'; import { createPlugin, createPageExtension, useRouteRef } from '@backstage/frontend-plugin-api'; -import { indexRouteRef, createComponentRouteRef } from './routes'; +import { indexRouteRef, detailsRouteRef, createComponentRouteRef } from './routes'; -const indexPage = createPageExtension({ +const catalogIndexPage = createPageExtension({ defaultPath: '/entities', routeRef: indexRouteRef, loader: async () => { - const href = useRouteRef(createComponentRouteRef)(); + const createComponentLink = useRouteRef(createComponentRouteRef); return (
-

Catalog Entities

+

Index Page

{/* Linking to a create component page without direct reference */} - Create Component + Create Component
); } }); +const catalogDetailsPage = createPageExtension({ + name: 'details', + defaultPath: '/entities/:namespace/:kind/:name', + routeRef: detailsRouteRef, + loader: async () => { + const Component = () => { + // Getting the parameters from the URL + const params = useParams(); + return ( +
+

Details Page

+
    +
  • Kind: {params.kind}
  • +
  • Namespace: {params.namespace}
  • +
  • Name: {params.name}
  • +
+
+ ); + }; + return ; + }, +}); + export default createPlugin({ id: 'catalog', routes: { index: indexRouteRef, + details: detailsRouteRef, } externalRoutes: { createComponent: createComponentRouteRef, }, - extensions: [indexPage] + extensions: [catalogIndexPage] }); // plugins/catalog/src/index.ts @@ -254,7 +285,7 @@ _Scaffolder Plugin_ // plugins/scaffolder/src/routes.ts import { createRouteRef } from '@backstage/frontend-plugin-api'; -const indexRouteRef = createRouteRef(); +export const indexRouteRef = createRouteRef(); // plugins/scaffolder/src/plugin.tsx import React from 'react'; @@ -264,7 +295,7 @@ import { } from '@backstage/frontend-plugin-api'; import { indexRouteRef } from './routes'; -const indexPage = createPageExtension({ +const scaffolderIndexPage = createPageExtension({ defaultPath: '/create', routeRef: indexRouteRef, loader: async () => ( @@ -279,14 +310,62 @@ export default createPlugin({ routes: { index: indexRouteRef, }, - extensions: [indexPage], + extensions: [scaffolderIndexPage], }); // plugins/scaffolder/src/index.ts export { default } from './plugin'; ``` -Now let's move on and configure the app to point to the Scaffolder create component page when the catalog create component ref be used. +One last thing is that external routes can also be parametrize, so if Scaffolder wants to redirect to the Catalog entity details page whenever a new component is created, the Scaffolder plugin can also expose a external route like this: + +```ts +// plugins/scaffolder/src/routes.ts +import { + createRouteRef, + createExternalRouteRef, +} from '@backstage/frontend-plugin-api'; + +export const indexRouteRef = createRouteRef(); +export const entityDetailsExternalRouteRef = createExternalRouteRef({ + // The parameters that must be included in the path of this route reference + params: ['kind', 'namespace', 'name'], +}); + +// plugins/scaffolder/src/plugin.tsx +import React from 'react'; +import { + createPlugin, + createPageExtension, +} from '@backstage/frontend-plugin-api'; +import { indexRouteRef, entityDetailsExternalRouteRef } from './routes'; + +const scaffolderIndexPage = createPageExtension({ + defaultPath: '/create', + routeRef: indexRouteRef, + loader: async () => ( +
+

Create Component

+
+ ), +}); + +export default createPlugin({ + id: 'scaffolder', + routes: { + index: indexRouteRef, + }, + externalRoutes: { + entityDetails: entityDetailsExternalRouteRef, + }, + extensions: [scaffolderIndexPage], +}); + +// plugins/scaffolder/src/index.ts +export { default } from './plugin'; +``` + +Now let's move on and configure the app to point to the Scaffolder create component page when the Catalog create component ref be used and also to poin to the Catalog entity details page when the Scaffolder entity details ref be used. ### Binding External Route References @@ -300,6 +379,7 @@ app: routes: bindings: plugin.catalog.externalRoutes.createComponent: plugin.scaffolder.routes.index + plugin.scaffolder.externalRoutes.entityDetails: plugin.catalog.routes.details ``` Or via code, in the file where the app is created: @@ -315,6 +395,9 @@ const app = createApp({ bind(catalog.externalRoutes, { createComponent: scaffolder.routes.createComponent, }); + bind(scaffolder.externalRoutes, { + entityDetails: catalog.routes.details, + }); }, }); @@ -325,11 +408,11 @@ Given the above binding, using `useRouteRef(createComponentRouteRef)` within the Note that we are not importing and using the `RouteRef`s directly in the app, and instead rely on the plugin instance to access routes of the plugins. This is a new convention that was introduced to provide better namespacing and discoverability of routes, as well as reduce the number of separate exports from each plugin package. -Another thing to note is that this indirection in the routing is particularly useful for open source plugins that need to leave flexibility in how they are integrated. For plugins that you build internally for your own Backstage application, you can choose to go the route of direct imports or even use concrete routes directly. Although there can be some benefits to using the full routing system even in internal plugins. It can help you structure your routes, and as you will see further down it also helps you manage route parameters.parameters. +Another thing to note is that this indirection in the routing is particularly useful for open source plugins that need to leave flexibility in how they are integrated. For plugins that you build internally for your own Backstage application, you can choose to go the route of direct imports or even use concrete routes directly. Although there can be some benefits to using the full routing system even in internal plugins. It can help you structure your routes, and as you will see further down it also helps you manage route parameters. ### Optional External Route References -It is possible to define an `ExternalRouteRef` as optional, so it is not required to bind it in the app. When calling `useRouteRef` with an optional external route, its return signature is changed to `RouteFunc | undefined`, and the returned value can be used used to decide whether a certain link should be displayed or if an action should be taken: +It is possible to define an `ExternalRouteRef` as optional, so it is not required to bind it in the app. When calling `useRouteRef` with an optional external route, its return signature is changed to `RouteFunc | undefined`, and the returned value can be used to decide whether a certain link should be displayed or if an action should be taken: ```tsx // plugins/catalog/src/routes.ts @@ -338,8 +421,8 @@ import { createExternalRouteRef, } from '@backstage/frontend-plugin-api'; -const indexRouteRef = createRouteRef(); -const createComponentRouteRef = createExternalRouteRef({ +export const indexRouteRef = createRouteRef(); +export const createComponentRouteRef = createExternalRouteRef({ optional: true, }); @@ -352,17 +435,17 @@ import { } from '@backstage/frontend-plugin-api'; import { indexRouteRef, createComponentRouteRef } from './routes'; -const indexPage = createPageExtension({ +const catalogIndexPage = createPageExtension({ defaultPath: '/entities', routeRef: indexRouteRef, loader: async () => { - const link = useRouteRef(createComponentRouteRef); + const createComponentLink = useRouteRef(createComponentRouteRef); return (
-

Catalog Entities

+

Index Page

{/* Since the route is optional, rendering the link only if the href is defined */} - {link && Create Component} + {link && Create Component}
); }, @@ -376,7 +459,7 @@ export default createPlugin({ externalRoutes: { createComponent: createComponentRouteRef, }, - extensions: [indexPage], + extensions: [catalogIndexPage], }); // index.ts @@ -396,8 +479,8 @@ import { createSubRouteRef, } from '@backstage/frontend-plugin-api'; -const indexRouteRef = createRouteRef(); -const detailsSubRouteRef = createSubRouteRef({ +export const indexRouteRef = createRouteRef(); +export const detailsSubRouteRef = createSubRouteRef({ parent: indexRouteRef, path: '/details', }); @@ -418,22 +501,22 @@ const DetailsPage = () => (
); -const indexPage = createPageExtension({ +const catalogIndexPage = createPageExtension({ defaultPath: '/entities', routeRef: indexRouteRef, loader: async () => { const Component = () => { const { pathname } = useLocation(); - const indexPath = useRouteRef(indexRouteRef)(); - const detailsPath = useRouteRef(detailsSubRouteRef)(); + const indexLink = useRouteRef(indexRouteRef); + const detailsLink = useRouteRef(detailsSubRouteRef); return (

Index Page

{/* Linking to the index route */} - {pathname === detailsPath && Hide details} + {pathname === detailsLink() && Hide details} {/* Linking to the details sub route */} - {pathname === indexPath && Show details} + {pathname === indexLink() && Show details} {/* Registering the details sub route */} } /> @@ -452,7 +535,7 @@ export default createPlugin({ index: indexRouteRef, details: detailsSubRouteRef, }, - extensions: [indexPage], + extensions: [catalogIndexPage], }); // plugins/catalog/src/index.ts @@ -468,8 +551,8 @@ import { createSubRouteRef, } from '@backstage/frontend-plugin-api'; -const indexRouteRef = createRouteRef(); -const detailsSubRouteRef = createSubRouteRef({ +export const indexRouteRef = createRouteRef(); +export const detailsSubRouteRef = createSubRouteRef({ parent: indexRouteRef, path: '/:name/:namespace/:kind', }); @@ -499,14 +582,17 @@ const DetailsPage = () => { ); }; -const indexPage = createPageExtension({ +const catalogIndexPage = createPageExtension({ defaultPath: '/entities', routeRef: indexRouteRef, loader: async () => { const Component = () => { const { pathname } = useLocation(); - const indexPath = useRouteRef(indexRouteRef)(); - const detailsPath = useRouteRef(detailsSubRouteRef)({ + const indexLink = useRouteRef(indexRouteRef)(); + const detailsLink = useRouteRef(detailsSubRouteRef); + + const indexPath = indexLink(); + const detailsPath = detailsLink({ // Setting the details subroute params kind: 'component', namespace: 'default', @@ -557,7 +643,7 @@ export default createPlugin({ index: indexRouteRef, details: detailsSubRouteRef, }, - extensions: [indexPage], + extensions: [catalogIndexPage], }); // plugins/catalog/src/index.ts From 07a79c695c147b2361dbcad62379083fc1927d74 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 12 Jan 2024 10:32:54 +0100 Subject: [PATCH 129/283] docs(frontend-system): use promise resolve on the route examples Signed-off-by: Camila Belo --- .../frontend-system/architecture/07-routes.md | 149 +++++++++++------- 1 file changed, 96 insertions(+), 53 deletions(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 0fe2a8cc85..723649d7af 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -41,7 +41,7 @@ Note that you almost always want to create the route references themselves in a Route refs do not have any behavior, in other words, they are an opaque type that represents route targets in an app, which are bound to specific paths at runtime, but they provide a level of indirection to help mix together different plugins that otherwise wouldn't know how to route to each other. -The code snippet of the previous section does not indicate which plugin the route belongs to. To do so, you have to use it in the creation of any kind of routable extension, such as a page extension. When this extension is installed in the app it will become associated with the newly created `RouteRef`, making it possible to use the route ref to navigate the the extension. Here's what we need to do: +The previous section code snippet does not indicate which plugin the route belongs to. To do so, you have to use it in the creation of any kind of routable extension, such as a page extension. When this extension is installed in the app it will become associated with the newly created `RouteRef`, making it possible to use the route ref to navigate the extension. Here's what we need to do: ```tsx // plugins/catalog/src/routes.ts @@ -62,7 +62,8 @@ const catalogIndexPage = createPageExtension({ // [2] defaultPath: '/entities', routeRef: indexRouteRef, - loader: async () =>
Index Page
, + // Promise.resolve is a replacement for `import(...)` + loader: () => Promise.resolve(
Index Page
), }); export default createPlugin({ @@ -88,7 +89,7 @@ It may be unclear why we need to pass the route to the plugin once it has alread ### Route Path Parameters -The referenced route can also accepts `params`. Here is how you create a reference for a route that requires a `kind`, `namespace` and `name` params, like in this path `/entities/:kind/:namespace/:name`: +The referenced route can also accepts `params`. Here is how you create a reference for a route that requires a kind, namespace and name `params`, like in this path `/entities/:kind/:namespace/:name`: ```tsx // plugins/catalog/src/routes.ts @@ -136,7 +137,7 @@ import { rootRouteRef, detailsRouteRef } from './routes'; const catalogIndexPage = createPageExtension({ defaultPath: '/entities', routeRef: indexRouteRef, - loader: async () => { + loader: () => { const Component = () => { const detailsLink = useRouteRef(detailsRouteRef); const detailsPath = detailsLink({ @@ -153,7 +154,7 @@ const catalogIndexPage = createPageExtension({ ); }; - return ; + return Promise.resolve(); }, }); @@ -163,7 +164,7 @@ const catalogDetailsPage = createPageExtension({ // It will be their responsibility to make sure that it contains the same parameters, although they don't necessarily need to be in the same order. defaultPath: '/entities/:namespace/:kind/:name', routeRef: detailsRouteRef, - loader: async () => { + loader: () => { const Component = () => { // Getting the parameters from the URL const params = useParams(); @@ -178,7 +179,8 @@ const catalogDetailsPage = createPageExtension({
); }; - return ; + + return Promise.resolve(); }, }); @@ -221,30 +223,42 @@ export const createComponentRouteRef = createExternalRouteRef(); // plugins/catalog/src/plugin.tsx import React from 'react'; -import { createPlugin, createPageExtension, useRouteRef } from '@backstage/frontend-plugin-api'; -import { indexRouteRef, detailsRouteRef, createComponentRouteRef } from './routes'; +import { + createPlugin, + createPageExtension, + useRouteRef, +} from '@backstage/frontend-plugin-api'; +import { + indexRouteRef, + detailsRouteRef, + createComponentRouteRef, +} from './routes'; const catalogIndexPage = createPageExtension({ defaultPath: '/entities', routeRef: indexRouteRef, - loader: async () => { - const createComponentLink = useRouteRef(createComponentRouteRef); + loader: () => { + const Component = () => { + const createComponentLink = useRouteRef(createComponentRouteRef); - return ( -
-

Index Page

- {/* Linking to a create component page without direct reference */} - Create Component -
- ); - } + return ( +
+

Index Page

+ {/* Linking to a create component page without direct reference */} + Create Component +
+ ); + }; + + return Promise.resolve(); + }, }); const catalogDetailsPage = createPageExtension({ name: 'details', defaultPath: '/entities/:namespace/:kind/:name', routeRef: detailsRouteRef, - loader: async () => { + loader: () => { const Component = () => { // Getting the parameters from the URL const params = useParams(); @@ -259,7 +273,8 @@ const catalogDetailsPage = createPageExtension({
); }; - return ; + + return Promise.resolve(); }, }); @@ -268,11 +283,11 @@ export default createPlugin({ routes: { index: indexRouteRef, details: detailsRouteRef, - } + }, externalRoutes: { createComponent: createComponentRouteRef, }, - extensions: [catalogIndexPage] + extensions: [catalogIndexPage, catalogDetailsPage], }); // plugins/catalog/src/index.ts @@ -298,11 +313,12 @@ import { indexRouteRef } from './routes'; const scaffolderIndexPage = createPageExtension({ defaultPath: '/create', routeRef: indexRouteRef, - loader: async () => ( -
-

Create Component

-
- ), + loader: () => + Promise.resolve( +
+

Create Component

+
, + ), }); export default createPlugin({ @@ -317,7 +333,7 @@ export default createPlugin({ export { default } from './plugin'; ``` -One last thing is that external routes can also be parametrize, so if Scaffolder wants to redirect to the Catalog entity details page whenever a new component is created, the Scaffolder plugin can also expose a external route like this: +The Scaffolder plugin can also expose an external route that redirects to the Catalog entity details page whenever a new component is created, such as: ```ts // plugins/scaffolder/src/routes.ts @@ -327,7 +343,7 @@ import { } from '@backstage/frontend-plugin-api'; export const indexRouteRef = createRouteRef(); -export const entityDetailsExternalRouteRef = createExternalRouteRef({ +export const componentDetailsExternalRouteRef = createExternalRouteRef({ // The parameters that must be included in the path of this route reference params: ['kind', 'namespace', 'name'], }); @@ -337,17 +353,37 @@ import React from 'react'; import { createPlugin, createPageExtension, + useRouteRef, } from '@backstage/frontend-plugin-api'; -import { indexRouteRef, entityDetailsExternalRouteRef } from './routes'; +import { indexRouteRef, componentDetailsExternalRouteRef } from './routes'; const scaffolderIndexPage = createPageExtension({ defaultPath: '/create', routeRef: indexRouteRef, - loader: async () => ( -
-

Create Component

-
- ), + loader: () => { + const Component = () => { + const componentDetailsLink = useRouteRef( + componentDetailsExternalRouteRef, + ); + + return ( +
+

Create Component

+ + See component details + +
+ ); + }; + + return Promise.resolve(); + }, }); export default createPlugin({ @@ -356,7 +392,7 @@ export default createPlugin({ index: indexRouteRef, }, externalRoutes: { - entityDetails: entityDetailsExternalRouteRef, + componentDetails: componentDetailsExternalRouteRef, }, extensions: [scaffolderIndexPage], }); @@ -365,7 +401,8 @@ export default createPlugin({ export { default } from './plugin'; ``` -Now let's move on and configure the app to point to the Scaffolder create component page when the Catalog create component ref be used and also to poin to the Catalog entity details page when the Scaffolder entity details ref be used. +Note that external routes can also have path parameters! +Now let's move on and configure the app to point to the Scaffolder create component page when the Catalog create component ref be used and also point to the Catalog entity details page when the Scaffolder component details ref be used. ### Binding External Route References @@ -378,8 +415,10 @@ Using the above example of the Catalog entities list page to the Scaffolder crea app: routes: bindings: + # point to the Scaffolder create component page when the Catalog create component ref be used plugin.catalog.externalRoutes.createComponent: plugin.scaffolder.routes.index - plugin.scaffolder.externalRoutes.entityDetails: plugin.catalog.routes.details + # point to the Catalog details page when the Scaffolder component details ref be used + plugin.scaffolder.externalRoutes.componentDetails: plugin.catalog.routes.details ``` Or via code, in the file where the app is created: @@ -396,7 +435,7 @@ const app = createApp({ createComponent: scaffolder.routes.createComponent, }); bind(scaffolder.externalRoutes, { - entityDetails: catalog.routes.details, + componentDetails: catalog.routes.details, }); }, }); @@ -438,16 +477,20 @@ import { indexRouteRef, createComponentRouteRef } from './routes'; const catalogIndexPage = createPageExtension({ defaultPath: '/entities', routeRef: indexRouteRef, - loader: async () => { - const createComponentLink = useRouteRef(createComponentRouteRef); + loader: () => { + const Component = () => { + const createComponentLink = useRouteRef(createComponentRouteRef); - return ( -
-

Index Page

- {/* Since the route is optional, rendering the link only if the href is defined */} - {link && Create Component} -
- ); + return ( +
+

Index Page

+ {/* Since the route is optional, rendering the link only if the href is defined */} + {link && Create Component} +
+ ); + }; + + return Promise.resolve(); }, }); @@ -504,7 +547,7 @@ const DetailsPage = () => ( const catalogIndexPage = createPageExtension({ defaultPath: '/entities', routeRef: indexRouteRef, - loader: async () => { + loader: () => { const Component = () => { const { pathname } = useLocation(); const indexLink = useRouteRef(indexRouteRef); @@ -525,7 +568,7 @@ const catalogIndexPage = createPageExtension({ ); }; - return ; + return Promise.resolve(); }, }); @@ -585,7 +628,7 @@ const DetailsPage = () => { const catalogIndexPage = createPageExtension({ defaultPath: '/entities', routeRef: indexRouteRef, - loader: async () => { + loader: () => { const Component = () => { const { pathname } = useLocation(); const indexLink = useRouteRef(indexRouteRef)(); @@ -633,7 +676,7 @@ const catalogIndexPage = createPageExtension({ ); }; - return ; + return Promise.resolve(); }, }); From 93fd34024280f612b11e024dc5bedc3ca06e44dc Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 12 Jan 2024 14:24:44 +0100 Subject: [PATCH 130/283] Update docs/frontend-system/architecture/07-routes.md Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 723649d7af..305e200a24 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -18,7 +18,7 @@ The frontend system isn't a single API surface. It is a collection of patterns, ## Route References -In order to address the problem outlined above, we introduced the concept of route references. A `RouteRef` is an abstract path in a Backstage app, and these paths can be configured both at plugin level (by plugin developers) and at instance level (by application integrators). +In order to address the problem outlined above, we introduced the concept of route references. A `RouteRef` is an abstract path in a Backstage app, and these paths can be configured both at plugin level (by plugin developers) and at the app level (by integrators). Plugin developers create a `RouteRef` to expose a path in Backstage's routing system. You will see below how routes are defined programmatically, but before diving into code, let us explain how to configure them at app level. In spite of the fact that plugin developers choose a default route path for the routes their plugin provides, paths are configurable, so app integrators can set a custom path to a route whenever they like to (more information in the following sessions). From c16323db068dd05f8f1c8d38e7fe29fb6da73c15 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 12 Jan 2024 14:24:52 +0100 Subject: [PATCH 131/283] Update docs/frontend-system/architecture/07-routes.md Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 305e200a24..ea839f27b4 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -20,7 +20,7 @@ The frontend system isn't a single API surface. It is a collection of patterns, In order to address the problem outlined above, we introduced the concept of route references. A `RouteRef` is an abstract path in a Backstage app, and these paths can be configured both at plugin level (by plugin developers) and at the app level (by integrators). -Plugin developers create a `RouteRef` to expose a path in Backstage's routing system. You will see below how routes are defined programmatically, but before diving into code, let us explain how to configure them at app level. In spite of the fact that plugin developers choose a default route path for the routes their plugin provides, paths are configurable, so app integrators can set a custom path to a route whenever they like to (more information in the following sessions). +Plugin developers create a `RouteRef` to expose a path in Backstage's routing system. You will see below how routes are defined programmatically, but before diving into code, let us explain how to configure them at app level. In spite of the fact that plugin developers choose a default route path for the routes their plugin provides, paths are configurable, so app integrators can set a custom path to a route whenever they like to (more information in the following sections). There are 3 types of route references: regular route, sub route, and external route, and we will cover both the concept and code definition for each. Keep reading 🙂! From ef87f165992be5a21dcaa056b4ad327a7832e94b Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 12 Jan 2024 14:25:43 +0100 Subject: [PATCH 132/283] Update docs/frontend-system/architecture/07-routes.md Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index ea839f27b4..4b8b98a3e7 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -26,7 +26,7 @@ There are 3 types of route references: regular route, sub route, and external ro ### Creating a Route Reference -Route references, also known as plugins' index pages or regular routes, are created as follows: +Route references, also known as "absolute" or "regular" routes, are created as follows: ```tsx // plugins/catalog/src/routes.ts From ed670cec063f9ab7eaf5349b6113836f8670b08e Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 12 Jan 2024 14:25:58 +0100 Subject: [PATCH 133/283] Update docs/frontend-system/architecture/07-routes.md Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 4b8b98a3e7..15bfe615ac 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -445,7 +445,7 @@ export default app.createRoot(); Given the above binding, using `useRouteRef(createComponentRouteRef)` within the Catalog plugin will let us create a link to whatever path the Scaffolder create component page is mounted at. -Note that we are not importing and using the `RouteRef`s directly in the app, and instead rely on the plugin instance to access routes of the plugins. This is a new convention that was introduced to provide better namespacing and discoverability of routes, as well as reduce the number of separate exports from each plugin package. +Note that we are not importing and using the `RouteRef`s directly in the app, and instead rely on the plugin instance to access routes of the plugins. This provides better namespacing and discoverability of routes, as well as reduce the number of separate exports from each plugin package. Another thing to note is that this indirection in the routing is particularly useful for open source plugins that need to leave flexibility in how they are integrated. For plugins that you build internally for your own Backstage application, you can choose to go the route of direct imports or even use concrete routes directly. Although there can be some benefits to using the full routing system even in internal plugins. It can help you structure your routes, and as you will see further down it also helps you manage route parameters. From fa379b6333b60a7bd3987d70109f1c77f5562539 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 12 Jan 2024 15:12:43 +0100 Subject: [PATCH 134/283] Update docs/frontend-system/architecture/07-routes.md Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 15bfe615ac..2f8d3a5b7a 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -421,7 +421,7 @@ app: plugin.scaffolder.externalRoutes.componentDetails: plugin.catalog.routes.details ``` -Or via code, in the file where the app is created: +We also have the ability to express this in code as an option to `createApp`, but you of course only need to use one of these two methods: ```tsx // packages/app/src/App.tsx From 6f4fbb06ea9d473c6ef697e75571918e4f16b198 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 12 Jan 2024 15:50:48 +0100 Subject: [PATCH 135/283] Update docs/frontend-system/architecture/07-routes.md Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 2f8d3a5b7a..4dd06ffb90 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -35,7 +35,7 @@ import { createRouteRef } from '@backstage/frontend-plugin-api'; export const indexRouteRef = createRouteRef(); ``` -Note that you almost always want to create the route references themselves in a different file than the one that creates the plugin instance, for example a top-level routes.ts. This is to avoid circular imports when you use the route references from other parts of the same plugin. +Note that you often want to create the route references themselves in a different file than the one that creates the plugin instance, for example a top-level routes.ts. This is to avoid circular imports when you use the route references from other parts of the same plugin. ### Providing Route References to Plugins From 1c7ca6f643ab389e2f601c63eb9c04b6956b2175 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 12 Jan 2024 15:51:10 +0100 Subject: [PATCH 136/283] Update docs/frontend-system/architecture/07-routes.md Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 4dd06ffb90..99438dc868 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -39,7 +39,7 @@ Note that you often want to create the route references themselves in a differen ### Providing Route References to Plugins -Route refs do not have any behavior, in other words, they are an opaque type that represents route targets in an app, which are bound to specific paths at runtime, but they provide a level of indirection to help mix together different plugins that otherwise wouldn't know how to route to each other. +Route refs do not have any behavior themselves. They are an opaque value that represents route targets in an app, which are bound to specific paths at runtime. Their role is to provide a level of indirection to help link together different pages that otherwise wouldn't know how to route to each other. The previous section code snippet does not indicate which plugin the route belongs to. To do so, you have to use it in the creation of any kind of routable extension, such as a page extension. When this extension is installed in the app it will become associated with the newly created `RouteRef`, making it possible to use the route ref to navigate the extension. Here's what we need to do: From 88cf8a665ea82f60987b9e84e0c8367d644a8afe Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 12 Jan 2024 15:51:56 +0100 Subject: [PATCH 137/283] Update docs/frontend-system/architecture/07-routes.md Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 99438dc868..efdebaebd0 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -85,7 +85,7 @@ We have completed our journey of creating a plugin page route. This is what the - [2] We associate our route reference with our page by providing it as an option during creation of the page extension. - [3] Finally, our plugin provides both routes and extensions. -It may be unclear why we need to pass the route to the plugin once it has already been passed to the extension, but the explanation can be found in the (Binding External Route References)[#building-external-route-references] section, wait a bit, keep reading and you'll understand why. +It may be unclear why we need to pass the route to the plugin when it has already been passed to the extension. We do that to make it possible for other plugins to route to our page, which is explained in detail in the (Binding External Route References)[#building-external-route-references] section. ### Route Path Parameters From c01052ec3278f349c600c3486fca454efd29b00d Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 12 Jan 2024 15:52:16 +0100 Subject: [PATCH 138/283] Update docs/frontend-system/architecture/07-routes.md Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index efdebaebd0..b069743ef9 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -89,7 +89,7 @@ It may be unclear why we need to pass the route to the plugin when it has alread ### Route Path Parameters -The referenced route can also accepts `params`. Here is how you create a reference for a route that requires a kind, namespace and name `params`, like in this path `/entities/:kind/:namespace/:name`: +Route references optionally accept a `params` option, which will require the listed parameter names to be present in the route path. Here is how you create a reference for a route that requires a `kind`, `namespace` and `name` parameters, like in this path `/entities/:kind/:namespace/:name`: ```tsx // plugins/catalog/src/routes.ts From 6d88c626c0667109001582328d279363506bac52 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 12 Jan 2024 15:52:32 +0100 Subject: [PATCH 139/283] Update docs/frontend-system/architecture/07-routes.md Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index b069743ef9..b4e562aca9 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -103,7 +103,7 @@ export const detailsRouteRef = createRouteRef({ ### Using a Route Reference -You can link to the routes from other pages in the same plugin or you can also link between different plugins pages. In this section we will cover the first scenario, if you are interested in link to a page of a different plugin, please go to the [external routes](#external-router-references) section below. +Route references can be used to link to page in the same plugin, or to pages in a different plugins. In this section we will cover the first scenario, if you are interested in link to a page of a different plugin, please go to the [external routes](#external-router-references) section below. Alright, let's presume that we have a plugin that renders two different pages, and these pages link to each other. From e083d88a23256e7cfccc10491f598902f4c526e3 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 12 Jan 2024 15:52:58 +0100 Subject: [PATCH 140/283] Update docs/frontend-system/architecture/07-routes.md Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index b4e562aca9..3e8c29ddfb 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -105,7 +105,7 @@ export const detailsRouteRef = createRouteRef({ Route references can be used to link to page in the same plugin, or to pages in a different plugins. In this section we will cover the first scenario, if you are interested in link to a page of a different plugin, please go to the [external routes](#external-router-references) section below. -Alright, let's presume that we have a plugin that renders two different pages, and these pages link to each other. +Let's presume that we have a plugin that renders two different pages, and these pages link to each other. First lets create the routes references: From 513919d2669b0c8a30985194f1f340250ab3f47e Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 12 Jan 2024 15:54:06 +0100 Subject: [PATCH 141/283] Update docs/frontend-system/architecture/07-routes.md Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 3e8c29ddfb..a07df23d70 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -402,7 +402,7 @@ export { default } from './plugin'; ``` Note that external routes can also have path parameters! -Now let's move on and configure the app to point to the Scaffolder create component page when the Catalog create component ref be used and also point to the Catalog entity details page when the Scaffolder component details ref be used. +Now let's move on and configure the app to resolve these external routes, so that the Scaffolder links to the Catalog entity page, and the Catalog links to the Scaffolder page. ### Binding External Route References From 9487a419139fbbdb79302fff1e42ee2eb40c6260 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 12 Jan 2024 15:55:12 +0100 Subject: [PATCH 142/283] Update docs/frontend-system/architecture/07-routes.md Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index a07df23d70..c1fd424ae3 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -415,9 +415,9 @@ Using the above example of the Catalog entities list page to the Scaffolder crea app: routes: bindings: - # point to the Scaffolder create component page when the Catalog create component ref be used + # point to the Scaffolder create component page when the Catalog create component ref is used plugin.catalog.externalRoutes.createComponent: plugin.scaffolder.routes.index - # point to the Catalog details page when the Scaffolder component details ref be used + # point to the Catalog details page when the Scaffolder component details ref is used plugin.scaffolder.externalRoutes.componentDetails: plugin.catalog.routes.details ``` From 9f949e27ba57cb86d71a6ca6f1bb4c625aced087 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 12 Jan 2024 17:03:22 +0100 Subject: [PATCH 143/283] docs(routing): try to reduce code snippets Signed-off-by: Camila Belo --- .../frontend-system/architecture/07-routes.md | 664 +++++------------- 1 file changed, 191 insertions(+), 473 deletions(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index c1fd424ae3..0aa6980713 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -10,46 +10,38 @@ description: Frontend routes ## Introduction -This page describes the frontend system that helps bring together content from a multitude of plugins into one Backstage application. +In Backstage, plug-in boundaries and connections must be clearly defined. The app should allow navigation between plug-ins while isolating faults within them. -The core principle of the frontend system is that plugins should have clear boundaries and connections. It should isolate crashes within a plugin, but allow navigation between them. It should allow for plugins to be loaded only when needed, and enable plugins to provide extension points for other plugins to build upon. The frontend system is also built with an app-first mindset, prioritizing simplicity and clarity in the app over that in the plugins and core APIs. - -The frontend system isn't a single API surface. It is a collection of patterns, primitives, and APIs. At the core is the concept of extensions, which are exported by plugins for use in the app. One of the concepts is `RouteRef` which enables us route between pages in a flexible way, and it is especially important when bringing together different open source plugins. +In order to address the problem outlined above, we introduced the concept of `RouteRef` which enables us route between pages in a flexible way, and it is especially important when bringing together different open source plugins. ## Route References -In order to address the problem outlined above, we introduced the concept of route references. A `RouteRef` is an abstract path in a Backstage app, and these paths can be configured both at plugin level (by plugin developers) and at the app level (by integrators). +A `RouteRef` is an abstract path in a Backstage app, and these paths can be configured both at plugin level (by plugin developers) and at the app level (by integrators). Plugin developers create a `RouteRef` to expose a path in Backstage's routing system. You will see below how routes are defined programmatically, but before diving into code, let us explain how to configure them at app level. In spite of the fact that plugin developers choose a default route path for the routes their plugin provides, paths are configurable, so app integrators can set a custom path to a route whenever they like to (more information in the following sections). -There are 3 types of route references: regular route, sub route, and external route, and we will cover both the concept and code definition for each. Keep reading 🙂! +There are 3 types of route references: regular route, sub route, and external route, and we will cover both the concept and code definition for each. ### Creating a Route Reference Route references, also known as "absolute" or "regular" routes, are created as follows: -```tsx -// plugins/catalog/src/routes.ts +```tsx title="plugins/catalog/src/routes.ts" showLineNumbers import { createRouteRef } from '@backstage/frontend-plugin-api'; +// Creates a route reference, which is not yet associated with any plugin page export const indexRouteRef = createRouteRef(); ``` Note that you often want to create the route references themselves in a different file than the one that creates the plugin instance, for example a top-level routes.ts. This is to avoid circular imports when you use the route references from other parts of the same plugin. -### Providing Route References to Plugins - Route refs do not have any behavior themselves. They are an opaque value that represents route targets in an app, which are bound to specific paths at runtime. Their role is to provide a level of indirection to help link together different pages that otherwise wouldn't know how to route to each other. -The previous section code snippet does not indicate which plugin the route belongs to. To do so, you have to use it in the creation of any kind of routable extension, such as a page extension. When this extension is installed in the app it will become associated with the newly created `RouteRef`, making it possible to use the route ref to navigate the extension. Here's what we need to do: +### Providing Route References to Plugins -```tsx -// plugins/catalog/src/routes.ts -import { createRouteRef } from '@backstage/frontend-plugin-api'; +The previous section code snippet does not indicate which plugin the route belongs to. To do so, you have to use it in the creation of any kind of routable extension, such as a page extension: -export const indexRouteRef = createRouteRef(); // [1] - -// plugins/catalog/src/plugin.tsx +```tsx title="plugins/catalog/src/plugin.tsx" {11,17-19} showLineNumbers import React from 'react'; import { createPlugin, @@ -57,42 +49,36 @@ import { } from '@backstage/frontend-plugin-api'; import { indexRouteRef } from './routes'; -// The `name` option is omitted since this is the index page const catalogIndexPage = createPageExtension({ - // [2] + // The `name` option is omitted because this is an index page defaultPath: '/entities', routeRef: indexRouteRef, - // Promise.resolve is a replacement for `import(...)` - loader: () => Promise.resolve(
Index Page
), + loader: () => import('./components').then(m => ), }); export default createPlugin({ - // [3] id: 'catalog', routes: { index: indexRouteRef, }, extensions: [catalogIndexPage], }); - -// plugins/catalog/src/index.ts -export { default } from './plugin'; ``` -We have completed our journey of creating a plugin page route. This is what the code does: +In the example above we have associated a route ref with an plugin page. This is what the code does: -- [1] The line 1 creates a route reference, which is not yet associated with any plugin page; -- [2] We associate our route reference with our page by providing it as an option during creation of the page extension. -- [3] Finally, our plugin provides both routes and extensions. +- Line 11: Associates the `indexRouteRef` with the `catalogIndexPage` extension; +- Line 17 to 19: Provides both the `indexRouteRef` and `catalogIndexPage` via the Catalog plugin. -It may be unclear why we need to pass the route to the plugin when it has already been passed to the extension. We do that to make it possible for other plugins to route to our page, which is explained in detail in the (Binding External Route References)[#building-external-route-references] section. +When this extension is installed in the app it will become associated with the newly created `RouteRef`, making it possible to use the route ref to navigate the extension. -### Route Path Parameters +It may be unclear why we configure the routes option when creating a plugin as the route has already been passed to the extension. We do that to make it possible for other plugins to route to our page, which is explained in detail in the [binding routes](#binding-external-route-references) section. + +### Defining References with Path Parameters Route references optionally accept a `params` option, which will require the listed parameter names to be present in the route path. Here is how you create a reference for a route that requires a `kind`, `namespace` and `name` parameters, like in this path `/entities/:kind/:namespace/:name`: -```tsx -// plugins/catalog/src/routes.ts +```tsx title="plugins/catalog/src/routes.ts" {5} showLineNumbers import { createRouteRef } from '@backstage/frontend-plugin-api'; export const detailsRouteRef = createRouteRef({ @@ -105,303 +91,134 @@ export const detailsRouteRef = createRouteRef({ Route references can be used to link to page in the same plugin, or to pages in a different plugins. In this section we will cover the first scenario, if you are interested in link to a page of a different plugin, please go to the [external routes](#external-router-references) section below. -Let's presume that we have a plugin that renders two different pages, and these pages link to each other. +Suppose we are creating a plugin that renders a Catalog index page with a link to a "Foo" component details page. Here is the code for the index page: -First lets create the routes references: - -```tsx -// plugins/catalog/src/routes.ts -import { createRouteRef } from '@backstage/frontend-plugin-api'; - -export const indexRouteRef = createRouteRef(); - -export const detailsRouteRef = createRouteRef({ - // The parameters that must be included in the path of this route reference - params: ['kind', 'namespace', 'name'], -}); -``` - -Now we are ready to provide these routes via plugin extensions and link between pages: - -```tsx -// plugins/catalog/src/plugin.tsx +```tsx title="plugins/catalog/src/components/IndexPage.tsx" {6,11-15} showLineNumbers import React from 'react'; -import { useParams } from 'react-router'; -import { - createPlugin, - createPageExtension, - useRouteRef, -} from '@backstage/frontend-plugin-api'; -import { rootRouteRef, detailsRouteRef } from './routes'; +import { useRouteRef } from '@backstage/frontend-plugin-api'; +import { detailsRouteRef } from '../routes'; -const catalogIndexPage = createPageExtension({ - defaultPath: '/entities', - routeRef: indexRouteRef, - loader: () => { - const Component = () => { - const detailsLink = useRouteRef(detailsRouteRef); - const detailsPath = detailsLink({ - kind: 'component', - namespace: 'default', - name: 'foo', - }); - - return ( -
-

Index Page

- See details -
- ); - }; - - return Promise.resolve(); - }, -}); - -const catalogDetailsPage = createPageExtension({ - name: 'details', - // It is important to mention here if an integrator configures a different path for this page via config file - // It will be their responsibility to make sure that it contains the same parameters, although they don't necessarily need to be in the same order. - defaultPath: '/entities/:namespace/:kind/:name', - routeRef: detailsRouteRef, - loader: () => { - const Component = () => { - // Getting the parameters from the URL - const params = useParams(); - return ( -
-

Details Page

-
    -
  • Kind: {params.kind}
  • -
  • Namespace: {params.namespace}
  • -
  • Name: {params.name}
  • -
-
- ); - }; - - return Promise.resolve(); - }, -}); - -export default createPlugin({ - id: 'catalog', - routes: { - index: indexRouteRef, - details: detailsRouteRef, - }, - extensions: [catalogIndexPage, catalogDetailsPage], -}); - -// plugins/catalog/src/index.ts -export { default } from './plugin'; +export const IndexPage = () => { + const getDetailsPath = useRouteRef(detailsRouteRef); + return ( +
+

Index Page

+ + See "Foo" details + +
+ ); +}; ``` -During runtime, in the index page, we used a hook `useRouteRef` to get the path to the details page. Because we are linking to pages of the same plugin, we are currently accessing the reference directly, but in the following sections, you will see how to link to pages of different plugins. +Line 6 uses a hook called `useRouteRef` to access a getter function that returns the details page path. On line 11, we call the getter, passing it an object with the kind, namespace, and name. These parameters are used to construct a concrete path to details the "Foo" details page. + +Let's see how the details page can get the parameters from the URL: + +```tsx title="plugins/catalog/src/components/DetailsPage.tsx" {6,11-13} showLineNumbers +import React from 'react'; +import { useRouteRefParams } from '@backstage/frontend-plugin-api'; +import { detailsRouteRef } from '../routes'; + +export const DetailsPage = () => { + const params = useRouteRefParams(detailsRouteRef); + return ( +
+

Details Page

+
    +
  • Kind: {params.kind}
  • +
  • Namespace: {params.namespace}
  • +
  • Name: {params.name}
  • +
+
+ ); +}; +``` + +On line 6, we are using the `useRouteRefParams` hook to retrieve the entity-composed id from the URL. The parameter object contains three values: kind, namespace, and name. We can display these values or call an API using them. + +Since we are linking to pages of the same package, we are using a route ref directly. However, in the following sections, you will see how to link to pages of different plugins. ## External Router References -Now let's assume that we want to link from the Catalog entities list page to the Scaffolder create component page. We don't want to reference the Scaffolder plugin directly, since that would create an unnecessary dependency. It would also provided little flexibility in allowing the app to tie plugins together, with the links instead being dictated by the plugins themselves. To solve this, we use an `ExternalRouteRef`. Much like regular route references, they can be passed to `useRouteRef` to create concrete URLs, but they can not be used in page extensions and instead have to be associated with a target route using route bindings in the app. +External routes are made for linking to a page of an external plugin. +For this section example, let's assume that we want to link from the Catalog entities list page to the Scaffolder create component page. + +We don't want to reference the Scaffolder plugin directly, since that would create an unnecessary dependency. It would also provided little flexibility in allowing the app to tie plugins together, with the links instead being dictated by the plugins themselves. To solve this, we use an `ExternalRouteRef`. Much like regular route references, they can be passed to `useRouteRef` to create concrete URLs, but they can not be used in page extensions and instead have to be associated with a target route using route bindings in the app. We create a new `RouteRef` inside the Scaffolder plugin, using a neutral name that describes its role in the plugin rather than a specific plugin page that it might be linking to, allowing the app to decide the final target. If the Catalog entity list page for example wants to link the Scaffolder create component page in the header, it might declare an `ExternalRouteRef` similar to this: -_Catalog Plugin_ +```tsx title="plugins/catalog/src/routes.ts" showLineNumbers +import { createExternalRouteRef } from '@backstage/frontend-plugin-api'; -```tsx -// plugins/catalog/src/routes.ts -import { - createRouteRef, - createExternalRouteRef, -} from '@backstage/frontend-plugin-api'; +export const createComponentExternalRouteRef = createExternalRouteRef(); +``` -export const indexRouteRef = createRouteRef(); -export const detailsRouteRef = createRouteRef({ - // The parameters that must be included in the path of this route reference - params: ['kind', 'namespace', 'name'], -}); -export const createComponentRouteRef = createExternalRouteRef(); +External routes are also used in a similar way as regular routes: -// plugins/catalog/src/plugin.tsx +```tsx title="plugins/catalog/src/components/IndexPage.tsx" {6,10} showLineNumbers +import React from 'react'; +import { useRouteRef } from '@backstage/frontend-plugin-api'; +import { createComponentExternalRouteRef } from '../routes'; + +export const IndexPage = () => { + const getCreateComponentPath = useRouteRef(createComponentExternalRouteRef); + return ( +
+

Index Page

+ Create Component +
+ ); +}; +``` + +Given the above binding, using `useRouteRef(createComponentExternalRouteRef)` within the Catalog plugin will let us create a link to whatever path the Scaffolder create component page is mounted at. Note that there is no direct dependency between the Catalog plugin and Scaffolder, that is, we are not importing the `createComponentExternalRouteRef` from the Scaffolder package. + +Now the only thing left is to provide the page and external route via a plugin: + +```tsx title="plugins/catalog/src/plugin.tsx" {20-23} showLineNumbers import React from 'react'; import { createPlugin, createPageExtension, useRouteRef, } from '@backstage/frontend-plugin-api'; -import { - indexRouteRef, - detailsRouteRef, - createComponentRouteRef, -} from './routes'; +import { indexRouteRef, createComponentExternalRouteRef } from './routes'; const catalogIndexPage = createPageExtension({ defaultPath: '/entities', routeRef: indexRouteRef, - loader: () => { - const Component = () => { - const createComponentLink = useRouteRef(createComponentRouteRef); - - return ( -
-

Index Page

- {/* Linking to a create component page without direct reference */} - Create Component -
- ); - }; - - return Promise.resolve(); - }, -}); - -const catalogDetailsPage = createPageExtension({ - name: 'details', - defaultPath: '/entities/:namespace/:kind/:name', - routeRef: detailsRouteRef, - loader: () => { - const Component = () => { - // Getting the parameters from the URL - const params = useParams(); - return ( -
-

Details Page

-
    -
  • Kind: {params.kind}
  • -
  • Namespace: {params.namespace}
  • -
  • Name: {params.name}
  • -
-
- ); - }; - - return Promise.resolve(); - }, + loader: () => import('./components').then(m => ), }); export default createPlugin({ id: 'catalog', routes: { index: indexRouteRef, - details: detailsRouteRef, }, externalRoutes: { - createComponent: createComponentRouteRef, + createComponent: createComponentExternalRouteRef, }, - extensions: [catalogIndexPage, catalogDetailsPage], + extensions: [catalogIndexPage], }); - -// plugins/catalog/src/index.ts -export { default } from './plugin'; ``` -_Scaffolder Plugin_ +External routes can also have parameters. For example, if you want to link to an entity's details page from Scaffolder, you'll need to create an external route that receives the same parameters the Catalog details page expects: -```tsx -// plugins/scaffolder/src/routes.ts -import { createRouteRef } from '@backstage/frontend-plugin-api'; +```tsx title="plugins/scaffolder/src/routes.ts" {4} showLineNumbers +import { createExternalRouteRef } from '@backstage/frontend-plugin-api'; -export const indexRouteRef = createRouteRef(); - -// plugins/scaffolder/src/plugin.tsx -import React from 'react'; -import { - createPlugin, - createPageExtension, -} from '@backstage/frontend-plugin-api'; -import { indexRouteRef } from './routes'; - -const scaffolderIndexPage = createPageExtension({ - defaultPath: '/create', - routeRef: indexRouteRef, - loader: () => - Promise.resolve( -
-

Create Component

-
, - ), -}); - -export default createPlugin({ - id: 'scaffolder', - routes: { - index: indexRouteRef, - }, - extensions: [scaffolderIndexPage], -}); - -// plugins/scaffolder/src/index.ts -export { default } from './plugin'; -``` - -The Scaffolder plugin can also expose an external route that redirects to the Catalog entity details page whenever a new component is created, such as: - -```ts -// plugins/scaffolder/src/routes.ts -import { - createRouteRef, - createExternalRouteRef, -} from '@backstage/frontend-plugin-api'; - -export const indexRouteRef = createRouteRef(); -export const componentDetailsExternalRouteRef = createExternalRouteRef({ - // The parameters that must be included in the path of this route reference +export const entityDetailsExternalRouteRef = createExternalRouteRef({ params: ['kind', 'namespace', 'name'], }); - -// plugins/scaffolder/src/plugin.tsx -import React from 'react'; -import { - createPlugin, - createPageExtension, - useRouteRef, -} from '@backstage/frontend-plugin-api'; -import { indexRouteRef, componentDetailsExternalRouteRef } from './routes'; - -const scaffolderIndexPage = createPageExtension({ - defaultPath: '/create', - routeRef: indexRouteRef, - loader: () => { - const Component = () => { - const componentDetailsLink = useRouteRef( - componentDetailsExternalRouteRef, - ); - - return ( -
-

Create Component

- - See component details - -
- ); - }; - - return Promise.resolve(); - }, -}); - -export default createPlugin({ - id: 'scaffolder', - routes: { - index: indexRouteRef, - }, - externalRoutes: { - componentDetails: componentDetailsExternalRouteRef, - }, - extensions: [scaffolderIndexPage], -}); - -// plugins/scaffolder/src/index.ts -export { default } from './plugin'; ``` -Note that external routes can also have path parameters! Now let's move on and configure the app to resolve these external routes, so that the Scaffolder links to the Catalog entity page, and the Catalog links to the Scaffolder page. ### Binding External Route References @@ -410,8 +227,7 @@ The association of external routes is controlled by the app. Each `ExternalRoute Using the above example of the Catalog entities list page to the Scaffolder create component page, we might do something like this in the app configuration file: -```yaml -# app-config.yaml +```yaml title="app-config.yaml" {5,7} showLineNumbers app: routes: bindings: @@ -423,8 +239,7 @@ app: We also have the ability to express this in code as an option to `createApp`, but you of course only need to use one of these two methods: -```tsx -// packages/app/src/App.tsx +```tsx title="packages/app/src/App.tsx" {6-13} showLineNumbers import { createApp } from '@backstage/frontend-app-api'; import catalog from '@backstage/plugin-catalog'; import scaffolder from '@backstage/plugin-scaffolder'; @@ -443,70 +258,41 @@ const app = createApp({ export default app.createRoot(); ``` -Given the above binding, using `useRouteRef(createComponentRouteRef)` within the Catalog plugin will let us create a link to whatever path the Scaffolder create component page is mounted at. - Note that we are not importing and using the `RouteRef`s directly in the app, and instead rely on the plugin instance to access routes of the plugins. This provides better namespacing and discoverability of routes, as well as reduce the number of separate exports from each plugin package. Another thing to note is that this indirection in the routing is particularly useful for open source plugins that need to leave flexibility in how they are integrated. For plugins that you build internally for your own Backstage application, you can choose to go the route of direct imports or even use concrete routes directly. Although there can be some benefits to using the full routing system even in internal plugins. It can help you structure your routes, and as you will see further down it also helps you manage route parameters. ### Optional External Route References -It is possible to define an `ExternalRouteRef` as optional, so it is not required to bind it in the app. When calling `useRouteRef` with an optional external route, its return signature is changed to `RouteFunc | undefined`, and the returned value can be used to decide whether a certain link should be displayed or if an action should be taken: +It is possible to define an `ExternalRouteRef` as optional, so it is not required to bind it in the app. -```tsx -// plugins/catalog/src/routes.ts -import { - createRouteRef, - createExternalRouteRef, -} from '@backstage/frontend-plugin-api'; +```tsx title="plugins/catalog/src/routes.ts" {4} showLineNumbers +import { createExternalRouteRef } from '@backstage/frontend-plugin-api'; -export const indexRouteRef = createRouteRef(); -export const createComponentRouteRef = createExternalRouteRef({ +export const createComponentExternalRouteRef = createExternalRouteRef({ optional: true, }); +``` -// plugins/catalog/src/plugin.tsx +When calling `useRouteRef` with an optional external route, its return signature is changed to `RouteFunc | undefined`, and the returned value can be used to decide whether a certain link should be displayed or if an action should be taken: + +```tsx title="plugins/catalog/src/components/IndexPage.tsx" {11} showLineNumbers import React from 'react'; -import { - createPlugin, - createPageExtension, - useRouteRef, -} from '@backstage/frontend-plugin-api'; -import { indexRouteRef, createComponentRouteRef } from './routes'; +import { useRouteRef } from '@backstage/frontend-plugin-api'; +import { createComponentExternalRouteRef } from '../routes'; -const catalogIndexPage = createPageExtension({ - defaultPath: '/entities', - routeRef: indexRouteRef, - loader: () => { - const Component = () => { - const createComponentLink = useRouteRef(createComponentRouteRef); - - return ( -
-

Index Page

- {/* Since the route is optional, rendering the link only if the href is defined */} - {link && Create Component} -
- ); - }; - - return Promise.resolve(); - }, -}); - -export default createPlugin({ - id: 'catalog', - routes: { - index: indexRouteRef, - }, - externalRoutes: { - createComponent: createComponentRouteRef, - }, - extensions: [catalogIndexPage], -}); - -// index.ts -export { default } from './plugin'; +export const IndexPage = () => { + const getCreateComponentPath = useRouteRef(createComponentExternalRouteRef); + return ( +
+

Index Page

+ {/* Rendering the link only if the getCreateComponentPath is defined */} + {getCreateComponentPath && ( + Create Component + )} +
+ ); +}; ``` ## Sub Route References @@ -515,8 +301,7 @@ The last kind of route refs that can be created are `SubRouteRef`s, which can be For example: -```tsx -// plugins/catalog/src/routes.ts +```tsx title ="plugins/catalog/src/routes.ts" {4,7} showLineNumbers import { createRouteRef, createSubRouteRef, @@ -527,91 +312,65 @@ export const detailsSubRouteRef = createSubRouteRef({ parent: indexRouteRef, path: '/details', }); - -// plugins/catalog/src/plugin.ts -import React from 'react'; -import { Routes, Route, useLocation } from 'react-router-dom'; -import { - createPlugin, - createPageExtension, - useRouteRef, -} from '@backstage/frontend-plugin-api'; -import { indexRouteRef, detailsSubRouteRef } from './routes.ts'; - -const DetailsPage = () => ( -
-

Details Sub Page

-
-); - -const catalogIndexPage = createPageExtension({ - defaultPath: '/entities', - routeRef: indexRouteRef, - loader: () => { - const Component = () => { - const { pathname } = useLocation(); - const indexLink = useRouteRef(indexRouteRef); - const detailsLink = useRouteRef(detailsSubRouteRef); - - return ( -
-

Index Page

- {/* Linking to the index route */} - {pathname === detailsLink() && Hide details} - {/* Linking to the details sub route */} - {pathname === indexLink() && Show details} - {/* Registering the details sub route */} - - } /> - -
- ); - }; - - return Promise.resolve(); - }, -}); - -export default createPlugin({ - id: 'catalog', - routes: { - index: indexRouteRef, - details: detailsSubRouteRef, - }, - extensions: [catalogIndexPage], -}); - -// plugins/catalog/src/index.ts -export { default } from './plugin'; ``` -Subroutes can also receive parameters, here is an example: +There are substantial differences between creating subroutes and regular or external routes because subroutes are associated with regular routes, and the sub route path must be specified. The path string must include the parameters if this sub route has them: -```tsx -// plugins/catalog/src/routes.ts -import { - createRouteRef, - createSubRouteRef, -} from '@backstage/frontend-plugin-api'; - -export const indexRouteRef = createRouteRef(); +```tsx title ="plugins/catalog/src/routes.ts" {4} showLineNumbers +// Omitting rest of the previous example file export const detailsSubRouteRef = createSubRouteRef({ parent: indexRouteRef, path: '/:name/:namespace/:kind', }); +``` -// plugins/catalog/src/plugin.ts +Using subroutes in a page extension is as simple as this: + +```tsx title="plugins/catalog/src/components/IndexPage.ts" showLineNumbers import React from 'react'; -import { Routes, Route, Link, useParams, useLocation } from 'react-router-dom'; -import { - createPlugin, - createPageExtension, - useRouteRef, -} from '@backstage/frontend-plugin-api'; -import { indexRouteRef, detailsSubRouteRef } from './routes.ts'; +import { Routes, Route, useLocation } from 'react-router-dom'; +import { useRouteRef } from '@backstage/frontend-plugin-api'; +import { indexRouteRef, detailsSubRouteRef } from '../routes'; +import { DetailsPage } from './DetailsPage'; -const DetailsPage = () => { - // Getting the parameters from the URL +export const IndexPage = () => { + const { pathname } = useLocation(); + const getIndexPath = useRouteRef(indexRouteRef); + const getDetailsPath = useRouteRef(detailsSubRouteRef); + return ( +
+

Index Page

+ {/* Linking to the details sub route */} + {pathname === getIndexPath() ? ( + // Setting the details sub route params + + Show details + + ) : ( + Hide details + )} + {/* Registering the details sub route */} + + } /> + +
+ ); +}; +``` + +This is how you can get the parameters of a sub route URL: + +```tsx title="plugins/catalog/src/components/DetailsPage.ts" {5} showLineNumbers +import React from 'react'; +import { useParams } from 'react-router-dom'; + +export const DetailsPage = () => { const params = useParams(); return (
@@ -624,60 +383,22 @@ const DetailsPage = () => {
); }; +``` + +Finally, see how a plugin can provide subroutes: + +```tsx title="plugins/catalog/src/plugin.ts" {18} showLineNumbers +import React from 'react'; +import { + createPlugin, + createPageExtension, +} from '@backstage/frontend-plugin-api'; +import { indexRouteRef, detailsSubRouteRef } from './routes'; const catalogIndexPage = createPageExtension({ defaultPath: '/entities', routeRef: indexRouteRef, - loader: () => { - const Component = () => { - const { pathname } = useLocation(); - const indexLink = useRouteRef(indexRouteRef)(); - const detailsLink = useRouteRef(detailsSubRouteRef); - - const indexPath = indexLink(); - const detailsPath = detailsLink({ - // Setting the details subroute params - kind: 'component', - namespace: 'default', - name: 'foo', - }); - - return ( -
-

Index Page

- - - - - - - - - - - - - -
NameDetails
Foo - {/* Linking to the index route */} - {pathname === detailsPath && ( - Hide details - )} - {/* Linking to the details sub route */} - {pathname === indexPath && ( - Show details - )} -
- {/* Registering the details subroute */} - - } /> - -
- ); - }; - - return Promise.resolve(); - }, + loader: () => import('./components').then(m => ), }); export default createPlugin({ @@ -688,7 +409,4 @@ export default createPlugin({ }, extensions: [catalogIndexPage], }); - -// plugins/catalog/src/index.ts -export { default } from './plugin'; ``` From f7a737e52f678a921f975cb3a97b2587f7f726cf Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 17 Jan 2024 14:19:29 +0100 Subject: [PATCH 144/283] Update docs/frontend-system/architecture/07-routes.md Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 0aa6980713..631ea87f97 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -117,7 +117,7 @@ export const IndexPage = () => { }; ``` -Line 6 uses a hook called `useRouteRef` to access a getter function that returns the details page path. On line 11, we call the getter, passing it an object with the kind, namespace, and name. These parameters are used to construct a concrete path to details the "Foo" details page. +We use the `useRouteRef` hook to create a link generator function that returns the details page path. We then call the link generator, passing it an object with the kind, namespace, and name. These parameters are used to construct a concrete path to details the "Foo" details page. Let's see how the details page can get the parameters from the URL: From 6b022bf6c76e30073f2dfe547d98def5602c11c5 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 17 Jan 2024 14:20:37 +0100 Subject: [PATCH 145/283] Update docs/frontend-system/architecture/07-routes.md Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 631ea87f97..2585053683 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -10,9 +10,9 @@ description: Frontend routes ## Introduction -In Backstage, plug-in boundaries and connections must be clearly defined. The app should allow navigation between plug-ins while isolating faults within them. +Each Backstage plugin is an isolated piece of functionality that doesn't typically communicate directly with other plugins. In order to achieve this, there are many parts of the frontend system that provide a layer of indirection for cross-plugin communication, and they routing system is one of them. -In order to address the problem outlined above, we introduced the concept of `RouteRef` which enables us route between pages in a flexible way, and it is especially important when bringing together different open source plugins. +The Backstage routing system makes it possible to implement navigation across plugin boundaries, without each individual plugin knowing the concrete path or location of other plugins in the routing hierarchy, or even its own. This is achieved through the concept of route references, which are opaque reference values that can be shared and used to create concrete links to different parts of an app. ## Route References From 4082cd192a1a14c46208eeb60ba1c0b1c4df01fd Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 17 Jan 2024 14:21:09 +0100 Subject: [PATCH 146/283] Update docs/frontend-system/architecture/07-routes.md Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 2585053683..6326f848d5 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -39,7 +39,7 @@ Route refs do not have any behavior themselves. They are an opaque value that re ### Providing Route References to Plugins -The previous section code snippet does not indicate which plugin the route belongs to. To do so, you have to use it in the creation of any kind of routable extension, such as a page extension: +The code snippet in the previous section does not indicate which plugin the route belongs to. To do so, you have to use it in the creation of any kind of routable extension, such as a page extension: ```tsx title="plugins/catalog/src/plugin.tsx" {11,17-19} showLineNumbers import React from 'react'; From 01167e332dff4b27066517fc57fffcedce19e365 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 17 Jan 2024 14:31:32 +0100 Subject: [PATCH 147/283] Update docs/frontend-system/architecture/07-routes.md Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 6326f848d5..918fddb43c 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -16,7 +16,7 @@ The Backstage routing system makes it possible to implement navigation across pl ## Route References -A `RouteRef` is an abstract path in a Backstage app, and these paths can be configured both at plugin level (by plugin developers) and at the app level (by integrators). +A `RouteRef` is an abstract path in a Backstage app, and these paths can be configured both at plugin level (by plugin developers) and at the app level (by integrators). It is up to plugin developers to create route references for any page content in their plugin that they want it to be possible to link to or from. Plugin developers create a `RouteRef` to expose a path in Backstage's routing system. You will see below how routes are defined programmatically, but before diving into code, let us explain how to configure them at app level. In spite of the fact that plugin developers choose a default route path for the routes their plugin provides, paths are configurable, so app integrators can set a custom path to a route whenever they like to (more information in the following sections). From fffed2e4dadf0d0acf5f81cc5653e7f43165785d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 17 Jan 2024 14:39:50 +0100 Subject: [PATCH 148/283] Delete contrib/chart directory These charts are no longer maintained, backstage/charts should be used instead. Signed-off-by: Patrik Oldsberg --- contrib/chart/backstage/Chart.lock | 6 - contrib/chart/backstage/Chart.yaml | 30 -- contrib/chart/backstage/README.md | 282 ----------------- .../files/app-config.development.yaml.tpl | 51 ---- .../backstage/files/create-backend-dbs.sql | 13 - .../chart/backstage/templates/_helpers.tpl | 286 ------------------ .../templates/backend-deployment.yaml | 98 ------ .../backstage/templates/backend-secret.yaml | 24 -- .../templates/backstage-app-config.yaml | 27 -- .../templates/backstage-auth-config.yaml | 21 -- .../templates/frontend-deployment.yaml | 66 ---- .../chart/backstage/templates/ingress.yaml | 150 --------- contrib/chart/backstage/templates/issuer.yaml | 19 -- .../templates/lighthouse-config.yaml | 12 - .../templates/lighthouse-deployment.yaml | 86 ------ .../templates/postgresql-ca-config.yaml | 21 -- .../templates/postgresql-certs-secret.yaml | 16 - .../templates/postgresql-initdb-secret.yaml | 14 - .../postgresql-password-backend-secret.yaml | 15 - ...postgresql-password-lighthouse-secret.yaml | 17 -- .../templates/tests/test-app-connection.yaml | 23 -- .../templates/tests/test-postgresql.yaml | 33 -- contrib/chart/backstage/values.yaml | 216 ------------- 23 files changed, 1526 deletions(-) delete mode 100644 contrib/chart/backstage/Chart.lock delete mode 100644 contrib/chart/backstage/Chart.yaml delete mode 100644 contrib/chart/backstage/README.md delete mode 100644 contrib/chart/backstage/files/app-config.development.yaml.tpl delete mode 100644 contrib/chart/backstage/files/create-backend-dbs.sql delete mode 100644 contrib/chart/backstage/templates/_helpers.tpl delete mode 100644 contrib/chart/backstage/templates/backend-deployment.yaml delete mode 100644 contrib/chart/backstage/templates/backend-secret.yaml delete mode 100644 contrib/chart/backstage/templates/backstage-app-config.yaml delete mode 100644 contrib/chart/backstage/templates/backstage-auth-config.yaml delete mode 100644 contrib/chart/backstage/templates/frontend-deployment.yaml delete mode 100644 contrib/chart/backstage/templates/ingress.yaml delete mode 100644 contrib/chart/backstage/templates/issuer.yaml delete mode 100644 contrib/chart/backstage/templates/lighthouse-config.yaml delete mode 100644 contrib/chart/backstage/templates/lighthouse-deployment.yaml delete mode 100644 contrib/chart/backstage/templates/postgresql-ca-config.yaml delete mode 100644 contrib/chart/backstage/templates/postgresql-certs-secret.yaml delete mode 100644 contrib/chart/backstage/templates/postgresql-initdb-secret.yaml delete mode 100644 contrib/chart/backstage/templates/postgresql-password-backend-secret.yaml delete mode 100644 contrib/chart/backstage/templates/postgresql-password-lighthouse-secret.yaml delete mode 100644 contrib/chart/backstage/templates/tests/test-app-connection.yaml delete mode 100644 contrib/chart/backstage/templates/tests/test-postgresql.yaml delete mode 100644 contrib/chart/backstage/values.yaml diff --git a/contrib/chart/backstage/Chart.lock b/contrib/chart/backstage/Chart.lock deleted file mode 100644 index bd909c1071..0000000000 --- a/contrib/chart/backstage/Chart.lock +++ /dev/null @@ -1,6 +0,0 @@ -dependencies: -- name: postgresql - repository: https://charts.bitnami.com/bitnami - version: 13.2.30 -digest: sha256:7b558cf1628b8cce366c980f20bd80a3cd7685fe419e43ee9d6df75bc577ec20 -generated: "2024-01-15T11:57:35.306830879Z" diff --git a/contrib/chart/backstage/Chart.yaml b/contrib/chart/backstage/Chart.yaml deleted file mode 100644 index f926c1b0d7..0000000000 --- a/contrib/chart/backstage/Chart.yaml +++ /dev/null @@ -1,30 +0,0 @@ -apiVersion: v2 -name: backstage -description: A Helm chart for Backstage -type: application - -# This is the chart version. This version number should be incremented each time you make changes -# to the chart and its templates, including the app version. -version: 0.1.3 - -# This is the version number of the application being deployed. This version number should be -# incremented each time you make changes to the application. -appVersion: v0.1.1-alpha.23 - -sources: - - https://github.com/backstage/backstage - - https://github.com/spotify/lighthouse-audit-service - -dependencies: - - name: postgresql - condition: postgresql.enabled - version: 13.2.30 - repository: https://charts.bitnami.com/bitnami - -maintainers: - - name: Martina Iglesias Fernández - email: martina@roadie.io - url: https://roadie.io - - name: David Tuite - email: david@roadie.io - url: https://roadie.io diff --git a/contrib/chart/backstage/README.md b/contrib/chart/backstage/README.md deleted file mode 100644 index 40bb2666bc..0000000000 --- a/contrib/chart/backstage/README.md +++ /dev/null @@ -1,282 +0,0 @@ -# Backstage demo helm charts - -This folder contains Helm charts that can easily create a Kubernetes deployment of a demo Backstage app. - -### Pre-requisites - -These charts depend on the `nginx-ingress` controller being present in the cluster. If it's not already installed you -can run: - -```shell -helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx -helm install nginx-ingress ingress-nginx/ingress-nginx -``` - -### Installing the charts - -After choosing a DNS name where backstage will be hosted create a yaml file for your custom configuration. - -```yaml -appConfig: - app: - baseUrl: https://backstage.mydomain.com - title: Backstage - backend: - baseUrl: https://backstage.mydomain.com - cors: - origin: https://backstage.mydomain.com - lighthouse: - baseUrl: https://backstage.mydomain.com/lighthouse-api - techdocs: - storageUrl: https://backstage.mydomain.com/api/techdocs/static/docs - requestUrl: https://backstage.mydomain.com/api/techdocs -``` - -Then use it to run: - -```shell -git clone https://github.com/backstage/backstage.git -cd contrib/chart/backstage -helm dependency update -helm install -f backstage-mydomain.yaml backstage . -``` - -This command will deploy the following pieces: - -- Backstage frontend -- Backstage backend with scaffolder and auth plugins -- (optional) a PostgreSQL instance -- lighthouse plugin -- ingress - -After a few minutes Backstage should be up and running in your cluster under the DNS specified earlier. - -Make sure to create the appropriate DNS entry in your infrastructure. To find the public IP address run: - -```shell -$ kubectl get ingress -NAME HOSTS ADDRESS PORTS AGE -backstage-ingress * 123.1.2.3 80 17m -``` - -> **NOTE**: this is not a production ready deployment. - -## Customization - -### Issue certificates - -These charts can install or reuse a `clusterIssuer` to generate certificates for the backstage `ingress`. To do that: - -1. [Install][install-cert-manager] or make sure [cert-manager][cert-manager] is installed in the cluster. -2. Enable the issuer in the charts. This will first check if there is a `letsencrypt` issuer already deployed in your - cluster and deploy one if it doesn't exist. - -To enable it you need to provide a valid email address in the chart's values: - -```yaml -issuer: - email: me@example.com - clusterIssuer: 'letsencrypt-prod' -``` - -By default, the charts use `letsencrypt-staging` so in the above example we instruct helm to use the production issuer -instead. - -[cert-manager]: https://cert-manager.io/docs/ -[install-cert-manager]: https://cert-manager.io/docs/installation/kubernetes/#installing-with-helm - -### Custom PostgreSQL instance - -Configuring a connection to an existing PostgreSQL instance is possible through the chart's values. - -First create a yaml file with the configuration you want to override, for example `backstage-prod.yaml`: - -```yaml -postgresql: - enabled: false - -appConfig: - app: - baseUrl: https://backstage-demo.mydomain.com - title: Backstage - backend: - baseUrl: https://backstage-demo.mydomain.com - cors: - origin: https://backstage-demo.mydomain.com - database: - client: pg - connection: - database: backstage_plugin_catalog - host: - user: - password: - lighthouse: - baseUrl: https://backstage-demo.mydomain.com/lighthouse-api - -lighthouse: - database: - client: pg - connection: - host: - user: - password: - database: lighthouse_audit_service -``` - -For the CA, create a `configMap` named `--postgres-ca` with a file called `ca.crt`: - -```shell -kubectl create configmap my-company-backstage-postgres-ca --from-file=ca.crt" -``` - -or disable CA mount - -```yaml -backend: - postgresCertMountEnabled: false - -lighthouse: - postgresCertMountEnabled: false -``` - -> Where the release name contains the chart name "backstage" then only the release name will be used. - -Now install the helm chart: - -```shell -cd contrib/chart/backstage -helm install -f backstage-prod.yaml my-backstage . -``` - -### Use your own docker images - -The docker images used for the deployment can be configured through the charts values: - -```yaml -frontend: - image: - repository: - tag: - -backend: - image: - repository: - tag: - -lighthouse: - image: - repository: - tag: -``` - -### Use a private docker repo - -Create a docker-registry secret - -```shell -kubectl create secret docker-registry # args -``` - -> For private images on docker hub --docker-server can be set to docker.io - -Reference the secret in your chart values - -```yaml -dockerRegistrySecretName: -``` - -### Different namespace - -To install the charts a specific namespace use `--namespace `: - -```shell -helm install -f my_values.yaml --namespace demos backstage . -``` - -### Disable loading of demo data - -To deploy backstage with the pre-loaded demo data disable `backend.demoData`: - -```shell -helm install -f my_values.yaml --set backend.demoData=false backstage . -``` - -### Other options - -For more customization options take a look at the [values.yaml](/contrib/chart/backstage/values.yaml) file. - -## Troubleshooting - -Some resources created by these charts are meant to survive after upgrades and even after uninstalls. When -troubleshooting these charts it can be useful to delete these resources between re-installs. - -Secrets: - -``` --postgresql-certs -- contains the certificates used by the deployed PostgreSQL -``` - -Persistent volumes: - -``` -data--postgresql-0 -- this is the data volume used by PostgreSQL to store data and configuration -``` - -> **NOTE**: this volume also stores the configuration for PostgreSQL which includes things like the password for the -> `postgres` user. This means that uninstalling and re-installing the charts with `postgres.enabled` set to `true` and -> auto generated passwords will fail. The solution is to delete this volume with -> `kubectl delete pvc data--postgresql-0` - -ConfigMaps: - -``` --postgres-ca -- contains the generated CA certificate for PostgreSQL when `postgres` is enabled -``` - -#### Unable to verify signature - -``` -Backend failed to start up Error: unable to verify the first certificate - at TLSSocket.onConnectSecure (_tls_wrap.js:1501:34) - at TLSSocket.emit (events.js:315:20) - at TLSSocket._finishInit (_tls_wrap.js:936:8) - at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:710:12) { - code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' -``` - -This error happens in the backend when it tries to connect to the configured PostgreSQL database and the specified CA is not correct. The solution is to make sure that the contents of the `configMap` that holds the certificate match the CA for the PostgreSQL instance. A workaround is to set `appConfig.backend.database.connection.ssl.rejectUnauthorized` to `false` in the chart's values. - -#### Multi-Platform Kubernetes Services - -If you are running a multi-platform Kubernetes service with Windows and Linux nodes then you will need to apply a `nodeSelector` to the Helm chart to ensure that pods are scheduled onto the correct platform nodes. - -Add the following to your Helm values file: - -```yaml -global: - nodeSelector: - kubernetes.io/os: linux - -# If using Postgres Chart also add -postgresql: - master: - nodeSelector: - kubernetes.io/os: linux - slave: - nodeSelector: - kubernetes.io/os: linux -``` - - - -## Uninstalling Backstage - -To uninstall Backstage simply run: - -```shell -RELEASE_NAME= # use `helm list` to find out the name -helm uninstall ${RELEASE_NAME} -kubectl delete pvc data-${RELEASE_NAME}-postgresql-0 -kubectl delete secret ${RELEASE_NAME}-postgresql-certs -kubectl delete configMap ${RELEASE_NAME}-postgres-ca -``` diff --git a/contrib/chart/backstage/files/app-config.development.yaml.tpl b/contrib/chart/backstage/files/app-config.development.yaml.tpl deleted file mode 100644 index 105ba3b259..0000000000 --- a/contrib/chart/backstage/files/app-config.development.yaml.tpl +++ /dev/null @@ -1,51 +0,0 @@ -backend: - lighthouseHostname: {{ include "lighthouse.serviceName" . | quote }} - listen: - port: {{ .Values.appConfig.backend.listen.port | default 7007 }} - database: - client: {{ .Values.appConfig.backend.database.client | quote }} - connection: - host: {{ include "backend.postgresql.host" . | quote }} - port: {{ include "backend.postgresql.port" . | quote }} - user: {{ include "backend.postgresql.user" . | quote }} - database: {{ .Values.appConfig.backend.database.connection.database | quote }} - ssl: - rejectUnauthorized: {{ .Values.appConfig.backend.database.connection.ssl.rejectUnauthorized | quote }} - ca: {{ include "backstage.backend.postgresCaFilename" . | quote }} - -catalog: -{{- if .Values.backend.demoData }} - locations: - # Backstage example components - - type: github - target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/all-components.yaml - # Example component for github-actions - - type: github - target: https://github.com/backstage/backstage/blob/master/plugins/github-actions/examples/sample.yaml - # Example component for techdocs - - type: github - target: https://github.com/backstage/backstage/blob/master/plugins/techdocs-backend/examples/documented-component/documented-component.yaml - # Backstage example APIs - - type: github - target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/all-apis.yaml - # Backstage example templates - - type: github - target: https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend/sample-templates/all-templates.yaml -{{- else }} - locations: [] -{{- end }} - -auth: - providers: - microsoft: null - -scaffolder: - azure: null - - -sentry: - organization: {{ .Values.appConfig.sentry.organization | quote }} - -techdocs: - generator: - runIn: 'local' \ No newline at end of file diff --git a/contrib/chart/backstage/files/create-backend-dbs.sql b/contrib/chart/backstage/files/create-backend-dbs.sql deleted file mode 100644 index 043ff7daf5..0000000000 --- a/contrib/chart/backstage/files/create-backend-dbs.sql +++ /dev/null @@ -1,13 +0,0 @@ -{{ $backendDb := .Values.appConfig.backend.database.connection.database }} -{{ $lighthouseDb := .Values.lighthouse.database.connection.database }} -{{ $user := .Values.global.postgresql.postgresqlUsername }} - -grant all privileges on database {{ $backendDb }} to {{ $user }}; - -create database backstage_plugin_auth; -grant all privileges on database backstage_plugin_auth to {{ $user }}; - -{{ if not (eq $backendDb $lighthouseDb) }} -create database {{ $lighthouseDb }}; -grant all privileges on database {{ $lighthouseDb }} to {{ $user }}; -{{ end }} diff --git a/contrib/chart/backstage/templates/_helpers.tpl b/contrib/chart/backstage/templates/_helpers.tpl deleted file mode 100644 index 123d4dba5b..0000000000 --- a/contrib/chart/backstage/templates/_helpers.tpl +++ /dev/null @@ -1,286 +0,0 @@ -{{/* -Expand the name of the chart. -*/}} -{{- define "backstage.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "backstage.fullname" -}} -{{- if .Values.fullnameOverride -}} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- .Release.Name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "backstage.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Common App labels -*/}} -{{- define "backstage.app.labels" -}} -app.kubernetes.io/name: {{ include "backstage.name" . }}-app -helm.sh/chart: {{ include "backstage.chart" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end -}} - -{{/* -Common Backend labels -*/}} -{{- define "backstage.backend.labels" -}} -app.kubernetes.io/name: {{ include "backstage.name" . }}-backend -helm.sh/chart: {{ include "backstage.chart" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end -}} - -{{/* -Name for postgresql dependency -See https://github.com/helm/helm/issues/3920#issuecomment-686913512 -*/}} -{{- define "backstage.postgresql.fullname" -}} -{{ printf "%s-%s" .Release.Name .Values.postgresql.nameOverride }} -{{- end -}} - - -{{/* -Create the name of the service account to use for the app -*/}} -{{- define "backstage.app.serviceAccountName" -}} -{{- if .Values.app.serviceAccount.create -}} - {{ default "default" .Values.app.serviceAccount.name }} -{{- else -}} - {{ default "default" .Values.app.serviceAccount.name }} -{{- end -}} -{{- end -}} - -{{/* -Create the name of the service account to use for the backend -*/}} -{{- define "backstage.backend.serviceAccountName" -}} -{{- if .Values.backend.serviceAccount.create -}} - {{ default default .Values.backend.serviceAccount.name }} -{{- else -}} - {{ default "default" .Values.backend.serviceAccount.name }} -{{- end -}} -{{- end -}} - -{{/* -Path to the CA certificate file in the backend -*/}} -{{- define "backstage.backend.postgresCaFilename" -}} -{{ include "backstage.backend.postgresCaDir" . }}/{{- required "The name for the CA certificate file for postgresql is required" .Values.global.postgresql.caFilename }} -{{- end -}} -{{/* - -{{/* -Directory path to the CA certificate file in the backend -*/}} -{{- define "backstage.backend.postgresCaDir" -}} -{{- if .Values.appConfig.backend.database.connection.ssl.ca -}} - {{ .Values.appConfig.backend.database.connection.ssl.ca }} -{{- else -}} -/etc/postgresql -{{- end -}} -{{- end -}} -{{/* - -Path to the CA certificate file in lighthouse -*/}} -{{- define "backstage.lighthouse.postgresCaFilename" -}} -{{ include "backstage.lighthouse.postgresCaDir" . }}/{{- required "The name for the CA certificate file for postgresql is required" .Values.global.postgresql.caFilename }} -{{- end -}} - -{{/* -Directory path to the CA certificate file in lighthouse -*/}} -{{- define "backstage.lighthouse.postgresCaDir" -}} -{{- if .Values.lighthouse.database.pathToDatabaseCa -}} - {{ .Values.lighthouse.database.pathToDatabaseCa }} -{{- else -}} -/etc/postgresql -{{- end -}} -{{- end -}} -{{/* - -{{/* -Generate ca for postgresql -*/}} -{{- define "backstage.postgresql.generateCA" -}} -{{- $ca := .ca | default (genCA (include "backstage.postgresql.fullname" .) 365) -}} -{{- $_ := set . "ca" $ca -}} -{{- $ca.Cert -}} -{{- end -}} - -{{/* -Generate certificates for postgresql -*/}} -{{- define "generateCerts" -}} -{{- $postgresName := (include "backstage.postgresql.fullname" .) }} -{{- $altNames := list $postgresName ( printf "%s.%s" $postgresName .Release.Namespace ) ( printf "%s.%s.svc" ( $postgresName ) .Release.Namespace ) -}} -{{- $ca := .ca | default (genCA (include "backstage.postgresql.fullname" .) 365) -}} -{{- $_ := set . "ca" $ca -}} -{{- $cert := genSignedCert ( $postgresName ) nil $altNames 365 $ca -}} -tls.crt: {{ $cert.Cert | b64enc }} -tls.key: {{ $cert.Key | b64enc }} -{{- end -}} - -{{/* -Generate a password for the postgres user used for the connections from the backend and lighthouse -*/}} -{{- define "postgresql.generateUserPassword" -}} -{{- $pgPassword := .pgPassword | default ( randAlphaNum 12 ) -}} -{{- $_ := set . "pgPassword" $pgPassword -}} -{{ $pgPassword}} -{{- end -}} - -{{/* -Name of the backend service -*/}} -{{- define "backend.serviceName" -}} -{{ include "backstage.fullname" . }}-backend -{{- end -}} - -{{/* -Name of the frontend service -*/}} -{{- define "frontend.serviceName" -}} -{{ include "backstage.fullname" . }}-frontend -{{- end -}} - -{{/* -Name of the lighthouse backend service -*/}} -{{- define "lighthouse.serviceName" -}} -{{ include "backstage.fullname" . }}-lighthouse -{{- end -}} - -{{/* -Name of the postgresql service -*/}} -{{- define "postgresql.serviceName" -}} -{{- include "backstage.postgresql.fullname" . }} -{{- end -}} - -{{/* -Postgres host for lighthouse -*/}} -{{- define "lighthouse.postgresql.host" -}} -{{- if .Values.postgresql.enabled }} -{{- include "postgresql.serviceName" . }} -{{- else -}} -{{- required "A valid .Values.lighthouse.database.connection.host is required when postgresql is not enabled" .Values.lighthouse.database.connection.host -}} -{{- end -}} -{{- end -}} - -{{/* -Postgres host for the backend -*/}} -{{- define "backend.postgresql.host" -}} -{{- if .Values.postgresql.enabled }} -{{- include "postgresql.serviceName" . }} -{{- else -}} -{{- required "A valid .Values.appConfig.backend.database.connection.host is required when postgresql is not enabled" .Values.appConfig.backend.database.connection.host -}} -{{- end -}} -{{- end -}} - -{{/* -Postgres port for the backend -*/}} -{{- define "backend.postgresql.port" -}} -{{- if .Values.postgresql.enabled }} -{{- .Values.postgresql.service.port }} -{{- else if .Values.appConfig.backend.database.connection.port -}} -{{- .Values.appConfig.backend.database.connection.port }} -{{- else -}} -5432 -{{- end -}} -{{- end -}} - -{{/* -Postgres port for lighthouse -*/}} -{{- define "lighthouse.postgresql.port" -}} -{{- if .Values.postgresql.enabled }} -{{- .Values.postgresql.service.port }} -{{- else if .Values.lighthouse.database.connection.port -}} -{{- .Values.lighthouse.database.connection.port }} -{{- else -}} -5432 -{{- end -}} -{{- end -}} - -{{/* -Postgres user for backend -*/}} -{{- define "backend.postgresql.user" -}} -{{- if .Values.postgresql.enabled }} -{{- .Values.global.postgresql.postgresqlUsername }} -{{- else -}} -{{- required "A valid .Values.appConfig.backend.database.connection.user is required when postgresql is not enabled" .Values.appConfig.backend.database.connection.user -}} -{{- end -}} -{{- end -}} - -{{/* -Postgres user for lighthouse -*/}} -{{- define "lighthouse.postgresql.user" -}} -{{- if .Values.postgresql.enabled }} -{{- .Values.global.postgresql.postgresqlUsername }} -{{- else -}} -{{- required "A valid .Values.lighthouse.database.connection.user is required when postgresql is not enabled" .Values.lighthouse.database.connection.user -}} -{{- end -}} -{{- end -}} - -{{/* -Postgres password secret for backend -*/}} -{{- define "backend.postgresql.passwordSecret" -}} -{{- if .Values.postgresql.enabled }} -{{- template "backstage.postgresql.fullname" . }} -{{- else -}} -{{ $secretName := (printf "%s-backend-postgres" (include "backstage.fullname" . )) }} -{{- required "A valid .Values.appConfig.backend.database.connection.password is required when postgresql is not enabled" $secretName -}} -{{- end -}} -{{- end -}} - -{{/* -Postgres password for lighthouse -*/}} -{{- define "lighthouse.postgresql.passwordSecret" -}} -{{- if .Values.postgresql.enabled }} -{{- template "backstage.postgresql.fullname" . }} -{{- else -}} -{{ $secretName := (printf "%s-lighthouse-postgres" (include "backstage.fullname" . )) }} -{{- required "A valid .Values.lighthouse.database.connection.password is required when postgresql is not enabled" $secretName -}} -{{- end -}} -{{- end -}} - -{{/* -app-config file name -*/}} -{{- define "backstage.appConfigFilename" -}} -{{- "app-config.development.yaml" -}} -{{- end -}} diff --git a/contrib/chart/backstage/templates/backend-deployment.yaml b/contrib/chart/backstage/templates/backend-deployment.yaml deleted file mode 100644 index 0fa6b7fbe2..0000000000 --- a/contrib/chart/backstage/templates/backend-deployment.yaml +++ /dev/null @@ -1,98 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "backstage.fullname" . }}-backend - -spec: - replicas: {{ .Values.backend.replicaCount }} - - selector: - matchLabels: - app: backstage - component: backend - - template: - metadata: - annotations: - ad.datadoghq.com/backstage.logs: '[{"source":"backstage","service":"backend"}]' - labels: - app: backstage - component: backend - - spec: - {{- if .Values.dockerRegistrySecretName }} - imagePullSecrets: - - name: {{ .Values.dockerRegistrySecretName }} - {{- end}} - containers: - - name: {{ .Chart.Name }}-backend - command: ["node"] - args: - - "packages/backend" - - "--config" - - "app-config.yaml" - - "--config" - - {{ printf "/usr/src/app/%s" (include "backstage.appConfigFilename" .) | quote }} - image: {{ .Values.backend.image.repository }}:{{ .Values.backend.image.tag }} - imagePullPolicy: {{ .Values.backend.image.pullPolicy }} - ports: - - containerPort: {{ .Values.backend.containerPort }} - resources: - {{- toYaml .Values.backend.resources | nindent 12 }} - - envFrom: - - secretRef: - name: {{ include "backstage.fullname" . }}-backend - - configMapRef: - name: {{ include "backstage.fullname" . }}-app-env - - configMapRef: - name: {{ include "backstage.fullname" . }}-auth - env: - - name: NODE_ENV - value: {{ .Values.backend.nodeEnv | default "development" }} - - name: APP_CONFIG_backend_database_connection_password - valueFrom: - secretKeyRef: - name: {{ include "backend.postgresql.passwordSecret" .}} - key: postgresql-password - volumeMounts: - {{- if .Values.backend.postgresCertMountEnabled }} - - name: postgres-ca - mountPath: {{ include "backstage.backend.postgresCaDir" . }} - {{- end }} - - name: app-config - mountPath: {{ printf "/usr/src/app/%s" (include "backstage.appConfigFilename" .) }} - subPath: {{ include "backstage.appConfigFilename" . }} - - volumes: - {{- if .Values.backend.postgresCertMountEnabled }} - - name: postgres-ca - configMap: - name: {{ include "backstage.fullname" . }}-postgres-ca - {{- end }} - - name: app-config - configMap: - name: {{ include "backstage.fullname" . }}-app-config - - {{- if .Values.global.nodeSelector }} - nodeSelector: {{- toYaml .Values.global.nodeSelector | nindent 8 }} - {{- end }} - -{{- if .Values.backend.enabled }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ include "backend.serviceName" . }} - -spec: - ports: - - port: 80 - targetPort: {{ .Values.backend.containerPort }} - - selector: - app: backstage - component: backend - - type: {{ .Values.backend.serviceType }} -{{- end }} diff --git a/contrib/chart/backstage/templates/backend-secret.yaml b/contrib/chart/backstage/templates/backend-secret.yaml deleted file mode 100644 index 299d893ec4..0000000000 --- a/contrib/chart/backstage/templates/backend-secret.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- if .Values.backend.enabled }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ include "backstage.fullname" . }}-backend -type: Opaque -stringData: - AUTH_GOOGLE_CLIENT_SECRET: {{ .Values.auth.google.clientSecret }} - AUTH_GITHUB_CLIENT_SECRET: {{ .Values.auth.github.clientSecret }} - AUTH_GITLAB_CLIENT_SECRET: {{ .Values.auth.gitlab.clientSecret }} - AUTH_OKTA_CLIENT_SECRET: {{ .Values.auth.okta.clientSecret }} - AUTH_OAUTH2_CLIENT_SECRET: {{ .Values.auth.oauth2.clientSecret }} - AUTH_AUTH0_CLIENT_SECRET: {{ .Values.auth.auth0.clientSecret }} - AUTH_MICROSOFT_CLIENT_SECRET: {{ .Values.auth.microsoft.clientSecret }} - SENTRY_TOKEN: {{ .Values.auth.sentryToken }} - ROLLBAR_ACCOUNT_TOKEN: {{ .Values.auth.rollbarAccountToken }} - CIRCLECI_AUTH_TOKEN: {{ .Values.auth.circleciAuthToken }} - GITHUB_TOKEN: {{ .Values.auth.githubToken }} - GITLAB_TOKEN: {{ .Values.auth.gitlabToken }} - AZURE_TOKEN: {{ .Values.auth.azure.api.token }} - NEW_RELIC_REST_API_KEY: {{ .Values.auth.newRelicRestApiKey }} - TRAVISCI_AUTH_TOKEN: {{ .Values.auth.travisciAuthToken }} - PAGERDUTY_TOKEN: {{ .Values.auth.pagerdutyToken }} -{{- end }} diff --git a/contrib/chart/backstage/templates/backstage-app-config.yaml b/contrib/chart/backstage/templates/backstage-app-config.yaml deleted file mode 100644 index 061fc3285b..0000000000 --- a/contrib/chart/backstage/templates/backstage-app-config.yaml +++ /dev/null @@ -1,27 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "backstage.fullname" . }}-app-config -data: -{{ include "backstage.appConfigFilename" . | indent 2 }}: | -{{ tpl (.Files.Get "files/app-config.development.yaml.tpl") . | indent 4 }} ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "backstage.fullname" . }}-app-env -data: - APP_CONFIG_app_baseUrl: {{ .Values.appConfig.app.baseUrl | quote | quote }} - APP_CONFIG_app_title: {{ .Values.appConfig.app.title | quote | quote }} - APP_CONFIG_backend_baseUrl: {{ .Values.appConfig.backend.baseUrl | quote | quote }} - APP_CONFIG_backend_cors_origin: {{ .Values.appConfig.backend.cors.origin | quote | quote }} - APP_CONFIG_techdocs_storageUrl: {{ .Values.appConfig.techdocs.storageUrl | quote | quote }} - APP_CONFIG_techdocs_requestUrl: {{ .Values.appConfig.techdocs.requestUrl | quote | quote }} - APP_CONFIG_lighthouse_baseUrl: {{ .Values.appConfig.lighthouse.baseUrl | quote | quote }} - APP_CONFIG_backend_database_connection_ssl_rejectUnauthorized: "false" - APP_CONFIG_auth_providers_github_development_appOrigin: {{ .Values.appConfig.auth.providers.github.development.appOrigin | quote | quote }} - APP_CONFIG_auth_providers_google_development_appOrigin: {{ .Values.appConfig.auth.providers.google.development.appOrigin | quote | quote }} - APP_CONFIG_auth_providers_gitlab_development_appOrigin: {{ .Values.appConfig.auth.providers.gitlab.development.appOrigin | quote | quote }} - APP_CONFIG_auth_providers_okta_development_appOrigin: {{ .Values.appConfig.auth.providers.okta.development.appOrigin | quote | quote }} - APP_CONFIG_auth_providers_oauth2_development_appOrigin: {{ .Values.appConfig.auth.providers.oauth2.development.appOrigin | quote | quote }} - diff --git a/contrib/chart/backstage/templates/backstage-auth-config.yaml b/contrib/chart/backstage/templates/backstage-auth-config.yaml deleted file mode 100644 index 7dcf8379aa..0000000000 --- a/contrib/chart/backstage/templates/backstage-auth-config.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "backstage.fullname" . }}-auth -data: - AUTH_GOOGLE_CLIENT_ID: {{ .Values.auth.google.clientId }} - AUTH_GITHUB_CLIENT_ID: {{ .Values.auth.github.clientId }} - AUTH_GITLAB_CLIENT_ID: {{ .Values.auth.gitlab.clientId }} - # This should not be prefixed with AUTH_. This could be a typo in the Backstage app config. - # Regardless, it is not decided by me. - GITLAB_BASE_URL: {{ .Values.auth.gitlab.baseUrl }} - AUTH_OKTA_CLIENT_ID: {{ .Values.auth.okta.clientId }} - AUTH_OKTA_AUDIENCE: {{ .Values.auth.okta.audience }} - AUTH_OAUTH2_CLIENT_ID: {{ .Values.auth.oauth2.clientId }} - AUTH_OAUTH2_AUTH_URL: {{ .Values.auth.oauth2.authUrl }} - AUTH_OAUTH2_TOKEN_URL: {{ .Values.auth.oauth2.tokenUrl }} - AUTH_AUTH0_CLIENT_ID: {{ .Values.auth.auth0.clientId }} - AUTH_AUTH0_DOMAIN: {{ .Values.auth.auth0.domain }} - AUTH_MICROSOFT_CLIENT_ID: {{ .Values.auth.microsoft.clientId }} - AUTH_MICROSOFT_TENANT_ID: {{ .Values.auth.microsoft.tenantId }} - diff --git a/contrib/chart/backstage/templates/frontend-deployment.yaml b/contrib/chart/backstage/templates/frontend-deployment.yaml deleted file mode 100644 index dba4e2c96a..0000000000 --- a/contrib/chart/backstage/templates/frontend-deployment.yaml +++ /dev/null @@ -1,66 +0,0 @@ -{{- if .Values.frontend.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "backstage.fullname" . }}-frontend - -spec: - replicas: {{ .Values.frontend.replicaCount }} - - selector: - matchLabels: - app: backstage - component: frontend - - template: - metadata: - annotations: - ad.datadoghq.com/backstage.logs: '[{"source":"backstage","service":"frontend"}]' - labels: - app: backstage - component: frontend - - spec: - {{- if .Values.dockerRegistrySecretName }} - imagePullSecrets: - - name: {{ .Values.dockerRegistrySecretName }} - {{- end}} - containers: - - name: {{ .Chart.Name }}-frontend - image: {{ .Values.frontend.image.repository }}:{{ .Values.frontend.image.tag }} - imagePullPolicy: {{ .Values.frontend.image.pullPolicy }} - ports: - - containerPort: {{ .Values.frontend.containerPort }} - resources: - {{- toYaml .Values.frontend.resources | nindent 12 }} - envFrom: - - configMapRef: - name: {{ include "backstage.fullname" . }}-app-env - volumeMounts: - - name: app-config - mountPath: {{ printf "/usr/share/nginx/html/static/%s" (include "backstage.appConfigFilename" .) }} - subPath: {{ include "backstage.appConfigFilename" . }} - volumes: - - name: app-config - configMap: - name: {{ include "backstage.fullname" . }}-app-config - {{- if .Values.global.nodeSelector }} - nodeSelector: {{- toYaml .Values.global.nodeSelector | nindent 8 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ include "frontend.serviceName" . }} - -spec: - ports: - - port: 80 - targetPort: {{ .Values.frontend.containerPort }} - - selector: - app: backstage - component: frontend - - type: {{ .Values.frontend.serviceType }} -{{- end }} diff --git a/contrib/chart/backstage/templates/ingress.yaml b/contrib/chart/backstage/templates/ingress.yaml deleted file mode 100644 index 7e008c5d9d..0000000000 --- a/contrib/chart/backstage/templates/ingress.yaml +++ /dev/null @@ -1,150 +0,0 @@ -{{- $frontendUrl := urlParse .Values.appConfig.app.baseUrl}} -{{- $backendUrl := urlParse .Values.appConfig.backend.baseUrl}} -{{- $lighthouseUrl := urlParse .Values.appConfig.lighthouse.baseUrl}} - -{{/* Determine the api type for the ingress */}} -{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }} -apiVersion: networking.k8s.io/v1 -{{- else -}} -apiVersion: networking.k8s.io/v1beta1 -{{- end }} -kind: Ingress -metadata: - name: {{ include "backstage.fullname" . }}-ingress - annotations: - {{- if .Values.issuer.email }} - cert-manager.io/cluster-issuer: {{ .Values.issuer.clusterIssuer }} - {{- end }} - nginx.ingress.kubernetes.io/ssl-redirect: "false" - nginx.ingress.kubernetes.io/configuration-snippet: | - if ($scheme = https) { - add_header Strict-Transport-Security "max-age=0;"; - } - {{- toYaml .Values.ingress.annotations | nindent 4 }} -spec: - tls: - - secretName: {{ include "backstage.fullname" . }}-tls - hosts: - - {{ $frontendUrl.host }} - - {{ $backendUrl.host }} - - {{ $lighthouseUrl.host }} - rules: - - host: {{ $frontendUrl.host }} - http: - paths: - - path: / - {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }} - pathType: Prefix - {{- end }} - backend: - {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }} - service: - name: {{ include "frontend.serviceName" . }} - port: - number: 80 - {{- else -}} - serviceName: {{ include "frontend.serviceName" . }} - servicePort: 80 - {{- end }} - {{/* Route the backend inside the same hostname as the frontend when they are the same */}} - {{- if eq $frontendUrl.host $backendUrl.host}} - - path: /api/ - {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }} - pathType: Prefix - {{- end }} - backend: - {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }} - service: - name: {{ include "backend.serviceName" . }} - port: - number: 80 - {{- else -}} - serviceName: {{ include "backend.serviceName" . }} - servicePort: 80 - {{- end }} - {{/* Route the backend through a different host */}} - {{- else -}} - - host: {{ $backendUrl.host }} - http: - paths: - - path: {{ $backendUrl.path | default "/" }} - {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }} - pathType: Prefix - {{- end }} - backend: - {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }} - service: - name: {{ include "backend.serviceName" . }} - port: - number: 80 - {{- else -}} - serviceName: {{ include "backend.serviceName" . }} - servicePort: 80 - {{- end }} - {{- end }} - -{{/* Route lighthouse through a different host */}} -{{- if not ( eq $frontendUrl.host $lighthouseUrl.host ) }} - - host: {{ $lighthouseUrl.host }} - http: - paths: - - path: {{ $lighthouseUrl.path | default "/" }} - {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }} - pathType: Prefix - {{- end }} - backend: - {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }} - service: - name: {{ include "lighthouse.serviceName" . }} - port: - number: 80 - {{- else -}} - serviceName: {{ include "lighthouse.serviceName" . }} - servicePort: 80 - {{- end }} -{{- else }} -{{/* Route lighthouse by path with re-write rules when it is hosted under the same hostname */}} ---- -{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }} -apiVersion: networking.k8s.io/v1 -{{- else -}} -apiVersion: networking.k8s.io/v1beta1 -{{- end }} -kind: Ingress -metadata: - name: {{ include "backstage.fullname" . }}-ingress-lighthouse - annotations: - {{- if .Values.issuer.email }} - cert-manager.io/cluster-issuer: {{ .Values.issuer.clusterIssuer }} - {{- end }} - nginx.ingress.kubernetes.io/rewrite-target: /$2 - nginx.ingress.kubernetes.io/ssl-redirect: "false" - nginx.ingress.kubernetes.io/configuration-snippet: | - if ($scheme = https) { - add_header Strict-Transport-Security "max-age=0;"; - } - {{- toYaml .Values.ingress.annotations | nindent 4 }} -spec: - tls: - - secretName: {{ include "backstage.fullname" . }}-tls - hosts: - - {{ $lighthouseUrl.host }} - rules: - - host: {{ $frontendUrl.host }} - http: - paths: - - path: {{$lighthouseUrl.path}}(/|$)(.*) - {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }} - pathType: Prefix - {{- end }} - backend: - {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }} - service: - name: {{ include "lighthouse.serviceName" . }} - port: - number: 80 - {{- else -}} - serviceName: {{ include "lighthouse.serviceName" . }} - servicePort: 80 - {{- end }} -{{- end }} diff --git a/contrib/chart/backstage/templates/issuer.yaml b/contrib/chart/backstage/templates/issuer.yaml deleted file mode 100644 index d129c8c701..0000000000 --- a/contrib/chart/backstage/templates/issuer.yaml +++ /dev/null @@ -1,19 +0,0 @@ -{{- if (and (.Capabilities.APIVersions.Has "cert-manager.io/v1alpha2") .Values.issuer.email ) -}} -{{/* Only install issuer if it doesn't already exist in the cluster */}} -{{- if not ( lookup "cert-manager.io/v1alpha2" "ClusterIssuer" "" .Values.issuer.clusterIssuer ) }} -apiVersion: cert-manager.io/v1alpha2 -kind: ClusterIssuer -metadata: - name: {{ .Values.issuer.clusterIssuer }} -spec: - acme: - server: https://acme-v02.api.letsencrypt.org/directory - email: {{ required "expected a valid .Values.issuer.email to enable ClusterIssuer" .Values.issuer.email }} - privateKeySecretRef: - name: {{ required "expected .Values.issuer.cluster-issuer to not be empty (letsencrypt-prod | letsencrypt-staging)" .Values.issuer.clusterIssuer }} - solvers: - - http01: - ingress: - class: nginx -{{- end -}} -{{- end -}} diff --git a/contrib/chart/backstage/templates/lighthouse-config.yaml b/contrib/chart/backstage/templates/lighthouse-config.yaml deleted file mode 100644 index 7b8cad42dc..0000000000 --- a/contrib/chart/backstage/templates/lighthouse-config.yaml +++ /dev/null @@ -1,12 +0,0 @@ -{{- if .Values.lighthouse.enabled }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "backstage.fullname" . -}}-lighthouse -data: - PGDATABASE: {{ .Values.lighthouse.database.connection.database | quote }} - PGUSER: {{ include "lighthouse.postgresql.user" . | quote }} - PGPORT: {{ include "lighthouse.postgresql.port" . | quote }} - PGHOST: {{ include "lighthouse.postgresql.host" . | quote }} - PGPATH_TO_CA: {{ include "backstage.lighthouse.postgresCaFilename" . | quote }} -{{- end }} \ No newline at end of file diff --git a/contrib/chart/backstage/templates/lighthouse-deployment.yaml b/contrib/chart/backstage/templates/lighthouse-deployment.yaml deleted file mode 100644 index 849c48d7a6..0000000000 --- a/contrib/chart/backstage/templates/lighthouse-deployment.yaml +++ /dev/null @@ -1,86 +0,0 @@ -{{- if .Values.lighthouse.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "backstage.fullname" . }}-lighthouse - -spec: - replicas: {{ .Values.lighthouse.replicaCount }} - - selector: - matchLabels: - app: backstage - component: lighthouse-audit-service - - template: - metadata: - annotations: - ad.datadoghq.com/backstage.logs: '[{"source":"backstage","service":"lighthouse"}]' - labels: - app: backstage - component: lighthouse-audit-service - - spec: - {{- if .Values.dockerRegistrySecretName }} - imagePullSecrets: - - name: {{ .Values.dockerRegistrySecretName }} - {{- end}} - containers: - - name: lighthouse-audit-service - image: {{ .Values.lighthouse.image.repository }}:{{ .Values.lighthouse.image.tag }} - imagePullPolicy: {{ .Values.lighthouse.image.pullPolicy }} - ports: - - containerPort: {{ .Values.lighthouse.containerPort }} - resources: - {{- toYaml .Values.lighthouse.resources | nindent 12 }} - - envFrom: - - configMapRef: - name: {{ include "backstage.fullname" . -}}-lighthouse - - configMapRef: - name: {{ include "backstage.fullname" . }}-app-env - - env: - - name: LAS_PORT - value: {{ .Values.lighthouse.containerPort | quote }} - - name: LAS_CORS - value: "true" - - name: PGPASSWORD - valueFrom: - secretKeyRef: - name: {{ include "lighthouse.postgresql.passwordSecret" . }} - key: postgresql-password - - {{- if .Values.lighthouse.postgresCertMountEnabled }} - volumeMounts: - - name: postgres-ca - mountPath: {{ include "backstage.lighthouse.postgresCaDir" . }} - {{- end }} - - {{- if .Values.lighthouse.postgresCertMountEnabled }} - volumes: - - name: postgres-ca - configMap: - name: {{ include "backstage.fullname" . }}-postgres-ca - {{- end }} - - {{- if .Values.global.nodeSelector }} - nodeSelector: {{- toYaml .Values.global.nodeSelector | nindent 8 }} - {{- end }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ include "lighthouse.serviceName" . }} - -spec: - ports: - - port: 80 - targetPort: {{ .Values.lighthouse.containerPort }} - - selector: - app: backstage - component: lighthouse-audit-service - - type: {{ .Values.lighthouse.serviceType }} -{{- end }} diff --git a/contrib/chart/backstage/templates/postgresql-ca-config.yaml b/contrib/chart/backstage/templates/postgresql-ca-config.yaml deleted file mode 100644 index 2631989f4e..0000000000 --- a/contrib/chart/backstage/templates/postgresql-ca-config.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if .Values.postgresql.enabled }} ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "backstage.fullname" . }}-postgres-ca - labels: - app: {{ include "backstage.postgresql.fullname" . }} - release: {{ .Release.Name }} - annotations: - "helm.sh/hook": "pre-install" - "helm.sh/hook-delete-policy": "before-hook-creation" -data: - {{ .Values.global.postgresql.caFilename }}: | -{{ include "backstage.postgresql.generateCA" . | indent 4}} -{{- else }} -{{- $caConfig := printf "%s-postgres-ca" (include "backstage.fullname" .) }} -{{- if not ( lookup "v1" "ConfigMap" .Release.Namespace $caConfig ) }} -{{- fail (printf "\n\nPlease create the '%s' configmap with the CA certificate for your existing postgresql: kubectl create configmap %s --from-file=ca.crt" $caConfig $caConfig) }} -{{- end }} -{{- end }} \ No newline at end of file diff --git a/contrib/chart/backstage/templates/postgresql-certs-secret.yaml b/contrib/chart/backstage/templates/postgresql-certs-secret.yaml deleted file mode 100644 index c6845caa7e..0000000000 --- a/contrib/chart/backstage/templates/postgresql-certs-secret.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if .Values.postgresql.enabled }} ---- -apiVersion: v1 -kind: Secret -type: kubernetes.io/tls -metadata: - name: {{ required ".Values.postgresql.tls.certificatesSecret is required" .Values.postgresql.tls.certificatesSecret }} - labels: - app: {{ include "backstage.postgresql.fullname" . }} - release: {{ .Release.Name }} - annotations: - "helm.sh/hook": "pre-install" - "helm.sh/hook-delete-policy": "before-hook-creation" -data: -{{ include "generateCerts" . | indent 2 }} -{{- end }} diff --git a/contrib/chart/backstage/templates/postgresql-initdb-secret.yaml b/contrib/chart/backstage/templates/postgresql-initdb-secret.yaml deleted file mode 100644 index d1c446f79f..0000000000 --- a/contrib/chart/backstage/templates/postgresql-initdb-secret.yaml +++ /dev/null @@ -1,14 +0,0 @@ -{{- if .Values.postgresql.enabled }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ required ".Values.postgresql.initdbScriptsSecret is required" .Values.postgresql.initdbScriptsSecret }} - annotations: - "helm.sh/hook": "pre-install" - "helm.sh/hook-delete-policy": "before-hook-creation" -type: Opaque -data: - create-backend-dbs.sql: | - {{ tpl (.Files.Get "files/create-backend-dbs.sql") . | b64enc }} -{{- end }} - diff --git a/contrib/chart/backstage/templates/postgresql-password-backend-secret.yaml b/contrib/chart/backstage/templates/postgresql-password-backend-secret.yaml deleted file mode 100644 index a71cef7b21..0000000000 --- a/contrib/chart/backstage/templates/postgresql-password-backend-secret.yaml +++ /dev/null @@ -1,15 +0,0 @@ -{{- if not .Values.postgresql.enabled }} ---- -apiVersion: v1 -kind: Secret -type: Opaque -metadata: - name: {{ include "backend.postgresql.passwordSecret" . }} - labels: - release: {{ .Release.Name }} - annotations: - "helm.sh/hook": "pre-install,pre-upgrade" - "helm.sh/hook-delete-policy": "before-hook-creation" -data: - postgresql-password: {{ .Values.appConfig.backend.database.connection.password | b64enc }} -{{- end }} diff --git a/contrib/chart/backstage/templates/postgresql-password-lighthouse-secret.yaml b/contrib/chart/backstage/templates/postgresql-password-lighthouse-secret.yaml deleted file mode 100644 index e7374e70db..0000000000 --- a/contrib/chart/backstage/templates/postgresql-password-lighthouse-secret.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if .Values.lighthouse.enabled }} -{{- if not .Values.postgresql.enabled }} ---- -apiVersion: v1 -kind: Secret -type: Opaque -metadata: - name: {{ include "lighthouse.postgresql.passwordSecret" . }} - labels: - release: {{ .Release.Name }} - annotations: - "helm.sh/hook": "pre-install,pre-upgrade" - "helm.sh/hook-delete-policy": "before-hook-creation" -data: - postgresql-password: {{ .Values.lighthouse.database.connection.password | b64enc }} -{{- end }} -{{- end }} diff --git a/contrib/chart/backstage/templates/tests/test-app-connection.yaml b/contrib/chart/backstage/templates/tests/test-app-connection.yaml deleted file mode 100644 index 93f51f3f09..0000000000 --- a/contrib/chart/backstage/templates/tests/test-app-connection.yaml +++ /dev/null @@ -1,23 +0,0 @@ ---- -apiVersion: v1 -kind: Pod -metadata: - name: {{ include "backstage.fullname" . -}}-test-app-connection - annotations: - "helm.sh/hook": test -spec: - containers: - - name: test-app - image: busybox - command: - - /bin/sh - - -ecx - - | - echo -e "===== Testing the connection with the frontend...\n" - wget -q -O - {{ printf "%s.%s" (include "frontend.serviceName" .) .Release.Namespace | quote }} - echo -e "\n\n===== Testing the connection with the backend...\n" - wget -q -O - {{ printf "http://%s.%s/catalog/entities" (include "backend.serviceName" .) .Release.Namespace | quote }} - echo -e "\n\n===== Testing the connection with the lighthouse plugin...\n" - wget -q -O - {{ printf "%s.%s/v1/audits" (include "lighthouse.serviceName" .) .Release.Namespace | quote }} - echo -e "\n" - restartPolicy: Never \ No newline at end of file diff --git a/contrib/chart/backstage/templates/tests/test-postgresql.yaml b/contrib/chart/backstage/templates/tests/test-postgresql.yaml deleted file mode 100644 index 8eec1db452..0000000000 --- a/contrib/chart/backstage/templates/tests/test-postgresql.yaml +++ /dev/null @@ -1,33 +0,0 @@ -{{- if .Values.postgresql.enabled}} ---- -apiVersion: v1 -kind: Pod -metadata: - name: {{ include "backstage.name" . -}}-test-postgres - annotations: - "helm.sh/hook": test -spec: - containers: - - name: postgresql-client - image: bitnami/postgresql - env: - - name: PG_HOST - value: {{ include "postgresql.serviceName" . | quote }} - - name: PG_PORT - value: {{ .Values.postgresql.service.port | quote }} - - name: PG_USER - value: {{ .Values.global.postgresql.postgresqlUsername | quote }} - - name: PGPASSWORD - valueFrom: - secretKeyRef: - name: {{ include "backend.postgresql.passwordSecret" .}} - key: postgresql-password - - name: PG_DBNAME - value: {{ .Values.appConfig.backend.database.connection.database }} - command: - - /bin/bash - - -ecx - - | - psql --host=$PG_HOST --port=$PG_PORT --username=$PG_USER --dbname=$PG_DBNAME --no-password - restartPolicy: Never -{{- end }} \ No newline at end of file diff --git a/contrib/chart/backstage/values.yaml b/contrib/chart/backstage/values.yaml deleted file mode 100644 index cd80fd954b..0000000000 --- a/contrib/chart/backstage/values.yaml +++ /dev/null @@ -1,216 +0,0 @@ -# Default values for backstage. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -frontend: - enabled: false - replicaCount: 1 - image: - repository: martinaif/backstage-k8s-demo-frontend - tag: test1 - pullPolicy: IfNotPresent - containerPort: 80 - serviceType: ClusterIP - resources: - requests: - memory: 128Mi - limits: - memory: 256Mi - -backend: - enabled: true - nodeEnv: development - demoData: true - replicaCount: 1 - image: - repository: martinaif/backstage-k8s-demo-backend - tag: 20210423T1550 - pullPolicy: IfNotPresent - containerPort: 7007 - serviceType: ClusterIP - postgresCertMountEnabled: true - resources: - requests: - memory: 512Mi - limits: - memory: 1024Mi - -lighthouse: - enabled: true - replicaCount: 1 - image: - repository: roadiehq/lighthouse-audit-service - tag: latest - pullPolicy: IfNotPresent - containerPort: 3003 - serviceType: ClusterIP - postgresCertMountEnabled: true - resources: - requests: - memory: 128Mi - limits: - memory: 256Mi - database: - connection: - port: - host: - user: - password: - database: lighthouse_audit_service - pathToDatabaseCa: - -nameOverride: '' -fullnameOverride: '' - -ingress: - annotations: - kubernetes.io/ingress.class: nginx - -issuer: - email: - clusterIssuer: 'letsencrypt-staging' - -global: - postgresql: - postgresqlUsername: backend-user - caFilename: ca.crt - nodeSelector: {} - -postgresql: - enabled: true - nameOverride: postgresql - tls: - enabled: true - certificatesSecret: backstage-postgresql-certs - certFilename: tls.crt - certKeyFilename: tls.key - volumePermissions: - enabled: true - initdbScriptsSecret: backstage-postgresql-initdb - -appConfig: - app: - baseUrl: https://demo.example.com - title: Backstage - backend: - baseUrl: https://demo.example.com - listen: - port: 7007 - cors: - origin: https://demo.example.com - database: - client: pg - connection: - database: backstage_plugin_catalog - host: - user: - port: - password: - ssl: - rejectUnauthorized: false - ca: - sentry: - organization: example-org-name - techdocs: - storageUrl: https://demo.example.com/api/techdocs/static/docs - requestUrl: https://demo.example.com/api/techdocs - lighthouse: - baseUrl: https://demo.example.com/lighthouse-api - rollbar: - organization: example-org-name - - # Auth config has recently moved into the app config file in upstream Backstage. However, - # most of this config simply mandates that items like the client id and client secret should - # be picked up from the environment variables named below. Those environment variables are - # set in this helm controlled environment by the 'auth' configuration below this section. - # Thus, the only key in this config which directly controls an app config is the - # auth.providers.github.development.appOrigin property. - auth: - providers: - google: - development: - appOrigin: 'http://localhost:3000/' - secure: false - clientId: ${AUTH_GOOGLE_CLIENT_ID} - clientSecret: ${AUTH_GOOGLE_CLIENT_SECRET} - github: - development: - appOrigin: 'http://localhost:3000/' - secure: false - clientId: ${AUTH_GITHUB_CLIENT_ID} - clientSecret: ${AUTH_GITHUB_CLIENT_SECRET} - enterpriseInstanceUrl: ${AUTH_GITHUB_ENTERPRISE_INSTANCE_URL} - gitlab: - development: - appOrigin: 'http://localhost:3000/' - secure: false - clientId: ${AUTH_GITLAB_CLIENT_ID} - clientSecret: ${AUTH_GITLAB_CLIENT_SECRET} - audience: ${GITLAB_BASE_URL} - okta: - development: - appOrigin: 'http://localhost:3000/' - secure: false - clientId: ${AUTH_OKTA_CLIENT_ID} - clientSecret: ${AUTH_OKTA_CLIENT_SECRET} - audience: ${AUTH_OKTA_AUDIENCE} - oauth2: - development: - appOrigin: 'http://localhost:3000/' - secure: false - clientId: ${AUTH_OAUTH2_CLIENT_ID} - clientSecret: ${AUTH_OAUTH2_CLIENT_SECRET} - authorizationURL: ${AUTH_OAUTH2_AUTH_URL} - tokenURL: ${AUTH_OAUTH2_TOKEN_URL} - auth0: - development: - clientId: ${AUTH_AUTH0_CLIENT_ID} - clientSecret: ${AUTH_AUTH0_CLIENT_SECRET} - domain: ${AUTH_AUTH0_DOMAIN} - microsoft: - development: - clientId: ${AUTH_MICROSOFT_CLIENT_ID} - clientSecret: ${AUTH_MICROSOFT_CLIENT_SECRET} - tenantId: ${AUTH_MICROSOFT_TENANT_ID} - -auth: - google: - clientId: a - clientSecret: a - github: - clientId: c - clientSecret: c - gitlab: - clientId: b - clientSecret: b - baseUrl: b - okta: - clientId: b - clientSecret: b - audience: b - oauth2: - clientId: b - clientSecret: b - authUrl: b - tokenUrl: b - auth0: - clientId: b - clientSecret: b - domain: b - microsoft: - clientId: f - clientSecret: f - tenantId: f - azure: - api: - token: h - sentryToken: e - rollbarAccountToken: f - # This is a 'Personal Access Token' - circleciAuthToken: r - # Used by the scaffolder to create GitHub repos. Must have 'repo' scope. - githubToken: g - gitlabToken: g - newRelicRestApiKey: r - travisciAuthToken: fake-travis-ci-auth-token - pagerdutyToken: h From 85313970b7f490c4b12bfc236edb116e99fb9a2a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 14:04:51 +0000 Subject: [PATCH 149/283] chore(deps): update snyk/actions digest to 1d672a4 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/sync_snyk-github-issues.yml | 2 +- .github/workflows/sync_snyk-monitor.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sync_snyk-github-issues.yml b/.github/workflows/sync_snyk-github-issues.yml index f1a91ed7e6..ec7c00111d 100644 --- a/.github/workflows/sync_snyk-github-issues.yml +++ b/.github/workflows/sync_snyk-github-issues.yml @@ -29,7 +29,7 @@ jobs: cache-prefix: ${{ runner.os }}-v18.x - name: Create Snyk report - uses: snyk/actions/node@3e2680e8df93a24b52d119b1305fb7cedc60ceae # master + uses: snyk/actions/node@1d672a455ab3339ef0a0021e1ec809165ee12fad # master continue-on-error: true # Snyk CLI exits with error when vulnerabilities are found with: args: > diff --git a/.github/workflows/sync_snyk-monitor.yml b/.github/workflows/sync_snyk-monitor.yml index c3f7af1550..04367c2639 100644 --- a/.github/workflows/sync_snyk-monitor.yml +++ b/.github/workflows/sync_snyk-monitor.yml @@ -31,7 +31,7 @@ jobs: - uses: actions/checkout@v4.1.1 - name: Monitor and Synchronize Snyk Policies - uses: snyk/actions/node@3e2680e8df93a24b52d119b1305fb7cedc60ceae # master + uses: snyk/actions/node@1d672a455ab3339ef0a0021e1ec809165ee12fad # master with: command: monitor args: > @@ -46,7 +46,7 @@ jobs: # Above we run the `monitor` command, this runs the `test` command which is # the one that generates the SARIF report that we can upload to GitHub. - name: Create Snyk report - uses: snyk/actions/node@3e2680e8df93a24b52d119b1305fb7cedc60ceae # master + uses: snyk/actions/node@1d672a455ab3339ef0a0021e1ec809165ee12fad # master continue-on-error: true # To make sure that SARIF upload gets called with: args: > From 3bca2252d8a610a9ceaa01997727740689e503e1 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 17 Jan 2024 15:13:57 +0100 Subject: [PATCH 150/283] refactor(docs-frontend): do not show line numbers Signed-off-by: Camila Belo --- .../frontend-system/architecture/07-routes.md | 79 +++++++++++++------ 1 file changed, 53 insertions(+), 26 deletions(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 918fddb43c..1cf5ed8c68 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -26,7 +26,7 @@ There are 3 types of route references: regular route, sub route, and external ro Route references, also known as "absolute" or "regular" routes, are created as follows: -```tsx title="plugins/catalog/src/routes.ts" showLineNumbers +```tsx title="plugins/catalog/src/routes.ts" import { createRouteRef } from '@backstage/frontend-plugin-api'; // Creates a route reference, which is not yet associated with any plugin page @@ -41,7 +41,7 @@ Route refs do not have any behavior themselves. They are an opaque value that re The code snippet in the previous section does not indicate which plugin the route belongs to. To do so, you have to use it in the creation of any kind of routable extension, such as a page extension: -```tsx title="plugins/catalog/src/plugin.tsx" {11,17-19} showLineNumbers +```tsx title="plugins/catalog/src/plugin.tsx" import React from 'react'; import { createPlugin, @@ -52,25 +52,23 @@ import { indexRouteRef } from './routes'; const catalogIndexPage = createPageExtension({ // The `name` option is omitted because this is an index page defaultPath: '/entities', + // highlight-next-line routeRef: indexRouteRef, loader: () => import('./components').then(m => ), }); export default createPlugin({ id: 'catalog', + // highlight-start routes: { index: indexRouteRef, }, + // highlight-end extensions: [catalogIndexPage], }); ``` -In the example above we have associated a route ref with an plugin page. This is what the code does: - -- Line 11: Associates the `indexRouteRef` with the `catalogIndexPage` extension; -- Line 17 to 19: Provides both the `indexRouteRef` and `catalogIndexPage` via the Catalog plugin. - -When this extension is installed in the app it will become associated with the newly created `RouteRef`, making it possible to use the route ref to navigate the extension. +In the example above we associated the `indexRouteRef` with the `catalogIndexPage` extension and provided both the route ref and page via the Catalog plugin. So, When this plugin is installed in the app, the index page will become associated with the newly created `RouteRef`, making it possible to use the route ref to navigate the page extension. It may be unclear why we configure the routes option when creating a plugin as the route has already been passed to the extension. We do that to make it possible for other plugins to route to our page, which is explained in detail in the [binding routes](#binding-external-route-references) section. @@ -78,11 +76,12 @@ It may be unclear why we configure the routes option when creating a plugin as t Route references optionally accept a `params` option, which will require the listed parameter names to be present in the route path. Here is how you create a reference for a route that requires a `kind`, `namespace` and `name` parameters, like in this path `/entities/:kind/:namespace/:name`: -```tsx title="plugins/catalog/src/routes.ts" {5} showLineNumbers +```tsx title="plugins/catalog/src/routes.ts" import { createRouteRef } from '@backstage/frontend-plugin-api'; export const detailsRouteRef = createRouteRef({ // The parameters that must be included in the path of this route reference + // highlight-next-line params: ['kind', 'namespace', 'name'], }); ``` @@ -93,22 +92,25 @@ Route references can be used to link to page in the same plugin, or to pages in Suppose we are creating a plugin that renders a Catalog index page with a link to a "Foo" component details page. Here is the code for the index page: -```tsx title="plugins/catalog/src/components/IndexPage.tsx" {6,11-15} showLineNumbers +```tsx title="plugins/catalog/src/components/IndexPage.tsx" import React from 'react'; import { useRouteRef } from '@backstage/frontend-plugin-api'; import { detailsRouteRef } from '../routes'; export const IndexPage = () => { + // highlight-next-line const getDetailsPath = useRouteRef(detailsRouteRef); return (

Index Page

See "Foo" details @@ -121,27 +123,30 @@ We use the `useRouteRef` hook to create a link generator function that returns t Let's see how the details page can get the parameters from the URL: -```tsx title="plugins/catalog/src/components/DetailsPage.tsx" {6,11-13} showLineNumbers +```tsx title="plugins/catalog/src/components/DetailsPage.tsx" import React from 'react'; import { useRouteRefParams } from '@backstage/frontend-plugin-api'; import { detailsRouteRef } from '../routes'; export const DetailsPage = () => { + // highlight-next-line const params = useRouteRefParams(detailsRouteRef); return (

Details Page

    + {/* highlight-start */}
  • Kind: {params.kind}
  • Namespace: {params.namespace}
  • Name: {params.name}
  • + {/* highlight-end */}
); }; ``` -On line 6, we are using the `useRouteRefParams` hook to retrieve the entity-composed id from the URL. The parameter object contains three values: kind, namespace, and name. We can display these values or call an API using them. +In the code above, we are using the `useRouteRefParams` hook to retrieve the entity-composed id from the URL. The parameter object contains three values: kind, namespace, and name. We can display these values or call an API using them. Since we are linking to pages of the same package, we are using a route ref directly. However, in the following sections, you will see how to link to pages of different plugins. @@ -154,7 +159,7 @@ We don't want to reference the Scaffolder plugin directly, since that would crea We create a new `RouteRef` inside the Scaffolder plugin, using a neutral name that describes its role in the plugin rather than a specific plugin page that it might be linking to, allowing the app to decide the final target. If the Catalog entity list page for example wants to link the Scaffolder create component page in the header, it might declare an `ExternalRouteRef` similar to this: -```tsx title="plugins/catalog/src/routes.ts" showLineNumbers +```tsx title="plugins/catalog/src/routes.ts" import { createExternalRouteRef } from '@backstage/frontend-plugin-api'; export const createComponentExternalRouteRef = createExternalRouteRef(); @@ -162,16 +167,18 @@ export const createComponentExternalRouteRef = createExternalRouteRef(); External routes are also used in a similar way as regular routes: -```tsx title="plugins/catalog/src/components/IndexPage.tsx" {6,10} showLineNumbers +```tsx title="plugins/catalog/src/components/IndexPage.tsx" import React from 'react'; import { useRouteRef } from '@backstage/frontend-plugin-api'; import { createComponentExternalRouteRef } from '../routes'; export const IndexPage = () => { + // highlight-next-line const getCreateComponentPath = useRouteRef(createComponentExternalRouteRef); return (

Index Page

+ {/* highlight-next-line */} Create Component
); @@ -182,7 +189,7 @@ Given the above binding, using `useRouteRef(createComponentExternalRouteRef)` wi Now the only thing left is to provide the page and external route via a plugin: -```tsx title="plugins/catalog/src/plugin.tsx" {20-23} showLineNumbers +```tsx title="plugins/catalog/src/plugin.tsx" import React from 'react'; import { createPlugin, @@ -202,19 +209,22 @@ export default createPlugin({ routes: { index: indexRouteRef, }, + // highlight-start externalRoutes: { createComponent: createComponentExternalRouteRef, }, extensions: [catalogIndexPage], + // highlight-end }); ``` External routes can also have parameters. For example, if you want to link to an entity's details page from Scaffolder, you'll need to create an external route that receives the same parameters the Catalog details page expects: -```tsx title="plugins/scaffolder/src/routes.ts" {4} showLineNumbers +```tsx title="plugins/scaffolder/src/routes.ts" import { createExternalRouteRef } from '@backstage/frontend-plugin-api'; export const entityDetailsExternalRouteRef = createExternalRouteRef({ + // highlight-next-line params: ['kind', 'namespace', 'name'], }); ``` @@ -227,24 +237,27 @@ The association of external routes is controlled by the app. Each `ExternalRoute Using the above example of the Catalog entities list page to the Scaffolder create component page, we might do something like this in the app configuration file: -```yaml title="app-config.yaml" {5,7} showLineNumbers +```yaml title="app-config.yaml" app: routes: bindings: # point to the Scaffolder create component page when the Catalog create component ref is used + # highlight-next-line plugin.catalog.externalRoutes.createComponent: plugin.scaffolder.routes.index # point to the Catalog details page when the Scaffolder component details ref is used + # highlight-next-line plugin.scaffolder.externalRoutes.componentDetails: plugin.catalog.routes.details ``` We also have the ability to express this in code as an option to `createApp`, but you of course only need to use one of these two methods: -```tsx title="packages/app/src/App.tsx" {6-13} showLineNumbers +```tsx title="packages/app/src/App.tsx" import { createApp } from '@backstage/frontend-app-api'; import catalog from '@backstage/plugin-catalog'; import scaffolder from '@backstage/plugin-scaffolder'; const app = createApp({ + // highlight-start bindRoutes({ bind }) { bind(catalog.externalRoutes, { createComponent: scaffolder.routes.createComponent, @@ -253,6 +266,7 @@ const app = createApp({ componentDetails: catalog.routes.details, }); }, + // highlight-end }); export default app.createRoot(); @@ -266,17 +280,18 @@ Another thing to note is that this indirection in the routing is particularly us It is possible to define an `ExternalRouteRef` as optional, so it is not required to bind it in the app. -```tsx title="plugins/catalog/src/routes.ts" {4} showLineNumbers +```tsx title="plugins/catalog/src/routes.ts" import { createExternalRouteRef } from '@backstage/frontend-plugin-api'; export const createComponentExternalRouteRef = createExternalRouteRef({ + // highlight-next-line optional: true, }); ``` When calling `useRouteRef` with an optional external route, its return signature is changed to `RouteFunc | undefined`, and the returned value can be used to decide whether a certain link should be displayed or if an action should be taken: -```tsx title="plugins/catalog/src/components/IndexPage.tsx" {11} showLineNumbers +```tsx title="plugins/catalog/src/components/IndexPage.tsx" import React from 'react'; import { useRouteRef } from '@backstage/frontend-plugin-api'; import { createComponentExternalRouteRef } from '../routes'; @@ -287,9 +302,11 @@ export const IndexPage = () => {

Index Page

{/* Rendering the link only if the getCreateComponentPath is defined */} + {/* highlight-start */} {getCreateComponentPath && ( Create Component )} + {/* highlight-end */}
); }; @@ -301,32 +318,35 @@ The last kind of route refs that can be created are `SubRouteRef`s, which can be For example: -```tsx title ="plugins/catalog/src/routes.ts" {4,7} showLineNumbers +```tsx title ="plugins/catalog/src/routes.ts" import { createRouteRef, createSubRouteRef, } from '@backstage/frontend-plugin-api'; export const indexRouteRef = createRouteRef(); +// highlight-start export const detailsSubRouteRef = createSubRouteRef({ parent: indexRouteRef, path: '/details', }); +// highlight-end ``` There are substantial differences between creating subroutes and regular or external routes because subroutes are associated with regular routes, and the sub route path must be specified. The path string must include the parameters if this sub route has them: -```tsx title ="plugins/catalog/src/routes.ts" {4} showLineNumbers +```tsx title ="plugins/catalog/src/routes.ts" // Omitting rest of the previous example file export const detailsSubRouteRef = createSubRouteRef({ parent: indexRouteRef, + // highlight-next-line path: '/:name/:namespace/:kind', }); ``` Using subroutes in a page extension is as simple as this: -```tsx title="plugins/catalog/src/components/IndexPage.ts" showLineNumbers +```tsx title="plugins/catalog/src/components/IndexPage.ts" import React from 'react'; import { Routes, Route, useLocation } from 'react-router-dom'; import { useRouteRef } from '@backstage/frontend-plugin-api'; @@ -342,8 +362,9 @@ export const IndexPage = () => {

Index Page

{/* Linking to the details sub route */} {pathname === getIndexPath() ? ( - // Setting the details sub route params + // highlight-start { > Show details + // highlight-end ) : ( + // highlight-next-line Hide details )} {/* Registering the details sub route */} @@ -366,19 +389,22 @@ export const IndexPage = () => { This is how you can get the parameters of a sub route URL: -```tsx title="plugins/catalog/src/components/DetailsPage.ts" {5} showLineNumbers +```tsx title="plugins/catalog/src/components/DetailsPage.ts" import React from 'react'; import { useParams } from 'react-router-dom'; export const DetailsPage = () => { + // highlight-next-line const params = useParams(); return (

Details Sub Page

    + {/* highlight-start */}
  • Kind: {params.kind}
  • Namespace: {params.namespace}
  • Name: {params.name}
  • + {/* highlight-end */}
); @@ -387,7 +413,7 @@ export const DetailsPage = () => { Finally, see how a plugin can provide subroutes: -```tsx title="plugins/catalog/src/plugin.ts" {18} showLineNumbers +```tsx title="plugins/catalog/src/plugin.ts" import React from 'react'; import { createPlugin, @@ -405,6 +431,7 @@ export default createPlugin({ id: 'catalog', routes: { index: indexRouteRef, + // highlight-next-line details: detailsSubRouteRef, }, extensions: [catalogIndexPage], From f37ba7c0b5407d12954387c2528d80ec109c0107 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 14:14:24 +0000 Subject: [PATCH 151/283] fix(deps): update dependency isomorphic-git to v1.25.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index b9ab306f65..ccfd1ec70b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -30340,8 +30340,8 @@ __metadata: linkType: hard "isomorphic-git@npm:^1.23.0": - version: 1.25.2 - resolution: "isomorphic-git@npm:1.25.2" + version: 1.25.3 + resolution: "isomorphic-git@npm:1.25.3" dependencies: async-lock: ^1.1.0 clean-git-ref: ^2.0.1 @@ -30356,7 +30356,7 @@ __metadata: simple-get: ^4.0.1 bin: isogit: cli.cjs - checksum: b8e7a1b66c393ac1ab30fd0deb561b97e4ca249aad97367f11be8ed18b20132460bec89451752e3533e64a5a8c47b3509dc5a7dee2eea266c812b45df633b441 + checksum: 747da1bd0435898a02f8c1ba07ce66c704ea311338b66a44830a5ce1fe9a256a3ea1ec9be5baa087f88134aa686b5d0c6dc2b9338b1fd523f2869ef2480e4d4e languageName: node linkType: hard From a66ae33632d33343c3204ceb3afb31c5e089d4f6 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 17 Jan 2024 15:20:25 +0100 Subject: [PATCH 152/283] refactor(docs-frontend): update intro section Signed-off-by: Camila Belo --- docs/frontend-system/architecture/07-routes.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 1cf5ed8c68..60bf335158 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -12,12 +12,10 @@ description: Frontend routes Each Backstage plugin is an isolated piece of functionality that doesn't typically communicate directly with other plugins. In order to achieve this, there are many parts of the frontend system that provide a layer of indirection for cross-plugin communication, and they routing system is one of them. -The Backstage routing system makes it possible to implement navigation across plugin boundaries, without each individual plugin knowing the concrete path or location of other plugins in the routing hierarchy, or even its own. This is achieved through the concept of route references, which are opaque reference values that can be shared and used to create concrete links to different parts of an app. +The Backstage routing system makes it possible to implement navigation across plugin boundaries, without each individual plugin knowing the concrete path or location of other plugins in the routing hierarchy, or even its own. This is achieved through the concept of route references, which are opaque reference values that can be shared and used to create concrete links to different parts of an app. The route ref paths can be configured both at plugin level (by plugin developers) and at the app level (by integrators). It is up to plugin developers to create route references for any page content in their plugin that they want it to be possible to link to or from. ## Route References -A `RouteRef` is an abstract path in a Backstage app, and these paths can be configured both at plugin level (by plugin developers) and at the app level (by integrators). It is up to plugin developers to create route references for any page content in their plugin that they want it to be possible to link to or from. - Plugin developers create a `RouteRef` to expose a path in Backstage's routing system. You will see below how routes are defined programmatically, but before diving into code, let us explain how to configure them at app level. In spite of the fact that plugin developers choose a default route path for the routes their plugin provides, paths are configurable, so app integrators can set a custom path to a route whenever they like to (more information in the following sections). There are 3 types of route references: regular route, sub route, and external route, and we will cover both the concept and code definition for each. From bd0e1f062763e409f27b0c1e698fb2b568b58b64 Mon Sep 17 00:00:00 2001 From: Philipp Hugenroth Date: Wed, 17 Jan 2024 15:59:18 +0100 Subject: [PATCH 153/283] Update adr011-plugin-package-structure.md Signed-off-by: Philipp Hugenroth --- docs/architecture-decisions/adr011-plugin-package-structure.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/architecture-decisions/adr011-plugin-package-structure.md b/docs/architecture-decisions/adr011-plugin-package-structure.md index 2def903dfc..8e4b5435f9 100644 --- a/docs/architecture-decisions/adr011-plugin-package-structure.md +++ b/docs/architecture-decisions/adr011-plugin-package-structure.md @@ -7,8 +7,7 @@ description: Architecture Decision Record (ADR) for Plugin Package Structure ## Context -A core feature of Backstage is the extensibility via plugins. The Backstage -repository is open for contributions of plugins. Even most of the core features +A core feature of Backstage is the extensibility via plugins. Even most of the core features are implemented as plugins. A plugin consists of one or multiple packages in the `plugins/` directory. Up till now, we have a simple conventions for naming plugin packages: Plugins are named `x`, with the option of having a related From e7e542bd0519cb6ade61b7e37b7c41f72b924dc3 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Mon, 18 Dec 2023 15:40:25 +0100 Subject: [PATCH 154/283] docs: draft extension overrides arch Signed-off-by: Camila Belo --- .../architecture/05-extension-overrides.md | 105 +++++++++++++++--- 1 file changed, 87 insertions(+), 18 deletions(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index e722145552..20476c24b0 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -10,38 +10,107 @@ description: Frontend extension overrides ## Introduction - +- When you just want to configure a plugin, such as changing the attachment point, a path or any other setting. Be sure to read the extension documentation before overriding an extension to make sure you cannot configure it to work the way you want; +- It is already possible to enable an extension that is already provided by the plugin. Imagine we have a Search plugin that provides a default search result item extension for rendering search results. Consider also that we have a Catalog plugin with a disabled Catalog search result item extension. To change the way Catalog search result items are rendered, you don't need to override the default result item extension. The only thing you need to do is enable the Catalog search result extension via the config file. For other types of search results, the default Search result item will continue to be used. -## Creating a Extension Override +## Creating an Extension Override - +For this example, we are creating overrides for the light and dark theme extensions and exporting the overrides from the plugin index file. Now we are able to use the overrides in a Backstage app: + +```tsx +// packages/app/src/App.tsx +import { createApp } from '@backstage/frontend-app-api'; +import apertureOverrides from ‘@backstage/plugin-aperture-overrides’ + +const app = createApp({ + features: [ apertureOverrides ], +}); + +export default app.createRoot(). +``` + +If the plugin you want to change is internal to your company or you just want to replace one of the application's core extensions, you can decide to create replacements directly in the application for local replacements. See an example below: + +```tsx +// packages/app/src/themes.ts +import { createExtensionOverrides } from from '@backstage/frontend-plugin-api'; + +// Creating the light theme extension; +export const apertureLightTheme = createThemeApi({ … }); + +// Creating the light theme extension; +const apertureDarkTheme = createThemeApi({ … }); + +// Exporting your custom extensions +export default [apertureLightTheme, apertureDarkTheme]; + +// packages/app/src/App.tsx +import { createApp } from '@backstage/frontend-app-api'; +import themes from ‘./themes’ + +const app = createApp({ + features: [ + createExtensionOverrides({ + extensions: [ + ...themes, + ], + }), + ], +}); + +export default app.createRoot(); +``` + +Note that it can still be a good idea to split your overrides out into separate packages in large projects. But it's up to you to decide how to group the extensions into extension overrides. ## Overriding Existing Extensions - +We recommend that plugin developes share the extension ids in their plugin documentations, but usually you can infer the id by following the (Naming pattern)[./08-naming-patterns] standars. From f6909fee983aaf2961b63086e724a545b1bba734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 22 Dec 2023 14:34:08 +0100 Subject: [PATCH 155/283] Update docs/frontend-system/architecture/05-extension-overrides.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Patrik Oldsberg Signed-off-by: Fredrik Adelöw --- docs/frontend-system/architecture/05-extension-overrides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index 20476c24b0..2bceab52d9 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -42,7 +42,7 @@ const apertureDarkTheme = createThemeApi({ … }); // Creating an extension overrides preset export createExtensionOverrides({ - Extensions: [apertureLightTheme, apertureDarkTheme] + extensions: [apertureLightTheme, apertureDarkTheme] }); // plugins/aperture-overrides/src/index.ts From 27aa7dc95780976723e18b101db889fd19e32fad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 22 Dec 2023 14:34:15 +0100 Subject: [PATCH 156/283] Update docs/frontend-system/architecture/05-extension-overrides.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Patrik Oldsberg Signed-off-by: Fredrik Adelöw --- docs/frontend-system/architecture/05-extension-overrides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index 2bceab52d9..cfb590d217 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -37,7 +37,7 @@ import { // Creating a light theme extension; const apertureLightTheme = createThemeApi({ … }); -// Creating a light theme extension; +// Creating a dark theme extension; const apertureDarkTheme = createThemeApi({ … }); // Creating an extension overrides preset From 2827fc2ba91fda463b90fcfac65c3e8022166ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 22 Dec 2023 14:34:39 +0100 Subject: [PATCH 157/283] Update docs/frontend-system/architecture/05-extension-overrides.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Patrik Oldsberg Signed-off-by: Fredrik Adelöw --- docs/frontend-system/architecture/05-extension-overrides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index cfb590d217..facae81e21 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -101,7 +101,7 @@ Note that it can still be a good idea to split your overrides out into separate To override an existing extension (which is already provided by a plugin), you need to provide an extension that has the same ID as the existing extension. That is, all kind, namespaces, and name must match the extension you want to replace. This means that you typically need to provide an explicit namespace when overriding extensions from a plugin. -Imagine that we have a plugin with search id and the plugin provides a search page extension that you want to fully override with your own custom component. To do so, you have to create your page extension and inform to the extension factory that the extension namespace is search to make sure you are overriding the search page of the plugin with id 'search' and not creating a anonymous page that will not override thesearch plugin one. +Imagine you have a plugin with the ID `'search'`, and the plugin provides a page extension that you want to fully override with your own custom component. To do so, you need to create your page extension with an explicit `namespace` option that matches that of the plugin that you want to override, in this case `'search'`. If the existing extension also has an explicit `name` you'd need to set the `name` of your override extension to the same value as well. ```tsx // packages/app/src/search.ts From 564f731e964e960d2e1bd4970d687e88345113b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 22 Dec 2023 14:34:47 +0100 Subject: [PATCH 158/283] Update docs/frontend-system/architecture/05-extension-overrides.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Patrik Oldsberg Signed-off-by: Fredrik Adelöw --- docs/frontend-system/architecture/05-extension-overrides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index facae81e21..4ee859709b 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -113,4 +113,4 @@ const customSearchPage = createPageExtension({ }); ``` -We recommend that plugin developes share the extension ids in their plugin documentations, but usually you can infer the id by following the (Naming pattern)[./08-naming-patterns] standars. +We recommend that plugin developes share the extension IDs in their plugin documentations, but usually you can infer the id by following the (Naming pattern)[./08-naming-patterns] standars. From ebc63612ace1318e5a51d44f187a9191245cf93e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 22 Dec 2023 15:15:13 +0100 Subject: [PATCH 159/283] address some of the comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .github/vale/Vocab/Backstage/accept.txt | 4 +++- .../architecture/05-extension-overrides.md | 15 +++------------ 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/.github/vale/Vocab/Backstage/accept.txt b/.github/vale/Vocab/Backstage/accept.txt index d557434d78..dc0b74b98c 100644 --- a/.github/vale/Vocab/Backstage/accept.txt +++ b/.github/vale/Vocab/Backstage/accept.txt @@ -312,6 +312,8 @@ rebase rebasing Recharts Redash +renderer +renderers replicasets repo Repo @@ -463,4 +465,4 @@ zod Zolotusky zoomable zsh -scrollable \ No newline at end of file +scrollable diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index 4ee859709b..6317783347 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -10,18 +10,9 @@ description: Frontend extension overrides ## Introduction -An extension override is another building block in the Frontend System that allows you to programmatically override app or plugin extensions. Extension overrides are recommended in the following cases: +An extension override is a building block of the Frontend System that allows you to programmatically override app or plugin extensions anywhere in your application. Since the entire application is built mostly out of extensions from the bottom up, this is a powerful feature. You can use it for example to provide your own app root layout, to replace the implementation of a Utility API with your a custom one, to override how the catalog page renders itself, and much more. -- Override the app skeleton layout; -- Override a default api implementation; -- Override a default app component; -- Override a plugin's default page; -- Etc. - -It is also important to clarify when an override isn't needed. Creating an extension override is not recommended when: - -- When you just want to configure a plugin, such as changing the attachment point, a path or any other setting. Be sure to read the extension documentation before overriding an extension to make sure you cannot configure it to work the way you want; -- It is already possible to enable an extension that is already provided by the plugin. Imagine we have a Search plugin that provides a default search result item extension for rendering search results. Consider also that we have a Catalog plugin with a disabled Catalog search result item extension. To change the way Catalog search result items are rendered, you don't need to override the default result item extension. The only thing you need to do is enable the Catalog search result extension via the config file. For other types of search results, the default Search result item will continue to be used. +Note that in general, most features should have a good level of customizability built into themselves, so that users do not have to leverage extension overrides to achieve common goals. A well written feature often has app-config settings, or uses extension inputs for extensibility where applicable. An example of this is the search plugin which allows you to provide result renderers as inputs rather than replacing the result page wholesale just to tweak how results are shown. Adopters should be taken advantage of those when possible, and only use extension overrides when it's necessary to entirely replace the extension. Check the respective extension documentation if available for guidance. ## Creating an Extension Override @@ -113,4 +104,4 @@ const customSearchPage = createPageExtension({ }); ``` -We recommend that plugin developes share the extension IDs in their plugin documentations, but usually you can infer the id by following the (Naming pattern)[./08-naming-patterns] standars. +We recommend that plugin developes share the extension IDs in their plugin documentation, but usually you can infer the ID by following the (naming patterns)[./08-naming-patterns] documentation. From 445a8dc1d31d783fab5dc505d63f92a84a42f6d1 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 12 Jan 2024 15:05:05 +0100 Subject: [PATCH 160/283] refactor: apply review sugggestions Signed-off-by: Camila Belo --- .../architecture/05-extension-overrides.md | 89 +++++++++---------- 1 file changed, 42 insertions(+), 47 deletions(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index 6317783347..17daef6b6c 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -14,38 +14,63 @@ An extension override is a building block of the Frontend System that allows you Note that in general, most features should have a good level of customizability built into themselves, so that users do not have to leverage extension overrides to achieve common goals. A well written feature often has app-config settings, or uses extension inputs for extensibility where applicable. An example of this is the search plugin which allows you to provide result renderers as inputs rather than replacing the result page wholesale just to tweak how results are shown. Adopters should be taken advantage of those when possible, and only use extension overrides when it's necessary to entirely replace the extension. Check the respective extension documentation if available for guidance. -## Creating an Extension Override +## Overriding App Extensions -The following steps should be followed to override extensions: +If you want to override an app extension, you will need to create a new extension to replace the existing one and add it to the list of overridden features. The steps are: + +1. Create your extension overrides + +In this example below, we are going to create custom extensions for the app light and dark themes: ```tsx -// plugins/aperture-overrides/src/overrides.ts +// packages/app/src/themes.ts import { - createThemeApi, + createThemeExtension, createExtensionOverrides } from '@backstage/frontend-plugin-api'; +import { apertureThemes } from './themes'; +import { ApertureLightIcon, ApertureDarkIcon } from './icons'; // Creating a light theme extension; -const apertureLightTheme = createThemeApi({ … }); +const apertureLightTheme = createThemeExtension({ + namespace: 'app', + name: 'light', + title: 'Aperture Light Theme', + variant: 'light', + icon: , + Provider: ({ children }) => ( + + ), +}); // Creating a dark theme extension; -const apertureDarkTheme = createThemeApi({ … }); +const apertureDarkTheme = createThemeExtension({ + namespace: 'app', + name: 'dark', + title: 'Aperture Dark Theme', + variant: 'dark', + icon: , + Provider: ({ children }) => ( + + ), +}); // Creating an extension overrides preset export createExtensionOverrides({ extensions: [apertureLightTheme, apertureDarkTheme] }); - -// plugins/aperture-overrides/src/index.ts -export { default } from './overrides'; ``` -For this example, we are creating overrides for the light and dark theme extensions and exporting the overrides from the plugin index file. Now we are able to use the overrides in a Backstage app: +We exported the overrides for the light and dark app theme extensions from a separate file in the code snippet above. To override the default app's light and dark theme extensions, we must ensure that the extension namespace and name match the ones in the default app themes extension definitions. + +2. Use the overrides in your Backstage App + +Now we are able to use the overrides in a Backstage app: ```tsx // packages/app/src/App.tsx import { createApp } from '@backstage/frontend-app-api'; -import apertureOverrides from ‘@backstage/plugin-aperture-overrides’ +import apertureOverrides from '@backstage/plugin-aperture-overrides' const app = createApp({ features: [ apertureOverrides ], @@ -54,43 +79,13 @@ const app = createApp({ export default app.createRoot(). ``` -If the plugin you want to change is internal to your company or you just want to replace one of the application's core extensions, you can decide to create replacements directly in the application for local replacements. See an example below: - -```tsx -// packages/app/src/themes.ts -import { createExtensionOverrides } from from '@backstage/frontend-plugin-api'; - -// Creating the light theme extension; -export const apertureLightTheme = createThemeApi({ … }); - -// Creating the light theme extension; -const apertureDarkTheme = createThemeApi({ … }); - -// Exporting your custom extensions -export default [apertureLightTheme, apertureDarkTheme]; - -// packages/app/src/App.tsx -import { createApp } from '@backstage/frontend-app-api'; -import themes from ‘./themes’ - -const app = createApp({ - features: [ - createExtensionOverrides({ - extensions: [ - ...themes, - ], - }), - ], -}); - -export default app.createRoot(); -``` +If the plugin you want to change is internal to your company or you just want to replace one of the application's core extensions, you can decide to store the overrides code directly in the app package or extract them to a separate package. Note that it can still be a good idea to split your overrides out into separate packages in large projects. But it's up to you to decide how to group the extensions into extension overrides. -## Overriding Existing Extensions +## Overriding Plugin Extensions -To override an existing extension (which is already provided by a plugin), you need to provide an extension that has the same ID as the existing extension. That is, all kind, namespaces, and name must match the extension you want to replace. This means that you typically need to provide an explicit namespace when overriding extensions from a plugin. +To override an extension that is provided by a plugin, you need to provide an new extension that has the same ID as the existing extension. That is, all kind, namespace, and name options must match the extension you want to replace. This means that you typically need to provide an explicit namespace when overriding extensions from a plugin. Imagine you have a plugin with the ID `'search'`, and the plugin provides a page extension that you want to fully override with your own custom component. To do so, you need to create your page extension with an explicit `namespace` option that matches that of the plugin that you want to override, in this case `'search'`. If the existing extension also has an explicit `name` you'd need to set the `name` of your override extension to the same value as well. @@ -98,9 +93,9 @@ Imagine you have a plugin with the ID `'search'`, and the plugin provides a page // packages/app/src/search.ts const customSearchPage = createPageExtension({ namespace: 'search', - // Omitting name since it is the root plugin page - defaultPath: 'search' - loader: async () =>
My custom search page + // Omitting name since it is the index plugin page + defaultPath: 'search', + loader: () => Promise.resolve(
My custom search page
), }); ``` From deeb5f70fda95b10fc412d82d4aa78b94fd48426 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Mon, 15 Jan 2024 22:41:57 +0100 Subject: [PATCH 161/283] Update docs/frontend-system/architecture/05-extension-overrides.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Camila Belo --- docs/frontend-system/architecture/05-extension-overrides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index 17daef6b6c..53f5ad8b1d 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -12,7 +12,7 @@ description: Frontend extension overrides An extension override is a building block of the Frontend System that allows you to programmatically override app or plugin extensions anywhere in your application. Since the entire application is built mostly out of extensions from the bottom up, this is a powerful feature. You can use it for example to provide your own app root layout, to replace the implementation of a Utility API with your a custom one, to override how the catalog page renders itself, and much more. -Note that in general, most features should have a good level of customizability built into themselves, so that users do not have to leverage extension overrides to achieve common goals. A well written feature often has app-config settings, or uses extension inputs for extensibility where applicable. An example of this is the search plugin which allows you to provide result renderers as inputs rather than replacing the result page wholesale just to tweak how results are shown. Adopters should be taken advantage of those when possible, and only use extension overrides when it's necessary to entirely replace the extension. Check the respective extension documentation if available for guidance. +Note that in general, most features should have a good level of customizability built into themselves, so that users do not have to leverage extension overrides to achieve common goals. A well written feature often has app-config settings, or uses extension inputs for extensibility where applicable. An example of this is the search plugin which allows you to provide result renderers as inputs rather than replacing the result page wholesale just to tweak how results are shown. Adopters should take advantage of those when possible, and only use extension overrides when it's necessary to entirely replace the extension. Check the respective extension documentation if available for guidance. ## Overriding App Extensions From 147d7a4067a5b112dcbb7a208fc77c0baa3e16ad Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Mon, 15 Jan 2024 22:42:32 +0100 Subject: [PATCH 162/283] Update docs/frontend-system/architecture/05-extension-overrides.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Camila Belo --- docs/frontend-system/architecture/05-extension-overrides.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index 53f5ad8b1d..03ead23537 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -22,8 +22,7 @@ If you want to override an app extension, you will need to create a new extensio In this example below, we are going to create custom extensions for the app light and dark themes: -```tsx -// packages/app/src/themes.ts +```tsx title="packages/app/src/themes.ts" import { createThemeExtension, createExtensionOverrides From 7066b00773acf715a51e7694205e4ec8c95f9289 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Mon, 15 Jan 2024 22:42:38 +0100 Subject: [PATCH 163/283] Update docs/frontend-system/architecture/05-extension-overrides.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Camila Belo --- docs/frontend-system/architecture/05-extension-overrides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index 03ead23537..5dff6a3ccd 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -93,7 +93,7 @@ Imagine you have a plugin with the ID `'search'`, and the plugin provides a page const customSearchPage = createPageExtension({ namespace: 'search', // Omitting name since it is the index plugin page - defaultPath: 'search', + defaultPath: '/search', loader: () => Promise.resolve(
My custom search page
), }); ``` From d45d5bc879ab128e11d2c5cf081cb989ff709fdd Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Mon, 15 Jan 2024 23:50:34 +0100 Subject: [PATCH 164/283] docs(frontend-system): add orphan extension overrides section Signed-off-by: Camila Belo --- .../architecture/05-extension-overrides.md | 91 +++++++++++++++---- 1 file changed, 74 insertions(+), 17 deletions(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index 5dff6a3ccd..572018606e 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -16,13 +16,13 @@ Note that in general, most features should have a good level of customizability ## Overriding App Extensions -If you want to override an app extension, you will need to create a new extension to replace the existing one and add it to the list of overridden features. The steps are: +In order to override an app extension, you must create a new extension and add it to the list of overridden features. The steps are: create your extension overrides and use them in Backstage. -1. Create your extension overrides +### Example -In this example below, we are going to create custom extensions for the app light and dark themes: +In the example below, we create a file that exports custom extensions for the app's `light` and `dark` themes: -```tsx title="packages/app/src/themes.ts" +```tsx title="packages/app/src/themes.ts" {10-11,22-23} showLineNumbers import { createThemeExtension, createExtensionOverrides @@ -30,7 +30,7 @@ import { import { apertureThemes } from './themes'; import { ApertureLightIcon, ApertureDarkIcon } from './icons'; -// Creating a light theme extension; +// Creating a light theme extension const apertureLightTheme = createThemeExtension({ namespace: 'app', name: 'light', @@ -42,7 +42,7 @@ const apertureLightTheme = createThemeExtension({ ), }); -// Creating a dark theme extension; +// Creating a dark theme extension const apertureDarkTheme = createThemeExtension({ namespace: 'app', name: 'dark', @@ -60,16 +60,13 @@ export createExtensionOverrides({ }); ``` -We exported the overrides for the light and dark app theme extensions from a separate file in the code snippet above. To override the default app's light and dark theme extensions, we must ensure that the extension namespace and name match the ones in the default app themes extension definitions. - -2. Use the overrides in your Backstage App +Lines `10` and `22` should be highlighted because they declare `namespace` as `'app'`, so the system knows we are overriding app extensions. Additionally, to specifically override the `light` and `dark` theme extensions, we set the `name` option to `light` and `dark` respectively on lines `11` and `23`. Therefore, to override app theme extensions, we ensure that the extension `namespace` and `name` match those of the default app theme extension definitions. Now we are able to use the overrides in a Backstage app: -```tsx -// packages/app/src/App.tsx +```tsx title="packages/app/src/App.tsx" {5} showLineNumbers import { createApp } from '@backstage/frontend-app-api'; -import apertureOverrides from '@backstage/plugin-aperture-overrides' +import apertureOverrides from './themes'; const app = createApp({ features: [ apertureOverrides ], @@ -84,18 +81,78 @@ Note that it can still be a good idea to split your overrides out into separate ## Overriding Plugin Extensions -To override an extension that is provided by a plugin, you need to provide an new extension that has the same ID as the existing extension. That is, all kind, namespace, and name options must match the extension you want to replace. This means that you typically need to provide an explicit namespace when overriding extensions from a plugin. +To override an extension that is provided by a plugin, you need to provide an new extension that has the same ID as the existing extension. That is, all kind, namespace, and name options must match the extension you want to replace. This means that you typically need to provide an explicit `namespace` when overriding extensions from a plugin. + +:::info +We recommend that plugin developers share the extension IDs in their plugin documentation, but usually you can infer the ID by following the [naming patterns](./08-naming-patterns.md) documentation. +::: + +### Example Imagine you have a plugin with the ID `'search'`, and the plugin provides a page extension that you want to fully override with your own custom component. To do so, you need to create your page extension with an explicit `namespace` option that matches that of the plugin that you want to override, in this case `'search'`. If the existing extension also has an explicit `name` you'd need to set the `name` of your override extension to the same value as well. -```tsx -// packages/app/src/search.ts +```tsx title="packages/app/src/search.ts" showLineNumbers +import { createPageExtension } from '@backstage/frontend-plugin-api'; + +// Creating a custom search page extension const customSearchPage = createPageExtension({ namespace: 'search', // Omitting name since it is the index plugin page defaultPath: '/search', - loader: () => Promise.resolve(
My custom search page
), + loader: () => import('./SearchPage').then(m => m.), +}); + +export createExtensionOverrides({ + extensions: [customSearchPage] }); ``` -We recommend that plugin developes share the extension IDs in their plugin documentation, but usually you can infer the ID by following the (naming patterns)[./08-naming-patterns] documentation. +Don't forget to configure your overrides in the `createApp` function: + +```tsx title="packages/app/src/App.tsx" {5} showLineNumbers +import { createApp } from '@backstage/frontend-app-api'; +import searchOverrides from './search'; + +const app = createApp({ + features: [searchOverrides], +}); + +export default app.createRoot(); +``` + +Now let's talk about the last override case, orphan extensions. + +## Creating Orphan Extensions + +Sometimes you just need to quickly create a new extension and not overwrite an app extension or plugin. You can also use overrides to create extensions, but remember that if you want to make this extension available for installation by other users, we recommend providing it via a plugin in a separate package. + +### Example + +Imagine you want to create a page that is currently only used by your application, like an Institutional page for example, you can use overrides to extend the Backstage app to render it. To do so, simply create a page extension and pass it to the app as an override: + +```tsx title="packages/app/src/App.ts" showLineNumbers +import { createApp } from '@backstage/frontend-app-api'; +import { + createPageExtension, + createExtensionOverrides, +} from '@backstage/frontend-plugin-api'; + +const app = createApp({ + features: [ + createExtensionOverrides({ + extensions: [ + createPageExtension({ + name: 'institutional', + defaultPath: '/institutional', + loader: () => + import('./institutional').then(m => ), + }), + ], + }), + ], +}); + +export default app.createRoot(); +``` + +Note that we are omitting `namespace` when creating the page extension. When we omit `namespace`, we are telling the system the new extension is orphaned (not an application or plugin extension) and this is all about orphaned extensions! From 6d1d2967b313728f9d92939242edeb9870877d2a Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 16 Jan 2024 12:26:30 +0100 Subject: [PATCH 165/283] Update docs/frontend-system/architecture/05-extension-overrides.md Co-authored-by: Philipp Hugenroth Signed-off-by: Camila Belo --- docs/frontend-system/architecture/05-extension-overrides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index 572018606e..5a40bd079c 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -12,7 +12,7 @@ description: Frontend extension overrides An extension override is a building block of the Frontend System that allows you to programmatically override app or plugin extensions anywhere in your application. Since the entire application is built mostly out of extensions from the bottom up, this is a powerful feature. You can use it for example to provide your own app root layout, to replace the implementation of a Utility API with your a custom one, to override how the catalog page renders itself, and much more. -Note that in general, most features should have a good level of customizability built into themselves, so that users do not have to leverage extension overrides to achieve common goals. A well written feature often has app-config settings, or uses extension inputs for extensibility where applicable. An example of this is the search plugin which allows you to provide result renderers as inputs rather than replacing the result page wholesale just to tweak how results are shown. Adopters should take advantage of those when possible, and only use extension overrides when it's necessary to entirely replace the extension. Check the respective extension documentation if available for guidance. +In general, most features should have a good level of customization built into them, so that users do not have to leverage extension overrides to achieve common goals. A well written feature often has `app-config` settings, or uses extension inputs for extensibility where applicable. An example of this is the search plugin, which allows you to provide result renderers as inputs rather than replacing the result page wholesale just to tweak how results are shown. Adopters should take advantage of those when possible, and only use extension overrides when it's necessary to entirely replace the extension. Check the respective extension documentation for guidance. ## Overriding App Extensions From e0e6e853b2953f8146b5abdd6843879bb90e78d0 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 16 Jan 2024 12:27:03 +0100 Subject: [PATCH 166/283] Update docs/frontend-system/architecture/05-extension-overrides.md Co-authored-by: Philipp Hugenroth Signed-off-by: Camila Belo --- docs/frontend-system/architecture/05-extension-overrides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index 5a40bd079c..52c76a4673 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -128,7 +128,7 @@ Sometimes you just need to quickly create a new extension and not overwrite an a ### Example -Imagine you want to create a page that is currently only used by your application, like an Institutional page for example, you can use overrides to extend the Backstage app to render it. To do so, simply create a page extension and pass it to the app as an override: +Imagine you want to create a page that is currently only used by your application, like an Institutional page, for example. You can use overrides to extend the Backstage app to render it. To do so, simply create a page extension and pass it to the app as an override: ```tsx title="packages/app/src/App.ts" showLineNumbers import { createApp } from '@backstage/frontend-app-api'; From e761ab547116b26853c51ff1aee122dd37ae8d78 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 16 Jan 2024 12:27:19 +0100 Subject: [PATCH 167/283] Update docs/frontend-system/architecture/05-extension-overrides.md Co-authored-by: Philipp Hugenroth Signed-off-by: Camila Belo --- docs/frontend-system/architecture/05-extension-overrides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index 52c76a4673..618efefc56 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -155,4 +155,4 @@ const app = createApp({ export default app.createRoot(); ``` -Note that we are omitting `namespace` when creating the page extension. When we omit `namespace`, we are telling the system the new extension is orphaned (not an application or plugin extension) and this is all about orphaned extensions! +Note that we are omitting `namespace` when creating the page extension. When we omit `namespace`, we are telling the system the new extension is orphaned and not an application or plugin extension! From bf48a5bb8f7d25dd38df5dab734cf781395bc0b4 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 16 Jan 2024 12:27:39 +0100 Subject: [PATCH 168/283] Update docs/frontend-system/architecture/05-extension-overrides.md Co-authored-by: Philipp Hugenroth Signed-off-by: Camila Belo --- docs/frontend-system/architecture/05-extension-overrides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index 618efefc56..996f60f77d 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -81,7 +81,7 @@ Note that it can still be a good idea to split your overrides out into separate ## Overriding Plugin Extensions -To override an extension that is provided by a plugin, you need to provide an new extension that has the same ID as the existing extension. That is, all kind, namespace, and name options must match the extension you want to replace. This means that you typically need to provide an explicit `namespace` when overriding extensions from a plugin. +To override an extension that is provided by a plugin, you need to provide a new extension that has the same ID as the existing extension. That is, all kind, namespace, and name options must match the extension you want to replace. This means that you typically need to provide an explicit `namespace` when overriding extensions from a plugin. :::info We recommend that plugin developers share the extension IDs in their plugin documentation, but usually you can infer the ID by following the [naming patterns](./08-naming-patterns.md) documentation. From b144eba4a536e259f667433fe40a0855caf2ee19 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 16 Jan 2024 12:28:52 +0100 Subject: [PATCH 169/283] Update docs/frontend-system/architecture/05-extension-overrides.md Co-authored-by: Philipp Hugenroth Signed-off-by: Camila Belo --- docs/frontend-system/architecture/05-extension-overrides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index 996f60f77d..d51ebcea93 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -14,7 +14,7 @@ An extension override is a building block of the Frontend System that allows you In general, most features should have a good level of customization built into them, so that users do not have to leverage extension overrides to achieve common goals. A well written feature often has `app-config` settings, or uses extension inputs for extensibility where applicable. An example of this is the search plugin, which allows you to provide result renderers as inputs rather than replacing the result page wholesale just to tweak how results are shown. Adopters should take advantage of those when possible, and only use extension overrides when it's necessary to entirely replace the extension. Check the respective extension documentation for guidance. -## Overriding App Extensions +## Override App Extensions In order to override an app extension, you must create a new extension and add it to the list of overridden features. The steps are: create your extension overrides and use them in Backstage. From 012b38c8812745bd07c5896bb0af4905bdd6fb3f Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 16 Jan 2024 12:29:01 +0100 Subject: [PATCH 170/283] Update docs/frontend-system/architecture/05-extension-overrides.md Co-authored-by: Philipp Hugenroth Signed-off-by: Camila Belo --- docs/frontend-system/architecture/05-extension-overrides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index d51ebcea93..ffe8ff11c4 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -10,7 +10,7 @@ description: Frontend extension overrides ## Introduction -An extension override is a building block of the Frontend System that allows you to programmatically override app or plugin extensions anywhere in your application. Since the entire application is built mostly out of extensions from the bottom up, this is a powerful feature. You can use it for example to provide your own app root layout, to replace the implementation of a Utility API with your a custom one, to override how the catalog page renders itself, and much more. +An extension override is a building block of the frontend system that allows you to programmatically override app or plugin extensions anywhere in your application. Since the entire application is built mostly out of extensions from the bottom up, this is a powerful feature. You can use it for example to provide your own app root layout, to replace the implementation of a Utility API with a custom one, to override how the catalog page renders itself, and much more. In general, most features should have a good level of customization built into them, so that users do not have to leverage extension overrides to achieve common goals. A well written feature often has `app-config` settings, or uses extension inputs for extensibility where applicable. An example of this is the search plugin, which allows you to provide result renderers as inputs rather than replacing the result page wholesale just to tweak how results are shown. Adopters should take advantage of those when possible, and only use extension overrides when it's necessary to entirely replace the extension. Check the respective extension documentation for guidance. From 1c0c187d6ac9fe6eef4ebbc70fcf1562ea647a79 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 16 Jan 2024 13:01:33 +0100 Subject: [PATCH 171/283] Update docs/frontend-system/architecture/05-extension-overrides.md Co-authored-by: Philipp Hugenroth Signed-off-by: Camila Belo --- docs/frontend-system/architecture/05-extension-overrides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index ffe8ff11c4..6921315d5a 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -79,7 +79,7 @@ If the plugin you want to change is internal to your company or you just want to Note that it can still be a good idea to split your overrides out into separate packages in large projects. But it's up to you to decide how to group the extensions into extension overrides. -## Overriding Plugin Extensions +## Override Plugin Extensions To override an extension that is provided by a plugin, you need to provide a new extension that has the same ID as the existing extension. That is, all kind, namespace, and name options must match the extension you want to replace. This means that you typically need to provide an explicit `namespace` when overriding extensions from a plugin. From 17b2750329136dccf61c066823eeb4c3e69fb307 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 16 Jan 2024 13:12:09 +0100 Subject: [PATCH 172/283] docs(frontend-system): update orphan extensions section title Signed-off-by: Camila Belo --- docs/frontend-system/architecture/05-extension-overrides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index 6921315d5a..3791ee43b1 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -122,7 +122,7 @@ export default app.createRoot(); Now let's talk about the last override case, orphan extensions. -## Creating Orphan Extensions +## Create Orphan Extensions Sometimes you just need to quickly create a new extension and not overwrite an app extension or plugin. You can also use overrides to create extensions, but remember that if you want to make this extension available for installation by other users, we recommend providing it via a plugin in a separate package. From fbe52d23cff83f2f639f89baa8508cd1baee0bdc Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 17 Jan 2024 15:22:41 +0100 Subject: [PATCH 173/283] Update docs/frontend-system/architecture/05-extension-overrides.md Co-authored-by: Patrik Oldsberg Signed-off-by: Camila Belo --- docs/frontend-system/architecture/05-extension-overrides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index 3791ee43b1..bb177cd703 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -122,7 +122,7 @@ export default app.createRoot(); Now let's talk about the last override case, orphan extensions. -## Create Orphan Extensions +## Create Standalone Extensions Sometimes you just need to quickly create a new extension and not overwrite an app extension or plugin. You can also use overrides to create extensions, but remember that if you want to make this extension available for installation by other users, we recommend providing it via a plugin in a separate package. From 51d351cd6d1611d7be686214c3d6d2aa3b4fede0 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 17 Jan 2024 16:08:28 +0100 Subject: [PATCH 174/283] refactor(frontend-system/overrides): apply docs suggestions Signed-off-by: Camila Belo --- .../architecture/05-extension-overrides.md | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index bb177cd703..6a1037341e 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -22,7 +22,7 @@ In order to override an app extension, you must create a new extension and add i In the example below, we create a file that exports custom extensions for the app's `light` and `dark` themes: -```tsx title="packages/app/src/themes.ts" {10-11,22-23} showLineNumbers +```tsx title="packages/app/src/themes.ts" import { createThemeExtension, createExtensionOverrides @@ -32,8 +32,10 @@ import { ApertureLightIcon, ApertureDarkIcon } from './icons'; // Creating a light theme extension const apertureLightTheme = createThemeExtension({ + // highlight-start namespace: 'app', name: 'light', + // highlight-end title: 'Aperture Light Theme', variant: 'light', icon: , @@ -44,8 +46,10 @@ const apertureLightTheme = createThemeExtension({ // Creating a dark theme extension const apertureDarkTheme = createThemeExtension({ + // highlight-start namespace: 'app', name: 'dark', + // highlight-end title: 'Aperture Dark Theme', variant: 'dark', icon: , @@ -60,16 +64,17 @@ export createExtensionOverrides({ }); ``` -Lines `10` and `22` should be highlighted because they declare `namespace` as `'app'`, so the system knows we are overriding app extensions. Additionally, to specifically override the `light` and `dark` theme extensions, we set the `name` option to `light` and `dark` respectively on lines `11` and `23`. Therefore, to override app theme extensions, we ensure that the extension `namespace` and `name` match those of the default app theme extension definitions. +Note that we declare `namespace` as `'app'` while creating the themes, so the system knows we are overriding app extensions. Additionally, to specifically override the `light` and `dark` theme extensions, we set the `name` option to `light` and `dark`. Therefore, to override app theme extensions, we ensure that the extension `namespace` and `name` match those of the default app theme extension definitions. Now we are able to use the overrides in a Backstage app: -```tsx title="packages/app/src/App.tsx" {5} showLineNumbers +```tsx title="packages/app/src/App.tsx" import { createApp } from '@backstage/frontend-app-api'; -import apertureOverrides from './themes'; +import themeOverrides from './themes'; const app = createApp({ - features: [ apertureOverrides ], + // highlight-next-line + features: [ themeOverrides ], }); export default app.createRoot(). @@ -91,11 +96,12 @@ We recommend that plugin developers share the extension IDs in their plugin docu Imagine you have a plugin with the ID `'search'`, and the plugin provides a page extension that you want to fully override with your own custom component. To do so, you need to create your page extension with an explicit `namespace` option that matches that of the plugin that you want to override, in this case `'search'`. If the existing extension also has an explicit `name` you'd need to set the `name` of your override extension to the same value as well. -```tsx title="packages/app/src/search.ts" showLineNumbers +```tsx title="packages/app/src/search.ts" import { createPageExtension } from '@backstage/frontend-plugin-api'; // Creating a custom search page extension const customSearchPage = createPageExtension({ + // highlight-next-line namespace: 'search', // Omitting name since it is the index plugin page defaultPath: '/search', @@ -109,11 +115,12 @@ export createExtensionOverrides({ Don't forget to configure your overrides in the `createApp` function: -```tsx title="packages/app/src/App.tsx" {5} showLineNumbers +```tsx title="packages/app/src/App.tsx" import { createApp } from '@backstage/frontend-app-api'; import searchOverrides from './search'; const app = createApp({ + // highlight-next-line features: [searchOverrides], }); @@ -130,7 +137,7 @@ Sometimes you just need to quickly create a new extension and not overwrite an a Imagine you want to create a page that is currently only used by your application, like an Institutional page, for example. You can use overrides to extend the Backstage app to render it. To do so, simply create a page extension and pass it to the app as an override: -```tsx title="packages/app/src/App.ts" showLineNumbers +```tsx title="packages/app/src/App.ts" import { createApp } from '@backstage/frontend-app-api'; import { createPageExtension, @@ -141,12 +148,14 @@ const app = createApp({ features: [ createExtensionOverrides({ extensions: [ + // highlight-start createPageExtension({ name: 'institutional', defaultPath: '/institutional', loader: () => import('./institutional').then(m => ), }), + // highlight-end ], }), ], @@ -155,4 +164,4 @@ const app = createApp({ export default app.createRoot(); ``` -Note that we are omitting `namespace` when creating the page extension. When we omit `namespace`, we are telling the system the new extension is orphaned and not an application or plugin extension! +Note that we are omitting `namespace` when creating the page extension. When we omit `namespace`, we are telling the system the new extension is standalone and not an application or plugin extension! From 943ac7a6cdb464d32de7cdf1aa614d73c566c74d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:42:05 +0000 Subject: [PATCH 175/283] chore(deps): update chromaui/action digest to 7fb6b04 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/verify_storybook.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/verify_storybook.yml b/.github/workflows/verify_storybook.yml index d7f90118de..29d86e913a 100644 --- a/.github/workflows/verify_storybook.yml +++ b/.github/workflows/verify_storybook.yml @@ -51,7 +51,7 @@ jobs: - run: yarn build-storybook - - uses: chromaui/action@722516a3934360dac82cdef8dbab38e824fc6fa1 # v1 + - uses: chromaui/action@7fb6b0407c69171ce521d08355a825958a5ef81a # v1 with: token: ${{ secrets.GITHUB_TOKEN }} # projectToken intentionally shared to allow collaborators to run Chromatic on forks From 375dd30fa33f4be26e1c7c49a4d4eb1ee9e19657 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 8 Jan 2024 13:43:36 +0100 Subject: [PATCH 176/283] docs/frontend-system: add missing sorting prefix Signed-off-by: Patrik Oldsberg --- .../building-plugins/{testing.md => 02-testing.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/frontend-system/building-plugins/{testing.md => 02-testing.md} (100%) diff --git a/docs/frontend-system/building-plugins/testing.md b/docs/frontend-system/building-plugins/02-testing.md similarity index 100% rename from docs/frontend-system/building-plugins/testing.md rename to docs/frontend-system/building-plugins/02-testing.md From 39a1dbd9d837e0479b24438ec265f35b38b3d8ea Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 9 Jan 2024 21:02:42 +0100 Subject: [PATCH 177/283] docs/frontend-system: initial plugin index docs Signed-off-by: Patrik Oldsberg --- .../building-plugins/01-index.md | 201 ++++++++++++++++++ microsite/sidebars.json | 5 +- 2 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 docs/frontend-system/building-plugins/01-index.md diff --git a/docs/frontend-system/building-plugins/01-index.md b/docs/frontend-system/building-plugins/01-index.md new file mode 100644 index 0000000000..730dd58156 --- /dev/null +++ b/docs/frontend-system/building-plugins/01-index.md @@ -0,0 +1,201 @@ +--- +id: index +title: Building Frontend Plugins +sidebar_label: Overview +# prettier-ignore +description: Building frontend plugins using the new frontend system +--- + +> **NOTE: The new frontend system is in alpha and is only supported by a small number of plugins.** + +This section covers how to build your own frontend [plugins](../architecture/04-plugins.md) and +[overrides](../architecture/05-extension-overrides.md). They are sometimes collectively referred to as +frontend _features_, and what you install to build up a Backstage frontend [app](../architecture/02-app.md). + +## Creating a new plugin + +This guide assumes that you already have a Backstage project set up. Even if you only want to develop a single plugin for publishing, we still recommend that you do so in a standard Backstage monorepo project, as you often end up needing multiple packages. For instructions on how to set up a new project, see our [getting started](../../getting-started/index.md#prerequisites) documentation. + +To create a frontend plugin, run `yarn new`, select `plugin`, and fill out the rest of the prompts. This will create a new package at `plugins/`, which will be the main entrypoint for your plugin. + +> **NOT: The created plugin will currently be templated for use in the legacy frontend system, and you will need to replace the existing plugin wiring code.** + +## The plugin instance + +The starting point of a frontend plugin is the `createPlugin` function, which accepts a single options object as its only parameter. It is imported from `@backstage/frontend-plugin-api`, which is where you will find most of the common APIs for building plugins. + +This is how to create a minimal plugin: + +```tsx title="in src/plugin.ts" +import { createPlugin } from '@backstage/frontend-plugin-api'; + +export const examplePlugin = createPlugin({ + id: 'example', + extensions: [], +}); +``` + +```tsx title="in src/index.ts" +export { examplePlugin as default } from './plugin'; +``` + +Note that we export the plugin as the default export of our package from `src/index.ts`. This is important, as it is how users of our plugin are able to seamlessly install the plugin package in a Backstage app without having to reference the plugin instance through code. + +The plugin ID should be a lowercase dash-separated string, while the plugin instance variable should be the camelCase version of the ID with a `Plugin` suffix. For more details on naming patterns within the frontend system, see [the article on naming patterns](../architecture/08-naming-patterns.md). By sticking to these naming patterns you ensure that users of your plugin more easily recognize the exports and features provided by your plugin. + +## Adding extensions + +The plugin that we created above is empty, and does't provide any actual functionality. To add functionality to a plugin you need to create and provide it with one or more [extensions](../architecture/03-extensions.md). Let's continue by adding a standalone page to our plugin, as well as a navigation item that allows users to navigate to the page. + +To create a new extension you typically use pre-defined [extension creators](../architecture/03-extensions.md#extension-creators), provided either by the framework itself or by other plugins. In this case we'll need to use `createPageExtension` and `createNavItemExtension`, both from `@backstage/frontend-plugin-api`. We will also need to [create a route reference](../architecture/07-routes.md#creating-a-route-reference) to use as a reference for out page, allowing us to dynamically create URLs that link to our page. + +```tsx title="in src/routes.ts" +import { createRouteRef } from '@backstage/frontend-plugin-api'; + +// Typically all routes are defined in src/routes.ts, in order to avoid circular imports. + +// This will be the route reference for our example page. If you want to link +// to the page from somewhere else, you can use this reference to generate the target path. +export const rootRouteRef = createRouteRef(); +``` + +```tsx title="in src/plugin.ts" +import { + createPlugin, + createPageExtension, + createNavItemExtension, +} from '@backstage/frontend-plugin-api'; +import { rootRouteRef } from './routes'; + +// Note that these extensions aren't exported, only the plugin itself it. +// You can export it locally for testing purposes, but don't export it from the plugin package. +const examplePage = createPageExtension({ + routeRef: rootRouteRef, + + // This is the default path of this page, but integrators are free to override it + defaultPath: '/example', + + // Page extensions are always dynamically loaded using React.lazy(). + // [1] All of the functionality of this page is implemented in the + // ExamplePage component, which is a regular React component. + loader: () => import('./components/ExamplePage').then(m => m.ExamplePage), +}); + +// This nav item is provided to the app.nav extension, and will by default be rendered as a sidebar item +const exampleNavItem = createNavItemExtension({ + routeRef: rootRouteRef, + title: 'Example', + icon: ExampleIcon, // Custom SvgIcon, or one from the Material UI icon library +}); + +// The same plugin as above, now with the extensions added +export const examplePlugin = createPlugin({ + id: 'example', + extensions: [examplePage, exampleNavItem], + // [2] We can also make routes available to other plugins. + routes: { + root: rootRouteRef, + }, +}); +``` + +What we've built here is a very common type of plugin. It's a top-level tool that provides a single page, along with a method for navigating to that page. The implementation of the page component at `[1]` can be arbitrarily complex, anything from a single simple information page, to a full-blown application with multiple sub-pages. + +We have also made the route reference available to other plugins at `[2]`. This makes it possible for app integrators to bind an external link from a different plugin to our plugin page. You can read more about how this works in the [External Route References](../architecture/07-routes.md#external-route-references) section. + +## Utility APIs + +Another type of extensions that is commonly used are [Utility APIs](../utility-apis/01-index.md). They can encapsulate shared pieces of functionality of your plugin, for example an API client for a backend service. You can optionally export your Utility API for other plugins to use, or allow integrators to replace the implementation of your Utility API with their own. For details on how to define and provide your own Utility API in your plugin, see the section on [creating Utility APIs](../utility-apis/02-creating.md). + +What we'll show here is a complete example of a simple Utility API used only within the plugin itself: + +```tsx title="src/api.ts - Defining an interface, API reference, and default implementation" +import { createApiRef } from '@backstage/frontend-plugin-api'; + +export interface ExampleApi { + getExample(): { example: string }; +} + +export const exampleApiRef = createApiRef({ + id: 'plugin.example', +}); + +export class DefaultExampleApi implements ExampleApi { + getExample(): { example: string } { + return { example: 'Hello World!' }; + } +} +``` + +```tsx title="src/components/ExamplePage.tsx - Using the API in our page component" +import { useApi } from '@backstage/frontend-plugin-api'; +import { exampleApiRef } from '../api'; + +export function ExamplePage() { + // highlight-next-line + const exampleApi = useApi(exampleApiRef); + + return ( +
+

Example Page

+

Example: {exampleApi.getExample()}

+
+ ); +} +``` + +```tsx title="in src/plugin.ts - Registering a factory for our API" +import { + createApiFactory, + createApiExtension, +} from '@backstage/frontend-plugin-api'; +import { exampleApiRef, DefaultExampleApi } from './api'; + +// highlight-add-start +const exampleApi = createApiExtension({ + factory: createApiFactory({ + api: exampleApiRef, + deps: {}, + factory: () => new DefaultExampleApi(), + }), +}); +// highlight-add-end + +/* Omitted definitions for examplePage, exampleNavItem, and rootRouteRef. */ + +export const examplePlugin = createPlugin({ + id: 'example', + extensions: [ + // highlight-add-next-line + exampleApi, + examplePage, + exampleNavItem, + ], + routes: { + root: rootRouteRef, + }, +}); +``` + +## Plugin specific extensions + +There are many different plugins that you can extend with additional functionality through extensions. One such plugin is the catalog plugin, one of the core features of Backstage. It lets you catalog the software in your organization, where each item in the catalog has its own page that can be populated with tools and information relating to that catalog entity. In this example we will explore how our plugin can provide such a tool to display on an entity page. + +```tsx title="in src/plugin.ts - An example entity content extension" +import { createEntityContentExtension } from '@backstage/plugin-catalog-react'; + +// Entity content extension are similar to page extensions in that they are rendered at a route, +// although they also have a title to support in-line navigation between the different content. +// Just like a page extensions the content is lazy loaded, and you can also provide a +// route reference if you want to be able to generate a URL that links to the content. +const exampleEntityContent = createEntityContentExtension({ + defaultPath: 'example', + defaultTitle: 'Example', + loader: () => + import('./components/ExampleEntityContent').then(m => ( + + )), +}); +``` + +The `ExampleEntityContent` itself is again a regular React component where you can implement any functionality you want. To access the entity that the content is being rendered for, you can use the `useEntity` hook from `@backstage/plugin-catalog-react`. You can see a full list of API provided by the catalog React library in [the API reference](../../reference/plugin-catalog-react.md). diff --git a/microsite/sidebars.json b/microsite/sidebars.json index c54e59f45c..c34598376f 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -411,7 +411,10 @@ { "type": "category", "label": "Building Plugins", - "items": ["frontend-system/building-plugins/testing"] + "items": [ + "frontend-system/building-plugins/index", + "frontend-system/building-plugins/testing" + ] }, { "type": "category", From 07b40ecb87909aff23e1c67e917ad7d9b15ea4fb Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 9 Jan 2024 22:51:49 +0100 Subject: [PATCH 178/283] docs/frontend-system: add extenison types doc Signed-off-by: Patrik Oldsberg --- .../building-plugins/03-extension-types.md | 43 +++++++++++++++++++ microsite/sidebars.json | 3 +- 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 docs/frontend-system/building-plugins/03-extension-types.md diff --git a/docs/frontend-system/building-plugins/03-extension-types.md b/docs/frontend-system/building-plugins/03-extension-types.md new file mode 100644 index 0000000000..36eda55112 --- /dev/null +++ b/docs/frontend-system/building-plugins/03-extension-types.md @@ -0,0 +1,43 @@ +--- +id: index +title: Frontend System Extension Types +sidebar_label: Extension Types +# prettier-ignore +description: Extension types provided by the frontend system and core features +--- + +> **NOTE: The new frontend system is in alpha and is only supported by a small number of plugins.** + +This section covers many of the [extension types](../architecture/03-extensions.md#extension-creators) available at your disposal when building Backstage frontend plugins. + +## Built-in extension types + +These are the extension types provided by the Backstage frontend framework itself. + +### Api - [Reference](../../reference/frontend-plugin-api.createapiextension.md) + +An API extension is used to add or override [Utility API factories](../utility-apis/01-index.md) in the app. They are commonly used by plugins for both internal and shared APIs. There are also many built-in Api extensions provided by the framework that you are able to override. + +### Component - [Reference](../../reference/frontend-plugin-api.createcomponentextension.md) + +Components extensions are used to override the component associated with a component reference throughout the app. + +### NavItem - [Reference](../../reference/frontend-plugin-api.createnavitemextension.md) + +Navigation item extensions are used to provide menu items that link to different parts of the app. By default nav items are attached to the app nav extension, which by default is rendered as the left sidebar in the app. + +### Page - [Reference](../../reference/frontend-plugin-api.createpageextension.md) + +Page extensions provide content for a particular route in the app. By default pages are attached to the app routes extensions, which renders the root routes. + +### SignInPage - [Reference](../../reference/frontend-plugin-api.createsigninpageextension.md) + +Sign-in page extension have a single purpose - to implement a custom sign-in page. They are always attached to the app root extension and are rendered before the rest of the app until the user is signed in. + +### Theme - [Reference](../../reference/frontend-plugin-api.createthemeextension.md) + +Theme extensions provide custom themes for the app. They are always attached to the app extension and you can have any number of themes extensions installed in an app at once, letting the user choose which theme to use. + +### Translation - [Reference](../../reference/frontend-plugin-api.createtranslationextension.md) + +Translation extension provide custom translation messages for the app. They can be used both to override the default english messages to custom ones, as well as provide translations for additional languages. diff --git a/microsite/sidebars.json b/microsite/sidebars.json index c34598376f..234afd78d6 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -413,7 +413,8 @@ "label": "Building Plugins", "items": [ "frontend-system/building-plugins/index", - "frontend-system/building-plugins/testing" + "frontend-system/building-plugins/testing", + "frontend-system/building-plugins/extension-types" ] }, { From 894497677b81d1dc9cf65743189c315df3ea4486 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 9 Jan 2024 23:15:53 +0100 Subject: [PATCH 179/283] docs/frontend-system: add core feature extension types Signed-off-by: Patrik Oldsberg --- .../frontend-system/building-plugins/01-index.md | 2 ++ .../building-plugins/03-extension-types.md | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/docs/frontend-system/building-plugins/01-index.md b/docs/frontend-system/building-plugins/01-index.md index 730dd58156..80182126be 100644 --- a/docs/frontend-system/building-plugins/01-index.md +++ b/docs/frontend-system/building-plugins/01-index.md @@ -199,3 +199,5 @@ const exampleEntityContent = createEntityContentExtension({ ``` The `ExampleEntityContent` itself is again a regular React component where you can implement any functionality you want. To access the entity that the content is being rendered for, you can use the `useEntity` hook from `@backstage/plugin-catalog-react`. You can see a full list of API provided by the catalog React library in [the API reference](../../reference/plugin-catalog-react.md). + +For a more complete list of the different types of extensions that you can create for your plugin, see the [extension types](./03-extension-types.md) section. diff --git a/docs/frontend-system/building-plugins/03-extension-types.md b/docs/frontend-system/building-plugins/03-extension-types.md index 36eda55112..1d59c60545 100644 --- a/docs/frontend-system/building-plugins/03-extension-types.md +++ b/docs/frontend-system/building-plugins/03-extension-types.md @@ -41,3 +41,19 @@ Theme extensions provide custom themes for the app. They are always attached to ### Translation - [Reference](../../reference/frontend-plugin-api.createtranslationextension.md) Translation extension provide custom translation messages for the app. They can be used both to override the default english messages to custom ones, as well as provide translations for additional languages. + +## Core feature extension types + +These are the extension types provided by the Backstage core feature plugins. + +### EntityCard - [Reference](../../reference/plugin-catalog-react.createentitycardextension.md) + +Creates entity cards to be displayed on the entity pages of the catalog plugin. + +### EntityContent - [Reference](../../reference/plugin-catalog-react.createentitycontentextension.md) + +Creates entity content to be displayed on the entity pages of the catalog plugin. + +### SearchResultListItem - [Reference](../../reference/plugin-search-react.createsearchresultlistitemextension.md) + +Creates search result list items for different types of search results, to be displayed in search result lists. From 22940cb56165167d63f06b5dd98a8ab0a53de9d1 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 12 Jan 2024 10:30:18 +0100 Subject: [PATCH 180/283] docs/frontend-system: update extension type links to use alpha API report Signed-off-by: Patrik Oldsberg --- docs/frontend-system/building-plugins/03-extension-types.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/frontend-system/building-plugins/03-extension-types.md b/docs/frontend-system/building-plugins/03-extension-types.md index 1d59c60545..1db99a78b9 100644 --- a/docs/frontend-system/building-plugins/03-extension-types.md +++ b/docs/frontend-system/building-plugins/03-extension-types.md @@ -46,14 +46,14 @@ Translation extension provide custom translation messages for the app. They can These are the extension types provided by the Backstage core feature plugins. -### EntityCard - [Reference](../../reference/plugin-catalog-react.createentitycardextension.md) +### EntityCard - [Reference](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/api-report-alpha.md) Creates entity cards to be displayed on the entity pages of the catalog plugin. -### EntityContent - [Reference](../../reference/plugin-catalog-react.createentitycontentextension.md) +### EntityContent - [Reference](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/api-report-alpha.md) Creates entity content to be displayed on the entity pages of the catalog plugin. -### SearchResultListItem - [Reference](../../reference/plugin-search-react.createsearchresultlistitemextension.md) +### SearchResultListItem - [Reference](https://github.com/backstage/backstage/blob/master/plugins/search-react/api-report-alpha.md) Creates search result list items for different types of search results, to be displayed in search result lists. From f26024be00a7d34c03973f97007d79e11c56a6f0 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 12 Jan 2024 14:17:38 +0100 Subject: [PATCH 181/283] docs/frontend-system: plugin index vale fixes Signed-off-by: Patrik Oldsberg --- docs/frontend-system/building-plugins/01-index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/frontend-system/building-plugins/01-index.md b/docs/frontend-system/building-plugins/01-index.md index 80182126be..afdc9546dd 100644 --- a/docs/frontend-system/building-plugins/01-index.md +++ b/docs/frontend-system/building-plugins/01-index.md @@ -41,11 +41,11 @@ export { examplePlugin as default } from './plugin'; Note that we export the plugin as the default export of our package from `src/index.ts`. This is important, as it is how users of our plugin are able to seamlessly install the plugin package in a Backstage app without having to reference the plugin instance through code. -The plugin ID should be a lowercase dash-separated string, while the plugin instance variable should be the camelCase version of the ID with a `Plugin` suffix. For more details on naming patterns within the frontend system, see [the article on naming patterns](../architecture/08-naming-patterns.md). By sticking to these naming patterns you ensure that users of your plugin more easily recognize the exports and features provided by your plugin. +The plugin ID should be a lowercase dash-separated string, while the plugin instance variable should be the camel case version of the ID with a `Plugin` suffix. For more details on naming patterns within the frontend system, see [the article on naming patterns](../architecture/08-naming-patterns.md). By sticking to these naming patterns you ensure that users of your plugin more easily recognize the exports and features provided by your plugin. ## Adding extensions -The plugin that we created above is empty, and does't provide any actual functionality. To add functionality to a plugin you need to create and provide it with one or more [extensions](../architecture/03-extensions.md). Let's continue by adding a standalone page to our plugin, as well as a navigation item that allows users to navigate to the page. +The plugin that we created above is empty, and doesn't provide any actual functionality. To add functionality to a plugin you need to create and provide it with one or more [extensions](../architecture/03-extensions.md). Let's continue by adding a standalone page to our plugin, as well as a navigation item that allows users to navigate to the page. To create a new extension you typically use pre-defined [extension creators](../architecture/03-extensions.md#extension-creators), provided either by the framework itself or by other plugins. In this case we'll need to use `createPageExtension` and `createNavItemExtension`, both from `@backstage/frontend-plugin-api`. We will also need to [create a route reference](../architecture/07-routes.md#creating-a-route-reference) to use as a reference for out page, allowing us to dynamically create URLs that link to our page. From 9cab5ad7f069135aaa62449e197eebb92457d72d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:48:40 +0000 Subject: [PATCH 182/283] fix(deps): update dependency mini-css-extract-plugin to v2.7.7 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 41218e601c..e69b573700 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34022,13 +34022,13 @@ __metadata: linkType: hard "mini-css-extract-plugin@npm:^2.4.2": - version: 2.7.6 - resolution: "mini-css-extract-plugin@npm:2.7.6" + version: 2.7.7 + resolution: "mini-css-extract-plugin@npm:2.7.7" dependencies: schema-utils: ^4.0.0 peerDependencies: webpack: ^5.0.0 - checksum: be6f7cefc6275168eb0a6b8fe977083a18c743c9612c9f00e6c1a62c3393ca7960e93fba1a7ebb09b75f36a0204ad087d772c1ef574bc29c90c0e8175a3c0b83 + checksum: 04af0e7d8c1a4ff31c70ac2d0895837dae3d51cce3bfd90e3c1d90d50eef7de21778361a3064531df046d775d80b3bf056324dddea93831c7def2047c5aa8718 languageName: node linkType: hard From 28248998b0af56699a00bbb4c43e7ab97a56307a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 17 Jan 2024 17:28:25 +0100 Subject: [PATCH 183/283] docs/frontend-system: plugin building review fixes Signed-off-by: Patrik Oldsberg --- docs/frontend-system/building-plugins/01-index.md | 13 ++++++++----- .../building-plugins/03-extension-types.md | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/frontend-system/building-plugins/01-index.md b/docs/frontend-system/building-plugins/01-index.md index afdc9546dd..cb29b3518a 100644 --- a/docs/frontend-system/building-plugins/01-index.md +++ b/docs/frontend-system/building-plugins/01-index.md @@ -76,9 +76,10 @@ const examplePage = createPageExtension({ defaultPath: '/example', // Page extensions are always dynamically loaded using React.lazy(). - // [1] All of the functionality of this page is implemented in the + // All of the functionality of this page is implemented in the // ExamplePage component, which is a regular React component. - loader: () => import('./components/ExamplePage').then(m => m.ExamplePage), + // highlight-next-line + loader: () => import('./components/ExamplePage').then(m => ), }); // This nav item is provided to the app.nav extension, and will by default be rendered as a sidebar item @@ -92,16 +93,18 @@ const exampleNavItem = createNavItemExtension({ export const examplePlugin = createPlugin({ id: 'example', extensions: [examplePage, exampleNavItem], - // [2] We can also make routes available to other plugins. + // We can also make routes available to other plugins. + // highlight-start routes: { root: rootRouteRef, }, + // highlight-end }); ``` -What we've built here is a very common type of plugin. It's a top-level tool that provides a single page, along with a method for navigating to that page. The implementation of the page component at `[1]` can be arbitrarily complex, anything from a single simple information page, to a full-blown application with multiple sub-pages. +What we've built here is a very common type of plugin. It's a top-level tool that provides a single page, along with a method for navigating to that page. The implementation of the page component, in this case the highlighted `ExamplePage`, can be arbitrarily complex. It can be anything from a single simple information page, to a full-blown application with multiple sub-pages. -We have also made the route reference available to other plugins at `[2]`. This makes it possible for app integrators to bind an external link from a different plugin to our plugin page. You can read more about how this works in the [External Route References](../architecture/07-routes.md#external-route-references) section. +We have also provided external access to our route reference by passing it to the plugin `routes` option. This makes it possible for app integrators to bind an external link from a different plugin to our plugin page. You can read more about how this works in the [External Route References](../architecture/07-routes.md#external-router-references) section. ## Utility APIs diff --git a/docs/frontend-system/building-plugins/03-extension-types.md b/docs/frontend-system/building-plugins/03-extension-types.md index 1db99a78b9..2bea073ed6 100644 --- a/docs/frontend-system/building-plugins/03-extension-types.md +++ b/docs/frontend-system/building-plugins/03-extension-types.md @@ -1,5 +1,5 @@ --- -id: index +id: extension-types title: Frontend System Extension Types sidebar_label: Extension Types # prettier-ignore From 2a0c08f4d992f584a3b78d32509c18cad49c8f4f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 16:36:13 +0000 Subject: [PATCH 184/283] fix(deps): update dependency react-use to v17.4.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 41218e601c..ebe16e1906 100644 --- a/yarn.lock +++ b/yarn.lock @@ -38716,8 +38716,8 @@ __metadata: linkType: hard "react-use@npm:^17.2.4, react-use@npm:^17.3.1, react-use@npm:^17.3.2, react-use@npm:^17.4.0": - version: 17.4.2 - resolution: "react-use@npm:17.4.2" + version: 17.4.3 + resolution: "react-use@npm:17.4.3" dependencies: "@types/js-cookie": ^2.2.6 "@xobotyi/scrollbar-width": ^1.9.5 @@ -38736,7 +38736,7 @@ __metadata: peerDependencies: react: "*" react-dom: "*" - checksum: 1b15add951a80eee637045e5e769dd565edde47838da3d8d0e9a4a2cfd547eb59626b5c5b020ba3c067c01356d2042c5948c534a90729114a7fc7d1e18763d0c + checksum: efa54c795ca900902022096c4c87b2a8c2290fe1748f3b2bf4d31ad40bfa35c1520f67e3da5f0a227a6429256df7bca251d9323487652debc924de5208a9cedd languageName: node linkType: hard From d4ef6e7a0116840c66187b3da4df9bd24126bc62 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 16:36:52 +0000 Subject: [PATCH 185/283] fix(deps): update dependency react-virtualized-auto-sizer to v1.0.21 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index 41218e601c..1041c132a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18668,11 +18668,11 @@ __metadata: linkType: hard "@types/react-virtualized-auto-sizer@npm:^1.0.1": - version: 1.0.3 - resolution: "@types/react-virtualized-auto-sizer@npm:1.0.3" + version: 1.0.4 + resolution: "@types/react-virtualized-auto-sizer@npm:1.0.4" dependencies: "@types/react": "*" - checksum: 7fcc516241903b937481b567a560c75cd23d27e63222938db725972d93cde0c07f846f98e104c78edcaa765608be156a9d08cf24e2261a3e11463b11343d964c + checksum: e0d41ac6cf0f48dfef45c0cd70146578f42ad83dad90911aa0dfe72b0e1ea62ca9ff56d4f43f322ec6dae2e7cb4d025aefe0e85241f7782c249aeface1050512 languageName: node linkType: hard @@ -38741,12 +38741,12 @@ __metadata: linkType: hard "react-virtualized-auto-sizer@npm:^1.0.11, react-virtualized-auto-sizer@npm:^1.0.6": - version: 1.0.20 - resolution: "react-virtualized-auto-sizer@npm:1.0.20" + version: 1.0.21 + resolution: "react-virtualized-auto-sizer@npm:1.0.21" peerDependencies: - react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc - react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc - checksum: 2c616ec7587de64a46aa8c6c301e75fee87eb7a39013f25d940b0fe95eee5e8a8a3c109923e241b427752d71fba80f44cd2c8557750967df0777d99ebd16ba24 + react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 + react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 + checksum: 9c0929a0363b3b3b10ad65ac57d7562a20966a9c38c28c10dfd296d0a6a3e678319dce2384c5177f43965c2b7f226f5766deffc4b7eaaab0ee7c2cfe0c7d6b48 languageName: node linkType: hard From e2fd9f3d1a71a3ac130ead4c94a3d083f90d7495 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 17:27:48 +0000 Subject: [PATCH 186/283] fix(deps): update dependency recharts to v2.10.4 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 41218e601c..c7ebe2dfce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -38946,8 +38946,8 @@ __metadata: linkType: hard "recharts@npm:^2.5.0": - version: 2.10.3 - resolution: "recharts@npm:2.10.3" + version: 2.10.4 + resolution: "recharts@npm:2.10.4" dependencies: clsx: ^2.0.0 eventemitter3: ^4.0.1 @@ -38961,7 +38961,7 @@ __metadata: prop-types: ^15.6.0 react: ^16.0.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 - checksum: 503c9fefa8648e0e8834a11ccc09fdcc310d391807438f4c0567b1888d7cd5f7a1f65f020afb981ec54ad6f96d31ebe757ab9025e93782edabc5c741f1aa946a + checksum: f283a21367aa675af83ada6d92ebd7bfa8931ba805bba34ee6247f74cba1b5d37c5fd48d20baa3533bbd3f0a98a1566e5d3733d23825caee8b256dd66ae5ff2c languageName: node linkType: hard From 9e7418aaaea501b52ad055b35d8a56665288ec6f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 17:28:25 +0000 Subject: [PATCH 187/283] fix(deps): update dependency style-loader to v3.3.4 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 41218e601c..4cd293ec8c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -41518,11 +41518,11 @@ __metadata: linkType: hard "style-loader@npm:^3.3.1": - version: 3.3.3 - resolution: "style-loader@npm:3.3.3" + version: 3.3.4 + resolution: "style-loader@npm:3.3.4" peerDependencies: webpack: ^5.0.0 - checksum: f59c953f56f6a935bd6a1dfa409f1128fed2b66b48ce4a7a75b85862a7156e5e90ab163878962762f528ec4d510903d828da645e143fbffd26f055dc1c094078 + checksum: caac3f2fe2c3c89e49b7a2a9329e1cfa515ecf5f36b9c4885f9b218019fda207a9029939b2c35821dec177a264a007e7c391ccdd3ff7401881ce6287b9c8f38b languageName: node linkType: hard From 846a8ef59c5931291f7e6c5d4fb1df39df1aab34 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 18:31:53 +0000 Subject: [PATCH 188/283] fix(deps): update material-ui monorepo to v5.15.5 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 184 +++++++++++++++++++++++++++--------------------------- 1 file changed, 92 insertions(+), 92 deletions(-) diff --git a/yarn.lock b/yarn.lock index 41218e601c..b495a65a3b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3119,12 +3119,12 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.1, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.20.6, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.6, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.4.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.0, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": - version: 7.23.6 - resolution: "@babel/runtime@npm:7.23.6" +"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.1, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.20.6, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.8, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.4.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.0, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": + version: 7.23.8 + resolution: "@babel/runtime@npm:7.23.8" dependencies: regenerator-runtime: ^0.14.0 - checksum: 1a8eaf3d3a103ef5227b60ca7ab5c589118c36ca65ef2d64e65380b32a98a3f3b5b3ef96660fa0471b079a18b619a8317f3e7f03ab2b930c45282a8b69ed9a16 + checksum: 0bd5543c26811153822a9f382fd39886f66825ff2a397a19008011376533747cd05c33a91f6248c0b8b0edf0448d7c167ebfba34786088f1b7eb11c65be7dfc3 languageName: node linkType: hard @@ -10943,41 +10943,41 @@ __metadata: languageName: node linkType: hard -"@floating-ui/core@npm:^1.4.2": - version: 1.5.0 - resolution: "@floating-ui/core@npm:1.5.0" - dependencies: - "@floating-ui/utils": ^0.1.3 - checksum: 54b4fe26b3c228746ac5589f97303abf158b80aa5f8b99027259decd68d1c2030c4c637648ebd33dfe78a4212699453bc2bd7537fd5a594d3bd3e63d362f666f - languageName: node - linkType: hard - -"@floating-ui/dom@npm:^1.5.1": +"@floating-ui/core@npm:^1.5.3": version: 1.5.3 - resolution: "@floating-ui/dom@npm:1.5.3" + resolution: "@floating-ui/core@npm:1.5.3" dependencies: - "@floating-ui/core": ^1.4.2 - "@floating-ui/utils": ^0.1.3 - checksum: 00053742064aac70957f0bd5c1542caafb3bfe9716588bfe1d409fef72a67ed5e60450d08eb492a77f78c22ed1ce4f7955873cc72bf9f9caf2b0f43ae3561c21 + "@floating-ui/utils": ^0.2.0 + checksum: 72af8563e1742791acee82e86f82a0fbca7445809988d31eea3fd5771909463aa7655a6cb001cc244f8fe3a9de600420257e4dfb887ca33e2a31ac47b52e39a2 languageName: node linkType: hard -"@floating-ui/react-dom@npm:^2.0.0, @floating-ui/react-dom@npm:^2.0.4": - version: 2.0.4 - resolution: "@floating-ui/react-dom@npm:2.0.4" +"@floating-ui/dom@npm:^1.5.4": + version: 1.5.4 + resolution: "@floating-ui/dom@npm:1.5.4" dependencies: - "@floating-ui/dom": ^1.5.1 + "@floating-ui/core": ^1.5.3 + "@floating-ui/utils": ^0.2.0 + checksum: 5e6f05532ff4e6daf9f2d91534184d8f942ddb8fd260c2543a49bdf0c0ff69fd0867937ce1d023126008724ac238f8fc89b5e48f82cdf9f8355a1d04edd085bd + languageName: node + linkType: hard + +"@floating-ui/react-dom@npm:^2.0.0, @floating-ui/react-dom@npm:^2.0.5": + version: 2.0.6 + resolution: "@floating-ui/react-dom@npm:2.0.6" + dependencies: + "@floating-ui/dom": ^1.5.4 peerDependencies: react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: 91b2369e25f84888486e48c1656117468248906034ed482d411bb9ed1061b908dd32435b4ca3d0cd0ca6083291510a98ce74d76c671d5cc25b0c41e5fa824bae + checksum: 3608537be6cae5f0442d3f826379b8e4a9ce5c4bdecf1d2b34e6709842d80444be1a00eca3641d680e2e6405d833092f58005d1b120a9d39ffd341c60b0c017c languageName: node linkType: hard -"@floating-ui/utils@npm:^0.1.3": - version: 0.1.4 - resolution: "@floating-ui/utils@npm:0.1.4" - checksum: e6195ded5b3a6fd38411a833605184c31f24609b08feab2615e90ccc063bf4d3965383d817642fc7e8ca5ab6a54c29c71103e874f3afb0518595c8bd3390ba16 +"@floating-ui/utils@npm:^0.2.0": + version: 0.2.1 + resolution: "@floating-ui/utils@npm:0.2.1" + checksum: 9ed4380653c7c217cd6f66ae51f20fdce433730dbc77f95b5abfb5a808f5fdb029c6ae249b4e0490a816f2453aa6e586d9a873cd157fdba4690f65628efc6e06 languageName: node linkType: hard @@ -12762,16 +12762,16 @@ __metadata: languageName: node linkType: hard -"@mui/base@npm:5.0.0-beta.29": - version: 5.0.0-beta.29 - resolution: "@mui/base@npm:5.0.0-beta.29" +"@mui/base@npm:5.0.0-beta.32": + version: 5.0.0-beta.32 + resolution: "@mui/base@npm:5.0.0-beta.32" dependencies: - "@babel/runtime": ^7.23.6 - "@floating-ui/react-dom": ^2.0.4 - "@mui/types": ^7.2.11 - "@mui/utils": ^5.15.2 + "@babel/runtime": ^7.23.8 + "@floating-ui/react-dom": ^2.0.5 + "@mui/types": ^7.2.13 + "@mui/utils": ^5.15.5 "@popperjs/core": ^2.11.8 - clsx: ^2.0.0 + clsx: ^2.1.0 prop-types: ^15.8.1 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -12780,29 +12780,29 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 40481f18d5b4c560e0f9868876727203af76954b5b8b208bfc01da666229f8eef45852b5d87403aa42b4c8515a5b9d2e99d4ae40446289d7456c56310fce72c7 + checksum: 5f27be8914c072ffcbe6720de9aa6129180e68927657e8bcbc03a6f322d1ee6c6740a199d72ed0b490a7b29b79cc0c59d1e05a427089b17f4cbc9cc756e67506 languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.15.2": - version: 5.15.2 - resolution: "@mui/core-downloads-tracker@npm:5.15.2" - checksum: 8c88ac73a1d87c8ce565f6295dcd084c643580848e8f59159402e9db89975263da06305a0e605d3744479e917c2d297319496534bca9df8338e203162f1e7c33 +"@mui/core-downloads-tracker@npm:^5.15.5": + version: 5.15.5 + resolution: "@mui/core-downloads-tracker@npm:5.15.5" + checksum: 4c9b1281ebe8d17d402e22f7f50c347c0b3918b1ed17af721f4de5ce282d90bc6d90fe9730595998b2bbb2f7ebe57fc55d4c858f31754fccdb606af472a59dc8 languageName: node linkType: hard "@mui/material@npm:^5.12.2": - version: 5.15.2 - resolution: "@mui/material@npm:5.15.2" + version: 5.15.5 + resolution: "@mui/material@npm:5.15.5" dependencies: - "@babel/runtime": ^7.23.6 - "@mui/base": 5.0.0-beta.29 - "@mui/core-downloads-tracker": ^5.15.2 - "@mui/system": ^5.15.2 - "@mui/types": ^7.2.11 - "@mui/utils": ^5.15.2 + "@babel/runtime": ^7.23.8 + "@mui/base": 5.0.0-beta.32 + "@mui/core-downloads-tracker": ^5.15.5 + "@mui/system": ^5.15.5 + "@mui/types": ^7.2.13 + "@mui/utils": ^5.15.5 "@types/react-transition-group": ^4.4.10 - clsx: ^2.0.0 + clsx: ^2.1.0 csstype: ^3.1.2 prop-types: ^15.8.1 react-is: ^18.2.0 @@ -12820,16 +12820,16 @@ __metadata: optional: true "@types/react": optional: true - checksum: 7586b0160c686214c4d3a6f8af76306413bfe13286a4679ca7696b764615f511b5d5b27a8129e15ae81856492317e7f139f4bd075f6b2dfe6e60de46755d7dbc + checksum: dbfcb31810c674d9ab3b9145752433de3917d9c0d1b491bdff84c44b8f1124e8fe8ab04fa09b974b497983b7bd3011b86fb441ad365f979f971d3ddb46712060 languageName: node linkType: hard -"@mui/private-theming@npm:^5.15.2": - version: 5.15.2 - resolution: "@mui/private-theming@npm:5.15.2" +"@mui/private-theming@npm:^5.15.5": + version: 5.15.5 + resolution: "@mui/private-theming@npm:5.15.5" dependencies: - "@babel/runtime": ^7.23.6 - "@mui/utils": ^5.15.2 + "@babel/runtime": ^7.23.8 + "@mui/utils": ^5.15.5 prop-types: ^15.8.1 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -12837,15 +12837,15 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 63cc69adc3eca03533dd72296aac6449abe133522f6f5c62c8497e57dbd092c131cba3488ee8d97dfb76c31a194df014f4da3b2d30027614e987ed72581a4acf + checksum: 3a5f7f190aa69a0ad69a34f77e54ee2fdcb088d21a61d4720b76d098d178e1c3f6a470fc5e7a30d351db10efbc062cb11af75b8789e2f38eaa2ca612bcb0f851 languageName: node linkType: hard -"@mui/styled-engine@npm:^5.15.2": - version: 5.15.2 - resolution: "@mui/styled-engine@npm:5.15.2" +"@mui/styled-engine@npm:^5.15.5": + version: 5.15.5 + resolution: "@mui/styled-engine@npm:5.15.5" dependencies: - "@babel/runtime": ^7.23.6 + "@babel/runtime": ^7.23.8 "@emotion/cache": ^11.11.0 csstype: ^3.1.2 prop-types: ^15.8.1 @@ -12858,20 +12858,20 @@ __metadata: optional: true "@emotion/styled": optional: true - checksum: daa15b61be2e785c9719e091047a5900aa5aa0b6a9dfbc2ea373f6718f6ec3485f44e05596cd9506a90a7c55d8d372233a80cbeca4d81ceb8d5e6a10ce0f8292 + checksum: 42bb7f50ed33ec88f799bd90a00337689837ee0b2d603681fe69c9a14850e5ae1d037505365ce78cd564307cc2c0654c46cece8d9250adb21c77b1de316e3c45 languageName: node linkType: hard "@mui/styles@npm:^5.14.18": - version: 5.15.2 - resolution: "@mui/styles@npm:5.15.2" + version: 5.15.5 + resolution: "@mui/styles@npm:5.15.5" dependencies: - "@babel/runtime": ^7.23.6 + "@babel/runtime": ^7.23.8 "@emotion/hash": ^0.9.1 - "@mui/private-theming": ^5.15.2 - "@mui/types": ^7.2.11 - "@mui/utils": ^5.15.2 - clsx: ^2.0.0 + "@mui/private-theming": ^5.15.5 + "@mui/types": ^7.2.13 + "@mui/utils": ^5.15.5 + clsx: ^2.1.0 csstype: ^3.1.2 hoist-non-react-statics: ^3.3.2 jss: ^10.10.0 @@ -12889,20 +12889,20 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 53ee6fb6c1114469dfeacbf5d26fc6ef7bc897428258301515012fcea95f5abcc73d5b70d1ea1da9382f7742aa7da7a9749a7594331e78f85b6b4cd8f8216d11 + checksum: dc131c0e7763f7ac4fd96a1db3dd85abf59de5429a73f7cf9ed15d423fb9bb5883835c1951d36e8804da9ab2ed13d603ed349f12e7cd15885f8279d90d13511b languageName: node linkType: hard -"@mui/system@npm:^5.15.2": - version: 5.15.2 - resolution: "@mui/system@npm:5.15.2" +"@mui/system@npm:^5.15.5": + version: 5.15.5 + resolution: "@mui/system@npm:5.15.5" dependencies: - "@babel/runtime": ^7.23.6 - "@mui/private-theming": ^5.15.2 - "@mui/styled-engine": ^5.15.2 - "@mui/types": ^7.2.11 - "@mui/utils": ^5.15.2 - clsx: ^2.0.0 + "@babel/runtime": ^7.23.8 + "@mui/private-theming": ^5.15.5 + "@mui/styled-engine": ^5.15.5 + "@mui/types": ^7.2.13 + "@mui/utils": ^5.15.5 + clsx: ^2.1.0 csstype: ^3.1.2 prop-types: ^15.8.1 peerDependencies: @@ -12917,27 +12917,27 @@ __metadata: optional: true "@types/react": optional: true - checksum: ce6297a4cfa6f91891fa84679e05e40e12c4a27fe4fb34d78cbcbae172da293c05fa6f07c24fec66c864eac64179aeec1f7a70358e376b8c16ffc8e91f93a904 + checksum: 3f736f120d65fa14588cd7554a9ef63c9d4480716807d7ee5543b9f25d936b5ac0396a51a565c53b2905114fed5f94880c896f091e8d269260bfc53e8a8e2fb5 languageName: node linkType: hard -"@mui/types@npm:^7.2.11": - version: 7.2.11 - resolution: "@mui/types@npm:7.2.11" +"@mui/types@npm:^7.2.13": + version: 7.2.13 + resolution: "@mui/types@npm:7.2.13" peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: ce6bbe8ba963af218bf86797f4c8adbf0f294047adeaf6596d3bb4a96f1b01701f1b1ae7dcfe2f7972f6e23c85eee4187e496fb481541713ed8bf12e96f3c34f + checksum: 58dfc96f9654288519ff01d6b54e6a242f05cadad51210deb85710a81be4fa1501a116c8968e2614b16c748fc1f407dc23beeeeae70fa37fceb6c6de876ff70d languageName: node linkType: hard -"@mui/utils@npm:^5.14.15, @mui/utils@npm:^5.15.2": - version: 5.15.2 - resolution: "@mui/utils@npm:5.15.2" +"@mui/utils@npm:^5.14.15, @mui/utils@npm:^5.15.5": + version: 5.15.5 + resolution: "@mui/utils@npm:5.15.5" dependencies: - "@babel/runtime": ^7.23.6 + "@babel/runtime": ^7.23.8 "@types/prop-types": ^15.7.11 prop-types: ^15.8.1 react-is: ^18.2.0 @@ -12947,7 +12947,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: c78ad9fb1a5fa1dc5955cada77227c605f1e5bf45503bf2bb0080bc92cf28bdcf1cbb83322d19162c5424ec245a66cef849603c7681fa1ec89093e0b1922dc58 + checksum: fe71ce69e23cb4c00886138da1422e4baa66959cd10f97b2aa00f7324a038b13084ea4a0da123774c0018f48ddb6ce4f3cb20a915ec3c5c1ff5495bf337f665f languageName: node linkType: hard @@ -22475,10 +22475,10 @@ __metadata: languageName: node linkType: hard -"clsx@npm:^2.0.0": - version: 2.0.0 - resolution: "clsx@npm:2.0.0" - checksum: a2cfb2351b254611acf92faa0daf15220f4cd648bdf96ce369d729813b85336993871a4bf6978ddea2b81b5a130478339c20d9d0b5c6fc287e5147f0c059276e +"clsx@npm:^2.0.0, clsx@npm:^2.1.0": + version: 2.1.0 + resolution: "clsx@npm:2.1.0" + checksum: 43fefc29b6b49c9476fbce4f8b1cc75c27b67747738e598e6651dd40d63692135dc60b18fa1c5b78a2a9ba8ae6fd2055a068924b94e20b42039bd53b78b98e1d languageName: node linkType: hard From 8e2043b27862dec1a63dd390a6e0adb0c8a069e6 Mon Sep 17 00:00:00 2001 From: armandocomellas1 Date: Wed, 17 Jan 2024 12:57:57 -0600 Subject: [PATCH 189/283] Updated with the new paramter in line 84 with the new paramter authProvider in the config schema Signed-off-by: armandocomellas1 --- plugins/kubernetes-backend/config.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/kubernetes-backend/config.d.ts b/plugins/kubernetes-backend/config.d.ts index e9b5878920..50b0e382b5 100644 --- a/plugins/kubernetes-backend/config.d.ts +++ b/plugins/kubernetes-backend/config.d.ts @@ -81,6 +81,8 @@ export interface Config { /** @visibility frontend */ region?: string; /** @visibility frontend */ + authProvider?: string; + /** @visibility frontend */ skipTLSVerify?: boolean; /** @visibility frontend */ skipMetricsLookup?: boolean; From 63617ad9e162a539db249dce3407d22d1b1a1558 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 17 Jan 2024 20:52:41 +0100 Subject: [PATCH 190/283] docs/tutorials: add migration guide for React 18 Signed-off-by: Patrik Oldsberg --- docs/tutorials/react18-migration.md | 106 ++++++++++++++++++++++++++++ microsite/sidebars.json | 1 + 2 files changed, 107 insertions(+) create mode 100644 docs/tutorials/react18-migration.md diff --git a/docs/tutorials/react18-migration.md b/docs/tutorials/react18-migration.md new file mode 100644 index 0000000000..deb8518550 --- /dev/null +++ b/docs/tutorials/react18-migration.md @@ -0,0 +1,106 @@ +--- +id: react18-migration +title: Migrating to React 18 +description: Additional resources for the Material UI v5 migration guide specifically for Backstage +--- + +The Backstage core libraries and plugins are compatible with all versions of React from v16.8 to v18. This means that you can migrate projects at your own pace. We do however encourage you to do so sooner rather than later, both to keep up with the evolving ecosystem, but also because React 18 brings performance improvements, in particular in tests. + +## Migration + +_Before diving in, this is a heads-up that for large projects this can be a tricky migration due to the fact that it is hard to break down into a gradual migration. In practice the difficult part of this migration is switching to the new version of the `@testing-library/react` package for tests, since there is no overlapping support across major React versions, more on that later._ + +### Switching to React 18 + +To switch a project to React 18, there are generally three changes that need to be made. + +1. Update the resolutions in your root `package.json` to the new versions of `@types/react` and `@types/react-dom`: + +```json title="package.json" + "resolutions": { + // highlight-remove-next-line + "@types/react": "^17", + // highlight-remove-next-line + "@types/react": "^17", + // highlight-add-next-line + "@types/react-dom": "^18", + // highlight-add-next-line + "@types/react-dom": "^18", + }, +``` + +2. Update the `react` and `react-dom` dependencies in your `packages/app/package.json` to the new versions: + +```json title="packages/app/package.json" + "dependencies": { + ... + // highlight-remove-next-line + "react": "^17.0.2", + // highlight-remove-next-line + "react-dom": "^17.0.2", + // highlight-add-next-line + "react": "^18.0.2", + // highlight-add-next-line + "react-dom": "^18.0.2", + ... + }, +``` + +3. Update `packages/app/src/index.tsx` to use the new `react-dom/client` API to render the app: + +```tsx title="packages/app/src/index.tsx" +import '@backstage/cli/asset-types'; +import React from 'react'; +// highlight-remove-next-line +import ReactDOM from 'react-dom'; +// highlight-add-next-line +import ReactDOM from 'react-dom/client'; +import App from './App'; + +// highlight-remove-next-line +ReactDOM.render(, document.getElementById('root')); +// highlight-add-next-line +ReactDOM.createRoot(document.getElementById('root')!).render(); +``` + +Once these steps are done you should be able to run your app and see it working as before, except now using React 18. + +### Migrating Tests + +At this point the app hopefully works, but if you run your tests you may see that a lot of them are failing. This is because the current version of the `@testing-library/react` package does not support React 18. Unfortunately the new version that we will be moving to does not support React 17, which is why we need to do this all at once. + +:::info +If migrating your entire project at once is not feasible, you can try to add `devDependencies` for `react` and `react-dom` v17 to individual plugins to be migrated later. This is not something we have tried ourselves in practice, so let us know in the community Discord if you attempt this and how it goes. +::: + +#### Dependency Upgrades + +To get the tests working again we need to update `@testing-library/react` to at least v13, although while at it is sensible to move at least all the way to v14 since the additional breaking changes have low impact. For more information on the changes in v13, see the [release notes](https://github.com/testing-library/react-testing-library/releases/tag/v13.0.0). + +In addition to bumping `@testing-library/react` you also need to remove the `@testing-library/react-hooks` package, since it is now included in `@testing-library/react` itself. You can find more information on this change in the `@testing-library/react-hooks` [README.md](https://github.com/testing-library/react-hooks-testing-library?tab=readme-ov-file#a-note-about-react-18-support). + +The following search-and-replace RegEx patterns may by helpful in updating your `package.json` files: + +Find: `"@testing-library/react": ".*"`
+Replace: `"@testing-library/react": "^14.0.0"` + +Find: `"@testing-library/react-hooks": ".*",?`
+Replace: `` + +#### Test Updates + +Once you have installed the new versions of the dependencies this turns into a fairly mechanical process of updating the tests. Use your own favorite method for this, running all tests once to find the breakages and then focusing on one test file at a time was fairly smooth. + +When updating the tests in the Backstage project we found the following patterns to be useful: + +- Many existing `act(...)` calls can be removed, it is built into most testing utilities like `waitFor`, `.findBy*`, and `@testing-library/user-event`. +- Use `.findBy*` to wait for elements to appear. +- Use `waitFor(...)` to wait for any other expected state changes or multiple elements. +- Use `@testing-library/user-event` for user interactions. +- `renderHook` no longer forwards initial props to `wrapper`, they may need to be moved to a wrapper for the `wrapper` instead. +- Waiting for mock functions to be called by a component and then expecting render state to be updated is no longer reliable. +- Rendered components often don't immediately update on user input, it's more common to need to use `waitFor` or other utilities to wait for the expected state to be reached. + +You can also refer to the test changes in this [PR](https://github.com/backstage/backstage/pull/20598/files?file-filters%5B%5D=.ts&file-filters%5B%5D=.tsx), which was the migration to React 18 for the Backstage project itself. + +Best of luck! For question please join the [community Discord](https://discord.gg/backstage-687207715902193673). If you think this documentation could be improved we welcome you to [open an issue](https://github.com/backstage/backstage/issues/new/choose) or submit a pull request. diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 234afd78d6..187c41ad75 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -452,6 +452,7 @@ "tutorials/journey", "tutorials/quickstart-app-plugin", "tutorials/react-router-stable-migration", + "tutorials/react18-migration", "tutorials/package-role-migration", "tutorials/migrating-away-from-core", "tutorials/configuring-plugin-databases", From c043396c27ce869185a06d287065213be628cb48 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 17 Jan 2024 21:27:08 +0100 Subject: [PATCH 191/283] e2e-test: removed outdated unhandled rejection handler that would ignore errors Signed-off-by: Patrik Oldsberg --- packages/e2e-test/src/index.ts | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/packages/e2e-test/src/index.ts b/packages/e2e-test/src/index.ts index 92adc24b1e..f3c63ae175 100644 --- a/packages/e2e-test/src/index.ts +++ b/packages/e2e-test/src/index.ts @@ -36,23 +36,4 @@ async function main(argv: string[]) { program.parse(argv); } -process.on('unhandledRejection', (rejection: unknown) => { - // Try to avoid exiting if the unhandled error is coming from jsdom, i.e. zombie. - // Those are typically errors on the page that should be benign, at least in the - // context of this test. We have other ways of asserting that the page is being - // rendered correctly. - if ( - rejection instanceof Error && - rejection?.stack?.includes('node_modules/jsdom/lib') - ) { - console.log(`Ignored error inside jsdom, ${rejection?.stack ?? rejection}`); - } else { - if (rejection instanceof Error) { - exitWithError(rejection); - } else { - exitWithError(new Error(`Unknown rejection: '${rejection}'`)); - } - } -}); - main(process.argv).catch(exitWithError); From aeec29caf07e96f947049bb698ad5c3f4f42900e Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 17 Jan 2024 20:53:19 +0100 Subject: [PATCH 192/283] create-app: migrate to React 18 Signed-off-by: Patrik Oldsberg --- .changeset/sour-rivers-fry.md | 9 +++++++++ packages/app/src/App.test.tsx | 9 ++++++--- .../create-app/templates/default-app/package.json.hbs | 4 ++-- .../default-app/packages/app/package.json.hbs | 10 +++++----- .../default-app/packages/app/src/App.test.tsx | 9 ++++++--- .../templates/default-app/packages/app/src/index.tsx | 4 ++-- 6 files changed, 30 insertions(+), 15 deletions(-) create mode 100644 .changeset/sour-rivers-fry.md diff --git a/.changeset/sour-rivers-fry.md b/.changeset/sour-rivers-fry.md new file mode 100644 index 0000000000..1b74850614 --- /dev/null +++ b/.changeset/sour-rivers-fry.md @@ -0,0 +1,9 @@ +--- +'@backstage/create-app': patch +--- + +Updated `packages/app` as well as the root `package.json` type resolutions to use React v18. + +The `@testing-library/*` dependencies have also been updated to the ones compatible with React v18, and the test at `packages/app/src/App.test.tsx` had been updated to use more modern patterns that work better with these new versions. + +For information on how to migrate existing apps to React v18, see the [migration guide](https://backstage.io/docs/tutorials/react18-migration) diff --git a/packages/app/src/App.test.tsx b/packages/app/src/App.test.tsx index 8c7cefeb2c..919a60e53d 100644 --- a/packages/app/src/App.test.tsx +++ b/packages/app/src/App.test.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { renderWithEffects } from '@backstage/test-utils'; +import { render, waitFor } from '@testing-library/react'; import App from './App'; describe('App', () => { @@ -42,7 +42,10 @@ describe('App', () => { ] as any, }; - const rendered = await renderWithEffects(); - expect(rendered.baseElement).toBeInTheDocument(); + const rendered = render(); + + await waitFor(() => { + expect(rendered.baseElement).toBeInTheDocument(); + }); }); }); diff --git a/packages/create-app/templates/default-app/package.json.hbs b/packages/create-app/templates/default-app/package.json.hbs index b74957dd56..40cc8282d9 100644 --- a/packages/create-app/templates/default-app/package.json.hbs +++ b/packages/create-app/templates/default-app/package.json.hbs @@ -42,8 +42,8 @@ "typescript": "~5.2.0" }, "resolutions": { - "@types/react": "^17", - "@types/react-dom": "^17" + "@types/react": "^18", + "@types/react-dom": "^18" }, "prettier": "@spotify/prettier-config", "lint-staged": { diff --git a/packages/create-app/templates/default-app/packages/app/package.json.hbs b/packages/create-app/templates/default-app/packages/app/package.json.hbs index 598f049a4c..b403295b09 100644 --- a/packages/create-app/templates/default-app/packages/app/package.json.hbs +++ b/packages/create-app/templates/default-app/packages/app/package.json.hbs @@ -42,8 +42,8 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "history": "^5.0.0", - "react": "^17.0.2", - "react-dom": "^17.0.2", + "react": "^18.0.2", + "react-dom": "^18.0.2", "react-router": "^6.3.0", "react-router-dom": "^6.3.0", "react-use": "^17.2.4" @@ -51,10 +51,10 @@ "devDependencies": { "@backstage/test-utils": "^{{version '@backstage/test-utils'}}", "@playwright/test": "^1.32.3", - "@testing-library/jest-dom": "^5.10.1", - "@testing-library/react": "^12.1.3", + "@testing-library/jest-dom": "^6.0.0", + "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.0.0", - "@testing-library/dom": "^8.0.0", + "@testing-library/dom": "^9.0.0", "@types/react-dom": "*", "cross-env": "^7.0.0" }, diff --git a/packages/create-app/templates/default-app/packages/app/src/App.test.tsx b/packages/create-app/templates/default-app/packages/app/src/App.test.tsx index b94cac73b3..ec8ba1d714 100644 --- a/packages/create-app/templates/default-app/packages/app/src/App.test.tsx +++ b/packages/create-app/templates/default-app/packages/app/src/App.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { renderWithEffects } from '@backstage/test-utils'; +import { render, waitFor } from '@testing-library/react'; import App from './App'; describe('App', () => { @@ -20,7 +20,10 @@ describe('App', () => { ] as any, }; - const rendered = await renderWithEffects(); - expect(rendered.baseElement).toBeInTheDocument(); + const rendered = render(); + + await waitFor(() => { + expect(rendered.baseElement).toBeInTheDocument(); + }); }); }); diff --git a/packages/create-app/templates/default-app/packages/app/src/index.tsx b/packages/create-app/templates/default-app/packages/app/src/index.tsx index b16aaf7cd2..d875c774c8 100644 --- a/packages/create-app/templates/default-app/packages/app/src/index.tsx +++ b/packages/create-app/templates/default-app/packages/app/src/index.tsx @@ -1,6 +1,6 @@ import '@backstage/cli/asset-types'; import React from 'react'; -import ReactDOM from 'react-dom'; +import ReactDOM from 'react-dom/client'; import App from './App'; -ReactDOM.render(, document.getElementById('root')); +ReactDOM.createRoot(document.getElementById('root')!).render(); From dc13f436197742e25807f4e59834f398778e8874 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 17 Jan 2024 22:19:50 +0100 Subject: [PATCH 193/283] docs/tutorials/react18: add type errors step Signed-off-by: Patrik Oldsberg --- docs/tutorials/react18-migration.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/tutorials/react18-migration.md b/docs/tutorials/react18-migration.md index deb8518550..a3412b5105 100644 --- a/docs/tutorials/react18-migration.md +++ b/docs/tutorials/react18-migration.md @@ -65,9 +65,17 @@ ReactDOM.createRoot(document.getElementById('root')!).render(); Once these steps are done you should be able to run your app and see it working as before, except now using React 18. +### TypeScript Errors + +When upgrading to React 18 you are likely to see a fair number of TypeScript type errors. A summary of the breaking changes can be found in the [Pull Request that introduced them](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/56210). A codemod is also provided to help with the migration. + +Run `yarn tsc:full` to asses the damage. + +The good news is that these errors can be fixed while still staying on React 17. If you have a large number of errors to fix you can address as few or many is you like at a time and merge them into your main branch **without** the version bumps from step 1. This lets you gradually migrate the types in your project while not yet fully moving over to React 18. Once all type breakages are fixed you can move on to the next step of migrating tests. + ### Migrating Tests -At this point the app hopefully works, but if you run your tests you may see that a lot of them are failing. This is because the current version of the `@testing-library/react` package does not support React 18. Unfortunately the new version that we will be moving to does not support React 17, which is why we need to do this all at once. +At this point the app hopefully works and you have no type errors, but if you run your tests you may see that a lot of them are failing. This is because the current version of the `@testing-library/react` package does not support React 18. Unfortunately the new version that we will be moving to does not support React 17, which is why we need to do this all at once. :::info If migrating your entire project at once is not feasible, you can try to add `devDependencies` for `react` and `react-dom` v17 to individual plugins to be migrated later. This is not something we have tried ourselves in practice, so let us know in the community Discord if you attempt this and how it goes. From 98d0ac461cc691d1aa05e835ed8c681bcfc8538e Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 17 Jan 2024 22:33:47 +0100 Subject: [PATCH 194/283] docs/tutorials/react18: some more details on how to migrate renderHook Signed-off-by: Patrik Oldsberg --- docs/tutorials/react18-migration.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/tutorials/react18-migration.md b/docs/tutorials/react18-migration.md index a3412b5105..2d3b3a961a 100644 --- a/docs/tutorials/react18-migration.md +++ b/docs/tutorials/react18-migration.md @@ -105,7 +105,10 @@ When updating the tests in the Backstage project we found the following patterns - Use `.findBy*` to wait for elements to appear. - Use `waitFor(...)` to wait for any other expected state changes or multiple elements. - Use `@testing-library/user-event` for user interactions. -- `renderHook` no longer forwards initial props to `wrapper`, they may need to be moved to a wrapper for the `wrapper` instead. +- The `renderHook` API has changes in several ways: + - It no longer returns `waitForValueToChange` or `waitForNextUpdate`, you'll likely want to use `waitFor` instead. + - It now throws errors rather than returns them as part of the result. + - It no longer forwards `initialProps` to the `wrapper`, a workaround for this is provided in the [docs](https://testing-library.com/docs/react-testing-library/api/#renderhook-options-initialprops). - Waiting for mock functions to be called by a component and then expecting render state to be updated is no longer reliable. - Rendered components often don't immediately update on user input, it's more common to need to use `waitFor` or other utilities to wait for the expected state to be reached. From 762809def515faf01f05fbe40faca5885a9efd29 Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Fri, 12 Jan 2024 10:50:07 -0500 Subject: [PATCH 195/283] clean up KubernetesBuilder tests * reduce whitespace * reduce duplication * simplify stubs (mostly using `mockResolvedValue`) * non-exhaustive attempt to ensure test backends get cleaned up Signed-off-by: Jamie Klassen --- .../src/service/KubernetesBuilder.test.ts | 453 +++++------------- 1 file changed, 125 insertions(+), 328 deletions(-) diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts index 5719a9392a..a35e488b50 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { Entity } from '@backstage/catalog-model'; import { ANNOTATION_KUBERNETES_AUTH_PROVIDER, ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER, @@ -24,10 +23,8 @@ import { import request from 'supertest'; import { ClusterDetails, - FetchResponseWrapper, KubernetesFetcher, KubernetesServiceLocator, - ObjectFetchParams, } from '../types/types'; import { KubernetesCredential } from '../auth/types'; import { @@ -64,95 +61,65 @@ describe('KubernetesBuilder', () => { let app: ExtendedHttpServer; let objectsProviderMock: KubernetesObjectsProvider; const happyK8SResult = { - items: [ - { - clusterOne: { - pods: [ - { - metadata: { - name: 'pod1', - }, - }, - ], - }, - }, - ], - } as any; - const policyMock: jest.Mocked = { - authorize: jest.fn(), - authorizeConditional: jest.fn(), + items: [{ clusterOne: { pods: [{ metadata: { name: 'pod1' } }] } }], }; const permissionsMock: ServiceMock = - mockServices.permissions.mock(policyMock); + mockServices.permissions.mock({ + authorize: jest.fn(), + authorizeConditional: jest.fn(), + }); + const minimalValidConfigService = mockServices.rootConfig.factory({ + data: { + kubernetes: { + serviceLocatorMethod: { type: 'multiTenant' }, + clusterLocatorMethods: [], + }, + }, + }); + const withClusters = (clusters: ClusterDetails[]) => + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testClusterSupplier', + register(env) { + env.registerInit({ + deps: { extension: kubernetesClusterSupplierExtensionPoint }, + async init({ extension }) { + extension.addClusterSupplier({ + getClusters: jest.fn().mockResolvedValue(clusters), + }); + }, + }); + }, + }); beforeEach(async () => { jest.resetAllMocks(); objectsProviderMock = { - getKubernetesObjectsByEntity: jest.fn().mockImplementation(_ => { - return Promise.resolve(happyK8SResult); - }), - getCustomResourcesByEntity: jest.fn().mockImplementation(_ => { - return Promise.resolve(happyK8SResult); - }), - }; - - const clusterSupplierMock = { - getClusters: jest.fn().mockImplementation(_ => { - return Promise.resolve([ - { - name: 'some-cluster', - url: 'https://localhost:1234', - authMetadata: { - [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount', - }, - }, - { - name: 'some-other-cluster', - url: 'https://localhost:1235', - authMetadata: { - [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'oidc', - [ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER]: 'google', - }, - }, - ]); - }), + getKubernetesObjectsByEntity: jest.fn().mockResolvedValue(happyK8SResult), + getCustomResourcesByEntity: jest.fn().mockResolvedValue(happyK8SResult), }; jest.mock('@backstage/catalog-client', () => ({ - CatalogClient: jest.fn().mockImplementation(() => ({ - getEntityByRef: jest.fn().mockImplementation(entityRef => { + CatalogClient: jest.fn().mockReturnValue({ + getEntityByRef: jest.fn().mockImplementation(async entityRef => { if (entityRef.name === 'noentity') { - return Promise.resolve(undefined); + return undefined; } - return Promise.resolve({ + return { kind: entityRef.kind, metadata: { name: entityRef.name, namespace: entityRef.namespace, }, - } as Entity); + }; }), - })), + }), })); const { server } = await startTestBackend({ features: [ - mockServices.rootConfig.factory({ - data: { - kubernetes: { - serviceLocatorMethod: { - type: 'multiTenant', - }, - clusterLocatorMethods: [ - { - type: 'config', - clusters: [], - }, - ], - }, - }, - }), + minimalValidConfigService, import('@backstage/plugin-kubernetes-backend/alpha'), import('@backstage/plugin-permission-backend/alpha'), import('@backstage/plugin-permission-backend-module-allow-all-policy'), @@ -168,24 +135,33 @@ describe('KubernetesBuilder', () => { }); }, }), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testClusterSupplier', - register(env) { - env.registerInit({ - deps: { extension: kubernetesClusterSupplierExtensionPoint }, - async init({ extension }) { - extension.addClusterSupplier(clusterSupplierMock); - }, - }); + withClusters([ + { + name: 'some-cluster', + url: 'https://localhost:1234', + authMetadata: { + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount', + }, }, - }), + { + name: 'some-other-cluster', + url: 'https://localhost:1235', + authMetadata: { + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'oidc', + [ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER]: 'google', + }, + }, + ]), ], }); app = server; }); + afterEach(() => { + app.stop(); + }); + describe('get /clusters', () => { it('happy path: lists clusters', async () => { const response = await request(app).get('/api/kubernetes/clusters'); @@ -219,20 +195,16 @@ describe('KubernetesBuilder', () => { it('happy path: lists kubernetes objects with auth in request body', async () => { const response = await request(app) .post('/api/kubernetes/services/test-service') - .send({ - auth: { - google: 'google_token_123', - }, - }) + .send({ auth: { google: 'google_token_123' } }) .set('Content-Type', 'application/json'); expect(response.status).toEqual(200); expect(response.body).toEqual(happyK8SResult); }); it('internal error: lists kubernetes objects', async () => { - objectsProviderMock.getKubernetesObjectsByEntity = jest - .fn() - .mockRejectedValue(Error('some internal error')); + objectsProviderMock.getKubernetesObjectsByEntity.mockRejectedValue( + Error('some internal error'), + ); const response = await request(app).post( '/api/kubernetes/services/test-service', @@ -260,96 +232,29 @@ describe('KubernetesBuilder', () => { }, ]; - const clusterSupplierMock = { - getClusters: jest.fn().mockImplementation(_ => { - return Promise.resolve(clusters); + const pod = { metadata: { name: 'pod1' } }; + + const mockServiceLocator: jest.Mocked = { + getClustersByEntity: jest.fn().mockResolvedValue({ + clusters: [someCluster], }), }; - const pod = { - metadata: { - name: 'pod1', - }, - }; - const result: ObjectsByEntityResponse = { - items: [ - { - cluster: { - name: someCluster.name, - }, - errors: [], - podMetrics: [], - resources: [ - { - type: 'pods', - resources: [pod], - }, - ], - }, - ], - }; - - const mockServiceLocator: KubernetesServiceLocator = { - getClustersByEntity( - _entity: Entity, - ): Promise<{ clusters: ClusterDetails[] }> { - return Promise.resolve({ clusters: [someCluster] }); - }, - }; - - const mockFetcher: KubernetesFetcher = { - fetchPodMetricsByNamespaces( - _clusterDetails: ClusterDetails, - _credential: KubernetesCredential, - _namespaces: Set, - ): Promise { - return Promise.resolve({ errors: [], responses: [] }); - }, - fetchObjectsForService( - _params: ObjectFetchParams, - ): Promise { - return Promise.resolve({ - errors: [], - responses: [ - { - type: 'pods', - resources: [pod], - }, - ], - }); - }, + const mockFetcher: jest.Mocked = { + fetchPodMetricsByNamespaces: jest + .fn() + .mockResolvedValue({ errors: [], responses: [] }), + fetchObjectsForService: jest.fn().mockResolvedValue({ + errors: [], + responses: [{ type: 'pods', resources: [pod] }], + }), }; const { server } = await startTestBackend({ features: [ - mockServices.rootConfig.factory({ - data: { - kubernetes: { - serviceLocatorMethod: { - type: 'multiTenant', - }, - clusterLocatorMethods: [ - { - type: 'config', - clusters: [], - }, - ], - }, - }, - }), + minimalValidConfigService, import('@backstage/plugin-kubernetes-backend/alpha'), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testClusterSupplier', - register(env) { - env.registerInit({ - deps: { extension: kubernetesClusterSupplierExtensionPoint }, - async init({ extension }) { - extension.addClusterSupplier(clusterSupplierMock); - }, - }); - }, - }), + withClusters(clusters), createBackendModule({ pluginId: 'kubernetes', moduleId: 'testFetcher', @@ -376,20 +281,22 @@ describe('KubernetesBuilder', () => { }), ], }); - app = server; const response = await request(app) .post('/api/kubernetes/services/test-service') - .send({ - entity: { - metadata: { - name: 'thing', - }, - }, - }); + .send({ entity: { metadata: { name: 'thing' } } }); - expect(response.body).toEqual(result); + expect(response.body).toEqual({ + items: [ + { + cluster: { name: someCluster.name }, + errors: [], + podMetrics: [], + resources: [{ type: 'pods', resources: [pod] }], + }, + ], + }); expect(response.status).toEqual(200); }); @@ -406,9 +313,11 @@ describe('KubernetesBuilder', () => { }), }; - const clusterSupplierMock = { - getClusters: jest.fn().mockImplementation(_ => { - return Promise.resolve([ + const { server } = await startTestBackend({ + features: [ + minimalValidConfigService, + import('@backstage/plugin-kubernetes-backend/alpha'), + withClusters([ { name: 'custom-cluster', url: 'http://my.cluster.url', @@ -416,40 +325,7 @@ describe('KubernetesBuilder', () => { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'custom', }, }, - ]); - }), - }; - - const { server } = await startTestBackend({ - features: [ - mockServices.rootConfig.factory({ - data: { - kubernetes: { - serviceLocatorMethod: { - type: 'multiTenant', - }, - clusterLocatorMethods: [ - { - type: 'config', - clusters: [], - }, - ], - }, - }, - }), - import('@backstage/plugin-kubernetes-backend/alpha'), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testClusterSupplier', - register(env) { - env.registerInit({ - deps: { extension: kubernetesClusterSupplierExtensionPoint }, - async init({ extension }) { - extension.addClusterSupplier(clusterSupplierMock); - }, - }); - }, - }), + ]), createBackendModule({ pluginId: 'kubernetes', moduleId: 'testAuthStrategy', @@ -493,11 +369,7 @@ describe('KubernetesBuilder', () => { await request(app) .post('/api/kubernetes/services/test-service') .send({ - entity: { - metadata: { - name: 'thing', - }, - }, + entity: { metadata: { name: 'thing' } }, auth: { custom: 'custom-token' }, }); @@ -534,30 +406,26 @@ describe('KubernetesBuilder', () => { ); }); - it('returns the given request body with permission set to allow', async () => { - const requestBody = { + it('forwards request body to k8s', async () => { + const namespaceManifest = { kind: 'Namespace', apiVersion: 'v1', - metadata: { - name: 'new-ns', - }, + metadata: { name: 'new-ns' }, }; const proxyEndpointRequest = request(app) .post('/api/kubernetes/proxy/api/v1/namespaces') .set(HEADER_KUBERNETES_CLUSTER, 'some-cluster') .set(HEADER_KUBERNETES_AUTH, 'randomtoken') - .send(requestBody); - + .send(namespaceManifest); worker.use(rest.all(proxyEndpointRequest.url, req => req.passthrough())); - const response = await proxyEndpointRequest; - expect(response.body).toStrictEqual(requestBody); + expect(response.body).toStrictEqual(namespaceManifest); }); - it('supports yaml content type with permission set to allow', async () => { - const requestBody = `--- + it('supports yaml content type', async () => { + const yamlManifest = `--- kind: Namespace apiVersion: v1 metadata: @@ -569,55 +437,37 @@ metadata: .set(HEADER_KUBERNETES_CLUSTER, 'some-cluster') .set(HEADER_KUBERNETES_AUTH, 'randomtoken') .set('content-type', 'application/yaml') - .send(requestBody); + .send(yamlManifest); worker.use(rest.all(proxyEndpointRequest.url, req => req.passthrough())); const response = await proxyEndpointRequest; - expect(response.text).toEqual(requestBody); + expect(response.text).toEqual(yamlManifest); }); - it('returns a 403 response if Permission Policy is in place that blocks endpoint', async () => { - const requestBody = { - kind: 'Namespace', - apiVersion: 'v1', - metadata: { - name: 'new-ns', - }, - }; - + it('returns 403 response when permission blocks endpoint', async () => { permissionsMock.authorize.mockResolvedValue([ { result: AuthorizeResult.DENY }, ]); const { server } = await startTestBackend({ features: [ - mockServices.rootConfig.factory({ - data: { - kubernetes: { - serviceLocatorMethod: { - type: 'multiTenant', - }, - clusterLocatorMethods: [ - { - type: 'config', - clusters: [], - }, - ], - }, - }, - }), + minimalValidConfigService, permissionsMock.factory, import('@backstage/plugin-kubernetes-backend/alpha'), - // import('@backstage/plugin-permission-backend/alpha'), ], }); + app = server; - const proxyEndpointRequest = request(server) + const proxyEndpointRequest = request(app) .post('/api/kubernetes/proxy/api/v1/namespaces') .set(HEADER_KUBERNETES_CLUSTER, 'some-cluster') .set(HEADER_KUBERNETES_AUTH, 'randomtoken') - .send(requestBody); + .send({ + kind: 'Namespace', + apiVersion: 'v1', + metadata: { name: 'new-ns' }, + }); worker.use(rest.all(proxyEndpointRequest.url, req => req.passthrough())); @@ -636,62 +486,17 @@ metadata: }), ); - const clusterSupplierMock = { - getClusters: jest.fn().mockImplementation(_ => { - return Promise.resolve([ + const { server } = await startTestBackend({ + features: [ + minimalValidConfigService, + import('@backstage/plugin-kubernetes-backend/alpha'), + withClusters([ { name: 'custom-cluster', url: 'http://my.cluster.url', - authMetadata: { - [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'custom', - }, + authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'custom' }, }, - ]); - }), - }; - - const { server } = await startTestBackend({ - features: [ - mockServices.rootConfig.factory({ - data: { - kubernetes: { - serviceLocatorMethod: { - type: 'multiTenant', - }, - clusterLocatorMethods: [ - { - type: 'config', - clusters: [], - }, - ], - }, - }, - }), - import('@backstage/plugin-kubernetes-backend/alpha'), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testObjectsProvider', - register(env) { - env.registerInit({ - deps: { extension: kubernetesObjectsProviderExtensionPoint }, - async init({ extension }) { - extension.addObjectsProvider(objectsProviderMock); - }, - }); - }, - }), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testClusterSupplier', - register(env) { - env.registerInit({ - deps: { extension: kubernetesClusterSupplierExtensionPoint }, - async init({ extension }) { - extension.addClusterSupplier(clusterSupplierMock); - }, - }); - }, - }), + ]), createBackendModule({ pluginId: 'kubernetes', moduleId: 'testAuthStrategy', @@ -715,9 +520,7 @@ metadata: ], }); - app = server; - - const proxyEndpointRequest = request(app) + const proxyEndpointRequest = request(server) .get('/api/kubernetes/proxy/api/v1/namespaces') .set(HEADER_KUBERNETES_CLUSTER, 'custom-cluster') .set(HEADER_KUBERNETES_AUTH, 'custom-token'); @@ -727,9 +530,9 @@ metadata: expect(response.body).toStrictEqual({ items: [] }); }); - it('should not permit custom auth strategies with dashes', async () => { - const throwError = async () => { - await startTestBackend({ + it('should not permit custom auth strategies with dashes', () => { + const throwError = () => + startTestBackend({ features: [ import('@backstage/plugin-kubernetes-backend/alpha'), createBackendModule({ @@ -754,9 +557,7 @@ metadata: }), ], }); - }; - - await expect(throwError).rejects.toThrow( + return expect(throwError).rejects.toThrow( 'Strategy name can not include dashes', ); }); @@ -771,11 +572,7 @@ metadata: expect(response.status).toEqual(200); expect(response.body).toMatchObject({ permissions: [ - { - type: 'basic', - name: 'kubernetes.proxy', - attributes: {}, - }, + { type: 'basic', name: 'kubernetes.proxy', attributes: {} }, ], rules: [], }); From 7f6ff255f1b2af507941577a8dfc4de1f9e7b874 Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Fri, 12 Jan 2024 12:40:40 -0500 Subject: [PATCH 196/283] enable custom auth metadata in config Signed-off-by: Jamie Klassen --- .changeset/ten-numbers-happen.md | 5 + plugins/kubernetes-backend/config.d.ts | 11 +- .../ConfigClusterLocator.test.ts | 61 +++++++ .../cluster-locator/ConfigClusterLocator.ts | 8 +- .../src/service/KubernetesBuilder.test.ts | 150 ++++++++++++------ 5 files changed, 185 insertions(+), 50 deletions(-) create mode 100644 .changeset/ten-numbers-happen.md diff --git a/.changeset/ten-numbers-happen.md b/.changeset/ten-numbers-happen.md new file mode 100644 index 0000000000..73397d4568 --- /dev/null +++ b/.changeset/ten-numbers-happen.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +--- + +Custom per-cluster auth metadata (mainly for use with custom `AuthenticationStrategy` implementations) can now be specified in the `authMetadata` property of clusters in the app-config. diff --git a/plugins/kubernetes-backend/config.d.ts b/plugins/kubernetes-backend/config.d.ts index e9b5878920..9c5417a00e 100644 --- a/plugins/kubernetes-backend/config.d.ts +++ b/plugins/kubernetes-backend/config.d.ts @@ -46,13 +46,16 @@ export interface Config { /** @visibility secret */ serviceAccountToken?: string; /** @visibility frontend */ - authProvider: + authProvider?: + | 'aks' | 'aws' - | 'google' - | 'serviceAccount' | 'azure' + | 'google' + | 'googleServiceAccount' | 'oidc' - | 'googleServiceAccount'; + | 'serviceAccount'; + /** @visibility secret */ + authMetadata?: object; /** @visibility frontend */ oidcTokenProvider?: string; /** @visibility frontend */ diff --git a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts index 258cddcd66..cca2b28fcf 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts @@ -177,6 +177,67 @@ describe('ConfigClusterLocator', () => { ]); }); + it('reads custom authMetadata', async () => { + const config: Config = new ConfigReader({ + clusters: [ + { + name: 'cluster', + url: 'http://url', + authProvider: 'authProvider', + authMetadata: { 'custom-key': 'custom-value' }, + }, + ], + }); + + const result = await ConfigClusterLocator.fromConfig( + config, + authStrategy, + ).getClusters(); + + expect(result).toMatchObject([ + { + authMetadata: expect.objectContaining({ 'custom-key': 'custom-value' }), + }, + ]); + }); + + it('reads authProvider from metadata block', async () => { + const config: Config = new ConfigReader({ + clusters: [ + { + name: 'cluster', + url: 'http://url', + authMetadata: { + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount', + }, + }, + ], + }); + + const result = await ConfigClusterLocator.fromConfig( + config, + authStrategy, + ).getClusters(); + + expect(result).toMatchObject([ + { + authMetadata: { + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount', + }, + }, + ]); + }); + + it('forbids cluster without auth provider', () => { + const config: Config = new ConfigReader({ + clusters: [{ name: 'cluster', url: 'http://url' }], + }); + + expect(() => ConfigClusterLocator.fromConfig(config, authStrategy)).toThrow( + 'Missing required config value', + ); + }); + it('one cluster with dashboardParameters', async () => { const config: Config = new ConfigReader({ clusters: [ diff --git a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts index 7899d7762d..816a9da0a6 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts @@ -37,7 +37,12 @@ export class ConfigClusterLocator implements KubernetesClustersSupplier { ): ConfigClusterLocator { return new ConfigClusterLocator( config.getConfigArray('clusters').map(c => { - const authProvider = c.getString('authProvider'); + const authMetadataBlock = c.getOptional<{ + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]?: string; + }>('authMetadata'); + const authProvider = + authMetadataBlock?.[ANNOTATION_KUBERNETES_AUTH_PROVIDER] ?? + c.getString('authProvider'); const clusterDetails: ClusterDetails = { name: c.getString('name'), url: c.getString('url'), @@ -48,6 +53,7 @@ export class ConfigClusterLocator implements KubernetesClustersSupplier { authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: authProvider, ...ConfigClusterLocator.parseAuthMetadata(c), + ...authMetadataBlock, }, }; diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts index a35e488b50..42f953a2fe 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts @@ -17,7 +17,6 @@ import { ANNOTATION_KUBERNETES_AUTH_PROVIDER, ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER, - ObjectsByEntityResponse, KubernetesRequestAuth, } from '@backstage/plugin-kubernetes-common'; import request from 'supertest'; @@ -39,10 +38,7 @@ import { startTestBackend, } from '@backstage/backend-test-utils'; import { rest } from 'msw'; -import { - AuthorizeResult, - PermissionEvaluator, -} from '@backstage/plugin-permission-common'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; import { PermissionsService, createBackendModule, @@ -57,9 +53,9 @@ import { } from '@backstage/plugin-kubernetes-node'; import { ExtendedHttpServer } from '@backstage/backend-app-api'; -describe('KubernetesBuilder', () => { +describe('API integration tests', () => { let app: ExtendedHttpServer; - let objectsProviderMock: KubernetesObjectsProvider; + let objectsProviderMock: jest.Mocked; const happyK8SResult = { items: [{ clusterOne: { pods: [{ metadata: { name: 'pod1' } }] } }], }; @@ -530,52 +526,116 @@ metadata: expect(response.body).toStrictEqual({ items: [] }); }); - it('should not permit custom auth strategies with dashes', () => { - const throwError = () => - startTestBackend({ - features: [ - import('@backstage/plugin-kubernetes-backend/alpha'), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testAuthStrategy', - register(env) { - env.registerInit({ - deps: { extension: kubernetesAuthStrategyExtensionPoint }, - async init({ extension }) { - extension.addAuthStrategy('custom-strategy', { - getCredential: jest - .fn< - Promise, - [ClusterDetails, KubernetesRequestAuth] - >() - .mockResolvedValue({ type: 'anonymous' }), - validateCluster: jest.fn().mockReturnValue([]), - }); + it('reads custom auth metadata from config', async () => { + const authStrategy = { + getCredential: jest.fn().mockResolvedValue({ type: 'anonymous' }), + validateCluster: jest.fn().mockReturnValue([]), + }; + worker.use( + rest.get('http://my.cluster/api', (_req, res, ctx) => + res(ctx.json({})), + ), + ); + const { server } = await startTestBackend({ + features: [ + mockServices.rootConfig.factory({ + data: { + kubernetes: { + serviceLocatorMethod: { type: 'multiTenant' }, + clusterLocatorMethods: [ + { + type: 'config', + clusters: [ + { + name: 'cluster', + url: 'http://my.cluster', + authProvider: 'custom', + authMetadata: { 'custom-key': 'custom-value' }, + }, + ], }, - }); + ], }, - }), - ], - }); - return expect(throwError).rejects.toThrow( - 'Strategy name can not include dashes', + }, + }), + import('@backstage/plugin-kubernetes-backend/alpha'), + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testAuthStrategy', + register(env) { + env.registerInit({ + deps: { extension: kubernetesAuthStrategyExtensionPoint }, + async init({ extension }) { + extension.addAuthStrategy('custom', authStrategy); + }, + }); + }, + }), + ], + }); + app = server; + + const proxyEndpointRequest = request(app).get( + '/api/kubernetes/proxy/api', + ); + worker.use(rest.all(proxyEndpointRequest.url, req => req.passthrough())); + const response = await proxyEndpointRequest; + + expect(response.body).toStrictEqual({}); + expect(authStrategy.getCredential).toHaveBeenCalledWith( + expect.objectContaining({ + authMetadata: expect.objectContaining({ + 'custom-key': 'custom-value', + }), + }), + expect.anything(), ); }); }); - describe('get /.well-known/backstage/permissions/metadata', () => { - it('lists permissions supported by the kubernetes plugin', async () => { - const response = await request(app).get( - '/api/kubernetes/.well-known/backstage/permissions/metadata', - ); - - expect(response.status).toEqual(200); - expect(response.body).toMatchObject({ - permissions: [ - { type: 'basic', name: 'kubernetes.proxy', attributes: {} }, + it('forbids custom auth strategies with dashes', () => { + const throwError = () => + startTestBackend({ + features: [ + import('@backstage/plugin-kubernetes-backend/alpha'), + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testAuthStrategy', + register(env) { + env.registerInit({ + deps: { extension: kubernetesAuthStrategyExtensionPoint }, + async init({ extension }) { + extension.addAuthStrategy('custom-strategy', { + getCredential: jest + .fn< + Promise, + [ClusterDetails, KubernetesRequestAuth] + >() + .mockResolvedValue({ type: 'anonymous' }), + validateCluster: jest.fn().mockReturnValue([]), + }); + }, + }); + }, + }), ], - rules: [], }); + return expect(throwError).rejects.toThrow( + 'Strategy name can not include dashes', + ); + }); + + it('serves permission integration endpoint', async () => { + const response = await request(app).get( + '/api/kubernetes/.well-known/backstage/permissions/metadata', + ); + + expect(response.status).toEqual(200); + expect(response.body).toMatchObject({ + permissions: [ + { type: 'basic', name: 'kubernetes.proxy', attributes: {} }, + ], + rules: [], }); }); From 7125d9c4329542544cc9413c3a435573dec4691a Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Fri, 12 Jan 2024 17:41:49 -0500 Subject: [PATCH 197/283] regression test for parameter precedence Signed-off-by: Jamie Klassen --- .../ConfigClusterLocator.test.ts | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts index cca2b28fcf..6fb33d8b3a 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts @@ -228,6 +228,34 @@ describe('ConfigClusterLocator', () => { ]); }); + it('prefers authMetadata block to top-level keys', async () => { + const sut = ConfigClusterLocator.fromConfig( + new ConfigReader({ + clusters: [ + { + name: 'cluster', + url: 'http://url', + authProvider: 'aws', + authMetadata: { + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount', + }, + }, + ], + }), + authStrategy, + ); + + const result = await sut.getClusters(); + + expect(result).toMatchObject([ + { + authMetadata: { + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount', + }, + }, + ]); + }); + it('forbids cluster without auth provider', () => { const config: Config = new ConfigReader({ clusters: [{ name: 'cluster', url: 'http://url' }], From 413f08ddcc5dd156eb77c22b4ab7e69300cce70d Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Fri, 12 Jan 2024 17:42:23 -0500 Subject: [PATCH 198/283] improve error message on missing authProvider Signed-off-by: Jamie Klassen --- .../src/cluster-locator/ConfigClusterLocator.test.ts | 4 +++- .../src/cluster-locator/ConfigClusterLocator.ts | 12 ++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts index 6fb33d8b3a..1720ef5ed6 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts @@ -262,7 +262,9 @@ describe('ConfigClusterLocator', () => { }); expect(() => ConfigClusterLocator.fromConfig(config, authStrategy)).toThrow( - 'Missing required config value', + `cluster 'cluster' has no auth provider configured; this must be specified` + + ` via the 'authProvider' or ` + + `'authMetadata.${ANNOTATION_KUBERNETES_AUTH_PROVIDER}' parameter`, ); }); diff --git a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts index 816a9da0a6..19ba8634ad 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts @@ -40,11 +40,19 @@ export class ConfigClusterLocator implements KubernetesClustersSupplier { const authMetadataBlock = c.getOptional<{ [ANNOTATION_KUBERNETES_AUTH_PROVIDER]?: string; }>('authMetadata'); + const name = c.getString('name'); const authProvider = authMetadataBlock?.[ANNOTATION_KUBERNETES_AUTH_PROVIDER] ?? - c.getString('authProvider'); + c.getOptionalString('authProvider'); + if (!authProvider) { + throw new Error( + `cluster '${name}' has no auth provider configured; this must be ` + + `specified via the 'authProvider' or ` + + `'authMetadata.${ANNOTATION_KUBERNETES_AUTH_PROVIDER}' parameter`, + ); + } const clusterDetails: ClusterDetails = { - name: c.getString('name'), + name, url: c.getString('url'), skipTLSVerify: c.getOptionalBoolean('skipTLSVerify') ?? false, skipMetricsLookup: c.getOptionalBoolean('skipMetricsLookup') ?? false, From 8eb00c076799072b49a830e1da7fd43ec5c9cbd6 Mon Sep 17 00:00:00 2001 From: geon hyeon Date: Thu, 18 Jan 2024 10:07:30 +0900 Subject: [PATCH 199/283] Update README-ko_kr.md Signed-off-by: geon hyeon --- README-ko_kr.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README-ko_kr.md b/README-ko_kr.md index f7bcba144b..0544304cea 100644 --- a/README-ko_kr.md +++ b/README-ko_kr.md @@ -22,10 +22,10 @@ Backstage 는 모든 인프라 도구, 서비스 및 문서를 통합하여 처 ![software-catalog](docs/assets/header.png) -Backstage 다음을 포함합니다: +Backstage는 다음을 포함합니다: - [Backstage Software Catalog](https://backstage.io/docs/features/software-catalog/) 마이크로 서비스, 라이브러리, 데이터 파이프라인, 웹 사이트, ML 모델 등 모든 소프트웨어 관리 -- [Backstage Software Templates](https://backstage.io/docs/features/software-templates/) 새로운 프로젝트를 신속하게 시작하고 조직의 모밤 사례에따라 도구를 표준화 +- [Backstage Software Templates](https://backstage.io/docs/features/software-templates/) 새로운 프로젝트를 신속하게 시작하고 조직의 모범 사례에따라 도구를 표준화 - [Backstage TechDocs](https://backstage.io/docs/features/techdocs/) "docs like code" 접근 방식을 사용하여 기술 문서를 쉽게 작성, 유지 관리, 검색 및 사용 - [open source plugins](https://github.com/backstage/backstage/tree/master/plugins) Backstage의 사용자 정의 가능성과 기능을 확장 From 0d526c85549081647abe0f3c50d3b91e163f7998 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Mon, 18 Dec 2023 17:22:30 -0500 Subject: [PATCH 200/283] feat: Make PodExecTerminal UI OptIn Signed-off-by: Carlos Esteban Lopez --- .changeset/sixty-shoes-prove.md | 6 ++ plugins/kubernetes-react/config.d.ts | 31 +++++++++ plugins/kubernetes-react/package.json | 4 +- .../Pods/PodDrawer/ContainerCard.tsx | 17 +++-- plugins/kubernetes-react/src/hooks/index.ts | 1 + .../useIsPodExecTerminalEnabled.test.tsx | 64 +++++++++++++++++++ .../src/hooks/useIsPodExecTerminalEnabled.ts | 27 ++++++++ .../useIsPodExecTerminalSupported.test.ts | 2 +- .../hooks/useIsPodExecTerminalSupported.ts | 1 + 9 files changed, 145 insertions(+), 8 deletions(-) create mode 100644 .changeset/sixty-shoes-prove.md create mode 100644 plugins/kubernetes-react/config.d.ts create mode 100644 plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.test.tsx create mode 100644 plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.ts diff --git a/.changeset/sixty-shoes-prove.md b/.changeset/sixty-shoes-prove.md new file mode 100644 index 0000000000..67a019f1ea --- /dev/null +++ b/.changeset/sixty-shoes-prove.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +'@backstage/plugin-kubernetes-react': patch +--- + +Make PodExecTerminal UI OptIn diff --git a/plugins/kubernetes-react/config.d.ts b/plugins/kubernetes-react/config.d.ts new file mode 100644 index 0000000000..d8f6ba8ca9 --- /dev/null +++ b/plugins/kubernetes-react/config.d.ts @@ -0,0 +1,31 @@ +import { PodExecTerminal } from './src/components/PodExecTerminal/PodExecTerminal'; +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export interface Config { + kubernetes?: { + /** + * Pod Exec Terminal config + */ + podExecTerminal?: { + /** + * Enable `PodExecTerminal` UI feature + * @visibility frontend + */ + enable?: boolean; + }; + }; +} diff --git a/plugins/kubernetes-react/package.json b/plugins/kubernetes-react/package.json index 8389b4d2a9..d85cb7ba35 100644 --- a/plugins/kubernetes-react/package.json +++ b/plugins/kubernetes-react/package.json @@ -14,6 +14,7 @@ "role": "web-library" }, "sideEffects": false, + "configSchema": "config.d.ts", "scripts": { "start": "backstage-cli package start", "build": "backstage-cli package build", @@ -60,6 +61,7 @@ "msw": "^1.3.1" }, "files": [ - "dist" + "dist", + "config.d.ts" ] } diff --git a/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.tsx b/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.tsx index db70f92160..592a93e3ea 100644 --- a/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.tsx +++ b/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.tsx @@ -27,6 +27,7 @@ import { IContainer, IContainerStatus } from 'kubernetes-models/v1'; import { DateTime } from 'luxon'; import React from 'react'; +import { useIsPodExecTerminalEnabled } from '../../../hooks'; import { bytesToMiB, formatMillicores } from '../../../utils/resources'; import { PodExecTerminalDialog } from '../../PodExecTerminal/PodExecTerminalDialog'; import { ResourceUtilization } from '../../ResourceUtilization'; @@ -108,6 +109,8 @@ export const ContainerCard: React.FC = ({ containerStatus, containerMetrics, }: ContainerCardProps) => { + const isPodExecTerminalEnabled = useIsPodExecTerminalEnabled(); + // This should never be undefined if (containerSpec === undefined) { return error reading pod from cluster; @@ -228,12 +231,14 @@ export const ContainerCard: React.FC = ({ ...podScope, }} /> - + {isPodExecTerminalEnabled && ( + + )} ); diff --git a/plugins/kubernetes-react/src/hooks/index.ts b/plugins/kubernetes-react/src/hooks/index.ts index 141bc3815b..2bc519d69a 100644 --- a/plugins/kubernetes-react/src/hooks/index.ts +++ b/plugins/kubernetes-react/src/hooks/index.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +export * from './useIsPodExecTerminalEnabled'; export * from './useIsPodExecTerminalSupported'; export * from './useKubernetesObjects'; export * from './useCustomResources'; diff --git a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.test.tsx b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.test.tsx new file mode 100644 index 0000000000..3faf81d9ae --- /dev/null +++ b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.test.tsx @@ -0,0 +1,64 @@ +/* + * Copyright 2023 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 { ConfigReader } from '@backstage/core-app-api'; +import { configApiRef } from '@backstage/core-plugin-api'; +import { TestApiProvider } from '@backstage/test-utils'; +import { renderHook } from '@testing-library/react'; +import { PropsWithChildren } from 'react'; +import React from 'react'; + +import { useIsPodExecTerminalEnabled } from './useIsPodExecTerminalEnabled'; + +describe('useIsPodExecTerminalEnabled', () => { + let isPodExecTerminalEnabled: boolean | undefined; + + const apiWrapper = ({ children }: PropsWithChildren) => ( + + {children} + + ); + + it.each([ + { + condition: 'missing config', + returnValue: undefined, + }, + { condition: 'disabled', returnValue: false }, + { + condition: 'enabled', + returnValue: true, + }, + ])('Should return $returnValue if $condition', async ({ returnValue }) => { + isPodExecTerminalEnabled = returnValue; + + const { result } = renderHook(() => useIsPodExecTerminalEnabled(), { + wrapper: apiWrapper, + }); + + expect(result.current).toEqual(returnValue); + }); +}); diff --git a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.ts b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.ts new file mode 100644 index 0000000000..683b9b9a5a --- /dev/null +++ b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2023 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 { configApiRef, useApi } from '@backstage/core-plugin-api'; + +/** + * Check if conditions for a pod exec call through the proxy endpoint are met + * + * @internal + */ +export const useIsPodExecTerminalEnabled = (): boolean | undefined => { + const configApi = useApi(configApiRef); + + return configApi.getOptionalBoolean('kubernetes.podExecTerminal.enable'); +}; diff --git a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.test.ts b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.test.ts index 93bfb6dd4d..c4df347c6f 100644 --- a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.test.ts +++ b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.test.ts @@ -20,7 +20,7 @@ import { useIsPodExecTerminalSupported } from './useIsPodExecTerminalSupported'; jest.mock('@backstage/core-plugin-api'); -describe('useIsClusterShellEnabled', () => { +describe('useIsPodExecTerminalSupported', () => { let clusters: { authProvider: string }[] = []; beforeEach(() => { diff --git a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.ts b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.ts index e881951059..2483bb9412 100644 --- a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.ts +++ b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.ts @@ -15,6 +15,7 @@ */ import { useApi } from '@backstage/core-plugin-api'; import useAsync, { AsyncState } from 'react-use/lib/useAsync'; + import { kubernetesApiRef } from '../api/types'; /** From 8ed83b5b1023790d9085cae343878e947e590ba9 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Mon, 18 Dec 2023 17:26:55 -0500 Subject: [PATCH 201/283] chore: Remove unnecesary changeset package Signed-off-by: Carlos Esteban Lopez --- .changeset/sixty-shoes-prove.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.changeset/sixty-shoes-prove.md b/.changeset/sixty-shoes-prove.md index 67a019f1ea..5db1586ae0 100644 --- a/.changeset/sixty-shoes-prove.md +++ b/.changeset/sixty-shoes-prove.md @@ -1,5 +1,4 @@ --- -'@backstage/plugin-kubernetes-backend': patch '@backstage/plugin-kubernetes-react': patch --- From 3b84b4b9e48be9160a0e52e7b5b383bc4b819daa Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Thu, 4 Jan 2024 15:31:42 -0500 Subject: [PATCH 202/283] Update .changeset/sixty-shoes-prove.md Co-authored-by: Jamie Klassen Signed-off-by: Carlos Esteban Lopez Jaramillo --- .changeset/sixty-shoes-prove.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/sixty-shoes-prove.md b/.changeset/sixty-shoes-prove.md index 5db1586ae0..92edbcc079 100644 --- a/.changeset/sixty-shoes-prove.md +++ b/.changeset/sixty-shoes-prove.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-kubernetes-react': patch +'@backstage/plugin-kubernetes-react': minor --- Make PodExecTerminal UI OptIn From 7133da27dc67bfd3f4adeae0bf28a2658f1b3d0a Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Thu, 4 Jan 2024 15:32:45 -0500 Subject: [PATCH 203/283] Update .changeset/sixty-shoes-prove.md Co-authored-by: Jamie Klassen Signed-off-by: Carlos Esteban Lopez Jaramillo --- .changeset/sixty-shoes-prove.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/sixty-shoes-prove.md b/.changeset/sixty-shoes-prove.md index 92edbcc079..fe9438eeb2 100644 --- a/.changeset/sixty-shoes-prove.md +++ b/.changeset/sixty-shoes-prove.md @@ -2,4 +2,4 @@ '@backstage/plugin-kubernetes-react': minor --- -Make PodExecTerminal UI OptIn +**BREAKING** The pod exec terminal is now disabled by default since there are several scenarios where it is known not to work. It can be re-enabled at your own risk by setting the config parameter `kubernetes.podExecTerminal.enabled` to `true`. From d98604b667b561d2c7f5b15456a549137158e291 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Thu, 4 Jan 2024 15:33:19 -0500 Subject: [PATCH 204/283] Apply suggestions from code review Co-authored-by: Jamie Klassen Signed-off-by: Carlos Esteban Lopez Jaramillo --- plugins/kubernetes-react/config.d.ts | 2 +- .../src/hooks/useIsPodExecTerminalEnabled.test.tsx | 2 +- .../kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/kubernetes-react/config.d.ts b/plugins/kubernetes-react/config.d.ts index d8f6ba8ca9..2d2b790d05 100644 --- a/plugins/kubernetes-react/config.d.ts +++ b/plugins/kubernetes-react/config.d.ts @@ -25,7 +25,7 @@ export interface Config { * Enable `PodExecTerminal` UI feature * @visibility frontend */ - enable?: boolean; + enabled?: boolean; }; }; } diff --git a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.test.tsx b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.test.tsx index 3faf81d9ae..84e75ce529 100644 --- a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.test.tsx +++ b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.test.tsx @@ -32,7 +32,7 @@ describe('useIsPodExecTerminalEnabled', () => { configApiRef, new ConfigReader({ kubernetes: { - podExecTerminal: { enable: isPodExecTerminalEnabled }, + podExecTerminal: { enabled: isPodExecTerminalEnabled }, }, }), ], diff --git a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.ts b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.ts index 683b9b9a5a..7598e1c570 100644 --- a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.ts +++ b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.ts @@ -23,5 +23,5 @@ import { configApiRef, useApi } from '@backstage/core-plugin-api'; export const useIsPodExecTerminalEnabled = (): boolean | undefined => { const configApi = useApi(configApiRef); - return configApi.getOptionalBoolean('kubernetes.podExecTerminal.enable'); + return configApi.getOptionalBoolean('kubernetes.podExecTerminal.enabled'); }; From 536f67dd3d09403cfea37aed990524efd160f874 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Wed, 3 Jan 2024 18:05:23 -0500 Subject: [PATCH 205/283] fix: Revert broken xterm css import Signed-off-by: Carlos Esteban Lopez --- .changeset/funny-timers-visit.md | 5 +++++ .../PodExecTerminal/PodExecTerminal.tsx | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 .changeset/funny-timers-visit.md diff --git a/.changeset/funny-timers-visit.md b/.changeset/funny-timers-visit.md new file mode 100644 index 0000000000..3d802328b5 --- /dev/null +++ b/.changeset/funny-timers-visit.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-react': patch +--- + +Fix broken XtermJS CSS import diff --git a/plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminal.tsx b/plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminal.tsx index f8106bd011..f67d79abb8 100644 --- a/plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminal.tsx +++ b/plugins/kubernetes-react/src/components/PodExecTerminal/PodExecTerminal.tsx @@ -13,9 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import 'xterm'; +import 'xterm/css/xterm.css'; import { discoveryApiRef, useApi } from '@backstage/core-plugin-api'; +import { createStyles, makeStyles, Theme } from '@material-ui/core'; import React, { useEffect, useMemo, useState } from 'react'; import { Terminal } from 'xterm'; import { FitAddon } from 'xterm-addon-fit'; @@ -37,12 +38,23 @@ export interface PodExecTerminalProps { const hasSocketProtocol = (url: string | URL) => /wss?:\/\//.test(url.toString()); +const useStyles = makeStyles((theme: Theme) => + createStyles({ + podExecTerminal: { + width: '100%', + height: '100%', + '& .xterm-screen': { padding: theme.spacing(1) }, + }, + }), +); + /** * Executes a `/bin/sh` process in the given pod's container and opens a terminal connected to it * * @public */ export const PodExecTerminal = (props: PodExecTerminalProps) => { + const classes = useStyles(); const { containerName, podNamespace, podName } = props; const [baseUrl, setBaseUrl] = useState(window.location.host); @@ -122,10 +134,7 @@ export const PodExecTerminal = (props: PodExecTerminalProps) => {
); }; From c2108f75819c250e166ae13b0c704f28330254f6 Mon Sep 17 00:00:00 2001 From: Aizat Faiz Date: Thu, 18 Jan 2024 10:49:09 +0800 Subject: [PATCH 206/283] revert changes to AboutCard.tsx Signed-off-by: Aizat Faiz --- plugins/catalog/src/components/AboutCard/AboutCard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/catalog/src/components/AboutCard/AboutCard.tsx b/plugins/catalog/src/components/AboutCard/AboutCard.tsx index 2bbbc20760..763f6fc094 100644 --- a/plugins/catalog/src/components/AboutCard/AboutCard.tsx +++ b/plugins/catalog/src/components/AboutCard/AboutCard.tsx @@ -166,7 +166,7 @@ export function AboutCard(props: AboutCardProps) { const subHeaderLinks = [viewInSource, viewInTechDocs]; if (isTemplateEntityV1beta3(entity)) { - const Icon = app.getSystemIcon('kind:template') ?? CreateComponentIcon; + const Icon = app.getSystemIcon('scaffolder') ?? CreateComponentIcon; const launchTemplate: IconLinkVerticalProps = { label: 'Launch Template', From b92105443c1785fb969362bb85c4076e9662a737 Mon Sep 17 00:00:00 2001 From: Adam Vollrath Date: Wed, 17 Jan 2024 21:53:00 -0600 Subject: [PATCH 207/283] Include cluster name in initial "deploying" comment. This ensures the initial comment is discovered by the `find-comment` step. See line 114. This should prevent duplicate comments if the deployment fails. Signed-off-by: Adam Vollrath --- .github/workflows/uffizzi-preview.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/uffizzi-preview.yaml b/.github/workflows/uffizzi-preview.yaml index 9591af3a23..2c1c353847 100644 --- a/.github/workflows/uffizzi-preview.yaml +++ b/.github/workflows/uffizzi-preview.yaml @@ -124,7 +124,7 @@ jobs: body: | ## Uffizzi Ephemeral Environment - Virtual Cluster - :cloud: deploying ... + :cloud: deploying cluster `pr-${{ needs.cache-manifests-file.outputs.pr-number }}` :gear: Updating now by workflow run [${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}). From b5abb970f6ebd5fbb4a80452782ade870eec0616 Mon Sep 17 00:00:00 2001 From: David Weber Date: Sun, 14 Jan 2024 14:09:33 +0100 Subject: [PATCH 208/283] chore: add end of life plugin Signed-off-by: David Weber --- microsite/data/plugins/end-of-life.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 microsite/data/plugins/end-of-life.yaml diff --git a/microsite/data/plugins/end-of-life.yaml b/microsite/data/plugins/end-of-life.yaml new file mode 100644 index 0000000000..d54a6bc5f9 --- /dev/null +++ b/microsite/data/plugins/end-of-life.yaml @@ -0,0 +1,10 @@ +--- +title: End of life +author: dweber019 +authorUrl: https://github.com/dweber019 +category: Quality +description: Display end of life data for entities from endoflife.data +documentation: https://github.com/dweber019/backstage-plugin-endoflife +iconUrl: https://raw.githubusercontent.com/dweber019/backstage-plugin-endoflife/main/plugins/endoflife/docs/pluginIcon.png +npmPackageName: '@dweber019/backstage-plugin-endoflife' +addedDate: '2024-01-18' From 109e0fc0c31f43174945e8310c5fced2e516e3dd Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 18 Jan 2024 08:46:31 +0100 Subject: [PATCH 209/283] docs(frontend-system): fix building plugins typo Signed-off-by: Camila Belo --- docs/frontend-system/building-plugins/01-index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/frontend-system/building-plugins/01-index.md b/docs/frontend-system/building-plugins/01-index.md index cb29b3518a..eea2351977 100644 --- a/docs/frontend-system/building-plugins/01-index.md +++ b/docs/frontend-system/building-plugins/01-index.md @@ -18,7 +18,7 @@ This guide assumes that you already have a Backstage project set up. Even if you To create a frontend plugin, run `yarn new`, select `plugin`, and fill out the rest of the prompts. This will create a new package at `plugins/`, which will be the main entrypoint for your plugin. -> **NOT: The created plugin will currently be templated for use in the legacy frontend system, and you will need to replace the existing plugin wiring code.** +> **NOTE: The created plugin will currently be templated for use in the legacy frontend system, and you will need to replace the existing plugin wiring code.** ## The plugin instance From 9cedb2c2607f4d02b1de2cf3a38ac4a287d66534 Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Wed, 17 Jan 2024 13:50:29 +0100 Subject: [PATCH 210/283] beps: 0002-dynamic-frontend-plugins Signed-off-by: Martin Marosi --- beps/0002-dynamic-frontend-plugins/README.md | 492 +++++++++++++++++++ 1 file changed, 492 insertions(+) create mode 100644 beps/0002-dynamic-frontend-plugins/README.md diff --git a/beps/0002-dynamic-frontend-plugins/README.md b/beps/0002-dynamic-frontend-plugins/README.md new file mode 100644 index 0000000000..a75ec77229 --- /dev/null +++ b/beps/0002-dynamic-frontend-plugins/README.md @@ -0,0 +1,492 @@ +--- +title: BEP Dynamic frontend plugins +status: provisional +authors: + - '@Hyperkid123' +owners: +project-areas: + - aaa +creation-date: 2024-01-17 +--- + + + +# BEP: + + + +[**Discussion Issue**](https://github.com/backstage/backstage/issues/NNNNN) + +- [Summary](#summary) +- [Motivation](#motivation) + - [Goals](#goals) + - [Non-Goals](#non-goals) +- [Proposal](#proposal) +- [Design Details](#design-details) +- [Release Plan](#release-plan) +- [Dependencies](#dependencies) +- [Alternatives](#alternatives) + +## Summary + + + +The dynamic frontend plugins feature is a way of loading additional frontend plugins at runtime, without the requirement of rebuilding and restarting a running backstage instance. + +This system should significantly improve frontend plugin management for backstage instances. + +The dynamic plugins leverage the declarative UI system to define what a plugin is and how it should be represented in the browser. + +## Motivation + + + +### Goals + + + +- discover and choose tooling to enable dynamic frontend plugins +- easy way of converting existing frontend plugins to be dynamic +- turning on and off UI plugins at runtime without the requirement of rebuilding or restarting backstage +- manage dynamic plugins declaratively + +An additional goal might be exploring the scope of a "on demand" rending and loading. Currently all plugins, or at least some portion of them must be loaded at UI bootstrap. This approach is not fully dynamic and might be considered a waste of resources. Fully optimizing dynamic plugins loading would require additional changes to the new UI system. + +### Non-Goals + + + +## Proposal + + + +### Definition of UI dynamic plugin + +A dynamic UI plugin (from now just plugin) is a plugin that is not part of the output of a backstage instance build. The plugin and its assets are injected into backstage at runtime. In this case, its injected into the browser at some point during user session. + +From the user POV, there is no difference between classic and dynamic plugins. + +The difference is known only to maintainers and should be limited to + +- build requirements +- integration into backstage + +### Dynamic loading tool + +Traditional plugins are not dynamic out of the box. Additional changes are required during build time to make a plugin dynamic. + +The main application (shell) also requires some changes to be able to load, inject, and propagate mandatory context to dynamic plugins. + +Over the last few year, [Module Federation](https://github.com/module-federation) has become the standard when it comes to dynamically load JS modules browser (and nodejs) environment from remote locations and sharing context between the shell and the remote module. + +Although there are other options, like externalizing dependencies, the module federation has proven itself as a robust solution to this particular problem. + +### Module federation implementation + +There are multiple available implementations of module federation. + +Historically, module federation was implemented as a [Webpack feature](https://webpack.js.org/). Since then, additional implementations were created. Mainly for [Rspack](https://www.rspack.dev/) and [Vite](https://github.com/originjs/vite-plugin-federation). + +Recent changes _claim_, that all of these module federation implementations should be compatible with each other and there should be no need for locking backstage into a single implementation. + +Compatibility between Webpack and Rspack should available via the [@module-federation/enhanced](https://www.npmjs.com/package/@module-federation/enhanced) package. The compatibility is further [described here](https://www.rspack.dev/blog/module-federation-added-to-rspack.html#introducing-rspack-050). + +The Vite plugin claims webpack compatibility as well. The Vite plugin _is not part of the @module-federation_ organization. The extend of compatibility is at this time unknown. + +**The level of compatibility has to be tested.** Before then, no decision in regards to which implementation(s) will be used should be made. The chosen tool, or their mix, will shape the design and implementation. + +That said, packages from the `@module-federation/*` organization should have higher priority as they are based directly on the module federation concepts and are wll supported. + +### Plugin integration into shell applications + +Plugins should be integrated via the new UI system. The system already provides an asynchronous way of loading plugins. The dynamic plugins can be loaded in a similar fashion. + +Plugins should be defined declaratively through configuration. Similar to what was described in this [RFC](https://github.com/backstage/backstage/issues/18372) and in this [issue](https://github.com/backstage/backstage/issues/19545). + +### Plugin registry + +Because plugins are not available at build time, some sort of registry needs to exist to store the information. + +This registry needs to be mutable at runtime (add/remove new plugin metadata) and changes have to be reflected on session refresh. + +This is currently an issue as the app config is embedded into JS assets during build time. + +Each plugin is required to provide manifest file (metadata) in predefined format. This manifest will be used to inject the plugin assets into the browser. + +### Plugin discovery + +Plugin discovery is a pre-requisite for Plugin registry. This should be responsible for scanning for available plugins and generating/modifying the plugin registry to always keep it up to date. + +## Design Details + +> NOTE The details are based on the Janus implementation of dynamic frontend plugins. The implementation leverages [Scalprum](https://github.com/scalprum/scaffolding) which is a Webpack based dynamic plugin manager for React applications. + +### Module federation implementation experiments + +> NOTE Share outcome of testing mixing multiple tools for module federation. + +Test should consist of trying to run permutations of webpack/Rspack/vite based shell apps/plugins and discover if we can freely choose any tool, or if we should restrict the tooling to just a subset of the available options. + +### Plugin manifest + +Each plugin should have a manifest file with important metadata. This metadata is used to load the remote assets to browser. The plugin manifest should be part of a build output. + +A manifest should have: + +- name of plugin +- how can be the init container accessed +- what is the base URL (assets pathname) +- name of the entry script(s) + +#### Scalprum compatible manifest + +```TS +type PluginManifest = { + name: string; + version: string; + dependencies?: Record; + customProperties?: AnyObject; + baseURL: string; + extensions: Extension[]; + loadScripts: string[]; + registrationMethod: 'callback' | 'custom'; + buildHash?: string; +} +``` + +```js +{ + "name": "backstage.plugin-github-actions", + "version": "0.6.6", + "extensions": [], + "registrationMethod": "callback", // where container init is available in browser + "baseURL": "auto", + "loadScripts": [ + "backstage.plugin-github-actions.804b91040fcbca6585ce.js" + ], + "buildHash": "804b91040fcbca6585ce1bcd4b1f8aa2" +} +``` + +##### `registrationMethod` + +Refers to [webpack output.libraryTarget](https://webpack.js.org/configuration/output/#outputlibrarytarget). + +Callback refers to `jsonp` and a the `custom` is used if other available target configuration has been picked. + +It is recommended to use either `global` or `jsonp` as these are environment agnostic (browser VS node). `jsonp` requires additional configurations. The `global` is preferable due to its simplicity. + +##### `baseURL` + +The `baseURL` is derived from [webpack public path](https://webpack.js.org/configuration/output/#outputpublicpath) + +The public path can also be set to `auto` to remove the need to specify origin or pathname and resolve the pathname at runtime. + +In Scalprum, some manifest [post processing](https://github.com/janus-idp/backstage-showcase/blob/main/packages/app/src/components/DynamicRoot/DynamicRoot.tsx#L323) is required to load the initial scripts if the `auto` baseURL is chosen. + +### Plugin registry + +Plugin registry can be fairly simplistic. It can be as simple as JSON file containing list/map of available plugins and their manifests + +```TS +type RegistryEntry = { + name: string // plugin name + manifestLocation: string // path to the manifest resource +} + +// object for easy access +type PluginRegistry = { + [pluginName: string]: RegistryEntry +} + +// or as an array +type PluginRegistry = RegistryEntry[] +``` + +Example of such registry + +```JS +// as object +{ + "backstage.plugin-github-actions": { + "name": "backstage.plugin-github-actions", + "manifestLocation": "https://foo-bar.com/api/plugin-storage/plugin-manifest.json" + }, + // ..rest of plugins +} + +// as array +[ + { + "name": "backstage.plugin-github-actions", + "manifestLocation": "https://foo-bar.com/api/plugin-storage/plugin-manifest.json" + }, + // ...rest of plugins +] +``` + +Scalprum by default lazy loads plugins and manifests. That is because Scalprum initializes plugins only once they are supposed to be rendered in browser. + +Because backstage does not require that functionality in initial dynamic plugin implementation and loads all plugins at bootstrap, there is an alternative to embed manifest data into the registry itself. + +```TS +type RegistryEntry = { + name: string // plugin name + pluginManifest: PluginManifest +} + +// object for easy access +type PluginRegistry = { + [pluginName: string]: RegistryEntry +} + +// or as an array +type PluginRegistry = RegistryEntry[] + +``` + +Example of registry with embedded manifests + +```JS +// as object +{ + "backstage.plugin-github-actions": { + "name": "backstage.plugin-github-actions", + "pluginManifest": { + "name": "backstage.plugin-github-actions", + "version": "0.6.6", + "extensions": [], + "registrationMethod": "callback", + "baseURL": "auto", + "loadScripts": [ + "backstage.plugin-github-actions.804b91040fcbca6585ce.js" + ], + "buildHash": "804b91040fcbca6585ce1bcd4b1f8aa2" + } + }, + // ..rest of plugins +} + +// as array +[ + { + "name": "backstage.plugin-github-actions", + "pluginManifest": { + "name": "backstage.plugin-github-actions", + "version": "0.6.6", + "extensions": [], + "registrationMethod": "callback", + "baseURL": "auto", + "loadScripts": [ + "backstage.plugin-github-actions.804b91040fcbca6585ce.js" + ], + "buildHash": "804b91040fcbca6585ce1bcd4b1f8aa2" + } + }, + // ...rest of plugins +] + +``` + +### Webpack build configuration + +> NOTE This is a sample current configuration in the Janus project. It uses Scalprum webpack based build plugin to generate the output. It does not take the [all options](#Module-federation-implementation-experiments) in consideration. This section will likely change considerably. + +Part of a Scalprum tooling is also [dynamic-plugins-sdk](https://github.com/openshift/dynamic-plugin-sdk). Right now the package is a part of a different project, but that is about to change. More details in the [Scalprum roadmap](https://github.com/scalprum/scaffolding/blob/main/ROADMAP.md). + +#### Sample plugin configuration using Scalprum SDK + +```TS +import { DynamicRemotePlugin } from '@openshift/dynamic-plugin-sdk-webpack'; + +const sharedModules = { + /** + * Mandatory singleton packages for sharing + */ + react: { + singleton: true, + requiredVersion: '*', + }, + 'react-dom': { + singleton: true, + requiredVersion: '*', + }, + 'react-router-dom': { + singleton: true, + requiredVersion: '*', + }, + 'react-router': { + singleton: true, + requiredVersion: '*', + }, + ... + /** + * Full list of shared modules in Janus + * https://github.com/janus-idp/backstage-plugins/blob/87a6b045c7b0f301ebed8b8f99dc1741fa2b044b/packages/cli/src/lib/bundler/scalprumConfig.ts#L16 + */ + +} + +const dynamicPluginPlugin = new DynamicRemotePlugin({ + extensions: [], + sharedModules, + entryScriptFilename: `${options.pluginMetadata.name}.[contenthash].js`, + pluginMetadata: { + // version cna be used from the package.json version field + version: '1.0.0', + /** + * Name can be easily derived from the plugin name + * https://github.com/janus-idp/backstage-plugins/blob/87a6b045c7b0f301ebed8b8f99dc1741fa2b044b/packages/cli/src/commands/export-dynamic-plugin/frontend.ts#L40 + */ + name: 'backstage.plugin-github-actions', + /** + * Path to the plugin entry point. + * It can default to the same entry point as in regular build. + * Plugins can expose multiple modules. We have found that one is sufficient from backstage plugins. + */ + exposedModules: { + PluginRoot: './src/index.ts' + } + }, +}); +``` + +The `DynamicRemotePlugin` webpack plugin takes care of the rest, including the manifest generation. + +#### Sample plugin raw webpack configuration + +The Scalprum config translates to a following base webpack plugin configuration: + +```JS +import { container } from 'webpack'; + +const dynamicPlugin = new container.ModuleFederationPlugin({ + name: 'backstage.plugin-github-actions', + library: { + type: 'global', + /** + * Some library.type has name limitation + * for example, if "type": "var" is used, the library.name can contain the "-" character + */ + name: 'backstage.plugin-github-actions' + }, + filename: 'backstage.plugin-github-actions.[contenthash].js', + exposes: { + PluginRoot: './src/index.ts' + }, + // list of shared modules like "react", "react-dom", etc + shared: sharedModules, +}); +``` + +Additional plugin would have to be written from scratch to generate the plugin manifest file. + +### Sample shell application webpack configuration + +Shell application (backstage) has very simple module federation configuration. It does not require anything special to be able to inject plugins. Main requirement is to provide core shared packages like react and react-dom. + +```JS +import { container } from 'webpack'; + +const scalprumPlugin = new container.ModuleFederationPlugin({ + name: 'backstageHost', + filename: 'backstageHost.[contenthash].js', + // same share modules list as with plugin config + shared: [sharedModules], +}); +``` + +Nothing else is required. + +### Plugin storage + +Where will the dynamic plugin assets be hosted? Module federation does not strictly require the remote assets to be all hosted on the same origin. + +Theoretically plugins can be hosted on some "public CDN" which is detached from individual backstage instances. + +Assets can be also be hosted in the same way as they have always been. + +### Plugin discovery + +How to notify/send data to browser + +### Plugin initialization + +Currently all plugins have to be initialized at UI bootstrap (page refresh). The new UI async API can be used to initialize the remote assets. + +The `CreateAppFeatureLoader` can be leveraged to initialize the remote container. + +```TS +const allPluginManifests = {...} // get this from the config + +const asyncFeatureLoaders: CreateAppFeatureLoader[] = Object.values(allPluginManifests).map(({ manifest }) => { + return { + getLoaderName: () => manifest.name, + load: (options) => { + // initialize the remote container, depends on tooling + const plugin = initDynamicPlugin(manifest) + } + } +}) + +const app = createApp({ + features: [ + ...asyncFeatureLoaders, + // rest of classic features + ] +}) +``` + +### Plugin declarative configuration + +Janus dynamic plugins ref: https://github.com/janus-idp/backstage-showcase/blob/main/showcase-docs%2Fdynamic-plugins.md#frontend-layout-configuration + +TBD, depends heavily on the new UI system + + + +## Release Plan + + + +## Dependencies + + + +## Alternatives + + From b1ed0ebe2971709864273bbefebb321b440f7739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 16 Jan 2024 14:24:07 +0100 Subject: [PATCH 211/283] bump to vale 3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../vale/{Vocab => config/vocabularies}/Backstage/accept.txt | 0 .github/workflows/verify_docs-quality.yml | 2 +- CONTRIBUTING.md | 2 +- scripts/check-docs-quality.js | 4 ++-- 4 files changed, 4 insertions(+), 4 deletions(-) rename .github/vale/{Vocab => config/vocabularies}/Backstage/accept.txt (100%) diff --git a/.github/vale/Vocab/Backstage/accept.txt b/.github/vale/config/vocabularies/Backstage/accept.txt similarity index 100% rename from .github/vale/Vocab/Backstage/accept.txt rename to .github/vale/config/vocabularies/Backstage/accept.txt diff --git a/.github/workflows/verify_docs-quality.yml b/.github/workflows/verify_docs-quality.yml index 8e3b333dd3..d4b83ccefc 100644 --- a/.github/workflows/verify_docs-quality.yml +++ b/.github/workflows/verify_docs-quality.yml @@ -30,6 +30,6 @@ jobs: with: # This also contains --config=.github/vale/config.ini ... :/ files: '${{ steps.generate.outputs.args }}' - version: 2.30.0 # TODO: migrate to v3 + version: latest env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 527957677b..be88ed2249 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -386,7 +386,7 @@ Here are a few things that can help as you go through the review process: - PRs get automatically assigned so you don't need to ping people, they will be notified and have a process of their own for this - If you are waiting for a review or mid-review and your PR goes stale one of the easiest ways to clear the stale bot is by simply rebasing your PR - There are times where you might run into conflict with the `yarn.lock` during a rebase, to help with that make sure your `master` branch is up to date and then in your branch run `git checkout master yarn.lock` and then run `yarn install`, this will get you a conflict free `yarn.lock` file you can commit -- If Vale finds issues with your documentation but it's a code reference you can fix it by putting backticks (`) around it. Now if it is a special word or maybe a name there are two ways you can fix that by adding it to the list of accepted words in the [accept.txt file](https://github.com/backstage/backstage/blob/master/.github/vale/Vocab/Backstage/accept.txt) and them committing that change +- If Vale finds issues with your documentation but it's a code reference you can fix it by putting backticks (`) around it. Now if it is a special word or maybe a name there are two ways you can fix that by adding it to the list of accepted words in the [accept.txt file](https://github.com/backstage/backstage/blob/master/.github/vale/config/vocabularies/Backstage/accept.txt) and them committing that change ### Merging to Master diff --git a/scripts/check-docs-quality.js b/scripts/check-docs-quality.js index d3b51a49a3..7960ff72bb 100755 --- a/scripts/check-docs-quality.js +++ b/scripts/check-docs-quality.js @@ -70,7 +70,7 @@ async function exitIfMissingVale() { process.exit(1); } console.log(`Language linter (vale) generated errors. Please check the errors and review any markdown files that you changed. - Possibly update .github/vale/Vocab/Backstage/accept.txt to add new valid words.\n`); + Possibly update .github/vale/config/vocabularies/Backstage/accept.txt to add new valid words.\n`); process.exit(0); } } @@ -89,7 +89,7 @@ async function runVale(files) { // If it contains system level error. In this case vale does not exist. if (process.platform !== 'win32' || result.error) { console.log(`Language linter (vale) generated errors. Please check the errors and review any markdown files that you changed. - Possibly update .github/vale/Vocab/Backstage/accept.txt to add new valid words.\n`); + Possibly update .github/vale/config/vocabularies/Backstage/accept.txt to add new valid words.\n`); } return false; } From 49b3b5ef9907c1157aad49620bd6c43602d01b1d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 09:22:49 +0000 Subject: [PATCH 212/283] fix(deps): update dependency @asyncapi/react-component to v1.2.13 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .changeset/renovate-fb2e0b9.md | 5 +++ plugins/api-docs/package.json | 2 +- yarn.lock | 66 +++++++++++++++++----------------- 3 files changed, 39 insertions(+), 34 deletions(-) create mode 100644 .changeset/renovate-fb2e0b9.md diff --git a/.changeset/renovate-fb2e0b9.md b/.changeset/renovate-fb2e0b9.md new file mode 100644 index 0000000000..39277aaa2a --- /dev/null +++ b/.changeset/renovate-fb2e0b9.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-api-docs': patch +--- + +Updated dependency `@asyncapi/react-component` to `1.2.13`. diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 1819d80208..7159aec206 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -33,7 +33,7 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@asyncapi/react-component": "1.2.6", + "@asyncapi/react-component": "1.2.13", "@backstage/catalog-model": "workspace:^", "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", diff --git a/yarn.lock b/yarn.lock index 53cd19f848..04e255eadc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -138,35 +138,35 @@ __metadata: languageName: node linkType: hard -"@asyncapi/avro-schema-parser@npm:^3.0.7": - version: 3.0.7 - resolution: "@asyncapi/avro-schema-parser@npm:3.0.7" +"@asyncapi/avro-schema-parser@npm:^3.0.9": + version: 3.0.9 + resolution: "@asyncapi/avro-schema-parser@npm:3.0.9" dependencies: - "@asyncapi/parser": ^3.0.1 + "@asyncapi/parser": ^3.0.2 "@types/json-schema": ^7.0.11 avsc: ^5.7.6 - checksum: c7755708161f41812ebee90c92fb721176230f0006ddd01683b72c7c1d484a6c5cbe7d7e59c54a5c7221f5f722388642ec26b19a67adc9d30059067cc4276d69 + checksum: db451bc9413a9caef2e45f577dbc04c0e2f94183793ab791979384e900716b2af9d77db15251128b4316b6a87bdb4be6405fb12d3712a21a6f6d3e71256a18e4 languageName: node linkType: hard -"@asyncapi/openapi-schema-parser@npm:^3.0.8": - version: 3.0.8 - resolution: "@asyncapi/openapi-schema-parser@npm:3.0.8" +"@asyncapi/openapi-schema-parser@npm:^3.0.10": + version: 3.0.10 + resolution: "@asyncapi/openapi-schema-parser@npm:3.0.10" dependencies: - "@asyncapi/parser": ^3.0.1 + "@asyncapi/parser": ^3.0.2 "@openapi-contrib/openapi-schema-to-json-schema": ~3.2.0 ajv: ^8.11.0 ajv-errors: ^3.0.0 ajv-formats: ^2.1.1 - checksum: 9c3f49d1a826818b864b2a0b16144d88eb2ecf7ca1d9c1e8554eac30d9875619638924892d093f0270b6b9a04efca1a8918dd5a7eb13fd88c14183d467af5ceb + checksum: ddab8b38b86a2ca12dc9345e1a911cfd63bd537524bbb3bc804a137947381eb97e287c6383cf3575a46cadb73f60c2a826a589c54b15ef3881e5a2bb499d2f4c languageName: node linkType: hard -"@asyncapi/parser@npm:^3.0.1": - version: 3.0.1 - resolution: "@asyncapi/parser@npm:3.0.1" +"@asyncapi/parser@npm:^3.0.2": + version: 3.0.2 + resolution: "@asyncapi/parser@npm:3.0.2" dependencies: - "@asyncapi/specs": ^6.1.0 + "@asyncapi/specs": ^6.2.0 "@openapi-contrib/openapi-schema-to-json-schema": ~3.2.0 "@stoplight/json": ^3.20.2 "@stoplight/json-ref-readers": ^1.2.2 @@ -185,29 +185,29 @@ __metadata: js-yaml: ^4.1.0 jsonpath-plus: ^7.2.0 node-fetch: 2.6.7 - checksum: 6dce457e58dcf9dab8bfb945a7cb9507a2fb686c143d04b77f2f1fe1c1247f9fa76134c872203c3e10398005155f4b9bb4b5e43edfb956c1e9ae4d3d95b6ceb3 + checksum: 07c82c5fddbc97f5f53a7ab29e0e8b538d325bbd2a15c9f130b79d7f0d253af001207ea9121b7de88d672f23514bdf33d327bb322653281f0cd582ea9f15e962 languageName: node linkType: hard -"@asyncapi/protobuf-schema-parser@npm:^3.0.4": - version: 3.0.4 - resolution: "@asyncapi/protobuf-schema-parser@npm:3.0.4" +"@asyncapi/protobuf-schema-parser@npm:^3.0.6": + version: 3.0.6 + resolution: "@asyncapi/protobuf-schema-parser@npm:3.0.6" dependencies: - "@asyncapi/parser": ^3.0.1 + "@asyncapi/parser": ^3.0.2 "@types/protocol-buffers-schema": ^3.4.1 protocol-buffers-schema: ^3.6.0 - checksum: c176e6d86e53f342ac91067279fb6e1ac3ed9d7f36de197fc723a2ceaf2a2588267c445203d67edcb3cd75308c0c0d6ea401ad69508bfe378c9194420702d3db + checksum: 9e185734971c10bcc5155b734939a74f3b87b4fe6173c8e4d404c723611b0257a67e4728c3999ea5d37d9ae89608026f73a9bdc4fb51bfa958eb5eece418aee3 languageName: node linkType: hard -"@asyncapi/react-component@npm:1.2.6": - version: 1.2.6 - resolution: "@asyncapi/react-component@npm:1.2.6" +"@asyncapi/react-component@npm:1.2.13": + version: 1.2.13 + resolution: "@asyncapi/react-component@npm:1.2.13" dependencies: - "@asyncapi/avro-schema-parser": ^3.0.7 - "@asyncapi/openapi-schema-parser": ^3.0.8 - "@asyncapi/parser": ^3.0.1 - "@asyncapi/protobuf-schema-parser": ^3.0.4 + "@asyncapi/avro-schema-parser": ^3.0.9 + "@asyncapi/openapi-schema-parser": ^3.0.10 + "@asyncapi/parser": ^3.0.2 + "@asyncapi/protobuf-schema-parser": ^3.0.6 highlight.js: ^10.7.2 isomorphic-dompurify: ^0.13.0 marked: ^4.0.14 @@ -216,7 +216,7 @@ __metadata: peerDependencies: react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: 4afb34562767771048d0848323adea8d498dc555cc529947d4a45f3ec8d7f172bb454814bcf9c4419e105a743736368b56b3ed54d09b60addc06a287ca0e82b9 + checksum: 1e870caa07a3507685ab52af7e34f31c47b31464159f435f29b0be68adf1c110dc0c9196d8f20ab1d6b998500bbac821181477897636322c0c29fe2708284871 languageName: node linkType: hard @@ -229,12 +229,12 @@ __metadata: languageName: node linkType: hard -"@asyncapi/specs@npm:^6.1.0": - version: 6.1.0 - resolution: "@asyncapi/specs@npm:6.1.0" +"@asyncapi/specs@npm:^6.2.0": + version: 6.2.0 + resolution: "@asyncapi/specs@npm:6.2.0" dependencies: "@types/json-schema": ^7.0.11 - checksum: d4ad199ef58b8ef6be081e2e71fd172fdf6720479f3ae6f9b1e58037f833ca177c8af1dadeab4525c2c07e68ea0a4832e0d3dd67c3b033b988ca2435245f6aa6 + checksum: 9fa959350a75d9d9ab886436720d59bbf1c7bff16ed657fa34cce3a006136d2d853264366c8eee5abf4761f611c305acd5d7fb17e6de92fdc573b32e08f94912 languageName: node linkType: hard @@ -4425,7 +4425,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-api-docs@workspace:plugins/api-docs" dependencies: - "@asyncapi/react-component": 1.2.6 + "@asyncapi/react-component": 1.2.13 "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/core-app-api": "workspace:^" From ff57376959c93a9131298606e302b55cc19b4232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 18 Jan 2024 10:02:09 +0100 Subject: [PATCH 213/283] some minor doc tweaks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../architecture/05-extension-overrides.md | 4 +-- .../frontend-system/architecture/07-routes.md | 22 ++++++------- .../building-plugins/01-index.md | 32 ++++++++++++++----- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/docs/frontend-system/architecture/05-extension-overrides.md b/docs/frontend-system/architecture/05-extension-overrides.md index 6a1037341e..21028627bc 100644 --- a/docs/frontend-system/architecture/05-extension-overrides.md +++ b/docs/frontend-system/architecture/05-extension-overrides.md @@ -12,7 +12,7 @@ description: Frontend extension overrides An extension override is a building block of the frontend system that allows you to programmatically override app or plugin extensions anywhere in your application. Since the entire application is built mostly out of extensions from the bottom up, this is a powerful feature. You can use it for example to provide your own app root layout, to replace the implementation of a Utility API with a custom one, to override how the catalog page renders itself, and much more. -In general, most features should have a good level of customization built into them, so that users do not have to leverage extension overrides to achieve common goals. A well written feature often has `app-config` settings, or uses extension inputs for extensibility where applicable. An example of this is the search plugin, which allows you to provide result renderers as inputs rather than replacing the result page wholesale just to tweak how results are shown. Adopters should take advantage of those when possible, and only use extension overrides when it's necessary to entirely replace the extension. Check the respective extension documentation for guidance. +In general, most features should have a good level of customization built into them, so that users do not have to leverage extension overrides to achieve common goals. A well written feature often has [configuration](../../conf/) settings, or uses extension inputs for extensibility where applicable. An example of this is the search plugin, which allows you to provide result renderers as inputs rather than replacing the result page wholesale just to tweak how results are shown. Adopters should take advantage of those when possible, and only use extension overrides when it's necessary to entirely replace the extension. Check the respective extension documentation for guidance. ## Override App Extensions @@ -74,7 +74,7 @@ import themeOverrides from './themes'; const app = createApp({ // highlight-next-line - features: [ themeOverrides ], + features: [themeOverrides], }); export default app.createRoot(). diff --git a/docs/frontend-system/architecture/07-routes.md b/docs/frontend-system/architecture/07-routes.md index 60bf335158..8351a864ba 100644 --- a/docs/frontend-system/architecture/07-routes.md +++ b/docs/frontend-system/architecture/07-routes.md @@ -10,15 +10,15 @@ description: Frontend routes ## Introduction -Each Backstage plugin is an isolated piece of functionality that doesn't typically communicate directly with other plugins. In order to achieve this, there are many parts of the frontend system that provide a layer of indirection for cross-plugin communication, and they routing system is one of them. +Each Backstage plugin is an isolated piece of functionality that doesn't typically communicate directly with other plugins. In order to achieve this, there are many parts of the frontend system that provide a layer of indirection for cross-plugin communication, and the routing system is one of them. The Backstage routing system makes it possible to implement navigation across plugin boundaries, without each individual plugin knowing the concrete path or location of other plugins in the routing hierarchy, or even its own. This is achieved through the concept of route references, which are opaque reference values that can be shared and used to create concrete links to different parts of an app. The route ref paths can be configured both at plugin level (by plugin developers) and at the app level (by integrators). It is up to plugin developers to create route references for any page content in their plugin that they want it to be possible to link to or from. ## Route References -Plugin developers create a `RouteRef` to expose a path in Backstage's routing system. You will see below how routes are defined programmatically, but before diving into code, let us explain how to configure them at app level. In spite of the fact that plugin developers choose a default route path for the routes their plugin provides, paths are configurable, so app integrators can set a custom path to a route whenever they like to (more information in the following sections). +Plugin developers create a `RouteRef` to expose a path in Backstage's routing system. You will see below how routes are defined programmatically, but before diving into code, let us explain how to configure them at the app level. In spite of the fact that plugin developers choose a default route path for the routes their plugin provides, paths are configurable, so app integrators can set a custom path to a route whenever they like to (more information in the following sections). -There are 3 types of route references: regular route, sub route, and external route, and we will cover both the concept and code definition for each. +There are three types of route references: regular route, sub route, and external route, and we will cover both the concept and code definition for each. ### Creating a Route Reference @@ -31,7 +31,7 @@ import { createRouteRef } from '@backstage/frontend-plugin-api'; export const indexRouteRef = createRouteRef(); ``` -Note that you often want to create the route references themselves in a different file than the one that creates the plugin instance, for example a top-level routes.ts. This is to avoid circular imports when you use the route references from other parts of the same plugin. +Note that you often want to create the route references themselves in a different file than the one that creates the plugin instance, for example a top-level `routes.ts`. This is to avoid circular imports when you use the route references from other parts of the same plugin. Route refs do not have any behavior themselves. They are an opaque value that represents route targets in an app, which are bound to specific paths at runtime. Their role is to provide a level of indirection to help link together different pages that otherwise wouldn't know how to route to each other. @@ -68,7 +68,7 @@ export default createPlugin({ In the example above we associated the `indexRouteRef` with the `catalogIndexPage` extension and provided both the route ref and page via the Catalog plugin. So, When this plugin is installed in the app, the index page will become associated with the newly created `RouteRef`, making it possible to use the route ref to navigate the page extension. -It may be unclear why we configure the routes option when creating a plugin as the route has already been passed to the extension. We do that to make it possible for other plugins to route to our page, which is explained in detail in the [binding routes](#binding-external-route-references) section. +It may seem unclear why we configure the `routes` option when creating a plugin as the route has already been passed to the extension. We do that to make it possible for other plugins to route to our page, which is explained in detail in the [binding routes](#binding-external-route-references) section. ### Defining References with Path Parameters @@ -86,7 +86,7 @@ export const detailsRouteRef = createRouteRef({ ### Using a Route Reference -Route references can be used to link to page in the same plugin, or to pages in a different plugins. In this section we will cover the first scenario, if you are interested in link to a page of a different plugin, please go to the [external routes](#external-router-references) section below. +Route references can be used to link to page in the same plugin, or to pages in different plugins. In this section we will cover the first scenario. If you are interested in linking to a page of a different plugin, please go to the [external routes](#external-route-references) section below. Suppose we are creating a plugin that renders a Catalog index page with a link to a "Foo" component details page. Here is the code for the index page: @@ -117,7 +117,7 @@ export const IndexPage = () => { }; ``` -We use the `useRouteRef` hook to create a link generator function that returns the details page path. We then call the link generator, passing it an object with the kind, namespace, and name. These parameters are used to construct a concrete path to details the "Foo" details page. +We use the `useRouteRef` hook to create a link generator function that returns the details page path. We then call the link generator, passing it an object with the kind, namespace, and name. These parameters are used to construct a concrete path to the "Foo" details page. Let's see how the details page can get the parameters from the URL: @@ -148,12 +148,12 @@ In the code above, we are using the `useRouteRefParams` hook to retrieve the ent Since we are linking to pages of the same package, we are using a route ref directly. However, in the following sections, you will see how to link to pages of different plugins. -## External Router References +## External Route References External routes are made for linking to a page of an external plugin. For this section example, let's assume that we want to link from the Catalog entities list page to the Scaffolder create component page. -We don't want to reference the Scaffolder plugin directly, since that would create an unnecessary dependency. It would also provided little flexibility in allowing the app to tie plugins together, with the links instead being dictated by the plugins themselves. To solve this, we use an `ExternalRouteRef`. Much like regular route references, they can be passed to `useRouteRef` to create concrete URLs, but they can not be used in page extensions and instead have to be associated with a target route using route bindings in the app. +We don't want to reference the Scaffolder plugin directly, since that would create an unnecessary dependency. It would also provide little flexibility in allowing the app to tie plugins together, with the links instead being dictated by the plugins themselves. To solve this, we use an `ExternalRouteRef`. Much like regular route references, they can be passed to `useRouteRef` to create concrete URLs, but they can not be used in page extensions and instead have to be associated with a target route using route bindings in the app. We create a new `RouteRef` inside the Scaffolder plugin, using a neutral name that describes its role in the plugin rather than a specific plugin page that it might be linking to, allowing the app to decide the final target. If the Catalog entity list page for example wants to link the Scaffolder create component page in the header, it might declare an `ExternalRouteRef` similar to this: @@ -272,7 +272,7 @@ export default app.createRoot(); Note that we are not importing and using the `RouteRef`s directly in the app, and instead rely on the plugin instance to access routes of the plugins. This provides better namespacing and discoverability of routes, as well as reduce the number of separate exports from each plugin package. -Another thing to note is that this indirection in the routing is particularly useful for open source plugins that need to leave flexibility in how they are integrated. For plugins that you build internally for your own Backstage application, you can choose to go the route of direct imports or even use concrete routes directly. Although there can be some benefits to using the full routing system even in internal plugins. It can help you structure your routes, and as you will see further down it also helps you manage route parameters. +Another thing to note is that this indirection in the routing is particularly useful for open source plugins that need to provide flexibility in how they are integrated. For plugins that you build internally for your own Backstage application, you can choose to use direct imports or even concrete route path strings directly. Although there can be some benefits to using the full routing system even in internal plugins: it can help you structure your routes, and as you will see further down it also helps you manage route parameters. ### Optional External Route References @@ -312,7 +312,7 @@ export const IndexPage = () => { ## Sub Route References -The last kind of route refs that can be created are `SubRouteRef`s, which can be used to create a route ref with a fixed path relative to an absolute `RouteRef`. They are useful if you have a page that internally is mounted at a sub route of a page extension component, and you want other plugins to be able to route to that page. And they can be a useful utility to handle routing within a plugin itself as well. +The last kind of route ref that can be created is a `SubRouteRef`, which can be used to create a route ref with a fixed path relative to an absolute `RouteRef`. They are useful if you have a page that internally is mounted at a sub route of a page extension component, and you want other plugins to be able to route to that page. And they can be a useful utility to handle routing within a plugin itself as well. For example: diff --git a/docs/frontend-system/building-plugins/01-index.md b/docs/frontend-system/building-plugins/01-index.md index eea2351977..f8d80f9382 100644 --- a/docs/frontend-system/building-plugins/01-index.md +++ b/docs/frontend-system/building-plugins/01-index.md @@ -18,7 +18,9 @@ This guide assumes that you already have a Backstage project set up. Even if you To create a frontend plugin, run `yarn new`, select `plugin`, and fill out the rest of the prompts. This will create a new package at `plugins/`, which will be the main entrypoint for your plugin. -> **NOTE: The created plugin will currently be templated for use in the legacy frontend system, and you will need to replace the existing plugin wiring code.** +:::info +The created plugin will currently be templated for use in the legacy frontend system, and you will need to replace the existing plugin wiring code. +::: ## The plugin instance @@ -67,7 +69,7 @@ import { } from '@backstage/frontend-plugin-api'; import { rootRouteRef } from './routes'; -// Note that these extensions aren't exported, only the plugin itself it. +// Note that these extensions aren't exported, only the plugin itself is. // You can export it locally for testing purposes, but don't export it from the plugin package. const examplePage = createPageExtension({ routeRef: rootRouteRef, @@ -104,7 +106,7 @@ export const examplePlugin = createPlugin({ What we've built here is a very common type of plugin. It's a top-level tool that provides a single page, along with a method for navigating to that page. The implementation of the page component, in this case the highlighted `ExamplePage`, can be arbitrarily complex. It can be anything from a single simple information page, to a full-blown application with multiple sub-pages. -We have also provided external access to our route reference by passing it to the plugin `routes` option. This makes it possible for app integrators to bind an external link from a different plugin to our plugin page. You can read more about how this works in the [External Route References](../architecture/07-routes.md#external-router-references) section. +We have also provided external access to our route reference by passing it to the plugin `routes` option. This makes it possible for app integrators to bind an external link from a different plugin to our plugin page. You can read more about how this works in the [External Route References](../architecture/07-routes.md#external-route-references) section. ## Utility APIs @@ -141,7 +143,7 @@ export function ExamplePage() { return (

Example Page

-

Example: {exampleApi.getExample()}

+

Example: {exampleApi.getExample().example}

); } @@ -182,14 +184,14 @@ export const examplePlugin = createPlugin({ ## Plugin specific extensions -There are many different plugins that you can extend with additional functionality through extensions. One such plugin is the catalog plugin, one of the core features of Backstage. It lets you catalog the software in your organization, where each item in the catalog has its own page that can be populated with tools and information relating to that catalog entity. In this example we will explore how our plugin can provide such a tool to display on an entity page. +There are many different plugins that you can extend with additional functionality through extensions. One such plugin is [the catalog plugin](../../features/software-catalog/), one of the core features of Backstage. It lets you catalog the software in your organization, where each item in the catalog has its own page that can be populated with tools and information relating to that catalog entity. In this example we will explore how our plugin can provide such a tool to display on an entity page. ```tsx title="in src/plugin.ts - An example entity content extension" import { createEntityContentExtension } from '@backstage/plugin-catalog-react'; -// Entity content extension are similar to page extensions in that they are rendered at a route, +// Entity content extensions are similar to page extensions in that they are rendered at a route, // although they also have a title to support in-line navigation between the different content. -// Just like a page extensions the content is lazy loaded, and you can also provide a +// Just like a page extension the content is lazy loaded, and you can also provide a // route reference if you want to be able to generate a URL that links to the content. const exampleEntityContent = createEntityContentExtension({ defaultPath: 'example', @@ -199,8 +201,22 @@ const exampleEntityContent = createEntityContentExtension({ )), }); + +export const examplePlugin = createPlugin({ + id: 'example', + extensions: [ + // highlight-add-next-line + exampleEntityContent + exampleApi, + examplePage, + exampleNavItem, + ], + routes: { + root: rootRouteRef, + }, +}); ``` -The `ExampleEntityContent` itself is again a regular React component where you can implement any functionality you want. To access the entity that the content is being rendered for, you can use the `useEntity` hook from `@backstage/plugin-catalog-react`. You can see a full list of API provided by the catalog React library in [the API reference](../../reference/plugin-catalog-react.md). +The `ExampleEntityContent` itself is again a regular React component where you can implement any functionality you want. To access the entity that the content is being rendered for, you can use the `useEntity` hook from `@backstage/plugin-catalog-react`. You can see a full list of APIs provided by the catalog React library in [the API reference](../../reference/plugin-catalog-react.md). For a more complete list of the different types of extensions that you can create for your plugin, see the [extension types](./03-extension-types.md) section. From 2aef2c951cba58366f24ae50ee2ad69adf21da59 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 10:03:43 +0000 Subject: [PATCH 214/283] chore(deps): update dependency vite-plugin-html to v3.2.2 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 04e255eadc..335a01e55a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -43811,8 +43811,8 @@ __metadata: linkType: hard "vite-plugin-html@npm:^3.2.0": - version: 3.2.1 - resolution: "vite-plugin-html@npm:3.2.1" + version: 3.2.2 + resolution: "vite-plugin-html@npm:3.2.2" dependencies: "@rollup/pluginutils": ^4.2.0 colorette: ^2.0.16 @@ -43828,7 +43828,7 @@ __metadata: pathe: ^0.2.0 peerDependencies: vite: ">=2.0.0" - checksum: 6add7cd7a8f9e83b0c58b20cde2d4da7e132ef56db6a60f3d4cc7022c944896236aeca6bde4c6dc2da3d506f756f63de56251adc47f0ae359c07485b24dd64db + checksum: 2fd6e1f91f74a4432222ed28e68d5f27e58ccbc9ad44e71ff9d02b684b358b0c634bdb4dd32e9d93d09e88d83c3b7b74b89698e25510bc5b94173cdc067b3ac2 languageName: node linkType: hard From 88e3fb20480d876f38384cd18cb8acc0f5b94e26 Mon Sep 17 00:00:00 2001 From: Navya Govind Date: Thu, 18 Jan 2024 11:47:25 +0100 Subject: [PATCH 215/283] dynamic overflow Signed-off-by: Navya Govind --- .../src/components/EntityOwnerPicker/EntityOwnerPicker.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx index 8876266db2..5b5bd39310 100644 --- a/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx +++ b/plugins/catalog-react/src/components/EntityOwnerPicker/EntityOwnerPicker.tsx @@ -66,6 +66,9 @@ const FixedWidthFormControlLabel = withStyles( label: { width: '100%', }, + root: { + width: '90%', + }, }), { name: 'FixedWidthFormControlLabel' }, )(FormControlLabel); From ca7ce199d61bae00bb552f89ea60185b02ac7d68 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 11:04:38 +0000 Subject: [PATCH 216/283] chore(deps): update dependency @openapitools/openapi-generator-cli to v2.8.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 145 ++++++++++++++++++++++++------------------------------ 1 file changed, 64 insertions(+), 81 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4cdd331ec2..834786fa6b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12959,58 +12959,54 @@ __metadata: languageName: node linkType: hard -"@nestjs/axios@npm:0.1.0": - version: 0.1.0 - resolution: "@nestjs/axios@npm:0.1.0" - dependencies: - axios: 0.27.2 +"@nestjs/axios@npm:3.0.1": + version: 3.0.1 + resolution: "@nestjs/axios@npm:3.0.1" peerDependencies: - "@nestjs/common": ^7.0.0 || ^8.0.0 || ^9.0.0 + "@nestjs/common": ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 + axios: ^1.3.1 reflect-metadata: ^0.1.12 rxjs: ^6.0.0 || ^7.0.0 - checksum: 72929b25caacb85517bae962b13d865a31aa3984aa9e55305e0a2306e54338fe51a7eb38ca38cab0fe8b4116fb35219bd02c8b0c4cac70e7b5aeb84d03a1db3f + checksum: 01cebc64efa7a1d9df7a9053fbc5124986a95078789a0f280a2a61c31601a70a35745e07fc385497b4f85c7bdb6216a3575728646f1e6e684c038ac31900129c languageName: node linkType: hard -"@nestjs/common@npm:9.3.11": - version: 9.3.11 - resolution: "@nestjs/common@npm:9.3.11" +"@nestjs/common@npm:10.3.0": + version: 10.3.0 + resolution: "@nestjs/common@npm:10.3.0" dependencies: iterare: 1.2.1 - tslib: 2.5.0 - uid: 2.0.1 + tslib: 2.6.2 + uid: 2.0.2 peerDependencies: - cache-manager: <=5 class-transformer: "*" class-validator: "*" reflect-metadata: ^0.1.12 rxjs: ^7.1.0 peerDependenciesMeta: - cache-manager: - optional: true class-transformer: optional: true class-validator: optional: true - checksum: c39dfa9f02268e3f7fa22c4e9eecff0cfbee39c4d4dd0efc757a52117696dc9aec1f87588252b8b267a18469a6c12987707708b44f97ccbb5c6297396c0d9c00 + checksum: c5444cb46bd4f4a4d28b5031f7c28a0cf9863bc2d5518910bfed6a49734f59e1ea08dd4651e2117ae82df81c933ef84f0963c5cdeee5ef1608cf1bd36ee291c5 languageName: node linkType: hard -"@nestjs/core@npm:9.3.11": - version: 9.3.11 - resolution: "@nestjs/core@npm:9.3.11" +"@nestjs/core@npm:10.3.0": + version: 10.3.0 + resolution: "@nestjs/core@npm:10.3.0" dependencies: "@nuxtjs/opencollective": 0.3.2 fast-safe-stringify: 2.1.1 iterare: 1.2.1 path-to-regexp: 3.2.0 - tslib: 2.5.0 - uid: 2.0.1 + tslib: 2.6.2 + uid: 2.0.2 peerDependencies: - "@nestjs/common": ^9.0.0 - "@nestjs/microservices": ^9.0.0 - "@nestjs/platform-express": ^9.0.0 - "@nestjs/websockets": ^9.0.0 + "@nestjs/common": ^10.0.0 + "@nestjs/microservices": ^10.0.0 + "@nestjs/platform-express": ^10.0.0 + "@nestjs/websockets": ^10.0.0 reflect-metadata: ^0.1.12 rxjs: ^7.1.0 peerDependenciesMeta: @@ -13020,7 +13016,7 @@ __metadata: optional: true "@nestjs/websockets": optional: true - checksum: 39d49e5b16cc260887233dd6701dbc53c073dc7522975d592f6c355db1f42fcf31eeaf300b9d03c63943f7330ecee910281cb78bb66d1c2d938d9b13491e70b4 + checksum: 7677b9fb97c8dec512c2a736c273ef08698b377af8c046bc5aad442ba3d35acbc17d177e76bf44a66678cae2ced2d265183e85be4190c501a195f16496df6396 languageName: node linkType: hard @@ -13980,28 +13976,29 @@ __metadata: linkType: hard "@openapitools/openapi-generator-cli@npm:^2.4.26, @openapitools/openapi-generator-cli@npm:^2.7.0": - version: 2.7.0 - resolution: "@openapitools/openapi-generator-cli@npm:2.7.0" + version: 2.8.0 + resolution: "@openapitools/openapi-generator-cli@npm:2.8.0" dependencies: - "@nestjs/axios": 0.1.0 - "@nestjs/common": 9.3.11 - "@nestjs/core": 9.3.11 + "@nestjs/axios": 3.0.1 + "@nestjs/common": 10.3.0 + "@nestjs/core": 10.3.0 "@nuxtjs/opencollective": 0.3.2 + axios: 1.6.5 chalk: 4.1.2 commander: 8.3.0 compare-versions: 4.1.4 concurrently: 6.5.1 console.table: 0.10.0 fs-extra: 10.1.0 - glob: 7.1.6 + glob: 7.2.3 inquirer: 8.2.5 lodash: 4.17.21 reflect-metadata: 0.1.13 rxjs: 7.8.0 - tslib: 2.0.3 + tslib: 2.6.2 bin: openapi-generator-cli: main.js - checksum: 92ca36779b43fe1e4868cd89bde4cb96918868aa62c8a69a9e199711d8e7093bab67f484d266fcbf37ca4ad87e4e91ea5759fb322c7999a299f5bfdc179065b8 + checksum: 76a43d3087b2a4eb521814369ce99ade622fc146bb2414f52c01a7565f81fa94a6d42f2bf6889a4b25814744f0462613853a609d97c12a608c5717aed2e3898a languageName: node linkType: hard @@ -20882,13 +20879,14 @@ __metadata: languageName: node linkType: hard -"axios@npm:0.27.2, axios@npm:^0.27.2": - version: 0.27.2 - resolution: "axios@npm:0.27.2" +"axios@npm:1.6.5, axios@npm:^1.4.0, axios@npm:^1.6.0": + version: 1.6.5 + resolution: "axios@npm:1.6.5" dependencies: - follow-redirects: ^1.14.9 + follow-redirects: ^1.15.4 form-data: ^4.0.0 - checksum: 38cb7540465fe8c4102850c4368053c21683af85c5fdf0ea619f9628abbcb59415d1e22ebc8a6390d2bbc9b58a9806c874f139767389c862ec9b772235f06854 + proxy-from-env: ^1.1.0 + checksum: e28d67b2d9134cb4608c44d8068b0678cfdccc652742e619006f27264a30c7aba13b2cd19c6f1f52ae195b5232734925928fb192d5c85feea7edd2f273df206d languageName: node linkType: hard @@ -20901,14 +20899,13 @@ __metadata: languageName: node linkType: hard -"axios@npm:^1.4.0, axios@npm:^1.6.0": - version: 1.6.5 - resolution: "axios@npm:1.6.5" +"axios@npm:^0.27.2": + version: 0.27.2 + resolution: "axios@npm:0.27.2" dependencies: - follow-redirects: ^1.15.4 + follow-redirects: ^1.14.9 form-data: ^4.0.0 - proxy-from-env: ^1.1.0 - checksum: e28d67b2d9134cb4608c44d8068b0678cfdccc652742e619006f27264a30c7aba13b2cd19c6f1f52ae195b5232734925928fb192d5c85feea7edd2f273df206d + checksum: 38cb7540465fe8c4102850c4368053c21683af85c5fdf0ea619f9628abbcb59415d1e22ebc8a6390d2bbc9b58a9806c874f139767389c862ec9b772235f06854 languageName: node linkType: hard @@ -28102,6 +28099,20 @@ __metadata: languageName: node linkType: hard +"glob@npm:7.2.3, glob@npm:^7.0.0, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.1.7, glob@npm:^7.2.0": + version: 7.2.3 + resolution: "glob@npm:7.2.3" + dependencies: + fs.realpath: ^1.0.0 + inflight: ^1.0.4 + inherits: 2 + minimatch: ^3.1.1 + once: ^1.3.0 + path-is-absolute: ^1.0.0 + checksum: 29452e97b38fa704dabb1d1045350fb2467cf0277e155aa9ff7077e90ad81d1ea9d53d3ee63bd37c05b09a065e90f16aec4a65f5b8de401d1dac40bc5605d133 + languageName: node + linkType: hard + "glob@npm:^10.2.2, glob@npm:^10.3.10": version: 10.3.10 resolution: "glob@npm:10.3.10" @@ -28117,20 +28128,6 @@ __metadata: languageName: node linkType: hard -"glob@npm:^7.0.0, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.1.7, glob@npm:^7.2.0": - version: 7.2.3 - resolution: "glob@npm:7.2.3" - dependencies: - fs.realpath: ^1.0.0 - inflight: ^1.0.4 - inherits: 2 - minimatch: ^3.1.1 - once: ^1.3.0 - path-is-absolute: ^1.0.0 - checksum: 29452e97b38fa704dabb1d1045350fb2467cf0277e155aa9ff7077e90ad81d1ea9d53d3ee63bd37c05b09a065e90f16aec4a65f5b8de401d1dac40bc5605d133 - languageName: node - linkType: hard - "glob@npm:^8.0.0, glob@npm:^8.0.1, glob@npm:^8.0.3": version: 8.1.0 resolution: "glob@npm:8.1.0" @@ -42543,17 +42540,10 @@ __metadata: languageName: node linkType: hard -"tslib@npm:2.0.3": - version: 2.0.3 - resolution: "tslib@npm:2.0.3" - checksum: 00fcdd1f9995c9f8eb6a4a1ad03f55bc95946321b7f55434182dddac259d4e095fedf78a84f73b6e32dd3f881d9281f09cb583123d3159ed4bdac9ad7393ef8b - languageName: node - linkType: hard - -"tslib@npm:2.5.0": - version: 2.5.0 - resolution: "tslib@npm:2.5.0" - checksum: ae3ed5f9ce29932d049908ebfdf21b3a003a85653a9a140d614da6b767a93ef94f460e52c3d787f0e4f383546981713f165037dc2274df212ea9f8a4541004e1 +"tslib@npm:2.6.2, tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.4.1, tslib@npm:^2.4.1 || ^1.9.3, tslib@npm:^2.5.0, tslib@npm:^2.6.0, tslib@npm:^2.6.2": + version: 2.6.2 + resolution: "tslib@npm:2.6.2" + checksum: 329ea56123005922f39642318e3d1f0f8265d1e7fcb92c633e0809521da75eeaca28d2cf96d7248229deb40e5c19adf408259f4b9640afd20d13aecc1430f3ad languageName: node linkType: hard @@ -42564,13 +42554,6 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.4.1, tslib@npm:^2.4.1 || ^1.9.3, tslib@npm:^2.5.0, tslib@npm:^2.6.0, tslib@npm:^2.6.2": - version: 2.6.2 - resolution: "tslib@npm:2.6.2" - checksum: 329ea56123005922f39642318e3d1f0f8265d1e7fcb92c633e0809521da75eeaca28d2cf96d7248229deb40e5c19adf408259f4b9640afd20d13aecc1430f3ad - languageName: node - linkType: hard - "tsutils@npm:^3.21.0": version: 3.21.0 resolution: "tsutils@npm:3.21.0" @@ -42964,12 +42947,12 @@ __metadata: languageName: node linkType: hard -"uid@npm:2.0.1": - version: 2.0.1 - resolution: "uid@npm:2.0.1" +"uid@npm:2.0.2": + version: 2.0.2 + resolution: "uid@npm:2.0.2" dependencies: "@lukeed/csprng": ^1.0.0 - checksum: 0a3c697d8dd1f3b647afa35c411b11fd8fa2fb6dbd8a49fe109a4aa5214068c2c58781aa6e4516dfd16f0fc524fb7bba0833e9c1dc1ed3f1965b520349be9ad5 + checksum: 98aabddcd6fe46f9b331b0378a93ee9cc51474348ada02006df9d10b4abc783ed596748ed9f20d7f6c5ff395dbcd1e764a65a68db6f39a31c95ae85ef13fe979 languageName: node linkType: hard From e24e4d36b9d4dcbaa746765a94cba1c54ae5aa21 Mon Sep 17 00:00:00 2001 From: AmbrishRamachandiran Date: Thu, 18 Jan 2024 16:39:30 +0530 Subject: [PATCH 217/283] Updated readme document of bitrise plugin Signed-off-by: AmbrishRamachandiran --- .changeset/sharp-pandas-hunt.md | 5 +++++ plugins/bitrise/README.md | 7 +++---- 2 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 .changeset/sharp-pandas-hunt.md diff --git a/.changeset/sharp-pandas-hunt.md b/.changeset/sharp-pandas-hunt.md new file mode 100644 index 0000000000..1c69c02a0b --- /dev/null +++ b/.changeset/sharp-pandas-hunt.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-bitrise': patch +--- + +Update README diff --git a/plugins/bitrise/README.md b/plugins/bitrise/README.md index 9c99f28568..e5d5c2122c 100644 --- a/plugins/bitrise/README.md +++ b/plugins/bitrise/README.md @@ -28,9 +28,8 @@ const websiteEntityPage = ( ``` -Now your plugin should be visible as a tab at the top of the entity pages, -specifically for components that are of the type `website`. -However, it warns of a missing `bitrise.io/app` annotation. +Your plugin should now appear as a tab at the top of entity pages, particularly for `website` component types. +However, it alerts you to a missing `bitrise.io/app` annotation. Add the annotation to your component [catalog-info.yaml](https://github.com/backstage/backstage/blob/master/catalog-info.yaml) as shown in the highlighted example below: @@ -51,4 +50,4 @@ proxy: Authorization: ${BITRISE_AUTH_TOKEN} ``` -Learn on https://devcenter.bitrise.io/api/authentication how to create a new Bitrise token. +Learn how to generate a new Bitrise token at https://devcenter.bitrise.io/api/authentication. From 7c490bd54ad7ee6ed1bf4d6e199de3082b18a8d9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 11:16:16 +0000 Subject: [PATCH 218/283] chore(deps): update dependency @playwright/test to v1.41.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/yarn.lock b/yarn.lock index bcc184718d..a2bb4835e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14113,13 +14113,13 @@ __metadata: linkType: hard "@playwright/test@npm:^1.32.3": - version: 1.40.1 - resolution: "@playwright/test@npm:1.40.1" + version: 1.41.0 + resolution: "@playwright/test@npm:1.41.0" dependencies: - playwright: 1.40.1 + playwright: 1.41.0 bin: playwright: cli.js - checksum: ae094e6cb809365c0707ee2b184e42d2a2542569ada020d2d44ca5866066941262bd9a67af185f86c2fb0133c9b712ea8cb73e2959a289e4261c5fd17077283c + checksum: 3a7039f8cd14dd242154255417c100a99c3254a3c1fd26df2a11be24c10b06ef77d2736336d7743dedc5e1a6a52748e58ced730b6048f8bd75d8867ce81661e0 languageName: node linkType: hard @@ -36778,27 +36778,27 @@ __metadata: languageName: node linkType: hard -"playwright-core@npm:1.40.1": - version: 1.40.1 - resolution: "playwright-core@npm:1.40.1" +"playwright-core@npm:1.41.0": + version: 1.41.0 + resolution: "playwright-core@npm:1.41.0" bin: playwright-core: cli.js - checksum: 84d92fb9b86e3c225b16b6886bf858eb5059b4e60fa1205ff23336e56a06dcb2eac62650992dede72f406c8e70a7b6a5303e511f9b4bc0b85022ede356a01ee0 + checksum: 14671265916a1fd0c71d94640de19c48bcce3f7dec35530f10e349e97030ea44ffa8ee518cbf811501e3ab2b74874aecf917e46bf40fea0570db1d4bea1fe7ac languageName: node linkType: hard -"playwright@npm:1.40.1": - version: 1.40.1 - resolution: "playwright@npm:1.40.1" +"playwright@npm:1.41.0": + version: 1.41.0 + resolution: "playwright@npm:1.41.0" dependencies: fsevents: 2.3.2 - playwright-core: 1.40.1 + playwright-core: 1.41.0 dependenciesMeta: fsevents: optional: true bin: playwright: cli.js - checksum: 9e36791c1b4a649c104aa365fdd9d049924eeb518c5967c0e921aa38b9b00994aa6ee54784d6c2af194b3b494b6f69772673081ef53c6c4a4b2065af9955c4ba + checksum: e7c32136911c58e06b964fe7d33f8b3d8f6a067ae5218662a0811dd6c90e007db1774eb7e161f4aa748d760f404f4c066b7b7303c2b617f7448b6ee4b86c9999 languageName: node linkType: hard From e0cad28ae112f29f2b4404b39bc7b545111ad62a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 11:17:21 +0000 Subject: [PATCH 219/283] chore(deps): update dependency @testing-library/jest-dom to v6.2.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/yarn.lock b/yarn.lock index bcc184718d..747ef72671 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17106,15 +17106,15 @@ __metadata: linkType: hard "@testing-library/jest-dom@npm:^6.0.0": - version: 6.1.6 - resolution: "@testing-library/jest-dom@npm:6.1.6" + version: 6.2.0 + resolution: "@testing-library/jest-dom@npm:6.2.0" dependencies: "@adobe/css-tools": ^4.3.2 "@babel/runtime": ^7.9.2 aria-query: ^5.0.0 chalk: ^3.0.0 css.escape: ^1.5.1 - dom-accessibility-api: ^0.5.6 + dom-accessibility-api: ^0.6.3 lodash: ^4.17.15 redent: ^3.0.0 peerDependencies: @@ -17131,7 +17131,7 @@ __metadata: optional: true vitest: optional: true - checksum: 8d1a80678027915228b483a116fb9e358d25e2faffcd9a2c40b371752fbd53b5cb87351215866a43dd09393e7d364c46fc43923566b00ef63bbf3576d47da940 + checksum: 3d46e36b1b7c2cb3c92f64d55d458aab44ae135ac77299df14d14dcf567a286590de58b2f140011b8f7a343f0703ff88f144f27c6ae4921fd612741771d8ee2c languageName: node linkType: hard @@ -24684,13 +24684,20 @@ __metadata: languageName: node linkType: hard -"dom-accessibility-api@npm:^0.5.6, dom-accessibility-api@npm:^0.5.9": +"dom-accessibility-api@npm:^0.5.9": version: 0.5.13 resolution: "dom-accessibility-api@npm:0.5.13" checksum: a5a5f14c01e466d424750aaac9225f1dc43cf16d101a1c40e01a554abce63c48084707002c39b805f2ce212273c179dd6d2258175997cd06d5f79851bf52dd40 languageName: node linkType: hard +"dom-accessibility-api@npm:^0.6.3": + version: 0.6.3 + resolution: "dom-accessibility-api@npm:0.6.3" + checksum: c325b5144bb406df23f4affecffc117dbaec9af03daad9ee6b510c5be647b14d28ef0a4ea5ca06d696d8ab40bb777e5fed98b985976fdef9d8790178fa1d573f + languageName: node + linkType: hard + "dom-converter@npm:^0.2.0": version: 0.2.0 resolution: "dom-converter@npm:0.2.0" From a77559663cef96841dca535514836614658c6c29 Mon Sep 17 00:00:00 2001 From: Andres Mauricio Gomez P Date: Tue, 9 Jan 2024 18:45:25 -0500 Subject: [PATCH 220/283] Enabled a way to include custom auth metadata info on the clusters endpoint Signed-off-by: Andres Mauricio Gomez P --- .changeset/kind-clouds-fly.md | 6 + plugins/kubernetes-backend/api-report.md | 106 +- .../src/auth/AksStrategy.ts | 13 +- .../src/auth/AnonymousStrategy.ts | 10 +- .../src/auth/AwsIamStrategy.ts | 12 +- .../src/auth/AzureIdentityStrategy.ts | 10 +- .../src/auth/DispatchStrategy.test.ts | 1 + .../src/auth/DispatchStrategy.ts | 12 +- .../src/auth/GoogleServiceAccountStrategy.ts | 11 +- .../src/auth/GoogleStrategy.ts | 13 +- .../src/auth/OidcStrategy.ts | 12 +- .../src/auth/ServiceAccountStrategy.ts | 12 +- .../ConfigClusterLocator.test.ts | 1 + .../src/cluster-locator/index.test.ts | 1 + .../src/service/KubernetesBuilder.test.ts | 966 ++++++++++-------- .../src/service/KubernetesBuilder.ts | 22 +- .../service/KubernetesFanOutHandler.test.ts | 2 + .../src/service/KubernetesProxy.test.ts | 2 + plugins/kubernetes-node/api-report.md | 2 + plugins/kubernetes-node/src/types/types.ts | 1 + 20 files changed, 743 insertions(+), 472 deletions(-) create mode 100644 .changeset/kind-clouds-fly.md diff --git a/.changeset/kind-clouds-fly.md b/.changeset/kind-clouds-fly.md new file mode 100644 index 0000000000..7d8d7c4a0e --- /dev/null +++ b/.changeset/kind-clouds-fly.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +'@backstage/plugin-kubernetes-node': patch +--- + +Enabled a way to include custom auth metadata info on the clusters endpoint diff --git a/plugins/kubernetes-backend/api-report.md b/plugins/kubernetes-backend/api-report.md index e6996484dd..afdb3bcf9a 100644 --- a/plugins/kubernetes-backend/api-report.md +++ b/plugins/kubernetes-backend/api-report.md @@ -4,6 +4,7 @@ ```ts import { AuthenticationStrategy as AuthenticationStrategy_2 } from '@backstage/plugin-kubernetes-node'; +import { AuthMetadata as AuthMetadata_2 } from '@backstage/plugin-kubernetes-node'; import { CatalogApi } from '@backstage/catalog-client'; import { ClusterDetails as ClusterDetails_2 } from '@backstage/plugin-kubernetes-node'; import { Config } from '@backstage/config'; @@ -12,9 +13,12 @@ import { Duration } from 'luxon'; import express from 'express'; import * as k8sAuthTypes from '@backstage/plugin-kubernetes-node'; import { KubernetesClustersSupplier as KubernetesClustersSupplier_2 } from '@backstage/plugin-kubernetes-node'; +import { KubernetesCredential as KubernetesCredential_2 } from '@backstage/plugin-kubernetes-node'; +import { KubernetesFetcher as KubernetesFetcher_2 } from '@backstage/plugin-kubernetes-node'; import { KubernetesObjectsProvider as KubernetesObjectsProvider_2 } from '@backstage/plugin-kubernetes-node'; import { KubernetesRequestAuth } from '@backstage/plugin-kubernetes-common'; import type { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; +import { KubernetesServiceLocator as KubernetesServiceLocator_2 } from '@backstage/plugin-kubernetes-node'; import { Logger } from 'winston'; import { ObjectToFetch as ObjectToFetch_2 } from '@backstage/plugin-kubernetes-node'; import { PermissionEvaluator } from '@backstage/plugin-permission-common'; @@ -23,20 +27,24 @@ import { RequestHandler } from 'http-proxy-middleware'; import { TokenCredential } from '@azure/identity'; // @public (undocumented) -export class AksStrategy implements AuthenticationStrategy { +export class AksStrategy implements AuthenticationStrategy_2 { // (undocumented) getCredential( - _: ClusterDetails, + _: ClusterDetails_2, requestAuth: KubernetesRequestAuth, - ): Promise; + ): Promise; + // (undocumented) + presentAuthMetadata(_authMetadata: AuthMetadata_2): AuthMetadata_2; // (undocumented) validateCluster(): Error[]; } // @public (undocumented) -export class AnonymousStrategy implements AuthenticationStrategy { +export class AnonymousStrategy implements AuthenticationStrategy_2 { // (undocumented) - getCredential(): Promise; + getCredential(): Promise; + // (undocumented) + presentAuthMetadata(_authMetadata: AuthMetadata_2): AuthMetadata_2; // (undocumented) validateCluster(): Error[]; } @@ -48,19 +56,25 @@ export type AuthenticationStrategy = k8sAuthTypes.AuthenticationStrategy; export type AuthMetadata = k8sAuthTypes.AuthMetadata; // @public (undocumented) -export class AwsIamStrategy implements AuthenticationStrategy { +export class AwsIamStrategy implements AuthenticationStrategy_2 { constructor(opts: { config: Config }); // (undocumented) - getCredential(clusterDetails: ClusterDetails): Promise; + getCredential( + clusterDetails: ClusterDetails_2, + ): Promise; + // (undocumented) + presentAuthMetadata(_authMetadata: AuthMetadata_2): AuthMetadata_2; // (undocumented) validateCluster(): Error[]; } // @public (undocumented) -export class AzureIdentityStrategy implements AuthenticationStrategy { +export class AzureIdentityStrategy implements AuthenticationStrategy_2 { constructor(logger: Logger, tokenCredential?: TokenCredential); // (undocumented) - getCredential(): Promise; + getCredential(): Promise; + // (undocumented) + presentAuthMetadata(_authMetadata: AuthMetadata_2): AuthMetadata_2; // (undocumented) validateCluster(): Error[]; } @@ -81,21 +95,23 @@ export type CustomResourcesByEntity = k8sAuthTypes.CustomResourcesByEntity; export const DEFAULT_OBJECTS: ObjectToFetch[]; // @public -export class DispatchStrategy implements AuthenticationStrategy { +export class DispatchStrategy implements AuthenticationStrategy_2 { constructor(options: DispatchStrategyOptions); // (undocumented) getCredential( - clusterDetails: ClusterDetails, + clusterDetails: ClusterDetails_2, auth: KubernetesRequestAuth, - ): Promise; + ): Promise; // (undocumented) - validateCluster(authMetadata: AuthMetadata): Error[]; + presentAuthMetadata(_authMetadata: AuthMetadata_2): AuthMetadata_2; + // (undocumented) + validateCluster(authMetadata: AuthMetadata_2): Error[]; } // @public (undocumented) export type DispatchStrategyOptions = { authStrategyMap: { - [key: string]: AuthenticationStrategy; + [key: string]: AuthenticationStrategy_2; }; }; @@ -103,20 +119,24 @@ export type DispatchStrategyOptions = { export type FetchResponseWrapper = k8sAuthTypes.FetchResponseWrapper; // @public (undocumented) -export class GoogleServiceAccountStrategy implements AuthenticationStrategy { +export class GoogleServiceAccountStrategy implements AuthenticationStrategy_2 { // (undocumented) - getCredential(): Promise; + getCredential(): Promise; + // (undocumented) + presentAuthMetadata(_authMetadata: AuthMetadata_2): AuthMetadata_2; // (undocumented) validateCluster(): Error[]; } // @public (undocumented) -export class GoogleStrategy implements AuthenticationStrategy { +export class GoogleStrategy implements AuthenticationStrategy_2 { // (undocumented) getCredential( - _: ClusterDetails, + _: ClusterDetails_2, requestAuth: KubernetesRequestAuth, - ): Promise; + ): Promise; + // (undocumented) + presentAuthMetadata(_authMetadata: AuthMetadata_2): AuthMetadata_2; // (undocumented) validateCluster(): Error[]; } @@ -131,7 +151,7 @@ export const HEADER_KUBERNETES_CLUSTER: string; export class KubernetesBuilder { constructor(env: KubernetesEnvironment); // (undocumented) - addAuthStrategy(key: string, strategy: AuthenticationStrategy): this; + addAuthStrategy(key: string, strategy: AuthenticationStrategy_2): this; // (undocumented) build(): KubernetesBuilderReturn; // (undocumented) @@ -145,15 +165,15 @@ export class KubernetesBuilder { // (undocumented) protected buildCustomResources(): CustomResource_2[]; // (undocumented) - protected buildFetcher(): KubernetesFetcher; + protected buildFetcher(): KubernetesFetcher_2; // (undocumented) protected buildHttpServiceLocator( _clusterSupplier: KubernetesClustersSupplier_2, - ): KubernetesServiceLocator; + ): KubernetesServiceLocator_2; // (undocumented) protected buildMultiTenantServiceLocator( clusterSupplier: KubernetesClustersSupplier_2, - ): KubernetesServiceLocator; + ): KubernetesServiceLocator_2; // (undocumented) protected buildObjectsProvider( options: KubernetesObjectsProviderOptions, @@ -175,11 +195,11 @@ export class KubernetesBuilder { protected buildServiceLocator( method: ServiceLocatorMethod, clusterSupplier: KubernetesClustersSupplier_2, - ): KubernetesServiceLocator; + ): KubernetesServiceLocator_2; // (undocumented) protected buildSingleTenantServiceLocator( clusterSupplier: KubernetesClustersSupplier_2, - ): KubernetesServiceLocator; + ): KubernetesServiceLocator_2; // (undocumented) static createBuilder(env: KubernetesEnvironment): KubernetesBuilder; // (undocumented) @@ -195,7 +215,7 @@ export class KubernetesBuilder { // (undocumented) protected getClusterSupplier(): KubernetesClustersSupplier_2; // (undocumented) - protected getFetcher(): KubernetesFetcher; + protected getFetcher(): KubernetesFetcher_2; // (undocumented) protected getObjectsProvider( options: KubernetesObjectsProviderOptions, @@ -208,38 +228,38 @@ export class KubernetesBuilder { clusterSupplier: KubernetesClustersSupplier_2, ): KubernetesProxy; // (undocumented) - protected getServiceLocator(): KubernetesServiceLocator; + protected getServiceLocator(): KubernetesServiceLocator_2; // (undocumented) protected getServiceLocatorMethod(): ServiceLocatorMethod; // (undocumented) setAuthStrategyMap(authStrategyMap: { - [key: string]: AuthenticationStrategy; + [key: string]: AuthenticationStrategy_2; }): void; // (undocumented) setClusterSupplier(clusterSupplier?: KubernetesClustersSupplier_2): this; // (undocumented) setDefaultClusterRefreshInterval(refreshInterval: Duration): this; // (undocumented) - setFetcher(fetcher?: KubernetesFetcher): this; + setFetcher(fetcher?: KubernetesFetcher_2): this; // (undocumented) setObjectsProvider(objectsProvider?: KubernetesObjectsProvider_2): this; // (undocumented) setProxy(proxy?: KubernetesProxy): this; // (undocumented) - setServiceLocator(serviceLocator?: KubernetesServiceLocator): this; + setServiceLocator(serviceLocator?: KubernetesServiceLocator_2): this; } // @public export type KubernetesBuilderReturn = Promise<{ router: express.Router; clusterSupplier: KubernetesClustersSupplier_2; - customResources: CustomResource[]; - fetcher: KubernetesFetcher; + customResources: CustomResource_2[]; + fetcher: KubernetesFetcher_2; proxy: KubernetesProxy; objectsProvider: KubernetesObjectsProvider_2; - serviceLocator: KubernetesServiceLocator; + serviceLocator: KubernetesServiceLocator_2; authStrategyMap: { - [key: string]: AuthenticationStrategy; + [key: string]: AuthenticationStrategy_2; }; }>; @@ -321,14 +341,16 @@ export type ObjectsByEntityRequest = KubernetesRequestBody; export type ObjectToFetch = k8sAuthTypes.ObjectToFetch; // @public (undocumented) -export class OidcStrategy implements AuthenticationStrategy { +export class OidcStrategy implements AuthenticationStrategy_2 { // (undocumented) getCredential( - clusterDetails: ClusterDetails, + clusterDetails: ClusterDetails_2, authConfig: KubernetesRequestAuth, - ): Promise; + ): Promise; // (undocumented) - validateCluster(authMetadata: AuthMetadata): Error[]; + presentAuthMetadata(_authMetadata: AuthMetadata_2): AuthMetadata_2; + // (undocumented) + validateCluster(authMetadata: AuthMetadata_2): Error[]; } // @public (undocumented) @@ -348,9 +370,13 @@ export interface RouterOptions { } // @public (undocumented) -export class ServiceAccountStrategy implements AuthenticationStrategy { +export class ServiceAccountStrategy implements AuthenticationStrategy_2 { // (undocumented) - getCredential(clusterDetails: ClusterDetails): Promise; + getCredential( + clusterDetails: ClusterDetails_2, + ): Promise; + // (undocumented) + presentAuthMetadata(_authMetadata: AuthMetadata_2): AuthMetadata_2; // (undocumented) validateCluster(): Error[]; } diff --git a/plugins/kubernetes-backend/src/auth/AksStrategy.ts b/plugins/kubernetes-backend/src/auth/AksStrategy.ts index 07bdf2efe0..40151314a8 100644 --- a/plugins/kubernetes-backend/src/auth/AksStrategy.ts +++ b/plugins/kubernetes-backend/src/auth/AksStrategy.ts @@ -13,8 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { ClusterDetails } from '../types/types'; -import { AuthenticationStrategy, KubernetesCredential } from './types'; +import { + AuthMetadata, + AuthenticationStrategy, + ClusterDetails, + KubernetesCredential, +} from '@backstage/plugin-kubernetes-node'; import { KubernetesRequestAuth } from '@backstage/plugin-kubernetes-common'; /** @@ -31,7 +35,12 @@ export class AksStrategy implements AuthenticationStrategy { ? { type: 'bearer token', token: token as string } : { type: 'anonymous' }; } + public validateCluster(): Error[] { return []; } + + public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata { + return {}; + } } diff --git a/plugins/kubernetes-backend/src/auth/AnonymousStrategy.ts b/plugins/kubernetes-backend/src/auth/AnonymousStrategy.ts index 30a9593773..0f1aad398a 100644 --- a/plugins/kubernetes-backend/src/auth/AnonymousStrategy.ts +++ b/plugins/kubernetes-backend/src/auth/AnonymousStrategy.ts @@ -14,7 +14,11 @@ * limitations under the License. */ -import { AuthenticationStrategy, KubernetesCredential } from './types'; +import { + AuthMetadata, + AuthenticationStrategy, + KubernetesCredential, +} from '@backstage/plugin-kubernetes-node'; /** * @@ -28,4 +32,8 @@ export class AnonymousStrategy implements AuthenticationStrategy { public validateCluster(): Error[] { return []; } + + public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata { + return {}; + } } diff --git a/plugins/kubernetes-backend/src/auth/AwsIamStrategy.ts b/plugins/kubernetes-backend/src/auth/AwsIamStrategy.ts index 53b880d60c..942b93615f 100644 --- a/plugins/kubernetes-backend/src/auth/AwsIamStrategy.ts +++ b/plugins/kubernetes-backend/src/auth/AwsIamStrategy.ts @@ -25,8 +25,12 @@ import { ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE, ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID, } from '@backstage/plugin-kubernetes-common'; -import { ClusterDetails } from '../types/types'; -import { AuthenticationStrategy, KubernetesCredential } from './types'; +import { + AuthMetadata, + AuthenticationStrategy, + ClusterDetails, + KubernetesCredential, +} from '@backstage/plugin-kubernetes-node'; /** * @@ -128,4 +132,8 @@ export class AwsIamStrategy implements AuthenticationStrategy { return `k8s-aws-v1.${Buffer.from(url).toString('base64url')}`; } + + public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata { + return {}; + } } diff --git a/plugins/kubernetes-backend/src/auth/AzureIdentityStrategy.ts b/plugins/kubernetes-backend/src/auth/AzureIdentityStrategy.ts index d0eea3c13c..a1b29a10a1 100644 --- a/plugins/kubernetes-backend/src/auth/AzureIdentityStrategy.ts +++ b/plugins/kubernetes-backend/src/auth/AzureIdentityStrategy.ts @@ -15,12 +15,16 @@ */ import { Logger } from 'winston'; -import { AuthenticationStrategy, KubernetesCredential } from './types'; import { AccessToken, DefaultAzureCredential, TokenCredential, } from '@azure/identity'; +import { + AuthMetadata, + AuthenticationStrategy, + KubernetesCredential, +} from '@backstage/plugin-kubernetes-node'; const aksScope = '6dae42f8-4368-4678-94ff-3960e28e3630/.default'; // This scope is the same for all Azure Managed Kubernetes @@ -89,4 +93,8 @@ export class AzureIdentityStrategy implements AuthenticationStrategy { private tokenExpired(): boolean { return Date.now() >= this.accessToken.expiresOnTimestamp; } + + public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata { + return {}; + } } diff --git a/plugins/kubernetes-backend/src/auth/DispatchStrategy.test.ts b/plugins/kubernetes-backend/src/auth/DispatchStrategy.test.ts index 7202311d6f..773e464168 100644 --- a/plugins/kubernetes-backend/src/auth/DispatchStrategy.test.ts +++ b/plugins/kubernetes-backend/src/auth/DispatchStrategy.test.ts @@ -31,6 +31,7 @@ describe('getCredential', () => { mockStrategy = { getCredential: jest.fn(), validateCluster: jest.fn(), + presentAuthMetadata: jest.fn(), }; strategy = new DispatchStrategy({ authStrategyMap: { google: mockStrategy }, diff --git a/plugins/kubernetes-backend/src/auth/DispatchStrategy.ts b/plugins/kubernetes-backend/src/auth/DispatchStrategy.ts index f12e49b577..14a3009a65 100644 --- a/plugins/kubernetes-backend/src/auth/DispatchStrategy.ts +++ b/plugins/kubernetes-backend/src/auth/DispatchStrategy.ts @@ -14,12 +14,16 @@ * limitations under the License. */ -import { AuthenticationStrategy, KubernetesCredential } from './types'; -import { AuthMetadata, ClusterDetails } from '../types'; import { ANNOTATION_KUBERNETES_AUTH_PROVIDER, KubernetesRequestAuth, } from '@backstage/plugin-kubernetes-common'; +import { + AuthMetadata, + AuthenticationStrategy, + ClusterDetails, + KubernetesCredential, +} from '@backstage/plugin-kubernetes-node'; /** * @@ -67,4 +71,8 @@ export class DispatchStrategy implements AuthenticationStrategy { } return strategy.validateCluster(authMetadata); } + + public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata { + return {}; + } } diff --git a/plugins/kubernetes-backend/src/auth/GoogleServiceAccountStrategy.ts b/plugins/kubernetes-backend/src/auth/GoogleServiceAccountStrategy.ts index 2a44a31d6c..f6757d6a64 100644 --- a/plugins/kubernetes-backend/src/auth/GoogleServiceAccountStrategy.ts +++ b/plugins/kubernetes-backend/src/auth/GoogleServiceAccountStrategy.ts @@ -13,7 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { AuthenticationStrategy, KubernetesCredential } from './types'; + +import { + AuthMetadata, + AuthenticationStrategy, + KubernetesCredential, +} from '@backstage/plugin-kubernetes-node'; import * as container from '@google-cloud/container'; /** @@ -36,4 +41,8 @@ export class GoogleServiceAccountStrategy implements AuthenticationStrategy { public validateCluster(): Error[] { return []; } + + public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata { + return {}; + } } diff --git a/plugins/kubernetes-backend/src/auth/GoogleStrategy.ts b/plugins/kubernetes-backend/src/auth/GoogleStrategy.ts index c1290dc1fe..c48086f7f8 100644 --- a/plugins/kubernetes-backend/src/auth/GoogleStrategy.ts +++ b/plugins/kubernetes-backend/src/auth/GoogleStrategy.ts @@ -14,9 +14,13 @@ * limitations under the License. */ -import { AuthenticationStrategy, KubernetesCredential } from './types'; -import { ClusterDetails } from '../types/types'; import { KubernetesRequestAuth } from '@backstage/plugin-kubernetes-common'; +import { + AuthMetadata, + AuthenticationStrategy, + ClusterDetails, + KubernetesCredential, +} from '@backstage/plugin-kubernetes-node'; /** * @@ -35,7 +39,12 @@ export class GoogleStrategy implements AuthenticationStrategy { } return { type: 'bearer token', token: token as string }; } + public validateCluster(): Error[] { return []; } + + public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata { + return {}; + } } diff --git a/plugins/kubernetes-backend/src/auth/OidcStrategy.ts b/plugins/kubernetes-backend/src/auth/OidcStrategy.ts index 445799cbb8..1039f1d40c 100644 --- a/plugins/kubernetes-backend/src/auth/OidcStrategy.ts +++ b/plugins/kubernetes-backend/src/auth/OidcStrategy.ts @@ -18,8 +18,12 @@ import { ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER, KubernetesRequestAuth, } from '@backstage/plugin-kubernetes-common'; -import { AuthenticationStrategy, KubernetesCredential } from './types'; -import { AuthMetadata, ClusterDetails } from '../types/types'; +import { + AuthMetadata, + AuthenticationStrategy, + ClusterDetails, + KubernetesCredential, +} from '@backstage/plugin-kubernetes-node'; /** * @@ -57,4 +61,8 @@ export class OidcStrategy implements AuthenticationStrategy { } return []; } + + public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata { + return {}; + } } diff --git a/plugins/kubernetes-backend/src/auth/ServiceAccountStrategy.ts b/plugins/kubernetes-backend/src/auth/ServiceAccountStrategy.ts index 714b2a94d1..aff6e61a64 100644 --- a/plugins/kubernetes-backend/src/auth/ServiceAccountStrategy.ts +++ b/plugins/kubernetes-backend/src/auth/ServiceAccountStrategy.ts @@ -14,10 +14,14 @@ * limitations under the License. */ +import { + AuthMetadata, + AuthenticationStrategy, + ClusterDetails, + KubernetesCredential, +} from '@backstage/plugin-kubernetes-node'; import { KubeConfig, User } from '@kubernetes/client-node'; import fs from 'fs-extra'; -import { AuthenticationStrategy, KubernetesCredential } from './types'; -import { ClusterDetails } from '../types/types'; /** * @@ -45,4 +49,8 @@ export class ServiceAccountStrategy implements AuthenticationStrategy { public validateCluster(): Error[] { return []; } + + public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata { + return {}; + } } diff --git a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts index 1720ef5ed6..ad3203a16d 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts @@ -32,6 +32,7 @@ describe('ConfigClusterLocator', () => { authStrategy = { getCredential: jest.fn(), validateCluster: jest.fn().mockReturnValue([]), + presentAuthMetadata: jest.fn(), }; }); diff --git a/plugins/kubernetes-backend/src/cluster-locator/index.test.ts b/plugins/kubernetes-backend/src/cluster-locator/index.test.ts index ded0faac5b..beb9fc9cfe 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/index.test.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/index.test.ts @@ -53,6 +53,7 @@ describe('getCombinedClusterSupplier', () => { const mockStrategy: jest.Mocked = { getCredential: jest.fn(), validateCluster: jest.fn().mockReturnValue([]), + presentAuthMetadata: jest.fn(), }; const clusterSupplier = getCombinedClusterSupplier( diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts index 42f953a2fe..5030adaa81 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts @@ -16,6 +16,9 @@ import { ANNOTATION_KUBERNETES_AUTH_PROVIDER, + ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE, + ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID, + ANNOTATION_KUBERNETES_DASHBOARD_URL, ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER, KubernetesRequestAuth, } from '@backstage/plugin-kubernetes-common'; @@ -50,6 +53,7 @@ import { kubernetesObjectsProviderExtensionPoint, kubernetesFetcherExtensionPoint, kubernetesServiceLocatorExtensionPoint, + AuthMetadata, } from '@backstage/plugin-kubernetes-node'; import { ExtendedHttpServer } from '@backstage/backend-app-api'; @@ -177,151 +181,75 @@ describe('API integration tests', () => { ], }); }); - }); - describe('post /services/:serviceId', () => { - it('happy path: lists kubernetes objects without auth in request body', async () => { - const response = await request(app).post( - '/api/kubernetes/services/test-service', - ); - expect(response.status).toEqual(200); - expect(response.body).toEqual(happyK8SResult); - }); - - it('happy path: lists kubernetes objects with auth in request body', async () => { - const response = await request(app) - .post('/api/kubernetes/services/test-service') - .send({ auth: { google: 'google_token_123' } }) - .set('Content-Type', 'application/json'); - expect(response.status).toEqual(200); - expect(response.body).toEqual(happyK8SResult); - }); - - it('internal error: lists kubernetes objects', async () => { - objectsProviderMock.getKubernetesObjectsByEntity.mockRejectedValue( - Error('some internal error'), - ); - - const response = await request(app).post( - '/api/kubernetes/services/test-service', - ); - - expect(response.status).toEqual(500); - expect(response.body).toEqual({ error: 'some internal error' }); - }); - - it('custom service locator', async () => { - const someCluster = { - name: 'some-cluster', - url: 'https://localhost:1234', - authMetadata: { - [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount', - serviceAccountToken: 'placeholder-token', - }, - }; - const clusters: ClusterDetails[] = [ - someCluster, - { - name: 'some-other-cluster', - url: 'https://localhost:1235', - authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'google' }, - }, - ]; - - const pod = { metadata: { name: 'pod1' } }; - - const mockServiceLocator: jest.Mocked = { - getClustersByEntity: jest.fn().mockResolvedValue({ - clusters: [someCluster], - }), - }; - - const mockFetcher: jest.Mocked = { - fetchPodMetricsByNamespaces: jest + it('happy path: lists clusters with custom AuthStrategy and custom auth metadata', async () => { + objectsProviderMock = { + getKubernetesObjectsByEntity: jest .fn() - .mockResolvedValue({ errors: [], responses: [] }), - fetchObjectsForService: jest.fn().mockResolvedValue({ - errors: [], - responses: [{ type: 'pods', resources: [pod] }], - }), + .mockResolvedValue(happyK8SResult), + getCustomResourcesByEntity: jest.fn().mockResolvedValue(happyK8SResult), }; - const { server } = await startTestBackend({ - features: [ - minimalValidConfigService, - import('@backstage/plugin-kubernetes-backend/alpha'), - withClusters(clusters), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testFetcher', - register(env) { - env.registerInit({ - deps: { extension: kubernetesFetcherExtensionPoint }, - async init({ extension }) { - extension.addFetcher(mockFetcher); - }, - }); - }, - }), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testServiceLocator', - register(env) { - env.registerInit({ - deps: { extension: kubernetesServiceLocatorExtensionPoint }, - async init({ extension }) { - extension.addServiceLocator(mockServiceLocator); - }, - }); - }, - }), - ], - }); - app = server; - - const response = await request(app) - .post('/api/kubernetes/services/test-service') - .send({ entity: { metadata: { name: 'thing' } } }); - - expect(response.body).toEqual({ - items: [ - { - cluster: { name: someCluster.name }, - errors: [], - podMetrics: [], - resources: [{ type: 'pods', resources: [pod] }], - }, - ], - }); - expect(response.status).toEqual(200); - }); - - it('reads auth data for custom strategy', async () => { - const mockFetcher = { - fetchPodMetricsByNamespaces: jest - .fn() - .mockResolvedValue({ errors: [], responses: [] }), - fetchObjectsForService: jest.fn().mockResolvedValue({ - errors: [], - responses: [ - { type: 'pods', resources: [{ metadata: { name: 'pod1' } }] }, - ], - }), - }; - - const { server } = await startTestBackend({ - features: [ - minimalValidConfigService, - import('@backstage/plugin-kubernetes-backend/alpha'), - withClusters([ + const clusterSupplierMock = { + getClusters: jest.fn().mockResolvedValue( + Promise.resolve([ { - name: 'custom-cluster', - url: 'http://my.cluster.url', + name: 'some-cluster', + url: 'https://localhost:1234', authMetadata: { - [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'custom', + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'customAuth', + [ANNOTATION_KUBERNETES_DASHBOARD_URL]: + 'https://127.0.0.1:8443/dashboard', + [ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID]: '12650152165654', + [ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE]: 'my_aws_role', }, }, ]), + ), + }; + + const { server } = await startTestBackend({ + features: [ + mockServices.rootConfig.factory({ + data: { + kubernetes: { + serviceLocatorMethod: { + type: 'multiTenant', + }, + clusterLocatorMethods: [ + { + type: 'config', + clusters: [], + }, + ], + }, + }, + }), + import('@backstage/plugin-kubernetes-backend/alpha'), + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testObjectsProvider', + register(env) { + env.registerInit({ + deps: { extension: kubernetesObjectsProviderExtensionPoint }, + async init({ extension }) { + extension.addObjectsProvider(objectsProviderMock); + }, + }); + }, + }), + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testClusterSupplier', + register(env) { + env.registerInit({ + deps: { extension: kubernetesClusterSupplierExtensionPoint }, + async init({ extension }) { + extension.addClusterSupplier(clusterSupplierMock); + }, + }); + }, + }), createBackendModule({ pluginId: 'kubernetes', moduleId: 'testAuthStrategy', @@ -329,7 +257,7 @@ describe('API integration tests', () => { env.registerInit({ deps: { extension: kubernetesAuthStrategyExtensionPoint }, async init({ extension }) { - extension.addAuthStrategy('custom', { + extension.addAuthStrategy('customAuth', { getCredential: jest .fn< Promise, @@ -340,322 +268,538 @@ describe('API integration tests', () => { token: requestAuth.custom as string, })), validateCluster: jest.fn().mockReturnValue([]), + presentAuthMetadata: ( + authMetadata: AuthMetadata, + ): AuthMetadata => { + const authMetadataFilter = Object.entries(authMetadata) + .filter(([key, _value]) => { + return [ + ANNOTATION_KUBERNETES_DASHBOARD_URL, + ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE, + ].includes(key); + }) + .reduce( + ( + accumulator: AuthMetadata, + currentValue: [string, string], + ) => { + accumulator[currentValue[0]] = currentValue[1]; + return accumulator; + }, + {}, + ); + + return authMetadataFilter; + }, }); }, }); }, }), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testFetcher', - register(env) { - env.registerInit({ - deps: { extension: kubernetesFetcherExtensionPoint }, - async init({ extension }) { - extension.addFetcher(mockFetcher); - }, - }); - }, - }), ], }); + }); - app = server; + describe('post /services/:serviceId', () => { + it('happy path: lists kubernetes objects without auth in request body', async () => { + const response = await request(app).post( + '/api/kubernetes/services/test-service', + ); + expect(response.status).toEqual(200); + expect(response.body).toEqual(happyK8SResult); + }); - await request(app) - .post('/api/kubernetes/services/test-service') - .send({ - entity: { metadata: { name: 'thing' } }, - auth: { custom: 'custom-token' }, + it('happy path: lists kubernetes objects with auth in request body', async () => { + const response = await request(app) + .post('/api/kubernetes/services/test-service') + .send({ auth: { google: 'google_token_123' } }) + .set('Content-Type', 'application/json'); + expect(response.status).toEqual(200); + expect(response.body).toEqual(happyK8SResult); + }); + + it('internal error: lists kubernetes objects', async () => { + objectsProviderMock.getKubernetesObjectsByEntity.mockRejectedValue( + Error('some internal error'), + ); + + const response = await request(app).post( + '/api/kubernetes/services/test-service', + ); + + expect(response.status).toEqual(500); + expect(response.body).toEqual({ error: 'some internal error' }); + }); + + it('custom service locator', async () => { + const someCluster = { + name: 'some-cluster', + url: 'https://localhost:1234', + authMetadata: { + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount', + serviceAccountToken: 'placeholder-token', + }, + }; + const clusters: ClusterDetails[] = [ + someCluster, + { + name: 'some-other-cluster', + url: 'https://localhost:1235', + authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'google' }, + }, + ]; + + const pod = { metadata: { name: 'pod1' } }; + + const mockServiceLocator: jest.Mocked = { + getClustersByEntity: jest.fn().mockResolvedValue({ + clusters: [someCluster], + }), + }; + + const mockFetcher: jest.Mocked = { + fetchPodMetricsByNamespaces: jest + .fn() + .mockResolvedValue({ errors: [], responses: [] }), + fetchObjectsForService: jest.fn().mockResolvedValue({ + errors: [], + responses: [{ type: 'pods', resources: [pod] }], + }), + }; + + const { server } = await startTestBackend({ + features: [ + minimalValidConfigService, + import('@backstage/plugin-kubernetes-backend/alpha'), + withClusters(clusters), + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testFetcher', + register(env) { + env.registerInit({ + deps: { extension: kubernetesFetcherExtensionPoint }, + async init({ extension }) { + extension.addFetcher(mockFetcher); + }, + }); + }, + }), + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testServiceLocator', + register(env) { + env.registerInit({ + deps: { extension: kubernetesServiceLocatorExtensionPoint }, + async init({ extension }) { + extension.addServiceLocator(mockServiceLocator); + }, + }); + }, + }), + ], + }); + app = server; + + const response = await request(app) + .post('/api/kubernetes/services/test-service') + .send({ entity: { metadata: { name: 'thing' } } }); + + expect(response.body).toEqual({ + items: [ + { + cluster: { name: someCluster.name }, + errors: [], + podMetrics: [], + resources: [{ type: 'pods', resources: [pod] }], + }, + ], + }); + expect(response.status).toEqual(200); + }); + + it('reads auth data for custom strategy', async () => { + const mockFetcher = { + fetchPodMetricsByNamespaces: jest + .fn() + .mockResolvedValue({ errors: [], responses: [] }), + fetchObjectsForService: jest.fn().mockResolvedValue({ + errors: [], + responses: [ + { type: 'pods', resources: [{ metadata: { name: 'pod1' } }] }, + ], + }), + }; + + const { server } = await startTestBackend({ + features: [ + minimalValidConfigService, + import('@backstage/plugin-kubernetes-backend/alpha'), + withClusters([ + { + name: 'custom-cluster', + url: 'http://my.cluster.url', + authMetadata: { + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'custom', + }, + }, + ]), + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testAuthStrategy', + register(env) { + env.registerInit({ + deps: { extension: kubernetesAuthStrategyExtensionPoint }, + async init({ extension }) { + extension.addAuthStrategy('custom', { + getCredential: jest + .fn< + Promise, + [ClusterDetails, KubernetesRequestAuth] + >() + .mockImplementation(async (_, requestAuth) => ({ + type: 'bearer token', + token: requestAuth.custom as string, + })), + validateCluster: jest.fn().mockReturnValue([]), + presentAuthMetadata: jest.fn().mockReturnValue({}), + }); + }, + }); + }, + }), + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testFetcher', + register(env) { + env.registerInit({ + deps: { extension: kubernetesFetcherExtensionPoint }, + async init({ extension }) { + extension.addFetcher(mockFetcher); + }, + }); + }, + }), + ], }); - expect(mockFetcher.fetchObjectsForService).toHaveBeenCalledWith( - expect.objectContaining({ - credential: { type: 'bearer token', token: 'custom-token' }, - }), - ); - }); - }); + app = server; - describe('/proxy', () => { - const worker = setupServer(); - setupRequestMockHandlers(worker); + await request(app) + .post('/api/kubernetes/services/test-service') + .send({ + entity: { metadata: { name: 'thing' } }, + auth: { custom: 'custom-token' }, + }); - beforeEach(() => { - worker.use( - rest.post( - 'https://localhost:1234/api/v1/namespaces', - (req, res, ctx) => { - if (!req.headers.get('Authorization')) { - return res(ctx.status(401)); - } - return req - .arrayBuffer() - .then(body => - res( - ctx.set('content-type', `${req.headers.get('content-type')}`), - ctx.body(body), - ), - ); - }, - ), - ); + expect(mockFetcher.fetchObjectsForService).toHaveBeenCalledWith( + expect.objectContaining({ + credential: { type: 'bearer token', token: 'custom-token' }, + }), + ); + }); }); - it('forwards request body to k8s', async () => { - const namespaceManifest = { - kind: 'Namespace', - apiVersion: 'v1', - metadata: { name: 'new-ns' }, - }; + describe('/proxy', () => { + const worker = setupServer(); + setupRequestMockHandlers(worker); - const proxyEndpointRequest = request(app) - .post('/api/kubernetes/proxy/api/v1/namespaces') - .set(HEADER_KUBERNETES_CLUSTER, 'some-cluster') - .set(HEADER_KUBERNETES_AUTH, 'randomtoken') - .send(namespaceManifest); - worker.use(rest.all(proxyEndpointRequest.url, req => req.passthrough())); - const response = await proxyEndpointRequest; + beforeEach(() => { + worker.use( + rest.post( + 'https://localhost:1234/api/v1/namespaces', + (req, res, ctx) => { + if (!req.headers.get('Authorization')) { + return res(ctx.status(401)); + } + return req + .arrayBuffer() + .then(body => + res( + ctx.set( + 'content-type', + `${req.headers.get('content-type')}`, + ), + ctx.body(body), + ), + ); + }, + ), + ); + }); - expect(response.body).toStrictEqual(namespaceManifest); - }); + it('forwards request body to k8s', async () => { + const namespaceManifest = { + kind: 'Namespace', + apiVersion: 'v1', + metadata: { name: 'new-ns' }, + }; - it('supports yaml content type', async () => { - const yamlManifest = `--- + const proxyEndpointRequest = request(app) + .post('/api/kubernetes/proxy/api/v1/namespaces') + .set(HEADER_KUBERNETES_CLUSTER, 'some-cluster') + .set(HEADER_KUBERNETES_AUTH, 'randomtoken') + .send(namespaceManifest); + worker.use( + rest.all(proxyEndpointRequest.url, req => req.passthrough()), + ); + const response = await proxyEndpointRequest; + + expect(response.body).toStrictEqual(namespaceManifest); + }); + + it('supports yaml content type', async () => { + const yamlManifest = `--- kind: Namespace apiVersion: v1 metadata: name: new-ns `; - const proxyEndpointRequest = request(app) - .post('/api/kubernetes/proxy/api/v1/namespaces') - .set(HEADER_KUBERNETES_CLUSTER, 'some-cluster') - .set(HEADER_KUBERNETES_AUTH, 'randomtoken') - .set('content-type', 'application/yaml') - .send(yamlManifest); + const proxyEndpointRequest = request(app) + .post('/api/kubernetes/proxy/api/v1/namespaces') + .set(HEADER_KUBERNETES_CLUSTER, 'some-cluster') + .set(HEADER_KUBERNETES_AUTH, 'randomtoken') + .set('content-type', 'application/yaml') + .send(yamlManifest); - worker.use(rest.all(proxyEndpointRequest.url, req => req.passthrough())); + worker.use( + rest.all(proxyEndpointRequest.url, req => req.passthrough()), + ); - const response = await proxyEndpointRequest; - expect(response.text).toEqual(yamlManifest); - }); - - it('returns 403 response when permission blocks endpoint', async () => { - permissionsMock.authorize.mockResolvedValue([ - { result: AuthorizeResult.DENY }, - ]); - - const { server } = await startTestBackend({ - features: [ - minimalValidConfigService, - permissionsMock.factory, - import('@backstage/plugin-kubernetes-backend/alpha'), - ], + const response = await proxyEndpointRequest; + expect(response.text).toEqual(yamlManifest); }); - app = server; - const proxyEndpointRequest = request(app) - .post('/api/kubernetes/proxy/api/v1/namespaces') - .set(HEADER_KUBERNETES_CLUSTER, 'some-cluster') - .set(HEADER_KUBERNETES_AUTH, 'randomtoken') - .send({ - kind: 'Namespace', - apiVersion: 'v1', - metadata: { name: 'new-ns' }, + it('returns 403 response when permission blocks endpoint', async () => { + permissionsMock.authorize.mockResolvedValue([ + { result: AuthorizeResult.DENY }, + ]); + + const { server } = await startTestBackend({ + features: [ + minimalValidConfigService, + permissionsMock.factory, + import('@backstage/plugin-kubernetes-backend/alpha'), + ], + }); + app = server; + + const proxyEndpointRequest = request(app) + .post('/api/kubernetes/proxy/api/v1/namespaces') + .set(HEADER_KUBERNETES_CLUSTER, 'some-cluster') + .set(HEADER_KUBERNETES_AUTH, 'randomtoken') + .send({ + kind: 'Namespace', + apiVersion: 'v1', + metadata: { name: 'new-ns' }, + }); + + worker.use( + rest.all(proxyEndpointRequest.url, req => req.passthrough()), + ); + + const response = await proxyEndpointRequest; + + expect(response.status).toEqual(403); + }); + + it('permits custom client-side auth strategy', async () => { + worker.use( + rest.get( + 'http://my.cluster.url/api/v1/namespaces', + (req, res, ctx) => { + if (req.headers.get('Authorization') !== 'custom-token') { + return res(ctx.status(401)); + } + return res(ctx.json({ items: [] })); + }, + ), + ); + + const { server } = await startTestBackend({ + features: [ + minimalValidConfigService, + import('@backstage/plugin-kubernetes-backend/alpha'), + withClusters([ + { + name: 'custom-cluster', + url: 'http://my.cluster.url', + authMetadata: { + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'custom', + }, + }, + ]), + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testAuthStrategy', + register(env) { + env.registerInit({ + deps: { extension: kubernetesAuthStrategyExtensionPoint }, + async init({ extension }) { + extension.addAuthStrategy('custom', { + getCredential: jest + .fn< + Promise, + [ClusterDetails, KubernetesRequestAuth] + >() + .mockResolvedValue({ type: 'anonymous' }), + validateCluster: jest.fn().mockReturnValue([]), + presentAuthMetadata: jest.fn().mockReturnValue({}), + }); + }, + }); + }, + }), + ], }); - worker.use(rest.all(proxyEndpointRequest.url, req => req.passthrough())); + const proxyEndpointRequest = request(server) + .get('/api/kubernetes/proxy/api/v1/namespaces') + .set(HEADER_KUBERNETES_CLUSTER, 'custom-cluster') + .set(HEADER_KUBERNETES_AUTH, 'custom-token'); + worker.use( + rest.all(proxyEndpointRequest.url, req => req.passthrough()), + ); + const response = await proxyEndpointRequest; - const response = await proxyEndpointRequest; - - expect(response.status).toEqual(403); - }); - - it('permits custom client-side auth strategy', async () => { - worker.use( - rest.get('http://my.cluster.url/api/v1/namespaces', (req, res, ctx) => { - if (req.headers.get('Authorization') !== 'custom-token') { - return res(ctx.status(401)); - } - return res(ctx.json({ items: [] })); - }), - ); - - const { server } = await startTestBackend({ - features: [ - minimalValidConfigService, - import('@backstage/plugin-kubernetes-backend/alpha'), - withClusters([ - { - name: 'custom-cluster', - url: 'http://my.cluster.url', - authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'custom' }, - }, - ]), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testAuthStrategy', - register(env) { - env.registerInit({ - deps: { extension: kubernetesAuthStrategyExtensionPoint }, - async init({ extension }) { - extension.addAuthStrategy('custom', { - getCredential: jest - .fn< - Promise, - [ClusterDetails, KubernetesRequestAuth] - >() - .mockResolvedValue({ type: 'anonymous' }), - validateCluster: jest.fn().mockReturnValue([]), - }); - }, - }); - }, - }), - ], + expect(response.body).toStrictEqual({ items: [] }); }); - const proxyEndpointRequest = request(server) - .get('/api/kubernetes/proxy/api/v1/namespaces') - .set(HEADER_KUBERNETES_CLUSTER, 'custom-cluster') - .set(HEADER_KUBERNETES_AUTH, 'custom-token'); - worker.use(rest.all(proxyEndpointRequest.url, req => req.passthrough())); - const response = await proxyEndpointRequest; - - expect(response.body).toStrictEqual({ items: [] }); - }); - - it('reads custom auth metadata from config', async () => { - const authStrategy = { - getCredential: jest.fn().mockResolvedValue({ type: 'anonymous' }), - validateCluster: jest.fn().mockReturnValue([]), - }; - worker.use( - rest.get('http://my.cluster/api', (_req, res, ctx) => - res(ctx.json({})), - ), - ); - const { server } = await startTestBackend({ - features: [ - mockServices.rootConfig.factory({ - data: { - kubernetes: { - serviceLocatorMethod: { type: 'multiTenant' }, - clusterLocatorMethods: [ - { - type: 'config', - clusters: [ - { - name: 'cluster', - url: 'http://my.cluster', - authProvider: 'custom', - authMetadata: { 'custom-key': 'custom-value' }, - }, - ], + it('reads custom auth metadata from config', async () => { + const authStrategy = { + getCredential: jest.fn().mockResolvedValue({ type: 'anonymous' }), + validateCluster: jest.fn().mockReturnValue([]), + presentAuthMetadata: jest.fn().mockReturnValue({}), + }; + worker.use( + rest.get('http://my.cluster/api', (_req, res, ctx) => + res(ctx.json({})), + ), + ); + const { server } = await startTestBackend({ + features: [ + mockServices.rootConfig.factory({ + data: { + kubernetes: { + serviceLocatorMethod: { type: 'multiTenant' }, + clusterLocatorMethods: [ + { + type: 'config', + clusters: [ + { + name: 'cluster', + url: 'http://my.cluster', + authProvider: 'custom', + authMetadata: { 'custom-key': 'custom-value' }, + }, + ], + }, + ], + }, + }, + }), + import('@backstage/plugin-kubernetes-backend/alpha'), + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testAuthStrategy', + register(env) { + env.registerInit({ + deps: { extension: kubernetesAuthStrategyExtensionPoint }, + async init({ extension }) { + extension.addAuthStrategy('custom', authStrategy); }, - ], + }); }, - }, + }), + ], + }); + app = server; + + const proxyEndpointRequest = request(app).get( + '/api/kubernetes/proxy/api', + ); + worker.use( + rest.all(proxyEndpointRequest.url, req => req.passthrough()), + ); + const response = await proxyEndpointRequest; + + expect(response.body).toStrictEqual({}); + expect(authStrategy.getCredential).toHaveBeenCalledWith( + expect.objectContaining({ + authMetadata: expect.objectContaining({ + 'custom-key': 'custom-value', + }), }), - import('@backstage/plugin-kubernetes-backend/alpha'), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testAuthStrategy', - register(env) { - env.registerInit({ - deps: { extension: kubernetesAuthStrategyExtensionPoint }, - async init({ extension }) { - extension.addAuthStrategy('custom', authStrategy); - }, - }); - }, - }), - ], + expect.anything(), + ); }); - app = server; + }); - const proxyEndpointRequest = request(app).get( - '/api/kubernetes/proxy/api', + it('forbids custom auth strategies with dashes', () => { + const throwError = () => + startTestBackend({ + features: [ + import('@backstage/plugin-kubernetes-backend/alpha'), + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testAuthStrategy', + register(env) { + env.registerInit({ + deps: { extension: kubernetesAuthStrategyExtensionPoint }, + async init({ extension }) { + extension.addAuthStrategy('custom-strategy', { + getCredential: jest + .fn< + Promise, + [ClusterDetails, KubernetesRequestAuth] + >() + .mockResolvedValue({ type: 'anonymous' }), + validateCluster: jest.fn().mockReturnValue([]), + presentAuthMetadata: jest.fn().mockReturnValue({}), + }); + }, + }); + }, + }), + ], + }); + return expect(throwError).rejects.toThrow( + 'Strategy name can not include dashes', ); - worker.use(rest.all(proxyEndpointRequest.url, req => req.passthrough())); - const response = await proxyEndpointRequest; + }); - expect(response.body).toStrictEqual({}); - expect(authStrategy.getCredential).toHaveBeenCalledWith( - expect.objectContaining({ - authMetadata: expect.objectContaining({ - 'custom-key': 'custom-value', - }), + it('serves permission integration endpoint', async () => { + const response = await request(app).get( + '/api/kubernetes/.well-known/backstage/permissions/metadata', + ); + + expect(response.status).toEqual(200); + expect(response.body).toMatchObject({ + permissions: [ + { type: 'basic', name: 'kubernetes.proxy', attributes: {} }, + ], + rules: [], + }); + }); + + it('fails when an unsupported serviceLocator type is specified', () => { + return expect(() => + startTestBackend({ + features: [ + mockServices.rootConfig.factory({ + data: { + kubernetes: { + serviceLocatorMethod: { type: 'unsupported' }, + clusterLocatorMethods: [{ type: 'config', clusters: [] }], + }, + }, + }), + import('@backstage/plugin-kubernetes-backend/alpha'), + ], }), - expect.anything(), + ).rejects.toThrow( + 'Unsupported kubernetes.serviceLocatorMethod "unsupported"', ); }); }); - - it('forbids custom auth strategies with dashes', () => { - const throwError = () => - startTestBackend({ - features: [ - import('@backstage/plugin-kubernetes-backend/alpha'), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testAuthStrategy', - register(env) { - env.registerInit({ - deps: { extension: kubernetesAuthStrategyExtensionPoint }, - async init({ extension }) { - extension.addAuthStrategy('custom-strategy', { - getCredential: jest - .fn< - Promise, - [ClusterDetails, KubernetesRequestAuth] - >() - .mockResolvedValue({ type: 'anonymous' }), - validateCluster: jest.fn().mockReturnValue([]), - }); - }, - }); - }, - }), - ], - }); - return expect(throwError).rejects.toThrow( - 'Strategy name can not include dashes', - ); - }); - - it('serves permission integration endpoint', async () => { - const response = await request(app).get( - '/api/kubernetes/.well-known/backstage/permissions/metadata', - ); - - expect(response.status).toEqual(200); - expect(response.body).toMatchObject({ - permissions: [ - { type: 'basic', name: 'kubernetes.proxy', attributes: {} }, - ], - rules: [], - }); - }); - - it('fails when an unsupported serviceLocator type is specified', () => { - return expect(() => - startTestBackend({ - features: [ - mockServices.rootConfig.factory({ - data: { - kubernetes: { - serviceLocatorMethod: { type: 'unsupported' }, - clusterLocatorMethods: [{ type: 'config', clusters: [] }], - }, - }, - }), - import('@backstage/plugin-kubernetes-backend/alpha'), - ], - }), - ).rejects.toThrow( - 'Unsupported kubernetes.serviceLocatorMethod "unsupported"', - ); - }); }); diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts index a4a577db85..81cc3d471d 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts @@ -29,7 +29,6 @@ import { Logger } from 'winston'; import { getCombinedClusterSupplier } from '../cluster-locator'; import { - AuthenticationStrategy, AnonymousStrategy, DispatchStrategy, GoogleStrategy, @@ -45,17 +44,19 @@ import { addResourceRoutesToRouter } from '../routes/resourcesRoutes'; import { MultiTenantServiceLocator } from '../service-locator/MultiTenantServiceLocator'; import { SingleTenantServiceLocator } from '../service-locator/SingleTenantServiceLocator'; import { - CustomResource, - KubernetesFetcher, KubernetesObjectsProviderOptions, - KubernetesObjectTypes, - KubernetesServiceLocator, ObjectsByEntityRequest, ServiceLocatorMethod, } from '../types/types'; import { + AuthenticationStrategy, + AuthMetadata, + CustomResource, KubernetesClustersSupplier, + KubernetesFetcher, KubernetesObjectsProvider, + KubernetesObjectTypes, + KubernetesServiceLocator, } from '@backstage/plugin-kubernetes-node'; import { DEFAULT_OBJECTS, @@ -369,11 +370,20 @@ export class KubernetesBuilder { items: clusterDetails.map(cd => { const oidcTokenProvider = cd.authMetadata[ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER]; + const authProvider = + cd.authMetadata[ANNOTATION_KUBERNETES_AUTH_PROVIDER]; + const strategy = this.getAuthStrategyMap()[authProvider]; + let auth: AuthMetadata = {}; + if (strategy) { + auth = strategy.presentAuthMetadata(cd.authMetadata); + } + return { name: cd.name, dashboardUrl: cd.dashboardUrl, - authProvider: cd.authMetadata[ANNOTATION_KUBERNETES_AUTH_PROVIDER], + authProvider, ...(oidcTokenProvider && { oidcTokenProvider }), + ...(auth && Object.keys(auth).length !== 0 && { auth }), }; }), }); diff --git a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts index 1faf2f0673..a50d0b37a2 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.test.ts @@ -196,6 +196,7 @@ describe('KubernetesFanOutHandler', () => { >() .mockResolvedValue({ type: 'anonymous' }), validateCluster: jest.fn().mockReturnValue([]), + presentAuthMetadata: jest.fn(), }, config, }); @@ -1147,6 +1148,7 @@ describe('KubernetesFanOutHandler', () => { >() .mockResolvedValue({ type: 'bearer token', token: 'token' }), validateCluster: jest.fn().mockReturnValue([]), + presentAuthMetadata: jest.fn(), }, config, }); diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts index 9bee21867d..a9f49be780 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts @@ -131,6 +131,7 @@ describe('KubernetesProxy', () => { >() .mockResolvedValue({ type: 'anonymous' }), validateCluster: jest.fn(), + presentAuthMetadata: jest.fn(), }; proxy = new KubernetesProxy({ logger, clusterSupplier, authStrategy }); permissionApi.authorize.mockResolvedValue([ @@ -514,6 +515,7 @@ describe('KubernetesProxy', () => { .fn() .mockReturnValue({ type: 'bearer token', token: 'MY_TOKEN3' }), validateCluster: jest.fn(), + presentAuthMetadata: jest.fn(), }; proxy = new KubernetesProxy({ diff --git a/plugins/kubernetes-node/api-report.md b/plugins/kubernetes-node/api-report.md index 2272035742..aba1cdd1ae 100644 --- a/plugins/kubernetes-node/api-report.md +++ b/plugins/kubernetes-node/api-report.md @@ -25,6 +25,8 @@ export interface AuthenticationStrategy { authConfig: KubernetesRequestAuth, ): Promise; // (undocumented) + presentAuthMetadata(authMetadata: AuthMetadata): AuthMetadata; + // (undocumented) validateCluster(authMetadata: AuthMetadata): Error[]; } diff --git a/plugins/kubernetes-node/src/types/types.ts b/plugins/kubernetes-node/src/types/types.ts index a0f48d0c26..34a3286eb7 100644 --- a/plugins/kubernetes-node/src/types/types.ts +++ b/plugins/kubernetes-node/src/types/types.ts @@ -151,6 +151,7 @@ export interface AuthenticationStrategy { authConfig: KubernetesRequestAuth, ): Promise; validateCluster(authMetadata: AuthMetadata): Error[]; + presentAuthMetadata(authMetadata: AuthMetadata): AuthMetadata; } /** From d158a7afe865c4e398c78858f89448298b571978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Mauricio=20G=C3=B3mez=20P?= Date: Wed, 10 Jan 2024 15:10:25 -0500 Subject: [PATCH 221/283] Update plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jamie Klassen Signed-off-by: Andrés Mauricio Gómez P Signed-off-by: Andres Mauricio Gomez P --- .changeset/kind-clouds-fly.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/kind-clouds-fly.md b/.changeset/kind-clouds-fly.md index 7d8d7c4a0e..2cb04b520d 100644 --- a/.changeset/kind-clouds-fly.md +++ b/.changeset/kind-clouds-fly.md @@ -3,4 +3,4 @@ '@backstage/plugin-kubernetes-node': patch --- -Enabled a way to include custom auth metadata info on the clusters endpoint +Enabled a way to include custom auth metadata info on the clusters endpoint. Ff you want to implement a Kubernetes auth strategy which requires surfacing custom auth metadata to the frontend, use the new presentAuthMetadata method on the AuthenticationStrategy interface From 9d7cae0fafbeb4655a300229665e91453b64a60b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 13:35:51 +0000 Subject: [PATCH 222/283] fix(deps): update dependency @swc/jest to v0.2.30 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 40 +++++++++------------------------------- 1 file changed, 9 insertions(+), 31 deletions(-) diff --git a/yarn.lock b/yarn.lock index ef4f1cbc43..d1d0a23206 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11754,12 +11754,12 @@ __metadata: languageName: node linkType: hard -"@jest/create-cache-key-function@npm:^27.4.2": - version: 27.5.1 - resolution: "@jest/create-cache-key-function@npm:27.5.1" +"@jest/create-cache-key-function@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/create-cache-key-function@npm:29.7.0" dependencies: - "@jest/types": ^27.5.1 - checksum: a6c3a8c769aca6f66f5dc80f1c77e66980b4f213a6b2a15a92ba3595f032848a1261c06c9c798dcf2b672b1ffbefad5085af89d130548741c85ddbe0cf4284e7 + "@jest/types": ^29.6.3 + checksum: 681bc761fa1d6fa3dd77578d444f97f28296ea80755e90e46d1c8fa68661b9e67f54dd38b988742db636d26cf160450dc6011892cec98b3a7ceb58cad8ff3aae languageName: node linkType: hard @@ -11942,19 +11942,6 @@ __metadata: languageName: node linkType: hard -"@jest/types@npm:^27.5.1": - version: 27.5.1 - resolution: "@jest/types@npm:27.5.1" - dependencies: - "@types/istanbul-lib-coverage": ^2.0.0 - "@types/istanbul-reports": ^3.0.0 - "@types/node": "*" - "@types/yargs": ^16.0.0 - chalk: ^4.0.0 - checksum: d1f43cc946d87543ddd79d49547aab2399481d34025d5c5f2025d3d99c573e1d9832fa83cef25e9d9b07a8583500229d15bbb07b8e233d127d911d133e2f14b1 - languageName: node - linkType: hard - "@jest/types@npm:^28.1.3": version: 28.1.3 resolution: "@jest/types@npm:28.1.3" @@ -16993,14 +16980,14 @@ __metadata: linkType: hard "@swc/jest@npm:^0.2.22": - version: 0.2.29 - resolution: "@swc/jest@npm:0.2.29" + version: 0.2.30 + resolution: "@swc/jest@npm:0.2.30" dependencies: - "@jest/create-cache-key-function": ^27.4.2 + "@jest/create-cache-key-function": ^29.7.0 jsonc-parser: ^3.2.0 peerDependencies: "@swc/core": "*" - checksum: 9eaad322310f34e81f67d41411a7d60663341af1bd9fb65456faa914c936d849d6f643fa3b942a187d52e71e62c33097098c639d25c2047fa874f49bf51cec76 + checksum: 8ce25300949b8dfedaadec866d056a511ae2791e5cbbc8008b7d086c9c29b1b727c3f42aade88e824aa8205616e9aab812f9fa83ab4384e72f49a469f503256b languageName: node linkType: hard @@ -19147,15 +19134,6 @@ __metadata: languageName: node linkType: hard -"@types/yargs@npm:^16.0.0": - version: 16.0.4 - resolution: "@types/yargs@npm:16.0.4" - dependencies: - "@types/yargs-parser": "*" - checksum: caa21d2c957592fe2184a8368c8cbe5a82a6c2e2f2893722e489f842dc5963293d2f3120bc06fe3933d60a3a0d1e2eb269649fd6b1947fe1820f8841ba611dd9 - languageName: node - linkType: hard - "@types/yargs@npm:^17.0.8": version: 17.0.12 resolution: "@types/yargs@npm:17.0.12" From 3abcc134bd296cd320f51e60ba1c691cc402bb45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Mauricio=20G=C3=B3mez=20P?= Date: Fri, 12 Jan 2024 10:55:20 -0500 Subject: [PATCH 223/283] Update .changeset/kind-clouds-fly.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jamie Klassen Signed-off-by: Andrés Mauricio Gómez P Signed-off-by: Andres Mauricio Gomez P --- .changeset/kind-clouds-fly.md | 2 +- .../src/service/KubernetesBuilder.test.ts | 1007 ++++++++--------- 2 files changed, 485 insertions(+), 524 deletions(-) diff --git a/.changeset/kind-clouds-fly.md b/.changeset/kind-clouds-fly.md index 2cb04b520d..22aa7cda33 100644 --- a/.changeset/kind-clouds-fly.md +++ b/.changeset/kind-clouds-fly.md @@ -3,4 +3,4 @@ '@backstage/plugin-kubernetes-node': patch --- -Enabled a way to include custom auth metadata info on the clusters endpoint. Ff you want to implement a Kubernetes auth strategy which requires surfacing custom auth metadata to the frontend, use the new presentAuthMetadata method on the AuthenticationStrategy interface +Enabled a way to include custom auth metadata info on the clusters endpoint. If you want to implement a Kubernetes auth strategy which requires surfacing custom auth metadata to the frontend, use the new presentAuthMetadata method on the AuthenticationStrategy interface. diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts index 5030adaa81..5d19c6d94d 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts @@ -47,13 +47,13 @@ import { createBackendModule, } from '@backstage/backend-plugin-api'; import { + AuthMetadata, KubernetesObjectsProvider, kubernetesAuthStrategyExtensionPoint, kubernetesClusterSupplierExtensionPoint, kubernetesObjectsProviderExtensionPoint, kubernetesFetcherExtensionPoint, kubernetesServiceLocatorExtensionPoint, - AuthMetadata, } from '@backstage/plugin-kubernetes-node'; import { ExtendedHttpServer } from '@backstage/backend-app-api'; @@ -183,48 +183,9 @@ describe('API integration tests', () => { }); it('happy path: lists clusters with custom AuthStrategy and custom auth metadata', async () => { - objectsProviderMock = { - getKubernetesObjectsByEntity: jest - .fn() - .mockResolvedValue(happyK8SResult), - getCustomResourcesByEntity: jest.fn().mockResolvedValue(happyK8SResult), - }; - - const clusterSupplierMock = { - getClusters: jest.fn().mockResolvedValue( - Promise.resolve([ - { - name: 'some-cluster', - url: 'https://localhost:1234', - authMetadata: { - [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'customAuth', - [ANNOTATION_KUBERNETES_DASHBOARD_URL]: - 'https://127.0.0.1:8443/dashboard', - [ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID]: '12650152165654', - [ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE]: 'my_aws_role', - }, - }, - ]), - ), - }; - const { server } = await startTestBackend({ features: [ - mockServices.rootConfig.factory({ - data: { - kubernetes: { - serviceLocatorMethod: { - type: 'multiTenant', - }, - clusterLocatorMethods: [ - { - type: 'config', - clusters: [], - }, - ], - }, - }, - }), + minimalValidConfigService, import('@backstage/plugin-kubernetes-backend/alpha'), createBackendModule({ pluginId: 'kubernetes', @@ -238,18 +199,19 @@ describe('API integration tests', () => { }); }, }), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testClusterSupplier', - register(env) { - env.registerInit({ - deps: { extension: kubernetesClusterSupplierExtensionPoint }, - async init({ extension }) { - extension.addClusterSupplier(clusterSupplierMock); - }, - }); + withClusters([ + { + name: 'some-cluster', + url: 'https://localhost:1234', + authMetadata: { + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'customAuth', + [ANNOTATION_KUBERNETES_DASHBOARD_URL]: + 'https://127.0.0.1:8443/dashboard', + [ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID]: '12650152165654', + [ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE]: 'my_aws_role', + }, }, - }), + ]), createBackendModule({ pluginId: 'kubernetes', moduleId: 'testAuthStrategy', @@ -298,508 +260,507 @@ describe('API integration tests', () => { }), ], }); - }); + app = server; - describe('post /services/:serviceId', () => { - it('happy path: lists kubernetes objects without auth in request body', async () => { - const response = await request(app).post( - '/api/kubernetes/services/test-service', - ); - expect(response.status).toEqual(200); - expect(response.body).toEqual(happyK8SResult); - }); + const response = await request(app).get('/api/kubernetes/clusters'); - it('happy path: lists kubernetes objects with auth in request body', async () => { - const response = await request(app) - .post('/api/kubernetes/services/test-service') - .send({ auth: { google: 'google_token_123' } }) - .set('Content-Type', 'application/json'); - expect(response.status).toEqual(200); - expect(response.body).toEqual(happyK8SResult); - }); - - it('internal error: lists kubernetes objects', async () => { - objectsProviderMock.getKubernetesObjectsByEntity.mockRejectedValue( - Error('some internal error'), - ); - - const response = await request(app).post( - '/api/kubernetes/services/test-service', - ); - - expect(response.status).toEqual(500); - expect(response.body).toEqual({ error: 'some internal error' }); - }); - - it('custom service locator', async () => { - const someCluster = { - name: 'some-cluster', - url: 'https://localhost:1234', - authMetadata: { - [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount', - serviceAccountToken: 'placeholder-token', - }, - }; - const clusters: ClusterDetails[] = [ - someCluster, + expect(response.status).toEqual(200); + expect(response.body).toStrictEqual({ + items: [ { - name: 'some-other-cluster', - url: 'https://localhost:1235', - authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'google' }, - }, - ]; - - const pod = { metadata: { name: 'pod1' } }; - - const mockServiceLocator: jest.Mocked = { - getClustersByEntity: jest.fn().mockResolvedValue({ - clusters: [someCluster], - }), - }; - - const mockFetcher: jest.Mocked = { - fetchPodMetricsByNamespaces: jest - .fn() - .mockResolvedValue({ errors: [], responses: [] }), - fetchObjectsForService: jest.fn().mockResolvedValue({ - errors: [], - responses: [{ type: 'pods', resources: [pod] }], - }), - }; - - const { server } = await startTestBackend({ - features: [ - minimalValidConfigService, - import('@backstage/plugin-kubernetes-backend/alpha'), - withClusters(clusters), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testFetcher', - register(env) { - env.registerInit({ - deps: { extension: kubernetesFetcherExtensionPoint }, - async init({ extension }) { - extension.addFetcher(mockFetcher); - }, - }); - }, - }), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testServiceLocator', - register(env) { - env.registerInit({ - deps: { extension: kubernetesServiceLocatorExtensionPoint }, - async init({ extension }) { - extension.addServiceLocator(mockServiceLocator); - }, - }); - }, - }), - ], - }); - app = server; - - const response = await request(app) - .post('/api/kubernetes/services/test-service') - .send({ entity: { metadata: { name: 'thing' } } }); - - expect(response.body).toEqual({ - items: [ - { - cluster: { name: someCluster.name }, - errors: [], - podMetrics: [], - resources: [{ type: 'pods', resources: [pod] }], + name: 'some-cluster', + authProvider: 'customAuth', + auth: { + 'kubernetes.io/aws-assume-role': 'my_aws_role', + 'kubernetes.io/dashboard-url': 'https://127.0.0.1:8443/dashboard', }, - ], - }); - expect(response.status).toEqual(200); - }); - - it('reads auth data for custom strategy', async () => { - const mockFetcher = { - fetchPodMetricsByNamespaces: jest - .fn() - .mockResolvedValue({ errors: [], responses: [] }), - fetchObjectsForService: jest.fn().mockResolvedValue({ - errors: [], - responses: [ - { type: 'pods', resources: [{ metadata: { name: 'pod1' } }] }, - ], - }), - }; - - const { server } = await startTestBackend({ - features: [ - minimalValidConfigService, - import('@backstage/plugin-kubernetes-backend/alpha'), - withClusters([ - { - name: 'custom-cluster', - url: 'http://my.cluster.url', - authMetadata: { - [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'custom', - }, - }, - ]), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testAuthStrategy', - register(env) { - env.registerInit({ - deps: { extension: kubernetesAuthStrategyExtensionPoint }, - async init({ extension }) { - extension.addAuthStrategy('custom', { - getCredential: jest - .fn< - Promise, - [ClusterDetails, KubernetesRequestAuth] - >() - .mockImplementation(async (_, requestAuth) => ({ - type: 'bearer token', - token: requestAuth.custom as string, - })), - validateCluster: jest.fn().mockReturnValue([]), - presentAuthMetadata: jest.fn().mockReturnValue({}), - }); - }, - }); - }, - }), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testFetcher', - register(env) { - env.registerInit({ - deps: { extension: kubernetesFetcherExtensionPoint }, - async init({ extension }) { - extension.addFetcher(mockFetcher); - }, - }); - }, - }), - ], - }); - - app = server; - - await request(app) - .post('/api/kubernetes/services/test-service') - .send({ - entity: { metadata: { name: 'thing' } }, - auth: { custom: 'custom-token' }, - }); - - expect(mockFetcher.fetchObjectsForService).toHaveBeenCalledWith( - expect.objectContaining({ - credential: { type: 'bearer token', token: 'custom-token' }, - }), - ); + }, + ], }); }); + }); - describe('/proxy', () => { - const worker = setupServer(); - setupRequestMockHandlers(worker); + describe('post /services/:serviceId', () => { + it('happy path: lists kubernetes objects without auth in request body', async () => { + const response = await request(app).post( + '/api/kubernetes/services/test-service', + ); + expect(response.status).toEqual(200); + expect(response.body).toEqual(happyK8SResult); + }); - beforeEach(() => { - worker.use( - rest.post( - 'https://localhost:1234/api/v1/namespaces', - (req, res, ctx) => { - if (!req.headers.get('Authorization')) { - return res(ctx.status(401)); - } - return req - .arrayBuffer() - .then(body => - res( - ctx.set( - 'content-type', - `${req.headers.get('content-type')}`, - ), - ctx.body(body), - ), - ); + it('happy path: lists kubernetes objects with auth in request body', async () => { + const response = await request(app) + .post('/api/kubernetes/services/test-service') + .send({ auth: { google: 'google_token_123' } }) + .set('Content-Type', 'application/json'); + expect(response.status).toEqual(200); + expect(response.body).toEqual(happyK8SResult); + }); + + it('internal error: lists kubernetes objects', async () => { + objectsProviderMock.getKubernetesObjectsByEntity.mockRejectedValue( + Error('some internal error'), + ); + + const response = await request(app).post( + '/api/kubernetes/services/test-service', + ); + + expect(response.status).toEqual(500); + expect(response.body).toEqual({ error: 'some internal error' }); + }); + + it('custom service locator', async () => { + const someCluster = { + name: 'some-cluster', + url: 'https://localhost:1234', + authMetadata: { + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'serviceAccount', + serviceAccountToken: 'placeholder-token', + }, + }; + const clusters: ClusterDetails[] = [ + someCluster, + { + name: 'some-other-cluster', + url: 'https://localhost:1235', + authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'google' }, + }, + ]; + + const pod = { metadata: { name: 'pod1' } }; + + const mockServiceLocator: jest.Mocked = { + getClustersByEntity: jest.fn().mockResolvedValue({ + clusters: [someCluster], + }), + }; + + const mockFetcher: jest.Mocked = { + fetchPodMetricsByNamespaces: jest + .fn() + .mockResolvedValue({ errors: [], responses: [] }), + fetchObjectsForService: jest.fn().mockResolvedValue({ + errors: [], + responses: [{ type: 'pods', resources: [pod] }], + }), + }; + + const { server } = await startTestBackend({ + features: [ + minimalValidConfigService, + import('@backstage/plugin-kubernetes-backend/alpha'), + withClusters(clusters), + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testFetcher', + register(env) { + env.registerInit({ + deps: { extension: kubernetesFetcherExtensionPoint }, + async init({ extension }) { + extension.addFetcher(mockFetcher); + }, + }); }, - ), - ); + }), + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testServiceLocator', + register(env) { + env.registerInit({ + deps: { extension: kubernetesServiceLocatorExtensionPoint }, + async init({ extension }) { + extension.addServiceLocator(mockServiceLocator); + }, + }); + }, + }), + ], + }); + app = server; + + const response = await request(app) + .post('/api/kubernetes/services/test-service') + .send({ entity: { metadata: { name: 'thing' } } }); + + expect(response.body).toEqual({ + items: [ + { + cluster: { name: someCluster.name }, + errors: [], + podMetrics: [], + resources: [{ type: 'pods', resources: [pod] }], + }, + ], + }); + expect(response.status).toEqual(200); + }); + + it('reads auth data for custom strategy', async () => { + const mockFetcher = { + fetchPodMetricsByNamespaces: jest + .fn() + .mockResolvedValue({ errors: [], responses: [] }), + fetchObjectsForService: jest.fn().mockResolvedValue({ + errors: [], + responses: [ + { type: 'pods', resources: [{ metadata: { name: 'pod1' } }] }, + ], + }), + }; + + const { server } = await startTestBackend({ + features: [ + minimalValidConfigService, + import('@backstage/plugin-kubernetes-backend/alpha'), + withClusters([ + { + name: 'custom-cluster', + url: 'http://my.cluster.url', + authMetadata: { + [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'custom', + }, + }, + ]), + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testAuthStrategy', + register(env) { + env.registerInit({ + deps: { extension: kubernetesAuthStrategyExtensionPoint }, + async init({ extension }) { + extension.addAuthStrategy('custom', { + getCredential: jest + .fn< + Promise, + [ClusterDetails, KubernetesRequestAuth] + >() + .mockImplementation(async (_, requestAuth) => ({ + type: 'bearer token', + token: requestAuth.custom as string, + })), + validateCluster: jest.fn().mockReturnValue([]), + presentAuthMetadata: jest.fn().mockReturnValue({}), + }); + }, + }); + }, + }), + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testFetcher', + register(env) { + env.registerInit({ + deps: { extension: kubernetesFetcherExtensionPoint }, + async init({ extension }) { + extension.addFetcher(mockFetcher); + }, + }); + }, + }), + ], }); - it('forwards request body to k8s', async () => { - const namespaceManifest = { - kind: 'Namespace', - apiVersion: 'v1', - metadata: { name: 'new-ns' }, - }; + app = server; - const proxyEndpointRequest = request(app) - .post('/api/kubernetes/proxy/api/v1/namespaces') - .set(HEADER_KUBERNETES_CLUSTER, 'some-cluster') - .set(HEADER_KUBERNETES_AUTH, 'randomtoken') - .send(namespaceManifest); - worker.use( - rest.all(proxyEndpointRequest.url, req => req.passthrough()), - ); - const response = await proxyEndpointRequest; + await request(app) + .post('/api/kubernetes/services/test-service') + .send({ + entity: { metadata: { name: 'thing' } }, + auth: { custom: 'custom-token' }, + }); - expect(response.body).toStrictEqual(namespaceManifest); - }); + expect(mockFetcher.fetchObjectsForService).toHaveBeenCalledWith( + expect.objectContaining({ + credential: { type: 'bearer token', token: 'custom-token' }, + }), + ); + }); + }); - it('supports yaml content type', async () => { - const yamlManifest = `--- + describe('/proxy', () => { + const worker = setupServer(); + setupRequestMockHandlers(worker); + + beforeEach(() => { + worker.use( + rest.post( + 'https://localhost:1234/api/v1/namespaces', + (req, res, ctx) => { + if (!req.headers.get('Authorization')) { + return res(ctx.status(401)); + } + return req + .arrayBuffer() + .then(body => + res( + ctx.set('content-type', `${req.headers.get('content-type')}`), + ctx.body(body), + ), + ); + }, + ), + ); + }); + + it('forwards request body to k8s', async () => { + const namespaceManifest = { + kind: 'Namespace', + apiVersion: 'v1', + metadata: { name: 'new-ns' }, + }; + + const proxyEndpointRequest = request(app) + .post('/api/kubernetes/proxy/api/v1/namespaces') + .set(HEADER_KUBERNETES_CLUSTER, 'some-cluster') + .set(HEADER_KUBERNETES_AUTH, 'randomtoken') + .send(namespaceManifest); + worker.use(rest.all(proxyEndpointRequest.url, req => req.passthrough())); + const response = await proxyEndpointRequest; + + expect(response.body).toStrictEqual(namespaceManifest); + }); + + it('supports yaml content type', async () => { + const yamlManifest = `--- kind: Namespace apiVersion: v1 metadata: name: new-ns `; - const proxyEndpointRequest = request(app) - .post('/api/kubernetes/proxy/api/v1/namespaces') - .set(HEADER_KUBERNETES_CLUSTER, 'some-cluster') - .set(HEADER_KUBERNETES_AUTH, 'randomtoken') - .set('content-type', 'application/yaml') - .send(yamlManifest); + const proxyEndpointRequest = request(app) + .post('/api/kubernetes/proxy/api/v1/namespaces') + .set(HEADER_KUBERNETES_CLUSTER, 'some-cluster') + .set(HEADER_KUBERNETES_AUTH, 'randomtoken') + .set('content-type', 'application/yaml') + .send(yamlManifest); - worker.use( - rest.all(proxyEndpointRequest.url, req => req.passthrough()), - ); + worker.use(rest.all(proxyEndpointRequest.url, req => req.passthrough())); - const response = await proxyEndpointRequest; - expect(response.text).toEqual(yamlManifest); - }); - - it('returns 403 response when permission blocks endpoint', async () => { - permissionsMock.authorize.mockResolvedValue([ - { result: AuthorizeResult.DENY }, - ]); - - const { server } = await startTestBackend({ - features: [ - minimalValidConfigService, - permissionsMock.factory, - import('@backstage/plugin-kubernetes-backend/alpha'), - ], - }); - app = server; - - const proxyEndpointRequest = request(app) - .post('/api/kubernetes/proxy/api/v1/namespaces') - .set(HEADER_KUBERNETES_CLUSTER, 'some-cluster') - .set(HEADER_KUBERNETES_AUTH, 'randomtoken') - .send({ - kind: 'Namespace', - apiVersion: 'v1', - metadata: { name: 'new-ns' }, - }); - - worker.use( - rest.all(proxyEndpointRequest.url, req => req.passthrough()), - ); - - const response = await proxyEndpointRequest; - - expect(response.status).toEqual(403); - }); - - it('permits custom client-side auth strategy', async () => { - worker.use( - rest.get( - 'http://my.cluster.url/api/v1/namespaces', - (req, res, ctx) => { - if (req.headers.get('Authorization') !== 'custom-token') { - return res(ctx.status(401)); - } - return res(ctx.json({ items: [] })); - }, - ), - ); - - const { server } = await startTestBackend({ - features: [ - minimalValidConfigService, - import('@backstage/plugin-kubernetes-backend/alpha'), - withClusters([ - { - name: 'custom-cluster', - url: 'http://my.cluster.url', - authMetadata: { - [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'custom', - }, - }, - ]), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testAuthStrategy', - register(env) { - env.registerInit({ - deps: { extension: kubernetesAuthStrategyExtensionPoint }, - async init({ extension }) { - extension.addAuthStrategy('custom', { - getCredential: jest - .fn< - Promise, - [ClusterDetails, KubernetesRequestAuth] - >() - .mockResolvedValue({ type: 'anonymous' }), - validateCluster: jest.fn().mockReturnValue([]), - presentAuthMetadata: jest.fn().mockReturnValue({}), - }); - }, - }); - }, - }), - ], - }); - - const proxyEndpointRequest = request(server) - .get('/api/kubernetes/proxy/api/v1/namespaces') - .set(HEADER_KUBERNETES_CLUSTER, 'custom-cluster') - .set(HEADER_KUBERNETES_AUTH, 'custom-token'); - worker.use( - rest.all(proxyEndpointRequest.url, req => req.passthrough()), - ); - const response = await proxyEndpointRequest; - - expect(response.body).toStrictEqual({ items: [] }); - }); - - it('reads custom auth metadata from config', async () => { - const authStrategy = { - getCredential: jest.fn().mockResolvedValue({ type: 'anonymous' }), - validateCluster: jest.fn().mockReturnValue([]), - presentAuthMetadata: jest.fn().mockReturnValue({}), - }; - worker.use( - rest.get('http://my.cluster/api', (_req, res, ctx) => - res(ctx.json({})), - ), - ); - const { server } = await startTestBackend({ - features: [ - mockServices.rootConfig.factory({ - data: { - kubernetes: { - serviceLocatorMethod: { type: 'multiTenant' }, - clusterLocatorMethods: [ - { - type: 'config', - clusters: [ - { - name: 'cluster', - url: 'http://my.cluster', - authProvider: 'custom', - authMetadata: { 'custom-key': 'custom-value' }, - }, - ], - }, - ], - }, - }, - }), - import('@backstage/plugin-kubernetes-backend/alpha'), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testAuthStrategy', - register(env) { - env.registerInit({ - deps: { extension: kubernetesAuthStrategyExtensionPoint }, - async init({ extension }) { - extension.addAuthStrategy('custom', authStrategy); - }, - }); - }, - }), - ], - }); - app = server; - - const proxyEndpointRequest = request(app).get( - '/api/kubernetes/proxy/api', - ); - worker.use( - rest.all(proxyEndpointRequest.url, req => req.passthrough()), - ); - const response = await proxyEndpointRequest; - - expect(response.body).toStrictEqual({}); - expect(authStrategy.getCredential).toHaveBeenCalledWith( - expect.objectContaining({ - authMetadata: expect.objectContaining({ - 'custom-key': 'custom-value', - }), - }), - expect.anything(), - ); - }); + const response = await proxyEndpointRequest; + expect(response.text).toEqual(yamlManifest); }); - it('forbids custom auth strategies with dashes', () => { - const throwError = () => - startTestBackend({ - features: [ - import('@backstage/plugin-kubernetes-backend/alpha'), - createBackendModule({ - pluginId: 'kubernetes', - moduleId: 'testAuthStrategy', - register(env) { - env.registerInit({ - deps: { extension: kubernetesAuthStrategyExtensionPoint }, - async init({ extension }) { - extension.addAuthStrategy('custom-strategy', { - getCredential: jest - .fn< - Promise, - [ClusterDetails, KubernetesRequestAuth] - >() - .mockResolvedValue({ type: 'anonymous' }), - validateCluster: jest.fn().mockReturnValue([]), - presentAuthMetadata: jest.fn().mockReturnValue({}), - }); - }, - }); - }, - }), - ], - }); - return expect(throwError).rejects.toThrow( - 'Strategy name can not include dashes', - ); - }); + it('returns 403 response when permission blocks endpoint', async () => { + permissionsMock.authorize.mockResolvedValue([ + { result: AuthorizeResult.DENY }, + ]); - it('serves permission integration endpoint', async () => { - const response = await request(app).get( - '/api/kubernetes/.well-known/backstage/permissions/metadata', - ); - - expect(response.status).toEqual(200); - expect(response.body).toMatchObject({ - permissions: [ - { type: 'basic', name: 'kubernetes.proxy', attributes: {} }, + const { server } = await startTestBackend({ + features: [ + minimalValidConfigService, + permissionsMock.factory, + import('@backstage/plugin-kubernetes-backend/alpha'), ], - rules: [], }); + app = server; + + const proxyEndpointRequest = request(app) + .post('/api/kubernetes/proxy/api/v1/namespaces') + .set(HEADER_KUBERNETES_CLUSTER, 'some-cluster') + .set(HEADER_KUBERNETES_AUTH, 'randomtoken') + .send({ + kind: 'Namespace', + apiVersion: 'v1', + metadata: { name: 'new-ns' }, + }); + + worker.use(rest.all(proxyEndpointRequest.url, req => req.passthrough())); + + const response = await proxyEndpointRequest; + + expect(response.status).toEqual(403); }); - it('fails when an unsupported serviceLocator type is specified', () => { - return expect(() => - startTestBackend({ - features: [ - mockServices.rootConfig.factory({ - data: { - kubernetes: { - serviceLocatorMethod: { type: 'unsupported' }, - clusterLocatorMethods: [{ type: 'config', clusters: [] }], - }, - }, - }), - import('@backstage/plugin-kubernetes-backend/alpha'), - ], + it('permits custom client-side auth strategy', async () => { + worker.use( + rest.get('http://my.cluster.url/api/v1/namespaces', (req, res, ctx) => { + if (req.headers.get('Authorization') !== 'custom-token') { + return res(ctx.status(401)); + } + return res(ctx.json({ items: [] })); }), - ).rejects.toThrow( - 'Unsupported kubernetes.serviceLocatorMethod "unsupported"', + ); + + const { server } = await startTestBackend({ + features: [ + minimalValidConfigService, + import('@backstage/plugin-kubernetes-backend/alpha'), + withClusters([ + { + name: 'custom-cluster', + url: 'http://my.cluster.url', + authMetadata: { [ANNOTATION_KUBERNETES_AUTH_PROVIDER]: 'custom' }, + }, + ]), + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testAuthStrategy', + register(env) { + env.registerInit({ + deps: { extension: kubernetesAuthStrategyExtensionPoint }, + async init({ extension }) { + extension.addAuthStrategy('custom', { + getCredential: jest + .fn< + Promise, + [ClusterDetails, KubernetesRequestAuth] + >() + .mockResolvedValue({ type: 'anonymous' }), + validateCluster: jest.fn().mockReturnValue([]), + presentAuthMetadata: jest.fn().mockReturnValue({}), + }); + }, + }); + }, + }), + ], + }); + + const proxyEndpointRequest = request(server) + .get('/api/kubernetes/proxy/api/v1/namespaces') + .set(HEADER_KUBERNETES_CLUSTER, 'custom-cluster') + .set(HEADER_KUBERNETES_AUTH, 'custom-token'); + worker.use(rest.all(proxyEndpointRequest.url, req => req.passthrough())); + const response = await proxyEndpointRequest; + + expect(response.body).toStrictEqual({ items: [] }); + }); + + it('reads custom auth metadata from config', async () => { + const authStrategy = { + getCredential: jest.fn().mockResolvedValue({ type: 'anonymous' }), + validateCluster: jest.fn().mockReturnValue([]), + presentAuthMetadata: jest.fn().mockReturnValue({}), + }; + worker.use( + rest.get('http://my.cluster/api', (_req, res, ctx) => + res(ctx.json({})), + ), + ); + const { server } = await startTestBackend({ + features: [ + mockServices.rootConfig.factory({ + data: { + kubernetes: { + serviceLocatorMethod: { type: 'multiTenant' }, + clusterLocatorMethods: [ + { + type: 'config', + clusters: [ + { + name: 'cluster', + url: 'http://my.cluster', + authProvider: 'custom', + authMetadata: { 'custom-key': 'custom-value' }, + }, + ], + }, + ], + }, + }, + }), + import('@backstage/plugin-kubernetes-backend/alpha'), + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testAuthStrategy', + register(env) { + env.registerInit({ + deps: { extension: kubernetesAuthStrategyExtensionPoint }, + async init({ extension }) { + extension.addAuthStrategy('custom', authStrategy); + }, + }); + }, + }), + ], + }); + app = server; + + const proxyEndpointRequest = request(app).get( + '/api/kubernetes/proxy/api', + ); + worker.use(rest.all(proxyEndpointRequest.url, req => req.passthrough())); + const response = await proxyEndpointRequest; + + expect(response.body).toStrictEqual({}); + expect(authStrategy.getCredential).toHaveBeenCalledWith( + expect.objectContaining({ + authMetadata: expect.objectContaining({ + 'custom-key': 'custom-value', + }), + }), + expect.anything(), ); }); }); + + it('forbids custom auth strategies with dashes', () => { + const throwError = () => + startTestBackend({ + features: [ + import('@backstage/plugin-kubernetes-backend/alpha'), + createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'testAuthStrategy', + register(env) { + env.registerInit({ + deps: { extension: kubernetesAuthStrategyExtensionPoint }, + async init({ extension }) { + extension.addAuthStrategy('custom-strategy', { + getCredential: jest + .fn< + Promise, + [ClusterDetails, KubernetesRequestAuth] + >() + .mockResolvedValue({ type: 'anonymous' }), + validateCluster: jest.fn().mockReturnValue([]), + presentAuthMetadata: jest.fn().mockReturnValue({}), + }); + }, + }); + }, + }), + ], + }); + return expect(throwError).rejects.toThrow( + 'Strategy name can not include dashes', + ); + }); + + it('serves permission integration endpoint', async () => { + const response = await request(app).get( + '/api/kubernetes/.well-known/backstage/permissions/metadata', + ); + + expect(response.status).toEqual(200); + expect(response.body).toMatchObject({ + permissions: [ + { type: 'basic', name: 'kubernetes.proxy', attributes: {} }, + ], + rules: [], + }); + }); + + it('fails when an unsupported serviceLocator type is specified', () => { + return expect(() => + startTestBackend({ + features: [ + mockServices.rootConfig.factory({ + data: { + kubernetes: { + serviceLocatorMethod: { type: 'unsupported' }, + clusterLocatorMethods: [{ type: 'config', clusters: [] }], + }, + }, + }), + import('@backstage/plugin-kubernetes-backend/alpha'), + ], + }), + ).rejects.toThrow( + 'Unsupported kubernetes.serviceLocatorMethod "unsupported"', + ); + }); }); From 8c8b6a019715b1f8008d655e34a93c52a907a753 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 14:17:19 +0000 Subject: [PATCH 224/283] chore(deps): update dependency better-sqlite3 to v9.3.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 0342b37b52..ace835f1d0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21221,13 +21221,13 @@ __metadata: linkType: hard "better-sqlite3@npm:^9.0.0": - version: 9.2.2 - resolution: "better-sqlite3@npm:9.2.2" + version: 9.3.0 + resolution: "better-sqlite3@npm:9.3.0" dependencies: bindings: ^1.5.0 node-gyp: latest prebuild-install: ^7.1.1 - checksum: 11d78ed15c8f059c5b58845c40b921692468cef291975ad9f9395278c6ba3005ae2aceb20175fe18e901983ed68c785fdd39c729dc789d72be4184a406bd9a2c + checksum: 03dedaeef92aaa5e963e9fad5849afca3568c987b4d6f36957f9879137c994aa18f9654fe7bcc3804620ede55eabd19ff9bcba03ad0bf985aa8bd5561e4aaa43 languageName: node linkType: hard From b0d1d809e6c096ebabeb42884d5bddc5c7cc8e95 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 18 Jan 2024 15:48:18 +0100 Subject: [PATCH 225/283] scaffolder: initial support for new frontend system Signed-off-by: Patrik Oldsberg --- .changeset/grumpy-poets-study.md | 5 ++ plugins/scaffolder/api-report-alpha.md | 31 ++++++++ plugins/scaffolder/package.json | 6 +- plugins/scaffolder/src/alpha.ts | 23 ------ plugins/scaffolder/src/alpha.tsx | 103 +++++++++++++++++++++++++ yarn.lock | 2 + 6 files changed, 145 insertions(+), 25 deletions(-) create mode 100644 .changeset/grumpy-poets-study.md delete mode 100644 plugins/scaffolder/src/alpha.ts create mode 100644 plugins/scaffolder/src/alpha.tsx diff --git a/.changeset/grumpy-poets-study.md b/.changeset/grumpy-poets-study.md new file mode 100644 index 0000000000..9925f2f87a --- /dev/null +++ b/.changeset/grumpy-poets-study.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Added basic support for the new frontend system, exported from the `/alpha` subpath. diff --git a/plugins/scaffolder/api-report-alpha.md b/plugins/scaffolder/api-report-alpha.md index 6a1e0648a4..c8824d42da 100644 --- a/plugins/scaffolder/api-report-alpha.md +++ b/plugins/scaffolder/api-report-alpha.md @@ -5,19 +5,50 @@ ```ts /// +import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ComponentType } from 'react'; import { Entity } from '@backstage/catalog-model'; +import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; import type { FormProps as FormProps_2 } from '@rjsf/core'; import { FormProps as FormProps_3 } from '@backstage/plugin-scaffolder-react'; import { JSX as JSX_2 } from 'react'; import { LayoutOptions } from '@backstage/plugin-scaffolder-react'; +import { PathParams } from '@backstage/core-plugin-api'; import { PropsWithChildren } from 'react'; import { default as React_2 } from 'react'; import { ReviewStepProps } from '@backstage/plugin-scaffolder-react'; +import { RouteRef } from '@backstage/frontend-plugin-api'; +import { SubRouteRef } from '@backstage/frontend-plugin-api'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; import { TemplateGroupFilter } from '@backstage/plugin-scaffolder-react'; +// @alpha (undocumented) +const _default: BackstagePlugin< + { + root: RouteRef; + selectedTemplate: SubRouteRef< + PathParams<'/templates/:namespace/:templateName'> + >; + ongoingTask: SubRouteRef>; + actions: SubRouteRef; + listTasks: SubRouteRef; + edit: SubRouteRef; + }, + { + registerComponent: ExternalRouteRef; + viewTechDoc: ExternalRouteRef< + { + name: string; + kind: string; + namespace: string; + }, + true + >; + } +>; +export default _default; + // @alpha @deprecated export type FormProps = Pick< FormProps_2, diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 690af2f971..8652c380ba 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -10,13 +10,13 @@ }, "exports": { ".": "./src/index.ts", - "./alpha": "./src/alpha.ts", + "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, "typesVersions": { "*": { "alpha": [ - "src/alpha.ts" + "src/alpha.tsx" ], "package.json": [ "package.json" @@ -48,9 +48,11 @@ "dependencies": { "@backstage/catalog-client": "workspace:^", "@backstage/catalog-model": "workspace:^", + "@backstage/core-compat-api": "workspace:^", "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", "@backstage/errors": "workspace:^", + "@backstage/frontend-plugin-api": "workspace:^", "@backstage/integration": "workspace:^", "@backstage/integration-react": "workspace:^", "@backstage/plugin-catalog-common": "workspace:^", diff --git a/plugins/scaffolder/src/alpha.ts b/plugins/scaffolder/src/alpha.ts deleted file mode 100644 index 92ec945de4..0000000000 --- a/plugins/scaffolder/src/alpha.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { - type FormProps, - type TemplateListPageProps, - type TemplateWizardPageProps, -} from './next'; - -export * from './legacy'; diff --git a/plugins/scaffolder/src/alpha.tsx b/plugins/scaffolder/src/alpha.tsx new file mode 100644 index 0000000000..152745eec1 --- /dev/null +++ b/plugins/scaffolder/src/alpha.tsx @@ -0,0 +1,103 @@ +/* + * Copyright 2023 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 React from 'react'; +import { + createApiExtension, + createApiFactory, + createNavItemExtension, + createPageExtension, + createPlugin, + discoveryApiRef, + fetchApiRef, + identityApiRef, +} from '@backstage/frontend-plugin-api'; +import CreateComponentIcon from '@material-ui/icons/AddCircleOutline'; +import { + compatWrapper, + convertLegacyRouteRef, +} from '@backstage/core-compat-api'; +import { scmIntegrationsApiRef } from '@backstage/integration-react'; +import { scaffolderApiRef } from '@backstage/plugin-scaffolder-react'; +import { ScaffolderClient } from './api'; +import { + registerComponentRouteRef, + rootRouteRef, + viewTechDocRouteRef, + selectedTemplateRouteRef, + scaffolderTaskRouteRef, + scaffolderListTaskRouteRef, + actionsRouteRef, + editRouteRef, +} from './routes'; + +export { + type FormProps, + type TemplateListPageProps, + type TemplateWizardPageProps, +} from './next'; + +export * from './legacy'; + +const scaffolderApi = createApiExtension({ + factory: createApiFactory({ + api: scaffolderApiRef, + deps: { + discoveryApi: discoveryApiRef, + scmIntegrationsApi: scmIntegrationsApiRef, + fetchApi: fetchApiRef, + identityApi: identityApiRef, + }, + factory: ({ discoveryApi, scmIntegrationsApi, fetchApi, identityApi }) => + new ScaffolderClient({ + discoveryApi, + scmIntegrationsApi, + fetchApi, + identityApi, + }), + }), +}); + +const scaffolderPage = createPageExtension({ + routeRef: convertLegacyRouteRef(rootRouteRef), + defaultPath: '/create', + loader: () => + import('./components/Router').then(m => compatWrapper()), +}); + +const scaffolderNavItem = createNavItemExtension({ + routeRef: convertLegacyRouteRef(rootRouteRef), + title: 'Create...', + icon: CreateComponentIcon, +}); + +/** @alpha */ +export default createPlugin({ + id: 'scaffolder', + routes: { + root: convertLegacyRouteRef(rootRouteRef), + selectedTemplate: convertLegacyRouteRef(selectedTemplateRouteRef), + ongoingTask: convertLegacyRouteRef(scaffolderTaskRouteRef), + actions: convertLegacyRouteRef(actionsRouteRef), + listTasks: convertLegacyRouteRef(scaffolderListTaskRouteRef), + edit: convertLegacyRouteRef(editRouteRef), + }, + externalRoutes: { + registerComponent: convertLegacyRouteRef(registerComponentRouteRef), + viewTechDoc: convertLegacyRouteRef(viewTechDocRouteRef), + }, + extensions: [scaffolderApi, scaffolderPage, scaffolderNavItem], +}); diff --git a/yarn.lock b/yarn.lock index ef4f1cbc43..41d7365fe7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8328,10 +8328,12 @@ __metadata: "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/core-app-api": "workspace:^" + "@backstage/core-compat-api": "workspace:^" "@backstage/core-components": "workspace:^" "@backstage/core-plugin-api": "workspace:^" "@backstage/dev-utils": "workspace:^" "@backstage/errors": "workspace:^" + "@backstage/frontend-plugin-api": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/integration-react": "workspace:^" "@backstage/plugin-catalog": "workspace:^" From 7eae3e0c702005920b8a5a6b21f42b926739a7d2 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 18 Jan 2024 14:15:46 +0100 Subject: [PATCH 226/283] frontend-plugin-api: added IconsApi Signed-off-by: Patrik Oldsberg --- .changeset/flat-wasps-fold.md | 5 +++ packages/frontend-plugin-api/api-report.md | 13 +++++++ .../src/apis/definitions/IconsApi.ts | 38 +++++++++++++++++++ .../src/apis/definitions/index.ts | 1 + 4 files changed, 57 insertions(+) create mode 100644 .changeset/flat-wasps-fold.md create mode 100644 packages/frontend-plugin-api/src/apis/definitions/IconsApi.ts diff --git a/.changeset/flat-wasps-fold.md b/.changeset/flat-wasps-fold.md new file mode 100644 index 0000000000..653dc0d78f --- /dev/null +++ b/.changeset/flat-wasps-fold.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-plugin-api': patch +--- + +Added initial `IconsApi` definition. diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index 1d42d8bab8..fd0e1302b7 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -976,6 +976,19 @@ export type IconComponent = ComponentType< } >; +// @public +export interface IconsApi { + // (undocumented) + getIcon(key: string): IconComponent | undefined; + // (undocumented) + listIconKeys(): { + keys: Iterable; + }; +} + +// @public +export const iconsApiRef: ApiRef; + export { IdentityApi }; export { identityApiRef }; diff --git a/packages/frontend-plugin-api/src/apis/definitions/IconsApi.ts b/packages/frontend-plugin-api/src/apis/definitions/IconsApi.ts new file mode 100644 index 0000000000..daef2ca40f --- /dev/null +++ b/packages/frontend-plugin-api/src/apis/definitions/IconsApi.ts @@ -0,0 +1,38 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createApiRef } from '@backstage/core-plugin-api'; +import { IconComponent } from '../../icons'; + +/** + * API for accessing app icons. + * + * @public + */ +export interface IconsApi { + getIcon(key: string): IconComponent | undefined; + + listIconKeys(): { keys: Iterable }; +} + +/** + * The `ApiRef` of {@link IconsApi}. + * + * @public + */ +export const iconsApiRef = createApiRef({ + id: 'core.icons', +}); diff --git a/packages/frontend-plugin-api/src/apis/definitions/index.ts b/packages/frontend-plugin-api/src/apis/definitions/index.ts index f2496ee61a..c0a2101db0 100644 --- a/packages/frontend-plugin-api/src/apis/definitions/index.ts +++ b/packages/frontend-plugin-api/src/apis/definitions/index.ts @@ -40,6 +40,7 @@ export * from './DiscoveryApi'; export * from './ErrorApi'; export * from './FeatureFlagsApi'; export * from './FetchApi'; +export * from './IconsApi'; export * from './IdentityApi'; export * from './OAuthRequestApi'; export * from './StorageApi'; From 42ebf27c0bd6a2ae10a44bfe6450c4198ac1a2f6 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 18 Jan 2024 14:18:47 +0100 Subject: [PATCH 227/283] frontend-app-api: added IconsApi implementation and icons option for createApp Signed-off-by: Patrik Oldsberg --- .changeset/dry-lobsters-flash.md | 5 +++ packages/frontend-app-api/api-report.md | 7 ++++ .../apis/implementations/IconsApi/IconsApi.ts | 38 +++++++++++++++++++ .../apis/implementations/IconsApi/index.ts | 17 +++++++++ .../frontend-app-api/src/wiring/createApp.tsx | 21 +++++++++- 5 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 .changeset/dry-lobsters-flash.md create mode 100644 packages/frontend-app-api/src/apis/implementations/IconsApi/IconsApi.ts create mode 100644 packages/frontend-app-api/src/apis/implementations/IconsApi/index.ts diff --git a/.changeset/dry-lobsters-flash.md b/.changeset/dry-lobsters-flash.md new file mode 100644 index 0000000000..9815bf62f4 --- /dev/null +++ b/.changeset/dry-lobsters-flash.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-app-api': patch +--- + +Added `IconsApi` implementation and the ability to configure icons through the `icons` option for `createApp` and `createSpecializedApp`. This is not a long-term solution as icons should be installable via extensions instead. This is just a stop-gap to make sure there is feature parity with the existing frontend system. diff --git a/packages/frontend-app-api/api-report.md b/packages/frontend-app-api/api-report.md index e7dd584734..d0aadb7e8c 100644 --- a/packages/frontend-app-api/api-report.md +++ b/packages/frontend-app-api/api-report.md @@ -8,12 +8,16 @@ import { ConfigApi } from '@backstage/core-plugin-api'; import { ExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; import { FrontendFeature } from '@backstage/frontend-plugin-api'; +import { IconComponent } from '@backstage/core-plugin-api'; import { JSX as JSX_2 } from 'react'; import { RouteRef } from '@backstage/frontend-plugin-api'; import { SubRouteRef } from '@backstage/frontend-plugin-api'; // @public (undocumented) export function createApp(options?: { + icons?: { + [key in string]: IconComponent; + }; features?: (FrontendFeature | CreateAppFeatureLoader)[]; configLoader?: () => Promise<{ config: ConfigApi; @@ -49,6 +53,9 @@ export function createExtensionTree(options: { config: Config }): ExtensionTree; // @public export function createSpecializedApp(options?: { + icons?: { + [key in string]: IconComponent; + }; features?: FrontendFeature[]; config?: ConfigApi; bindRoutes?(context: { bind: CreateAppRouteBinder }): void; diff --git a/packages/frontend-app-api/src/apis/implementations/IconsApi/IconsApi.ts b/packages/frontend-app-api/src/apis/implementations/IconsApi/IconsApi.ts new file mode 100644 index 0000000000..f64bbc67f9 --- /dev/null +++ b/packages/frontend-app-api/src/apis/implementations/IconsApi/IconsApi.ts @@ -0,0 +1,38 @@ +/* + * Copyright 2023 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 { IconComponent, IconsApi } from '@backstage/frontend-plugin-api'; + +/** + * Implementation for the {@link IconsApi} + * + * @internal + */ +export class DefaultIconsApi implements IconsApi { + #icons: Map; + + constructor(icons: { [key in string]: IconComponent }) { + this.#icons = new Map(Object.entries(icons)); + } + + getIcon(key: string): IconComponent | undefined { + return this.#icons.get(key); + } + + listIconKeys: IconsApi['listIconKeys'] = () => { + return { keys: this.#icons.keys() }; + }; +} diff --git a/packages/frontend-app-api/src/apis/implementations/IconsApi/index.ts b/packages/frontend-app-api/src/apis/implementations/IconsApi/index.ts new file mode 100644 index 0000000000..4a73182e84 --- /dev/null +++ b/packages/frontend-app-api/src/apis/implementations/IconsApi/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { DefaultIconsApi } from './IconsApi'; diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createApp.tsx index 7b2f17193e..832aa2663b 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createApp.tsx @@ -29,6 +29,7 @@ import { createTranslationExtension, ExtensionDataRef, FrontendFeature, + iconsApiRef, RouteRef, useRouteRef, } from '@backstage/frontend-plugin-api'; @@ -105,7 +106,10 @@ import { toInternalBackstagePlugin } from '../../../frontend-plugin-api/src/wiri // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { toInternalExtensionOverrides } from '../../../frontend-plugin-api/src/wiring/createExtensionOverrides'; import { DefaultComponentsApi } from '../apis/implementations/ComponentsApi'; +import { DefaultIconsApi } from '../apis/implementations/IconsApi'; import { stringifyError } from '@backstage/errors'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { icons as defaultIcons } from '../../../app-defaults/src/defaults'; const DefaultApis = defaultApis.map(factory => createApiExtension({ factory })); @@ -269,6 +273,7 @@ export interface CreateAppFeatureLoader { /** @public */ export function createApp(options?: { + icons?: { [key in string]: IconComponent }; features?: (FrontendFeature | CreateAppFeatureLoader)[]; configLoader?: () => Promise<{ config: ConfigApi }>; bindRoutes?(context: { bind: CreateAppRouteBinder }): void; @@ -303,6 +308,7 @@ export function createApp(options?: { } const app = createSpecializedApp({ + icons: options?.icons, config, features: [...discoveredFeatures, ...providedFeatures], bindRoutes: options?.bindRoutes, @@ -330,6 +336,7 @@ export function createApp(options?: { * @public */ export function createSpecializedApp(options?: { + icons?: { [key in string]: IconComponent }; features?: FrontendFeature[]; config?: ConfigApi; bindRoutes?(context: { bind: CreateAppRouteBinder }): void; @@ -348,7 +355,12 @@ export function createSpecializedApp(options?: { }); const appIdentityProxy = new AppIdentityProxy(); - const apiHolder = createApiHolder(tree, config, appIdentityProxy); + const apiHolder = createApiHolder( + tree, + config, + appIdentityProxy, + options?.icons, + ); const featureFlagApi = apiHolder.get(featureFlagsApiRef); if (featureFlagApi) { @@ -402,6 +414,7 @@ function createApiHolder( tree: AppTree, configApi: ConfigApi, appIdentityProxy: AppIdentityProxy, + icons?: { [key in string]: IconComponent }, ): ApiHolder { const factoryRegistry = new ApiFactoryRegistry(); @@ -470,6 +483,12 @@ function createApiHolder( factory: () => new DefaultComponentsApi(componentsMap), }); + factoryRegistry.register('static', { + api: iconsApiRef, + deps: {}, + factory: () => new DefaultIconsApi({ ...defaultIcons, ...icons }), + }); + factoryRegistry.register('static', { api: appThemeApiRef, deps: {}, From 1fa5041091aa0dafb4f56835e1cab2ca642c45e9 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 18 Jan 2024 14:20:38 +0100 Subject: [PATCH 228/283] core-compat-api: make compatWrapper use ComponentsApi and IconsApi Signed-off-by: Patrik Oldsberg --- .changeset/chilly-seahorses-bake.md | 5 ++ .../compatWrapper/BackwardsCompatProvider.tsx | 62 ++++++++++++++----- .../src/compatWrapper/compatWrapper.test.tsx | 2 +- 3 files changed, 54 insertions(+), 15 deletions(-) create mode 100644 .changeset/chilly-seahorses-bake.md diff --git a/.changeset/chilly-seahorses-bake.md b/.changeset/chilly-seahorses-bake.md new file mode 100644 index 0000000000..8ab80cf93e --- /dev/null +++ b/.changeset/chilly-seahorses-bake.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-compat-api': patch +--- + +The backwards compatibility provider will now use the new `ComponentsApi` and `IconsApi` when implementing the old `AppContext`. diff --git a/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx b/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx index 099993a392..1dd64efb89 100644 --- a/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx +++ b/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx @@ -18,14 +18,13 @@ import React, { useMemo } from 'react'; import { ReactNode } from 'react'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { AppContextProvider } from '../../../core-app-api/src/app/AppContext'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { - components as defaultComponents, - icons as defaultIcons, -} from '../../../app-defaults/src/defaults'; import { + createPlugin as createNewPlugin, BackstagePlugin as NewBackstagePlugin, appTreeApiRef, + componentsApiRef, + coreComponentRefs, + iconsApiRef, useApi, } from '@backstage/frontend-plugin-api'; import { @@ -71,15 +70,35 @@ function toLegacyPlugin(plugin: NewBackstagePlugin): LegacyBackstagePlugin { return legacy; } +// TODO: Currently a very naive implementation, may need some more work +function toNewPlugin(plugin: LegacyBackstagePlugin): NewBackstagePlugin { + return createNewPlugin({ + id: plugin.getId(), + }); +} + // Recreates the old AppContext APIs using the various new APIs that replaced it function LegacyAppContextProvider(props: { children: ReactNode }) { const appTreeApi = useApi(appTreeApiRef); + const componentsApi = useApi(componentsApiRef); + const iconsApi = useApi(iconsApiRef); const appContext = useMemo(() => { const { tree } = appTreeApi.getTree(); let gatheredPlugins: LegacyBackstagePlugin[] | undefined = undefined; + const ErrorBoundaryFallback = componentsApi.getComponent( + coreComponentRefs.errorBoundaryFallback, + ); + const ErrorBoundaryFallbackWrapper: AppComponents['ErrorBoundaryFallback'] = + ({ plugin, ...rest }) => ( + + ); + return { getPlugins(): LegacyBackstagePlugin[] { if (gatheredPlugins) { @@ -98,24 +117,39 @@ function LegacyAppContextProvider(props: { children: ReactNode }) { return gatheredPlugins; }, - // TODO: Grab these from new API once it exists getSystemIcon(key: string): IconComponent | undefined { - return key in defaultIcons - ? defaultIcons[key as keyof typeof defaultIcons] - : undefined; + return iconsApi.getIcon(key); }, - // TODO: Grab these from new API once it exists getSystemIcons(): Record { - return defaultIcons; + const { keys } = iconsApi.listIconKeys(); + + return Object.fromEntries( + Array.from(keys).map(key => [key, iconsApi.getIcon(key)!]), + ); }, - // TODO: Grab these from new API once it exists getComponents(): AppComponents { - return defaultComponents; + return { + NotFoundErrorPage: componentsApi.getComponent( + coreComponentRefs.notFoundErrorPage, + ), + BootErrorPage() { + throw new Error( + 'The BootErrorPage app component should not be accessed by plugins', + ); + }, + Progress: componentsApi.getComponent(coreComponentRefs.progress), + Router() { + throw new Error( + 'The Router app component should not be accessed by plugins', + ); + }, + ErrorBoundaryFallback: ErrorBoundaryFallbackWrapper, + }; }, }; - }, [appTreeApi]); + }, [appTreeApi, componentsApi, iconsApi]); return ( diff --git a/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx b/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx index b2ad7f3d0c..2e7dbd9d37 100644 --- a/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx +++ b/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx @@ -60,7 +60,7 @@ describe('BackwardsCompatProvider', () => { expect(screen.getByTestId('ctx').textContent).toMatchInlineSnapshot(` "plugins: - components: Progress, Router, NotFoundErrorPage, BootErrorPage, ErrorBoundaryFallback + components: NotFoundErrorPage, BootErrorPage, Progress, Router, ErrorBoundaryFallback icons: brokenImage, catalog, scaffolder, techdocs, search, chat, dashboard, docs, email, github, group, help, kind:api, kind:component, kind:domain, kind:group, kind:location, kind:system, kind:user, kind:resource, kind:template, user, warning" `); }); From ef18e8b484d24803b161de025164e5eb743d6954 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 15:15:23 +0000 Subject: [PATCH 229/283] chore(deps): update dependency eslint to v8.56.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index ace835f1d0..d7544bafc4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10873,10 +10873,10 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:8.55.0": - version: 8.55.0 - resolution: "@eslint/js@npm:8.55.0" - checksum: fa33ef619f0646ed15649b0c2e313e4d9ccee8425884bdbfc78020d6b6b64c0c42fa9d83061d0e6158e1d4274f03f0f9008786540e2efab8fcdc48082259908c +"@eslint/js@npm:8.56.0": + version: 8.56.0 + resolution: "@eslint/js@npm:8.56.0" + checksum: 5804130574ef810207bdf321c265437814e7a26f4e6fac9b496de3206afd52f533e09ec002a3be06cd9adcc9da63e727f1883938e663c4e4751c007d5b58e539 languageName: node linkType: hard @@ -26005,13 +26005,13 @@ __metadata: linkType: hard "eslint@npm:^8.33.0, eslint@npm:^8.6.0": - version: 8.55.0 - resolution: "eslint@npm:8.55.0" + version: 8.56.0 + resolution: "eslint@npm:8.56.0" dependencies: "@eslint-community/eslint-utils": ^4.2.0 "@eslint-community/regexpp": ^4.6.1 "@eslint/eslintrc": ^2.1.4 - "@eslint/js": 8.55.0 + "@eslint/js": 8.56.0 "@humanwhocodes/config-array": ^0.11.13 "@humanwhocodes/module-importer": ^1.0.1 "@nodelib/fs.walk": ^1.2.8 @@ -26048,7 +26048,7 @@ __metadata: text-table: ^0.2.0 bin: eslint: bin/eslint.js - checksum: 83f82a604559dc1faae79d28fdf3dfc9e592ca221052e2ea516e1b379b37e77e4597705a16880e2f5ece4f79087c1dd13fd7f6e9746f794a401175519db18b41 + checksum: 883436d1e809b4a25d9eb03d42f584b84c408dbac28b0019f6ea07b5177940bf3cca86208f749a6a1e0039b63e085ee47aca1236c30721e91f0deef5cc5a5136 languageName: node linkType: hard From c60fd9c71e70f0c4e2c90edc8f9837b43f84e9aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 18 Jan 2024 16:46:31 +0100 Subject: [PATCH 230/283] fix the adopter form clipping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- microsite/src/pages/home/hubSpotNewAdoptersForm.module.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/microsite/src/pages/home/hubSpotNewAdoptersForm.module.scss b/microsite/src/pages/home/hubSpotNewAdoptersForm.module.scss index 77e1a87a53..24d07be2e7 100644 --- a/microsite/src/pages/home/hubSpotNewAdoptersForm.module.scss +++ b/microsite/src/pages/home/hubSpotNewAdoptersForm.module.scss @@ -4,6 +4,8 @@ display: flex; position: fixed; transform: translateY(-50%); + margin-top: 44px; + max-height: calc(100% - 44px); transition: all 250ms ease-in-out; @@ -22,9 +24,7 @@ } .hubSpotNewAdopterFormContent { - height: 600px; max-width: 500px; - overflow-y: hidden; border-radius: 8px 0 0 8px; background-color: var(--ifm-color-white); From aea7e811528e1338848dd5e15470585ccdf99412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 18 Jan 2024 16:52:59 +0100 Subject: [PATCH 231/283] address comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- microsite/src/pages/home/hubSpotNewAdoptersForm.module.scss | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/microsite/src/pages/home/hubSpotNewAdoptersForm.module.scss b/microsite/src/pages/home/hubSpotNewAdoptersForm.module.scss index 24d07be2e7..9533890660 100644 --- a/microsite/src/pages/home/hubSpotNewAdoptersForm.module.scss +++ b/microsite/src/pages/home/hubSpotNewAdoptersForm.module.scss @@ -1,11 +1,13 @@ +$page-header-height: 44px; + .hubSpotNewAdopterFormContainer { top: 50%; right: 0; display: flex; position: fixed; transform: translateY(-50%); - margin-top: 44px; - max-height: calc(100% - 44px); + margin-top: $page-header-height; + max-height: calc(100% - $page-header-height); transition: all 250ms ease-in-out; From cc53965ead5a1d5b1a28007492044f4aa4b7fc03 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 18 Jan 2024 17:14:33 +0100 Subject: [PATCH 232/283] Apply suggestions from code review Signed-off-by: Patrik Oldsberg --- beps/0002-dynamic-frontend-plugins/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/beps/0002-dynamic-frontend-plugins/README.md b/beps/0002-dynamic-frontend-plugins/README.md index a75ec77229..e9259660cb 100644 --- a/beps/0002-dynamic-frontend-plugins/README.md +++ b/beps/0002-dynamic-frontend-plugins/README.md @@ -1,11 +1,11 @@ --- -title: BEP Dynamic frontend plugins +title: Dynamic Frontend Plugins status: provisional authors: - '@Hyperkid123' owners: project-areas: - - aaa + - core creation-date: 2024-01-17 --- From 52761e8bcf048478e7fe267d15da530c62616a16 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 18 Jan 2024 17:20:03 +0100 Subject: [PATCH 233/283] .github/workflows: skip CI checks for beps Signed-off-by: Patrik Oldsberg --- .github/workflows/ci-noop.yml | 1 + .github/workflows/ci.yml | 1 + .github/workflows/uffizzi-build.yml | 1 + .github/workflows/verify_e2e-linux-noop.yml | 1 + .github/workflows/verify_e2e-linux.yml | 1 + .github/workflows/verify_microsite-noop.yml | 1 + .github/workflows/verify_microsite.yml | 1 + 7 files changed, 7 insertions(+) diff --git a/.github/workflows/ci-noop.yml b/.github/workflows/ci-noop.yml index 6918db4be5..f7c6c40832 100644 --- a/.github/workflows/ci-noop.yml +++ b/.github/workflows/ci-noop.yml @@ -6,6 +6,7 @@ on: pull_request: paths: - 'microsite/**' + - 'beps/**' permissions: contents: read diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ada4233f18..364c02bd76 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,6 +4,7 @@ on: pull_request: paths-ignore: - 'microsite/**' + - 'beps/**' concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/uffizzi-build.yml b/.github/workflows/uffizzi-build.yml index c0bbde49f3..da839b24d0 100644 --- a/.github/workflows/uffizzi-build.yml +++ b/.github/workflows/uffizzi-build.yml @@ -7,6 +7,7 @@ on: - 'contrib/**' - 'docs/**' - 'microsite/**' + - 'beps/**' - 'scripts/**' - 'storybook/**' - '**/*.test.*' diff --git a/.github/workflows/verify_e2e-linux-noop.yml b/.github/workflows/verify_e2e-linux-noop.yml index c1ac6ecf89..19b2508d27 100644 --- a/.github/workflows/verify_e2e-linux-noop.yml +++ b/.github/workflows/verify_e2e-linux-noop.yml @@ -9,6 +9,7 @@ on: - 'contrib/**' - 'docs/**' - 'microsite/**' + - 'beps/**' concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/verify_e2e-linux.yml b/.github/workflows/verify_e2e-linux.yml index 0e335b8fe0..3f403b2c91 100644 --- a/.github/workflows/verify_e2e-linux.yml +++ b/.github/workflows/verify_e2e-linux.yml @@ -7,6 +7,7 @@ on: - 'contrib/**' - 'docs/**' - 'microsite/**' + - 'beps/**' concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/verify_microsite-noop.yml b/.github/workflows/verify_microsite-noop.yml index ac0e397127..d730c7aba6 100644 --- a/.github/workflows/verify_microsite-noop.yml +++ b/.github/workflows/verify_microsite-noop.yml @@ -7,6 +7,7 @@ on: paths-ignore: - '.github/workflows/verify_microsite.yml' - 'microsite/**' + - 'beps/**' - 'mkdocs.yml' - 'docs/**' diff --git a/.github/workflows/verify_microsite.yml b/.github/workflows/verify_microsite.yml index 42a6663e59..5c76148b92 100644 --- a/.github/workflows/verify_microsite.yml +++ b/.github/workflows/verify_microsite.yml @@ -5,6 +5,7 @@ on: paths: - '.github/workflows/verify_microsite.yml' - 'microsite/**' + - 'beps/**' - 'mkdocs.yml' - 'docs/**' From d3f16734d3b41b4291f09ce9f9ff6cd594641c2e Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 18 Jan 2024 17:22:41 +0100 Subject: [PATCH 234/283] Update beps/0002-dynamic-frontend-plugins/README.md Signed-off-by: Patrik Oldsberg --- beps/0002-dynamic-frontend-plugins/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beps/0002-dynamic-frontend-plugins/README.md b/beps/0002-dynamic-frontend-plugins/README.md index e9259660cb..0fd42d389f 100644 --- a/beps/0002-dynamic-frontend-plugins/README.md +++ b/beps/0002-dynamic-frontend-plugins/README.md @@ -115,7 +115,7 @@ The Vite plugin claims webpack compatibility as well. The Vite plugin _is not pa **The level of compatibility has to be tested.** Before then, no decision in regards to which implementation(s) will be used should be made. The chosen tool, or their mix, will shape the design and implementation. -That said, packages from the `@module-federation/*` organization should have higher priority as they are based directly on the module federation concepts and are wll supported. +That said, packages from the `@module-federation/*` organization should have higher priority as they are based directly on the module federation concepts and are well supported. ### Plugin integration into shell applications From b29ef0a0eab8e5cd9bec6cb1e7f5f8a7637e6451 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 18 Jan 2024 17:22:58 +0100 Subject: [PATCH 235/283] Apply suggestions from code review Signed-off-by: Patrik Oldsberg --- beps/0002-dynamic-frontend-plugins/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/beps/0002-dynamic-frontend-plugins/README.md b/beps/0002-dynamic-frontend-plugins/README.md index 0fd42d389f..b44c4a8b20 100644 --- a/beps/0002-dynamic-frontend-plugins/README.md +++ b/beps/0002-dynamic-frontend-plugins/README.md @@ -105,11 +105,11 @@ Although there are other options, like externalizing dependencies, the module fe There are multiple available implementations of module federation. -Historically, module federation was implemented as a [Webpack feature](https://webpack.js.org/). Since then, additional implementations were created. Mainly for [Rspack](https://www.rspack.dev/) and [Vite](https://github.com/originjs/vite-plugin-federation). +Historically, module federation was implemented as a [Webpack feature](https://webpack.js.org/). Since then, additional implementations were created. Mainly for [`rspack`](https://www.rspack.dev/) and [Vite](https://github.com/originjs/vite-plugin-federation). Recent changes _claim_, that all of these module federation implementations should be compatible with each other and there should be no need for locking backstage into a single implementation. -Compatibility between Webpack and Rspack should available via the [@module-federation/enhanced](https://www.npmjs.com/package/@module-federation/enhanced) package. The compatibility is further [described here](https://www.rspack.dev/blog/module-federation-added-to-rspack.html#introducing-rspack-050). +Compatibility between Webpack and `rspack` should available via the [@module-federation/enhanced](https://www.npmjs.com/package/@module-federation/enhanced) package. The compatibility is further [described here](https://www.rspack.dev/blog/module-federation-added-to-rspack.html#introducing-rspack-050). The Vite plugin claims webpack compatibility as well. The Vite plugin _is not part of the @module-federation_ organization. The extend of compatibility is at this time unknown. From 3dd117d7cce6666bf72d80a0a5bc32f0edabd812 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 16:29:11 +0000 Subject: [PATCH 236/283] chore(deps): update dependency msw to v2.1.2 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 70 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/yarn.lock b/yarn.lock index d7544bafc4..8e503b3047 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12736,9 +12736,9 @@ __metadata: languageName: node linkType: hard -"@mswjs/interceptors@npm:^0.25.13": - version: 0.25.13 - resolution: "@mswjs/interceptors@npm:0.25.13" +"@mswjs/interceptors@npm:^0.25.14": + version: 0.25.14 + resolution: "@mswjs/interceptors@npm:0.25.14" dependencies: "@open-draft/deferred-promise": ^2.2.0 "@open-draft/logger": ^0.3.0 @@ -12746,7 +12746,7 @@ __metadata: is-node-process: ^1.2.0 outvariant: ^1.2.1 strict-event-emitter: ^0.5.1 - checksum: 21eaefbd66dc2c3bbeec5b6a2fdc714f6a0967158c0137cd1e4b875284e55d358b4a032030d5e0783e5826cdb27918086d1fd8412f3cbcc70e5368554f678d46 + checksum: caf9513cf6848ff0c3f1402abf881d3c1333f68fae54076cfd3fd919b7edb709769342bd3afd2a60ef4ae698ef47776b6203e0ea6a5d8e788e97eda7ed9dbbd4 languageName: node linkType: hard @@ -17537,6 +17537,13 @@ __metadata: languageName: node linkType: hard +"@types/cookie@npm:^0.6.0": + version: 0.6.0 + resolution: "@types/cookie@npm:0.6.0" + checksum: 5edce7995775b0b196b142883e4d4f71fd93c294eaec973670f1fa2540b70ea7390408ed513ddefef5fcb12a578100c76596e8f2a714b0c2ae9f70ee773f4510 + languageName: node + linkType: hard + "@types/cookiejar@npm:*": version: 2.1.1 resolution: "@types/cookiejar@npm:2.1.1" @@ -18066,10 +18073,10 @@ __metadata: languageName: node linkType: hard -"@types/js-levenshtein@npm:^1.1.1": - version: 1.1.1 - resolution: "@types/js-levenshtein@npm:1.1.1" - checksum: 1d1ff1ee2ad551909e47f3ce19fcf85b64dc5146d3b531c8d26fc775492d36e380b32cf5ef68ff301e812c3b00282f37aac579ebb44498b94baff0ace7509769 +"@types/js-levenshtein@npm:^1.1.1, @types/js-levenshtein@npm:^1.1.3": + version: 1.1.3 + resolution: "@types/js-levenshtein@npm:1.1.3" + checksum: eb338696da976925ea8448a42d775d7615a14323dceeb08909f187d0b3d3b4c1f67a1c36ef586b1c2318b70ab141bba8fc58311ba1c816711704605aec09db8b languageName: node linkType: hard @@ -18905,7 +18912,7 @@ __metadata: languageName: node linkType: hard -"@types/statuses@npm:^2.0.1": +"@types/statuses@npm:^2.0.4": version: 2.0.4 resolution: "@types/statuses@npm:2.0.4" checksum: 3a806c3b96d1845e3e7441fbf0839037e95f717334760ddb7c29223c9a34a7206b68e2998631f89f1a1e3ef5b67b15652f6e8fa14987ebd7f6d38587c1bffd18 @@ -28777,7 +28784,7 @@ __metadata: languageName: node linkType: hard -"headers-polyfill@npm:^4.0.1": +"headers-polyfill@npm:^4.0.2": version: 4.0.2 resolution: "headers-polyfill@npm:4.0.2" checksum: a95280ed58df429fc86c4f49b21596be3ea3f5f3d790e7d75238668df9b90b292f15a968c7c19ae1db88c0ae036dd1bf363a71b8e771199d82848e2d8b3c6c2e @@ -34457,38 +34464,38 @@ __metadata: linkType: hard "msw@npm:^2.0.0, msw@npm:^2.0.8": - version: 2.0.11 - resolution: "msw@npm:2.0.11" + version: 2.1.2 + resolution: "msw@npm:2.1.2" dependencies: "@bundled-es-modules/cookie": ^2.0.0 "@bundled-es-modules/js-levenshtein": ^2.0.1 "@bundled-es-modules/statuses": ^1.0.1 "@mswjs/cookies": ^1.1.0 - "@mswjs/interceptors": ^0.25.13 + "@mswjs/interceptors": ^0.25.14 "@open-draft/until": ^2.1.0 - "@types/cookie": ^0.4.1 - "@types/js-levenshtein": ^1.1.1 - "@types/statuses": ^2.0.1 + "@types/cookie": ^0.6.0 + "@types/js-levenshtein": ^1.1.3 + "@types/statuses": ^2.0.4 chalk: ^4.1.2 chokidar: ^3.4.2 graphql: ^16.8.1 - headers-polyfill: ^4.0.1 + headers-polyfill: ^4.0.2 inquirer: ^8.2.0 is-node-process: ^1.2.0 js-levenshtein: ^1.1.6 - outvariant: ^1.4.0 + outvariant: ^1.4.2 path-to-regexp: ^6.2.0 - strict-event-emitter: ^0.5.0 - type-fest: ^2.19.0 - yargs: ^17.3.1 + strict-event-emitter: ^0.5.1 + type-fest: ^4.9.0 + yargs: ^17.7.2 peerDependencies: - typescript: ">= 4.7.x <= 5.2.x" + typescript: ">= 4.7.x <= 5.3.x" peerDependenciesMeta: typescript: optional: true bin: msw: cli/index.js - checksum: a87175f53e3b510dfdfb16e11f2b0d399a9859ce1f249a70741045ce6325b3512075878921d4bd30ad6cb0789cd6fc4f9eac5db68ae425777e96ad208285242d + checksum: 58b6e9ad480f5a3e7b7f6d32e9ea87a4b8b4940614991d8762f4b8a319f9d04fef8db4207bb427450f033cdade9495ef5b87dde91e26ded257c98e3544529cef languageName: node linkType: hard @@ -35693,10 +35700,10 @@ __metadata: languageName: node linkType: hard -"outvariant@npm:^1.2.1, outvariant@npm:^1.4.0": - version: 1.4.0 - resolution: "outvariant@npm:1.4.0" - checksum: ec32dfc315c464bb6e4906b2f450d259ce0b86caf70b70b249054359d9af21a7fccf53a8b6aa232f8d718449e31c1cfa594e6ebffaafe7bf908b502495256d7b +"outvariant@npm:^1.2.1, outvariant@npm:^1.4.0, outvariant@npm:^1.4.2": + version: 1.4.2 + resolution: "outvariant@npm:1.4.2" + checksum: 5d9e2b3edb1cc8be9cbfc1c8c97e8b05137c4384bbfc56e0a465de26c5d2f023e65732ddcda9d46599b06d667fbc0de32c30d2ecd11f6f3f43bcf8ce0d320918 languageName: node linkType: hard @@ -41215,7 +41222,7 @@ __metadata: languageName: node linkType: hard -"strict-event-emitter@npm:^0.5.0, strict-event-emitter@npm:^0.5.1": +"strict-event-emitter@npm:^0.5.1": version: 0.5.1 resolution: "strict-event-emitter@npm:0.5.1" checksum: 350480431bc1c28fdb601ef4976c2f8155fc364b4740f9692dd03e5bdd48aafc99a5e021fe655fbd986d0b803e9f3fc5c4b018b35cb838c4690d60f2a26f1cf3 @@ -42694,6 +42701,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^4.9.0": + version: 4.9.0 + resolution: "type-fest@npm:4.9.0" + checksum: 73383de23237b399a70397a53101152548846d919aebcc7d8733000c6c354dc2632fe37c4a70b8571b79fdbfa099e2d8304c5ac56b3254780acff93e4c7a797f + languageName: node + linkType: hard + "type-is@npm:^1.6.4, type-is@npm:~1.6.18": version: 1.6.18 resolution: "type-is@npm:1.6.18" From acd286092e9b64d88cd99dfbb3bb4f5155c792ce Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 16:29:30 +0000 Subject: [PATCH 237/283] chore(deps): update dependency vite-plugin-node-polyfills to ^0.19.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .changeset/renovate-4b698fb.md | 5 +++++ packages/app/package.json | 2 +- packages/cli/package.json | 2 +- yarn.lock | 34 ++++++++++++++++------------------ 4 files changed, 23 insertions(+), 20 deletions(-) create mode 100644 .changeset/renovate-4b698fb.md diff --git a/.changeset/renovate-4b698fb.md b/.changeset/renovate-4b698fb.md new file mode 100644 index 0000000000..220aa5c848 --- /dev/null +++ b/.changeset/renovate-4b698fb.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Updated dependency `vite-plugin-node-polyfills` to `^0.19.0`. diff --git a/packages/app/package.json b/packages/app/package.json index 53f25883d0..bf2bf74c4c 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -103,7 +103,7 @@ "react-use": "^17.2.4", "vite": "^4.4.9", "vite-plugin-html": "^3.2.0", - "vite-plugin-node-polyfills": "^0.17.0", + "vite-plugin-node-polyfills": "^0.19.0", "zen-observable": "^0.10.0" }, "devDependencies": { diff --git a/packages/cli/package.json b/packages/cli/package.json index a02e7474ff..1c7447b7c3 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -177,7 +177,7 @@ "@vitejs/plugin-react": "^4.0.4", "vite": "^4.4.9", "vite-plugin-html": "^3.2.0", - "vite-plugin-node-polyfills": "^0.17.0" + "vite-plugin-node-polyfills": "^0.19.0" }, "peerDependenciesMeta": { "@vitejs/plugin-react": { diff --git a/yarn.lock b/yarn.lock index d7544bafc4..709d9b905b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3668,7 +3668,7 @@ __metadata: "@vitejs/plugin-react": ^4.0.4 vite: ^4.4.9 vite-plugin-html: ^3.2.0 - vite-plugin-node-polyfills: ^0.17.0 + vite-plugin-node-polyfills: ^0.19.0 peerDependenciesMeta: "@vitejs/plugin-react": optional: true @@ -21658,16 +21658,6 @@ __metadata: languageName: node linkType: hard -"buffer-polyfill@npm:buffer@^6.0.3, buffer@npm:^6.0.3": - version: 6.0.3 - resolution: "buffer@npm:6.0.3" - dependencies: - base64-js: ^1.3.1 - ieee754: ^1.2.1 - checksum: 5ad23293d9a731e4318e420025800b42bf0d264004c0286c8cc010af7a270c7a0f6522e84f54b9ad65cbd6db20b8badbfd8d2ebf4f80fa03dab093b89e68c3f9 - languageName: node - linkType: hard - "buffer-writer@npm:2.0.0": version: 2.0.0 resolution: "buffer-writer@npm:2.0.0" @@ -21713,6 +21703,16 @@ __metadata: languageName: node linkType: hard +"buffer@npm:^6.0.3": + version: 6.0.3 + resolution: "buffer@npm:6.0.3" + dependencies: + base64-js: ^1.3.1 + ieee754: ^1.2.1 + checksum: 5ad23293d9a731e4318e420025800b42bf0d264004c0286c8cc010af7a270c7a0f6522e84f54b9ad65cbd6db20b8badbfd8d2ebf4f80fa03dab093b89e68c3f9 + languageName: node + linkType: hard + "builtin-modules@npm:^3.3.0": version: 3.3.0 resolution: "builtin-modules@npm:3.3.0" @@ -26443,7 +26443,7 @@ __metadata: react-use: ^17.2.4 vite: ^4.4.9 vite-plugin-html: ^3.2.0 - vite-plugin-node-polyfills: ^0.17.0 + vite-plugin-node-polyfills: ^0.19.0 zen-observable: ^0.10.0 languageName: unknown linkType: soft @@ -43800,17 +43800,15 @@ __metadata: languageName: node linkType: hard -"vite-plugin-node-polyfills@npm:^0.17.0": - version: 0.17.0 - resolution: "vite-plugin-node-polyfills@npm:0.17.0" +"vite-plugin-node-polyfills@npm:^0.19.0": + version: 0.19.0 + resolution: "vite-plugin-node-polyfills@npm:0.19.0" dependencies: "@rollup/plugin-inject": ^5.0.5 - buffer-polyfill: "npm:buffer@^6.0.3" node-stdlib-browser: ^1.2.0 - process: ^0.11.10 peerDependencies: vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 - checksum: 760d29c25adfa72b5fc731c1bb0826f9c6cc495afc856d38f634ac811566b158a11b1ea968e5d9d536889072470666e9b933ca38ea0c533854375806503b1729 + checksum: f01962d9c0bdb97c22c8d8994396ae950350c2bbeebcc837303e520216390fb194423cde92a47df5c835375efb86f5b33cc8ab224b0a7bf8e3e2800a66630f60 languageName: node linkType: hard From 4a519aedc8b7a063933b9e2c8b130705d17121e9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 17:05:14 +0000 Subject: [PATCH 238/283] chore(deps): update dependency lint-staged to v15.2.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 144 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 103 insertions(+), 41 deletions(-) diff --git a/yarn.lock b/yarn.lock index 02134ba3f9..5b449d6d32 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20176,12 +20176,12 @@ __metadata: languageName: node linkType: hard -"ansi-escapes@npm:^5.0.0": - version: 5.0.0 - resolution: "ansi-escapes@npm:5.0.0" +"ansi-escapes@npm:^6.2.0": + version: 6.2.0 + resolution: "ansi-escapes@npm:6.2.0" dependencies: - type-fest: ^1.0.2 - checksum: d4b5eb8207df38367945f5dd2ef41e08c28edc192dc766ef18af6b53736682f49d8bfcfa4e4d6ecbc2e2f97c258fda084fb29a9e43b69170b71090f771afccac + type-fest: ^3.0.0 + checksum: f0bc667d5f1ededc3ea89b73c34f0cba95473525b07e1290ddfd3fc868c94614e95f3549f5c4fd0c05424af7d3fd298101fb3d9a52a597d3782508b340783bd7 languageName: node linkType: hard @@ -20240,7 +20240,7 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^6.0.0, ansi-styles@npm:^6.1.0": +"ansi-styles@npm:^6.0.0, ansi-styles@npm:^6.1.0, ansi-styles@npm:^6.2.1": version: 6.2.1 resolution: "ansi-styles@npm:6.2.1" checksum: ef940f2f0ced1a6347398da88a91da7930c33ecac3c77b72c5905f8b8fe402c52e6fde304ff5347f616e27a742da3f1dc76de98f6866c69251ad0b07a66776d9 @@ -22326,13 +22326,13 @@ __metadata: languageName: node linkType: hard -"cli-truncate@npm:^3.1.0": - version: 3.1.0 - resolution: "cli-truncate@npm:3.1.0" +"cli-truncate@npm:^4.0.0": + version: 4.0.0 + resolution: "cli-truncate@npm:4.0.0" dependencies: slice-ansi: ^5.0.0 - string-width: ^5.0.0 - checksum: c3243e41974445691c63f8b405df1d5a24049dc33d324fe448dc572e561a7b772ae982692900b1a5960901cc4fc7def25a629b9c69a4208ee89d12ab3332617a + string-width: ^7.0.0 + checksum: d5149175fd25ca985731bdeec46a55ec237475cf74c1a5e103baea696aceb45e372ac4acbaabf1316f06bd62e348123060f8191ffadfeedebd2a70a2a7fb199d languageName: node linkType: hard @@ -25065,6 +25065,13 @@ __metadata: languageName: node linkType: hard +"emoji-regex@npm:^10.3.0": + version: 10.3.0 + resolution: "emoji-regex@npm:10.3.0" + checksum: 5da48edfeb9462fb1ae5495cff2d79129974c696853fb0ce952cbf560f29a2756825433bf51cfd5157ec7b9f93f46f31d712e896d63e3d8ac9c3832bdb45ab73 + languageName: node + linkType: hard + "emoji-regex@npm:^8.0.0": version: 8.0.0 resolution: "emoji-regex@npm:8.0.0" @@ -27909,6 +27916,13 @@ __metadata: languageName: node linkType: hard +"get-east-asian-width@npm:^1.0.0": + version: 1.2.0 + resolution: "get-east-asian-width@npm:1.2.0" + checksum: ea55f4d4a42c4b00d3d9be3111bc17eb0161f60ed23fc257c1390323bb780a592d7a8bdd550260fd4627dabee9a118cdfa3475ae54edca35ebcd3bdae04179e3 + languageName: node + linkType: hard + "get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.0, get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.0, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.2": version: 1.2.2 resolution: "get-intrinsic@npm:1.2.2" @@ -29888,6 +29902,15 @@ __metadata: languageName: node linkType: hard +"is-fullwidth-code-point@npm:^5.0.0": + version: 5.0.0 + resolution: "is-fullwidth-code-point@npm:5.0.0" + dependencies: + get-east-asian-width: ^1.0.0 + checksum: 8dfb2d2831b9e87983c136f5c335cd9d14c1402973e357a8ff057904612ed84b8cba196319fabedf9aefe4639e14fe3afe9d9966d1d006ebeb40fe1fed4babe5 + languageName: node + linkType: hard + "is-generator-fn@npm:^2.0.0": version: 2.1.0 resolution: "is-generator-fn@npm:2.1.0" @@ -32320,7 +32343,14 @@ __metadata: languageName: node linkType: hard -"lilconfig@npm:2.1.0, lilconfig@npm:^2.0.3": +"lilconfig@npm:3.0.0": + version: 3.0.0 + resolution: "lilconfig@npm:3.0.0" + checksum: a155f1cd24d324ab20dd6974db9ebcf3fb6f2b60175f7c052d917ff8a746b590bc1ee550f6fc3cb1e8716c8b58304e22fe2193febebc0cf16fa86d85e6f896c5 + languageName: node + linkType: hard + +"lilconfig@npm:^2.0.3": version: 2.1.0 resolution: "lilconfig@npm:2.1.0" checksum: 8549bb352b8192375fed4a74694cd61ad293904eee33f9d4866c2192865c44c4eb35d10782966242634e0cbc1e91fe62b1247f148dc5514918e3a966da7ea117 @@ -32380,22 +32410,22 @@ __metadata: linkType: hard "lint-staged@npm:^15.0.0": - version: 15.1.0 - resolution: "lint-staged@npm:15.1.0" + version: 15.2.0 + resolution: "lint-staged@npm:15.2.0" dependencies: chalk: 5.3.0 commander: 11.1.0 debug: 4.3.4 execa: 8.0.1 - lilconfig: 2.1.0 - listr2: 7.0.2 + lilconfig: 3.0.0 + listr2: 8.0.0 micromatch: 4.0.5 pidtree: 0.6.0 string-argv: 0.3.2 yaml: 2.3.4 bin: lint-staged: bin/lint-staged.js - checksum: e99bdedb32d20fa22c0d0798ecf014fd00ac9cce1158373d7caf47855c0b9b4c20d228417677a05ea81f6941f957ae9347dccb3846a48bc1fdd0cdeed2ccf0ef + checksum: 4fb178b8d3ff454f7874697dfbd41017630f61a06296d12ac9dfd578d078c70aff7108b67fab38af94896ef2740a1e7541c1512d0d3c688ed90e6c3af3530f0d languageName: node linkType: hard @@ -32406,17 +32436,17 @@ __metadata: languageName: node linkType: hard -"listr2@npm:7.0.2": - version: 7.0.2 - resolution: "listr2@npm:7.0.2" +"listr2@npm:8.0.0": + version: 8.0.0 + resolution: "listr2@npm:8.0.0" dependencies: - cli-truncate: ^3.1.0 + cli-truncate: ^4.0.0 colorette: ^2.0.20 eventemitter3: ^5.0.1 - log-update: ^5.0.1 + log-update: ^6.0.0 rfdc: ^1.3.0 - wrap-ansi: ^8.1.0 - checksum: 1734c6b9367ceeb09bf372427930a4586b3727097373408f2f840896b9333cc80e53a1a696771a83a7d4d9ada46229843f3052b87f3b0b58c20e9451362c2dd3 + wrap-ansi: ^9.0.0 + checksum: 5cb110a710d14488c71d2207fc5141256abb1f21cbe5ebc12177ae640f94e040a1ef8c031b70ff9f24c4a8fa57c0825a54b534e52bdfaffc122a81082faae8ed languageName: node linkType: hard @@ -32769,16 +32799,16 @@ __metadata: languageName: node linkType: hard -"log-update@npm:^5.0.1": - version: 5.0.1 - resolution: "log-update@npm:5.0.1" +"log-update@npm:^6.0.0": + version: 6.0.0 + resolution: "log-update@npm:6.0.0" dependencies: - ansi-escapes: ^5.0.0 + ansi-escapes: ^6.2.0 cli-cursor: ^4.0.0 - slice-ansi: ^5.0.0 - strip-ansi: ^7.0.1 - wrap-ansi: ^8.0.1 - checksum: 2c6b47dcce6f9233df6d232a37d9834cb3657a0749ef6398f1706118de74c55f158587d4128c225297ea66803f35c5ac3db4f3f617046d817233c45eedc32ef1 + slice-ansi: ^7.0.0 + strip-ansi: ^7.1.0 + wrap-ansi: ^9.0.0 + checksum: 8803ceba2fb28626951b85de598c8d5a4f5e39f1f767cc54fd925412cc7780ba89ce1dbec24dc96fa46f89d226e1ae984534aa729dc9c9b734e36bb805428ffa languageName: node linkType: hard @@ -40593,6 +40623,16 @@ __metadata: languageName: node linkType: hard +"slice-ansi@npm:^7.0.0": + version: 7.1.0 + resolution: "slice-ansi@npm:7.1.0" + dependencies: + ansi-styles: ^6.2.1 + is-fullwidth-code-point: ^5.0.0 + checksum: 10313dd3cf7a2e4b265f527b1684c7c568210b09743fd1bd74f2194715ed13ffba653dc93a5fa79e3b1711518b8990a732cb7143aa01ddafe626e99dfa6474b2 + languageName: node + linkType: hard + "slugify@npm:^1.6.4": version: 1.6.6 resolution: "slugify@npm:1.6.6" @@ -41280,7 +41320,7 @@ __metadata: languageName: node linkType: hard -"string-width@npm:^5.0.0, string-width@npm:^5.0.1, string-width@npm:^5.1.2": +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": version: 5.1.2 resolution: "string-width@npm:5.1.2" dependencies: @@ -41291,6 +41331,17 @@ __metadata: languageName: node linkType: hard +"string-width@npm:^7.0.0": + version: 7.0.0 + resolution: "string-width@npm:7.0.0" + dependencies: + emoji-regex: ^10.3.0 + get-east-asian-width: ^1.0.0 + strip-ansi: ^7.1.0 + checksum: bc0de5700a2690895169fce447ec4ed44bc62de80312c2093d5606bfd48319bb88e48a99e97f269dff2bc9577448b91c26b3804c16e7d9b389699795e4655c3b + languageName: node + linkType: hard + "string.prototype.matchall@npm:^4.0.8": version: 4.0.8 resolution: "string.prototype.matchall@npm:4.0.8" @@ -42689,13 +42740,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^1.0.2": - version: 1.4.0 - resolution: "type-fest@npm:1.4.0" - checksum: b011c3388665b097ae6a109a437a04d6f61d81b7357f74cbcb02246f2f5bd72b888ae33631b99871388122ba0a87f4ff1c94078e7119ff22c70e52c0ff828201 - languageName: node - linkType: hard - "type-fest@npm:^2.19.0": version: 2.19.0 resolution: "type-fest@npm:2.19.0" @@ -42703,6 +42747,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^3.0.0": + version: 3.13.1 + resolution: "type-fest@npm:3.13.1" + checksum: c06b0901d54391dc46de3802375f5579868949d71f93b425ce564e19a428a0d411ae8d8cb0e300d330071d86152c3ea86e744c3f2860a42a79585b6ec2fdae8e + languageName: node + linkType: hard + "type-fest@npm:^4.9.0": version: 4.9.0 resolution: "type-fest@npm:4.9.0" @@ -44459,7 +44510,7 @@ __metadata: languageName: node linkType: hard -"wrap-ansi@npm:^8.0.1, wrap-ansi@npm:^8.1.0": +"wrap-ansi@npm:^8.1.0": version: 8.1.0 resolution: "wrap-ansi@npm:8.1.0" dependencies: @@ -44470,6 +44521,17 @@ __metadata: languageName: node linkType: hard +"wrap-ansi@npm:^9.0.0": + version: 9.0.0 + resolution: "wrap-ansi@npm:9.0.0" + dependencies: + ansi-styles: ^6.2.1 + string-width: ^7.0.0 + strip-ansi: ^7.1.0 + checksum: b2d43b76b3d8dcbdd64768165e548aad3e54e1cae4ecd31bac9966faaa7cf0b0345677ad6879db10ba58eb446ba8fa44fb82b4951872fd397f096712467a809f + languageName: node + linkType: hard + "wrappy@npm:1": version: 1.0.2 resolution: "wrappy@npm:1.0.2" From 9e3886f0def5d2bbbfa4d4bb0a63398eed946dc5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 17:07:36 +0000 Subject: [PATCH 239/283] chore(deps): update docker/metadata-action action to v5.5.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/uffizzi-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/uffizzi-build.yml b/.github/workflows/uffizzi-build.yml index c0bbde49f3..4e53a5a989 100644 --- a/.github/workflows/uffizzi-build.yml +++ b/.github/workflows/uffizzi-build.yml @@ -60,7 +60,7 @@ jobs: - name: Docker metadata id: meta - uses: docker/metadata-action@e6428a5c4e294a61438ed7f43155db912025b6b3 # v5.2.0 + uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c # v5.5.0 with: images: registry.uffizzi.com/${{ env.UUID_TAG_APP }} tags: type=raw,value=60d From db6eac26bef926298bb970c62708f72b94358552 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 17:07:43 +0000 Subject: [PATCH 240/283] chore(deps): update github/codeql-action action to v2.23.1 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- .github/workflows/sync_snyk-monitor.yml | 2 +- .github/workflows/verify_codeql.yml | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 64472e71c6..a05d5acee1 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -66,6 +66,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: 'Upload to code-scanning' - uses: github/codeql-action/upload-sarif@1500a131381b66de0c52ac28abb13cd79f4b7ecc # v2.22.12 + uses: github/codeql-action/upload-sarif@4759df8df70c5ebe7042c3029bbace20eee13edd # v2.23.1 with: sarif_file: results.sarif diff --git a/.github/workflows/sync_snyk-monitor.yml b/.github/workflows/sync_snyk-monitor.yml index 04367c2639..a4ae1ac803 100644 --- a/.github/workflows/sync_snyk-monitor.yml +++ b/.github/workflows/sync_snyk-monitor.yml @@ -58,6 +58,6 @@ jobs: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} NODE_OPTIONS: --max-old-space-size=7168 - name: Upload Snyk report - uses: github/codeql-action/upload-sarif@v2.22.12 + uses: github/codeql-action/upload-sarif@v2.23.1 with: sarif_file: snyk.sarif diff --git a/.github/workflows/verify_codeql.yml b/.github/workflows/verify_codeql.yml index 61be150ff8..43a762e3c9 100644 --- a/.github/workflows/verify_codeql.yml +++ b/.github/workflows/verify_codeql.yml @@ -55,7 +55,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2.22.12 + uses: github/codeql-action/init@v2.23.1 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -66,7 +66,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v2.22.12 + uses: github/codeql-action/autobuild@v2.23.1 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -80,4 +80,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2.22.12 + uses: github/codeql-action/analyze@v2.23.1 From d2e576d55aead2de14810485b4c6ac796eda6192 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 18 Jan 2024 17:32:48 +0100 Subject: [PATCH 241/283] frontend-plugin-api: swtich IconApi.listIconKeys to return an array direcly instead Signed-off-by: Patrik Oldsberg --- .../src/compatWrapper/BackwardsCompatProvider.tsx | 4 +--- .../IconsApi/{IconsApi.ts => DefaultIconsApi.ts} | 6 +++--- .../src/apis/implementations/IconsApi/index.ts | 2 +- packages/frontend-plugin-api/api-report.md | 4 +--- .../frontend-plugin-api/src/apis/definitions/IconsApi.ts | 2 +- 5 files changed, 7 insertions(+), 11 deletions(-) rename packages/frontend-app-api/src/apis/implementations/IconsApi/{IconsApi.ts => DefaultIconsApi.ts} (91%) diff --git a/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx b/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx index 1dd64efb89..8c6ef1f375 100644 --- a/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx +++ b/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx @@ -122,10 +122,8 @@ function LegacyAppContextProvider(props: { children: ReactNode }) { }, getSystemIcons(): Record { - const { keys } = iconsApi.listIconKeys(); - return Object.fromEntries( - Array.from(keys).map(key => [key, iconsApi.getIcon(key)!]), + iconsApi.listIconKeys().map(key => [key, iconsApi.getIcon(key)!]), ); }, diff --git a/packages/frontend-app-api/src/apis/implementations/IconsApi/IconsApi.ts b/packages/frontend-app-api/src/apis/implementations/IconsApi/DefaultIconsApi.ts similarity index 91% rename from packages/frontend-app-api/src/apis/implementations/IconsApi/IconsApi.ts rename to packages/frontend-app-api/src/apis/implementations/IconsApi/DefaultIconsApi.ts index f64bbc67f9..53a7fa6421 100644 --- a/packages/frontend-app-api/src/apis/implementations/IconsApi/IconsApi.ts +++ b/packages/frontend-app-api/src/apis/implementations/IconsApi/DefaultIconsApi.ts @@ -32,7 +32,7 @@ export class DefaultIconsApi implements IconsApi { return this.#icons.get(key); } - listIconKeys: IconsApi['listIconKeys'] = () => { - return { keys: this.#icons.keys() }; - }; + listIconKeys(): string[] { + return Array.from(this.#icons.keys()); + } } diff --git a/packages/frontend-app-api/src/apis/implementations/IconsApi/index.ts b/packages/frontend-app-api/src/apis/implementations/IconsApi/index.ts index 4a73182e84..e07f6379ed 100644 --- a/packages/frontend-app-api/src/apis/implementations/IconsApi/index.ts +++ b/packages/frontend-app-api/src/apis/implementations/IconsApi/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { DefaultIconsApi } from './IconsApi'; +export { DefaultIconsApi } from './DefaultIconsApi'; diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index fd0e1302b7..3a7a0f3ee6 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -981,9 +981,7 @@ export interface IconsApi { // (undocumented) getIcon(key: string): IconComponent | undefined; // (undocumented) - listIconKeys(): { - keys: Iterable; - }; + listIconKeys(): string[]; } // @public diff --git a/packages/frontend-plugin-api/src/apis/definitions/IconsApi.ts b/packages/frontend-plugin-api/src/apis/definitions/IconsApi.ts index daef2ca40f..aa5b7f4fac 100644 --- a/packages/frontend-plugin-api/src/apis/definitions/IconsApi.ts +++ b/packages/frontend-plugin-api/src/apis/definitions/IconsApi.ts @@ -25,7 +25,7 @@ import { IconComponent } from '../../icons'; export interface IconsApi { getIcon(key: string): IconComponent | undefined; - listIconKeys(): { keys: Iterable }; + listIconKeys(): string[]; } /** From 48738d9bc358d9f71f14976c58967e72cb5bced3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 18:44:45 +0000 Subject: [PATCH 242/283] chore(deps): update ruby docker tag to v3.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- plugins/scaffolder-backend-module-rails/Rails.dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend-module-rails/Rails.dockerfile b/plugins/scaffolder-backend-module-rails/Rails.dockerfile index 921faa601d..8ea3fc370a 100644 --- a/plugins/scaffolder-backend-module-rails/Rails.dockerfile +++ b/plugins/scaffolder-backend-module-rails/Rails.dockerfile @@ -1,4 +1,4 @@ -FROM ruby:3.2 +FROM ruby:3.3 RUN apt-get update -qq && \ apt-get install -y nodejs postgresql-client git && \ From 3b105bf353eb2a82fc071192a43bec1be3eae2ba Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 18:53:16 +0000 Subject: [PATCH 243/283] fix(deps): update aws-sdk-js-v3 monorepo Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 1662 +++++++++++++++++++++++++++-------------------------- 1 file changed, 841 insertions(+), 821 deletions(-) diff --git a/yarn.lock b/yarn.lock index 5b449d6d32..220114f30e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -363,505 +363,515 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-cognito-identity@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/client-cognito-identity@npm:3.465.0" +"@aws-sdk/client-cognito-identity@npm:3.490.0": + version: 3.490.0 + resolution: "@aws-sdk/client-cognito-identity@npm:3.490.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.465.0 - "@aws-sdk/core": 3.465.0 - "@aws-sdk/credential-provider-node": 3.465.0 - "@aws-sdk/middleware-host-header": 3.465.0 - "@aws-sdk/middleware-logger": 3.465.0 - "@aws-sdk/middleware-recursion-detection": 3.465.0 - "@aws-sdk/middleware-signing": 3.465.0 - "@aws-sdk/middleware-user-agent": 3.465.0 - "@aws-sdk/region-config-resolver": 3.465.0 - "@aws-sdk/types": 3.465.0 - "@aws-sdk/util-endpoints": 3.465.0 - "@aws-sdk/util-user-agent-browser": 3.465.0 - "@aws-sdk/util-user-agent-node": 3.465.0 - "@smithy/config-resolver": ^2.0.18 - "@smithy/fetch-http-handler": ^2.2.6 - "@smithy/hash-node": ^2.0.15 - "@smithy/invalid-dependency": ^2.0.13 - "@smithy/middleware-content-length": ^2.0.15 - "@smithy/middleware-endpoint": ^2.2.0 - "@smithy/middleware-retry": ^2.0.20 - "@smithy/middleware-serde": ^2.0.13 - "@smithy/middleware-stack": ^2.0.7 - "@smithy/node-config-provider": ^2.1.5 - "@smithy/node-http-handler": ^2.1.9 - "@smithy/protocol-http": ^3.0.9 - "@smithy/smithy-client": ^2.1.15 - "@smithy/types": ^2.5.0 - "@smithy/url-parser": ^2.0.13 + "@aws-sdk/client-sts": 3.490.0 + "@aws-sdk/core": 3.490.0 + "@aws-sdk/credential-provider-node": 3.490.0 + "@aws-sdk/middleware-host-header": 3.489.0 + "@aws-sdk/middleware-logger": 3.489.0 + "@aws-sdk/middleware-recursion-detection": 3.489.0 + "@aws-sdk/middleware-signing": 3.489.0 + "@aws-sdk/middleware-user-agent": 3.489.0 + "@aws-sdk/region-config-resolver": 3.489.0 + "@aws-sdk/types": 3.489.0 + "@aws-sdk/util-endpoints": 3.489.0 + "@aws-sdk/util-user-agent-browser": 3.489.0 + "@aws-sdk/util-user-agent-node": 3.489.0 + "@smithy/config-resolver": ^2.0.23 + "@smithy/core": ^1.2.2 + "@smithy/fetch-http-handler": ^2.3.2 + "@smithy/hash-node": ^2.0.18 + "@smithy/invalid-dependency": ^2.0.16 + "@smithy/middleware-content-length": ^2.0.18 + "@smithy/middleware-endpoint": ^2.3.0 + "@smithy/middleware-retry": ^2.0.26 + "@smithy/middleware-serde": ^2.0.16 + "@smithy/middleware-stack": ^2.0.10 + "@smithy/node-config-provider": ^2.1.9 + "@smithy/node-http-handler": ^2.2.2 + "@smithy/protocol-http": ^3.0.12 + "@smithy/smithy-client": ^2.2.1 + "@smithy/types": ^2.8.0 + "@smithy/url-parser": ^2.0.16 "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.0 + "@smithy/util-body-length-browser": ^2.0.1 "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.19 - "@smithy/util-defaults-mode-node": ^2.0.25 - "@smithy/util-endpoints": ^1.0.4 - "@smithy/util-retry": ^2.0.6 + "@smithy/util-defaults-mode-browser": ^2.0.24 + "@smithy/util-defaults-mode-node": ^2.0.32 + "@smithy/util-endpoints": ^1.0.8 + "@smithy/util-retry": ^2.0.9 "@smithy/util-utf8": ^2.0.2 tslib: ^2.5.0 - checksum: e02382ef3138cae6c0b7a23cce4df4105ac440e2644b59a4a151033128a8db7e6bdc4d8eab60e550f7e686bb5900d57c14deee2d889db3962a7bf76f17a2d665 + checksum: 4b131c722d611242c8d5eb961115fb60f40bd228ecb2f6ce4851d30bae7b3b39b68cfd6ca363f901e8c16571539d37c7a617dae6681aa0bcfeec189a6b5afcea languageName: node linkType: hard "@aws-sdk/client-eks@npm:^3.350.0": - version: 3.465.0 - resolution: "@aws-sdk/client-eks@npm:3.465.0" + version: 3.490.0 + resolution: "@aws-sdk/client-eks@npm:3.490.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.465.0 - "@aws-sdk/core": 3.465.0 - "@aws-sdk/credential-provider-node": 3.465.0 - "@aws-sdk/middleware-host-header": 3.465.0 - "@aws-sdk/middleware-logger": 3.465.0 - "@aws-sdk/middleware-recursion-detection": 3.465.0 - "@aws-sdk/middleware-signing": 3.465.0 - "@aws-sdk/middleware-user-agent": 3.465.0 - "@aws-sdk/region-config-resolver": 3.465.0 - "@aws-sdk/types": 3.465.0 - "@aws-sdk/util-endpoints": 3.465.0 - "@aws-sdk/util-user-agent-browser": 3.465.0 - "@aws-sdk/util-user-agent-node": 3.465.0 - "@smithy/config-resolver": ^2.0.18 - "@smithy/fetch-http-handler": ^2.2.6 - "@smithy/hash-node": ^2.0.15 - "@smithy/invalid-dependency": ^2.0.13 - "@smithy/middleware-content-length": ^2.0.15 - "@smithy/middleware-endpoint": ^2.2.0 - "@smithy/middleware-retry": ^2.0.20 - "@smithy/middleware-serde": ^2.0.13 - "@smithy/middleware-stack": ^2.0.7 - "@smithy/node-config-provider": ^2.1.5 - "@smithy/node-http-handler": ^2.1.9 - "@smithy/protocol-http": ^3.0.9 - "@smithy/smithy-client": ^2.1.15 - "@smithy/types": ^2.5.0 - "@smithy/url-parser": ^2.0.13 + "@aws-sdk/client-sts": 3.490.0 + "@aws-sdk/core": 3.490.0 + "@aws-sdk/credential-provider-node": 3.490.0 + "@aws-sdk/middleware-host-header": 3.489.0 + "@aws-sdk/middleware-logger": 3.489.0 + "@aws-sdk/middleware-recursion-detection": 3.489.0 + "@aws-sdk/middleware-signing": 3.489.0 + "@aws-sdk/middleware-user-agent": 3.489.0 + "@aws-sdk/region-config-resolver": 3.489.0 + "@aws-sdk/types": 3.489.0 + "@aws-sdk/util-endpoints": 3.489.0 + "@aws-sdk/util-user-agent-browser": 3.489.0 + "@aws-sdk/util-user-agent-node": 3.489.0 + "@smithy/config-resolver": ^2.0.23 + "@smithy/core": ^1.2.2 + "@smithy/fetch-http-handler": ^2.3.2 + "@smithy/hash-node": ^2.0.18 + "@smithy/invalid-dependency": ^2.0.16 + "@smithy/middleware-content-length": ^2.0.18 + "@smithy/middleware-endpoint": ^2.3.0 + "@smithy/middleware-retry": ^2.0.26 + "@smithy/middleware-serde": ^2.0.16 + "@smithy/middleware-stack": ^2.0.10 + "@smithy/node-config-provider": ^2.1.9 + "@smithy/node-http-handler": ^2.2.2 + "@smithy/protocol-http": ^3.0.12 + "@smithy/smithy-client": ^2.2.1 + "@smithy/types": ^2.8.0 + "@smithy/url-parser": ^2.0.16 "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.0 + "@smithy/util-body-length-browser": ^2.0.1 "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.19 - "@smithy/util-defaults-mode-node": ^2.0.25 - "@smithy/util-endpoints": ^1.0.4 - "@smithy/util-retry": ^2.0.6 + "@smithy/util-defaults-mode-browser": ^2.0.24 + "@smithy/util-defaults-mode-node": ^2.0.32 + "@smithy/util-endpoints": ^1.0.8 + "@smithy/util-retry": ^2.0.9 "@smithy/util-utf8": ^2.0.2 - "@smithy/util-waiter": ^2.0.13 + "@smithy/util-waiter": ^2.0.16 tslib: ^2.5.0 uuid: ^8.3.2 - checksum: 9359da8f2c1e68de36b40ad6767d07442322db9c845f745f14213fa9672661b88aea7a61ab2bfad6f7fee7f3dde1efa0a55fe0b5577e998e2ae5e17495c9c8ff + checksum: 367e3c987f644b0b4a6c5fba1ef1e6caa52594205ac9efe095960e00dcf4b0191f143080cfbdbb3807b91140cda14973f734e536104b355908d9c7ed3ba9fa64 languageName: node linkType: hard "@aws-sdk/client-organizations@npm:^3.350.0": - version: 3.465.0 - resolution: "@aws-sdk/client-organizations@npm:3.465.0" + version: 3.490.0 + resolution: "@aws-sdk/client-organizations@npm:3.490.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.465.0 - "@aws-sdk/core": 3.465.0 - "@aws-sdk/credential-provider-node": 3.465.0 - "@aws-sdk/middleware-host-header": 3.465.0 - "@aws-sdk/middleware-logger": 3.465.0 - "@aws-sdk/middleware-recursion-detection": 3.465.0 - "@aws-sdk/middleware-signing": 3.465.0 - "@aws-sdk/middleware-user-agent": 3.465.0 - "@aws-sdk/region-config-resolver": 3.465.0 - "@aws-sdk/types": 3.465.0 - "@aws-sdk/util-endpoints": 3.465.0 - "@aws-sdk/util-user-agent-browser": 3.465.0 - "@aws-sdk/util-user-agent-node": 3.465.0 - "@smithy/config-resolver": ^2.0.18 - "@smithy/fetch-http-handler": ^2.2.6 - "@smithy/hash-node": ^2.0.15 - "@smithy/invalid-dependency": ^2.0.13 - "@smithy/middleware-content-length": ^2.0.15 - "@smithy/middleware-endpoint": ^2.2.0 - "@smithy/middleware-retry": ^2.0.20 - "@smithy/middleware-serde": ^2.0.13 - "@smithy/middleware-stack": ^2.0.7 - "@smithy/node-config-provider": ^2.1.5 - "@smithy/node-http-handler": ^2.1.9 - "@smithy/protocol-http": ^3.0.9 - "@smithy/smithy-client": ^2.1.15 - "@smithy/types": ^2.5.0 - "@smithy/url-parser": ^2.0.13 + "@aws-sdk/client-sts": 3.490.0 + "@aws-sdk/core": 3.490.0 + "@aws-sdk/credential-provider-node": 3.490.0 + "@aws-sdk/middleware-host-header": 3.489.0 + "@aws-sdk/middleware-logger": 3.489.0 + "@aws-sdk/middleware-recursion-detection": 3.489.0 + "@aws-sdk/middleware-signing": 3.489.0 + "@aws-sdk/middleware-user-agent": 3.489.0 + "@aws-sdk/region-config-resolver": 3.489.0 + "@aws-sdk/types": 3.489.0 + "@aws-sdk/util-endpoints": 3.489.0 + "@aws-sdk/util-user-agent-browser": 3.489.0 + "@aws-sdk/util-user-agent-node": 3.489.0 + "@smithy/config-resolver": ^2.0.23 + "@smithy/core": ^1.2.2 + "@smithy/fetch-http-handler": ^2.3.2 + "@smithy/hash-node": ^2.0.18 + "@smithy/invalid-dependency": ^2.0.16 + "@smithy/middleware-content-length": ^2.0.18 + "@smithy/middleware-endpoint": ^2.3.0 + "@smithy/middleware-retry": ^2.0.26 + "@smithy/middleware-serde": ^2.0.16 + "@smithy/middleware-stack": ^2.0.10 + "@smithy/node-config-provider": ^2.1.9 + "@smithy/node-http-handler": ^2.2.2 + "@smithy/protocol-http": ^3.0.12 + "@smithy/smithy-client": ^2.2.1 + "@smithy/types": ^2.8.0 + "@smithy/url-parser": ^2.0.16 "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.0 + "@smithy/util-body-length-browser": ^2.0.1 "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.19 - "@smithy/util-defaults-mode-node": ^2.0.25 - "@smithy/util-endpoints": ^1.0.4 - "@smithy/util-retry": ^2.0.6 + "@smithy/util-defaults-mode-browser": ^2.0.24 + "@smithy/util-defaults-mode-node": ^2.0.32 + "@smithy/util-endpoints": ^1.0.8 + "@smithy/util-retry": ^2.0.9 "@smithy/util-utf8": ^2.0.2 tslib: ^2.5.0 - checksum: 556b8f7233c71a075504be48ec5dcf2597cc95c3247fba0c992de6ba91db994e8560f80d9a05022c3c9f9c4764fed361488c9c3c35dfe1d2c370eee3f5ae93d8 + checksum: 073bc5ecc31e7c0cb0fd195e868f17946e7f60e12cdab3402fd1752374939915affb8f15fb55697f1a626736d7b05e35e65d466a5dddfd6e091eb0e16803f8a8 languageName: node linkType: hard "@aws-sdk/client-s3@npm:^3.350.0": - version: 3.465.0 - resolution: "@aws-sdk/client-s3@npm:3.465.0" + version: 3.490.0 + resolution: "@aws-sdk/client-s3@npm:3.490.0" dependencies: "@aws-crypto/sha1-browser": 3.0.0 "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.465.0 - "@aws-sdk/core": 3.465.0 - "@aws-sdk/credential-provider-node": 3.465.0 - "@aws-sdk/middleware-bucket-endpoint": 3.465.0 - "@aws-sdk/middleware-expect-continue": 3.465.0 - "@aws-sdk/middleware-flexible-checksums": 3.465.0 - "@aws-sdk/middleware-host-header": 3.465.0 - "@aws-sdk/middleware-location-constraint": 3.465.0 - "@aws-sdk/middleware-logger": 3.465.0 - "@aws-sdk/middleware-recursion-detection": 3.465.0 - "@aws-sdk/middleware-sdk-s3": 3.465.0 - "@aws-sdk/middleware-signing": 3.465.0 - "@aws-sdk/middleware-ssec": 3.465.0 - "@aws-sdk/middleware-user-agent": 3.465.0 - "@aws-sdk/region-config-resolver": 3.465.0 - "@aws-sdk/signature-v4-multi-region": 3.465.0 - "@aws-sdk/types": 3.465.0 - "@aws-sdk/util-endpoints": 3.465.0 - "@aws-sdk/util-user-agent-browser": 3.465.0 - "@aws-sdk/util-user-agent-node": 3.465.0 - "@aws-sdk/xml-builder": 3.465.0 - "@smithy/config-resolver": ^2.0.18 - "@smithy/eventstream-serde-browser": ^2.0.13 - "@smithy/eventstream-serde-config-resolver": ^2.0.13 - "@smithy/eventstream-serde-node": ^2.0.13 - "@smithy/fetch-http-handler": ^2.2.6 - "@smithy/hash-blob-browser": ^2.0.14 - "@smithy/hash-node": ^2.0.15 - "@smithy/hash-stream-node": ^2.0.15 - "@smithy/invalid-dependency": ^2.0.13 - "@smithy/md5-js": ^2.0.15 - "@smithy/middleware-content-length": ^2.0.15 - "@smithy/middleware-endpoint": ^2.2.0 - "@smithy/middleware-retry": ^2.0.20 - "@smithy/middleware-serde": ^2.0.13 - "@smithy/middleware-stack": ^2.0.7 - "@smithy/node-config-provider": ^2.1.5 - "@smithy/node-http-handler": ^2.1.9 - "@smithy/protocol-http": ^3.0.9 - "@smithy/smithy-client": ^2.1.15 - "@smithy/types": ^2.5.0 - "@smithy/url-parser": ^2.0.13 + "@aws-sdk/client-sts": 3.490.0 + "@aws-sdk/core": 3.490.0 + "@aws-sdk/credential-provider-node": 3.490.0 + "@aws-sdk/middleware-bucket-endpoint": 3.489.0 + "@aws-sdk/middleware-expect-continue": 3.489.0 + "@aws-sdk/middleware-flexible-checksums": 3.489.0 + "@aws-sdk/middleware-host-header": 3.489.0 + "@aws-sdk/middleware-location-constraint": 3.489.0 + "@aws-sdk/middleware-logger": 3.489.0 + "@aws-sdk/middleware-recursion-detection": 3.489.0 + "@aws-sdk/middleware-sdk-s3": 3.489.0 + "@aws-sdk/middleware-signing": 3.489.0 + "@aws-sdk/middleware-ssec": 3.489.0 + "@aws-sdk/middleware-user-agent": 3.489.0 + "@aws-sdk/region-config-resolver": 3.489.0 + "@aws-sdk/signature-v4-multi-region": 3.489.0 + "@aws-sdk/types": 3.489.0 + "@aws-sdk/util-endpoints": 3.489.0 + "@aws-sdk/util-user-agent-browser": 3.489.0 + "@aws-sdk/util-user-agent-node": 3.489.0 + "@aws-sdk/xml-builder": 3.485.0 + "@smithy/config-resolver": ^2.0.23 + "@smithy/core": ^1.2.2 + "@smithy/eventstream-serde-browser": ^2.0.16 + "@smithy/eventstream-serde-config-resolver": ^2.0.16 + "@smithy/eventstream-serde-node": ^2.0.16 + "@smithy/fetch-http-handler": ^2.3.2 + "@smithy/hash-blob-browser": ^2.0.17 + "@smithy/hash-node": ^2.0.18 + "@smithy/hash-stream-node": ^2.0.18 + "@smithy/invalid-dependency": ^2.0.16 + "@smithy/md5-js": ^2.0.18 + "@smithy/middleware-content-length": ^2.0.18 + "@smithy/middleware-endpoint": ^2.3.0 + "@smithy/middleware-retry": ^2.0.26 + "@smithy/middleware-serde": ^2.0.16 + "@smithy/middleware-stack": ^2.0.10 + "@smithy/node-config-provider": ^2.1.9 + "@smithy/node-http-handler": ^2.2.2 + "@smithy/protocol-http": ^3.0.12 + "@smithy/smithy-client": ^2.2.1 + "@smithy/types": ^2.8.0 + "@smithy/url-parser": ^2.0.16 "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.0 + "@smithy/util-body-length-browser": ^2.0.1 "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.19 - "@smithy/util-defaults-mode-node": ^2.0.25 - "@smithy/util-endpoints": ^1.0.4 - "@smithy/util-retry": ^2.0.6 - "@smithy/util-stream": ^2.0.20 + "@smithy/util-defaults-mode-browser": ^2.0.24 + "@smithy/util-defaults-mode-node": ^2.0.32 + "@smithy/util-endpoints": ^1.0.8 + "@smithy/util-retry": ^2.0.9 + "@smithy/util-stream": ^2.0.24 "@smithy/util-utf8": ^2.0.2 - "@smithy/util-waiter": ^2.0.13 + "@smithy/util-waiter": ^2.0.16 fast-xml-parser: 4.2.5 tslib: ^2.5.0 - checksum: 05b80b8f3f9dd56b98fba39f8ec01e4f9db1ffd515594def1cc9e27a10d9f188042b482e92fd1865c1eaa91f633a28cf500ff212fa4a7a2f5c58108e9f3829d5 + checksum: 28fc1c384bdba8c374ac8f150350feb5b6e8afaef76aaba2705d8d06d60dec9a209869888a3e91e75c88454084940916b1bc6070cc422d50712af7dd20a66ccf languageName: node linkType: hard "@aws-sdk/client-sqs@npm:^3.350.0": - version: 3.465.0 - resolution: "@aws-sdk/client-sqs@npm:3.465.0" + version: 3.490.0 + resolution: "@aws-sdk/client-sqs@npm:3.490.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.465.0 - "@aws-sdk/core": 3.465.0 - "@aws-sdk/credential-provider-node": 3.465.0 - "@aws-sdk/middleware-host-header": 3.465.0 - "@aws-sdk/middleware-logger": 3.465.0 - "@aws-sdk/middleware-recursion-detection": 3.465.0 - "@aws-sdk/middleware-sdk-sqs": 3.465.0 - "@aws-sdk/middleware-signing": 3.465.0 - "@aws-sdk/middleware-user-agent": 3.465.0 - "@aws-sdk/region-config-resolver": 3.465.0 - "@aws-sdk/types": 3.465.0 - "@aws-sdk/util-endpoints": 3.465.0 - "@aws-sdk/util-user-agent-browser": 3.465.0 - "@aws-sdk/util-user-agent-node": 3.465.0 - "@smithy/config-resolver": ^2.0.18 - "@smithy/fetch-http-handler": ^2.2.6 - "@smithy/hash-node": ^2.0.15 - "@smithy/invalid-dependency": ^2.0.13 - "@smithy/md5-js": ^2.0.15 - "@smithy/middleware-content-length": ^2.0.15 - "@smithy/middleware-endpoint": ^2.2.0 - "@smithy/middleware-retry": ^2.0.20 - "@smithy/middleware-serde": ^2.0.13 - "@smithy/middleware-stack": ^2.0.7 - "@smithy/node-config-provider": ^2.1.5 - "@smithy/node-http-handler": ^2.1.9 - "@smithy/protocol-http": ^3.0.9 - "@smithy/smithy-client": ^2.1.15 - "@smithy/types": ^2.5.0 - "@smithy/url-parser": ^2.0.13 + "@aws-sdk/client-sts": 3.490.0 + "@aws-sdk/core": 3.490.0 + "@aws-sdk/credential-provider-node": 3.490.0 + "@aws-sdk/middleware-host-header": 3.489.0 + "@aws-sdk/middleware-logger": 3.489.0 + "@aws-sdk/middleware-recursion-detection": 3.489.0 + "@aws-sdk/middleware-sdk-sqs": 3.489.0 + "@aws-sdk/middleware-user-agent": 3.489.0 + "@aws-sdk/region-config-resolver": 3.489.0 + "@aws-sdk/types": 3.489.0 + "@aws-sdk/util-endpoints": 3.489.0 + "@aws-sdk/util-user-agent-browser": 3.489.0 + "@aws-sdk/util-user-agent-node": 3.489.0 + "@smithy/config-resolver": ^2.0.23 + "@smithy/core": ^1.2.2 + "@smithy/fetch-http-handler": ^2.3.2 + "@smithy/hash-node": ^2.0.18 + "@smithy/invalid-dependency": ^2.0.16 + "@smithy/md5-js": ^2.0.18 + "@smithy/middleware-content-length": ^2.0.18 + "@smithy/middleware-endpoint": ^2.3.0 + "@smithy/middleware-retry": ^2.0.26 + "@smithy/middleware-serde": ^2.0.16 + "@smithy/middleware-stack": ^2.0.10 + "@smithy/node-config-provider": ^2.1.9 + "@smithy/node-http-handler": ^2.2.2 + "@smithy/protocol-http": ^3.0.12 + "@smithy/smithy-client": ^2.2.1 + "@smithy/types": ^2.8.0 + "@smithy/url-parser": ^2.0.16 "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.0 + "@smithy/util-body-length-browser": ^2.0.1 "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.19 - "@smithy/util-defaults-mode-node": ^2.0.25 - "@smithy/util-endpoints": ^1.0.4 - "@smithy/util-retry": ^2.0.6 + "@smithy/util-defaults-mode-browser": ^2.0.24 + "@smithy/util-defaults-mode-node": ^2.0.32 + "@smithy/util-endpoints": ^1.0.8 + "@smithy/util-middleware": ^2.0.9 + "@smithy/util-retry": ^2.0.9 "@smithy/util-utf8": ^2.0.2 tslib: ^2.5.0 - checksum: 0137ad4ca2fe482a21955f6085dc76eccc87ec3e3b36b18171aa0726f582b0f2c5041e6fa3f076ce60e266865262d7d52fa921abd1c958af7b3eafa8160d2beb + checksum: 394f351ca8feff09b631eab6e285068379384a592832ec8ae502a15f60a475f2aa43e29d74b0dd5c2732610a9f7f122148ee442550975ecded53368b8d01a6b1 languageName: node linkType: hard -"@aws-sdk/client-sso@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/client-sso@npm:3.465.0" +"@aws-sdk/client-sso@npm:3.490.0": + version: 3.490.0 + resolution: "@aws-sdk/client-sso@npm:3.490.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/core": 3.465.0 - "@aws-sdk/middleware-host-header": 3.465.0 - "@aws-sdk/middleware-logger": 3.465.0 - "@aws-sdk/middleware-recursion-detection": 3.465.0 - "@aws-sdk/middleware-user-agent": 3.465.0 - "@aws-sdk/region-config-resolver": 3.465.0 - "@aws-sdk/types": 3.465.0 - "@aws-sdk/util-endpoints": 3.465.0 - "@aws-sdk/util-user-agent-browser": 3.465.0 - "@aws-sdk/util-user-agent-node": 3.465.0 - "@smithy/config-resolver": ^2.0.18 - "@smithy/fetch-http-handler": ^2.2.6 - "@smithy/hash-node": ^2.0.15 - "@smithy/invalid-dependency": ^2.0.13 - "@smithy/middleware-content-length": ^2.0.15 - "@smithy/middleware-endpoint": ^2.2.0 - "@smithy/middleware-retry": ^2.0.20 - "@smithy/middleware-serde": ^2.0.13 - "@smithy/middleware-stack": ^2.0.7 - "@smithy/node-config-provider": ^2.1.5 - "@smithy/node-http-handler": ^2.1.9 - "@smithy/protocol-http": ^3.0.9 - "@smithy/smithy-client": ^2.1.15 - "@smithy/types": ^2.5.0 - "@smithy/url-parser": ^2.0.13 + "@aws-sdk/core": 3.490.0 + "@aws-sdk/middleware-host-header": 3.489.0 + "@aws-sdk/middleware-logger": 3.489.0 + "@aws-sdk/middleware-recursion-detection": 3.489.0 + "@aws-sdk/middleware-user-agent": 3.489.0 + "@aws-sdk/region-config-resolver": 3.489.0 + "@aws-sdk/types": 3.489.0 + "@aws-sdk/util-endpoints": 3.489.0 + "@aws-sdk/util-user-agent-browser": 3.489.0 + "@aws-sdk/util-user-agent-node": 3.489.0 + "@smithy/config-resolver": ^2.0.23 + "@smithy/core": ^1.2.2 + "@smithy/fetch-http-handler": ^2.3.2 + "@smithy/hash-node": ^2.0.18 + "@smithy/invalid-dependency": ^2.0.16 + "@smithy/middleware-content-length": ^2.0.18 + "@smithy/middleware-endpoint": ^2.3.0 + "@smithy/middleware-retry": ^2.0.26 + "@smithy/middleware-serde": ^2.0.16 + "@smithy/middleware-stack": ^2.0.10 + "@smithy/node-config-provider": ^2.1.9 + "@smithy/node-http-handler": ^2.2.2 + "@smithy/protocol-http": ^3.0.12 + "@smithy/smithy-client": ^2.2.1 + "@smithy/types": ^2.8.0 + "@smithy/url-parser": ^2.0.16 "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.0 + "@smithy/util-body-length-browser": ^2.0.1 "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.19 - "@smithy/util-defaults-mode-node": ^2.0.25 - "@smithy/util-endpoints": ^1.0.4 - "@smithy/util-retry": ^2.0.6 + "@smithy/util-defaults-mode-browser": ^2.0.24 + "@smithy/util-defaults-mode-node": ^2.0.32 + "@smithy/util-endpoints": ^1.0.8 + "@smithy/util-retry": ^2.0.9 "@smithy/util-utf8": ^2.0.2 tslib: ^2.5.0 - checksum: 83c2a1c1883a7900ea0c564e3f13c9d04a6970067e67182123b9be52505abbb1cf30d676312cb73ec637be4aab5094baa95d62e0ac910b0b2304cfe089f4f2df + checksum: f09172f7af1de8371dc4bd03ef18f2a260bd9868db9460912d392d0f2bcf4101e8f78eed440db6bd99437a3b8d1c1a107fb3bc904f20f4a99eb0a262c0644b14 languageName: node linkType: hard -"@aws-sdk/client-sts@npm:3.465.0, @aws-sdk/client-sts@npm:^3.350.0": - version: 3.465.0 - resolution: "@aws-sdk/client-sts@npm:3.465.0" +"@aws-sdk/client-sts@npm:3.490.0, @aws-sdk/client-sts@npm:^3.350.0": + version: 3.490.0 + resolution: "@aws-sdk/client-sts@npm:3.490.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/core": 3.465.0 - "@aws-sdk/credential-provider-node": 3.465.0 - "@aws-sdk/middleware-host-header": 3.465.0 - "@aws-sdk/middleware-logger": 3.465.0 - "@aws-sdk/middleware-recursion-detection": 3.465.0 - "@aws-sdk/middleware-sdk-sts": 3.465.0 - "@aws-sdk/middleware-signing": 3.465.0 - "@aws-sdk/middleware-user-agent": 3.465.0 - "@aws-sdk/region-config-resolver": 3.465.0 - "@aws-sdk/types": 3.465.0 - "@aws-sdk/util-endpoints": 3.465.0 - "@aws-sdk/util-user-agent-browser": 3.465.0 - "@aws-sdk/util-user-agent-node": 3.465.0 - "@smithy/config-resolver": ^2.0.18 - "@smithy/fetch-http-handler": ^2.2.6 - "@smithy/hash-node": ^2.0.15 - "@smithy/invalid-dependency": ^2.0.13 - "@smithy/middleware-content-length": ^2.0.15 - "@smithy/middleware-endpoint": ^2.2.0 - "@smithy/middleware-retry": ^2.0.20 - "@smithy/middleware-serde": ^2.0.13 - "@smithy/middleware-stack": ^2.0.7 - "@smithy/node-config-provider": ^2.1.5 - "@smithy/node-http-handler": ^2.1.9 - "@smithy/protocol-http": ^3.0.9 - "@smithy/smithy-client": ^2.1.15 - "@smithy/types": ^2.5.0 - "@smithy/url-parser": ^2.0.13 + "@aws-sdk/core": 3.490.0 + "@aws-sdk/credential-provider-node": 3.490.0 + "@aws-sdk/middleware-host-header": 3.489.0 + "@aws-sdk/middleware-logger": 3.489.0 + "@aws-sdk/middleware-recursion-detection": 3.489.0 + "@aws-sdk/middleware-user-agent": 3.489.0 + "@aws-sdk/region-config-resolver": 3.489.0 + "@aws-sdk/types": 3.489.0 + "@aws-sdk/util-endpoints": 3.489.0 + "@aws-sdk/util-user-agent-browser": 3.489.0 + "@aws-sdk/util-user-agent-node": 3.489.0 + "@smithy/config-resolver": ^2.0.23 + "@smithy/core": ^1.2.2 + "@smithy/fetch-http-handler": ^2.3.2 + "@smithy/hash-node": ^2.0.18 + "@smithy/invalid-dependency": ^2.0.16 + "@smithy/middleware-content-length": ^2.0.18 + "@smithy/middleware-endpoint": ^2.3.0 + "@smithy/middleware-retry": ^2.0.26 + "@smithy/middleware-serde": ^2.0.16 + "@smithy/middleware-stack": ^2.0.10 + "@smithy/node-config-provider": ^2.1.9 + "@smithy/node-http-handler": ^2.2.2 + "@smithy/protocol-http": ^3.0.12 + "@smithy/smithy-client": ^2.2.1 + "@smithy/types": ^2.8.0 + "@smithy/url-parser": ^2.0.16 "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.0 + "@smithy/util-body-length-browser": ^2.0.1 "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.19 - "@smithy/util-defaults-mode-node": ^2.0.25 - "@smithy/util-endpoints": ^1.0.4 - "@smithy/util-retry": ^2.0.6 + "@smithy/util-defaults-mode-browser": ^2.0.24 + "@smithy/util-defaults-mode-node": ^2.0.32 + "@smithy/util-endpoints": ^1.0.8 + "@smithy/util-middleware": ^2.0.9 + "@smithy/util-retry": ^2.0.9 "@smithy/util-utf8": ^2.0.2 fast-xml-parser: 4.2.5 tslib: ^2.5.0 - checksum: 79c9fec0b4e682ef0258d5da75c18bbbdf278ebabfc2a2c80e1d5a8e13bb94aebf28a2d6e58940bb1b17ef9a8025a9e0c39ef7f6f52e723893f8fbf5d3fb61f0 + checksum: 0fffd52bfae00c2e1beacf2cc58924131097efb7022a72f2d8c00e93e9c00ceb584d085b92160a2798d761726c7ca8492da5a7e8665d103a658ad96f9633e04e languageName: node linkType: hard -"@aws-sdk/core@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/core@npm:3.465.0" +"@aws-sdk/core@npm:3.490.0": + version: 3.490.0 + resolution: "@aws-sdk/core@npm:3.490.0" dependencies: - "@smithy/smithy-client": ^2.1.15 + "@smithy/core": ^1.2.2 + "@smithy/protocol-http": ^3.0.12 + "@smithy/signature-v4": ^2.0.0 + "@smithy/smithy-client": ^2.2.1 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: 25aed5f8a15830a845a332e952cc55a92a52162af598a9dc2c6c6a92f711a32ab26826cabddedb6e41f597a1cbdcc68b896054a8e1396bacc31e985fe50188d4 + checksum: 8d711ba4373b4ee074f5a225642cb91cd0052daf1e2880da1f5bd1b38197ea5c7888a4181710f715393f83618aacc4465262f9a80de8f4faf2644d5832e455b5 languageName: node linkType: hard -"@aws-sdk/credential-provider-cognito-identity@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.465.0" +"@aws-sdk/credential-provider-cognito-identity@npm:3.490.0": + version: 3.490.0 + resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.490.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.465.0 - "@aws-sdk/types": 3.465.0 + "@aws-sdk/client-cognito-identity": 3.490.0 + "@aws-sdk/types": 3.489.0 "@smithy/property-provider": ^2.0.0 - "@smithy/types": ^2.5.0 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: ad8400bdd6e92b7e40f12cd640f16c7289d4e7aee7a30c9389971baba793f10bd6d83cfbc676197fb1515d94d5e2a816aaede84492eb439c9833e5e51b1e475a + checksum: c1ee2aa0c1d6c9bd61f17550c9381b05e790f23afc5dd757a242e2a9f8ee0c03c49f8b29452258b86c5f68b9e87fba3eb5b299ceb6414f1db6919de32aacba17 languageName: node linkType: hard -"@aws-sdk/credential-provider-env@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/credential-provider-env@npm:3.465.0" +"@aws-sdk/credential-provider-env@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.489.0" dependencies: - "@aws-sdk/types": 3.465.0 + "@aws-sdk/types": 3.489.0 "@smithy/property-provider": ^2.0.0 - "@smithy/types": ^2.5.0 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: 89f5f9b8edd1251f60e1aa32819480cc14e0b77c24249d070b653f21d788885c0fdbc4a69dd1ed9c526b31ee12869eda8979d2431b914af2bf664ef3940e58df + checksum: ef1c3fb9e12cb3b62be41d87ce168b704d462b6fb27d08eab58b003940e3b24b043f122efab42cdc41d0bd632074114f39b474c480705dc61ed6e879690fa93f languageName: node linkType: hard -"@aws-sdk/credential-provider-http@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/credential-provider-http@npm:3.465.0" +"@aws-sdk/credential-provider-http@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.489.0" dependencies: - "@aws-sdk/types": 3.465.0 - "@smithy/fetch-http-handler": ^2.2.6 - "@smithy/node-http-handler": ^2.1.9 + "@aws-sdk/types": 3.489.0 + "@smithy/fetch-http-handler": ^2.3.2 + "@smithy/node-http-handler": ^2.2.2 "@smithy/property-provider": ^2.0.0 - "@smithy/protocol-http": ^3.0.9 - "@smithy/smithy-client": ^2.1.15 - "@smithy/types": ^2.5.0 - "@smithy/util-stream": ^2.0.20 + "@smithy/protocol-http": ^3.0.12 + "@smithy/smithy-client": ^2.2.1 + "@smithy/types": ^2.8.0 + "@smithy/util-stream": ^2.0.24 tslib: ^2.5.0 - checksum: cbad41fb117b73136923d213d90cbe2753f984e96c1f2acc7504c4eb72e8f1e00db945f2f57989eed5e18d03857695ba40f3b71e3678e72ac48630d98fdf207f + checksum: 601580c4299b1b0d7a696a94643b78c12491261f975275c5ae544ca5eee1f08fb4d21af1935257f2972b1f8ed8c0246275963e9c97cc53484f6d501ad6dbd4c6 languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.465.0" +"@aws-sdk/credential-provider-ini@npm:3.490.0": + version: 3.490.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.490.0" dependencies: - "@aws-sdk/credential-provider-env": 3.465.0 - "@aws-sdk/credential-provider-process": 3.465.0 - "@aws-sdk/credential-provider-sso": 3.465.0 - "@aws-sdk/credential-provider-web-identity": 3.465.0 - "@aws-sdk/types": 3.465.0 + "@aws-sdk/credential-provider-env": 3.489.0 + "@aws-sdk/credential-provider-process": 3.489.0 + "@aws-sdk/credential-provider-sso": 3.490.0 + "@aws-sdk/credential-provider-web-identity": 3.489.0 + "@aws-sdk/types": 3.489.0 "@smithy/credential-provider-imds": ^2.0.0 "@smithy/property-provider": ^2.0.0 "@smithy/shared-ini-file-loader": ^2.0.6 - "@smithy/types": ^2.5.0 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: 6640707dd4a86b0e860e77a4560922f8c7689d25892b18246276b65aab3350547bf489a4f41a8377cde408f5d906259adebc3bf7cd77e74cec3d4ce7b3daa78a + checksum: 5dd24af06b3a2977c1ebd47621619b18b8d9f9bed04e8ac5daae9faedabe66d6c6792a62da54513d668f0b11315cab4fd41a85637e35646cec46588742e36b1f languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:3.465.0, @aws-sdk/credential-provider-node@npm:^3.350.0": - version: 3.465.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.465.0" +"@aws-sdk/credential-provider-node@npm:3.490.0, @aws-sdk/credential-provider-node@npm:^3.350.0": + version: 3.490.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.490.0" dependencies: - "@aws-sdk/credential-provider-env": 3.465.0 - "@aws-sdk/credential-provider-ini": 3.465.0 - "@aws-sdk/credential-provider-process": 3.465.0 - "@aws-sdk/credential-provider-sso": 3.465.0 - "@aws-sdk/credential-provider-web-identity": 3.465.0 - "@aws-sdk/types": 3.465.0 + "@aws-sdk/credential-provider-env": 3.489.0 + "@aws-sdk/credential-provider-ini": 3.490.0 + "@aws-sdk/credential-provider-process": 3.489.0 + "@aws-sdk/credential-provider-sso": 3.490.0 + "@aws-sdk/credential-provider-web-identity": 3.489.0 + "@aws-sdk/types": 3.489.0 "@smithy/credential-provider-imds": ^2.0.0 "@smithy/property-provider": ^2.0.0 "@smithy/shared-ini-file-loader": ^2.0.6 - "@smithy/types": ^2.5.0 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: 9c8d444d95f67e64463679f0f6a87d3bb42cdbc4abd44abdb11e8da4c1f7e620a7dba424d26b97cf86965e790fd9933f984df7ad651b10524136511971cd5ab4 + checksum: 52820573a6aff0ea8c7ca0699fb374ba9a94a9e9eb777c2b1225d3565fdde7a65c70fcbe9ec887cf555c2df73cdc341641791f1358a102e052869d0f4978d4d0 languageName: node linkType: hard -"@aws-sdk/credential-provider-process@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/credential-provider-process@npm:3.465.0" +"@aws-sdk/credential-provider-process@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.489.0" dependencies: - "@aws-sdk/types": 3.465.0 + "@aws-sdk/types": 3.489.0 "@smithy/property-provider": ^2.0.0 "@smithy/shared-ini-file-loader": ^2.0.6 - "@smithy/types": ^2.5.0 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: e48cb385eccd44ddbf6a32b8fb26113025cd474ee28942953b1777a2d02b4bdc905da5d69aee9cf3712cdb888e652b86a7d9853f14caf7436ce59e6657c02140 + checksum: 19eb75f0222176f33ad5fbeb5a02b312a37a48966b73ff5c1af9974d439dc4c6faeffe745c2a23b0abb67ab876f9e10099b4a22c2ee9d15be5290556331a7a9a languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.465.0" +"@aws-sdk/credential-provider-sso@npm:3.490.0": + version: 3.490.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.490.0" dependencies: - "@aws-sdk/client-sso": 3.465.0 - "@aws-sdk/token-providers": 3.465.0 - "@aws-sdk/types": 3.465.0 + "@aws-sdk/client-sso": 3.490.0 + "@aws-sdk/token-providers": 3.489.0 + "@aws-sdk/types": 3.489.0 "@smithy/property-provider": ^2.0.0 "@smithy/shared-ini-file-loader": ^2.0.6 - "@smithy/types": ^2.5.0 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: 40764632b5b117bd9f8263b6dced2a6231093f4e5e26b6cc6730e16e6c92b478563d78dbc49a5fde80e1d588439c3218c89acf1821030dc8979211e164502892 + checksum: ea3c9d180f13f676b7717a8e0aabdca33b36f2dbf27128dfa6f8172040aa895437ef03e08802b9d6b104a783b8606b8af923193ff54f79e92118aa54babaa311 languageName: node linkType: hard -"@aws-sdk/credential-provider-web-identity@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.465.0" +"@aws-sdk/credential-provider-web-identity@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.489.0" dependencies: - "@aws-sdk/types": 3.465.0 + "@aws-sdk/types": 3.489.0 "@smithy/property-provider": ^2.0.0 - "@smithy/types": ^2.5.0 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: 2bdd92ed25b310d88fbbf42fa26e58070d910dd25bd569b4a3bc7d328f3dff421beb1a775f21c1a1696f439f561ccf7dd595a42829a3b88d432683b3f4a8c58e + checksum: 6da681688c9a61b6e100c71983a1ba19ef34bcbd8d1e4e85e3399d86e74cdc8d81f57b6da1983319596c87ef1600471e82c5243fb909f9752eff99a6ef26a8ea languageName: node linkType: hard "@aws-sdk/credential-providers@npm:^3.350.0": - version: 3.465.0 - resolution: "@aws-sdk/credential-providers@npm:3.465.0" + version: 3.490.0 + resolution: "@aws-sdk/credential-providers@npm:3.490.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.465.0 - "@aws-sdk/client-sso": 3.465.0 - "@aws-sdk/client-sts": 3.465.0 - "@aws-sdk/credential-provider-cognito-identity": 3.465.0 - "@aws-sdk/credential-provider-env": 3.465.0 - "@aws-sdk/credential-provider-http": 3.465.0 - "@aws-sdk/credential-provider-ini": 3.465.0 - "@aws-sdk/credential-provider-node": 3.465.0 - "@aws-sdk/credential-provider-process": 3.465.0 - "@aws-sdk/credential-provider-sso": 3.465.0 - "@aws-sdk/credential-provider-web-identity": 3.465.0 - "@aws-sdk/types": 3.465.0 + "@aws-sdk/client-cognito-identity": 3.490.0 + "@aws-sdk/client-sso": 3.490.0 + "@aws-sdk/client-sts": 3.490.0 + "@aws-sdk/credential-provider-cognito-identity": 3.490.0 + "@aws-sdk/credential-provider-env": 3.489.0 + "@aws-sdk/credential-provider-http": 3.489.0 + "@aws-sdk/credential-provider-ini": 3.490.0 + "@aws-sdk/credential-provider-node": 3.490.0 + "@aws-sdk/credential-provider-process": 3.489.0 + "@aws-sdk/credential-provider-sso": 3.490.0 + "@aws-sdk/credential-provider-web-identity": 3.489.0 + "@aws-sdk/types": 3.489.0 "@smithy/credential-provider-imds": ^2.0.0 "@smithy/property-provider": ^2.0.0 - "@smithy/types": ^2.5.0 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: ff594821d82227c2cf9884283f003d72c322f78d0aeace12fb47f5b0fa7fbb3cce7d6b96822df848a89649eeea6bc9dda18de40e5a5399a8c5f6930fe906d3e3 + checksum: 470f752cdf07861b6d5d7aff18e0541400bb211fcda7037347593f67d3882be9f5bd66b334915dc6549b96c554e1334e1dfec3286210eb9e18628a8bc2f19052 languageName: node linkType: hard @@ -887,34 +897,34 @@ __metadata: linkType: hard "@aws-sdk/lib-storage@npm:^3.350.0": - version: 3.465.0 - resolution: "@aws-sdk/lib-storage@npm:3.465.0" + version: 3.490.0 + resolution: "@aws-sdk/lib-storage@npm:3.490.0" dependencies: "@smithy/abort-controller": ^2.0.1 - "@smithy/middleware-endpoint": ^2.2.0 - "@smithy/smithy-client": ^2.1.15 + "@smithy/middleware-endpoint": ^2.3.0 + "@smithy/smithy-client": ^2.2.1 buffer: 5.6.0 events: 3.3.0 stream-browserify: 3.0.0 tslib: ^2.5.0 peerDependencies: "@aws-sdk/client-s3": ^3.0.0 - checksum: fe351e545dbc28d20d936ae6e3ea1c5faf672bdc402d3e15a3709fc8175060b8925647b381b0a3ad0eac1d25b73e16c5580ad1e32764a011a1ca77432662f682 + checksum: 253dc2e4fd33efcf5ee8d3ad76bb3f2ed1d4573e27fa8be23dc3b9b60bcf22e769684f3ab639c3551a66282e160e4b1693527ac49062c6a42b55716e7aadc6df languageName: node linkType: hard -"@aws-sdk/middleware-bucket-endpoint@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.465.0" +"@aws-sdk/middleware-bucket-endpoint@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.489.0" dependencies: - "@aws-sdk/types": 3.465.0 + "@aws-sdk/types": 3.489.0 "@aws-sdk/util-arn-parser": 3.465.0 - "@smithy/node-config-provider": ^2.1.5 - "@smithy/protocol-http": ^3.0.9 - "@smithy/types": ^2.5.0 - "@smithy/util-config-provider": ^2.0.0 + "@smithy/node-config-provider": ^2.1.9 + "@smithy/protocol-http": ^3.0.12 + "@smithy/types": ^2.8.0 + "@smithy/util-config-provider": ^2.1.0 tslib: ^2.5.0 - checksum: 381375b8eb4e37e14612c7a5c9e027163cd116747a766e2c2fc0cf5a5349f0e3fd5f8b871657c0c38596c8a0c28c1093fcebcbeb99c142d7d17a3f2f88690650 + checksum: 209278da47bf7e3b0e3cd6bc0f80d56bd6fc06400c12041474d1fdef7d227b8120bd7ac0b471fd15e03433e8c9e5e8c7a20d4f5f057dc23edfecaf4b61ad1378 languageName: node linkType: hard @@ -931,119 +941,107 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-expect-continue@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/middleware-expect-continue@npm:3.465.0" +"@aws-sdk/middleware-expect-continue@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/middleware-expect-continue@npm:3.489.0" dependencies: - "@aws-sdk/types": 3.465.0 - "@smithy/protocol-http": ^3.0.9 - "@smithy/types": ^2.5.0 + "@aws-sdk/types": 3.489.0 + "@smithy/protocol-http": ^3.0.12 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: 88ca4283f94057978dabc463083dafddd2b01d368cc0fb9fb6d15d21dbbf828fd615e6fc649a47bac2919d2e226376d233604f91bf942421452ea34827e0a652 + checksum: 2e4bc714e5c410d2362ec274e2f36ffbb35dc826030ac64ec2d34bf9a89b1defa3c8cd1e0d92c4f41ddb64035039ddfac927069152ea70437061f2f078d43cc1 languageName: node linkType: hard -"@aws-sdk/middleware-flexible-checksums@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.465.0" +"@aws-sdk/middleware-flexible-checksums@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.489.0" dependencies: "@aws-crypto/crc32": 3.0.0 "@aws-crypto/crc32c": 3.0.0 - "@aws-sdk/types": 3.465.0 + "@aws-sdk/types": 3.489.0 "@smithy/is-array-buffer": ^2.0.0 - "@smithy/protocol-http": ^3.0.9 - "@smithy/types": ^2.5.0 + "@smithy/protocol-http": ^3.0.12 + "@smithy/types": ^2.8.0 "@smithy/util-utf8": ^2.0.2 tslib: ^2.5.0 - checksum: e003b96421e1251eb629231a6afebd99b5795c219562496c4f1d23165233a073fffc754e18819f874a600a518ada4c2647a4c9fbd88b2bf2ce39f68501d04a0f + checksum: 522f234ba9fdf5fe1476c72b7480158723a52e15db0560a4d79fa00dd43935633104648a4be2d0d741afa90f5b4f5ced3e99ffdece9b1aa75f4c08389dbe5f10 languageName: node linkType: hard -"@aws-sdk/middleware-host-header@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/middleware-host-header@npm:3.465.0" +"@aws-sdk/middleware-host-header@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.489.0" dependencies: - "@aws-sdk/types": 3.465.0 - "@smithy/protocol-http": ^3.0.9 - "@smithy/types": ^2.5.0 + "@aws-sdk/types": 3.489.0 + "@smithy/protocol-http": ^3.0.12 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: fe7fba3fdd12d3d7bee052583a353cd5afb64e652a44c89af0c416d7994110dfcf7e03df3380ce06724305a10774661a72d09369f655f6c4b7d1d9ead28a957a + checksum: 15072d8409066de23ae815ce84c9ab9ce509e368654a3438b398e0f1bec5e215a52a59388ede1fe4c7a40cb639759c50aab3a3562ffe17352a24e6f92f2ddd1e languageName: node linkType: hard -"@aws-sdk/middleware-location-constraint@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/middleware-location-constraint@npm:3.465.0" +"@aws-sdk/middleware-location-constraint@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/middleware-location-constraint@npm:3.489.0" dependencies: - "@aws-sdk/types": 3.465.0 - "@smithy/types": ^2.5.0 + "@aws-sdk/types": 3.489.0 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: 341e9adc1eb255b5033d23b3797e6093ae1955ea2df912f7de69bf35632d8e1197d73166900d16e8224bc7ecdc800ba5649b38fec8e101efbe8ed0d27b344ec6 + checksum: d9499c897ef1f89afafdc2b4ebaa32cb31396cd7412ddaab545427820c33ef90e6f3e9f16b82607cc7a0d402994034b0c51255c06e2bd15f30d618d10f8bcbc6 languageName: node linkType: hard -"@aws-sdk/middleware-logger@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/middleware-logger@npm:3.465.0" +"@aws-sdk/middleware-logger@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/middleware-logger@npm:3.489.0" dependencies: - "@aws-sdk/types": 3.465.0 - "@smithy/types": ^2.5.0 + "@aws-sdk/types": 3.489.0 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: dd28c204cc9986780f25090ce9d91115b5784cc31c5677018f7f289c90476a631a044702da70c576d3263a5f16f99aa41851fc28948e115eaf64fc0986a18a7f + checksum: 10fa2538663512158f7a5889da693b0351f1f464457e45bc02199540adf6985ddfda81fe36dbdddabe1fe12709118fa106a365988e691fab834c9d93bf34329e languageName: node linkType: hard -"@aws-sdk/middleware-recursion-detection@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.465.0" +"@aws-sdk/middleware-recursion-detection@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.489.0" dependencies: - "@aws-sdk/types": 3.465.0 - "@smithy/protocol-http": ^3.0.9 - "@smithy/types": ^2.5.0 + "@aws-sdk/types": 3.489.0 + "@smithy/protocol-http": ^3.0.12 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: 3b718e0e300fa115198702645d177916d059612c76b17ea81c6d722b3c8312606b50aa765a990711f44c899724bc82c8ebd45a2a5ddaee788cb28ef3449f726b + checksum: bf1592f0577e8a5be5857100c288c0de0895b98b00d1947403d9ff99936d366cd3e8ae4838560ee68ff0d5fb74f26c2f139f23fee8b72ce8f753a742b467bb02 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-s3@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/middleware-sdk-s3@npm:3.465.0" +"@aws-sdk/middleware-sdk-s3@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/middleware-sdk-s3@npm:3.489.0" dependencies: - "@aws-sdk/types": 3.465.0 + "@aws-sdk/types": 3.489.0 "@aws-sdk/util-arn-parser": 3.465.0 - "@smithy/node-config-provider": ^2.1.5 - "@smithy/protocol-http": ^3.0.9 + "@smithy/node-config-provider": ^2.1.9 + "@smithy/protocol-http": ^3.0.12 "@smithy/signature-v4": ^2.0.0 - "@smithy/smithy-client": ^2.1.15 - "@smithy/types": ^2.5.0 - "@smithy/util-config-provider": ^2.0.0 + "@smithy/smithy-client": ^2.2.1 + "@smithy/types": ^2.8.0 + "@smithy/util-config-provider": ^2.1.0 tslib: ^2.5.0 - checksum: 61117fa5da796ac89926df1caf3709ad8405810b20b089e7c122f069f3440556923d939da1fd24765cadc8ccde5670d1339dc84ed4e82908c7755ff2d73406cd + checksum: 4a1541d7e21172a270cf3965171abcfd1dcb1fc98eac982fb2d3f8dbc10cfecec5ea13bfb27ada66c1a40a6446d027399818edabf1180b340e496eb6826fa8d7 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-sqs@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.465.0" +"@aws-sdk/middleware-sdk-sqs@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.489.0" dependencies: - "@aws-sdk/types": 3.465.0 - "@smithy/types": ^2.5.0 + "@aws-sdk/types": 3.489.0 + "@smithy/types": ^2.8.0 "@smithy/util-hex-encoding": ^2.0.0 "@smithy/util-utf8": ^2.0.2 tslib: ^2.5.0 - checksum: b760657584c0362c603f38ea4df4744b42d40734c6433232fe5ec590f501cac7be705da8a2afa6c5cce0e4cb73b8bbffbc7066d7b9d28dd042055f478a8f0490 - languageName: node - linkType: hard - -"@aws-sdk/middleware-sdk-sts@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/middleware-sdk-sts@npm:3.465.0" - dependencies: - "@aws-sdk/middleware-signing": 3.465.0 - "@aws-sdk/types": 3.465.0 - "@smithy/types": ^2.5.0 - tslib: ^2.5.0 - checksum: cddb425eacd40dddf490d2af0f8b9e6032cd0cc7da0138f25876aa3d57ab48148cc105db16f411aaf1857c22c3841e8e904a781c383f3b6f8b541282575ffd48 + checksum: a87d0f4c4dd0afd67b37cd5b4de4daa2505c7a51faa2c6aeef6eac0d6a74e68aa3457ec30bc6c174418899899de252ccda1ce53afe8380db2183c8620a4fa84f languageName: node linkType: hard @@ -1057,42 +1055,42 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-signing@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/middleware-signing@npm:3.465.0" +"@aws-sdk/middleware-signing@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/middleware-signing@npm:3.489.0" dependencies: - "@aws-sdk/types": 3.465.0 + "@aws-sdk/types": 3.489.0 "@smithy/property-provider": ^2.0.0 - "@smithy/protocol-http": ^3.0.9 + "@smithy/protocol-http": ^3.0.12 "@smithy/signature-v4": ^2.0.0 - "@smithy/types": ^2.5.0 - "@smithy/util-middleware": ^2.0.6 + "@smithy/types": ^2.8.0 + "@smithy/util-middleware": ^2.0.9 tslib: ^2.5.0 - checksum: de9aa66c61d3f499c4f0cca7bee5359777d8357c3aaccf51a9062eda923b82f2d5b13808462c2a2f9120231e3c1a66ae4e35636f08da8ec3521ace1d970ff67a + checksum: bf50942d8ca7baf2d27b0a6d8fb06219971da9863ee0fa7a2ab56c85d344b0374724f608cec371b75a2ea2a0cd4da6d7d431f8bf1f3d9fe5f1797a4d15272962 languageName: node linkType: hard -"@aws-sdk/middleware-ssec@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/middleware-ssec@npm:3.465.0" +"@aws-sdk/middleware-ssec@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/middleware-ssec@npm:3.489.0" dependencies: - "@aws-sdk/types": 3.465.0 - "@smithy/types": ^2.5.0 + "@aws-sdk/types": 3.489.0 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: c04dd79af338bbbb6f439e123adc961698a5a71d5ab66deab8ef3fe08dc63c7d24d92646b32cc7c6eb684e101dfb0fd590618124567470b40a389f63fa90f7b3 + checksum: c3666f606bcdcbe2c36a21e0460fd9514ea6f7a3faf09fb392457ca7fc9f41da81351a50f4432ce748a24daad5715736eddf7e59694f0fbbcc530b395c2bf12c languageName: node linkType: hard -"@aws-sdk/middleware-user-agent@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.465.0" +"@aws-sdk/middleware-user-agent@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.489.0" dependencies: - "@aws-sdk/types": 3.465.0 - "@aws-sdk/util-endpoints": 3.465.0 - "@smithy/protocol-http": ^3.0.9 - "@smithy/types": ^2.5.0 + "@aws-sdk/types": 3.489.0 + "@aws-sdk/util-endpoints": 3.489.0 + "@smithy/protocol-http": ^3.0.12 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: e00a86370f0d3e4f63d2ca7153dcbfa12b8d492141434dd5cdfd3ec402bbed4d5c80661d2aec50f251979c6091c15752a16431058a928788f1200757605271bd + checksum: b5254863f2203b598199ad65ca87a5a3b92a3ecb51cabbb910819b0f03f61b26b553364e047b9b3329463f8dd4324a650d045deaf548cb5e7de2c08ed2f5dfd6 languageName: node linkType: hard @@ -1140,30 +1138,31 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/region-config-resolver@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/region-config-resolver@npm:3.465.0" +"@aws-sdk/region-config-resolver@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.489.0" dependencies: - "@smithy/node-config-provider": ^2.1.5 - "@smithy/types": ^2.5.0 - "@smithy/util-config-provider": ^2.0.0 - "@smithy/util-middleware": ^2.0.6 + "@aws-sdk/types": 3.489.0 + "@smithy/node-config-provider": ^2.1.9 + "@smithy/types": ^2.8.0 + "@smithy/util-config-provider": ^2.1.0 + "@smithy/util-middleware": ^2.0.9 tslib: ^2.5.0 - checksum: 3af46df3f8a36a7280ff488f03e59c16801287bc56607186e1e7af1818adfb1610524d7873648ac31378277c64b44d549205232e495f544d5ca1ea34dda0f745 + checksum: 2352d0b3409e6d5225fd3f6f5da81164fcb93bb528579eacefea75ef8760f8626434e377eb3c7785046ce996732209f300de70958905124acbd1eb45a192e24b languageName: node linkType: hard -"@aws-sdk/signature-v4-multi-region@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/signature-v4-multi-region@npm:3.465.0" +"@aws-sdk/signature-v4-multi-region@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.489.0" dependencies: - "@aws-sdk/middleware-sdk-s3": 3.465.0 - "@aws-sdk/types": 3.465.0 - "@smithy/protocol-http": ^3.0.9 + "@aws-sdk/middleware-sdk-s3": 3.489.0 + "@aws-sdk/types": 3.489.0 + "@smithy/protocol-http": ^3.0.12 "@smithy/signature-v4": ^2.0.0 - "@smithy/types": ^2.5.0 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: d40dbc77b963357afa3536cd461bfb1dd1d7ad734d33185a9d82b6a6104f517ec7283e48a9855ec75d90235fc7fdd06d66992c5a792d9f36e5ac717155069271 + checksum: 613ab4f64682844dd9a6c6675f7db218185d3415a40b255e1346a0217576bad431156324739d148542421c67036462476b95ac801ea8c7f24f5abac96514ee23 languageName: node linkType: hard @@ -1183,48 +1182,48 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/token-providers@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/token-providers@npm:3.465.0" +"@aws-sdk/token-providers@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/token-providers@npm:3.489.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/middleware-host-header": 3.465.0 - "@aws-sdk/middleware-logger": 3.465.0 - "@aws-sdk/middleware-recursion-detection": 3.465.0 - "@aws-sdk/middleware-user-agent": 3.465.0 - "@aws-sdk/region-config-resolver": 3.465.0 - "@aws-sdk/types": 3.465.0 - "@aws-sdk/util-endpoints": 3.465.0 - "@aws-sdk/util-user-agent-browser": 3.465.0 - "@aws-sdk/util-user-agent-node": 3.465.0 - "@smithy/config-resolver": ^2.0.18 - "@smithy/fetch-http-handler": ^2.2.6 - "@smithy/hash-node": ^2.0.15 - "@smithy/invalid-dependency": ^2.0.13 - "@smithy/middleware-content-length": ^2.0.15 - "@smithy/middleware-endpoint": ^2.2.0 - "@smithy/middleware-retry": ^2.0.20 - "@smithy/middleware-serde": ^2.0.13 - "@smithy/middleware-stack": ^2.0.7 - "@smithy/node-config-provider": ^2.1.5 - "@smithy/node-http-handler": ^2.1.9 + "@aws-sdk/middleware-host-header": 3.489.0 + "@aws-sdk/middleware-logger": 3.489.0 + "@aws-sdk/middleware-recursion-detection": 3.489.0 + "@aws-sdk/middleware-user-agent": 3.489.0 + "@aws-sdk/region-config-resolver": 3.489.0 + "@aws-sdk/types": 3.489.0 + "@aws-sdk/util-endpoints": 3.489.0 + "@aws-sdk/util-user-agent-browser": 3.489.0 + "@aws-sdk/util-user-agent-node": 3.489.0 + "@smithy/config-resolver": ^2.0.23 + "@smithy/fetch-http-handler": ^2.3.2 + "@smithy/hash-node": ^2.0.18 + "@smithy/invalid-dependency": ^2.0.16 + "@smithy/middleware-content-length": ^2.0.18 + "@smithy/middleware-endpoint": ^2.3.0 + "@smithy/middleware-retry": ^2.0.26 + "@smithy/middleware-serde": ^2.0.16 + "@smithy/middleware-stack": ^2.0.10 + "@smithy/node-config-provider": ^2.1.9 + "@smithy/node-http-handler": ^2.2.2 "@smithy/property-provider": ^2.0.0 - "@smithy/protocol-http": ^3.0.9 + "@smithy/protocol-http": ^3.0.12 "@smithy/shared-ini-file-loader": ^2.0.6 - "@smithy/smithy-client": ^2.1.15 - "@smithy/types": ^2.5.0 - "@smithy/url-parser": ^2.0.13 + "@smithy/smithy-client": ^2.2.1 + "@smithy/types": ^2.8.0 + "@smithy/url-parser": ^2.0.16 "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.0 + "@smithy/util-body-length-browser": ^2.0.1 "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.19 - "@smithy/util-defaults-mode-node": ^2.0.25 - "@smithy/util-endpoints": ^1.0.4 - "@smithy/util-retry": ^2.0.6 + "@smithy/util-defaults-mode-browser": ^2.0.24 + "@smithy/util-defaults-mode-node": ^2.0.32 + "@smithy/util-endpoints": ^1.0.8 + "@smithy/util-retry": ^2.0.9 "@smithy/util-utf8": ^2.0.2 tslib: ^2.5.0 - checksum: ebfeb68e09294775b345f4fbd76be546283a5a10cb388fdf25c38d0f229c29616dbe0c708d0fcf196a74a52e3df0a55e77cada158cbcb6ace44a86f9606ce1eb + checksum: cf2e14a09ead031e9ac3426fd0e5bc71656f1ce9ba470c860af26d8935dce65b28365973388175f982dd2d8fb6c470520dee426045b26174663a5adc6ac5928c languageName: node linkType: hard @@ -1238,13 +1237,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:3.465.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": - version: 3.465.0 - resolution: "@aws-sdk/types@npm:3.465.0" +"@aws-sdk/types@npm:3.489.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": + version: 3.489.0 + resolution: "@aws-sdk/types@npm:3.489.0" dependencies: - "@smithy/types": ^2.5.0 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: 73f05accd990f70a0eb58c5c568ed091a097caab808415efb420deee0873e912469fe2e0a68e1d0087cd376237cc4a7e3182a475670cd295676735d90f132ca6 + checksum: e4692f04daee278e4fc7faeadb8fee077aee5b1210a6c237c203b4688b714d1efc96c9f4574b71e264f71d8f4aad06b5728bcba13d12242c92f93dec81e3d3da languageName: node linkType: hard @@ -1278,14 +1277,15 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-endpoints@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/util-endpoints@npm:3.465.0" +"@aws-sdk/util-endpoints@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/util-endpoints@npm:3.489.0" dependencies: - "@aws-sdk/types": 3.465.0 - "@smithy/util-endpoints": ^1.0.4 + "@aws-sdk/types": 3.489.0 + "@smithy/types": ^2.8.0 + "@smithy/util-endpoints": ^1.0.8 tslib: ^2.5.0 - checksum: 38b0a5335f67c63dcc3562b1b34161249ff5638da4ebdc295f561d64448d84215fb4b46825ee6ebcfa7010449e1725c3705230529a74510e40f2a0e37881a0f1 + checksum: 5c225b12ce5c18ecd64079d2e4133374244728ac7c8055efb07ca5b274266cb0e2d6c88ce5ae4385d45d67b2999fcd5bbe5e8dd4299792542683682ac05950e8 languageName: node linkType: hard @@ -1337,32 +1337,32 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-browser@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.465.0" +"@aws-sdk/util-user-agent-browser@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.489.0" dependencies: - "@aws-sdk/types": 3.465.0 - "@smithy/types": ^2.5.0 + "@aws-sdk/types": 3.489.0 + "@smithy/types": ^2.8.0 bowser: ^2.11.0 tslib: ^2.5.0 - checksum: 46c280a8284ddc34096eff401a9372f0fc84c1805c8dc1489ad4e6a44b4fac0b5c58bc200a00c873ce5928bf2bbc11fe4ab465b8cb606ddf64ca2cb76be205c4 + checksum: b24009655bd5a7755575d6ed5c955d6fcfa3a70248e1a9c9d4a58cc7ed4bb25936a276917a0ab60b6e11e7ed915d5dcfdd5e9112e373bd23b24d24963324e516 languageName: node linkType: hard -"@aws-sdk/util-user-agent-node@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/util-user-agent-node@npm:3.465.0" +"@aws-sdk/util-user-agent-node@npm:3.489.0": + version: 3.489.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.489.0" dependencies: - "@aws-sdk/types": 3.465.0 - "@smithy/node-config-provider": ^2.1.5 - "@smithy/types": ^2.5.0 + "@aws-sdk/types": 3.489.0 + "@smithy/node-config-provider": ^2.1.9 + "@smithy/types": ^2.8.0 tslib: ^2.5.0 peerDependencies: aws-crt: ">=1.0.0" peerDependenciesMeta: aws-crt: optional: true - checksum: 197203f9345aefedda3109bc523c218382de2138f9fd2ef284ddc8f6d73819a5688503706098fb86562d3efd8dde3dc769f9fd59feba284fa890b3152111a1de + checksum: 755845ce1cebdc78d3bb2bab058cf8e966658373daa7c62ae808fc0fc733248ed019042b1eed4ad3274ae08f23506cc000e1b0d41b6f01fd29cccad4275b3f8e languageName: node linkType: hard @@ -1385,12 +1385,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/xml-builder@npm:3.465.0": - version: 3.465.0 - resolution: "@aws-sdk/xml-builder@npm:3.465.0" +"@aws-sdk/xml-builder@npm:3.485.0": + version: 3.485.0 + resolution: "@aws-sdk/xml-builder@npm:3.485.0" dependencies: + "@smithy/types": ^2.8.0 tslib: ^2.5.0 - checksum: 33c370b216aece520352bc36dc147649bee0bca7139a5d5c6e49e99756e9ca369c73bacc55dff5920f6003d06a29a1375920e18b9776c264de925c5a9cfc3deb + checksum: 97eacc7fff1161876cb672051905156d6aec8116f76b35d5f2ca87b676b5b270fc6de0b9bed53792272a7712d835077ac64b4135fed7ea81c3e4cbf070f1be58 languageName: node linkType: hard @@ -15346,338 +15347,355 @@ __metadata: languageName: node linkType: hard -"@smithy/abort-controller@npm:^2.0.1, @smithy/abort-controller@npm:^2.0.13, @smithy/abort-controller@npm:^2.0.14": - version: 2.0.14 - resolution: "@smithy/abort-controller@npm:2.0.14" +"@smithy/abort-controller@npm:^2.0.1, @smithy/abort-controller@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/abort-controller@npm:2.1.0" dependencies: - "@smithy/types": ^2.6.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: f89c7b0523fcb4df7dd7057d15a6deff9aa0b9ac5fe816a2f1331353d3874cf8d3e9b2280a1daa903c32be0fe280ef034a2222f6e62f733fc7dc40be3b1cbe38 + checksum: 52ad57706997dd1fabeb5b4d1f43d65403f31f8c7bf2fd6addb84b8132b406763574911499ab757be1c0c7329c06c574174750f17383507cfb05e1df05b26882 languageName: node linkType: hard -"@smithy/chunked-blob-reader-native@npm:^2.0.1": - version: 2.0.1 - resolution: "@smithy/chunked-blob-reader-native@npm:2.0.1" +"@smithy/chunked-blob-reader-native@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/chunked-blob-reader-native@npm:2.1.0" dependencies: - "@smithy/util-base64": ^2.0.1 + "@smithy/util-base64": ^2.1.0 tslib: ^2.5.0 - checksum: db13a380a51ace30c8ed5947ea1b9fa65f5f5d0dbb722b4abc4d19e4a1215979174f35365c692f9fe7d3c116eaaf90dd9fb58e1dcff4fe943fc76d86c7f1798d + checksum: 39ff866a5887dfbe515463d841d869559e18aa18e97a644be49f12821012c171d89d759dbe3999b0bedcafdad8c1202c747b2f5a71a6c1f63082b0fae13b844c languageName: node linkType: hard -"@smithy/chunked-blob-reader@npm:^2.0.0": - version: 2.0.0 - resolution: "@smithy/chunked-blob-reader@npm:2.0.0" +"@smithy/chunked-blob-reader@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/chunked-blob-reader@npm:2.1.0" dependencies: tslib: ^2.5.0 - checksum: a47e5298f0b28e25eaa5825ea9737718f0e2b7cf0f03a49cca186eb5544dd20ac91a2d92069f9805e40e5f3ab34d32f8091853518672fdbca009411179dbeb2a + checksum: 0e59309a3566057e6529d33954ac2621d979dcbc93f92696df617c89bf7b382576cac43b874cba8b394a16f619d60d25acc6f2c839278c2c50df3ddeacb90e02 languageName: node linkType: hard -"@smithy/config-resolver@npm:^2.0.18": - version: 2.0.18 - resolution: "@smithy/config-resolver@npm:2.0.18" +"@smithy/config-resolver@npm:^2.0.23, @smithy/config-resolver@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/config-resolver@npm:2.1.0" dependencies: - "@smithy/node-config-provider": ^2.1.5 - "@smithy/types": ^2.5.0 - "@smithy/util-config-provider": ^2.0.0 - "@smithy/util-middleware": ^2.0.6 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/types": ^2.9.0 + "@smithy/util-config-provider": ^2.2.0 + "@smithy/util-middleware": ^2.1.0 tslib: ^2.5.0 - checksum: 40d89b243143baf61e2ab7495a97594b33a15ca7b498fc40b04c1b19f754eab95ab840733f6c63e7ac42b282c96d0925d256cdf399c915a0e24e75a7c6258a10 + checksum: 09bda075b007bf08a3253ea257685ade769f70e0735d154c4495469a87ac941efc76501c3a5afecb1209ade4a35db2e4c0ae6c50f71b9970576c7eade8f4b42b languageName: node linkType: hard -"@smithy/credential-provider-imds@npm:^2.0.0, @smithy/credential-provider-imds@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/credential-provider-imds@npm:2.1.1" +"@smithy/core@npm:^1.2.2": + version: 1.3.0 + resolution: "@smithy/core@npm:1.3.0" dependencies: - "@smithy/node-config-provider": ^2.1.5 - "@smithy/property-provider": ^2.0.14 - "@smithy/types": ^2.5.0 - "@smithy/url-parser": ^2.0.13 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/middleware-retry": ^2.1.0 + "@smithy/middleware-serde": ^2.1.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/util-middleware": ^2.1.0 tslib: ^2.5.0 - checksum: 110c4185b39849c9baac6355deac959fbe6ff5bfcaeb6cafd6ff3c30b98fffe618d3b08aa2ef538b8f6f1f84e0f56b7f2d7f60c603967f5410768e8da002f8e9 + checksum: b35792e3915412e15062e561c3de84cd5ffdf3fe6d053460a48843bd97d16af44048e8cede18011b5fec0b12732f7d22feedcae526cd077d18c2a3567e291686 languageName: node linkType: hard -"@smithy/eventstream-codec@npm:^2.0.1, @smithy/eventstream-codec@npm:^2.0.13": - version: 2.0.13 - resolution: "@smithy/eventstream-codec@npm:2.0.13" +"@smithy/credential-provider-imds@npm:^2.0.0, @smithy/credential-provider-imds@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/credential-provider-imds@npm:2.2.0" + dependencies: + "@smithy/node-config-provider": ^2.2.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/types": ^2.9.0 + "@smithy/url-parser": ^2.1.0 + tslib: ^2.5.0 + checksum: 4c1722f5e541cb64211f8d6cd81298ae6c74a41f93c223f7c8e2b118cf103cdd16e20ff6440c8393aa4f017c619fa8ca691049729f5869b8f9aa852b1b9cb448 + languageName: node + linkType: hard + +"@smithy/eventstream-codec@npm:^2.0.1, @smithy/eventstream-codec@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/eventstream-codec@npm:2.1.0" dependencies: "@aws-crypto/crc32": 3.0.0 - "@smithy/types": ^2.5.0 - "@smithy/util-hex-encoding": ^2.0.0 + "@smithy/types": ^2.9.0 + "@smithy/util-hex-encoding": ^2.1.0 tslib: ^2.5.0 - checksum: fdae10c869061e6335903d9f0d80dbd0bb9fb5af484c97e5c9490a59ce3d27ca0bba8683149ee2dee7045c84c4d8c014b411611164535bb53936e1fef21ed8bc + checksum: de1f72d3d4146b3c4bb81aa93b423b6cce89a606feeb209c6b181643686cd1832af56ebd632041c8d708e1923f8c779353953b988b437a35ca4a9b57c9c57329 languageName: node linkType: hard -"@smithy/eventstream-serde-browser@npm:^2.0.13": - version: 2.0.13 - resolution: "@smithy/eventstream-serde-browser@npm:2.0.13" +"@smithy/eventstream-serde-browser@npm:^2.0.16": + version: 2.1.0 + resolution: "@smithy/eventstream-serde-browser@npm:2.1.0" dependencies: - "@smithy/eventstream-serde-universal": ^2.0.13 - "@smithy/types": ^2.5.0 + "@smithy/eventstream-serde-universal": ^2.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 1107de0ed525cd7cc1315693d8b1601da09c66131b808496f0869324e87e9bced2efc06425dc8761756f4ceca24b6ae9ba7d4fca239fcf49d4fcc5aed93f4421 + checksum: 77b2a904ec7562ebd4eb69b960ecf1b134c8e9a676b52804ec7d40703f505d36158390f511f3d5d56ae1991d6f4ac30c4b8c0889e09ffa384f470e573ab838e2 languageName: node linkType: hard -"@smithy/eventstream-serde-config-resolver@npm:^2.0.13": - version: 2.0.13 - resolution: "@smithy/eventstream-serde-config-resolver@npm:2.0.13" +"@smithy/eventstream-serde-config-resolver@npm:^2.0.16": + version: 2.1.0 + resolution: "@smithy/eventstream-serde-config-resolver@npm:2.1.0" dependencies: - "@smithy/types": ^2.5.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 29de012f1224ec5b9079088d55f06315be60729a6455aa1b340f6eac05fe53fd07c785d8f1908bdf8a97aa7fb4142a6ebf6715f479bf09c021680b55050c83bc + checksum: 62b4c7062a775954a76744dd268eeb0504669f81e537245a876851d97ed4187ceb0685fe02bfa73e6e04502f81cb81b4acdf40c8237d7049c7ed8df8c1952ac2 languageName: node linkType: hard -"@smithy/eventstream-serde-node@npm:^2.0.13": - version: 2.0.13 - resolution: "@smithy/eventstream-serde-node@npm:2.0.13" +"@smithy/eventstream-serde-node@npm:^2.0.16": + version: 2.1.0 + resolution: "@smithy/eventstream-serde-node@npm:2.1.0" dependencies: - "@smithy/eventstream-serde-universal": ^2.0.13 - "@smithy/types": ^2.5.0 + "@smithy/eventstream-serde-universal": ^2.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: c83fdaf2ccc42a4f5f0d153adb37dd409cc78c15c1c73608a39af42219a714e30d9e47c3d80f2da1b810643c1964649b8d115e3a706f43b6401c3aab3b8f322f + checksum: f882576d7a26c8ff3013550a6d8c224ab2a4082fb28fb21edbe4fa80593041e7cad0b86c0c8c1ffcebffda9fd55f63d84ae4f8524984dcb7243afc221ccdd000 languageName: node linkType: hard -"@smithy/eventstream-serde-universal@npm:^2.0.13": - version: 2.0.13 - resolution: "@smithy/eventstream-serde-universal@npm:2.0.13" +"@smithy/eventstream-serde-universal@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/eventstream-serde-universal@npm:2.1.0" dependencies: - "@smithy/eventstream-codec": ^2.0.13 - "@smithy/types": ^2.5.0 + "@smithy/eventstream-codec": ^2.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 138fa619e3ae588438fd962a1a12988c8ec22b330d7cc787be75b5ec7650aa5cabec047c8ef0601545d0614d13803f1ec1f2d185f68bface54ccf643c5055075 + checksum: 206e7c7154a485c5538d970fc95b8b3d0ebbce6be0f02617146ab17b02787e4b424e6ae06cc38397fb9477a6db25b5afff76b4756ba2f736a68fd01154fc9f28 languageName: node linkType: hard -"@smithy/fetch-http-handler@npm:^2.2.6": - version: 2.2.6 - resolution: "@smithy/fetch-http-handler@npm:2.2.6" +"@smithy/fetch-http-handler@npm:^2.3.2, @smithy/fetch-http-handler@npm:^2.4.0": + version: 2.4.0 + resolution: "@smithy/fetch-http-handler@npm:2.4.0" dependencies: - "@smithy/protocol-http": ^3.0.9 - "@smithy/querystring-builder": ^2.0.13 - "@smithy/types": ^2.5.0 - "@smithy/util-base64": ^2.0.1 + "@smithy/protocol-http": ^3.1.0 + "@smithy/querystring-builder": ^2.1.0 + "@smithy/types": ^2.9.0 + "@smithy/util-base64": ^2.1.0 tslib: ^2.5.0 - checksum: 2bc59c5bd9ad5ffe72f1a686853444318118a0ac833acf6029114236804480ac3d9a9d41e0d92cea0263a2aa7d76a82dd8b6850ecfea2e4eeed30e1d8225ccc3 + checksum: 1f6165ca546bb274d6111b9819ae7d4969ea79a81e718b41438feae04d2aaee942ef62464c3e6e2999e78f27b977c39c560e06fbb76fb9fda443c2bc77db2a3d languageName: node linkType: hard -"@smithy/hash-blob-browser@npm:^2.0.14": - version: 2.0.14 - resolution: "@smithy/hash-blob-browser@npm:2.0.14" +"@smithy/hash-blob-browser@npm:^2.0.17": + version: 2.1.0 + resolution: "@smithy/hash-blob-browser@npm:2.1.0" dependencies: - "@smithy/chunked-blob-reader": ^2.0.0 - "@smithy/chunked-blob-reader-native": ^2.0.1 - "@smithy/types": ^2.5.0 + "@smithy/chunked-blob-reader": ^2.1.0 + "@smithy/chunked-blob-reader-native": ^2.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: c492891d1854ad2ed9a99dbe815b2e5e9970cef45647c770182be47bb715ddf238fae2865af7e4c3f04ffc4e6ce386fe2a6bc211549b2c3dfa2c0eb7b91924a6 + checksum: c76e9a9393f1fcfa3b567083ea50764f565d01879bb8062da09c8cf403a92867e7e60fdae0d6f82d4df7a684026537efa9e6be7d26245e08ea5ec6bd4680de19 languageName: node linkType: hard -"@smithy/hash-node@npm:^2.0.15": - version: 2.0.15 - resolution: "@smithy/hash-node@npm:2.0.15" +"@smithy/hash-node@npm:^2.0.18": + version: 2.1.0 + resolution: "@smithy/hash-node@npm:2.1.0" dependencies: - "@smithy/types": ^2.5.0 - "@smithy/util-buffer-from": ^2.0.0 - "@smithy/util-utf8": ^2.0.2 + "@smithy/types": ^2.9.0 + "@smithy/util-buffer-from": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: c3a2efed56ee6f58811d3a87a6e272a9c5fd82db527ea2c72cfe39401b61417676f2d7f952926be7b51ece134e662a8608a4ff4c2c500eb756a91a41384b716e + checksum: fbeca22f0ce172e16530c6b84ac8452a6fdf965451bfacd7a626dc992ec69696edea7dc95e5e4bc8109ccb905db104d62b023788432df075e5a1a70e976907fa languageName: node linkType: hard -"@smithy/hash-stream-node@npm:^2.0.15": - version: 2.0.15 - resolution: "@smithy/hash-stream-node@npm:2.0.15" +"@smithy/hash-stream-node@npm:^2.0.18": + version: 2.1.0 + resolution: "@smithy/hash-stream-node@npm:2.1.0" dependencies: - "@smithy/types": ^2.5.0 - "@smithy/util-utf8": ^2.0.2 + "@smithy/types": ^2.9.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: 9588a91c6cfbe65289632a9d4369b340e949b83552311520e1df95d2f06456f8d11be0c6227eb266c96cbc56b7f9b631d75462616544b38fb160a616244a3996 + checksum: 0f86820521fda9d82b5114630ac69cb0a04ad68158ef02636b3c7bcd46461b9f7ec1bf3c46a1cb34bcac135faf61f94f127913f365f6ee9187928932b4bfaabb languageName: node linkType: hard -"@smithy/invalid-dependency@npm:^2.0.13": - version: 2.0.13 - resolution: "@smithy/invalid-dependency@npm:2.0.13" +"@smithy/invalid-dependency@npm:^2.0.16": + version: 2.1.0 + resolution: "@smithy/invalid-dependency@npm:2.1.0" dependencies: - "@smithy/types": ^2.5.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: f744eb38f5ee77d0b8ef5c57dfabf9befda4626f68808742e8b42754eba05e1def3e2a24e0daf2940b5454f52460af14e871dd8431b0237e87cb300be6704057 + checksum: 72b8f405cc77a0050f46f4ef648322aa5c1a421f25cac282b172f421b20a790809ffd621959e2278d174d6daf6f3c45acc533236fbfbc157a2537aeb88206f26 languageName: node linkType: hard -"@smithy/is-array-buffer@npm:^2.0.0": - version: 2.0.0 - resolution: "@smithy/is-array-buffer@npm:2.0.0" +"@smithy/is-array-buffer@npm:^2.0.0, @smithy/is-array-buffer@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/is-array-buffer@npm:2.1.0" dependencies: tslib: ^2.5.0 - checksum: 6d101cf509a7818667f42d297894f88f86ef41d3cc9d02eae38bbe5e69b16edf83b8e67eb691964d859a16a4e39db1aad323d83f6ae55ae4512a14ff6406c02d + checksum: cf32161a01a0384b47738bbc58dd6a317e3b5113f411ad141f174cc44e2a9e91f72082bdefa4477dc53c8e3ab6292d1487f26d66fce4f1fe7cc5da4ecde31e11 languageName: node linkType: hard -"@smithy/md5-js@npm:^2.0.15": - version: 2.0.15 - resolution: "@smithy/md5-js@npm:2.0.15" +"@smithy/md5-js@npm:^2.0.18": + version: 2.1.0 + resolution: "@smithy/md5-js@npm:2.1.0" dependencies: - "@smithy/types": ^2.5.0 - "@smithy/util-utf8": ^2.0.2 + "@smithy/types": ^2.9.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: d5a40f063629977201bcf72092ed4e2bfea18134ef693721f69823356a878f919ec4b00b621ee078201167e429e1eb79e1d80c26f03b06d7ee999bfbd882788b + checksum: b8d2f24df059e33feff8362fc9c4bdffc6f3e220f5a9c25959ea763d2f92d482ab7fb554164bc846b7d838c398be1fa76147cca616bf3e04c560e31c1cc315d5 languageName: node linkType: hard -"@smithy/middleware-content-length@npm:^2.0.15": - version: 2.0.15 - resolution: "@smithy/middleware-content-length@npm:2.0.15" +"@smithy/middleware-content-length@npm:^2.0.18": + version: 2.1.0 + resolution: "@smithy/middleware-content-length@npm:2.1.0" dependencies: - "@smithy/protocol-http": ^3.0.9 - "@smithy/types": ^2.5.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: f22a35e175f09b929655eb1445dc0954b2f1580bffc41b91cd01f67bf0e41367e510919f213c239157083b2a25f1aa0b9cc60b1b6832f3e03d4e00ec3228e7cb + checksum: 794a467d1db31015ee0fc3886363b4081b7213268c8ce175647077b2b7485a9a280b00349013b79d5f545476b7818ace85e14428df5b5587bb96219685cc7ebe languageName: node linkType: hard -"@smithy/middleware-endpoint@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/middleware-endpoint@npm:2.2.0" +"@smithy/middleware-endpoint@npm:^2.3.0, @smithy/middleware-endpoint@npm:^2.4.0": + version: 2.4.0 + resolution: "@smithy/middleware-endpoint@npm:2.4.0" dependencies: - "@smithy/middleware-serde": ^2.0.13 - "@smithy/node-config-provider": ^2.1.5 - "@smithy/shared-ini-file-loader": ^2.2.4 - "@smithy/types": ^2.5.0 - "@smithy/url-parser": ^2.0.13 - "@smithy/util-middleware": ^2.0.6 + "@smithy/middleware-serde": ^2.1.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/shared-ini-file-loader": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/url-parser": ^2.1.0 + "@smithy/util-middleware": ^2.1.0 tslib: ^2.5.0 - checksum: 2cf37d0859b2bb24deeca9e9907be38f120be56967970c0adbb443a9e126fd9889012b2d871df1fa1a1b2367f80b097f3f152d6bf8e4fdaf01fc6c714a1cc963 + checksum: 0ff6c10d5ddeef3add524c1b4fbe155aeaf6aeeff9c714111236bc5ad76f8459ec82dc9bd07355a63ef509ffb51173514d268d83b89eb75537976722400e7786 languageName: node linkType: hard -"@smithy/middleware-retry@npm:^2.0.20": - version: 2.0.20 - resolution: "@smithy/middleware-retry@npm:2.0.20" +"@smithy/middleware-retry@npm:^2.0.26, @smithy/middleware-retry@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/middleware-retry@npm:2.1.0" dependencies: - "@smithy/node-config-provider": ^2.1.5 - "@smithy/protocol-http": ^3.0.9 - "@smithy/service-error-classification": ^2.0.6 - "@smithy/types": ^2.5.0 - "@smithy/util-middleware": ^2.0.6 - "@smithy/util-retry": ^2.0.6 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/service-error-classification": ^2.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/util-middleware": ^2.1.0 + "@smithy/util-retry": ^2.1.0 tslib: ^2.5.0 uuid: ^8.3.2 - checksum: 8b76aaeba90dd80409a615f5c866ae8490b537bcc21c0bb5371026a891b7c74ac0a1647175bd1752b2c3d6a1b443eddddf2dc093b24da585d924e957dea18113 + checksum: 4ac9dacd7295f31378d8828810e44f7f7c526761010cef0e5cbd602cdc7306906a42e57b7d06e5e31e100f2cf9a3d73398d6350e9dc502b3375a2182608dbb16 languageName: node linkType: hard -"@smithy/middleware-serde@npm:^2.0.13": - version: 2.0.13 - resolution: "@smithy/middleware-serde@npm:2.0.13" +"@smithy/middleware-serde@npm:^2.0.16, @smithy/middleware-serde@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/middleware-serde@npm:2.1.0" dependencies: - "@smithy/types": ^2.5.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 549bdc9d2a79ee746572d631c0f10f700fa251a46ca289271ce1904027b483ac617f2e01c43b3f7f202395588f6607f436b32930318a83ecd6004a0b869ccf09 + checksum: d225f8bd960a1586219c53926ec33ae06f868f558ccc1777850abd160fb1d179ca4d4838c67032e8ea5cc8491e721b1317d14f040ffe735a6b0515e6847eda1c languageName: node linkType: hard -"@smithy/middleware-stack@npm:^2.0.7": - version: 2.0.7 - resolution: "@smithy/middleware-stack@npm:2.0.7" +"@smithy/middleware-stack@npm:^2.0.10, @smithy/middleware-stack@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/middleware-stack@npm:2.1.0" dependencies: - "@smithy/types": ^2.5.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 46405edb32290c1d6e291352a943687afcdacbaea413494f86b61b99b7a85ffc8f8f5aaf58f14ecc3c7cd80535231047d748e5d9ee3c38cd1b02c20daea938aa + checksum: 160abf4bd8ad0799f25053054585b6da987373f1352649f215a496d007a8c2ffed9cb1f2fde7219dcf8dc6883952be63d547f7b6cfcab45db61e645ff6d4bebb languageName: node linkType: hard -"@smithy/node-config-provider@npm:^2.1.5": - version: 2.1.5 - resolution: "@smithy/node-config-provider@npm:2.1.5" +"@smithy/node-config-provider@npm:^2.1.9, @smithy/node-config-provider@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/node-config-provider@npm:2.2.0" dependencies: - "@smithy/property-provider": ^2.0.14 - "@smithy/shared-ini-file-loader": ^2.2.4 - "@smithy/types": ^2.5.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/shared-ini-file-loader": ^2.3.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 813a0b0fa9758cc181074e1b3c1d7d3a9598e7bbbbed5da24eb38ec3053a8c00d675ee293d245d84cb601ade2e83e3faa054e68131307973419f93828abeb780 + checksum: d46a83f51e7186bdc80404df260e676979f5f576ad6e958ee59a24feeb0ac661558646d772991e70bef63398c24e4cf0dfea38cd76935860aaab9c7d61e4d234 languageName: node linkType: hard -"@smithy/node-http-handler@npm:^2.1.7, @smithy/node-http-handler@npm:^2.1.9": - version: 2.1.10 - resolution: "@smithy/node-http-handler@npm:2.1.10" +"@smithy/node-http-handler@npm:^2.1.7, @smithy/node-http-handler@npm:^2.2.2, @smithy/node-http-handler@npm:^2.3.0": + version: 2.3.0 + resolution: "@smithy/node-http-handler@npm:2.3.0" dependencies: - "@smithy/abort-controller": ^2.0.14 - "@smithy/protocol-http": ^3.0.10 - "@smithy/querystring-builder": ^2.0.14 - "@smithy/types": ^2.6.0 + "@smithy/abort-controller": ^2.1.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/querystring-builder": ^2.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: b24a3d2ebf87458f92274ba099af05a1a8d933d8df3767ab5d3baf273890c1cfd4be291b06b5323e5119898ba07e88a1f257b8970f7e75fc8944b7071090fa55 + checksum: 8f431d7fa4e07908ecfd58d13721b5adc41519415e9ea58d104ab44da008c0244fd551a6fddc27e9bac1ca8ba98d3f117b37c379c096e5038ff70b723466dce6 languageName: node linkType: hard -"@smithy/property-provider@npm:^2.0.0, @smithy/property-provider@npm:^2.0.14": - version: 2.0.14 - resolution: "@smithy/property-provider@npm:2.0.14" +"@smithy/property-provider@npm:^2.0.0, @smithy/property-provider@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/property-provider@npm:2.1.0" dependencies: - "@smithy/types": ^2.5.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 44cd1b4eeb07be4b88c6a2e8a1f4cd6b56e40f1f457b64f596fc2f46ce7c4991230b0c9654cb4489f93897678b81457a1cac104f566d9856cfbc92a66efa1a2e + checksum: abeceb40091e121bdbc4788af8c4664d4b624a5a3ffe17185cbe29c21deb785b9788dfec70bb552d82422ab566f4c8aed0b7697d50abc8bf76e498ad929e49a5 languageName: node linkType: hard -"@smithy/protocol-http@npm:^3.0.10, @smithy/protocol-http@npm:^3.0.9": - version: 3.0.10 - resolution: "@smithy/protocol-http@npm:3.0.10" +"@smithy/protocol-http@npm:^3.0.12, @smithy/protocol-http@npm:^3.1.0": + version: 3.1.0 + resolution: "@smithy/protocol-http@npm:3.1.0" dependencies: - "@smithy/types": ^2.6.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 77bda5c76e00e0fee6a0654d10a0127287402484522dcdcb0eda84a6be196304301a68d263ba27639fb288dbcbb891bfa3efa50a24ea9a9878915a0e1ddc8620 + checksum: 3aae910192708bfd5cc3de85dc28c2eb7f6b425d6edc2b930f769330bc4912f8e7ff2a5dc8b9dd98614d1f9fa8d4f64a9f9eb45e54c4da94e29612accc3218fc languageName: node linkType: hard -"@smithy/querystring-builder@npm:^2.0.13, @smithy/querystring-builder@npm:^2.0.14": - version: 2.0.14 - resolution: "@smithy/querystring-builder@npm:2.0.14" +"@smithy/querystring-builder@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/querystring-builder@npm:2.1.0" dependencies: - "@smithy/types": ^2.6.0 - "@smithy/util-uri-escape": ^2.0.0 + "@smithy/types": ^2.9.0 + "@smithy/util-uri-escape": ^2.1.0 tslib: ^2.5.0 - checksum: e1287709055abd016b214e4cede9d976a63aa73aff8f3092db60a0fe7e103f7a1294bdedf39a7bbea4b2bf1b959682cbcf8e078ca0489a8a58b8b5706679b55d + checksum: 307cfec9c5765b9aca10318913cd91513d323895d9cfb863309b49fe634dfdb3ebf74ef3dc17e3d4aa60d1c4e8f48a63cfd11c2b2099b36cd4d9f53198e933a0 languageName: node linkType: hard -"@smithy/querystring-parser@npm:^2.0.13": - version: 2.0.13 - resolution: "@smithy/querystring-parser@npm:2.0.13" +"@smithy/querystring-parser@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/querystring-parser@npm:2.1.0" dependencies: - "@smithy/types": ^2.5.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: aaaa21dcdaa44d5d3d734512e3fe8591fff9713dc32da129aa836d938f5469286952eba997adc68fb2f9d8655b0e02a4bba7a6163ff22f799880c913b74396dd + checksum: 59c149d9654712066496c4685ab1ebf1ca792dd05de8bb88cdd512a2408b2c62cd618a3d3aab1eae2a74eb5b6da3649ef68b01e67b1c4838fe6881dc25e73775 languageName: node linkType: hard -"@smithy/service-error-classification@npm:^2.0.6": - version: 2.0.6 - resolution: "@smithy/service-error-classification@npm:2.0.6" +"@smithy/service-error-classification@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/service-error-classification@npm:2.1.0" dependencies: - "@smithy/types": ^2.5.0 - checksum: 07be989a2d3e17e14f8c7824bf9342632ec5ed1e4e0b4f2d242442f49a50058db5cbb7b8419b684126bf5c4ba08f6bce3360f43d73bd2def15771a1af7c1c95f + "@smithy/types": ^2.9.0 + checksum: 3889559eea95d96175b701d968d2b40409c0abee7de7434e6e9ebf4d5d1ecf90bda0cbf62b9768b787f0d18e39e729bc8d67bd6b1537df253cb854b263a96dc6 languageName: node linkType: hard -"@smithy/shared-ini-file-loader@npm:^2.0.6, @smithy/shared-ini-file-loader@npm:^2.2.4": - version: 2.2.4 - resolution: "@smithy/shared-ini-file-loader@npm:2.2.4" +"@smithy/shared-ini-file-loader@npm:^2.0.6, @smithy/shared-ini-file-loader@npm:^2.3.0": + version: 2.3.0 + resolution: "@smithy/shared-ini-file-loader@npm:2.3.0" dependencies: - "@smithy/types": ^2.5.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 790cc9c1e0d39ec179fcb97f612205770112ed14fa6626b2dee81ef140d6fa0d89a87825ccddda35475f9de9e6b8b70228565b2ed90c1487de20b603cc79505a + checksum: ea2855ef47df8711b89623f74e84151ced3716fd0255310071e67e8d1a303e0b1a9aa86a72cc7216ad82a162f37b019c639e5a7c5b4a8462499fa4def7e40bdb languageName: node linkType: hard @@ -15697,15 +15715,17 @@ __metadata: languageName: node linkType: hard -"@smithy/smithy-client@npm:^2.1.15": - version: 2.1.15 - resolution: "@smithy/smithy-client@npm:2.1.15" +"@smithy/smithy-client@npm:^2.2.1, @smithy/smithy-client@npm:^2.3.0": + version: 2.3.0 + resolution: "@smithy/smithy-client@npm:2.3.0" dependencies: - "@smithy/middleware-stack": ^2.0.7 - "@smithy/types": ^2.5.0 - "@smithy/util-stream": ^2.0.20 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/middleware-stack": ^2.1.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/types": ^2.9.0 + "@smithy/util-stream": ^2.1.0 tslib: ^2.5.0 - checksum: ad9aa105748866f22147d5e357759edd4cc4e263269b50ad4d9d2f4ec211297d90bd768cd4f182eb8230a32134166b38532b24a8884589e75c417a6e964eaa6d + checksum: ed101b2b8cb4c439fb7e0e37d399317e599b8ea9cef267da5491c63797d85f82b42675a4e69e2795ad984a7ef00f87c56276a755155e11fc6f5c56f41b6b813a languageName: node linkType: hard @@ -15718,42 +15738,42 @@ __metadata: languageName: node linkType: hard -"@smithy/types@npm:^2.0.2, @smithy/types@npm:^2.5.0, @smithy/types@npm:^2.6.0": - version: 2.6.0 - resolution: "@smithy/types@npm:2.6.0" +"@smithy/types@npm:^2.0.2, @smithy/types@npm:^2.8.0, @smithy/types@npm:^2.9.0": + version: 2.9.0 + resolution: "@smithy/types@npm:2.9.0" dependencies: tslib: ^2.5.0 - checksum: 9233d1e6e414a8b807f9fe7a7c30064626f77b0242d8634b9b1c192f77b27a997a3caf90ecf7f4361d5926c9e9cc761991eecfb47bbfa6ce2be21c5533a3bea6 + checksum: 74d59ddcc2eca419c493b99d09f912e72511d088df0c6b6548df876dd49407b3cbb68550c9d6fa1d03d65f96bb099c450bdad1b4724d52144ca65f547850a4bb languageName: node linkType: hard -"@smithy/url-parser@npm:^2.0.13": - version: 2.0.13 - resolution: "@smithy/url-parser@npm:2.0.13" +"@smithy/url-parser@npm:^2.0.16, @smithy/url-parser@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/url-parser@npm:2.1.0" dependencies: - "@smithy/querystring-parser": ^2.0.13 - "@smithy/types": ^2.5.0 + "@smithy/querystring-parser": ^2.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 96b64d0740aa8ce365316a361f5549c55fee92218e6d5673750ce8036bb68a9c200f2a39a945e548815c5206a5f28cb0022155e60d357fbb4a6bb41381d4b622 + checksum: e61ee1d7a3357f02f8f0d8364de3d2798134b0b5c686e3ab12917352feff5e445d0b8b16237f2c5444a9e48c8df57e8ca91770b29d804f8f469d6bdbc7498f97 languageName: node linkType: hard -"@smithy/util-base64@npm:^2.0.1": - version: 2.0.1 - resolution: "@smithy/util-base64@npm:2.0.1" +"@smithy/util-base64@npm:^2.0.1, @smithy/util-base64@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/util-base64@npm:2.1.0" dependencies: - "@smithy/util-buffer-from": ^2.0.0 + "@smithy/util-buffer-from": ^2.1.0 tslib: ^2.5.0 - checksum: 6320916b50a0f4048462564cbc413e619ee02747e188463721670ce554d0b1652517068a1aa066209101a2185b4f3d13afd0c173aac99c461ca685a1fa15f934 + checksum: 76a58830c82c4400374eddc09cd38f3f62f14f0d42295dfb468ed7cfc3928a7093c2879c01ed2e8c858f0bab47710a0514deb8da754d640b94a70281bec87315 languageName: node linkType: hard -"@smithy/util-body-length-browser@npm:^2.0.0": - version: 2.0.0 - resolution: "@smithy/util-body-length-browser@npm:2.0.0" +"@smithy/util-body-length-browser@npm:^2.0.1": + version: 2.1.0 + resolution: "@smithy/util-body-length-browser@npm:2.1.0" dependencies: tslib: ^2.5.0 - checksum: 4bccdd857bd24c9dcb6e9f2d5be03d59415f9a94d660ec7b3efb45e9aa04017f34c387368f176f24233a071af3b7a2b5f8236a2f5a83bfc884d24dfcc341e836 + checksum: ca37935d801ae4812e39c70e54651aaa029ad0bb6720a3529d9a0367a64316e892683805b25a36981126f458a3d3f5633be4f9b9e8de2a7293b8ea08bfd8607a languageName: node linkType: hard @@ -15766,137 +15786,137 @@ __metadata: languageName: node linkType: hard -"@smithy/util-buffer-from@npm:^2.0.0": - version: 2.0.0 - resolution: "@smithy/util-buffer-from@npm:2.0.0" +"@smithy/util-buffer-from@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/util-buffer-from@npm:2.1.0" dependencies: - "@smithy/is-array-buffer": ^2.0.0 + "@smithy/is-array-buffer": ^2.1.0 tslib: ^2.5.0 - checksum: d33cbf3e488d23390c88705ddae71b08de7a87b6453e38b508cd37a22a02e8b5be9f0cd46c1347b496c3977a815a7399b18840544ecdc4cce8cf3dcd0f5bb009 + checksum: 0e90dd3f324eae8863377d11f88cbdabf22aa29f5cb365bda8c5a23f24bbc2671c314aefccfab33e048fbeb18c939228bb43a5f0dc719fed71d484142ef3aaf5 languageName: node linkType: hard -"@smithy/util-config-provider@npm:^2.0.0": - version: 2.0.0 - resolution: "@smithy/util-config-provider@npm:2.0.0" +"@smithy/util-config-provider@npm:^2.1.0, @smithy/util-config-provider@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-config-provider@npm:2.2.0" dependencies: tslib: ^2.5.0 - checksum: cdc34db5b42658a7c98652ddb2e35b31e0d76f22a051d71724927999a53467fb38fe6dcf228585544bc168cbd54ded3913e14cbc33c947d3c8a45ca518a9b7b0 + checksum: ec61ff7f2f89c7c7c621141b9e19e8a5fa3c05041632d9b894b28b7d8bae9231271a61acfce19737bde0efce186062fa03cc05e4a006d96ea5c35ecf8a7e7e8d languageName: node linkType: hard -"@smithy/util-defaults-mode-browser@npm:^2.0.19": - version: 2.0.19 - resolution: "@smithy/util-defaults-mode-browser@npm:2.0.19" +"@smithy/util-defaults-mode-browser@npm:^2.0.24": + version: 2.1.0 + resolution: "@smithy/util-defaults-mode-browser@npm:2.1.0" dependencies: - "@smithy/property-provider": ^2.0.14 - "@smithy/smithy-client": ^2.1.15 - "@smithy/types": ^2.5.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 bowser: ^2.11.0 tslib: ^2.5.0 - checksum: 13b1f9fed2a9bbb9f755b192e1ddaccdb5624f104f89c0f0404c48ad1eafb006733f9b930692e50261c8479821cdcce08cfb71771ea5c0d112638bd4d23ba24d + checksum: 55a5cf94ddeb573b959265609e3854bdca62d9c1460a9d12b765266d6a8bdba8485a8beb765495755ffb32df1cc78b97c8f4f1c2b3556f073cd988b278e07b4f languageName: node linkType: hard -"@smithy/util-defaults-mode-node@npm:^2.0.25": - version: 2.0.25 - resolution: "@smithy/util-defaults-mode-node@npm:2.0.25" +"@smithy/util-defaults-mode-node@npm:^2.0.32": + version: 2.1.0 + resolution: "@smithy/util-defaults-mode-node@npm:2.1.0" dependencies: - "@smithy/config-resolver": ^2.0.18 - "@smithy/credential-provider-imds": ^2.1.1 - "@smithy/node-config-provider": ^2.1.5 - "@smithy/property-provider": ^2.0.14 - "@smithy/smithy-client": ^2.1.15 - "@smithy/types": ^2.5.0 + "@smithy/config-resolver": ^2.1.0 + "@smithy/credential-provider-imds": ^2.2.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 8e82f7f0c4260475e172f5baaf449155150c7d5ccb7939ccee3a061831b58998c55046cfd89761c06e43637e3e50805ca38277c5410f59b0906323e748285b80 + checksum: 4f244dc6d85c356f0e83296d75a57179ec4ce16001d26169a93d3d449a0be0748495309db96f4425dbd0ecf85d00a46be6a5869c14d1b3083d393efd9fef5edf languageName: node linkType: hard -"@smithy/util-endpoints@npm:^1.0.4": - version: 1.0.4 - resolution: "@smithy/util-endpoints@npm:1.0.4" +"@smithy/util-endpoints@npm:^1.0.8": + version: 1.1.0 + resolution: "@smithy/util-endpoints@npm:1.1.0" dependencies: - "@smithy/node-config-provider": ^2.1.5 - "@smithy/types": ^2.5.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 8c121070c0207b728e498a9d0b6082fcc83098b0ab33fde9b0b2db1bef724affc8712d9ae251bc155f595b7ca61a61529b519597c549808129d51bfdef9ad119 + checksum: ab646e2a8779e5901ff8be43744516ef413514efc9b42c82cea0461c9ee9b25b44709666b1504124d98c3512e93e5b24e532b0cade7031e4ea2ad7c3a752b306 languageName: node linkType: hard -"@smithy/util-hex-encoding@npm:^2.0.0": - version: 2.0.0 - resolution: "@smithy/util-hex-encoding@npm:2.0.0" +"@smithy/util-hex-encoding@npm:^2.0.0, @smithy/util-hex-encoding@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/util-hex-encoding@npm:2.1.0" dependencies: tslib: ^2.5.0 - checksum: 884373e089d909e3c9805bdb78f367d1f3612e4e1e6d8f0263cc82a8b9689eddc0bc80b8b58aa711bd5b48d9cb124f9996906c172e951c9dac78984459e831cf + checksum: 6a86bd3c7429b1762300a500d86b17a20499d9364c14c7e08aba49db3ee98b08dfa576513bbbd0cfed466807e04b6d71ff4922e71b89e59a79f0ffe482691364 languageName: node linkType: hard -"@smithy/util-middleware@npm:^2.0.0, @smithy/util-middleware@npm:^2.0.6": - version: 2.0.6 - resolution: "@smithy/util-middleware@npm:2.0.6" +"@smithy/util-middleware@npm:^2.0.0, @smithy/util-middleware@npm:^2.0.9, @smithy/util-middleware@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/util-middleware@npm:2.1.0" dependencies: - "@smithy/types": ^2.5.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: bf31193bbd08691c23e18da069fe95e2e989fcfde87133d183d469dc6e34d76918d56d68f5e5ff15d4f58575e7426ca6f952d248e51421739a2968c51e42e5b7 + checksum: 5b64efb80ad8f0855fd313812ea083a601d78e219898bab467fbfda50a8f7e1ee8399b895ca8c797c4becc8edc701d3ee976b9ae7b57b7b126ae69fc926574ac languageName: node linkType: hard -"@smithy/util-retry@npm:^2.0.6": - version: 2.0.6 - resolution: "@smithy/util-retry@npm:2.0.6" +"@smithy/util-retry@npm:^2.0.9, @smithy/util-retry@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/util-retry@npm:2.1.0" dependencies: - "@smithy/service-error-classification": ^2.0.6 - "@smithy/types": ^2.5.0 + "@smithy/service-error-classification": ^2.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: c37d163f83981ca58c7d924b178a09e18abc915ffb5efb20fcc4e662ad909938296fd295244ed84a209e84e56d66a629a9eba655306ca401c1a3b91c4433ff22 + checksum: 944ea383095357b2f4892849b2be05502183b5a07f825ca4012366e0e878dd9f478e774f1b413dc4190d38ae15e5cf3e26f484670f6b793488c07ccdaaa5e129 languageName: node linkType: hard -"@smithy/util-stream@npm:^2.0.20": - version: 2.0.20 - resolution: "@smithy/util-stream@npm:2.0.20" +"@smithy/util-stream@npm:^2.0.24, @smithy/util-stream@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/util-stream@npm:2.1.0" dependencies: - "@smithy/fetch-http-handler": ^2.2.6 - "@smithy/node-http-handler": ^2.1.9 - "@smithy/types": ^2.5.0 - "@smithy/util-base64": ^2.0.1 - "@smithy/util-buffer-from": ^2.0.0 - "@smithy/util-hex-encoding": ^2.0.0 - "@smithy/util-utf8": ^2.0.2 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/util-base64": ^2.1.0 + "@smithy/util-buffer-from": ^2.1.0 + "@smithy/util-hex-encoding": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: 24aeaa4cbb69c1faecf35a5c15631beae92742b0deb140fd565053aa995bd5587fef3150e58cc87d16896bf35ebefd5afcc894daee0dde4d44deafd4a158ff22 + checksum: 41a4929ba5fd0dec38bbd859f1ef8d4fc244dc0ce8fcc897ae450e1b22e949b12c8d972120066055e03757702494241d9cd65cfdaa35f977cf3a513248bd52b6 languageName: node linkType: hard -"@smithy/util-uri-escape@npm:^2.0.0": - version: 2.0.0 - resolution: "@smithy/util-uri-escape@npm:2.0.0" +"@smithy/util-uri-escape@npm:^2.0.0, @smithy/util-uri-escape@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/util-uri-escape@npm:2.1.0" dependencies: tslib: ^2.5.0 - checksum: d201cee524ece997c406902463b5ea0b72599994f7b3ac1d923d5645497e9ef93126d146016f13dd4afafe33b9a3e92faf4e023cf0af510b270c1b9ce3d78da8 + checksum: 11aca3e04a57428266fdb09f408f21bb51d5fa0b6b31ceb5769a63c670ad8f24c95bcbc1d6046d625b7992293e86f46207d1018233130e9f4c4e97d236ff9cd8 languageName: node linkType: hard -"@smithy/util-utf8@npm:^2.0.0, @smithy/util-utf8@npm:^2.0.2": - version: 2.0.2 - resolution: "@smithy/util-utf8@npm:2.0.2" +"@smithy/util-utf8@npm:^2.0.0, @smithy/util-utf8@npm:^2.0.2, @smithy/util-utf8@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/util-utf8@npm:2.1.0" dependencies: - "@smithy/util-buffer-from": ^2.0.0 + "@smithy/util-buffer-from": ^2.1.0 tslib: ^2.5.0 - checksum: e38fd6324ca2858f76fb6fce427c03faec599213acf95a5b18eb77b72cdf9327bd688e5a260dbccc0f512ea5426422ed200122a9542c00b14a6d9becc3f84c79 + checksum: eb33393c3e83262418f9a08ed7dc3dd3895c281a4a38b03fca9a2686b67b64db7ba657287da0201d9083d41a4528be39ff8b9ab7bd5b9b9b2ce4d1c3a144c7bc languageName: node linkType: hard -"@smithy/util-waiter@npm:^2.0.13": - version: 2.0.13 - resolution: "@smithy/util-waiter@npm:2.0.13" +"@smithy/util-waiter@npm:^2.0.16": + version: 2.1.0 + resolution: "@smithy/util-waiter@npm:2.1.0" dependencies: - "@smithy/abort-controller": ^2.0.13 - "@smithy/types": ^2.5.0 + "@smithy/abort-controller": ^2.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 1325887f9002b9f08c5cfcabcf35ce4488b4c2d009333955a166b27aa40b149a19f8359fdd8b265995409f64686bfb3aa02eb7bc18aea15aaa8d309d640107a5 + checksum: 1b861e2eec1848afcca08c13dac3a32b02187f9958f26d79cb5805ba140fca228268c54f7122fae1b74c4000a70fccad4aad61f21ec02acfa4e9511eebecc31e languageName: node linkType: hard From 2992a4c3103e1f669bf8f8fc7c63f8e1d8be87bd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 19:14:24 +0000 Subject: [PATCH 244/283] fix(deps): update dependency @gitbeaker/rest to v39.30.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 53 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/yarn.lock b/yarn.lock index 5b449d6d32..f6e3acd0b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11017,14 +11017,14 @@ __metadata: languageName: node linkType: hard -"@gitbeaker/core@npm:^39.25.0": - version: 39.25.0 - resolution: "@gitbeaker/core@npm:39.25.0" +"@gitbeaker/core@npm:^39.30.0": + version: 39.30.0 + resolution: "@gitbeaker/core@npm:39.30.0" dependencies: - "@gitbeaker/requester-utils": ^39.25.0 + "@gitbeaker/requester-utils": ^39.30.0 qs: ^6.11.2 xcase: ^2.0.1 - checksum: 56ebe3c6ba1078c47a6cae0abcd5ae4fd928dc73c9eb7dc462894d497d6fa5373c0d09a7a7a0583097cffa641eeb0b28b1764d33a085a7b95f0115399240bc7e + checksum: 4724659bab57cde13b63bba7ffad52651ebb726c444bb1d6c1c69c70efb89ed3d319abf12c117f9a8ab6741cc26e6a19c23e237bebd07d13b2f8c970171dc069 languageName: node linkType: hard @@ -11052,25 +11052,25 @@ __metadata: languageName: node linkType: hard -"@gitbeaker/requester-utils@npm:^39.25.0": - version: 39.25.0 - resolution: "@gitbeaker/requester-utils@npm:39.25.0" +"@gitbeaker/requester-utils@npm:^39.30.0": + version: 39.30.0 + resolution: "@gitbeaker/requester-utils@npm:39.30.0" dependencies: - async-sema: ^3.1.1 - micromatch: ^4.0.5 + picomatch-browser: ^2.2.6 qs: ^6.11.2 + rate-limiter-flexible: ^4.0.0 xcase: ^2.0.1 - checksum: 1ca90f5ac705d5ef9df682b3051106326bc660427b9b2a88762992690981ce0b6bed4b22bc08af0ba97043766f9898605ba58ed6c1a08b6711af34032f013ed2 + checksum: 05a60b027736edd165341c88ddbe095c78e77616f60033a9c9b419b657cd7d9998a9a801470a88d25d96be44b3a5233e3f1a4042aee075872f2882d10122db69 languageName: node linkType: hard "@gitbeaker/rest@npm:^39.25.0": - version: 39.25.0 - resolution: "@gitbeaker/rest@npm:39.25.0" + version: 39.30.0 + resolution: "@gitbeaker/rest@npm:39.30.0" dependencies: - "@gitbeaker/core": ^39.25.0 - "@gitbeaker/requester-utils": ^39.25.0 - checksum: 5732a34fe3f2fe0a048963baf90b237fde7a1be61fa327e2c7aa69266649394b5b48cd99a6c6abaf1cf8b32b84a293800af33eef49c011b252d6e061f7fe1af9 + "@gitbeaker/core": ^39.30.0 + "@gitbeaker/requester-utils": ^39.30.0 + checksum: 2b04dbb28c1a5f47c067c376ff0b4664278d72dcdef7696646a6d9331a400d9dfe75382e041a0a683fdc5ac1805abdb2919455fea786fd97f0eb65a5473d3fb5 languageName: node linkType: hard @@ -20699,13 +20699,6 @@ __metadata: languageName: node linkType: hard -"async-sema@npm:^3.1.1": - version: 3.1.1 - resolution: "async-sema@npm:3.1.1" - checksum: 07b8c51f6cab107417ecdd8126b7a9fe5a75151b7f69fdd420dcc8ee08f9e37c473a217247e894b56e999b088b32e902dbe41637e4e9b594d3f8dfcdddfadc5e - languageName: node - linkType: hard - "async@npm:^2.6.2, async@npm:^2.6.4": version: 2.6.4 resolution: "async@npm:2.6.4" @@ -36656,6 +36649,13 @@ __metadata: languageName: node linkType: hard +"picomatch-browser@npm:^2.2.6": + version: 2.2.6 + resolution: "picomatch-browser@npm:2.2.6" + checksum: 946c50a8654da43167a0f9a90dd0b50f3d4e830ee71c0926ee9052d7e6f40d8907deaafba19cea71b97207b4aaa52c245335e4cd5bbaf78fe2ba567cd0c341fa + languageName: node + linkType: hard + "picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.2, picomatch@npm:^2.2.3, picomatch@npm:^2.3.0, picomatch@npm:^2.3.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" @@ -37992,6 +37992,13 @@ __metadata: languageName: node linkType: hard +"rate-limiter-flexible@npm:^4.0.0": + version: 4.0.0 + resolution: "rate-limiter-flexible@npm:4.0.0" + checksum: defaa10e35d77399c4bbdeaa0e3f0028bcc5f6d678118d54496d5c01a4c9d5d56e16885e2ea339e7dd1ea056a3594bba24a18b5da236965f1d186fd52bdbe9fe + languageName: node + linkType: hard + "raw-body@npm:2.5.1": version: 2.5.1 resolution: "raw-body@npm:2.5.1" From 9047bc3109d37f895f0e0e1d91991fe1320dc2c2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 19:14:49 +0000 Subject: [PATCH 245/283] fix(deps): update dependency @google-cloud/firestore to v7.2.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 5b449d6d32..1a509dc3ec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11084,14 +11084,14 @@ __metadata: linkType: hard "@google-cloud/firestore@npm:^7.0.0": - version: 7.1.0 - resolution: "@google-cloud/firestore@npm:7.1.0" + version: 7.2.0 + resolution: "@google-cloud/firestore@npm:7.2.0" dependencies: fast-deep-equal: ^3.1.1 functional-red-black-tree: ^1.0.1 google-gax: ^4.0.4 protobufjs: ^7.2.5 - checksum: 271deeb1fbf389237f34e0a6fa90336ddd3beccc8ff4b6519c22ee1edd2da4c74aa7ee3b14a669fb16dc67ea21bf3c3baf5d1ffb01218c121fd9ac71bb4e873b + checksum: 2f9a5fa24741bb3e93c6dad2a366d8bfdab2a05d1a742a842eb432cc0e9e6cfc05828b0f6215827aa0da875556a329d1a39f06349b5b371b8dec685cd3225d6b languageName: node linkType: hard From 599c3826aaa8eb21df6c9cf432c12ccd4c7cd3f5 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 18 Jan 2024 20:18:28 +0100 Subject: [PATCH 246/283] .github/workflows: switch to 4 Jest workers Signed-off-by: Patrik Oldsberg --- .github/workflows/ci.yml | 2 +- .github/workflows/deploy_packages.yml | 2 +- .github/workflows/verify_windows.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ada4233f18..a0072634dc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -215,7 +215,7 @@ jobs: run: yarn backstage-cli repo lint --since origin/master - name: test changed packages - run: yarn backstage-cli repo test --maxWorkers=2 --workerIdleMemoryLimit=1300M --since origin/master + run: yarn backstage-cli repo test --maxWorkers=4 --workerIdleMemoryLimit=1300M --since origin/master env: BACKSTAGE_TEST_DISABLE_DOCKER: 1 BACKSTAGE_TEST_DATABASE_POSTGRES16_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres16.ports[5432] }} diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index 0d81f1c40a..cd7ca23a86 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -98,7 +98,7 @@ jobs: - name: test (and upload coverage) run: | - yarn backstage-cli repo test --maxWorkers=2 --workerIdleMemoryLimit=1300M --coverage + yarn backstage-cli repo test --maxWorkers=4 --workerIdleMemoryLimit=1300M --coverage bash <(curl -s https://codecov.io/bash) # Upload code coverage for some specific flags. Also see .codecov.yml bash <(curl -s https://codecov.io/bash) -f packages/core-app-api/coverage/* -F core-app-api diff --git a/.github/workflows/verify_windows.yml b/.github/workflows/verify_windows.yml index 4cffa959da..0acf1cc1ef 100644 --- a/.github/workflows/verify_windows.yml +++ b/.github/workflows/verify_windows.yml @@ -55,7 +55,7 @@ jobs: run: yarn lint:type-deps - name: test - run: yarn backstage-cli repo test --maxWorkers=2 --workerIdleMemoryLimit=1300M + run: yarn backstage-cli repo test --maxWorkers=4 --workerIdleMemoryLimit=1300M env: BACKSTAGE_TEST_DISABLE_DOCKER: 1 From 825ad9510c3b7d1d4120255446bfb575a67abaa0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 20:10:49 +0000 Subject: [PATCH 247/283] fix(deps): update dependency @newrelic/browser-agent to v1.250.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1d180ec720..0feb2fd83c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13011,14 +13011,14 @@ __metadata: linkType: hard "@newrelic/browser-agent@npm:^1.236.0": - version: 1.248.0 - resolution: "@newrelic/browser-agent@npm:1.248.0" + version: 1.250.0 + resolution: "@newrelic/browser-agent@npm:1.250.0" dependencies: core-js: ^3.26.0 fflate: ^0.7.4 rrweb: 2.0.0-alpha.11 web-vitals: ^3.1.0 - checksum: 0db9d85304e687f6d0e0be89306d26ab99469475ecb8107e224d9757da98627d67c5a652d65782092aa543738976bcb0ae701c92a7fcac7b2ef72c283342cba5 + checksum: 4cea599b5544c3981c8a564cd1f31cce33c286130cab8cfdb7adc08adf47499d525f0a555d648f0aa17ccb23749e572fb548a84c061c789a996dc264de5ed7cc languageName: node linkType: hard From ee1a530f4d5c524e4cf9b8fe544f0cce7ab3da13 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 20:11:23 +0000 Subject: [PATCH 248/283] fix(deps): update dependency @opensearch-project/opensearch to v2.5.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1d180ec720..1d95ba031f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13993,15 +13993,15 @@ __metadata: linkType: hard "@opensearch-project/opensearch@npm:^2.2.1": - version: 2.4.0 - resolution: "@opensearch-project/opensearch@npm:2.4.0" + version: 2.5.0 + resolution: "@opensearch-project/opensearch@npm:2.5.0" dependencies: aws4: ^1.11.0 debug: ^4.3.1 hpagent: ^1.2.0 ms: ^2.1.3 secure-json-parse: ^2.4.0 - checksum: 961ba055276c2cea9733247e57c1a1df76671a777b46ba4caa64a15c8b2aeb12d205c02026a6181382d3b575af49c4bf72b7bcb8fe82bc8dc2c519e1792746f3 + checksum: f9a4afa06c2917ffb76baac1ee1df9b8cf4594af6aded451b7c4838a4a0320101a432c0cbd3586d3533a4eb662fc414d4f1b315b73fac5b7a0c1d5f0ff0ac6ed languageName: node linkType: hard From bcaff38c9dcf4fa55511fe48757cbf438ee15f48 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 18 Jan 2024 22:13:32 +0100 Subject: [PATCH 249/283] .github/workflows: switch to 3 Jest workers Signed-off-by: Patrik Oldsberg --- .github/workflows/ci.yml | 2 +- .github/workflows/deploy_packages.yml | 2 +- .github/workflows/verify_windows.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4c46380fef..fd6e2edbc3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -216,7 +216,7 @@ jobs: run: yarn backstage-cli repo lint --since origin/master - name: test changed packages - run: yarn backstage-cli repo test --maxWorkers=4 --workerIdleMemoryLimit=1300M --since origin/master + run: yarn backstage-cli repo test --maxWorkers=3 --workerIdleMemoryLimit=1300M --since origin/master env: BACKSTAGE_TEST_DISABLE_DOCKER: 1 BACKSTAGE_TEST_DATABASE_POSTGRES16_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres16.ports[5432] }} diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index cd7ca23a86..6cd6caecf9 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -98,7 +98,7 @@ jobs: - name: test (and upload coverage) run: | - yarn backstage-cli repo test --maxWorkers=4 --workerIdleMemoryLimit=1300M --coverage + yarn backstage-cli repo test --maxWorkers=3 --workerIdleMemoryLimit=1300M --coverage bash <(curl -s https://codecov.io/bash) # Upload code coverage for some specific flags. Also see .codecov.yml bash <(curl -s https://codecov.io/bash) -f packages/core-app-api/coverage/* -F core-app-api diff --git a/.github/workflows/verify_windows.yml b/.github/workflows/verify_windows.yml index 0acf1cc1ef..143b22c8b6 100644 --- a/.github/workflows/verify_windows.yml +++ b/.github/workflows/verify_windows.yml @@ -55,7 +55,7 @@ jobs: run: yarn lint:type-deps - name: test - run: yarn backstage-cli repo test --maxWorkers=4 --workerIdleMemoryLimit=1300M + run: yarn backstage-cli repo test --maxWorkers=3 --workerIdleMemoryLimit=1300M env: BACKSTAGE_TEST_DISABLE_DOCKER: 1 From b1329c569d63cda445b0d79fd751d48fb0807cf9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 21:27:43 +0000 Subject: [PATCH 250/283] fix(deps): update aws-sdk-js-v3 monorepo to v3.495.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 1304 ++++++++++++++++++++++++++--------------------------- 1 file changed, 652 insertions(+), 652 deletions(-) diff --git a/yarn.lock b/yarn.lock index 39042b78e8..8bf8b426dd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -363,515 +363,515 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-cognito-identity@npm:3.490.0": - version: 3.490.0 - resolution: "@aws-sdk/client-cognito-identity@npm:3.490.0" +"@aws-sdk/client-cognito-identity@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/client-cognito-identity@npm:3.495.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.490.0 - "@aws-sdk/core": 3.490.0 - "@aws-sdk/credential-provider-node": 3.490.0 - "@aws-sdk/middleware-host-header": 3.489.0 - "@aws-sdk/middleware-logger": 3.489.0 - "@aws-sdk/middleware-recursion-detection": 3.489.0 - "@aws-sdk/middleware-signing": 3.489.0 - "@aws-sdk/middleware-user-agent": 3.489.0 - "@aws-sdk/region-config-resolver": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-endpoints": 3.489.0 - "@aws-sdk/util-user-agent-browser": 3.489.0 - "@aws-sdk/util-user-agent-node": 3.489.0 - "@smithy/config-resolver": ^2.0.23 - "@smithy/core": ^1.2.2 - "@smithy/fetch-http-handler": ^2.3.2 - "@smithy/hash-node": ^2.0.18 - "@smithy/invalid-dependency": ^2.0.16 - "@smithy/middleware-content-length": ^2.0.18 - "@smithy/middleware-endpoint": ^2.3.0 - "@smithy/middleware-retry": ^2.0.26 - "@smithy/middleware-serde": ^2.0.16 - "@smithy/middleware-stack": ^2.0.10 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/node-http-handler": ^2.2.2 - "@smithy/protocol-http": ^3.0.12 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/url-parser": ^2.0.16 - "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.1 - "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.24 - "@smithy/util-defaults-mode-node": ^2.0.32 - "@smithy/util-endpoints": ^1.0.8 - "@smithy/util-retry": ^2.0.9 - "@smithy/util-utf8": ^2.0.2 + "@aws-sdk/client-sts": 3.495.0 + "@aws-sdk/core": 3.495.0 + "@aws-sdk/credential-provider-node": 3.495.0 + "@aws-sdk/middleware-host-header": 3.495.0 + "@aws-sdk/middleware-logger": 3.495.0 + "@aws-sdk/middleware-recursion-detection": 3.495.0 + "@aws-sdk/middleware-signing": 3.495.0 + "@aws-sdk/middleware-user-agent": 3.495.0 + "@aws-sdk/region-config-resolver": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-endpoints": 3.495.0 + "@aws-sdk/util-user-agent-browser": 3.495.0 + "@aws-sdk/util-user-agent-node": 3.495.0 + "@smithy/config-resolver": ^2.1.0 + "@smithy/core": ^1.3.0 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/hash-node": ^2.1.0 + "@smithy/invalid-dependency": ^2.1.0 + "@smithy/middleware-content-length": ^2.1.0 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/middleware-retry": ^2.1.0 + "@smithy/middleware-serde": ^2.1.0 + "@smithy/middleware-stack": ^2.1.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/url-parser": ^2.1.0 + "@smithy/util-base64": ^2.1.0 + "@smithy/util-body-length-browser": ^2.1.0 + "@smithy/util-body-length-node": ^2.2.0 + "@smithy/util-defaults-mode-browser": ^2.1.0 + "@smithy/util-defaults-mode-node": ^2.1.0 + "@smithy/util-endpoints": ^1.1.0 + "@smithy/util-retry": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: 4b131c722d611242c8d5eb961115fb60f40bd228ecb2f6ce4851d30bae7b3b39b68cfd6ca363f901e8c16571539d37c7a617dae6681aa0bcfeec189a6b5afcea + checksum: 078c17e6f6fed15ee320a4d94e9925ff7ccb537416552492b3e66179998a8259c1d68c2f1523243c497c7bc64d613f33acc92b9f9c2c9238eee41be26aebcaf9 languageName: node linkType: hard "@aws-sdk/client-eks@npm:^3.350.0": - version: 3.490.0 - resolution: "@aws-sdk/client-eks@npm:3.490.0" + version: 3.495.0 + resolution: "@aws-sdk/client-eks@npm:3.495.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.490.0 - "@aws-sdk/core": 3.490.0 - "@aws-sdk/credential-provider-node": 3.490.0 - "@aws-sdk/middleware-host-header": 3.489.0 - "@aws-sdk/middleware-logger": 3.489.0 - "@aws-sdk/middleware-recursion-detection": 3.489.0 - "@aws-sdk/middleware-signing": 3.489.0 - "@aws-sdk/middleware-user-agent": 3.489.0 - "@aws-sdk/region-config-resolver": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-endpoints": 3.489.0 - "@aws-sdk/util-user-agent-browser": 3.489.0 - "@aws-sdk/util-user-agent-node": 3.489.0 - "@smithy/config-resolver": ^2.0.23 - "@smithy/core": ^1.2.2 - "@smithy/fetch-http-handler": ^2.3.2 - "@smithy/hash-node": ^2.0.18 - "@smithy/invalid-dependency": ^2.0.16 - "@smithy/middleware-content-length": ^2.0.18 - "@smithy/middleware-endpoint": ^2.3.0 - "@smithy/middleware-retry": ^2.0.26 - "@smithy/middleware-serde": ^2.0.16 - "@smithy/middleware-stack": ^2.0.10 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/node-http-handler": ^2.2.2 - "@smithy/protocol-http": ^3.0.12 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/url-parser": ^2.0.16 - "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.1 - "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.24 - "@smithy/util-defaults-mode-node": ^2.0.32 - "@smithy/util-endpoints": ^1.0.8 - "@smithy/util-retry": ^2.0.9 - "@smithy/util-utf8": ^2.0.2 - "@smithy/util-waiter": ^2.0.16 + "@aws-sdk/client-sts": 3.495.0 + "@aws-sdk/core": 3.495.0 + "@aws-sdk/credential-provider-node": 3.495.0 + "@aws-sdk/middleware-host-header": 3.495.0 + "@aws-sdk/middleware-logger": 3.495.0 + "@aws-sdk/middleware-recursion-detection": 3.495.0 + "@aws-sdk/middleware-signing": 3.495.0 + "@aws-sdk/middleware-user-agent": 3.495.0 + "@aws-sdk/region-config-resolver": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-endpoints": 3.495.0 + "@aws-sdk/util-user-agent-browser": 3.495.0 + "@aws-sdk/util-user-agent-node": 3.495.0 + "@smithy/config-resolver": ^2.1.0 + "@smithy/core": ^1.3.0 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/hash-node": ^2.1.0 + "@smithy/invalid-dependency": ^2.1.0 + "@smithy/middleware-content-length": ^2.1.0 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/middleware-retry": ^2.1.0 + "@smithy/middleware-serde": ^2.1.0 + "@smithy/middleware-stack": ^2.1.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/url-parser": ^2.1.0 + "@smithy/util-base64": ^2.1.0 + "@smithy/util-body-length-browser": ^2.1.0 + "@smithy/util-body-length-node": ^2.2.0 + "@smithy/util-defaults-mode-browser": ^2.1.0 + "@smithy/util-defaults-mode-node": ^2.1.0 + "@smithy/util-endpoints": ^1.1.0 + "@smithy/util-retry": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 + "@smithy/util-waiter": ^2.1.0 tslib: ^2.5.0 uuid: ^8.3.2 - checksum: 367e3c987f644b0b4a6c5fba1ef1e6caa52594205ac9efe095960e00dcf4b0191f143080cfbdbb3807b91140cda14973f734e536104b355908d9c7ed3ba9fa64 + checksum: f4d9ce87c23c1d117e4046c97ac974131e54b878eb0aed9457739ca0d202f8d36c9b2ba3718120de531fdb200ccab123a4d1f848ef8c3858b1ca5d81dcd9c789 languageName: node linkType: hard "@aws-sdk/client-organizations@npm:^3.350.0": - version: 3.490.0 - resolution: "@aws-sdk/client-organizations@npm:3.490.0" + version: 3.495.0 + resolution: "@aws-sdk/client-organizations@npm:3.495.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.490.0 - "@aws-sdk/core": 3.490.0 - "@aws-sdk/credential-provider-node": 3.490.0 - "@aws-sdk/middleware-host-header": 3.489.0 - "@aws-sdk/middleware-logger": 3.489.0 - "@aws-sdk/middleware-recursion-detection": 3.489.0 - "@aws-sdk/middleware-signing": 3.489.0 - "@aws-sdk/middleware-user-agent": 3.489.0 - "@aws-sdk/region-config-resolver": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-endpoints": 3.489.0 - "@aws-sdk/util-user-agent-browser": 3.489.0 - "@aws-sdk/util-user-agent-node": 3.489.0 - "@smithy/config-resolver": ^2.0.23 - "@smithy/core": ^1.2.2 - "@smithy/fetch-http-handler": ^2.3.2 - "@smithy/hash-node": ^2.0.18 - "@smithy/invalid-dependency": ^2.0.16 - "@smithy/middleware-content-length": ^2.0.18 - "@smithy/middleware-endpoint": ^2.3.0 - "@smithy/middleware-retry": ^2.0.26 - "@smithy/middleware-serde": ^2.0.16 - "@smithy/middleware-stack": ^2.0.10 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/node-http-handler": ^2.2.2 - "@smithy/protocol-http": ^3.0.12 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/url-parser": ^2.0.16 - "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.1 - "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.24 - "@smithy/util-defaults-mode-node": ^2.0.32 - "@smithy/util-endpoints": ^1.0.8 - "@smithy/util-retry": ^2.0.9 - "@smithy/util-utf8": ^2.0.2 + "@aws-sdk/client-sts": 3.495.0 + "@aws-sdk/core": 3.495.0 + "@aws-sdk/credential-provider-node": 3.495.0 + "@aws-sdk/middleware-host-header": 3.495.0 + "@aws-sdk/middleware-logger": 3.495.0 + "@aws-sdk/middleware-recursion-detection": 3.495.0 + "@aws-sdk/middleware-signing": 3.495.0 + "@aws-sdk/middleware-user-agent": 3.495.0 + "@aws-sdk/region-config-resolver": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-endpoints": 3.495.0 + "@aws-sdk/util-user-agent-browser": 3.495.0 + "@aws-sdk/util-user-agent-node": 3.495.0 + "@smithy/config-resolver": ^2.1.0 + "@smithy/core": ^1.3.0 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/hash-node": ^2.1.0 + "@smithy/invalid-dependency": ^2.1.0 + "@smithy/middleware-content-length": ^2.1.0 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/middleware-retry": ^2.1.0 + "@smithy/middleware-serde": ^2.1.0 + "@smithy/middleware-stack": ^2.1.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/url-parser": ^2.1.0 + "@smithy/util-base64": ^2.1.0 + "@smithy/util-body-length-browser": ^2.1.0 + "@smithy/util-body-length-node": ^2.2.0 + "@smithy/util-defaults-mode-browser": ^2.1.0 + "@smithy/util-defaults-mode-node": ^2.1.0 + "@smithy/util-endpoints": ^1.1.0 + "@smithy/util-retry": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: 073bc5ecc31e7c0cb0fd195e868f17946e7f60e12cdab3402fd1752374939915affb8f15fb55697f1a626736d7b05e35e65d466a5dddfd6e091eb0e16803f8a8 + checksum: 3c7deae27a0549ff97551d577df701f21823ca6f3fc965b35add491642faf3ddb060183752687264727e10cc80addb1a3c263af81f2a35d15fe0c3edb02a5da2 languageName: node linkType: hard "@aws-sdk/client-s3@npm:^3.350.0": - version: 3.490.0 - resolution: "@aws-sdk/client-s3@npm:3.490.0" + version: 3.495.0 + resolution: "@aws-sdk/client-s3@npm:3.495.0" dependencies: "@aws-crypto/sha1-browser": 3.0.0 "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.490.0 - "@aws-sdk/core": 3.490.0 - "@aws-sdk/credential-provider-node": 3.490.0 - "@aws-sdk/middleware-bucket-endpoint": 3.489.0 - "@aws-sdk/middleware-expect-continue": 3.489.0 - "@aws-sdk/middleware-flexible-checksums": 3.489.0 - "@aws-sdk/middleware-host-header": 3.489.0 - "@aws-sdk/middleware-location-constraint": 3.489.0 - "@aws-sdk/middleware-logger": 3.489.0 - "@aws-sdk/middleware-recursion-detection": 3.489.0 - "@aws-sdk/middleware-sdk-s3": 3.489.0 - "@aws-sdk/middleware-signing": 3.489.0 - "@aws-sdk/middleware-ssec": 3.489.0 - "@aws-sdk/middleware-user-agent": 3.489.0 - "@aws-sdk/region-config-resolver": 3.489.0 - "@aws-sdk/signature-v4-multi-region": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-endpoints": 3.489.0 - "@aws-sdk/util-user-agent-browser": 3.489.0 - "@aws-sdk/util-user-agent-node": 3.489.0 - "@aws-sdk/xml-builder": 3.485.0 - "@smithy/config-resolver": ^2.0.23 - "@smithy/core": ^1.2.2 - "@smithy/eventstream-serde-browser": ^2.0.16 - "@smithy/eventstream-serde-config-resolver": ^2.0.16 - "@smithy/eventstream-serde-node": ^2.0.16 - "@smithy/fetch-http-handler": ^2.3.2 - "@smithy/hash-blob-browser": ^2.0.17 - "@smithy/hash-node": ^2.0.18 - "@smithy/hash-stream-node": ^2.0.18 - "@smithy/invalid-dependency": ^2.0.16 - "@smithy/md5-js": ^2.0.18 - "@smithy/middleware-content-length": ^2.0.18 - "@smithy/middleware-endpoint": ^2.3.0 - "@smithy/middleware-retry": ^2.0.26 - "@smithy/middleware-serde": ^2.0.16 - "@smithy/middleware-stack": ^2.0.10 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/node-http-handler": ^2.2.2 - "@smithy/protocol-http": ^3.0.12 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/url-parser": ^2.0.16 - "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.1 - "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.24 - "@smithy/util-defaults-mode-node": ^2.0.32 - "@smithy/util-endpoints": ^1.0.8 - "@smithy/util-retry": ^2.0.9 - "@smithy/util-stream": ^2.0.24 - "@smithy/util-utf8": ^2.0.2 - "@smithy/util-waiter": ^2.0.16 + "@aws-sdk/client-sts": 3.495.0 + "@aws-sdk/core": 3.495.0 + "@aws-sdk/credential-provider-node": 3.495.0 + "@aws-sdk/middleware-bucket-endpoint": 3.495.0 + "@aws-sdk/middleware-expect-continue": 3.495.0 + "@aws-sdk/middleware-flexible-checksums": 3.495.0 + "@aws-sdk/middleware-host-header": 3.495.0 + "@aws-sdk/middleware-location-constraint": 3.495.0 + "@aws-sdk/middleware-logger": 3.495.0 + "@aws-sdk/middleware-recursion-detection": 3.495.0 + "@aws-sdk/middleware-sdk-s3": 3.495.0 + "@aws-sdk/middleware-signing": 3.495.0 + "@aws-sdk/middleware-ssec": 3.495.0 + "@aws-sdk/middleware-user-agent": 3.495.0 + "@aws-sdk/region-config-resolver": 3.495.0 + "@aws-sdk/signature-v4-multi-region": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-endpoints": 3.495.0 + "@aws-sdk/util-user-agent-browser": 3.495.0 + "@aws-sdk/util-user-agent-node": 3.495.0 + "@aws-sdk/xml-builder": 3.495.0 + "@smithy/config-resolver": ^2.1.0 + "@smithy/core": ^1.3.0 + "@smithy/eventstream-serde-browser": ^2.1.0 + "@smithy/eventstream-serde-config-resolver": ^2.1.0 + "@smithy/eventstream-serde-node": ^2.1.0 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/hash-blob-browser": ^2.1.0 + "@smithy/hash-node": ^2.1.0 + "@smithy/hash-stream-node": ^2.1.0 + "@smithy/invalid-dependency": ^2.1.0 + "@smithy/md5-js": ^2.1.0 + "@smithy/middleware-content-length": ^2.1.0 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/middleware-retry": ^2.1.0 + "@smithy/middleware-serde": ^2.1.0 + "@smithy/middleware-stack": ^2.1.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/url-parser": ^2.1.0 + "@smithy/util-base64": ^2.1.0 + "@smithy/util-body-length-browser": ^2.1.0 + "@smithy/util-body-length-node": ^2.2.0 + "@smithy/util-defaults-mode-browser": ^2.1.0 + "@smithy/util-defaults-mode-node": ^2.1.0 + "@smithy/util-endpoints": ^1.1.0 + "@smithy/util-retry": ^2.1.0 + "@smithy/util-stream": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 + "@smithy/util-waiter": ^2.1.0 fast-xml-parser: 4.2.5 tslib: ^2.5.0 - checksum: 28fc1c384bdba8c374ac8f150350feb5b6e8afaef76aaba2705d8d06d60dec9a209869888a3e91e75c88454084940916b1bc6070cc422d50712af7dd20a66ccf + checksum: 2add0f58189bfc394a6b3963ef4295b9997f3ea544d8a92ba2d16b9051f4fd07fb9f184e9ad6ca6ce665cbec496abd5e0e69a91a97213117dc20aafd3bed2840 languageName: node linkType: hard "@aws-sdk/client-sqs@npm:^3.350.0": - version: 3.490.0 - resolution: "@aws-sdk/client-sqs@npm:3.490.0" + version: 3.495.0 + resolution: "@aws-sdk/client-sqs@npm:3.495.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.490.0 - "@aws-sdk/core": 3.490.0 - "@aws-sdk/credential-provider-node": 3.490.0 - "@aws-sdk/middleware-host-header": 3.489.0 - "@aws-sdk/middleware-logger": 3.489.0 - "@aws-sdk/middleware-recursion-detection": 3.489.0 - "@aws-sdk/middleware-sdk-sqs": 3.489.0 - "@aws-sdk/middleware-user-agent": 3.489.0 - "@aws-sdk/region-config-resolver": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-endpoints": 3.489.0 - "@aws-sdk/util-user-agent-browser": 3.489.0 - "@aws-sdk/util-user-agent-node": 3.489.0 - "@smithy/config-resolver": ^2.0.23 - "@smithy/core": ^1.2.2 - "@smithy/fetch-http-handler": ^2.3.2 - "@smithy/hash-node": ^2.0.18 - "@smithy/invalid-dependency": ^2.0.16 - "@smithy/md5-js": ^2.0.18 - "@smithy/middleware-content-length": ^2.0.18 - "@smithy/middleware-endpoint": ^2.3.0 - "@smithy/middleware-retry": ^2.0.26 - "@smithy/middleware-serde": ^2.0.16 - "@smithy/middleware-stack": ^2.0.10 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/node-http-handler": ^2.2.2 - "@smithy/protocol-http": ^3.0.12 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/url-parser": ^2.0.16 - "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.1 - "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.24 - "@smithy/util-defaults-mode-node": ^2.0.32 - "@smithy/util-endpoints": ^1.0.8 - "@smithy/util-middleware": ^2.0.9 - "@smithy/util-retry": ^2.0.9 - "@smithy/util-utf8": ^2.0.2 + "@aws-sdk/client-sts": 3.495.0 + "@aws-sdk/core": 3.495.0 + "@aws-sdk/credential-provider-node": 3.495.0 + "@aws-sdk/middleware-host-header": 3.495.0 + "@aws-sdk/middleware-logger": 3.495.0 + "@aws-sdk/middleware-recursion-detection": 3.495.0 + "@aws-sdk/middleware-sdk-sqs": 3.495.0 + "@aws-sdk/middleware-user-agent": 3.495.0 + "@aws-sdk/region-config-resolver": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-endpoints": 3.495.0 + "@aws-sdk/util-user-agent-browser": 3.495.0 + "@aws-sdk/util-user-agent-node": 3.495.0 + "@smithy/config-resolver": ^2.1.0 + "@smithy/core": ^1.3.0 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/hash-node": ^2.1.0 + "@smithy/invalid-dependency": ^2.1.0 + "@smithy/md5-js": ^2.1.0 + "@smithy/middleware-content-length": ^2.1.0 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/middleware-retry": ^2.1.0 + "@smithy/middleware-serde": ^2.1.0 + "@smithy/middleware-stack": ^2.1.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/url-parser": ^2.1.0 + "@smithy/util-base64": ^2.1.0 + "@smithy/util-body-length-browser": ^2.1.0 + "@smithy/util-body-length-node": ^2.2.0 + "@smithy/util-defaults-mode-browser": ^2.1.0 + "@smithy/util-defaults-mode-node": ^2.1.0 + "@smithy/util-endpoints": ^1.1.0 + "@smithy/util-middleware": ^2.1.0 + "@smithy/util-retry": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: 394f351ca8feff09b631eab6e285068379384a592832ec8ae502a15f60a475f2aa43e29d74b0dd5c2732610a9f7f122148ee442550975ecded53368b8d01a6b1 + checksum: 4dcbf031c1902149d8fa82f7c555eb416d904c1e197ad2deae927856748719c03b025bb122a131df34435269039a6b0538635826e0bcab204b86ef24fe4595b8 languageName: node linkType: hard -"@aws-sdk/client-sso@npm:3.490.0": - version: 3.490.0 - resolution: "@aws-sdk/client-sso@npm:3.490.0" +"@aws-sdk/client-sso@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/client-sso@npm:3.495.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/core": 3.490.0 - "@aws-sdk/middleware-host-header": 3.489.0 - "@aws-sdk/middleware-logger": 3.489.0 - "@aws-sdk/middleware-recursion-detection": 3.489.0 - "@aws-sdk/middleware-user-agent": 3.489.0 - "@aws-sdk/region-config-resolver": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-endpoints": 3.489.0 - "@aws-sdk/util-user-agent-browser": 3.489.0 - "@aws-sdk/util-user-agent-node": 3.489.0 - "@smithy/config-resolver": ^2.0.23 - "@smithy/core": ^1.2.2 - "@smithy/fetch-http-handler": ^2.3.2 - "@smithy/hash-node": ^2.0.18 - "@smithy/invalid-dependency": ^2.0.16 - "@smithy/middleware-content-length": ^2.0.18 - "@smithy/middleware-endpoint": ^2.3.0 - "@smithy/middleware-retry": ^2.0.26 - "@smithy/middleware-serde": ^2.0.16 - "@smithy/middleware-stack": ^2.0.10 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/node-http-handler": ^2.2.2 - "@smithy/protocol-http": ^3.0.12 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/url-parser": ^2.0.16 - "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.1 - "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.24 - "@smithy/util-defaults-mode-node": ^2.0.32 - "@smithy/util-endpoints": ^1.0.8 - "@smithy/util-retry": ^2.0.9 - "@smithy/util-utf8": ^2.0.2 + "@aws-sdk/core": 3.495.0 + "@aws-sdk/middleware-host-header": 3.495.0 + "@aws-sdk/middleware-logger": 3.495.0 + "@aws-sdk/middleware-recursion-detection": 3.495.0 + "@aws-sdk/middleware-user-agent": 3.495.0 + "@aws-sdk/region-config-resolver": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-endpoints": 3.495.0 + "@aws-sdk/util-user-agent-browser": 3.495.0 + "@aws-sdk/util-user-agent-node": 3.495.0 + "@smithy/config-resolver": ^2.1.0 + "@smithy/core": ^1.3.0 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/hash-node": ^2.1.0 + "@smithy/invalid-dependency": ^2.1.0 + "@smithy/middleware-content-length": ^2.1.0 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/middleware-retry": ^2.1.0 + "@smithy/middleware-serde": ^2.1.0 + "@smithy/middleware-stack": ^2.1.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/url-parser": ^2.1.0 + "@smithy/util-base64": ^2.1.0 + "@smithy/util-body-length-browser": ^2.1.0 + "@smithy/util-body-length-node": ^2.2.0 + "@smithy/util-defaults-mode-browser": ^2.1.0 + "@smithy/util-defaults-mode-node": ^2.1.0 + "@smithy/util-endpoints": ^1.1.0 + "@smithy/util-retry": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: f09172f7af1de8371dc4bd03ef18f2a260bd9868db9460912d392d0f2bcf4101e8f78eed440db6bd99437a3b8d1c1a107fb3bc904f20f4a99eb0a262c0644b14 + checksum: a4672a8a2c454be634cb7e97a3cc075df55ad7ab8eb494bda3e4d16831f110212069668ab4fe6085f4b09920d1a04f3bd2cca0caf3a395d874cbcf5d71c6ffe7 languageName: node linkType: hard -"@aws-sdk/client-sts@npm:3.490.0, @aws-sdk/client-sts@npm:^3.350.0": - version: 3.490.0 - resolution: "@aws-sdk/client-sts@npm:3.490.0" +"@aws-sdk/client-sts@npm:3.495.0, @aws-sdk/client-sts@npm:^3.350.0": + version: 3.495.0 + resolution: "@aws-sdk/client-sts@npm:3.495.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/core": 3.490.0 - "@aws-sdk/credential-provider-node": 3.490.0 - "@aws-sdk/middleware-host-header": 3.489.0 - "@aws-sdk/middleware-logger": 3.489.0 - "@aws-sdk/middleware-recursion-detection": 3.489.0 - "@aws-sdk/middleware-user-agent": 3.489.0 - "@aws-sdk/region-config-resolver": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-endpoints": 3.489.0 - "@aws-sdk/util-user-agent-browser": 3.489.0 - "@aws-sdk/util-user-agent-node": 3.489.0 - "@smithy/config-resolver": ^2.0.23 - "@smithy/core": ^1.2.2 - "@smithy/fetch-http-handler": ^2.3.2 - "@smithy/hash-node": ^2.0.18 - "@smithy/invalid-dependency": ^2.0.16 - "@smithy/middleware-content-length": ^2.0.18 - "@smithy/middleware-endpoint": ^2.3.0 - "@smithy/middleware-retry": ^2.0.26 - "@smithy/middleware-serde": ^2.0.16 - "@smithy/middleware-stack": ^2.0.10 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/node-http-handler": ^2.2.2 - "@smithy/protocol-http": ^3.0.12 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/url-parser": ^2.0.16 - "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.1 - "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.24 - "@smithy/util-defaults-mode-node": ^2.0.32 - "@smithy/util-endpoints": ^1.0.8 - "@smithy/util-middleware": ^2.0.9 - "@smithy/util-retry": ^2.0.9 - "@smithy/util-utf8": ^2.0.2 + "@aws-sdk/core": 3.495.0 + "@aws-sdk/credential-provider-node": 3.495.0 + "@aws-sdk/middleware-host-header": 3.495.0 + "@aws-sdk/middleware-logger": 3.495.0 + "@aws-sdk/middleware-recursion-detection": 3.495.0 + "@aws-sdk/middleware-user-agent": 3.495.0 + "@aws-sdk/region-config-resolver": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-endpoints": 3.495.0 + "@aws-sdk/util-user-agent-browser": 3.495.0 + "@aws-sdk/util-user-agent-node": 3.495.0 + "@smithy/config-resolver": ^2.1.0 + "@smithy/core": ^1.3.0 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/hash-node": ^2.1.0 + "@smithy/invalid-dependency": ^2.1.0 + "@smithy/middleware-content-length": ^2.1.0 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/middleware-retry": ^2.1.0 + "@smithy/middleware-serde": ^2.1.0 + "@smithy/middleware-stack": ^2.1.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/url-parser": ^2.1.0 + "@smithy/util-base64": ^2.1.0 + "@smithy/util-body-length-browser": ^2.1.0 + "@smithy/util-body-length-node": ^2.2.0 + "@smithy/util-defaults-mode-browser": ^2.1.0 + "@smithy/util-defaults-mode-node": ^2.1.0 + "@smithy/util-endpoints": ^1.1.0 + "@smithy/util-middleware": ^2.1.0 + "@smithy/util-retry": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 fast-xml-parser: 4.2.5 tslib: ^2.5.0 - checksum: 0fffd52bfae00c2e1beacf2cc58924131097efb7022a72f2d8c00e93e9c00ceb584d085b92160a2798d761726c7ca8492da5a7e8665d103a658ad96f9633e04e + checksum: 33c5ef3fc87a2fb8cb5dc6bc855c5756712110d1c0be713543ffd657fcae4062e10ce9a1501bb9bc7a9f821a542f6e52c3bd9d88add89af67a116f3f5ab486fd languageName: node linkType: hard -"@aws-sdk/core@npm:3.490.0": - version: 3.490.0 - resolution: "@aws-sdk/core@npm:3.490.0" +"@aws-sdk/core@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/core@npm:3.495.0" dependencies: - "@smithy/core": ^1.2.2 - "@smithy/protocol-http": ^3.0.12 - "@smithy/signature-v4": ^2.0.0 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 + "@smithy/core": ^1.3.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/signature-v4": ^2.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 8d711ba4373b4ee074f5a225642cb91cd0052daf1e2880da1f5bd1b38197ea5c7888a4181710f715393f83618aacc4465262f9a80de8f4faf2644d5832e455b5 + checksum: 2038b283ab62a0a10880a7193cef8b3673298ff9b7ba3005e3a47df43c588d3a3a9dfdbe607b99183932675a74ec17a88a90f9a5c5f5896292a9e6cbc888cf13 languageName: node linkType: hard -"@aws-sdk/credential-provider-cognito-identity@npm:3.490.0": - version: 3.490.0 - resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.490.0" +"@aws-sdk/credential-provider-cognito-identity@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.495.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.490.0 - "@aws-sdk/types": 3.489.0 - "@smithy/property-provider": ^2.0.0 - "@smithy/types": ^2.8.0 + "@aws-sdk/client-cognito-identity": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: c1ee2aa0c1d6c9bd61f17550c9381b05e790f23afc5dd757a242e2a9f8ee0c03c49f8b29452258b86c5f68b9e87fba3eb5b299ceb6414f1db6919de32aacba17 + checksum: 8bd8841d5d2e5316c271f6e5585216f906d60a42b221d5afdd52d49b6318faa6776cdc956704a22b675c5dd41fd164a2cf512f069a99738660eeea24c3316234 languageName: node linkType: hard -"@aws-sdk/credential-provider-env@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/credential-provider-env@npm:3.489.0" +"@aws-sdk/credential-provider-env@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/property-provider": ^2.0.0 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: ef1c3fb9e12cb3b62be41d87ce168b704d462b6fb27d08eab58b003940e3b24b043f122efab42cdc41d0bd632074114f39b474c480705dc61ed6e879690fa93f + checksum: 5454a770638e2122877679897acb422871e0381c7e8a2a848c1837f16115bea7d3abaf56e2282b9986885de186538868f90c62292348251bbbd84c872c4a5eb0 languageName: node linkType: hard -"@aws-sdk/credential-provider-http@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/credential-provider-http@npm:3.489.0" +"@aws-sdk/credential-provider-http@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/fetch-http-handler": ^2.3.2 - "@smithy/node-http-handler": ^2.2.2 - "@smithy/property-provider": ^2.0.0 - "@smithy/protocol-http": ^3.0.12 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/util-stream": ^2.0.24 + "@aws-sdk/types": 3.495.0 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/util-stream": ^2.1.0 tslib: ^2.5.0 - checksum: 601580c4299b1b0d7a696a94643b78c12491261f975275c5ae544ca5eee1f08fb4d21af1935257f2972b1f8ed8c0246275963e9c97cc53484f6d501ad6dbd4c6 + checksum: 367563058b01bc681523de85f4753bb53c53b0975c9258d6b4583222a28543ca2b2e3b5f75c1f1f6fb25a25baeb053d8d46c86b6997c4243bfc062a03093bae8 languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:3.490.0": - version: 3.490.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.490.0" +"@aws-sdk/credential-provider-ini@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.495.0" dependencies: - "@aws-sdk/credential-provider-env": 3.489.0 - "@aws-sdk/credential-provider-process": 3.489.0 - "@aws-sdk/credential-provider-sso": 3.490.0 - "@aws-sdk/credential-provider-web-identity": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@smithy/credential-provider-imds": ^2.0.0 - "@smithy/property-provider": ^2.0.0 - "@smithy/shared-ini-file-loader": ^2.0.6 - "@smithy/types": ^2.8.0 + "@aws-sdk/credential-provider-env": 3.495.0 + "@aws-sdk/credential-provider-process": 3.495.0 + "@aws-sdk/credential-provider-sso": 3.495.0 + "@aws-sdk/credential-provider-web-identity": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@smithy/credential-provider-imds": ^2.2.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/shared-ini-file-loader": ^2.3.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 5dd24af06b3a2977c1ebd47621619b18b8d9f9bed04e8ac5daae9faedabe66d6c6792a62da54513d668f0b11315cab4fd41a85637e35646cec46588742e36b1f + checksum: fcd401dcc8a71a601888a9abd5e915ae8bdf19501ed0f497478d8844a7e11769314488b2b3a1995c33a954ab499ab118911decdfaf8151e47c4768d6e090a429 languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:3.490.0, @aws-sdk/credential-provider-node@npm:^3.350.0": - version: 3.490.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.490.0" +"@aws-sdk/credential-provider-node@npm:3.495.0, @aws-sdk/credential-provider-node@npm:^3.350.0": + version: 3.495.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.495.0" dependencies: - "@aws-sdk/credential-provider-env": 3.489.0 - "@aws-sdk/credential-provider-ini": 3.490.0 - "@aws-sdk/credential-provider-process": 3.489.0 - "@aws-sdk/credential-provider-sso": 3.490.0 - "@aws-sdk/credential-provider-web-identity": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@smithy/credential-provider-imds": ^2.0.0 - "@smithy/property-provider": ^2.0.0 - "@smithy/shared-ini-file-loader": ^2.0.6 - "@smithy/types": ^2.8.0 + "@aws-sdk/credential-provider-env": 3.495.0 + "@aws-sdk/credential-provider-ini": 3.495.0 + "@aws-sdk/credential-provider-process": 3.495.0 + "@aws-sdk/credential-provider-sso": 3.495.0 + "@aws-sdk/credential-provider-web-identity": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@smithy/credential-provider-imds": ^2.2.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/shared-ini-file-loader": ^2.3.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 52820573a6aff0ea8c7ca0699fb374ba9a94a9e9eb777c2b1225d3565fdde7a65c70fcbe9ec887cf555c2df73cdc341641791f1358a102e052869d0f4978d4d0 + checksum: c661de3423fb106d1f3347e24287d0fd9208e02a2fe4159300ec7c1df90196f09df25aab06428f64d3cfcae2a28482737d8cd9ad6d8adca0aa0cfa810276b0ac languageName: node linkType: hard -"@aws-sdk/credential-provider-process@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/credential-provider-process@npm:3.489.0" +"@aws-sdk/credential-provider-process@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/property-provider": ^2.0.0 - "@smithy/shared-ini-file-loader": ^2.0.6 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/shared-ini-file-loader": ^2.3.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 19eb75f0222176f33ad5fbeb5a02b312a37a48966b73ff5c1af9974d439dc4c6faeffe745c2a23b0abb67ab876f9e10099b4a22c2ee9d15be5290556331a7a9a + checksum: e19812756fb578cf5e7845db1fc2df77fadb427efaefe7ce23effa20f5f7e1661cea05179ab425e3cbef08966b1821a4ccfbd00343f68f65b0564c0b06510b9a languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:3.490.0": - version: 3.490.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.490.0" +"@aws-sdk/credential-provider-sso@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.495.0" dependencies: - "@aws-sdk/client-sso": 3.490.0 - "@aws-sdk/token-providers": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@smithy/property-provider": ^2.0.0 - "@smithy/shared-ini-file-loader": ^2.0.6 - "@smithy/types": ^2.8.0 + "@aws-sdk/client-sso": 3.495.0 + "@aws-sdk/token-providers": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/shared-ini-file-loader": ^2.3.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: ea3c9d180f13f676b7717a8e0aabdca33b36f2dbf27128dfa6f8172040aa895437ef03e08802b9d6b104a783b8606b8af923193ff54f79e92118aa54babaa311 + checksum: 2f96aba1921612026e8dcd7d7f58988c63efdf270a8688adb0704f2e442778700d7160c890cf926a89eb79a2471ee9084329bd8463998bbb416b0f5ebfe8f7e3 languageName: node linkType: hard -"@aws-sdk/credential-provider-web-identity@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.489.0" +"@aws-sdk/credential-provider-web-identity@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/property-provider": ^2.0.0 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 6da681688c9a61b6e100c71983a1ba19ef34bcbd8d1e4e85e3399d86e74cdc8d81f57b6da1983319596c87ef1600471e82c5243fb909f9752eff99a6ef26a8ea + checksum: d22fda65683d0558dd03e710c8ef4762c4c500d8527cf951b3597a716a56ffbd1d9bf22089e4714325f4043a5e9eb9f6b27e2e3f217eef06de3cc3364e5a8a0f languageName: node linkType: hard "@aws-sdk/credential-providers@npm:^3.350.0": - version: 3.490.0 - resolution: "@aws-sdk/credential-providers@npm:3.490.0" + version: 3.495.0 + resolution: "@aws-sdk/credential-providers@npm:3.495.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.490.0 - "@aws-sdk/client-sso": 3.490.0 - "@aws-sdk/client-sts": 3.490.0 - "@aws-sdk/credential-provider-cognito-identity": 3.490.0 - "@aws-sdk/credential-provider-env": 3.489.0 - "@aws-sdk/credential-provider-http": 3.489.0 - "@aws-sdk/credential-provider-ini": 3.490.0 - "@aws-sdk/credential-provider-node": 3.490.0 - "@aws-sdk/credential-provider-process": 3.489.0 - "@aws-sdk/credential-provider-sso": 3.490.0 - "@aws-sdk/credential-provider-web-identity": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@smithy/credential-provider-imds": ^2.0.0 - "@smithy/property-provider": ^2.0.0 - "@smithy/types": ^2.8.0 + "@aws-sdk/client-cognito-identity": 3.495.0 + "@aws-sdk/client-sso": 3.495.0 + "@aws-sdk/client-sts": 3.495.0 + "@aws-sdk/credential-provider-cognito-identity": 3.495.0 + "@aws-sdk/credential-provider-env": 3.495.0 + "@aws-sdk/credential-provider-http": 3.495.0 + "@aws-sdk/credential-provider-ini": 3.495.0 + "@aws-sdk/credential-provider-node": 3.495.0 + "@aws-sdk/credential-provider-process": 3.495.0 + "@aws-sdk/credential-provider-sso": 3.495.0 + "@aws-sdk/credential-provider-web-identity": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@smithy/credential-provider-imds": ^2.2.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 470f752cdf07861b6d5d7aff18e0541400bb211fcda7037347593f67d3882be9f5bd66b334915dc6549b96c554e1334e1dfec3286210eb9e18628a8bc2f19052 + checksum: 1cb201bc9fe2f2f5edd277416962e32e6f99ecc98b5d386bfcac91d6db1719d66b57b1e690d660a6fe1ac198648d5df906397ac5e2d9d5a35d345bcc3230324a languageName: node linkType: hard @@ -897,34 +897,34 @@ __metadata: linkType: hard "@aws-sdk/lib-storage@npm:^3.350.0": - version: 3.490.0 - resolution: "@aws-sdk/lib-storage@npm:3.490.0" + version: 3.495.0 + resolution: "@aws-sdk/lib-storage@npm:3.495.0" dependencies: - "@smithy/abort-controller": ^2.0.1 - "@smithy/middleware-endpoint": ^2.3.0 - "@smithy/smithy-client": ^2.2.1 + "@smithy/abort-controller": ^2.1.0 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/smithy-client": ^2.3.0 buffer: 5.6.0 events: 3.3.0 stream-browserify: 3.0.0 tslib: ^2.5.0 peerDependencies: "@aws-sdk/client-s3": ^3.0.0 - checksum: 253dc2e4fd33efcf5ee8d3ad76bb3f2ed1d4573e27fa8be23dc3b9b60bcf22e769684f3ab639c3551a66282e160e4b1693527ac49062c6a42b55716e7aadc6df + checksum: 6d7a1576f30ff2432f0907a8357604de5a6d338c706e34c8e85ef6fbb4e2a878c84ce41978c79844757454b0e90914c83b4c983a428a7ea0ba67b6ce7d15c9a8 languageName: node linkType: hard -"@aws-sdk/middleware-bucket-endpoint@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.489.0" +"@aws-sdk/middleware-bucket-endpoint@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-arn-parser": 3.465.0 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/protocol-http": ^3.0.12 - "@smithy/types": ^2.8.0 - "@smithy/util-config-provider": ^2.1.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-arn-parser": 3.495.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/types": ^2.9.0 + "@smithy/util-config-provider": ^2.2.0 tslib: ^2.5.0 - checksum: 209278da47bf7e3b0e3cd6bc0f80d56bd6fc06400c12041474d1fdef7d227b8120bd7ac0b471fd15e03433e8c9e5e8c7a20d4f5f057dc23edfecaf4b61ad1378 + checksum: d75288d8d290b0749a9f17bf893dfb2d334a08707dbda2d24d187f53096c58f190e102a789310045b03792fe6d145a23af7dbac07994b27473f386328cc2bb5c languageName: node linkType: hard @@ -941,107 +941,107 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-expect-continue@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-expect-continue@npm:3.489.0" +"@aws-sdk/middleware-expect-continue@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-expect-continue@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/protocol-http": ^3.0.12 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 2e4bc714e5c410d2362ec274e2f36ffbb35dc826030ac64ec2d34bf9a89b1defa3c8cd1e0d92c4f41ddb64035039ddfac927069152ea70437061f2f078d43cc1 + checksum: d9e49bd36994cc5a0114d51fb050efecf5f9ae46bd5718b5acb98d486a864d33ced0d1a0afc96f22192a23f4a9acf8c784db3d97243b25452c55fd4e3491aec8 languageName: node linkType: hard -"@aws-sdk/middleware-flexible-checksums@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.489.0" +"@aws-sdk/middleware-flexible-checksums@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.495.0" dependencies: "@aws-crypto/crc32": 3.0.0 "@aws-crypto/crc32c": 3.0.0 - "@aws-sdk/types": 3.489.0 - "@smithy/is-array-buffer": ^2.0.0 - "@smithy/protocol-http": ^3.0.12 - "@smithy/types": ^2.8.0 - "@smithy/util-utf8": ^2.0.2 + "@aws-sdk/types": 3.495.0 + "@smithy/is-array-buffer": ^2.1.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/types": ^2.9.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: 522f234ba9fdf5fe1476c72b7480158723a52e15db0560a4d79fa00dd43935633104648a4be2d0d741afa90f5b4f5ced3e99ffdece9b1aa75f4c08389dbe5f10 + checksum: 5ec9e6543222349ee4cc1560ebd0ec3fc076e62bb6a6f2fcfb55cb2b7b6d7f944dd3801869bc3a0367975bf7efbc587c1acb19fc9de07faf389aa966e8eeb15f languageName: node linkType: hard -"@aws-sdk/middleware-host-header@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-host-header@npm:3.489.0" +"@aws-sdk/middleware-host-header@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/protocol-http": ^3.0.12 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 15072d8409066de23ae815ce84c9ab9ce509e368654a3438b398e0f1bec5e215a52a59388ede1fe4c7a40cb639759c50aab3a3562ffe17352a24e6f92f2ddd1e + checksum: 4b4f64827f2f75df045229987625560c1ee35a30e48044f3b60292dbb0599760459097a79e805e2982e1a1150def39758aaf5637e8696b8d21101c03988499ff languageName: node linkType: hard -"@aws-sdk/middleware-location-constraint@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-location-constraint@npm:3.489.0" +"@aws-sdk/middleware-location-constraint@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-location-constraint@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: d9499c897ef1f89afafdc2b4ebaa32cb31396cd7412ddaab545427820c33ef90e6f3e9f16b82607cc7a0d402994034b0c51255c06e2bd15f30d618d10f8bcbc6 + checksum: 8315ea52cff810e8c19176e24528bee4a29af7f2631b1508e04a8936396dd020535e507300df9e5d8b98d4b8c1c5fd78b9e868f0500b7a66e0743394fd2313a5 languageName: node linkType: hard -"@aws-sdk/middleware-logger@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-logger@npm:3.489.0" +"@aws-sdk/middleware-logger@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-logger@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 10fa2538663512158f7a5889da693b0351f1f464457e45bc02199540adf6985ddfda81fe36dbdddabe1fe12709118fa106a365988e691fab834c9d93bf34329e + checksum: d36ee788bdcfc19bd73525c7b0dc476e63b26f4a798a43626fdc76776c0b46f905867bd86c8792aaa7736cbfb18b1fe36c22ef86af4cd8dacdc10e34feee0caf languageName: node linkType: hard -"@aws-sdk/middleware-recursion-detection@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.489.0" +"@aws-sdk/middleware-recursion-detection@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/protocol-http": ^3.0.12 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: bf1592f0577e8a5be5857100c288c0de0895b98b00d1947403d9ff99936d366cd3e8ae4838560ee68ff0d5fb74f26c2f139f23fee8b72ce8f753a742b467bb02 + checksum: eaa7921de46d6d2389b56eb36417a32bd1af41c4ed24f6e2956fa4fd1bb14141253368d96882402df4f6498eaee081c67c170ce74f042d74b0ec431cd1219df7 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-s3@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-sdk-s3@npm:3.489.0" +"@aws-sdk/middleware-sdk-s3@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-sdk-s3@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-arn-parser": 3.465.0 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/protocol-http": ^3.0.12 - "@smithy/signature-v4": ^2.0.0 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/util-config-provider": ^2.1.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-arn-parser": 3.495.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/signature-v4": ^2.1.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/util-config-provider": ^2.2.0 tslib: ^2.5.0 - checksum: 4a1541d7e21172a270cf3965171abcfd1dcb1fc98eac982fb2d3f8dbc10cfecec5ea13bfb27ada66c1a40a6446d027399818edabf1180b340e496eb6826fa8d7 + checksum: b3c6e8fda75ca696a1ba8b2327c1cf3ec941d19af5927614949f4ba317934db2733c22fa011f614651a093a3374d7be1fa5c3f834517a48a6884060ff6cfd625 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-sqs@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.489.0" +"@aws-sdk/middleware-sdk-sqs@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/types": ^2.8.0 - "@smithy/util-hex-encoding": ^2.0.0 - "@smithy/util-utf8": ^2.0.2 + "@aws-sdk/types": 3.495.0 + "@smithy/types": ^2.9.0 + "@smithy/util-hex-encoding": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: a87d0f4c4dd0afd67b37cd5b4de4daa2505c7a51faa2c6aeef6eac0d6a74e68aa3457ec30bc6c174418899899de252ccda1ce53afe8380db2183c8620a4fa84f + checksum: 78c2b4a59fe5fe6797b5a31c486b7169aba57c4c070db1e691c1049d03a6952a406cd88d0d612bbb252a8d06855437022f505934f137e8244db93d33572545ea languageName: node linkType: hard @@ -1055,42 +1055,42 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-signing@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-signing@npm:3.489.0" +"@aws-sdk/middleware-signing@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-signing@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/property-provider": ^2.0.0 - "@smithy/protocol-http": ^3.0.12 - "@smithy/signature-v4": ^2.0.0 - "@smithy/types": ^2.8.0 - "@smithy/util-middleware": ^2.0.9 + "@aws-sdk/types": 3.495.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/signature-v4": ^2.1.0 + "@smithy/types": ^2.9.0 + "@smithy/util-middleware": ^2.1.0 tslib: ^2.5.0 - checksum: bf50942d8ca7baf2d27b0a6d8fb06219971da9863ee0fa7a2ab56c85d344b0374724f608cec371b75a2ea2a0cd4da6d7d431f8bf1f3d9fe5f1797a4d15272962 + checksum: ca717e5c2bc03157f4ee6f3c05d8c815ecf7bab83f5f86c8751a3106d4f5459630258d945d8840650bfb367b881ff3be1fc0c9037162f717380c2a76dec938db languageName: node linkType: hard -"@aws-sdk/middleware-ssec@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-ssec@npm:3.489.0" +"@aws-sdk/middleware-ssec@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-ssec@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: c3666f606bcdcbe2c36a21e0460fd9514ea6f7a3faf09fb392457ca7fc9f41da81351a50f4432ce748a24daad5715736eddf7e59694f0fbbcc530b395c2bf12c + checksum: 5f92ae6ac0b7a869203650c343eb0f42375b8784b20abed88f2075db4413935469c988c5daee6b520aea63a2208ca412a9a78c6fbb0b14fc7719c9dbc9ffdc65 languageName: node linkType: hard -"@aws-sdk/middleware-user-agent@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.489.0" +"@aws-sdk/middleware-user-agent@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-endpoints": 3.489.0 - "@smithy/protocol-http": ^3.0.12 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-endpoints": 3.495.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: b5254863f2203b598199ad65ca87a5a3b92a3ecb51cabbb910819b0f03f61b26b553364e047b9b3329463f8dd4324a650d045deaf548cb5e7de2c08ed2f5dfd6 + checksum: a36dcd5252b001786a8d970143855e80242fa1d88252693a8c2a244114fcfae02eb4ae958a37efa92aeff5cc792506f9199961c346fd943949141a3e078c3123 languageName: node linkType: hard @@ -1138,31 +1138,31 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/region-config-resolver@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/region-config-resolver@npm:3.489.0" +"@aws-sdk/region-config-resolver@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/types": ^2.8.0 - "@smithy/util-config-provider": ^2.1.0 - "@smithy/util-middleware": ^2.0.9 + "@aws-sdk/types": 3.495.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/types": ^2.9.0 + "@smithy/util-config-provider": ^2.2.0 + "@smithy/util-middleware": ^2.1.0 tslib: ^2.5.0 - checksum: 2352d0b3409e6d5225fd3f6f5da81164fcb93bb528579eacefea75ef8760f8626434e377eb3c7785046ce996732209f300de70958905124acbd1eb45a192e24b + checksum: f0f723dbd46761246dd771d975cb60c60afcbb10a94138183b7b00cad633ce92fdd7f2ee9ae60fcfc369d4aadd653d56562f5a14652dc8974816fbaf2c924182 languageName: node linkType: hard -"@aws-sdk/signature-v4-multi-region@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/signature-v4-multi-region@npm:3.489.0" +"@aws-sdk/signature-v4-multi-region@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.495.0" dependencies: - "@aws-sdk/middleware-sdk-s3": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@smithy/protocol-http": ^3.0.12 - "@smithy/signature-v4": ^2.0.0 - "@smithy/types": ^2.8.0 + "@aws-sdk/middleware-sdk-s3": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/signature-v4": ^2.1.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 613ab4f64682844dd9a6c6675f7db218185d3415a40b255e1346a0217576bad431156324739d148542421c67036462476b95ac801ea8c7f24f5abac96514ee23 + checksum: 93559456f5d4cae2fde06f49c41275d411bc9c4625cb73b6fc88f165c960d7a9a5e1432ae95ad6243430e6c0d07b6710e94aaf0ca39c7514e7c9f0240a466507 languageName: node linkType: hard @@ -1182,48 +1182,48 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/token-providers@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/token-providers@npm:3.489.0" +"@aws-sdk/token-providers@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/token-providers@npm:3.495.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/middleware-host-header": 3.489.0 - "@aws-sdk/middleware-logger": 3.489.0 - "@aws-sdk/middleware-recursion-detection": 3.489.0 - "@aws-sdk/middleware-user-agent": 3.489.0 - "@aws-sdk/region-config-resolver": 3.489.0 - "@aws-sdk/types": 3.489.0 - "@aws-sdk/util-endpoints": 3.489.0 - "@aws-sdk/util-user-agent-browser": 3.489.0 - "@aws-sdk/util-user-agent-node": 3.489.0 - "@smithy/config-resolver": ^2.0.23 - "@smithy/fetch-http-handler": ^2.3.2 - "@smithy/hash-node": ^2.0.18 - "@smithy/invalid-dependency": ^2.0.16 - "@smithy/middleware-content-length": ^2.0.18 - "@smithy/middleware-endpoint": ^2.3.0 - "@smithy/middleware-retry": ^2.0.26 - "@smithy/middleware-serde": ^2.0.16 - "@smithy/middleware-stack": ^2.0.10 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/node-http-handler": ^2.2.2 - "@smithy/property-provider": ^2.0.0 - "@smithy/protocol-http": ^3.0.12 - "@smithy/shared-ini-file-loader": ^2.0.6 - "@smithy/smithy-client": ^2.2.1 - "@smithy/types": ^2.8.0 - "@smithy/url-parser": ^2.0.16 - "@smithy/util-base64": ^2.0.1 - "@smithy/util-body-length-browser": ^2.0.1 - "@smithy/util-body-length-node": ^2.1.0 - "@smithy/util-defaults-mode-browser": ^2.0.24 - "@smithy/util-defaults-mode-node": ^2.0.32 - "@smithy/util-endpoints": ^1.0.8 - "@smithy/util-retry": ^2.0.9 - "@smithy/util-utf8": ^2.0.2 + "@aws-sdk/middleware-host-header": 3.495.0 + "@aws-sdk/middleware-logger": 3.495.0 + "@aws-sdk/middleware-recursion-detection": 3.495.0 + "@aws-sdk/middleware-user-agent": 3.495.0 + "@aws-sdk/region-config-resolver": 3.495.0 + "@aws-sdk/types": 3.495.0 + "@aws-sdk/util-endpoints": 3.495.0 + "@aws-sdk/util-user-agent-browser": 3.495.0 + "@aws-sdk/util-user-agent-node": 3.495.0 + "@smithy/config-resolver": ^2.1.0 + "@smithy/fetch-http-handler": ^2.4.0 + "@smithy/hash-node": ^2.1.0 + "@smithy/invalid-dependency": ^2.1.0 + "@smithy/middleware-content-length": ^2.1.0 + "@smithy/middleware-endpoint": ^2.4.0 + "@smithy/middleware-retry": ^2.1.0 + "@smithy/middleware-serde": ^2.1.0 + "@smithy/middleware-stack": ^2.1.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/node-http-handler": ^2.3.0 + "@smithy/property-provider": ^2.1.0 + "@smithy/protocol-http": ^3.1.0 + "@smithy/shared-ini-file-loader": ^2.3.0 + "@smithy/smithy-client": ^2.3.0 + "@smithy/types": ^2.9.0 + "@smithy/url-parser": ^2.1.0 + "@smithy/util-base64": ^2.1.0 + "@smithy/util-body-length-browser": ^2.1.0 + "@smithy/util-body-length-node": ^2.2.0 + "@smithy/util-defaults-mode-browser": ^2.1.0 + "@smithy/util-defaults-mode-node": ^2.1.0 + "@smithy/util-endpoints": ^1.1.0 + "@smithy/util-retry": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: cf2e14a09ead031e9ac3426fd0e5bc71656f1ce9ba470c860af26d8935dce65b28365973388175f982dd2d8fb6c470520dee426045b26174663a5adc6ac5928c + checksum: 76b8dacaf9d0d9c608866d10bb8d0d42070e88872688f9dae3cd2cce2cd573bb6937ffd4e4ef3ca94763ac4f549faaf6f7d1e1bea714d7ec37b5a7ca533f5599 languageName: node linkType: hard @@ -1237,13 +1237,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:3.489.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": - version: 3.489.0 - resolution: "@aws-sdk/types@npm:3.489.0" +"@aws-sdk/types@npm:3.495.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": + version: 3.495.0 + resolution: "@aws-sdk/types@npm:3.495.0" dependencies: - "@smithy/types": ^2.8.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: e4692f04daee278e4fc7faeadb8fee077aee5b1210a6c237c203b4688b714d1efc96c9f4574b71e264f71d8f4aad06b5728bcba13d12242c92f93dec81e3d3da + checksum: 786d7d860cd8c22a631d48e5a2a0570b941f43927d3bee1da36d4749f71fbdc2e7908f15f73582d0572c74f9f0e6b411a33f94facf27aec93d9f2920b9a662f4 languageName: node linkType: hard @@ -1258,12 +1258,12 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-arn-parser@npm:3.465.0, @aws-sdk/util-arn-parser@npm:^3.310.0": - version: 3.465.0 - resolution: "@aws-sdk/util-arn-parser@npm:3.465.0" +"@aws-sdk/util-arn-parser@npm:3.495.0, @aws-sdk/util-arn-parser@npm:^3.310.0": + version: 3.495.0 + resolution: "@aws-sdk/util-arn-parser@npm:3.495.0" dependencies: tslib: ^2.5.0 - checksum: ce2dd638e9b8ef3260ce1c1ae299a4e44cbaa28a07cda9f1033b763cea8b1d901b7a963338e8a172af17074d06811f09605f3f903318c4bd2bbf102e92d02546 + checksum: 130f1b1c0d2b9917782049693aa4ab6aec98858d6e2b46c14a3a6c4979e65073f731aec96aa0e1c04e927d0b32ad2d4a6a701e2a6d5d416c6ea35e670e4eb987 languageName: node linkType: hard @@ -1277,15 +1277,15 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-endpoints@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/util-endpoints@npm:3.489.0" +"@aws-sdk/util-endpoints@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/util-endpoints@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/types": ^2.8.0 - "@smithy/util-endpoints": ^1.0.8 + "@aws-sdk/types": 3.495.0 + "@smithy/types": ^2.9.0 + "@smithy/util-endpoints": ^1.1.0 tslib: ^2.5.0 - checksum: 5c225b12ce5c18ecd64079d2e4133374244728ac7c8055efb07ca5b274266cb0e2d6c88ce5ae4385d45d67b2999fcd5bbe5e8dd4299792542683682ac05950e8 + checksum: a479feeea6b136c9a07f885373e859a37f19b4d55cf6f9ecd89017c13349f55d239aa5a083465b1d945ff6bf13809efd27133340bdecaef875e72bd60d534c76 languageName: node linkType: hard @@ -1337,32 +1337,32 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-browser@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.489.0" +"@aws-sdk/util-user-agent-browser@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/types": ^2.9.0 bowser: ^2.11.0 tslib: ^2.5.0 - checksum: b24009655bd5a7755575d6ed5c955d6fcfa3a70248e1a9c9d4a58cc7ed4bb25936a276917a0ab60b6e11e7ed915d5dcfdd5e9112e373bd23b24d24963324e516 + checksum: 47071d5d514e08ef2818e42b437798238df771bff320256eef4589a24dae3f84ac064897c941919e1b571aaf95345282a7e8e43729f787526b70e80dfba8dead languageName: node linkType: hard -"@aws-sdk/util-user-agent-node@npm:3.489.0": - version: 3.489.0 - resolution: "@aws-sdk/util-user-agent-node@npm:3.489.0" +"@aws-sdk/util-user-agent-node@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.495.0" dependencies: - "@aws-sdk/types": 3.489.0 - "@smithy/node-config-provider": ^2.1.9 - "@smithy/types": ^2.8.0 + "@aws-sdk/types": 3.495.0 + "@smithy/node-config-provider": ^2.2.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 peerDependencies: aws-crt: ">=1.0.0" peerDependenciesMeta: aws-crt: optional: true - checksum: 755845ce1cebdc78d3bb2bab058cf8e966658373daa7c62ae808fc0fc733248ed019042b1eed4ad3274ae08f23506cc000e1b0d41b6f01fd29cccad4275b3f8e + checksum: e4c188c91b78b33d8da77984f3513a61ece3454d02d16605ec985b8481d309d12ad7544d2233d1396aaffd0758b4d0d1c4c143b9edd68d66e2681a4fd32eac34 languageName: node linkType: hard @@ -1385,13 +1385,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/xml-builder@npm:3.485.0": - version: 3.485.0 - resolution: "@aws-sdk/xml-builder@npm:3.485.0" +"@aws-sdk/xml-builder@npm:3.495.0": + version: 3.495.0 + resolution: "@aws-sdk/xml-builder@npm:3.495.0" dependencies: - "@smithy/types": ^2.8.0 + "@smithy/types": ^2.9.0 tslib: ^2.5.0 - checksum: 97eacc7fff1161876cb672051905156d6aec8116f76b35d5f2ca87b676b5b270fc6de0b9bed53792272a7712d835077ac64b4135fed7ea81c3e4cbf070f1be58 + checksum: f2c695268c887e1f0e39991867ceca861f3242a0c12689ccfe582bce4f3543cf241a7ea4873a4a1c8b3637a5592a29c8f9266040f375a3eaaa9aebce6d697ecd languageName: node linkType: hard @@ -15347,7 +15347,7 @@ __metadata: languageName: node linkType: hard -"@smithy/abort-controller@npm:^2.0.1, @smithy/abort-controller@npm:^2.1.0": +"@smithy/abort-controller@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/abort-controller@npm:2.1.0" dependencies: @@ -15376,7 +15376,7 @@ __metadata: languageName: node linkType: hard -"@smithy/config-resolver@npm:^2.0.23, @smithy/config-resolver@npm:^2.1.0": +"@smithy/config-resolver@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/config-resolver@npm:2.1.0" dependencies: @@ -15389,7 +15389,7 @@ __metadata: languageName: node linkType: hard -"@smithy/core@npm:^1.2.2": +"@smithy/core@npm:^1.3.0": version: 1.3.0 resolution: "@smithy/core@npm:1.3.0" dependencies: @@ -15405,7 +15405,7 @@ __metadata: languageName: node linkType: hard -"@smithy/credential-provider-imds@npm:^2.0.0, @smithy/credential-provider-imds@npm:^2.2.0": +"@smithy/credential-provider-imds@npm:^2.2.0": version: 2.2.0 resolution: "@smithy/credential-provider-imds@npm:2.2.0" dependencies: @@ -15418,7 +15418,7 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-codec@npm:^2.0.1, @smithy/eventstream-codec@npm:^2.1.0": +"@smithy/eventstream-codec@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/eventstream-codec@npm:2.1.0" dependencies: @@ -15430,7 +15430,7 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-browser@npm:^2.0.16": +"@smithy/eventstream-serde-browser@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/eventstream-serde-browser@npm:2.1.0" dependencies: @@ -15441,7 +15441,7 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-config-resolver@npm:^2.0.16": +"@smithy/eventstream-serde-config-resolver@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/eventstream-serde-config-resolver@npm:2.1.0" dependencies: @@ -15451,7 +15451,7 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-node@npm:^2.0.16": +"@smithy/eventstream-serde-node@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/eventstream-serde-node@npm:2.1.0" dependencies: @@ -15473,7 +15473,7 @@ __metadata: languageName: node linkType: hard -"@smithy/fetch-http-handler@npm:^2.3.2, @smithy/fetch-http-handler@npm:^2.4.0": +"@smithy/fetch-http-handler@npm:^2.4.0": version: 2.4.0 resolution: "@smithy/fetch-http-handler@npm:2.4.0" dependencies: @@ -15486,7 +15486,7 @@ __metadata: languageName: node linkType: hard -"@smithy/hash-blob-browser@npm:^2.0.17": +"@smithy/hash-blob-browser@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/hash-blob-browser@npm:2.1.0" dependencies: @@ -15498,7 +15498,7 @@ __metadata: languageName: node linkType: hard -"@smithy/hash-node@npm:^2.0.18": +"@smithy/hash-node@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/hash-node@npm:2.1.0" dependencies: @@ -15510,7 +15510,7 @@ __metadata: languageName: node linkType: hard -"@smithy/hash-stream-node@npm:^2.0.18": +"@smithy/hash-stream-node@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/hash-stream-node@npm:2.1.0" dependencies: @@ -15521,7 +15521,7 @@ __metadata: languageName: node linkType: hard -"@smithy/invalid-dependency@npm:^2.0.16": +"@smithy/invalid-dependency@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/invalid-dependency@npm:2.1.0" dependencies: @@ -15531,7 +15531,7 @@ __metadata: languageName: node linkType: hard -"@smithy/is-array-buffer@npm:^2.0.0, @smithy/is-array-buffer@npm:^2.1.0": +"@smithy/is-array-buffer@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/is-array-buffer@npm:2.1.0" dependencies: @@ -15540,7 +15540,7 @@ __metadata: languageName: node linkType: hard -"@smithy/md5-js@npm:^2.0.18": +"@smithy/md5-js@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/md5-js@npm:2.1.0" dependencies: @@ -15551,7 +15551,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-content-length@npm:^2.0.18": +"@smithy/middleware-content-length@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/middleware-content-length@npm:2.1.0" dependencies: @@ -15562,7 +15562,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-endpoint@npm:^2.3.0, @smithy/middleware-endpoint@npm:^2.4.0": +"@smithy/middleware-endpoint@npm:^2.4.0": version: 2.4.0 resolution: "@smithy/middleware-endpoint@npm:2.4.0" dependencies: @@ -15577,7 +15577,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-retry@npm:^2.0.26, @smithy/middleware-retry@npm:^2.1.0": +"@smithy/middleware-retry@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/middleware-retry@npm:2.1.0" dependencies: @@ -15594,7 +15594,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-serde@npm:^2.0.16, @smithy/middleware-serde@npm:^2.1.0": +"@smithy/middleware-serde@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/middleware-serde@npm:2.1.0" dependencies: @@ -15604,7 +15604,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-stack@npm:^2.0.10, @smithy/middleware-stack@npm:^2.1.0": +"@smithy/middleware-stack@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/middleware-stack@npm:2.1.0" dependencies: @@ -15614,7 +15614,7 @@ __metadata: languageName: node linkType: hard -"@smithy/node-config-provider@npm:^2.1.9, @smithy/node-config-provider@npm:^2.2.0": +"@smithy/node-config-provider@npm:^2.2.0": version: 2.2.0 resolution: "@smithy/node-config-provider@npm:2.2.0" dependencies: @@ -15626,7 +15626,7 @@ __metadata: languageName: node linkType: hard -"@smithy/node-http-handler@npm:^2.1.7, @smithy/node-http-handler@npm:^2.2.2, @smithy/node-http-handler@npm:^2.3.0": +"@smithy/node-http-handler@npm:^2.1.7, @smithy/node-http-handler@npm:^2.3.0": version: 2.3.0 resolution: "@smithy/node-http-handler@npm:2.3.0" dependencies: @@ -15639,7 +15639,7 @@ __metadata: languageName: node linkType: hard -"@smithy/property-provider@npm:^2.0.0, @smithy/property-provider@npm:^2.1.0": +"@smithy/property-provider@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/property-provider@npm:2.1.0" dependencies: @@ -15649,7 +15649,7 @@ __metadata: languageName: node linkType: hard -"@smithy/protocol-http@npm:^3.0.12, @smithy/protocol-http@npm:^3.1.0": +"@smithy/protocol-http@npm:^3.1.0": version: 3.1.0 resolution: "@smithy/protocol-http@npm:3.1.0" dependencies: @@ -15689,7 +15689,7 @@ __metadata: languageName: node linkType: hard -"@smithy/shared-ini-file-loader@npm:^2.0.6, @smithy/shared-ini-file-loader@npm:^2.3.0": +"@smithy/shared-ini-file-loader@npm:^2.3.0": version: 2.3.0 resolution: "@smithy/shared-ini-file-loader@npm:2.3.0" dependencies: @@ -15699,23 +15699,23 @@ __metadata: languageName: node linkType: hard -"@smithy/signature-v4@npm:^2.0.0": - version: 2.0.1 - resolution: "@smithy/signature-v4@npm:2.0.1" +"@smithy/signature-v4@npm:^2.1.0": + version: 2.1.0 + resolution: "@smithy/signature-v4@npm:2.1.0" dependencies: - "@smithy/eventstream-codec": ^2.0.1 - "@smithy/is-array-buffer": ^2.0.0 - "@smithy/types": ^2.0.2 - "@smithy/util-hex-encoding": ^2.0.0 - "@smithy/util-middleware": ^2.0.0 - "@smithy/util-uri-escape": ^2.0.0 - "@smithy/util-utf8": ^2.0.0 + "@smithy/eventstream-codec": ^2.1.0 + "@smithy/is-array-buffer": ^2.1.0 + "@smithy/types": ^2.9.0 + "@smithy/util-hex-encoding": ^2.1.0 + "@smithy/util-middleware": ^2.1.0 + "@smithy/util-uri-escape": ^2.1.0 + "@smithy/util-utf8": ^2.1.0 tslib: ^2.5.0 - checksum: 2c4bc499251dfbdbea0359fc5196002ac805df7f6f87d7cba36164d8fcd16a749a3c1a52259569134628511dc496724d5e76744c1c39fee3a3f42c5fbfe3749b + checksum: 3e2fa005930f8228b9480087f4eeacbf36200e268c760890182e21ae4035b5e02e9d10bc6d9f9ae0bc257b02cadadb522afdf1f3bddf3c2d61c3e3796f90e8ca languageName: node linkType: hard -"@smithy/smithy-client@npm:^2.2.1, @smithy/smithy-client@npm:^2.3.0": +"@smithy/smithy-client@npm:^2.3.0": version: 2.3.0 resolution: "@smithy/smithy-client@npm:2.3.0" dependencies: @@ -15738,7 +15738,7 @@ __metadata: languageName: node linkType: hard -"@smithy/types@npm:^2.0.2, @smithy/types@npm:^2.8.0, @smithy/types@npm:^2.9.0": +"@smithy/types@npm:^2.9.0": version: 2.9.0 resolution: "@smithy/types@npm:2.9.0" dependencies: @@ -15747,7 +15747,7 @@ __metadata: languageName: node linkType: hard -"@smithy/url-parser@npm:^2.0.16, @smithy/url-parser@npm:^2.1.0": +"@smithy/url-parser@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/url-parser@npm:2.1.0" dependencies: @@ -15758,7 +15758,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-base64@npm:^2.0.1, @smithy/util-base64@npm:^2.1.0": +"@smithy/util-base64@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-base64@npm:2.1.0" dependencies: @@ -15768,7 +15768,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-body-length-browser@npm:^2.0.1": +"@smithy/util-body-length-browser@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-body-length-browser@npm:2.1.0" dependencies: @@ -15777,12 +15777,12 @@ __metadata: languageName: node linkType: hard -"@smithy/util-body-length-node@npm:^2.1.0": - version: 2.1.0 - resolution: "@smithy/util-body-length-node@npm:2.1.0" +"@smithy/util-body-length-node@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-body-length-node@npm:2.2.0" dependencies: tslib: ^2.5.0 - checksum: e4635251898f12e1825f2848e0b7cc9d01ec6635b3f1f71b790734bb702b88e795f6c539d42d95472dad00e50e9ff13fcf396791092b131e5834069cb8f52ed0 + checksum: a2ada7daeb31147675b66f0a95cd24ed10ee800211ddde34b1bbbd0a2bfbfdc82efbc8fe2c9bf4e18a67e7112aaf432f381a32e19be06735c8f4e0c3eec1a4a5 languageName: node linkType: hard @@ -15796,7 +15796,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-config-provider@npm:^2.1.0, @smithy/util-config-provider@npm:^2.2.0": +"@smithy/util-config-provider@npm:^2.2.0": version: 2.2.0 resolution: "@smithy/util-config-provider@npm:2.2.0" dependencies: @@ -15805,7 +15805,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-browser@npm:^2.0.24": +"@smithy/util-defaults-mode-browser@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-defaults-mode-browser@npm:2.1.0" dependencies: @@ -15818,7 +15818,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-node@npm:^2.0.32": +"@smithy/util-defaults-mode-node@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-defaults-mode-node@npm:2.1.0" dependencies: @@ -15833,7 +15833,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-endpoints@npm:^1.0.8": +"@smithy/util-endpoints@npm:^1.1.0": version: 1.1.0 resolution: "@smithy/util-endpoints@npm:1.1.0" dependencies: @@ -15844,7 +15844,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-hex-encoding@npm:^2.0.0, @smithy/util-hex-encoding@npm:^2.1.0": +"@smithy/util-hex-encoding@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-hex-encoding@npm:2.1.0" dependencies: @@ -15853,7 +15853,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-middleware@npm:^2.0.0, @smithy/util-middleware@npm:^2.0.9, @smithy/util-middleware@npm:^2.1.0": +"@smithy/util-middleware@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-middleware@npm:2.1.0" dependencies: @@ -15863,7 +15863,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-retry@npm:^2.0.9, @smithy/util-retry@npm:^2.1.0": +"@smithy/util-retry@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-retry@npm:2.1.0" dependencies: @@ -15874,7 +15874,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-stream@npm:^2.0.24, @smithy/util-stream@npm:^2.1.0": +"@smithy/util-stream@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-stream@npm:2.1.0" dependencies: @@ -15890,7 +15890,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-uri-escape@npm:^2.0.0, @smithy/util-uri-escape@npm:^2.1.0": +"@smithy/util-uri-escape@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-uri-escape@npm:2.1.0" dependencies: @@ -15899,7 +15899,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-utf8@npm:^2.0.0, @smithy/util-utf8@npm:^2.0.2, @smithy/util-utf8@npm:^2.1.0": +"@smithy/util-utf8@npm:^2.0.0, @smithy/util-utf8@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-utf8@npm:2.1.0" dependencies: @@ -15909,7 +15909,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-waiter@npm:^2.0.16": +"@smithy/util-waiter@npm:^2.1.0": version: 2.1.0 resolution: "@smithy/util-waiter@npm:2.1.0" dependencies: From 0788a2dda8273578a1d6c416ea22dcd391e08fe6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 21:29:24 +0000 Subject: [PATCH 251/283] fix(deps): update dependency @rollup/plugin-json to v6.1.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/yarn.lock b/yarn.lock index 39042b78e8..11bbe31272 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15048,16 +15048,16 @@ __metadata: linkType: hard "@rollup/plugin-json@npm:^6.0.0": - version: 6.0.1 - resolution: "@rollup/plugin-json@npm:6.0.1" + version: 6.1.0 + resolution: "@rollup/plugin-json@npm:6.1.0" dependencies: - "@rollup/pluginutils": ^5.0.1 + "@rollup/pluginutils": ^5.1.0 peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true - checksum: 86995e3ceec0205bd0b5ae3075f4592e0ab3e6e6327a5dcfc825b44113eaae5819d26d5403d29b177ac59299e0b08c641c8d030e0c72805b92805ededc9cac44 + checksum: cc018d20c80242a2b8b44fae61a968049cf31bb8406218187cc7cda35747616594e79452dd65722e7da6dd825b392e90d4599d43cd4461a02fefa2865945164e languageName: node linkType: hard @@ -15106,19 +15106,19 @@ __metadata: languageName: node linkType: hard -"@rollup/pluginutils@npm:^5.0.1": - version: 5.0.4 - resolution: "@rollup/pluginutils@npm:5.0.4" +"@rollup/pluginutils@npm:^5.0.1, @rollup/pluginutils@npm:^5.1.0": + version: 5.1.0 + resolution: "@rollup/pluginutils@npm:5.1.0" dependencies: "@types/estree": ^1.0.0 estree-walker: ^2.0.2 picomatch: ^2.3.1 peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true - checksum: 893d5805ac4121fc704926963a0ae4e79e9e2bc8d736c3b28499ab69a404cce5119ca3a4e0c3d3a81d62f1beb3966f35285c36935d94b061794f26e94fed4cd1 + checksum: 3cc5a6d91452a6eabbfd1ae79b4dd1f1e809d2eecda6e175deb784e75b0911f47e9ecce73f8dd315d6a8b3f362582c91d3c0f66908b6ced69345b3cbe28f8ce8 languageName: node linkType: hard From e6c2f88abcd6407fb15fb319e314efae03362a5c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 22:17:10 +0000 Subject: [PATCH 252/283] fix(deps): update dependency @stoplight/types to v14.1.1 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9c19a225b5..8a2b906b13 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16201,12 +16201,12 @@ __metadata: linkType: hard "@stoplight/types@npm:^14.0.0": - version: 14.0.0 - resolution: "@stoplight/types@npm:14.0.0" + version: 14.1.1 + resolution: "@stoplight/types@npm:14.1.1" dependencies: "@types/json-schema": ^7.0.4 utility-types: ^3.10.0 - checksum: 462fb6c718a2679927421ca1fffb5e31be2d150130e95a2771ffba04f68fc0e0f8ef3d4ae050e63fd4044bc4103e2ea82c98e1f5c7ff192a78914838eb250e5e + checksum: 1da2e683e88afe2f72c3b3af341537bc9bac153d224f65744ca60d44eade93609ce91172064ae27093e1ebfa7bcbf05fb232a1910d83b2aee5b1eed4bb726200 languageName: node linkType: hard From 8e2ea17b1cb20ce91c34d733ec6f34c40a495635 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 22:18:43 +0000 Subject: [PATCH 253/283] fix(deps): update dependency azure-devops-node-api to v12.3.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9c19a225b5..dcdd0ce70b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20926,12 +20926,12 @@ __metadata: linkType: hard "azure-devops-node-api@npm:^12.0.0": - version: 12.1.0 - resolution: "azure-devops-node-api@npm:12.1.0" + version: 12.3.0 + resolution: "azure-devops-node-api@npm:12.3.0" dependencies: tunnel: 0.0.6 typed-rest-client: ^1.8.4 - checksum: aa3c3f3eff89485a44ea31843749c5abf5ddfb0d2f059a3f5623d75d5eddbab5b839a5458c158e7941b9c8a2adfde2ecfea128ed076f730c309c869e8a318a78 + checksum: 4f76f4633f57b92267b9f841591ee2c9548bc51421d3d5b0072c854f6a3f3bc77b3a334863a22f1b903c620492a8be877ee16ff5af05e6d131b281a683a7f695 languageName: node linkType: hard From bcd277a311a06fd45bcd87a3cd730fc8998fd866 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 03:43:47 +0000 Subject: [PATCH 254/283] chore(deps): update dependency @openapitools/openapi-generator-cli to v2.8.1 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 52 ++++++++++------------------------------------------ 1 file changed, 10 insertions(+), 42 deletions(-) diff --git a/yarn.lock b/yarn.lock index e224a5129a..d42c31b56b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13966,8 +13966,8 @@ __metadata: linkType: hard "@openapitools/openapi-generator-cli@npm:^2.4.26, @openapitools/openapi-generator-cli@npm:^2.7.0": - version: 2.8.0 - resolution: "@openapitools/openapi-generator-cli@npm:2.8.0" + version: 2.8.1 + resolution: "@openapitools/openapi-generator-cli@npm:2.8.1" dependencies: "@nestjs/axios": 3.0.1 "@nestjs/common": 10.3.0 @@ -13981,14 +13981,14 @@ __metadata: console.table: 0.10.0 fs-extra: 10.1.0 glob: 7.2.3 - inquirer: 8.2.5 + inquirer: 8.2.6 lodash: 4.17.21 reflect-metadata: 0.1.13 - rxjs: 7.8.0 + rxjs: 7.8.1 tslib: 2.6.2 bin: openapi-generator-cli: main.js - checksum: 76a43d3087b2a4eb521814369ce99ade622fc146bb2414f52c01a7565f81fa94a6d42f2bf6889a4b25814744f0462613853a609d97c12a608c5717aed2e3898a + checksum: 5e0e5460ec8cf5f96338703820066265d187ce984f24cfcf6f1abe70049b38a8953f0835658f5915ec41304a98bd76cf17ec9fb50fa746701116be6502dca39e languageName: node linkType: hard @@ -29536,30 +29536,7 @@ __metadata: languageName: node linkType: hard -"inquirer@npm:8.2.5": - version: 8.2.5 - resolution: "inquirer@npm:8.2.5" - dependencies: - ansi-escapes: ^4.2.1 - chalk: ^4.1.1 - cli-cursor: ^3.1.0 - cli-width: ^3.0.0 - external-editor: ^3.0.3 - figures: ^3.0.0 - lodash: ^4.17.21 - mute-stream: 0.0.8 - ora: ^5.4.1 - run-async: ^2.4.0 - rxjs: ^7.5.5 - string-width: ^4.1.0 - strip-ansi: ^6.0.0 - through: ^2.3.6 - wrap-ansi: ^7.0.0 - checksum: f13ee4c444187786fb393609dedf6b30870115a57b603f2e6424f29a99abc13446fd45ee22461c33c9c40a92a60a8df62d0d6b25d74fc6676fa4cb211de55b55 - languageName: node - linkType: hard - -"inquirer@npm:^8.0.0, inquirer@npm:^8.2.0": +"inquirer@npm:8.2.6, inquirer@npm:^8.0.0, inquirer@npm:^8.2.0": version: 8.2.6 resolution: "inquirer@npm:8.2.6" dependencies: @@ -39930,12 +39907,12 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:7.8.0": - version: 7.8.0 - resolution: "rxjs@npm:7.8.0" +"rxjs@npm:7.8.1, rxjs@npm:^7.2.0, rxjs@npm:^7.5.5, rxjs@npm:^7.8.1": + version: 7.8.1 + resolution: "rxjs@npm:7.8.1" dependencies: tslib: ^2.1.0 - checksum: 61b4d4fd323c1043d8d6ceb91f24183b28bcf5def4f01ca111511d5c6b66755bc5578587fe714ef5d67cf4c9f2e26f4490d4e1d8cabf9bd5967687835e9866a2 + checksum: de4b53db1063e618ec2eca0f7965d9137cabe98cf6be9272efe6c86b47c17b987383df8574861bcced18ebd590764125a901d5506082be84a8b8e364bf05f119 languageName: node linkType: hard @@ -39948,15 +39925,6 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:^7.2.0, rxjs@npm:^7.5.5, rxjs@npm:^7.8.1": - version: 7.8.1 - resolution: "rxjs@npm:7.8.1" - dependencies: - tslib: ^2.1.0 - checksum: de4b53db1063e618ec2eca0f7965d9137cabe98cf6be9272efe6c86b47c17b987383df8574861bcced18ebd590764125a901d5506082be84a8b8e364bf05f119 - languageName: node - linkType: hard - "sade@npm:^1.7.3": version: 1.8.1 resolution: "sade@npm:1.8.1" From ec48be1dab9540e7e501bc587883597ab74560f8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 03:44:29 +0000 Subject: [PATCH 255/283] fix(deps): update dependency classnames to v2.5.1 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index e224a5129a..01f4f2ab04 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22242,9 +22242,9 @@ __metadata: linkType: hard "classnames@npm:*, classnames@npm:^2.2.5, classnames@npm:^2.2.6, classnames@npm:^2.3.1": - version: 2.3.3 - resolution: "classnames@npm:2.3.3" - checksum: 0cb4db9cc3b8d2363c81f857f85b30351605fe683c89d140939aed4e06895a9570be737494ef3907e7069e2b98ed25ba3960fbf087b33309a18707fc38565e95 + version: 2.5.1 + resolution: "classnames@npm:2.5.1" + checksum: da424a8a6f3a96a2e87d01a432ba19315503294ac7e025f9fece656db6b6a0f7b5003bb1fbb51cbb0d9624d964f1b9bb35a51c73af9b2434c7b292c42231c1e5 languageName: node linkType: hard From a4bdc80fd76fce2643875384b55ba163366c5fc0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 04:18:18 +0000 Subject: [PATCH 256/283] fix(deps): update dependency clsx to v2.1.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- microsite/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/microsite/yarn.lock b/microsite/yarn.lock index 5e976cce69..e9f027d3a7 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -4383,9 +4383,9 @@ __metadata: linkType: hard "clsx@npm:^2.0.0": - version: 2.0.0 - resolution: "clsx@npm:2.0.0" - checksum: a2cfb2351b254611acf92faa0daf15220f4cd648bdf96ce369d729813b85336993871a4bf6978ddea2b81b5a130478339c20d9d0b5c6fc287e5147f0c059276e + version: 2.1.0 + resolution: "clsx@npm:2.1.0" + checksum: 43fefc29b6b49c9476fbce4f8b1cc75c27b67747738e598e6651dd40d63692135dc60b18fa1c5b78a2a9ba8ae6fd2055a068924b94e20b42039bd53b78b98e1d languageName: node linkType: hard From 74803f1568f08623c0f84b4569118160d63dbfec Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 05:32:26 +0000 Subject: [PATCH 257/283] fix(deps): update dependency core-js to v3.35.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 0c40ea23ed..dd4ff651af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23234,9 +23234,9 @@ __metadata: linkType: hard "core-js@npm:^3.26.0, core-js@npm:^3.6.5": - version: 3.33.3 - resolution: "core-js@npm:3.33.3" - checksum: 070b9c696f5a9b22bab0208daf9fcdffbc3b4f4c89ed2be512b7d99d4be363accfbb26fa6eec7261055d89e8ea0a5bcfccad5923fe43f1f2eafca9f568cc5596 + version: 3.35.0 + resolution: "core-js@npm:3.35.0" + checksum: 25c224aca3df012b98f08f13ccbd8171ef5852acd33fd5e58e106d27f5f0c97de2fdbc520f0b4364d26253caf2deb3e5d265310f57d2a66ae6cc922850e649f0 languageName: node linkType: hard From c05175f515921051ec38580216c101a44e51bf8f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 05:33:02 +0000 Subject: [PATCH 258/283] fix(deps): update dependency css-loader to v6.9.1 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/yarn.lock b/yarn.lock index 0c40ea23ed..82a38f7ea0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23600,20 +23600,20 @@ __metadata: linkType: hard "css-loader@npm:^6.5.1": - version: 6.8.1 - resolution: "css-loader@npm:6.8.1" + version: 6.9.1 + resolution: "css-loader@npm:6.9.1" dependencies: icss-utils: ^5.1.0 - postcss: ^8.4.21 + postcss: ^8.4.33 postcss-modules-extract-imports: ^3.0.0 - postcss-modules-local-by-default: ^4.0.3 - postcss-modules-scope: ^3.0.0 + postcss-modules-local-by-default: ^4.0.4 + postcss-modules-scope: ^3.1.1 postcss-modules-values: ^4.0.0 postcss-value-parser: ^4.2.0 - semver: ^7.3.8 + semver: ^7.5.4 peerDependencies: webpack: ^5.0.0 - checksum: 7c1784247bdbe76dc5c55fb1ac84f1d4177a74c47259942c9cfdb7a8e6baef11967a0bc85ac285f26bd26d5059decb848af8154a03fdb4f4894f41212f45eef3 + checksum: b0c1776f9c46474219eb471eeb8f4c8986a7735dc8356e578a63303cf292a7c8cb868fa74bf94a1a174e948fcb6523c63fca081cac6bbf246be8275b3cc384f0 languageName: node linkType: hard @@ -37050,27 +37050,27 @@ __metadata: languageName: node linkType: hard -"postcss-modules-local-by-default@npm:^4.0.0, postcss-modules-local-by-default@npm:^4.0.3": - version: 4.0.3 - resolution: "postcss-modules-local-by-default@npm:4.0.3" +"postcss-modules-local-by-default@npm:^4.0.0, postcss-modules-local-by-default@npm:^4.0.4": + version: 4.0.4 + resolution: "postcss-modules-local-by-default@npm:4.0.4" dependencies: icss-utils: ^5.0.0 postcss-selector-parser: ^6.0.2 postcss-value-parser: ^4.1.0 peerDependencies: postcss: ^8.1.0 - checksum: 2f8083687f3d6067885f8863dd32dbbb4f779cfcc7e52c17abede9311d84faf6d3ed8760e7c54c6380281732ae1f78e5e56a28baf3c271b33f450a11c9e30485 + checksum: 578b955b0773147890caa88c30b10dfc849c5b1412a47ad51751890dba16fca9528c3ab00a19b186a8c2c150c2d08e2ce64d3d907800afee1f37c6d38252e365 languageName: node linkType: hard -"postcss-modules-scope@npm:^3.0.0": - version: 3.0.0 - resolution: "postcss-modules-scope@npm:3.0.0" +"postcss-modules-scope@npm:^3.0.0, postcss-modules-scope@npm:^3.1.1": + version: 3.1.1 + resolution: "postcss-modules-scope@npm:3.1.1" dependencies: postcss-selector-parser: ^6.0.4 peerDependencies: postcss: ^8.1.0 - checksum: 330b9398dbd44c992c92b0dc612c0626135e2cc840fee41841eb61247a6cfed95af2bd6f67ead9dd9d0bb41f5b0367129d93c6e434fa3e9c58ade391d9a5a138 + checksum: 9e9d23abb0babc7fa243be65704d72a5a9ceb2bded4dbaef96a88210d468b03c8c3158c197f4e22300c851f08c6fdddd6ebe65f44e4c34448b45b8a2e063a16d languageName: node linkType: hard @@ -37283,7 +37283,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.1.0, postcss@npm:^8.4.21, postcss@npm:^8.4.27": +"postcss@npm:^8.1.0, postcss@npm:^8.4.27, postcss@npm:^8.4.33": version: 8.4.33 resolution: "postcss@npm:8.4.33" dependencies: From 60528c59a497d2f2975aa897624f65e06f4ea555 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 06:22:41 +0000 Subject: [PATCH 259/283] fix(deps): update dependency elastic-builder to v2.24.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 651198d5d7..33ee0fc70f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25041,8 +25041,8 @@ __metadata: linkType: hard "elastic-builder@npm:^2.16.0": - version: 2.23.0 - resolution: "elastic-builder@npm:2.23.0" + version: 2.24.0 + resolution: "elastic-builder@npm:2.24.0" dependencies: lodash.has: ^4.5.2 lodash.hasin: ^4.5.2 @@ -25052,7 +25052,7 @@ __metadata: lodash.isobject: ^3.0.2 lodash.isstring: ^4.0.1 lodash.omit: ^4.5.0 - checksum: 6cd3d6fd3ea20adb2f48a21d3bd25fd89dd9f692feab95357356b8a814f5a36579c7a8326e818127fc5ec50774c1818c4f8e5d0aeea00cccd0aeda5563e17123 + checksum: 4bbfa66a179b78dbd90a0a3ee19cf7fc2105deca195c65d3047cf2ef2e6fa4925049038ed1f28d46a3ce96daa47f2cf8d924ea2e2fc0c585569a5a7acd09f2ed languageName: node linkType: hard From 6009879578b91f08b2fdf2dcbd62d3cab0cc772a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 07:09:54 +0000 Subject: [PATCH 260/283] fix(deps): update dependency graphiql to v3.1.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 33ee0fc70f..92d760c61f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -28409,7 +28409,7 @@ __metadata: languageName: node linkType: hard -"graphiql@npm:3.0.10, graphiql@npm:^3.0.6": +"graphiql@npm:3.0.10": version: 3.0.10 resolution: "graphiql@npm:3.0.10" dependencies: @@ -28425,6 +28425,22 @@ __metadata: languageName: node linkType: hard +"graphiql@npm:^3.0.6": + version: 3.1.0 + resolution: "graphiql@npm:3.1.0" + dependencies: + "@graphiql/react": ^0.20.2 + "@graphiql/toolkit": ^0.9.1 + graphql-language-service: ^5.2.0 + markdown-it: ^12.2.0 + peerDependencies: + graphql: ^15.5.0 || ^16.0.0 + react: ^16.8.0 || ^17 || ^18 + react-dom: ^16.8.0 || ^17 || ^18 + checksum: a8969ea299561fe627ba566fb72dd90eda31b195e9983af87c4079bf807f5b356d116ece133e46d5098d6809a88b8f3b64b04a9e95dfe34cd84eb8fd109e2b8a + languageName: node + linkType: hard + "graphlib@npm:^2.1.8": version: 2.1.8 resolution: "graphlib@npm:2.1.8" From 8ab9b2d95d5ac59f8e6ba7502f7ca8eeab8940a9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 07:10:26 +0000 Subject: [PATCH 261/283] fix(deps): update dependency html-webpack-plugin to v5.6.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 33ee0fc70f..7808d07f7f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -28990,8 +28990,8 @@ __metadata: linkType: hard "html-webpack-plugin@npm:^5.3.1": - version: 5.5.4 - resolution: "html-webpack-plugin@npm:5.5.4" + version: 5.6.0 + resolution: "html-webpack-plugin@npm:5.6.0" dependencies: "@types/html-minifier-terser": ^6.0.0 html-minifier-terser: ^6.0.2 @@ -28999,8 +28999,14 @@ __metadata: pretty-error: ^4.0.0 tapable: ^2.0.0 peerDependencies: + "@rspack/core": 0.x || 1.x webpack: ^5.20.0 - checksum: b49befb73d67a3716fd0e6f7776b108d2b0b7050fb8221f05cd114cbae13c03150a13b7cdf5e76170be040ce7936a1cf76f7a4bfd9ebe1552b72d7889a74c374 + peerDependenciesMeta: + "@rspack/core": + optional: true + webpack: + optional: true + checksum: 32a6e41da538e798fd0be476637d7611a5e8a98a3508f031996e9eb27804dcdc282cb01f847cf5d066f21b49cfb8e21627fcf977ffd0c9bea81cf80e5a65070d languageName: node linkType: hard From dd15d3df0cedafa483dab38761c7ce35ff9769cc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 08:11:11 +0000 Subject: [PATCH 262/283] fix(deps): update dependency knex to v3.1.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/yarn.lock b/yarn.lock index 25f67aaed4..e2f53b8bfc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -32141,8 +32141,8 @@ __metadata: linkType: hard "knex@npm:3, knex@npm:^3.0.0": - version: 3.0.1 - resolution: "knex@npm:3.0.1" + version: 3.1.0 + resolution: "knex@npm:3.1.0" dependencies: colorette: 2.0.19 commander: ^10.0.0 @@ -32153,7 +32153,7 @@ __metadata: getopts: 2.3.0 interpret: ^2.2.0 lodash: ^4.17.21 - pg-connection-string: 2.6.1 + pg-connection-string: 2.6.2 rechoir: ^0.8.0 resolve-from: ^5.0.0 tarn: ^3.0.2 @@ -32175,7 +32175,7 @@ __metadata: optional: true bin: knex: bin/cli.js - checksum: bcfc3f8da9a7e898a873d2a122856ac9355f5ee1c0ab39534d6cac9ea69388da2fe0fa607b20d65298e191a4377af72f8ff7f4430f8b8c4abc144010b7e9796c + checksum: 3905f8d27960975f7f57f3f488d1ef3ccf47784acc8eb627e8a28cbbe1f296c6879c8ef0cbd9e17e867be80117d305cd948545f3fbd4c74b24c90d2413bbc021 languageName: node linkType: hard @@ -36542,14 +36542,7 @@ __metadata: languageName: node linkType: hard -"pg-connection-string@npm:2.6.1": - version: 2.6.1 - resolution: "pg-connection-string@npm:2.6.1" - checksum: 882344a47e1ecf3a91383e0809bf2ac48facea97fcec0358d6e060e1cbcb8737acde419b4c86f05da4ce4a16634ee50fff1d2bb787d73b52ccbfde697243ad8a - languageName: node - linkType: hard - -"pg-connection-string@npm:^2.3.0, pg-connection-string@npm:^2.5.0, pg-connection-string@npm:^2.6.2": +"pg-connection-string@npm:2.6.2, pg-connection-string@npm:^2.3.0, pg-connection-string@npm:^2.5.0, pg-connection-string@npm:^2.6.2": version: 2.6.2 resolution: "pg-connection-string@npm:2.6.2" checksum: 22265882c3b6f2320785378d0760b051294a684989163d5a1cde4009e64e84448d7bf67d9a7b9e7f69440c3ee9e2212f9aa10dd17ad6773f6143c6020cebbcb5 From 029295cd940bf23b54267295ed038d915529f59c Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 17 Jan 2024 14:13:36 +0100 Subject: [PATCH 263/283] chore: remove the legacy exports from alpha Signed-off-by: blam --- packages/app/src/App.tsx | 76 +-- plugins/scaffolder-react/src/alpha.ts | 1 - .../src/legacy/extensions/index.tsx | 56 -- .../src/legacy/extensions/types.ts | 65 --- plugins/scaffolder-react/src/legacy/index.ts | 16 - plugins/scaffolder/dev/index.tsx | 25 +- plugins/scaffolder/src/components/index.ts | 2 - plugins/scaffolder/src/components/types.ts | 15 - plugins/scaffolder/src/deprecated.ts | 10 + .../FieldOverrides/DescriptionField.tsx | 22 - .../MultistepJsonForm/FieldOverrides/index.ts | 16 - .../MultistepJsonForm.test.tsx | 88 --- .../MultistepJsonForm/MultistepJsonForm.tsx | 225 -------- .../legacy/MultistepJsonForm/ReviewStep.tsx | 128 ----- .../src/legacy/MultistepJsonForm/index.ts | 16 - .../legacy/MultistepJsonForm/schema.test.ts | 535 ------------------ .../src/legacy/MultistepJsonForm/schema.ts | 129 ----- plugins/scaffolder/src/legacy/Router.tsx | 183 ------ .../legacy/ScaffolderPage/ScaffolderPage.tsx | 159 ------ .../ScaffolderPageContextMenu.test.tsx | 83 --- .../ScaffolderPageContextMenu.tsx | 129 ----- .../src/legacy/ScaffolderPage/index.ts | 16 - .../src/legacy/TaskPage/IconLink.test.tsx | 30 - .../src/legacy/TaskPage/TaskErrors.tsx | 39 -- .../src/legacy/TaskPage/TaskPage.tsx | 393 ------------- .../legacy/TaskPage/TaskPageLinks.test.tsx | 67 --- .../scaffolder/src/legacy/TaskPage/index.ts | 17 - .../src/legacy/TemplateCard/TemplateCard.tsx | 316 ----------- .../src/legacy/TemplateCard/index.ts | 17 - .../CustomFieldExplorer.tsx | 205 ------- .../TemplateEditorPage/TemplateEditor.tsx | 92 --- .../TemplateEditorPage/TemplateEditorForm.tsx | 261 --------- .../TemplateEditorPage/TemplateEditorPage.tsx | 105 ---- .../TemplateFormPreviewer.tsx | 221 -------- .../src/legacy/TemplateEditorPage/index.ts | 16 - .../legacy/TemplateList/TemplateList.test.tsx | 83 --- .../src/legacy/TemplateList/TemplateList.tsx | 114 ---- .../src/legacy/TemplateList/index.ts | 17 - .../legacy/TemplatePage/TemplatePage.test.tsx | 366 ------------ .../src/legacy/TemplatePage/TemplatePage.tsx | 187 ------ .../TemplatePage/createValidator.test.ts | 200 ------- .../legacy/TemplatePage/createValidator.ts | 103 ---- .../src/legacy/TemplatePage/index.ts | 17 - plugins/scaffolder/src/legacy/index.ts | 17 - .../DryRunResults/DryRunResultsView.tsx | 4 +- .../DryRunResults}/IconLink.tsx | 3 +- .../DryRunResults}/TaskPageLinks.tsx | 0 .../DryRunResults/TaskStatusStepper.tsx | 199 +++++++ plugins/scaffolder/src/plugin.tsx | 12 - 49 files changed, 236 insertions(+), 4860 deletions(-) delete mode 100644 plugins/scaffolder-react/src/legacy/extensions/index.tsx delete mode 100644 plugins/scaffolder-react/src/legacy/extensions/types.ts delete mode 100644 plugins/scaffolder-react/src/legacy/index.ts delete mode 100644 plugins/scaffolder/src/components/types.ts delete mode 100644 plugins/scaffolder/src/legacy/MultistepJsonForm/FieldOverrides/DescriptionField.tsx delete mode 100644 plugins/scaffolder/src/legacy/MultistepJsonForm/FieldOverrides/index.ts delete mode 100644 plugins/scaffolder/src/legacy/MultistepJsonForm/MultistepJsonForm.test.tsx delete mode 100644 plugins/scaffolder/src/legacy/MultistepJsonForm/MultistepJsonForm.tsx delete mode 100644 plugins/scaffolder/src/legacy/MultistepJsonForm/ReviewStep.tsx delete mode 100644 plugins/scaffolder/src/legacy/MultistepJsonForm/index.ts delete mode 100644 plugins/scaffolder/src/legacy/MultistepJsonForm/schema.test.ts delete mode 100644 plugins/scaffolder/src/legacy/MultistepJsonForm/schema.ts delete mode 100644 plugins/scaffolder/src/legacy/Router.tsx delete mode 100644 plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPage.tsx delete mode 100644 plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPageContextMenu.test.tsx delete mode 100644 plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPageContextMenu.tsx delete mode 100644 plugins/scaffolder/src/legacy/ScaffolderPage/index.ts delete mode 100644 plugins/scaffolder/src/legacy/TaskPage/IconLink.test.tsx delete mode 100644 plugins/scaffolder/src/legacy/TaskPage/TaskErrors.tsx delete mode 100644 plugins/scaffolder/src/legacy/TaskPage/TaskPage.tsx delete mode 100644 plugins/scaffolder/src/legacy/TaskPage/TaskPageLinks.test.tsx delete mode 100644 plugins/scaffolder/src/legacy/TaskPage/index.ts delete mode 100644 plugins/scaffolder/src/legacy/TemplateCard/TemplateCard.tsx delete mode 100644 plugins/scaffolder/src/legacy/TemplateCard/index.ts delete mode 100644 plugins/scaffolder/src/legacy/TemplateEditorPage/CustomFieldExplorer.tsx delete mode 100644 plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditor.tsx delete mode 100644 plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditorForm.tsx delete mode 100644 plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditorPage.tsx delete mode 100644 plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateFormPreviewer.tsx delete mode 100644 plugins/scaffolder/src/legacy/TemplateEditorPage/index.ts delete mode 100644 plugins/scaffolder/src/legacy/TemplateList/TemplateList.test.tsx delete mode 100644 plugins/scaffolder/src/legacy/TemplateList/TemplateList.tsx delete mode 100644 plugins/scaffolder/src/legacy/TemplateList/index.ts delete mode 100644 plugins/scaffolder/src/legacy/TemplatePage/TemplatePage.test.tsx delete mode 100644 plugins/scaffolder/src/legacy/TemplatePage/TemplatePage.tsx delete mode 100644 plugins/scaffolder/src/legacy/TemplatePage/createValidator.test.ts delete mode 100644 plugins/scaffolder/src/legacy/TemplatePage/createValidator.ts delete mode 100644 plugins/scaffolder/src/legacy/TemplatePage/index.ts delete mode 100644 plugins/scaffolder/src/legacy/index.ts rename plugins/scaffolder/src/{legacy/TaskPage => next/TemplateEditorPage/DryRunResults}/IconLink.tsx (97%) rename plugins/scaffolder/src/{legacy/TaskPage => next/TemplateEditorPage/DryRunResults}/TaskPageLinks.tsx (100%) create mode 100644 plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index c2296d01e7..d2dde95f68 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -31,7 +31,6 @@ import { AppRouter, ConfigReader, defaultConfigLoader, - FeatureFlagged, FlatRoutes, } from '@backstage/core-app-api'; import { @@ -64,7 +63,6 @@ import { GcpProjectsPage } from '@backstage/plugin-gcp-projects'; import { HomepageCompositionRoot, VisitListener } from '@backstage/plugin-home'; import { LighthousePage } from '@backstage/plugin-lighthouse'; import { NewRelicPage } from '@backstage/plugin-newrelic'; -import { LegacyScaffolderPage } from '@backstage/plugin-scaffolder/alpha'; import { ScaffolderPage, scaffolderPlugin } from '@backstage/plugin-scaffolder'; import { ScaffolderFieldExtensions, @@ -96,10 +94,7 @@ import { apis } from './apis'; import { entityPage } from './components/catalog/EntityPage'; import { homePage } from './components/home/HomePage'; import { Root } from './components/Root'; -import { - DelayingComponentFieldExtension, - LowerCaseValuePickerFieldExtension, -} from './components/scaffolder/customScaffolderExtensions'; +import { DelayingComponentFieldExtension } from './components/scaffolder/customScaffolderExtensions'; import { defaultPreviewTemplate } from './components/scaffolder/defaultPreviewTemplate'; import { searchPage } from './components/search/SearchPage'; import { providers } from './identityProviders'; @@ -236,53 +231,28 @@ const routes = ( - - - entity?.metadata?.tags?.includes('recommended') ?? false, - }, - ]} - /> - } - > - - - - - - - - - - - entity?.metadata?.tags?.includes('recommended') ?? false, - }, - ]} - /> - } - > - - - - - - - - + + entity?.metadata?.tags?.includes('recommended') ?? false, + }, + ]} + /> + } + > + + + + + + + } /> ( - options: LegacyFieldExtensionOptions, -): Extension> { - return { - expose() { - const FieldExtensionDataHolder: any = () => null; - - attachComponentData( - FieldExtensionDataHolder, - FIELD_EXTENSION_KEY, - options, - ); - - return FieldExtensionDataHolder; - }, - }; -} - -export type { - LegacyCustomFieldValidator, - LegacyFieldExtensionOptions, - LegacyFieldExtensionComponentProps, -}; diff --git a/plugins/scaffolder-react/src/legacy/extensions/types.ts b/plugins/scaffolder-react/src/legacy/extensions/types.ts deleted file mode 100644 index 54c38ad2cd..0000000000 --- a/plugins/scaffolder-react/src/legacy/extensions/types.ts +++ /dev/null @@ -1,65 +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 { ApiHolder } from '@backstage/core-plugin-api'; -import { FieldValidation } from '@rjsf/utils'; -import { - CustomFieldExtensionSchema, - ScaffolderRJSFFieldProps, -} from '@backstage/plugin-scaffolder-react'; - -/** - * Field validation type for Custom Field Extensions. - * - * @alpha - */ -export type LegacyCustomFieldValidator = ( - data: TFieldReturnValue, - field: FieldValidation, - context: { apiHolder: ApiHolder }, -) => void | Promise; - -/** - * Type for the Custom Field Extension with the - * name and components and validation function. - * - * @alpha - */ -export type LegacyFieldExtensionOptions< - TFieldReturnValue = unknown, - TInputProps = unknown, -> = { - name: string; - component: ( - props: LegacyFieldExtensionComponentProps, - ) => JSX.Element | null; - validation?: LegacyCustomFieldValidator; - schema?: CustomFieldExtensionSchema; -}; - -/** - * Type for field extensions and being able to type - * incoming props easier. - * - * @alpha - */ -export interface LegacyFieldExtensionComponentProps< - TFieldReturnValue, - TUiOptions = unknown, -> extends ScaffolderRJSFFieldProps { - uiSchema: ScaffolderRJSFFieldProps['uiSchema'] & { - 'ui:options'?: TUiOptions; - }; -} diff --git a/plugins/scaffolder-react/src/legacy/index.ts b/plugins/scaffolder-react/src/legacy/index.ts deleted file mode 100644 index c539a8ba60..0000000000 --- a/plugins/scaffolder-react/src/legacy/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export * from './extensions'; diff --git a/plugins/scaffolder/dev/index.tsx b/plugins/scaffolder/dev/index.tsx index b683345ff5..e4425b04bf 100644 --- a/plugins/scaffolder/dev/index.tsx +++ b/plugins/scaffolder/dev/index.tsx @@ -24,7 +24,7 @@ import { } from '@backstage/plugin-catalog-react'; import React from 'react'; import { scaffolderApiRef, ScaffolderClient } from '../src'; -import { ScaffolderPage, LegacyScaffolderPage } from '../src/plugin'; +import { ScaffolderPage } from '../src/plugin'; import { discoveryApiRef, fetchApiRef, @@ -68,11 +68,6 @@ createDevApp() title: 'Create', element: , }) - .addPage({ - path: '/legacy-create', - title: 'Create (next)', - element: , - }) .addPage({ path: '/create-groups', title: 'Groups', @@ -91,22 +86,4 @@ createDevApp() /> ), }) - .addPage({ - path: '/legacy-create-groups', - title: 'Groups (next)', - element: ( - e.metadata.tags?.includes('techdocs') || false, - title: 'Techdocs', - }, - { - filter: e => e.metadata.tags?.includes('react') || false, - title: 'React', - }, - ]} - /> - ), - }) .render(); diff --git a/plugins/scaffolder/src/components/index.ts b/plugins/scaffolder/src/components/index.ts index fd8c11e2da..552a75c99b 100644 --- a/plugins/scaffolder/src/components/index.ts +++ b/plugins/scaffolder/src/components/index.ts @@ -22,5 +22,3 @@ export type { RouterProps } from './Router'; export { OngoingTask as TaskPage } from './OngoingTask'; export type { ReviewStepProps } from '@backstage/plugin-scaffolder-react'; - -export type { TaskPageProps } from '../legacy/TaskPage'; diff --git a/plugins/scaffolder/src/components/types.ts b/plugins/scaffolder/src/components/types.ts deleted file mode 100644 index b1e99a84e6..0000000000 --- a/plugins/scaffolder/src/components/types.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2020 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. - */ diff --git a/plugins/scaffolder/src/deprecated.ts b/plugins/scaffolder/src/deprecated.ts index f08a83c594..ffe923058b 100644 --- a/plugins/scaffolder/src/deprecated.ts +++ b/plugins/scaffolder/src/deprecated.ts @@ -212,3 +212,13 @@ export type LayoutTemplate = LayoutTemplateTemp; * @deprecated use import from {@link @backstage/plugin-scaffolder-react#LayoutOptions} instead as this has now been moved. */ export type LayoutOptions = LayoutOptionsTemp; + +/** + * TaskPageProps for constructing a TaskPage + * @param loadingText - Optional loading text shown before a task begins executing. + * @public + * @deprecated - this is a useless type that is no longer used. + */ +export type TaskPageProps = { + loadingText?: string; +}; diff --git a/plugins/scaffolder/src/legacy/MultistepJsonForm/FieldOverrides/DescriptionField.tsx b/plugins/scaffolder/src/legacy/MultistepJsonForm/FieldOverrides/DescriptionField.tsx deleted file mode 100644 index eded38beee..0000000000 --- a/plugins/scaffolder/src/legacy/MultistepJsonForm/FieldOverrides/DescriptionField.tsx +++ /dev/null @@ -1,22 +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 React from 'react'; -import { MarkdownContent } from '@backstage/core-components'; -import { FieldProps } from '@rjsf/utils'; - -export const DescriptionField = ({ description }: FieldProps) => - description && ; diff --git a/plugins/scaffolder/src/legacy/MultistepJsonForm/FieldOverrides/index.ts b/plugins/scaffolder/src/legacy/MultistepJsonForm/FieldOverrides/index.ts deleted file mode 100644 index d6d0bf3499..0000000000 --- a/plugins/scaffolder/src/legacy/MultistepJsonForm/FieldOverrides/index.ts +++ /dev/null @@ -1,16 +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. - */ -export { DescriptionField } from './DescriptionField'; diff --git a/plugins/scaffolder/src/legacy/MultistepJsonForm/MultistepJsonForm.test.tsx b/plugins/scaffolder/src/legacy/MultistepJsonForm/MultistepJsonForm.test.tsx deleted file mode 100644 index 3f8e153b65..0000000000 --- a/plugins/scaffolder/src/legacy/MultistepJsonForm/MultistepJsonForm.test.tsx +++ /dev/null @@ -1,88 +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 { getReviewData, getUiSchemasFromSteps } from './ReviewStep'; - -describe('MultistepJsonForm', () => { - const formDataMock = { - password: 'password', - masked: 'Some info to mask', - open: 'Some open info', - hidden: 'Some info to hide', - 'other-open': 'Other open info', - }; - - const stepsMock = [ - { - title: 'The test template', - schema: { - title: 'The test template', - properties: { - password: { - title: 'Password', - type: 'string', - 'ui:widget': 'password', - }, - masked: { - title: 'Masked', - type: 'string', - 'ui:backstage': { - review: { - mask: '******', - }, - }, - }, - open: { - title: 'Open info', - type: 'string', - }, - }, - }, - }, - { - title: 'Other fields', - schema: { - title: 'Other fields', - properties: { - hidden: { - title: 'Hidden', - type: 'string', - 'ui:backstage': { - review: { - show: false, - }, - }, - }, - 'other-open': { - title: 'Other Open Info', - type: 'string', - }, - }, - }, - }, - ]; - - test('Fields are defined to be hidden or masked', () => { - const schemas = getUiSchemasFromSteps(stepsMock); - const reviewData = getReviewData(formDataMock, schemas); - - expect(reviewData.password).toBe('******'); - expect(reviewData.masked).toBe('******'); - expect(reviewData.open).toBe('Some open info'); - expect(reviewData.hidden).toBeUndefined(); - expect(reviewData['other-open']).toBe('Other open info'); - }); -}); diff --git a/plugins/scaffolder/src/legacy/MultistepJsonForm/MultistepJsonForm.tsx b/plugins/scaffolder/src/legacy/MultistepJsonForm/MultistepJsonForm.tsx deleted file mode 100644 index 68b25d97d2..0000000000 --- a/plugins/scaffolder/src/legacy/MultistepJsonForm/MultistepJsonForm.tsx +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2020 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 { - Button, - Step as StepUI, - StepContent, - StepLabel, - Stepper, - Typography, -} from '@material-ui/core'; -import { JsonObject } from '@backstage/types'; -import { - errorApiRef, - featureFlagsApiRef, - useAnalytics, - useRouteRefParams, - useApi, -} from '@backstage/core-plugin-api'; -import { FormProps, IChangeEvent, withTheme } from '@rjsf/core'; -import { Theme as MuiTheme } from '@rjsf/material-ui'; -import React, { ComponentType, useState } from 'react'; -import { transformSchemaToProps } from './schema'; -import cloneDeep from 'lodash/cloneDeep'; -import * as fieldOverrides from './FieldOverrides'; -import { ReviewStep } from './ReviewStep'; -import validator from '@rjsf/validator-ajv8'; -import { extractSchemaFromStep } from '@backstage/plugin-scaffolder-react/alpha'; -import { selectedTemplateRouteRef } from '../../routes'; -import { - LayoutOptions, - ReviewStepProps, -} from '@backstage/plugin-scaffolder-react'; - -const Form = withTheme(MuiTheme); - -type Step = { - schema: JsonObject; - title: string; -} & Partial, 'schema'>>; - -/** - * The props for a dynamic form of a scaffolder template. - */ -export type MultistepJsonFormProps = { - /** - * Steps for the form, each contains title and form schema - */ - steps: Step[]; - formData: Record; - onChange: (e: IChangeEvent) => void; - onReset: () => void; - onFinish?: () => Promise; - widgets?: FormProps['widgets']; - fields?: FormProps['fields']; - finishButtonLabel?: string; - layouts: LayoutOptions[]; - ReviewStepComponent?: ComponentType; -}; - -export function getSchemasFromSteps(steps: Step[]) { - return steps.map(({ schema }) => ({ - mergedSchema: schema, - ...extractSchemaFromStep(schema), - })); -} - -/** - * Creates the dynamic form for a scaffolder template. - */ -export const MultistepJsonForm = (props: MultistepJsonFormProps) => { - const { - formData, - onChange, - onReset, - onFinish, - fields, - widgets, - layouts, - ReviewStepComponent, - } = props; - const { templateName } = useRouteRefParams(selectedTemplateRouteRef); - const analytics = useAnalytics(); - const [activeStep, setActiveStep] = useState(0); - const [disableButtons, setDisableButtons] = useState(false); - const errorApi = useApi(errorApiRef); - const featureFlagApi = useApi(featureFlagsApiRef); - const featureFlagKey = 'backstage:featureFlag'; - const filterOutProperties = (step: Step): Step => { - const filteredStep = cloneDeep(step); - const removedPropertyKeys: Array = []; - if (filteredStep.schema.properties) { - filteredStep.schema.properties = Object.fromEntries( - Object.entries(filteredStep.schema.properties).filter( - ([key, value]) => { - if (value[featureFlagKey]) { - if (featureFlagApi.isActive(value[featureFlagKey])) { - return true; - } - removedPropertyKeys.push(key); - return false; - } - return true; - }, - ), - ); - - // remove the feature flag property key from required if they are not active - filteredStep.schema.required = Array.isArray(filteredStep.schema.required) - ? filteredStep.schema.required?.filter( - r => !removedPropertyKeys.includes(r as string), - ) - : filteredStep.schema.required; - } - return filteredStep; - }; - - const steps = props.steps - .filter(step => { - const featureFlag = step.schema[featureFlagKey]; - return ( - typeof featureFlag !== 'string' || featureFlagApi.isActive(featureFlag) - ); - }) - .map(filterOutProperties); - - const handleReset = () => { - setActiveStep(0); - onReset(); - }; - const handleNext = () => { - const stepNum = Math.min(activeStep + 1, steps.length); - setActiveStep(stepNum); - analytics.captureEvent('click', `Next Step (${stepNum})`); - }; - const handleBack = () => setActiveStep(Math.max(activeStep - 1, 0)); - const handleCreate = async () => { - if (!onFinish) { - return; - } - - setDisableButtons(true); - try { - await onFinish(); - analytics.captureEvent('create', formData.name || `new ${templateName}`); - } catch (err) { - errorApi.post(err); - } finally { - setDisableButtons(false); - } - }; - - const ReviewStepElement = ReviewStepComponent ?? ReviewStep; - - return ( - <> - - {steps.map(({ title, schema, ...formProps }, index) => { - return ( - - - - {title} - - - -
) => { - if (e.errors.length === 0) handleNext(); - }} - experimental_defaultFormStateBehavior={{ - allOf: 'populateDefaults', - }} - {...formProps} - {...transformSchemaToProps(schema, layouts)} - > - - -
-
-
- ); - })} -
- {activeStep === steps.length && ( - - )} - - ); -}; diff --git a/plugins/scaffolder/src/legacy/MultistepJsonForm/ReviewStep.tsx b/plugins/scaffolder/src/legacy/MultistepJsonForm/ReviewStep.tsx deleted file mode 100644 index c3b244e921..0000000000 --- a/plugins/scaffolder/src/legacy/MultistepJsonForm/ReviewStep.tsx +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2020 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 { Box, Button, Paper, Typography } from '@material-ui/core'; -import React from 'react'; -import { Content, StructuredMetadataTable } from '@backstage/core-components'; -import { UiSchema } from '@rjsf/utils'; -import { JsonObject } from '@backstage/types'; -import { ReviewStepProps } from '@backstage/plugin-scaffolder-react'; - -export function getReviewData( - formData: Record, - uiSchemas: UiSchema[], -) { - const reviewData: Record = {}; - const orderedReviewProperties = new Set( - uiSchemas.map(us => us.name).concat(Object.getOwnPropertyNames(formData)), - ); - - for (const key of orderedReviewProperties) { - const uiSchema = uiSchemas.find(us => us.name === key); - - if (!uiSchema) { - reviewData[key] = formData[key]; - continue; - } - - if (uiSchema['ui:widget'] === 'password') { - reviewData[key] = '******'; - continue; - } - - if (!uiSchema['ui:backstage'] || !uiSchema['ui:backstage'].review) { - reviewData[key] = formData[key]; - continue; - } - - const review = uiSchema['ui:backstage'].review as JsonObject; - if (review.mask) { - reviewData[key] = review.mask; - continue; - } - - if (!review.show) { - continue; - } - reviewData[key] = formData[key]; - } - - return reviewData; -} - -export function getUiSchemasFromSteps( - steps: { - schema: JsonObject; - }[], -): UiSchema[] { - const uiSchemas: Array = []; - steps.forEach(step => { - const schemaProps = step.schema.properties as JsonObject; - for (const key in schemaProps) { - if (schemaProps.hasOwnProperty(key)) { - const uiSchema = schemaProps[key] as UiSchema; - uiSchema.name = key; - uiSchemas.push(uiSchema); - } - } - }); - return uiSchemas; -} - -/** - * The component displaying the Last Step in scaffolder template form. - * Which represents the summary of the input provided by the end user. - */ -export const ReviewStep = (props: ReviewStepProps) => { - const { - disableButtons, - formData, - handleBack, - handleCreate, - handleReset, - steps, - } = props; - return ( - - - Review and create - ({ schema: mergedSchema })), - ), - )} - /> - - - - - - - ); -}; diff --git a/plugins/scaffolder/src/legacy/MultistepJsonForm/index.ts b/plugins/scaffolder/src/legacy/MultistepJsonForm/index.ts deleted file mode 100644 index b125e7c4c2..0000000000 --- a/plugins/scaffolder/src/legacy/MultistepJsonForm/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { MultistepJsonForm } from './MultistepJsonForm'; diff --git a/plugins/scaffolder/src/legacy/MultistepJsonForm/schema.test.ts b/plugins/scaffolder/src/legacy/MultistepJsonForm/schema.test.ts deleted file mode 100644 index af5bb7fac5..0000000000 --- a/plugins/scaffolder/src/legacy/MultistepJsonForm/schema.test.ts +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Copyright 2020 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 { transformSchemaToProps } from './schema'; - -describe('transformSchemaToProps', () => { - it('transforms deep schema', () => { - const inputSchema = { - type: 'object', - 'ui:welp': 'warp', - properties: { - field1: { - type: 'string', - 'ui:derp': 'herp', - }, - field2: { - type: 'object', - properties: { - fieldX: { - type: 'string', - 'ui:derp': 'xerp', - }, - }, - }, - }, - }; - const expectedSchema = { - type: 'object', - properties: { - field1: { - type: 'string', - }, - field2: { - type: 'object', - properties: { - fieldX: { - type: 'string', - }, - }, - }, - }, - }; - const expectedUiSchema = { - 'ui:welp': 'warp', - field1: { - 'ui:derp': 'herp', - }, - field2: { - fieldX: { - 'ui:derp': 'xerp', - }, - }, - }; - - expect(transformSchemaToProps(inputSchema)).toEqual({ - schema: expectedSchema, - uiSchema: expectedUiSchema, - }); - }); - - it('transforms schema with anyOf fields', () => { - const inputSchema = { - type: 'object', - anyOf: [ - { - properties: { - field3: { - type: 'string', - default: 'Value 1', - 'ui:readonly': true, - }, - }, - }, - { - properties: { - field3: { - type: 'string', - default: 'Value 2', - 'ui:readonly': true, - }, - }, - }, - ], - oneOf: [ - { - properties: { - field4: { - type: 'string', - default: 'Value 1', - 'ui:readonly': true, - }, - }, - }, - ], - allOf: [ - { - properties: { - field5: { - type: 'string', - default: 'Value 1', - 'ui:readonly': true, - }, - }, - }, - ], - properties: { - field1: { - type: 'object', - anyOf: [ - { - properties: { - field3: { - type: 'string', - default: 'Value 1', - 'ui:readonly': true, - }, - }, - }, - { - properties: { - field3: { - type: 'string', - default: 'Value 2', - 'ui:readonly': true, - }, - }, - }, - ], - oneOf: [ - { - properties: { - field4: { - type: 'string', - default: 'Value 1', - 'ui:readonly': true, - }, - }, - }, - ], - allOf: [ - { - properties: { - field5: { - type: 'string', - default: 'Value 1', - 'ui:readonly': true, - }, - }, - }, - ], - }, - field2: { - type: 'string', - 'ui:derp': 'xerp', - }, - }, - }; - const expectedSchema = { - type: 'object', - anyOf: [ - { - properties: { - field3: { - type: 'string', - default: 'Value 1', - }, - }, - }, - { - properties: { - field3: { - type: 'string', - default: 'Value 2', - }, - }, - }, - ], - oneOf: [ - { - properties: { - field4: { - type: 'string', - default: 'Value 1', - }, - }, - }, - ], - allOf: [ - { - properties: { - field5: { - type: 'string', - default: 'Value 1', - }, - }, - }, - ], - properties: { - field1: { - type: 'object', - anyOf: [ - { - properties: { - field3: { - type: 'string', - default: 'Value 1', - }, - }, - }, - { - properties: { - field3: { - type: 'string', - default: 'Value 2', - }, - }, - }, - ], - oneOf: [ - { - properties: { - field4: { - type: 'string', - default: 'Value 1', - }, - }, - }, - ], - allOf: [ - { - properties: { - field5: { - type: 'string', - default: 'Value 1', - }, - }, - }, - ], - }, - field2: { - type: 'string', - }, - }, - }; - const expectedUiSchema = { - field3: { - 'ui:readonly': true, - }, - field4: { - 'ui:readonly': true, - }, - field5: { - 'ui:readonly': true, - }, - field1: { - field3: { - 'ui:readonly': true, - }, - field4: { - 'ui:readonly': true, - }, - field5: { - 'ui:readonly': true, - }, - }, - field2: { - 'ui:derp': 'xerp', - }, - }; - - expect(transformSchemaToProps(inputSchema)).toEqual({ - schema: expectedSchema, - uiSchema: expectedUiSchema, - }); - }); - - it('transforms schema with dependencies', () => { - const inputSchema = { - type: 'object', - properties: { - name: { - type: 'string', - }, - credit_card: { - type: 'number', - }, - }, - required: ['name'], - dependencies: { - credit_card: { - properties: { - billing_address: { - type: 'string', - 'ui:widget': 'textarea', - }, - }, - required: ['billing_address'], - }, - }, - }; - const expectedSchema = { - type: 'object', - properties: { - name: { - type: 'string', - }, - credit_card: { - type: 'number', - }, - }, - required: ['name'], - dependencies: { - credit_card: { - properties: { - billing_address: { - type: 'string', - }, - }, - required: ['billing_address'], - }, - }, - }; - const expectedUiSchema = { - billing_address: { - 'ui:widget': 'textarea', - }, - credit_card: {}, - name: {}, - }; - - expect(transformSchemaToProps(inputSchema)).toEqual({ - schema: expectedSchema, - uiSchema: expectedUiSchema, - }); - }); - - it('transforms schema with complex dependencies', () => { - const inputSchema = { - type: 'object', - properties: { - conditional: { - title: 'Person', - type: 'object', - properties: { - 'Do you have any pets?': { - type: 'string', - enum: ['No', 'Yes: One', 'Yes: More than one'], - default: 'No', - 'ui:widget': 'radio', - }, - }, - required: ['Do you have any pets?'], - dependencies: { - 'Do you have any pets?': { - oneOf: [ - { - properties: { - 'Do you have any pets?': { - enum: ['No'], - }, - }, - }, - { - properties: { - 'Do you have any pets?': { - enum: ['Yes: One'], - }, - 'How old is your pet?': { - type: 'number', - }, - }, - required: ['How old is your pet?'], - }, - { - properties: { - 'Do you have any pets?': { - enum: ['Yes: More than one'], - }, - 'Do you want to get rid of any?': { - type: 'boolean', - }, - }, - required: ['Do you want to get rid of any?'], - }, - ], - }, - }, - }, - }, - }; - const expectedSchema = { - type: 'object', - properties: { - conditional: { - title: 'Person', - type: 'object', - properties: { - 'Do you have any pets?': { - type: 'string', - enum: ['No', 'Yes: One', 'Yes: More than one'], - default: 'No', - }, - }, - required: ['Do you have any pets?'], - dependencies: { - 'Do you have any pets?': { - oneOf: [ - { - properties: { - 'Do you have any pets?': { - enum: ['No'], - }, - }, - }, - { - properties: { - 'Do you have any pets?': { - enum: ['Yes: One'], - }, - 'How old is your pet?': { - type: 'number', - }, - }, - required: ['How old is your pet?'], - }, - { - properties: { - 'Do you have any pets?': { - enum: ['Yes: More than one'], - }, - 'Do you want to get rid of any?': { - type: 'boolean', - }, - }, - required: ['Do you want to get rid of any?'], - }, - ], - }, - }, - }, - }, - }; - const expectedUiSchema = { - conditional: { - 'Do you have any pets?': { - 'ui:widget': 'radio', - }, - 'Do you want to get rid of any?': {}, - 'How old is your pet?': {}, - }, - }; - - expect(transformSchemaToProps(inputSchema)).toEqual({ - schema: expectedSchema, - uiSchema: expectedUiSchema, - }); - }); - - it('transforms schema with array items', () => { - const inputSchema = { - type: 'object', - properties: { - person: { - type: 'array', - items: { - type: 'object', - properties: { - name: { - type: 'string', - }, - address: { - type: 'string', - 'ui:widget': 'textarea', - }, - }, - }, - }, - accountNumber: { - type: 'number', - }, - }, - }; - const expectedSchema = { - type: 'object', - properties: { - person: { - type: 'array', - items: { - type: 'object', - properties: { - name: { - type: 'string', - }, - address: { - type: 'string', - }, - }, - }, - }, - accountNumber: { - type: 'number', - }, - }, - }; - const expectedUiSchema = { - accountNumber: {}, - person: { - items: { - name: {}, - address: { - 'ui:widget': 'textarea', - }, - }, - }, - }; - - expect(transformSchemaToProps(inputSchema)).toEqual({ - schema: expectedSchema, - uiSchema: expectedUiSchema, - }); - }); -}); diff --git a/plugins/scaffolder/src/legacy/MultistepJsonForm/schema.ts b/plugins/scaffolder/src/legacy/MultistepJsonForm/schema.ts deleted file mode 100644 index e6221cb8d5..0000000000 --- a/plugins/scaffolder/src/legacy/MultistepJsonForm/schema.ts +++ /dev/null @@ -1,129 +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 { JsonObject } from '@backstage/types'; -import { UiSchema } from '@rjsf/utils'; -import type { LayoutOptions } from '@backstage/plugin-scaffolder-react'; -import { FormProps } from '@rjsf/core'; - -function isObject(value: unknown): value is JsonObject { - return typeof value === 'object' && value !== null && !Array.isArray(value); -} - -function extractUiSchema(schema: JsonObject, uiSchema: JsonObject) { - if (!isObject(schema)) { - return; - } - - const { properties, items, anyOf, oneOf, allOf, dependencies } = schema; - - for (const propName in schema) { - if (!schema.hasOwnProperty(propName)) { - continue; - } - - if (propName.startsWith('ui:')) { - uiSchema[propName] = schema[propName]; - delete schema[propName]; - } - } - - if (isObject(properties)) { - for (const propName in properties) { - if (!properties.hasOwnProperty(propName)) { - continue; - } - - const schemaNode = properties[propName]; - if (!isObject(schemaNode)) { - continue; - } - const innerUiSchema = {}; - uiSchema[propName] = uiSchema[propName] || innerUiSchema; - extractUiSchema(schemaNode, innerUiSchema); - } - } - - if (isObject(items)) { - const innerUiSchema = {}; - uiSchema.items = innerUiSchema; - extractUiSchema(items, innerUiSchema); - } - - if (Array.isArray(anyOf)) { - for (const schemaNode of anyOf) { - if (!isObject(schemaNode)) { - continue; - } - extractUiSchema(schemaNode, uiSchema); - } - } - - if (Array.isArray(oneOf)) { - for (const schemaNode of oneOf) { - if (!isObject(schemaNode)) { - continue; - } - extractUiSchema(schemaNode, uiSchema); - } - } - - if (Array.isArray(allOf)) { - for (const schemaNode of allOf) { - if (!isObject(schemaNode)) { - continue; - } - extractUiSchema(schemaNode, uiSchema); - } - } - - if (isObject(dependencies)) { - for (const depName of Object.keys(dependencies)) { - const schemaNode = dependencies[depName]; - if (!isObject(schemaNode)) { - continue; - } - extractUiSchema(schemaNode, uiSchema); - } - } -} - -export function transformSchemaToProps( - inputSchema: JsonObject, - layouts: LayoutOptions[] = [], -): { - schema: FormProps['schema']; - uiSchema: FormProps['uiSchema']; -} { - const customLayoutName = inputSchema['ui:ObjectFieldTemplate']; - inputSchema.type = inputSchema.type || 'object'; - const schema = JSON.parse(JSON.stringify(inputSchema)); - delete schema.title; // Rendered separately - const uiSchema: UiSchema = {}; - extractUiSchema(schema, uiSchema); - - if (customLayoutName) { - const Layout = layouts.find( - layout => layout.name === customLayoutName, - )?.component; - - if (Layout) { - uiSchema['ui:ObjectFieldTemplate'] = Layout; - } - } - - return { schema, uiSchema }; -} diff --git a/plugins/scaffolder/src/legacy/Router.tsx b/plugins/scaffolder/src/legacy/Router.tsx deleted file mode 100644 index ac183b9470..0000000000 --- a/plugins/scaffolder/src/legacy/Router.tsx +++ /dev/null @@ -1,183 +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 React, { ComponentType, useEffect, PropsWithChildren } from 'react'; -import { Navigate, Route, Routes, useOutlet } from 'react-router-dom'; -import { Entity } from '@backstage/catalog-model'; -import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; -import { ScaffolderPage } from './ScaffolderPage'; -import { TemplatePage } from './TemplatePage'; -import { TaskPage } from './TaskPage'; -import { ActionsPage } from '../components/ActionsPage'; -import { DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from '../extensions/default'; -import { useRouteRef, useRouteRefParams } from '@backstage/core-plugin-api'; -import { LegacyFieldExtensionOptions } from '@backstage/plugin-scaffolder-react/alpha'; -import { - ReviewStepProps, - SecretsContextProvider, - useCustomFieldExtensions, - useCustomLayouts, -} from '@backstage/plugin-scaffolder-react'; -import { ListTasksPage } from '../components/ListTasksPage'; -import { - actionsRouteRef, - editRouteRef, - legacySelectedTemplateRouteRef, - scaffolderListTaskRouteRef, - scaffolderTaskRouteRef, - selectedTemplateRouteRef, -} from '../routes'; -import { TemplateEditorPage } from './TemplateEditorPage'; - -/** - * The props for the entrypoint `ScaffolderPage` component the plugin. - * @alpha - */ -export type LegacyRouterProps = { - components?: { - ReviewStepComponent?: ComponentType; - TemplateCardComponent?: - | ComponentType<{ template: TemplateEntityV1beta3 }> - | undefined; - TaskPageComponent?: ComponentType>; - }; - groups?: Array<{ - title?: React.ReactNode; - filter: (entity: Entity) => boolean; - }>; - templateFilter?: (entity: TemplateEntityV1beta3) => boolean; - defaultPreviewTemplate?: string; - headerOptions?: { - pageTitleOverride?: string; - title?: string; - subtitle?: string; - }; - /** - * Options for the context menu on the scaffolder page. - */ - contextMenu?: { - /** Whether to show a link to the template editor */ - editor?: boolean; - /** Whether to show a link to the actions documentation */ - actions?: boolean; - }; -}; - -/** - * The legacy router - * - * @alpha - */ -export const LegacyRouter = (props: LegacyRouterProps) => { - const { - groups, - templateFilter, - components = {}, - defaultPreviewTemplate, - } = props; - - const { ReviewStepComponent, TemplateCardComponent, TaskPageComponent } = - components; - - const outlet = useOutlet(); - const TaskPageElement = TaskPageComponent ?? TaskPage; - - const customFieldExtensions = - useCustomFieldExtensions(outlet); - - const fieldExtensions = [ - ...customFieldExtensions, - ...DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS.filter( - ({ name }) => - !customFieldExtensions.some( - customFieldExtension => customFieldExtension.name === name, - ), - ), - ] as LegacyFieldExtensionOptions[]; - - const customLayouts = useCustomLayouts(outlet); - - /** - * This component can be deleted once the older routes have been deprecated. - */ - const RedirectingComponent = () => { - const { templateName } = useRouteRefParams(legacySelectedTemplateRouteRef); - const newLink = useRouteRef(selectedTemplateRouteRef); - useEffect( - () => - // eslint-disable-next-line no-console - console.warn( - 'The route /template/:templateName is deprecated, please use the new /template/:namespace/:templateName route instead', - ), - [], - ); - return ; - }; - - return ( - - - } - /> - } - /> - - - - } - /> - } - /> - } /> - } /> - - - - } - /> - - } /> - - ); -}; diff --git a/plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPage.tsx b/plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPage.tsx deleted file mode 100644 index 54122eddf0..0000000000 --- a/plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPage.tsx +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2020 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 { - Content, - ContentHeader, - CreateButton, - Header, - Page, - SupportButton, -} from '@backstage/core-components'; -import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; -import { useRouteRef } from '@backstage/core-plugin-api'; -import { - CatalogFilterLayout, - EntityKindPicker, - EntityListProvider, - EntitySearchBar, - EntityTagPicker, - UserListPicker, -} from '@backstage/plugin-catalog-react'; -import React, { ComponentType } from 'react'; -import { TemplateList } from '../TemplateList'; -import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha'; -import { usePermission } from '@backstage/plugin-permission-react'; -import { ScaffolderPageContextMenu } from './ScaffolderPageContextMenu'; -import { registerComponentRouteRef } from '../../routes'; -import { TemplateTypePicker } from '../../components'; - -export type ScaffolderPageProps = { - TemplateCardComponent?: - | ComponentType<{ template: TemplateEntityV1beta3 }> - | undefined; - groups?: Array<{ - title?: React.ReactNode; - filter: (entity: TemplateEntityV1beta3) => boolean; - }>; - templateFilter?: (entity: TemplateEntityV1beta3) => boolean; - contextMenu?: { - editor?: boolean; - actions?: boolean; - tasks?: boolean; - }; - headerOptions?: { - pageTitleOverride?: string; - title?: string; - subtitle?: string; - }; -}; - -export const ScaffolderPageContents = ({ - TemplateCardComponent, - groups, - templateFilter, - contextMenu, - headerOptions, -}: ScaffolderPageProps) => { - const registerComponentLink = useRouteRef(registerComponentRouteRef); - const otherTemplatesGroup = { - title: groups ? 'Other Templates' : 'Templates', - filter: (entity: TemplateEntityV1beta3) => { - const filtered = (groups ?? []).map(group => group.filter(entity)); - return !filtered.some(result => result === true); - }, - }; - - const { allowed } = usePermission({ - permission: catalogEntityCreatePermission, - }); - - return ( - -
- -
- - - {allowed && ( - - )} - - Create new software components using standard templates. Different - templates create different kinds of components (services, websites, - documentation, ...). - - - - - - - - - {groups && - groups.map((group, index) => ( - - ))} - - - - -
- ); -}; - -export const ScaffolderPage = ({ - TemplateCardComponent, - groups, - templateFilter, - contextMenu, - headerOptions, -}: ScaffolderPageProps) => ( - - - -); diff --git a/plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPageContextMenu.test.tsx b/plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPageContextMenu.test.tsx deleted file mode 100644 index 66513591d0..0000000000 --- a/plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPageContextMenu.test.tsx +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2020 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 userEvent from '@testing-library/user-event'; -import { renderInTestApp } from '@backstage/test-utils'; -import { screen } from '@testing-library/react'; -import React from 'react'; -import { ScaffolderPageContextMenu } from './ScaffolderPageContextMenu'; -import { rootRouteRef } from '../../routes'; - -describe('ScaffolderPageContextMenu', () => { - it('does not render anything if fully disabled', async () => { - await renderInTestApp( -
- -
, - { mountedRoutes: { '/': rootRouteRef } }, - ); - - expect(screen.getByTestId('container')).toBeEmptyDOMElement(); - }); - - it('renders the editor option', async () => { - await renderInTestApp( -
- -
, - { - mountedRoutes: { '/': rootRouteRef }, - }, - ); - - await userEvent.click(screen.getByTestId('container').firstElementChild!); - - expect(screen.getByText('Template Editor')).toBeInTheDocument(); - expect(screen.queryByText('Installed Actions')).not.toBeInTheDocument(); - }); - - it('renders the actions option', async () => { - await renderInTestApp( -
- -
, - { - mountedRoutes: { '/': rootRouteRef }, - }, - ); - - await userEvent.click(screen.getByTestId('container').firstElementChild!); - - expect(screen.queryByText('Template Editor')).not.toBeInTheDocument(); - expect(screen.getByText('Installed Actions')).toBeInTheDocument(); - }); - - it('renders all options', async () => { - await renderInTestApp( -
- -
, - { - mountedRoutes: { '/': rootRouteRef }, - }, - ); - - await userEvent.click(screen.getByTestId('container').firstElementChild!); - - expect(screen.getByText('Template Editor')).toBeInTheDocument(); - expect(screen.getByText('Installed Actions')).toBeInTheDocument(); - }); -}); diff --git a/plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPageContextMenu.tsx b/plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPageContextMenu.tsx deleted file mode 100644 index f6151c227b..0000000000 --- a/plugins/scaffolder/src/legacy/ScaffolderPage/ScaffolderPageContextMenu.tsx +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2020 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 { useRouteRef } from '@backstage/core-plugin-api'; -import IconButton from '@material-ui/core/IconButton'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import ListItemText from '@material-ui/core/ListItemText'; -import MenuItem from '@material-ui/core/MenuItem'; -import MenuList from '@material-ui/core/MenuList'; -import Popover from '@material-ui/core/Popover'; -import { makeStyles } from '@material-ui/core/styles'; -import Description from '@material-ui/icons/Description'; -import Edit from '@material-ui/icons/Edit'; -import List from '@material-ui/icons/List'; -import MoreVert from '@material-ui/icons/MoreVert'; -import React, { useState } from 'react'; -import { useNavigate } from 'react-router-dom'; -import { - actionsRouteRef, - editRouteRef, - scaffolderListTaskRouteRef, -} from '../../routes'; - -const useStyles = makeStyles(theme => ({ - button: { - color: theme.page.fontColor, - }, -})); - -export type ScaffolderPageContextMenuProps = { - editor?: boolean; - actions?: boolean; - tasks?: boolean; -}; - -export function ScaffolderPageContextMenu( - props: ScaffolderPageContextMenuProps, -) { - const classes = useStyles(); - const [anchorEl, setAnchorEl] = useState(); - const editLink = useRouteRef(editRouteRef); - const actionsLink = useRouteRef(actionsRouteRef); - const tasksLink = useRouteRef(scaffolderListTaskRouteRef); - - const navigate = useNavigate(); - - const showEditor = props.editor !== false; - const showActions = props.actions !== false; - const showTasks = props.tasks !== false; - - if (!showEditor && !showActions) { - return null; - } - - const onOpen = (event: React.SyntheticEvent) => { - setAnchorEl(event.currentTarget); - }; - - const onClose = () => { - setAnchorEl(undefined); - }; - - return ( - <> - - - - - - {showEditor && ( - navigate(editLink())}> - - - - - - )} - {showActions && ( - navigate(actionsLink())}> - - - - - - )} - {showTasks && ( - navigate(tasksLink())}> - - - - - - )} - - - - ); -} diff --git a/plugins/scaffolder/src/legacy/ScaffolderPage/index.ts b/plugins/scaffolder/src/legacy/ScaffolderPage/index.ts deleted file mode 100644 index 433e39723f..0000000000 --- a/plugins/scaffolder/src/legacy/ScaffolderPage/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { ScaffolderPage } from './ScaffolderPage'; diff --git a/plugins/scaffolder/src/legacy/TaskPage/IconLink.test.tsx b/plugins/scaffolder/src/legacy/TaskPage/IconLink.test.tsx deleted file mode 100644 index 0b6092c37d..0000000000 --- a/plugins/scaffolder/src/legacy/TaskPage/IconLink.test.tsx +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2020 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 { renderInTestApp } from '@backstage/test-utils'; -import CloudIcon from '@material-ui/icons/Cloud'; -import React from 'react'; -import { IconLink } from './IconLink'; - -describe('IconLink', () => { - it('should render an icon link', async () => { - const rendered = await renderInTestApp( - , - ); - - expect(rendered.getByText('I am Link')).toBeInTheDocument(); - }); -}); diff --git a/plugins/scaffolder/src/legacy/TaskPage/TaskErrors.tsx b/plugins/scaffolder/src/legacy/TaskPage/TaskErrors.tsx deleted file mode 100644 index 4f8ce974c8..0000000000 --- a/plugins/scaffolder/src/legacy/TaskPage/TaskErrors.tsx +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { Box } from '@material-ui/core'; -import React, { useEffect, useRef } from 'react'; -import { DismissableBanner } from '@backstage/core-components'; - -type TaskErrorsProps = { - error?: Error; -}; - -export const TaskErrors = ({ error }: TaskErrorsProps) => { - const id = useRef(''); - - useEffect(() => { - id.current = String(Math.random()); - }, [error]); - return error ? ( - - - - ) : null; -}; diff --git a/plugins/scaffolder/src/legacy/TaskPage/TaskPage.tsx b/plugins/scaffolder/src/legacy/TaskPage/TaskPage.tsx deleted file mode 100644 index affb9a31b7..0000000000 --- a/plugins/scaffolder/src/legacy/TaskPage/TaskPage.tsx +++ /dev/null @@ -1,393 +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 { parseEntityRef } from '@backstage/catalog-model'; -import { - Content, - ErrorPage, - Header, - LogViewer, - Page, - Progress, -} from '@backstage/core-components'; -import { - useApi, - useRouteRef, - useRouteRefParams, -} from '@backstage/core-plugin-api'; -import { - Button, - CircularProgress, - Paper, - StepButton, - StepIconProps, -} from '@material-ui/core'; -import Grid from '@material-ui/core/Grid'; -import Step from '@material-ui/core/Step'; -import StepLabel from '@material-ui/core/StepLabel'; -import Stepper from '@material-ui/core/Stepper'; -import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'; -import Typography from '@material-ui/core/Typography'; -import Cancel from '@material-ui/icons/Cancel'; -import Check from '@material-ui/icons/Check'; -import FiberManualRecordIcon from '@material-ui/icons/FiberManualRecord'; -import classNames from 'classnames'; -import { DateTime, Interval } from 'luxon'; -import qs from 'qs'; -import React, { memo, useEffect, useMemo, useState } from 'react'; -import { useNavigate } from 'react-router-dom'; -import useInterval from 'react-use/lib/useInterval'; -import { - ScaffolderTaskStatus, - ScaffolderTaskOutput, - useTaskEventStream, -} from '@backstage/plugin-scaffolder-react'; -import { TaskErrors } from './TaskErrors'; -import { TaskPageLinks } from './TaskPageLinks'; -import { - rootRouteRef, - scaffolderTaskRouteRef, - selectedTemplateRouteRef, -} from '../../routes'; -import { scaffolderApiRef } from '@backstage/plugin-scaffolder-react'; -import humanizeDuration from 'humanize-duration'; - -const useStyles = makeStyles((theme: Theme) => - createStyles({ - root: { - width: '100%', - }, - button: { - marginBottom: theme.spacing(2), - marginLeft: theme.spacing(2), - }, - actionsContainer: { - marginBottom: theme.spacing(2), - }, - resetContainer: { - padding: theme.spacing(3), - }, - labelWrapper: { - display: 'flex', - flex: 1, - flexDirection: 'row', - justifyContent: 'space-between', - }, - stepWrapper: { - width: '100%', - }, - }), -); - -type TaskStep = { - id: string; - name: string; - status: ScaffolderTaskStatus; - startedAt?: string; - endedAt?: string; -}; - -const StepTimeTicker = ({ step }: { step: TaskStep }) => { - const [time, setTime] = useState(''); - - useInterval(() => { - if (!step.startedAt) { - setTime(''); - return; - } - - const end = step.endedAt - ? DateTime.fromISO(step.endedAt) - : DateTime.local(); - - const startedAt = DateTime.fromISO(step.startedAt); - const formatted = Interval.fromDateTimes(startedAt, end) - .toDuration() - .valueOf(); - - setTime(humanizeDuration(formatted, { round: true })); - }, 1000); - - return {time}; -}; - -const useStepIconStyles = makeStyles(theme => - createStyles({ - root: { - color: theme.palette.text.disabled, - display: 'flex', - height: 22, - alignItems: 'center', - }, - completed: { - color: theme.palette.status.ok, - }, - error: { - color: theme.palette.status.error, - }, - }), -); - -function TaskStepIconComponent(props: StepIconProps) { - const classes = useStepIconStyles(); - const { active, completed, error } = props; - - const getMiddle = () => { - if (active) { - return ; - } - if (completed) { - return ; - } - if (error) { - return ; - } - return ; - }; - - return ( -
- {getMiddle()} -
- ); -} - -export const TaskStatusStepper = memo( - (props: { - steps: TaskStep[]; - currentStepId: string | undefined; - onUserStepChange: (id: string) => void; - classes?: { - root?: string; - }; - }) => { - const { steps, currentStepId, onUserStepChange } = props; - const classes = useStyles(props); - - return ( -
- s.id === currentStepId)} - orientation="vertical" - nonLinear - > - {steps.map((step, index) => { - const isCancelled = step.status === 'cancelled'; - const isActive = step.status === 'processing'; - const isCompleted = step.status === 'completed'; - const isFailed = step.status === 'failed'; - const isSkipped = step.status === 'skipped'; - - return ( - - onUserStepChange(step.id)}> - -
- {step.name} - {isSkipped ? ( - Skipped - ) : ( - - )} -
-
-
-
- ); - })} -
-
- ); - }, -); - -const hasLinks = ({ links = [] }: ScaffolderTaskOutput): boolean => - links.length > 0; - -/** - * TaskPageProps for constructing a TaskPage - * @param loadingText - Optional loading text shown before a task begins executing. - * @public - * @deprecated - this is a useless type that is no longer used. - */ -export type TaskPageProps = { - loadingText?: string; -}; - -/** - * TaskPage for showing the status of the taskId provided as a param - * - * @alpha - */ -export const TaskPage = (props: TaskPageProps) => { - const { loadingText } = props; - const classes = useStyles(); - const navigate = useNavigate(); - const rootPath = useRouteRef(rootRouteRef); - const scaffolderApi = useApi(scaffolderApiRef); - const templateRoute = useRouteRef(selectedTemplateRouteRef); - const [userSelectedStepId, setUserSelectedStepId] = useState< - string | undefined - >(undefined); - const [clickedToCancel, setClickedToCancel] = useState(false); - const [lastActiveStepId, setLastActiveStepId] = useState( - undefined, - ); - const { taskId } = useRouteRefParams(scaffolderTaskRouteRef); - const taskStream = useTaskEventStream(taskId); - const completed = taskStream.completed; - const taskCancelled = taskStream.cancelled; - const steps = useMemo( - () => - taskStream.task?.spec.steps.map(step => ({ - ...step, - ...taskStream?.steps?.[step.id], - })) ?? [], - [taskStream], - ); - - useEffect(() => { - const mostRecentFailedOrActiveStep = steps.find(step => - ['failed', 'processing'].includes(step.status), - ); - if (completed && !mostRecentFailedOrActiveStep) { - setLastActiveStepId(steps[steps.length - 1]?.id); - return; - } - - setLastActiveStepId(mostRecentFailedOrActiveStep?.id); - }, [steps, completed]); - - const currentStepId = userSelectedStepId ?? lastActiveStepId; - - const logAsString = useMemo(() => { - if (!currentStepId) { - return loadingText ? loadingText : 'Loading...'; - } - const log = taskStream.stepLogs[currentStepId]; - - if (!log?.length) { - return 'Waiting for logs...'; - } - return log.join('\n'); - }, [taskStream.stepLogs, currentStepId, loadingText]); - - const taskNotFound = - taskStream.completed && !taskStream.loading && !taskStream.task; - - const { output } = taskStream; - - const handleStartOver = () => { - if (!taskStream.task || !taskStream.task?.spec.templateInfo?.entityRef) { - navigate(rootPath()); - return; - } - - const formData = taskStream.task!.spec.parameters; - - const { name, namespace } = parseEntityRef( - taskStream.task!.spec.templateInfo?.entityRef, - ); - - navigate( - `${templateRoute({ templateName: name, namespace })}?${qs.stringify({ - formData: JSON.stringify(formData), - })}`, - ); - }; - - const handleCancel = async () => { - setClickedToCancel(true); - await scaffolderApi.cancelTask(taskId); - }; - - return ( - -
- - {taskNotFound ? ( - - ) : ( -
- - - - - {output && hasLinks(output) && ( - - )} - - - - - - {!currentStepId && } - -
- - -
-
-
-
- )} -
- - ); -}; diff --git a/plugins/scaffolder/src/legacy/TaskPage/TaskPageLinks.test.tsx b/plugins/scaffolder/src/legacy/TaskPage/TaskPageLinks.test.tsx deleted file mode 100644 index 2f5d015f8d..0000000000 --- a/plugins/scaffolder/src/legacy/TaskPage/TaskPageLinks.test.tsx +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2020 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 { entityRouteRef } from '@backstage/plugin-catalog-react'; -import { renderInTestApp } from '@backstage/test-utils'; -import React from 'react'; -import { TaskPageLinks } from './TaskPageLinks'; - -describe('TaskPageLinks', () => { - beforeEach(() => {}); - - afterEach(() => { - jest.resetAllMocks(); - }); - - it('renders further links', async () => { - const output = { - links: [ - { url: 'https://first.url', title: 'Cool link 1' }, - { url: 'https://second.url', title: 'Cool link 2' }, - { entityRef: 'Component:default/my-app', title: 'Open in catalog' }, - { title: 'Skipped' }, - ], - }; - const { findByText, queryByText } = await renderInTestApp( - , - { - mountedRoutes: { - '/catalog/:namespace/:kind/:name/*': entityRouteRef, - }, - }, - ); - - let element = await findByText('Cool link 1'); - - expect(element).toBeInTheDocument(); - expect(element).toHaveAttribute('href', 'https://first.url'); - - element = await findByText('Cool link 2'); - - expect(element).toBeInTheDocument(); - expect(element).toHaveAttribute('href', 'https://second.url'); - - element = await findByText('Open in catalog'); - - expect(element).toBeInTheDocument(); - expect(element).toHaveAttribute( - 'href', - '/catalog/default/Component/my-app', - ); - - expect(queryByText('Skipped')).not.toBeInTheDocument(); - }); -}); diff --git a/plugins/scaffolder/src/legacy/TaskPage/index.ts b/plugins/scaffolder/src/legacy/TaskPage/index.ts deleted file mode 100644 index f7876888f9..0000000000 --- a/plugins/scaffolder/src/legacy/TaskPage/index.ts +++ /dev/null @@ -1,17 +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. - */ -export { TaskPage } from './TaskPage'; -export type { TaskPageProps } from './TaskPage'; diff --git a/plugins/scaffolder/src/legacy/TemplateCard/TemplateCard.tsx b/plugins/scaffolder/src/legacy/TemplateCard/TemplateCard.tsx deleted file mode 100644 index 80f719bd36..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateCard/TemplateCard.tsx +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright 2020 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 { - DEFAULT_NAMESPACE, - Entity, - EntityLink, - parseEntityRef, - RELATION_OWNED_BY, - stringifyEntityRef, -} from '@backstage/catalog-model'; -import { - ItemCardHeader, - Link, - LinkButton, - MarkdownContent, -} from '@backstage/core-components'; -import { - IconComponent, - useApi, - useApp, - useRouteRef, -} from '@backstage/core-plugin-api'; -import { - ScmIntegrationIcon, - scmIntegrationsApiRef, -} from '@backstage/integration-react'; -import { - EntityRefLinks, - FavoriteEntity, - getEntityRelations, - getEntitySourceLocation, -} from '@backstage/plugin-catalog-react'; -import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; -import { - Box, - Card, - CardActions, - CardContent, - CardMedia, - Chip, - IconButton, - makeStyles, - Theme, - Tooltip, - Typography, - useTheme, -} from '@material-ui/core'; -import LanguageIcon from '@material-ui/icons/Language'; -import WarningIcon from '@material-ui/icons/Warning'; -import React from 'react'; -import { selectedTemplateRouteRef, viewTechDocRouteRef } from '../../routes'; - -const useStyles = makeStyles< - Theme, - { fontColor: string; backgroundImage: string } ->(theme => ({ - cardHeader: { - position: 'relative', - }, - title: { - backgroundImage: ({ backgroundImage }) => backgroundImage, - color: ({ fontColor }) => fontColor, - }, - box: { - overflow: 'hidden', - textOverflow: 'ellipsis', - display: '-webkit-box', - '-webkit-line-clamp': 10, - '-webkit-box-orient': 'vertical', - }, - label: { - color: theme.palette.text.secondary, - textTransform: 'uppercase', - fontSize: '0.65rem', - fontWeight: 'bold', - letterSpacing: 0.5, - lineHeight: 1, - paddingBottom: '0.2rem', - }, - linksLabel: { - padding: '0 16px', - }, - description: { - '& p': { - margin: '0px', - }, - }, - leftButton: { - marginRight: 'auto', - }, - starButton: { - position: 'absolute', - top: theme.spacing(0.5), - right: theme.spacing(0.5), - padding: '0.25rem', - color: ({ fontColor }) => fontColor, - }, -})); - -const MuiIcon = ({ icon: Icon }: { icon: IconComponent }) => ; - -const useDeprecationStyles = makeStyles(theme => ({ - deprecationIcon: { - position: 'absolute', - top: theme.spacing(0.5), - right: theme.spacing(3.5), - padding: '0.25rem', - }, - link: { - color: theme.palette.warning.light, - }, -})); - -export type TemplateCardProps = { - template: TemplateEntityV1beta3; - deprecated?: boolean; -}; - -type TemplateProps = { - description: string; - tags: string[]; - title: string; - type: string; - name: string; - links: EntityLink[]; -}; - -const getTemplateCardProps = ( - template: TemplateEntityV1beta3, -): TemplateProps & { key: string } => { - return { - key: template.metadata.uid!, - name: template.metadata.name, - title: `${(template.metadata.title || template.metadata.name) ?? ''}`, - type: template.spec.type ?? '', - description: template.metadata.description ?? '-', - tags: (template.metadata?.tags as string[]) ?? [], - links: template.metadata.links ?? [], - }; -}; - -const DeprecationWarning = () => { - const styles = useDeprecationStyles(); - - const Title = ( - - This template uses a syntax that has been deprecated, and should be - migrated to a newer syntax. Click for more info. - - ); - - return ( -
- - - - - -
- ); -}; - -export const TemplateCard = ({ template, deprecated }: TemplateCardProps) => { - const app = useApp(); - const backstageTheme = useTheme(); - const templateRoute = useRouteRef(selectedTemplateRouteRef); - const templateProps = getTemplateCardProps(template); - const ownedByRelations = getEntityRelations( - template as Entity, - RELATION_OWNED_BY, - ); - const themeId = backstageTheme.getPageTheme({ themeId: templateProps.type }) - ? templateProps.type - : 'other'; - const theme = backstageTheme.getPageTheme({ themeId }); - const classes = useStyles({ - fontColor: theme.fontColor, - backgroundImage: theme.backgroundImage, - }); - const { name, namespace } = parseEntityRef(stringifyEntityRef(template)); - const href = templateRoute({ templateName: name, namespace }); - - // TechDocs Link - const viewTechDoc = useRouteRef(viewTechDocRouteRef); - const viewTechDocsAnnotation = - template.metadata.annotations?.['backstage.io/techdocs-ref']; - const viewTechDocsLink = - !!viewTechDocsAnnotation && - !!viewTechDoc && - viewTechDoc({ - namespace: template.metadata.namespace || DEFAULT_NAMESPACE, - kind: template.kind, - name: template.metadata.name, - }); - - const iconResolver = (key?: string): IconComponent => - key ? app.getSystemIcon(key) ?? LanguageIcon : LanguageIcon; - - const scmIntegrationsApi = useApi(scmIntegrationsApiRef); - const sourceLocation = getEntitySourceLocation(template, scmIntegrationsApi); - - return ( - - - - {deprecated && } - - - - - - Description - - - - - - Owner - - - - - - Tags - - {templateProps.tags?.map(tag => ( - - ))} - - - - Links - - -
- {sourceLocation && ( - - - - - - )} - {viewTechDocsLink && ( - - - - - - )} - {templateProps.links?.map((link, i) => ( - - - - - - ))} -
- - Choose - -
-
- ); -}; diff --git a/plugins/scaffolder/src/legacy/TemplateCard/index.ts b/plugins/scaffolder/src/legacy/TemplateCard/index.ts deleted file mode 100644 index 291a06ed69..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateCard/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { TemplateCard } from './TemplateCard'; -export type { TemplateCardProps } from './TemplateCard'; diff --git a/plugins/scaffolder/src/legacy/TemplateEditorPage/CustomFieldExplorer.tsx b/plugins/scaffolder/src/legacy/TemplateEditorPage/CustomFieldExplorer.tsx deleted file mode 100644 index def3bf1796..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateEditorPage/CustomFieldExplorer.tsx +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { StreamLanguage } from '@codemirror/language'; -import { yaml as yamlSupport } from '@codemirror/legacy-modes/mode/yaml'; -import { - Button, - Card, - CardContent, - CardHeader, - FormControl, - IconButton, - InputLabel, - makeStyles, - MenuItem, - Select, -} from '@material-ui/core'; -import CloseIcon from '@material-ui/icons/Close'; -import CodeMirror from '@uiw/react-codemirror'; -import React, { useCallback, useMemo, useState } from 'react'; -import yaml from 'yaml'; -import { Form } from '@backstage/plugin-scaffolder-react/alpha'; -import { TemplateEditorForm } from './TemplateEditorForm'; -import validator from '@rjsf/validator-ajv8'; -import { LegacyFieldExtensionOptions } from '@backstage/plugin-scaffolder-react/alpha'; - -const useStyles = makeStyles(theme => ({ - root: { - gridArea: 'pageContent', - display: 'grid', - gridTemplateAreas: ` - "controls controls" - "fieldForm preview" - `, - gridTemplateRows: 'auto 1fr', - gridTemplateColumns: '1fr 1fr', - }, - controls: { - gridArea: 'controls', - display: 'flex', - flexFlow: 'row nowrap', - alignItems: 'center', - margin: theme.spacing(1), - }, - fieldForm: { - gridArea: 'fieldForm', - }, - preview: { - gridArea: 'preview', - }, -})); - -export const CustomFieldExplorer = ({ - customFieldExtensions = [], - onClose, -}: { - customFieldExtensions?: LegacyFieldExtensionOptions[]; - onClose?: () => void; -}) => { - const classes = useStyles(); - const fieldOptions = customFieldExtensions.filter(field => !!field.schema); - const [selectedField, setSelectedField] = useState(fieldOptions[0]); - const [fieldFormState, setFieldFormState] = useState({}); - const [refreshKey, setRefreshKey] = useState(Date.now()); - const [formState, setFormState] = useState({}); - const sampleFieldTemplate = useMemo( - () => - yaml.stringify({ - parameters: [ - { - title: `${selectedField.name} Example`, - properties: { - [selectedField.name]: { - type: selectedField.schema?.returnValue?.type, - 'ui:field': selectedField.name, - 'ui:options': fieldFormState, - }, - }, - }, - ], - }), - [fieldFormState, selectedField], - ); - - const fieldComponents = useMemo(() => { - return Object.fromEntries( - customFieldExtensions.map(({ name, component }) => [name, component]), - ); - }, [customFieldExtensions]); - - const handleSelectionChange = useCallback( - (selection: LegacyFieldExtensionOptions) => { - setSelectedField(selection); - setFieldFormState({}); - setFormState({}); - }, - [setFieldFormState, setSelectedField, setFormState], - ); - - const handleFieldConfigChange = useCallback( - (state: {}) => { - setFieldFormState(state); - // Force TemplateEditorForm to re-render since some fields - // may not be responsive to ui:option changes - setRefreshKey(Date.now()); - }, - [setFieldFormState, setRefreshKey], - ); - - return ( -
-
- - - Choose Custom Field Extension - - - - - - - -
-
- - - -
handleFieldConfigChange(e.formData)} - validator={validator} - schema={selectedField.schema?.uiOptions || {}} - experimental_defaultFormStateBehavior={{ - allOf: 'populateDefaults', - }} - > - -
-
-
-
-
- - - - - - - null} - /> -
-
- ); -}; diff --git a/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditor.tsx b/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditor.tsx deleted file mode 100644 index f6e7b38d7d..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditor.tsx +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { makeStyles } from '@material-ui/core'; -import React, { useState } from 'react'; -import { LegacyFieldExtensionOptions } from '@backstage/plugin-scaffolder-react/alpha'; -import { TemplateDirectoryAccess } from '../../lib/filesystem'; -import { LayoutOptions } from '@backstage/plugin-scaffolder-react'; -import { DirectoryEditorProvider } from '../../next/TemplateEditorPage/DirectoryEditorContext'; -import { DryRunProvider } from '../../next/TemplateEditorPage/DryRunContext'; -import { TemplateEditorBrowser } from '../../next/TemplateEditorPage/TemplateEditorBrowser'; -import { TemplateEditorTextArea } from '../../next/TemplateEditorPage/TemplateEditorTextArea'; -import { TemplateEditorForm } from './TemplateEditorForm'; -import { DryRunResults } from '../../next/TemplateEditorPage/DryRunResults'; - -const useStyles = makeStyles({ - // Reset and fix sizing to make sure scrolling behaves correctly - root: { - gridArea: 'pageContent', - - display: 'grid', - gridTemplateAreas: ` - "browser editor preview" - "results results results" - `, - gridTemplateColumns: '1fr 3fr 2fr', - gridTemplateRows: '1fr auto', - }, - browser: { - gridArea: 'browser', - overflow: 'auto', - }, - editor: { - gridArea: 'editor', - overflow: 'auto', - }, - preview: { - gridArea: 'preview', - overflow: 'auto', - }, - results: { - gridArea: 'results', - }, -}); - -export const TemplateEditor = (props: { - directory: TemplateDirectoryAccess; - fieldExtensions?: LegacyFieldExtensionOptions[]; - layouts?: LayoutOptions[]; - onClose?: () => void; -}) => { - const classes = useStyles(); - - const [errorText, setErrorText] = useState(); - - return ( - - -
-
- -
-
- -
-
- -
-
- -
-
-
-
- ); -}; diff --git a/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditorForm.tsx b/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditorForm.tsx deleted file mode 100644 index df05efc921..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditorForm.tsx +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { useApiHolder } from '@backstage/core-plugin-api'; -import { JsonObject, JsonValue } from '@backstage/types'; -import { makeStyles } from '@material-ui/core/styles'; -import React, { Component, ReactNode, useMemo, useState } from 'react'; -import useDebounce from 'react-use/lib/useDebounce'; -import yaml from 'yaml'; -import { - LayoutOptions, - TemplateParameterSchema, -} from '@backstage/plugin-scaffolder-react'; - -import { useDryRun } from '../../next/TemplateEditorPage/DryRunContext'; -import { useDirectoryEditor } from '../../next/TemplateEditorPage/DirectoryEditorContext'; -import { MultistepJsonForm } from '../MultistepJsonForm'; -import { createValidator } from '../TemplatePage'; -import { LegacyFieldExtensionOptions } from '@backstage/plugin-scaffolder-react/alpha'; - -const useStyles = makeStyles({ - containerWrapper: { - position: 'relative', - width: '100%', - height: '100%', - }, - container: { - position: 'absolute', - top: 0, - bottom: 0, - left: 0, - right: 0, - overflow: 'auto', - }, -}); - -interface ErrorBoundaryProps { - invalidator: unknown; - setErrorText(errorText: string | undefined): void; - children: ReactNode; -} - -interface ErrorBoundaryState { - shouldRender: boolean; -} - -class ErrorBoundary extends Component { - state = { - shouldRender: true, - }; - - componentDidUpdate(prevProps: { invalidator: unknown }) { - if (prevProps.invalidator !== this.props.invalidator) { - this.setState({ shouldRender: true }); - } - } - - componentDidCatch(error: Error) { - this.props.setErrorText(error.message); - this.setState({ shouldRender: false }); - } - - render() { - return this.state.shouldRender ? this.props.children : null; - } -} - -interface TemplateEditorFormProps { - content?: string; - /** Setting this to true will cause the content to be parsed as if it is the template entity spec */ - contentIsSpec?: boolean; - data: JsonObject; - onUpdate: (data: JsonObject) => void; - setErrorText: (errorText?: string) => void; - - onDryRun?: (data: JsonObject) => Promise; - fieldExtensions?: LegacyFieldExtensionOptions[]; - layouts?: LayoutOptions[]; -} - -function isJsonObject(value: JsonValue | undefined): value is JsonObject { - return typeof value === 'object' && value !== null && !Array.isArray(value); -} - -/** Shows the a template form that is parsed from the provided content */ -export function TemplateEditorForm(props: TemplateEditorFormProps) { - const { - content, - contentIsSpec, - data, - onUpdate, - onDryRun, - setErrorText, - fieldExtensions = [], - layouts = [], - } = props; - const classes = useStyles(); - const apiHolder = useApiHolder(); - - const [steps, setSteps] = useState(); - - const fields = useMemo(() => { - return Object.fromEntries( - fieldExtensions.map(({ name, component }) => [name, component]), - ); - }, [fieldExtensions]); - - useDebounce( - () => { - try { - if (!content) { - setSteps(undefined); - return; - } - const parsed: JsonValue = yaml - .parseAllDocuments(content) - .filter(c => c) - .map(c => c.toJSON())[0]; - - if (!isJsonObject(parsed)) { - setSteps(undefined); - return; - } - - let rootObj = parsed; - if (!contentIsSpec) { - const isTemplate = - String(parsed.kind).toLocaleLowerCase('en-US') === 'template'; - if (!isTemplate) { - setSteps(undefined); - return; - } - - rootObj = isJsonObject(parsed.spec) ? parsed.spec : {}; - } - - const { parameters } = rootObj; - - if (!Array.isArray(parameters)) { - setErrorText('Template parameters must be an array'); - setSteps(undefined); - return; - } - - const fieldValidators = Object.fromEntries( - fieldExtensions.map(({ name, validation }) => [name, validation]), - ); - - setErrorText(); - setSteps( - parameters.flatMap(param => - isJsonObject(param) - ? [ - { - title: String(param.title), - schema: param, - validate: createValidator(param, fieldValidators, { - apiHolder, - }), - }, - ] - : [], - ), - ); - } catch (e) { - setErrorText(e.message); - } - }, - 250, - [contentIsSpec, content, apiHolder], - ); - - if (!steps) { - return null; - } - - return ( -
-
- - onUpdate(e.formData)} - onReset={() => onUpdate({})} - finishButtonLabel={onDryRun && 'Try It'} - onFinish={onDryRun && (() => onDryRun(data))} - layouts={layouts} - /> - -
-
- ); -} - -/** A version of the TemplateEditorForm that is connected to the DirectoryEditor and DryRun contexts */ -export function TemplateEditorFormDirectoryEditorDryRun( - props: Pick< - TemplateEditorFormProps, - 'setErrorText' | 'fieldExtensions' | 'layouts' - >, -) { - const { setErrorText, fieldExtensions = [], layouts } = props; - const dryRun = useDryRun(); - - const directoryEditor = useDirectoryEditor(); - const { selectedFile } = directoryEditor; - - const [data, setData] = useState({}); - - const handleDryRun = async () => { - if (!selectedFile) { - return; - } - - try { - await dryRun.execute({ - templateContent: selectedFile.content, - values: data, - files: directoryEditor.files, - }); - setErrorText(); - } catch (e) { - setErrorText(String(e.cause || e)); - throw e; - } - }; - - const content = - selectedFile && selectedFile.path.match(/\.ya?ml$/) - ? selectedFile.content - : undefined; - - return ( - - ); -} - -TemplateEditorForm.DirectoryEditorDryRun = - TemplateEditorFormDirectoryEditorDryRun; diff --git a/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditorPage.tsx b/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditorPage.tsx deleted file mode 100644 index 127c73dcf5..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateEditorPage.tsx +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React, { useState } from 'react'; -import { Content, Header, Page } from '@backstage/core-components'; -import { - TemplateDirectoryAccess, - WebFileSystemAccess, -} from '../../lib/filesystem'; -import { type LayoutOptions } from '@backstage/plugin-scaffolder-react'; -import { LegacyFieldExtensionOptions } from '@backstage/plugin-scaffolder-react/alpha'; -import { TemplateEditorIntro } from '../../next/TemplateEditorPage/TemplateEditorIntro'; -import { TemplateEditor } from './TemplateEditor'; -import { TemplateFormPreviewer } from './TemplateFormPreviewer'; -import { CustomFieldExplorer } from './CustomFieldExplorer'; - -type Selection = - | { - type: 'local'; - directory: TemplateDirectoryAccess; - } - | { - type: 'form'; - } - | { - type: 'field-explorer'; - }; - -interface TemplateEditorPageProps { - defaultPreviewTemplate?: string; - customFieldExtensions?: LegacyFieldExtensionOptions[]; - layouts?: LayoutOptions[]; -} - -export function TemplateEditorPage(props: TemplateEditorPageProps) { - const [selection, setSelection] = useState(); - - let content: JSX.Element | null = null; - if (selection?.type === 'local') { - content = ( - setSelection(undefined)} - layouts={props.layouts} - /> - ); - } else if (selection?.type === 'form') { - content = ( - setSelection(undefined)} - layouts={props.layouts} - /> - ); - } else if (selection?.type === 'field-explorer') { - content = ( - setSelection(undefined)} - /> - ); - } else { - content = ( - - { - if (option === 'local') { - WebFileSystemAccess.requestDirectoryAccess() - .then(directory => setSelection({ type: 'local', directory })) - .catch(() => {}); - } else if (option === 'form') { - setSelection({ type: 'form' }); - } else if (option === 'field-explorer') { - setSelection({ type: 'field-explorer' }); - } - }} - /> - - ); - } - - return ( - -
- {content} - - ); -} diff --git a/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateFormPreviewer.tsx b/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateFormPreviewer.tsx deleted file mode 100644 index 9e92d12d93..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateEditorPage/TemplateFormPreviewer.tsx +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { Entity } from '@backstage/catalog-model'; -import { alertApiRef, useApi } from '@backstage/core-plugin-api'; -import { - catalogApiRef, - humanizeEntityRef, -} from '@backstage/plugin-catalog-react'; -import { - FormControl, - IconButton, - InputLabel, - LinearProgress, - makeStyles, - MenuItem, - Select, -} from '@material-ui/core'; -import CloseIcon from '@material-ui/icons/Close'; -import React, { useCallback, useState } from 'react'; -import useAsync from 'react-use/lib/useAsync'; -import yaml from 'yaml'; -import { LayoutOptions } from '@backstage/plugin-scaffolder-react'; -import { LegacyFieldExtensionOptions } from '@backstage/plugin-scaffolder-react/alpha'; -import { TemplateEditorTextArea } from '../../next/TemplateEditorPage/TemplateEditorTextArea'; -import { TemplateEditorForm } from './TemplateEditorForm'; - -const EXAMPLE_TEMPLATE_PARAMS_YAML = `# Edit the template parameters below to see how they will render in the scaffolder form UI -parameters: - - title: Fill in some steps - required: - - name - properties: - name: - title: Name - type: string - description: Unique name of the component - owner: - title: Owner - type: string - description: Owner of the component - ui:field: OwnerPicker - ui:options: - catalogFilter: - kind: Group - - title: Choose a location - required: - - repoUrl - properties: - repoUrl: - title: Repository Location - type: string - ui:field: RepoUrlPicker - ui:options: - allowedHosts: - - github.com -steps: - - id: fetch-base - name: Fetch Base - action: fetch:template - input: - url: ./template - values: - name: \${{parameters.name}} -`; - -type TemplateOption = { - label: string; - value: Entity; -}; - -const useStyles = makeStyles(theme => ({ - root: { - gridArea: 'pageContent', - display: 'grid', - gridTemplateAreas: ` - "controls controls" - "textArea preview" - `, - gridTemplateRows: 'auto 1fr', - gridTemplateColumns: '1fr 1fr', - }, - controls: { - gridArea: 'controls', - display: 'flex', - flexFlow: 'row nowrap', - alignItems: 'center', - margin: theme.spacing(1), - }, - textArea: { - gridArea: 'textArea', - }, - preview: { - gridArea: 'preview', - }, -})); - -export const TemplateFormPreviewer = ({ - defaultPreviewTemplate = EXAMPLE_TEMPLATE_PARAMS_YAML, - customFieldExtensions = [], - onClose, - layouts = [], -}: { - defaultPreviewTemplate?: string; - customFieldExtensions?: LegacyFieldExtensionOptions[]; - onClose?: () => void; - layouts?: LayoutOptions[]; -}) => { - const classes = useStyles(); - const alertApi = useApi(alertApiRef); - const catalogApi = useApi(catalogApiRef); - const [selectedTemplate, setSelectedTemplate] = useState(''); - const [errorText, setErrorText] = useState(); - const [templateOptions, setTemplateOptions] = useState([]); - const [templateYaml, setTemplateYaml] = useState(defaultPreviewTemplate); - const [formState, setFormState] = useState({}); - - const { loading } = useAsync( - () => - catalogApi - .getEntities({ - filter: { kind: 'template' }, - fields: [ - 'kind', - 'metadata.namespace', - 'metadata.name', - 'metadata.title', - 'spec.parameters', - 'spec.steps', - 'spec.output', - ], - }) - .then(({ items }) => - setTemplateOptions( - items.map(template => ({ - label: - template.metadata.title ?? - humanizeEntityRef(template, { defaultKind: 'template' }), - value: template, - })), - ), - ) - .catch(e => - alertApi.post({ - message: `Error loading exisiting templates: ${e.message}`, - severity: 'error', - }), - ), - [catalogApi], - ); - - const handleSelectChange = useCallback( - // TODO(Rugvip): Afaik this should be Entity, but didn't want to make runtime changes while fixing types - (selected: any) => { - setSelectedTemplate(selected); - setTemplateYaml(yaml.stringify(selected.spec)); - }, - [setTemplateYaml], - ); - - return ( - <> - {loading && } -
-
- - - Load Existing Template - - - - - - - -
-
- -
-
- -
-
- - ); -}; diff --git a/plugins/scaffolder/src/legacy/TemplateEditorPage/index.ts b/plugins/scaffolder/src/legacy/TemplateEditorPage/index.ts deleted file mode 100644 index 7de0d3c679..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateEditorPage/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { TemplateEditorPage } from './TemplateEditorPage'; diff --git a/plugins/scaffolder/src/legacy/TemplateList/TemplateList.test.tsx b/plugins/scaffolder/src/legacy/TemplateList/TemplateList.test.tsx deleted file mode 100644 index c65613d2f5..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateList/TemplateList.test.tsx +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2020 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 { screen } from '@testing-library/react'; -import React from 'react'; -import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { TemplateList } from './TemplateList'; -import { rootRouteRef } from '../../routes'; -import { - ScmIntegrationsApi, - scmIntegrationsApiRef, -} from '@backstage/integration-react'; -import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; - -jest.mock('@backstage/plugin-catalog-react', () => ({ - useEntityList: jest.fn().mockReturnValue({ - loading: false, - entities: [ - { - apiVersion: 'scaffolder.backstage.io/v1beta3', - kind: 'Template', - metadata: { - name: 't1', - }, - spec: {}, - }, - { - apiVersion: 'scaffolder.backstage.io/v1beta3', - kind: 'Template', - metadata: { - name: 't2', - }, - spec: {}, - }, - ], - }), - getEntityRelations: jest.fn().mockImplementation(() => []), - getEntitySourceLocation: jest.fn().mockImplementation(() => ({})), -})); - -describe('TemplateList', () => { - const mockIntegrationsApi: Partial = { - byHost: () => ({ type: 'github' }), - }; - - it('should filter out templates based on provided filter condition', async () => { - const TemplateCardComponent = ({ - template, - }: { - template: TemplateEntityV1beta3; - }) => ( -
{template.metadata.name}
- ); - - await renderInTestApp( - -
- e.metadata.name === 't1'} - TemplateCardComponent={TemplateCardComponent} - /> -
-
, - { mountedRoutes: { '/': rootRouteRef } }, - ); - - expect(() => screen.getByTestId('t2')).toThrow(); - expect(screen.getByTestId('t1')).toBeDefined(); - }); -}); diff --git a/plugins/scaffolder/src/legacy/TemplateList/TemplateList.tsx b/plugins/scaffolder/src/legacy/TemplateList/TemplateList.tsx deleted file mode 100644 index c925cdf6ef..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateList/TemplateList.tsx +++ /dev/null @@ -1,114 +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 React, { ComponentType } from 'react'; -import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; -import { - isTemplateEntityV1beta3, - TemplateEntityV1beta3, -} from '@backstage/plugin-scaffolder-common'; -import { - Content, - ContentHeader, - ItemCardGrid, - Link, - Progress, - WarningPanel, -} from '@backstage/core-components'; -import { useEntityList } from '@backstage/plugin-catalog-react'; -import { Typography } from '@material-ui/core'; -import { TemplateCard } from '../TemplateCard'; - -/** - * @internal - */ -export type TemplateListProps = { - TemplateCardComponent?: - | ComponentType<{ template: TemplateEntityV1beta3 }> - | undefined; - group?: { - title?: React.ReactNode; - filter: (entity: TemplateEntityV1beta3) => boolean; - }; - templateFilter?: (entity: TemplateEntityV1beta3) => boolean; -}; - -/** - * @internal - */ -export const TemplateList = ({ - TemplateCardComponent, - group, - templateFilter, -}: TemplateListProps) => { - const { loading, error, entities } = useEntityList(); - const Card = TemplateCardComponent || TemplateCard; - const templateEntities = entities.filter(isTemplateEntityV1beta3); - const maybeFilteredEntities = ( - group ? templateEntities.filter(group.filter) : templateEntities - ).filter(e => (templateFilter ? templateFilter(e) : true)); - - const titleComponent: React.ReactNode = (() => { - if (group && group.title) { - if (typeof group.title === 'string') { - return ; - } - return group.title; - } - - return ; - })(); - - if (group && maybeFilteredEntities.length === 0) { - return null; - } - return ( - <> - {loading && } - - {error && ( - - {error.message} - - )} - - {!error && !loading && !entities.length && ( - - No templates found that match your filter. Learn more about{' '} - - adding templates - - . - - )} - - - {titleComponent} - - {maybeFilteredEntities && - maybeFilteredEntities?.length > 0 && - maybeFilteredEntities.map((template: Entity) => ( - - ))} - - - - ); -}; diff --git a/plugins/scaffolder/src/legacy/TemplateList/index.ts b/plugins/scaffolder/src/legacy/TemplateList/index.ts deleted file mode 100644 index 0b62f9cbb1..0000000000 --- a/plugins/scaffolder/src/legacy/TemplateList/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { TemplateList } from './TemplateList'; -export type { TemplateListProps } from './TemplateList'; diff --git a/plugins/scaffolder/src/legacy/TemplatePage/TemplatePage.test.tsx b/plugins/scaffolder/src/legacy/TemplatePage/TemplatePage.test.tsx deleted file mode 100644 index 344929fa43..0000000000 --- a/plugins/scaffolder/src/legacy/TemplatePage/TemplatePage.test.tsx +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright 2020 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 { - MockAnalyticsApi, - renderInTestApp, - TestApiRegistry, -} from '@backstage/test-utils'; -import { act, fireEvent, screen, within } from '@testing-library/react'; -import React from 'react'; -import { Route, Routes } from 'react-router-dom'; -import { - scaffolderApiRef, - ScaffolderApi, - SecretsContextProvider, -} from '@backstage/plugin-scaffolder-react'; -import { TemplatePage } from './TemplatePage'; -import { - featureFlagsApiRef, - FeatureFlagsApi, - analyticsApiRef, -} from '@backstage/core-plugin-api'; -import { ApiProvider } from '@backstage/core-app-api'; -import { errorApiRef } from '@backstage/core-plugin-api'; -import { rootRouteRef } from '../../routes'; - -jest.mock('react-router-dom', () => { - return { - ...(jest.requireActual('react-router-dom') as any), - useParams: () => ({ - templateName: 'test', - }), - }; -}); - -const scaffolderApiMock: jest.Mocked = { - cancelTask: jest.fn(), - scaffold: jest.fn(), - getTemplateParameterSchema: jest.fn(), - getIntegrationsList: jest.fn(), - getTask: jest.fn(), - streamLogs: jest.fn(), - listActions: jest.fn(), - listTasks: jest.fn(), -}; - -const featureFlagsApiMock: jest.Mocked = { - isActive: jest.fn(), - registerFlag: jest.fn(), - getRegisteredFlags: jest.fn(), - save: jest.fn(), -}; - -const errorApiMock = { post: jest.fn(), error$: jest.fn() }; - -const analyticsMock = new MockAnalyticsApi(); - -const schemaMockValue = { - title: 'my-schema', - steps: [ - { - title: 'Fill in some steps', - schema: { - title: 'Fill in some steps', - 'backstage:featureFlag': 'experimental-feature', - properties: { - name: { - title: 'Name', - type: 'string', - 'backstage:featureFlag': 'should-show-some-stuff-first-option', - }, - description: { - title: 'Description', - type: 'string', - description: 'A description for the component', - }, - owner: { - title: 'Owner', - type: 'string', - description: 'Owner of the component', - }, - }, - type: 'object', - }, - }, - { - title: 'Send data', - schema: { - title: 'Send data', - properties: { - user: { - title: 'User', - type: 'string', - }, - }, - type: 'object', - }, - }, - ], -}; - -const apis = TestApiRegistry.from( - [scaffolderApiRef, scaffolderApiMock], - [errorApiRef, errorApiMock], - [featureFlagsApiRef, featureFlagsApiMock], - [analyticsApiRef, analyticsMock], -); - -describe('TemplatePage', () => { - beforeEach(() => jest.resetAllMocks()); - - it('renders correctly', async () => { - scaffolderApiMock.getTemplateParameterSchema.mockResolvedValue({ - title: 'React SSR Template', - steps: [], - }); - const rendered = await renderInTestApp( - - - - - , - { - mountedRoutes: { - '/create': rootRouteRef, - }, - }, - ); - - expect(rendered.getByText('Create a New Component')).toBeInTheDocument(); - expect(rendered.getByText('React SSR Template')).toBeInTheDocument(); - }); - - it('renders spinner while loading', async () => { - let resolve: Function; - const promise = new Promise(res => { - resolve = res; - }); - scaffolderApiMock.getTemplateParameterSchema.mockReturnValueOnce(promise); - const rendered = await renderInTestApp( - - - - - , - { - mountedRoutes: { - '/create': rootRouteRef, - }, - }, - ); - - expect(rendered.getByText('Create a New Component')).toBeInTheDocument(); - expect(rendered.getByTestId('loading-progress')).toBeInTheDocument(); - - await act(async () => { - resolve!({ - title: 'React SSR Template', - steps: [], - }); - }); - }); - - it('captures expected analytics events', async () => { - scaffolderApiMock.scaffold.mockResolvedValue({ taskId: 'xyz' }); - scaffolderApiMock.getTemplateParameterSchema.mockResolvedValue({ - title: 'schema-4-analytics', - steps: [ - { - title: 'Fill in some steps', - schema: { - properties: { - name: { - title: 'Name', - type: 'string', - }, - }, - required: ['name'], - }, - }, - ], - }); - const { findByLabelText, findByText } = await renderInTestApp( - - - - - , - { - mountedRoutes: { - '/create': rootRouteRef, - }, - }, - ); - - // Fill out the name field - expect(await findByText('Fill in some steps')).toBeInTheDocument(); - fireEvent.change(await findByLabelText('Name', { exact: false }), { - target: { value: 'expected-name' }, - }); - - // Go to the final page - fireEvent.click(await findByText('Next step')); - expect(await findByText('Reset')).toBeInTheDocument(); - - // Create the software - await act(async () => { - fireEvent.click(await findByText('Create')); - }); - - // The "Next Step" button should have fired an event - expect(analyticsMock.getEvents()[0]).toMatchObject({ - action: 'click', - subject: 'Next Step (1)', - context: { entityRef: 'template:default/test' }, - }); - - // And the "Create" button should have fired an event - expect(analyticsMock.getEvents()[1]).toMatchObject({ - action: 'create', - subject: 'expected-name', - context: { entityRef: 'template:default/test' }, - }); - }); - - it('navigates away if no template was loaded', async () => { - scaffolderApiMock.getTemplateParameterSchema.mockResolvedValue( - undefined as any, - ); - - const rendered = await renderInTestApp( - - - - - - } - /> - This is root} /> - - , - { - routeEntries: ['/create'], - mountedRoutes: { '/create': rootRouteRef }, - }, - ); - - expect( - rendered.queryByText('Create a New Component'), - ).not.toBeInTheDocument(); - expect(rendered.getByText('This is root')).toBeInTheDocument(); - }); - - it('display template with oneOf', async () => { - scaffolderApiMock.getTemplateParameterSchema.mockResolvedValue({ - title: 'my-schema', - steps: [ - { - title: 'Fill in some steps', - schema: { - oneOf: [ - { - title: 'First', - properties: { - name: { - title: 'Name', - type: 'string', - }, - }, - required: ['name'], - }, - { - title: 'Second', - properties: { - something: { - title: 'Something', - type: 'string', - }, - }, - required: ['something'], - }, - ], - }, - }, - ], - }); - - const { findByText, findByLabelText, findAllByRole, findByRole } = - await renderInTestApp( - - - - - , - { - mountedRoutes: { - '/create/actions': rootRouteRef, - }, - }, - ); - - expect(await findByText('Fill in some steps')).toBeInTheDocument(); - - // Fill the first option - fireEvent.change(await findByLabelText('Name', { exact: false }), { - target: { value: 'my-name' }, - }); - - // Switch to second option - fireEvent.mouseDown((await findAllByRole('button'))[0]); - const listbox = within(await findByRole('listbox')); - fireEvent.click(listbox.getByText(/Second/i)); - - // Fill the second option - fireEvent.change(await findByLabelText('Something', { exact: false }), { - target: { value: 'my-something' }, - }); - - // Go to the final page - fireEvent.click(await findByText('Next step')); - expect(await findByText('Reset')).toBeInTheDocument(); - }); - - it('should display a section or property based on a feature flag', async () => { - featureFlagsApiMock.isActive.mockImplementation(flag => { - return flag === 'experimental-feature'; - }); - scaffolderApiMock.getTemplateParameterSchema.mockResolvedValue( - schemaMockValue, - ); - - await renderInTestApp( - - - - - , - { - mountedRoutes: { - '/create/actions': rootRouteRef, - }, - }, - ); - - expect(screen.queryByText('Name')).not.toBeInTheDocument(); - expect(screen.getByText('Description')).toBeInTheDocument(); - expect(screen.getByText('Owner')).toBeInTheDocument(); - expect(screen.getByText('Send data')).toBeInTheDocument(); - }); -}); diff --git a/plugins/scaffolder/src/legacy/TemplatePage/TemplatePage.tsx b/plugins/scaffolder/src/legacy/TemplatePage/TemplatePage.tsx deleted file mode 100644 index ffb754bae3..0000000000 --- a/plugins/scaffolder/src/legacy/TemplatePage/TemplatePage.tsx +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright 2020 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 { LinearProgress } from '@material-ui/core'; -import { IChangeEvent } from '@rjsf/core'; -import qs from 'qs'; -import React, { ComponentType, useCallback, useState } from 'react'; -import { Navigate, useNavigate } from 'react-router-dom'; -import useAsync from 'react-use/lib/useAsync'; -import { - type LayoutOptions, - scaffolderApiRef, - useTemplateSecrets, - ReviewStepProps, -} from '@backstage/plugin-scaffolder-react'; -import { MultistepJsonForm } from '../MultistepJsonForm'; -import { createValidator } from './createValidator'; - -import { Content, Header, InfoCard, Page } from '@backstage/core-components'; -import { - AnalyticsContext, - errorApiRef, - useApi, - useApiHolder, - useRouteRef, - useRouteRefParams, -} from '@backstage/core-plugin-api'; -import { stringifyEntityRef } from '@backstage/catalog-model'; -import { - rootRouteRef, - scaffolderTaskRouteRef, - selectedTemplateRouteRef, -} from '../../routes'; -import { LegacyFieldExtensionOptions } from '@backstage/plugin-scaffolder-react/alpha'; - -const useTemplateParameterSchema = (templateRef: string) => { - const scaffolderApi = useApi(scaffolderApiRef); - const { value, loading, error } = useAsync( - () => scaffolderApi.getTemplateParameterSchema(templateRef), - [scaffolderApi, templateRef], - ); - return { schema: value, loading, error }; -}; - -type Props = { - ReviewStepComponent?: ComponentType; - customFieldExtensions?: LegacyFieldExtensionOptions[]; - layouts?: LayoutOptions[]; - headerOptions?: { - pageTitleOverride?: string; - title?: string; - subtitle?: string; - }; -}; - -export const TemplatePage = ({ - ReviewStepComponent, - customFieldExtensions = [], - layouts = [], - headerOptions, -}: Props) => { - const apiHolder = useApiHolder(); - const secretsContext = useTemplateSecrets(); - const errorApi = useApi(errorApiRef); - const scaffolderApi = useApi(scaffolderApiRef); - const { templateName, namespace } = useRouteRefParams( - selectedTemplateRouteRef, - ); - const templateRef = stringifyEntityRef({ - name: templateName, - kind: 'template', - namespace, - }); - const navigate = useNavigate(); - const scaffolderTaskRoute = useRouteRef(scaffolderTaskRouteRef); - const rootRoute = useRouteRef(rootRouteRef); - const { schema, loading, error } = useTemplateParameterSchema(templateRef); - const [formState, setFormState] = useState>(() => { - const query = qs.parse(window.location.search, { - ignoreQueryPrefix: true, - }); - - try { - return JSON.parse(query.formData as string); - } catch (e) { - return query.formData ?? {}; - } - }); - const handleFormReset = () => setFormState({}); - const handleChange = useCallback( - (e: IChangeEvent) => setFormState(e.formData), - [setFormState], - ); - - const handleCreate = async () => { - const { taskId } = await scaffolderApi.scaffold({ - templateRef, - values: formState, - secrets: secretsContext?.secrets, - }); - - const formParams = qs.stringify( - { formData: formState }, - { addQueryPrefix: true }, - ); - const newUrl = `${window.location.pathname}${formParams}`; - // We use direct history manipulation since useSearchParams and - // useNavigate in react-router-dom cause unnecessary extra rerenders. - // Also make sure to replace the state rather than pushing to avoid - // extra back/forward slots. - window.history?.replaceState(null, document.title, newUrl); - - navigate(scaffolderTaskRoute({ taskId })); - }; - - if (error) { - errorApi.post(new Error(`Failed to load template, ${error}`)); - return ; - } - if (!loading && !schema) { - errorApi.post(new Error('Template was not found.')); - return ; - } - - const customFieldComponents = Object.fromEntries( - customFieldExtensions.map(({ name, component }) => [name, component]), - ); - - const customFieldValidators = Object.fromEntries( - customFieldExtensions.map(({ name, validation }) => [name, validation]), - ); - - return ( - - -
- - {loading && } - {schema && ( - - { - return { - ...step, - validate: createValidator( - step.schema, - customFieldValidators, - { apiHolder }, - ), - }; - })} - /> - - )} - - - - ); -}; diff --git a/plugins/scaffolder/src/legacy/TemplatePage/createValidator.test.ts b/plugins/scaffolder/src/legacy/TemplatePage/createValidator.test.ts deleted file mode 100644 index d6a5cd7499..0000000000 --- a/plugins/scaffolder/src/legacy/TemplatePage/createValidator.test.ts +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { createValidator } from './createValidator'; -import { LegacyCustomFieldValidator } from '@backstage/plugin-scaffolder-react/alpha'; -import { ApiHolder } from '@backstage/core-plugin-api'; -import { FieldValidation, FormValidation } from '@rjsf/utils'; - -type CustomLinkType = { - url: string; - title: string; - icon: string; -}; - -describe('createValidator', () => { - const validators: Record< - string, - undefined | LegacyCustomFieldValidator - > = { - CustomPicker: ( - value: unknown, - fieldValidation: FieldValidation, - _context: { apiHolder: ApiHolder }, - ) => { - if (!value || !(value as { value?: unknown }).value) { - fieldValidation.addError('Error !'); - } - }, - CustomLink: ( - values: unknown, - fieldValidation: FieldValidation, - _context: { apiHolder: ApiHolder }, - ) => { - const input = values as CustomLinkType[]; - for (const item of input) { - const validGitlabUrlRegex = - /gitlab\.(?:stg\.)?spotify\.com\?owner=.*&repo=.*/; - - if (!item || !validGitlabUrlRegex.test(item.url)) { - fieldValidation.addError( - `Make sure to put in a valid gitlab clone url.`, - ); - } - } - }, - TagPicker: ( - values: unknown, - fieldValidation: FieldValidation, - _context: { apiHolder: ApiHolder }, - ) => { - const input = values as string[]; - for (const item of input) { - if (!/^[a-z0-9-]+$/.test(item)) { - fieldValidation.addError( - 'A tag name can only contain lowercase letters, numeric characters or dashes', - ); - } - } - }, - }; - - const apiHolderMock: jest.Mocked = { - get: jest.fn().mockImplementation(() => { - return null; - }), - }; - - const context = { - apiHolder: apiHolderMock, - }; - - it('should call validator for object property from a custom field extension', () => { - /* GIVEN */ - const rootSchema = { - title: 'Title', - properties: { - p1: { - title: 'PropertyOn', - type: 'object', - 'ui:field': 'CustomPicker', - }, - }, - }; - const validator = createValidator(rootSchema, validators, context); - - const formData = { - p1: {}, - }; - const errors = { - addError: jest.fn(), - p1: { - addError: jest.fn(), - } as unknown as FormValidation, - } as unknown as FormValidation; - - /* WHEN */ - const result = validator(formData, errors); - - /* THEN */ - expect(result).not.toBeNull(); - expect(result.p1?.addError).toHaveBeenCalledTimes(1); - }); - - it('should call validator for array property from a custom field extension', () => { - /* GIVEN */ - const rootSchema = { - title: 'My form', - properties: { - tags: { - title: 'Tags', - type: 'array', - items: { - type: 'string', - 'ui:field': 'TagPicker', - }, - }, - }, - }; - const validator = createValidator(rootSchema, validators, context); - - const formData = { - tags: ['invalid-tag$$'], - }; - const errors = { - addError: jest.fn(), - tags: { - addError: jest.fn(), - } as unknown as FormValidation, - } as unknown as FormValidation; - - /* WHEN */ - const result = validator(formData, errors); - - /* THEN */ - expect(result).not.toBeNull(); - expect(result.tags?.addError).toHaveBeenCalledTimes(1); - }); - - it('should call validator for array object property from a custom field extension', () => { - /* GIVEN */ - const rootSchema = { - title: 'My links', - properties: { - links: { - title: 'Links', - type: 'array', - items: { - type: 'object', - required: ['url', 'title', 'icon'], - properties: { - url: { - title: 'url', - description: 'url', - type: 'object', - 'ui:field': 'CustomLink', - }, - }, - }, - }, - }, - }; - const validator = createValidator(rootSchema, validators, context); - - const formData = { - links: [ - { - url: 'http://gitlab.spotify.nl/owener=me&repo=test', - icon: 'subject', - title: 'My repository for testing features', - } as CustomLinkType, - ], - }; - const errors = { - addError: jest.fn(), - links: { - addError: jest.fn(), - } as unknown as FormValidation, - } as unknown as FormValidation; - - /* WHEN */ - const result = validator(formData, errors); - - /* THEN */ - expect(result).not.toBeNull(); - expect(result.links?.addError).toHaveBeenCalledTimes(1); - }); -}); diff --git a/plugins/scaffolder/src/legacy/TemplatePage/createValidator.ts b/plugins/scaffolder/src/legacy/TemplatePage/createValidator.ts deleted file mode 100644 index ae0b834fe9..0000000000 --- a/plugins/scaffolder/src/legacy/TemplatePage/createValidator.ts +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { LegacyCustomFieldValidator } from '@backstage/plugin-scaffolder-react/alpha'; -import { FieldValidation, FormValidation } from '@rjsf/utils'; -import { JsonObject, JsonValue } from '@backstage/types'; -import { ApiHolder } from '@backstage/core-plugin-api'; - -function isObject(obj: unknown): obj is JsonObject { - return typeof obj === 'object' && obj !== null && !Array.isArray(obj); -} - -function isArray(obj: unknown): obj is JsonObject { - return typeof obj === 'object' && obj !== null && Array.isArray(obj); -} - -export const createValidator = ( - rootSchema: JsonObject, - validators: Record>, - context: { - apiHolder: ApiHolder; - }, -) => { - function validate( - schema: JsonObject, - formData: JsonObject, - errors: FormValidation, - ) { - const schemaProps = schema.properties; - const customObject = schema.type === 'object' && schemaProps === undefined; - - if (!isObject(schemaProps) && !customObject) { - return; - } - - if (schemaProps) { - for (const [key, propData] of Object.entries(formData)) { - const propValidation = errors[key]; - - const doValidate = (item: JsonValue | undefined) => { - if (item && isObject(item)) { - const fieldName = item['ui:field'] as string; - if (fieldName && typeof validators[fieldName] === 'function') { - validators[fieldName]!( - propData as JsonObject[], - propValidation as FieldValidation, - context, - ); - } - } - }; - - const propSchemaProps = schemaProps[key]; - if (isObject(propData) && isObject(propSchemaProps)) { - validate( - propSchemaProps, - propData as JsonObject, - propValidation as FormValidation, - ); - } else if (isArray(propData)) { - if (isObject(propSchemaProps)) { - const { items } = propSchemaProps; - if (isObject(items)) { - if (items.type === 'object') { - const properties = (items?.properties ?? []) as JsonObject[]; - for (const [, value] of Object.entries(properties)) { - doValidate(value); - } - } else { - doValidate(items); - } - } - } - } else { - doValidate(propSchemaProps); - } - } - } else if (customObject) { - const fieldName = schema['ui:field'] as string; - if (fieldName && typeof validators[fieldName] === 'function') { - validators[fieldName]!(formData, errors, context); - } - } - } - - return (formData: JsonObject, errors: FormValidation) => { - validate(rootSchema, formData, errors); - return errors; - }; -}; diff --git a/plugins/scaffolder/src/legacy/TemplatePage/index.ts b/plugins/scaffolder/src/legacy/TemplatePage/index.ts deleted file mode 100644 index d3ae24504b..0000000000 --- a/plugins/scaffolder/src/legacy/TemplatePage/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { TemplatePage } from './TemplatePage'; -export { createValidator } from './createValidator'; diff --git a/plugins/scaffolder/src/legacy/index.ts b/plugins/scaffolder/src/legacy/index.ts deleted file mode 100644 index 2393be0f69..0000000000 --- a/plugins/scaffolder/src/legacy/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { LegacyRouter, type LegacyRouterProps } from './Router'; -export { LegacyScaffolderPage } from '../plugin'; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx index 68ed6f906f..fb69dabe13 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx +++ b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/DryRunResultsView.tsx @@ -27,8 +27,8 @@ import React, { useEffect, useMemo, useState } from 'react'; import { useDryRun } from '../DryRunContext'; import { DryRunResultsSplitView } from './DryRunResultsSplitView'; import { FileBrowser } from '../../../components/FileBrowser'; -import { TaskPageLinks } from '../../../legacy/TaskPage/TaskPageLinks'; -import { TaskStatusStepper } from '../../../legacy/TaskPage/TaskPage'; +import { TaskPageLinks } from './TaskPageLinks'; +import { TaskStatusStepper } from './TaskStatusStepper'; const useStyles = makeStyles({ root: { diff --git a/plugins/scaffolder/src/legacy/TaskPage/IconLink.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/IconLink.tsx similarity index 97% rename from plugins/scaffolder/src/legacy/TaskPage/IconLink.tsx rename to plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/IconLink.tsx index dd0b3da876..6676c622fa 100644 --- a/plugins/scaffolder/src/legacy/TaskPage/IconLink.tsx +++ b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/IconLink.tsx @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Backstage Authors + * Copyright 2024 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - import React from 'react'; import { Grid, LinkProps, makeStyles, Typography } from '@material-ui/core'; import LanguageIcon from '@material-ui/icons/Language'; diff --git a/plugins/scaffolder/src/legacy/TaskPage/TaskPageLinks.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx similarity index 100% rename from plugins/scaffolder/src/legacy/TaskPage/TaskPageLinks.tsx rename to plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx new file mode 100644 index 0000000000..f776d133e0 --- /dev/null +++ b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx @@ -0,0 +1,199 @@ +/* + * Copyright 2024 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 React, { useState } from 'react'; +import { memo } from 'react'; +import Step from '@material-ui/core/Step'; +import StepLabel from '@material-ui/core/StepLabel'; +import Stepper from '@material-ui/core/Stepper'; +import { ScaffolderTaskStatus } from '@backstage/plugin-scaffolder-react'; +import { + StepButton, + StepIconProps, + Theme, + createStyles, + makeStyles, + CircularProgress, +} from '@material-ui/core'; +import Cancel from '@material-ui/icons/Cancel'; +import Check from '@material-ui/icons/Check'; +import FiberManualRecordIcon from '@material-ui/icons/FiberManualRecord'; +import Typography from '@material-ui/core/Typography'; +import { DateTime, Interval } from 'luxon'; +import useInterval from 'react-use/lib/useInterval'; +import humanizeDuration from 'humanize-duration'; +import classNames from 'classnames'; + +const useStyles = makeStyles((theme: Theme) => + createStyles({ + root: { + width: '100%', + }, + button: { + marginBottom: theme.spacing(2), + marginLeft: theme.spacing(2), + }, + actionsContainer: { + marginBottom: theme.spacing(2), + }, + resetContainer: { + padding: theme.spacing(3), + }, + labelWrapper: { + display: 'flex', + flex: 1, + flexDirection: 'row', + justifyContent: 'space-between', + }, + stepWrapper: { + width: '100%', + }, + }), +); + +type TaskStep = { + id: string; + name: string; + status: ScaffolderTaskStatus; + startedAt?: string; + endedAt?: string; +}; + +const useStepIconStyles = makeStyles(theme => + createStyles({ + root: { + color: theme.palette.text.disabled, + display: 'flex', + height: 22, + alignItems: 'center', + }, + completed: { + color: theme.palette.status.ok, + }, + error: { + color: theme.palette.status.error, + }, + }), +); + +const StepTimeTicker = ({ step }: { step: TaskStep }) => { + const [time, setTime] = useState(''); + + useInterval(() => { + if (!step.startedAt) { + setTime(''); + return; + } + + const end = step.endedAt + ? DateTime.fromISO(step.endedAt) + : DateTime.local(); + + const startedAt = DateTime.fromISO(step.startedAt); + const formatted = Interval.fromDateTimes(startedAt, end) + .toDuration() + .valueOf(); + + setTime(humanizeDuration(formatted, { round: true })); + }, 1000); + + return {time}; +}; + +function TaskStepIconComponent(props: StepIconProps) { + const classes = useStepIconStyles(); + const { active, completed, error } = props; + + const getMiddle = () => { + if (active) { + return ; + } + if (completed) { + return ; + } + if (error) { + return ; + } + return ; + }; + + return ( +
+ {getMiddle()} +
+ ); +} + +export const TaskStatusStepper = memo( + (props: { + steps: TaskStep[]; + currentStepId: string | undefined; + onUserStepChange: (id: string) => void; + classes?: { + root?: string; + }; + }) => { + const { steps, currentStepId, onUserStepChange } = props; + const classes = useStyles(props); + + return ( +
+ s.id === currentStepId)} + orientation="vertical" + nonLinear + > + {steps.map((step, index) => { + const isCancelled = step.status === 'cancelled'; + const isActive = step.status === 'processing'; + const isCompleted = step.status === 'completed'; + const isFailed = step.status === 'failed'; + const isSkipped = step.status === 'skipped'; + + return ( + + onUserStepChange(step.id)}> + +
+ {step.name} + {isSkipped ? ( + Skipped + ) : ( + + )} +
+
+
+
+ ); + })} +
+
+ ); + }, +); diff --git a/plugins/scaffolder/src/plugin.tsx b/plugins/scaffolder/src/plugin.tsx index fdde81695d..7fa7dc1521 100644 --- a/plugins/scaffolder/src/plugin.tsx +++ b/plugins/scaffolder/src/plugin.tsx @@ -212,15 +212,3 @@ export const EntityTagsPickerFieldExtension = scaffolderPlugin.provide( schema: EntityTagsPickerSchema, }), ); - -/** - * @alpha - * The Router and main entrypoint to the Alpha Scaffolder plugin. - */ -export const LegacyScaffolderPage = scaffolderPlugin.provide( - createRoutableExtension({ - name: 'LegacyScaffolderPage', - component: () => import('./legacy/Router').then(m => m.LegacyRouter), - mountPoint: rootRouteRef, - }), -); From 4cca1bd66b82cdcd6af05d183aad5d0747734182 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 17 Jan 2024 14:18:31 +0100 Subject: [PATCH 264/283] chore: api-reports Signed-off-by: blam --- plugins/scaffolder-react/api-report-alpha.md | 45 -------------------- 1 file changed, 45 deletions(-) diff --git a/plugins/scaffolder-react/api-report-alpha.md b/plugins/scaffolder-react/api-report-alpha.md index 615b54df84..6976951670 100644 --- a/plugins/scaffolder-react/api-report-alpha.md +++ b/plugins/scaffolder-react/api-report-alpha.md @@ -7,11 +7,8 @@ import { ApiHolder } from '@backstage/core-plugin-api'; import { ComponentType } from 'react'; -import { CustomFieldExtensionSchema } from '@backstage/plugin-scaffolder-react'; import { CustomFieldValidator } from '@backstage/plugin-scaffolder-react'; import { Dispatch } from 'react'; -import { Extension } from '@backstage/core-plugin-api'; -import { FieldExtensionComponent } from '@backstage/plugin-scaffolder-react'; import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; import { FieldValidation } from '@rjsf/utils'; import { FormProps } from '@backstage/plugin-scaffolder-react'; @@ -24,7 +21,6 @@ import { default as React_2 } from 'react'; import { ReactElement } from 'react'; import { ReactNode } from 'react'; import { ReviewStepProps } from '@backstage/plugin-scaffolder-react'; -import { ScaffolderRJSFFieldProps } from '@backstage/plugin-scaffolder-react'; import { ScaffolderRJSFFormProps } from '@backstage/plugin-scaffolder-react'; import { ScaffolderStep } from '@backstage/plugin-scaffolder-react'; import { ScaffolderTaskOutput } from '@backstage/plugin-scaffolder-react'; @@ -51,14 +47,6 @@ export const createAsyncValidators: ( // @alpha export const createFieldValidation: () => FieldValidation; -// @alpha -export function createLegacyScaffolderFieldExtension< - TReturnValue = unknown, - TInputProps = unknown, ->( - options: LegacyFieldExtensionOptions, -): Extension>; - // @alpha export const DefaultTemplateOutputs: (props: { output?: ScaffolderTaskOutput; @@ -83,39 +71,6 @@ export type FormValidation = { [name: string]: FieldValidation | FormValidation; }; -// @alpha -export type LegacyCustomFieldValidator = ( - data: TFieldReturnValue, - field: FieldValidation, - context: { - apiHolder: ApiHolder; - }, -) => void | Promise; - -// @alpha -export interface LegacyFieldExtensionComponentProps< - TFieldReturnValue, - TUiOptions = unknown, -> extends ScaffolderRJSFFieldProps { - // (undocumented) - uiSchema: ScaffolderRJSFFieldProps['uiSchema'] & { - 'ui:options'?: TUiOptions; - }; -} - -// @alpha -export type LegacyFieldExtensionOptions< - TFieldReturnValue = unknown, - TInputProps = unknown, -> = { - name: string; - component: ( - props: LegacyFieldExtensionComponentProps, - ) => JSX.Element | null; - validation?: LegacyCustomFieldValidator; - schema?: CustomFieldExtensionSchema; -}; - // @alpha export interface ParsedTemplateSchema { // (undocumented) From c56f1a2e90ee4e0f2e2d1c3fa9152db8e0c96e99 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 17 Jan 2024 14:19:16 +0100 Subject: [PATCH 265/283] chore: added changeset Signed-off-by: blam --- .changeset/fast-jeans-walk.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/fast-jeans-walk.md diff --git a/.changeset/fast-jeans-walk.md b/.changeset/fast-jeans-walk.md new file mode 100644 index 0000000000..f733c9f464 --- /dev/null +++ b/.changeset/fast-jeans-walk.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder-react': minor +'@backstage/plugin-scaffolder': minor +--- + +Remove the old legacy exports from `/alpha` From 73d7e2c6f9e6cdae234e9c81522732b6d302e166 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 17 Jan 2024 16:19:51 +0100 Subject: [PATCH 266/283] chore: fix tsdoc Signed-off-by: blam Signed-off-by: blam --- plugins/scaffolder/src/deprecated.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scaffolder/src/deprecated.ts b/plugins/scaffolder/src/deprecated.ts index ffe923058b..907871946c 100644 --- a/plugins/scaffolder/src/deprecated.ts +++ b/plugins/scaffolder/src/deprecated.ts @@ -215,10 +215,10 @@ export type LayoutOptions = LayoutOptionsTemp; /** * TaskPageProps for constructing a TaskPage - * @param loadingText - Optional loading text shown before a task begins executing. * @public * @deprecated - this is a useless type that is no longer used. */ export type TaskPageProps = { + // Optional loading text shown before a task begins executing. loadingText?: string; }; From dbbfb664f8856b4055f22eed42722a6395a25e66 Mon Sep 17 00:00:00 2001 From: blam Date: Fri, 19 Jan 2024 10:12:33 +0100 Subject: [PATCH 267/283] chore: fixing rebase issues Signed-off-by: blam --- plugins/scaffolder/api-report-alpha.md | 40 -------------------------- plugins/scaffolder/src/alpha.tsx | 2 -- 2 files changed, 42 deletions(-) diff --git a/plugins/scaffolder/api-report-alpha.md b/plugins/scaffolder/api-report-alpha.md index c8824d42da..3f0b60cd95 100644 --- a/plugins/scaffolder/api-report-alpha.md +++ b/plugins/scaffolder/api-report-alpha.md @@ -3,19 +3,13 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -/// - import { BackstagePlugin } from '@backstage/frontend-plugin-api'; -import { ComponentType } from 'react'; -import { Entity } from '@backstage/catalog-model'; import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; import type { FormProps as FormProps_2 } from '@rjsf/core'; import { FormProps as FormProps_3 } from '@backstage/plugin-scaffolder-react'; -import { JSX as JSX_2 } from 'react'; import { LayoutOptions } from '@backstage/plugin-scaffolder-react'; import { PathParams } from '@backstage/core-plugin-api'; -import { PropsWithChildren } from 'react'; import { default as React_2 } from 'react'; import { ReviewStepProps } from '@backstage/plugin-scaffolder-react'; import { RouteRef } from '@backstage/frontend-plugin-api'; @@ -55,40 +49,6 @@ export type FormProps = Pick< 'transformErrors' | 'noHtml5Validate' >; -// @alpha -export const LegacyRouter: (props: LegacyRouterProps) => React_2.JSX.Element; - -// @alpha -export type LegacyRouterProps = { - components?: { - ReviewStepComponent?: ComponentType; - TemplateCardComponent?: - | ComponentType<{ - template: TemplateEntityV1beta3; - }> - | undefined; - TaskPageComponent?: ComponentType>; - }; - groups?: Array<{ - title?: React_2.ReactNode; - filter: (entity: Entity) => boolean; - }>; - templateFilter?: (entity: TemplateEntityV1beta3) => boolean; - defaultPreviewTemplate?: string; - headerOptions?: { - pageTitleOverride?: string; - title?: string; - subtitle?: string; - }; - contextMenu?: { - editor?: boolean; - actions?: boolean; - }; -}; - -// @alpha -export const LegacyScaffolderPage: (props: LegacyRouterProps) => JSX_2.Element; - // @alpha (undocumented) export type TemplateListPageProps = { TemplateCardComponent?: React_2.ComponentType<{ diff --git a/plugins/scaffolder/src/alpha.tsx b/plugins/scaffolder/src/alpha.tsx index 152745eec1..0d079f9c40 100644 --- a/plugins/scaffolder/src/alpha.tsx +++ b/plugins/scaffolder/src/alpha.tsx @@ -50,8 +50,6 @@ export { type TemplateWizardPageProps, } from './next'; -export * from './legacy'; - const scaffolderApi = createApiExtension({ factory: createApiFactory({ api: scaffolderApiRef, From 7c88d8f49bc84a3292a1cc89a920cff42a0f64d7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:23:08 +0000 Subject: [PATCH 268/283] chore(deps): update dependency @types/node to v16.18.72 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9ecf43baa9..5496b78a2e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18370,9 +18370,9 @@ __metadata: linkType: hard "@types/node@npm:^16.11.26, @types/node@npm:^16.7.10, @types/node@npm:^16.9.2": - version: 16.18.71 - resolution: "@types/node@npm:16.18.71" - checksum: 7b61ec0abd2a298518b562618ddbcc1704a6427c666c9512a0b12700a2b26cad151ccfd3c147c9ab77ac5e0bcb62bfbf67c48fa0ef812a00859a1e33368e8802 + version: 16.18.72 + resolution: "@types/node@npm:16.18.72" + checksum: c0f1748b20566417d3b777d11962f84500b4cb9c77ebb59c51f2882c3e5141bd4636709dc63fe2e45d6d6799fc4c5a98931abcb2dd3a5b107e448d76ae848320 languageName: node linkType: hard From a8c4290ac62556a288cac93aa5c79f2f7751156e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:23:48 +0000 Subject: [PATCH 269/283] fix(deps): update dependency react-hook-form to v7.49.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9ecf43baa9..55a291eff6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -38311,11 +38311,11 @@ __metadata: linkType: hard "react-hook-form@npm:^7.12.2, react-hook-form@npm:^7.13.0": - version: 7.48.2 - resolution: "react-hook-form@npm:7.48.2" + version: 7.49.3 + resolution: "react-hook-form@npm:7.49.3" peerDependencies: react: ^16.8.0 || ^17 || ^18 - checksum: 39652d08f78f16e5234049ceeb794d8bcd4d146772aca99c6db8c5aea8926cd4a230d02098886a441074deefbc24ffcb5ed57bc7cb0009d950115f5b3e627f12 + checksum: 9769845e2749f5c9d1d033be3819bc572ffa67f19ec2e567c61a58d0d060107facdf8425aab253c2e667c00853b7706a50bd6739fca6228c284c9313420ca26f languageName: node linkType: hard From 7155c30a889b5f8ff45b6d401ee491b98e9ec33f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 19 Jan 2024 11:17:56 +0100 Subject: [PATCH 270/283] core-compat-api: added convertLegacyRouteRefs Signed-off-by: Patrik Oldsberg --- .changeset/olive-singers-accept.md | 5 +++ packages/core-compat-api/api-report.md | 21 +++++++++++ .../src/convertLegacyRouteRef.ts | 37 +++++++++++++++++++ packages/core-compat-api/src/index.ts | 6 ++- 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 .changeset/olive-singers-accept.md diff --git a/.changeset/olive-singers-accept.md b/.changeset/olive-singers-accept.md new file mode 100644 index 0000000000..7e8cf7ae8d --- /dev/null +++ b/.changeset/olive-singers-accept.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-compat-api': patch +--- + +Added `convertLegacyRouteRefs` for bulk conversion of plugin routes. diff --git a/packages/core-compat-api/api-report.md b/packages/core-compat-api/api-report.md index 494747be60..a7aae2b5b9 100644 --- a/packages/core-compat-api/api-report.md +++ b/packages/core-compat-api/api-report.md @@ -40,5 +40,26 @@ export function convertLegacyRouteRef< ref: ExternalRouteRef, ): ExternalRouteRef_2; +// @public +export function convertLegacyRouteRefs< + TRefs extends { + [name in string]: RouteRef | SubRouteRef | ExternalRouteRef; + }, +>( + refs: TRefs, +): { + [KName in keyof TRefs]: ToNewRouteRef; +}; + +// @public +export type ToNewRouteRef = + T extends RouteRef + ? RouteRef_2 + : T extends SubRouteRef + ? SubRouteRef_2 + : T extends ExternalRouteRef + ? ExternalRouteRef_2 + : never; + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/core-compat-api/src/convertLegacyRouteRef.ts b/packages/core-compat-api/src/convertLegacyRouteRef.ts index c5ee603722..36311dc081 100644 --- a/packages/core-compat-api/src/convertLegacyRouteRef.ts +++ b/packages/core-compat-api/src/convertLegacyRouteRef.ts @@ -40,6 +40,43 @@ import { toInternalSubRouteRef } from '../../frontend-plugin-api/src/routing/Sub // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { toInternalExternalRouteRef } from '../../frontend-plugin-api/src/routing/ExternalRouteRef'; +/** + * Converts a legacy route ref type to the new system. + * + * @public + */ +export type ToNewRouteRef< + T extends LegacyRouteRef | LegacySubRouteRef | LegacyExternalRouteRef, +> = T extends LegacyRouteRef + ? RouteRef + : T extends LegacySubRouteRef + ? SubRouteRef + : T extends LegacyExternalRouteRef + ? ExternalRouteRef + : never; + +/** + * Converts a collection of legacy route refs to the new system. + * This is particularly useful when defining plugin `routes` and `externalRoutes`. + * + * @public + */ +export function convertLegacyRouteRefs< + TRefs extends { + [name in string]: + | LegacyRouteRef + | LegacySubRouteRef + | LegacyExternalRouteRef; + }, +>(refs: TRefs): { [KName in keyof TRefs]: ToNewRouteRef } { + return Object.fromEntries( + Object.entries(refs).map(([name, ref]) => [ + name, + convertLegacyRouteRef(ref as LegacyRouteRef), + ]), + ) as { [KName in keyof TRefs]: ToNewRouteRef }; +} + /** * A temporary helper to convert a legacy route ref to the new system. * diff --git a/packages/core-compat-api/src/index.ts b/packages/core-compat-api/src/index.ts index 68e5d9cf19..b632bf8a57 100644 --- a/packages/core-compat-api/src/index.ts +++ b/packages/core-compat-api/src/index.ts @@ -16,4 +16,8 @@ export * from './compatWrapper'; export { convertLegacyApp } from './convertLegacyApp'; -export { convertLegacyRouteRef } from './convertLegacyRouteRef'; +export { + convertLegacyRouteRef, + convertLegacyRouteRefs, + type ToNewRouteRef, +} from './convertLegacyRouteRef'; From 2f2a1d2ad24a5c9ff5a613e9e7abdad6b0102c4d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 19 Jan 2024 11:19:43 +0100 Subject: [PATCH 271/283] core-compat-api: forward routes to converted plugins Signed-off-by: Patrik Oldsberg --- .changeset/twenty-taxis-mate.md | 5 +++++ packages/core-compat-api/src/collectLegacyRoutes.tsx | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .changeset/twenty-taxis-mate.md diff --git a/.changeset/twenty-taxis-mate.md b/.changeset/twenty-taxis-mate.md new file mode 100644 index 0000000000..ab3cc6d406 --- /dev/null +++ b/.changeset/twenty-taxis-mate.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-compat-api': patch +--- + +Plugins converted by `convertLegacyApp` now have their `routes` and `externalRoutes` included as well, allowing the to be used to bind external routes in configuration. diff --git a/packages/core-compat-api/src/collectLegacyRoutes.tsx b/packages/core-compat-api/src/collectLegacyRoutes.tsx index 4d560b81d5..7ddb8c4f7e 100644 --- a/packages/core-compat-api/src/collectLegacyRoutes.tsx +++ b/packages/core-compat-api/src/collectLegacyRoutes.tsx @@ -32,7 +32,10 @@ import { } from '@backstage/frontend-plugin-api'; import React, { Children, ReactNode, isValidElement } from 'react'; import { Route, Routes } from 'react-router-dom'; -import { convertLegacyRouteRef } from './convertLegacyRouteRef'; +import { + convertLegacyRouteRef, + convertLegacyRouteRefs, +} from './convertLegacyRouteRef'; import { compatWrapper } from './compatWrapper'; /* @@ -244,6 +247,8 @@ export function collectLegacyRoutes( createApiExtension({ factory }), ), ], + routes: convertLegacyRouteRefs(plugin.routes ?? {}), + externalRoutes: convertLegacyRouteRefs(plugin.externalRoutes ?? {}), }), ); } From 912ca7b583e01884638bff04859cd4d2871e0eac Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 19 Jan 2024 11:20:39 +0100 Subject: [PATCH 272/283] plugins: use convertLegacyRouteRefs Signed-off-by: Patrik Oldsberg --- .changeset/hot-pillows-poke.md | 11 +++++++++++ plugins/catalog/src/alpha/plugin.tsx | 22 +++++++++++----------- plugins/graphiql/src/alpha.tsx | 7 ++++--- plugins/scaffolder/src/alpha.tsx | 25 +++++++++++++------------ plugins/search/src/alpha.tsx | 7 ++++--- plugins/tech-radar/src/alpha.tsx | 7 ++++--- plugins/techdocs/src/alpha.tsx | 11 ++++++----- plugins/user-settings/src/alpha.tsx | 7 ++++--- 8 files changed, 57 insertions(+), 40 deletions(-) create mode 100644 .changeset/hot-pillows-poke.md diff --git a/.changeset/hot-pillows-poke.md b/.changeset/hot-pillows-poke.md new file mode 100644 index 0000000000..8060e7121f --- /dev/null +++ b/.changeset/hot-pillows-poke.md @@ -0,0 +1,11 @@ +--- +'@backstage/plugin-user-settings': patch +'@backstage/plugin-scaffolder': patch +'@backstage/plugin-tech-radar': patch +'@backstage/plugin-graphiql': patch +'@backstage/plugin-techdocs': patch +'@backstage/plugin-catalog': patch +'@backstage/plugin-search': patch +--- + +Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. diff --git a/plugins/catalog/src/alpha/plugin.tsx b/plugins/catalog/src/alpha/plugin.tsx index 99aacd27da..9a964c4e46 100644 --- a/plugins/catalog/src/alpha/plugin.tsx +++ b/plugins/catalog/src/alpha/plugin.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { convertLegacyRouteRef } from '@backstage/core-compat-api'; +import { convertLegacyRouteRefs } from '@backstage/core-compat-api'; import { createPlugin } from '@backstage/frontend-plugin-api'; import { entityRouteRef } from '@backstage/plugin-catalog-react'; @@ -38,16 +38,16 @@ import searchResultItems from './searchResultItems'; /** @alpha */ export default createPlugin({ id: 'catalog', - routes: { - catalogIndex: convertLegacyRouteRef(rootRouteRef), - catalogEntity: convertLegacyRouteRef(entityRouteRef), - }, - externalRoutes: { - viewTechDoc: convertLegacyRouteRef(viewTechDocRouteRef), - createComponent: convertLegacyRouteRef(createComponentRouteRef), - createFromTemplate: convertLegacyRouteRef(createFromTemplateRouteRef), - unregisterRedirect: convertLegacyRouteRef(unregisterRedirectRouteRef), - }, + routes: convertLegacyRouteRefs({ + catalogIndex: rootRouteRef, + catalogEntity: entityRouteRef, + }), + externalRoutes: convertLegacyRouteRefs({ + viewTechDoc: viewTechDocRouteRef, + createComponent: createComponentRouteRef, + createFromTemplate: createFromTemplateRouteRef, + unregisterRedirect: unregisterRedirectRouteRef, + }), extensions: [ ...apis, ...pages, diff --git a/plugins/graphiql/src/alpha.tsx b/plugins/graphiql/src/alpha.tsx index fdd343020d..086f397d7a 100644 --- a/plugins/graphiql/src/alpha.tsx +++ b/plugins/graphiql/src/alpha.tsx @@ -37,6 +37,7 @@ import { graphiQLRouteRef } from './route-refs'; import { compatWrapper, convertLegacyRouteRef, + convertLegacyRouteRefs, } from '@backstage/core-compat-api'; /** @alpha */ @@ -128,7 +129,7 @@ export default createPlugin({ graphiqlGitlabGraphiQLEndpointExtension, graphiqlNavItem, ], - routes: { - root: convertLegacyRouteRef(graphiQLRouteRef), - }, + routes: convertLegacyRouteRefs({ + root: graphiQLRouteRef, + }), }); diff --git a/plugins/scaffolder/src/alpha.tsx b/plugins/scaffolder/src/alpha.tsx index 0d079f9c40..37e2978802 100644 --- a/plugins/scaffolder/src/alpha.tsx +++ b/plugins/scaffolder/src/alpha.tsx @@ -29,6 +29,7 @@ import CreateComponentIcon from '@material-ui/icons/AddCircleOutline'; import { compatWrapper, convertLegacyRouteRef, + convertLegacyRouteRefs, } from '@backstage/core-compat-api'; import { scmIntegrationsApiRef } from '@backstage/integration-react'; import { scaffolderApiRef } from '@backstage/plugin-scaffolder-react'; @@ -85,17 +86,17 @@ const scaffolderNavItem = createNavItemExtension({ /** @alpha */ export default createPlugin({ id: 'scaffolder', - routes: { - root: convertLegacyRouteRef(rootRouteRef), - selectedTemplate: convertLegacyRouteRef(selectedTemplateRouteRef), - ongoingTask: convertLegacyRouteRef(scaffolderTaskRouteRef), - actions: convertLegacyRouteRef(actionsRouteRef), - listTasks: convertLegacyRouteRef(scaffolderListTaskRouteRef), - edit: convertLegacyRouteRef(editRouteRef), - }, - externalRoutes: { - registerComponent: convertLegacyRouteRef(registerComponentRouteRef), - viewTechDoc: convertLegacyRouteRef(viewTechDocRouteRef), - }, + routes: convertLegacyRouteRefs({ + root: rootRouteRef, + selectedTemplate: selectedTemplateRouteRef, + ongoingTask: scaffolderTaskRouteRef, + actions: actionsRouteRef, + listTasks: scaffolderListTaskRouteRef, + edit: editRouteRef, + }), + externalRoutes: convertLegacyRouteRefs({ + registerComponent: registerComponentRouteRef, + viewTechDoc: viewTechDocRouteRef, + }), extensions: [scaffolderApi, scaffolderPage, scaffolderNavItem], }); diff --git a/plugins/search/src/alpha.tsx b/plugins/search/src/alpha.tsx index a3a5023693..4f654548f5 100644 --- a/plugins/search/src/alpha.tsx +++ b/plugins/search/src/alpha.tsx @@ -70,6 +70,7 @@ import { UrlUpdater } from './components/SearchPage/SearchPage'; import { compatWrapper, convertLegacyRouteRef, + convertLegacyRouteRefs, } from '@backstage/core-compat-api'; /** @alpha */ @@ -248,7 +249,7 @@ export const searchNavItem = createNavItemExtension({ export default createPlugin({ id: 'search', extensions: [searchApi, searchPage, searchNavItem], - routes: { - root: convertLegacyRouteRef(rootRouteRef), - }, + routes: convertLegacyRouteRefs({ + root: rootRouteRef, + }), }); diff --git a/plugins/tech-radar/src/alpha.tsx b/plugins/tech-radar/src/alpha.tsx index 1fb5fa06f3..54e209fae3 100644 --- a/plugins/tech-radar/src/alpha.tsx +++ b/plugins/tech-radar/src/alpha.tsx @@ -27,6 +27,7 @@ import { SampleTechRadarApi } from './sample'; import { compatWrapper, convertLegacyRouteRef, + convertLegacyRouteRefs, } from '@backstage/core-compat-api'; import { rootRouteRef } from './plugin'; @@ -61,7 +62,7 @@ export const techRadarApi = createApiExtension({ export default createPlugin({ id: 'tech-radar', extensions: [techRadarPage, techRadarApi], - routes: { - root: convertLegacyRouteRef(rootRouteRef), - }, + routes: convertLegacyRouteRefs({ + root: rootRouteRef, + }), }); diff --git a/plugins/techdocs/src/alpha.tsx b/plugins/techdocs/src/alpha.tsx index ef564d469a..88dce3b48e 100644 --- a/plugins/techdocs/src/alpha.tsx +++ b/plugins/techdocs/src/alpha.tsx @@ -34,6 +34,7 @@ import { import { compatWrapper, convertLegacyRouteRef, + convertLegacyRouteRefs, } from '@backstage/core-compat-api'; import { techdocsApiRef, @@ -168,9 +169,9 @@ export default createPlugin({ techDocsEntityContent, techDocsSearchResultListItemExtension, ], - routes: { - root: convertLegacyRouteRef(rootRouteRef), - docRoot: convertLegacyRouteRef(rootDocsRouteRef), - entityContent: convertLegacyRouteRef(rootCatalogDocsRouteRef), - }, + routes: convertLegacyRouteRefs({ + root: rootRouteRef, + docRoot: rootDocsRouteRef, + entityContent: rootCatalogDocsRouteRef, + }), }); diff --git a/plugins/user-settings/src/alpha.tsx b/plugins/user-settings/src/alpha.tsx index 5dabd70739..f14db7233d 100644 --- a/plugins/user-settings/src/alpha.tsx +++ b/plugins/user-settings/src/alpha.tsx @@ -22,6 +22,7 @@ import { } from '@backstage/frontend-plugin-api'; import { convertLegacyRouteRef, + convertLegacyRouteRefs, compatWrapper, } from '@backstage/core-compat-api'; import SettingsIcon from '@material-ui/icons/Settings'; @@ -65,7 +66,7 @@ export const settingsNavItem = createNavItemExtension({ export default createPlugin({ id: 'user-settings', extensions: [userSettingsPage, settingsNavItem], - routes: { - root: convertLegacyRouteRef(settingsRouteRef), - }, + routes: convertLegacyRouteRefs({ + root: settingsRouteRef, + }), }); From 53d2a7dcc2e224b6fa155c20f7146e232e3a9b1f Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 19 Jan 2024 11:33:35 +0100 Subject: [PATCH 273/283] app-next: add route binding from migrated app to a converted one Signed-off-by: Patrik Oldsberg --- packages/app-next/app-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/app-next/app-config.yaml b/packages/app-next/app-config.yaml index 77f4284455..1b77205d5e 100644 --- a/packages/app-next/app-config.yaml +++ b/packages/app-next/app-config.yaml @@ -5,6 +5,7 @@ app: bindings: plugin.pages.externalRoutes.pageX: plugin.pages.routes.pageX plugin.catalog.externalRoutes.viewTechDoc: plugin.techdocs.routes.docRoot + plugin.catalog.externalRoutes.createComponent: plugin.catalog-import.routes.importPage extensions: # - apis.plugin.graphiql.browse.gitlab: true From d5d9912f3b7a444441bac4f57c2056468cd81713 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 19 Jan 2024 12:06:56 +0100 Subject: [PATCH 274/283] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Patrik Oldsberg --- .changeset/twenty-taxis-mate.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/twenty-taxis-mate.md b/.changeset/twenty-taxis-mate.md index ab3cc6d406..65ed158e9b 100644 --- a/.changeset/twenty-taxis-mate.md +++ b/.changeset/twenty-taxis-mate.md @@ -2,4 +2,4 @@ '@backstage/core-compat-api': patch --- -Plugins converted by `convertLegacyApp` now have their `routes` and `externalRoutes` included as well, allowing the to be used to bind external routes in configuration. +Plugins converted by `convertLegacyApp` now have their `routes` and `externalRoutes` included as well, allowing them to be used to bind external routes in configuration. From 5d3fd7942dba99c3a498a9b214f130ed421a3971 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 12:07:10 +0000 Subject: [PATCH 275/283] chore(deps): update dependency @openapitools/openapi-generator-cli to v2.9.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 55a291eff6..7d3134509b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13966,8 +13966,8 @@ __metadata: linkType: hard "@openapitools/openapi-generator-cli@npm:^2.4.26, @openapitools/openapi-generator-cli@npm:^2.7.0": - version: 2.8.1 - resolution: "@openapitools/openapi-generator-cli@npm:2.8.1" + version: 2.9.0 + resolution: "@openapitools/openapi-generator-cli@npm:2.9.0" dependencies: "@nestjs/axios": 3.0.1 "@nestjs/common": 10.3.0 @@ -13988,7 +13988,7 @@ __metadata: tslib: 2.6.2 bin: openapi-generator-cli: main.js - checksum: 5e0e5460ec8cf5f96338703820066265d187ce984f24cfcf6f1abe70049b38a8953f0835658f5915ec41304a98bd76cf17ec9fb50fa746701116be6502dca39e + checksum: 102040381b42edbab4fa34aa49c3cf8188fdb892c3e251bcb5bdf7c599597f3572d52d44fed7bead5fcaec24d624491c20dc96d2f164fa44e7fc232c7d787f69 languageName: node linkType: hard From c7bf00693cba7e255ef68de96eae42d8af31aca2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 12:08:17 +0000 Subject: [PATCH 276/283] fix(deps): update dependency sass to v1.70.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- microsite/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/microsite/yarn.lock b/microsite/yarn.lock index e9f027d3a7..a2489da001 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -10817,15 +10817,15 @@ __metadata: linkType: hard "sass@npm:^1.57.1": - version: 1.69.7 - resolution: "sass@npm:1.69.7" + version: 1.70.0 + resolution: "sass@npm:1.70.0" dependencies: chokidar: ">=3.0.0 <4.0.0" immutable: ^4.0.0 source-map-js: ">=0.6.2 <2.0.0" bin: sass: sass.js - checksum: c67cd32b69fb26a50e4535353e4145de8cbc8187db07c467cc335157fd56d03cae98754f86efe43b880b29f20c0a168ab972c7f74ebfe234e2bd2dfb868890cb + checksum: fd1b622cf9b7fa699a03ec634611997552ece45eb98ac365fef22f42bdcb8ed63b326b64173379c966830c8551ae801e44e4a00d2de16fdadda2dc8f35400bbb languageName: node linkType: hard From b679e61ee8bbb6af7fb2f5f24f825a4ed86753e7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 12:08:52 +0000 Subject: [PATCH 277/283] fix(deps): update dependency sucrase to v3.35.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/yarn.lock b/yarn.lock index 55a291eff6..349abda05b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -28106,20 +28106,6 @@ __metadata: languageName: node linkType: hard -"glob@npm:7.1.6": - version: 7.1.6 - resolution: "glob@npm:7.1.6" - dependencies: - fs.realpath: ^1.0.0 - inflight: ^1.0.4 - inherits: 2 - minimatch: ^3.0.4 - once: ^1.3.0 - path-is-absolute: ^1.0.0 - checksum: 351d549dd90553b87c2d3f90ce11aed9e1093c74130440e7ae0592e11bbcd2ce7f0ebb8ba6bfe63aaf9b62166a7f4c80cb84490ae5d78408bb2572bf7d4ee0a6 - languageName: node - linkType: hard - "glob@npm:7.2.3, glob@npm:^7.0.0, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.1.7, glob@npm:^7.2.0": version: 7.2.3 resolution: "glob@npm:7.2.3" @@ -41669,12 +41655,12 @@ __metadata: linkType: hard "sucrase@npm:^3.20.2": - version: 3.34.0 - resolution: "sucrase@npm:3.34.0" + version: 3.35.0 + resolution: "sucrase@npm:3.35.0" dependencies: "@jridgewell/gen-mapping": ^0.3.2 commander: ^4.0.0 - glob: 7.1.6 + glob: ^10.3.10 lines-and-columns: ^1.1.6 mz: ^2.7.0 pirates: ^4.0.1 @@ -41682,7 +41668,7 @@ __metadata: bin: sucrase: bin/sucrase sucrase-node: bin/sucrase-node - checksum: 61860063bdf6103413698e13247a3074d25843e91170825a9752e4af7668ffadd331b6e99e92fc32ee5b3c484ee134936f926fa9039d5711fafff29d017a2110 + checksum: 9fc5792a9ab8a14dcf9c47dcb704431d35c1cdff1d17d55d382a31c2e8e3063870ad32ce120a80915498486246d612e30cda44f1624d9d9a10423e1a43487ad1 languageName: node linkType: hard From 71f3794765805aa17cf1cd12586b4a68ec84f49b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 13:31:14 +0000 Subject: [PATCH 278/283] fix(deps): update dependency swagger-ui-react to v5.11.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 581 +++++++++++++++++++++++++++++------------------------- 1 file changed, 315 insertions(+), 266 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9b30c4a836..897d934365 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3110,13 +3110,13 @@ __metadata: languageName: node linkType: hard -"@babel/runtime-corejs3@npm:^7.20.7, @babel/runtime-corejs3@npm:^7.22.15, @babel/runtime-corejs3@npm:^7.23.5": - version: 7.23.6 - resolution: "@babel/runtime-corejs3@npm:7.23.6" +"@babel/runtime-corejs3@npm:^7.20.7, @babel/runtime-corejs3@npm:^7.22.15, @babel/runtime-corejs3@npm:^7.23.7": + version: 7.23.8 + resolution: "@babel/runtime-corejs3@npm:7.23.8" dependencies: core-js-pure: ^3.30.2 regenerator-runtime: ^0.14.0 - checksum: 92576ea17ff674025aa3cd208bfb8301e4bde432cfa404b56f94242948cbd40125c1a4c9c54a99134e08ded8bcde305633a22b1f4c676687c3b868557d23b762 + checksum: e786b79bcb3031bd7433fb4523e43f0acbd386cd7bb5b0a6df6e627c7965706b3d5612211ea3d729ce4459ba1d1b654ccdd8aefe791c6413f70882ee1be903b9 languageName: node linkType: hard @@ -9692,10 +9692,10 @@ __metadata: languageName: node linkType: hard -"@braintree/sanitize-url@npm:=6.0.4": - version: 6.0.4 - resolution: "@braintree/sanitize-url@npm:6.0.4" - checksum: f5ec6048973722ea1c46ae555d2e9eb848d7fa258994f8ea7d6db9514ee754ea3ef344ef71b3696d486776bcb839f3124e79f67c6b5b2814ed2da220b340627c +"@braintree/sanitize-url@npm:=7.0.0": + version: 7.0.0 + resolution: "@braintree/sanitize-url@npm:7.0.0" + checksum: 2ca9c617343d00c668486f5382cd6ef7d0bd54ba6c8d40deb0f3e7843390a056cf0c590f1d06d38a49b7d8b3f63c006f89873944996742835f2b523b707913a0 languageName: node linkType: hard @@ -16423,406 +16423,452 @@ __metadata: languageName: node linkType: hard -"@swagger-api/apidom-ast@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-ast@npm:0.83.0" +"@swagger-api/apidom-ast@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ast@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-error": ^0.83.0 + "@swagger-api/apidom-error": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 unraw: ^3.0.0 - checksum: 7449e1c3eb316920e277d773a3504af9379ade513836342a55817888c73ad65bf08c6c11222fbd9f6862108ab3fad3d2ce2dfa7ab4f9acf48a3134f27f057f87 + checksum: 11770246944b3bb5964a88e71a7e32e37691b7a3b6ec9ae6acf58cd580571ca75c079d749bb952cd08c86be2155cbef3ed418ad6194681e1e2fea643a2128af2 languageName: node linkType: hard -"@swagger-api/apidom-core@npm:>=0.83.0 <1.0.0, @swagger-api/apidom-core@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-core@npm:0.83.0" +"@swagger-api/apidom-core@npm:>=0.90.0 <1.0.0, @swagger-api/apidom-core@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-core@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-ast": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 + "@swagger-api/apidom-ast": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 "@types/ramda": ~0.29.6 minim: ~0.23.8 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 short-unique-id: ^5.0.2 stampit: ^4.3.2 - checksum: acbdd94eabb7ad44ba5c7c1e69a831bd5b53aca6f4e66abb66ad5e8d53717cb453a5885c51008b6a7b5f7e16de8660a1b5652a4498883c84d37cb62b093e3e91 + checksum: e02f1a838ab1d811960a48f98922c66bb306f1a5a1a154b8fe4c6445fb0a20c671409fee14a2e49051387bc7b5c28e218161bcc1519c6ad9cbc767bf432ee05d languageName: node linkType: hard -"@swagger-api/apidom-error@npm:>=0.83.0 <1.0.0, @swagger-api/apidom-error@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-error@npm:0.83.0" +"@swagger-api/apidom-error@npm:>=0.90.0 <1.0.0, @swagger-api/apidom-error@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-error@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - checksum: 94fee6b4ee4a60a7d121d17c92808bec452bd7c638c3ecceda6fc427f47a0297e78a2366a37c7216b84b4a95aead825eb421356fa17dc67dd44da86e27660d1c + checksum: bdd3051a47f4300344c0f1f2a55c4bb3dbe147ba8ebd27c94a77db2c90e8cc371bca63b72dfb49d0034794b82929edbf70d20ab33f59ba9f8c2d2fc8dc0430db languageName: node linkType: hard -"@swagger-api/apidom-json-pointer@npm:>=0.83.0 <1.0.0, @swagger-api/apidom-json-pointer@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-json-pointer@npm:0.83.0" +"@swagger-api/apidom-json-pointer@npm:>=0.90.0 <1.0.0, @swagger-api/apidom-json-pointer@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-json-pointer@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: b48d784f18a8d8e948292c1126a0b768a0df347d31b6b1e4fa28df64ceb83cbb5d465a80fc87e127529e339000eb97d28f7c4d632af47db3dbe7eeb92f9477c1 + checksum: 89d748fd1f52fce381d4e07710244d94c4d9f8a20411ca8bcfb33e7ec515432c7766660b296a9c603fa6b861b39eca4917151f98f3688f1bdcf10f25f9d90134 languageName: node linkType: hard -"@swagger-api/apidom-ns-api-design-systems@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-ns-api-design-systems@npm:0.83.0" +"@swagger-api/apidom-ns-api-design-systems@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ns-api-design-systems@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 - "@swagger-api/apidom-ns-openapi-3-1": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 + "@swagger-api/apidom-ns-openapi-3-1": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: 711a533d1a386e296525bbb131948e24ca548ee0d4de67acd8ae9f37097fef5801d82887eecdb9a45f954fb10c30666634fa78edb2e09d061beaab8dde47da35 + checksum: 8e993f6b8cd37cb9857a34437e2b16e087ccce524373726a167bf98ab622c44a03c47c81e218ff4b00aa7bd973a25bd696e2437c5fd018ace09ba2ad0fcda9de languageName: node linkType: hard -"@swagger-api/apidom-ns-asyncapi-2@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-ns-asyncapi-2@npm:0.83.0" +"@swagger-api/apidom-ns-asyncapi-2@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ns-asyncapi-2@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-json-schema-draft-7": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-json-schema-draft-7": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: 0c7e6bc35c2b5e46bd08922309cd494133302ce3b6b8d0cbfbfb99106ea7c1e160ca4ab11f21161598c532c86fafa9127320e5b561560a01e51ceef9d545e767 + checksum: bef3de2c2a854590c8bb1cd892a5b170b65e14119a97528652457bf1e3e19f4a05d7da41ddb697f64de9972c8fad8afc7e6ccfa97ce8809fc9eba8c1305d509c languageName: node linkType: hard -"@swagger-api/apidom-ns-json-schema-draft-4@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-ns-json-schema-draft-4@npm:0.83.0" +"@swagger-api/apidom-ns-json-schema-draft-4@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ns-json-schema-draft-4@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-ast": ^0.83.0 - "@swagger-api/apidom-core": ^0.83.0 + "@swagger-api/apidom-ast": ^0.92.0 + "@swagger-api/apidom-core": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: 7fb5db60a95d3531b9fb38693a0b758a8bb3e946f7e7f4e202eaef093cdd53c6289031c8b8977e8548c6376b8e41a627827b64e2c9f5de2f63fc3a427e2f670b + checksum: 6b0d57acf1c34df314c401ab25d0feb3ad5638fc8c848f6b84c76691fef177a39a9e8ebfa16309d22c764d9bfb292ed5ad39943b2cece67dde746a6e9d5fdc12 languageName: node linkType: hard -"@swagger-api/apidom-ns-json-schema-draft-6@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-ns-json-schema-draft-6@npm:0.83.0" +"@swagger-api/apidom-ns-json-schema-draft-6@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ns-json-schema-draft-6@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 - "@swagger-api/apidom-ns-json-schema-draft-4": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 + "@swagger-api/apidom-ns-json-schema-draft-4": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: 60d3d359bf0e8054bad013fb2d7bd4c020d4fb0ce6819538b47986ea7f89269af5f1c3b65c7ddb864bc502a7c41e6069c042a9be753cd9d47dc13b9d0572d216 + checksum: 5660459753ff1359527e61820db59a6465ecc8b51cc5a6c14e155b2144b67570c6fc2c7c41d97617470d1478b85e26879fadc3f1ff4460c6309411c13db209e6 languageName: node linkType: hard -"@swagger-api/apidom-ns-json-schema-draft-7@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-ns-json-schema-draft-7@npm:0.83.0" +"@swagger-api/apidom-ns-json-schema-draft-7@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ns-json-schema-draft-7@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 - "@swagger-api/apidom-ns-json-schema-draft-6": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 + "@swagger-api/apidom-ns-json-schema-draft-6": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: 01623f0c65795d1022e903d39858caac018f9fe338049247ea668805e1926d05713faae9f8ea43188e465a1e2f6783a5e3b38036965b56859036a16d8deb3b86 + checksum: 838d2b9917b4086880156e895d67adfd6400236e97b2a75814356dc55b0d45afd3e458bfe97b52af39aeea4c3483fc40f7a1551af14285977009513a168fb87c languageName: node linkType: hard -"@swagger-api/apidom-ns-openapi-2@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-ns-openapi-2@npm:0.83.0" +"@swagger-api/apidom-ns-openapi-2@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ns-openapi-2@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 - "@swagger-api/apidom-ns-json-schema-draft-4": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 + "@swagger-api/apidom-ns-json-schema-draft-4": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: 078b138517b0c0dffa67186f2a23938ba87c98c9dd98d431ff812a8be45b3b711e22749b62e22ccd70d4615a92c0ca442b793386fe201583aa8c52556260b082 + checksum: 154de0b299a3ff0fcac40cf995dafb8c173cb4e294c75f952a9fa9cd5452eaab7783a9e5abb425fbc6e7135466155645e9b96fa9495f3effa7aec18f3152e6c3 languageName: node linkType: hard -"@swagger-api/apidom-ns-openapi-3-0@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-ns-openapi-3-0@npm:0.83.0" +"@swagger-api/apidom-ns-openapi-3-0@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ns-openapi-3-0@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 - "@swagger-api/apidom-ns-json-schema-draft-4": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 + "@swagger-api/apidom-ns-json-schema-draft-4": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: dabe0745da3c4a3e719f1d9d7d3fbcd177c3735ec00ad762414ed6d9d82eed43b0897896d48e3b8690186029b952146b8bfcab2406d91797e6a9f81f451c51f3 + checksum: 9ae883feea63c06f2514ba834b637bd00d6a56c35fe9b875507698d991199202d307a90bd06ebeaeb5642e3e42fe54238249858568c8a61a1797792fa5fff259 languageName: node linkType: hard -"@swagger-api/apidom-ns-openapi-3-1@npm:>=0.83.0 <1.0.0, @swagger-api/apidom-ns-openapi-3-1@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-ns-openapi-3-1@npm:0.83.0" +"@swagger-api/apidom-ns-openapi-3-1@npm:>=0.90.0 <1.0.0, @swagger-api/apidom-ns-openapi-3-1@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ns-openapi-3-1@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-ast": ^0.83.0 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-openapi-3-0": ^0.83.0 + "@swagger-api/apidom-ast": ^0.92.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-openapi-3-0": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: 499818a4e437017f7a7ca8861dc1b8e90ba8bb8c300a1f2754bb7b2b05f95e0e897f6305bec1aa5c5af0f03c94e541660a412da25467091bcf35847cc2ee6a4c + checksum: 316861ccd563d28c46039fa4202337f2266e0b99bf803bc71f64d307d824a74dcf7e4cdf7fc4ac25d6cf3521aebc74938c2001eb74ef0c364bc02470a1ffc723 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-api-design-systems-json@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-api-design-systems-json@npm:0.83.0" +"@swagger-api/apidom-ns-workflows-1@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-ns-workflows-1@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-api-design-systems": ^0.83.0 - "@swagger-api/apidom-parser-adapter-json": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-openapi-3-1": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 + ramda-adjunct: ^4.1.1 + stampit: ^4.3.2 + checksum: 684804790b58b52a28ae10ffc7fc2fa5bf6b99d8cb3e5d9409e28325c4d4b9ce5b5cc10e0cc401fb21788753ea65287e33db79337388afccd54f6902f60d9159 + languageName: node + linkType: hard + +"@swagger-api/apidom-parser-adapter-api-design-systems-json@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-api-design-systems-json@npm:0.92.0" + dependencies: + "@babel/runtime-corejs3": ^7.20.7 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-api-design-systems": ^0.92.0 + "@swagger-api/apidom-parser-adapter-json": ^0.92.0 + "@types/ramda": ~0.29.6 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 5a0ccf6158f4d9582002c3df4c30136ad8e0f7ee8e75a32f000d638e9b1906e1c42d9137fc4093532bbdbc7ebb3b23eb9fe2819690ae7643e9dde301710b264f + checksum: d9c361b8bb7b8a056acc2c52ef70a2d7304c511efc836cfebc315558ced7e93fe4e958dd554030a3315702d49ace30082ff7f2f91e9a76aaa2fff944a19fe39e languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-api-design-systems-yaml@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-api-design-systems-yaml@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-api-design-systems-yaml@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-api-design-systems-yaml@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-api-design-systems": ^0.83.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-api-design-systems": ^0.92.0 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: add8a138f379eddf4ce0fa78ffaf91d65c66b073d7304e11ed9db7f6262e2a981e8c9cb5cd36bb2471f573a37179c0f5414be9934714cc9166a98bfb6766931e + checksum: 248e61ed6e202eeab048c7c5e3eff0e0f2b6bfea958a02cbc6d8b831693a015d063db118af25c2e7380a4828ab84bf991764d200409a8eb99ffadb0dc6db65c0 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-asyncapi-json-2@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-asyncapi-json-2@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-asyncapi-json-2@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-asyncapi-json-2@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-asyncapi-2": ^0.83.0 - "@swagger-api/apidom-parser-adapter-json": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-asyncapi-2": ^0.92.0 + "@swagger-api/apidom-parser-adapter-json": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 0f510d2fb6b69daaebbc55cb186820394584941495ca2d7ae3ad608cc78f48f7b49d8dbf7299ac3fde2c553c8b0244bf265037e435e1e79176afc30029f127ca + checksum: 0fc981bc839758af1b3a8dfa0695376919a515a11ae71e6f9f1e0c91dd1530aa659fa7405cb73109db28fd95f594f09b5ee941611cc4ce4f3d1817335b12ec4b languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-asyncapi-2": ^0.83.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-asyncapi-2": ^0.92.0 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 46c4fff48263ec0bb40698ded08018c2d6bb653da1e88b1a50ea1b433b83a922a65029d09a77b0febaed6b26822ac520222a8495eafc5f86d81be003b8d0f418 + checksum: a1554f73cc20b75df71296322f6bdf5b5a0f1d775bd9bff89d7798843606e1a383c48960ddc2b1f879c962d2d56962e6096c3000ec2ad6091d49627aa2992b2e languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-json@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-json@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-json@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-json@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-ast": ^0.83.0 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 + "@swagger-api/apidom-ast": ^0.92.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 "@types/ramda": ~0.29.6 node-gyp: latest - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 - stampit: ^4.3.2 tree-sitter: =0.20.4 tree-sitter-json: =0.20.1 web-tree-sitter: =0.20.3 - checksum: be94a40fb8d342fe6394f01a803f0403612a796017bd6169dd52c201b26d60ed36cf6b7363faf2c8203fa67b65349d74c99b685c589ffbad30c26df29a3a53db + checksum: ca66dd9fffaa84249398420b9cf2301721d2b173340e0f07097348b73654f54698a370a94d814d7f51b7e662f968054b7fc745607074dbd71892c53714a18b62 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-openapi-json-2@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-openapi-json-2@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-openapi-json-2@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-openapi-json-2@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-openapi-2": ^0.83.0 - "@swagger-api/apidom-parser-adapter-json": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-openapi-2": ^0.92.0 + "@swagger-api/apidom-parser-adapter-json": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: e65c17bc9809af2b4c240c7f128258602bb8bdb440ad508ef08f5829b3347cc053624d117a4297c806a621ed61d9a53158a4aa4ed5cb3487a38935c32226d57d + checksum: 383827eec8fbc2bb36c095c8db4f8dce5264e5ffdfa7aca9a938d603294d99f0a552d57947222c160fbbbc1b79be7d08a7091348f3b373bbe25bd52a34bee529 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-openapi-json-3-0@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-openapi-json-3-0@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-openapi-json-3-0@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-openapi-json-3-0@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-openapi-3-0": ^0.83.0 - "@swagger-api/apidom-parser-adapter-json": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-openapi-3-0": ^0.92.0 + "@swagger-api/apidom-parser-adapter-json": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 3a0df777ad9dfdc6e9f6fb4984dfd3e3299a3ceff430719dc26eda9526e2102f786c89a08705cd780602eab5e85344ebe82dca1043741ecbf3ebd7b1961c109c + checksum: 592c1149d901a3c21594aca5c96a997382648ff559fb67cd6b75630440248a52f26df91ad96fa762e585e297725e20eb6f5623f91a6b6a5e2c950f57df4de760 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-openapi-json-3-1@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-openapi-json-3-1@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-openapi-json-3-1@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-openapi-json-3-1@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-openapi-3-1": ^0.83.0 - "@swagger-api/apidom-parser-adapter-json": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-openapi-3-1": ^0.92.0 + "@swagger-api/apidom-parser-adapter-json": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 5cec1f6237871f479233d75b862ccf774ffe5c6d63c9f08734fa6c0067e53ec9091683e5d309bf94cf080bd570bd4cc2496c85988ec0d52cdc378219033a8bdc + checksum: feaa0b825921ea9defde642b65a07049a8539905142baa113b3b5e90c76630a58ef2557a6f770740e32e5cfa46486fc9f7d3c468b8ec29aaa53cb507c4ad3469 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-openapi-yaml-2@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-openapi-yaml-2@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-openapi-yaml-2@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-openapi-yaml-2@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-openapi-2": ^0.83.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-openapi-2": ^0.92.0 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: bee0a9f82ddd02c1cbcf2b90896b70c2607a3ff53ca4431d176639878e0da0173946d6e303bab69d4d794dde178fcbd3c815428123f73eca2095ca89e828330d + checksum: efd8dbd705592accadce53b25fc293ee48d1d11ec191f618df4243e6fdfea1add502ef3a5d433051883092dd29bf0a9f2026f2314a0cced1b8f04af59e63e995 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-openapi-3-0": ^0.83.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-openapi-3-0": ^0.92.0 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: d6b3db2b4bf6280a14a76c29b9b6998380a1af09c0726bf736c7b64b30999268c2360776a284c76c2ec45d19f7c106816c98b2f399ec6225cfc9222dee3fb6ff + checksum: 47a034efae971b56d13e96bc64d0973a2015ca303bf63334117ebbcfb2b2676d50a0b68aa24ea5a3b669786a524035762d52ae1cc795f3c3dc65249297a23068 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-ns-openapi-3-1": ^0.83.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-openapi-3-1": ^0.92.0 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 "@types/ramda": ~0.29.6 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 6bd8cf74b04d7f8fbf0cb0202253db349c7ce1ace7ccc9cff72ae36035a3dac5606e73fc5a829f0ac02af2369aff81ad3991701674091e692ffefb4ffed9499d + checksum: c565913065e401109e7e4494f1024d24958959c742e5f842247a56eca6b75dcc9c3495a4c550912a62d62db896b2803bd317642336b4b18c851adc141fa38b61 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-yaml-1-2@npm:^0.83.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-parser-adapter-yaml-1-2@npm:0.83.0" +"@swagger-api/apidom-parser-adapter-workflows-json-1@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-workflows-json-1@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-ast": ^0.83.0 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-workflows-1": ^0.92.0 + "@swagger-api/apidom-parser-adapter-json": ^0.92.0 + "@types/ramda": ~0.29.6 + ramda: ~0.29.1 + ramda-adjunct: ^4.0.0 + checksum: 570f8323aaa5c67da3b5421d6ca6a9f0c3bf486a602584fa5969476e6a4943abe9a7f8f2bd7dfc1a7019286746e65cc76b050cadfabab276e0d452fbad4db59f + languageName: node + linkType: hard + +"@swagger-api/apidom-parser-adapter-workflows-yaml-1@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-workflows-yaml-1@npm:0.92.0" + dependencies: + "@babel/runtime-corejs3": ^7.20.7 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-ns-workflows-1": ^0.92.0 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 + "@types/ramda": ~0.29.6 + ramda: ~0.29.1 + ramda-adjunct: ^4.0.0 + checksum: 020ecd34fb45ba57977377f71dc0b28ebba95b950bb873e1f6222eb6b544f91243dfb6b1f7555fe5f279d7bee044089337216a3f4b8e58612fb7066530938f32 + languageName: node + linkType: hard + +"@swagger-api/apidom-parser-adapter-yaml-1-2@npm:^0.92.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-parser-adapter-yaml-1-2@npm:0.92.0" + dependencies: + "@babel/runtime-corejs3": ^7.20.7 + "@swagger-api/apidom-ast": ^0.92.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 "@types/ramda": ~0.29.6 node-gyp: latest - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 - stampit: ^4.3.2 tree-sitter: =0.20.4 tree-sitter-yaml: =0.5.0 web-tree-sitter: =0.20.3 - checksum: df777f06199a82b8ccfb3ea53def7bbd08d06f3e3f4b5083526661bc86dd920ac83ca5b34dcaa26c0194d1dd7e104b6f324454790504b6934eb684011f6a5749 + checksum: 1ee0bf2c2f7fed54ff194917034f31080ad4ad36e14dc2018c80d8bda38f8b6574ace974eca1a65aa336a86df375dabd0661215909551031e796dcee9d0d1a14 languageName: node linkType: hard -"@swagger-api/apidom-reference@npm:>=0.83.0 <1.0.0": - version: 0.83.0 - resolution: "@swagger-api/apidom-reference@npm:0.83.0" +"@swagger-api/apidom-reference@npm:>=0.90.0 <1.0.0": + version: 0.92.0 + resolution: "@swagger-api/apidom-reference@npm:0.92.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.83.0 - "@swagger-api/apidom-error": ^0.83.0 - "@swagger-api/apidom-json-pointer": ^0.83.0 - "@swagger-api/apidom-ns-asyncapi-2": ^0.83.0 - "@swagger-api/apidom-ns-openapi-2": ^0.83.0 - "@swagger-api/apidom-ns-openapi-3-0": ^0.83.0 - "@swagger-api/apidom-ns-openapi-3-1": ^0.83.0 - "@swagger-api/apidom-parser-adapter-api-design-systems-json": ^0.83.0 - "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": ^0.83.0 - "@swagger-api/apidom-parser-adapter-asyncapi-json-2": ^0.83.0 - "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": ^0.83.0 - "@swagger-api/apidom-parser-adapter-json": ^0.83.0 - "@swagger-api/apidom-parser-adapter-openapi-json-2": ^0.83.0 - "@swagger-api/apidom-parser-adapter-openapi-json-3-0": ^0.83.0 - "@swagger-api/apidom-parser-adapter-openapi-json-3-1": ^0.83.0 - "@swagger-api/apidom-parser-adapter-openapi-yaml-2": ^0.83.0 - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": ^0.83.0 - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": ^0.83.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.83.0 + "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-error": ^0.92.0 + "@swagger-api/apidom-json-pointer": ^0.92.0 + "@swagger-api/apidom-ns-asyncapi-2": ^0.92.0 + "@swagger-api/apidom-ns-openapi-2": ^0.92.0 + "@swagger-api/apidom-ns-openapi-3-0": ^0.92.0 + "@swagger-api/apidom-ns-openapi-3-1": ^0.92.0 + "@swagger-api/apidom-ns-workflows-1": ^0.92.0 + "@swagger-api/apidom-parser-adapter-api-design-systems-json": ^0.92.0 + "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": ^0.92.0 + "@swagger-api/apidom-parser-adapter-asyncapi-json-2": ^0.92.0 + "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": ^0.92.0 + "@swagger-api/apidom-parser-adapter-json": ^0.92.0 + "@swagger-api/apidom-parser-adapter-openapi-json-2": ^0.92.0 + "@swagger-api/apidom-parser-adapter-openapi-json-3-0": ^0.92.0 + "@swagger-api/apidom-parser-adapter-openapi-json-3-1": ^0.92.0 + "@swagger-api/apidom-parser-adapter-openapi-yaml-2": ^0.92.0 + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": ^0.92.0 + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": ^0.92.0 + "@swagger-api/apidom-parser-adapter-workflows-json-1": ^0.92.0 + "@swagger-api/apidom-parser-adapter-workflows-yaml-1": ^0.92.0 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 "@types/ramda": ~0.29.6 axios: ^1.4.0 minimatch: ^7.4.3 process: ^0.11.10 - ramda: ~0.29.0 + ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 dependenciesMeta: @@ -16838,6 +16884,8 @@ __metadata: optional: true "@swagger-api/apidom-ns-openapi-3-1": optional: true + "@swagger-api/apidom-ns-workflows-1": + optional: true "@swagger-api/apidom-parser-adapter-api-design-systems-json": optional: true "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": @@ -16860,9 +16908,13 @@ __metadata: optional: true "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": optional: true + "@swagger-api/apidom-parser-adapter-workflows-json-1": + optional: true + "@swagger-api/apidom-parser-adapter-workflows-yaml-1": + optional: true "@swagger-api/apidom-parser-adapter-yaml-1-2": optional: true - checksum: b19c9c98cda575b139b1556327809c2367cca9e169ac50ea64049f6cc64148630709e5cc11573124460bcd5f5fc834c0c4434b8564fac4488e16de3cef65a16f + checksum: 05b2c97233f2f60879d2dc62a811a4b31520acb7b3c730d47e60e5927f861c1bf1376e790648b773b242ccb1e24596c567014c570d123655dc59fc2c590668c7 languageName: node linkType: hard @@ -17940,7 +17992,7 @@ __metadata: languageName: node linkType: hard -"@types/hoist-non-react-statics@npm:^3.3.0, @types/hoist-non-react-statics@npm:^3.3.1": +"@types/hoist-non-react-statics@npm:^3.3.0": version: 3.3.1 resolution: "@types/hoist-non-react-statics@npm:3.3.1" dependencies: @@ -22234,7 +22286,7 @@ __metadata: languageName: node linkType: hard -"classnames@npm:*, classnames@npm:^2.2.5, classnames@npm:^2.2.6, classnames@npm:^2.3.1": +"classnames@npm:*, classnames@npm:^2.2.5, classnames@npm:^2.2.6, classnames@npm:^2.3.1, classnames@npm:^2.5.1": version: 2.5.1 resolution: "classnames@npm:2.5.1" checksum: da424a8a6f3a96a2e87d01a432ba19315503294ac7e025f9fece656db6b6a0f7b5003bb1fbb51cbb0d9624d964f1b9bb35a51c73af9b2434c7b292c42231c1e5 @@ -37923,10 +37975,10 @@ __metadata: languageName: node linkType: hard -"ramda@npm:~0.29.0": - version: 0.29.0 - resolution: "ramda@npm:0.29.0" - checksum: 9ab26c06eb7545cbb7eebcf75526d6ee2fcaae19e338f165b2bf32772121e7b28192d6664d1ba222ff76188ba26ab307342d66e805dbb02c860560adc4d5dd57 +"ramda@npm:~0.29.1": + version: 0.29.1 + resolution: "ramda@npm:0.29.1" + checksum: df7c627597a66d5f317f6ba77ad17d7ba818efc9c2c4a638440bc23f2c651e823970ea05b05a28895738c0e4b738fadbdc17b2c97b3ad922826febc09c859c44 languageName: node linkType: hard @@ -38436,35 +38488,25 @@ __metadata: languageName: node linkType: hard -"react-redux@npm:^8.1.3": - version: 8.1.3 - resolution: "react-redux@npm:8.1.3" +"react-redux@npm:^9.0.4": + version: 9.1.0 + resolution: "react-redux@npm:9.1.0" dependencies: - "@babel/runtime": ^7.12.1 - "@types/hoist-non-react-statics": ^3.3.1 "@types/use-sync-external-store": ^0.0.3 - hoist-non-react-statics: ^3.3.2 - react-is: ^18.0.0 use-sync-external-store: ^1.0.0 peerDependencies: - "@types/react": ^16.8 || ^17.0 || ^18.0 - "@types/react-dom": ^16.8 || ^17.0 || ^18.0 - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - react-native: ">=0.59" - redux: ^4 || ^5.0.0-beta.0 + "@types/react": ^18.2.25 + react: ^18.0 + react-native: ">=0.69" + redux: ^5.0.0 peerDependenciesMeta: "@types/react": optional: true - "@types/react-dom": - optional: true - react-dom: - optional: true react-native: optional: true redux: optional: true - checksum: 192ea6f6053148ec80a4148ec607bc259403b937e515f616a1104ca5ab357e97e98b8245ed505a17afee67a72341d4a559eaca9607968b4a422aa9b44ba7eb89 + checksum: 1b07714379ff0087b4fb43ffd138cc84efb7608c874d632a4e2162e1874f3e0f6b69a0a9b0f24f93cbf122c694ac9cfd315770676d4cabb167d159f1ef419560 languageName: node linkType: hard @@ -39070,7 +39112,7 @@ __metadata: languageName: node linkType: hard -"redux@npm:^4.0.0, redux@npm:^4.0.4, redux@npm:^4.1.2": +"redux@npm:^4.0.0, redux@npm:^4.0.4": version: 4.1.2 resolution: "redux@npm:4.1.2" dependencies: @@ -39079,6 +39121,13 @@ __metadata: languageName: node linkType: hard +"redux@npm:^5.0.0": + version: 5.0.1 + resolution: "redux@npm:5.0.1" + checksum: e74affa9009dd5d994878b9a1ce30d6569d986117175056edb003de2651c05b10fe7819d6fa94aea1a94de9a82f252f986547f007a2fbeb35c317a2e5f5ecf2c + languageName: node + linkType: hard + "reflect-metadata@npm:0.1.13": version: 0.1.13 resolution: "reflect-metadata@npm:0.1.13" @@ -39382,10 +39431,10 @@ __metadata: languageName: node linkType: hard -"reselect@npm:^4.1.8": - version: 4.1.8 - resolution: "reselect@npm:4.1.8" - checksum: a4ac87cedab198769a29be92bc221c32da76cfdad6911eda67b4d3e7136dca86208c3b210e31632eae31ebd2cded18596f0dd230d3ccc9e978df22f233b5583e +"reselect@npm:^5.0.1": + version: 5.1.0 + resolution: "reselect@npm:5.1.0" + checksum: 5bc9c5d03d7caea00d0c0e24330bf23d91801227346fec1cef6a60988ab8d3dd7cee76e6994ca0915bc1c20845bb2bd929b95753763e0a9db74c0f9dff5cb845 languageName: node linkType: hard @@ -41774,16 +41823,16 @@ __metadata: languageName: node linkType: hard -"swagger-client@npm:^3.24.6": - version: 3.24.6 - resolution: "swagger-client@npm:3.24.6" +"swagger-client@npm:^3.25.0": + version: 3.25.0 + resolution: "swagger-client@npm:3.25.0" dependencies: "@babel/runtime-corejs3": ^7.22.15 - "@swagger-api/apidom-core": ">=0.83.0 <1.0.0" - "@swagger-api/apidom-error": ">=0.83.0 <1.0.0" - "@swagger-api/apidom-json-pointer": ">=0.83.0 <1.0.0" - "@swagger-api/apidom-ns-openapi-3-1": ">=0.83.0 <1.0.0" - "@swagger-api/apidom-reference": ">=0.83.0 <1.0.0" + "@swagger-api/apidom-core": ">=0.90.0 <1.0.0" + "@swagger-api/apidom-error": ">=0.90.0 <1.0.0" + "@swagger-api/apidom-json-pointer": ">=0.90.0 <1.0.0" + "@swagger-api/apidom-ns-openapi-3-1": ">=0.90.0 <1.0.0" + "@swagger-api/apidom-reference": ">=0.90.0 <1.0.0" cookie: ~0.6.0 deepmerge: ~4.3.0 fast-json-patch: ^3.0.0-1 @@ -41794,18 +41843,18 @@ __metadata: qs: ^6.10.2 traverse: ~0.6.6 undici: ^5.24.0 - checksum: 8bb1aeea4576fdd88543c4e011b1f087c52b34e5a069d560937a5c32a6e1e6c7eda243810886f8b09e4e12062e8f2768edaa5e6193140a28f9604bac42b18104 + checksum: 2e989059b4edeab26b148993cea8a68c4ad34927d4058479f2722c01d8bd0f67bfb1f69dc93ce24a5adb5a8e0f45e4438ad38f8bfb70f8d0b1a8d66650abe060 languageName: node linkType: hard "swagger-ui-react@npm:^5.0.0": - version: 5.10.5 - resolution: "swagger-ui-react@npm:5.10.5" + version: 5.11.0 + resolution: "swagger-ui-react@npm:5.11.0" dependencies: - "@babel/runtime-corejs3": ^7.23.5 - "@braintree/sanitize-url": =6.0.4 + "@babel/runtime-corejs3": ^7.23.7 + "@braintree/sanitize-url": =7.0.0 base64-js: ^1.5.1 - classnames: ^2.3.1 + classnames: ^2.5.1 css.escape: 1.5.1 deep-extend: 0.6.0 dompurify: =3.0.6 @@ -41823,23 +41872,23 @@ __metadata: react-immutable-proptypes: 2.2.0 react-immutable-pure-component: ^2.2.0 react-inspector: ^6.0.1 - react-redux: ^8.1.3 + react-redux: ^9.0.4 react-syntax-highlighter: ^15.5.0 - redux: ^4.1.2 + redux: ^5.0.0 redux-immutable: ^4.0.0 remarkable: ^2.0.1 - reselect: ^4.1.8 + reselect: ^5.0.1 serialize-error: ^8.1.0 sha.js: ^2.4.11 - swagger-client: ^3.24.6 + swagger-client: ^3.25.0 url-parse: ^1.5.10 xml: =1.0.1 xml-but-prettier: ^1.0.1 zenscroll: ^4.0.2 peerDependencies: - react: ">=17.0.0" - react-dom: ">=17.0.0" - checksum: 79256d68d56389d089a953f7d6c3a95a67c0b4e2794ae3992ba60adc0312aeb4446d8ba1e20687fcd7708d562e7c15fa733dbcb54cd8f99948ebf4c4513fa042 + react: ">=16.8.0 <19" + react-dom: ">=16.8.0 <19" + checksum: f46acfe503f80566f5a28c5a7a27091f80a764d4602e81ef2dc59466097bdf0e6f6568b866a0a90ab23db39a88fe6f5e4d96b3d5367d05b8ecedb256477fb1cb languageName: node linkType: hard From 92864eb1667f94db29371905fa2c782feda9bd25 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 13:32:07 +0000 Subject: [PATCH 279/283] fix(deps): update dependency tsx to v4.7.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9b30c4a836..02252c2b43 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25534,7 +25534,7 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.18.10, esbuild@npm:~0.18.20": +"esbuild@npm:^0.18.10": version: 0.18.20 resolution: "esbuild@npm:0.18.20" dependencies: @@ -25611,7 +25611,7 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.19.0": +"esbuild@npm:^0.19.0, esbuild@npm:~0.19.10": version: 0.19.11 resolution: "esbuild@npm:0.19.11" dependencies: @@ -42607,10 +42607,10 @@ __metadata: linkType: hard "tsx@npm:^4.0.0": - version: 4.6.2 - resolution: "tsx@npm:4.6.2" + version: 4.7.0 + resolution: "tsx@npm:4.7.0" dependencies: - esbuild: ~0.18.20 + esbuild: ~0.19.10 fsevents: ~2.3.3 get-tsconfig: ^4.7.2 dependenciesMeta: @@ -42618,7 +42618,7 @@ __metadata: optional: true bin: tsx: dist/cli.mjs - checksum: a9f13bdb67bfb316bbfc92303d8464323ab1b673aa93ea97271c211a8ba7c59274d4b32eeec5ad8fbd0b04260a092a3ad2116abeb6913254ba456010ff685743 + checksum: a3a17fa8a40dbe0aff26fb2bc71a069e568152e0685b0bd9a31ea1091806274ba14882551433ed01efa7eae16f1aa965e2e47f3075ec1e914c42cf5dfce1f924 languageName: node linkType: hard From c1d2ba2d1cefeb012ec076c09221a0fc653f998c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 14:15:47 +0000 Subject: [PATCH 280/283] chore(deps): update dependency vite to v4.5.2 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7c5f8e3917..10e2ce02d4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -43925,8 +43925,8 @@ __metadata: linkType: hard "vite@npm:^4.4.9": - version: 4.5.1 - resolution: "vite@npm:4.5.1" + version: 4.5.2 + resolution: "vite@npm:4.5.2" dependencies: esbuild: ^0.18.10 fsevents: ~2.3.2 @@ -43960,7 +43960,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 72b3584b3d3b8d14e8a37f0248e47fb8b4d02ab35de5b5a8e5ca8ae55c3be2aab73760dc36edac4fa722de182f78cc492eb44888fcb4a9a0712c4605dad644f9 + checksum: 9d1f84f703c2660aced34deee7f309278ed368880f66e9570ac115c793d91f7fffb80ab19c602b3c8bc1341fe23437d86a3fcca2a9ef82f7ef0cdac5a40d0c86 languageName: node linkType: hard From 551616a7f694a25cb639b7dce78cd0bef6aaf09e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 15:58:39 +0000 Subject: [PATCH 281/283] fix(deps): update opentelemetry-js monorepo Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/backend/package.json | 2 +- yarn.lock | 58 +++++++++++++++++------------------ 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index cdd0a548c8..4223a92a28 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -82,7 +82,7 @@ "@gitbeaker/node": "^35.1.0", "@octokit/rest": "^19.0.3", "@opentelemetry/api": "^1.4.1", - "@opentelemetry/exporter-prometheus": "^0.45.0", + "@opentelemetry/exporter-prometheus": "^0.47.0", "@opentelemetry/sdk-metrics": "^1.13.0", "azure-devops-node-api": "^12.0.0", "better-sqlite3": "^9.0.0", diff --git a/yarn.lock b/yarn.lock index 8501156914..ede8d0e77a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14012,59 +14012,59 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/core@npm:1.18.1": - version: 1.18.1 - resolution: "@opentelemetry/core@npm:1.18.1" +"@opentelemetry/core@npm:1.20.0": + version: 1.20.0 + resolution: "@opentelemetry/core@npm:1.20.0" dependencies: - "@opentelemetry/semantic-conventions": 1.18.1 + "@opentelemetry/semantic-conventions": 1.20.0 peerDependencies: "@opentelemetry/api": ">=1.0.0 <1.8.0" - checksum: dfb3181836ce04d2e983c0e8382e4bd0228ec42280e0a3f5330e2742903c0fb1db0efc2792479d27f928533a386f163c2e0fce2a2f45b05e66b2809d268915dc + checksum: 90a01430902926894a3d7ac6a5bd68b3bcb59aede568d08ca09abdd6d9cc46e9423f2fc65a496c7a8c13a2d3df259586f1a0d500fac6271524f189247e97d8fa languageName: node linkType: hard -"@opentelemetry/exporter-prometheus@npm:^0.45.0": - version: 0.45.1 - resolution: "@opentelemetry/exporter-prometheus@npm:0.45.1" +"@opentelemetry/exporter-prometheus@npm:^0.47.0": + version: 0.47.0 + resolution: "@opentelemetry/exporter-prometheus@npm:0.47.0" dependencies: - "@opentelemetry/core": 1.18.1 - "@opentelemetry/resources": 1.18.1 - "@opentelemetry/sdk-metrics": 1.18.1 + "@opentelemetry/core": 1.20.0 + "@opentelemetry/resources": 1.20.0 + "@opentelemetry/sdk-metrics": 1.20.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 033fda6759610350d7f11c91d66a2c0e3cc7ac1182267e6ed4aba2fb90add66e344925e6ab89db76ff91c7fa67c82c0c4099657c5a9b68c4140ca4d0a3c1abac + checksum: 7b9af3e1912f4ef796f29d34e6a7a35cc51c6c4bef1252678c58180ff4e90a121663acbaf5c4ff90a197258e2ab596f7b873364ca80ea3096bc675e97df5bead languageName: node linkType: hard -"@opentelemetry/resources@npm:1.18.1": - version: 1.18.1 - resolution: "@opentelemetry/resources@npm:1.18.1" +"@opentelemetry/resources@npm:1.20.0": + version: 1.20.0 + resolution: "@opentelemetry/resources@npm:1.20.0" dependencies: - "@opentelemetry/core": 1.18.1 - "@opentelemetry/semantic-conventions": 1.18.1 + "@opentelemetry/core": 1.20.0 + "@opentelemetry/semantic-conventions": 1.20.0 peerDependencies: "@opentelemetry/api": ">=1.0.0 <1.8.0" - checksum: b3311734802dca77eb379331ae7c409867ffe82cf17bca0e362de49e2d28313441a0177f62fc8c6c1f605bfc82c50e80ac065f17d81fc4fa131afff146db6432 + checksum: 22b851789bccd778901ea095f51006b57b0059ddeb0ff153ce548c92cd83202af5739fc9dd5c1d2e4640c8eacf7a08ffd24d5ae30f2ebae60855b026ecb87d33 languageName: node linkType: hard -"@opentelemetry/sdk-metrics@npm:1.18.1, @opentelemetry/sdk-metrics@npm:^1.13.0": - version: 1.18.1 - resolution: "@opentelemetry/sdk-metrics@npm:1.18.1" +"@opentelemetry/sdk-metrics@npm:1.20.0, @opentelemetry/sdk-metrics@npm:^1.13.0": + version: 1.20.0 + resolution: "@opentelemetry/sdk-metrics@npm:1.20.0" dependencies: - "@opentelemetry/core": 1.18.1 - "@opentelemetry/resources": 1.18.1 + "@opentelemetry/core": 1.20.0 + "@opentelemetry/resources": 1.20.0 lodash.merge: ^4.6.2 peerDependencies: "@opentelemetry/api": ">=1.3.0 <1.8.0" - checksum: ed2b87ea6380adc04bf50955cf7ae65220c6f35292b7d0535562c2e83d8b672306103c48fd45f3cc03ab3d640a8d2c6e367b265f5f4b0cbe03b0f51eb85759c7 + checksum: 6bd2d77ee14d85d9894ba08715969bc18d75582a53d9d31e2fed6a77f46c32e5fbae6daf6f1c32446a3cc5169620b7f29da27ca006d7c16750f9d83966fd864e languageName: node linkType: hard -"@opentelemetry/semantic-conventions@npm:1.18.1": - version: 1.18.1 - resolution: "@opentelemetry/semantic-conventions@npm:1.18.1" - checksum: b60c008c01067c0e8f130ab5d61f5207c85b6db08fa926f629c854ab9917ca93fbabd7ae8d1586f9f82e3b29706b0444ded9d6781f7fb7a003eeb27d89af468f +"@opentelemetry/semantic-conventions@npm:1.20.0": + version: 1.20.0 + resolution: "@opentelemetry/semantic-conventions@npm:1.20.0" + checksum: c71d466ab37158c57ff15a8fcb55682c812993b9d0d8e05114094abbe70f5ce2735909d70b749fddbc0621e5cdae19fecbb4e087034f606bce98e3bf9c74613e languageName: node linkType: hard @@ -26633,7 +26633,7 @@ __metadata: "@gitbeaker/node": ^35.1.0 "@octokit/rest": ^19.0.3 "@opentelemetry/api": ^1.4.1 - "@opentelemetry/exporter-prometheus": ^0.45.0 + "@opentelemetry/exporter-prometheus": ^0.47.0 "@opentelemetry/sdk-metrics": ^1.13.0 "@types/dockerode": ^3.3.0 "@types/express": ^4.17.6 From 88802efe66675582911b7273b297d20f23917c61 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 17:53:38 +0000 Subject: [PATCH 282/283] fix(deps): update dependency @smithy/node-http-handler to v2.3.1 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 62 +++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/yarn.lock b/yarn.lock index ede8d0e77a..4992eb3807 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15347,13 +15347,13 @@ __metadata: languageName: node linkType: hard -"@smithy/abort-controller@npm:^2.1.0": - version: 2.1.0 - resolution: "@smithy/abort-controller@npm:2.1.0" +"@smithy/abort-controller@npm:^2.1.0, @smithy/abort-controller@npm:^2.1.1": + version: 2.1.1 + resolution: "@smithy/abort-controller@npm:2.1.1" dependencies: - "@smithy/types": ^2.9.0 + "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: 52ad57706997dd1fabeb5b4d1f43d65403f31f8c7bf2fd6addb84b8132b406763574911499ab757be1c0c7329c06c574174750f17383507cfb05e1df05b26882 + checksum: 4bfad0d6b3a75bd1e6f997aa41cc9d8ba8bfdf548cfe703553ad7b42f0bf3e06b595d584be7b9ab90d2e3b22aacad94c02c32e21bea96e46933443f09c59523a languageName: node linkType: hard @@ -15627,15 +15627,15 @@ __metadata: linkType: hard "@smithy/node-http-handler@npm:^2.1.7, @smithy/node-http-handler@npm:^2.3.0": - version: 2.3.0 - resolution: "@smithy/node-http-handler@npm:2.3.0" + version: 2.3.1 + resolution: "@smithy/node-http-handler@npm:2.3.1" dependencies: - "@smithy/abort-controller": ^2.1.0 - "@smithy/protocol-http": ^3.1.0 - "@smithy/querystring-builder": ^2.1.0 - "@smithy/types": ^2.9.0 + "@smithy/abort-controller": ^2.1.1 + "@smithy/protocol-http": ^3.1.1 + "@smithy/querystring-builder": ^2.1.1 + "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: 8f431d7fa4e07908ecfd58d13721b5adc41519415e9ea58d104ab44da008c0244fd551a6fddc27e9bac1ca8ba98d3f117b37c379c096e5038ff70b723466dce6 + checksum: e6a514098f44cfc962318b15df79bb5e9de7fffe883fe073965879b2cf2436726709b5be14262871794104272e8506f793f8e77b8bf5b36398714a3a51512516 languageName: node linkType: hard @@ -15649,24 +15649,24 @@ __metadata: languageName: node linkType: hard -"@smithy/protocol-http@npm:^3.1.0": - version: 3.1.0 - resolution: "@smithy/protocol-http@npm:3.1.0" +"@smithy/protocol-http@npm:^3.1.0, @smithy/protocol-http@npm:^3.1.1": + version: 3.1.1 + resolution: "@smithy/protocol-http@npm:3.1.1" dependencies: - "@smithy/types": ^2.9.0 + "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: 3aae910192708bfd5cc3de85dc28c2eb7f6b425d6edc2b930f769330bc4912f8e7ff2a5dc8b9dd98614d1f9fa8d4f64a9f9eb45e54c4da94e29612accc3218fc + checksum: a5be1c5b5bff18c5a35c23870e1ffa38da33e56f93bdd8f26c615f4c0d2d3e1effffe441e756c0b0ba3aad2dd0845332f634702bf8455ed865a04eebfef1329b languageName: node linkType: hard -"@smithy/querystring-builder@npm:^2.1.0": - version: 2.1.0 - resolution: "@smithy/querystring-builder@npm:2.1.0" +"@smithy/querystring-builder@npm:^2.1.0, @smithy/querystring-builder@npm:^2.1.1": + version: 2.1.1 + resolution: "@smithy/querystring-builder@npm:2.1.1" dependencies: - "@smithy/types": ^2.9.0 - "@smithy/util-uri-escape": ^2.1.0 + "@smithy/types": ^2.9.1 + "@smithy/util-uri-escape": ^2.1.1 tslib: ^2.5.0 - checksum: 307cfec9c5765b9aca10318913cd91513d323895d9cfb863309b49fe634dfdb3ebf74ef3dc17e3d4aa60d1c4e8f48a63cfd11c2b2099b36cd4d9f53198e933a0 + checksum: b8623c7ef6d19fb21c41bfda29cce9c673ac501914085b39642ff5a72cf5742b19cd9de1a1851d13f2e1bbfc2e9522070b5ca32ed906aacf93f732a56e76098a languageName: node linkType: hard @@ -15738,12 +15738,12 @@ __metadata: languageName: node linkType: hard -"@smithy/types@npm:^2.9.0": - version: 2.9.0 - resolution: "@smithy/types@npm:2.9.0" +"@smithy/types@npm:^2.9.0, @smithy/types@npm:^2.9.1": + version: 2.9.1 + resolution: "@smithy/types@npm:2.9.1" dependencies: tslib: ^2.5.0 - checksum: 74d59ddcc2eca419c493b99d09f912e72511d088df0c6b6548df876dd49407b3cbb68550c9d6fa1d03d65f96bb099c450bdad1b4724d52144ca65f547850a4bb + checksum: 8570affb4abb5d0ead57293977fc915d44be481120defcabb87a3fb1c7b5d2501b117835eca357b5d54ea4bbee08032f9dc3d909ecbf0abb0cec2ca9678ae7bd languageName: node linkType: hard @@ -15890,12 +15890,12 @@ __metadata: languageName: node linkType: hard -"@smithy/util-uri-escape@npm:^2.1.0": - version: 2.1.0 - resolution: "@smithy/util-uri-escape@npm:2.1.0" +"@smithy/util-uri-escape@npm:^2.1.0, @smithy/util-uri-escape@npm:^2.1.1": + version: 2.1.1 + resolution: "@smithy/util-uri-escape@npm:2.1.1" dependencies: tslib: ^2.5.0 - checksum: 11aca3e04a57428266fdb09f408f21bb51d5fa0b6b31ceb5769a63c670ad8f24c95bcbc1d6046d625b7992293e86f46207d1018233130e9f4c4e97d236ff9cd8 + checksum: 822ed7390e28d5c7b8dab5e5c5a8de998e0778220137962a71b47b2d8900289d48a3a2c9945e68e1cac921d43f61660045e7fdffe8df9e63004575fcf2aa99b2 languageName: node linkType: hard From c7259dc12dc8743570c62b55cfbfdc6c485f20ea Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 20 Jan 2024 10:25:48 +0100 Subject: [PATCH 283/283] changesets: added changeset for cli backend module template update Signed-off-by: Patrik Oldsberg --- .changeset/two-coats-smile.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/two-coats-smile.md diff --git a/.changeset/two-coats-smile.md b/.changeset/two-coats-smile.md new file mode 100644 index 0000000000..65abb7a1eb --- /dev/null +++ b/.changeset/two-coats-smile.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Updated the backend module template to make the module instance the package default export.