@backstage/integration 1.21.0-next.0 → 2.0.0-next.2

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.
Files changed (52) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/config.d.ts +3 -60
  3. package/dist/ScmIntegrations.cjs.js +1 -17
  4. package/dist/ScmIntegrations.cjs.js.map +1 -1
  5. package/dist/ScmIntegrations.esm.js +1 -17
  6. package/dist/ScmIntegrations.esm.js.map +1 -1
  7. package/dist/azure/config.cjs.js +14 -35
  8. package/dist/azure/config.cjs.js.map +1 -1
  9. package/dist/azure/config.esm.js +14 -35
  10. package/dist/azure/config.esm.js.map +1 -1
  11. package/dist/bitbucketCloud/core.cjs.js +3 -2
  12. package/dist/bitbucketCloud/core.cjs.js.map +1 -1
  13. package/dist/bitbucketCloud/core.esm.js +3 -2
  14. package/dist/bitbucketCloud/core.esm.js.map +1 -1
  15. package/dist/bitbucketServer/core.cjs.js +8 -2
  16. package/dist/bitbucketServer/core.cjs.js.map +1 -1
  17. package/dist/bitbucketServer/core.esm.js +8 -2
  18. package/dist/bitbucketServer/core.esm.js.map +1 -1
  19. package/dist/gerrit/core.cjs.js +6 -33
  20. package/dist/gerrit/core.cjs.js.map +1 -1
  21. package/dist/gerrit/core.esm.js +7 -32
  22. package/dist/gerrit/core.esm.js.map +1 -1
  23. package/dist/github/core.cjs.js +2 -17
  24. package/dist/github/core.cjs.js.map +1 -1
  25. package/dist/github/core.esm.js +3 -13
  26. package/dist/github/core.esm.js.map +1 -1
  27. package/dist/helpers.cjs.js +23 -1
  28. package/dist/helpers.cjs.js.map +1 -1
  29. package/dist/helpers.esm.js +23 -2
  30. package/dist/helpers.esm.js.map +1 -1
  31. package/dist/index.cjs.js +61 -76
  32. package/dist/index.cjs.js.map +1 -1
  33. package/dist/index.d.ts +2 -222
  34. package/dist/index.esm.js +2 -6
  35. package/dist/index.esm.js.map +1 -1
  36. package/package.json +2 -2
  37. package/dist/azure/deprecated.cjs.js +0 -26
  38. package/dist/azure/deprecated.cjs.js.map +0 -1
  39. package/dist/azure/deprecated.esm.js +0 -24
  40. package/dist/azure/deprecated.esm.js.map +0 -1
  41. package/dist/bitbucket/BitbucketIntegration.cjs.js +0 -65
  42. package/dist/bitbucket/BitbucketIntegration.cjs.js.map +0 -1
  43. package/dist/bitbucket/BitbucketIntegration.esm.js +0 -59
  44. package/dist/bitbucket/BitbucketIntegration.esm.js.map +0 -1
  45. package/dist/bitbucket/config.cjs.js +0 -48
  46. package/dist/bitbucket/config.cjs.js.map +0 -1
  47. package/dist/bitbucket/config.esm.js +0 -45
  48. package/dist/bitbucket/config.esm.js.map +0 -1
  49. package/dist/bitbucket/core.cjs.js +0 -95
  50. package/dist/bitbucket/core.cjs.js.map +0 -1
  51. package/dist/bitbucket/core.esm.js +0 -85
  52. package/dist/bitbucket/core.esm.js.map +0 -1
