@socketsecurity/cli-with-sentry 0.14.103 → 0.14.105

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.
@@ -5,9 +5,9 @@ const process$1 = require('node:process')
5
5
  const vendor = require('./vendor.js')
6
6
  const logger = require('@socketsecurity/registry/lib/logger')
7
7
  const constants = require('./constants.js')
8
+ const arrays = require('@socketsecurity/registry/lib/arrays')
8
9
  const packageurlJs = require('@socketregistry/packageurl-js')
9
10
  const registry = require('@socketsecurity/registry')
10
- const arrays = require('@socketsecurity/registry/lib/arrays')
11
11
  const debug = require('@socketsecurity/registry/lib/debug')
12
12
  const objects = require('@socketsecurity/registry/lib/objects')
13
13
  const isInteractive = require('@socketregistry/is-interactive/index.cjs')
@@ -15,7 +15,7 @@ const registryConstants = require('@socketsecurity/registry/lib/constants')
15
15
  const prompts = require('@socketsecurity/registry/lib/prompts')
16
16
  const strings = require('@socketsecurity/registry/lib/strings')
17
17
  const sdk = require('@socketsecurity/sdk')
18
- const require$$0 = require('node:fs')
18
+ const fs = require('node:fs')
19
19
  const os = require('node:os')
20
20
  const path = require('node:path')
21
21
  const promises = require('node:timers/promises')
