@socketsecurity/cli-with-sentry 0.14.55 → 0.14.57

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 (40) hide show
  1. package/bin/cli.js +8 -10
  2. package/bin/npm-cli.js +1 -1
  3. package/bin/npx-cli.js +3 -1
  4. package/dist/constants.d.ts +21 -11
  5. package/dist/constants.js +47 -33
  6. package/dist/constants.js.map +1 -1
  7. package/dist/instrument-with-sentry.js +3 -3
  8. package/dist/instrument-with-sentry.js.map +1 -1
  9. package/dist/module-sync/cli.js +760 -497
  10. package/dist/module-sync/cli.js.map +1 -1
  11. package/dist/module-sync/color-or-markdown.d.ts +16 -0
  12. package/dist/module-sync/edge.d.ts +1 -1
  13. package/dist/module-sync/index.d.ts +3 -173
  14. package/dist/module-sync/node.d.ts +1 -1
  15. package/dist/module-sync/override-set.d.ts +37 -0
  16. package/dist/module-sync/path-resolve.d.ts +2 -3
  17. package/dist/module-sync/shadow-bin.d.ts +1 -1
  18. package/dist/module-sync/shadow-bin.js +16 -24
  19. package/dist/module-sync/shadow-bin.js.map +1 -1
  20. package/dist/module-sync/{index.js → shadow-npm-inject.js} +46 -41
  21. package/dist/module-sync/shadow-npm-inject.js.map +1 -0
  22. package/dist/module-sync/{npm-paths.js → shadow-npm-paths.js} +5 -16
  23. package/dist/module-sync/shadow-npm-paths.js.map +1 -0
  24. package/dist/module-sync/socket-url.d.ts +3 -0
  25. package/dist/require/cli.js +760 -497
  26. package/dist/require/cli.js.map +1 -1
  27. package/dist/require/shadow-npm-inject.js +3 -0
  28. package/dist/require/shadow-npm-paths.js +3 -0
  29. package/package.json +41 -63
  30. package/dist/module-sync/index.js.map +0 -1
  31. package/dist/module-sync/npm-injection.js +0 -26
  32. package/dist/module-sync/npm-injection.js.map +0 -1
  33. package/dist/module-sync/npm-paths.js.map +0 -1
  34. package/dist/module-sync/proc-log.d.ts +0 -3
  35. package/dist/module-sync/reify.d.ts +0 -1018
  36. package/dist/require/index.js +0 -3
  37. package/dist/require/npm-injection.js +0 -3
  38. package/dist/require/npm-paths.js +0 -3
  39. /package/dist/module-sync/{npm-injection.d.ts → shadow-npm-inject.d.ts} +0 -0
  40. /package/dist/module-sync/{npm-paths.d.ts → shadow-npm-paths.d.ts} +0 -0
@@ -24,7 +24,7 @@ var fs = require('node:fs');
24
24
  var path = require('node:path');
25
25
  var ndjson = _socketInterop(require('ndjson'));
26
26
  var rest = _socketInterop(require('@octokit/rest'));
27
- var index = require('./index.js');
27
+ var shadowNpmInject = require('./shadow-npm-inject.js');
28
28
  var constants = require('./constants.js');
29
29
  var meow = _socketInterop(require('meow'));
30
30
  var objects = require('@socketsecurity/registry/lib/objects');
@@ -36,10 +36,11 @@ var contrib = _socketInterop(require('blessed-contrib'));
36
36
  var prompts = require('@socketsecurity/registry/lib/prompts');
37
37
  var yargsParse = _socketInterop(require('yargs-parser'));
38
38
  var words = require('@socketsecurity/registry/lib/words');
39
- var npm = require('@socketsecurity/registry/lib/npm');
39
+ var shadowBin = require('./shadow-bin.js');
40
40
  var chalkTable = _socketInterop(require('chalk-table'));
41
41
  var util = require('node:util');
42
42
  var registry = require('@socketsecurity/registry');
43
+ var npm = require('@socketsecurity/registry/lib/npm');
43
44
  var packages = require('@socketsecurity/registry/lib/packages');
44
45
  var registryConstants = require('@socketsecurity/registry/lib/constants');
45
46
  var isInteractive = require('@socketregistry/is-interactive/index.cjs');
@@ -56,7 +57,7 @@ var sorts = require('@socketsecurity/registry/lib/sorts');
56
57
  var strings = require('@socketsecurity/registry/lib/strings');
57
58
  var yaml = _socketInterop(require('yaml'));
58
59
  var debug = require('@socketsecurity/registry/lib/debug');
59
- var npmPaths = require('./npm-paths.js');
60
+ var shadowNpmPaths = require('./shadow-npm-paths.js');
60
61
  var betterAjvErrors = _socketInterop(require('@apideck/better-ajv-errors'));
61
62
  var config$A = require('@socketsecurity/config');
62
63
  var assert = require('node:assert');
@@ -839,7 +840,7 @@ function getIgnoreOptions({
839
840
  ignoreCommands.push(data);
840
841
  }
841
842
  } catch (e) {
842
- logger.logger.error(`Unable to process ignore command for ${comment}`);
843
+ logger.logger.fail(`Unable to process ignore command for ${comment}`);
843
844
  logger.logger.error(e);
844
845
  }
845
846
  }
