@dotenvx/dotenvx 0.17.1 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -56,6 +56,18 @@ see [extended quickstart guide](https://dotenvx.com/docs/quickstart)
56
56
 
57
57
  More examples
58
58
 
59
+ * <details><summary>TypeScript 📘</summary><br>
60
+
61
+ ```sh
62
+ $ echo "HELLO=World" > .env
63
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.ts
64
+
65
+ $ dotenvx run -- npx ts-node index.ts
66
+ Hello World
67
+ ```
68
+
69
+ </details>
70
+
59
71
  * <details><summary>Python 🐍</summary><br>
60
72
 
61
73
  ```sh
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.17.1",
2
+ "version": "0.19.0",
3
3
  "name": "@dotenvx/dotenvx",
4
4
  "description": "a better dotenv–from the creator of `dotenv`",
5
5
  "author": "@motdotla",
@@ -7,20 +7,6 @@ const helpers = require('./../helpers')
7
7
  const createSpinner = require('./../../shared/createSpinner')
8
8
  const spinner = createSpinner('encrypting')
9
9
 
10
- const RESERVED_ENV_FILES = ['.env.vault', '.env.project', '.env.keys', '.env.me', '.env.x']
11
-
12
- const findEnvFiles = function (directory) {
13
- const files = fs.readdirSync(directory)
14
-
15
- const envFiles = files.filter(file =>
16
- file.startsWith('.env') &&
17
- !file.endsWith('.previous') &&
18
- !RESERVED_ENV_FILES.includes(file)
19
- )
20
-
21
- return envFiles
22
- }
23
-
24
10
  async function encrypt (directory) {
25
11
  spinner.start()
26
12
  await helpers.sleep(500) // better dx
@@ -30,8 +16,6 @@ async function encrypt (directory) {
30
16
  const options = this.opts()
31
17
  logger.debug(`options: ${JSON.stringify(options)}`)
32
18
 
33
- const optionEnvFile = options.envFile || findEnvFiles(directory)
34
-
35
19
  try {
36
20
  const {
37
21
  dotenvKeys,
@@ -41,10 +25,11 @@ async function encrypt (directory) {
41
25
  dotenvVaultFile,
42
26
  addedVaults,
43
27
  existingVaults,
44
- addedDotenvFilenames
45
- } = main.encrypt(directory, optionEnvFile)
28
+ addedDotenvFilenames,
29
+ envFile
30
+ } = main.encrypt(directory, options.envFile)
46
31
 
47
- logger.verbose(`generating .env.keys from ${optionEnvFile}`)
32
+ logger.verbose(`generating .env.keys from ${envFile}`)
48
33
  if (addedKeys.length > 0) {
49
34
  logger.verbose(`generated ${addedKeys}`)
50
35
  }
@@ -53,7 +38,7 @@ async function encrypt (directory) {
53
38
  }
54
39
  fs.writeFileSync(path.resolve(directory, '.env.keys'), dotenvKeysFile)
55
40
 
56
- logger.verbose(`generating .env.vault from ${optionEnvFile}`)
41
+ logger.verbose(`generating .env.vault from ${envFile}`)
57
42
  if (addedVaults.length > 0) {
58
43
  logger.verbose(`encrypting ${addedVaults}`)
59
44
  }
@@ -66,7 +51,7 @@ async function encrypt (directory) {
66
51
  spinner.succeed(`encrypted to .env.vault (${addedDotenvFilenames})`)
67
52
  logger.help2('ℹ commit .env.vault to code: [git commit -am ".env.vault"]')
68
53
  } else {
69
- spinner.done(`no changes (${optionEnvFile})`)
54
+ spinner.done(`no changes (${envFile})`)
70
55
  }
71
56
 
72
57
  if (addedKeys.length > 0) {
@@ -0,0 +1,24 @@
1
+ const logger = require('./../../shared/logger')
2
+
3
+ const main = require('./../../lib/main')
4
+
5
+ function get (key) {
6
+ logger.debug(`key: ${key}`)
7
+
8
+ const options = this.opts()
9
+ logger.debug(`options: ${JSON.stringify(options)}`)
10
+
11
+ const value = main.get(key, options.envFile, options.overload, options.all)
12
+
13
+ if (typeof value === 'object' && value !== null) {
14
+ if (options.prettyPrint) {
15
+ logger.blank(JSON.stringify(value, null, 2))
16
+ } else {
17
+ logger.blank(value)
18
+ }
19
+ } else {
20
+ logger.blank(value)
21
+ }
22
+ }
23
+
24
+ module.exports = get
@@ -0,0 +1,27 @@
1
+ const execa = require('execa')
2
+
3
+ const logger = require('./../../shared/logger')
4
+
5
+ async function scan () {
6
+ const options = this.opts()
7
+ logger.debug(`options: ${JSON.stringify(options)}`)
8
+
9
+ try {
10
+ await execa('gitleaks', ['version'])
11
+ } catch (error) {
12
+ logger.error('gitleaks command not found')
13
+ logger.help('? install gitleaks: [brew install gitleaks]')
14
+ logger.help2('? other install options: [https://github.com/gitleaks/gitleaks]')
15
+ process.exit(1)
16
+ }
17
+
18
+ try {
19
+ const { stderr } = await execa('gitleaks', ['detect', '-v'])
20
+ logger.blank(stderr) // gitleaks sends output as stderr for strange reason
21
+ } catch (error) {
22
+ logger.error(error.message)
23
+ process.exit(1)
24
+ }
25
+ }
26
+
27
+ module.exports = scan
@@ -97,6 +97,11 @@ program.command('genexample')
97
97
  .option('-f, --env-file <paths...>', 'path(s) to your env file(s)', '.env')
98
98
  .action(require('./actions/genexample'))
99
99
 
100
+ // dotenvx scan
101
+ program.command('scan')
102
+ .description('scan for leaked secrets')
103
+ .action(require('./actions/scan'))
104
+
100
105
  // dotenvx ls
101
106
  program.command('ls')
102
107
  .description('print all .env files in a tree structure')
@@ -104,6 +109,16 @@ program.command('ls')
104
109
  .option('-f, --env-file <filenames...>', 'path(s) to your env file(s)', '.env*')
105
110
  .action(require('./actions/ls'))
106
111
 
112
+ // dotenvx get
113
+ program.command('get')
114
+ .description('Return environment variable(s)')
115
+ .argument('[key]', 'environment variable name')
116
+ .option('-f, --env-file <paths...>', 'path(s) to your env file(s)', '.env')
117
+ .option('-o, --overload', 'override existing env variables')
118
+ .option('-a, --all', 'include all machine envs as well')
119
+ .option('-pp, --pretty-print', 'pretty print output')
120
+ .action(require('./actions/get'))
121
+
107
122
  // dotenvx hub
108
123
  program.addCommand(require('./commands/hub'))
109
124
 
package/src/lib/main.js CHANGED
@@ -5,6 +5,7 @@ const dotenvExpand = require('dotenv-expand')
5
5
  // services
6
6
  const Encrypt = require('./services/encrypt')
7
7
  const Ls = require('./services/ls')
8
+ const Get = require('./services/get')
8
9
 
9
10
  const config = function (options) {
10
11
  return dotenv.config(options)
@@ -114,6 +115,10 @@ const ls = function (directory, envFile) {
114
115
  return new Ls(directory, envFile).run()
115
116
  }
116
117
 
118
+ const get = function (key, envFile, overload, all) {
119
+ return new Get(key, envFile, overload, all).run()
120
+ }
121
+
117
122
  module.exports = {
118
123
  config,
119
124
  configDotenv,
@@ -121,6 +126,7 @@ module.exports = {
121
126
  parse,
122
127
  parseExpand,
123
128
  inject,
129
+ encrypt,
124
130
  ls,
125
- encrypt
131
+ get
126
132
  }
@@ -6,11 +6,12 @@ const DotenvKeys = require('./../helpers/dotenvKeys')
6
6
  const DotenvVault = require('./../helpers/dotenvVault')
7
7
 
8
8
  const ENCODING = 'utf8'
9
+ const RESERVED_ENV_FILES = ['.env.vault', '.env.project', '.env.keys', '.env.me', '.env.x']
9
10
 
10
11
  class Encrypt {
11
- constructor (directory = '.', envFile = '.env') {
12
+ constructor (directory = '.', envFile) {
12
13
  this.directory = directory
13
- this.envFile = envFile
14
+ this.envFile = envFile || this._findEnvFiles()
14
15
  // calculated
15
16
  this.envKeysFilepath = path.resolve(this.directory, '.env.keys')
16
17
  this.envVaultFilepath = path.resolve(this.directory, '.env.vault')
@@ -83,7 +84,8 @@ class Encrypt {
83
84
  dotenvVaultFile,
84
85
  addedVaults,
85
86
  existingVaults,
86
- addedDotenvFilenames
87
+ addedDotenvFilenames,
88
+ envFile: this.envFile
87
89
  }
88
90
  }
89
91
 
@@ -110,6 +112,17 @@ class Encrypt {
110
112
 
111
113
  return dotenv.configDotenv(options).parsed
112
114
  }
115
+
116
+ _findEnvFiles () {
117
+ const files = fs.readdirSync(this.directory)
118
+ const envFiles = files.filter(file =>
119
+ file.startsWith('.env') &&
120
+ !file.endsWith('.previous') &&
121
+ !RESERVED_ENV_FILES.includes(file)
122
+ )
123
+
124
+ return envFiles
125
+ }
113
126
  }
114
127
 
115
128
  module.exports = Encrypt
@@ -0,0 +1,47 @@
1
+ const dotenv = require('dotenv')
2
+ const dotenvExpand = require('dotenv-expand')
3
+
4
+ class Get {
5
+ constructor (key, envFile = '.env', overload = false, all = false) {
6
+ this.key = key
7
+ this.envFile = envFile
8
+ this.overload = overload
9
+ this.all = all
10
+ }
11
+
12
+ run () {
13
+ const clonedEnv = { ...process.env }
14
+ const options = {
15
+ processEnv: clonedEnv,
16
+ path: this.envFile,
17
+ override: this.overload
18
+ }
19
+ const parsed = dotenv.config(options).parsed
20
+
21
+ const expandedEnv = { ...clonedEnv }
22
+ const expandOptions = {
23
+ processEnv: expandedEnv,
24
+ parsed
25
+ }
26
+ dotenvExpand.expand(expandOptions)
27
+
28
+ if (!this.key) {
29
+ // if user wants to return ALL envs (even prior set on machine)
30
+ if (this.all) {
31
+ return expandedEnv
32
+ }
33
+
34
+ // typical scenario - return only envs that were identified in the .env file
35
+ const result = {}
36
+ for (const key of Object.keys(parsed)) {
37
+ result[key] = expandedEnv[key]
38
+ }
39
+
40
+ return result
41
+ }
42
+
43
+ return expandedEnv[this.key]
44
+ }
45
+ }
46
+
47
+ module.exports = Get