UNPKG

@layerfig/config

Version:

Layer and runtime-validate type-safe configs for JavaScript apps.

79 lines (78 loc) 2.69 kB
//#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