var util = require("util"); var url = require("url"); var fallbacksDisabled = false; var throwError = true; function _value(varName, fallback) { var value = process.env[varName]; if (value === undefined) { if (fallback === undefined && !throwError) { return value; } if (fallback === undefined) { throw new Error('GetEnv.Nonexistent: ' + varName + ' does not exist ' + 'and no fallback value provided.'); } if (fallbacksDisabled) { throw new Error('GetEnv.DisabledFallbacks: ' + varName + ' relying on fallback ' + 'when fallbacks have been disabled'); } return '' + fallback; } return value; } var convert = { string: function(value) { return '' + value; }, int: function(value) { var isInt = value.match(/^-?\d+$/); if (!isInt) { throw new Error('GetEnv.NoInteger: ' + value + ' is not an integer.'); } return +value; }, float: function(value) { var isInfinity = (+value === Infinity || +value === -Infinity); if (isInfinity) { throw new Error('GetEnv.Infinity: ' + value + ' is set to +/-Infinity.'); } var isFloat = !(isNaN(value) || value === ''); if (!isFloat) { throw new Error('GetEnv.NoFloat: ' + value + ' is not a number.'); } return +value; }, bool: function(value) { var isBool = (value === 'true' || value === 'false'); if (!isBool) { throw new Error('GetEnv.NoBoolean: ' + value + ' is not a boolean.'); } return (value === 'true') }, boolish: function(value) { try { return convert.bool(value) } catch(err) { var isBool = (value === '1' || value === '0'); if (!isBool) { throw new Error('GetEnv.NoBoolean: ' + value + ' is not a boolean.'); } return (value === '1'); } }, url: url.parse }; function converter(type) { return function(varName, fallback) { if(typeof varName == 'string') { // default var value = _value(varName, fallback); return convert[type](value); } else { // multibert! return getenv.multi(varName); } }; }; var getenv = converter('string'); Object.keys(convert).forEach(function(type) { getenv[type] = converter(type); }); getenv.array = function array(varName, type, fallback) { type = type || 'string'; if (Object.keys(convert).indexOf(type) === -1) { throw new Error('GetEnv.ArrayUndefinedType: Unknown array type ' + type); } var value = _value(varName, fallback); return value.split(/\s*,\s*/).map(convert[type]); }; getenv.multi = function multi(spec) { var key, value; var result = {}; for(var key in spec) { var value = spec[key]; if(util.isArray(value)) { // default value & typecast switch(value.length) { case 1: // no default value case 2: // no type casting result[key] = getenv(value[0], value[1]); // dirty, when case 1: value[1] is undefined break; case 3: // with typecast result[key] = getenv[value[2]](value[0], value[1]); break; default: // wtf? throw('getenv.multi(): invalid spec'); break; } } else { // value or throw result[key] = getenv(value); } } return result; }; getenv.disableFallbacks = function() { fallbacksDisabled = true; }; getenv.enableFallbacks = function() { fallbacksDisabled = false; }; getenv.disableErrors = function() { throwError = false; }; getenv.enableErrors = function() { throwError = true; }; module.exports = getenv;