renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
148 lines • 6.46 kB
JavaScript
;
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