forked from brysgo/babel-plugin-inline-dotenv
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
125 lines (107 loc) · 3.37 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
const nodepath = require("path");
const fs = require("fs");
const os = require("os");
// Parse configuration file
// File must be text file with KEY=VALUE pair (shell style) settings
// Return Map with key/values
const parse = (path, opts = {}) => {
const abortOnError = opts.abortOnError || false;
const cfg = new Map();
if (!fs.existsSync(path)) {
const err = `${path} does not exist`;
if (abortOnError) throw new Error(err);
else {
console.log(err);
return cfg;
}
}
const content = fs.readFileSync(path, "utf8").split("\n");
content.forEach((l) => {
if (!l.includes("=")) return;
const [key, value] = l.split("=");
if (key && key.length > 0) cfg.set(key, value || "");
});
// console.log('parse', path, cfg)
return cfg;
};
// Merge two or more Maps
// Returns single merged Map
const mergeCfg = (configs) => {
const config = new Map();
configs.forEach((_cfg) => {
for (const [key, value] of _cfg.entries()) {
config.set(key, value);
}
});
// console.log('mergeCfg', config)
return config;
};
// Write configuration (Map) to temporary text file
// as KEY=VALUE pair (shell style) settings
// Returns path to temp file
const write = (cfg) => {
const tmpFile = `${os.tmpdir()}/.env.${Date.now().toString(16)}`;
let content = "";
for (const [key, value] of cfg.entries()) {
content += `${key}=${value}\n`;
}
fs.writeFileSync(tmpFile, content);
// console.log('Wrote', tmpFile)
return tmpFile;
};
let dotenv;
module.exports = function (options) {
const t = options.types;
return {
visitor: {
MemberExpression: function MemberExpression(path, state) {
if (
t.isAssignmentExpression(path.parent) &&
path.parent.left === path.node
)
return;
if (path.get("object").matchesPattern("process.env")) {
if (!dotenv) {
const configDir = nodepath.dirname(state.opts.path);
const cfgDefault = parse(nodepath.join(configDir, ".env.defaults"));
const cfgEnv = parse(state.opts.path);
const cfg = mergeCfg([cfgDefault, cfgEnv]);
const tmpFile = write(cfg);
state.opts.path = tmpFile;
dotenv = require("dotenv").config(state.opts);
let dotenvExpand;
try {
dotenvExpand = require("dotenv-expand");
} catch (e) {}
if (dotenvExpand) dotenvExpand(dotenv);
if (fs.existsSync(tmpFile)) fs.unlinkSync(tmpFile);
else console.log(`Temporary file ${tmpFile} not found`);
console.log("babel-plugin-inline-env: ", dotenv.parsed);
}
const key = path.toComputedKey();
if (t.isStringLiteral(key)) {
const name = key.value;
const value =
state.opts.env && name in state.opts.env
? state.opts.env[name]
: process.env[name];
const me = t.memberExpression;
const i = t.identifier;
const le = t.logicalExpression;
path.replaceWith(
le(
"||",
le(
"&&",
le("&&", i("process"), me(i("process"), i("env"))),
me(i("process.env"), i(name))
),
t.valueToNode(value)
)
);
}
}
},
},
};
};