socket 0.15.54 → 0.15.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/cli.js +537 -298
  2. package/dist/cli.js.map +1 -1
  3. package/dist/constants.js +15 -3
  4. package/dist/constants.js.map +1 -1
  5. package/dist/types/commands/json/cmd-json.d.mts +10 -0
  6. package/dist/types/commands/json/cmd-json.d.mts.map +1 -0
  7. package/dist/types/commands/json/handle-cmd-json.d.mts +2 -0
  8. package/dist/types/commands/json/handle-cmd-json.d.mts.map +1 -0
  9. package/dist/types/commands/json/output-cmd-json.d.mts +2 -0
  10. package/dist/types/commands/json/output-cmd-json.d.mts.map +1 -0
  11. package/dist/types/commands/oops/cmd-oops.d.mts.map +1 -1
  12. package/dist/types/commands/package/output-purls-deep-score.d.mts +5 -0
  13. package/dist/types/commands/package/output-purls-deep-score.d.mts.map +1 -0
  14. package/dist/types/commands/package/output-purls-shallow-score.d.mts +25 -0
  15. package/dist/types/commands/package/output-purls-shallow-score.d.mts.map +1 -1
  16. package/dist/types/commands/scan/cmd-scan-reach.d.mts.map +1 -1
  17. package/dist/types/commands/scan/scan-reachability.d.mts.map +1 -1
  18. package/dist/types/constants.d.mts +3 -0
  19. package/dist/types/constants.d.mts.map +1 -1
  20. package/dist/types/utils/meow-with-subcommands.d.mts.map +1 -1
  21. package/dist/types/utils/tildify.d.mts +4 -0
  22. package/dist/types/utils/tildify.d.mts.map +1 -0
  23. package/dist/utils.js +63 -36
  24. package/dist/utils.js.map +1 -1
  25. package/dist/vendor.js +31637 -31637
  26. package/external/@coana-tech/cli/cli.mjs +216492 -0
  27. package/package.json +6 -6
  28. package/dist/types/commands/package/output-purl-score.d.mts +0 -4
  29. package/dist/types/commands/package/output-purl-score.d.mts.map +0 -1
