@nodesecure/scanner 3.3.0 → 3.5.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.
package/README.md CHANGED
@@ -1,95 +1,97 @@
1
- # NodeSecure Scanner
2
- ![version](https://img.shields.io/badge/dynamic/json.svg?url=https://raw.githubusercontent.com/NodeSecure/scanner/master/package.json&query=$.version&label=Version)
3
- [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/NodeSecure/scanner/commit-activity)
4
- [![Security Responsible Disclosure](https://img.shields.io/badge/Security-Responsible%20Disclosure-yellow.svg)](https://github.com/nodejs/security-wg/blob/master/processes/responsible_disclosure_template.md
5
- )
6
- [![mit](https://img.shields.io/github/license/Naereen/StrapDown.js.svg)](https://github.com/NodeSecure/scanner/blob/master/LICENSE)
7
- ![build](https://img.shields.io/github/workflow/status/NodeSecure/scanner/Node.js%20CI)
8
-
9
- ⚡️ Run a static analysis of your module's dependencies.
10
-
11
- ## Requirements
12
-
13
- - [Node.js](https://nodejs.org/en/) version 16 or higher
14
-
15
- ## Getting Started
16
-
17
- This package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com).
18
-
19
- ```bash
20
- $ npm i @nodesecure/scanner
21
- # or
22
- $ yarn add @nodesecure/scanner
23
- ```
24
-
25
- ## Usage example
26
-
27
- ```js
28
- import * as scanner from "@nodesecure/scanner";
29
- import fs from "fs/promises";
30
-
31
- // CONSTANTS
32
- const kPackagesToAnalyze = ["mocha", "cacache", "is-wsl"];
33
-
34
- const payloads = await Promise.all(
35
- kPackagesToAnalyze.map((name) => scanner.from(name))
36
- );
37
-
38
- const promises = [];
39
- for (let i = 0; i < kPackagesToAnalyze.length; i++) {
40
- const data = JSON.stringify(payloads[i], null, 2);
41
-
42
- promises.push(fs.writeFile(`${kPackagesToAnalyze[i]}.json`, data));
43
- }
44
- await Promise.allSettled(promises);
45
- ```
46
-
47
- ## API
48
-
49
- See `types/api.d.ts` for a complete TypeScript definition.
50
-
51
- ```ts
52
- function cwd(location: string, options?: Scanner.Options): Promise<Scanner.Payload>;
53
- function from(packageName: string, options?: Scanner.Options): Promise<Scanner.Payload>;
54
- function verify(packageName?: string | null): Promise<Scanner.VerifyPayload>;
55
- ```
56
-
57
- `Options` is described with the following TypeScript interface:
58
-
59
- ```ts
60
- interface Options {
61
- readonly maxDepth?: number;
62
- readonly usePackageLock?: boolean;
63
- readonly vulnerabilityStrategy: Strategy.Kind;
64
- readonly forceRootAnalysis?: boolean;
65
- readonly fullLockMode?: boolean;
66
- }
67
- ```
68
-
69
- ## Contributors ✨
70
-
71
- <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
72
- [![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#contributors-)
73
- <!-- ALL-CONTRIBUTORS-BADGE:END -->
74
-
75
- Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
76
-
77
- <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
78
- <!-- prettier-ignore-start -->
79
- <!-- markdownlint-disable -->
80
- <table>
81
- <tr>
82
- <td align="center"><a href="https://www.linkedin.com/in/thomas-gentilhomme/"><img src="https://avatars.githubusercontent.com/u/4438263?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gentilhomme</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=fraxken" title="Code">💻</a> <a href="https://github.com/NodeSecure/scanner/commits?author=fraxken" title="Documentation">📖</a> <a href="https://github.com/NodeSecure/scanner/pulls?q=is%3Apr+reviewed-by%3Afraxken" title="Reviewed Pull Requests">👀</a> <a href="#security-fraxken" title="Security">🛡️</a> <a href="https://github.com/NodeSecure/scanner/issues?q=author%3Afraxken" title="Bug reports">🐛</a></td>
83
- <td align="center"><a href="http://tonygo.dev"><img src="https://avatars.githubusercontent.com/u/22824417?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tony Gorez</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=tony-go" title="Code">💻</a> <a href="https://github.com/NodeSecure/scanner/commits?author=tony-go" title="Documentation">📖</a> <a href="https://github.com/NodeSecure/scanner/pulls?q=is%3Apr+reviewed-by%3Atony-go" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/NodeSecure/scanner/issues?q=author%3Atony-go" title="Bug reports">🐛</a></td>
84
- <td align="center"><a href="https://mickaelcroquet.fr"><img src="https://avatars.githubusercontent.com/u/23740372?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Haze</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=CroquetMickael" title="Code">💻</a></td>
85
- <td align="center"><a href="https://github.com/mbalabash"><img src="https://avatars.githubusercontent.com/u/16868922?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Maksim Balabash</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=mbalabash" title="Code">💻</a></td>
86
- </tr>
87
- </table>
88
-
89
- <!-- markdownlint-restore -->
90
- <!-- prettier-ignore-end -->
91
-
92
- <!-- ALL-CONTRIBUTORS-LIST:END -->
93
-
94
- ## License
95
- MIT
1
+ # NodeSecure Scanner
2
+ ![version](https://img.shields.io/badge/dynamic/json.svg?url=https://raw.githubusercontent.com/NodeSecure/scanner/master/package.json&query=$.version&label=Version)
3
+ [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/NodeSecure/scanner/commit-activity)
4
+ [![Security Responsible Disclosure](https://img.shields.io/badge/Security-Responsible%20Disclosure-yellow.svg)](https://github.com/nodejs/security-wg/blob/master/processes/responsible_disclosure_template.md
5
+ )
6
+ [![mit](https://img.shields.io/github/license/Naereen/StrapDown.js.svg)](https://github.com/NodeSecure/scanner/blob/master/LICENSE)
7
+ ![build](https://img.shields.io/github/workflow/status/NodeSecure/scanner/Node.js%20CI)
8
+
9
+ ⚡️ Run a static analysis of your module's dependencies.
10
+
11
+ ## Requirements
12
+
13
+ - [Node.js](https://nodejs.org/en/) version 16 or higher
14
+
15
+ ## Getting Started
16
+
17
+ This package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com).
18
+
19
+ ```bash
20
+ $ npm i @nodesecure/scanner
21
+ # or
22
+ $ yarn add @nodesecure/scanner
23
+ ```
24
+
25
+ ## Usage example
26
+
27
+ ```js
28
+ import * as scanner from "@nodesecure/scanner";
29
+ import fs from "fs/promises";
30
+
31
+ // CONSTANTS
32
+ const kPackagesToAnalyze = ["mocha", "cacache", "is-wsl"];
33
+
34
+ const payloads = await Promise.all(
35
+ kPackagesToAnalyze.map((name) => scanner.from(name))
36
+ );
37
+
38
+ const promises = [];
39
+ for (let i = 0; i < kPackagesToAnalyze.length; i++) {
40
+ const data = JSON.stringify(payloads[i], null, 2);
41
+
42
+ promises.push(fs.writeFile(`${kPackagesToAnalyze[i]}.json`, data));
43
+ }
44
+ await Promise.allSettled(promises);
45
+ ```
46
+
47
+ ## API
48
+
49
+ See `types/api.d.ts` for a complete TypeScript definition.
50
+
51
+ ```ts
52
+ function cwd(location: string, options?: Scanner.Options): Promise<Scanner.Payload>;
53
+ function from(packageName: string, options?: Omit<Scanner.Options, "includeDevDeps">): Promise<Scanner.Payload>;
54
+ function verify(packageName?: string | null): Promise<Scanner.VerifyPayload>;
55
+ ```
56
+
57
+ `Options` is described with the following TypeScript interface:
58
+
59
+ ```ts
60
+ interface Options {
61
+ readonly maxDepth?: number;
62
+ readonly usePackageLock?: boolean;
63
+ readonly includeDevDeps?: boolean;
64
+ readonly vulnerabilityStrategy: Strategy.Kind;
65
+ readonly forceRootAnalysis?: boolean;
66
+ readonly fullLockMode?: boolean;
67
+ }
68
+ ```
69
+
70
+ ## Contributors ✨
71
+
72
+ <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
73
+ [![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors-)
74
+ <!-- ALL-CONTRIBUTORS-BADGE:END -->
75
+
76
+ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
77
+
78
+ <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
79
+ <!-- prettier-ignore-start -->
80
+ <!-- markdownlint-disable -->
81
+ <table>
82
+ <tr>
83
+ <td align="center"><a href="https://www.linkedin.com/in/thomas-gentilhomme/"><img src="https://avatars.githubusercontent.com/u/4438263?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gentilhomme</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=fraxken" title="Code">💻</a> <a href="https://github.com/NodeSecure/scanner/commits?author=fraxken" title="Documentation">📖</a> <a href="https://github.com/NodeSecure/scanner/pulls?q=is%3Apr+reviewed-by%3Afraxken" title="Reviewed Pull Requests">👀</a> <a href="#security-fraxken" title="Security">🛡️</a> <a href="https://github.com/NodeSecure/scanner/issues?q=author%3Afraxken" title="Bug reports">🐛</a></td>
84
+ <td align="center"><a href="http://tonygo.dev"><img src="https://avatars.githubusercontent.com/u/22824417?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tony Gorez</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=tony-go" title="Code">💻</a> <a href="https://github.com/NodeSecure/scanner/commits?author=tony-go" title="Documentation">📖</a> <a href="https://github.com/NodeSecure/scanner/pulls?q=is%3Apr+reviewed-by%3Atony-go" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/NodeSecure/scanner/issues?q=author%3Atony-go" title="Bug reports">🐛</a></td>
85
+ <td align="center"><a href="https://mickaelcroquet.fr"><img src="https://avatars.githubusercontent.com/u/23740372?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Haze</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=CroquetMickael" title="Code">💻</a></td>
86
+ <td align="center"><a href="https://github.com/mbalabash"><img src="https://avatars.githubusercontent.com/u/16868922?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Maksim Balabash</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=mbalabash" title="Code">💻</a></td>
87
+ <td align="center"><a href="https://dev.to/antoinecoulon"><img src="https://avatars.githubusercontent.com/u/43391199?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Antoine Coulon</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=antoine-coulon" title="Code">💻</a> <a href="#security-antoine-coulon" title="Security">🛡️</a></td>
88
+ </tr>
89
+ </table>
90
+
91
+ <!-- markdownlint-restore -->
92
+ <!-- prettier-ignore-end -->
93
+
94
+ <!-- ALL-CONTRIBUTORS-LIST:END -->
95
+
96
+ ## License
97
+ MIT
package/index.js CHANGED
@@ -16,7 +16,7 @@ import Logger from "./src/class/logger.class.js";
16
16
  import * as tarball from "./src/tarball.js";
17
17
 
18
18
  // CONSTANTS
19
- const kDefaultCwdOptions = { forceRootAnalysis: true, usePackageLock: true };
19
+ const kDefaultCwdOptions = { forceRootAnalysis: true, usePackageLock: true, includeDevDeps: false };
20
20
 
21
21
  export async function cwd(location = process.cwd(), options = {}, logger = new Logger()) {
22
22
  const finalizedOptions = Object.assign({ location }, kDefaultCwdOptions, options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodesecure/scanner",
3
- "version": "3.3.0",
3
+ "version": "3.5.0",
4
4
  "description": "A package API to run a static analysis of your module's dependencies.",
5
5
  "exports": "./index.js",
6
6
  "engines": {
@@ -48,39 +48,39 @@
48
48
  },
49
49
  "homepage": "https://github.com/NodeSecure/scanner#readme",
50
50
  "devDependencies": {
51
- "@nodesecure/eslint-config": "^1.3.1",
51
+ "@nodesecure/eslint-config": "^1.4.0",
52
52
  "@slimio/is": "^1.5.1",
53
- "@small-tech/esm-tape-runner": "^1.0.3",
54
- "@small-tech/tap-monkey": "^1.3.0",
55
- "@types/node": "^17.0.13",
56
- "c8": "^7.11.0",
53
+ "@small-tech/esm-tape-runner": "^2.0.0",
54
+ "@small-tech/tap-monkey": "^1.4.0",
55
+ "@types/node": "^17.0.39",
56
+ "c8": "^7.11.3",
57
57
  "cross-env": "^7.0.3",
58
- "dotenv": "^14.3.2",
59
- "eslint": "^8.7.0",
58
+ "dotenv": "^16.0.1",
59
+ "eslint": "^8.17.0",
60
60
  "get-folder-size": "^3.1.0",
61
- "pkg-ok": "^2.3.1",
62
- "sinon": "^12.0.1",
61
+ "pkg-ok": "^3.0.0",
62
+ "sinon": "^14.0.0",
63
63
  "snap-shot-core": "^10.2.4",
64
- "tape": "^5.5.0"
64
+ "tape": "^5.5.3"
65
65
  },
66
66
  "dependencies": {
67
67
  "@nodesecure/flags": "^2.2.0",
68
68
  "@nodesecure/fs-walk": "^1.0.0",
69
- "@nodesecure/i18n": "^1.2.1",
70
- "@nodesecure/js-x-ray": "^4.2.0",
69
+ "@nodesecure/i18n": "^1.3.0",
70
+ "@nodesecure/js-x-ray": "^4.4.0",
71
71
  "@nodesecure/npm-registry-sdk": "^1.3.0",
72
72
  "@nodesecure/ntlp": "^2.1.0",
73
73
  "@nodesecure/utils": "^1.0.0",
74
- "@nodesecure/vuln": "^1.5.0",
75
- "@npm/types": "^1.0.1",
76
- "@npmcli/arborist": "^4.3.0",
74
+ "@nodesecure/vuln": "^1.7.0",
75
+ "@npm/types": "^1.0.2",
76
+ "@npmcli/arborist": "^5.2.1",
77
77
  "@slimio/lock": "^1.0.0",
78
- "builtins": "^4.0.0",
78
+ "builtins": "^5.0.1",
79
79
  "combine-async-iterators": "^2.0.1",
80
80
  "itertools": "^1.7.1",
81
81
  "lodash.difference": "^4.5.0",
82
- "pacote": "^12.0.3",
83
- "semver": "^7.3.4"
82
+ "pacote": "^13.6.0",
83
+ "semver": "^7.3.7"
84
84
  },
85
85
  "type": "module"
86
86
  }
@@ -1,99 +1,102 @@
1
- export default class Dependency {
2
- #flags = new Set();
3
- #parent = null;
4
-
5
- constructor(name, version, parent = null) {
6
- this.gitUrl = null;
7
- this.dependencyCount = 0;
8
- this.warnings = [];
9
- this.name = name;
10
- this.version = version;
11
-
12
- if (parent !== null) {
13
- parent.dependencyCount++;
14
- }
15
- this.#parent = parent;
16
- }
17
-
18
- get fullName() {
19
- return `${this.name} ${this.version}`;
20
- }
21
-
22
- get flags() {
23
- return [...this.#flags];
24
- }
25
-
26
- get parent() {
27
- return this.#parent === null ? {} : { [this.#parent.name]: this.#parent.version };
28
- }
29
-
30
- addFlag(flagName, predicate = true) {
31
- if (typeof flagName !== "string") {
32
- throw new TypeError("flagName argument must be typeof string");
33
- }
34
-
35
- if (predicate) {
36
- if (flagName === "hasDependencies" && this.#parent !== null) {
37
- this.#parent.addFlag("hasIndirectDependencies");
38
- }
39
-
40
- this.#flags.add(flagName);
41
- }
42
- }
43
-
44
- isGit(url) {
45
- this.#flags.add("isGit");
46
- if (typeof url === "string") {
47
- this.gitUrl = url;
48
- }
49
-
50
- return this;
51
- }
52
-
53
- exportAsPlainObject(customId) {
54
- if (this.warnings.length > 0) {
55
- this.addFlag("hasWarnings");
56
- }
57
-
58
- return {
59
- versions: {
60
- [this.version]: {
61
- id: typeof customId === "number" ? customId : Dependency.currentId++,
62
- usedBy: this.parent,
63
- flags: this.flags,
64
- description: "",
65
- size: 0,
66
- author: {},
67
- warnings: this.warnings,
68
- composition: {
69
- extensions: [],
70
- files: [],
71
- minified: [],
72
- unused: [],
73
- missing: [],
74
- required_files: [],
75
- required_nodejs: [],
76
- required_thirdparty: []
77
- },
78
- license: "unkown license",
79
- gitUrl: this.gitUrl
80
- }
81
- },
82
- vulnerabilities: [],
83
- metadata: {
84
- dependencyCount: this.dependencyCount,
85
- publishedCount: 0,
86
- lastUpdateAt: null,
87
- lastVersion: null,
88
- hasManyPublishers: false,
89
- hasReceivedUpdateInOneYear: true,
90
- homepage: null,
91
- author: {},
92
- publishers: [],
93
- maintainers: []
94
- }
95
- };
96
- }
97
- }
98
-
99
- Dependency.currentId = 1;
1
+ export default class Dependency {
2
+ #flags = new Set();
3
+ #parent = null;
4
+
5
+ constructor(name, version, parent = null) {
6
+ this.gitUrl = null;
7
+ this.dependencyCount = 0;
8
+ this.warnings = [];
9
+ this.name = name;
10
+ this.version = version;
11
+ this.dev = false;
12
+
13
+ if (parent !== null) {
14
+ parent.dependencyCount++;
15
+ }
16
+ this.#parent = parent;
17
+ }
18
+
19
+ get fullName() {
20
+ return `${this.name} ${this.version}`;
21
+ }
22
+
23
+ get flags() {
24
+ return [...this.#flags];
25
+ }
26
+
27
+ get parent() {
28
+ return this.#parent === null ? {} : { [this.#parent.name]: this.#parent.version };
29
+ }
30
+
31
+ addFlag(flagName, predicate = true) {
32
+ if (typeof flagName !== "string") {
33
+ throw new TypeError("flagName argument must be typeof string");
34
+ }
35
+
36
+ if (predicate) {
37
+ if (flagName === "hasDependencies" && this.#parent !== null) {
38
+ this.#parent.addFlag("hasIndirectDependencies");
39
+ }
40
+
41
+ this.#flags.add(flagName);
42
+ }
43
+ }
44
+
45
+ isGit(url) {
46
+ this.#flags.add("isGit");
47
+ if (typeof url === "string") {
48
+ this.gitUrl = url;
49
+ }
50
+
51
+ return this;
52
+ }
53
+
54
+ exportAsPlainObject(customId) {
55
+ if (this.warnings.length > 0) {
56
+ this.addFlag("hasWarnings");
57
+ }
58
+
59
+ return {
60
+ versions: {
61
+ [this.version]: {
62
+ id: typeof customId === "number" ? customId : Dependency.currentId++,
63
+ usedBy: this.parent,
64
+ isDevDependency: this.dev,
65
+ flags: this.flags,
66
+ description: "",
67
+ size: 0,
68
+ author: {},
69
+ warnings: this.warnings,
70
+ composition: {
71
+ extensions: [],
72
+ files: [],
73
+ minified: [],
74
+ unused: [],
75
+ missing: [],
76
+ required_files: [],
77
+ required_nodejs: [],
78
+ required_thirdparty: [],
79
+ required_subpath: []
80
+ },
81
+ license: "unkown license",
82
+ gitUrl: this.gitUrl
83
+ }
84
+ },
85
+ vulnerabilities: [],
86
+ metadata: {
87
+ dependencyCount: this.dependencyCount,
88
+ publishedCount: 0,
89
+ lastUpdateAt: null,
90
+ lastVersion: null,
91
+ hasManyPublishers: false,
92
+ hasReceivedUpdateInOneYear: true,
93
+ homepage: null,
94
+ author: {},
95
+ publishers: [],
96
+ maintainers: []
97
+ }
98
+ };
99
+ }
100
+ }
101
+
102
+ Dependency.currentId = 1;
package/src/depWalker.js CHANGED
@@ -75,13 +75,15 @@ export async function* searchDeepDependencies(packageName, gitURL, options) {
75
75
  yield current;
76
76
  }
77
77
 
78
- export async function* deepReadEdges(currentPackageName, { to, parent, exclude, fullLockMode }) {
78
+ export async function* deepReadEdges(currentPackageName, options) {
79
+ const { to, parent, exclude, fullLockMode, includeDevDeps } = options;
79
80
  const { version, integrity = to.integrity } = to.package;
80
81
 
81
82
  const updatedVersion = version === "*" || typeof version === "undefined" ? "latest" : version;
82
83
  const current = new Dependency(currentPackageName, updatedVersion, parent);
84
+ current.dev = to.dev;
83
85
 
84
- if (fullLockMode) {
86
+ if (fullLockMode && !includeDevDeps) {
85
87
  const { deprecated, _integrity, ...pkg } = await pacote.manifest(`${currentPackageName}@${updatedVersion}`, {
86
88
  ...NPM_TOKEN,
87
89
  registry: getLocalRegistryURL(),
@@ -96,7 +98,7 @@ export async function* deepReadEdges(currentPackageName, { to, parent, exclude,
96
98
  current.addFlag("hasDependencies", to.edgesOut.size > 0);
97
99
 
98
100
  for (const [packageName, { to: toNode }] of to.edgesOut) {
99
- if (toNode === null || toNode.dev) {
101
+ if (toNode === null || (!includeDevDeps && toNode.dev)) {
100
102
  continue;
101
103
  }
102
104
  const cleanName = `${packageName}@${toNode.package.version}`;
@@ -113,7 +115,11 @@ export async function* deepReadEdges(currentPackageName, { to, parent, exclude,
113
115
  }
114
116
 
115
117
  export async function* getRootDependencies(manifest, options) {
116
- const { maxDepth = 4, exclude, usePackageLock, fullLockMode, location } = options;
118
+ const {
119
+ maxDepth = 4, exclude,
120
+ usePackageLock, fullLockMode, includeDevDeps,
121
+ location
122
+ } = options;
117
123
 
118
124
  const { dependencies, customResolvers } = mergeDependencies(manifest, void 0);
119
125
  const parent = new Dependency(manifest.name, manifest.version);
@@ -137,9 +143,10 @@ export async function* getRootDependencies(manifest, options) {
137
143
  }
138
144
 
139
145
  iterators = [
140
- ...iter.filter(tree.edgesOut.entries(), ([, { to }]) => to !== null && (!to.dev || to.isWorkspace))
146
+ ...iter
147
+ .filter(tree.edgesOut.entries(), ([, { to }]) => to !== null && (includeDevDeps ? true : (!to.dev || to.isWorkspace)))
141
148
  .map(([packageName, { to }]) => [packageName, to.isWorkspace ? to.target : to])
142
- .map(([packageName, to]) => deepReadEdges(packageName, { to, parent, fullLockMode, exclude }))
149
+ .map(([packageName, to]) => deepReadEdges(packageName, { to, parent, fullLockMode, includeDevDeps, exclude }))
143
150
  ];
144
151
  }
145
152
  else {
@@ -178,6 +185,7 @@ export async function depWalker(manifest, options = {}, logger = new Logger()) {
178
185
  const {
179
186
  forceRootAnalysis = false,
180
187
  usePackageLock = false,
188
+ includeDevDeps = false,
181
189
  fullLockMode = false,
182
190
  maxDepth,
183
191
  location,
@@ -210,9 +218,9 @@ export async function depWalker(manifest, options = {}, logger = new Logger()) {
210
218
  const tarballLocker = new Lock({ maxConcurrent: 5 });
211
219
  tarballLocker.on("freeOne", () => logger.tick(ScannerLoggerEvents.analysis.tarball));
212
220
 
213
- const rootDepsOptions = { maxDepth, exclude, usePackageLock, fullLockMode, location };
221
+ const rootDepsOptions = { maxDepth, exclude, usePackageLock, fullLockMode, includeDevDeps, location };
214
222
  for await (const currentDep of getRootDependencies(manifest, rootDepsOptions)) {
215
- const { name, version } = currentDep;
223
+ const { name, version, dev } = currentDep;
216
224
  const current = currentDep.exportAsPlainObject(name === manifest.name ? 0 : void 0);
217
225
  let proceedDependencyAnalysis = true;
218
226
 
@@ -234,6 +242,11 @@ export async function depWalker(manifest, options = {}, logger = new Logger()) {
234
242
  dependencies.set(name, current);
235
243
  }
236
244
 
245
+ // If the dependency is a DevDependencies we ignore it.
246
+ if (dev) {
247
+ continue;
248
+ }
249
+
237
250
  if (proceedDependencyAnalysis) {
238
251
  logger.tick(ScannerLoggerEvents.analysis.tree);
239
252
 
@@ -270,7 +283,8 @@ export async function depWalker(manifest, options = {}, logger = new Logger()) {
270
283
 
271
284
  const { hydratePayloadDependencies, strategy } = await vuln.setStrategy(vulnerabilityStrategy);
272
285
  await hydratePayloadDependencies(dependencies, {
273
- useStandardFormat: true
286
+ useStandardFormat: true,
287
+ path: location
274
288
  });
275
289
 
276
290
  payload.vulnerabilityStrategy = strategy;