@socketsecurity/cli-with-sentry 0.15.61 → 0.15.63

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
  }));
@@ -3863,8 +3918,8 @@ function getActiveBranchesForPackage(ciEnv, partialPurl, openPrs) {
3863
3918
  if (!ciEnv) {
3864
3919
  return [];
3865
3920
  }
3866
- const partialPurlObj = utils.getPurlObject(partialPurl);
3867
3921
  const activeBranches = [];
3922
+ const partialPurlObj = utils.getPurlObject(partialPurl);
3868
3923
  const branchFullName = getSocketBranchFullNameComponent(partialPurlObj);
3869
3924
  const branchPurlType = getSocketBranchPurlTypeComponent(partialPurlObj);
3870
3925
  for (const pr of openPrs) {
@@ -3873,10 +3928,13 @@ function getActiveBranchesForPackage(ciEnv, partialPurl, openPrs) {
3873
3928
  activeBranches.push(parsedBranch);
3874
3929
  }
3875
3930
  }
3876
- if (activeBranches.length) {
3877
- debug.debugFn(`found: ${activeBranches.length} active branches\n`, activeBranches);
3878
- } else if (openPrs.length) {
3879
- debug.debugFn('miss: 0 active branches found');
3931
+ if (debug.isDebug()) {
3932
+ const fullName = packages.resolvePackageName(partialPurlObj);
3933
+ if (activeBranches.length) {
3934
+ debug.debugFn(`found: ${activeBranches.length} active branches for ${fullName}\n`, activeBranches);
3935
+ } else if (openPrs.length) {
3936
+ debug.debugFn(`miss: 0 active branches found for ${fullName}`);
3937
+ }
3880
3938
  }
3881
3939
  return activeBranches;
3882
3940
  }
@@ -4026,7 +4084,7 @@ async function cleanupOpenPrs(owner, repo, options) {
4026
4084
  return match;
4027
4085
  }));
