@dotenvx/dotenvx 1.3.2 → 1.5.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/CHANGELOG.md +22 -1
- package/README.md +12 -0
- package/package.json +2 -4
- package/src/cli/actions/ext/genexample.js +1 -1
- package/src/cli/actions/ext/vault/decrypt.js +1 -1
- package/src/cli/actions/ext/vault/encrypt.js +1 -1
- package/src/cli/commands/ext.js +42 -1
- package/src/cli/dotenvx.js +4 -10
- package/src/cli/examples.js +17 -1
- package/src/shared/confirm.js +12 -0
- package/src/shared/createSpinner.js +84 -4
- package/src/cli/actions/ext/hub/login.js +0 -126
- package/src/cli/actions/ext/hub/logout.js +0 -43
- package/src/cli/actions/ext/hub/open.js +0 -63
- package/src/cli/actions/ext/hub/pull.js +0 -105
- package/src/cli/actions/ext/hub/push.js +0 -112
- package/src/cli/actions/ext/hub/status.js +0 -8
- package/src/cli/actions/ext/hub/token.js +0 -9
- package/src/cli/commands/ext/hub.js +0 -89
- package/src/cli/commands/hub.js +0 -89
- package/src/lib/helpers/remoteVersion.js +0 -42
- package/src/lib/helpers/updateNotice/check.js +0 -29
- package/src/lib/helpers/updateNotice.js +0 -39
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
-
## [Unreleased](https://github.com/dotenvx/dotenvx/compare/v1.
|
|
5
|
+
## [Unreleased](https://github.com/dotenvx/dotenvx/compare/v1.5.0...main)
|
|
6
|
+
|
|
7
|
+
## 1.5.0
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
* add help text for dashed values on `set`. example: `dotenvx set KEY -- "- + * ÷"` ([#293](https://github.com/dotenvx/dotenvx/pull/293))
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
* replace `@inquirer/confirm` and `ora` ([#285](https://github.com/dotenvx/dotenvx/pull/285))
|
|
16
|
+
|
|
17
|
+
### Removed
|
|
18
|
+
|
|
19
|
+
* remove `dotenvx ext hub`, replace with [dotenvx-ext-hub](https://github.com/dotenvx/dotenvx-ext-hub) (install there to continue using hub) ([#291](https://github.com/dotenvx/dotenvx/pull/291))
|
|
20
|
+
|
|
21
|
+
## 1.4.0
|
|
22
|
+
|
|
23
|
+
### Removed
|
|
24
|
+
|
|
25
|
+
* remove update notice. let users decide what version they want without nagging them to update ([#288](https://github.com/dotenvx/dotenvx/pull/288))
|
|
26
|
+
* remove `dotenvx hub`. still available at `dotenvx ext hub` ([#290](https://github.com/dotenvx/dotenvx/pull/290))
|
|
6
27
|
|
|
7
28
|
## 1.3.2
|
|
8
29
|
|
package/README.md
CHANGED
|
@@ -1071,6 +1071,18 @@ More examples
|
|
|
1071
1071
|
set HELLO with encryption (.env.ci)
|
|
1072
1072
|
```
|
|
1073
1073
|
|
|
1074
|
+
</details>
|
|
1075
|
+
* <details><summary>`set KEY -- "- + * ÷"`</summary><br>
|
|
1076
|
+
|
|
1077
|
+
If your value starts with a dash (`-`), then place two dashes instructing the cli that there are no more flag arguments.
|
|
1078
|
+
|
|
1079
|
+
```sh
|
|
1080
|
+
$ touch .env.ci
|
|
1081
|
+
|
|
1082
|
+
$ dotenvx set HELLO -f .env.ci -- "- + * ÷"
|
|
1083
|
+
set HELLO with encryption (.env.ci)
|
|
1084
|
+
```
|
|
1085
|
+
|
|
1074
1086
|
</details>
|
|
1075
1087
|
* <details><summary>`set KEY value --plain`</summary><br>
|
|
1076
1088
|
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.5.0",
|
|
3
3
|
"name": "@dotenvx/dotenvx",
|
|
4
4
|
"description": "a better dotenv–from the creator of `dotenv`",
|
|
5
5
|
"author": "@motdotla",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"funding": "https://dotenvx.com",
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@
|
|
34
|
+
"@clack/core": "^0.3.4",
|
|
35
35
|
"arch": "^2.1.1",
|
|
36
36
|
"chalk": "^4.1.2",
|
|
37
37
|
"commander": "^11.1.0",
|
|
@@ -45,9 +45,7 @@
|
|
|
45
45
|
"is-wsl": "^2.1.1",
|
|
46
46
|
"object-treeify": "1.1.33",
|
|
47
47
|
"open": "^8.4.2",
|
|
48
|
-
"ora": "^5.4.1",
|
|
49
48
|
"picomatch": "^3.0.1",
|
|
50
|
-
"semver": "^7.3.4",
|
|
51
49
|
"undici": "^5.28.3",
|
|
52
50
|
"which": "^4.0.0",
|
|
53
51
|
"winston": "^3.11.0",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
const main = require('./../../../lib/main')
|
|
3
3
|
const { logger } = require('./../../../shared/logger')
|
|
4
|
-
const createSpinner = require('./../../../shared/createSpinner')
|
|
4
|
+
const { createSpinner } = require('./../../../shared/createSpinner')
|
|
5
5
|
|
|
6
6
|
const sleep = require('./../../../lib/helpers/sleep')
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
|
|
3
3
|
const { logger } = require('./../../../../shared/logger')
|
|
4
|
-
const createSpinner = require('./../../../../shared/createSpinner')
|
|
4
|
+
const { createSpinner } = require('./../../../../shared/createSpinner')
|
|
5
5
|
const sleep = require('./../../../../lib/helpers/sleep')
|
|
6
6
|
|
|
7
7
|
const Decrypt = require('./../../../../lib/services/decrypt')
|
|
@@ -3,7 +3,7 @@ const path = require('path')
|
|
|
3
3
|
|
|
4
4
|
const main = require('./../../../../lib/main')
|
|
5
5
|
const { logger } = require('./../../../../shared/logger')
|
|
6
|
-
const createSpinner = require('./../../../../shared/createSpinner')
|
|
6
|
+
const { createSpinner } = require('./../../../../shared/createSpinner')
|
|
7
7
|
const sleep = require('./../../../../lib/helpers/sleep')
|
|
8
8
|
const pluralize = require('./../../../../lib/helpers/pluralize')
|
|
9
9
|
|
package/src/cli/commands/ext.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
const path = require('path')
|
|
2
|
+
const { spawnSync } = require('child_process')
|
|
1
3
|
const { Command } = require('commander')
|
|
4
|
+
const { logger } = require('../../shared/logger')
|
|
2
5
|
|
|
3
6
|
const examples = require('./../examples')
|
|
4
7
|
|
|
@@ -6,6 +9,45 @@ const ext = new Command('ext')
|
|
|
6
9
|
|
|
7
10
|
ext
|
|
8
11
|
.description('🔌 extensions')
|
|
12
|
+
.allowUnknownOption()
|
|
13
|
+
|
|
14
|
+
ext.addHelpText('after', ' hub 🚫 DEPRECATED: to be replaced by [dotenvx pro]')
|
|
15
|
+
|
|
16
|
+
ext
|
|
17
|
+
.argument('[command]', 'dynamic ext command')
|
|
18
|
+
.argument('[args...]', 'dynamic ext command arguments')
|
|
19
|
+
.action((command, args, cmdObj) => {
|
|
20
|
+
if (!command) {
|
|
21
|
+
ext.outputHelp()
|
|
22
|
+
process.exit(1)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// construct the full command line manually including flags
|
|
26
|
+
const rawArgs = process.argv.slice(3) // adjust the index based on where actual args start
|
|
27
|
+
const commandIndex = rawArgs.indexOf(command)
|
|
28
|
+
const forwardedArgs = rawArgs.slice(commandIndex + 1)
|
|
29
|
+
|
|
30
|
+
logger.debug(`command: ${command}`)
|
|
31
|
+
logger.debug(`args: ${JSON.stringify(forwardedArgs)}`)
|
|
32
|
+
|
|
33
|
+
const binPath = path.join(process.cwd(), 'node_modules', '.bin')
|
|
34
|
+
const newPath = `${binPath}:${process.env.PATH}`
|
|
35
|
+
const env = { ...process.env, PATH: newPath }
|
|
36
|
+
|
|
37
|
+
const result = spawnSync(`dotenvx-ext-${command}`, forwardedArgs, { stdio: 'inherit', env })
|
|
38
|
+
if (result.error) {
|
|
39
|
+
if (command === 'hub') {
|
|
40
|
+
logger.warn(`[INSTALLATION_NEEDED] install dotenvx-ext-${command} to use [dotenvx ext ${command}] commands`)
|
|
41
|
+
logger.help('? see installation instructions [https://github.com/dotenvx/dotenvx-ext-hub]')
|
|
42
|
+
} else {
|
|
43
|
+
logger.info(`error: unknown command '${command}'`)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (result.status !== 0) {
|
|
48
|
+
process.exit(result.status)
|
|
49
|
+
}
|
|
50
|
+
})
|
|
9
51
|
|
|
10
52
|
// dotenvx ext ls
|
|
11
53
|
ext.command('ls')
|
|
@@ -53,6 +95,5 @@ ext.command('settings')
|
|
|
53
95
|
.action(require('./../actions/ext/settings'))
|
|
54
96
|
|
|
55
97
|
ext.addCommand(require('./../commands/ext/vault'))
|
|
56
|
-
ext.addCommand(require('./../commands/ext/hub'))
|
|
57
98
|
|
|
58
99
|
module.exports = ext
|
package/src/cli/dotenvx.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
const fs = require('fs')
|
|
4
4
|
const path = require('path')
|
|
5
5
|
const { execSync } = require('child_process')
|
|
6
|
-
const UpdateNotice = require('./../lib/helpers/updateNotice')
|
|
7
6
|
const { Command } = require('commander')
|
|
8
7
|
const program = new Command()
|
|
9
8
|
|
|
@@ -11,13 +10,6 @@ const { setLogLevel, logger } = require('../shared/logger')
|
|
|
11
10
|
const examples = require('./examples')
|
|
12
11
|
const packageJson = require('./../lib/helpers/packageJson')
|
|
13
12
|
|
|
14
|
-
// once a day check for any updates
|
|
15
|
-
const notice = new UpdateNotice()
|
|
16
|
-
notice.check()
|
|
17
|
-
if (notice.update) {
|
|
18
|
-
logger.warn(`Update available ${notice.packageVersion} → ${notice.latestVersion} 0.38.0 and higher have SIGNIFICANT changes. please read the changelog: https://dotenvx.com/changelog`)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
13
|
// for use with run
|
|
22
14
|
const envs = []
|
|
23
15
|
function collectEnvs (type) {
|
|
@@ -80,14 +72,17 @@ program.command('get')
|
|
|
80
72
|
})
|
|
81
73
|
|
|
82
74
|
// dotenvx set
|
|
75
|
+
const setAction = require('./actions/set')
|
|
83
76
|
program.command('set')
|
|
84
77
|
.description('set a single environment variable')
|
|
78
|
+
.addHelpText('after', examples.set)
|
|
79
|
+
.allowUnknownOption()
|
|
85
80
|
.argument('KEY', 'KEY')
|
|
86
81
|
.argument('value', 'value')
|
|
87
82
|
.option('-f, --env-file <paths...>', 'path(s) to your env file(s)', '.env')
|
|
88
83
|
.option('-c, --encrypt', 'encrypt value (default: true)', true)
|
|
89
84
|
.option('-p, --plain', 'store value as plain text', false)
|
|
90
|
-
.action(
|
|
85
|
+
.action(setAction)
|
|
91
86
|
|
|
92
87
|
// dotenvx encrypt
|
|
93
88
|
const encryptAction = require('./actions/encrypt')
|
|
@@ -124,7 +119,6 @@ program.addCommand(require('./commands/ext'))
|
|
|
124
119
|
//
|
|
125
120
|
// DEPRECATED AND hidden
|
|
126
121
|
//
|
|
127
|
-
program.addCommand(require('./commands/hub'))
|
|
128
122
|
program.addCommand(require('./commands/vault'))
|
|
129
123
|
|
|
130
124
|
program.command('convert')
|
package/src/cli/examples.js
CHANGED
|
@@ -100,10 +100,26 @@ Try it:
|
|
|
100
100
|
`
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
const set = function () {
|
|
104
|
+
return `
|
|
105
|
+
Examples:
|
|
106
|
+
|
|
107
|
+
\`\`\`
|
|
108
|
+
$ dotenvx set KEY value
|
|
109
|
+
$ dotenvx set KEY "value with spaces"
|
|
110
|
+
$ dotenvx set KEY -- "---value with a dash---"
|
|
111
|
+
$ dotenvx set KEY -- "-----BEGIN OPENSSH PRIVATE KEY-----
|
|
112
|
+
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
|
113
|
+
-----END OPENSSH PRIVATE KEY-----"
|
|
114
|
+
\`\`\`
|
|
115
|
+
`
|
|
116
|
+
}
|
|
117
|
+
|
|
103
118
|
module.exports = {
|
|
104
119
|
run,
|
|
105
120
|
vaultEncrypt,
|
|
106
121
|
precommit,
|
|
107
122
|
prebuild,
|
|
108
|
-
gitignore
|
|
123
|
+
gitignore,
|
|
124
|
+
set
|
|
109
125
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const { ConfirmPrompt } = require('@clack/core')
|
|
2
|
+
|
|
3
|
+
module.exports = (opts) => {
|
|
4
|
+
return new ConfirmPrompt({
|
|
5
|
+
active: 'Y',
|
|
6
|
+
inactive: 'N',
|
|
7
|
+
initialValue: true,
|
|
8
|
+
render () {
|
|
9
|
+
return `${opts.message} (${this.value ? 'Y/n' : 'y/N'})`
|
|
10
|
+
}
|
|
11
|
+
}).prompt()
|
|
12
|
+
}
|
|
@@ -1,8 +1,88 @@
|
|
|
1
|
-
const ora = require('ora')
|
|
2
1
|
const chalk = require('chalk')
|
|
3
2
|
|
|
4
|
-
const
|
|
5
|
-
|
|
3
|
+
const FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
|
|
4
|
+
const HIDE_CURSOR = '\u001B[?25l'
|
|
5
|
+
const SHOW_CURSOR = '\u001B[?25h'
|
|
6
|
+
const CLEAR_LINE = '\r\x1b[K'
|
|
7
|
+
const SYMBOL_INFO = 'ℹ'
|
|
8
|
+
const SYMBOL_WARN = '⚠'
|
|
9
|
+
const SYMBOL_ERROR = '✖'
|
|
10
|
+
const SYMBOL_SUCCESS = '✔'
|
|
11
|
+
|
|
12
|
+
class Spinner {
|
|
13
|
+
text
|
|
14
|
+
interval
|
|
15
|
+
frameIndex = 0
|
|
16
|
+
symbol = chalk.blue(FRAMES[0])
|
|
17
|
+
|
|
18
|
+
constructor (text) {
|
|
19
|
+
this.text = text
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
start (text) {
|
|
23
|
+
if (text) {
|
|
24
|
+
this.text = text
|
|
25
|
+
}
|
|
26
|
+
this.render()
|
|
27
|
+
this.interval = setInterval(() => this.tick(), 50)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
tick () {
|
|
31
|
+
this.symbol = chalk.blue(FRAMES[this.frameIndex++])
|
|
32
|
+
if (this.frameIndex === FRAMES.length - 1) this.frameIndex = 0
|
|
33
|
+
this.render()
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
render () {
|
|
37
|
+
process.stdout.write(CLEAR_LINE + HIDE_CURSOR + (this.symbol ? this.symbol + ' ' : '') + this.text)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
succeed (text) {
|
|
41
|
+
if (text) {
|
|
42
|
+
this.text = text
|
|
43
|
+
}
|
|
44
|
+
this.symbol = chalk.green(SYMBOL_SUCCESS)
|
|
45
|
+
this.end()
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
info (text) {
|
|
49
|
+
if (text) {
|
|
50
|
+
this.text = text
|
|
51
|
+
}
|
|
52
|
+
this.symbol = chalk.blue(SYMBOL_INFO)
|
|
53
|
+
this.end()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
warn (text) {
|
|
57
|
+
if (text) {
|
|
58
|
+
this.text = text
|
|
59
|
+
}
|
|
60
|
+
this.symbol = chalk.yellow(SYMBOL_WARN)
|
|
61
|
+
this.end()
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
fail (text) {
|
|
65
|
+
if (text) {
|
|
66
|
+
this.text = text
|
|
67
|
+
}
|
|
68
|
+
this.symbol = chalk.red(SYMBOL_ERROR)
|
|
69
|
+
this.end()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
stop () {
|
|
73
|
+
this.symbol = ''
|
|
74
|
+
this.end()
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
end () {
|
|
78
|
+
this.render()
|
|
79
|
+
clearInterval(this.interval)
|
|
80
|
+
process.stdout.write(SHOW_CURSOR + '\n')
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const createSpinner = (initialMessage = '') => {
|
|
85
|
+
const spinner = new Spinner(initialMessage)
|
|
6
86
|
|
|
7
87
|
return {
|
|
8
88
|
start: (message) => spinner.start(message),
|
|
@@ -14,4 +94,4 @@ const createSpinner = function (initialMessage = '') {
|
|
|
14
94
|
}
|
|
15
95
|
}
|
|
16
96
|
|
|
17
|
-
module.exports = createSpinner
|
|
97
|
+
module.exports = { createSpinner, Spinner }
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
const open = require('open')
|
|
2
|
-
const { request } = require('undici')
|
|
3
|
-
const clipboardy = require('./../../../../lib/helpers/clipboardy')
|
|
4
|
-
const confirm = require('@inquirer/confirm').default
|
|
5
|
-
|
|
6
|
-
const createSpinner = require('./../../../../shared/createSpinner')
|
|
7
|
-
const store = require('./../../../../shared/store')
|
|
8
|
-
const { logger } = require('./../../../../shared/logger')
|
|
9
|
-
|
|
10
|
-
const OAUTH_CLIENT_ID = 'oac_dotenvxcli'
|
|
11
|
-
|
|
12
|
-
const spinner = createSpinner('waiting on user authorization')
|
|
13
|
-
|
|
14
|
-
const formatCode = function (str) {
|
|
15
|
-
const parts = []
|
|
16
|
-
|
|
17
|
-
for (let i = 0; i < str.length; i += 4) {
|
|
18
|
-
parts.push(str.substring(i, i + 4))
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return parts.join('-')
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async function pollTokenUrl (tokenUrl, deviceCode, interval) {
|
|
25
|
-
logger.http(`POST ${tokenUrl} with deviceCode ${deviceCode} at interval ${interval}`)
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
const response = await request(tokenUrl, {
|
|
29
|
-
method: 'POST',
|
|
30
|
-
headers: {
|
|
31
|
-
'Content-Type': 'application/json'
|
|
32
|
-
},
|
|
33
|
-
body: JSON.stringify({
|
|
34
|
-
client_id: OAUTH_CLIENT_ID,
|
|
35
|
-
device_code: deviceCode,
|
|
36
|
-
grant_type: 'urn:ietf:params:oauth:grant-type:device_code'
|
|
37
|
-
})
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
const responseData = await response.body.json()
|
|
41
|
-
|
|
42
|
-
logger.http(responseData)
|
|
43
|
-
|
|
44
|
-
if (response.statusCode >= 400) {
|
|
45
|
-
// continue polling if authorization_pending
|
|
46
|
-
if (responseData.error === 'authorization_pending') {
|
|
47
|
-
setTimeout(() => pollTokenUrl(tokenUrl, deviceCode, interval), interval * 1000)
|
|
48
|
-
} else {
|
|
49
|
-
spinner.start()
|
|
50
|
-
spinner.fail(responseData.error_description)
|
|
51
|
-
process.exit(1)
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (responseData.access_token) {
|
|
56
|
-
spinner.start()
|
|
57
|
-
store.setToken(responseData.full_username, responseData.access_token)
|
|
58
|
-
store.setHostname(responseData.hostname)
|
|
59
|
-
spinner.succeed(`logged in as ${responseData.username}`)
|
|
60
|
-
process.exit(0)
|
|
61
|
-
} else {
|
|
62
|
-
// continue polling if no access_token. shouldn't ever get here it server is implemented correctly
|
|
63
|
-
setTimeout(() => pollTokenUrl(tokenUrl, deviceCode, interval), interval * 1000)
|
|
64
|
-
}
|
|
65
|
-
} catch (error) {
|
|
66
|
-
spinner.start()
|
|
67
|
-
spinner.fail(error.toString())
|
|
68
|
-
process.exit(1)
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async function login () {
|
|
73
|
-
const options = this.opts()
|
|
74
|
-
logger.debug(`options: ${JSON.stringify(options)}`)
|
|
75
|
-
|
|
76
|
-
const hostname = options.hostname
|
|
77
|
-
const deviceCodeUrl = `${hostname}/oauth/device/code`
|
|
78
|
-
const tokenUrl = `${hostname}/oauth/token`
|
|
79
|
-
|
|
80
|
-
try {
|
|
81
|
-
const response = await request(deviceCodeUrl, {
|
|
82
|
-
method: 'POST',
|
|
83
|
-
headers: {
|
|
84
|
-
'Content-Type': 'application/json'
|
|
85
|
-
},
|
|
86
|
-
body: JSON.stringify({ client_id: OAUTH_CLIENT_ID })
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
const responseData = await response.body.json()
|
|
90
|
-
|
|
91
|
-
if (response.statusCode >= 400) {
|
|
92
|
-
logger.http(responseData)
|
|
93
|
-
|
|
94
|
-
spinner.start()
|
|
95
|
-
spinner.fail(responseData.error_description)
|
|
96
|
-
process.exit(1)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const deviceCode = responseData.device_code
|
|
100
|
-
const userCode = responseData.user_code
|
|
101
|
-
const verificationUri = responseData.verification_uri
|
|
102
|
-
const interval = responseData.interval
|
|
103
|
-
|
|
104
|
-
try { clipboardy.writeSync(userCode) } catch (_e) {}
|
|
105
|
-
|
|
106
|
-
// qrcode.generate(verificationUri, { small: true }) // too verbose
|
|
107
|
-
|
|
108
|
-
// begin polling
|
|
109
|
-
pollTokenUrl(tokenUrl, deviceCode, interval)
|
|
110
|
-
|
|
111
|
-
// optionally allow user to open browser
|
|
112
|
-
const answer = await confirm({ message: `press Enter to open [${verificationUri}] and enter code [${formatCode(userCode)}]...` })
|
|
113
|
-
|
|
114
|
-
if (answer) {
|
|
115
|
-
await open(verificationUri)
|
|
116
|
-
|
|
117
|
-
spinner.start()
|
|
118
|
-
}
|
|
119
|
-
} catch (error) {
|
|
120
|
-
spinner.start()
|
|
121
|
-
spinner.fail(error.toString())
|
|
122
|
-
process.exit(1)
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
module.exports = login
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
const openBrowser = require('open')
|
|
2
|
-
const confirm = require('@inquirer/confirm').default
|
|
3
|
-
|
|
4
|
-
const createSpinner = require('./../../../../shared/createSpinner')
|
|
5
|
-
const store = require('./../../../../shared/store')
|
|
6
|
-
const { logger } = require('./../../../../shared/logger')
|
|
7
|
-
const sleep = require('./../../../../lib/helpers/sleep')
|
|
8
|
-
|
|
9
|
-
const username = store.getUsername()
|
|
10
|
-
const usernamePart = username ? ` [${username}]` : ''
|
|
11
|
-
const spinner = createSpinner(`logging off machine${usernamePart}`)
|
|
12
|
-
|
|
13
|
-
async function logout () {
|
|
14
|
-
spinner.start()
|
|
15
|
-
await sleep(500) // better dx
|
|
16
|
-
|
|
17
|
-
// debug opts
|
|
18
|
-
const options = this.opts()
|
|
19
|
-
logger.debug(`options: ${JSON.stringify(options)}`)
|
|
20
|
-
|
|
21
|
-
logger.debug('deleting settings.DOTENVX_TOKEN')
|
|
22
|
-
store.deleteToken()
|
|
23
|
-
|
|
24
|
-
logger.debug('deleting settings.DOTENVX_HOSTNAME')
|
|
25
|
-
store.deleteHostname()
|
|
26
|
-
|
|
27
|
-
spinner.done(`logged off machine${usernamePart}`)
|
|
28
|
-
|
|
29
|
-
const hostname = options.hostname
|
|
30
|
-
const logoutUrl = `${hostname}/logout`
|
|
31
|
-
|
|
32
|
-
// optionally allow user to open browser
|
|
33
|
-
const answer = await confirm({ message: `press Enter to also log off browser [${logoutUrl}]...` })
|
|
34
|
-
|
|
35
|
-
if (answer) {
|
|
36
|
-
spinner.start()
|
|
37
|
-
await sleep(500) // better dx
|
|
38
|
-
await openBrowser(logoutUrl)
|
|
39
|
-
spinner.done(`logged off browser${usernamePart}`)
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
module.exports = logout
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
const openBrowser = require('open')
|
|
2
|
-
const confirm = require('@inquirer/confirm').default
|
|
3
|
-
|
|
4
|
-
const createSpinner = require('./../../../../shared/createSpinner')
|
|
5
|
-
const { logger } = require('./../../../../shared/logger')
|
|
6
|
-
|
|
7
|
-
const isGitRepo = require('./../../../../lib/helpers/isGitRepo')
|
|
8
|
-
const isGithub = require('./../../../../lib/helpers/isGithub')
|
|
9
|
-
const gitUrl = require('./../../../../lib/helpers/gitUrl')
|
|
10
|
-
const gitRoot = require('./../../../../lib/helpers/gitRoot')
|
|
11
|
-
const extractUsernameName = require('./../../../../lib/helpers/extractUsernameName')
|
|
12
|
-
const sleep = require('./../../../../lib/helpers/sleep')
|
|
13
|
-
|
|
14
|
-
const spinner = createSpinner('opening')
|
|
15
|
-
|
|
16
|
-
async function open () {
|
|
17
|
-
// debug opts
|
|
18
|
-
const options = this.opts()
|
|
19
|
-
logger.debug(`options: ${JSON.stringify(options)}`)
|
|
20
|
-
|
|
21
|
-
// must be a git repo
|
|
22
|
-
if (!isGitRepo()) {
|
|
23
|
-
spinner.fail('oops, must be a git repository')
|
|
24
|
-
logger.help('? create one with [git init .]')
|
|
25
|
-
process.exit(1)
|
|
26
|
-
}
|
|
27
|
-
// must be a git root
|
|
28
|
-
const gitroot = gitRoot()
|
|
29
|
-
if (!gitroot) {
|
|
30
|
-
spinner.fail('oops, could not determine git repository\'s root')
|
|
31
|
-
logger.help('? create one with [git init .]')
|
|
32
|
-
process.exit(1)
|
|
33
|
-
}
|
|
34
|
-
// must have a remote origin url
|
|
35
|
-
const giturl = gitUrl()
|
|
36
|
-
if (!giturl) {
|
|
37
|
-
spinner.fail('oops, must have a remote origin (git remote -v)')
|
|
38
|
-
logger.help('? create it at [github.com/new] and then run [git remote add origin git@github.com:username/repository.git]')
|
|
39
|
-
process.exit(1)
|
|
40
|
-
}
|
|
41
|
-
// must be a github remote
|
|
42
|
-
if (!isGithub(giturl)) {
|
|
43
|
-
spinner.fail('oops, must be a github.com remote origin (git remote -v)')
|
|
44
|
-
logger.help('? create it at [github.com/new] and then run [git remote add origin git@github.com:username/repository.git]')
|
|
45
|
-
logger.help2('ℹ need support for other origins? [please tell us](https://github.com/dotenvx/dotenvx/issues)')
|
|
46
|
-
process.exit(1)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const usernameName = extractUsernameName(giturl)
|
|
50
|
-
const openUrl = `${options.hostname}/gh/${usernameName}`
|
|
51
|
-
|
|
52
|
-
// optionally allow user to open browser
|
|
53
|
-
const answer = await confirm({ message: `press Enter to open [${openUrl}]...` })
|
|
54
|
-
|
|
55
|
-
if (answer) {
|
|
56
|
-
spinner.start()
|
|
57
|
-
await sleep(500) // better dx
|
|
58
|
-
await openBrowser(openUrl)
|
|
59
|
-
spinner.succeed(`opened [${usernameName}]`)
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
module.exports = open
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const { request } = require('undici')
|
|
4
|
-
|
|
5
|
-
const store = require('./../../../../shared/store')
|
|
6
|
-
const { logger } = require('./../../../../shared/logger')
|
|
7
|
-
const createSpinner = require('./../../../../shared/createSpinner')
|
|
8
|
-
|
|
9
|
-
const isGitRepo = require('./../../../../lib/helpers/isGitRepo')
|
|
10
|
-
const isGithub = require('./../../../../lib/helpers/isGithub')
|
|
11
|
-
const gitUrl = require('./../../../../lib/helpers/gitUrl')
|
|
12
|
-
const gitRoot = require('./../../../../lib/helpers/gitRoot')
|
|
13
|
-
const extractUsernameName = require('./../../../../lib/helpers/extractUsernameName')
|
|
14
|
-
const sleep = require('./../../../../lib/helpers/sleep')
|
|
15
|
-
|
|
16
|
-
const spinner = createSpinner('pulling')
|
|
17
|
-
|
|
18
|
-
// constants
|
|
19
|
-
const ENCODING = 'utf8'
|
|
20
|
-
|
|
21
|
-
// Create a simple-git instance for the current directory
|
|
22
|
-
async function pull (directory) {
|
|
23
|
-
spinner.start()
|
|
24
|
-
await sleep(500) // better dx
|
|
25
|
-
|
|
26
|
-
// debug args
|
|
27
|
-
logger.debug(`directory: ${directory}`)
|
|
28
|
-
|
|
29
|
-
// debug opts
|
|
30
|
-
const options = this.opts()
|
|
31
|
-
logger.debug(`options: ${JSON.stringify(options)}`)
|
|
32
|
-
|
|
33
|
-
// must be a git repo
|
|
34
|
-
if (!isGitRepo()) {
|
|
35
|
-
spinner.fail('oops, must be a git repository')
|
|
36
|
-
logger.help('? create one with [git init .]')
|
|
37
|
-
process.exit(1)
|
|
38
|
-
}
|
|
39
|
-
// must be a git root
|
|
40
|
-
const gitroot = gitRoot()
|
|
41
|
-
if (!gitroot) {
|
|
42
|
-
spinner.fail('oops, could not determine git repository\'s root')
|
|
43
|
-
logger.help('? create one with [git init .]')
|
|
44
|
-
process.exit(1)
|
|
45
|
-
}
|
|
46
|
-
// must have a remote origin url
|
|
47
|
-
const giturl = gitUrl()
|
|
48
|
-
if (!giturl) {
|
|
49
|
-
spinner.fail('oops, must have a remote origin (git remote -v)')
|
|
50
|
-
logger.help('? create it at [github.com/new] and then run [git remote add origin git@github.com:username/repository.git]')
|
|
51
|
-
process.exit(1)
|
|
52
|
-
}
|
|
53
|
-
// must be a github remote
|
|
54
|
-
if (!isGithub(giturl)) {
|
|
55
|
-
spinner.fail('oops, must be a github.com remote origin (git remote -v)')
|
|
56
|
-
logger.help('? create it at [github.com/new] and then run [git remote add origin git@github.com:username/repository.git]')
|
|
57
|
-
logger.help2('ℹ need support for other origins? [please tell us](https://github.com/dotenvx/dotenvx/issues)')
|
|
58
|
-
process.exit(1)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const envKeysFilepath = path.join(directory, '.env.keys')
|
|
62
|
-
const hostname = options.hostname
|
|
63
|
-
const pullUrl = `${hostname}/v1/pull`
|
|
64
|
-
const oauthToken = store.getToken()
|
|
65
|
-
const usernameName = extractUsernameName(giturl)
|
|
66
|
-
const relativeEnvKeysFilepath = path.relative(gitroot, path.join(process.cwd(), directory, '.env.keys')).replace(/\\/g, '/') // smartly determine path/to/.env.keys file from repository root - where user is cd-ed inside a folder or at repo root
|
|
67
|
-
|
|
68
|
-
try {
|
|
69
|
-
const response = await request(pullUrl, {
|
|
70
|
-
method: 'POST',
|
|
71
|
-
headers: {
|
|
72
|
-
Authorization: `Bearer ${oauthToken}`,
|
|
73
|
-
'Content-Type': 'application/json'
|
|
74
|
-
},
|
|
75
|
-
body: JSON.stringify({
|
|
76
|
-
username_name: usernameName,
|
|
77
|
-
filepath: relativeEnvKeysFilepath
|
|
78
|
-
})
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
const responseData = await response.body.json()
|
|
82
|
-
|
|
83
|
-
if (response.statusCode >= 400) {
|
|
84
|
-
logger.http(responseData)
|
|
85
|
-
spinner.fail(responseData.error.message)
|
|
86
|
-
if (response.statusCode === 404) {
|
|
87
|
-
logger.help(`? try visiting [${hostname}/gh/${usernameName}] in your browser`)
|
|
88
|
-
}
|
|
89
|
-
process.exit(1)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (fs.existsSync(envKeysFilepath) && fs.readFileSync(envKeysFilepath, ENCODING) === responseData.DOTENV_KEYS) {
|
|
93
|
-
spinner.done(`no changes (${envKeysFilepath})`)
|
|
94
|
-
} else {
|
|
95
|
-
fs.writeFileSync(envKeysFilepath, responseData.DOTENV_KEYS)
|
|
96
|
-
spinner.succeed(`pulled [${usernameName}]`)
|
|
97
|
-
logger.help2(`ℹ run [cat ${envKeysFilepath}] to view locally`)
|
|
98
|
-
}
|
|
99
|
-
} catch (error) {
|
|
100
|
-
spinner.fail(error.toString())
|
|
101
|
-
process.exit(1)
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
module.exports = pull
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const { request } = require('undici')
|
|
4
|
-
|
|
5
|
-
const store = require('./../../../../shared/store')
|
|
6
|
-
const { logger } = require('./../../../../shared/logger')
|
|
7
|
-
const createSpinner = require('./../../../../shared/createSpinner')
|
|
8
|
-
|
|
9
|
-
const isGitRepo = require('./../../../../lib/helpers/isGitRepo')
|
|
10
|
-
const isGithub = require('./../../../../lib/helpers/isGithub')
|
|
11
|
-
const gitUrl = require('./../../../../lib/helpers/gitUrl')
|
|
12
|
-
const gitRoot = require('./../../../../lib/helpers/gitRoot')
|
|
13
|
-
const extractUsernameName = require('./../../../../lib/helpers/extractUsernameName')
|
|
14
|
-
const sleep = require('./../../../../lib/helpers/sleep')
|
|
15
|
-
const forgivingDirectory = require('./../../../../lib/helpers/forgivingDirectory')
|
|
16
|
-
|
|
17
|
-
const spinner = createSpinner('pushing')
|
|
18
|
-
|
|
19
|
-
// constants
|
|
20
|
-
const ENCODING = 'utf8'
|
|
21
|
-
|
|
22
|
-
// Create a simple-git instance for the current directory
|
|
23
|
-
async function push (directory) {
|
|
24
|
-
spinner.start()
|
|
25
|
-
await sleep(500) // better dx
|
|
26
|
-
|
|
27
|
-
directory = forgivingDirectory(directory)
|
|
28
|
-
|
|
29
|
-
// debug args
|
|
30
|
-
logger.debug(`directory: ${directory}`)
|
|
31
|
-
|
|
32
|
-
// debug opts
|
|
33
|
-
const options = this.opts()
|
|
34
|
-
logger.debug(`options: ${JSON.stringify(options)}`)
|
|
35
|
-
|
|
36
|
-
// must be a git repo
|
|
37
|
-
if (!isGitRepo()) {
|
|
38
|
-
spinner.fail('oops, must be a git repository')
|
|
39
|
-
logger.help('? create one with [git init .]')
|
|
40
|
-
process.exit(1)
|
|
41
|
-
}
|
|
42
|
-
// must be a git root
|
|
43
|
-
const gitroot = gitRoot()
|
|
44
|
-
if (!gitroot) {
|
|
45
|
-
spinner.fail('oops, could not determine git repository\'s root')
|
|
46
|
-
logger.help('? create one with [git init .]')
|
|
47
|
-
process.exit(1)
|
|
48
|
-
}
|
|
49
|
-
// must have a remote origin url
|
|
50
|
-
const giturl = gitUrl()
|
|
51
|
-
if (!giturl) {
|
|
52
|
-
spinner.fail('oops, must have a remote origin (git remote -v)')
|
|
53
|
-
logger.help('? create it at [github.com/new] and then run [git remote add origin git@github.com:username/repository.git]')
|
|
54
|
-
process.exit(1)
|
|
55
|
-
}
|
|
56
|
-
// must be a github remote
|
|
57
|
-
if (!isGithub(giturl)) {
|
|
58
|
-
spinner.fail('oops, must be a github.com remote origin (git remote -v)')
|
|
59
|
-
logger.help('? create it at [github.com/new] and then run [git remote add origin git@github.com:username/repository.git]')
|
|
60
|
-
logger.help2('ℹ need support for other origins? [please tell us](https://github.com/dotenvx/dotenvx/issues)')
|
|
61
|
-
process.exit(1)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const envKeysFilepath = path.join(directory, '.env.keys')
|
|
65
|
-
if (!fs.existsSync(envKeysFilepath)) {
|
|
66
|
-
spinner.fail('oops, missing .env.keys file')
|
|
67
|
-
logger.help(`? generate one with [dotenvx encrypt${directory ? ` ${directory}` : ''}]`)
|
|
68
|
-
logger.help2('ℹ a .env.keys file holds decryption keys for a .env.vault file')
|
|
69
|
-
process.exit(1)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const hostname = options.hostname
|
|
73
|
-
const pushUrl = `${hostname}/v1/push`
|
|
74
|
-
const oauthToken = store.getToken()
|
|
75
|
-
const dotenvKeysContent = fs.readFileSync(envKeysFilepath, ENCODING)
|
|
76
|
-
const usernameName = extractUsernameName(giturl)
|
|
77
|
-
const relativeEnvKeysFilepath = path.relative(gitroot, path.join(process.cwd(), directory, '.env.keys')).replace(/\\/g, '/') // smartly determine path/to/.env.keys file from repository root - where user is cd-ed inside a folder or at repo root
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
const response = await request(pushUrl, {
|
|
81
|
-
method: 'POST',
|
|
82
|
-
headers: {
|
|
83
|
-
Authorization: `Bearer ${oauthToken}`,
|
|
84
|
-
'Content-Type': 'application/json'
|
|
85
|
-
},
|
|
86
|
-
body: JSON.stringify({
|
|
87
|
-
username_name: usernameName,
|
|
88
|
-
DOTENV_KEYS: dotenvKeysContent,
|
|
89
|
-
filepath: relativeEnvKeysFilepath
|
|
90
|
-
})
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
const responseData = await response.body.json()
|
|
94
|
-
|
|
95
|
-
if (response.statusCode >= 400) {
|
|
96
|
-
logger.http(responseData)
|
|
97
|
-
spinner.fail(responseData.error.message)
|
|
98
|
-
if (response.statusCode === 404) {
|
|
99
|
-
logger.help(`? try visiting [${hostname}/gh/${usernameName}] in your browser`)
|
|
100
|
-
}
|
|
101
|
-
process.exit(1)
|
|
102
|
-
}
|
|
103
|
-
} catch (error) {
|
|
104
|
-
spinner.fail(error.toString())
|
|
105
|
-
process.exit(1)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
spinner.succeed(`pushed [${usernameName}]`)
|
|
109
|
-
logger.help2('ℹ run [dotenvx ext hub open] to view on hub')
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
module.exports = push
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
const { Command } = require('commander')
|
|
2
|
-
|
|
3
|
-
const store = require('./../../../shared/store')
|
|
4
|
-
const { logger } = require('./../../../shared/logger')
|
|
5
|
-
|
|
6
|
-
const hub = new Command('hub')
|
|
7
|
-
|
|
8
|
-
hub
|
|
9
|
-
.description('🚫 DEPRECATED: to be replaced by [dotenvx pro]')
|
|
10
|
-
|
|
11
|
-
const loginAction = require('./../../actions/ext/hub/login')
|
|
12
|
-
hub
|
|
13
|
-
.command('login')
|
|
14
|
-
.description('authenticate to dotenvx hub')
|
|
15
|
-
.option('-h, --hostname <url>', 'set hostname', store.getHostname())
|
|
16
|
-
.action(function (...args) {
|
|
17
|
-
logger.warn('DEPRECATION NOTICE: to be replaced by [dotenvx pro]')
|
|
18
|
-
|
|
19
|
-
loginAction.apply(this, args)
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
const pushAction = require('./../../actions/ext/hub/push')
|
|
23
|
-
hub
|
|
24
|
-
.command('push')
|
|
25
|
-
.description('push .env.keys to dotenvx hub')
|
|
26
|
-
.argument('[directory]', 'directory to push', '.')
|
|
27
|
-
.option('-h, --hostname <url>', 'set hostname', store.getHostname())
|
|
28
|
-
.action(function (...args) {
|
|
29
|
-
logger.warn('DEPRECATION NOTICE: to be replaced by [dotenvx pro]')
|
|
30
|
-
|
|
31
|
-
pushAction.apply(this, args)
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
const pullAction = require('./../../actions/ext/hub/pull')
|
|
35
|
-
hub
|
|
36
|
-
.command('pull')
|
|
37
|
-
.description('pull .env.keys from dotenvx hub')
|
|
38
|
-
.argument('[directory]', 'directory to pull', '.')
|
|
39
|
-
.option('-h, --hostname <url>', 'set hostname', store.getHostname())
|
|
40
|
-
.action(function (...args) {
|
|
41
|
-
logger.warn('DEPRECATION NOTICE: to be replaced by [dotenvx pro]')
|
|
42
|
-
|
|
43
|
-
pullAction.apply(this, args)
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
const openAction = require('./../../actions/ext/hub/open')
|
|
47
|
-
hub
|
|
48
|
-
.command('open')
|
|
49
|
-
.description('view repository on dotenvx hub')
|
|
50
|
-
.option('-h, --hostname <url>', 'set hostname', store.getHostname())
|
|
51
|
-
.action(function (...args) {
|
|
52
|
-
logger.warn('DEPRECATION NOTICE: to be replaced by [dotenvx pro]')
|
|
53
|
-
|
|
54
|
-
openAction.apply(this, args)
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
const tokenAction = require('./../../actions/ext/hub/token')
|
|
58
|
-
hub
|
|
59
|
-
.command('token')
|
|
60
|
-
.description('print the auth token dotenvx hub is configured to use')
|
|
61
|
-
.option('-h, --hostname <url>', 'set hostname', 'https://hub.dotenvx.com')
|
|
62
|
-
.action(function (...args) {
|
|
63
|
-
logger.warn('DEPRECATION NOTICE: to be replaced by [dotenvx pro]')
|
|
64
|
-
|
|
65
|
-
tokenAction.apply(this, args)
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
const statusAction = require('./../../actions/ext/hub/status')
|
|
69
|
-
hub
|
|
70
|
-
.command('status')
|
|
71
|
-
.description('display logged in user')
|
|
72
|
-
.action(function (...args) {
|
|
73
|
-
logger.warn('DEPRECATION NOTICE: to be replaced by [dotenvx pro]')
|
|
74
|
-
|
|
75
|
-
statusAction.apply(this, args)
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
const logoutAction = require('./../../actions/ext/hub/logout')
|
|
79
|
-
hub
|
|
80
|
-
.command('logout')
|
|
81
|
-
.description('log out this machine from dotenvx hub')
|
|
82
|
-
.option('-h, --hostname <url>', 'set hostname', store.getHostname())
|
|
83
|
-
.action(function (...args) {
|
|
84
|
-
logger.warn('DEPRECATION NOTICE: to be replaced by [dotenvx pro]')
|
|
85
|
-
|
|
86
|
-
logoutAction.apply(this, args)
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
module.exports = hub
|
package/src/cli/commands/hub.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
const { Command } = require('commander')
|
|
2
|
-
|
|
3
|
-
const store = require('./../../shared/store')
|
|
4
|
-
const { logger } = require('./../../shared/logger')
|
|
5
|
-
|
|
6
|
-
const hub = new Command('hub')
|
|
7
|
-
|
|
8
|
-
hub
|
|
9
|
-
.description('DEPRECATED: to be replaced by [dotenvx pro]')
|
|
10
|
-
|
|
11
|
-
const loginAction = require('./../actions/ext/hub/login')
|
|
12
|
-
hub
|
|
13
|
-
.command('login')
|
|
14
|
-
.description('DEPRECATED: moved to [dotenvx ext hub login]')
|
|
15
|
-
.option('-h, --hostname <url>', 'set hostname', store.getHostname())
|
|
16
|
-
.action(function (...args) {
|
|
17
|
-
logger.warn('DEPRECATION NOTICE: [dotenvx hub login] moved to [dotenvx ext hub login]')
|
|
18
|
-
|
|
19
|
-
loginAction.apply(this, args)
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
const pushAction = require('./../actions/ext/hub/push')
|
|
23
|
-
hub
|
|
24
|
-
.command('push')
|
|
25
|
-
.description('DEPRECATED: moved to [dotenvx ext hub push]')
|
|
26
|
-
.argument('[directory]', 'directory to push', '.')
|
|
27
|
-
.option('-h, --hostname <url>', 'set hostname', store.getHostname())
|
|
28
|
-
.action(function (...args) {
|
|
29
|
-
logger.warn('DEPRECATION NOTICE: [dotenvx hub push] moved to [dotenvx ext hub push]')
|
|
30
|
-
|
|
31
|
-
pushAction.apply(this, args)
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
const pullAction = require('./../actions/ext/hub/pull')
|
|
35
|
-
hub
|
|
36
|
-
.command('pull')
|
|
37
|
-
.description('DEPRECATED: moved to [dotenvx ext hub pull]')
|
|
38
|
-
.argument('[directory]', 'directory to pull', '.')
|
|
39
|
-
.option('-h, --hostname <url>', 'set hostname', store.getHostname())
|
|
40
|
-
.action(function (...args) {
|
|
41
|
-
logger.warn('DEPRECATION NOTICE: [dotenvx hub pull] moved to [dotenvx ext hub pull]')
|
|
42
|
-
|
|
43
|
-
pullAction.apply(this, args)
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
const openAction = require('./../actions/ext/hub/open')
|
|
47
|
-
hub
|
|
48
|
-
.command('open')
|
|
49
|
-
.description('DEPRECATED: moved to [dotenvx ext hub open]')
|
|
50
|
-
.option('-h, --hostname <url>', 'set hostname', store.getHostname())
|
|
51
|
-
.action(function (...args) {
|
|
52
|
-
logger.warn('DEPRECATION NOTICE: [dotenvx hub open] moved to [dotenvx ext hub open]')
|
|
53
|
-
|
|
54
|
-
openAction.apply(this, args)
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
const tokenAction = require('./../actions/ext/hub/token')
|
|
58
|
-
hub
|
|
59
|
-
.command('token')
|
|
60
|
-
.description('DEPRECATED: moved to [dotenvx ext hub token]')
|
|
61
|
-
.option('-h, --hostname <url>', 'set hostname', 'https://hub.dotenvx.com')
|
|
62
|
-
.action(function (...args) {
|
|
63
|
-
logger.warn('DEPRECATION NOTICE: [dotenvx hub token] moved to [dotenvx ext hub token]')
|
|
64
|
-
|
|
65
|
-
tokenAction.apply(this, args)
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
const statusAction = require('./../actions/ext/hub/status')
|
|
69
|
-
hub
|
|
70
|
-
.command('status')
|
|
71
|
-
.description('DEPRECATED: moved to [dotenvx ext hub status]')
|
|
72
|
-
.action(function (...args) {
|
|
73
|
-
logger.warn('DEPRECATION NOTICE: [dotenvx hub status] moved to [dotenvx ext hub status]')
|
|
74
|
-
|
|
75
|
-
statusAction.apply(this, args)
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
const logoutAction = require('./../actions/ext/hub/logout')
|
|
79
|
-
hub
|
|
80
|
-
.command('logout')
|
|
81
|
-
.description('DEPRECATED: moved to [dotenvx ext hub logout]')
|
|
82
|
-
.option('-h, --hostname <url>', 'set hostname', store.getHostname())
|
|
83
|
-
.action(function (...args) {
|
|
84
|
-
logger.warn('DEPRECATION NOTICE: [dotenvx hub logout] moved to [dotenvx ext hub logout]')
|
|
85
|
-
|
|
86
|
-
logoutAction.apply(this, args)
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
module.exports = hub
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
const { request } = require('undici')
|
|
2
|
-
|
|
3
|
-
const packageJson = require('./packageJson')
|
|
4
|
-
|
|
5
|
-
class RemoteVersion {
|
|
6
|
-
constructor () {
|
|
7
|
-
this.packageName = '@dotenvx/dotenvx'
|
|
8
|
-
this.tag = 'latest'
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Returns the latest version of this package
|
|
13
|
-
* @returns {Promise<string?>}
|
|
14
|
-
*/
|
|
15
|
-
async run () {
|
|
16
|
-
return await this._npmVersion()
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async _npmVersion () {
|
|
20
|
-
try {
|
|
21
|
-
const response = await request(`https://registry.npmjs.org/${this.packageName}/${this.tag}`, {
|
|
22
|
-
method: 'GET',
|
|
23
|
-
headers: {
|
|
24
|
-
Accept: 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*',
|
|
25
|
-
'Content-Type': 'application/json'
|
|
26
|
-
}
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
if (response.statusCode !== 200) {
|
|
30
|
-
return packageJson.version
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const data = await response.body.json()
|
|
34
|
-
|
|
35
|
-
return data.version
|
|
36
|
-
} catch (_error) {
|
|
37
|
-
return packageJson.version
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
module.exports = RemoteVersion
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
(async () => {
|
|
2
|
-
const store = require('../../../shared/store')
|
|
3
|
-
const RemoteVersion = require('../remoteVersion')
|
|
4
|
-
const packageJson = require('../packageJson')
|
|
5
|
-
const semver = require('semver')
|
|
6
|
-
|
|
7
|
-
// Exit process when offline
|
|
8
|
-
setTimeout(process.exit, 1000 * 30)
|
|
9
|
-
|
|
10
|
-
const remoteVersion = await new RemoteVersion().run()
|
|
11
|
-
|
|
12
|
-
// set DOTENVX_LATEST_VERSION_LAST_CHECKED (for use with interval (one day) checks)
|
|
13
|
-
store.setLatestVersionLastChecked(Date.now())
|
|
14
|
-
|
|
15
|
-
const localVersion = packageJson.version
|
|
16
|
-
const updateAvailable = semver.gt(remoteVersion, localVersion)
|
|
17
|
-
|
|
18
|
-
// if update is available then set DOTENVX_LATEST_VERSION
|
|
19
|
-
if (updateAvailable) {
|
|
20
|
-
store.setLatestVersion(remoteVersion)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Call process exit explicitly to terminate the child process,
|
|
24
|
-
// otherwise the child process will run forever, according to the Node.js docs
|
|
25
|
-
process.exit()
|
|
26
|
-
})().catch(error => {
|
|
27
|
-
console.error(error)
|
|
28
|
-
process.exit(1)
|
|
29
|
-
})
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
const { spawn } = require('child_process')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const semver = require('semver')
|
|
4
|
-
|
|
5
|
-
const store = require('../../shared/store')
|
|
6
|
-
const packageJson = require('./packageJson')
|
|
7
|
-
|
|
8
|
-
const ONE_DAY = 1000 * 60 * 60 * 24
|
|
9
|
-
|
|
10
|
-
class UpdateNotice {
|
|
11
|
-
constructor () {
|
|
12
|
-
this.latestVersion = store.getLatestVersion()
|
|
13
|
-
this.latestVersionLastChecked = store.getLatestVersionLastChecked()
|
|
14
|
-
this.packageVersion = packageJson.version
|
|
15
|
-
this.updateCheckInterval = ONE_DAY
|
|
16
|
-
this.update = false
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
check () {
|
|
20
|
-
const updateAvailable = semver.gt(this.latestVersion, packageJson.version)
|
|
21
|
-
|
|
22
|
-
// Only check for updates on a set interval
|
|
23
|
-
if (Date.now() - this.latestVersionLastChecked < this.updateCheckInterval) {
|
|
24
|
-
return
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (updateAvailable) {
|
|
28
|
-
this.update = true
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Spawn a detached process
|
|
32
|
-
spawn(process.execPath, [path.join(__dirname, './updateNotice/check.js')], {
|
|
33
|
-
detached: true,
|
|
34
|
-
stdio: 'ignore'
|
|
35
|
-
}).unref()
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
module.exports = UpdateNotice
|