You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
2.6 KiB
103 lines
2.6 KiB
/* @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
|
|
|