@socketsecurity/cli-with-sentry 1.1.13 → 1.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/cli.js +50 -58
  3. package/dist/cli.js.map +1 -1
  4. package/dist/constants.js +107 -5
  5. package/dist/constants.js.map +1 -1
  6. package/dist/flags.js.map +1 -1
  7. package/dist/npm-cli.js +3 -2
  8. package/dist/npm-cli.js.map +1 -1
  9. package/dist/shadow-npm-inject.js.map +1 -1
  10. package/dist/tsconfig.dts.tsbuildinfo +1 -1
  11. package/dist/types/commands/fix/cmd-fix.d.mts.map +1 -1
  12. package/dist/types/commands/fix/coana-fix.d.mts.map +1 -1
  13. package/dist/types/commands/fix/git.d.mts +1 -1
  14. package/dist/types/commands/fix/git.d.mts.map +1 -1
  15. package/dist/types/commands/fix/handle-fix.d.mts +2 -1
  16. package/dist/types/commands/fix/handle-fix.d.mts.map +1 -1
  17. package/dist/types/commands/fix/pull-request.d.mts +1 -1
  18. package/dist/types/commands/fix/pull-request.d.mts.map +1 -1
  19. package/dist/types/commands/fix/types.d.mts +1 -0
  20. package/dist/types/commands/fix/types.d.mts.map +1 -1
  21. package/dist/types/commands/login/apply-login.d.mts.map +1 -1
  22. package/dist/types/commands/login/attempt-login.d.mts.map +1 -1
  23. package/dist/types/commands/logout/apply-logout.d.mts.map +1 -1
  24. package/dist/types/commands/manifest/run-cdxgen.d.mts.map +1 -1
  25. package/dist/types/commands/scan/perform-reachability-analysis.d.mts.map +1 -1
  26. package/dist/types/constants.d.mts +74 -6
  27. package/dist/types/constants.d.mts.map +1 -1
  28. package/dist/types/flags.d.mts +1 -1
  29. package/dist/types/flags.d.mts.map +1 -1
  30. package/dist/types/shadow/npm/arborist/types.d.mts +10 -10
  31. package/dist/types/shadow/npm/arborist/types.d.mts.map +1 -1
  32. package/dist/types/types.d.mts +4 -4
  33. package/dist/types/types.d.mts.map +1 -1
  34. package/dist/types/utils/alert/artifact.d.mts +1 -1
  35. package/dist/types/utils/alert/artifact.d.mts.map +1 -1
  36. package/dist/types/utils/api.d.mts +2 -2
  37. package/dist/types/utils/api.d.mts.map +1 -1
  38. package/dist/types/utils/coana.d.mts +0 -4
  39. package/dist/types/utils/coana.d.mts.map +1 -1
  40. package/dist/types/utils/config.d.mts +4 -3
  41. package/dist/types/utils/config.d.mts.map +1 -1
  42. package/dist/types/utils/determine-org-slug.d.mts.map +1 -1
  43. package/dist/types/utils/dlx.d.mts +33 -0
  44. package/dist/types/utils/dlx.d.mts.map +1 -0
  45. package/dist/types/utils/errors.d.mts +1 -1
  46. package/dist/types/utils/errors.d.mts.map +1 -1
  47. package/dist/types/utils/github.d.mts +3 -3
  48. package/dist/types/utils/github.d.mts.map +1 -1
  49. package/dist/types/utils/glob.d.mts.map +1 -1
  50. package/dist/types/utils/meow-with-subcommands.d.mts +1 -1
  51. package/dist/types/utils/meow-with-subcommands.d.mts.map +1 -1
  52. package/dist/types/utils/package-environment.d.mts.map +1 -1
  53. package/dist/types/utils/sdk.d.mts.map +1 -1
  54. package/dist/types/utils/socket-json.d.mts +27 -27
  55. package/dist/types/utils/socket-json.d.mts.map +1 -1
  56. package/dist/utils.js +283 -140
  57. package/dist/utils.js.map +1 -1
  58. package/dist/vendor.js +235 -235
  59. package/package.json +2 -2
package/dist/utils.js CHANGED
@@ -28,8 +28,8 @@ var globs = require('../external/@socketsecurity/registry/lib/globs');
28
28
  var streams = require('../external/@socketsecurity/registry/lib/streams');
29
29
 
