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