snyk-config
Version:
Config setup for snyk shared across projects
110 lines • 4.32 kB
JavaScript
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
;