@dotenvx/dotenvx 0.15.4 → 0.16.1

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/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.15.4",
2
+ "version": "0.16.1",
3
3
  "name": "@dotenvx/dotenvx",
4
4
  "description": "a better dotenv–from the creator of `dotenv`",
5
5
  "author": "@motdotla",
@@ -21,7 +21,9 @@
21
21
  "scripts": {
22
22
  "standard": "standard",
23
23
  "standard:fix": "standard --fix",
24
- "test": "jest --verbose"
24
+ "test": "tap 'tests/**/*.test.js' --100",
25
+ "prerelease": "npm test",
26
+ "release": "standard-version"
25
27
  },
26
28
  "funding": "Have you seen dotenvx.com? run anywhere, cross-platform, and encrypted envs.",
27
29
  "dependencies": {
@@ -30,10 +32,12 @@
30
32
  "clipboardy": "^2.3.0",
31
33
  "commander": "^11.1.0",
32
34
  "conf": "^10.2.0",
33
- "dotenv": "^16.4.2",
34
- "dotenv-expand": "^11.0.3",
35
+ "dotenv": "^16.4.5",
36
+ "dotenv-expand": "^11.0.6",
35
37
  "execa": "^5.1.1",
38
+ "glob": "^10.3.10",
36
39
  "ignore": "^5.3.0",
40
+ "object-treeify": "1.1.33",
37
41
  "open": "^8.4.2",
38
42
  "ora": "^5.4.1",
39
43
  "undici": "^5.28.3",
@@ -42,15 +46,13 @@
42
46
  "xxhashjs": "^0.2.2"
43
47
  },
44
48
  "devDependencies": {
45
- "jest": "^29.7.0",
46
- "jest-mock-process": "^2.0.0",
49
+ "capture-console": "^1.0.2",
47
50
  "pkg": "^5.8.1",
48
- "standard": "^17.1.0"
49
- },
50
- "standard": {
51
- "env": [
52
- "jest"
53
- ]
51
+ "proxyquire": "^2.1.3",
52
+ "sinon": "^14.0.1",
53
+ "standard": "^17.1.0",
54
+ "standard-version": "^9.5.0",
55
+ "tap": "^16.3.0"
54
56
  },
