@socketsecurity/cli-with-sentry 1.14.1 → 1.15.0
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/CHANGELOG.md +13 -0
- package/README.md +31 -6
- package/dist/cli.js +355 -206
- package/dist/cli.js.map +1 -1
- package/dist/constants.js +7 -4
- package/dist/constants.js.map +1 -1
- package/dist/manifest-scripts/dotnet-tool/socket-facts-dotnet.dll +0 -0
- package/dist/manifest-scripts/maven-extension/coana-maven-extension.jar +0 -0
- package/dist/shadow-npm-bin2.js +5 -2
- package/dist/shadow-npm-bin2.js.map +1 -1
- package/dist/shadow-pnpm-bin2.js +3 -2
- package/dist/shadow-pnpm-bin2.js.map +1 -1
- package/dist/shadow-yarn-bin.js +4 -2
- package/dist/shadow-yarn-bin.js.map +1 -1
- package/dist/tsconfig.dts.tsbuildinfo +1 -1
- package/dist/types/commands/config/handle-config-set.d.mts.map +1 -1
- package/dist/types/commands/login/apply-login.d.mts.map +1 -1
- package/dist/types/commands/login/attempt-login.d.mts +5 -1
- package/dist/types/commands/login/attempt-login.d.mts.map +1 -1
- package/dist/types/commands/login/cmd-login.d.mts.map +1 -1
- package/dist/types/commands/logout/apply-logout.d.mts.map +1 -1
- package/dist/types/commands/logout/attempt-logout.d.mts +1 -1
- package/dist/types/commands/logout/attempt-logout.d.mts.map +1 -1
- package/dist/types/commands/manifest/bazel/bazel-socket-json-trust.d.mts +35 -0
- package/dist/types/commands/manifest/bazel/bazel-socket-json-trust.d.mts.map +1 -0
- package/dist/types/commands/manifest/bazel/cmd-manifest-bazel.d.mts.map +1 -1
- package/dist/types/commands/scan/fetch-report-data.d.mts +1 -8
- package/dist/types/commands/scan/fetch-report-data.d.mts.map +1 -1
- package/dist/types/commands/scan/generate-report.d.mts +1 -2
- package/dist/types/commands/scan/generate-report.d.mts.map +1 -1
- package/dist/types/commands/scan/output-scan-report.d.mts +0 -2
- package/dist/types/commands/scan/output-scan-report.d.mts.map +1 -1
- package/dist/types/constants.d.mts +4 -2
- package/dist/types/constants.d.mts.map +1 -1
- package/dist/types/shadow/npm-base.d.mts.map +1 -1
- package/dist/types/shadow/pnpm/bin.d.mts.map +1 -1
- package/dist/types/shadow/yarn/bin.d.mts.map +1 -1
- package/dist/types/utils/api-transport.d.mts +4 -0
- package/dist/types/utils/api-transport.d.mts.map +1 -0
- package/dist/types/utils/api.d.mts +2 -1
- package/dist/types/utils/api.d.mts.map +1 -1
- package/dist/types/utils/cmd.d.mts.map +1 -1
- package/dist/types/utils/coana-release.d.mts.map +1 -1
- package/dist/types/utils/config.d.mts +1 -0
- package/dist/types/utils/config.d.mts.map +1 -1
- package/dist/types/utils/oauth.d.mts +33 -0
- package/dist/types/utils/oauth.d.mts.map +1 -0
- package/dist/types/utils/package-manager.d.mts +2 -2
- package/dist/types/utils/package-manager.d.mts.map +1 -1
- package/dist/types/utils/sdk.d.mts +14 -6
- package/dist/types/utils/sdk.d.mts.map +1 -1
- package/dist/utils.js +809 -128
- package/dist/utils.js.map +1 -1
- package/dist/vendor.js +567 -567
- package/package.json +2 -2
- package/requirements.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -1194,132 +1194,60 @@ async function finalizeTier1Scan(tier1ReachabilityScanId, scanId) {
|
|
|
1194
1194
|
});
|
|
1195
1195
|
}
|
|
1196
1196
|
|
|
1197
|
-
/**
|
|
1198
|
-
* This fetches all the relevant pieces of data to generate a report, given a
|
|
1199
|
-
* full scan ID.
|
|
1200
|
-
*/
|
|
1197
|
+
/** Fetch the scan data needed to generate a report. */
|
|
1201
1198
|
async function fetchScanData(orgSlug, scanId, options) {
|
|
1202
|
-
const {
|
|
1203
|
-
includeLicensePolicy,
|
|
1204
|
-
sdkOpts
|
|
1205
|
-
} = {
|
|
1206
|
-
__proto__: null,
|
|
1207
|
-
...options
|
|
1208
|
-
};
|
|
1209
|
-
const sockSdkCResult = await utils.setupSdk(sdkOpts);
|
|
1210
|
-
if (!sockSdkCResult.ok) {
|
|
1211
|
-
return sockSdkCResult;
|
|
1212
|
-
}
|
|
1213
|
-
const sockSdk = sockSdkCResult.data;
|
|
1214
|
-
let policyStatus = 'requested...';
|
|
1215
|
-
let scanStatus = 'requested...';
|
|
1216
|
-
let finishedFetching = false;
|
|
1217
1199
|
const {
|
|
1218
1200
|
spinner
|
|
1219
1201
|
} = constants.default;
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
}
|
|
1224
|
-
function updatePolicy(status) {
|
|
1225
|
-
policyStatus = status;
|
|
1226
|
-
updateProgress();
|
|
1227
|
-
}
|
|
1228
|
-
function updateProgress() {
|
|
1229
|
-
if (finishedFetching) {
|
|
1230
|
-
spinner.stop();
|
|
1231
|
-
logger.logger.info(`Scan result: ${scanStatus}. Security policy: ${policyStatus}.`);
|
|
1232
|
-
} else {
|
|
1233
|
-
spinner.start(`Scan result: ${scanStatus}. Security policy: ${policyStatus}.`);
|
|
1234
|
-
}
|
|
1235
|
-
}
|
|
1236
|
-
async function fetchScanResult() {
|
|
1237
|
-
const result = await utils.queryApiSafeText(`orgs/${orgSlug}/full-scans/${encodeURIComponent(scanId)}${includeLicensePolicy ? '?include_license_details=true' : ''}`);
|
|
1238
|
-
updateScan(`response received`);
|
|
1202
|
+
spinner.start('Scan result: requested...');
|
|
1203
|
+
try {
|
|
1204
|
+
const result = await utils.queryApiSafeText(`orgs/${orgSlug}/full-scans/${encodeURIComponent(scanId)}${options?.includeLicensePolicy ? '?include_license_details=true' : ''}`);
|
|
1239
1205
|
if (!result.ok) {
|
|
1206
|
+
spinner.stop();
|
|
1207
|
+
logger.logger.info('Scan result: request failed.');
|
|
1240
1208
|
return result;
|
|
1241
1209
|
}
|
|
1242
|
-
const
|
|
1243
|
-
|
|
1244
|
-
// This is nd-json; each line is a json object.
|
|
1245
|
-
const lines = ndJsonString.split('\n').filter(Boolean);
|
|
1246
|
-
let ok = true;
|
|
1247
|
-
const data = lines.map(line => {
|
|
1210
|
+
const data = [];
|
|
1211
|
+
for (const line of result.data.split('\n').filter(Boolean)) {
|
|
1248
1212
|
try {
|
|
1249
|
-
|
|
1250
|
-
} catch (
|
|
1251
|
-
ok = false;
|
|
1213
|
+
data.push(JSON.parse(line));
|
|
1214
|
+
} catch (error) {
|
|
1252
1215
|
debug.debugFn('error', 'Failed to parse report data line as JSON');
|
|
1253
1216
|
debug.debugDir('error', {
|
|
1254
|
-
error
|
|
1217
|
+
error,
|
|
1255
1218
|
line
|
|
1256
1219
|
});
|
|
1257
|
-
|
|
1220
|
+
spinner.stop();
|
|
1221
|
+
logger.logger.info('Scan result: received invalid JSON response.');
|
|
1222
|
+
return {
|
|
1223
|
+
ok: false,
|
|
1224
|
+
message: 'Invalid Socket API response',
|
|
1225
|
+
cause: 'The Socket API responded with at least one line that was not valid JSON. Please report if this persists.'
|
|
1226
|
+
};
|
|
1258
1227
|
}
|
|
1259
|
-
});
|
|
1260
|
-
if (ok) {
|
|
1261
|
-
updateScan('success');
|
|
1262
|
-
return {
|
|
1263
|
-
ok: true,
|
|
1264
|
-
data
|
|
1265
|
-
};
|
|
1266
1228
|
}
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
ok: false,
|
|
1270
|
-
message: 'Invalid Socket API response',
|
|
1271
|
-
cause: 'The Socket API responded with at least one line that was not valid JSON. Please report if this persists.'
|
|
1272
|
-
};
|
|
1273
|
-
}
|
|
1274
|
-
async function fetchSecurityPolicy() {
|
|
1275
|
-
const result = await utils.handleApiCallNoSpinner(sockSdk.getOrgSecurityPolicy(orgSlug), 'GetOrgSecurityPolicy');
|
|
1276
|
-
updatePolicy('received policy');
|
|
1277
|
-
return result;
|
|
1278
|
-
}
|
|
1279
|
-
updateProgress();
|
|
1280
|
-
const [scan, securityPolicy] = await Promise.all([fetchScanResult().catch(e => {
|
|
1281
|
-
updateScan('failure; unknown blocking error occurred');
|
|
1229
|
+
spinner.stop();
|
|
1230
|
+
logger.logger.info('Scan result: success.');
|
|
1282
1231
|
return {
|
|
1283
|
-
ok:
|
|
1284
|
-
|
|
1285
|
-
|
|
1232
|
+
ok: true,
|
|
1233
|
+
data: {
|
|
1234
|
+
scan: data
|
|
1235
|
+
}
|
|
1286
1236
|
};
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1237
|
+
} catch (error) {
|
|
1238
|
+
spinner.stop();
|
|
1239
|
+
logger.logger.info('Scan result: request failed.');
|
|
1289
1240
|
return {
|
|
1290
1241
|
ok: false,
|
|
1291
1242
|
message: 'Socket API error',
|
|
1292
|
-
cause: utils.formatErrorWithDetail('Error requesting
|
|
1243
|
+
cause: utils.formatErrorWithDetail('Error requesting scan', error) || 'Error requesting scan: (no error message found)'
|
|
1293
1244
|
};
|
|
1294
|
-
})]).finally(() => {
|
|
1295
|
-
finishedFetching = true;
|
|
1296
|
-
updateProgress();
|
|
1297
|
-
});
|
|
1298
|
-
if (!scan.ok) {
|
|
1299
|
-
return scan;
|
|
1300
1245
|
}
|
|
1301
|
-
if (!securityPolicy.ok) {
|
|
1302
|
-
return securityPolicy;
|
|
1303
|
-
}
|
|
1304
|
-
if (!Array.isArray(scan.data)) {
|
|
1305
|
-
return {
|
|
1306
|
-
ok: false,
|
|
1307
|
-
message: 'Failed to fetch',
|
|
1308
|
-
cause: 'Was unable to fetch scan result, bailing'
|
|
1309
|
-
};
|
|
1310
|
-
}
|
|
1311
|
-
return {
|
|
1312
|
-
ok: true,
|
|
1313
|
-
data: {
|
|
1314
|
-
scan: scan.data,
|
|
1315
|
-
securityPolicy: securityPolicy.data
|
|
1316
|
-
}
|
|
1317
|
-
};
|
|
1318
1246
|
}
|
|
1319
1247
|
|
|
1320
1248
|
// Note: The returned cResult will only be ok:false when the generation
|
|
1321
1249
|
// failed. It won't reflect the healthy state.
|
|
1322
|
-
function generateReport(scan,
|
|
1250
|
+
function generateReport(scan, {
|
|
1323
1251
|
fold,
|
|
1324
1252
|
orgSlug,
|
|
1325
1253
|
reportLevel,
|
|
@@ -1341,7 +1269,7 @@ function generateReport(scan, securityPolicy, {
|
|
|
1341
1269
|
|
|
1342
1270
|
// In the context of a report;
|
|
1343
1271
|
// - the alert.severity is irrelevant
|
|
1344
|
-
// - the
|
|
1272
|
+
// - policy defaults are irrelevant because the API resolves actions per alert
|
|
1345
1273
|
// - the report defaults to healthy:true with no alerts
|
|
1346
1274
|
// - the appearance of an alert will trigger the policy action;
|
|
1347
1275
|
// - error: healthy will end up as false, add alerts to report
|
|
@@ -1359,61 +1287,50 @@ function generateReport(scan, securityPolicy, {
|
|
|
1359
1287
|
|
|
1360
1288
|
const violations = new Map();
|
|
1361
1289
|
let healthy = true;
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
{
|
|
1378
|
-
|
|
1379
|
-
if (!short) {
|
|
1380
|
-
addAlert(artifact, violations, fold, ecosystem, pkgName, version, alert, action);
|
|
1381
|
-
}
|
|
1382
|
-
break;
|
|
1383
|
-
}
|
|
1384
|
-
case constants.default.REPORT_LEVEL_WARN:
|
|
1385
|
-
{
|
|
1386
|
-
if (!short && reportLevel !== constants.default.REPORT_LEVEL_ERROR) {
|
|
1387
|
-
addAlert(artifact, violations, fold, ecosystem, pkgName, version, alert, action);
|
|
1388
|
-
}
|
|
1389
|
-
break;
|
|
1290
|
+
|
|
1291
|
+
// Note: reportLevel: error > warn > monitor > ignore > defer
|
|
1292
|
+
scan.forEach(artifact => {
|
|
1293
|
+
const {
|
|
1294
|
+
alerts,
|
|
1295
|
+
name: pkgName = constants.UNKNOWN_VALUE,
|
|
1296
|
+
type: ecosystem,
|
|
1297
|
+
version = constants.UNKNOWN_VALUE
|
|
1298
|
+
} = artifact;
|
|
1299
|
+
alerts?.forEach(alert => {
|
|
1300
|
+
const action = alert.action;
|
|
1301
|
+
switch (action) {
|
|
1302
|
+
case constants.default.REPORT_LEVEL_ERROR:
|
|
1303
|
+
{
|
|
1304
|
+
healthy = false;
|
|
1305
|
+
if (!short) {
|
|
1306
|
+
addAlert(artifact, violations, fold, ecosystem, pkgName, version, alert, action);
|
|
1390
1307
|
}
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1308
|
+
break;
|
|
1309
|
+
}
|
|
1310
|
+
case constants.default.REPORT_LEVEL_WARN:
|
|
1311
|
+
{
|
|
1312
|
+
if (!short && reportLevel !== constants.default.REPORT_LEVEL_ERROR) {
|
|
1313
|
+
addAlert(artifact, violations, fold, ecosystem, pkgName, version, alert, action);
|
|
1397
1314
|
}
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1315
|
+
break;
|
|
1316
|
+
}
|
|
1317
|
+
case constants.default.REPORT_LEVEL_MONITOR:
|
|
1318
|
+
{
|
|
1319
|
+
if (!short && reportLevel !== constants.default.REPORT_LEVEL_WARN && reportLevel !== constants.default.REPORT_LEVEL_ERROR) {
|
|
1320
|
+
addAlert(artifact, violations, fold, ecosystem, pkgName, version, alert, action);
|
|
1404
1321
|
}
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
break;
|
|
1322
|
+
break;
|
|
1323
|
+
}
|
|
1324
|
+
case constants.default.REPORT_LEVEL_IGNORE:
|
|
1325
|
+
{
|
|
1326
|
+
if (!short && reportLevel !== constants.default.REPORT_LEVEL_MONITOR && reportLevel !== constants.default.REPORT_LEVEL_WARN && reportLevel !== constants.default.REPORT_LEVEL_ERROR) {
|
|
1327
|
+
addAlert(artifact, violations, fold, ecosystem, pkgName, version, alert, action);
|
|
1412
1328
|
}
|
|
1413
|
-
|
|
1414
|
-
|
|
1329
|
+
break;
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1415
1332
|
});
|
|
1416
|
-
}
|
|
1333
|
+
});
|
|
1417
1334
|
spinner?.successAndStop(`Generated reported in ${Date.now() - now} ms`);
|
|
1418
1335
|
if (short) {
|
|
1419
1336
|
return {
|
|
@@ -1556,7 +1473,7 @@ async function outputScanReport(result, {
|
|
|
1556
1473
|
logger.logger.fail(utils.failMsgWithBadge(result.message, result.cause));
|
|
1557
1474
|
return;
|
|
1558
1475
|
}
|
|
1559
|
-
const scanReport = generateReport(result.data.scan,
|
|
1476
|
+
const scanReport = generateReport(result.data.scan, {
|
|
1560
1477
|
orgSlug,
|
|
1561
1478
|
scanId,
|
|
1562
1479
|
fold,
|
|
@@ -9652,6 +9569,11 @@ async function handleConfigSet({
|
|
|
9652
9569
|
outputKind
|
|
9653
9570
|
});
|
|
9654
9571
|
const result = utils.updateConfigValue(key, value);
|
|
9572
|
+
if (result.ok && !result.data && key === constants.CONFIG_KEY_API_TOKEN) {
|
|
9573
|
+
// An explicit API-token update must take precedence over a saved OAuth
|
|
9574
|
+
// session, which otherwise remains the active credential source.
|
|
9575
|
+
utils.updateConfigValue(constants.CONFIG_KEY_AUTH_TYPE, 'api-token');
|
|
9576
|
+
}
|
|
9655
9577
|
|
|
9656
9578
|
// `config set` is a one-shot command: an in-memory-only change is a no-op
|
|
9657
9579
|
// because the process exits before anything reads it. updateConfigValue only
|
|
@@ -12047,13 +11969,20 @@ async function run$M(argv, importMeta, {
|
|
|
12047
11969
|
function applyLogin(apiToken, enforcedOrgs, apiBaseUrl, apiProxy) {
|
|
12048
11970
|
utils.updateConfigValue(constants.CONFIG_KEY_ENFORCED_ORGS, enforcedOrgs);
|
|
12049
11971
|
utils.updateConfigValue(constants.CONFIG_KEY_API_TOKEN, apiToken);
|
|
11972
|
+
utils.updateConfigValue(constants.CONFIG_KEY_AUTH_TYPE, 'api-token');
|
|
12050
11973
|
utils.updateConfigValue(constants.CONFIG_KEY_API_BASE_URL, apiBaseUrl);
|
|
12051
11974
|
utils.updateConfigValue(constants.CONFIG_KEY_API_PROXY, apiProxy);
|
|
12052
11975
|
}
|
|
12053
11976
|
|
|
12054
|
-
async function attemptLogin(apiBaseUrl, apiProxy) {
|
|
11977
|
+
async function attemptLogin(apiBaseUrl, apiProxy, apiTokenMode = false) {
|
|
11978
|
+
if (!apiTokenMode) {
|
|
11979
|
+
return await attemptOAuthLogin(apiBaseUrl, apiProxy);
|
|
11980
|
+
}
|
|
11981
|
+
return await attemptApiTokenLogin(apiBaseUrl, apiProxy);
|
|
11982
|
+
}
|
|
11983
|
+
async function attemptApiTokenLogin(apiBaseUrl, apiProxy) {
|
|
12055
11984
|
apiBaseUrl ??= utils.getConfigValueOrUndef(constants.CONFIG_KEY_API_BASE_URL) ?? undefined;
|
|
12056
|
-
apiProxy
|
|
11985
|
+
apiProxy ||= utils.getDefaultProxyUrl();
|
|
12057
11986
|
const apiTokenInput = await prompts.password({
|
|
12058
11987
|
message: `Enter your ${utils.socketDocsLink('/docs/api-keys', 'Socket.dev API token')} (leave blank to use a limited public token)`
|
|
12059
11988
|
});
|
|
@@ -12171,6 +12100,18 @@ async function attemptLogin(apiBaseUrl, apiProxy) {
|
|
|
12171
12100
|
const previousPersistedToken = utils.getConfigValueOrUndef(constants.CONFIG_KEY_API_TOKEN);
|
|
12172
12101
|
try {
|
|
12173
12102
|
applyLogin(apiToken, enforcedOrgs, apiBaseUrl, apiProxy);
|
|
12103
|
+
if (constants.default.socketAppDataPath && !utils.isConfigFromFlag()) {
|
|
12104
|
+
try {
|
|
12105
|
+
const result = await utils.logoutOAuth(constants.default.socketAppDataPath, {
|
|
12106
|
+
apiProxy
|
|
12107
|
+
});
|
|
12108
|
+
if (result.warning) {
|
|
12109
|
+
logger.logger.warn(result.warning);
|
|
12110
|
+
}
|
|
12111
|
+
} catch {
|
|
12112
|
+
logger.logger.warn('The previous browser sign-in could not be removed.');
|
|
12113
|
+
}
|
|
12114
|
+
}
|
|
12174
12115
|
logger.logger.success(`API credentials ${previousPersistedToken === apiToken ? 'refreshed' : previousPersistedToken ? 'updated' : 'set'}`);
|
|
12175
12116
|
if (utils.isConfigFromFlag()) {
|
|
12176
12117
|
logger.logger.log('');
|
|
@@ -12178,12 +12119,103 @@ async function attemptLogin(apiBaseUrl, apiProxy) {
|
|
|
12178
12119
|
}
|
|
12179
12120
|
} catch {
|
|
12180
12121
|
process.exitCode = 1;
|
|
12181
|
-
logger.logger.fail(
|
|
12122
|
+
logger.logger.fail('API login failed');
|
|
12123
|
+
}
|
|
12124
|
+
}
|
|
12125
|
+
async function attemptOAuthLogin(apiBaseUrl, apiProxy) {
|
|
12126
|
+
if (utils.isConfigFromFlag()) {
|
|
12127
|
+
throw new Error('Browser sign-in cannot be saved while --config or SOCKET_CLI_CONFIG is active. Remove the config override and run `socket login` again.');
|
|
12128
|
+
}
|
|
12129
|
+
const configuredBaseUrl = apiBaseUrl || utils.getDefaultApiBaseUrl();
|
|
12130
|
+
if (configuredBaseUrl) {
|
|
12131
|
+
let configuredOrigin;
|
|
12132
|
+
try {
|
|
12133
|
+
configuredOrigin = new URL(configuredBaseUrl).origin;
|
|
12134
|
+
} catch {
|
|
12135
|
+
throw new Error('The configured Socket API URL is invalid for OAuth.');
|
|
12136
|
+
}
|
|
12137
|
+
if (configuredOrigin !== utils.OAUTH_ISSUER) {
|
|
12138
|
+
throw new Error('Browser sign-in is only available with Socket’s trusted API URL. Use `socket login --api-token --api-base-url <url>` for a custom API URL.');
|
|
12139
|
+
}
|
|
12140
|
+
}
|
|
12141
|
+
const existingToken = utils.getConfigValueOrUndef(constants.CONFIG_KEY_API_TOKEN);
|
|
12142
|
+
const activeAuthType = utils.getConfigValueOrUndef(constants.CONFIG_KEY_AUTH_TYPE);
|
|
12143
|
+
if (existingToken && activeAuthType !== 'oauth') {
|
|
12144
|
+
const choice = await prompts.select({
|
|
12145
|
+
message: 'An API token is already saved. Keep using it or switch to read-only browser sign-in?',
|
|
12146
|
+
choices: [{
|
|
12147
|
+
name: 'Keep the saved API token',
|
|
12148
|
+
value: 'keep'
|
|
12149
|
+
}, {
|
|
12150
|
+
name: 'Switch to browser sign-in (read-only)',
|
|
12151
|
+
value: 'oauth'
|
|
12152
|
+
}]
|
|
12153
|
+
});
|
|
12154
|
+
if (choice === undefined) {
|
|
12155
|
+
logger.logger.fail('Canceled by user');
|
|
12156
|
+
return {
|
|
12157
|
+
ok: false,
|
|
12158
|
+
message: 'Canceled',
|
|
12159
|
+
cause: 'Canceled by user'
|
|
12160
|
+
};
|
|
12161
|
+
}
|
|
12162
|
+
if (choice === 'keep') {
|
|
12163
|
+
logger.logger.success('Kept the saved API token login');
|
|
12164
|
+
return {
|
|
12165
|
+
ok: true
|
|
12166
|
+
};
|
|
12167
|
+
}
|
|
12168
|
+
}
|
|
12169
|
+
apiProxy ||= utils.getDefaultProxyUrl();
|
|
12170
|
+
const result = await utils.beginOAuthLogin({
|
|
12171
|
+
apiProxy,
|
|
12172
|
+
openBrowser: true,
|
|
12173
|
+
onAuthorizationUrl(url) {
|
|
12174
|
+
logger.logger.log('Open this URL in your browser to sign in:');
|
|
12175
|
+
logger.logger.log(url);
|
|
12176
|
+
}
|
|
12177
|
+
});
|
|
12178
|
+
const baseUrl = new URL('/v0/', result.apiOrigin).href;
|
|
12179
|
+
const sdkResult = await utils.setupSdk({
|
|
12180
|
+
apiBaseUrl: baseUrl,
|
|
12181
|
+
apiProxy,
|
|
12182
|
+
apiToken: result.accessToken
|
|
12183
|
+
});
|
|
12184
|
+
if (!sdkResult.ok) {
|
|
12185
|
+
process.exitCode = 1;
|
|
12186
|
+
logger.logger.fail(utils.failMsgWithBadge(sdkResult.message, sdkResult.cause));
|
|
12187
|
+
return;
|
|
12188
|
+
}
|
|
12189
|
+
const orgsResult = await utils.fetchOrganization({
|
|
12190
|
+
description: 'browser sign-in validation',
|
|
12191
|
+
sdk: sdkResult.data
|
|
12192
|
+
});
|
|
12193
|
+
if (!orgsResult.ok) {
|
|
12194
|
+
process.exitCode = 1;
|
|
12195
|
+
logger.logger.fail(utils.failMsgWithBadge(orgsResult.message, orgsResult.cause));
|
|
12196
|
+
return;
|
|
12197
|
+
}
|
|
12198
|
+
const orgSlugs = utils.getOrgSlugs(orgsResult.data.organizations);
|
|
12199
|
+
if (orgSlugs.length === 0) {
|
|
12200
|
+
process.exitCode = 1;
|
|
12201
|
+
logger.logger.fail('Browser sign-in succeeded, but no accessible organization was returned. Check your organization membership and try again; existing credentials were kept.');
|
|
12202
|
+
return;
|
|
12203
|
+
}
|
|
12204
|
+
await utils.saveOAuthCredentials(constants.default.socketAppDataPath, result);
|
|
12205
|
+
utils.updateConfigValue(constants.CONFIG_KEY_API_TOKEN, null);
|
|
12206
|
+
utils.updateConfigValue(constants.CONFIG_KEY_DEFAULT_ORG, orgSlugs[0]);
|
|
12207
|
+
utils.updateConfigValue(constants.CONFIG_KEY_API_BASE_URL, null);
|
|
12208
|
+
utils.updateConfigValue(constants.CONFIG_KEY_API_PROXY, apiProxy);
|
|
12209
|
+
utils.updateConfigValue(constants.CONFIG_KEY_AUTH_TYPE, 'oauth');
|
|
12210
|
+
logger.logger.success(`Browser sign-in saved for ${arrays.joinAnd(orgSlugs)}`);
|
|
12211
|
+
logger.logger.warn('This sign-in is read-only and supports package, alert, and threat-feed queries. Write and scan commands require API-token credentials; use `socket login --api-token` or SOCKET_CLI_API_TOKEN.');
|
|
12212
|
+
if (constants.default.ENV.SOCKET_CLI_API_TOKEN) {
|
|
12213
|
+
logger.logger.warn('SOCKET_CLI_API_TOKEN remains active and takes precedence over browser sign-in for this session.');
|
|
12182
12214
|
}
|
|
12183
12215
|
}
|
|
12184
12216
|
|
|
12185
12217
|
const CMD_NAME$r = 'login';
|
|
12186
|
-
const description$x = '
|
|
12218
|
+
const description$x = 'Sign in to Socket and configure the CLI';
|
|
12187
12219
|
const hidden$r = false;
|
|
12188
12220
|
const cmdLogin = {
|
|
12189
12221
|
description: description$x,
|
|
@@ -12199,10 +12231,15 @@ async function run$L(argv, importMeta, {
|
|
|
12199
12231
|
hidden: hidden$r,
|
|
12200
12232
|
flags: {
|
|
12201
12233
|
...flags.commonFlags,
|
|
12234
|
+
apiToken: {
|
|
12235
|
+
type: 'boolean',
|
|
12236
|
+
default: false,
|
|
12237
|
+
description: 'Use masked API-token login for scans and write commands'
|
|
12238
|
+
},
|
|
12202
12239
|
apiBaseUrl: {
|
|
12203
12240
|
type: 'string',
|
|
12204
12241
|
default: '',
|
|
12205
|
-
description: 'API server
|
|
12242
|
+
description: 'API server for API-token login'
|
|
12206
12243
|
},
|
|
12207
12244
|
apiProxy: {
|
|
12208
12245
|
type: 'string',
|
|
@@ -12217,13 +12254,16 @@ async function run$L(argv, importMeta, {
|
|
|
12217
12254
|
API Token Requirements
|
|
12218
12255
|
${utils.getFlagApiRequirementsOutput(`${parentName}:${CMD_NAME$r}`)}
|
|
12219
12256
|
|
|
12220
|
-
|
|
12257
|
+
By default, opens a browser for read-only package, alert, and threat-feed
|
|
12258
|
+
access. Use --api-token for scans and write operations. A sign-in URL is
|
|
12259
|
+
printed so you can open it manually if the browser does not launch.
|
|
12221
12260
|
|
|
12222
12261
|
Options
|
|
12223
12262
|
${utils.getFlagListOutput(config.flags)}
|
|
12224
12263
|
|
|
12225
12264
|
Examples
|
|
12226
12265
|
$ ${command}
|
|
12266
|
+
$ ${command} --api-token
|
|
12227
12267
|
$ ${command} --api-proxy=http://localhost:1234
|
|
12228
12268
|
`
|
|
12229
12269
|
};
|
|
@@ -12238,33 +12278,53 @@ async function run$L(argv, importMeta, {
|
|
|
12238
12278
|
logger.logger.log(constants.default.DRY_RUN_BAILING_NOW);
|
|
12239
12279
|
return;
|
|
12240
12280
|
}
|
|
12281
|
+
const apiTokenMode = !!cli.flags['apiToken'];
|
|
12241
12282
|
if (!vendor.isInteractiveExports()) {
|
|
12242
|
-
throw new utils.InputError('
|
|
12283
|
+
throw new utils.InputError('Login requires an interactive terminal. Set SOCKET_CLI_API_TOKEN for automation.');
|
|
12243
12284
|
}
|
|
12244
12285
|
const {
|
|
12245
12286
|
apiBaseUrl,
|
|
12246
12287
|
apiProxy
|
|
12247
12288
|
} = cli.flags;
|
|
12248
|
-
await attemptLogin(apiBaseUrl, apiProxy);
|
|
12289
|
+
await attemptLogin(apiBaseUrl, apiProxy, apiTokenMode);
|
|
12249
12290
|
}
|
|
12250
12291
|
|
|
12251
12292
|
function applyLogout() {
|
|
12252
12293
|
utils.updateConfigValue(constants.CONFIG_KEY_API_TOKEN, null);
|
|
12294
|
+
utils.updateConfigValue(constants.CONFIG_KEY_AUTH_TYPE, null);
|
|
12253
12295
|
utils.updateConfigValue(constants.CONFIG_KEY_API_BASE_URL, null);
|
|
12254
12296
|
utils.updateConfigValue(constants.CONFIG_KEY_API_PROXY, null);
|
|
12255
12297
|
utils.updateConfigValue(constants.CONFIG_KEY_ENFORCED_ORGS, null);
|
|
12256
12298
|
}
|
|
12257
12299
|
|
|
12258
|
-
function attemptLogout() {
|
|
12300
|
+
async function attemptLogout() {
|
|
12301
|
+
let warning;
|
|
12259
12302
|
try {
|
|
12260
|
-
|
|
12303
|
+
const directory = constants.default.socketAppDataPath;
|
|
12304
|
+
try {
|
|
12305
|
+
if (directory && !utils.isConfigFromFlag()) {
|
|
12306
|
+
const result = await utils.logoutOAuth(directory, {
|
|
12307
|
+
apiProxy: utils.getDefaultProxyUrl()
|
|
12308
|
+
});
|
|
12309
|
+
warning = result.warning;
|
|
12310
|
+
}
|
|
12311
|
+
} finally {
|
|
12312
|
+
applyLogout();
|
|
12313
|
+
}
|
|
12261
12314
|
logger.logger.success('Successfully logged out');
|
|
12315
|
+
if (warning) {
|
|
12316
|
+
logger.logger.warn(`Local sign-out completed. ${warning}`);
|
|
12317
|
+
}
|
|
12318
|
+
if (constants.default.ENV.SOCKET_CLI_API_TOKEN) {
|
|
12319
|
+
logger.logger.warn('SOCKET_CLI_API_TOKEN remains active and takes precedence until it is unset.');
|
|
12320
|
+
}
|
|
12262
12321
|
if (utils.isConfigFromFlag()) {
|
|
12263
12322
|
logger.logger.log('');
|
|
12264
12323
|
logger.logger.warn('Note: config is in read-only mode, at least one key was overridden through flag/env, so the logout was not persisted!');
|
|
12265
12324
|
}
|
|
12266
|
-
} catch {
|
|
12325
|
+
} catch (error) {
|
|
12267
12326
|
logger.logger.fail('Failed to complete logout steps');
|
|
12327
|
+
logger.logger.warn(utils.getErrorCause(error));
|
|
12268
12328
|
}
|
|
12269
12329
|
}
|
|
12270
12330
|
|
|
@@ -12304,7 +12364,7 @@ async function run$K(argv, importMeta, {
|
|
|
12304
12364
|
logger.logger.log(constants.default.DRY_RUN_BAILING_NOW);
|
|
12305
12365
|
return;
|
|
12306
12366
|
}
|
|
12307
|
-
attemptLogout();
|
|
12367
|
+
await attemptLogout();
|
|
12308
12368
|
}
|
|
12309
12369
|
|
|
12310
12370
|
const {
|
|
@@ -12705,6 +12765,90 @@ async function run$J(argv, importMeta, context) {
|
|
|
12705
12765
|
await spawnPromise;
|
|
12706
12766
|
}
|
|
12707
12767
|
|
|
12768
|
+
function canonicalizeForContainment(filePath) {
|
|
12769
|
+
let existingPath = path.resolve(filePath);
|
|
12770
|
+
const missingSegments = [];
|
|
12771
|
+
while (!u.existsSync(existingPath)) {
|
|
12772
|
+
const parent = path.dirname(existingPath);
|
|
12773
|
+
if (parent === existingPath) {
|
|
12774
|
+
break;
|
|
12775
|
+
}
|
|
12776
|
+
missingSegments.unshift(path.basename(existingPath));
|
|
12777
|
+
existingPath = parent;
|
|
12778
|
+
}
|
|
12779
|
+
return path.join(u.realpathSync(existingPath), ...missingSegments);
|
|
12780
|
+
}
|
|
12781
|
+
function readSetting(cliValue, socketJsonValue, flag, trustSocketJson, refusedFields, socketJsonDefaults) {
|
|
12782
|
+
if (typeof cliValue === 'string' && cliValue.length > 0) {
|
|
12783
|
+
return cliValue;
|
|
12784
|
+
}
|
|
12785
|
+
if (typeof socketJsonValue !== 'string' || socketJsonValue.length === 0) {
|
|
12786
|
+
return undefined;
|
|
12787
|
+
}
|
|
12788
|
+
if (!trustSocketJson) {
|
|
12789
|
+
refusedFields.push(flag);
|
|
12790
|
+
return undefined;
|
|
12791
|
+
}
|
|
12792
|
+
socketJsonDefaults.push({
|
|
12793
|
+
flag,
|
|
12794
|
+
value: socketJsonValue
|
|
12795
|
+
});
|
|
12796
|
+
return socketJsonValue;
|
|
12797
|
+
}
|
|
12798
|
+
function resolveBazelManifestSettings({
|
|
12799
|
+
cli,
|
|
12800
|
+
cwd,
|
|
12801
|
+
socketJson,
|
|
12802
|
+
trustSocketJson
|
|
12803
|
+
}) {
|
|
12804
|
+
const config = socketJson.defaults?.manifest?.bazel ?? {};
|
|
12805
|
+
const refusedFields = [];
|
|
12806
|
+
const socketJsonDefaults = [];
|
|
12807
|
+
const bazel = readSetting(cli.bazel, config.bazel ?? config.bin, '--bazel', trustSocketJson, refusedFields, socketJsonDefaults);
|
|
12808
|
+
const bazelFlags = readSetting(cli.bazelFlags, config.bazelFlags, '--bazel-flags', trustSocketJson, refusedFields, socketJsonDefaults);
|
|
12809
|
+
const bazelOutputBase = readSetting(cli.bazelOutputBase, config.bazelOutputBase, '--bazel-output-base', trustSocketJson, refusedFields, socketJsonDefaults);
|
|
12810
|
+
const bazelRc = readSetting(cli.bazelRc, config.bazelRc, '--bazel-rc', trustSocketJson, refusedFields, socketJsonDefaults);
|
|
12811
|
+
if (refusedFields.length > 0) {
|
|
12812
|
+
return {
|
|
12813
|
+
ok: false,
|
|
12814
|
+
message: `Refused bazel settings chosen by ${constants.SOCKET_JSON}`,
|
|
12815
|
+
cause: [`${constants.SOCKET_JSON} in ${cwd} sets ${refusedFields.join(', ')}.`, 'Saw repository-supplied bazel execution settings, wanted none.', 'These values choose the Bazel executable and its options, and the scanned repository controls its own socket.json.', 'Fix: pass --bazel, --bazel-flags, --bazel-rc, or --bazel-output-base on the command line, or re-run with --trust-socket-json.'].join('\n')
|
|
12816
|
+
};
|
|
12817
|
+
}
|
|
12818
|
+
const cliOut = typeof cli.out === 'string' ? cli.out : undefined;
|
|
12819
|
+
const socketJsonOut = config.out;
|
|
12820
|
+
const outFromSocketJson = !cliOut && typeof socketJsonOut === 'string';
|
|
12821
|
+
const outValue = cliOut ?? socketJsonOut;
|
|
12822
|
+
const resolvedOut = outValue ? path.resolve(cwd, outValue) : path.join(cwd, '.socket', 'bazel-manifests');
|
|
12823
|
+
const canonicalCwd = canonicalizeForContainment(cwd);
|
|
12824
|
+
const canonicalOut = canonicalizeForContainment(resolvedOut);
|
|
12825
|
+
const relativeOut = path.relative(canonicalCwd, canonicalOut);
|
|
12826
|
+
if (outFromSocketJson && !trustSocketJson && (relativeOut === '..' || relativeOut.startsWith(`..${path.sep}`) || path.isAbsolute(relativeOut))) {
|
|
12827
|
+
return {
|
|
12828
|
+
ok: false,
|
|
12829
|
+
message: `Refused a bazel output path chosen by ${constants.SOCKET_JSON}`,
|
|
12830
|
+
cause: [`${constants.SOCKET_JSON} in ${cwd} sets defaults.manifest.bazel.out.`, `Saw \`${socketJsonOut}\` (resolves to ${resolvedOut}), wanted a path inside ${cwd}.`, 'The CLI writes generated manifests there, so a scanned repository must not choose an output path outside the project.', `Fix: pass --out=${socketJsonOut} if you trust this path, or re-run with --trust-socket-json to honor the setting.`].join('\n')
|
|
12831
|
+
};
|
|
12832
|
+
}
|
|
12833
|
+
if (outFromSocketJson) {
|
|
12834
|
+
socketJsonDefaults.push({
|
|
12835
|
+
flag: '--out',
|
|
12836
|
+
value: resolvedOut
|
|
12837
|
+
});
|
|
12838
|
+
}
|
|
12839
|
+
return {
|
|
12840
|
+
ok: true,
|
|
12841
|
+
data: {
|
|
12842
|
+
bazel,
|
|
12843
|
+
bazelFlags: bazelFlags ?? '',
|
|
12844
|
+
bazelOutputBase,
|
|
12845
|
+
bazelRc,
|
|
12846
|
+
out: resolvedOut,
|
|
12847
|
+
socketJsonDefaults
|
|
12848
|
+
}
|
|
12849
|
+
};
|
|
12850
|
+
}
|
|
12851
|
+
|
|
12708
12852
|
// Result shape returned by `validatePypiHub`. Kept local to the PyPI module
|
|
12709
12853
|
// since validation here is hub-alias-marker based (different from the
|
|
12710
12854
|
// Maven-side tri-state classifier).
|
|
@@ -13714,6 +13858,11 @@ const config$h = {
|
|
|
13714
13858
|
type: 'number',
|
|
13715
13859
|
description: 'Per-hub bazel cquery timeout in milliseconds; default: 120000'
|
|
13716
13860
|
},
|
|
13861
|
+
trustSocketJson: {
|
|
13862
|
+
type: 'boolean',
|
|
13863
|
+
default: false,
|
|
13864
|
+
description: `Run Bazel settings declared in ${constants.SOCKET_JSON}. Off by default because the scanned repository controls that file.`
|
|
13865
|
+
},
|
|
13717
13866
|
verbose: {
|
|
13718
13867
|
type: 'boolean',
|
|
13719
13868
|
description: 'Emit bounded Bazel diagnostics with argv, duration, exit status, and output sizes'
|
|
@@ -13735,6 +13884,11 @@ const config$h = {
|
|
|
13735
13884
|
--ecosystem may be repeated to select which ecosystems to extract.
|
|
13736
13885
|
When omitted, Maven is generated by default. PyPI is explicit opt-in.
|
|
13737
13886
|
|
|
13887
|
+
A ${constants.SOCKET_JSON} that sets \`bazel\`/\`bin\`, \`bazelFlags\`, \`bazelRc\`, or
|
|
13888
|
+
\`bazelOutputBase\`, or an \`out\` outside the project, is refused unless
|
|
13889
|
+
you pass --trust-socket-json. Pass the matching command-line flags to
|
|
13890
|
+
override these defaults without trusting ${constants.SOCKET_JSON}.
|
|
13891
|
+
|
|
13738
13892
|
Note: this command generates dependency manifests for Bazel workspaces.
|
|
13739
13893
|
It does not run reachability analysis.
|
|
13740
13894
|
|
|
@@ -13898,53 +14052,48 @@ async function run$I(argv, importMeta, {
|
|
|
13898
14052
|
verbose
|
|
13899
14053
|
} = cli.flags;
|
|
13900
14054
|
let perRepoTimeout = cli.flags['perRepoTimeout'];
|
|
13901
|
-
|
|
13902
|
-
|
|
13903
|
-
|
|
13904
|
-
|
|
13905
|
-
|
|
13906
|
-
|
|
13907
|
-
|
|
13908
|
-
|
|
13909
|
-
|
|
13910
|
-
|
|
13911
|
-
|
|
13912
|
-
|
|
13913
|
-
|
|
13914
|
-
|
|
13915
|
-
if (
|
|
13916
|
-
|
|
13917
|
-
logger.logger.info(`Using default --bazel-flags from ${constants.SOCKET_JSON}:`, bazelFlags);
|
|
14055
|
+
const settings = resolveBazelManifestSettings({
|
|
14056
|
+
cli: {
|
|
14057
|
+
bazel,
|
|
14058
|
+
bazelFlags,
|
|
14059
|
+
bazelOutputBase,
|
|
14060
|
+
bazelRc,
|
|
14061
|
+
out
|
|
14062
|
+
},
|
|
14063
|
+
cwd,
|
|
14064
|
+
socketJson: sockJson,
|
|
14065
|
+
trustSocketJson: Boolean(cli.flags['trustSocketJson'])
|
|
14066
|
+
});
|
|
14067
|
+
if (!settings.ok) {
|
|
14068
|
+
process.exitCode = 1;
|
|
14069
|
+
if (outputKind === 'json') {
|
|
14070
|
+
logger.logger.log(utils.serializeResultJson(settings));
|
|
13918
14071
|
} else {
|
|
13919
|
-
|
|
13920
|
-
}
|
|
13921
|
-
}
|
|
13922
|
-
if (!bazelOutputBase) {
|
|
13923
|
-
if (sockJson.defaults?.manifest?.bazel?.bazelOutputBase) {
|
|
13924
|
-
bazelOutputBase = sockJson.defaults?.manifest?.bazel?.bazelOutputBase;
|
|
13925
|
-
logger.logger.info(`Using default --bazel-output-base from ${constants.SOCKET_JSON}:`, bazelOutputBase);
|
|
14072
|
+
logger.logger.fail(utils.failMsgWithBadge(settings.message, settings.cause));
|
|
13926
14073
|
}
|
|
14074
|
+
return;
|
|
13927
14075
|
}
|
|
13928
|
-
|
|
13929
|
-
|
|
13930
|
-
|
|
13931
|
-
|
|
13932
|
-
}
|
|
14076
|
+
for (const {
|
|
14077
|
+
flag,
|
|
14078
|
+
value
|
|
14079
|
+
} of settings.data.socketJsonDefaults) {
|
|
14080
|
+
logger.logger.info(`Using default ${flag} from ${constants.SOCKET_JSON}:`, value);
|
|
13933
14081
|
}
|
|
13934
|
-
|
|
13935
|
-
|
|
13936
|
-
|
|
13937
|
-
|
|
13938
|
-
|
|
13939
|
-
|
|
13940
|
-
|
|
14082
|
+
bazel = settings.data.bazel;
|
|
14083
|
+
bazelFlags = settings.data.bazelFlags;
|
|
14084
|
+
bazelOutputBase = settings.data.bazelOutputBase;
|
|
14085
|
+
bazelRc = settings.data.bazelRc;
|
|
14086
|
+
out = settings.data.out;
|
|
14087
|
+
|
|
14088
|
+
// Set defaults for any flag/arg that is not given. Check socket.json first.
|
|
14089
|
+
if (bazel && cli.flags['bazel']) {
|
|
14090
|
+
bazel = path.resolve(process.cwd(), String(bazel));
|
|
13941
14091
|
}
|
|
14092
|
+
bazelFlags ??= '';
|
|
13942
14093
|
if (verbose === undefined) {
|
|
14094
|
+
verbose = sockJson.defaults?.manifest?.bazel?.verbose ?? false;
|
|
13943
14095
|
if (sockJson.defaults?.manifest?.bazel?.verbose !== undefined) {
|
|
13944
|
-
verbose = sockJson.defaults?.manifest?.bazel?.verbose;
|
|
13945
14096
|
logger.logger.info(`Using default --verbose from ${constants.SOCKET_JSON}:`, verbose);
|
|
13946
|
-
} else {
|
|
13947
|
-
verbose = false;
|
|
13948
14097
|
}
|
|
13949
14098
|
}
|
|
13950
14099
|
if (perRepoTimeout === undefined) {
|
|
@@ -25599,7 +25748,7 @@ function addSocketWrapper(file) {
|
|
|
25599
25748
|
return new Error(`There was an error setting up the alias: ${err}`);
|
|
25600
25749
|
}
|
|
25601
25750
|
logger.logger.success(`The alias was added to ${file}. Running 'npm install' will now be wrapped in Socket's "safe npm" 🎉`);
|
|
25602
|
-
logger.logger.log(` If you want to disable it at any time, run \`socket wrapper
|
|
25751
|
+
logger.logger.log(` If you want to disable it at any time, run \`socket wrapper off\``);
|
|
25603
25752
|
logger.logger.log('');
|
|
25604
25753
|
logger.logger.info(`This will only be active in new terminal sessions going forward.`);
|
|
25605
25754
|
logger.logger.log(` You will need to restart your terminal or run this command to activate the alias in the current session:`);
|
|
@@ -26143,5 +26292,5 @@ process.on('unhandledRejection', async (reason, promise) => {
|
|
|
26143
26292
|
// eslint-disable-next-line n/no-process-exit
|
|
26144
26293
|
process.exit(1);
|
|
26145
26294
|
});
|
|
26146
|
-
//# debugId=
|
|
26295
|
+
//# debugId=f0475874-f135-4a6b-aa96-64e325d96f5f
|
|
26147
26296
|
//# sourceMappingURL=cli.js.map
|