UNPKG

renovate

Version:

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

148 lines 6.46 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TerraformModuleDatasource = void 0; const tslib_1 = require("tslib"); const logger_1 = require("../../../logger"); const decorator_1 = require("../../../util/cache/package/decorator"); const regex_1 = require("../../../util/regex"); const string_1 = require("../../../util/string"); const timestamp_1 = require("../../../util/timestamp"); const url_1 = require("../../../util/url"); const hashicorpVersioning = tslib_1.__importStar(require("../../versioning/hashicorp")); const base_1 = require("./base"); const utils_1 = require("./utils"); class TerraformModuleDatasource extends base_1.TerraformDatasource { static id = 'terraform-module'; constructor() { super(TerraformModuleDatasource.id); } defaultRegistryUrls = ['https://registry.terraform.io']; defaultVersioning = hashicorpVersioning.id; releaseTimestampSupport = true; releaseTimestampNote = 'The release timestamp is only supported for the latest version, and is determined from the `published_at` field in the results.'; sourceUrlSupport = 'package'; sourceUrlNote = 'The source URL is determined from the the `source` field in the results.'; extendedApiRegistryUrls = [ 'https://registry.terraform.io', 'https://app.terraform.io', ]; /** * This function will fetch a package from the specified Terraform registry and return all semver versions. * - `sourceUrl` is supported if "source" field is set * - `homepage` is set to the Terraform registry's page if it's on the official main registry */ async getReleases({ packageName, registryUrl, }) { /* v8 ignore next 3 -- should never happen */ if (!registryUrl) { return null; } const { registry: registryUrlNormalized, repository } = TerraformModuleDatasource.getRegistryRepository(packageName, registryUrl); logger_1.logger.trace({ registryUrlNormalized, terraformRepository: repository }, 'terraform-module.getReleases()'); const serviceDiscovery = await this.getTerraformServiceDiscoveryResult(registryUrlNormalized); if (this.extendedApiRegistryUrls.includes(registryUrlNormalized)) { return await this.queryRegistryExtendedApi(serviceDiscovery, registryUrlNormalized, repository); } return await this.queryRegistryVersions(serviceDiscovery, registryUrlNormalized, repository); } /** * this uses the api that terraform registry has in addition to the base api * this endpoint provides more information, such as release date * https://www.terraform.io/registry/api-docs#latest-version-for-a-specific-module-provider */ async queryRegistryExtendedApi(serviceDiscovery, registryUrl, repository) { let res; let pkgUrl; try { // TODO: types (#22198) pkgUrl = (0, utils_1.createSDBackendURL)(registryUrl, 'modules.v1', serviceDiscovery, repository); res = (await this.http.getJsonUnchecked(pkgUrl)).body; const returnedName = res.namespace + '/' + res.name + '/' + res.provider; if (returnedName !== repository) { logger_1.logger.warn({ pkgUrl }, 'Terraform registry result mismatch'); return null; } } catch (err) { this.handleGenericErrors(err); } // Simplify response before caching and returning const dep = { releases: res.versions.map((version) => ({ version, })), }; if (res.source) { dep.sourceUrl = res.source; } dep.homepage = `${registryUrl}/modules/${repository}`; // set published date for latest release const latestVersion = dep.releases.find((release) => res.version === release.version); if (latestVersion) { latestVersion.releaseTimestamp = (0, timestamp_1.asTimestamp)(res.published_at); } return dep; } /** * this version uses the Module Registry Protocol that all registries are required to implement * https://www.terraform.io/internals/module-registry-protocol */ async queryRegistryVersions(serviceDiscovery, registryUrl, repository) { let res; let pkgUrl; try { // TODO: types (#22198) pkgUrl = (0, utils_1.createSDBackendURL)(registryUrl, 'modules.v1', serviceDiscovery, `${repository}/versions`); res = (await this.http.getJsonUnchecked(pkgUrl)) .body; if (res.modules.length < 1) { logger_1.logger.warn({ pkgUrl }, 'Terraform registry result mismatch'); return null; } } catch (err) { this.handleGenericErrors(err); } // Simplify response before caching and returning const dep = { releases: res.modules[0].versions.map(({ version }) => ({ version, })), }; // Add the source URL if given if ((0, url_1.isHttpUrl)(res.modules[0].source)) { dep.sourceUrl = res.modules[0].source; } return dep; } static getRegistryRepository(packageName, registryUrl) { let registry; const split = packageName.split('/'); if (split.length > 3 && split[0].includes('.')) { [registry] = split; split.shift(); } else { registry = (0, string_1.coerceString)(registryUrl); } if (!(0, regex_1.regEx)(/^https?:\/\//).test(registry)) { registry = `https://${registry}`; } const repository = split.join('/'); return { registry, repository, }; } static getCacheKey({ packageName, registryUrl, }) { const { registry, repository } = TerraformModuleDatasource.getRegistryRepository(packageName, registryUrl); return `${registry}/${repository}`; } } exports.TerraformModuleDatasource = TerraformModuleDatasource; tslib_1.__decorate([ (0, decorator_1.cache)({ namespace: `datasource-${TerraformModuleDatasource.id}`, key: (getReleasesConfig) => TerraformModuleDatasource.getCacheKey(getReleasesConfig), }) ], TerraformModuleDatasource.prototype, "getReleases", null); //# sourceMappingURL=index.js.map