@dotenvx/dotenvx 2.27.0 → 2.28.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 CHANGED
@@ -2,7 +2,24 @@
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/v2.27.0...main)
5
+ [Unreleased](https://github.com/dotenvx/dotenvx/compare/v2.28.0...main)
6
+
7
+ ## [2.28.0](https://github.com/dotenvx/dotenvx/compare/v2.27.0...v2.28.0) (2026-09-16)
8
+
9
+ ### Added
10
+
11
+ * Choose where you custody your keys ([#972](https://github.com/dotenvx/dotenvx/pull/972))
12
+
13
+ ```text
14
+ Your private key
15
+ ├── ⛉ Local Custody
16
+ │ ├── OS (macOS Keychain / Windows Credential Manager / Linux Secret Service)
17
+ │ ├── 1Password
18
+ │ ├── Bitwarden
19
+ │ └── File (.env.keys)
20
+ └── ⛊ Managed Custody
21
+ └── ⛨ Armor
22
+ ```
6
23
 
7
24
  ## [2.27.0](https://github.com/dotenvx/dotenvx/compare/v2.26.1...v2.27.0) (2026-09-16)
8
25
 
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.27.0",
2
+ "version": "2.28.0",
3
3
  "name": "@dotenvx/dotenvx",
4
4
  "description": "a secure dotenv–from the creator of `dotenv`",
5
5
  "author": "@motdotla",
@@ -8,7 +8,8 @@ function choicesForSelect (choices) {
8
8
 
9
9
  return {
10
10
  name: choice.value,
11
- message: choice.name || choice.value
11
+ message: choice.name || choice.value,
12
+ ...(choice.disabled !== undefined ? { disabled: choice.disabled === true ? '(unavailable)' : choice.disabled } : {})
12
13
  }
13
14
  })
14
15
  }
@@ -13,22 +13,28 @@ async function selectKeyStorage (options = {}) {
13
13
  const defaultStorage = useNative ? 'native' : 'file'
14
14
  if (process.env.CI || options.noCreate || !process.stdin.isTTY || !process.stderr.isTTY) return defaultStorage
15
15
 
16
- const choices = [
17
- ...(useNative ? [{ name: `□ Local Custody (Native ${secretStoreNames[process.platform]})`, value: 'native' }] : [])
16
+ const use1Password = !options.no1Password && process.env.DOTENVX_NO_1PASSWORD !== 'true' && await onePasswordCustody.available()
17
+ const useBitwarden = !options.noBitwarden && process.env.DOTENVX_NO_BITWARDEN !== 'true' && await bitwardenCustody.available()
18
+ const localChoices = [
19
+ { name: `OS${secretStoreNames[process.platform] ? ` (${secretStoreNames[process.platform]})` : ''}`, value: 'native', disabled: !useNative },
20
+ { name: '1Password', value: 'onepassword', disabled: !use1Password },
21
+ { name: 'Bitwarden', value: 'bitwarden', disabled: !useBitwarden },
22
+ { name: 'File (.env.keys)', value: 'file', disabled: false }
18
23
  ]
19
- if (!options.no1Password && process.env.DOTENVX_NO_1PASSWORD !== 'true' && await onePasswordCustody.available()) {
20
- choices.push({ name: '□ Local Custody (1Password)', value: 'onepassword' })
21
- }
22
- if (!options.noBitwarden && process.env.DOTENVX_NO_BITWARDEN !== 'true' && await bitwardenCustody.available()) {
23
- choices.push({ name: '□ Local Custody (Bitwarden)', value: 'bitwarden' })
24
- }
25
- if (!options.noArmor) choices.push({ name: '⛨ Managed Custody (Armor)', value: 'armored' })
26
- if (choices.length < 2) return choices.length ? choices[0].value : defaultStorage
27
24
 
28
- return prompts.select({
25
+ const choices = [{ name: '⛉ Local Custody', value: 'local', disabled: false }]
26
+ if (!options.noArmor) choices.push({ name: '⛊ Managed Custody', value: 'managed' })
27
+
28
+ const context = { input: process.stdin, output: process.stderr }
29
+ const custody = await prompts.select({
29
30
  message: 'Choose private key storage',
30
31
  choices
31
- }, { input: process.stdin, output: process.stderr })
32
+ }, context)
33
+
34
+ return prompts.select({
35
+ message: custody === 'local' ? 'Choose local custody' : 'Choose managed custody',
36
+ choices: custody === 'local' ? localChoices : [{ name: '⛨ Armor', value: 'armored' }]
37
+ }, context)
32
38
  }
33
39
 
34
40
  module.exports = selectKeyStorage