terrac
Version:
A minimal private module registry for Terraform and OpenTofu
94 lines (93 loc) • 3.44 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseConfigOverwrites = exports.resolveVersion = exports.expandSemver = exports.isSemver = exports.saveConfig = exports.loadConfig = exports.validateConfig = exports.projectConfigSchema = exports.moduleConfigSchema = exports.backendConfigSchema = void 0;
const fs_extra_1 = require("fs-extra");
const lodash_1 = require("lodash");
const Joi = require("joi");
const semver_1 = require("semver");
const factory_1 = require("./backends/factory");
exports.backendConfigSchema = factory_1.configSchema;
exports.moduleConfigSchema = Joi.object({
name: Joi.string().pattern(/^[\dA-Za-z-]+$/).required().description('Module name'),
version: Joi.string().pattern(/^[\d.a-z-]+$/).required().description('Module version'),
});
exports.projectConfigSchema = Joi.object({
backend: exports.backendConfigSchema.required(),
module: exports.moduleConfigSchema.optional(),
});
async function validateConfig(schema, config) {
try {
await schema.validateAsync(config);
}
catch (error) {
throw new Error(`Terrac configuration is invalid. ${error.message}`);
}
}
exports.validateConfig = validateConfig;
async function loadConfig(rootDir, overwrites = {}) {
const config = await (0, fs_extra_1.readJson)(`${rootDir}/terrac.json`);
const defaults = {
backend: {
keyPrefix: '',
},
};
const result = Object.assign({}, defaults, config);
for (const [key, value] of Object.entries(overwrites)) {
(0, lodash_1.set)(result, key, value);
}
return result;
}
exports.loadConfig = loadConfig;
async function saveConfig(rootDir, config) {
await validateConfig(exports.projectConfigSchema, config);
await (0, fs_extra_1.writeFile)(`${rootDir}/terrac.json`, JSON.stringify(config, null, 2));
}
exports.saveConfig = saveConfig;
function isSemver(version) {
return version.match(/^(\d+)(\.\d+)?(\.\d+)?$/) !== null;
}
exports.isSemver = isSemver;
function expandSemver(version) {
const versions = [];
const checkSemver = version.match(/(\d+)\.(\d+)\.(\d+)/);
if (!checkSemver) {
throw new Error(`The version "${version}" is not a semver.`);
}
versions.push(checkSemver[1], `${checkSemver[1]}.${checkSemver[2]}`, version);
return versions;
}
exports.expandSemver = expandSemver;
function resolveVersion(meta, target) {
const versions = meta.releases.map(release => release.version);
if (!isSemver(target)) {
if (target === 'latest') {
return meta.version;
}
if (!versions.includes(target)) {
throw new Error(`The version ${target} is not found.`);
}
return target;
}
let found = '0.0.0';
for (const version of versions) {
if (isSemver(version) &&
version.startsWith(target) &&
(0, semver_1.gt)(version, found)) {
found = version;
}
}
if (found === '0.0.0' && meta.version !== '0.0.0') {
throw new Error(`The version ${target} cannot be resolved.`);
}
return found;
}
exports.resolveVersion = resolveVersion;
function parseConfigOverwrites(inputs = []) {
const overwrites = {};
for (const conifg of inputs) {
const [key, value] = conifg.split('=');
overwrites[key] = value;
}
return overwrites;
}
exports.parseConfigOverwrites = parseConfigOverwrites;