renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
71 lines • 3.15 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MetadataCache = void 0;
const tslib_1 = require("tslib");
const logger_1 = require("../../../logger");
const packageCache = tslib_1.__importStar(require("../../../util/cache/package"));
const hash_1 = require("../../../util/hash");
const result_1 = require("../../../util/result");
const url_1 = require("../../../util/url");
const common_1 = require("./common");
function hashVersions(versions) {
return (0, hash_1.toSha256)(versions.sort().join(','));
}
function hashReleases(releases) {
return hashVersions(releases.releases.map((release) => release.version));
}
class MetadataCache {
http;
constructor(http) {
this.http = http;
}
async getRelease(registryUrl, packageName, versions) {
const cacheNs = `datasource-rubygems`;
const cacheKey = `metadata-cache:${registryUrl}:${packageName}`;
const versionsHash = hashVersions(versions);
const loadCache = () => result_1.Result.wrapNullable(packageCache.get(cacheNs, cacheKey), { type: 'cache-not-found' }).transform((cache) => {
return versionsHash === cache.hash
? result_1.Result.ok(cache.data)
: result_1.Result.err({ type: 'cache-stale', cache });
});
const saveCache = async (cache, ttlMinutes = 100 * 24 * 60, ttlDelta = 10 * 24 * 60) => {
const registryHostname = (0, url_1.parseUrl)(registryUrl)?.hostname;
if (registryHostname === 'rubygems.org') {
const ttlRandomDelta = Math.floor(Math.random() * ttlDelta);
const ttl = ttlMinutes + ttlRandomDelta;
await packageCache.set(cacheNs, cacheKey, cache, ttl);
}
};
return await loadCache()
.catch((err) => (0, common_1.getV1Releases)(this.http, registryUrl, packageName).transform(async (data) => {
const dataHash = hashReleases(data);
if (dataHash === versionsHash) {
await saveCache({
hash: dataHash,
data,
});
return result_1.Result.ok(data);
}
/**
* Return stale cache for 24 hours,
* if metadata is inconsistent with versions list.
*/
if (err.type === 'cache-stale') {
const staleCache = err.cache;
if (!staleCache.isFallback) {
await saveCache({ ...staleCache, isFallback: true }, 24 * 60, 0);
}
return result_1.Result.ok(staleCache.data);
}
return result_1.Result.err({ type: 'cache-invalid' });
}))
.catch((err) => {
logger_1.logger.debug({ err }, 'Rubygems: error fetching rubygems data, falling back to versions-only result');
const releases = versions.map((version) => ({ version }));
return result_1.Result.ok({ releases });
})
.unwrapOrThrow();
}
}
exports.MetadataCache = MetadataCache;
//# sourceMappingURL=metadata-cache.js.map