@layerfig/config
Version:
Layer and runtime-validate type-safe configs for JavaScript apps.
79 lines (78 loc) • 2.69 kB
JavaScript
//#region src/sources/source.ts
var Source = class {
maybeReplaceSlotFromValue({ value, slotPrefix, runtimeEnv }) {
const slots = this.#extractSlotName({
slotPrefix,
value
});
if (slots === null) return value;
let newValue = value;
for (const slot of slots) {
let envVarValue;
for (const envVar of slot.envVarName) {
const value$1 = runtimeEnv[envVar];
if (value$1) {
envVarValue = value$1;
break;
}
}
envVarValue ??= slot.fallback;
if (envVarValue) newValue = newValue.replace(slot.slotPattern, envVarValue);
else console.warn("[SLOT_REPLACEMENT]", `The value for the slot "${slot.envVarName}" is not defined in the runtime environment. The slot will not be replaced.`);
}
return newValue;
}
#extractSlotName({ slotPrefix, value }) {
/**
* Something like: /\$\w+/g
* To match basic slots like $MY_VAR
*/
const basicSlotRegex = new RegExp(`\\${slotPrefix}\\w+`, "g");
/**
* Something like: /\$\{.*\}/g
* To match multi-slot patterns like ${MY_VAR:MY_OTHER_VAR}
*/
const multiSlotRegex = new RegExp(`\\${slotPrefix}{.*}`, "g");
const basicMatches = value.match(basicSlotRegex);
const multiMatches = value.match(multiSlotRegex);
if (!basicMatches && !multiMatches) return null;
const result = [];
if (basicMatches) {
const uniqueSlots = new Set(basicMatches);
result.push(...Array.from(uniqueSlots).map((slotMatch) => ({
envVarName: [slotMatch.replace(slotPrefix, "")],
slotPattern: this.#safeSlotRegex(slotMatch),
value
})));
}
if (multiMatches) {
const possibleEnvVarSlots = new Set(multiMatches);
for (const possibleSlot of possibleEnvVarSlots) {
let fallbackValue;
const values = possibleSlot.replace(`${slotPrefix}{`, "").replace("}", "").split(":");
if (values[values.length - 1]?.includes("-")) fallbackValue = values.pop()?.trim().replace("-", "");
result.push({
envVarName: values,
slotPattern: this.#safeSlotRegex(possibleSlot),
value,
fallback: fallbackValue
});
}
}
return result;
}
#safeSlotRegex(slot) {
/**
* Escape the first character to ensure it is treated literally in the regex
* This is necessary because the first character could be a special regex character
* such as $, ^, or \, which would otherwise be interpreted by the regex engine.
* For example, if the slot is "$MY_VAR", we want to match it literally as "\$MY_VAR".
* This ensures that the regex will match the slot name exactly as it appears in the string.
*/
const safe = slot.replace(/^./, (m) => `\\${m}`);
return new RegExp(safe, "gm");
}
};
//#endregion
export { Source };
//# sourceMappingURL=source-BvmiqUNz.js.map