Skip to content

Commit 9052d43

Browse files
author
Raulo Erwan.
committed
feat: option to highlight packages
1 parent a299d76 commit 9052d43

File tree

11 files changed

+201
-6
lines changed

11 files changed

+201
-6
lines changed

bin/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ function defaultScannerCommand(name, options = {}) {
152152
.option("-d, --depth", i18n.getTokenSync("cli.commands.option_depth"), Infinity)
153153
.option("--silent", i18n.getTokenSync("cli.commands.option_silent"), false)
154154
.option("-c, --contacts", i18n.getTokenSync("cli.commands.option_contacts"), [])
155+
.option("-p, --packages", i18n.getTokenSync("cli.commands.option_packages"), [])
155156
.option("--verbose", i18n.getTokenSync("cli.commands.option_verbose"), false);
156157

157158
if (includeOutput) {

docs/cli/auto.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,6 @@ $ nsecure auto --keep
2828
| `--vulnerabilityStrategy` | `-s` | github-advisory | Strategy used to fetch package vulnerabilities (see Vulnera [available strategy](https://github.com/NodeSecure/vulnera?tab=readme-ov-file#available-strategy)). |
2929
| `--keep` | `-k` | `false` | Preserve JSON payload after execution. |
3030
| `--developer` | | `false` | Launch the server in developer mode, enabling automatic refresh on HTML/CSS/JS changes. |
31-
| `--contacts` | `-c` | `[]` | List of contacts to highlight. | `--verbose` | | `false` | Sets cli log level to verbose, causing the CLI to output more detailed logs. |
31+
| `--contacts` | `-c` | `[]` | List of contacts to highlight. |
32+
| `--packages` | `-p` | `[]` | List of packages to highlight. |
33+
`--verbose` | | `false` | Sets cli log level to verbose, causing the CLI to output more detailed logs. |

docs/cli/cwd.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,6 @@ $ nsecure cwd [options]
1818
| `--silent` | | `false` | Suppress console output, making execution silent. |
1919
| `--output` | `-o` | `nsecure-result` | Specify the output file for the results. |
2020
| `--vulnerabilityStrategy` | `-s` | github-advisory | Strategy used to fetch package vulnerabilities (see Vulnera [available strategy](https://github.com/NodeSecure/vulnera?tab=readme-ov-file#available-strategy)). |
21-
| `--contacts` | `-c` | `[]` | List of contacts to highlight. | `--verbose` | | `false` | Sets cli log level to verbose, causing the CLI to output more detailed logs. |
21+
| `--contacts` | `-c` | `[]` | List of contacts to highlight. |
22+
| `--packages` | `-p` | `[]` | List of packages to highlight. |
23+
`--verbose` | | `false` | Sets cli log level to verbose, causing the CLI to output more detailed logs. |

docs/cli/from.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,6 @@ $ nsecure from express@3.0.0 -o express-report
2424
| `--silent` | | `false` | Suppress console output, making execution silent. |
2525
| `--output` | `-o` | `nsecure-result` | Specify the output file for the results. |
2626
| `--vulnerabilityStrategy` | `-s` | github-advisory | Strategy used to fetch package vulnerabilities (see Vulnera [available strategy](https://github.com/NodeSecure/vulnera?tab=readme-ov-file#available-strategy)). |
27-
| `--contacts` | `-c` | `[]` | List of contacts to highlight. | `--verbose` | | `false` | Sets cli log level to verbose, causing the CLI to output more detailed logs. |
27+
| `--contacts` | `-c` | `[]` | List of contacts to highlight. |
28+
| `--packages` | `-p` | `[]` | List of packages to highlight. |
29+
`--verbose` | | `false` | Sets cli log level to verbose, causing the CLI to output more detailed logs. |

i18n/arabic.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const cli = {
2222
option_output: "اسم ملف JSON الناتج",
2323
option_silent: "تفعيل الوضع الصامت الذي يعطل مؤشرات CLI",
2424
option_contacts: "قائمة جهات الاتصال للتمييز",
25+
option_packages: "قائمة الحزم للتمييز",
2526
option_verbose: "ضبط مستوى الـ log الخاص بالـ CLI على verbose، مما يجعل الـ CLI يولّد logs أكثر تفصيلاً.",
2627
strategy: "مصدر الثغرات للاستخدام",
2728
cwd: {

i18n/english.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const cli = {
2727
option_output: "Json file output name",
2828
option_silent: "enable silent mode which disable CLI spinners",
2929
option_contacts: "List of contacts to hightlight",
30+
option_packages: "List of packages to highlight",
3031
option_verbose: "Sets cli log level to verbose, causing the CLI to output more detailed logs.",
3132
strategy: "Vulnerabilities source to use",
3233
cwd: {

i18n/french.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const cli = {
2727
option_output: "Nom de sortie du fichier json",
2828
option_silent: "Activer le mode silencieux qui désactive les spinners du CLI",
2929
option_contacts: "Liste des contacts à mettre en évidence",
30+
option_packages: "Liste des packages à mettre en évidence",
3031
option_verbose: "Définir le niveau de log CLI à verbeux, ce qui amènera la CLI à générer des logs plus détaillés.",
3132
strategy: "Source de vulnérabilités à utiliser",
3233
cwd: {

i18n/turkish.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const cli = {
2424
option_output: "JSON dosyası çıktı adı",
2525
option_silent: "CLI döndürücülerini devre dışı bırakan sessiz modu etkinleştir",
2626
option_contacts: "Vurgulanacak kişilerin listesi",
27+
option_packages: "Vurgulanacak paketlerin listesi",
2728
option_verbose: "CLI'nin log seviyesini verbose olarak ayarlar, bu da CLI'nin daha ayrıntılı loglar üretmesine neden olur.",
2829
strategy: "Kullanılacak güvenlik açığı kaynağı",
2930
cwd: {

src/commands/parsers/packages.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* Parse a list of CLI package strings into the expected HighlightPackages format expected
3+
* by @nodesecure/scanner: `string[] | Record<string, string[] | SemverRange>`.
4+
*
5+
* Each input string can be:
6+
* - "lodash" → plain name, no version constraint
7+
* - "lodash@^4.0.0" → name with a semver range
8+
* - "lodash@1.0.0,2.0.0" → name with a list of specific versions
9+
* - "@scope/pkg" → scoped package, no version constraint
10+
* - "@scope/pkg@^1.0.0" → scoped package with a semver range
11+
*
12+
* When none of the entries carry a version constraint the function returns a plain `string[]`.
13+
* If at least one entry has a version constraint the function returns a `Record`;
14+
* Entries without a constraint are mapped to '*'
15+
*
16+
* @param {string | string[]} input
17+
* @returns {string[] | Record<string, string[] | string>}
18+
*/
19+
export function parsePackages(input) {
20+
const items = Array.isArray(input) ? input : [input];
21+
const parsed = items.map(parseOne);
22+
23+
const hasVersionConstraints = parsed.some(({ version }) => version !== null);
24+
25+
if (!hasVersionConstraints) {
26+
return parsed.map(({ name }) => name);
27+
}
28+
29+
return Object.fromEntries(
30+
parsed.map(({ name, version }) => [name, version ?? "*"])
31+
);
32+
}
33+
34+
/**
35+
* @param {string} str
36+
* @returns {{ name: string, version: string | string[] | null }}
37+
*/
38+
function parseOne(str) {
39+
// Scoped packages start with "@", so search for a second "@" after index 1.
40+
const versionSeparator = str.startsWith("@") ? str.indexOf("@", 1) : str.indexOf("@");
41+
42+
if (versionSeparator === -1) {
43+
return { name: str.trim(), version: null };
44+
}
45+
46+
const name = str.slice(0, versionSeparator).trim();
47+
const versionStr = str.slice(versionSeparator + 1).trim();
48+
49+
if (versionStr === "") {
50+
return { name, version: null };
51+
}
52+
53+
if (versionStr.includes(",")) {
54+
const versions = versionStr.split(",").map((v) => v.trim()).filter(Boolean);
55+
let version;
56+
if (versions.length === 0) {
57+
version = null;
58+
}
59+
else if (versions.length === 1) {
60+
version = versions[0];
61+
}
62+
else {
63+
version = versions;
64+
}
65+
66+
return { name, version };
67+
}
68+
69+
return { name, version: versionStr };
70+
}

src/commands/scanner.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,16 @@ import {
2020
formatMs
2121
} from "./loggers/logger.js";
2222
import { parseContacts } from "./parsers/contacts.js";
23+
import { parsePackages } from "./parsers/packages.js";
2324

2425
export async function auto(spec, options) {
2526
const { keep, ...commandOptions } = options;
2627

2728
const optionsWithContacts = {
2829
...commandOptions,
2930
highlight: {
30-
contacts: parseContacts(options.contacts)
31+
contacts: parseContacts(options.contacts),
32+
packages: parsePackages(options.packages ?? [])
3133
}
3234
};
3335

@@ -75,6 +77,7 @@ export async function cwd(options, cache) {
7577
vulnerabilityStrategy,
7678
silent,
7779
contacts,
80+
packages,
7881
verbose
7982
} = options;
8083

@@ -86,7 +89,8 @@ export async function cwd(options, cache) {
8689
fullLockMode: full,
8790
vulnerabilityStrategy,
8891
highlight: {
89-
contacts: parseContacts(contacts)
92+
contacts: parseContacts(contacts),
93+
packages: parsePackages(packages)
9094
},
9195
isVerbose: verbose,
9296
workers: true,
@@ -118,6 +122,7 @@ export async function from(spec, options, cache) {
118122
output,
119123
silent,
120124
contacts,
125+
packages,
121126
vulnerabilityStrategy,
122127
verbose
123128
} = options;
@@ -128,7 +133,8 @@ export async function from(spec, options, cache) {
128133
maxDepth,
129134
vulnerabilityStrategy,
130135
highlight: {
131-
contacts: parseContacts(contacts)
136+
contacts: parseContacts(contacts),
137+
packages: parsePackages(packages)
132138
},
133139
isVerbose: verbose,
134140
workers: true,

0 commit comments

Comments
 (0)