@socketsecurity/cli-with-sentry 0.14.56 → 0.14.58
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.
- package/bin/cli.js +10 -10
- package/bin/npm-cli.js +1 -1
- package/bin/npx-cli.js +3 -1
- package/dist/constants.d.ts +20 -8
- package/dist/constants.js +54 -25
- package/dist/constants.js.map +1 -1
- package/dist/instrument-with-sentry.js +3 -3
- package/dist/instrument-with-sentry.js.map +1 -1
- package/dist/module-sync/artifact.d.ts +75 -0
- package/dist/module-sync/cli.js +1372 -1062
- package/dist/module-sync/cli.js.map +1 -1
- package/dist/module-sync/edge.d.ts +1 -1
- package/dist/module-sync/index.d.ts +5 -173
- package/dist/module-sync/node.d.ts +1 -1
- package/dist/module-sync/override-set.d.ts +37 -0
- package/dist/module-sync/shadow-bin.js +10 -8
- package/dist/module-sync/shadow-bin.js.map +1 -1
- package/dist/module-sync/{index.js → shadow-npm-inject.js} +1436 -1302
- package/dist/module-sync/shadow-npm-inject.js.map +1 -0
- package/dist/module-sync/{npm-paths.js → shadow-npm-paths.js} +4 -4
- package/dist/module-sync/shadow-npm-paths.js.map +1 -0
- package/dist/module-sync/socket-package-alert.d.ts +46 -0
- package/dist/module-sync/types.d.ts +11 -3
- package/dist/require/cli.js +1372 -1062
- package/dist/require/cli.js.map +1 -1
- package/dist/require/shadow-npm-inject.js +3 -0
- package/dist/require/shadow-npm-paths.js +3 -0
- package/package.json +14 -11
- package/dist/module-sync/index.js.map +0 -1
- package/dist/module-sync/npm-injection.js +0 -26
- package/dist/module-sync/npm-injection.js.map +0 -1
- package/dist/module-sync/npm-paths.js.map +0 -1
- package/dist/module-sync/proc-log.d.ts +0 -3
- package/dist/module-sync/reify.d.ts +0 -1020
- package/dist/require/index.js +0 -3
- package/dist/require/npm-injection.js +0 -3
- package/dist/require/npm-paths.js +0 -3
- /package/dist/module-sync/{npm-injection.d.ts → shadow-npm-inject.d.ts} +0 -0
- /package/dist/module-sync/{npm-paths.d.ts → shadow-npm-paths.d.ts} +0 -0
package/dist/require/cli.js
CHANGED
|
@@ -23,9 +23,10 @@ var events = require('node:events');
|
|
|
23
23
|
var fs = require('node:fs');
|
|
24
24
|
var path = require('node:path');
|
|
25
25
|
var ndjson = _socketInterop(require('ndjson'));
|
|
26
|
-
var
|
|
26
|
+
var shadowNpmInject = require('./shadow-npm-inject.js');
|
|
27
27
|
var constants = require('./constants.js');
|
|
28
28
|
var objects = require('@socketsecurity/registry/lib/objects');
|
|
29
|
+
var path$1 = require('@socketsecurity/registry/lib/path');
|
|
29
30
|
var regexps = require('@socketsecurity/registry/lib/regexps');
|
|
30
31
|
var commonTags = _socketInterop(require('common-tags'));
|
|
31
32
|
var fs$1 = require('node:fs/promises');
|
|
@@ -40,26 +41,29 @@ var require$$0$1 = require('node:util');
|
|
|
40
41
|
var registry = require('@socketsecurity/registry');
|
|
41
42
|
var npm = require('@socketsecurity/registry/lib/npm');
|
|
42
43
|
var packages = require('@socketsecurity/registry/lib/packages');
|
|
43
|
-
var
|
|
44
|
-
var
|
|
45
|
-
var
|
|
44
|
+
var lockfileFile = _socketInterop(require('@pnpm/lockfile-file'));
|
|
45
|
+
var lockfile_detectDepTypes = _socketInterop(require('@pnpm/lockfile.detect-dep-types'));
|
|
46
|
+
var debug = require('@socketsecurity/registry/lib/debug');
|
|
46
47
|
var spawn = require('@socketsecurity/registry/lib/spawn');
|
|
47
|
-
var
|
|
48
|
-
var semver = _socketInterop(require('semver'));
|
|
49
|
-
var tinyglobby = _socketInterop(require('tinyglobby'));
|
|
50
|
-
var promises = require('@socketsecurity/registry/lib/promises');
|
|
48
|
+
var shadowNpmPaths = require('./shadow-npm-paths.js');
|
|
51
49
|
var browserslist = _socketInterop(require('browserslist'));
|
|
50
|
+
var semver = _socketInterop(require('semver'));
|
|
52
51
|
var which = _socketInterop(require('which'));
|
|
53
52
|
var index_cjs = require('@socketregistry/hyrious__bun.lockb/index.cjs');
|
|
54
53
|
var sorts = require('@socketsecurity/registry/lib/sorts');
|
|
55
54
|
var strings = require('@socketsecurity/registry/lib/strings');
|
|
55
|
+
var registryConstants = require('@socketsecurity/registry/lib/constants');
|
|
56
|
+
var isInteractive = require('@socketregistry/is-interactive/index.cjs');
|
|
57
|
+
var terminalLink = _socketInterop(require('terminal-link'));
|
|
58
|
+
var npa = _socketInterop(require('npm-package-arg'));
|
|
59
|
+
var tinyglobby = _socketInterop(require('tinyglobby'));
|
|
60
|
+
var promises = require('@socketsecurity/registry/lib/promises');
|
|
56
61
|
var yaml = _socketInterop(require('yaml'));
|
|
57
|
-
var debug = require('@socketsecurity/registry/lib/debug');
|
|
58
|
-
var npmPaths = require('./npm-paths.js');
|
|
59
62
|
var betterAjvErrors = _socketInterop(require('@apideck/better-ajv-errors'));
|
|
60
63
|
var config$A = require('@socketsecurity/config');
|
|
61
64
|
var assert = require('node:assert');
|
|
62
65
|
var readline = require('node:readline/promises');
|
|
66
|
+
var BoxWidget = _socketInterop(require('blessed/lib/widgets/box'));
|
|
63
67
|
var TableWidget = _socketInterop(require('blessed-contrib/lib/widget/table'));
|
|
64
68
|
var readline$1 = require('node:readline');
|
|
65
69
|
|
|
@@ -321,7 +325,7 @@ class Core {
|
|
|
321
325
|
}) {
|
|
322
326
|
const introducedBy = [];
|
|
323
327
|
if (pkg.direct) {
|
|
324
|
-
|
|
328
|
+
const manifests = pkg.manifestFiles.map(({
|
|
325
329
|
file
|
|
326
330
|
}) => file).join(';');
|
|
327
331
|
introducedBy.push(['direct', manifests]);
|
|
@@ -332,7 +336,7 @@ class Core {
|
|
|
332
336
|
continue;
|
|
333
337
|
}
|
|
334
338
|
const topPurl = `${topPackage.type}/${topPackage.name}@${topPackage.version}`;
|
|
335
|
-
|
|
339
|
+
const manifests = topPackage.manifestFiles.map(({
|
|
336
340
|
file
|
|
337
341
|
}) => file).join(';');
|
|
338
342
|
introducedBy.push([topPurl, manifests]);
|
|
@@ -764,7 +768,7 @@ function processSecurityComment({
|
|
|
764
768
|
const result = [];
|
|
765
769
|
let start = false;
|
|
766
770
|
let ignoreAll = false;
|
|
767
|
-
|
|
771
|
+
const ignoredPackages = [];
|
|
768
772
|
for (const ignoreComment of ignoreComments) {
|
|
769
773
|
const parsed = parseIgnoreCommand(ignoreComment.body?.split('\n').at(0) ?? '');
|
|
770
774
|
if (parsed.ignoreAll) {
|
|
@@ -788,7 +792,7 @@ function processSecurityComment({
|
|
|
788
792
|
const [_, _title, packageLink, _introducedBy, _manifest, _ci] = line.split('|');
|
|
789
793
|
|
|
790
794
|
// Parsing package link [npm/pkg](url)
|
|
791
|
-
|
|
795
|
+
const [_ecosystem, pkg] = packageLink.slice(1, packageLink.indexOf(']')).split('/', 2);
|
|
792
796
|
const [pkgName, pkgVersion] = pkg.split('@');
|
|
793
797
|
|
|
794
798
|
// Checking if this package should be ignored
|
|
@@ -837,7 +841,7 @@ function getIgnoreOptions({
|
|
|
837
841
|
ignoreCommands.push(data);
|
|
838
842
|
}
|
|
839
843
|
} catch (e) {
|
|
840
|
-
logger.logger.
|
|
844
|
+
logger.logger.fail(`Unable to process ignore command for ${comment}`);
|
|
841
845
|
logger.logger.error(e);
|
|
842
846
|
}
|
|
843
847
|
}
|
|
@@ -1111,8 +1115,8 @@ function createSources(alert) {
|
|
|
1111
1115
|
manifests.push(addStr);
|
|
1112
1116
|
}
|
|
1113
1117
|
}
|
|
1114
|
-
|
|
1115
|
-
|
|
1118
|
+
const manifestList = manifests.join('');
|
|
1119
|
+
const sourceList = sources.join('');
|
|
1116
1120
|
const manifestStr = `<ul>${manifestList}</ul>`;
|
|
1117
1121
|
const sourcesStr = `<ul>${sourceList}</ul>`;
|
|
1118
1122
|
return [manifestStr, sourcesStr];
|
|
@@ -1223,7 +1227,7 @@ function securityCommentTemplate(diff) {
|
|
|
1223
1227
|
// TODO: is this a github action handler?
|
|
1224
1228
|
async function runAction(githubEventBefore, githubEventAfter) {
|
|
1225
1229
|
//TODO
|
|
1226
|
-
const socket = new sdk.SocketSdk(
|
|
1230
|
+
const socket = new sdk.SocketSdk(shadowNpmInject.getDefaultToken());
|
|
1227
1231
|
const git = simpleGit.simpleGit();
|
|
1228
1232
|
const changedFiles = (await git.diff(process.env['GITHUB_EVENT_NAME'] === 'pull_request' ? ['--name-only', 'HEAD^1', 'HEAD'] : ['--name-only', githubEventBefore, githubEventAfter])).split('\n');
|
|
1229
1233
|
logger.logger.log({
|
|
@@ -1257,8 +1261,8 @@ async function runAction(githubEventBefore, githubEventAfter) {
|
|
|
1257
1261
|
const securityComment = securityCommentTemplate(diff);
|
|
1258
1262
|
let newSecurityComment = true;
|
|
1259
1263
|
let newOverviewComment = true;
|
|
1260
|
-
|
|
1261
|
-
|
|
1264
|
+
const updateOldSecurityComment = comments.security !== undefined;
|
|
1265
|
+
const updateOldOverviewComment = comments.overview !== undefined;
|
|
1262
1266
|
if (diff.newAlerts.length === 0) {
|
|
1263
1267
|
if (!updateOldSecurityComment) {
|
|
1264
1268
|
newSecurityComment = false;
|
|
@@ -1288,15 +1292,14 @@ async function runAction(githubEventBefore, githubEventAfter) {
|
|
|
1288
1292
|
const {
|
|
1289
1293
|
API_V0_URL
|
|
1290
1294
|
} = constants;
|
|
1291
|
-
function handleUnsuccessfulApiResponse(_name, result
|
|
1295
|
+
function handleUnsuccessfulApiResponse(_name, result) {
|
|
1292
1296
|
// SocketSdkErrorType['error'] is not typed.
|
|
1293
1297
|
const resultErrorMessage = result.error?.message;
|
|
1294
1298
|
const message = typeof resultErrorMessage === 'string' ? resultErrorMessage : 'No error message returned';
|
|
1295
1299
|
if (result.status === 401 || result.status === 403) {
|
|
1296
|
-
|
|
1297
|
-
throw new index.AuthError(message);
|
|
1300
|
+
throw new shadowNpmInject.AuthError(message);
|
|
1298
1301
|
}
|
|
1299
|
-
|
|
1302
|
+
logger.logger.fail(`${colors.bgRed(colors.white('API returned an error:'))} ${message}`);
|
|
1300
1303
|
process$1.exit(1);
|
|
1301
1304
|
}
|
|
1302
1305
|
async function handleApiCall(value, description) {
|
|
@@ -1401,8 +1404,7 @@ const validationFlags = {
|
|
|
1401
1404
|
|
|
1402
1405
|
const {
|
|
1403
1406
|
DRY_RUN_LABEL: DRY_RUN_LABEL$1,
|
|
1404
|
-
REDACTED
|
|
1405
|
-
SOCKET_CLI_SHOW_BANNER
|
|
1407
|
+
REDACTED
|
|
1406
1408
|
} = constants;
|
|
1407
1409
|
async function meowWithSubcommands(subcommands, options) {
|
|
1408
1410
|
const {
|
|
@@ -1436,11 +1438,7 @@ async function meowWithSubcommands(subcommands, options) {
|
|
|
1436
1438
|
};
|
|
1437
1439
|
// ...else we provide basic instructions and help.
|
|
1438
1440
|
|
|
1439
|
-
|
|
1440
|
-
// Lazily access constants.ENV[SOCKET_CLI_SHOW_BANNER].
|
|
1441
|
-
if (constants.ENV[SOCKET_CLI_SHOW_BANNER]) {
|
|
1442
|
-
logger.logger.log(getAsciiHeader(name));
|
|
1443
|
-
}
|
|
1441
|
+
emitBanner(name);
|
|
1444
1442
|
const cli = vendor.meow(`
|
|
1445
1443
|
Usage
|
|
1446
1444
|
$ ${name} <command>
|
|
@@ -1475,8 +1473,8 @@ async function meowWithSubcommands(subcommands, options) {
|
|
|
1475
1473
|
autoHelp: false // otherwise we can't exit(0)
|
|
1476
1474
|
});
|
|
1477
1475
|
if (!cli.flags['help'] && cli.flags['dryRun']) {
|
|
1478
|
-
logger.logger.log(`${DRY_RUN_LABEL$1}: No-op, call a sub-command; ok`);
|
|
1479
1476
|
process.exitCode = 0;
|
|
1477
|
+
logger.logger.log(`${DRY_RUN_LABEL$1}: No-op, call a sub-command; ok`);
|
|
1480
1478
|
} else {
|
|
1481
1479
|
cli.showHelp();
|
|
1482
1480
|
}
|
|
@@ -1494,11 +1492,7 @@ function meowOrExit({
|
|
|
1494
1492
|
parentName
|
|
1495
1493
|
}) {
|
|
1496
1494
|
const command = `${parentName} ${config.commandName}`;
|
|
1497
|
-
|
|
1498
|
-
// Lazily access constants.ENV[SOCKET_CLI_SHOW_BANNER].
|
|
1499
|
-
if (constants.ENV[SOCKET_CLI_SHOW_BANNER]) {
|
|
1500
|
-
logger.logger.log(getAsciiHeader(command));
|
|
1501
|
-
}
|
|
1495
|
+
emitBanner(command);
|
|
1502
1496
|
|
|
1503
1497
|
// This exits if .printHelp() is called either by meow itself or by us.
|
|
1504
1498
|
const cli = vendor.meow({
|
|
@@ -1515,13 +1509,24 @@ function meowOrExit({
|
|
|
1515
1509
|
}
|
|
1516
1510
|
return cli;
|
|
1517
1511
|
}
|
|
1512
|
+
function emitBanner(name) {
|
|
1513
|
+
// Print a banner at the top of each command.
|
|
1514
|
+
// This helps with brand recognition and marketing.
|
|
1515
|
+
// It also helps with debugging since it contains version and command details.
|
|
1516
|
+
// Note: print over stderr to preserve stdout for flags like --json and
|
|
1517
|
+
// --markdown. If we don't do this, you can't use --json in particular
|
|
1518
|
+
// and pipe the result to other tools. By emiting the banner over stderr
|
|
1519
|
+
// you can do something like `socket scan view xyz | jq | process`.
|
|
1520
|
+
// The spinner also emits over stderr for example.
|
|
1521
|
+
logger.logger.error(getAsciiHeader(name));
|
|
1522
|
+
}
|
|
1518
1523
|
function getAsciiHeader(command) {
|
|
1519
1524
|
const cliVersion = // The '@rollup/plugin-replace' will replace "process.env['SOCKET_CLI_VERSION_HASH']".
|
|
1520
|
-
"0.14.
|
|
1525
|
+
"0.14.58:f270068:05655527:pub";
|
|
1521
1526
|
const nodeVersion = process.version;
|
|
1522
|
-
const apiToken =
|
|
1527
|
+
const apiToken = shadowNpmInject.getSetting('apiToken');
|
|
1523
1528
|
const shownToken = apiToken ? getLastFiveOfApiToken(apiToken) : 'no';
|
|
1524
|
-
const relCwd = process.cwd().replace(new RegExp(`^${regexps.escapeRegExp(constants.homePath)}`, 'i'), '~/');
|
|
1529
|
+
const relCwd = path$1.normalizePath(process.cwd().replace(new RegExp(`^${regexps.escapeRegExp(constants.homePath)}(?:${path.sep}|$)`, 'i'), '~/'));
|
|
1525
1530
|
const body = `
|
|
1526
1531
|
_____ _ _ /---------------
|
|
1527
1532
|
| __|___ ___| |_ ___| |_ | Socket.dev CLI ver ${cliVersion}
|
|
@@ -1592,10 +1597,10 @@ async function run$z(argv, importMeta, {
|
|
|
1592
1597
|
}
|
|
1593
1598
|
|
|
1594
1599
|
async function fetchOrgAnalyticsData(time, spinner, apiToken) {
|
|
1595
|
-
const socketSdk = await
|
|
1600
|
+
const socketSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
1596
1601
|
const result = await handleApiCall(socketSdk.getOrgAnalytics(time.toString()), 'fetching analytics data');
|
|
1597
1602
|
if (result.success === false) {
|
|
1598
|
-
handleUnsuccessfulApiResponse('getOrgAnalytics', result
|
|
1603
|
+
handleUnsuccessfulApiResponse('getOrgAnalytics', result);
|
|
1599
1604
|
return undefined;
|
|
1600
1605
|
}
|
|
1601
1606
|
spinner.stop();
|
|
@@ -1607,10 +1612,10 @@ async function fetchOrgAnalyticsData(time, spinner, apiToken) {
|
|
|
1607
1612
|
}
|
|
1608
1613
|
|
|
1609
1614
|
async function fetchRepoAnalyticsData(repo, time, spinner, apiToken) {
|
|
1610
|
-
const socketSdk = await
|
|
1615
|
+
const socketSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
1611
1616
|
const result = await handleApiCall(socketSdk.getRepoAnalytics(repo, time.toString()), 'fetching analytics data');
|
|
1612
1617
|
if (result.success === false) {
|
|
1613
|
-
handleUnsuccessfulApiResponse('getRepoAnalytics', result
|
|
1618
|
+
handleUnsuccessfulApiResponse('getRepoAnalytics', result);
|
|
1614
1619
|
return undefined;
|
|
1615
1620
|
}
|
|
1616
1621
|
spinner.stop();
|
|
@@ -1684,9 +1689,9 @@ async function displayAnalytics({
|
|
|
1684
1689
|
scope,
|
|
1685
1690
|
time
|
|
1686
1691
|
}) {
|
|
1687
|
-
const apiToken =
|
|
1692
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
1688
1693
|
if (!apiToken) {
|
|
1689
|
-
throw new
|
|
1694
|
+
throw new shadowNpmInject.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API token.');
|
|
1690
1695
|
}
|
|
1691
1696
|
await outputAnalyticsWithToken({
|
|
1692
1697
|
apiToken,
|
|
@@ -1720,16 +1725,16 @@ async function outputAnalyticsWithToken({
|
|
|
1720
1725
|
// A message should already have been printed if we have no data here
|
|
1721
1726
|
if (!data) return;
|
|
1722
1727
|
if (outputKind === 'json') {
|
|
1723
|
-
|
|
1728
|
+
const serialized = renderJson(data);
|
|
1724
1729
|
if (!serialized) return;
|
|
1725
1730
|
if (filePath && filePath !== '-') {
|
|
1726
1731
|
try {
|
|
1727
1732
|
await fs$1.writeFile(filePath, serialized, 'utf8');
|
|
1728
1733
|
logger.logger.log(`Data successfully written to ${filePath}`);
|
|
1729
1734
|
} catch (e) {
|
|
1730
|
-
logger.logger.error('There was an error trying to write the json to disk');
|
|
1731
|
-
logger.logger.error(e);
|
|
1732
1735
|
process.exitCode = 1;
|
|
1736
|
+
logger.logger.fail('There was an error trying to write the json to disk');
|
|
1737
|
+
logger.logger.error(e);
|
|
1733
1738
|
}
|
|
1734
1739
|
} else {
|
|
1735
1740
|
logger.logger.log(serialized);
|
|
@@ -1757,9 +1762,9 @@ function renderJson(data) {
|
|
|
1757
1762
|
try {
|
|
1758
1763
|
return JSON.stringify(data, null, 2);
|
|
1759
1764
|
} catch (e) {
|
|
1760
|
-
// This could be caused by circular references, which is an "us" problem
|
|
1761
|
-
logger.logger.error('There was a problem converting the data set to JSON. Please try without --json or with --markdown');
|
|
1762
1765
|
process.exitCode = 1;
|
|
1766
|
+
// This could be caused by circular references, which is an "us" problem
|
|
1767
|
+
logger.logger.fail('There was a problem converting the data set to JSON. Please try without --json or with --markdown');
|
|
1763
1768
|
return;
|
|
1764
1769
|
}
|
|
1765
1770
|
}
|
|
@@ -1994,7 +1999,7 @@ async function run$y(argv, importMeta, {
|
|
|
1994
1999
|
// options or missing arguments.
|
|
1995
2000
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
1996
2001
|
process.exitCode = 2;
|
|
1997
|
-
logger.logger.
|
|
2002
|
+
logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
1998
2003
|
|
|
1999
2004
|
- Scope must be "repo" or "org" ${badScope ? colors.red('(bad!)') : colors.green('(ok)')}
|
|
2000
2005
|
|
|
@@ -2028,9 +2033,9 @@ async function getAuditLog({
|
|
|
2028
2033
|
page,
|
|
2029
2034
|
perPage
|
|
2030
2035
|
}) {
|
|
2031
|
-
const apiToken =
|
|
2036
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
2032
2037
|
if (!apiToken) {
|
|
2033
|
-
throw new
|
|
2038
|
+
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.');
|
|
2034
2039
|
}
|
|
2035
2040
|
const auditLogs = await getAuditLogWithToken({
|
|
2036
2041
|
apiToken,
|
|
@@ -2074,8 +2079,8 @@ async function outputAsJson(auditLogs, orgSlug, logType, page, perPage) {
|
|
|
2074
2079
|
})
|
|
2075
2080
|
}, null, 2);
|
|
2076
2081
|
} catch (e) {
|
|
2077
|
-
logger.logger.error('There was a problem converting the logs to JSON, please try without the `--json` flag');
|
|
2078
2082
|
process.exitCode = 1;
|
|
2083
|
+
logger.logger.fail('There was a problem converting the logs to JSON, please try without the `--json` flag');
|
|
2079
2084
|
return;
|
|
2080
2085
|
}
|
|
2081
2086
|
logger.logger.log(json);
|
|
@@ -2096,9 +2101,9 @@ These are the Socket.dev audit logs as per requested query.
|
|
|
2096
2101
|
${table}
|
|
2097
2102
|
`);
|
|
2098
2103
|
} catch (e) {
|
|
2099
|
-
logger.logger.error('There was a problem converting the logs to JSON, please try without the `--json` flag');
|
|
2100
|
-
logger.logger.error(e);
|
|
2101
2104
|
process.exitCode = 1;
|
|
2105
|
+
logger.logger.fail('There was a problem converting the logs to JSON, please try without the `--json` flag');
|
|
2106
|
+
logger.logger.error(e);
|
|
2102
2107
|
return;
|
|
2103
2108
|
}
|
|
2104
2109
|
}
|
|
@@ -2140,7 +2145,7 @@ async function getAuditLogWithToken({
|
|
|
2140
2145
|
spinner
|
|
2141
2146
|
} = constants;
|
|
2142
2147
|
spinner.start(`Looking up audit log for ${orgSlug}`);
|
|
2143
|
-
const socketSdk = await
|
|
2148
|
+
const socketSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
2144
2149
|
const result = await handleApiCall(socketSdk.getAuditLogEvents(orgSlug, {
|
|
2145
2150
|
outputJson: outputKind === 'json',
|
|
2146
2151
|
// I'm not sure this is used at all
|
|
@@ -2152,7 +2157,7 @@ async function getAuditLogWithToken({
|
|
|
2152
2157
|
per_page: perPage
|
|
2153
2158
|
}), `Looking up audit log for ${orgSlug}\n`);
|
|
2154
2159
|
if (!result.success) {
|
|
2155
|
-
handleUnsuccessfulApiResponse('getAuditLogEvents', result
|
|
2160
|
+
handleUnsuccessfulApiResponse('getAuditLogEvents', result);
|
|
2156
2161
|
return;
|
|
2157
2162
|
}
|
|
2158
2163
|
spinner.stop();
|
|
@@ -2192,6 +2197,9 @@ const config$x = {
|
|
|
2192
2197
|
Usage
|
|
2193
2198
|
$ ${command} <org slug>
|
|
2194
2199
|
|
|
2200
|
+
This feature requires an Enterprise Plan. To learn more about getting access
|
|
2201
|
+
to this feature and many more, please visit https://socket.dev/pricing
|
|
2202
|
+
|
|
2195
2203
|
Options
|
|
2196
2204
|
${getFlagListOutput(config.flags, 6)}
|
|
2197
2205
|
|
|
@@ -2227,7 +2235,7 @@ async function run$x(argv, importMeta, {
|
|
|
2227
2235
|
// options or missing arguments.
|
|
2228
2236
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
2229
2237
|
process.exitCode = 2;
|
|
2230
|
-
logger.logger.
|
|
2238
|
+
logger.logger.fail(commonTags.stripIndents`
|
|
2231
2239
|
${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
|
|
2232
2240
|
- Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
2233
2241
|
`);
|
|
@@ -2247,22 +2255,22 @@ async function run$x(argv, importMeta, {
|
|
|
2247
2255
|
}
|
|
2248
2256
|
|
|
2249
2257
|
const {
|
|
2250
|
-
NPM: NPM$
|
|
2258
|
+
NPM: NPM$g,
|
|
2251
2259
|
NPX: NPX$3,
|
|
2252
|
-
PNPM: PNPM$
|
|
2260
|
+
PNPM: PNPM$a
|
|
2253
2261
|
} = constants;
|
|
2254
|
-
const nodejsPlatformTypes = new Set(['javascript', 'js', 'nodejs', NPM$
|
|
2262
|
+
const nodejsPlatformTypes = new Set(['javascript', 'js', 'nodejs', NPM$g, PNPM$a, 'ts', 'tsx', 'typescript']);
|
|
2255
2263
|
async function runCycloneDX(yargv) {
|
|
2256
2264
|
let cleanupPackageLock = false;
|
|
2257
2265
|
if (yargv.type !== 'yarn' && nodejsPlatformTypes.has(yargv.type) && fs.existsSync('./yarn.lock')) {
|
|
2258
2266
|
if (fs.existsSync('./package-lock.json')) {
|
|
2259
|
-
yargv.type = NPM$
|
|
2267
|
+
yargv.type = NPM$g;
|
|
2260
2268
|
} else {
|
|
2261
2269
|
// Use synp to create a package-lock.json from the yarn.lock,
|
|
2262
2270
|
// based on the node_modules folder, for a more accurate SBOM.
|
|
2263
2271
|
try {
|
|
2264
2272
|
await shadowBin(NPX$3, ['synp@1.9.14', '--', '--source-file', './yarn.lock'], 2);
|
|
2265
|
-
yargv.type = NPM$
|
|
2273
|
+
yargv.type = NPM$g;
|
|
2266
2274
|
cleanupPackageLock = true;
|
|
2267
2275
|
} catch {}
|
|
2268
2276
|
}
|
|
@@ -2413,7 +2421,7 @@ async function run$w(argv, importMeta, {
|
|
|
2413
2421
|
//
|
|
2414
2422
|
//
|
|
2415
2423
|
// if (cli.input.length)
|
|
2416
|
-
// logger.
|
|
2424
|
+
// logger.fail(
|
|
2417
2425
|
// stripIndents`
|
|
2418
2426
|
// ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
2419
2427
|
//
|
|
@@ -2437,7 +2445,7 @@ async function run$w(argv, importMeta, {
|
|
|
2437
2445
|
// options or missing arguments.
|
|
2438
2446
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
2439
2447
|
process$1.exitCode = 2;
|
|
2440
|
-
logger.logger.
|
|
2448
|
+
logger.logger.fail(`Unknown ${words.pluralize('argument', unknownLength)}: ${yargv._.join(', ')}`);
|
|
2441
2449
|
return;
|
|
2442
2450
|
}
|
|
2443
2451
|
if (yargv.output === undefined) {
|
|
@@ -2456,22 +2464,22 @@ async function findDependencies({
|
|
|
2456
2464
|
offset,
|
|
2457
2465
|
outputJson
|
|
2458
2466
|
}) {
|
|
2459
|
-
const apiToken =
|
|
2467
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
2460
2468
|
if (!apiToken) {
|
|
2461
|
-
throw new
|
|
2469
|
+
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.');
|
|
2462
2470
|
}
|
|
2463
2471
|
// Lazily access constants.spinner.
|
|
2464
2472
|
const {
|
|
2465
2473
|
spinner
|
|
2466
2474
|
} = constants;
|
|
2467
2475
|
spinner.start('Searching dependencies...');
|
|
2468
|
-
const socketSdk = await
|
|
2476
|
+
const socketSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
2469
2477
|
const result = await handleApiCall(socketSdk.searchDependencies({
|
|
2470
2478
|
limit,
|
|
2471
2479
|
offset
|
|
2472
2480
|
}), 'Searching dependencies');
|
|
2473
2481
|
if (!result.success) {
|
|
2474
|
-
handleUnsuccessfulApiResponse('searchDependencies', result
|
|
2482
|
+
handleUnsuccessfulApiResponse('searchDependencies', result);
|
|
2475
2483
|
return;
|
|
2476
2484
|
}
|
|
2477
2485
|
spinner.stop('Organization dependencies:');
|
|
@@ -2576,9 +2584,9 @@ async function getDiffScan({
|
|
|
2576
2584
|
orgSlug,
|
|
2577
2585
|
outputJson
|
|
2578
2586
|
}) {
|
|
2579
|
-
const apiToken =
|
|
2587
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
2580
2588
|
if (!apiToken) {
|
|
2581
|
-
throw new
|
|
2589
|
+
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.');
|
|
2582
2590
|
}
|
|
2583
2591
|
await getDiffScanWithToken({
|
|
2584
2592
|
after,
|
|
@@ -2623,16 +2631,17 @@ async function getDiffScanWithToken({
|
|
|
2623
2631
|
try {
|
|
2624
2632
|
json = JSON.stringify(result, null, 2);
|
|
2625
2633
|
} catch (e) {
|
|
2626
|
-
// Most likely caused by a circular reference (or OOM)
|
|
2627
|
-
logger.logger.error('There was a problem converting the data to JSON');
|
|
2628
2634
|
process.exitCode = 1;
|
|
2635
|
+
// Most likely caused by a circular reference (or OOM)
|
|
2636
|
+
logger.logger.fail('There was a problem converting the data to JSON');
|
|
2637
|
+
logger.logger.error(e);
|
|
2629
2638
|
return;
|
|
2630
2639
|
}
|
|
2631
2640
|
if (file && file !== '-') {
|
|
2632
2641
|
logger.logger.log(`Writing json to \`${file}\``);
|
|
2633
2642
|
fs.writeFile(file, JSON.stringify(result, null, 2), err => {
|
|
2634
2643
|
if (err) {
|
|
2635
|
-
logger.logger.
|
|
2644
|
+
logger.logger.fail(`Writing to \`${file}\` failed...`);
|
|
2636
2645
|
logger.logger.error(err);
|
|
2637
2646
|
} else {
|
|
2638
2647
|
logger.logger.log(`Data successfully written to \`${file}\``);
|
|
@@ -2738,7 +2747,7 @@ async function run$u(argv, importMeta, {
|
|
|
2738
2747
|
// options or missing arguments.
|
|
2739
2748
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
2740
2749
|
process.exitCode = 2;
|
|
2741
|
-
logger.logger.
|
|
2750
|
+
logger.logger.fail(`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
|
|
2742
2751
|
- Specify a before and after full scan ID ${!before && !after ? colors.red('(missing before and after!)') : !before ? colors.red('(missing before!)') : !after ? colors.red('(missing after!)') : colors.green('(ok)')}\n
|
|
2743
2752
|
- To get full scans IDs, you can run the command "socket scan list <your org slug>".
|
|
2744
2753
|
The args are expecting a full \`aaa0aa0a-aaaa-0000-0a0a-0000000a00a0\` ID.\n
|
|
@@ -2781,254 +2790,766 @@ const cmdDiffScan = {
|
|
|
2781
2790
|
}
|
|
2782
2791
|
};
|
|
2783
2792
|
|
|
2784
|
-
// import { detect } from '../../utils/package-environment-detector'
|
|
2785
|
-
|
|
2786
2793
|
const {
|
|
2787
|
-
NPM: NPM$
|
|
2794
|
+
NPM: NPM$f
|
|
2788
2795
|
} = constants;
|
|
2789
2796
|
function isTopLevel(tree, node) {
|
|
2790
2797
|
return tree.children.get(node.name) === node;
|
|
2791
2798
|
}
|
|
2792
|
-
async function
|
|
2793
|
-
// Lazily access constants.spinner.
|
|
2799
|
+
async function npmFix(_pkgEnvDetails, cwd, options) {
|
|
2794
2800
|
const {
|
|
2795
2801
|
spinner
|
|
2796
|
-
} =
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
// const agentDetails = await detect()
|
|
2803
|
-
|
|
2804
|
-
const arb = new index.SafeArborist({
|
|
2802
|
+
} = {
|
|
2803
|
+
__proto__: null,
|
|
2804
|
+
...options
|
|
2805
|
+
};
|
|
2806
|
+
spinner?.start();
|
|
2807
|
+
const arb = new shadowNpmInject.SafeArborist({
|
|
2805
2808
|
path: cwd,
|
|
2806
|
-
...
|
|
2809
|
+
...shadowNpmInject.SAFE_ARBORIST_REIFY_OPTIONS_OVERRIDES
|
|
2807
2810
|
});
|
|
2808
2811
|
await arb.reify();
|
|
2809
|
-
const
|
|
2812
|
+
const alertsMap = await shadowNpmInject.getAlertsMapFromArborist(arb, {
|
|
2810
2813
|
consolidate: true,
|
|
2811
|
-
|
|
2812
|
-
|
|
2814
|
+
include: {
|
|
2815
|
+
existing: true,
|
|
2816
|
+
unfixable: false,
|
|
2817
|
+
upgrade: false
|
|
2818
|
+
}
|
|
2813
2819
|
});
|
|
2814
|
-
const infoByPkg =
|
|
2820
|
+
const infoByPkg = shadowNpmInject.getCveInfoByAlertsMap(alertsMap);
|
|
2821
|
+
if (!infoByPkg) {
|
|
2822
|
+
spinner?.stop();
|
|
2823
|
+
return;
|
|
2824
|
+
}
|
|
2815
2825
|
await arb.buildIdealTree();
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
}
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2826
|
+
const editablePkgJson = await packages.readPackageJson(cwd, {
|
|
2827
|
+
editable: true
|
|
2828
|
+
});
|
|
2829
|
+
for (const {
|
|
2830
|
+
0: name,
|
|
2831
|
+
1: infos
|
|
2832
|
+
} of infoByPkg) {
|
|
2833
|
+
const revertToIdealTree = arb.idealTree;
|
|
2834
|
+
arb.idealTree = null;
|
|
2835
|
+
// eslint-disable-next-line no-await-in-loop
|
|
2836
|
+
await arb.buildIdealTree();
|
|
2837
|
+
const tree = arb.idealTree;
|
|
2838
|
+
const hasUpgrade = !!registry.getManifestData(NPM$f, name);
|
|
2839
|
+
if (hasUpgrade) {
|
|
2840
|
+
spinner?.info(`Skipping ${name}. Socket Optimize package exists.`);
|
|
2841
|
+
continue;
|
|
2842
|
+
}
|
|
2843
|
+
const nodes = shadowNpmInject.findPackageNodes(tree, name);
|
|
2844
|
+
const packument = nodes.length && infos.length ?
|
|
2845
|
+
// eslint-disable-next-line no-await-in-loop
|
|
2846
|
+
await packages.fetchPackagePackument(name) : null;
|
|
2847
|
+
if (!packument) {
|
|
2848
|
+
continue;
|
|
2849
|
+
}
|
|
2850
|
+
for (let i = 0, {
|
|
2851
|
+
length: nodesLength
|
|
2852
|
+
} = nodes; i < nodesLength; i += 1) {
|
|
2853
|
+
const node = nodes[i];
|
|
2854
|
+
for (let j = 0, {
|
|
2855
|
+
length: infosLength
|
|
2856
|
+
} = infos; j < infosLength; j += 1) {
|
|
2857
|
+
const {
|
|
2858
|
+
firstPatchedVersionIdentifier,
|
|
2859
|
+
vulnerableVersionRange
|
|
2860
|
+
} = infos[j];
|
|
2861
|
+
const {
|
|
2862
|
+
version: oldVersion
|
|
2863
|
+
} = node;
|
|
2864
|
+
if (shadowNpmInject.updateNode(node, packument, vulnerableVersionRange)) {
|
|
2865
|
+
try {
|
|
2866
|
+
// eslint-disable-next-line no-await-in-loop
|
|
2867
|
+
await npm.runScript('test', [], {
|
|
2868
|
+
spinner,
|
|
2869
|
+
stdio: 'ignore'
|
|
2870
|
+
});
|
|
2871
|
+
spinner?.info(`Patched ${name} ${oldVersion} -> ${node.version}`);
|
|
2872
|
+
if (isTopLevel(tree, node)) {
|
|
2873
|
+
for (const depField of ['dependencies', 'optionalDependencies', 'peerDependencies']) {
|
|
2874
|
+
const {
|
|
2875
|
+
content: pkgJson
|
|
2876
|
+
} = editablePkgJson;
|
|
2877
|
+
const oldVersion = pkgJson[depField]?.[name];
|
|
2878
|
+
if (oldVersion) {
|
|
2879
|
+
const decorator = /^[~^]/.exec(oldVersion)?.[0] ?? '';
|
|
2880
|
+
pkgJson[depField][name] = `${decorator}${node.version}`;
|
|
2866
2881
|
}
|
|
2867
|
-
// eslint-disable-next-line no-await-in-loop
|
|
2868
|
-
await editablePkgJson.save();
|
|
2869
|
-
} catch {
|
|
2870
|
-
spinner.error(`Reverting ${name} to ${oldVersion}`);
|
|
2871
|
-
arb.idealTree = revertToIdealTree;
|
|
2872
2882
|
}
|
|
2873
|
-
} else {
|
|
2874
|
-
spinner.error(`Could not patch ${name} ${oldVersion}`);
|
|
2875
2883
|
}
|
|
2884
|
+
// eslint-disable-next-line no-await-in-loop
|
|
2885
|
+
await editablePkgJson.save();
|
|
2886
|
+
} catch {
|
|
2887
|
+
spinner?.error(`Reverting ${name} to ${oldVersion}`);
|
|
2888
|
+
arb.idealTree = revertToIdealTree;
|
|
2876
2889
|
}
|
|
2890
|
+
} else {
|
|
2891
|
+
spinner?.error(`Could not patch ${name} ${oldVersion}`);
|
|
2877
2892
|
}
|
|
2878
2893
|
}
|
|
2879
2894
|
}
|
|
2880
2895
|
}
|
|
2881
|
-
const arb2 = new
|
|
2896
|
+
const arb2 = new shadowNpmInject.Arborist({
|
|
2882
2897
|
path: cwd
|
|
2883
2898
|
});
|
|
2884
2899
|
arb2.idealTree = arb.idealTree;
|
|
2885
2900
|
await arb2.reify();
|
|
2886
|
-
spinner
|
|
2901
|
+
spinner?.stop();
|
|
2887
2902
|
}
|
|
2888
2903
|
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
`
|
|
2906
|
-
|
|
2907
|
-
const
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
importMeta,
|
|
2919
|
-
parentName
|
|
2920
|
-
});
|
|
2921
|
-
if (cli.flags['dryRun']) {
|
|
2922
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$s);
|
|
2923
|
-
return;
|
|
2904
|
+
async function getAlertsMapFromPnpmLockfile(lockfile, options) {
|
|
2905
|
+
const {
|
|
2906
|
+
spinner
|
|
2907
|
+
} = {
|
|
2908
|
+
__proto__: null,
|
|
2909
|
+
...options
|
|
2910
|
+
};
|
|
2911
|
+
const depTypes = lockfile_detectDepTypes.detectDepTypes(lockfile);
|
|
2912
|
+
const pkgIds = Object.keys(depTypes);
|
|
2913
|
+
let {
|
|
2914
|
+
length: remaining
|
|
2915
|
+
} = pkgIds;
|
|
2916
|
+
const alertsByPkgId = new Map();
|
|
2917
|
+
if (!remaining) {
|
|
2918
|
+
return alertsByPkgId;
|
|
2919
|
+
}
|
|
2920
|
+
const getText = () => `Looking up data for ${remaining} packages`;
|
|
2921
|
+
spinner?.start(getText());
|
|
2922
|
+
const toAlertsMapOptions = {
|
|
2923
|
+
overrides: lockfile.overrides,
|
|
2924
|
+
...options
|
|
2925
|
+
};
|
|
2926
|
+
for await (const artifact of shadowNpmInject.batchScan(pkgIds)) {
|
|
2927
|
+
await shadowNpmInject.addArtifactToAlertsMap(artifact, alertsByPkgId, toAlertsMapOptions);
|
|
2928
|
+
remaining -= 1;
|
|
2929
|
+
if (spinner && remaining > 0) {
|
|
2930
|
+
spinner.start();
|
|
2931
|
+
spinner.setText(getText());
|
|
2932
|
+
}
|
|
2924
2933
|
}
|
|
2925
|
-
|
|
2934
|
+
spinner?.stop();
|
|
2935
|
+
return alertsByPkgId;
|
|
2926
2936
|
}
|
|
2927
2937
|
|
|
2928
|
-
function
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2938
|
+
function cmdFlagsToString(args) {
|
|
2939
|
+
const result = [];
|
|
2940
|
+
for (let i = 0, {
|
|
2941
|
+
length
|
|
2942
|
+
} = args; i < length; i += 1) {
|
|
2943
|
+
if (args[i].startsWith('--')) {
|
|
2944
|
+
// Check if the next item exists and is NOT another flag.
|
|
2945
|
+
if (i + 1 < length && !args[i + 1].startsWith('--')) {
|
|
2946
|
+
result.push(`${args[i]}=${args[i + 1]}`);
|
|
2947
|
+
i += 1;
|
|
2948
|
+
} else {
|
|
2949
|
+
result.push(args[i]);
|
|
2950
|
+
}
|
|
2932
2951
|
}
|
|
2933
2952
|
}
|
|
2934
|
-
return
|
|
2953
|
+
return result.join(' ');
|
|
2935
2954
|
}
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2955
|
+
|
|
2956
|
+
const {
|
|
2957
|
+
SOCKET_IPC_HANDSHAKE
|
|
2958
|
+
} = constants;
|
|
2959
|
+
function safeNpmInstall(options) {
|
|
2960
|
+
const {
|
|
2961
|
+
agentExecPath = shadowNpmPaths.getNpmBinPath(),
|
|
2962
|
+
args = [],
|
|
2963
|
+
ipc,
|
|
2964
|
+
spinner,
|
|
2965
|
+
...spawnOptions
|
|
2966
|
+
} = {
|
|
2967
|
+
__proto__: null,
|
|
2968
|
+
...options
|
|
2969
|
+
};
|
|
2970
|
+
const useIpc = objects.isObject(ipc);
|
|
2971
|
+
const useDebug = debug.isDebug();
|
|
2972
|
+
const terminatorPos = args.indexOf('--');
|
|
2973
|
+
const npmArgs = (terminatorPos === -1 ? args : args.slice(0, terminatorPos)).filter(a => !npm.isAuditFlag(a) && !npm.isFundFlag(a) && !npm.isProgressFlag(a));
|
|
2974
|
+
const otherArgs = terminatorPos === -1 ? [] : args.slice(terminatorPos);
|
|
2975
|
+
const isSilent = !useDebug && !npmArgs.some(npm.isLoglevelFlag);
|
|
2976
|
+
const logLevelArgs = isSilent ? ['--loglevel', 'error'] : [];
|
|
2977
|
+
const spawnPromise = spawn.spawn(
|
|
2978
|
+
// Lazily access constants.execPath.
|
|
2979
|
+
constants.execPath, [
|
|
2980
|
+
// Lazily access constants.nodeHardenFlags.
|
|
2981
|
+
...constants.nodeHardenFlags,
|
|
2982
|
+
// Lazily access constants.nodeNoWarningsFlags.
|
|
2983
|
+
...constants.nodeNoWarningsFlags, '--require',
|
|
2984
|
+
// Lazily access constants.distShadowNpmInjectPath.
|
|
2985
|
+
constants.distShadowNpmInjectPath, agentExecPath, 'install',
|
|
2986
|
+
// Avoid code paths for 'audit' and 'fund'.
|
|
2987
|
+
'--no-audit', '--no-fund',
|
|
2988
|
+
// Add `--no-progress` flag to fix input being swallowed by the spinner
|
|
2989
|
+
// when running the command with recent versions of npm.
|
|
2990
|
+
'--no-progress',
|
|
2991
|
+
// Add '--loglevel=error' if a loglevel flag is not provided and the
|
|
2992
|
+
// SOCKET_CLI_DEBUG environment variable is not truthy.
|
|
2993
|
+
...logLevelArgs, ...npmArgs, ...otherArgs], {
|
|
2994
|
+
spinner,
|
|
2995
|
+
// Set stdio to include 'ipc'.
|
|
2996
|
+
// See https://github.com/nodejs/node/blob/v23.6.0/lib/child_process.js#L161-L166
|
|
2997
|
+
// and https://github.com/nodejs/node/blob/v23.6.0/lib/internal/child_process.js#L238.
|
|
2998
|
+
stdio: useIpc ? [0, 1, 2, 'ipc'] : 'inherit',
|
|
2999
|
+
...spawnOptions,
|
|
3000
|
+
env: {
|
|
3001
|
+
...process$1.env,
|
|
3002
|
+
...spawnOptions.env
|
|
3003
|
+
}
|
|
3004
|
+
});
|
|
3005
|
+
if (useIpc) {
|
|
3006
|
+
spawnPromise.process.send({
|
|
3007
|
+
[SOCKET_IPC_HANDSHAKE]: ipc
|
|
3008
|
+
});
|
|
2940
3009
|
}
|
|
2941
|
-
return
|
|
3010
|
+
return spawnPromise;
|
|
2942
3011
|
}
|
|
2943
3012
|
|
|
2944
|
-
|
|
2945
|
-
|
|
3013
|
+
const {
|
|
3014
|
+
NPM: NPM$e
|
|
3015
|
+
} = constants;
|
|
3016
|
+
function runAgentInstall(pkgEnvDetails, options) {
|
|
2946
3017
|
const {
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
3018
|
+
agent,
|
|
3019
|
+
agentExecPath
|
|
3020
|
+
} = pkgEnvDetails;
|
|
3021
|
+
// All package managers support the "install" command.
|
|
3022
|
+
if (agent === NPM$e) {
|
|
3023
|
+
return safeNpmInstall({
|
|
3024
|
+
agentExecPath,
|
|
3025
|
+
...options
|
|
3026
|
+
});
|
|
2954
3027
|
}
|
|
2955
|
-
const
|
|
2956
|
-
|
|
3028
|
+
const {
|
|
3029
|
+
args = [],
|
|
3030
|
+
spinner,
|
|
3031
|
+
...spawnOptions
|
|
3032
|
+
} = {
|
|
3033
|
+
__proto__: null,
|
|
3034
|
+
...options
|
|
3035
|
+
};
|
|
3036
|
+
return spawn.spawn(agentExecPath, ['install', ...args], {
|
|
3037
|
+
spinner,
|
|
3038
|
+
stdio: debug.isDebug() ? 'inherit' : 'ignore',
|
|
3039
|
+
...spawnOptions,
|
|
3040
|
+
env: {
|
|
3041
|
+
...process.env,
|
|
3042
|
+
NODE_OPTIONS: cmdFlagsToString([
|
|
3043
|
+
// Lazily access constants.nodeHardenFlags.
|
|
3044
|
+
...constants.nodeHardenFlags,
|
|
3045
|
+
// Lazily access constants.nodeNoWarningsFlags.
|
|
3046
|
+
...constants.nodeNoWarningsFlags]),
|
|
3047
|
+
...spawnOptions.env
|
|
3048
|
+
}
|
|
3049
|
+
});
|
|
2957
3050
|
}
|
|
2958
3051
|
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
3052
|
+
const {
|
|
3053
|
+
NPM: NPM$d,
|
|
3054
|
+
OVERRIDES: OVERRIDES$2,
|
|
3055
|
+
PNPM: PNPM$9
|
|
3056
|
+
} = constants;
|
|
3057
|
+
async function pnpmFix(pkgEnvDetails, cwd, options) {
|
|
3058
|
+
const {
|
|
3059
|
+
spinner
|
|
3060
|
+
} = {
|
|
3061
|
+
__proto__: null,
|
|
3062
|
+
...options
|
|
3063
|
+
};
|
|
3064
|
+
spinner?.start();
|
|
3065
|
+
const lockfile = await lockfileFile.readWantedLockfile(cwd, {
|
|
3066
|
+
ignoreIncompatible: false
|
|
3067
|
+
});
|
|
3068
|
+
if (!lockfile) {
|
|
3069
|
+
spinner?.stop();
|
|
3070
|
+
return;
|
|
2968
3071
|
}
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
summary.push(`${severityCount[severity]} ${severity}`);
|
|
3072
|
+
const alertsMap = await getAlertsMapFromPnpmLockfile(lockfile, {
|
|
3073
|
+
consolidate: true,
|
|
3074
|
+
include: {
|
|
3075
|
+
existing: true,
|
|
3076
|
+
unfixable: false,
|
|
3077
|
+
upgrade: false
|
|
2976
3078
|
}
|
|
3079
|
+
});
|
|
3080
|
+
const infoByPkg = shadowNpmInject.getCveInfoByAlertsMap(alertsMap);
|
|
3081
|
+
if (!infoByPkg) {
|
|
3082
|
+
spinner?.stop();
|
|
3083
|
+
return;
|
|
2977
3084
|
}
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
3085
|
+
const arb = new shadowNpmInject.SafeArborist({
|
|
3086
|
+
path: cwd,
|
|
3087
|
+
...shadowNpmInject.SAFE_ARBORIST_REIFY_OPTIONS_OVERRIDES
|
|
3088
|
+
});
|
|
3089
|
+
await arb.loadActual();
|
|
3090
|
+
const editablePkgJson = await packages.readPackageJson(cwd, {
|
|
3091
|
+
editable: true
|
|
3092
|
+
});
|
|
3093
|
+
const {
|
|
3094
|
+
content: pkgJson
|
|
3095
|
+
} = editablePkgJson;
|
|
3096
|
+
for (const {
|
|
3097
|
+
0: name,
|
|
3098
|
+
1: infos
|
|
3099
|
+
} of infoByPkg) {
|
|
3100
|
+
const tree = arb.actualTree;
|
|
3101
|
+
const hasUpgrade = !!registry.getManifestData(NPM$d, name);
|
|
3102
|
+
if (hasUpgrade) {
|
|
3103
|
+
spinner?.info(`Skipping ${name}. Socket Optimize package exists.`);
|
|
2992
3104
|
continue;
|
|
2993
3105
|
}
|
|
2994
|
-
|
|
2995
|
-
|
|
3106
|
+
const nodes = shadowNpmInject.findPackageNodes(tree, name);
|
|
3107
|
+
const packument = nodes.length && infos.length ?
|
|
3108
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3109
|
+
await packages.fetchPackagePackument(name) : null;
|
|
3110
|
+
if (!packument) {
|
|
3111
|
+
continue;
|
|
2996
3112
|
}
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
}
|
|
3113
|
+
for (let i = 0, {
|
|
3114
|
+
length: nodesLength
|
|
3115
|
+
} = nodes; i < nodesLength; i += 1) {
|
|
3116
|
+
const node = nodes[i];
|
|
3117
|
+
for (let j = 0, {
|
|
3118
|
+
length: infosLength
|
|
3119
|
+
} = infos; j < infosLength; j += 1) {
|
|
3120
|
+
const {
|
|
3121
|
+
firstPatchedVersionIdentifier,
|
|
3122
|
+
vulnerableVersionRange
|
|
3123
|
+
} = infos[j];
|
|
3124
|
+
const {
|
|
3125
|
+
version: oldVersion
|
|
3126
|
+
} = node;
|
|
3127
|
+
const availableVersions = Object.keys(packument.versions);
|
|
3128
|
+
// Find the highest non-vulnerable version within the same major range
|
|
3129
|
+
const targetVersion = shadowNpmInject.findBestPatchVersion(node, availableVersions, vulnerableVersionRange);
|
|
3130
|
+
const targetPackument = targetVersion ? packument.versions[targetVersion] : undefined;
|
|
3131
|
+
if (targetPackument) {
|
|
3132
|
+
const oldPnpm = pkgJson[PNPM$9];
|
|
3133
|
+
const oldOverrides = oldPnpm?.[OVERRIDES$2];
|
|
3134
|
+
try {
|
|
3135
|
+
editablePkgJson.update({
|
|
3136
|
+
[PNPM$9]: {
|
|
3137
|
+
...oldPnpm,
|
|
3138
|
+
[OVERRIDES$2]: {
|
|
3139
|
+
[`${node.name}@${vulnerableVersionRange}`]: `^${targetVersion}`,
|
|
3140
|
+
...oldOverrides
|
|
3141
|
+
}
|
|
3142
|
+
}
|
|
3143
|
+
});
|
|
3144
|
+
spinner?.info(`Patched ${name} ${oldVersion} -> ${node.version}`);
|
|
3000
3145
|
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3146
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3147
|
+
await editablePkgJson.save();
|
|
3148
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3149
|
+
await runAgentInstall(pkgEnvDetails, {
|
|
3150
|
+
spinner
|
|
3151
|
+
});
|
|
3152
|
+
} catch {
|
|
3153
|
+
spinner?.error(`Reverting ${name} to ${oldVersion}`);
|
|
3154
|
+
}
|
|
3155
|
+
} else {
|
|
3156
|
+
spinner?.error(`Could not patch ${name} ${oldVersion}`);
|
|
3157
|
+
}
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3015
3160
|
}
|
|
3016
|
-
|
|
3017
|
-
spinner?.successAndStop('Data fetched');
|
|
3018
|
-
return {
|
|
3019
|
-
data: result.data,
|
|
3020
|
-
severityCount,
|
|
3021
|
-
score: scoreResult.data
|
|
3022
|
-
};
|
|
3161
|
+
spinner?.stop();
|
|
3023
3162
|
}
|
|
3024
3163
|
|
|
3025
3164
|
const {
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3165
|
+
BINARY_LOCK_EXT,
|
|
3166
|
+
BUN: BUN$6,
|
|
3167
|
+
LOCK_EXT: LOCK_EXT$1,
|
|
3168
|
+
NPM: NPM$c,
|
|
3169
|
+
PNPM: PNPM$8,
|
|
3170
|
+
VLT: VLT$6,
|
|
3171
|
+
YARN,
|
|
3172
|
+
YARN_BERRY: YARN_BERRY$6,
|
|
3173
|
+
YARN_CLASSIC: YARN_CLASSIC$6
|
|
3174
|
+
} = constants;
|
|
3175
|
+
const AGENTS = [BUN$6, NPM$c, PNPM$8, YARN_BERRY$6, YARN_CLASSIC$6, VLT$6];
|
|
3176
|
+
const binByAgent = {
|
|
3177
|
+
__proto__: null,
|
|
3178
|
+
[BUN$6]: BUN$6,
|
|
3179
|
+
[NPM$c]: NPM$c,
|
|
3180
|
+
[PNPM$8]: PNPM$8,
|
|
3181
|
+
[YARN_BERRY$6]: YARN,
|
|
3182
|
+
[YARN_CLASSIC$6]: YARN,
|
|
3183
|
+
[VLT$6]: VLT$6
|
|
3184
|
+
};
|
|
3185
|
+
async function getAgentExecPath(agent) {
|
|
3186
|
+
const binName = binByAgent[agent];
|
|
3187
|
+
return (await which(binName, {
|
|
3188
|
+
nothrow: true
|
|
3189
|
+
})) ?? binName;
|
|
3190
|
+
}
|
|
3191
|
+
async function getAgentVersion(agentExecPath, cwd) {
|
|
3192
|
+
let result;
|
|
3193
|
+
try {
|
|
3194
|
+
result = semver.coerce(
|
|
3195
|
+
// All package managers support the "--version" flag.
|
|
3196
|
+
(await spawn.spawn(agentExecPath, ['--version'], {
|
|
3197
|
+
cwd
|
|
3198
|
+
})).stdout) ?? undefined;
|
|
3199
|
+
} catch {}
|
|
3200
|
+
return result;
|
|
3201
|
+
}
|
|
3202
|
+
|
|
3203
|
+
// The order of LOCKS properties IS significant as it affects iteration order.
|
|
3204
|
+
const LOCKS = {
|
|
3205
|
+
[`bun${LOCK_EXT$1}`]: BUN$6,
|
|
3206
|
+
[`bun${BINARY_LOCK_EXT}`]: BUN$6,
|
|
3207
|
+
// If both package-lock.json and npm-shrinkwrap.json are present in the root
|
|
3208
|
+
// of a project, npm-shrinkwrap.json will take precedence and package-lock.json
|
|
3209
|
+
// will be ignored.
|
|
3210
|
+
// https://docs.npmjs.com/cli/v10/configuring-npm/package-lock-json#package-lockjson-vs-npm-shrinkwrapjson
|
|
3211
|
+
'npm-shrinkwrap.json': NPM$c,
|
|
3212
|
+
'package-lock.json': NPM$c,
|
|
3213
|
+
'pnpm-lock.yaml': PNPM$8,
|
|
3214
|
+
'pnpm-lock.yml': PNPM$8,
|
|
3215
|
+
[`yarn${LOCK_EXT$1}`]: YARN_CLASSIC$6,
|
|
3216
|
+
'vlt-lock.json': VLT$6,
|
|
3217
|
+
// Lastly, look for a hidden lock file which is present if .npmrc has package-lock=false:
|
|
3218
|
+
// https://docs.npmjs.com/cli/v10/configuring-npm/package-lock-json#hidden-lockfiles
|
|
3219
|
+
//
|
|
3220
|
+
// Unlike the other LOCKS keys this key contains a directory AND filename so
|
|
3221
|
+
// it has to be handled differently.
|
|
3222
|
+
'node_modules/.package-lock.json': NPM$c
|
|
3223
|
+
};
|
|
3224
|
+
const readLockFileByAgent = (() => {
|
|
3225
|
+
function wrapReader(reader) {
|
|
3226
|
+
return async (...args) => {
|
|
3227
|
+
try {
|
|
3228
|
+
return await reader(...args);
|
|
3229
|
+
} catch {}
|
|
3230
|
+
return undefined;
|
|
3231
|
+
};
|
|
3232
|
+
}
|
|
3233
|
+
const binaryReader = wrapReader(shadowNpmInject.readFileBinary);
|
|
3234
|
+
const defaultReader = wrapReader(async lockPath => await shadowNpmInject.readFileUtf8(lockPath));
|
|
3235
|
+
return {
|
|
3236
|
+
[BUN$6]: wrapReader(async (lockPath, agentExecPath) => {
|
|
3237
|
+
const ext = path.extname(lockPath);
|
|
3238
|
+
if (ext === LOCK_EXT$1) {
|
|
3239
|
+
return await defaultReader(lockPath);
|
|
3240
|
+
}
|
|
3241
|
+
if (ext === BINARY_LOCK_EXT) {
|
|
3242
|
+
const lockBuffer = await binaryReader(lockPath);
|
|
3243
|
+
if (lockBuffer) {
|
|
3244
|
+
try {
|
|
3245
|
+
return index_cjs.parse(lockBuffer);
|
|
3246
|
+
} catch {}
|
|
3247
|
+
}
|
|
3248
|
+
// To print a Yarn lockfile to your console without writing it to disk
|
|
3249
|
+
// use `bun bun.lockb`.
|
|
3250
|
+
// https://bun.sh/guides/install/yarnlock
|
|
3251
|
+
return (await spawn.spawn(agentExecPath, [lockPath])).stdout.trim();
|
|
3252
|
+
}
|
|
3253
|
+
return undefined;
|
|
3254
|
+
}),
|
|
3255
|
+
[NPM$c]: defaultReader,
|
|
3256
|
+
[PNPM$8]: defaultReader,
|
|
3257
|
+
[VLT$6]: defaultReader,
|
|
3258
|
+
[YARN_BERRY$6]: defaultReader,
|
|
3259
|
+
[YARN_CLASSIC$6]: defaultReader
|
|
3260
|
+
};
|
|
3261
|
+
})();
|
|
3262
|
+
async function detectPackageEnvironment({
|
|
3263
|
+
cwd = process$1.cwd(),
|
|
3264
|
+
onUnknown
|
|
3265
|
+
} = {}) {
|
|
3266
|
+
let lockPath = await shadowNpmInject.findUp(Object.keys(LOCKS), {
|
|
3267
|
+
cwd
|
|
3268
|
+
});
|
|
3269
|
+
let lockName = lockPath ? path.basename(lockPath) : undefined;
|
|
3270
|
+
const isHiddenLockFile = lockName === '.package-lock.json';
|
|
3271
|
+
const pkgJsonPath = lockPath ? path.resolve(lockPath, `${isHiddenLockFile ? '../' : ''}../package.json`) : await shadowNpmInject.findUp('package.json', {
|
|
3272
|
+
cwd
|
|
3273
|
+
});
|
|
3274
|
+
const pkgPath = pkgJsonPath && fs.existsSync(pkgJsonPath) ? path.dirname(pkgJsonPath) : undefined;
|
|
3275
|
+
const editablePkgJson = pkgPath ? await packages.readPackageJson(pkgPath, {
|
|
3276
|
+
editable: true
|
|
3277
|
+
}) : undefined;
|
|
3278
|
+
const pkgJson = editablePkgJson?.content;
|
|
3279
|
+
// Read Corepack `packageManager` field in package.json:
|
|
3280
|
+
// https://nodejs.org/api/packages.html#packagemanager
|
|
3281
|
+
const pkgManager = strings.isNonEmptyString(pkgJson?.packageManager) ? pkgJson.packageManager : undefined;
|
|
3282
|
+
let agent;
|
|
3283
|
+
let agentVersion;
|
|
3284
|
+
if (pkgManager) {
|
|
3285
|
+
const atSignIndex = pkgManager.lastIndexOf('@');
|
|
3286
|
+
if (atSignIndex !== -1) {
|
|
3287
|
+
const name = pkgManager.slice(0, atSignIndex);
|
|
3288
|
+
const version = pkgManager.slice(atSignIndex + 1);
|
|
3289
|
+
if (version && AGENTS.includes(name)) {
|
|
3290
|
+
agent = name;
|
|
3291
|
+
agentVersion = semver.coerce(version) ?? undefined;
|
|
3292
|
+
}
|
|
3293
|
+
}
|
|
3294
|
+
}
|
|
3295
|
+
if (agent === undefined && !isHiddenLockFile && typeof pkgJsonPath === 'string' && typeof lockName === 'string') {
|
|
3296
|
+
agent = LOCKS[lockName];
|
|
3297
|
+
}
|
|
3298
|
+
if (agent === undefined) {
|
|
3299
|
+
agent = NPM$c;
|
|
3300
|
+
onUnknown?.(pkgManager);
|
|
3301
|
+
}
|
|
3302
|
+
const agentExecPath = await getAgentExecPath(agent);
|
|
3303
|
+
const npmExecPath = agent === NPM$c ? agentExecPath : await getAgentExecPath(NPM$c);
|
|
3304
|
+
if (agentVersion === undefined) {
|
|
3305
|
+
agentVersion = await getAgentVersion(agentExecPath, cwd);
|
|
3306
|
+
}
|
|
3307
|
+
if (agent === YARN_CLASSIC$6 && (agentVersion?.major ?? 0) > 1) {
|
|
3308
|
+
agent = YARN_BERRY$6;
|
|
3309
|
+
}
|
|
3310
|
+
const targets = {
|
|
3311
|
+
browser: false,
|
|
3312
|
+
node: true
|
|
3313
|
+
};
|
|
3314
|
+
let lockSrc;
|
|
3315
|
+
// Lazily access constants.maintainedNodeVersions.
|
|
3316
|
+
let minimumNodeVersion = constants.maintainedNodeVersions.last;
|
|
3317
|
+
if (pkgJson) {
|
|
3318
|
+
const browserField = pkgJson.browser;
|
|
3319
|
+
if (strings.isNonEmptyString(browserField) || objects.isObjectObject(browserField)) {
|
|
3320
|
+
targets.browser = true;
|
|
3321
|
+
}
|
|
3322
|
+
const nodeRange = pkgJson.engines?.['node'];
|
|
3323
|
+
if (strings.isNonEmptyString(nodeRange)) {
|
|
3324
|
+
const coerced = semver.coerce(nodeRange);
|
|
3325
|
+
if (coerced && semver.lt(coerced, minimumNodeVersion)) {
|
|
3326
|
+
minimumNodeVersion = coerced.version;
|
|
3327
|
+
}
|
|
3328
|
+
}
|
|
3329
|
+
const browserslistQuery = pkgJson['browserslist'];
|
|
3330
|
+
if (Array.isArray(browserslistQuery)) {
|
|
3331
|
+
const browserslistTargets = browserslist(browserslistQuery).map(s => s.toLowerCase()).sort(sorts.naturalCompare);
|
|
3332
|
+
const browserslistNodeTargets = browserslistTargets.filter(v => v.startsWith('node ')).map(v => v.slice(5 /*'node '.length*/));
|
|
3333
|
+
if (!targets.browser && browserslistTargets.length) {
|
|
3334
|
+
targets.browser = browserslistTargets.length !== browserslistNodeTargets.length;
|
|
3335
|
+
}
|
|
3336
|
+
if (browserslistNodeTargets.length) {
|
|
3337
|
+
const coerced = semver.coerce(browserslistNodeTargets[0]);
|
|
3338
|
+
if (coerced && semver.lt(coerced, minimumNodeVersion)) {
|
|
3339
|
+
minimumNodeVersion = coerced.version;
|
|
3340
|
+
}
|
|
3341
|
+
}
|
|
3342
|
+
}
|
|
3343
|
+
// Lazily access constants.maintainedNodeVersions.
|
|
3344
|
+
targets.node = constants.maintainedNodeVersions.some(v => semver.satisfies(v, `>=${minimumNodeVersion}`));
|
|
3345
|
+
lockSrc = typeof lockPath === 'string' ? await readLockFileByAgent[agent](lockPath, agentExecPath) : undefined;
|
|
3346
|
+
} else {
|
|
3347
|
+
lockName = undefined;
|
|
3348
|
+
lockPath = undefined;
|
|
3349
|
+
}
|
|
3350
|
+
return {
|
|
3351
|
+
agent,
|
|
3352
|
+
agentExecPath,
|
|
3353
|
+
agentVersion,
|
|
3354
|
+
lockName,
|
|
3355
|
+
lockPath,
|
|
3356
|
+
lockSrc,
|
|
3357
|
+
minimumNodeVersion,
|
|
3358
|
+
npmExecPath,
|
|
3359
|
+
pkgJson: editablePkgJson,
|
|
3360
|
+
pkgPath,
|
|
3361
|
+
supported: targets.browser || targets.node,
|
|
3362
|
+
targets
|
|
3363
|
+
};
|
|
3364
|
+
}
|
|
3365
|
+
|
|
3366
|
+
const {
|
|
3367
|
+
BUN: BUN$5,
|
|
3368
|
+
VLT: VLT$5,
|
|
3369
|
+
YARN_BERRY: YARN_BERRY$5
|
|
3370
|
+
} = constants;
|
|
3371
|
+
const COMMAND_TITLE$2 = 'Socket Optimize';
|
|
3372
|
+
async function detectAndValidatePackageEnvironment(cwd, options) {
|
|
3373
|
+
const {
|
|
3374
|
+
logger,
|
|
3375
|
+
prod
|
|
3376
|
+
} = {
|
|
3377
|
+
__proto__: null,
|
|
3378
|
+
...options
|
|
3379
|
+
};
|
|
3380
|
+
const details = await detectPackageEnvironment({
|
|
3381
|
+
cwd,
|
|
3382
|
+
onUnknown(pkgManager) {
|
|
3383
|
+
logger?.warn(`${COMMAND_TITLE$2}: Unknown package manager${pkgManager ? ` ${pkgManager}` : ''}, defaulting to npm`);
|
|
3384
|
+
}
|
|
3385
|
+
});
|
|
3386
|
+
if (!details.supported) {
|
|
3387
|
+
logger?.fail(`${COMMAND_TITLE$2}: No supported Node or browser range detected`);
|
|
3388
|
+
return;
|
|
3389
|
+
}
|
|
3390
|
+
if (details.agent === VLT$5) {
|
|
3391
|
+
logger?.fail(`${COMMAND_TITLE$2}: ${details.agent} does not support overrides. Soon, though ⚡`);
|
|
3392
|
+
return;
|
|
3393
|
+
}
|
|
3394
|
+
const lockName = details.lockName ?? 'lock file';
|
|
3395
|
+
if (details.lockName === undefined || details.lockSrc === undefined) {
|
|
3396
|
+
logger?.fail(`${COMMAND_TITLE$2}: No ${lockName} found`);
|
|
3397
|
+
return;
|
|
3398
|
+
}
|
|
3399
|
+
if (details.lockSrc.trim() === '') {
|
|
3400
|
+
logger?.fail(`${COMMAND_TITLE$2}: ${lockName} is empty`);
|
|
3401
|
+
return;
|
|
3402
|
+
}
|
|
3403
|
+
if (details.pkgPath === undefined) {
|
|
3404
|
+
logger?.fail(`${COMMAND_TITLE$2}: No package.json found`);
|
|
3405
|
+
return;
|
|
3406
|
+
}
|
|
3407
|
+
if (prod && (details.agent === BUN$5 || details.agent === YARN_BERRY$5)) {
|
|
3408
|
+
logger?.fail(`${COMMAND_TITLE$2}: --prod not supported for ${details.agent}${details.agentVersion ? `@${details.agentVersion.toString()}` : ''}`);
|
|
3409
|
+
return;
|
|
3410
|
+
}
|
|
3411
|
+
if (details.lockPath && path.relative(cwd, details.lockPath).startsWith('.')) {
|
|
3412
|
+
logger?.warn(`${COMMAND_TITLE$2}: Package ${lockName} found at ${details.lockPath}`);
|
|
3413
|
+
}
|
|
3414
|
+
return details;
|
|
3415
|
+
}
|
|
3416
|
+
|
|
3417
|
+
const {
|
|
3418
|
+
NPM: NPM$b,
|
|
3419
|
+
PNPM: PNPM$7
|
|
3420
|
+
} = constants;
|
|
3421
|
+
async function runFix() {
|
|
3422
|
+
// Lazily access constants.spinner.
|
|
3423
|
+
const {
|
|
3424
|
+
spinner
|
|
3425
|
+
} = constants;
|
|
3426
|
+
spinner.start();
|
|
3427
|
+
const cwd = process.cwd();
|
|
3428
|
+
const pkgEnvDetails = await detectAndValidatePackageEnvironment(cwd, {
|
|
3429
|
+
logger: logger.logger
|
|
3430
|
+
});
|
|
3431
|
+
if (!pkgEnvDetails) {
|
|
3432
|
+
spinner.stop();
|
|
3433
|
+
return;
|
|
3434
|
+
}
|
|
3435
|
+
switch (pkgEnvDetails.agent) {
|
|
3436
|
+
case NPM$b:
|
|
3437
|
+
{
|
|
3438
|
+
await npmFix(pkgEnvDetails, cwd);
|
|
3439
|
+
break;
|
|
3440
|
+
}
|
|
3441
|
+
case PNPM$7:
|
|
3442
|
+
{
|
|
3443
|
+
await pnpmFix(pkgEnvDetails, cwd);
|
|
3444
|
+
break;
|
|
3445
|
+
}
|
|
3446
|
+
}
|
|
3447
|
+
spinner.successAndStop('Socket.dev fix successful');
|
|
3448
|
+
}
|
|
3449
|
+
|
|
3450
|
+
const {
|
|
3451
|
+
DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$s
|
|
3452
|
+
} = constants;
|
|
3453
|
+
const config$t = {
|
|
3454
|
+
commandName: 'fix',
|
|
3455
|
+
description: 'Fix "fixable" Socket alerts',
|
|
3456
|
+
hidden: true,
|
|
3457
|
+
flags: {
|
|
3458
|
+
...commonFlags
|
|
3459
|
+
},
|
|
3460
|
+
help: (command, config) => `
|
|
3461
|
+
Usage
|
|
3462
|
+
$ ${command}
|
|
3463
|
+
|
|
3464
|
+
Options
|
|
3465
|
+
${getFlagListOutput(config.flags, 6)}
|
|
3466
|
+
`
|
|
3467
|
+
};
|
|
3468
|
+
const cmdFix = {
|
|
3469
|
+
description: config$t.description,
|
|
3470
|
+
hidden: config$t.hidden,
|
|
3471
|
+
run: run$t
|
|
3472
|
+
};
|
|
3473
|
+
async function run$t(argv, importMeta, {
|
|
3474
|
+
parentName
|
|
3475
|
+
}) {
|
|
3476
|
+
const cli = meowOrExit({
|
|
3477
|
+
argv,
|
|
3478
|
+
config: config$t,
|
|
3479
|
+
importMeta,
|
|
3480
|
+
parentName
|
|
3481
|
+
});
|
|
3482
|
+
if (cli.flags['dryRun']) {
|
|
3483
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$s);
|
|
3484
|
+
return;
|
|
3485
|
+
}
|
|
3486
|
+
await runFix();
|
|
3487
|
+
}
|
|
3488
|
+
|
|
3489
|
+
async function fetchPackageInfo(pkgName, pkgVersion, includeAllIssues) {
|
|
3490
|
+
const socketSdk = await shadowNpmInject.setupSdk(shadowNpmInject.getPublicToken());
|
|
3491
|
+
const result = await handleApiCall(socketSdk.getIssuesByNPMPackage(pkgName, pkgVersion), 'looking up package');
|
|
3492
|
+
const scoreResult = await handleApiCall(socketSdk.getScoreByNPMPackage(pkgName, pkgVersion), 'looking up package score');
|
|
3493
|
+
if (result.success === false) {
|
|
3494
|
+
return handleUnsuccessfulApiResponse('getIssuesByNPMPackage', result);
|
|
3495
|
+
}
|
|
3496
|
+
if (scoreResult.success === false) {
|
|
3497
|
+
return handleUnsuccessfulApiResponse('getScoreByNPMPackage', scoreResult);
|
|
3498
|
+
}
|
|
3499
|
+
const severityCount = shadowNpmInject.getSeverityCount(result.data, includeAllIssues ? undefined : 'high');
|
|
3500
|
+
return {
|
|
3501
|
+
data: result.data,
|
|
3502
|
+
severityCount,
|
|
3503
|
+
score: scoreResult.data
|
|
3504
|
+
};
|
|
3505
|
+
}
|
|
3506
|
+
|
|
3507
|
+
const {
|
|
3508
|
+
NPM: NPM$a
|
|
3509
|
+
} = registryConstants;
|
|
3510
|
+
function formatScore(score) {
|
|
3511
|
+
if (score > 80) {
|
|
3512
|
+
return colors.green(`${score}`);
|
|
3513
|
+
} else if (score < 80 && score > 60) {
|
|
3514
|
+
return colors.yellow(`${score}`);
|
|
3515
|
+
}
|
|
3516
|
+
return colors.red(`${score}`);
|
|
3517
|
+
}
|
|
3518
|
+
function logPackageIssuesDetails(packageData, outputMarkdown) {
|
|
3519
|
+
const issueDetails = packageData.filter(d => d.value?.severity === shadowNpmInject.SEVERITY.critical || d.value?.severity === shadowNpmInject.SEVERITY.high);
|
|
3520
|
+
const uniqueIssueDetails = issueDetails.reduce((acc, issue) => {
|
|
3521
|
+
const {
|
|
3522
|
+
type
|
|
3523
|
+
} = issue;
|
|
3524
|
+
if (type) {
|
|
3525
|
+
const details = acc.get(type);
|
|
3526
|
+
if (details) {
|
|
3527
|
+
details.count += 1;
|
|
3528
|
+
} else {
|
|
3529
|
+
acc.set(type, {
|
|
3530
|
+
label: issue.value?.label ?? '',
|
|
3531
|
+
count: 1
|
|
3532
|
+
});
|
|
3533
|
+
}
|
|
3534
|
+
}
|
|
3535
|
+
return acc;
|
|
3536
|
+
}, new Map());
|
|
3537
|
+
const format = new shadowNpmInject.ColorOrMarkdown(outputMarkdown);
|
|
3538
|
+
for (const [type, details] of uniqueIssueDetails.entries()) {
|
|
3539
|
+
const issueWithLink = format.hyperlink(details.label, shadowNpmInject.getSocketDevAlertUrl(type), {
|
|
3540
|
+
fallbackToUrl: true
|
|
3541
|
+
});
|
|
3542
|
+
if (details.count === 1) {
|
|
3543
|
+
logger.logger.log(`- ${issueWithLink}`);
|
|
3544
|
+
} else {
|
|
3545
|
+
logger.logger.log(`- ${issueWithLink}: ${details.count}`);
|
|
3546
|
+
}
|
|
3547
|
+
}
|
|
3548
|
+
}
|
|
3549
|
+
function logPackageInfo({
|
|
3550
|
+
data,
|
|
3551
|
+
score,
|
|
3552
|
+
severityCount
|
|
3032
3553
|
}, {
|
|
3033
3554
|
name,
|
|
3034
3555
|
outputKind,
|
|
@@ -3040,10 +3561,13 @@ function formatPackageInfo({
|
|
|
3040
3561
|
return;
|
|
3041
3562
|
}
|
|
3042
3563
|
if (outputKind === 'markdown') {
|
|
3043
|
-
logger.logger.log(
|
|
3044
|
-
|
|
3564
|
+
logger.logger.log(commonTags.stripIndents`
|
|
3565
|
+
# Package report for ${pkgName}
|
|
3566
|
+
|
|
3567
|
+
Package report card:
|
|
3568
|
+
`);
|
|
3045
3569
|
} else {
|
|
3046
|
-
logger.logger.log(
|
|
3570
|
+
logger.logger.log(`Package report card for ${pkgName}:`);
|
|
3047
3571
|
}
|
|
3048
3572
|
const scoreResult = {
|
|
3049
3573
|
'Supply Chain Risk': Math.floor(score.supplyChainRisk.score * 100),
|
|
@@ -3052,19 +3576,20 @@ function formatPackageInfo({
|
|
|
3052
3576
|
Vulnerabilities: Math.floor(score.vulnerability.score * 100),
|
|
3053
3577
|
License: Math.floor(score.license.score * 100)
|
|
3054
3578
|
};
|
|
3579
|
+
logger.logger.log('\n');
|
|
3055
3580
|
Object.entries(scoreResult).map(score => logger.logger.log(`- ${score[0]}: ${formatScore(score[1])}`));
|
|
3056
3581
|
logger.logger.log('\n');
|
|
3057
|
-
if (
|
|
3582
|
+
if (objects.hasKeys(severityCount)) {
|
|
3058
3583
|
if (outputKind === 'markdown') {
|
|
3059
3584
|
logger.logger.log('# Issues\n');
|
|
3060
3585
|
}
|
|
3061
|
-
logger.logger.log(`Package has these issues: ${formatSeverityCount(severityCount)}\n`);
|
|
3062
|
-
|
|
3586
|
+
logger.logger.log(`Package has these issues: ${shadowNpmInject.formatSeverityCount(severityCount)}\n`);
|
|
3587
|
+
logPackageIssuesDetails(data, outputKind === 'markdown');
|
|
3063
3588
|
} else {
|
|
3064
3589
|
logger.logger.log('Package has no issues');
|
|
3065
3590
|
}
|
|
3066
|
-
const format = new
|
|
3067
|
-
const url =
|
|
3591
|
+
const format = new shadowNpmInject.ColorOrMarkdown(outputKind === 'markdown');
|
|
3592
|
+
const url = shadowNpmInject.getSocketDevPackageOverviewUrl(NPM$a, pkgName, pkgVersion);
|
|
3068
3593
|
logger.logger.log('\n');
|
|
3069
3594
|
if (pkgVersion === 'latest') {
|
|
3070
3595
|
logger.logger.log(`Detailed info on socket.dev: ${format.hyperlink(`${pkgName}`, url, {
|
|
@@ -3081,44 +3606,6 @@ function formatPackageInfo({
|
|
|
3081
3606
|
logger.logger.log('');
|
|
3082
3607
|
}
|
|
3083
3608
|
}
|
|
3084
|
-
function formatPackageIssuesDetails(packageData, outputMarkdown) {
|
|
3085
|
-
const issueDetails = packageData.filter(d => d.value?.severity === 'high' || d.value?.severity === 'critical');
|
|
3086
|
-
const uniqueIssues = issueDetails.reduce((acc, issue) => {
|
|
3087
|
-
const {
|
|
3088
|
-
type
|
|
3089
|
-
} = issue;
|
|
3090
|
-
if (type) {
|
|
3091
|
-
if (acc[type] === undefined) {
|
|
3092
|
-
acc[type] = {
|
|
3093
|
-
label: issue.value?.label,
|
|
3094
|
-
count: 1
|
|
3095
|
-
};
|
|
3096
|
-
} else {
|
|
3097
|
-
acc[type].count += 1;
|
|
3098
|
-
}
|
|
3099
|
-
}
|
|
3100
|
-
return acc;
|
|
3101
|
-
}, {});
|
|
3102
|
-
const format = new index.ColorOrMarkdown(outputMarkdown);
|
|
3103
|
-
for (const issue of Object.keys(uniqueIssues)) {
|
|
3104
|
-
const issueWithLink = format.hyperlink(`${uniqueIssues[issue]?.label}`, index.getSocketDevAlertUrl(issue), {
|
|
3105
|
-
fallbackToUrl: true
|
|
3106
|
-
});
|
|
3107
|
-
if (uniqueIssues[issue]?.count === 1) {
|
|
3108
|
-
logger.logger.log(`- ${issueWithLink}`);
|
|
3109
|
-
} else {
|
|
3110
|
-
logger.logger.log(`- ${issueWithLink}: ${uniqueIssues[issue]?.count}`);
|
|
3111
|
-
}
|
|
3112
|
-
}
|
|
3113
|
-
}
|
|
3114
|
-
function formatScore(score) {
|
|
3115
|
-
if (score > 80) {
|
|
3116
|
-
return colors.green(`${score}`);
|
|
3117
|
-
} else if (score < 80 && score > 60) {
|
|
3118
|
-
return colors.yellow(`${score}`);
|
|
3119
|
-
}
|
|
3120
|
-
return colors.red(`${score}`);
|
|
3121
|
-
}
|
|
3122
3609
|
|
|
3123
3610
|
async function getPackageInfo({
|
|
3124
3611
|
commandName,
|
|
@@ -3128,15 +3615,21 @@ async function getPackageInfo({
|
|
|
3128
3615
|
pkgVersion,
|
|
3129
3616
|
strict
|
|
3130
3617
|
}) {
|
|
3618
|
+
// Lazily access constants.spinner.
|
|
3619
|
+
const {
|
|
3620
|
+
spinner
|
|
3621
|
+
} = constants;
|
|
3622
|
+
spinner.start(pkgVersion === 'latest' ? `Looking up data for the latest version of ${pkgName}` : `Looking up data for version ${pkgVersion} of ${pkgName}`);
|
|
3131
3623
|
const packageData = await fetchPackageInfo(pkgName, pkgVersion, includeAllIssues);
|
|
3624
|
+
spinner.successAndStop('Data fetched');
|
|
3132
3625
|
if (packageData) {
|
|
3133
|
-
|
|
3626
|
+
logPackageInfo(packageData, {
|
|
3134
3627
|
name: commandName,
|
|
3135
3628
|
outputKind,
|
|
3136
3629
|
pkgName,
|
|
3137
3630
|
pkgVersion
|
|
3138
3631
|
});
|
|
3139
|
-
if (strict &&
|
|
3632
|
+
if (strict && objects.hasKeys(packageData.severityCount)) {
|
|
3140
3633
|
// Let NodeJS exit gracefully but with exit(1)
|
|
3141
3634
|
process$1.exitCode = 1;
|
|
3142
3635
|
}
|
|
@@ -3193,7 +3686,7 @@ async function run$s(argv, importMeta, {
|
|
|
3193
3686
|
// options or missing arguments.
|
|
3194
3687
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
3195
3688
|
process.exitCode = 2;
|
|
3196
|
-
logger.logger.
|
|
3689
|
+
logger.logger.fail(`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
|
|
3197
3690
|
- Expecting a package name ${!rawPkgName ? colors.red('(missing!)') : colors.green('(ok)')}\n
|
|
3198
3691
|
- Can only accept one package at a time ${cli.input.length > 1 ? colors.red('(got ' + cli.input.length + '!)') : colors.green('(ok)')}\n`);
|
|
3199
3692
|
return;
|
|
@@ -3216,18 +3709,18 @@ async function run$s(argv, importMeta, {
|
|
|
3216
3709
|
}
|
|
3217
3710
|
|
|
3218
3711
|
function applyLogin(apiToken, enforcedOrgs, apiBaseUrl, apiProxy) {
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3712
|
+
shadowNpmInject.updateSetting('enforcedOrgs', enforcedOrgs);
|
|
3713
|
+
shadowNpmInject.updateSetting('apiToken', apiToken);
|
|
3714
|
+
shadowNpmInject.updateSetting('apiBaseUrl', apiBaseUrl);
|
|
3715
|
+
shadowNpmInject.updateSetting('apiProxy', apiProxy);
|
|
3223
3716
|
}
|
|
3224
3717
|
|
|
3225
3718
|
const {
|
|
3226
3719
|
SOCKET_PUBLIC_API_TOKEN
|
|
3227
3720
|
} = constants;
|
|
3228
3721
|
async function attemptLogin(apiBaseUrl, apiProxy) {
|
|
3229
|
-
apiBaseUrl ??=
|
|
3230
|
-
apiProxy ??=
|
|
3722
|
+
apiBaseUrl ??= shadowNpmInject.getSetting('apiBaseUrl') ?? undefined;
|
|
3723
|
+
apiProxy ??= shadowNpmInject.getSetting('apiProxy') ?? undefined;
|
|
3231
3724
|
const apiToken = (await prompts.password({
|
|
3232
3725
|
message: `Enter your ${terminalLink('Socket.dev API key', 'https://docs.socket.dev/docs/api-keys')} (leave blank for a public key)`
|
|
3233
3726
|
})) || SOCKET_PUBLIC_API_TOKEN;
|
|
@@ -3238,13 +3731,13 @@ async function attemptLogin(apiBaseUrl, apiProxy) {
|
|
|
3238
3731
|
spinner.start('Verifying API key...');
|
|
3239
3732
|
let orgs;
|
|
3240
3733
|
try {
|
|
3241
|
-
const sdk = await
|
|
3734
|
+
const sdk = await shadowNpmInject.setupSdk(apiToken, apiBaseUrl, apiProxy);
|
|
3242
3735
|
const result = await sdk.getOrganizations();
|
|
3243
3736
|
if (!result.success) {
|
|
3244
|
-
throw new
|
|
3737
|
+
throw new shadowNpmInject.AuthError();
|
|
3245
3738
|
}
|
|
3246
3739
|
orgs = result.data;
|
|
3247
|
-
spinner.
|
|
3740
|
+
spinner.success('API key verified');
|
|
3248
3741
|
} catch {
|
|
3249
3742
|
spinner.errorAndStop('Invalid API key');
|
|
3250
3743
|
return;
|
|
@@ -3282,14 +3775,13 @@ async function attemptLogin(apiBaseUrl, apiProxy) {
|
|
|
3282
3775
|
}
|
|
3283
3776
|
}
|
|
3284
3777
|
}
|
|
3285
|
-
|
|
3778
|
+
spinner.stop();
|
|
3779
|
+
const oldToken = shadowNpmInject.getSetting('apiToken');
|
|
3286
3780
|
try {
|
|
3287
3781
|
applyLogin(apiToken, enforcedOrgs, apiBaseUrl, apiProxy);
|
|
3288
|
-
|
|
3289
|
-
spinner.successAndStop(`API credentials ${oldToken ? 'updated' : 'set'}`);
|
|
3782
|
+
logger.logger.success(`API credentials ${oldToken ? 'updated' : 'set'}`);
|
|
3290
3783
|
} catch {
|
|
3291
|
-
|
|
3292
|
-
spinner.errorAndStop(`API login failed`);
|
|
3784
|
+
logger.logger.fail(`API login failed`);
|
|
3293
3785
|
}
|
|
3294
3786
|
}
|
|
3295
3787
|
|
|
@@ -3339,23 +3831,23 @@ async function run$r(argv, importMeta, {
|
|
|
3339
3831
|
importMeta,
|
|
3340
3832
|
parentName
|
|
3341
3833
|
});
|
|
3342
|
-
|
|
3343
|
-
|
|
3834
|
+
const apiBaseUrl = cli.flags['apiBaseUrl'];
|
|
3835
|
+
const apiProxy = cli.flags['apiProxy'];
|
|
3344
3836
|
if (cli.flags['dryRun']) {
|
|
3345
3837
|
logger.logger.log(DRY_RUN_BAIL_TEXT$q);
|
|
3346
3838
|
return;
|
|
3347
3839
|
}
|
|
3348
3840
|
if (!isInteractive()) {
|
|
3349
|
-
throw new
|
|
3841
|
+
throw new shadowNpmInject.InputError('Cannot prompt for credentials in a non-interactive shell');
|
|
3350
3842
|
}
|
|
3351
3843
|
await attemptLogin(apiBaseUrl, apiProxy);
|
|
3352
3844
|
}
|
|
3353
3845
|
|
|
3354
3846
|
function applyLogout() {
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3847
|
+
shadowNpmInject.updateSetting('apiToken', null);
|
|
3848
|
+
shadowNpmInject.updateSetting('apiBaseUrl', null);
|
|
3849
|
+
shadowNpmInject.updateSetting('apiProxy', null);
|
|
3850
|
+
shadowNpmInject.updateSetting('enforcedOrgs', null);
|
|
3359
3851
|
}
|
|
3360
3852
|
|
|
3361
3853
|
function attemptLogout() {
|
|
@@ -3363,7 +3855,7 @@ function attemptLogout() {
|
|
|
3363
3855
|
applyLogout();
|
|
3364
3856
|
logger.logger.success('Successfully logged out');
|
|
3365
3857
|
} catch {
|
|
3366
|
-
logger.logger.
|
|
3858
|
+
logger.logger.fail('Failed to complete logout steps');
|
|
3367
3859
|
}
|
|
3368
3860
|
}
|
|
3369
3861
|
|
|
@@ -3445,14 +3937,14 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
|
|
|
3445
3937
|
logger.logger.groupEnd();
|
|
3446
3938
|
}
|
|
3447
3939
|
if (output.stderr) {
|
|
3448
|
-
|
|
3940
|
+
process.exitCode = 1;
|
|
3941
|
+
logger.logger.fail('There were errors while running gradle');
|
|
3449
3942
|
// (In verbose mode, stderr was printed above, no need to repeat it)
|
|
3450
3943
|
if (!verbose) {
|
|
3451
3944
|
logger.logger.group('[VERBOSE] stderr:');
|
|
3452
3945
|
logger.logger.error(output.stderr);
|
|
3453
3946
|
logger.logger.groupEnd();
|
|
3454
3947
|
}
|
|
3455
|
-
process.exitCode = 1;
|
|
3456
3948
|
return;
|
|
3457
3949
|
}
|
|
3458
3950
|
logger.logger.success('Executed gradle successfully');
|
|
@@ -3464,7 +3956,7 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
|
|
|
3464
3956
|
|
|
3465
3957
|
// const loc = output.stdout?.match(/Wrote (.*?.pom)\n/)?.[1]?.trim()
|
|
3466
3958
|
// if (!loc) {
|
|
3467
|
-
// logger.
|
|
3959
|
+
// logger.fail(
|
|
3468
3960
|
// 'There were no errors from sbt but could not find the location of resulting .pom file either'
|
|
3469
3961
|
// )
|
|
3470
3962
|
// process.exit(1)
|
|
@@ -3490,15 +3982,14 @@ async function convertGradleToMaven(target, bin, _out, verbose, gradleOpts) {
|
|
|
3490
3982
|
// spinner.successAndStop(`OK. File should be available in \`${out}\``)
|
|
3491
3983
|
// }
|
|
3492
3984
|
} catch (e) {
|
|
3493
|
-
|
|
3985
|
+
process.exitCode = 1;
|
|
3986
|
+
spinner.stop();
|
|
3987
|
+
logger.logger.fail('There was an unexpected error while running this' + (verbose ? '' : ' (use --verbose for details)'));
|
|
3494
3988
|
if (verbose) {
|
|
3495
3989
|
logger.logger.group('[VERBOSE] error:');
|
|
3496
3990
|
logger.logger.log(e);
|
|
3497
3991
|
logger.logger.groupEnd();
|
|
3498
3992
|
}
|
|
3499
|
-
process.exitCode = 1;
|
|
3500
|
-
} finally {
|
|
3501
|
-
spinner.stop();
|
|
3502
3993
|
}
|
|
3503
3994
|
}
|
|
3504
3995
|
|
|
@@ -3608,7 +4099,7 @@ async function run$p(argv, importMeta, {
|
|
|
3608
4099
|
// options or missing arguments.
|
|
3609
4100
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
3610
4101
|
process.exitCode = 2;
|
|
3611
|
-
logger.logger.
|
|
4102
|
+
logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
3612
4103
|
|
|
3613
4104
|
- The DIR arg is required ${!target ? colors.red('(missing!)') : target === '-' ? colors.red('(stdin is not supported)') : colors.green('(ok)')}
|
|
3614
4105
|
|
|
@@ -3684,14 +4175,14 @@ async function convertSbtToMaven(target, bin, out, verbose, sbtOpts) {
|
|
|
3684
4175
|
logger.logger.groupEnd();
|
|
3685
4176
|
}
|
|
3686
4177
|
if (output.stderr) {
|
|
3687
|
-
|
|
4178
|
+
process.exitCode = 1;
|
|
4179
|
+
logger.logger.fail('There were errors while running sbt');
|
|
3688
4180
|
// (In verbose mode, stderr was printed above, no need to repeat it)
|
|
3689
4181
|
if (!verbose) {
|
|
3690
4182
|
logger.logger.group('[VERBOSE] stderr:');
|
|
3691
4183
|
logger.logger.error(output.stderr);
|
|
3692
4184
|
logger.logger.groupEnd();
|
|
3693
4185
|
}
|
|
3694
|
-
process.exitCode = 1;
|
|
3695
4186
|
return;
|
|
3696
4187
|
}
|
|
3697
4188
|
const poms = [];
|
|
@@ -3700,8 +4191,8 @@ async function convertSbtToMaven(target, bin, out, verbose, sbtOpts) {
|
|
|
3700
4191
|
return fn;
|
|
3701
4192
|
});
|
|
3702
4193
|
if (!poms.length) {
|
|
3703
|
-
logger.logger.error('There were no errors from sbt but it seems to not have generated any poms either');
|
|
3704
4194
|
process.exitCode = 1;
|
|
4195
|
+
logger.logger.fail('There were no errors from sbt but it seems to not have generated any poms either');
|
|
3705
4196
|
return;
|
|
3706
4197
|
}
|
|
3707
4198
|
// Move the pom file to ...? initial cwd? loc will be an absolute path, or dump to stdout
|
|
@@ -3709,14 +4200,14 @@ async function convertSbtToMaven(target, bin, out, verbose, sbtOpts) {
|
|
|
3709
4200
|
// TODO: maybe we can add an option to target a specific file to dump to stdout
|
|
3710
4201
|
if (out === '-' && poms.length === 1) {
|
|
3711
4202
|
logger.logger.log('Result:\n```');
|
|
3712
|
-
logger.logger.log(await
|
|
4203
|
+
logger.logger.log(await shadowNpmInject.safeReadFile(poms[0], 'utf8'));
|
|
3713
4204
|
logger.logger.log('```');
|
|
3714
4205
|
logger.logger.success(`OK`);
|
|
3715
4206
|
} else if (out === '-') {
|
|
3716
|
-
|
|
4207
|
+
process.exitCode = 1;
|
|
4208
|
+
logger.logger.fail('Requested out target was stdout but there are multiple generated files');
|
|
3717
4209
|
poms.forEach(fn => logger.logger.error('-', fn));
|
|
3718
4210
|
logger.logger.error('Exiting now...');
|
|
3719
|
-
process.exitCode = 1;
|
|
3720
4211
|
return;
|
|
3721
4212
|
} else {
|
|
3722
4213
|
// if (verbose) {
|
|
@@ -3733,15 +4224,14 @@ async function convertSbtToMaven(target, bin, out, verbose, sbtOpts) {
|
|
|
3733
4224
|
logger.logger.success(`OK`);
|
|
3734
4225
|
}
|
|
3735
4226
|
} catch (e) {
|
|
3736
|
-
|
|
4227
|
+
process.exitCode = 1;
|
|
4228
|
+
spinner.stop();
|
|
4229
|
+
logger.logger.fail('There was an unexpected error while running this' + (verbose ? '' : ' (use --verbose for details)'));
|
|
3737
4230
|
if (verbose) {
|
|
3738
4231
|
logger.logger.group('[VERBOSE] error:');
|
|
3739
4232
|
logger.logger.log(e);
|
|
3740
4233
|
logger.logger.groupEnd();
|
|
3741
4234
|
}
|
|
3742
|
-
process.exitCode = 1;
|
|
3743
|
-
} finally {
|
|
3744
|
-
spinner.stop();
|
|
3745
4235
|
}
|
|
3746
4236
|
}
|
|
3747
4237
|
|
|
@@ -3811,6 +4301,9 @@ const config$o = {
|
|
|
3811
4301
|
|
|
3812
4302
|
Support is beta. Please report issues or give us feedback on what's missing.
|
|
3813
4303
|
|
|
4304
|
+
This is only for SBT. If your Scala setup uses gradle, please see the help
|
|
4305
|
+
sections for \`socket manifest gradle\` or \`socket cdxgen\`.
|
|
4306
|
+
|
|
3814
4307
|
Examples
|
|
3815
4308
|
|
|
3816
4309
|
$ ${command} ./build.sbt
|
|
@@ -3849,7 +4342,7 @@ async function run$o(argv, importMeta, {
|
|
|
3849
4342
|
// options or missing arguments.
|
|
3850
4343
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
3851
4344
|
process.exitCode = 2;
|
|
3852
|
-
logger.logger.
|
|
4345
|
+
logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
3853
4346
|
|
|
3854
4347
|
- The DIR or FILE arg is required ${!target ? colors.red('(missing!)') : target === '-' ? colors.red('(stdin is not supported)') : colors.green('(ok)')}
|
|
3855
4348
|
|
|
@@ -4109,7 +4602,7 @@ async function run$m(argv, importMeta, {
|
|
|
4109
4602
|
// options or missing arguments.
|
|
4110
4603
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
4111
4604
|
process.exitCode = 2;
|
|
4112
|
-
logger.logger.
|
|
4605
|
+
logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
4113
4606
|
|
|
4114
4607
|
- The DIR arg is required ${!target ? colors.red('(missing!)') : target === '-' ? colors.red('(stdin is not supported)') : colors.green('(ok)')}
|
|
4115
4608
|
|
|
@@ -4184,22 +4677,21 @@ async function run$l(argv, importMeta, {
|
|
|
4184
4677
|
}
|
|
4185
4678
|
|
|
4186
4679
|
const {
|
|
4187
|
-
NPM: NPM$
|
|
4188
|
-
SHADOW_BIN: SHADOW_BIN$1
|
|
4680
|
+
NPM: NPM$9
|
|
4189
4681
|
} = constants;
|
|
4190
4682
|
async function wrapNpm(argv) {
|
|
4191
|
-
// Lazily access constants.
|
|
4192
|
-
const shadowBin = require(
|
|
4193
|
-
await shadowBin(NPM$
|
|
4683
|
+
// Lazily access constants.distShadowNpmBinPath.
|
|
4684
|
+
const shadowBin = require(constants.distShadowNpmBinPath);
|
|
4685
|
+
await shadowBin(NPM$9, argv);
|
|
4194
4686
|
}
|
|
4195
4687
|
|
|
4196
4688
|
const {
|
|
4197
4689
|
DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$k,
|
|
4198
|
-
NPM: NPM$
|
|
4690
|
+
NPM: NPM$8
|
|
4199
4691
|
} = constants;
|
|
4200
4692
|
const config$k = {
|
|
4201
4693
|
commandName: 'npm',
|
|
4202
|
-
description: `${NPM$
|
|
4694
|
+
description: `${NPM$8} wrapper functionality`,
|
|
4203
4695
|
hidden: false,
|
|
4204
4696
|
flags: {},
|
|
4205
4697
|
help: (command, _config) => `
|
|
@@ -4230,12 +4722,11 @@ async function run$k(argv, importMeta, {
|
|
|
4230
4722
|
}
|
|
4231
4723
|
|
|
4232
4724
|
const {
|
|
4233
|
-
NPX: NPX$2
|
|
4234
|
-
SHADOW_BIN
|
|
4725
|
+
NPX: NPX$2
|
|
4235
4726
|
} = constants;
|
|
4236
4727
|
async function wrapNpx(argv) {
|
|
4237
|
-
// Lazily access constants.
|
|
4238
|
-
const shadowBin = require(
|
|
4728
|
+
// Lazily access constants.distShadowNpmBinPath.
|
|
4729
|
+
const shadowBin = require(constants.distShadowNpmBinPath);
|
|
4239
4730
|
await shadowBin(NPX$2, argv);
|
|
4240
4731
|
}
|
|
4241
4732
|
|
|
@@ -4298,289 +4789,36 @@ const cmdOops = {
|
|
|
4298
4789
|
run: run$i
|
|
4299
4790
|
};
|
|
4300
4791
|
async function run$i(argv, importMeta, {
|
|
4301
|
-
parentName
|
|
4302
|
-
}) {
|
|
4303
|
-
const cli = meowOrExit({
|
|
4304
|
-
argv,
|
|
4305
|
-
config: config$i,
|
|
4306
|
-
importMeta,
|
|
4307
|
-
parentName
|
|
4308
|
-
});
|
|
4309
|
-
if (cli.flags['dryRun']) {
|
|
4310
|
-
logger.logger.log(DRY_RUN_BAIL_TEXT$i);
|
|
4311
|
-
return;
|
|
4312
|
-
}
|
|
4313
|
-
throw new Error('This error was intentionally left blank');
|
|
4314
|
-
}
|
|
4315
|
-
|
|
4316
|
-
const {
|
|
4317
|
-
BUN: BUN$6,
|
|
4318
|
-
NPM: NPM$9,
|
|
4319
|
-
PNPM: PNPM$7,
|
|
4320
|
-
VLT: VLT$6,
|
|
4321
|
-
YARN_BERRY: YARN_BERRY$6,
|
|
4322
|
-
YARN_CLASSIC: YARN_CLASSIC$6
|
|
4323
|
-
} = constants;
|
|
4324
|
-
function matchHumanStdout(stdout, name) {
|
|
4325
|
-
return stdout.includes(` ${name}@`);
|
|
4326
|
-
}
|
|
4327
|
-
function matchQueryStdout(stdout, name) {
|
|
4328
|
-
return stdout.includes(`"${name}"`);
|
|
4329
|
-
}
|
|
4330
|
-
const depsIncludesByAgent = new Map([[BUN$6, matchHumanStdout], [NPM$9, matchQueryStdout], [PNPM$7, matchQueryStdout], [VLT$6, matchQueryStdout], [YARN_BERRY$6, matchHumanStdout], [YARN_CLASSIC$6, matchHumanStdout]]);
|
|
4331
|
-
|
|
4332
|
-
const {
|
|
4333
|
-
BINARY_LOCK_EXT,
|
|
4334
|
-
BUN: BUN$5,
|
|
4335
|
-
LOCK_EXT: LOCK_EXT$1,
|
|
4336
|
-
NPM: NPM$8,
|
|
4337
|
-
PNPM: PNPM$6,
|
|
4338
|
-
VLT: VLT$5,
|
|
4339
|
-
YARN,
|
|
4340
|
-
YARN_BERRY: YARN_BERRY$5,
|
|
4341
|
-
YARN_CLASSIC: YARN_CLASSIC$5
|
|
4342
|
-
} = constants;
|
|
4343
|
-
const AGENTS = [BUN$5, NPM$8, PNPM$6, YARN_BERRY$5, YARN_CLASSIC$5, VLT$5];
|
|
4344
|
-
const binByAgent = {
|
|
4345
|
-
__proto__: null,
|
|
4346
|
-
[BUN$5]: BUN$5,
|
|
4347
|
-
[NPM$8]: NPM$8,
|
|
4348
|
-
[PNPM$6]: PNPM$6,
|
|
4349
|
-
[YARN_BERRY$5]: YARN,
|
|
4350
|
-
[YARN_CLASSIC$5]: YARN,
|
|
4351
|
-
[VLT$5]: VLT$5
|
|
4352
|
-
};
|
|
4353
|
-
async function getAgentExecPath(agent) {
|
|
4354
|
-
const binName = binByAgent[agent];
|
|
4355
|
-
return (await which(binName, {
|
|
4356
|
-
nothrow: true
|
|
4357
|
-
})) ?? binName;
|
|
4358
|
-
}
|
|
4359
|
-
async function getAgentVersion(agentExecPath, cwd) {
|
|
4360
|
-
let result;
|
|
4361
|
-
try {
|
|
4362
|
-
result = semver.coerce(
|
|
4363
|
-
// All package managers support the "--version" flag.
|
|
4364
|
-
(await spawn.spawn(agentExecPath, ['--version'], {
|
|
4365
|
-
cwd
|
|
4366
|
-
})).stdout) ?? undefined;
|
|
4367
|
-
} catch {}
|
|
4368
|
-
return result;
|
|
4369
|
-
}
|
|
4370
|
-
|
|
4371
|
-
// The order of LOCKS properties IS significant as it affects iteration order.
|
|
4372
|
-
const LOCKS = {
|
|
4373
|
-
[`bun${LOCK_EXT$1}`]: BUN$5,
|
|
4374
|
-
[`bun${BINARY_LOCK_EXT}`]: BUN$5,
|
|
4375
|
-
// If both package-lock.json and npm-shrinkwrap.json are present in the root
|
|
4376
|
-
// of a project, npm-shrinkwrap.json will take precedence and package-lock.json
|
|
4377
|
-
// will be ignored.
|
|
4378
|
-
// https://docs.npmjs.com/cli/v10/configuring-npm/package-lock-json#package-lockjson-vs-npm-shrinkwrapjson
|
|
4379
|
-
'npm-shrinkwrap.json': NPM$8,
|
|
4380
|
-
'package-lock.json': NPM$8,
|
|
4381
|
-
'pnpm-lock.yaml': PNPM$6,
|
|
4382
|
-
'pnpm-lock.yml': PNPM$6,
|
|
4383
|
-
[`yarn${LOCK_EXT$1}`]: YARN_CLASSIC$5,
|
|
4384
|
-
'vlt-lock.json': VLT$5,
|
|
4385
|
-
// Lastly, look for a hidden lock file which is present if .npmrc has package-lock=false:
|
|
4386
|
-
// https://docs.npmjs.com/cli/v10/configuring-npm/package-lock-json#hidden-lockfiles
|
|
4387
|
-
//
|
|
4388
|
-
// Unlike the other LOCKS keys this key contains a directory AND filename so
|
|
4389
|
-
// it has to be handled differently.
|
|
4390
|
-
'node_modules/.package-lock.json': NPM$8
|
|
4391
|
-
};
|
|
4392
|
-
const readLockFileByAgent = (() => {
|
|
4393
|
-
function wrapReader(reader) {
|
|
4394
|
-
return async (...args) => {
|
|
4395
|
-
try {
|
|
4396
|
-
return await reader(...args);
|
|
4397
|
-
} catch {}
|
|
4398
|
-
return undefined;
|
|
4399
|
-
};
|
|
4400
|
-
}
|
|
4401
|
-
const binaryReader = wrapReader(index.readFileBinary);
|
|
4402
|
-
const defaultReader = wrapReader(async lockPath => await index.readFileUtf8(lockPath));
|
|
4403
|
-
return {
|
|
4404
|
-
[BUN$5]: wrapReader(async (lockPath, agentExecPath) => {
|
|
4405
|
-
const ext = path.extname(lockPath);
|
|
4406
|
-
if (ext === LOCK_EXT$1) {
|
|
4407
|
-
return await defaultReader(lockPath);
|
|
4408
|
-
}
|
|
4409
|
-
if (ext === BINARY_LOCK_EXT) {
|
|
4410
|
-
const lockBuffer = await binaryReader(lockPath);
|
|
4411
|
-
if (lockBuffer) {
|
|
4412
|
-
try {
|
|
4413
|
-
return index_cjs.parse(lockBuffer);
|
|
4414
|
-
} catch {}
|
|
4415
|
-
}
|
|
4416
|
-
// To print a Yarn lockfile to your console without writing it to disk
|
|
4417
|
-
// use `bun bun.lockb`.
|
|
4418
|
-
// https://bun.sh/guides/install/yarnlock
|
|
4419
|
-
return (await spawn.spawn(agentExecPath, [lockPath])).stdout.trim();
|
|
4420
|
-
}
|
|
4421
|
-
return undefined;
|
|
4422
|
-
}),
|
|
4423
|
-
[NPM$8]: defaultReader,
|
|
4424
|
-
[PNPM$6]: defaultReader,
|
|
4425
|
-
[VLT$5]: defaultReader,
|
|
4426
|
-
[YARN_BERRY$5]: defaultReader,
|
|
4427
|
-
[YARN_CLASSIC$5]: defaultReader
|
|
4428
|
-
};
|
|
4429
|
-
})();
|
|
4430
|
-
async function detectPackageEnvironment({
|
|
4431
|
-
cwd = process$1.cwd(),
|
|
4432
|
-
onUnknown
|
|
4433
|
-
} = {}) {
|
|
4434
|
-
let lockPath = await index.findUp(Object.keys(LOCKS), {
|
|
4435
|
-
cwd
|
|
4436
|
-
});
|
|
4437
|
-
let lockName = lockPath ? path.basename(lockPath) : undefined;
|
|
4438
|
-
const isHiddenLockFile = lockName === '.package-lock.json';
|
|
4439
|
-
const pkgJsonPath = lockPath ? path.resolve(lockPath, `${isHiddenLockFile ? '../' : ''}../package.json`) : await index.findUp('package.json', {
|
|
4440
|
-
cwd
|
|
4441
|
-
});
|
|
4442
|
-
const pkgPath = pkgJsonPath && fs.existsSync(pkgJsonPath) ? path.dirname(pkgJsonPath) : undefined;
|
|
4443
|
-
const editablePkgJson = pkgPath ? await packages.readPackageJson(pkgPath, {
|
|
4444
|
-
editable: true
|
|
4445
|
-
}) : undefined;
|
|
4446
|
-
const pkgJson = editablePkgJson?.content;
|
|
4447
|
-
// Read Corepack `packageManager` field in package.json:
|
|
4448
|
-
// https://nodejs.org/api/packages.html#packagemanager
|
|
4449
|
-
const pkgManager = strings.isNonEmptyString(pkgJson?.packageManager) ? pkgJson.packageManager : undefined;
|
|
4450
|
-
let agent;
|
|
4451
|
-
let agentVersion;
|
|
4452
|
-
if (pkgManager) {
|
|
4453
|
-
const atSignIndex = pkgManager.lastIndexOf('@');
|
|
4454
|
-
if (atSignIndex !== -1) {
|
|
4455
|
-
const name = pkgManager.slice(0, atSignIndex);
|
|
4456
|
-
const version = pkgManager.slice(atSignIndex + 1);
|
|
4457
|
-
if (version && AGENTS.includes(name)) {
|
|
4458
|
-
agent = name;
|
|
4459
|
-
agentVersion = semver.coerce(version) ?? undefined;
|
|
4460
|
-
}
|
|
4461
|
-
}
|
|
4462
|
-
}
|
|
4463
|
-
if (agent === undefined && !isHiddenLockFile && typeof pkgJsonPath === 'string' && typeof lockName === 'string') {
|
|
4464
|
-
agent = LOCKS[lockName];
|
|
4465
|
-
}
|
|
4466
|
-
if (agent === undefined) {
|
|
4467
|
-
agent = NPM$8;
|
|
4468
|
-
onUnknown?.(pkgManager);
|
|
4469
|
-
}
|
|
4470
|
-
const agentExecPath = await getAgentExecPath(agent);
|
|
4471
|
-
const npmExecPath = agent === NPM$8 ? agentExecPath : await getAgentExecPath(NPM$8);
|
|
4472
|
-
if (agentVersion === undefined) {
|
|
4473
|
-
agentVersion = await getAgentVersion(agentExecPath, cwd);
|
|
4474
|
-
}
|
|
4475
|
-
if (agent === YARN_CLASSIC$5 && (agentVersion?.major ?? 0) > 1) {
|
|
4476
|
-
agent = YARN_BERRY$5;
|
|
4477
|
-
}
|
|
4478
|
-
const targets = {
|
|
4479
|
-
browser: false,
|
|
4480
|
-
node: true
|
|
4481
|
-
};
|
|
4482
|
-
let lockSrc;
|
|
4483
|
-
// Lazily access constants.maintainedNodeVersions.
|
|
4484
|
-
let minimumNodeVersion = constants.maintainedNodeVersions.previous;
|
|
4485
|
-
if (pkgJson) {
|
|
4486
|
-
const browserField = pkgJson.browser;
|
|
4487
|
-
if (strings.isNonEmptyString(browserField) || objects.isObjectObject(browserField)) {
|
|
4488
|
-
targets.browser = true;
|
|
4489
|
-
}
|
|
4490
|
-
const nodeRange = pkgJson.engines?.['node'];
|
|
4491
|
-
if (strings.isNonEmptyString(nodeRange)) {
|
|
4492
|
-
const coerced = semver.coerce(nodeRange);
|
|
4493
|
-
if (coerced && semver.lt(coerced, minimumNodeVersion)) {
|
|
4494
|
-
minimumNodeVersion = coerced.version;
|
|
4495
|
-
}
|
|
4496
|
-
}
|
|
4497
|
-
const browserslistQuery = pkgJson['browserslist'];
|
|
4498
|
-
if (Array.isArray(browserslistQuery)) {
|
|
4499
|
-
const browserslistTargets = browserslist(browserslistQuery).map(s => s.toLowerCase()).sort(sorts.naturalCompare);
|
|
4500
|
-
const browserslistNodeTargets = browserslistTargets.filter(v => v.startsWith('node ')).map(v => v.slice(5 /*'node '.length*/));
|
|
4501
|
-
if (!targets.browser && browserslistTargets.length) {
|
|
4502
|
-
targets.browser = browserslistTargets.length !== browserslistNodeTargets.length;
|
|
4503
|
-
}
|
|
4504
|
-
if (browserslistNodeTargets.length) {
|
|
4505
|
-
const coerced = semver.coerce(browserslistNodeTargets[0]);
|
|
4506
|
-
if (coerced && semver.lt(coerced, minimumNodeVersion)) {
|
|
4507
|
-
minimumNodeVersion = coerced.version;
|
|
4508
|
-
}
|
|
4509
|
-
}
|
|
4510
|
-
}
|
|
4511
|
-
// Lazily access constants.maintainedNodeVersions.
|
|
4512
|
-
targets.node = constants.maintainedNodeVersions.some(v => semver.satisfies(v, `>=${minimumNodeVersion}`));
|
|
4513
|
-
lockSrc = typeof lockPath === 'string' ? await readLockFileByAgent[agent](lockPath, agentExecPath) : undefined;
|
|
4514
|
-
} else {
|
|
4515
|
-
lockName = undefined;
|
|
4516
|
-
lockPath = undefined;
|
|
4792
|
+
parentName
|
|
4793
|
+
}) {
|
|
4794
|
+
const cli = meowOrExit({
|
|
4795
|
+
argv,
|
|
4796
|
+
config: config$i,
|
|
4797
|
+
importMeta,
|
|
4798
|
+
parentName
|
|
4799
|
+
});
|
|
4800
|
+
if (cli.flags['dryRun']) {
|
|
4801
|
+
logger.logger.log(DRY_RUN_BAIL_TEXT$i);
|
|
4802
|
+
return;
|
|
4517
4803
|
}
|
|
4518
|
-
|
|
4519
|
-
agent,
|
|
4520
|
-
agentExecPath,
|
|
4521
|
-
agentVersion,
|
|
4522
|
-
lockName,
|
|
4523
|
-
lockPath,
|
|
4524
|
-
lockSrc,
|
|
4525
|
-
minimumNodeVersion,
|
|
4526
|
-
npmExecPath,
|
|
4527
|
-
pkgJson: editablePkgJson,
|
|
4528
|
-
pkgPath,
|
|
4529
|
-
supported: targets.browser || targets.node,
|
|
4530
|
-
targets
|
|
4531
|
-
};
|
|
4804
|
+
throw new Error('This error was intentionally left blank');
|
|
4532
4805
|
}
|
|
4533
4806
|
|
|
4534
4807
|
const {
|
|
4535
4808
|
BUN: BUN$4,
|
|
4809
|
+
NPM: NPM$7,
|
|
4810
|
+
PNPM: PNPM$6,
|
|
4536
4811
|
VLT: VLT$4,
|
|
4537
|
-
YARN_BERRY: YARN_BERRY$4
|
|
4812
|
+
YARN_BERRY: YARN_BERRY$4,
|
|
4813
|
+
YARN_CLASSIC: YARN_CLASSIC$5
|
|
4538
4814
|
} = constants;
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
const {
|
|
4542
|
-
logger,
|
|
4543
|
-
prod
|
|
4544
|
-
} = {
|
|
4545
|
-
__proto__: null,
|
|
4546
|
-
...options
|
|
4547
|
-
};
|
|
4548
|
-
const details = await detectPackageEnvironment({
|
|
4549
|
-
cwd,
|
|
4550
|
-
onUnknown(pkgManager) {
|
|
4551
|
-
logger?.warn(`⚠️ ${COMMAND_TITLE$2}: Unknown package manager${pkgManager ? ` ${pkgManager}` : ''}, defaulting to npm`);
|
|
4552
|
-
}
|
|
4553
|
-
});
|
|
4554
|
-
if (!details.supported) {
|
|
4555
|
-
logger?.error(`✖️ ${COMMAND_TITLE$2}: No supported Node or browser range detected`);
|
|
4556
|
-
return;
|
|
4557
|
-
}
|
|
4558
|
-
if (details.agent === VLT$4) {
|
|
4559
|
-
logger?.error(`✖️ ${COMMAND_TITLE$2}: ${details.agent} does not support overrides. Soon, though ⚡`);
|
|
4560
|
-
return;
|
|
4561
|
-
}
|
|
4562
|
-
const lockName = details.lockName ?? 'lock file';
|
|
4563
|
-
if (details.lockName === undefined || details.lockSrc === undefined) {
|
|
4564
|
-
logger?.error(`✖️ ${COMMAND_TITLE$2}: No ${lockName} found`);
|
|
4565
|
-
return;
|
|
4566
|
-
}
|
|
4567
|
-
if (details.lockSrc.trim() === '') {
|
|
4568
|
-
logger?.error(`✖️ ${COMMAND_TITLE$2}: ${lockName} is empty`);
|
|
4569
|
-
return;
|
|
4570
|
-
}
|
|
4571
|
-
if (details.pkgPath === undefined) {
|
|
4572
|
-
logger?.error(`✖️ ${COMMAND_TITLE$2}: No package.json found`);
|
|
4573
|
-
return;
|
|
4574
|
-
}
|
|
4575
|
-
if (prod && (details.agent === BUN$4 || details.agent === YARN_BERRY$4)) {
|
|
4576
|
-
logger?.error(`✖️ ${COMMAND_TITLE$2}: --prod not supported for ${details.agent}${details.agentVersion ? `@${details.agentVersion.toString()}` : ''}`);
|
|
4577
|
-
return;
|
|
4578
|
-
}
|
|
4579
|
-
if (details.lockPath && path.relative(cwd, details.lockPath).startsWith('.')) {
|
|
4580
|
-
logger?.warn(`⚠️ ${COMMAND_TITLE$2}: Package ${lockName} found at ${details.lockPath}`);
|
|
4581
|
-
}
|
|
4582
|
-
return details;
|
|
4815
|
+
function matchLsCmdViewHumanStdout(stdout, name) {
|
|
4816
|
+
return stdout.includes(` ${name}@`);
|
|
4583
4817
|
}
|
|
4818
|
+
function matchQueryCmdStdout(stdout, name) {
|
|
4819
|
+
return stdout.includes(`"${name}"`);
|
|
4820
|
+
}
|
|
4821
|
+
const depsIncludesByAgent = new Map([[BUN$4, matchLsCmdViewHumanStdout], [NPM$7, matchQueryCmdStdout], [PNPM$6, matchQueryCmdStdout], [VLT$4, matchQueryCmdStdout], [YARN_BERRY$4, matchLsCmdViewHumanStdout], [YARN_CLASSIC$5, matchLsCmdViewHumanStdout]]);
|
|
4584
4822
|
|
|
4585
4823
|
function getDependencyEntries(pkgJson) {
|
|
4586
4824
|
const {
|
|
@@ -4608,7 +4846,7 @@ function getDependencyEntries(pkgJson) {
|
|
|
4608
4846
|
|
|
4609
4847
|
const {
|
|
4610
4848
|
BUN: BUN$3,
|
|
4611
|
-
NPM: NPM$
|
|
4849
|
+
NPM: NPM$6,
|
|
4612
4850
|
OVERRIDES: OVERRIDES$1,
|
|
4613
4851
|
PNPM: PNPM$5,
|
|
4614
4852
|
RESOLUTIONS: RESOLUTIONS$1,
|
|
@@ -4629,7 +4867,7 @@ function getOverridesDataBun(pkgJson) {
|
|
|
4629
4867
|
function getOverridesDataNpm(pkgJson) {
|
|
4630
4868
|
const overrides = pkgJson?.[OVERRIDES$1] ?? {};
|
|
4631
4869
|
return {
|
|
4632
|
-
type: NPM$
|
|
4870
|
+
type: NPM$6,
|
|
4633
4871
|
overrides
|
|
4634
4872
|
};
|
|
4635
4873
|
}
|
|
@@ -4670,7 +4908,7 @@ function getOverridesDataClassic(pkgJson) {
|
|
|
4670
4908
|
overrides
|
|
4671
4909
|
};
|
|
4672
4910
|
}
|
|
4673
|
-
const overridesDataByAgent = new Map([[BUN$3, getOverridesDataBun], [NPM$
|
|
4911
|
+
const overridesDataByAgent = new Map([[BUN$3, getOverridesDataBun], [NPM$6, getOverridesDataNpm], [PNPM$5, getOverridesDataPnpm], [VLT$3, getOverridesDataVlt], [YARN_BERRY$3, getOverridesDataYarn], [YARN_CLASSIC$4, getOverridesDataClassic]]);
|
|
4674
4912
|
|
|
4675
4913
|
const {
|
|
4676
4914
|
PNPM: PNPM$4
|
|
@@ -4681,7 +4919,7 @@ async function getWorkspaceGlobs(agent, pkgPath, pkgJson) {
|
|
|
4681
4919
|
if (agent === PNPM$4) {
|
|
4682
4920
|
for (const workspacePath of [path.join(pkgPath, `${PNPM_WORKSPACE}.yaml`), path.join(pkgPath, `${PNPM_WORKSPACE}.yml`)]) {
|
|
4683
4921
|
// eslint-disable-next-line no-await-in-loop
|
|
4684
|
-
const yml = await
|
|
4922
|
+
const yml = await shadowNpmInject.safeReadFile(workspacePath, 'utf8');
|
|
4685
4923
|
if (yml) {
|
|
4686
4924
|
try {
|
|
4687
4925
|
workspacePatterns = yaml.parse(yml)?.packages;
|
|
@@ -4718,26 +4956,26 @@ function workspacePatternToGlobPattern(workspace) {
|
|
|
4718
4956
|
const {
|
|
4719
4957
|
BUN: BUN$2,
|
|
4720
4958
|
LOCK_EXT,
|
|
4721
|
-
NPM: NPM$
|
|
4959
|
+
NPM: NPM$5,
|
|
4722
4960
|
PNPM: PNPM$3,
|
|
4723
4961
|
VLT: VLT$2,
|
|
4724
4962
|
YARN_BERRY: YARN_BERRY$2,
|
|
4725
4963
|
YARN_CLASSIC: YARN_CLASSIC$3
|
|
4726
4964
|
} = constants;
|
|
4727
|
-
function
|
|
4965
|
+
function includesNpm(lockSrc, name) {
|
|
4728
4966
|
// Detects the package name in the following cases:
|
|
4729
4967
|
// "name":
|
|
4730
4968
|
return lockSrc.includes(`"${name}":`);
|
|
4731
4969
|
}
|
|
4732
|
-
function
|
|
4970
|
+
function includesBun(lockSrc, name, lockName) {
|
|
4733
4971
|
// This is a bit counterintuitive. When lockName ends with a .lockb
|
|
4734
4972
|
// we treat it as a yarn.lock. When lockName ends with a .lock we
|
|
4735
4973
|
// treat it as a package-lock.json. The bun.lock format is not identical
|
|
4736
4974
|
// package-lock.json, however it close enough for npmLockIncludes to work.
|
|
4737
|
-
const
|
|
4738
|
-
return
|
|
4975
|
+
const lockfileScanner = lockName?.endsWith(LOCK_EXT) ? includesNpm : includesYarn;
|
|
4976
|
+
return lockfileScanner(lockSrc, name);
|
|
4739
4977
|
}
|
|
4740
|
-
function
|
|
4978
|
+
function includesPnpm(lockSrc, name) {
|
|
4741
4979
|
const escapedName = regexps.escapeRegExp(name);
|
|
4742
4980
|
return new RegExp(
|
|
4743
4981
|
// Detects the package name in the following cases:
|
|
@@ -4747,12 +4985,12 @@ function lockIncludesPnpm(lockSrc, name) {
|
|
|
4747
4985
|
// name@
|
|
4748
4986
|
`(?<=^\\s*)(?:(['/])${escapedName}\\1|${escapedName}(?=[:@]))`, 'm').test(lockSrc);
|
|
4749
4987
|
}
|
|
4750
|
-
function
|
|
4988
|
+
function includesVlt(lockSrc, name) {
|
|
4751
4989
|
// Detects the package name in the following cases:
|
|
4752
4990
|
// "name"
|
|
4753
4991
|
return lockSrc.includes(`"${name}"`);
|
|
4754
4992
|
}
|
|
4755
|
-
function
|
|
4993
|
+
function includesYarn(lockSrc, name) {
|
|
4756
4994
|
const escapedName = regexps.escapeRegExp(name);
|
|
4757
4995
|
return new RegExp(
|
|
4758
4996
|
// Detects the package name in the following cases:
|
|
@@ -4762,11 +5000,11 @@ function lockIncludesYarn(lockSrc, name) {
|
|
|
4762
5000
|
// , name@
|
|
4763
5001
|
`(?<=(?:^\\s*|,\\s*)"?)${escapedName}(?=@)`, 'm').test(lockSrc);
|
|
4764
5002
|
}
|
|
4765
|
-
const
|
|
5003
|
+
const lockfileIncludesByAgent = new Map([[BUN$2, includesBun], [NPM$5, includesNpm], [PNPM$3, includesPnpm], [VLT$2, includesVlt], [YARN_BERRY$2, includesYarn], [YARN_CLASSIC$3, includesYarn]]);
|
|
4766
5004
|
|
|
4767
5005
|
const {
|
|
4768
5006
|
BUN: BUN$1,
|
|
4769
|
-
NPM: NPM$
|
|
5007
|
+
NPM: NPM$4,
|
|
4770
5008
|
PNPM: PNPM$2,
|
|
4771
5009
|
VLT: VLT$1,
|
|
4772
5010
|
YARN_BERRY: YARN_BERRY$1,
|
|
@@ -4802,11 +5040,11 @@ function cleanupQueryStdout(stdout) {
|
|
|
4802
5040
|
}
|
|
4803
5041
|
return JSON.stringify([...names], null, 2);
|
|
4804
5042
|
}
|
|
4805
|
-
function
|
|
5043
|
+
function parsableToQueryStdout(stdout) {
|
|
4806
5044
|
if (stdout === '') {
|
|
4807
5045
|
return '';
|
|
4808
5046
|
}
|
|
4809
|
-
// Convert the
|
|
5047
|
+
// Convert the parsable stdout into a json array of unique names.
|
|
4810
5048
|
// The matchAll regexp looks for a forward (posix) or backward (win32) slash
|
|
4811
5049
|
// and matches one or more non-slashes until the newline.
|
|
4812
5050
|
const names = new Set(stdout.matchAll(/(?<=[/\\])[^/\\]+(?=\n)/g));
|
|
@@ -4836,7 +5074,7 @@ async function lsNpm(agentExecPath, cwd) {
|
|
|
4836
5074
|
}
|
|
4837
5075
|
async function lsPnpm(agentExecPath, cwd, options) {
|
|
4838
5076
|
const npmExecPath = options?.npmExecPath;
|
|
4839
|
-
if (npmExecPath && npmExecPath !== NPM$
|
|
5077
|
+
if (npmExecPath && npmExecPath !== NPM$4) {
|
|
4840
5078
|
const result = await npmQuery(npmExecPath, cwd);
|
|
4841
5079
|
if (result) {
|
|
4842
5080
|
return result;
|
|
@@ -4844,15 +5082,19 @@ async function lsPnpm(agentExecPath, cwd, options) {
|
|
|
4844
5082
|
}
|
|
4845
5083
|
let stdout = '';
|
|
4846
5084
|
try {
|
|
4847
|
-
stdout = (await spawn.spawn(agentExecPath,
|
|
5085
|
+
stdout = (await spawn.spawn(agentExecPath,
|
|
5086
|
+
// Pnpm uses the alternative spelling of parsable.
|
|
5087
|
+
// https://en.wiktionary.org/wiki/parsable
|
|
5088
|
+
['ls', '--parseable', '--prod', '--depth', 'Infinity'], {
|
|
4848
5089
|
cwd
|
|
4849
5090
|
})).stdout;
|
|
4850
5091
|
} catch {}
|
|
4851
|
-
return
|
|
5092
|
+
return parsableToQueryStdout(stdout);
|
|
4852
5093
|
}
|
|
4853
5094
|
async function lsVlt(agentExecPath, cwd) {
|
|
4854
5095
|
let stdout = '';
|
|
4855
5096
|
try {
|
|
5097
|
+
// See https://docs.vlt.sh/cli/commands/list#options.
|
|
4856
5098
|
stdout = (await spawn.spawn(agentExecPath, ['ls', '--view', 'human', ':not(.dev)'], {
|
|
4857
5099
|
cwd
|
|
4858
5100
|
})).stdout;
|
|
@@ -4883,20 +5125,39 @@ async function lsYarnClassic(agentExecPath, cwd) {
|
|
|
4883
5125
|
} catch {}
|
|
4884
5126
|
return '';
|
|
4885
5127
|
}
|
|
4886
|
-
const lsByAgent =
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
5128
|
+
const lsByAgent = new Map([[BUN$1, lsBun], [NPM$4, lsNpm], [PNPM$2, lsPnpm], [VLT$1, lsVlt], [YARN_BERRY$1, lsYarnBerry], [YARN_CLASSIC$2, lsYarnClassic]]);
|
|
5129
|
+
|
|
5130
|
+
const {
|
|
5131
|
+
NPM: NPM$3
|
|
5132
|
+
} = constants;
|
|
5133
|
+
const COMMAND_TITLE$1 = 'Socket Optimize';
|
|
5134
|
+
async function updateLockfile(pkgEnvDetails, options) {
|
|
5135
|
+
const {
|
|
5136
|
+
logger,
|
|
5137
|
+
spinner
|
|
5138
|
+
} = {
|
|
5139
|
+
__proto__: null,
|
|
5140
|
+
...options
|
|
5141
|
+
};
|
|
5142
|
+
spinner?.start(`Updating ${pkgEnvDetails.lockName}...`);
|
|
5143
|
+
try {
|
|
5144
|
+
await runAgentInstall(pkgEnvDetails, {
|
|
5145
|
+
spinner
|
|
5146
|
+
});
|
|
5147
|
+
spinner?.stop();
|
|
5148
|
+
if (pkgEnvDetails.agent === NPM$3) {
|
|
5149
|
+
logger?.log(`💡 Re-run ${COMMAND_TITLE$1} whenever ${pkgEnvDetails.lockName} changes.\n This can be skipped once npm v11.2.0 is released.`);
|
|
5150
|
+
}
|
|
5151
|
+
} catch (e) {
|
|
5152
|
+
spinner?.stop();
|
|
5153
|
+
logger?.fail(`${COMMAND_TITLE$1}: ${pkgEnvDetails.agent} install failed to update ${pkgEnvDetails.lockName}`);
|
|
5154
|
+
logger?.error(e);
|
|
5155
|
+
}
|
|
5156
|
+
}
|
|
4896
5157
|
|
|
4897
5158
|
const {
|
|
4898
5159
|
BUN,
|
|
4899
|
-
NPM: NPM$
|
|
5160
|
+
NPM: NPM$2,
|
|
4900
5161
|
OVERRIDES,
|
|
4901
5162
|
PNPM: PNPM$1,
|
|
4902
5163
|
RESOLUTIONS,
|
|
@@ -4916,7 +5177,9 @@ function getHighestEntryIndex(entries, keys) {
|
|
|
4916
5177
|
return getEntryIndexes(entries, keys).at(-1) ?? -1;
|
|
4917
5178
|
}
|
|
4918
5179
|
function updatePkgJson(editablePkgJson, field, value) {
|
|
4919
|
-
const
|
|
5180
|
+
const {
|
|
5181
|
+
content: pkgJson
|
|
5182
|
+
} = editablePkgJson;
|
|
4920
5183
|
const oldValue = pkgJson[field];
|
|
4921
5184
|
if (oldValue) {
|
|
4922
5185
|
// The field already exists so we simply update the field value.
|
|
@@ -4972,205 +5235,43 @@ function updatePkgJson(editablePkgJson, field, value) {
|
|
|
4972
5235
|
} else if (field === PNPM_FIELD_NAME) {
|
|
4973
5236
|
insertIndex = getLowestEntryIndex(entries, [OVERRIDES, RESOLUTIONS]);
|
|
4974
5237
|
if (insertIndex === -1) {
|
|
4975
|
-
isPlacingHigher = true;
|
|
4976
|
-
insertIndex = getHighestEntryIndex(entries, depFields);
|
|
4977
|
-
}
|
|
4978
|
-
}
|
|
4979
|
-
if (insertIndex === -1) {
|
|
4980
|
-
insertIndex = getLowestEntryIndex(entries, ['engines', 'files']);
|
|
4981
|
-
}
|
|
4982
|
-
if (insertIndex === -1) {
|
|
4983
|
-
isPlacingHigher = true;
|
|
4984
|
-
insertIndex = getHighestEntryIndex(entries, ['exports', 'imports', 'main']);
|
|
4985
|
-
}
|
|
4986
|
-
if (insertIndex === -1) {
|
|
4987
|
-
insertIndex = entries.length;
|
|
4988
|
-
} else if (isPlacingHigher) {
|
|
4989
|
-
insertIndex += 1;
|
|
4990
|
-
}
|
|
4991
|
-
entries.splice(insertIndex, 0, [field, value]);
|
|
4992
|
-
editablePkgJson.fromJSON(`${JSON.stringify(Object.fromEntries(entries), null, 2)}\n`);
|
|
4993
|
-
}
|
|
4994
|
-
function updateOverrides(editablePkgJson, overrides) {
|
|
4995
|
-
updatePkgJson(editablePkgJson, OVERRIDES, overrides);
|
|
4996
|
-
}
|
|
4997
|
-
function updateResolutions(editablePkgJson, overrides) {
|
|
4998
|
-
updatePkgJson(editablePkgJson, RESOLUTIONS, overrides);
|
|
4999
|
-
}
|
|
5000
|
-
function pnpmUpdatePkgJson(editablePkgJson, overrides) {
|
|
5001
|
-
updatePkgJson(editablePkgJson, PNPM_FIELD_NAME, overrides);
|
|
5002
|
-
}
|
|
5003
|
-
const updateManifestByAgent = new Map([[BUN, updateResolutions], [NPM$4, updateOverrides], [PNPM$1, pnpmUpdatePkgJson], [VLT, updateOverrides], [YARN_BERRY, updateResolutions], [YARN_CLASSIC$1, updateResolutions]]);
|
|
5004
|
-
|
|
5005
|
-
const {
|
|
5006
|
-
SOCKET_IPC_HANDSHAKE
|
|
5007
|
-
} = constants;
|
|
5008
|
-
function safeNpmInstall(options) {
|
|
5009
|
-
const {
|
|
5010
|
-
args = [],
|
|
5011
|
-
ipc,
|
|
5012
|
-
spinner,
|
|
5013
|
-
...spawnOptions
|
|
5014
|
-
} = {
|
|
5015
|
-
__proto__: null,
|
|
5016
|
-
...options
|
|
5017
|
-
};
|
|
5018
|
-
const terminatorPos = args.indexOf('--');
|
|
5019
|
-
const npmArgs = (terminatorPos === -1 ? args : args.slice(0, terminatorPos)).filter(a => !npm.isAuditFlag(a) && !npm.isFundFlag(a) && !npm.isProgressFlag(a));
|
|
5020
|
-
const otherArgs = terminatorPos === -1 ? [] : args.slice(terminatorPos);
|
|
5021
|
-
const useIpc = objects.isObject(ipc);
|
|
5022
|
-
const useDebug = debug.isDebug();
|
|
5023
|
-
const isSilent = !useDebug && !npmArgs.some(npm.isLoglevelFlag);
|
|
5024
|
-
const spawnPromise = spawn.spawn(
|
|
5025
|
-
// Lazily access constants.execPath.
|
|
5026
|
-
constants.execPath, [
|
|
5027
|
-
// Lazily access constants.nodeNoWarningsFlags.
|
|
5028
|
-
...constants.nodeNoWarningsFlags, '--require',
|
|
5029
|
-
// Lazily access constants.npmInjectionPath.
|
|
5030
|
-
constants.npmInjectionPath, npmPaths.getNpmBinPath(), 'install',
|
|
5031
|
-
// Even though the '--silent' flag is passed npm will still run through
|
|
5032
|
-
// code paths for 'audit' and 'fund' unless '--no-audit' and '--no-fund'
|
|
5033
|
-
// flags are passed.
|
|
5034
|
-
'--no-audit', '--no-fund',
|
|
5035
|
-
// Add `--no-progress` and `--silent` flags to fix input being swallowed
|
|
5036
|
-
// by the spinner when running the command with recent versions of npm.
|
|
5037
|
-
'--no-progress',
|
|
5038
|
-
// Add the '--silent' flag if a loglevel flag is not provided and the
|
|
5039
|
-
// SOCKET_CLI_DEBUG environment variable is not truthy.
|
|
5040
|
-
...(isSilent ? ['--silent'] : []), ...npmArgs, ...otherArgs], {
|
|
5041
|
-
spinner,
|
|
5042
|
-
// Set stdio to include 'ipc'.
|
|
5043
|
-
// See https://github.com/nodejs/node/blob/v23.6.0/lib/child_process.js#L161-L166
|
|
5044
|
-
// and https://github.com/nodejs/node/blob/v23.6.0/lib/internal/child_process.js#L238.
|
|
5045
|
-
stdio: isSilent ?
|
|
5046
|
-
// 'ignore'
|
|
5047
|
-
useIpc ? ['ignore', 'ignore', 'ignore', 'ipc'] : 'ignore' :
|
|
5048
|
-
// 'inherit'
|
|
5049
|
-
useIpc ? [0, 1, 2, 'ipc'] : 'inherit',
|
|
5050
|
-
...spawnOptions,
|
|
5051
|
-
env: {
|
|
5052
|
-
...process$1.env,
|
|
5053
|
-
...spawnOptions.env
|
|
5054
|
-
}
|
|
5055
|
-
});
|
|
5056
|
-
if (useIpc) {
|
|
5057
|
-
spawnPromise.process.send({
|
|
5058
|
-
[SOCKET_IPC_HANDSHAKE]: ipc
|
|
5059
|
-
});
|
|
5060
|
-
}
|
|
5061
|
-
return spawnPromise;
|
|
5062
|
-
}
|
|
5063
|
-
|
|
5064
|
-
const {
|
|
5065
|
-
NPM: NPM$3,
|
|
5066
|
-
abortSignal
|
|
5067
|
-
} = constants;
|
|
5068
|
-
function runAgentInstall(agent, agentExecPath, options) {
|
|
5069
|
-
// All package managers support the "install" command.
|
|
5070
|
-
if (agent === NPM$3) {
|
|
5071
|
-
return safeNpmInstall(options);
|
|
5072
|
-
}
|
|
5073
|
-
const {
|
|
5074
|
-
args = [],
|
|
5075
|
-
spinner,
|
|
5076
|
-
...spawnOptions
|
|
5077
|
-
} = {
|
|
5078
|
-
__proto__: null,
|
|
5079
|
-
...options
|
|
5080
|
-
};
|
|
5081
|
-
const isSilent = !debug.isDebug();
|
|
5082
|
-
return spawn.spawn(agentExecPath, ['install', ...args], {
|
|
5083
|
-
signal: abortSignal,
|
|
5084
|
-
spinner,
|
|
5085
|
-
stdio: isSilent ? 'ignore' : 'inherit',
|
|
5086
|
-
...spawnOptions,
|
|
5087
|
-
env: {
|
|
5088
|
-
...process.env,
|
|
5089
|
-
...spawnOptions.env
|
|
5090
|
-
}
|
|
5091
|
-
});
|
|
5092
|
-
}
|
|
5093
|
-
|
|
5094
|
-
const {
|
|
5095
|
-
NPM: NPM$2
|
|
5096
|
-
} = constants;
|
|
5097
|
-
const COMMAND_TITLE$1 = 'Socket Optimize';
|
|
5098
|
-
async function updatePackageLockJson(pkgEnvDetails, options) {
|
|
5099
|
-
const {
|
|
5100
|
-
logger,
|
|
5101
|
-
spinner
|
|
5102
|
-
} = {
|
|
5103
|
-
__proto__: null,
|
|
5104
|
-
...options
|
|
5105
|
-
};
|
|
5106
|
-
spinner?.start(`Updating ${pkgEnvDetails.lockName}...`);
|
|
5107
|
-
try {
|
|
5108
|
-
await runAgentInstall(pkgEnvDetails.agent, pkgEnvDetails.agentExecPath, {
|
|
5109
|
-
spinner
|
|
5110
|
-
});
|
|
5111
|
-
spinner?.stop();
|
|
5112
|
-
if (pkgEnvDetails.agent === NPM$2) {
|
|
5113
|
-
logger?.log(`💡 Re-run ${COMMAND_TITLE$1} whenever ${pkgEnvDetails.lockName} changes.\n This can be skipped once npm v11.2.0 is released.`);
|
|
5114
|
-
}
|
|
5115
|
-
} catch (e) {
|
|
5116
|
-
spinner?.stop();
|
|
5117
|
-
logger?.error(`${COMMAND_TITLE$1}: ${pkgEnvDetails.agent} install failed to update ${pkgEnvDetails.lockName}`);
|
|
5118
|
-
logger?.error(e);
|
|
5119
|
-
}
|
|
5120
|
-
}
|
|
5121
|
-
|
|
5122
|
-
const {
|
|
5123
|
-
NPM: NPM$1,
|
|
5124
|
-
PNPM,
|
|
5125
|
-
YARN_CLASSIC
|
|
5126
|
-
} = constants;
|
|
5127
|
-
const COMMAND_TITLE = 'Socket Optimize';
|
|
5128
|
-
const manifestNpmOverrides = registry.getManifestData(NPM$1);
|
|
5129
|
-
async function applyOptimization(cwd, pin, prod) {
|
|
5130
|
-
const pkgEnvDetails = await detectAndValidatePackageEnvironment(cwd, {
|
|
5131
|
-
logger: logger.logger,
|
|
5132
|
-
prod
|
|
5133
|
-
});
|
|
5134
|
-
if (!pkgEnvDetails) {
|
|
5135
|
-
return;
|
|
5136
|
-
}
|
|
5137
|
-
// Lazily access constants.spinner.
|
|
5138
|
-
const {
|
|
5139
|
-
spinner
|
|
5140
|
-
} = constants;
|
|
5141
|
-
spinner.start('Socket optimizing...');
|
|
5142
|
-
const state = await addOverrides(pkgEnvDetails.pkgPath, pkgEnvDetails, {
|
|
5143
|
-
logger: logger.logger,
|
|
5144
|
-
pin,
|
|
5145
|
-
prod,
|
|
5146
|
-
spinner
|
|
5147
|
-
});
|
|
5148
|
-
spinner.stop();
|
|
5149
|
-
const addedCount = state.added.size;
|
|
5150
|
-
const updatedCount = state.updated.size;
|
|
5151
|
-
const pkgJsonChanged = addedCount > 0 || updatedCount > 0;
|
|
5152
|
-
if (pkgJsonChanged) {
|
|
5153
|
-
if (updatedCount > 0) {
|
|
5154
|
-
logger.logger?.log(`${createActionMessage('Updated', updatedCount, state.updatedInWorkspaces.size)}${addedCount ? '.' : '🚀'}`);
|
|
5155
|
-
}
|
|
5156
|
-
if (addedCount > 0) {
|
|
5157
|
-
logger.logger?.log(`${createActionMessage('Added', addedCount, state.addedInWorkspaces.size)} 🚀`);
|
|
5238
|
+
isPlacingHigher = true;
|
|
5239
|
+
insertIndex = getHighestEntryIndex(entries, depFields);
|
|
5158
5240
|
}
|
|
5159
|
-
} else {
|
|
5160
|
-
logger.logger?.log('Congratulations! Already Socket.dev optimized 🎉');
|
|
5161
5241
|
}
|
|
5162
|
-
if (
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
});
|
|
5242
|
+
if (insertIndex === -1) {
|
|
5243
|
+
insertIndex = getLowestEntryIndex(entries, ['engines', 'files']);
|
|
5244
|
+
}
|
|
5245
|
+
if (insertIndex === -1) {
|
|
5246
|
+
isPlacingHigher = true;
|
|
5247
|
+
insertIndex = getHighestEntryIndex(entries, ['exports', 'imports', 'main']);
|
|
5169
5248
|
}
|
|
5249
|
+
if (insertIndex === -1) {
|
|
5250
|
+
insertIndex = entries.length;
|
|
5251
|
+
} else if (isPlacingHigher) {
|
|
5252
|
+
insertIndex += 1;
|
|
5253
|
+
}
|
|
5254
|
+
entries.splice(insertIndex, 0, [field, value]);
|
|
5255
|
+
editablePkgJson.fromJSON(`${JSON.stringify(Object.fromEntries(entries), null, 2)}\n`);
|
|
5170
5256
|
}
|
|
5171
|
-
function
|
|
5172
|
-
|
|
5257
|
+
function updateOverrides(editablePkgJson, overrides) {
|
|
5258
|
+
updatePkgJson(editablePkgJson, OVERRIDES, overrides);
|
|
5259
|
+
}
|
|
5260
|
+
function updateResolutions(editablePkgJson, overrides) {
|
|
5261
|
+
updatePkgJson(editablePkgJson, RESOLUTIONS, overrides);
|
|
5262
|
+
}
|
|
5263
|
+
function pnpmUpdatePkgJson(editablePkgJson, overrides) {
|
|
5264
|
+
updatePkgJson(editablePkgJson, PNPM_FIELD_NAME, overrides);
|
|
5173
5265
|
}
|
|
5266
|
+
const updateManifestByAgent = new Map([[BUN, updateResolutions], [NPM$2, updateOverrides], [PNPM$1, pnpmUpdatePkgJson], [VLT, updateOverrides], [YARN_BERRY, updateResolutions], [YARN_CLASSIC$1, updateResolutions]]);
|
|
5267
|
+
|
|
5268
|
+
const {
|
|
5269
|
+
NPM: NPM$1,
|
|
5270
|
+
PNPM,
|
|
5271
|
+
YARN_CLASSIC
|
|
5272
|
+
} = constants;
|
|
5273
|
+
const COMMAND_TITLE = 'Socket Optimize';
|
|
5274
|
+
const manifestNpmOverrides = registry.getManifestData(NPM$1);
|
|
5174
5275
|
async function addOverrides(pkgPath, pkgEnvDetails, options) {
|
|
5175
5276
|
const {
|
|
5176
5277
|
agent,
|
|
@@ -5214,16 +5315,16 @@ async function addOverrides(pkgPath, pkgEnvDetails, options) {
|
|
|
5214
5315
|
const isWorkspace = !!workspaceGlobs;
|
|
5215
5316
|
if (isWorkspace && agent === PNPM && npmExecPath === NPM$1 && !state.warnedPnpmWorkspaceRequiresNpm) {
|
|
5216
5317
|
state.warnedPnpmWorkspaceRequiresNpm = true;
|
|
5217
|
-
logger?.warn(
|
|
5318
|
+
logger?.warn(`${COMMAND_TITLE}: pnpm workspace support requires \`npm ls\`, falling back to \`pnpm list\``);
|
|
5218
5319
|
}
|
|
5219
|
-
const thingToScan = isLockScanned ? lockSrc : await lsByAgent
|
|
5320
|
+
const thingToScan = isLockScanned ? lockSrc : await lsByAgent.get(agent)(agentExecPath, pkgPath, {
|
|
5220
5321
|
npmExecPath
|
|
5221
5322
|
});
|
|
5222
5323
|
// The AgentDepsIncludesFn and AgentLockIncludesFn types overlap in their
|
|
5223
5324
|
// first two parameters. AgentLockIncludesFn accepts an optional third
|
|
5224
5325
|
// parameter which AgentDepsIncludesFn will ignore so we cast thingScanner
|
|
5225
5326
|
// as an AgentLockIncludesFn type.
|
|
5226
|
-
const thingScanner = isLockScanned ?
|
|
5327
|
+
const thingScanner = isLockScanned ? lockfileIncludesByAgent.get(agent) : depsIncludesByAgent.get(agent);
|
|
5227
5328
|
const depEntries = getDependencyEntries(pkgJson);
|
|
5228
5329
|
const overridesDataObjects = [];
|
|
5229
5330
|
if (pkgJson['private'] || isWorkspace) {
|
|
@@ -5349,6 +5450,51 @@ async function addOverrides(pkgPath, pkgEnvDetails, options) {
|
|
|
5349
5450
|
}
|
|
5350
5451
|
return state;
|
|
5351
5452
|
}
|
|
5453
|
+
function createActionMessage(verb, overrideCount, workspaceCount) {
|
|
5454
|
+
return `${verb} ${overrideCount} Socket.dev optimized ${words.pluralize('override', overrideCount)}${workspaceCount ? ` in ${workspaceCount} ${words.pluralize('workspace', workspaceCount)}` : ''}`;
|
|
5455
|
+
}
|
|
5456
|
+
async function applyOptimization(cwd, pin, prod) {
|
|
5457
|
+
const pkgEnvDetails = await detectAndValidatePackageEnvironment(cwd, {
|
|
5458
|
+
logger: logger.logger,
|
|
5459
|
+
prod
|
|
5460
|
+
});
|
|
5461
|
+
if (!pkgEnvDetails) {
|
|
5462
|
+
return;
|
|
5463
|
+
}
|
|
5464
|
+
// Lazily access constants.spinner.
|
|
5465
|
+
const {
|
|
5466
|
+
spinner
|
|
5467
|
+
} = constants;
|
|
5468
|
+
spinner.start('Socket optimizing...');
|
|
5469
|
+
const state = await addOverrides(pkgEnvDetails.pkgPath, pkgEnvDetails, {
|
|
5470
|
+
logger: logger.logger,
|
|
5471
|
+
pin,
|
|
5472
|
+
prod,
|
|
5473
|
+
spinner
|
|
5474
|
+
});
|
|
5475
|
+
spinner.stop();
|
|
5476
|
+
const addedCount = state.added.size;
|
|
5477
|
+
const updatedCount = state.updated.size;
|
|
5478
|
+
const pkgJsonChanged = addedCount > 0 || updatedCount > 0;
|
|
5479
|
+
if (pkgJsonChanged) {
|
|
5480
|
+
if (updatedCount > 0) {
|
|
5481
|
+
logger.logger?.log(`${createActionMessage('Updated', updatedCount, state.updatedInWorkspaces.size)}${addedCount ? '.' : '🚀'}`);
|
|
5482
|
+
}
|
|
5483
|
+
if (addedCount > 0) {
|
|
5484
|
+
logger.logger?.log(`${createActionMessage('Added', addedCount, state.addedInWorkspaces.size)} 🚀`);
|
|
5485
|
+
}
|
|
5486
|
+
} else {
|
|
5487
|
+
logger.logger?.log('Congratulations! Already Socket.dev optimized 🎉');
|
|
5488
|
+
}
|
|
5489
|
+
if (pkgEnvDetails.agent === NPM$1 || pkgJsonChanged) {
|
|
5490
|
+
// Always update package-lock.json until the npm overrides PR lands:
|
|
5491
|
+
// https://github.com/npm/cli/pull/8089
|
|
5492
|
+
await updateLockfile(pkgEnvDetails, {
|
|
5493
|
+
logger: logger.logger,
|
|
5494
|
+
spinner
|
|
5495
|
+
});
|
|
5496
|
+
}
|
|
5497
|
+
}
|
|
5352
5498
|
|
|
5353
5499
|
const {
|
|
5354
5500
|
DRY_RUN_BAIL_TEXT: DRY_RUN_BAIL_TEXT$h
|
|
@@ -5405,9 +5551,9 @@ async function run$h(argv, importMeta, {
|
|
|
5405
5551
|
}
|
|
5406
5552
|
|
|
5407
5553
|
async function getOrganization(format = 'text') {
|
|
5408
|
-
const apiToken =
|
|
5554
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
5409
5555
|
if (!apiToken) {
|
|
5410
|
-
throw new
|
|
5556
|
+
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.');
|
|
5411
5557
|
}
|
|
5412
5558
|
await printOrganizationsFromToken(apiToken, format);
|
|
5413
5559
|
}
|
|
@@ -5417,10 +5563,10 @@ async function printOrganizationsFromToken(apiToken, format = 'text') {
|
|
|
5417
5563
|
spinner
|
|
5418
5564
|
} = constants;
|
|
5419
5565
|
spinner.start('Fetching organizations...');
|
|
5420
|
-
const socketSdk = await
|
|
5566
|
+
const socketSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
5421
5567
|
const result = await handleApiCall(socketSdk.getOrganizations(), 'looking up organizations');
|
|
5422
5568
|
if (!result.success) {
|
|
5423
|
-
handleUnsuccessfulApiResponse('getOrganizations', result
|
|
5569
|
+
handleUnsuccessfulApiResponse('getOrganizations', result);
|
|
5424
5570
|
return;
|
|
5425
5571
|
}
|
|
5426
5572
|
spinner.stop();
|
|
@@ -5511,7 +5657,7 @@ async function run$g(argv, importMeta, {
|
|
|
5511
5657
|
// options or missing arguments.
|
|
5512
5658
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
5513
5659
|
process.exitCode = 2;
|
|
5514
|
-
logger.logger.
|
|
5660
|
+
logger.logger.fail(commonTags.stripIndents`
|
|
5515
5661
|
${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
5516
5662
|
|
|
5517
5663
|
- The json and markdown flags cannot be both set, pick one
|
|
@@ -5526,7 +5672,7 @@ ${colors.bgRed(colors.white('Input error'))}: Please provide the required fields
|
|
|
5526
5672
|
}
|
|
5527
5673
|
|
|
5528
5674
|
async function runRawNpm(argv) {
|
|
5529
|
-
const spawnPromise = spawn.spawn(
|
|
5675
|
+
const spawnPromise = spawn.spawn(shadowNpmPaths.getNpmBinPath(), argv, {
|
|
5530
5676
|
stdio: 'inherit'
|
|
5531
5677
|
});
|
|
5532
5678
|
// See https://nodejs.org/api/all.html#all_child_process_event-exit.
|
|
@@ -5580,7 +5726,7 @@ async function run$f(argv, importMeta, {
|
|
|
5580
5726
|
}
|
|
5581
5727
|
|
|
5582
5728
|
async function runRawNpx(argv) {
|
|
5583
|
-
const spawnPromise = spawn.spawn(
|
|
5729
|
+
const spawnPromise = spawn.spawn(shadowNpmPaths.getNpxBinPath(), argv, {
|
|
5584
5730
|
stdio: 'inherit'
|
|
5585
5731
|
});
|
|
5586
5732
|
// See https://nodejs.org/api/all.html#all_child_process_event-exit.
|
|
@@ -5644,16 +5790,16 @@ async function createReport(socketConfig, inputPaths, {
|
|
|
5644
5790
|
const {
|
|
5645
5791
|
spinner
|
|
5646
5792
|
} = constants;
|
|
5647
|
-
const socketSdk = await
|
|
5793
|
+
const socketSdk = await shadowNpmInject.setupSdk();
|
|
5648
5794
|
const supportedFiles = await socketSdk.getReportSupportedFiles().then(res => {
|
|
5649
|
-
if (!res.success) handleUnsuccessfulApiResponse('getReportSupportedFiles', res
|
|
5795
|
+
if (!res.success) handleUnsuccessfulApiResponse('getReportSupportedFiles', res);
|
|
5650
5796
|
return res.data;
|
|
5651
5797
|
}).catch(cause => {
|
|
5652
5798
|
throw new Error('Failed getting supported files for report', {
|
|
5653
5799
|
cause
|
|
5654
5800
|
});
|
|
5655
5801
|
});
|
|
5656
|
-
const packagePaths = await
|
|
5802
|
+
const packagePaths = await shadowNpmPaths.getPackageFilesFullScans(cwd, inputPaths, supportedFiles, socketConfig);
|
|
5657
5803
|
const packagePathsCount = packagePaths.length;
|
|
5658
5804
|
if (packagePathsCount && debug.isDebug()) {
|
|
5659
5805
|
for (const pkgPath of packagePaths) {
|
|
@@ -5668,7 +5814,7 @@ async function createReport(socketConfig, inputPaths, {
|
|
|
5668
5814
|
const apiCall = socketSdk.createReportFromFilePaths(packagePaths, cwd, socketConfig?.issueRules);
|
|
5669
5815
|
const result = await handleApiCall(apiCall, 'creating report');
|
|
5670
5816
|
if (!result.success) {
|
|
5671
|
-
handleUnsuccessfulApiResponse('createReport', result
|
|
5817
|
+
handleUnsuccessfulApiResponse('createReport', result);
|
|
5672
5818
|
return undefined;
|
|
5673
5819
|
}
|
|
5674
5820
|
spinner.successAndStop();
|
|
@@ -5686,7 +5832,7 @@ async function getSocketConfig(absoluteConfigPath) {
|
|
|
5686
5832
|
errors: cause.validationErrors,
|
|
5687
5833
|
schema: cause.schema
|
|
5688
5834
|
});
|
|
5689
|
-
throw new
|
|
5835
|
+
throw new shadowNpmInject.InputError('The socket.yml config is not valid', betterErrors.map(err => `[${err.path}] ${err.message}.${err.suggestion ? err.suggestion : ''}`).join('\n'));
|
|
5690
5836
|
} else {
|
|
5691
5837
|
throw new Error('Failed to read socket.yml config', {
|
|
5692
5838
|
cause
|
|
@@ -5704,7 +5850,7 @@ async function fetchReportData(reportId, includeAllIssues, strict) {
|
|
|
5704
5850
|
spinner
|
|
5705
5851
|
} = constants;
|
|
5706
5852
|
spinner.start(`Fetching report with ID ${reportId} (this could take a while)`);
|
|
5707
|
-
const socketSdk = await
|
|
5853
|
+
const socketSdk = await shadowNpmInject.setupSdk();
|
|
5708
5854
|
let result;
|
|
5709
5855
|
for (let retry = 1; !result; ++retry) {
|
|
5710
5856
|
try {
|
|
@@ -5718,7 +5864,7 @@ async function fetchReportData(reportId, includeAllIssues, strict) {
|
|
|
5718
5864
|
}
|
|
5719
5865
|
}
|
|
5720
5866
|
if (!result.success) {
|
|
5721
|
-
return handleUnsuccessfulApiResponse('getReport', result
|
|
5867
|
+
return handleUnsuccessfulApiResponse('getReport', result);
|
|
5722
5868
|
}
|
|
5723
5869
|
|
|
5724
5870
|
// Conclude the status of the API call.
|
|
@@ -5729,8 +5875,8 @@ async function fetchReportData(reportId, includeAllIssues, strict) {
|
|
|
5729
5875
|
spinner.error('Report result deemed unhealthy for project');
|
|
5730
5876
|
}
|
|
5731
5877
|
} else if (!result.data.healthy) {
|
|
5732
|
-
const severityCount = getSeverityCount(result.data.issues, includeAllIssues ? undefined : 'high');
|
|
5733
|
-
const issueSummary = formatSeverityCount(severityCount);
|
|
5878
|
+
const severityCount = shadowNpmInject.getSeverityCount(result.data.issues, includeAllIssues ? undefined : 'high');
|
|
5879
|
+
const issueSummary = shadowNpmInject.formatSeverityCount(severityCount);
|
|
5734
5880
|
spinner.success(`Report has these issues: ${issueSummary}`);
|
|
5735
5881
|
} else {
|
|
5736
5882
|
spinner.success('Report has no issues');
|
|
@@ -5743,7 +5889,7 @@ function formatReportDataOutput(reportId, data, commandName, outputJson, outputM
|
|
|
5743
5889
|
if (outputJson) {
|
|
5744
5890
|
logger.logger.log(JSON.stringify(data, undefined, 2));
|
|
5745
5891
|
} else {
|
|
5746
|
-
const format = new
|
|
5892
|
+
const format = new shadowNpmInject.ColorOrMarkdown(outputMarkdown);
|
|
5747
5893
|
logger.logger.log(commonTags.stripIndents`
|
|
5748
5894
|
Detailed info on socket.dev: ${format.hyperlink(reportId, data.url, {
|
|
5749
5895
|
fallbackToUrl: true
|
|
@@ -5847,7 +5993,7 @@ async function run$d(argv, importMeta, {
|
|
|
5847
5993
|
} else if (json) {
|
|
5848
5994
|
logger.logger.log(JSON.stringify(result.data, undefined, 2));
|
|
5849
5995
|
} else {
|
|
5850
|
-
const format = new
|
|
5996
|
+
const format = new shadowNpmInject.ColorOrMarkdown(markdown);
|
|
5851
5997
|
logger.logger.log(`New report: ${format.hyperlink(result.data.id, result.data.url, {
|
|
5852
5998
|
fallbackToUrl: true
|
|
5853
5999
|
})}`);
|
|
@@ -5894,7 +6040,7 @@ async function run$c(argv, importMeta, {
|
|
|
5894
6040
|
// options or missing arguments.
|
|
5895
6041
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
5896
6042
|
process.exitCode = 2;
|
|
5897
|
-
logger.logger.
|
|
6043
|
+
logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
5898
6044
|
|
|
5899
6045
|
- Need at least one report ID ${!reportId ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
5900
6046
|
|
|
@@ -5935,13 +6081,33 @@ const cmdReport = {
|
|
|
5935
6081
|
};
|
|
5936
6082
|
|
|
5937
6083
|
async function createRepo({
|
|
6084
|
+
default_branch,
|
|
6085
|
+
description,
|
|
6086
|
+
homepage,
|
|
6087
|
+
orgSlug,
|
|
6088
|
+
repoName,
|
|
6089
|
+
visibility
|
|
6090
|
+
}) {
|
|
6091
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
6092
|
+
if (!apiToken) {
|
|
6093
|
+
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.');
|
|
6094
|
+
}
|
|
6095
|
+
await createRepoWithToken({
|
|
6096
|
+
apiToken,
|
|
6097
|
+
default_branch,
|
|
6098
|
+
description,
|
|
6099
|
+
homepage,
|
|
6100
|
+
orgSlug,
|
|
6101
|
+
repoName,
|
|
6102
|
+
visibility
|
|
6103
|
+
});
|
|
6104
|
+
}
|
|
6105
|
+
async function createRepoWithToken({
|
|
5938
6106
|
apiToken,
|
|
5939
6107
|
default_branch,
|
|
5940
6108
|
description,
|
|
5941
6109
|
homepage,
|
|
5942
6110
|
orgSlug,
|
|
5943
|
-
outputJson,
|
|
5944
|
-
outputMarkdown,
|
|
5945
6111
|
repoName,
|
|
5946
6112
|
visibility
|
|
5947
6113
|
}) {
|
|
@@ -5950,22 +6116,19 @@ async function createRepo({
|
|
|
5950
6116
|
spinner
|
|
5951
6117
|
} = constants;
|
|
5952
6118
|
spinner.start('Creating repository...');
|
|
5953
|
-
const socketSdk = await
|
|
6119
|
+
const socketSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
5954
6120
|
const result = await handleApiCall(socketSdk.createOrgRepo(orgSlug, {
|
|
5955
|
-
outputJson,
|
|
5956
|
-
outputMarkdown,
|
|
5957
|
-
orgSlug,
|
|
5958
6121
|
name: repoName,
|
|
5959
6122
|
description,
|
|
5960
6123
|
homepage,
|
|
5961
6124
|
default_branch,
|
|
5962
6125
|
visibility
|
|
5963
6126
|
}), 'creating repository');
|
|
5964
|
-
if (result.success) {
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
handleUnsuccessfulApiResponse('createOrgRepo', result, spinner);
|
|
6127
|
+
if (!result.success) {
|
|
6128
|
+
handleUnsuccessfulApiResponse('createOrgRepo', result);
|
|
6129
|
+
return;
|
|
5968
6130
|
}
|
|
6131
|
+
spinner.successAndStop('Repository created successfully');
|
|
5969
6132
|
}
|
|
5970
6133
|
|
|
5971
6134
|
const {
|
|
@@ -5977,7 +6140,6 @@ const config$b = {
|
|
|
5977
6140
|
hidden: false,
|
|
5978
6141
|
flags: {
|
|
5979
6142
|
...commonFlags,
|
|
5980
|
-
...outputFlags,
|
|
5981
6143
|
repoName: {
|
|
5982
6144
|
type: 'string',
|
|
5983
6145
|
shortFlag: 'n',
|
|
@@ -6041,7 +6203,7 @@ async function run$b(argv, importMeta, {
|
|
|
6041
6203
|
// options or missing arguments.
|
|
6042
6204
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
6043
6205
|
process.exitCode = 2;
|
|
6044
|
-
logger.logger.
|
|
6206
|
+
logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
6045
6207
|
|
|
6046
6208
|
- Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
6047
6209
|
|
|
@@ -6052,36 +6214,36 @@ async function run$b(argv, importMeta, {
|
|
|
6052
6214
|
logger.logger.log(DRY_RUN_BAIL_TEXT$b);
|
|
6053
6215
|
return;
|
|
6054
6216
|
}
|
|
6055
|
-
const apiToken = index.getDefaultToken();
|
|
6056
|
-
if (!apiToken) {
|
|
6057
|
-
throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
|
|
6058
|
-
}
|
|
6059
6217
|
await createRepo({
|
|
6060
|
-
outputJson: Boolean(cli.flags['json']),
|
|
6061
|
-
outputMarkdown: Boolean(cli.flags['markdown']),
|
|
6062
6218
|
orgSlug,
|
|
6063
6219
|
repoName,
|
|
6064
6220
|
description: String(cli.flags['repoDescription'] || ''),
|
|
6065
6221
|
homepage: String(cli.flags['homepage'] || ''),
|
|
6066
6222
|
default_branch: String(cli.flags['defaultBranch'] || ''),
|
|
6067
|
-
visibility: String(cli.flags['visibility'] || 'private')
|
|
6068
|
-
apiToken
|
|
6223
|
+
visibility: String(cli.flags['visibility'] || 'private')
|
|
6069
6224
|
});
|
|
6070
6225
|
}
|
|
6071
6226
|
|
|
6072
|
-
async function deleteRepo(orgSlug, repoName
|
|
6227
|
+
async function deleteRepo(orgSlug, repoName) {
|
|
6228
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
6229
|
+
if (!apiToken) {
|
|
6230
|
+
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.');
|
|
6231
|
+
}
|
|
6232
|
+
await deleteRepoWithToken(orgSlug, repoName, apiToken);
|
|
6233
|
+
}
|
|
6234
|
+
async function deleteRepoWithToken(orgSlug, repoName, apiToken) {
|
|
6073
6235
|
// Lazily access constants.spinner.
|
|
6074
6236
|
const {
|
|
6075
6237
|
spinner
|
|
6076
6238
|
} = constants;
|
|
6077
6239
|
spinner.start('Deleting repository...');
|
|
6078
|
-
const socketSdk = await
|
|
6240
|
+
const socketSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
6079
6241
|
const result = await handleApiCall(socketSdk.deleteOrgRepo(orgSlug, repoName), 'deleting repository');
|
|
6080
|
-
if (result.success) {
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
handleUnsuccessfulApiResponse('deleteOrgRepo', result, spinner);
|
|
6242
|
+
if (!result.success) {
|
|
6243
|
+
handleUnsuccessfulApiResponse('deleteOrgRepo', result);
|
|
6244
|
+
return;
|
|
6084
6245
|
}
|
|
6246
|
+
spinner.successAndStop('Repository deleted successfully');
|
|
6085
6247
|
}
|
|
6086
6248
|
|
|
6087
6249
|
const {
|
|
@@ -6125,7 +6287,7 @@ async function run$a(argv, importMeta, {
|
|
|
6125
6287
|
// options or missing arguments.
|
|
6126
6288
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
6127
6289
|
process.exitCode = 2;
|
|
6128
|
-
logger.logger.
|
|
6290
|
+
logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
6129
6291
|
|
|
6130
6292
|
- Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
6131
6293
|
|
|
@@ -6138,20 +6300,37 @@ async function run$a(argv, importMeta, {
|
|
|
6138
6300
|
logger.logger.log(DRY_RUN_BAIL_TEXT$a);
|
|
6139
6301
|
return;
|
|
6140
6302
|
}
|
|
6141
|
-
|
|
6142
|
-
if (!apiToken) {
|
|
6143
|
-
throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
|
|
6144
|
-
}
|
|
6145
|
-
await deleteRepo(orgSlug, repoName, apiToken);
|
|
6303
|
+
await deleteRepo(orgSlug, repoName);
|
|
6146
6304
|
}
|
|
6147
6305
|
|
|
6148
6306
|
// @ts-ignore
|
|
6149
6307
|
async function listRepos({
|
|
6308
|
+
direction,
|
|
6309
|
+
orgSlug,
|
|
6310
|
+
outputKind,
|
|
6311
|
+
page,
|
|
6312
|
+
per_page,
|
|
6313
|
+
sort
|
|
6314
|
+
}) {
|
|
6315
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
6316
|
+
if (!apiToken) {
|
|
6317
|
+
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.');
|
|
6318
|
+
}
|
|
6319
|
+
await listReposWithToken({
|
|
6320
|
+
apiToken,
|
|
6321
|
+
direction,
|
|
6322
|
+
orgSlug,
|
|
6323
|
+
outputKind,
|
|
6324
|
+
page,
|
|
6325
|
+
per_page,
|
|
6326
|
+
sort
|
|
6327
|
+
});
|
|
6328
|
+
}
|
|
6329
|
+
async function listReposWithToken({
|
|
6150
6330
|
apiToken,
|
|
6151
6331
|
direction,
|
|
6152
6332
|
orgSlug,
|
|
6153
|
-
|
|
6154
|
-
outputMarkdown,
|
|
6333
|
+
outputKind,
|
|
6155
6334
|
page,
|
|
6156
6335
|
per_page,
|
|
6157
6336
|
sort
|
|
@@ -6160,23 +6339,20 @@ async function listRepos({
|
|
|
6160
6339
|
const {
|
|
6161
6340
|
spinner
|
|
6162
6341
|
} = constants;
|
|
6163
|
-
spinner.start('
|
|
6164
|
-
const socketSdk = await
|
|
6342
|
+
spinner.start('Fetching list of repositories...');
|
|
6343
|
+
const socketSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
6165
6344
|
const result = await handleApiCall(socketSdk.getOrgRepoList(orgSlug, {
|
|
6166
|
-
outputJson,
|
|
6167
|
-
outputMarkdown,
|
|
6168
|
-
orgSlug,
|
|
6169
6345
|
sort,
|
|
6170
6346
|
direction,
|
|
6171
6347
|
per_page,
|
|
6172
6348
|
page
|
|
6173
6349
|
}), 'listing repositories');
|
|
6174
6350
|
if (!result.success) {
|
|
6175
|
-
handleUnsuccessfulApiResponse('getOrgRepoList', result
|
|
6351
|
+
handleUnsuccessfulApiResponse('getOrgRepoList', result);
|
|
6176
6352
|
return;
|
|
6177
6353
|
}
|
|
6178
|
-
spinner.stop();
|
|
6179
|
-
if (
|
|
6354
|
+
spinner.stop('Fetch complete.');
|
|
6355
|
+
if (outputKind === 'json') {
|
|
6180
6356
|
const data = result.data.results.map(o => ({
|
|
6181
6357
|
id: o.id,
|
|
6182
6358
|
name: o.name,
|
|
@@ -6273,7 +6449,7 @@ async function run$9(argv, importMeta, {
|
|
|
6273
6449
|
// options or missing arguments.
|
|
6274
6450
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
6275
6451
|
process.exitCode = 2;
|
|
6276
|
-
logger.logger.
|
|
6452
|
+
logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
6277
6453
|
|
|
6278
6454
|
- Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
6279
6455
|
|
|
@@ -6284,30 +6460,44 @@ async function run$9(argv, importMeta, {
|
|
|
6284
6460
|
logger.logger.log(DRY_RUN_BAIL_TEXT$9);
|
|
6285
6461
|
return;
|
|
6286
6462
|
}
|
|
6287
|
-
const apiToken = index.getDefaultToken();
|
|
6288
|
-
if (!apiToken) {
|
|
6289
|
-
throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
|
|
6290
|
-
}
|
|
6291
6463
|
await listRepos({
|
|
6292
|
-
apiToken,
|
|
6293
|
-
outputJson: Boolean(cli.flags['json']),
|
|
6294
|
-
outputMarkdown: Boolean(cli.flags['markdown']),
|
|
6295
|
-
orgSlug,
|
|
6296
|
-
sort: String(cli.flags['sort'] || 'created_at'),
|
|
6297
6464
|
direction: cli.flags['direction'] === 'asc' ? 'asc' : 'desc',
|
|
6465
|
+
orgSlug,
|
|
6466
|
+
outputKind: cli.flags['json'] ? 'json' : cli.flags['markdown'] ? 'markdown' : 'print',
|
|
6298
6467
|
page: Number(cli.flags['page']) || 1,
|
|
6299
|
-
per_page: Number(cli.flags['perPage']) || 30
|
|
6468
|
+
per_page: Number(cli.flags['perPage']) || 30,
|
|
6469
|
+
sort: String(cli.flags['sort'] || 'created_at')
|
|
6300
6470
|
});
|
|
6301
6471
|
}
|
|
6302
6472
|
|
|
6303
6473
|
async function updateRepo({
|
|
6474
|
+
default_branch,
|
|
6475
|
+
description,
|
|
6476
|
+
homepage,
|
|
6477
|
+
orgSlug,
|
|
6478
|
+
repoName,
|
|
6479
|
+
visibility
|
|
6480
|
+
}) {
|
|
6481
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
6482
|
+
if (!apiToken) {
|
|
6483
|
+
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.');
|
|
6484
|
+
}
|
|
6485
|
+
await updateRepoWithToken({
|
|
6486
|
+
apiToken,
|
|
6487
|
+
default_branch,
|
|
6488
|
+
description,
|
|
6489
|
+
homepage,
|
|
6490
|
+
orgSlug,
|
|
6491
|
+
repoName,
|
|
6492
|
+
visibility
|
|
6493
|
+
});
|
|
6494
|
+
}
|
|
6495
|
+
async function updateRepoWithToken({
|
|
6304
6496
|
apiToken,
|
|
6305
6497
|
default_branch,
|
|
6306
6498
|
description,
|
|
6307
6499
|
homepage,
|
|
6308
6500
|
orgSlug,
|
|
6309
|
-
outputJson,
|
|
6310
|
-
outputMarkdown,
|
|
6311
6501
|
repoName,
|
|
6312
6502
|
visibility
|
|
6313
6503
|
}) {
|
|
@@ -6316,10 +6506,8 @@ async function updateRepo({
|
|
|
6316
6506
|
spinner
|
|
6317
6507
|
} = constants;
|
|
6318
6508
|
spinner.start('Updating repository...');
|
|
6319
|
-
const socketSdk = await
|
|
6509
|
+
const socketSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
6320
6510
|
const result = await handleApiCall(socketSdk.updateOrgRepo(orgSlug, repoName, {
|
|
6321
|
-
outputJson,
|
|
6322
|
-
outputMarkdown,
|
|
6323
6511
|
orgSlug,
|
|
6324
6512
|
name: repoName,
|
|
6325
6513
|
description,
|
|
@@ -6327,11 +6515,11 @@ async function updateRepo({
|
|
|
6327
6515
|
default_branch,
|
|
6328
6516
|
visibility
|
|
6329
6517
|
}), 'updating repository');
|
|
6330
|
-
if (result.success) {
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
handleUnsuccessfulApiResponse('updateOrgRepo', result, spinner);
|
|
6518
|
+
if (!result.success) {
|
|
6519
|
+
handleUnsuccessfulApiResponse('updateOrgRepo', result);
|
|
6520
|
+
return;
|
|
6334
6521
|
}
|
|
6522
|
+
spinner.successAndStop('Repository updated successfully');
|
|
6335
6523
|
}
|
|
6336
6524
|
|
|
6337
6525
|
const {
|
|
@@ -6343,7 +6531,6 @@ const config$8 = {
|
|
|
6343
6531
|
hidden: false,
|
|
6344
6532
|
flags: {
|
|
6345
6533
|
...commonFlags,
|
|
6346
|
-
...outputFlags,
|
|
6347
6534
|
repoName: {
|
|
6348
6535
|
type: 'string',
|
|
6349
6536
|
shortFlag: 'n',
|
|
@@ -6407,7 +6594,7 @@ async function run$8(argv, importMeta, {
|
|
|
6407
6594
|
// options or missing arguments.
|
|
6408
6595
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
6409
6596
|
process.exitCode = 2;
|
|
6410
|
-
logger.logger.
|
|
6597
|
+
logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
6411
6598
|
|
|
6412
6599
|
- Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
6413
6600
|
|
|
@@ -6420,14 +6607,7 @@ async function run$8(argv, importMeta, {
|
|
|
6420
6607
|
logger.logger.log(DRY_RUN_BAIL_TEXT$8);
|
|
6421
6608
|
return;
|
|
6422
6609
|
}
|
|
6423
|
-
const apiToken = index.getDefaultToken();
|
|
6424
|
-
if (!apiToken) {
|
|
6425
|
-
throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
|
|
6426
|
-
}
|
|
6427
6610
|
await updateRepo({
|
|
6428
|
-
apiToken,
|
|
6429
|
-
outputJson: Boolean(cli.flags['json']),
|
|
6430
|
-
outputMarkdown: Boolean(cli.flags['markdown']),
|
|
6431
6611
|
orgSlug,
|
|
6432
6612
|
repoName,
|
|
6433
6613
|
description: String(cli.flags['repoDescription'] || ''),
|
|
@@ -6438,16 +6618,45 @@ async function run$8(argv, importMeta, {
|
|
|
6438
6618
|
}
|
|
6439
6619
|
|
|
6440
6620
|
// @ts-ignore
|
|
6441
|
-
async function viewRepo(orgSlug, repoName,
|
|
6621
|
+
async function viewRepo(orgSlug, repoName, outputKind) {
|
|
6622
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
6623
|
+
if (!apiToken) {
|
|
6624
|
+
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.');
|
|
6625
|
+
}
|
|
6626
|
+
await viewRepoWithToken(orgSlug, repoName, apiToken, outputKind);
|
|
6627
|
+
}
|
|
6628
|
+
async function viewRepoWithToken(orgSlug, repoName, apiToken, outputKind) {
|
|
6442
6629
|
// Lazily access constants.spinner.
|
|
6443
6630
|
const {
|
|
6444
6631
|
spinner
|
|
6445
6632
|
} = constants;
|
|
6446
|
-
spinner.start('Fetching repository...');
|
|
6447
|
-
const socketSdk = await
|
|
6633
|
+
spinner.start('Fetching repository data...');
|
|
6634
|
+
const socketSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
6448
6635
|
const result = await handleApiCall(socketSdk.getOrgRepo(orgSlug, repoName), 'fetching repository');
|
|
6449
6636
|
if (!result.success) {
|
|
6450
|
-
handleUnsuccessfulApiResponse('getOrgRepo', result
|
|
6637
|
+
handleUnsuccessfulApiResponse('getOrgRepo', result);
|
|
6638
|
+
return;
|
|
6639
|
+
}
|
|
6640
|
+
spinner.stop('Fetched repository data.');
|
|
6641
|
+
if (outputKind === 'json') {
|
|
6642
|
+
const {
|
|
6643
|
+
archived,
|
|
6644
|
+
created_at,
|
|
6645
|
+
default_branch,
|
|
6646
|
+
homepage,
|
|
6647
|
+
id,
|
|
6648
|
+
name,
|
|
6649
|
+
visibility
|
|
6650
|
+
} = result.data;
|
|
6651
|
+
logger.logger.log(JSON.stringify({
|
|
6652
|
+
id,
|
|
6653
|
+
name,
|
|
6654
|
+
visibility,
|
|
6655
|
+
default_branch,
|
|
6656
|
+
homepage,
|
|
6657
|
+
archived,
|
|
6658
|
+
created_at
|
|
6659
|
+
}, null, 2));
|
|
6451
6660
|
return;
|
|
6452
6661
|
}
|
|
6453
6662
|
const options = {
|
|
@@ -6474,7 +6683,7 @@ async function viewRepo(orgSlug, repoName, apiToken) {
|
|
|
6474
6683
|
name: colors.magenta('Created at')
|
|
6475
6684
|
}]
|
|
6476
6685
|
};
|
|
6477
|
-
|
|
6686
|
+
logger.logger.log(chalkTable(options, [result.data]));
|
|
6478
6687
|
}
|
|
6479
6688
|
|
|
6480
6689
|
const {
|
|
@@ -6486,7 +6695,12 @@ const config$7 = {
|
|
|
6486
6695
|
hidden: false,
|
|
6487
6696
|
flags: {
|
|
6488
6697
|
...commonFlags,
|
|
6489
|
-
...outputFlags
|
|
6698
|
+
...outputFlags,
|
|
6699
|
+
repoName: {
|
|
6700
|
+
description: 'The repository to check',
|
|
6701
|
+
default: '',
|
|
6702
|
+
type: 'string'
|
|
6703
|
+
}
|
|
6490
6704
|
},
|
|
6491
6705
|
help: (command, config) => `
|
|
6492
6706
|
Usage
|
|
@@ -6520,7 +6734,7 @@ async function run$7(argv, importMeta, {
|
|
|
6520
6734
|
// options or missing arguments.
|
|
6521
6735
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
6522
6736
|
process.exitCode = 2;
|
|
6523
|
-
logger.logger.
|
|
6737
|
+
logger.logger.fail(commonTags.stripIndents`
|
|
6524
6738
|
${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
6525
6739
|
|
|
6526
6740
|
- Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
@@ -6533,11 +6747,7 @@ async function run$7(argv, importMeta, {
|
|
|
6533
6747
|
logger.logger.log(DRY_RUN_BAIL_TEXT$7);
|
|
6534
6748
|
return;
|
|
6535
6749
|
}
|
|
6536
|
-
|
|
6537
|
-
if (!apiToken) {
|
|
6538
|
-
throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
|
|
6539
|
-
}
|
|
6540
|
-
await viewRepo(orgSlug, repoName, apiToken);
|
|
6750
|
+
await viewRepo(orgSlug, repoName, cli.flags['json'] ? 'json' : cli.flags['markdown'] ? 'markdown' : 'print');
|
|
6541
6751
|
}
|
|
6542
6752
|
|
|
6543
6753
|
const description$1 = 'Repositories related commands';
|
|
@@ -6722,10 +6932,10 @@ async function createFullScan({
|
|
|
6722
6932
|
const {
|
|
6723
6933
|
spinner
|
|
6724
6934
|
} = constants;
|
|
6725
|
-
const socketSdk = await
|
|
6935
|
+
const socketSdk = await shadowNpmInject.setupSdk();
|
|
6726
6936
|
const supportedFiles = await socketSdk.getReportSupportedFiles().then(res => {
|
|
6727
6937
|
if (!res.success) {
|
|
6728
|
-
handleUnsuccessfulApiResponse('getReportSupportedFiles', res
|
|
6938
|
+
handleUnsuccessfulApiResponse('getReportSupportedFiles', res);
|
|
6729
6939
|
assert(false, 'handleUnsuccessfulApiResponse should unconditionally throw');
|
|
6730
6940
|
}
|
|
6731
6941
|
return res.data;
|
|
@@ -6748,14 +6958,14 @@ async function createFullScan({
|
|
|
6748
6958
|
// const absoluteConfigPath = path.join(cwd, 'socket.yml')
|
|
6749
6959
|
// const socketConfig = await getSocketConfig(absoluteConfigPath)
|
|
6750
6960
|
|
|
6751
|
-
const packagePaths = await
|
|
6961
|
+
const packagePaths = await shadowNpmPaths.getPackageFilesFullScans(cwd, targets, supportedFiles
|
|
6752
6962
|
// socketConfig
|
|
6753
6963
|
);
|
|
6754
6964
|
|
|
6755
6965
|
// We're going to need an api token to suggest data because those suggestions
|
|
6756
6966
|
// must come from data we already know. Don't error on missing api token yet.
|
|
6757
6967
|
// If the api-token is not set, ignore it for the sake of suggestions.
|
|
6758
|
-
const apiToken =
|
|
6968
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
6759
6969
|
|
|
6760
6970
|
// If the current cwd is unknown and is used as a repo slug anyways, we will
|
|
6761
6971
|
// first need to register the slug before we can use it.
|
|
@@ -6789,7 +6999,7 @@ async function createFullScan({
|
|
|
6789
6999
|
// options or missing arguments.
|
|
6790
7000
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
6791
7001
|
process$1.exitCode = 2;
|
|
6792
|
-
logger.logger.
|
|
7002
|
+
logger.logger.fail(commonTags.stripIndents`
|
|
6793
7003
|
${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
6794
7004
|
|
|
6795
7005
|
- Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
@@ -6811,7 +7021,7 @@ async function createFullScan({
|
|
|
6811
7021
|
logger.logger.log('```');
|
|
6812
7022
|
}
|
|
6813
7023
|
if (!apiToken) {
|
|
6814
|
-
throw new
|
|
7024
|
+
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.');
|
|
6815
7025
|
}
|
|
6816
7026
|
if (readOnly) {
|
|
6817
7027
|
logger.logger.log('[ReadOnly] Bailing now');
|
|
@@ -6827,7 +7037,7 @@ async function createFullScan({
|
|
|
6827
7037
|
tmp
|
|
6828
7038
|
}, packagePaths, cwd), 'Creating scan');
|
|
6829
7039
|
if (!result.success) {
|
|
6830
|
-
handleUnsuccessfulApiResponse('CreateOrgFullScan', result
|
|
7040
|
+
handleUnsuccessfulApiResponse('CreateOrgFullScan', result);
|
|
6831
7041
|
return;
|
|
6832
7042
|
}
|
|
6833
7043
|
spinner.successAndStop('Scan created successfully');
|
|
@@ -6967,20 +7177,21 @@ async function run$6(argv, importMeta, {
|
|
|
6967
7177
|
});
|
|
6968
7178
|
const [orgSlug = '', ...targets] = cli.input;
|
|
6969
7179
|
const cwd = cli.flags['cwd'] && cli.flags['cwd'] !== 'process.cwd()' ? String(cli.flags['cwd']) : process$1.cwd();
|
|
6970
|
-
|
|
7180
|
+
const {
|
|
6971
7181
|
branch: branchName,
|
|
6972
7182
|
repo: repoName
|
|
6973
7183
|
} = cli.flags;
|
|
6974
|
-
const apiToken =
|
|
7184
|
+
const apiToken = shadowNpmInject.getDefaultToken(); // This checks if we _can_ suggest anything
|
|
6975
7185
|
|
|
6976
7186
|
if (!apiToken && (!orgSlug || !repoName || !branchName || !targets.length)) {
|
|
6977
7187
|
// Without api token we cannot recover because we can't request more info
|
|
6978
7188
|
// from the server, to match and help with the current cwd/git status.
|
|
7189
|
+
//
|
|
6979
7190
|
// Use exit status of 2 to indicate incorrect usage, generally invalid
|
|
6980
7191
|
// options or missing arguments.
|
|
6981
7192
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
6982
7193
|
process$1.exitCode = 2;
|
|
6983
|
-
logger.logger.
|
|
7194
|
+
logger.logger.fail(commonTags.stripIndents`
|
|
6984
7195
|
${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
6985
7196
|
|
|
6986
7197
|
- Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
@@ -7019,9 +7230,9 @@ async function run$6(argv, importMeta, {
|
|
|
7019
7230
|
}
|
|
7020
7231
|
|
|
7021
7232
|
async function deleteOrgFullScan(orgSlug, fullScanId) {
|
|
7022
|
-
const apiToken =
|
|
7233
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
7023
7234
|
if (!apiToken) {
|
|
7024
|
-
throw new
|
|
7235
|
+
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.');
|
|
7025
7236
|
}
|
|
7026
7237
|
await deleteOrgFullScanWithToken(orgSlug, fullScanId, apiToken);
|
|
7027
7238
|
}
|
|
@@ -7031,10 +7242,10 @@ async function deleteOrgFullScanWithToken(orgSlug, fullScanId, apiToken) {
|
|
|
7031
7242
|
spinner
|
|
7032
7243
|
} = constants;
|
|
7033
7244
|
spinner.start('Deleting scan...');
|
|
7034
|
-
const socketSdk = await
|
|
7245
|
+
const socketSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
7035
7246
|
const result = await handleApiCall(socketSdk.deleteOrgFullScan(orgSlug, fullScanId), 'Deleting scan');
|
|
7036
7247
|
if (!result.success) {
|
|
7037
|
-
handleUnsuccessfulApiResponse('deleteOrgFullScan', result
|
|
7248
|
+
handleUnsuccessfulApiResponse('deleteOrgFullScan', result);
|
|
7038
7249
|
return;
|
|
7039
7250
|
}
|
|
7040
7251
|
spinner.successAndStop('Scan deleted successfully');
|
|
@@ -7082,7 +7293,7 @@ async function run$5(argv, importMeta, {
|
|
|
7082
7293
|
// options or missing arguments.
|
|
7083
7294
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
7084
7295
|
process.exitCode = 2;
|
|
7085
|
-
logger.logger.
|
|
7296
|
+
logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
7086
7297
|
|
|
7087
7298
|
- Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
7088
7299
|
|
|
@@ -7106,9 +7317,9 @@ async function listFullScans({
|
|
|
7106
7317
|
per_page,
|
|
7107
7318
|
sort
|
|
7108
7319
|
}) {
|
|
7109
|
-
const apiToken =
|
|
7320
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
7110
7321
|
if (!apiToken) {
|
|
7111
|
-
throw new
|
|
7322
|
+
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.');
|
|
7112
7323
|
}
|
|
7113
7324
|
await listFullScansWithToken({
|
|
7114
7325
|
apiToken,
|
|
@@ -7136,7 +7347,7 @@ async function listFullScansWithToken({
|
|
|
7136
7347
|
spinner
|
|
7137
7348
|
} = constants;
|
|
7138
7349
|
spinner.start('Fetching list of scans...');
|
|
7139
|
-
const socketSdk = await
|
|
7350
|
+
const socketSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
7140
7351
|
const result = await handleApiCall(socketSdk.getOrgFullScanList(orgSlug, {
|
|
7141
7352
|
sort,
|
|
7142
7353
|
direction,
|
|
@@ -7145,7 +7356,7 @@ async function listFullScansWithToken({
|
|
|
7145
7356
|
from: from_time
|
|
7146
7357
|
}), 'Listing scans');
|
|
7147
7358
|
if (!result.success) {
|
|
7148
|
-
handleUnsuccessfulApiResponse('getOrgFullScanList', result
|
|
7359
|
+
handleUnsuccessfulApiResponse('getOrgFullScanList', result);
|
|
7149
7360
|
return;
|
|
7150
7361
|
}
|
|
7151
7362
|
spinner.stop(`Fetch complete`);
|
|
@@ -7261,7 +7472,7 @@ async function run$4(argv, importMeta, {
|
|
|
7261
7472
|
// options or missing arguments.
|
|
7262
7473
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
7263
7474
|
process.exitCode = 2;
|
|
7264
|
-
logger.logger.
|
|
7475
|
+
logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
7265
7476
|
|
|
7266
7477
|
- Org name as the argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}`);
|
|
7267
7478
|
return;
|
|
@@ -7282,9 +7493,9 @@ async function run$4(argv, importMeta, {
|
|
|
7282
7493
|
}
|
|
7283
7494
|
|
|
7284
7495
|
async function getOrgScanMetadata(orgSlug, scanId, outputKind) {
|
|
7285
|
-
const apiToken =
|
|
7496
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
7286
7497
|
if (!apiToken) {
|
|
7287
|
-
throw new
|
|
7498
|
+
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.');
|
|
7288
7499
|
}
|
|
7289
7500
|
await getOrgScanMetadataWithToken(orgSlug, scanId, apiToken, outputKind);
|
|
7290
7501
|
}
|
|
@@ -7294,10 +7505,10 @@ async function getOrgScanMetadataWithToken(orgSlug, scanId, apiToken, outputKind
|
|
|
7294
7505
|
spinner
|
|
7295
7506
|
} = constants;
|
|
7296
7507
|
spinner.start('Fetching meta data for a full scan...');
|
|
7297
|
-
const socketSdk = await
|
|
7508
|
+
const socketSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
7298
7509
|
const result = await handleApiCall(socketSdk.getOrgFullScanMetadata(orgSlug, scanId), 'Listing scans');
|
|
7299
7510
|
if (!result.success) {
|
|
7300
|
-
handleUnsuccessfulApiResponse('getOrgFullScanMetadata', result
|
|
7511
|
+
handleUnsuccessfulApiResponse('getOrgFullScanMetadata', result);
|
|
7301
7512
|
return;
|
|
7302
7513
|
}
|
|
7303
7514
|
spinner?.successAndStop('Fetched the meta data\n');
|
|
@@ -7363,7 +7574,7 @@ async function run$3(argv, importMeta, {
|
|
|
7363
7574
|
// options or missing arguments.
|
|
7364
7575
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
7365
7576
|
process.exitCode = 2;
|
|
7366
|
-
logger.logger.
|
|
7577
|
+
logger.logger.fail(commonTags.stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
7367
7578
|
|
|
7368
7579
|
- Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
7369
7580
|
|
|
@@ -7382,15 +7593,15 @@ async function streamFullScan(orgSlug, fullScanId, file) {
|
|
|
7382
7593
|
const {
|
|
7383
7594
|
spinner
|
|
7384
7595
|
} = constants;
|
|
7385
|
-
const apiToken =
|
|
7596
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
7386
7597
|
if (!apiToken) {
|
|
7387
|
-
throw new
|
|
7598
|
+
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.');
|
|
7388
7599
|
}
|
|
7389
7600
|
spinner.start('Fetching scan...');
|
|
7390
|
-
const socketSdk = await
|
|
7601
|
+
const socketSdk = await shadowNpmInject.setupSdk(apiToken);
|
|
7391
7602
|
const data = await handleApiCall(socketSdk.getOrgFullScan(orgSlug, fullScanId, file === '-' ? undefined : file), 'Fetching a scan');
|
|
7392
7603
|
if (!data?.success) {
|
|
7393
|
-
handleUnsuccessfulApiResponse('getOrgFullScan', data
|
|
7604
|
+
handleUnsuccessfulApiResponse('getOrgFullScan', data);
|
|
7394
7605
|
return;
|
|
7395
7606
|
}
|
|
7396
7607
|
spinner?.successAndStop(file ? `Full scan details written to ${file}` : 'stdout');
|
|
@@ -7402,16 +7613,16 @@ async function getFullScan(orgSlug, fullScanId) {
|
|
|
7402
7613
|
const {
|
|
7403
7614
|
spinner
|
|
7404
7615
|
} = constants;
|
|
7405
|
-
const apiToken =
|
|
7616
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
7406
7617
|
if (!apiToken) {
|
|
7407
|
-
throw new
|
|
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.');
|
|
7408
7619
|
}
|
|
7409
7620
|
spinner.start('Fetching full-scan...');
|
|
7410
7621
|
const response = await queryAPI(`orgs/${orgSlug}/full-scans/${encodeURIComponent(fullScanId)}`, apiToken);
|
|
7411
7622
|
spinner.stop('Fetch complete.');
|
|
7412
7623
|
if (!response.ok) {
|
|
7413
7624
|
const err = await handleAPIError(response.status);
|
|
7414
|
-
logger.logger.
|
|
7625
|
+
logger.logger.fail(`${colors.bgRed(colors.white(response.statusText))}: Fetch error: ${err}`);
|
|
7415
7626
|
return;
|
|
7416
7627
|
}
|
|
7417
7628
|
|
|
@@ -7459,9 +7670,9 @@ View this report at: https://socket.dev/dashboard/org/${orgSlug}/sbom/${fullScan
|
|
|
7459
7670
|
await fs$1.writeFile(filePath, report, 'utf8');
|
|
7460
7671
|
logger.logger.log(`Data successfully written to ${filePath}`);
|
|
7461
7672
|
} catch (e) {
|
|
7462
|
-
logger.logger.error('There was an error trying to write the json to disk');
|
|
7463
|
-
logger.logger.error(e);
|
|
7464
7673
|
process.exitCode = 1;
|
|
7674
|
+
logger.logger.fail('There was an error trying to write the json to disk');
|
|
7675
|
+
logger.logger.error(e);
|
|
7465
7676
|
}
|
|
7466
7677
|
} else {
|
|
7467
7678
|
logger.logger.log(report);
|
|
@@ -7512,7 +7723,7 @@ async function run$2(argv, importMeta, {
|
|
|
7512
7723
|
// options or missing arguments.
|
|
7513
7724
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
7514
7725
|
process.exitCode = 2;
|
|
7515
|
-
logger.logger.
|
|
7726
|
+
logger.logger.fail(commonTags.stripIndents`
|
|
7516
7727
|
${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
|
|
7517
7728
|
|
|
7518
7729
|
- Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
|
|
@@ -7561,11 +7772,36 @@ const cmdScan = {
|
|
|
7561
7772
|
}
|
|
7562
7773
|
};
|
|
7563
7774
|
|
|
7775
|
+
// Note: Widgets does not seem to actually work as code :'(
|
|
7776
|
+
|
|
7564
7777
|
async function getThreatFeed({
|
|
7778
|
+
direction,
|
|
7779
|
+
ecosystem,
|
|
7780
|
+
filter,
|
|
7781
|
+
outputKind,
|
|
7782
|
+
page,
|
|
7783
|
+
perPage
|
|
7784
|
+
}) {
|
|
7785
|
+
const apiToken = shadowNpmInject.getDefaultToken();
|
|
7786
|
+
if (!apiToken) {
|
|
7787
|
+
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.');
|
|
7788
|
+
}
|
|
7789
|
+
await getThreatFeedWithToken({
|
|
7790
|
+
apiToken,
|
|
7791
|
+
direction,
|
|
7792
|
+
ecosystem,
|
|
7793
|
+
filter,
|
|
7794
|
+
outputKind,
|
|
7795
|
+
page,
|
|
7796
|
+
perPage
|
|
7797
|
+
});
|
|
7798
|
+
}
|
|
7799
|
+
async function getThreatFeedWithToken({
|
|
7565
7800
|
apiToken,
|
|
7566
7801
|
direction,
|
|
7802
|
+
ecosystem,
|
|
7567
7803
|
filter,
|
|
7568
|
-
|
|
7804
|
+
outputKind,
|
|
7569
7805
|
page,
|
|
7570
7806
|
perPage
|
|
7571
7807
|
}) {
|
|
@@ -7573,17 +7809,12 @@ async function getThreatFeed({
|
|
|
7573
7809
|
const {
|
|
7574
7810
|
spinner
|
|
7575
7811
|
} = constants;
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
page,
|
|
7580
|
-
direction,
|
|
7581
|
-
filter
|
|
7582
|
-
}).join('&');
|
|
7583
|
-
const response = await queryAPI(`threat-feed?${formattedQueryParams}`, apiToken);
|
|
7812
|
+
const queryParams = new URLSearchParams([['direction', direction], ['ecosystem', ecosystem], ['filter', filter], ['page', page], ['per_page', String(perPage)]]);
|
|
7813
|
+
spinner.start('Fetching Threat Feed data...');
|
|
7814
|
+
const response = await queryAPI(`threat-feed?${queryParams}`, apiToken);
|
|
7584
7815
|
const data = await response.json();
|
|
7585
|
-
spinner.stop();
|
|
7586
|
-
if (
|
|
7816
|
+
spinner.stop('Threat feed data fetched');
|
|
7817
|
+
if (outputKind === 'json') {
|
|
7587
7818
|
logger.logger.log(data);
|
|
7588
7819
|
return;
|
|
7589
7820
|
}
|
|
@@ -7596,47 +7827,98 @@ async function getThreatFeed({
|
|
|
7596
7827
|
interactive: 'true',
|
|
7597
7828
|
label: 'Threat feed',
|
|
7598
7829
|
width: '100%',
|
|
7599
|
-
height: '
|
|
7830
|
+
height: '70%',
|
|
7831
|
+
// Changed from 100% to 70%
|
|
7832
|
+
border: {
|
|
7833
|
+
type: 'line',
|
|
7834
|
+
fg: 'cyan'
|
|
7835
|
+
},
|
|
7836
|
+
columnWidth: [10, 30, 20, 18, 15, 200],
|
|
7837
|
+
// TODO: the truncation doesn't seem to work too well yet but when we add
|
|
7838
|
+
// `pad` alignment fails, when we extend columnSpacing alignment fails
|
|
7839
|
+
columnSpacing: 1,
|
|
7840
|
+
truncate: '_'
|
|
7841
|
+
});
|
|
7842
|
+
|
|
7843
|
+
// Create details box at the bottom
|
|
7844
|
+
const detailsBox = new BoxWidget({
|
|
7845
|
+
bottom: 0,
|
|
7846
|
+
height: '30%',
|
|
7847
|
+
width: '100%',
|
|
7600
7848
|
border: {
|
|
7601
7849
|
type: 'line',
|
|
7602
7850
|
fg: 'cyan'
|
|
7603
7851
|
},
|
|
7604
|
-
|
|
7605
|
-
|
|
7606
|
-
|
|
7852
|
+
label: 'Details',
|
|
7853
|
+
content: 'Use arrow keys to navigate. Press Enter to select a threat. Press q to exit.',
|
|
7854
|
+
style: {
|
|
7855
|
+
fg: 'white'
|
|
7856
|
+
}
|
|
7607
7857
|
});
|
|
7608
7858
|
|
|
7609
7859
|
// allow control the table with the keyboard
|
|
7610
7860
|
table.focus();
|
|
7611
7861
|
screen.append(table);
|
|
7862
|
+
screen.append(detailsBox);
|
|
7612
7863
|
const formattedOutput = formatResults(data.results);
|
|
7864
|
+
const descriptions = data.results.map(d => d.description);
|
|
7613
7865
|
table.setData({
|
|
7614
|
-
headers: ['Ecosystem', 'Name', 'Version', 'Threat type', 'Detected at', 'Details'],
|
|
7866
|
+
headers: [' Ecosystem', ' Name', ' Version', ' Threat type', ' Detected at', ' Details'],
|
|
7615
7867
|
data: formattedOutput
|
|
7616
7868
|
});
|
|
7869
|
+
|
|
7870
|
+
// Update details box when selection changes
|
|
7871
|
+
table.rows.on('select item', () => {
|
|
7872
|
+
const selectedIndex = table.rows.selected;
|
|
7873
|
+
if (selectedIndex !== undefined && selectedIndex >= 0) {
|
|
7874
|
+
const selectedRow = formattedOutput[selectedIndex];
|
|
7875
|
+
if (selectedRow) {
|
|
7876
|
+
// Note: the spacing works around issues with the table; it refuses to pad!
|
|
7877
|
+
detailsBox.setContent(`Ecosystem: ${selectedRow[0]}\n` + `Name: ${selectedRow[1]}\n` + `Version:${selectedRow[2]}\n` + `Threat type:${selectedRow[3]}\n` + `Detected at:${selectedRow[4]}\n` + `Details: ${selectedRow[5]}\n` + `Description: ${descriptions[selectedIndex]}`);
|
|
7878
|
+
screen.render();
|
|
7879
|
+
}
|
|
7880
|
+
}
|
|
7881
|
+
});
|
|
7617
7882
|
screen.render();
|
|
7618
7883
|
screen.key(['escape', 'q', 'C-c'], () => process$1.exit(0));
|
|
7884
|
+
screen.key(['return'], () => {
|
|
7885
|
+
const selectedIndex = table.rows.selected;
|
|
7886
|
+
screen.destroy();
|
|
7887
|
+
const selectedRow = formattedOutput[selectedIndex];
|
|
7888
|
+
console.log(selectedRow);
|
|
7889
|
+
});
|
|
7619
7890
|
}
|
|
7620
7891
|
function formatResults(data) {
|
|
7621
7892
|
return data.map(d => {
|
|
7622
7893
|
const ecosystem = d.purl.split('pkg:')[1].split('/')[0];
|
|
7623
7894
|
const name = d.purl.split('/')[1].split('@')[0];
|
|
7624
7895
|
const version = d.purl.split('@')[1];
|
|
7625
|
-
const
|
|
7626
|
-
|
|
7627
|
-
|
|
7628
|
-
|
|
7629
|
-
return [ecosystem, decodeURIComponent(name), version, d.threatType, hourDiff, d.locationHtmlUrl];
|
|
7896
|
+
const timeDiff = msAtHome(d.createdAt);
|
|
7897
|
+
|
|
7898
|
+
// Note: the spacing works around issues with the table; it refuses to pad!
|
|
7899
|
+
return [ecosystem, decodeURIComponent(name), ` ${version}`, ` ${d.threatType}`, ` ${timeDiff}`, d.locationHtmlUrl];
|
|
7630
7900
|
});
|
|
7631
7901
|
}
|
|
7632
|
-
function
|
|
7633
|
-
|
|
7634
|
-
|
|
7635
|
-
|
|
7636
|
-
|
|
7637
|
-
|
|
7638
|
-
|
|
7639
|
-
|
|
7902
|
+
function msAtHome(isoTimeStamp) {
|
|
7903
|
+
const timeStart = Date.parse(isoTimeStamp);
|
|
7904
|
+
const timeEnd = Date.now();
|
|
7905
|
+
const rtf = new Intl.RelativeTimeFormat('en', {
|
|
7906
|
+
numeric: 'always',
|
|
7907
|
+
style: 'short'
|
|
7908
|
+
});
|
|
7909
|
+
const delta = timeEnd - timeStart;
|
|
7910
|
+
if (delta < 60 * 60 * 1000) {
|
|
7911
|
+
return rtf.format(-Math.round(delta / (60 * 1000)), 'minute');
|
|
7912
|
+
// return Math.round(delta / (60 * 1000)) + ' min ago'
|
|
7913
|
+
} else if (delta < 24 * 60 * 60 * 1000) {
|
|
7914
|
+
return rtf.format(-(delta / (60 * 60 * 1000)).toFixed(1), 'hour');
|
|
7915
|
+
// return (delta / (60 * 60 * 1000)).toFixed(1) + ' hr ago'
|
|
7916
|
+
} else if (delta < 7 * 24 * 60 * 60 * 1000) {
|
|
7917
|
+
return rtf.format(-(delta / (24 * 60 * 60 * 1000)).toFixed(1), 'day');
|
|
7918
|
+
// return (delta / (24 * 60 * 60 * 1000)).toFixed(1) + ' day ago'
|
|
7919
|
+
} else {
|
|
7920
|
+
return isoTimeStamp.slice(0, 10);
|
|
7921
|
+
}
|
|
7640
7922
|
}
|
|
7641
7923
|
|
|
7642
7924
|
const {
|
|
@@ -7644,7 +7926,7 @@ const {
|
|
|
7644
7926
|
} = constants;
|
|
7645
7927
|
const config$1 = {
|
|
7646
7928
|
commandName: 'threat-feed',
|
|
7647
|
-
description: '
|
|
7929
|
+
description: '[beta] View the threat feed',
|
|
7648
7930
|
hidden: false,
|
|
7649
7931
|
flags: {
|
|
7650
7932
|
...commonFlags,
|
|
@@ -7667,6 +7949,12 @@ const config$1 = {
|
|
|
7667
7949
|
default: 'desc',
|
|
7668
7950
|
description: 'Order asc or desc by the createdAt attribute.'
|
|
7669
7951
|
},
|
|
7952
|
+
eco: {
|
|
7953
|
+
type: 'string',
|
|
7954
|
+
shortFlag: 'e',
|
|
7955
|
+
default: '',
|
|
7956
|
+
description: 'Only show threats for a particular ecosystem'
|
|
7957
|
+
},
|
|
7670
7958
|
filter: {
|
|
7671
7959
|
type: 'string',
|
|
7672
7960
|
shortFlag: 'f',
|
|
@@ -7678,9 +7966,35 @@ const config$1 = {
|
|
|
7678
7966
|
Usage
|
|
7679
7967
|
$ ${command}
|
|
7680
7968
|
|
|
7969
|
+
This feature requires a Threat Feed license. Please contact
|
|
7970
|
+
sales@socket.dev if you are interested in purchasing this access.
|
|
7971
|
+
|
|
7681
7972
|
Options
|
|
7682
7973
|
${getFlagListOutput(config.flags, 6)}
|
|
7683
7974
|
|
|
7975
|
+
Valid filters:
|
|
7976
|
+
|
|
7977
|
+
- anom Anomaly
|
|
7978
|
+
- c Do not filter
|
|
7979
|
+
- fp False Positives
|
|
7980
|
+
- joke Joke / Fake
|
|
7981
|
+
- mal Malware and Possible Malware [default]
|
|
7982
|
+
- secret Secrets
|
|
7983
|
+
- spy Telemetry
|
|
7984
|
+
- tp False Positives and Unreviewed
|
|
7985
|
+
- typo Typo-squat
|
|
7986
|
+
- u Unreviewed
|
|
7987
|
+
- vuln Vulnerability
|
|
7988
|
+
|
|
7989
|
+
Valid ecosystems:
|
|
7990
|
+
|
|
7991
|
+
- gem
|
|
7992
|
+
- golang
|
|
7993
|
+
- maven
|
|
7994
|
+
- npm
|
|
7995
|
+
- nuget
|
|
7996
|
+
- pypi
|
|
7997
|
+
|
|
7684
7998
|
Examples
|
|
7685
7999
|
$ ${command}
|
|
7686
8000
|
$ ${command} --perPage=5 --page=2 --direction=asc --filter=joke
|
|
@@ -7704,17 +8018,13 @@ async function run$1(argv, importMeta, {
|
|
|
7704
8018
|
logger.logger.log(DRY_RUN_BAIL_TEXT$1);
|
|
7705
8019
|
return;
|
|
7706
8020
|
}
|
|
7707
|
-
const apiToken = index.getDefaultToken();
|
|
7708
|
-
if (!apiToken) {
|
|
7709
|
-
throw new index.AuthError('User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.');
|
|
7710
|
-
}
|
|
7711
8021
|
await getThreatFeed({
|
|
7712
|
-
apiToken,
|
|
7713
8022
|
direction: String(cli.flags['direction'] || 'desc'),
|
|
8023
|
+
ecosystem: String(cli.flags['eco'] || ''),
|
|
7714
8024
|
filter: String(cli.flags['filter'] || 'mal'),
|
|
7715
|
-
|
|
7716
|
-
page: String(cli.flags['
|
|
7717
|
-
perPage: Number(cli.flags['
|
|
8025
|
+
outputKind: cli.flags['json'] ? 'json' : cli.flags['markdown'] ? 'markdown' : 'print',
|
|
8026
|
+
page: String(cli.flags['page'] || '1'),
|
|
8027
|
+
perPage: Number(cli.flags['perPage']) || 30
|
|
7718
8028
|
});
|
|
7719
8029
|
}
|
|
7720
8030
|
|
|
@@ -7801,7 +8111,7 @@ function askQuestion(rl, query) {
|
|
|
7801
8111
|
function removeSocketWrapper(file) {
|
|
7802
8112
|
return fs.readFile(file, 'utf8', function (err, data) {
|
|
7803
8113
|
if (err) {
|
|
7804
|
-
logger.logger.
|
|
8114
|
+
logger.logger.fail('There was an error removing the alias:');
|
|
7805
8115
|
logger.logger.error(err);
|
|
7806
8116
|
return;
|
|
7807
8117
|
}
|
|
@@ -7878,7 +8188,7 @@ async function run(argv, importMeta, {
|
|
|
7878
8188
|
// options or missing arguments.
|
|
7879
8189
|
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
|
|
7880
8190
|
process.exitCode = 2;
|
|
7881
|
-
logger.logger.
|
|
8191
|
+
logger.logger.fail(commonTags.stripIndents`
|
|
7882
8192
|
${colors.bgRed(colors.white('Input error'))}: Please provide the required flags:
|
|
7883
8193
|
|
|
7884
8194
|
- Must use --enabled or --disabled
|
|
@@ -7911,7 +8221,7 @@ async function run(argv, importMeta, {
|
|
|
7911
8221
|
}
|
|
7912
8222
|
}
|
|
7913
8223
|
if (!fs.existsSync(bashRcPath) && !fs.existsSync(zshRcPath)) {
|
|
7914
|
-
logger.logger.
|
|
8224
|
+
logger.logger.fail('There was an issue setting up the alias in your bash profile');
|
|
7915
8225
|
}
|
|
7916
8226
|
}
|
|
7917
8227
|
|
|
@@ -7970,10 +8280,10 @@ void (async () => {
|
|
|
7970
8280
|
let errorBody;
|
|
7971
8281
|
let errorTitle;
|
|
7972
8282
|
let errorMessage = '';
|
|
7973
|
-
if (e instanceof
|
|
8283
|
+
if (e instanceof shadowNpmInject.AuthError) {
|
|
7974
8284
|
errorTitle = 'Authentication error';
|
|
7975
8285
|
errorMessage = e.message;
|
|
7976
|
-
} else if (e instanceof
|
|
8286
|
+
} else if (e instanceof shadowNpmInject.InputError) {
|
|
7977
8287
|
errorTitle = 'Invalid input';
|
|
7978
8288
|
errorMessage = e.message;
|
|
7979
8289
|
errorBody = e.body;
|
|
@@ -7984,12 +8294,12 @@ void (async () => {
|
|
|
7984
8294
|
} else {
|
|
7985
8295
|
errorTitle = 'Unexpected error with no details';
|
|
7986
8296
|
}
|
|
7987
|
-
logger.logger.
|
|
8297
|
+
logger.logger.fail(`${colors.bgRed(colors.white(errorTitle + ':'))} ${errorMessage}`);
|
|
7988
8298
|
if (errorBody) {
|
|
7989
8299
|
logger.logger.error(`\n${errorBody}`);
|
|
7990
8300
|
}
|
|
7991
|
-
await
|
|
8301
|
+
await shadowNpmInject.captureException(e);
|
|
7992
8302
|
}
|
|
7993
8303
|
})();
|
|
7994
|
-
//# debugId=
|
|
8304
|
+
//# debugId=b5131c8e-e05e-4ce0-8d35-03afa5b09043
|
|
7995
8305
|
//# sourceMappingURL=cli.js.map
|