@socketsecurity/cli-with-sentry 0.14.153 → 0.14.155

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.
Files changed (107) hide show
  1. package/dist/.config/tsconfig.dts.tsbuildinfo +1 -1
  2. package/dist/cli.js +1398 -2502
  3. package/dist/cli.js.map +1 -1
  4. package/dist/constants.js +7 -6
  5. package/dist/constants.js.map +1 -1
  6. package/dist/instrument-with-sentry.js +10 -3
  7. package/dist/instrument-with-sentry.js.map +1 -1
  8. package/dist/shadow-bin.js +5 -7
  9. package/dist/shadow-bin.js.map +1 -1
  10. package/dist/shadow-npm-inject.js +130 -1646
  11. package/dist/shadow-npm-inject.js.map +1 -1
  12. package/dist/types/commands/analytics/cmd-analytics.d.mts.map +1 -1
  13. package/dist/types/commands/analytics/fetch-org-analytics.d.mts.map +1 -1
  14. package/dist/types/commands/analytics/fetch-repo-analytics.d.mts.map +1 -1
  15. package/dist/types/commands/analytics/handle-analytics.d.mts.map +1 -1
  16. package/dist/types/commands/analytics/output-analytics.d.mts +15 -16
  17. package/dist/types/commands/analytics/output-analytics.d.mts.map +1 -1
  18. package/dist/types/commands/audit-log/fetch-audit-log.d.mts.map +1 -1
  19. package/dist/types/commands/cdxgen/cmd-cdxgen.d.mts.map +1 -1
  20. package/dist/types/commands/ci/fetch-default-org-slug.d.mts.map +1 -1
  21. package/dist/types/commands/dependencies/fetch-dependencies.d.mts.map +1 -1
  22. package/dist/types/commands/diff-scan/fetch-diff-scan.d.mts.map +1 -1
  23. package/dist/types/commands/fix/git.d.mts +9 -1
  24. package/dist/types/commands/fix/git.d.mts.map +1 -1
  25. package/dist/types/commands/fix/npm-fix.d.mts.map +1 -1
  26. package/dist/types/commands/fix/open-pr.d.mts +30 -16
  27. package/dist/types/commands/fix/open-pr.d.mts.map +1 -1
  28. package/dist/types/commands/fix/pnpm-fix.d.mts.map +1 -1
  29. package/dist/types/commands/info/fetch-package-info.d.mts.map +1 -1
  30. package/dist/types/commands/login/attempt-login.d.mts.map +1 -1
  31. package/dist/types/commands/npm/wrap-npm.d.mts.map +1 -1
  32. package/dist/types/commands/npx/wrap-npx.d.mts.map +1 -1
  33. package/dist/types/commands/optimize/deps-includes-by-agent.d.mts +1 -1
  34. package/dist/types/commands/optimize/get-overrides-by-agent.d.mts +1 -1
  35. package/dist/types/commands/optimize/lockfile-includes-by-agent.d.mts +1 -1
  36. package/dist/types/commands/optimize/ls-by-agent.d.mts +1 -1
  37. package/dist/types/commands/optimize/update-manifest-by-agent.d.mts +1 -1
  38. package/dist/types/commands/organization/fetch-license-policy.d.mts.map +1 -1
  39. package/dist/types/commands/organization/fetch-organization-list.d.mts.map +1 -1
  40. package/dist/types/commands/organization/fetch-quota.d.mts.map +1 -1
  41. package/dist/types/commands/organization/fetch-security-policy.d.mts.map +1 -1
  42. package/dist/types/commands/package/fetch-purl-deep-score.d.mts.map +1 -1
  43. package/dist/types/commands/package/fetch-purls-shallow-score.d.mts.map +1 -1
  44. package/dist/types/commands/repos/cmd-repos-create.d.mts.map +1 -1
  45. package/dist/types/commands/repos/cmd-repos-del.d.mts.map +1 -1
  46. package/dist/types/commands/repos/cmd-repos-update.d.mts.map +1 -1
  47. package/dist/types/commands/repos/fetch-create-repo.d.mts.map +1 -1
  48. package/dist/types/commands/repos/fetch-delete-repo.d.mts.map +1 -1
  49. package/dist/types/commands/repos/fetch-list-repos.d.mts.map +1 -1
  50. package/dist/types/commands/repos/fetch-update-repo.d.mts.map +1 -1
  51. package/dist/types/commands/repos/fetch-view-repo.d.mts.map +1 -1
  52. package/dist/types/commands/repos/handle-create-repo.d.mts.map +1 -1
  53. package/dist/types/commands/repos/output-create-repo.d.mts +2 -1
  54. package/dist/types/commands/repos/output-create-repo.d.mts.map +1 -1
  55. package/dist/types/commands/repos/output-delete-repo.d.mts +1 -0
  56. package/dist/types/commands/repos/output-delete-repo.d.mts.map +1 -1
  57. package/dist/types/commands/repos/output-update-repo.d.mts +1 -0
  58. package/dist/types/commands/repos/output-update-repo.d.mts.map +1 -1
  59. package/dist/types/commands/scan/fetch-create-org-full-scan.d.mts.map +1 -1
  60. package/dist/types/commands/scan/fetch-delete-org-full-scan.d.mts.map +1 -1
  61. package/dist/types/commands/scan/fetch-diff-scan.d.mts.map +1 -1
  62. package/dist/types/commands/scan/fetch-list-scans.d.mts.map +1 -1
  63. package/dist/types/commands/scan/fetch-report-data.d.mts.map +1 -1
  64. package/dist/types/commands/scan/fetch-scan-metadata.d.mts.map +1 -1
  65. package/dist/types/commands/scan/fetch-supported-scan-file-names.d.mts.map +1 -1
  66. package/dist/types/commands/scan/generate-report.d.mts +7 -1
  67. package/dist/types/commands/scan/generate-report.d.mts.map +1 -1
  68. package/dist/types/commands/scan/output-scan-report.d.mts.map +1 -1
  69. package/dist/types/commands/scan/stream-scan.d.mts +1 -1
  70. package/dist/types/commands/scan/stream-scan.d.mts.map +1 -1
  71. package/dist/types/commands/scan/suggest-org-slug.d.mts.map +1 -1
  72. package/dist/types/commands/threat-feed/output-threat-feed.d.mts.map +1 -1
  73. package/dist/types/constants.d.mts +1 -1
  74. package/dist/types/constants.d.mts.map +1 -1
  75. package/dist/types/shadow/npm/arborist/lib/dep-valid.d.mts +2 -2
  76. package/dist/types/shadow/npm/arborist/lib/dep-valid.d.mts.map +1 -1
  77. package/dist/types/{utils → shadow/npm}/arborist-helpers.d.mts +19 -3
  78. package/dist/types/shadow/npm/arborist-helpers.d.mts.map +1 -0
  79. package/dist/types/{utils/npm.d.mts → shadow/npm/install.d.mts} +2 -2
  80. package/dist/types/shadow/npm/install.d.mts.map +1 -0
  81. package/dist/types/shadow/npm/paths.d.mts +0 -6
  82. package/dist/types/shadow/npm/paths.d.mts.map +1 -1
  83. package/dist/types/utils/agent.d.mts +2 -2
  84. package/dist/types/utils/agent.d.mts.map +1 -1
  85. package/dist/types/utils/alerts-map.d.mts +0 -11
  86. package/dist/types/utils/alerts-map.d.mts.map +1 -1
  87. package/dist/types/utils/api.d.mts +15 -5
  88. package/dist/types/utils/api.d.mts.map +1 -1
  89. package/dist/types/utils/npm-paths.d.mts +7 -0
  90. package/dist/types/utils/npm-paths.d.mts.map +1 -0
  91. package/dist/types/utils/pnpm.d.mts +2 -1
  92. package/dist/types/utils/pnpm.d.mts.map +1 -1
  93. package/dist/types/utils/translations.d.mts.map +1 -1
  94. package/dist/utils.js +3169 -0
  95. package/dist/utils.js.map +1 -0
  96. package/dist/vendor.js +1284 -1231
  97. package/dist/vendor.js.map +1 -1
  98. package/external/@socketsecurity/registry/external/browserslist.js +382 -366
  99. package/external/@socketsecurity/registry/external/browserslist.js.map +1 -1
  100. package/external/@socketsecurity/registry/lib/constants/maintained-node-versions.js +7 -8
  101. package/external/@socketsecurity/registry/lib/fs.d.ts +6 -4
  102. package/external/@socketsecurity/registry/package.json +5 -5
  103. package/package.json +19 -19
  104. package/dist/shadow-npm-paths.js +0 -291
  105. package/dist/shadow-npm-paths.js.map +0 -1
  106. package/dist/types/utils/arborist-helpers.d.mts.map +0 -1
  107. package/dist/types/utils/npm.d.mts.map +0 -1
@@ -1,777 +1,96 @@
1
1
  'use strict'
2
2
 
3
3
  const Module = require('node:module')
4
- const shadowNpmPaths = require('./shadow-npm-paths.js')
5
- const logger = require('../external/@socketsecurity/registry/lib/logger')
4
+ const path = require('node:path')
5
+ const path$1 = require('../external/@socketsecurity/registry/lib/path')
6
6
  const constants = require('./constants.js')
7
- const arrays = require('../external/@socketsecurity/registry/lib/arrays')
7
+ const utils = require('./utils.js')
8
+ const logger = require('../external/@socketsecurity/registry/lib/logger')
8
9
  const vendor = require('./vendor.js')
9
10
  const registry = require('../external/@socketsecurity/registry')
10
11
  const objects = require('../external/@socketsecurity/registry/lib/objects')
11
- const debug = require('../external/@socketsecurity/registry/lib/debug')
12
- const packages = require('../external/@socketsecurity/registry/lib/packages')
13
- const prompts = require('../external/@socketsecurity/registry/lib/prompts')
14
- const strings = require('../external/@socketsecurity/registry/lib/strings')
15
- const fs = require('node:fs')
16
- const os = require('node:os')
17
- const path = require('node:path')
18
- const fs$1 = require('../external/@socketsecurity/registry/lib/fs')
19
- const promises = require('node:timers/promises')
20
- const sorts = require('../external/@socketsecurity/registry/lib/sorts')
21
12
 
22
13
  const _documentCurrentScript =
23
14
  typeof document !== 'undefined' ? document.currentScript : null
