@dotenvx/dotenvx-ops 0.45.0 → 0.45.2
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 +13 -1
- package/package.json +1 -1
- package/src/cli/actions/armor/down.js +1 -1
- package/src/cli/actions/armor/pull.js +1 -1
- package/src/cli/actions/armor/push.js +1 -1
- package/src/cli/actions/armor/up.js +1 -1
- package/src/cli/commands/armor.js +4 -0
- package/src/lib/api/postArmorDown.js +5 -2
- package/src/lib/api/postArmorPull.js +5 -2
- package/src/lib/services/armorDown.js +36 -2
- package/src/lib/services/armorPull.js +36 -2
- package/src/lib/services/armorPush.js +34 -15
- package/src/lib/services/armorUp.js +34 -14
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,19 @@
|
|
|
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-ops/compare/v0.45.
|
|
5
|
+
[Unreleased](https://github.com/dotenvx/dotenvx-ops/compare/v0.45.2...main)
|
|
6
|
+
|
|
7
|
+
## [0.45.2](https://github.com/dotenvx/dotenvx-ops/compare/v0.45.1...v0.45.2) (2026-05-07)
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
* Surface team selector for `down|pull` ([#68](https://github.com/dotenvx/dotenvx-ops/pull/68))
|
|
12
|
+
|
|
13
|
+
## [0.45.1](https://github.com/dotenvx/dotenvx-ops/compare/v0.45.0...v0.45.1) (2026-05-07)
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
* Surface team selector for `up|push` only when member of multiple teams ([#67](https://github.com/dotenvx/dotenvx-ops/pull/66))
|
|
6
18
|
|
|
7
19
|
## [0.45.0](https://github.com/dotenvx/dotenvx-ops/compare/v0.44.0...v0.45.0) (2026-05-07)
|
|
8
20
|
|
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@ async function down () {
|
|
|
17
17
|
try {
|
|
18
18
|
const devicePublicKey = sesh.devicePublicKey()
|
|
19
19
|
|
|
20
|
-
const { changed, privateKeyName } = await new ArmorDown(hostname, token, devicePublicKey, options.envFile).run()
|
|
20
|
+
const { changed, privateKeyName } = await new ArmorDown(hostname, token, devicePublicKey, options.envFile, options.team).run()
|
|
21
21
|
|
|
22
22
|
if (spinner) spinner.stop()
|
|
23
23
|
if (changed) {
|
|
@@ -17,7 +17,7 @@ async function pull () {
|
|
|
17
17
|
try {
|
|
18
18
|
const devicePublicKey = sesh.devicePublicKey()
|
|
19
19
|
|
|
20
|
-
const { changed, privateKeyName } = await new ArmorPull(hostname, token, devicePublicKey, options.envFile).run()
|
|
20
|
+
const { changed, privateKeyName } = await new ArmorPull(hostname, token, devicePublicKey, options.envFile, options.team).run()
|
|
21
21
|
|
|
22
22
|
if (spinner) spinner.stop()
|
|
23
23
|
if (changed) {
|
|
@@ -17,7 +17,7 @@ async function push () {
|
|
|
17
17
|
try {
|
|
18
18
|
const devicePublicKey = sesh.devicePublicKey()
|
|
19
19
|
|
|
20
|
-
const { changed, privateKeyName } = await new ArmorPush(hostname, token, devicePublicKey, options.envFile).run()
|
|
20
|
+
const { changed, privateKeyName } = await new ArmorPush(hostname, token, devicePublicKey, options.envFile, options.team).run()
|
|
21
21
|
|
|
22
22
|
if (spinner) spinner.stop()
|
|
23
23
|
if (changed) {
|
|
@@ -17,7 +17,7 @@ async function up () {
|
|
|
17
17
|
try {
|
|
18
18
|
const devicePublicKey = sesh.devicePublicKey()
|
|
19
19
|
|
|
20
|
-
const { changed, privateKeyName } = await new ArmorUp(hostname, token, devicePublicKey, options.envFile).run()
|
|
20
|
+
const { changed, privateKeyName } = await new ArmorUp(hostname, token, devicePublicKey, options.envFile, options.team).run()
|
|
21
21
|
|
|
22
22
|
if (spinner) spinner.stop()
|
|
23
23
|
if (changed) {
|
|
@@ -18,6 +18,7 @@ armor
|
|
|
18
18
|
.command('up')
|
|
19
19
|
.description('armor private key')
|
|
20
20
|
.option('-f, --env-file <path>', 'path to your env file')
|
|
21
|
+
.option('--team <team>', 'team to armor private key for')
|
|
21
22
|
.action(upAction)
|
|
22
23
|
|
|
23
24
|
// dotenvx-ops armor down
|
|
@@ -26,6 +27,7 @@ armor
|
|
|
26
27
|
.command('down')
|
|
27
28
|
.description('dearmor private key')
|
|
28
29
|
.option('-f, --env-file <path>', 'path to your env file')
|
|
30
|
+
.option('--team <team>', 'team to dearmor private key from')
|
|
29
31
|
.action(downAction)
|
|
30
32
|
|
|
31
33
|
// dotenvx-ops armor push
|
|
@@ -34,6 +36,7 @@ armor
|
|
|
34
36
|
.command('push')
|
|
35
37
|
.description('push armored key (from .env.keys)')
|
|
36
38
|
.option('-f, --env-file <path>', 'path to your env file')
|
|
39
|
+
.option('--team <team>', 'team to push armored private key for')
|
|
37
40
|
.action(pushAction)
|
|
38
41
|
|
|
39
42
|
// dotenvx-ops armor pull
|
|
@@ -42,6 +45,7 @@ armor
|
|
|
42
45
|
.command('pull')
|
|
43
46
|
.description('pull armored key (into .env.keys)')
|
|
44
47
|
.option('-f, --env-file <path>', 'path to your env file')
|
|
48
|
+
.option('--team <team>', 'team to pull armored private key from')
|
|
45
49
|
.action(pullAction)
|
|
46
50
|
|
|
47
51
|
// dotenvx-ops armor rotate
|
|
@@ -4,23 +4,26 @@ const packageJson = require('../../lib/helpers/packageJson')
|
|
|
4
4
|
const normalizeToken = require('../../lib/helpers/normalizeToken')
|
|
5
5
|
|
|
6
6
|
class PostArmorDown {
|
|
7
|
-
constructor (hostname, token, devicePublicKey, publicKey) {
|
|
7
|
+
constructor (hostname, token, devicePublicKey, publicKey, team) {
|
|
8
8
|
this.hostname = hostname || 'https://ops.dotenvx.com'
|
|
9
9
|
this.token = token
|
|
10
10
|
this.devicePublicKey = devicePublicKey
|
|
11
11
|
this.publicKey = publicKey
|
|
12
|
+
this.team = team
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
async run () {
|
|
15
16
|
const token = normalizeToken(this.token)
|
|
16
17
|
const devicePublicKey = this.devicePublicKey
|
|
17
18
|
const publicKey = this.publicKey
|
|
19
|
+
const team = this.team
|
|
18
20
|
const url = `${this.hostname}/api/armor/down`
|
|
19
21
|
|
|
20
22
|
const body = {
|
|
21
23
|
device_public_key: devicePublicKey,
|
|
22
24
|
cli_version: packageJson.version,
|
|
23
|
-
public_key: publicKey
|
|
25
|
+
public_key: publicKey,
|
|
26
|
+
team
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
const resp = await http(url, {
|
|
@@ -4,23 +4,26 @@ const packageJson = require('../../lib/helpers/packageJson')
|
|
|
4
4
|
const normalizeToken = require('../../lib/helpers/normalizeToken')
|
|
5
5
|
|
|
6
6
|
class PostArmorPull {
|
|
7
|
-
constructor (hostname, token, devicePublicKey, publicKey) {
|
|
7
|
+
constructor (hostname, token, devicePublicKey, publicKey, team) {
|
|
8
8
|
this.hostname = hostname || 'https://ops.dotenvx.com'
|
|
9
9
|
this.token = token
|
|
10
10
|
this.devicePublicKey = devicePublicKey
|
|
11
11
|
this.publicKey = publicKey
|
|
12
|
+
this.team = team
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
async run () {
|
|
15
16
|
const token = normalizeToken(this.token)
|
|
16
17
|
const devicePublicKey = this.devicePublicKey
|
|
17
18
|
const publicKey = this.publicKey
|
|
19
|
+
const team = this.team
|
|
18
20
|
const url = `${this.hostname}/api/armor/pull`
|
|
19
21
|
|
|
20
22
|
const body = {
|
|
21
23
|
device_public_key: devicePublicKey,
|
|
22
24
|
cli_version: packageJson.version,
|
|
23
|
-
public_key: publicKey
|
|
25
|
+
public_key: publicKey,
|
|
26
|
+
team
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
const resp = await http(url, {
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
const dotenvx = require('@dotenvx/dotenvx')
|
|
2
|
+
const prompts = require('@inquirer/prompts')
|
|
2
3
|
const PostArmorDown = require('../api/postArmorDown')
|
|
3
4
|
const keyNamesForEnvFile = require('../helpers/keyNamesForEnvFile')
|
|
4
5
|
const upsertEnvKey = require('../helpers/upsertEnvKey')
|
|
5
6
|
|
|
7
|
+
function teamChoicesFromMeta (meta) {
|
|
8
|
+
return meta.organizations.map(org => ({
|
|
9
|
+
name: org.provider_slug,
|
|
10
|
+
value: org.provider_slug
|
|
11
|
+
}))
|
|
12
|
+
}
|
|
13
|
+
|
|
6
14
|
class ArmorDown {
|
|
7
|
-
constructor (hostname, token, devicePublicKey, envFile = '.env') {
|
|
15
|
+
constructor (hostname, token, devicePublicKey, envFile = '.env', team = undefined) {
|
|
8
16
|
this.hostname = hostname
|
|
9
17
|
this.token = token
|
|
10
18
|
this.devicePublicKey = devicePublicKey
|
|
11
19
|
this.envFile = envFile
|
|
20
|
+
this.team = team
|
|
12
21
|
}
|
|
13
22
|
|
|
14
23
|
async run () {
|
|
@@ -16,6 +25,7 @@ class ArmorDown {
|
|
|
16
25
|
const token = this.token
|
|
17
26
|
const devicePublicKey = this.devicePublicKey
|
|
18
27
|
const envFile = this.envFile
|
|
28
|
+
const team = this.team
|
|
19
29
|
|
|
20
30
|
const {
|
|
21
31
|
publicKeyName,
|
|
@@ -23,7 +33,31 @@ class ArmorDown {
|
|
|
23
33
|
} = keyNamesForEnvFile(envFile)
|
|
24
34
|
|
|
25
35
|
const publicKey = dotenvx.get(publicKeyName, { path: envFile, strict: true, ignore: ['MISSING_PRIVATE_KEY'], noOps: true })
|
|
26
|
-
|
|
36
|
+
let json
|
|
37
|
+
|
|
38
|
+
if (team) {
|
|
39
|
+
json = await new PostArmorDown(hostname, token, devicePublicKey, publicKey, team).run()
|
|
40
|
+
} else {
|
|
41
|
+
try {
|
|
42
|
+
json = await new PostArmorDown(hostname, token, devicePublicKey, publicKey, undefined).run()
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (error.code !== 'DOTENVX_TEAM_REQUIRED') {
|
|
45
|
+
throw error
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const choices = teamChoicesFromMeta(error.meta)
|
|
49
|
+
|
|
50
|
+
let team = choices[0].value
|
|
51
|
+
if (choices.length > 1) {
|
|
52
|
+
team = await prompts.select({
|
|
53
|
+
message: 'Select team',
|
|
54
|
+
choices
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
json = await new PostArmorDown(hostname, token, devicePublicKey, publicKey, team).run()
|
|
59
|
+
}
|
|
60
|
+
}
|
|
27
61
|
|
|
28
62
|
upsertEnvKey(privateKeyName, json.private_key)
|
|
29
63
|
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
const dotenvx = require('@dotenvx/dotenvx')
|
|
2
|
+
const prompts = require('@inquirer/prompts')
|
|
2
3
|
const PostArmorPull = require('../api/postArmorPull')
|
|
3
4
|
const upsertEnvKey = require('../helpers/upsertEnvKey')
|
|
4
5
|
const keyNamesForEnvFile = require('../helpers/keyNamesForEnvFile')
|
|
5
6
|
|
|
7
|
+
function teamChoicesFromMeta (meta) {
|
|
8
|
+
return meta.organizations.map(org => ({
|
|
9
|
+
name: org.provider_slug,
|
|
10
|
+
value: org.provider_slug
|
|
11
|
+
}))
|
|
12
|
+
}
|
|
13
|
+
|
|
6
14
|
class ArmorPull {
|
|
7
|
-
constructor (hostname, token, devicePublicKey, envFile = '.env') {
|
|
15
|
+
constructor (hostname, token, devicePublicKey, envFile = '.env', team = undefined) {
|
|
8
16
|
this.hostname = hostname
|
|
9
17
|
this.token = token
|
|
10
18
|
this.devicePublicKey = devicePublicKey
|
|
11
19
|
this.envFile = envFile
|
|
20
|
+
this.team = team
|
|
12
21
|
}
|
|
13
22
|
|
|
14
23
|
async run () {
|
|
@@ -16,6 +25,7 @@ class ArmorPull {
|
|
|
16
25
|
const token = this.token
|
|
17
26
|
const devicePublicKey = this.devicePublicKey
|
|
18
27
|
const envFile = this.envFile
|
|
28
|
+
const team = this.team
|
|
19
29
|
|
|
20
30
|
const {
|
|
21
31
|
publicKeyName,
|
|
@@ -23,7 +33,31 @@ class ArmorPull {
|
|
|
23
33
|
} = keyNamesForEnvFile(envFile)
|
|
24
34
|
|
|
25
35
|
const publicKey = dotenvx.get(publicKeyName, { path: envFile, strict: true, ignore: ['MISSING_PRIVATE_KEY'], noOps: true })
|
|
26
|
-
|
|
36
|
+
let json
|
|
37
|
+
|
|
38
|
+
if (team) {
|
|
39
|
+
json = await new PostArmorPull(hostname, token, devicePublicKey, publicKey, team).run()
|
|
40
|
+
} else {
|
|
41
|
+
try {
|
|
42
|
+
json = await new PostArmorPull(hostname, token, devicePublicKey, publicKey, undefined).run()
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (error.code !== 'DOTENVX_TEAM_REQUIRED') {
|
|
45
|
+
throw error
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const choices = teamChoicesFromMeta(error.meta)
|
|
49
|
+
|
|
50
|
+
let team = choices[0].value
|
|
51
|
+
if (choices.length > 1) {
|
|
52
|
+
team = await prompts.select({
|
|
53
|
+
message: 'Select team',
|
|
54
|
+
choices
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
json = await new PostArmorPull(hostname, token, devicePublicKey, publicKey, team).run()
|
|
59
|
+
}
|
|
60
|
+
}
|
|
27
61
|
|
|
28
62
|
const result = upsertEnvKey(privateKeyName, json.private_key)
|
|
29
63
|
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
const dotenvx = require('@dotenvx/dotenvx')
|
|
2
2
|
const prompts = require('@inquirer/prompts')
|
|
3
3
|
const PostArmorPush = require('../api/postArmorPush')
|
|
4
|
-
const GetAccount = require('../api/getAccount')
|
|
5
4
|
const keyNamesForEnvFile = require('../helpers/keyNamesForEnvFile')
|
|
6
5
|
|
|
6
|
+
function teamChoicesFromMeta (meta) {
|
|
7
|
+
return meta.organizations.map(org => ({
|
|
8
|
+
name: org.provider_slug,
|
|
9
|
+
value: org.provider_slug
|
|
10
|
+
}))
|
|
11
|
+
}
|
|
12
|
+
|
|
7
13
|
class ArmorPush {
|
|
8
|
-
constructor (hostname, token, devicePublicKey, envFile = '.env') {
|
|
14
|
+
constructor (hostname, token, devicePublicKey, envFile = '.env', team = undefined) {
|
|
9
15
|
this.hostname = hostname
|
|
10
16
|
this.token = token
|
|
11
17
|
this.devicePublicKey = devicePublicKey
|
|
12
18
|
this.envFile = envFile
|
|
19
|
+
this.team = team
|
|
13
20
|
}
|
|
14
21
|
|
|
15
22
|
async run () {
|
|
@@ -17,25 +24,37 @@ class ArmorPush {
|
|
|
17
24
|
const token = this.token
|
|
18
25
|
const devicePublicKey = this.devicePublicKey
|
|
19
26
|
const envFile = this.envFile
|
|
27
|
+
const team = this.team
|
|
20
28
|
|
|
21
29
|
const { privateKeyName } = keyNamesForEnvFile(envFile)
|
|
22
30
|
|
|
23
31
|
const privateKey = dotenvx.get(privateKeyName, { path: '.env.keys', strict: true, noOps: true })
|
|
24
32
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
33
|
+
let json
|
|
34
|
+
|
|
35
|
+
if (team) {
|
|
36
|
+
json = await new PostArmorPush(hostname, token, devicePublicKey, privateKey, team).run()
|
|
37
|
+
} else {
|
|
38
|
+
try {
|
|
39
|
+
json = await new PostArmorPush(hostname, token, devicePublicKey, privateKey, undefined).run()
|
|
40
|
+
} catch (error) {
|
|
41
|
+
if (error.code !== 'DOTENVX_TEAM_REQUIRED') {
|
|
42
|
+
throw error
|
|
43
|
+
}
|
|
37
44
|
|
|
38
|
-
|
|
45
|
+
const choices = teamChoicesFromMeta(error.meta)
|
|
46
|
+
|
|
47
|
+
let team = choices[0].value
|
|
48
|
+
if (choices.length > 1) {
|
|
49
|
+
team = await prompts.select({
|
|
50
|
+
message: 'Select team',
|
|
51
|
+
choices
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
json = await new PostArmorPush(hostname, token, devicePublicKey, privateKey, team).run()
|
|
56
|
+
}
|
|
57
|
+
}
|
|
39
58
|
|
|
40
59
|
return {
|
|
41
60
|
...json,
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
const dotenvx = require('@dotenvx/dotenvx')
|
|
2
2
|
const prompts = require('@inquirer/prompts')
|
|
3
3
|
const PostArmorUp = require('../api/postArmorUp')
|
|
4
|
-
const GetAccount = require('../api/getAccount')
|
|
5
4
|
const keyNamesForEnvFile = require('../helpers/keyNamesForEnvFile')
|
|
6
5
|
const removeEnvKey = require('../helpers/removeEnvKey')
|
|
7
6
|
|
|
7
|
+
function teamChoicesFromMeta (meta) {
|
|
8
|
+
return meta.organizations.map(org => ({
|
|
9
|
+
name: org.provider_slug,
|
|
10
|
+
value: org.provider_slug
|
|
11
|
+
}))
|
|
12
|
+
}
|
|
13
|
+
|
|
8
14
|
class ArmorUp {
|
|
9
|
-
constructor (hostname, token, devicePublicKey, envFile = '.env') {
|
|
15
|
+
constructor (hostname, token, devicePublicKey, envFile = '.env', team = undefined) {
|
|
10
16
|
this.hostname = hostname
|
|
11
17
|
this.token = token
|
|
12
18
|
this.devicePublicKey = devicePublicKey
|
|
13
19
|
this.envFile = envFile
|
|
20
|
+
this.team = team
|
|
14
21
|
}
|
|
15
22
|
|
|
16
23
|
async run () {
|
|
@@ -18,6 +25,7 @@ class ArmorUp {
|
|
|
18
25
|
const token = this.token
|
|
19
26
|
const devicePublicKey = this.devicePublicKey
|
|
20
27
|
const envFile = this.envFile
|
|
28
|
+
const team = this.team
|
|
21
29
|
|
|
22
30
|
const {
|
|
23
31
|
publicKeyName,
|
|
@@ -27,20 +35,32 @@ class ArmorUp {
|
|
|
27
35
|
const publicKey = dotenvx.get(publicKeyName, { path: envFile, strict: true, ignore: ['MISSING_PRIVATE_KEY'], noOps: true })
|
|
28
36
|
const privateKey = dotenvx.get(privateKeyName, { path: '.env.keys', strict: true, ignore: ['MISSING_KEY'], noOps: true })
|
|
29
37
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
let json
|
|
39
|
+
|
|
40
|
+
if (team) {
|
|
41
|
+
json = await new PostArmorUp(hostname, token, devicePublicKey, publicKey, privateKey, team).run()
|
|
42
|
+
} else {
|
|
43
|
+
try {
|
|
44
|
+
json = await new PostArmorUp(hostname, token, devicePublicKey, publicKey, privateKey, undefined).run()
|
|
45
|
+
} catch (error) {
|
|
46
|
+
if (error.code !== 'DOTENVX_TEAM_REQUIRED') {
|
|
47
|
+
throw error
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const choices = teamChoicesFromMeta(error.meta)
|
|
51
|
+
|
|
52
|
+
let team = choices[0].value
|
|
53
|
+
if (choices.length > 1) {
|
|
54
|
+
team = await prompts.select({
|
|
55
|
+
message: 'Select team',
|
|
56
|
+
choices
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
json = await new PostArmorUp(hostname, token, devicePublicKey, publicKey, privateKey, team).run()
|
|
61
|
+
}
|
|
41
62
|
}
|
|
42
63
|
|
|
43
|
-
const json = await new PostArmorUp(hostname, token, devicePublicKey, publicKey, privateKey, team).run()
|
|
44
64
|
removeEnvKey(privateKeyName)
|
|
45
65
|
|
|
46
66
|
return {
|