@socketsecurity/cli-with-sentry 0.14.103 → 0.14.104

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.
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const require$$0 = require('node:fs')
3
+ const fs = require('node:fs')
4
4
  const Module = require('node:module')
5
5
  const path = require('node:path')
6
6
  const process = require('node:process')
@@ -11,7 +11,11 @@ const vendor = require('./vendor.js')
11
11
  const debug = require('@socketsecurity/registry/lib/debug')
12
12
  const npm = require('@socketsecurity/registry/lib/npm')
13
13
  const words = require('@socketsecurity/registry/lib/words')
14
+ const strings = require('@socketsecurity/registry/lib/strings')
15
+ const shadowNpmInject = require('./shadow-npm-inject.js')
14
16
 
17
+ const { NPM: NPM$2, PNPM } = constants
18
+ const PNPM_WORKSPACE = `${PNPM}-workspace`
15
19
  const ignoredDirs = [
16
20
  // Taken from ignore-by-default:
17
21
  // https://github.com/novemberborn/ignore-by-default/blob/v2.1.0/index.js
@@ -36,13 +40,115 @@ const ignoredDirs = [
36
40
  'flow-typed'
37
41
  ]
38
42
  const ignoredDirPatterns = ignoredDirs.map(i => `**/${i}`)
39
- function directoryPatterns() {
40
- return [...ignoredDirPatterns]
43
+ async function getWorkspaceGlobs(pkgEnvDetails) {
44
+ let workspacePatterns
45
+ if (pkgEnvDetails.agent === PNPM) {
46
+ for (const workspacePath of [
47
+ path.join(pkgEnvDetails.pkgPath, `${PNPM_WORKSPACE}.yaml`),
48
+ path.join(pkgEnvDetails.pkgPath, `${PNPM_WORKSPACE}.yml`)
49
+ ]) {
50
+ // eslint-disable-next-line no-await-in-loop
51
+ const yml = await shadowNpmInject.safeReadFile(workspacePath)
52
+ if (yml) {
53
+ try {
54
+ workspacePatterns = vendor.distExports$1.parse(yml)?.packages
55
+ } catch {}
56
+ if (workspacePatterns) {
57
+ break
58
+ }
59
+ }
60
+ }
61
+ } else {
62
+ workspacePatterns = pkgEnvDetails.editablePkgJson.content['workspaces']
63
+ }
64
+ return Array.isArray(workspacePatterns)
65
+ ? workspacePatterns
66
+ .filter(strings.isNonEmptyString)
67
+ .map(workspacePatternToGlobPattern)
68
+ : []
69
+ }
70
+ function ignoreFileLinesToGlobPatterns(lines, filepath, cwd) {
71
+ const base = path.relative(cwd, path.dirname(filepath)).replace(/\\/g, '/')
72
+ const patterns = []
73
+ for (let i = 0, { length } = lines; i < length; i += 1) {
74
+ const pattern = lines[i].trim()
75
+ if (pattern.length > 0 && pattern.charCodeAt(0) !== 35 /*'#'*/) {
76
+ patterns.push(
77
+ ignorePatternToMinimatch(
78
+ pattern.length && pattern.charCodeAt(0) === 33 /*'!'*/
79
+ ? `!${path.posix.join(base, pattern.slice(1))}`
80
+ : path.posix.join(base, pattern)
81
+ )
82
+ )
83
+ }
84
+ }
85
+ return patterns
86
+ }
87
+ function ignoreFileToGlobPatterns(content, filepath, cwd) {
88
+ return ignoreFileLinesToGlobPatterns(content.split(/\r?\n/), filepath, cwd)
41
89
  }
42
90
 
43
- const { NODE_MODULES: NODE_MODULES$1, NPM: NPM$1, shadowBinPath } = constants
91
+ // Based on `@eslint/compat` convertIgnorePatternToMinimatch.
92
+ // Apache v2.0 licensed
93
+ // Copyright Nicholas C. Zakas
94
+ // https://github.com/eslint/rewrite/blob/compat-v1.2.1/packages/compat/src/ignore-file.js#L28
95
+ function ignorePatternToMinimatch(pattern) {
96
+ const isNegated = pattern.startsWith('!')
97
+ const negatedPrefix = isNegated ? '!' : ''
98
+ const patternToTest = (isNegated ? pattern.slice(1) : pattern).trimEnd()
99
+ // Special cases.
100
+ if (
101
+ patternToTest === '' ||
102
+ patternToTest === '**' ||
103
+ patternToTest === '/**' ||
104
+ patternToTest === '**'
105
+ ) {
106
+ return `${negatedPrefix}${patternToTest}`
107
+ }
108
+ const firstIndexOfSlash = patternToTest.indexOf('/')
109
+ const matchEverywherePrefix =
110
+ firstIndexOfSlash === -1 || firstIndexOfSlash === patternToTest.length - 1
111
+ ? '**/'
112
+ : ''
113
+ const patternWithoutLeadingSlash =
114
+ firstIndexOfSlash === 0 ? patternToTest.slice(1) : patternToTest
115
+ // Escape `{` and `(` because in gitignore patterns they are just
116
+ // literal characters without any specific syntactic meaning,
117
+ // while in minimatch patterns they can form brace expansion or extglob syntax.
118
+ //
119
+ // For example, gitignore pattern `src/{a,b}.js` ignores file `src/{a,b}.js`.
120
+ // But, the same minimatch pattern `src/{a,b}.js` ignores files `src/a.js` and `src/b.js`.
121
+ // Minimatch pattern `src/\{a,b}.js` is equivalent to gitignore pattern `src/{a,b}.js`.
122
+ const escapedPatternWithoutLeadingSlash =
123
+ patternWithoutLeadingSlash.replaceAll(
124
+ /(?=((?:\\.|[^{(])*))\1([{(])/guy,
125
+ '$1\\$2'
126
+ )
127
+ const matchInsideSuffix = patternToTest.endsWith('/**') ? '/*' : ''
128
+ return `${negatedPrefix}${matchEverywherePrefix}${escapedPatternWithoutLeadingSlash}${matchInsideSuffix}`
129
+ }
130
+ function workspacePatternToGlobPattern(workspace) {
131
+ const { length } = workspace
132
+ if (!length) {
133
+ return ''
134
+ }
135
+ // If the workspace ends with "/"
136
+ if (workspace.charCodeAt(length - 1) === 47 /*'/'*/) {
137
+ return `${workspace}/*/package.json`
138
+ }
139
+ // If the workspace ends with "/**"
140
+ if (
141
+ workspace.charCodeAt(length - 1) === 42 /*'*'*/ &&
142
+ workspace.charCodeAt(length - 2) === 42 /*'*'*/ &&
143
+ workspace.charCodeAt(length - 3) === 47 /*'/'*/
144
+ ) {
145
+ return `${workspace}/*/**/package.json`
146
+ }
147
+ // Things like "packages/a" or "packages/*"
148
+ return `${workspace}/package.json`
149
+ }
44
150
  async function filterGlobResultToSupportedFiles(entries, supportedFiles) {
45
- const patterns = ['golang', NPM$1, 'maven', 'pypi', 'gem', 'nuget'].reduce(
151
+ const patterns = ['golang', NPM$2, 'maven', 'pypi', 'gem', 'nuget'].reduce(
46
152
  (r, n) => {
47
153
  const supported = supportedFiles[n]
48
154
  r.push(
@@ -72,7 +178,7 @@ async function globWithGitIgnore(patterns, options) {
72
178
  expandDirectories: true
73
179
  })
74
180
  const ignores = [
75
- ...directoryPatterns(),
181
+ ...ignoredDirPatterns,
76
182
  ...(Array.isArray(projectIgnorePaths)
77
183
  ? ignoreFileLinesToGlobPatterns(
78
184
  projectIgnorePaths,
@@ -84,7 +190,7 @@ async function globWithGitIgnore(patterns, options) {
84
190
  await Promise.all(
85
191
  ignoreFiles.map(async filepath =>
86
192
  ignoreFileToGlobPatterns(
87
- await require$$0.promises.readFile(filepath, 'utf8'),
193
+ await fs.promises.readFile(filepath, 'utf8'),
88
194
  filepath,
89
195
  cwd
90
196
  )
@@ -114,73 +220,25 @@ async function globWithGitIgnore(patterns, options) {
114
220
  .filter(absolute ? result.map(p => path.relative(cwd, p)) : result)
115
221
  return absolute ? filtered.map(p => path.resolve(cwd, p)) : filtered
116
222
  }
117
- function ignoreFileLinesToGlobPatterns(lines, filepath, cwd) {
118
- const base = path.relative(cwd, path.dirname(filepath)).replace(/\\/g, '/')
119
- const patterns = []
120
- for (let i = 0, { length } = lines; i < length; i += 1) {
121
- const pattern = lines[i].trim()
122
- if (pattern.length > 0 && pattern.charCodeAt(0) !== 35 /*'#'*/) {
123
- patterns.push(
124
- ignorePatternToMinimatch(
125
- pattern.length && pattern.charCodeAt(0) === 33 /*'!'*/
126
- ? `!${path.posix.join(base, pattern.slice(1))}`
127
- : path.posix.join(base, pattern)
128
- )
129
- )
130
- }
131
- }
132
- return patterns
133
- }
134
- function ignoreFileToGlobPatterns(content, filepath, cwd) {
135
- return ignoreFileLinesToGlobPatterns(content.split(/\r?\n/), filepath, cwd)
223
+ async function globWorkspace(pkgEnvDetails) {
224
+ const workspaceGlobs = await getWorkspaceGlobs(pkgEnvDetails)
225
+ return workspaceGlobs.length
226
+ ? await vendor.distExports.glob(workspaceGlobs, {
227
+ absolute: true,
228
+ cwd: pkgEnvDetails.pkgPath,
229
+ ignore: ['**/node_modules/**', '**/bower_components/**']
230
+ })
231
+ : []
136
232
  }
137
-
138
- // Based on `@eslint/compat` convertIgnorePatternToMinimatch.
139
- // Apache v2.0 licensed
140
- // Copyright Nicholas C. Zakas
141
- // https://github.com/eslint/rewrite/blob/compat-v1.2.1/packages/compat/src/ignore-file.js#L28
142
- function ignorePatternToMinimatch(pattern) {
143
- const isNegated = pattern.startsWith('!')
144
- const negatedPrefix = isNegated ? '!' : ''
145
- const patternToTest = (isNegated ? pattern.slice(1) : pattern).trimEnd()
146
- // Special cases.
147
- if (
148
- patternToTest === '' ||
149
- patternToTest === '**' ||
150
- patternToTest === '/**' ||
151
- patternToTest === '**'
152
- ) {
153
- return `${negatedPrefix}${patternToTest}`
154
- }
155
- const firstIndexOfSlash = patternToTest.indexOf('/')
156
- const matchEverywherePrefix =
157
- firstIndexOfSlash === -1 || firstIndexOfSlash === patternToTest.length - 1
158
- ? '**/'
159
- : ''
160
- const patternWithoutLeadingSlash =
161
- firstIndexOfSlash === 0 ? patternToTest.slice(1) : patternToTest
162
- // Escape `{` and `(` because in gitignore patterns they are just
163
- // literal characters without any specific syntactic meaning,
164
- // while in minimatch patterns they can form brace expansion or extglob syntax.
165
- //
166
- // For example, gitignore pattern `src/{a,b}.js` ignores file `src/{a,b}.js`.
167
- // But, the same minimatch pattern `src/{a,b}.js` ignores files `src/a.js` and `src/b.js`.
168
- // Minimatch pattern `src/\{a,b}.js` is equivalent to gitignore pattern `src/{a,b}.js`.
169
- const escapedPatternWithoutLeadingSlash =
170
- patternWithoutLeadingSlash.replaceAll(
171
- /(?=((?:\\.|[^{(])*))\1([{(])/guy,
172
- '$1\\$2'
173
- )
174
- const matchInsideSuffix = patternToTest.endsWith('/**') ? '/*' : ''
175
- return `${negatedPrefix}${matchEverywherePrefix}${escapedPatternWithoutLeadingSlash}${matchInsideSuffix}`
176
- }
177
- function pathsToPatterns(paths) {
233
+ function pathsToGlobPatterns(paths) {
178
234
  // TODO: Does not support `~/` paths.
179
235
  return paths.map(p => (p === '.' || p === './' ? '**/*' : p))
180
236
  }
237
+
238
+ const { NODE_MODULES: NODE_MODULES$1, NPM: NPM$1, shadowBinPath } = constants
181
239
  function findBinPathDetailsSync(binName) {
182
240
  const binPaths =
183
- vendor.libExports$1.sync(binName, {
241
+ vendor.libExports$2.sync(binName, {
184
242
  all: true,
185
243
  nothrow: true
186
244
  }) ?? []
@@ -216,8 +274,8 @@ function findNpmPathSync(npmBinPath) {
216
274
  // Use existsSync here because statsSync, even with { throwIfNoEntry: false },
217
275
  // will throw an ENOTDIR error for paths like ./a-file-that-exists/a-directory-that-does-not.
218
276
  // See https://github.com/nodejs/node/issues/56993.
219
- require$$0.existsSync(libNmNpmPath) &&
220
- require$$0
277
+ fs.existsSync(libNmNpmPath) &&
278
+ fs
221
279
  .statSync(libNmNpmPath, {
222
280
  throwIfNoEntry: false
223
281
  })
@@ -237,8 +295,8 @@ function findNpmPathSync(npmBinPath) {
237
295
  // In practically all cases the npm path contains a node_modules folder:
238
296
  // /usr/local/share/npm/bin/npm/node_modules
239
297
  // C:\Program Files\nodejs\node_modules
240
- require$$0.existsSync(nmPath) &&
241
- require$$0
298
+ fs.existsSync(nmPath) &&
299
+ fs
242
300
  .statSync(nmPath, {
243
301
  throwIfNoEntry: false
244
302
  })
@@ -246,7 +304,7 @@ function findNpmPathSync(npmBinPath) {
246
304
  // Optimistically look for the default location.
247
305
  (path.basename(thePath) === NPM$1 ||
248
306
  // Chocolatey installs npm bins in the same directory as node bins.
249
- (WIN32 && require$$0.existsSync(path.join(thePath, `${NPM$1}.cmd`))))
307
+ (WIN32 && fs.existsSync(path.join(thePath, `${NPM$1}.cmd`))))
250
308
  ) {
251
309
  return thePath
252
310
  }
@@ -265,7 +323,7 @@ async function getPackageFilesForScan(cwd, inputPaths, supportedFiles, config) {
265
323
 
266
324
  // Lazily access constants.spinner.
267
325
  const { spinner } = constants
268
- const patterns = pathsToPatterns(inputPaths)
326
+ const patterns = pathsToGlobPatterns(inputPaths)
269
327
  spinner.start('Searching for local files to include in scan...')
270
328
  const entries = await globWithGitIgnore(patterns, {
271
329
  cwd,
@@ -371,7 +429,7 @@ function getNpmRequire() {
371
429
  const npmNmPath = path.join(npmPath, NODE_MODULES, NPM)
372
430
  _npmRequire = Module.createRequire(
373
431
  path.join(
374
- require$$0.existsSync(npmNmPath) ? npmNmPath : npmPath,
432
+ fs.existsSync(npmNmPath) ? npmNmPath : npmPath,
375
433
  '<dummy-basename>'
376
434
  )
377
435
  )
@@ -450,7 +508,8 @@ exports.getNpmBinPath = getNpmBinPath
450
508
  exports.getNpmRequire = getNpmRequire
451
509
  exports.getNpxBinPath = getNpxBinPath
452
510
  exports.getPackageFilesForScan = getPackageFilesForScan
511
+ exports.globWorkspace = globWorkspace
453
512
  exports.isNpmBinPathShadowed = isNpmBinPathShadowed
454
513
  exports.isNpxBinPathShadowed = isNpxBinPathShadowed
455
- //# debugId=94de2f72-f785-4ee7-85de-932aaba92a8e
514
+ //# debugId=e333b4b6-8d6d-4e14-b5aa-429279ab5db0
456
515
  //# sourceMappingURL=shadow-npm-paths.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shadow-npm-paths.js","sources":["../../src/utils/ignore-by-default.ts","../../src/utils/path-resolve.ts","../../src/shadow/npm/paths.ts"],"sourcesContent":["const ignoredDirs = [\n // Taken from ignore-by-default:\n // https://github.com/novemberborn/ignore-by-default/blob/v2.1.0/index.js\n '.git', // Git repository files, see <https://git-scm.com/>\n '.log', // Log files emitted by tools such as `tsserver`, see <https://github.com/Microsoft/TypeScript/wiki/Standalone-Server-%28tsserver%29>\n '.nyc_output', // Temporary directory where nyc stores coverage data, see <https://github.com/bcoe/nyc>\n '.sass-cache', // Cache folder for node-sass, see <https://github.com/sass/node-sass>\n '.yarn', // Where node modules are installed when using Yarn, see <https://yarnpkg.com/>\n 'bower_components', // Where Bower packages are installed, see <http://bower.io/>\n 'coverage', // Standard output directory for code coverage reports, see <https://github.com/gotwarlost/istanbul>\n 'node_modules', // Where Node modules are installed, see <https://nodejs.org/>\n // Taken from globby:\n // https://github.com/sindresorhus/globby/blob/v14.0.2/ignore.js#L11-L16\n 'flow-typed'\n] as const\n\nconst ignoredDirPatterns = ignoredDirs.map(i => `**/${i}`)\n\nexport function directoryPatterns() {\n return [...ignoredDirPatterns]\n}\n","import { existsSync, promises as fs, statSync } from 'node:fs'\nimport path from 'node:path'\nimport process from 'node:process'\n\nimport ignore from 'ignore'\nimport micromatch from 'micromatch'\nimport { glob as tinyGlob } from 'tinyglobby'\nimport which from 'which'\n\nimport { debugLog, isDebug } from '@socketsecurity/registry/lib/debug'\nimport { resolveBinPath } from '@socketsecurity/registry/lib/npm'\nimport { pluralize } from '@socketsecurity/registry/lib/words'\n\nimport { directoryPatterns } from './ignore-by-default'\nimport constants from '../constants'\n\nimport type { SocketYml } from '@socketsecurity/config'\nimport type { SocketSdkReturnType } from '@socketsecurity/sdk'\nimport type { GlobOptions } from 'tinyglobby'\n\ntype GlobWithGitIgnoreOptions = GlobOptions & {\n socketConfig?: SocketYml | undefined\n}\n\nconst { NODE_MODULES, NPM, shadowBinPath } = constants\n\nasync function filterGlobResultToSupportedFiles(\n entries: string[],\n supportedFiles: SocketSdkReturnType<'getReportSupportedFiles'>['data']\n): Promise<string[]> {\n const patterns = ['golang', NPM, 'maven', 'pypi', 'gem', 'nuget'].reduce(\n (r: string[], n: string) => {\n const supported = supportedFiles[n]\n r.push(\n ...(supported\n ? Object.values(supported).map(p => `**/${p.pattern}`)\n : [])\n )\n return r\n },\n []\n )\n return entries.filter(p => micromatch.some(p, patterns))\n}\n\nasync function globWithGitIgnore(\n patterns: string[],\n options: GlobWithGitIgnoreOptions\n) {\n const {\n cwd = process.cwd(),\n socketConfig,\n ...additionalOptions\n } = { __proto__: null, ...options } as GlobWithGitIgnoreOptions\n const projectIgnorePaths = socketConfig?.projectIgnorePaths\n const ignoreFiles = await tinyGlob(['**/.gitignore'], {\n absolute: true,\n cwd,\n expandDirectories: true\n })\n const ignores = [\n ...directoryPatterns(),\n ...(Array.isArray(projectIgnorePaths)\n ? ignoreFileLinesToGlobPatterns(\n projectIgnorePaths,\n path.join(cwd, '.gitignore'),\n cwd\n )\n : []),\n ...(\n await Promise.all(\n ignoreFiles.map(async filepath =>\n ignoreFileToGlobPatterns(\n await fs.readFile(filepath, 'utf8'),\n filepath,\n cwd\n )\n )\n )\n ).flat()\n ]\n const hasNegatedPattern = ignores.some(p => p.charCodeAt(0) === 33 /*'!'*/)\n const globOptions = {\n absolute: true,\n cwd,\n expandDirectories: false,\n ignore: hasNegatedPattern ? [] : ignores,\n ...additionalOptions\n }\n const result = await tinyGlob(patterns, globOptions)\n if (!hasNegatedPattern) {\n return result\n }\n const { absolute } = globOptions\n\n // Note: the input files must be INSIDE the cwd. If you get strange looking\n // relative path errors here, most likely your path is outside the given cwd.\n const filtered = ignore()\n .add(ignores)\n .filter(absolute ? result.map(p => path.relative(cwd, p)) : result)\n return absolute ? filtered.map(p => path.resolve(cwd, p)) : filtered\n}\n\nfunction ignoreFileLinesToGlobPatterns(\n lines: string[],\n filepath: string,\n cwd: string\n): string[] {\n const base = path.relative(cwd, path.dirname(filepath)).replace(/\\\\/g, '/')\n const patterns = []\n for (let i = 0, { length } = lines; i < length; i += 1) {\n const pattern = lines[i]!.trim()\n if (pattern.length > 0 && pattern.charCodeAt(0) !== 35 /*'#'*/) {\n patterns.push(\n ignorePatternToMinimatch(\n pattern.length && pattern.charCodeAt(0) === 33 /*'!'*/\n ? `!${path.posix.join(base, pattern.slice(1))}`\n : path.posix.join(base, pattern)\n )\n )\n }\n }\n return patterns\n}\n\nfunction ignoreFileToGlobPatterns(\n content: string,\n filepath: string,\n cwd: string\n): string[] {\n return ignoreFileLinesToGlobPatterns(content.split(/\\r?\\n/), filepath, cwd)\n}\n\n// Based on `@eslint/compat` convertIgnorePatternToMinimatch.\n// Apache v2.0 licensed\n// Copyright Nicholas C. Zakas\n// https://github.com/eslint/rewrite/blob/compat-v1.2.1/packages/compat/src/ignore-file.js#L28\nfunction ignorePatternToMinimatch(pattern: string): string {\n const isNegated = pattern.startsWith('!')\n const negatedPrefix = isNegated ? '!' : ''\n const patternToTest = (isNegated ? pattern.slice(1) : pattern).trimEnd()\n // Special cases.\n if (\n patternToTest === '' ||\n patternToTest === '**' ||\n patternToTest === '/**' ||\n patternToTest === '**'\n ) {\n return `${negatedPrefix}${patternToTest}`\n }\n const firstIndexOfSlash = patternToTest.indexOf('/')\n const matchEverywherePrefix =\n firstIndexOfSlash === -1 || firstIndexOfSlash === patternToTest.length - 1\n ? '**/'\n : ''\n const patternWithoutLeadingSlash =\n firstIndexOfSlash === 0 ? patternToTest.slice(1) : patternToTest\n // Escape `{` and `(` because in gitignore patterns they are just\n // literal characters without any specific syntactic meaning,\n // while in minimatch patterns they can form brace expansion or extglob syntax.\n //\n // For example, gitignore pattern `src/{a,b}.js` ignores file `src/{a,b}.js`.\n // But, the same minimatch pattern `src/{a,b}.js` ignores files `src/a.js` and `src/b.js`.\n // Minimatch pattern `src/\\{a,b}.js` is equivalent to gitignore pattern `src/{a,b}.js`.\n const escapedPatternWithoutLeadingSlash =\n patternWithoutLeadingSlash.replaceAll(\n /(?=((?:\\\\.|[^{(])*))\\1([{(])/guy,\n '$1\\\\$2'\n )\n const matchInsideSuffix = patternToTest.endsWith('/**') ? '/*' : ''\n return `${negatedPrefix}${matchEverywherePrefix}${escapedPatternWithoutLeadingSlash}${matchInsideSuffix}`\n}\n\nfunction pathsToPatterns(paths: string[] | readonly string[]): string[] {\n // TODO: Does not support `~/` paths.\n return paths.map(p => (p === '.' || p === './' ? '**/*' : p))\n}\n\nexport function findBinPathDetailsSync(binName: string): {\n name: string\n path: string | undefined\n shadowed: boolean\n} {\n const binPaths =\n which.sync(binName, {\n all: true,\n nothrow: true\n }) ?? []\n let shadowIndex = -1\n let theBinPath: string | undefined\n for (let i = 0, { length } = binPaths; i < length; i += 1) {\n const binPath = binPaths[i]!\n // Skip our bin directory if it's in the front.\n if (path.dirname(binPath) === shadowBinPath) {\n shadowIndex = i\n } else {\n theBinPath = resolveBinPath(binPath)\n break\n }\n }\n return { name: binName, path: theBinPath, shadowed: shadowIndex !== -1 }\n}\n\nexport function findNpmPathSync(npmBinPath: string): string | undefined {\n // Lazily access constants.WIN32.\n const { WIN32 } = constants\n let thePath = npmBinPath\n while (true) {\n const libNmNpmPath = path.join(thePath, 'lib', NODE_MODULES, NPM)\n // mise puts its npm bin in a path like:\n // /Users/SomeUsername/.local/share/mise/installs/node/vX.X.X/bin/npm.\n // HOWEVER, the location of the npm install is:\n // /Users/SomeUsername/.local/share/mise/installs/node/vX.X.X/lib/node_modules/npm.\n if (\n // Use existsSync here because statsSync, even with { throwIfNoEntry: false },\n // will throw an ENOTDIR error for paths like ./a-file-that-exists/a-directory-that-does-not.\n // See https://github.com/nodejs/node/issues/56993.\n existsSync(libNmNpmPath) &&\n statSync(libNmNpmPath, { throwIfNoEntry: false })?.isDirectory()\n ) {\n thePath = path.join(libNmNpmPath, NPM)\n }\n const nmPath = path.join(thePath, NODE_MODULES)\n if (\n // npm bin paths may look like:\n // /usr/local/share/npm/bin/npm\n // /Users/SomeUsername/.nvm/versions/node/vX.X.X/bin/npm\n // C:\\Users\\SomeUsername\\AppData\\Roaming\\npm\\bin\\npm.cmd\n // OR\n // C:\\Program Files\\nodejs\\npm.cmd\n //\n // In practically all cases the npm path contains a node_modules folder:\n // /usr/local/share/npm/bin/npm/node_modules\n // C:\\Program Files\\nodejs\\node_modules\n existsSync(nmPath) &&\n statSync(nmPath, { throwIfNoEntry: false })?.isDirectory() &&\n // Optimistically look for the default location.\n (path.basename(thePath) === NPM ||\n // Chocolatey installs npm bins in the same directory as node bins.\n (WIN32 && existsSync(path.join(thePath, `${NPM}.cmd`))))\n ) {\n return thePath\n }\n const parent = path.dirname(thePath)\n if (parent === thePath) {\n return undefined\n }\n thePath = parent\n }\n}\n\nexport async function getPackageFilesForScan(\n cwd: string,\n inputPaths: string[],\n supportedFiles: SocketSdkReturnType<'getReportSupportedFiles'>['data'],\n config?: SocketYml | undefined\n): Promise<string[]> {\n debugLog(\n `getPackageFilesForScan: resolving ${inputPaths.length} paths:\\n`,\n inputPaths\n )\n\n // Lazily access constants.spinner.\n const { spinner } = constants\n\n const patterns = pathsToPatterns(inputPaths)\n\n spinner.start('Searching for local files to include in scan...')\n\n const entries = await globWithGitIgnore(patterns, {\n cwd,\n socketConfig: config\n })\n\n if (isDebug()) {\n spinner.stop()\n debugLog(\n `Resolved ${inputPaths.length} paths to ${entries.length} local paths:\\n`,\n entries\n )\n spinner.start('Searching for files now...')\n } else {\n spinner.start(\n `Resolved ${inputPaths.length} paths to ${entries.length} local paths, searching for files now...`\n )\n }\n\n const packageFiles = await filterGlobResultToSupportedFiles(\n entries,\n supportedFiles\n )\n\n spinner.successAndStop(\n `Found ${packageFiles.length} local ${pluralize('file', packageFiles.length)}`\n )\n debugLog('Absolute paths:\\n', packageFiles)\n\n return packageFiles\n}\n","import { existsSync } from 'node:fs'\nimport Module from 'node:module'\nimport path from 'node:path'\nimport process from 'node:process'\n\nimport { logger } from '@socketsecurity/registry/lib/logger'\nimport { normalizePath } from '@socketsecurity/registry/lib/path'\n\nimport constants from '../../constants'\nimport {\n findBinPathDetailsSync,\n findNpmPathSync\n} from '../../utils/path-resolve'\n\nconst { NODE_MODULES, NPM, NPX, SOCKET_CLI_ISSUES_URL } = constants\n\nfunction exitWithBinPathError(binName: string): never {\n logger.fail(\n `Socket unable to locate ${binName}; ensure it is available in the PATH environment variable`\n )\n // The exit code 127 indicates that the command or binary being executed\n // could not be found.\n // eslint-disable-next-line n/no-process-exit\n process.exit(127)\n}\n\nlet _npmBinPathDetails: ReturnType<typeof findBinPathDetailsSync> | undefined\nfunction getNpmBinPathDetails(): ReturnType<typeof findBinPathDetailsSync> {\n if (_npmBinPathDetails === undefined) {\n _npmBinPathDetails = findBinPathDetailsSync(NPM)\n }\n return _npmBinPathDetails\n}\n\nlet _npxBinPathDetails: ReturnType<typeof findBinPathDetailsSync> | undefined\nfunction getNpxBinPathDetails(): ReturnType<typeof findBinPathDetailsSync> {\n if (_npxBinPathDetails === undefined) {\n _npxBinPathDetails = findBinPathDetailsSync(NPX)\n }\n return _npxBinPathDetails\n}\n\nlet _npmBinPath: string | undefined\nexport function getNpmBinPath(): string {\n if (_npmBinPath === undefined) {\n _npmBinPath = getNpmBinPathDetails().path\n if (!_npmBinPath) {\n exitWithBinPathError(NPM)\n }\n }\n return _npmBinPath\n}\n\nexport function isNpmBinPathShadowed() {\n return getNpmBinPathDetails().shadowed\n}\n\nlet _npxBinPath: string | undefined\nexport function getNpxBinPath(): string {\n if (_npxBinPath === undefined) {\n _npxBinPath = getNpxBinPathDetails().path\n if (!_npxBinPath) {\n exitWithBinPathError(NPX)\n }\n }\n return _npxBinPath\n}\n\nexport function isNpxBinPathShadowed() {\n return getNpxBinPathDetails().shadowed\n}\n\nlet _npmPath: string | undefined\nexport function getNpmPath() {\n if (_npmPath === undefined) {\n const npmBinPath = getNpmBinPath()\n _npmPath = npmBinPath ? findNpmPathSync(npmBinPath) : undefined\n if (!_npmPath) {\n let message = 'Unable to find npm CLI install directory.'\n if (npmBinPath) {\n message += `\\nSearched parent directories of ${path.dirname(npmBinPath)}.`\n }\n message += `\\n\\nThis is may be a bug with socket-npm related to changes to the npm CLI.\\nPlease report to ${SOCKET_CLI_ISSUES_URL}.`\n logger.fail(message)\n // The exit code 127 indicates that the command or binary being executed\n // could not be found.\n // eslint-disable-next-line n/no-process-exit\n process.exit(127)\n }\n }\n return _npmPath\n}\n\nlet _npmRequire: NodeJS.Require | undefined\nexport function getNpmRequire(): NodeJS.Require {\n if (_npmRequire === undefined) {\n const npmPath = getNpmPath()\n const npmNmPath = path.join(npmPath, NODE_MODULES, NPM)\n _npmRequire = Module.createRequire(\n path.join(existsSync(npmNmPath) ? npmNmPath : npmPath, '<dummy-basename>')\n )\n }\n return _npmRequire\n}\n\nlet _arboristPkgPath: string | undefined\nexport function getArboristPackagePath() {\n if (_arboristPkgPath === undefined) {\n const pkgName = '@npmcli/arborist'\n const mainPathWithForwardSlashes = normalizePath(\n getNpmRequire().resolve(pkgName)\n )\n const arboristPkgPathWithForwardSlashes = mainPathWithForwardSlashes.slice(\n 0,\n mainPathWithForwardSlashes.lastIndexOf(pkgName) + pkgName.length\n )\n // Lazily access constants.WIN32.\n _arboristPkgPath = constants.WIN32\n ? path.normalize(arboristPkgPathWithForwardSlashes)\n : arboristPkgPathWithForwardSlashes\n }\n return _arboristPkgPath\n}\n\nlet _arboristClassPath: string | undefined\nexport function getArboristClassPath() {\n if (_arboristClassPath === undefined) {\n _arboristClassPath = path.join(\n getArboristPackagePath(),\n 'lib/arborist/index.js'\n )\n }\n return _arboristClassPath\n}\n\nlet _arboristDepValidPath: string | undefined\nexport function getArboristDepValidPath() {\n if (_arboristDepValidPath === undefined) {\n _arboristDepValidPath = path.join(\n getArboristPackagePath(),\n 'lib/dep-valid.js'\n )\n }\n return _arboristDepValidPath\n}\n\nlet _arboristEdgeClassPath: string | undefined\nexport function getArboristEdgeClassPath() {\n if (_arboristEdgeClassPath === undefined) {\n _arboristEdgeClassPath = path.join(getArboristPackagePath(), 'lib/edge.js')\n }\n return _arboristEdgeClassPath\n}\n\nlet _arboristNodeClassPath: string | undefined\nexport function getArboristNodeClassPath() {\n if (_arboristNodeClassPath === undefined) {\n _arboristNodeClassPath = path.join(getArboristPackagePath(), 'lib/node.js')\n }\n return _arboristNodeClassPath\n}\n\nlet _arboristOverrideSetClassPath: string | undefined\nexport function getArboristOverrideSetClassPath() {\n if (_arboristOverrideSetClassPath === undefined) {\n _arboristOverrideSetClassPath = path.join(\n getArboristPackagePath(),\n 'lib/override-set.js'\n )\n }\n return _arboristOverrideSetClassPath\n}\n"],"names":["shadowBinPath","cwd","__proto__","absolute","expandDirectories","ignore","length","all","nothrow","shadowIndex","theBinPath","name","path","WIN32","existsSync","throwIfNoEntry","thePath","spinner","socketConfig","debugLog","SOCKET_CLI_ISSUES_URL","logger","process","_npmBinPathDetails","_npxBinPathDetails","_npmBinPath","_npxBinPath","_arboristPkgPath"],"mappings":";;;;;;;;;;;;;;AAAA;AACE;AACA;AACA;AAAQ;AACR;AAAQ;AACR;AAAe;AACf;AAAe;AACf;AAAS;AACT;AAAoB;AACpB;AAAY;AACZ;AAAgB;AAChB;AACA;AACA;AAGF;AAEO;;AAEP;;ACIA;;;AAA2BA;AAAc;AAEzC;;AAMM;;AAMA;;AAIJ;AACF;AAEA;;AAKIC;;;AAGF;AAAMC;;;AACN;;AAEEC;;AAEAC;AACF;AACA;AAqBA;AACA;AACED;;AAEAC;AACAC;;;;;AAKA;AACF;;AACQF;AAAS;;AAEjB;AACA;AACA;AAGA;AACF;AAEA;;;AAOE;AAAkBG;;;AAEhB;;AAQA;AACF;AACA;AACF;AAEA;AAKE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACE;AACA;AACA;AACA;AACA;AAME;AACF;AACA;AACA;AAIA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAQF;AAEA;AACE;AACA;AACF;AAEO;AAKL;AAEIC;AACAC;;;AAGJ;AACA;AAAkBF;;AAChB;AACA;;AAEEG;AACF;AACEC;AACA;AACF;AACF;;AACSC;AAAeC;;;AAC1B;AAEO;AACL;;AACQC;AAAM;;AAEd;AACE;AACA;AACA;AACA;AACA;AACA;AACE;AACA;AACA;AACAC;AACyBC;AAAsB;;AAGjD;;AAEA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACAD;AACmBC;AAAsB;AACzC;AACCH;AACC;AACCC;AAEH;AACF;AACA;;AAEE;AACF;AACAG;AACF;AACF;AAEO;;;AAWL;;AACQC;AAAQ;AAEhB;AAEAA;AAEA;;AAEEC;AACF;;;AAIEC;AAIAF;AACF;AACEA;AAGF;;AAOAA;AAGAE;AAEA;AACF;;AC5RA;;;;AAAgCC;AAAsB;AAEtD;AACEC;AAGA;AACA;AACA;AACAC;AACF;AAEA;AACA;;AAEIC;AACF;AACA;AACF;AAEA;AACA;;AAEIC;AACF;AACA;AACF;AAEA;AACO;;AAEHC;;;AAGA;AACF;AACA;AACF;AAEO;AACL;AACF;AAEA;AACO;;AAEHC;;;AAGA;AACF;AACA;AACF;AAEO;AACL;AACF;AAEA;AACO;;AAEH;;;;AAIE;;AAEA;;AAEAL;AACA;AACA;AACA;AACAC;AACF;AACF;AACA;AACF;AAEA;AACO;;AAEH;;;AAKF;AACA;AACF;AAEA;AACO;;;AAGH;AAGA;AAIA;AACAK;AAGF;AACA;AACF;AAEA;AACO;;;AAML;AACA;AACF;AAEA;AACO;;;AAML;AACA;AACF;AAEA;AACO;;;AAGL;AACA;AACF;AAEA;AACO;;;AAGL;AACA;AACF;AAEA;AACO;;;AAML;AACA;AACF;;;;;;;;;;;;","debugId":"94de2f72-f785-4ee7-85de-932aaba92a8e"}
1
+ {"version":3,"file":"shadow-npm-paths.js","sources":["../../src/utils/glob.ts","../../src/utils/path-resolve.ts","../../src/shadow/npm/paths.ts"],"sourcesContent":["import { promises as fs } from 'node:fs'\nimport path from 'node:path'\nimport process from 'node:process'\n\nimport ignore from 'ignore'\nimport micromatch from 'micromatch'\nimport { glob as tinyGlob } from 'tinyglobby'\nimport { parse as yamlParse } from 'yaml'\n\nimport { isNonEmptyString } from '@socketsecurity/registry/lib/strings'\n\nimport constants from '../constants'\nimport { safeReadFile } from './fs'\n\nimport type { EnvDetails } from './package-environment'\nimport type { SocketYml } from '@socketsecurity/config'\nimport type { SocketSdkReturnType } from '@socketsecurity/sdk'\nimport type { GlobOptions } from 'tinyglobby'\n\nconst { NPM, PNPM } = constants\n\nconst PNPM_WORKSPACE = `${PNPM}-workspace`\n\nconst ignoredDirs = [\n // Taken from ignore-by-default:\n // https://github.com/novemberborn/ignore-by-default/blob/v2.1.0/index.js\n '.git', // Git repository files, see <https://git-scm.com/>\n '.log', // Log files emitted by tools such as `tsserver`, see <https://github.com/Microsoft/TypeScript/wiki/Standalone-Server-%28tsserver%29>\n '.nyc_output', // Temporary directory where nyc stores coverage data, see <https://github.com/bcoe/nyc>\n '.sass-cache', // Cache folder for node-sass, see <https://github.com/sass/node-sass>\n '.yarn', // Where node modules are installed when using Yarn, see <https://yarnpkg.com/>\n 'bower_components', // Where Bower packages are installed, see <http://bower.io/>\n 'coverage', // Standard output directory for code coverage reports, see <https://github.com/gotwarlost/istanbul>\n 'node_modules', // Where Node modules are installed, see <https://nodejs.org/>\n // Taken from globby:\n // https://github.com/sindresorhus/globby/blob/v14.0.2/ignore.js#L11-L16\n 'flow-typed'\n] as const\n\nconst ignoredDirPatterns = ignoredDirs.map(i => `**/${i}`)\n\nasync function getWorkspaceGlobs(pkgEnvDetails: EnvDetails): Promise<string[]> {\n let workspacePatterns\n if (pkgEnvDetails.agent === PNPM) {\n for (const workspacePath of [\n path.join(pkgEnvDetails.pkgPath, `${PNPM_WORKSPACE}.yaml`),\n path.join(pkgEnvDetails.pkgPath, `${PNPM_WORKSPACE}.yml`)\n ]) {\n // eslint-disable-next-line no-await-in-loop\n const yml = await safeReadFile(workspacePath)\n if (yml) {\n try {\n workspacePatterns = yamlParse(yml)?.packages\n } catch {}\n if (workspacePatterns) {\n break\n }\n }\n }\n } else {\n workspacePatterns = pkgEnvDetails.editablePkgJson.content['workspaces']\n }\n return Array.isArray(workspacePatterns)\n ? workspacePatterns\n .filter(isNonEmptyString)\n .map(workspacePatternToGlobPattern)\n : []\n}\n\nfunction ignoreFileLinesToGlobPatterns(\n lines: string[] | readonly string[],\n filepath: string,\n cwd: string\n): string[] {\n const base = path.relative(cwd, path.dirname(filepath)).replace(/\\\\/g, '/')\n const patterns = []\n for (let i = 0, { length } = lines; i < length; i += 1) {\n const pattern = lines[i]!.trim()\n if (pattern.length > 0 && pattern.charCodeAt(0) !== 35 /*'#'*/) {\n patterns.push(\n ignorePatternToMinimatch(\n pattern.length && pattern.charCodeAt(0) === 33 /*'!'*/\n ? `!${path.posix.join(base, pattern.slice(1))}`\n : path.posix.join(base, pattern)\n )\n )\n }\n }\n return patterns\n}\n\nfunction ignoreFileToGlobPatterns(\n content: string,\n filepath: string,\n cwd: string\n): string[] {\n return ignoreFileLinesToGlobPatterns(content.split(/\\r?\\n/), filepath, cwd)\n}\n\n// Based on `@eslint/compat` convertIgnorePatternToMinimatch.\n// Apache v2.0 licensed\n// Copyright Nicholas C. Zakas\n// https://github.com/eslint/rewrite/blob/compat-v1.2.1/packages/compat/src/ignore-file.js#L28\nfunction ignorePatternToMinimatch(pattern: string): string {\n const isNegated = pattern.startsWith('!')\n const negatedPrefix = isNegated ? '!' : ''\n const patternToTest = (isNegated ? pattern.slice(1) : pattern).trimEnd()\n // Special cases.\n if (\n patternToTest === '' ||\n patternToTest === '**' ||\n patternToTest === '/**' ||\n patternToTest === '**'\n ) {\n return `${negatedPrefix}${patternToTest}`\n }\n const firstIndexOfSlash = patternToTest.indexOf('/')\n const matchEverywherePrefix =\n firstIndexOfSlash === -1 || firstIndexOfSlash === patternToTest.length - 1\n ? '**/'\n : ''\n const patternWithoutLeadingSlash =\n firstIndexOfSlash === 0 ? patternToTest.slice(1) : patternToTest\n // Escape `{` and `(` because in gitignore patterns they are just\n // literal characters without any specific syntactic meaning,\n // while in minimatch patterns they can form brace expansion or extglob syntax.\n //\n // For example, gitignore pattern `src/{a,b}.js` ignores file `src/{a,b}.js`.\n // But, the same minimatch pattern `src/{a,b}.js` ignores files `src/a.js` and `src/b.js`.\n // Minimatch pattern `src/\\{a,b}.js` is equivalent to gitignore pattern `src/{a,b}.js`.\n const escapedPatternWithoutLeadingSlash =\n patternWithoutLeadingSlash.replaceAll(\n /(?=((?:\\\\.|[^{(])*))\\1([{(])/guy,\n '$1\\\\$2'\n )\n const matchInsideSuffix = patternToTest.endsWith('/**') ? '/*' : ''\n return `${negatedPrefix}${matchEverywherePrefix}${escapedPatternWithoutLeadingSlash}${matchInsideSuffix}`\n}\n\nfunction workspacePatternToGlobPattern(workspace: string): string {\n const { length } = workspace\n if (!length) {\n return ''\n }\n // If the workspace ends with \"/\"\n if (workspace.charCodeAt(length - 1) === 47 /*'/'*/) {\n return `${workspace}/*/package.json`\n }\n // If the workspace ends with \"/**\"\n if (\n workspace.charCodeAt(length - 1) === 42 /*'*'*/ &&\n workspace.charCodeAt(length - 2) === 42 /*'*'*/ &&\n workspace.charCodeAt(length - 3) === 47 /*'/'*/\n ) {\n return `${workspace}/*/**/package.json`\n }\n // Things like \"packages/a\" or \"packages/*\"\n return `${workspace}/package.json`\n}\n\nexport async function filterGlobResultToSupportedFiles(\n entries: string[] | readonly string[],\n supportedFiles: SocketSdkReturnType<'getReportSupportedFiles'>['data']\n): Promise<string[]> {\n const patterns = ['golang', NPM, 'maven', 'pypi', 'gem', 'nuget'].reduce(\n (r: string[], n: string) => {\n const supported = supportedFiles[n]\n r.push(\n ...(supported\n ? Object.values(supported).map(p => `**/${p.pattern}`)\n : [])\n )\n return r\n },\n []\n )\n return entries.filter(p => micromatch.some(p, patterns))\n}\n\ntype GlobWithGitIgnoreOptions = GlobOptions & {\n socketConfig?: SocketYml | undefined\n}\n\nexport async function globWithGitIgnore(\n patterns: string[] | readonly string[],\n options: GlobWithGitIgnoreOptions\n) {\n const {\n cwd = process.cwd(),\n socketConfig,\n ...additionalOptions\n } = { __proto__: null, ...options } as GlobWithGitIgnoreOptions\n const projectIgnorePaths = socketConfig?.projectIgnorePaths\n const ignoreFiles = await tinyGlob(['**/.gitignore'], {\n absolute: true,\n cwd,\n expandDirectories: true\n })\n const ignores = [\n ...ignoredDirPatterns,\n ...(Array.isArray(projectIgnorePaths)\n ? ignoreFileLinesToGlobPatterns(\n projectIgnorePaths,\n path.join(cwd, '.gitignore'),\n cwd\n )\n : []),\n ...(\n await Promise.all(\n ignoreFiles.map(async filepath =>\n ignoreFileToGlobPatterns(\n await fs.readFile(filepath, 'utf8'),\n filepath,\n cwd\n )\n )\n )\n ).flat()\n ]\n const hasNegatedPattern = ignores.some(p => p.charCodeAt(0) === 33 /*'!'*/)\n const globOptions = {\n absolute: true,\n cwd,\n expandDirectories: false,\n ignore: hasNegatedPattern ? [] : ignores,\n ...additionalOptions\n }\n const result = await tinyGlob(patterns as string[], globOptions)\n if (!hasNegatedPattern) {\n return result\n }\n const { absolute } = globOptions\n\n // Note: the input files must be INSIDE the cwd. If you get strange looking\n // relative path errors here, most likely your path is outside the given cwd.\n const filtered = ignore()\n .add(ignores)\n .filter(absolute ? result.map(p => path.relative(cwd, p)) : result)\n return absolute ? filtered.map(p => path.resolve(cwd, p)) : filtered\n}\n\nexport async function globWorkspace(\n pkgEnvDetails: EnvDetails\n): Promise<string[]> {\n const workspaceGlobs = await getWorkspaceGlobs(pkgEnvDetails)\n return workspaceGlobs.length\n ? await tinyGlob(workspaceGlobs, {\n absolute: true,\n cwd: pkgEnvDetails.pkgPath,\n ignore: ['**/node_modules/**', '**/bower_components/**']\n })\n : []\n}\n\nexport function pathsToGlobPatterns(\n paths: string[] | readonly string[]\n): string[] {\n // TODO: Does not support `~/` paths.\n return paths.map(p => (p === '.' || p === './' ? '**/*' : p))\n}\n","import { existsSync, statSync } from 'node:fs'\nimport path from 'node:path'\n\nimport which from 'which'\n\nimport { debugLog, isDebug } from '@socketsecurity/registry/lib/debug'\nimport { resolveBinPath } from '@socketsecurity/registry/lib/npm'\nimport { pluralize } from '@socketsecurity/registry/lib/words'\n\nimport constants from '../constants'\nimport {\n filterGlobResultToSupportedFiles,\n globWithGitIgnore,\n pathsToGlobPatterns\n} from './glob'\n\nimport type { SocketYml } from '@socketsecurity/config'\nimport type { SocketSdkReturnType } from '@socketsecurity/sdk'\n\nconst { NODE_MODULES, NPM, shadowBinPath } = constants\n\nexport function findBinPathDetailsSync(binName: string): {\n name: string\n path: string | undefined\n shadowed: boolean\n} {\n const binPaths =\n which.sync(binName, {\n all: true,\n nothrow: true\n }) ?? []\n let shadowIndex = -1\n let theBinPath: string | undefined\n for (let i = 0, { length } = binPaths; i < length; i += 1) {\n const binPath = binPaths[i]!\n // Skip our bin directory if it's in the front.\n if (path.dirname(binPath) === shadowBinPath) {\n shadowIndex = i\n } else {\n theBinPath = resolveBinPath(binPath)\n break\n }\n }\n return { name: binName, path: theBinPath, shadowed: shadowIndex !== -1 }\n}\n\nexport function findNpmPathSync(npmBinPath: string): string | undefined {\n // Lazily access constants.WIN32.\n const { WIN32 } = constants\n let thePath = npmBinPath\n while (true) {\n const libNmNpmPath = path.join(thePath, 'lib', NODE_MODULES, NPM)\n // mise puts its npm bin in a path like:\n // /Users/SomeUsername/.local/share/mise/installs/node/vX.X.X/bin/npm.\n // HOWEVER, the location of the npm install is:\n // /Users/SomeUsername/.local/share/mise/installs/node/vX.X.X/lib/node_modules/npm.\n if (\n // Use existsSync here because statsSync, even with { throwIfNoEntry: false },\n // will throw an ENOTDIR error for paths like ./a-file-that-exists/a-directory-that-does-not.\n // See https://github.com/nodejs/node/issues/56993.\n existsSync(libNmNpmPath) &&\n statSync(libNmNpmPath, { throwIfNoEntry: false })?.isDirectory()\n ) {\n thePath = path.join(libNmNpmPath, NPM)\n }\n const nmPath = path.join(thePath, NODE_MODULES)\n if (\n // npm bin paths may look like:\n // /usr/local/share/npm/bin/npm\n // /Users/SomeUsername/.nvm/versions/node/vX.X.X/bin/npm\n // C:\\Users\\SomeUsername\\AppData\\Roaming\\npm\\bin\\npm.cmd\n // OR\n // C:\\Program Files\\nodejs\\npm.cmd\n //\n // In practically all cases the npm path contains a node_modules folder:\n // /usr/local/share/npm/bin/npm/node_modules\n // C:\\Program Files\\nodejs\\node_modules\n existsSync(nmPath) &&\n statSync(nmPath, { throwIfNoEntry: false })?.isDirectory() &&\n // Optimistically look for the default location.\n (path.basename(thePath) === NPM ||\n // Chocolatey installs npm bins in the same directory as node bins.\n (WIN32 && existsSync(path.join(thePath, `${NPM}.cmd`))))\n ) {\n return thePath\n }\n const parent = path.dirname(thePath)\n if (parent === thePath) {\n return undefined\n }\n thePath = parent\n }\n}\n\nexport async function getPackageFilesForScan(\n cwd: string,\n inputPaths: string[],\n supportedFiles: SocketSdkReturnType<'getReportSupportedFiles'>['data'],\n config?: SocketYml | undefined\n): Promise<string[]> {\n debugLog(\n `getPackageFilesForScan: resolving ${inputPaths.length} paths:\\n`,\n inputPaths\n )\n\n // Lazily access constants.spinner.\n const { spinner } = constants\n\n const patterns = pathsToGlobPatterns(inputPaths)\n\n spinner.start('Searching for local files to include in scan...')\n\n const entries = await globWithGitIgnore(patterns, {\n cwd,\n socketConfig: config\n })\n\n if (isDebug()) {\n spinner.stop()\n debugLog(\n `Resolved ${inputPaths.length} paths to ${entries.length} local paths:\\n`,\n entries\n )\n spinner.start('Searching for files now...')\n } else {\n spinner.start(\n `Resolved ${inputPaths.length} paths to ${entries.length} local paths, searching for files now...`\n )\n }\n\n const packageFiles = await filterGlobResultToSupportedFiles(\n entries,\n supportedFiles\n )\n\n spinner.successAndStop(\n `Found ${packageFiles.length} local ${pluralize('file', packageFiles.length)}`\n )\n debugLog('Absolute paths:\\n', packageFiles)\n\n return packageFiles\n}\n","import { existsSync } from 'node:fs'\nimport Module from 'node:module'\nimport path from 'node:path'\nimport process from 'node:process'\n\nimport { logger } from '@socketsecurity/registry/lib/logger'\nimport { normalizePath } from '@socketsecurity/registry/lib/path'\n\nimport constants from '../../constants'\nimport {\n findBinPathDetailsSync,\n findNpmPathSync\n} from '../../utils/path-resolve'\n\nconst { NODE_MODULES, NPM, NPX, SOCKET_CLI_ISSUES_URL } = constants\n\nfunction exitWithBinPathError(binName: string): never {\n logger.fail(\n `Socket unable to locate ${binName}; ensure it is available in the PATH environment variable`\n )\n // The exit code 127 indicates that the command or binary being executed\n // could not be found.\n // eslint-disable-next-line n/no-process-exit\n process.exit(127)\n}\n\nlet _npmBinPathDetails: ReturnType<typeof findBinPathDetailsSync> | undefined\nfunction getNpmBinPathDetails(): ReturnType<typeof findBinPathDetailsSync> {\n if (_npmBinPathDetails === undefined) {\n _npmBinPathDetails = findBinPathDetailsSync(NPM)\n }\n return _npmBinPathDetails\n}\n\nlet _npxBinPathDetails: ReturnType<typeof findBinPathDetailsSync> | undefined\nfunction getNpxBinPathDetails(): ReturnType<typeof findBinPathDetailsSync> {\n if (_npxBinPathDetails === undefined) {\n _npxBinPathDetails = findBinPathDetailsSync(NPX)\n }\n return _npxBinPathDetails\n}\n\nlet _npmBinPath: string | undefined\nexport function getNpmBinPath(): string {\n if (_npmBinPath === undefined) {\n _npmBinPath = getNpmBinPathDetails().path\n if (!_npmBinPath) {\n exitWithBinPathError(NPM)\n }\n }\n return _npmBinPath\n}\n\nexport function isNpmBinPathShadowed() {\n return getNpmBinPathDetails().shadowed\n}\n\nlet _npxBinPath: string | undefined\nexport function getNpxBinPath(): string {\n if (_npxBinPath === undefined) {\n _npxBinPath = getNpxBinPathDetails().path\n if (!_npxBinPath) {\n exitWithBinPathError(NPX)\n }\n }\n return _npxBinPath\n}\n\nexport function isNpxBinPathShadowed() {\n return getNpxBinPathDetails().shadowed\n}\n\nlet _npmPath: string | undefined\nexport function getNpmPath() {\n if (_npmPath === undefined) {\n const npmBinPath = getNpmBinPath()\n _npmPath = npmBinPath ? findNpmPathSync(npmBinPath) : undefined\n if (!_npmPath) {\n let message = 'Unable to find npm CLI install directory.'\n if (npmBinPath) {\n message += `\\nSearched parent directories of ${path.dirname(npmBinPath)}.`\n }\n message += `\\n\\nThis is may be a bug with socket-npm related to changes to the npm CLI.\\nPlease report to ${SOCKET_CLI_ISSUES_URL}.`\n logger.fail(message)\n // The exit code 127 indicates that the command or binary being executed\n // could not be found.\n // eslint-disable-next-line n/no-process-exit\n process.exit(127)\n }\n }\n return _npmPath\n}\n\nlet _npmRequire: NodeJS.Require | undefined\nexport function getNpmRequire(): NodeJS.Require {\n if (_npmRequire === undefined) {\n const npmPath = getNpmPath()\n const npmNmPath = path.join(npmPath, NODE_MODULES, NPM)\n _npmRequire = Module.createRequire(\n path.join(existsSync(npmNmPath) ? npmNmPath : npmPath, '<dummy-basename>')\n )\n }\n return _npmRequire\n}\n\nlet _arboristPkgPath: string | undefined\nexport function getArboristPackagePath() {\n if (_arboristPkgPath === undefined) {\n const pkgName = '@npmcli/arborist'\n const mainPathWithForwardSlashes = normalizePath(\n getNpmRequire().resolve(pkgName)\n )\n const arboristPkgPathWithForwardSlashes = mainPathWithForwardSlashes.slice(\n 0,\n mainPathWithForwardSlashes.lastIndexOf(pkgName) + pkgName.length\n )\n // Lazily access constants.WIN32.\n _arboristPkgPath = constants.WIN32\n ? path.normalize(arboristPkgPathWithForwardSlashes)\n : arboristPkgPathWithForwardSlashes\n }\n return _arboristPkgPath\n}\n\nlet _arboristClassPath: string | undefined\nexport function getArboristClassPath() {\n if (_arboristClassPath === undefined) {\n _arboristClassPath = path.join(\n getArboristPackagePath(),\n 'lib/arborist/index.js'\n )\n }\n return _arboristClassPath\n}\n\nlet _arboristDepValidPath: string | undefined\nexport function getArboristDepValidPath() {\n if (_arboristDepValidPath === undefined) {\n _arboristDepValidPath = path.join(\n getArboristPackagePath(),\n 'lib/dep-valid.js'\n )\n }\n return _arboristDepValidPath\n}\n\nlet _arboristEdgeClassPath: string | undefined\nexport function getArboristEdgeClassPath() {\n if (_arboristEdgeClassPath === undefined) {\n _arboristEdgeClassPath = path.join(getArboristPackagePath(), 'lib/edge.js')\n }\n return _arboristEdgeClassPath\n}\n\nlet _arboristNodeClassPath: string | undefined\nexport function getArboristNodeClassPath() {\n if (_arboristNodeClassPath === undefined) {\n _arboristNodeClassPath = path.join(getArboristPackagePath(), 'lib/node.js')\n }\n return _arboristNodeClassPath\n}\n\nlet _arboristOverrideSetClassPath: string | undefined\nexport function getArboristOverrideSetClassPath() {\n if (_arboristOverrideSetClassPath === undefined) {\n _arboristOverrideSetClassPath = path.join(\n getArboristPackagePath(),\n 'lib/override-set.js'\n )\n }\n return _arboristOverrideSetClassPath\n}\n"],"names":["PNPM","workspacePatterns","length","cwd","__proto__","absolute","expandDirectories","ignore","shadowBinPath","all","nothrow","shadowIndex","theBinPath","name","path","WIN32","existsSync","throwIfNoEntry","thePath","spinner","socketConfig","debugLog","SOCKET_CLI_ISSUES_URL","logger","process","_npmBinPathDetails","_npxBinPathDetails","_npmBinPath","_npxBinPath","_arboristPkgPath"],"mappings":";;;;;;;;;;;;;;;;AAmBA;;AAAaA;AAAK;AAElB;AAEA;AACE;AACA;AACA;AAAQ;AACR;AAAQ;AACR;AAAe;AACf;AAAe;AACf;AAAS;AACT;AAAoB;AACpB;AAAY;AACZ;AAAgB;AAChB;AACA;AACA;AAGF;AAEA;AACE;AACA;AACE;AAIE;AACA;AACA;;AAEIC;;AAEF;AACE;AACF;AACF;AACF;AACF;;AAEA;AACA;AAKF;AAEA;;;AAOE;AAAkBC;;;AAEhB;;AAQA;AACF;AACA;AACF;AAEA;AAKE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACE;AACA;AACA;AACA;AACA;AAME;AACF;AACA;AACA;AAIA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAQF;AAEA;;AACUA;AAAO;;AAEb;AACF;AACA;;;AAGA;AACA;AACA;;AAMA;AACA;;AAEF;AAEO;;AAMD;;AAMA;;AAIJ;AACF;AAMO;;AAKHC;;;AAGF;AAAMC;;;AACN;;AAEEC;;AAEAC;AACF;AACA;AAqBA;AACA;AACED;;AAEAC;AACAC;;;;;AAKA;AACF;;AACQF;AAAS;;AAEjB;AACA;AACA;AAGA;AACF;AAEO;AAGL;;AAGMA;;AAEAE;;AAGR;AAEO;AAGL;AACA;AACF;;AChPA;;;AAA2BC;AAAc;AAElC;AAKL;AAEIC;AACAC;;;AAGJ;AACA;AAAkBR;;AAChB;AACA;;AAEES;AACF;AACEC;AACA;AACF;AACF;;AACSC;AAAeC;;;AAC1B;AAEO;AACL;;AACQC;AAAM;;AAEd;AACE;AACA;AACA;AACA;AACA;AACA;AACE;AACA;AACA;AACAC;AACyBC;AAAsB;;AAGjD;;AAEA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACAD;AACmBC;AAAsB;AACzC;AACCH;AACC;AACCC;AAEH;AACF;AACA;;AAEE;AACF;AACAG;AACF;AACF;AAEO;;;AAWL;;AACQC;AAAQ;AAEhB;AAEAA;AAEA;;AAEEC;AACF;;;AAIEC;AAIAF;AACF;AACEA;AAGF;;AAOAA;AAGAE;AAEA;AACF;;AC/HA;;;;AAAgCC;AAAsB;AAEtD;AACEC;AAGA;AACA;AACA;AACAC;AACF;AAEA;AACA;;AAEIC;AACF;AACA;AACF;AAEA;AACA;;AAEIC;AACF;AACA;AACF;AAEA;AACO;;AAEHC;;;AAGA;AACF;AACA;AACF;AAEO;AACL;AACF;AAEA;AACO;;AAEHC;;;AAGA;AACF;AACA;AACF;AAEO;AACL;AACF;AAEA;AACO;;AAEH;;;;AAIE;;AAEA;;AAEAL;AACA;AACA;AACA;AACAC;AACF;AACF;AACA;AACF;AAEA;AACO;;AAEH;;;AAKF;AACA;AACF;AAEA;AACO;;;AAGH;AAGA;AAIA;AACAK;AAGF;AACA;AACF;AAEA;AACO;;;AAML;AACA;AACF;AAEA;AACO;;;AAML;AACA;AACF;AAEA;AACO;;;AAGL;AACA;AACF;AAEA;AACO;;;AAGL;AACA;AACF;AAEA;AACO;;;AAML;AACA;AACF;;;;;;;;;;;;;","debugId":"e333b4b6-8d6d-4e14-b5aa-429279ab5db0"}