package/dist/cli.js CHANGED
@@ -305,7 +305,7 @@ async function handleAnalytics({
305
305
  const {
306
306
  DRY_RUN_BAILING_NOW: DRY_RUN_BAILING_NOW$O
307
307
  } = constants;
308
- const config$T = {
308
+ const config$U = {
309
309
  commandName: 'analytics',
310
310
  description: `Look up analytics data`,
311
311
  hidden: false,
@@ -367,16 +367,16 @@ const config$T = {
367
367
  .replace(/\n(?: *\n)+/g, '\n\n')
368
368
  };
369
369
  const cmdAnalytics = {
370
- description: config$T.description,
371
- hidden: config$T.hidden,
372
- run: run$T
370
+ description: config$U.description,
371
+ hidden: config$U.hidden,
372
+ run: run$U
373
373
  };
374
- async function run$T(argv, importMeta, {
374
+ async function run$U(argv, importMeta, {
375
375
  parentName
376
376
  }) {
377
377
  const cli = utils.meowOrExit({
378
378
  argv,
379
- config: config$T,
379
+ config: config$U,
380
380
  importMeta,
381
381
  parentName
382
382
  });
@@ -663,7 +663,7 @@ const {
663
663
  DRY_RUN_BAILING_NOW: DRY_RUN_BAILING_NOW$N,
664
664
  SOCKET_WEBSITE_URL: SOCKET_WEBSITE_URL$3
665
665
  } = constants;
666
- const config$S = {
666
+ const config$T = {
667
667
  commandName: 'audit-log',
668
668
  description: 'Look up the audit log for an organization',
669
669
  hidden: false,
@@ -717,16 +717,16 @@ const config$S = {
717
717
  `
718
718
  };
719
719
  const cmdAuditLog = {
720
- description: config$S.description,
721
- hidden: config$S.hidden,
722
- run: run$S
720
+ description: config$T.description,
721
+ hidden: config$T.hidden,
722
+ run: run$T
723
723
  };
724
- async function run$S(argv, importMeta, {
724
+ async function run$T(argv, importMeta, {
725
725
  parentName
726
726
  }) {
727
727
  const cli = utils.meowOrExit({
728
728
  argv,
729
- config: config$S,
729
+ config: config$T,
730
730
  importMeta,
731
731
  parentName
732
732
  });
@@ -1059,7 +1059,7 @@ const yargsConfig = {
1059
1059
  'usages-slices-file' // hidden
1060
1060
  ]
1061
1061
  };
1062
- const config$R = {
1062
+ const config$S = {
1063
1063
  commandName: 'cdxgen',
1064
1064
  description: 'Create an SBOM with CycloneDX generator (cdxgen)',
1065
1065
  hidden: false,
@@ -1069,17 +1069,17 @@ const config$R = {
1069
1069
  help: () => ''
1070
1070
  };
1071
1071
  const cmdManifestCdxgen = {
1072
- description: config$R.description,
1073
- hidden: config$R.hidden,
1074
- run: run$R
1072
+ description: config$S.description,
1073
+ hidden: config$S.hidden,
1074
+ run: run$S
1075
1075
  };
1076
- async function run$R(argv, importMeta, {
1076
+ async function run$S(argv, importMeta, {
1077
1077
  parentName
1078
1078
  }) {
1079
1079
  const cli = utils.meowOrExit({
1080
1080
  // Don't let meow take over --help.
1081
1081
  argv: argv.filter(a => !utils.isHelpFlag(a)),
1082
- config: config$R,
1082
+ config: config$S,
1083
1083
  importMeta,
1084
1084
  parentName
1085
1085
  });
@@ -1130,15 +1130,15 @@ async function handleCdxgen(argv, importMeta, {
1130
1130
  });
1131
1131
  }
1132
1132
 
1133
- const config$Q = {
1133
+ const config$R = {
1134
1134
  description: 'Create an SBOM with CycloneDX generator (cdxgen)',
1135
1135
  hidden: true};
1136
1136
  const cmdCdxgen = {
1137
- description: config$Q.description,
1138
- hidden: config$Q.hidden,
1139
- run: run$Q
1137
+ description: config$R.description,
1138
+ hidden: config$R.hidden,
1139
+ run: run$R
1140
1140
  };
1141
- async function run$Q(argv, importMeta, {
1141
+ async function run$R(argv, importMeta, {
1142
1142
  parentName
1143
1143
  }) {
1144
1144
  logger.logger.warn('Warning: The `socket cdxgen` command moved to `socket manifest cdxgen` and will be removed as a toplevel command in the next major bump.');
@@ -2373,7 +2373,7 @@ async function handleCI(autoManifest) {
2373
2373
  const {
2374
2374
  DRY_RUN_BAILING_NOW: DRY_RUN_BAILING_NOW$L
2375
2375
  } = constants;
2376
- const config$P = {
2376
+ const config$Q = {
2377
2377
  commandName: 'ci',
2378
2378
  description: 'Create a new scan and report whether it passes your security policy',
2379
2379
  hidden: true,
@@ -2391,7 +2391,7 @@ const config$P = {
2391
2391
  $ ${parentName}
2392
2392
 
2393
2393
  Options
2394
- ${utils.getFlagListOutput(config$P.flags, 6)}
2394
+ ${utils.getFlagListOutput(config$Q.flags, 6)}
2395
2395
 
2396
2396
  This command is intended to use in CI runs to allow automated systems to
2397
2397
  accept or reject a current build. When the scan does not pass your security
@@ -2406,16 +2406,16 @@ const config$P = {
2406
2406
  `
2407
2407
  };
2408
2408
  const cmdCI = {
2409
- description: config$P.description,
2410
- hidden: config$P.hidden,
2411
- run: run$P
2409
+ description: config$Q.description,
2410
+ hidden: config$Q.hidden,
2411
+ run: run$Q
2412
2412
  };
2413
- async function run$P(argv, importMeta, {
2413
+ async function run$Q(argv, importMeta, {
2414
2414
  parentName
2415
2415
  }) {
2416
2416
  const cli = utils.meowOrExit({
2417
2417
  argv,
2418
- config: config$P,
2418
+ config: config$Q,
2419
2419
  importMeta,
2420
2420
  parentName
2421
2421
  });
@@ -2666,7 +2666,7 @@ async function handleConfigAuto({
2666
2666
  const {
2667
2667
  DRY_RUN_BAILING_NOW: DRY_RUN_BAILING_NOW$K
2668
2668
  } = constants;
2669
- const config$O = {
2669
+ const config$P = {
2670
2670
  commandName: 'auto',
2671
2671
  description: 'Automatically discover and set the correct value config item',
2672
2672
  hidden: false,
@@ -2695,16 +2695,16 @@ ${Array.from(utils.supportedConfigKeys.entries()).map(([key, desc]) => ` - $
2695
2695
  `
2696
2696
  };
2697
2697
  const cmdConfigAuto = {
2698
- description: config$O.description,
2699
- hidden: config$O.hidden,
2700
- run: run$O
2698
+ description: config$P.description,
2699
+ hidden: config$P.hidden,
2700
+ run: run$P
2701
2701
  };
2702
- async function run$O(argv, importMeta, {
2702
+ async function run$P(argv, importMeta, {
2703
2703
  parentName
2704
2704
  }) {
2705
2705
  const cli = utils.meowOrExit({
2706
2706
  argv,
2707
- config: config$O,
2707
+ config: config$P,
2708
2708
  importMeta,
2709
2709
  parentName
2710
2710
  });
@@ -2780,7 +2780,7 @@ async function handleConfigGet({
2780
2780
  const {
2781
2781
  DRY_RUN_BAILING_NOW: DRY_RUN_BAILING_NOW$J
2782
2782
  } = constants;
2783
- const config$N = {
2783
+ const config$O = {
2784
2784
  commandName: 'get',
2785
2785
  description: 'Get the value of a local CLI config item',
2786
2786
  hidden: false,
@@ -2804,16 +2804,16 @@ ${Array.from(utils.supportedConfigKeys.entries()).map(([key, desc]) => ` - $
2804
2804
  `
2805
2805
  };
2806
2806
  const cmdConfigGet = {
2807
- description: config$N.description,
2808
- hidden: config$N.hidden,
2809
- run: run$N
2807
+ description: config$O.description,
2808
+ hidden: config$O.hidden,
2809
+ run: run$O
2810
2810
  };
2811
- async function run$N(argv, importMeta, {
2811
+ async function run$O(argv, importMeta, {
2812
2812
  parentName
2813
2813
  }) {
2814
2814
  const cli = utils.meowOrExit({
2815
2815
  argv,
2816
- config: config$N,
2816
+ config: config$O,
2817
2817
  importMeta,
2818
2818
  parentName
2819
2819
  });
@@ -2918,7 +2918,7 @@ async function outputConfigList({
2918
2918
  const {
2919
2919
  DRY_RUN_BAILING_NOW: DRY_RUN_BAILING_NOW$I
2920
2920
  } = constants;
2921
- const config$M = {
2921
+ const config$N = {
2922
2922
  commandName: 'list',
2923
2923
  description: 'Show all local CLI config items and their values',
2924
2924
  hidden: false,
@@ -2947,16 +2947,16 @@ ${Array.from(utils.supportedConfigKeys.entries()).map(([key, desc]) => ` - $
2947
2947
  `
2948
2948
  };
2949
2949
  const cmdConfigList = {
2950
- description: config$M.description,
2951
- hidden: config$M.hidden,
2952
- run: run$M
2950
+ description: config$N.description,
2951
+ hidden: config$N.hidden,
2952
+ run: run$N
2953
2953
  };
2954
- async function run$M(argv, importMeta, {
2954
+ async function run$N(argv, importMeta, {
2955
2955
  parentName
2956
2956
  }) {
2957
2957
  const cli = utils.meowOrExit({
2958
2958
  argv,
2959
- config: config$M,
2959
+ config: config$N,
2960
2960
  importMeta,
2961
2961
  parentName
2962
2962
  });
@@ -3028,7 +3028,7 @@ async function handleConfigSet({
3028
3028
  const {
3029
3029
  DRY_RUN_BAILING_NOW: DRY_RUN_BAILING_NOW$H
3030
3030
  } = constants;
3031
- const config$L = {
3031
+ const config$M = {
3032
3032
  commandName: 'set',
3033
3033
  description: 'Update the value of a local CLI config item',
3034
3034
  hidden: false,
@@ -3057,16 +3057,16 @@ ${Array.from(utils.supportedConfigKeys.entries()).map(([key, desc]) => ` - $
3057
3057
  `
3058
3058
  };
3059
3059
  const cmdConfigSet = {
3060
- description: config$L.description,
3061
- hidden: config$L.hidden,
3062
- run: run$L
3060
+ description: config$M.description,
3061
+ hidden: config$M.hidden,
3062
+ run: run$M
3063
3063
  };
3064
- async function run$L(argv, importMeta, {
3064
+ async function run$M(argv, importMeta, {
3065
3065
  parentName
3066
3066
  }) {
3067
3067
  const cli = utils.meowOrExit({
3068
3068
  argv,
3069
- config: config$L,
3069
+ config: config$M,
3070
3070
  importMeta,
3071
3071
  parentName
3072
3072
  });
@@ -3150,7 +3150,7 @@ async function handleConfigUnset({
3150
3150
  const {
3151
3151
  DRY_RUN_BAILING_NOW: DRY_RUN_BAILING_NOW$G
3152
3152
  } = constants;
3153
- const config$K = {
3153
+ const config$L = {
3154
3154
  commandName: 'unset',
3155
3155
  description: 'Clear the value of a local CLI config item',
3156
3156
  hidden: false,
@@ -3174,16 +3174,16 @@ ${Array.from(utils.supportedConfigKeys.entries()).map(([key, desc]) => ` - $
3174
3174
  `
3175
3175
  };
3176
3176
  const cmdConfigUnset = {
3177
- description: config$K.description,
3178
- hidden: config$K.hidden,
3179
- run: run$K
3177
+ description: config$L.description,
3178
+ hidden: config$L.hidden,
3179
+ run: run$L
3180
3180
  };
3181
- async function run$K(argv, importMeta, {
3181
+ async function run$L(argv, importMeta, {
3182
3182
  parentName
3183
3183
  }) {
3184
3184
  const cli = utils.meowOrExit({
3185
3185
  argv,
3186
- config: config$K,
3186
+ config: config$L,
3187
3187
  importMeta,
3188
3188
  parentName
3189
3189
  });
@@ -3320,7 +3320,7 @@ async function handleDependencies({
3320
3320
  const {
3321
3321
  DRY_RUN_BAILING_NOW: DRY_RUN_BAILING_NOW$F
3322
3322
  } = constants;
3323
- const config$J = {
3323
+ const config$K = {
3324
3324
  commandName: 'dependencies',
3325
3325
  description: 'Search for any dependency that is being used in your organization',
3326
3326
  hidden: false,
@@ -3356,16 +3356,16 @@ const config$J = {
3356
3356
  `
3357
3357
  };
3358
3358
  const cmdScanCreate$1 = {
3359
- description: config$J.description,
3360
- hidden: config$J.hidden,
3361
- run: run$J
3359
+ description: config$K.description,
3360
+ hidden: config$K.hidden,
3361
+ run: run$K
3362
3362
  };
3363
- async function run$J(argv, importMeta, {
3363
+ async function run$K(argv, importMeta, {
3364
3364
  parentName
3365
3365
  }) {
3366
3366
  const cli = utils.meowOrExit({
3367
3367
  argv,
3368
- config: config$J,
3368
+ config: config$K,
3369
3369
  importMeta,
3370
3370
  parentName
3371
3371
  });
@@ -3493,7 +3493,7 @@ async function handleDiffScan$1({
3493
3493
  const {
3494
3494
  DRY_RUN_BAILING_NOW: DRY_RUN_BAILING_NOW$E
3495
3495
  } = constants;
3496
- const config$I = {
3496
+ const config$J = {
3497
3497
  commandName: 'get',
3498
3498
  description: 'Get a diff scan for an organization',
3499
3499
  hidden: false,
@@ -3552,16 +3552,16 @@ const config$I = {
3552
3552
  `
3553
3553
  };
3554
3554
  const cmdDiffScanGet = {
3555
- description: config$I.description,
3556
- hidden: config$I.hidden,
3557
- run: run$I
3555
+ description: config$J.description,
3556
+ hidden: config$J.hidden,
3557
+ run: run$J
3558
3558
  };
3559
- async function run$I(argv, importMeta, {
3559
+ async function run$J(argv, importMeta, {
3560
3560
  parentName
3561
3561
  }) {
3562
3562
  const cli = utils.meowOrExit({
3563
3563
  argv,
3564
- config: config$I,
3564
+ config: config$J,
3565
3565
  importMeta,
3566
3566
  parentName
3567
3567
  });
@@ -5385,7 +5385,7 @@ async function handleFix({
5385
5385
  const {
5386
5386
  DRY_RUN_NOT_SAVING
5387
5387
  } = constants;
5388
- const config$H = {
5388
+ const config$I = {
5389
5389
  commandName: 'fix',
5390
5390
  description: 'Update dependencies with "fixable" Socket alerts',
5391
5391
  hidden: false,
@@ -5453,16 +5453,16 @@ const config$H = {
5453
5453
  `
5454
5454
  };
5455
5455
  const cmdFix = {
5456
- description: config$H.description,
5457
- hidden: config$H.hidden,
5458
- run: run$H
5456
+ description: config$I.description,
5457
+ hidden: config$I.hidden,
5458
+ run: run$I
5459
5459
  };
5460
- async function run$H(argv, importMeta, {
5460
+ async function run$I(argv, importMeta, {
5461
5461
  parentName
5462
5462
  }) {
5463
5463
  const cli = utils.meowOrExit({
5464
5464
  argv,
5465
- config: config$H,
5465
+ config: config$I,
5466
5466
  importMeta,
5467
5467
  parentName
5468
5468
  });
@@ -5666,7 +5666,7 @@ async function handlePackageInfo({
5666
5666
  const {
5667
5667
  DRY_RUN_BAILING_NOW: DRY_RUN_BAILING_NOW$D
5668
5668
  } = constants;
5669
- const config$G = {
5669
+ const config$H = {
5670
5670
  commandName: 'info',
5671
5671
  description: 'Look up info regarding a package',
5672
5672
  hidden: true,
@@ -5691,16 +5691,16 @@ const config$G = {
5691
5691
  `
5692
5692
  };
5693
5693
  const cmdInfo = {
5694
- description: config$G.description,
5695
- hidden: config$G.hidden,
5696
- run: run$G
5694
+ description: config$H.description,
5695
+ hidden: config$H.hidden,
5696
+ run: run$H
5697
5697
  };
5698
- async function run$G(argv, importMeta, {
5698
+ async function run$H(argv, importMeta, {
5699
5699
  parentName
5700
5700
  }) {
5701
5701
  const cli = utils.meowOrExit({
5702
5702
  argv,
5703
- config: config$G,
5703
+ config: config$H,
5704
5704
  importMeta,
5705
5705
  parentName
5706
5706
  });
@@ -5741,7 +5741,7 @@ async function run$G(argv, importMeta, {
5741
5741
  return;
5742
5742
  }
5743
5743
  await handlePackageInfo({
5744
- commandName: `${parentName} ${config$G.commandName}`,
5744
+ commandName: `${parentName} ${config$H.commandName}`,
5745
5745
  includeAllIssues: Boolean(all),
5746
5746
  outputKind,
5747
5747
  pkgName,
@@ -5871,7 +5871,7 @@ async function handleInstallCompletion(targetName) {
5871
5871
  const {
5872
5872
  DRY_RUN_BAILING_NOW: DRY_RUN_BAILING_NOW$C
5873
5873
  } = constants;
5874
- const config$F = {
5874
+ const config$G = {
5875
5875
  commandName: 'completion',
5876
5876
  description: 'Install bash completion for Socket CLI',
5877
5877
  hidden: true,
@@ -5909,16 +5909,16 @@ const config$F = {
5909
5909
  `
5910
5910
  };
5911
5911
  const cmdInstallCompletion = {
5912
- description: config$F.description,
5913
- hidden: config$F.hidden,
5914
- run: run$F
5912
+ description: config$G.description,
5913
+ hidden: config$G.hidden,
5914
+ run: run$G
5915
5915
  };
5916
- async function run$F(argv, importMeta, {
5916
+ async function run$G(argv, importMeta, {
5917
5917
  parentName
5918
5918
  }) {
5919
5919
  const cli = utils.meowOrExit({
5920
5920
  argv,
5921
- config: config$F,
5921
+ config: config$G,
5922
5922
  importMeta,
5923
5923
  parentName
5924
5924
  });
@@ -5949,6 +5949,67 @@ const cmdInstall = {
5949
5949
  }
5950
5950
  };
5951
5951
 
5952
+ async function outputCmdJson(cwd) {
5953
+ logger.logger.info('Target cwd:', constants.ENV.VITEST ? '<redacted>' : utils.tildify(cwd));
5954
+ const sjpath = path.join(cwd, 'socket.json');
5955
+ const tildeSjpath = constants.ENV.VITEST ? '<redacted>' : utils.tildify(sjpath);
5956
+ if (!fs$1.existsSync(sjpath)) {
5957
+ logger.logger.fail(`Not found: ${tildeSjpath}`);
5958
+ process.exitCode = 1;
5959
+ return;
5960
+ }
5961
+ if (!fs$1.lstatSync(sjpath).isFile()) {
5962
+ logger.logger.fail(`This is not a regular file (maybe a directory?): ${tildeSjpath}`);
5963
+ process.exitCode = 1;
5964
+ return;
5965
+ }
5966
+ const data = fs$1.readFileSync(sjpath, 'utf8');
5967
+ logger.logger.success(`This is the contents of ${tildeSjpath}:`);
5968
+ logger.logger.error('');
5969
+ logger.logger.log(data);
5970
+ }
5971
+
5972
+ async function handleCmdJson(cwd) {
5973
+ await outputCmdJson(cwd);
5974
+ }
5975
+
5976
+ const config$F = {
5977
+ commandName: 'json',
5978
+ description: 'Display the `socket.json` that would be applied for target folder',
5979
+ hidden: true,
5980
+ // This is a power tool. No need to clutter the toplevel.
5981
+ flags: {
5982
+ ...utils.commonFlags
5983
+ },
5984
+ help: parentName => `
5985
+ Usage
5986
+ $ ${parentName} [CWD=.]
5987
+
5988
+ Display the \`socket.json\` file that would apply when running relevant commands
5989
+ in the target directory.
5990
+ `
5991
+ };
5992
+ const cmdJson = {
5993
+ description: config$F.description,
5994
+ hidden: config$F.hidden,
5995
+ run: run$F
5996
+ };
5997
+ async function run$F(argv, importMeta, {
5998
+ parentName
5999
+ }) {
6000
+ const cli = utils.meowOrExit({
6001
+ argv,
6002
+ config: config$F,
6003
+ importMeta,
6004
+ parentName
6005
+ });
6006
+ let [cwd = '.'] = cli.input;
6007
+ // Note: path.resolve vs .join:
6008
+ // If given path is absolute then cwd should not affect it.
6009
+ cwd = path.resolve(process.cwd(), cwd);
6010
+ await handleCmdJson(cwd);
6011
+ }
6012
+
5952
6013
  function applyLogin(apiToken, enforcedOrgs, apiBaseUrl, apiProxy) {
5953
6014
  utils.updateConfigValue('enforcedOrgs', enforcedOrgs);
5954
6015
  utils.updateConfigValue('apiToken', apiToken);
@@ -7504,7 +7565,12 @@ const config$t = {
7504
7565
  hidden: true,
7505
7566
  flags: {
7506
7567
  ...utils.commonFlags,
7507
- ...utils.outputFlags
7568
+ ...utils.outputFlags,
7569
+ throw: {
7570
+ type: 'boolean',
7571
+ default: false,
7572
+ description: 'Throw an explicit error even if --json or --markdown are set'
7573
+ }
7508
7574
  },
7509
7575
  help: (parentName, config) => `
7510
7576
  Usage
@@ -7529,13 +7595,14 @@ async function run$t(argv, importMeta, {
7529
7595
  });
7530
7596
  const {
7531
7597
  json,
7532
- markdown
7598
+ markdown,
7599
+ throw: justThrow
7533
7600
  } = cli.flags;
7534
7601
  if (cli.flags['dryRun']) {
7535
7602
  logger.logger.log(DRY_RUN_BAILING_NOW$r);
7536
7603
  return;
7537
7604
  }
7538
- if (json) {
7605
+ if (json && !justThrow) {
7539
7606
  process.exitCode = 1;
7540
7607
  logger.logger.log(utils.serializeResultJson({
7541
7608
  ok: false,
@@ -7543,7 +7610,7 @@ async function run$t(argv, importMeta, {
7543
7610
  cause: 'This error was intentionally left blank'
7544
7611
  }));
7545
7612
  }
7546
- if (markdown) {
7613
+ if (markdown && !justThrow) {
7547
7614
  process.exitCode = 1;
7548
7615
  logger.logger.fail(utils.failMsgWithBadge('Oops', 'This error was intentionally left blank'));
7549
7616
  return;
@@ -8918,7 +8985,7 @@ async function fetchPurlDeepScore(purl) {
8918
8985
  return await utils.queryApiSafeJson(`purl/score/${encodeURIComponent(purl)}`, 'the deep package scores');
8919
8986
  }
8920
8987
 
8921
- async function outputPurlScore(purl, result, outputKind) {
8988
+ async function outputPurlsDeepScore(purl, result, outputKind) {
8922
8989
  if (!result.ok) {
8923
8990
  process.exitCode = result.code ?? 1;
8924
8991
  }
@@ -8931,151 +8998,156 @@ async function outputPurlScore(purl, result, outputKind) {
8931
8998
  return;
8932
8999
  }
8933
9000
  if (outputKind === 'markdown') {
8934
- const {
8935
- purl: requestedPurl,
8936
- self: {
8937
- alerts: selfAlerts,
8938
- capabilities: selfCaps,
8939
- purl,
8940
- score: selfScore
8941
- },
8942
- transitively: {
8943
- alerts,
8944
- capabilities,
8945
- dependencyCount,
8946
- func,
8947
- lowest,
8948
- score
8949
- }
8950
- } = result.data;
8951
- logger.logger.success(`Score report for "${requestedPurl}" ("${purl}"):\n`);
8952
- logger.logger.log('# Complete Package Score');
8953
- logger.logger.log('');
8954
- if (dependencyCount) {
8955
- logger.logger.log(`This is a Socket report for the package *"${purl}"* and its *${dependencyCount}* direct/transitive dependencies.`);
8956
- } else {
8957
- logger.logger.log(`This is a Socket report for the package *"${purl}"*. It has *no dependencies*.`);
8958
- }
8959
- logger.logger.log('');
8960
- if (dependencyCount) {
8961
- logger.logger.log(`It will show you the shallow score for just the package itself and a deep score for all the transitives combined. Additionally you can see which capabilities were found and the top alerts as well as a package that was responsible for it.`);
8962
- } else {
8963
- logger.logger.log(`It will show you the shallow score for the package itself, which capabilities were found, and its top alerts.`);
8964
- logger.logger.log('');
8965
- logger.logger.log('Since it has no dependencies, the shallow score is also the deep score.');
8966
- }
8967
- logger.logger.log('');
9001
+ const md = createMarkdownReport(result.data);
9002
+ logger.logger.success(`Score report for "${result.data.purl}" ("${purl}"):\n`);
9003
+ logger.logger.log(md);
9004
+ return;
9005
+ }
9006
+ logger.logger.log(`Score report for "${purl}" (use --json for raw and --markdown for formatted reports):`);
9007
+ logger.logger.log(result.data);
9008
+ logger.logger.log('');
9009
+ }
9010
+ function createMarkdownReport(data) {
9011
+ const {
9012
+ self: {
9013
+ alerts: selfAlerts,
9014
+ capabilities: selfCaps,
9015
+ purl,
9016
+ score: selfScore
9017
+ },
9018
+ transitively: {
9019
+ alerts,
9020
+ capabilities,
9021
+ dependencyCount,
9022
+ func,
9023
+ lowest,
9024
+ score
9025
+ }
9026
+ } = data;
9027
+ const arr = [];
9028
+ arr.push('# Complete Package Score');
9029
+ arr.push('');
9030
+ if (dependencyCount) {
9031
+ arr.push(`This is a Socket report for the package *"${purl}"* and its *${dependencyCount}* direct/transitive dependencies.`);
9032
+ } else {
9033
+ arr.push(`This is a Socket report for the package *"${purl}"*. It has *no dependencies*.`);
9034
+ }
9035
+ arr.push('');
9036
+ if (dependencyCount) {
9037
+ arr.push(`It will show you the shallow score for just the package itself and a deep score for all the transitives combined. Additionally you can see which capabilities were found and the top alerts as well as a package that was responsible for it.`);
9038
+ } else {
9039
+ arr.push(`It will show you the shallow score for the package itself, which capabilities were found, and its top alerts.`);
9040
+ arr.push('');
9041
+ arr.push('Since it has no dependencies, the shallow score is also the deep score.');
9042
+ }
9043
+ arr.push('');
9044
+ if (dependencyCount) {
9045
+ // This doesn't make much sense if there are no dependencies. Better to omit it.
9046
+ arr.push('The report should give you a good insight into the status of this package.');
9047
+ arr.push('');
9048
+ arr.push('## Package itself');
9049
+ arr.push('');
9050
+ arr.push('Here are results for the package itself (excluding data from dependencies).');
9051
+ } else {
9052
+ arr.push('## Report');
9053
+ arr.push('');
9054
+ arr.push('The report should give you a good insight into the status of this package.');
9055
+ }
9056
+ arr.push('');
9057
+ arr.push('### Shallow Score');
9058
+ arr.push('');
9059
+ arr.push('This score is just for the package itself:');
9060
+ arr.push('');
9061
+ arr.push('- Overall: ' + selfScore.overall);
9062
+ arr.push('- Maintenance: ' + selfScore.maintenance);
9063
+ arr.push('- Quality: ' + selfScore.quality);
9064
+ arr.push('- Supply Chain: ' + selfScore.supplyChain);
9065
+ arr.push('- Vulnerability: ' + selfScore.vulnerability);
9066
+ arr.push('- License: ' + selfScore.license);
9067
+ arr.push('');
9068
+ arr.push('### Capabilities');
9069
+ arr.push('');
9070
+ if (selfCaps.length) {
9071
+ arr.push('These are the capabilities detected in the package itself:');
9072
+ arr.push('');
9073
+ selfCaps.forEach(cap => {
9074
+ arr.push(`- ${cap}`);
9075
+ });
9076
+ } else {
9077
+ arr.push('No capabilities were found in the package.');
9078
+ }
9079
+ arr.push('');
9080
+ arr.push('### Alerts for this package');
9081
+ arr.push('');
9082
+ if (selfAlerts.length) {
8968
9083
  if (dependencyCount) {
8969
- // This doesn't make much sense if there are no dependencies. Better to omit it.
8970
- logger.logger.log('The report should give you a good insight into the status of this package.');
8971
- logger.logger.log('');
8972
- logger.logger.log('## Package itself');
8973
- logger.logger.log('');
8974
- logger.logger.log('Here are results for the package itself (excluding data from dependencies).');
9084
+ arr.push('These are the alerts found for the package itself:');
8975
9085
  } else {
8976
- logger.logger.log('## Report');
8977
- logger.logger.log('');
8978
- logger.logger.log('The report should give you a good insight into the status of this package.');
9086
+ arr.push('These are the alerts found for this package:');
8979
9087
  }
8980
- logger.logger.log('');
8981
- logger.logger.log('### Shallow Score');
8982
- logger.logger.log('');
8983
- logger.logger.log('This score is just for the package itself:');
8984
- logger.logger.log('');
8985
- logger.logger.log('- Overall: ' + selfScore.overall);
8986
- logger.logger.log('- Maintenance: ' + selfScore.maintenance);
8987
- logger.logger.log('- Quality: ' + selfScore.quality);
8988
- logger.logger.log('- Supply Chain: ' + selfScore.supplyChain);
8989
- logger.logger.log('- Vulnerability: ' + selfScore.vulnerability);
8990
- logger.logger.log('- License: ' + selfScore.license);
8991
- logger.logger.log('');
8992
- logger.logger.log('### Capabilities');
8993
- logger.logger.log('');
8994
- if (selfCaps.length) {
8995
- logger.logger.log('These are the capabilities detected in the package itself:');
8996
- logger.logger.log('');
8997
- selfCaps.forEach(cap => {
8998
- logger.logger.log(`- ${cap}`);
9088
+ arr.push('');
9089
+ arr.push(utils.mdTable(selfAlerts, ['severity', 'name'], ['Severity', 'Alert Name']));
9090
+ } else {
9091
+ arr.push('There are currently no alerts for this package.');
9092
+ }
9093
+ arr.push('');
9094
+ if (dependencyCount) {
9095
+ arr.push('## Transitive Package Results');
9096
+ arr.push('');
9097
+ arr.push('Here are results for the package and its direct/transitive dependencies.');
9098
+ arr.push('');
9099
+ arr.push('### Deep Score');
9100
+ arr.push('');
9101
+ arr.push('This score represents the package and and its direct/transitive dependencies:');
9102
+ arr.push(`The function used to calculate the values in aggregate is: *"${func}"*`);
9103
+ arr.push('');
9104
+ arr.push('- Overall: ' + score.overall);
9105
+ arr.push('- Maintenance: ' + score.maintenance);
9106
+ arr.push('- Quality: ' + score.quality);
9107
+ arr.push('- Supply Chain: ' + score.supplyChain);
9108
+ arr.push('- Vulnerability: ' + score.vulnerability);
9109
+ arr.push('- License: ' + score.license);
9110
+ arr.push('');
9111
+ arr.push('### Capabilities');
9112
+ arr.push('');
9113
+ arr.push('These are the packages with the lowest recorded score. If there is more than one with the lowest score, just one is shown here. This may help you figure out the source of low scores.');
9114
+ arr.push('');
9115
+ arr.push('- Overall: ' + lowest.overall);
9116
+ arr.push('- Maintenance: ' + lowest.maintenance);
9117
+ arr.push('- Quality: ' + lowest.quality);
9118
+ arr.push('- Supply Chain: ' + lowest.supplyChain);
9119
+ arr.push('- Vulnerability: ' + lowest.vulnerability);
9120
+ arr.push('- License: ' + lowest.license);
9121
+ arr.push('');
9122
+ arr.push('### Capabilities');
9123
+ arr.push('');
9124
+ if (capabilities.length) {
9125
+ arr.push('These are the capabilities detected in at least one package:');
9126
+ arr.push('');
9127
+ capabilities.forEach(cap => {
9128
+ arr.push(`- ${cap}`);
8999
9129
  });
9000
9130
  } else {
9001
- logger.logger.log('No capabilities were found in the package.');
9131
+ arr.push('This package had no capabilities and neither did any of its direct/transitive dependencies.');
9002
9132
  }
9003
- logger.logger.log('');
9004
- logger.logger.log('### Alerts for this package');
9005
- logger.logger.log('');
9006
- if (selfAlerts.length) {
9007
- if (dependencyCount) {
9008
- logger.logger.log('These are the alerts found for the package itself:');
9009
- } else {
9010
- logger.logger.log('These are the alerts found for this package:');
9011
- }
9012
- logger.logger.log('');
9013
- logger.logger.log(utils.mdTable(selfAlerts, ['severity', 'name'], ['Severity', 'Alert Name']));
9133
+ arr.push('');
9134
+ arr.push('### Alerts');
9135
+ arr.push('');
9136
+ if (alerts.length) {
9137
+ arr.push('These are the alerts found:');
9138
+ arr.push('');
9139
+ arr.push(utils.mdTable(alerts, ['severity', 'name', 'example'], ['Severity', 'Alert Name', 'Example package reporting it']));
9014
9140
  } else {
9015
- logger.logger.log('There are currently no alerts for this package.');
9141
+ arr.push('This package had no alerts and neither did any of its direct/transitive dependencies');
9016
9142
  }
9017
- logger.logger.log('');
9018
- if (dependencyCount) {
9019
- logger.logger.log('## Transitive Package Results');
9020
- logger.logger.log('');
9021
- logger.logger.log('Here are results for the package and its direct/transitive dependencies.');
9022
- logger.logger.log('');
9023
- logger.logger.log('### Deep Score');
9024
- logger.logger.log('');
9025
- logger.logger.log('This score represents the package and and its direct/transitive dependencies:');
9026
- logger.logger.log(`The function used to calculate the values in aggregate is: *"${func}"*`);
9027
- logger.logger.log('');
9028
- logger.logger.log('- Overall: ' + score.overall);
9029
- logger.logger.log('- Maintenance: ' + score.maintenance);
9030
- logger.logger.log('- Quality: ' + score.quality);
9031
- logger.logger.log('- Supply Chain: ' + score.supplyChain);
9032
- logger.logger.log('- Vulnerability: ' + score.vulnerability);
9033
- logger.logger.log('- License: ' + score.license);
9034
- logger.logger.log('');
9035
- logger.logger.log('### Capabilities');
9036
- logger.logger.log('');
9037
- logger.logger.log('These are the packages with the lowest recorded score. If there is more than one with the lowest score, just one is shown here. This may help you figure out the source of low scores.');
9038
- logger.logger.log('');
9039
- logger.logger.log('- Overall: ' + lowest.overall);
9040
- logger.logger.log('- Maintenance: ' + lowest.maintenance);
9041
- logger.logger.log('- Quality: ' + lowest.quality);
9042
- logger.logger.log('- Supply Chain: ' + lowest.supplyChain);
9043
- logger.logger.log('- Vulnerability: ' + lowest.vulnerability);
9044
- logger.logger.log('- License: ' + lowest.license);
9045
- logger.logger.log('');
9046
- logger.logger.log('### Capabilities');
9047
- logger.logger.log('');
9048
- if (capabilities.length) {
9049
- logger.logger.log('These are the capabilities detected in at least one package:');
9050
- logger.logger.log('');
9051
- capabilities.forEach(cap => {
9052
- logger.logger.log(`- ${cap}`);
9053
- });
9054
- } else {
9055
- logger.logger.log('This package had no capabilities and neither did any of its direct/transitive dependencies.');
9056
- }
9057
- logger.logger.log('');
9058
- logger.logger.log('### Alerts');
9059
- logger.logger.log('');
9060
- if (alerts.length) {
9061
- logger.logger.log('These are the alerts found:');
9062
- logger.logger.log('');
9063
- logger.logger.log(utils.mdTable(alerts, ['severity', 'name', 'example'], ['Severity', 'Alert Name', 'Example package reporting it']));
9064
- } else {
9065
- logger.logger.log('This package had no alerts and neither did any of its direct/transitive dependencies');
9066
- }
9067
- logger.logger.log('');
9068
- }
9069
- return;
9143
+ arr.push('');
9144
+ return arr.join('\n');
9070
9145
  }
9071
- logger.logger.log(`Score report for "${purl}" (use --json for raw and --markdown for formatted reports):`);
9072
- logger.logger.log(result.data);
9073
- logger.logger.log('');
9074
9146
  }
9075
9147
 
9076
9148
  async function handlePurlDeepScore(purl, outputKind) {
9077
9149
  const result = await fetchPurlDeepScore(purl);
9078
- await outputPurlScore(purl, result, outputKind);
9150
+ await outputPurlsDeepScore(purl, result, outputKind);
9079
9151
  }
9080
9152
 
9081
9153
  // Either an ecosystem was given or all args must be (namespaced) purls
@@ -9255,6 +9327,8 @@ async function fetchPurlsShallowScore(purls) {
9255
9327
  };
9256
9328
  }
9257
9329
 
9330
+ // This is a simplified view of an artifact. Potentially merged with other artifacts.
9331
+
9258
9332
  function outputPurlsShallowScore(purls, result, outputKind) {
9259
9333
  if (!result.ok) {
9260
9334
  process.exitCode = result.code ?? 1;
@@ -9267,59 +9341,31 @@ function outputPurlsShallowScore(purls, result, outputKind) {
9267
9341
  logger.logger.fail(utils.failMsgWithBadge(result.message, result.cause));
9268
9342
  return;
9269
9343
  }
9270
-
9271
- // Make some effort to match the requested data with the response
9272
-
9273
- const set = new Set();
9274
- result.data.forEach(data => {
9275
- set.add('pkg:' + data.type + '/' + data.name + '@' + data.version);
9276
- set.add('pkg:' + data.type + '/' + data.name);
9277
- });
9278
- const missing = purls.filter(purl => {
9279
- if (set.has(purl)) {
9280
- return false;
9281
- }
9282
- if (purl.endsWith('@latest') && set.has(purl.slice(0, -'@latest'.length))) {
9283
- return false;
9284
- }
9285
- return true; // not found
9286
- });
9344
+ const {
9345
+ missing,
9346
+ rows
9347
+ } = preProcess(result.data, purls);
9287
9348
  if (outputKind === 'markdown') {
9288
- logger.logger.log(`
9289
- # Shallow Package Report
9290
-
9291
- This report contains the response for requesting data on some package url(s).
9292
-
9293
- Please note: The listed scores are ONLY for the package itself. It does NOT
9294
- reflect the scores of any dependencies, transitive or otherwise.
9295
-
9296
- ${missing.length ? `\n## Missing response\n\nAt least one package had no response or the purl was not canonical:\n\n${missing.map(purl => '- ' + purl + '\n').join('')}` : ''}
9297
-
9298
- ${result.data.map(data => '## ' + formatReportCard(data, false)).join('\n\n\n')}
9299
- `.trim());
9349
+ const md = generateMarkdownReport(rows, missing);
9350
+ logger.logger.log(md);
9300
9351
  return;
9301
9352
  }
9302
- logger.logger.log('\n' + vendor.yoctocolorsCjsExports.bold('Shallow Package Score') + '\n');
9303
- logger.logger.log('Please note: The listed scores are ONLY for the package itself. It does NOT\n' + ' reflect the scores of any dependencies, transitive or otherwise.');
9304
- if (missing.length) {
9305
- logger.logger.log(`\nAt least one package had no response or the purl was not canonical:\n${missing.map(purl => '\n- ' + vendor.yoctocolorsCjsExports.bold(purl)).join('')}`);
9306
- }
9307
- result.data.forEach(data => {
9308
- logger.logger.log('\n');
9309
- logger.logger.log(formatReportCard(data, true));
9310
- });
9311
- logger.logger.log('');
9353
+ const txt = generateTextReport(rows, missing);
9354
+ logger.logger.log(txt);
9312
9355
  }
9313
- function formatReportCard(data, color) {
9356
+ function formatReportCard(artifact, color) {
9314
9357
  const scoreResult = {
9315
- 'Supply Chain Risk': Math.floor((data.score?.supplyChain ?? 0) * 100),
9316
- Maintenance: Math.floor((data.score?.maintenance ?? 0) * 100),
9317
- Quality: Math.floor((data.score?.quality ?? 0) * 100),
9318
- Vulnerabilities: Math.floor((data.score?.vulnerability ?? 0) * 100),
9319
- License: Math.floor((data.score?.license ?? 0) * 100)
9358
+ 'Supply Chain Risk': Math.floor((artifact.score?.supplyChain ?? 0) * 100),
9359
+ Maintenance: Math.floor((artifact.score?.maintenance ?? 0) * 100),
9360
+ Quality: Math.floor((artifact.score?.quality ?? 0) * 100),
9361
+ Vulnerabilities: Math.floor((artifact.score?.vulnerability ?? 0) * 100),
9362
+ License: Math.floor((artifact.score?.license ?? 0) * 100)
9320
9363
  };
9321
- const alertString = getAlertString(data.alerts, !color);
9322
- const purl = 'pkg:' + data.type + '/' + data.name + '@' + data.version;
9364
+ const alertString = getAlertString(artifact.alerts, !color);
9365
+ if (!artifact.ecosystem) {
9366
+ console.log('WTF?', artifact);
9367
+ }
9368
+ const purl = `pkg:${artifact.ecosystem}/${artifact.name}${artifact.version ? '@' + artifact.version : ''}`;
9323
9369
  return ['Package: ' + (color ? vendor.yoctocolorsCjsExports.bold(purl) : purl), '', ...Object.entries(scoreResult).map(score => `- ${score[0]}:`.padEnd(20, ' ') + ` ${formatScore(score[1], !color, true)}`), alertString].join('\n');
9324
9370
  }
9325
9371
  function formatScore(score, noColor = false, pad = false) {
@@ -9336,12 +9382,13 @@ function formatScore(score, noColor = false, pad = false) {
9336
9382
  return vendor.yoctocolorsCjsExports.red(padded);
9337
9383
  }
9338
9384
  function getAlertString(alerts, noColor = false) {
9339
- if (!alerts?.length) {
9385
+ if (!alerts.size) {
9340
9386
  return noColor ? `- Alerts: none!` : `- Alerts: ${vendor.yoctocolorsCjsExports.green('none')}!`;
9341
9387
  }
9342
- const bad = alerts.filter(alert => alert.severity !== 'low' && alert.severity !== 'middle').sort((a, b) => a.type < b.type ? -1 : a.type > b.type ? 1 : 0);
9343
- const mid = alerts.filter(alert => alert.severity === 'middle').sort((a, b) => a.type < b.type ? -1 : a.type > b.type ? 1 : 0);
9344
- const low = alerts.filter(alert => alert.severity === 'low').sort((a, b) => a.type < b.type ? -1 : a.type > b.type ? 1 : 0);
9388
+ const arr = Array.from(alerts.values());
9389
+ const bad = arr.filter(alert => alert.severity !== 'low' && alert.severity !== 'middle').sort((a, b) => a.type < b.type ? -1 : a.type > b.type ? 1 : 0);
9390
+ const mid = arr.filter(alert => alert.severity === 'middle').sort((a, b) => a.type < b.type ? -1 : a.type > b.type ? 1 : 0);
9391
+ const low = arr.filter(alert => alert.severity === 'low').sort((a, b) => a.type < b.type ? -1 : a.type > b.type ? 1 : 0);
9345
9392
 
9346
9393
  // We need to create the no-color string regardless because the actual string
9347
9394
  // contains a bunch of invisible ANSI chars which would screw up length checks.
@@ -9351,6 +9398,146 @@ function getAlertString(alerts, noColor = false) {
9351
9398
  }
9352
9399
  return `- Alerts (${vendor.yoctocolorsCjsExports.red(bad.length.toString())}/${vendor.yoctocolorsCjsExports.yellow(mid.length.toString())}/${low.length}):` + ' '.repeat(Math.max(0, 20 - colorless.length)) + ' ' + [bad.map(alert => vendor.yoctocolorsCjsExports.red(vendor.yoctocolorsCjsExports.dim(`[${alert.severity}] `) + alert.type)).join(', '), mid.map(alert => vendor.yoctocolorsCjsExports.yellow(vendor.yoctocolorsCjsExports.dim(`[${alert.severity}] `) + alert.type)).join(', '), low.map(alert => vendor.yoctocolorsCjsExports.dim(`[${alert.severity}] `) + alert.type).join(', ')].filter(Boolean).join(', ');
9353
9400
  }
9401
+ function preProcess(artifacts, requestedPurls) {
9402
+ // Dedupe results (for example, pypi will emit one package for each system release (win/mac/cpu) even if it's
9403
+ // the same package version with same results. The duplication is irrelevant and annoying to the user.
9404
+
9405
+ // Make some effort to match the requested data with the response
9406
+ // Dedupe and merge results when only the .release value is different
9407
+
9408
+ // API does not tell us which purls were not found.
9409
+ // Generate all purls to try so we can try to match search request.
9410
+ const purls = new Set();
9411
+ artifacts.forEach(data => {
9412
+ purls.add(`pkg:${data.type}/${data.namespace ? `${data.namespace}/` : ''}${data.name}@${data.version}`);
9413
+ purls.add(`pkg:${data.type}/${data.name}@${data.version}`);
9414
+ purls.add(`pkg:${data.type}/${data.name}`);
9415
+ purls.add(`pkg:${data.type}/${data.namespace ? `${data.namespace}/` : ''}${data.name}`);
9416
+ });
9417
+ // Try to match the searched purls against this list
9418
+ const missing = requestedPurls.filter(purl => {
9419
+ if (purls.has(purl)) {
9420
+ return false;
9421
+ }
9422
+ if (purl.endsWith('@latest') && purls.has(purl.slice(0, -'@latest'.length))) {
9423
+ return false;
9424
+ }
9425
+ return true; // not found
9426
+ });
9427
+
9428
+ // Create a unique set of rows which represents each artifact that is returned
9429
+ // while deduping when the artifact (main) meta data only differs due to the
9430
+ // .release field (observed with python, at least).
9431
+ // Merge the alerts for duped packages. Use lowest score between all of them.
9432
+ const rows = new Map();
9433
+ artifacts.forEach(artifact => {
9434
+ const purl = `pkg:${artifact.type}/${artifact.namespace ? `${artifact.namespace}/` : ''}${artifact.name}${artifact.version ? `@${artifact.version}` : ''}`;
9435
+ if (rows.has(purl)) {
9436
+ const row = rows.get(purl);
9437
+ if (!row) {
9438
+ // unreachable; satisfy TS
9439
+ return;
9440
+ }
9441
+ if ((artifact.score?.supplyChain || 100) < row.score.supplyChain) {
9442
+ row.score.supplyChain = artifact.score?.supplyChain || 100;
9443
+ }
9444
+ if ((artifact.score?.maintenance || 100) < row.score.maintenance) {
9445
+ row.score.maintenance = artifact.score?.maintenance || 100;
9446
+ }
9447
+ if ((artifact.score?.quality || 100) < row.score.quality) {
9448
+ row.score.quality = artifact.score?.quality || 100;
9449
+ }
9450
+ if ((artifact.score?.vulnerability || 100) < row.score.vulnerability) {
9451
+ row.score.vulnerability = artifact.score?.vulnerability || 100;
9452
+ }
9453
+ if ((artifact.score?.license || 100) < row.score.license) {
9454
+ row.score.license = artifact.score?.license || 100;
9455
+ }
9456
+ artifact.alerts?.forEach(({
9457
+ severity,
9458
+ type
9459
+ }) => {
9460
+ row.alerts.set(`${type}:${severity}`, {
9461
+ type: type ?? 'unknown',
9462
+ severity: severity ?? 'none'
9463
+ });
9464
+ });
9465
+ } else {
9466
+ const alerts = new Map();
9467
+ artifact.alerts?.forEach(({
9468
+ severity,
9469
+ type
9470
+ }) => {
9471
+ alerts.set(`${type}:${severity}`, {
9472
+ type: type ?? 'unknown',
9473
+ severity: severity ?? 'none'
9474
+ });
9475
+ });
9476
+ rows.set(purl, {
9477
+ ecosystem: artifact.type,
9478
+ namespace: artifact.namespace || '',
9479
+ name: artifact.name,
9480
+ version: artifact.version || '',
9481
+ score: {
9482
+ supplyChain: artifact.score?.supplyChain || 100,
9483
+ maintenance: artifact.score?.maintenance || 100,
9484
+ quality: artifact.score?.quality || 100,
9485
+ vulnerability: artifact.score?.vulnerability || 100,
9486
+ license: artifact.score?.license || 100
9487
+ },
9488
+ alerts
9489
+ });
9490
+ }
9491
+ });
9492
+ return {
9493
+ rows,
9494
+ missing
9495
+ };
9496
+ }
9497
+ function generateMarkdownReport(artifacts, missing) {
9498
+ const blocks = [];
9499
+ const dupes = new Set();
9500
+ artifacts.forEach(artifact => {
9501
+ const block = '## ' + formatReportCard(artifact, false);
9502
+ if (dupes.has(block)) {
9503
+ return;
9504
+ }
9505
+ dupes.add(block);
9506
+ blocks.push(block);
9507
+ });
9508
+ return `
9509
+ # Shallow Package Report
9510
+
9511
+ This report contains the response for requesting data on some package url(s).
9512
+
9513
+ Please note: The listed scores are ONLY for the package itself. It does NOT
9514
+ reflect the scores of any dependencies, transitive or otherwise.
9515
+
9516
+ ${missing.length ? `\n## Missing response\n\nAt least one package had no response or the purl was not canonical:\n\n${missing.map(purl => '- ' + purl + '\n').join('')}` : ''}
9517
+
9518
+ ${blocks.join('\n\n\n')}
9519
+ `.trim();
9520
+ }
9521
+ function generateTextReport(artifacts, missing) {
9522
+ const arr = [];
9523
+ arr.push('\n' + vendor.yoctocolorsCjsExports.bold('Shallow Package Score') + '\n');
9524
+ arr.push('Please note: The listed scores are ONLY for the package itself. It does NOT\n' + ' reflect the scores of any dependencies, transitive or otherwise.');
9525
+ if (missing.length) {
9526
+ arr.push(`\nAt least one package had no response or the purl was not canonical:\n${missing.map(purl => '\n- ' + vendor.yoctocolorsCjsExports.bold(purl)).join('')}`);
9527
+ }
9528
+ const dupes = new Set(); // Omit dupes when output is identical
9529
+ artifacts.forEach(artifact => {
9530
+ const block = formatReportCard(artifact, true);
9531
+ if (dupes.has(block)) {
9532
+ return;
9533
+ }
9534
+ dupes.add(block);
9535
+ arr.push('\n');
9536
+ arr.push(block);
9537
+ });
9538
+ arr.push('');
9539
+ return arr.join('\n');
9540
+ }
9354
9541
 
9355
9542
  async function handlePurlsShallowScore({
9356
9543
  outputKind,
@@ -11777,6 +11964,15 @@ async function streamDownloadWithFetch(localPath, downloadUrl) {
11777
11964
  cause: 'Response body is null or undefined.'
11778
11965
  };
11779
11966
  }
11967
+
11968
+ // Make sure the dir exists. It may be nested and we need to construct that
11969
+ // before starting the download.
11970
+ const dir = path.dirname(localPath);
11971
+ if (!fs$1.existsSync(dir)) {
11972
+ fs$1.mkdirSync(dir, {
11973
+ recursive: true
11974
+ });
11975
+ }
11780
11976
  const fileStream = fs$1.createWriteStream(localPath);
11781
11977
 
11782
11978
  // Using stream.pipeline for better error handling and cleanup
@@ -12653,12 +12849,35 @@ async function outputScanReach(result, cwd, outputKind) {
12653
12849
  logger.logger.success('finished on', cwd);
12654
12850
  }
12655
12851
 
12852
+ const {
12853
+ DOT_SOCKET_DOT_FACTS_JSON
12854
+ } = constants;
12656
12855
  async function scanReachability(cwd) {
12657
- logger.logger.log('Scanning now... as soon as you implement me! From', cwd);
12658
- return {
12659
- ok: true,
12660
- data: undefined
12661
- };
12856
+ try {
12857
+ const result = await spawn.spawn(constants.execPath, [
12858
+ // Lazily access constants.nodeNoWarningsFlags.
12859
+ ...constants.nodeNoWarningsFlags,
12860
+ // Lazily access constants.coanaBinPath.
12861
+ constants.coanaBinPath, 'run', cwd, '--output-dir', cwd, '--disable-report-submission', '--socket-mode', DOT_SOCKET_DOT_FACTS_JSON], {
12862
+ cwd,
12863
+ env: {
12864
+ ...process.env,
12865
+ // Lazily access constants.ENV.SOCKET_CLI_API_TOKEN
12866
+ SOCKET_CLI_API_TOKEN: constants.ENV.SOCKET_CLI_API_TOKEN
12867
+ }
12868
+ });
12869
+ return {
12870
+ ok: true,
12871
+ data: result.stdout.trim()
12872
+ };
12873
+ } catch (e) {
12874
+ const message = e?.stdout ?? e?.message;
12875
+ return {
12876
+ ok: false,
12877
+ data: e,
12878
+ message
12879
+ };
12880
+ }
12662
12881
  }
12663
12882
 
12664
12883
  async function handleScanReach(cwd, outputKind) {
@@ -12675,12 +12894,7 @@ const config$6 = {
12675
12894
  hidden: true,
12676
12895
  flags: {
12677
12896
  ...utils.commonFlags,
12678
- ...utils.outputFlags,
12679
- interactive: {
12680
- type: 'boolean',
12681
- default: true,
12682
- description: 'Allow for interactive elements, asking for input. Use --no-interactive to prevent any input questions, defaulting them to cancel/no.'
12683
- }
12897
+ ...utils.outputFlags
12684
12898
  },
12685
12899
  help: (command, config) => `
12686
12900
  Usage
@@ -12710,7 +12924,6 @@ async function run$6(argv, importMeta, {
12710
12924
  });
12711
12925
  const {
12712
12926
  dryRun,
12713
- interactive,
12714
12927
  json,
12715
12928
  markdown
12716
12929
  } = cli.flags;
@@ -12719,7 +12932,6 @@ async function run$6(argv, importMeta, {
12719
12932
  // Note: path.resolve vs .join:
12720
12933
  // If given path is absolute then cwd should not affect it.
12721
12934
  cwd = path.resolve(process.cwd(), cwd);
12722
- logger.logger.info('If you dont have any interactive bits then drop the flag', interactive);
12723
12935
  const wasValidInput = utils.checkCommandInput(outputKind);
12724
12936
  if (!wasValidInput) {
12725
12937
  return;
@@ -14247,6 +14459,7 @@ void (async () => {
14247
14459
  fix: cmdFix,
14248
14460
  info: cmdInfo,
14249
14461
  install: cmdInstall,
14462
+ json: cmdJson,
14250
14463
  login: cmdLogin,
14251
14464
  logout: cmdLogout,
14252
14465
  npm: cmdNpm,
@@ -14354,6 +14567,24 @@ void (async () => {
14354
14567
  });
14355
14568
  } catch (e) {
14356
14569
  process.exitCode = 1;
14570
+ debug.debugFn('Uncaught error (BAD!):');
14571
+ debug.debugFn(e);
14572
+
14573
+ // Try to parse the flags, find out if --json or --markdown is set
14574
+ let isJson = false;
14575
+ try {
14576
+ const cli = vendor.meow(``, {
14577
+ argv: process.argv.slice(2),
14578
+ importMeta: {
14579
+ url: `${require$$0.pathToFileURL(__filename$1)}`
14580
+ },
14581
+ flags: {},
14582
+ // Do not strictly check for flags here.
14583
+ allowUnknownFlags: true,
14584
+ autoHelp: false
14585
+ });
14586
+ isJson = !!cli.flags['json'];
14587
+ } catch {}
14357
14588
  let errorBody;
14358
14589
  let errorTitle;
14359
14590
  let errorMessage = '';
@@ -14371,14 +14602,22 @@ void (async () => {
14371
14602
  } else {
14372
14603
  errorTitle = 'Unexpected error with no details';
14373
14604
  }
14374
- logger.logger.error('\n'); // Any-spinner-newline
14375
- logger.logger.fail(utils.failMsgWithBadge(errorTitle, errorMessage));
14376
- if (errorBody) {
14377
- // Explicitly use debugLog here.
14378
- debug.debugLog(errorBody);
14605
+ if (isJson) {
14606
+ logger.logger.log(utils.serializeResultJson({
14607
+ ok: false,
14608
+ message: errorTitle,
14609
+ cause: errorMessage
14610
+ }));
14611
+ } else {
14612
+ logger.logger.error('\n'); // Any-spinner-newline
14613
+ logger.logger.fail(utils.failMsgWithBadge(errorTitle, errorMessage));
14614
+ if (errorBody) {
14615
+ // Explicitly use debugLog here.
14616
+ debug.debugLog(errorBody);
14617
+ }
14379
14618
  }
14380
14619
  await utils.captureException(e);
14381
14620
  }
14382
14621
  })();
14383
- //# debugId=c367b9c2-15d4-4650-9e2f-c8866daf46cd
14622
+ //# debugId=46cd08dc-8e3e-40e8-bfdb-0a0801cce912
14384
14623
  //# sourceMappingURL=cli.js.map