UNPKG

renovate

Version:

Automated dependency updates. Flexible so you don't need to be.

173 lines • 7.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PackagistDatasource = void 0; const tslib_1 = require("tslib"); const is_1 = tslib_1.__importDefault(require("@sindresorhus/is")); const zod_1 = require("zod"); const logger_1 = require("../../../logger"); const external_host_error_1 = require("../../../types/errors/external-host-error"); const decorator_1 = require("../../../util/cache/package/decorator"); const hostRules = tslib_1.__importStar(require("../../../util/host-rules")); const p = tslib_1.__importStar(require("../../../util/promises")); const url_1 = require("../../../util/url"); const composerVersioning = tslib_1.__importStar(require("../../versioning/composer")); const datasource_1 = require("../datasource"); const schema_1 = require("./schema"); class PackagistDatasource extends datasource_1.Datasource { static id = 'packagist'; constructor() { super(PackagistDatasource.id); } defaultRegistryUrls = ['https://repo.packagist.org']; defaultVersioning = composerVersioning.id; registryStrategy = 'hunt'; releaseTimestampSupport = true; releaseTimestampNote = 'The release timestamp is determined from the `time` field in the results.'; // Note: this can be changed to 'release', as the source is present in each release but we remove it while processing sourceUrlSupport = 'package'; sourceUrlNote = 'The source URL is determined from `source` field in the results.'; // We calculate auth at this datasource layer so that we can know whether it's safe to cache or not static getHostOpts(url) { const { username, password } = hostRules.find({ hostType: PackagistDatasource.id, url, }); return username && password ? { username, password } : {}; } async getJson(url, schema) { const opts = PackagistDatasource.getHostOpts(url); const { body } = await this.http.getJson(url, opts, schema); return body; } async getRegistryMeta(regUrl) { const url = (0, url_1.resolveBaseUrl)(regUrl, 'packages.json'); const result = await this.getJson(url, schema_1.RegistryMeta); return result; } static isPrivatePackage(regUrl) { const opts = PackagistDatasource.getHostOpts(regUrl); return !!opts.password; } static getPackagistFileUrl(regUrl, regFile) { const { key, hash } = regFile; const fileName = hash ? key.replace('%hash%', hash) : /* istanbul ignore next: hard to test */ key; const url = (0, url_1.resolveBaseUrl)(regUrl, fileName); return url; } async getPackagistFile(regUrl, regFile) { const url = PackagistDatasource.getPackagistFileUrl(regUrl, regFile); const packagistFile = await this.getJson(url, schema_1.PackagistFile); return packagistFile; } async fetchProviderPackages(regUrl, meta) { await p.map(meta.files, async (file) => { const res = await this.getPackagistFile(regUrl, file); Object.assign(meta.providerPackages, res.providers); }); } async fetchIncludesPackages(regUrl, meta) { await p.map(meta.includesFiles, async (file) => { const res = await this.getPackagistFile(regUrl, file); for (const [key, val] of Object.entries(res.packages)) { meta.includesPackages[key] = (0, schema_1.extractDepReleases)(val); } }); } async packagistV2Lookup(registryUrl, metadataUrl, packageName) { const pkgUrl = (0, url_1.replaceUrlPath)(registryUrl, metadataUrl.replace('%package%', packageName)); const pkgPromise = this.getJson(pkgUrl, zod_1.z.unknown()); const devUrl = (0, url_1.replaceUrlPath)(registryUrl, metadataUrl.replace('%package%', `${packageName}~dev`)); const devPromise = this.getJson(devUrl, zod_1.z.unknown()).then((x) => x, () => null); const responses = await Promise.all([ pkgPromise, devPromise, ]).then((responses) => responses.filter(is_1.default.object)); return (0, schema_1.parsePackagesResponses)(packageName, responses); } getPkgUrl(packageName, registryUrl, registryMeta) { if (registryMeta.providersUrl && packageName in registryMeta.providerPackages) { let url = registryMeta.providersUrl.replace('%package%', packageName); const hash = registryMeta.providerPackages[packageName]; if (hash) { url = url.replace('%hash%', hash); } return (0, url_1.replaceUrlPath)(registryUrl, url); } if (registryMeta.providersLazyUrl) { return (0, url_1.replaceUrlPath)(registryUrl, registryMeta.providersLazyUrl.replace('%package%', packageName)); } return null; } async getReleases({ packageName, registryUrl, }) { logger_1.logger.trace(`getReleases(${packageName})`); /* v8 ignore next 3 -- should never happen */ if (!registryUrl) { return null; } try { const meta = await this.getRegistryMeta(registryUrl); if (meta.availablePackages && !meta.availablePackages.includes(packageName)) { return null; } if (meta.metadataUrl) { const packagistResult = await this.packagistV2Lookup(registryUrl, meta.metadataUrl, packageName); return packagistResult; } if (meta.packages[packageName]) { const result = (0, schema_1.extractDepReleases)(meta.packages[packageName]); return result; } await this.fetchIncludesPackages(registryUrl, meta); if (meta.includesPackages[packageName]) { return meta.includesPackages[packageName]; } await this.fetchProviderPackages(registryUrl, meta); const pkgUrl = this.getPkgUrl(packageName, registryUrl, meta); if (!pkgUrl) { return null; } const pkgRes = await this.getJson(pkgUrl, schema_1.PackagesResponse); const dep = (0, schema_1.extractDepReleases)(pkgRes.packages[packageName]); logger_1.logger.trace({ dep }, 'dep'); return dep; } catch (err) /* istanbul ignore next */ { if (err.host === 'packagist.org') { if (err.code === 'ECONNRESET' || err.code === 'ETIMEDOUT') { throw new external_host_error_1.ExternalHostError(err); } if (err.statusCode && err.statusCode >= 500 && err.statusCode < 600) { throw new external_host_error_1.ExternalHostError(err); } } throw err; } } } exports.PackagistDatasource = PackagistDatasource; tslib_1.__decorate([ (0, decorator_1.cache)({ namespace: `datasource-${PackagistDatasource.id}`, key: (regUrl) => `getRegistryMeta:${regUrl}`, }) ], PackagistDatasource.prototype, "getRegistryMeta", null); tslib_1.__decorate([ (0, decorator_1.cache)({ namespace: `datasource-${PackagistDatasource.id}`, key: (regUrl, regFile) => `getPackagistFile:${PackagistDatasource.getPackagistFileUrl(regUrl, regFile)}`, cacheable: (regUrl) => !PackagistDatasource.isPrivatePackage(regUrl), ttlMinutes: 1440, }) ], PackagistDatasource.prototype, "getPackagistFile", null); tslib_1.__decorate([ (0, decorator_1.cache)({ namespace: `datasource-${PackagistDatasource.id}`, key: (registryUrl, metadataUrl, packageName) => `packagistV2Lookup:${registryUrl}:${metadataUrl}:${packageName}`, ttlMinutes: 10, }) ], PackagistDatasource.prototype, "packagistV2Lookup", null); //# sourceMappingURL=index.js.map