@backstage-community/plugin-bitbucket-pull-requests 3.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @backstage-community/plugin-bitbucket-pull-requests
2
2
 
3
+ ## 3.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - d1c665e: Replace cross-fetch with Backstage fetchApi and add config visibility for bitbucket.proxyPath
8
+
3
9
  ## 3.0.0
4
10
 
5
11
  ### Major Changes
package/config.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ /*
2
+ * Copyright 2026 The Backstage Authors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ export interface Config {
17
+ bitbucket?: {
18
+ /**
19
+ * Proxy path for BitBucket API requests
20
+ * @visibility frontend
21
+ */
22
+ proxyPath?: string;
23
+ };
24
+ }
@@ -1,4 +1,3 @@
1
- import fetch from 'cross-fetch';
2
1
  import { createApiRef } from '@backstage/core-plugin-api';
3
2
  import { parseEntityRef } from '@backstage/catalog-model';
4
3
 
@@ -11,10 +10,12 @@ class BitbucketApi {
11
10
  discoveryApi;
12
11
  identityApi;
13
12
  configApi;
13
+ fetchApi;
14
14
  constructor(options) {
15
15
  this.discoveryApi = options.discoveryApi;
16
16
  this.identityApi = options.identityApi;
17
17
  this.configApi = options.configApi;
18
+ this.fetchApi = options.fetchApi;
18
19
  }
19
20
  /**
20
21
  * Gets the configured proxy path from config or returns the default
@@ -33,7 +34,7 @@ class BitbucketApi {
33
34
  params.append("state", state);
34
35
  }
35
36
  params.append("limit", limit.toString());
36
- const response = await fetch(`${url}?${params}`, {
37
+ const response = await this.fetchApi.fetch(`${url}?${params}`, {
37
38
  headers: {
38
39
  "Content-Type": "application/json"
39
40
  }
@@ -46,7 +47,7 @@ class BitbucketApi {
46
47
  }
47
48
  async fetchBuildStatus(commitId) {
48
49
  const proxyUrl = await this.discoveryApi.getBaseUrl("proxy");
49
- const response = await fetch(
50
+ const response = await this.fetchApi.fetch(
50
51
  `${proxyUrl}${this.getProxyPath()}/rest/build-status/latest/commits/stats/${commitId}`,
51
52
  { headers: { "Content-Type": "application/json" } }
52
53
  );
@@ -119,7 +120,7 @@ class BitbucketApi {
119
120
  role,
120
121
  user: name
121
122
  });
122
- const response = await fetch(`${url}?${params}`, {
123
+ const response = await this.fetchApi.fetch(`${url}?${params}`, {
123
124
  headers: {
124
125
  "Content-Type": "application/json"
125
126
  }
@@ -1 +1 @@
1
- {"version":3,"file":"BitbucketApi.esm.js","sources":["../../src/api/BitbucketApi.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport fetch from 'cross-fetch';\n\nimport {\n createApiRef,\n DiscoveryApi,\n IdentityApi,\n ConfigApi,\n} from '@backstage/core-plugin-api';\nimport { parseEntityRef } from '@backstage/catalog-model';\n\nexport const bitbucketApiRef = createApiRef<BitbucketApi>({\n id: 'plugin.bitbucket.service',\n});\n\nexport type User = {\n displayName: string;\n slug: string;\n};\n\nexport type BuildStatus = {\n cancelled: number;\n failed: number;\n inProgress: number;\n successful: number;\n unknown: number;\n};\n\nexport type PullRequest = {\n id: number;\n title: string;\n author: User;\n createdDate: number;\n updatedDate: number;\n state: string;\n description: string;\n url: string;\n repoUrl: string;\n fromRepo: string;\n fromProject: string;\n sourceBranch: string;\n targetBranch: string;\n latestCommit?: string;\n buildStatus?: 'SUCCESSFUL' | 'FAILED' | 'INPROGRESS' | 'STOPPED' | 'UNKNOWN';\n reviewers: User[];\n};\nconst DEFAULT_PROXY_PATH = '/bitbucket/api';\nconst DEFAULT_LIMIT = 50;\ntype Options = {\n discoveryApi: DiscoveryApi;\n identityApi: IdentityApi;\n configApi?: ConfigApi;\n};\nexport class BitbucketApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly identityApi: IdentityApi;\n private readonly configApi?: ConfigApi;\n\n constructor(options: Options) {\n this.discoveryApi = options.discoveryApi;\n this.identityApi = options.identityApi;\n this.configApi = options.configApi;\n }\n\n /**\n * Gets the configured proxy path from config or returns the default\n * @returns The configured proxy path\n */\n private getProxyPath(): string {\n return (\n this.configApi?.getOptionalString('bitbucket.proxyPath') ||\n DEFAULT_PROXY_PATH\n );\n }\n\n async fetchPullRequestListForRepo(\n project: string,\n repo: string,\n state?: string,\n limit: number = DEFAULT_LIMIT,\n ): Promise<PullRequest[]> {\n const proxyUrl = await this.discoveryApi.getBaseUrl('proxy');\n const url = new URL(\n `${proxyUrl}${this.getProxyPath()}/projects/${project}/repos/${repo}/pull-requests`,\n );\n\n const params = new URLSearchParams();\n if (state) {\n params.append('state', state);\n }\n params.append('limit', limit.toString());\n\n const response = await fetch(`${url}?${params}`, {\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n if (!response.ok) {\n throw new Error('Failed to fetch pull requests');\n }\n\n const data = await response.json();\n return this.mapPullRequests(data);\n }\n\n private async fetchBuildStatus(commitId: string): Promise<BuildStatus> {\n const proxyUrl = await this.discoveryApi.getBaseUrl('proxy');\n const response = await fetch(\n `${proxyUrl}${this.getProxyPath()}/rest/build-status/latest/commits/stats/${commitId}`,\n { headers: { 'Content-Type': 'application/json' } },\n );\n\n if (!response.ok) {\n throw new Error(`Failed to fetch build status for commit ${commitId}`);\n }\n\n return response.json();\n }\n\n private determineBuildState(\n status: BuildStatus,\n ): 'SUCCESSFUL' | 'FAILED' | 'INPROGRESS' | 'STOPPED' | undefined {\n if (status.failed > 0) return 'FAILED';\n if (status.inProgress > 0) return 'INPROGRESS';\n if (status.cancelled > 0) return 'STOPPED';\n if (status.successful > 0) return 'SUCCESSFUL';\n return undefined;\n }\n\n private async enhancePrWithBuildStatus(\n pr: PullRequest,\n ): Promise<PullRequest> {\n if (pr.latestCommit) {\n return this.fetchBuildStatus(pr.latestCommit)\n .then(buildStatus => ({\n ...pr,\n buildStatus: this.determineBuildState(buildStatus),\n }))\n .catch(() => ({\n ...pr,\n buildStatus: 'UNKNOWN' as const,\n }));\n }\n return pr;\n }\n\n public mapPullRequests(data: any): PullRequest[] {\n return (\n data.values?.map((pr: any) => ({\n id: pr.id,\n title: pr.title,\n author: {\n displayName: pr.author.user.displayName,\n slug: pr.author.user.slug,\n },\n createdDate: pr.createdDate,\n updatedDate: pr.updatedDate,\n state: pr.state,\n url: pr.links.self[0].href,\n repoUrl: pr.fromRef.repository.links.self[0].href,\n description: pr.description || '',\n fromRepo: pr.fromRef.repository.name,\n fromProject: pr.fromRef.repository.project.key,\n sourceBranch: pr.fromRef.displayId,\n targetBranch: pr.toRef.displayId,\n latestCommit: pr.fromRef.latestCommit,\n reviewers:\n pr.reviewers?.map((r: any) => ({\n displayName: r.user.displayName,\n slug: r.user.slug,\n })) || [],\n })) || []\n );\n }\n\n async fetchUserPullRequests(\n role: 'REVIEWER' | 'AUTHOR' = 'REVIEWER',\n state: 'OPEN' | 'MERGED' | 'DECLINED' | 'ALL' = 'OPEN',\n limit: number = DEFAULT_LIMIT,\n options: { includeBuildStatus?: boolean } = { includeBuildStatus: true },\n ): Promise<PullRequest[]> {\n if (!this.identityApi) {\n throw new Error('Identity API is not available');\n }\n\n const { userEntityRef } = await this.identityApi.getBackstageIdentity();\n\n const { name } = parseEntityRef(userEntityRef);\n\n if (!name) {\n throw new Error('User not found');\n }\n\n const proxyUrl = await this.discoveryApi.getBaseUrl('proxy');\n const url = new URL(\n `${proxyUrl}${this.getProxyPath()}/dashboard/pull-requests`,\n );\n\n const params = new URLSearchParams({\n order: 'participant_status',\n limit: limit.toString(),\n state,\n role,\n user: name,\n });\n\n const response = await fetch(`${url}?${params}`, {\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n let errorMessage = 'Failed to fetch pull requests from Bitbucket';\n\n try {\n const errorText = await response.text();\n const errorJson = JSON.parse(errorText);\n\n if (\n response.status === 404 &&\n errorJson.errors?.[0]?.message?.includes('does not exist')\n ) {\n errorMessage = `User '${name}' not found in Bitbucket. Please ensure your Bitbucket account exists.`;\n }\n } catch (e) {\n errorMessage = e instanceof Error ? e.message : String(e);\n }\n\n throw new Error(errorMessage);\n }\n\n const data = await response.json();\n const pullRequests = this.mapPullRequests(data);\n if (options.includeBuildStatus) {\n const enhancedPullRequests = await Promise.all(\n pullRequests.map(pr => this.enhancePrWithBuildStatus(pr)),\n );\n return enhancedPullRequests;\n }\n return pullRequests;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BitbucketApi.esm.js","sources":["../../src/api/BitbucketApi.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createApiRef,\n DiscoveryApi,\n IdentityApi,\n ConfigApi,\n FetchApi,\n} from '@backstage/core-plugin-api';\nimport { parseEntityRef } from '@backstage/catalog-model';\n\nexport const bitbucketApiRef = createApiRef<BitbucketApi>({\n id: 'plugin.bitbucket.service',\n});\n\nexport type User = {\n displayName: string;\n slug: string;\n};\n\nexport type BuildStatus = {\n cancelled: number;\n failed: number;\n inProgress: number;\n successful: number;\n unknown: number;\n};\n\nexport type PullRequest = {\n id: number;\n title: string;\n author: User;\n createdDate: number;\n updatedDate: number;\n state: string;\n description: string;\n url: string;\n repoUrl: string;\n fromRepo: string;\n fromProject: string;\n sourceBranch: string;\n targetBranch: string;\n latestCommit?: string;\n buildStatus?: 'SUCCESSFUL' | 'FAILED' | 'INPROGRESS' | 'STOPPED' | 'UNKNOWN';\n reviewers: User[];\n};\nconst DEFAULT_PROXY_PATH = '/bitbucket/api';\nconst DEFAULT_LIMIT = 50;\ntype Options = {\n discoveryApi: DiscoveryApi;\n identityApi: IdentityApi;\n configApi?: ConfigApi;\n fetchApi: FetchApi;\n};\nexport class BitbucketApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly identityApi: IdentityApi;\n private readonly configApi?: ConfigApi;\n private readonly fetchApi: FetchApi;\n\n constructor(options: Options) {\n this.discoveryApi = options.discoveryApi;\n this.identityApi = options.identityApi;\n this.configApi = options.configApi;\n this.fetchApi = options.fetchApi;\n }\n\n /**\n * Gets the configured proxy path from config or returns the default\n * @returns The configured proxy path\n */\n private getProxyPath(): string {\n return (\n this.configApi?.getOptionalString('bitbucket.proxyPath') ||\n DEFAULT_PROXY_PATH\n );\n }\n\n async fetchPullRequestListForRepo(\n project: string,\n repo: string,\n state?: string,\n limit: number = DEFAULT_LIMIT,\n ): Promise<PullRequest[]> {\n const proxyUrl = await this.discoveryApi.getBaseUrl('proxy');\n const url = new URL(\n `${proxyUrl}${this.getProxyPath()}/projects/${project}/repos/${repo}/pull-requests`,\n );\n\n const params = new URLSearchParams();\n if (state) {\n params.append('state', state);\n }\n params.append('limit', limit.toString());\n\n const response = await this.fetchApi.fetch(`${url}?${params}`, {\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n if (!response.ok) {\n throw new Error('Failed to fetch pull requests');\n }\n\n const data = await response.json();\n return this.mapPullRequests(data);\n }\n\n private async fetchBuildStatus(commitId: string): Promise<BuildStatus> {\n const proxyUrl = await this.discoveryApi.getBaseUrl('proxy');\n const response = await this.fetchApi.fetch(\n `${proxyUrl}${this.getProxyPath()}/rest/build-status/latest/commits/stats/${commitId}`,\n { headers: { 'Content-Type': 'application/json' } },\n );\n\n if (!response.ok) {\n throw new Error(`Failed to fetch build status for commit ${commitId}`);\n }\n\n return response.json();\n }\n\n private determineBuildState(\n status: BuildStatus,\n ): 'SUCCESSFUL' | 'FAILED' | 'INPROGRESS' | 'STOPPED' | undefined {\n if (status.failed > 0) return 'FAILED';\n if (status.inProgress > 0) return 'INPROGRESS';\n if (status.cancelled > 0) return 'STOPPED';\n if (status.successful > 0) return 'SUCCESSFUL';\n return undefined;\n }\n\n private async enhancePrWithBuildStatus(\n pr: PullRequest,\n ): Promise<PullRequest> {\n if (pr.latestCommit) {\n return this.fetchBuildStatus(pr.latestCommit)\n .then(buildStatus => ({\n ...pr,\n buildStatus: this.determineBuildState(buildStatus),\n }))\n .catch(() => ({\n ...pr,\n buildStatus: 'UNKNOWN' as const,\n }));\n }\n return pr;\n }\n\n public mapPullRequests(data: any): PullRequest[] {\n return (\n data.values?.map((pr: any) => ({\n id: pr.id,\n title: pr.title,\n author: {\n displayName: pr.author.user.displayName,\n slug: pr.author.user.slug,\n },\n createdDate: pr.createdDate,\n updatedDate: pr.updatedDate,\n state: pr.state,\n url: pr.links.self[0].href,\n repoUrl: pr.fromRef.repository.links.self[0].href,\n description: pr.description || '',\n fromRepo: pr.fromRef.repository.name,\n fromProject: pr.fromRef.repository.project.key,\n sourceBranch: pr.fromRef.displayId,\n targetBranch: pr.toRef.displayId,\n latestCommit: pr.fromRef.latestCommit,\n reviewers:\n pr.reviewers?.map((r: any) => ({\n displayName: r.user.displayName,\n slug: r.user.slug,\n })) || [],\n })) || []\n );\n }\n\n async fetchUserPullRequests(\n role: 'REVIEWER' | 'AUTHOR' = 'REVIEWER',\n state: 'OPEN' | 'MERGED' | 'DECLINED' | 'ALL' = 'OPEN',\n limit: number = DEFAULT_LIMIT,\n options: { includeBuildStatus?: boolean } = { includeBuildStatus: true },\n ): Promise<PullRequest[]> {\n if (!this.identityApi) {\n throw new Error('Identity API is not available');\n }\n\n const { userEntityRef } = await this.identityApi.getBackstageIdentity();\n\n const { name } = parseEntityRef(userEntityRef);\n\n if (!name) {\n throw new Error('User not found');\n }\n\n const proxyUrl = await this.discoveryApi.getBaseUrl('proxy');\n const url = new URL(\n `${proxyUrl}${this.getProxyPath()}/dashboard/pull-requests`,\n );\n\n const params = new URLSearchParams({\n order: 'participant_status',\n limit: limit.toString(),\n state,\n role,\n user: name,\n });\n\n const response = await this.fetchApi.fetch(`${url}?${params}`, {\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n let errorMessage = 'Failed to fetch pull requests from Bitbucket';\n\n try {\n const errorText = await response.text();\n const errorJson = JSON.parse(errorText);\n\n if (\n response.status === 404 &&\n errorJson.errors?.[0]?.message?.includes('does not exist')\n ) {\n errorMessage = `User '${name}' not found in Bitbucket. Please ensure your Bitbucket account exists.`;\n }\n } catch (e) {\n errorMessage = e instanceof Error ? e.message : String(e);\n }\n\n throw new Error(errorMessage);\n }\n\n const data = await response.json();\n const pullRequests = this.mapPullRequests(data);\n if (options.includeBuildStatus) {\n const enhancedPullRequests = await Promise.all(\n pullRequests.map(pr => this.enhancePrWithBuildStatus(pr)),\n );\n return enhancedPullRequests;\n }\n return pullRequests;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { createPlugin, createApiFactory, configApiRef, identityApiRef, discoveryApiRef, createRoutableExtension } from '@backstage/core-plugin-api';
1
+ import { createPlugin, createApiFactory, fetchApiRef, configApiRef, identityApiRef, discoveryApiRef, createRoutableExtension } from '@backstage/core-plugin-api';
2
2
  import { rootRouteRef } from './routes.esm.js';
3
3
  import { BitbucketApi, bitbucketApiRef } from './api/BitbucketApi.esm.js';
4
4
  import 'react/jsx-runtime';
@@ -14,9 +14,10 @@ const bitbucketPlugin = createPlugin({
14
14
  deps: {
15
15
  discoveryApi: discoveryApiRef,
16
16
  identityApi: identityApiRef,
17
- configApi: configApiRef
17
+ configApi: configApiRef,
18
+ fetchApi: fetchApiRef
18
19
  },
19
- factory: ({ discoveryApi, identityApi, configApi }) => new BitbucketApi({ discoveryApi, identityApi, configApi })
20
+ factory: ({ discoveryApi, identityApi, configApi, fetchApi }) => new BitbucketApi({ discoveryApi, identityApi, configApi, fetchApi })
20
21
  })
21
22
  ],
22
23
  routes: {
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createPlugin,\n createApiFactory,\n discoveryApiRef,\n createRoutableExtension,\n identityApiRef,\n configApiRef,\n} from '@backstage/core-plugin-api';\nimport { rootRouteRef } from './routes';\nimport { bitbucketApiRef, BitbucketApi } from './api/BitbucketApi';\n\n/**\n * Plugin for Bitbucket pull requests integration\n * @public\n */\nexport const bitbucketPlugin = createPlugin({\n id: 'bitbucket-pullrequests',\n apis: [\n createApiFactory({\n api: bitbucketApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n identityApi: identityApiRef,\n configApi: configApiRef,\n },\n factory: ({ discoveryApi, identityApi, configApi }) =>\n new BitbucketApi({ discoveryApi, identityApi, configApi }),\n }),\n ],\n routes: {\n root: rootRouteRef,\n },\n});\n\n/**\n * Component for displaying Bitbucket pull requests in the entity page\n * @public\n */\nexport const EntityBitbucketPullRequestsContent = bitbucketPlugin.provide(\n createRoutableExtension({\n name: 'EntityBitbucketPullRequestsContent',\n component: () => import('./components/Router').then(m => m.Router),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport { HomePagePullRequestsCard } from './components/HomePage/HomePagePullRequestsCard';\nexport type { HomePagePullRequestsCardProps } from './components/HomePage/HomePagePullRequestsCard';\n"],"names":[],"mappings":";;;;;;;;AA+BO,MAAM,kBAAkB,YAAA,CAAa;AAAA,EAC1C,EAAA,EAAI,wBAAA;AAAA,EACJ,IAAA,EAAM;AAAA,IACJ,gBAAA,CAAiB;AAAA,MACf,GAAA,EAAK,eAAA;AAAA,MACL,IAAA,EAAM;AAAA,QACJ,YAAA,EAAc,eAAA;AAAA,QACd,WAAA,EAAa,cAAA;AAAA,QACb,SAAA,EAAW;AAAA,OACb;AAAA,MACA,OAAA,EAAS,CAAC,EAAE,YAAA,EAAc,WAAA,EAAa,SAAA,EAAU,KAC/C,IAAI,YAAA,CAAa,EAAE,YAAA,EAAc,WAAA,EAAa,WAAW;AAAA,KAC5D;AAAA,GACH;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM;AAAA;AAEV,CAAC;AAMM,MAAM,qCAAqC,eAAA,CAAgB,OAAA;AAAA,EAChE,uBAAA,CAAwB;AAAA,IACtB,IAAA,EAAM,oCAAA;AAAA,IACN,SAAA,EAAW,MAAM,OAAO,4BAAqB,EAAE,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,MAAM,CAAA;AAAA,IACjE,UAAA,EAAY;AAAA,GACb;AACH;;;;"}
1
+ {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createPlugin,\n createApiFactory,\n discoveryApiRef,\n createRoutableExtension,\n identityApiRef,\n configApiRef,\n fetchApiRef,\n} from '@backstage/core-plugin-api';\nimport { rootRouteRef } from './routes';\nimport { bitbucketApiRef, BitbucketApi } from './api/BitbucketApi';\n\n/**\n * Plugin for Bitbucket pull requests integration\n * @public\n */\nexport const bitbucketPlugin = createPlugin({\n id: 'bitbucket-pullrequests',\n apis: [\n createApiFactory({\n api: bitbucketApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n identityApi: identityApiRef,\n configApi: configApiRef,\n fetchApi: fetchApiRef,\n },\n factory: ({ discoveryApi, identityApi, configApi, fetchApi }) =>\n new BitbucketApi({ discoveryApi, identityApi, configApi, fetchApi }),\n }),\n ],\n routes: {\n root: rootRouteRef,\n },\n});\n\n/**\n * Component for displaying Bitbucket pull requests in the entity page\n * @public\n */\nexport const EntityBitbucketPullRequestsContent = bitbucketPlugin.provide(\n createRoutableExtension({\n name: 'EntityBitbucketPullRequestsContent',\n component: () => import('./components/Router').then(m => m.Router),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport { HomePagePullRequestsCard } from './components/HomePage/HomePagePullRequestsCard';\nexport type { HomePagePullRequestsCardProps } from './components/HomePage/HomePagePullRequestsCard';\n"],"names":[],"mappings":";;;;;;;;AAgCO,MAAM,kBAAkB,YAAA,CAAa;AAAA,EAC1C,EAAA,EAAI,wBAAA;AAAA,EACJ,IAAA,EAAM;AAAA,IACJ,gBAAA,CAAiB;AAAA,MACf,GAAA,EAAK,eAAA;AAAA,MACL,IAAA,EAAM;AAAA,QACJ,YAAA,EAAc,eAAA;AAAA,QACd,WAAA,EAAa,cAAA;AAAA,QACb,SAAA,EAAW,YAAA;AAAA,QACX,QAAA,EAAU;AAAA,OACZ;AAAA,MACA,OAAA,EAAS,CAAC,EAAE,YAAA,EAAc,aAAa,SAAA,EAAW,QAAA,EAAS,KACzD,IAAI,aAAa,EAAE,YAAA,EAAc,WAAA,EAAa,SAAA,EAAW,UAAU;AAAA,KACtE;AAAA,GACH;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM;AAAA;AAEV,CAAC;AAMM,MAAM,qCAAqC,eAAA,CAAgB,OAAA;AAAA,EAChE,uBAAA,CAAwB;AAAA,IACtB,IAAA,EAAM,oCAAA;AAAA,IACN,SAAA,EAAW,MAAM,OAAO,4BAAqB,EAAE,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,MAAM,CAAA;AAAA,IACjE,UAAA,EAAY;AAAA,GACb;AACH;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage-community/plugin-bitbucket-pull-requests",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "main": "dist/index.esm.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -70,8 +70,10 @@
70
70
  "react-dom": "^18"
71
71
  },
72
72
  "files": [
73
- "dist"
73
+ "dist",
74
+ "config.d.ts"
74
75
  ],
76
+ "configSchema": "config.d.ts",
75
77
  "typesVersions": {
76
78
  "*": {
77
79
  "package.json": [