24
- const { NPM: NPM$3, PNPM } = constants
25
- const PNPM_WORKSPACE = `${PNPM}-workspace`
26
- const ignoredDirs = [
27
- // Taken from ignore-by-default:
28
- // https://github.com/novemberborn/ignore-by-default/blob/v2.1.0/index.js
29
- '.git',
30
- // Git repository files, see <https://git-scm.com/>
31
- '.log',
32
- // Log files emitted by tools such as `tsserver`, see <https://github.com/Microsoft/TypeScript/wiki/Standalone-Server-%28tsserver%29>
33
- '.nyc_output',
34
- // Temporary directory where nyc stores coverage data, see <https://github.com/bcoe/nyc>
35
- '.sass-cache',
36
- // Cache folder for node-sass, see <https://github.com/sass/node-sass>
37
- '.yarn',
38
- // Where node modules are installed when using Yarn, see <https://yarnpkg.com/>
39
- 'bower_components',
40
- // Where Bower packages are installed, see <http://bower.io/>
41
- 'coverage',
42
- // Standard output directory for code coverage reports, see <https://github.com/gotwarlost/istanbul>
43
- 'node_modules',
44
- // Where Node modules are installed, see <https://nodejs.org/>
45
- // Taken from globby:
46
- // https://github.com/sindresorhus/globby/blob/v14.0.2/ignore.js#L11-L16
47
- 'flow-typed'
48
- ]
49
- const ignoredDirPatterns = ignoredDirs.map(i => `**/${i}`)
50
- async function getWorkspaceGlobs(agent, cwd = process.cwd()) {
51
- let workspacePatterns
52
- if (agent === PNPM) {
53
- for (const workspacePath of [
54
- path.join(cwd, `${PNPM_WORKSPACE}.yaml`),
55
- path.join(cwd, `${PNPM_WORKSPACE}.yml`)
56
- ]) {
57
- // eslint-disable-next-line no-await-in-loop
58
- const yml = await safeReadFile(workspacePath)
59
- if (yml) {
60
- try {
61
- workspacePatterns = vendor.distExports$1.parse(yml)?.packages
62
- } catch {}
63
- if (workspacePatterns) {
64
- break
65
- }
66
- }
67
- }
68
- } else {
69
- workspacePatterns = (
70
- await packages.readPackageJson(cwd, {
71
- throws: false
72
- })
73
- )?.['workspaces']
74
- }
75
- return Array.isArray(workspacePatterns)
76
- ? workspacePatterns
77
- .filter(strings.isNonEmptyString)
78
- .map(workspacePatternToGlobPattern)
79
- : []
80
- }
81
- function ignoreFileLinesToGlobPatterns(lines, filepath, cwd) {
82
- const base = path.relative(cwd, path.dirname(filepath)).replace(/\\/g, '/')
83
- const patterns = []
84
- for (let i = 0, { length } = lines; i < length; i += 1) {
85
- const pattern = lines[i].trim()
86
- if (pattern.length > 0 && pattern.charCodeAt(0) !== 35 /*'#'*/) {
87
- patterns.push(
88
- ignorePatternToMinimatch(
89
- pattern.length && pattern.charCodeAt(0) === 33 /*'!'*/
90
- ? `!${path.posix.join(base, pattern.slice(1))}`
91
- : path.posix.join(base, pattern)
92
- )
93
- )
94
- }
95
- }
96
- return patterns
97
- }
98
- function ignoreFileToGlobPatterns(content, filepath, cwd) {
99
- return ignoreFileLinesToGlobPatterns(content.split(/\r?\n/), filepath, cwd)
100
- }
15
+ const DiffAction = utils.createEnum({
16
+ add: 'ADD',
17
+ change: 'CHANGE',
18
+ remove: 'REMOVE'
19
+ })
101
20
 