@@ -1,45 +0,0 @@
1
- import { trimEnd } from 'lodash';
2
- import { isValidHost } from '../helpers.esm.js';
3
-
4
- const BITBUCKET_HOST = "bitbucket.org";
5
- const BITBUCKET_API_BASE_URL = "https://api.bitbucket.org/2.0";
6
- function readBitbucketIntegrationConfig(config) {
7
- const host = config.getOptionalString("host") ?? BITBUCKET_HOST;
8
- let apiBaseUrl = config.getOptionalString("apiBaseUrl");
9
- const token = config.getOptionalString("token")?.trim();
10
- const username = config.getOptionalString("username");
11
- const appPassword = config.getOptionalString("appPassword")?.trim();
12
- if (!isValidHost(host)) {
13
- throw new Error(
14
- `Invalid Bitbucket integration config, '${host}' is not a valid host`
15
- );
16
- }
17
- if (apiBaseUrl) {
18
- apiBaseUrl = trimEnd(apiBaseUrl, "/");
19
- } else if (host === BITBUCKET_HOST) {
20
- apiBaseUrl = BITBUCKET_API_BASE_URL;
21
- } else {
22
- apiBaseUrl = `https://${host}/rest/api/1.0`;
23
- }
24
- return {
25
- host,
26
- apiBaseUrl,
27
- token,
28
- username,
29
- appPassword,
30
- commitSigningKey: config.getOptionalString("commitSigningKey")
31
- };
32
- }
33
- function readBitbucketIntegrationConfigs(configs) {
34
- const result = configs.map(readBitbucketIntegrationConfig);
35
- if (!result.some((c) => c.host === BITBUCKET_HOST)) {
36
- result.push({
37
- host: BITBUCKET_HOST,
38
- apiBaseUrl: BITBUCKET_API_BASE_URL
39
- });
40
- }
41
- return result;
42
- }
43
-
44
- export { readBitbucketIntegrationConfig, readBitbucketIntegrationConfigs };
45
- //# sourceMappingURL=config.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.esm.js","sources":["../../src/bitbucket/config.ts"],"sourcesContent":["/*\n * Copyright 2020 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 { Config } from '@backstage/config';\nimport { trimEnd } from 'lodash';\nimport { isValidHost } from '../helpers';\n\nconst BITBUCKET_HOST = 'bitbucket.org';\nconst BITBUCKET_API_BASE_URL = 'https://api.bitbucket.org/2.0';\n\n/**\n * The configuration parameters for a single Bitbucket API provider.\n *\n * @public\n * @deprecated bitbucket integration replaced by integrations bitbucketCloud and bitbucketServer.\n */\nexport type BitbucketIntegrationConfig = {\n /**\n * The host of the target that this matches on, e.g. \"bitbucket.org\"\n */\n host: string;\n\n /**\n * The base URL of the API of this provider, e.g. \"https://api.bitbucket.org/2.0\",\n * with no trailing slash.\n *\n * Values omitted at the optional property at the app-config will be deduced\n * from the \"host\" value.\n */\n apiBaseUrl: string;\n\n /**\n * The authorization token to use for requests to a Bitbucket Server provider.\n *\n * See https://confluence.atlassian.com/bitbucketserver/personal-access-tokens-939515499.html\n *\n * If no token is specified, anonymous access is used.\n */\n token?: string;\n\n /**\n * The username to use for requests to Bitbucket Cloud (bitbucket.org).\n */\n username?: string;\n\n /**\n * Authentication with Bitbucket Cloud (bitbucket.org) is done using app passwords.\n *\n * See https://support.atlassian.com/bitbucket-cloud/docs/app-passwords/\n */\n appPassword?: string;\n\n /**\n * Signing key for commits\n */\n commitSigningKey?: string;\n};\n\n/**\n * Reads a single Bitbucket integration config.\n *\n * @param config - The config object of a single integration\n * @public\n * @deprecated bitbucket integration replaced by integrations bitbucketCloud and bitbucketServer.\n */\nexport function readBitbucketIntegrationConfig(\n config: Config,\n): BitbucketIntegrationConfig {\n const host = config.getOptionalString('host') ?? BITBUCKET_HOST;\n let apiBaseUrl = config.getOptionalString('apiBaseUrl');\n const token = config.getOptionalString('token')?.trim();\n const username = config.getOptionalString('username');\n const appPassword = config.getOptionalString('appPassword')?.trim();\n\n if (!isValidHost(host)) {\n throw new Error(\n `Invalid Bitbucket integration config, '${host}' is not a valid host`,\n );\n }\n\n if (apiBaseUrl) {\n apiBaseUrl = trimEnd(apiBaseUrl, '/');\n } else if (host === BITBUCKET_HOST) {\n apiBaseUrl = BITBUCKET_API_BASE_URL;\n } else {\n apiBaseUrl = `https://${host}/rest/api/1.0`;\n }\n\n return {\n host,\n apiBaseUrl,\n token,\n username,\n appPassword,\n commitSigningKey: config.getOptionalString('commitSigningKey'),\n };\n}\n\n/**\n * Reads a set of Bitbucket integration configs, and inserts some defaults for\n * public Bitbucket if not specified.\n *\n * @param configs - All of the integration config objects\n * @public\n * @deprecated bitbucket integration replaced by integrations bitbucketCloud and bitbucketServer.\n */\nexport function readBitbucketIntegrationConfigs(\n configs: Config[],\n): BitbucketIntegrationConfig[] {\n // First read all the explicit integrations\n const result = configs.map(readBitbucketIntegrationConfig);\n\n // If no explicit bitbucket.org integration was added, put one in the list as\n // a convenience\n if (!result.some(c => c.host === BITBUCKET_HOST)) {\n result.push({\n host: BITBUCKET_HOST,\n apiBaseUrl: BITBUCKET_API_BASE_URL,\n });\n }\n\n return result;\n}\n"],"names":[],"mappings":";;;AAoBA,MAAM,cAAA,GAAiB,eAAA;AACvB,MAAM,sBAAA,GAAyB,+BAAA;AAyDxB,SAAS,+BACd,MAAA,EAC4B;AAC5B,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,iBAAA,CAAkB,MAAM,CAAA,IAAK,cAAA;AACjD,EAAA,IAAI,UAAA,GAAa,MAAA,CAAO,iBAAA,CAAkB,YAAY,CAAA;AACtD,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,iBAAA,CAAkB,OAAO,GAAG,IAAA,EAAK;AACtD,EAAA,MAAM,QAAA,GAAW,MAAA,CAAO,iBAAA,CAAkB,UAAU,CAAA;AACpD,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,iBAAA,CAAkB,aAAa,GAAG,IAAA,EAAK;AAElE,EAAA,IAAI,CAAC,WAAA,CAAY,IAAI,CAAA,EAAG;AACtB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,0CAA0C,IAAI,CAAA,qBAAA;AAAA,KAChD;AAAA,EACF;AAEA,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,UAAA,GAAa,OAAA,CAAQ,YAAY,GAAG,CAAA;AAAA,EACtC,CAAA,MAAA,IAAW,SAAS,cAAA,EAAgB;AAClC,IAAA,UAAA,GAAa,sBAAA;AAAA,EACf,CAAA,MAAO;AACL,IAAA,UAAA,GAAa,WAAW,IAAI,CAAA,aAAA,CAAA;AAAA,EAC9B;AAEA,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,UAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAA;AAAA,IACA,gBAAA,EAAkB,MAAA,CAAO,iBAAA,CAAkB,kBAAkB;AAAA,GAC/D;AACF;AAUO,SAAS,gCACd,OAAA,EAC8B;AAE9B,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,8BAA8B,CAAA;AAIzD,EAAA,IAAI,CAAC,MAAA,CAAO,IAAA,CAAK,OAAK,CAAA,CAAE,IAAA,KAAS,cAAc,CAAA,EAAG;AAChD,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,IAAA,EAAM,cAAA;AAAA,MACN,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,MAAA;AACT;;;;"}
@@ -1,95 +0,0 @@
1
- 'use strict';
2
-
3
- var fetch = require('cross-fetch');
4
- var parseGitUrl = require('git-url-parse');
5
-
6
- function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
7
-
8
- var fetch__default = /*#__PURE__*/_interopDefaultCompat(fetch);
9
- var parseGitUrl__default = /*#__PURE__*/_interopDefaultCompat(parseGitUrl);
10
-
11
- async function getBitbucketDefaultBranch(url, config) {
12
- const { name: repoName, owner: project, resource } = parseGitUrl__default.default(url);
13
- const isHosted = resource === "bitbucket.org";
14
- let branchUrl = isHosted ? `${config.apiBaseUrl}/repositories/${project}/${repoName}` : `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/default-branch`;
15
- let response = await fetch__default.default(branchUrl, getBitbucketRequestOptions(config));
16
- if (response.status === 404 && !isHosted) {
17
- branchUrl = `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/branches/default`;
18
- response = await fetch__default.default(branchUrl, getBitbucketRequestOptions(config));
19
- }
20
- if (!response.ok) {
21
- const message = `Failed to retrieve default branch from ${branchUrl}, ${response.status} ${response.statusText}`;
22
- throw new Error(message);
23
- }
24
- let defaultBranch;
25
- if (isHosted) {
26
- const repoInfo = await response.json();
27
- defaultBranch = repoInfo.mainbranch.name;
28
- } else {
29
- const { displayId } = await response.json();
30
- defaultBranch = displayId;
31
- }
32
- if (!defaultBranch) {
33
- throw new Error(
34
- `Failed to read default branch from ${branchUrl}. Response ${response.status} ${response.json()}`
35
- );
36
- }
37
- return defaultBranch;
38
- }
39
- async function getBitbucketDownloadUrl(url, config) {
40
- const {
41
- name: repoName,
42
- owner: project,
43
- ref,
44
- protocol,
45
- resource,
46
- filepath
47
- } = parseGitUrl__default.default(url);
48
- const isHosted = resource === "bitbucket.org";
49
- let branch = ref;
50
- if (!branch) {
51
- branch = await getBitbucketDefaultBranch(url, config);
52
- }
53
- const path = filepath ? `&path=${encodeURIComponent(decodeURIComponent(filepath))}` : "";
54
- const archiveUrl = isHosted ? `${protocol}://${resource}/${project}/${repoName}/get/${branch}.tar.gz` : `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/archive?format=tgz&at=${branch}&prefix=${project}-${repoName}${path}`;
55
- return archiveUrl;
56
- }
57
- function getBitbucketFileFetchUrl(url, config) {
58
- try {
59
- const { owner, name, ref, filepathtype, filepath } = parseGitUrl__default.default(url);
60
- if (!owner || !name || filepathtype !== "browse" && filepathtype !== "raw" && filepathtype !== "src") {
61
- throw new Error("Invalid Bitbucket URL or file path");
62
- }
63
- const pathWithoutSlash = filepath.replace(/^\//, "");
64
- if (config.host === "bitbucket.org") {
65
- if (!ref) {
66
- throw new Error("Invalid Bitbucket URL or file path");
67
- }
68
- return `${config.apiBaseUrl}/repositories/${owner}/${name}/src/${ref}/${pathWithoutSlash}`;
69
- }
70
- return `${config.apiBaseUrl}/projects/${owner}/repos/${name}/raw/${pathWithoutSlash}?at=${ref}`;
71
- } catch (e) {
72
- throw new Error(`Incorrect URL: ${url}, ${e}`);
73
- }
74
- }
75
- function getBitbucketRequestOptions(config) {
76
- const headers = {};
77
- if (config.token) {
78
- headers.Authorization = `Bearer ${config.token}`;
79
- } else if (config.username && config.appPassword) {
80
- const buffer = Buffer.from(
81
- `${config.username}:${config.appPassword}`,
82
- "utf8"
83
- );
84
- headers.Authorization = `Basic ${buffer.toString("base64")}`;
85
- }
86
- return {
87
- headers
88
- };
89
- }
90
-
91
- exports.getBitbucketDefaultBranch = getBitbucketDefaultBranch;
92
- exports.getBitbucketDownloadUrl = getBitbucketDownloadUrl;
93
- exports.getBitbucketFileFetchUrl = getBitbucketFileFetchUrl;
94
- exports.getBitbucketRequestOptions = getBitbucketRequestOptions;
95
- //# sourceMappingURL=core.cjs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"core.cjs.js","sources":["../../src/bitbucket/core.ts"],"sourcesContent":["/*\n * Copyright 2020 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';\nimport parseGitUrl from 'git-url-parse';\nimport { BitbucketIntegrationConfig } from './config';\n\n/**\n * Given a URL pointing to a path on a provider, returns the default branch.\n *\n * @param url - A URL pointing to a path\n * @param config - The relevant provider config\n * @public\n * @deprecated no longer in use, bitbucket integration replaced by integrations bitbucketCloud and bitbucketServer.\n */\nexport async function getBitbucketDefaultBranch(\n url: string,\n config: BitbucketIntegrationConfig,\n): Promise<string> {\n const { name: repoName, owner: project, resource } = parseGitUrl(url);\n\n const isHosted = resource === 'bitbucket.org';\n // Bitbucket Server https://docs.atlassian.com/bitbucket-server/rest/7.9.0/bitbucket-rest.html#idp184\n let branchUrl = isHosted\n ? `${config.apiBaseUrl}/repositories/${project}/${repoName}`\n : `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/default-branch`;\n\n let response = await fetch(branchUrl, getBitbucketRequestOptions(config));\n\n if (response.status === 404 && !isHosted) {\n // First try the new format, and then if it gets specifically a 404 it should try the old format\n // (to support old Atlassian Bitbucket v5.11.1 format )\n branchUrl = `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/branches/default`;\n response = await fetch(branchUrl, getBitbucketRequestOptions(config));\n }\n\n if (!response.ok) {\n const message = `Failed to retrieve default branch from ${branchUrl}, ${response.status} ${response.statusText}`;\n throw new Error(message);\n }\n\n let defaultBranch;\n if (isHosted) {\n const repoInfo = await response.json();\n defaultBranch = repoInfo.mainbranch.name;\n } else {\n const { displayId } = await response.json();\n defaultBranch = displayId;\n }\n if (!defaultBranch) {\n throw new Error(\n `Failed to read default branch from ${branchUrl}. ` +\n `Response ${response.status} ${response.json()}`,\n );\n }\n return defaultBranch;\n}\n\n/**\n * Given a URL pointing to a path on a provider, returns a URL that is suitable\n * for downloading the subtree.\n *\n * @param url - A URL pointing to a path\n * @param config - The relevant provider config\n * @public\n * @deprecated no longer in use, bitbucket integration replaced by integrations bitbucketCloud and bitbucketServer.\n */\nexport async function getBitbucketDownloadUrl(\n url: string,\n config: BitbucketIntegrationConfig,\n): Promise<string> {\n const {\n name: repoName,\n owner: project,\n ref,\n protocol,\n resource,\n filepath,\n } = parseGitUrl(url);\n\n const isHosted = resource === 'bitbucket.org';\n\n let branch = ref;\n if (!branch) {\n branch = await getBitbucketDefaultBranch(url, config);\n }\n // path will limit the downloaded content\n // /docs will only download the docs folder and everything below it\n // /docs/index.md will download the docs folder and everything below it\n const path = filepath\n ? `&path=${encodeURIComponent(decodeURIComponent(filepath))}`\n : '';\n const archiveUrl = isHosted\n ? `${protocol}://${resource}/${project}/${repoName}/get/${branch}.tar.gz`\n : `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/archive?format=tgz&at=${branch}&prefix=${project}-${repoName}${path}`;\n\n return archiveUrl;\n}\n\n/**\n * Given a URL pointing to a file on a provider, returns a URL that is suitable\n * for fetching the contents of the data.\n *\n * @remarks\n *\n * Converts\n * from: https://bitbucket.org/orgname/reponame/src/master/file.yaml\n * to: https://api.bitbucket.org/2.0/repositories/orgname/reponame/src/master/file.yaml\n *\n * @param url - A URL pointing to a file\n * @param config - The relevant provider config\n * @public\n * @deprecated no longer in use, bitbucket integration replaced by integrations bitbucketCloud and bitbucketServer.\n */\nexport function getBitbucketFileFetchUrl(\n url: string,\n config: BitbucketIntegrationConfig,\n): string {\n try {\n const { owner, name, ref, filepathtype, filepath } = parseGitUrl(url);\n if (\n !owner ||\n !name ||\n (filepathtype !== 'browse' &&\n filepathtype !== 'raw' &&\n filepathtype !== 'src')\n ) {\n throw new Error('Invalid Bitbucket URL or file path');\n }\n\n const pathWithoutSlash = filepath.replace(/^\\//, '');\n\n if (config.host === 'bitbucket.org') {\n if (!ref) {\n throw new Error('Invalid Bitbucket URL or file path');\n }\n return `${config.apiBaseUrl}/repositories/${owner}/${name}/src/${ref}/${pathWithoutSlash}`;\n }\n return `${config.apiBaseUrl}/projects/${owner}/repos/${name}/raw/${pathWithoutSlash}?at=${ref}`;\n } catch (e) {\n throw new Error(`Incorrect URL: ${url}, ${e}`);\n }\n}\n\n/**\n * Gets the request options necessary to make requests to a given provider.\n *\n * @param config - The relevant provider config\n * @public\n * @deprecated no longer in use, bitbucket integration replaced by integrations bitbucketCloud and bitbucketServer.\n */\nexport function getBitbucketRequestOptions(\n config: BitbucketIntegrationConfig,\n): { headers: Record<string, string> } {\n const headers: Record<string, string> = {};\n\n if (config.token) {\n headers.Authorization = `Bearer ${config.token}`;\n } else if (config.username && config.appPassword) {\n const buffer = Buffer.from(\n `${config.username}:${config.appPassword}`,\n 'utf8',\n );\n headers.Authorization = `Basic ${buffer.toString('base64')}`;\n }\n\n return {\n headers,\n };\n}\n"],"names":["parseGitUrl","fetch"],"mappings":"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"}
@@ -1,85 +0,0 @@
1
- import fetch from 'cross-fetch';
2
- import parseGitUrl from 'git-url-parse';
3
-
4
- async function getBitbucketDefaultBranch(url, config) {
5
- const { name: repoName, owner: project, resource } = parseGitUrl(url);
6
- const isHosted = resource === "bitbucket.org";
7
- let branchUrl = isHosted ? `${config.apiBaseUrl}/repositories/${project}/${repoName}` : `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/default-branch`;
8
- let response = await fetch(branchUrl, getBitbucketRequestOptions(config));
9
- if (response.status === 404 && !isHosted) {
10
- branchUrl = `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/branches/default`;
11
- response = await fetch(branchUrl, getBitbucketRequestOptions(config));
12
- }
13
- if (!response.ok) {
14
- const message = `Failed to retrieve default branch from ${branchUrl}, ${response.status} ${response.statusText}`;
15
- throw new Error(message);
16
- }
17
- let defaultBranch;
18
- if (isHosted) {
19
- const repoInfo = await response.json();
20
- defaultBranch = repoInfo.mainbranch.name;
21
- } else {
22
- const { displayId } = await response.json();
23
- defaultBranch = displayId;
24
- }
25
- if (!defaultBranch) {
26
- throw new Error(
27
- `Failed to read default branch from ${branchUrl}. Response ${response.status} ${response.json()}`
28
- );
29
- }
30
- return defaultBranch;
31
- }
32
- async function getBitbucketDownloadUrl(url, config) {
33
- const {
34
- name: repoName,
35
- owner: project,
36
- ref,
37
- protocol,
38
- resource,
39
- filepath
40
- } = parseGitUrl(url);
41
- const isHosted = resource === "bitbucket.org";
42
- let branch = ref;
43
- if (!branch) {
44
- branch = await getBitbucketDefaultBranch(url, config);
45
- }
46
- const path = filepath ? `&path=${encodeURIComponent(decodeURIComponent(filepath))}` : "";
47
- const archiveUrl = isHosted ? `${protocol}://${resource}/${project}/${repoName}/get/${branch}.tar.gz` : `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/archive?format=tgz&at=${branch}&prefix=${project}-${repoName}${path}`;
48
- return archiveUrl;
49
- }
50
- function getBitbucketFileFetchUrl(url, config) {
51
- try {
52
- const { owner, name, ref, filepathtype, filepath } = parseGitUrl(url);
53
- if (!owner || !name || filepathtype !== "browse" && filepathtype !== "raw" && filepathtype !== "src") {
54
- throw new Error("Invalid Bitbucket URL or file path");
55
- }
56
- const pathWithoutSlash = filepath.replace(/^\//, "");
57
- if (config.host === "bitbucket.org") {
58
- if (!ref) {
59
- throw new Error("Invalid Bitbucket URL or file path");
60
- }
61
- return `${config.apiBaseUrl}/repositories/${owner}/${name}/src/${ref}/${pathWithoutSlash}`;
62
- }
63
- return `${config.apiBaseUrl}/projects/${owner}/repos/${name}/raw/${pathWithoutSlash}?at=${ref}`;
64
- } catch (e) {
65
- throw new Error(`Incorrect URL: ${url}, ${e}`);
66
- }
67
- }
68
- function getBitbucketRequestOptions(config) {
69
- const headers = {};
70
- if (config.token) {
71
- headers.Authorization = `Bearer ${config.token}`;
72
- } else if (config.username && config.appPassword) {
73
- const buffer = Buffer.from(
74
- `${config.username}:${config.appPassword}`,
75
- "utf8"
76
- );
77
- headers.Authorization = `Basic ${buffer.toString("base64")}`;
78
- }
79
- return {
80
- headers
81
- };
82
- }
83
-
84
- export { getBitbucketDefaultBranch, getBitbucketDownloadUrl, getBitbucketFileFetchUrl, getBitbucketRequestOptions };
85
- //# sourceMappingURL=core.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"core.esm.js","sources":["../../src/bitbucket/core.ts"],"sourcesContent":["/*\n * Copyright 2020 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';\nimport parseGitUrl from 'git-url-parse';\nimport { BitbucketIntegrationConfig } from './config';\n\n/**\n * Given a URL pointing to a path on a provider, returns the default branch.\n *\n * @param url - A URL pointing to a path\n * @param config - The relevant provider config\n * @public\n * @deprecated no longer in use, bitbucket integration replaced by integrations bitbucketCloud and bitbucketServer.\n */\nexport async function getBitbucketDefaultBranch(\n url: string,\n config: BitbucketIntegrationConfig,\n): Promise<string> {\n const { name: repoName, owner: project, resource } = parseGitUrl(url);\n\n const isHosted = resource === 'bitbucket.org';\n // Bitbucket Server https://docs.atlassian.com/bitbucket-server/rest/7.9.0/bitbucket-rest.html#idp184\n let branchUrl = isHosted\n ? `${config.apiBaseUrl}/repositories/${project}/${repoName}`\n : `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/default-branch`;\n\n let response = await fetch(branchUrl, getBitbucketRequestOptions(config));\n\n if (response.status === 404 && !isHosted) {\n // First try the new format, and then if it gets specifically a 404 it should try the old format\n // (to support old Atlassian Bitbucket v5.11.1 format )\n branchUrl = `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/branches/default`;\n response = await fetch(branchUrl, getBitbucketRequestOptions(config));\n }\n\n if (!response.ok) {\n const message = `Failed to retrieve default branch from ${branchUrl}, ${response.status} ${response.statusText}`;\n throw new Error(message);\n }\n\n let defaultBranch;\n if (isHosted) {\n const repoInfo = await response.json();\n defaultBranch = repoInfo.mainbranch.name;\n } else {\n const { displayId } = await response.json();\n defaultBranch = displayId;\n }\n if (!defaultBranch) {\n throw new Error(\n `Failed to read default branch from ${branchUrl}. ` +\n `Response ${response.status} ${response.json()}`,\n );\n }\n return defaultBranch;\n}\n\n/**\n * Given a URL pointing to a path on a provider, returns a URL that is suitable\n * for downloading the subtree.\n *\n * @param url - A URL pointing to a path\n * @param config - The relevant provider config\n * @public\n * @deprecated no longer in use, bitbucket integration replaced by integrations bitbucketCloud and bitbucketServer.\n */\nexport async function getBitbucketDownloadUrl(\n url: string,\n config: BitbucketIntegrationConfig,\n): Promise<string> {\n const {\n name: repoName,\n owner: project,\n ref,\n protocol,\n resource,\n filepath,\n } = parseGitUrl(url);\n\n const isHosted = resource === 'bitbucket.org';\n\n let branch = ref;\n if (!branch) {\n branch = await getBitbucketDefaultBranch(url, config);\n }\n // path will limit the downloaded content\n // /docs will only download the docs folder and everything below it\n // /docs/index.md will download the docs folder and everything below it\n const path = filepath\n ? `&path=${encodeURIComponent(decodeURIComponent(filepath))}`\n : '';\n const archiveUrl = isHosted\n ? `${protocol}://${resource}/${project}/${repoName}/get/${branch}.tar.gz`\n : `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/archive?format=tgz&at=${branch}&prefix=${project}-${repoName}${path}`;\n\n return archiveUrl;\n}\n\n/**\n * Given a URL pointing to a file on a provider, returns a URL that is suitable\n * for fetching the contents of the data.\n *\n * @remarks\n *\n * Converts\n * from: https://bitbucket.org/orgname/reponame/src/master/file.yaml\n * to: https://api.bitbucket.org/2.0/repositories/orgname/reponame/src/master/file.yaml\n *\n * @param url - A URL pointing to a file\n * @param config - The relevant provider config\n * @public\n * @deprecated no longer in use, bitbucket integration replaced by integrations bitbucketCloud and bitbucketServer.\n */\nexport function getBitbucketFileFetchUrl(\n url: string,\n config: BitbucketIntegrationConfig,\n): string {\n try {\n const { owner, name, ref, filepathtype, filepath } = parseGitUrl(url);\n if (\n !owner ||\n !name ||\n (filepathtype !== 'browse' &&\n filepathtype !== 'raw' &&\n filepathtype !== 'src')\n ) {\n throw new Error('Invalid Bitbucket URL or file path');\n }\n\n const pathWithoutSlash = filepath.replace(/^\\//, '');\n\n if (config.host === 'bitbucket.org') {\n if (!ref) {\n throw new Error('Invalid Bitbucket URL or file path');\n }\n return `${config.apiBaseUrl}/repositories/${owner}/${name}/src/${ref}/${pathWithoutSlash}`;\n }\n return `${config.apiBaseUrl}/projects/${owner}/repos/${name}/raw/${pathWithoutSlash}?at=${ref}`;\n } catch (e) {\n throw new Error(`Incorrect URL: ${url}, ${e}`);\n }\n}\n\n/**\n * Gets the request options necessary to make requests to a given provider.\n *\n * @param config - The relevant provider config\n * @public\n * @deprecated no longer in use, bitbucket integration replaced by integrations bitbucketCloud and bitbucketServer.\n */\nexport function getBitbucketRequestOptions(\n config: BitbucketIntegrationConfig,\n): { headers: Record<string, string> } {\n const headers: Record<string, string> = {};\n\n if (config.token) {\n headers.Authorization = `Bearer ${config.token}`;\n } else if (config.username && config.appPassword) {\n const buffer = Buffer.from(\n `${config.username}:${config.appPassword}`,\n 'utf8',\n );\n headers.Authorization = `Basic ${buffer.toString('base64')}`;\n }\n\n return {\n headers,\n };\n}\n"],"names":[],"mappings":"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"}