@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
@@ -23,7 +23,7 @@ var events = require('node:events');
23
23
  var fs = require('node:fs');
24
24
  var path = require('node:path');
25
25
  var ndjson = _socketInterop(require('ndjson'));
26
- var index = require('./index.js');
26
+ var shadowNpmInject = require('./shadow-npm-inject.js');
27
27
  var constants = require('./constants.js');
28
28
  var objects = require('@socketsecurity/registry/lib/objects');
29
29
  var regexps = require('@socketsecurity/registry/lib/regexps');
@@ -34,10 +34,11 @@ var contrib = _socketInterop(require('blessed-contrib'));
34
34
  var prompts = require('@socketsecurity/registry/lib/prompts');
35
35
  var yargsParse = _socketInterop(require('yargs-parser'));
36
36
  var words = require('@socketsecurity/registry/lib/words');
37
- var npm = require('@socketsecurity/registry/lib/npm');
37
+ var shadowBin = require('./shadow-bin.js');
38
38
  var chalkTable = _socketInterop(require('chalk-table'));
39
39
  var require$$0$1 = require('node:util');
40
40
  var registry = require('@socketsecurity/registry');
41
+ var npm = require('@socketsecurity/registry/lib/npm');
41
42
  var packages = require('@socketsecurity/registry/lib/packages');
42
43
  var registryConstants = require('@socketsecurity/registry/lib/constants');
43
44
  var isInteractive = require('@socketregistry/is-interactive/index.cjs');
@@ -54,7 +55,7 @@ var sorts = require('@socketsecurity/registry/lib/sorts');
54
55
  var strings = require('@socketsecurity/registry/lib/strings');
55
56
  var yaml = _socketInterop(require('yaml'));
56
57
  var debug = require('@socketsecurity/registry/lib/debug');
57
- var npmPaths = require('./npm-paths.js');
58
+ var shadowNpmPaths = require('./shadow-npm-paths.js');
58
59
  var betterAjvErrors = _socketInterop(require('@apideck/better-ajv-errors'));
59
60
  var config$A = require('@socketsecurity/config');
60
61
  var assert = require('node:assert');
@@ -836,7 +837,7 @@ function getIgnoreOptions({
836
837
  ignoreCommands.push(data);
837
838
  }
838
839
  } catch (e) {
839
- logger.logger.error(`Unable to process ignore command for ${comment}`);
840
+ logger.logger.fail(`Unable to process ignore command for ${comment}`);
840
841
  logger.logger.error(e);
841
842
  }
842
843
  }
