@socketsecurity/cli-with-sentry 0.14.66 → 0.14.67

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.
@@ -56,8 +56,7 @@ var tinyglobby = _socketInterop(require('tinyglobby'));
56
56
  var promises = require('@socketsecurity/registry/lib/promises');
57
57
  var yaml = _socketInterop(require('yaml'));
58
58
  var betterAjvErrors = _socketInterop(require('@apideck/better-ajv-errors'));
59
- var config$D = require('@socketsecurity/config');
60
- var assert = require('node:assert');
59
+ var config$H = require('@socketsecurity/config');
61
60
  var readline = require('node:readline/promises');
62
61
  var open = _socketInterop(require('open'));
63
62
  var BoxWidget = _socketInterop(require('blessed/lib/widgets/box'));
@@ -105,7 +104,7 @@ function getLastFiveOfApiToken(token) {
105
104
 
106
105
  // The API server that should be used for operations.
107
106
  function getDefaultApiBaseUrl() {
108
- const baseUrl = process$1.env['SOCKET_SECURITY_API_BASE_URL'] || shadowNpmInject.getSetting('apiBaseUrl');
107
+ const baseUrl = process$1.env['SOCKET_SECURITY_API_BASE_URL'] || shadowNpmInject.getConfigValue('apiBaseUrl');
109
108
  return strings.isNonEmptyString(baseUrl) ? baseUrl : undefined;
110
109
  }
111
110
  async function queryApi(path, apiToken) {
@@ -119,8 +118,8 @@ async function queryApi(path, apiToken) {
119
118
  }
120
119
 
121
120
  async function fetchOrgAnalyticsData(time, spinner, apiToken) {
122
- const socketSdk = await shadowNpmInject.setupSdk(apiToken);
123
- const result = await handleApiCall(socketSdk.getOrgAnalytics(time.toString()), 'fetching analytics data');
121
+ const sockSdk = await shadowNpmInject.setupSdk(apiToken);
122
+ const result = await handleApiCall(sockSdk.getOrgAnalytics(time.toString()), 'fetching analytics data');
124
123
  if (result.success === false) {
125
124
  handleUnsuccessfulApiResponse('getOrgAnalytics', result);
126
125
  return undefined;
@@ -134,8 +133,8 @@ async function fetchOrgAnalyticsData(time, spinner, apiToken) {
134
133
  }
135
134
 
136
135
  async function fetchRepoAnalyticsData(repo, time, spinner, apiToken) {
137
- const socketSdk = await shadowNpmInject.setupSdk(apiToken);
138
- const result = await handleApiCall(socketSdk.getRepoAnalytics(repo, time.toString()), 'fetching analytics data');
136
+ const sockSdk = await shadowNpmInject.setupSdk(apiToken);
137
+ const result = await handleApiCall(sockSdk.getRepoAnalytics(repo, time.toString()), 'fetching analytics data');
139
138
  if (result.success === false) {
140
139
  handleUnsuccessfulApiResponse('getRepoAnalytics', result);
141
140
  return undefined;
@@ -655,9 +654,9 @@ function emitBanner(name) {
655
654
  }
656
655
  function getAsciiHeader(command) {
657
656
  const cliVersion = // The '@rollup/plugin-replace' will replace "process.env['INLINED_SOCKET_CLI_VERSION_HASH']".
658
- "0.14.66:3dec148:3a36e9f3:pub";
657
+ "0.14.67:a2db5d2:df42d424:pub";
659
658
  const nodeVersion = process.version;
660
- const apiToken = shadowNpmInject.getSetting('apiToken');
659
+ const apiToken = shadowNpmInject.getConfigValue('apiToken');
661
660
  const shownToken = apiToken ? getLastFiveOfApiToken(apiToken) : 'no';
662
661
  const relCwd = path.normalizePath(process.cwd().replace(new RegExp(`^${regexps.escapeRegExp(constants.homePath)}(?:${path$1.sep}|$)`, 'i'), '~/'));
663
662
  const body = `
@@ -669,9 +668,9 @@ function getAsciiHeader(command) {
669
668
  }
670
669
 
671
670
  const {
672
- DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$B
671
+ DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$F
673
672
  } = constants;
674
- const config$C = {
673
+ const config$G = {
675
674
  commandName: 'analytics',
676
675
  description: `Look up analytics data`,
677
676
  hidden: false,
@@ -722,16 +721,16 @@ const config$C = {
722
721
  `
723
722
  };
724
723
  const cmdAnalytics = {
725
- description: config$C.description,
726
- hidden: config$C.hidden,
727
- run: run$C
724
+ description: config$G.description,
725
+ hidden: config$G.hidden,
726
+ run: run$G
728
727
  };
729
- async function run$C(argv, importMeta, {
728
+ async function run$G(argv, importMeta, {
730
729
  parentName
731
730
  }) {
732
731
  const cli = meowOrExit({
733
732
  argv,
734
- config: config$C,
733
+ config: config$G,
735
734
  importMeta,
736
735
  parentName
737
736
  });
@@ -768,7 +767,7 @@ async function run$C(argv, importMeta, {
768
767
  return;
769
768
  }
770
769
  if (cli.flags['dryRun']) {
771
- logger.logger.log(DRY_RUN_BAIL_TEXT$B);
770
+ logger.logger.log(DRY_RUN_BAIL_TEXT$F);
772
771
  return;
773
772
  }
774
773
  return await displayAnalytics({
@@ -811,8 +810,8 @@ async function fetchAuditLogWithToken(apiToken, {
811
810
  spinner
812
811
  } = constants;
813
812
  spinner.start(`Looking up audit log for ${orgSlug}`);
814
- const socketSdk = await shadowNpmInject.setupSdk(apiToken);
815
- const result = await handleApiCall(socketSdk.getAuditLogEvents(orgSlug, {
813
+ const sockSdk = await shadowNpmInject.setupSdk(apiToken);
814
+ const result = await handleApiCall(sockSdk.getAuditLogEvents(orgSlug, {
816
815
  // I'm not sure this is used at all.
817
816
  outputJson: String(outputKind === 'json'),
818
817
  // I'm not sure this is used at all.
@@ -955,9 +954,9 @@ async function handleAuditLog({
955
954
  }
956
955
 
957
956
  const {
958
- DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$A
957
+ DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$E
959
958
  } = constants;
960
- const config$B = {
959
+ const config$F = {
961
960
  commandName: 'audit-log',
962
961
  description: 'Look up the audit log for an organization',
963
962
  hidden: false,
@@ -998,16 +997,16 @@ const config$B = {
998
997
  `
999
998
  };
1000
999
  const cmdAuditLog = {
1001
- description: config$B.description,
1002
- hidden: config$B.hidden,
1003
- run: run$B
1000
+ description: config$F.description,
1001
+ hidden: config$F.hidden,
1002
+ run: run$F
1004
1003
  };
1005
- async function run$B(argv, importMeta, {
1004
+ async function run$F(argv, importMeta, {
1006
1005
  parentName
1007
1006
  }) {
1008
1007
  const cli = meowOrExit({
1009
1008
  argv,
1010
- config: config$B,
1009
+ config: config$F,
1011
1010
  importMeta,
1012
1011
  parentName
1013
1012
  });
@@ -1032,7 +1031,7 @@ async function run$B(argv, importMeta, {
1032
1031
  return;
1033
1032
  }
1034
1033
  if (cli.flags['dryRun']) {
1035
- logger.logger.log(DRY_RUN_BAIL_TEXT$A);
1034
+ logger.logger.log(DRY_RUN_BAIL_TEXT$E);
1036
1035
  return;
1037
1036
  }
1038
1037
  await handleAuditLog({
@@ -1149,7 +1148,7 @@ function isHelpFlag(cmdArg) {
1149
1148
 
1150
1149
  // import { meowOrExit } from '../../utils/meow-with-subcommands'
1151
1150
  const {
1152
- DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$z
1151
+ DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$D
1153
1152
  } = constants;
1154
1153
 
1155
1154
  // TODO: convert yargs to meow. Or convert all the other things to yargs.
@@ -1226,7 +1225,7 @@ const yargsConfig = {
1226
1225
  'yes'],
1227
1226
  string: ['api-key', 'lifecycle', 'output', 'parent-project-id', 'profile', 'project-group', 'project-name', 'project-version', 'project-id', 'server-host', 'server-port', 'server-url', 'spec-version']
1228
1227
  };
1229
- const config$A = {
1228
+ const config$E = {
1230
1229
  commandName: 'cdxgen',
1231
1230
  description: 'Create an SBOM with CycloneDX generator (cdxgen)',
1232
1231
  hidden: false,
@@ -1242,18 +1241,18 @@ const config$A = {
1242
1241
  `
1243
1242
  };
1244
1243
  const cmdCdxgen = {
1245
- description: config$A.description,
1246
- hidden: config$A.hidden,
1247
- run: run$A
1244
+ description: config$E.description,
1245
+ hidden: config$E.hidden,
1246
+ run: run$E
1248
1247
  };
1249
- async function run$A(argv, importMeta, {
1248
+ async function run$E(argv, importMeta, {
1250
1249
  parentName
1251
1250
  }) {
1252
1251
  const cli = meowOrExit({
1253
1252
  allowUnknownFlags: true,
1254
1253
  // Don't let meow take over --help.
1255
1254
  argv: argv.filter(a => !isHelpFlag(a)),
1256
- config: config$A,
1255
+ config: config$E,
1257
1256
  importMeta,
1258
1257
  parentName
1259
1258
  });
@@ -1285,7 +1284,7 @@ async function run$A(argv, importMeta, {
1285
1284
  return;
1286
1285
  }
1287
1286
  if (cli.flags['dryRun']) {
1288
- logger.logger.log(DRY_RUN_BAIL_TEXT$z);
1287
+ logger.logger.log(DRY_RUN_BAIL_TEXT$D);
1289
1288
  return;
1290
1289
  }
1291
1290
  if (yargv.output === undefined) {
@@ -1294,6 +1293,405 @@ async function run$A(argv, importMeta, {
1294
1293
  await runCycloneDX(yargv);
1295
1294
  }
1296
1295
 
1296
+ async function outputConfigGet(key, value, outputKind) {
1297
+ if (outputKind === 'json') {
1298
+ logger.logger.log(JSON.stringify({
1299
+ success: true,
1300
+ result: {
1301
+ key,
1302
+ value
1303
+ }
1304
+ }));
1305
+ } else if (outputKind === 'markdown') {
1306
+ logger.logger.log(`# Config Value`);
1307
+ logger.logger.log('');
1308
+ logger.logger.log(`Config key '${key}' has value '${value}`);
1309
+ } else {
1310
+ logger.logger.log(`${key}: ${value}`);
1311
+ }
1312
+ }
1313
+
1314
+ async function handleConfigGet({
1315
+ key,
1316
+ outputKind
1317
+ }) {
1318
+ const value = shadowNpmInject.getConfigValue(key);
1319
+ await outputConfigGet(key, value, outputKind);
1320
+ }
1321
+
1322
+ const {
1323
+ DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$C
1324
+ } = constants;
1325
+ const config$D = {
1326
+ commandName: 'get',
1327
+ description: 'Get the value of a local CLI config item',
1328
+ hidden: false,
1329
+ flags: {
1330
+ ...commonFlags,
1331
+ ...outputFlags
1332
+ },
1333
+ help: (command, config) => `
1334
+ Usage
1335
+ $ ${command} <org slug>
1336
+
1337
+ Options
1338
+ ${getFlagListOutput(config.flags, 6)}
1339
+
1340
+ Keys:
1341
+
1342
+ ${Array.from(shadowNpmInject.supportedConfigKeys.entries()).map(([key, desc]) => ` - ${key} -- ${desc}`).join('\n')}
1343
+
1344
+ Examples
1345
+ $ ${command} FakeOrg --repoName=test-repo
1346
+ `
1347
+ };
1348
+ const cmdConfigGet = {
1349
+ description: config$D.description,
1350
+ hidden: config$D.hidden,
1351
+ run: run$D
1352
+ };
1353
+ async function run$D(argv, importMeta, {
1354
+ parentName
1355
+ }) {
1356
+ const cli = meowOrExit({
1357
+ argv,
1358
+ config: config$D,
1359
+ importMeta,
1360
+ parentName
1361
+ });
1362
+ const {
1363
+ json,
1364
+ markdown
1365
+ } = cli.flags;
1366
+ const [key = ''] = cli.input;
1367
+ if (!shadowNpmInject.supportedConfigKeys.has(key) && key !== 'test') {
1368
+ // Use exit status of 2 to indicate incorrect usage, generally invalid
1369
+ // options or missing arguments.
1370
+ // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
1371
+ process.exitCode = 2;
1372
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
1373
+
1374
+ - Config key should be the first arg ${!key ? colors.red('(missing!)') : !shadowNpmInject.supportedConfigKeys.has(key) ? colors.red('(invalid config key!)') : colors.green('(ok)')}
1375
+ `);
1376
+ return;
1377
+ }
1378
+ if (cli.flags['dryRun']) {
1379
+ logger.logger.log(DRY_RUN_BAIL_TEXT$C);
1380
+ return;
1381
+ }
1382
+ await handleConfigGet({
1383
+ key: key,
1384
+ outputKind: json ? 'json' : markdown ? 'markdown' : 'text'
1385
+ });
1386
+ }
1387
+
1388
+ async function outputConfigList({
1389
+ full,
1390
+ outputKind
1391
+ }) {
1392
+ if (outputKind === 'json') {
1393
+ const obj = {};
1394
+ for (const key of shadowNpmInject.supportedConfigKeys.keys()) {
1395
+ let value = shadowNpmInject.getConfigValue(key);
1396
+ if (!full && shadowNpmInject.sensitiveConfigKeys.has(key)) {
1397
+ value = '********';
1398
+ }
1399
+ if (full || value !== undefined) {
1400
+ obj[key] = value ?? '<none>';
1401
+ }
1402
+ }
1403
+ logger.logger.log(JSON.stringify({
1404
+ success: true,
1405
+ full,
1406
+ config: obj
1407
+ }, null, 2));
1408
+ } else {
1409
+ const maxWidth = Array.from(shadowNpmInject.supportedConfigKeys.keys()).reduce((a, b) => Math.max(a, b.length), 0);
1410
+ logger.logger.log('# Local CLI Config');
1411
+ logger.logger.log('');
1412
+ logger.logger.log(`This is the local CLI config (full=${!!full}):`);
1413
+ logger.logger.log('');
1414
+ for (const key of shadowNpmInject.supportedConfigKeys.keys()) {
1415
+ let value = shadowNpmInject.getConfigValue(key);
1416
+ if (!full && shadowNpmInject.sensitiveConfigKeys.has(key)) {
1417
+ value = '********';
1418
+ }
1419
+ if (full || value !== undefined) {
1420
+ logger.logger.log(`- ${key}:${' '.repeat(Math.max(0, maxWidth - key.length + 3))} ${Array.isArray(value) ? value.join(', ') || '<none>' : value ?? '<none>'}`);
1421
+ }
1422
+ }
1423
+ }
1424
+ }
1425
+
1426
+ const {
1427
+ DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$B
1428
+ } = constants;
1429
+ const config$C = {
1430
+ commandName: 'list',
1431
+ description: 'Show all local CLI config items and their values',
1432
+ hidden: false,
1433
+ flags: {
1434
+ ...commonFlags,
1435
+ ...outputFlags,
1436
+ full: {
1437
+ type: 'boolean',
1438
+ default: false,
1439
+ description: 'Show full tokens in plaintext (unsafe)'
1440
+ }
1441
+ },
1442
+ help: (command, config) => `
1443
+ Usage
1444
+ $ ${command} <org slug>
1445
+
1446
+ Options
1447
+ ${getFlagListOutput(config.flags, 6)}
1448
+
1449
+ Keys:
1450
+
1451
+ ${Array.from(shadowNpmInject.supportedConfigKeys.entries()).map(([key, desc]) => ` - ${key} -- ${desc}`).join('\n')}
1452
+
1453
+ Examples
1454
+ $ ${command} FakeOrg --repoName=test-repo
1455
+ `
1456
+ };
1457
+ const cmdConfigList = {
1458
+ description: config$C.description,
1459
+ hidden: config$C.hidden,
1460
+ run: run$C
1461
+ };
1462
+ async function run$C(argv, importMeta, {
1463
+ parentName
1464
+ }) {
1465
+ const cli = meowOrExit({
1466
+ argv,
1467
+ config: config$C,
1468
+ importMeta,
1469
+ parentName
1470
+ });
1471
+ const {
1472
+ full,
1473
+ json,
1474
+ markdown
1475
+ } = cli.flags;
1476
+ if (cli.flags['dryRun']) {
1477
+ logger.logger.log(DRY_RUN_BAIL_TEXT$B);
1478
+ return;
1479
+ }
1480
+ await outputConfigList({
1481
+ full: !!full,
1482
+ outputKind: json ? 'json' : markdown ? 'markdown' : 'text'
1483
+ });
1484
+ }
1485
+
1486
+ async function outputConfigSet(key, _value, outputKind) {
1487
+ if (outputKind === 'json') {
1488
+ logger.logger.log(JSON.stringify({
1489
+ success: true,
1490
+ message: `Config key '${key}' was updated`
1491
+ }));
1492
+ } else if (outputKind === 'markdown') {
1493
+ logger.logger.log(`# Update config`);
1494
+ logger.logger.log('');
1495
+ logger.logger.log(`Config key '${key}' was updated`);
1496
+ } else {
1497
+ logger.logger.log(`OK`);
1498
+ }
1499
+ }
1500
+
1501
+ async function handleConfigSet({
1502
+ key,
1503
+ outputKind,
1504
+ value
1505
+ }) {
1506
+ shadowNpmInject.updateConfigValue(key, value);
1507
+ await outputConfigSet(key, value, outputKind);
1508
+ }
1509
+
1510
+ const {
1511
+ DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$A
1512
+ } = constants;
1513
+ const config$B = {
1514
+ commandName: 'set',
1515
+ description: 'Update the value of a local CLI config item',
1516
+ hidden: false,
1517
+ flags: {
1518
+ ...commonFlags,
1519
+ ...outputFlags
1520
+ },
1521
+ help: (command, config) => `
1522
+ Usage
1523
+ $ ${command} <key> <value>
1524
+
1525
+ Options
1526
+ ${getFlagListOutput(config.flags, 6)}
1527
+
1528
+ This is a crude way of updating the local configuration for this CLI tool.
1529
+
1530
+ Note that updating a value here is nothing more than updating a key/value
1531
+ store entry. No validation is happening. The server may reject your config.
1532
+
1533
+ Keys:
1534
+
1535
+ ${Array.from(shadowNpmInject.supportedConfigKeys.entries()).map(([key, desc]) => ` - ${key} -- ${desc}`).join('\n')}
1536
+
1537
+ Examples
1538
+ $ ${command} apiProxy https://example.com
1539
+ `
1540
+ };
1541
+ const cmdConfigSet = {
1542
+ description: config$B.description,
1543
+ hidden: config$B.hidden,
1544
+ run: run$B
1545
+ };
1546
+ async function run$B(argv, importMeta, {
1547
+ parentName
1548
+ }) {
1549
+ const cli = meowOrExit({
1550
+ argv,
1551
+ config: config$B,
1552
+ importMeta,
1553
+ parentName
1554
+ });
1555
+ const {
1556
+ json,
1557
+ markdown
1558
+ } = cli.flags;
1559
+ const [key = '', ...rest] = cli.input;
1560
+ const value = rest.join(' ');
1561
+ if (!shadowNpmInject.supportedConfigKeys.has(key) && key !== 'test' || !value) {
1562
+ // Use exit status of 2 to indicate incorrect usage, generally invalid
1563
+ // options or missing arguments.
1564
+ // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
1565
+ process.exitCode = 2;
1566
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
1567
+
1568
+ - Config key should be the first arg ${!key ? colors.red('(missing!)') : !shadowNpmInject.supportedConfigKeys.has(key) ? colors.red('(invalid config key!)') : colors.green('(ok)')}
1569
+
1570
+ - Key value should be the remaining args (use \`del\` to unset a value) ${!value ? colors.red('(missing!)') : colors.green('(ok)')}`);
1571
+ return;
1572
+ }
1573
+ if (cli.flags['dryRun']) {
1574
+ logger.logger.log(DRY_RUN_BAIL_TEXT$A);
1575
+ return;
1576
+ }
1577
+ await handleConfigSet({
1578
+ key: key,
1579
+ outputKind: json ? 'json' : markdown ? 'markdown' : 'text',
1580
+ value
1581
+ });
1582
+ }
1583
+
1584
+ async function outputConfigUnset(key, outputKind) {
1585
+ if (outputKind === 'json') {
1586
+ logger.logger.log(JSON.stringify({
1587
+ success: true,
1588
+ message: `Config key '${key}' was unset`
1589
+ }));
1590
+ } else if (outputKind === 'markdown') {
1591
+ logger.logger.log(`# Update config`);
1592
+ logger.logger.log('');
1593
+ logger.logger.log(`Config key '${key}' was unset`);
1594
+ } else {
1595
+ logger.logger.log(`OK`);
1596
+ }
1597
+ }
1598
+
1599
+ async function handleConfigUnset({
1600
+ key,
1601
+ outputKind
1602
+ }) {
1603
+ shadowNpmInject.updateConfigValue(key, undefined);
1604
+ await outputConfigUnset(key, outputKind);
1605
+ }
1606
+
1607
+ const {
1608
+ DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$z
1609
+ } = constants;
1610
+ const config$A = {
1611
+ commandName: 'unset',
1612
+ description: 'Clear the value of a local CLI config item',
1613
+ hidden: false,
1614
+ flags: {
1615
+ ...commonFlags,
1616
+ ...outputFlags
1617
+ },
1618
+ help: (command, config) => `
1619
+ Usage
1620
+ $ ${command} <org slug>
1621
+
1622
+ Options
1623
+ ${getFlagListOutput(config.flags, 6)}
1624
+
1625
+ Keys:
1626
+
1627
+ ${Array.from(shadowNpmInject.supportedConfigKeys.entries()).map(([key, desc]) => ` - ${key} -- ${desc}`).join('\n')}
1628
+
1629
+ Examples
1630
+ $ ${command} FakeOrg --repoName=test-repo
1631
+ `
1632
+ };
1633
+ const cmdConfigUnset = {
1634
+ description: config$A.description,
1635
+ hidden: config$A.hidden,
1636
+ run: run$A
1637
+ };
1638
+ async function run$A(argv, importMeta, {
1639
+ parentName
1640
+ }) {
1641
+ const cli = meowOrExit({
1642
+ argv,
1643
+ config: config$A,
1644
+ importMeta,
1645
+ parentName
1646
+ });
1647
+ const {
1648
+ json,
1649
+ markdown
1650
+ } = cli.flags;
1651
+ const [key = ''] = cli.input;
1652
+ if (!shadowNpmInject.supportedConfigKeys.has(key) && key !== 'test') {
1653
+ // Use exit status of 2 to indicate incorrect usage, generally invalid
1654
+ // options or missing arguments.
1655
+ // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
1656
+ process.exitCode = 2;
1657
+ logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
1658
+
1659
+ - Config key should be the first arg ${!key ? colors.red('(missing!)') : !shadowNpmInject.supportedConfigKeys.has(key) ? colors.red('(invalid config key!)') : colors.green('(ok)')}
1660
+ `);
1661
+ return;
1662
+ }
1663
+ if (cli.flags['dryRun']) {
1664
+ logger.logger.log(DRY_RUN_BAIL_TEXT$z);
1665
+ return;
1666
+ }
1667
+ await handleConfigUnset({
1668
+ key: key,
1669
+ outputKind: json ? 'json' : markdown ? 'markdown' : 'text'
1670
+ });
1671
+ }
1672
+
1673
+ const description$7 = 'Commands related to the local CLI configuration';
1674
+ const cmdConfig = {
1675
+ description: description$7,
1676
+ hidden: true,
1677
+ // [beta]
1678
+ async run(argv, importMeta, {
1679
+ parentName
1680
+ }) {
1681
+ await meowWithSubcommands({
1682
+ unset: cmdConfigUnset,
1683
+ get: cmdConfigGet,
1684
+ list: cmdConfigList,
1685
+ set: cmdConfigSet
1686
+ }, {
1687
+ argv,
1688
+ description: description$7,
1689
+ importMeta,
1690
+ name: `${parentName} config`
1691
+ });
1692
+ }
1693
+ };
1694
+
1297
1695
  async function fetchDependencies({
1298
1696
  limit,
1299
1697
  offset
@@ -1316,8 +1714,8 @@ async function fetchDependenciesWithToken(apiToken, {
1316
1714
  spinner
1317
1715
  } = constants;
1318
1716
  spinner.start('Fetching organization dependencies...');
1319
- const socketSdk = await shadowNpmInject.setupSdk(apiToken);
1320
- const result = await handleApiCall(socketSdk.searchDependencies({
1717
+ const sockSdk = await shadowNpmInject.setupSdk(apiToken);
1718
+ const result = await handleApiCall(sockSdk.searchDependencies({
1321
1719
  limit,
1322
1720
  offset
1323
1721
  }), 'Searching dependencies');
@@ -1830,12 +2228,12 @@ async function getAlertsMapFromPnpmLockfile(lockfile, options) {
1830
2228
  }
1831
2229
  const getText = () => `Looking up data for ${remaining} packages`;
1832
2230
  spinner?.start(getText());
1833
- const socketSdk = await shadowNpmInject.setupSdk(shadowNpmInject.getPublicToken());
2231
+ const sockSdk = await shadowNpmInject.setupSdk(shadowNpmInject.getPublicToken());
1834
2232
  const toAlertsMapOptions = {
1835
2233
  overrides: lockfile.overrides,
1836
2234
  ...options
1837
2235
  };
1838
- for await (const batchPackageFetchResult of socketSdk.batchPackageStream({
2236
+ for await (const batchPackageFetchResult of sockSdk.batchPackageStream({
1839
2237
  alerts: 'true',
1840
2238
  compact: 'true',
1841
2239
  fixable: include.unfixable ? 'false' : 'true'
@@ -2436,15 +2834,15 @@ async function run$x(argv, importMeta, {
2436
2834
  }
2437
2835
 
2438
2836
  async function fetchPackageInfo(pkgName, pkgVersion, includeAllIssues) {
2439
- const socketSdk = await shadowNpmInject.setupSdk(shadowNpmInject.getPublicToken());
2837
+ const sockSdk = await shadowNpmInject.setupSdk(shadowNpmInject.getPublicToken());
2440
2838
 
2441
2839
  // Lazily access constants.spinner.
2442
2840
  const {
2443
2841
  spinner
2444
2842
  } = constants;
2445
2843
  spinner.start(pkgVersion === 'latest' ? `Looking up data for the latest version of ${pkgName}` : `Looking up data for version ${pkgVersion} of ${pkgName}`);
2446
- const result = await handleApiCall(socketSdk.getIssuesByNPMPackage(pkgName, pkgVersion), 'looking up package');
2447
- const scoreResult = await handleApiCall(socketSdk.getScoreByNPMPackage(pkgName, pkgVersion), 'looking up package score');
2844
+ const result = await handleApiCall(sockSdk.getIssuesByNPMPackage(pkgName, pkgVersion), 'looking up package');
2845
+ const scoreResult = await handleApiCall(sockSdk.getScoreByNPMPackage(pkgName, pkgVersion), 'looking up package score');
2448
2846
  spinner.successAndStop('Data fetched');
2449
2847
  if (result.success === false) {
2450
2848
  return handleUnsuccessfulApiResponse('getIssuesByNPMPackage', result);
@@ -2659,18 +3057,18 @@ async function run$w(argv, importMeta, {
2659
3057
  }
2660
3058
 
2661
3059
  function applyLogin(apiToken, enforcedOrgs, apiBaseUrl, apiProxy) {
2662
- shadowNpmInject.updateSetting('enforcedOrgs', enforcedOrgs);
2663
- shadowNpmInject.updateSetting('apiToken', apiToken);
2664
- shadowNpmInject.updateSetting('apiBaseUrl', apiBaseUrl);
2665
- shadowNpmInject.updateSetting('apiProxy', apiProxy);
3060
+ shadowNpmInject.updateConfigValue('enforcedOrgs', enforcedOrgs);
3061
+ shadowNpmInject.updateConfigValue('apiToken', apiToken);
3062
+ shadowNpmInject.updateConfigValue('apiBaseUrl', apiBaseUrl);
3063
+ shadowNpmInject.updateConfigValue('apiProxy', apiProxy);
2666
3064
  }
2667
3065
 
2668
3066
  const {
2669
3067
  SOCKET_PUBLIC_API_TOKEN
2670
3068
  } = constants;
2671
3069
  async function attemptLogin(apiBaseUrl, apiProxy) {
2672
- apiBaseUrl ??= shadowNpmInject.getSetting('apiBaseUrl') ?? undefined;
2673
- apiProxy ??= shadowNpmInject.getSetting('apiProxy') ?? undefined;
3070
+ apiBaseUrl ??= shadowNpmInject.getConfigValue('apiBaseUrl') ?? undefined;
3071
+ apiProxy ??= shadowNpmInject.getConfigValue('apiProxy') ?? undefined;
2674
3072
  const apiToken = (await prompts.password({
2675
3073
  message: `Enter your ${terminalLink('Socket.dev API key', 'https://docs.socket.dev/docs/api-keys')} (leave blank for a public key)`
2676
3074
  })) || SOCKET_PUBLIC_API_TOKEN;
@@ -2726,7 +3124,7 @@ async function attemptLogin(apiBaseUrl, apiProxy) {
2726
3124
  }
2727
3125
  }
2728
3126
  spinner.stop();
2729
- const oldToken = shadowNpmInject.getSetting('apiToken');
3127
+ const oldToken = shadowNpmInject.getConfigValue('apiToken');
2730
3128
  try {
2731
3129
  applyLogin(apiToken, enforcedOrgs, apiBaseUrl, apiProxy);
2732
3130
  logger.logger.success(`API credentials ${oldToken ? 'updated' : 'set'}`);
@@ -2794,10 +3192,10 @@ async function run$v(argv, importMeta, {
2794
3192
  }
2795
3193
 
2796
3194
  function applyLogout() {
2797
- shadowNpmInject.updateSetting('apiToken', null);
2798
- shadowNpmInject.updateSetting('apiBaseUrl', null);
2799
- shadowNpmInject.updateSetting('apiProxy', null);
2800
- shadowNpmInject.updateSetting('enforcedOrgs', null);
3195
+ shadowNpmInject.updateConfigValue('apiToken', null);
3196
+ shadowNpmInject.updateConfigValue('apiBaseUrl', null);
3197
+ shadowNpmInject.updateConfigValue('apiProxy', null);
3198
+ shadowNpmInject.updateConfigValue('enforcedOrgs', null);
2801
3199
  }
2802
3200
 
2803
3201
  function attemptLogout() {
@@ -4546,14 +4944,14 @@ async function fetchOrganization() {
4546
4944
  return await fetchOrganizationWithToken(apiToken);
4547
4945
  }
4548
4946
  async function fetchOrganizationWithToken(apiToken) {
4549
- const socketSdk = await shadowNpmInject.setupSdk(apiToken);
4947
+ const sockSdk = await shadowNpmInject.setupSdk(apiToken);
4550
4948
 
4551
4949
  // Lazily access constants.spinner.
4552
4950
  const {
4553
4951
  spinner
4554
4952
  } = constants;
4555
4953
  spinner.start('Fetching organization list...');
4556
- const result = await handleApiCall(socketSdk.getOrganizations(), 'looking up organizations');
4954
+ const result = await handleApiCall(sockSdk.getOrganizations(), 'looking up organizations');
4557
4955
  spinner.successAndStop('Received organization list response.');
4558
4956
  if (!result.success) {
4559
4957
  handleUnsuccessfulApiResponse('getOrganizations', result);
@@ -4683,9 +5081,9 @@ async function fetchSecurityPolicyWithToken(apiToken, orgSlug) {
4683
5081
  const {
4684
5082
  spinner
4685
5083
  } = constants;
4686
- const socketSdk = await shadowNpmInject.setupSdk(apiToken);
5084
+ const sockSdk = await shadowNpmInject.setupSdk(apiToken);
4687
5085
  spinner.start('Fetching organization quota...');
4688
- const result = await handleApiCall(socketSdk.getOrgSecurityPolicy(orgSlug), 'looking up organization quota');
5086
+ const result = await handleApiCall(sockSdk.getOrgSecurityPolicy(orgSlug), 'looking up organization quota');
4689
5087
  spinner?.successAndStop('Received organization quota response.');
4690
5088
  if (!result.success) {
4691
5089
  handleUnsuccessfulApiResponse('getOrgSecurityPolicy', result);
@@ -4828,9 +5226,9 @@ async function fetchQuotaWithToken(apiToken) {
4828
5226
  const {
4829
5227
  spinner
4830
5228
  } = constants;
4831
- const socketSdk = await shadowNpmInject.setupSdk(apiToken);
5229
+ const sockSdk = await shadowNpmInject.setupSdk(apiToken);
4832
5230
  spinner.start('Fetching organization quota...');
4833
- const result = await handleApiCall(socketSdk.getQuota(), 'looking up organization quota');
5231
+ const result = await handleApiCall(sockSdk.getQuota(), 'looking up organization quota');
4834
5232
  spinner?.successAndStop('Recieved organization quota response.');
4835
5233
  if (!result.success) {
4836
5234
  handleUnsuccessfulApiResponse('getQuota', result);
@@ -4957,8 +5355,8 @@ async function fetchPurlsShallowScore(purls) {
4957
5355
  spinner
4958
5356
  } = constants;
4959
5357
  spinner.start(`Requesting data ...`);
4960
- const socketSdk = await shadowNpmInject.setupSdk(shadowNpmInject.getPublicToken());
4961
- const result = await handleApiCall(socketSdk.batchPackageFetch({
5358
+ const sockSdk = await shadowNpmInject.setupSdk(shadowNpmInject.getPublicToken());
5359
+ const result = await handleApiCall(sockSdk.batchPackageFetch({
4962
5360
  alerts: 'true'
4963
5361
  // compact: false,
4964
5362
  // fixable: false,
@@ -5359,8 +5757,8 @@ async function createReport(socketConfig, inputPaths, {
5359
5757
  const {
5360
5758
  spinner
5361
5759
  } = constants;
5362
- const socketSdk = await shadowNpmInject.setupSdk();
5363
- const supportedFiles = await socketSdk.getReportSupportedFiles().then(res => {
5760
+ const sockSdk = await shadowNpmInject.setupSdk();
5761
+ const supportedFiles = await sockSdk.getReportSupportedFiles().then(res => {
5364
5762
  if (!res.success) handleUnsuccessfulApiResponse('getReportSupportedFiles', res);
5365
5763
  return res.data;
5366
5764
  }).catch(cause => {
@@ -5368,7 +5766,7 @@ async function createReport(socketConfig, inputPaths, {
5368
5766
  cause
5369
5767
  });
5370
5768
  });
5371
- const packagePaths = await shadowNpmPaths.getPackageFilesFullScans(cwd, inputPaths, supportedFiles, socketConfig);
5769
+ const packagePaths = await shadowNpmPaths.getPackageFilesForScan(cwd, inputPaths, supportedFiles, socketConfig);
5372
5770
  const packagePathsCount = packagePaths.length;
5373
5771
  if (packagePathsCount && debug.isDebug()) {
5374
5772
  for (const pkgPath of packagePaths) {
@@ -5380,7 +5778,7 @@ async function createReport(socketConfig, inputPaths, {
5380
5778
  return undefined;
5381
5779
  }
5382
5780
  spinner.start(`Creating report with ${packagePathsCount} package ${words.pluralize('file', packagePathsCount)}`);
5383
- const apiCall = socketSdk.createReportFromFilePaths(packagePaths, cwd, socketConfig?.issueRules);
5781
+ const apiCall = sockSdk.createReportFromFilePaths(packagePaths, cwd, socketConfig?.issueRules);
5384
5782
  const result = await handleApiCall(apiCall, 'creating report');
5385
5783
  if (!result.success) {
5386
5784
  handleUnsuccessfulApiResponse('createReport', result);
@@ -5391,8 +5789,8 @@ async function createReport(socketConfig, inputPaths, {
5391
5789
  }
5392
5790
 
5393
5791
  async function getSocketConfig(absoluteConfigPath) {
5394
- const socketConfig = await config$D.readSocketConfig(absoluteConfigPath).catch(cause => {
5395
- if (cause && typeof cause === 'object' && cause instanceof config$D.SocketValidationError) {
5792
+ const socketConfig = await config$H.readSocketConfig(absoluteConfigPath).catch(cause => {
5793
+ if (cause && typeof cause === 'object' && cause instanceof config$H.SocketValidationError) {
5396
5794
  // Inspired by workbox-build:
5397
5795
  // https://github.com/GoogleChrome/workbox/blob/95f97a207fd51efb3f8a653f6e3e58224183a778/packages/workbox-build/src/lib/validate-options.ts#L68-L71
5398
5796
  const betterErrors = betterAjvErrors.betterAjvErrors({
@@ -5420,12 +5818,12 @@ async function fetchReportData$1(reportId, includeAllIssues, strict) {
5420
5818
  } = constants;
5421
5819
  spinner.log('Fetching report with ID ${reportId} (this could take a while)');
5422
5820
  spinner.start(`Fetch started... (this could take a while)`);
5423
- const socketSdk = await shadowNpmInject.setupSdk();
5821
+ const sockSdk = await shadowNpmInject.setupSdk();
5424
5822
  let result;
5425
5823
  for (let retry = 1; !result; ++retry) {
5426
5824
  try {
5427
5825
  // eslint-disable-next-line no-await-in-loop
5428
- result = await handleApiCall(socketSdk.getReport(reportId), 'fetching report');
5826
+ result = await handleApiCall(sockSdk.getReport(reportId), 'fetching report');
5429
5827
  } catch (err) {
5430
5828
  if (retry >= MAX_TIMEOUT_RETRY || !(err instanceof Error) || err.cause?.cause?.response?.statusCode !== HTTP_CODE_TIMEOUT) {
5431
5829
  spinner.stop(`Failed to fetch report`);
@@ -5477,7 +5875,7 @@ function formatReportDataOutput(reportId, data, commandName, outputKind, strict,
5477
5875
  }
5478
5876
  }
5479
5877
 
5480
- async function getFullScan(orgSlug, fullScanId) {
5878
+ async function fetchScan(orgSlug, scanId) {
5481
5879
  // Lazily access constants.spinner.
5482
5880
  const {
5483
5881
  spinner
@@ -5487,7 +5885,7 @@ async function getFullScan(orgSlug, fullScanId) {
5487
5885
  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.');
5488
5886
  }
5489
5887
  spinner.start('Fetching full-scan...');
5490
- const response = await queryApi(`orgs/${orgSlug}/full-scans/${encodeURIComponent(fullScanId)}`, apiToken);
5888
+ const response = await queryApi(`orgs/${orgSlug}/full-scans/${encodeURIComponent(scanId)}`, apiToken);
5491
5889
  spinner.stop('Fetch complete.');
5492
5890
  if (!response.ok) {
5493
5891
  const err = await handleApiError(response.status);
@@ -5516,7 +5914,7 @@ async function viewReport(reportId, {
5516
5914
  strict
5517
5915
  }) {
5518
5916
  const result = await fetchReportData$1(reportId, all, strict);
5519
- const artifacts = await getFullScan('socketdev', reportId);
5917
+ const artifacts = await fetchScan('socketdev', reportId);
5520
5918
  if (result) {
5521
5919
  formatReportDataOutput(reportId, result, commandName, outputKind, strict, artifacts);
5522
5920
  }
@@ -5717,9 +6115,9 @@ async function fetchCreateRepoWithToken(apiToken, {
5717
6115
  const {
5718
6116
  spinner
5719
6117
  } = constants;
5720
- const socketSdk = await shadowNpmInject.setupSdk(apiToken);
6118
+ const sockSdk = await shadowNpmInject.setupSdk(apiToken);
5721
6119
  spinner.start('Sending request ot create a repository...');
5722
- const result = await handleApiCall(socketSdk.createOrgRepo(orgSlug, {
6120
+ const result = await handleApiCall(sockSdk.createOrgRepo(orgSlug, {
5723
6121
  name: repoName,
5724
6122
  description,
5725
6123
  homepage,
@@ -5864,8 +6262,8 @@ async function deleteRepoWithToken(orgSlug, repoName, apiToken) {
5864
6262
  spinner
5865
6263
  } = constants;
5866
6264
  spinner.start('Deleting repository...');
5867
- const socketSdk = await shadowNpmInject.setupSdk(apiToken);
5868
- const result = await handleApiCall(socketSdk.deleteOrgRepo(orgSlug, repoName), 'deleting repository');
6265
+ const sockSdk = await shadowNpmInject.setupSdk(apiToken);
6266
+ const result = await handleApiCall(sockSdk.deleteOrgRepo(orgSlug, repoName), 'deleting repository');
5869
6267
  if (!result.success) {
5870
6268
  handleUnsuccessfulApiResponse('deleteOrgRepo', result);
5871
6269
  return;
@@ -5960,9 +6358,9 @@ async function fetchListReposWithToken(apiToken, {
5960
6358
  const {
5961
6359
  spinner
5962
6360
  } = constants;
5963
- const socketSdk = await shadowNpmInject.setupSdk(apiToken);
6361
+ const sockSdk = await shadowNpmInject.setupSdk(apiToken);
5964
6362
  spinner.start('Fetching list of repositories...');
5965
- const result = await handleApiCall(socketSdk.getOrgRepoList(orgSlug, {
6363
+ const result = await handleApiCall(sockSdk.getOrgRepoList(orgSlug, {
5966
6364
  sort,
5967
6365
  direction,
5968
6366
  per_page: String(per_page),
@@ -6149,8 +6547,8 @@ async function fetchUpdateRepoWithToken(apiToken, {
6149
6547
  spinner
6150
6548
  } = constants;
6151
6549
  spinner.start('Sending request to update a repository...');
6152
- const socketSdk = await shadowNpmInject.setupSdk(apiToken);
6153
- const result = await handleApiCall(socketSdk.updateOrgRepo(orgSlug, repoName, {
6550
+ const sockSdk = await shadowNpmInject.setupSdk(apiToken);
6551
+ const result = await handleApiCall(sockSdk.updateOrgRepo(orgSlug, repoName, {
6154
6552
  orgSlug,
6155
6553
  name: repoName,
6156
6554
  description,
@@ -6297,9 +6695,9 @@ async function fetchViewRepoWithToken(orgSlug, repoName, apiToken) {
6297
6695
  const {
6298
6696
  spinner
6299
6697
  } = constants;
6300
- const socketSdk = await shadowNpmInject.setupSdk(apiToken);
6698
+ const sockSdk = await shadowNpmInject.setupSdk(apiToken);
6301
6699
  spinner.start('Fetching repository data...');
6302
- const result = await handleApiCall(socketSdk.getOrgRepo(orgSlug, repoName), 'fetching repository');
6700
+ const result = await handleApiCall(sockSdk.getOrgRepo(orgSlug, repoName), 'fetching repository');
6303
6701
  spinner.successAndStop('Received response while fetched repository data.');
6304
6702
  if (!result.success) {
6305
6703
  handleUnsuccessfulApiResponse('getOrgRepo', result);
@@ -6453,8 +6851,106 @@ const cmdRepos = {
6453
6851
  }
6454
6852
  };
6455
6853
 
6456
- async function suggestOrgSlug(socketSdk) {
6457
- const result = await handleApiCall(socketSdk.getOrganizations(), 'looking up organizations');
6854
+ async function fetchCreateOrgFullScan(packagePaths, orgSlug, repoName, branchName, commitMessage, defaultBranch, pendingHead, tmp, cwd) {
6855
+ const sockSdk = await shadowNpmInject.setupSdk();
6856
+
6857
+ // Lazily access constants.spinner.
6858
+ const {
6859
+ spinner
6860
+ } = constants;
6861
+ spinner.start(`Creating a scan with ${packagePaths.length} packages...`);
6862
+ const result = await handleApiCall(sockSdk.createOrgFullScan(orgSlug, {
6863
+ repo: repoName,
6864
+ branch: branchName,
6865
+ commit_message: commitMessage,
6866
+ make_default_branch: String(defaultBranch),
6867
+ set_as_pending_head: String(pendingHead),
6868
+ tmp: String(tmp)
6869
+ }, packagePaths, cwd), 'Creating scan');
6870
+ spinner.successAndStop('Scan created successfully');
6871
+ if (!result.success) {
6872
+ handleUnsuccessfulApiResponse('CreateOrgFullScan', result);
6873
+ return;
6874
+ }
6875
+ return result.data;
6876
+ }
6877
+
6878
+ async function fetchSupportedScanFileNames() {
6879
+ const sockSdk = await shadowNpmInject.setupSdk();
6880
+
6881
+ // Lazily access constants.spinner.
6882
+ const {
6883
+ spinner
6884
+ } = constants;
6885
+ spinner.start('Requesting supported scan file types from API...');
6886
+ const result = await handleApiCall(sockSdk.getReportSupportedFiles(), 'fetching supported scan file types');
6887
+ spinner.successAndStop('Received response while fetched supported scan file types.');
6888
+ if (!result.success) {
6889
+ handleUnsuccessfulApiResponse('getReportSupportedFiles', result);
6890
+ return;
6891
+ }
6892
+ return result.data;
6893
+ }
6894
+
6895
+ async function outputCreateNewScan(data) {
6896
+ const link = colors.underline(colors.cyan(`${data.html_report_url}`));
6897
+ logger.logger.log(`Available at: ${link}`);
6898
+ const rl = readline.createInterface({
6899
+ input: process$1.stdin,
6900
+ output: process$1.stdout
6901
+ });
6902
+ const answer = await rl.question('Would you like to open it in your browser? (y/n)');
6903
+ if (answer.toLowerCase() === 'y') {
6904
+ await open(`${data.html_report_url}`);
6905
+ }
6906
+ rl.close();
6907
+ }
6908
+
6909
+ async function handleCreateNewScan({
6910
+ branchName,
6911
+ commitMessage,
6912
+ cwd,
6913
+ defaultBranch,
6914
+ orgSlug,
6915
+ pendingHead,
6916
+ readOnly,
6917
+ repoName,
6918
+ targets,
6919
+ tmp
6920
+ }) {
6921
+ const apiToken = shadowNpmInject.getDefaultToken();
6922
+
6923
+ // Note: you need an apiToken to request supportedScanFileNames from the API
6924
+ if (!apiToken) {
6925
+ throw new shadowNpmInject.AuthError('User must be authenticated to create and submit new scans. To log in, run the command `socket login` and enter your API key.');
6926
+ }
6927
+ const supportedFileNames = await fetchSupportedScanFileNames();
6928
+ if (!supportedFileNames) return;
6929
+ const packagePaths = await shadowNpmPaths.getPackageFilesForScan(cwd, targets, supportedFileNames
6930
+ // socketConfig
6931
+ );
6932
+ if (!packagePaths.length) {
6933
+ // Use exit status of 2 to indicate incorrect usage, generally invalid
6934
+ // options or missing arguments.
6935
+ // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
6936
+ process$1.exitCode = 2;
6937
+ logger.logger.fail(commonTags.stripIndents`
6938
+ ${colors.bgRed(colors.white('Input error'))}: The TARGET did not contain any matching / supported files for a scan
6939
+ `);
6940
+ return;
6941
+ }
6942
+ if (readOnly) {
6943
+ logger.logger.log('[ReadOnly] Bailing now');
6944
+ return;
6945
+ }
6946
+ const data = await fetchCreateOrgFullScan(packagePaths, orgSlug, repoName, branchName, commitMessage, defaultBranch, pendingHead, tmp, cwd);
6947
+ if (!data) return;
6948
+ await outputCreateNewScan(data);
6949
+ }
6950
+
6951
+ async function suggestOrgSlug() {
6952
+ const sockSdk = await shadowNpmInject.setupSdk();
6953
+ const result = await handleApiCall(sockSdk.getOrganizations(), 'looking up organizations');
6458
6954
  // Ignore a failed request here. It was not the primary goal of
6459
6955
  // running this command and reporting it only leads to end-user confusion.
6460
6956
  if (result.success) {
@@ -6475,13 +6971,17 @@ async function suggestOrgSlug(socketSdk) {
6475
6971
  if (proceed) {
6476
6972
  return proceed;
6477
6973
  }
6974
+ } else {
6975
+ logger.logger.fail('Failed to lookup organization list from API, unable to suggest.');
6478
6976
  }
6479
6977
  }
6480
6978
 
6481
- async function suggestRepoSlug(socketSdk, orgSlug) {
6979
+ async function suggestRepoSlug(orgSlug) {
6980
+ const sockSdk = await shadowNpmInject.setupSdk();
6981
+
6482
6982
  // Same as above, but if there's a repo with the same name as cwd then
6483
6983
  // default the selection to that name.
6484
- const result = await handleApiCall(socketSdk.getOrgRepoList(orgSlug, {
6984
+ const result = await handleApiCall(sockSdk.getOrgRepoList(orgSlug, {
6485
6985
  orgSlug,
6486
6986
  sort: 'name',
6487
6987
  direction: 'asc',
@@ -6491,6 +6991,7 @@ async function suggestRepoSlug(socketSdk, orgSlug) {
6491
6991
  perPage: '10',
6492
6992
  page: '0'
6493
6993
  }), 'looking up known repos');
6994
+
6494
6995
  // Ignore a failed request here. It was not the primary goal of
6495
6996
  // running this command and reporting it only leads to end-user confusion.
6496
6997
  if (result.success) {
@@ -6498,7 +6999,7 @@ async function suggestRepoSlug(socketSdk, orgSlug) {
6498
6999
  let cwdIsKnown = !!currentDirName && result.data.results.some(obj => obj.slug === currentDirName);
6499
7000
  if (!cwdIsKnown && currentDirName) {
6500
7001
  // Do an explicit request so we can assert that the cwd exists or not
6501
- const result = await handleApiCall(socketSdk.getOrgRepo(orgSlug, currentDirName), 'checking if current cwd is a known repo');
7002
+ const result = await handleApiCall(sockSdk.getOrgRepo(orgSlug, currentDirName), 'checking if current cwd is a known repo');
6502
7003
  if (result.success) {
6503
7004
  cwdIsKnown = true;
6504
7005
  }
@@ -6537,203 +7038,64 @@ async function suggestRepoSlug(socketSdk, orgSlug) {
6537
7038
  }
6538
7039
  });
6539
7040
  return {
6540
- slug: repoName,
6541
- defaultBranch: repoDefaultBranch
6542
- };
6543
- }
6544
- }
6545
- }
6546
- function dirNameToSlug(name) {
6547
- // Uses slug specs asserted by our servers
6548
- // Note: this can lead to collisions; eg. slug for `x--y` and `x---y` is `x-y`
6549
- return name.toLowerCase().replace(/[^[a-zA-Z0-9_.-]/g, '_').replace(/--+/g, '-').replace(/__+/g, '_').replace(/\.\.+/g, '.').replace(/[._-]+$/, '');
6550
- }
6551
-
6552
- async function suggestBranchSlug(repoDefaultBranch) {
6553
- const spawnResult = spawn.spawnSync('git', ['branch', '--show-current']);
6554
- const currentBranch = spawnResult.stdout.toString('utf8').trim();
6555
- if (currentBranch && spawnResult.status === 0) {
6556
- const proceed = await prompts.select({
6557
- message: 'Use the current git branch as target branch name?',
6558
- choices: [{
6559
- name: `Yes [${currentBranch}]`,
6560
- value: currentBranch,
6561
- description: 'Use the current git branch for branch name'
6562
- }, ...(repoDefaultBranch && repoDefaultBranch !== currentBranch ? [{
6563
- name: `No, use the default branch [${repoDefaultBranch}]`,
6564
- value: repoDefaultBranch,
6565
- description: 'Use the default branch for target repo as the target branch name'
6566
- }] : []), {
6567
- name: 'No',
6568
- value: '',
6569
- description: 'Do not use the current git branch as name (will end in a no-op)'
6570
- }].filter(Boolean)
6571
- });
6572
- if (proceed) {
6573
- return proceed;
6574
- }
6575
- }
6576
- }
6577
-
6578
- async function suggestTarget() {
6579
- // We could prefill this with sub-dirs of the current
6580
- // dir ... but is that going to be useful?
6581
- const proceed = await prompts.select({
6582
- message: 'No TARGET given. Do you want to use the current directory?',
6583
- choices: [{
6584
- name: 'Yes',
6585
- value: true,
6586
- description: 'Target the current directory'
6587
- }, {
6588
- name: 'No',
6589
- value: false,
6590
- description: 'Do not use the current directory (this will end in a no-op)'
6591
- }]
6592
- });
6593
- if (proceed) {
6594
- return ['.'];
6595
- }
6596
- }
6597
-
6598
- async function createFullScan({
6599
- branchName,
6600
- commitHash: _commitHash,
6601
- commitMessage,
6602
- committers: _committers,
6603
- cwd,
6604
- defaultBranch,
6605
- orgSlug,
6606
- pendingHead,
6607
- pullRequest: _pullRequest,
6608
- readOnly,
6609
- repoName,
6610
- targets,
6611
- tmp
6612
- }) {
6613
- // Lazily access constants.spinner.
6614
- const {
6615
- spinner
6616
- } = constants;
6617
- const socketSdk = await shadowNpmInject.setupSdk();
6618
- const supportedFiles = await socketSdk.getReportSupportedFiles().then(res => {
6619
- if (!res.success) {
6620
- handleUnsuccessfulApiResponse('getReportSupportedFiles', res);
6621
- assert(false, 'handleUnsuccessfulApiResponse should unconditionally throw');
6622
- }
6623
- return res.data;
6624
- }).catch(cause => {
6625
- throw new Error('Failed getting supported files for report', {
6626
- cause
6627
- });
6628
- });
6629
-
6630
- // If we updated any inputs then we should print the command line to repeat
6631
- // the command without requiring user input, as a suggestion.
6632
- let updatedInput = false;
6633
- if (!targets.length) {
6634
- const received = await suggestTarget();
6635
- targets = received ?? [];
6636
- updatedInput = true;
6637
- }
6638
-
6639
- // // TODO: we'll probably use socket.json or something else soon...
6640
- // const absoluteConfigPath = path.join(cwd, 'socket.yml')
6641
- // const socketConfig = await getSocketConfig(absoluteConfigPath)
6642
-
6643
- const packagePaths = await shadowNpmPaths.getPackageFilesFullScans(cwd, targets, supportedFiles
6644
- // socketConfig
6645
- );
6646
-
6647
- // We're going to need an api token to suggest data because those suggestions
6648
- // must come from data we already know. Don't error on missing api token yet.
6649
- // If the api-token is not set, ignore it for the sake of suggestions.
6650
- const apiToken = shadowNpmInject.getDefaultToken();
6651
-
6652
- // If the current cwd is unknown and is used as a repo slug anyways, we will
6653
- // first need to register the slug before we can use it.
6654
- let repoDefaultBranch = '';
6655
- if (apiToken) {
6656
- if (!orgSlug) {
6657
- const suggestion = await suggestOrgSlug(socketSdk);
6658
- if (suggestion) orgSlug = suggestion;
6659
- updatedInput = true;
6660
- }
6661
-
6662
- // (Don't bother asking for the rest if we didn't get an org slug above)
6663
- if (orgSlug && !repoName) {
6664
- const suggestion = await suggestRepoSlug(socketSdk, orgSlug);
6665
- if (suggestion) {
6666
- repoDefaultBranch = suggestion.defaultBranch;
6667
- repoName = suggestion.slug;
6668
- }
6669
- updatedInput = true;
6670
- }
6671
-
6672
- // (Don't bother asking for the rest if we didn't get an org/repo above)
6673
- if (orgSlug && repoName && !branchName) {
6674
- const suggestion = await suggestBranchSlug(repoDefaultBranch);
6675
- if (suggestion) branchName = suggestion;
6676
- updatedInput = true;
7041
+ slug: repoName,
7042
+ defaultBranch: repoDefaultBranch
7043
+ };
6677
7044
  }
7045
+ } else {
7046
+ logger.logger.fail('Failed to lookup repo list from API, unable to suggest.');
6678
7047
  }
6679
- if (!orgSlug || !repoName || !branchName || !packagePaths.length) {
6680
- // Use exit status of 2 to indicate incorrect usage, generally invalid
6681
- // options or missing arguments.
6682
- // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
6683
- process$1.exitCode = 2;
6684
- logger.logger.fail(commonTags.stripIndents`
6685
- ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
6686
-
6687
- - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
6688
-
6689
- - Repository name using --repo ${!repoName ? colors.red('(missing!)') : colors.green('(ok)')}
6690
-
6691
- - Branch name using --branch ${!branchName ? colors.red('(missing!)') : colors.green('(ok)')}
6692
-
6693
- - 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)')}
7048
+ }
7049
+ function dirNameToSlug(name) {
7050
+ // Uses slug specs asserted by our servers
7051
+ // Note: this can lead to collisions; eg. slug for `x--y` and `x---y` is `x-y`
7052
+ return name.toLowerCase().replace(/[^[a-zA-Z0-9_.-]/g, '_').replace(/--+/g, '-').replace(/__+/g, '_').replace(/\.\.+/g, '.').replace(/[._-]+$/, '');
7053
+ }
6694
7054
 
6695
- ${!apiToken ? 'Note: was unable to make suggestions because no API Token was found; this would make command fail regardless' : ''}
6696
- `);
6697
- return;
6698
- }
6699
- if (updatedInput) {
6700
- logger.logger.log('Note: You can invoke this command next time to skip the interactive questions:');
6701
- logger.logger.log('```');
6702
- logger.logger.log(` socket scan create [other flags...] --repo ${repoName} --branch ${branchName} ${orgSlug} ${targets.join(' ')}`);
6703
- logger.logger.log('```');
6704
- }
6705
- if (!apiToken) {
6706
- 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.');
6707
- }
6708
- if (readOnly) {
6709
- logger.logger.log('[ReadOnly] Bailing now');
6710
- return;
6711
- }
6712
- spinner.start(`Creating a scan with ${packagePaths.length} packages...`);
6713
- const result = await handleApiCall(socketSdk.createOrgFullScan(orgSlug, {
6714
- repo: repoName,
6715
- branch: branchName,
6716
- commit_message: commitMessage,
6717
- make_default_branch: String(defaultBranch),
6718
- set_as_pending_head: String(pendingHead),
6719
- tmp: String(tmp)
6720
- }, packagePaths, cwd), 'Creating scan');
6721
- if (!result.success) {
6722
- handleUnsuccessfulApiResponse('CreateOrgFullScan', result);
6723
- return;
7055
+ async function suggestBranchSlug(repoDefaultBranch) {
7056
+ const spawnResult = spawn.spawnSync('git', ['branch', '--show-current']);
7057
+ const currentBranch = spawnResult.stdout.toString('utf8').trim();
7058
+ if (currentBranch && spawnResult.status === 0) {
7059
+ const proceed = await prompts.select({
7060
+ message: 'Use the current git branch as target branch name?',
7061
+ choices: [{
7062
+ name: `Yes [${currentBranch}]`,
7063
+ value: currentBranch,
7064
+ description: 'Use the current git branch for branch name'
7065
+ }, ...(repoDefaultBranch && repoDefaultBranch !== currentBranch ? [{
7066
+ name: `No, use the default branch [${repoDefaultBranch}]`,
7067
+ value: repoDefaultBranch,
7068
+ description: 'Use the default branch for target repo as the target branch name'
7069
+ }] : []), {
7070
+ name: 'No',
7071
+ value: '',
7072
+ description: 'Do not use the current git branch as name (will end in a no-op)'
7073
+ }].filter(Boolean)
7074
+ });
7075
+ if (proceed) {
7076
+ return proceed;
7077
+ }
6724
7078
  }
6725
- spinner.successAndStop('Scan created successfully');
6726
- const link = colors.underline(colors.cyan(`${result.data.html_report_url}`));
6727
- logger.logger.log(`Available at: ${link}`);
6728
- const rl = readline.createInterface({
6729
- input: process$1.stdin,
6730
- output: process$1.stdout
7079
+ }
7080
+
7081
+ async function suggestTarget() {
7082
+ // We could prefill this with sub-dirs of the current
7083
+ // dir ... but is that going to be useful?
7084
+ const proceed = await prompts.select({
7085
+ message: 'No TARGET given. Do you want to use the current directory?',
7086
+ choices: [{
7087
+ name: 'Yes',
7088
+ value: true,
7089
+ description: 'Target the current directory'
7090
+ }, {
7091
+ name: 'No',
7092
+ value: false,
7093
+ description: 'Do not use the current directory (this will end in a no-op)'
7094
+ }]
6731
7095
  });
6732
- const answer = await rl.question('Would you like to open it in your browser? (y/n)');
6733
- if (answer.toLowerCase() === 'y') {
6734
- await open(`${result.data.html_report_url}`);
7096
+ if (proceed) {
7097
+ return ['.'];
6735
7098
  }
6736
- rl.close();
6737
7099
  }
6738
7100
 
6739
7101
  const {
@@ -6857,18 +7219,66 @@ async function run$7(argv, importMeta, {
6857
7219
  importMeta,
6858
7220
  parentName
6859
7221
  });
6860
- const [orgSlug = '', ...targets] = cli.input;
6861
- const cwd = cli.flags['cwd'] && cli.flags['cwd'] !== 'process.cwd()' ? String(cli.flags['cwd']) : process$1.cwd();
6862
7222
  const {
7223
+ cwd: cwdOverride,
7224
+ dryRun
7225
+ } = cli.flags;
7226
+ const cwd = cwdOverride && cwdOverride !== 'process.cwd()' ? String(cwdOverride) : process$1.cwd();
7227
+ let {
6863
7228
  branch: branchName,
6864
7229
  repo: repoName
6865
7230
  } = cli.flags;
6866
- const apiToken = shadowNpmInject.getDefaultToken(); // This checks if we _can_ suggest anything
7231
+ let [orgSlug = '', ...targets] = cli.input;
6867
7232
 
6868
- if (!apiToken && (!orgSlug || !repoName || !branchName || !targets.length)) {
6869
- // Without api token we cannot recover because we can't request more info
6870
- // from the server, to match and help with the current cwd/git status.
6871
- //
7233
+ // We're going to need an api token to suggest data because those suggestions
7234
+ // must come from data we already know. Don't error on missing api token yet.
7235
+ // If the api-token is not set, ignore it for the sake of suggestions.
7236
+ const apiToken = shadowNpmInject.getDefaultToken();
7237
+
7238
+ // If we updated any inputs then we should print the command line to repeat
7239
+ // the command without requiring user input, as a suggestion.
7240
+ let updatedInput = false;
7241
+ if (!targets.length && !dryRun) {
7242
+ const received = await suggestTarget();
7243
+ targets = received ?? [];
7244
+ updatedInput = true;
7245
+ }
7246
+
7247
+ // If the current cwd is unknown and is used as a repo slug anyways, we will
7248
+ // first need to register the slug before we can use it.
7249
+ let repoDefaultBranch = '';
7250
+ // Only do suggestions with an apiToken and when not in dryRun mode
7251
+ if (apiToken && !dryRun) {
7252
+ if (!orgSlug) {
7253
+ const suggestion = await suggestOrgSlug();
7254
+ if (suggestion) orgSlug = suggestion;
7255
+ updatedInput = true;
7256
+ }
7257
+
7258
+ // (Don't bother asking for the rest if we didn't get an org slug above)
7259
+ if (orgSlug && !repoName) {
7260
+ const suggestion = await suggestRepoSlug(orgSlug);
7261
+ if (suggestion) {
7262
+ repoDefaultBranch = suggestion.defaultBranch;
7263
+ repoName = suggestion.slug;
7264
+ }
7265
+ updatedInput = true;
7266
+ }
7267
+
7268
+ // (Don't bother asking for the rest if we didn't get an org/repo above)
7269
+ if (orgSlug && repoName && !branchName) {
7270
+ const suggestion = await suggestBranchSlug(repoDefaultBranch);
7271
+ if (suggestion) branchName = suggestion;
7272
+ updatedInput = true;
7273
+ }
7274
+ }
7275
+ if (updatedInput && repoName && branchName && orgSlug && targets?.length) {
7276
+ logger.logger.error('Note: You can invoke this command next time to skip the interactive questions:');
7277
+ logger.logger.error('```');
7278
+ logger.logger.error(` socket scan create [other flags...] --repo ${repoName} --branch ${branchName} ${orgSlug} ${targets.join(' ')}`);
7279
+ logger.logger.error('```\n');
7280
+ }
7281
+ if (!orgSlug || !repoName || !branchName || !targets.length) {
6872
7282
  // Use exit status of 2 to indicate incorrect usage, generally invalid
6873
7283
  // options or missing arguments.
6874
7284
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
@@ -6882,28 +7292,25 @@ async function run$7(argv, importMeta, {
6882
7292
 
6883
7293
  - Branch name using --branch ${!branchName ? colors.red('(missing!)') : colors.green('(ok)')}
6884
7294
 
6885
- - At least one TARGET (e.g. \`.\` or \`./package.json\`) ${!targets.length ? '(missing)' : colors.green('(ok)')}
7295
+ - At least one TARGET (e.g. \`.\` or \`./package.json\`) ${!targets.length ? colors.red('(missing)') : colors.green('(ok)')}
6886
7296
 
6887
- (Additionally, no API Token was set so we cannot auto-discover these details)
7297
+ ${!apiToken ? 'Note: was unable to make suggestions because no API Token was found; this would make the command fail regardless' : ''}
6888
7298
  `);
6889
7299
  return;
6890
7300
  }
6891
7301
 
6892
7302
  // Note exiting earlier to skirt a hidden auth requirement
6893
- if (cli.flags['dryRun']) {
7303
+ if (dryRun) {
6894
7304
  logger.logger.log(DRY_RUN_BAIL_TEXT$7);
6895
7305
  return;
6896
7306
  }
6897
- await createFullScan({
7307
+ await handleCreateNewScan({
6898
7308
  branchName: branchName,
6899
- commitHash: cli.flags['commitHash'] ?? '',
6900
7309
  commitMessage: cli.flags['commitMessage'] ?? '',
6901
- committers: cli.flags['committers'] ?? '',
6902
7310
  cwd,
6903
7311
  defaultBranch: Boolean(cli.flags['defaultBranch']),
6904
7312
  orgSlug,
6905
7313
  pendingHead: Boolean(cli.flags['pendingHead']),
6906
- pullRequest: cli.flags['pullRequest'] ?? undefined,
6907
7314
  readOnly: Boolean(cli.flags['readOnly']),
6908
7315
  repoName: repoName,
6909
7316
  targets,
@@ -6911,26 +7318,37 @@ async function run$7(argv, importMeta, {
6911
7318
  });
6912
7319
  }
6913
7320
 
6914
- async function deleteOrgFullScan(orgSlug, fullScanId) {
7321
+ async function fetchDeleteOrgFullScan(orgSlug, scanId) {
6915
7322
  const apiToken = shadowNpmInject.getDefaultToken();
6916
7323
  if (!apiToken) {
6917
7324
  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.');
6918
7325
  }
6919
- await deleteOrgFullScanWithToken(orgSlug, fullScanId, apiToken);
7326
+ await fetchDeleteOrgFullScanWithToken(apiToken, orgSlug, scanId);
6920
7327
  }
6921
- async function deleteOrgFullScanWithToken(orgSlug, fullScanId, apiToken) {
7328
+ async function fetchDeleteOrgFullScanWithToken(apiToken, orgSlug, scanId) {
6922
7329
  // Lazily access constants.spinner.
6923
7330
  const {
6924
7331
  spinner
6925
7332
  } = constants;
6926
- spinner.start('Deleting scan...');
6927
- const socketSdk = await shadowNpmInject.setupSdk(apiToken);
6928
- const result = await handleApiCall(socketSdk.deleteOrgFullScan(orgSlug, fullScanId), 'Deleting scan');
7333
+ const sockSdk = await shadowNpmInject.setupSdk(apiToken);
7334
+ spinner.start('Requesting the scan to be deleted...');
7335
+ const result = await handleApiCall(sockSdk.deleteOrgFullScan(orgSlug, scanId), 'Deleting scan');
7336
+ spinner.successAndStop('Received response for deleting a scan.');
6929
7337
  if (!result.success) {
6930
7338
  handleUnsuccessfulApiResponse('deleteOrgFullScan', result);
6931
7339
  return;
6932
7340
  }
6933
- spinner.successAndStop('Scan deleted successfully');
7341
+ return result.data;
7342
+ }
7343
+
7344
+ async function outputDeleteScan(_data) {
7345
+ logger.logger.success('Scan deleted successfully');
7346
+ }
7347
+
7348
+ async function handleDeleteScan(orgSlug, scanId) {
7349
+ const data = await fetchDeleteOrgFullScan(orgSlug, scanId);
7350
+ if (!data) return;
7351
+ await outputDeleteScan();
6934
7352
  }
6935
7353
 
6936
7354
  const {
@@ -6969,8 +7387,8 @@ async function run$6(argv, importMeta, {
6969
7387
  importMeta,
6970
7388
  parentName
6971
7389
  });
6972
- const [orgSlug = '', fullScanId = ''] = cli.input;
6973
- if (!orgSlug || !fullScanId) {
7390
+ const [orgSlug = '', scanId = ''] = cli.input;
7391
+ if (!orgSlug || !scanId) {
6974
7392
  // Use exit status of 2 to indicate incorrect usage, generally invalid
6975
7393
  // options or missing arguments.
6976
7394
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
@@ -6979,22 +7397,20 @@ async function run$6(argv, importMeta, {
6979
7397
 
6980
7398
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
6981
7399
 
6982
- - Full Scan ID to delete as second argument ${!fullScanId ? colors.red('(missing!)') : colors.green('(ok)')}`);
7400
+ - Full Scan ID to delete as second argument ${!scanId ? colors.red('(missing!)') : colors.green('(ok)')}`);
6983
7401
  return;
6984
7402
  }
6985
7403
  if (cli.flags['dryRun']) {
6986
7404
  logger.logger.log(DRY_RUN_BAIL_TEXT$6);
6987
7405
  return;
6988
7406
  }
6989
- await deleteOrgFullScan(orgSlug, fullScanId);
7407
+ await handleDeleteScan(orgSlug, scanId);
6990
7408
  }
6991
7409
 
6992
- // @ts-ignore
6993
- async function listFullScans({
7410
+ async function fetchListScans({
6994
7411
  direction,
6995
7412
  from_time,
6996
7413
  orgSlug,
6997
- outputKind,
6998
7414
  page,
6999
7415
  per_page,
7000
7416
  sort
@@ -7003,23 +7419,19 @@ async function listFullScans({
7003
7419
  if (!apiToken) {
7004
7420
  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.');
7005
7421
  }
7006
- await listFullScansWithToken({
7007
- apiToken,
7422
+ await fetchListScansWithToken(apiToken, {
7008
7423
  direction,
7009
7424
  from_time,
7010
7425
  orgSlug,
7011
- outputKind,
7012
7426
  page,
7013
7427
  per_page,
7014
7428
  sort
7015
7429
  });
7016
7430
  }
7017
- async function listFullScansWithToken({
7018
- apiToken,
7431
+ async function fetchListScansWithToken(apiToken, {
7019
7432
  direction,
7020
7433
  from_time,
7021
7434
  orgSlug,
7022
- outputKind,
7023
7435
  page,
7024
7436
  per_page,
7025
7437
  sort
@@ -7028,22 +7440,27 @@ async function listFullScansWithToken({
7028
7440
  const {
7029
7441
  spinner
7030
7442
  } = constants;
7443
+ const sockSdk = await shadowNpmInject.setupSdk(apiToken);
7031
7444
  spinner.start('Fetching list of scans...');
7032
- const socketSdk = await shadowNpmInject.setupSdk(apiToken);
7033
- const result = await handleApiCall(socketSdk.getOrgFullScanList(orgSlug, {
7445
+ const result = await handleApiCall(sockSdk.getOrgFullScanList(orgSlug, {
7034
7446
  sort,
7035
7447
  direction,
7036
7448
  per_page: String(per_page),
7037
7449
  page: String(page),
7038
7450
  from: from_time
7039
7451
  }), 'Listing scans');
7452
+ spinner.successAndStop(`Received response for list of scans.`);
7040
7453
  if (!result.success) {
7041
7454
  handleUnsuccessfulApiResponse('getOrgFullScanList', result);
7042
7455
  return;
7043
7456
  }
7044
- spinner.stop(`Fetch complete`);
7457
+ return result.data;
7458
+ }
7459
+
7460
+ // @ts-ignore
7461
+ async function outputListScans(data, outputKind) {
7045
7462
  if (outputKind === 'json') {
7046
- logger.logger.log(result.data);
7463
+ logger.logger.log(data);
7047
7464
  return;
7048
7465
  }
7049
7466
  const options = {
@@ -7061,7 +7478,7 @@ async function listFullScansWithToken({
7061
7478
  name: colors.magenta('Created at')
7062
7479
  }]
7063
7480
  };
7064
- const formattedResults = result.data.results.map(d => {
7481
+ const formattedResults = data.results.map(d => {
7065
7482
  return {
7066
7483
  id: d.id,
7067
7484
  report_url: colors.underline(`${d.html_report_url}`),
@@ -7076,6 +7493,27 @@ async function listFullScansWithToken({
7076
7493
  logger.logger.log(chalkTable(options, formattedResults));
7077
7494
  }
7078
7495
 
7496
+ async function handleListScans({
7497
+ direction,
7498
+ from_time,
7499
+ orgSlug,
7500
+ outputKind,
7501
+ page,
7502
+ per_page,
7503
+ sort
7504
+ }) {
7505
+ const data = await fetchListScans({
7506
+ direction,
7507
+ from_time,
7508
+ orgSlug,
7509
+ page,
7510
+ per_page,
7511
+ sort
7512
+ });
7513
+ if (!data) return;
7514
+ await outputListScans(data, outputKind);
7515
+ }
7516
+
7079
7517
  const {
7080
7518
  DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$5
7081
7519
  } = constants;
@@ -7163,7 +7601,7 @@ async function run$5(argv, importMeta, {
7163
7601
  logger.logger.log(DRY_RUN_BAIL_TEXT$5);
7164
7602
  return;
7165
7603
  }
7166
- await listFullScans({
7604
+ await handleListScans({
7167
7605
  direction: String(cli.flags['direction'] || ''),
7168
7606
  from_time: String(cli.flags['fromTime'] || ''),
7169
7607
  orgSlug,
@@ -7174,46 +7612,56 @@ async function run$5(argv, importMeta, {
7174
7612
  });
7175
7613
  }
7176
7614
 
7177
- async function getOrgScanMetadata(orgSlug, scanId, outputKind) {
7615
+ async function fetchScanMetadata(orgSlug, scanId) {
7178
7616
  const apiToken = shadowNpmInject.getDefaultToken();
7179
7617
  if (!apiToken) {
7180
7618
  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.');
7181
7619
  }
7182
- await getOrgScanMetadataWithToken(orgSlug, scanId, apiToken, outputKind);
7620
+ await fetchScanMetadataWithToken(apiToken, orgSlug, scanId);
7183
7621
  }
7184
- async function getOrgScanMetadataWithToken(orgSlug, scanId, apiToken, outputKind) {
7622
+ async function fetchScanMetadataWithToken(apiToken, orgSlug, scanId) {
7185
7623
  // Lazily access constants.spinner.
7186
7624
  const {
7187
7625
  spinner
7188
7626
  } = constants;
7627
+ const sockSdk = await shadowNpmInject.setupSdk(apiToken);
7189
7628
  spinner.start('Fetching meta data for a full scan...');
7190
- const socketSdk = await shadowNpmInject.setupSdk(apiToken);
7191
- const result = await handleApiCall(socketSdk.getOrgFullScanMetadata(orgSlug, scanId), 'Listing scans');
7629
+ const result = await handleApiCall(sockSdk.getOrgFullScanMetadata(orgSlug, scanId), 'Listing scans');
7630
+ spinner.successAndStop('Received response for scan meta data.');
7192
7631
  if (!result.success) {
7193
7632
  handleUnsuccessfulApiResponse('getOrgFullScanMetadata', result);
7194
7633
  return;
7195
7634
  }
7196
- spinner?.successAndStop('Fetched the meta data\n');
7635
+ return result.data;
7636
+ }
7637
+
7638
+ async function outputScanMetadata(data, scanId, outputKind) {
7197
7639
  if (outputKind === 'json') {
7198
- logger.logger.log(result.data);
7640
+ logger.logger.log(data);
7199
7641
  } else {
7200
7642
  // Markdown = print
7201
7643
  if (outputKind === 'markdown') {
7202
7644
  logger.logger.log('# Scan meta data\n');
7203
7645
  }
7204
7646
  logger.logger.log(`Scan ID: ${scanId}\n`);
7205
- for (const [key, value] of Object.entries(result.data)) {
7647
+ for (const [key, value] of Object.entries(data)) {
7206
7648
  if (['id', 'updated_at', 'organization_id', 'repository_id', 'commit_hash', 'html_report_url'].includes(key)) continue;
7207
7649
  logger.logger.log(`- ${key}:`, value);
7208
7650
  }
7209
7651
  if (outputKind === 'markdown') {
7210
- logger.logger.log(`\nYou can view this report at: [${result.data.html_report_url}](${result.data.html_report_url})\n`);
7652
+ logger.logger.log(`\nYou can view this report at: [${data.html_report_url}](${data.html_report_url})\n`);
7211
7653
  } else {
7212
- logger.logger.log(`\nYou can view this report at: ${result.data.html_report_url}]\n`);
7654
+ logger.logger.log(`\nYou can view this report at: ${data.html_report_url}]\n`);
7213
7655
  }
7214
7656
  }
7215
7657
  }
7216
7658
 
7659
+ async function handleOrgScanMetadata(orgSlug, scanId, outputKind) {
7660
+ const data = await fetchScanMetadata(orgSlug, scanId);
7661
+ if (!data) return;
7662
+ await outputScanMetadata(data, scanId, outputKind);
7663
+ }
7664
+
7217
7665
  const {
7218
7666
  DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$4
7219
7667
  } = constants;
@@ -7250,8 +7698,8 @@ async function run$4(argv, importMeta, {
7250
7698
  importMeta,
7251
7699
  parentName
7252
7700
  });
7253
- const [orgSlug = '', fullScanId = ''] = cli.input;
7254
- if (!orgSlug || !fullScanId) {
7701
+ const [orgSlug = '', scanId = ''] = cli.input;
7702
+ if (!orgSlug || !scanId) {
7255
7703
  // Use exit status of 2 to indicate incorrect usage, generally invalid
7256
7704
  // options or missing arguments.
7257
7705
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
@@ -7260,14 +7708,14 @@ async function run$4(argv, importMeta, {
7260
7708
 
7261
7709
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
7262
7710
 
7263
- - Full Scan ID to inspect as second argument ${!fullScanId ? colors.red('(missing!)') : colors.green('(ok)')}`);
7711
+ - Full Scan ID to inspect as second argument ${!scanId ? colors.red('(missing!)') : colors.green('(ok)')}`);
7264
7712
  return;
7265
7713
  }
7266
7714
  if (cli.flags['dryRun']) {
7267
7715
  logger.logger.log(DRY_RUN_BAIL_TEXT$4);
7268
7716
  return;
7269
7717
  }
7270
- await getOrgScanMetadata(orgSlug, fullScanId, cli.flags['json'] ? 'json' : cli.flags['markdown'] ? 'markdown' : 'print');
7718
+ await handleOrgScanMetadata(orgSlug, scanId, cli.flags['json'] ? 'json' : cli.flags['markdown'] ? 'markdown' : 'print');
7271
7719
  }
7272
7720
 
7273
7721
  /**
@@ -7275,7 +7723,7 @@ async function run$4(argv, importMeta, {
7275
7723
  * full scan ID.
7276
7724
  * It can optionally only fetch the security or license side of things.
7277
7725
  */
7278
- async function fetchReportData(orgSlug, fullScanId,
7726
+ async function fetchReportData(orgSlug, scanId,
7279
7727
  // includeLicensePolicy: boolean,
7280
7728
  includeSecurityPolicy) {
7281
7729
  let haveScan = false;
@@ -7312,14 +7760,14 @@ includeSecurityPolicy) {
7312
7760
  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.');
7313
7761
  }
7314
7762
  updateProgress();
7315
- const socketSdk = await shadowNpmInject.setupSdk(apiToken);
7763
+ const sockSdk = await shadowNpmInject.setupSdk(apiToken);
7316
7764
 
7317
7765
  // @ts-ignore
7318
7766
  const [scan,
7319
7767
  // licensePolicyMaybe,
7320
7768
  securityPolicyMaybe] = await Promise.all([(async () => {
7321
7769
  try {
7322
- const response = await queryApi(`orgs/${orgSlug}/full-scans/${encodeURIComponent(fullScanId)}`, apiToken);
7770
+ const response = await queryApi(`orgs/${orgSlug}/full-scans/${encodeURIComponent(scanId)}`, apiToken);
7323
7771
  haveScan = true;
7324
7772
  updateProgress();
7325
7773
  if (!response.ok) {
@@ -7345,7 +7793,7 @@ includeSecurityPolicy) {
7345
7793
  })(),
7346
7794
  // includeLicensePolicy &&
7347
7795
  // (async () => {
7348
- // const r = await socketSdk.getOrgSecurityPolicy(orgSlug)
7796
+ // const r = await sockSdk.getOrgSecurityPolicy(orgSlug)
7349
7797
  // haveLicensePolicy = true
7350
7798
  // updateProgress()
7351
7799
  // return await handleApiCall(
@@ -7354,7 +7802,7 @@ includeSecurityPolicy) {
7354
7802
  // )
7355
7803
  // })(),
7356
7804
  includeSecurityPolicy && (async () => {
7357
- const r = await socketSdk.getOrgSecurityPolicy(orgSlug);
7805
+ const r = await sockSdk.getOrgSecurityPolicy(orgSlug);
7358
7806
  haveSecurityPolicy = true;
7359
7807
  updateProgress();
7360
7808
  return await handleApiCall(r, "looking up organization's security policy");
@@ -7600,40 +8048,31 @@ function* walkNestedMap(map, keys = []) {
7600
8048
  }
7601
8049
  }
7602
8050
 
7603
- async function reportFullScan({
8051
+ async function outputScanReport(scan,
8052
+ // licensePolicy: undefined | SocketSdkReturnType<'getOrgSecurityPolicy'>,
8053
+ securityPolicy, {
7604
8054
  filePath,
7605
8055
  fold,
7606
- fullScanId,
7607
8056
  includeLicensePolicy,
7608
8057
  includeSecurityPolicy,
7609
8058
  orgSlug,
7610
8059
  outputKind,
7611
8060
  reportLevel,
8061
+ scanId,
7612
8062
  short
7613
8063
  }) {
7614
- logger.logger.error('output:', outputKind, ', file:', filePath, ', fold:', fold, ', reportLevel:', reportLevel);
7615
8064
  if (!includeSecurityPolicy) {
8065
+ process.exitCode = 1;
7616
8066
  return; // caller should assert
7617
8067
  }
7618
- const {
7619
- // licensePolicy,
7620
- ok,
7621
- scan,
7622
- securityPolicy
7623
- } = await fetchReportData(orgSlug, fullScanId,
7624
- // includeLicensePolicy
7625
- includeSecurityPolicy);
7626
- if (!ok) {
7627
- return;
7628
- }
7629
8068
  const scanReport = generateReport(scan, undefined,
7630
8069
  // licensePolicy,
7631
8070
  securityPolicy, {
7632
8071
  orgSlug,
7633
- scanId: fullScanId,
8072
+ scanId,
7634
8073
  fold,
7635
- short,
7636
- reportLevel
8074
+ reportLevel,
8075
+ short
7637
8076
  });
7638
8077
  if (!scanReport.healthy) {
7639
8078
  process.exitCode = 1;
@@ -7720,6 +8159,43 @@ ${!report.alerts.size ? '' : mdTable(flatData, ['Policy', 'Alert Type', 'Package
7720
8159
  return md;
7721
8160
  }
7722
8161
 
8162
+ async function handleScanReport({
8163
+ filePath,
8164
+ fold,
8165
+ includeLicensePolicy,
8166
+ includeSecurityPolicy,
8167
+ orgSlug,
8168
+ outputKind,
8169
+ reportLevel,
8170
+ scanId,
8171
+ short
8172
+ }) {
8173
+ if (!includeSecurityPolicy) {
8174
+ process.exitCode = 1;
8175
+ return; // caller should assert
8176
+ }
8177
+ const {
8178
+ // licensePolicy,
8179
+ ok,
8180
+ scan,
8181
+ securityPolicy
8182
+ } = await fetchReportData(orgSlug, scanId,
8183
+ // includeLicensePolicy
8184
+ includeSecurityPolicy);
8185
+ if (!ok) return;
8186
+ await outputScanReport(scan, securityPolicy, {
8187
+ filePath,
8188
+ fold,
8189
+ scanId: scanId,
8190
+ includeLicensePolicy,
8191
+ includeSecurityPolicy,
8192
+ orgSlug,
8193
+ outputKind,
8194
+ reportLevel,
8195
+ short
8196
+ });
8197
+ }
8198
+
7723
8199
  const {
7724
8200
  DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$3
7725
8201
  } = constants;
@@ -7806,8 +8282,8 @@ async function run$3(argv, importMeta, {
7806
8282
  reportLevel = 'warn',
7807
8283
  security
7808
8284
  } = cli.flags;
7809
- const [orgSlug = '', fullScanId = '', file = '-'] = cli.input;
7810
- if (!orgSlug || !fullScanId ||
8285
+ const [orgSlug = '', scanId = '', file = '-'] = cli.input;
8286
+ if (!orgSlug || !scanId ||
7811
8287
  // (!license && !security) ||
7812
8288
  json && markdown) {
7813
8289
  // Use exit status of 2 to indicate incorrect usage, generally invalid
@@ -7819,7 +8295,7 @@ async function run$3(argv, importMeta, {
7819
8295
 
7820
8296
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
7821
8297
 
7822
- - Full Scan ID to fetch as second argument ${!fullScanId ? colors.red('(missing!)') : colors.green('(ok)')}
8298
+ - Full Scan ID to fetch as second argument ${!scanId ? colors.red('(missing!)') : colors.green('(ok)')}
7823
8299
 
7824
8300
  - Not both the --json and --markdown flags ${json && markdown ? colors.red('(pick one!)') : colors.green('(ok)')}
7825
8301
  `
@@ -7831,9 +8307,9 @@ async function run$3(argv, importMeta, {
7831
8307
  logger.logger.log(DRY_RUN_BAIL_TEXT$3);
7832
8308
  return;
7833
8309
  }
7834
- await reportFullScan({
8310
+ await handleScanReport({
7835
8311
  orgSlug,
7836
- fullScanId,
8312
+ scanId: scanId,
7837
8313
  includeLicensePolicy: false,
7838
8314
  // !!license,
7839
8315
  includeSecurityPolicy: typeof security === 'boolean' ? security : true,
@@ -7845,29 +8321,7 @@ async function run$3(argv, importMeta, {
7845
8321
  });
7846
8322
  }
7847
8323
 
7848
- async function streamFullScan(orgSlug, fullScanId, file) {
7849
- // Lazily access constants.spinner.
7850
- const {
7851
- spinner
7852
- } = constants;
7853
- const apiToken = shadowNpmInject.getDefaultToken();
7854
- if (!apiToken) {
7855
- 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.');
7856
- }
7857
- spinner.start('Fetching scan...');
7858
- const socketSdk = await shadowNpmInject.setupSdk(apiToken);
7859
- const data = await handleApiCall(socketSdk.getOrgFullScan(orgSlug, fullScanId, file === '-' ? undefined : file), 'Fetching a scan');
7860
- if (!data?.success) {
7861
- handleUnsuccessfulApiResponse('getOrgFullScan', data);
7862
- return;
7863
- }
7864
- spinner?.successAndStop(file ? `Full scan details written to ${file}` : 'stdout');
7865
- return data;
7866
- }
7867
-
7868
- async function viewFullScan(orgSlug, fullScanId, filePath) {
7869
- const artifacts = await getFullScan(orgSlug, fullScanId);
7870
- if (!artifacts) return;
8324
+ async function outputScanView(artifacts, orgSlug, scanId, filePath) {
7871
8325
  const display = artifacts.map(art => {
7872
8326
  const author = Array.isArray(art.author) ? `${art.author[0]}${art.author.length > 1 ? ' et.al.' : ''}` : art.author;
7873
8327
  return {
@@ -7884,11 +8338,11 @@ async function viewFullScan(orgSlug, fullScanId, filePath) {
7884
8338
 
7885
8339
  These are the artifacts and their scores found.
7886
8340
 
7887
- Sscan ID: ${fullScanId}
8341
+ Scan ID: ${scanId}
7888
8342
 
7889
8343
  ${md}
7890
8344
 
7891
- View this report at: https://socket.dev/dashboard/org/${orgSlug}/sbom/${fullScanId}
8345
+ View this report at: https://socket.dev/dashboard/org/${orgSlug}/sbom/${scanId}
7892
8346
  `.trim() + '\n';
7893
8347
  if (filePath && filePath !== '-') {
7894
8348
  try {
@@ -7904,6 +8358,32 @@ View this report at: https://socket.dev/dashboard/org/${orgSlug}/sbom/${fullScan
7904
8358
  }
7905
8359
  }
7906
8360
 
8361
+ async function handleScanView(orgSlug, scanId, filePath) {
8362
+ const data = await fetchScan(orgSlug, scanId);
8363
+ if (!data) return;
8364
+ await outputScanView(data, orgSlug, scanId, filePath);
8365
+ }
8366
+
8367
+ async function streamScan(orgSlug, scanId, file) {
8368
+ // Lazily access constants.spinner.
8369
+ const {
8370
+ spinner
8371
+ } = constants;
8372
+ const apiToken = shadowNpmInject.getDefaultToken();
8373
+ if (!apiToken) {
8374
+ 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.');
8375
+ }
8376
+ const sockSdk = await shadowNpmInject.setupSdk(apiToken);
8377
+ spinner.start('Fetching scan...');
8378
+ const data = await handleApiCall(sockSdk.getOrgFullScan(orgSlug, scanId, file === '-' ? undefined : file), 'Fetching a scan');
8379
+ spinner?.successAndStop(file ? `Full scan details written to ${file}` : 'stdout');
8380
+ if (!data?.success) {
8381
+ handleUnsuccessfulApiResponse('getOrgFullScan', data);
8382
+ return;
8383
+ }
8384
+ return data;
8385
+ }
8386
+
7907
8387
  const {
7908
8388
  DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$2
7909
8389
  } = constants;
@@ -7942,8 +8422,8 @@ async function run$2(argv, importMeta, {
7942
8422
  importMeta,
7943
8423
  parentName
7944
8424
  });
7945
- const [orgSlug = '', fullScanId = '', file = '-'] = cli.input;
7946
- if (!orgSlug || !fullScanId) {
8425
+ const [orgSlug = '', scanId = '', file = '-'] = cli.input;
8426
+ if (!orgSlug || !scanId) {
7947
8427
  // Use exit status of 2 to indicate incorrect usage, generally invalid
7948
8428
  // options or missing arguments.
7949
8429
  // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
@@ -7953,7 +8433,7 @@ async function run$2(argv, importMeta, {
7953
8433
 
7954
8434
  - Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
7955
8435
 
7956
- - Full Scan ID to fetch as second argument ${!fullScanId ? colors.red('(missing!)') : colors.green('(ok)')}
8436
+ - Full Scan ID to fetch as second argument ${!scanId ? colors.red('(missing!)') : colors.green('(ok)')}
7957
8437
  `);
7958
8438
  return;
7959
8439
  }
@@ -7962,9 +8442,9 @@ async function run$2(argv, importMeta, {
7962
8442
  return;
7963
8443
  }
7964
8444
  if (cli.flags['json']) {
7965
- await streamFullScan(orgSlug, fullScanId, file);
8445
+ await streamScan(orgSlug, scanId, file);
7966
8446
  } else {
7967
- await viewFullScan(orgSlug, fullScanId, file);
8447
+ await handleScanView(orgSlug, scanId, file);
7968
8448
  }
7969
8449
  }
7970
8450
 
@@ -8460,12 +8940,13 @@ void (async () => {
8460
8940
  await updateNotifier({
8461
8941
  name: SOCKET_CLI_BIN_NAME,
8462
8942
  // The '@rollup/plugin-replace' will replace "process.env['INLINED_SOCKET_CLI_VERSION']".
8463
- version: "0.14.66",
8943
+ version: "0.14.67",
8464
8944
  ttl: 86_400_000 /* 24 hours in milliseconds */
8465
8945
  });
8466
8946
  try {
8467
8947
  await meowWithSubcommands({
8468
8948
  cdxgen: cmdCdxgen,
8949
+ config: cmdConfig,
8469
8950
  fix: cmdFix,
8470
8951
  info: cmdInfo,
8471
8952
  login: cmdLogin,
@@ -8527,5 +9008,5 @@ void (async () => {
8527
9008
  await shadowNpmInject.captureException(e);
8528
9009
  }
8529
9010
  })();
8530
- //# debugId=640f53d3-ca09-4212-b657-069970ae5d97
9011
+ //# debugId=436bf807-b015-4a97-803d-9a1ae68db89f
8531
9012
  //# sourceMappingURL=cli.js.map