1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | const fs = require('fs')
|
25 | const path = require('path')
|
26 |
|
27 | function log (message /*: string */) {
|
28 | console.log(`[dotenv][DEBUG] ${message}`)
|
29 | }
|
30 |
|
31 | const NEWLINE = '\n'
|
32 | const RE_INI_KEY_VAL = /^\s*([\w.-]+)\s*=\s*(.*)?\s*$/
|
33 | const RE_NEWLINES = /\\n/g
|
34 | const NEWLINES_MATCH = /\n|\r|\r\n/
|
35 |
|
36 |
|
37 | function parse (src /*: string | Buffer */, options /*: ?DotenvParseOptions */) /*: DotenvParseOutput */ {
|
38 | const debug = Boolean(options && options.debug)
|
39 | const obj = {}
|
40 |
|
41 |
|
42 | src.toString().split(NEWLINES_MATCH).forEach(function (line, idx) {
|
43 |
|
44 | const keyValueArr = line.match(RE_INI_KEY_VAL)
|
45 |
|
46 | if (keyValueArr != null) {
|
47 | const key = keyValueArr[1]
|
48 |
|
49 | let val = (keyValueArr[2] || '')
|
50 | const end = val.length - 1
|
51 | const isDoubleQuoted = val[0] === '"' && val[end] === '"'
|
52 | const isSingleQuoted = val[0] === "'" && val[end] === "'"
|
53 |
|
54 |
|
55 | if (isSingleQuoted || isDoubleQuoted) {
|
56 | val = val.substring(1, end)
|
57 |
|
58 |
|
59 | if (isDoubleQuoted) {
|
60 | val = val.replace(RE_NEWLINES, NEWLINE)
|
61 | }
|
62 | } else {
|
63 |
|
64 | val = val.trim()
|
65 | }
|
66 |
|
67 | obj[key] = val
|
68 | } else if (debug) {
|
69 | log(`did not match key and value when parsing line ${idx + 1}: ${line}`)
|
70 | }
|
71 | })
|
72 |
|
73 | return obj
|
74 | }
|
75 |
|
76 |
|
77 | function config (options /*: ?DotenvConfigOptions */) /*: DotenvConfigOutput */ {
|
78 | let dotenvPath = path.resolve(process.cwd(), '.env')
|
79 | let encoding = 'utf8'
|
80 | let debug = false
|
81 |
|
82 | if (options) {
|
83 | if (options.path != null) {
|
84 | dotenvPath = options.path
|
85 | }
|
86 | if (options.encoding != null) {
|
87 | encoding = options.encoding
|
88 | }
|
89 | if (options.debug != null) {
|
90 | debug = true
|
91 | }
|
92 | }
|
93 |
|
94 | try {
|
95 |
|
96 | const parsed = parse(fs.readFileSync(dotenvPath, { encoding }), { debug })
|
97 |
|
98 | Object.keys(parsed).forEach(function (key) {
|
99 | if (!Object.prototype.hasOwnProperty.call(process.env, key)) {
|
100 | process.env[key] = parsed[key]
|
101 | } else if (debug) {
|
102 | log(`"${key}" is already defined in \`process.env\` and will not be overwritten`)
|
103 | }
|
104 | })
|
105 |
|
106 | return { parsed }
|
107 | } catch (e) {
|
108 | return { error: e }
|
109 | }
|
110 | }
|
111 |
|
112 | module.exports.config = config
|
113 | module.exports.parse = parse
|