dependency-radar 0.7.0 → 0.8.1
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 +108 -7
- package/dist/aggregator.js +35 -9
- package/dist/cli.js +347 -39
- package/dist/compare.js +79 -0
- package/dist/failOn.js +16 -2
- package/dist/findings.js +166 -0
- package/dist/generated/spdx.js +3 -0
- package/dist/nodeEngine.js +181 -0
- package/dist/outputFormats.js +185 -0
- package/dist/report-assets.js +2 -2
- package/dist/report.js +137 -71
- package/dist/runners/importGraphRunner.js +9 -5
- package/dist/runners/lockfileGraph.js +144 -1
- package/dist/runners/lockfileSignals.js +303 -0
- package/dist/runners/npmLs.js +15 -0
- package/dist/schema.js +107 -0
- package/dist/utils.js +62 -3
- package/dist/why.js +69 -0
- package/dist/workspaceFilter.js +25 -0
- package/package.json +6 -5
- package/dist/runners/depcheckRunner.js +0 -23
- package/dist/runners/licenseChecker.js +0 -33
- package/dist/runners/madgeRunner.js +0 -29
package/README.md
CHANGED
|
@@ -34,6 +34,9 @@ This runs a scan against the current project and writes a self-contained `depend
|
|
|
34
34
|
- **Full transitive tree** — shows depth, parent relationships, fan-in/fan-out, and dependency origins
|
|
35
35
|
- **Workspace support** — works across npm, pnpm, and Yarn workspaces
|
|
36
36
|
- **CI-friendly** — `--fail-on` flag lets you enforce licence and vulnerability policies in pipelines
|
|
37
|
+
- **Review-friendly outputs** — emit JSON, SARIF, CycloneDX SBOM, or SPDX SBOM artifacts from the same local scan
|
|
38
|
+
- **Change comparison** — compare a fresh scan with a previous `dependency-radar.json` to see added dependencies, removed dependencies, version changes, and new findings
|
|
39
|
+
- **Lockfile supply-chain signals** — flags git/local/tarball sources, missing integrity, unexpected registry hosts, and optional npm signature/provenance verification
|
|
37
40
|
- **Completely offline-capable** — use `--offline` to skip registry calls; all package metadata is read from local `node_modules`
|
|
38
41
|
- **Single self-contained HTML file** — no server needed; open it locally, attach it to a ticket, or share it with your team
|
|
39
42
|
|
|
@@ -94,8 +97,14 @@ The `scan` command is the default and can also be run explicitly as `npx depende
|
|
|
94
97
|
| `--project <path>` | Path to the project to scan (defaults to current directory) |
|
|
95
98
|
| `--quiet` | Suppress progress/info logs, browser opening, and footer messaging while keeping the final summary and failures visible |
|
|
96
99
|
| `--out <path>` | Output path for the report file |
|
|
100
|
+
| `--format <format>` | Output format: `html`, `json`, `sarif`, `cyclonedx`, or `spdx` |
|
|
101
|
+
| `--sbom <format>` | Convenience alias for SBOM output: `cyclonedx` or `spdx` |
|
|
102
|
+
| `--target-node <major>` | Add Node major compatibility findings based on local `engines.node` metadata |
|
|
103
|
+
| `--audit-signatures` | Run `npm audit signatures` for registry signature/provenance verification (opt-in; skipped with `--offline`) |
|
|
104
|
+
| `--schema` | Print the current Dependency Radar JSON schema, or write it with `--out <path>` |
|
|
97
105
|
| `--offline` | Skip `npm audit` and `npm outdated` (useful for offline/air-gapped scans) |
|
|
98
106
|
| `--json` | Output JSON instead of HTML (`dependency-radar.json`) |
|
|
107
|
+
| `--timestamp` | Add a local timestamp to generated report filenames (`dependency-radar.YYYY-MM-DD_HH-mm-ss.html`) |
|
|
99
108
|
| `--no-report` | Run analysis only; no HTML/JSON output written |
|
|
100
109
|
| `--keep-temp` | Keep the temporary `.dependency-radar/` folder for debugging |
|
|
101
110
|
| `--open` | Open the generated report using the system default browser |
|
|
@@ -145,6 +154,26 @@ Notes:
|
|
|
145
154
|
- "Static import evidence" means Dependency Radar found local source imports for that package. It is a code-usage heuristic, not exploit reachability analysis.
|
|
146
155
|
- "Introduced via root packages" and "Direct parents" are shown from the current scan model. The command does not currently print full ancestry chains.
|
|
147
156
|
|
|
157
|
+
### Show why a dependency is present
|
|
158
|
+
|
|
159
|
+
Use `why` to print shortest dependency paths from direct dependencies to a package:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
npx dependency-radar why lodash
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
This uses the same local scan model as the HTML report. When full paths are unavailable, it falls back to the package origins and direct parent evidence available in the report model.
|
|
166
|
+
|
|
167
|
+
### Compare against a previous report
|
|
168
|
+
|
|
169
|
+
Use `compare` to scan the current project and compare it with an earlier JSON report:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
npx dependency-radar compare ./dependency-radar-before.json --json --offline
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
The comparison highlights added dependencies, removed dependencies, one-version package changes, new findings, and resolved findings. This is useful in pull requests and release checks.
|
|
176
|
+
|
|
148
177
|
### CI policy enforcement (`--fail-on`)
|
|
149
178
|
|
|
150
179
|
```
|
|
@@ -161,6 +190,7 @@ Supported rules:
|
|
|
161
190
|
| `licence-mismatch` | Fail if at least one dependency has a declared-vs-inferred licence mismatch |
|
|
162
191
|
| `copyleft-detected` | Fail if strong copyleft (GPL/AGPL) appears in runtime dependencies |
|
|
163
192
|
| `unknown-licence` | Fail if at least one dependency has neither declared nor inferred licence data |
|
|
193
|
+
| `supply-chain-source` | Fail if lockfile source signals detect git/local/tarball sources, missing integrity, or unexpected registry hosts |
|
|
164
194
|
|
|
165
195
|
When rules are violated, Dependency Radar prints `✖ Policy violations detected:` and exits `1`. Unknown rules also exit `1` with a clear error message.
|
|
166
196
|
|
|
@@ -176,6 +206,42 @@ npx dependency-radar --open
|
|
|
176
206
|
npx dependency-radar --project ./my-app --out ./reports/dependency-radar.html
|
|
177
207
|
```
|
|
178
208
|
|
|
209
|
+
### Example: write SARIF for CI/code scanning
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
npx dependency-radar --format sarif --out ./reports/dependency-radar.sarif
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Example: write an SBOM
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
npx dependency-radar --sbom cyclonedx --out ./reports/bom.cdx.json
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
npx dependency-radar --sbom spdx --out ./reports/bom.spdx.json
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Example: check Node upgrade readiness signals
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
npx dependency-radar --target-node 22
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Example: verify npm registry signatures/provenance
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
npx dependency-radar --audit-signatures
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
This runs `npm audit signatures` as an opt-in online check. It is skipped when `--offline` is used.
|
|
238
|
+
|
|
239
|
+
### Example: write the JSON schema
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
npx dependency-radar --schema --out ./reports/dependency-radar.schema.json
|
|
243
|
+
```
|
|
244
|
+
|
|
179
245
|
### Example: keep temp files for debugging
|
|
180
246
|
```bash
|
|
181
247
|
npx dependency-radar --keep-temp
|
|
@@ -241,7 +307,8 @@ The blocker detail counts can overlap: a single package may contribute to multip
|
|
|
241
307
|
| pnpm | ✅ Lockfile-first (`pnpm-lock.yaml`) | ✅ | ✅ | ✅ |
|
|
242
308
|
| Yarn Classic (v1) | ✅ Lockfile-first (`yarn.lock`) | ✅ | ✅ | ✅ |
|
|
243
309
|
| Yarn Berry (v2+, node-modules linker) | ✅ Lockfile-first (`yarn.lock`) | ✅ | ⚠️ Plugin-dependent | ✅ |
|
|
244
|
-
| Yarn Plug'n'Play |
|
|
310
|
+
| Yarn Plug'n'Play | ⚠️ Lockfile-derived graph only; package metadata may be incomplete without `node_modules` | ✅ | ⚠️ Plugin-dependent | ✅ |
|
|
311
|
+
| Bun | ⚠️ Text `bun.lock` parsing; binary `bun.lockb` is reported with a migration hint | N/A | ❌ | ⚠️ package.json workspaces only |
|
|
245
312
|
|
|
246
313
|
## Requirements
|
|
247
314
|
|
|
@@ -252,12 +319,13 @@ The blocker detail counts can overlap: a single package may contribute to multip
|
|
|
252
319
|
|
|
253
320
|
When you run `npx dependency-radar` (or `dependency-radar scan`), the CLI executes this pipeline:
|
|
254
321
|
|
|
255
|
-
1. Parse CLI options (`--project`, `--out`, `--offline`, `--json`, `--no-report`, `--keep-temp`, `--open`, `--fail-on`).
|
|
322
|
+
1. Parse CLI options (`--project`, `--out`, `--offline`, `--json`, `--timestamp`, `--no-report`, `--keep-temp`, `--open`, `--fail-on`, `--audit-signatures`, `--schema`).
|
|
256
323
|
2. Detect workspace/package-manager context:
|
|
257
324
|
- Workspace roots from `pnpm-workspace.yaml` or `package.json#workspaces`
|
|
258
325
|
- Dependency policy from `package.json` and `pnpm-workspace.yaml` overrides/resolutions
|
|
259
326
|
- Package manager from `packageManager`, lockfiles, and installed metadata
|
|
260
327
|
- Yarn Plug'n'Play detection (`.pnp.cjs`/`.pnp.js` or `.yarnrc.yml nodeLinker: pnp`)
|
|
328
|
+
- Bun text lockfile detection (`bun.lock`; binary `bun.lockb` is not parsed)
|
|
261
329
|
3. Create a temporary `.dependency-radar/` directory inside the scanned project.
|
|
262
330
|
4. For each workspace package (or just the project root in single-package mode), collect dependency graph data:
|
|
263
331
|
- Lockfile-first graph parsing (`pnpm-lock.yaml`, `npm-shrinkwrap.json`/`package-lock.json`, `yarn.lock`)
|
|
@@ -267,6 +335,8 @@ When you run `npx dependency-radar` (or `dependency-radar scan`), the CLI execut
|
|
|
267
335
|
- Vulnerabilities (`npm audit` / `pnpm audit` / `yarn audit` or `yarn npm audit`)
|
|
268
336
|
- Version drift (`npm outdated` / `pnpm outdated` / `yarn outdated`, where available)
|
|
269
337
|
- Source import graph (static import/require parsing in `src/` or project root)
|
|
338
|
+
- Lockfile supply-chain source signals
|
|
339
|
+
- Optional npm registry signature/provenance verification (`--audit-signatures`)
|
|
270
340
|
6. Normalize outputs into one internal shape and merge workspace package results.
|
|
271
341
|
- PNPM lock/CLI dependency trees are filtered to installed-only packages (non-installed optional/platform variants are dropped)
|
|
272
342
|
7. Resolve and crawl installed package directories in `node_modules` to collect local metadata:
|
|
@@ -278,10 +348,15 @@ When you run `npx dependency-radar` (or `dependency-radar scan`), the CLI execut
|
|
|
278
348
|
- Root-cause/origin and runtime-impact heuristics
|
|
279
349
|
- Install-time execution signals
|
|
280
350
|
- Local package metadata (`description`, links, deprecation, TypeScript type availability, installed file count, CLI `bin` presence)
|
|
281
|
-
9.
|
|
351
|
+
9. Build normalized findings from the aggregated dependency model:
|
|
352
|
+
- Vulnerabilities, license review items, install-time execution surface, native bindings, deprecated packages, target Node compatibility findings, lockfile source signals, and npm signature/provenance failures
|
|
353
|
+
10. Write final output as one of:
|
|
282
354
|
- `dependency-radar.html` (self-contained report), or
|
|
283
355
|
- `dependency-radar.json` (raw aggregated model)
|
|
284
|
-
|
|
356
|
+
- SARIF (`--format sarif`)
|
|
357
|
+
- CycloneDX SBOM (`--format cyclonedx` / `--sbom cyclonedx`)
|
|
358
|
+
- SPDX SBOM (`--format spdx` / `--sbom spdx`)
|
|
359
|
+
11. Remove `.dependency-radar/` unless `--keep-temp` is set.
|
|
285
360
|
|
|
286
361
|
The scan is local-first: package metadata is read from `node_modules`; only audit/outdated commands require registry access.
|
|
287
362
|
|
|
@@ -400,7 +475,7 @@ The JSON schema matches the `AggregatedData` TypeScript interface in `src/types.
|
|
|
400
475
|
|
|
401
476
|
```ts
|
|
402
477
|
export interface AggregatedData {
|
|
403
|
-
schemaVersion: '1.
|
|
478
|
+
schemaVersion: '1.4'; // Report schema version for compatibility checks
|
|
404
479
|
generatedAt: string; // ISO timestamp when the scan finished
|
|
405
480
|
dependencyRadarVersion: string; // CLI version that produced the report
|
|
406
481
|
git: {
|
|
@@ -438,11 +513,12 @@ export interface AggregatedData {
|
|
|
438
513
|
nodeVersion: string; // Node.js version from process.versions.node
|
|
439
514
|
runtimeVersion: string; // Node.js runtime version from process.version
|
|
440
515
|
minRequiredMajor: number; // Strictest Node major required by dependency engines (0 if unknown)
|
|
516
|
+
targetNodeMajor?: number; // Node major passed through --target-node
|
|
441
517
|
platform?: string; // OS platform (process.platform)
|
|
442
518
|
arch?: string; // CPU architecture (process.arch)
|
|
443
519
|
ci?: boolean; // True when CI indicators are detected
|
|
444
520
|
packageManagerField?: string; // package.json packageManager field (e.g. pnpm@9.1.0)
|
|
445
|
-
packageManager?: 'npm' | 'pnpm' | 'yarn'; // Package manager used for dependency/audit/outdated collection
|
|
521
|
+
packageManager?: 'npm' | 'pnpm' | 'yarn' | 'bun'; // Package manager used for dependency/audit/outdated collection
|
|
446
522
|
packageManagerVersion?: string; // Version of the selected package manager (when available)
|
|
447
523
|
toolVersions?: {
|
|
448
524
|
npm?: string;
|
|
@@ -452,7 +528,7 @@ export interface AggregatedData {
|
|
|
452
528
|
};
|
|
453
529
|
workspaces: {
|
|
454
530
|
enabled: boolean; // True when the scan used workspace aggregation
|
|
455
|
-
type?: 'npm' | 'pnpm' | 'yarn' | 'none'; // Workspace mode (CLI currently always emits this)
|
|
531
|
+
type?: 'npm' | 'pnpm' | 'yarn' | 'bun' | 'none'; // Workspace mode (CLI currently always emits this)
|
|
456
532
|
packageCount?: number; // Number of workspace packages scanned (CLI currently always emits this)
|
|
457
533
|
workspacePackages?: WorkspacePackage[]; // Lightweight first-party workspace metadata
|
|
458
534
|
};
|
|
@@ -460,7 +536,32 @@ export interface AggregatedData {
|
|
|
460
536
|
dependencyCount: number; // Total EXTERNAL dependencies in the graph
|
|
461
537
|
directCount: number; // External dependencies listed in package.json
|
|
462
538
|
transitiveCount: number; // External dependencies pulled in by other dependencies
|
|
539
|
+
findingCount?: number; // Number of normalized findings generated from the dependency model
|
|
540
|
+
};
|
|
541
|
+
supplyChain?: {
|
|
542
|
+
signals: Array<{
|
|
543
|
+
type:
|
|
544
|
+
| 'git-dependency'
|
|
545
|
+
| 'file-dependency'
|
|
546
|
+
| 'non-registry-tarball'
|
|
547
|
+
| 'missing-integrity'
|
|
548
|
+
| 'unexpected-registry-host'
|
|
549
|
+
| 'signature-verification-failed'
|
|
550
|
+
| 'signature-verification-unavailable';
|
|
551
|
+
packageName?: string;
|
|
552
|
+
packageVersion?: string;
|
|
553
|
+
packageId?: string;
|
|
554
|
+
source: string;
|
|
555
|
+
detail: string;
|
|
556
|
+
}>;
|
|
557
|
+
signatureAudit?: {
|
|
558
|
+
attempted: boolean;
|
|
559
|
+
ok: boolean;
|
|
560
|
+
output?: string;
|
|
561
|
+
error?: string;
|
|
562
|
+
};
|
|
463
563
|
};
|
|
564
|
+
findings?: DependencyFinding[]; // Normalized review/CI findings
|
|
464
565
|
dependencies: Record<string, DependencyRecord>; // External third-party packages keyed by name@version
|
|
465
566
|
}
|
|
466
567
|
|
package/dist/aggregator.js
CHANGED
|
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.aggregateData = aggregateData;
|
|
7
7
|
const utils_1 = require("./utils");
|
|
8
8
|
const license_1 = require("./license");
|
|
9
|
+
const findings_1 = require("./findings");
|
|
10
|
+
const nodeEngine_1 = require("./nodeEngine");
|
|
9
11
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
10
12
|
const path_1 = __importDefault(require("path"));
|
|
11
13
|
const os_1 = __importDefault(require("os"));
|
|
@@ -286,7 +288,7 @@ function isWorkspacePackageNode(node, input) {
|
|
|
286
288
|
return false;
|
|
287
289
|
}
|
|
288
290
|
async function aggregateData(input) {
|
|
289
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
291
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
290
292
|
const pkg = input.pkgOverride || (await (0, utils_1.readPackageJson)(input.projectPath));
|
|
291
293
|
let projectPkg = input.projectPackageJson;
|
|
292
294
|
if (!projectPkg) {
|
|
@@ -305,7 +307,8 @@ async function aggregateData(input) {
|
|
|
305
307
|
const importGraph = normalizeImportGraph((_c = input.importGraphResult) === null || _c === void 0 ? void 0 : _c.data);
|
|
306
308
|
const usageResult = buildUsageSummary(importGraph, input.projectPath);
|
|
307
309
|
const outdatedById = buildOutdatedMap(input.outdatedResult);
|
|
308
|
-
const
|
|
310
|
+
const supplyChain = normalizeSupplyChain((_d = input.supplyChainResult) === null || _d === void 0 ? void 0 : _d.data);
|
|
311
|
+
const outdatedUnknownNames = new Set(((_e = input.outdatedResult) === null || _e === void 0 ? void 0 : _e.unknownNames) || []);
|
|
309
312
|
const packageMetaCache = new Map();
|
|
310
313
|
const resolvePaths = input.resolvePaths && input.resolvePaths.length > 0
|
|
311
314
|
? input.resolvePaths
|
|
@@ -346,7 +349,7 @@ async function aggregateData(input) {
|
|
|
346
349
|
const runtimeImpact = usageResult.runtimeImpact.get(node.name);
|
|
347
350
|
const introduction = determineIntroduction(direct, scope, rootCauses, runtimeImpact);
|
|
348
351
|
const parentIds = Array.from(node.parents).sort();
|
|
349
|
-
const origins = buildOrigins(rootCauses, parentIds, (
|
|
352
|
+
const origins = buildOrigins(rootCauses, parentIds, (_f = input.workspaceUsage) === null || _f === void 0 ? void 0 : _f.get(node.name), input.workspaceEnabled, MAX_TOP_ROOT_PACKAGES, MAX_TOP_PARENT_PACKAGES);
|
|
350
353
|
const execution = packageInsights.execution;
|
|
351
354
|
const id = node.key;
|
|
352
355
|
const upgrade = buildUpgradeBlock(packageInsights);
|
|
@@ -359,7 +362,10 @@ async function aggregateData(input) {
|
|
|
359
362
|
...(outdated ? { outdatedStatus: outdated.status } : {}),
|
|
360
363
|
...((outdated === null || outdated === void 0 ? void 0 : outdated.latestVersion) ? { latestVersion: outdated.latestVersion } : {}),
|
|
361
364
|
...((upgrade === null || upgrade === void 0 ? void 0 : upgrade.blockers) ? { blockers: upgrade.blockers } : {}),
|
|
362
|
-
...((upgrade === null || upgrade === void 0 ? void 0 : upgrade.blocksNodeMajor) ? { blocksNodeMajor: upgrade.blocksNodeMajor } : {})
|
|
365
|
+
...((upgrade === null || upgrade === void 0 ? void 0 : upgrade.blocksNodeMajor) ? { blocksNodeMajor: upgrade.blocksNodeMajor } : {}),
|
|
366
|
+
...(typeof input.targetNodeMajor === 'number' && packageInsights.nodeEngine
|
|
367
|
+
? { targetNodeCompatible: (0, nodeEngine_1.isNodeEngineTargetCompatible)(packageInsights.nodeEngine, input.targetNodeMajor) }
|
|
368
|
+
: {})
|
|
363
369
|
};
|
|
364
370
|
dependencies[id] = {
|
|
365
371
|
package: {
|
|
@@ -372,9 +378,9 @@ async function aggregateData(input) {
|
|
|
372
378
|
deprecated: packageInsights.deprecated,
|
|
373
379
|
links: {
|
|
374
380
|
npm: `https://www.npmjs.com/package/${node.name}`,
|
|
375
|
-
...(((
|
|
376
|
-
...(((
|
|
377
|
-
...(((
|
|
381
|
+
...(((_g = packageInsights.links) === null || _g === void 0 ? void 0 : _g.repository) ? { repository: packageInsights.links.repository } : {}),
|
|
382
|
+
...(((_h = packageInsights.links) === null || _h === void 0 ? void 0 : _h.homepage) ? { homepage: packageInsights.links.homepage } : {}),
|
|
383
|
+
...(((_j = packageInsights.links) === null || _j === void 0 ? void 0 : _j.bugs) ? { bugs: packageInsights.links.bugs } : {})
|
|
378
384
|
}
|
|
379
385
|
},
|
|
380
386
|
compliance: {
|
|
@@ -416,8 +422,8 @@ async function aggregateData(input) {
|
|
|
416
422
|
const nodeVersion = process.versions.node;
|
|
417
423
|
const dependencyCount = nodes.length;
|
|
418
424
|
const transitiveCount = dependencyCount - directCount;
|
|
419
|
-
|
|
420
|
-
schemaVersion: '1.
|
|
425
|
+
const aggregated = {
|
|
426
|
+
schemaVersion: '1.4',
|
|
421
427
|
generatedAt: new Date().toISOString(),
|
|
422
428
|
dependencyRadarVersion,
|
|
423
429
|
git: {
|
|
@@ -428,6 +434,7 @@ async function aggregateData(input) {
|
|
|
428
434
|
nodeVersion,
|
|
429
435
|
runtimeVersion,
|
|
430
436
|
minRequiredMajor: minRequiredMajor !== null && minRequiredMajor !== void 0 ? minRequiredMajor : 0,
|
|
437
|
+
...(typeof input.targetNodeMajor === 'number' ? { targetNodeMajor: input.targetNodeMajor } : {}),
|
|
431
438
|
...(input.platform ? { platform: input.platform } : {}),
|
|
432
439
|
...(input.arch ? { arch: input.arch } : {}),
|
|
433
440
|
...(typeof input.ci === 'boolean' ? { ci: input.ci } : {}),
|
|
@@ -449,8 +456,27 @@ async function aggregateData(input) {
|
|
|
449
456
|
directCount,
|
|
450
457
|
transitiveCount
|
|
451
458
|
},
|
|
459
|
+
...(supplyChain ? { supplyChain } : {}),
|
|
452
460
|
dependencies
|
|
453
461
|
};
|
|
462
|
+
const findings = (0, findings_1.buildDependencyFindings)(aggregated, { targetNodeMajor: input.targetNodeMajor });
|
|
463
|
+
aggregated.findings = findings;
|
|
464
|
+
aggregated.summary.findingCount = findings.length;
|
|
465
|
+
return aggregated;
|
|
466
|
+
}
|
|
467
|
+
function normalizeSupplyChain(data) {
|
|
468
|
+
if (!data || typeof data !== 'object')
|
|
469
|
+
return undefined;
|
|
470
|
+
const signals = Array.isArray(data.signals) ? data.signals : [];
|
|
471
|
+
const signatureAudit = data.signatureAudit && typeof data.signatureAudit === 'object'
|
|
472
|
+
? data.signatureAudit
|
|
473
|
+
: undefined;
|
|
474
|
+
if (signals.length === 0 && !signatureAudit)
|
|
475
|
+
return undefined;
|
|
476
|
+
return {
|
|
477
|
+
signals,
|
|
478
|
+
...(signatureAudit ? { signatureAudit } : {})
|
|
479
|
+
};
|
|
454
480
|
}
|
|
455
481
|
function deriveMinRequiredMajor(engineRanges) {
|
|
456
482
|
let strictest;
|