55
57
  "publishConfig": {
56
58
  "access": "public"
@@ -0,0 +1,24 @@
1
+ const treeify = require('object-treeify')
2
+
3
+ const logger = require('./../../shared/logger')
4
+
5
+ const main = require('./../../lib/main')
6
+ const ArrayToTree = require('./../../lib/helpers/arrayToTree')
7
+
8
+ function ls (directory) {
9
+ // debug args
10
+ logger.debug(`directory: ${directory}`)
11
+
12
+ const options = this.opts()
13
+ logger.debug(`options: ${JSON.stringify(options)}`)
14
+
15
+ const filepaths = main.ls(directory, options.envFile)
16
+ logger.debug(`filepaths: ${JSON.stringify(filepaths)}`)
17
+
18
+ const tree = new ArrayToTree(filepaths).run()
19
+ logger.debug(`tree: ${JSON.stringify(tree)}`)
20
+
21
+ logger.info(treeify(tree))
22
+ }
23
+
24
+ module.exports = ls
@@ -1,15 +1,20 @@
1
1
  const fs = require('fs')
2
2
  const path = require('path')
3
-
4
3
  const ignore = require('ignore')
5
4
 
6
5
  const logger = require('./../../shared/logger')
6
+
7
7
  const helpers = require('./../helpers')
8
8
 
9
+ const Precommit = require('./../../lib/services/precommit')
10
+
9
11
  function precommit () {
10
12
  const options = this.opts()
11
13
  logger.debug(`options: ${JSON.stringify(options)}`)
12
14
 
15
+ const precommit = new Precommit(options)
16
+ precommit.run()
17
+
13
18
  // 0. handle the --install flag
14
19
  if (options.install) {
15
20
  installPrecommitHook()
@@ -14,7 +14,8 @@ async function run () {
14
14
 
15
15
  // load from .env.vault file
16
16
  if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {
17
- const filepath = helpers.resolvePath('.env.vault')
17
+ const envVaultFilepath = options.envVaultFile // .env.vault
18
+ const filepath = helpers.resolvePath(envVaultFilepath)
18
19
 
19
20
  if (!fs.existsSync(filepath)) {
20
21
  logger.error(`you set DOTENV_KEY but your .env.vault file is missing: ${filepath}`)
@@ -56,7 +57,7 @@ async function run () {
56
57
  const parsed = main.parseExpand(decrypted)
57
58
  const result = main.inject(process.env, parsed, options.overload)
58
59
 
59
- logger.successv(`injecting env (${result.injected.size}) from encrypted .env.vault`)
60
+ logger.successv(`injecting env (${result.injected.size}) from encrypted ${envVaultFilepath}`)
60
61
  } catch (e) {
61
62
  logger.error(e)
62
63
  }
@@ -56,6 +56,7 @@ program.command('run')
56
56
  .description('inject env at runtime [dotenvx run -- yourcommand]')
57
57
  .addHelpText('after', examples.run)
58
58
  .option('-f, --env-file <paths...>', 'path(s) to your env file(s)', '.env')
59
+ .option('-fv, --env-vault-file <path>', 'path to your .env.vault file', '.env.vault')
59
60
  .option('-o, --overload', 'override existing env variables')
60
61
  .action(require('./actions/run'))
61
62
 
@@ -96,6 +97,13 @@ program.command('genexample')
96
97
  .option('-f, --env-file <paths...>', 'path(s) to your env file(s)', '.env')
97
98
  .action(require('./actions/genexample'))
98
99
 
100
+ // dotenvx ls
101
+ program.command('ls')
102
+ .description('print all .env files in a tree structure')
103
+ .argument('[directory]', 'directory to list .env files from', '.')
104
+ .option('-f, --env-file <filenames...>', 'path(s) to your env file(s)', '.env*')
105
+ .action(require('./actions/ls'))
106
+
99
107
  // dotenvx hub
100
108
  program.addCommand(require('./commands/hub'))
101
109
 
@@ -0,0 +1,24 @@
1
+ class ArrayToTree {
2
+ constructor (arr) {
3
+ this.arr = arr
4
+ }
5
+
6
+ run () {
7
+ const tree = {}
8
+
9
+ for (let i = 0; i < this.arr.length; i++) {
10
+ const parts = this.arr[i].split('/')
11
+ let current = tree
12
+
13
+ for (let j = 0; j < parts.length; j++) {
14
+ const part = parts[j]
15
+ current[part] = current[part] || {}
16
+ current = current[part]
17
+ }
18
+ }
19
+
20
+ return tree
21
+ }
22
+ }
23
+
24
+ module.exports = ArrayToTree
@@ -0,0 +1,63 @@
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+
4
+ const logger = require('./../../shared/logger')
5
+
6
+ const HOOK_SCRIPT = `#!/bin/sh
7
+
8
+ if ! command -v dotenvx &> /dev/null
9
+ then
10
+ echo "[dotenvx][precommit] 'dotenvx' command not found"
11
+ echo "[dotenvx][precommit] ? install it with [brew install dotenvx/brew/dotenvx]"
12
+ echo "[dotenvx][precommit] ? other install options [https://dotenvx.com/docs/install]"
13
+ exit 1
14
+ fi
15
+
16
+ dotenvx precommit`
17
+
18
+ class InstallPrecommitHook {
19
+ constructor () {
20
+ this.hookPath = path.join('.git', 'hooks', 'pre-commit')
21
+ }
22
+
23
+ run () {
24
+ try {
25
+ // Check if the pre-commit file already exists
26
+ if (this._exists()) {
27
+ // Check if 'dotenvx precommit' already exists in the file
28
+ if (!this._currentHook().includes('dotenvx precommit')) {
29
+ this._appendHook()
30
+ } else {
31
+ logger.warnvp(`dotenvx precommit exists [${this.hookPath}]`)
32
+ }
33
+ } else {
34
+ this._createHook()
35
+ }
36
+ } catch (err) {
37
+ logger.errorvp(`failed to modify pre-commit hook: ${err.message}`)
38
+ }
39
+ }
40
+
41
+ _exists () {
42
+ return fs.existsSync(this.hookPath)
43
+ }
44
+
45
+ _currentHook () {
46
+ return fs.readFileSync(this.hookPath, 'utf8')
47
+ }
48
+
49
+ _createHook () {
50
+ // If the pre-commit file doesn't exist, create a new one with the hookScript
51
+ fs.writeFileSync(this.hookPath, HOOK_SCRIPT)
52
+ fs.chmodSync(this.hookPath, '755') // Make the file executable
53
+ logger.successvp(`dotenvx precommit installed [${this.hookPath}]`)
54
+ }
55
+
56
+ _appendHook () {
57
+ // Append 'dotenvx precommit' to the existing file
58
+ fs.appendFileSync(this.hookPath, '\n' + HOOK_SCRIPT)
59
+ logger.successvp(`dotenvx precommit appended [${this.hookPath}]`)
60
+ }
61
+ }
62
+
63
+ module.exports = InstallPrecommitHook
package/src/lib/main.js CHANGED
@@ -2,6 +2,9 @@ const logger = require('./../shared/logger')
2
2
  const dotenv = require('dotenv')
3
3
  const dotenvExpand = require('dotenv-expand')
4
4
 
5
+ // services
6
+ const Ls = require('./services/ls')
7
+
5
8
  const config = function (options) {
6
9
  return dotenv.config(options)
7
10
  }
@@ -56,9 +59,7 @@ const parseExpand = function (src, overload) {
56
59
  // but then for logging only log the original keys existing in parsed. this feels unnecessarily complex - like dotenv-expand should support the ability to inject additional `process.env` or objects as it sees fit to the object it wants to expand
57
60
  const result = {}
58
61
  for (const key in parsed) {
59
- if (Object.prototype.hasOwnProperty.call(expanded, key)) {
60
- result[key] = expanded[key]
61
- }
62
+ result[key] = expanded[key]
62
63
  }
63
64
 
64
65
  logger.debug(result)
@@ -104,11 +105,16 @@ const inject = function (processEnv = {}, parsed = {}, overload = false) {
104
105
  }
105
106
  }
106
107
 
108
+ const ls = function (directory, envFile) {
109
+ return new Ls(directory, envFile).run()
110
+ }
111
+
107
112
  module.exports = {
108
113
  config,
109
114
  configDotenv,
110
115
  decrypt,
111
116
  parse,
112
117
  parseExpand,
113
- inject
118
+ inject,
119
+ ls
114
120
  }
@@ -0,0 +1,41 @@
1
+ const path = require('path')
2
+ const globSync = require('glob').globSync
3
+
4
+ class Ls {
5
+ constructor (directory = './', envFile = '.env*') {
6
+ this.ignore = ['node_modules/**', '.git/**']
7
+
8
+ this.cwd = path.resolve(directory)
9
+ this.envFile = envFile
10
+ }
11
+
12
+ run () {
13
+ return this._filepaths()
14
+ }
15
+
16
+ _filepaths () {
17
+ const options = {
18
+ ignore: this.ignore,
19
+ cwd: this.cwd // context dirctory for globSync
20
+ }
21
+
22
+ const patterns = this._patterns()
23
+ return globSync(patterns, options)
24
+ }
25
+
26
+ _patterns () {
27
+ if (!Array.isArray(this.envFile)) {
28
+ return `**/${this.envFile}`
29
+ }
30
+
31
+ const out = []
32
+
33
+ for (let i = 0; i < this.envFile.length; i++) {
34
+ const part = this.envFile[i]
35
+ out.push(`**/${part}`)
36
+ }
37
+ return out
38
+ }
39
+ }
40
+
41
+ module.exports = Ls
@@ -0,0 +1,26 @@
1
+ const logger = require('./../../shared/logger')
2
+
3
+ const InstallPrecommitHook = require('./../helpers/installPrecommitHook')
4
+
5
+ class Precommit {
6
+ constructor (options = {}) {
7
+ this.install = options.install
8
+ }
9
+
10
+ run () {
11
+ if (this.install) {
12
+ this._installPrecommitHook()
13
+
14
+ return true
15
+ }
16
+
17
+ logger.info('implement')
18
+ }
19
+
20
+ /* istanbul ignore next */
21
+ _installPrecommitHook () {
22
+ new InstallPrecommitHook().run()
23
+ }
24
+ }
25
+
26
+ module.exports = Precommit
@@ -83,8 +83,6 @@ const dotenvxFormat = printf(({ level, message, label, timestamp }) => {
83
83
  return debug(formattedMessage)
84
84
  case 'blank': // custom
85
85
  return formattedMessage
86
- default: // handle uncaught
87
- return formattedMessage
88
86
  }
89
87
  })
90
88