30
30
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
31
- const sensitiveConfigKeyLookup = new Set(['apiToken']);
32
- const supportedConfig = new Map([['apiBaseUrl', 'Base URL of the Socket API endpoint'], ['apiProxy', 'A proxy through which to access the Socket API'], ['apiToken', 'The Socket API token required to access most Socket API endpoints'], ['defaultOrg', 'The default org slug to use; usually the org your Socket API token has access to. When set, all orgSlug arguments are implied to be this value.'], ['enforcedOrgs', 'Orgs in this list have their security policies enforced on this machine'], ['skipAskToPersistDefaultOrg', 'This flag prevents the Socket CLI from asking you to persist the org slug when you selected one interactively'], ['org', 'Alias for defaultOrg']]);
31
+ const sensitiveConfigKeyLookup = new Set([constants.CONFIG_KEY_API_TOKEN]);
32
+ const supportedConfig = new Map([[constants.CONFIG_KEY_API_BASE_URL, 'Base URL of the Socket API endpoint'], [constants.CONFIG_KEY_API_PROXY, 'A proxy through which to access the Socket API'], [constants.CONFIG_KEY_API_TOKEN, 'The Socket API token required to access most Socket API endpoints'], [constants.CONFIG_KEY_DEFAULT_ORG, 'The default org slug to use; usually the org your Socket API token has access to. When set, all orgSlug arguments are implied to be this value.'], [constants.CONFIG_KEY_ENFORCED_ORGS, 'Orgs in this list have their security policies enforced on this machine'], ['skipAskToPersistDefaultOrg', 'This flag prevents the Socket CLI from asking you to persist the org slug when you selected one interactively'], [constants.CONFIG_KEY_ORG, 'Alias for defaultOrg']]);
33
33
  const supportedConfigEntries = [...supportedConfig.entries()].sort((a, b) => sorts.naturalCompare(a[0], b[0]));
34
34
  const supportedConfigKeys = supportedConfigEntries.map(p => p[0]);
