socket 0.15.60 → 0.15.62

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 CHANGED
@@ -3660,29 +3660,64 @@ async function outputFixResult(result, outputKind) {
3660
3660
  function formatBranchName(name) {
3661
3661
  return name.replace(/[^-a-zA-Z0-9/._-]+/g, '+');
3662
3662
  }
3663
- function getBaseGitBranch() {
3664
- // Lazily access constants.ENV.GITHUB_REF_NAME.
3665
- return constants.ENV.GITHUB_REF_NAME ||
3663
+ function createSocketBranchParser(options) {
3664
+ const pattern = getSocketBranchPattern(options);
3665
+ return function parse(branch) {
3666
+ const match = pattern.exec(branch);
3667
+ if (!match) {
3668
+ return null;
3669
+ }
3670
+ const {
3671
+ 1: type,
3672
+ 2: workspace,
3673
+ 3: fullName,
3674
+ 4: version,
3675
+ 5: newVersion
3676
+ } = match;
3677
+ return {
3678
+ fullName,
3679
+ newVersion: vendor.semverExports.coerce(newVersion.replaceAll('+', '.'))?.version,
3680
+ type,
3681
+ workspace,
3682
+ version: vendor.semverExports.coerce(version.replaceAll('+', '.'))?.version
3683
+ };
3684
+ };
3685
+ }
3686
+ async function getBaseGitBranch(cwd = process.cwd()) {
3687
+ // Lazily access constants.ENV properties.
3688
+ const {
3689
+ GITHUB_BASE_REF,
3690
+ GITHUB_REF_NAME,
3691
+ GITHUB_REF_TYPE
3692
+ } = constants.ENV;
3693
+ // 1. In a pull request, this is always the base branch.
3694
+ if (GITHUB_BASE_REF) {
3695
+ return GITHUB_BASE_REF;
3696
+ }
3697
+ // 2. If it's a branch (not a tag), GITHUB_REF_TYPE should be 'branch'.
3698
+ if (GITHUB_REF_TYPE === 'branch' && GITHUB_REF_NAME) {
3699
+ return GITHUB_REF_NAME;
3700
+ }
3701
+ // 3. Try to resolve the default remote branch using 'git remote show origin'.
3702
+ // This handles detached HEADs or workflows triggered by tags/releases.
3703
+ try {
3704
+ const stdout = (await spawn.spawn('git', ['remote', 'show', 'origin'], {
3705
+ cwd
3706
+ })).stdout.trim();
3707
+ const match = /(?<=HEAD branch: ).+/.exec(stdout);
3708
+ if (match?.[0]) {
3709
+ return match[0].trim();
3710
+ }
3711
+ } catch {}
3666
3712
  // GitHub defaults to branch name "main"
3667
3713
  // https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-branches#about-the-default-branch
3668
- 'main';
3669
- }
3670
- function getSocketBranchPurlTypeComponent(purl) {
3671
- const purlObj = utils.getPurlObject(purl);
3672
- return formatBranchName(purlObj.type);
3714
+ return 'main';
3673
3715
  }
3674
3716
  function getSocketBranchFullNameComponent(pkgName) {
3675
3717
  const purlObj = utils.getPurlObject(typeof pkgName === 'string' && !pkgName.startsWith('pkg:') ? vendor.packageurlJsExports.PackageURL.fromString(`pkg:unknown/${pkgName}`) : pkgName);
3676
3718
  const fmtMaybeNamespace = purlObj.namespace ? `${formatBranchName(purlObj.namespace)}--` : '';
3677
3719
  return `${fmtMaybeNamespace}${formatBranchName(purlObj.name)}`;
3678
3720
  }
3679
- function getSocketBranchPackageVersionComponent(version) {
3680
- const purlObj = utils.getPurlObject(typeof version === 'string' && !version.startsWith('pkg:') ? vendor.packageurlJsExports.PackageURL.fromString(`pkg:unknown/unknown@${version}`) : version);
3681
- return formatBranchName(purlObj.version);
3682
- }
3683
- function getSocketBranchWorkspaceComponent(workspace) {
3684
- return workspace ? formatBranchName(workspace) : 'root';
3685
- }
3686
3721
  function getSocketBranchName(purl, newVersion, workspace) {
3687
3722
  const purlObj = utils.getPurlObject(purl);
3688
3723
  const fmtType = getSocketBranchPurlTypeComponent(purlObj);
@@ -3692,6 +3727,10 @@ function getSocketBranchName(purl, newVersion, workspace) {
3692
3727
  const fmtNewVersion = formatBranchName(newVersion);
3693
3728
  return `socket/${fmtType}/${fmtWorkspace}/${fmtFullName}_${fmtVersion}_${fmtNewVersion}`;
3694
3729
  }
3730
+ function getSocketBranchPackageVersionComponent(version) {
3731
+ const purlObj = utils.getPurlObject(typeof version === 'string' && !version.startsWith('pkg:') ? vendor.packageurlJsExports.PackageURL.fromString(`pkg:unknown/unknown@${version}`) : version);
3732
+ return formatBranchName(purlObj.version);
3733
+ }
3695
3734
  function getSocketBranchPattern(options) {
3696
3735
  const {
3697
3736
  newVersion,
@@ -3710,33 +3749,17 @@ function getSocketBranchPattern(options) {
3710
3749
  const escNewVersion = newVersion ? regexps.escapeRegExp(formatBranchName(newVersion)) : '[^_]+';
3711
3750
  return new RegExp(`^socket/(${escType})/(${escWorkspace})/(${escFullName})_(${escVersion})_(${escNewVersion})$`);
3712
3751
  }
3713
- function createSocketBranchParser(options) {
3714
- const pattern = getSocketBranchPattern(options);
3715
- return function parse(branch) {
3716
- const match = pattern.exec(branch);
3717
- if (!match) {
3718
- return null;
3719
- }
3720
- const {
3721
- 1: type,
3722
- 2: workspace,
3723
- 3: fullName,
3724
- 4: version,
3725
- 5: newVersion
3726
- } = match;
3727
- return {
3728
- fullName,
3729
- newVersion: vendor.semverExports.coerce(newVersion.replaceAll('+', '.'))?.version,
3730
- type,
3731
- workspace,
3732
- version: vendor.semverExports.coerce(version.replaceAll('+', '.'))?.version
3733
- };
3734
- };
3752
+ function getSocketBranchPurlTypeComponent(purl) {
3753
+ const purlObj = utils.getPurlObject(purl);
3754
+ return formatBranchName(purlObj.type);
3735
3755
  }
3736
- function getSocketPullRequestTitle(purl, newVersion, workspace) {
3756
+ function getSocketBranchWorkspaceComponent(workspace) {
3757
+ return workspace ? formatBranchName(workspace) : 'root';
3758
+ }
3759
+ function getSocketCommitMessage(purl, newVersion, workspace) {
3737
3760
  const purlObj = utils.getPurlObject(purl);
3738
3761
  const fullName = utils.getPkgFullNameFromPurl(purlObj);
3739
- return `Bump ${fullName} from ${purlObj.version} to ${newVersion}${workspace ? ` in ${workspace}` : ''}`;
3762
+ return `socket: Bump ${fullName} from ${purlObj.version} to ${newVersion}${workspace ? ` in ${workspace}` : ''}`;
3740
3763
  }
3741
3764
  function getSocketPullRequestBody(purl, newVersion, workspace) {
3742
3765
  const purlObj = utils.getPurlObject(purl);
@@ -3744,10 +3767,10 @@ function getSocketPullRequestBody(purl, newVersion, workspace) {
3744
3767
  const pkgOverviewUrl = utils.getSocketDevPackageOverviewUrlFromPurl(purlObj);
3745
3768
  return `Bump [${fullName}](${pkgOverviewUrl}) from ${purlObj.version} to ${newVersion}${workspace ? ` in ${workspace}` : ''}.`;
3746
3769
  }
3747
- function getSocketCommitMessage(purl, newVersion, workspace) {
3770
+ function getSocketPullRequestTitle(purl, newVersion, workspace) {
3748
3771
  const purlObj = utils.getPurlObject(purl);
3749
3772
  const fullName = utils.getPkgFullNameFromPurl(purlObj);
3750
- return `socket: Bump ${fullName} from ${purlObj.version} to ${newVersion}${workspace ? ` in ${workspace}` : ''}`;
3773
+ return `Bump ${fullName} from ${purlObj.version} to ${newVersion}${workspace ? ` in ${workspace}` : ''}`;
3751
3774
  }
3752
3775
  async function gitCleanFdx(cwd = process.cwd()) {
3753
3776
  const stdioIgnoreOptions = {
@@ -3780,7 +3803,7 @@ async function gitCreateAndPushBranch(branch, commitMsg, filepaths, options) {
3780
3803
  await spawn.spawn('git', ['push', '--force', '--set-upstream', 'origin', branch], stdioIgnoreOptions);
3781
3804
  return true;
3782
3805
  } catch (e) {
3783
- debug.debugFn('catch: unexpected\n', e);
3806
+ debug.debugFn(`catch: git push --force --set-upstream origin ${branch} failed\n`, e);
3784
3807
  }
3785
3808
  try {
3786
3809
  // Will throw with exit code 1 if branch does not exist.
@@ -3788,6 +3811,38 @@ async function gitCreateAndPushBranch(branch, commitMsg, filepaths, options) {
3788
3811
  } catch {}
3789
3812
  return false;
3790
3813
  }
3814
+ async function gitRepoInfo(cwd = process.cwd()) {
3815
+ try {
3816
+ const remoteUrl = (await spawn.spawn('git', ['remote', 'get-url', 'origin'], {
3817
+ cwd
3818
+ })).stdout.trim();
3819
+ // 1. Handle SSH-style, e.g. git@github.com:owner/repo.git
3820
+ const sshMatch = /^git@[^:]+:([^/]+)\/(.+?)(?:\.git)?$/.exec(remoteUrl);
3821
+ if (sshMatch) {
3822
+ return {
3823
+ owner: sshMatch[1],
3824
+ repo: sshMatch[2]
3825
+ };
3826
+ }
3827
+ // 2. Handle HTTPS/URL-style, e.g. https://github.com/owner/repo.git
3828
+ try {
3829
+ const parsed = new URL(remoteUrl);
3830
+ const segments = parsed.pathname.split('/');
3831
+ const owner = segments.at(-2);
3832
+ const repo = segments.at(-1)?.replace(/\.git$/, '');
3833
+ if (owner && repo) {
3834
+ return {
3835
+ owner,
3836
+ repo
3837
+ };
3838
+ }
3839
+ } catch {}
3840
+ debug.debugFn('git: unmatched git remote URL format', remoteUrl);
3841
+ } catch (e) {
3842
+ debug.debugFn('catch: git remote get-url origin failed\n', e);
3843
+ }
3844
+ return null;
3845
+ }
3791
3846
  async function gitEnsureIdentity(name, email, cwd = process.cwd()) {
3792
3847
  const stdioIgnoreOptions = {
3793
3848
  cwd,
@@ -3810,7 +3865,7 @@ async function gitEnsureIdentity(name, email, cwd = process.cwd()) {
3810
3865
  try {
3811
3866
  await spawn.spawn('git', ['config', prop, value], stdioIgnoreOptions);
3812
3867
  } catch (e) {
3813
- debug.debugFn('catch: unexpected\n', e);
3868
+ debug.debugFn(`catch: git config ${prop} ${value} failed\n`, e);
3814
3869
  }
3815
3870
  }
3816
3871
  }));
@@ -3859,6 +3914,28 @@ async function gitUnstagedModifiedFiles(cwd = process.cwd()) {
3859
3914
  }
3860
3915
  }
3861
3916
 
3917
+ function getActiveBranchesForPackage(ciEnv, partialPurl, openPrs) {
3918
+ if (!ciEnv) {
3919
+ return [];
3920
+ }
3921
+ const partialPurlObj = utils.getPurlObject(partialPurl);
3922
+ const activeBranches = [];
3923
+ const branchFullName = getSocketBranchFullNameComponent(partialPurlObj);
3924
+ const branchPurlType = getSocketBranchPurlTypeComponent(partialPurlObj);
3925
+ for (const pr of openPrs) {
3926
+ const parsedBranch = ciEnv.branchParser(pr.headRefName);
3927
+ if (branchPurlType === parsedBranch?.type && branchFullName === parsedBranch?.fullName) {
3928
+ activeBranches.push(parsedBranch);
3929
+ }
3930
+ }
3931
+ if (activeBranches.length) {
3932
+ debug.debugFn(`found: ${activeBranches.length} active branches\n`, activeBranches);
3933
+ } else if (openPrs.length) {
3934
+ debug.debugFn('miss: 0 active branches found');
3935
+ }
3936
+ return activeBranches;
3937
+ }
3938
+
3862
3939
  let _octokit;
3863
3940
  function getOctokit() {
3864
3941
  if (_octokit === undefined) {
@@ -4053,24 +4130,6 @@ async function enablePrAutoMerge({
4053
4130
  enabled: false
4054
4131
  };
4055
4132
  }
4056
- function getGithubEnvRepoInfo() {
4057
- // Lazily access constants.ENV.GITHUB_REPOSITORY.
4058
- const {
4059
- GITHUB_REPOSITORY
4060
- } = constants.ENV;
4061
- if (!GITHUB_REPOSITORY) {
4062
- debug.debugFn('miss: GITHUB_REPOSITORY env var');
4063
- }
4064
- const ownerSlashRepo = GITHUB_REPOSITORY;
4065
- const slashIndex = ownerSlashRepo.indexOf('/');
4066
- if (slashIndex === -1) {
4067
- return null;
4068
- }
4069
- return {
4070
- owner: ownerSlashRepo.slice(0, slashIndex),
4071
- repo: ownerSlashRepo.slice(slashIndex + 1)
4072
- };
4073
- }
4074
4133
  async function getOpenSocketPrs(owner, repo, options) {
4075
4134
  return (await getOpenSocketPrsWithContext(owner, repo, options)).map(d => d.match);
4076
4135
  }
@@ -4196,11 +4255,6 @@ async function openPr(owner, repo, branch, purl, newVersion, options) {
4196
4255
  __proto__: null,
4197
4256
  ...options
4198
4257
  };
4199
- // Lazily access constants.ENV.GITHUB_ACTIONS.
4200
- if (!constants.ENV.GITHUB_ACTIONS) {
4201
- debug.debugFn('miss: GITHUB_ACTIONS env var');
4202
- return null;
4203
- }
4204
4258
  const purlObj = utils.getPurlObject(purl);
4205
4259
  const octokit = getOctokit();
4206
4260
  try {
@@ -4252,6 +4306,55 @@ async function setGitRemoteGithubRepoUrl(owner, repo, token, cwd = process.cwd()
4252
4306
  }
4253
4307
  }
4254
4308
 
4309
+ async function getEnvRepoInfo(cwd) {
4310
+ // Lazily access constants.ENV.GITHUB_REPOSITORY.
4311
+ const {
4312
+ GITHUB_REPOSITORY
4313
+ } = constants.ENV;
4314
+ if (!GITHUB_REPOSITORY) {
4315
+ debug.debugFn('miss: GITHUB_REPOSITORY env var');
4316
+ }
4317
+ const ownerSlashRepo = GITHUB_REPOSITORY;
4318
+ const slashIndex = ownerSlashRepo.indexOf('/');
4319
+ if (slashIndex !== -1) {
4320
+ return {
4321
+ owner: ownerSlashRepo.slice(0, slashIndex),
4322
+ repo: ownerSlashRepo.slice(slashIndex + 1)
4323
+ };
4324
+ }
4325
+ return await gitRepoInfo(cwd);
4326
+ }
4327
+ async function getCiEnv() {
4328
+ const gitEmail = constants.ENV.SOCKET_CLI_GIT_USER_EMAIL;
4329
+ const gitUser = constants.ENV.SOCKET_CLI_GIT_USER_NAME;
4330
+ const githubToken = constants.ENV.SOCKET_CLI_GITHUB_TOKEN;
4331
+ const isCi = !!(constants.ENV.CI && gitEmail && gitUser && githubToken);
4332
+ if (!isCi) {
4333
+ return null;
4334
+ }
4335
+ const baseBranch = await getBaseGitBranch();
4336
+ if (!baseBranch) {
4337
+ return null;
4338
+ }
4339
+ const repoInfo = await getEnvRepoInfo();
4340
+ if (!repoInfo) {
4341
+ return null;
4342
+ }
4343
+ return {
4344
+ gitEmail,
4345
+ gitUser,
4346
+ githubToken,
4347
+ repoInfo,
4348
+ baseBranch,
4349
+ branchParser: createSocketBranchParser()
4350
+ };
4351
+ }
4352
+ async function getOpenPrsForEnvironment(env) {
4353
+ return env ? await getOpenSocketPrs(env.repoInfo.owner, env.repoInfo.repo, {
4354
+ author: env.gitUser
4355
+ }) : [];
4356
+ }
4357
+
4255
4358
  const CMD_NAME$1 = 'socket fix';
4256
4359
  function getAlertsMapOptions(options = {}) {
4257
4360
  return {
@@ -4303,19 +4406,9 @@ async function npmFix(pkgEnvDetails, {
4303
4406
  const {
4304
4407
  pkgPath: rootPath
4305
4408
  } = pkgEnvDetails;
4306
-
4307
- // Lazily access constants.ENV properties.
4308
- const gitEmail = constants.ENV.SOCKET_CLI_GIT_USER_EMAIL;
4309
- const gitUser = constants.ENV.SOCKET_CLI_GIT_USER_NAME;
4310
- const githubToken = constants.ENV.SOCKET_CLI_GITHUB_TOKEN;
4311
- const isCi = !!(constants.ENV.CI && constants.ENV.GITHUB_ACTIONS && constants.ENV.GITHUB_REPOSITORY && gitEmail && gitUser && githubToken);
4312
- const repoInfo = isCi ? getGithubEnvRepoInfo() : null;
4313
4409
  spinner?.start();
4314
- const openPrs =
4315
- // Check repoInfo to make TypeScript happy.
4316
- isCi && repoInfo ? await getOpenSocketPrs(repoInfo.owner, repoInfo.repo, {
4317
- author: gitUser
4318
- }) : [];
4410
+ const ciEnv = await getCiEnv();
4411
+ const openPrs = ciEnv ? await getOpenPrsForEnvironment(ciEnv) : [];
4319
4412
  let count = 0;
4320
4413
  const arb = new shadowNpmInject.Arborist({
4321
4414
  path: rootPath,
@@ -4353,17 +4446,23 @@ async function npmFix(pkgEnvDetails, {
4353
4446
  }
4354
4447
  };
4355
4448
  }
4356
- const baseBranch = isCi ? getBaseGitBranch() : '';
4357
- const branchParser = isCi ? createSocketBranchParser() : null;
4449
+
4450
+ // Lazily access constants.packumentCache.
4451
+ const {
4452
+ packumentCache
4453
+ } = constants;
4358
4454
  const workspacePkgJsonPaths = await utils.globWorkspace(pkgEnvDetails.agent, rootPath);
4359
4455
  const pkgJsonPaths = [...workspacePkgJsonPaths,
4360
4456
  // Process the workspace root last since it will add an override to package.json.
4361
4457
  pkgEnvDetails.editablePkgJson.filename];
4362
4458
  const sortedInfoEntries = [...infoByPartialPurl.entries()].sort((a, b) => sorts.naturalCompare(a[0], b[0]));
4363
- const handleInstallFail = () => {
4364
- debug.debugFn(`fail: ${pkgEnvDetails.agent} install\n`);
4459
+ const cleanupInfoEntriesLoop = () => {
4365
4460
  logger.logger.dedent();
4366
4461
  spinner?.dedent();
4462
+ packumentCache.clear();
4463
+ };
4464
+ const handleInstallFail = () => {
4465
+ cleanupInfoEntriesLoop();
4367
4466
  return {
4368
4467
  ok: false,
4369
4468
  message: 'Installation failure',
@@ -4382,22 +4481,7 @@ async function npmFix(pkgEnvDetails, {
4382
4481
  if (!infos.length) {
4383
4482
  continue infoEntriesLoop;
4384
4483
  }
4385
- const activeBranches = [];
4386
- if (isCi) {
4387
- const branchFullName = getSocketBranchFullNameComponent(partialPurlObj);
4388
- const branchPurlType = getSocketBranchPurlTypeComponent(partialPurlObj);
4389
- for (const pr of openPrs) {
4390
- const parsedBranch = branchParser(pr.headRefName);
4391
- if (branchPurlType === parsedBranch?.type && branchFullName === parsedBranch?.fullName) {
4392
- activeBranches.push(parsedBranch);
4393
- }
4394
- }
4395
- if (activeBranches.length) {
4396
- debug.debugFn(`found: ${activeBranches.length} active branches\n`, activeBranches);
4397
- } else if (openPrs.length) {
4398
- debug.debugFn('miss: 0 active branches found');
4399
- }
4400
- }
4484
+ const activeBranches = getActiveBranchesForPackage(ciEnv, infoEntry[0], openPrs);
4401
4485
  logger.logger.log(`Processing vulns for ${name}:`);
4402
4486
  logger.logger.indent();
4403
4487
  spinner?.indent();
@@ -4408,8 +4492,7 @@ async function npmFix(pkgEnvDetails, {
4408
4492
  const packument = await packages.fetchPackagePackument(name);
4409
4493
  if (!packument) {
4410
4494
  logger.logger.warn(`Unexpected condition: No packument found for ${name}.\n`);
4411
- logger.logger.dedent();
4412
- spinner?.dedent();
4495
+ cleanupInfoEntriesLoop();
4413
4496
  continue infoEntriesLoop;
4414
4497
  }
4415
4498
  const availableVersions = Object.keys(packument.versions);
@@ -4424,13 +4507,12 @@ async function npmFix(pkgEnvDetails, {
4424
4507
  const pkgPath = path.dirname(pkgJsonPath);
4425
4508
  const isWorkspaceRoot = pkgJsonPath === pkgEnvDetails.editablePkgJson.filename;
4426
4509
  const workspace = isWorkspaceRoot ? 'root' : path.relative(rootPath, pkgPath);
4427
- const branchWorkspace = isCi ? getSocketBranchWorkspaceComponent(workspace) : '';
4510
+ const branchWorkspace = ciEnv ? getSocketBranchWorkspaceComponent(workspace) : '';
4428
4511
  const oldVersions = arrays.arrayUnique(shadowNpmInject.findPackageNodes(actualTree, name).map(n => n.target?.version ?? n.version).filter(Boolean));
4429
4512
  if (!oldVersions.length) {
4430
4513
  debug.debugFn(`skip: ${name} not found\n`);
4431
4514
  // Skip to next package.
4432
- logger.logger.dedent();
4433
- spinner?.dedent();
4515
+ cleanupInfoEntriesLoop();
4434
4516
  continue infoEntriesLoop;
4435
4517
  }
4436
4518
 
@@ -4440,6 +4522,7 @@ async function npmFix(pkgEnvDetails, {
4440
4522
  const editablePkgJson = await packages.readPackageJson(pkgJsonPath, {
4441
4523
  editable: true
4442
4524
  });
4525
+ const fixedVersions = new Set();
4443
4526
  let hasAnnouncedWorkspace = false;
4444
4527
  let workspaceLogCallCount = logger.logger.logCallCount;
4445
4528
  if (debug.isDebug()) {
@@ -4459,25 +4542,27 @@ async function npmFix(pkgEnvDetails, {
4459
4542
  firstPatchedVersionIdentifier,
4460
4543
  vulnerableVersionRange
4461
4544
  } of infos.values()) {
4462
- if (vendor.semverExports.gte(oldVersion, firstPatchedVersionIdentifier)) {
4463
- debug.debugFn(`skip: ${oldId} is >= ${firstPatchedVersionIdentifier}`);
4545
+ const newVersion = shadowNpmInject.findBestPatchVersion(node, availableVersions, vulnerableVersionRange);
4546
+ const newVersionPackument = newVersion ? packument.versions[newVersion] : undefined;
4547
+ if (!(newVersion && newVersionPackument)) {
4548
+ warningsForAfter.add(`${oldId} not updated: requires >=${firstPatchedVersionIdentifier}`);
4549
+ continue infosLoop;
4550
+ }
4551
+ if (fixedVersions.has(newVersion)) {
4552
+ continue infosLoop;
4553
+ }
4554
+ if (vendor.semverExports.gte(oldVersion, newVersion)) {
4555
+ debug.debugFn(`skip: ${oldId} is >= ${newVersion}`);
4464
4556
  continue infosLoop;
4465
4557
  }
4466
- const newVersion = shadowNpmInject.findBestPatchVersion(node, availableVersions, vulnerableVersionRange);
4467
4558
  if (activeBranches.find(b => b.workspace === branchWorkspace && b.newVersion === newVersion)) {
4468
4559
  debug.debugFn(`skip: open PR found for ${name}@${newVersion}`);
4469
4560
  if (++count >= limit) {
4470
- logger.logger.dedent();
4471
- spinner?.dedent();
4561
+ cleanupInfoEntriesLoop();
4472
4562
  break infoEntriesLoop;
4473
4563
  }
4474
4564
  continue infosLoop;
4475
4565
  }
4476
- const newVersionPackument = newVersion ? packument.versions[newVersion] : undefined;
4477
- if (!(newVersion && newVersionPackument)) {
4478
- warningsForAfter.add(`${oldId} not updated: requires >=${firstPatchedVersionIdentifier}`);
4479
- continue infosLoop;
4480
- }
4481
4566
  const newVersionRange = utils.applyRange(oldVersion, newVersion, rangeStyle);
4482
4567
  const newId = `${name}@${newVersionRange}`;
4483
4568
  const revertData = {
@@ -4507,9 +4592,9 @@ async function npmFix(pkgEnvDetails, {
4507
4592
  }))) {
4508
4593
  debug.debugFn(`skip: ${workspace}/package.json unchanged`);
4509
4594
  // Reset things just in case.
4510
- if (isCi) {
4595
+ if (ciEnv) {
4511
4596
  // eslint-disable-next-line no-await-in-loop
4512
- await gitResetAndClean(baseBranch, cwd);
4597
+ await gitResetAndClean(ciEnv.baseBranch, cwd);
4513
4598
  }
4514
4599
  continue infosLoop;
4515
4600
  }
@@ -4537,6 +4622,7 @@ async function npmFix(pkgEnvDetails, {
4537
4622
  });
4538
4623
  }
4539
4624
  spinner?.success(`Fixed ${name} in ${workspace}.`);
4625
+ fixedVersions.add(newVersion);
4540
4626
  } else {
4541
4627
  errored = true;
4542
4628
  }
@@ -4547,7 +4633,7 @@ async function npmFix(pkgEnvDetails, {
4547
4633
  spinner?.stop();
4548
4634
 
4549
4635
  // Check repoInfo to make TypeScript happy.
4550
- if (!errored && isCi && repoInfo) {
4636
+ if (!errored && ciEnv?.repoInfo) {
4551
4637
  try {
4552
4638
  // eslint-disable-next-line no-await-in-loop
4553
4639
  const result = await gitUnstagedModifiedFiles(cwd);
@@ -4569,7 +4655,7 @@ async function npmFix(pkgEnvDetails, {
4569
4655
  let skipPr = false;
4570
4656
  if (
4571
4657
  // eslint-disable-next-line no-await-in-loop
4572
- await prExistForBranch(repoInfo.owner, repoInfo.repo, branch)) {
4658
+ await prExistForBranch(ciEnv.repoInfo.owner, ciEnv.repoInfo.repo, branch)) {
4573
4659
  skipPr = true;
4574
4660
  debug.debugFn(`skip: branch "${branch}" exists`);
4575
4661
  }
@@ -4581,15 +4667,15 @@ async function npmFix(pkgEnvDetails, {
4581
4667
  // eslint-disable-next-line no-await-in-loop
4582
4668
  !(await gitCreateAndPushBranch(branch, getSocketCommitMessage(oldPurl, newVersion, workspace), moddedFilepaths, {
4583
4669
  cwd,
4584
- email: gitEmail,
4585
- user: gitUser
4670
+ email: ciEnv.gitEmail,
4671
+ user: ciEnv.gitUser
4586
4672
  }))) {
4587
4673
  skipPr = true;
4588
4674
  logger.logger.warn('Unexpected condition: Push failed, skipping PR creation.');
4589
4675
  }
4590
4676
  if (skipPr) {
4591
4677
  // eslint-disable-next-line no-await-in-loop
4592
- await gitResetAndClean(baseBranch, cwd);
4678
+ await gitResetAndClean(ciEnv.baseBranch, cwd);
4593
4679
  // eslint-disable-next-line no-await-in-loop
4594
4680
  const maybeActualTree = await install$1(arb, {
4595
4681
  cwd
@@ -4603,14 +4689,14 @@ async function npmFix(pkgEnvDetails, {
4603
4689
  }
4604
4690
 
4605
4691
  // eslint-disable-next-line no-await-in-loop
4606
- await Promise.allSettled([setGitRemoteGithubRepoUrl(repoInfo.owner, repoInfo.repo, githubToken, cwd), cleanupOpenPrs(repoInfo.owner, repoInfo.repo, {
4692
+ await Promise.allSettled([setGitRemoteGithubRepoUrl(ciEnv.repoInfo.owner, ciEnv.repoInfo.repo, ciEnv.githubToken, cwd), cleanupOpenPrs(ciEnv.repoInfo.owner, ciEnv.repoInfo.repo, {
4607
4693
  newVersion,
4608
4694
  purl: oldPurl,
4609
4695
  workspace
4610
4696
  })]);
4611
4697
  // eslint-disable-next-line no-await-in-loop
4612
- const prResponse = await openPr(repoInfo.owner, repoInfo.repo, branch, oldPurl, newVersion, {
4613
- baseBranch,
4698
+ const prResponse = await openPr(ciEnv.repoInfo.owner, ciEnv.repoInfo.repo, branch, oldPurl, newVersion, {
4699
+ baseBranch: ciEnv.baseBranch,
4614
4700
  cwd,
4615
4701
  workspace
4616
4702
  });
@@ -4643,10 +4729,10 @@ async function npmFix(pkgEnvDetails, {
4643
4729
  errored = true;
4644
4730
  }
4645
4731
  }
4646
- if (isCi) {
4732
+ if (ciEnv) {
4647
4733
  spinner?.start();
4648
4734
  // eslint-disable-next-line no-await-in-loop
4649
- await gitResetAndClean(baseBranch, cwd);
4735
+ await gitResetAndClean(ciEnv.baseBranch, cwd);
4650
4736
  // eslint-disable-next-line no-await-in-loop
4651
4737
  const maybeActualTree = await install$1(arb, {
4652
4738
  cwd
@@ -4659,7 +4745,7 @@ async function npmFix(pkgEnvDetails, {
4659
4745
  }
4660
4746
  }
4661
4747
  if (errored) {
4662
- if (!isCi) {
4748
+ if (!ciEnv) {
4663
4749
  spinner?.start();
4664
4750
  editablePkgJson.update(revertData);
4665
4751
  // eslint-disable-next-line no-await-in-loop
@@ -4680,8 +4766,7 @@ async function npmFix(pkgEnvDetails, {
4680
4766
  logger.logger.fail(`Update failed for ${oldId} in ${workspace}.`, error);
4681
4767
  }
4682
4768
  if (++count >= limit) {
4683
- logger.logger.dedent();
4684
- spinner?.dedent();
4769
+ cleanupInfoEntriesLoop();
4685
4770
  break infoEntriesLoop;
4686
4771
  }
4687
4772
  }
@@ -4696,8 +4781,7 @@ async function npmFix(pkgEnvDetails, {
4696
4781
  if (!isLastInfoEntry) {
4697
4782
  logger.logger.logNewline();
4698
4783
  }
4699
- logger.logger.dedent();
4700
- spinner?.dedent();
4784
+ cleanupInfoEntriesLoop();
4701
4785
  }
4702
4786
  spinner?.stop();
4703
4787
  return {
@@ -4764,19 +4848,9 @@ async function pnpmFix(pkgEnvDetails, {
4764
4848
  const {
4765
4849
  pkgPath: rootPath
4766
4850
  } = pkgEnvDetails;
4767
-
4768
- // Lazily access constants.ENV properties.
4769
- const gitEmail = constants.ENV.SOCKET_CLI_GIT_USER_EMAIL;
4770
- const gitUser = constants.ENV.SOCKET_CLI_GIT_USER_NAME;
4771
- const githubToken = constants.ENV.SOCKET_CLI_GITHUB_TOKEN;
4772
- const isCi = !!(constants.ENV.CI && constants.ENV.GITHUB_ACTIONS && constants.ENV.GITHUB_REPOSITORY && gitEmail && gitUser && githubToken);
4773
- const repoInfo = isCi ? getGithubEnvRepoInfo() : null;
4774
4851
  spinner?.start();
4775
- const openPrs =
4776
- // Check repoInfo to make TypeScript happy.
4777
- isCi && repoInfo ? await getOpenSocketPrs(repoInfo.owner, repoInfo.repo, {
4778
- author: gitUser
4779
- }) : [];
4852
+ const ciEnv = await getCiEnv();
4853
+ const openPrs = ciEnv ? await getOpenPrsForEnvironment(ciEnv) : [];
4780
4854
  let count = 0;
4781
4855
  let actualTree;
4782
4856
  const lockfilePath = path.join(rootPath, 'pnpm-lock.yaml');
@@ -4852,16 +4926,23 @@ async function pnpmFix(pkgEnvDetails, {
4852
4926
  }
4853
4927
  };
4854
4928
  }
4855
- const baseBranch = isCi ? getBaseGitBranch() : '';
4856
- const branchParser = isCi ? createSocketBranchParser() : null;
4929
+
4930
+ // Lazily access constants.packumentCache.
4931
+ const {
4932
+ packumentCache
4933
+ } = constants;
4857
4934
  const workspacePkgJsonPaths = await utils.globWorkspace(pkgEnvDetails.agent, rootPath);
4858
4935
  const pkgJsonPaths = [...workspacePkgJsonPaths,
4859
4936
  // Process the workspace root last since it will add an override to package.json.
4860
4937
  pkgEnvDetails.editablePkgJson.filename];
4861
4938
  const sortedInfoEntries = [...infoByPartialPurl.entries()].sort((a, b) => sorts.naturalCompare(a[0], b[0]));
4862
- const handleInstallFail = () => {
4939
+ const cleanupInfoEntriesLoop = () => {
4863
4940
  logger.logger.dedent();
4864
4941
  spinner?.dedent();
4942
+ packumentCache.clear();
4943
+ };
4944
+ const handleInstallFail = () => {
4945
+ cleanupInfoEntriesLoop();
4865
4946
  return {
4866
4947
  ok: false,
4867
4948
  message: 'Install failed',
@@ -4880,22 +4961,7 @@ async function pnpmFix(pkgEnvDetails, {
4880
4961
  if (!infos.length) {
4881
4962
  continue infoEntriesLoop;
4882
4963
  }
4883
- const activeBranches = [];
4884
- if (isCi) {
4885
- const branchFullName = getSocketBranchFullNameComponent(partialPurlObj);
4886
- const branchPurlType = getSocketBranchPurlTypeComponent(partialPurlObj);
4887
- for (const pr of openPrs) {
4888
- const parsedBranch = branchParser(pr.headRefName);
4889
- if (branchPurlType === parsedBranch?.type && branchFullName === parsedBranch?.fullName) {
4890
- activeBranches.push(parsedBranch);
4891
- }
4892
- }
4893
- if (activeBranches.length) {
4894
- debug.debugFn(`found: ${activeBranches.length} active branches\n`, activeBranches);
4895
- } else if (openPrs.length) {
4896
- debug.debugFn('miss: 0 active branches found');
4897
- }
4898
- }
4964
+ const activeBranches = getActiveBranchesForPackage(ciEnv, infoEntry[0], openPrs);
4899
4965
  logger.logger.log(`Processing vulns for ${name}:`);
4900
4966
  logger.logger.indent();
4901
4967
  spinner?.indent();
@@ -4906,8 +4972,7 @@ async function pnpmFix(pkgEnvDetails, {
4906
4972
  const packument = await packages.fetchPackagePackument(name);
4907
4973
  if (!packument) {
4908
4974
  logger.logger.warn(`Unexpected condition: No packument found for ${name}.\n`);
4909
- logger.logger.dedent();
4910
- spinner?.dedent();
4975
+ cleanupInfoEntriesLoop();
4911
4976
  continue infoEntriesLoop;
4912
4977
  }
4913
4978
  const availableVersions = Object.keys(packument.versions);
@@ -4922,15 +4987,15 @@ async function pnpmFix(pkgEnvDetails, {
4922
4987
  const pkgPath = path.dirname(pkgJsonPath);
4923
4988
  const isWorkspaceRoot = pkgJsonPath === pkgEnvDetails.editablePkgJson.filename;
4924
4989
  const workspace = isWorkspaceRoot ? 'root' : path.relative(rootPath, pkgPath);
4925
- const branchWorkspace = isCi ? getSocketBranchWorkspaceComponent(workspace) : '';
4990
+ const branchWorkspace = ciEnv ? getSocketBranchWorkspaceComponent(workspace) : '';
4926
4991
 
4927
4992
  // actualTree may not be defined on the first iteration of pkgJsonPathsLoop.
4928
4993
  if (!actualTree) {
4929
- if (!isCi) {
4994
+ if (!ciEnv) {
4930
4995
  // eslint-disable-next-line no-await-in-loop
4931
4996
  await utils.removeNodeModules(cwd);
4932
4997
  }
4933
- const maybeActualTree = isCi && fs$1.existsSync(path.join(rootPath, 'node_modules')) ?
4998
+ const maybeActualTree = ciEnv && fs$1.existsSync(path.join(rootPath, 'node_modules')) ?
4934
4999
  // eslint-disable-next-line no-await-in-loop
4935
5000
  await getActualTree(cwd) :
4936
5001
  // eslint-disable-next-line no-await-in-loop
@@ -4954,8 +5019,7 @@ async function pnpmFix(pkgEnvDetails, {
4954
5019
  if (!oldVersions.length) {
4955
5020
  debug.debugFn(`skip: ${name} not found\n`);
4956
5021
  // Skip to next package.
4957
- logger.logger.dedent();
4958
- spinner?.dedent();
5022
+ cleanupInfoEntriesLoop();
4959
5023
  continue infoEntriesLoop;
4960
5024
  }
4961
5025
 
@@ -4965,6 +5029,8 @@ async function pnpmFix(pkgEnvDetails, {
4965
5029
  const editablePkgJson = await packages.readPackageJson(pkgJsonPath, {
4966
5030
  editable: true
4967
5031
  });
5032
+ const fixedVersions = new Set();
5033
+
4968
5034
  // Get current overrides for revert logic.
4969
5035
  const oldPnpmSection = editablePkgJson.content[PNPM$7];
4970
5036
  const oldOverrides = oldPnpmSection?.[OVERRIDES$2];
@@ -4987,25 +5053,27 @@ async function pnpmFix(pkgEnvDetails, {
4987
5053
  firstPatchedVersionIdentifier,
4988
5054
  vulnerableVersionRange
4989
5055
  } of infos) {
4990
- if (vendor.semverExports.gte(oldVersion, firstPatchedVersionIdentifier)) {
4991
- debug.debugFn(`skip: ${oldId} is >= ${firstPatchedVersionIdentifier}`);
5056
+ const newVersion = shadowNpmInject.findBestPatchVersion(node, availableVersions, vulnerableVersionRange);
5057
+ const newVersionPackument = newVersion ? packument.versions[newVersion] : undefined;
5058
+ if (!(newVersion && newVersionPackument)) {
5059
+ warningsForAfter.add(`${oldId} not updated: requires >=${firstPatchedVersionIdentifier}`);
5060
+ continue infosLoop;
5061
+ }
5062
+ if (fixedVersions.has(newVersion)) {
5063
+ continue infosLoop;
5064
+ }
5065
+ if (vendor.semverExports.gte(oldVersion, newVersion)) {
5066
+ debug.debugFn(`skip: ${oldId} is >= ${newVersion}`);
4992
5067
  continue infosLoop;
4993
5068
  }
4994
- const newVersion = shadowNpmInject.findBestPatchVersion(node, availableVersions, vulnerableVersionRange);
4995
5069
  if (activeBranches.find(b => b.workspace === branchWorkspace && b.newVersion === newVersion)) {
4996
5070
  debug.debugFn(`skip: open PR found for ${name}@${newVersion}`);
4997
5071
  if (++count >= limit) {
4998
- logger.logger.dedent();
4999
- spinner?.dedent();
5072
+ cleanupInfoEntriesLoop();
5000
5073
  break infoEntriesLoop;
5001
5074
  }
5002
5075
  continue infosLoop;
5003
5076
  }
5004
- const newVersionPackument = newVersion ? packument.versions[newVersion] : undefined;
5005
- if (!(newVersion && newVersionPackument)) {
5006
- warningsForAfter.add(`${oldId} not updated: requires >=${firstPatchedVersionIdentifier}`);
5007
- continue infosLoop;
5008
- }
5009
5077
  const overrideKey = `${name}@${vulnerableVersionRange}`;
5010
5078
  const newVersionRange = utils.applyRange(oldOverrides?.[overrideKey] ?? oldVersion, newVersion, rangeStyle);
5011
5079
  const newId = `${name}@${newVersionRange}`;
@@ -5057,9 +5125,9 @@ async function pnpmFix(pkgEnvDetails, {
5057
5125
  }))) {
5058
5126
  debug.debugFn(`skip: ${workspace}/package.json unchanged`);
5059
5127
  // Reset things just in case.
5060
- if (isCi) {
5128
+ if (ciEnv) {
5061
5129
  // eslint-disable-next-line no-await-in-loop
5062
- await gitResetAndClean(baseBranch, cwd);
5130
+ await gitResetAndClean(ciEnv.baseBranch, cwd);
5063
5131
  }
5064
5132
  continue infosLoop;
5065
5133
  }
@@ -5106,6 +5174,7 @@ async function pnpmFix(pkgEnvDetails, {
5106
5174
  });
5107
5175
  }
5108
5176
  spinner?.success(`Fixed ${name} in ${workspace}.`);
5177
+ fixedVersions.add(newVersion);
5109
5178
  } else {
5110
5179
  errored = true;
5111
5180
  }
@@ -5116,7 +5185,7 @@ async function pnpmFix(pkgEnvDetails, {
5116
5185
  spinner?.stop();
5117
5186
 
5118
5187
  // Check repoInfo to make TypeScript happy.
5119
- if (!errored && isCi && repoInfo) {
5188
+ if (!errored && ciEnv?.repoInfo) {
5120
5189
  try {
5121
5190
  // eslint-disable-next-line no-await-in-loop
5122
5191
  const result = await gitUnstagedModifiedFiles(cwd);
@@ -5136,7 +5205,7 @@ async function pnpmFix(pkgEnvDetails, {
5136
5205
  let skipPr = false;
5137
5206
  if (
5138
5207
  // eslint-disable-next-line no-await-in-loop
5139
- await prExistForBranch(repoInfo.owner, repoInfo.repo, branch)) {
5208
+ await prExistForBranch(ciEnv.repoInfo.owner, ciEnv.repoInfo.repo, branch)) {
5140
5209
  skipPr = true;
5141
5210
  debug.debugFn(`skip: branch "${branch}" exists`);
5142
5211
  }
@@ -5148,15 +5217,15 @@ async function pnpmFix(pkgEnvDetails, {
5148
5217
  // eslint-disable-next-line no-await-in-loop
5149
5218
  !(await gitCreateAndPushBranch(branch, getSocketCommitMessage(oldPurl, newVersion, workspace), moddedFilepaths, {
5150
5219
  cwd,
5151
- email: gitEmail,
5152
- user: gitUser
5220
+ email: ciEnv.gitEmail,
5221
+ user: ciEnv.gitUser
5153
5222
  }))) {
5154
5223
  skipPr = true;
5155
5224
  logger.logger.warn('Unexpected condition: Push failed, skipping PR creation.');
5156
5225
  }
5157
5226
  if (skipPr) {
5158
5227
  // eslint-disable-next-line no-await-in-loop
5159
- await gitResetAndClean(baseBranch, cwd);
5228
+ await gitResetAndClean(ciEnv.baseBranch, cwd);
5160
5229
  // eslint-disable-next-line no-await-in-loop
5161
5230
  const maybeActualTree = await install(pkgEnvDetails, {
5162
5231
  cwd,
@@ -5175,14 +5244,14 @@ async function pnpmFix(pkgEnvDetails, {
5175
5244
  }
5176
5245
 
5177
5246
  // eslint-disable-next-line no-await-in-loop
5178
- await Promise.allSettled([setGitRemoteGithubRepoUrl(repoInfo.owner, repoInfo.repo, githubToken, cwd), cleanupOpenPrs(repoInfo.owner, repoInfo.repo, {
5247
+ await Promise.allSettled([setGitRemoteGithubRepoUrl(ciEnv.repoInfo.owner, ciEnv.repoInfo.repo, ciEnv.githubToken, cwd), cleanupOpenPrs(ciEnv.repoInfo.owner, ciEnv.repoInfo.repo, {
5179
5248
  newVersion,
5180
5249
  purl: oldPurl,
5181
5250
  workspace
5182
5251
  })]);
5183
5252
  // eslint-disable-next-line no-await-in-loop
5184
- const prResponse = await openPr(repoInfo.owner, repoInfo.repo, branch, oldPurl, newVersion, {
5185
- baseBranch,
5253
+ const prResponse = await openPr(ciEnv.repoInfo.owner, ciEnv.repoInfo.repo, branch, oldPurl, newVersion, {
5254
+ baseBranch: ciEnv.baseBranch,
5186
5255
  cwd,
5187
5256
  workspace
5188
5257
  });
@@ -5215,10 +5284,10 @@ async function pnpmFix(pkgEnvDetails, {
5215
5284
  errored = true;
5216
5285
  }
5217
5286
  }
5218
- if (isCi) {
5287
+ if (ciEnv) {
5219
5288
  spinner?.start();
5220
5289
  // eslint-disable-next-line no-await-in-loop
5221
- await gitResetAndClean(baseBranch, cwd);
5290
+ await gitResetAndClean(ciEnv.baseBranch, cwd);
5222
5291
  // eslint-disable-next-line no-await-in-loop
5223
5292
  const maybeActualTree = await install(pkgEnvDetails, {
5224
5293
  cwd,
@@ -5236,7 +5305,7 @@ async function pnpmFix(pkgEnvDetails, {
5236
5305
  }
5237
5306
  }
5238
5307
  if (errored) {
5239
- if (!isCi) {
5308
+ if (!ciEnv) {
5240
5309
  spinner?.start();
5241
5310
  editablePkgJson.update(revertData);
5242
5311
  // eslint-disable-next-line no-await-in-loop
@@ -5269,8 +5338,7 @@ async function pnpmFix(pkgEnvDetails, {
5269
5338
  debug.debugFn('name:', name);
5270
5339
  debug.debugFn('increment: count', count + 1);
5271
5340
  if (++count >= limit) {
5272
- logger.logger.dedent();
5273
- spinner?.dedent();
5341
+ cleanupInfoEntriesLoop();
5274
5342
  break infoEntriesLoop;
5275
5343
  }
5276
5344
  }
@@ -5285,8 +5353,7 @@ async function pnpmFix(pkgEnvDetails, {
5285
5353
  if (!isLastInfoEntry) {
5286
5354
  logger.logger.logNewline();
5287
5355
  }
5288
- logger.logger.dedent();
5289
- spinner?.dedent();
5356
+ cleanupInfoEntriesLoop();
5290
5357
  }
5291
5358
  spinner?.stop();
5292
5359
 
@@ -14645,5 +14712,5 @@ void (async () => {
14645
14712
  await utils.captureException(e);
14646
14713
  }
14647
14714
  })();
14648
- //# debugId=858f0ee1-e2b9-482a-bf53-f0c50425ff4
14715
+ //# debugId=ff4cb15e-6c8d-4702-a71b-9fdebd5e1b1
14649
14716
  //# sourceMappingURL=cli.js.map