@@ -1225,7 +1226,7 @@ function securityCommentTemplate(diff) {
1225
1226
  // TODO: is this a github action handler?
1226
1227
  async function runAction(githubEventBefore, githubEventAfter) {
1227
1228
  //TODO
1228
- const socket = new sdk.SocketSdk(index.getDefaultToken());
1229
+ const socket = new sdk.SocketSdk(shadowNpmInject.getDefaultToken());
1229
1230
  const git = simpleGit.simpleGit();
1230
1231
  const changedFiles = (await git.diff(process.env['GITHUB_EVENT_NAME'] === 'pull_request' ? ['--name-only', 'HEAD^1', 'HEAD'] : ['--name-only', githubEventBefore, githubEventAfter])).split('\n');
1231
1232
  logger.logger.log({
@@ -1290,15 +1291,14 @@ async function runAction(githubEventBefore, githubEventAfter) {
1290
1291
  const {
1291
1292
  API_V0_URL
1292
1293
  } = constants;
1293
- function handleUnsuccessfulApiResponse(_name, result, spinner) {
1294
+ function handleUnsuccessfulApiResponse(_name, result) {
1294
1295
  // SocketSdkErrorType['error'] is not typed.
1295
1296
  const resultErrorMessage = result.error?.message;
1296
1297
  const message = typeof resultErrorMessage === 'string' ? resultErrorMessage : 'No error message returned';
1297
1298
  if (result.status === 401 || result.status === 403) {
1298
- spinner.stop();
1299
- throw new index.AuthError(message);
1299
+ throw new shadowNpmInject.AuthError(message);
1300
1300
  }
1301
- spinner.errorAndStop(`${colors.bgRed(colors.white('API returned an error:'))} ${message}`);
1301
+ logger.logger.fail(`${colors.bgRed(colors.white('API returned an error:'))} ${message}`);
1302
1302
  process$1.exit(1);
1303
1303
  }
1304
1304
  async function handleApiCall(value, description) {
@@ -1477,8 +1477,8 @@ async function meowWithSubcommands(subcommands, options) {
1477
1477
  autoHelp: false // otherwise we can't exit(0)
1478
1478
  });
1479
1479
  if (!cli.flags['help'] && cli.flags['dryRun']) {
1480
- logger.logger.log(`${DRY_RUN_LABEL$1}: No-op, call a sub-command; ok`);
1481
1480
  process.exitCode = 0;
1481
+ logger.logger.log(`${DRY_RUN_LABEL$1}: No-op, call a sub-command; ok`);
1482
1482
  } else {
1483
1483
  cli.showHelp();
1484
1484
  }
@@ -1519,9 +1519,9 @@ function meowOrExit({
1519
1519
  }
1520
1520
  function getAsciiHeader(command) {
1521
1521
  const cliVersion = // The '@rollup/plugin-replace' will replace "process.env['SOCKET_CLI_VERSION_HASH']".
1522
- "0.14.55:51de259:b691b88f:pub";
1522
+ "0.14.57:6783de7:236c7308:pub";
1523
1523
  const nodeVersion = process.version;
1524
- const apiToken = index.getSetting('apiToken');
1524
+ const apiToken = shadowNpmInject.getSetting('apiToken');
1525
1525
  const shownToken = apiToken ? getLastFiveOfApiToken(apiToken) : 'no';
1526
1526
  const relCwd = process.cwd().replace(new RegExp(`^${regexps.escapeRegExp(constants.homePath)}`, 'i'), '~/');
1527
1527
  const body = `
@@ -1594,10 +1594,10 @@ async function run$z(argv, importMeta, {
1594
1594
  }
1595
1595
 
1596
1596
  async function fetchOrgAnalyticsData(time, spinner, apiToken) {
1597
- const socketSdk = await index.setupSdk(apiToken);
1597
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
1598
1598
  const result = await handleApiCall(socketSdk.getOrgAnalytics(time.toString()), 'fetching analytics data');
1599
1599
  if (result.success === false) {
1600
- handleUnsuccessfulApiResponse('getOrgAnalytics', result, spinner);
1600
+ handleUnsuccessfulApiResponse('getOrgAnalytics', result);
1601
1601
  return undefined;
1602
1602
  }
1603
1603
  spinner.stop();
@@ -1609,10 +1609,10 @@ async function fetchOrgAnalyticsData(time, spinner, apiToken) {
1609
1609
  }
1610
1610
 
1611
1611
  async function fetchRepoAnalyticsData(repo, time, spinner, apiToken) {
1612
- const socketSdk = await index.setupSdk(apiToken);
1612
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
1613
1613
  const result = await handleApiCall(socketSdk.getRepoAnalytics(repo, time.toString()), 'fetching analytics data');
1614
1614
  if (result.success === false) {
1615
- handleUnsuccessfulApiResponse('getRepoAnalytics', result, spinner);
1615
+ handleUnsuccessfulApiResponse('getRepoAnalytics', result);
1616
1616
  return undefined;
1617
1617
  }
1618
1618
  spinner.stop();
@@ -1643,6 +1643,35 @@ function mdTableStringNumber(title1, title2, obj) {
1643
1643
  lines.push(`| ${'-'.repeat(mw1)} | ${'-'.repeat(mw2)} |`);
1644
1644
  return lines.join('\n');
1645
1645
  }
1646
+ function mdTable(logs,
1647
+ // This is saying "an array of strings and the strings are a valid key of elements of T"
1648
+ // In turn, T is defined above as the audit log event type from our OpenAPI docs.
1649
+ cols) {
1650
+ // Max col width required to fit all data in that column
1651
+ const cws = cols.map(col => col.length);
1652
+ for (const log of logs) {
1653
+ for (let i = 0; i < cols.length; ++i) {
1654
+ // @ts-ignore
1655
+ const val = log[cols[i] ?? ''] ?? '';
1656
+ cws[i] = Math.max(cws[i] ?? 0, String(val).length);
1657
+ }
1658
+ }
1659
+ let div = '|';
1660
+ for (const cw of cws) div += ' ' + '-'.repeat(cw) + ' |';
1661
+ let header = '|';
1662
+ for (let i = 0; i < cols.length; ++i) header += ' ' + String(cols[i]).padEnd(cws[i] ?? 0, ' ') + ' |';
1663
+ let body = '';
1664
+ for (const log of logs) {
1665
+ body += '|';
1666
+ for (let i = 0; i < cols.length; ++i) {
1667
+ // @ts-ignore
1668
+ const val = log[cols[i] ?? ''] ?? '';
1669
+ body += ' ' + String(val).padEnd(cws[i] ?? 0, ' ') + ' |';
1670
+ }
1671
+ body += '\n';
1672
+ }
1673
+ return [div, header, div, body.trim(), div].filter(s => !!s.trim()).join('\n');
1674
+ }
1646
1675
 
1647
1676
  // Note: Widgets does not seem to actually work as code :'(
1648
1677
 
@@ -1657,9 +1686,9 @@ async function displayAnalytics({
1657
1686
  scope,
1658
1687
  time
1659
1688
  }) {
1660
- const apiToken = index.getDefaultToken();
1689
+ const apiToken = shadowNpmInject.getDefaultToken();
1661
1690
  if (!apiToken) {
1662
- throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API token.');
1691
+ throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API token.');
1663
1692
  }
1664
1693
  await outputAnalyticsWithToken({
1665
1694
  apiToken,
@@ -1700,9 +1729,9 @@ async function outputAnalyticsWithToken({
1700
1729
  await fs$1.writeFile(filePath, serialized, 'utf8');
1701
1730
  logger.logger.log(`Data successfully written to ${filePath}`);
1702
1731
  } catch (e) {
1703
- logger.logger.error('There was an error trying to write the json to disk');
1704
- logger.logger.error(e);
1705
1732
  process.exitCode = 1;
1733
+ logger.logger.fail('There was an error trying to write the json to disk');
1734
+ logger.logger.error(e);
1706
1735
  }
1707
1736
  } else {
1708
1737
  logger.logger.log(serialized);
@@ -1730,9 +1759,9 @@ function renderJson(data) {
1730
1759
  try {
1731
1760
  return JSON.stringify(data, null, 2);
1732
1761
  } catch (e) {
1733
- // This could be caused by circular references, which is an "us" problem
1734
- logger.logger.error('There was a problem converting the data set to JSON. Please try without --json or with --markdown');
1735
1762
  process.exitCode = 1;
1763
+ // This could be caused by circular references, which is an "us" problem
1764
+ logger.logger.fail('There was a problem converting the data set to JSON. Please try without --json or with --markdown');
1736
1765
  return;
1737
1766
  }
1738
1767
  }
@@ -1967,7 +1996,7 @@ async function run$y(argv, importMeta, {
1967
1996
  // options or missing arguments.
1968
1997
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
1969
1998
  process.exitCode = 2;
1970
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
1999
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
1971
2000
 
1972
2001
  - Scope must be "repo" or "org" ${badScope ? colors.red('(bad!)') : colors.green('(ok)')}
1973
2002
 
@@ -2001,9 +2030,9 @@ async function getAuditLog({
2001
2030
  page,
2002
2031
  perPage
2003
2032
  }) {
2004
- const apiToken = index.getDefaultToken();
2033
+ const apiToken = shadowNpmInject.getDefaultToken();
2005
2034
  if (!apiToken) {
2006
- throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
2035
+ throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
2007
2036
  }
2008
2037
  const auditLogs = await getAuditLogWithToken({
2009
2038
  apiToken,
@@ -2047,8 +2076,8 @@ async function outputAsJson(auditLogs, orgSlug, logType, page, perPage) {
2047
2076
  })
2048
2077
  }, null, 2);
2049
2078
  } catch (e) {
2050
- logger.logger.error('There was a problem converting the logs to JSON, please try without the `--json` flag');
2051
2079
  process.exitCode = 1;
2080
+ logger.logger.fail('There was a problem converting the logs to JSON, please try without the `--json` flag');
2052
2081
  return;
2053
2082
  }
2054
2083
  logger.logger.log(json);
@@ -2069,41 +2098,12 @@ These are the Socket.dev audit logs as per requested query.
2069
2098
  ${table}
2070
2099
  `);
2071
2100
  } catch (e) {
2072
- logger.logger.error('There was a problem converting the logs to JSON, please try without the `--json` flag');
2073
- logger.logger.error(e);
2074
2101
  process.exitCode = 1;
2102
+ logger.logger.fail('There was a problem converting the logs to JSON, please try without the `--json` flag');
2103
+ logger.logger.error(e);
2075
2104
  return;
2076
2105
  }
2077
2106
  }
2078
- function mdTable(logs,
2079
- // This is saying "an array of strings and the strings are a valid key of elements of T"
2080
- // In turn, T is defined above as the audit log event type from our OpenAPI docs.
2081
- cols) {
2082
- // Max col width required to fit all data in that column
2083
- const cws = cols.map(col => col.length);
2084
- for (const log of logs) {
2085
- for (let i = 0; i < cols.length; ++i) {
2086
- // @ts-ignore
2087
- const val = log[cols[i] ?? ''] ?? '';
2088
- cws[i] = Math.max(cws[i] ?? 0, String(val).length);
2089
- }
2090
- }
2091
- let div = '|';
2092
- for (const cw of cws) div += ' ' + '-'.repeat(cw) + ' |';
2093
- let header = '|';
2094
- for (let i = 0; i < cols.length; ++i) header += ' ' + String(cols[i]).padEnd(cws[i] ?? 0, ' ') + ' |';
2095
- let body = '';
2096
- for (const log of logs) {
2097
- body += '|';
2098
- for (let i = 0; i < cols.length; ++i) {
2099
- // @ts-ignore
2100
- const val = log[cols[i] ?? ''] ?? '';
2101
- body += ' ' + String(val).padEnd(cws[i] ?? 0, ' ') + ' |';
2102
- }
2103
- body += '\n';
2104
- }
2105
- return [div, header, div, body.trim(), div].filter(s => !!s.trim()).join('\n');
2106
- }
2107
2107
  async function outputAsPrint(auditLogs, orgSlug, logType) {
2108
2108
  const data = [];
2109
2109
  const logDetails = {};
@@ -2142,7 +2142,7 @@ async function getAuditLogWithToken({
2142
2142
  spinner
2143
2143
  } = constants;
2144
2144
  spinner.start(`Looking up audit log for ${orgSlug}`);
2145
- const socketSdk = await index.setupSdk(apiToken);
2145
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
2146
2146
  const result = await handleApiCall(socketSdk.getAuditLogEvents(orgSlug, {
2147
2147
  outputJson: outputKind === 'json',
2148
2148
  // I'm not sure this is used at all
@@ -2154,7 +2154,7 @@ async function getAuditLogWithToken({
2154
2154
  per_page: perPage
2155
2155
  }), `Looking up audit log for ${orgSlug}\n`);
2156
2156
  if (!result.success) {
2157
- handleUnsuccessfulApiResponse('getAuditLogEvents', result, spinner);
2157
+ handleUnsuccessfulApiResponse('getAuditLogEvents', result);
2158
2158
  return;
2159
2159
  }
2160
2160
  spinner.stop();
@@ -2229,7 +2229,7 @@ async function run$x(argv, importMeta, {
2229
2229
  // options or missing arguments.
2230
2230
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
2231
2231
  process.exitCode = 2;
2232
- logger.logger.error(commonTags.stripIndents`
2232
+ logger.logger.fail(commonTags.stripIndents`
2233
2233
  ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
2234
2234
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
2235
2235
  `);
@@ -2248,18 +2248,10 @@ async function run$x(argv, importMeta, {
2248
2248
  });
2249
2249
  }
2250
2250
 
2251
- const {
2252
- SBOM_SIGN_ALGORITHM,
2253
- // Algorithm. Example: RS512
2254
- SBOM_SIGN_PRIVATE_KEY,
2255
- // Location to the RSA private key
2256
- SBOM_SIGN_PUBLIC_KEY // Optional. Location to the RSA public key
2257
- } = process$1.env;
2258
2251
  const {
2259
2252
  NPM: NPM$e,
2260
- PNPM: PNPM$8,
2261
- cdxgenBinPath,
2262
- synpBinPath
2253
+ NPX: NPX$3,
2254
+ PNPM: PNPM$8
2263
2255
  } = constants;
2264
2256
  const nodejsPlatformTypes = new Set(['javascript', 'js', 'nodejs', NPM$e, PNPM$8, 'ts', 'tsx', 'typescript']);
2265
2257
  async function runCycloneDX(yargv) {
@@ -2271,21 +2263,13 @@ async function runCycloneDX(yargv) {
2271
2263
  // Use synp to create a package-lock.json from the yarn.lock,
2272
2264
  // based on the node_modules folder, for a more accurate SBOM.
2273
2265
  try {
2274
- await npm.runBin(await fs.promises.realpath(synpBinPath), ['--source-file', './yarn.lock']);
2266
+ await shadowBin(NPX$3, ['synp@1.9.14', '--', '--source-file', './yarn.lock'], 2);
2275
2267
  yargv.type = NPM$e;
2276
2268
  cleanupPackageLock = true;
2277
2269
  } catch {}
2278
2270
  }
2279
2271
  }
2280
- await npm.runBin(await fs.promises.realpath(cdxgenBinPath), argvToArray(yargv), {
2281
- env: {
2282
- NODE_ENV: '',
2283
- SBOM_SIGN_ALGORITHM,
2284
- SBOM_SIGN_PRIVATE_KEY,
2285
- SBOM_SIGN_PUBLIC_KEY
2286
- },
2287
- stdio: 'inherit'
2288
- });
2272
+ await shadowBin(NPX$3, ['@cyclonedx/cdxgen@11.2.0', '--', ...argvToArray(yargv)], 2);
2289
2273
  if (cleanupPackageLock) {
2290
2274
  try {
2291
2275
  await fs.promises.rm('./package-lock.json');
@@ -2431,7 +2415,7 @@ async function run$w(argv, importMeta, {
2431
2415
  //
2432
2416
  //
2433
2417
  // if (cli.input.length)
2434
- // logger.error(
2418
+ // logger.fail(
2435
2419
  // stripIndents`
2436
2420
  // ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
2437
2421
  //
@@ -2455,7 +2439,7 @@ async function run$w(argv, importMeta, {
2455
2439
  // options or missing arguments.
2456
2440
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
2457
2441
  process$1.exitCode = 2;
2458
- logger.logger.error(`Unknown ${words.pluralize('argument', unknownLength)}: ${yargv._.join(', ')}`);
2442
+ logger.logger.fail(`Unknown ${words.pluralize('argument', unknownLength)}: ${yargv._.join(', ')}`);
2459
2443
  return;
2460
2444
  }
2461
2445
  if (yargv.output === undefined) {
@@ -2474,22 +2458,22 @@ async function findDependencies({
2474
2458
  offset,
2475
2459
  outputJson
2476
2460
  }) {
2477
- const apiToken = index.getDefaultToken();
2461
+ const apiToken = shadowNpmInject.getDefaultToken();
2478
2462
  if (!apiToken) {
2479
- throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
2463
+ throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
2480
2464
  }
2481
2465
  // Lazily access constants.spinner.
2482
2466
  const {
2483
2467
  spinner
2484
2468
  } = constants;
2485
2469
  spinner.start('Searching dependencies...');
2486
- const socketSdk = await index.setupSdk(apiToken);
2470
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
2487
2471
  const result = await handleApiCall(socketSdk.searchDependencies({
2488
2472
  limit,
2489
2473
  offset
2490
2474
  }), 'Searching dependencies');
2491
2475
  if (!result.success) {
2492
- handleUnsuccessfulApiResponse('searchDependencies', result, spinner);
2476
+ handleUnsuccessfulApiResponse('searchDependencies', result);
2493
2477
  return;
2494
2478
  }
2495
2479
  spinner.stop('Organization dependencies:');
@@ -2497,6 +2481,7 @@ async function findDependencies({
2497
2481
  logger.logger.log(result.data);
2498
2482
  return;
2499
2483
  }
2484
+ logger.logger.log('Request details: Offset:', offset, ', limit:', limit, ', is there more data after this?', result.data.end ? 'no' : 'yes');
2500
2485
  const options = {
2501
2486
  columns: [{
2502
2487
  field: 'namespace',
@@ -2588,43 +2573,96 @@ async function run$v(argv, importMeta, {
2588
2573
  async function getDiffScan({
2589
2574
  after,
2590
2575
  before,
2576
+ depth,
2591
2577
  file,
2592
2578
  orgSlug,
2593
2579
  outputJson
2594
- }, apiToken) {
2580
+ }) {
2581
+ const apiToken = shadowNpmInject.getDefaultToken();
2582
+ if (!apiToken) {
2583
+ throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
2584
+ }
2585
+ await getDiffScanWithToken({
2586
+ after,
2587
+ before,
2588
+ depth,
2589
+ file,
2590
+ orgSlug,
2591
+ outputJson,
2592
+ apiToken
2593
+ });
2594
+ }
2595
+ async function getDiffScanWithToken({
2596
+ after,
2597
+ apiToken,
2598
+ before,
2599
+ depth,
2600
+ file,
2601
+ orgSlug,
2602
+ outputJson
2603
+ }) {
2595
2604
  // Lazily access constants.spinner.
2596
2605
  const {
2597
2606
  spinner
2598
2607
  } = constants;
2599
2608
  spinner.start('Getting diff scan...');
2600
- const response = await queryAPI(`${orgSlug}/full-scans/diff?before=${before}&after=${after}&preview`, apiToken);
2601
- const data = await response.json();
2609
+ const response = await queryAPI(`orgs/${orgSlug}/full-scans/diff?before=${encodeURIComponent(before)}&after=${encodeURIComponent(after)}`, apiToken);
2602
2610
  if (!response.ok) {
2603
2611
  const err = await handleAPIError(response.status);
2604
2612
  spinner.errorAndStop(`${colors.bgRed(colors.white(response.statusText))}: ${err}`);
2605
2613
  return;
2606
2614
  }
2615
+ const result = await handleApiCall(await response.json(), 'Deserializing json');
2607
2616
  spinner.stop();
2608
- if (file && !outputJson) {
2609
- fs.writeFile(file, JSON.stringify(data), err => {
2610
- err ? logger.logger.error(err) : logger.logger.log(`Data successfully written to ${file}`);
2611
- });
2612
- return;
2613
- }
2614
- if (outputJson) {
2615
- logger.logger.log(`\n Diff scan result: \n`);
2616
- logger.logger.log(util.inspect(data, {
2617
- showHidden: false,
2618
- depth: null,
2619
- colors: true
2620
- }));
2621
- logger.logger.log(`\n View this diff scan in the Socket dashboard: ${colors.cyan(data?.['diff_report_url'])}`);
2617
+ const dashboardUrl = result?.['diff_report_url'];
2618
+ const dashboardMessage = dashboardUrl ? `\n View this diff scan in the Socket dashboard: ${colors.cyan(dashboardUrl)}` : '';
2619
+
2620
+ // When forcing json, or dumping to file, serialize to string such that it
2621
+ // won't get truncated. The only way to dump the full raw JSON to stdout is
2622
+ // to use `--json --file -` (the dash is a standard notation for stdout)
2623
+ if (outputJson || file) {
2624
+ let json;
2625
+ try {
2626
+ json = JSON.stringify(result, null, 2);
2627
+ } catch (e) {
2628
+ process.exitCode = 1;
2629
+ // Most likely caused by a circular reference (or OOM)
2630
+ logger.logger.fail('There was a problem converting the data to JSON');
2631
+ logger.logger.error(e);
2632
+ return;
2633
+ }
2634
+ if (file && file !== '-') {
2635
+ logger.logger.log(`Writing json to \`${file}\``);
2636
+ fs.writeFile(file, JSON.stringify(result, null, 2), err => {
2637
+ if (err) {
2638
+ logger.logger.fail(`Writing to \`${file}\` failed...`);
2639
+ logger.logger.error(err);
2640
+ } else {
2641
+ logger.logger.log(`Data successfully written to \`${file}\``);
2642
+ }
2643
+ logger.logger.error(dashboardMessage);
2644
+ });
2645
+ } else {
2646
+ // TODO: expose different method for writing to stderr when simply dodging stdout
2647
+ logger.logger.error(`\n Diff scan result: \n`);
2648
+ logger.logger.log(json);
2649
+ logger.logger.error(dashboardMessage);
2650
+ }
2622
2651
  return;
2623
2652
  }
2653
+
2654
+ // In this case neither the --json nor the --file flag was passed
2655
+ // Dump the JSON to CLI and let NodeJS deal with truncation
2656
+
2624
2657
  logger.logger.log('Diff scan result:');
2625
- logger.logger.log(data);
2658
+ logger.logger.log(util.inspect(result, {
2659
+ showHidden: false,
2660
+ depth: depth > 0 ? depth : null,
2661
+ colors: true,
2662
+ maxArrayLength: null
2663
+ }));
2626
2664
  logger.logger.log(`\n 📝 To display the detailed report in the terminal, use the --json flag \n`);
2627
- logger.logger.log(`\n View this diff scan in the Socket dashboard: ${colors.cyan(data?.['diff_report_url'])}`);
2665
+ logger.logger.log(dashboardMessage);
2628
2666
  }
2629
2667
 
2630
2668
  const {
@@ -2636,36 +2674,44 @@ const config$u = {
2636
2674
  hidden: false,
2637
2675
  flags: {
2638
2676
  ...commonFlags,
2677
+ after: {
2678
+ type: 'string',
2679
+ shortFlag: 'a',
2680
+ default: '',
2681
+ description: 'The full scan ID of the head scan'
2682
+ },
2639
2683
  before: {
2640
2684
  type: 'string',
2641
2685
  shortFlag: 'b',
2642
2686
  default: '',
2643
2687
  description: 'The full scan ID of the base scan'
2644
2688
  },
2645
- after: {
2646
- type: 'string',
2647
- shortFlag: 'a',
2648
- default: '',
2649
- description: 'The full scan ID of the head scan'
2689
+ depth: {
2690
+ type: 'number',
2691
+ default: 2,
2692
+ description: 'Max depth of JSON to display before truncating, use zero for no limit (without --json/--file)'
2650
2693
  },
2651
- preview: {
2694
+ json: {
2652
2695
  type: 'boolean',
2653
- shortFlag: 'p',
2654
- default: true,
2655
- description: 'A boolean flag to persist or not the diff scan result'
2696
+ shortFlag: 'j',
2697
+ default: false,
2698
+ description: 'Output result as json. This can be big. Use --file to store it to disk without truncation.'
2656
2699
  },
2657
2700
  file: {
2658
2701
  type: 'string',
2659
2702
  shortFlag: 'f',
2660
2703
  default: '',
2661
- description: 'Path to a local file where the output should be saved'
2662
- },
2663
- ...outputFlags
2704
+ description: 'Path to a local file where the output should be saved. Use `-` to force stdout.'
2705
+ }
2664
2706
  },
2665
2707
  help: (command, config) => `
2666
2708
  Usage
2667
2709
  $ ${command} <org slug> --before=<before> --after=<after>
2668
2710
 
2711
+ This command displays the package changes between two scans. The full output
2712
+ can be pretty large depending on the size of your repo and time range. It is
2713
+ best stored to disk to be further analyzed by other tools.
2714
+
2669
2715
  Options
2670
2716
  ${getFlagListOutput(config.flags, 6)}
2671
2717
 
@@ -2695,9 +2741,10 @@ async function run$u(argv, importMeta, {
2695
2741
  // options or missing arguments.
2696
2742
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
2697
2743
  process.exitCode = 2;
2698
- logger.logger.error(`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
2744
+ logger.logger.fail(`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
2699
2745
  - Specify a before and after full scan ID ${!before && !after ? colors.red('(missing before and after!)') : !before ? colors.red('(missing before!)') : !after ? colors.red('(missing after!)') : colors.green('(ok)')}\n
2700
2746
  - To get full scans IDs, you can run the command "socket scan list <your org slug>".
2747
+ The args are expecting a full \`aaa0aa0a-aaaa-0000-0a0a-0000000a00a0\` ID.\n
2701
2748
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}\n`);
2702
2749
  return;
2703
2750
  }
@@ -2705,24 +2752,24 @@ async function run$u(argv, importMeta, {
2705
2752
  logger.logger.log(DRY_RUN_BAIL_TEXT$t);
2706
2753
  return;
2707
2754
  }
2708
- const apiToken = index.getDefaultToken();
2709
- if (!apiToken) {
2710
- throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
2711
- }
2712
2755
  await getDiffScan({
2713
2756
  outputJson: Boolean(cli.flags['json']),
2714
- outputMarkdown: Boolean(cli.flags['markdown']),
2715
2757
  before,
2716
2758
  after,
2717
- preview: Boolean(cli.flags['preview']),
2759
+ depth: Number(cli.flags['depth']),
2718
2760
  orgSlug,
2719
2761
  file: String(cli.flags['file'] || '')
2720
- }, apiToken);
2762
+ });
2721
2763
  }
2722
2764
 
2723
2765
  const description$3 = 'Diff scans related commands';
2724
2766
  const cmdDiffScan = {
2725
2767
  description: description$3,
2768
+ // Hidden because it was broken all this time (nobody could be using it)
2769
+ // and we're not sure if it's useful to anyone in its current state.
2770
+ // Until we do, we'll hide this to keep the help tidier.
2771
+ // And later, we may simply move this under `scan`, anyways.
2772
+ hidden: true,
2726
2773
  async run(argv, importMeta, {
2727
2774
  parentName
2728
2775
  }) {
@@ -2757,17 +2804,17 @@ async function runFix() {
2757
2804
  });
2758
2805
  // const agentDetails = await detect()
2759
2806
 
2760
- const arb = new index.SafeArborist({
2807
+ const arb = new shadowNpmInject.SafeArborist({
2761
2808
  path: cwd,
2762
- ...index.SAFE_ARBORIST_REIFY_OPTIONS_OVERRIDES
2809
+ ...shadowNpmInject.SAFE_ARBORIST_REIFY_OPTIONS_OVERRIDES
2763
2810
  });
2764
2811
  await arb.reify();
2765
- const alerts = await index.getPackagesAlerts(arb, {
2812
+ const alerts = await shadowNpmInject.getPackagesAlerts(arb, {
2766
2813
  consolidate: true,
2767
2814
  includeExisting: true,
2768
2815
  includeUnfixable: false
2769
2816
  });
2770
- const infoByPkg = index.getCveInfoByPackage(alerts);
2817
+ const infoByPkg = shadowNpmInject.getCveInfoByPackage(alerts);
2771
2818
  await arb.buildIdealTree();
2772
2819
  if (infoByPkg) {
2773
2820
  for (const {
@@ -2784,7 +2831,7 @@ async function runFix() {
2784
2831
  spinner.info(`Skipping ${name}. Socket Optimize package exists.`);
2785
2832
  continue;
2786
2833
  }
2787
- const nodes = index.findPackageNodes(tree, name);
2834
+ const nodes = shadowNpmInject.findPackageNodes(tree, name);
2788
2835
  const packument = nodes.length && infos.length ?
2789
2836
  // eslint-disable-next-line no-await-in-loop
2790
2837
  await packages.fetchPackagePackument(name) : null;
@@ -2803,7 +2850,7 @@ async function runFix() {
2803
2850
  const {
2804
2851
  version: oldVersion
2805
2852
  } = node;
2806
- if (index.updateNode(node, packument, vulnerableVersionRange)) {
2853
+ if (shadowNpmInject.updateNode(node, packument, vulnerableVersionRange)) {
2807
2854
  try {
2808
2855
  // eslint-disable-next-line no-await-in-loop
2809
2856
  await npm.runScript('test', [], {
@@ -2834,7 +2881,7 @@ async function runFix() {
2834
2881
  }
2835
2882
  }
2836
2883
  }
2837
- const arb2 = new index.Arborist({
2884
+ const arb2 = new shadowNpmInject.Arborist({
2838
2885
  path: cwd
2839
2886
  });
2840
2887
  arb2.idealTree = arb.idealTree;
@@ -2954,15 +3001,15 @@ function getSeverityCount(issues, lowestToInclude) {
2954
3001
  return severityCount;
2955
3002
  }
2956
3003
 
2957
- async function fetchPackageInfo(pkgName, pkgVersion, includeAllIssues, spinner) {
2958
- const socketSdk = await index.setupSdk(index.getPublicToken());
3004
+ async function fetchPackageInfo(pkgName, pkgVersion, includeAllIssues) {
3005
+ const socketSdk = await shadowNpmInject.setupSdk(shadowNpmInject.getPublicToken());
2959
3006
  const result = await handleApiCall(socketSdk.getIssuesByNPMPackage(pkgName, pkgVersion), 'looking up package');
2960
3007
  const scoreResult = await handleApiCall(socketSdk.getScoreByNPMPackage(pkgName, pkgVersion), 'looking up package score');
2961
3008
  if (result.success === false) {
2962
- return handleUnsuccessfulApiResponse('getIssuesByNPMPackage', result, spinner);
3009
+ return handleUnsuccessfulApiResponse('getIssuesByNPMPackage', result);
2963
3010
  }
2964
3011
  if (scoreResult.success === false) {
2965
- return handleUnsuccessfulApiResponse('getScoreByNPMPackage', scoreResult, spinner);
3012
+ return handleUnsuccessfulApiResponse('getScoreByNPMPackage', scoreResult);
2966
3013
  }
2967
3014
  const severityCount = getSeverityCount(result.data, includeAllIssues ? undefined : 'high');
2968
3015
  return {
@@ -2981,49 +3028,54 @@ function formatPackageInfo({
2981
3028
  severityCount
2982
3029
  }, {
2983
3030
  name,
2984
- outputJson,
2985
- outputMarkdown,
3031
+ outputKind,
2986
3032
  pkgName,
2987
- pkgVersion,
2988
- strict
2989
- }, spinner) {
2990
- if (outputJson) {
3033
+ pkgVersion
3034
+ }) {
3035
+ if (outputKind === 'json') {
2991
3036
  logger.logger.log(JSON.stringify(data, undefined, 2));
3037
+ return;
3038
+ }
3039
+ if (outputKind === 'markdown') {
3040
+ logger.logger.log(`\n# Package report for ${pkgName}\n`);
3041
+ logger.logger.log('Package report card:\n');
2992
3042
  } else {
2993
- logger.logger.log('\nPackage report card:');
2994
- const scoreResult = {
2995
- 'Supply Chain Risk': Math.floor(score.supplyChainRisk.score * 100),
2996
- Maintenance: Math.floor(score.maintenance.score * 100),
2997
- Quality: Math.floor(score.quality.score * 100),
2998
- Vulnerabilities: Math.floor(score.vulnerability.score * 100),
2999
- License: Math.floor(score.license.score * 100)
3000
- };
3001
- Object.entries(scoreResult).map(score => logger.logger.log(`- ${score[0]}: ${formatScore(score[1])}`));
3002
- logger.logger.log('\n');
3003
- if (objectSome(severityCount)) {
3004
- spinner[strict ? 'error' : 'success'](`Package has these issues: ${formatSeverityCount(severityCount)}`);
3005
- formatPackageIssuesDetails(data, outputMarkdown);
3006
- } else {
3007
- spinner.successAndStop('Package has no issues');
3008
- }
3009
- const format = new index.ColorOrMarkdown(!!outputMarkdown);
3010
- const url = index.getSocketDevPackageOverviewUrl(NPM$c, pkgName, pkgVersion);
3011
- logger.logger.log('\n');
3012
- if (pkgVersion === 'latest') {
3013
- logger.logger.log(`Detailed info on socket.dev: ${format.hyperlink(`${pkgName}`, url, {
3014
- fallbackToUrl: true
3015
- })}`);
3016
- } else {
3017
- logger.logger.log(`Detailed info on socket.dev: ${format.hyperlink(`${pkgName} v${pkgVersion}`, url, {
3018
- fallbackToUrl: true
3019
- })}`);
3020
- }
3021
- if (!outputMarkdown) {
3022
- logger.logger.log(colors.dim(`\nOr rerun ${colors.italic(name)} using the ${colors.italic('--json')} flag to get full JSON output`));
3043
+ logger.logger.log(`\nPackage report card for ${pkgName}:\n`);
3044
+ }
3045
+ const scoreResult = {
3046
+ 'Supply Chain Risk': Math.floor(score.supplyChainRisk.score * 100),
3047
+ Maintenance: Math.floor(score.maintenance.score * 100),
3048
+ Quality: Math.floor(score.quality.score * 100),
3049
+ Vulnerabilities: Math.floor(score.vulnerability.score * 100),
3050
+ License: Math.floor(score.license.score * 100)
3051
+ };
3052
+ Object.entries(scoreResult).map(score => logger.logger.log(`- ${score[0]}: ${formatScore(score[1])}`));
3053
+ logger.logger.log('\n');
3054
+ if (objectSome(severityCount)) {
3055
+ if (outputKind === 'markdown') {
3056
+ logger.logger.log('# Issues\n');
3023
3057
  }
3058
+ logger.logger.log(`Package has these issues: ${formatSeverityCount(severityCount)}\n`);
3059
+ formatPackageIssuesDetails(data, outputKind === 'markdown');
3060
+ } else {
3061
+ logger.logger.log('Package has no issues');
3024
3062
  }
3025
- if (strict && objectSome(severityCount)) {
3026
- process$1.exit(1);
3063
+ const format = new shadowNpmInject.ColorOrMarkdown(outputKind === 'markdown');
3064
+ const url = shadowNpmInject.getSocketDevPackageOverviewUrl(NPM$c, pkgName, pkgVersion);
3065
+ logger.logger.log('\n');
3066
+ if (pkgVersion === 'latest') {
3067
+ logger.logger.log(`Detailed info on socket.dev: ${format.hyperlink(`${pkgName}`, url, {
3068
+ fallbackToUrl: true
3069
+ })}`);
3070
+ } else {
3071
+ logger.logger.log(`Detailed info on socket.dev: ${format.hyperlink(`${pkgName} v${pkgVersion}`, url, {
3072
+ fallbackToUrl: true
3073
+ })}`);
3074
+ }
3075
+ if (outputKind !== 'markdown') {
3076
+ logger.logger.log(colors.dim(`\nOr rerun ${colors.italic(name)} using the ${colors.italic('--json')} flag to get full JSON output`));
3077
+ } else {
3078
+ logger.logger.log('');
3027
3079
  }
3028
3080
  }
3029
3081
  function formatPackageIssuesDetails(packageData, outputMarkdown) {
@@ -3044,9 +3096,9 @@ function formatPackageIssuesDetails(packageData, outputMarkdown) {
3044
3096
  }
3045
3097
  return acc;
3046
3098
  }, {});
3047
- const format = new index.ColorOrMarkdown(!!outputMarkdown);
3099
+ const format = new shadowNpmInject.ColorOrMarkdown(outputMarkdown);
3048
3100
  for (const issue of Object.keys(uniqueIssues)) {
3049
- const issueWithLink = format.hyperlink(`${uniqueIssues[issue]?.label}`, index.getSocketDevAlertUrl(issue), {
3101
+ const issueWithLink = format.hyperlink(`${uniqueIssues[issue]?.label}`, shadowNpmInject.getSocketDevAlertUrl(issue), {
3050
3102
  fallbackToUrl: true
3051
3103
  });
3052
3104
  if (uniqueIssues[issue]?.count === 1) {
@@ -3068,8 +3120,7 @@ function formatScore(score) {
3068
3120
  async function getPackageInfo({
3069
3121
  commandName,
3070
3122
  includeAllIssues,
3071
- outputJson,
3072
- outputMarkdown,
3123
+ outputKind,
3073
3124
  pkgName,
3074
3125
  pkgVersion,
3075
3126
  strict
@@ -3079,16 +3130,19 @@ async function getPackageInfo({
3079
3130
  spinner
3080
3131
  } = constants;
3081
3132
  spinner.start(pkgVersion === 'latest' ? `Looking up data for the latest version of ${pkgName}` : `Looking up data for version ${pkgVersion} of ${pkgName}`);
3082
- const packageData = await fetchPackageInfo(pkgName, pkgVersion, includeAllIssues, spinner);
3133
+ const packageData = await fetchPackageInfo(pkgName, pkgVersion, includeAllIssues);
3134
+ spinner.successAndStop('Data fetched');
3083
3135
  if (packageData) {
3084
3136
  formatPackageInfo(packageData, {
3085
3137
  name: commandName,
3086
- outputJson,
3087
- outputMarkdown,
3138
+ outputKind,
3088
3139
  pkgName,
3089
- pkgVersion,
3090
- strict
3091
- }, spinner);
3140
+ pkgVersion
3141
+ });
3142
+ if (strict && objectSome(packageData.severityCount)) {
3143
+ // Let NodeJS exit gracefully but with exit(1)
3144
+ process$1.exitCode = 1;
3145
+ }
3092
3146
  }
3093
3147
  }
3094
3148
 
@@ -3130,13 +3184,19 @@ async function run$s(argv, importMeta, {
3130
3184
  importMeta,
3131
3185
  parentName
3132
3186
  });
3187
+ const {
3188
+ all,
3189
+ json,
3190
+ markdown,
3191
+ strict
3192
+ } = cli.flags;
3133
3193
  const [rawPkgName = ''] = cli.input;
3134
3194
  if (!rawPkgName || cli.input.length > 1) {
3135
3195
  // Use exit status of 2 to indicate incorrect usage, generally invalid
3136
3196
  // options or missing arguments.
3137
3197
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
3138
3198
  process.exitCode = 2;
3139
- logger.logger.error(`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
3199
+ logger.logger.fail(`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
3140
3200
  - Expecting a package name ${!rawPkgName ? colors.red('(missing!)') : colors.green('(ok)')}\n
3141
3201
  - Can only accept one package at a time ${cli.input.length > 1 ? colors.red('(got ' + cli.input.length + '!)') : colors.green('(ok)')}\n`);
3142
3202
  return;
@@ -3150,28 +3210,27 @@ async function run$s(argv, importMeta, {
3150
3210
  }
3151
3211
  await getPackageInfo({
3152
3212
  commandName: `${parentName} ${config$s.commandName}`,
3153
- includeAllIssues: Boolean(cli.flags['all']),
3154
- outputJson: Boolean(cli.flags['json']),
3155
- outputMarkdown: Boolean(cli.flags['markdown']),
3213
+ includeAllIssues: Boolean(all),
3214
+ outputKind: json ? 'json' : markdown ? 'markdown' : 'print',
3156
3215
  pkgName,
3157
3216
  pkgVersion,
3158
- strict: Boolean(cli.flags['strict'])
3217
+ strict: Boolean(strict)
3159
3218
  });
3160
3219
  }
3161
3220
 
3162
3221
  function applyLogin(apiToken, enforcedOrgs, apiBaseUrl, apiProxy) {
3163
- index.updateSetting('enforcedOrgs', enforcedOrgs);
3164
- index.updateSetting('apiToken', apiToken);
3165
- index.updateSetting('apiBaseUrl', apiBaseUrl);
3166
- index.updateSetting('apiProxy', apiProxy);
3222
+ shadowNpmInject.updateSetting('enforcedOrgs', enforcedOrgs);
3223
+ shadowNpmInject.updateSetting('apiToken', apiToken);
3224
+ shadowNpmInject.updateSetting('apiBaseUrl', apiBaseUrl);
3225
+ shadowNpmInject.updateSetting('apiProxy', apiProxy);
3167
3226
  }
3168
3227
 
3169
3228
  const {
3170
3229
  SOCKET_PUBLIC_API_TOKEN
3171
3230
  } = constants;
3172
3231
  async function attemptLogin(apiBaseUrl, apiProxy) {
3173
- apiBaseUrl ??= index.getSetting('apiBaseUrl') ?? undefined;
3174
- apiProxy ??= index.getSetting('apiProxy') ?? undefined;
3232
+ apiBaseUrl ??= shadowNpmInject.getSetting('apiBaseUrl') ?? undefined;
3233
+ apiProxy ??= shadowNpmInject.getSetting('apiProxy') ?? undefined;
3175
3234
  const apiToken = (await prompts.password({
3176
3235
  message: `Enter your ${terminalLink('Socket.dev API key', 'https://docs.socket.dev/docs/api-keys')} (leave blank for a public key)`
3177
3236
  })) || SOCKET_PUBLIC_API_TOKEN;
@@ -3182,10 +3241,10 @@ async function attemptLogin(apiBaseUrl, apiProxy) {
3182
3241
  spinner.start('Verifying API key...');
3183
3242
  let orgs;
3184
3243
  try {
3185
- const sdk = await index.setupSdk(apiToken, apiBaseUrl, apiProxy);
3244
+ const sdk = await shadowNpmInject.setupSdk(apiToken, apiBaseUrl, apiProxy);
3186
3245
  const result = await sdk.getOrganizations();
3187
3246
  if (!result.success) {
3188
- throw new index.AuthError();
3247
+ throw new shadowNpmInject.AuthError();
3189
3248
  }
3190
3249
  orgs = result.data;
3191
3250
  spinner.success('API key verified');
@@ -3226,12 +3285,13 @@ async function attemptLogin(apiBaseUrl, apiProxy) {
3226
3285
  }
3227
3286
  }
3228
3287
  }
3229
- const oldToken = index.getSetting('apiToken');
3288
+ spinner.stop();
3289
+ const oldToken = shadowNpmInject.getSetting('apiToken');
3230
3290
  try {
3231
3291
  applyLogin(apiToken, enforcedOrgs, apiBaseUrl, apiProxy);
3232
- spinner.successAndStop(`API credentials ${oldToken ? 'updated' : 'set'}`);
3292
+ logger.logger.success(`API credentials ${oldToken ? 'updated' : 'set'}`);
3233
3293
  } catch {
3234
- spinner.errorAndStop(`API login failed`);
3294
+ logger.logger.fail(`API login failed`);
3235
3295
  }
3236
3296
  }
3237
3297
 
@@ -3288,16 +3348,16 @@ async function run$r(argv, importMeta, {
3288
3348
  return;
3289
3349
  }
3290
3350
  if (!isInteractive()) {
3291
- throw new index.InputError('Cannot prompt for credentials in a non-interactive shell');
3351
+ throw new shadowNpmInject.InputError('Cannot prompt for credentials in a non-interactive shell');
3292
3352
  }
3293
3353
  await attemptLogin(apiBaseUrl, apiProxy);
3294
3354
  }
3295
3355
 
3296
3356
  function applyLogout() {
3297
- index.updateSetting('apiToken', null);
3298
- index.updateSetting('apiBaseUrl', null);
3299
- index.updateSetting('apiProxy', null);
3300
- index.updateSetting('enforcedOrgs', null);
3357
+ shadowNpmInject.updateSetting('apiToken', null);
3358
+ shadowNpmInject.updateSetting('apiBaseUrl', null);
3359
+ shadowNpmInject.updateSetting('apiProxy', null);
3360
+ shadowNpmInject.updateSetting('enforcedOrgs', null);
3301
3361
  }
3302
3362
 
3303
3363
  function attemptLogout() {
@@ -3305,7 +3365,7 @@ function attemptLogout() {
3305
3365
  applyLogout();
3306
3366
  logger.logger.success('Successfully logged out');
3307
3367
  } catch {
3308
- logger.logger.error('Failed to complete logout steps');
3368
+ logger.logger.fail('Failed to complete logout steps');
3309
3369
  }
3310
3370
  }
3311
3371
 
@@ -3365,7 +3425,6 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
3365
3425
  logger.logger.log(`- src dir: \`${target}\``);
3366
3426
  logger.logger.groupEnd();
3367
3427
  }
3368
- spinner.start(`Converting gradle to maven from \`${bin}\` on \`${target}\`...`);
3369
3428
  try {
3370
3429
  // Run sbt with the init script we provide which should yield zero or more pom files.
3371
3430
  // We have to figure out where to store those pom files such that we can upload them and predict them through the GitHub API.
@@ -3375,8 +3434,9 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
3375
3434
  const initLocation = path.join(constants.rootDistPath, 'init.gradle');
3376
3435
  const commandArgs = ['--init-script', initLocation, ...gradleOpts, 'pom'];
3377
3436
  if (verbose) {
3378
- spinner.log('[VERBOSE] Executing:', bin, commandArgs);
3437
+ logger.logger.log('[VERBOSE] Executing:', bin, commandArgs);
3379
3438
  }
3439
+ spinner.start(`Converting gradle to maven from \`${bin}\` on \`${target}\`...`);
3380
3440
  const output = await spawn.spawn(bin, commandArgs, {
3381
3441
  cwd: target || '.'
3382
3442
  });
@@ -3387,14 +3447,15 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
3387
3447
  logger.logger.groupEnd();
3388
3448
  }
3389
3449
  if (output.stderr) {
3390
- logger.logger.error('There were errors while running gradle');
3450
+ process.exitCode = 1;
3451
+ logger.logger.fail('There were errors while running gradle');
3391
3452
  // (In verbose mode, stderr was printed above, no need to repeat it)
3392
3453
  if (!verbose) {
3393
3454
  logger.logger.group('[VERBOSE] stderr:');
3394
3455
  logger.logger.error(output.stderr);
3395
3456
  logger.logger.groupEnd();
3396
3457
  }
3397
- process.exit(1);
3458
+ return;
3398
3459
  }
3399
3460
  logger.logger.success('Executed gradle successfully');
3400
3461
  logger.logger.log('Reported exports:');
@@ -3405,7 +3466,7 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
3405
3466
 
3406
3467
  // const loc = output.stdout?.match(/Wrote (.*?.pom)\n/)?.[1]?.trim()
3407
3468
  // if (!loc) {
3408
- // logger.error(
3469
+ // logger.fail(
3409
3470
  // 'There were no errors from sbt but could not find the location of resulting .pom file either'
3410
3471
  // )
3411
3472
  // process.exit(1)
@@ -3431,14 +3492,14 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
3431
3492
  // spinner.successAndStop(`OK. File should be available in \`${out}\``)
3432
3493
  // }
3433
3494
  } catch (e) {
3495
+ process.exitCode = 1;
3434
3496
  spinner.stop();
3435
- logger.logger.error('There was an unexpected error while running this' + (verbose ? '' : ' (use --verbose for details)'));
3497
+ logger.logger.fail('There was an unexpected error while running this' + (verbose ? '' : ' (use --verbose for details)'));
3436
3498
  if (verbose) {
3437
3499
  logger.logger.group('[VERBOSE] error:');
3438
3500
  logger.logger.log(e);
3439
3501
  logger.logger.groupEnd();
3440
3502
  }
3441
- process.exit(1);
3442
3503
  }
3443
3504
  }
3444
3505
 
@@ -3548,7 +3609,7 @@ async function run$p(argv, importMeta, {
3548
3609
  // options or missing arguments.
3549
3610
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
3550
3611
  process.exitCode = 2;
3551
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
3612
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
3552
3613
 
3553
3614
  - The DIR arg is required ${!target ? colors.red('(missing!)') : target === '-' ? colors.red('(stdin is not supported)') : colors.green('(ok)')}
3554
3615
 
@@ -3606,8 +3667,9 @@ async function convertSbtToMaven(target, bin, out, verbose, sbtOpts) {
3606
3667
  // logger.log(`- dst dir: \`${out}\``)
3607
3668
  logger.logger.groupEnd();
3608
3669
  }
3609
- spinner.start(`Converting sbt to maven from \`${bin}\` on \`${target}\`...`);
3610
3670
  try {
3671
+ spinner.start(`Converting sbt to maven from \`${bin}\` on \`${target}\`...`);
3672
+
3611
3673
  // Run sbt with the init script we provide which should yield zero or more
3612
3674
  // pom files. We have to figure out where to store those pom files such that
3613
3675
  // we can upload them and predict them through the GitHub API. We could do a
@@ -3623,14 +3685,15 @@ async function convertSbtToMaven(target, bin, out, verbose, sbtOpts) {
3623
3685
  logger.logger.groupEnd();
3624
3686
  }
3625
3687
  if (output.stderr) {
3626
- logger.logger.error('There were errors while running sbt');
3688
+ process.exitCode = 1;
3689
+ logger.logger.fail('There were errors while running sbt');
3627
3690
  // (In verbose mode, stderr was printed above, no need to repeat it)
3628
3691
  if (!verbose) {
3629
3692
  logger.logger.group('[VERBOSE] stderr:');
3630
3693
  logger.logger.error(output.stderr);
3631
3694
  logger.logger.groupEnd();
3632
3695
  }
3633
- process.exit(1);
3696
+ return;
3634
3697
  }
3635
3698
  const poms = [];
3636
3699
  output.stdout.replace(/Wrote (.*?.pom)\n/g, (_all, fn) => {
@@ -3638,22 +3701,24 @@ async function convertSbtToMaven(target, bin, out, verbose, sbtOpts) {
3638
3701
  return fn;
3639
3702
  });
3640
3703
  if (!poms.length) {
3641
- logger.logger.error('There were no errors from sbt but it seems to not have generated any poms either');
3642
- process.exit(1);
3704
+ process.exitCode = 1;
3705
+ logger.logger.fail('There were no errors from sbt but it seems to not have generated any poms either');
3706
+ return;
3643
3707
  }
3644
3708
  // Move the pom file to ...? initial cwd? loc will be an absolute path, or dump to stdout
3645
3709
  // TODO: what to do with multiple output files? Do we want to dump them to stdout? Raw or with separators or ?
3646
3710
  // TODO: maybe we can add an option to target a specific file to dump to stdout
3647
3711
  if (out === '-' && poms.length === 1) {
3648
3712
  logger.logger.log('Result:\n```');
3649
- logger.logger.log(await index.safeReadFile(poms[0], 'utf8'));
3713
+ logger.logger.log(await shadowNpmInject.safeReadFile(poms[0], 'utf8'));
3650
3714
  logger.logger.log('```');
3651
3715
  logger.logger.success(`OK`);
3652
3716
  } else if (out === '-') {
3653
- logger.logger.error('Requested out target was stdout but there are multiple generated files');
3717
+ process.exitCode = 1;
3718
+ logger.logger.fail('Requested out target was stdout but there are multiple generated files');
3654
3719
  poms.forEach(fn => logger.logger.error('-', fn));
3655
3720
  logger.logger.error('Exiting now...');
3656
- process.exit(1);
3721
+ return;
3657
3722
  } else {
3658
3723
  // if (verbose) {
3659
3724
  // logger.log(
@@ -3669,14 +3734,14 @@ async function convertSbtToMaven(target, bin, out, verbose, sbtOpts) {
3669
3734
  logger.logger.success(`OK`);
3670
3735
  }
3671
3736
  } catch (e) {
3737
+ process.exitCode = 1;
3672
3738
  spinner.stop();
3673
- logger.logger.error('There was an unexpected error while running this' + (verbose ? '' : ' (use --verbose for details)'));
3739
+ logger.logger.fail('There was an unexpected error while running this' + (verbose ? '' : ' (use --verbose for details)'));
3674
3740
  if (verbose) {
3675
3741
  logger.logger.group('[VERBOSE] error:');
3676
3742
  logger.logger.log(e);
3677
3743
  logger.logger.groupEnd();
3678
3744
  }
3679
- process.exit(1);
3680
3745
  }
3681
3746
  }
3682
3747
 
@@ -3784,7 +3849,7 @@ async function run$o(argv, importMeta, {
3784
3849
  // options or missing arguments.
3785
3850
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
3786
3851
  process.exitCode = 2;
3787
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
3852
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
3788
3853
 
3789
3854
  - The DIR or FILE arg is required ${!target ? colors.red('(missing!)') : target === '-' ? colors.red('(stdin is not supported)') : colors.green('(ok)')}
3790
3855
 
@@ -4044,7 +4109,7 @@ async function run$m(argv, importMeta, {
4044
4109
  // options or missing arguments.
4045
4110
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
4046
4111
  process.exitCode = 2;
4047
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
4112
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
4048
4113
 
4049
4114
  - The DIR arg is required ${!target ? colors.red('(missing!)') : target === '-' ? colors.red('(stdin is not supported)') : colors.green('(ok)')}
4050
4115
 
@@ -4119,12 +4184,11 @@ async function run$l(argv, importMeta, {
4119
4184
  }
4120
4185
 
4121
4186
  const {
4122
- NPM: NPM$b,
4123
- SHADOW_BIN: SHADOW_BIN$1
4187
+ NPM: NPM$b
4124
4188
  } = constants;
4125
4189
  async function wrapNpm(argv) {
4126
- // Lazily access constants.distPath.
4127
- const shadowBin = require(`${constants.distPath}/${SHADOW_BIN$1}.js`);
4190
+ // Lazily access constants.distShadowNpmBinPath.
4191
+ const shadowBin = require(constants.distShadowNpmBinPath);
4128
4192
  await shadowBin(NPM$b, argv);
4129
4193
  }
4130
4194
 
@@ -4165,12 +4229,11 @@ async function run$k(argv, importMeta, {
4165
4229
  }
4166
4230
 
4167
4231
  const {
4168
- NPX: NPX$2,
4169
- SHADOW_BIN
4232
+ NPX: NPX$2
4170
4233
  } = constants;
4171
4234
  async function wrapNpx(argv) {
4172
- // Lazily access constants.distPath.
4173
- const shadowBin = require(`${constants.distPath}/${SHADOW_BIN}.js`);
4235
+ // Lazily access constants.distShadowNpmBinPath.
4236
+ const shadowBin = require(constants.distShadowNpmBinPath);
4174
4237
  await shadowBin(NPX$2, argv);
4175
4238
  }
4176
4239
 
@@ -4333,8 +4396,8 @@ const readLockFileByAgent = (() => {
4333
4396
  return undefined;
4334
4397
  };
4335
4398
  }
4336
- const binaryReader = wrapReader(index.readFileBinary);
4337
- const defaultReader = wrapReader(async lockPath => await index.readFileUtf8(lockPath));
4399
+ const binaryReader = wrapReader(shadowNpmInject.readFileBinary);
4400
+ const defaultReader = wrapReader(async lockPath => await shadowNpmInject.readFileUtf8(lockPath));
4338
4401
  return {
4339
4402
  [BUN$5]: wrapReader(async (lockPath, agentExecPath) => {
4340
4403
  const ext = path.extname(lockPath);
@@ -4366,12 +4429,12 @@ async function detectPackageEnvironment({
4366
4429
  cwd = process$1.cwd(),
4367
4430
  onUnknown
4368
4431
  } = {}) {
4369
- let lockPath = await index.findUp(Object.keys(LOCKS), {
4432
+ let lockPath = await shadowNpmInject.findUp(Object.keys(LOCKS), {
4370
4433
  cwd
4371
4434
  });
4372
4435
  let lockName = lockPath ? path.basename(lockPath) : undefined;
4373
4436
  const isHiddenLockFile = lockName === '.package-lock.json';
4374
- const pkgJsonPath = lockPath ? path.resolve(lockPath, `${isHiddenLockFile ? '../' : ''}../package.json`) : await index.findUp('package.json', {
4437
+ const pkgJsonPath = lockPath ? path.resolve(lockPath, `${isHiddenLockFile ? '../' : ''}../package.json`) : await shadowNpmInject.findUp('package.json', {
4375
4438
  cwd
4376
4439
  });
4377
4440
  const pkgPath = pkgJsonPath && fs.existsSync(pkgJsonPath) ? path.dirname(pkgJsonPath) : undefined;
@@ -4483,36 +4546,36 @@ async function detectAndValidatePackageEnvironment(cwd, options) {
4483
4546
  const details = await detectPackageEnvironment({
4484
4547
  cwd,
4485
4548
  onUnknown(pkgManager) {
4486
- logger?.warn(`⚠️ ${COMMAND_TITLE$2}: Unknown package manager${pkgManager ? ` ${pkgManager}` : ''}, defaulting to npm`);
4549
+ logger?.warn(`${COMMAND_TITLE$2}: Unknown package manager${pkgManager ? ` ${pkgManager}` : ''}, defaulting to npm`);
4487
4550
  }
4488
4551
  });
4489
4552
  if (!details.supported) {
4490
- logger?.error(`✖️ ${COMMAND_TITLE$2}: No supported Node or browser range detected`);
4553
+ logger?.fail(`${COMMAND_TITLE$2}: No supported Node or browser range detected`);
4491
4554
  return;
4492
4555
  }
4493
4556
  if (details.agent === VLT$4) {
4494
- logger?.error(`✖️ ${COMMAND_TITLE$2}: ${details.agent} does not support overrides. Soon, though ⚡`);
4557
+ logger?.fail(`${COMMAND_TITLE$2}: ${details.agent} does not support overrides. Soon, though ⚡`);
4495
4558
  return;
4496
4559
  }
4497
4560
  const lockName = details.lockName ?? 'lock file';
4498
4561
  if (details.lockName === undefined || details.lockSrc === undefined) {
4499
- logger?.error(`✖️ ${COMMAND_TITLE$2}: No ${lockName} found`);
4562
+ logger?.fail(`${COMMAND_TITLE$2}: No ${lockName} found`);
4500
4563
  return;
4501
4564
  }
4502
4565
  if (details.lockSrc.trim() === '') {
4503
- logger?.error(`✖️ ${COMMAND_TITLE$2}: ${lockName} is empty`);
4566
+ logger?.fail(`${COMMAND_TITLE$2}: ${lockName} is empty`);
4504
4567
  return;
4505
4568
  }
4506
4569
  if (details.pkgPath === undefined) {
4507
- logger?.error(`✖️ ${COMMAND_TITLE$2}: No package.json found`);
4570
+ logger?.fail(`${COMMAND_TITLE$2}: No package.json found`);
4508
4571
  return;
4509
4572
  }
4510
4573
  if (prod && (details.agent === BUN$4 || details.agent === YARN_BERRY$4)) {
4511
- logger?.error(`✖️ ${COMMAND_TITLE$2}: --prod not supported for ${details.agent}${details.agentVersion ? `@${details.agentVersion.toString()}` : ''}`);
4574
+ logger?.fail(`${COMMAND_TITLE$2}: --prod not supported for ${details.agent}${details.agentVersion ? `@${details.agentVersion.toString()}` : ''}`);
4512
4575
  return;
4513
4576
  }
4514
4577
  if (details.lockPath && path.relative(cwd, details.lockPath).startsWith('.')) {
4515
- logger?.warn(`⚠️ ${COMMAND_TITLE$2}: Package ${lockName} found at ${details.lockPath}`);
4578
+ logger?.warn(`${COMMAND_TITLE$2}: Package ${lockName} found at ${details.lockPath}`);
4516
4579
  }
4517
4580
  return details;
4518
4581
  }
@@ -4616,7 +4679,7 @@ async function getWorkspaceGlobs(agent, pkgPath, pkgJson) {
4616
4679
  if (agent === PNPM$4) {
4617
4680
  for (const workspacePath of [path.join(pkgPath, `${PNPM_WORKSPACE}.yaml`), path.join(pkgPath, `${PNPM_WORKSPACE}.yml`)]) {
4618
4681
  // eslint-disable-next-line no-await-in-loop
4619
- const yml = await index.safeReadFile(workspacePath, 'utf8');
4682
+ const yml = await shadowNpmInject.safeReadFile(workspacePath, 'utf8');
4620
4683
  if (yml) {
4621
4684
  try {
4622
4685
  workspacePatterns = yaml.parse(yml)?.packages;
@@ -4961,8 +5024,8 @@ function safeNpmInstall(options) {
4961
5024
  constants.execPath, [
4962
5025
  // Lazily access constants.nodeNoWarningsFlags.
4963
5026
  ...constants.nodeNoWarningsFlags, '--require',
4964
- // Lazily access constants.npmInjectionPath.
4965
- constants.npmInjectionPath, npmPaths.getNpmBinPath(), 'install',
5027
+ // Lazily access constants.distShadowNpmInjectPath.
5028
+ constants.distShadowNpmInjectPath, shadowNpmPaths.getNpmBinPath(), 'install',
4966
5029
  // Even though the '--silent' flag is passed npm will still run through
4967
5030
  // code paths for 'audit' and 'fund' unless '--no-audit' and '--no-fund'
4968
5031
  // flags are passed.
@@ -5049,7 +5112,7 @@ async function updatePackageLockJson(pkgEnvDetails, options) {
5049
5112
  }
5050
5113
  } catch (e) {
5051
5114
  spinner?.stop();
5052
- logger?.error(`${COMMAND_TITLE$1}: ${pkgEnvDetails.agent} install failed to update ${pkgEnvDetails.lockName}`);
5115
+ logger?.fail(`${COMMAND_TITLE$1}: ${pkgEnvDetails.agent} install failed to update ${pkgEnvDetails.lockName}`);
5053
5116
  logger?.error(e);
5054
5117
  }
5055
5118
  }
@@ -5149,7 +5212,7 @@ async function addOverrides(pkgPath, pkgEnvDetails, options) {
5149
5212
  const isWorkspace = !!workspaceGlobs;
5150
5213
  if (isWorkspace && agent === PNPM && npmExecPath === NPM$1 && !state.warnedPnpmWorkspaceRequiresNpm) {
5151
5214
  state.warnedPnpmWorkspaceRequiresNpm = true;
5152
- logger?.warn(`⚠️ ${COMMAND_TITLE}: pnpm workspace support requires \`npm ls\`, falling back to \`pnpm list\``);
5215
+ logger?.warn(`${COMMAND_TITLE}: pnpm workspace support requires \`npm ls\`, falling back to \`pnpm list\``);
5153
5216
  }
5154
5217
  const thingToScan = isLockScanned ? lockSrc : await lsByAgent[agent](agentExecPath, pkgPath, {
5155
5218
  npmExecPath
@@ -5340,9 +5403,9 @@ async function run$h(argv, importMeta, {
5340
5403
  }
5341
5404
 
5342
5405
  async function getOrganization(format = 'text') {
5343
- const apiToken = index.getDefaultToken();
5406
+ const apiToken = shadowNpmInject.getDefaultToken();
5344
5407
  if (!apiToken) {
5345
- throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
5408
+ throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
5346
5409
  }
5347
5410
  await printOrganizationsFromToken(apiToken, format);
5348
5411
  }
@@ -5352,10 +5415,10 @@ async function printOrganizationsFromToken(apiToken, format = 'text') {
5352
5415
  spinner
5353
5416
  } = constants;
5354
5417
  spinner.start('Fetching organizations...');
5355
- const socketSdk = await index.setupSdk(apiToken);
5418
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
5356
5419
  const result = await handleApiCall(socketSdk.getOrganizations(), 'looking up organizations');
5357
5420
  if (!result.success) {
5358
- handleUnsuccessfulApiResponse('getOrganizations', result, spinner);
5421
+ handleUnsuccessfulApiResponse('getOrganizations', result);
5359
5422
  return;
5360
5423
  }
5361
5424
  spinner.stop();
@@ -5446,7 +5509,7 @@ async function run$g(argv, importMeta, {
5446
5509
  // options or missing arguments.
5447
5510
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
5448
5511
  process.exitCode = 2;
5449
- logger.logger.error(commonTags.stripIndents`
5512
+ logger.logger.fail(commonTags.stripIndents`
5450
5513
  ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
5451
5514
 
5452
5515
  - The json and markdown flags cannot be both set, pick one
@@ -5461,7 +5524,7 @@ ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields
5461
5524
  }
5462
5525
 
5463
5526
  async function runRawNpm(argv) {
5464
- const spawnPromise = spawn.spawn(npmPaths.getNpmBinPath(), argv, {
5527
+ const spawnPromise = spawn.spawn(shadowNpmPaths.getNpmBinPath(), argv, {
5465
5528
  stdio: 'inherit'
5466
5529
  });
5467
5530
  // See https://nodejs.org/api/all.html#all_child_process_event-exit.
@@ -5484,13 +5547,10 @@ const config$f = {
5484
5547
  description: `Temporarily disable the Socket ${NPM} wrapper`,
5485
5548
  hidden: false,
5486
5549
  flags: {},
5487
- help: (command, config) => `
5550
+ help: command => `
5488
5551
  Usage
5489
5552
  $ ${command} <command>
5490
5553
 
5491
- Options
5492
- ${getFlagListOutput(config.flags, 6)}
5493
-
5494
5554
  Examples
5495
5555
  $ ${command} install
5496
5556
  `
@@ -5518,7 +5578,7 @@ async function run$f(argv, importMeta, {
5518
5578
  }
5519
5579
 
5520
5580
  async function runRawNpx(argv) {
5521
- const spawnPromise = spawn.spawn(npmPaths.getNpxBinPath(), argv, {
5581
+ const spawnPromise = spawn.spawn(shadowNpmPaths.getNpxBinPath(), argv, {
5522
5582
  stdio: 'inherit'
5523
5583
  });
5524
5584
  // See https://nodejs.org/api/all.html#all_child_process_event-exit.
@@ -5541,13 +5601,10 @@ const config$e = {
5541
5601
  description: `Temporarily disable the Socket ${NPX} wrapper`,
5542
5602
  hidden: false,
5543
5603
  flags: {},
5544
- help: (command, config) => `
5604
+ help: command => `
5545
5605
  Usage
5546
5606
  $ ${command} <command>
5547
5607
 
5548
- Options
5549
- ${getFlagListOutput(config.flags, 6)}
5550
-
5551
5608
  Examples
5552
5609
  $ ${command} install
5553
5610
  `
@@ -5585,19 +5642,17 @@ async function createReport(socketConfig, inputPaths, {
5585
5642
  const {
5586
5643
  spinner
5587
5644
  } = constants;
5588
- const socketSdk = await index.setupSdk();
5645
+ const socketSdk = await shadowNpmInject.setupSdk();
5589
5646
  const supportedFiles = await socketSdk.getReportSupportedFiles().then(res => {
5590
- if (!res.success) handleUnsuccessfulApiResponse('getReportSupportedFiles', res, spinner);
5647
+ if (!res.success) handleUnsuccessfulApiResponse('getReportSupportedFiles', res);
5591
5648
  return res.data;
5592
5649
  }).catch(cause => {
5593
5650
  throw new Error('Failed getting supported files for report', {
5594
5651
  cause
5595
5652
  });
5596
5653
  });
5597
- const packagePaths = await npmPaths.getPackageFiles(cwd, inputPaths, socketConfig, supportedFiles);
5598
- const {
5599
- length: packagePathsCount
5600
- } = packagePaths;
5654
+ const packagePaths = await shadowNpmPaths.getPackageFilesFullScans(cwd, inputPaths, supportedFiles, socketConfig);
5655
+ const packagePathsCount = packagePaths.length;
5601
5656
  if (packagePathsCount && debug.isDebug()) {
5602
5657
  for (const pkgPath of packagePaths) {
5603
5658
  debug.debugLog(`Uploading: ${pkgPath}`);
@@ -5611,7 +5666,7 @@ async function createReport(socketConfig, inputPaths, {
5611
5666
  const apiCall = socketSdk.createReportFromFilePaths(packagePaths, cwd, socketConfig?.issueRules);
5612
5667
  const result = await handleApiCall(apiCall, 'creating report');
5613
5668
  if (!result.success) {
5614
- handleUnsuccessfulApiResponse('createReport', result, spinner);
5669
+ handleUnsuccessfulApiResponse('createReport', result);
5615
5670
  return undefined;
5616
5671
  }
5617
5672
  spinner.successAndStop();
@@ -5629,7 +5684,7 @@ async function getSocketConfig(absoluteConfigPath) {
5629
5684
  errors: cause.validationErrors,
5630
5685
  schema: cause.schema
5631
5686
  });
5632
- throw new index.InputError('The socket.yml config is not valid', betterErrors.map(err => `[${err.path}] ${err.message}.${err.suggestion ? err.suggestion : ''}`).join('\n'));
5687
+ throw new shadowNpmInject.InputError('The socket.yml config is not valid', betterErrors.map(err => `[${err.path}] ${err.message}.${err.suggestion ? err.suggestion : ''}`).join('\n'));
5633
5688
  } else {
5634
5689
  throw new Error('Failed to read socket.yml config', {
5635
5690
  cause
@@ -5647,7 +5702,7 @@ async function fetchReportData(reportId, includeAllIssues, strict) {
5647
5702
  spinner
5648
5703
  } = constants;
5649
5704
  spinner.start(`Fetching report with ID ${reportId} (this could take a while)`);
5650
- const socketSdk = await index.setupSdk();
5705
+ const socketSdk = await shadowNpmInject.setupSdk();
5651
5706
  let result;
5652
5707
  for (let retry = 1; !result; ++retry) {
5653
5708
  try {
@@ -5661,7 +5716,7 @@ async function fetchReportData(reportId, includeAllIssues, strict) {
5661
5716
  }
5662
5717
  }
5663
5718
  if (!result.success) {
5664
- return handleUnsuccessfulApiResponse('getReport', result, spinner);
5719
+ return handleUnsuccessfulApiResponse('getReport', result);
5665
5720
  }
5666
5721
 
5667
5722
  // Conclude the status of the API call.
@@ -5686,7 +5741,7 @@ function formatReportDataOutput(reportId, data, commandName, outputJson, outputM
5686
5741
  if (outputJson) {
5687
5742
  logger.logger.log(JSON.stringify(data, undefined, 2));
5688
5743
  } else {
5689
- const format = new index.ColorOrMarkdown(outputMarkdown);
5744
+ const format = new shadowNpmInject.ColorOrMarkdown(outputMarkdown);
5690
5745
  logger.logger.log(commonTags.stripIndents`
5691
5746
  Detailed info on socket.dev: ${format.hyperlink(reportId, data.url, {
5692
5747
  fallbackToUrl: true
@@ -5718,7 +5773,7 @@ const {
5718
5773
  } = constants;
5719
5774
  const config$d = {
5720
5775
  commandName: 'create',
5721
- description: 'Create a project report',
5776
+ description: '[Deprecated] Create a project report',
5722
5777
  hidden: false,
5723
5778
  flags: {
5724
5779
  ...commonFlags,
@@ -5736,27 +5791,9 @@ const config$d = {
5736
5791
  description: 'Will wait for and return the created report'
5737
5792
  }
5738
5793
  },
5739
- help: (command, config) => `
5740
- Usage
5741
- $ ${command} <paths-to-package-folders-and-files>
5742
-
5743
- Uploads the specified "package.json" and lock files for JavaScript, Python, and Go dependency manifests.
5744
- If any folder is specified, the ones found in there recursively are uploaded.
5745
-
5746
- Supports globbing such as "**/package.json", "**/requirements.txt", "**/pyproject.toml", and "**/go.mod".
5747
-
5748
- Ignores any file specified in your project's ".gitignore", your project's
5749
- "socket.yml" file's "projectIgnorePaths" and also has a sensible set of
5750
- default ignores from the "ignore-by-default" module.
5751
-
5752
- Options
5753
- ${getFlagListOutput(config.flags, 6)}
5754
-
5755
- Examples
5756
- $ ${command} .
5757
- $ ${command} '**/package.json'
5758
- $ ${command} /path/to/a/package.json /path/to/another/package.json
5759
- $ ${command} . --view --json
5794
+ help: () => `
5795
+ This command is deprecated in favor of \`socket scan create\`.
5796
+ It will be removed in the next major release of the CLI.
5760
5797
  `
5761
5798
  };
5762
5799
  const cmdReportCreate = {
@@ -5808,7 +5845,7 @@ async function run$d(argv, importMeta, {
5808
5845
  } else if (json) {
5809
5846
  logger.logger.log(JSON.stringify(result.data, undefined, 2));
5810
5847
  } else {
5811
- const format = new index.ColorOrMarkdown(markdown);
5848
+ const format = new shadowNpmInject.ColorOrMarkdown(markdown);
5812
5849
  logger.logger.log(`New report: ${format.hyperlink(result.data.id, result.data.url, {
5813
5850
  fallbackToUrl: true
5814
5851
  })}`);
@@ -5821,22 +5858,16 @@ const {
5821
5858
  } = constants;
5822
5859
  const config$c = {
5823
5860
  commandName: 'view',
5824
- description: 'View a project report',
5861
+ description: '[Deprecated] View a project report',
5825
5862
  hidden: false,
5826
5863
  flags: {
5827
5864
  ...commonFlags,
5828
5865
  ...outputFlags,
5829
5866
  ...validationFlags
5830
5867
  },
5831
- help: (command, config) => `
5832
- Usage
5833
- $ ${command} <report-identifier>
5834
-
5835
- Options
5836
- ${getFlagListOutput(config.flags, 6)}
5837
-
5838
- Examples
5839
- $ ${command} QXU8PmK7LfH608RAwfIKdbcHgwEd_ZeWJ9QEGv05FJUQ
5868
+ help: () => `
5869
+ This command is deprecated in favor of \`socket scan view\`.
5870
+ It will be removed in the next major release of the CLI.
5840
5871
  `
5841
5872
  };
5842
5873
  const cmdReportView = {
@@ -5861,7 +5892,7 @@ async function run$c(argv, importMeta, {
5861
5892
  // options or missing arguments.
5862
5893
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
5863
5894
  process.exitCode = 2;
5864
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
5895
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
5865
5896
 
5866
5897
  - Need at least one report ID ${!reportId ? colors.red('(missing!)') : colors.green('(ok)')}
5867
5898
 
@@ -5884,6 +5915,8 @@ async function run$c(argv, importMeta, {
5884
5915
  const description$2 = '[Deprecated] Project report related commands';
5885
5916
  const cmdReport = {
5886
5917
  description: description$2,
5918
+ hidden: true,
5919
+ // Deprecated in favor of `scan`
5887
5920
  async run(argv, importMeta, {
5888
5921
  parentName
5889
5922
  }) {
@@ -5900,13 +5933,33 @@ const cmdReport = {
5900
5933
  };
5901
5934
 
5902
5935
  async function createRepo({
5936
+ default_branch,
5937
+ description,
5938
+ homepage,
5939
+ orgSlug,
5940
+ repoName,
5941
+ visibility
5942
+ }) {
5943
+ const apiToken = shadowNpmInject.getDefaultToken();
5944
+ if (!apiToken) {
5945
+ throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
5946
+ }
5947
+ await createRepoWithToken({
5948
+ apiToken,
5949
+ default_branch,
5950
+ description,
5951
+ homepage,
5952
+ orgSlug,
5953
+ repoName,
5954
+ visibility
5955
+ });
5956
+ }
5957
+ async function createRepoWithToken({
5903
5958
  apiToken,
5904
5959
  default_branch,
5905
5960
  description,
5906
5961
  homepage,
5907
5962
  orgSlug,
5908
- outputJson,
5909
- outputMarkdown,
5910
5963
  repoName,
5911
5964
  visibility
5912
5965
  }) {
@@ -5915,22 +5968,19 @@ async function createRepo({
5915
5968
  spinner
5916
5969
  } = constants;
5917
5970
  spinner.start('Creating repository...');
5918
- const socketSdk = await index.setupSdk(apiToken);
5971
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
5919
5972
  const result = await handleApiCall(socketSdk.createOrgRepo(orgSlug, {
5920
- outputJson,
5921
- outputMarkdown,
5922
- orgSlug,
5923
5973
  name: repoName,
5924
5974
  description,
5925
5975
  homepage,
5926
5976
  default_branch,
5927
5977
  visibility
5928
5978
  }), 'creating repository');
5929
- if (result.success) {
5930
- spinner.successAndStop('Repository created successfully');
5931
- } else {
5932
- handleUnsuccessfulApiResponse('createOrgRepo', result, spinner);
5979
+ if (!result.success) {
5980
+ handleUnsuccessfulApiResponse('createOrgRepo', result);
5981
+ return;
5933
5982
  }
5983
+ spinner.successAndStop('Repository created successfully');
5934
5984
  }
5935
5985
 
5936
5986
  const {
@@ -5942,7 +5992,6 @@ const config$b = {
5942
5992
  hidden: false,
5943
5993
  flags: {
5944
5994
  ...commonFlags,
5945
- ...outputFlags,
5946
5995
  repoName: {
5947
5996
  type: 'string',
5948
5997
  shortFlag: 'n',
@@ -6006,7 +6055,7 @@ async function run$b(argv, importMeta, {
6006
6055
  // options or missing arguments.
6007
6056
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
6008
6057
  process.exitCode = 2;
6009
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6058
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6010
6059
 
6011
6060
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
6012
6061
 
@@ -6017,36 +6066,36 @@ async function run$b(argv, importMeta, {
6017
6066
  logger.logger.log(DRY_RUN_BAIL_TEXT$b);
6018
6067
  return;
6019
6068
  }
6020
- const apiToken = index.getDefaultToken();
6021
- if (!apiToken) {
6022
- throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
6023
- }
6024
6069
  await createRepo({
6025
- outputJson: Boolean(cli.flags['json']),
6026
- outputMarkdown: Boolean(cli.flags['markdown']),
6027
6070
  orgSlug,
6028
6071
  repoName,
6029
6072
  description: String(cli.flags['repoDescription'] || ''),
6030
6073
  homepage: String(cli.flags['homepage'] || ''),
6031
6074
  default_branch: String(cli.flags['defaultBranch'] || ''),
6032
- visibility: String(cli.flags['visibility'] || 'private'),
6033
- apiToken
6075
+ visibility: String(cli.flags['visibility'] || 'private')
6034
6076
  });
6035
6077
  }
6036
6078
 
6037
- async function deleteRepo(orgSlug, repoName, apiToken) {
6079
+ async function deleteRepo(orgSlug, repoName) {
6080
+ const apiToken = shadowNpmInject.getDefaultToken();
6081
+ if (!apiToken) {
6082
+ throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
6083
+ }
6084
+ await deleteRepoWithToken(orgSlug, repoName, apiToken);
6085
+ }
6086
+ async function deleteRepoWithToken(orgSlug, repoName, apiToken) {
6038
6087
  // Lazily access constants.spinner.
6039
6088
  const {
6040
6089
  spinner
6041
6090
  } = constants;
6042
6091
  spinner.start('Deleting repository...');
6043
- const socketSdk = await index.setupSdk(apiToken);
6092
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
6044
6093
  const result = await handleApiCall(socketSdk.deleteOrgRepo(orgSlug, repoName), 'deleting repository');
6045
- if (result.success) {
6046
- spinner.successAndStop('Repository deleted successfully');
6047
- } else {
6048
- handleUnsuccessfulApiResponse('deleteOrgRepo', result, spinner);
6094
+ if (!result.success) {
6095
+ handleUnsuccessfulApiResponse('deleteOrgRepo', result);
6096
+ return;
6049
6097
  }
6098
+ spinner.successAndStop('Repository deleted successfully');
6050
6099
  }
6051
6100
 
6052
6101
  const {
@@ -6090,7 +6139,7 @@ async function run$a(argv, importMeta, {
6090
6139
  // options or missing arguments.
6091
6140
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
6092
6141
  process.exitCode = 2;
6093
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6142
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6094
6143
 
6095
6144
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
6096
6145
 
@@ -6103,20 +6152,37 @@ async function run$a(argv, importMeta, {
6103
6152
  logger.logger.log(DRY_RUN_BAIL_TEXT$a);
6104
6153
  return;
6105
6154
  }
6106
- const apiToken = index.getDefaultToken();
6107
- if (!apiToken) {
6108
- throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
6109
- }
6110
- await deleteRepo(orgSlug, repoName, apiToken);
6155
+ await deleteRepo(orgSlug, repoName);
6111
6156
  }
6112
6157
 
6113
6158
  // @ts-ignore
6114
6159
  async function listRepos({
6160
+ direction,
6161
+ orgSlug,
6162
+ outputKind,
6163
+ page,
6164
+ per_page,
6165
+ sort
6166
+ }) {
6167
+ const apiToken = shadowNpmInject.getDefaultToken();
6168
+ if (!apiToken) {
6169
+ throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
6170
+ }
6171
+ await listReposWithToken({
6172
+ apiToken,
6173
+ direction,
6174
+ orgSlug,
6175
+ outputKind,
6176
+ page,
6177
+ per_page,
6178
+ sort
6179
+ });
6180
+ }
6181
+ async function listReposWithToken({
6115
6182
  apiToken,
6116
6183
  direction,
6117
6184
  orgSlug,
6118
- outputJson,
6119
- outputMarkdown,
6185
+ outputKind,
6120
6186
  page,
6121
6187
  per_page,
6122
6188
  sort
@@ -6125,23 +6191,20 @@ async function listRepos({
6125
6191
  const {
6126
6192
  spinner
6127
6193
  } = constants;
6128
- spinner.start('Listing repositories...');
6129
- const socketSdk = await index.setupSdk(apiToken);
6194
+ spinner.start('Fetching list of repositories...');
6195
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
6130
6196
  const result = await handleApiCall(socketSdk.getOrgRepoList(orgSlug, {
6131
- outputJson,
6132
- outputMarkdown,
6133
- orgSlug,
6134
6197
  sort,
6135
6198
  direction,
6136
6199
  per_page,
6137
6200
  page
6138
6201
  }), 'listing repositories');
6139
6202
  if (!result.success) {
6140
- handleUnsuccessfulApiResponse('getOrgRepoList', result, spinner);
6203
+ handleUnsuccessfulApiResponse('getOrgRepoList', result);
6141
6204
  return;
6142
6205
  }
6143
- spinner.stop();
6144
- if (outputJson) {
6206
+ spinner.stop('Fetch complete.');
6207
+ if (outputKind === 'json') {
6145
6208
  const data = result.data.results.map(o => ({
6146
6209
  id: o.id,
6147
6210
  name: o.name,
@@ -6238,7 +6301,7 @@ async function run$9(argv, importMeta, {
6238
6301
  // options or missing arguments.
6239
6302
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
6240
6303
  process.exitCode = 2;
6241
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6304
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6242
6305
 
6243
6306
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
6244
6307
 
@@ -6249,30 +6312,44 @@ async function run$9(argv, importMeta, {
6249
6312
  logger.logger.log(DRY_RUN_BAIL_TEXT$9);
6250
6313
  return;
6251
6314
  }
6252
- const apiToken = index.getDefaultToken();
6253
- if (!apiToken) {
6254
- throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
6255
- }
6256
6315
  await listRepos({
6257
- apiToken,
6258
- outputJson: Boolean(cli.flags['json']),
6259
- outputMarkdown: Boolean(cli.flags['markdown']),
6260
- orgSlug,
6261
- sort: String(cli.flags['sort'] || 'created_at'),
6262
6316
  direction: cli.flags['direction'] === 'asc' ? 'asc' : 'desc',
6317
+ orgSlug,
6318
+ outputKind: cli.flags['json'] ? 'json' : cli.flags['markdown'] ? 'markdown' : 'print',
6263
6319
  page: Number(cli.flags['page']) || 1,
6264
- per_page: Number(cli.flags['perPage']) || 30
6320
+ per_page: Number(cli.flags['perPage']) || 30,
6321
+ sort: String(cli.flags['sort'] || 'created_at')
6265
6322
  });
6266
6323
  }
6267
6324
 
6268
6325
  async function updateRepo({
6326
+ default_branch,
6327
+ description,
6328
+ homepage,
6329
+ orgSlug,
6330
+ repoName,
6331
+ visibility
6332
+ }) {
6333
+ const apiToken = shadowNpmInject.getDefaultToken();
6334
+ if (!apiToken) {
6335
+ throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
6336
+ }
6337
+ await updateRepoWithToken({
6338
+ apiToken,
6339
+ default_branch,
6340
+ description,
6341
+ homepage,
6342
+ orgSlug,
6343
+ repoName,
6344
+ visibility
6345
+ });
6346
+ }
6347
+ async function updateRepoWithToken({
6269
6348
  apiToken,
6270
6349
  default_branch,
6271
6350
  description,
6272
6351
  homepage,
6273
6352
  orgSlug,
6274
- outputJson,
6275
- outputMarkdown,
6276
6353
  repoName,
6277
6354
  visibility
6278
6355
  }) {
@@ -6281,10 +6358,8 @@ async function updateRepo({
6281
6358
  spinner
6282
6359
  } = constants;
6283
6360
  spinner.start('Updating repository...');
6284
- const socketSdk = await index.setupSdk(apiToken);
6361
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
6285
6362
  const result = await handleApiCall(socketSdk.updateOrgRepo(orgSlug, repoName, {
6286
- outputJson,
6287
- outputMarkdown,
6288
6363
  orgSlug,
6289
6364
  name: repoName,
6290
6365
  description,
@@ -6292,11 +6367,11 @@ async function updateRepo({
6292
6367
  default_branch,
6293
6368
  visibility
6294
6369
  }), 'updating repository');
6295
- if (result.success) {
6296
- spinner.successAndStop('Repository updated successfully');
6297
- } else {
6298
- handleUnsuccessfulApiResponse('updateOrgRepo', result, spinner);
6370
+ if (!result.success) {
6371
+ handleUnsuccessfulApiResponse('updateOrgRepo', result);
6372
+ return;
6299
6373
  }
6374
+ spinner.successAndStop('Repository updated successfully');
6300
6375
  }
6301
6376
 
6302
6377
  const {
@@ -6308,7 +6383,6 @@ const config$8 = {
6308
6383
  hidden: false,
6309
6384
  flags: {
6310
6385
  ...commonFlags,
6311
- ...outputFlags,
6312
6386
  repoName: {
6313
6387
  type: 'string',
6314
6388
  shortFlag: 'n',
@@ -6372,7 +6446,7 @@ async function run$8(argv, importMeta, {
6372
6446
  // options or missing arguments.
6373
6447
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
6374
6448
  process.exitCode = 2;
6375
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6449
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6376
6450
 
6377
6451
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
6378
6452
 
@@ -6385,14 +6459,7 @@ async function run$8(argv, importMeta, {
6385
6459
  logger.logger.log(DRY_RUN_BAIL_TEXT$8);
6386
6460
  return;
6387
6461
  }
6388
- const apiToken = index.getDefaultToken();
6389
- if (!apiToken) {
6390
- throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
6391
- }
6392
6462
  await updateRepo({
6393
- apiToken,
6394
- outputJson: Boolean(cli.flags['json']),
6395
- outputMarkdown: Boolean(cli.flags['markdown']),
6396
6463
  orgSlug,
6397
6464
  repoName,
6398
6465
  description: String(cli.flags['repoDescription'] || ''),
@@ -6403,16 +6470,45 @@ async function run$8(argv, importMeta, {
6403
6470
  }
6404
6471
 
6405
6472
  // @ts-ignore
6406
- async function viewRepo(orgSlug, repoName, apiToken) {
6473
+ async function viewRepo(orgSlug, repoName, outputKind) {
6474
+ const apiToken = shadowNpmInject.getDefaultToken();
6475
+ if (!apiToken) {
6476
+ throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
6477
+ }
6478
+ await viewRepoWithToken(orgSlug, repoName, apiToken, outputKind);
6479
+ }
6480
+ async function viewRepoWithToken(orgSlug, repoName, apiToken, outputKind) {
6407
6481
  // Lazily access constants.spinner.
6408
6482
  const {
6409
6483
  spinner
6410
6484
  } = constants;
6411
- spinner.start('Fetching repository...');
6412
- const socketSdk = await index.setupSdk(apiToken);
6485
+ spinner.start('Fetching repository data...');
6486
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
6413
6487
  const result = await handleApiCall(socketSdk.getOrgRepo(orgSlug, repoName), 'fetching repository');
6414
6488
  if (!result.success) {
6415
- handleUnsuccessfulApiResponse('getOrgRepo', result, spinner);
6489
+ handleUnsuccessfulApiResponse('getOrgRepo', result);
6490
+ return;
6491
+ }
6492
+ spinner.stop('Fetched repository data.');
6493
+ if (outputKind === 'json') {
6494
+ const {
6495
+ archived,
6496
+ created_at,
6497
+ default_branch,
6498
+ homepage,
6499
+ id,
6500
+ name,
6501
+ visibility
6502
+ } = result.data;
6503
+ logger.logger.log(JSON.stringify({
6504
+ id,
6505
+ name,
6506
+ visibility,
6507
+ default_branch,
6508
+ homepage,
6509
+ archived,
6510
+ created_at
6511
+ }, null, 2));
6416
6512
  return;
6417
6513
  }
6418
6514
  const options = {
@@ -6439,7 +6535,7 @@ async function viewRepo(orgSlug, repoName, apiToken) {
6439
6535
  name: colors.magenta('Created at')
6440
6536
  }]
6441
6537
  };
6442
- spinner.stop(chalkTable(options, [result.data]));
6538
+ logger.logger.log(chalkTable(options, [result.data]));
6443
6539
  }
6444
6540
 
6445
6541
  const {
@@ -6451,7 +6547,12 @@ const config$7 = {
6451
6547
  hidden: false,
6452
6548
  flags: {
6453
6549
  ...commonFlags,
6454
- ...outputFlags
6550
+ ...outputFlags,
6551
+ repoName: {
6552
+ description: 'The repository to check',
6553
+ default: '',
6554
+ type: 'string'
6555
+ }
6455
6556
  },
6456
6557
  help: (command, config) => `
6457
6558
  Usage
@@ -6485,7 +6586,7 @@ async function run$7(argv, importMeta, {
6485
6586
  // options or missing arguments.
6486
6587
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
6487
6588
  process.exitCode = 2;
6488
- logger.logger.error(commonTags.stripIndents`
6589
+ logger.logger.fail(commonTags.stripIndents`
6489
6590
  ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6490
6591
 
6491
6592
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
@@ -6498,11 +6599,7 @@ async function run$7(argv, importMeta, {
6498
6599
  logger.logger.log(DRY_RUN_BAIL_TEXT$7);
6499
6600
  return;
6500
6601
  }
6501
- const apiToken = index.getDefaultToken();
6502
- if (!apiToken) {
6503
- throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
6504
- }
6505
- await viewRepo(orgSlug, repoName, apiToken);
6602
+ await viewRepo(orgSlug, repoName, cli.flags['json'] ? 'json' : cli.flags['markdown'] ? 'markdown' : 'print');
6506
6603
  }
6507
6604
 
6508
6605
  const description$1 = 'Repositories related commands';
@@ -6687,10 +6784,10 @@ async function createFullScan({
6687
6784
  const {
6688
6785
  spinner
6689
6786
  } = constants;
6690
- const socketSdk = await index.setupSdk();
6787
+ const socketSdk = await shadowNpmInject.setupSdk();
6691
6788
  const supportedFiles = await socketSdk.getReportSupportedFiles().then(res => {
6692
6789
  if (!res.success) {
6693
- handleUnsuccessfulApiResponse('getReportSupportedFiles', res, spinner);
6790
+ handleUnsuccessfulApiResponse('getReportSupportedFiles', res);
6694
6791
  assert(false, 'handleUnsuccessfulApiResponse should unconditionally throw');
6695
6792
  }
6696
6793
  return res.data;
@@ -6708,46 +6805,53 @@ async function createFullScan({
6708
6805
  targets = received ?? [];
6709
6806
  updatedInput = true;
6710
6807
  }
6711
- const packagePaths = await npmPaths.getPackageFilesFullScans(cwd, targets, supportedFiles);
6808
+
6809
+ // // TODO: we'll probably use socket.json or something else soon...
6810
+ // const absoluteConfigPath = path.join(cwd, 'socket.yml')
6811
+ // const socketConfig = await getSocketConfig(absoluteConfigPath)
6812
+
6813
+ const packagePaths = await shadowNpmPaths.getPackageFilesFullScans(cwd, targets, supportedFiles
6814
+ // socketConfig
6815
+ );
6712
6816
 
6713
6817
  // We're going to need an api token to suggest data because those suggestions
6714
6818
  // must come from data we already know. Don't error on missing api token yet.
6715
6819
  // If the api-token is not set, ignore it for the sake of suggestions.
6716
- const apiToken = index.getDefaultToken();
6717
- if (apiToken && !orgSlug) {
6718
- const suggestion = await suggestOrgSlug(socketSdk);
6719
- if (suggestion) orgSlug = suggestion;
6720
- updatedInput = true;
6721
- }
6820
+ const apiToken = shadowNpmInject.getDefaultToken();
6722
6821
 
6723
6822
  // If the current cwd is unknown and is used as a repo slug anyways, we will
6724
6823
  // first need to register the slug before we can use it.
6725
6824
  let repoDefaultBranch = '';
6726
-
6727
- // (Don't bother asking for the rest if we didn't get an org slug above)
6728
- if (apiToken && orgSlug && !repoName) {
6729
- const suggestion = await suggestRepoSlug(socketSdk, orgSlug);
6730
- if (suggestion) {
6731
- ({
6732
- defaultBranch: repoDefaultBranch,
6733
- slug: repoName
6734
- } = suggestion);
6825
+ if (apiToken) {
6826
+ if (!orgSlug) {
6827
+ const suggestion = await suggestOrgSlug(socketSdk);
6828
+ if (suggestion) orgSlug = suggestion;
6829
+ updatedInput = true;
6830
+ }
6831
+
6832
+ // (Don't bother asking for the rest if we didn't get an org slug above)
6833
+ if (orgSlug && !repoName) {
6834
+ const suggestion = await suggestRepoSlug(socketSdk, orgSlug);
6835
+ if (suggestion) {
6836
+ repoDefaultBranch = suggestion.defaultBranch;
6837
+ repoName = suggestion.slug;
6838
+ }
6839
+ updatedInput = true;
6735
6840
  }
6736
- updatedInput = true;
6737
- }
6738
6841
 
6739
- // (Don't bother asking for the rest if we didn't get an org/repo above)
6740
- if (apiToken && orgSlug && repoName && !branchName) {
6741
- const suggestion = await suggestBranchSlug(repoDefaultBranch);
6742
- if (suggestion) branchName = suggestion;
6743
- updatedInput = true;
6842
+ // (Don't bother asking for the rest if we didn't get an org/repo above)
6843
+ if (orgSlug && repoName && !branchName) {
6844
+ const suggestion = await suggestBranchSlug(repoDefaultBranch);
6845
+ if (suggestion) branchName = suggestion;
6846
+ updatedInput = true;
6847
+ }
6744
6848
  }
6745
6849
  if (!orgSlug || !repoName || !branchName || !packagePaths.length) {
6746
6850
  // Use exit status of 2 to indicate incorrect usage, generally invalid
6747
6851
  // options or missing arguments.
6748
6852
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
6749
6853
  process$1.exitCode = 2;
6750
- logger.logger.error(commonTags.stripIndents`
6854
+ logger.logger.fail(commonTags.stripIndents`
6751
6855
  ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6752
6856
 
6753
6857
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
@@ -6769,13 +6873,13 @@ async function createFullScan({
6769
6873
  logger.logger.log('```');
6770
6874
  }
6771
6875
  if (!apiToken) {
6772
- throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
6876
+ throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
6773
6877
  }
6774
6878
  if (readOnly) {
6775
6879
  logger.logger.log('[ReadOnly] Bailing now');
6776
6880
  return;
6777
6881
  }
6778
- spinner.start('Creating a scan...');
6882
+ spinner.start(`Creating a scan with ${packagePaths.length} packages...`);
6779
6883
  const result = await handleApiCall(socketSdk.createOrgFullScan(orgSlug, {
6780
6884
  repo: repoName,
6781
6885
  branch: branchName,
@@ -6785,7 +6889,7 @@ async function createFullScan({
6785
6889
  tmp
6786
6890
  }, packagePaths, cwd), 'Creating scan');
6787
6891
  if (!result.success) {
6788
- handleUnsuccessfulApiResponse('CreateOrgFullScan', result, spinner);
6892
+ handleUnsuccessfulApiResponse('CreateOrgFullScan', result);
6789
6893
  return;
6790
6894
  }
6791
6895
  spinner.successAndStop('Scan created successfully');
@@ -6875,13 +6979,29 @@ const config$6 = {
6875
6979
  shortFlag: 't',
6876
6980
  default: false,
6877
6981
  description: 'Set the visibility (true/false) of the scan in your dashboard'
6982
+ },
6983
+ view: {
6984
+ type: 'boolean',
6985
+ shortFlag: 'v',
6986
+ default: true,
6987
+ description: 'Will wait for and return the created report. Use --no-view to disable.'
6878
6988
  }
6879
6989
  },
6990
+ // TODO: your project's "socket.yml" file's "projectIgnorePaths"
6880
6991
  help: (command, config) => `
6881
6992
  Usage
6882
6993
  $ ${command} [...options] <org> <TARGET> [TARGET...]
6883
6994
 
6884
- Where TARGET is a FILE or DIR that _must_ be inside the CWD.
6995
+ Uploads the specified "package.json" and lock files for JavaScript, Python,
6996
+ Go, Scala, Gradle, and Kotlin dependency manifests.
6997
+ If any folder is specified, the ones found in there recursively are uploaded.
6998
+
6999
+ Supports globbing such as "**/package.json", "**/requirements.txt", etc.
7000
+
7001
+ Ignores any file specified in your project's ".gitignore" and also has a
7002
+ sensible set of default ignores from the "ignore-by-default" module.
7003
+
7004
+ TARGET should be a FILE or DIR that _must_ be inside the CWD.
6885
7005
 
6886
7006
  When a FILE is given only that FILE is targeted. Otherwise any eligible
6887
7007
  files in the given DIR will be considered.
@@ -6913,15 +7033,17 @@ async function run$6(argv, importMeta, {
6913
7033
  branch: branchName,
6914
7034
  repo: repoName
6915
7035
  } = cli.flags;
6916
- const apiToken = index.getDefaultToken();
7036
+ const apiToken = shadowNpmInject.getDefaultToken(); // This checks if we _can_ suggest anything
7037
+
6917
7038
  if (!apiToken && (!orgSlug || !repoName || !branchName || !targets.length)) {
6918
7039
  // Without api token we cannot recover because we can't request more info
6919
7040
  // from the server, to match and help with the current cwd/git status.
7041
+ //
6920
7042
  // Use exit status of 2 to indicate incorrect usage, generally invalid
6921
7043
  // options or missing arguments.
6922
7044
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
6923
7045
  process$1.exitCode = 2;
6924
- logger.logger.error(commonTags.stripIndents`
7046
+ logger.logger.fail(commonTags.stripIndents`
6925
7047
  ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6926
7048
 
6927
7049
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
@@ -6959,16 +7081,23 @@ async function run$6(argv, importMeta, {
6959
7081
  });
6960
7082
  }
6961
7083
 
6962
- async function deleteOrgFullScan(orgSlug, fullScanId, apiToken) {
7084
+ async function deleteOrgFullScan(orgSlug, fullScanId) {
7085
+ const apiToken = shadowNpmInject.getDefaultToken();
7086
+ if (!apiToken) {
7087
+ throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
7088
+ }
7089
+ await deleteOrgFullScanWithToken(orgSlug, fullScanId, apiToken);
7090
+ }
7091
+ async function deleteOrgFullScanWithToken(orgSlug, fullScanId, apiToken) {
6963
7092
  // Lazily access constants.spinner.
6964
7093
  const {
6965
7094
  spinner
6966
7095
  } = constants;
6967
7096
  spinner.start('Deleting scan...');
6968
- const socketSdk = await index.setupSdk(apiToken);
7097
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
6969
7098
  const result = await handleApiCall(socketSdk.deleteOrgFullScan(orgSlug, fullScanId), 'Deleting scan');
6970
7099
  if (!result.success) {
6971
- handleUnsuccessfulApiResponse('deleteOrgFullScan', result, spinner);
7100
+ handleUnsuccessfulApiResponse('deleteOrgFullScan', result);
6972
7101
  return;
6973
7102
  }
6974
7103
  spinner.successAndStop('Scan deleted successfully');
@@ -7016,7 +7145,7 @@ async function run$5(argv, importMeta, {
7016
7145
  // options or missing arguments.
7017
7146
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
7018
7147
  process.exitCode = 2;
7019
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
7148
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
7020
7149
 
7021
7150
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
7022
7151
 
@@ -7027,24 +7156,64 @@ async function run$5(argv, importMeta, {
7027
7156
  logger.logger.log(DRY_RUN_BAIL_TEXT$5);
7028
7157
  return;
7029
7158
  }
7030
- const apiToken = index.getDefaultToken();
7031
- if (!apiToken) {
7032
- throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
7033
- }
7034
- await deleteOrgFullScan(orgSlug, fullScanId, apiToken);
7159
+ await deleteOrgFullScan(orgSlug, fullScanId);
7035
7160
  }
7036
7161
 
7037
7162
  // @ts-ignore
7038
- async function listFullScans(orgSlug, input, apiToken) {
7163
+ async function listFullScans({
7164
+ direction,
7165
+ from_time,
7166
+ orgSlug,
7167
+ outputKind,
7168
+ page,
7169
+ per_page,
7170
+ sort
7171
+ }) {
7172
+ const apiToken = shadowNpmInject.getDefaultToken();
7173
+ if (!apiToken) {
7174
+ throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
7175
+ }
7176
+ await listFullScansWithToken({
7177
+ apiToken,
7178
+ direction,
7179
+ from_time,
7180
+ orgSlug,
7181
+ outputKind,
7182
+ page,
7183
+ per_page,
7184
+ sort
7185
+ });
7186
+ }
7187
+ async function listFullScansWithToken({
7188
+ apiToken,
7189
+ direction,
7190
+ from_time,
7191
+ orgSlug,
7192
+ outputKind,
7193
+ page,
7194
+ per_page,
7195
+ sort
7196
+ }) {
7039
7197
  // Lazily access constants.spinner.
7040
7198
  const {
7041
7199
  spinner
7042
7200
  } = constants;
7043
- spinner.start('Listing scans...');
7044
- const socketSdk = await index.setupSdk(apiToken);
7045
- const result = await handleApiCall(socketSdk.getOrgFullScanList(orgSlug, input), 'Listing scans');
7201
+ spinner.start('Fetching list of scans...');
7202
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
7203
+ const result = await handleApiCall(socketSdk.getOrgFullScanList(orgSlug, {
7204
+ sort,
7205
+ direction,
7206
+ per_page,
7207
+ page,
7208
+ from: from_time
7209
+ }), 'Listing scans');
7046
7210
  if (!result.success) {
7047
- handleUnsuccessfulApiResponse('getOrgFullScanList', result, spinner);
7211
+ handleUnsuccessfulApiResponse('getOrgFullScanList', result);
7212
+ return;
7213
+ }
7214
+ spinner.stop(`Fetch complete`);
7215
+ if (outputKind === 'json') {
7216
+ logger.logger.log(result.data);
7048
7217
  return;
7049
7218
  }
7050
7219
  const options = {
@@ -7074,7 +7243,6 @@ async function listFullScans(orgSlug, input, apiToken) {
7074
7243
  branch: d.branch
7075
7244
  };
7076
7245
  });
7077
- spinner.stop(`Listing scans for: ${orgSlug}`);
7078
7246
  logger.logger.log(chalkTable(options, formattedResults));
7079
7247
  }
7080
7248
 
@@ -7156,7 +7324,7 @@ async function run$4(argv, importMeta, {
7156
7324
  // options or missing arguments.
7157
7325
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
7158
7326
  process.exitCode = 2;
7159
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
7327
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
7160
7328
 
7161
7329
  - Org name as the argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}`);
7162
7330
  return;
@@ -7165,39 +7333,55 @@ async function run$4(argv, importMeta, {
7165
7333
  logger.logger.log(DRY_RUN_BAIL_TEXT$4);
7166
7334
  return;
7167
7335
  }
7168
- const apiToken = index.getDefaultToken();
7169
- if (!apiToken) {
7170
- throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
7171
- }
7172
- await listFullScans(orgSlug,
7173
- // TODO: refine this object to what we need
7174
- {
7175
- outputJson: cli.flags['json'],
7176
- outputMarkdown: cli.flags['markdown'],
7336
+ await listFullScans({
7337
+ direction: String(cli.flags['direction'] || ''),
7338
+ from_time: String(cli.flags['fromTime'] || ''),
7177
7339
  orgSlug,
7178
- sort: cli.flags['sort'],
7179
- direction: cli.flags['direction'],
7180
- per_page: cli.flags['perPage'],
7181
- page: cli.flags['page'],
7182
- from_time: cli.flags['fromTime'],
7183
- until_time: cli.flags['untilTime']
7184
- }, apiToken);
7340
+ outputKind: cli.flags['json'] ? 'json' : cli.flags['markdown'] ? 'markdown' : 'print',
7341
+ page: Number(cli.flags['page'] || 1),
7342
+ per_page: Number(cli.flags['perPage'] || 30),
7343
+ sort: String(cli.flags['sort'] || '')
7344
+ });
7185
7345
  }
7186
7346
 
7187
- async function getOrgScanMetadata(orgSlug, scanId, apiToken) {
7347
+ async function getOrgScanMetadata(orgSlug, scanId, outputKind) {
7348
+ const apiToken = shadowNpmInject.getDefaultToken();
7349
+ if (!apiToken) {
7350
+ throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
7351
+ }
7352
+ await getOrgScanMetadataWithToken(orgSlug, scanId, apiToken, outputKind);
7353
+ }
7354
+ async function getOrgScanMetadataWithToken(orgSlug, scanId, apiToken, outputKind) {
7188
7355
  // Lazily access constants.spinner.
7189
7356
  const {
7190
7357
  spinner
7191
7358
  } = constants;
7192
- spinner.start("Getting scan's metadata...");
7193
- const socketSdk = await index.setupSdk(apiToken);
7359
+ spinner.start('Fetching meta data for a full scan...');
7360
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
7194
7361
  const result = await handleApiCall(socketSdk.getOrgFullScanMetadata(orgSlug, scanId), 'Listing scans');
7195
7362
  if (!result.success) {
7196
- handleUnsuccessfulApiResponse('getOrgFullScanMetadata', result, spinner);
7363
+ handleUnsuccessfulApiResponse('getOrgFullScanMetadata', result);
7197
7364
  return;
7198
7365
  }
7199
- spinner.stop('Scan metadata:');
7200
- logger.logger.log(result.data);
7366
+ spinner?.successAndStop('Fetched the meta data\n');
7367
+ if (outputKind === 'json') {
7368
+ logger.logger.log(result.data);
7369
+ } else {
7370
+ // Markdown = print
7371
+ if (outputKind === 'markdown') {
7372
+ logger.logger.log('# Scan meta data\n');
7373
+ }
7374
+ logger.logger.log(`Scan ID: ${scanId}\n`);
7375
+ for (const [key, value] of Object.entries(result.data)) {
7376
+ if (['id', 'updated_at', 'organization_id', 'repository_id', 'commit_hash', 'html_report_url'].includes(key)) continue;
7377
+ logger.logger.log(`- ${key}:`, value);
7378
+ }
7379
+ if (outputKind === 'markdown') {
7380
+ logger.logger.log(`\nYou can view this report at: [${result.data.html_report_url}](${result.data.html_report_url})\n`);
7381
+ } else {
7382
+ logger.logger.log(`\nYou can view this report at: ${result.data.html_report_url}]\n`);
7383
+ }
7384
+ }
7201
7385
  }
7202
7386
 
7203
7387
  const {
@@ -7242,7 +7426,7 @@ async function run$3(argv, importMeta, {
7242
7426
  // options or missing arguments.
7243
7427
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
7244
7428
  process.exitCode = 2;
7245
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
7429
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
7246
7430
 
7247
7431
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
7248
7432
 
@@ -7253,35 +7437,106 @@ async function run$3(argv, importMeta, {
7253
7437
  logger.logger.log(DRY_RUN_BAIL_TEXT$3);
7254
7438
  return;
7255
7439
  }
7256
- const apiToken = index.getDefaultToken();
7440
+ await getOrgScanMetadata(orgSlug, fullScanId, cli.flags['json'] ? 'json' : cli.flags['markdown'] ? 'markdown' : 'print');
7441
+ }
7442
+
7443
+ async function streamFullScan(orgSlug, fullScanId, file) {
7444
+ // Lazily access constants.spinner.
7445
+ const {
7446
+ spinner
7447
+ } = constants;
7448
+ const apiToken = shadowNpmInject.getDefaultToken();
7257
7449
  if (!apiToken) {
7258
- throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
7450
+ throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
7259
7451
  }
7260
- await getOrgScanMetadata(orgSlug, fullScanId, apiToken);
7452
+ spinner.start('Fetching scan...');
7453
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
7454
+ const data = await handleApiCall(socketSdk.getOrgFullScan(orgSlug, fullScanId, file === '-' ? undefined : file), 'Fetching a scan');
7455
+ if (!data?.success) {
7456
+ handleUnsuccessfulApiResponse('getOrgFullScan', data);
7457
+ return;
7458
+ }
7459
+ spinner?.successAndStop(file ? `Full scan details written to ${file}` : 'stdout');
7460
+ return data;
7261
7461
  }
7262
7462
 
7263
- async function getFullScan(orgSlug, fullScanId, file, apiToken) {
7463
+ async function getFullScan(orgSlug, fullScanId) {
7264
7464
  // Lazily access constants.spinner.
7265
7465
  const {
7266
7466
  spinner
7267
7467
  } = constants;
7268
- spinner.start('Streaming scan...');
7269
- const socketSdk = await index.setupSdk(apiToken);
7270
- const data = await handleApiCall(socketSdk.getOrgFullScan(orgSlug, fullScanId, file === '-' ? undefined : file), 'Streaming a scan');
7271
- if (data?.success) {
7272
- spinner.stop(file ? `Full scan details written to ${file}` : '');
7273
- } else {
7274
- handleUnsuccessfulApiResponse('getOrgFullScan', data, spinner);
7468
+ const apiToken = shadowNpmInject.getDefaultToken();
7469
+ if (!apiToken) {
7470
+ throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
7275
7471
  }
7472
+ spinner.start('Fetching full-scan...');
7473
+ const response = await queryAPI(`orgs/${orgSlug}/full-scans/${encodeURIComponent(fullScanId)}`, apiToken);
7474
+ spinner.stop('Fetch complete.');
7475
+ if (!response.ok) {
7476
+ const err = await handleAPIError(response.status);
7477
+ logger.logger.fail(`${colors.bgRed(colors.white(response.statusText))}: Fetch error: ${err}`);
7478
+ return;
7479
+ }
7480
+
7481
+ // This is nd-json; each line is a json object
7482
+ const jsons = await response.text();
7483
+ const lines = jsons.split('\n').filter(Boolean);
7484
+ const data = lines.map(line => {
7485
+ try {
7486
+ return JSON.parse(line);
7487
+ } catch {
7488
+ console.error('At least one line item was returned that could not be parsed as JSON...');
7489
+ return {};
7490
+ }
7491
+ });
7276
7492
  return data;
7277
7493
  }
7278
7494
 
7495
+ async function viewFullScan(orgSlug, fullScanId, filePath) {
7496
+ const artifacts = await getFullScan(orgSlug, fullScanId);
7497
+ if (!artifacts) return;
7498
+ const display = artifacts.map(art => {
7499
+ const author = Array.isArray(art.author) ? `${art.author[0]}${art.author.length > 1 ? ' et.al.' : ''}` : art.author;
7500
+ return {
7501
+ type: art.type,
7502
+ name: art.name,
7503
+ version: art.version,
7504
+ author,
7505
+ score: JSON.stringify(art.score)
7506
+ };
7507
+ });
7508
+ const md = mdTable(display, ['type', 'version', 'name', 'author', 'score']);
7509
+ const report = `
7510
+ # Scan Details
7511
+
7512
+ These are the artifacts and their scores found.
7513
+
7514
+ Sscan ID: ${fullScanId}
7515
+
7516
+ ${md}
7517
+
7518
+ View this report at: https://socket.dev/dashboard/org/${orgSlug}/sbom/${fullScanId}
7519
+ `.trim() + '\n';
7520
+ if (filePath && filePath !== '-') {
7521
+ try {
7522
+ await fs$1.writeFile(filePath, report, 'utf8');
7523
+ logger.logger.log(`Data successfully written to ${filePath}`);
7524
+ } catch (e) {
7525
+ process.exitCode = 1;
7526
+ logger.logger.fail('There was an error trying to write the json to disk');
7527
+ logger.logger.error(e);
7528
+ }
7529
+ } else {
7530
+ logger.logger.log(report);
7531
+ }
7532
+ }
7533
+
7279
7534
  const {
7280
7535
  DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$2
7281
7536
  } = constants;
7282
7537
  const config$2 = {
7283
- commandName: 'stream',
7284
- description: 'Stream the output of a scan',
7538
+ commandName: 'view',
7539
+ description: 'View the raw results of a scan',
7285
7540
  hidden: false,
7286
7541
  flags: {
7287
7542
  ...commonFlags,
@@ -7300,7 +7555,7 @@ const config$2 = {
7300
7555
  $ ${command} FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 ./stream.txt
7301
7556
  `
7302
7557
  };
7303
- const cmdScanStream = {
7558
+ const cmdScanView = {
7304
7559
  description: config$2.description,
7305
7560
  hidden: config$2.hidden,
7306
7561
  run: run$2
@@ -7320,7 +7575,7 @@ async function run$2(argv, importMeta, {
7320
7575
  // options or missing arguments.
7321
7576
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
7322
7577
  process.exitCode = 2;
7323
- logger.logger.error(commonTags.stripIndents`
7578
+ logger.logger.fail(commonTags.stripIndents`
7324
7579
  ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
7325
7580
 
7326
7581
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
@@ -7333,14 +7588,14 @@ async function run$2(argv, importMeta, {
7333
7588
  logger.logger.log(DRY_RUN_BAIL_TEXT$2);
7334
7589
  return;
7335
7590
  }
7336
- const apiToken = index.getDefaultToken();
7337
- if (!apiToken) {
7338
- throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
7591
+ if (cli.flags['json']) {
7592
+ await streamFullScan(orgSlug, fullScanId, file);
7593
+ } else {
7594
+ await viewFullScan(orgSlug, fullScanId, file);
7339
7595
  }
7340
- await getFullScan(orgSlug, fullScanId, file, apiToken);
7341
7596
  }
7342
7597
 
7343
- const description = 'Scans related commands';
7598
+ const description = 'Full Scan related commands';
7344
7599
  const cmdScan = {
7345
7600
  description,
7346
7601
  async run(argv, importMeta, {
@@ -7348,11 +7603,19 @@ const cmdScan = {
7348
7603
  }) {
7349
7604
  await meowWithSubcommands({
7350
7605
  create: cmdScanCreate,
7351
- stream: cmdScanStream,
7352
7606
  list: cmdScanList,
7353
7607
  del: cmdScanDel,
7354
- metadata: cmdScanMetadata
7608
+ metadata: cmdScanMetadata,
7609
+ view: cmdScanView
7355
7610
  }, {
7611
+ aliases: {
7612
+ // Backwards compat. TODO: Drop next major bump
7613
+ stream: {
7614
+ description: cmdScanView.description,
7615
+ hidden: true,
7616
+ argv: ['view'] // Original args will be appended (!)
7617
+ }
7618
+ },
7356
7619
  argv,
7357
7620
  description,
7358
7621
  importMeta,
@@ -7504,9 +7767,9 @@ async function run$1(argv, importMeta, {
7504
7767
  logger.logger.log(DRY_RUN_BAIL_TEXT$1);
7505
7768
  return;
7506
7769
  }
7507
- const apiToken = index.getDefaultToken();
7770
+ const apiToken = shadowNpmInject.getDefaultToken();
7508
7771
  if (!apiToken) {
7509
- throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
7772
+ throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
7510
7773
  }
7511
7774
  await getThreatFeed({
7512
7775
  apiToken,
@@ -7601,7 +7864,7 @@ function askQuestion(rl, query) {
7601
7864
  function removeSocketWrapper(file) {
7602
7865
  return fs.readFile(file, 'utf8', function (err, data) {
7603
7866
  if (err) {
7604
- logger.logger.error('There was an error removing the alias:');
7867
+ logger.logger.fail('There was an error removing the alias:');
7605
7868
  logger.logger.error(err);
7606
7869
  return;
7607
7870
  }
@@ -7678,7 +7941,7 @@ async function run(argv, importMeta, {
7678
7941
  // options or missing arguments.
7679
7942
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
7680
7943
  process.exitCode = 2;
7681
- logger.logger.error(commonTags.stripIndents`
7944
+ logger.logger.fail(commonTags.stripIndents`
7682
7945
  ${colors.bgRed(colors.white('Input error'))}: Please provide the required flags:
7683
7946
 
7684
7947
  - Must use --enabled or --disabled
@@ -7711,7 +7974,7 @@ async function run(argv, importMeta, {
7711
7974
  }
7712
7975
  }
7713
7976
  if (!fs.existsSync(bashRcPath) && !fs.existsSync(zshRcPath)) {
7714
- logger.logger.error('There was an issue setting up the alias in your bash profile');
7977
+ logger.logger.fail('There was an issue setting up the alias in your bash profile');
7715
7978
  }
7716
7979
  }
7717
7980
 
@@ -7770,10 +8033,10 @@ void (async () => {
7770
8033
  let errorBody;
7771
8034
  let errorTitle;
7772
8035
  let errorMessage = '';
7773
- if (e instanceof index.AuthError) {
8036
+ if (e instanceof shadowNpmInject.AuthError) {
7774
8037
  errorTitle = 'Authentication error';
7775
8038
  errorMessage = e.message;
7776
- } else if (e instanceof index.InputError) {
8039
+ } else if (e instanceof shadowNpmInject.InputError) {
7777
8040
  errorTitle = 'Invalid input';
7778
8041
  errorMessage = e.message;
7779
8042
  errorBody = e.body;
@@ -7784,12 +8047,12 @@ void (async () => {
7784
8047
  } else {
7785
8048
  errorTitle = 'Unexpected error with no details';
7786
8049
  }
7787
- logger.logger.error(`${colors.bgRed(colors.white(errorTitle + ':'))} ${errorMessage}`);
8050
+ logger.logger.fail(`${colors.bgRed(colors.white(errorTitle + ':'))} ${errorMessage}`);
7788
8051
  if (errorBody) {
7789
8052
  logger.logger.error(`\n${errorBody}`);
7790
8053
  }
7791
- await index.captureException(e);
8054
+ await shadowNpmInject.captureException(e);
7792
8055
  }
7793
8056
  })();
7794
- //# debugId=e6a98767-74ff-4fd4-a15e-82ce65af55f8
8057
+ //# debugId=6f2331ca-147d-40b1-aa4e-e5b6a5c2eba0
7795
8058
  //# sourceMappingURL=cli.js.map