(
value: unknown,
envVars: Record<string, string>,
options: EnvVarResolveOptions = {}
)
| 49 | * Resolve {{ENV_VAR}} references in values using provided env vars. |
| 50 | */ |
| 51 | export function resolveEnvVarReferences( |
| 52 | value: unknown, |
| 53 | envVars: Record<string, string>, |
| 54 | options: EnvVarResolveOptions = {} |
| 55 | ): unknown { |
| 56 | const { |
| 57 | allowEmbedded = ENV_VAR_RESOLVE_DEFAULTS.allowEmbedded, |
| 58 | resolveExactMatch = ENV_VAR_RESOLVE_DEFAULTS.resolveExactMatch, |
| 59 | trimKeys = ENV_VAR_RESOLVE_DEFAULTS.trimKeys, |
| 60 | onMissing = ENV_VAR_RESOLVE_DEFAULTS.onMissing, |
| 61 | deep = ENV_VAR_RESOLVE_DEFAULTS.deep, |
| 62 | } = options |
| 63 | |
| 64 | if (typeof value === 'string') { |
| 65 | if (resolveExactMatch) { |
| 66 | const exactMatchPattern = new RegExp( |
| 67 | `^\\${REFERENCE.ENV_VAR_START}([^}]+)\\${REFERENCE.ENV_VAR_END}$` |
| 68 | ) |
| 69 | const exactMatch = exactMatchPattern.exec(value) |
| 70 | if (exactMatch) { |
| 71 | const envKey = trimKeys ? exactMatch[1].trim() : exactMatch[1] |
| 72 | const envValue = envVars[envKey] |
| 73 | if (envValue !== undefined) return envValue |
| 74 | if (options.missingKeys) options.missingKeys.push(envKey) |
| 75 | if (onMissing === 'throw') { |
| 76 | throw new Error(`Environment variable "${envKey}" was not found`) |
| 77 | } |
| 78 | if (onMissing === 'empty') { |
| 79 | return '' |
| 80 | } |
| 81 | return value |
| 82 | } |
| 83 | } |
| 84 | |
| 85 | if (!allowEmbedded) return value |
| 86 | |
| 87 | const envVarPattern = createEnvVarPattern() |
| 88 | return value.replace(envVarPattern, (match, varName) => { |
| 89 | const envKey = trimKeys ? String(varName).trim() : String(varName) |
| 90 | const envValue = envVars[envKey] |
| 91 | if (envValue !== undefined) return envValue |
| 92 | if (options.missingKeys) options.missingKeys.push(envKey) |
| 93 | if (onMissing === 'throw') { |
| 94 | throw new Error(`Environment variable "${envKey}" was not found`) |
| 95 | } |
| 96 | if (onMissing === 'empty') { |
| 97 | return '' |
| 98 | } |
| 99 | return match |
| 100 | }) |
| 101 | } |
| 102 | |
| 103 | if (deep && Array.isArray(value)) { |
| 104 | return value.map((item) => resolveEnvVarReferences(item, envVars, options)) |
| 105 | } |
| 106 | |
| 107 | if (deep && value !== null && typeof value === 'object') { |
| 108 | const resolved: Record<string, any> = {} |
no test coverage detected