main.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. const fs = require('fs')
  2. const path = require('path')
  3. const os = require('os')
  4. const LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg
  5. // Parser src into an Object
  6. function parse (src) {
  7. const obj = {}
  8. // Convert buffer to string
  9. let lines = src.toString()
  10. // Convert line breaks to same format
  11. lines = lines.replace(/\r\n?/mg, '\n')
  12. let match
  13. while ((match = LINE.exec(lines)) != null) {
  14. const key = match[1]
  15. // Default undefined or null to empty string
  16. let value = (match[2] || '')
  17. // Remove whitespace
  18. value = value.trim()
  19. // Check if double quoted
  20. const maybeQuote = value[0]
  21. // Remove surrounding quotes
  22. value = value.replace(/^(['"`])([\s\S]*)\1$/mg, '$2')
  23. // Expand newlines if double quoted
  24. if (maybeQuote === '"') {
  25. value = value.replace(/\\n/g, '\n')
  26. value = value.replace(/\\r/g, '\r')
  27. }
  28. // Add to object
  29. obj[key] = value
  30. }
  31. return obj
  32. }
  33. function _log (message) {
  34. console.log(`[dotenv][DEBUG] ${message}`)
  35. }
  36. function _resolveHome (envPath) {
  37. return envPath[0] === '~' ? path.join(os.homedir(), envPath.slice(1)) : envPath
  38. }
  39. // Populates process.env from .env file
  40. function config (options) {
  41. let dotenvPath = path.resolve(process.cwd(), '.env')
  42. let encoding = 'utf8'
  43. const debug = Boolean(options && options.debug)
  44. const override = Boolean(options && options.override)
  45. if (options) {
  46. if (options.path != null) {
  47. dotenvPath = _resolveHome(options.path)
  48. }
  49. if (options.encoding != null) {
  50. encoding = options.encoding
  51. }
  52. }
  53. try {
  54. // Specifying an encoding returns a string instead of a buffer
  55. const parsed = DotenvModule.parse(fs.readFileSync(dotenvPath, { encoding }))
  56. Object.keys(parsed).forEach(function (key) {
  57. if (!Object.prototype.hasOwnProperty.call(process.env, key)) {
  58. process.env[key] = parsed[key]
  59. } else {
  60. if (override === true) {
  61. process.env[key] = parsed[key]
  62. }
  63. if (debug) {
  64. if (override === true) {
  65. _log(`"${key}" is already defined in \`process.env\` and WAS overwritten`)
  66. } else {
  67. _log(`"${key}" is already defined in \`process.env\` and was NOT overwritten`)
  68. }
  69. }
  70. }
  71. })
  72. return { parsed }
  73. } catch (e) {
  74. if (debug) {
  75. _log(`Failed to load ${dotenvPath} ${e.message}`)
  76. }
  77. return { error: e }
  78. }
  79. }
  80. const DotenvModule = {
  81. config,
  82. parse
  83. }
  84. module.exports.config = DotenvModule.config
  85. module.exports.parse = DotenvModule.parse
  86. module.exports = DotenvModule