socket 0.14.49 → 0.14.50

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.
@@ -58,8 +58,10 @@ var npmPaths = require('./npm-paths.js');
58
58
  var npm$1 = require('./npm.js');
59
59
  var betterAjvErrors = _socketInterop(require('@apideck/better-ajv-errors'));
60
60
  var config$A = require('@socketsecurity/config');
61
+ var assert = require('node:assert');
61
62
  var readline = require('node:readline/promises');
62
63
  var open = _socketInterop(require('open'));
64
+ var node_child_process = require('node:child_process');
63
65
  var TableWidget = _socketInterop(require('blessed-contrib/lib/widget/table'));
64
66
  var readline$1 = require('node:readline');
65
67
 
@@ -1296,7 +1298,7 @@ function handleUnsuccessfulApiResponse(_name, result, spinner) {
1296
1298
  spinner.stop();
1297
1299
  throw new index.AuthError(message);
1298
1300
  }
1299
- spinner.error(`${colors.bgRed(colors.white('API returned an error:'))} ${message}`);
1301
+ spinner.errorAndStop(`${colors.bgRed(colors.white('API returned an error:'))} ${message}`);
1300
1302
  process$1.exit(1);
1301
1303
  }
1302
1304
  async function handleApiCall(value, description) {
@@ -1515,7 +1517,7 @@ function meowOrExit({
1515
1517
  }
1516
1518
  function getAsciiHeader(command) {
1517
1519
  const cliVersion = // The '@rollup/plugin-replace' will replace "process.env['SOCKET_CLI_VERSION_HASH']".
1518
- "0.14.49:216163f:fdc0b2b7:pub";
1520
+ "0.14.50:c8e152a:9d057324:pub";
1519
1521
  const nodeVersion = process.version;
1520
1522
  const apiToken = index.getSetting('apiToken');
1521
1523
  const shownToken = apiToken ? getLastFiveOfApiToken(apiToken) : 'no';
@@ -2343,7 +2345,7 @@ async function getDiffScan({
2343
2345
  const data = await response.json();
2344
2346
  if (!response.ok) {
2345
2347
  const err = await handleAPIError(response.status);
2346
- spinner$1.error(`${colors.bgRed(colors.white(response.statusText))}: ${err}`);
2348
+ spinner$1.errorAndStop(`${colors.bgRed(colors.white(response.statusText))}: ${err}`);
2347
2349
  return;
2348
2350
  }
2349
2351
  spinner$1.stop();
@@ -2559,7 +2561,7 @@ async function runFix() {
2559
2561
  // eslint-disable-next-line no-await-in-loop
2560
2562
  await editablePkgJson.save();
2561
2563
  } catch {
2562
- spinner$1.error(`Reverting ${name} to ${oldVersion}`);
2564
+ spinner$1.errorAndStop(`Reverting ${name} to ${oldVersion}`);
2563
2565
  spinner$1.start();
2564
2566
  arb.idealTree = revertToIdealTree;
2565
2567
  }
@@ -2739,7 +2741,7 @@ function formatPackageInfo({
2739
2741
  spinner[strict ? 'error' : 'success'](`Package has these issues: ${formatSeverityCount(severityCount)}`);
2740
2742
  formatPackageIssuesDetails(data, outputMarkdown);
2741
2743
  } else {
2742
- spinner.success('Package has no issues');
2744
+ spinner.successAndStop('Package has no issues');
2743
2745
  }
2744
2746
  const format = new index.ColorOrMarkdown(!!outputMarkdown);
2745
2747
  const url = index.getSocketDevPackageOverviewUrl(NPM$c, pkgName, pkgVersion);
@@ -2920,7 +2922,7 @@ async function attemptLogin(apiBaseUrl, apiProxy) {
2920
2922
  orgs = result.data;
2921
2923
  spinner$1.success('API key verified');
2922
2924
  } catch {
2923
- spinner$1.error('Invalid API key');
2925
+ spinner$1.errorAndStop('Invalid API key');
2924
2926
  return;
2925
2927
  }
2926
2928
  const enforcedChoices = Object.values(orgs.organizations).filter(org => org?.plan === 'enterprise').map(org => ({
@@ -2955,9 +2957,9 @@ async function attemptLogin(apiBaseUrl, apiProxy) {
2955
2957
  const oldToken = index.getSetting('apiToken');
2956
2958
  try {
2957
2959
  applyLogin(apiToken, enforcedOrgs, apiBaseUrl, apiProxy);
2958
- spinner$1.success(`API credentials ${oldToken ? 'updated' : 'set'}`);
2960
+ spinner$1.successAndStop(`API credentials ${oldToken ? 'updated' : 'set'}`);
2959
2961
  } catch {
2960
- spinner$1.error(`API login failed`);
2962
+ spinner$1.errorAndStop(`API login failed`);
2961
2963
  }
2962
2964
  }
2963
2965
 
@@ -3099,14 +3101,14 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
3099
3101
  const output = await spawn(bin, commandArgs, {
3100
3102
  cwd: target || '.'
3101
3103
  });
3102
- spinner$1.success();
3104
+ spinner$1.stop();
3103
3105
  if (verbose) {
3104
3106
  console.group('[VERBOSE] gradle stdout:');
3105
3107
  console.log(output);
3106
3108
  console.groupEnd();
3107
3109
  }
3108
3110
  if (output.stderr) {
3109
- spinner$1.error('There were errors while running gradle');
3111
+ spinner$1.errorAndStop('There were errors while running gradle');
3110
3112
  // (In verbose mode, stderr was printed above, no need to repeat it)
3111
3113
  if (!verbose) {
3112
3114
  console.group('[VERBOSE] stderr:');
@@ -3115,6 +3117,8 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
3115
3117
  }
3116
3118
  process.exit(1);
3117
3119
  }
3120
+ spinner$1.start();
3121
+ spinner$1.successAndStop('Executed gradle successfully');
3118
3122
  console.log('Reported exports:');
3119
3123
  output.stdout.replace(/^POM file copied to: (.*)/gm, (_all, fn) => {
3120
3124
  console.log('- ', fn);
@@ -3123,7 +3127,7 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
3123
3127
 
3124
3128
  // const loc = output.stdout?.match(/Wrote (.*?.pom)\n/)?.[1]?.trim()
3125
3129
  // if (!loc) {
3126
- // spinner.error(
3130
+ // spinner.errorAndStop(
3127
3131
  // 'There were no errors from sbt but could not find the location of resulting .pom file either'
3128
3132
  // )
3129
3133
  // process.exit(1)
@@ -3145,11 +3149,11 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
3145
3149
  // }
3146
3150
  // // TODO: do we prefer fs-extra? renaming can be gnarly on windows and fs-extra's version is better
3147
3151
  // await renamep(loc, out)
3148
- // spinner.success()
3152
+ // spinner.successAndStop()
3149
3153
  // spinner.start().success(`OK. File should be available in \`${out}\``)
3150
3154
  // }
3151
3155
  } catch (e) {
3152
- spinner$1.error('There was an unexpected error while running this' + (verbose ? '' : ' (use --verbose for details)'));
3156
+ spinner$1.errorAndStop('There was an unexpected error while running this' + (verbose ? '' : ' (use --verbose for details)'));
3153
3157
  if (verbose) {
3154
3158
  console.group('[VERBOSE] error:');
3155
3159
  console.log(e);
@@ -3324,14 +3328,15 @@ async function convertSbtToMaven(target, bin, out, verbose, sbtOpts) {
3324
3328
  const output = await spawn(bin, ['makePom'].concat(sbtOpts), {
3325
3329
  cwd: target || '.'
3326
3330
  });
3327
- spinner$1.success();
3331
+ spinner$1.successAndStop();
3328
3332
  if (verbose) {
3329
3333
  console.group('[VERBOSE] sbt stdout:');
3330
3334
  console.log(output);
3331
3335
  console.groupEnd();
3332
3336
  }
3333
3337
  if (output.stderr) {
3334
- spinner$1.error('There were errors while running sbt');
3338
+ spinner$1.start();
3339
+ spinner$1.errorAndStop('There were errors while running sbt');
3335
3340
  // (In verbose mode, stderr was printed above, no need to repeat it)
3336
3341
  if (!verbose) {
3337
3342
  console.group('[VERBOSE] stderr:');
@@ -3346,7 +3351,7 @@ async function convertSbtToMaven(target, bin, out, verbose, sbtOpts) {
3346
3351
  return fn;
3347
3352
  });
3348
3353
  if (!poms.length) {
3349
- spinner$1.error('There were no errors from sbt but it seems to not have generated any poms either');
3354
+ spinner$1.errorAndStop('There were no errors from sbt but it seems to not have generated any poms either');
3350
3355
  process.exit(1);
3351
3356
  }
3352
3357
 
@@ -3378,7 +3383,7 @@ async function convertSbtToMaven(target, bin, out, verbose, sbtOpts) {
3378
3383
  spinner$1.start().success(`OK`);
3379
3384
  }
3380
3385
  } catch (e) {
3381
- spinner$1.error('There was an unexpected error while running this' + (verbose ? '' : ' (use --verbose for details)'));
3386
+ spinner$1.errorAndStop('There was an unexpected error while running this' + (verbose ? '' : ' (use --verbose for details)'));
3382
3387
  if (verbose) {
3383
3388
  console.group('[VERBOSE] error:');
3384
3389
  console.log(e);
@@ -5238,7 +5243,7 @@ async function createReport(socketConfig, inputPaths, {
5238
5243
  handleUnsuccessfulApiResponse('createReport', result, spinner$1);
5239
5244
  return undefined;
5240
5245
  }
5241
- spinner$1.success();
5246
+ spinner$1.successAndStop();
5242
5247
  return result;
5243
5248
  }
5244
5249
  }
@@ -5290,16 +5295,16 @@ async function fetchReportData(reportId, includeAllIssues, strict) {
5290
5295
 
5291
5296
  if (strict) {
5292
5297
  if (result.data.healthy) {
5293
- spinner$1.success('Report result is healthy and great!');
5298
+ spinner$1.successAndStop('Report result is healthy and great!');
5294
5299
  } else {
5295
- spinner$1.error('Report result deemed unhealthy for project');
5300
+ spinner$1.errorAndStop('Report result deemed unhealthy for project');
5296
5301
  }
5297
5302
  } else if (!result.data.healthy) {
5298
5303
  const severityCount = getSeverityCount(result.data.issues, includeAllIssues ? undefined : 'high');
5299
5304
  const issueSummary = formatSeverityCount(severityCount);
5300
- spinner$1.success(`Report has these issues: ${issueSummary}`);
5305
+ spinner$1.successAndStop(`Report has these issues: ${issueSummary}`);
5301
5306
  } else {
5302
- spinner$1.success('Report has no issues');
5307
+ spinner$1.successAndStop('Report has no issues');
5303
5308
  }
5304
5309
  return result.data;
5305
5310
  }
@@ -5538,7 +5543,7 @@ async function createRepo({
5538
5543
  visibility
5539
5544
  }), 'creating repository');
5540
5545
  if (result.success) {
5541
- spinner$1.success('Repository created successfully');
5546
+ spinner$1.successAndStop('Repository created successfully');
5542
5547
  } else {
5543
5548
  handleUnsuccessfulApiResponse('createOrgRepo', result, spinner$1);
5544
5549
  }
@@ -5647,7 +5652,7 @@ async function deleteRepo(orgSlug, repoName, apiToken) {
5647
5652
  const socketSdk = await index.setupSdk(apiToken);
5648
5653
  const result = await handleApiCall(socketSdk.deleteOrgRepo(orgSlug, repoName), 'deleting repository');
5649
5654
  if (result.success) {
5650
- spinner$1.success('Repository deleted successfully');
5655
+ spinner$1.successAndStop('Repository deleted successfully');
5651
5656
  } else {
5652
5657
  handleUnsuccessfulApiResponse('deleteOrgRepo', result, spinner$1);
5653
5658
  }
@@ -5736,6 +5741,18 @@ async function listRepos({
5736
5741
  handleUnsuccessfulApiResponse('getOrgRepoList', result, spinner$1);
5737
5742
  return;
5738
5743
  }
5744
+ spinner$1.stop();
5745
+ if (outputJson) {
5746
+ const data = result.data.results.map(o => ({
5747
+ id: o.id,
5748
+ name: o.name,
5749
+ visibility: o.visibility,
5750
+ defaultBranch: o.default_branch,
5751
+ archived: o.archived
5752
+ }));
5753
+ console.log(JSON.stringify(data, null, 2));
5754
+ return;
5755
+ }
5739
5756
  const options = {
5740
5757
  columns: [{
5741
5758
  field: 'id',
@@ -5754,7 +5771,7 @@ async function listRepos({
5754
5771
  name: colors.magenta('Archived')
5755
5772
  }]
5756
5773
  };
5757
- spinner$1.stop(chalkTable(options, result.data.results));
5774
+ console.log(chalkTable(options, result.data.results));
5758
5775
  }
5759
5776
 
5760
5777
  const config$9 = {
@@ -5870,7 +5887,7 @@ async function updateRepo({
5870
5887
  visibility
5871
5888
  }), 'updating repository');
5872
5889
  if (result.success) {
5873
- spinner$1.success('Repository updated successfully');
5890
+ spinner$1.successAndStop('Repository updated successfully');
5874
5891
  } else {
5875
5892
  handleUnsuccessfulApiResponse('updateOrgRepo', result, spinner$1);
5876
5893
  }
@@ -6087,8 +6104,149 @@ const cmdRepos = {
6087
6104
  }
6088
6105
  };
6089
6106
 
6107
+ async function suggestOrgSlug(socketSdk) {
6108
+ const result = await handleApiCall(socketSdk.getOrganizations(), 'looking up organizations');
6109
+ // Ignore a failed request here. It was not the primary goal of
6110
+ // running this command and reporting it only leads to end-user confusion.
6111
+ if (result.success) {
6112
+ const proceed = await prompts.select({
6113
+ message: 'Missing org name; do you want to use any of these orgs for this scan?',
6114
+ choices: Array.from(Object.values(result.data.organizations)).map(({
6115
+ name: slug
6116
+ }) => ({
6117
+ name: 'Yes [' + slug + ']',
6118
+ value: slug,
6119
+ description: `Use "${slug}" as the organization`
6120
+ })).concat({
6121
+ name: 'No',
6122
+ value: '',
6123
+ description: 'Do not use any of these organizations (will end in a no-op)'
6124
+ })
6125
+ });
6126
+ if (proceed) {
6127
+ return proceed;
6128
+ }
6129
+ }
6130
+ }
6131
+
6132
+ async function suggestRepoSlug(socketSdk, orgSlug) {
6133
+ // Same as above, but if there's a repo with the same name as cwd then
6134
+ // default the selection to that name.
6135
+ const result = await handleApiCall(socketSdk.getOrgRepoList(orgSlug, {
6136
+ orgSlug,
6137
+ sort: 'name',
6138
+ direction: 'asc',
6139
+ // There's no guarantee that the cwd is part of this page. If it's not
6140
+ // then do an additional request and specific search for it instead.
6141
+ // This way we can offer the tip of "do you want to create [cwd]?".
6142
+ perPage: 10,
6143
+ page: 0
6144
+ }), 'looking up known repos');
6145
+ // Ignore a failed request here. It was not the primary goal of
6146
+ // running this command and reporting it only leads to end-user confusion.
6147
+ if (result.success) {
6148
+ const currentDirName = dirNameToSlug(path.basename(process$1.cwd()));
6149
+ let cwdIsKnown = !!currentDirName && result.data.results.some(obj => obj.slug === currentDirName);
6150
+ if (!cwdIsKnown && currentDirName) {
6151
+ // Do an explicit request so we can assert that the cwd exists or not
6152
+ const result = await handleApiCall(socketSdk.getOrgRepo(orgSlug, currentDirName), 'checking if current cwd is a known repo');
6153
+ if (result.success) {
6154
+ cwdIsKnown = true;
6155
+ }
6156
+ }
6157
+ const proceed = await prompts.select({
6158
+ message: 'Missing repo name; do you want to use any of these known repo names for this scan?',
6159
+ choices:
6160
+ // Put the CWD suggestion at the top, whether it exists or not
6161
+ (currentDirName ? [{
6162
+ name: `Yes, current dir [${cwdIsKnown ? currentDirName : `create repo for ${currentDirName}`}]`,
6163
+ value: currentDirName,
6164
+ description: cwdIsKnown ? 'Register a new repo name under the given org and use it' : 'Use current dir as repo'
6165
+ }] : []).concat(result.data.results.filter(({
6166
+ slug
6167
+ }) => !!slug && slug !== currentDirName).map(({
6168
+ slug
6169
+ }) => ({
6170
+ name: 'Yes [' + slug + ']',
6171
+ value: slug || '',
6172
+ // Filtered above but TS is like nah.
6173
+ description: `Use "${slug}" as the repo name`
6174
+ })), {
6175
+ name: 'No',
6176
+ value: '',
6177
+ description: 'Do not use any of these repos (will end in a no-op)'
6178
+ })
6179
+ });
6180
+ if (proceed) {
6181
+ const repoName = proceed;
6182
+ let repoDefaultBranch = '';
6183
+ // Store the default branch to help with the branch name question next
6184
+ result.data.results.some(obj => {
6185
+ if (obj.slug === proceed && obj.default_branch) {
6186
+ repoDefaultBranch = obj.default_branch;
6187
+ return;
6188
+ }
6189
+ });
6190
+ return {
6191
+ slug: repoName,
6192
+ defaultBranch: repoDefaultBranch
6193
+ };
6194
+ }
6195
+ }
6196
+ }
6197
+ function dirNameToSlug(name) {
6198
+ // Uses slug specs asserted by our servers
6199
+ // Note: this can lead to collisions; eg. slug for `x--y` and `x---y` is `x-y`
6200
+ return name.toLowerCase().replace(/[^[a-zA-Z0-9_.-]/g, '_').replace(/--+/g, '-').replace(/__+/g, '_').replace(/\.\.+/g, '.').replace(/[._-]+$/, '');
6201
+ }
6202
+
6203
+ async function suggestBranchSlug(repoDefaultBranch) {
6204
+ const spawnResult = node_child_process.spawnSync('git', ['branch', '--show-current']);
6205
+ const currentBranch = spawnResult.stdout.toString('utf8').trim();
6206
+ if (spawnResult.status === 0 && currentBranch) {
6207
+ const proceed = await prompts.select({
6208
+ message: 'Use the current git branch as target branch name?',
6209
+ choices: [{
6210
+ name: `Yes [${currentBranch}]`,
6211
+ value: currentBranch,
6212
+ description: 'Use the current git branch for branch name'
6213
+ }, ...(repoDefaultBranch && repoDefaultBranch !== currentBranch ? [{
6214
+ name: `No, use the default branch [${repoDefaultBranch}]`,
6215
+ value: repoDefaultBranch,
6216
+ description: 'Use the default branch for target repo as the target branch name'
6217
+ }] : []), {
6218
+ name: 'No',
6219
+ value: '',
6220
+ description: 'Do not use the current git branch as name (will end in a no-op)'
6221
+ }].filter(Boolean)
6222
+ });
6223
+ if (proceed) {
6224
+ return proceed;
6225
+ }
6226
+ }
6227
+ }
6228
+
6229
+ async function suggestTarget() {
6230
+ // We could prefill this with sub-dirs of the current
6231
+ // dir ... but is that going to be useful?
6232
+ const proceed = await prompts.select({
6233
+ message: 'No TARGET given. Do you want to use the current directory?',
6234
+ choices: [{
6235
+ name: 'Yes',
6236
+ value: true,
6237
+ description: 'Target the current directory'
6238
+ }, {
6239
+ name: 'No',
6240
+ value: false,
6241
+ description: 'Do not use the current directory (this will end in a no-op)'
6242
+ }]
6243
+ });
6244
+ if (proceed) {
6245
+ return ['.'];
6246
+ }
6247
+ }
6248
+
6090
6249
  async function createFullScan({
6091
- apiToken,
6092
6250
  branchName,
6093
6251
  commitHash: _commitHash,
6094
6252
  commitMessage,
@@ -6096,17 +6254,100 @@ async function createFullScan({
6096
6254
  cwd,
6097
6255
  defaultBranch,
6098
6256
  orgSlug,
6099
- packagePaths,
6100
6257
  pendingHead,
6101
6258
  pullRequest: _pullRequest,
6259
+ readOnly,
6102
6260
  repoName,
6261
+ targets,
6103
6262
  tmp
6104
6263
  }) {
6264
+ const socketSdk = await index.setupSdk();
6265
+ const supportedFiles = await socketSdk.getReportSupportedFiles().then(res => {
6266
+ if (!res.success) {
6267
+ handleUnsuccessfulApiResponse('getReportSupportedFiles', res, new spinner.Spinner());
6268
+ assert(false, 'handleUnsuccessfulApiResponse should unconditionally throw');
6269
+ }
6270
+ return res.data;
6271
+ }).catch(cause => {
6272
+ throw new Error('Failed getting supported files for report', {
6273
+ cause
6274
+ });
6275
+ });
6276
+
6277
+ // If we updated any inputs then we should print the command line to repeat
6278
+ // the command without requiring user input, as a suggestion.
6279
+ let updatedInput = false;
6280
+ if (!targets.length) {
6281
+ const received = await suggestTarget();
6282
+ targets = received ?? [];
6283
+ updatedInput = true;
6284
+ }
6285
+ const packagePaths = await npmPaths.getPackageFilesFullScans(cwd, targets, supportedFiles);
6286
+
6287
+ // We're going to need an api token to suggest data because those suggestions
6288
+ // must come from data we already know. Don't error on missing api token yet.
6289
+ // If the api-token is not set, ignore it for the sake of suggestions.
6290
+ const apiToken = index.getDefaultToken();
6291
+ if (apiToken && !orgSlug) {
6292
+ const suggestion = await suggestOrgSlug(socketSdk);
6293
+ if (suggestion) orgSlug = suggestion;
6294
+ updatedInput = true;
6295
+ }
6296
+
6297
+ // If the current cwd is unknown and is used as a repo slug anyways, we will
6298
+ // first need to register the slug before we can use it.
6299
+ let repoDefaultBranch = '';
6300
+
6301
+ // (Don't bother asking for the rest if we didn't get an org slug above)
6302
+ if (apiToken && orgSlug && !repoName) {
6303
+ const suggestion = await suggestRepoSlug(socketSdk, orgSlug);
6304
+ if (suggestion) {
6305
+ ({
6306
+ defaultBranch: repoDefaultBranch,
6307
+ slug: repoName
6308
+ } = suggestion);
6309
+ }
6310
+ updatedInput = true;
6311
+ }
6312
+
6313
+ // (Don't bother asking for the rest if we didn't get an org/repo above)
6314
+ if (apiToken && orgSlug && repoName && !branchName) {
6315
+ const suggestion = await suggestBranchSlug(repoDefaultBranch);
6316
+ if (suggestion) branchName = suggestion;
6317
+ updatedInput = true;
6318
+ }
6319
+ if (!orgSlug || !repoName || !branchName || !packagePaths.length) {
6320
+ // Use exit status of 2 to indicate incorrect usage, generally invalid
6321
+ // options or missing arguments.
6322
+ // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
6323
+ process$1.exitCode = 2;
6324
+ console.error(`
6325
+ ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
6326
+ - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}\n
6327
+ - Repository name using --repo ${!repoName ? colors.red('(missing!)') : colors.green('(ok)')}\n
6328
+ - Branch name using --branch ${!branchName ? colors.red('(missing!)') : colors.green('(ok)')}\n
6329
+ - At least one TARGET (e.g. \`.\` or \`./package.json\`) ${!packagePaths.length ? colors.red(targets.length > 0 ? '(TARGET' + (targets.length ? 's' : '') + ' contained no matching/supported files!)' : '(missing)') : colors.green('(ok)')}\n
6330
+ ${!apiToken ? 'Note: was unable to make suggestions because no API Token was found; this would make command fail regardless\n' : ''}
6331
+ `);
6332
+ return;
6333
+ }
6334
+ if (updatedInput) {
6335
+ console.log('Note: You can invoke this command next time to skip the interactive questions:');
6336
+ console.log('```');
6337
+ console.log(` socket scan create [other flags...] --repo ${repoName} --branch ${branchName} ${orgSlug} ${targets.join(' ')}`);
6338
+ console.log('```');
6339
+ }
6340
+ if (!apiToken) {
6341
+ 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.');
6342
+ }
6343
+ if (readOnly) {
6344
+ console.log('[ReadOnly] Bailing now');
6345
+ return;
6346
+ }
6105
6347
  const spinnerText = 'Creating a scan... \n';
6106
6348
  const spinner$1 = new spinner.Spinner({
6107
6349
  text: spinnerText
6108
6350
  }).start();
6109
- const socketSdk = await index.setupSdk(apiToken);
6110
6351
  const result = await handleApiCall(socketSdk.createOrgFullScan(orgSlug, {
6111
6352
  repo: repoName,
6112
6353
  branch: branchName,
@@ -6119,7 +6360,7 @@ async function createFullScan({
6119
6360
  handleUnsuccessfulApiResponse('CreateOrgFullScan', result, spinner$1);
6120
6361
  return;
6121
6362
  }
6122
- spinner$1.success('Scan created successfully');
6363
+ spinner$1.successAndStop('Scan created successfully');
6123
6364
  const link = colors.underline(colors.cyan(`${result.data.html_report_url}`));
6124
6365
  console.log(`Available at: ${link}`);
6125
6366
  const rl = readline.createInterface({
@@ -6193,6 +6434,11 @@ const config$6 = {
6193
6434
  default: false,
6194
6435
  description: 'Set as pending head'
6195
6436
  },
6437
+ readOnly: {
6438
+ type: 'boolean',
6439
+ default: false,
6440
+ description: 'Similar to --dry-run except it can read from remote, stops before it would create an actual report'
6441
+ },
6196
6442
  tmp: {
6197
6443
  type: 'boolean',
6198
6444
  shortFlag: 't',
@@ -6232,56 +6478,47 @@ async function run$6(argv, importMeta, {
6232
6478
  });
6233
6479
  const [orgSlug = '', ...targets] = cli.input;
6234
6480
  const cwd = cli.flags['cwd'] && cli.flags['cwd'] !== 'process.cwd()' ? String(cli.flags['cwd']) : process$1.cwd();
6235
-
6236
- // Note exiting earlier to skirt a hidden auth requirement
6237
- if (cli.flags['dryRun']) {
6238
- return console.log('[DryRun] Bailing now');
6239
- }
6240
- const socketSdk = await index.setupSdk();
6241
- const supportedFiles = await socketSdk.getReportSupportedFiles().then(res => {
6242
- if (!res.success) handleUnsuccessfulApiResponse('getReportSupportedFiles', res, new spinner.Spinner());
6243
- // TODO: verify type at runtime? Consider it trusted data and assume type?
6244
- return res.data;
6245
- }).catch(cause => {
6246
- throw new Error('Failed getting supported files for report', {
6247
- cause
6248
- });
6249
- });
6250
- const packagePaths = await npmPaths.getPackageFilesFullScans(cwd, targets, supportedFiles);
6251
- const {
6481
+ let {
6252
6482
  branch: branchName,
6253
6483
  repo: repoName
6254
6484
  } = cli.flags;
6255
- if (!orgSlug || !repoName || !branchName || !packagePaths.length) {
6485
+ const apiToken = index.getDefaultToken();
6486
+ if (!apiToken && (!orgSlug || !repoName || !branchName || !targets.length)) {
6487
+ // Without api token we cannot recover because we can't request more info
6488
+ // from the server, to match and help with the current cwd/git status.
6256
6489
  // Use exit status of 2 to indicate incorrect usage, generally invalid
6257
6490
  // options or missing arguments.
6258
6491
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
6259
6492
  process$1.exitCode = 2;
6260
- console.error(`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
6261
- - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}\n
6262
- - Repository name using --repo ${!repoName ? colors.red('(missing!)') : colors.green('(ok)')}\n
6263
- - Branch name using --branch ${!branchName ? colors.red('(missing!)') : colors.green('(ok)')}\n
6264
- - At least one TARGET (e.g. \`.\` or \`./package.json\`) ${!packagePaths.length ? colors.red(targets.length > 0 ? '(TARGET' + (targets.length ? 's' : '') + ' contained no matching/supported files!)' : '(missing)') : colors.green('(ok)')}\n`);
6493
+ console.error(`
6494
+ ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
6495
+ - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}\n
6496
+ - Repository name using --repo ${!repoName ? colors.red('(missing!)') : colors.green('(ok)')}\n
6497
+ - Branch name using --branch ${!branchName ? colors.red('(missing!)') : colors.green('(ok)')}\n
6498
+ - At least one TARGET (e.g. \`.\` or \`./package.json\`) ${!targets.length ? '(missing)' : colors.green('(ok)')}\n
6499
+ (Additionally, no API Token was set so we cannot auto-discover these details)\n
6500
+ `);
6265
6501
  return;
6266
6502
  }
6267
- const apiToken = index.getDefaultToken();
6268
- if (!apiToken) {
6269
- 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.');
6503
+
6504
+ // Note exiting earlier to skirt a hidden auth requirement
6505
+ if (cli.flags['dryRun']) {
6506
+ return console.log('[DryRun] Bailing now');
6270
6507
  }
6271
6508
  await createFullScan({
6272
- apiToken,
6273
- orgSlug,
6274
- repoName: repoName,
6275
6509
  branchName: branchName,
6510
+ commitHash: cli.flags['commitHash'] ?? '',
6276
6511
  commitMessage: cli.flags['commitMessage'] ?? '',
6512
+ committers: cli.flags['committers'] ?? '',
6513
+ cwd,
6277
6514
  defaultBranch: Boolean(cli.flags['defaultBranch']),
6515
+ orgSlug,
6278
6516
  pendingHead: Boolean(cli.flags['pendingHead']),
6279
- tmp: Boolean(cli.flags['tmp']),
6280
- packagePaths,
6281
- cwd,
6282
- commitHash: cli.flags['commitHash'] ?? '',
6283
- committers: cli.flags['committers'] ?? '',
6284
- pullRequest: cli.flags['pullRequest'] ?? undefined
6517
+ pullRequest: cli.flags['pullRequest'] ?? undefined,
6518
+ readOnly: Boolean(cli.flags['readOnly']),
6519
+ repoName: repoName,
6520
+ targets,
6521
+ tmp: Boolean(cli.flags['tmp'])
6285
6522
  });
6286
6523
  }
6287
6524
 
@@ -6293,7 +6530,7 @@ async function deleteOrgFullScan(orgSlug, fullScanId, apiToken) {
6293
6530
  const socketSdk = await index.setupSdk(apiToken);
6294
6531
  const result = await handleApiCall(socketSdk.deleteOrgFullScan(orgSlug, fullScanId), 'Deleting scan');
6295
6532
  if (result.success) {
6296
- spinner$1.success('Scan deleted successfully');
6533
+ spinner$1.successAndStop('Scan deleted successfully');
6297
6534
  } else {
6298
6535
  handleUnsuccessfulApiResponse('deleteOrgFullScan', result, spinner$1);
6299
6536
  }
@@ -7074,5 +7311,5 @@ void (async () => {
7074
7311
  await index.captureException(e);
7075
7312
  }
7076
7313
  })();
7077
- //# debugId=9211012b-2bab-40e6-b115-6389952c7273
7314
+ //# debugId=5ebdde59-83d7-40b0-a2b4-52200ebea950
7078
7315
  //# sourceMappingURL=cli.js.map