renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
65 lines (64 loc) • 2.96 kB
JavaScript
import { CONFIG_SECRETS_INVALID, CONFIG_VALIDATION, CONFIG_VARIABLES_INVALID } from "../constants/error-messages.js";
import { capitalize } from "./string.js";
import { logger } from "../logger/index.js";
import { isArray, isPlainObject, isString } from "@sindresorhus/is";
//#region lib/util/interpolator.ts
function validateInterpolatedValues(input, options) {
if (!input) return;
const { name, nameRegex } = options;
const validationErrors = [];
if (isPlainObject(input)) for (const [key, value] of Object.entries(input)) {
if (!nameRegex.test(key)) validationErrors.push(`Invalid ${name} name "${key}"`);
if (!isString(value)) validationErrors.push(`${capitalize(name)} values must be strings. Found type ${typeof value} for ${name} ${key}`);
}
else validationErrors.push(`Config ${name}s must be a plain object. Found: ${typeof input}`);
if (validationErrors.length) {
logger.error({ validationErrors }, `Invalid ${name}s configured`);
throw new Error(name === "secrets" ? CONFIG_SECRETS_INVALID : CONFIG_VARIABLES_INVALID);
}
}
function replaceInterpolatedValuesInString(key, value, input, options) {
const { name, templateRegex } = options;
templateRegex.lastIndex = 0;
if (!templateRegex.test(value)) return value;
if ([
"branch",
"commit",
"group",
"pr",
"semantic"
].some((prefix) => key.startsWith(prefix))) {
const error = new Error(CONFIG_VALIDATION);
error.validationSource = "config";
error.validationError = `Disallowed ${name} substitution`;
error.validationMessage = `The field \`${key}\` may not use ${name} substitution`;
throw error;
}
return value.replace(templateRegex, (_, key) => {
if (input?.[key]) return input[key];
const error = new Error(CONFIG_VALIDATION);
error.validationSource = "config";
error.validationError = `Unknown ${name} name`;
error.validationMessage = `The following ${name} name was not found in config: ${String(key)}`;
throw error;
});
}
function replaceInterpolatedValuesInObject(config_, input, options, deleteValues = true) {
const config = { ...config_ };
const { name } = options;
if (deleteValues) delete config[name];
for (const [key, value] of Object.entries(config)) {
if (isPlainObject(value) && key !== "onboardingConfig") config[key] = replaceInterpolatedValuesInObject(value, input, options, deleteValues);
if (isString(value)) config[key] = replaceInterpolatedValuesInString(key, value, input, options);
if (isArray(value)) {
for (const [arrayIndex, arrayItem] of value.entries())
// v8 ignore else -- TODO: add test #40625
if (isPlainObject(arrayItem)) value[arrayIndex] = replaceInterpolatedValuesInObject(arrayItem, input, options, deleteValues);
else if (isString(arrayItem)) value[arrayIndex] = replaceInterpolatedValuesInString(key, arrayItem, input, options);
}
}
return config;
}
//#endregion
export { replaceInterpolatedValuesInObject, validateInterpolatedValues };
//# sourceMappingURL=interpolator.js.map