@socketsecurity/cli-with-sentry 1.1.21 → 1.1.23
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 +21 -0
- package/README.md +37 -56
- package/dist/cli.js +35 -25
- package/dist/cli.js.map +1 -1
- package/dist/constants.js +6 -3
- package/dist/constants.js.map +1 -1
- package/dist/flags.js +8 -8
- package/dist/flags.js.map +1 -1
- package/dist/npm-cli.js +6 -2
- package/dist/npm-cli.js.map +1 -1
- package/dist/pnpm-cli.js +6 -2
- package/dist/pnpm-cli.js.map +1 -1
- package/dist/shadow-npm-bin2.js +7 -3
- package/dist/shadow-npm-bin2.js.map +1 -1
- package/dist/shadow-pnpm-bin2.js +40 -36
- package/dist/shadow-pnpm-bin2.js.map +1 -1
- package/dist/shadow-yarn-bin.js +14 -7
- package/dist/shadow-yarn-bin.js.map +1 -1
- package/dist/tsconfig.dts.tsbuildinfo +1 -1
- package/dist/types/commands/ci/cmd-ci.d.mts.map +1 -1
- package/dist/types/commands/fix/cmd-fix.d.mts.map +1 -1
- package/dist/types/commands/fix/handle-fix.d.mts +2 -2
- package/dist/types/commands/fix/handle-fix.d.mts.map +1 -1
- package/dist/types/commands/fix/types.d.mts +1 -1
- package/dist/types/commands/fix/types.d.mts.map +1 -1
- package/dist/types/commands/scan/suggest_branch_slug.d.mts.map +1 -1
- package/dist/types/constants.d.mts +3 -1
- package/dist/types/constants.d.mts.map +1 -1
- package/dist/types/flags.d.mts.map +1 -1
- package/dist/types/sea/bootstrap.d.mts +2 -0
- package/dist/types/sea/bootstrap.d.mts.map +1 -0
- package/dist/types/sea/build-sea.d.mts +27 -0
- package/dist/types/sea/build-sea.d.mts.map +1 -0
- package/dist/types/shadow/common.d.mts +0 -8
- package/dist/types/shadow/common.d.mts.map +1 -1
- package/dist/types/shadow/npm-base.d.mts.map +1 -1
- package/dist/types/shadow/pnpm/bin.d.mts.map +1 -1
- package/dist/types/shadow/yarn/bin.d.mts.map +1 -1
- package/dist/types/utils/agent.d.mts.map +1 -1
- package/dist/types/utils/cmd.d.mts +25 -4
- package/dist/types/utils/cmd.d.mts.map +1 -1
- package/dist/types/utils/dlx.d.mts.map +1 -1
- package/dist/types/utils/extract-names.d.mts +15 -0
- package/dist/types/utils/extract-names.d.mts.map +1 -0
- package/dist/types/utils/git.d.mts.map +1 -1
- package/dist/types/utils/meow-with-subcommands.d.mts.map +1 -1
- package/dist/utils.js +90 -32
- package/dist/utils.js.map +1 -1
- package/dist/yarn-cli.js +6 -2
- package/dist/yarn-cli.js.map +1 -1
- package/package.json +4 -1
package/dist/shadow-pnpm-bin2.js
CHANGED
|
@@ -8,22 +8,23 @@ var logger = require('../external/@socketsecurity/registry/lib/logger');
|
|
|
8
8
|
var spawn = require('../external/@socketsecurity/registry/lib/spawn');
|
|
9
9
|
var constants = require('./constants.js');
|
|
10
10
|
var utils = require('./utils.js');
|
|
11
|
+
var packages = require('../external/@socketsecurity/registry/lib/packages');
|
|
11
12
|
var shadowNpmBin = require('./shadow-npm-bin2.js');
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
|
-
* Extract package PURLs from add/dlx
|
|
15
|
+
* Extract package PURLs from command arguments for add/dlx commands where
|
|
16
|
+
* packages are specified as arguments.
|
|
17
|
+
* Used by: pnpm, yarn.
|
|
15
18
|
*/
|
|
16
|
-
function
|
|
19
|
+
function extractPackagePurlsFromCommandArgs(rawArgs) {
|
|
17
20
|
const packagePurls = [];
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
packagePurls.push(purl);
|
|
26
|
-
}
|
|
21
|
+
|
|
22
|
+
// For 'add package1 package2@version' or 'dlx package', get packages from args.
|
|
23
|
+
const packageArgs = rawArgs.slice(1).filter(a => !a.startsWith('-') && a !== '--');
|
|
24
|
+
for (const pkgSpec of packageArgs) {
|
|
25
|
+
const purl = utils.safeNpmSpecToPurl(pkgSpec);
|
|
26
|
+
if (purl) {
|
|
27
|
+
packagePurls.push(purl);
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
return packagePurls;
|
|
@@ -31,19 +32,22 @@ function extractPackagePurlsFromArgs(command, rawArgs, dlxCommands) {
|
|
|
31
32
|
|
|
32
33
|
/**
|
|
33
34
|
* Extract package PURLs from package.json for install/update commands.
|
|
35
|
+
* Used by: pnpm, yarn.
|
|
34
36
|
*/
|
|
35
|
-
async function extractPackagePurlsFromPackageJson(cwd) {
|
|
37
|
+
async function extractPackagePurlsFromPackageJson(cwd = process.cwd()) {
|
|
36
38
|
const packagePurls = [];
|
|
37
39
|
try {
|
|
38
|
-
const
|
|
39
|
-
const packageJson = JSON.parse(packageJsonContent);
|
|
40
|
+
const pkgJson = await packages.readPackageJson(cwd);
|
|
40
41
|
const allDeps = {
|
|
41
|
-
...
|
|
42
|
-
...
|
|
43
|
-
...
|
|
44
|
-
...
|
|
42
|
+
...pkgJson.dependencies,
|
|
43
|
+
...pkgJson.devDependencies,
|
|
44
|
+
...pkgJson.optionalDependencies,
|
|
45
|
+
...pkgJson.peerDependencies
|
|
45
46
|
};
|
|
46
|
-
for (const
|
|
47
|
+
for (const {
|
|
48
|
+
0: name,
|
|
49
|
+
1: version
|
|
50
|
+
} of Object.entries(allDeps)) {
|
|
47
51
|
const purl = utils.safeNpmSpecToPurl(typeof version === 'string' ? `${name}@${version}` : name);
|
|
48
52
|
if (purl) {
|
|
49
53
|
packagePurls.push(purl);
|
|
@@ -51,7 +55,7 @@ async function extractPackagePurlsFromPackageJson(cwd) {
|
|
|
51
55
|
}
|
|
52
56
|
utils.debugScan('start', packagePurls.length);
|
|
53
57
|
} catch (e) {
|
|
54
|
-
require$$9.debugFn('warn',
|
|
58
|
+
require$$9.debugFn('warn', `${constants.PACKAGE_JSON} not found or invalid during dependency scanning`);
|
|
55
59
|
require$$9.debugDir('error', e);
|
|
56
60
|
}
|
|
57
61
|
return packagePurls;
|
|
@@ -90,8 +94,8 @@ async function scanPackagesAndLogAlerts(options) {
|
|
|
90
94
|
|
|
91
95
|
// Extract package names from command arguments before any downloads.
|
|
92
96
|
let packagePurls = [];
|
|
93
|
-
if (
|
|
94
|
-
packagePurls =
|
|
97
|
+
if (isDlxCommand || utils.isAddCommand(command)) {
|
|
98
|
+
packagePurls = extractPackagePurlsFromCommandArgs(rawArgs);
|
|
95
99
|
} else if (isInstallCommand) {
|
|
96
100
|
// For install/update, scan dependencies from package.json.
|
|
97
101
|
// Note: This scans direct dependencies only.
|
|
@@ -161,11 +165,6 @@ async function shadowPnpmBin(args = process.argv.slice(2), options, extra) {
|
|
|
161
165
|
ipc,
|
|
162
166
|
...spawnOpts
|
|
163
167
|
} = opts;
|
|
164
|
-
const {
|
|
165
|
-
spinner
|
|
166
|
-
} = opts;
|
|
167
|
-
const wasSpinning = !!spinner?.isSpinning;
|
|
168
|
-
spinner?.start();
|
|
169
168
|
let {
|
|
170
169
|
cwd = process.cwd()
|
|
171
170
|
} = opts;
|
|
@@ -174,26 +173,30 @@ async function shadowPnpmBin(args = process.argv.slice(2), options, extra) {
|
|
|
174
173
|
}
|
|
175
174
|
const terminatorPos = args.indexOf('--');
|
|
176
175
|
const rawPnpmArgs = terminatorPos === -1 ? args : args.slice(0, terminatorPos);
|
|
177
|
-
const
|
|
176
|
+
const {
|
|
177
|
+
spinner
|
|
178
|
+
} = opts;
|
|
179
|
+
const wasSpinning = !!spinner?.isSpinning;
|
|
178
180
|
|
|
179
181
|
// Check if this is a command that needs security scanning.
|
|
180
182
|
const command = rawPnpmArgs[0];
|
|
181
183
|
const isDlxCommand = command && DLX_COMMANDS.has(command);
|
|
182
184
|
const isInstallCommand = command && INSTALL_COMMANDS.has(command);
|
|
183
185
|
const needsScanning = isDlxCommand || isInstallCommand;
|
|
186
|
+
spinner?.start();
|
|
184
187
|
if (needsScanning && !rawPnpmArgs.includes(constants.FLAG_DRY_RUN)) {
|
|
185
188
|
const acceptRisks = !!constants.default.ENV.SOCKET_CLI_ACCEPT_RISKS;
|
|
186
189
|
const viewAllRisks = !!constants.default.ENV.SOCKET_CLI_VIEW_ALL_RISKS;
|
|
187
190
|
|
|
188
191
|
// Handle add and dlx commands with shared utility.
|
|
189
|
-
if (
|
|
192
|
+
if (isDlxCommand || utils.isAddCommand(command)) {
|
|
190
193
|
const scanResult = await scanPackagesAndLogAlerts({
|
|
191
194
|
acceptRisks,
|
|
192
195
|
command,
|
|
193
196
|
cwd,
|
|
194
197
|
dlxCommands: DLX_COMMANDS,
|
|
195
198
|
installCommands: INSTALL_COMMANDS,
|
|
196
|
-
managerName:
|
|
199
|
+
managerName: constants.PNPM,
|
|
197
200
|
rawArgs: rawPnpmArgs,
|
|
198
201
|
spinner,
|
|
199
202
|
viewAllRisks
|
|
@@ -204,7 +207,7 @@ async function shadowPnpmBin(args = process.argv.slice(2), options, extra) {
|
|
|
204
207
|
// This line is never reached in production, but helps tests.
|
|
205
208
|
throw new Error('process.exit called');
|
|
206
209
|
}
|
|
207
|
-
} else if (
|
|
210
|
+
} else if (utils.isPnpmLockfileScanCommand(command)) {
|
|
208
211
|
// For install/update, scan all dependencies from pnpm-lock.yaml
|
|
209
212
|
const pnpmLockPath = path.join(cwd, constants.PNPM_LOCK_YAML);
|
|
210
213
|
if (fs.existsSync(pnpmLockPath)) {
|
|
@@ -231,7 +234,7 @@ async function shadowPnpmBin(args = process.argv.slice(2), options, extra) {
|
|
|
231
234
|
hideAt: viewAllRisks ? 'none' : 'middle',
|
|
232
235
|
output: process.stderr
|
|
233
236
|
});
|
|
234
|
-
const errorMessage = `Socket
|
|
237
|
+
const errorMessage = `Socket ${constants.PNPM} exiting due to risks.${viewAllRisks ? '' : `\nView all risks - Rerun with environment variable ${constants.default.SOCKET_CLI_VIEW_ALL_RISKS}=1.`}${acceptRisks ? '' : `\nAccept risks - Rerun with environment variable ${constants.default.SOCKET_CLI_ACCEPT_RISKS}=1.`}`.trim();
|
|
235
238
|
logger.logger.error(errorMessage);
|
|
236
239
|
// eslint-disable-next-line n/no-process-exit
|
|
237
240
|
process.exit(1);
|
|
@@ -244,17 +247,17 @@ async function shadowPnpmBin(args = process.argv.slice(2), options, extra) {
|
|
|
244
247
|
}
|
|
245
248
|
}
|
|
246
249
|
} catch (e) {
|
|
247
|
-
require$$9.debugFn('error',
|
|
250
|
+
require$$9.debugFn('error', `${constants.PNPM} lockfile scanning failed`);
|
|
248
251
|
require$$9.debugDir('error', e);
|
|
249
252
|
}
|
|
250
253
|
} else {
|
|
251
|
-
require$$9.debugFn('notice',
|
|
254
|
+
require$$9.debugFn('notice', `skip: no ${constants.PNPM_LOCK_YAML} found, skipping bulk install scanning`);
|
|
252
255
|
}
|
|
253
256
|
}
|
|
254
257
|
require$$9.debugFn('notice', 'complete: scanning, proceeding with install');
|
|
255
258
|
}
|
|
256
259
|
const realPnpmPath = await utils.installPnpmLinks(constants.default.shadowBinPath);
|
|
257
|
-
|
|
260
|
+
const otherArgs = terminatorPos === -1 ? [] : args.slice(terminatorPos);
|
|
258
261
|
const suffixArgs = [...rawPnpmArgs, ...otherArgs];
|
|
259
262
|
require$$9.debugFn('notice', `spawn: ${constants.PNPM} shadow bin ${realPnpmPath} ${utils.cmdFlagsToString(suffixArgs)}`);
|
|
260
263
|
if (wasSpinning) {
|
|
@@ -265,6 +268,7 @@ async function shadowPnpmBin(args = process.argv.slice(2), options, extra) {
|
|
|
265
268
|
const stdio = shadowNpmBin.ensureIpcInStdio(spawnOpts.stdio);
|
|
266
269
|
const spawnPromise = spawn.spawn(realPnpmPath, suffixArgs, {
|
|
267
270
|
...spawnOpts,
|
|
271
|
+
cwd,
|
|
268
272
|
env: {
|
|
269
273
|
...process.env,
|
|
270
274
|
...spawnEnv
|
|
@@ -292,5 +296,5 @@ async function shadowPnpmBin(args = process.argv.slice(2), options, extra) {
|
|
|
292
296
|
|
|
293
297
|
exports.scanPackagesAndLogAlerts = scanPackagesAndLogAlerts;
|
|
294
298
|
exports.shadowPnpmBin = shadowPnpmBin;
|
|
295
|
-
//# debugId=
|
|
299
|
+
//# debugId=b4cf863e-3d5c-4dcc-ad18-e70648911b2
|
|
296
300
|
//# sourceMappingURL=shadow-pnpm-bin2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadow-pnpm-bin2.js","sources":["../src/shadow/common.mts","../src/shadow/pnpm/bin.mts"],"sourcesContent":["import { promises as fs } from 'node:fs'\nimport { fileURLToPath } from 'node:url'\n\nimport { debugDir, debugFn } from '@socketsecurity/registry/lib/debug'\nimport { logger } from '@socketsecurity/registry/lib/logger'\n\nimport constants, { FLAG_DRY_RUN } from '../constants.mts'\nimport { getAlertsMapFromPurls } from '../utils/alerts-map.mts'\nimport { debugScan } from '../utils/debug.mts'\nimport { safeNpmSpecToPurl } from '../utils/npm-spec.mts'\nimport { logAlertsMap } from '../utils/socket-package-alert.mts'\n\nimport type { AlertsByPurl } from '../utils/socket-package-alert.mts'\nimport type { Spinner } from '@socketsecurity/registry/lib/spinner'\n\n/**\n * Extract package PURLs from add/dlx command arguments.\n */\nexport function extractPackagePurlsFromArgs(\n command: string,\n rawArgs: string[] | readonly string[],\n dlxCommands?: Set<string>,\n): string[] {\n const packagePurls: string[] = []\n const isDlxCommand = dlxCommands?.has(command)\n\n if (command === 'add' || isDlxCommand) {\n // For 'add package1 package2@version' or 'dlx package', get packages from args.\n const packageArgs = rawArgs\n .slice(1)\n .filter(arg => !arg.startsWith('-') && arg !== '--')\n\n for (const pkgSpec of packageArgs) {\n const purl = safeNpmSpecToPurl(pkgSpec)\n if (purl) {\n packagePurls.push(purl)\n }\n }\n }\n\n return packagePurls\n}\n\n/**\n * Extract package PURLs from package.json for install/update commands.\n */\nexport async function extractPackagePurlsFromPackageJson(\n cwd: string,\n): Promise<string[]> {\n const packagePurls: string[] = []\n\n try {\n const packageJsonContent = await fs.readFile(`${cwd}/package.json`, 'utf8')\n const packageJson = JSON.parse(packageJsonContent)\n\n const allDeps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n ...packageJson.optionalDependencies,\n ...packageJson.peerDependencies,\n }\n\n for (const [name, version] of Object.entries(allDeps)) {\n const purl = safeNpmSpecToPurl(\n typeof version === 'string' ? `${name}@${version}` : name,\n )\n if (purl) {\n packagePurls.push(purl)\n }\n }\n\n debugScan('start', packagePurls.length)\n } catch (e) {\n debugFn(\n 'warn',\n 'Package.json not found or invalid during dependency scanning',\n )\n debugDir('error', e)\n }\n\n return packagePurls\n}\n\nexport type PackageScanOptions = {\n acceptRisks: boolean\n command: string | undefined\n cwd?: string | URL\n dlxCommands?: Set<string>\n installCommands: Set<string>\n managerName: string\n nothrow?: boolean\n rawArgs: string[] | readonly string[]\n spinner?: Spinner | undefined\n viewAllRisks: boolean\n}\n\nexport type PackageScanResult = {\n alertsMap?: AlertsByPurl\n shouldExit: boolean\n}\n\n/**\n * Scan packages and log alerts if found.\n */\nexport async function scanPackagesAndLogAlerts(\n options: PackageScanOptions,\n): Promise<PackageScanResult> {\n const {\n acceptRisks,\n command,\n dlxCommands,\n installCommands,\n managerName,\n nothrow = true,\n rawArgs,\n spinner,\n viewAllRisks,\n } = options\n\n let { cwd = process.cwd() } = options\n if (cwd instanceof URL) {\n cwd = fileURLToPath(cwd)\n }\n\n // Check if this is a command that needs security scanning.\n const isDlxCommand = dlxCommands && command && dlxCommands.has(command)\n const isInstallCommand = command && installCommands.has(command)\n const needsScanning = isDlxCommand || isInstallCommand\n\n if (!needsScanning || rawArgs.includes(FLAG_DRY_RUN)) {\n return { shouldExit: false }\n }\n\n // Extract package names from command arguments before any downloads.\n let packagePurls: string[] = []\n\n if (command === 'add' || isDlxCommand) {\n packagePurls = extractPackagePurlsFromArgs(command, rawArgs, dlxCommands)\n } else if (isInstallCommand) {\n // For install/update, scan dependencies from package.json.\n // Note: This scans direct dependencies only.\n packagePurls = await extractPackagePurlsFromPackageJson(cwd)\n }\n\n if (!packagePurls.length) {\n return { shouldExit: false }\n }\n\n debugScan('start', packagePurls.length)\n debugDir('inspect', { packagePurls })\n\n try {\n const alertsMap = await getAlertsMapFromPurls(packagePurls, {\n filter: acceptRisks\n ? { actions: ['error'], blocked: true }\n : { actions: ['error', 'monitor', 'warn'] },\n nothrow,\n spinner,\n })\n\n if (alertsMap.size) {\n process.exitCode = 1\n spinner?.stop()\n logAlertsMap(alertsMap, {\n hideAt: viewAllRisks ? 'none' : 'middle',\n output: process.stderr,\n })\n\n const errorMessage = `Socket ${managerName} exiting due to risks.${\n viewAllRisks\n ? ''\n : `\\nView all risks - Rerun with environment variable ${constants.SOCKET_CLI_VIEW_ALL_RISKS}=1.`\n }${\n acceptRisks\n ? ''\n : `\\nAccept risks - Rerun with environment variable ${constants.SOCKET_CLI_ACCEPT_RISKS}=1.`\n }`.trim()\n\n logger.error(errorMessage)\n return { alertsMap, shouldExit: true }\n }\n } catch (e) {\n spinner?.stop()\n // Re-throw process.exit errors from tests.\n if (e instanceof Error && e.message === 'process.exit called') {\n throw e\n }\n debugScan('error', undefined, e)\n // Continue with installation if scanning fails.\n }\n\n debugScan('complete', packagePurls.length)\n debugDir('inspect', { args: rawArgs.slice(1) })\n\n return { shouldExit: false }\n}\n","import { existsSync } from 'node:fs'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport { debugDir, debugFn } from '@socketsecurity/registry/lib/debug'\nimport { logger } from '@socketsecurity/registry/lib/logger'\nimport { spawn } from '@socketsecurity/registry/lib/spawn'\n\nimport constants, {\n FLAG_DRY_RUN,\n PNPM,\n PNPM_LOCK_YAML,\n} from '../../constants.mts'\nimport { getAlertsMapFromPnpmLockfile } from '../../utils/alerts-map.mts'\nimport { cmdFlagsToString } from '../../utils/cmd.mts'\nimport { parsePnpmLockfile, readPnpmLockfile } from '../../utils/pnpm.mts'\nimport { getPublicApiToken } from '../../utils/sdk.mts'\nimport { installPnpmLinks } from '../../utils/shadow-links.mts'\nimport { logAlertsMap } from '../../utils/socket-package-alert.mts'\nimport { scanPackagesAndLogAlerts } from '../common.mts'\nimport { ensureIpcInStdio } from '../stdio-ipc.mts'\n\nimport type { IpcObject } from '../../constants.mts'\nimport type {\n SpawnExtra,\n SpawnOptions,\n SpawnResult,\n} from '@socketsecurity/registry/lib/spawn'\n\nexport type ShadowPnpmOptions = SpawnOptions & {\n ipc?: IpcObject | undefined\n}\n\nexport type ShadowPnpmResult = {\n spawnPromise: SpawnResult<string, SpawnExtra | undefined>\n}\n\nconst DLX_COMMANDS = new Set(['dlx'])\n\nconst INSTALL_COMMANDS = new Set([\n 'add',\n 'i',\n 'install',\n 'install-test',\n 'it',\n 'update',\n 'up',\n])\n\nexport default async function shadowPnpmBin(\n args: string[] | readonly string[] = process.argv.slice(2),\n options?: ShadowPnpmOptions | undefined,\n extra?: SpawnExtra | undefined,\n): Promise<ShadowPnpmResult> {\n const opts = { __proto__: null, ...options } as ShadowPnpmOptions\n const { env: spawnEnv, ipc, ...spawnOpts } = opts\n const { spinner } = opts\n\n const wasSpinning = !!spinner?.isSpinning\n\n spinner?.start()\n\n let { cwd = process.cwd() } = opts\n if (cwd instanceof URL) {\n cwd = fileURLToPath(cwd)\n }\n\n const terminatorPos = args.indexOf('--')\n const rawPnpmArgs = terminatorPos === -1 ? args : args.slice(0, terminatorPos)\n const otherArgs = terminatorPos === -1 ? [] : args.slice(terminatorPos)\n\n // Check if this is a command that needs security scanning.\n const command = rawPnpmArgs[0]\n const isDlxCommand = command && DLX_COMMANDS.has(command)\n const isInstallCommand = command && INSTALL_COMMANDS.has(command)\n const needsScanning = isDlxCommand || isInstallCommand\n\n if (needsScanning && !rawPnpmArgs.includes(FLAG_DRY_RUN)) {\n const acceptRisks = !!constants.ENV.SOCKET_CLI_ACCEPT_RISKS\n const viewAllRisks = !!constants.ENV.SOCKET_CLI_VIEW_ALL_RISKS\n\n // Handle add and dlx commands with shared utility.\n if (command === 'add' || isDlxCommand) {\n const scanResult = await scanPackagesAndLogAlerts({\n acceptRisks,\n command,\n cwd,\n dlxCommands: DLX_COMMANDS,\n installCommands: INSTALL_COMMANDS,\n managerName: 'pnpm',\n rawArgs: rawPnpmArgs,\n spinner,\n viewAllRisks,\n })\n\n if (scanResult.shouldExit) {\n // eslint-disable-next-line n/no-process-exit\n process.exit(1)\n // This line is never reached in production, but helps tests.\n throw new Error('process.exit called')\n }\n } else if (['install', 'i', 'update', 'up'].includes(command)) {\n // For install/update, scan all dependencies from pnpm-lock.yaml\n const pnpmLockPath = path.join(cwd, PNPM_LOCK_YAML)\n if (existsSync(pnpmLockPath)) {\n try {\n const lockfileContent = await readPnpmLockfile(pnpmLockPath)\n if (lockfileContent) {\n const lockfile = parsePnpmLockfile(lockfileContent)\n if (lockfile) {\n // Use existing function to scan the entire lockfile\n debugFn(\n 'notice',\n `scanning: all dependencies from ${PNPM_LOCK_YAML}`,\n )\n\n const alertsMap = await getAlertsMapFromPnpmLockfile(lockfile, {\n nothrow: true,\n filter: acceptRisks\n ? { actions: ['error'], blocked: true }\n : { actions: ['error', 'monitor', 'warn'] },\n })\n\n spinner?.stop()\n\n if (alertsMap.size) {\n process.exitCode = 1\n logAlertsMap(alertsMap, {\n hideAt: viewAllRisks ? 'none' : 'middle',\n output: process.stderr,\n })\n\n const errorMessage = `Socket pnpm exiting due to risks.${\n viewAllRisks\n ? ''\n : `\\nView all risks - Rerun with environment variable ${constants.SOCKET_CLI_VIEW_ALL_RISKS}=1.`\n }${\n acceptRisks\n ? ''\n : `\\nAccept risks - Rerun with environment variable ${constants.SOCKET_CLI_ACCEPT_RISKS}=1.`\n }`.trim()\n\n logger.error(errorMessage)\n // eslint-disable-next-line n/no-process-exit\n process.exit(1)\n // This line is never reached in production, but helps tests.\n throw new Error('process.exit called')\n }\n\n // Return early since we've already done the scanning\n debugFn(\n 'notice',\n 'complete: lockfile scanning, proceeding with install',\n )\n }\n }\n } catch (e) {\n debugFn('error', 'PNPM lockfile scanning failed')\n debugDir('error', e)\n }\n } else {\n debugFn(\n 'notice',\n 'skip: no pnpm-lock.yaml found, skipping bulk install scanning',\n )\n }\n }\n\n debugFn('notice', 'complete: scanning, proceeding with install')\n }\n\n const realPnpmPath = await installPnpmLinks(constants.shadowBinPath)\n\n spinner?.stop()\n\n const suffixArgs = [...rawPnpmArgs, ...otherArgs]\n\n debugFn(\n 'notice',\n `spawn: ${PNPM} shadow bin ${realPnpmPath} ${cmdFlagsToString(suffixArgs)}`,\n )\n\n if (wasSpinning) {\n spinner?.start()\n }\n\n // Set up stdio with IPC channel.\n const stdio = ensureIpcInStdio(spawnOpts.stdio)\n\n const spawnPromise = spawn(\n realPnpmPath,\n suffixArgs,\n {\n ...spawnOpts,\n env: {\n ...process.env,\n ...spawnEnv,\n },\n stdio,\n // On Windows, pnpm is often a .cmd file that requires shell execution.\n // The spawn function from @socketsecurity/registry will handle this properly\n // when shell is true.\n shell: constants.WIN32,\n },\n extra,\n )\n\n // Send IPC handshake.\n spawnPromise.process.send({\n [constants.SOCKET_IPC_HANDSHAKE]: {\n [constants.SOCKET_CLI_SHADOW_API_TOKEN]: getPublicApiToken(),\n [constants.SOCKET_CLI_SHADOW_BIN]: PNPM,\n [constants.SOCKET_CLI_SHADOW_PROGRESS]: true,\n ...ipc,\n },\n })\n\n return { spawnPromise }\n}\n"],"names":["packagePurls","debugScan","debugFn","debugDir","nothrow","viewAllRisks","cwd","shouldExit","blocked","actions","spinner","hideAt","logger","args","__proto__","env","dlxCommands","installCommands","managerName","rawArgs","process","spawnPromise"],"mappings":";;;;;;;;;;;;AAeA;AACA;AACA;AACO;;AAML;AAEA;AACE;;AAKA;AACE;AACA;AACEA;AACF;AACF;AACF;AAEA;AACF;;AAEA;AACA;AACA;AACO;;;AAMH;AACA;AAEA;;;;AAIE;;AAGF;AACE;AAGA;AACEA;AACF;AACF;AAEAC;;AAEAC;AAIAC;AACF;AAEA;AACF;AAoBA;AACA;AACA;AACO;;;;;;;AASHC;;;AAGAC;AACF;;AAEMC;AAAoB;;AAExBA;AACF;;AAEA;;;AAGA;;;AAGWC;;AACX;;AAEA;;AAGA;;;AAGE;AACA;AACAP;AACF;AAEA;;AACWO;;AACX;AAEAN;;AACsBD;AAAa;;AAGjC;;;AAE4BQ;AAAc;AAClCC;;;AAENC;AACF;;;;;AAMIC;;AAEF;AAEA;AAUAC;;;AACoBL;;AACtB;;;AAGA;;AAEE;AACF;AACAN;AACA;AACF;AAEAA;;AACsBY;AAAuB;;AAEpCN;;AACX;;AC9JA;AAEA;AAUe;AAKb;AAAeO;;;;AACPC;;;AAAiC;;AACjCL;AAAQ;AAEhB;;;AAIMJ;AAAoB;;AAExBA;AACF;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;;;;;AAME;AACA;AACE;;;;AAIEU;AACAC;AACAC;AACAC;;AAEAd;AACF;;AAGE;AACAe;AACA;AACA;AACF;AACF;AACE;;AAEA;;AAEI;AACA;AACE;AACA;AACE;AACAlB;AAKA;AACEE;;;AAE0BI;AAAc;AAClCC;AAAsC;AAC9C;;;;;AAOIE;;AAEF;;AAYAC;AACA;AACAQ;AACA;AACA;AACF;;AAEA;AACAlB;AAIF;AACF;;AAEAA;AACAC;AACF;AACF;AACED;AAIF;AACF;AAEAA;AACF;;;;AAQAA;AAKA;;AAEA;;AAEA;AACA;AAEA;AAII;AACAa;;;;;AAKA;AACA;AACA;;;;AAMJ;AACAM;;AAEI;AACA;AACA;;AAEF;AACF;;AAESA;;AACX;;;","debugId":"1e3148ec-bac2-494c-808c-c14f2bc99e12"}
|
|
1
|
+
{"version":3,"file":"shadow-pnpm-bin2.js","sources":["../src/shadow/common.mts","../src/shadow/pnpm/bin.mts"],"sourcesContent":["import { fileURLToPath } from 'node:url'\n\nimport { debugDir, debugFn } from '@socketsecurity/registry/lib/debug'\nimport { logger } from '@socketsecurity/registry/lib/logger'\nimport { readPackageJson } from '@socketsecurity/registry/lib/packages'\n\nimport constants, { FLAG_DRY_RUN, PACKAGE_JSON } from '../constants.mts'\nimport { getAlertsMapFromPurls } from '../utils/alerts-map.mts'\nimport { isAddCommand } from '../utils/cmd.mts'\nimport { debugScan } from '../utils/debug.mts'\nimport { safeNpmSpecToPurl } from '../utils/npm-spec.mts'\nimport { logAlertsMap } from '../utils/socket-package-alert.mts'\n\nimport type { AlertsByPurl } from '../utils/socket-package-alert.mts'\nimport type { Spinner } from '@socketsecurity/registry/lib/spinner'\n\n/**\n * Extract package PURLs from command arguments for add/dlx commands where\n * packages are specified as arguments.\n * Used by: pnpm, yarn.\n */\nfunction extractPackagePurlsFromCommandArgs(\n rawArgs: string[] | readonly string[],\n): string[] {\n const packagePurls: string[] = []\n\n // For 'add package1 package2@version' or 'dlx package', get packages from args.\n const packageArgs = rawArgs\n .slice(1)\n .filter(a => !a.startsWith('-') && a !== '--')\n\n for (const pkgSpec of packageArgs) {\n const purl = safeNpmSpecToPurl(pkgSpec)\n if (purl) {\n packagePurls.push(purl)\n }\n }\n\n return packagePurls\n}\n\n/**\n * Extract package PURLs from package.json for install/update commands.\n * Used by: pnpm, yarn.\n */\nasync function extractPackagePurlsFromPackageJson(\n cwd = process.cwd(),\n): Promise<string[]> {\n const packagePurls: string[] = []\n\n try {\n const pkgJson = await readPackageJson(cwd)\n\n const allDeps = {\n ...pkgJson.dependencies,\n ...pkgJson.devDependencies,\n ...pkgJson.optionalDependencies,\n ...pkgJson.peerDependencies,\n }\n\n for (const { 0: name, 1: version } of Object.entries(allDeps)) {\n const purl = safeNpmSpecToPurl(\n typeof version === 'string' ? `${name}@${version}` : name,\n )\n if (purl) {\n packagePurls.push(purl)\n }\n }\n\n debugScan('start', packagePurls.length)\n } catch (e) {\n debugFn(\n 'warn',\n `${PACKAGE_JSON} not found or invalid during dependency scanning`,\n )\n debugDir('error', e)\n }\n\n return packagePurls\n}\n\nexport type PackageScanOptions = {\n acceptRisks: boolean\n command: string | undefined\n cwd?: string | URL\n dlxCommands?: Set<string>\n installCommands: Set<string>\n managerName: string\n nothrow?: boolean\n rawArgs: string[] | readonly string[]\n spinner?: Spinner | undefined\n viewAllRisks: boolean\n}\n\nexport type PackageScanResult = {\n alertsMap?: AlertsByPurl\n shouldExit: boolean\n}\n\n/**\n * Scan packages and log alerts if found.\n */\nexport async function scanPackagesAndLogAlerts(\n options: PackageScanOptions,\n): Promise<PackageScanResult> {\n const {\n acceptRisks,\n command,\n dlxCommands,\n installCommands,\n managerName,\n nothrow = true,\n rawArgs,\n spinner,\n viewAllRisks,\n } = options\n\n let { cwd = process.cwd() } = options\n if (cwd instanceof URL) {\n cwd = fileURLToPath(cwd)\n }\n\n // Check if this is a command that needs security scanning.\n const isDlxCommand = dlxCommands && command && dlxCommands.has(command)\n const isInstallCommand = command && installCommands.has(command)\n const needsScanning = isDlxCommand || isInstallCommand\n\n if (!needsScanning || rawArgs.includes(FLAG_DRY_RUN)) {\n return { shouldExit: false }\n }\n\n // Extract package names from command arguments before any downloads.\n let packagePurls: string[] = []\n\n if (isDlxCommand || isAddCommand(command)) {\n packagePurls = extractPackagePurlsFromCommandArgs(rawArgs)\n } else if (isInstallCommand) {\n // For install/update, scan dependencies from package.json.\n // Note: This scans direct dependencies only.\n packagePurls = await extractPackagePurlsFromPackageJson(cwd)\n }\n\n if (!packagePurls.length) {\n return { shouldExit: false }\n }\n\n debugScan('start', packagePurls.length)\n debugDir('inspect', { packagePurls })\n\n try {\n const alertsMap = await getAlertsMapFromPurls(packagePurls, {\n filter: acceptRisks\n ? { actions: ['error'], blocked: true }\n : { actions: ['error', 'monitor', 'warn'] },\n nothrow,\n spinner,\n })\n\n if (alertsMap.size) {\n process.exitCode = 1\n spinner?.stop()\n logAlertsMap(alertsMap, {\n hideAt: viewAllRisks ? 'none' : 'middle',\n output: process.stderr,\n })\n\n const errorMessage = `Socket ${managerName} exiting due to risks.${\n viewAllRisks\n ? ''\n : `\\nView all risks - Rerun with environment variable ${constants.SOCKET_CLI_VIEW_ALL_RISKS}=1.`\n }${\n acceptRisks\n ? ''\n : `\\nAccept risks - Rerun with environment variable ${constants.SOCKET_CLI_ACCEPT_RISKS}=1.`\n }`.trim()\n\n logger.error(errorMessage)\n return { alertsMap, shouldExit: true }\n }\n } catch (e) {\n spinner?.stop()\n // Re-throw process.exit errors from tests.\n if (e instanceof Error && e.message === 'process.exit called') {\n throw e\n }\n debugScan('error', undefined, e)\n // Continue with installation if scanning fails.\n }\n\n debugScan('complete', packagePurls.length)\n debugDir('inspect', { args: rawArgs.slice(1) })\n\n return { shouldExit: false }\n}\n","import { existsSync } from 'node:fs'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport { debugDir, debugFn } from '@socketsecurity/registry/lib/debug'\nimport { logger } from '@socketsecurity/registry/lib/logger'\nimport { spawn } from '@socketsecurity/registry/lib/spawn'\n\nimport constants, {\n FLAG_DRY_RUN,\n PNPM,\n PNPM_LOCK_YAML,\n} from '../../constants.mts'\nimport { getAlertsMapFromPnpmLockfile } from '../../utils/alerts-map.mts'\nimport {\n cmdFlagsToString,\n isAddCommand,\n isPnpmLockfileScanCommand,\n} from '../../utils/cmd.mts'\nimport { parsePnpmLockfile, readPnpmLockfile } from '../../utils/pnpm.mts'\nimport { getPublicApiToken } from '../../utils/sdk.mts'\nimport { installPnpmLinks } from '../../utils/shadow-links.mts'\nimport { logAlertsMap } from '../../utils/socket-package-alert.mts'\nimport { scanPackagesAndLogAlerts } from '../common.mts'\nimport { ensureIpcInStdio } from '../stdio-ipc.mts'\n\nimport type { IpcObject } from '../../constants.mts'\nimport type {\n SpawnExtra,\n SpawnOptions,\n SpawnResult,\n} from '@socketsecurity/registry/lib/spawn'\n\nexport type ShadowPnpmOptions = SpawnOptions & {\n ipc?: IpcObject | undefined\n}\n\nexport type ShadowPnpmResult = {\n spawnPromise: SpawnResult<string, SpawnExtra | undefined>\n}\n\nconst DLX_COMMANDS = new Set(['dlx'])\n\nconst INSTALL_COMMANDS = new Set([\n 'add',\n 'i',\n 'install',\n 'install-test',\n 'it',\n 'update',\n 'up',\n])\n\nexport default async function shadowPnpmBin(\n args: string[] | readonly string[] = process.argv.slice(2),\n options?: ShadowPnpmOptions | undefined,\n extra?: SpawnExtra | undefined,\n): Promise<ShadowPnpmResult> {\n const opts = { __proto__: null, ...options } as ShadowPnpmOptions\n const { env: spawnEnv, ipc, ...spawnOpts } = opts\n\n let { cwd = process.cwd() } = opts\n if (cwd instanceof URL) {\n cwd = fileURLToPath(cwd)\n }\n\n const terminatorPos = args.indexOf('--')\n const rawPnpmArgs = terminatorPos === -1 ? args : args.slice(0, terminatorPos)\n\n const { spinner } = opts\n const wasSpinning = !!spinner?.isSpinning\n\n // Check if this is a command that needs security scanning.\n const command = rawPnpmArgs[0]\n const isDlxCommand = command && DLX_COMMANDS.has(command)\n const isInstallCommand = command && INSTALL_COMMANDS.has(command)\n const needsScanning = isDlxCommand || isInstallCommand\n\n spinner?.start()\n\n if (needsScanning && !rawPnpmArgs.includes(FLAG_DRY_RUN)) {\n const acceptRisks = !!constants.ENV.SOCKET_CLI_ACCEPT_RISKS\n const viewAllRisks = !!constants.ENV.SOCKET_CLI_VIEW_ALL_RISKS\n\n // Handle add and dlx commands with shared utility.\n if (isDlxCommand || isAddCommand(command)) {\n const scanResult = await scanPackagesAndLogAlerts({\n acceptRisks,\n command,\n cwd,\n dlxCommands: DLX_COMMANDS,\n installCommands: INSTALL_COMMANDS,\n managerName: PNPM,\n rawArgs: rawPnpmArgs,\n spinner,\n viewAllRisks,\n })\n\n if (scanResult.shouldExit) {\n // eslint-disable-next-line n/no-process-exit\n process.exit(1)\n // This line is never reached in production, but helps tests.\n throw new Error('process.exit called')\n }\n } else if (isPnpmLockfileScanCommand(command)) {\n // For install/update, scan all dependencies from pnpm-lock.yaml\n const pnpmLockPath = path.join(cwd, PNPM_LOCK_YAML)\n if (existsSync(pnpmLockPath)) {\n try {\n const lockfileContent = await readPnpmLockfile(pnpmLockPath)\n if (lockfileContent) {\n const lockfile = parsePnpmLockfile(lockfileContent)\n if (lockfile) {\n // Use existing function to scan the entire lockfile\n debugFn(\n 'notice',\n `scanning: all dependencies from ${PNPM_LOCK_YAML}`,\n )\n\n const alertsMap = await getAlertsMapFromPnpmLockfile(lockfile, {\n nothrow: true,\n filter: acceptRisks\n ? { actions: ['error'], blocked: true }\n : { actions: ['error', 'monitor', 'warn'] },\n })\n\n spinner?.stop()\n\n if (alertsMap.size) {\n process.exitCode = 1\n logAlertsMap(alertsMap, {\n hideAt: viewAllRisks ? 'none' : 'middle',\n output: process.stderr,\n })\n\n const errorMessage = `Socket ${PNPM} exiting due to risks.${\n viewAllRisks\n ? ''\n : `\\nView all risks - Rerun with environment variable ${constants.SOCKET_CLI_VIEW_ALL_RISKS}=1.`\n }${\n acceptRisks\n ? ''\n : `\\nAccept risks - Rerun with environment variable ${constants.SOCKET_CLI_ACCEPT_RISKS}=1.`\n }`.trim()\n\n logger.error(errorMessage)\n // eslint-disable-next-line n/no-process-exit\n process.exit(1)\n // This line is never reached in production, but helps tests.\n throw new Error('process.exit called')\n }\n\n // Return early since we've already done the scanning\n debugFn(\n 'notice',\n 'complete: lockfile scanning, proceeding with install',\n )\n }\n }\n } catch (e) {\n debugFn('error', `${PNPM} lockfile scanning failed`)\n debugDir('error', e)\n }\n } else {\n debugFn(\n 'notice',\n `skip: no ${PNPM_LOCK_YAML} found, skipping bulk install scanning`,\n )\n }\n }\n\n debugFn('notice', 'complete: scanning, proceeding with install')\n }\n\n const realPnpmPath = await installPnpmLinks(constants.shadowBinPath)\n\n const otherArgs = terminatorPos === -1 ? [] : args.slice(terminatorPos)\n const suffixArgs = [...rawPnpmArgs, ...otherArgs]\n\n debugFn(\n 'notice',\n `spawn: ${PNPM} shadow bin ${realPnpmPath} ${cmdFlagsToString(suffixArgs)}`,\n )\n\n if (wasSpinning) {\n spinner?.start()\n }\n\n // Set up stdio with IPC channel.\n const stdio = ensureIpcInStdio(spawnOpts.stdio)\n\n const spawnPromise = spawn(\n realPnpmPath,\n suffixArgs,\n {\n ...spawnOpts,\n cwd,\n env: {\n ...process.env,\n ...spawnEnv,\n },\n stdio,\n // On Windows, pnpm is often a .cmd file that requires shell execution.\n // The spawn function from @socketsecurity/registry will handle this properly\n // when shell is true.\n shell: constants.WIN32,\n },\n extra,\n )\n\n // Send IPC handshake.\n spawnPromise.process.send({\n [constants.SOCKET_IPC_HANDSHAKE]: {\n [constants.SOCKET_CLI_SHADOW_API_TOKEN]: getPublicApiToken(),\n [constants.SOCKET_CLI_SHADOW_BIN]: PNPM,\n [constants.SOCKET_CLI_SHADOW_PROGRESS]: true,\n ...ipc,\n },\n })\n\n return { spawnPromise }\n}\n"],"names":["packagePurls","debugScan","debugFn","debugDir","nothrow","viewAllRisks","cwd","shouldExit","blocked","actions","spinner","hideAt","logger","args","__proto__","env","dlxCommands","installCommands","managerName","rawArgs","process","spawnPromise"],"mappings":";;;;;;;;;;;;;AAgBA;AACA;AACA;AACA;AACA;AACA;;;AAKE;;AAKA;AACE;AACA;AACEA;AACF;AACF;AAEA;AACF;;AAEA;AACA;AACA;AACA;AACA;;;AAMI;AAEA;;;;AAIE;;AAGF;AAAa;AAAS;AAAW;AAC/B;AAGA;AACEA;AACF;AACF;AAEAC;;AAEAC;AAIAC;AACF;AAEA;AACF;AAoBA;AACA;AACA;AACO;;;;;;;AASHC;;;AAGAC;AACF;;AAEMC;AAAoB;;AAExBA;AACF;;AAEA;;;AAGA;;;AAGWC;;AACX;;AAEA;;AAGA;AACEP;;AAEA;AACA;AACAA;AACF;AAEA;;AACWO;;AACX;AAEAN;;AACsBD;AAAa;;AAGjC;;;AAE4BQ;AAAc;AAClCC;;;AAENC;AACF;;;;;AAMIC;;AAEF;AAEA;AAUAC;;;AACoBL;;AACtB;;;AAGA;;AAEE;AACF;AACAN;AACA;AACF;AAEAA;;AACsBY;AAAuB;;AAEpCN;;AACX;;ACxJA;AAEA;AAUe;AAKb;AAAeO;;;;AACPC;;;AAAiC;;AAEnCT;AAAoB;;AAExBA;AACF;AAEA;AACA;;AAEQI;AAAQ;AAChB;;AAEA;AACA;;;AAGA;;;;;;AAQE;AACA;AACE;;;;AAIEM;AACAC;AACAC;AACAC;;AAEAd;AACF;;AAGE;AACAe;AACA;AACA;AACF;AACF;AACE;;AAEA;;AAEI;AACA;AACE;AACA;AACE;AACAlB;AAKA;AACEE;;;AAE0BI;AAAc;AAClCC;AAAsC;AAC9C;;;;;AAOIE;;AAEF;AAEA;AAUAC;AACA;AACAQ;AACA;AACA;AACF;;AAEA;AACAlB;AAIF;AACF;;AAEAA;AACAC;AACF;AACF;AACED;AAIF;AACF;AAEAA;AACF;;AAIA;;AAGAA;AAKA;;AAEA;;AAEA;AACA;AAEA;AAII;;AAEAa;;;;;AAKA;AACA;AACA;;;;AAMJ;AACAM;;AAEI;AACA;AACA;;AAEF;AACF;;AAESA;;AACX;;;","debugId":"b4cf863e-3d5c-4dcc-ad18-e70648911b2"}
|
package/dist/shadow-yarn-bin.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var require$$0 = require('node:url');
|
|
3
4
|
var require$$9 = require('../external/@socketsecurity/registry/lib/debug');
|
|
4
5
|
var spawn = require('../external/@socketsecurity/registry/lib/spawn');
|
|
5
6
|
var constants = require('./constants.js');
|
|
@@ -19,24 +20,29 @@ async function shadowYarnBin(args = process.argv.slice(2), options, extra) {
|
|
|
19
20
|
ipc,
|
|
20
21
|
...spawnOpts
|
|
21
22
|
} = opts;
|
|
23
|
+
let {
|
|
24
|
+
cwd = process.cwd()
|
|
25
|
+
} = opts;
|
|
26
|
+
if (cwd instanceof URL) {
|
|
27
|
+
cwd = require$$0.fileURLToPath(cwd);
|
|
28
|
+
}
|
|
29
|
+
const terminatorPos = args.indexOf('--');
|
|
30
|
+
const rawYarnArgs = terminatorPos === -1 ? args : args.slice(0, terminatorPos);
|
|
22
31
|
const {
|
|
23
32
|
spinner
|
|
24
33
|
} = opts;
|
|
25
34
|
const wasSpinning = !!spinner?.isSpinning;
|
|
26
35
|
spinner?.start();
|
|
27
|
-
const terminatorPos = args.indexOf('--');
|
|
28
|
-
const rawYarnArgs = terminatorPos === -1 ? args : args.slice(0, terminatorPos);
|
|
29
|
-
const otherArgs = terminatorPos === -1 ? [] : args.slice(terminatorPos);
|
|
30
36
|
|
|
31
37
|
// Check for package scanning.
|
|
32
38
|
const command = rawYarnArgs[0];
|
|
33
39
|
const scanResult = await shadowPnpmBin.scanPackagesAndLogAlerts({
|
|
34
40
|
acceptRisks: !!constants.default.ENV.SOCKET_CLI_ACCEPT_RISKS,
|
|
35
41
|
command,
|
|
36
|
-
cwd
|
|
42
|
+
cwd,
|
|
37
43
|
dlxCommands: DLX_COMMANDS,
|
|
38
44
|
installCommands: INSTALL_COMMANDS,
|
|
39
|
-
managerName:
|
|
45
|
+
managerName: constants.YARN,
|
|
40
46
|
rawArgs: rawYarnArgs,
|
|
41
47
|
spinner,
|
|
42
48
|
viewAllRisks: !!constants.default.ENV.SOCKET_CLI_VIEW_ALL_RISKS
|
|
@@ -48,7 +54,7 @@ async function shadowYarnBin(args = process.argv.slice(2), options, extra) {
|
|
|
48
54
|
throw new Error('process.exit called');
|
|
49
55
|
}
|
|
50
56
|
const realYarnPath = await utils.installYarnLinks(constants.default.shadowBinPath);
|
|
51
|
-
|
|
57
|
+
const otherArgs = terminatorPos === -1 ? [] : args.slice(terminatorPos);
|
|
52
58
|
const suffixArgs = [...rawYarnArgs, ...otherArgs];
|
|
53
59
|
require$$9.debugFn('notice', `spawn: ${constants.YARN} shadow bin ${realYarnPath} ${utils.cmdFlagsToString(suffixArgs)}`);
|
|
54
60
|
if (wasSpinning) {
|
|
@@ -59,6 +65,7 @@ async function shadowYarnBin(args = process.argv.slice(2), options, extra) {
|
|
|
59
65
|
const stdio = shadowNpmBin.ensureIpcInStdio(spawnOpts.stdio);
|
|
60
66
|
const spawnPromise = spawn.spawn(realYarnPath, suffixArgs, {
|
|
61
67
|
...spawnOpts,
|
|
68
|
+
cwd,
|
|
62
69
|
env: {
|
|
63
70
|
...process.env,
|
|
64
71
|
...spawnEnv
|
|
@@ -85,5 +92,5 @@ async function shadowYarnBin(args = process.argv.slice(2), options, extra) {
|
|
|
85
92
|
}
|
|
86
93
|
|
|
87
94
|
module.exports = shadowYarnBin;
|
|
88
|
-
//# debugId=
|
|
95
|
+
//# debugId=673b7dc1-02c4-46a2-b70b-e0f78c541d47
|
|
89
96
|
//# sourceMappingURL=shadow-yarn-bin.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadow-yarn-bin.js","sources":["../src/shadow/yarn/bin.mts"],"sourcesContent":["import { debugFn } from '@socketsecurity/registry/lib/debug'\nimport { spawn } from '@socketsecurity/registry/lib/spawn'\n\nimport constants, { YARN } from '../../constants.mts'\nimport { cmdFlagsToString } from '../../utils/cmd.mts'\nimport { getPublicApiToken } from '../../utils/sdk.mts'\nimport { installYarnLinks } from '../../utils/shadow-links.mts'\nimport { scanPackagesAndLogAlerts } from '../common.mts'\nimport { ensureIpcInStdio } from '../stdio-ipc.mts'\n\nimport type { IpcObject } from '../../constants.mts'\nimport type {\n SpawnExtra,\n SpawnOptions,\n SpawnResult,\n} from '@socketsecurity/registry/lib/spawn'\n\nexport type ShadowYarnOptions = SpawnOptions & {\n ipc?: IpcObject | undefined\n}\n\nexport type ShadowYarnResult = {\n spawnPromise: SpawnResult<string, SpawnExtra | undefined>\n}\n\nconst DLX_COMMANDS = new Set(['dlx'])\n\nconst INSTALL_COMMANDS = new Set([\n 'add',\n 'install',\n 'up',\n 'upgrade',\n 'upgrade-interactive',\n])\n\nexport default async function shadowYarnBin(\n args: string[] | readonly string[] = process.argv.slice(2),\n options?: ShadowYarnOptions | undefined,\n extra?: SpawnExtra | undefined,\n): Promise<ShadowYarnResult> {\n const opts = { __proto__: null, ...options } as ShadowYarnOptions\n const { env: spawnEnv, ipc, ...spawnOpts } = opts\n
|
|
1
|
+
{"version":3,"file":"shadow-yarn-bin.js","sources":["../src/shadow/yarn/bin.mts"],"sourcesContent":["import { fileURLToPath } from 'node:url'\n\nimport { debugFn } from '@socketsecurity/registry/lib/debug'\nimport { spawn } from '@socketsecurity/registry/lib/spawn'\n\nimport constants, { YARN } from '../../constants.mts'\nimport { cmdFlagsToString } from '../../utils/cmd.mts'\nimport { getPublicApiToken } from '../../utils/sdk.mts'\nimport { installYarnLinks } from '../../utils/shadow-links.mts'\nimport { scanPackagesAndLogAlerts } from '../common.mts'\nimport { ensureIpcInStdio } from '../stdio-ipc.mts'\n\nimport type { IpcObject } from '../../constants.mts'\nimport type {\n SpawnExtra,\n SpawnOptions,\n SpawnResult,\n} from '@socketsecurity/registry/lib/spawn'\n\nexport type ShadowYarnOptions = SpawnOptions & {\n ipc?: IpcObject | undefined\n}\n\nexport type ShadowYarnResult = {\n spawnPromise: SpawnResult<string, SpawnExtra | undefined>\n}\n\nconst DLX_COMMANDS = new Set(['dlx'])\n\nconst INSTALL_COMMANDS = new Set([\n 'add',\n 'install',\n 'up',\n 'upgrade',\n 'upgrade-interactive',\n])\n\nexport default async function shadowYarnBin(\n args: string[] | readonly string[] = process.argv.slice(2),\n options?: ShadowYarnOptions | undefined,\n extra?: SpawnExtra | undefined,\n): Promise<ShadowYarnResult> {\n const opts = { __proto__: null, ...options } as ShadowYarnOptions\n const { env: spawnEnv, ipc, ...spawnOpts } = opts\n\n let { cwd = process.cwd() } = opts\n if (cwd instanceof URL) {\n cwd = fileURLToPath(cwd)\n }\n\n const terminatorPos = args.indexOf('--')\n const rawYarnArgs = terminatorPos === -1 ? args : args.slice(0, terminatorPos)\n\n const { spinner } = opts\n const wasSpinning = !!spinner?.isSpinning\n\n spinner?.start()\n\n // Check for package scanning.\n const command = rawYarnArgs[0]\n const scanResult = await scanPackagesAndLogAlerts({\n acceptRisks: !!constants.ENV.SOCKET_CLI_ACCEPT_RISKS,\n command,\n cwd,\n dlxCommands: DLX_COMMANDS,\n installCommands: INSTALL_COMMANDS,\n managerName: YARN,\n rawArgs: rawYarnArgs,\n spinner,\n viewAllRisks: !!constants.ENV.SOCKET_CLI_VIEW_ALL_RISKS,\n })\n\n if (scanResult.shouldExit) {\n // eslint-disable-next-line n/no-process-exit\n process.exit(1)\n // This line is never reached in production, but helps tests.\n throw new Error('process.exit called')\n }\n\n const realYarnPath = await installYarnLinks(constants.shadowBinPath)\n\n const otherArgs = terminatorPos === -1 ? [] : args.slice(terminatorPos)\n const suffixArgs = [...rawYarnArgs, ...otherArgs]\n\n debugFn(\n 'notice',\n `spawn: ${YARN} shadow bin ${realYarnPath} ${cmdFlagsToString(suffixArgs)}`,\n )\n\n if (wasSpinning) {\n spinner?.start()\n }\n\n // Set up stdio with IPC channel.\n const stdio = ensureIpcInStdio(spawnOpts.stdio)\n\n const spawnPromise = spawn(\n realYarnPath,\n suffixArgs,\n {\n ...spawnOpts,\n cwd,\n env: {\n ...process.env,\n ...spawnEnv,\n },\n stdio,\n // On Windows, yarn is often a .cmd file that requires shell execution.\n // The spawn function from @socketsecurity/registry will handle this properly\n // when shell is true.\n shell: constants.WIN32,\n },\n extra,\n )\n\n // Send IPC handshake.\n spawnPromise.process.send({\n [constants.SOCKET_IPC_HANDSHAKE]: {\n [constants.SOCKET_CLI_SHADOW_API_TOKEN]: getPublicApiToken(),\n [constants.SOCKET_CLI_SHADOW_BIN]: YARN,\n [constants.SOCKET_CLI_SHADOW_PROGRESS]: true,\n ...ipc,\n },\n })\n\n return { spawnPromise }\n}\n"],"names":["__proto__","env","cwd","spinner","acceptRisks","dlxCommands","installCommands","managerName","rawArgs","viewAllRisks","process","debugFn","spawnPromise"],"mappings":";;;;;;;;;;AA2BA;AAEA;AAQe;AAKb;AAAeA;;;;AACPC;;;AAAiC;;AAEnCC;AAAoB;;AAExBA;AACF;AAEA;AACA;;AAEQC;AAAQ;AAChB;;;AAIA;AACA;AACA;AACEC;;;AAGAC;AACAC;AACAC;AACAC;;AAEAC;AACF;;AAGE;AACAC;AACA;AACA;AACF;;AAIA;;AAGAC;AAKA;;AAEA;;AAEA;AACA;AAEA;AAII;;AAEAV;;;;;AAKA;AACA;AACA;;;;AAMJ;AACAW;;AAEI;AACA;AACA;;AAEF;AACF;;AAESA;;AACX;;","debugId":"673b7dc1-02c4-46a2-b70b-e0f78c541d47"}
|