@socketsecurity/cli-with-sentry 0.14.103 → 0.14.105
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants.js +3 -3
- package/dist/constants.js.map +1 -1
- package/dist/instrument-with-sentry.js +2 -2
- package/dist/instrument-with-sentry.js.map +1 -1
- package/dist/module-sync/arborist-helpers.d.ts +69 -0
- package/dist/module-sync/cli.js +1560 -1165
- package/dist/module-sync/cli.js.map +1 -1
- package/dist/module-sync/index.d.ts +1 -1
- package/dist/module-sync/package-environment.d.ts +7 -7
- package/dist/module-sync/semver.d.ts +16 -0
- package/dist/module-sync/shadow-npm-inject.js +451 -431
- package/dist/module-sync/shadow-npm-inject.js.map +1 -1
- package/dist/module-sync/shadow-npm-paths.d.ts +23 -2
- package/dist/module-sync/shadow-npm-paths.js +135 -76
- package/dist/module-sync/shadow-npm-paths.js.map +1 -1
- package/dist/module-sync/vendor.js +25199 -25208
- package/dist/module-sync/vendor.js.map +1 -1
- package/dist/require/cli.js +1560 -1165
- package/dist/require/cli.js.map +1 -1
- package/dist/require/shadow-npm-inject.js +451 -431
- package/dist/require/shadow-npm-inject.js.map +1 -1
- package/dist/require/shadow-npm-paths.d.ts +23 -2
- package/dist/require/shadow-npm-paths.js +135 -76
- package/dist/require/shadow-npm-paths.js.map +1 -1
- package/package.json +9 -9
- package/dist/module-sync/shared.d.ts +0 -11
- package/dist/module-sync/types.d.ts +0 -27
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
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
|
|
40
|
-
|
|
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
|
-
|
|
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$
|
|
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
|
-
...
|
|
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
|
|
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
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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$
|
|
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
|
-
|
|
220
|
-
|
|
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
|
-
|
|
241
|
-
|
|
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 &&
|
|
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 =
|
|
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
|
-
|
|
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=
|
|
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"}
|