'use strict'; var parseGitUrl = require('git-url-parse'); var lodash = require('lodash'); var identity = require('@azure/identity'); var fetch = require('cross-fetch'); var authApp = require('@octokit/auth-app'); var rest = require('@octokit/rest'); var luxon = require('luxon'); function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; } var parseGitUrl__default = /*#__PURE__*/_interopDefaultCompat(parseGitUrl); var fetch__default = /*#__PURE__*/_interopDefaultCompat(fetch); function isValidHost(host) { const check = new URL("http://example.com"); check.host = host; return check.host === host; } function isValidUrl(url) { try { new URL(url); return true; } catch { return false; } } function basicIntegrations(integrations, getHost) { return { list() { return integrations; }, byUrl(url) { try { const parsed = typeof url === "string" ? new URL(url) : url; return integrations.find((i) => getHost(i) === parsed.host); } catch { return void 0; } }, byHost(host) { return integrations.find((i) => getHost(i) === host); } }; } function defaultScmResolveUrl(options) { const { url, base, lineNumber } = options; try { new URL(url); return url; } catch { } let updated; if (url.startsWith("/")) { const { href, filepath } = parseGitUrl__default.default(base); updated = new URL(href); const repoRootPath = lodash.trimEnd( updated.pathname.substring(0, updated.pathname.length - filepath.length), "/" ); updated.pathname = `${repoRootPath}${url}`; } else { updated = new URL(url, base); } updated.search = new URL(base).search; if (lineNumber) { updated.hash = `L${lineNumber}`; } return updated.toString(); } const AMAZON_AWS_HOST = "amazonaws.com"; function readAwsS3IntegrationConfig(config) { var _a, _b; const endpoint = config.getOptionalString("endpoint"); const s3ForcePathStyle = (_a = config.getOptionalBoolean("s3ForcePathStyle")) != null ? _a : false; let host; let pathname; if (endpoint) { try { const url = new URL(endpoint); host = url.host; pathname = url.pathname; } catch { throw new Error( `invalid awsS3 integration config, endpoint '${endpoint}' is not a valid URL` ); } if (pathname !== "/") { throw new Error( `invalid awsS3 integration config, endpoints cannot contain path, got '${endpoint}'` ); } } else { host = AMAZON_AWS_HOST; } const accessKeyId = config.getOptionalString("accessKeyId"); const secretAccessKey = (_b = config.getOptionalString("secretAccessKey")) == null ? void 0 : _b.trim(); const roleArn = config.getOptionalString("roleArn"); const externalId = config.getOptionalString("externalId"); return { host, endpoint, s3ForcePathStyle, accessKeyId, secretAccessKey, roleArn, externalId }; } function readAwsS3IntegrationConfigs(configs) { const result = configs.map(readAwsS3IntegrationConfig); if (!result.some((c) => c.host === AMAZON_AWS_HOST)) { result.push({ host: AMAZON_AWS_HOST }); } return result; } var __defProp$e = Object.defineProperty; var __defNormalProp$e = (obj, key, value) => key in obj ? __defProp$e(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$e = (obj, key, value) => { __defNormalProp$e(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; const _AwsS3Integration = class _AwsS3Integration { constructor(integrationConfig) { this.integrationConfig = integrationConfig; } get type() { return "awsS3"; } get title() { return this.integrationConfig.host; } get config() { return this.integrationConfig; } resolveUrl(options) { const resolved = defaultScmResolveUrl(options); return resolved; } resolveEditUrl(url) { return url; } }; __publicField$e(_AwsS3Integration, "factory", ({ config }) => { var _a; const configs = readAwsS3IntegrationConfigs( (_a = config.getOptionalConfigArray("integrations.awsS3")) != null ? _a : [] ); return basicIntegrations( configs.map((c) => new _AwsS3Integration(c)), (i) => i.config.host ); }); let AwsS3Integration = _AwsS3Integration; const AMAZON_AWS_CODECOMMIT_HOST = "console.aws.amazon.com"; function readAwsCodeCommitIntegrationConfig(config) { var _a; const accessKeyId = config.getOptionalString("accessKeyId"); const secretAccessKey = (_a = config.getOptionalString("secretAccessKey")) == null ? void 0 : _a.trim(); const roleArn = config.getOptionalString("roleArn"); const externalId = config.getOptionalString("externalId"); const host = AMAZON_AWS_CODECOMMIT_HOST; return { host, accessKeyId, secretAccessKey, roleArn, externalId }; } function readAwsCodeCommitIntegrationConfigs(configs) { const result = configs.map(readAwsCodeCommitIntegrationConfig); if (!result.some((c) => c.host === AMAZON_AWS_CODECOMMIT_HOST)) { result.push({ host: AMAZON_AWS_CODECOMMIT_HOST }); } return result; } var __defProp$d = Object.defineProperty; var __defNormalProp$d = (obj, key, value) => key in obj ? __defProp$d(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$d = (obj, key, value) => { __defNormalProp$d(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; const _AwsCodeCommitIntegration = class _AwsCodeCommitIntegration { constructor(integrationConfig) { this.integrationConfig = integrationConfig; } get type() { return "awsCodeCommit"; } get config() { return this.integrationConfig; } get title() { return this.integrationConfig.host; } resolveUrl(options) { const resolved = defaultScmResolveUrl(options); return resolved; } resolveEditUrl(url) { const parsedUrl = new URL(url); const pathMatch = parsedUrl.pathname.match( /^\/codesuite\/codecommit\/repositories\/([^\/]+)\// ); if (!pathMatch) { throw new Error(``); } const [, repositoryName] = pathMatch; return replaceCodeCommitUrlType(url, repositoryName, "edit"); } }; __publicField$d(_AwsCodeCommitIntegration, "factory", ({ config }) => { var _a; const configs = readAwsCodeCommitIntegrationConfigs( (_a = config.getOptionalConfigArray("integrations.awsCodeCommit")) != null ? _a : [] ); return basicIntegrations( configs.map((c) => new _AwsCodeCommitIntegration(c)), (i) => i.config.host ); }); let AwsCodeCommitIntegration = _AwsCodeCommitIntegration; function replaceCodeCommitUrlType(url, repositoryName, type) { const newString = type === "edit" ? `files/edit` : type; return url.replace( new RegExp( `/codesuite/codecommit/repositories/${repositoryName}/(browse|files/edit)/` ), `/codesuite/codecommit/repositories/${repositoryName}/${newString}/` ); } var __accessCheck = (obj, member, msg) => { if (!member.has(obj)) throw TypeError("Cannot " + msg); }; var __privateGet = (obj, member, getter) => { __accessCheck(obj, member, "read from private field"); return getter ? getter.call(obj) : member.get(obj); }; var __privateAdd = (obj, member, value) => { if (member.has(obj)) throw TypeError("Cannot add the same private member more than once"); member instanceof WeakSet ? member.add(obj) : member.set(obj, value); }; var __privateSet = (obj, member, value, setter) => { __accessCheck(obj, member, "write to private field"); setter ? setter.call(obj, value) : member.set(obj, value); return value; }; var _origin, _owner, _project, _repo, _path, _ref, _baseUrl; const VERSION_PREFIX_GIT_BRANCH = "GB"; const _AzureUrl = class _AzureUrl { constructor(origin, owner, project, repo, path, ref) { __privateAdd(this, _origin, void 0); __privateAdd(this, _owner, void 0); __privateAdd(this, _project, void 0); __privateAdd(this, _repo, void 0); __privateAdd(this, _path, void 0); __privateAdd(this, _ref, void 0); __privateAdd(this, _baseUrl, (...parts) => { const url = new URL(__privateGet(this, _origin)); url.pathname = parts.map((part) => encodeURIComponent(part)).join("/"); return url; }); __privateSet(this, _origin, origin); __privateSet(this, _owner, owner); __privateSet(this, _project, project); __privateSet(this, _repo, repo); __privateSet(this, _path, path); __privateSet(this, _ref, ref); } /** * Parses an azure URL as copied from the browser address bar. * * Throws an error if the URL is not a valid azure repo URL. */ static fromRepoUrl(repoUrl) { var _a; const url = new URL(repoUrl); let owner; let project; let repo; const parts = url.pathname.split("/").map((part) => decodeURIComponent(part)); if (parts[2] === "_git") { owner = parts[1]; project = repo = parts[3]; } else if (parts[3] === "_git") { owner = parts[1]; project = parts[2]; repo = parts[4]; } else if (parts[4] === "_git") { owner = `${parts[1]}/${parts[2]}`; project = parts[3]; repo = parts[5]; } if (!owner || !project || !repo) { throw new Error("Azure URL must point to a git repository"); } const path = (_a = url.searchParams.get("path")) != null ? _a : void 0; let ref; const version = url.searchParams.get("version"); if (version) { const prefix = version.slice(0, 2); if (prefix !== "GB") { throw new Error("Azure URL version must point to a git branch"); } ref = version.slice(2); } return new _AzureUrl(url.origin, owner, project, repo, path, ref); } /** * Returns a repo URL that can be used to navigate to the resource in azure. * * Throws an error if the URL is not a valid azure repo URL. */ toRepoUrl() { let url; if (__privateGet(this, _project) === __privateGet(this, _repo)) { url = __privateGet(this, _baseUrl).call(this, __privateGet(this, _owner), "_git", __privateGet(this, _repo)); } else { url = __privateGet(this, _baseUrl).call(this, __privateGet(this, _owner), __privateGet(this, _project), "_git", __privateGet(this, _repo)); } if (__privateGet(this, _path)) { url.searchParams.set("path", __privateGet(this, _path)); } if (__privateGet(this, _ref)) { url.searchParams.set("version", VERSION_PREFIX_GIT_BRANCH + __privateGet(this, _ref)); } return url.toString(); } /** * Returns the file download URL for this azure resource. * * Throws an error if the URL does not point to a file. */ toFileUrl() { if (!__privateGet(this, _path)) { throw new Error( "Azure URL must point to a specific path to be able to download a file" ); } const url = __privateGet(this, _baseUrl).call(this, __privateGet(this, _owner), __privateGet(this, _project), "_apis", "git", "repositories", __privateGet(this, _repo), "items"); url.searchParams.set("api-version", "6.0"); url.searchParams.set("path", __privateGet(this, _path)); if (__privateGet(this, _ref)) { url.searchParams.set("version", __privateGet(this, _ref)); } return url.toString(); } /** * Returns the archive download URL for this azure resource. * * Throws an error if the URL does not point to a repo. */ toArchiveUrl() { const url = __privateGet(this, _baseUrl).call(this, __privateGet(this, _owner), __privateGet(this, _project), "_apis", "git", "repositories", __privateGet(this, _repo), "items"); url.searchParams.set("recursionLevel", "full"); url.searchParams.set("download", "true"); url.searchParams.set("api-version", "6.0"); if (__privateGet(this, _path)) { url.searchParams.set("scopePath", __privateGet(this, _path)); } if (__privateGet(this, _ref)) { url.searchParams.set("version", __privateGet(this, _ref)); } return url.toString(); } /** * Returns the API url for fetching commits from a branch for this azure resource. * * Throws an error if the URL does not point to a commit. */ toCommitsUrl() { const url = __privateGet(this, _baseUrl).call(this, __privateGet(this, _owner), __privateGet(this, _project), "_apis", "git", "repositories", __privateGet(this, _repo), "commits"); url.searchParams.set("api-version", "6.0"); if (__privateGet(this, _ref)) { url.searchParams.set("searchCriteria.itemVersion.version", __privateGet(this, _ref)); } return url.toString(); } /** * Returns the name of the owner, a user or an organization. */ getOwner() { return __privateGet(this, _owner); } /** * Returns the name of the project. */ getProject() { return __privateGet(this, _project); } /** * Returns the name of the repo. */ getRepo() { return __privateGet(this, _repo); } /** * Returns the file path within the repo if the URL contains one. */ getPath() { return __privateGet(this, _path); } /** * Returns the git ref in the repo if the URL contains one. */ getRef() { return __privateGet(this, _ref); } }; _origin = new WeakMap(); _owner = new WeakMap(); _project = new WeakMap(); _repo = new WeakMap(); _path = new WeakMap(); _ref = new WeakMap(); _baseUrl = new WeakMap(); let AzureUrl = _AzureUrl; const AZURE_HOST = "dev.azure.com"; const AzureDevOpsCredentialFields = [ "clientId", "clientSecret", "tenantId", "personalAccessToken" ]; const AzureDevopsCredentialFieldMap = /* @__PURE__ */ new Map([ ["ClientSecret", ["clientId", "clientSecret", "tenantId"]], ["ManagedIdentity", ["clientId"]], ["PersonalAccessToken", ["personalAccessToken"]] ]); function asAzureDevOpsCredential(credential) { for (const entry of AzureDevopsCredentialFieldMap.entries()) { const [kind, requiredFields] = entry; const forbiddenFields = AzureDevOpsCredentialFields.filter( (field) => !requiredFields.includes(field) ); if (requiredFields.every((field) => credential[field] !== void 0) && forbiddenFields.every((field) => credential[field] === void 0)) { return { kind, organizations: credential.organizations, ...requiredFields.reduce((acc, field) => { acc[field] = credential[field]; return acc; }, {}) }; } } throw new Error("is not a valid credential"); } function readAzureIntegrationConfig(config) { var _a, _b, _c, _d, _e, _f, _g; const host = (_a = config.getOptionalString("host")) != null ? _a : AZURE_HOST; let credentialConfigs = (_b = config.getOptionalConfigArray("credentials")) == null ? void 0 : _b.map((credential) => { var _a2, _b2; const result = { organizations: credential.getOptionalStringArray("organizations"), personalAccessToken: (_a2 = credential.getOptionalString("personalAccessToken")) == null ? void 0 : _a2.trim(), tenantId: credential.getOptionalString("tenantId"), clientId: credential.getOptionalString("clientId"), clientSecret: (_b2 = credential.getOptionalString("clientSecret")) == null ? void 0 : _b2.trim() }; return result; }); const token = (_c = config.getOptionalString("token")) == null ? void 0 : _c.trim(); if (config.getOptional("credential") !== void 0 && config.getOptional("credentials") !== void 0) { throw new Error( `Invalid Azure integration config, 'credential' and 'credentials' cannot be used together. Use 'credentials' instead.` ); } if (config.getOptional("token") !== void 0 && config.getOptional("credentials") !== void 0) { throw new Error( `Invalid Azure integration config, 'token' and 'credentials' cannot be used together. Use 'credentials' instead.` ); } if (token !== void 0) { const mapped = [{ personalAccessToken: token }]; credentialConfigs = (_d = credentialConfigs == null ? void 0 : credentialConfigs.concat(mapped)) != null ? _d : mapped; } if (config.getOptional("credential") !== void 0) { const mapped = [ { organizations: config.getOptionalStringArray( "credential.organizations" ), token: (_e = config.getOptionalString("credential.token")) == null ? void 0 : _e.trim(), tenantId: config.getOptionalString("credential.tenantId"), clientId: config.getOptionalString("credential.clientId"), clientSecret: (_f = config.getOptionalString("credential.clientSecret")) == null ? void 0 : _f.trim() } ]; credentialConfigs = (_g = credentialConfigs == null ? void 0 : credentialConfigs.concat(mapped)) != null ? _g : mapped; } if (!isValidHost(host)) { throw new Error( `Invalid Azure integration config, '${host}' is not a valid host` ); } let credentials = void 0; if (credentialConfigs !== void 0) { const errors = credentialConfigs == null ? void 0 : credentialConfigs.reduce((acc, credentialConfig, index) => { let error = void 0; try { asAzureDevOpsCredential(credentialConfig); } catch (e) { error = e.message; } if (error !== void 0) { acc.push(`credential at position ${index + 1} ${error}`); } return acc; }, Array.of()).concat( Object.entries( credentialConfigs.filter( (credential) => credential.organizations !== void 0 && credential.organizations.length > 0 ).reduce((acc, credential, index) => { var _a2; (_a2 = credential.organizations) == null ? void 0 : _a2.forEach((organization) => { if (!acc[organization]) { acc[organization] = []; } acc[organization].push(index + 1); }); return acc; }, {}) ).filter(([_, indexes]) => indexes.length > 1).reduce((acc, [org, indexes]) => { acc.push( `organization ${org} is specified multiple times in credentials at positions ${indexes.slice(0, indexes.length - 1).join(", ")} and ${indexes[indexes.length - 1]}` ); return acc; }, Array.of()) ); if ((errors == null ? void 0 : errors.length) > 0) { throw new Error( `Invalid Azure integration config for ${host}: ${errors.join("; ")}` ); } credentials = credentialConfigs.map( (credentialConfig) => asAzureDevOpsCredential(credentialConfig) ); if (credentials.some( (credential) => credential.kind !== "PersonalAccessToken" ) && host !== AZURE_HOST) { throw new Error( `Invalid Azure integration config for ${host}, only personal access tokens can be used with hosts other than ${AZURE_HOST}` ); } if (credentials.filter( (credential) => credential.organizations === void 0 || credential.organizations.length === 0 ).length > 1) { throw new Error( `Invalid Azure integration config for ${host}, you cannot specify multiple credentials without organizations` ); } } return { host, credentials }; } function readAzureIntegrationConfigs(configs) { const result = configs.map(readAzureIntegrationConfig); if (!result.some((c) => c.host === AZURE_HOST)) { result.push({ host: AZURE_HOST }); } return result; } var __defProp$c = Object.defineProperty; var __defNormalProp$c = (obj, key, value) => key in obj ? __defProp$c(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$c = (obj, key, value) => { __defNormalProp$c(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; const _AzureIntegration = class _AzureIntegration { constructor(integrationConfig) { this.integrationConfig = integrationConfig; } get type() { return "azure"; } get title() { return this.integrationConfig.host; } get config() { return this.integrationConfig; } /* * Azure repo URLs on the form with a `path` query param are treated specially. * * Example base URL: https://dev.azure.com/organization/project/_git/repository?path=%2Fcatalog-info.yaml */ resolveUrl(options) { var _a; const { url, base } = options; if (isValidUrl(url)) { return url; } try { const azureUrl = AzureUrl.fromRepoUrl(base); const newUrl = new URL(base); const mockBaseUrl = new URL(`https://a.com${(_a = azureUrl.getPath()) != null ? _a : ""}`); const updatedPath = new URL(url, mockBaseUrl).pathname; newUrl.searchParams.set("path", updatedPath); if (options.lineNumber) { newUrl.searchParams.set("line", String(options.lineNumber)); newUrl.searchParams.set("lineEnd", String(options.lineNumber + 1)); newUrl.searchParams.set("lineStartColumn", "1"); newUrl.searchParams.set("lineEndColumn", "1"); } return newUrl.toString(); } catch { return new URL(url, base).toString(); } } resolveEditUrl(url) { return url; } }; __publicField$c(_AzureIntegration, "factory", ({ config }) => { var _a; const configs = readAzureIntegrationConfigs( (_a = config.getOptionalConfigArray("integrations.azure")) != null ? _a : [] ); return basicIntegrations( configs.map((c) => new _AzureIntegration(c)), (i) => i.config.host ); }); let AzureIntegration = _AzureIntegration; function getAzureFileFetchUrl(url) { return AzureUrl.fromRepoUrl(url).toFileUrl(); } function getAzureDownloadUrl(url) { return AzureUrl.fromRepoUrl(url).toArchiveUrl(); } function getAzureCommitsUrl(url) { return AzureUrl.fromRepoUrl(url).toCommitsUrl(); } var __defProp$b = Object.defineProperty; var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$b = (obj, key, value) => { __defNormalProp$b(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; const tenMinutes = 1e3 * 60 * 10; class CachedAzureDevOpsCredentialsProvider { constructor(credential) { this.credential = credential; __publicField$b(this, "azureDevOpsScope", "499b84ac-1321-427f-aa17-267ca6975798/.default"); __publicField$b(this, "cached"); } static fromAzureDevOpsCredential(credential) { switch (credential.kind) { case "PersonalAccessToken": return CachedAzureDevOpsCredentialsProvider.fromPersonalAccessTokenCredential( credential ); case "ClientSecret": return CachedAzureDevOpsCredentialsProvider.fromTokenCredential( new identity.ClientSecretCredential( credential.tenantId, credential.clientId, credential.clientSecret ) ); case "ManagedIdentity": return CachedAzureDevOpsCredentialsProvider.fromTokenCredential( new identity.ManagedIdentityCredential(credential.clientId) ); default: throw new Error( `Credential kind '${credential.kind}' not supported` ); } } static fromTokenCredential(credential) { return new CachedAzureDevOpsCredentialsProvider(credential); } static fromPersonalAccessTokenCredential(credential) { return new CachedAzureDevOpsCredentialsProvider( credential.personalAccessToken ); } async getCredentials() { if (this.cached === void 0 || this.cached.expiresAt !== void 0 && Date.now() > this.cached.expiresAt) { if (typeof this.credential === "string") { this.cached = { headers: { Authorization: `Basic ${btoa(`:${this.credential}`)}` }, type: "pat", token: this.credential }; } else { const accessToken = await this.credential.getToken( this.azureDevOpsScope ); if (!accessToken) { throw new Error("Failed to retrieve access token"); } this.cached = { expiresAt: accessToken.expiresOnTimestamp - tenMinutes, headers: { Authorization: `Bearer ${accessToken.token}` }, type: "bearer", token: accessToken.token }; } } return this.cached; } } class DefaultAzureDevOpsCredentialsProvider { constructor(providers) { this.providers = providers; } static fromIntegrations(integrations) { const providers = integrations.azure.list().reduce((acc, integration) => { var _a; (_a = integration.config.credentials) == null ? void 0 : _a.forEach((credential) => { var _a2; if (credential.organizations === void 0 || credential.organizations.length === 0) { if (acc.get(integration.config.host) === void 0) { acc.set( integration.config.host, CachedAzureDevOpsCredentialsProvider.fromAzureDevOpsCredential( credential ) ); } } else { const provider = CachedAzureDevOpsCredentialsProvider.fromAzureDevOpsCredential( credential ); (_a2 = credential.organizations) == null ? void 0 : _a2.forEach((organization) => { acc.set(`${integration.config.host}/${organization}`, provider); }); } }); if (integration.config.host === "dev.azure.com" && acc.get(integration.config.host) === void 0) { acc.set( integration.config.host, CachedAzureDevOpsCredentialsProvider.fromTokenCredential( new identity.DefaultAzureCredential() ) ); } return acc; }, /* @__PURE__ */ new Map()); return new DefaultAzureDevOpsCredentialsProvider(providers); } forAzureDevOpsServerOrganization(url) { const parts = url.pathname.split("/").filter((part) => part !== ""); if (url.host !== "dev.azure.com" && parts.length > 0) { if (parts[0] !== "tfs") { return this.providers.get(`${url.host}/${parts[0]}`); } else if (parts[0] === "tfs" && parts.length > 1) { return this.providers.get(`${url.host}/${parts[1]}`); } } return void 0; } forAzureDevOpsOrganization(url) { const parts = url.pathname.split("/").filter((part) => part !== ""); if (url.host === "dev.azure.com" && parts.length > 0) { return this.providers.get(`${url.host}/${parts[0]}`); } return void 0; } forHost(url) { return this.providers.get(url.host); } async getCredentials(opts) { var _a, _b; const url = new URL(opts.url); const provider = (_b = (_a = this.forAzureDevOpsOrganization(url)) != null ? _a : this.forAzureDevOpsServerOrganization(url)) != null ? _b : this.forHost(url); if (provider === void 0) { return void 0; } return provider.getCredentials(opts); } } async function getAzureRequestOptions(config, additionalHeaders) { var _a; const headers = additionalHeaders ? { ...additionalHeaders } : {}; const credentialConfig = (_a = config.credentials) == null ? void 0 : _a.filter( (credential) => credential.organizations === void 0 || credential.organizations.length === 0 )[0]; if (credentialConfig) { const credentialsProvider = CachedAzureDevOpsCredentialsProvider.fromAzureDevOpsCredential( credentialConfig ); const credentials = await credentialsProvider.getCredentials(); return { headers: { ...credentials == null ? void 0 : credentials.headers, ...headers } }; } return { headers }; } const BITBUCKET_HOST = "bitbucket.org"; const BITBUCKET_API_BASE_URL = "https://api.bitbucket.org/2.0"; function readBitbucketIntegrationConfig(config) { var _a, _b, _c; const host = (_a = config.getOptionalString("host")) != null ? _a : BITBUCKET_HOST; let apiBaseUrl = config.getOptionalString("apiBaseUrl"); const token = (_b = config.getOptionalString("token")) == null ? void 0 : _b.trim(); const username = config.getOptionalString("username"); const appPassword = (_c = config.getOptionalString("appPassword")) == null ? void 0 : _c.trim(); if (!isValidHost(host)) { throw new Error( `Invalid Bitbucket integration config, '${host}' is not a valid host` ); } if (apiBaseUrl) { apiBaseUrl = lodash.trimEnd(apiBaseUrl, "/"); } else if (host === BITBUCKET_HOST) { apiBaseUrl = BITBUCKET_API_BASE_URL; } else { apiBaseUrl = `https://${host}/rest/api/1.0`; } return { host, apiBaseUrl, token, username, appPassword }; } function readBitbucketIntegrationConfigs(configs) { const result = configs.map(readBitbucketIntegrationConfig); if (!result.some((c) => c.host === BITBUCKET_HOST)) { result.push({ host: BITBUCKET_HOST, apiBaseUrl: BITBUCKET_API_BASE_URL }); } return result; } var __defProp$a = Object.defineProperty; var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$a = (obj, key, value) => { __defNormalProp$a(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; const _BitbucketIntegration = class _BitbucketIntegration { constructor(integrationConfig) { this.integrationConfig = integrationConfig; } get type() { return "bitbucket"; } get title() { return this.integrationConfig.host; } get config() { return this.integrationConfig; } resolveUrl(options) { const resolved = defaultScmResolveUrl(options); if (!options.lineNumber) { return resolved; } const url = new URL(resolved); if (this.integrationConfig.host === "bitbucket.org") { url.hash = `lines-${options.lineNumber}`; } else { url.hash = `${options.lineNumber}`; } return url.toString(); } resolveEditUrl(url) { const urlData = parseGitUrl__default.default(url); const editUrl = new URL(url); editUrl.searchParams.set("mode", "edit"); editUrl.searchParams.set("spa", "0"); editUrl.searchParams.set("at", urlData.ref); return editUrl.toString(); } }; __publicField$a(_BitbucketIntegration, "factory", ({ config }) => { var _a, _b, _c; const configs = readBitbucketIntegrationConfigs( (_c = config.getOptionalConfigArray("integrations.bitbucket")) != null ? _c : [ // if integrations.bitbucket was not used assume the use was migrated to the new configs // and backport for the deprecated integration to be usable for other parts of the system // until these got migrated ...(_a = config.getOptionalConfigArray("integrations.bitbucketCloud")) != null ? _a : [], ...(_b = config.getOptionalConfigArray("integrations.bitbucketServer")) != null ? _b : [] ] ); return basicIntegrations( configs.map((c) => new _BitbucketIntegration(c)), (i) => i.config.host ); }); let BitbucketIntegration = _BitbucketIntegration; async function getBitbucketDefaultBranch(url, config) { const { name: repoName, owner: project, resource } = parseGitUrl__default.default(url); const isHosted = resource === "bitbucket.org"; let branchUrl = isHosted ? `${config.apiBaseUrl}/repositories/${project}/${repoName}` : `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/default-branch`; let response = await fetch__default.default(branchUrl, getBitbucketRequestOptions(config)); if (response.status === 404 && !isHosted) { branchUrl = `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/branches/default`; response = await fetch__default.default(branchUrl, getBitbucketRequestOptions(config)); } if (!response.ok) { const message = `Failed to retrieve default branch from ${branchUrl}, ${response.status} ${response.statusText}`; throw new Error(message); } let defaultBranch; if (isHosted) { const repoInfo = await response.json(); defaultBranch = repoInfo.mainbranch.name; } else { const { displayId } = await response.json(); defaultBranch = displayId; } if (!defaultBranch) { throw new Error( `Failed to read default branch from ${branchUrl}. Response ${response.status} ${response.json()}` ); } return defaultBranch; } async function getBitbucketDownloadUrl(url, config) { const { name: repoName, owner: project, ref, protocol, resource, filepath } = parseGitUrl__default.default(url); const isHosted = resource === "bitbucket.org"; let branch = ref; if (!branch) { branch = await getBitbucketDefaultBranch(url, config); } const path = filepath ? `&path=${encodeURIComponent(decodeURIComponent(filepath))}` : ""; 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}`; return archiveUrl; } function getBitbucketFileFetchUrl(url, config) { try { const { owner, name, ref, filepathtype, filepath } = parseGitUrl__default.default(url); if (!owner || !name || filepathtype !== "browse" && filepathtype !== "raw" && filepathtype !== "src") { throw new Error("Invalid Bitbucket URL or file path"); } const pathWithoutSlash = filepath.replace(/^\//, ""); if (config.host === "bitbucket.org") { if (!ref) { throw new Error("Invalid Bitbucket URL or file path"); } return `${config.apiBaseUrl}/repositories/${owner}/${name}/src/${ref}/${pathWithoutSlash}`; } return `${config.apiBaseUrl}/projects/${owner}/repos/${name}/raw/${pathWithoutSlash}?at=${ref}`; } catch (e) { throw new Error(`Incorrect URL: ${url}, ${e}`); } } function getBitbucketRequestOptions(config) { const headers = {}; if (config.token) { headers.Authorization = `Bearer ${config.token}`; } else if (config.username && config.appPassword) { const buffer = Buffer.from( `${config.username}:${config.appPassword}`, "utf8" ); headers.Authorization = `Basic ${buffer.toString("base64")}`; } return { headers }; } const BITBUCKET_CLOUD_HOST = "bitbucket.org"; const BITBUCKET_CLOUD_API_BASE_URL = "https://api.bitbucket.org/2.0"; function readBitbucketCloudIntegrationConfig(config) { var _a; const host = BITBUCKET_CLOUD_HOST; const apiBaseUrl = BITBUCKET_CLOUD_API_BASE_URL; const username = config.getString("username"); const appPassword = (_a = config.getString("appPassword")) == null ? void 0 : _a.trim(); return { host, apiBaseUrl, username, appPassword }; } function readBitbucketCloudIntegrationConfigs(configs) { const result = configs.map(readBitbucketCloudIntegrationConfig); if (result.length === 0) { result.push({ host: BITBUCKET_CLOUD_HOST, apiBaseUrl: BITBUCKET_CLOUD_API_BASE_URL }); } return result; } var __defProp$9 = Object.defineProperty; var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$9 = (obj, key, value) => { __defNormalProp$9(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; const _BitbucketCloudIntegration = class _BitbucketCloudIntegration { constructor(integrationConfig) { this.integrationConfig = integrationConfig; } get type() { return "bitbucketCloud"; } get title() { return this.integrationConfig.host; } get config() { return this.integrationConfig; } resolveUrl(options) { const resolved = defaultScmResolveUrl(options); if (options.lineNumber) { const url = new URL(resolved); url.hash = `lines-${options.lineNumber}`; return url.toString(); } return resolved; } resolveEditUrl(url) { const urlData = parseGitUrl__default.default(url); const editUrl = new URL(url); editUrl.searchParams.set("mode", "edit"); editUrl.searchParams.set("at", urlData.ref); return editUrl.toString(); } }; __publicField$9(_BitbucketCloudIntegration, "factory", ({ config }) => { var _a; const configs = readBitbucketCloudIntegrationConfigs( (_a = config.getOptionalConfigArray("integrations.bitbucketCloud")) != null ? _a : [] ); return basicIntegrations( configs.map((c) => new _BitbucketCloudIntegration(c)), (i) => i.config.host ); }); let BitbucketCloudIntegration = _BitbucketCloudIntegration; async function getBitbucketCloudDefaultBranch(url, config) { const { name: repoName, owner: project } = parseGitUrl__default.default(url); const branchUrl = `${config.apiBaseUrl}/repositories/${project}/${repoName}`; const response = await fetch__default.default( branchUrl, getBitbucketCloudRequestOptions(config) ); if (!response.ok) { const message = `Failed to retrieve default branch from ${branchUrl}, ${response.status} ${response.statusText}`; throw new Error(message); } const repoInfo = await response.json(); const defaultBranch = repoInfo.mainbranch.name; if (!defaultBranch) { throw new Error( `Failed to read default branch from ${branchUrl}. Response ${response.status} ${response.json()}` ); } return defaultBranch; } async function getBitbucketCloudDownloadUrl(url, config) { const { name: repoName, owner: project, ref, protocol, resource } = parseGitUrl__default.default(url); let branch = ref; if (!branch) { branch = await getBitbucketCloudDefaultBranch(url, config); } return `${protocol}://${resource}/${project}/${repoName}/get/${branch}.tar.gz`; } function getBitbucketCloudFileFetchUrl(url, config) { try { const { owner, name, ref, filepathtype, filepath } = parseGitUrl__default.default(url); if (!owner || !name || filepathtype !== "src" && filepathtype !== "raw") { throw new Error("Invalid Bitbucket Cloud URL or file path"); } const pathWithoutSlash = filepath.replace(/^\//, ""); if (!ref) { throw new Error("Invalid Bitbucket Cloud URL or file path"); } return `${config.apiBaseUrl}/repositories/${owner}/${name}/src/${ref}/${pathWithoutSlash}`; } catch (e) { throw new Error(`Incorrect URL: ${url}, ${e}`); } } function getBitbucketCloudRequestOptions(config) { const headers = {}; if (config.username && config.appPassword) { const buffer = Buffer.from( `${config.username}:${config.appPassword}`, "utf8" ); headers.Authorization = `Basic ${buffer.toString("base64")}`; } return { headers }; } function readBitbucketServerIntegrationConfig(config) { var _a; const host = config.getString("host"); let apiBaseUrl = config.getOptionalString("apiBaseUrl"); const token = (_a = config.getOptionalString("token")) == null ? void 0 : _a.trim(); const username = config.getOptionalString("username"); const password = config.getOptionalString("password"); if (!isValidHost(host)) { throw new Error( `Invalid Bitbucket Server integration config, '${host}' is not a valid host` ); } if (apiBaseUrl) { apiBaseUrl = lodash.trimEnd(apiBaseUrl, "/"); } else { apiBaseUrl = `https://${host}/rest/api/1.0`; } return { host, apiBaseUrl, token, username, password }; } function readBitbucketServerIntegrationConfigs(configs) { return configs.map(readBitbucketServerIntegrationConfig); } var __defProp$8 = Object.defineProperty; var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$8 = (obj, key, value) => { __defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; const _BitbucketServerIntegration = class _BitbucketServerIntegration { constructor(integrationConfig) { this.integrationConfig = integrationConfig; } get type() { return "bitbucketServer"; } get title() { return this.integrationConfig.host; } get config() { return this.integrationConfig; } resolveUrl(options) { const resolved = defaultScmResolveUrl(options); if (options.lineNumber) { const url = new URL(resolved); url.hash = options.lineNumber.toString(); return url.toString(); } return resolved; } resolveEditUrl(url) { if (url.includes("?")) { return url.substring(0, url.indexOf("?")); } return url; } }; __publicField$8(_BitbucketServerIntegration, "factory", ({ config }) => { var _a; const configs = readBitbucketServerIntegrationConfigs( (_a = config.getOptionalConfigArray("integrations.bitbucketServer")) != null ? _a : [] ); return basicIntegrations( configs.map((c) => new _BitbucketServerIntegration(c)), (i) => i.config.host ); }); let BitbucketServerIntegration = _BitbucketServerIntegration; async function getBitbucketServerDefaultBranch(url, config) { const { name: repoName, owner: project } = parseGitUrl__default.default(url); let branchUrl = `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/default-branch`; let response = await fetch__default.default( branchUrl, getBitbucketServerRequestOptions(config) ); if (response.status === 404) { branchUrl = `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/branches/default`; response = await fetch__default.default(branchUrl, getBitbucketServerRequestOptions(config)); } if (!response.ok) { const message = `Failed to retrieve default branch from ${branchUrl}, ${response.status} ${response.statusText}`; throw new Error(message); } const { displayId } = await response.json(); const defaultBranch = displayId; if (!defaultBranch) { throw new Error( `Failed to read default branch from ${branchUrl}. Response ${response.status} ${response.json()}` ); } return defaultBranch; } async function getBitbucketServerDownloadUrl(url, config) { const { name: repoName, owner: project, ref, filepath } = parseGitUrl__default.default(url); let branch = ref; if (!branch) { branch = await getBitbucketServerDefaultBranch(url, config); } const path = filepath ? `&path=${encodeURIComponent(decodeURIComponent(filepath))}` : ""; return `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/archive?format=tgz&at=${branch}&prefix=${project}-${repoName}${path}`; } function getBitbucketServerFileFetchUrl(url, config) { try { const { owner, name, ref, filepathtype, filepath } = parseGitUrl__default.default(url); if (!owner || !name || filepathtype !== "browse" && filepathtype !== "raw" && filepathtype !== "src") { throw new Error("Invalid Bitbucket Server URL or file path"); } const pathWithoutSlash = filepath.replace(/^\//, ""); return `${config.apiBaseUrl}/projects/${owner}/repos/${name}/raw/${pathWithoutSlash}?at=${ref}`; } catch (e) { throw new Error(`Incorrect URL: ${url}, ${e}`); } } function getBitbucketServerRequestOptions(config) { const headers = {}; if (config.token) { headers.Authorization = `Bearer ${config.token}`; } else if (config.username && config.password) { const buffer = Buffer.from(`${config.username}:${config.password}`, "utf8"); headers.Authorization = `Basic ${buffer.toString("base64")}`; } return { headers }; } function readGerritIntegrationConfig(config) { var _a; const host = config.getString("host"); let baseUrl = config.getOptionalString("baseUrl"); let cloneUrl = config.getOptionalString("cloneUrl"); let gitilesBaseUrl = config.getOptionalString("gitilesBaseUrl"); const username = config.getOptionalString("username"); const password = (_a = config.getOptionalString("password")) == null ? void 0 : _a.trim(); if (!isValidHost(host)) { throw new Error( `Invalid Gerrit integration config, '${host}' is not a valid host` ); } else if (baseUrl && !isValidUrl(baseUrl)) { throw new Error( `Invalid Gerrit integration config, '${baseUrl}' is not a valid baseUrl` ); } else if (cloneUrl && !isValidUrl(cloneUrl)) { throw new Error( `Invalid Gerrit integration config, '${cloneUrl}' is not a valid cloneUrl` ); } else if (gitilesBaseUrl && !isValidUrl(gitilesBaseUrl)) { throw new Error( `Invalid Gerrit integration config, '${gitilesBaseUrl}' is not a valid gitilesBaseUrl` ); } if (baseUrl) { baseUrl = lodash.trimEnd(baseUrl, "/"); } else { baseUrl = `https://${host}`; } if (gitilesBaseUrl) { gitilesBaseUrl = lodash.trimEnd(gitilesBaseUrl, "/"); } else { gitilesBaseUrl = `https://${host}`; } if (cloneUrl) { cloneUrl = lodash.trimEnd(cloneUrl, "/"); } else { cloneUrl = baseUrl; } return { host, baseUrl, cloneUrl, gitilesBaseUrl, username, password }; } function readGerritIntegrationConfigs(configs) { return configs.map(readGerritIntegrationConfig); } const GERRIT_BODY_PREFIX = ")]}'"; function parseGerritGitilesUrl(config, url) { const baseUrlParse = new URL(config.gitilesBaseUrl); const urlParse = new URL(url); const urlPath = urlParse.pathname.substring(urlParse.pathname.startsWith("/a/") ? 2 : 0).replace(baseUrlParse.pathname, ""); const parts = urlPath.split("/").filter((p) => !!p); const projectEndIndex = parts.indexOf("+"); if (projectEndIndex <= 0) { throw new Error(`Unable to parse project from url: ${url}`); } const project = lodash.trimStart(parts.slice(0, projectEndIndex).join("/"), "/"); const branchIndex = parts.indexOf("heads"); if (branchIndex <= 0) { throw new Error(`Unable to parse branch from url: ${url}`); } const branch = parts[branchIndex + 1]; const filePath = parts.slice(branchIndex + 2).join("/"); return { branch, filePath: filePath === "" ? "/" : filePath, project }; } function buildGerritGitilesUrl(config, project, branch, filePath) { return `${config.gitilesBaseUrl}/${project}/+/refs/heads/${branch}/${lodash.trimStart(filePath, "/")}`; } function buildGerritGitilesArchiveUrl(config, project, branch, filePath) { const archiveName = filePath === "/" || filePath === "" ? ".tar.gz" : `/${filePath}.tar.gz`; return `${getGitilesAuthenticationUrl( config )}/${project}/+archive/refs/heads/${branch}${archiveName}`; } function getAuthenticationPrefix(config) { return config.password ? "/a/" : "/"; } function getGitilesAuthenticationUrl(config) { if (!config.baseUrl || !config.gitilesBaseUrl) { throw new Error( "Unexpected Gerrit config values. baseUrl or gitilesBaseUrl not set." ); } if (config.gitilesBaseUrl.startsWith(config.baseUrl)) { return config.gitilesBaseUrl.replace( config.baseUrl.concat("/"), config.baseUrl.concat(getAuthenticationPrefix(config)) ); } if (config.password) { throw new Error( "Since the baseUrl (Gerrit) is not part of the gitilesBaseUrl, an authentication URL could not be constructed." ); } return config.gitilesBaseUrl; } function getGerritBranchApiUrl(config, url) { const { branch, project } = parseGerritGitilesUrl(config, url); return `${config.baseUrl}${getAuthenticationPrefix( config )}projects/${encodeURIComponent(project)}/branches/${branch}`; } function getGerritCloneRepoUrl(config, url) { const { project } = parseGerritGitilesUrl(config, url); return `${config.cloneUrl}${getAuthenticationPrefix(config)}${project}`; } function getGerritFileContentsApiUrl(config, url) { const { branch, filePath, project } = parseGerritGitilesUrl(config, url); return `${config.baseUrl}${getAuthenticationPrefix( config )}projects/${encodeURIComponent( project )}/branches/${branch}/files/${encodeURIComponent(filePath)}/content`; } function getGerritProjectsApiUrl(config) { return `${config.baseUrl}${getAuthenticationPrefix(config)}projects/`; } function getGerritRequestOptions(config) { const headers = {}; if (!config.password) { return headers; } const buffer = Buffer.from(`${config.username}:${config.password}`, "utf8"); headers.Authorization = `Basic ${buffer.toString("base64")}`; return { headers }; } async function parseGerritJsonResponse(response) { const responseBody = await response.text(); if (responseBody.startsWith(GERRIT_BODY_PREFIX)) { try { return JSON.parse(responseBody.slice(GERRIT_BODY_PREFIX.length)); } catch (ex) { throw new Error( `Invalid response from Gerrit: ${responseBody.slice(0, 10)} - ${ex}` ); } } throw new Error( `Gerrit JSON body prefix missing. Found: ${responseBody.slice(0, 10)}` ); } var __defProp$7 = Object.defineProperty; var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$7 = (obj, key, value) => { __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; const _GerritIntegration = class _GerritIntegration { constructor(integrationConfig) { this.integrationConfig = integrationConfig; } get type() { return "gerrit"; } get title() { return this.integrationConfig.host; } get config() { return this.integrationConfig; } resolveUrl(options) { const { url, base, lineNumber } = options; let updated; if (url.startsWith("/")) { const { branch, project } = parseGerritGitilesUrl(this.config, base); return buildGerritGitilesUrl(this.config, project, branch, url); } if (url) { updated = new URL(url, base); } else { updated = new URL(base); } if (lineNumber) { updated.hash = lineNumber.toString(); } return updated.toString(); } resolveEditUrl(url) { return url; } }; __publicField$7(_GerritIntegration, "factory", ({ config }) => { var _a; const configs = readGerritIntegrationConfigs( (_a = config.getOptionalConfigArray("integrations.gerrit")) != null ? _a : [] ); return basicIntegrations( configs.map((c) => new _GerritIntegration(c)), (i) => i.config.host ); }); let GerritIntegration = _GerritIntegration; function readGiteaConfig(config) { var _a; const host = config.getString("host"); let baseUrl = config.getOptionalString("baseUrl"); const username = config.getOptionalString("username"); const password = (_a = config.getOptionalString("password")) == null ? void 0 : _a.trim(); if (!isValidHost(host)) { throw new Error( `Invalid Gitea integration config, '${host}' is not a valid host` ); } else if (baseUrl && !isValidUrl(baseUrl)) { throw new Error( `Invalid Gitea integration config, '${baseUrl}' is not a valid baseUrl` ); } if (baseUrl) { baseUrl = lodash.trimEnd(baseUrl, "/"); } else { baseUrl = `https://${host}`; } return { host, baseUrl, username, password }; } function getGiteaEditContentsUrl(config, url) { const giteaUrl = parseGiteaUrl(config, url); return `${giteaUrl.url}/${giteaUrl.owner}/${giteaUrl.name}/_edit/${giteaUrl.ref}/${giteaUrl.path}`; } function getGiteaFileContentsUrl(config, url) { const giteaUrl = parseGiteaUrl(config, url); return `${giteaUrl.url}/api/v1/repos/${giteaUrl.owner}/${giteaUrl.name}/contents/${giteaUrl.path}?ref=${giteaUrl.ref}`; } function getGiteaArchiveUrl(config, url) { const giteaUrl = parseGiteaUrl(config, url); return `${giteaUrl.url}/api/v1/repos/${giteaUrl.owner}/${giteaUrl.name}/archive/${giteaUrl.ref}.tar.gz`; } function getGiteaLatestCommitUrl(config, url) { const giteaUrl = parseGiteaUrl(config, url); return `${giteaUrl.url}/api/v1/repos/${giteaUrl.owner}/${giteaUrl.name}/git/commits/${giteaUrl.ref}`; } function getGiteaRequestOptions(config) { const headers = {}; const { username, password } = config; if (!password) { return headers; } if (username) { headers.Authorization = `basic ${Buffer.from( `${username}:${password}` ).toString("base64")}`; } else { headers.Authorization = `token ${password}`; } return { headers }; } function parseGiteaUrl(config, url) { var _a; const baseUrl = (_a = config.baseUrl) != null ? _a : `https://${config.host}`; try { const [_blank, owner, name, _src, _branch, ref, ...path] = url.replace(baseUrl, "").split("/"); const pathWithoutSlash = path.join("/").replace(/^\//, ""); return { url: baseUrl, owner, name, ref, path: pathWithoutSlash }; } catch (e) { throw new Error(`Incorrect URL: ${url}, ${e}`); } } var __defProp$6 = Object.defineProperty; var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$6 = (obj, key, value) => { __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; const _GiteaIntegration = class _GiteaIntegration { constructor(config) { this.config = config; } get type() { return "gitea"; } get title() { return this.config.host; } resolveUrl(options) { return defaultScmResolveUrl(options); } resolveEditUrl(url) { return getGiteaEditContentsUrl(this.config, url); } }; __publicField$6(_GiteaIntegration, "factory", ({ config }) => { var _a; const configs = (_a = config.getOptionalConfigArray("integrations.gitea")) != null ? _a : []; const giteaConfigs = configs.map((c) => readGiteaConfig(c)); return basicIntegrations( giteaConfigs.map((c) => new _GiteaIntegration(c)), (gitea) => gitea.config.host ); }); let GiteaIntegration = _GiteaIntegration; const GITHUB_HOST = "github.com"; const GITHUB_API_BASE_URL = "https://api.github.com"; const GITHUB_RAW_BASE_URL = "https://raw.githubusercontent.com"; function readGithubIntegrationConfig(config) { var _a, _b, _c; const host = (_a = config.getOptionalString("host")) != null ? _a : GITHUB_HOST; let apiBaseUrl = config.getOptionalString("apiBaseUrl"); let rawBaseUrl = config.getOptionalString("rawBaseUrl"); const token = (_b = config.getOptionalString("token")) == null ? void 0 : _b.trim(); const apps = (_c = config.getOptionalConfigArray("apps")) == null ? void 0 : _c.map((c) => ({ appId: c.getNumber("appId"), clientId: c.getString("clientId"), clientSecret: c.getString("clientSecret"), webhookSecret: c.getString("webhookSecret"), privateKey: c.getString("privateKey"), allowedInstallationOwners: c.getOptionalStringArray( "allowedInstallationOwners" ) })); if (!isValidHost(host)) { throw new Error( `Invalid GitHub integration config, '${host}' is not a valid host` ); } if (apiBaseUrl) { apiBaseUrl = lodash.trimEnd(apiBaseUrl, "/"); } else if (host === GITHUB_HOST) { apiBaseUrl = GITHUB_API_BASE_URL; } if (rawBaseUrl) { rawBaseUrl = lodash.trimEnd(rawBaseUrl, "/"); } else if (host === GITHUB_HOST) { rawBaseUrl = GITHUB_RAW_BASE_URL; } return { host, apiBaseUrl, rawBaseUrl, token, apps }; } function readGithubIntegrationConfigs(configs) { const result = configs.map(readGithubIntegrationConfig); if (!result.some((c) => c.host === GITHUB_HOST)) { result.push({ host: GITHUB_HOST, apiBaseUrl: GITHUB_API_BASE_URL, rawBaseUrl: GITHUB_RAW_BASE_URL }); } return result; } function getGithubFileFetchUrl(url, config, credentials) { try { const { owner, name, ref, filepathtype, filepath } = parseGitUrl__default.default(url); if (!owner || !name || !ref || // GitHub is automatically redirecting tree urls to blob urls so it's // fine to pass a tree url. filepathtype !== "blob" && filepathtype !== "raw" && filepathtype !== "tree") { throw new Error("Invalid GitHub URL or file path"); } const pathWithoutSlash = filepath.replace(/^\//, ""); if (chooseEndpoint(config, credentials) === "api") { return `${config.apiBaseUrl}/repos/${owner}/${name}/contents/${pathWithoutSlash}?ref=${ref}`; } return `${config.rawBaseUrl}/${owner}/${name}/${ref}/${pathWithoutSlash}`; } catch (e) { throw new Error(`Incorrect URL: ${url}, ${e}`); } } function getGitHubRequestOptions(config, credentials) { const headers = {}; if (chooseEndpoint(config, credentials) === "api") { headers.Accept = "application/vnd.github.v3.raw"; } if (credentials.token) { headers.Authorization = `token ${credentials.token}`; } return { headers }; } function chooseEndpoint(config, credentials) { if (config.apiBaseUrl && (credentials.token || !config.rawBaseUrl)) { return "api"; } return "raw"; } var __defProp$5 = Object.defineProperty; var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$5 = (obj, key, value) => { __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; class Cache { constructor() { __publicField$5(this, "tokenCache", /* @__PURE__ */ new Map()); __publicField$5(this, "isExpired", (date) => luxon.DateTime.local() > date); } async getOrCreateToken(owner, repo, supplier) { let existingInstallationData = this.tokenCache.get(owner); if (!existingInstallationData || this.isExpired(existingInstallationData.expiresAt)) { existingInstallationData = await supplier(); existingInstallationData.expiresAt = existingInstallationData.expiresAt.minus({ minutes: 10 }); this.tokenCache.set(owner, existingInstallationData); } if (!this.appliesToRepo(existingInstallationData, repo)) { throw new Error( `The Backstage GitHub application used in the ${owner} organization does not have access to a repository with the name ${repo}` ); } return { accessToken: existingInstallationData.token }; } appliesToRepo(tokenData, repo) { if (repo === void 0) { return true; } if (tokenData.repositories !== void 0) { return tokenData.repositories.includes(repo); } return true; } } const HEADERS = { Accept: "application/vnd.github.machine-man-preview+json" }; class GithubAppManager { // undefined allows all installations constructor(config, baseUrl) { __publicField$5(this, "appClient"); __publicField$5(this, "baseUrl"); __publicField$5(this, "baseAuthConfig"); __publicField$5(this, "cache", new Cache()); __publicField$5(this, "allowedInstallationOwners"); this.allowedInstallationOwners = config.allowedInstallationOwners; this.baseUrl = baseUrl; this.baseAuthConfig = { appId: config.appId, privateKey: config.privateKey.replace(/\\n/gm, "\n") }; this.appClient = new rest.Octokit({ baseUrl, headers: HEADERS, authStrategy: authApp.createAppAuth, auth: this.baseAuthConfig }); } async getInstallationCredentials(owner, repo) { var _a; if (this.allowedInstallationOwners) { if (!((_a = this.allowedInstallationOwners) == null ? void 0 : _a.includes(owner))) { return { accessToken: void 0 }; } } return this.cache.getOrCreateToken(owner, repo, async () => { var _a2; const { installationId, suspended } = await this.getInstallationData( owner ); if (suspended) { throw new Error(`The GitHub application for ${owner} is suspended`); } const result = await this.appClient.apps.createInstallationAccessToken({ installation_id: installationId, headers: HEADERS }); let repositoryNames; if (result.data.repository_selection === "selected") { const installationClient = new rest.Octokit({ baseUrl: this.baseUrl, auth: result.data.token }); const repos = await installationClient.paginate( installationClient.apps.listReposAccessibleToInstallation ); const repositories = (_a2 = repos.repositories) != null ? _a2 : repos; repositoryNames = repositories.map((repository) => repository.name); } return { token: result.data.token, expiresAt: luxon.DateTime.fromISO(result.data.expires_at), repositories: repositoryNames }; }); } getInstallations() { return this.appClient.paginate(this.appClient.apps.listInstallations); } async getInstallationData(owner) { const allInstallations = await this.getInstallations(); const installation = allInstallations.find( (inst) => { var _a; return inst.account && "login" in inst.account && ((_a = inst.account.login) == null ? void 0 : _a.toLocaleLowerCase("en-US")) === owner.toLocaleLowerCase("en-US"); } ); if (installation) { return { installationId: installation.id, suspended: Boolean(installation.suspended_by) }; } const notFoundError = new Error( `No app installation found for ${owner} in ${this.baseAuthConfig.appId}` ); notFoundError.name = "NotFoundError"; throw notFoundError; } } class GithubAppCredentialsMux { constructor(config) { __publicField$5(this, "apps"); var _a, _b; this.apps = (_b = (_a = config.apps) == null ? void 0 : _a.map((ac) => new GithubAppManager(ac, config.apiBaseUrl))) != null ? _b : []; } async getAllInstallations() { if (!this.apps.length) { return []; } const installs = await Promise.all( this.apps.map((app) => app.getInstallations()) ); return installs.flat(); } async getAppToken(owner, repo) { if (this.apps.length === 0) { return void 0; } const results = await Promise.all( this.apps.map( (app) => app.getInstallationCredentials(owner, repo).then( (credentials) => ({ credentials, error: void 0 }), (error) => ({ credentials: void 0, error }) ) ) ); const result = results.find( (resultItem) => { var _a; return (_a = resultItem.credentials) == null ? void 0 : _a.accessToken; } ); if (result) { return result.credentials.accessToken; } const errors = results.map((r) => r.error); const notNotFoundError = errors.find((err) => (err == null ? void 0 : err.name) !== "NotFoundError"); if (notNotFoundError) { throw notNotFoundError; } return void 0; } } const _SingleInstanceGithubCredentialsProvider = class _SingleInstanceGithubCredentialsProvider { constructor(githubAppCredentialsMux, token) { this.githubAppCredentialsMux = githubAppCredentialsMux; this.token = token; } /** * Returns {@link GithubCredentials} for a given URL. * * @remarks * * Consecutive calls to this method with the same URL will return cached * credentials. * * The shortest lifetime for a token returned is 10 minutes. * * @example * ```ts * const { token, headers } = await getCredentials({ * url: 'github.com/backstage/foobar' * }) * ``` * * @param opts - The organization or repository URL * @returns A promise of {@link GithubCredentials}. */ async getCredentials(opts) { const parsed = parseGitUrl__default.default(opts.url); const owner = parsed.owner || parsed.name; const repo = parsed.owner ? parsed.name : void 0; let type = "app"; let token = await this.githubAppCredentialsMux.getAppToken(owner, repo); if (!token) { type = "token"; token = this.token; } return { headers: token ? { Authorization: `Bearer ${token}` } : void 0, token, type }; } }; __publicField$5(_SingleInstanceGithubCredentialsProvider, "create", (config) => { return new _SingleInstanceGithubCredentialsProvider( new GithubAppCredentialsMux(config), config.token ); }); let SingleInstanceGithubCredentialsProvider = _SingleInstanceGithubCredentialsProvider; class DefaultGithubCredentialsProvider { constructor(providers) { this.providers = providers; } static fromIntegrations(integrations) { const credentialsProviders = /* @__PURE__ */ new Map(); integrations.github.list().forEach((integration) => { const credentialsProvider = SingleInstanceGithubCredentialsProvider.create(integration.config); credentialsProviders.set(integration.config.host, credentialsProvider); }); return new DefaultGithubCredentialsProvider(credentialsProviders); } /** * Returns {@link GithubCredentials} for a given URL. * * @remarks * * Consecutive calls to this method with the same URL will return cached * credentials. * * The shortest lifetime for a token returned is 10 minutes. * * @example * ```ts * const { token, headers } = await getCredentials({ * url: 'https://github.com/backstage/foobar' * }) * * const { token, headers } = await getCredentials({ * url: 'https://github.com/backstage' * }) * ``` * * @param opts - The organization or repository URL * @returns A promise of {@link GithubCredentials}. */ async getCredentials(opts) { const parsed = new URL(opts.url); const provider = this.providers.get(parsed.host); if (!provider) { throw new Error( `There is no GitHub integration that matches ${opts.url}. Please add a configuration for an integration.` ); } return provider.getCredentials(opts); } } var __defProp$4 = Object.defineProperty; var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$4 = (obj, key, value) => { __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; const _GithubIntegration = class _GithubIntegration { constructor(integrationConfig) { this.integrationConfig = integrationConfig; } get type() { return "github"; } get title() { return this.integrationConfig.host; } get config() { return this.integrationConfig; } resolveUrl(options) { return replaceGithubUrlType(defaultScmResolveUrl(options), "tree"); } resolveEditUrl(url) { return replaceGithubUrlType(url, "edit"); } parseRateLimitInfo(response) { return { isRateLimited: response.status === 429 || response.status === 403 && response.headers.get("x-ratelimit-remaining") === "0" }; } }; __publicField$4(_GithubIntegration, "factory", ({ config }) => { var _a; const configs = readGithubIntegrationConfigs( (_a = config.getOptionalConfigArray("integrations.github")) != null ? _a : [] ); return basicIntegrations( configs.map((c) => new _GithubIntegration(c)), (i) => i.config.host ); }); let GithubIntegration = _GithubIntegration; function replaceGithubUrlType(url, type) { return url.replace( /\/\/([^/]+)\/([^/]+)\/([^/]+)\/(blob|tree|edit)\//, (_, host, owner, repo) => { return `//${host}/${owner}/${repo}/${type}/`; } ); } var __defProp$3 = Object.defineProperty; var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$3 = (obj, key, value) => { __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; const getGitHubFileFetchUrl = getGithubFileFetchUrl; class GitHubIntegration extends GithubIntegration { constructor(integrationConfig) { super(integrationConfig); } get config() { return super.config; } } __publicField$3(GitHubIntegration, "factory", GithubIntegration.factory); const readGitHubIntegrationConfig = readGithubIntegrationConfig; const readGitHubIntegrationConfigs = readGithubIntegrationConfigs; const replaceGitHubUrlType = replaceGithubUrlType; const GITLAB_HOST = "gitlab.com"; const GITLAB_API_BASE_URL = "https://gitlab.com/api/v4"; function readGitLabIntegrationConfig(config) { var _a; const host = config.getString("host"); let apiBaseUrl = config.getOptionalString("apiBaseUrl"); const token = (_a = config.getOptionalString("token")) == null ? void 0 : _a.trim(); let baseUrl = config.getOptionalString("baseUrl"); if (apiBaseUrl) { apiBaseUrl = lodash.trimEnd(apiBaseUrl, "/"); } else if (host === GITLAB_HOST) { apiBaseUrl = GITLAB_API_BASE_URL; } if (baseUrl) { baseUrl = lodash.trimEnd(baseUrl, "/"); } else { baseUrl = `https://${host}`; } if (!isValidHost(host)) { throw new Error( `Invalid GitLab integration config, '${host}' is not a valid host` ); } else if (!apiBaseUrl || !isValidUrl(apiBaseUrl)) { throw new Error( `Invalid GitLab integration config, '${apiBaseUrl}' is not a valid apiBaseUrl` ); } else if (!isValidUrl(baseUrl)) { throw new Error( `Invalid GitLab integration config, '${baseUrl}' is not a valid baseUrl` ); } return { host, token, apiBaseUrl, baseUrl }; } function readGitLabIntegrationConfigs(configs) { const result = configs.map(readGitLabIntegrationConfig); if (!result.some((c) => c.host === GITLAB_HOST)) { result.push({ host: GITLAB_HOST, apiBaseUrl: GITLAB_API_BASE_URL, baseUrl: `https://${GITLAB_HOST}` }); } return result; } function getGitLabIntegrationRelativePath(config) { let relativePath = ""; if (config.host !== GITLAB_HOST) { relativePath = new URL(config.baseUrl).pathname; } return lodash.trimEnd(relativePath, "/"); } async function getGitLabFileFetchUrl(url, config) { const projectID = await getProjectId(url, config); return buildProjectUrl(url, projectID, config).toString(); } function getGitLabRequestOptions(config) { const { token = "" } = config; return { headers: { "PRIVATE-TOKEN": token } }; } function buildProjectUrl(target, projectID, config) { try { const url = new URL(target); const branchAndFilePath = url.pathname.split("/blob/").slice(1).join("/blob/"); const [branch, ...filePath] = branchAndFilePath.split("/"); const relativePath = getGitLabIntegrationRelativePath(config); url.pathname = [ ...relativePath ? [relativePath] : [], "api/v4/projects", projectID, "repository/files", encodeURIComponent(decodeURIComponent(filePath.join("/"))), "raw" ].join("/"); url.search = `?ref=${branch}`; return url; } catch (e) { throw new Error(`Incorrect url: ${target}, ${e}`); } } async function getProjectId(target, config) { const url = new URL(target); if (!url.pathname.includes("/blob/")) { throw new Error("Please provide full path to yaml file from GitLab"); } try { let repo = url.pathname.split("/-/blob/")[0].split("/blob/")[0]; const relativePath = getGitLabIntegrationRelativePath(config); if (relativePath) { repo = repo.replace(relativePath, ""); } const repoIDLookup = new URL( `${url.origin}${relativePath}/api/v4/projects/${encodeURIComponent( repo.replace(/^\//, "") )}` ); const response = await fetch__default.default( repoIDLookup.toString(), getGitLabRequestOptions(config) ); const data = await response.json(); if (!response.ok) { throw new Error( `GitLab Error '${data.error}', ${data.error_description}` ); } return Number(data.id); } catch (e) { throw new Error(`Could not get GitLab project ID for: ${target}, ${e}`); } } var __defProp$2 = Object.defineProperty; var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$2 = (obj, key, value) => { __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; const _GitLabIntegration = class _GitLabIntegration { constructor(integrationConfig) { this.integrationConfig = integrationConfig; } get type() { return "gitlab"; } get title() { return this.integrationConfig.host; } get config() { return this.integrationConfig; } resolveUrl(options) { return defaultScmResolveUrl(options); } resolveEditUrl(url) { return replaceGitLabUrlType(url, "edit"); } }; __publicField$2(_GitLabIntegration, "factory", ({ config }) => { var _a; const configs = readGitLabIntegrationConfigs( (_a = config.getOptionalConfigArray("integrations.gitlab")) != null ? _a : [] ); return basicIntegrations( configs.map((c) => new _GitLabIntegration(c)), (i) => i.config.host ); }); let GitLabIntegration = _GitLabIntegration; function replaceGitLabUrlType(url, type) { return url.replace(/\/\-\/(blob|tree|edit)\//, `/-/${type}/`); } var __defProp$1 = Object.defineProperty; var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$1 = (obj, key, value) => { __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; const _SingleInstanceGitlabCredentialsProvider = class _SingleInstanceGitlabCredentialsProvider { constructor(token) { this.token = token; } async getCredentials(_opts) { if (!this.token) { return {}; } return { headers: { Authorization: `Bearer ${this.token}` }, token: this.token }; } }; __publicField$1(_SingleInstanceGitlabCredentialsProvider, "create", (config) => { return new _SingleInstanceGitlabCredentialsProvider(config.token); }); let SingleInstanceGitlabCredentialsProvider = _SingleInstanceGitlabCredentialsProvider; class DefaultGitlabCredentialsProvider { constructor(providers) { this.providers = providers; } static fromIntegrations(integrations) { const credentialsProviders = /* @__PURE__ */ new Map(); integrations.gitlab.list().forEach((integration) => { const credentialsProvider = SingleInstanceGitlabCredentialsProvider.create(integration.config); credentialsProviders.set(integration.config.host, credentialsProvider); }); return new DefaultGitlabCredentialsProvider(credentialsProviders); } async getCredentials(opts) { const parsed = new URL(opts.url); const provider = this.providers.get(parsed.host); if (!provider) { throw new Error( `There is no GitLab integration that matches ${opts.url}. Please add a configuration for an integration.` ); } return provider.getCredentials(opts); } } function readGoogleGcsIntegrationConfig(config) { if (!config) { return {}; } if (!config.has("clientEmail") && !config.has("privateKey")) { return {}; } const privateKey = config.getString("privateKey").split("\\n").join("\n"); const clientEmail = config.getString("clientEmail"); return { clientEmail, privateKey }; } var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; class ScmIntegrations { constructor(integrationsByType) { __publicField(this, "byType"); this.byType = integrationsByType; } static fromConfig(config) { return new ScmIntegrations({ awsS3: AwsS3Integration.factory({ config }), awsCodeCommit: AwsCodeCommitIntegration.factory({ config }), azure: AzureIntegration.factory({ config }), bitbucket: BitbucketIntegration.factory({ config }), bitbucketCloud: BitbucketCloudIntegration.factory({ config }), bitbucketServer: BitbucketServerIntegration.factory({ config }), gerrit: GerritIntegration.factory({ config }), github: GithubIntegration.factory({ config }), gitlab: GitLabIntegration.factory({ config }), gitea: GiteaIntegration.factory({ config }) }); } get awsS3() { return this.byType.awsS3; } get awsCodeCommit() { return this.byType.awsCodeCommit; } get azure() { return this.byType.azure; } /** * @deprecated in favor of `bitbucketCloud()` and `bitbucketServer()` */ get bitbucket() { return this.byType.bitbucket; } get bitbucketCloud() { return this.byType.bitbucketCloud; } get bitbucketServer() { return this.byType.bitbucketServer; } get gerrit() { return this.byType.gerrit; } get github() { return this.byType.github; } get gitlab() { return this.byType.gitlab; } get gitea() { return this.byType.gitea; } list() { return Object.values(this.byType).flatMap( (i) => i.list() ); } byUrl(url) { let candidates = Object.values(this.byType).map((i) => i.byUrl(url)).filter(Boolean); if (candidates.length > 1) { const filteredCandidates = candidates.filter( (x) => !(x instanceof BitbucketIntegration) ); if (filteredCandidates.length !== 0) { candidates = filteredCandidates; } } return candidates[0]; } byHost(host) { return Object.values(this.byType).map((i) => i.byHost(host)).find(Boolean); } resolveUrl(options) { const integration = this.byUrl(options.base); if (!integration) { return defaultScmResolveUrl(options); } return integration.resolveUrl(options); } resolveEditUrl(url) { const integration = this.byUrl(url); if (!integration) { return url; } return integration.resolveEditUrl(url); } } exports.AwsCodeCommitIntegration = AwsCodeCommitIntegration; exports.AwsS3Integration = AwsS3Integration; exports.AzureIntegration = AzureIntegration; exports.BitbucketCloudIntegration = BitbucketCloudIntegration; exports.BitbucketIntegration = BitbucketIntegration; exports.BitbucketServerIntegration = BitbucketServerIntegration; exports.DefaultAzureDevOpsCredentialsProvider = DefaultAzureDevOpsCredentialsProvider; exports.DefaultGithubCredentialsProvider = DefaultGithubCredentialsProvider; exports.DefaultGitlabCredentialsProvider = DefaultGitlabCredentialsProvider; exports.GerritIntegration = GerritIntegration; exports.GitHubIntegration = GitHubIntegration; exports.GitLabIntegration = GitLabIntegration; exports.GiteaIntegration = GiteaIntegration; exports.GithubAppCredentialsMux = GithubAppCredentialsMux; exports.GithubIntegration = GithubIntegration; exports.ScmIntegrations = ScmIntegrations; exports.SingleInstanceGithubCredentialsProvider = SingleInstanceGithubCredentialsProvider; exports.buildGerritGitilesArchiveUrl = buildGerritGitilesArchiveUrl; exports.defaultScmResolveUrl = defaultScmResolveUrl; exports.getAzureCommitsUrl = getAzureCommitsUrl; exports.getAzureDownloadUrl = getAzureDownloadUrl; exports.getAzureFileFetchUrl = getAzureFileFetchUrl; exports.getAzureRequestOptions = getAzureRequestOptions; exports.getBitbucketCloudDefaultBranch = getBitbucketCloudDefaultBranch; exports.getBitbucketCloudDownloadUrl = getBitbucketCloudDownloadUrl; exports.getBitbucketCloudFileFetchUrl = getBitbucketCloudFileFetchUrl; exports.getBitbucketCloudRequestOptions = getBitbucketCloudRequestOptions; exports.getBitbucketDefaultBranch = getBitbucketDefaultBranch; exports.getBitbucketDownloadUrl = getBitbucketDownloadUrl; exports.getBitbucketFileFetchUrl = getBitbucketFileFetchUrl; exports.getBitbucketRequestOptions = getBitbucketRequestOptions; exports.getBitbucketServerDefaultBranch = getBitbucketServerDefaultBranch; exports.getBitbucketServerDownloadUrl = getBitbucketServerDownloadUrl; exports.getBitbucketServerFileFetchUrl = getBitbucketServerFileFetchUrl; exports.getBitbucketServerRequestOptions = getBitbucketServerRequestOptions; exports.getGerritBranchApiUrl = getGerritBranchApiUrl; exports.getGerritCloneRepoUrl = getGerritCloneRepoUrl; exports.getGerritFileContentsApiUrl = getGerritFileContentsApiUrl; exports.getGerritProjectsApiUrl = getGerritProjectsApiUrl; exports.getGerritRequestOptions = getGerritRequestOptions; exports.getGitHubFileFetchUrl = getGitHubFileFetchUrl; exports.getGitHubRequestOptions = getGitHubRequestOptions; exports.getGitLabFileFetchUrl = getGitLabFileFetchUrl; exports.getGitLabIntegrationRelativePath = getGitLabIntegrationRelativePath; exports.getGitLabRequestOptions = getGitLabRequestOptions; exports.getGiteaArchiveUrl = getGiteaArchiveUrl; exports.getGiteaEditContentsUrl = getGiteaEditContentsUrl; exports.getGiteaFileContentsUrl = getGiteaFileContentsUrl; exports.getGiteaLatestCommitUrl = getGiteaLatestCommitUrl; exports.getGiteaRequestOptions = getGiteaRequestOptions; exports.getGithubFileFetchUrl = getGithubFileFetchUrl; exports.parseGerritGitilesUrl = parseGerritGitilesUrl; exports.parseGerritJsonResponse = parseGerritJsonResponse; exports.parseGiteaUrl = parseGiteaUrl; exports.readAwsCodeCommitIntegrationConfig = readAwsCodeCommitIntegrationConfig; exports.readAwsCodeCommitIntegrationConfigs = readAwsCodeCommitIntegrationConfigs; exports.readAwsS3IntegrationConfig = readAwsS3IntegrationConfig; exports.readAwsS3IntegrationConfigs = readAwsS3IntegrationConfigs; exports.readAzureIntegrationConfig = readAzureIntegrationConfig; exports.readAzureIntegrationConfigs = readAzureIntegrationConfigs; exports.readBitbucketCloudIntegrationConfig = readBitbucketCloudIntegrationConfig; exports.readBitbucketCloudIntegrationConfigs = readBitbucketCloudIntegrationConfigs; exports.readBitbucketIntegrationConfig = readBitbucketIntegrationConfig; exports.readBitbucketIntegrationConfigs = readBitbucketIntegrationConfigs; exports.readBitbucketServerIntegrationConfig = readBitbucketServerIntegrationConfig; exports.readBitbucketServerIntegrationConfigs = readBitbucketServerIntegrationConfigs; exports.readGerritIntegrationConfig = readGerritIntegrationConfig; exports.readGerritIntegrationConfigs = readGerritIntegrationConfigs; exports.readGitHubIntegrationConfig = readGitHubIntegrationConfig; exports.readGitHubIntegrationConfigs = readGitHubIntegrationConfigs; exports.readGitLabIntegrationConfig = readGitLabIntegrationConfig; exports.readGitLabIntegrationConfigs = readGitLabIntegrationConfigs; exports.readGiteaConfig = readGiteaConfig; exports.readGithubIntegrationConfig = readGithubIntegrationConfig; exports.readGithubIntegrationConfigs = readGithubIntegrationConfigs; exports.readGoogleGcsIntegrationConfig = readGoogleGcsIntegrationConfig; exports.replaceGitHubUrlType = replaceGitHubUrlType; exports.replaceGitLabUrlType = replaceGitLabUrlType; exports.replaceGithubUrlType = replaceGithubUrlType; //# sourceMappingURL=index.cjs.js.map