@backstage/integration 1.1.0 → 1.2.0-next.0
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 +40 -0
- package/config.d.ts +42 -1
- package/dist/index.cjs.js +358 -77
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +364 -78
- package/dist/index.esm.js +341 -78
- package/dist/index.esm.js.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# @backstage/integration
|
|
2
2
|
|
|
3
|
+
## 1.2.0-next.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 6673babab9: Gerrit UrlReader: Implemented `readTree`
|
|
8
|
+
- 1b4e1e2306: Split `bitbucket` integration into `bitbucketCloud` and `bitbucketServer`
|
|
9
|
+
(backwards compatible).
|
|
10
|
+
|
|
11
|
+
In order to migrate to the new integration configs,
|
|
12
|
+
move your configs from `integrations.bitbucket`
|
|
13
|
+
to `integrations.bitbucketCloud` or `integrations.bitbucketServer`.
|
|
14
|
+
|
|
15
|
+
Migration example:
|
|
16
|
+
|
|
17
|
+
**Before:**
|
|
18
|
+
|
|
19
|
+
```yaml
|
|
20
|
+
integrations:
|
|
21
|
+
bitbucket:
|
|
22
|
+
- host: bitbucket.org
|
|
23
|
+
username: bitbucket_user
|
|
24
|
+
appPassword: app-password
|
|
25
|
+
- host: bitbucket-server.company.com
|
|
26
|
+
token: my-token
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**After:**
|
|
30
|
+
|
|
31
|
+
```yaml
|
|
32
|
+
integrations:
|
|
33
|
+
bitbucketCloud:
|
|
34
|
+
- username: bitbucket_user
|
|
35
|
+
appPassword: app-password
|
|
36
|
+
bitbucketServer:
|
|
37
|
+
- host: bitbucket-server.company.com
|
|
38
|
+
token: my-token
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
- 566407bf8a: Gerrit Integration: Added the `getGerritProjectsApiUrl` function
|
|
42
|
+
|
|
3
43
|
## 1.1.0
|
|
4
44
|
|
|
5
45
|
### Minor Changes
|
package/config.d.ts
CHANGED
|
@@ -31,7 +31,10 @@ export interface Config {
|
|
|
31
31
|
token?: string;
|
|
32
32
|
}>;
|
|
33
33
|
|
|
34
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* Integration configuration for Bitbucket
|
|
36
|
+
* @deprecated replaced by bitbucketCloud and bitbucketServer
|
|
37
|
+
*/
|
|
35
38
|
bitbucket?: Array<{
|
|
36
39
|
/**
|
|
37
40
|
* The hostname of the given Bitbucket instance
|
|
@@ -60,6 +63,39 @@ export interface Config {
|
|
|
60
63
|
appPassword?: string;
|
|
61
64
|
}>;
|
|
62
65
|
|
|
66
|
+
/** Integration configuration for Bitbucket Cloud */
|
|
67
|
+
bitbucketCloud?: Array<{
|
|
68
|
+
/**
|
|
69
|
+
* The username to use for authenticated requests.
|
|
70
|
+
* @visibility secret
|
|
71
|
+
*/
|
|
72
|
+
username: string;
|
|
73
|
+
/**
|
|
74
|
+
* Bitbucket Cloud app password used to authenticate requests.
|
|
75
|
+
* @visibility secret
|
|
76
|
+
*/
|
|
77
|
+
appPassword: string;
|
|
78
|
+
}>;
|
|
79
|
+
|
|
80
|
+
/** Integration configuration for Bitbucket Server */
|
|
81
|
+
bitbucketServer?: Array<{
|
|
82
|
+
/**
|
|
83
|
+
* The hostname of the given Bitbucket Server instance
|
|
84
|
+
* @visibility frontend
|
|
85
|
+
*/
|
|
86
|
+
host: string;
|
|
87
|
+
/**
|
|
88
|
+
* Token used to authenticate requests.
|
|
89
|
+
* @visibility secret
|
|
90
|
+
*/
|
|
91
|
+
token?: string;
|
|
92
|
+
/**
|
|
93
|
+
* The base url for the Bitbucket Server API, for example https://<host>/rest/api/1.0
|
|
94
|
+
* @visibility frontend
|
|
95
|
+
*/
|
|
96
|
+
apiBaseUrl?: string;
|
|
97
|
+
}>;
|
|
98
|
+
|
|
63
99
|
/** Integration configuration for Gerrit */
|
|
64
100
|
gerrit?: Array<{
|
|
65
101
|
/**
|
|
@@ -72,6 +108,11 @@ export interface Config {
|
|
|
72
108
|
* @visibility frontend
|
|
73
109
|
*/
|
|
74
110
|
baseUrl?: string;
|
|
111
|
+
/**
|
|
112
|
+
* The base url for cloning repos.
|
|
113
|
+
* @visibility frontend
|
|
114
|
+
*/
|
|
115
|
+
cloneUrl?: string;
|
|
75
116
|
/**
|
|
76
117
|
* The username to use for authenticated requests.
|
|
77
118
|
* @visibility secret
|
package/dist/index.cjs.js
CHANGED
|
@@ -68,6 +68,79 @@ function defaultScmResolveUrl(options) {
|
|
|
68
68
|
return updated.toString();
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
const AMAZON_AWS_HOST = "amazonaws.com";
|
|
72
|
+
function readAwsS3IntegrationConfig(config) {
|
|
73
|
+
var _a;
|
|
74
|
+
const endpoint = config.getOptionalString("endpoint");
|
|
75
|
+
const s3ForcePathStyle = (_a = config.getOptionalBoolean("s3ForcePathStyle")) != null ? _a : false;
|
|
76
|
+
let host;
|
|
77
|
+
let pathname;
|
|
78
|
+
if (endpoint) {
|
|
79
|
+
try {
|
|
80
|
+
const url = new URL(endpoint);
|
|
81
|
+
host = url.host;
|
|
82
|
+
pathname = url.pathname;
|
|
83
|
+
} catch {
|
|
84
|
+
throw new Error(`invalid awsS3 integration config, endpoint '${endpoint}' is not a valid URL`);
|
|
85
|
+
}
|
|
86
|
+
if (pathname !== "/") {
|
|
87
|
+
throw new Error(`invalid awsS3 integration config, endpoints cannot contain path, got '${endpoint}'`);
|
|
88
|
+
}
|
|
89
|
+
} else {
|
|
90
|
+
host = AMAZON_AWS_HOST;
|
|
91
|
+
}
|
|
92
|
+
const accessKeyId = config.getOptionalString("accessKeyId");
|
|
93
|
+
const secretAccessKey = config.getOptionalString("secretAccessKey");
|
|
94
|
+
const roleArn = config.getOptionalString("roleArn");
|
|
95
|
+
const externalId = config.getOptionalString("externalId");
|
|
96
|
+
return {
|
|
97
|
+
host,
|
|
98
|
+
endpoint,
|
|
99
|
+
s3ForcePathStyle,
|
|
100
|
+
accessKeyId,
|
|
101
|
+
secretAccessKey,
|
|
102
|
+
roleArn,
|
|
103
|
+
externalId
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function readAwsS3IntegrationConfigs(configs) {
|
|
107
|
+
const result = configs.map(readAwsS3IntegrationConfig);
|
|
108
|
+
if (!result.some((c) => c.host === AMAZON_AWS_HOST)) {
|
|
109
|
+
result.push({
|
|
110
|
+
host: AMAZON_AWS_HOST
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const _AwsS3Integration = class {
|
|
117
|
+
constructor(integrationConfig) {
|
|
118
|
+
this.integrationConfig = integrationConfig;
|
|
119
|
+
}
|
|
120
|
+
get type() {
|
|
121
|
+
return "awsS3";
|
|
122
|
+
}
|
|
123
|
+
get title() {
|
|
124
|
+
return this.integrationConfig.host;
|
|
125
|
+
}
|
|
126
|
+
get config() {
|
|
127
|
+
return this.integrationConfig;
|
|
128
|
+
}
|
|
129
|
+
resolveUrl(options) {
|
|
130
|
+
const resolved = defaultScmResolveUrl(options);
|
|
131
|
+
return resolved;
|
|
132
|
+
}
|
|
133
|
+
resolveEditUrl(url) {
|
|
134
|
+
return url;
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
let AwsS3Integration = _AwsS3Integration;
|
|
138
|
+
AwsS3Integration.factory = ({ config }) => {
|
|
139
|
+
var _a;
|
|
140
|
+
const configs = readAwsS3IntegrationConfigs((_a = config.getOptionalConfigArray("integrations.awsS3")) != null ? _a : []);
|
|
141
|
+
return basicIntegrations(configs.map((c) => new _AwsS3Integration(c)), (i) => i.config.host);
|
|
142
|
+
};
|
|
143
|
+
|
|
71
144
|
var __accessCheck = (obj, member, msg) => {
|
|
72
145
|
if (!member.has(obj))
|
|
73
146
|
throw TypeError("Cannot " + msg);
|
|
@@ -371,8 +444,11 @@ let BitbucketIntegration = _BitbucketIntegration;
|
|
|
371
444
|
BitbucketIntegration.factory = ({
|
|
372
445
|
config
|
|
373
446
|
}) => {
|
|
374
|
-
var _a;
|
|
375
|
-
const configs = readBitbucketIntegrationConfigs((
|
|
447
|
+
var _a, _b, _c;
|
|
448
|
+
const configs = readBitbucketIntegrationConfigs((_c = config.getOptionalConfigArray("integrations.bitbucket")) != null ? _c : [
|
|
449
|
+
...(_a = config.getOptionalConfigArray("integrations.bitbucketCloud")) != null ? _a : [],
|
|
450
|
+
...(_b = config.getOptionalConfigArray("integrations.bitbucketServer")) != null ? _b : []
|
|
451
|
+
]);
|
|
376
452
|
return basicIntegrations(configs.map((c) => new _BitbucketIntegration(c)), (i) => i.config.host);
|
|
377
453
|
};
|
|
378
454
|
|
|
@@ -451,9 +527,242 @@ function getBitbucketRequestOptions(config) {
|
|
|
451
527
|
};
|
|
452
528
|
}
|
|
453
529
|
|
|
530
|
+
const BITBUCKET_CLOUD_HOST = "bitbucket.org";
|
|
531
|
+
const BITBUCKET_CLOUD_API_BASE_URL = "https://api.bitbucket.org/2.0";
|
|
532
|
+
function readBitbucketCloudIntegrationConfig(config) {
|
|
533
|
+
const host = BITBUCKET_CLOUD_HOST;
|
|
534
|
+
const apiBaseUrl = BITBUCKET_CLOUD_API_BASE_URL;
|
|
535
|
+
const username = config.getString("username");
|
|
536
|
+
const appPassword = config.getString("appPassword");
|
|
537
|
+
return {
|
|
538
|
+
host,
|
|
539
|
+
apiBaseUrl,
|
|
540
|
+
username,
|
|
541
|
+
appPassword
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
function readBitbucketCloudIntegrationConfigs(configs) {
|
|
545
|
+
const result = configs.map(readBitbucketCloudIntegrationConfig);
|
|
546
|
+
if (result.length === 0) {
|
|
547
|
+
result.push({
|
|
548
|
+
host: BITBUCKET_CLOUD_HOST,
|
|
549
|
+
apiBaseUrl: BITBUCKET_CLOUD_API_BASE_URL
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
return result;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
const _BitbucketCloudIntegration = class {
|
|
556
|
+
constructor(integrationConfig) {
|
|
557
|
+
this.integrationConfig = integrationConfig;
|
|
558
|
+
}
|
|
559
|
+
get type() {
|
|
560
|
+
return "bitbucketCloud";
|
|
561
|
+
}
|
|
562
|
+
get title() {
|
|
563
|
+
return this.integrationConfig.host;
|
|
564
|
+
}
|
|
565
|
+
get config() {
|
|
566
|
+
return this.integrationConfig;
|
|
567
|
+
}
|
|
568
|
+
resolveUrl(options) {
|
|
569
|
+
const resolved = defaultScmResolveUrl(options);
|
|
570
|
+
if (options.lineNumber) {
|
|
571
|
+
const url = new URL(resolved);
|
|
572
|
+
url.hash = `lines-${options.lineNumber}`;
|
|
573
|
+
return url.toString();
|
|
574
|
+
}
|
|
575
|
+
return resolved;
|
|
576
|
+
}
|
|
577
|
+
resolveEditUrl(url) {
|
|
578
|
+
const urlData = parseGitUrl__default["default"](url);
|
|
579
|
+
const editUrl = new URL(url);
|
|
580
|
+
editUrl.searchParams.set("mode", "edit");
|
|
581
|
+
editUrl.searchParams.set("at", urlData.ref);
|
|
582
|
+
return editUrl.toString();
|
|
583
|
+
}
|
|
584
|
+
};
|
|
585
|
+
let BitbucketCloudIntegration = _BitbucketCloudIntegration;
|
|
586
|
+
BitbucketCloudIntegration.factory = ({
|
|
587
|
+
config
|
|
588
|
+
}) => {
|
|
589
|
+
var _a;
|
|
590
|
+
const configs = readBitbucketCloudIntegrationConfigs((_a = config.getOptionalConfigArray("integrations.bitbucketCloud")) != null ? _a : []);
|
|
591
|
+
return basicIntegrations(configs.map((c) => new _BitbucketCloudIntegration(c)), (i) => i.config.host);
|
|
592
|
+
};
|
|
593
|
+
|
|
594
|
+
async function getBitbucketCloudDefaultBranch(url, config) {
|
|
595
|
+
const { name: repoName, owner: project } = parseGitUrl__default["default"](url);
|
|
596
|
+
const branchUrl = `${config.apiBaseUrl}/repositories/${project}/${repoName}`;
|
|
597
|
+
const response = await fetch__default["default"](branchUrl, getBitbucketCloudRequestOptions(config));
|
|
598
|
+
if (!response.ok) {
|
|
599
|
+
const message = `Failed to retrieve default branch from ${branchUrl}, ${response.status} ${response.statusText}`;
|
|
600
|
+
throw new Error(message);
|
|
601
|
+
}
|
|
602
|
+
const repoInfo = await response.json();
|
|
603
|
+
const defaultBranch = repoInfo.mainbranch.name;
|
|
604
|
+
if (!defaultBranch) {
|
|
605
|
+
throw new Error(`Failed to read default branch from ${branchUrl}. Response ${response.status} ${response.json()}`);
|
|
606
|
+
}
|
|
607
|
+
return defaultBranch;
|
|
608
|
+
}
|
|
609
|
+
async function getBitbucketCloudDownloadUrl(url, config) {
|
|
610
|
+
const {
|
|
611
|
+
name: repoName,
|
|
612
|
+
owner: project,
|
|
613
|
+
ref,
|
|
614
|
+
protocol,
|
|
615
|
+
resource
|
|
616
|
+
} = parseGitUrl__default["default"](url);
|
|
617
|
+
let branch = ref;
|
|
618
|
+
if (!branch) {
|
|
619
|
+
branch = await getBitbucketCloudDefaultBranch(url, config);
|
|
620
|
+
}
|
|
621
|
+
return `${protocol}://${resource}/${project}/${repoName}/get/${branch}.tar.gz`;
|
|
622
|
+
}
|
|
623
|
+
function getBitbucketCloudFileFetchUrl(url, config) {
|
|
624
|
+
try {
|
|
625
|
+
const { owner, name, ref, filepathtype, filepath } = parseGitUrl__default["default"](url);
|
|
626
|
+
if (!owner || !name || filepathtype !== "src" && filepathtype !== "raw") {
|
|
627
|
+
throw new Error("Invalid Bitbucket Cloud URL or file path");
|
|
628
|
+
}
|
|
629
|
+
const pathWithoutSlash = filepath.replace(/^\//, "");
|
|
630
|
+
if (!ref) {
|
|
631
|
+
throw new Error("Invalid Bitbucket Cloud URL or file path");
|
|
632
|
+
}
|
|
633
|
+
return `${config.apiBaseUrl}/repositories/${owner}/${name}/src/${ref}/${pathWithoutSlash}`;
|
|
634
|
+
} catch (e) {
|
|
635
|
+
throw new Error(`Incorrect URL: ${url}, ${e}`);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
function getBitbucketCloudRequestOptions(config) {
|
|
639
|
+
const headers = {};
|
|
640
|
+
if (config.username && config.appPassword) {
|
|
641
|
+
const buffer = Buffer.from(`${config.username}:${config.appPassword}`, "utf8");
|
|
642
|
+
headers.Authorization = `Basic ${buffer.toString("base64")}`;
|
|
643
|
+
}
|
|
644
|
+
return {
|
|
645
|
+
headers
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
function readBitbucketServerIntegrationConfig(config) {
|
|
650
|
+
const host = config.getString("host");
|
|
651
|
+
let apiBaseUrl = config.getOptionalString("apiBaseUrl");
|
|
652
|
+
const token = config.getOptionalString("token");
|
|
653
|
+
if (!isValidHost(host)) {
|
|
654
|
+
throw new Error(`Invalid Bitbucket Server integration config, '${host}' is not a valid host`);
|
|
655
|
+
}
|
|
656
|
+
if (apiBaseUrl) {
|
|
657
|
+
apiBaseUrl = lodash.trimEnd(apiBaseUrl, "/");
|
|
658
|
+
} else {
|
|
659
|
+
apiBaseUrl = `https://${host}/rest/api/1.0`;
|
|
660
|
+
}
|
|
661
|
+
return {
|
|
662
|
+
host,
|
|
663
|
+
apiBaseUrl,
|
|
664
|
+
token
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
function readBitbucketServerIntegrationConfigs(configs) {
|
|
668
|
+
return configs.map(readBitbucketServerIntegrationConfig);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
const _BitbucketServerIntegration = class {
|
|
672
|
+
constructor(integrationConfig) {
|
|
673
|
+
this.integrationConfig = integrationConfig;
|
|
674
|
+
}
|
|
675
|
+
get type() {
|
|
676
|
+
return "bitbucketServer";
|
|
677
|
+
}
|
|
678
|
+
get title() {
|
|
679
|
+
return this.integrationConfig.host;
|
|
680
|
+
}
|
|
681
|
+
get config() {
|
|
682
|
+
return this.integrationConfig;
|
|
683
|
+
}
|
|
684
|
+
resolveUrl(options) {
|
|
685
|
+
const resolved = defaultScmResolveUrl(options);
|
|
686
|
+
if (options.lineNumber) {
|
|
687
|
+
const url = new URL(resolved);
|
|
688
|
+
const filename = url.pathname.split("/").slice(-1)[0];
|
|
689
|
+
url.hash = `${filename}-${options.lineNumber}`;
|
|
690
|
+
return url.toString();
|
|
691
|
+
}
|
|
692
|
+
return resolved;
|
|
693
|
+
}
|
|
694
|
+
resolveEditUrl(url) {
|
|
695
|
+
const urlData = parseGitUrl__default["default"](url);
|
|
696
|
+
const editUrl = new URL(url);
|
|
697
|
+
editUrl.searchParams.set("mode", "edit");
|
|
698
|
+
editUrl.searchParams.set("spa", "0");
|
|
699
|
+
editUrl.searchParams.set("at", urlData.ref);
|
|
700
|
+
return editUrl.toString();
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
let BitbucketServerIntegration = _BitbucketServerIntegration;
|
|
704
|
+
BitbucketServerIntegration.factory = ({
|
|
705
|
+
config
|
|
706
|
+
}) => {
|
|
707
|
+
var _a;
|
|
708
|
+
const configs = readBitbucketServerIntegrationConfigs((_a = config.getOptionalConfigArray("integrations.bitbucketServer")) != null ? _a : []);
|
|
709
|
+
return basicIntegrations(configs.map((c) => new _BitbucketServerIntegration(c)), (i) => i.config.host);
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
async function getBitbucketServerDefaultBranch(url, config) {
|
|
713
|
+
const { name: repoName, owner: project } = parseGitUrl__default["default"](url);
|
|
714
|
+
let branchUrl = `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/default-branch`;
|
|
715
|
+
let response = await fetch__default["default"](branchUrl, getBitbucketServerRequestOptions(config));
|
|
716
|
+
if (response.status === 404) {
|
|
717
|
+
branchUrl = `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/branches/default`;
|
|
718
|
+
response = await fetch__default["default"](branchUrl, getBitbucketServerRequestOptions(config));
|
|
719
|
+
}
|
|
720
|
+
if (!response.ok) {
|
|
721
|
+
const message = `Failed to retrieve default branch from ${branchUrl}, ${response.status} ${response.statusText}`;
|
|
722
|
+
throw new Error(message);
|
|
723
|
+
}
|
|
724
|
+
const { displayId } = await response.json();
|
|
725
|
+
const defaultBranch = displayId;
|
|
726
|
+
if (!defaultBranch) {
|
|
727
|
+
throw new Error(`Failed to read default branch from ${branchUrl}. Response ${response.status} ${response.json()}`);
|
|
728
|
+
}
|
|
729
|
+
return defaultBranch;
|
|
730
|
+
}
|
|
731
|
+
async function getBitbucketServerDownloadUrl(url, config) {
|
|
732
|
+
const { name: repoName, owner: project, ref, filepath } = parseGitUrl__default["default"](url);
|
|
733
|
+
let branch = ref;
|
|
734
|
+
if (!branch) {
|
|
735
|
+
branch = await getBitbucketServerDefaultBranch(url, config);
|
|
736
|
+
}
|
|
737
|
+
const path = filepath ? `&path=${encodeURIComponent(filepath)}` : "";
|
|
738
|
+
return `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/archive?format=tgz&at=${branch}&prefix=${project}-${repoName}${path}`;
|
|
739
|
+
}
|
|
740
|
+
function getBitbucketServerFileFetchUrl(url, config) {
|
|
741
|
+
try {
|
|
742
|
+
const { owner, name, ref, filepathtype, filepath } = parseGitUrl__default["default"](url);
|
|
743
|
+
if (!owner || !name || filepathtype !== "browse" && filepathtype !== "raw" && filepathtype !== "src") {
|
|
744
|
+
throw new Error("Invalid Bitbucket Server URL or file path");
|
|
745
|
+
}
|
|
746
|
+
const pathWithoutSlash = filepath.replace(/^\//, "");
|
|
747
|
+
return `${config.apiBaseUrl}/projects/${owner}/repos/${name}/raw/${pathWithoutSlash}?at=${ref}`;
|
|
748
|
+
} catch (e) {
|
|
749
|
+
throw new Error(`Incorrect URL: ${url}, ${e}`);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
function getBitbucketServerRequestOptions(config) {
|
|
753
|
+
const headers = {};
|
|
754
|
+
if (config.token) {
|
|
755
|
+
headers.Authorization = `Bearer ${config.token}`;
|
|
756
|
+
}
|
|
757
|
+
return {
|
|
758
|
+
headers
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
|
|
454
762
|
function readGerritIntegrationConfig(config) {
|
|
455
763
|
const host = config.getString("host");
|
|
456
764
|
let baseUrl = config.getOptionalString("baseUrl");
|
|
765
|
+
let cloneUrl = config.getOptionalString("cloneUrl");
|
|
457
766
|
let gitilesBaseUrl = config.getOptionalString("gitilesBaseUrl");
|
|
458
767
|
const username = config.getOptionalString("username");
|
|
459
768
|
const password = config.getOptionalString("password");
|
|
@@ -461,6 +770,8 @@ function readGerritIntegrationConfig(config) {
|
|
|
461
770
|
throw new Error(`Invalid Gerrit integration config, '${host}' is not a valid host`);
|
|
462
771
|
} else if (baseUrl && !isValidUrl(baseUrl)) {
|
|
463
772
|
throw new Error(`Invalid Gerrit integration config, '${baseUrl}' is not a valid baseUrl`);
|
|
773
|
+
} else if (cloneUrl && !isValidUrl(cloneUrl)) {
|
|
774
|
+
throw new Error(`Invalid Gerrit integration config, '${cloneUrl}' is not a valid cloneUrl`);
|
|
464
775
|
} else if (gitilesBaseUrl && !isValidUrl(gitilesBaseUrl)) {
|
|
465
776
|
throw new Error(`Invalid Gerrit integration config, '${gitilesBaseUrl}' is not a valid gitilesBaseUrl`);
|
|
466
777
|
}
|
|
@@ -474,9 +785,15 @@ function readGerritIntegrationConfig(config) {
|
|
|
474
785
|
} else {
|
|
475
786
|
gitilesBaseUrl = `https://${host}`;
|
|
476
787
|
}
|
|
788
|
+
if (cloneUrl) {
|
|
789
|
+
cloneUrl = lodash.trimEnd(cloneUrl, "/");
|
|
790
|
+
} else {
|
|
791
|
+
cloneUrl = baseUrl;
|
|
792
|
+
}
|
|
477
793
|
return {
|
|
478
794
|
host,
|
|
479
795
|
baseUrl,
|
|
796
|
+
cloneUrl,
|
|
480
797
|
gitilesBaseUrl,
|
|
481
798
|
username,
|
|
482
799
|
password
|
|
@@ -524,7 +841,7 @@ GerritIntegration.factory = ({ config }) => {
|
|
|
524
841
|
};
|
|
525
842
|
|
|
526
843
|
const GERRIT_BODY_PREFIX = ")]}'";
|
|
527
|
-
function
|
|
844
|
+
function parseGerritGitilesUrl(config, url) {
|
|
528
845
|
const urlPath = url.replace(config.gitilesBaseUrl, "");
|
|
529
846
|
const parts = urlPath.split("/").filter((p) => !!p);
|
|
530
847
|
const projectEndIndex = parts.indexOf("+");
|
|
@@ -547,10 +864,21 @@ function parseGitilesUrl(config, url) {
|
|
|
547
864
|
function getAuthenticationPrefix(config) {
|
|
548
865
|
return config.password ? "/a/" : "/";
|
|
549
866
|
}
|
|
867
|
+
function getGerritBranchApiUrl(config, url) {
|
|
868
|
+
const { branch, project } = parseGerritGitilesUrl(config, url);
|
|
869
|
+
return `${config.baseUrl}${getAuthenticationPrefix(config)}projects/${encodeURIComponent(project)}/branches/${branch}`;
|
|
870
|
+
}
|
|
871
|
+
function getGerritCloneRepoUrl(config, url) {
|
|
872
|
+
const { project } = parseGerritGitilesUrl(config, url);
|
|
873
|
+
return `${config.cloneUrl}${getAuthenticationPrefix(config)}${project}`;
|
|
874
|
+
}
|
|
550
875
|
function getGerritFileContentsApiUrl(config, url) {
|
|
551
|
-
const { branch, filePath, project } =
|
|
876
|
+
const { branch, filePath, project } = parseGerritGitilesUrl(config, url);
|
|
552
877
|
return `${config.baseUrl}${getAuthenticationPrefix(config)}projects/${encodeURIComponent(project)}/branches/${branch}/files/${encodeURIComponent(filePath)}/content`;
|
|
553
878
|
}
|
|
879
|
+
function getGerritProjectsApiUrl(config) {
|
|
880
|
+
return `${config.baseUrl}${getAuthenticationPrefix(config)}projects/`;
|
|
881
|
+
}
|
|
554
882
|
function getGerritRequestOptions(config) {
|
|
555
883
|
const headers = {};
|
|
556
884
|
if (!config.password) {
|
|
@@ -995,85 +1323,14 @@ function readGoogleGcsIntegrationConfig(config) {
|
|
|
995
1323
|
return { clientEmail, privateKey };
|
|
996
1324
|
}
|
|
997
1325
|
|
|
998
|
-
const AMAZON_AWS_HOST = "amazonaws.com";
|
|
999
|
-
function readAwsS3IntegrationConfig(config) {
|
|
1000
|
-
var _a;
|
|
1001
|
-
const endpoint = config.getOptionalString("endpoint");
|
|
1002
|
-
const s3ForcePathStyle = (_a = config.getOptionalBoolean("s3ForcePathStyle")) != null ? _a : false;
|
|
1003
|
-
let host;
|
|
1004
|
-
let pathname;
|
|
1005
|
-
if (endpoint) {
|
|
1006
|
-
try {
|
|
1007
|
-
const url = new URL(endpoint);
|
|
1008
|
-
host = url.host;
|
|
1009
|
-
pathname = url.pathname;
|
|
1010
|
-
} catch {
|
|
1011
|
-
throw new Error(`invalid awsS3 integration config, endpoint '${endpoint}' is not a valid URL`);
|
|
1012
|
-
}
|
|
1013
|
-
if (pathname !== "/") {
|
|
1014
|
-
throw new Error(`invalid awsS3 integration config, endpoints cannot contain path, got '${endpoint}'`);
|
|
1015
|
-
}
|
|
1016
|
-
} else {
|
|
1017
|
-
host = AMAZON_AWS_HOST;
|
|
1018
|
-
}
|
|
1019
|
-
const accessKeyId = config.getOptionalString("accessKeyId");
|
|
1020
|
-
const secretAccessKey = config.getOptionalString("secretAccessKey");
|
|
1021
|
-
const roleArn = config.getOptionalString("roleArn");
|
|
1022
|
-
const externalId = config.getOptionalString("externalId");
|
|
1023
|
-
return {
|
|
1024
|
-
host,
|
|
1025
|
-
endpoint,
|
|
1026
|
-
s3ForcePathStyle,
|
|
1027
|
-
accessKeyId,
|
|
1028
|
-
secretAccessKey,
|
|
1029
|
-
roleArn,
|
|
1030
|
-
externalId
|
|
1031
|
-
};
|
|
1032
|
-
}
|
|
1033
|
-
function readAwsS3IntegrationConfigs(configs) {
|
|
1034
|
-
const result = configs.map(readAwsS3IntegrationConfig);
|
|
1035
|
-
if (!result.some((c) => c.host === AMAZON_AWS_HOST)) {
|
|
1036
|
-
result.push({
|
|
1037
|
-
host: AMAZON_AWS_HOST
|
|
1038
|
-
});
|
|
1039
|
-
}
|
|
1040
|
-
return result;
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
|
-
const _AwsS3Integration = class {
|
|
1044
|
-
constructor(integrationConfig) {
|
|
1045
|
-
this.integrationConfig = integrationConfig;
|
|
1046
|
-
}
|
|
1047
|
-
get type() {
|
|
1048
|
-
return "awsS3";
|
|
1049
|
-
}
|
|
1050
|
-
get title() {
|
|
1051
|
-
return this.integrationConfig.host;
|
|
1052
|
-
}
|
|
1053
|
-
get config() {
|
|
1054
|
-
return this.integrationConfig;
|
|
1055
|
-
}
|
|
1056
|
-
resolveUrl(options) {
|
|
1057
|
-
const resolved = defaultScmResolveUrl(options);
|
|
1058
|
-
return resolved;
|
|
1059
|
-
}
|
|
1060
|
-
resolveEditUrl(url) {
|
|
1061
|
-
return url;
|
|
1062
|
-
}
|
|
1063
|
-
};
|
|
1064
|
-
let AwsS3Integration = _AwsS3Integration;
|
|
1065
|
-
AwsS3Integration.factory = ({ config }) => {
|
|
1066
|
-
var _a;
|
|
1067
|
-
const configs = readAwsS3IntegrationConfigs((_a = config.getOptionalConfigArray("integrations.awsS3")) != null ? _a : []);
|
|
1068
|
-
return basicIntegrations(configs.map((c) => new _AwsS3Integration(c)), (i) => i.config.host);
|
|
1069
|
-
};
|
|
1070
|
-
|
|
1071
1326
|
class ScmIntegrations {
|
|
1072
1327
|
static fromConfig(config) {
|
|
1073
1328
|
return new ScmIntegrations({
|
|
1074
1329
|
awsS3: AwsS3Integration.factory({ config }),
|
|
1075
1330
|
azure: AzureIntegration.factory({ config }),
|
|
1076
1331
|
bitbucket: BitbucketIntegration.factory({ config }),
|
|
1332
|
+
bitbucketCloud: BitbucketCloudIntegration.factory({ config }),
|
|
1333
|
+
bitbucketServer: BitbucketServerIntegration.factory({ config }),
|
|
1077
1334
|
gerrit: GerritIntegration.factory({ config }),
|
|
1078
1335
|
github: GitHubIntegration.factory({ config }),
|
|
1079
1336
|
gitlab: GitLabIntegration.factory({ config })
|
|
@@ -1091,6 +1348,12 @@ class ScmIntegrations {
|
|
|
1091
1348
|
get bitbucket() {
|
|
1092
1349
|
return this.byType.bitbucket;
|
|
1093
1350
|
}
|
|
1351
|
+
get bitbucketCloud() {
|
|
1352
|
+
return this.byType.bitbucketCloud;
|
|
1353
|
+
}
|
|
1354
|
+
get bitbucketServer() {
|
|
1355
|
+
return this.byType.bitbucketServer;
|
|
1356
|
+
}
|
|
1094
1357
|
get gerrit() {
|
|
1095
1358
|
return this.byType.gerrit;
|
|
1096
1359
|
}
|
|
@@ -1127,7 +1390,9 @@ class ScmIntegrations {
|
|
|
1127
1390
|
|
|
1128
1391
|
exports.AwsS3Integration = AwsS3Integration;
|
|
1129
1392
|
exports.AzureIntegration = AzureIntegration;
|
|
1393
|
+
exports.BitbucketCloudIntegration = BitbucketCloudIntegration;
|
|
1130
1394
|
exports.BitbucketIntegration = BitbucketIntegration;
|
|
1395
|
+
exports.BitbucketServerIntegration = BitbucketServerIntegration;
|
|
1131
1396
|
exports.DefaultGithubCredentialsProvider = DefaultGithubCredentialsProvider;
|
|
1132
1397
|
exports.GerritIntegration = GerritIntegration;
|
|
1133
1398
|
exports.GitHubIntegration = GitHubIntegration;
|
|
@@ -1140,23 +1405,39 @@ exports.getAzureCommitsUrl = getAzureCommitsUrl;
|
|
|
1140
1405
|
exports.getAzureDownloadUrl = getAzureDownloadUrl;
|
|
1141
1406
|
exports.getAzureFileFetchUrl = getAzureFileFetchUrl;
|
|
1142
1407
|
exports.getAzureRequestOptions = getAzureRequestOptions;
|
|
1408
|
+
exports.getBitbucketCloudDefaultBranch = getBitbucketCloudDefaultBranch;
|
|
1409
|
+
exports.getBitbucketCloudDownloadUrl = getBitbucketCloudDownloadUrl;
|
|
1410
|
+
exports.getBitbucketCloudFileFetchUrl = getBitbucketCloudFileFetchUrl;
|
|
1411
|
+
exports.getBitbucketCloudRequestOptions = getBitbucketCloudRequestOptions;
|
|
1143
1412
|
exports.getBitbucketDefaultBranch = getBitbucketDefaultBranch;
|
|
1144
1413
|
exports.getBitbucketDownloadUrl = getBitbucketDownloadUrl;
|
|
1145
1414
|
exports.getBitbucketFileFetchUrl = getBitbucketFileFetchUrl;
|
|
1146
1415
|
exports.getBitbucketRequestOptions = getBitbucketRequestOptions;
|
|
1416
|
+
exports.getBitbucketServerDefaultBranch = getBitbucketServerDefaultBranch;
|
|
1417
|
+
exports.getBitbucketServerDownloadUrl = getBitbucketServerDownloadUrl;
|
|
1418
|
+
exports.getBitbucketServerFileFetchUrl = getBitbucketServerFileFetchUrl;
|
|
1419
|
+
exports.getBitbucketServerRequestOptions = getBitbucketServerRequestOptions;
|
|
1420
|
+
exports.getGerritBranchApiUrl = getGerritBranchApiUrl;
|
|
1421
|
+
exports.getGerritCloneRepoUrl = getGerritCloneRepoUrl;
|
|
1147
1422
|
exports.getGerritFileContentsApiUrl = getGerritFileContentsApiUrl;
|
|
1423
|
+
exports.getGerritProjectsApiUrl = getGerritProjectsApiUrl;
|
|
1148
1424
|
exports.getGerritRequestOptions = getGerritRequestOptions;
|
|
1149
1425
|
exports.getGitHubFileFetchUrl = getGitHubFileFetchUrl;
|
|
1150
1426
|
exports.getGitHubRequestOptions = getGitHubRequestOptions;
|
|
1151
1427
|
exports.getGitLabFileFetchUrl = getGitLabFileFetchUrl;
|
|
1152
1428
|
exports.getGitLabRequestOptions = getGitLabRequestOptions;
|
|
1429
|
+
exports.parseGerritGitilesUrl = parseGerritGitilesUrl;
|
|
1153
1430
|
exports.parseGerritJsonResponse = parseGerritJsonResponse;
|
|
1154
1431
|
exports.readAwsS3IntegrationConfig = readAwsS3IntegrationConfig;
|
|
1155
1432
|
exports.readAwsS3IntegrationConfigs = readAwsS3IntegrationConfigs;
|
|
1156
1433
|
exports.readAzureIntegrationConfig = readAzureIntegrationConfig;
|
|
1157
1434
|
exports.readAzureIntegrationConfigs = readAzureIntegrationConfigs;
|
|
1435
|
+
exports.readBitbucketCloudIntegrationConfig = readBitbucketCloudIntegrationConfig;
|
|
1436
|
+
exports.readBitbucketCloudIntegrationConfigs = readBitbucketCloudIntegrationConfigs;
|
|
1158
1437
|
exports.readBitbucketIntegrationConfig = readBitbucketIntegrationConfig;
|
|
1159
1438
|
exports.readBitbucketIntegrationConfigs = readBitbucketIntegrationConfigs;
|
|
1439
|
+
exports.readBitbucketServerIntegrationConfig = readBitbucketServerIntegrationConfig;
|
|
1440
|
+
exports.readBitbucketServerIntegrationConfigs = readBitbucketServerIntegrationConfigs;
|
|
1160
1441
|
exports.readGerritIntegrationConfig = readGerritIntegrationConfig;
|
|
1161
1442
|
exports.readGerritIntegrationConfigs = readGerritIntegrationConfigs;
|
|
1162
1443
|
exports.readGitHubIntegrationConfig = readGitHubIntegrationConfig;
|