renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
115 lines (114 loc) • 4.26 kB
JavaScript
import "../../../constants/error-messages.js";
import { logger } from "../../../logger/index.js";
import { getQueryString, joinUrlParts } from "../../../util/url.js";
import { ExternalHostError } from "../../../types/errors/external-host-error.js";
import { withCache } from "../../../util/cache/package/with-cache.js";
import { Datasource } from "../datasource.js";
import { RepologyPackages } from "./schema.js";
import { isNonEmptyArray } from "@sindresorhus/is";
//#region lib/modules/datasource/repology/index.ts
const packageTypes = ["binname", "srcname"];
function findPackageInResponse(response, repoName, pkgName, types) {
const repoPackages = response.filter((pkg) => pkg.repo === repoName);
if (repoPackages.length === 0) return null;
if (repoPackages.length === 1) return repoPackages;
const packagesWithType = repoPackages.filter((pkg) => {
for (const pkgType of types) if (pkg[pkgType] && pkg[pkgType] === pkgName) return true;
return false;
});
return packagesWithType.length > 0 ? packagesWithType : null;
}
var RepologyDatasource = class RepologyDatasource extends Datasource {
static id = "repology";
defaultRegistryUrls = ["https://repology.org/"];
registryStrategy = "hunt";
constructor() {
super(RepologyDatasource.id);
}
async queryPackages(url) {
try {
return (await this.http.getJson(url, RepologyPackages)).body;
} catch (err) {
if (err.statusCode === 404) return [];
throw err;
}
}
async queryPackagesViaResolver(registryUrl, repoName, packageName, packageType) {
const query = getQueryString({
repo: repoName,
name_type: packageType,
target_page: "api_v1_project",
noautoresolve: "on",
name: packageName
});
return await this.queryPackages(joinUrlParts(registryUrl, `tools/project-by?${query}`));
}
async queryPackagesViaAPI(registryUrl, packageName) {
return await this.queryPackages(joinUrlParts(registryUrl, `api/v1/project`, packageName));
}
async _queryPackage(registryUrl, repoName, pkgName) {
let response;
try {
for (const pkgType of packageTypes) {
response = await this.queryPackagesViaResolver(registryUrl, repoName, pkgName, pkgType);
if (response) {
const pkg = findPackageInResponse(response, repoName, pkgName, [pkgType]);
if (isNonEmptyArray(pkg)) return pkg;
}
}
} catch (err) {
if (err.statusCode === 403) {
logger.debug({
repoName,
pkgName
}, "Repology does not support tools/project-by lookups for repository. Will try direct API access now");
response = await this.queryPackagesViaAPI(registryUrl, pkgName);
const pkg = findPackageInResponse(response, repoName, pkgName, packageTypes);
if (isNonEmptyArray(pkg)) return pkg;
} else if (err.statusCode === 300) {
logger.warn({
repoName,
pkgName
}, "Ambiguous redirection from package name to project name in Repology. Skipping this package");
return;
}
throw err;
}
logger.debug({
repoName,
pkgName
}, "Repository or package not found on Repology");
}
queryPackage(registryUrl, repoName, pkgName) {
return withCache({
ttlMinutes: 60,
namespace: `datasource-${RepologyDatasource.id}`,
key: joinUrlParts(registryUrl, repoName, pkgName)
}, () => this._queryPackage(registryUrl, repoName, pkgName));
}
async getReleases({ packageName, registryUrl }) {
/* v8 ignore next 3 -- should never happen */
if (!registryUrl) return null;
const [repoName, pkgName] = packageName.split("/", 2);
if (!repoName || !pkgName) throw new ExternalHostError(/* @__PURE__ */ new Error("Repology lookup name must contain repository and package separated by slash (<repo>/<pkg>)"));
logger.trace(`repology.getReleases(${repoName}, ${pkgName})`);
try {
const pkg = await this.queryPackage(registryUrl, repoName, pkgName);
if (!pkg) return null;
return { releases: pkg.map((item) => ({ version: item.origversion ?? item.version })) };
} catch (err) {
if (err.message === "host-disabled") logger.trace({
packageName,
err
}, "Host disabled");
else logger.warn({
packageName,
err
}, "Repology lookup failed with unexpected error");
throw new ExternalHostError(err);
}
}
};
//#endregion
export { RepologyDatasource };
//# sourceMappingURL=index.js.map