@socketsecurity/cli-with-sentry 1.1.15 → 1.1.18
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/CHANGELOG.md +15 -0
- package/dist/cli.js +14 -15
- package/dist/cli.js.map +1 -1
- package/dist/constants.js +35 -37
- package/dist/constants.js.map +1 -1
- package/dist/shadow-npm-bin.js +6 -6
- package/dist/shadow-npm-bin.js.map +1 -1
- package/dist/shadow-pnpm-bin.js +3 -5
- package/dist/shadow-pnpm-bin.js.map +1 -1
- package/dist/shadow-yarn-bin.js +2 -2
- package/dist/shadow-yarn-bin.js.map +1 -1
- package/dist/tsconfig.dts.tsbuildinfo +1 -1
- package/dist/types/commands/fix/coana-fix.d.mts.map +1 -1
- package/dist/types/commands/optimize/apply-optimization.d.mts.map +1 -1
- package/dist/types/commands/optimize/update-lockfile.d.mts.map +1 -1
- package/dist/types/commands/patch/cmd-patch.d.mts.map +1 -1
- package/dist/types/commands/patch/handle-patch.d.mts.map +1 -1
- package/dist/types/commands/yarn/cmd-yarn.d.mts +1 -1
- package/dist/types/commands/yarn/cmd-yarn.d.mts.map +1 -1
- package/dist/types/constants.d.mts +15 -19
- package/dist/types/constants.d.mts.map +1 -1
- package/dist/types/shadow/pnpm/bin.d.mts.map +1 -1
- package/dist/types/utils/agent.d.mts.map +1 -1
- package/dist/types/utils/dlx.d.mts.map +1 -1
- package/dist/types/utils/package-environment.d.mts.map +1 -1
- package/dist/types/utils/path-resolve.d.mts.map +1 -1
- package/dist/utils.js +65 -27
- package/dist/utils.js.map +1 -1
- package/dist/vendor.js +522 -524
- package/external/@socketsecurity/registry/external/@inquirer/confirm.js +45 -205
- package/external/@socketsecurity/registry/external/@inquirer/input.js +45 -205
- package/external/@socketsecurity/registry/external/@inquirer/password.js +181 -205
- package/external/@socketsecurity/registry/external/@inquirer/search.js +47 -207
- package/external/@socketsecurity/registry/external/@inquirer/select.js +183 -207
- package/external/@socketsecurity/registry/external/@npmcli/package-json/index.js +388 -2280
- package/external/@socketsecurity/registry/external/browserslist.js +11534 -567
- package/external/@socketsecurity/registry/external/cacache.js +2575 -4914
- package/external/@socketsecurity/registry/external/libnpmpack.js +64667 -166061
- package/external/@socketsecurity/registry/external/make-fetch-happen.js +384 -4044
- package/external/@socketsecurity/registry/external/normalize-package-data.js +30 -278
- package/external/@socketsecurity/registry/external/npm-package-arg.js +28 -9
- package/external/@socketsecurity/registry/external/pacote.js +46680 -66482
- package/external/@socketsecurity/registry/external/spdx-correct.js +19 -0
- package/external/@socketsecurity/registry/external/spdx-expression-parse.js +19 -0
- package/external/@socketsecurity/registry/lib/agent.js +390 -0
- package/external/@socketsecurity/registry/lib/arrays.js +31 -0
- package/external/@socketsecurity/registry/lib/bin.js +650 -0
- package/external/@socketsecurity/registry/lib/constants/bun-lock.js +3 -0
- package/external/@socketsecurity/registry/lib/constants/bun-lockb.js +3 -0
- package/external/@socketsecurity/registry/lib/constants/bun.js +3 -0
- package/external/@socketsecurity/registry/lib/constants/dot-git-dir.js +3 -0
- package/external/@socketsecurity/registry/lib/constants/dot-socket-dir.js +3 -0
- package/external/@socketsecurity/registry/lib/constants/empty-value.js +3 -0
- package/external/@socketsecurity/registry/lib/constants/env.js +17 -3
- package/external/@socketsecurity/registry/lib/constants/ext-yaml.js +3 -0
- package/external/@socketsecurity/registry/lib/constants/ext-yml.js +3 -0
- package/external/@socketsecurity/registry/lib/constants/index.js +20 -11
- package/external/@socketsecurity/registry/lib/constants/npm-exec-path.js +2 -2
- package/external/@socketsecurity/registry/lib/constants/npm-real-exec-path.js +1 -1
- package/external/@socketsecurity/registry/lib/constants/npm-shrinkwrap-json.js +3 -0
- package/external/@socketsecurity/registry/lib/constants/pnpm-exec-path.js +5 -0
- package/external/@socketsecurity/registry/lib/constants/pnpm-lock-yaml.js +3 -0
- package/external/@socketsecurity/registry/lib/constants/unknown-error.js +3 -0
- package/external/@socketsecurity/registry/lib/constants/unknown-value.js +3 -0
- package/external/@socketsecurity/registry/lib/constants/vlt-lock-json.js +3 -0
- package/external/@socketsecurity/registry/lib/constants/vlt.js +3 -0
- package/external/@socketsecurity/registry/lib/constants/yarn-berry.js +3 -0
- package/external/@socketsecurity/registry/lib/constants/yarn-classic.js +3 -0
- package/external/@socketsecurity/registry/lib/constants/yarn-exec-path.js +5 -0
- package/external/@socketsecurity/registry/lib/constants/yarn.js +3 -0
- package/external/@socketsecurity/registry/lib/debug.js +53 -0
- package/external/@socketsecurity/registry/lib/env.js +18 -0
- package/external/@socketsecurity/registry/lib/fs.js +218 -2
- package/external/@socketsecurity/registry/lib/functions.js +5 -0
- package/external/@socketsecurity/registry/lib/globs.js +22 -1
- package/external/@socketsecurity/registry/lib/json.js +16 -0
- package/external/@socketsecurity/registry/lib/logger.js +157 -0
- package/external/@socketsecurity/registry/lib/objects.js +103 -0
- package/external/@socketsecurity/registry/lib/packages.js +88 -0
- package/external/@socketsecurity/registry/lib/path.js +51 -1
- package/external/@socketsecurity/registry/lib/promises.js +55 -0
- package/external/@socketsecurity/registry/lib/regexps.js +5 -0
- package/external/@socketsecurity/registry/lib/sorts.js +17 -0
- package/external/@socketsecurity/registry/lib/spawn.js +105 -7
- package/external/@socketsecurity/registry/lib/streams.js +26 -0
- package/external/@socketsecurity/registry/lib/strings.js +123 -9
- package/external/@socketsecurity/registry/lib/url.js +21 -0
- package/external/@socketsecurity/registry/lib/words.js +16 -0
- package/external/@socketsecurity/registry/manifest.json +5 -4
- package/package.json +6 -5
- package/external/@socketsecurity/registry/external/ansi-regex.js +0 -13
- package/external/@socketsecurity/registry/lib/constants/node-workspaces.js +0 -3
- package/external/@socketsecurity/registry/lib/constants/parse-args-config.js +0 -14
- package/external/@socketsecurity/registry/lib/constants/skip-tests-by-ecosystem.js +0 -43
- package/external/@socketsecurity/registry/lib/constants/template-cjs-browser.js +0 -3
- package/external/@socketsecurity/registry/lib/constants/template-cjs-esm.js +0 -3
- package/external/@socketsecurity/registry/lib/constants/template-cjs.js +0 -3
- package/external/@socketsecurity/registry/lib/constants/template-es-shim-constructor.js +0 -3
- package/external/@socketsecurity/registry/lib/constants/template-es-shim-prototype-method.js +0 -3
- package/external/@socketsecurity/registry/lib/constants/template-es-shim-static-method.js +0 -3
- package/external/@socketsecurity/registry/lib/constants/win32-ensure-tests-by-ecosystem.js +0 -3
- package/external/@socketsecurity/registry/lib/npm.js +0 -404
- /package/external/@socketsecurity/registry/lib/constants/{hidden-package-lock-json.js → dot-package-lock-json.js} +0 -0
|
@@ -0,0 +1,650 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { readJsonSync } = /*@__PURE__*/ require('./fs')
|
|
4
|
+
const { getOwn } = /*@__PURE__*/ require('./objects')
|
|
5
|
+
const { isPath, normalizePath } = /*@__PURE__*/ require('./path')
|
|
6
|
+
const { spawn } = /*@__PURE__*/ require('./spawn')
|
|
7
|
+
|
|
8
|
+
let _fs
|
|
9
|
+
/**
|
|
10
|
+
* Lazily load the fs module to avoid Webpack errors.
|
|
11
|
+
* @returns {import('fs')} The Node.js fs module.
|
|
12
|
+
*/
|
|
13
|
+
/*@__NO_SIDE_EFFECTS__*/
|
|
14
|
+
function getFs() {
|
|
15
|
+
if (_fs === undefined) {
|
|
16
|
+
// Use non-'node:' prefixed require to avoid Webpack errors.
|
|
17
|
+
// eslint-disable-next-line n/prefer-node-protocol
|
|
18
|
+
_fs = /*@__PURE__*/ require('fs')
|
|
19
|
+
}
|
|
20
|
+
return _fs
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let _path
|
|
24
|
+
/**
|
|
25
|
+
* Lazily load the path module to avoid Webpack errors.
|
|
26
|
+
* @returns {import('path')} The Node.js path module.
|
|
27
|
+
*/
|
|
28
|
+
/*@__NO_SIDE_EFFECTS__*/
|
|
29
|
+
function getPath() {
|
|
30
|
+
if (_path === undefined) {
|
|
31
|
+
// Use non-'node:' prefixed require to avoid Webpack errors.
|
|
32
|
+
// eslint-disable-next-line n/prefer-node-protocol
|
|
33
|
+
_path = /*@__PURE__*/ require('path')
|
|
34
|
+
}
|
|
35
|
+
return _path
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
let _which
|
|
39
|
+
/**
|
|
40
|
+
* Lazily load the which module for finding executables.
|
|
41
|
+
* @returns {import('which')} The which module.
|
|
42
|
+
*/
|
|
43
|
+
/*@__NO_SIDE_EFFECTS__*/
|
|
44
|
+
function getWhich() {
|
|
45
|
+
if (_which === undefined) {
|
|
46
|
+
_which = /*@__PURE__*/ require('../external/which')
|
|
47
|
+
}
|
|
48
|
+
return _which
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/*@__NO_SIDE_EFFECTS__*/
|
|
52
|
+
/**
|
|
53
|
+
* Create an error for when a binary path cannot be resolved.
|
|
54
|
+
* @param {string} binPath - The binary path that couldn't be resolved.
|
|
55
|
+
* @param {string} [source=''] - Optional source context for debugging.
|
|
56
|
+
* @returns {Error} The error object.
|
|
57
|
+
*/
|
|
58
|
+
function getNotResolvedError(binPath, source = '') {
|
|
59
|
+
// Based on node-which:
|
|
60
|
+
// ISC License
|
|
61
|
+
// Copyright (c) Isaac Z. Schlueter and Contributors
|
|
62
|
+
// https://github.com/npm/node-which/blob/v5.0.0/lib/index.js#L15
|
|
63
|
+
const error = new Error(
|
|
64
|
+
`not resolved: ${binPath}${source ? `:\n\n${source}` : ''}`
|
|
65
|
+
)
|
|
66
|
+
error.code = 'ENOENT'
|
|
67
|
+
return error
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/*@__NO_SIDE_EFFECTS__*/
|
|
71
|
+
/**
|
|
72
|
+
* Execute a binary with the given arguments.
|
|
73
|
+
* @param {string} binPath - Path or name of the binary to execute.
|
|
74
|
+
* @param {string[] | readonly string[]} args - Arguments to pass to the binary.
|
|
75
|
+
* @param {import('./spawn').SpawnOptions} [options] - Spawn options.
|
|
76
|
+
* @returns {Promise<{ stdout: string; stderr: string }>} Command output.
|
|
77
|
+
*/
|
|
78
|
+
function execBin(binPath, args, options) {
|
|
79
|
+
return spawn(
|
|
80
|
+
/*@__PURE__*/ require('./constants/exec-path'),
|
|
81
|
+
[
|
|
82
|
+
.../*@__PURE__*/ require('./constants/node-no-warnings-flags'),
|
|
83
|
+
isPath(binPath) ? resolveBinPathSync(binPath) : whichBinSync(binPath),
|
|
84
|
+
...args
|
|
85
|
+
],
|
|
86
|
+
options
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Find and resolve a binary in the system PATH asynchronously.
|
|
92
|
+
* @template {import('which').Options} T
|
|
93
|
+
* @param {string} binName - Name of the binary to find.
|
|
94
|
+
* @param {T} options - Options for the which module.
|
|
95
|
+
* @returns {T extends {all: true, nothrow: true} ? Promise<string[] | null> : T extends {all: true} ? Promise<string[]> : T extends {nothrow: true} ? Promise<string | null> : Promise<string>} The resolved binary path(s).
|
|
96
|
+
* @throws {Error} If the binary is not found and nothrow is false.
|
|
97
|
+
*/
|
|
98
|
+
async function whichBin(binName, options) {
|
|
99
|
+
const which = getWhich()
|
|
100
|
+
// Depending on options `which` may throw if `binName` is not found.
|
|
101
|
+
// The default behavior is to throw when `binName` is not found.
|
|
102
|
+
const result = await which(binName, options)
|
|
103
|
+
|
|
104
|
+
// When 'all: true' is specified, ensure we always return an array.
|
|
105
|
+
if (options?.all) {
|
|
106
|
+
const paths = Array.isArray(result)
|
|
107
|
+
? result
|
|
108
|
+
: typeof result === 'string'
|
|
109
|
+
? [result]
|
|
110
|
+
: result
|
|
111
|
+
// If all is true and we have paths, resolve each one.
|
|
112
|
+
return paths?.length ? paths.map(p => resolveBinPathSync(p)) : paths
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return resolveBinPathSync(result)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Find and resolve a binary in the system PATH synchronously.
|
|
120
|
+
* @template {import('which').Options} T
|
|
121
|
+
* @param {string} binName - Name of the binary to find.
|
|
122
|
+
* @param {T} options - Options for the which module.
|
|
123
|
+
* @returns {T extends {all: true, nothrow: true} ? string[] | null : T extends {all: true} ? string[] : T extends {nothrow: true} ? string | null : string} The resolved binary path(s).
|
|
124
|
+
* @throws {Error} If the binary is not found and nothrow is false.
|
|
125
|
+
*/
|
|
126
|
+
function whichBinSync(binName, options) {
|
|
127
|
+
// Depending on options `which` may throw if `binName` is not found.
|
|
128
|
+
// The default behavior is to throw when `binName` is not found.
|
|
129
|
+
const result = getWhich().sync(binName, options)
|
|
130
|
+
|
|
131
|
+
// When 'all: true' is specified, ensure we always return an array.
|
|
132
|
+
if (getOwn(options, 'all')) {
|
|
133
|
+
const paths = Array.isArray(result)
|
|
134
|
+
? result
|
|
135
|
+
: typeof result === 'string'
|
|
136
|
+
? [result]
|
|
137
|
+
: result
|
|
138
|
+
// If all is true and we have paths, resolve each one.
|
|
139
|
+
return paths?.length ? paths.map(p => resolveBinPathSync(p)) : paths
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return resolveBinPathSync(result)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Check if a directory path contains any shadow bin patterns.
|
|
147
|
+
* @param {string} dirPath - Directory path to check.
|
|
148
|
+
* @returns {boolean} True if the path contains shadow bin patterns.
|
|
149
|
+
*/
|
|
150
|
+
function isShadowBinPath(dirPath) {
|
|
151
|
+
return (
|
|
152
|
+
dirPath.includes('shadow-bin') ||
|
|
153
|
+
dirPath.includes('shadow-npm-bin') ||
|
|
154
|
+
dirPath.includes('shadow-pnpm-bin') ||
|
|
155
|
+
dirPath.includes('shadow-yarn-bin')
|
|
156
|
+
)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Find the real executable for a binary, bypassing shadow bins.
|
|
161
|
+
* @param {string} binName - Name of the binary to find.
|
|
162
|
+
* @param {string[]} commonPaths - Common paths to check first.
|
|
163
|
+
* @returns {string} The path to the real binary.
|
|
164
|
+
*/
|
|
165
|
+
function findRealBin(binName, commonPaths = []) {
|
|
166
|
+
const fs = getFs()
|
|
167
|
+
const path = getPath()
|
|
168
|
+
const which = getWhich()
|
|
169
|
+
|
|
170
|
+
// Try common locations first.
|
|
171
|
+
for (const binPath of commonPaths) {
|
|
172
|
+
if (fs.existsSync(binPath)) {
|
|
173
|
+
return binPath
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Fall back to which.sync if no direct path found.
|
|
178
|
+
const binPath = which.sync(binName, { nothrow: true })
|
|
179
|
+
if (binPath) {
|
|
180
|
+
const binDir = path.dirname(binPath)
|
|
181
|
+
|
|
182
|
+
if (isShadowBinPath(binDir)) {
|
|
183
|
+
// This is likely a shadowed binary, try to find the real one.
|
|
184
|
+
const allPaths = which.sync(binName, { all: true, nothrow: true }) || []
|
|
185
|
+
// Ensure allPaths is an array.
|
|
186
|
+
const pathsArray = Array.isArray(allPaths)
|
|
187
|
+
? allPaths
|
|
188
|
+
: typeof allPaths === 'string'
|
|
189
|
+
? [allPaths]
|
|
190
|
+
: []
|
|
191
|
+
|
|
192
|
+
for (const altPath of pathsArray) {
|
|
193
|
+
const altDir = path.dirname(altPath)
|
|
194
|
+
if (!isShadowBinPath(altDir)) {
|
|
195
|
+
return altPath
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return binPath
|
|
200
|
+
}
|
|
201
|
+
// If all else fails, return the binary name and let the system resolve it.
|
|
202
|
+
return binName
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Find the real npm executable, bypassing any aliases and shadow bins.
|
|
207
|
+
* @returns {string} The path to the real npm binary.
|
|
208
|
+
*/
|
|
209
|
+
function findRealNpm() {
|
|
210
|
+
const fs = getFs()
|
|
211
|
+
const path = getPath()
|
|
212
|
+
|
|
213
|
+
// Try to find npm in the same directory as the node executable.
|
|
214
|
+
const nodeDir = path.dirname(process.execPath)
|
|
215
|
+
const npmInNodeDir = path.join(nodeDir, 'npm')
|
|
216
|
+
|
|
217
|
+
if (fs.existsSync(npmInNodeDir)) {
|
|
218
|
+
return npmInNodeDir
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Try common npm locations.
|
|
222
|
+
const commonPaths = ['/usr/local/bin/npm', '/usr/bin/npm']
|
|
223
|
+
const result = findRealBin('npm', commonPaths)
|
|
224
|
+
|
|
225
|
+
// If we found a valid path, return it.
|
|
226
|
+
if (fs.existsSync(result)) {
|
|
227
|
+
return result
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// As a last resort, try to use whichBinSync to find npm.
|
|
231
|
+
// This handles cases where npm is installed in non-standard locations.
|
|
232
|
+
const npmPath = whichBinSync('npm', { nothrow: true })
|
|
233
|
+
if (npmPath && fs.existsSync(npmPath)) {
|
|
234
|
+
return npmPath
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Return the basic 'npm' and let the system resolve it.
|
|
238
|
+
return 'npm'
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Find the real pnpm executable, bypassing any aliases and shadow bins.
|
|
243
|
+
* @returns {string} The path to the real pnpm binary.
|
|
244
|
+
*/
|
|
245
|
+
function findRealPnpm() {
|
|
246
|
+
const ENV = /*@__PURE__*/ require('./constants/env')
|
|
247
|
+
const WIN32 = /*@__PURE__*/ require('./constants/win32')
|
|
248
|
+
const path = getPath()
|
|
249
|
+
|
|
250
|
+
// Try common pnpm locations.
|
|
251
|
+
const commonPaths = WIN32
|
|
252
|
+
? [
|
|
253
|
+
// Windows common paths.
|
|
254
|
+
path.join(ENV.APPDATA, 'npm', 'pnpm.cmd'),
|
|
255
|
+
path.join(ENV.APPDATA, 'npm', 'pnpm'),
|
|
256
|
+
path.join(ENV.LOCALAPPDATA, 'pnpm', 'pnpm.cmd'),
|
|
257
|
+
path.join(ENV.LOCALAPPDATA, 'pnpm', 'pnpm'),
|
|
258
|
+
'C:\\Program Files\\nodejs\\pnpm.cmd',
|
|
259
|
+
'C:\\Program Files\\nodejs\\pnpm'
|
|
260
|
+
].filter(Boolean)
|
|
261
|
+
: [
|
|
262
|
+
// Unix common paths.
|
|
263
|
+
'/usr/local/bin/pnpm',
|
|
264
|
+
'/usr/bin/pnpm',
|
|
265
|
+
path.join(ENV.XDG_DATA_HOME, 'pnpm/pnpm'),
|
|
266
|
+
path.join(ENV.HOME, '.pnpm/pnpm')
|
|
267
|
+
].filter(Boolean)
|
|
268
|
+
|
|
269
|
+
return findRealBin('pnpm', commonPaths)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Find the real yarn executable, bypassing any aliases and shadow bins.
|
|
274
|
+
* @returns {string} The path to the real yarn binary.
|
|
275
|
+
*/
|
|
276
|
+
function findRealYarn() {
|
|
277
|
+
const ENV = /*@__PURE__*/ require('./constants/env')
|
|
278
|
+
const path = getPath()
|
|
279
|
+
|
|
280
|
+
// Try common yarn locations.
|
|
281
|
+
const commonPaths = [
|
|
282
|
+
'/usr/local/bin/yarn',
|
|
283
|
+
'/usr/bin/yarn',
|
|
284
|
+
path.join(ENV.HOME, '.yarn/bin/yarn'),
|
|
285
|
+
path.join(ENV.HOME, '.config/yarn/global/node_modules/.bin/yarn')
|
|
286
|
+
].filter(Boolean)
|
|
287
|
+
|
|
288
|
+
return findRealBin('yarn', commonPaths)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/*@__NO_SIDE_EFFECTS__*/
|
|
292
|
+
/**
|
|
293
|
+
* Resolve a binary path to its actual executable file.
|
|
294
|
+
* Handles Windows .cmd wrappers and Unix shell scripts.
|
|
295
|
+
* @param {string} binPath - The binary path to resolve.
|
|
296
|
+
* @returns {string} The resolved executable path.
|
|
297
|
+
* @throws {Error} If the binary cannot be resolved.
|
|
298
|
+
*/
|
|
299
|
+
function resolveBinPathSync(binPath) {
|
|
300
|
+
// Normalize the path once for consistent pattern matching.
|
|
301
|
+
binPath = normalizePath(binPath)
|
|
302
|
+
|
|
303
|
+
const fs = getFs()
|
|
304
|
+
const path = getPath()
|
|
305
|
+
|
|
306
|
+
const ext = path.extname(binPath)
|
|
307
|
+
const extLowered = ext.toLowerCase()
|
|
308
|
+
const basename = path.basename(binPath, ext)
|
|
309
|
+
const voltaIndex =
|
|
310
|
+
basename === 'node' ? -1 : (/(?<=\/)\.volta\//i.exec(binPath)?.index ?? -1)
|
|
311
|
+
if (voltaIndex !== -1) {
|
|
312
|
+
const voltaPath = binPath.slice(0, voltaIndex)
|
|
313
|
+
const voltaToolsPath = path.join(voltaPath, 'tools')
|
|
314
|
+
const voltaImagePath = path.join(voltaToolsPath, 'image')
|
|
315
|
+
const voltaUserPath = path.join(voltaToolsPath, 'user')
|
|
316
|
+
const voltaPlatform = readJsonSync(
|
|
317
|
+
path.join(voltaUserPath, 'platform.json'),
|
|
318
|
+
{ throws: false }
|
|
319
|
+
)
|
|
320
|
+
const voltaNodeVersion = voltaPlatform?.node?.runtime
|
|
321
|
+
const voltaNpmVersion = voltaPlatform?.node?.npm
|
|
322
|
+
let voltaBinPath = ''
|
|
323
|
+
if (basename === 'npm' || basename === 'npx') {
|
|
324
|
+
if (voltaNpmVersion) {
|
|
325
|
+
const relCliPath = `bin/${basename}-cli.js`
|
|
326
|
+
voltaBinPath = path.join(
|
|
327
|
+
voltaImagePath,
|
|
328
|
+
`npm/${voltaNpmVersion}/${relCliPath}`
|
|
329
|
+
)
|
|
330
|
+
if (voltaNodeVersion && !fs.existsSync(voltaBinPath)) {
|
|
331
|
+
voltaBinPath = path.join(
|
|
332
|
+
voltaImagePath,
|
|
333
|
+
`node/${voltaNodeVersion}/lib/node_modules/npm/${relCliPath}`
|
|
334
|
+
)
|
|
335
|
+
if (!fs.existsSync(voltaBinPath)) {
|
|
336
|
+
voltaBinPath = ''
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
} else {
|
|
341
|
+
const voltaUserBinPath = path.join(voltaUserPath, 'bin')
|
|
342
|
+
const binInfo = readJsonSync(
|
|
343
|
+
path.join(voltaUserBinPath, `${basename}.json`),
|
|
344
|
+
{ throws: false }
|
|
345
|
+
)
|
|
346
|
+
const binPackage = binInfo?.package
|
|
347
|
+
if (binPackage) {
|
|
348
|
+
voltaBinPath = path.join(
|
|
349
|
+
voltaImagePath,
|
|
350
|
+
`packages/${binPackage}/bin/${basename}`
|
|
351
|
+
)
|
|
352
|
+
if (!fs.existsSync(voltaBinPath)) {
|
|
353
|
+
voltaBinPath = `${voltaBinPath}.cmd`
|
|
354
|
+
if (!fs.existsSync(voltaBinPath)) {
|
|
355
|
+
voltaBinPath = ''
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
if (voltaBinPath) {
|
|
361
|
+
return fs.realpathSync.native(voltaBinPath)
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
const WIN32 = /*@__PURE__*/ require('./constants/win32')
|
|
365
|
+
if (WIN32) {
|
|
366
|
+
const hasKnownExt =
|
|
367
|
+
extLowered === '' || extLowered === '.cmd' || extLowered === '.ps1'
|
|
368
|
+
const isNpmOrNpx = basename === 'npm' || basename === 'npx'
|
|
369
|
+
const isPnpmOrYarn = basename === 'pnpm' || basename === 'yarn'
|
|
370
|
+
if (hasKnownExt && isNpmOrNpx) {
|
|
371
|
+
// The quick route assumes a bin path like: C:\Program Files\nodejs\npm.cmd
|
|
372
|
+
const quickPath = path.join(
|
|
373
|
+
path.dirname(binPath),
|
|
374
|
+
`node_modules/npm/bin/${basename}-cli.js`
|
|
375
|
+
)
|
|
376
|
+
if (fs.existsSync(quickPath)) {
|
|
377
|
+
return fs.realpathSync.native(quickPath)
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
let relPath = ''
|
|
381
|
+
if (hasKnownExt) {
|
|
382
|
+
const source = fs.readFileSync(binPath, 'utf8')
|
|
383
|
+
if (isNpmOrNpx) {
|
|
384
|
+
if (extLowered === '.cmd') {
|
|
385
|
+
// "npm.cmd" and "npx.cmd" defined by
|
|
386
|
+
// https://github.com/npm/cli/blob/v11.4.2/bin/npm.cmd
|
|
387
|
+
// https://github.com/npm/cli/blob/v11.4.2/bin/npx.cmd
|
|
388
|
+
relPath =
|
|
389
|
+
basename === 'npm'
|
|
390
|
+
? /(?<="NPM_CLI_JS=%~dp0\\).*(?=")/.exec(source)?.[0]
|
|
391
|
+
: /(?<="NPX_CLI_JS=%~dp0\\).*(?=")/.exec(source)?.[0]
|
|
392
|
+
} else if (extLowered === '') {
|
|
393
|
+
// Extensionless "npm" and "npx" defined by
|
|
394
|
+
// https://github.com/npm/cli/blob/v11.4.2/bin/npm
|
|
395
|
+
// https://github.com/npm/cli/blob/v11.4.2/bin/npx
|
|
396
|
+
relPath =
|
|
397
|
+
basename === 'npm'
|
|
398
|
+
? /(?<=NPM_CLI_JS="\$CLI_BASEDIR\/).*(?=")/.exec(source)?.[0]
|
|
399
|
+
: /(?<=NPX_CLI_JS="\$CLI_BASEDIR\/).*(?=")/.exec(source)?.[0]
|
|
400
|
+
} else if (extLowered === '.ps1') {
|
|
401
|
+
// "npm.ps1" and "npx.ps1" defined by
|
|
402
|
+
// https://github.com/npm/cli/blob/v11.4.2/bin/npm.ps1
|
|
403
|
+
// https://github.com/npm/cli/blob/v11.4.2/bin/npx.ps1
|
|
404
|
+
relPath =
|
|
405
|
+
basename === 'npm'
|
|
406
|
+
? /(?<=\$NPM_CLI_JS="\$PSScriptRoot\/).*(?=")/.exec(source)?.[0]
|
|
407
|
+
: /(?<=\$NPX_CLI_JS="\$PSScriptRoot\/).*(?=")/.exec(source)?.[0]
|
|
408
|
+
}
|
|
409
|
+
} else if (isPnpmOrYarn) {
|
|
410
|
+
if (extLowered === '.cmd') {
|
|
411
|
+
// pnpm.cmd and yarn.cmd can have different formats depending on installation method
|
|
412
|
+
// Common formats include:
|
|
413
|
+
// 1. Setup-pnpm action format: node "%~dp0\..\pnpm\bin\pnpm.cjs" %*
|
|
414
|
+
// 2. npm install -g pnpm format: similar to cmd-shim
|
|
415
|
+
// 3. Standalone installer format: various patterns
|
|
416
|
+
|
|
417
|
+
// Try setup-pnpm/setup-yarn action format first
|
|
418
|
+
relPath = /(?<=node\s+")%~dp0\\([^"]+)(?="\s+%\*)/.exec(source)?.[1]
|
|
419
|
+
|
|
420
|
+
// Try alternative format: "%~dp0\node.exe" "%~dp0\..\package\bin\binary.js" %*
|
|
421
|
+
if (!relPath) {
|
|
422
|
+
relPath =
|
|
423
|
+
/(?<="%~dp0\\[^"]*node[^"]*"\s+")%~dp0\\([^"]+)(?="\s+%\*)/.exec(
|
|
424
|
+
source
|
|
425
|
+
)?.[1]
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Try cmd-shim format as fallback
|
|
429
|
+
if (!relPath) {
|
|
430
|
+
relPath = /(?<="%dp0%\\).*(?=" %\*\r\n)/.exec(source)?.[0]
|
|
431
|
+
}
|
|
432
|
+
} else if (extLowered === '') {
|
|
433
|
+
// Extensionless pnpm/yarn - try common shebang formats
|
|
434
|
+
// Handle pnpm installed via standalone installer or global install
|
|
435
|
+
// Format: exec "$basedir/node" "$basedir/.tools/pnpm/VERSION/..." "$@"
|
|
436
|
+
// Note: may have multiple spaces between arguments
|
|
437
|
+
relPath = /(?<="\$basedir\/)\.tools\/pnpm\/[^"]+(?="\s+"\$@")/.exec(
|
|
438
|
+
source
|
|
439
|
+
)?.[0]
|
|
440
|
+
if (!relPath) {
|
|
441
|
+
// Also try: exec node "$basedir/.tools/pnpm/VERSION/..." "$@"
|
|
442
|
+
relPath =
|
|
443
|
+
/(?<=exec\s+node\s+"\$basedir\/)\.tools\/pnpm\/[^"]+(?="\s+"\$@")/.exec(
|
|
444
|
+
source
|
|
445
|
+
)?.[0]
|
|
446
|
+
}
|
|
447
|
+
if (!relPath) {
|
|
448
|
+
// Try standard cmd-shim format: exec node "$basedir/../package/bin/binary.js" "$@"
|
|
449
|
+
relPath = /(?<="\$basedir\/).*(?=" "\$@"\n)/.exec(source)?.[0]
|
|
450
|
+
}
|
|
451
|
+
} else if (extLowered === '.ps1') {
|
|
452
|
+
// PowerShell format
|
|
453
|
+
relPath = /(?<="\$basedir\/).*(?=" $args\n)/.exec(source)?.[0]
|
|
454
|
+
}
|
|
455
|
+
} else if (extLowered === '.cmd') {
|
|
456
|
+
// "bin.CMD" generated by
|
|
457
|
+
// https://github.com/npm/cmd-shim/blob/v7.0.0/lib/index.js#L98:
|
|
458
|
+
//
|
|
459
|
+
// @ECHO off
|
|
460
|
+
// GOTO start
|
|
461
|
+
// :find_dp0
|
|
462
|
+
// SET dp0=%~dp0
|
|
463
|
+
// EXIT /b
|
|
464
|
+
// :start
|
|
465
|
+
// SETLOCAL
|
|
466
|
+
// CALL :find_dp0
|
|
467
|
+
//
|
|
468
|
+
// IF EXIST "%dp0%\node.exe" (
|
|
469
|
+
// SET "_prog=%dp0%\node.exe"
|
|
470
|
+
// ) ELSE (
|
|
471
|
+
// SET "_prog=node"
|
|
472
|
+
// SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
473
|
+
// )
|
|
474
|
+
//
|
|
475
|
+
// endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\<PACKAGE_NAME>\path\to\bin.js" %*
|
|
476
|
+
relPath = /(?<="%dp0%\\).*(?=" %\*\r\n)/.exec(source)?.[0]
|
|
477
|
+
} else if (extLowered === '') {
|
|
478
|
+
// Extensionless "bin" generated by
|
|
479
|
+
// https://github.com/npm/cmd-shim/blob/v7.0.0/lib/index.js#L138:
|
|
480
|
+
//
|
|
481
|
+
// #!/bin/sh
|
|
482
|
+
// basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
483
|
+
//
|
|
484
|
+
// case `uname` in
|
|
485
|
+
// *CYGWIN*|*MINGW*|*MSYS*)
|
|
486
|
+
// if command -v cygpath > /dev/null 2>&1; then
|
|
487
|
+
// basedir=`cygpath -w "$basedir"`
|
|
488
|
+
// fi
|
|
489
|
+
// ;;
|
|
490
|
+
// esac
|
|
491
|
+
//
|
|
492
|
+
// if [ -x "$basedir/node" ]; then
|
|
493
|
+
// exec "$basedir/node" "$basedir/../<PACKAGE_NAME>/path/to/bin.js" "$@"
|
|
494
|
+
// else
|
|
495
|
+
// exec node "$basedir/../<PACKAGE_NAME>/path/to/bin.js" "$@"
|
|
496
|
+
// fi
|
|
497
|
+
relPath = /(?<="$basedir\/).*(?=" "\$@"\n)/.exec(source)?.[0]
|
|
498
|
+
} else if (extLowered === '.ps1') {
|
|
499
|
+
// "bin.PS1" generated by
|
|
500
|
+
// https://github.com/npm/cmd-shim/blob/v7.0.0/lib/index.js#L192:
|
|
501
|
+
//
|
|
502
|
+
// #!/usr/bin/env pwsh
|
|
503
|
+
// $basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
504
|
+
//
|
|
505
|
+
// $exe=""
|
|
506
|
+
// if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
507
|
+
// # Fix case when both the Windows and Linux builds of Node
|
|
508
|
+
// # are installed in the same directory
|
|
509
|
+
// $exe=".exe"
|
|
510
|
+
// }
|
|
511
|
+
// $ret=0
|
|
512
|
+
// if (Test-Path "$basedir/node$exe") {
|
|
513
|
+
// # Support pipeline input
|
|
514
|
+
// if ($MyInvocation.ExpectingInput) {
|
|
515
|
+
// $input | & "$basedir/node$exe" "$basedir/../<PACKAGE_NAME>/path/to/bin.js" $args
|
|
516
|
+
// } else {
|
|
517
|
+
// & "$basedir/node$exe" "$basedir/../<PACKAGE_NAME>/path/to/bin.js" $args
|
|
518
|
+
// }
|
|
519
|
+
// $ret=$LASTEXITCODE
|
|
520
|
+
// } else {
|
|
521
|
+
// # Support pipeline input
|
|
522
|
+
// if ($MyInvocation.ExpectingInput) {
|
|
523
|
+
// $input | & "node$exe" "$basedir/../<PACKAGE_NAME>/path/to/bin.js" $args
|
|
524
|
+
// } else {
|
|
525
|
+
// & "node$exe" "$basedir/../<PACKAGE_NAME>/path/to/bin.js" $args
|
|
526
|
+
// }
|
|
527
|
+
// $ret=$LASTEXITCODE
|
|
528
|
+
// }
|
|
529
|
+
// exit $ret
|
|
530
|
+
relPath = /(?<="\$basedir\/).*(?=" $args\n)/.exec(source)?.[0]
|
|
531
|
+
}
|
|
532
|
+
if (!relPath) {
|
|
533
|
+
throw getNotResolvedError(binPath, source)
|
|
534
|
+
}
|
|
535
|
+
binPath = normalizePath(path.join(path.dirname(binPath), relPath))
|
|
536
|
+
} else if (
|
|
537
|
+
extLowered !== '.js' &&
|
|
538
|
+
extLowered !== '.cjs' &&
|
|
539
|
+
extLowered !== '.mjs' &&
|
|
540
|
+
extLowered !== '.ts' &&
|
|
541
|
+
extLowered !== '.cts' &&
|
|
542
|
+
extLowered !== '.mts'
|
|
543
|
+
) {
|
|
544
|
+
throw getNotResolvedError(binPath)
|
|
545
|
+
}
|
|
546
|
+
} else {
|
|
547
|
+
// Handle Unix shell scripts (non-Windows platforms)
|
|
548
|
+
let hasNoExt = extLowered === ''
|
|
549
|
+
const isPnpmOrYarn = basename === 'pnpm' || basename === 'yarn'
|
|
550
|
+
const isNpmOrNpx = basename === 'npm' || basename === 'npx'
|
|
551
|
+
|
|
552
|
+
// Handle special case where pnpm path in CI has extra segments.
|
|
553
|
+
// In setup-pnpm GitHub Action, the path might be malformed like:
|
|
554
|
+
// /home/runner/setup-pnpm/node_modules/.bin/pnpm/bin/pnpm.cjs
|
|
555
|
+
// This happens when the shell script contains a relative path that
|
|
556
|
+
// when resolved, creates an invalid nested structure.
|
|
557
|
+
if (isPnpmOrYarn && binPath.includes('/.bin/pnpm/bin/')) {
|
|
558
|
+
// Extract the correct pnpm bin path.
|
|
559
|
+
const binIndex = binPath.indexOf('/.bin/pnpm')
|
|
560
|
+
if (binIndex !== -1) {
|
|
561
|
+
// Get the base path up to /.bin/pnpm.
|
|
562
|
+
const baseBinPath = binPath.slice(0, binIndex + '/.bin/pnpm'.length)
|
|
563
|
+
// Check if the original shell script exists.
|
|
564
|
+
try {
|
|
565
|
+
const stats = fs.statSync(baseBinPath)
|
|
566
|
+
// Only use this path if it's a file (the shell script).
|
|
567
|
+
if (stats.isFile()) {
|
|
568
|
+
binPath = baseBinPath
|
|
569
|
+
// Recompute hasNoExt since we changed the path.
|
|
570
|
+
hasNoExt = !path.extname(binPath)
|
|
571
|
+
}
|
|
572
|
+
} catch {
|
|
573
|
+
// If stat fails, continue with the original path.
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
if (hasNoExt && (isPnpmOrYarn || isNpmOrNpx)) {
|
|
579
|
+
const source = fs.readFileSync(binPath, 'utf8')
|
|
580
|
+
let relPath = ''
|
|
581
|
+
|
|
582
|
+
if (isPnpmOrYarn) {
|
|
583
|
+
// Handle pnpm/yarn Unix shell scripts.
|
|
584
|
+
// Format: exec "$basedir/node" "$basedir/.tools/pnpm/VERSION/..." "$@"
|
|
585
|
+
// or: exec node "$basedir/.tools/pnpm/VERSION/..." "$@"
|
|
586
|
+
relPath = /(?<="\$basedir\/)\.tools\/[^"]+(?="\s+"\$@")/.exec(
|
|
587
|
+
source
|
|
588
|
+
)?.[0]
|
|
589
|
+
if (!relPath) {
|
|
590
|
+
// Try standard cmd-shim format: exec node "$basedir/../package/bin/binary.js" "$@"
|
|
591
|
+
// Example: exec node "$basedir/../pnpm/bin/pnpm.cjs" "$@"
|
|
592
|
+
// ^^^^^^^^^^^^^^^^^^^^^ captures this part
|
|
593
|
+
// This regex needs to be more careful to not match "$@" at the end.
|
|
594
|
+
relPath = /(?<="\$basedir\/)[^"]+(?="\s+"\$@")/.exec(source)?.[0]
|
|
595
|
+
}
|
|
596
|
+
// Special case for setup-pnpm GitHub Action which may use a different format.
|
|
597
|
+
// The setup-pnpm action creates a shell script that references ../pnpm/bin/pnpm.cjs
|
|
598
|
+
if (!relPath) {
|
|
599
|
+
// Try to match: exec node "$basedir/../pnpm/bin/pnpm.cjs" "$@"
|
|
600
|
+
const match = /exec\s+node\s+"?\$basedir\/([^"]+)"?\s+"\$@"/.exec(
|
|
601
|
+
source
|
|
602
|
+
)
|
|
603
|
+
if (match) {
|
|
604
|
+
relPath = match[1]
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
// Check if the extracted path looks wrong (e.g., pnpm/bin/pnpm.cjs without ../).
|
|
608
|
+
// This happens with setup-pnpm action when it creates a malformed shell script.
|
|
609
|
+
if (relPath && basename === 'pnpm' && relPath.startsWith('pnpm/')) {
|
|
610
|
+
// The path should be ../pnpm/... not pnpm/...
|
|
611
|
+
// Prepend ../ to fix the relative path.
|
|
612
|
+
relPath = '../' + relPath
|
|
613
|
+
}
|
|
614
|
+
} else if (isNpmOrNpx) {
|
|
615
|
+
// Handle npm/npx Unix shell scripts
|
|
616
|
+
relPath =
|
|
617
|
+
basename === 'npm'
|
|
618
|
+
? /(?<=NPM_CLI_JS="\$CLI_BASEDIR\/).*(?=")/.exec(source)?.[0]
|
|
619
|
+
: /(?<=NPX_CLI_JS="\$CLI_BASEDIR\/).*(?=")/.exec(source)?.[0]
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
if (relPath) {
|
|
623
|
+
// Normalize the relative path to handle .. segments properly.
|
|
624
|
+
const resolvedPath = path.resolve(path.dirname(binPath), relPath)
|
|
625
|
+
binPath = normalizePath(resolvedPath)
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
try {
|
|
630
|
+
return fs.realpathSync.native(binPath)
|
|
631
|
+
} catch (error) {
|
|
632
|
+
// Provide more context when realpath fails.
|
|
633
|
+
if (error.code === 'ENOTDIR') {
|
|
634
|
+
throw new Error(`Path resolution failed - not a directory: ${binPath}`)
|
|
635
|
+
}
|
|
636
|
+
throw error
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
module.exports = {
|
|
641
|
+
execBin,
|
|
642
|
+
findRealBin,
|
|
643
|
+
findRealNpm,
|
|
644
|
+
findRealPnpm,
|
|
645
|
+
findRealYarn,
|
|
646
|
+
isShadowBinPath,
|
|
647
|
+
resolveBinPathSync,
|
|
648
|
+
whichBin,
|
|
649
|
+
whichBinSync
|
|
650
|
+
}
|