UNPKG

snyk-config

Version:

Config setup for snyk shared across projects

110 lines 4.32 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.loadConfig = void 0; const debugFactory = require("debug"); const path = require("path"); const _merge = require("lodash.merge"); // Use vendored and patched nconf without yargs and with our custom TRUE/FALSE logic in env.ts file const nconf_1 = require("./nconf/nconf"); const debug = debugFactory('snyk:config'); function loadConfig(dir, options) { if (!dir) { dir = ''; } options = options || {}; const secretConfig = options.secretConfig || process.env['CONFIG_SECRET_FILE'] || path.resolve(dir, 'config.secret.json'); const parseEnvValues = getParseEnvValues(options); if (!path.isAbsolute(dir)) { throw new Error('config requires absolute path to read from'); } const serviceEnv = process.env['SERVICE_ENV']; const localConfig = serviceEnv ? serviceEnv : 'local'; const localConfigPath = path.resolve(dir, `config.${localConfig}.json`); debug('dir: %s, local: %s, secret: %s', dir, localConfigPath, secretConfig); const snykMatch = /^SNYK_.*$/; nconf_1.default.env({ parseValues: parseEnvValues, separator: '__', match: snykMatch, whitelist: ['NODE_ENV', 'PORT'], }); // This argv parser is using minimist on the background, instead of yargs as nconf by default // Do not pass `options` to this parser nconf_1.default.argv(); nconf_1.default.file('secret', { file: path.resolve(secretConfig) }); nconf_1.default.file('local', { file: localConfigPath }); nconf_1.default.file('default', { file: path.resolve(dir, 'config.default.json') }); const config = nconf_1.default.get(); // strip prefix from env vars in config Object.keys(config).forEach(function (key) { if (key.match(snykMatch)) { const trimmedKey = key.replace(/^SNYK_/, ''); if (typeof config[trimmedKey] === 'object' && typeof config[key] === 'object') { config[trimmedKey] = _merge(config[trimmedKey], config[key]); } else { config[trimmedKey] = config[key]; } delete config[key]; } }); substituteEnvVarValues(config); debug('loading from %s', dir, JSON.stringify(config, null, 2)); return config; } exports.loadConfig = loadConfig; // recursively replace ${VAL} in config values with process.env.VAL function substituteEnvVarValues(config) { Object.keys(config).forEach(function (key) { // recurse through nested objects if (typeof config[key] === 'object') { return substituteEnvVarValues(config[key]); } // replace /\${.*?}/g in strings with env var if such exists if (typeof config[key] === 'string') { config[key] = config[key].replace(/(\${.*?})/g, function (_, match) { const val = match.slice(2, -1); // ditch the wrappers // explode if env var is missing if (process.env[val] === undefined) { throw new Error('Missing env var to substitute ' + val + " in '" + key + ': "' + config[key] + '"\''); } return process.env[val]; }); } }); } function getParseEnvValues(configOptions) { if (configOptions.parseEnvValues !== undefined) { if (typeof configOptions.parseEnvValues !== 'boolean') { throw new Error('options.parseEnvValues must be a boolean'); } return configOptions.parseEnvValues; } const envVarVal = process.env['CONFIG_PARSE_ENV_VALUES']; if (envVarVal !== undefined && envVarVal !== '' && envVarVal !== 'undefined') { let parsed; try { parsed = JSON.parse(envVarVal.toLowerCase()); } catch (_a) { throw new Error('CONFIG_PARSE_ENV_VALUES must be a boolean'); } if (typeof parsed !== 'boolean') { throw new Error('CONFIG_PARSE_ENV_VALUES must be a boolean'); } return parsed; } return false; } //# sourceMappingURL=index.js.map