@nodesecure/scanner 3.3.0 → 3.4.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
@@ -50,7 +50,7 @@ See `types/api.d.ts` for a complete TypeScript definition.
50
50
 
51
51
  ```ts
52
52
  function cwd(location: string, options?: Scanner.Options): Promise<Scanner.Payload>;
53
- function from(packageName: string, options?: Scanner.Options): Promise<Scanner.Payload>;
53
+ function from(packageName: string, options?: Omit<Scanner.Options, "includeDevDeps">): Promise<Scanner.Payload>;
54
54
  function verify(packageName?: string | null): Promise<Scanner.VerifyPayload>;
55
55
  ```
56
56
 
@@ -60,6 +60,7 @@ function verify(packageName?: string | null): Promise<Scanner.VerifyPayload>;
60
60
  interface Options {
61
61
  readonly maxDepth?: number;
62
62
  readonly usePackageLock?: boolean;
63
+ readonly includeDevDeps?: boolean;
63
64
  readonly vulnerabilityStrategy: Strategy.Kind;
64
65
  readonly forceRootAnalysis?: boolean;
65
66
  readonly fullLockMode?: boolean;
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.4.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": {
@@ -52,34 +52,34 @@
52
52
  "@slimio/is": "^1.5.1",
53
53
  "@small-tech/esm-tape-runner": "^1.0.3",
54
54
  "@small-tech/tap-monkey": "^1.3.0",
55
- "@types/node": "^17.0.13",
55
+ "@types/node": "^17.0.21",
56
56
  "c8": "^7.11.0",
57
57
  "cross-env": "^7.0.3",
58
- "dotenv": "^14.3.2",
59
- "eslint": "^8.7.0",
58
+ "dotenv": "^16.0.0",
59
+ "eslint": "^8.11.0",
60
60
  "get-folder-size": "^3.1.0",
61
61
  "pkg-ok": "^2.3.1",
62
- "sinon": "^12.0.1",
62
+ "sinon": "^13.0.1",
63
63
  "snap-shot-core": "^10.2.4",
64
- "tape": "^5.5.0"
64
+ "tape": "^5.5.2"
65
65
  },
66
66
  "dependencies": {
67
67
  "@nodesecure/flags": "^2.2.0",
68
68
  "@nodesecure/fs-walk": "^1.0.0",
69
69
  "@nodesecure/i18n": "^1.2.1",
70
- "@nodesecure/js-x-ray": "^4.2.0",
70
+ "@nodesecure/js-x-ray": "^4.2.1",
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",
74
+ "@nodesecure/vuln": "^1.6.0",
75
75
  "@npm/types": "^1.0.1",
76
- "@npmcli/arborist": "^4.3.0",
76
+ "@npmcli/arborist": "^5.0.3",
77
77
  "@slimio/lock": "^1.0.0",
78
78
  "builtins": "^4.0.0",
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",
82
+ "pacote": "^13.0.5",
83
83
  "semver": "^7.3.4"
84
84
  },
85
85
  "type": "module"
@@ -1,99 +1,101 @@
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
+ },
80
+ license: "unkown license",
81
+ gitUrl: this.gitUrl
82
+ }
83
+ },
84
+ vulnerabilities: [],
85
+ metadata: {
86
+ dependencyCount: this.dependencyCount,
87
+ publishedCount: 0,
88
+ lastUpdateAt: null,
89
+ lastVersion: null,
90
+ hasManyPublishers: false,
91
+ hasReceivedUpdateInOneYear: true,
92
+ homepage: null,
93
+ author: {},
94
+ publishers: [],
95
+ maintainers: []
96
+ }
97
+ };
98
+ }
99
+ }
100
+
101
+ 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
 