@@ -1222,7 +1223,7 @@ function securityCommentTemplate(diff) {
1222
1223
  // TODO: is this a github action handler?
1223
1224
  async function runAction(githubEventBefore, githubEventAfter) {
1224
1225
  //TODO
1225
- const socket = new sdk.SocketSdk(index.getDefaultToken());
1226
+ const socket = new sdk.SocketSdk(shadowNpmInject.getDefaultToken());
1226
1227
  const git = simpleGit.simpleGit();
1227
1228
  const changedFiles = (await git.diff(process.env['GITHUB_EVENT_NAME'] === 'pull_request' ? ['--name-only', 'HEAD^1', 'HEAD'] : ['--name-only', githubEventBefore, githubEventAfter])).split('\n');
1228
1229
  logger.logger.log({
@@ -1287,15 +1288,14 @@ async function runAction(githubEventBefore, githubEventAfter) {
1287
1288
  const {
1288
1289
  API_V0_URL
1289
1290
  } = constants;
1290
- function handleUnsuccessfulApiResponse(_name, result, spinner) {
1291
+ function handleUnsuccessfulApiResponse(_name, result) {
1291
1292
  // SocketSdkErrorType['error'] is not typed.
1292
1293
  const resultErrorMessage = result.error?.message;
1293
1294
  const message = typeof resultErrorMessage === 'string' ? resultErrorMessage : 'No error message returned';
1294
1295
  if (result.status === 401 || result.status === 403) {
1295
- spinner.stop();
1296
- throw new index.AuthError(message);
1296
+ throw new shadowNpmInject.AuthError(message);
1297
1297
  }
1298
- spinner.errorAndStop(`${colors.bgRed(colors.white('API returned an error:'))} ${message}`);
1298
+ logger.logger.fail(`${colors.bgRed(colors.white('API returned an error:'))} ${message}`);
1299
1299
  process$1.exit(1);
1300
1300
  }
1301
1301
  async function handleApiCall(value, description) {
@@ -1474,8 +1474,8 @@ async function meowWithSubcommands(subcommands, options) {
1474
1474
  autoHelp: false // otherwise we can't exit(0)
1475
1475
  });
1476
1476
  if (!cli.flags['help'] && cli.flags['dryRun']) {
1477
- logger.logger.log(`${DRY_RUN_LABEL$1}: No-op, call a sub-command; ok`);
1478
1477
  process.exitCode = 0;
1478
+ logger.logger.log(`${DRY_RUN_LABEL$1}: No-op, call a sub-command; ok`);
1479
1479
  } else {
1480
1480
  cli.showHelp();
1481
1481
  }
@@ -1516,9 +1516,9 @@ function meowOrExit({
1516
1516
  }
1517
1517
  function getAsciiHeader(command) {
1518
1518
  const cliVersion = // The '@rollup/plugin-replace' will replace "process.env['SOCKET_CLI_VERSION_HASH']".
1519
- "0.14.55:51de259:b691b88f:pub";
1519
+ "0.14.57:6783de7:236c7308:pub";
1520
1520
  const nodeVersion = process.version;
1521
- const apiToken = index.getSetting('apiToken');
1521
+ const apiToken = shadowNpmInject.getSetting('apiToken');
1522
1522
  const shownToken = apiToken ? getLastFiveOfApiToken(apiToken) : 'no';
1523
1523
  const relCwd = process.cwd().replace(new RegExp(`^${regexps.escapeRegExp(constants.homePath)}`, 'i'), '~/');
1524
1524
  const body = `
@@ -1591,10 +1591,10 @@ async function run$z(argv, importMeta, {
1591
1591
  }
1592
1592
 
1593
1593
  async function fetchOrgAnalyticsData(time, spinner, apiToken) {
1594
- const socketSdk = await index.setupSdk(apiToken);
1594
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
1595
1595
  const result = await handleApiCall(socketSdk.getOrgAnalytics(time.toString()), 'fetching analytics data');
1596
1596
  if (result.success === false) {
1597
- handleUnsuccessfulApiResponse('getOrgAnalytics', result, spinner);
1597
+ handleUnsuccessfulApiResponse('getOrgAnalytics', result);
1598
1598
  return undefined;
1599
1599
  }
1600
1600
  spinner.stop();
@@ -1606,10 +1606,10 @@ async function fetchOrgAnalyticsData(time, spinner, apiToken) {
1606
1606
  }
1607
1607
 
1608
1608
  async function fetchRepoAnalyticsData(repo, time, spinner, apiToken) {
1609
- const socketSdk = await index.setupSdk(apiToken);
1609
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
1610
1610
  const result = await handleApiCall(socketSdk.getRepoAnalytics(repo, time.toString()), 'fetching analytics data');
1611
1611
  if (result.success === false) {
1612
- handleUnsuccessfulApiResponse('getRepoAnalytics', result, spinner);
1612
+ handleUnsuccessfulApiResponse('getRepoAnalytics', result);
1613
1613
  return undefined;
1614
1614
  }
1615
1615
  spinner.stop();
@@ -1640,6 +1640,35 @@ function mdTableStringNumber(title1, title2, obj) {
1640
1640
  lines.push(`| ${'-'.repeat(mw1)} | ${'-'.repeat(mw2)} |`);
1641
1641
  return lines.join('\n');
1642
1642
  }
1643
+ function mdTable(logs,
1644
+ // This is saying "an array of strings and the strings are a valid key of elements of T"
1645
+ // In turn, T is defined above as the audit log event type from our OpenAPI docs.
1646
+ cols) {
1647
+ // Max col width required to fit all data in that column
1648
+ const cws = cols.map(col => col.length);
1649
+ for (const log of logs) {
1650
+ for (let i = 0; i < cols.length; ++i) {
1651
+ // @ts-ignore
1652
+ const val = log[cols[i] ?? ''] ?? '';
1653
+ cws[i] = Math.max(cws[i] ?? 0, String(val).length);
1654
+ }
1655
+ }
1656
+ let div = '|';
1657
+ for (const cw of cws) div += ' ' + '-'.repeat(cw) + ' |';
1658
+ let header = '|';
1659
+ for (let i = 0; i < cols.length; ++i) header += ' ' + String(cols[i]).padEnd(cws[i] ?? 0, ' ') + ' |';
1660
+ let body = '';
1661
+ for (const log of logs) {
1662
+ body += '|';
1663
+ for (let i = 0; i < cols.length; ++i) {
1664
+ // @ts-ignore
1665
+ const val = log[cols[i] ?? ''] ?? '';
1666
+ body += ' ' + String(val).padEnd(cws[i] ?? 0, ' ') + ' |';
1667
+ }
1668
+ body += '\n';
1669
+ }
1670
+ return [div, header, div, body.trim(), div].filter(s => !!s.trim()).join('\n');
1671
+ }
1643
1672
 
1644
1673
  // Note: Widgets does not seem to actually work as code :'(
1645
1674
 
@@ -1654,9 +1683,9 @@ async function displayAnalytics({
1654
1683
  scope,
1655
1684
  time
1656
1685
  }) {
1657
- const apiToken = index.getDefaultToken();
1686
+ const apiToken = shadowNpmInject.getDefaultToken();
1658
1687
  if (!apiToken) {
1659
- 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.');
1688
+ 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.');
1660
1689
  }
1661
1690
  await outputAnalyticsWithToken({
1662
1691
  apiToken,
@@ -1697,9 +1726,9 @@ async function outputAnalyticsWithToken({
1697
1726
  await fs$1.writeFile(filePath, serialized, 'utf8');
1698
1727
  logger.logger.log(`Data successfully written to ${filePath}`);
1699
1728
  } catch (e) {
1700
- logger.logger.error('There was an error trying to write the json to disk');
1701
- logger.logger.error(e);
1702
1729
  process.exitCode = 1;
1730
+ logger.logger.fail('There was an error trying to write the json to disk');
1731
+ logger.logger.error(e);
1703
1732
  }
1704
1733
  } else {
1705
1734
  logger.logger.log(serialized);
@@ -1727,9 +1756,9 @@ function renderJson(data) {
1727
1756
  try {
1728
1757
  return JSON.stringify(data, null, 2);
1729
1758
  } catch (e) {
1730
- // This could be caused by circular references, which is an "us" problem
1731
- logger.logger.error('There was a problem converting the data set to JSON. Please try without --json or with --markdown');
1732
1759
  process.exitCode = 1;
1760
+ // This could be caused by circular references, which is an "us" problem
1761
+ logger.logger.fail('There was a problem converting the data set to JSON. Please try without --json or with --markdown');
1733
1762
  return;
1734
1763
  }
1735
1764
  }
@@ -1964,7 +1993,7 @@ async function run$y(argv, importMeta, {
1964
1993
  // options or missing arguments.
1965
1994
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
1966
1995
  process.exitCode = 2;
1967
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
1996
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
1968
1997
 
1969
1998
  - Scope must be "repo" or "org" ${badScope ? colors.red('(bad!)') : colors.green('(ok)')}
1970
1999
 
@@ -1998,9 +2027,9 @@ async function getAuditLog({
1998
2027
  page,
1999
2028
  perPage
2000
2029
  }) {
2001
- const apiToken = index.getDefaultToken();
2030
+ const apiToken = shadowNpmInject.getDefaultToken();
2002
2031
  if (!apiToken) {
2003
- 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.');
2032
+ 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.');
2004
2033
  }
2005
2034
  const auditLogs = await getAuditLogWithToken({
2006
2035
  apiToken,
@@ -2044,8 +2073,8 @@ async function outputAsJson(auditLogs, orgSlug, logType, page, perPage) {
2044
2073
  })
2045
2074
  }, null, 2);
2046
2075
  } catch (e) {
2047
- logger.logger.error('There was a problem converting the logs to JSON, please try without the `--json` flag');
2048
2076
  process.exitCode = 1;
2077
+ logger.logger.fail('There was a problem converting the logs to JSON, please try without the `--json` flag');
2049
2078
  return;
2050
2079
  }
2051
2080
  logger.logger.log(json);
@@ -2066,41 +2095,12 @@ These are the Socket.dev audit logs as per requested query.
2066
2095
  ${table}
2067
2096
  `);
2068
2097
  } catch (e) {
2069
- logger.logger.error('There was a problem converting the logs to JSON, please try without the `--json` flag');
2070
- logger.logger.error(e);
2071
2098
  process.exitCode = 1;
2099
+ logger.logger.fail('There was a problem converting the logs to JSON, please try without the `--json` flag');
2100
+ logger.logger.error(e);
2072
2101
  return;
2073
2102
  }
2074
2103
  }
2075
- function mdTable(logs,
2076
- // This is saying "an array of strings and the strings are a valid key of elements of T"
2077
- // In turn, T is defined above as the audit log event type from our OpenAPI docs.
2078
- cols) {
2079
- // Max col width required to fit all data in that column
2080
- const cws = cols.map(col => col.length);
2081
- for (const log of logs) {
2082
- for (let i = 0; i < cols.length; ++i) {
2083
- // @ts-ignore
2084
- const val = log[cols[i] ?? ''] ?? '';
2085
- cws[i] = Math.max(cws[i] ?? 0, String(val).length);
2086
- }
2087
- }
2088
- let div = '|';
2089
- for (const cw of cws) div += ' ' + '-'.repeat(cw) + ' |';
2090
- let header = '|';
2091
- for (let i = 0; i < cols.length; ++i) header += ' ' + String(cols[i]).padEnd(cws[i] ?? 0, ' ') + ' |';
2092
- let body = '';
2093
- for (const log of logs) {
2094
- body += '|';
2095
- for (let i = 0; i < cols.length; ++i) {
2096
- // @ts-ignore
2097
- const val = log[cols[i] ?? ''] ?? '';
2098
- body += ' ' + String(val).padEnd(cws[i] ?? 0, ' ') + ' |';
2099
- }
2100
- body += '\n';
2101
- }
2102
- return [div, header, div, body.trim(), div].filter(s => !!s.trim()).join('\n');
2103
- }
2104
2104
  async function outputAsPrint(auditLogs, orgSlug, logType) {
2105
2105
  const data = [];
2106
2106
  const logDetails = {};
@@ -2139,7 +2139,7 @@ async function getAuditLogWithToken({
2139
2139
  spinner
2140
2140
  } = constants;
2141
2141
  spinner.start(`Looking up audit log for ${orgSlug}`);
2142
- const socketSdk = await index.setupSdk(apiToken);
2142
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
2143
2143
  const result = await handleApiCall(socketSdk.getAuditLogEvents(orgSlug, {
2144
2144
  outputJson: outputKind === 'json',
2145
2145
  // I'm not sure this is used at all
@@ -2151,7 +2151,7 @@ async function getAuditLogWithToken({
2151
2151
  per_page: perPage
2152
2152
  }), `Looking up audit log for ${orgSlug}\n`);
2153
2153
  if (!result.success) {
2154
- handleUnsuccessfulApiResponse('getAuditLogEvents', result, spinner);
2154
+ handleUnsuccessfulApiResponse('getAuditLogEvents', result);
2155
2155
  return;
2156
2156
  }
2157
2157
  spinner.stop();
@@ -2226,7 +2226,7 @@ async function run$x(argv, importMeta, {
2226
2226
  // options or missing arguments.
2227
2227
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
2228
2228
  process.exitCode = 2;
2229
- logger.logger.error(commonTags.stripIndents`
2229
+ logger.logger.fail(commonTags.stripIndents`
2230
2230
  ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
2231
2231
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
2232
2232
  `);
@@ -2245,18 +2245,10 @@ async function run$x(argv, importMeta, {
2245
2245
  });
2246
2246
  }
2247
2247
 
2248
- const {
2249
- SBOM_SIGN_ALGORITHM,
2250
- // Algorithm. Example: RS512
2251
- SBOM_SIGN_PRIVATE_KEY,
2252
- // Location to the RSA private key
2253
- SBOM_SIGN_PUBLIC_KEY // Optional. Location to the RSA public key
2254
- } = process$1.env;
2255
2248
  const {
2256
2249
  NPM: NPM$e,
2257
- PNPM: PNPM$8,
2258
- cdxgenBinPath,
2259
- synpBinPath
2250
+ NPX: NPX$3,
2251
+ PNPM: PNPM$8
2260
2252
  } = constants;
2261
2253
  const nodejsPlatformTypes = new Set(['javascript', 'js', 'nodejs', NPM$e, PNPM$8, 'ts', 'tsx', 'typescript']);
2262
2254
  async function runCycloneDX(yargv) {
@@ -2268,21 +2260,13 @@ async function runCycloneDX(yargv) {
2268
2260
  // Use synp to create a package-lock.json from the yarn.lock,
2269
2261
  // based on the node_modules folder, for a more accurate SBOM.
2270
2262
  try {
2271
- await npm.runBin(await fs.promises.realpath(synpBinPath), ['--source-file', './yarn.lock']);
2263
+ await shadowBin(NPX$3, ['synp@1.9.14', '--', '--source-file', './yarn.lock'], 2);
2272
2264
  yargv.type = NPM$e;
2273
2265
  cleanupPackageLock = true;
2274
2266
  } catch {}
2275
2267
  }
2276
2268
  }
2277
- await npm.runBin(await fs.promises.realpath(cdxgenBinPath), argvToArray(yargv), {
2278
- env: {
2279
- NODE_ENV: '',
2280
- SBOM_SIGN_ALGORITHM,
2281
- SBOM_SIGN_PRIVATE_KEY,
2282
- SBOM_SIGN_PUBLIC_KEY
2283
- },
2284
- stdio: 'inherit'
2285
- });
2269
+ await shadowBin(NPX$3, ['@cyclonedx/cdxgen@11.2.0', '--', ...argvToArray(yargv)], 2);
2286
2270
  if (cleanupPackageLock) {
2287
2271
  try {
2288
2272
  await fs.promises.rm('./package-lock.json');
@@ -2428,7 +2412,7 @@ async function run$w(argv, importMeta, {
2428
2412
  //
2429
2413
  //
2430
2414
  // if (cli.input.length)
2431
- // logger.error(
2415
+ // logger.fail(
2432
2416
  // stripIndents`
2433
2417
  // ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
2434
2418
  //
@@ -2452,7 +2436,7 @@ async function run$w(argv, importMeta, {
2452
2436
  // options or missing arguments.
2453
2437
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
2454
2438
  process$1.exitCode = 2;
2455
- logger.logger.error(`Unknown ${words.pluralize('argument', unknownLength)}: ${yargv._.join(', ')}`);
2439
+ logger.logger.fail(`Unknown ${words.pluralize('argument', unknownLength)}: ${yargv._.join(', ')}`);
2456
2440
  return;
2457
2441
  }
2458
2442
  if (yargv.output === undefined) {
@@ -2471,22 +2455,22 @@ async function findDependencies({
2471
2455
  offset,
2472
2456
  outputJson
2473
2457
  }) {
2474
- const apiToken = index.getDefaultToken();
2458
+ const apiToken = shadowNpmInject.getDefaultToken();
2475
2459
  if (!apiToken) {
2476
- 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.');
2460
+ 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.');
2477
2461
  }
2478
2462
  // Lazily access constants.spinner.
2479
2463
  const {
2480
2464
  spinner
2481
2465
  } = constants;
2482
2466
  spinner.start('Searching dependencies...');
2483
- const socketSdk = await index.setupSdk(apiToken);
2467
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
2484
2468
  const result = await handleApiCall(socketSdk.searchDependencies({
2485
2469
  limit,
2486
2470
  offset
2487
2471
  }), 'Searching dependencies');
2488
2472
  if (!result.success) {
2489
- handleUnsuccessfulApiResponse('searchDependencies', result, spinner);
2473
+ handleUnsuccessfulApiResponse('searchDependencies', result);
2490
2474
  return;
2491
2475
  }
2492
2476
  spinner.stop('Organization dependencies:');
@@ -2494,6 +2478,7 @@ async function findDependencies({
2494
2478
  logger.logger.log(result.data);
2495
2479
  return;
2496
2480
  }
2481
+ logger.logger.log('Request details: Offset:', offset, ', limit:', limit, ', is there more data after this?', result.data.end ? 'no' : 'yes');
2497
2482
  const options = {
2498
2483
  columns: [{
2499
2484
  field: 'namespace',
@@ -2585,43 +2570,96 @@ async function run$v(argv, importMeta, {
2585
2570
  async function getDiffScan({
2586
2571
  after,
2587
2572
  before,
2573
+ depth,
2588
2574
  file,
2589
2575
  orgSlug,
2590
2576
  outputJson
2591
- }, apiToken) {
2577
+ }) {
2578
+ const apiToken = shadowNpmInject.getDefaultToken();
2579
+ if (!apiToken) {
2580
+ 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.');
2581
+ }
2582
+ await getDiffScanWithToken({
2583
+ after,
2584
+ before,
2585
+ depth,
2586
+ file,
2587
+ orgSlug,
2588
+ outputJson,
2589
+ apiToken
2590
+ });
2591
+ }
2592
+ async function getDiffScanWithToken({
2593
+ after,
2594
+ apiToken,
2595
+ before,
2596
+ depth,
2597
+ file,
2598
+ orgSlug,
2599
+ outputJson
2600
+ }) {
2592
2601
  // Lazily access constants.spinner.
2593
2602
  const {
2594
2603
  spinner
2595
2604
  } = constants;
2596
2605
  spinner.start('Getting diff scan...');
2597
- const response = await queryAPI(`${orgSlug}/full-scans/diff?before=${before}&after=${after}&preview`, apiToken);
2598
- const data = await response.json();
2606
+ const response = await queryAPI(`orgs/${orgSlug}/full-scans/diff?before=${encodeURIComponent(before)}&after=${encodeURIComponent(after)}`, apiToken);
2599
2607
  if (!response.ok) {
2600
2608
  const err = await handleAPIError(response.status);
2601
2609
  spinner.errorAndStop(`${colors.bgRed(colors.white(response.statusText))}: ${err}`);
2602
2610
  return;
2603
2611
  }
2612
+ const result = await handleApiCall(await response.json(), 'Deserializing json');
2604
2613
  spinner.stop();
2605
- if (file && !outputJson) {
2606
- fs.writeFile(file, JSON.stringify(data), err => {
2607
- err ? logger.logger.error(err) : logger.logger.log(`Data successfully written to ${file}`);
2608
- });
2609
- return;
2610
- }
2611
- if (outputJson) {
2612
- logger.logger.log(`\n Diff scan result: \n`);
2613
- logger.logger.log(require$$0$1.inspect(data, {
2614
- showHidden: false,
2615
- depth: null,
2616
- colors: true
2617
- }));
2618
- logger.logger.log(`\n View this diff scan in the Socket dashboard: ${colors.cyan(data?.['diff_report_url'])}`);
2614
+ const dashboardUrl = result?.['diff_report_url'];
2615
+ const dashboardMessage = dashboardUrl ? `\n View this diff scan in the Socket dashboard: ${colors.cyan(dashboardUrl)}` : '';
2616
+
2617
+ // When forcing json, or dumping to file, serialize to string such that it
2618
+ // won't get truncated. The only way to dump the full raw JSON to stdout is
2619
+ // to use `--json --file -` (the dash is a standard notation for stdout)
2620
+ if (outputJson || file) {
2621
+ let json;
2622
+ try {
2623
+ json = JSON.stringify(result, null, 2);
2624
+ } catch (e) {
2625
+ process.exitCode = 1;
2626
+ // Most likely caused by a circular reference (or OOM)
2627
+ logger.logger.fail('There was a problem converting the data to JSON');
2628
+ logger.logger.error(e);
2629
+ return;
2630
+ }
2631
+ if (file && file !== '-') {
2632
+ logger.logger.log(`Writing json to \`${file}\``);
2633
+ fs.writeFile(file, JSON.stringify(result, null, 2), err => {
2634
+ if (err) {
2635
+ logger.logger.fail(`Writing to \`${file}\` failed...`);
2636
+ logger.logger.error(err);
2637
+ } else {
2638
+ logger.logger.log(`Data successfully written to \`${file}\``);
2639
+ }
2640
+ logger.logger.error(dashboardMessage);
2641
+ });
2642
+ } else {
2643
+ // TODO: expose different method for writing to stderr when simply dodging stdout
2644
+ logger.logger.error(`\n Diff scan result: \n`);
2645
+ logger.logger.log(json);
2646
+ logger.logger.error(dashboardMessage);
2647
+ }
2619
2648
  return;
2620
2649
  }
2650
+
2651
+ // In this case neither the --json nor the --file flag was passed
2652
+ // Dump the JSON to CLI and let NodeJS deal with truncation
2653
+
2621
2654
  logger.logger.log('Diff scan result:');
2622
- logger.logger.log(data);
2655
+ logger.logger.log(require$$0$1.inspect(result, {
2656
+ showHidden: false,
2657
+ depth: depth > 0 ? depth : null,
2658
+ colors: true,
2659
+ maxArrayLength: null
2660
+ }));
2623
2661
  logger.logger.log(`\n 📝 To display the detailed report in the terminal, use the --json flag \n`);
2624
- logger.logger.log(`\n View this diff scan in the Socket dashboard: ${colors.cyan(data?.['diff_report_url'])}`);
2662
+ logger.logger.log(dashboardMessage);
2625
2663
  }
2626
2664
 
2627
2665
  const {
@@ -2633,36 +2671,44 @@ const config$u = {
2633
2671
  hidden: false,
2634
2672
  flags: {
2635
2673
  ...commonFlags,
2674
+ after: {
2675
+ type: 'string',
2676
+ shortFlag: 'a',
2677
+ default: '',
2678
+ description: 'The full scan ID of the head scan'
2679
+ },
2636
2680
  before: {
2637
2681
  type: 'string',
2638
2682
  shortFlag: 'b',
2639
2683
  default: '',
2640
2684
  description: 'The full scan ID of the base scan'
2641
2685
  },
2642
- after: {
2643
- type: 'string',
2644
- shortFlag: 'a',
2645
- default: '',
2646
- description: 'The full scan ID of the head scan'
2686
+ depth: {
2687
+ type: 'number',
2688
+ default: 2,
2689
+ description: 'Max depth of JSON to display before truncating, use zero for no limit (without --json/--file)'
2647
2690
  },
2648
- preview: {
2691
+ json: {
2649
2692
  type: 'boolean',
2650
- shortFlag: 'p',
2651
- default: true,
2652
- description: 'A boolean flag to persist or not the diff scan result'
2693
+ shortFlag: 'j',
2694
+ default: false,
2695
+ description: 'Output result as json. This can be big. Use --file to store it to disk without truncation.'
2653
2696
  },
2654
2697
  file: {
2655
2698
  type: 'string',
2656
2699
  shortFlag: 'f',
2657
2700
  default: '',
2658
- description: 'Path to a local file where the output should be saved'
2659
- },
2660
- ...outputFlags
2701
+ description: 'Path to a local file where the output should be saved. Use `-` to force stdout.'
2702
+ }
2661
2703
  },
2662
2704
  help: (command, config) => `
2663
2705
  Usage
2664
2706
  $ ${command} <org slug> --before=<before> --after=<after>
2665
2707
 
2708
+ This command displays the package changes between two scans. The full output
2709
+ can be pretty large depending on the size of your repo and time range. It is
2710
+ best stored to disk to be further analyzed by other tools.
2711
+
2666
2712
  Options
2667
2713
  ${getFlagListOutput(config.flags, 6)}
2668
2714
 
@@ -2692,9 +2738,10 @@ async function run$u(argv, importMeta, {
2692
2738
  // options or missing arguments.
2693
2739
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
2694
2740
  process.exitCode = 2;
2695
- logger.logger.error(`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
2741
+ logger.logger.fail(`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
2696
2742
  - 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
2697
2743
  - To get full scans IDs, you can run the command "socket scan list <your org slug>".
2744
+ The args are expecting a full \`aaa0aa0a-aaaa-0000-0a0a-0000000a00a0\` ID.\n
2698
2745
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}\n`);
2699
2746
  return;
2700
2747
  }
@@ -2702,24 +2749,24 @@ async function run$u(argv, importMeta, {
2702
2749
  logger.logger.log(DRY_RUN_BAIL_TEXT$t);
2703
2750
  return;
2704
2751
  }
2705
- const apiToken = index.getDefaultToken();
2706
- if (!apiToken) {
2707
- 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.');
2708
- }
2709
2752
  await getDiffScan({
2710
2753
  outputJson: Boolean(cli.flags['json']),
2711
- outputMarkdown: Boolean(cli.flags['markdown']),
2712
2754
  before,
2713
2755
  after,
2714
- preview: Boolean(cli.flags['preview']),
2756
+ depth: Number(cli.flags['depth']),
2715
2757
  orgSlug,
2716
2758
  file: String(cli.flags['file'] || '')
2717
- }, apiToken);
2759
+ });
2718
2760
  }
2719
2761
 
2720
2762
  const description$3 = 'Diff scans related commands';
2721
2763
  const cmdDiffScan = {
2722
2764
  description: description$3,
2765
+ // Hidden because it was broken all this time (nobody could be using it)
2766
+ // and we're not sure if it's useful to anyone in its current state.
2767
+ // Until we do, we'll hide this to keep the help tidier.
2768
+ // And later, we may simply move this under `scan`, anyways.
2769
+ hidden: true,
2723
2770
  async run(argv, importMeta, {
2724
2771
  parentName
2725
2772
  }) {
@@ -2754,17 +2801,17 @@ async function runFix() {
2754
2801
  });
2755
2802
  // const agentDetails = await detect()
2756
2803
 
2757
- const arb = new index.SafeArborist({
2804
+ const arb = new shadowNpmInject.SafeArborist({
2758
2805
  path: cwd,
2759
- ...index.SAFE_ARBORIST_REIFY_OPTIONS_OVERRIDES
2806
+ ...shadowNpmInject.SAFE_ARBORIST_REIFY_OPTIONS_OVERRIDES
2760
2807
  });
2761
2808
  await arb.reify();
2762
- const alerts = await index.getPackagesAlerts(arb, {
2809
+ const alerts = await shadowNpmInject.getPackagesAlerts(arb, {
2763
2810
  consolidate: true,
2764
2811
  includeExisting: true,
2765
2812
  includeUnfixable: false
2766
2813
  });
2767
- const infoByPkg = index.getCveInfoByPackage(alerts);
2814
+ const infoByPkg = shadowNpmInject.getCveInfoByPackage(alerts);
2768
2815
  await arb.buildIdealTree();
2769
2816
  if (infoByPkg) {
2770
2817
  for (const {
@@ -2781,7 +2828,7 @@ async function runFix() {
2781
2828
  spinner.info(`Skipping ${name}. Socket Optimize package exists.`);
2782
2829
  continue;
2783
2830
  }
2784
- const nodes = index.findPackageNodes(tree, name);
2831
+ const nodes = shadowNpmInject.findPackageNodes(tree, name);
2785
2832
  const packument = nodes.length && infos.length ?
2786
2833
  // eslint-disable-next-line no-await-in-loop
2787
2834
  await packages.fetchPackagePackument(name) : null;
@@ -2800,7 +2847,7 @@ async function runFix() {
2800
2847
  const {
2801
2848
  version: oldVersion
2802
2849
  } = node;
2803
- if (index.updateNode(node, packument, vulnerableVersionRange)) {
2850
+ if (shadowNpmInject.updateNode(node, packument, vulnerableVersionRange)) {
2804
2851
  try {
2805
2852
  // eslint-disable-next-line no-await-in-loop
2806
2853
  await npm.runScript('test', [], {
@@ -2831,7 +2878,7 @@ async function runFix() {
2831
2878
  }
2832
2879
  }
2833
2880
  }
2834
- const arb2 = new index.Arborist({
2881
+ const arb2 = new shadowNpmInject.Arborist({
2835
2882
  path: cwd
2836
2883
  });
2837
2884
  arb2.idealTree = arb.idealTree;
@@ -2951,15 +2998,15 @@ function getSeverityCount(issues, lowestToInclude) {
2951
2998
  return severityCount;
2952
2999
  }
2953
3000
 
2954
- async function fetchPackageInfo(pkgName, pkgVersion, includeAllIssues, spinner) {
2955
- const socketSdk = await index.setupSdk(index.getPublicToken());
3001
+ async function fetchPackageInfo(pkgName, pkgVersion, includeAllIssues) {
3002
+ const socketSdk = await shadowNpmInject.setupSdk(shadowNpmInject.getPublicToken());
2956
3003
  const result = await handleApiCall(socketSdk.getIssuesByNPMPackage(pkgName, pkgVersion), 'looking up package');
2957
3004
  const scoreResult = await handleApiCall(socketSdk.getScoreByNPMPackage(pkgName, pkgVersion), 'looking up package score');
2958
3005
  if (result.success === false) {
2959
- return handleUnsuccessfulApiResponse('getIssuesByNPMPackage', result, spinner);
3006
+ return handleUnsuccessfulApiResponse('getIssuesByNPMPackage', result);
2960
3007
  }
2961
3008
  if (scoreResult.success === false) {
2962
- return handleUnsuccessfulApiResponse('getScoreByNPMPackage', scoreResult, spinner);
3009
+ return handleUnsuccessfulApiResponse('getScoreByNPMPackage', scoreResult);
2963
3010
  }
2964
3011
  const severityCount = getSeverityCount(result.data, includeAllIssues ? undefined : 'high');
2965
3012
  return {
@@ -2978,49 +3025,54 @@ function formatPackageInfo({
2978
3025
  severityCount
2979
3026
  }, {
2980
3027
  name,
2981
- outputJson,
2982
- outputMarkdown,
3028
+ outputKind,
2983
3029
  pkgName,
2984
- pkgVersion,
2985
- strict
2986
- }, spinner) {
2987
- if (outputJson) {
3030
+ pkgVersion
3031
+ }) {
3032
+ if (outputKind === 'json') {
2988
3033
  logger.logger.log(JSON.stringify(data, undefined, 2));
3034
+ return;
3035
+ }
3036
+ if (outputKind === 'markdown') {
3037
+ logger.logger.log(`\n# Package report for ${pkgName}\n`);
3038
+ logger.logger.log('Package report card:\n');
2989
3039
  } else {
2990
- logger.logger.log('\nPackage report card:');
2991
- const scoreResult = {
2992
- 'Supply Chain Risk': Math.floor(score.supplyChainRisk.score * 100),
2993
- Maintenance: Math.floor(score.maintenance.score * 100),
2994
- Quality: Math.floor(score.quality.score * 100),
2995
- Vulnerabilities: Math.floor(score.vulnerability.score * 100),
2996
- License: Math.floor(score.license.score * 100)
2997
- };
2998
- Object.entries(scoreResult).map(score => logger.logger.log(`- ${score[0]}: ${formatScore(score[1])}`));
2999
- logger.logger.log('\n');
3000
- if (objectSome(severityCount)) {
3001
- spinner[strict ? 'error' : 'success'](`Package has these issues: ${formatSeverityCount(severityCount)}`);
3002
- formatPackageIssuesDetails(data, outputMarkdown);
3003
- } else {
3004
- spinner.successAndStop('Package has no issues');
3005
- }
3006
- const format = new index.ColorOrMarkdown(!!outputMarkdown);
3007
- const url = index.getSocketDevPackageOverviewUrl(NPM$c, pkgName, pkgVersion);
3008
- logger.logger.log('\n');
3009
- if (pkgVersion === 'latest') {
3010
- logger.logger.log(`Detailed info on socket.dev: ${format.hyperlink(`${pkgName}`, url, {
3011
- fallbackToUrl: true
3012
- })}`);
3013
- } else {
3014
- logger.logger.log(`Detailed info on socket.dev: ${format.hyperlink(`${pkgName} v${pkgVersion}`, url, {
3015
- fallbackToUrl: true
3016
- })}`);
3017
- }
3018
- if (!outputMarkdown) {
3019
- logger.logger.log(colors.dim(`\nOr rerun ${colors.italic(name)} using the ${colors.italic('--json')} flag to get full JSON output`));
3040
+ logger.logger.log(`\nPackage report card for ${pkgName}:\n`);
3041
+ }
3042
+ const scoreResult = {
3043
+ 'Supply Chain Risk': Math.floor(score.supplyChainRisk.score * 100),
3044
+ Maintenance: Math.floor(score.maintenance.score * 100),
3045
+ Quality: Math.floor(score.quality.score * 100),
3046
+ Vulnerabilities: Math.floor(score.vulnerability.score * 100),
3047
+ License: Math.floor(score.license.score * 100)
3048
+ };
3049
+ Object.entries(scoreResult).map(score => logger.logger.log(`- ${score[0]}: ${formatScore(score[1])}`));
3050
+ logger.logger.log('\n');
3051
+ if (objectSome(severityCount)) {
3052
+ if (outputKind === 'markdown') {
3053
+ logger.logger.log('# Issues\n');
3020
3054
  }
3055
+ logger.logger.log(`Package has these issues: ${formatSeverityCount(severityCount)}\n`);
3056
+ formatPackageIssuesDetails(data, outputKind === 'markdown');
3057
+ } else {
3058
+ logger.logger.log('Package has no issues');
3021
3059
  }
3022
- if (strict && objectSome(severityCount)) {
3023
- process$1.exit(1);
3060
+ const format = new shadowNpmInject.ColorOrMarkdown(outputKind === 'markdown');
3061
+ const url = shadowNpmInject.getSocketDevPackageOverviewUrl(NPM$c, pkgName, pkgVersion);
3062
+ logger.logger.log('\n');
3063
+ if (pkgVersion === 'latest') {
3064
+ logger.logger.log(`Detailed info on socket.dev: ${format.hyperlink(`${pkgName}`, url, {
3065
+ fallbackToUrl: true
3066
+ })}`);
3067
+ } else {
3068
+ logger.logger.log(`Detailed info on socket.dev: ${format.hyperlink(`${pkgName} v${pkgVersion}`, url, {
3069
+ fallbackToUrl: true
3070
+ })}`);
3071
+ }
3072
+ if (outputKind !== 'markdown') {
3073
+ logger.logger.log(colors.dim(`\nOr rerun ${colors.italic(name)} using the ${colors.italic('--json')} flag to get full JSON output`));
3074
+ } else {
3075
+ logger.logger.log('');
3024
3076
  }
3025
3077
  }
3026
3078
  function formatPackageIssuesDetails(packageData, outputMarkdown) {
@@ -3041,9 +3093,9 @@ function formatPackageIssuesDetails(packageData, outputMarkdown) {
3041
3093
  }
3042
3094
  return acc;
3043
3095
  }, {});
3044
- const format = new index.ColorOrMarkdown(!!outputMarkdown);
3096
+ const format = new shadowNpmInject.ColorOrMarkdown(outputMarkdown);
3045
3097
  for (const issue of Object.keys(uniqueIssues)) {
3046
- const issueWithLink = format.hyperlink(`${uniqueIssues[issue]?.label}`, index.getSocketDevAlertUrl(issue), {
3098
+ const issueWithLink = format.hyperlink(`${uniqueIssues[issue]?.label}`, shadowNpmInject.getSocketDevAlertUrl(issue), {
3047
3099
  fallbackToUrl: true
3048
3100
  });
3049
3101
  if (uniqueIssues[issue]?.count === 1) {
@@ -3065,8 +3117,7 @@ function formatScore(score) {
3065
3117
  async function getPackageInfo({
3066
3118
  commandName,
3067
3119
  includeAllIssues,
3068
- outputJson,
3069
- outputMarkdown,
3120
+ outputKind,
3070
3121
  pkgName,
3071
3122
  pkgVersion,
3072
3123
  strict
@@ -3076,16 +3127,19 @@ async function getPackageInfo({
3076
3127
  spinner
3077
3128
  } = constants;
3078
3129
  spinner.start(pkgVersion === 'latest' ? `Looking up data for the latest version of ${pkgName}` : `Looking up data for version ${pkgVersion} of ${pkgName}`);
3079
- const packageData = await fetchPackageInfo(pkgName, pkgVersion, includeAllIssues, spinner);
3130
+ const packageData = await fetchPackageInfo(pkgName, pkgVersion, includeAllIssues);
3131
+ spinner.successAndStop('Data fetched');
3080
3132
  if (packageData) {
3081
3133
  formatPackageInfo(packageData, {
3082
3134
  name: commandName,
3083
- outputJson,
3084
- outputMarkdown,
3135
+ outputKind,
3085
3136
  pkgName,
3086
- pkgVersion,
3087
- strict
3088
- }, spinner);
3137
+ pkgVersion
3138
+ });
3139
+ if (strict && objectSome(packageData.severityCount)) {
3140
+ // Let NodeJS exit gracefully but with exit(1)
3141
+ process$1.exitCode = 1;
3142
+ }
3089
3143
  }
3090
3144
  }
3091
3145
 
@@ -3127,13 +3181,19 @@ async function run$s(argv, importMeta, {
3127
3181
  importMeta,
3128
3182
  parentName
3129
3183
  });
3184
+ const {
3185
+ all,
3186
+ json,
3187
+ markdown,
3188
+ strict
3189
+ } = cli.flags;
3130
3190
  const [rawPkgName = ''] = cli.input;
3131
3191
  if (!rawPkgName || cli.input.length > 1) {
3132
3192
  // Use exit status of 2 to indicate incorrect usage, generally invalid
3133
3193
  // options or missing arguments.
3134
3194
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
3135
3195
  process.exitCode = 2;
3136
- logger.logger.error(`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
3196
+ logger.logger.fail(`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
3137
3197
  - Expecting a package name ${!rawPkgName ? colors.red('(missing!)') : colors.green('(ok)')}\n
3138
3198
  - Can only accept one package at a time ${cli.input.length > 1 ? colors.red('(got ' + cli.input.length + '!)') : colors.green('(ok)')}\n`);
3139
3199
  return;
@@ -3147,28 +3207,27 @@ async function run$s(argv, importMeta, {
3147
3207
  }
3148
3208
  await getPackageInfo({
3149
3209
  commandName: `${parentName} ${config$s.commandName}`,
3150
- includeAllIssues: Boolean(cli.flags['all']),
3151
- outputJson: Boolean(cli.flags['json']),
3152
- outputMarkdown: Boolean(cli.flags['markdown']),
3210
+ includeAllIssues: Boolean(all),
3211
+ outputKind: json ? 'json' : markdown ? 'markdown' : 'print',
3153
3212
  pkgName,
3154
3213
  pkgVersion,
3155
- strict: Boolean(cli.flags['strict'])
3214
+ strict: Boolean(strict)
3156
3215
  });
3157
3216
  }
3158
3217
 
3159
3218
  function applyLogin(apiToken, enforcedOrgs, apiBaseUrl, apiProxy) {
3160
- index.updateSetting('enforcedOrgs', enforcedOrgs);
3161
- index.updateSetting('apiToken', apiToken);
3162
- index.updateSetting('apiBaseUrl', apiBaseUrl);
3163
- index.updateSetting('apiProxy', apiProxy);
3219
+ shadowNpmInject.updateSetting('enforcedOrgs', enforcedOrgs);
3220
+ shadowNpmInject.updateSetting('apiToken', apiToken);
3221
+ shadowNpmInject.updateSetting('apiBaseUrl', apiBaseUrl);
3222
+ shadowNpmInject.updateSetting('apiProxy', apiProxy);
3164
3223
  }
3165
3224
 
3166
3225
  const {
3167
3226
  SOCKET_PUBLIC_API_TOKEN
3168
3227
  } = constants;
3169
3228
  async function attemptLogin(apiBaseUrl, apiProxy) {
3170
- apiBaseUrl ??= index.getSetting('apiBaseUrl') ?? undefined;
3171
- apiProxy ??= index.getSetting('apiProxy') ?? undefined;
3229
+ apiBaseUrl ??= shadowNpmInject.getSetting('apiBaseUrl') ?? undefined;
3230
+ apiProxy ??= shadowNpmInject.getSetting('apiProxy') ?? undefined;
3172
3231
  const apiToken = (await prompts.password({
3173
3232
  message: `Enter your ${terminalLink('Socket.dev API key', 'https://docs.socket.dev/docs/api-keys')} (leave blank for a public key)`
3174
3233
  })) || SOCKET_PUBLIC_API_TOKEN;
@@ -3179,10 +3238,10 @@ async function attemptLogin(apiBaseUrl, apiProxy) {
3179
3238
  spinner.start('Verifying API key...');
3180
3239
  let orgs;
3181
3240
  try {
3182
- const sdk = await index.setupSdk(apiToken, apiBaseUrl, apiProxy);
3241
+ const sdk = await shadowNpmInject.setupSdk(apiToken, apiBaseUrl, apiProxy);
3183
3242
  const result = await sdk.getOrganizations();
3184
3243
  if (!result.success) {
3185
- throw new index.AuthError();
3244
+ throw new shadowNpmInject.AuthError();
3186
3245
  }
3187
3246
  orgs = result.data;
3188
3247
  spinner.success('API key verified');
@@ -3223,12 +3282,13 @@ async function attemptLogin(apiBaseUrl, apiProxy) {
3223
3282
  }
3224
3283
  }
3225
3284
  }
3226
- const oldToken = index.getSetting('apiToken');
3285
+ spinner.stop();
3286
+ const oldToken = shadowNpmInject.getSetting('apiToken');
3227
3287
  try {
3228
3288
  applyLogin(apiToken, enforcedOrgs, apiBaseUrl, apiProxy);
3229
- spinner.successAndStop(`API credentials ${oldToken ? 'updated' : 'set'}`);
3289
+ logger.logger.success(`API credentials ${oldToken ? 'updated' : 'set'}`);
3230
3290
  } catch {
3231
- spinner.errorAndStop(`API login failed`);
3291
+ logger.logger.fail(`API login failed`);
3232
3292
  }
3233
3293
  }
3234
3294
 
@@ -3285,16 +3345,16 @@ async function run$r(argv, importMeta, {
3285
3345
  return;
3286
3346
  }
3287
3347
  if (!isInteractive()) {
3288
- throw new index.InputError('Cannot prompt for credentials in a non-interactive shell');
3348
+ throw new shadowNpmInject.InputError('Cannot prompt for credentials in a non-interactive shell');
3289
3349
  }
3290
3350
  await attemptLogin(apiBaseUrl, apiProxy);
3291
3351
  }
3292
3352
 
3293
3353
  function applyLogout() {
3294
- index.updateSetting('apiToken', null);
3295
- index.updateSetting('apiBaseUrl', null);
3296
- index.updateSetting('apiProxy', null);
3297
- index.updateSetting('enforcedOrgs', null);
3354
+ shadowNpmInject.updateSetting('apiToken', null);
3355
+ shadowNpmInject.updateSetting('apiBaseUrl', null);
3356
+ shadowNpmInject.updateSetting('apiProxy', null);
3357
+ shadowNpmInject.updateSetting('enforcedOrgs', null);
3298
3358
  }
3299
3359
 
3300
3360
  function attemptLogout() {
@@ -3302,7 +3362,7 @@ function attemptLogout() {
3302
3362
  applyLogout();
3303
3363
  logger.logger.success('Successfully logged out');
3304
3364
  } catch {
3305
- logger.logger.error('Failed to complete logout steps');
3365
+ logger.logger.fail('Failed to complete logout steps');
3306
3366
  }
3307
3367
  }
3308
3368
 
@@ -3362,7 +3422,6 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
3362
3422
  logger.logger.log(`- src dir: \`${target}\``);
3363
3423
  logger.logger.groupEnd();
3364
3424
  }
3365
- spinner.start(`Converting gradle to maven from \`${bin}\` on \`${target}\`...`);
3366
3425
  try {
3367
3426
  // Run sbt with the init script we provide which should yield zero or more pom files.
3368
3427
  // We have to figure out where to store those pom files such that we can upload them and predict them through the GitHub API.
@@ -3372,8 +3431,9 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
3372
3431
  const initLocation = path.join(constants.rootDistPath, 'init.gradle');
3373
3432
  const commandArgs = ['--init-script', initLocation, ...gradleOpts, 'pom'];
3374
3433
  if (verbose) {
3375
- spinner.log('[VERBOSE] Executing:', bin, commandArgs);
3434
+ logger.logger.log('[VERBOSE] Executing:', bin, commandArgs);
3376
3435
  }
3436
+ spinner.start(`Converting gradle to maven from \`${bin}\` on \`${target}\`...`);
3377
3437
  const output = await spawn.spawn(bin, commandArgs, {
3378
3438
  cwd: target || '.'
3379
3439
  });
@@ -3384,14 +3444,15 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
3384
3444
  logger.logger.groupEnd();
3385
3445
  }
3386
3446
  if (output.stderr) {
3387
- logger.logger.error('There were errors while running gradle');
3447
+ process.exitCode = 1;
3448
+ logger.logger.fail('There were errors while running gradle');
3388
3449
  // (In verbose mode, stderr was printed above, no need to repeat it)
3389
3450
  if (!verbose) {
3390
3451
  logger.logger.group('[VERBOSE] stderr:');
3391
3452
  logger.logger.error(output.stderr);
3392
3453
  logger.logger.groupEnd();
3393
3454
  }
3394
- process.exit(1);
3455
+ return;
3395
3456
  }
3396
3457
  logger.logger.success('Executed gradle successfully');
3397
3458
  logger.logger.log('Reported exports:');
@@ -3402,7 +3463,7 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
3402
3463
 
3403
3464
  // const loc = output.stdout?.match(/Wrote (.*?.pom)\n/)?.[1]?.trim()
3404
3465
  // if (!loc) {
3405
- // logger.error(
3466
+ // logger.fail(
3406
3467
  // 'There were no errors from sbt but could not find the location of resulting .pom file either'
3407
3468
  // )
3408
3469
  // process.exit(1)
@@ -3428,14 +3489,14 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
3428
3489
  // spinner.successAndStop(`OK. File should be available in \`${out}\``)
3429
3490
  // }
3430
3491
  } catch (e) {
3492
+ process.exitCode = 1;
3431
3493
  spinner.stop();
3432
- logger.logger.error('There was an unexpected error while running this' + (verbose ? '' : ' (use --verbose for details)'));
3494
+ logger.logger.fail('There was an unexpected error while running this' + (verbose ? '' : ' (use --verbose for details)'));
3433
3495
  if (verbose) {
3434
3496
  logger.logger.group('[VERBOSE] error:');
3435
3497
  logger.logger.log(e);
3436
3498
  logger.logger.groupEnd();
3437
3499
  }
3438
- process.exit(1);
3439
3500
  }
3440
3501
  }
3441
3502
 
@@ -3545,7 +3606,7 @@ async function run$p(argv, importMeta, {
3545
3606
  // options or missing arguments.
3546
3607
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
3547
3608
  process.exitCode = 2;
3548
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
3609
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
3549
3610
 
3550
3611
  - The DIR arg is required ${!target ? colors.red('(missing!)') : target === '-' ? colors.red('(stdin is not supported)') : colors.green('(ok)')}
3551
3612
 
@@ -3603,8 +3664,9 @@ async function convertSbtToMaven(target, bin, out, verbose, sbtOpts) {
3603
3664
  // logger.log(`- dst dir: \`${out}\``)
3604
3665
  logger.logger.groupEnd();
3605
3666
  }
3606
- spinner.start(`Converting sbt to maven from \`${bin}\` on \`${target}\`...`);
3607
3667
  try {
3668
+ spinner.start(`Converting sbt to maven from \`${bin}\` on \`${target}\`...`);
3669
+
3608
3670
  // Run sbt with the init script we provide which should yield zero or more
3609
3671
  // pom files. We have to figure out where to store those pom files such that
3610
3672
  // we can upload them and predict them through the GitHub API. We could do a
@@ -3620,14 +3682,15 @@ async function convertSbtToMaven(target, bin, out, verbose, sbtOpts) {
3620
3682
  logger.logger.groupEnd();
3621
3683
  }
3622
3684
  if (output.stderr) {
3623
- logger.logger.error('There were errors while running sbt');
3685
+ process.exitCode = 1;
3686
+ logger.logger.fail('There were errors while running sbt');
3624
3687
  // (In verbose mode, stderr was printed above, no need to repeat it)
3625
3688
  if (!verbose) {
3626
3689
  logger.logger.group('[VERBOSE] stderr:');
3627
3690
  logger.logger.error(output.stderr);
3628
3691
  logger.logger.groupEnd();
3629
3692
  }
3630
- process.exit(1);
3693
+ return;
3631
3694
  }
3632
3695
  const poms = [];
3633
3696
  output.stdout.replace(/Wrote (.*?.pom)\n/g, (_all, fn) => {
@@ -3635,22 +3698,24 @@ async function convertSbtToMaven(target, bin, out, verbose, sbtOpts) {
3635
3698
  return fn;
3636
3699
  });
3637
3700
  if (!poms.length) {
3638
- logger.logger.error('There were no errors from sbt but it seems to not have generated any poms either');
3639
- process.exit(1);
3701
+ process.exitCode = 1;
3702
+ logger.logger.fail('There were no errors from sbt but it seems to not have generated any poms either');
3703
+ return;
3640
3704
  }
3641
3705
  // Move the pom file to ...? initial cwd? loc will be an absolute path, or dump to stdout
3642
3706
  // TODO: what to do with multiple output files? Do we want to dump them to stdout? Raw or with separators or ?
3643
3707
  // TODO: maybe we can add an option to target a specific file to dump to stdout
3644
3708
  if (out === '-' && poms.length === 1) {
3645
3709
  logger.logger.log('Result:\n```');
3646
- logger.logger.log(await index.safeReadFile(poms[0], 'utf8'));
3710
+ logger.logger.log(await shadowNpmInject.safeReadFile(poms[0], 'utf8'));
3647
3711
  logger.logger.log('```');
3648
3712
  logger.logger.success(`OK`);
3649
3713
  } else if (out === '-') {
3650
- logger.logger.error('Requested out target was stdout but there are multiple generated files');
3714
+ process.exitCode = 1;
3715
+ logger.logger.fail('Requested out target was stdout but there are multiple generated files');
3651
3716
  poms.forEach(fn => logger.logger.error('-', fn));
3652
3717
  logger.logger.error('Exiting now...');
3653
- process.exit(1);
3718
+ return;
3654
3719
  } else {
3655
3720
  // if (verbose) {
3656
3721
  // logger.log(
@@ -3666,14 +3731,14 @@ async function convertSbtToMaven(target, bin, out, verbose, sbtOpts) {
3666
3731
  logger.logger.success(`OK`);
3667
3732
  }
3668
3733
  } catch (e) {
3734
+ process.exitCode = 1;
3669
3735
  spinner.stop();
3670
- logger.logger.error('There was an unexpected error while running this' + (verbose ? '' : ' (use --verbose for details)'));
3736
+ logger.logger.fail('There was an unexpected error while running this' + (verbose ? '' : ' (use --verbose for details)'));
3671
3737
  if (verbose) {
3672
3738
  logger.logger.group('[VERBOSE] error:');
3673
3739
  logger.logger.log(e);
3674
3740
  logger.logger.groupEnd();
3675
3741
  }
3676
- process.exit(1);
3677
3742
  }
3678
3743
  }
3679
3744
 
@@ -3781,7 +3846,7 @@ async function run$o(argv, importMeta, {
3781
3846
  // options or missing arguments.
3782
3847
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
3783
3848
  process.exitCode = 2;
3784
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
3849
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
3785
3850
 
3786
3851
  - The DIR or FILE arg is required ${!target ? colors.red('(missing!)') : target === '-' ? colors.red('(stdin is not supported)') : colors.green('(ok)')}
3787
3852
 
@@ -4041,7 +4106,7 @@ async function run$m(argv, importMeta, {
4041
4106
  // options or missing arguments.
4042
4107
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
4043
4108
  process.exitCode = 2;
4044
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
4109
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
4045
4110
 
4046
4111
  - The DIR arg is required ${!target ? colors.red('(missing!)') : target === '-' ? colors.red('(stdin is not supported)') : colors.green('(ok)')}
4047
4112
 
@@ -4116,12 +4181,11 @@ async function run$l(argv, importMeta, {
4116
4181
  }
4117
4182
 
4118
4183
  const {
4119
- NPM: NPM$b,
4120
- SHADOW_BIN: SHADOW_BIN$1
4184
+ NPM: NPM$b
4121
4185
  } = constants;
4122
4186
  async function wrapNpm(argv) {
4123
- // Lazily access constants.distPath.
4124
- const shadowBin = require(`${constants.distPath}/${SHADOW_BIN$1}.js`);
4187
+ // Lazily access constants.distShadowNpmBinPath.
4188
+ const shadowBin = require(constants.distShadowNpmBinPath);
4125
4189
  await shadowBin(NPM$b, argv);
4126
4190
  }
4127
4191
 
@@ -4162,12 +4226,11 @@ async function run$k(argv, importMeta, {
4162
4226
  }
4163
4227
 
4164
4228
  const {
4165
- NPX: NPX$2,
4166
- SHADOW_BIN
4229
+ NPX: NPX$2
4167
4230
  } = constants;
4168
4231
  async function wrapNpx(argv) {
4169
- // Lazily access constants.distPath.
4170
- const shadowBin = require(`${constants.distPath}/${SHADOW_BIN}.js`);
4232
+ // Lazily access constants.distShadowNpmBinPath.
4233
+ const shadowBin = require(constants.distShadowNpmBinPath);
4171
4234
  await shadowBin(NPX$2, argv);
4172
4235
  }
4173
4236
 
@@ -4330,8 +4393,8 @@ const readLockFileByAgent = (() => {
4330
4393
  return undefined;
4331
4394
  };
4332
4395
  }
4333
- const binaryReader = wrapReader(index.readFileBinary);
4334
- const defaultReader = wrapReader(async lockPath => await index.readFileUtf8(lockPath));
4396
+ const binaryReader = wrapReader(shadowNpmInject.readFileBinary);
4397
+ const defaultReader = wrapReader(async lockPath => await shadowNpmInject.readFileUtf8(lockPath));
4335
4398
  return {
4336
4399
  [BUN$5]: wrapReader(async (lockPath, agentExecPath) => {
4337
4400
  const ext = path.extname(lockPath);
@@ -4363,12 +4426,12 @@ async function detectPackageEnvironment({
4363
4426
  cwd = process$1.cwd(),
4364
4427
  onUnknown
4365
4428
  } = {}) {
4366
- let lockPath = await index.findUp(Object.keys(LOCKS), {
4429
+ let lockPath = await shadowNpmInject.findUp(Object.keys(LOCKS), {
4367
4430
  cwd
4368
4431
  });
4369
4432
  let lockName = lockPath ? path.basename(lockPath) : undefined;
4370
4433
  const isHiddenLockFile = lockName === '.package-lock.json';
4371
- const pkgJsonPath = lockPath ? path.resolve(lockPath, `${isHiddenLockFile ? '../' : ''}../package.json`) : await index.findUp('package.json', {
4434
+ const pkgJsonPath = lockPath ? path.resolve(lockPath, `${isHiddenLockFile ? '../' : ''}../package.json`) : await shadowNpmInject.findUp('package.json', {
4372
4435
  cwd
4373
4436
  });
4374
4437
  const pkgPath = pkgJsonPath && fs.existsSync(pkgJsonPath) ? path.dirname(pkgJsonPath) : undefined;
@@ -4480,36 +4543,36 @@ async function detectAndValidatePackageEnvironment(cwd, options) {
4480
4543
  const details = await detectPackageEnvironment({
4481
4544
  cwd,
4482
4545
  onUnknown(pkgManager) {
4483
- logger?.warn(`⚠️ ${COMMAND_TITLE$2}: Unknown package manager${pkgManager ? ` ${pkgManager}` : ''}, defaulting to npm`);
4546
+ logger?.warn(`${COMMAND_TITLE$2}: Unknown package manager${pkgManager ? ` ${pkgManager}` : ''}, defaulting to npm`);
4484
4547
  }
4485
4548
  });
4486
4549
  if (!details.supported) {
4487
- logger?.error(`✖️ ${COMMAND_TITLE$2}: No supported Node or browser range detected`);
4550
+ logger?.fail(`${COMMAND_TITLE$2}: No supported Node or browser range detected`);
4488
4551
  return;
4489
4552
  }
4490
4553
  if (details.agent === VLT$4) {
4491
- logger?.error(`✖️ ${COMMAND_TITLE$2}: ${details.agent} does not support overrides. Soon, though ⚡`);
4554
+ logger?.fail(`${COMMAND_TITLE$2}: ${details.agent} does not support overrides. Soon, though ⚡`);
4492
4555
  return;
4493
4556
  }
4494
4557
  const lockName = details.lockName ?? 'lock file';
4495
4558
  if (details.lockName === undefined || details.lockSrc === undefined) {
4496
- logger?.error(`✖️ ${COMMAND_TITLE$2}: No ${lockName} found`);
4559
+ logger?.fail(`${COMMAND_TITLE$2}: No ${lockName} found`);
4497
4560
  return;
4498
4561
  }
4499
4562
  if (details.lockSrc.trim() === '') {
4500
- logger?.error(`✖️ ${COMMAND_TITLE$2}: ${lockName} is empty`);
4563
+ logger?.fail(`${COMMAND_TITLE$2}: ${lockName} is empty`);
4501
4564
  return;
4502
4565
  }
4503
4566
  if (details.pkgPath === undefined) {
4504
- logger?.error(`✖️ ${COMMAND_TITLE$2}: No package.json found`);
4567
+ logger?.fail(`${COMMAND_TITLE$2}: No package.json found`);
4505
4568
  return;
4506
4569
  }
4507
4570
  if (prod && (details.agent === BUN$4 || details.agent === YARN_BERRY$4)) {
4508
- logger?.error(`✖️ ${COMMAND_TITLE$2}: --prod not supported for ${details.agent}${details.agentVersion ? `@${details.agentVersion.toString()}` : ''}`);
4571
+ logger?.fail(`${COMMAND_TITLE$2}: --prod not supported for ${details.agent}${details.agentVersion ? `@${details.agentVersion.toString()}` : ''}`);
4509
4572
  return;
4510
4573
  }
4511
4574
  if (details.lockPath && path.relative(cwd, details.lockPath).startsWith('.')) {
4512
- logger?.warn(`⚠️ ${COMMAND_TITLE$2}: Package ${lockName} found at ${details.lockPath}`);
4575
+ logger?.warn(`${COMMAND_TITLE$2}: Package ${lockName} found at ${details.lockPath}`);
4513
4576
  }
4514
4577
  return details;
4515
4578
  }
@@ -4613,7 +4676,7 @@ async function getWorkspaceGlobs(agent, pkgPath, pkgJson) {
4613
4676
  if (agent === PNPM$4) {
4614
4677
  for (const workspacePath of [path.join(pkgPath, `${PNPM_WORKSPACE}.yaml`), path.join(pkgPath, `${PNPM_WORKSPACE}.yml`)]) {
4615
4678
  // eslint-disable-next-line no-await-in-loop
4616
- const yml = await index.safeReadFile(workspacePath, 'utf8');
4679
+ const yml = await shadowNpmInject.safeReadFile(workspacePath, 'utf8');
4617
4680
  if (yml) {
4618
4681
  try {
4619
4682
  workspacePatterns = yaml.parse(yml)?.packages;
@@ -4958,8 +5021,8 @@ function safeNpmInstall(options) {
4958
5021
  constants.execPath, [
4959
5022
  // Lazily access constants.nodeNoWarningsFlags.
4960
5023
  ...constants.nodeNoWarningsFlags, '--require',
4961
- // Lazily access constants.npmInjectionPath.
4962
- constants.npmInjectionPath, npmPaths.getNpmBinPath(), 'install',
5024
+ // Lazily access constants.distShadowNpmInjectPath.
5025
+ constants.distShadowNpmInjectPath, shadowNpmPaths.getNpmBinPath(), 'install',
4963
5026
  // Even though the '--silent' flag is passed npm will still run through
4964
5027
  // code paths for 'audit' and 'fund' unless '--no-audit' and '--no-fund'
4965
5028
  // flags are passed.
@@ -5046,7 +5109,7 @@ async function updatePackageLockJson(pkgEnvDetails, options) {
5046
5109
  }
5047
5110
  } catch (e) {
5048
5111
  spinner?.stop();
5049
- logger?.error(`${COMMAND_TITLE$1}: ${pkgEnvDetails.agent} install failed to update ${pkgEnvDetails.lockName}`);
5112
+ logger?.fail(`${COMMAND_TITLE$1}: ${pkgEnvDetails.agent} install failed to update ${pkgEnvDetails.lockName}`);
5050
5113
  logger?.error(e);
5051
5114
  }
5052
5115
  }
@@ -5146,7 +5209,7 @@ async function addOverrides(pkgPath, pkgEnvDetails, options) {
5146
5209
  const isWorkspace = !!workspaceGlobs;
5147
5210
  if (isWorkspace && agent === PNPM && npmExecPath === NPM$1 && !state.warnedPnpmWorkspaceRequiresNpm) {
5148
5211
  state.warnedPnpmWorkspaceRequiresNpm = true;
5149
- logger?.warn(`⚠️ ${COMMAND_TITLE}: pnpm workspace support requires \`npm ls\`, falling back to \`pnpm list\``);
5212
+ logger?.warn(`${COMMAND_TITLE}: pnpm workspace support requires \`npm ls\`, falling back to \`pnpm list\``);
5150
5213
  }
5151
5214
  const thingToScan = isLockScanned ? lockSrc : await lsByAgent[agent](agentExecPath, pkgPath, {
5152
5215
  npmExecPath
@@ -5337,9 +5400,9 @@ async function run$h(argv, importMeta, {
5337
5400
  }
5338
5401
 
5339
5402
  async function getOrganization(format = 'text') {
5340
- const apiToken = index.getDefaultToken();
5403
+ const apiToken = shadowNpmInject.getDefaultToken();
5341
5404
  if (!apiToken) {
5342
- 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.');
5405
+ 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.');
5343
5406
  }
5344
5407
  await printOrganizationsFromToken(apiToken, format);
5345
5408
  }
@@ -5349,10 +5412,10 @@ async function printOrganizationsFromToken(apiToken, format = 'text') {
5349
5412
  spinner
5350
5413
  } = constants;
5351
5414
  spinner.start('Fetching organizations...');
5352
- const socketSdk = await index.setupSdk(apiToken);
5415
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
5353
5416
  const result = await handleApiCall(socketSdk.getOrganizations(), 'looking up organizations');
5354
5417
  if (!result.success) {
5355
- handleUnsuccessfulApiResponse('getOrganizations', result, spinner);
5418
+ handleUnsuccessfulApiResponse('getOrganizations', result);
5356
5419
  return;
5357
5420
  }
5358
5421
  spinner.stop();
@@ -5443,7 +5506,7 @@ async function run$g(argv, importMeta, {
5443
5506
  // options or missing arguments.
5444
5507
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
5445
5508
  process.exitCode = 2;
5446
- logger.logger.error(commonTags.stripIndents`
5509
+ logger.logger.fail(commonTags.stripIndents`
5447
5510
  ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
5448
5511
 
5449
5512
  - The json and markdown flags cannot be both set, pick one
@@ -5458,7 +5521,7 @@ ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields
5458
5521
  }
5459
5522
 
5460
5523
  async function runRawNpm(argv) {
5461
- const spawnPromise = spawn.spawn(npmPaths.getNpmBinPath(), argv, {
5524
+ const spawnPromise = spawn.spawn(shadowNpmPaths.getNpmBinPath(), argv, {
5462
5525
  stdio: 'inherit'
5463
5526
  });
5464
5527
  // See https://nodejs.org/api/all.html#all_child_process_event-exit.
@@ -5481,13 +5544,10 @@ const config$f = {
5481
5544
  description: `Temporarily disable the Socket ${NPM} wrapper`,
5482
5545
  hidden: false,
5483
5546
  flags: {},
5484
- help: (command, config) => `
5547
+ help: command => `
5485
5548
  Usage
5486
5549
  $ ${command} <command>
5487
5550
 
5488
- Options
5489
- ${getFlagListOutput(config.flags, 6)}
5490
-
5491
5551
  Examples
5492
5552
  $ ${command} install
5493
5553
  `
@@ -5515,7 +5575,7 @@ async function run$f(argv, importMeta, {
5515
5575
  }
5516
5576
 
5517
5577
  async function runRawNpx(argv) {
5518
- const spawnPromise = spawn.spawn(npmPaths.getNpxBinPath(), argv, {
5578
+ const spawnPromise = spawn.spawn(shadowNpmPaths.getNpxBinPath(), argv, {
5519
5579
  stdio: 'inherit'
5520
5580
  });
5521
5581
  // See https://nodejs.org/api/all.html#all_child_process_event-exit.
@@ -5538,13 +5598,10 @@ const config$e = {
5538
5598
  description: `Temporarily disable the Socket ${NPX} wrapper`,
5539
5599
  hidden: false,
5540
5600
  flags: {},
5541
- help: (command, config) => `
5601
+ help: command => `
5542
5602
  Usage
5543
5603
  $ ${command} <command>
5544
5604
 
5545
- Options
5546
- ${getFlagListOutput(config.flags, 6)}
5547
-
5548
5605
  Examples
5549
5606
  $ ${command} install
5550
5607
  `
@@ -5582,19 +5639,17 @@ async function createReport(socketConfig, inputPaths, {
5582
5639
  const {
5583
5640
  spinner
5584
5641
  } = constants;
5585
- const socketSdk = await index.setupSdk();
5642
+ const socketSdk = await shadowNpmInject.setupSdk();
5586
5643
  const supportedFiles = await socketSdk.getReportSupportedFiles().then(res => {
5587
- if (!res.success) handleUnsuccessfulApiResponse('getReportSupportedFiles', res, spinner);
5644
+ if (!res.success) handleUnsuccessfulApiResponse('getReportSupportedFiles', res);
5588
5645
  return res.data;
5589
5646
  }).catch(cause => {
5590
5647
  throw new Error('Failed getting supported files for report', {
5591
5648
  cause
5592
5649
  });
5593
5650
  });
5594
- const packagePaths = await npmPaths.getPackageFiles(cwd, inputPaths, socketConfig, supportedFiles);
5595
- const {
5596
- length: packagePathsCount
5597
- } = packagePaths;
5651
+ const packagePaths = await shadowNpmPaths.getPackageFilesFullScans(cwd, inputPaths, supportedFiles, socketConfig);
5652
+ const packagePathsCount = packagePaths.length;
5598
5653
  if (packagePathsCount && debug.isDebug()) {
5599
5654
  for (const pkgPath of packagePaths) {
5600
5655
  debug.debugLog(`Uploading: ${pkgPath}`);
@@ -5608,7 +5663,7 @@ async function createReport(socketConfig, inputPaths, {
5608
5663
  const apiCall = socketSdk.createReportFromFilePaths(packagePaths, cwd, socketConfig?.issueRules);
5609
5664
  const result = await handleApiCall(apiCall, 'creating report');
5610
5665
  if (!result.success) {
5611
- handleUnsuccessfulApiResponse('createReport', result, spinner);
5666
+ handleUnsuccessfulApiResponse('createReport', result);
5612
5667
  return undefined;
5613
5668
  }
5614
5669
  spinner.successAndStop();
@@ -5626,7 +5681,7 @@ async function getSocketConfig(absoluteConfigPath) {
5626
5681
  errors: cause.validationErrors,
5627
5682
  schema: cause.schema
5628
5683
  });
5629
- throw new index.InputError('The socket.yml config is not valid', betterErrors.map(err => `[${err.path}] ${err.message}.${err.suggestion ? err.suggestion : ''}`).join('\n'));
5684
+ throw new shadowNpmInject.InputError('The socket.yml config is not valid', betterErrors.map(err => `[${err.path}] ${err.message}.${err.suggestion ? err.suggestion : ''}`).join('\n'));
5630
5685
  } else {
5631
5686
  throw new Error('Failed to read socket.yml config', {
5632
5687
  cause
@@ -5644,7 +5699,7 @@ async function fetchReportData(reportId, includeAllIssues, strict) {
5644
5699
  spinner
5645
5700
  } = constants;
5646
5701
  spinner.start(`Fetching report with ID ${reportId} (this could take a while)`);
5647
- const socketSdk = await index.setupSdk();
5702
+ const socketSdk = await shadowNpmInject.setupSdk();
5648
5703
  let result;
5649
5704
  for (let retry = 1; !result; ++retry) {
5650
5705
  try {
@@ -5658,7 +5713,7 @@ async function fetchReportData(reportId, includeAllIssues, strict) {
5658
5713
  }
5659
5714
  }
5660
5715
  if (!result.success) {
5661
- return handleUnsuccessfulApiResponse('getReport', result, spinner);
5716
+ return handleUnsuccessfulApiResponse('getReport', result);
5662
5717
  }
5663
5718
 
5664
5719
  // Conclude the status of the API call.
@@ -5683,7 +5738,7 @@ function formatReportDataOutput(reportId, data, commandName, outputJson, outputM
5683
5738
  if (outputJson) {
5684
5739
  logger.logger.log(JSON.stringify(data, undefined, 2));
5685
5740
  } else {
5686
- const format = new index.ColorOrMarkdown(outputMarkdown);
5741
+ const format = new shadowNpmInject.ColorOrMarkdown(outputMarkdown);
5687
5742
  logger.logger.log(commonTags.stripIndents`
5688
5743
  Detailed info on socket.dev: ${format.hyperlink(reportId, data.url, {
5689
5744
  fallbackToUrl: true
@@ -5715,7 +5770,7 @@ const {
5715
5770
  } = constants;
5716
5771
  const config$d = {
5717
5772
  commandName: 'create',
5718
- description: 'Create a project report',
5773
+ description: '[Deprecated] Create a project report',
5719
5774
  hidden: false,
5720
5775
  flags: {
5721
5776
  ...commonFlags,
@@ -5733,27 +5788,9 @@ const config$d = {
5733
5788
  description: 'Will wait for and return the created report'
5734
5789
  }
5735
5790
  },
5736
- help: (command, config) => `
5737
- Usage
5738
- $ ${command} <paths-to-package-folders-and-files>
5739
-
5740
- Uploads the specified "package.json" and lock files for JavaScript, Python, and Go dependency manifests.
5741
- If any folder is specified, the ones found in there recursively are uploaded.
5742
-
5743
- Supports globbing such as "**/package.json", "**/requirements.txt", "**/pyproject.toml", and "**/go.mod".
5744
-
5745
- Ignores any file specified in your project's ".gitignore", your project's
5746
- "socket.yml" file's "projectIgnorePaths" and also has a sensible set of
5747
- default ignores from the "ignore-by-default" module.
5748
-
5749
- Options
5750
- ${getFlagListOutput(config.flags, 6)}
5751
-
5752
- Examples
5753
- $ ${command} .
5754
- $ ${command} '**/package.json'
5755
- $ ${command} /path/to/a/package.json /path/to/another/package.json
5756
- $ ${command} . --view --json
5791
+ help: () => `
5792
+ This command is deprecated in favor of \`socket scan create\`.
5793
+ It will be removed in the next major release of the CLI.
5757
5794
  `
5758
5795
  };
5759
5796
  const cmdReportCreate = {
@@ -5805,7 +5842,7 @@ async function run$d(argv, importMeta, {
5805
5842
  } else if (json) {
5806
5843
  logger.logger.log(JSON.stringify(result.data, undefined, 2));
5807
5844
  } else {
5808
- const format = new index.ColorOrMarkdown(markdown);
5845
+ const format = new shadowNpmInject.ColorOrMarkdown(markdown);
5809
5846
  logger.logger.log(`New report: ${format.hyperlink(result.data.id, result.data.url, {
5810
5847
  fallbackToUrl: true
5811
5848
  })}`);
@@ -5818,22 +5855,16 @@ const {
5818
5855
  } = constants;
5819
5856
  const config$c = {
5820
5857
  commandName: 'view',
5821
- description: 'View a project report',
5858
+ description: '[Deprecated] View a project report',
5822
5859
  hidden: false,
5823
5860
  flags: {
5824
5861
  ...commonFlags,
5825
5862
  ...outputFlags,
5826
5863
  ...validationFlags
5827
5864
  },
5828
- help: (command, config) => `
5829
- Usage
5830
- $ ${command} <report-identifier>
5831
-
5832
- Options
5833
- ${getFlagListOutput(config.flags, 6)}
5834
-
5835
- Examples
5836
- $ ${command} QXU8PmK7LfH608RAwfIKdbcHgwEd_ZeWJ9QEGv05FJUQ
5865
+ help: () => `
5866
+ This command is deprecated in favor of \`socket scan view\`.
5867
+ It will be removed in the next major release of the CLI.
5837
5868
  `
5838
5869
  };
5839
5870
  const cmdReportView = {
@@ -5858,7 +5889,7 @@ async function run$c(argv, importMeta, {
5858
5889
  // options or missing arguments.
5859
5890
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
5860
5891
  process.exitCode = 2;
5861
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
5892
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
5862
5893
 
5863
5894
  - Need at least one report ID ${!reportId ? colors.red('(missing!)') : colors.green('(ok)')}
5864
5895
 
@@ -5881,6 +5912,8 @@ async function run$c(argv, importMeta, {
5881
5912
  const description$2 = '[Deprecated] Project report related commands';
5882
5913
  const cmdReport = {
5883
5914
  description: description$2,
5915
+ hidden: true,
5916
+ // Deprecated in favor of `scan`
5884
5917
  async run(argv, importMeta, {
5885
5918
  parentName
5886
5919
  }) {
@@ -5897,13 +5930,33 @@ const cmdReport = {
5897
5930
  };
5898
5931
 
5899
5932
  async function createRepo({
5933
+ default_branch,
5934
+ description,
5935
+ homepage,
5936
+ orgSlug,
5937
+ repoName,
5938
+ visibility
5939
+ }) {
5940
+ const apiToken = shadowNpmInject.getDefaultToken();
5941
+ if (!apiToken) {
5942
+ 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.');
5943
+ }
5944
+ await createRepoWithToken({
5945
+ apiToken,
5946
+ default_branch,
5947
+ description,
5948
+ homepage,
5949
+ orgSlug,
5950
+ repoName,
5951
+ visibility
5952
+ });
5953
+ }
5954
+ async function createRepoWithToken({
5900
5955
  apiToken,
5901
5956
  default_branch,
5902
5957
  description,
5903
5958
  homepage,
5904
5959
  orgSlug,
5905
- outputJson,
5906
- outputMarkdown,
5907
5960
  repoName,
5908
5961
  visibility
5909
5962
  }) {
@@ -5912,22 +5965,19 @@ async function createRepo({
5912
5965
  spinner
5913
5966
  } = constants;
5914
5967
  spinner.start('Creating repository...');
5915
- const socketSdk = await index.setupSdk(apiToken);
5968
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
5916
5969
  const result = await handleApiCall(socketSdk.createOrgRepo(orgSlug, {
5917
- outputJson,
5918
- outputMarkdown,
5919
- orgSlug,
5920
5970
  name: repoName,
5921
5971
  description,
5922
5972
  homepage,
5923
5973
  default_branch,
5924
5974
  visibility
5925
5975
  }), 'creating repository');
5926
- if (result.success) {
5927
- spinner.successAndStop('Repository created successfully');
5928
- } else {
5929
- handleUnsuccessfulApiResponse('createOrgRepo', result, spinner);
5976
+ if (!result.success) {
5977
+ handleUnsuccessfulApiResponse('createOrgRepo', result);
5978
+ return;
5930
5979
  }
5980
+ spinner.successAndStop('Repository created successfully');
5931
5981
  }
5932
5982
 
5933
5983
  const {
@@ -5939,7 +5989,6 @@ const config$b = {
5939
5989
  hidden: false,
5940
5990
  flags: {
5941
5991
  ...commonFlags,
5942
- ...outputFlags,
5943
5992
  repoName: {
5944
5993
  type: 'string',
5945
5994
  shortFlag: 'n',
@@ -6003,7 +6052,7 @@ async function run$b(argv, importMeta, {
6003
6052
  // options or missing arguments.
6004
6053
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
6005
6054
  process.exitCode = 2;
6006
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6055
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6007
6056
 
6008
6057
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
6009
6058
 
@@ -6014,36 +6063,36 @@ async function run$b(argv, importMeta, {
6014
6063
  logger.logger.log(DRY_RUN_BAIL_TEXT$b);
6015
6064
  return;
6016
6065
  }
6017
- const apiToken = index.getDefaultToken();
6018
- if (!apiToken) {
6019
- 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.');
6020
- }
6021
6066
  await createRepo({
6022
- outputJson: Boolean(cli.flags['json']),
6023
- outputMarkdown: Boolean(cli.flags['markdown']),
6024
6067
  orgSlug,
6025
6068
  repoName,
6026
6069
  description: String(cli.flags['repoDescription'] || ''),
6027
6070
  homepage: String(cli.flags['homepage'] || ''),
6028
6071
  default_branch: String(cli.flags['defaultBranch'] || ''),
6029
- visibility: String(cli.flags['visibility'] || 'private'),
6030
- apiToken
6072
+ visibility: String(cli.flags['visibility'] || 'private')
6031
6073
  });
6032
6074
  }
6033
6075
 
6034
- async function deleteRepo(orgSlug, repoName, apiToken) {
6076
+ async function deleteRepo(orgSlug, repoName) {
6077
+ const apiToken = shadowNpmInject.getDefaultToken();
6078
+ if (!apiToken) {
6079
+ 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.');
6080
+ }
6081
+ await deleteRepoWithToken(orgSlug, repoName, apiToken);
6082
+ }
6083
+ async function deleteRepoWithToken(orgSlug, repoName, apiToken) {
6035
6084
  // Lazily access constants.spinner.
6036
6085
  const {
6037
6086
  spinner
6038
6087
  } = constants;
6039
6088
  spinner.start('Deleting repository...');
6040
- const socketSdk = await index.setupSdk(apiToken);
6089
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
6041
6090
  const result = await handleApiCall(socketSdk.deleteOrgRepo(orgSlug, repoName), 'deleting repository');
6042
- if (result.success) {
6043
- spinner.successAndStop('Repository deleted successfully');
6044
- } else {
6045
- handleUnsuccessfulApiResponse('deleteOrgRepo', result, spinner);
6091
+ if (!result.success) {
6092
+ handleUnsuccessfulApiResponse('deleteOrgRepo', result);
6093
+ return;
6046
6094
  }
6095
+ spinner.successAndStop('Repository deleted successfully');
6047
6096
  }
6048
6097
 
6049
6098
  const {
@@ -6087,7 +6136,7 @@ async function run$a(argv, importMeta, {
6087
6136
  // options or missing arguments.
6088
6137
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
6089
6138
  process.exitCode = 2;
6090
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6139
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6091
6140
 
6092
6141
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
6093
6142
 
@@ -6100,20 +6149,37 @@ async function run$a(argv, importMeta, {
6100
6149
  logger.logger.log(DRY_RUN_BAIL_TEXT$a);
6101
6150
  return;
6102
6151
  }
6103
- const apiToken = index.getDefaultToken();
6104
- if (!apiToken) {
6105
- 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.');
6106
- }
6107
- await deleteRepo(orgSlug, repoName, apiToken);
6152
+ await deleteRepo(orgSlug, repoName);
6108
6153
  }
6109
6154
 
6110
6155
  // @ts-ignore
6111
6156
  async function listRepos({
6157
+ direction,
6158
+ orgSlug,
6159
+ outputKind,
6160
+ page,
6161
+ per_page,
6162
+ sort
6163
+ }) {
6164
+ const apiToken = shadowNpmInject.getDefaultToken();
6165
+ if (!apiToken) {
6166
+ 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.');
6167
+ }
6168
+ await listReposWithToken({
6169
+ apiToken,
6170
+ direction,
6171
+ orgSlug,
6172
+ outputKind,
6173
+ page,
6174
+ per_page,
6175
+ sort
6176
+ });
6177
+ }
6178
+ async function listReposWithToken({
6112
6179
  apiToken,
6113
6180
  direction,
6114
6181
  orgSlug,
6115
- outputJson,
6116
- outputMarkdown,
6182
+ outputKind,
6117
6183
  page,
6118
6184
  per_page,
6119
6185
  sort
@@ -6122,23 +6188,20 @@ async function listRepos({
6122
6188
  const {
6123
6189
  spinner
6124
6190
  } = constants;
6125
- spinner.start('Listing repositories...');
6126
- const socketSdk = await index.setupSdk(apiToken);
6191
+ spinner.start('Fetching list of repositories...');
6192
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
6127
6193
  const result = await handleApiCall(socketSdk.getOrgRepoList(orgSlug, {
6128
- outputJson,
6129
- outputMarkdown,
6130
- orgSlug,
6131
6194
  sort,
6132
6195
  direction,
6133
6196
  per_page,
6134
6197
  page
6135
6198
  }), 'listing repositories');
6136
6199
  if (!result.success) {
6137
- handleUnsuccessfulApiResponse('getOrgRepoList', result, spinner);
6200
+ handleUnsuccessfulApiResponse('getOrgRepoList', result);
6138
6201
  return;
6139
6202
  }
6140
- spinner.stop();
6141
- if (outputJson) {
6203
+ spinner.stop('Fetch complete.');
6204
+ if (outputKind === 'json') {
6142
6205
  const data = result.data.results.map(o => ({
6143
6206
  id: o.id,
6144
6207
  name: o.name,
@@ -6235,7 +6298,7 @@ async function run$9(argv, importMeta, {
6235
6298
  // options or missing arguments.
6236
6299
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
6237
6300
  process.exitCode = 2;
6238
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6301
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6239
6302
 
6240
6303
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
6241
6304
 
@@ -6246,30 +6309,44 @@ async function run$9(argv, importMeta, {
6246
6309
  logger.logger.log(DRY_RUN_BAIL_TEXT$9);
6247
6310
  return;
6248
6311
  }
6249
- const apiToken = index.getDefaultToken();
6250
- if (!apiToken) {
6251
- 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.');
6252
- }
6253
6312
  await listRepos({
6254
- apiToken,
6255
- outputJson: Boolean(cli.flags['json']),
6256
- outputMarkdown: Boolean(cli.flags['markdown']),
6257
- orgSlug,
6258
- sort: String(cli.flags['sort'] || 'created_at'),
6259
6313
  direction: cli.flags['direction'] === 'asc' ? 'asc' : 'desc',
6314
+ orgSlug,
6315
+ outputKind: cli.flags['json'] ? 'json' : cli.flags['markdown'] ? 'markdown' : 'print',
6260
6316
  page: Number(cli.flags['page']) || 1,
6261
- per_page: Number(cli.flags['perPage']) || 30
6317
+ per_page: Number(cli.flags['perPage']) || 30,
6318
+ sort: String(cli.flags['sort'] || 'created_at')
6262
6319
  });
6263
6320
  }
6264
6321
 
6265
6322
  async function updateRepo({
6323
+ default_branch,
6324
+ description,
6325
+ homepage,
6326
+ orgSlug,
6327
+ repoName,
6328
+ visibility
6329
+ }) {
6330
+ const apiToken = shadowNpmInject.getDefaultToken();
6331
+ if (!apiToken) {
6332
+ 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.');
6333
+ }
6334
+ await updateRepoWithToken({
6335
+ apiToken,
6336
+ default_branch,
6337
+ description,
6338
+ homepage,
6339
+ orgSlug,
6340
+ repoName,
6341
+ visibility
6342
+ });
6343
+ }
6344
+ async function updateRepoWithToken({
6266
6345
  apiToken,
6267
6346
  default_branch,
6268
6347
  description,
6269
6348
  homepage,
6270
6349
  orgSlug,
6271
- outputJson,
6272
- outputMarkdown,
6273
6350
  repoName,
6274
6351
  visibility
6275
6352
  }) {
@@ -6278,10 +6355,8 @@ async function updateRepo({
6278
6355
  spinner
6279
6356
  } = constants;
6280
6357
  spinner.start('Updating repository...');
6281
- const socketSdk = await index.setupSdk(apiToken);
6358
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
6282
6359
  const result = await handleApiCall(socketSdk.updateOrgRepo(orgSlug, repoName, {
6283
- outputJson,
6284
- outputMarkdown,
6285
6360
  orgSlug,
6286
6361
  name: repoName,
6287
6362
  description,
@@ -6289,11 +6364,11 @@ async function updateRepo({
6289
6364
  default_branch,
6290
6365
  visibility
6291
6366
  }), 'updating repository');
6292
- if (result.success) {
6293
- spinner.successAndStop('Repository updated successfully');
6294
- } else {
6295
- handleUnsuccessfulApiResponse('updateOrgRepo', result, spinner);
6367
+ if (!result.success) {
6368
+ handleUnsuccessfulApiResponse('updateOrgRepo', result);
6369
+ return;
6296
6370
  }
6371
+ spinner.successAndStop('Repository updated successfully');
6297
6372
  }
6298
6373
 
6299
6374
  const {
@@ -6305,7 +6380,6 @@ const config$8 = {
6305
6380
  hidden: false,
6306
6381
  flags: {
6307
6382
  ...commonFlags,
6308
- ...outputFlags,
6309
6383
  repoName: {
6310
6384
  type: 'string',
6311
6385
  shortFlag: 'n',
@@ -6369,7 +6443,7 @@ async function run$8(argv, importMeta, {
6369
6443
  // options or missing arguments.
6370
6444
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
6371
6445
  process.exitCode = 2;
6372
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6446
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6373
6447
 
6374
6448
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
6375
6449
 
@@ -6382,14 +6456,7 @@ async function run$8(argv, importMeta, {
6382
6456
  logger.logger.log(DRY_RUN_BAIL_TEXT$8);
6383
6457
  return;
6384
6458
  }
6385
- const apiToken = index.getDefaultToken();
6386
- if (!apiToken) {
6387
- 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.');
6388
- }
6389
6459
  await updateRepo({
6390
- apiToken,
6391
- outputJson: Boolean(cli.flags['json']),
6392
- outputMarkdown: Boolean(cli.flags['markdown']),
6393
6460
  orgSlug,
6394
6461
  repoName,
6395
6462
  description: String(cli.flags['repoDescription'] || ''),
@@ -6400,16 +6467,45 @@ async function run$8(argv, importMeta, {
6400
6467
  }
6401
6468
 
6402
6469
  // @ts-ignore
6403
- async function viewRepo(orgSlug, repoName, apiToken) {
6470
+ async function viewRepo(orgSlug, repoName, outputKind) {
6471
+ const apiToken = shadowNpmInject.getDefaultToken();
6472
+ if (!apiToken) {
6473
+ 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.');
6474
+ }
6475
+ await viewRepoWithToken(orgSlug, repoName, apiToken, outputKind);
6476
+ }
6477
+ async function viewRepoWithToken(orgSlug, repoName, apiToken, outputKind) {
6404
6478
  // Lazily access constants.spinner.
6405
6479
  const {
6406
6480
  spinner
6407
6481
  } = constants;
6408
- spinner.start('Fetching repository...');
6409
- const socketSdk = await index.setupSdk(apiToken);
6482
+ spinner.start('Fetching repository data...');
6483
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
6410
6484
  const result = await handleApiCall(socketSdk.getOrgRepo(orgSlug, repoName), 'fetching repository');
6411
6485
  if (!result.success) {
6412
- handleUnsuccessfulApiResponse('getOrgRepo', result, spinner);
6486
+ handleUnsuccessfulApiResponse('getOrgRepo', result);
6487
+ return;
6488
+ }
6489
+ spinner.stop('Fetched repository data.');
6490
+ if (outputKind === 'json') {
6491
+ const {
6492
+ archived,
6493
+ created_at,
6494
+ default_branch,
6495
+ homepage,
6496
+ id,
6497
+ name,
6498
+ visibility
6499
+ } = result.data;
6500
+ logger.logger.log(JSON.stringify({
6501
+ id,
6502
+ name,
6503
+ visibility,
6504
+ default_branch,
6505
+ homepage,
6506
+ archived,
6507
+ created_at
6508
+ }, null, 2));
6413
6509
  return;
6414
6510
  }
6415
6511
  const options = {
@@ -6436,7 +6532,7 @@ async function viewRepo(orgSlug, repoName, apiToken) {
6436
6532
  name: colors.magenta('Created at')
6437
6533
  }]
6438
6534
  };
6439
- spinner.stop(chalkTable(options, [result.data]));
6535
+ logger.logger.log(chalkTable(options, [result.data]));
6440
6536
  }
6441
6537
 
6442
6538
  const {
@@ -6448,7 +6544,12 @@ const config$7 = {
6448
6544
  hidden: false,
6449
6545
  flags: {
6450
6546
  ...commonFlags,
6451
- ...outputFlags
6547
+ ...outputFlags,
6548
+ repoName: {
6549
+ description: 'The repository to check',
6550
+ default: '',
6551
+ type: 'string'
6552
+ }
6452
6553
  },
6453
6554
  help: (command, config) => `
6454
6555
  Usage
@@ -6482,7 +6583,7 @@ async function run$7(argv, importMeta, {
6482
6583
  // options or missing arguments.
6483
6584
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
6484
6585
  process.exitCode = 2;
6485
- logger.logger.error(commonTags.stripIndents`
6586
+ logger.logger.fail(commonTags.stripIndents`
6486
6587
  ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6487
6588
 
6488
6589
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
@@ -6495,11 +6596,7 @@ async function run$7(argv, importMeta, {
6495
6596
  logger.logger.log(DRY_RUN_BAIL_TEXT$7);
6496
6597
  return;
6497
6598
  }
6498
- const apiToken = index.getDefaultToken();
6499
- if (!apiToken) {
6500
- 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.');
6501
- }
6502
- await viewRepo(orgSlug, repoName, apiToken);
6599
+ await viewRepo(orgSlug, repoName, cli.flags['json'] ? 'json' : cli.flags['markdown'] ? 'markdown' : 'print');
6503
6600
  }
6504
6601
 
6505
6602
  const description$1 = 'Repositories related commands';
@@ -6684,10 +6781,10 @@ async function createFullScan({
6684
6781
  const {
6685
6782
  spinner
6686
6783
  } = constants;
6687
- const socketSdk = await index.setupSdk();
6784
+ const socketSdk = await shadowNpmInject.setupSdk();
6688
6785
  const supportedFiles = await socketSdk.getReportSupportedFiles().then(res => {
6689
6786
  if (!res.success) {
6690
- handleUnsuccessfulApiResponse('getReportSupportedFiles', res, spinner);
6787
+ handleUnsuccessfulApiResponse('getReportSupportedFiles', res);
6691
6788
  assert(false, 'handleUnsuccessfulApiResponse should unconditionally throw');
6692
6789
  }
6693
6790
  return res.data;
@@ -6705,46 +6802,53 @@ async function createFullScan({
6705
6802
  targets = received ?? [];
6706
6803
  updatedInput = true;
6707
6804
  }
6708
- const packagePaths = await npmPaths.getPackageFilesFullScans(cwd, targets, supportedFiles);
6805
+
6806
+ // // TODO: we'll probably use socket.json or something else soon...
6807
+ // const absoluteConfigPath = path.join(cwd, 'socket.yml')
6808
+ // const socketConfig = await getSocketConfig(absoluteConfigPath)
6809
+
6810
+ const packagePaths = await shadowNpmPaths.getPackageFilesFullScans(cwd, targets, supportedFiles
6811
+ // socketConfig
6812
+ );
6709
6813
 
6710
6814
  // We're going to need an api token to suggest data because those suggestions
6711
6815
  // must come from data we already know. Don't error on missing api token yet.
6712
6816
  // If the api-token is not set, ignore it for the sake of suggestions.
6713
- const apiToken = index.getDefaultToken();
6714
- if (apiToken && !orgSlug) {
6715
- const suggestion = await suggestOrgSlug(socketSdk);
6716
- if (suggestion) orgSlug = suggestion;
6717
- updatedInput = true;
6718
- }
6817
+ const apiToken = shadowNpmInject.getDefaultToken();
6719
6818
 
6720
6819
  // If the current cwd is unknown and is used as a repo slug anyways, we will
6721
6820
  // first need to register the slug before we can use it.
6722
6821
  let repoDefaultBranch = '';
6723
-
6724
- // (Don't bother asking for the rest if we didn't get an org slug above)
6725
- if (apiToken && orgSlug && !repoName) {
6726
- const suggestion = await suggestRepoSlug(socketSdk, orgSlug);
6727
- if (suggestion) {
6728
- ({
6729
- defaultBranch: repoDefaultBranch,
6730
- slug: repoName
6731
- } = suggestion);
6822
+ if (apiToken) {
6823
+ if (!orgSlug) {
6824
+ const suggestion = await suggestOrgSlug(socketSdk);
6825
+ if (suggestion) orgSlug = suggestion;
6826
+ updatedInput = true;
6827
+ }
6828
+
6829
+ // (Don't bother asking for the rest if we didn't get an org slug above)
6830
+ if (orgSlug && !repoName) {
6831
+ const suggestion = await suggestRepoSlug(socketSdk, orgSlug);
6832
+ if (suggestion) {
6833
+ repoDefaultBranch = suggestion.defaultBranch;
6834
+ repoName = suggestion.slug;
6835
+ }
6836
+ updatedInput = true;
6732
6837
  }
6733
- updatedInput = true;
6734
- }
6735
6838
 
6736
- // (Don't bother asking for the rest if we didn't get an org/repo above)
6737
- if (apiToken && orgSlug && repoName && !branchName) {
6738
- const suggestion = await suggestBranchSlug(repoDefaultBranch);
6739
- if (suggestion) branchName = suggestion;
6740
- updatedInput = true;
6839
+ // (Don't bother asking for the rest if we didn't get an org/repo above)
6840
+ if (orgSlug && repoName && !branchName) {
6841
+ const suggestion = await suggestBranchSlug(repoDefaultBranch);
6842
+ if (suggestion) branchName = suggestion;
6843
+ updatedInput = true;
6844
+ }
6741
6845
  }
6742
6846
  if (!orgSlug || !repoName || !branchName || !packagePaths.length) {
6743
6847
  // Use exit status of 2 to indicate incorrect usage, generally invalid
6744
6848
  // options or missing arguments.
6745
6849
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
6746
6850
  process$1.exitCode = 2;
6747
- logger.logger.error(commonTags.stripIndents`
6851
+ logger.logger.fail(commonTags.stripIndents`
6748
6852
  ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6749
6853
 
6750
6854
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
@@ -6766,13 +6870,13 @@ async function createFullScan({
6766
6870
  logger.logger.log('```');
6767
6871
  }
6768
6872
  if (!apiToken) {
6769
- 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.');
6873
+ 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.');
6770
6874
  }
6771
6875
  if (readOnly) {
6772
6876
  logger.logger.log('[ReadOnly] Bailing now');
6773
6877
  return;
6774
6878
  }
6775
- spinner.start('Creating a scan...');
6879
+ spinner.start(`Creating a scan with ${packagePaths.length} packages...`);
6776
6880
  const result = await handleApiCall(socketSdk.createOrgFullScan(orgSlug, {
6777
6881
  repo: repoName,
6778
6882
  branch: branchName,
@@ -6782,7 +6886,7 @@ async function createFullScan({
6782
6886
  tmp
6783
6887
  }, packagePaths, cwd), 'Creating scan');
6784
6888
  if (!result.success) {
6785
- handleUnsuccessfulApiResponse('CreateOrgFullScan', result, spinner);
6889
+ handleUnsuccessfulApiResponse('CreateOrgFullScan', result);
6786
6890
  return;
6787
6891
  }
6788
6892
  spinner.successAndStop('Scan created successfully');
@@ -6872,13 +6976,29 @@ const config$6 = {
6872
6976
  shortFlag: 't',
6873
6977
  default: false,
6874
6978
  description: 'Set the visibility (true/false) of the scan in your dashboard'
6979
+ },
6980
+ view: {
6981
+ type: 'boolean',
6982
+ shortFlag: 'v',
6983
+ default: true,
6984
+ description: 'Will wait for and return the created report. Use --no-view to disable.'
6875
6985
  }
6876
6986
  },
6987
+ // TODO: your project's "socket.yml" file's "projectIgnorePaths"
6877
6988
  help: (command, config) => `
6878
6989
  Usage
6879
6990
  $ ${command} [...options] <org> <TARGET> [TARGET...]
6880
6991
 
6881
- Where TARGET is a FILE or DIR that _must_ be inside the CWD.
6992
+ Uploads the specified "package.json" and lock files for JavaScript, Python,
6993
+ Go, Scala, Gradle, and Kotlin dependency manifests.
6994
+ If any folder is specified, the ones found in there recursively are uploaded.
6995
+
6996
+ Supports globbing such as "**/package.json", "**/requirements.txt", etc.
6997
+
6998
+ Ignores any file specified in your project's ".gitignore" and also has a
6999
+ sensible set of default ignores from the "ignore-by-default" module.
7000
+
7001
+ TARGET should be a FILE or DIR that _must_ be inside the CWD.
6882
7002
 
6883
7003
  When a FILE is given only that FILE is targeted. Otherwise any eligible
6884
7004
  files in the given DIR will be considered.
@@ -6910,15 +7030,17 @@ async function run$6(argv, importMeta, {
6910
7030
  branch: branchName,
6911
7031
  repo: repoName
6912
7032
  } = cli.flags;
6913
- const apiToken = index.getDefaultToken();
7033
+ const apiToken = shadowNpmInject.getDefaultToken(); // This checks if we _can_ suggest anything
7034
+
6914
7035
  if (!apiToken && (!orgSlug || !repoName || !branchName || !targets.length)) {
6915
7036
  // Without api token we cannot recover because we can't request more info
6916
7037
  // from the server, to match and help with the current cwd/git status.
7038
+ //
6917
7039
  // Use exit status of 2 to indicate incorrect usage, generally invalid
6918
7040
  // options or missing arguments.
6919
7041
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
6920
7042
  process$1.exitCode = 2;
6921
- logger.logger.error(commonTags.stripIndents`
7043
+ logger.logger.fail(commonTags.stripIndents`
6922
7044
  ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6923
7045
 
6924
7046
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
@@ -6956,16 +7078,23 @@ async function run$6(argv, importMeta, {
6956
7078
  });
6957
7079
  }
6958
7080
 
6959
- async function deleteOrgFullScan(orgSlug, fullScanId, apiToken) {
7081
+ async function deleteOrgFullScan(orgSlug, fullScanId) {
7082
+ const apiToken = shadowNpmInject.getDefaultToken();
7083
+ if (!apiToken) {
7084
+ 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.');
7085
+ }
7086
+ await deleteOrgFullScanWithToken(orgSlug, fullScanId, apiToken);
7087
+ }
7088
+ async function deleteOrgFullScanWithToken(orgSlug, fullScanId, apiToken) {
6960
7089
  // Lazily access constants.spinner.
6961
7090
  const {
6962
7091
  spinner
6963
7092
  } = constants;
6964
7093
  spinner.start('Deleting scan...');
6965
- const socketSdk = await index.setupSdk(apiToken);
7094
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
6966
7095
  const result = await handleApiCall(socketSdk.deleteOrgFullScan(orgSlug, fullScanId), 'Deleting scan');
6967
7096
  if (!result.success) {
6968
- handleUnsuccessfulApiResponse('deleteOrgFullScan', result, spinner);
7097
+ handleUnsuccessfulApiResponse('deleteOrgFullScan', result);
6969
7098
  return;
6970
7099
  }
6971
7100
  spinner.successAndStop('Scan deleted successfully');
@@ -7013,7 +7142,7 @@ async function run$5(argv, importMeta, {
7013
7142
  // options or missing arguments.
7014
7143
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
7015
7144
  process.exitCode = 2;
7016
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
7145
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
7017
7146
 
7018
7147
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
7019
7148
 
@@ -7024,24 +7153,64 @@ async function run$5(argv, importMeta, {
7024
7153
  logger.logger.log(DRY_RUN_BAIL_TEXT$5);
7025
7154
  return;
7026
7155
  }
7027
- const apiToken = index.getDefaultToken();
7028
- if (!apiToken) {
7029
- 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.');
7030
- }
7031
- await deleteOrgFullScan(orgSlug, fullScanId, apiToken);
7156
+ await deleteOrgFullScan(orgSlug, fullScanId);
7032
7157
  }
7033
7158
 
7034
7159
  // @ts-ignore
7035
- async function listFullScans(orgSlug, input, apiToken) {
7160
+ async function listFullScans({
7161
+ direction,
7162
+ from_time,
7163
+ orgSlug,
7164
+ outputKind,
7165
+ page,
7166
+ per_page,
7167
+ sort
7168
+ }) {
7169
+ const apiToken = shadowNpmInject.getDefaultToken();
7170
+ if (!apiToken) {
7171
+ 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.');
7172
+ }
7173
+ await listFullScansWithToken({
7174
+ apiToken,
7175
+ direction,
7176
+ from_time,
7177
+ orgSlug,
7178
+ outputKind,
7179
+ page,
7180
+ per_page,
7181
+ sort
7182
+ });
7183
+ }
7184
+ async function listFullScansWithToken({
7185
+ apiToken,
7186
+ direction,
7187
+ from_time,
7188
+ orgSlug,
7189
+ outputKind,
7190
+ page,
7191
+ per_page,
7192
+ sort
7193
+ }) {
7036
7194
  // Lazily access constants.spinner.
7037
7195
  const {
7038
7196
  spinner
7039
7197
  } = constants;
7040
- spinner.start('Listing scans...');
7041
- const socketSdk = await index.setupSdk(apiToken);
7042
- const result = await handleApiCall(socketSdk.getOrgFullScanList(orgSlug, input), 'Listing scans');
7198
+ spinner.start('Fetching list of scans...');
7199
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
7200
+ const result = await handleApiCall(socketSdk.getOrgFullScanList(orgSlug, {
7201
+ sort,
7202
+ direction,
7203
+ per_page,
7204
+ page,
7205
+ from: from_time
7206
+ }), 'Listing scans');
7043
7207
  if (!result.success) {
7044
- handleUnsuccessfulApiResponse('getOrgFullScanList', result, spinner);
7208
+ handleUnsuccessfulApiResponse('getOrgFullScanList', result);
7209
+ return;
7210
+ }
7211
+ spinner.stop(`Fetch complete`);
7212
+ if (outputKind === 'json') {
7213
+ logger.logger.log(result.data);
7045
7214
  return;
7046
7215
  }
7047
7216
  const options = {
@@ -7071,7 +7240,6 @@ async function listFullScans(orgSlug, input, apiToken) {
7071
7240
  branch: d.branch
7072
7241
  };
7073
7242
  });
7074
- spinner.stop(`Listing scans for: ${orgSlug}`);
7075
7243
  logger.logger.log(chalkTable(options, formattedResults));
7076
7244
  }
7077
7245
 
@@ -7153,7 +7321,7 @@ async function run$4(argv, importMeta, {
7153
7321
  // options or missing arguments.
7154
7322
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
7155
7323
  process.exitCode = 2;
7156
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
7324
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
7157
7325
 
7158
7326
  - Org name as the argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}`);
7159
7327
  return;
@@ -7162,39 +7330,55 @@ async function run$4(argv, importMeta, {
7162
7330
  logger.logger.log(DRY_RUN_BAIL_TEXT$4);
7163
7331
  return;
7164
7332
  }
7165
- const apiToken = index.getDefaultToken();
7166
- if (!apiToken) {
7167
- 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.');
7168
- }
7169
- await listFullScans(orgSlug,
7170
- // TODO: refine this object to what we need
7171
- {
7172
- outputJson: cli.flags['json'],
7173
- outputMarkdown: cli.flags['markdown'],
7333
+ await listFullScans({
7334
+ direction: String(cli.flags['direction'] || ''),
7335
+ from_time: String(cli.flags['fromTime'] || ''),
7174
7336
  orgSlug,
7175
- sort: cli.flags['sort'],
7176
- direction: cli.flags['direction'],
7177
- per_page: cli.flags['perPage'],
7178
- page: cli.flags['page'],
7179
- from_time: cli.flags['fromTime'],
7180
- until_time: cli.flags['untilTime']
7181
- }, apiToken);
7337
+ outputKind: cli.flags['json'] ? 'json' : cli.flags['markdown'] ? 'markdown' : 'print',
7338
+ page: Number(cli.flags['page'] || 1),
7339
+ per_page: Number(cli.flags['perPage'] || 30),
7340
+ sort: String(cli.flags['sort'] || '')
7341
+ });
7182
7342
  }
7183
7343
 
7184
- async function getOrgScanMetadata(orgSlug, scanId, apiToken) {
7344
+ async function getOrgScanMetadata(orgSlug, scanId, outputKind) {
7345
+ const apiToken = shadowNpmInject.getDefaultToken();
7346
+ if (!apiToken) {
7347
+ 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.');
7348
+ }
7349
+ await getOrgScanMetadataWithToken(orgSlug, scanId, apiToken, outputKind);
7350
+ }
7351
+ async function getOrgScanMetadataWithToken(orgSlug, scanId, apiToken, outputKind) {
7185
7352
  // Lazily access constants.spinner.
7186
7353
  const {
7187
7354
  spinner
7188
7355
  } = constants;
7189
- spinner.start("Getting scan's metadata...");
7190
- const socketSdk = await index.setupSdk(apiToken);
7356
+ spinner.start('Fetching meta data for a full scan...');
7357
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
7191
7358
  const result = await handleApiCall(socketSdk.getOrgFullScanMetadata(orgSlug, scanId), 'Listing scans');
7192
7359
  if (!result.success) {
7193
- handleUnsuccessfulApiResponse('getOrgFullScanMetadata', result, spinner);
7360
+ handleUnsuccessfulApiResponse('getOrgFullScanMetadata', result);
7194
7361
  return;
7195
7362
  }
7196
- spinner.stop('Scan metadata:');
7197
- logger.logger.log(result.data);
7363
+ spinner?.successAndStop('Fetched the meta data\n');
7364
+ if (outputKind === 'json') {
7365
+ logger.logger.log(result.data);
7366
+ } else {
7367
+ // Markdown = print
7368
+ if (outputKind === 'markdown') {
7369
+ logger.logger.log('# Scan meta data\n');
7370
+ }
7371
+ logger.logger.log(`Scan ID: ${scanId}\n`);
7372
+ for (const [key, value] of Object.entries(result.data)) {
7373
+ if (['id', 'updated_at', 'organization_id', 'repository_id', 'commit_hash', 'html_report_url'].includes(key)) continue;
7374
+ logger.logger.log(`- ${key}:`, value);
7375
+ }
7376
+ if (outputKind === 'markdown') {
7377
+ logger.logger.log(`\nYou can view this report at: [${result.data.html_report_url}](${result.data.html_report_url})\n`);
7378
+ } else {
7379
+ logger.logger.log(`\nYou can view this report at: ${result.data.html_report_url}]\n`);
7380
+ }
7381
+ }
7198
7382
  }
7199
7383
 
7200
7384
  const {
@@ -7239,7 +7423,7 @@ async function run$3(argv, importMeta, {
7239
7423
  // options or missing arguments.
7240
7424
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
7241
7425
  process.exitCode = 2;
7242
- logger.logger.error(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
7426
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
7243
7427
 
7244
7428
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
7245
7429
 
@@ -7250,35 +7434,106 @@ async function run$3(argv, importMeta, {
7250
7434
  logger.logger.log(DRY_RUN_BAIL_TEXT$3);
7251
7435
  return;
7252
7436
  }
7253
- const apiToken = index.getDefaultToken();
7437
+ await getOrgScanMetadata(orgSlug, fullScanId, cli.flags['json'] ? 'json' : cli.flags['markdown'] ? 'markdown' : 'print');
7438
+ }
7439
+
7440
+ async function streamFullScan(orgSlug, fullScanId, file) {
7441
+ // Lazily access constants.spinner.
7442
+ const {
7443
+ spinner
7444
+ } = constants;
7445
+ const apiToken = shadowNpmInject.getDefaultToken();
7254
7446
  if (!apiToken) {
7255
- 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.');
7447
+ 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.');
7256
7448
  }
7257
- await getOrgScanMetadata(orgSlug, fullScanId, apiToken);
7449
+ spinner.start('Fetching scan...');
7450
+ const socketSdk = await shadowNpmInject.setupSdk(apiToken);
7451
+ const data = await handleApiCall(socketSdk.getOrgFullScan(orgSlug, fullScanId, file === '-' ? undefined : file), 'Fetching a scan');
7452
+ if (!data?.success) {
7453
+ handleUnsuccessfulApiResponse('getOrgFullScan', data);
7454
+ return;
7455
+ }
7456
+ spinner?.successAndStop(file ? `Full scan details written to ${file}` : 'stdout');
7457
+ return data;
7258
7458
  }
7259
7459
 
7260
- async function getFullScan(orgSlug, fullScanId, file, apiToken) {
7460
+ async function getFullScan(orgSlug, fullScanId) {
7261
7461
  // Lazily access constants.spinner.
7262
7462
  const {
7263
7463
  spinner
7264
7464
  } = constants;
7265
- spinner.start('Streaming scan...');
7266
- const socketSdk = await index.setupSdk(apiToken);
7267
- const data = await handleApiCall(socketSdk.getOrgFullScan(orgSlug, fullScanId, file === '-' ? undefined : file), 'Streaming a scan');
7268
- if (data?.success) {
7269
- spinner.stop(file ? `Full scan details written to ${file}` : '');
7270
- } else {
7271
- handleUnsuccessfulApiResponse('getOrgFullScan', data, spinner);
7465
+ const apiToken = shadowNpmInject.getDefaultToken();
7466
+ if (!apiToken) {
7467
+ 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.');
7272
7468
  }
7469
+ spinner.start('Fetching full-scan...');
7470
+ const response = await queryAPI(`orgs/${orgSlug}/full-scans/${encodeURIComponent(fullScanId)}`, apiToken);
7471
+ spinner.stop('Fetch complete.');
7472
+ if (!response.ok) {
7473
+ const err = await handleAPIError(response.status);
7474
+ logger.logger.fail(`${colors.bgRed(colors.white(response.statusText))}: Fetch error: ${err}`);
7475
+ return;
7476
+ }
7477
+
7478
+ // This is nd-json; each line is a json object
7479
+ const jsons = await response.text();
7480
+ const lines = jsons.split('\n').filter(Boolean);
7481
+ const data = lines.map(line => {
7482
+ try {
7483
+ return JSON.parse(line);
7484
+ } catch {
7485
+ console.error('At least one line item was returned that could not be parsed as JSON...');
7486
+ return {};
7487
+ }
7488
+ });
7273
7489
  return data;
7274
7490
  }
7275
7491
 
7492
+ async function viewFullScan(orgSlug, fullScanId, filePath) {
7493
+ const artifacts = await getFullScan(orgSlug, fullScanId);
7494
+ if (!artifacts) return;
7495
+ const display = artifacts.map(art => {
7496
+ const author = Array.isArray(art.author) ? `${art.author[0]}${art.author.length > 1 ? ' et.al.' : ''}` : art.author;
7497
+ return {
7498
+ type: art.type,
7499
+ name: art.name,
7500
+ version: art.version,
7501
+ author,
7502
+ score: JSON.stringify(art.score)
7503
+ };
7504
+ });
7505
+ const md = mdTable(display, ['type', 'version', 'name', 'author', 'score']);
7506
+ const report = `
7507
+ # Scan Details
7508
+
7509
+ These are the artifacts and their scores found.
7510
+
7511
+ Sscan ID: ${fullScanId}
7512
+
7513
+ ${md}
7514
+
7515
+ View this report at: https://socket.dev/dashboard/org/${orgSlug}/sbom/${fullScanId}
7516
+ `.trim() + '\n';
7517
+ if (filePath && filePath !== '-') {
7518
+ try {
7519
+ await fs$1.writeFile(filePath, report, 'utf8');
7520
+ logger.logger.log(`Data successfully written to ${filePath}`);
7521
+ } catch (e) {
7522
+ process.exitCode = 1;
7523
+ logger.logger.fail('There was an error trying to write the json to disk');
7524
+ logger.logger.error(e);
7525
+ }
7526
+ } else {
7527
+ logger.logger.log(report);
7528
+ }
7529
+ }
7530
+
7276
7531
  const {
7277
7532
  DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$2
7278
7533
  } = constants;
7279
7534
  const config$2 = {
7280
- commandName: 'stream',
7281
- description: 'Stream the output of a scan',
7535
+ commandName: 'view',
7536
+ description: 'View the raw results of a scan',
7282
7537
  hidden: false,
7283
7538
  flags: {
7284
7539
  ...commonFlags,
@@ -7297,7 +7552,7 @@ const config$2 = {
7297
7552
  $ ${command} FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0 ./stream.txt
7298
7553
  `
7299
7554
  };
7300
- const cmdScanStream = {
7555
+ const cmdScanView = {
7301
7556
  description: config$2.description,
7302
7557
  hidden: config$2.hidden,
7303
7558
  run: run$2
@@ -7317,7 +7572,7 @@ async function run$2(argv, importMeta, {
7317
7572
  // options or missing arguments.
7318
7573
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
7319
7574
  process.exitCode = 2;
7320
- logger.logger.error(commonTags.stripIndents`
7575
+ logger.logger.fail(commonTags.stripIndents`
7321
7576
  ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
7322
7577
 
7323
7578
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
@@ -7330,14 +7585,14 @@ async function run$2(argv, importMeta, {
7330
7585
  logger.logger.log(DRY_RUN_BAIL_TEXT$2);
7331
7586
  return;
7332
7587
  }
7333
- const apiToken = index.getDefaultToken();
7334
- if (!apiToken) {
7335
- 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.');
7588
+ if (cli.flags['json']) {
7589
+ await streamFullScan(orgSlug, fullScanId, file);
7590
+ } else {
7591
+ await viewFullScan(orgSlug, fullScanId, file);
7336
7592
  }
7337
- await getFullScan(orgSlug, fullScanId, file, apiToken);
7338
7593
  }
7339
7594
 
7340
- const description = 'Scans related commands';
7595
+ const description = 'Full Scan related commands';
7341
7596
  const cmdScan = {
7342
7597
  description,
7343
7598
  async run(argv, importMeta, {
@@ -7345,11 +7600,19 @@ const cmdScan = {
7345
7600
  }) {
7346
7601
  await meowWithSubcommands({
7347
7602
  create: cmdScanCreate,
7348
- stream: cmdScanStream,
7349
7603
  list: cmdScanList,
7350
7604
  del: cmdScanDel,
7351
- metadata: cmdScanMetadata
7605
+ metadata: cmdScanMetadata,
7606
+ view: cmdScanView
7352
7607
  }, {
7608
+ aliases: {
7609
+ // Backwards compat. TODO: Drop next major bump
7610
+ stream: {
7611
+ description: cmdScanView.description,
7612
+ hidden: true,
7613
+ argv: ['view'] // Original args will be appended (!)
7614
+ }
7615
+ },
7353
7616
  argv,
7354
7617
  description,
7355
7618
  importMeta,
@@ -7501,9 +7764,9 @@ async function run$1(argv, importMeta, {
7501
7764
  logger.logger.log(DRY_RUN_BAIL_TEXT$1);
7502
7765
  return;
7503
7766
  }
7504
- const apiToken = index.getDefaultToken();
7767
+ const apiToken = shadowNpmInject.getDefaultToken();
7505
7768
  if (!apiToken) {
7506
- 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.');
7769
+ 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.');
7507
7770
  }
7508
7771
  await getThreatFeed({
7509
7772
  apiToken,
@@ -7598,7 +7861,7 @@ function askQuestion(rl, query) {
7598
7861
  function removeSocketWrapper(file) {
7599
7862
  return fs.readFile(file, 'utf8', function (err, data) {
7600
7863
  if (err) {
7601
- logger.logger.error('There was an error removing the alias:');
7864
+ logger.logger.fail('There was an error removing the alias:');
7602
7865
  logger.logger.error(err);
7603
7866
  return;
7604
7867
  }
@@ -7675,7 +7938,7 @@ async function run(argv, importMeta, {
7675
7938
  // options or missing arguments.
7676
7939
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
7677
7940
  process.exitCode = 2;
7678
- logger.logger.error(commonTags.stripIndents`
7941
+ logger.logger.fail(commonTags.stripIndents`
7679
7942
  ${colors.bgRed(colors.white('Input error'))}: Please provide the required flags:
7680
7943
 
7681
7944
  - Must use --enabled or --disabled
@@ -7708,7 +7971,7 @@ async function run(argv, importMeta, {
7708
7971
  }
7709
7972
  }
7710
7973
  if (!fs.existsSync(bashRcPath) && !fs.existsSync(zshRcPath)) {
7711
- logger.logger.error('There was an issue setting up the alias in your bash profile');
7974
+ logger.logger.fail('There was an issue setting up the alias in your bash profile');
7712
7975
  }
7713
7976
  }
7714
7977
 
@@ -7767,10 +8030,10 @@ void (async () => {
7767
8030
  let errorBody;
7768
8031
  let errorTitle;
7769
8032
  let errorMessage = '';
7770
- if (e instanceof index.AuthError) {
8033
+ if (e instanceof shadowNpmInject.AuthError) {
7771
8034
  errorTitle = 'Authentication error';
7772
8035
  errorMessage = e.message;
7773
- } else if (e instanceof index.InputError) {
8036
+ } else if (e instanceof shadowNpmInject.InputError) {
7774
8037
  errorTitle = 'Invalid input';
7775
8038
  errorMessage = e.message;
7776
8039
  errorBody = e.body;
@@ -7781,12 +8044,12 @@ void (async () => {
7781
8044
  } else {
7782
8045
  errorTitle = 'Unexpected error with no details';
7783
8046
  }
7784
- logger.logger.error(`${colors.bgRed(colors.white(errorTitle + ':'))} ${errorMessage}`);
8047
+ logger.logger.fail(`${colors.bgRed(colors.white(errorTitle + ':'))} ${errorMessage}`);
7785
8048
  if (errorBody) {
7786
8049
  logger.logger.error(`\n${errorBody}`);
7787
8050
  }
7788
- await index.captureException(e);
8051
+ await shadowNpmInject.captureException(e);
7789
8052
  }
7790
8053
  })();
7791
- //# debugId=b11caea8-68eb-4110-977e-c8cc2d1f4464
8054
+ //# debugId=da32be80-6a12-4a4c-b9c4-0cfdd490ce52
7792
8055
  //# sourceMappingURL=cli.js.map