| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 | /* @flow *//*::type DotenvParseOptions = {  debug?: boolean}// keys and values from srctype 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}`)}const NEWLINE = '\n'const RE_INI_KEY_VAL = /^\s*([\w.-]+)\s*=\s*(.*)?\s*$/const RE_NEWLINES = /\\n/g// Parses src into an Objectfunction 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(NEWLINE).forEach(function (line, idx) {    // matching "KEY' and 'VAL' in 'KEY=VAL'    const keyValueArr = line.match(RE_INI_KEY_VAL)    // matched?    if (keyValueArr != null) {      const key = keyValueArr[1]      // default undefined or missing values to empty string      let val = (keyValueArr[2] || '')      const end = val.length - 1      const isDoubleQuoted = val[0] === '"' && val[end] === '"'      const isSingleQuoted = val[0] === "'" && val[end] === "'"      // if single or double quoted, remove quotes      if (isSingleQuoted || isDoubleQuoted) {        val = val.substring(1, end)        // if double quoted, expand newlines        if (isDoubleQuoted) {          val = val.replace(RE_NEWLINES, NEWLINE)        }      } else {        // remove surrounding whitespace        val = val.trim()      }      obj[key] = val    } else if (debug) {      log(`did not match key and value when parsing line ${idx + 1}: ${line}`)    }  })  return obj}// Populates process.env from .env filefunction 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 = configmodule.exports.parse = parse
 |