Skip to content

Commit f6396e1

Browse files
ErwanRauloRaulo Erwan.
andauthored
fix: extract integrity command (#647)
* fix(command): extract integrity spec argument * fix(command): extract integrity unit tests --------- Co-authored-by: Raulo Erwan. <erwan.raulo.externe@emeria.eu>
1 parent d809579 commit f6396e1

File tree

12 files changed

+309
-139
lines changed

12 files changed

+309
-139
lines changed

bin/index.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@ catch {
99
}
1010

1111
// Import Node.js Dependencies
12-
import path from "node:path";
1312
import { createRequire } from "node:module";
13+
import path from "node:path";
1414
import { fileURLToPath } from "node:url";
1515

1616
// Import Third-party Dependencies
17-
import sade from "sade";
18-
import semver from "semver";
1917
import * as i18n from "@nodesecure/i18n";
20-
import * as vulnera from "@nodesecure/vulnera";
2118
import { loadRegistryURLFromLocalSystem } from "@nodesecure/npm-registry-sdk";
19+
import * as vulnera from "@nodesecure/vulnera";
20+
import sade from "sade";
21+
import semver from "semver";
2222

2323
// Import Internal Dependencies
2424
import * as commands from "../src/commands/index.js";
@@ -135,8 +135,9 @@ prog
135135
.action(commands.cache.main);
136136

137137
prog
138-
.command("extract integrity [spec]")
138+
.command("extract integrity <spec>")
139139
.describe(i18n.getTokenSync("cli.commands.extractIntegrity.desc"))
140+
.example("nsecure extract integrity lodash@^4.1.2")
140141
.action(commands.extractIntegrity.main);
141142

142143
prog.parse(process.argv);

i18n/english.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,10 @@ const cli = {
7878
cleared: "Cache cleared successfully!"
7979
},
8080
extractIntegrity: {
81-
desc: "Extract the integrity of a package from its manifest and tarball and compare the two integrities if different from one another."
81+
desc: "Extract the integrity of a package from its manifest and tarball and compare the two integrities if different from one another.",
82+
missingSpecVersion: tS`You must specify a version for '${0}' package.`,
83+
invalidSpec: tS`The package spec '${0}' is invalid.`,
84+
specNotFound: tS`The package spec '${0}' could not be found from the npm registry.`
8285
}
8386
},
8487
startHttp: {

i18n/french.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,10 @@ const cli = {
7878
cleared: "Cache nettoyé avec succès !"
7979
},
8080
extractIntegrity: {
81-
desc: "Extraire l'intégrité d'un paquet à partir de son manifeste et du tarball et comparer les deux intégrités si elles sont différentes."
81+
desc: "Extraire l'intégrité d'un paquet à partir de son manifeste et du tarball et comparer les deux intégrités si elles sont différentes.",
82+
missingSpecVersion: tS`Vous devez spécifier une version pour le package '${0}'.`,
83+
invalidSpec: tS`La spécification '${0}' est invalide.`,
84+
specNotFound: tS`La spécification '${0}' n'a pas pu être trouvée dans le registre npm.`
8285
}
8386
},
8487
startHttp: {

src/commands/extract-integrity.js

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,53 @@ import os from "node:os";
44
import path from "node:path";
55

66
// Import Third-party Dependencies
7-
import * as npmRegistrySDK from "@nodesecure/npm-registry-sdk";
8-
import { diff } from "json-diff-ts";
9-
import { tarball } from "@nodesecure/scanner";
7+
import * as i18n from "@nodesecure/i18n";
8+
109
import {
11-
parseNpmSpec,
12-
packageJSONIntegrityHash
10+
packageJSONIntegrityHash,
11+
parseNpmSpec
1312
} from "@nodesecure/mama";
13+
import * as npmRegistrySDK from "@nodesecure/npm-registry-sdk";
14+
import { tarball } from "@nodesecure/scanner";
15+
import { diff } from "json-diff-ts";
16+
17+
// Import Internal Dependencies
18+
import kleur from "../utils/styleText.js";
19+
20+
const Ki18nCommandName = "cli.commands.extractIntegrity";
1421

1522
export async function main(
1623
npmPackageSpec
1724
) {
1825
const parsedPackageSpec = parseNpmSpec(npmPackageSpec);
1926
if (!parsedPackageSpec) {
20-
throw new Error(`Invalid npm spec: ${npmPackageSpec}`);
27+
console.log(kleur.red().bold(` [!] ${i18n.getTokenSync(`${Ki18nCommandName}.invalidSpec`, npmPackageSpec)}\n`));
28+
process.exit(1);
29+
}
30+
31+
const { name, semver } = parsedPackageSpec;
32+
if (!semver) {
33+
console.log(kleur.red().bold(` [!] ${i18n.getTokenSync(`${Ki18nCommandName}.missingSpecVersion`, name)}\n`));
34+
process.exit(1);
2135
}
2236

23-
const packumentVersion = await npmRegistrySDK.packumentVersion(
24-
parsedPackageSpec.name,
25-
parsedPackageSpec.semver,
26-
{
27-
token: process.env.NODE_SECURE_TOKEN
37+
let packumentVersion;
38+
try {
39+
packumentVersion = await npmRegistrySDK.packumentVersion(
40+
name,
41+
semver,
42+
{
43+
token: process.env.NODE_SECURE_TOKEN
44+
}
45+
);
46+
}
47+
catch (error) {
48+
if (error.statusCode === 404) {
49+
console.log(kleur.yellow().bold(` [!] ${i18n.getTokenSync(`${Ki18nCommandName}.specNotFound`, npmPackageSpec)}\n`));
50+
process.exit(1);
2851
}
29-
);
52+
}
53+
3054
const remote = packageJSONIntegrityHash(
3155
packumentVersion,
3256
{ isFromRemoteRegistry: true }

test/commands/cache.test.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,26 @@ catch {
77
}
88

99
// Import Node.js Dependencies
10-
import fs from "node:fs";
11-
import path from "node:path";
12-
import url from "node:url";
1310
import assert from "node:assert";
1411
import childProcess from "node:child_process";
12+
import fs from "node:fs";
13+
import path from "node:path";
1514
import { after, before, describe, it } from "node:test";
15+
import url from "node:url";
1616

1717
// Import Third-party Dependencies
18+
import { DEFAULT_PAYLOAD_PATH } from "@nodesecure/cache";
1819
import * as i18n from "@nodesecure/i18n";
1920
import { cache } from "@nodesecure/server";
20-
import { DEFAULT_PAYLOAD_PATH } from "@nodesecure/cache";
2121

2222
// Import Internal Dependencies
23-
import { arrayFromAsync } from "../helpers/utils.js";
2423
import { main } from "../../src/commands/cache.js";
24+
import { arrayFromAsync } from "../helpers/utils.js";
2525

2626
// CONSTANTS
2727
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
2828

29-
describe("Cache command", { concurrency: 1 }, () => {
29+
describe("CLI Commands: cache", { concurrency: 1 }, () => {
3030
let lang;
3131
let actualCache;
3232
let dummyPayload = null;
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Load .env file if it exists (quiet - no error if missing)
2+
try {
3+
process.loadEnvFile();
4+
}
5+
catch {
6+
// .env file not found or not readable - ignore silently
7+
}
8+
9+
// Import Node.js Dependencies
10+
import assert from "node:assert";
11+
import path from "node:path";
12+
import { describe, test } from "node:test";
13+
import { fileURLToPath } from "node:url";
14+
15+
// Import Internal Dependencies
16+
import { runProcess } from "../helpers/cliCommandRunner.js";
17+
import { arrayFromAsync } from "../helpers/utils.js";
18+
19+
// CONSTANTS
20+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
21+
const kProcessDir = path.join(__dirname, "..", "process");
22+
23+
describe("CLI Commands: extract integrity", () => {
24+
test("should not find an integrity diff", async() => {
25+
const expectedLine = "no integrity diff found";
26+
27+
const lines = await arrayFromAsync(runProcess({ path: path.join(kProcessDir, "extract-integrity/valid-spec.js") }));
28+
29+
assert.equal(lines[0], expectedLine, `should be ${expectedLine}`);
30+
});
31+
32+
test("should not check integrity if version is missing", async() => {
33+
const expectedLine = " [!] You must specify a version for 'express' package.";
34+
35+
const lines = await arrayFromAsync(runProcess({ path: path.join(kProcessDir, "extract-integrity/missing-version.js") }));
36+
37+
assert.equal(lines[0], expectedLine, `should be ${expectedLine}`);
38+
});
39+
40+
test("should not check integrity for invalid spec", async() => {
41+
const expectedLine = " [!] The package spec '' is invalid.";
42+
43+
const lines = await arrayFromAsync(runProcess({ path: path.join(kProcessDir, "extract-integrity/invalid-spec.js") }));
44+
45+
assert.equal(lines[0], expectedLine, `should be ${expectedLine}`);
46+
});
47+
48+
test("should not check integrity if spec is not found", async() => {
49+
const expectedLine = " [!] The package spec 'express@not-found' could not be found from the npm registry.";
50+
51+
const lines = await arrayFromAsync(runProcess({ path: path.join(kProcessDir, "extract-integrity/not-found.js") }));
52+
53+
assert.equal(lines[0], expectedLine, `should be ${expectedLine}`);
54+
});
55+
});

0 commit comments

Comments
 (0)