npmguard-cli 0.2.3 → 0.3.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.
@@ -1,7 +1,18 @@
1
1
  import chalk from "chalk";
2
2
  import ora from "ora";
3
3
  import { execSync } from "node:child_process";
4
+ import { writeFile, unlink, mkdir } from "node:fs/promises";
5
+ import { join } from "node:path";
6
+ import { tmpdir } from "node:os";
4
7
  const IPFS_GATEWAY = "https://gateway.pinata.cloud/ipfs";
8
+ async function downloadFromIPFS(cid, dest) {
9
+ const resp = await fetch(`${IPFS_GATEWAY}/${cid}`);
10
+ if (!resp.ok) {
11
+ throw new Error(`IPFS download failed: ${resp.status}`);
12
+ }
13
+ const buffer = Buffer.from(await resp.arrayBuffer());
14
+ await writeFile(dest, buffer);
15
+ }
5
16
  export async function installCommand(packageSpec, auditSource, force = false) {
6
17
  const atIndex = packageSpec.lastIndexOf("@");
7
18
  let packageName;
@@ -35,11 +46,11 @@ export async function installCommand(packageSpec, auditSource, force = false) {
35
46
  console.log();
36
47
  console.log(chalk.bold(` ${packageName}@${requestedVersion}`));
37
48
  console.log();
49
+ // No audit found — fallback to npm
38
50
  if (!audit) {
39
51
  console.log(chalk.gray(` NOT AUDITED — no NpmGuard record found for this version.`));
40
- console.log(chalk.gray(` https://www.npmjs.com/package/${packageName}/v/${requestedVersion}`));
41
52
  console.log();
42
- console.log(chalk.gray(" Proceeding with standard npm install..."));
53
+ console.log(chalk.gray(" Falling back to npm install..."));
43
54
  console.log();
44
55
  execSync(`npm install ${packageSpec}`, { stdio: "inherit" });
45
56
  return;
@@ -54,36 +65,46 @@ export async function installCommand(packageSpec, auditSource, force = false) {
54
65
  else if (audit.verdict === "CRITICAL") {
55
66
  console.log(chalk.red(` CRITICAL (score: ${audit.score})`));
56
67
  }
57
- // Show capabilities
58
68
  if (audit.capabilities.length > 0) {
59
69
  console.log(chalk.gray(` Capabilities: ${audit.capabilities.join(", ")}`));
60
70
  }
61
- // Show IPFS links
62
71
  if (audit.reportCid) {
63
72
  console.log(chalk.gray(` Report: ${IPFS_GATEWAY}/${audit.reportCid}`));
64
73
  }
65
- if (audit.sourceCid) {
66
- console.log(chalk.gray(` Source: ${IPFS_GATEWAY}/${audit.sourceCid}`));
67
- }
68
74
  console.log();
69
- if (audit.verdict === "SAFE") {
70
- execSync(`npm install ${packageSpec}`, { stdio: "inherit" });
71
- }
72
- else if (audit.verdict === "WARNING") {
73
- console.log(chalk.yellow(" Installing with warning..."));
75
+ // Block CRITICAL unless --force
76
+ if (audit.verdict === "CRITICAL" && !force) {
77
+ console.log(chalk.red.bold(" Installation blocked. This package has critical security issues."));
78
+ console.log(chalk.gray(" Use --force to install anyway."));
74
79
  console.log();
75
- execSync(`npm install ${packageSpec}`, { stdio: "inherit" });
80
+ return;
76
81
  }
77
- else if (audit.verdict === "CRITICAL") {
78
- if (force) {
79
- console.log(chalk.red(" --force: Installing despite CRITICAL verdict..."));
82
+ // Install from IPFS if sourceCid is available
83
+ if (audit.sourceCid) {
84
+ const dlSpinner = ora(`Downloading verified source from IPFS (${audit.sourceCid.slice(0, 12)}...)`).start();
85
+ try {
86
+ const tmpDir = join(tmpdir(), "npmguard");
87
+ await mkdir(tmpDir, { recursive: true });
88
+ const tarballPath = join(tmpDir, `${packageName}-${requestedVersion}.tgz`);
89
+ await downloadFromIPFS(audit.sourceCid, tarballPath);
90
+ dlSpinner.succeed("Downloaded from IPFS");
91
+ console.log(chalk.green(` Installing from verified IPFS source...`));
80
92
  console.log();
81
- execSync(`npm install ${packageSpec}`, { stdio: "inherit" });
93
+ execSync(`npm install ${tarballPath}`, { stdio: "inherit" });
94
+ // Cleanup
95
+ await unlink(tarballPath).catch(() => { });
82
96
  }
83
- else {
84
- console.log(chalk.red.bold(" Installation blocked. This package has critical security issues."));
85
- console.log(chalk.gray(" Use --force to install anyway."));
97
+ catch (err) {
98
+ dlSpinner.fail("IPFS download failed");
99
+ console.log(chalk.yellow(" Falling back to npm install..."));
86
100
  console.log();
101
+ execSync(`npm install ${packageSpec}`, { stdio: "inherit" });
87
102
  }
88
103
  }
104
+ else {
105
+ // No sourceCid — install from npm
106
+ console.log(chalk.gray(" No IPFS source available, installing from npm..."));
107
+ console.log();
108
+ execSync(`npm install ${packageSpec}`, { stdio: "inherit" });
109
+ }
89
110
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "npmguard-cli",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "description": "Check npm packages against NpmGuard security audits on ENS before installing",
6
6
  "bin": "./dist/index.js",