@@ -1,36 +1,36 @@
1
- // Import Third-party Dependencies
2
- import { getToken, taggedString } from "@nodesecure/i18n";
3
-
4
- // CONSTANTS
5
- const kDetectedDep = taggedString`The dependency '${0}' has been detected in the dependency Tree.`;
6
- const kWarningsMessages = Object.freeze({
7
- "@scarf/scarf": getToken("warnings.disable_scarf"),
8
- iohook: getToken("warnings.keylogging")
9
- });
10
- const kPackages = new Set(Object.keys(kWarningsMessages));
11
- const kAuthors = new Set(["marak", "marak.squires@gmail.com"]);
12
-
13
- function getWarning(depName) {
14
- return `${kDetectedDep(depName)} ${kWarningsMessages[depName]}`;
15
- }
16
-
17
- export function getDependenciesWarnings(dependencies) {
18
- const warnings = [];
19
- for (const depName of kPackages) {
20
- if (dependencies.has(depName)) {
21
- warnings.push(getWarning(depName));
22
- }
23
- }
24
-
25
- // TODO: optimize with @nodesecure/author later
26
- for (const [packageName, dependency] of dependencies) {
27
- for (const { name, email } of dependency.metadata.maintainers) {
28
- if (kAuthors.has(name) || kAuthors.has(email)) {
29
- warnings.push(`'Marak Squires' package '${packageName}' has been detected in the dependency tree`);
30
- }
31
- }
32
- }
33
-
34
- return warnings;
35
- }
36
-
1
+ // Import Third-party Dependencies
2
+ import { getToken, taggedString } from "@nodesecure/i18n";
3
+
4
+ // CONSTANTS
5
+ const kDetectedDep = taggedString`The dependency '${0}' has been detected in the dependency Tree.`;
6
+ const kWarningsMessages = Object.freeze({
7
+ "@scarf/scarf": getToken("warnings.disable_scarf"),
8
+ iohook: getToken("warnings.keylogging")
9
+ });
10
+ const kPackages = new Set(Object.keys(kWarningsMessages));
11
+ const kAuthors = new Set(["marak", "marak.squires@gmail.com"]);
12
+
13
+ function getWarning(depName) {
14
+ return `${kDetectedDep(depName)} ${kWarningsMessages[depName]}`;
15
+ }
16
+
17
+ export function getDependenciesWarnings(dependencies) {
18
+ const warnings = [];
19
+ for (const depName of kPackages) {
20
+ if (dependencies.has(depName)) {
21
+ warnings.push(getWarning(depName));
22
+ }
23
+ }
24
+
25
+ // TODO: optimize with @nodesecure/author later
26
+ for (const [packageName, dependency] of dependencies) {
27
+ for (const { name, email } of dependency.metadata.maintainers) {
28
+ if (kAuthors.has(name) || kAuthors.has(email)) {
29
+ warnings.push(`'Marak Squires' package '${packageName}' has been detected in the dependency tree`);
30
+ }
31
+ }
32
+ }
33
+
34
+ return warnings;
35
+ }
36
+
package/types/api.d.ts CHANGED
@@ -11,5 +11,5 @@ export {
11
11
  declare const ScannerLoggerEvents: LoggerEvents;
12
12
 
13
13
  declare function cwd(location: string, options?: Scanner.Options, logger?: Logger): Promise<Scanner.Payload>;
14
- declare function from(packageName: string, options?: Scanner.Options, logger?: Logger): Promise<Scanner.Payload>;
14
+ declare function from(packageName: string, options?: Omit<Scanner.Options, "includeDevDeps">, logger?: Logger): Promise<Scanner.Payload>;
15
15
  declare function verify(packageName?: string | null): Promise<Scanner.VerifyPayload>;
@@ -1,185 +1,192 @@
1
- // Import NodeSecure Dependencies
2
- import * as JSXRay from "@nodesecure/js-x-ray";
3
- import { license as License } from "@nodesecure/ntlp";
4
- import * as Vuln from "@nodesecure/vuln";
5
- import { Flags } from "@nodesecure/flags";
6
-
7
- // Import Third-party Dependencies
8
- import { Maintainer } from "@npm/types";
9
-
10
- export = Scanner;
11
-
12
- declare namespace Scanner {
13
- export interface Publisher {
14
- /**
15
- * Publisher npm user name.
16
- */
17
- name: string;
18
- /**
19
- * Publisher npm user email.
20
- */
21
- email: string;
22
- /**
23
- * First version published.
24
- */
25
- version: string;
26
- /**
27
- * Date of the first publication
28
- * @example 2021-08-10T20:45:08.342Z
29
- */
30
- at: string;
31
- }
32
-
33
- export interface DependencyVersion {
34
- /** Id of the package (useful for usedBy relation) */
35
- id: number;
36
- /** By whom (id) is used the package */
37
- usedBy: Record<string, string>;
38
- /** Size on disk of the extracted tarball (in bytes) */
39
- size: number;
40
- /** Package description */
41
- description: string;
42
- /** Author of the package. This information is not trustable and can be empty. */
43
- author: Maintainer;
44
- /**
45
- * JS-X-Ray warnings
46
- *
47
- * @see https://github.com/NodeSecure/js-x-ray/blob/master/WARNINGS.md
48
- */
49
- warnings: JSXRay.Warning<JSXRay.BaseWarning>[];
50
- /** Tarball composition (files and dependencies) */
51
- composition: {
52
- /** Files extensions (.js, .md, .exe etc..) */
53
- extensions: string[];
54
- files: string[];
55
- /** Minified files (foo.min.js etc..) */
56
- minified: string[];
57
- required_files: string[];
58
- required_thirdparty: string[];
59
- required_nodejs: string[];
60
- unused: string[];
61
- missing: string[];
62
- };
63
- /**
64
- * Package licenses with SPDX expression.
65
- *
66
- * @see https://github.com/NodeSecure/licenses-conformance
67
- * @see https://github.com/NodeSecure/npm-tarball-license-parser
68
- */
69
- license: License[];
70
- /**
71
- * Flags (Array of string)
72
- *
73
- * @see https://github.com/NodeSecure/flags/blob/main/FLAGS.md
74
- */
75
- flags: Flags[];
76
- /**
77
- * If the dependency is a GIT repository
78
- */
79
- gitUrl: null | string;
80
- }
81
-
82
- export interface Dependency {
83
- /** NPM Registry metadata */
84
- metadata: {
85
- /** Count of dependencies */
86
- dependencyCount: number;
87
- /** Number of releases published on npm */
88
- publishedCount: number;
89
- lastUpdateAt: number;
90
- /** Last version SemVer */
91
- lastVersion: number;
92
- hasChangedAuthor: boolean;
93
- hasManyPublishers: boolean;
94
- hasReceivedUpdateInOneYear: boolean;
95
- /** Author of the package. This information is not trustable and can be empty. */
96
- author: Maintainer;
97
- /** Package home page */
98
- homepage: string | null;
99
- /**
100
- * List of maintainers (list of people in the organization related to the package)
101
- */
102
- maintainers: { name: string, email: string }[];
103
- /**
104
- * List of people who published this package
105
- */
106
- publishers: Publisher[];
107
- }
108
- /** List of versions of this package available in the dependency tree (In the payload) */
109
- versions: Record<string, DependencyVersion>;
110
- /**
111
- * Vulnerabilities fetched dependending on the selected vulnerabilityStrategy
112
- *
113
- * @see https://github.com/NodeSecure/vuln
114
- */
115
- vulnerabilities: Vuln.Strategy.StandardVulnerability[];
116
- }
117
-
118
- export type GlobalWarning = string[];
119
- export type Dependencies = Record<string, Dependency>;
120
-
121
- export interface Payload {
122
- /** Payload unique id */
123
- id: string;
124
- /** Name of the analyzed package */
125
- rootDependencyName: string;
126
- /** Global warnings list */
127
- warnings: GlobalWarning[];
128
- /** All the dependencies of the package (flattened) */
129
- dependencies: Dependencies;
130
- /** Version of the scanner used to generate the result */
131
- scannerVersion: string;
132
- /** Vulnerability strategy name (npm, snyk, node) */
133
- vulnerabilityStrategy: Vuln.Strategy.Kind;
134
- }
135
-
136
- export interface VerifyPayload {
137
- files: {
138
- list: string[];
139
- extensions: string[];
140
- minified: string[];
141
- };
142
- directorySize: number;
143
- uniqueLicenseIds: string[];
144
- licenses: License[];
145
- ast: {
146
- dependencies: Record<string, JSXRay.Dependency>;
147
- warnings: JSXRay.Warning<JSXRay.BaseWarning>[];
148
- };
149
- }
150
-
151
- export interface Options {
152
- /**
153
- * Maximum tree depth
154
- *
155
- * @default 4
156
- */
157
- readonly maxDepth?: number;
158
- /**
159
- * Use root package-lock.json. This will have the effect of triggering the Arborist package.
160
- *
161
- * @default false for from() API
162
- * @default true for cwd() API
163
- */
164
- readonly usePackageLock?: boolean;
165
- /**
166
- * Vulnerability strategy name (npm, snyk, node)
167
- *
168
- * @default NONE
169
- */
170
- readonly vulnerabilityStrategy: Vuln.Strategy.Kind;
171
- /**
172
- * Analyze root package.
173
- *
174
- * @default false for from() API
175
- * @default true for cwd() API
176
- */
177
- readonly forceRootAnalysis?: boolean;
178
- /**
179
- * Deeper dependencies analysis with cwd() API.
180
- *
181
- * @default false
182
- */
183
- readonly fullLockMode?: boolean;
184
- }
185
- }
1
+ // Import NodeSecure Dependencies
2
+ import * as JSXRay from "@nodesecure/js-x-ray";
3
+ import { license as License } from "@nodesecure/ntlp";
4
+ import * as Vuln from "@nodesecure/vuln";
5
+ import { Flags } from "@nodesecure/flags";
6
+
7
+ // Import Third-party Dependencies
8
+ import { Maintainer } from "@npm/types";
9
+
10
+ export = Scanner;
11
+
12
+ declare namespace Scanner {
13
+ export interface Publisher {
14
+ /**
15
+ * Publisher npm user name.
16
+ */
17
+ name: string;
18
+ /**
19
+ * Publisher npm user email.
20
+ */
21
+ email: string;
22
+ /**
23
+ * First version published.
24
+ */
25
+ version: string;
26
+ /**
27
+ * Date of the first publication
28
+ * @example 2021-08-10T20:45:08.342Z
29
+ */
30
+ at: string;
31
+ }
32
+
33
+ export interface DependencyVersion {
34
+ /** Id of the package (useful for usedBy relation) */
35
+ id: number;
36
+ isDevDependency: boolean;
37
+ /** By whom (id) is used the package */
38
+ usedBy: Record<string, string>;
39
+ /** Size on disk of the extracted tarball (in bytes) */
40
+ size: number;
41
+ /** Package description */
42
+ description: string;
43
+ /** Author of the package. This information is not trustable and can be empty. */
44
+ author: Maintainer;
45
+ /**
46
+ * JS-X-Ray warnings
47
+ *
48
+ * @see https://github.com/NodeSecure/js-x-ray/blob/master/WARNINGS.md
49
+ */
50
+ warnings: JSXRay.Warning<JSXRay.BaseWarning>[];
51
+ /** Tarball composition (files and dependencies) */
52
+ composition: {
53
+ /** Files extensions (.js, .md, .exe etc..) */
54
+ extensions: string[];
55
+ files: string[];
56
+ /** Minified files (foo.min.js etc..) */
57
+ minified: string[];
58
+ required_files: string[];
59
+ required_thirdparty: string[];
60
+ required_nodejs: string[];
61
+ unused: string[];
62
+ missing: string[];
63
+ };
64
+ /**
65
+ * Package licenses with SPDX expression.
66
+ *
67
+ * @see https://github.com/NodeSecure/licenses-conformance
68
+ * @see https://github.com/NodeSecure/npm-tarball-license-parser
69
+ */
70
+ license: License[];
71
+ /**
72
+ * Flags (Array of string)
73
+ *
74
+ * @see https://github.com/NodeSecure/flags/blob/main/FLAGS.md
75
+ */
76
+ flags: Flags[];
77
+ /**
78
+ * If the dependency is a GIT repository
79
+ */
80
+ gitUrl: null | string;
81
+ }
82
+
83
+ export interface Dependency {
84
+ /** NPM Registry metadata */
85
+ metadata: {
86
+ /** Count of dependencies */
87
+ dependencyCount: number;
88
+ /** Number of releases published on npm */
89
+ publishedCount: number;
90
+ lastUpdateAt: number;
91
+ /** Last version SemVer */
92
+ lastVersion: number;
93
+ hasChangedAuthor: boolean;
94
+ hasManyPublishers: boolean;
95
+ hasReceivedUpdateInOneYear: boolean;
96
+ /** Author of the package. This information is not trustable and can be empty. */
97
+ author: Maintainer;
98
+ /** Package home page */
99
+ homepage: string | null;
100
+ /**
101
+ * List of maintainers (list of people in the organization related to the package)
102
+ */
103
+ maintainers: { name: string, email: string }[];
104
+ /**
105
+ * List of people who published this package
106
+ */
107
+ publishers: Publisher[];
108
+ }
109
+ /** List of versions of this package available in the dependency tree (In the payload) */
110
+ versions: Record<string, DependencyVersion>;
111
+ /**
112
+ * Vulnerabilities fetched dependending on the selected vulnerabilityStrategy
113
+ *
114
+ * @see https://github.com/NodeSecure/vuln
115
+ */
116
+ vulnerabilities: Vuln.Strategy.StandardVulnerability[];
117
+ }
118
+
119
+ export type GlobalWarning = string[];
120
+ export type Dependencies = Record<string, Dependency>;
121
+
122
+ export interface Payload {
123
+ /** Payload unique id */
124
+ id: string;
125
+ /** Name of the analyzed package */
126
+ rootDependencyName: string;
127
+ /** Global warnings list */
128
+ warnings: GlobalWarning[];
129
+ /** All the dependencies of the package (flattened) */
130
+ dependencies: Dependencies;
131
+ /** Version of the scanner used to generate the result */
132
+ scannerVersion: string;
133
+ /** Vulnerability strategy name (npm, snyk, node) */
134
+ vulnerabilityStrategy: Vuln.Strategy.Kind;
135
+ }
136
+
137
+ export interface VerifyPayload {
138
+ files: {
139
+ list: string[];
140
+ extensions: string[];
141
+ minified: string[];
142
+ };
143
+ directorySize: number;
144
+ uniqueLicenseIds: string[];
145
+ licenses: License[];
146
+ ast: {
147
+ dependencies: Record<string, JSXRay.Dependency>;
148
+ warnings: JSXRay.Warning<JSXRay.BaseWarning>[];
149
+ };
150
+ }
151
+
152
+ export interface Options {
153
+ /**
154
+ * Maximum tree depth
155
+ *
156
+ * @default 4
157
+ */
158
+ readonly maxDepth?: number;
159
+ /**
160
+ * Use root package-lock.json. This will have the effect of triggering the Arborist package.
161
+ *
162
+ * @default false for from() API
163
+ * @default true for cwd() API
164
+ */
165
+ readonly usePackageLock?: boolean;
166
+ /**
167
+ * Include project devDependencies (only available for cwd command)
168
+ *
169
+ * @default false
170
+ */
171
+ readonly includeDevDeps?: boolean;
172
+ /**
173
+ * Vulnerability strategy name (npm, snyk, node)
174
+ *
175
+ * @default NONE
176
+ */
177
+ readonly vulnerabilityStrategy: Vuln.Strategy.Kind;
178
+ /**
179
+ * Analyze root package.
180
+ *
181
+ * @default false for from() API
182
+ * @default true for cwd() API
183
+ */
184
+ readonly forceRootAnalysis?: boolean;
185
+ /**
186
+ * Deeper dependencies analysis with cwd() API.
187
+ *
188
+ * @default false
189
+ */
190
+ readonly fullLockMode?: boolean;
191
+ }
192
+ }