@openrewrite/recipes-nodejs 0.37.0-20260106-083133 → 0.37.0-20260106-170728
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/dist/security/dependency-vulnerability-check.d.ts +8 -54
- package/dist/security/dependency-vulnerability-check.d.ts.map +1 -1
- package/dist/security/dependency-vulnerability-check.js +176 -287
- package/dist/security/dependency-vulnerability-check.js.map +1 -1
- package/dist/security/index.d.ts +3 -0
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +3 -0
- package/dist/security/index.js.map +1 -1
- package/dist/security/npm-utils.d.ts +8 -2
- package/dist/security/npm-utils.d.ts.map +1 -1
- package/dist/security/npm-utils.js +114 -14
- package/dist/security/npm-utils.js.map +1 -1
- package/dist/security/override-utils.d.ts +23 -0
- package/dist/security/override-utils.d.ts.map +1 -0
- package/dist/security/override-utils.js +169 -0
- package/dist/security/override-utils.js.map +1 -0
- package/dist/security/remove-redundant-overrides.d.ts +1 -10
- package/dist/security/remove-redundant-overrides.d.ts.map +1 -1
- package/dist/security/remove-redundant-overrides.js +4 -152
- package/dist/security/remove-redundant-overrides.js.map +1 -1
- package/dist/security/types.d.ts +42 -0
- package/dist/security/types.d.ts.map +1 -0
- package/dist/security/types.js +7 -0
- package/dist/security/types.js.map +1 -0
- package/dist/security/version-utils.d.ts +13 -0
- package/dist/security/version-utils.d.ts.map +1 -0
- package/dist/security/version-utils.js +173 -0
- package/dist/security/version-utils.js.map +1 -0
- package/package.json +1 -1
- package/src/security/dependency-vulnerability-check.ts +300 -525
- package/src/security/index.ts +3 -0
- package/src/security/npm-utils.ts +172 -37
- package/src/security/override-utils.ts +253 -0
- package/src/security/remove-redundant-overrides.ts +9 -211
- package/src/security/types.ts +115 -0
- package/src/security/version-utils.ts +198 -0
|
@@ -49,8 +49,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
49
49
|
};
|
|
50
50
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
51
51
|
exports.DependencyVulnerabilityCheck = void 0;
|
|
52
|
-
exports.extractVersionPrefix = extractVersionPrefix;
|
|
53
|
-
exports.applyVersionPrefix = applyVersionPrefix;
|
|
54
52
|
const rewrite_1 = require("@openrewrite/rewrite");
|
|
55
53
|
const json_1 = require("@openrewrite/rewrite/json");
|
|
56
54
|
const text_1 = require("@openrewrite/rewrite/text");
|
|
@@ -60,9 +58,9 @@ const semver = __importStar(require("semver"));
|
|
|
60
58
|
const path = __importStar(require("path"));
|
|
61
59
|
const vulnerability_1 = require("./vulnerability");
|
|
62
60
|
const npm_utils_1 = require("./npm-utils");
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
const version_utils_1 = require("./version-utils");
|
|
62
|
+
const types_1 = require("./types");
|
|
63
|
+
const override_utils_1 = require("./override-utils");
|
|
66
64
|
class VulnerabilityReportRow {
|
|
67
65
|
constructor(sourcePath, cve, packageName, version, fixedVersion, lastAffectedVersion, upgradeable, summary, severity, depth, cwes, isDirect, dependencyPath) {
|
|
68
66
|
this.sourcePath = sourcePath;
|
|
@@ -160,7 +158,7 @@ __decorate([
|
|
|
160
158
|
], VulnerabilityReportRow.prototype, "dependencyPath", void 0);
|
|
161
159
|
class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
162
160
|
constructor(options) {
|
|
163
|
-
var _a, _b, _c, _d, _e;
|
|
161
|
+
var _a, _b, _c, _d, _e, _f;
|
|
164
162
|
super(options);
|
|
165
163
|
this.name = "org.openrewrite.node.dependency-vulnerability-check";
|
|
166
164
|
this.displayName = "Find and fix vulnerable npm dependencies";
|
|
@@ -171,10 +169,11 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
171
169
|
"Vulnerability information comes from the GitHub Security Advisory Database.";
|
|
172
170
|
this.vulnerabilityReport = new rewrite_1.DataTable("org.openrewrite.nodejs.table.VulnerabilityReport", "Vulnerability Report", "Lists all vulnerabilities found in project dependencies.", VulnerabilityReportRow);
|
|
173
171
|
(_a = this.transitiveFixStrategy) !== null && _a !== void 0 ? _a : (this.transitiveFixStrategy = 'report');
|
|
174
|
-
(_b = this.
|
|
175
|
-
(_c = this.
|
|
176
|
-
(_d = this.
|
|
177
|
-
(_e = this.
|
|
172
|
+
(_b = this.preferDirectUpgrade) !== null && _b !== void 0 ? _b : (this.preferDirectUpgrade = true);
|
|
173
|
+
(_c = this.maximumUpgradeDelta) !== null && _c !== void 0 ? _c : (this.maximumUpgradeDelta = 'patch');
|
|
174
|
+
(_d = this.minimumSeverity) !== null && _d !== void 0 ? _d : (this.minimumSeverity = vulnerability_1.Severity.LOW);
|
|
175
|
+
(_e = this.fixDeclaredVersions) !== null && _e !== void 0 ? _e : (this.fixDeclaredVersions = false);
|
|
176
|
+
(_f = this.addOverrideComments) !== null && _f !== void 0 ? _f : (this.addOverrideComments = true);
|
|
178
177
|
if (options === null || options === void 0 ? void 0 : options.minimumSeverity) {
|
|
179
178
|
this.minimumSeverity = (0, vulnerability_1.parseSeverity)(options.minimumSeverity);
|
|
180
179
|
}
|
|
@@ -182,33 +181,29 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
182
181
|
try {
|
|
183
182
|
this.cvePatternRegex = new RegExp(this.cvePattern);
|
|
184
183
|
}
|
|
185
|
-
catch (
|
|
184
|
+
catch (_g) {
|
|
186
185
|
}
|
|
187
186
|
}
|
|
188
187
|
}
|
|
189
188
|
shouldScanTransitives() {
|
|
190
|
-
return
|
|
191
|
-
}
|
|
192
|
-
shouldFixTransitives() {
|
|
193
|
-
return this.transitiveFixStrategy !== 'report';
|
|
189
|
+
return true;
|
|
194
190
|
}
|
|
195
191
|
shouldVerifyTransitiveFixes() {
|
|
196
|
-
return this.
|
|
197
|
-
this.transitiveFixStrategy === 'prefer-direct-upgrade';
|
|
192
|
+
return this.preferDirectUpgrade === true;
|
|
198
193
|
}
|
|
199
194
|
filterRemainingTransitiveFixes(fixes, lockFileContent, packageManager, db) {
|
|
200
195
|
const result = [];
|
|
201
196
|
for (const fix of fixes) {
|
|
202
|
-
if (!fix.isTransitive || fix.
|
|
197
|
+
if (!fix.isTransitive || (fix.fixViaDirectUpgrades && fix.fixViaDirectUpgrades.length > 0)) {
|
|
203
198
|
result.push(fix);
|
|
204
199
|
continue;
|
|
205
200
|
}
|
|
206
|
-
const
|
|
207
|
-
if (
|
|
201
|
+
const resolvedVersions = (0, npm_utils_1.extractAllVersionsFromLockFile)(lockFileContent, fix.packageName, packageManager);
|
|
202
|
+
if (resolvedVersions.length === 0) {
|
|
208
203
|
continue;
|
|
209
204
|
}
|
|
210
|
-
const
|
|
211
|
-
if (
|
|
205
|
+
const anyVersionVulnerable = resolvedVersions.some(version => this.isVersionStillVulnerable(fix.packageName, version, fix.cves, db));
|
|
206
|
+
if (anyVersionVulnerable) {
|
|
212
207
|
result.push(fix);
|
|
213
208
|
}
|
|
214
209
|
}
|
|
@@ -217,7 +212,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
217
212
|
isVersionStillVulnerable(packageName, version, cves, db) {
|
|
218
213
|
const vulns = db.getVulnerabilities(packageName);
|
|
219
214
|
for (const vuln of vulns) {
|
|
220
|
-
if (cves.includes(vuln.cve) &&
|
|
215
|
+
if (cves.includes(vuln.cve) && (0, version_utils_1.isVersionAffected)(version, vuln)) {
|
|
221
216
|
return true;
|
|
222
217
|
}
|
|
223
218
|
}
|
|
@@ -235,100 +230,6 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
235
230
|
}
|
|
236
231
|
return this.cvePatternRegex.test(vulnerability.cve);
|
|
237
232
|
}
|
|
238
|
-
isVersionAffected(version, vulnerability) {
|
|
239
|
-
try {
|
|
240
|
-
const v = semver.parse(version);
|
|
241
|
-
if (!v)
|
|
242
|
-
return false;
|
|
243
|
-
if (vulnerability.introducedVersion && vulnerability.introducedVersion !== '0') {
|
|
244
|
-
const introduced = semver.parse(vulnerability.introducedVersion);
|
|
245
|
-
if (introduced && semver.lt(v, introduced)) {
|
|
246
|
-
return false;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
if (vulnerability.fixedVersion) {
|
|
250
|
-
const fixed = semver.parse(vulnerability.fixedVersion);
|
|
251
|
-
if (fixed && semver.gte(v, fixed)) {
|
|
252
|
-
return false;
|
|
253
|
-
}
|
|
254
|
-
return true;
|
|
255
|
-
}
|
|
256
|
-
if (vulnerability.lastAffectedVersion) {
|
|
257
|
-
const lastAffected = semver.parse(vulnerability.lastAffectedVersion);
|
|
258
|
-
if (lastAffected && semver.gt(v, lastAffected)) {
|
|
259
|
-
return false;
|
|
260
|
-
}
|
|
261
|
-
return true;
|
|
262
|
-
}
|
|
263
|
-
return true;
|
|
264
|
-
}
|
|
265
|
-
catch (_a) {
|
|
266
|
-
return false;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
isUpgradeableWithinDelta(currentVersion, vulnerability) {
|
|
270
|
-
if (this.isReportOnly()) {
|
|
271
|
-
return false;
|
|
272
|
-
}
|
|
273
|
-
try {
|
|
274
|
-
const current = semver.parse(currentVersion);
|
|
275
|
-
if (!current)
|
|
276
|
-
return false;
|
|
277
|
-
const delta = this.maximumUpgradeDelta;
|
|
278
|
-
if (vulnerability.fixedVersion) {
|
|
279
|
-
const fixed = semver.parse(vulnerability.fixedVersion);
|
|
280
|
-
if (!fixed)
|
|
281
|
-
return false;
|
|
282
|
-
switch (delta) {
|
|
283
|
-
case 'patch':
|
|
284
|
-
return current.major === fixed.major && current.minor === fixed.minor;
|
|
285
|
-
case 'minor':
|
|
286
|
-
return current.major === fixed.major;
|
|
287
|
-
case 'major':
|
|
288
|
-
return true;
|
|
289
|
-
case 'none':
|
|
290
|
-
return false;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
if (vulnerability.lastAffectedVersion) {
|
|
294
|
-
const lastAffected = semver.parse(vulnerability.lastAffectedVersion);
|
|
295
|
-
if (!lastAffected)
|
|
296
|
-
return false;
|
|
297
|
-
switch (delta) {
|
|
298
|
-
case 'patch':
|
|
299
|
-
return current.major === lastAffected.major &&
|
|
300
|
-
current.minor === lastAffected.minor;
|
|
301
|
-
case 'minor':
|
|
302
|
-
return current.major === lastAffected.major;
|
|
303
|
-
case 'major':
|
|
304
|
-
return true;
|
|
305
|
-
case 'none':
|
|
306
|
-
return false;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
return false;
|
|
310
|
-
}
|
|
311
|
-
catch (_a) {
|
|
312
|
-
return false;
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
getUpgradeVersion(vulnerability) {
|
|
316
|
-
if (vulnerability.fixedVersion) {
|
|
317
|
-
return vulnerability.fixedVersion;
|
|
318
|
-
}
|
|
319
|
-
return undefined;
|
|
320
|
-
}
|
|
321
|
-
getVersionPrefixForDelta() {
|
|
322
|
-
switch (this.maximumUpgradeDelta) {
|
|
323
|
-
case 'patch':
|
|
324
|
-
return '~';
|
|
325
|
-
case 'minor':
|
|
326
|
-
case 'major':
|
|
327
|
-
return '^';
|
|
328
|
-
default:
|
|
329
|
-
return '';
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
233
|
renderPath(scope, path) {
|
|
333
234
|
const parts = [];
|
|
334
235
|
if (scope) {
|
|
@@ -339,6 +240,39 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
339
240
|
}
|
|
340
241
|
return parts.join(' > ');
|
|
341
242
|
}
|
|
243
|
+
findAllDirectDepsForTransitive(marker, transitivePackageName, scopesToCheck) {
|
|
244
|
+
const results = [];
|
|
245
|
+
for (const scope of scopesToCheck) {
|
|
246
|
+
const deps = marker[scope] || [];
|
|
247
|
+
for (const dep of deps) {
|
|
248
|
+
if (dep.resolved && this.hasTransitiveInTree(dep.resolved, transitivePackageName, new Set())) {
|
|
249
|
+
results.push({
|
|
250
|
+
name: dep.resolved.name,
|
|
251
|
+
version: dep.resolved.version,
|
|
252
|
+
scope
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return results;
|
|
258
|
+
}
|
|
259
|
+
hasTransitiveInTree(resolved, targetPackageName, visited) {
|
|
260
|
+
const key = `${resolved.name}@${resolved.version}`;
|
|
261
|
+
if (visited.has(key))
|
|
262
|
+
return false;
|
|
263
|
+
visited.add(key);
|
|
264
|
+
if (resolved.dependencies) {
|
|
265
|
+
for (const child of resolved.dependencies) {
|
|
266
|
+
if (child.name === targetPackageName) {
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
if (child.resolved && this.hasTransitiveInTree(child.resolved, targetPackageName, visited)) {
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
342
276
|
findVulnerabilities(resolved, db, depth, isDirect, scope, path, visited, results) {
|
|
343
277
|
const key = `${resolved.name}@${resolved.version}`;
|
|
344
278
|
if (visited.has(key))
|
|
@@ -353,7 +287,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
353
287
|
if (!this.matchesCvePattern(vuln)) {
|
|
354
288
|
continue;
|
|
355
289
|
}
|
|
356
|
-
if (
|
|
290
|
+
if ((0, version_utils_1.isVersionAffected)(resolved.version, vuln)) {
|
|
357
291
|
results.push({
|
|
358
292
|
resolved,
|
|
359
293
|
vulnerability: vuln,
|
|
@@ -385,7 +319,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
385
319
|
for (const dep of deps) {
|
|
386
320
|
if (!dep.resolved)
|
|
387
321
|
continue;
|
|
388
|
-
const declaredMinVersion =
|
|
322
|
+
const declaredMinVersion = (0, version_utils_1.extractMinimumVersion)(dep.versionConstraint);
|
|
389
323
|
if (!declaredMinVersion)
|
|
390
324
|
continue;
|
|
391
325
|
if (declaredMinVersion === dep.resolved.version)
|
|
@@ -401,8 +335,8 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
401
335
|
if (!this.matchesCvePattern(vuln)) {
|
|
402
336
|
continue;
|
|
403
337
|
}
|
|
404
|
-
if (
|
|
405
|
-
!
|
|
338
|
+
if ((0, version_utils_1.isVersionAffected)(declaredMinVersion, vuln) &&
|
|
339
|
+
!(0, version_utils_1.isVersionAffected)(dep.resolved.version, vuln)) {
|
|
406
340
|
affectedCves.push(vuln.cve);
|
|
407
341
|
affectedCveSummaries.set(vuln.cve, vuln.summary);
|
|
408
342
|
const fixVersion = vuln.fixedVersion;
|
|
@@ -433,20 +367,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
433
367
|
if (this.isReportOnly()) {
|
|
434
368
|
return false;
|
|
435
369
|
}
|
|
436
|
-
return
|
|
437
|
-
}
|
|
438
|
-
extractMinimumVersion(constraint) {
|
|
439
|
-
if (!constraint)
|
|
440
|
-
return undefined;
|
|
441
|
-
if (semver.valid(constraint)) {
|
|
442
|
-
return constraint;
|
|
443
|
-
}
|
|
444
|
-
const match = constraint.match(/^[~^>=<]*\s*(\d+\.\d+\.\d+(?:-[a-zA-Z0-9.]+)?)/);
|
|
445
|
-
if (match && semver.valid(match[1])) {
|
|
446
|
-
return match[1];
|
|
447
|
-
}
|
|
448
|
-
const coerced = semver.coerce(constraint);
|
|
449
|
-
return coerced === null || coerced === void 0 ? void 0 : coerced.version;
|
|
370
|
+
return (0, version_utils_1.isVersionWithinDelta)(fromVersion, toVersion, this.maximumUpgradeDelta);
|
|
450
371
|
}
|
|
451
372
|
findHighestSafeVersion(packageName, originalVersion, initialFixVersion, db, visited = new Set()) {
|
|
452
373
|
if (visited.has(initialFixVersion)) {
|
|
@@ -454,15 +375,15 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
454
375
|
}
|
|
455
376
|
visited.add(initialFixVersion);
|
|
456
377
|
const vulnsInFixVersion = db.getVulnerabilities(packageName)
|
|
457
|
-
.filter(v =>
|
|
378
|
+
.filter(v => (0, version_utils_1.isVersionAffected)(initialFixVersion, v));
|
|
458
379
|
if (vulnsInFixVersion.length === 0) {
|
|
459
380
|
return initialFixVersion;
|
|
460
381
|
}
|
|
461
382
|
let highestFixVersion = initialFixVersion;
|
|
462
383
|
for (const vuln of vulnsInFixVersion) {
|
|
463
|
-
const fixVersion =
|
|
384
|
+
const fixVersion = (0, version_utils_1.getUpgradeVersion)(vuln);
|
|
464
385
|
if (fixVersion && semver.valid(fixVersion)) {
|
|
465
|
-
if (
|
|
386
|
+
if ((0, version_utils_1.isVersionWithinDelta)(originalVersion, fixVersion, this.maximumUpgradeDelta)) {
|
|
466
387
|
if (semver.gt(fixVersion, highestFixVersion)) {
|
|
467
388
|
highestFixVersion = fixVersion;
|
|
468
389
|
}
|
|
@@ -474,29 +395,6 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
474
395
|
}
|
|
475
396
|
return initialFixVersion;
|
|
476
397
|
}
|
|
477
|
-
isVersionWithinDelta(originalVersion, targetVersion) {
|
|
478
|
-
try {
|
|
479
|
-
const original = semver.parse(originalVersion);
|
|
480
|
-
const target = semver.parse(targetVersion);
|
|
481
|
-
if (!original || !target)
|
|
482
|
-
return false;
|
|
483
|
-
switch (this.maximumUpgradeDelta) {
|
|
484
|
-
case 'patch':
|
|
485
|
-
return original.major === target.major && original.minor === target.minor;
|
|
486
|
-
case 'minor':
|
|
487
|
-
return original.major === target.major;
|
|
488
|
-
case 'major':
|
|
489
|
-
return true;
|
|
490
|
-
case 'none':
|
|
491
|
-
return false;
|
|
492
|
-
default:
|
|
493
|
-
return false;
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
catch (_a) {
|
|
497
|
-
return false;
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
398
|
computeFixes(vulnerabilities, db, projectContext) {
|
|
501
399
|
return __awaiter(this, void 0, void 0, function* () {
|
|
502
400
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
@@ -531,23 +429,28 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
531
429
|
let isTransitive = true;
|
|
532
430
|
let scope;
|
|
533
431
|
let originalVersion;
|
|
534
|
-
|
|
432
|
+
const directDepInfosMap = new Map();
|
|
535
433
|
for (const vuln of vulns) {
|
|
536
434
|
if (!originalVersion) {
|
|
537
435
|
originalVersion = vuln.resolved.version;
|
|
538
436
|
}
|
|
539
|
-
if (!vuln.isDirect && vuln.path.length > 0
|
|
437
|
+
if (!vuln.isDirect && vuln.path.length > 0) {
|
|
540
438
|
const directDep = vuln.path[0];
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
439
|
+
const depScope = vuln.scope || 'dependencies';
|
|
440
|
+
const key = `${directDep.name}@${depScope}`;
|
|
441
|
+
if (!directDepInfosMap.has(key)) {
|
|
442
|
+
directDepInfosMap.set(key, {
|
|
443
|
+
name: directDep.name,
|
|
444
|
+
version: directDep.version,
|
|
445
|
+
scope: depScope
|
|
446
|
+
});
|
|
447
|
+
}
|
|
546
448
|
}
|
|
547
|
-
|
|
449
|
+
const upgradeCheck = (0, version_utils_1.isUpgradeableWithinDelta)(vuln.resolved.version, vuln.vulnerability, this.maximumUpgradeDelta);
|
|
450
|
+
if (this.isReportOnly() || !upgradeCheck) {
|
|
548
451
|
continue;
|
|
549
452
|
}
|
|
550
|
-
const fixVersion =
|
|
453
|
+
const fixVersion = (0, version_utils_1.getUpgradeVersion)(vuln.vulnerability);
|
|
551
454
|
if (fixVersion) {
|
|
552
455
|
const fixMajor = (_g = semver.parse(fixVersion)) === null || _g === void 0 ? void 0 : _g.major;
|
|
553
456
|
const shouldConsiderFix = hasMultipleMajorVersions
|
|
@@ -566,8 +469,18 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
566
469
|
scope = vuln.scope;
|
|
567
470
|
}
|
|
568
471
|
}
|
|
472
|
+
if (isTransitive && (projectContext === null || projectContext === void 0 ? void 0 : projectContext.marker) && (projectContext === null || projectContext === void 0 ? void 0 : projectContext.scopesToCheck)) {
|
|
473
|
+
const allDirectDeps = this.findAllDirectDepsForTransitive(projectContext.marker, packageName, projectContext.scopesToCheck);
|
|
474
|
+
for (const dep of allDirectDeps) {
|
|
475
|
+
const key = `${dep.name}@${dep.scope}`;
|
|
476
|
+
if (!directDepInfosMap.has(key)) {
|
|
477
|
+
directDepInfosMap.set(key, dep);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
569
481
|
if (highestFixVersion && cves.length > 0 && originalVersion) {
|
|
570
482
|
const safeVersion = this.findHighestSafeVersion(packageName, originalVersion, highestFixVersion, db);
|
|
483
|
+
const directDepInfosArray = Array.from(directDepInfosMap.values());
|
|
571
484
|
const fix = {
|
|
572
485
|
packageName,
|
|
573
486
|
newVersion: safeVersion || highestFixVersion,
|
|
@@ -576,11 +489,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
576
489
|
cveSummaries,
|
|
577
490
|
scope,
|
|
578
491
|
originalMajorVersion: originalMajor,
|
|
579
|
-
|
|
580
|
-
name: directDepInfo.name,
|
|
581
|
-
version: directDepInfo.version,
|
|
582
|
-
scope: directDepInfo.scope
|
|
583
|
-
} : undefined
|
|
492
|
+
directDepInfos: isTransitive && directDepInfosArray.length > 0 ? directDepInfosArray : undefined
|
|
584
493
|
};
|
|
585
494
|
fixes.push(fix);
|
|
586
495
|
}
|
|
@@ -588,47 +497,50 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
588
497
|
return fixes;
|
|
589
498
|
});
|
|
590
499
|
}
|
|
591
|
-
|
|
592
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
593
|
-
const isVulnerable = (version) => {
|
|
594
|
-
try {
|
|
595
|
-
return semver.lt(version, requiredFixVersion);
|
|
596
|
-
}
|
|
597
|
-
catch (_a) {
|
|
598
|
-
return true;
|
|
599
|
-
}
|
|
600
|
-
};
|
|
601
|
-
const isWithinDelta = (from, to) => {
|
|
602
|
-
return this.isVersionWithinDelta(from, to);
|
|
603
|
-
};
|
|
604
|
-
try {
|
|
605
|
-
const upgradeVersion = yield (0, npm_utils_1.findDirectUpgradeThatFixesTransitive)(projectContext.packageManager, directDepInfo.name, directDepInfo.version, transitivePackageName, isVulnerable, isWithinDelta, projectContext.originalPackageJson, directDepInfo.scope, projectContext.configFiles);
|
|
606
|
-
return upgradeVersion;
|
|
607
|
-
}
|
|
608
|
-
catch (_a) {
|
|
609
|
-
return undefined;
|
|
610
|
-
}
|
|
611
|
-
});
|
|
612
|
-
}
|
|
613
|
-
tryDirectUpgradesForTransitives(fixes, updateInfo, db) {
|
|
500
|
+
tryDirectUpgradesForTransitives(fixes, updateInfo) {
|
|
614
501
|
return __awaiter(this, void 0, void 0, function* () {
|
|
615
502
|
const result = [];
|
|
616
503
|
for (const fix of fixes) {
|
|
617
|
-
if (!fix.
|
|
504
|
+
if (!fix.directDepInfos || fix.directDepInfos.length === 0) {
|
|
618
505
|
result.push(fix);
|
|
619
506
|
continue;
|
|
620
507
|
}
|
|
621
|
-
const
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
508
|
+
const candidateUpgrades = [];
|
|
509
|
+
const isVulnerable = (version) => {
|
|
510
|
+
try {
|
|
511
|
+
return semver.lt(version, fix.newVersion);
|
|
512
|
+
}
|
|
513
|
+
catch (_a) {
|
|
514
|
+
return true;
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
const isWithinDelta = (from, to) => {
|
|
518
|
+
return (0, version_utils_1.isVersionWithinDelta)(from, to, this.maximumUpgradeDelta);
|
|
519
|
+
};
|
|
520
|
+
for (const directDepInfo of fix.directDepInfos) {
|
|
521
|
+
const directUpgradeVersion = yield (0, npm_utils_1.findDirectUpgradeWithSafeTransitiveInIsolation)(updateInfo.packageManager, directDepInfo.name, directDepInfo.version, fix.packageName, isVulnerable, isWithinDelta, directDepInfo.scope, updateInfo.configFiles);
|
|
522
|
+
if (directUpgradeVersion) {
|
|
523
|
+
candidateUpgrades.push({
|
|
524
|
+
directDepName: directDepInfo.name,
|
|
629
525
|
directDepVersion: directUpgradeVersion,
|
|
630
|
-
directDepScope:
|
|
631
|
-
}
|
|
526
|
+
directDepScope: directDepInfo.scope
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
if (candidateUpgrades.length > 0) {
|
|
531
|
+
const foundAllUpgrades = candidateUpgrades.length === fix.directDepInfos.length;
|
|
532
|
+
if (foundAllUpgrades) {
|
|
533
|
+
const allFixed = yield (0, npm_utils_1.verifyAllUpgradesFixTransitive)(updateInfo.packageManager, candidateUpgrades.map(u => ({
|
|
534
|
+
name: u.directDepName,
|
|
535
|
+
version: u.directDepVersion,
|
|
536
|
+
scope: u.directDepScope
|
|
537
|
+
})), fix.packageName, isVulnerable, updateInfo.originalPackageJson, updateInfo.configFiles);
|
|
538
|
+
if (allFixed) {
|
|
539
|
+
result.push(Object.assign(Object.assign({}, fix), { fixViaDirectUpgrades: candidateUpgrades }));
|
|
540
|
+
continue;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
result.push(Object.assign(Object.assign({}, fix), { fixViaDirectUpgrades: candidateUpgrades }));
|
|
632
544
|
}
|
|
633
545
|
else {
|
|
634
546
|
result.push(fix);
|
|
@@ -680,7 +592,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
680
592
|
const visited = new Set();
|
|
681
593
|
const scopesToCheck = recipe.scope
|
|
682
594
|
? [recipe.scope]
|
|
683
|
-
: ALL_DEPENDENCY_SCOPES;
|
|
595
|
+
: types_1.ALL_DEPENDENCY_SCOPES;
|
|
684
596
|
for (const scope of scopesToCheck) {
|
|
685
597
|
const deps = marker[scope] || [];
|
|
686
598
|
for (const dep of deps) {
|
|
@@ -713,7 +625,9 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
713
625
|
fixes = yield recipe.computeFixes(vulnerabilities, acc.db, {
|
|
714
626
|
packageManager: pm,
|
|
715
627
|
originalPackageJson,
|
|
716
|
-
configFiles: Object.keys(configFiles).length > 0 ? configFiles : undefined
|
|
628
|
+
configFiles: Object.keys(configFiles).length > 0 ? configFiles : undefined,
|
|
629
|
+
marker,
|
|
630
|
+
scopesToCheck
|
|
717
631
|
});
|
|
718
632
|
}
|
|
719
633
|
if (recipe.fixDeclaredVersions) {
|
|
@@ -844,7 +758,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
844
758
|
const vulnerabilities = acc.vulnerableByProject.get(doc.sourcePath);
|
|
845
759
|
if (vulnerabilities && vulnerabilities.length > 0) {
|
|
846
760
|
for (const vuln of vulnerabilities) {
|
|
847
|
-
const upgradeable = recipe.isUpgradeableWithinDelta(vuln.resolved.version, vuln.vulnerability);
|
|
761
|
+
const upgradeable = !recipe.isReportOnly() && (0, version_utils_1.isUpgradeableWithinDelta)(vuln.resolved.version, vuln.vulnerability, recipe.maximumUpgradeDelta);
|
|
848
762
|
recipe.vulnerabilityReport.insertRow(ctx, new VulnerabilityReportRow(doc.sourcePath, vuln.vulnerability.cve, vuln.resolved.name, vuln.resolved.version, vuln.vulnerability.fixedVersion || '', vuln.vulnerability.lastAffectedVersion || '', upgradeable, vuln.vulnerability.summary, vuln.vulnerability.severity, vuln.depth, vuln.vulnerability.cwes, vuln.isDirect, recipe.renderPath(vuln.scope, vuln.path)));
|
|
849
763
|
}
|
|
850
764
|
}
|
|
@@ -1011,8 +925,8 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
1011
925
|
}
|
|
1012
926
|
runPackageManagerInstall(acc, updateInfo, fixes) {
|
|
1013
927
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1014
|
-
const directFixes = fixes.filter(f => !f.isTransitive || f.
|
|
1015
|
-
const transitiveFixes = fixes.filter(f => f.isTransitive && !f.
|
|
928
|
+
const directFixes = fixes.filter(f => !f.isTransitive || (f.fixViaDirectUpgrades && f.fixViaDirectUpgrades.length > 0));
|
|
929
|
+
const transitiveFixes = fixes.filter(f => f.isTransitive && (!f.fixViaDirectUpgrades || f.fixViaDirectUpgrades.length === 0));
|
|
1016
930
|
if (this.shouldVerifyTransitiveFixes() && transitiveFixes.length > 0) {
|
|
1017
931
|
const phase1PackageJson = this.createModifiedPackageJson(updateInfo.originalPackageJson, directFixes, updateInfo.packageManager);
|
|
1018
932
|
const phase1Result = yield (0, javascript_1.runInstallInTempDir)(updateInfo.packageManager, phase1PackageJson, {
|
|
@@ -1031,8 +945,8 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
1031
945
|
(0, javascript_1.storeInstallResult)(phase1Result, acc, updateInfo, phase1PackageJson);
|
|
1032
946
|
return;
|
|
1033
947
|
}
|
|
1034
|
-
if (this.
|
|
1035
|
-
remainingTransitiveFixes = yield this.tryDirectUpgradesForTransitives(remainingTransitiveFixes, updateInfo
|
|
948
|
+
if (this.preferDirectUpgrade) {
|
|
949
|
+
remainingTransitiveFixes = yield this.tryDirectUpgradesForTransitives(remainingTransitiveFixes, updateInfo);
|
|
1036
950
|
}
|
|
1037
951
|
const finalFixes = [...directFixes, ...remainingTransitiveFixes];
|
|
1038
952
|
const finalPackageJson = this.createModifiedPackageJson(updateInfo.originalPackageJson, finalFixes, updateInfo.packageManager);
|
|
@@ -1053,21 +967,18 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
1053
967
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1054
968
|
const memberPaths = acc.workspaceRoots.get(rootPath) || [];
|
|
1055
969
|
const pm = rootUpdateInfo.packageManager;
|
|
1056
|
-
const allDirectFixes = [];
|
|
1057
970
|
const allTransitiveFixes = [];
|
|
1058
971
|
const rootFixes = acc.fixesByProject.get(rootPath) || [];
|
|
1059
|
-
const rootDirectFixes = rootFixes.filter(f => !f.isTransitive || f.
|
|
1060
|
-
const rootTransitiveFixes = rootFixes.filter(f => f.isTransitive && !f.
|
|
1061
|
-
allDirectFixes.push(...rootDirectFixes);
|
|
972
|
+
const rootDirectFixes = rootFixes.filter(f => !f.isTransitive || (f.fixViaDirectUpgrades && f.fixViaDirectUpgrades.length > 0));
|
|
973
|
+
const rootTransitiveFixes = rootFixes.filter(f => f.isTransitive && (!f.fixViaDirectUpgrades || f.fixViaDirectUpgrades.length === 0));
|
|
1062
974
|
allTransitiveFixes.push(...rootTransitiveFixes);
|
|
1063
975
|
const memberDirectFixes = new Map();
|
|
1064
976
|
for (const memberPath of memberPaths) {
|
|
1065
977
|
const memberFixes = acc.fixesByProject.get(memberPath) || [];
|
|
1066
|
-
const directFixes = memberFixes.filter(f => !f.isTransitive || f.
|
|
1067
|
-
const transitiveFixes = memberFixes.filter(f => f.isTransitive && !f.
|
|
978
|
+
const directFixes = memberFixes.filter(f => !f.isTransitive || (f.fixViaDirectUpgrades && f.fixViaDirectUpgrades.length > 0));
|
|
979
|
+
const transitiveFixes = memberFixes.filter(f => f.isTransitive && (!f.fixViaDirectUpgrades || f.fixViaDirectUpgrades.length === 0));
|
|
1068
980
|
if (directFixes.length > 0) {
|
|
1069
981
|
memberDirectFixes.set(memberPath, directFixes);
|
|
1070
|
-
allDirectFixes.push(...directFixes);
|
|
1071
982
|
}
|
|
1072
983
|
allTransitiveFixes.push(...transitiveFixes);
|
|
1073
984
|
}
|
|
@@ -1109,8 +1020,8 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
1109
1020
|
(0, javascript_1.storeInstallResult)(phase1Result, acc, rootUpdateInfo, phase1RootPackageJson);
|
|
1110
1021
|
return;
|
|
1111
1022
|
}
|
|
1112
|
-
if (this.
|
|
1113
|
-
remainingTransitiveFixes = yield this.tryDirectUpgradesForTransitives(remainingTransitiveFixes, rootUpdateInfo
|
|
1023
|
+
if (this.preferDirectUpgrade) {
|
|
1024
|
+
remainingTransitiveFixes = yield this.tryDirectUpgradesForTransitives(remainingTransitiveFixes, rootUpdateInfo);
|
|
1114
1025
|
}
|
|
1115
1026
|
const finalRootPackageJson = this.createModifiedPackageJson(rootOriginalContent, [...rootDirectFixes, ...remainingTransitiveFixes], pm);
|
|
1116
1027
|
const finalResult = yield (0, javascript_1.runWorkspaceInstallInTempDir)(pm, finalRootPackageJson, {
|
|
@@ -1134,7 +1045,7 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
1134
1045
|
if (!fix.isTransitive && fix.scope) {
|
|
1135
1046
|
if (packageJson[fix.scope] && packageJson[fix.scope][fix.packageName]) {
|
|
1136
1047
|
const originalVersion = packageJson[fix.scope][fix.packageName];
|
|
1137
|
-
packageJson[fix.scope][fix.packageName] = applyVersionPrefix(originalVersion, fix.newVersion);
|
|
1048
|
+
packageJson[fix.scope][fix.packageName] = (0, version_utils_1.applyVersionPrefix)(originalVersion, fix.newVersion);
|
|
1138
1049
|
}
|
|
1139
1050
|
}
|
|
1140
1051
|
}
|
|
@@ -1154,19 +1065,24 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
1154
1065
|
if (!fix.isTransitive && fix.scope) {
|
|
1155
1066
|
if (packageJson[fix.scope] && packageJson[fix.scope][fix.packageName]) {
|
|
1156
1067
|
const originalVersion = packageJson[fix.scope][fix.packageName];
|
|
1157
|
-
packageJson[fix.scope][fix.packageName] = applyVersionPrefix(originalVersion, fix.newVersion);
|
|
1068
|
+
packageJson[fix.scope][fix.packageName] = (0, version_utils_1.applyVersionPrefix)(originalVersion, fix.newVersion);
|
|
1158
1069
|
}
|
|
1159
1070
|
}
|
|
1160
1071
|
else if (fix.isTransitive) {
|
|
1161
|
-
if (
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1072
|
+
if (this.transitiveFixStrategy === 'lock-file') {
|
|
1073
|
+
continue;
|
|
1074
|
+
}
|
|
1075
|
+
if (fix.fixViaDirectUpgrades && fix.fixViaDirectUpgrades.length > 0) {
|
|
1076
|
+
for (const upgrade of fix.fixViaDirectUpgrades) {
|
|
1077
|
+
const { directDepName, directDepVersion, directDepScope } = upgrade;
|
|
1078
|
+
if ((_a = packageJson[directDepScope]) === null || _a === void 0 ? void 0 : _a[directDepName]) {
|
|
1079
|
+
const originalVersion = packageJson[directDepScope][directDepName];
|
|
1080
|
+
packageJson[directDepScope][directDepName] = (0, version_utils_1.applyVersionPrefix)(originalVersion, directDepVersion);
|
|
1081
|
+
}
|
|
1167
1082
|
}
|
|
1083
|
+
continue;
|
|
1168
1084
|
}
|
|
1169
|
-
const directDepScope = findDirectDependencyScope(packageJson, fix.packageName);
|
|
1085
|
+
const directDepScope = (0, override_utils_1.findDirectDependencyScope)(packageJson, fix.packageName);
|
|
1170
1086
|
if (directDepScope) {
|
|
1171
1087
|
const directVersion = packageJson[directDepScope][fix.packageName];
|
|
1172
1088
|
const directMajor = semver.major(semver.coerce(directVersion) || '0.0.0');
|
|
@@ -1182,13 +1098,13 @@ class DependencyVulnerabilityCheck extends rewrite_1.ScanningRecipe {
|
|
|
1182
1098
|
}
|
|
1183
1099
|
continue;
|
|
1184
1100
|
}
|
|
1185
|
-
packageJson[directDepScope][fix.packageName] = applyVersionPrefix(directVersion, fix.newVersion);
|
|
1101
|
+
packageJson[directDepScope][fix.packageName] = (0, version_utils_1.applyVersionPrefix)(directVersion, fix.newVersion);
|
|
1186
1102
|
continue;
|
|
1187
1103
|
}
|
|
1188
1104
|
const packageFixes = fixesByPackage.get(fix.packageName) || [];
|
|
1189
1105
|
const hasMultipleMajorVersions = packageFixes.length > 1 &&
|
|
1190
1106
|
new Set(packageFixes.map(f => f.originalMajorVersion)).size > 1;
|
|
1191
|
-
const existingOverrides = getOverridesFromPackageJson(packageJson, packageManager);
|
|
1107
|
+
const existingOverrides = (0, override_utils_1.getOverridesFromPackageJson)(packageJson, packageManager);
|
|
1192
1108
|
const hasExistingVersionSpecificOverrides = existingOverrides &&
|
|
1193
1109
|
Object.keys(existingOverrides).some(key => key.startsWith(`${fix.packageName}@`));
|
|
1194
1110
|
const isYarn = packageManager === "YarnClassic" ||
|
|
@@ -1262,7 +1178,7 @@ __decorate([
|
|
|
1262
1178
|
(0, rewrite_1.Option)({
|
|
1263
1179
|
displayName: "Scope",
|
|
1264
1180
|
description: "Match dependencies with the specified scope. Default includes all scopes. " +
|
|
1265
|
-
"Use
|
|
1181
|
+
"Use `dependencies` for production dependencies, `devDependencies` for development only, etc.",
|
|
1266
1182
|
required: false,
|
|
1267
1183
|
example: "dependencies",
|
|
1268
1184
|
valid: ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]
|
|
@@ -1272,20 +1188,31 @@ __decorate([
|
|
|
1272
1188
|
(0, rewrite_1.Option)({
|
|
1273
1189
|
displayName: "Transitive fix strategy",
|
|
1274
1190
|
description: "Strategy for handling transitive dependency vulnerabilities. " +
|
|
1275
|
-
"
|
|
1276
|
-
"
|
|
1277
|
-
"
|
|
1278
|
-
"Default is
|
|
1191
|
+
"`report` only reports them without fixing. " +
|
|
1192
|
+
"`override` adds overrides/resolutions for transitive vulnerabilities. " +
|
|
1193
|
+
"`lock-file` updates the lock file to resolve safe versions without modifying `package.json` (similar to Dependabot). " +
|
|
1194
|
+
"Default is `report`.",
|
|
1279
1195
|
required: false,
|
|
1280
1196
|
example: "override",
|
|
1281
|
-
valid: ["report", "override", "
|
|
1197
|
+
valid: ["report", "override", "lock-file"]
|
|
1282
1198
|
})
|
|
1283
1199
|
], DependencyVulnerabilityCheck.prototype, "transitiveFixStrategy", void 0);
|
|
1200
|
+
__decorate([
|
|
1201
|
+
(0, rewrite_1.Option)({
|
|
1202
|
+
displayName: "Prefer direct upgrade",
|
|
1203
|
+
description: "When fixing transitive vulnerabilities, first try to find higher versions of " +
|
|
1204
|
+
"direct dependencies that include safe transitive versions. Falls back to the " +
|
|
1205
|
+
"`transitiveFixStrategy` if no suitable direct upgrade exists. Queries npm registry. " +
|
|
1206
|
+
"Default is `true`.",
|
|
1207
|
+
required: false,
|
|
1208
|
+
example: "false"
|
|
1209
|
+
})
|
|
1210
|
+
], DependencyVulnerabilityCheck.prototype, "preferDirectUpgrade", void 0);
|
|
1284
1211
|
__decorate([
|
|
1285
1212
|
(0, rewrite_1.Option)({
|
|
1286
1213
|
displayName: "Maximum upgrade delta",
|
|
1287
1214
|
description: "The maximum difference to allow when upgrading a dependency version. " +
|
|
1288
|
-
"Use
|
|
1215
|
+
"Use `none` to only report vulnerabilities without making any changes. " +
|
|
1289
1216
|
"Patch version upgrades are the default and safest option. " +
|
|
1290
1217
|
"Minor version upgrades can introduce new features but typically no breaking changes. " +
|
|
1291
1218
|
"Major version upgrades may require code changes.",
|
|
@@ -1298,8 +1225,8 @@ __decorate([
|
|
|
1298
1225
|
(0, rewrite_1.Option)({
|
|
1299
1226
|
displayName: "Minimum severity",
|
|
1300
1227
|
description: "Only fix vulnerabilities with a severity level equal to or higher than the specified minimum. " +
|
|
1301
|
-
"Vulnerabilities are classified as LOW
|
|
1302
|
-
"Default is LOW
|
|
1228
|
+
"Vulnerabilities are classified as `LOW`, `MODERATE`, `HIGH`, or `CRITICAL` based on their potential impact. " +
|
|
1229
|
+
"Default is `LOW`, which includes all severity levels.",
|
|
1303
1230
|
required: false,
|
|
1304
1231
|
example: "MODERATE",
|
|
1305
1232
|
valid: ["LOW", "MODERATE", "HIGH", "CRITICAL"]
|
|
@@ -1319,11 +1246,11 @@ __decorate([
|
|
|
1319
1246
|
__decorate([
|
|
1320
1247
|
(0, rewrite_1.Option)({
|
|
1321
1248
|
displayName: "Fix declared versions",
|
|
1322
|
-
description: "When enabled, also upgrades version specifiers declared in package.json that specify vulnerable versions, " +
|
|
1249
|
+
description: "When enabled, also upgrades version specifiers declared in `package.json` that specify vulnerable versions, " +
|
|
1323
1250
|
"even if the lock file already resolves to a safe version. This is a preventive measure to ensure that " +
|
|
1324
1251
|
"future installs (e.g., on a different machine or after lock file changes) won't install vulnerable versions. " +
|
|
1325
1252
|
"These preventive upgrades are NOT reported in the vulnerability data table since there's no actual vulnerability. " +
|
|
1326
|
-
"Default is false
|
|
1253
|
+
"Default is `false`.",
|
|
1327
1254
|
required: false,
|
|
1328
1255
|
example: "true"
|
|
1329
1256
|
})
|
|
@@ -1331,49 +1258,11 @@ __decorate([
|
|
|
1331
1258
|
__decorate([
|
|
1332
1259
|
(0, rewrite_1.Option)({
|
|
1333
1260
|
displayName: "Add override comments",
|
|
1334
|
-
description: "When enabled, adds a comment field (e.g.,
|
|
1261
|
+
description: "When enabled, adds a comment field (e.g., `//overrides`) alongside overrides to document which CVEs " +
|
|
1335
1262
|
"each override is fixing. This helps with auditing and knowing when overrides can be removed. " +
|
|
1336
|
-
"Default is true
|
|
1263
|
+
"Default is `true`.",
|
|
1337
1264
|
required: false,
|
|
1338
1265
|
example: "true"
|
|
1339
1266
|
})
|
|
1340
1267
|
], DependencyVulnerabilityCheck.prototype, "addOverrideComments", void 0);
|
|
1341
|
-
function extractVersionPrefix(versionString) {
|
|
1342
|
-
const match = versionString.match(/^([~^]|>=?|<=?|=)?(.*)$/);
|
|
1343
|
-
if (match) {
|
|
1344
|
-
return {
|
|
1345
|
-
prefix: match[1] || '',
|
|
1346
|
-
version: match[2]
|
|
1347
|
-
};
|
|
1348
|
-
}
|
|
1349
|
-
return { prefix: '', version: versionString };
|
|
1350
|
-
}
|
|
1351
|
-
function applyVersionPrefix(originalVersion, newVersion) {
|
|
1352
|
-
const { prefix } = extractVersionPrefix(originalVersion);
|
|
1353
|
-
return prefix + newVersion;
|
|
1354
|
-
}
|
|
1355
|
-
function findDirectDependencyScope(packageJson, packageName) {
|
|
1356
|
-
var _a;
|
|
1357
|
-
for (const scope of ALL_DEPENDENCY_SCOPES) {
|
|
1358
|
-
if ((_a = packageJson[scope]) === null || _a === void 0 ? void 0 : _a[packageName]) {
|
|
1359
|
-
return scope;
|
|
1360
|
-
}
|
|
1361
|
-
}
|
|
1362
|
-
return undefined;
|
|
1363
|
-
}
|
|
1364
|
-
function getOverridesFromPackageJson(packageJson, packageManager) {
|
|
1365
|
-
var _a;
|
|
1366
|
-
switch (packageManager) {
|
|
1367
|
-
case "Npm":
|
|
1368
|
-
case "Bun":
|
|
1369
|
-
return packageJson.overrides;
|
|
1370
|
-
case "Pnpm":
|
|
1371
|
-
return (_a = packageJson.pnpm) === null || _a === void 0 ? void 0 : _a.overrides;
|
|
1372
|
-
case "YarnClassic":
|
|
1373
|
-
case "YarnBerry":
|
|
1374
|
-
return packageJson.resolutions;
|
|
1375
|
-
default:
|
|
1376
|
-
return undefined;
|
|
1377
|
-
}
|
|
1378
|
-
}
|
|
1379
1268
|
//# sourceMappingURL=dependency-vulnerability-check.js.map
|