@dotenvx/dotenvx-ops 0.39.0 → 0.39.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/CHANGELOG.md CHANGED
@@ -2,7 +2,13 @@
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.39.0...main)
5
+ [Unreleased](https://github.com/dotenvx/dotenvx-ops/compare/v0.39.1...main)
6
+
7
+ ## [0.39.1](https://github.com/dotenvx/dotenvx-ops/compare/v0.39.0...v0.39.1) (2026-04-23)
8
+
9
+ ### Added
10
+
11
+ * Display install command with update notification ([#54](https://github.com/dotenvx/dotenvx-ops/pull/54))
6
12
 
7
13
  ## [0.39.0](https://github.com/dotenvx/dotenvx-ops/compare/v0.38.3...v0.39.0) (2026-04-23)
8
14
 
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.39.0",
2
+ "version": "0.39.1",
3
3
  "name": "@dotenvx/dotenvx-ops",
4
4
  "description": "Secrets for agents–from the creator of `dotenv` and `dotenvx`",
5
5
  "author": "@motdotla",
@@ -1,10 +1,16 @@
1
1
  const { Command } = require('commander')
2
+ const Session = require('./../../db/session')
2
3
 
3
4
  const armor = new Command('armor')
4
5
 
5
6
  armor
6
7
  .description('ARMORED KEYS ⛨')
7
8
  .allowUnknownOption()
9
+ .action(async function () {
10
+ const sesh = new Session()
11
+ await sesh.notifyUpdate()
12
+ this.help()
13
+ })
8
14
 
9
15
  // dotenvx-ops armor up
10
16
  const upAction = require('./../actions/armor/up')
@@ -7,6 +7,7 @@ const program = new Command()
7
7
  const { setLogLevel } = require('@dotenvx/dotenvx')
8
8
 
9
9
  const packageJson = require('./../lib/helpers/packageJson')
10
+ const Session = require('./../db/session')
10
11
  const argv = process.argv.slice(2)
11
12
  const firstArg = argv[0]
12
13
 
@@ -150,4 +151,10 @@ program.helpInformation = function () {
150
151
  }
151
152
 
152
153
  /* c8 ignore stop */
153
- program.parse(process.argv)
154
+ program.action(async function () {
155
+ const sesh = new Session()
156
+ await sesh.notifyUpdate()
157
+ this.help()
158
+ })
159
+
160
+ program.parseAsync(process.argv)
package/src/db/session.js CHANGED
@@ -6,6 +6,7 @@ const { logger } = require('@dotenvx/dotenvx')
6
6
 
7
7
  const Device = require('./device')
8
8
  const jsonToEnv = require('./../lib/helpers/jsonToEnv')
9
+ const likelyUpdateCommand = require('./../lib/helpers/likelyUpdateCommand')
9
10
  const packageJson = require('./../lib/helpers/packageJson')
10
11
  const GetVersion = require('./../lib/api/getVersion')
11
12
 
@@ -85,6 +86,8 @@ class Session {
85
86
  //
86
87
  async notifyUpdate () {
87
88
  try {
89
+ logger.debug('checking if update available')
90
+
88
91
  const lastCheck = Number(this.store.get('DOTENVX_OPS_VERSION_LAST_CHECK') || 0)
89
92
  const now = Date.now()
90
93
 
@@ -94,7 +97,10 @@ class Session {
94
97
  let remote = local // in case of http fetch error
95
98
 
96
99
  try {
100
+ logger.debug('fetching latest available version')
97
101
  const VERSION = await new GetVersion().run()
102
+ logger.debug(`latest version: ${VERSION}`)
103
+
98
104
  remote = VERSION
99
105
  this.store.set('DOTENVX_OPS_VERSION', VERSION) // remote version
100
106
  } catch (err) {
@@ -106,7 +112,7 @@ class Session {
106
112
 
107
113
  if (semver.gt(remote, local)) {
108
114
  const diff = semver.diff(local, remote)
109
- console.error(`⛆ update available (${diff})`)
115
+ console.error(`⛆ update available (${diff}) [${likelyUpdateCommand()}]`)
110
116
  }
111
117
  }
112
118
  } catch (err) {
@@ -0,0 +1,33 @@
1
+ const normalizePath = require('./normalizePath')
2
+ const safeRealpath = require('./safeRealpath')
3
+
4
+ const NPM_COMMAND = 'npm i @dotenvx/dotenvx-ops'
5
+ const CURL_COMMAND = 'curl -sfS https://dotenvx.sh/ops | sh'
6
+
7
+ function likelyUpdateCommand () {
8
+ const isPackaged = Boolean(process.pkg)
9
+ const executablePath = isPackaged ? process.execPath : (process.argv[1] || process.execPath)
10
+ const resolvedExecutablePath = safeRealpath(executablePath)
11
+ const normalizedPath = normalizePath(resolvedExecutablePath || executablePath || '')
12
+
13
+ if (
14
+ normalizedPath.includes('/node_modules/@dotenvx/dotenvx-ops/') ||
15
+ normalizedPath.includes('/node_modules/.bin/dotenvx-ops')
16
+ ) {
17
+ return NPM_COMMAND
18
+ }
19
+
20
+ if (
21
+ isPackaged ||
22
+ normalizedPath.endsWith('/usr/local/bin/dotenvx-ops') ||
23
+ normalizedPath.endsWith('/opt/homebrew/bin/dotenvx-ops') ||
24
+ normalizedPath.endsWith('/usr/bin/dotenvx-ops') ||
25
+ normalizedPath.endsWith('/bin/dotenvx-ops')
26
+ ) {
27
+ return CURL_COMMAND
28
+ }
29
+
30
+ return NPM_COMMAND
31
+ }
32
+
33
+ module.exports = likelyUpdateCommand
@@ -0,0 +1,5 @@
1
+ function normalizePath (value) {
2
+ return String(value || '').replace(/\\/g, '/').toLowerCase()
3
+ }
4
+
5
+ module.exports = normalizePath
@@ -0,0 +1,13 @@
1
+ const fs = require('fs')
2
+
3
+ function safeRealpath (filePath) {
4
+ if (!filePath) return filePath
5
+
6
+ try {
7
+ return fs.realpathSync(filePath)
8
+ } catch (e) {
9
+ return filePath
10
+ }
11
+ }
12
+
13
+ module.exports = safeRealpath