herozion 1.1.87 → 1.1.88

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/README.md CHANGED
@@ -15,6 +15,47 @@ npx herozion scan .
15
15
 
16
16
  The binary is stored inside `node_modules/herozion/bin/` — it never touches your system PATH.
17
17
 
18
+ ## Update (global install)
19
+
20
+ ```bash
21
+ npm install -g herozion@latest --foreground-scripts
22
+ ```
23
+
24
+ `herozion --version` reads the **downloaded binary**, not the npm wrapper alone. If the version does not change after update, the postinstall download was skipped — force it:
25
+
26
+ ```bash
27
+ rm -rf "$(npm root -g)/herozion"
28
+ npm install -g herozion@latest --foreground-scripts
29
+ which -a herozion
30
+ herozion --version
31
+ ```
32
+
33
+ ## Uninstall (global install)
34
+
35
+ ```bash
36
+ npm uninstall -g herozion
37
+ ```
38
+
39
+ If you see a binary download instead of a removal (older package versions), use:
40
+
41
+ ```bash
42
+ npm uninstall -g herozion --ignore-scripts
43
+ ```
44
+
45
+ Then verify removal:
46
+
47
+ ```bash
48
+ npm list -g herozion # should report empty
49
+ command -v herozion # should print nothing
50
+ ```
51
+
52
+ If the command still exists, remove leftovers manually:
53
+
54
+ ```bash
55
+ rm -rf "$(npm root -g)/herozion"
56
+ rm -f "$(npm bin -g)/herozion"
57
+ ```
58
+
18
59
  ## Full documentation
19
60
 
20
61
  See [github.com/Herozion/scanner](https://github.com/Herozion/scanner#readme)
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "_comment": "SHA-256 hashes for each platform binary. Auto-generated in CI from release CHECKSUMS.sha256. DO NOT edit manually.",
3
- "_version": "1.1.87",
4
- "herozion-linux-amd64": "feab66c6df5fee00aab00c3d593882cfcf1f3fd48a546ec7f4f0d0a9ddfc9eb6",
5
- "herozion-macos-amd64": "a9dd1fa3e8d57d0b565a22eaaae4cd5eee688eb9860972bdb95c35e94d5789b3",
6
- "herozion-macos-arm64": "5484c69d84eb0c568af6144d41cb82c7c9e38a216bb547ee7ef9ab6300c2e86b",
7
- "herozion-windows-amd64.exe": "5ef2f7d8a7a4b907ada68b7fc56ce9edb159b674cd7c5c5d6a0669286eafa05d"
3
+ "_version": "1.1.88",
4
+ "herozion-linux-amd64": "097a6451cf73b1b2988bf8c79549f88061673c4eb84091a5a133af9274557de3",
5
+ "herozion-macos-amd64": "24a8d848ca59cff41fc903374614b93777ccd1c03d741ca24f4d1798e5bd6d94",
6
+ "herozion-macos-arm64": "95148e52080f2a9a79708110663687b21c927f109e51687afb21e34d70215220",
7
+ "herozion-windows-amd64.exe": "bd874fd07aa25d41b0f73e76db3f741051f358242a04f906f36031dc9d587770"
8
8
  }