102
- // Based on `@eslint/compat` convertIgnorePatternToMinimatch.
103
- // Apache v2.0 licensed
104
- // Copyright Nicholas C. Zakas
105
- // https://github.com/eslint/rewrite/blob/compat-v1.2.1/packages/compat/src/ignore-file.js#L28
106
- function ignorePatternToMinimatch(pattern) {
107
- const isNegated = pattern.startsWith('!')
108
- const negatedPrefix = isNegated ? '!' : ''
109
- const patternToTest = (isNegated ? pattern.slice(1) : pattern).trimEnd()
110
- // Special cases.
111
- if (
112
- patternToTest === '' ||
113
- patternToTest === '**' ||
114
- patternToTest === '/**' ||
115
- patternToTest === '**'
116
- ) {
117
- return `${negatedPrefix}${patternToTest}`
118
- }
119
- const firstIndexOfSlash = patternToTest.indexOf('/')
120
- const matchEverywherePrefix =
121
- firstIndexOfSlash === -1 || firstIndexOfSlash === patternToTest.length - 1
122
- ? '**/'
123
- : ''
124
- const patternWithoutLeadingSlash =
125
- firstIndexOfSlash === 0 ? patternToTest.slice(1) : patternToTest
126
- // Escape `{` and `(` because in gitignore patterns they are just
127
- // literal characters without any specific syntactic meaning,
128
- // while in minimatch patterns they can form brace expansion or extglob syntax.
129
- //
130
- // For example, gitignore pattern `src/{a,b}.js` ignores file `src/{a,b}.js`.
131
- // But, the same minimatch pattern `src/{a,b}.js` ignores files `src/a.js` and `src/b.js`.
132
- // Minimatch pattern `src/\{a,b}.js` is equivalent to gitignore pattern `src/{a,b}.js`.
133
- const escapedPatternWithoutLeadingSlash =
134
- patternWithoutLeadingSlash.replaceAll(
135
- /(?=((?:\\.|[^{(])*))\1([{(])/guy,
136
- '$1\\$2'
21
+ let _arboristPkgPath
22
+ function getArboristPackagePath() {
23
+ if (_arboristPkgPath === undefined) {
24
+ const pkgName = '@npmcli/arborist'
25
+ const mainPathWithForwardSlashes = path$1.normalizePath(
26
+ utils.getNpmRequire().resolve(pkgName)
27
+ )
28
+ const arboristPkgPathWithForwardSlashes = mainPathWithForwardSlashes.slice(
29
+ 0,
30
+ mainPathWithForwardSlashes.lastIndexOf(pkgName) + pkgName.length
137
31
  )
138
- const matchInsideSuffix = patternToTest.endsWith('/**') ? '/*' : ''
139
- return `${negatedPrefix}${matchEverywherePrefix}${escapedPatternWithoutLeadingSlash}${matchInsideSuffix}`
140
- }
141
- function workspacePatternToGlobPattern(workspace) {
142
- const { length } = workspace
143
- if (!length) {
144
- return ''
145
- }
146
- // If the workspace ends with "/"
147
- if (workspace.charCodeAt(length - 1) === 47 /*'/'*/) {
148
- return `${workspace}/*/package.json`
149
- }
150
- // If the workspace ends with "/**"
151
- if (
152
- workspace.charCodeAt(length - 1) === 42 /*'*'*/ &&
153
- workspace.charCodeAt(length - 2) === 42 /*'*'*/ &&
154
- workspace.charCodeAt(length - 3) === 47 /*'/'*/
155
- ) {
156
- return `${workspace}/*/**/package.json`
157
- }
158
- // Things like "packages/a" or "packages/*"
159
- return `${workspace}/package.json`
160
- }
161
- async function filterGlobResultToSupportedFiles(entries, supportedFiles) {
162
- const patterns = ['golang', NPM$3, 'maven', 'pypi', 'gem', 'nuget'].reduce(
163
- (r, n) => {
164
- const supported = supportedFiles[n]
165
- r.push(
166
- ...(supported
167
- ? Object.values(supported).map(p => `**/${p.pattern}`)
168
- : [])
169
- )
170
- return r
171
- },
172
- []
173
- )
174
- return entries.filter(p => vendor.micromatchExports.some(p, patterns))
175
- }
176
- async function globWithGitIgnore(patterns, options) {
177
- const {
178
- cwd = process.cwd(),
179
- socketConfig,
180
- ...additionalOptions
181
- } = {
182
- __proto__: null,
183
- ...options
184
- }
185
- const projectIgnorePaths = socketConfig?.projectIgnorePaths
186
- const ignoreFiles = await vendor.distExports.glob(['**/.gitignore'], {
187
- absolute: true,
188
- cwd,
189
- expandDirectories: true
190
- })
191
- const ignores = [
192
- ...ignoredDirPatterns,
193
- ...(Array.isArray(projectIgnorePaths)
194
- ? ignoreFileLinesToGlobPatterns(
195
- projectIgnorePaths,
196
- path.join(cwd, '.gitignore'),
197
- cwd
198
- )
199
- : []),
200
- ...(
201
- await Promise.all(
202
- ignoreFiles.map(async filepath =>
203
- ignoreFileToGlobPatterns(
204
- await fs.promises.readFile(filepath, 'utf8'),
205
- filepath,
206
- cwd
207
- )
208
- )
209
- )
210
- ).flat()
211
- ]
212
- const hasNegatedPattern = ignores.some(p => p.charCodeAt(0) === 33 /*'!'*/)
213
- const globOptions = {
214
- absolute: true,
215
- cwd,
216
- expandDirectories: false,
217
- ignore: hasNegatedPattern ? [] : ignores,
218
- ...additionalOptions
219
- }
220
- const result = await vendor.distExports.glob(patterns, globOptions)
221
- if (!hasNegatedPattern) {
222
- return result
223
- }
224
- const { absolute } = globOptions
225
-
226
- // Note: the input files must be INSIDE the cwd. If you get strange looking
227
- // relative path errors here, most likely your path is outside the given cwd.
228
- const filtered = vendor
229
- .ignoreExports()
230
- .add(ignores)
231
- .filter(absolute ? result.map(p => path.relative(cwd, p)) : result)
232
- return absolute ? filtered.map(p => path.resolve(cwd, p)) : filtered
233
- }
234
- async function globNodeModules(cwd = process.cwd()) {
235
- return await vendor.distExports.glob('**/node_modules/**', {
236
- absolute: true,
237
- cwd
238
- })
239
- }
240
- async function globWorkspace(agent, cwd = process.cwd()) {
241
- const workspaceGlobs = await getWorkspaceGlobs(agent, cwd)
242
- return workspaceGlobs.length
243
- ? await vendor.distExports.glob(workspaceGlobs, {
244
- absolute: true,
245
- cwd,
246
- ignore: ['**/node_modules/**', '**/bower_components/**']
247
- })
248
- : []
249
- }
250
- function pathsToGlobPatterns(paths) {
251
- // TODO: Does not support `~/` paths.
252
- return paths.map(p => (p === '.' || p === './' ? '**/*' : p))
253
- }
254
-
255
- const { abortSignal } = constants
256
- async function removeNodeModules(cwd = process.cwd()) {
257
- const nodeModulesPaths = await globNodeModules(cwd)
258
- await Promise.all(nodeModulesPaths.map(p => fs$1.remove(p)))
259
- }
260
- async function findUp(name, { cwd = process.cwd(), signal = abortSignal }) {
261
- let dir = path.resolve(cwd)
262
- const { root } = path.parse(dir)
263
- const names = [name].flat()
264
- while (dir && dir !== root) {
265
- for (const name of names) {
266
- if (signal?.aborted) {
267
- return undefined
268
- }
269
- const filePath = path.join(dir, name)
270
- try {
271
- // eslint-disable-next-line no-await-in-loop
272
- const stats = await fs.promises.stat(filePath)
273
- if (stats.isFile()) {
274
- return filePath
275
- }
276
- } catch {}
277
- }
278
- dir = path.dirname(dir)
279
- }
280
- return undefined
281
- }
282
- async function readFileBinary(filepath, options) {
283
- return await fs.promises.readFile(filepath, {
284
- signal: abortSignal,
285
- ...options,
286
- encoding: 'binary'
287
- })
288
- }
289
- async function readFileUtf8(filepath, options) {
290
- return await fs.promises.readFile(filepath, {
291
- signal: abortSignal,
292
- ...options,
293
- encoding: 'utf8'
294
- })
295
- }
296
- async function safeReadFile(filepath, options) {
297
- try {
298
- return await fs.promises.readFile(filepath, {
299
- encoding: 'utf8',
300
- signal: abortSignal,
301
- ...(typeof options === 'string'
302
- ? {
303
- encoding: options
304
- }
305
- : options)
306
- })
307
- } catch {}
308
- return undefined
309
- }
310
- function safeReadFileSync(filepath, options) {
311
- try {
312
- return fs.readFileSync(filepath, {
313
- encoding: 'utf8',
314
- ...(typeof options === 'string'
315
- ? {
316
- encoding: options
317
- }
318
- : options)
319
- })
320
- } catch {}
321
- return undefined
322
- }
323
-
324
- const { LOCALAPPDATA, SOCKET_APP_DIR } = constants
325
- const supportedConfigKeys = new Map([
326
- ['apiBaseUrl', 'Base URL of the API endpoint'],
327
- ['apiProxy', 'A proxy through which to access the API'],
328
- ['apiToken', 'The API token required to access most API endpoints'],
329
- [
330
- 'defaultOrg',
331
- 'The default org slug to use; usually the org your API token has access to. When set, all orgSlug arguments are implied to be this value.'
332
- ],
333
- [
334
- 'enforcedOrgs',
335
- 'Orgs in this list have their security policies enforced on this machine'
336
- ],
337
- ['isTestingV1', 'For development of testing the next major bump']
338
- ])
339
- const sensitiveConfigKeys = new Set(['apiToken'])
340
- let _cachedConfig
341
- // When using --config or SOCKET_CLI_CONFIG, do not persist the config.
342
- let _readOnlyConfig = false
343
- function overrideCachedConfig(jsonConfig) {
344
- debug.debugLog('Overriding entire config, marking config as read-only')
345
- let config
346
- try {
347
- config = JSON.parse(String(jsonConfig))
348
- if (!config || typeof config !== 'object') {
349
- // `null` is valid json, so are primitive values. They're not valid config objects :)
350
- return {
351
- ok: false,
352
- message: 'Could not parse Config as JSON',
353
- cause:
354
- "Could not JSON parse the config override. Make sure it's a proper JSON object (double-quoted keys and strings, no unquoted `undefined`) and try again."
355
- }
356
- }
357
- } catch {
358
- // Force set an empty config to prevent accidentally using system settings
359
- _cachedConfig = {}
360
- _readOnlyConfig = true
361
- return {
362
- ok: false,
363
- message: 'Could not parse Config as JSON',
364
- cause:
365
- "Could not JSON parse the config override. Make sure it's a proper JSON object (double-quoted keys and strings, no unquoted `undefined`) and try again."
366
- }
367
- }
368
-
369
- // @ts-ignore Override an illegal object.
370
- _cachedConfig = config
371
- _readOnlyConfig = true
372
-
373
- // Normalize apiKey to apiToken.
374
- if (_cachedConfig['apiKey']) {
375
- if (_cachedConfig['apiToken']) {
376
- logger.logger.warn(
377
- 'Note: The config override had both apiToken and apiKey. Using the apiToken value. Remove the apiKey to get rid of this message.'
378
- )
379
- }
380
- _cachedConfig['apiToken'] = _cachedConfig['apiKey']
381
- delete _cachedConfig['apiKey']
382
- }
383
- return {
384
- ok: true,
385
- data: undefined
386
- }
387
- }
388
- function overrideConfigApiToken(apiToken) {
389
- debug.debugLog('Overriding API token, marking config as read-only')
390
- // Set token to the local cached config and mark it read-only so it doesn't persist
391
- _cachedConfig = {
392
- ...vendor.configExports,
393
- ...(apiToken === undefined
394
- ? {}
395
- : {
396
- apiToken: String(apiToken)
397
- })
398
- }
399
- _readOnlyConfig = true
400
- }
401
- function getConfigValues() {
402
- if (_cachedConfig === undefined) {
403
- _cachedConfig = {}
404
- // Order: env var > --config flag > file
405
- const configPath = getConfigPath()
406
- if (configPath) {
407
- const raw = safeReadFileSync(configPath)
408
- if (raw) {
409
- try {
410
- Object.assign(
411
- _cachedConfig,
412
- JSON.parse(Buffer.from(raw, 'base64').toString())
413
- )
414
- } catch {
415
- logger.logger.warn(`Failed to parse config at ${configPath}`)
416
- }
417
- // Normalize apiKey to apiToken and persist it.
418
- // This is a one time migration per user.
419
- if (_cachedConfig['apiKey']) {
420
- const token = _cachedConfig['apiKey']
421
- delete _cachedConfig['apiKey']
422
- updateConfigValue('apiToken', token)
423
- }
424
- } else {
425
- fs.mkdirSync(path.dirname(configPath), {
426
- recursive: true
427
- })
428
- }
429
- }
430
- }
431
- return _cachedConfig
432
- }
433
- let _configPath
434
- let _warnedConfigPathWin32Missing = false
435
- function getConfigPath() {
436
- // Get the OS app data folder:
437
- // - Win: %LOCALAPPDATA% or fail?
438
- // - Mac: %XDG_DATA_HOME% or fallback to "~/Library/Application Support/"
439
- // - Linux: %XDG_DATA_HOME% or fallback to "~/.local/share/"
440
- // Note: LOCALAPPDATA is typically: C:\Users\USERNAME\AppData
441
- // Note: XDG stands for "X Desktop Group", nowadays "freedesktop.org"
442
- // On most systems that path is: $HOME/.local/share
443
- // Then append `socket/settings`, so:
444
- // - Win: %LOCALAPPDATA%\socket\settings or return undefined
445
- // - Mac: %XDG_DATA_HOME%/socket/settings or "~/Library/Application Support/socket/settings"
446
- // - Linux: %XDG_DATA_HOME%/socket/settings or "~/.local/share/socket/settings"
447
-
448
- if (_configPath === undefined) {
449
32
  // Lazily access constants.WIN32.
450
- const { WIN32 } = constants
451
- let dataHome = WIN32
452
- ? // Lazily access constants.ENV.LOCALAPPDATA
453
- constants.ENV.LOCALAPPDATA
454
- : // Lazily access constants.ENV.XDG_DATA_HOME
455
- constants.ENV.XDG_DATA_HOME
456
- if (!dataHome) {
457
- if (WIN32) {
458
- if (!_warnedConfigPathWin32Missing) {
459
- _warnedConfigPathWin32Missing = true
460
- logger.logger.warn(`Missing %${LOCALAPPDATA}%`)
461
- }
462
- } else {
463
- dataHome = path.join(
464
- os.homedir(),
465
- ...(process.platform === 'darwin'
466
- ? ['Library', 'Application Support']
467
- : ['.local', 'share'])
468
- )
469
- }
470
- }
471
- _configPath = dataHome ? path.join(dataHome, SOCKET_APP_DIR) : undefined
472
- }
473
- return _configPath
474
- }
475
- function normalizeConfigKey(key) {
476
- // Note: apiKey was the old name of the token. When we load a config with
477
- // property apiKey, we'll copy that to apiToken and delete the old property.
478
- const normalizedKey = key === 'apiKey' ? 'apiToken' : key
479
- if (!supportedConfigKeys.has(normalizedKey)) {
480
- return {
481
- ok: false,
482
- message: `Invalid config key: ${normalizedKey}`,
483
- data: undefined
484
- }
485
- }
486
- return {
487
- ok: true,
488
- data: key
489
- }
490
- }
491
- function findSocketYmlSync(dir = process.cwd()) {
492
- let prevDir = null
493
- while (dir !== prevDir) {
494
- let ymlPath = path.join(dir, 'socket.yml')
495
- let yml = safeReadFileSync(ymlPath)
496
- if (yml === undefined) {
497
- ymlPath = path.join(dir, 'socket.yaml')
498
- yml = safeReadFileSync(ymlPath)
499
- }
500
- if (typeof yml === 'string') {
501
- try {
502
- return {
503
- path: ymlPath,
504
- parsed: vendor.configExports.parseSocketConfig(yml)
505
- }
506
- } catch {
507
- throw new Error(`Found file but was unable to parse ${ymlPath}`)
508
- }
509
- }
510
- prevDir = dir
511
- dir = path.join(dir, '..')
512
- }
513
- return null
514
- }
515
- function getConfigValue(key) {
516
- const localConfig = getConfigValues()
517
- const keyResult = normalizeConfigKey(key)
518
- if (!keyResult.ok) {
519
- return keyResult
520
- }
521
- return {
522
- ok: true,
523
- data: localConfig[keyResult.data]
524
- }
525
- }
526
- // This version squashes errors, returning undefined instead.
527
- // Should be used when we can reasonably predict the call can't fail.
528
- function getConfigValueOrUndef(key) {
529
- const localConfig = getConfigValues()
530
- const keyResult = normalizeConfigKey(key)
531
- if (!keyResult.ok) {
532
- return undefined
533
- }
534
- return localConfig[keyResult.data]
535
- }
536
- function isReadOnlyConfig() {
537
- return _readOnlyConfig
538
- }
539
- let _pendingSave = false
540
- function updateConfigValue(key, value) {
541
- const localConfig = getConfigValues()
542
- const keyResult = normalizeConfigKey(key)
543
- if (!keyResult.ok) {
544
- return keyResult
545
- }
546
- localConfig[keyResult.data] = value
547
- if (_readOnlyConfig) {
548
- return {
549
- ok: true,
550
- message: `Config key '${key}' was updated`,
551
- data: 'Change applied but not persisted; current config is overridden through env var or flag'
552
- }
553
- }
554
- if (!_pendingSave) {
555
- _pendingSave = true
556
- process.nextTick(() => {
557
- _pendingSave = false
558
- const configPath = getConfigPath()
559
- if (configPath) {
560
- fs.writeFileSync(
561
- configPath,
562
- Buffer.from(JSON.stringify(localConfig)).toString('base64')
563
- )
564
- }
565
- })
566
- }
567
- return {
568
- ok: true,
569
- message: `Config key '${key}' was updated`,
570
- data: undefined
571
- }
572
- }
573
- function isTestingV1() {
574
- return !!getConfigValueOrUndef('isTestingV1')
575
- }
576
-
577
- const {
578
- kInternalsSymbol: kInternalsSymbol$1,
579
- [kInternalsSymbol$1]: { getSentry }
580
- } = constants
581
- class AuthError extends Error {}
582
- class InputError extends Error {
583
- constructor(message, body) {
584
- super(message)
585
- this.body = body
586
- }
587
- }
588
- async function captureException(exception, hint) {
589
- const result = captureExceptionSync(exception, hint)
590
- // "Sleep" for a second, just in case, hopefully enough time to initiate fetch.
591
- await promises.setTimeout(1000)
592
- return result
593
- }
594
- function captureExceptionSync(exception, hint) {
595
- const Sentry = getSentry()
596
- if (!Sentry) {
597
- return ''
598
- }
599
- debug.debugLog('captureException: Sending exception to Sentry')
600
- return Sentry.captureException(exception, hint)
601
- }
602
-
603
- const { SOCKET_PUBLIC_API_TOKEN } = constants
604
-
605
- // The API server that should be used for operations.
606
- function getDefaultApiBaseUrl() {
607
- const baseUrl =
608
- // Lazily access constants.ENV.SOCKET_SECURITY_API_BASE_URL.
609
- constants.ENV.SOCKET_SECURITY_API_BASE_URL ||
610
- getConfigValueOrUndef('apiBaseUrl')
611
- return strings.isNonEmptyString(baseUrl) ? baseUrl : undefined
612
- }
613
-
614
- // The API server that should be used for operations.
615
- function getDefaultHttpProxy() {
616
- const apiProxy =
617
- // Lazily access constants.ENV.SOCKET_SECURITY_API_PROXY.
618
- constants.ENV.SOCKET_SECURITY_API_PROXY || getConfigValueOrUndef('apiProxy')
619
- return strings.isNonEmptyString(apiProxy) ? apiProxy : undefined
620
- }
621
-
622
- // This API key should be stored globally for the duration of the CLI execution.
623
- let _defaultToken
624
- function getDefaultToken() {
625
- // Lazily access constants.ENV.SOCKET_CLI_NO_API_TOKEN.
626
- if (constants.ENV.SOCKET_CLI_NO_API_TOKEN) {
627
- _defaultToken = undefined
628
- } else {
629
- const key =
630
- // Lazily access constants.ENV.SOCKET_SECURITY_API_TOKEN.
631
- constants.ENV.SOCKET_SECURITY_API_TOKEN ||
632
- getConfigValueOrUndef('apiToken') ||
633
- _defaultToken
634
- _defaultToken = strings.isNonEmptyString(key) ? key : undefined
33
+ _arboristPkgPath = constants.WIN32
34
+ ? path.normalize(arboristPkgPathWithForwardSlashes)
35
+ : arboristPkgPathWithForwardSlashes
36
+ }
37
+ return _arboristPkgPath
38
+ }
39
+ let _arboristClassPath
40
+ function getArboristClassPath() {
41
+ if (_arboristClassPath === undefined) {
42
+ _arboristClassPath = path.join(
43
+ getArboristPackagePath(),
44
+ 'lib/arborist/index.js'
45
+ )
635
46
  }
636
- return _defaultToken
47
+ return _arboristClassPath
637
48
  }
638
- function getPublicToken() {
639
- return (
640
- // Lazily access constants.ENV.SOCKET_SECURITY_API_TOKEN.
641
- (constants.ENV.SOCKET_SECURITY_API_TOKEN || getDefaultToken()) ??
642
- SOCKET_PUBLIC_API_TOKEN
643
- )
644
- }
645
- async function setupSdk(
646
- apiToken = getDefaultToken(),
647
- apiBaseUrl = getDefaultApiBaseUrl(),
648
- proxy = getDefaultHttpProxy()
649
- ) {
650
- if (typeof apiToken !== 'string' && vendor.isInteractiveExports()) {
651
- apiToken = await prompts.password({
652
- message:
653
- 'Enter your Socket.dev API key (not saved, use socket login to persist)'
654
- })
655
- _defaultToken = apiToken
656
- }
657
- if (!apiToken) {
658
- // TODO: eliminate this throw in favor of CResult (or anything else)
659
- throw new AuthError('You need to provide an API key')
49
+ let _arboristDepValidPath
50
+ function getArboristDepValidPath() {
51
+ if (_arboristDepValidPath === undefined) {
52
+ _arboristDepValidPath = path.join(
53
+ getArboristPackagePath(),
54
+ 'lib/dep-valid.js'
55
+ )
660
56
  }
661
- return new vendor.distExports$2.SocketSdk(apiToken, {
662
- agent: proxy
663
- ? new vendor.HttpsProxyAgent({
664
- proxy
665
- })
666
- : undefined,
667
- baseUrl: apiBaseUrl,
668
- userAgent: vendor.distExports$2.createUserAgentFromPkgJson({
669
- // Lazily access constants.ENV.INLINED_SOCKET_CLI_NAME.
670
- name: constants.ENV.INLINED_SOCKET_CLI_NAME,
671
- // Lazily access constants.ENV.INLINED_SOCKET_CLI_VERSION.
672
- version: constants.ENV.INLINED_SOCKET_CLI_VERSION,
673
- // Lazily access constants.ENV.INLINED_SOCKET_CLI_HOMEPAGE.
674
- homepage: constants.ENV.INLINED_SOCKET_CLI_HOMEPAGE
675
- })
676
- })
57
+ return _arboristDepValidPath
677
58
  }
678
-
679
- const RangeStyles = ['caret', 'gt', 'lt', 'pin', 'preserve', 'tilde']
680
- function applyRange(refRange, version, style = 'preserve') {
681
- switch (style) {
682
- case 'caret':
683
- return `^${version}`
684
- case 'gt':
685
- return `>${version}`
686
- case 'gte':
687
- return `>=${version}`
688
- case 'lt':
689
- return `<${version}`
690
- case 'lte':
691
- return `<=${version}`
692
- case 'preserve': {
693
- const range = new vendor.semverExports.Range(refRange)
694
- const { raw } = range
695
- const comparators = [...range.set].flat()
696
- const { length } = comparators
697
- if (length === 1) {
698
- const char = /^[<>]=?/.exec(raw)?.[0]
699
- if (char) {
700
- return `${char}${version}`
701
- }
702
- } else if (length === 2) {
703
- const char = /^[~^]/.exec(raw)?.[0]
704
- if (char) {
705
- return `${char}${version}`
706
- }
707
- }
708
- return version
709
- }
710
- case 'tilde':
711
- return `~${version}`
712
- case 'pin':
713
- default:
714
- return version
59
+ let _arboristEdgeClassPath
60
+ function getArboristEdgeClassPath() {
61
+ if (_arboristEdgeClassPath === undefined) {
62
+ _arboristEdgeClassPath = path.join(getArboristPackagePath(), 'lib/edge.js')
715
63
  }
64
+ return _arboristEdgeClassPath
716
65
  }
717
- function getMajor(version) {
718
- const coerced = vendor.semverExports.coerce(version)
719
- if (coerced) {
720
- try {
721
- return vendor.semverExports.major(coerced)
722
- } catch (e) {
723
- debug.debugLog(`Error parsing '${version}':\n`, e)
724
- }
66
+ let _arboristNodeClassPath
67
+ function getArboristNodeClassPath() {
68
+ if (_arboristNodeClassPath === undefined) {
69
+ _arboristNodeClassPath = path.join(getArboristPackagePath(), 'lib/node.js')
725
70
  }
726
- return null
727
- }
728
-
729
- function idToPurl(id) {
730
- return `pkg:npm/${id}`
731
- }
732
- function resolvePackageVersion(purlObj) {
733
- const { version } = purlObj
734
- return version
735
- ? (vendor.semverExports.coerce(stripPeerSuffix(version))?.version ?? '')
736
- : ''
737
- }
738
- function stripLeadingSlash(path) {
739
- return path.startsWith('/') ? path.slice(1) : path
740
- }
741
- function stripPeerSuffix(depPath) {
742
- const idx = depPath.indexOf('(')
743
- return idx === -1 ? depPath : depPath.slice(0, idx)
744
- }
745
-
746
- function createEnum(obj) {
747
- return Object.freeze({
748
- __proto__: null,
749
- ...obj
750
- })
71
+ return _arboristNodeClassPath
751
72
  }
752
- function pick(input, keys) {
753
- const result = {}
754
- for (const key of keys) {
755
- result[key] = input[key]
73
+ let _arboristOverrideSetClassPath
74
+ function getArboristOverrideSetClassPath() {
75
+ if (_arboristOverrideSetClassPath === undefined) {
76
+ _arboristOverrideSetClassPath = path.join(
77
+ getArboristPackagePath(),
78
+ 'lib/override-set.js'
79
+ )
756
80
  }
757
- return result
81
+ return _arboristOverrideSetClassPath
758
82
  }
759
83
 
760
- const DiffAction = createEnum({
761
- add: 'ADD',
762
- change: 'CHANGE',
763
- remove: 'REMOVE'
764
- })
765
-
766
84
  const require$6 = Module.createRequire(
767
- typeof document === 'undefined'
768
- ? require('u' + 'rl').pathToFileURL(__filename).href
769
- : (_documentCurrentScript &&
770
- _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' &&
771
- _documentCurrentScript.src) ||
772
- new URL('shadow-npm-inject.js', document.baseURI).href
85
+ require('u' + 'rl').pathToFileURL(__filename).href
773
86
  )
774
- const depValid = require$6(shadowNpmPaths.getArboristDepValidPath())
87
+ let _depValid
88
+ function depValid(child, requested, accept, requester) {
89
+ if (_depValid === undefined) {
90
+ _depValid = require$6(getArboristDepValidPath())
91
+ }
92
+ return _depValid(child, requested, accept, requester)
93
+ }
775
94
 
776
95
  const { UNDEFINED_TOKEN } = constants
777
96
  function tryRequire(req, ...ids) {
@@ -800,7 +119,7 @@ let _log = UNDEFINED_TOKEN
800
119
  function getLogger() {
801
120
  if (_log === UNDEFINED_TOKEN) {
802
121
  _log = tryRequire(
803
- shadowNpmPaths.getNpmRequire(),
122
+ utils.getNpmRequire(),
804
123
  [
805
124
  'proc-log/lib/index.js',
806
125
  // The proc-log DefinitelyTyped definition is incorrect. The type definition
@@ -814,14 +133,9 @@ function getLogger() {
814
133
  }
815
134
 
816
135
  const require$5 = Module.createRequire(
817
- typeof document === 'undefined'
818
- ? require('u' + 'rl').pathToFileURL(__filename).href
819
- : (_documentCurrentScript &&
820
- _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' &&
821
- _documentCurrentScript.src) ||
822
- new URL('shadow-npm-inject.js', document.baseURI).href
136
+ require('u' + 'rl').pathToFileURL(__filename).href
823
137
  )
824
- const OverrideSet = require$5(shadowNpmPaths.getArboristOverrideSetClassPath())
138
+ const OverrideSet = require$5(getArboristOverrideSetClassPath())
825
139
 
826
140
  // Implementation code not related to patch https://github.com/npm/cli/pull/8089
827
141
  // is based on https://github.com/npm/cli/blob/v11.0.0/workspaces/arborist/lib/override-set.js:
@@ -951,14 +265,9 @@ class SafeOverrideSet extends OverrideSet {
951
265
  }
952
266
 
953
267
  const require$4 = Module.createRequire(
954
- typeof document === 'undefined'
955
- ? require('u' + 'rl').pathToFileURL(__filename).href
956
- : (_documentCurrentScript &&
957
- _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' &&
958
- _documentCurrentScript.src) ||
959
- new URL('shadow-npm-inject.js', document.baseURI).href
268
+ require('u' + 'rl').pathToFileURL(__filename).href
960
269
  )
961
- const Node = require$4(shadowNpmPaths.getArboristNodeClassPath())
270
+ const Node = require$4(getArboristNodeClassPath())
962
271
 
963
272
  // Implementation code not related to patch https://github.com/npm/cli/pull/8089
964
273
  // is based on https://github.com/npm/cli/blob/v11.0.0/workspaces/arborist/lib/node.js:
@@ -1266,14 +575,9 @@ class SafeNode extends Node {
1266
575
  }
1267
576
 
1268
577
  const require$3 = Module.createRequire(
1269
- typeof document === 'undefined'
1270
- ? require('u' + 'rl').pathToFileURL(__filename).href
1271
- : (_documentCurrentScript &&
1272
- _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' &&
1273
- _documentCurrentScript.src) ||
1274
- new URL('shadow-npm-inject.js', document.baseURI).href
578
+ require('u' + 'rl').pathToFileURL(__filename).href
1275
579
  )
1276
- const Edge = require$3(shadowNpmPaths.getArboristEdgeClassPath())
580
+ const Edge = require$3(getArboristEdgeClassPath())
1277
581
 
1278
582
  // The Edge class makes heavy use of private properties which subclasses do NOT
1279
583
  // have access to. So we have to recreate any functionality that relies on those
@@ -1533,7 +837,7 @@ class SafeEdge extends Edge {
1533
837
  }
1534
838
  }
1535
839
 
1536
- const { LOOP_SENTINEL, NPM: NPM$2, NPM_REGISTRY_URL } = constants
840
+ const { LOOP_SENTINEL, NPM: NPM$1, NPM_REGISTRY_URL } = constants
1537
841
  function getUrlOrigin(input) {
1538
842
  try {
1539
843
  // TODO: URL.parse is available in Node 22.1.0. We can use it when we drop Node 18.
@@ -1549,16 +853,18 @@ function findBestPatchVersion(
1549
853
  vulnerableVersionRange,
1550
854
  _firstPatchedVersionIdentifier
1551
855
  ) {
1552
- const manifestData = registry.getManifestData(NPM$2, node.name)
856
+ const manifestData = registry.getManifestData(NPM$1, node.name)
1553
857
  let eligibleVersions
1554
858
  if (manifestData && manifestData.name === manifestData.package) {
1555
- const major = getMajor(manifestData.version)
859
+ const major = utils.getMajor(manifestData.version)
1556
860
  if (typeof major !== 'number') {
1557
861
  return null
1558
862
  }
1559
- eligibleVersions = availableVersions.filter(v => getMajor(v) === major)
863
+ eligibleVersions = availableVersions.filter(
864
+ v => utils.getMajor(v) === major
865
+ )
1560
866
  } else {
1561
- const major = getMajor(node.version)
867
+ const major = utils.getMajor(node.version)
1562
868
  if (typeof major !== 'number') {
1563
869
  return null
1564
870
  }
@@ -1566,7 +872,7 @@ function findBestPatchVersion(
1566
872
  v =>
1567
873
  // Filter for versions that are within the current major version and
1568
874
  // are NOT in the vulnerable range.
1569
- getMajor(v) === major &&
875
+ utils.getMajor(v) === major &&
1570
876
  (!vulnerableVersionRange ||
1571
877
  !vendor.semverExports.satisfies(v, vulnerableVersionRange))
1572
878
  )
@@ -1613,6 +919,43 @@ function findPackageNodes(tree, name, version) {
1613
919
  }
1614
920
  return matches
1615
921
  }
922
+ async function getAlertsMapFromArborist(arb, options_) {
923
+ const options = {
924
+ __proto__: null,
925
+ consolidate: false,
926
+ limit: Infinity,
927
+ nothrow: false,
928
+ ...options_
929
+ }
930
+ const include = {
931
+ __proto__: null,
932
+ existing: false,
933
+ ...options.include
934
+ }
935
+ const needInfoOn = getDetailsFromDiff(arb.diff, {
936
+ include: {
937
+ unchanged: include.existing
938
+ }
939
+ })
940
+ const purls = needInfoOn.map(d => utils.idToPurl(d.node.pkgid))
941
+ let overrides
942
+ const overridesMap = (
943
+ arb.actualTree ??
944
+ arb.idealTree ??
945
+ (await arb.loadActual())
946
+ )?.overrides?.children
947
+ if (overridesMap) {
948
+ overrides = Object.fromEntries(
949
+ [...overridesMap.entries()].map(([key, overrideSet]) => {
950
+ return [key, overrideSet.value]
951
+ })
952
+ )
953
+ }
954
+ return await utils.getAlertsMapFromPurls(purls, {
955
+ overrides,
956
+ ...options
957
+ })
958
+ }
1616
959
  function getDetailsFromDiff(diff_, options) {
1617
960
  const details = []
1618
961
  // `diff_` is `null` when `npm install --package-lock-only` is passed.
@@ -1706,7 +1049,7 @@ function updateNode(node, newVersion, newVersionPackument) {
1706
1049
  node.package.version = newVersion
1707
1050
  // Update node.resolved.
1708
1051
  const purlObj = vendor.packageurlJsExports.PackageURL.fromString(
1709
- idToPurl(node.name)
1052
+ utils.idToPurl(node.name)
1710
1053
  )
1711
1054
  node.resolved = `${NPM_REGISTRY_URL}/${node.name}/-/${purlObj.name}-${newVersion}.tgz`
1712
1055
  // Update node.integrity with the targetPackument.dist.integrity value if available
@@ -1774,7 +1117,7 @@ function updatePackageJsonFromNode(
1774
1117
  if (depObject) {
1775
1118
  const oldRange = depObject[name]
1776
1119
  if (oldRange) {
1777
- const newRange = applyRange(oldRange, newVersion, rangeStyle)
1120
+ const newRange = utils.applyRange(oldRange, newVersion, rangeStyle)
1778
1121
  if (oldRange !== newRange) {
1779
1122
  result = true
1780
1123
  editablePkgJson.update({
@@ -1790,826 +1133,8 @@ function updatePackageJsonFromNode(
1790
1133
  return result
1791
1134
  }
1792
1135
 
1793
- function extractPurlsFromPnpmLockfileV6(lockfile) {
1794
- const deps = new Set()
1795
- for (const importer of Object.values(lockfile.importers || {})) {
1796
- if (importer.dependencies) {
1797
- for (const { 0: alias, 1: ref } of Object.entries(
1798
- importer.dependencies
1799
- )) {
1800
- const id = resolvePnpmPackageId(alias, ref)
1801
- if (id) {
1802
- deps.add(idToPurl(id))
1803
- }
1804
- }
1805
- }
1806
- if (importer.devDependencies) {
1807
- for (const { 0: alias, 1: ref } of Object.entries(
1808
- importer.devDependencies
1809
- )) {
1810
- const id = resolvePnpmPackageId(alias, ref)
1811
- if (id) {
1812
- deps.add(idToPurl(id))
1813
- }
1814
- }
1815
- }
1816
- if (importer.optionalDependencies) {
1817
- for (const { 0: alias, 1: ref } of Object.entries(
1818
- importer.optionalDependencies
1819
- )) {
1820
- const id = resolvePnpmPackageId(alias, ref)
1821
- if (id) {
1822
- deps.add(idToPurl(id))
1823
- }
1824
- }
1825
- }
1826
- }
1827
- if (lockfile.packages) {
1828
- for (const pkgPath of Object.keys(lockfile.packages)) {
1829
- const id = resolvePnpmPackageIdFromPath(pkgPath, '')
1830
- if (id) {
1831
- deps.add(idToPurl(id))
1832
- }
1833
- }
1834
- }
1835
- return Array.from(deps)
1836
- }
1837
- function extractPurlsFromPnpmLockfileV9(lockfile) {
1838
- const depTypes = vendor.libExports$1.detectDepTypes(lockfile)
1839
- return Object.keys(depTypes).map(refId => {
1840
- const purlObj = vendor.packageurlJsExports.PackageURL.fromString(
1841
- idToPurl(refId)
1842
- )
1843
- const name = packages.resolvePackageName(purlObj)
1844
- const version = resolvePackageVersion(purlObj)
1845
- return idToPurl(`${name}@${version}`)
1846
- })
1847
- }
1848
- function extractPurlsFromPnpmLockfile(lockfile) {
1849
- return parsePnpmLockfileVersion(lockfile.lockfileVersion) >= 9
1850
- ? extractPurlsFromPnpmLockfileV9(lockfile)
1851
- : extractPurlsFromPnpmLockfileV6(lockfile)
1852
- }
1853
- function parsePnpmLockfileVersion(version) {
1854
- return parseInt(version.split('.')[0] ?? '', 10) || 0
1855
- }
1856
- function resolvePnpmPackageId(alias, ref) {
1857
- return ref.startsWith('/')
1858
- ? resolvePnpmPackageIdFromPath(ref, alias)
1859
- : `${alias}@${stripPeerSuffix(ref)}`
1860
- }
1861
- function resolvePnpmPackageIdFromPath(ref, alias) {
1862
- const relative = vendor.libExports$2.refToRelative(ref, alias)
1863
- if (relative) {
1864
- const id = stripLeadingSlash(relative)
1865
- const purlObj = vendor.packageurlJsExports.PackageURL.fromString(
1866
- idToPurl(id)
1867
- )
1868
- const name = packages.resolvePackageName(purlObj)
1869
- const version = resolvePackageVersion(purlObj)
1870
- return `${name}@${version}`
1871
- }
1872
- return null
1873
- }
1874
-
1875
- const {
1876
- ALERT_TYPE_CRITICAL_CVE,
1877
- ALERT_TYPE_CVE,
1878
- ALERT_TYPE_MEDIUM_CVE,
1879
- ALERT_TYPE_MILD_CVE
1880
- } = constants
1881
- function isArtifactAlertCve(alert) {
1882
- const { type } = alert
1883
- return (
1884
- type === ALERT_TYPE_CVE ||
1885
- type === ALERT_TYPE_MEDIUM_CVE ||
1886
- type === ALERT_TYPE_MILD_CVE ||
1887
- type === ALERT_TYPE_CRITICAL_CVE
1888
- )
1889
- }
1890
-
1891
- const ALERT_FIX_TYPE = createEnum({
1892
- cve: 'cve',
1893
- remove: 'remove',
1894
- upgrade: 'upgrade'
1895
- })
1896
-
1897
- function stringJoinWithSeparateFinalSeparator(list, separator = ' and ') {
1898
- const values = list.filter(Boolean)
1899
- const { length } = values
1900
- if (!length) {
1901
- return ''
1902
- }
1903
- if (length === 1) {
1904
- return values[0]
1905
- }
1906
- const finalValue = values.pop()
1907
- return `${values.join(', ')}${separator}${finalValue}`
1908
- }
1909
-
1910
- const ALERT_SEVERITY = createEnum({
1911
- critical: 'critical',
1912
- high: 'high',
1913
- middle: 'middle',
1914
- low: 'low'
1915
- })
1916
- // Ordered from most severe to least.
1917
- const ALERT_SEVERITIES_SORTED = Object.freeze([
1918
- 'critical',
1919
- 'high',
1920
- 'middle',
1921
- 'low'
1922
- ])
1923
- function getDesiredSeverities(lowestToInclude) {
1924
- const result = []
1925
- for (const severity of ALERT_SEVERITIES_SORTED) {
1926
- result.push(severity)
1927
- if (severity === lowestToInclude) {
1928
- break
1929
- }
1930
- }
1931
- return result
1932
- }
1933
- function formatSeverityCount(severityCount) {
1934
- const summary = []
1935
- for (const severity of ALERT_SEVERITIES_SORTED) {
1936
- if (severityCount[severity]) {
1937
- summary.push(`${severityCount[severity]} ${severity}`)
1938
- }
1939
- }
1940
- return stringJoinWithSeparateFinalSeparator(summary)
1941
- }
1942
- function getSeverityCount(issues, lowestToInclude) {
1943
- const severityCount = pick(
1944
- {
1945
- low: 0,
1946
- middle: 0,
1947
- high: 0,
1948
- critical: 0
1949
- },
1950
- getDesiredSeverities(lowestToInclude)
1951
- )
1952
- for (const issue of issues) {
1953
- const { value } = issue
1954
- if (!value) {
1955
- continue
1956
- }
1957
- const { severity } = value
1958
- if (severityCount[severity] !== undefined) {
1959
- severityCount[severity] += 1
1960
- }
1961
- }
1962
- return severityCount
1963
- }
1964
-
1965
- class ColorOrMarkdown {
1966
- constructor(useMarkdown) {
1967
- this.useMarkdown = !!useMarkdown
1968
- }
1969
- bold(text) {
1970
- return this.useMarkdown
1971
- ? `**${text}**`
1972
- : vendor.yoctocolorsCjsExports.bold(`${text}`)
1973
- }
1974
- header(text, level = 1) {
1975
- return this.useMarkdown
1976
- ? `\n${''.padStart(level, '#')} ${text}\n`
1977
- : vendor.yoctocolorsCjsExports.underline(
1978
- `\n${level === 1 ? vendor.yoctocolorsCjsExports.bold(text) : text}\n`
1979
- )
1980
- }
1981
- hyperlink(text, url, { fallback = true, fallbackToUrl } = {}) {
1982
- if (url) {
1983
- return this.useMarkdown
1984
- ? `[${text}](${url})`
1985
- : vendor.terminalLinkExports(text, url, {
1986
- fallback: fallbackToUrl ? (_text, url) => url : fallback
1987
- })
1988
- }
1989
- return text
1990
- }
1991
- indent(...args) {
1992
- return vendor.indentStringExports(...args)
1993
- }
1994
- italic(text) {
1995
- return this.useMarkdown
1996
- ? `_${text}_`
1997
- : vendor.yoctocolorsCjsExports.italic(`${text}`)
1998
- }
1999
- json(value) {
2000
- return this.useMarkdown
2001
- ? '```json\n' + JSON.stringify(value) + '\n```'
2002
- : JSON.stringify(value)
2003
- }
2004
- list(items) {
2005
- const indentedContent = items.map(item => this.indent(item).trimStart())
2006
- return this.useMarkdown
2007
- ? `* ${indentedContent.join('\n* ')}\n`
2008
- : `${indentedContent.join('\n')}\n`
2009
- }
2010
- }
2011
-
2012
- function getSocketDevAlertUrl(alertType) {
2013
- return `https://socket.dev/alerts/${alertType}`
2014
- }
2015
- function getSocketDevPackageOverviewUrl(eco, name, version) {
2016
- return `https://socket.dev/${eco}/package/${name}${version ? `/overview/${version}` : ''}`
2017
- }
2018
-
2019
- let _translations
2020
- function getTranslations() {
2021
- if (_translations === undefined) {
2022
- _translations = require(
2023
- // Lazily access constants.rootPath.
2024
- path.join(constants.rootPath, 'translations.json')
2025
- )
2026
- }
2027
- return _translations
2028
- }
2029
-
2030
- const ALERT_SEVERITY_COLOR = createEnum({
2031
- critical: 'magenta',
2032
- high: 'red',
2033
- middle: 'yellow',
2034
- low: 'white'
2035
- })
2036
- const ALERT_SEVERITY_ORDER = createEnum({
2037
- critical: 0,
2038
- high: 1,
2039
- middle: 2,
2040
- low: 3,
2041
- none: 4
2042
- })
2043
- const { CVE_ALERT_PROPS_FIRST_PATCHED_VERSION_IDENTIFIER, NPM: NPM$1 } =
2044
- constants
2045
- const MIN_ABOVE_THE_FOLD_COUNT = 3
2046
- const MIN_ABOVE_THE_FOLD_ALERT_COUNT = 1
2047
- const format = new ColorOrMarkdown(false)
2048
- function alertsHaveBlocked(alerts) {
2049
- return alerts.find(a => a.blocked) !== undefined
2050
- }
2051
- function alertsHaveSeverity(alerts, severity) {
2052
- return alerts.find(a => a.raw.severity === severity) !== undefined
2053
- }
2054
- function alertSeverityComparator(a, b) {
2055
- return getAlertSeverityOrder(a) - getAlertSeverityOrder(b)
2056
- }
2057
- function getAlertSeverityOrder(alert) {
2058
- const { severity } = alert.raw
2059
- return severity === ALERT_SEVERITY.critical
2060
- ? 0
2061
- : severity === ALERT_SEVERITY.high
2062
- ? 1
2063
- : severity === ALERT_SEVERITY.middle
2064
- ? 2
2065
- : severity === ALERT_SEVERITY.low
2066
- ? 3
2067
- : 4
2068
- }
2069
- function getAlertsSeverityOrder(alerts) {
2070
- return alertsHaveBlocked(alerts) ||
2071
- alertsHaveSeverity(alerts, ALERT_SEVERITY.critical)
2072
- ? 0
2073
- : alertsHaveSeverity(alerts, ALERT_SEVERITY.high)
2074
- ? 1
2075
- : alertsHaveSeverity(alerts, ALERT_SEVERITY.middle)
2076
- ? 2
2077
- : alertsHaveSeverity(alerts, ALERT_SEVERITY.low)
2078
- ? 3
2079
- : 4
2080
- }
2081
- function getHiddenRiskCounts(hiddenAlerts) {
2082
- const riskCounts = {
2083
- critical: 0,
2084
- high: 0,
2085
- middle: 0,
2086
- low: 0
2087
- }
2088
- for (const alert of hiddenAlerts) {
2089
- switch (getAlertSeverityOrder(alert)) {
2090
- case ALERT_SEVERITY_ORDER.critical:
2091
- riskCounts.critical += 1
2092
- break
2093
- case ALERT_SEVERITY_ORDER.high:
2094
- riskCounts.high += 1
2095
- break
2096
- case ALERT_SEVERITY_ORDER.middle:
2097
- riskCounts.middle += 1
2098
- break
2099
- case ALERT_SEVERITY_ORDER.low:
2100
- riskCounts.low += 1
2101
- break
2102
- }
2103
- }
2104
- return riskCounts
2105
- }
2106
- function getHiddenRisksDescription(riskCounts) {
2107
- const descriptions = []
2108
- if (riskCounts.critical) {
2109
- descriptions.push(`${riskCounts.critical} ${getSeverityLabel('critical')}`)
2110
- }
2111
- if (riskCounts.high) {
2112
- descriptions.push(`${riskCounts.high} ${getSeverityLabel('high')}`)
2113
- }
2114
- if (riskCounts.middle) {
2115
- descriptions.push(`${riskCounts.middle} ${getSeverityLabel('middle')}`)
2116
- }
2117
- if (riskCounts.low) {
2118
- descriptions.push(`${riskCounts.low} ${getSeverityLabel('low')}`)
2119
- }
2120
- return `(${descriptions.join('; ')})`
2121
- }
2122
- function getSeverityLabel(severity) {
2123
- return severity === 'middle' ? 'moderate' : severity
2124
- }
2125
- async function addArtifactToAlertsMap(artifact, alertsByPkgId, options) {
2126
- // Make TypeScript happy.
2127
- if (!artifact.name || !artifact.version || !artifact.alerts?.length) {
2128
- return alertsByPkgId
2129
- }
2130
- const {
2131
- consolidate = false,
2132
- include: _include,
2133
- overrides
2134
- } = {
2135
- __proto__: null,
2136
- ...options
2137
- }
2138
- const include = {
2139
- __proto__: null,
2140
- blocked: true,
2141
- critical: true,
2142
- cve: true,
2143
- unfixable: true,
2144
- upgradable: false,
2145
- ..._include
2146
- }
2147
- const name = packages.resolvePackageName(artifact)
2148
- const { version } = artifact
2149
- const pkgId = `${name}@${version}`
2150
- const major = vendor.semverExports.major(version)
2151
- const socketYml = findSocketYmlSync()
2152
- const enabledState = {
2153
- __proto__: null,
2154
- ...socketYml?.parsed.issueRules
2155
- }
2156
- let sockPkgAlerts = []
2157
- for (const alert of artifact.alerts) {
2158
- const action = alert.action ?? ''
2159
- const enabledFlag = enabledState[alert.type]
2160
- if (
2161
- (action === 'ignore' && enabledFlag !== true) ||
2162
- enabledFlag === false
2163
- ) {
2164
- continue
2165
- }
2166
- const blocked = action === 'error'
2167
- const critical = alert.severity === ALERT_SEVERITY.critical
2168
- const cve = isArtifactAlertCve(alert)
2169
- const fixType = alert.fix?.type ?? ''
2170
- const fixableCve = fixType === ALERT_FIX_TYPE.cve
2171
- const fixableUpgrade = fixType === ALERT_FIX_TYPE.upgrade
2172
- const fixable = fixableCve || fixableUpgrade
2173
- const upgradable = fixableUpgrade && !objects.hasOwn(overrides, name)
2174
- if (
2175
- (include.blocked && blocked) ||
2176
- (include.critical && critical) ||
2177
- (include.cve && cve) ||
2178
- (include.unfixable && !fixable) ||
2179
- (include.upgradable && upgradable)
2180
- ) {
2181
- sockPkgAlerts.push({
2182
- name,
2183
- version,
2184
- key: alert.key,
2185
- type: alert.type,
2186
- blocked,
2187
- critical,
2188
- fixable,
2189
- raw: alert,
2190
- upgradable
2191
- })
2192
- }
2193
- }
2194
- if (!sockPkgAlerts.length) {
2195
- return alertsByPkgId
2196
- }
2197
- if (consolidate) {
2198
- const highestForCve = new Map()
2199
- const highestForUpgrade = new Map()
2200
- const unfixableAlerts = []
2201
- for (const sockPkgAlert of sockPkgAlerts) {
2202
- const alert = sockPkgAlert.raw
2203
- const fixType = alert.fix?.type ?? ''
2204
- if (fixType === ALERT_FIX_TYPE.cve) {
2205
- const patchedVersion =
2206
- alert.props[CVE_ALERT_PROPS_FIRST_PATCHED_VERSION_IDENTIFIER]
2207
- const patchedMajor = vendor.semverExports.major(patchedVersion)
2208
- const oldHighest = highestForCve.get(patchedMajor)
2209
- const highest = oldHighest?.version ?? '0.0.0'
2210
- if (vendor.semverExports.gt(patchedVersion, highest)) {
2211
- highestForCve.set(patchedMajor, {
2212
- alert: sockPkgAlert,
2213
- version: patchedVersion
2214
- })
2215
- }
2216
- } else if (fixType === ALERT_FIX_TYPE.upgrade) {
2217
- const oldHighest = highestForUpgrade.get(major)
2218
- const highest = oldHighest?.version ?? '0.0.0'
2219
- if (vendor.semverExports.gt(version, highest)) {
2220
- highestForUpgrade.set(major, {
2221
- alert: sockPkgAlert,
2222
- version
2223
- })
2224
- }
2225
- } else {
2226
- unfixableAlerts.push(sockPkgAlert)
2227
- }
2228
- }
2229
- sockPkgAlerts = [
2230
- ...unfixableAlerts,
2231
- ...[...highestForCve.values()].map(d => d.alert),
2232
- ...[...highestForUpgrade.values()].map(d => d.alert)
2233
- ]
2234
- }
2235
- if (sockPkgAlerts.length) {
2236
- sockPkgAlerts.sort((a, b) => sorts.naturalCompare(a.type, b.type))
2237
- alertsByPkgId.set(pkgId, sockPkgAlerts)
2238
- }
2239
- return alertsByPkgId
2240
- }
2241
- function getCveInfoByAlertsMap(alertsMap, options) {
2242
- const { exclude: _exclude, limit = Infinity } = {
2243
- __proto__: null,
2244
- ...options
2245
- }
2246
- const exclude = {
2247
- __proto__: null,
2248
- upgradable: true,
2249
- ..._exclude
2250
- }
2251
- let count = 0
2252
- let infoByPkg = null
2253
- alertsMapLoop: for (const [pkgId, sockPkgAlerts] of alertsMap) {
2254
- const purlObj = vendor.packageurlJsExports.PackageURL.fromString(
2255
- idToPurl(pkgId)
2256
- )
2257
- const name = packages.resolvePackageName(purlObj)
2258
- for (const sockPkgAlert of sockPkgAlerts) {
2259
- const alert = sockPkgAlert.raw
2260
- if (
2261
- alert.fix?.type !== ALERT_FIX_TYPE.cve ||
2262
- (exclude.upgradable && registry.getManifestData(NPM$1, name))
2263
- ) {
2264
- continue
2265
- }
2266
- if (!infoByPkg) {
2267
- infoByPkg = new Map()
2268
- }
2269
- let infos = infoByPkg.get(name)
2270
- if (!infos) {
2271
- infos = []
2272
- infoByPkg.set(name, infos)
2273
- }
2274
- const { firstPatchedVersionIdentifier, vulnerableVersionRange } =
2275
- alert.props
2276
- try {
2277
- infos.push({
2278
- firstPatchedVersionIdentifier,
2279
- vulnerableVersionRange: new vendor.semverExports.Range(
2280
- // Replace ', ' in a range like '>= 1.0.0, < 1.8.2' with ' ' so that
2281
- // semver.Range will parse it without erroring.
2282
- vulnerableVersionRange.replace(/, +/g, ' ')
2283
- ).format()
2284
- })
2285
- if (++count >= limit) {
2286
- break alertsMapLoop
2287
- }
2288
- } catch (e) {
2289
- debug.debugLog('getCveInfoByAlertsMap', {
2290
- firstPatchedVersionIdentifier,
2291
- vulnerableVersionRange
2292
- })
2293
- debug.debugLog(e)
2294
- }
2295
- }
2296
- }
2297
- return infoByPkg
2298
- }
2299
- function logAlertsMap(alertsMap, options) {
2300
- const { hideAt = 'middle', output = process.stderr } = {
2301
- __proto__: null,
2302
- ...options
2303
- }
2304
- const translations = getTranslations()
2305
- const sortedEntries = [...alertsMap.entries()].sort(
2306
- (a, b) => getAlertsSeverityOrder(a[1]) - getAlertsSeverityOrder(b[1])
2307
- )
2308
- const aboveTheFoldPkgIds = new Set()
2309
- const viewableAlertsByPkgId = new Map()
2310
- const hiddenAlertsByPkgId = new Map()
2311
- for (let i = 0, { length } = sortedEntries; i < length; i += 1) {
2312
- const { 0: pkgId, 1: alerts } = sortedEntries[i]
2313
- const hiddenAlerts = []
2314
- const viewableAlerts = alerts.filter(a => {
2315
- const keep =
2316
- a.blocked || getAlertSeverityOrder(a) < ALERT_SEVERITY_ORDER[hideAt]
2317
- if (!keep) {
2318
- hiddenAlerts.push(a)
2319
- }
2320
- return keep
2321
- })
2322
- if (hiddenAlerts.length) {
2323
- hiddenAlertsByPkgId.set(pkgId, hiddenAlerts.sort(alertSeverityComparator))
2324
- }
2325
- if (!viewableAlerts.length) {
2326
- continue
2327
- }
2328
- viewableAlerts.sort(alertSeverityComparator)
2329
- viewableAlertsByPkgId.set(pkgId, viewableAlerts)
2330
- if (
2331
- viewableAlerts.find(
2332
- a => a.blocked || getAlertSeverityOrder(a) < ALERT_SEVERITY_ORDER.middle
2333
- )
2334
- ) {
2335
- aboveTheFoldPkgIds.add(pkgId)
2336
- }
2337
- }
2338
-
2339
- // If MIN_ABOVE_THE_FOLD_COUNT is NOT met add more from viewable pkg ids.
2340
- for (const { 0: pkgId } of viewableAlertsByPkgId.entries()) {
2341
- if (aboveTheFoldPkgIds.size >= MIN_ABOVE_THE_FOLD_COUNT) {
2342
- break
2343
- }
2344
- aboveTheFoldPkgIds.add(pkgId)
2345
- }
2346
- // If MIN_ABOVE_THE_FOLD_COUNT is STILL NOT met add more from hidden pkg ids.
2347
- for (const { 0: pkgId, 1: hiddenAlerts } of hiddenAlertsByPkgId.entries()) {
2348
- if (aboveTheFoldPkgIds.size >= MIN_ABOVE_THE_FOLD_COUNT) {
2349
- break
2350
- }
2351
- aboveTheFoldPkgIds.add(pkgId)
2352
- const viewableAlerts = viewableAlertsByPkgId.get(pkgId) ?? []
2353
- if (viewableAlerts.length < MIN_ABOVE_THE_FOLD_ALERT_COUNT) {
2354
- const neededCount = MIN_ABOVE_THE_FOLD_ALERT_COUNT - viewableAlerts.length
2355
- let removedHiddenAlerts
2356
- if (hiddenAlerts.length - neededCount > 0) {
2357
- removedHiddenAlerts = hiddenAlerts.splice(
2358
- 0,
2359
- MIN_ABOVE_THE_FOLD_ALERT_COUNT
2360
- )
2361
- } else {
2362
- removedHiddenAlerts = hiddenAlerts
2363
- hiddenAlertsByPkgId.delete(pkgId)
2364
- }
2365
- viewableAlertsByPkgId.set(pkgId, [
2366
- ...viewableAlerts,
2367
- ...removedHiddenAlerts
2368
- ])
2369
- }
2370
- }
2371
- const mentionedPkgIdsWithHiddenAlerts = new Set()
2372
- for (
2373
- let i = 0,
2374
- prevAboveTheFold = true,
2375
- entries = [...viewableAlertsByPkgId.entries()],
2376
- { length } = entries;
2377
- i < length;
2378
- i += 1
2379
- ) {
2380
- const { 0: pkgId, 1: alerts } = entries[i]
2381
- const lines = new Set()
2382
- for (const alert of alerts) {
2383
- const { type } = alert
2384
- const severity = alert.raw.severity ?? ''
2385
- const attributes = [
2386
- ...(severity
2387
- ? [
2388
- vendor.yoctocolorsCjsExports[ALERT_SEVERITY_COLOR[severity]](
2389
- getSeverityLabel(severity)
2390
- )
2391
- ]
2392
- : []),
2393
- ...(alert.blocked
2394
- ? [
2395
- vendor.yoctocolorsCjsExports.bold(
2396
- vendor.yoctocolorsCjsExports.red('blocked')
2397
- )
2398
- ]
2399
- : []),
2400
- ...(alert.fixable ? ['fixable'] : [])
2401
- ]
2402
- const maybeAttributes = attributes.length
2403
- ? ` ${vendor.yoctocolorsCjsExports.italic(`(${attributes.join('; ')})`)}`
2404
- : ''
2405
- // Based data from { pageProps: { alertTypes } } of:
2406
- // https://socket.dev/_next/data/94666139314b6437ee4491a0864e72b264547585/en-US.json
2407
- const info = translations.alerts[type]
2408
- const title = info?.title ?? type
2409
- const maybeDesc = info?.description ? ` - ${info.description}` : ''
2410
- const content = `${title}${maybeAttributes}${maybeDesc}`
2411
- // TODO: emoji seems to mis-align terminals sometimes
2412
- lines.add(` ${content}`)
2413
- }
2414
- const purlObj = vendor.packageurlJsExports.PackageURL.fromString(
2415
- idToPurl(pkgId)
2416
- )
2417
- const hyperlink = format.hyperlink(
2418
- pkgId,
2419
- getSocketDevPackageOverviewUrl(
2420
- NPM$1,
2421
- packages.resolvePackageName(purlObj),
2422
- purlObj.version
2423
- )
2424
- )
2425
- const isAboveTheFold = aboveTheFoldPkgIds.has(pkgId)
2426
- if (isAboveTheFold) {
2427
- aboveTheFoldPkgIds.add(pkgId)
2428
- output.write(`${i ? '\n' : ''}${hyperlink}:\n`)
2429
- } else {
2430
- output.write(`${prevAboveTheFold ? '\n' : ''}${hyperlink}:\n`)
2431
- }
2432
- for (const line of lines) {
2433
- output.write(`${line}\n`)
2434
- }
2435
- const hiddenAlerts = hiddenAlertsByPkgId.get(pkgId) ?? []
2436
- const { length: hiddenAlertsCount } = hiddenAlerts
2437
- if (hiddenAlertsCount) {
2438
- mentionedPkgIdsWithHiddenAlerts.add(pkgId)
2439
- if (hiddenAlertsCount === 1) {
2440
- output.write(
2441
- ` ${vendor.yoctocolorsCjsExports.dim(`+1 Hidden ${getSeverityLabel(hiddenAlerts[0].raw.severity ?? 'low')} risk alert`)}\n`
2442
- )
2443
- } else {
2444
- output.write(
2445
- ` ${vendor.yoctocolorsCjsExports.dim(`+${hiddenAlertsCount} Hidden alerts ${vendor.yoctocolorsCjsExports.italic(getHiddenRisksDescription(getHiddenRiskCounts(hiddenAlerts)))}`)}\n`
2446
- )
2447
- }
2448
- }
2449
- prevAboveTheFold = isAboveTheFold
2450
- }
2451
- const additionalHiddenCount =
2452
- hiddenAlertsByPkgId.size - mentionedPkgIdsWithHiddenAlerts.size
2453
- if (additionalHiddenCount) {
2454
- const totalRiskCounts = {
2455
- critical: 0,
2456
- high: 0,
2457
- middle: 0,
2458
- low: 0
2459
- }
2460
- for (const { 0: pkgId, 1: alerts } of hiddenAlertsByPkgId.entries()) {
2461
- if (mentionedPkgIdsWithHiddenAlerts.has(pkgId)) {
2462
- continue
2463
- }
2464
- const riskCounts = getHiddenRiskCounts(alerts)
2465
- totalRiskCounts.critical += riskCounts.critical
2466
- totalRiskCounts.high += riskCounts.high
2467
- totalRiskCounts.middle += riskCounts.middle
2468
- totalRiskCounts.low += riskCounts.low
2469
- }
2470
- output.write(
2471
- `${aboveTheFoldPkgIds.size ? '\n' : ''}${vendor.yoctocolorsCjsExports.dim(`${aboveTheFoldPkgIds.size ? '+' : ''}${additionalHiddenCount} Packages with hidden alerts ${vendor.yoctocolorsCjsExports.italic(getHiddenRisksDescription(totalRiskCounts))}`)}\n`
2472
- )
2473
- }
2474
- output.write('\n')
2475
- }
2476
-
2477
- async function getAlertsMapFromArborist(arb, options_) {
2478
- const options = {
2479
- __proto__: null,
2480
- consolidate: false,
2481
- limit: Infinity,
2482
- nothrow: false,
2483
- ...options_
2484
- }
2485
- const include = {
2486
- __proto__: null,
2487
- existing: false,
2488
- ...options.include
2489
- }
2490
- const needInfoOn = getDetailsFromDiff(arb.diff, {
2491
- include: {
2492
- unchanged: include.existing
2493
- }
2494
- })
2495
- const purls = needInfoOn.map(d => idToPurl(d.node.pkgid))
2496
- let overrides
2497
- const overridesMap = (
2498
- arb.actualTree ??
2499
- arb.idealTree ??
2500
- (await arb.loadActual())
2501
- )?.overrides?.children
2502
- if (overridesMap) {
2503
- overrides = Object.fromEntries(
2504
- [...overridesMap.entries()].map(([key, overrideSet]) => {
2505
- return [key, overrideSet.value]
2506
- })
2507
- )
2508
- }
2509
- return await getAlertsMapFromPurls(purls, {
2510
- overrides,
2511
- ...options
2512
- })
2513
- }
2514
- async function getAlertsMapFromPnpmLockfile(lockfile, options_) {
2515
- const options = {
2516
- __proto__: null,
2517
- consolidate: false,
2518
- limit: Infinity,
2519
- nothrow: false,
2520
- ...options_
2521
- }
2522
- const purls = extractPurlsFromPnpmLockfile(lockfile)
2523
- return await getAlertsMapFromPurls(purls, {
2524
- overrides: lockfile.overrides,
2525
- ...options
2526
- })
2527
- }
2528
- async function getAlertsMapFromPurls(purls, options_) {
2529
- const options = {
2530
- __proto__: null,
2531
- consolidate: false,
2532
- nothrow: false,
2533
- ...options_
2534
- }
2535
- const include = {
2536
- __proto__: null,
2537
- actions: undefined,
2538
- blocked: true,
2539
- critical: true,
2540
- cve: true,
2541
- existing: false,
2542
- unfixable: true,
2543
- upgradable: false,
2544
- ...options.include
2545
- }
2546
- const { spinner } = options
2547
- const uniqPurls = arrays.arrayUnique(purls)
2548
- let { length: remaining } = uniqPurls
2549
- const alertsByPkgId = new Map()
2550
- if (!remaining) {
2551
- return alertsByPkgId
2552
- }
2553
- const getText = () => `Looking up data for ${remaining} packages`
2554
- spinner?.start(getText())
2555
- const sockSdk = await setupSdk(getPublicToken())
2556
- const toAlertsMapOptions = {
2557
- overrides: options.overrides,
2558
- consolidate: options.consolidate,
2559
- include,
2560
- spinner
2561
- }
2562
- for await (const batchResult of sockSdk.batchPackageStream(
2563
- {
2564
- alerts: 'true',
2565
- compact: 'true',
2566
- ...(include.actions
2567
- ? {
2568
- actions: include.actions.join(',')
2569
- }
2570
- : {}),
2571
- ...(include.unfixable
2572
- ? {}
2573
- : {
2574
- fixable: 'true'
2575
- })
2576
- },
2577
- {
2578
- components: uniqPurls.map(purl => ({
2579
- purl
2580
- }))
2581
- }
2582
- )) {
2583
- if (batchResult.success) {
2584
- await addArtifactToAlertsMap(
2585
- batchResult.data,
2586
- alertsByPkgId,
2587
- toAlertsMapOptions
2588
- )
2589
- } else if (!options.nothrow) {
2590
- const statusCode = batchResult.status ?? 'unknown'
2591
- const statusMessage = batchResult.error ?? 'No status message'
2592
- throw new Error(
2593
- `Socket API server error (${statusCode}): ${statusMessage}`
2594
- )
2595
- }
2596
- remaining -= 1
2597
- if (spinner && remaining > 0) {
2598
- spinner.start()
2599
- spinner.setText(getText())
2600
- }
2601
- }
2602
- spinner?.stop()
2603
- return alertsByPkgId
2604
- }
2605
-
2606
1136
  const require$2 = Module.createRequire(
2607
- typeof document === 'undefined'
2608
- ? require('u' + 'rl').pathToFileURL(__filename).href
2609
- : (_documentCurrentScript &&
2610
- _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' &&
2611
- _documentCurrentScript.src) ||
2612
- new URL('shadow-npm-inject.js', document.baseURI).href
1137
+ require('u' + 'rl').pathToFileURL(__filename).href
2613
1138
  )
2614
1139
  const {
2615
1140
  NPM,
@@ -2634,7 +1159,7 @@ const SAFE_ARBORIST_REIFY_OPTIONS_OVERRIDES = {
2634
1159
  }
2635
1160
  const kCtorArgs = Symbol('ctorArgs')
2636
1161
  const kRiskyReify = Symbol('riskyReify')
2637
- const Arborist = require$2(shadowNpmPaths.getArboristClassPath())
1162
+ const Arborist = require$2(getArboristClassPath())
2638
1163
 
2639
1164
  // Implementation code not related to our custom behavior is based on
2640
1165
  // https://github.com/npm/cli/blob/v11.0.0/workspaces/arborist/lib/arborist/index.js:
@@ -2722,7 +1247,7 @@ class SafeArborist extends Arborist {
2722
1247
  process.exitCode = 1
2723
1248
  // Lazily access constants.ENV.SOCKET_CLI_VIEW_ALL_RISKS.
2724
1249
  const viewAllRisks = constants.ENV.SOCKET_CLI_VIEW_ALL_RISKS
2725
- logAlertsMap(alertsMap, {
1250
+ utils.logAlertsMap(alertsMap, {
2726
1251
  hideAt: viewAllRisks ? 'none' : 'middle',
2727
1252
  output: process.stderr
2728
1253
  })
@@ -2744,78 +1269,37 @@ class SafeArborist extends Arborist {
2744
1269
  }
2745
1270
 
2746
1271
  const require$1 = Module.createRequire(
2747
- typeof document === 'undefined'
2748
- ? require('u' + 'rl').pathToFileURL(__filename).href
2749
- : (_documentCurrentScript &&
2750
- _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' &&
2751
- _documentCurrentScript.src) ||
2752
- new URL('shadow-npm-inject.js', document.baseURI).href
1272
+ require('u' + 'rl').pathToFileURL(__filename).href
2753
1273
  )
2754
1274
  function installSafeArborist() {
2755
1275
  // Override '@npmcli/arborist' module exports with patched variants based on
2756
1276
  // https://github.com/npm/cli/pull/8089.
2757
1277
  const cache = require$1.cache
2758
- cache[shadowNpmPaths.getArboristClassPath()] = {
1278
+ cache[getArboristClassPath()] = {
2759
1279
  exports: SafeArborist
2760
1280
  }
2761
- cache[shadowNpmPaths.getArboristEdgeClassPath()] = {
1281
+ cache[getArboristEdgeClassPath()] = {
2762
1282
  exports: SafeEdge
2763
1283
  }
2764
- cache[shadowNpmPaths.getArboristNodeClassPath()] = {
1284
+ cache[getArboristNodeClassPath()] = {
2765
1285
  exports: SafeNode
2766
1286
  }
2767
- cache[shadowNpmPaths.getArboristOverrideSetClassPath()] = {
1287
+ cache[getArboristOverrideSetClassPath()] = {
2768
1288
  exports: SafeOverrideSet
2769
1289
  }
2770
1290
  }
2771
1291
 
2772
1292
  installSafeArborist()
2773
1293
 
2774
- exports.ALERT_SEVERITY = ALERT_SEVERITY
2775
1294
  exports.Arborist = Arborist
2776
- exports.AuthError = AuthError
2777
- exports.ColorOrMarkdown = ColorOrMarkdown
2778
- exports.InputError = InputError
2779
- exports.RangeStyles = RangeStyles
2780
1295
  exports.SAFE_ARBORIST_REIFY_OPTIONS_OVERRIDES =
2781
1296
  SAFE_ARBORIST_REIFY_OPTIONS_OVERRIDES
2782
1297
  exports.SafeArborist = SafeArborist
2783
- exports.applyRange = applyRange
2784
- exports.captureException = captureException
2785
- exports.filterGlobResultToSupportedFiles = filterGlobResultToSupportedFiles
2786
1298
  exports.findBestPatchVersion = findBestPatchVersion
2787
1299
  exports.findPackageNode = findPackageNode
2788
1300
  exports.findPackageNodes = findPackageNodes
2789
- exports.findUp = findUp
2790
- exports.formatSeverityCount = formatSeverityCount
2791
1301
  exports.getAlertsMapFromArborist = getAlertsMapFromArborist
2792
- exports.getAlertsMapFromPnpmLockfile = getAlertsMapFromPnpmLockfile
2793
- exports.getAlertsMapFromPurls = getAlertsMapFromPurls
2794
- exports.getConfigValue = getConfigValue
2795
- exports.getConfigValueOrUndef = getConfigValueOrUndef
2796
- exports.getCveInfoByAlertsMap = getCveInfoByAlertsMap
2797
- exports.getDefaultToken = getDefaultToken
2798
- exports.getPublicToken = getPublicToken
2799
- exports.getSeverityCount = getSeverityCount
2800
- exports.getSocketDevAlertUrl = getSocketDevAlertUrl
2801
- exports.getSocketDevPackageOverviewUrl = getSocketDevPackageOverviewUrl
2802
- exports.globWithGitIgnore = globWithGitIgnore
2803
- exports.globWorkspace = globWorkspace
2804
- exports.idToPurl = idToPurl
2805
- exports.isReadOnlyConfig = isReadOnlyConfig
2806
- exports.isTestingV1 = isTestingV1
2807
- exports.overrideCachedConfig = overrideCachedConfig
2808
- exports.overrideConfigApiToken = overrideConfigApiToken
2809
- exports.pathsToGlobPatterns = pathsToGlobPatterns
2810
- exports.readFileBinary = readFileBinary
2811
- exports.readFileUtf8 = readFileUtf8
2812
- exports.removeNodeModules = removeNodeModules
2813
- exports.safeReadFile = safeReadFile
2814
- exports.sensitiveConfigKeys = sensitiveConfigKeys
2815
- exports.setupSdk = setupSdk
2816
- exports.supportedConfigKeys = supportedConfigKeys
2817
- exports.updateConfigValue = updateConfigValue
2818
1302
  exports.updateNode = updateNode
2819
1303
  exports.updatePackageJsonFromNode = updatePackageJsonFromNode
2820
- //# debugId=914bfb89-28c3-474b-b7c7-be1acda844d4
1304
+ //# debugId=abb3ad9d-815d-4325-99e6-528b98325c45
2821
1305
  //# sourceMappingURL=shadow-npm-inject.js.map