@backstage/integration 1.2.2-next.2 → 1.3.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 +45 -0
- package/config.d.ts +10 -0
- package/dist/index.cjs.js +233 -72
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +25 -1
- package/dist/index.esm.js +233 -73
- package/dist/index.esm.js.map +1 -1
- package/package.json +11 -11
package/dist/index.esm.js
CHANGED
|
@@ -48,7 +48,10 @@ function defaultScmResolveUrl(options) {
|
|
|
48
48
|
if (url.startsWith("/")) {
|
|
49
49
|
const { filepath } = parseGitUrl(base);
|
|
50
50
|
updated = new URL(base);
|
|
51
|
-
const repoRootPath = trimEnd(
|
|
51
|
+
const repoRootPath = trimEnd(
|
|
52
|
+
updated.pathname.substring(0, updated.pathname.length - filepath.length),
|
|
53
|
+
"/"
|
|
54
|
+
);
|
|
52
55
|
updated.pathname = `${repoRootPath}${url}`;
|
|
53
56
|
} else {
|
|
54
57
|
updated = new URL(url, base);
|
|
@@ -73,10 +76,14 @@ function readAwsS3IntegrationConfig(config) {
|
|
|
73
76
|
host = url.host;
|
|
74
77
|
pathname = url.pathname;
|
|
75
78
|
} catch {
|
|
76
|
-
throw new Error(
|
|
79
|
+
throw new Error(
|
|
80
|
+
`invalid awsS3 integration config, endpoint '${endpoint}' is not a valid URL`
|
|
81
|
+
);
|
|
77
82
|
}
|
|
78
83
|
if (pathname !== "/") {
|
|
79
|
-
throw new Error(
|
|
84
|
+
throw new Error(
|
|
85
|
+
`invalid awsS3 integration config, endpoints cannot contain path, got '${endpoint}'`
|
|
86
|
+
);
|
|
80
87
|
}
|
|
81
88
|
} else {
|
|
82
89
|
host = AMAZON_AWS_HOST;
|
|
@@ -129,8 +136,13 @@ const _AwsS3Integration = class {
|
|
|
129
136
|
let AwsS3Integration = _AwsS3Integration;
|
|
130
137
|
AwsS3Integration.factory = ({ config }) => {
|
|
131
138
|
var _a;
|
|
132
|
-
const configs = readAwsS3IntegrationConfigs(
|
|
133
|
-
|
|
139
|
+
const configs = readAwsS3IntegrationConfigs(
|
|
140
|
+
(_a = config.getOptionalConfigArray("integrations.awsS3")) != null ? _a : []
|
|
141
|
+
);
|
|
142
|
+
return basicIntegrations(
|
|
143
|
+
configs.map((c) => new _AwsS3Integration(c)),
|
|
144
|
+
(i) => i.config.host
|
|
145
|
+
);
|
|
134
146
|
};
|
|
135
147
|
|
|
136
148
|
var __accessCheck = (obj, member, msg) => {
|
|
@@ -224,7 +236,9 @@ const _AzureUrl = class {
|
|
|
224
236
|
}
|
|
225
237
|
toFileUrl() {
|
|
226
238
|
if (!__privateGet(this, _path)) {
|
|
227
|
-
throw new Error(
|
|
239
|
+
throw new Error(
|
|
240
|
+
"Azure URL must point to a specific path to be able to download a file"
|
|
241
|
+
);
|
|
228
242
|
}
|
|
229
243
|
const url = __privateGet(this, _baseUrl).call(this, __privateGet(this, _owner), __privateGet(this, _project), "_apis", "git", "repositories", __privateGet(this, _repo), "items");
|
|
230
244
|
url.searchParams.set("api-version", "6.0");
|
|
@@ -286,7 +300,9 @@ function readAzureIntegrationConfig(config) {
|
|
|
286
300
|
const host = (_a = config.getOptionalString("host")) != null ? _a : AZURE_HOST;
|
|
287
301
|
const token = config.getOptionalString("token");
|
|
288
302
|
if (!isValidHost(host)) {
|
|
289
|
-
throw new Error(
|
|
303
|
+
throw new Error(
|
|
304
|
+
`Invalid Azure integration config, '${host}' is not a valid host`
|
|
305
|
+
);
|
|
290
306
|
}
|
|
291
307
|
return { host, token };
|
|
292
308
|
}
|
|
@@ -341,8 +357,13 @@ const _AzureIntegration = class {
|
|
|
341
357
|
let AzureIntegration = _AzureIntegration;
|
|
342
358
|
AzureIntegration.factory = ({ config }) => {
|
|
343
359
|
var _a;
|
|
344
|
-
const configs = readAzureIntegrationConfigs(
|
|
345
|
-
|
|
360
|
+
const configs = readAzureIntegrationConfigs(
|
|
361
|
+
(_a = config.getOptionalConfigArray("integrations.azure")) != null ? _a : []
|
|
362
|
+
);
|
|
363
|
+
return basicIntegrations(
|
|
364
|
+
configs.map((c) => new _AzureIntegration(c)),
|
|
365
|
+
(i) => i.config.host
|
|
366
|
+
);
|
|
346
367
|
};
|
|
347
368
|
|
|
348
369
|
function getAzureFileFetchUrl(url) {
|
|
@@ -373,7 +394,9 @@ function readBitbucketIntegrationConfig(config) {
|
|
|
373
394
|
const username = config.getOptionalString("username");
|
|
374
395
|
const appPassword = config.getOptionalString("appPassword");
|
|
375
396
|
if (!isValidHost(host)) {
|
|
376
|
-
throw new Error(
|
|
397
|
+
throw new Error(
|
|
398
|
+
`Invalid Bitbucket integration config, '${host}' is not a valid host`
|
|
399
|
+
);
|
|
377
400
|
}
|
|
378
401
|
if (apiBaseUrl) {
|
|
379
402
|
apiBaseUrl = trimEnd(apiBaseUrl, "/");
|
|
@@ -441,11 +464,16 @@ BitbucketIntegration.factory = ({
|
|
|
441
464
|
config
|
|
442
465
|
}) => {
|
|
443
466
|
var _a, _b, _c;
|
|
444
|
-
const configs = readBitbucketIntegrationConfigs(
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
467
|
+
const configs = readBitbucketIntegrationConfigs(
|
|
468
|
+
(_c = config.getOptionalConfigArray("integrations.bitbucket")) != null ? _c : [
|
|
469
|
+
...(_a = config.getOptionalConfigArray("integrations.bitbucketCloud")) != null ? _a : [],
|
|
470
|
+
...(_b = config.getOptionalConfigArray("integrations.bitbucketServer")) != null ? _b : []
|
|
471
|
+
]
|
|
472
|
+
);
|
|
473
|
+
return basicIntegrations(
|
|
474
|
+
configs.map((c) => new _BitbucketIntegration(c)),
|
|
475
|
+
(i) => i.config.host
|
|
476
|
+
);
|
|
449
477
|
};
|
|
450
478
|
|
|
451
479
|
async function getBitbucketDefaultBranch(url, config) {
|
|
@@ -470,7 +498,9 @@ async function getBitbucketDefaultBranch(url, config) {
|
|
|
470
498
|
defaultBranch = displayId;
|
|
471
499
|
}
|
|
472
500
|
if (!defaultBranch) {
|
|
473
|
-
throw new Error(
|
|
501
|
+
throw new Error(
|
|
502
|
+
`Failed to read default branch from ${branchUrl}. Response ${response.status} ${response.json()}`
|
|
503
|
+
);
|
|
474
504
|
}
|
|
475
505
|
return defaultBranch;
|
|
476
506
|
}
|
|
@@ -488,7 +518,7 @@ async function getBitbucketDownloadUrl(url, config) {
|
|
|
488
518
|
if (!branch) {
|
|
489
519
|
branch = await getBitbucketDefaultBranch(url, config);
|
|
490
520
|
}
|
|
491
|
-
const path = filepath ? `&path=${encodeURIComponent(filepath)}` : "";
|
|
521
|
+
const path = filepath ? `&path=${encodeURIComponent(decodeURIComponent(filepath))}` : "";
|
|
492
522
|
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}`;
|
|
493
523
|
return archiveUrl;
|
|
494
524
|
}
|
|
@@ -515,7 +545,10 @@ function getBitbucketRequestOptions(config) {
|
|
|
515
545
|
if (config.token) {
|
|
516
546
|
headers.Authorization = `Bearer ${config.token}`;
|
|
517
547
|
} else if (config.username && config.appPassword) {
|
|
518
|
-
const buffer = Buffer.from(
|
|
548
|
+
const buffer = Buffer.from(
|
|
549
|
+
`${config.username}:${config.appPassword}`,
|
|
550
|
+
"utf8"
|
|
551
|
+
);
|
|
519
552
|
headers.Authorization = `Basic ${buffer.toString("base64")}`;
|
|
520
553
|
}
|
|
521
554
|
return {
|
|
@@ -583,14 +616,22 @@ BitbucketCloudIntegration.factory = ({
|
|
|
583
616
|
config
|
|
584
617
|
}) => {
|
|
585
618
|
var _a;
|
|
586
|
-
const configs = readBitbucketCloudIntegrationConfigs(
|
|
587
|
-
|
|
619
|
+
const configs = readBitbucketCloudIntegrationConfigs(
|
|
620
|
+
(_a = config.getOptionalConfigArray("integrations.bitbucketCloud")) != null ? _a : []
|
|
621
|
+
);
|
|
622
|
+
return basicIntegrations(
|
|
623
|
+
configs.map((c) => new _BitbucketCloudIntegration(c)),
|
|
624
|
+
(i) => i.config.host
|
|
625
|
+
);
|
|
588
626
|
};
|
|
589
627
|
|
|
590
628
|
async function getBitbucketCloudDefaultBranch(url, config) {
|
|
591
629
|
const { name: repoName, owner: project } = parseGitUrl(url);
|
|
592
630
|
const branchUrl = `${config.apiBaseUrl}/repositories/${project}/${repoName}`;
|
|
593
|
-
const response = await fetch(
|
|
631
|
+
const response = await fetch(
|
|
632
|
+
branchUrl,
|
|
633
|
+
getBitbucketCloudRequestOptions(config)
|
|
634
|
+
);
|
|
594
635
|
if (!response.ok) {
|
|
595
636
|
const message = `Failed to retrieve default branch from ${branchUrl}, ${response.status} ${response.statusText}`;
|
|
596
637
|
throw new Error(message);
|
|
@@ -598,7 +639,9 @@ async function getBitbucketCloudDefaultBranch(url, config) {
|
|
|
598
639
|
const repoInfo = await response.json();
|
|
599
640
|
const defaultBranch = repoInfo.mainbranch.name;
|
|
600
641
|
if (!defaultBranch) {
|
|
601
|
-
throw new Error(
|
|
642
|
+
throw new Error(
|
|
643
|
+
`Failed to read default branch from ${branchUrl}. Response ${response.status} ${response.json()}`
|
|
644
|
+
);
|
|
602
645
|
}
|
|
603
646
|
return defaultBranch;
|
|
604
647
|
}
|
|
@@ -634,7 +677,10 @@ function getBitbucketCloudFileFetchUrl(url, config) {
|
|
|
634
677
|
function getBitbucketCloudRequestOptions(config) {
|
|
635
678
|
const headers = {};
|
|
636
679
|
if (config.username && config.appPassword) {
|
|
637
|
-
const buffer = Buffer.from(
|
|
680
|
+
const buffer = Buffer.from(
|
|
681
|
+
`${config.username}:${config.appPassword}`,
|
|
682
|
+
"utf8"
|
|
683
|
+
);
|
|
638
684
|
headers.Authorization = `Basic ${buffer.toString("base64")}`;
|
|
639
685
|
}
|
|
640
686
|
return {
|
|
@@ -646,8 +692,12 @@ function readBitbucketServerIntegrationConfig(config) {
|
|
|
646
692
|
const host = config.getString("host");
|
|
647
693
|
let apiBaseUrl = config.getOptionalString("apiBaseUrl");
|
|
648
694
|
const token = config.getOptionalString("token");
|
|
695
|
+
const username = config.getOptionalString("username");
|
|
696
|
+
const password = config.getOptionalString("password");
|
|
649
697
|
if (!isValidHost(host)) {
|
|
650
|
-
throw new Error(
|
|
698
|
+
throw new Error(
|
|
699
|
+
`Invalid Bitbucket Server integration config, '${host}' is not a valid host`
|
|
700
|
+
);
|
|
651
701
|
}
|
|
652
702
|
if (apiBaseUrl) {
|
|
653
703
|
apiBaseUrl = trimEnd(apiBaseUrl, "/");
|
|
@@ -657,7 +707,9 @@ function readBitbucketServerIntegrationConfig(config) {
|
|
|
657
707
|
return {
|
|
658
708
|
host,
|
|
659
709
|
apiBaseUrl,
|
|
660
|
-
token
|
|
710
|
+
token,
|
|
711
|
+
username,
|
|
712
|
+
password
|
|
661
713
|
};
|
|
662
714
|
}
|
|
663
715
|
function readBitbucketServerIntegrationConfigs(configs) {
|
|
@@ -701,14 +753,22 @@ BitbucketServerIntegration.factory = ({
|
|
|
701
753
|
config
|
|
702
754
|
}) => {
|
|
703
755
|
var _a;
|
|
704
|
-
const configs = readBitbucketServerIntegrationConfigs(
|
|
705
|
-
|
|
756
|
+
const configs = readBitbucketServerIntegrationConfigs(
|
|
757
|
+
(_a = config.getOptionalConfigArray("integrations.bitbucketServer")) != null ? _a : []
|
|
758
|
+
);
|
|
759
|
+
return basicIntegrations(
|
|
760
|
+
configs.map((c) => new _BitbucketServerIntegration(c)),
|
|
761
|
+
(i) => i.config.host
|
|
762
|
+
);
|
|
706
763
|
};
|
|
707
764
|
|
|
708
765
|
async function getBitbucketServerDefaultBranch(url, config) {
|
|
709
766
|
const { name: repoName, owner: project } = parseGitUrl(url);
|
|
710
767
|
let branchUrl = `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/default-branch`;
|
|
711
|
-
let response = await fetch(
|
|
768
|
+
let response = await fetch(
|
|
769
|
+
branchUrl,
|
|
770
|
+
getBitbucketServerRequestOptions(config)
|
|
771
|
+
);
|
|
712
772
|
if (response.status === 404) {
|
|
713
773
|
branchUrl = `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/branches/default`;
|
|
714
774
|
response = await fetch(branchUrl, getBitbucketServerRequestOptions(config));
|
|
@@ -720,7 +780,9 @@ async function getBitbucketServerDefaultBranch(url, config) {
|
|
|
720
780
|
const { displayId } = await response.json();
|
|
721
781
|
const defaultBranch = displayId;
|
|
722
782
|
if (!defaultBranch) {
|
|
723
|
-
throw new Error(
|
|
783
|
+
throw new Error(
|
|
784
|
+
`Failed to read default branch from ${branchUrl}. Response ${response.status} ${response.json()}`
|
|
785
|
+
);
|
|
724
786
|
}
|
|
725
787
|
return defaultBranch;
|
|
726
788
|
}
|
|
@@ -730,7 +792,7 @@ async function getBitbucketServerDownloadUrl(url, config) {
|
|
|
730
792
|
if (!branch) {
|
|
731
793
|
branch = await getBitbucketServerDefaultBranch(url, config);
|
|
732
794
|
}
|
|
733
|
-
const path = filepath ? `&path=${encodeURIComponent(filepath)}` : "";
|
|
795
|
+
const path = filepath ? `&path=${encodeURIComponent(decodeURIComponent(filepath))}` : "";
|
|
734
796
|
return `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/archive?format=tgz&at=${branch}&prefix=${project}-${repoName}${path}`;
|
|
735
797
|
}
|
|
736
798
|
function getBitbucketServerFileFetchUrl(url, config) {
|
|
@@ -750,6 +812,10 @@ function getBitbucketServerRequestOptions(config) {
|
|
|
750
812
|
if (config.token) {
|
|
751
813
|
headers.Authorization = `Bearer ${config.token}`;
|
|
752
814
|
}
|
|
815
|
+
if (config.username && config.password) {
|
|
816
|
+
const buffer = Buffer.from(`${config.username}:${config.password}`, "utf8");
|
|
817
|
+
headers.Authorization = `Basic ${buffer.toString("base64")}`;
|
|
818
|
+
}
|
|
753
819
|
return {
|
|
754
820
|
headers
|
|
755
821
|
};
|
|
@@ -763,13 +829,21 @@ function readGerritIntegrationConfig(config) {
|
|
|
763
829
|
const username = config.getOptionalString("username");
|
|
764
830
|
const password = config.getOptionalString("password");
|
|
765
831
|
if (!isValidHost(host)) {
|
|
766
|
-
throw new Error(
|
|
832
|
+
throw new Error(
|
|
833
|
+
`Invalid Gerrit integration config, '${host}' is not a valid host`
|
|
834
|
+
);
|
|
767
835
|
} else if (baseUrl && !isValidUrl(baseUrl)) {
|
|
768
|
-
throw new Error(
|
|
836
|
+
throw new Error(
|
|
837
|
+
`Invalid Gerrit integration config, '${baseUrl}' is not a valid baseUrl`
|
|
838
|
+
);
|
|
769
839
|
} else if (cloneUrl && !isValidUrl(cloneUrl)) {
|
|
770
|
-
throw new Error(
|
|
840
|
+
throw new Error(
|
|
841
|
+
`Invalid Gerrit integration config, '${cloneUrl}' is not a valid cloneUrl`
|
|
842
|
+
);
|
|
771
843
|
} else if (gitilesBaseUrl && !isValidUrl(gitilesBaseUrl)) {
|
|
772
|
-
throw new Error(
|
|
844
|
+
throw new Error(
|
|
845
|
+
`Invalid Gerrit integration config, '${gitilesBaseUrl}' is not a valid gitilesBaseUrl`
|
|
846
|
+
);
|
|
773
847
|
}
|
|
774
848
|
if (baseUrl) {
|
|
775
849
|
baseUrl = trimEnd(baseUrl, "/");
|
|
@@ -828,7 +902,9 @@ function getAuthenticationPrefix(config) {
|
|
|
828
902
|
}
|
|
829
903
|
function getGerritBranchApiUrl(config, url) {
|
|
830
904
|
const { branch, project } = parseGerritGitilesUrl(config, url);
|
|
831
|
-
return `${config.baseUrl}${getAuthenticationPrefix(
|
|
905
|
+
return `${config.baseUrl}${getAuthenticationPrefix(
|
|
906
|
+
config
|
|
907
|
+
)}projects/${encodeURIComponent(project)}/branches/${branch}`;
|
|
832
908
|
}
|
|
833
909
|
function getGerritCloneRepoUrl(config, url) {
|
|
834
910
|
const { project } = parseGerritGitilesUrl(config, url);
|
|
@@ -836,7 +912,11 @@ function getGerritCloneRepoUrl(config, url) {
|
|
|
836
912
|
}
|
|
837
913
|
function getGerritFileContentsApiUrl(config, url) {
|
|
838
914
|
const { branch, filePath, project } = parseGerritGitilesUrl(config, url);
|
|
839
|
-
return `${config.baseUrl}${getAuthenticationPrefix(
|
|
915
|
+
return `${config.baseUrl}${getAuthenticationPrefix(
|
|
916
|
+
config
|
|
917
|
+
)}projects/${encodeURIComponent(
|
|
918
|
+
project
|
|
919
|
+
)}/branches/${branch}/files/${encodeURIComponent(filePath)}/content`;
|
|
840
920
|
}
|
|
841
921
|
function getGerritProjectsApiUrl(config) {
|
|
842
922
|
return `${config.baseUrl}${getAuthenticationPrefix(config)}projects/`;
|
|
@@ -858,10 +938,14 @@ async function parseGerritJsonResponse(response) {
|
|
|
858
938
|
try {
|
|
859
939
|
return JSON.parse(responseBody.slice(GERRIT_BODY_PREFIX.length));
|
|
860
940
|
} catch (ex) {
|
|
861
|
-
throw new Error(
|
|
941
|
+
throw new Error(
|
|
942
|
+
`Invalid response from Gerrit: ${responseBody.slice(0, 10)} - ${ex}`
|
|
943
|
+
);
|
|
862
944
|
}
|
|
863
945
|
}
|
|
864
|
-
throw new Error(
|
|
946
|
+
throw new Error(
|
|
947
|
+
`Gerrit JSON body prefix missing. Found: ${responseBody.slice(0, 10)}`
|
|
948
|
+
);
|
|
865
949
|
}
|
|
866
950
|
|
|
867
951
|
const _GerritIntegration = class {
|
|
@@ -901,8 +985,13 @@ const _GerritIntegration = class {
|
|
|
901
985
|
let GerritIntegration = _GerritIntegration;
|
|
902
986
|
GerritIntegration.factory = ({ config }) => {
|
|
903
987
|
var _a;
|
|
904
|
-
const configs = readGerritIntegrationConfigs(
|
|
905
|
-
|
|
988
|
+
const configs = readGerritIntegrationConfigs(
|
|
989
|
+
(_a = config.getOptionalConfigArray("integrations.gerrit")) != null ? _a : []
|
|
990
|
+
);
|
|
991
|
+
return basicIntegrations(
|
|
992
|
+
configs.map((c) => new _GerritIntegration(c)),
|
|
993
|
+
(i) => i.config.host
|
|
994
|
+
);
|
|
906
995
|
};
|
|
907
996
|
|
|
908
997
|
const GITHUB_HOST = "github.com";
|
|
@@ -920,10 +1009,14 @@ function readGitHubIntegrationConfig(config) {
|
|
|
920
1009
|
clientSecret: c.getString("clientSecret"),
|
|
921
1010
|
webhookSecret: c.getString("webhookSecret"),
|
|
922
1011
|
privateKey: c.getString("privateKey"),
|
|
923
|
-
allowedInstallationOwners: c.getOptionalStringArray(
|
|
1012
|
+
allowedInstallationOwners: c.getOptionalStringArray(
|
|
1013
|
+
"allowedInstallationOwners"
|
|
1014
|
+
)
|
|
924
1015
|
}));
|
|
925
1016
|
if (!isValidHost(host)) {
|
|
926
|
-
throw new Error(
|
|
1017
|
+
throw new Error(
|
|
1018
|
+
`Invalid GitHub integration config, '${host}' is not a valid host`
|
|
1019
|
+
);
|
|
927
1020
|
}
|
|
928
1021
|
if (apiBaseUrl) {
|
|
929
1022
|
apiBaseUrl = trimEnd(apiBaseUrl, "/");
|
|
@@ -1028,6 +1121,7 @@ class GithubAppManager {
|
|
|
1028
1121
|
}
|
|
1029
1122
|
const cacheKey = repo ? `${owner}/${repo}` : owner;
|
|
1030
1123
|
return this.cache.getOrCreateToken(cacheKey, async () => {
|
|
1124
|
+
var _a2;
|
|
1031
1125
|
const result = await this.appClient.apps.createInstallationAccessToken({
|
|
1032
1126
|
installation_id: installationId,
|
|
1033
1127
|
headers: HEADERS
|
|
@@ -1037,12 +1131,17 @@ class GithubAppManager {
|
|
|
1037
1131
|
baseUrl: this.baseUrl,
|
|
1038
1132
|
auth: result.data.token
|
|
1039
1133
|
});
|
|
1040
|
-
const repos = await installationClient.paginate(
|
|
1041
|
-
|
|
1134
|
+
const repos = await installationClient.paginate(
|
|
1135
|
+
installationClient.apps.listReposAccessibleToInstallation
|
|
1136
|
+
);
|
|
1137
|
+
const repositories = (_a2 = repos.repositories) != null ? _a2 : repos;
|
|
1138
|
+
const hasRepo = repositories.some((repository) => {
|
|
1042
1139
|
return repository.name === repo;
|
|
1043
1140
|
});
|
|
1044
1141
|
if (!hasRepo) {
|
|
1045
|
-
throw new Error(
|
|
1142
|
+
throw new Error(
|
|
1143
|
+
`The Backstage GitHub application used in the ${owner} organization does not have access to a repository with the name ${repo}`
|
|
1144
|
+
);
|
|
1046
1145
|
}
|
|
1047
1146
|
}
|
|
1048
1147
|
return {
|
|
@@ -1056,17 +1155,21 @@ class GithubAppManager {
|
|
|
1056
1155
|
}
|
|
1057
1156
|
async getInstallationData(owner) {
|
|
1058
1157
|
const allInstallations = await this.getInstallations();
|
|
1059
|
-
const installation = allInstallations.find(
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1158
|
+
const installation = allInstallations.find(
|
|
1159
|
+
(inst) => {
|
|
1160
|
+
var _a, _b;
|
|
1161
|
+
return ((_b = (_a = inst.account) == null ? void 0 : _a.login) == null ? void 0 : _b.toLocaleLowerCase("en-US")) === owner.toLocaleLowerCase("en-US");
|
|
1162
|
+
}
|
|
1163
|
+
);
|
|
1063
1164
|
if (installation) {
|
|
1064
1165
|
return {
|
|
1065
1166
|
installationId: installation.id,
|
|
1066
1167
|
suspended: Boolean(installation.suspended_by)
|
|
1067
1168
|
};
|
|
1068
1169
|
}
|
|
1069
|
-
const notFoundError = new Error(
|
|
1170
|
+
const notFoundError = new Error(
|
|
1171
|
+
`No app installation found for ${owner} in ${this.baseAuthConfig.appId}`
|
|
1172
|
+
);
|
|
1070
1173
|
notFoundError.name = "NotFoundError";
|
|
1071
1174
|
throw notFoundError;
|
|
1072
1175
|
}
|
|
@@ -1080,14 +1183,23 @@ class GithubAppCredentialsMux {
|
|
|
1080
1183
|
if (!this.apps.length) {
|
|
1081
1184
|
return [];
|
|
1082
1185
|
}
|
|
1083
|
-
const installs = await Promise.all(
|
|
1186
|
+
const installs = await Promise.all(
|
|
1187
|
+
this.apps.map((app) => app.getInstallations())
|
|
1188
|
+
);
|
|
1084
1189
|
return installs.flat();
|
|
1085
1190
|
}
|
|
1086
1191
|
async getAppToken(owner, repo) {
|
|
1087
1192
|
if (this.apps.length === 0) {
|
|
1088
1193
|
return void 0;
|
|
1089
1194
|
}
|
|
1090
|
-
const results = await Promise.all(
|
|
1195
|
+
const results = await Promise.all(
|
|
1196
|
+
this.apps.map(
|
|
1197
|
+
(app) => app.getInstallationCredentials(owner, repo).then(
|
|
1198
|
+
(credentials) => ({ credentials, error: void 0 }),
|
|
1199
|
+
(error) => ({ credentials: void 0, error })
|
|
1200
|
+
)
|
|
1201
|
+
)
|
|
1202
|
+
);
|
|
1091
1203
|
const result = results.find((resultItem) => resultItem.credentials);
|
|
1092
1204
|
if (result) {
|
|
1093
1205
|
return result.credentials.accessToken;
|
|
@@ -1124,7 +1236,10 @@ const _SingleInstanceGithubCredentialsProvider = class {
|
|
|
1124
1236
|
};
|
|
1125
1237
|
let SingleInstanceGithubCredentialsProvider = _SingleInstanceGithubCredentialsProvider;
|
|
1126
1238
|
SingleInstanceGithubCredentialsProvider.create = (config) => {
|
|
1127
|
-
return new _SingleInstanceGithubCredentialsProvider(
|
|
1239
|
+
return new _SingleInstanceGithubCredentialsProvider(
|
|
1240
|
+
new GithubAppCredentialsMux(config),
|
|
1241
|
+
config.token
|
|
1242
|
+
);
|
|
1128
1243
|
};
|
|
1129
1244
|
|
|
1130
1245
|
class DefaultGithubCredentialsProvider {
|
|
@@ -1143,7 +1258,9 @@ class DefaultGithubCredentialsProvider {
|
|
|
1143
1258
|
const parsed = new URL(opts.url);
|
|
1144
1259
|
const provider = this.providers.get(parsed.host);
|
|
1145
1260
|
if (!provider) {
|
|
1146
|
-
throw new Error(
|
|
1261
|
+
throw new Error(
|
|
1262
|
+
`There is no GitHub integration that matches ${opts.url}. Please add a configuration for an integration.`
|
|
1263
|
+
);
|
|
1147
1264
|
}
|
|
1148
1265
|
return provider.getCredentials(opts);
|
|
1149
1266
|
}
|
|
@@ -1172,13 +1289,21 @@ const _GitHubIntegration = class {
|
|
|
1172
1289
|
let GitHubIntegration = _GitHubIntegration;
|
|
1173
1290
|
GitHubIntegration.factory = ({ config }) => {
|
|
1174
1291
|
var _a;
|
|
1175
|
-
const configs = readGitHubIntegrationConfigs(
|
|
1176
|
-
|
|
1292
|
+
const configs = readGitHubIntegrationConfigs(
|
|
1293
|
+
(_a = config.getOptionalConfigArray("integrations.github")) != null ? _a : []
|
|
1294
|
+
);
|
|
1295
|
+
return basicIntegrations(
|
|
1296
|
+
configs.map((c) => new _GitHubIntegration(c)),
|
|
1297
|
+
(i) => i.config.host
|
|
1298
|
+
);
|
|
1177
1299
|
};
|
|
1178
1300
|
function replaceGitHubUrlType(url, type) {
|
|
1179
|
-
return url.replace(
|
|
1180
|
-
|
|
1181
|
-
|
|
1301
|
+
return url.replace(
|
|
1302
|
+
/\/\/([^/]+)\/([^/]+)\/([^/]+)\/(blob|tree|edit)\//,
|
|
1303
|
+
(_, host, owner, repo) => {
|
|
1304
|
+
return `//${host}/${owner}/${repo}/${type}/`;
|
|
1305
|
+
}
|
|
1306
|
+
);
|
|
1182
1307
|
}
|
|
1183
1308
|
|
|
1184
1309
|
const GITLAB_HOST = "gitlab.com";
|
|
@@ -1199,11 +1324,17 @@ function readGitLabIntegrationConfig(config) {
|
|
|
1199
1324
|
baseUrl = `https://${host}`;
|
|
1200
1325
|
}
|
|
1201
1326
|
if (!isValidHost(host)) {
|
|
1202
|
-
throw new Error(
|
|
1327
|
+
throw new Error(
|
|
1328
|
+
`Invalid GitLab integration config, '${host}' is not a valid host`
|
|
1329
|
+
);
|
|
1203
1330
|
} else if (!apiBaseUrl || !isValidUrl(apiBaseUrl)) {
|
|
1204
|
-
throw new Error(
|
|
1331
|
+
throw new Error(
|
|
1332
|
+
`Invalid GitLab integration config, '${apiBaseUrl}' is not a valid apiBaseUrl`
|
|
1333
|
+
);
|
|
1205
1334
|
} else if (!isValidUrl(baseUrl)) {
|
|
1206
|
-
throw new Error(
|
|
1335
|
+
throw new Error(
|
|
1336
|
+
`Invalid GitLab integration config, '${baseUrl}' is not a valid baseUrl`
|
|
1337
|
+
);
|
|
1207
1338
|
}
|
|
1208
1339
|
return { host, token, apiBaseUrl, baseUrl };
|
|
1209
1340
|
}
|
|
@@ -1218,11 +1349,18 @@ function readGitLabIntegrationConfigs(configs) {
|
|
|
1218
1349
|
}
|
|
1219
1350
|
return result;
|
|
1220
1351
|
}
|
|
1352
|
+
function getGitLabIntegrationRelativePath(config) {
|
|
1353
|
+
let relativePath = "";
|
|
1354
|
+
if (config.host !== GITLAB_HOST) {
|
|
1355
|
+
relativePath = new URL(config.baseUrl).pathname;
|
|
1356
|
+
}
|
|
1357
|
+
return trimEnd(relativePath, "/");
|
|
1358
|
+
}
|
|
1221
1359
|
|
|
1222
1360
|
async function getGitLabFileFetchUrl(url, config) {
|
|
1223
1361
|
if (url.includes("/-/blob/")) {
|
|
1224
1362
|
const projectID = await getProjectId(url, config);
|
|
1225
|
-
return buildProjectUrl(url, projectID).toString();
|
|
1363
|
+
return buildProjectUrl(url, projectID, config).toString();
|
|
1226
1364
|
}
|
|
1227
1365
|
return buildRawUrl(url).toString();
|
|
1228
1366
|
}
|
|
@@ -1253,13 +1391,15 @@ function buildRawUrl(target) {
|
|
|
1253
1391
|
throw new InputError(`Incorrect url: ${target}, ${e}`);
|
|
1254
1392
|
}
|
|
1255
1393
|
}
|
|
1256
|
-
function buildProjectUrl(target, projectID) {
|
|
1394
|
+
function buildProjectUrl(target, projectID, config) {
|
|
1257
1395
|
try {
|
|
1258
1396
|
const url = new URL(target);
|
|
1259
1397
|
const branchAndFilePath = url.pathname.split("/-/blob/")[1];
|
|
1260
1398
|
const [branch, ...filePath] = branchAndFilePath.split("/");
|
|
1399
|
+
const relativePath = getGitLabIntegrationRelativePath(config);
|
|
1261
1400
|
url.pathname = [
|
|
1262
|
-
|
|
1401
|
+
...relativePath ? [relativePath] : [],
|
|
1402
|
+
"api/v4/projects",
|
|
1263
1403
|
projectID,
|
|
1264
1404
|
"repository/files",
|
|
1265
1405
|
encodeURIComponent(decodeURIComponent(filePath.join("/"))),
|
|
@@ -1277,12 +1417,25 @@ async function getProjectId(target, config) {
|
|
|
1277
1417
|
throw new Error("Please provide full path to yaml file from GitLab");
|
|
1278
1418
|
}
|
|
1279
1419
|
try {
|
|
1280
|
-
|
|
1281
|
-
const
|
|
1282
|
-
|
|
1420
|
+
let repo = url.pathname.split("/-/blob/")[0];
|
|
1421
|
+
const relativePath = getGitLabIntegrationRelativePath(config);
|
|
1422
|
+
if (relativePath) {
|
|
1423
|
+
repo = repo.replace(relativePath, "");
|
|
1424
|
+
}
|
|
1425
|
+
const repoIDLookup = new URL(
|
|
1426
|
+
`${url.origin}${relativePath}/api/v4/projects/${encodeURIComponent(
|
|
1427
|
+
repo.replace(/^\//, "")
|
|
1428
|
+
)}`
|
|
1429
|
+
);
|
|
1430
|
+
const response = await fetch(
|
|
1431
|
+
repoIDLookup.toString(),
|
|
1432
|
+
getGitLabRequestOptions(config)
|
|
1433
|
+
);
|
|
1283
1434
|
const data = await response.json();
|
|
1284
1435
|
if (!response.ok) {
|
|
1285
|
-
throw new Error(
|
|
1436
|
+
throw new Error(
|
|
1437
|
+
`GitLab Error '${data.error}', ${data.error_description}`
|
|
1438
|
+
);
|
|
1286
1439
|
}
|
|
1287
1440
|
return Number(data.id);
|
|
1288
1441
|
} catch (e) {
|
|
@@ -1313,8 +1466,13 @@ const _GitLabIntegration = class {
|
|
|
1313
1466
|
let GitLabIntegration = _GitLabIntegration;
|
|
1314
1467
|
GitLabIntegration.factory = ({ config }) => {
|
|
1315
1468
|
var _a;
|
|
1316
|
-
const configs = readGitLabIntegrationConfigs(
|
|
1317
|
-
|
|
1469
|
+
const configs = readGitLabIntegrationConfigs(
|
|
1470
|
+
(_a = config.getOptionalConfigArray("integrations.gitlab")) != null ? _a : []
|
|
1471
|
+
);
|
|
1472
|
+
return basicIntegrations(
|
|
1473
|
+
configs.map((c) => new _GitLabIntegration(c)),
|
|
1474
|
+
(i) => i.config.host
|
|
1475
|
+
);
|
|
1318
1476
|
};
|
|
1319
1477
|
function replaceGitLabUrlType(url, type) {
|
|
1320
1478
|
return url.replace(/\/\-\/(blob|tree|edit)\//, `/-/${type}/`);
|
|
@@ -1373,7 +1531,9 @@ class ScmIntegrations {
|
|
|
1373
1531
|
return this.byType.gitlab;
|
|
1374
1532
|
}
|
|
1375
1533
|
list() {
|
|
1376
|
-
return Object.values(this.byType).flatMap(
|
|
1534
|
+
return Object.values(this.byType).flatMap(
|
|
1535
|
+
(i) => i.list()
|
|
1536
|
+
);
|
|
1377
1537
|
}
|
|
1378
1538
|
byUrl(url) {
|
|
1379
1539
|
return Object.values(this.byType).map((i) => i.byUrl(url)).find(Boolean);
|
|
@@ -1397,5 +1557,5 @@ class ScmIntegrations {
|
|
|
1397
1557
|
}
|
|
1398
1558
|
}
|
|
1399
1559
|
|
|
1400
|
-
export { AwsS3Integration, AzureIntegration, BitbucketCloudIntegration, BitbucketIntegration, BitbucketServerIntegration, DefaultGithubCredentialsProvider, GerritIntegration, GitHubIntegration, GitLabIntegration, GithubAppCredentialsMux, ScmIntegrations, SingleInstanceGithubCredentialsProvider, defaultScmResolveUrl, getAzureCommitsUrl, getAzureDownloadUrl, getAzureFileFetchUrl, getAzureRequestOptions, getBitbucketCloudDefaultBranch, getBitbucketCloudDownloadUrl, getBitbucketCloudFileFetchUrl, getBitbucketCloudRequestOptions, getBitbucketDefaultBranch, getBitbucketDownloadUrl, getBitbucketFileFetchUrl, getBitbucketRequestOptions, getBitbucketServerDefaultBranch, getBitbucketServerDownloadUrl, getBitbucketServerFileFetchUrl, getBitbucketServerRequestOptions, getGerritBranchApiUrl, getGerritCloneRepoUrl, getGerritFileContentsApiUrl, getGerritProjectsApiUrl, getGerritRequestOptions, getGitHubFileFetchUrl, getGitHubRequestOptions, getGitLabFileFetchUrl, getGitLabRequestOptions, parseGerritGitilesUrl, parseGerritJsonResponse, readAwsS3IntegrationConfig, readAwsS3IntegrationConfigs, readAzureIntegrationConfig, readAzureIntegrationConfigs, readBitbucketCloudIntegrationConfig, readBitbucketCloudIntegrationConfigs, readBitbucketIntegrationConfig, readBitbucketIntegrationConfigs, readBitbucketServerIntegrationConfig, readBitbucketServerIntegrationConfigs, readGerritIntegrationConfig, readGerritIntegrationConfigs, readGitHubIntegrationConfig, readGitHubIntegrationConfigs, readGitLabIntegrationConfig, readGitLabIntegrationConfigs, readGoogleGcsIntegrationConfig, replaceGitHubUrlType, replaceGitLabUrlType };
|
|
1560
|
+
export { AwsS3Integration, AzureIntegration, BitbucketCloudIntegration, BitbucketIntegration, BitbucketServerIntegration, DefaultGithubCredentialsProvider, GerritIntegration, GitHubIntegration, GitLabIntegration, GithubAppCredentialsMux, ScmIntegrations, SingleInstanceGithubCredentialsProvider, defaultScmResolveUrl, getAzureCommitsUrl, getAzureDownloadUrl, getAzureFileFetchUrl, getAzureRequestOptions, getBitbucketCloudDefaultBranch, getBitbucketCloudDownloadUrl, getBitbucketCloudFileFetchUrl, getBitbucketCloudRequestOptions, getBitbucketDefaultBranch, getBitbucketDownloadUrl, getBitbucketFileFetchUrl, getBitbucketRequestOptions, getBitbucketServerDefaultBranch, getBitbucketServerDownloadUrl, getBitbucketServerFileFetchUrl, getBitbucketServerRequestOptions, getGerritBranchApiUrl, getGerritCloneRepoUrl, getGerritFileContentsApiUrl, getGerritProjectsApiUrl, getGerritRequestOptions, getGitHubFileFetchUrl, getGitHubRequestOptions, getGitLabFileFetchUrl, getGitLabIntegrationRelativePath, getGitLabRequestOptions, parseGerritGitilesUrl, parseGerritJsonResponse, readAwsS3IntegrationConfig, readAwsS3IntegrationConfigs, readAzureIntegrationConfig, readAzureIntegrationConfigs, readBitbucketCloudIntegrationConfig, readBitbucketCloudIntegrationConfigs, readBitbucketIntegrationConfig, readBitbucketIntegrationConfigs, readBitbucketServerIntegrationConfig, readBitbucketServerIntegrationConfigs, readGerritIntegrationConfig, readGerritIntegrationConfigs, readGitHubIntegrationConfig, readGitHubIntegrationConfigs, readGitLabIntegrationConfig, readGitLabIntegrationConfigs, readGoogleGcsIntegrationConfig, replaceGitHubUrlType, replaceGitLabUrlType };
|
|
1401
1561
|
//# sourceMappingURL=index.esm.js.map
|