renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
178 lines • 5.87 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.migrateRule = migrateRule;
exports.add = add;
exports.matchesHost = matchesHost;
exports.find = find;
exports.hosts = hosts;
exports.hostType = hostType;
exports.findAll = findAll;
exports.getAll = getAll;
exports.clear = clear;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const logger_1 = require("../logger");
const clone_1 = require("./clone");
const sanitize = tslib_1.__importStar(require("./sanitize"));
const string_1 = require("./string");
const url_1 = require("./url");
let hostRules = [];
function migrateRule(rule) {
const cloned = (0, clone_1.clone)(rule);
delete cloned.hostName;
delete cloned.domainName;
delete cloned.baseUrl;
const result = cloned;
const { matchHost } = result;
const { hostName, domainName, baseUrl } = rule;
const hostValues = [matchHost, hostName, domainName, baseUrl].filter(Boolean);
if (hostValues.length === 1) {
const [matchHost] = hostValues;
result.matchHost = matchHost;
}
else if (hostValues.length > 1) {
throw new Error(`hostRules cannot contain more than one host-matching field - use "matchHost" only.`);
}
return result;
}
function add(params) {
const rule = migrateRule(params);
const confidentialFields = ['password', 'token'];
if (rule.matchHost) {
rule.matchHost = (0, url_1.massageHostUrl)(rule.matchHost);
const parsedUrl = (0, url_1.parseUrl)(rule.matchHost);
rule.resolvedHost = parsedUrl?.hostname ?? rule.matchHost;
confidentialFields.forEach((field) => {
if (rule[field]) {
logger_1.logger.debug(
// TODO: types (#22198)
`Adding ${field} authentication for ${rule.matchHost} (hostType=${rule.hostType}) to hostRules`);
}
});
}
confidentialFields.forEach((field) => {
const secret = rule[field];
if (is_1.default.string(secret) && secret.length > 3) {
sanitize.addSecretForSanitizing(secret);
}
});
if (rule.username && rule.password) {
sanitize.addSecretForSanitizing((0, string_1.toBase64)(`${rule.username}:${rule.password}`));
}
hostRules.push(rule);
}
function matchesHost(url, matchHost) {
const parsedUrl = (0, url_1.parseUrl)(url);
if (!parsedUrl) {
return false;
}
const parsedMatchHost = (0, url_1.parseUrl)(matchHost);
if ((0, url_1.isHttpUrl)(parsedUrl) && (0, url_1.isHttpUrl)(parsedMatchHost)) {
return parsedUrl.href.startsWith(parsedMatchHost.href);
}
const { hostname } = parsedUrl;
if (!hostname) {
return false;
}
if (hostname === matchHost) {
return true;
}
const topLevelSuffix = matchHost.startsWith('.')
? matchHost
: `.${matchHost}`;
return hostname.endsWith(topLevelSuffix);
}
function fromShorterToLongerMatchHost(a, b) {
if (!a.matchHost || !b.matchHost) {
return 0;
}
return a.matchHost.length - b.matchHost.length;
}
function hostRuleRank({ hostType, matchHost, readOnly }) {
if ((hostType || readOnly) && matchHost) {
return 3;
}
if (matchHost) {
return 2;
}
if (hostType) {
return 1;
}
return 0;
}
function fromLowerToHigherRank(a, b) {
return hostRuleRank(a) - hostRuleRank(b);
}
function find(search) {
if ([search.hostType, search.url].every(is_1.default.falsy)) {
logger_1.logger.warn({ search }, 'Invalid hostRules search');
return {};
}
// Sort primarily by rank, and secondarily by matchHost length
const sortedRules = hostRules
.sort(fromShorterToLongerMatchHost)
.sort(fromLowerToHigherRank);
const matchedRules = [];
for (const rule of sortedRules) {
let hostTypeMatch = true;
let hostMatch = true;
let readOnlyMatch = true;
if (rule.hostType) {
hostTypeMatch = false;
if (search.hostType === rule.hostType) {
hostTypeMatch = true;
}
}
if (rule.matchHost && rule.resolvedHost) {
hostMatch = false;
if (search.url) {
hostMatch = matchesHost(search.url, rule.matchHost);
}
}
if (!is_1.default.undefined(rule.readOnly)) {
readOnlyMatch = false;
if (search.readOnly === rule.readOnly) {
readOnlyMatch = true;
hostTypeMatch = true; // When we match `readOnly`, we don't care about `hostType`
}
}
if (hostTypeMatch && readOnlyMatch && hostMatch) {
matchedRules.push((0, clone_1.clone)(rule));
}
}
const res = Object.assign({}, ...matchedRules);
delete res.hostType;
delete res.resolvedHost;
delete res.matchHost;
delete res.readOnly;
return res;
}
function hosts({ hostType }) {
return hostRules
.filter((rule) => rule.hostType === hostType)
.map((rule) => rule.resolvedHost)
.filter(is_1.default.truthy);
}
function hostType({ url }) {
return (hostRules
.filter((rule) => rule.matchHost && matchesHost(url, rule.matchHost))
.sort(fromShorterToLongerMatchHost)
.map((rule) => rule.hostType)
.filter(is_1.default.truthy)
.pop() ?? null);
}
function findAll({ hostType }) {
return hostRules.filter((rule) => rule.hostType === hostType);
}
/**
* @returns a deep copy of all known host rules without any filtering
*/
function getAll() {
return (0, clone_1.clone)(hostRules);
}
function clear() {
logger_1.logger.debug('Clearing hostRules');
hostRules = [];
sanitize.clearRepoSanitizedSecretsList();
}
//# sourceMappingURL=host-rules.js.map