package/install.js CHANGED
@@ -151,7 +151,29 @@ function sha256File(filePath) {
151
151
 
152
152
 
153
153
 
154
+ function shouldSkipInstall() {
155
+ const lifecycle = process.env.npm_lifecycle_event || "";
156
+ const command = process.env.npm_command || "";
157
+
158
+ // Never download during uninstall/remove (some npm versions can invoke scripts).
159
+ if (command === "uninstall" || command === "remove") {
160
+ return true;
161
+ }
162
+ if (lifecycle === "preuninstall" || lifecycle === "postuninstall") {
163
+ return true;
164
+ }
165
+ // Allow direct `node install.js` (dev) and normal postinstall only.
166
+ if (lifecycle && lifecycle !== "postinstall") {
167
+ return true;
168
+ }
169
+ return false;
170
+ }
171
+
154
172
  async function main() {
173
+ if (shouldSkipInstall()) {
174
+ return;
175
+ }
176
+
155
177
  const binaryName = getBinaryName();
156
178
  const url = `${BASE_URL}/${binaryName}`;
157
179
  // The release ships a combined CHECKSUMS.sha256 file, not per-binary .sha256 files.
@@ -166,13 +188,31 @@ async function main() {
166
188
  const destPath = path.join(binDir, destName);
167
189
  const tmpPath = destPath + ".tmp";
168
190
 
169
- // Skip download if binary already exists and matches binary version
191
+ // Skip download only when the on-disk binary matches this npm package version.
170
192
  const markerPath = path.join(binDir, `.version-${VERSION}`);
171
193
  if (fs.existsSync(destPath) && fs.existsSync(markerPath)) {
172
194
  console.log(`herozion: binary v${VERSION} already present, skipping download.`);
173
195
  return;
174
196
  }
175
197
 
198
+ // Upgrade path: npm bumped the package but postinstall was skipped earlier, or an
199
+ // old binary (e.g. v1.1.80) is still on disk while package.json is v1.1.87.
200
+ if (fs.existsSync(destPath) && !fs.existsSync(markerPath)) {
201
+ console.log(
202
+ `herozion: replacing stale binary with v${VERSION} (previous install out of date).`
203
+ );
204
+ try {
205
+ fs.unlinkSync(destPath);
206
+ } catch (_) {}
207
+ try {
208
+ for (const entry of fs.readdirSync(binDir)) {
209
+ if (entry.startsWith(".version-")) {
210
+ fs.unlinkSync(path.join(binDir, entry));
211
+ }
212
+ }
213
+ } catch (_) {}
214
+ }
215
+
176
216
  // ── Load bundled checksums (primary trust anchor) ─────────────────────────
177
217
  const bundledChecksumsPath = path.join(__dirname, "bin", "checksums.json");
178
218
  let bundledHash = "";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "herozion",
3
- "version": "1.1.87",
3
+ "version": "1.1.88",
4
4
  "description": "Security audit and performance analysis CLI tool for developers",
5
5
  "keywords": [
6
6
  "security",
@@ -25,10 +25,12 @@
25
25
  "bin/herozion.js",
26
26
  "bin/checksums.json",
27
27
  "install.js",
28
+ "uninstall.js",
28
29
  "README.md"
29
30
  ],
30
31
  "scripts": {
31
- "postinstall": "node install.js"
32
+ "postinstall": "node install.js",
33
+ "preuninstall": "node uninstall.js"
32
34
  },
33
35
  "engines": {
34
36
  "node": ">=16.0.0"
package/uninstall.js ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Herozion preuninstall script.
4
+ *
5
+ * Ensures we never download a binary while npm is removing this package.
6
+ * npm may invoke lifecycle scripts in edge cases; this script is a no-op cleanup
7
+ * hook so uninstall stays a true removal.
8
+ */
9
+
10
+ "use strict";
11
+
12
+ const fs = require("fs");
13
+ const path = require("path");
14
+
15
+ const binDir = path.join(__dirname, "bin");
16
+ const targets = ["herozion", "herozion.exe", "herozion.tmp"];
17
+
18
+ for (const name of targets) {
19
+ try {
20
+ fs.unlinkSync(path.join(binDir, name));
21
+ } catch (_) {
22
+ // already gone
23
+ }
24
+ }
25
+
26
+ try {
27
+ for (const entry of fs.readdirSync(binDir)) {
28
+ if (entry.startsWith(".version-")) {
29
+ try {
30
+ fs.unlinkSync(path.join(binDir, entry));
31
+ } catch (_) {}
32
+ }
33
+ }
34
+ } catch (_) {}