Skip to content

Commit 480db73

Browse files
authored
Merge pull request #22 from Platane/master
add option on how to merge env var from system
2 parents 41c18bd + b0b3bda commit 480db73

File tree

16 files changed

+976
-11
lines changed

16 files changed

+976
-11
lines changed

.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
EXAMPLE_ENV_VAR="simple example"
2+
EXAMPLE_ENV_VAR_SYSTEM="default"
23
EXAMPLE_ENV_VAR_EXPAND=$EXAMPLE_ENV_VAR-expand

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,22 @@ To replace with env value without `process && process.env && process.env.MY_VARI
5454
}
5555
```
5656

57+
The plugin support 3 mode to read the env var from the system :
58+
59+
```js
60+
{
61+
"plugins": [["inline-dotenv",{
62+
systemVar: 'all' | 'overwrite' | 'disable'
63+
}]]
64+
}
65+
```
66+
67+
- `all` _default_, every env var found in process.env will be used
68+
> ⚠️ This could leak super secret stuffs !
69+
70+
- `overwrite`, the value in process.env will overwrite the one present in .env only. Your .env file act as a whitelist
71+
72+
- `disable`, the process.env will not be used at all
5773

5874
### Via CLI
5975

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "Load your `.env` file and replace `process.env.MY_VARIABLE` with the value you set.",
55
"main": "src/index.js",
66
"scripts": {
7-
"test": "mocha --require babel-core/register",
7+
"test": "EXAMPLE_ENV_VAR_SYSTEM=system EXAMPLE_ENV_VAR_SECRET=secret mocha --require babel-core/register",
88
"test:watch": "npm run test -- --watch"
99
},
1010
"repository": {
@@ -31,7 +31,7 @@
3131
"babel-eslint": "^9.0.0",
3232
"babel-preset-es2015": "^6.1.18",
3333
"babel-register": "^6.2.0",
34-
"dotenv-expand": "^5.0.0",
34+
"dotenv-expand": "^5.1.0",
3535
"mocha": "^6.0.0"
3636
}
3737
}

src/index.js

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,29 @@
11
"use strict";
22

3-
var dotenv;
3+
var fs = require('fs');
4+
var pathResolve = require('path').resolve;
5+
6+
var dotenvContent;
7+
8+
function getValue(dotenvContent, systemContent, opts, name) {
9+
if (opts.env && name in opts.env) return opts.env[name];
10+
11+
switch (opts.systemVar) {
12+
case "overwrite":
13+
if (name in dotenvContent && name in systemContent)
14+
return systemContent[name];
15+
if (name in dotenvContent) return dotenvContent[name];
16+
return;
17+
case "disable":
18+
if (name in dotenvContent) return dotenvContent[name];
19+
return;
20+
case "all":
21+
default:
22+
if (name in systemContent) return systemContent[name];
23+
if (name in dotenvContent) return dotenvContent[name];
24+
return;
25+
}
26+
}
427

