UNPKG

@backstage/integration

Version:

Helpers for managing integrations towards external systems

84 lines (81 loc) 2.03 kB
import parseGitUrl from 'git-url-parse'; import { trimEnd } from 'lodash'; function parseGitUrlSafe(url) { const parsed = parseGitUrl(url); if (parsed.filepath) { let decoded = parsed.filepath; let previous; do { previous = decoded; try { decoded = decodeURIComponent(decoded); } catch { break; } } while (decoded !== previous); if (decoded.split("/").some((segment) => segment === ".." || segment === ".")) { throw new Error( "Invalid SCM URL: path traversal is not allowed in the URL" ); } } return parsed; } 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 } = parseGitUrlSafe(base); updated = new URL(href); const repoRootPath = 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(); } export { basicIntegrations, defaultScmResolveUrl, isValidHost, isValidUrl, parseGitUrlSafe }; //# sourceMappingURL=helpers.esm.js.map