4028
4086
  if (cachesToSave.size) {
4029
- await Promise.allSettled([...cachesToSave].map(({
4087
+ await Promise.allSettled(Array.from(cachesToSave).map(({
4030
4088
  0: key,
4031
4089
  1: data
4032
4090
  }) => writeCache(key, data)));
@@ -4075,24 +4133,6 @@ async function enablePrAutoMerge({
4075
4133
  enabled: false
4076
4134
  };
4077
4135
  }
4078
- function getGithubEnvRepoInfo() {
4079
- // Lazily access constants.ENV.GITHUB_REPOSITORY.
4080
- const {
4081
- GITHUB_REPOSITORY
4082
- } = constants.ENV;
4083
- if (!GITHUB_REPOSITORY) {
4084
- debug.debugFn('miss: GITHUB_REPOSITORY env var');
4085
- }
4086
- const ownerSlashRepo = GITHUB_REPOSITORY;
4087
- const slashIndex = ownerSlashRepo.indexOf('/');
4088
- if (slashIndex === -1) {
4089
- return null;
4090
- }
4091
- return {
4092
- owner: ownerSlashRepo.slice(0, slashIndex),
4093
- repo: ownerSlashRepo.slice(slashIndex + 1)
4094
- };
4095
- }
4096
4136
  async function getOpenSocketPrs(owner, repo, options) {
4097
4137
  return (await getOpenSocketPrsWithContext(owner, repo, options)).map(d => d.match);
4098
4138
  }
@@ -4218,11 +4258,6 @@ async function openPr(owner, repo, branch, purl, newVersion, options) {
4218
4258
  __proto__: null,
4219
4259
  ...options
4220
4260
  };
4221
- // Lazily access constants.ENV.GITHUB_ACTIONS.
4222
- if (!constants.ENV.GITHUB_ACTIONS) {
4223
- debug.debugFn('miss: GITHUB_ACTIONS env var');
4224
- return null;
4225
- }
4226
4261
  const purlObj = utils.getPurlObject(purl);
4227
4262
  const octokit = getOctokit();
4228
4263
  try {
@@ -4274,19 +4309,48 @@ async function setGitRemoteGithubRepoUrl(owner, repo, token, cwd = process.cwd()
4274
4309
  }
4275
4310
  }
4276
4311
 
4277
- function getCiEnv() {
4312
+ async function getEnvRepoInfo(cwd) {
4313
+ // Lazily access constants.ENV.GITHUB_REPOSITORY.
4314
+ const {
4315
+ GITHUB_REPOSITORY
4316
+ } = constants.ENV;
4317
+ if (!GITHUB_REPOSITORY) {
4318
+ debug.debugFn('miss: GITHUB_REPOSITORY env var');
4319
+ }
4320
+ const ownerSlashRepo = GITHUB_REPOSITORY;
4321
+ const slashIndex = ownerSlashRepo.indexOf('/');
4322
+ if (slashIndex !== -1) {
4323
+ return {
4324
+ owner: ownerSlashRepo.slice(0, slashIndex),
4325
+ repo: ownerSlashRepo.slice(slashIndex + 1)
4326
+ };
4327
+ }
4328
+ return await gitRepoInfo(cwd);
4329
+ }
4330
+ async function getCiEnv() {
4278
4331
  const gitEmail = constants.ENV.SOCKET_CLI_GIT_USER_EMAIL;
4279
4332
  const gitUser = constants.ENV.SOCKET_CLI_GIT_USER_NAME;
4280
4333
  const githubToken = constants.ENV.SOCKET_CLI_GITHUB_TOKEN;
4281
- const isCi = !!(constants.ENV.CI && constants.ENV.GITHUB_ACTIONS && constants.ENV.GITHUB_REPOSITORY && gitEmail && gitUser && githubToken);
4282
- return isCi ? {
4334
+ const isCi = !!(constants.ENV.CI && gitEmail && gitUser && githubToken);
4335
+ if (!isCi) {
4336
+ return null;
4337
+ }
4338
+ const baseBranch = await getBaseGitBranch();
4339
+ if (!baseBranch) {
4340
+ return null;
4341
+ }
4342
+ const repoInfo = await getEnvRepoInfo();
4343
+ if (!repoInfo) {
4344
+ return null;
4345
+ }
4346
+ return {
4283
4347
  gitEmail,
4284
4348
  gitUser,
4285
4349
  githubToken,
4286
- repoInfo: getGithubEnvRepoInfo(),
4287
- baseBranch: getBaseGitBranch(),
4350
+ repoInfo,
4351
+ baseBranch,
4288
4352
  branchParser: createSocketBranchParser()
4289
- } : null;
4353
+ };
4290
4354
  }
4291
4355
  async function getOpenPrsForEnvironment(env) {
4292
4356
  return env ? await getOpenSocketPrs(env.repoInfo.owner, env.repoInfo.repo, {
@@ -4346,7 +4410,7 @@ async function npmFix(pkgEnvDetails, {
4346
4410
  pkgPath: rootPath
4347
4411
  } = pkgEnvDetails;
4348
4412
  spinner?.start();
4349
- const ciEnv = getCiEnv();
4413
+ const ciEnv = await getCiEnv();
4350
4414
  const openPrs = ciEnv ? await getOpenPrsForEnvironment(ciEnv) : [];
4351
4415
  let count = 0;
4352
4416
  const arb = new shadowNpmInject.Arborist({
@@ -4394,7 +4458,7 @@ async function npmFix(pkgEnvDetails, {
4394
4458
  const pkgJsonPaths = [...workspacePkgJsonPaths,
4395
4459
  // Process the workspace root last since it will add an override to package.json.
4396
4460
  pkgEnvDetails.editablePkgJson.filename];
4397
- const sortedInfoEntries = [...infoByPartialPurl.entries()].sort((a, b) => sorts.naturalCompare(a[0], b[0]));
4461
+ const sortedInfoEntries = Array.from(infoByPartialPurl.entries()).sort((a, b) => sorts.naturalCompare(a[0], b[0]));
4398
4462
  const cleanupInfoEntriesLoop = () => {
4399
4463
  logger.logger.dedent();
4400
4464
  spinner?.dedent();
@@ -4416,11 +4480,10 @@ async function npmFix(pkgEnvDetails, {
4416
4480
  const infoEntry = sortedInfoEntries[i];
4417
4481
  const partialPurlObj = utils.getPurlObject(infoEntry[0]);
4418
4482
  const name = packages.resolvePackageName(partialPurlObj);
4419
- const infos = [...infoEntry[1].values()];
4483
+ const infos = Array.from(infoEntry[1].values());
4420
4484
  if (!infos.length) {
4421
4485
  continue infoEntriesLoop;
4422
4486
  }
4423
- const activeBranches = getActiveBranchesForPackage(ciEnv, infoEntry[0], openPrs);
4424
4487
  logger.logger.log(`Processing vulns for ${name}:`);
4425
4488
  logger.logger.indent();
4426
4489
  spinner?.indent();
@@ -4434,6 +4497,7 @@ async function npmFix(pkgEnvDetails, {
4434
4497
  cleanupInfoEntriesLoop();
4435
4498
  continue infoEntriesLoop;
4436
4499
  }
4500
+ const activeBranches = getActiveBranchesForPackage(ciEnv, infoEntry[0], openPrs);
4437
4501
  const availableVersions = Object.keys(packument.versions);
4438
4502
  const warningsForAfter = new Set();
4439
4503
 
@@ -4461,6 +4525,7 @@ async function npmFix(pkgEnvDetails, {
4461
4525
  const editablePkgJson = await packages.readPackageJson(pkgJsonPath, {
4462
4526
  editable: true
4463
4527
  });
4528
+ const fixedVersions = new Set();
4464
4529
  let hasAnnouncedWorkspace = false;
4465
4530
  let workspaceLogCallCount = logger.logger.logCallCount;
4466
4531
  if (debug.isDebug()) {
@@ -4486,6 +4551,9 @@ async function npmFix(pkgEnvDetails, {
4486
4551
  warningsForAfter.add(`${oldId} not updated: requires >=${firstPatchedVersionIdentifier}`);
4487
4552
  continue infosLoop;
4488
4553
  }
4554
+ if (fixedVersions.has(newVersion)) {
4555
+ continue infosLoop;
4556
+ }
4489
4557
  if (vendor.semverExports.gte(oldVersion, newVersion)) {
4490
4558
  debug.debugFn(`skip: ${oldId} is >= ${newVersion}`);
4491
4559
  continue infosLoop;
@@ -4557,6 +4625,7 @@ async function npmFix(pkgEnvDetails, {
4557
4625
  });
4558
4626
  }
4559
4627
  spinner?.success(`Fixed ${name} in ${workspace}.`);
4628
+ fixedVersions.add(newVersion);
4560
4629
  } else {
4561
4630
  errored = true;
4562
4631
  }
@@ -4783,7 +4852,7 @@ async function pnpmFix(pkgEnvDetails, {
4783
4852
  pkgPath: rootPath
4784
4853
  } = pkgEnvDetails;
4785
4854
  spinner?.start();
4786
- const ciEnv = getCiEnv();
4855
+ const ciEnv = await getCiEnv();
4787
4856
  const openPrs = ciEnv ? await getOpenPrsForEnvironment(ciEnv) : [];
4788
4857
  let count = 0;
4789
4858
  let actualTree;
@@ -4860,6 +4929,9 @@ async function pnpmFix(pkgEnvDetails, {
4860
4929
  }
4861
4930
  };
4862
4931
  }
4932
+ if (debug.isDebug()) {
4933
+ debug.debugFn('found: cves for', Array.from(infoByPartialPurl.keys()));
4934
+ }
4863
4935
 
4864
4936
  // Lazily access constants.packumentCache.
4865
4937
  const {
@@ -4869,7 +4941,7 @@ async function pnpmFix(pkgEnvDetails, {
4869
4941
  const pkgJsonPaths = [...workspacePkgJsonPaths,
4870
4942
  // Process the workspace root last since it will add an override to package.json.
4871
4943
  pkgEnvDetails.editablePkgJson.filename];
4872
- const sortedInfoEntries = [...infoByPartialPurl.entries()].sort((a, b) => sorts.naturalCompare(a[0], b[0]));
4944
+ const sortedInfoEntries = Array.from(infoByPartialPurl.entries()).sort((a, b) => sorts.naturalCompare(a[0], b[0]));
4873
4945
  const cleanupInfoEntriesLoop = () => {
4874
4946
  logger.logger.dedent();
4875
4947
  spinner?.dedent();
@@ -4891,11 +4963,10 @@ async function pnpmFix(pkgEnvDetails, {
4891
4963
  const infoEntry = sortedInfoEntries[i];
4892
4964
  const partialPurlObj = utils.getPurlObject(infoEntry[0]);
4893
4965
  const name = packages.resolvePackageName(partialPurlObj);
4894
- const infos = [...infoEntry[1].values()];
4966
+ const infos = Array.from(infoEntry[1].values());
4895
4967
  if (!infos.length) {
4896
4968
  continue infoEntriesLoop;
4897
4969
  }
4898
- const activeBranches = getActiveBranchesForPackage(ciEnv, infoEntry[0], openPrs);
4899
4970
  logger.logger.log(`Processing vulns for ${name}:`);
4900
4971
  logger.logger.indent();
4901
4972
  spinner?.indent();
@@ -4909,6 +4980,7 @@ async function pnpmFix(pkgEnvDetails, {
4909
4980
  cleanupInfoEntriesLoop();
4910
4981
  continue infoEntriesLoop;
4911
4982
  }
4983
+ const activeBranches = getActiveBranchesForPackage(ciEnv, infoEntry[0], openPrs);
4912
4984
  const availableVersions = Object.keys(packument.versions);
4913
4985
  const warningsForAfter = new Set();
4914
4986
 
@@ -4963,6 +5035,8 @@ async function pnpmFix(pkgEnvDetails, {
4963
5035
  const editablePkgJson = await packages.readPackageJson(pkgJsonPath, {
4964
5036
  editable: true
4965
5037
  });
5038
+ const fixedVersions = new Set();
5039
+
4966
5040
  // Get current overrides for revert logic.
4967
5041
  const oldPnpmSection = editablePkgJson.content[PNPM$7];
4968
5042
  const oldOverrides = oldPnpmSection?.[OVERRIDES$2];
@@ -4991,6 +5065,9 @@ async function pnpmFix(pkgEnvDetails, {
4991
5065
  warningsForAfter.add(`${oldId} not updated: requires >=${firstPatchedVersionIdentifier}`);
4992
5066
  continue infosLoop;
4993
5067
  }
5068
+ if (fixedVersions.has(newVersion)) {
5069
+ continue infosLoop;
5070
+ }
4994
5071
  if (vendor.semverExports.gte(oldVersion, newVersion)) {
4995
5072
  debug.debugFn(`skip: ${oldId} is >= ${newVersion}`);
4996
5073
  continue infosLoop;
@@ -5103,6 +5180,7 @@ async function pnpmFix(pkgEnvDetails, {
5103
5180
  });
5104
5181
  }
5105
5182
  spinner?.success(`Fixed ${name} in ${workspace}.`);
5183
+ fixedVersions.add(newVersion);
5106
5184
  } else {
5107
5185
  errored = true;
5108
5186
  }
@@ -7806,7 +7884,7 @@ function cleanupQueryStdout(stdout) {
7806
7884
  names.add(resolvedName);
7807
7885
  }
7808
7886
  }
7809
- return JSON.stringify([...names], null, 2);
7887
+ return JSON.stringify(Array.from(names), null, 2);
7810
7888
  }
7811
7889
  function parsableToQueryStdout(stdout) {
7812
7890
  if (stdout === '') {
@@ -7816,7 +7894,7 @@ function parsableToQueryStdout(stdout) {
7816
7894
  // The matchAll regexp looks for a forward (posix) or backward (win32) slash
7817
7895
  // and matches one or more non-slashes until the newline.
7818
7896
  const names = new Set(stdout.matchAll(/(?<=[/\\])[^/\\]+(?=\n)/g));
7819
- return JSON.stringify([...names], null, 2);
7897
+ return JSON.stringify(Array.from(names), null, 2);
7820
7898
  }
7821
7899
  async function npmQuery(npmExecPath, cwd) {
7822
7900
  let stdout = '';
@@ -14640,5 +14718,5 @@ void (async () => {
14640
14718
  await utils.captureException(e);
14641
14719
  }
14642
14720
  })();
14643
- //# debugId=f55e6ed3-61c1-4ff4-b932-f2758fcef19
14721
+ //# debugId=dab0d87c-3238-422d-976b-390f87d2120a
14644
14722
  //# sourceMappingURL=cli.js.map