/* @flow */ /*:: type DotenvParseOptions = { debug?: boolean } // keys and values from src type DotenvParseOutput = { [string]: string } type DotenvConfigOptions = { path?: string, // path to .env file encoding?: string, // encoding of .env file debug?: string // turn on logging for debugging purposes } type DotenvConfigOutput = { parsed?: DotenvParseOutput, error?: Error } */ const fs = require('fs') const path = require('path') function log (message /*: string */) { console.log(`[dotenv][DEBUG] ${message}`) } // Parses src into an Object function parse (src /*: string | Buffer */, options /*: ?DotenvParseOptions */) /*: DotenvParseOutput */ { const debug = Boolean(options && options.debug) const obj = {} // convert Buffers before splitting into lines and processing src.toString().split('\n').forEach(function (line, idx) { // matching "KEY' and 'VAL' in 'KEY=VAL' const keyValueArr = line.match(/^\s*([\w.-]+)\s*=\s*(.*)?\s*$/) // matched? if (keyValueArr != null) { const key = keyValueArr[1] // default undefined or missing values to empty string let value = keyValueArr[2] || '' // expand newlines in quoted values const len = value ? value.length : 0 if (len > 0 && value.charAt(0) === '"' && value.charAt(len - 1) === '"') { value = value.replace(/\\n/gm, '\n') } // remove any surrounding quotes and extra spaces value = value.replace(/(^['"]|['"]$)/g, '').trim() obj[key] = value } else if (debug) { log(`did not match key and value when parsing line ${idx + 1}: ${line}`) } }) return obj } // Populates process.env from .env file function config (options /*: ?DotenvConfigOptions */) /*: DotenvConfigOutput */ { let dotenvPath = path.resolve(process.cwd(), '.env') let encoding /*: string */ = 'utf8' let debug = false if (options) { if (options.path != null) { dotenvPath = options.path } if (options.encoding != null) { encoding = options.encoding } if (options.debug != null) { debug = true } } try { // specifying an encoding returns a string instead of a buffer const parsed = parse(fs.readFileSync(dotenvPath, { encoding }), { debug }) Object.keys(parsed).forEach(function (key) { if (!process.env.hasOwnProperty(key)) { process.env[key] = parsed[key] } else if (debug) { log(`"${key}" is already defined in \`process.env\` and will not be overwritten`) } }) return { parsed } } catch (e) { return { error: e } } } module.exports.config = config module.exports.load = config module.exports.parse = parse