528
module.exports = function (options) {
629
var t = options.types;
@@ -10,17 +33,29 @@ module.exports = function (options) {
1033
MemberExpression: function MemberExpression(path, state) {
1134
if(t.isAssignmentExpression(path.parent) && path.parent.left == path.node) return;
1235
if (path.get("object").matchesPattern("process.env")) {
13-
if (!dotenv) {
14-
dotenv = require('dotenv').config(state.opts);
36+
if (!dotenvContent) {
37+
var dotenvPath = pathResolve(process.cwd(), '.env')
38+
var encoding = 'utf8'
39+
var debug = false
40+
if (state.opts.path != null) {
41+
dotenvPath = state.opts.path
42+
}
43+
if (state.opts.encoding != null) {
44+
encoding = state.opts.encoding
45+
}
46+
if (state.opts.debug != null) {
47+
debug = true
48+
}
49+
dotenvContent = require('dotenv').parse(fs.readFileSync(dotenvPath, {encoding:encoding}), {debug:debug});
1550
var dotenvExpand;
1651
try { dotenvExpand = require('dotenv-expand'); } catch(e) {}
1752
if (dotenvExpand)
18-
dotenvExpand(dotenv);
53+
dotenvContent = dotenvExpand({parsed:dotenvContent, ignoreProcessEnv:true}).parsed;
1954
}
2055
var key = path.toComputedKey();
2156
if (t.isStringLiteral(key)) {
2257
var name = key.value;
23-
var value = state.opts.env && name in state.opts.env ? state.opts.env[name] : process.env[name];
58+
var value = getValue(dotenvContent, process.env, state.opts, name)
2459
var me = t.memberExpression;
2560
var i = t.identifier;
2661
var le = t.logicalExpression;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"plugins": [
3+
["../../../src", {
4+
"systemVar" : "disable",
5+
"transforms": [{
6+
"transform": "transform-lib"
7+
}]
8+
}]
9+
]
10+
}
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
"use strict";
2+
3+
// Example 1: Creating a new class (declaration-form)
4+
// ===============================================================
5+
6+
// A base class is defined using the new reserved 'class' keyword
7+
8+
const EXAMPLE_ENV_VAR = process.env.EXAMPLE_ENV_VAR;
9+
const EXAMPLE_ENV_VAR_EXPAND = process.env.EXAMPLE_ENV_VAR_EXPAND;
10+
const EXAMPLE_ENV_VAR_SECRET = process.env.EXAMPLE_ENV_VAR_SECRET;
11+
const EXAMPLE_ENV_VAR_SYSTEM = process.env.EXAMPLE_ENV_VAR_SYSTEM;
12+
13+
class Polygon {
14+
// ..and an (optional) custom class constructor. If one is
15+
// not supplied, a default constructor is used instead:
16+
// constructor() { }
17+
constructor(height, width) {
18+
this.name = "Polygon";
19+
this.height = height;
20+
this.width = width;
21+
}
22+
23+
// Simple class instance methods using short-hand method
24+
// declaration
25+
sayName() {
26+
console.log("Hi, I am a ", this.name + ".");
27+
}
28+
29+
sayHistory() {
30+
console.log(`
31+
"Polygon" is derived from the Greek polus (many) and gonia (angle).
32+
`);
33+
}
34+
35+
// We will look at static and subclassed methods shortly
36+
}
37+
38+
// Classes are used just like ES5 constructor functions:
39+
let p = new Polygon(300, 400);
40+
p.sayName();
41+
console.log("The width of this polygon is " + p.width);
42+
43+
// Example 2: Creating a new class (expression-form)
44+
// ===============================================================
45+
46+
// Our Polygon class above is an example of a Class declaration.
47+
// ES6 classes also support Class expressions - just another way
48+
// of defining a new class. For example:
49+
const MyPoly = class Poly {
50+
getPolyName() {
51+
console.log(`
52+
Hi. I was created with a Class expression. My name is ${Poly.name}
53+
`);
54+
}
55+
};
56+
57+
let inst = new MyPoly();
58+
inst.getPolyName();
59+
60+
// Example 3: Extending an existing class
61+
// ===============================================================
62+
63+
// Classes support extending other classes, but can also extend
64+
// other objects. Whatever you extend must be a constructor.
65+
//
66+
// Let's extend the Polygon class to create a new derived class
67+
// called Square.
68+
class Square extends Polygon {
69+
constructor(length) {
70+
// The reserved 'super' keyword is for making super-constructor
71+
// calls and allows access to parent methods.
72+
//
73+
// Here, it will call the parent class' constructor with lengths
74+
// provided for the Polygon's width and height
75+
super(length, length);
76+
// Note: In derived classes, super() must be called before you
77+
// can use 'this'. Leaving this out will cause a reference error.
78+
this.name = "Square";
79+
}
80+
81+
// Getter/setter methods are supported in classes,
82+
// similar to their ES5 equivalents
83+
get area() {
84+
return this.height * this.width;
85+
}
86+
87+
set area(value) {
88+
this.area = value;
89+
}
90+
}
91+
92+
let s = new Square(5);
93+
94+
s.sayName();
95+
console.log("The area of this square is " + s.area);
96+
97+
// Example 4: Subclassing methods of a parent class
98+
// ===============================================================
99+
100+
class Rectangle extends Polygon {
101+
constructor(height, width) {
102+
super(height, width);
103+
this.name = "Rectangle";
104+
}
105+
// Here, sayName() is a subclassed method which
106+
// overrides their superclass method of the same name.
107+
sayName() {
108+
console.log("Sup! My name is ", this.name + ".");
109+
super.sayHistory();
110+
}
111+
}
112+
113+
let r = new Rectangle(50, 60);
114+
r.sayName();
115+
116+
// Example 5: Defining static methods
117+
// ===============================================================
118+
119+
// Classes support static members which can be accessed without an
120+
// instance being present.
121+
class Triple {
122+
// Using the 'static' keyword creates a method which is associated
123+
// with a class, but not with an instance of the class.
124+
static triple(n) {
125+
n = n || 1;
126+
return n * 3;
127+
}
128+
}
129+
130+
// super.prop in this example is used for accessing super-properties from
131+
// a parent class. This works fine in static methods too:
132+
class BiggerTriple extends Triple {
133+
static triple(n) {
134+
return super.triple(n) * super.triple(n);
135+
}
136+
}
137+
138+
console.log(Triple.triple());
139+
console.log(Triple.triple(6));
140+
console.log(BiggerTriple.triple(3));
141+
// var tp = new Triple();
142+
// console.log(tp.triple()); tp.triple is not a function
143+
144+
// Example 6: Subclassing built-in classes and DOM
145+
// ===============================================================
146+
147+
// Extend Date built-in
148+
class MyDate extends Date {
149+
constructor() {
150+
super();
151+
}
152+
153+
getFormattedDate() {
154+
const m1 = ["Jan", "Feb", "Mar"];
155+
const m2 = ["Apr", "May", "Jun"];
156+
const m3 = ["Jul", "Aug", "Sep"];
157+
const m4 = ["Oct", "Nov", "Dec"];
158+
var months = [...m1, ...m2, ...m3, ...m4];
159+
const month = months.getMonth();
160+
const date = this.getDate();
161+
const year = this.getFullYear();
162+
return `${date}-${month}-${year}`;
163+
}
164+
}
165+
166+
var aDate = new MyDate();
167+
console.log(aDate.getTime());
168+
console.log(aDate.getFormattedDate());
169+
170+
// Extend Uint8Array
171+
class ExtendedUint8Array extends Uint8Array {
172+
constructor() {
173+
super(10);
174+
this[0] = 255;
175+
this[1] = 0xffa;
176+
}
177+
}
178+
179+
var eua = new ExtendedUint8Array();
180+
console.log(eua.byteLength);
181+
182+
// Extend DOM Audio element
183+
class MyAudio extends Audio {
184+
constructor() {
185+
super();
186+
this._lyrics = "";
187+
}
188+
189+
get lyrics() {
190+
return this._lyrics;
191+
}
192+
193+
set lyrics(str) {
194+
this._lyrics = str;
195+
}
196+
}
197+
198+
var player = new MyAudio();
199+
player.controls = true;
200+
player.lyrics = "Never gonna give you up";
201+
document.querySelector("body").appendChild(player);
202+
console.log(player.lyrics);
203+
204+
// Note: The V8 in Chrome 42 supports subclassing built-ins but Arrays.
205+
// Subclassing arrays supported in Chrome 43.
206+
207+
class Stack extends Array {
208+
constructor() {
209+
super();
210+
}
211+
212+
top() {
213+
return this[this.length - 1];
214+
}
215+
}
216+
217+
var stack = new Stack();
218+
stack.push("world");
219+
stack.push("hello");
220+
console.log(stack.top());
221+
console.log(stack.length);

0 commit comments

Comments
 (0)