@backstage/integration 1.2.2-next.3 → 1.3.0-next.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/dist/index.esm.js CHANGED
@@ -4,7 +4,6 @@ import fetch from 'cross-fetch';
4
4
  import { createAppAuth } from '@octokit/auth-app';
5
5
  import { Octokit } from '@octokit/rest';
6
6
  import { DateTime } from 'luxon';
7
- import { InputError } from '@backstage/errors';
8
7
 
9
8
  function isValidHost(host) {
10
9
  const check = new URL("http://example.com");
@@ -48,7 +47,10 @@ function defaultScmResolveUrl(options) {
48
47
  if (url.startsWith("/")) {
49
48
  const { filepath } = parseGitUrl(base);
50
49
  updated = new URL(base);
51
- const repoRootPath = trimEnd(updated.pathname.substring(0, updated.pathname.length - filepath.length), "/");
50
+ const repoRootPath = trimEnd(
51
+ updated.pathname.substring(0, updated.pathname.length - filepath.length),
52
+ "/"
53
+ );
52
54
  updated.pathname = `${repoRootPath}${url}`;
53
55
  } else {
54
56
  updated = new URL(url, base);
@@ -73,10 +75,14 @@ function readAwsS3IntegrationConfig(config) {
73
75
  host = url.host;
74
76
  pathname = url.pathname;
75
77
  } catch {
76
- throw new Error(`invalid awsS3 integration config, endpoint '${endpoint}' is not a valid URL`);
78
+ throw new Error(
79
+ `invalid awsS3 integration config, endpoint '${endpoint}' is not a valid URL`
80
+ );
77
81
  }
78
82
  if (pathname !== "/") {
79
- throw new Error(`invalid awsS3 integration config, endpoints cannot contain path, got '${endpoint}'`);
83
+ throw new Error(
84
+ `invalid awsS3 integration config, endpoints cannot contain path, got '${endpoint}'`
85
+ );
80
86
  }
81
87
  } else {
82
88
  host = AMAZON_AWS_HOST;
@@ -129,8 +135,13 @@ const _AwsS3Integration = class {
129
135
  let AwsS3Integration = _AwsS3Integration;
130
136
  AwsS3Integration.factory = ({ config }) => {
131
137
  var _a;
132
- const configs = readAwsS3IntegrationConfigs((_a = config.getOptionalConfigArray("integrations.awsS3")) != null ? _a : []);
133
- return basicIntegrations(configs.map((c) => new _AwsS3Integration(c)), (i) => i.config.host);
138
+ const configs = readAwsS3IntegrationConfigs(
139
+ (_a = config.getOptionalConfigArray("integrations.awsS3")) != null ? _a : []
140
+ );
141
+ return basicIntegrations(
142
+ configs.map((c) => new _AwsS3Integration(c)),
143
+ (i) => i.config.host
144
+ );
134
145
  };
135
146
 
136
147
  var __accessCheck = (obj, member, msg) => {
@@ -224,7 +235,9 @@ const _AzureUrl = class {
224
235
  }
225
236
  toFileUrl() {
226
237
  if (!__privateGet(this, _path)) {
227
- throw new Error("Azure URL must point to a specific path to be able to download a file");
238
+ throw new Error(
239
+ "Azure URL must point to a specific path to be able to download a file"
240
+ );
228
241
  }
229
242
  const url = __privateGet(this, _baseUrl).call(this, __privateGet(this, _owner), __privateGet(this, _project), "_apis", "git", "repositories", __privateGet(this, _repo), "items");
230
243
  url.searchParams.set("api-version", "6.0");
@@ -286,7 +299,9 @@ function readAzureIntegrationConfig(config) {
286
299
  const host = (_a = config.getOptionalString("host")) != null ? _a : AZURE_HOST;
287
300
  const token = config.getOptionalString("token");
288
301
  if (!isValidHost(host)) {
289
- throw new Error(`Invalid Azure integration config, '${host}' is not a valid host`);
302
+ throw new Error(
303
+ `Invalid Azure integration config, '${host}' is not a valid host`
304
+ );
290
305
  }
291
306
  return { host, token };
292
307
  }
@@ -341,8 +356,13 @@ const _AzureIntegration = class {
341
356
  let AzureIntegration = _AzureIntegration;
342
357
  AzureIntegration.factory = ({ config }) => {
343
358
  var _a;
344
- const configs = readAzureIntegrationConfigs((_a = config.getOptionalConfigArray("integrations.azure")) != null ? _a : []);
345
- return basicIntegrations(configs.map((c) => new _AzureIntegration(c)), (i) => i.config.host);
359
+ const configs = readAzureIntegrationConfigs(
360
+ (_a = config.getOptionalConfigArray("integrations.azure")) != null ? _a : []
361
+ );
362
+ return basicIntegrations(
363
+ configs.map((c) => new _AzureIntegration(c)),
364
+ (i) => i.config.host
365
+ );
346
366
  };
347
367
 
348
368
  function getAzureFileFetchUrl(url) {
@@ -373,7 +393,9 @@ function readBitbucketIntegrationConfig(config) {
373
393
  const username = config.getOptionalString("username");
374
394
  const appPassword = config.getOptionalString("appPassword");
375
395
  if (!isValidHost(host)) {
376
- throw new Error(`Invalid Bitbucket integration config, '${host}' is not a valid host`);
396
+ throw new Error(
397
+ `Invalid Bitbucket integration config, '${host}' is not a valid host`
398
+ );
377
399
  }
378
400
  if (apiBaseUrl) {
379
401
  apiBaseUrl = trimEnd(apiBaseUrl, "/");
@@ -441,11 +463,16 @@ BitbucketIntegration.factory = ({
441
463
  config
442
464
  }) => {
443
465
  var _a, _b, _c;
444
- const configs = readBitbucketIntegrationConfigs((_c = config.getOptionalConfigArray("integrations.bitbucket")) != null ? _c : [
445
- ...(_a = config.getOptionalConfigArray("integrations.bitbucketCloud")) != null ? _a : [],
446
- ...(_b = config.getOptionalConfigArray("integrations.bitbucketServer")) != null ? _b : []
447
- ]);
448
- return basicIntegrations(configs.map((c) => new _BitbucketIntegration(c)), (i) => i.config.host);
466
+ const configs = readBitbucketIntegrationConfigs(
467
+ (_c = config.getOptionalConfigArray("integrations.bitbucket")) != null ? _c : [
468
+ ...(_a = config.getOptionalConfigArray("integrations.bitbucketCloud")) != null ? _a : [],
469
+ ...(_b = config.getOptionalConfigArray("integrations.bitbucketServer")) != null ? _b : []
470
+ ]
471
+ );
472
+ return basicIntegrations(
473
+ configs.map((c) => new _BitbucketIntegration(c)),
474
+ (i) => i.config.host
475
+ );
449
476
  };
450
477
 
451
478
  async function getBitbucketDefaultBranch(url, config) {
@@ -470,7 +497,9 @@ async function getBitbucketDefaultBranch(url, config) {
470
497
  defaultBranch = displayId;
471
498
  }
472
499
  if (!defaultBranch) {
473
- throw new Error(`Failed to read default branch from ${branchUrl}. Response ${response.status} ${response.json()}`);
500
+ throw new Error(
501
+ `Failed to read default branch from ${branchUrl}. Response ${response.status} ${response.json()}`
502
+ );
474
503
  }
475
504
  return defaultBranch;
476
505
  }
@@ -488,7 +517,7 @@ async function getBitbucketDownloadUrl(url, config) {
488
517
  if (!branch) {
489
518
  branch = await getBitbucketDefaultBranch(url, config);
490
519
  }
491
- const path = filepath ? `&path=${encodeURIComponent(filepath)}` : "";
520
+ const path = filepath ? `&path=${encodeURIComponent(decodeURIComponent(filepath))}` : "";
492
521
  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
522
  return archiveUrl;
494
523
  }
@@ -515,7 +544,10 @@ function getBitbucketRequestOptions(config) {
515
544
  if (config.token) {
516
545
  headers.Authorization = `Bearer ${config.token}`;
517
546
  } else if (config.username && config.appPassword) {
518
- const buffer = Buffer.from(`${config.username}:${config.appPassword}`, "utf8");
547
+ const buffer = Buffer.from(
548
+ `${config.username}:${config.appPassword}`,
549
+ "utf8"
550
+ );
519
551
  headers.Authorization = `Basic ${buffer.toString("base64")}`;
520
552
  }
521
553
  return {
@@ -583,14 +615,22 @@ BitbucketCloudIntegration.factory = ({
583
615
  config
584
616
  }) => {
585
617
  var _a;
586
- const configs = readBitbucketCloudIntegrationConfigs((_a = config.getOptionalConfigArray("integrations.bitbucketCloud")) != null ? _a : []);
587
- return basicIntegrations(configs.map((c) => new _BitbucketCloudIntegration(c)), (i) => i.config.host);
618
+ const configs = readBitbucketCloudIntegrationConfigs(
619
+ (_a = config.getOptionalConfigArray("integrations.bitbucketCloud")) != null ? _a : []
620
+ );
621
+ return basicIntegrations(
622
+ configs.map((c) => new _BitbucketCloudIntegration(c)),
623
+ (i) => i.config.host
624
+ );
588
625
  };
589
626
 
590
627
  async function getBitbucketCloudDefaultBranch(url, config) {
591
628
  const { name: repoName, owner: project } = parseGitUrl(url);
592
629
  const branchUrl = `${config.apiBaseUrl}/repositories/${project}/${repoName}`;
593
- const response = await fetch(branchUrl, getBitbucketCloudRequestOptions(config));
630
+ const response = await fetch(
631
+ branchUrl,
632
+ getBitbucketCloudRequestOptions(config)
633
+ );
594
634
  if (!response.ok) {
595
635
  const message = `Failed to retrieve default branch from ${branchUrl}, ${response.status} ${response.statusText}`;
596
636
  throw new Error(message);
@@ -598,7 +638,9 @@ async function getBitbucketCloudDefaultBranch(url, config) {
598
638
  const repoInfo = await response.json();
599
639
  const defaultBranch = repoInfo.mainbranch.name;
600
640
  if (!defaultBranch) {
601
- throw new Error(`Failed to read default branch from ${branchUrl}. Response ${response.status} ${response.json()}`);
641
+ throw new Error(
642
+ `Failed to read default branch from ${branchUrl}. Response ${response.status} ${response.json()}`
643
+ );
602
644
  }
603
645
  return defaultBranch;
604
646
  }
@@ -634,7 +676,10 @@ function getBitbucketCloudFileFetchUrl(url, config) {
634
676
  function getBitbucketCloudRequestOptions(config) {
635
677
  const headers = {};
636
678
  if (config.username && config.appPassword) {
637
- const buffer = Buffer.from(`${config.username}:${config.appPassword}`, "utf8");
679
+ const buffer = Buffer.from(
680
+ `${config.username}:${config.appPassword}`,
681
+ "utf8"
682
+ );
638
683
  headers.Authorization = `Basic ${buffer.toString("base64")}`;
639
684
  }
640
685
  return {
@@ -646,8 +691,12 @@ function readBitbucketServerIntegrationConfig(config) {
646
691
  const host = config.getString("host");
647
692
  let apiBaseUrl = config.getOptionalString("apiBaseUrl");
648
693
  const token = config.getOptionalString("token");
694
+ const username = config.getOptionalString("username");
695
+ const password = config.getOptionalString("password");
649
696
  if (!isValidHost(host)) {
650
- throw new Error(`Invalid Bitbucket Server integration config, '${host}' is not a valid host`);
697
+ throw new Error(
698
+ `Invalid Bitbucket Server integration config, '${host}' is not a valid host`
699
+ );
651
700
  }
652
701
  if (apiBaseUrl) {
653
702
  apiBaseUrl = trimEnd(apiBaseUrl, "/");
@@ -657,7 +706,9 @@ function readBitbucketServerIntegrationConfig(config) {
657
706
  return {
658
707
  host,
659
708
  apiBaseUrl,
660
- token
709
+ token,
710
+ username,
711
+ password
661
712
  };
662
713
  }
663
714
  function readBitbucketServerIntegrationConfigs(configs) {
@@ -681,19 +732,16 @@ const _BitbucketServerIntegration = class {
681
732
  const resolved = defaultScmResolveUrl(options);
682
733
  if (options.lineNumber) {
683
734
  const url = new URL(resolved);
684
- const filename = url.pathname.split("/").slice(-1)[0];
685
- url.hash = `${filename}-${options.lineNumber}`;
735
+ url.hash = options.lineNumber.toString();
686
736
  return url.toString();
687
737
  }
688
738
  return resolved;
689
739
  }
690
740
  resolveEditUrl(url) {
691
- const urlData = parseGitUrl(url);
692
- const editUrl = new URL(url);
693
- editUrl.searchParams.set("mode", "edit");
694
- editUrl.searchParams.set("spa", "0");
695
- editUrl.searchParams.set("at", urlData.ref);
696
- return editUrl.toString();
741
+ if (url.includes("?")) {
742
+ return url.substring(0, url.indexOf("?"));
743
+ }
744
+ return url;
697
745
  }
698
746
  };
699
747
  let BitbucketServerIntegration = _BitbucketServerIntegration;
@@ -701,14 +749,22 @@ BitbucketServerIntegration.factory = ({
701
749
  config
702
750
  }) => {
703
751
  var _a;
704
- const configs = readBitbucketServerIntegrationConfigs((_a = config.getOptionalConfigArray("integrations.bitbucketServer")) != null ? _a : []);
705
- return basicIntegrations(configs.map((c) => new _BitbucketServerIntegration(c)), (i) => i.config.host);
752
+ const configs = readBitbucketServerIntegrationConfigs(
753
+ (_a = config.getOptionalConfigArray("integrations.bitbucketServer")) != null ? _a : []
754
+ );
755
+ return basicIntegrations(
756
+ configs.map((c) => new _BitbucketServerIntegration(c)),
757
+ (i) => i.config.host
758
+ );
706
759
  };
707
760
 
708
761
  async function getBitbucketServerDefaultBranch(url, config) {
709
762
  const { name: repoName, owner: project } = parseGitUrl(url);
710
763
  let branchUrl = `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/default-branch`;
711
- let response = await fetch(branchUrl, getBitbucketServerRequestOptions(config));
764
+ let response = await fetch(
765
+ branchUrl,
766
+ getBitbucketServerRequestOptions(config)
767
+ );
712
768
  if (response.status === 404) {
713
769
  branchUrl = `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/branches/default`;
714
770
  response = await fetch(branchUrl, getBitbucketServerRequestOptions(config));
@@ -720,7 +776,9 @@ async function getBitbucketServerDefaultBranch(url, config) {
720
776
  const { displayId } = await response.json();
721
777
  const defaultBranch = displayId;
722
778
  if (!defaultBranch) {
723
- throw new Error(`Failed to read default branch from ${branchUrl}. Response ${response.status} ${response.json()}`);
779
+ throw new Error(
780
+ `Failed to read default branch from ${branchUrl}. Response ${response.status} ${response.json()}`
781
+ );
724
782
  }
725
783
  return defaultBranch;
726
784
  }
@@ -750,6 +808,10 @@ function getBitbucketServerRequestOptions(config) {
750
808
  if (config.token) {
751
809
  headers.Authorization = `Bearer ${config.token}`;
752
810
  }
811
+ if (config.username && config.password) {
812
+ const buffer = Buffer.from(`${config.username}:${config.password}`, "utf8");
813
+ headers.Authorization = `Basic ${buffer.toString("base64")}`;
814
+ }
753
815
  return {
754
816
  headers
755
817
  };
@@ -763,13 +825,21 @@ function readGerritIntegrationConfig(config) {
763
825
  const username = config.getOptionalString("username");
764
826
  const password = config.getOptionalString("password");
765
827
  if (!isValidHost(host)) {
766
- throw new Error(`Invalid Gerrit integration config, '${host}' is not a valid host`);
828
+ throw new Error(
829
+ `Invalid Gerrit integration config, '${host}' is not a valid host`
830
+ );
767
831
  } else if (baseUrl && !isValidUrl(baseUrl)) {
768
- throw new Error(`Invalid Gerrit integration config, '${baseUrl}' is not a valid baseUrl`);
832
+ throw new Error(
833
+ `Invalid Gerrit integration config, '${baseUrl}' is not a valid baseUrl`
834
+ );
769
835
  } else if (cloneUrl && !isValidUrl(cloneUrl)) {
770
- throw new Error(`Invalid Gerrit integration config, '${cloneUrl}' is not a valid cloneUrl`);
836
+ throw new Error(
837
+ `Invalid Gerrit integration config, '${cloneUrl}' is not a valid cloneUrl`
838
+ );
771
839
  } else if (gitilesBaseUrl && !isValidUrl(gitilesBaseUrl)) {
772
- throw new Error(`Invalid Gerrit integration config, '${gitilesBaseUrl}' is not a valid gitilesBaseUrl`);
840
+ throw new Error(
841
+ `Invalid Gerrit integration config, '${gitilesBaseUrl}' is not a valid gitilesBaseUrl`
842
+ );
773
843
  }
774
844
  if (baseUrl) {
775
845
  baseUrl = trimEnd(baseUrl, "/");
@@ -828,7 +898,9 @@ function getAuthenticationPrefix(config) {
828
898
  }
829
899
  function getGerritBranchApiUrl(config, url) {
830
900
  const { branch, project } = parseGerritGitilesUrl(config, url);
831
- return `${config.baseUrl}${getAuthenticationPrefix(config)}projects/${encodeURIComponent(project)}/branches/${branch}`;
901
+ return `${config.baseUrl}${getAuthenticationPrefix(
902
+ config
903
+ )}projects/${encodeURIComponent(project)}/branches/${branch}`;
832
904
  }
833
905
  function getGerritCloneRepoUrl(config, url) {
834
906
  const { project } = parseGerritGitilesUrl(config, url);
@@ -836,7 +908,11 @@ function getGerritCloneRepoUrl(config, url) {
836
908
  }
837
909
  function getGerritFileContentsApiUrl(config, url) {
838
910
  const { branch, filePath, project } = parseGerritGitilesUrl(config, url);
839
- return `${config.baseUrl}${getAuthenticationPrefix(config)}projects/${encodeURIComponent(project)}/branches/${branch}/files/${encodeURIComponent(filePath)}/content`;
911
+ return `${config.baseUrl}${getAuthenticationPrefix(
912
+ config
913
+ )}projects/${encodeURIComponent(
914
+ project
915
+ )}/branches/${branch}/files/${encodeURIComponent(filePath)}/content`;
840
916
  }
841
917
  function getGerritProjectsApiUrl(config) {
842
918
  return `${config.baseUrl}${getAuthenticationPrefix(config)}projects/`;
@@ -858,10 +934,14 @@ async function parseGerritJsonResponse(response) {
858
934
  try {
859
935
  return JSON.parse(responseBody.slice(GERRIT_BODY_PREFIX.length));
860
936
  } catch (ex) {
861
- throw new Error(`Invalid response from Gerrit: ${responseBody.slice(0, 10)} - ${ex}`);
937
+ throw new Error(
938
+ `Invalid response from Gerrit: ${responseBody.slice(0, 10)} - ${ex}`
939
+ );
862
940
  }
863
941
  }
864
- throw new Error(`Gerrit JSON body prefix missing. Found: ${responseBody.slice(0, 10)}`);
942
+ throw new Error(
943
+ `Gerrit JSON body prefix missing. Found: ${responseBody.slice(0, 10)}`
944
+ );
865
945
  }
866
946
 
867
947
  const _GerritIntegration = class {
@@ -901,8 +981,13 @@ const _GerritIntegration = class {
901
981
  let GerritIntegration = _GerritIntegration;
902
982
  GerritIntegration.factory = ({ config }) => {
903
983
  var _a;
904
- const configs = readGerritIntegrationConfigs((_a = config.getOptionalConfigArray("integrations.gerrit")) != null ? _a : []);
905
- return basicIntegrations(configs.map((c) => new _GerritIntegration(c)), (i) => i.config.host);
984
+ const configs = readGerritIntegrationConfigs(
985
+ (_a = config.getOptionalConfigArray("integrations.gerrit")) != null ? _a : []
986
+ );
987
+ return basicIntegrations(
988
+ configs.map((c) => new _GerritIntegration(c)),
989
+ (i) => i.config.host
990
+ );
906
991
  };
907
992
 
908
993
  const GITHUB_HOST = "github.com";
@@ -920,10 +1005,14 @@ function readGitHubIntegrationConfig(config) {
920
1005
  clientSecret: c.getString("clientSecret"),
921
1006
  webhookSecret: c.getString("webhookSecret"),
922
1007
  privateKey: c.getString("privateKey"),
923
- allowedInstallationOwners: c.getOptionalStringArray("allowedInstallationOwners")
1008
+ allowedInstallationOwners: c.getOptionalStringArray(
1009
+ "allowedInstallationOwners"
1010
+ )
924
1011
  }));
925
1012
  if (!isValidHost(host)) {
926
- throw new Error(`Invalid GitHub integration config, '${host}' is not a valid host`);
1013
+ throw new Error(
1014
+ `Invalid GitHub integration config, '${host}' is not a valid host`
1015
+ );
927
1016
  }
928
1017
  if (apiBaseUrl) {
929
1018
  apiBaseUrl = trimEnd(apiBaseUrl, "/");
@@ -1028,6 +1117,7 @@ class GithubAppManager {
1028
1117
  }
1029
1118
  const cacheKey = repo ? `${owner}/${repo}` : owner;
1030
1119
  return this.cache.getOrCreateToken(cacheKey, async () => {
1120
+ var _a2;
1031
1121
  const result = await this.appClient.apps.createInstallationAccessToken({
1032
1122
  installation_id: installationId,
1033
1123
  headers: HEADERS
@@ -1037,12 +1127,17 @@ class GithubAppManager {
1037
1127
  baseUrl: this.baseUrl,
1038
1128
  auth: result.data.token
1039
1129
  });
1040
- const repos = await installationClient.paginate(installationClient.apps.listReposAccessibleToInstallation);
1041
- const hasRepo = repos.some((repository) => {
1130
+ const repos = await installationClient.paginate(
1131
+ installationClient.apps.listReposAccessibleToInstallation
1132
+ );
1133
+ const repositories = (_a2 = repos.repositories) != null ? _a2 : repos;
1134
+ const hasRepo = repositories.some((repository) => {
1042
1135
  return repository.name === repo;
1043
1136
  });
1044
1137
  if (!hasRepo) {
1045
- throw new Error(`The Backstage GitHub application used in the ${owner} organization does not have access to a repository with the name ${repo}`);
1138
+ throw new Error(
1139
+ `The Backstage GitHub application used in the ${owner} organization does not have access to a repository with the name ${repo}`
1140
+ );
1046
1141
  }
1047
1142
  }
1048
1143
  return {
@@ -1056,17 +1151,21 @@ class GithubAppManager {
1056
1151
  }
1057
1152
  async getInstallationData(owner) {
1058
1153
  const allInstallations = await this.getInstallations();
1059
- const installation = allInstallations.find((inst) => {
1060
- var _a, _b;
1061
- return ((_b = (_a = inst.account) == null ? void 0 : _a.login) == null ? void 0 : _b.toLocaleLowerCase("en-US")) === owner.toLocaleLowerCase("en-US");
1062
- });
1154
+ const installation = allInstallations.find(
1155
+ (inst) => {
1156
+ var _a, _b;
1157
+ return ((_b = (_a = inst.account) == null ? void 0 : _a.login) == null ? void 0 : _b.toLocaleLowerCase("en-US")) === owner.toLocaleLowerCase("en-US");
1158
+ }
1159
+ );
1063
1160
  if (installation) {
1064
1161
  return {
1065
1162
  installationId: installation.id,
1066
1163
  suspended: Boolean(installation.suspended_by)
1067
1164
  };
1068
1165
  }
1069
- const notFoundError = new Error(`No app installation found for ${owner} in ${this.baseAuthConfig.appId}`);
1166
+ const notFoundError = new Error(
1167
+ `No app installation found for ${owner} in ${this.baseAuthConfig.appId}`
1168
+ );
1070
1169
  notFoundError.name = "NotFoundError";
1071
1170
  throw notFoundError;
1072
1171
  }
@@ -1080,14 +1179,23 @@ class GithubAppCredentialsMux {
1080
1179
  if (!this.apps.length) {
1081
1180
  return [];
1082
1181
  }
1083
- const installs = await Promise.all(this.apps.map((app) => app.getInstallations()));
1182
+ const installs = await Promise.all(
1183
+ this.apps.map((app) => app.getInstallations())
1184
+ );
1084
1185
  return installs.flat();
1085
1186
  }
1086
1187
  async getAppToken(owner, repo) {
1087
1188
  if (this.apps.length === 0) {
1088
1189
  return void 0;
1089
1190
  }
1090
- const results = await Promise.all(this.apps.map((app) => app.getInstallationCredentials(owner, repo).then((credentials) => ({ credentials, error: void 0 }), (error) => ({ credentials: void 0, error }))));
1191
+ const results = await Promise.all(
1192
+ this.apps.map(
1193
+ (app) => app.getInstallationCredentials(owner, repo).then(
1194
+ (credentials) => ({ credentials, error: void 0 }),
1195
+ (error) => ({ credentials: void 0, error })
1196
+ )
1197
+ )
1198
+ );
1091
1199
  const result = results.find((resultItem) => resultItem.credentials);
1092
1200
  if (result) {
1093
1201
  return result.credentials.accessToken;
@@ -1124,7 +1232,10 @@ const _SingleInstanceGithubCredentialsProvider = class {
1124
1232
  };
1125
1233
  let SingleInstanceGithubCredentialsProvider = _SingleInstanceGithubCredentialsProvider;
1126
1234
  SingleInstanceGithubCredentialsProvider.create = (config) => {
1127
- return new _SingleInstanceGithubCredentialsProvider(new GithubAppCredentialsMux(config), config.token);
1235
+ return new _SingleInstanceGithubCredentialsProvider(
1236
+ new GithubAppCredentialsMux(config),
1237
+ config.token
1238
+ );
1128
1239
  };
1129
1240
 
1130
1241
  class DefaultGithubCredentialsProvider {
@@ -1143,7 +1254,9 @@ class DefaultGithubCredentialsProvider {
1143
1254
  const parsed = new URL(opts.url);
1144
1255
  const provider = this.providers.get(parsed.host);
1145
1256
  if (!provider) {
1146
- throw new Error(`There is no GitHub integration that matches ${opts.url}. Please add a configuration for an integration.`);
1257
+ throw new Error(
1258
+ `There is no GitHub integration that matches ${opts.url}. Please add a configuration for an integration.`
1259
+ );
1147
1260
  }
1148
1261
  return provider.getCredentials(opts);
1149
1262
  }
@@ -1172,13 +1285,21 @@ const _GitHubIntegration = class {
1172
1285
  let GitHubIntegration = _GitHubIntegration;
1173
1286
  GitHubIntegration.factory = ({ config }) => {
1174
1287
  var _a;
1175
- const configs = readGitHubIntegrationConfigs((_a = config.getOptionalConfigArray("integrations.github")) != null ? _a : []);
1176
- return basicIntegrations(configs.map((c) => new _GitHubIntegration(c)), (i) => i.config.host);
1288
+ const configs = readGitHubIntegrationConfigs(
1289
+ (_a = config.getOptionalConfigArray("integrations.github")) != null ? _a : []
1290
+ );
1291
+ return basicIntegrations(
1292
+ configs.map((c) => new _GitHubIntegration(c)),
1293
+ (i) => i.config.host
1294
+ );
1177
1295
  };
1178
1296
  function replaceGitHubUrlType(url, type) {
1179
- return url.replace(/\/\/([^/]+)\/([^/]+)\/([^/]+)\/(blob|tree|edit)\//, (_, host, owner, repo) => {
1180
- return `//${host}/${owner}/${repo}/${type}/`;
1181
- });
1297
+ return url.replace(
1298
+ /\/\/([^/]+)\/([^/]+)\/([^/]+)\/(blob|tree|edit)\//,
1299
+ (_, host, owner, repo) => {
1300
+ return `//${host}/${owner}/${repo}/${type}/`;
1301
+ }
1302
+ );
1182
1303
  }
1183
1304
 
1184
1305
  const GITLAB_HOST = "gitlab.com";
@@ -1199,11 +1320,17 @@ function readGitLabIntegrationConfig(config) {
1199
1320
  baseUrl = `https://${host}`;
1200
1321
  }
1201
1322
  if (!isValidHost(host)) {
1202
- throw new Error(`Invalid GitLab integration config, '${host}' is not a valid host`);
1323
+ throw new Error(
1324
+ `Invalid GitLab integration config, '${host}' is not a valid host`
1325
+ );
1203
1326
  } else if (!apiBaseUrl || !isValidUrl(apiBaseUrl)) {
1204
- throw new Error(`Invalid GitLab integration config, '${apiBaseUrl}' is not a valid apiBaseUrl`);
1327
+ throw new Error(
1328
+ `Invalid GitLab integration config, '${apiBaseUrl}' is not a valid apiBaseUrl`
1329
+ );
1205
1330
  } else if (!isValidUrl(baseUrl)) {
1206
- throw new Error(`Invalid GitLab integration config, '${baseUrl}' is not a valid baseUrl`);
1331
+ throw new Error(
1332
+ `Invalid GitLab integration config, '${baseUrl}' is not a valid baseUrl`
1333
+ );
1207
1334
  }
1208
1335
  return { host, token, apiBaseUrl, baseUrl };
1209
1336
  }
@@ -1218,13 +1345,17 @@ function readGitLabIntegrationConfigs(configs) {
1218
1345
  }
1219
1346
  return result;
1220
1347
  }
1348
+ function getGitLabIntegrationRelativePath(config) {
1349
+ let relativePath = "";
1350
+ if (config.host !== GITLAB_HOST) {
1351
+ relativePath = new URL(config.baseUrl).pathname;
1352
+ }
1353
+ return trimEnd(relativePath, "/");
1354
+ }
1221
1355
 
1222
1356
  async function getGitLabFileFetchUrl(url, config) {
1223
- if (url.includes("/-/blob/")) {
1224
- const projectID = await getProjectId(url, config);
1225
- return buildProjectUrl(url, projectID).toString();
1226
- }
1227
- return buildRawUrl(url).toString();
1357
+ const projectID = await getProjectId(url, config);
1358
+ return buildProjectUrl(url, projectID, config).toString();
1228
1359
  }
1229
1360
  function getGitLabRequestOptions(config) {
1230
1361
  const { token = "" } = config;
@@ -1234,32 +1365,15 @@ function getGitLabRequestOptions(config) {
1234
1365
  }
1235
1366
  };
1236
1367
  }
1237
- function buildRawUrl(target) {
1368
+ function buildProjectUrl(target, projectID, config) {
1238
1369
  try {
1239
1370
  const url = new URL(target);
1240
- const splitPath = url.pathname.split("/").filter(Boolean);
1241
- const blobIndex = splitPath.indexOf("blob", 2);
1242
- if (blobIndex < 2 || blobIndex === splitPath.length - 1) {
1243
- throw new InputError("Wrong GitLab URL");
1244
- }
1245
- const repoPath = splitPath.slice(0, blobIndex);
1246
- const restOfPath = splitPath.slice(blobIndex + 1);
1247
- if (!restOfPath.join("/").match(/\.(yaml|yml)$/)) {
1248
- throw new InputError("Wrong GitLab URL");
1249
- }
1250
- url.pathname = [...repoPath, "raw", ...restOfPath].join("/");
1251
- return url;
1252
- } catch (e) {
1253
- throw new InputError(`Incorrect url: ${target}, ${e}`);
1254
- }
1255
- }
1256
- function buildProjectUrl(target, projectID) {
1257
- try {
1258
- const url = new URL(target);
1259
- const branchAndFilePath = url.pathname.split("/-/blob/")[1];
1371
+ const branchAndFilePath = url.pathname.split("/blob/").slice(1).join("/blob/");
1260
1372
  const [branch, ...filePath] = branchAndFilePath.split("/");
1373
+ const relativePath = getGitLabIntegrationRelativePath(config);
1261
1374
  url.pathname = [
1262
- "/api/v4/projects",
1375
+ ...relativePath ? [relativePath] : [],
1376
+ "api/v4/projects",
1263
1377
  projectID,
1264
1378
  "repository/files",
1265
1379
  encodeURIComponent(decodeURIComponent(filePath.join("/"))),
@@ -1273,16 +1387,29 @@ function buildProjectUrl(target, projectID) {
1273
1387
  }
1274
1388
  async function getProjectId(target, config) {
1275
1389
  const url = new URL(target);
1276
- if (!url.pathname.includes("/-/blob/")) {
1390
+ if (!url.pathname.includes("/blob/")) {
1277
1391
  throw new Error("Please provide full path to yaml file from GitLab");
1278
1392
  }
1279
1393
  try {
1280
- const repo = url.pathname.split("/-/blob/")[0];
1281
- const repoIDLookup = new URL(`${url.origin}/api/v4/projects/${encodeURIComponent(repo.replace(/^\//, ""))}`);
1282
- const response = await fetch(repoIDLookup.toString(), getGitLabRequestOptions(config));
1394
+ let repo = url.pathname.split("/-/blob/")[0].split("/blob/")[0];
1395
+ const relativePath = getGitLabIntegrationRelativePath(config);
1396
+ if (relativePath) {
1397
+ repo = repo.replace(relativePath, "");
1398
+ }
1399
+ const repoIDLookup = new URL(
1400
+ `${url.origin}${relativePath}/api/v4/projects/${encodeURIComponent(
1401
+ repo.replace(/^\//, "")
1402
+ )}`
1403
+ );
1404
+ const response = await fetch(
1405
+ repoIDLookup.toString(),
1406
+ getGitLabRequestOptions(config)
1407
+ );
1283
1408
  const data = await response.json();
1284
1409
  if (!response.ok) {
1285
- throw new Error(`GitLab Error '${data.error}', ${data.error_description}`);
1410
+ throw new Error(
1411
+ `GitLab Error '${data.error}', ${data.error_description}`
1412
+ );
1286
1413
  }
1287
1414
  return Number(data.id);
1288
1415
  } catch (e) {
@@ -1313,8 +1440,13 @@ const _GitLabIntegration = class {
1313
1440
  let GitLabIntegration = _GitLabIntegration;
1314
1441
  GitLabIntegration.factory = ({ config }) => {
1315
1442
  var _a;
1316
- const configs = readGitLabIntegrationConfigs((_a = config.getOptionalConfigArray("integrations.gitlab")) != null ? _a : []);
1317
- return basicIntegrations(configs.map((c) => new _GitLabIntegration(c)), (i) => i.config.host);
1443
+ const configs = readGitLabIntegrationConfigs(
1444
+ (_a = config.getOptionalConfigArray("integrations.gitlab")) != null ? _a : []
1445
+ );
1446
+ return basicIntegrations(
1447
+ configs.map((c) => new _GitLabIntegration(c)),
1448
+ (i) => i.config.host
1449
+ );
1318
1450
  };
1319
1451
  function replaceGitLabUrlType(url, type) {
1320
1452
  return url.replace(/\/\-\/(blob|tree|edit)\//, `/-/${type}/`);
@@ -1373,10 +1505,21 @@ class ScmIntegrations {
1373
1505
  return this.byType.gitlab;
1374
1506
  }
1375
1507
  list() {
1376
- return Object.values(this.byType).flatMap((i) => i.list());
1508
+ return Object.values(this.byType).flatMap(
1509
+ (i) => i.list()
1510
+ );
1377
1511
  }
1378
1512
  byUrl(url) {
1379
- return Object.values(this.byType).map((i) => i.byUrl(url)).find(Boolean);
1513
+ let candidates = Object.values(this.byType).map((i) => i.byUrl(url)).filter(Boolean);
1514
+ if (candidates.length > 1) {
1515
+ const filteredCandidates = candidates.filter(
1516
+ (x) => !(x instanceof BitbucketIntegration)
1517
+ );
1518
+ if (filteredCandidates.length !== 0) {
1519
+ candidates = filteredCandidates;
1520
+ }
1521
+ }
1522
+ return candidates[0];
1380
1523
  }
1381
1524
  byHost(host) {
1382
1525
  return Object.values(this.byType).map((i) => i.byHost(host)).find(Boolean);
@@ -1397,5 +1540,5 @@ class ScmIntegrations {
1397
1540
  }
1398
1541
  }
1399
1542
 
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 };
1543
+ 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
1544
  //# sourceMappingURL=index.esm.js.map