@@ -36,7 +36,7 @@ async function findUp(name, { cwd = process$1.cwd(), signal = abortSignal }) {
36
36
  const filePath = path.join(dir, name)
37
37
  try {
38
38
  // eslint-disable-next-line no-await-in-loop
39
- const stats = await require$$0.promises.stat(filePath)
39
+ const stats = await fs.promises.stat(filePath)
40
40
  if (stats.isFile()) {
41
41
  return filePath
42
42
  }
@@ -47,14 +47,14 @@ async function findUp(name, { cwd = process$1.cwd(), signal = abortSignal }) {
47
47
  return undefined
48
48
  }
49
49
  async function readFileBinary(filepath, options) {
50
- return await require$$0.promises.readFile(filepath, {
50
+ return await fs.promises.readFile(filepath, {
51
51
  signal: abortSignal,
52
52
  ...options,
53
53
  encoding: 'binary'
54
54
  })
55
55
  }
56
56
  async function readFileUtf8(filepath, options) {
57
- return await require$$0.promises.readFile(filepath, {
57
+ return await fs.promises.readFile(filepath, {
58
58
  signal: abortSignal,
59
59
  ...options,
60
60
  encoding: 'utf8'
@@ -62,7 +62,7 @@ async function readFileUtf8(filepath, options) {
62
62
  }
63
63
  async function safeReadFile(filepath, options) {
64
64
  try {
65
- return await require$$0.promises.readFile(filepath, {
65
+ return await fs.promises.readFile(filepath, {
66
66
  encoding: 'utf8',
67
67
  signal: abortSignal,
68
68
  ...(typeof options === 'string'
@@ -76,7 +76,7 @@ async function safeReadFile(filepath, options) {
76
76
  }
77
77
  function safeReadFileSync(filepath, options) {
78
78
  try {
79
- return require$$0.readFileSync(filepath, {
79
+ return fs.readFileSync(filepath, {
80
80
  encoding: 'utf8',
81
81
  ...(typeof options === 'string'
82
82
  ? {
@@ -107,6 +107,7 @@ let _cachedConfig
107
107
  // When using --config or SOCKET_CLI_CONFIG, do not persist the config.
108
108
  let _readOnlyConfig = false
109
109
  function overrideCachedConfig(jsonConfig) {
110
+ debug.debugLog('Overriding entire config, marking config as read-only')
110
111
  let config
111
112
  try {
112
113
  config = JSON.parse(String(jsonConfig))
@@ -123,7 +124,7 @@ function overrideCachedConfig(jsonConfig) {
123
124
  }
124
125
  }
125
126
 
126
- // @ts-ignore if you want to override an illegal object, so be it?
127
+ // @ts-ignore Override an illegal object.
127
128
  _cachedConfig = config
128
129
  _readOnlyConfig = true
129
130
 
@@ -143,6 +144,7 @@ function overrideCachedConfig(jsonConfig) {
143
144
  }
144
145
  }
145
146
  function overrideConfigApiToken(apiToken) {
147
+ debug.debugLog('Overriding API token, marking config as read-only')
146
148
  // Set token to the local cached config and mark it read-only so it doesn't persist
147
149
  _cachedConfig = {
148
150
  ...vendor.configExports,
@@ -178,7 +180,7 @@ function getConfigValues() {
178
180
  updateConfigValue('apiToken', token)
179
181
  }
180
182
  } else {
181
- require$$0.mkdirSync(path.dirname(configPath), {
183
+ fs.mkdirSync(path.dirname(configPath), {
182
184
  recursive: true
183
185
  })
184
186
  }
@@ -282,7 +284,7 @@ function updateConfigValue(key, value) {
282
284
  _pendingSave = false
283
285
  const configPath = getConfigPath()
284
286
  if (configPath) {
285
- require$$0.writeFileSync(
287
+ fs.writeFileSync(
286
288
  configPath,
287
289
  Buffer.from(JSON.stringify(localConfig)).toString('base64')
288
290
  )
@@ -389,34 +391,14 @@ async function setupSdk(
389
391
  // The '@rollup/plugin-replace' will replace "process.env['INLINED_SOCKET_CLI_NAME']".
390
392
  name: '@socketsecurity/cli',
391
393
  // The '@rollup/plugin-replace' will replace "process.env['INLINED_SOCKET_CLI_VERSION']".
392
- version: '0.14.103',
394
+ version: '0.14.105',
393
395
  // The '@rollup/plugin-replace' will replace "process.env['INLINED_SOCKET_CLI_HOMEPAGE']".
394
396
  homepage: 'https://github.com/SocketDev/socket-cli'
395
397
  })
396
398
  })
397
399
  }
398
400
 
399
- function assignDefaultFixOptions(options) {
400
- if (options.autoPilot === undefined) {
401
- options.autoPilot = false
402
- }
403
- if (options.autoMerge === undefined) {
404
- options.autoMerge = !!options.autoPilot
405
- }
406
- if (options.cwd === undefined) {
407
- options.cwd = process.cwd()
408
- }
409
- if (options.rangeStyle === undefined) {
410
- options.rangeStyle = 'preserve'
411
- }
412
- if (options.test === undefined) {
413
- options.test = !!options.autoPilot || !!options.testScript
414
- }
415
- if (options.testScript === undefined) {
416
- options.testScript = 'test'
417
- }
418
- return options
419
- }
401
+ const RangeStyles = ['caret', 'gt', 'lt', 'pin', 'preserve', 'tilde']
420
402
  function applyRange(refRange, version, style = 'preserve') {
421
403
  switch (style) {
422
404
  case 'caret':
@@ -445,7 +427,6 @@ function applyRange(refRange, version, style = 'preserve') {
445
427
  return version
446
428
  }
447
429
  }
448
- const RangeStyles = ['caret', 'gt', 'lt', 'pin', 'preserve', 'tilde']
449
430
 
450
431
  const DiffAction = /*#__PURE__*/ (function (DiffAction) {
451
432
  DiffAction['add'] = 'ADD'
@@ -1192,135 +1173,406 @@ class SafeEdge extends Edge {
1192
1173
  }
1193
1174
  }
1194
1175
 
1195
- const {
1196
- ALERT_TYPE_CRITICAL_CVE,
1197
- ALERT_TYPE_CVE,
1198
- ALERT_TYPE_MEDIUM_CVE,
1199
- ALERT_TYPE_MILD_CVE
1200
- } = constants
1201
- function isArtifactAlertCve(alert) {
1202
- const { type } = alert
1203
- return (
1204
- type === ALERT_TYPE_CVE ||
1205
- type === ALERT_TYPE_MEDIUM_CVE ||
1206
- type === ALERT_TYPE_MILD_CVE ||
1207
- type === ALERT_TYPE_CRITICAL_CVE
1208
- )
1209
- }
1210
-
1211
- const ALERT_FIX_TYPE = /*#__PURE__*/ (function (ALERT_FIX_TYPE) {
1212
- ALERT_FIX_TYPE['cve'] = 'cve'
1213
- ALERT_FIX_TYPE['upgrade'] = 'upgrade'
1214
- return ALERT_FIX_TYPE
1215
- })({})
1216
-
1217
- function pick(input, keys) {
1218
- const result = {}
1219
- for (const key of keys) {
1220
- result[key] = input[key]
1221
- }
1222
- return result
1176
+ const { LOOP_SENTINEL, NPM: NPM$2, NPM_REGISTRY_URL } = constants
1177
+ function getUrlOrigin(input) {
1178
+ try {
1179
+ // TODO: URL.parse is available in Node 22.1.0. We can use it when we drop Node 18.
1180
+ // https://nodejs.org/docs/latest-v22.x/api/url.html#urlparseinput-base
1181
+ // return URL.parse(input)?.origin ?? ''
1182
+ return new URL(input).origin ?? ''
1183
+ } catch {}
1184
+ return ''
1223
1185
  }
1224
-
1225
- function stringJoinWithSeparateFinalSeparator(list, separator = ' and ') {
1226
- const values = list.filter(Boolean)
1227
- const { length } = values
1228
- if (!length) {
1229
- return ''
1230
- }
1231
- if (length === 1) {
1232
- return values[0]
1186
+ function findBestPatchVersion(
1187
+ node,
1188
+ availableVersions,
1189
+ vulnerableVersionRange,
1190
+ _firstPatchedVersionIdentifier
1191
+ ) {
1192
+ const manifestData = registry.getManifestData(NPM$2, node.name)
1193
+ let eligibleVersions
1194
+ if (manifestData && manifestData.name === manifestData.package) {
1195
+ const major = vendor.semverExports.major(manifestData.version)
1196
+ eligibleVersions = availableVersions.filter(
1197
+ v => vendor.semverExports.major(v) === major
1198
+ )
1199
+ } else {
1200
+ const major = vendor.semverExports.major(node.version)
1201
+ eligibleVersions = availableVersions.filter(
1202
+ v =>
1203
+ // Filter for versions that are within the current major version and
1204
+ // are NOT in the vulnerable range.
1205
+ vendor.semverExports.major(v) === major &&
1206
+ (!vulnerableVersionRange ||
1207
+ !vendor.semverExports.satisfies(v, vulnerableVersionRange))
1208
+ )
1233
1209
  }
1234
- const finalValue = values.pop()
1235
- return `${values.join(', ')}${separator}${finalValue}`
1210
+ return vendor.semverExports.maxSatisfying(eligibleVersions, '*')
1236
1211
  }
1237
-
1238
- const ALERT_SEVERITY = /*#__PURE__*/ (function (ALERT_SEVERITY) {
1239
- ALERT_SEVERITY['critical'] = 'critical'
1240
- ALERT_SEVERITY['high'] = 'high'
1241
- ALERT_SEVERITY['middle'] = 'middle'
1242
- ALERT_SEVERITY['low'] = 'low'
1243
- return ALERT_SEVERITY
1244
- })({})
1245
- // Ordered from most severe to least.
1246
- const ALERT_SEVERITIES_SORTED = Object.freeze([
1247
- 'critical',
1248
- 'high',
1249
- 'middle',
1250
- 'low'
1251
- ])
1252
- function getDesiredSeverities(lowestToInclude) {
1253
- const result = []
1254
- for (const severity of ALERT_SEVERITIES_SORTED) {
1255
- result.push(severity)
1256
- if (severity === lowestToInclude) {
1257
- break
1212
+ function findPackageNode(tree, name, version) {
1213
+ const queue = [tree]
1214
+ let sentinel = 0
1215
+ while (queue.length) {
1216
+ if (sentinel++ === LOOP_SENTINEL) {
1217
+ throw new Error('Detected infinite loop in findPackageNodes')
1258
1218
  }
1259
- }
1260
- return result
1261
- }
1262
- function formatSeverityCount(severityCount) {
1263
- const summary = []
1264
- for (const severity of ALERT_SEVERITIES_SORTED) {
1265
- if (severityCount[severity]) {
1266
- summary.push(`${severityCount[severity]} ${severity}`)
1219
+ const currentNode = queue.pop()
1220
+ const node = currentNode.children.get(name)
1221
+ if (node && (typeof version !== 'string' || node.version === version)) {
1222
+ return node
1223
+ }
1224
+ const children = [...currentNode.children.values()]
1225
+ for (let i = children.length - 1; i >= 0; i -= 1) {
1226
+ queue.push(children[i])
1267
1227
  }
1268
1228
  }
1269
- return stringJoinWithSeparateFinalSeparator(summary)
1270
1229
  }
1271
- function getSeverityCount(issues, lowestToInclude) {
1272
- const severityCount = pick(
1273
- {
1274
- low: 0,
1275
- middle: 0,
1276
- high: 0,
1277
- critical: 0
1278
- },
1279
- getDesiredSeverities(lowestToInclude)
1280
- )
1281
- for (const issue of issues) {
1282
- const { value } = issue
1283
- if (!value) {
1284
- continue
1230
+ function findPackageNodes(tree, name, version) {
1231
+ const queue = [tree]
1232
+ const matches = []
1233
+ let sentinel = 0
1234
+ while (queue.length) {
1235
+ if (sentinel++ === LOOP_SENTINEL) {
1236
+ throw new Error('Detected infinite loop in findPackageNodes')
1285
1237
  }
1286
- const { severity } = value
1287
- if (severityCount[severity] !== undefined) {
1288
- severityCount[severity] += 1
1238
+ const currentNode = queue.pop()
1239
+ const node = currentNode.children.get(name)
1240
+ if (node && 'undefined' !== 'string') {
1241
+ matches.push(node)
1242
+ }
1243
+ const children = [...currentNode.children.values()]
1244
+ for (let i = children.length - 1; i >= 0; i -= 1) {
1245
+ queue.push(children[i])
1289
1246
  }
1290
1247
  }
1291
- return severityCount
1248
+ return matches
1292
1249
  }
1293
-
1294
- class ColorOrMarkdown {
1295
- constructor(useMarkdown) {
1296
- this.useMarkdown = !!useMarkdown
1297
- }
1298
- bold(text) {
1299
- return this.useMarkdown
1300
- ? `**${text}**`
1301
- : vendor.yoctocolorsCjsExports.bold(`${text}`)
1250
+ function getDetailsFromDiff(diff_, options) {
1251
+ const details = []
1252
+ // `diff_` is `null` when `npm install --package-lock-only` is passed.
1253
+ if (!diff_) {
1254
+ return details
1302
1255
  }
1303
- header(text, level = 1) {
1304
- return this.useMarkdown
1305
- ? `\n${''.padStart(level, '#')} ${text}\n`
1306
- : vendor.yoctocolorsCjsExports.underline(
1307
- `\n${level === 1 ? vendor.yoctocolorsCjsExports.bold(text) : text}\n`
1308
- )
1256
+ const include = {
1257
+ __proto__: null,
1258
+ unchanged: false,
1259
+ unknownOrigin: false,
1260
+ ...{
1261
+ __proto__: null,
1262
+ ...options
1263
+ }.include
1309
1264
  }
1310
- hyperlink(text, url, { fallback = true, fallbackToUrl } = {}) {
1311
- if (url) {
1312
- return this.useMarkdown
1313
- ? `[${text}](${url})`
1314
- : vendor.terminalLinkExports(text, url, {
1315
- fallback: fallbackToUrl ? (_text, url) => url : fallback
1265
+ const queue = [...diff_.children]
1266
+ let pos = 0
1267
+ let { length: queueLength } = queue
1268
+ while (pos < queueLength) {
1269
+ if (pos === LOOP_SENTINEL) {
1270
+ throw new Error('Detected infinite loop while walking Arborist diff')
1271
+ }
1272
+ const diff = queue[pos++]
1273
+ const { action } = diff
1274
+ if (action) {
1275
+ // The `pkgNode`, i.e. the `ideal` node, will be `undefined` if the diff
1276
+ // action is 'REMOVE'
1277
+ // The `oldNode`, i.e. the `actual` node, will be `undefined` if the diff
1278
+ // action is 'ADD'.
1279
+ const { actual: oldNode, ideal: pkgNode } = diff
1280
+ let existing
1281
+ let keep = false
1282
+ if (action === DiffAction.change) {
1283
+ if (pkgNode?.package.version !== oldNode?.package.version) {
1284
+ keep = true
1285
+ if (
1286
+ oldNode?.package.name &&
1287
+ oldNode.package.name === pkgNode?.package.name
1288
+ ) {
1289
+ existing = oldNode
1290
+ }
1291
+ } else {
1292
+ debug.debugLog('SKIPPING META CHANGE ON\n', diff)
1293
+ }
1294
+ } else {
1295
+ keep = action !== DiffAction.remove
1296
+ }
1297
+ if (keep && pkgNode?.resolved && (!oldNode || oldNode.resolved)) {
1298
+ if (
1299
+ include.unknownOrigin ||
1300
+ getUrlOrigin(pkgNode.resolved) === NPM_REGISTRY_URL
1301
+ ) {
1302
+ details.push({
1303
+ node: pkgNode,
1304
+ existing
1316
1305
  })
1306
+ }
1307
+ }
1308
+ }
1309
+ for (const child of diff.children) {
1310
+ queue[queueLength++] = child
1317
1311
  }
1318
- return text
1319
1312
  }
1320
- indent(...args) {
1321
- return indentString(...args)
1313
+ if (include.unchanged) {
1314
+ const { unchanged } = diff_
1315
+ for (let i = 0, { length } = unchanged; i < length; i += 1) {
1316
+ const pkgNode = unchanged[i]
1317
+ if (
1318
+ include.unknownOrigin ||
1319
+ getUrlOrigin(pkgNode.resolved) === NPM_REGISTRY_URL
1320
+ ) {
1321
+ details.push({
1322
+ node: pkgNode,
1323
+ existing: pkgNode
1324
+ })
1325
+ }
1326
+ }
1322
1327
  }
1323
- italic(text) {
1328
+ return details
1329
+ }
1330
+ function isTopLevel(tree, node) {
1331
+ return tree.children.get(node.name) === node
1332
+ }
1333
+ function updateNode(
1334
+ node,
1335
+ packument,
1336
+ vulnerableVersionRange,
1337
+ firstPatchedVersionIdentifier
1338
+ ) {
1339
+ const availableVersions = Object.keys(packument.versions)
1340
+ // Find the highest non-vulnerable version within the same major range
1341
+ const targetVersion = findBestPatchVersion(
1342
+ node,
1343
+ availableVersions,
1344
+ vulnerableVersionRange
1345
+ )
1346
+ const targetPackument = targetVersion
1347
+ ? packument.versions[targetVersion]
1348
+ : undefined
1349
+ // Check !targetVersion to make TypeScript happy.
1350
+ if (!targetVersion || !targetPackument) {
1351
+ // No suitable patch version found.
1352
+ return false
1353
+ }
1354
+ // Object.defineProperty is needed to set the version property and replace
1355
+ // the old value with targetVersion.
1356
+ Object.defineProperty(node, 'version', {
1357
+ configurable: true,
1358
+ enumerable: true,
1359
+ get: () => targetVersion
1360
+ })
1361
+ // Update package.version associated with the node.
1362
+ node.package.version = targetVersion
1363
+ // Update node.resolved.
1364
+ const purlObj = packageurlJs.PackageURL.fromString(`pkg:npm/${node.name}`)
1365
+ node.resolved = `${NPM_REGISTRY_URL}/${node.name}/-/${purlObj.name}-${targetVersion}.tgz`
1366
+ // Update node.integrity with the targetPackument.dist.integrity value if available
1367
+ // else delete node.integrity so a new value is resolved for the target version.
1368
+ const { integrity } = targetPackument.dist
1369
+ if (integrity) {
1370
+ node.integrity = integrity
1371
+ } else {
1372
+ delete node.integrity
1373
+ }
1374
+ // Update node.package.deprecated based on targetPackument.deprecated.
1375
+ if (objects.hasOwn(targetPackument, 'deprecated')) {
1376
+ node.package['deprecated'] = targetPackument.deprecated
1377
+ } else {
1378
+ delete node.package['deprecated']
1379
+ }
1380
+ // Update node.package.dependencies.
1381
+ const newDeps = {
1382
+ ...targetPackument.dependencies
1383
+ }
1384
+ const { dependencies: oldDeps } = node.package
1385
+ node.package.dependencies = newDeps
1386
+ if (oldDeps) {
1387
+ for (const oldDepName of Object.keys(oldDeps)) {
1388
+ if (!objects.hasOwn(newDeps, oldDepName)) {
1389
+ // Detach old edges for dependencies that don't exist on the updated
1390
+ // node.package.dependencies.
1391
+ node.edgesOut.get(oldDepName)?.detach()
1392
+ }
1393
+ }
1394
+ }
1395
+ for (const newDepName of Object.keys(newDeps)) {
1396
+ if (!objects.hasOwn(oldDeps, newDepName)) {
1397
+ // Add new edges for dependencies that don't exist on the old
1398
+ // node.package.dependencies.
1399
+ node.addEdgeOut(
1400
+ new Edge({
1401
+ from: node,
1402
+ name: newDepName,
1403
+ spec: newDeps[newDepName],
1404
+ type: 'prod'
1405
+ })
1406
+ )
1407
+ }
1408
+ }
1409
+ return true
1410
+ }
1411
+ function updatePackageJsonFromNode(
1412
+ editablePkgJson,
1413
+ tree,
1414
+ node,
1415
+ targetVersion,
1416
+ rangeStyle
1417
+ ) {
1418
+ let result = false
1419
+ if (isTopLevel(tree, node)) {
1420
+ const { name } = node
1421
+ for (const depField of [
1422
+ 'dependencies',
1423
+ 'optionalDependencies',
1424
+ 'peerDependencies'
1425
+ ]) {
1426
+ const depObject = editablePkgJson.content[depField]
1427
+ if (depObject) {
1428
+ const oldRange = depObject[name]
1429
+ if (oldRange) {
1430
+ const newRange = applyRange(oldRange, targetVersion, rangeStyle)
1431
+ if (oldRange !== newRange) {
1432
+ result = true
1433
+ editablePkgJson.update({
1434
+ [depField]: {
1435
+ ...depObject,
1436
+ [name]: newRange
1437
+ }
1438
+ })
1439
+ }
1440
+ }
1441
+ }
1442
+ }
1443
+ }
1444
+ return result
1445
+ }
1446
+
1447
+ const {
1448
+ ALERT_TYPE_CRITICAL_CVE,
1449
+ ALERT_TYPE_CVE,
1450
+ ALERT_TYPE_MEDIUM_CVE,
1451
+ ALERT_TYPE_MILD_CVE
1452
+ } = constants
1453
+ function isArtifactAlertCve(alert) {
1454
+ const { type } = alert
1455
+ return (
1456
+ type === ALERT_TYPE_CVE ||
1457
+ type === ALERT_TYPE_MEDIUM_CVE ||
1458
+ type === ALERT_TYPE_MILD_CVE ||
1459
+ type === ALERT_TYPE_CRITICAL_CVE
1460
+ )
1461
+ }
1462
+
1463
+ const ALERT_FIX_TYPE = /*#__PURE__*/ (function (ALERT_FIX_TYPE) {
1464
+ ALERT_FIX_TYPE['cve'] = 'cve'
1465
+ ALERT_FIX_TYPE['upgrade'] = 'upgrade'
1466
+ return ALERT_FIX_TYPE
1467
+ })({})
1468
+
1469
+ function pick(input, keys) {
1470
+ const result = {}
1471
+ for (const key of keys) {
1472
+ result[key] = input[key]
1473
+ }
1474
+ return result
1475
+ }
1476
+
1477
+ function stringJoinWithSeparateFinalSeparator(list, separator = ' and ') {
1478
+ const values = list.filter(Boolean)
1479
+ const { length } = values
1480
+ if (!length) {
1481
+ return ''
1482
+ }
1483
+ if (length === 1) {
1484
+ return values[0]
1485
+ }
1486
+ const finalValue = values.pop()
1487
+ return `${values.join(', ')}${separator}${finalValue}`
1488
+ }
1489
+
1490
+ const ALERT_SEVERITY = /*#__PURE__*/ (function (ALERT_SEVERITY) {
1491
+ ALERT_SEVERITY['critical'] = 'critical'
1492
+ ALERT_SEVERITY['high'] = 'high'
1493
+ ALERT_SEVERITY['middle'] = 'middle'
1494
+ ALERT_SEVERITY['low'] = 'low'
1495
+ return ALERT_SEVERITY
1496
+ })({})
1497
+ // Ordered from most severe to least.
1498
+ const ALERT_SEVERITIES_SORTED = Object.freeze([
1499
+ 'critical',
1500
+ 'high',
1501
+ 'middle',
1502
+ 'low'
1503
+ ])
1504
+ function getDesiredSeverities(lowestToInclude) {
1505
+ const result = []
1506
+ for (const severity of ALERT_SEVERITIES_SORTED) {
1507
+ result.push(severity)
1508
+ if (severity === lowestToInclude) {
1509
+ break
1510
+ }
1511
+ }
1512
+ return result
1513
+ }
1514
+ function formatSeverityCount(severityCount) {
1515
+ const summary = []
1516
+ for (const severity of ALERT_SEVERITIES_SORTED) {
1517
+ if (severityCount[severity]) {
1518
+ summary.push(`${severityCount[severity]} ${severity}`)
1519
+ }
1520
+ }
1521
+ return stringJoinWithSeparateFinalSeparator(summary)
1522
+ }
1523
+ function getSeverityCount(issues, lowestToInclude) {
1524
+ const severityCount = pick(
1525
+ {
1526
+ low: 0,
1527
+ middle: 0,
1528
+ high: 0,
1529
+ critical: 0
1530
+ },
1531
+ getDesiredSeverities(lowestToInclude)
1532
+ )
1533
+ for (const issue of issues) {
1534
+ const { value } = issue
1535
+ if (!value) {
1536
+ continue
1537
+ }
1538
+ const { severity } = value
1539
+ if (severityCount[severity] !== undefined) {
1540
+ severityCount[severity] += 1
1541
+ }
1542
+ }
1543
+ return severityCount
1544
+ }
1545
+
1546
+ class ColorOrMarkdown {
1547
+ constructor(useMarkdown) {
1548
+ this.useMarkdown = !!useMarkdown
1549
+ }
1550
+ bold(text) {
1551
+ return this.useMarkdown
1552
+ ? `**${text}**`
1553
+ : vendor.yoctocolorsCjsExports.bold(`${text}`)
1554
+ }
1555
+ header(text, level = 1) {
1556
+ return this.useMarkdown
1557
+ ? `\n${''.padStart(level, '#')} ${text}\n`
1558
+ : vendor.yoctocolorsCjsExports.underline(
1559
+ `\n${level === 1 ? vendor.yoctocolorsCjsExports.bold(text) : text}\n`
1560
+ )
1561
+ }
1562
+ hyperlink(text, url, { fallback = true, fallbackToUrl } = {}) {
1563
+ if (url) {
1564
+ return this.useMarkdown
1565
+ ? `[${text}](${url})`
1566
+ : vendor.terminalLinkExports(text, url, {
1567
+ fallback: fallbackToUrl ? (_text, url) => url : fallback
1568
+ })
1569
+ }
1570
+ return text
1571
+ }
1572
+ indent(...args) {
1573
+ return indentString(...args)
1574
+ }
1575
+ italic(text) {
1324
1576
  return this.useMarkdown
1325
1577
  ? `_${text}_`
1326
1578
  : vendor.yoctocolorsCjsExports.italic(`${text}`)
@@ -1371,7 +1623,7 @@ const ALERT_SEVERITY_ORDER = /*#__PURE__*/ (function (ALERT_SEVERITY_ORDER) {
1371
1623
  ALERT_SEVERITY_ORDER[(ALERT_SEVERITY_ORDER['none'] = 4)] = 'none'
1372
1624
  return ALERT_SEVERITY_ORDER
1373
1625
  })({})
1374
- const { CVE_ALERT_PROPS_FIRST_PATCHED_VERSION_IDENTIFIER, NPM: NPM$2 } =
1626
+ const { CVE_ALERT_PROPS_FIRST_PATCHED_VERSION_IDENTIFIER, NPM: NPM$1 } =
1375
1627
  constants
1376
1628
  const MIN_ABOVE_THE_FOLD_COUNT = 3
1377
1629
  const MIN_ABOVE_THE_FOLD_ALERT_COUNT = 1
@@ -1585,7 +1837,7 @@ function getCveInfoByAlertsMap(alertsMap, options) {
1585
1837
  const alert = sockPkgAlert.raw
1586
1838
  if (
1587
1839
  alert.fix?.type !== ALERT_FIX_TYPE.cve ||
1588
- (exclude.upgradable && registry.getManifestData(NPM$2, name))
1840
+ (exclude.upgradable && registry.getManifestData(NPM$1, name))
1589
1841
  ) {
1590
1842
  continue
1591
1843
  }
@@ -1728,7 +1980,7 @@ function logAlertsMap(alertsMap, options) {
1728
1980
  const hyperlink = format.hyperlink(
1729
1981
  pkgId,
1730
1982
  getSocketDevPackageOverviewUrl(
1731
- NPM$2,
1983
+ NPM$1,
1732
1984
  packages.resolvePackageName(purlObj),
1733
1985
  purlObj.version
1734
1986
  )
@@ -1785,161 +2037,57 @@ function logAlertsMap(alertsMap, options) {
1785
2037
  output.write('\n')
1786
2038
  }
1787
2039
 
1788
- const { LOOP_SENTINEL, NPM: NPM$1, NPM_REGISTRY_URL } = constants
1789
- function getDetailsFromDiff(diff_, options) {
1790
- const details = []
1791
- // `diff_` is `null` when `npm install --package-lock-only` is passed.
1792
- if (!diff_) {
1793
- return details
2040
+ async function getAlertsMapFromArborist(arb, options_) {
2041
+ const options = {
2042
+ __proto__: null,
2043
+ consolidate: false,
2044
+ nothrow: false,
2045
+ ...options_
1794
2046
  }
1795
2047
  const include = {
1796
2048
  __proto__: null,
1797
- unchanged: false,
1798
- unknownOrigin: false,
1799
- ...{
1800
- __proto__: null,
1801
- ...options
1802
- }.include
2049
+ existing: false,
2050
+ ...options.include
1803
2051
  }
1804
- const queue = [...diff_.children]
1805
- let pos = 0
1806
- let { length: queueLength } = queue
1807
- while (pos < queueLength) {
1808
- if (pos === LOOP_SENTINEL) {
1809
- throw new Error('Detected infinite loop while walking Arborist diff')
1810
- }
1811
- const diff = queue[pos++]
1812
- const { action } = diff
1813
- if (action) {
1814
- // The `pkgNode`, i.e. the `ideal` node, will be `undefined` if the diff
1815
- // action is 'REMOVE'
1816
- // The `oldNode`, i.e. the `actual` node, will be `undefined` if the diff
1817
- // action is 'ADD'.
1818
- const { actual: oldNode, ideal: pkgNode } = diff
1819
- let existing
1820
- let keep = false
1821
- if (action === DiffAction.change) {
1822
- if (pkgNode?.package.version !== oldNode?.package.version) {
1823
- keep = true
1824
- if (
1825
- oldNode?.package.name &&
1826
- oldNode.package.name === pkgNode?.package.name
1827
- ) {
1828
- existing = oldNode
1829
- }
1830
- } else {
1831
- debug.debugLog('SKIPPING META CHANGE ON\n', diff)
1832
- }
1833
- } else {
1834
- keep = action !== DiffAction.remove
1835
- }
1836
- if (keep && pkgNode?.resolved && (!oldNode || oldNode.resolved)) {
1837
- if (
1838
- include.unknownOrigin ||
1839
- getUrlOrigin(pkgNode.resolved) === NPM_REGISTRY_URL
1840
- ) {
1841
- details.push({
1842
- node: pkgNode,
1843
- existing
1844
- })
1845
- }
1846
- }
1847
- }
1848
- for (const child of diff.children) {
1849
- queue[queueLength++] = child
1850
- }
1851
- }
1852
- if (include.unchanged) {
1853
- const { unchanged } = diff_
1854
- for (let i = 0, { length } = unchanged; i < length; i += 1) {
1855
- const pkgNode = unchanged[i]
1856
- if (
1857
- include.unknownOrigin ||
1858
- getUrlOrigin(pkgNode.resolved) === NPM_REGISTRY_URL
1859
- ) {
1860
- details.push({
1861
- node: pkgNode,
1862
- existing: pkgNode
1863
- })
1864
- }
2052
+ const needInfoOn = getDetailsFromDiff(arb.diff, {
2053
+ include: {
2054
+ unchanged: include.existing
1865
2055
  }
1866
- }
1867
- return details
1868
- }
1869
- function getUrlOrigin(input) {
1870
- try {
1871
- // TODO: URL.parse is available in Node 22.1.0. We can use it when we drop Node 18.
1872
- // https://nodejs.org/docs/latest-v22.x/api/url.html#urlparseinput-base
1873
- // return URL.parse(input)?.origin ?? ''
1874
- return new URL(input).origin ?? ''
1875
- } catch {}
1876
- return ''
1877
- }
1878
- function findBestPatchVersion(
1879
- node,
1880
- availableVersions,
1881
- vulnerableVersionRange,
1882
- _firstPatchedVersionIdentifier
1883
- ) {
1884
- const manifestData = registry.getManifestData(NPM$1, node.name)
1885
- let eligibleVersions
1886
- if (manifestData && manifestData.name === manifestData.package) {
1887
- const major = vendor.semverExports.major(manifestData.version)
1888
- eligibleVersions = availableVersions.filter(
1889
- v => vendor.semverExports.major(v) === major
1890
- )
1891
- } else {
1892
- const major = vendor.semverExports.major(node.version)
1893
- eligibleVersions = availableVersions.filter(
1894
- v =>
1895
- // Filter for versions that are within the current major version and
1896
- // are NOT in the vulnerable range.
1897
- vendor.semverExports.major(v) === major &&
1898
- (!vulnerableVersionRange ||
1899
- !vendor.semverExports.satisfies(v, vulnerableVersionRange))
2056
+ })
2057
+ const purls = needInfoOn.map(d => `pkg:npm/${d.node.pkgid}`)
2058
+ let overrides
2059
+ const overridesMap = (
2060
+ arb.actualTree ??
2061
+ arb.idealTree ??
2062
+ (await arb.loadActual())
2063
+ )?.overrides?.children
2064
+ if (overridesMap) {
2065
+ overrides = Object.fromEntries(
2066
+ [...overridesMap.entries()].map(([key, overrideSet]) => {
2067
+ return [key, overrideSet.value]
2068
+ })
1900
2069
  )
1901
2070
  }
1902
- return vendor.semverExports.maxSatisfying(eligibleVersions, '*')
1903
- }
1904
- function findPackageNode(tree, name, version) {
1905
- const queue = [tree]
1906
- let sentinel = 0
1907
- while (queue.length) {
1908
- if (sentinel++ === LOOP_SENTINEL) {
1909
- throw new Error('Detected infinite loop in findPackageNodes')
1910
- }
1911
- const currentNode = queue.pop()
1912
- const node = currentNode.children.get(name)
1913
- if (node && (typeof version !== 'string' || node.version === version)) {
1914
- return node
1915
- }
1916
- const children = [...currentNode.children.values()]
1917
- for (let i = children.length - 1; i >= 0; i -= 1) {
1918
- queue.push(children[i])
1919
- }
1920
- }
2071
+ return await getAlertsMapFromPurls(purls, {
2072
+ overrides,
2073
+ ...options
2074
+ })
1921
2075
  }
1922
- function findPackageNodes(tree, name, version) {
1923
- const queue = [tree]
1924
- const matches = []
1925
- let sentinel = 0
1926
- while (queue.length) {
1927
- if (sentinel++ === LOOP_SENTINEL) {
1928
- throw new Error('Detected infinite loop in findPackageNodes')
1929
- }
1930
- const currentNode = queue.pop()
1931
- const node = currentNode.children.get(name)
1932
- if (node && 'undefined' !== 'string') {
1933
- matches.push(node)
1934
- }
1935
- const children = [...currentNode.children.values()]
1936
- for (let i = children.length - 1; i >= 0; i -= 1) {
1937
- queue.push(children[i])
1938
- }
2076
+ async function getAlertsMapFromPnpmLockfile(lockfile, options_) {
2077
+ const options = {
2078
+ __proto__: null,
2079
+ consolidate: false,
2080
+ nothrow: false,
2081
+ ...options_
1939
2082
  }
1940
- return matches
2083
+ const depTypes = vendor.libExports$1.detectDepTypes(lockfile)
2084
+ const purls = Object.keys(depTypes).map(id => `pkg:npm/${id}`)
2085
+ return await getAlertsMapFromPurls(purls, {
2086
+ overrides: lockfile.overrides,
2087
+ ...options
2088
+ })
1941
2089
  }
1942
- async function getAlertsMapFromArborist(arb, options_) {
2090
+ async function getAlertsMapFromPurls(purls, options_) {
1943
2091
  const options = {
1944
2092
  __proto__: null,
1945
2093
  consolidate: false,
@@ -1958,35 +2106,17 @@ async function getAlertsMapFromArborist(arb, options_) {
1958
2106
  ...options.include
1959
2107
  }
1960
2108
  const { spinner } = options
1961
- const needInfoOn = getDetailsFromDiff(arb.diff, {
1962
- include: {
1963
- unchanged: include.existing
1964
- }
1965
- })
1966
- const pkgIds = arrays.arrayUnique(needInfoOn.map(d => d.node.pkgid))
1967
- let { length: remaining } = pkgIds
2109
+ const uniqPurls = arrays.arrayUnique(purls)
2110
+ let { length: remaining } = uniqPurls
1968
2111
  const alertsByPkgId = new Map()
1969
2112
  if (!remaining) {
1970
2113
  return alertsByPkgId
1971
2114
  }
1972
2115
  const getText = () => `Looking up data for ${remaining} packages`
1973
2116
  spinner?.start(getText())
1974
- let overrides
1975
- const overridesMap = (
1976
- arb.actualTree ??
1977
- arb.idealTree ??
1978
- (await arb.loadActual())
1979
- )?.overrides?.children
1980
- if (overridesMap) {
1981
- overrides = Object.fromEntries(
1982
- [...overridesMap.entries()].map(([key, overrideSet]) => {
1983
- return [key, overrideSet.value]
1984
- })
1985
- )
1986
- }
1987
2117
  const sockSdk = await setupSdk(getPublicToken())
1988
2118
  const toAlertsMapOptions = {
1989
- overrides,
2119
+ overrides: options.overrides,
1990
2120
  consolidate: options.consolidate,
1991
2121
  include,
1992
2122
  spinner
@@ -2007,8 +2137,8 @@ async function getAlertsMapFromArborist(arb, options_) {
2007
2137
  })
2008
2138
  },
2009
2139
  {
2010
- components: pkgIds.map(id => ({
2011
- purl: `pkg:npm/${id}`
2140
+ components: uniqPurls.map(purl => ({
2141
+ purl
2012
2142
  }))
2013
2143
  }
2014
2144
  )) {
@@ -2034,116 +2164,6 @@ async function getAlertsMapFromArborist(arb, options_) {
2034
2164
  spinner?.stop()
2035
2165
  return alertsByPkgId
2036
2166
  }
2037
- function isTopLevel(tree, node) {
2038
- return tree.children.get(node.name) === node
2039
- }
2040
- function updateNode(
2041
- node,
2042
- packument,
2043
- vulnerableVersionRange,
2044
- firstPatchedVersionIdentifier
2045
- ) {
2046
- const availableVersions = Object.keys(packument.versions)
2047
- // Find the highest non-vulnerable version within the same major range
2048
- const targetVersion = findBestPatchVersion(
2049
- node,
2050
- availableVersions,
2051
- vulnerableVersionRange
2052
- )
2053
- const targetPackument = targetVersion
2054
- ? packument.versions[targetVersion]
2055
- : undefined
2056
- // Check !targetVersion to make TypeScript happy.
2057
- if (!targetVersion || !targetPackument) {
2058
- // No suitable patch version found.
2059
- return false
2060
- }
2061
- // Object.defineProperty is needed to set the version property and replace
2062
- // the old value with targetVersion.
2063
- Object.defineProperty(node, 'version', {
2064
- configurable: true,
2065
- enumerable: true,
2066
- get: () => targetVersion
2067
- })
2068
- // Update package.version associated with the node.
2069
- node.package.version = targetVersion
2070
- // Update node.resolved.
2071
- const purlObj = packageurlJs.PackageURL.fromString(`pkg:npm/${node.name}`)
2072
- node.resolved = `${NPM_REGISTRY_URL}/${node.name}/-/${purlObj.name}-${targetVersion}.tgz`
2073
- // Update node.integrity with the targetPackument.dist.integrity value if available
2074
- // else delete node.integrity so a new value is resolved for the target version.
2075
- const { integrity } = targetPackument.dist
2076
- if (integrity) {
2077
- node.integrity = integrity
2078
- } else {
2079
- delete node.integrity
2080
- }
2081
- // Update node.package.deprecated based on targetPackument.deprecated.
2082
- if (objects.hasOwn(targetPackument, 'deprecated')) {
2083
- node.package['deprecated'] = targetPackument.deprecated
2084
- } else {
2085
- delete node.package['deprecated']
2086
- }
2087
- // Update node.package.dependencies.
2088
- const newDeps = {
2089
- ...targetPackument.dependencies
2090
- }
2091
- const { dependencies: oldDeps } = node.package
2092
- node.package.dependencies = newDeps
2093
- if (oldDeps) {
2094
- for (const oldDepName of Object.keys(oldDeps)) {
2095
- if (!objects.hasOwn(newDeps, oldDepName)) {
2096
- // Detach old edges for dependencies that don't exist on the updated
2097
- // node.package.dependencies.
2098
- node.edgesOut.get(oldDepName)?.detach()
2099
- }
2100
- }
2101
- }
2102
- for (const newDepName of Object.keys(newDeps)) {
2103
- if (!objects.hasOwn(oldDeps, newDepName)) {
2104
- // Add new edges for dependencies that don't exist on the old
2105
- // node.package.dependencies.
2106
- node.addEdgeOut(
2107
- new Edge({
2108
- from: node,
2109
- name: newDepName,
2110
- spec: newDeps[newDepName],
2111
- type: 'prod'
2112
- })
2113
- )
2114
- }
2115
- }
2116
- return true
2117
- }
2118
- function updatePackageJsonFromNode(
2119
- editablePkgJson,
2120
- tree,
2121
- node,
2122
- targetVersion,
2123
- rangeStyle
2124
- ) {
2125
- if (isTopLevel(tree, node)) {
2126
- const { name } = node
2127
- for (const depField of [
2128
- 'dependencies',
2129
- 'optionalDependencies',
2130
- 'peerDependencies'
2131
- ]) {
2132
- const oldValue = editablePkgJson.content[depField]
2133
- if (oldValue) {
2134
- const refRange = oldValue[name]
2135
- if (refRange) {
2136
- editablePkgJson.update({
2137
- [depField]: {
2138
- ...oldValue,
2139
- [name]: applyRange(refRange, targetVersion, rangeStyle)
2140
- }
2141
- })
2142
- }
2143
- }
2144
- }
2145
- }
2146
- }
2147
2167
 
2148
2168
  const {
2149
2169
  NPM,
@@ -2222,7 +2242,7 @@ class SafeArborist extends Arborist {
2222
2242
  ...SAFE_ARBORIST_REIFY_OPTIONS_OVERRIDES,
2223
2243
  progress: false
2224
2244
  },
2225
- // @ts-ignore: TS gets grumpy about rest parameters.
2245
+ // @ts-ignore: TypeScript gets grumpy about rest parameters.
2226
2246
  ...args.slice(1)
2227
2247
  )
2228
2248
  // Lazily access constants.ENV[SOCKET_CLI_ACCEPT_RISKS].
@@ -2260,7 +2280,7 @@ class SafeArborist extends Arborist {
2260
2280
  hideAt: viewAllRisks ? 'none' : 'middle',
2261
2281
  output: process$1.stderr
2262
2282
  })
2263
- throw new Error(vendor.stripIndents`
2283
+ throw new Error(vendor.html`
2264
2284
  Socket ${binName} exiting due to risks.${viewAllRisks ? '' : `\nView all risks - Rerun with environment variable ${SOCKET_CLI_VIEW_ALL_RISKS}=1.`}${acceptRisks ? '' : `\nAccept risks - Rerun with environment variable ${SOCKET_CLI_ACCEPT_RISKS}=1.`}
2265
2285
  `)
2266
2286
  } else if (!options['silent']) {
@@ -2304,9 +2324,7 @@ exports.RangeStyles = RangeStyles
2304
2324
  exports.SAFE_ARBORIST_REIFY_OPTIONS_OVERRIDES =
2305
2325
  SAFE_ARBORIST_REIFY_OPTIONS_OVERRIDES
2306
2326
  exports.SafeArborist = SafeArborist
2307
- exports.addArtifactToAlertsMap = addArtifactToAlertsMap
2308
2327
  exports.applyRange = applyRange
2309
- exports.assignDefaultFixOptions = assignDefaultFixOptions
2310
2328
  exports.captureException = captureException
2311
2329
  exports.findBestPatchVersion = findBestPatchVersion
2312
2330
  exports.findPackageNode = findPackageNode
@@ -2314,6 +2332,8 @@ exports.findPackageNodes = findPackageNodes
2314
2332
  exports.findUp = findUp
2315
2333
  exports.formatSeverityCount = formatSeverityCount
2316
2334
  exports.getAlertsMapFromArborist = getAlertsMapFromArborist
2335
+ exports.getAlertsMapFromPnpmLockfile = getAlertsMapFromPnpmLockfile
2336
+ exports.getAlertsMapFromPurls = getAlertsMapFromPurls
2317
2337
  exports.getConfigValue = getConfigValue
2318
2338
  exports.getCveInfoByAlertsMap = getCveInfoByAlertsMap
2319
2339
  exports.getDefaultToken = getDefaultToken
@@ -2333,5 +2353,5 @@ exports.supportedConfigKeys = supportedConfigKeys
2333
2353
  exports.updateConfigValue = updateConfigValue
2334
2354
  exports.updateNode = updateNode
2335
2355
  exports.updatePackageJsonFromNode = updatePackageJsonFromNode
2336
- //# debugId=037d646c-91c7-4b51-9605-c4d741b25f6
2356
+ //# debugId=a27fccc9-01d0-4c29-9aa2-77fb60ed46dc
2337
2357
  //# sourceMappingURL=shadow-npm-inject.js.map