UNPKG

@creditkarma/dynamic-config

Version:

Dynamic Config for Node.js backed by Consul and Vault

115 lines 3.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.envTranslator = void 0; /** * Plugin that replaces ${<variable-name>} with an environment placeholder. * * http://${HOSTNAME}:9000 */ const errors_1 = require("../errors"); function isValidChar(char) { return ((char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9') || char === '_' || char === '|'); } class Interpolater { constructor() { this.source = ''; this.len = 0; this.index = 0; this.match = ''; } run(source) { this.source = source; this.len = source.length; this.index = 0; this.match = ''; let result = ''; let defaultVal = ''; while (this.index < this.len) { const char = this.current(); if (char === '$' && this.peek() === '{') { this.advance(); // advance past $ this.advance(); // advance path { while (!this.isAtEnd() && this.current() !== '}' && isValidChar(this.current())) { // Check if we are handling a default value if (this.current() === '|' && this.peek() === '|') { this.advance(); // advance past first | this.advance(); // advance past second | defaultVal = this.parseDefault(); // Don't allow random pipe characters } else if (this.current() === '|') { // pipe is invalid unless defining default value throw new errors_1.InvalidCharacter(this.current()); // Otherwise we're still parsing the name match } else { this.match += this.current(); this.advance(); } // These handle the end of our parse if (this.current() === '}' && process.env[this.match.trim()] !== undefined) { // Match found this.advance(); // advance past } result += process.env[this.match.trim()]; this.match = ''; } else if (this.current() === '}' && defaultVal !== '') { result += defaultVal; this.advance(); // advance past } } else if (this.current() === '}') { throw new errors_1.MissingEnvironmentVariable(this.match); } else if (this.isAtEnd()) { result += this.match; this.match = ''; } } } else { result += char; this.advance(); } } return result; } parseDefault() { let result = ''; while (!this.isAtEnd() && this.current() !== '}') { result += this.current(); this.advance(); } return result.trim(); } current() { return this.source.charAt(this.index); } isAtEnd() { return this.index >= this.len; } peek() { return this.source.charAt(this.index + 1); } advance() { this.index += 1; } } const interpolater = new Interpolater(); exports.envTranslator = { translate(configValue) { if (typeof configValue === 'string') { const envVar = interpolater.run(configValue); if (envVar !== undefined) { return envVar; } } return configValue; }, }; //# sourceMappingURL=env.js.map