35
35
  function getConfigValues() {
@@ -52,7 +52,7 @@ function getConfigValues() {
52
52
  if (_cachedConfig['apiKey']) {
53
53
  const token = _cachedConfig['apiKey'];
54
54
  delete _cachedConfig['apiKey'];
55
- updateConfigValue('apiToken', token);
55
+ updateConfigValue(constants.CONFIG_KEY_API_TOKEN, token);
56
56
  }
57
57
  } else {
58
58
  fs$1.mkdirSync(path.dirname(socketAppDataPath), {
@@ -67,7 +67,7 @@ function normalizeConfigKey(key) {
67
67
  // Note: apiKey was the old name of the token. When we load a config with
68
68
  // property apiKey, we'll copy that to apiToken and delete the old property.
69
69
  // We added `org` as a convenience alias for `defaultOrg`
70
- const normalizedKey = key === 'apiKey' ? 'apiToken' : key === 'org' ? 'defaultOrg' : key;
70
+ const normalizedKey = key === 'apiKey' ? constants.CONFIG_KEY_API_TOKEN : key === constants.CONFIG_KEY_ORG ? constants.CONFIG_KEY_DEFAULT_ORG : key;
71
71
  if (!isSupportedConfigKey(normalizedKey)) {
72
72
  return {
73
73
  ok: false,
@@ -83,10 +83,10 @@ function normalizeConfigKey(key) {
83
83
  function findSocketYmlSync(dir = process.cwd()) {
84
84
  let prevDir = null;
85
85
  while (dir !== prevDir) {
86
- let ymlPath = path.join(dir, 'socket.yml');
86
+ let ymlPath = path.join(dir, constants.SOCKET_YML);
87
87
  let yml = fs.safeReadFileSync(ymlPath);
88
88
  if (yml === undefined) {
89
- ymlPath = path.join(dir, 'socket.yaml');
89
+ ymlPath = path.join(dir, constants.SOCKET_YAML);
90
90
  yml = fs.safeReadFileSync(ymlPath);
91
91
  }
92
92
  if (typeof yml === 'string') {
@@ -266,11 +266,11 @@ function updateConfigValue(configKey, value) {
266
266
  };
267
267
  }
268
268
 
269
- const require$2 = require$$5.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('utils.js', document.baseURI).href)));
269
+ const require$3 = require$$5.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('utils.js', document.baseURI).href)));
270
270
  let _requirements;
271
271
  function getRequirements() {
272
272
  if (_requirements === undefined) {
273
- _requirements = /*@__PURE__*/require$2(path.join(constants.default.rootPath, 'requirements.json'));
273
+ _requirements = /*@__PURE__*/require$3(path.join(constants.default.rootPath, 'requirements.json'));
274
274
  }
275
275
  return _requirements;
276
276
  }
@@ -288,13 +288,13 @@ const TOKEN_VISIBLE_LENGTH = 5;
288
288
 
289
289
  // The Socket API server that should be used for operations.
290
290
  function getDefaultApiBaseUrl$1() {
291
- const baseUrl = constants.default.ENV.SOCKET_CLI_API_BASE_URL || getConfigValueOrUndef('apiBaseUrl');
291
+ const baseUrl = constants.default.ENV.SOCKET_CLI_API_BASE_URL || getConfigValueOrUndef(constants.CONFIG_KEY_API_BASE_URL);
292
292
  return require$$13.isUrl(baseUrl) ? baseUrl : undefined;
293
293
  }
294
294
 
295
295
  // The Socket API server that should be used for operations.
296
296
  function getDefaultProxyUrl() {
297
- const apiProxy = constants.default.ENV.SOCKET_CLI_API_PROXY || getConfigValueOrUndef('apiProxy');
297
+ const apiProxy = constants.default.ENV.SOCKET_CLI_API_PROXY || getConfigValueOrUndef(constants.CONFIG_KEY_API_PROXY);
298
298
  return require$$13.isUrl(apiProxy) ? apiProxy : undefined;
299
299
  }
300
300
 
@@ -305,7 +305,7 @@ function getDefaultApiToken() {
305
305
  _defaultToken = undefined;
306
306
  return _defaultToken;
307
307
  }
308
- const key = constants.default.ENV.SOCKET_CLI_API_TOKEN || getConfigValueOrUndef('apiToken') || _defaultToken;
308
+ const key = constants.default.ENV.SOCKET_CLI_API_TOKEN || getConfigValueOrUndef(constants.CONFIG_KEY_API_TOKEN) || _defaultToken;
309
309
  _defaultToken = strings.isNonEmptyString(key) ? key : undefined;
310
310
  return _defaultToken;
311
311
  }
@@ -404,7 +404,7 @@ function logPermissionsFor403(cmdPath) {
404
404
 
405
405
  // The Socket API server that should be used for operations.
406
406
  function getDefaultApiBaseUrl() {
407
- const baseUrl = constants.default.ENV.SOCKET_CLI_API_BASE_URL || getConfigValueOrUndef('apiBaseUrl');
407
+ const baseUrl = constants.default.ENV.SOCKET_CLI_API_BASE_URL || getConfigValueOrUndef(constants.CONFIG_KEY_API_BASE_URL);
408
408
  if (strings.isNonEmptyString(baseUrl)) {
409
409
  return baseUrl;
410
410
  }
@@ -416,16 +416,16 @@ function getDefaultApiBaseUrl() {
416
416
  * Get user-friendly error message for HTTP status codes.
417
417
  */
418
418
  async function getErrorMessageForHttpStatusCode(code) {
419
- if (code === 400) {
419
+ if (code === constants.HTTP_STATUS_BAD_REQUEST) {
420
420
  return 'One of the options passed might be incorrect';
421
421
  }
422
- if (code === 403 || code === 401) {
422
+ if (code === constants.HTTP_STATUS_FORBIDDEN || code === constants.HTTP_STATUS_UNAUTHORIZED) {
423
423
  return 'Your Socket API token may not have the required permissions for this command or you might be trying to access (data from) an organization that is not linked to the API token you are logged in with';
424
424
  }
425
- if (code === 404) {
425
+ if (code === constants.HTTP_STATUS_NOT_FOUND) {
426
426
  return 'The requested Socket API endpoint was not found (404) or there was no result for the requested parameters. If unexpected, this could be a temporary problem caused by an incident or a bug in the CLI. If the problem persists please let us know.';
427
427
  }
428
- if (code === 500) {
428
+ if (code === constants.HTTP_STATUS_INTERNAL_SERVER_ERROR) {
429
429
  return 'There was an unknown server side problem with your request. This ought to be temporary. Please let us know if this problem persists.';
430
430
  }
431
431
  return `Server responded with status code ${code}`;
@@ -1100,7 +1100,7 @@ function getAsciiHeader(command, orgFlag) {
1100
1100
  const redacting = constants.default.ENV.VITEST;
1101
1101
  const cliVersion = redacting ? REDACTED : constants.default.ENV.INLINED_SOCKET_CLI_VERSION_HASH;
1102
1102
  const nodeVersion = redacting ? REDACTED : process.version;
1103
- const defaultOrg = getConfigValueOrUndef('defaultOrg');
1103
+ const defaultOrg = getConfigValueOrUndef(constants.CONFIG_KEY_DEFAULT_ORG);
1104
1104
  const readOnlyConfig = isReadOnlyConfig() ? '*' : '.';
1105
1105
  const shownToken = redacting ? REDACTED : getVisibleTokenPrefix() || '(not set)';
1106
1106
  const relCwd = redacting ? REDACTED : path$1.normalizePath(tildify(process.cwd()));
@@ -1669,7 +1669,7 @@ async function suggestToPersistOrgSlug(orgSlug) {
1669
1669
  }
1670
1670
 
1671
1671
  async function determineOrgSlug(orgFlag, interactive, dryRun) {
1672
- const defaultOrgSlug = getConfigValueOrUndef('defaultOrg');
1672
+ const defaultOrgSlug = getConfigValueOrUndef(constants.CONFIG_KEY_DEFAULT_ORG);
1673
1673
  let orgSlug = String(orgFlag || defaultOrgSlug || '');
1674
1674
  if (!orgSlug) {
1675
1675
  if (!interactive) {
@@ -2272,6 +2272,60 @@ function* walkNestedMap(map, keys = []) {
2272
2272
  }
2273
2273
  }
2274
2274
 
2275
+ function extractTier1ReachabilityScanId(socketFactsFile) {
2276
+ const json = fs.readJsonSync(socketFactsFile, {
2277
+ throws: false
2278
+ });
2279
+ const tier1ReachabilityScanId = String(json?.['tier1ReachabilityScanId'] ?? '').trim();
2280
+ return tier1ReachabilityScanId.length > 0 ? tier1ReachabilityScanId : undefined;
2281
+ }
2282
+
2283
+ async function findUp(name, options) {
2284
+ const opts = {
2285
+ __proto__: null,
2286
+ ...options
2287
+ };
2288
+ const {
2289
+ cwd = process.cwd(),
2290
+ signal = constants.default.abortSignal
2291
+ } = opts;
2292
+ let {
2293
+ onlyDirectories = false,
2294
+ onlyFiles = true
2295
+ } = opts;
2296
+ if (onlyDirectories) {
2297
+ onlyFiles = false;
2298
+ }
2299
+ if (onlyFiles) {
2300
+ onlyDirectories = false;
2301
+ }
2302
+ let dir = path.resolve(cwd);
2303
+ const {
2304
+ root
2305
+ } = path.parse(dir);
2306
+ const names = [name].flat();
2307
+ while (dir && dir !== root) {
2308
+ for (const name of names) {
2309
+ if (signal?.aborted) {
2310
+ return undefined;
2311
+ }
2312
+ const thePath = path.join(dir, name);
2313
+ try {
2314
+ // eslint-disable-next-line no-await-in-loop
2315
+ const stats = await fs$1.promises.stat(thePath);
2316
+ if (!onlyDirectories && stats.isFile()) {
2317
+ return thePath;
2318
+ }
2319
+ if (!onlyFiles && stats.isDirectory()) {
2320
+ return thePath;
2321
+ }
2322
+ } catch {}
2323
+ }
2324
+ dir = path.dirname(dir);
2325
+ }
2326
+ return undefined;
2327
+ }
2328
+
2275
2329
  const DEFAULT_IGNORE_FOR_GIT_IGNORE = globs.defaultIgnore.filter(p => !p.endsWith('.gitignore'));
2276
2330
  const IGNORED_DIRS = [
2277
2331
  // Taken from ignore-by-default:
@@ -2299,17 +2353,12 @@ const IGNORED_DIR_PATTERNS = IGNORED_DIRS.map(i => `**/${i}`);
2299
2353
  async function getWorkspaceGlobs(agent, cwd = process.cwd()) {
2300
2354
  let workspacePatterns;
2301
2355
  if (agent === constants.PNPM) {
2302
- for (const workspacePath of [path.join(cwd, 'pnpm-workspace.yaml'), path.join(cwd, 'pnpm-workspace.yml')]) {
2303
- // eslint-disable-next-line no-await-in-loop
2304
- const yml = await fs.safeReadFile(workspacePath);
2305
- if (yml) {
2306
- try {
2307
- workspacePatterns = vendor.distExports$1.parse(yml)?.packages;
2308
- } catch {}
2309
- if (workspacePatterns) {
2310
- break;
2311
- }
2312
- }
2356
+ const workspacePath = path.join(cwd, 'pnpm-workspace.yaml');
2357
+ const yml = await fs.safeReadFile(workspacePath);
2358
+ if (yml) {
2359
+ try {
2360
+ workspacePatterns = vendor.distExports$1.parse(yml)?.packages;
2361
+ } catch {}
2313
2362
  }
2314
2363
  } else {
2315
2364
  workspacePatterns = (await packages.readPackageJson(cwd, {
@@ -2570,12 +2619,64 @@ function exitWithBinPathError$2(binName) {
2570
2619
  // eslint-disable-next-line n/no-process-exit
2571
2620
  process.exit(127);
2572
2621
  }
2622
+ let _yarnBinPath;
2623
+ function getYarnBinPath() {
2624
+ if (_yarnBinPath === undefined) {
2625
+ _yarnBinPath = getYarnBinPathDetails().path;
2626
+ if (!_yarnBinPath) {
2627
+ exitWithBinPathError$2(constants.default.YARN);
2628
+ }
2629
+ }
2630
+ return _yarnBinPath;
2631
+ }
2632
+ let _yarnBinPathDetails;
2633
+ function getYarnBinPathDetails() {
2634
+ if (_yarnBinPathDetails === undefined) {
2635
+ _yarnBinPathDetails = findBinPathDetailsSync(constants.default.YARN);
2636
+ }
2637
+ return _yarnBinPathDetails;
2638
+ }
2639
+ function isYarnBinPathShadowed() {
2640
+ return getYarnBinPathDetails().shadowed;
2641
+ }
2642
+
2643
+ let _isYarnBerry;
2644
+ function isYarnBerry() {
2645
+ if (_isYarnBerry === undefined) {
2646
+ try {
2647
+ const yarnBinPath = getYarnBinPath();
2648
+ const result = spawn.spawnSync(yarnBinPath, ['--version'], {
2649
+ encoding: 'utf8',
2650
+ shell: constants.default.WIN32
2651
+ });
2652
+ if (result.status === 0 && result.stdout) {
2653
+ const version = result.stdout;
2654
+ // Yarn Berry starts from version 2.x
2655
+ const majorVersion = parseInt(version.split('.')[0], 10);
2656
+ _isYarnBerry = majorVersion >= 2;
2657
+ } else {
2658
+ _isYarnBerry = false;
2659
+ }
2660
+ } catch {
2661
+ _isYarnBerry = false;
2662
+ }
2663
+ }
2664
+ return _isYarnBerry;
2665
+ }
2666
+
2667
+ function exitWithBinPathError$1(binName) {
2668
+ logger.logger.fail(`Socket unable to locate ${binName}; ensure it is available in the PATH environment variable`);
2669
+ // The exit code 127 indicates that the command or binary being executed
2670
+ // could not be found.
2671
+ // eslint-disable-next-line n/no-process-exit
2672
+ process.exit(127);
2673
+ }
2573
2674
  let _npmBinPath;
2574
2675
  function getNpmBinPath() {
2575
2676
  if (_npmBinPath === undefined) {
2576
2677
  _npmBinPath = getNpmBinPathDetails().path;
2577
2678
  if (!_npmBinPath) {
2578
- exitWithBinPathError$2(constants.NPM);
2679
+ exitWithBinPathError$1(constants.NPM);
2579
2680
  }
2580
2681
  }
2581
2682
  return _npmBinPath;
@@ -2625,7 +2726,7 @@ function getNpxBinPath() {
2625
2726
  if (_npxBinPath === undefined) {
2626
2727
  _npxBinPath = getNpxBinPathDetails().path;
2627
2728
  if (!_npxBinPath) {
2628
- exitWithBinPathError$2('npx');
2729
+ exitWithBinPathError$1('npx');
2629
2730
  }
2630
2731
  }
2631
2732
  return _npxBinPath;
@@ -2760,64 +2861,126 @@ function isHelpFlag(cmdArg) {
2760
2861
  return helpFlags.has(cmdArg);
2761
2862
  }
2762
2863
 
2763
- async function findUp(name, options) {
2764
- const opts = {
2765
- __proto__: null,
2766
- ...options
2767
- };
2864
+ const require$2 = require$$5.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('utils.js', document.baseURI).href)));
2865
+ const {
2866
+ PACKAGE_LOCK_JSON,
2867
+ PNPM_LOCK_YAML,
2868
+ YARN_LOCK
2869
+ } = constants.default;
2870
+ /**
2871
+ * Regex to check if a version string contains range operators.
2872
+ * Matches any version with range operators: ~, ^, >, <, =, x, X, *, spaces, or ||.
2873
+ */
2874
+ const rangeOperatorsRegExp = /[~^><=xX* ]|\|\|/;
2875
+
2876
+ /**
2877
+ * Spawns a package using dlx-style execution (npx/pnpm dlx/yarn dlx).
2878
+ * Automatically detects the appropriate package manager if not specified.
2879
+ * Uses force/update flags to ensure the latest version within the range is fetched.
2880
+ */
2881
+ async function spawnDlx(packageSpec, args, options, spawnExtra) {
2882
+ // If version is not pinned exactly, default to force and silent for better UX.
2883
+ const isNotPinned = rangeOperatorsRegExp.test(packageSpec.version);
2768
2884
  const {
2769
- cwd = process.cwd(),
2770
- signal = constants.default.abortSignal
2771
- } = opts;
2772
- let {
2773
- onlyDirectories = false,
2774
- onlyFiles = true
2775
- } = opts;
2776
- if (onlyDirectories) {
2777
- onlyFiles = false;
2778
- }
2779
- if (onlyFiles) {
2780
- onlyDirectories = false;
2885
+ agent,
2886
+ force = false,
2887
+ silent = isNotPinned,
2888
+ ...shadowOptions
2889
+ } = options ?? {};
2890
+ let finalShadowOptions = shadowOptions;
2891
+ let pm = agent;
2892
+
2893
+ // Auto-detect package manager if not specified.
2894
+ if (!pm) {
2895
+ const pnpmLockPath = await findUp(PNPM_LOCK_YAML, {
2896
+ onlyFiles: true
2897
+ });
2898
+ const yarnLockPath = pnpmLockPath ? undefined : await findUp(YARN_LOCK, {
2899
+ onlyFiles: true
2900
+ });
2901
+ const npmLockPath = pnpmLockPath || yarnLockPath ? undefined : await findUp(PACKAGE_LOCK_JSON, {
2902
+ onlyFiles: true
2903
+ });
2904
+ if (pnpmLockPath) {
2905
+ pm = constants.PNPM;
2906
+ } else if (yarnLockPath) {
2907
+ pm = constants.YARN;
2908
+ } else if (npmLockPath) {
2909
+ pm = constants.NPM;
2910
+ } else {
2911
+ // Default to npm if no lockfile found.
2912
+ pm = constants.NPM;
2913
+ }
2781
2914
  }
2782
- let dir = path.resolve(cwd);
2783
- const {
2784
- root
2785
- } = path.parse(dir);
2786
- const names = [name].flat();
2787
- while (dir && dir !== root) {
2788
- for (const name of names) {
2789
- if (signal?.aborted) {
2790
- return undefined;
2791
- }
2792
- const thePath = path.join(dir, name);
2793
- try {
2794
- // eslint-disable-next-line no-await-in-loop
2795
- const stats = await fs$1.promises.stat(thePath);
2796
- if (!onlyDirectories && stats.isFile()) {
2797
- return thePath;
2798
- }
2799
- if (!onlyFiles && stats.isDirectory()) {
2800
- return thePath;
2915
+ const packageString = `${packageSpec.name}@${packageSpec.version}`;
2916
+
2917
+ // Build command args based on package manager.
2918
+ let binName;
2919
+ let spawnArgs;
2920
+ if (pm === constants.PNPM) {
2921
+ binName = constants.PNPM;
2922
+ spawnArgs = ['dlx'];
2923
+ if (force) {
2924
+ // For pnpm, set dlx-cache-max-age to 0 via env to force fresh download.
2925
+ // This ensures we always get the latest version within the range.
2926
+ finalShadowOptions = {
2927
+ ...finalShadowOptions,
2928
+ env: {
2929
+ ...require$$11.getOwn(finalShadowOptions, 'env'),
2930
+ // Set dlx cache max age to 0 minutes to bypass cache.
2931
+ // The npm_config_ prefix is how pnpm reads config from environment variables.
2932
+ // See: https://pnpm.io/npmrc#settings
2933
+ npm_config_dlx_cache_max_age: '0'
2801
2934
  }
2802
- } catch {}
2935
+ };
2936
+ // Add --ignore-scripts for extra security.
2937
+ // While pnpm dlx allows the executed package's scripts by default,
2938
+ // we disable them since coana/cdxgen/synp don't need postinstall scripts.
2939
+ spawnArgs.push('--ignore-scripts');
2803
2940
  }
2804
- dir = path.dirname(dir);
2941
+ if (silent) {
2942
+ spawnArgs.push('--silent');
2943
+ }
2944
+ spawnArgs.push(packageString, ...args);
2945
+ const shadowPnpmBin = /*@__PURE__*/require$2(constants.default.shadowPnpmBinPath);
2946
+ return await shadowPnpmBin(spawnArgs, finalShadowOptions, spawnExtra);
2947
+ } else if (pm === constants.YARN && isYarnBerry()) {
2948
+ binName = constants.YARN;
2949
+ spawnArgs = ['dlx'];
2950
+ // Yarn dlx runs in a temporary environment by design and should always fetch fresh.
2951
+ if (silent) {
2952
+ spawnArgs.push('--quiet');
2953
+ }
2954
+ spawnArgs.push(packageString, ...args);
2955
+ const shadowYarnBin = /*@__PURE__*/require$2(constants.default.shadowYarnBinPath);
2956
+ return await shadowYarnBin(spawnArgs, finalShadowOptions, spawnExtra);
2957
+ } else {
2958
+ // Use npm exec/npx.
2959
+ // For consistency, we'll use npx which is more commonly used for one-off execution.
2960
+ binName = 'npx';
2961
+ spawnArgs = ['--yes'];
2962
+ if (force) {
2963
+ // Use --force to bypass cache and get latest within range.
2964
+ spawnArgs.push('--force');
2965
+ }
2966
+ if (silent) {
2967
+ spawnArgs.push('--silent');
2968
+ }
2969
+ spawnArgs.push(packageString, ...args);
2970
+ return await shadowNpmBin(binName, spawnArgs, finalShadowOptions, spawnExtra);
2805
2971
  }
2806
- return undefined;
2807
2972
  }
2808
2973
 
2809
- function extractTier1ReachabilityScanId(socketFactsFile) {
2810
- const json = fs.readJsonSync(socketFactsFile, {
2811
- throws: false
2812
- });
2813
- const tier1ReachabilityScanId = String(json?.['tier1ReachabilityScanId'] ?? '').trim();
2814
- return tier1ReachabilityScanId.length > 0 ? tier1ReachabilityScanId : undefined;
2815
- }
2816
- async function spawnCoana(args, orgSlug, options, extra) {
2974
+ /**
2975
+ * Helper to spawn coana with dlx.
2976
+ * Automatically uses force and silent when version is not pinned exactly.
2977
+ * Returns a CResult with stdout extraction for backward compatibility.
2978
+ */
2979
+ async function spawnCoanaDlx(args, orgSlug, options, spawnExtra) {
2817
2980
  const {
2818
2981
  env: spawnEnv,
2819
2982
  ipc,
2820
- ...spawnOpts
2983
+ ...dlxOptions
2821
2984
  } = {
2822
2985
  __proto__: null,
2823
2986
  ...options
@@ -2842,10 +3005,13 @@ async function spawnCoana(args, orgSlug, options, extra) {
2842
3005
  mixinsEnv['SOCKET_CLI_API_PROXY'] = proxyUrl;
2843
3006
  }
2844
3007
  try {
2845
- const {
2846
- spawnPromise
2847
- } = await shadowNpmBin('npx', ['--yes', `@coana-tech/cli@~${constants.default.ENV.INLINED_SOCKET_CLI_COANA_TECH_CLI_VERSION}`, ...args], {
2848
- ...spawnOpts,
3008
+ const result = await spawnDlx({
3009
+ name: '@coana-tech/cli',
3010
+ version: `~${constants.default.ENV.INLINED_SOCKET_CLI_COANA_TECH_CLI_VERSION}`
3011
+ }, args, {
3012
+ force: true,
3013
+ silent: true,
3014
+ ...dlxOptions,
2849
3015
  env: {
2850
3016
  ...process.env,
2851
3017
  ...constants.default.processEnv,
@@ -2858,8 +3024,8 @@ async function spawnCoana(args, orgSlug, options, extra) {
2858
3024
  [constants.default.SOCKET_CLI_SHADOW_SILENT]: true,
2859
3025
  ...ipc
2860
3026
  }
2861
- }, extra);
2862
- const output = await spawnPromise;
3027
+ }, spawnExtra);
3028
+ const output = await result.spawnPromise;
2863
3029
  return {
2864
3030
  ok: true,
2865
3031
  data: output.stdout
@@ -2876,6 +3042,34 @@ async function spawnCoana(args, orgSlug, options, extra) {
2876
3042
  }
2877
3043
  }
2878
3044
 
3045
+ /**
3046
+ * Helper to spawn cdxgen with dlx.
3047
+ */
3048
+ async function spawnCdxgenDlx(args, options, spawnExtra) {
3049
+ return await spawnDlx({
3050
+ name: '@cyclonedx/cdxgen',
3051
+ version: `${constants.default.ENV.INLINED_SOCKET_CLI_CYCLONEDX_CDXGEN_VERSION}`
3052
+ }, args, {
3053
+ force: false,
3054
+ silent: true,
3055
+ ...options
3056
+ }, spawnExtra);
3057
+ }
3058
+
3059
+ /**
3060
+ * Helper to spawn synp with dlx.
3061
+ */
3062
+ async function spawnSynpDlx(args, options, spawnExtra) {
3063
+ return await spawnDlx({
3064
+ name: 'synp',
3065
+ version: `${constants.default.ENV.INLINED_SOCKET_CLI_SYNP_VERSION}`
3066
+ }, args, {
3067
+ force: false,
3068
+ silent: true,
3069
+ ...options
3070
+ }, spawnExtra);
3071
+ }
3072
+
2879
3073
  function getEnterpriseOrgs(orgs) {
2880
3074
  return orgs.filter(o => o.plan === 'enterprise');
2881
3075
  }
@@ -3394,58 +3588,6 @@ function captureExceptionSync(exception, hint) {
3394
3588
  return Sentry.captureException(exception, hint);
3395
3589
  }
3396
3590
 
3397
- function exitWithBinPathError$1(binName) {
3398
- logger.logger.fail(`Socket unable to locate ${binName}; ensure it is available in the PATH environment variable`);
3399
- // The exit code 127 indicates that the command or binary being executed
3400
- // could not be found.
3401
- // eslint-disable-next-line n/no-process-exit
3402
- process.exit(127);
3403
- }
3404
- let _yarnBinPath;
3405
- function getYarnBinPath() {
3406
- if (_yarnBinPath === undefined) {
3407
- _yarnBinPath = getYarnBinPathDetails().path;
3408
- if (!_yarnBinPath) {
3409
- exitWithBinPathError$1(constants.default.YARN);
3410
- }
3411
- }
3412
- return _yarnBinPath;
3413
- }
3414
- let _yarnBinPathDetails;
3415
- function getYarnBinPathDetails() {
3416
- if (_yarnBinPathDetails === undefined) {
3417
- _yarnBinPathDetails = findBinPathDetailsSync(constants.default.YARN);
3418
- }
3419
- return _yarnBinPathDetails;
3420
- }
3421
- function isYarnBinPathShadowed() {
3422
- return getYarnBinPathDetails().shadowed;
3423
- }
3424
-
3425
- let _isYarnBerry;
3426
- function isYarnBerry() {
3427
- if (_isYarnBerry === undefined) {
3428
- try {
3429
- const yarnBinPath = getYarnBinPath();
3430
- const result = spawn.spawnSync(yarnBinPath, ['--version'], {
3431
- encoding: 'utf8',
3432
- shell: constants.default.WIN32
3433
- });
3434
- if (result.status === 0 && result.stdout) {
3435
- const version = result.stdout;
3436
- // Yarn Berry starts from version 2.x
3437
- const majorVersion = parseInt(version.split('.')[0], 10);
3438
- _isYarnBerry = majorVersion >= 2;
3439
- } else {
3440
- _isYarnBerry = false;
3441
- }
3442
- } catch {
3443
- _isYarnBerry = false;
3444
- }
3445
- }
3446
- return _isYarnBerry;
3447
- }
3448
-
3449
3591
  function npa(...args) {
3450
3592
  try {
3451
3593
  return Reflect.apply(vendor.npaExports, undefined, args);
@@ -3616,7 +3758,6 @@ const LOCKS = {
3616
3758
  'npm-shrinkwrap.json': NPM,
3617
3759
  [constants.PACKAGE_LOCK_JSON]: NPM,
3618
3760
  [constants.PNPM_LOCK_YAML]: PNPM,
3619
- ['pnpm-lock.yml']: PNPM,
3620
3761
  [constants.YARN_LOCK]: YARN_CLASSIC,
3621
3762
  'vlt-lock.json': VLT,
3622
3763
  // Lastly, look for a hidden lock file which is present if .npmrc has package-lock=false:
@@ -4604,12 +4745,14 @@ exports.sendApiRequest = sendApiRequest;
4604
4745
  exports.serializeResultJson = serializeResultJson;
4605
4746
  exports.setGitRemoteGithubRepoUrl = setGitRemoteGithubRepoUrl;
4606
4747
  exports.setupSdk = setupSdk;
4607
- exports.spawnCoana = spawnCoana;
4748
+ exports.spawnCdxgenDlx = spawnCdxgenDlx;
4749
+ exports.spawnCoanaDlx = spawnCoanaDlx;
4750
+ exports.spawnSynpDlx = spawnSynpDlx;
4608
4751
  exports.suggestOrgSlug = suggestOrgSlug;
4609
4752
  exports.tildify = tildify;
4610
4753
  exports.toFilterConfig = toFilterConfig;
4611
4754
  exports.updateConfigValue = updateConfigValue;
4612
4755
  exports.walkNestedMap = walkNestedMap;
4613
4756
  exports.writeSocketJson = writeSocketJson;
4614
- //# debugId=1da7b4a0-f584-4be9-bf6b-9269a66c830
4757
+ //# debugId=fce77ca7-be25-4c37-b4fb-40d1e77af26c
4615
4758
  //# sourceMappingURL=utils.js.map