socket 0.15.32 → 0.15.34
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/dist/cli.js +297 -141
- package/dist/cli.js.map +1 -1
- package/dist/constants.js +3 -3
- package/dist/constants.js.map +1 -1
- package/dist/shadow-inject.js.map +1 -1
- package/dist/utils.js +128 -95
- package/dist/utils.js.map +1 -1
- package/external/@socketsecurity/registry/external/@inquirer/confirm.js +0 -1
- package/external/@socketsecurity/registry/external/@inquirer/input.js +0 -1
- package/external/@socketsecurity/registry/external/@inquirer/password.js +0 -1
- package/external/@socketsecurity/registry/external/@inquirer/search.js +0 -1
- package/external/@socketsecurity/registry/external/@inquirer/select.js +0 -1
- package/external/@socketsecurity/registry/external/@npmcli/package-json/index.js +0 -1
- package/external/@socketsecurity/registry/external/@npmcli/package-json/lib/read-package.js +0 -1
- package/external/@socketsecurity/registry/external/@npmcli/package-json/lib/sort.js +0 -1
- package/external/@socketsecurity/registry/external/@npmcli/promise-spawn.js +0 -1
- package/external/@socketsecurity/registry/external/@socketregistry/is-unicode-supported.js +0 -1
- package/external/@socketsecurity/registry/external/@socketregistry/packageurl-js.js +0 -1
- package/external/@socketsecurity/registry/external/@socketregistry/yocto-spinner.js +0 -1
- package/external/@socketsecurity/registry/external/@yarnpkg/extensions.js +0 -1
- package/external/@socketsecurity/registry/external/browserslist.js +0 -1
- package/external/@socketsecurity/registry/external/cacache.js +0 -1
- package/external/@socketsecurity/registry/external/fast-sort.js +0 -1
- package/external/@socketsecurity/registry/external/libnpmpack.js +0 -1
- package/external/@socketsecurity/registry/external/make-fetch-happen.js +0 -1
- package/external/@socketsecurity/registry/external/normalize-package-data.js +0 -1
- package/external/@socketsecurity/registry/external/npm-package-arg.js +0 -1
- package/external/@socketsecurity/registry/external/pacote.js +0 -1
- package/external/@socketsecurity/registry/external/picomatch.js +0 -1
- package/external/@socketsecurity/registry/external/semver.js +0 -1
- package/external/@socketsecurity/registry/external/signal-exit.js +0 -1
- package/external/@socketsecurity/registry/external/spdx-correct.js +0 -1
- package/external/@socketsecurity/registry/external/spdx-expression-parse.js +0 -1
- package/external/@socketsecurity/registry/external/tinyglobby.js +0 -1
- package/external/@socketsecurity/registry/external/validate-npm-package-name.js +0 -1
- package/external/@socketsecurity/registry/external/which.js +0 -1
- package/external/@socketsecurity/registry/external/yoctocolors-cjs.js +0 -1
- package/external/@socketsecurity/registry/lib/debug.js +37 -9
- package/package.json +4 -4
package/dist/cli.js
CHANGED
|
@@ -630,7 +630,7 @@ ${table}
|
|
|
630
630
|
process.exitCode = 1;
|
|
631
631
|
logger.logger.fail('There was a problem converting the logs to Markdown, please try the `--json` flag');
|
|
632
632
|
if (debug.isDebug()) {
|
|
633
|
-
debug.debugFn('
|
|
633
|
+
debug.debugFn('catch: unexpected\n', e);
|
|
634
634
|
}
|
|
635
635
|
return '';
|
|
636
636
|
}
|
|
@@ -1151,7 +1151,7 @@ async function run$O(argv, importMeta, {
|
|
|
1151
1151
|
async function getDefaultOrgSlug() {
|
|
1152
1152
|
const defaultOrgResult = utils.getConfigValueOrUndef('defaultOrg');
|
|
1153
1153
|
if (defaultOrgResult) {
|
|
1154
|
-
debug.debugFn('
|
|
1154
|
+
debug.debugFn('use: default org', defaultOrgResult);
|
|
1155
1155
|
return {
|
|
1156
1156
|
ok: true,
|
|
1157
1157
|
data: defaultOrgResult
|
|
@@ -1183,7 +1183,7 @@ async function getDefaultOrgSlug() {
|
|
|
1183
1183
|
data: `Was unable to determine the default organization for the current API token. Unable to continue.`
|
|
1184
1184
|
};
|
|
1185
1185
|
}
|
|
1186
|
-
debug.debugFn('
|
|
1186
|
+
debug.debugFn('resolve: org', slug);
|
|
1187
1187
|
return {
|
|
1188
1188
|
ok: true,
|
|
1189
1189
|
message: 'Retrieved default org from server',
|
|
@@ -1287,7 +1287,7 @@ async function fetchReportData(orgSlug, scanId, includeLicensePolicy) {
|
|
|
1287
1287
|
return JSON.parse(line);
|
|
1288
1288
|
} catch {
|
|
1289
1289
|
ok = false;
|
|
1290
|
-
debug.debugFn('
|
|
1290
|
+
debug.debugFn('fail: parse NDJSON\n', line);
|
|
1291
1291
|
return;
|
|
1292
1292
|
}
|
|
1293
1293
|
});
|
|
@@ -3711,6 +3711,7 @@ async function gitCleanFdx(cwd = process.cwd()) {
|
|
|
3711
3711
|
cwd,
|
|
3712
3712
|
stdio: 'ignore'
|
|
3713
3713
|
};
|
|
3714
|
+
// TODO: propagate CResult?
|
|
3714
3715
|
await spawn.spawn('git', ['clean', '-fdx'], stdioIgnoreOptions);
|
|
3715
3716
|
}
|
|
3716
3717
|
async function gitCreateAndPushBranch(branch, commitMsg, filepaths, options) {
|
|
@@ -3736,7 +3737,7 @@ async function gitCreateAndPushBranch(branch, commitMsg, filepaths, options) {
|
|
|
3736
3737
|
await spawn.spawn('git', ['push', '--force', '--set-upstream', 'origin', branch], stdioIgnoreOptions);
|
|
3737
3738
|
return true;
|
|
3738
3739
|
} catch (e) {
|
|
3739
|
-
debug.debugFn('
|
|
3740
|
+
debug.debugFn('catch: unexpected\n', e);
|
|
3740
3741
|
}
|
|
3741
3742
|
try {
|
|
3742
3743
|
// Will throw with exit code 1 if branch does not exist.
|
|
@@ -3766,7 +3767,7 @@ async function gitEnsureIdentity(name, email, cwd = process.cwd()) {
|
|
|
3766
3767
|
try {
|
|
3767
3768
|
await spawn.spawn('git', ['config', prop, value], stdioIgnoreOptions);
|
|
3768
3769
|
} catch (e) {
|
|
3769
|
-
debug.debugFn('
|
|
3770
|
+
debug.debugFn('catch: unexpected\n', e);
|
|
3770
3771
|
}
|
|
3771
3772
|
}
|
|
3772
3773
|
}));
|
|
@@ -3795,12 +3796,24 @@ async function gitResetHard(branch = 'HEAD', cwd = process.cwd()) {
|
|
|
3795
3796
|
await spawn.spawn('git', ['reset', '--hard', branch], stdioIgnoreOptions);
|
|
3796
3797
|
}
|
|
3797
3798
|
async function gitUnstagedModifiedFiles(cwd = process.cwd()) {
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3799
|
+
try {
|
|
3800
|
+
const stdioPipeOptions = {
|
|
3801
|
+
cwd
|
|
3802
|
+
};
|
|
3803
|
+
const stdout = (await spawn.spawn('git', ['diff', '--name-only'], stdioPipeOptions)).stdout.trim();
|
|
3804
|
+
const rawFiles = stdout.split('\n') ?? [];
|
|
3805
|
+
return {
|
|
3806
|
+
ok: true,
|
|
3807
|
+
data: rawFiles.map(relPath => path$1.normalizePath(relPath))
|
|
3808
|
+
};
|
|
3809
|
+
} catch (e) {
|
|
3810
|
+
debug.debugFn('catch: git diff --name-only failed\n', e);
|
|
3811
|
+
return {
|
|
3812
|
+
ok: false,
|
|
3813
|
+
message: 'Git Error',
|
|
3814
|
+
cause: 'Unexpected error while trying to ask git whether repo is dirty'
|
|
3815
|
+
};
|
|
3816
|
+
}
|
|
3804
3817
|
}
|
|
3805
3818
|
|
|
3806
3819
|
let _octokit;
|
|
@@ -3891,14 +3904,14 @@ async function cleanupOpenPrs(owner, repo, newVersion, options) {
|
|
|
3891
3904
|
pull_number: prNum,
|
|
3892
3905
|
state: 'closed'
|
|
3893
3906
|
});
|
|
3894
|
-
debug.debugFn(`
|
|
3907
|
+
debug.debugFn(`close: ${prRef} for ${prToVersion}`);
|
|
3895
3908
|
// Remove entry from parent object.
|
|
3896
3909
|
context.parent.splice(context.index, 1);
|
|
3897
3910
|
// Mark cache to be saved.
|
|
3898
3911
|
cachesToSave.set(context.cacheKey, context.data);
|
|
3899
3912
|
return null;
|
|
3900
3913
|
} catch (e) {
|
|
3901
|
-
debug.debugFn(`
|
|
3914
|
+
debug.debugFn(`fail: close ${prRef}\n`, e?.message || 'unknown error');
|
|
3902
3915
|
}
|
|
3903
3916
|
}
|
|
3904
3917
|
// Update stale PRs.
|
|
@@ -3911,7 +3924,7 @@ async function cleanupOpenPrs(owner, repo, newVersion, options) {
|
|
|
3911
3924
|
base: match.headRefName,
|
|
3912
3925
|
head: match.baseRefName
|
|
3913
3926
|
});
|
|
3914
|
-
debug.debugFn(
|
|
3927
|
+
debug.debugFn('update: stale', prRef);
|
|
3915
3928
|
// Update entry entry.
|
|
3916
3929
|
if (context.apiType === 'graphql') {
|
|
3917
3930
|
context.entry.mergeStateStatus = 'CLEAN';
|
|
@@ -3922,7 +3935,7 @@ async function cleanupOpenPrs(owner, repo, newVersion, options) {
|
|
|
3922
3935
|
cachesToSave.set(context.cacheKey, context.data);
|
|
3923
3936
|
} catch (e) {
|
|
3924
3937
|
const message = e?.message || 'Unknown error';
|
|
3925
|
-
debug.debugFn(`
|
|
3938
|
+
debug.debugFn(`fail: update ${prRef} - ${message}`);
|
|
3926
3939
|
}
|
|
3927
3940
|
}
|
|
3928
3941
|
return match;
|
|
@@ -3989,6 +4002,9 @@ function getGitHubEnvRepoInfo() {
|
|
|
3989
4002
|
repo: ownerSlashRepo.slice(slashIndex + 1)
|
|
3990
4003
|
};
|
|
3991
4004
|
}
|
|
4005
|
+
async function getOpenSocketPrs(owner, repo, options) {
|
|
4006
|
+
return (await getOpenSocketPrsWithContext(owner, repo, options)).map(d => d.match);
|
|
4007
|
+
}
|
|
3992
4008
|
async function getOpenSocketPrsWithContext(owner, repo, options_) {
|
|
3993
4009
|
const options = {
|
|
3994
4010
|
__proto__: null,
|
|
@@ -4111,7 +4127,7 @@ async function openPr(owner, repo, branch, purl, newVersion, options) {
|
|
|
4111
4127
|
};
|
|
4112
4128
|
// Lazily access constants.ENV.GITHUB_ACTIONS.
|
|
4113
4129
|
if (!constants.ENV.GITHUB_ACTIONS) {
|
|
4114
|
-
debug.debugFn('
|
|
4130
|
+
debug.debugFn('miss: GITHUB_ACTIONS env var');
|
|
4115
4131
|
return null;
|
|
4116
4132
|
}
|
|
4117
4133
|
const octokit = getOctokit();
|
|
@@ -4160,7 +4176,7 @@ async function setGitRemoteGitHubRepoUrl(owner, repo, token, cwd = process.cwd()
|
|
|
4160
4176
|
try {
|
|
4161
4177
|
await spawn.spawn('git', ['remote', 'set-url', 'origin', url], stdioIgnoreOptions);
|
|
4162
4178
|
} catch (e) {
|
|
4163
|
-
debug.debugFn('
|
|
4179
|
+
debug.debugFn('catch: unexpected\n', e);
|
|
4164
4180
|
}
|
|
4165
4181
|
}
|
|
4166
4182
|
|
|
@@ -4215,10 +4231,24 @@ async function npmFix(pkgEnvDetails, {
|
|
|
4215
4231
|
const {
|
|
4216
4232
|
spinner
|
|
4217
4233
|
} = constants;
|
|
4218
|
-
spinner?.start();
|
|
4219
4234
|
const {
|
|
4220
4235
|
pkgPath: rootPath
|
|
4221
4236
|
} = pkgEnvDetails;
|
|
4237
|
+
|
|
4238
|
+
// Lazily access constants.ENV properties.
|
|
4239
|
+
const gitEmail = constants.ENV.SOCKET_CLI_GIT_USER_EMAIL;
|
|
4240
|
+
const gitUser = constants.ENV.SOCKET_CLI_GIT_USER_NAME;
|
|
4241
|
+
const githubToken = constants.ENV.SOCKET_CLI_GITHUB_TOKEN;
|
|
4242
|
+
const isCi = !!(constants.ENV.CI && constants.ENV.GITHUB_ACTIONS && constants.ENV.GITHUB_REPOSITORY && gitEmail && gitUser && githubToken);
|
|
4243
|
+
spinner?.start();
|
|
4244
|
+
let count = 0;
|
|
4245
|
+
let repoInfo = null;
|
|
4246
|
+
if (isCi) {
|
|
4247
|
+
repoInfo = getGitHubEnvRepoInfo();
|
|
4248
|
+
count += (await getOpenSocketPrs(repoInfo.owner, repoInfo.repo, {
|
|
4249
|
+
author: gitUser
|
|
4250
|
+
})).length;
|
|
4251
|
+
}
|
|
4222
4252
|
const arb = new shadowInject.Arborist({
|
|
4223
4253
|
path: rootPath,
|
|
4224
4254
|
...shadowInject.SAFE_ARBORIST_REIFY_OPTIONS_OVERRIDES
|
|
@@ -4235,8 +4265,12 @@ async function npmFix(pkgEnvDetails, {
|
|
|
4235
4265
|
}));
|
|
4236
4266
|
} catch (e) {
|
|
4237
4267
|
spinner?.stop();
|
|
4238
|
-
|
|
4239
|
-
return
|
|
4268
|
+
debug.debugFn('catch: PURL API\n', e);
|
|
4269
|
+
return {
|
|
4270
|
+
ok: false,
|
|
4271
|
+
message: 'API Error',
|
|
4272
|
+
cause: e?.message || 'Unknown Socket batch PURL API error.'
|
|
4273
|
+
};
|
|
4240
4274
|
}
|
|
4241
4275
|
const infoByPkgName = utils.getCveInfoFromAlertsMap(alertsMap, {
|
|
4242
4276
|
limit
|
|
@@ -4244,25 +4278,30 @@ async function npmFix(pkgEnvDetails, {
|
|
|
4244
4278
|
if (!infoByPkgName) {
|
|
4245
4279
|
spinner?.stop();
|
|
4246
4280
|
logger.logger.info('No fixable vulns found.');
|
|
4247
|
-
return
|
|
4281
|
+
return {
|
|
4282
|
+
ok: true,
|
|
4283
|
+
data: {
|
|
4284
|
+
fixed: false
|
|
4285
|
+
}
|
|
4286
|
+
};
|
|
4248
4287
|
}
|
|
4249
|
-
|
|
4250
|
-
// Lazily access constants.ENV properties.
|
|
4251
|
-
const token = constants.ENV.SOCKET_CLI_GITHUB_TOKEN;
|
|
4252
|
-
const isCi = !!(constants.ENV.CI && constants.ENV.GITHUB_ACTIONS && constants.ENV.GITHUB_REPOSITORY && token);
|
|
4253
4288
|
const baseBranch = isCi ? getBaseGitBranch() : '';
|
|
4254
4289
|
const workspacePkgJsonPaths = await utils.globWorkspace(pkgEnvDetails.agent, rootPath);
|
|
4255
4290
|
const pkgJsonPaths = [...workspacePkgJsonPaths,
|
|
4256
4291
|
// Process the workspace root last since it will add an override to package.json.
|
|
4257
4292
|
pkgEnvDetails.editablePkgJson.filename];
|
|
4293
|
+
const sortedInfoEntries = [...infoByPkgName.entries()].sort((a, b) => sorts.naturalCompare(a[0], b[0]));
|
|
4258
4294
|
const handleInstallFail = () => {
|
|
4259
|
-
|
|
4295
|
+
debug.debugFn(`fail: ${pkgEnvDetails.agent} install\n`);
|
|
4260
4296
|
logger.logger.dedent();
|
|
4261
4297
|
spinner?.dedent();
|
|
4298
|
+
return {
|
|
4299
|
+
ok: false,
|
|
4300
|
+
message: 'Installation failure',
|
|
4301
|
+
cause: `Unexpected condition: ${pkgEnvDetails.agent} install failed.`
|
|
4302
|
+
};
|
|
4262
4303
|
};
|
|
4263
4304
|
spinner?.stop();
|
|
4264
|
-
let count = 0;
|
|
4265
|
-
const sortedInfoEntries = [...infoByPkgName.entries()].sort((a, b) => sorts.naturalCompare(a[0], b[0]));
|
|
4266
4305
|
infoEntriesLoop: for (let i = 0, {
|
|
4267
4306
|
length
|
|
4268
4307
|
} = sortedInfoEntries; i < length; i += 1) {
|
|
@@ -4275,7 +4314,7 @@ async function npmFix(pkgEnvDetails, {
|
|
|
4275
4314
|
logger.logger.indent();
|
|
4276
4315
|
spinner?.indent();
|
|
4277
4316
|
if (registry.getManifestData(NPM$a, name)) {
|
|
4278
|
-
debug.debugFn(`Socket Optimize
|
|
4317
|
+
debug.debugFn(`found: Socket Optimize variant for ${name}`);
|
|
4279
4318
|
}
|
|
4280
4319
|
// eslint-disable-next-line no-await-in-loop
|
|
4281
4320
|
const packument = await packages.fetchPackagePackument(name);
|
|
@@ -4299,7 +4338,7 @@ async function npmFix(pkgEnvDetails, {
|
|
|
4299
4338
|
const workspace = isWorkspaceRoot ? 'root' : path.relative(rootPath, pkgPath);
|
|
4300
4339
|
const oldVersions = arrays.arrayUnique(shadowInject.findPackageNodes(actualTree, name).map(n => n.target?.version ?? n.version).filter(Boolean));
|
|
4301
4340
|
if (!oldVersions.length) {
|
|
4302
|
-
debug.debugFn(
|
|
4341
|
+
debug.debugFn(`skip: ${name} not found\n`);
|
|
4303
4342
|
// Skip to next package.
|
|
4304
4343
|
logger.logger.dedent();
|
|
4305
4344
|
spinner?.dedent();
|
|
@@ -4315,7 +4354,7 @@ async function npmFix(pkgEnvDetails, {
|
|
|
4315
4354
|
let hasAnnouncedWorkspace = false;
|
|
4316
4355
|
let workspaceLogCallCount = logger.logger.logCallCount;
|
|
4317
4356
|
if (debug.isDebug()) {
|
|
4318
|
-
debug.debugFn(`
|
|
4357
|
+
debug.debugFn(`check: workspace ${workspace}`);
|
|
4319
4358
|
hasAnnouncedWorkspace = true;
|
|
4320
4359
|
workspaceLogCallCount = logger.logger.logCallCount;
|
|
4321
4360
|
}
|
|
@@ -4324,7 +4363,7 @@ async function npmFix(pkgEnvDetails, {
|
|
|
4324
4363
|
const oldPurl = utils.idToPurl(oldId);
|
|
4325
4364
|
const node = shadowInject.findPackageNode(actualTree, name, oldVersion);
|
|
4326
4365
|
if (!node) {
|
|
4327
|
-
debug.debugFn(
|
|
4366
|
+
debug.debugFn(`skip: ${oldId} not found`);
|
|
4328
4367
|
continue oldVersionsLoop;
|
|
4329
4368
|
}
|
|
4330
4369
|
infosLoop: for (const {
|
|
@@ -4332,7 +4371,7 @@ async function npmFix(pkgEnvDetails, {
|
|
|
4332
4371
|
vulnerableVersionRange
|
|
4333
4372
|
} of infos.values()) {
|
|
4334
4373
|
if (vendor.semverExports.gte(oldVersion, firstPatchedVersionIdentifier)) {
|
|
4335
|
-
debug.debugFn(
|
|
4374
|
+
debug.debugFn(`skip: ${oldId} is >= ${firstPatchedVersionIdentifier}`);
|
|
4336
4375
|
continue infosLoop;
|
|
4337
4376
|
}
|
|
4338
4377
|
const newVersion = shadowInject.findBestPatchVersion(node, availableVersions, vulnerableVersionRange);
|
|
@@ -4368,7 +4407,7 @@ async function npmFix(pkgEnvDetails, {
|
|
|
4368
4407
|
if (!(await editablePkgJson.save({
|
|
4369
4408
|
ignoreWhitespace: true
|
|
4370
4409
|
}))) {
|
|
4371
|
-
debug.debugFn(
|
|
4410
|
+
debug.debugFn(`skip: ${workspace}/package.json unchanged`);
|
|
4372
4411
|
// Reset things just in case.
|
|
4373
4412
|
if (isCi) {
|
|
4374
4413
|
// eslint-disable-next-line no-await-in-loop
|
|
@@ -4410,9 +4449,15 @@ async function npmFix(pkgEnvDetails, {
|
|
|
4410
4449
|
spinner?.stop();
|
|
4411
4450
|
if (!errored && isCi) {
|
|
4412
4451
|
try {
|
|
4413
|
-
const moddedFilepaths =
|
|
4414
4452
|
// eslint-disable-next-line no-await-in-loop
|
|
4415
|
-
|
|
4453
|
+
const result = await gitUnstagedModifiedFiles(cwd);
|
|
4454
|
+
if (!result.ok) {
|
|
4455
|
+
// Do we fail if this fails? If this git command
|
|
4456
|
+
// fails then probably other git commands do too?
|
|
4457
|
+
logger.logger.warn('Unexpected condition: Nothing to commit, skipping PR creation.');
|
|
4458
|
+
continue infosLoop;
|
|
4459
|
+
}
|
|
4460
|
+
const moddedFilepaths = result.data.filter(p => {
|
|
4416
4461
|
const basename = path.basename(p);
|
|
4417
4462
|
return basename === 'package.json' || basename === 'package-lock.json';
|
|
4418
4463
|
});
|
|
@@ -4420,23 +4465,24 @@ async function npmFix(pkgEnvDetails, {
|
|
|
4420
4465
|
logger.logger.warn('Unexpected condition: Nothing to commit, skipping PR creation.');
|
|
4421
4466
|
continue infosLoop;
|
|
4422
4467
|
}
|
|
4423
|
-
const repoInfo = getGitHubEnvRepoInfo();
|
|
4424
4468
|
const branch = getSocketBranchName(oldPurl, newVersion, workspace);
|
|
4425
4469
|
let skipPr = false;
|
|
4426
4470
|
if (
|
|
4427
4471
|
// eslint-disable-next-line no-await-in-loop
|
|
4428
4472
|
await prExistForBranch(repoInfo.owner, repoInfo.repo, branch)) {
|
|
4429
4473
|
skipPr = true;
|
|
4430
|
-
debug.debugFn(`
|
|
4474
|
+
debug.debugFn(`skip: branch "${branch}" exists`);
|
|
4431
4475
|
}
|
|
4432
4476
|
// eslint-disable-next-line no-await-in-loop
|
|
4433
4477
|
else if (await gitRemoteBranchExists(branch, cwd)) {
|
|
4434
4478
|
skipPr = true;
|
|
4435
|
-
debug.debugFn(`
|
|
4479
|
+
debug.debugFn(`skip: remote branch "${branch}" exists`);
|
|
4436
4480
|
} else if (
|
|
4437
4481
|
// eslint-disable-next-line no-await-in-loop
|
|
4438
4482
|
!(await gitCreateAndPushBranch(branch, getSocketCommitMessage(oldPurl, newVersion, workspace), moddedFilepaths, {
|
|
4439
|
-
cwd
|
|
4483
|
+
cwd,
|
|
4484
|
+
email: gitEmail,
|
|
4485
|
+
user: gitUser
|
|
4440
4486
|
}))) {
|
|
4441
4487
|
skipPr = true;
|
|
4442
4488
|
logger.logger.warn('Unexpected condition: Push failed, skipping PR creation.');
|
|
@@ -4450,15 +4496,14 @@ async function npmFix(pkgEnvDetails, {
|
|
|
4450
4496
|
});
|
|
4451
4497
|
if (!maybeActualTree) {
|
|
4452
4498
|
// Exit early if install fails.
|
|
4453
|
-
handleInstallFail();
|
|
4454
|
-
return;
|
|
4499
|
+
return handleInstallFail();
|
|
4455
4500
|
}
|
|
4456
4501
|
actualTree = maybeActualTree;
|
|
4457
4502
|
continue infosLoop;
|
|
4458
4503
|
}
|
|
4459
4504
|
|
|
4460
4505
|
// eslint-disable-next-line no-await-in-loop
|
|
4461
|
-
await Promise.allSettled([setGitRemoteGitHubRepoUrl(repoInfo.owner, repoInfo.repo,
|
|
4506
|
+
await Promise.allSettled([setGitRemoteGitHubRepoUrl(repoInfo.owner, repoInfo.repo, githubToken, cwd), cleanupOpenPrs(repoInfo.owner, repoInfo.repo, newVersion, {
|
|
4462
4507
|
purl: oldPurl,
|
|
4463
4508
|
workspace
|
|
4464
4509
|
})]);
|
|
@@ -4527,8 +4572,7 @@ async function npmFix(pkgEnvDetails, {
|
|
|
4527
4572
|
spinner?.stop();
|
|
4528
4573
|
if (!maybeActualTree) {
|
|
4529
4574
|
// Exit early if install fails.
|
|
4530
|
-
handleInstallFail();
|
|
4531
|
-
return;
|
|
4575
|
+
return handleInstallFail();
|
|
4532
4576
|
}
|
|
4533
4577
|
actualTree = maybeActualTree;
|
|
4534
4578
|
}
|
|
@@ -4555,6 +4599,12 @@ async function npmFix(pkgEnvDetails, {
|
|
|
4555
4599
|
spinner?.dedent();
|
|
4556
4600
|
}
|
|
4557
4601
|
spinner?.stop();
|
|
4602
|
+
return {
|
|
4603
|
+
ok: true,
|
|
4604
|
+
data: {
|
|
4605
|
+
fixed: true
|
|
4606
|
+
}
|
|
4607
|
+
}; // true? did we actually change anything?
|
|
4558
4608
|
}
|
|
4559
4609
|
|
|
4560
4610
|
const {
|
|
@@ -4614,7 +4664,21 @@ async function pnpmFix(pkgEnvDetails, {
|
|
|
4614
4664
|
const {
|
|
4615
4665
|
pkgPath: rootPath
|
|
4616
4666
|
} = pkgEnvDetails;
|
|
4667
|
+
|
|
4668
|
+
// Lazily access constants.ENV properties.
|
|
4669
|
+
const gitEmail = constants.ENV.SOCKET_CLI_GIT_USER_EMAIL;
|
|
4670
|
+
const gitUser = constants.ENV.SOCKET_CLI_GIT_USER_NAME;
|
|
4671
|
+
const githubToken = constants.ENV.SOCKET_CLI_GITHUB_TOKEN;
|
|
4672
|
+
const isCi = !!(constants.ENV.CI && constants.ENV.GITHUB_ACTIONS && constants.ENV.GITHUB_REPOSITORY && gitEmail && gitUser && githubToken);
|
|
4617
4673
|
spinner?.start();
|
|
4674
|
+
let count = 0;
|
|
4675
|
+
let repoInfo = null;
|
|
4676
|
+
if (isCi) {
|
|
4677
|
+
repoInfo = getGitHubEnvRepoInfo();
|
|
4678
|
+
count += (await getOpenSocketPrs(repoInfo.owner, repoInfo.repo, {
|
|
4679
|
+
author: gitUser
|
|
4680
|
+
})).length;
|
|
4681
|
+
}
|
|
4618
4682
|
let actualTree;
|
|
4619
4683
|
const lockfilePath = path.join(rootPath, 'pnpm-lock.yaml');
|
|
4620
4684
|
let lockfileContent = await utils.readPnpmLockfile(lockfilePath);
|
|
@@ -4654,8 +4718,11 @@ async function pnpmFix(pkgEnvDetails, {
|
|
|
4654
4718
|
// Check !lockfileContent to make TypeScript happy.
|
|
4655
4719
|
if (!lockfile || !lockfileContent) {
|
|
4656
4720
|
spinner?.stop();
|
|
4657
|
-
|
|
4658
|
-
|
|
4721
|
+
return {
|
|
4722
|
+
ok: false,
|
|
4723
|
+
message: 'Missing lockfile',
|
|
4724
|
+
cause: 'Required pnpm-lock.yaml not found or usable'
|
|
4725
|
+
};
|
|
4659
4726
|
}
|
|
4660
4727
|
let alertsMap;
|
|
4661
4728
|
try {
|
|
@@ -4666,8 +4733,12 @@ async function pnpmFix(pkgEnvDetails, {
|
|
|
4666
4733
|
}));
|
|
4667
4734
|
} catch (e) {
|
|
4668
4735
|
spinner?.stop();
|
|
4669
|
-
|
|
4670
|
-
return
|
|
4736
|
+
debug.debugFn('catch: PURL API\n', e);
|
|
4737
|
+
return {
|
|
4738
|
+
ok: false,
|
|
4739
|
+
message: 'API Error',
|
|
4740
|
+
cause: e?.message || 'Unknown Socket batch PURL API error.'
|
|
4741
|
+
};
|
|
4671
4742
|
}
|
|
4672
4743
|
const infoByPkgName = utils.getCveInfoFromAlertsMap(alertsMap, {
|
|
4673
4744
|
limit
|
|
@@ -4675,25 +4746,29 @@ async function pnpmFix(pkgEnvDetails, {
|
|
|
4675
4746
|
if (!infoByPkgName) {
|
|
4676
4747
|
spinner?.stop();
|
|
4677
4748
|
logger.logger.info('No fixable vulns found.');
|
|
4678
|
-
return
|
|
4749
|
+
return {
|
|
4750
|
+
ok: true,
|
|
4751
|
+
data: {
|
|
4752
|
+
fixed: false
|
|
4753
|
+
}
|
|
4754
|
+
};
|
|
4679
4755
|
}
|
|
4680
|
-
|
|
4681
|
-
// Lazily access constants.ENV properties.
|
|
4682
|
-
const token = constants.ENV.SOCKET_CLI_GITHUB_TOKEN;
|
|
4683
|
-
const isCi = !!(constants.ENV.CI && constants.ENV.GITHUB_ACTIONS && constants.ENV.GITHUB_REPOSITORY && token);
|
|
4684
4756
|
const baseBranch = isCi ? getBaseGitBranch() : '';
|
|
4685
4757
|
const workspacePkgJsonPaths = await utils.globWorkspace(pkgEnvDetails.agent, rootPath);
|
|
4686
4758
|
const pkgJsonPaths = [...workspacePkgJsonPaths,
|
|
4687
4759
|
// Process the workspace root last since it will add an override to package.json.
|
|
4688
4760
|
pkgEnvDetails.editablePkgJson.filename];
|
|
4761
|
+
const sortedInfoEntries = [...infoByPkgName.entries()].sort((a, b) => sorts.naturalCompare(a[0], b[0]));
|
|
4689
4762
|
const handleInstallFail = () => {
|
|
4690
|
-
logger.logger.error(`Unexpected condition: ${pkgEnvDetails.agent} install failed.\n`);
|
|
4691
4763
|
logger.logger.dedent();
|
|
4692
4764
|
spinner?.dedent();
|
|
4765
|
+
return {
|
|
4766
|
+
ok: false,
|
|
4767
|
+
message: 'Install failed',
|
|
4768
|
+
cause: `Unexpected condition: ${pkgEnvDetails.agent} install failed`
|
|
4769
|
+
};
|
|
4693
4770
|
};
|
|
4694
4771
|
spinner?.stop();
|
|
4695
|
-
let count = 0;
|
|
4696
|
-
const sortedInfoEntries = [...infoByPkgName.entries()].sort((a, b) => sorts.naturalCompare(a[0], b[0]));
|
|
4697
4772
|
infoEntriesLoop: for (let i = 0, {
|
|
4698
4773
|
length
|
|
4699
4774
|
} = sortedInfoEntries; i < length; i += 1) {
|
|
@@ -4706,7 +4781,7 @@ async function pnpmFix(pkgEnvDetails, {
|
|
|
4706
4781
|
logger.logger.indent();
|
|
4707
4782
|
spinner?.indent();
|
|
4708
4783
|
if (registry.getManifestData(NPM$9, name)) {
|
|
4709
|
-
debug.debugFn(`Socket Optimize
|
|
4784
|
+
debug.debugFn(`found: Socket Optimize variant for ${name}`);
|
|
4710
4785
|
}
|
|
4711
4786
|
// eslint-disable-next-line no-await-in-loop
|
|
4712
4787
|
const packument = await packages.fetchPackagePackument(name);
|
|
@@ -4731,6 +4806,10 @@ async function pnpmFix(pkgEnvDetails, {
|
|
|
4731
4806
|
|
|
4732
4807
|
// actualTree may not be defined on the first iteration of pkgJsonPathsLoop.
|
|
4733
4808
|
if (!actualTree) {
|
|
4809
|
+
if (!isCi) {
|
|
4810
|
+
// eslint-disable-next-line no-await-in-loop
|
|
4811
|
+
await utils.removeNodeModules(cwd);
|
|
4812
|
+
}
|
|
4734
4813
|
const maybeActualTree = isCi && fs$1.existsSync(path.join(rootPath, 'node_modules')) ?
|
|
4735
4814
|
// eslint-disable-next-line no-await-in-loop
|
|
4736
4815
|
await getActualTree(cwd) :
|
|
@@ -4749,12 +4828,11 @@ async function pnpmFix(pkgEnvDetails, {
|
|
|
4749
4828
|
}
|
|
4750
4829
|
if (!actualTree) {
|
|
4751
4830
|
// Exit early if install fails.
|
|
4752
|
-
handleInstallFail();
|
|
4753
|
-
return;
|
|
4831
|
+
return handleInstallFail();
|
|
4754
4832
|
}
|
|
4755
4833
|
const oldVersions = arrays.arrayUnique(shadowInject.findPackageNodes(actualTree, name).map(n => n.version).filter(Boolean));
|
|
4756
4834
|
if (!oldVersions.length) {
|
|
4757
|
-
debug.debugFn(
|
|
4835
|
+
debug.debugFn(`skip: ${name} not found\n`);
|
|
4758
4836
|
// Skip to next package.
|
|
4759
4837
|
logger.logger.dedent();
|
|
4760
4838
|
spinner?.dedent();
|
|
@@ -4773,7 +4851,7 @@ async function pnpmFix(pkgEnvDetails, {
|
|
|
4773
4851
|
let hasAnnouncedWorkspace = false;
|
|
4774
4852
|
let workspaceLogCallCount = logger.logger.logCallCount;
|
|
4775
4853
|
if (debug.isDebug()) {
|
|
4776
|
-
debug.debugFn(`
|
|
4854
|
+
debug.debugFn(`check: workspace ${workspace}`);
|
|
4777
4855
|
hasAnnouncedWorkspace = true;
|
|
4778
4856
|
workspaceLogCallCount = logger.logger.logCallCount;
|
|
4779
4857
|
}
|
|
@@ -4782,7 +4860,7 @@ async function pnpmFix(pkgEnvDetails, {
|
|
|
4782
4860
|
const oldPurl = utils.idToPurl(oldId);
|
|
4783
4861
|
const node = shadowInject.findPackageNode(actualTree, name, oldVersion);
|
|
4784
4862
|
if (!node) {
|
|
4785
|
-
debug.debugFn(
|
|
4863
|
+
debug.debugFn(`skip: ${oldId} not found`);
|
|
4786
4864
|
continue oldVersionsLoop;
|
|
4787
4865
|
}
|
|
4788
4866
|
infosLoop: for (const {
|
|
@@ -4790,7 +4868,7 @@ async function pnpmFix(pkgEnvDetails, {
|
|
|
4790
4868
|
vulnerableVersionRange
|
|
4791
4869
|
} of infos.values()) {
|
|
4792
4870
|
if (vendor.semverExports.gte(oldVersion, firstPatchedVersionIdentifier)) {
|
|
4793
|
-
debug.debugFn(
|
|
4871
|
+
debug.debugFn(`skip: ${oldId} is >= ${firstPatchedVersionIdentifier}`);
|
|
4794
4872
|
continue infosLoop;
|
|
4795
4873
|
}
|
|
4796
4874
|
const newVersion = shadowInject.findBestPatchVersion(node, availableVersions, vulnerableVersionRange);
|
|
@@ -4848,7 +4926,7 @@ async function pnpmFix(pkgEnvDetails, {
|
|
|
4848
4926
|
if (!(await editablePkgJson.save({
|
|
4849
4927
|
ignoreWhitespace: true
|
|
4850
4928
|
}))) {
|
|
4851
|
-
debug.debugFn(
|
|
4929
|
+
debug.debugFn(`skip: ${workspace}/package.json unchanged`);
|
|
4852
4930
|
// Reset things just in case.
|
|
4853
4931
|
if (isCi) {
|
|
4854
4932
|
// eslint-disable-next-line no-await-in-loop
|
|
@@ -4909,9 +4987,13 @@ async function pnpmFix(pkgEnvDetails, {
|
|
|
4909
4987
|
spinner?.stop();
|
|
4910
4988
|
if (!errored && isCi) {
|
|
4911
4989
|
try {
|
|
4912
|
-
const moddedFilepaths =
|
|
4913
4990
|
// eslint-disable-next-line no-await-in-loop
|
|
4914
|
-
|
|
4991
|
+
const result = await gitUnstagedModifiedFiles(cwd);
|
|
4992
|
+
if (!result.ok) {
|
|
4993
|
+
logger.logger.warn('Unexpected condition: Nothing to commit, skipping PR creation.');
|
|
4994
|
+
continue;
|
|
4995
|
+
}
|
|
4996
|
+
const moddedFilepaths = result.data.filter(p => {
|
|
4915
4997
|
const basename = path.basename(p);
|
|
4916
4998
|
return basename === 'package.json' || basename === 'pnpm-lock.yaml';
|
|
4917
4999
|
});
|
|
@@ -4919,23 +5001,24 @@ async function pnpmFix(pkgEnvDetails, {
|
|
|
4919
5001
|
logger.logger.warn('Unexpected condition: Nothing to commit, skipping PR creation.');
|
|
4920
5002
|
continue infosLoop;
|
|
4921
5003
|
}
|
|
4922
|
-
const repoInfo = getGitHubEnvRepoInfo();
|
|
4923
5004
|
const branch = getSocketBranchName(oldPurl, newVersion, workspace);
|
|
4924
5005
|
let skipPr = false;
|
|
4925
5006
|
if (
|
|
4926
5007
|
// eslint-disable-next-line no-await-in-loop
|
|
4927
5008
|
await prExistForBranch(repoInfo.owner, repoInfo.repo, branch)) {
|
|
4928
5009
|
skipPr = true;
|
|
4929
|
-
debug.debugFn(`
|
|
5010
|
+
debug.debugFn(`skip: branch "${branch}" exists`);
|
|
4930
5011
|
}
|
|
4931
5012
|
// eslint-disable-next-line no-await-in-loop
|
|
4932
5013
|
else if (await gitRemoteBranchExists(branch, cwd)) {
|
|
4933
5014
|
skipPr = true;
|
|
4934
|
-
debug.debugFn(`
|
|
5015
|
+
debug.debugFn(`skip: remote branch "${branch}" exists`);
|
|
4935
5016
|
} else if (
|
|
4936
5017
|
// eslint-disable-next-line no-await-in-loop
|
|
4937
5018
|
!(await gitCreateAndPushBranch(branch, getSocketCommitMessage(oldPurl, newVersion, workspace), moddedFilepaths, {
|
|
4938
|
-
cwd
|
|
5019
|
+
cwd,
|
|
5020
|
+
email: gitEmail,
|
|
5021
|
+
user: gitUser
|
|
4939
5022
|
}))) {
|
|
4940
5023
|
skipPr = true;
|
|
4941
5024
|
logger.logger.warn('Unexpected condition: Push failed, skipping PR creation.');
|
|
@@ -4957,12 +5040,11 @@ async function pnpmFix(pkgEnvDetails, {
|
|
|
4957
5040
|
continue infosLoop;
|
|
4958
5041
|
}
|
|
4959
5042
|
// Exit early if install fails.
|
|
4960
|
-
handleInstallFail();
|
|
4961
|
-
return;
|
|
5043
|
+
return handleInstallFail();
|
|
4962
5044
|
}
|
|
4963
5045
|
|
|
4964
5046
|
// eslint-disable-next-line no-await-in-loop
|
|
4965
|
-
await Promise.allSettled([setGitRemoteGitHubRepoUrl(repoInfo.owner, repoInfo.repo,
|
|
5047
|
+
await Promise.allSettled([setGitRemoteGitHubRepoUrl(repoInfo.owner, repoInfo.repo, githubToken, cwd), cleanupOpenPrs(repoInfo.owner, repoInfo.repo, newVersion, {
|
|
4966
5048
|
purl: oldPurl,
|
|
4967
5049
|
workspace
|
|
4968
5050
|
})]);
|
|
@@ -5043,11 +5125,14 @@ async function pnpmFix(pkgEnvDetails, {
|
|
|
5043
5125
|
lockfileContent = maybeLockfileContent;
|
|
5044
5126
|
} else {
|
|
5045
5127
|
// Exit early if install fails.
|
|
5046
|
-
handleInstallFail();
|
|
5047
|
-
return;
|
|
5128
|
+
return handleInstallFail();
|
|
5048
5129
|
}
|
|
5049
5130
|
}
|
|
5050
|
-
|
|
5131
|
+
return {
|
|
5132
|
+
ok: false,
|
|
5133
|
+
message: 'Update failed',
|
|
5134
|
+
cause: `Update failed for ${oldId} in ${workspace}${error ? '; ' + error : ''}`
|
|
5135
|
+
};
|
|
5051
5136
|
}
|
|
5052
5137
|
if (++count >= limit) {
|
|
5053
5138
|
logger.logger.dedent();
|
|
@@ -5070,6 +5155,14 @@ async function pnpmFix(pkgEnvDetails, {
|
|
|
5070
5155
|
spinner?.dedent();
|
|
5071
5156
|
}
|
|
5072
5157
|
spinner?.stop();
|
|
5158
|
+
|
|
5159
|
+
// Or, did we change anything?
|
|
5160
|
+
return {
|
|
5161
|
+
ok: true,
|
|
5162
|
+
data: {
|
|
5163
|
+
fixed: true
|
|
5164
|
+
}
|
|
5165
|
+
};
|
|
5073
5166
|
}
|
|
5074
5167
|
|
|
5075
5168
|
const {
|
|
@@ -5085,11 +5178,14 @@ async function runFix({
|
|
|
5085
5178
|
test,
|
|
5086
5179
|
testScript
|
|
5087
5180
|
}) {
|
|
5088
|
-
|
|
5089
|
-
const pkgEnvDetails = await utils.detectAndValidatePackageEnvironment(cwd, {
|
|
5181
|
+
const result = await utils.detectAndValidatePackageEnvironment(cwd, {
|
|
5090
5182
|
cmdName: CMD_NAME$1,
|
|
5091
5183
|
logger: logger.logger
|
|
5092
5184
|
});
|
|
5185
|
+
if (!result.ok) {
|
|
5186
|
+
return result;
|
|
5187
|
+
}
|
|
5188
|
+
const pkgEnvDetails = result.data;
|
|
5093
5189
|
if (!pkgEnvDetails) {
|
|
5094
5190
|
return {
|
|
5095
5191
|
ok: false,
|
|
@@ -5102,8 +5198,7 @@ async function runFix({
|
|
|
5102
5198
|
agent
|
|
5103
5199
|
} = pkgEnvDetails;
|
|
5104
5200
|
if (agent === NPM$8) {
|
|
5105
|
-
|
|
5106
|
-
await npmFix(pkgEnvDetails, {
|
|
5201
|
+
return await npmFix(pkgEnvDetails, {
|
|
5107
5202
|
autoMerge,
|
|
5108
5203
|
cwd,
|
|
5109
5204
|
limit,
|
|
@@ -5113,8 +5208,7 @@ async function runFix({
|
|
|
5113
5208
|
testScript
|
|
5114
5209
|
});
|
|
5115
5210
|
} else if (agent === PNPM$6) {
|
|
5116
|
-
|
|
5117
|
-
await pnpmFix(pkgEnvDetails, {
|
|
5211
|
+
return await pnpmFix(pkgEnvDetails, {
|
|
5118
5212
|
autoMerge,
|
|
5119
5213
|
cwd,
|
|
5120
5214
|
limit,
|
|
@@ -5130,10 +5224,6 @@ async function runFix({
|
|
|
5130
5224
|
cause: `${agent} is not supported by this command at the moment.`
|
|
5131
5225
|
};
|
|
5132
5226
|
}
|
|
5133
|
-
return {
|
|
5134
|
-
ok: true,
|
|
5135
|
-
data: undefined
|
|
5136
|
-
};
|
|
5137
5227
|
}
|
|
5138
5228
|
|
|
5139
5229
|
async function handleFix({
|
|
@@ -5218,10 +5308,14 @@ const config$F = {
|
|
|
5218
5308
|
},
|
|
5219
5309
|
help: (command, config) => `
|
|
5220
5310
|
Usage
|
|
5221
|
-
$ ${command}
|
|
5311
|
+
$ ${command} [options] [CWD=.]
|
|
5222
5312
|
|
|
5223
5313
|
Options
|
|
5224
5314
|
${utils.getFlagListOutput(config.flags, 6)}
|
|
5315
|
+
|
|
5316
|
+
Examples
|
|
5317
|
+
$ ${command}
|
|
5318
|
+
$ ${command} ./proj/tree --autoMerge
|
|
5225
5319
|
`
|
|
5226
5320
|
};
|
|
5227
5321
|
const cmdFix = {
|
|
@@ -5248,7 +5342,6 @@ async function run$F(argv, importMeta, {
|
|
|
5248
5342
|
rangeStyle,
|
|
5249
5343
|
test
|
|
5250
5344
|
} = cli.flags;
|
|
5251
|
-
// TODO: impl json/md further
|
|
5252
5345
|
const outputKind = utils.getOutputKind(json, markdown);
|
|
5253
5346
|
let [cwd = '.'] = cli.input;
|
|
5254
5347
|
// Note: path.resolve vs .join:
|
|
@@ -5568,9 +5661,9 @@ async function setupTabCompletion(targetName) {
|
|
|
5568
5661
|
|
|
5569
5662
|
// Target dir is something like ~/.local/share/socket/settings/completion (linux)
|
|
5570
5663
|
const targetDir = path.dirname(targetPath);
|
|
5571
|
-
debug.debugFn('
|
|
5664
|
+
debug.debugFn('target: path + dir', targetPath, targetDir);
|
|
5572
5665
|
if (!fs$1.existsSync(targetDir)) {
|
|
5573
|
-
debug.debugFn('
|
|
5666
|
+
debug.debugFn('create: target dir');
|
|
5574
5667
|
fs$1.mkdirSync(targetDir, {
|
|
5575
5668
|
recursive: true
|
|
5576
5669
|
});
|
|
@@ -7950,34 +8043,43 @@ async function updateLockfile(pkgEnvDetails, options) {
|
|
|
7950
8043
|
}
|
|
7951
8044
|
} catch (e) {
|
|
7952
8045
|
spinner?.stop();
|
|
7953
|
-
|
|
7954
|
-
|
|
8046
|
+
debug.debugFn('fail: update\n', e);
|
|
8047
|
+
return {
|
|
8048
|
+
ok: false,
|
|
8049
|
+
message: 'Update failed',
|
|
8050
|
+
cause: utils.cmdPrefixMessage(cmdName, `${pkgEnvDetails.agent} install failed to update ${pkgEnvDetails.lockName}`)
|
|
8051
|
+
};
|
|
7955
8052
|
}
|
|
7956
8053
|
if (isSpinning) {
|
|
7957
8054
|
spinner?.start();
|
|
7958
8055
|
} else {
|
|
7959
8056
|
spinner?.stop();
|
|
7960
8057
|
}
|
|
8058
|
+
return {
|
|
8059
|
+
ok: true,
|
|
8060
|
+
data: undefined
|
|
8061
|
+
};
|
|
7961
8062
|
}
|
|
7962
8063
|
|
|
7963
8064
|
const {
|
|
7964
8065
|
VLT
|
|
7965
8066
|
} = constants;
|
|
7966
|
-
function createActionMessage(verb, overrideCount, workspaceCount) {
|
|
7967
|
-
return `${verb} ${overrideCount} Socket.dev optimized ${words.pluralize('override', overrideCount)}${workspaceCount ? ` in ${workspaceCount} ${words.pluralize('workspace', workspaceCount)}` : ''}`;
|
|
7968
|
-
}
|
|
7969
8067
|
async function applyOptimization(cwd, pin, prod) {
|
|
7970
|
-
const
|
|
8068
|
+
const result = await utils.detectAndValidatePackageEnvironment(cwd, {
|
|
7971
8069
|
cmdName: CMD_NAME,
|
|
7972
8070
|
logger: logger.logger,
|
|
7973
8071
|
prod
|
|
7974
8072
|
});
|
|
7975
|
-
if (!
|
|
7976
|
-
return;
|
|
8073
|
+
if (!result.ok) {
|
|
8074
|
+
return result;
|
|
7977
8075
|
}
|
|
8076
|
+
const pkgEnvDetails = result.data;
|
|
7978
8077
|
if (pkgEnvDetails.agent === VLT) {
|
|
7979
|
-
|
|
7980
|
-
|
|
8078
|
+
return {
|
|
8079
|
+
ok: false,
|
|
8080
|
+
message: 'Unsupported',
|
|
8081
|
+
cause: utils.cmdPrefixMessage(CMD_NAME, `${VLT} does not support overrides. Soon, though ⚡`)
|
|
8082
|
+
};
|
|
7981
8083
|
}
|
|
7982
8084
|
|
|
7983
8085
|
// Lazily access constants.spinner.
|
|
@@ -7995,22 +8097,66 @@ async function applyOptimization(cwd, pin, prod) {
|
|
|
7995
8097
|
const updatedCount = state.updated.size;
|
|
7996
8098
|
const pkgJsonChanged = addedCount > 0 || updatedCount > 0;
|
|
7997
8099
|
if (pkgJsonChanged || pkgEnvDetails.features.npmBuggyOverrides) {
|
|
7998
|
-
await updateLockfile(pkgEnvDetails, {
|
|
8100
|
+
const result = await updateLockfile(pkgEnvDetails, {
|
|
7999
8101
|
cmdName: CMD_NAME,
|
|
8000
8102
|
logger: logger.logger,
|
|
8001
8103
|
spinner
|
|
8002
8104
|
});
|
|
8105
|
+
if (!result.ok) {
|
|
8106
|
+
return result;
|
|
8107
|
+
}
|
|
8003
8108
|
}
|
|
8004
8109
|
spinner.stop();
|
|
8005
|
-
|
|
8006
|
-
|
|
8110
|
+
return {
|
|
8111
|
+
ok: true,
|
|
8112
|
+
data: {
|
|
8113
|
+
addedCount,
|
|
8114
|
+
updatedCount,
|
|
8115
|
+
pkgJsonChanged,
|
|
8116
|
+
updatedInWorkspaces: state.updatedInWorkspaces.size,
|
|
8117
|
+
addedInWorkspaces: state.addedInWorkspaces.size
|
|
8118
|
+
}
|
|
8119
|
+
};
|
|
8120
|
+
}
|
|
8121
|
+
|
|
8122
|
+
async function outputOptimizeResult(result, outputKind) {
|
|
8123
|
+
if (!result.ok) {
|
|
8124
|
+
process.exitCode = result.code ?? 1;
|
|
8007
8125
|
}
|
|
8008
|
-
if (
|
|
8009
|
-
logger.logger
|
|
8126
|
+
if (outputKind === 'json') {
|
|
8127
|
+
logger.logger.log(utils.serializeResultJson(result));
|
|
8128
|
+
return;
|
|
8010
8129
|
}
|
|
8011
|
-
if (!
|
|
8130
|
+
if (!result.ok) {
|
|
8131
|
+
logger.logger.fail(utils.failMsgWithBadge(result.message, result.cause));
|
|
8132
|
+
return;
|
|
8133
|
+
}
|
|
8134
|
+
const data = result.data;
|
|
8135
|
+
if (data.updatedCount > 0) {
|
|
8136
|
+
logger.logger?.log(`${createActionMessage('Updated', data.updatedCount, data.updatedInWorkspaces)}${data.addedCount ? '.' : '🚀'}`);
|
|
8137
|
+
}
|
|
8138
|
+
if (data.addedCount > 0) {
|
|
8139
|
+
logger.logger?.log(`${createActionMessage('Added', data.addedCount, data.addedInWorkspaces)} 🚀`);
|
|
8140
|
+
}
|
|
8141
|
+
if (!data.pkgJsonChanged) {
|
|
8012
8142
|
logger.logger?.log('Scan complete. No Socket.dev optimized overrides applied.');
|
|
8013
8143
|
}
|
|
8144
|
+
logger.logger.log('');
|
|
8145
|
+
logger.logger.success('Finished!');
|
|
8146
|
+
logger.logger.log('');
|
|
8147
|
+
}
|
|
8148
|
+
function createActionMessage(verb, overrideCount, workspaceCount) {
|
|
8149
|
+
return `${verb} ${overrideCount} Socket.dev optimized ${words.pluralize('override', overrideCount)}${workspaceCount ? ` in ${workspaceCount} ${words.pluralize('workspace', workspaceCount)}` : ''}`;
|
|
8150
|
+
}
|
|
8151
|
+
|
|
8152
|
+
async function handleOptimize({
|
|
8153
|
+
cwd,
|
|
8154
|
+
outputKind,
|
|
8155
|
+
pin,
|
|
8156
|
+
prod
|
|
8157
|
+
}) {
|
|
8158
|
+
const result = await applyOptimization(cwd, pin, prod);
|
|
8159
|
+
await outputOptimizeResult(result, outputKind);
|
|
8014
8160
|
}
|
|
8015
8161
|
|
|
8016
8162
|
const {
|
|
@@ -8035,14 +8181,14 @@ const config$q = {
|
|
|
8035
8181
|
},
|
|
8036
8182
|
help: (command, config) => `
|
|
8037
8183
|
Usage
|
|
8038
|
-
$ ${command}
|
|
8184
|
+
$ ${command} [options] [CWD=.]
|
|
8039
8185
|
|
|
8040
8186
|
Options
|
|
8041
8187
|
${utils.getFlagListOutput(config.flags, 6)}
|
|
8042
8188
|
|
|
8043
8189
|
Examples
|
|
8044
8190
|
$ ${command}
|
|
8045
|
-
$ ${command} --pin
|
|
8191
|
+
$ ${command} ./proj/tree --pin
|
|
8046
8192
|
`
|
|
8047
8193
|
};
|
|
8048
8194
|
const cmdOptimize = {
|
|
@@ -8059,15 +8205,29 @@ async function run$q(argv, importMeta, {
|
|
|
8059
8205
|
importMeta,
|
|
8060
8206
|
parentName
|
|
8061
8207
|
});
|
|
8062
|
-
|
|
8063
|
-
|
|
8064
|
-
|
|
8065
|
-
|
|
8208
|
+
const {
|
|
8209
|
+
json,
|
|
8210
|
+
markdown
|
|
8211
|
+
} = cli.flags;
|
|
8212
|
+
const {
|
|
8213
|
+
pin,
|
|
8214
|
+
prod
|
|
8215
|
+
} = cli.flags;
|
|
8216
|
+
const outputKind = utils.getOutputKind(json, markdown);
|
|
8217
|
+
let [cwd = '.'] = cli.input;
|
|
8218
|
+
// Note: path.resolve vs .join:
|
|
8219
|
+
// If given path is absolute then cwd should not affect it.
|
|
8220
|
+
cwd = path.resolve(process.cwd(), cwd);
|
|
8066
8221
|
if (cli.flags['dryRun']) {
|
|
8067
8222
|
logger.logger.log(DRY_RUN_BAILING_NOW$o);
|
|
8068
8223
|
return;
|
|
8069
8224
|
}
|
|
8070
|
-
await
|
|
8225
|
+
await handleOptimize({
|
|
8226
|
+
cwd,
|
|
8227
|
+
pin: Boolean(pin),
|
|
8228
|
+
outputKind,
|
|
8229
|
+
prod: Boolean(prod)
|
|
8230
|
+
});
|
|
8071
8231
|
}
|
|
8072
8232
|
|
|
8073
8233
|
async function fetchOrganization() {
|
|
@@ -9726,7 +9886,7 @@ async function fetchListAllRepos({
|
|
|
9726
9886
|
page: String(nextPage)
|
|
9727
9887
|
}), 'list of repositories');
|
|
9728
9888
|
if (!result.ok) {
|
|
9729
|
-
debug.debugFn('
|
|
9889
|
+
debug.debugFn('fail: fetch repo\n', result);
|
|
9730
9890
|
return result;
|
|
9731
9891
|
}
|
|
9732
9892
|
result.data.results.forEach(row => rows.push(row));
|
|
@@ -11233,7 +11393,7 @@ async function scanOneRepo(repoSlug, {
|
|
|
11233
11393
|
};
|
|
11234
11394
|
}
|
|
11235
11395
|
const tmpDir = fs$1.mkdtempSync(path.join(os.tmpdir(), repoSlug));
|
|
11236
|
-
debug.debugFn('
|
|
11396
|
+
debug.debugFn('init: temp dir for scan root', tmpDir);
|
|
11237
11397
|
const downloadResult = await testAndDownloadManifestFiles({
|
|
11238
11398
|
files,
|
|
11239
11399
|
tmpDir,
|
|
@@ -11346,7 +11506,7 @@ async function testAndDownloadManifestFile({
|
|
|
11346
11506
|
repoApiUrl,
|
|
11347
11507
|
tmpDir
|
|
11348
11508
|
}) {
|
|
11349
|
-
debug.debugFn('
|
|
11509
|
+
debug.debugFn('test: file', file);
|
|
11350
11510
|
if (!SUPPORTED_FILE_PATTERNS.some(regex => regex.test(file))) {
|
|
11351
11511
|
// Not an error.
|
|
11352
11512
|
return {
|
|
@@ -11356,7 +11516,7 @@ async function testAndDownloadManifestFile({
|
|
|
11356
11516
|
}
|
|
11357
11517
|
};
|
|
11358
11518
|
}
|
|
11359
|
-
debug.
|
|
11519
|
+
debug.debugFn('found: manifest file', file);
|
|
11360
11520
|
const result = await downloadManifestFile({
|
|
11361
11521
|
file,
|
|
11362
11522
|
tmpDir,
|
|
@@ -11364,15 +11524,12 @@ async function testAndDownloadManifestFile({
|
|
|
11364
11524
|
repoApiUrl,
|
|
11365
11525
|
githubToken
|
|
11366
11526
|
});
|
|
11367
|
-
|
|
11368
|
-
return result;
|
|
11369
|
-
}
|
|
11370
|
-
return {
|
|
11527
|
+
return result.ok ? {
|
|
11371
11528
|
ok: true,
|
|
11372
11529
|
data: {
|
|
11373
11530
|
isManifest: true
|
|
11374
11531
|
}
|
|
11375
|
-
};
|
|
11532
|
+
} : result;
|
|
11376
11533
|
}
|
|
11377
11534
|
async function downloadManifestFile({
|
|
11378
11535
|
defaultBranch,
|
|
@@ -11381,34 +11538,33 @@ async function downloadManifestFile({
|
|
|
11381
11538
|
repoApiUrl,
|
|
11382
11539
|
tmpDir
|
|
11383
11540
|
}) {
|
|
11384
|
-
debug.
|
|
11541
|
+
debug.debugFn('request: download url from GitHub');
|
|
11385
11542
|
const fileUrl = `${repoApiUrl}/contents/${file}?ref=${defaultBranch}`;
|
|
11386
|
-
debug.debugFn('
|
|
11543
|
+
debug.debugFn('url: file', fileUrl);
|
|
11387
11544
|
const downloadUrlResponse = await fetch(fileUrl, {
|
|
11388
11545
|
method: 'GET',
|
|
11389
11546
|
headers: {
|
|
11390
11547
|
Authorization: `Bearer ${githubToken}`
|
|
11391
11548
|
}
|
|
11392
11549
|
});
|
|
11393
|
-
debug.
|
|
11550
|
+
debug.debugFn('complete: request');
|
|
11394
11551
|
const downloadUrlText = await downloadUrlResponse.text();
|
|
11395
|
-
debug.debugFn('
|
|
11552
|
+
debug.debugFn('response: raw download url', downloadUrlText);
|
|
11396
11553
|
let downloadUrl;
|
|
11397
11554
|
try {
|
|
11398
11555
|
downloadUrl = JSON.parse(downloadUrlText).download_url;
|
|
11399
11556
|
} catch {
|
|
11400
11557
|
logger.logger.fail(`GitHub response contained invalid JSON for download url for: ${file}`);
|
|
11401
|
-
debug.
|
|
11402
|
-
debug.debugLog(downloadUrlText);
|
|
11558
|
+
debug.debugFn('content: raw (not JSON)', downloadUrlText);
|
|
11403
11559
|
return {
|
|
11404
11560
|
ok: false,
|
|
11405
11561
|
message: 'Invalid JSON response',
|
|
11406
11562
|
cause: `Server responded with invalid JSON for download url ${downloadUrl}`
|
|
11407
11563
|
};
|
|
11408
11564
|
}
|
|
11409
|
-
debug.
|
|
11565
|
+
debug.debugFn('download: manifest file');
|
|
11410
11566
|
const localPath = path.join(tmpDir, file);
|
|
11411
|
-
debug.debugFn('
|
|
11567
|
+
debug.debugFn('download:', downloadUrl, '->', localPath);
|
|
11412
11568
|
|
|
11413
11569
|
// Now stream the file to that file...
|
|
11414
11570
|
|
|
@@ -11495,14 +11651,14 @@ async function getLastCommitDetails({
|
|
|
11495
11651
|
}) {
|
|
11496
11652
|
logger.logger.info(`Requesting last commit for default branch ${defaultBranch} for ${orgGithub}/${repoSlug}...`);
|
|
11497
11653
|
const commitApiUrl = `${repoApiUrl}/commits?sha=${defaultBranch}&per_page=1`;
|
|
11498
|
-
debug.debugFn('
|
|
11654
|
+
debug.debugFn('url: commit', commitApiUrl);
|
|
11499
11655
|
const commitResponse = await fetch(commitApiUrl, {
|
|
11500
11656
|
headers: {
|
|
11501
11657
|
Authorization: `Bearer ${githubToken}`
|
|
11502
11658
|
}
|
|
11503
11659
|
});
|
|
11504
11660
|
const commitText = await commitResponse.text();
|
|
11505
|
-
debug.debugFn('
|
|
11661
|
+
debug.debugFn('response: commit', commitText);
|
|
11506
11662
|
let lastCommit;
|
|
11507
11663
|
try {
|
|
11508
11664
|
lastCommit = JSON.parse(commitText)?.[0];
|
|
@@ -11589,7 +11745,7 @@ async function getRepoDetails({
|
|
|
11589
11745
|
repoSlug
|
|
11590
11746
|
}) {
|
|
11591
11747
|
const repoApiUrl = `${githubApiUrl}/repos/${orgGithub}/${repoSlug}`;
|
|
11592
|
-
debug.debugFn('
|
|
11748
|
+
debug.debugFn('url: repo', repoApiUrl);
|
|
11593
11749
|
const repoDetailsResponse = await fetch(repoApiUrl, {
|
|
11594
11750
|
method: 'GET',
|
|
11595
11751
|
headers: {
|
|
@@ -11598,7 +11754,7 @@ async function getRepoDetails({
|
|
|
11598
11754
|
});
|
|
11599
11755
|
logger.logger.success(`Request completed.`);
|
|
11600
11756
|
const repoDetailsText = await repoDetailsResponse.text();
|
|
11601
|
-
debug.debugFn('
|
|
11757
|
+
debug.debugFn('response: repo', repoDetailsText);
|
|
11602
11758
|
let repoDetails;
|
|
11603
11759
|
try {
|
|
11604
11760
|
repoDetails = JSON.parse(repoDetailsText);
|
|
@@ -11637,7 +11793,7 @@ async function getRepoBranchTree({
|
|
|
11637
11793
|
}) {
|
|
11638
11794
|
logger.logger.info(`Requesting default branch file tree; branch \`${defaultBranch}\`, repo \`${orgGithub}/${repoSlug}\`...`);
|
|
11639
11795
|
const treeApiUrl = `${repoApiUrl}/git/trees/${defaultBranch}?recursive=1`;
|
|
11640
|
-
debug.debugFn('
|
|
11796
|
+
debug.debugFn('url: tree', treeApiUrl);
|
|
11641
11797
|
const treeResponse = await fetch(treeApiUrl, {
|
|
11642
11798
|
method: 'GET',
|
|
11643
11799
|
headers: {
|
|
@@ -11645,7 +11801,7 @@ async function getRepoBranchTree({
|
|
|
11645
11801
|
}
|
|
11646
11802
|
});
|
|
11647
11803
|
const treeText = await treeResponse.text();
|
|
11648
|
-
debug.debugFn('
|
|
11804
|
+
debug.debugFn('response: tree', treeText);
|
|
11649
11805
|
let treeDetails;
|
|
11650
11806
|
try {
|
|
11651
11807
|
treeDetails = JSON.parse(treeText);
|
|
@@ -12422,7 +12578,7 @@ async function fetchScan(orgSlug, scanId) {
|
|
|
12422
12578
|
return JSON.parse(line);
|
|
12423
12579
|
} catch {
|
|
12424
12580
|
ok = false;
|
|
12425
|
-
debug.debugFn('
|
|
12581
|
+
debug.debugFn('fail: parse NDJSON\n', line);
|
|
12426
12582
|
return null;
|
|
12427
12583
|
}
|
|
12428
12584
|
});
|
|
@@ -13207,7 +13363,7 @@ Do you want to install "safe npm" (this will create an alias to the socket-npm c
|
|
|
13207
13363
|
}
|
|
13208
13364
|
}
|
|
13209
13365
|
} catch (e) {
|
|
13210
|
-
debug.debugFn('
|
|
13366
|
+
debug.debugFn('fail: setup tab completion\n', e);
|
|
13211
13367
|
// Ignore. Skip tab completion setup.
|
|
13212
13368
|
}
|
|
13213
13369
|
if (!updatedTabCompletion) {
|
|
@@ -13449,5 +13605,5 @@ void (async () => {
|
|
|
13449
13605
|
await utils.captureException(e);
|
|
13450
13606
|
}
|
|
13451
13607
|
})();
|
|
13452
|
-
//# debugId=
|
|
13608
|
+
//# debugId=7e206930-1632-4ae3-b9bc-0c092c388970
|
|
13453
13609
|
//# sourceMappingURL=cli.js.map
|