socket 1.0.111 → 1.1.1

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.
Files changed (63) hide show
  1. package/dist/cli.js +242 -1590
  2. package/dist/cli.js.map +1 -1
  3. package/dist/constants.js +6 -5
  4. package/dist/constants.js.map +1 -1
  5. package/dist/shadow-npm-bin.js +12 -6
  6. package/dist/shadow-npm-bin.js.map +1 -1
  7. package/dist/shadow-npm-inject.js +24 -243
  8. package/dist/shadow-npm-inject.js.map +1 -1
  9. package/dist/socket-completion.bash +1 -1
  10. package/dist/tsconfig.dts.tsbuildinfo +1 -1
  11. package/dist/types/commands/fix/cmd-fix.d.mts.map +1 -1
  12. package/dist/types/commands/fix/coana-fix.d.mts +1 -1
  13. package/dist/types/commands/fix/coana-fix.d.mts.map +1 -1
  14. package/dist/types/commands/fix/{fix-env-helpers.d.mts → env-helpers.d.mts} +1 -1
  15. package/dist/types/commands/fix/env-helpers.d.mts.map +1 -0
  16. package/dist/types/commands/fix/git.d.mts +13 -0
  17. package/dist/types/commands/fix/git.d.mts.map +1 -0
  18. package/dist/types/commands/fix/handle-fix.d.mts +1 -1
  19. package/dist/types/commands/fix/handle-fix.d.mts.map +1 -1
  20. package/dist/types/commands/fix/pull-request.d.mts +10 -53
  21. package/dist/types/commands/fix/pull-request.d.mts.map +1 -1
  22. package/dist/types/commands/fix/types.d.mts +18 -0
  23. package/dist/types/commands/fix/types.d.mts.map +1 -0
  24. package/dist/types/commands/scan/fetch-supported-scan-file-names.d.mts +2 -0
  25. package/dist/types/commands/scan/fetch-supported-scan-file-names.d.mts.map +1 -1
  26. package/dist/types/constants.d.mts.map +1 -1
  27. package/dist/types/shadow/npm/arborist/lib/arborist/index.d.mts.map +1 -1
  28. package/dist/types/shadow/npm/arborist-helpers.d.mts +1 -1
  29. package/dist/types/shadow/npm/arborist-helpers.d.mts.map +1 -1
  30. package/dist/types/shadow/npm/bin.d.mts.map +1 -1
  31. package/dist/types/shadow/npm/paths.d.mts +0 -1
  32. package/dist/types/shadow/npm/paths.d.mts.map +1 -1
  33. package/dist/types/utils/alerts-map.d.mts.map +1 -1
  34. package/dist/types/utils/fs.d.mts +3 -2
  35. package/dist/types/utils/fs.d.mts.map +1 -1
  36. package/dist/types/utils/github.d.mts +38 -0
  37. package/dist/types/utils/github.d.mts.map +1 -0
  38. package/dist/types/utils/glob.d.mts +0 -1
  39. package/dist/types/utils/glob.d.mts.map +1 -1
  40. package/dist/utils.js +843 -888
  41. package/dist/utils.js.map +1 -1
  42. package/dist/vendor.js +112511 -119840
  43. package/external/@socketsecurity/registry/external/libnpmpack.js +96569 -41361
  44. package/external/@socketsecurity/registry/external/pacote.js +77357 -68133
  45. package/external/@socketsecurity/registry/lib/fs.js +13 -27
  46. package/external/@socketsecurity/registry/lib/json.js +42 -0
  47. package/external/@socketsecurity/registry/manifest.json +4 -4
  48. package/package.json +10 -10
  49. package/dist/types/commands/fix/agent-fix.d.mts +0 -42
  50. package/dist/types/commands/fix/agent-fix.d.mts.map +0 -1
  51. package/dist/types/commands/fix/fix-branch-helpers.d.mts +0 -4
  52. package/dist/types/commands/fix/fix-branch-helpers.d.mts.map +0 -1
  53. package/dist/types/commands/fix/fix-env-helpers.d.mts.map +0 -1
  54. package/dist/types/commands/fix/get-actual-tree.d.mts +0 -3
  55. package/dist/types/commands/fix/get-actual-tree.d.mts.map +0 -1
  56. package/dist/types/commands/fix/npm-fix.d.mts +0 -7
  57. package/dist/types/commands/fix/npm-fix.d.mts.map +0 -1
  58. package/dist/types/commands/fix/pnpm-fix.d.mts +0 -7
  59. package/dist/types/commands/fix/pnpm-fix.d.mts.map +0 -1
  60. package/dist/types/commands/fix/shared.d.mts +0 -10
  61. package/dist/types/commands/fix/shared.d.mts.map +0 -1
  62. package/dist/types/commands/fix/socket-git.d.mts +0 -32
  63. package/dist/types/commands/fix/socket-git.d.mts.map +0 -1
package/dist/cli.js CHANGED
@@ -18,16 +18,13 @@ var spawn = require('../external/@socketsecurity/registry/lib/spawn');
18
18
  var fs$2 = require('../external/@socketsecurity/registry/lib/fs');
19
19
  var strings = require('../external/@socketsecurity/registry/lib/strings');
20
20
  var arrays = require('../external/@socketsecurity/registry/lib/arrays');
21
- var regexps = require('../external/@socketsecurity/registry/lib/regexps');
22
- var registry = require('../external/@socketsecurity/registry');
23
- var npm = require('../external/@socketsecurity/registry/lib/npm');
24
- var packages = require('../external/@socketsecurity/registry/lib/packages');
25
- var sorts = require('../external/@socketsecurity/registry/lib/sorts');
26
- var shadowNpmInject = require('./shadow-npm-inject.js');
27
- var require$$10 = require('../external/@socketsecurity/registry/lib/objects');
28
21
  var path$1 = require('../external/@socketsecurity/registry/lib/path');
29
22
  var shadowNpmBin = require('./shadow-npm-bin.js');
30
- var require$$11 = require('../external/@socketsecurity/registry/lib/promises');
23
+ var require$$11 = require('../external/@socketsecurity/registry/lib/objects');
24
+ var registry = require('../external/@socketsecurity/registry');
25
+ var packages = require('../external/@socketsecurity/registry/lib/packages');
26
+ var require$$12 = require('../external/@socketsecurity/registry/lib/promises');
27
+ var regexps = require('../external/@socketsecurity/registry/lib/regexps');
31
28
  var require$$1 = require('node:util');
32
29
  var os = require('node:os');
33
30
  var promises = require('node:stream/promises');
@@ -318,7 +315,7 @@ async function handleAnalytics({
318
315
  });
319
316
  }
320
317
 
321
- const CMD_NAME$x = 'analytics';
318
+ const CMD_NAME$w = 'analytics';
322
319
  const description$D = 'Look up analytics data';
323
320
  const hidden$v = false;
324
321
  const cmdAnalytics = {
@@ -330,7 +327,7 @@ async function run$Q(argv, importMeta, {
330
327
  parentName
331
328
  }) {
332
329
  const config = {
333
- commandName: CMD_NAME$x,
330
+ commandName: CMD_NAME$w,
334
331
  description: description$D,
335
332
  hidden: hidden$v,
336
333
  flags: {
@@ -348,7 +345,7 @@ async function run$Q(argv, importMeta, {
348
345
  $ ${command} [options] [ "org" | "repo" <reponame>] [TIME]
349
346
 
350
347
  API Token Requirements
351
- ${utils.getFlagApiRequirementsOutput(`${parentName}:${CMD_NAME$x}`)}
348
+ ${utils.getFlagApiRequirementsOutput(`${parentName}:${CMD_NAME$w}`)}
352
349
 
353
350
  The scope is either org or repo level, defaults to org.
354
351
 
@@ -742,7 +739,7 @@ async function handleAuditLog({
742
739
  });
743
740
  }
744
741
 
745
- const CMD_NAME$w = 'audit-log';
742
+ const CMD_NAME$v = 'audit-log';
746
743
  const description$C = 'Look up the audit log for an organization';
747
744
  const hidden$u = false;
748
745
  const cmdAuditLog = {
@@ -754,7 +751,7 @@ async function run$P(argv, importMeta, {
754
751
  parentName
755
752
  }) {
756
753
  const config = {
757
- commandName: CMD_NAME$w,
754
+ commandName: CMD_NAME$v,
758
755
  description: description$C,
759
756
  hidden: hidden$u,
760
757
  flags: {
@@ -784,7 +781,7 @@ async function run$P(argv, importMeta, {
784
781
  $ ${command} [options] [FILTER]
785
782
 
786
783
  API Token Requirements
787
- ${utils.getFlagApiRequirementsOutput(`${parentName}:${CMD_NAME$w}`)}
784
+ ${utils.getFlagApiRequirementsOutput(`${parentName}:${CMD_NAME$v}`)}
788
785
 
789
786
  This feature requires an Enterprise Plan. To learn more about getting access
790
787
  to this feature and many more, please visit ${constants.SOCKET_WEBSITE_URL}/pricing
@@ -926,7 +923,8 @@ async function fetchCreateOrgFullScan(packagePaths, orgSlug, config, options) {
926
923
 
927
924
  async function fetchSupportedScanFileNames(options) {
928
925
  const {
929
- sdkOpts
926
+ sdkOpts,
927
+ spinner
930
928
  } = {
931
929
  __proto__: null,
932
930
  ...options
@@ -937,7 +935,8 @@ async function fetchSupportedScanFileNames(options) {
937
935
  }
938
936
  const sockSdk = sockSdkCResult.data;
939
937
  return await utils.handleApiCall(sockSdk.getSupportedScanFiles(), {
940
- desc: 'supported scan file types'
938
+ desc: 'supported scan file types',
939
+ spinner
941
940
  });
942
941
  }
943
942
 
@@ -2157,7 +2156,12 @@ async function handleCreateNewScan({
2157
2156
  });
2158
2157
  logger.logger.info('Auto-generation finished. Proceeding with Scan creation.');
2159
2158
  }
2160
- const supportedFilesCResult = await fetchSupportedScanFileNames();
2159
+ const {
2160
+ spinner
2161
+ } = constants;
2162
+ const supportedFilesCResult = await fetchSupportedScanFileNames({
2163
+ spinner
2164
+ });
2161
2165
  if (!supportedFilesCResult.ok) {
2162
2166
  await outputCreateNewScan(supportedFilesCResult, {
2163
2167
  interactive,
@@ -2165,9 +2169,6 @@ async function handleCreateNewScan({
2165
2169
  });
2166
2170
  return;
2167
2171
  }
2168
- const {
2169
- spinner
2170
- } = constants;
2171
2172
  spinner.start('Searching for local files to include in scan...');
2172
2173
  const supportedFiles = supportedFilesCResult.data;
2173
2174
  const packagePaths = await utils.getPackageFilesForScan(targets, supportedFiles, {
@@ -2599,7 +2600,7 @@ async function handleConfigAuto({
2599
2600
  await outputConfigAuto(key, result, outputKind);
2600
2601
  }
2601
2602
 
2602
- const CMD_NAME$v = 'auto';
2603
+ const CMD_NAME$u = 'auto';
2603
2604
  const description$B = 'Automatically discover and set the correct value config item';
2604
2605
  const hidden$t = false;
2605
2606
  const cmdConfigAuto = {
@@ -2611,7 +2612,7 @@ async function run$N(argv, importMeta, {
2611
2612
  parentName
2612
2613
  }) {
2613
2614
  const config = {
2614
- commandName: CMD_NAME$v,
2615
+ commandName: CMD_NAME$u,
2615
2616
  description: description$B,
2616
2617
  hidden: hidden$t,
2617
2618
  flags: {
@@ -2949,7 +2950,7 @@ async function handleConfigSet({
2949
2950
  await outputConfigSet(result, outputKind);
2950
2951
  }
2951
2952
 
2952
- const CMD_NAME$u = 'set';
2953
+ const CMD_NAME$t = 'set';
2953
2954
  const description$A = 'Update the value of a local CLI config item';
2954
2955
  const hidden$s = false;
2955
2956
  const cmdConfigSet = {
@@ -2961,7 +2962,7 @@ async function run$K(argv, importMeta, {
2961
2962
  parentName
2962
2963
  }) {
2963
2964
  const config = {
2964
- commandName: CMD_NAME$u,
2965
+ commandName: CMD_NAME$t,
2965
2966
  description: description$A,
2966
2967
  hidden: hidden$s,
2967
2968
  flags: {
@@ -3073,7 +3074,7 @@ async function handleConfigUnset({
3073
3074
  await outputConfigUnset(updateResult, outputKind);
3074
3075
  }
3075
3076
 
3076
- const CMD_NAME$t = 'unset';
3077
+ const CMD_NAME$s = 'unset';
3077
3078
  const description$z = 'Clear the value of a local CLI config item';
3078
3079
  const hidden$r = false;
3079
3080
  const cmdConfigUnset = {
@@ -3085,7 +3086,7 @@ async function run$J(argv, importMeta, {
3085
3086
  parentName
3086
3087
  }) {
3087
3088
  const config = {
3088
- commandName: CMD_NAME$t,
3089
+ commandName: CMD_NAME$s,
3089
3090
  description: description$z,
3090
3091
  hidden: hidden$r,
3091
3092
  flags: {
@@ -3168,330 +3169,76 @@ const cmdConfig = {
3168
3169
  }
3169
3170
  };
3170
3171
 
3171
- function formatBranchName(name) {
3172
- return name.replace(/[^-a-zA-Z0-9/._-]+/g, '+');
3172
+ const GITHUB_ADVISORIES_URL = 'https://github.com/advisories';
3173
+ function getSocketFixBranchName(ghsaId) {
3174
+ return `socket/fix/${ghsaId}`;
3173
3175
  }
3174
- function createSocketBranchParser(options) {
3175
- const pattern = getSocketBranchPattern(options);
3176
- return function parse(branch) {
3177
- const match = pattern.exec(branch);
3178
- if (!match) {
3179
- return null;
3180
- }
3181
- const {
3182
- 1: type,
3183
- 2: workspace,
3184
- 3: fullName,
3185
- 4: version,
3186
- 5: newVersion
3187
- } = match;
3188
- return {
3189
- fullName,
3190
- newVersion: vendor.semverExports.coerce(newVersion.replaceAll('+', '.'))?.version,
3191
- type,
3192
- workspace,
3193
- version: vendor.semverExports.coerce(version.replaceAll('+', '.'))?.version
3194
- };
3195
- };
3176
+ function getSocketFixBranchPattern(ghsaId) {
3177
+ return new RegExp(`^socket/fix/(${ghsaId ?? '.+'})$`);
3196
3178
  }
3197
- const genericSocketBranchParser = createSocketBranchParser();
3198
- function getSocketBranchFullNameComponent(pkgName) {
3199
- const purlObj = utils.getPurlObject(typeof pkgName === 'string' && !pkgName.startsWith('pkg:') ? vendor.packageurlJsExports.PackageURL.fromString(`pkg:unknown/${pkgName}`) : pkgName);
3200
- const branchMaybeNamespace = purlObj.namespace ? `${formatBranchName(purlObj.namespace)}--` : '';
3201
- return `${branchMaybeNamespace}${formatBranchName(purlObj.name)}`;
3202
- }
3203
- function getSocketBranchName(purl, newVersion, workspace) {
3204
- const purlObj = utils.getPurlObject(purl);
3205
- const branchType = getSocketBranchPurlTypeComponent(purlObj);
3206
- const branchWorkspace = getSocketBranchWorkspaceComponent(workspace);
3207
- const branchFullName = getSocketBranchFullNameComponent(purlObj);
3208
- const branchVersion = getSocketBranchPackageVersionComponent(purlObj.version);
3209
- const branchNewVersion = formatBranchName(newVersion);
3210
- return `socket/${branchType}/${branchWorkspace}/${branchFullName}_${branchVersion}_${branchNewVersion}`;
3211
- }
3212
- function getSocketBranchPackageVersionComponent(version) {
3213
- const purlObj = utils.getPurlObject(typeof version === 'string' && !version.startsWith('pkg:') ? vendor.packageurlJsExports.PackageURL.fromString(`pkg:unknown/unknown@${version}`) : version);
3214
- return formatBranchName(purlObj.version);
3215
- }
3216
- function getSocketBranchPattern(options) {
3217
- const {
3218
- newVersion,
3219
- purl,
3220
- workspace
3221
- } = {
3222
- __proto__: null,
3223
- ...options
3224
- };
3225
- const purlObj = purl ? utils.getPurlObject(purl) : null;
3226
- const escType = purlObj ? regexps.escapeRegExp(purlObj.type) : '[^/]+';
3227
- const escWorkspace = workspace ? `${regexps.escapeRegExp(formatBranchName(workspace))}` : '.+';
3228
- const escMaybeNamespace = purlObj?.namespace ? `${regexps.escapeRegExp(formatBranchName(purlObj.namespace))}--` : '';
3229
- const escFullName = purlObj ? `${escMaybeNamespace}${regexps.escapeRegExp(formatBranchName(purlObj.name))}` : '[^/_]+';
3230
- const escVersion = purlObj ? regexps.escapeRegExp(formatBranchName(purlObj.version)) : '[^_]+';
3231
- const escNewVersion = newVersion ? regexps.escapeRegExp(formatBranchName(newVersion)) : '[^_]+';
3232
- return new RegExp(`^socket/(${escType})/(${escWorkspace})/(${escFullName})_(${escVersion})_(${escNewVersion})$`);
3233
- }
3234
- function getSocketBranchPurlTypeComponent(purl) {
3235
- const purlObj = utils.getPurlObject(purl);
3236
- return formatBranchName(purlObj.type);
3237
- }
3238
- function getSocketBranchWorkspaceComponent(workspace) {
3239
- return workspace ? formatBranchName(workspace) : 'root';
3240
- }
3241
- function getSocketCommitMessage(purl, newVersion, workspace) {
3242
- const purlObj = utils.getPurlObject(purl);
3243
- const fullName = utils.getPkgFullNameFromPurl(purlObj);
3244
- return `socket: Bump ${fullName} from ${purlObj.version} to ${newVersion}${workspace ? ` in ${workspace}` : ''}`;
3245
- }
3246
- function getSocketPullRequestBody(purl, newVersion, workspace) {
3247
- const purlObj = utils.getPurlObject(purl);
3248
- const fullName = utils.getPkgFullNameFromPurl(purlObj);
3249
- const pkgOverviewUrl = utils.getSocketDevPackageOverviewUrlFromPurl(purlObj);
3250
- return `Bump [${fullName}](${pkgOverviewUrl}) from ${purlObj.version} to ${newVersion}${workspace ? ` in ${workspace}` : ''}.`;
3251
- }
3252
- function getSocketPullRequestTitle(purl, newVersion, workspace) {
3253
- const purlObj = utils.getPurlObject(purl);
3254
- const fullName = utils.getPkgFullNameFromPurl(purlObj);
3255
- return `Bump ${fullName} from ${purlObj.version} to ${newVersion}${workspace ? ` in ${workspace}` : ''}`;
3256
- }
3257
-
3258
- let _octokit;
3259
- function getOctokit() {
3260
- if (_octokit === undefined) {
3261
- const {
3262
- SOCKET_CLI_GITHUB_TOKEN
3263
- } = constants.ENV;
3264
- if (!SOCKET_CLI_GITHUB_TOKEN) {
3265
- require$$9.debugFn('notice', 'miss: SOCKET_CLI_GITHUB_TOKEN env var');
3266
- }
3267
- const octokitOptions = {
3268
- auth: SOCKET_CLI_GITHUB_TOKEN,
3269
- baseUrl: constants.ENV.GITHUB_API_URL
3270
- };
3271
- require$$9.debugDir('inspect', {
3272
- octokitOptions
3273
- });
3274
- _octokit = new vendor.Octokit(octokitOptions);
3275
- }
3276
- return _octokit;
3179
+ function getSocketFixCommitMessage(ghsaId, details) {
3180
+ const summary = details?.summary;
3181
+ return `fix: ${ghsaId}${summary ? ` - ${summary}` : ''}`;
3277
3182
  }
3278
- let _octokitGraphql;
3279
- function getOctokitGraphql() {
3280
- if (!_octokitGraphql) {
3281
- const {
3282
- SOCKET_CLI_GITHUB_TOKEN
3283
- } = constants.ENV;
3284
- if (!SOCKET_CLI_GITHUB_TOKEN) {
3285
- require$$9.debugFn('notice', 'miss: SOCKET_CLI_GITHUB_TOKEN env var');
3286
- }
3287
- _octokitGraphql = vendor.graphql2.defaults({
3288
- headers: {
3289
- authorization: `token ${SOCKET_CLI_GITHUB_TOKEN}`
3290
- }
3291
- });
3292
- }
3293
- return _octokitGraphql;
3294
- }
3295
- async function readCache(key,
3296
- // 5 minute in milliseconds time to live (TTL).
3297
- ttlMs = 5 * 60 * 1000) {
3298
- const cacheJsonPath = path.join(constants.githubCachePath, `${key}.json`);
3299
- const stat = fs$2.safeStatsSync(cacheJsonPath);
3300
- if (stat) {
3301
- const isExpired = Date.now() - stat.mtimeMs > ttlMs;
3302
- if (!isExpired) {
3303
- return await fs$2.readJson(cacheJsonPath);
3183
+ function getSocketFixPullRequestBody(ghsaIds, ghsaDetails) {
3184
+ const vulnCount = ghsaIds.length;
3185
+ if (vulnCount === 1) {
3186
+ const ghsaId = ghsaIds[0];
3187
+ const details = ghsaDetails?.get(ghsaId);
3188
+ const body = `[Socket](${constants.SOCKET_WEBSITE_URL}) fix for [${ghsaId}](${GITHUB_ADVISORIES_URL}/${ghsaId}).`;
3189
+ if (!details) {
3190
+ return body;
3304
3191
  }
3192
+ const packages = details.vulnerabilities.nodes.map(v => `${v.package.name} (${v.package.ecosystem})`);
3193
+ return [body, '', '', `**Vulnerability Summary:** ${details.summary}`, '', `**Severity:** ${details.severity}`, '', `**Affected Packages:** ${arrays.joinAnd(packages)}`].join('\n');
3305
3194
  }
3306
- return null;
3307
- }
3308
- async function writeCache(key, data) {
3309
- const {
3310
- githubCachePath
3311
- } = constants;
3312
- const cacheJsonPath = path.join(githubCachePath, `${key}.json`);
3313
- if (!fs$1.existsSync(githubCachePath)) {
3314
- await fs$1.promises.mkdir(githubCachePath, {
3315
- recursive: true
3316
- });
3317
- }
3318
- await fs$2.writeJson(cacheJsonPath, data);
3319
- }
3320
- async function cacheFetch(key, fetcher, ttlMs) {
3321
- // Optionally disable cache.
3322
- if (constants.ENV.DISABLE_GITHUB_CACHE) {
3323
- return await fetcher();
3324
- }
3325
- let data = await readCache(key, ttlMs);
3326
- if (!data) {
3327
- data = await fetcher();
3328
- await writeCache(key, data);
3329
- }
3330
- return data;
3331
- }
3332
- async function fetchGhsaDetails(ids) {
3333
- const results = new Map();
3334
- if (!ids.length) {
3335
- return results;
3336
- }
3337
- const octokitGraphql = getOctokitGraphql();
3338
- try {
3339
- const gqlCacheKey = `${ids.join('-')}-graphql-snapshot`;
3340
- const aliases = ids.map((id, index) => `advisory${index}: securityAdvisory(ghsaId: "${id}") {
3341
- ghsaId
3342
- summary
3343
- severity
3344
- publishedAt
3345
- withdrawnAt
3346
- vulnerabilities(first: 10) {
3347
- nodes {
3348
- package {
3349
- ecosystem
3350
- name
3351
- }
3352
- vulnerableVersionRange
3353
- }
3354
- }
3355
- }`).join('\n');
3356
- const gqlResp = await cacheFetch(gqlCacheKey, () => octokitGraphql(`
3357
- query {
3358
- ${aliases}
3359
- }
3360
- `));
3361
- for (let i = 0, {
3362
- length
3363
- } = ids; i < length; i += 1) {
3364
- const id = ids[i];
3365
- const advisoryKey = `advisory${i}`;
3366
- const advisory = gqlResp?.[advisoryKey];
3367
- if (advisory && advisory.ghsaId) {
3368
- results.set(id, advisory);
3369
- } else {
3370
- require$$9.debugFn('notice', `miss: no advisory found for ${id}`);
3371
- }
3195
+ return [`[Socket](${constants.SOCKET_WEBSITE_URL}) fixes for ${vulnCount} GHSAs.`, '', '**Fixed Vulnerabilities:**', ...ghsaIds.map(id => {
3196
+ const details = ghsaDetails?.get(id);
3197
+ const item = `- [${id}](${GITHUB_ADVISORIES_URL}/${id})`;
3198
+ if (details) {
3199
+ const packages = details.vulnerabilities.nodes.map(v => `${v.package.name}`);
3200
+ return `${item} - ${details.summary} (${arrays.joinAnd(packages)})`;
3372
3201
  }
3373
- } catch (e) {
3374
- require$$9.debugFn('error', `Failed to fetch GHSA details: ${e?.message || 'Unknown error'}`);
3375
- }
3376
- return results;
3202
+ return item;
3203
+ })].join('\n');
3377
3204
  }
3378
- async function cleanupPrs(owner, repo, options) {
3379
- const contextualMatches = await getSocketPrsWithContext(owner, repo, options);
3380
- if (!contextualMatches.length) {
3381
- return [];
3382
- }
3383
- const cachesToSave = new Map();
3205
+ function getSocketFixPullRequestTitle(ghsaIds) {
3206
+ const vulnCount = ghsaIds.length;
3207
+ return vulnCount === 1 ? `Fix for ${ghsaIds[0]}` : `Fixes for ${vulnCount} GHSAs`;
3208
+ }
3209
+
3210
+ async function openSocketFixPr(owner, repo, branch, ghsaIds, options) {
3384
3211
  const {
3385
- newVersion
3212
+ baseBranch = 'main',
3213
+ ghsaDetails
3386
3214
  } = {
3387
3215
  __proto__: null,
3388
3216
  ...options
3389
3217
  };
3390
- const branchParser = createSocketBranchParser(options);
3391
- const octokit = getOctokit();
3392
- const settledMatches = await Promise.allSettled(contextualMatches.map(async ({
3393
- context,
3394
- match
3395
- }) => {
3396
- const {
3397
- number: prNum
3398
- } = match;
3399
- const prRef = `PR #${prNum}`;
3400
- const parsedBranch = branchParser(match.headRefName);
3401
- const prToVersion = parsedBranch?.newVersion;
3402
-
3403
- // Close older PRs.
3404
- if (prToVersion && newVersion && vendor.semverExports.lt(prToVersion, newVersion)) {
3405
- try {
3406
- await octokit.pulls.update({
3407
- owner,
3408
- repo,
3409
- pull_number: prNum,
3410
- state: 'closed'
3411
- });
3412
- require$$9.debugFn('notice', `pr: closing ${prRef} for ${prToVersion}`);
3413
- // Remove entry from parent object.
3414
- context.parent.splice(context.index, 1);
3415
- // Mark cache to be saved.
3416
- cachesToSave.set(context.cacheKey, context.data);
3417
- return null;
3418
- } catch (e) {
3419
- require$$9.debugFn('error', `pr: failed to close ${prRef} for ${prToVersion}\n`, e?.message || 'Unknown error');
3420
- }
3421
- }
3422
- // Update stale PRs.
3423
- // https://docs.github.com/en/graphql/reference/enums#mergestatestatus
3424
- if (match.mergeStateStatus === 'BEHIND') {
3425
- try {
3426
- await octokit.repos.merge({
3427
- owner,
3428
- repo,
3429
- base: match.headRefName,
3430
- head: match.baseRefName
3431
- });
3432
- require$$9.debugFn('notice', `pr: updating stale ${prRef}`);
3433
- // Update entry entry.
3434
- if (context.apiType === 'graphql') {
3435
- context.entry.mergeStateStatus = 'CLEAN';
3436
- } else if (context.apiType === 'rest') {
3437
- context.entry.mergeable_state = 'clean';
3438
- }
3439
- // Mark cache to be saved.
3440
- cachesToSave.set(context.cacheKey, context.data);
3441
- } catch (e) {
3442
- const message = e?.message || 'Unknown error';
3443
- require$$9.debugFn('error', `pr: failed to update ${prRef} - ${message}`);
3444
- }
3445
- }
3446
- return match;
3447
- }));
3448
- if (cachesToSave.size) {
3449
- await Promise.allSettled(Array.from(cachesToSave).map(({
3450
- 0: key,
3451
- 1: data
3452
- }) => writeCache(key, data)));
3453
- }
3454
- const fulfilledMatches = settledMatches.filter(r => r.status === 'fulfilled' && r.value);
3455
- return fulfilledMatches.map(r => r.value.match);
3456
- }
3457
- async function enablePrAutoMerge({
3458
- node_id: prId
3459
- }) {
3460
- const octokitGraphql = getOctokitGraphql();
3218
+ const octokit = utils.getOctokit();
3461
3219
  try {
3462
- const gqlResp = await octokitGraphql(`
3463
- mutation EnableAutoMerge($pullRequestId: ID!) {
3464
- enablePullRequestAutoMerge(input: {
3465
- pullRequestId: $pullRequestId,
3466
- mergeMethod: SQUASH
3467
- }) {
3468
- pullRequest {
3469
- number
3470
- }
3471
- }
3472
- }`, {
3473
- pullRequestId: prId
3220
+ const octokitPullsCreateParams = {
3221
+ owner,
3222
+ repo,
3223
+ title: getSocketFixPullRequestTitle(ghsaIds),
3224
+ head: branch,
3225
+ base: baseBranch,
3226
+ body: getSocketFixPullRequestBody(ghsaIds, ghsaDetails)
3227
+ };
3228
+ require$$9.debugDir('inspect', {
3229
+ octokitPullsCreateParams
3474
3230
  });
3475
- const respPrNumber = gqlResp?.enablePullRequestAutoMerge?.pullRequest?.number;
3476
- if (respPrNumber) {
3477
- return {
3478
- enabled: true
3479
- };
3480
- }
3231
+ return await octokit.pulls.create(octokitPullsCreateParams);
3481
3232
  } catch (e) {
3482
- if (e instanceof vendor.GraphqlResponseError && Array.isArray(e.errors) && e.errors.length) {
3483
- const details = e.errors.map(({
3484
- message: m
3485
- }) => m.trim());
3486
- return {
3487
- enabled: false,
3488
- details
3489
- };
3233
+ let message = `Failed to open pull request`;
3234
+ const errors = e instanceof vendor.RequestError ? e.response?.data?.['errors'] : undefined;
3235
+ if (Array.isArray(errors) && errors.length) {
3236
+ const details = errors.map(d => `- ${d.message?.trim() ?? `${d.resource}.${d.field} (${d.code})`}`).join('\n');
3237
+ message += `:\n${details}`;
3490
3238
  }
3239
+ require$$9.debugFn('error', message);
3491
3240
  }
3492
- return {
3493
- enabled: false
3494
- };
3241
+ return null;
3495
3242
  }
3496
3243
  async function getSocketPrs(owner, repo, options) {
3497
3244
  return (await getSocketPrsWithContext(owner, repo, options)).map(d => d.match);
@@ -3499,22 +3246,23 @@ async function getSocketPrs(owner, repo, options) {
3499
3246
  async function getSocketPrsWithContext(owner, repo, options) {
3500
3247
  const {
3501
3248
  author,
3249
+ ghsaId,
3502
3250
  states: statesValue = 'all'
3503
3251
  } = {
3504
3252
  __proto__: null,
3505
3253
  ...options
3506
3254
  };
3507
- const branchPattern = getSocketBranchPattern(options);
3255
+ const branchPattern = getSocketFixBranchPattern(ghsaId);
3508
3256
  const checkAuthor = strings.isNonEmptyString(author);
3509
- const octokit = getOctokit();
3510
- const octokitGraphql = getOctokitGraphql();
3257
+ const octokit = utils.getOctokit();
3258
+ const octokitGraphql = utils.getOctokitGraphql();
3511
3259
  const contextualMatches = [];
3512
3260
  const states = (typeof statesValue === 'string' ? statesValue.toLowerCase() === 'all' ? ['OPEN', 'CLOSED', 'MERGED'] : [statesValue] : statesValue).map(s => s.toUpperCase());
3513
3261
  try {
3514
3262
  // Optimistically fetch only the first 50 open PRs using GraphQL to minimize
3515
3263
  // API quota usage. Fallback to REST if no matching PRs are found.
3516
3264
  const gqlCacheKey = `${repo}-pr-graphql-snapshot`;
3517
- const gqlResp = await cacheFetch(gqlCacheKey, () => octokitGraphql(`
3265
+ const gqlResp = await utils.cacheFetch(gqlCacheKey, () => octokitGraphql(`
3518
3266
  query($owner: String!, $repo: String!, $states: [PullRequestState!]) {
3519
3267
  repository(owner: $owner, name: $repo) {
3520
3268
  pullRequests(first: 50, states: $states, orderBy: {field: CREATED_AT, direction: DESC}) {
@@ -3571,7 +3319,7 @@ async function getSocketPrsWithContext(owner, repo, options) {
3571
3319
  let allPrs;
3572
3320
  const cacheKey = `${repo}-pull-requests`;
3573
3321
  try {
3574
- allPrs = await cacheFetch(cacheKey, async () => await octokit.paginate(octokit.pulls.list, {
3322
+ allPrs = await utils.cacheFetch(cacheKey, async () => await octokit.paginate(octokit.pulls.list, {
3575
3323
  owner,
3576
3324
  repo,
3577
3325
  state: 'all',
@@ -3620,117 +3368,6 @@ async function getSocketPrsWithContext(owner, repo, options) {
3620
3368
  }
3621
3369
  return contextualMatches;
3622
3370
  }
3623
- async function openPr(owner, repo, branch, purl, newVersion, options) {
3624
- const {
3625
- baseBranch = 'main',
3626
- workspace
3627
- } = {
3628
- __proto__: null,
3629
- ...options
3630
- };
3631
- const purlObj = utils.getPurlObject(purl);
3632
- const octokit = getOctokit();
3633
- try {
3634
- const octokitPullsCreateParams = {
3635
- owner,
3636
- repo,
3637
- title: getSocketPullRequestTitle(purlObj, newVersion, workspace),
3638
- head: branch,
3639
- base: baseBranch,
3640
- body: getSocketPullRequestBody(purlObj, newVersion, workspace)
3641
- };
3642
- require$$9.debugDir('inspect', {
3643
- octokitPullsCreateParams
3644
- });
3645
- return await octokit.pulls.create(octokitPullsCreateParams);
3646
- } catch (e) {
3647
- let message = `Failed to open pull request`;
3648
- const errors = e instanceof vendor.RequestError ? e.response?.data?.['errors'] : undefined;
3649
- if (Array.isArray(errors) && errors.length) {
3650
- const details = errors.map(d => `- ${d.message?.trim() ?? `${d.resource}.${d.field} (${d.code})`}`).join('\n');
3651
- message += `:\n${details}`;
3652
- }
3653
- require$$9.debugFn('error', message);
3654
- }
3655
- return null;
3656
- }
3657
- async function openCoanaPr(owner, repo, branch, ghsaIds, options) {
3658
- const {
3659
- baseBranch = 'main',
3660
- ghsaDetails
3661
- } = {
3662
- __proto__: null,
3663
- ...options
3664
- };
3665
- const octokit = getOctokit();
3666
- const vulnCount = ghsaIds.length;
3667
- const prTitle = vulnCount === 1 ? `Fix for ${ghsaIds[0]}` : `Fixes for ${vulnCount} GHSAs`;
3668
- let prBody = '';
3669
- if (vulnCount === 1) {
3670
- const ghsaId = ghsaIds[0];
3671
- const details = ghsaDetails?.get(ghsaId);
3672
- prBody = `[Socket](https://socket.dev/) fix for [${ghsaId}](https://github.com/advisories/${ghsaId}).`;
3673
- if (details) {
3674
- const packages = details.vulnerabilities.nodes.map(v => `${v.package.name} (${v.package.ecosystem})`);
3675
- prBody += ['', '', `**Vulnerability Summary:** ${details.summary}`, '', `**Severity:** ${details.severity}`, '', `**Affected Packages:** ${arrays.joinAnd(packages)}`].join('\n');
3676
- }
3677
- } else {
3678
- prBody = [`[Socket](https://socket.dev/) fixes for ${vulnCount} GHSAs.`, '', '**Fixed Vulnerabilities:**', ...ghsaIds.map(id => {
3679
- const details = ghsaDetails?.get(id);
3680
- const item = `- [${id}](https://github.com/advisories/${id})`;
3681
- if (details) {
3682
- const packages = details.vulnerabilities.nodes.map(v => `${v.package.name}`);
3683
- return `${item} - ${details.summary} (${arrays.joinAnd(packages)})`;
3684
- }
3685
- return item;
3686
- })].join('\n');
3687
- }
3688
- try {
3689
- const octokitPullsCreateParams = {
3690
- owner,
3691
- repo,
3692
- title: prTitle,
3693
- head: branch,
3694
- base: baseBranch,
3695
- body: prBody
3696
- };
3697
- require$$9.debugDir('inspect', {
3698
- octokitPullsCreateParams
3699
- });
3700
- return await octokit.pulls.create(octokitPullsCreateParams);
3701
- } catch (e) {
3702
- let message = `Failed to open pull request`;
3703
- const errors = e instanceof vendor.RequestError ? e.response?.data?.['errors'] : undefined;
3704
- if (Array.isArray(errors) && errors.length) {
3705
- const details = errors.map(d => `- ${d.message?.trim() ?? `${d.resource}.${d.field} (${d.code})`}`).join('\n');
3706
- message += `:\n${details}`;
3707
- }
3708
- require$$9.debugFn('error', message);
3709
- }
3710
- return null;
3711
- }
3712
- async function setGitRemoteGithubRepoUrl(owner, repo, token, cwd = process.cwd()) {
3713
- const {
3714
- host
3715
- } = new URL(constants.ENV.GITHUB_SERVER_URL);
3716
- const url = `https://x-access-token:${token}@${host}/${owner}/${repo}`;
3717
- const stdioIgnoreOptions = {
3718
- cwd,
3719
- stdio: require$$9.isDebug('stdio') ? 'inherit' : 'ignore'
3720
- };
3721
- const quotedCmd = `\`git remote set-url origin ${url}\``;
3722
- require$$9.debugFn('stdio', `spawn: ${quotedCmd}`);
3723
- try {
3724
- await spawn.spawn('git', ['remote', 'set-url', 'origin', url], stdioIgnoreOptions);
3725
- return true;
3726
- } catch (e) {
3727
- require$$9.debugFn('error', `caught: ${quotedCmd} failed`);
3728
- require$$9.debugDir('inspect', {
3729
- error: e
3730
- });
3731
- }
3732
- return false;
3733
- }
3734
3371
 
3735
3372
  function ciRepoInfo() {
3736
3373
  const {
@@ -3809,7 +3446,9 @@ async function coanaFix(fixConfig) {
3809
3446
  return sockSdkCResult;
3810
3447
  }
3811
3448
  const sockSdk = sockSdkCResult.data;
3812
- const supportedFilesCResult = await fetchSupportedScanFileNames();
3449
+ const supportedFilesCResult = await fetchSupportedScanFileNames({
3450
+ spinner
3451
+ });
3813
3452
  if (!supportedFilesCResult.ok) {
3814
3453
  return supportedFilesCResult;
3815
3454
  }
@@ -3833,7 +3472,7 @@ async function coanaFix(fixConfig) {
3833
3472
  data: uploadCResult.data
3834
3473
  };
3835
3474
  }
3836
- const isAll = ghsas.length === 1 && (ghsas[0] === 'all' || ghsas[0] === 'auto');
3475
+ const isAll = !ghsas.length || ghsas.length === 1 && (ghsas[0] === 'all' || ghsas[0] === 'auto');
3837
3476
  const shouldOpenPrs = fixEnv.isCi && fixEnv.repoInfo;
3838
3477
  if (!shouldOpenPrs) {
3839
3478
  const ids = isAll ? ['all'] : ghsas.slice(0, limit);
@@ -3888,7 +3527,7 @@ async function coanaFix(fixConfig) {
3888
3527
  };
3889
3528
  }
3890
3529
  require$$9.debugFn('notice', `fetch: ${ids.length} GHSA details for ${arrays.joinAnd(ids)}`);
3891
- const ghsaDetails = await fetchGhsaDetails(ids);
3530
+ const ghsaDetails = await utils.fetchGhsaDetails(ids);
3892
3531
  const scanBaseNames = new Set(scanFilepaths.map(p => path.basename(p)));
3893
3532
  require$$9.debugFn('notice', `found: ${ghsaDetails.size} GHSA details`);
3894
3533
  let count = 0;
@@ -3898,18 +3537,18 @@ async function coanaFix(fixConfig) {
3898
3537
  ghsaLoop: for (let i = 0, {
3899
3538
  length
3900
3539
  } = ids; i < length; i += 1) {
3901
- const id = ids[i];
3902
- require$$9.debugFn('notice', `check: ${id}`);
3540
+ const ghsaId = ids[i];
3541
+ require$$9.debugFn('notice', `check: ${ghsaId}`);
3903
3542
 
3904
3543
  // Apply fix for single GHSA ID.
3905
3544
  // eslint-disable-next-line no-await-in-loop
3906
- const fixCResult = await utils.spawnCoana(['compute-fixes-and-upgrade-purls', cwd, '--manifests-tar-hash', tarHash, '--apply-fixes-to', id, ...(fixConfig.rangeStyle ? ['--range-style', fixConfig.rangeStyle] : []), ...fixConfig.unknownFlags], fixConfig.orgSlug, {
3545
+ const fixCResult = await utils.spawnCoana(['compute-fixes-and-upgrade-purls', cwd, '--manifests-tar-hash', tarHash, '--apply-fixes-to', ghsaId, ...(fixConfig.rangeStyle ? ['--range-style', fixConfig.rangeStyle] : []), ...fixConfig.unknownFlags], fixConfig.orgSlug, {
3907
3546
  cwd,
3908
3547
  spinner,
3909
3548
  stdio: 'inherit'
3910
3549
  });
3911
3550
  if (!fixCResult.ok) {
3912
- logger.logger.error(`Update failed for ${id}: ${fixCResult.message || 'Unknown error'}`);
3551
+ logger.logger.error(`Update failed for ${ghsaId}: ${fixCResult.message || 'Unknown error'}`);
3913
3552
  continue ghsaLoop;
3914
3553
  }
3915
3554
 
@@ -3918,11 +3557,11 @@ async function coanaFix(fixConfig) {
3918
3557
  const unstagedCResult = await utils.gitUnstagedModifiedFiles(cwd);
3919
3558
  const modifiedFiles = unstagedCResult.ok ? unstagedCResult.data.filter(relPath => scanBaseNames.has(path.basename(relPath))) : [];
3920
3559
  if (!modifiedFiles.length) {
3921
- require$$9.debugFn('notice', `skip: no changes for ${id}`);
3560
+ require$$9.debugFn('notice', `skip: no changes for ${ghsaId}`);
3922
3561
  continue ghsaLoop;
3923
3562
  }
3924
3563
  overallFixed = true;
3925
- const branch = `socket/fix/${id}`;
3564
+ const branch = getSocketFixBranchName(ghsaId);
3926
3565
  try {
3927
3566
  // Check if branch already exists.
3928
3567
  // eslint-disable-next-line no-await-in-loop
@@ -3930,17 +3569,16 @@ async function coanaFix(fixConfig) {
3930
3569
  require$$9.debugFn('notice', `skip: remote branch "${branch}" exists`);
3931
3570
  continue ghsaLoop;
3932
3571
  }
3933
- require$$9.debugFn('notice', `pr: creating for ${id}`);
3934
- const details = ghsaDetails.get(id);
3935
- const summary = details?.summary;
3936
- require$$9.debugFn('notice', `ghsa: ${id} details ${details ? 'found' : 'missing'}`);
3572
+ require$$9.debugFn('notice', `pr: creating for ${ghsaId}`);
3573
+ const details = ghsaDetails.get(ghsaId);
3574
+ require$$9.debugFn('notice', `ghsa: ${ghsaId} details ${details ? 'found' : 'missing'}`);
3937
3575
  const pushed =
3938
3576
  // eslint-disable-next-line no-await-in-loop
3939
3577
  (await utils.gitCreateBranch(branch, cwd)) && (
3940
3578
  // eslint-disable-next-line no-await-in-loop
3941
3579
  await utils.gitCheckoutBranch(branch, cwd)) && (
3942
3580
  // eslint-disable-next-line no-await-in-loop
3943
- await utils.gitCommit(`fix: ${id}${summary ? ` - ${summary}` : ''}`, modifiedFiles, {
3581
+ await utils.gitCommit(getSocketFixCommitMessage(ghsaId, details), modifiedFiles, {
3944
3582
  cwd,
3945
3583
  email: fixEnv.gitEmail,
3946
3584
  user: fixEnv.gitUser
@@ -3948,7 +3586,7 @@ async function coanaFix(fixConfig) {
3948
3586
  // eslint-disable-next-line no-await-in-loop
3949
3587
  await utils.gitPushBranch(branch, cwd));
3950
3588
  if (!pushed) {
3951
- logger.logger.warn(`Push failed for ${id}, skipping PR creation.`);
3589
+ logger.logger.warn(`Push failed for ${ghsaId}, skipping PR creation.`);
3952
3590
  // eslint-disable-next-line no-await-in-loop
3953
3591
  await utils.gitResetAndClean(fixEnv.baseBranch, cwd);
3954
3592
  // eslint-disable-next-line no-await-in-loop
@@ -3960,12 +3598,12 @@ async function coanaFix(fixConfig) {
3960
3598
 
3961
3599
  // Set up git remote.
3962
3600
  // eslint-disable-next-line no-await-in-loop
3963
- await setGitRemoteGithubRepoUrl(fixEnv.repoInfo.owner, fixEnv.repoInfo.repo, fixEnv.githubToken, cwd);
3601
+ await utils.setGitRemoteGithubRepoUrl(fixEnv.repoInfo.owner, fixEnv.repoInfo.repo, fixEnv.githubToken, cwd);
3964
3602
 
3965
3603
  // eslint-disable-next-line no-await-in-loop
3966
- const prResponse = await openCoanaPr(fixEnv.repoInfo.owner, fixEnv.repoInfo.repo, branch,
3604
+ const prResponse = await openSocketFixPr(fixEnv.repoInfo.owner, fixEnv.repoInfo.repo, branch,
3967
3605
  // Single GHSA ID.
3968
- [id], {
3606
+ [ghsaId], {
3969
3607
  baseBranch: fixEnv.baseBranch,
3970
3608
  cwd,
3971
3609
  ghsaDetails
@@ -3975,7 +3613,7 @@ async function coanaFix(fixConfig) {
3975
3613
  data
3976
3614
  } = prResponse;
3977
3615
  const prRef = `PR #${data.number}`;
3978
- logger.logger.success(`Opened ${prRef} for ${id}.`);
3616
+ logger.logger.success(`Opened ${prRef} for ${ghsaId}.`);
3979
3617
  if (autoMerge) {
3980
3618
  logger.logger.indent();
3981
3619
  spinner?.indent();
@@ -3983,7 +3621,7 @@ async function coanaFix(fixConfig) {
3983
3621
  const {
3984
3622
  details,
3985
3623
  enabled
3986
- } = await enablePrAutoMerge(data);
3624
+ } = await utils.enablePrAutoMerge(data);
3987
3625
  if (enabled) {
3988
3626
  logger.logger.info(`Auto-merge enabled for ${prRef}.`);
3989
3627
  } else {
@@ -4001,7 +3639,7 @@ async function coanaFix(fixConfig) {
4001
3639
  // eslint-disable-next-line no-await-in-loop
4002
3640
  await utils.gitCheckoutBranch(fixEnv.baseBranch, cwd);
4003
3641
  } catch (e) {
4004
- logger.logger.warn(`Unexpected condition: Push failed for ${id}, skipping PR creation.`);
3642
+ logger.logger.warn(`Unexpected condition: Push failed for ${ghsaId}, skipping PR creation.`);
4005
3643
  require$$9.debugDir('inspect', {
4006
3644
  error: e
4007
3645
  });
@@ -4016,822 +3654,13 @@ async function coanaFix(fixConfig) {
4016
3654
  break ghsaLoop;
4017
3655
  }
4018
3656
  }
4019
- spinner?.stop();
4020
- return {
4021
- ok: true,
4022
- data: {
4023
- fixed: overallFixed
4024
- }
4025
- };
4026
- }
4027
-
4028
- function getPrsForPurl(fixEnv, partialPurl) {
4029
- if (!fixEnv) {
4030
- return [];
4031
- }
4032
- const prs = [];
4033
- const partialPurlObj = utils.getPurlObject(partialPurl);
4034
- const branchFullName = getSocketBranchFullNameComponent(partialPurlObj);
4035
- const branchPurlType = getSocketBranchPurlTypeComponent(partialPurlObj);
4036
- for (const pr of fixEnv.prs) {
4037
- const parsedBranch = genericSocketBranchParser(pr.headRefName);
4038
- if (branchPurlType === parsedBranch?.type && branchFullName === parsedBranch?.fullName) {
4039
- prs.push(pr);
4040
- }
4041
- }
4042
- if (require$$9.isDebug('notice,silly')) {
4043
- const fullName = packages.resolvePackageName(partialPurlObj);
4044
- if (prs.length) {
4045
- require$$9.debugFn('notice', `found: ${prs.length} PRs for ${fullName}`);
4046
- require$$9.debugDir('silly', {
4047
- prs
4048
- });
4049
- } else if (fixEnv.prs.length) {
4050
- require$$9.debugFn('notice', `miss: 0 PRs found for ${fullName}`);
4051
- }
4052
- }
4053
- return prs;
4054
- }
4055
-
4056
- async function getActualTree(cwd = process.cwd()) {
4057
- try {
4058
- // @npmcli/arborist DOES have partial support for pnpm structured node_modules
4059
- // folders. However, support is iffy resulting in unhappy paths of errors and hangs.
4060
- // So, to avoid unhappy paths, we restrict our usage to --dry-run loading of the
4061
- // node_modules folder.
4062
- const arb = new shadowNpmInject.Arborist({
4063
- path: cwd,
4064
- ...shadowNpmInject.SAFE_NO_SAVE_ARBORIST_REIFY_OPTIONS_OVERRIDES
4065
- });
4066
- return {
4067
- actualTree: await arb.loadActual()
4068
- };
4069
- } catch (e) {
4070
- return {
4071
- error: e
4072
- };
4073
- }
4074
- }
4075
-
4076
- const {
4077
- BUN: BUN$4,
4078
- NPM: NPM$4,
4079
- OVERRIDES: OVERRIDES$1,
4080
- PNPM: PNPM$4,
4081
- RESOLUTIONS: RESOLUTIONS$1,
4082
- VLT: VLT$5,
4083
- YARN_BERRY: YARN_BERRY$4,
4084
- YARN_CLASSIC: YARN_CLASSIC$4
4085
- } = constants;
4086
- function getOverridesDataBun(pkgEnvDetails, pkgJson = pkgEnvDetails.editablePkgJson.content) {
4087
- const overrides = pkgJson?.[RESOLUTIONS$1] ?? {};
4088
- return {
4089
- type: YARN_BERRY$4,
4090
- overrides
4091
- };
4092
- }
4093
-
4094
- // npm overrides documentation:
4095
- // https://docs.npmjs.com/cli/v10/configuring-npm/package-json#overrides
4096
- function getOverridesDataNpm(pkgEnvDetails, pkgJson = pkgEnvDetails.editablePkgJson.content) {
4097
- const overrides = pkgJson?.[OVERRIDES$1] ?? {};
4098
- return {
4099
- type: NPM$4,
4100
- overrides
4101
- };
4102
- }
4103
-
4104
- // pnpm overrides documentation:
4105
- // https://pnpm.io/package_json#pnpmoverrides
4106
- function getOverridesDataPnpm(pkgEnvDetails, pkgJson = pkgEnvDetails.editablePkgJson.content) {
4107
- const overrides = pkgJson?.[PNPM$4]?.[OVERRIDES$1] ?? {};
4108
- return {
4109
- type: PNPM$4,
4110
- overrides
4111
- };
4112
- }
4113
- function getOverridesDataVlt(pkgEnvDetails, pkgJson = pkgEnvDetails.editablePkgJson.content) {
4114
- const overrides = pkgJson?.[OVERRIDES$1] ?? {};
4115
- return {
4116
- type: VLT$5,
4117
- overrides
4118
- };
4119
- }
4120
-
4121
- // Yarn resolutions documentation:
4122
- // https://yarnpkg.com/configuration/manifest#resolutions
4123
- function getOverridesDataYarn(pkgEnvDetails, pkgJson = pkgEnvDetails.editablePkgJson.content) {
4124
- const overrides = pkgJson?.[RESOLUTIONS$1] ?? {};
4125
- return {
4126
- type: YARN_BERRY$4,
4127
- overrides
4128
- };
4129
- }
4130
-
4131
- // Yarn resolutions documentation:
4132
- // https://classic.yarnpkg.com/en/docs/selective-version-resolutions
4133
- function getOverridesDataYarnClassic(pkgEnvDetails, pkgJson = pkgEnvDetails.editablePkgJson.content) {
4134
- const overrides = pkgJson?.[RESOLUTIONS$1] ?? {};
4135
- return {
4136
- type: YARN_CLASSIC$4,
4137
- overrides
4138
- };
4139
- }
4140
- function getOverridesData(pkgEnvDetails, pkgJson) {
4141
- switch (pkgEnvDetails.agent) {
4142
- case BUN$4:
4143
- return getOverridesDataBun(pkgEnvDetails, pkgJson);
4144
- case PNPM$4:
4145
- return getOverridesDataPnpm(pkgEnvDetails, pkgJson);
4146
- case VLT$5:
4147
- return getOverridesDataVlt(pkgEnvDetails, pkgJson);
4148
- case YARN_BERRY$4:
4149
- return getOverridesDataYarn(pkgEnvDetails, pkgJson);
4150
- case YARN_CLASSIC$4:
4151
- return getOverridesDataYarnClassic(pkgEnvDetails, pkgJson);
4152
- case NPM$4:
4153
- default:
4154
- return getOverridesDataNpm(pkgEnvDetails, pkgJson);
4155
- }
4156
- }
4157
-
4158
- const noopHandler = () => {};
4159
- async function agentFix(pkgEnvDetails, actualTree, alertsMap, installer, {
4160
- afterInstall = noopHandler,
4161
- afterUpdate = noopHandler,
4162
- beforeInstall = noopHandler,
4163
- revertInstall = noopHandler
4164
- }, fixConfig) {
4165
- const {
4166
- pkgPath: rootPath
4167
- } = pkgEnvDetails;
4168
- const fixEnv = await getFixEnv();
4169
- require$$9.debugDir('inspect', {
4170
- fixEnv
4171
- });
4172
- const {
4173
- autoMerge,
4174
- cwd,
4175
- limit,
4176
- minSatisfying,
4177
- prCheck,
4178
- rangeStyle,
4179
- spinner,
4180
- test,
4181
- testScript
4182
- } = fixConfig;
4183
- let count = 0;
4184
- const infoByPartialPurl = utils.getCveInfoFromAlertsMap(alertsMap, {
4185
- filter: {
4186
- upgradable: false
4187
- }
4188
- });
4189
- if (!infoByPartialPurl) {
4190
- spinner?.stop();
4191
- logger.logger.info('No fixable vulns found.');
4192
- if (alertsMap.size) {
4193
- require$$9.debugDir('inspect', {
4194
- alertsMap
4195
- });
4196
- } else {
4197
- require$$9.debugFn('inspect', '{ alertsMap: Map(0) {} }');
4198
- }
4199
- return {
4200
- ok: true,
4201
- data: {
4202
- fixed: false
4203
- }
4204
- };
4205
- }
4206
- if (require$$9.isDebug('notice,inspect')) {
4207
- spinner?.stop();
4208
- const partialPurls = Array.from(infoByPartialPurl.keys());
4209
- const {
4210
- length: purlsCount
4211
- } = partialPurls;
4212
- require$$9.debugFn('notice', `found: ${purlsCount} ${words.pluralize('PURL', purlsCount)} with CVEs`);
4213
- require$$9.debugDir('inspect', {
4214
- partialPurls
4215
- });
4216
- spinner?.start();
4217
- }
4218
- const {
4219
- packumentCache
4220
- } = constants;
4221
- const workspacePkgJsonPaths = await utils.globWorkspace(pkgEnvDetails.agent, rootPath);
4222
- const pkgJsonPaths = [...workspacePkgJsonPaths,
4223
- // Process the workspace root last since it will add an override to package.json.
4224
- pkgEnvDetails.editablePkgJson.filename];
4225
- const sortedInfoEntries = Array.from(infoByPartialPurl.entries()).sort((a, b) => sorts.naturalCompare(a[0], b[0]));
4226
- const cleanupInfoEntriesLoop = () => {
4227
- logger.logger.dedent();
4228
- spinner?.dedent();
4229
- packumentCache.clear();
4230
- };
4231
- const getModifiedFiles = async (cwd = process.cwd()) => {
4232
- const unstagedCResult = await utils.gitUnstagedModifiedFiles(cwd);
4233
- return unstagedCResult.ok ? unstagedCResult.data.filter(filepath => {
4234
- const basename = path.basename(filepath);
4235
- return basename === 'package.json' || basename === pkgEnvDetails.lockName;
4236
- }) : [];
4237
- };
4238
- const handleInstallFail = error => {
4239
- cleanupInfoEntriesLoop();
4240
- spinner?.stop();
4241
- return {
4242
- ok: false,
4243
- message: 'Install failed',
4244
- cause: `${pkgEnvDetails.agent} install failed${error ? `; ${error}` : ''}`
4245
- };
4246
- };
4247
- const hasModifiedFiles = async (cwd = process.cwd()) => {
4248
- return (await getModifiedFiles(cwd)).length > 0;
4249
- };
4250
- spinner?.stop();
4251
- infoEntriesLoop: for (let i = 0, {
4252
- length
4253
- } = sortedInfoEntries; i < length; i += 1) {
4254
- const isLastInfoEntry = i === length - 1;
4255
- const infoEntry = sortedInfoEntries[i];
4256
- const partialPurlObj = utils.getPurlObject(infoEntry[0]);
4257
- const name = packages.resolvePackageName(partialPurlObj);
4258
- const infos = Array.from(infoEntry[1].values());
4259
- if (!infos.length) {
4260
- require$$9.debugFn('notice', `miss: CVEs expected, but not found, for ${name}`);
4261
- continue infoEntriesLoop;
4262
- }
4263
- logger.logger.log(`Processing '${name}'`);
4264
- logger.logger.indent();
4265
- spinner?.indent();
4266
- if (registry.getManifestData(partialPurlObj.type, name)) {
4267
- require$$9.debugFn('notice', `found: Socket Optimize variant for ${name}`);
4268
- }
4269
- // eslint-disable-next-line no-await-in-loop
4270
- const packument = await packages.fetchPackagePackument(name);
4271
- if (!packument) {
4272
- logger.logger.warn(`Unexpected condition: No packument found for ${name}.\n`);
4273
- cleanupInfoEntriesLoop();
4274
- // Skip to next package.
4275
- continue infoEntriesLoop;
4276
- }
4277
- require$$9.debugDir('inspect', {
4278
- infos
4279
- });
4280
- const availableVersions = Object.keys(packument.versions);
4281
- const prs = getPrsForPurl(fixEnv, infoEntry[0]);
4282
- const warningsForAfter = new Set();
4283
- let changed = false;
4284
- // eslint-disable-next-line no-unused-labels
4285
- for (let j = 0, {
4286
- length: length_j
4287
- } = pkgJsonPaths; j < length_j; j += 1) {
4288
- const isLastPkgJsonPath = j === length_j - 1;
4289
- const pkgJsonPath = pkgJsonPaths[j];
4290
- const pkgPath = path.dirname(pkgJsonPath);
4291
- const isWorkspaceRoot = pkgJsonPath === pkgEnvDetails.editablePkgJson.filename;
4292
- const workspace = isWorkspaceRoot ? 'root' : path.relative(rootPath, pkgPath);
4293
- // actualTree may not be defined on the first iteration of pkgJsonPathsLoop.
4294
- if (!actualTree) {
4295
- if (!fixEnv.isCi) {
4296
- // eslint-disable-next-line no-await-in-loop
4297
- await utils.removeNodeModules(cwd);
4298
- }
4299
- if (fixEnv.isCi && fs$1.existsSync(path.join(rootPath, 'node_modules'))) {
4300
- // eslint-disable-next-line no-await-in-loop
4301
- const treeResult = await getActualTree(cwd);
4302
- const maybeActualTree = treeResult.actualTree;
4303
- if (!maybeActualTree) {
4304
- // Exit early if install fails.
4305
- return handleInstallFail(treeResult.error);
4306
- }
4307
- actualTree = maybeActualTree;
4308
- } else {
4309
- // eslint-disable-next-line no-await-in-loop
4310
- const installResult = await installer(pkgEnvDetails, {
4311
- cwd,
4312
- spinner
4313
- });
4314
- const maybeActualTree = installResult.actualTree;
4315
- if (!maybeActualTree) {
4316
- // Exit early if install fails.
4317
- return handleInstallFail(installResult.error);
4318
- }
4319
- actualTree = maybeActualTree;
4320
- }
4321
- if (!fs$1.existsSync(pkgEnvDetails.lockPath)) {
4322
- // Exit early if lockfile is missing.
4323
- return handleInstallFail(new Error(`Missing lockfile at ${pkgEnvDetails.lockPath}`));
4324
- }
4325
- }
4326
- const oldVersions = arrays.arrayUnique(shadowNpmInject.findPackageNodes(actualTree, name).map(n => n.version).filter(Boolean));
4327
- if (!oldVersions.length) {
4328
- require$$9.debugFn('notice', `skip: ${name} not found`);
4329
- cleanupInfoEntriesLoop();
4330
- // Skip to next package.
4331
- continue infoEntriesLoop;
4332
- }
4333
-
4334
- // Always re-read the editable package.json to avoid stale mutations
4335
- // across iterations.
4336
- // eslint-disable-next-line no-await-in-loop
4337
- const editablePkgJson = await packages.readPackageJson(pkgJsonPath, {
4338
- editable: true
4339
- });
4340
- const seenBranches = new Set();
4341
- const seenVersions = new Set();
4342
- let hasAnnouncedWorkspace = false;
4343
- let workspaceLogCallCount = logger.logger.logCallCount;
4344
- if (require$$9.isDebug('notice')) {
4345
- require$$9.debugFn('notice', `check: workspace ${workspace}`);
4346
- hasAnnouncedWorkspace = true;
4347
- workspaceLogCallCount = logger.logger.logCallCount;
4348
- }
4349
- oldVersionsLoop: for (const oldVersion of oldVersions) {
4350
- const oldId = `${name}@${oldVersion}`;
4351
- const oldPurl = utils.idToPurl(oldId, partialPurlObj.type);
4352
- const node = shadowNpmInject.findPackageNode(actualTree, name, oldVersion);
4353
- if (!node) {
4354
- require$$9.debugFn('notice', `skip: ${oldId} not found`);
4355
- continue oldVersionsLoop;
4356
- }
4357
- infosLoop: for (const {
4358
- firstPatchedVersionIdentifier,
4359
- vulnerableVersionRange
4360
- } of infos) {
4361
- const newVersion = shadowNpmInject.findBestPatchVersion(node, availableVersions, {
4362
- minSatisfying,
4363
- vulnerableVersionRange
4364
- });
4365
- const newVersionPackument = newVersion ? packument.versions[newVersion] : undefined;
4366
- if (!(newVersion && newVersionPackument)) {
4367
- warningsForAfter.add(`${oldId} not updated: requires >=${firstPatchedVersionIdentifier}`);
4368
- continue infosLoop;
4369
- }
4370
- if (seenVersions.has(newVersion)) {
4371
- continue infosLoop;
4372
- }
4373
- if (vendor.semverExports.gte(oldVersion, newVersion)) {
4374
- require$$9.debugFn('silly', `skip: ${oldId} is >= ${newVersion}`);
4375
- continue infosLoop;
4376
- }
4377
- const branch = getSocketBranchName(oldPurl, newVersion, workspace);
4378
- if (seenBranches.has(branch)) {
4379
- continue infosLoop;
4380
- }
4381
- const pr = prCheck ? prs.find(p => p.headRefName === branch) : undefined;
4382
- if (pr) {
4383
- require$$9.debugFn('notice', `skip: PR #${pr.number} for ${name}@${newVersion} exists`);
4384
- seenBranches.add(branch);
4385
- continue infosLoop;
4386
- }
4387
- if (fixEnv.isCi && (
4388
- // eslint-disable-next-line no-await-in-loop
4389
- await utils.gitRemoteBranchExists(branch, cwd))) {
4390
- require$$9.debugFn('notice', `skip: remote branch "${branch}" for ${name}@${newVersion} exists`);
4391
- seenBranches.add(branch);
4392
- continue infosLoop;
4393
- }
4394
- const {
4395
- overrides: oldOverrides
4396
- } = getOverridesData(pkgEnvDetails, editablePkgJson.content);
4397
- let refRange = oldOverrides?.[`${name}@${vulnerableVersionRange}`];
4398
- if (!strings.isNonEmptyString(refRange)) {
4399
- refRange = oldOverrides?.[name];
4400
- }
4401
- if (!strings.isNonEmptyString(refRange)) {
4402
- refRange = oldVersion;
4403
- }
4404
-
4405
- // eslint-disable-next-line no-await-in-loop
4406
- await beforeInstall(editablePkgJson, packument, oldVersion, newVersion, vulnerableVersionRange, fixConfig);
4407
- shadowNpmInject.updatePackageJsonFromNode(editablePkgJson, actualTree, node, newVersion, rangeStyle);
4408
-
4409
- // eslint-disable-next-line no-await-in-loop
4410
- await editablePkgJson.save({
4411
- ignoreWhitespace: true
4412
- });
4413
-
4414
- // eslint-disable-next-line no-await-in-loop
4415
- await afterUpdate(editablePkgJson, packument, oldVersion, newVersion, vulnerableVersionRange, fixConfig);
4416
-
4417
- // eslint-disable-next-line no-await-in-loop
4418
- if (!(await hasModifiedFiles(cwd))) {
4419
- require$$9.debugFn('notice', `skip: no changes for ${name}@${newVersion}`);
4420
- seenVersions.add(newVersion);
4421
- // Reset things just in case.
4422
- if (fixEnv.isCi) {
4423
- // eslint-disable-next-line no-await-in-loop
4424
- await utils.gitResetAndClean(fixEnv.baseBranch, cwd);
4425
- // eslint-disable-next-line no-await-in-loop
4426
- await utils.gitCheckoutBranch(fixEnv.baseBranch, cwd);
4427
- }
4428
- continue infosLoop;
4429
- }
4430
- spinner?.start();
4431
- if (!hasAnnouncedWorkspace) {
4432
- hasAnnouncedWorkspace = true;
4433
- workspaceLogCallCount = logger.logger.logCallCount;
4434
- }
4435
- const newId = `${name}@${utils.applyRange(refRange, newVersion, rangeStyle)}`;
4436
- spinner?.info(`Installing ${newId} in ${workspace}.`);
4437
- let error;
4438
- let errored = false;
4439
- try {
4440
- // eslint-disable-next-line no-await-in-loop
4441
- const installResult = await installer(pkgEnvDetails, {
4442
- cwd,
4443
- spinner
4444
- });
4445
- const maybeActualTree = installResult.actualTree;
4446
- if (!maybeActualTree) {
4447
- errored = true;
4448
- error = installResult.error;
4449
- } else if (!fs$1.existsSync(pkgEnvDetails.lockPath)) {
4450
- errored = true;
4451
- error = new Error(`Missing lockfile at ${pkgEnvDetails.lockPath}`);
4452
- } else {
4453
- actualTree = maybeActualTree;
4454
- // eslint-disable-next-line no-await-in-loop
4455
- await afterInstall(editablePkgJson, packument, oldVersion, newVersion, vulnerableVersionRange, fixConfig);
4456
- if (test) {
4457
- spinner?.info(`Testing ${newId} in ${workspace}.`);
4458
- // eslint-disable-next-line no-await-in-loop
4459
- await npm.runNpmScript(testScript, [], {
4460
- spinner,
4461
- stdio: 'ignore'
4462
- });
4463
- }
4464
- spinner?.success(`Fixed ${name} in ${workspace}.`);
4465
- seenVersions.add(newVersion);
4466
- }
4467
- } catch (e) {
4468
- error = e;
4469
- errored = true;
4470
- }
4471
- spinner?.stop();
4472
-
4473
- // Check repoInfo to make TypeScript happy.
4474
- if (!errored && fixEnv.isCi && fixEnv.repoInfo) {
4475
- require$$9.debugFn('notice', 'pr: creating');
4476
- try {
4477
- const pushed =
4478
- // eslint-disable-next-line no-await-in-loop
4479
- (await utils.gitCreateBranch(branch, cwd)) && (
4480
- // eslint-disable-next-line no-await-in-loop
4481
- await utils.gitCheckoutBranch(branch, cwd)) && (
4482
- // eslint-disable-next-line no-await-in-loop
4483
- await utils.gitCommit(getSocketCommitMessage(oldPurl, newVersion, workspace),
4484
- // eslint-disable-next-line no-await-in-loop
4485
- await getModifiedFiles(cwd), {
4486
- cwd,
4487
- email: fixEnv.gitEmail,
4488
- user: fixEnv.gitUser
4489
- })) && (
4490
- // eslint-disable-next-line no-await-in-loop
4491
- await utils.gitPushBranch(branch, cwd));
4492
- if (!pushed) {
4493
- logger.logger.warn('Unexpected condition: Push failed, skipping PR creation.');
4494
- // eslint-disable-next-line no-await-in-loop
4495
- await utils.gitResetAndClean(fixEnv.baseBranch, cwd);
4496
- // eslint-disable-next-line no-await-in-loop
4497
- await utils.gitCheckoutBranch(fixEnv.baseBranch, cwd);
4498
- // eslint-disable-next-line no-await-in-loop
4499
- await utils.gitDeleteBranch(branch, cwd);
4500
- // eslint-disable-next-line no-await-in-loop
4501
- const installResult = await installer(pkgEnvDetails, {
4502
- cwd,
4503
- spinner
4504
- });
4505
- const maybeActualTree = installResult.actualTree;
4506
- if (!maybeActualTree) {
4507
- // Exit early if install fails.
4508
- return handleInstallFail(installResult.error);
4509
- }
4510
- if (!fs$1.existsSync(pkgEnvDetails.lockPath)) {
4511
- // Exit early if lockfile is missing.
4512
- return handleInstallFail(new Error(`Missing lockfile at ${pkgEnvDetails.lockPath}`));
4513
- }
4514
- actualTree = maybeActualTree;
4515
- continue infosLoop;
4516
- }
4517
- seenBranches.add(branch);
4518
-
4519
- // eslint-disable-next-line no-await-in-loop
4520
- await Promise.allSettled([setGitRemoteGithubRepoUrl(fixEnv.repoInfo.owner, fixEnv.repoInfo.repo, fixEnv.githubToken, cwd), cleanupPrs(fixEnv.repoInfo.owner, fixEnv.repoInfo.repo, {
4521
- newVersion,
4522
- purl: oldPurl,
4523
- workspace
4524
- })]);
4525
- // eslint-disable-next-line no-await-in-loop
4526
- const prResponse = await openPr(fixEnv.repoInfo.owner, fixEnv.repoInfo.repo, branch, oldPurl, newVersion, {
4527
- baseBranch: fixEnv.baseBranch,
4528
- cwd,
4529
- workspace
4530
- });
4531
- if (prResponse) {
4532
- const {
4533
- data
4534
- } = prResponse;
4535
- const prRef = `PR #${data.number}`;
4536
- logger.logger.success(`Opened ${prRef}.`);
4537
- if (autoMerge) {
4538
- logger.logger.indent();
4539
- spinner?.indent();
4540
- // eslint-disable-next-line no-await-in-loop
4541
- const {
4542
- details,
4543
- enabled
4544
- } = await enablePrAutoMerge(data);
4545
- if (enabled) {
4546
- logger.logger.info(`Auto-merge enabled for ${prRef}.`);
4547
- } else {
4548
- const message = `Failed to enable auto-merge for ${prRef}${details ? `:\n${details.map(d => ` - ${d}`).join('\n')}` : '.'}`;
4549
- logger.logger.error(message);
4550
- }
4551
- logger.logger.dedent();
4552
- spinner?.dedent();
4553
- }
4554
- }
4555
- } catch (e) {
4556
- error = e;
4557
- errored = true;
4558
- }
4559
- } else if (fixEnv.isCi) {
4560
- require$$9.debugFn('notice', 'skip: PR creation');
4561
- }
4562
- if (fixEnv.isCi) {
4563
- spinner?.start();
4564
- // eslint-disable-next-line no-await-in-loop
4565
- await utils.gitResetAndClean(branch, cwd);
4566
- // eslint-disable-next-line no-await-in-loop
4567
- await utils.gitCheckoutBranch(fixEnv.baseBranch, cwd);
4568
- // eslint-disable-next-line no-await-in-loop
4569
- const installResult = await installer(pkgEnvDetails, {
4570
- cwd,
4571
- spinner
4572
- });
4573
- spinner?.stop();
4574
- const maybeActualTree = installResult.actualTree;
4575
- if (maybeActualTree) {
4576
- actualTree = maybeActualTree;
4577
- } else {
4578
- errored = true;
4579
- error = installResult.error;
4580
- }
4581
- }
4582
- if (errored) {
4583
- if (!fixEnv.isCi) {
4584
- spinner?.start();
4585
- // eslint-disable-next-line no-await-in-loop
4586
- await revertInstall(editablePkgJson, packument, oldVersion, newVersion, vulnerableVersionRange, fixConfig);
4587
- // eslint-disable-next-line no-await-in-loop
4588
- await Promise.all([utils.removeNodeModules(cwd), editablePkgJson.save({
4589
- ignoreWhitespace: true
4590
- })]);
4591
- // eslint-disable-next-line no-await-in-loop
4592
- const installResult = await installer(pkgEnvDetails, {
4593
- cwd,
4594
- spinner
4595
- });
4596
- spinner?.stop();
4597
- const maybeActualTree = installResult.actualTree;
4598
- if (!maybeActualTree) {
4599
- // Exit early if install fails.
4600
- return handleInstallFail(installResult.error);
4601
- }
4602
- actualTree = maybeActualTree;
4603
- }
4604
- return {
4605
- ok: false,
4606
- message: 'Update failed',
4607
- cause: `Update failed for ${oldId} in ${workspace}${error ? `; ${error}` : ''}`
4608
- };
4609
- } else {
4610
- changed = true;
4611
- }
4612
- require$$9.debugFn('notice', 'increment: count', count + 1);
4613
- if (++count >= limit) {
4614
- cleanupInfoEntriesLoop();
4615
- // Exit main loop.
4616
- break infoEntriesLoop;
4617
- }
4618
- }
4619
- }
4620
- if (!isLastPkgJsonPath && logger.logger.logCallCount > workspaceLogCallCount) {
4621
- logger.logger.logNewline();
4622
- }
4623
- }
4624
- for (const warningText of warningsForAfter) {
4625
- logger.logger.warn(warningText);
4626
- }
4627
- if (!changed && !warningsForAfter.size) {
4628
- logger.logger.info('No vulnerable versions found.');
4629
- }
4630
- if (!isLastInfoEntry) {
4631
- logger.logger.logNewline();
4632
- }
4633
- cleanupInfoEntriesLoop();
4634
- }
4635
- spinner?.stop();
4636
-
4637
- // Or, did we change anything?
4638
- return {
4639
- ok: true,
4640
- data: {
4641
- fixed: true
4642
- }
4643
- };
4644
- }
4645
-
4646
- const CMD_NAME$s = 'socket fix';
4647
- function getFixAlertsMapOptions(options = {}) {
4648
- return {
4649
- __proto__: null,
4650
- consolidate: true,
4651
- nothrow: true,
4652
- onlyFixable: true,
4653
- ...options,
4654
- filter: utils.toFilterConfig({
4655
- existing: true,
4656
- ...require$$10.getOwn(options, 'filter')
4657
- })
4658
- };
4659
- }
4660
-
4661
- async function install$1(pkgEnvDetails, options) {
4662
- const {
4663
- args: extraArgs,
4664
- cwd,
4665
- spinner
4666
- } = {
4667
- __proto__: null,
4668
- ...options
4669
- };
4670
- const useDebug = require$$9.isDebug('stdio');
4671
- const args = [
4672
- // If "true", npm does not run scripts specified in package.json files.
4673
- // Note that commands explicitly intended to run a particular script, such
4674
- // as `npm start`, `npm stop`, `npm restart`, `npm test`, and `npm run` will
4675
- // still run their intended script if `ignore-scripts` is set, but they will
4676
- // not run any pre- or post-scripts.
4677
- // https://docs.npmjs.com/cli/v11/commands/npm-install#ignore-scripts
4678
- '--ignore-scripts',
4679
- // When "true" submit audit reports alongside the current npm command to the
4680
- // default registry and all registries configured for scopes. See the
4681
- // documentation for `npm audit` for details on what is submitted.
4682
- // https://docs.npmjs.com/cli/v11/commands/npm-install#audit
4683
- '--no-audit',
4684
- // When "true" displays the message at the end of each `npm install` acknowledging
4685
- // the number of dependencies looking for funding. See `npm fund` for details.
4686
- // https://docs.npmjs.com/cli/v11/commands/npm-install#fund
4687
- '--no-fund',
4688
- // When set to "true", npm will display a progress bar during time intensive
4689
- // operations, if `process.stderr` is a TTY. Set to "false" to suppress the
4690
- // progress bar.
4691
- // https://docs.npmjs.com/cli/v8/using-npm/config#progress
4692
- '--no-progress',
4693
- // What level of logs to report. All logs are written to a debug log, with
4694
- // the path to that file printed if the execution of a command fails. The
4695
- // default is "notice".
4696
- // https://docs.npmjs.com/cli/v8/using-npm/config#loglevel
4697
- ...(useDebug ? [] : ['--silent']), ...(extraArgs ?? [])];
4698
- const wasSpinning = !!spinner?.isSpinning;
4699
- spinner?.stop();
4700
- const quotedCmd = `\`${pkgEnvDetails.agent} install ${args.join(' ')}\``;
4701
- require$$9.debugFn('stdio', `spawn: ${quotedCmd}`);
4702
- try {
4703
- await utils.runAgentInstall(pkgEnvDetails, {
4704
- args,
4705
- spinner,
4706
- stdio: useDebug ? 'inherit' : 'ignore'
4707
- });
4708
- } catch (error) {
4709
- const result = {
4710
- error
4711
- };
4712
- require$$9.debugFn('error', `caught: ${quotedCmd} failed`);
4713
- require$$9.debugDir('inspect', result);
4714
- return result;
4715
- }
4716
- const treeResult = await getActualTree(cwd);
4717
- if (treeResult.actualTree) {
4718
- if (wasSpinning) {
4719
- spinner.start();
4720
- }
4721
- return treeResult;
4722
- }
4723
- require$$9.debugFn('error', 'caught: await arb.loadActual() error');
4724
- require$$9.debugDir('inspect', treeResult);
4725
- if (wasSpinning) {
4726
- spinner.start();
4727
- }
4728
- return treeResult;
4729
- }
4730
- async function npmFix(pkgEnvDetails, fixConfig) {
4731
- const {
4732
- purls,
4733
- spinner
4734
- } = fixConfig;
4735
- spinner?.start();
4736
- const flatConfig = await utils.getNpmConfig({
4737
- npmVersion: pkgEnvDetails.agentVersion
4738
- });
4739
- let actualTree;
4740
- let alertsMap;
4741
- try {
4742
- if (purls.length) {
4743
- alertsMap = await utils.getAlertsMapFromPurls(purls, getFixAlertsMapOptions());
4744
- } else {
4745
- let arb;
4746
- try {
4747
- arb = new shadowNpmInject.Arborist({
4748
- path: pkgEnvDetails.pkgPath,
4749
- ...flatConfig,
4750
- ...shadowNpmInject.SAFE_WITH_SAVE_ARBORIST_REIFY_OPTIONS_OVERRIDES
4751
- });
4752
- // Calling arb.reify() creates the arb.diff object, nulls-out arb.idealTree,
4753
- // and populates arb.actualTree.
4754
- actualTree = await arb.reify();
4755
- } catch (e) {
4756
- spinner?.stop();
4757
- require$$9.debugFn('error', 'caught: await arb.reify() error');
4758
- require$$9.debugDir('inspect', {
4759
- error: e
4760
- });
4761
- return {
4762
- ok: false,
4763
- message: 'npm error',
4764
- cause: e?.message || 'Unknown npm error.'
4765
- };
4766
- }
4767
- alertsMap = await shadowNpmInject.getAlertsMapFromArborist(arb, getFixAlertsMapOptions());
4768
- }
4769
- } catch (e) {
4770
- spinner?.stop();
4771
- require$$9.debugFn('error', 'caught: Socket batch PURL API error');
4772
- require$$9.debugDir('inspect', {
4773
- error: e
4774
- });
4775
- return {
4776
- ok: false,
4777
- message: 'Socket API error',
4778
- cause: e?.message || 'Unknown Socket batch PURL API error.'
4779
- };
4780
- }
4781
- let revertData;
4782
- return await agentFix(pkgEnvDetails, actualTree, alertsMap, install$1, {
4783
- async beforeInstall(editablePkgJson) {
4784
- revertData = {
4785
- // Track existing dependencies in the root package.json to revert to later.
4786
- ...(editablePkgJson.content.dependencies && {
4787
- dependencies: {
4788
- ...editablePkgJson.content.dependencies
4789
- }
4790
- }),
4791
- ...(editablePkgJson.content.optionalDependencies && {
4792
- optionalDependencies: {
4793
- ...editablePkgJson.content.optionalDependencies
4794
- }
4795
- }),
4796
- ...(editablePkgJson.content.peerDependencies && {
4797
- peerDependencies: {
4798
- ...editablePkgJson.content.peerDependencies
4799
- }
4800
- })
4801
- };
4802
- },
4803
- async afterUpdate(editablePkgJson, packument, oldVersion, newVersion) {
4804
- // Exit early if not the root workspace.
4805
- if (editablePkgJson.filename !== pkgEnvDetails.editablePkgJson.filename) {
4806
- return;
4807
- }
4808
- // Update package-lock.json using @npmcli/arborist.
4809
- const arb = new shadowNpmInject.Arborist({
4810
- path: pkgEnvDetails.pkgPath,
4811
- ...flatConfig,
4812
- ...shadowNpmInject.SAFE_WITH_SAVE_ARBORIST_REIFY_OPTIONS_OVERRIDES
4813
- });
4814
- // Build the ideal tree of nodes that are used to generated the saved
4815
- // package-lock.json
4816
- const idealTree = await arb.buildIdealTree();
4817
- const node = shadowNpmInject.findPackageNode(idealTree, packument.name, oldVersion);
4818
- if (node) {
4819
- // Update the ideal tree node.
4820
- shadowNpmInject.updateNode(node, newVersion, packument.versions[newVersion]);
4821
- // Save package-lock.json lockfile.
4822
- await arb.reify();
4823
- }
4824
- },
4825
- async revertInstall(editablePkgJson) {
4826
- if (revertData) {
4827
- // Revert package.json.
4828
- editablePkgJson.update(revertData);
4829
- await editablePkgJson.save({
4830
- ignoreWhitespace: true
4831
- });
4832
- }
3657
+ spinner?.stop();
3658
+ return {
3659
+ ok: true,
3660
+ data: {
3661
+ fixed: overallFixed
4833
3662
  }
4834
- }, fixConfig);
3663
+ };
4835
3664
  }
4836
3665
 
4837
3666
  async function outputFixResult(result, outputKind) {
@@ -4850,216 +3679,6 @@ async function outputFixResult(result, outputKind) {
4850
3679
  logger.logger.success('Finished!');
4851
3680
  }
4852
3681
 
4853
- async function install(pkgEnvDetails, options) {
4854
- const {
4855
- args: extraArgs,
4856
- cwd,
4857
- spinner
4858
- } = {
4859
- __proto__: null,
4860
- ...options
4861
- };
4862
- const args = [
4863
- // Do not execute any scripts defined in the project package.json and its dependencies.
4864
- // https://pnpm.io/9.x/cli/install#--ignore-scripts
4865
- '--ignore-scripts',
4866
- // Enable pnpm updates to pnpm-lock.yaml in CI environments.
4867
- // https://pnpm.io/cli/install#--frozen-lockfile
4868
- '--no-frozen-lockfile',
4869
- // Enable a non-interactive pnpm install
4870
- // https://github.com/pnpm/pnpm/issues/6778
4871
- '--config.confirmModulesPurge=false', ...(extraArgs ?? [])];
4872
- const wasSpinning = !!spinner?.isSpinning;
4873
- spinner?.stop();
4874
- const quotedCmd = `\`${pkgEnvDetails.agent} install ${args.join(' ')}\``;
4875
- require$$9.debugFn('stdio', `spawn: ${quotedCmd}`);
4876
- try {
4877
- await utils.runAgentInstall(pkgEnvDetails, {
4878
- args,
4879
- spinner,
4880
- stdio: require$$9.isDebug('stdio') ? 'inherit' : 'ignore'
4881
- });
4882
- } catch (error) {
4883
- const result = {
4884
- error
4885
- };
4886
- require$$9.debugFn('error', `caught: ${quotedCmd} failed`);
4887
- require$$9.debugDir('inspect', result);
4888
- return result;
4889
- }
4890
- const treeResult = await getActualTree(cwd);
4891
- if (treeResult.actualTree) {
4892
- if (wasSpinning) {
4893
- spinner.start();
4894
- }
4895
- return treeResult;
4896
- }
4897
- require$$9.debugFn('error', 'caught: await arb.loadActual() error');
4898
- require$$9.debugDir('inspect', treeResult);
4899
- if (wasSpinning) {
4900
- spinner.start();
4901
- }
4902
- return treeResult;
4903
- }
4904
- async function pnpmFix(pkgEnvDetails, fixConfig) {
4905
- const {
4906
- cwd,
4907
- purls,
4908
- spinner
4909
- } = fixConfig;
4910
- spinner?.start();
4911
- let actualTree;
4912
- let lockSrc = pkgEnvDetails.lockSrc;
4913
- let lockfile = utils.parsePnpmLockfile(lockSrc);
4914
- // Update pnpm-lock.yaml if its version is older than what the installed pnpm
4915
- // produces.
4916
- if (pkgEnvDetails.agentVersion.major >= 10 && (utils.parsePnpmLockfileVersion(lockfile?.lockfileVersion)?.major ?? 0) <= 6) {
4917
- const installResult = await install(pkgEnvDetails, {
4918
- args: ['--lockfile-only'],
4919
- cwd,
4920
- spinner
4921
- });
4922
- const maybeActualTree = installResult.actualTree;
4923
- if (maybeActualTree) {
4924
- lockSrc = (await utils.readLockfile(pkgEnvDetails.lockPath)) ?? '';
4925
- } else {
4926
- lockSrc = '';
4927
- }
4928
- if (lockSrc) {
4929
- actualTree = maybeActualTree;
4930
- lockfile = utils.parsePnpmLockfile(lockSrc);
4931
- } else {
4932
- lockfile = null;
4933
- }
4934
- }
4935
-
4936
- // Exit early if pnpm-lock.yaml is not found or usable.
4937
- // Check !lockSrc to make TypeScript happy.
4938
- if (!lockfile || !lockSrc) {
4939
- spinner?.stop();
4940
- return {
4941
- ok: false,
4942
- message: 'Missing lockfile',
4943
- cause: 'Required pnpm-lock.yaml not found or usable'
4944
- };
4945
- }
4946
- let alertsMap;
4947
- try {
4948
- alertsMap = purls.length ? await utils.getAlertsMapFromPurls(purls, getFixAlertsMapOptions()) : await utils.getAlertsMapFromPnpmLockfile(lockfile, getFixAlertsMapOptions());
4949
- } catch (e) {
4950
- spinner?.stop();
4951
- require$$9.debugFn('error', 'caught: Socket batch PURL API error');
4952
- require$$9.debugDir('inspect', {
4953
- error: e
4954
- });
4955
- return {
4956
- ok: false,
4957
- message: 'Socket API error',
4958
- cause: e?.message || 'Unknown Socket batch PURL API error.'
4959
- };
4960
- }
4961
- let revertData;
4962
- let revertOverrides;
4963
- let revertOverridesSrc = '';
4964
- return await agentFix(pkgEnvDetails, actualTree, alertsMap, install, {
4965
- async beforeInstall(editablePkgJson, packument, oldVersion, newVersion, vulnerableVersionRange, options) {
4966
- lockSrc = (await utils.readLockfile(pkgEnvDetails.lockPath)) ?? '';
4967
-
4968
- // Update overrides for the root workspace.
4969
- if (editablePkgJson.filename === pkgEnvDetails.editablePkgJson.filename) {
4970
- const {
4971
- overrides: oldOverrides
4972
- } = getOverridesDataPnpm(pkgEnvDetails, editablePkgJson.content);
4973
- const oldPnpmSection = editablePkgJson.content['pnpm'];
4974
- const overrideKey = `${packument.name}@${vulnerableVersionRange}`;
4975
- revertOverridesSrc = utils.extractOverridesFromPnpmLockSrc(lockSrc);
4976
- // Track existing overrides in the root package.json to revert to later.
4977
- revertOverrides = {
4978
- pnpm: oldPnpmSection ? {
4979
- ...oldPnpmSection,
4980
- overrides: require$$10.hasKeys(oldOverrides) ? {
4981
- ...oldOverrides,
4982
- [overrideKey]: undefined
4983
- } :
4984
- // Properties with undefined values are deleted when saved as JSON.
4985
- undefined
4986
- } :
4987
- // Properties with undefined values are deleted when saved as JSON.
4988
- undefined
4989
- };
4990
- // Update overrides in the root package.json so that when `pnpm install`
4991
- // generates pnpm-lock.yaml it updates transitive dependencies too.
4992
- editablePkgJson.update({
4993
- pnpm: {
4994
- ...oldPnpmSection,
4995
- overrides: {
4996
- ...oldOverrides,
4997
- [overrideKey]: utils.applyRange(oldOverrides?.[overrideKey] ?? oldVersion, newVersion, options.rangeStyle)
4998
- }
4999
- }
5000
- });
5001
- } else {
5002
- revertOverrides = undefined;
5003
- revertOverridesSrc = '';
5004
- }
5005
- revertData = {
5006
- // If "pnpm" or "pnpm.overrides" fields are undefined they will be
5007
- // deleted when saved.
5008
- ...revertOverrides,
5009
- // Track existing dependencies in the root package.json to revert to later.
5010
- ...(editablePkgJson.content.dependencies && {
5011
- dependencies: {
5012
- ...editablePkgJson.content.dependencies
5013
- }
5014
- }),
5015
- ...(editablePkgJson.content.optionalDependencies && {
5016
- optionalDependencies: {
5017
- ...editablePkgJson.content.optionalDependencies
5018
- }
5019
- }),
5020
- ...(editablePkgJson.content.peerDependencies && {
5021
- peerDependencies: {
5022
- ...editablePkgJson.content.peerDependencies
5023
- }
5024
- })
5025
- };
5026
- },
5027
- async afterInstall(editablePkgJson) {
5028
- if (revertOverrides) {
5029
- // Revert overrides metadata in package.json now that pnpm-lock.yaml
5030
- // has been updated.
5031
- editablePkgJson.update(revertOverrides);
5032
- await editablePkgJson.save({
5033
- ignoreWhitespace: true
5034
- });
5035
- }
5036
- lockSrc = (await utils.readLockfile(pkgEnvDetails.lockPath)) ?? '';
5037
- // Remove "overrides" block from pnpm-lock.yaml lockfile when processing
5038
- // the root workspace.
5039
- if (editablePkgJson.filename === pkgEnvDetails.editablePkgJson.filename) {
5040
- const updatedOverridesContent = utils.extractOverridesFromPnpmLockSrc(lockSrc);
5041
- if (updatedOverridesContent) {
5042
- // Remove "overrides" block from pnpm-lock.yaml lockfile.
5043
- lockSrc = lockSrc.replace(updatedOverridesContent, revertOverridesSrc);
5044
- // Save pnpm-lock.yaml lockfile.
5045
- await fs$1.promises.writeFile(pkgEnvDetails.lockPath, lockSrc, 'utf8');
5046
- }
5047
- }
5048
- },
5049
- async revertInstall(editablePkgJson) {
5050
- if (revertData) {
5051
- // Revert package.json.
5052
- editablePkgJson.update(revertData);
5053
- await editablePkgJson.save({
5054
- ignoreWhitespace: true
5055
- });
5056
- // Revert pnpm-lock.yaml lockfile to be on the safe side.
5057
- await fs$1.promises.writeFile(pkgEnvDetails.lockPath, lockSrc, 'utf8');
5058
- }
5059
- }
5060
- }, fixConfig);
5061
- }
5062
-
5063
3682
  async function handleFix({
5064
3683
  autoMerge,
5065
3684
  cwd,
@@ -5076,70 +3695,14 @@ async function handleFix({
5076
3695
  testScript,
5077
3696
  unknownFlags
5078
3697
  }) {
5079
- if (ghsas.length) {
5080
- await outputFixResult(await coanaFix({
5081
- autoMerge,
5082
- cwd,
5083
- ghsas,
5084
- limit,
5085
- orgSlug,
5086
- rangeStyle,
5087
- spinner,
5088
- unknownFlags
5089
- }), outputKind);
5090
- return;
5091
- }
5092
- const pkgEnvCResult = await utils.detectAndValidatePackageEnvironment(cwd, {
5093
- cmdName: CMD_NAME$s,
5094
- logger: logger.logger
5095
- });
5096
- if (!pkgEnvCResult.ok) {
5097
- await outputFixResult(pkgEnvCResult, outputKind);
5098
- return;
5099
- }
5100
- const {
5101
- data: pkgEnvDetails
5102
- } = pkgEnvCResult;
5103
- if (!pkgEnvDetails) {
5104
- await outputFixResult({
5105
- ok: false,
5106
- message: 'No package found.',
5107
- cause: `No valid package environment found for project path: ${cwd}`
5108
- }, outputKind);
5109
- return;
5110
- }
5111
- require$$9.debugDir('inspect', {
5112
- pkgEnvDetails
5113
- });
5114
- const {
5115
- agent,
5116
- agentVersion
5117
- } = pkgEnvDetails;
5118
- const isNpm = agent === 'npm';
5119
- const isPnpm = agent === 'pnpm';
5120
- if (!isNpm && !isPnpm) {
5121
- await outputFixResult({
5122
- ok: false,
5123
- message: 'Not supported.',
5124
- cause: `${agent} v${agentVersion} is not supported by this command.`
5125
- }, outputKind);
5126
- return;
5127
- }
5128
- logger.logger.info(`Fixing packages for ${agent} v${agentVersion}.\n`);
5129
- const fixer = isNpm ? npmFix : pnpmFix;
5130
- await outputFixResult(await fixer(pkgEnvDetails, {
3698
+ await outputFixResult(await coanaFix({
5131
3699
  autoMerge,
5132
3700
  cwd,
5133
3701
  ghsas,
5134
3702
  limit,
5135
- minSatisfying,
5136
3703
  orgSlug,
5137
- prCheck,
5138
- purls,
5139
3704
  rangeStyle,
5140
3705
  spinner,
5141
- test,
5142
- testScript,
5143
3706
  unknownFlags
5144
3707
  }), outputKind);
5145
3708
  }
@@ -5171,14 +3734,14 @@ async function run$I(argv, importMeta, {
5171
3734
  autopilot: {
5172
3735
  type: 'boolean',
5173
3736
  default: false,
5174
- description: `Shorthand for --auto-merge --test`
3737
+ description: `Shorthand for --auto-merge --test`,
3738
+ hidden: true
5175
3739
  },
5176
- ghsa: {
3740
+ id: {
5177
3741
  type: 'string',
5178
3742
  default: [],
5179
- description: `Provide a list of ${vendor.terminalLinkExports('GHSA IDs', 'https://docs.github.com/en/code-security/security-advisories/working-with-global-security-advisories-from-the-github-advisory-database/about-the-github-advisory-database#about-ghsa-ids')} to compute fixes for, as either a comma separated value or as multiple flags.\nUse '--ghsa all' to lookup all GHSA IDs and compute fixes for them.`,
5180
- isMultiple: true,
5181
- hidden: true
3743
+ description: `Provide a list of ${vendor.terminalLinkExports('GHSA IDs', 'https://docs.github.com/en/code-security/security-advisories/working-with-global-security-advisories-from-the-github-advisory-database/about-the-github-advisory-database#about-ghsa-ids')} to compute fixes for, as either a comma separated value or as multiple flags`,
3744
+ isMultiple: true
5182
3745
  },
5183
3746
  limit: {
5184
3747
  type: 'number',
@@ -5194,7 +3757,8 @@ async function run$I(argv, importMeta, {
5194
3757
  minSatisfying: {
5195
3758
  type: 'boolean',
5196
3759
  default: false,
5197
- description: 'Constrain dependency updates to the minimum satisfying version'
3760
+ description: 'Constrain dependency updates to the minimum satisfying version',
3761
+ hidden: true
5198
3762
  },
5199
3763
  prCheck: {
5200
3764
  type: 'boolean',
@@ -5207,7 +3771,8 @@ async function run$I(argv, importMeta, {
5207
3771
  default: [],
5208
3772
  description: `Provide a list of ${vendor.terminalLinkExports('PURLs', 'https://github.com/package-url/purl-spec?tab=readme-ov-file#purl')} to compute fixes for, as either a comma separated value or as\nmultiple flags, instead of querying the Socket API`,
5209
3773
  isMultiple: true,
5210
- shortFlag: 'p'
3774
+ shortFlag: 'p',
3775
+ hidden: true
5211
3776
  },
5212
3777
  rangeStyle: {
5213
3778
  type: 'string',
@@ -5228,12 +3793,14 @@ Available styles:
5228
3793
  test: {
5229
3794
  type: 'boolean',
5230
3795
  default: false,
5231
- description: 'Verify the fix by running unit tests'
3796
+ description: 'Verify the fix by running unit tests',
3797
+ hidden: true
5232
3798
  },
5233
3799
  testScript: {
5234
3800
  type: 'string',
5235
3801
  default: 'test',
5236
- description: "The test script to run for fix attempts (default 'test')"
3802
+ description: "The test script to run for fix attempts (default 'test')",
3803
+ hidden: true
5237
3804
  }
5238
3805
  },
5239
3806
  help: (command, config) => `
@@ -7668,12 +6235,12 @@ async function run$t(argv, importMeta, {
7668
6235
  }
7669
6236
 
7670
6237
  const {
7671
- BUN: BUN$3,
7672
- NPM: NPM$3,
7673
- PNPM: PNPM$3,
7674
- VLT: VLT$4,
7675
- YARN_BERRY: YARN_BERRY$3,
7676
- YARN_CLASSIC: YARN_CLASSIC$3
6238
+ BUN: BUN$4,
6239
+ NPM: NPM$4,
6240
+ PNPM: PNPM$4,
6241
+ VLT: VLT$5,
6242
+ YARN_BERRY: YARN_BERRY$4,
6243
+ YARN_CLASSIC: YARN_CLASSIC$4
7677
6244
  } = constants;
7678
6245
  function matchLsCmdViewHumanStdout(stdout, name) {
7679
6246
  return stdout.includes(` ${name}@`);
@@ -7683,13 +6250,13 @@ function matchQueryCmdStdout(stdout, name) {
7683
6250
  }
7684
6251
  function lsStdoutIncludes(pkgEnvDetails, stdout, name) {
7685
6252
  switch (pkgEnvDetails.agent) {
7686
- case BUN$3:
7687
- case YARN_BERRY$3:
7688
- case YARN_CLASSIC$3:
6253
+ case BUN$4:
6254
+ case YARN_BERRY$4:
6255
+ case YARN_CLASSIC$4:
7689
6256
  return matchLsCmdViewHumanStdout(stdout, name);
7690
- case PNPM$3:
7691
- case VLT$4:
7692
- case NPM$3:
6257
+ case PNPM$4:
6258
+ case VLT$5:
6259
+ case NPM$4:
7693
6260
  default:
7694
6261
  return matchQueryCmdStdout(stdout, name);
7695
6262
  }
@@ -7719,6 +6286,88 @@ function getDependencyEntries(pkgEnvDetails) {
7719
6286
  }) => o);
7720
6287
  }
7721
6288
 
6289
+ const {
6290
+ BUN: BUN$3,
6291
+ NPM: NPM$3,
6292
+ OVERRIDES: OVERRIDES$1,
6293
+ PNPM: PNPM$3,
6294
+ RESOLUTIONS: RESOLUTIONS$1,
6295
+ VLT: VLT$4,
6296
+ YARN_BERRY: YARN_BERRY$3,
6297
+ YARN_CLASSIC: YARN_CLASSIC$3
6298
+ } = constants;
6299
+ function getOverridesDataBun(pkgEnvDetails, pkgJson = pkgEnvDetails.editablePkgJson.content) {
6300
+ const overrides = pkgJson?.[RESOLUTIONS$1] ?? {};
6301
+ return {
6302
+ type: YARN_BERRY$3,
6303
+ overrides
6304
+ };
6305
+ }
6306
+
6307
+ // npm overrides documentation:
6308
+ // https://docs.npmjs.com/cli/v10/configuring-npm/package-json#overrides
6309
+ function getOverridesDataNpm(pkgEnvDetails, pkgJson = pkgEnvDetails.editablePkgJson.content) {
6310
+ const overrides = pkgJson?.[OVERRIDES$1] ?? {};
6311
+ return {
6312
+ type: NPM$3,
6313
+ overrides
6314
+ };
6315
+ }
6316
+
6317
+ // pnpm overrides documentation:
6318
+ // https://pnpm.io/package_json#pnpmoverrides
6319
+ function getOverridesDataPnpm(pkgEnvDetails, pkgJson = pkgEnvDetails.editablePkgJson.content) {
6320
+ const overrides = pkgJson?.[PNPM$3]?.[OVERRIDES$1] ?? {};
6321
+ return {
6322
+ type: PNPM$3,
6323
+ overrides
6324
+ };
6325
+ }
6326
+ function getOverridesDataVlt(pkgEnvDetails, pkgJson = pkgEnvDetails.editablePkgJson.content) {
6327
+ const overrides = pkgJson?.[OVERRIDES$1] ?? {};
6328
+ return {
6329
+ type: VLT$4,
6330
+ overrides
6331
+ };
6332
+ }
6333
+
6334
+ // Yarn resolutions documentation:
6335
+ // https://yarnpkg.com/configuration/manifest#resolutions
6336
+ function getOverridesDataYarn(pkgEnvDetails, pkgJson = pkgEnvDetails.editablePkgJson.content) {
6337
+ const overrides = pkgJson?.[RESOLUTIONS$1] ?? {};
6338
+ return {
6339
+ type: YARN_BERRY$3,
6340
+ overrides
6341
+ };
6342
+ }
6343
+
6344
+ // Yarn resolutions documentation:
6345
+ // https://classic.yarnpkg.com/en/docs/selective-version-resolutions
6346
+ function getOverridesDataYarnClassic(pkgEnvDetails, pkgJson = pkgEnvDetails.editablePkgJson.content) {
6347
+ const overrides = pkgJson?.[RESOLUTIONS$1] ?? {};
6348
+ return {
6349
+ type: YARN_CLASSIC$3,
6350
+ overrides
6351
+ };
6352
+ }
6353
+ function getOverridesData(pkgEnvDetails, pkgJson) {
6354
+ switch (pkgEnvDetails.agent) {
6355
+ case BUN$3:
6356
+ return getOverridesDataBun(pkgEnvDetails, pkgJson);
6357
+ case PNPM$3:
6358
+ return getOverridesDataPnpm(pkgEnvDetails, pkgJson);
6359
+ case VLT$4:
6360
+ return getOverridesDataVlt(pkgEnvDetails, pkgJson);
6361
+ case YARN_BERRY$3:
6362
+ return getOverridesDataYarn(pkgEnvDetails, pkgJson);
6363
+ case YARN_CLASSIC$3:
6364
+ return getOverridesDataYarnClassic(pkgEnvDetails, pkgJson);
6365
+ case NPM$3:
6366
+ default:
6367
+ return getOverridesDataNpm(pkgEnvDetails, pkgJson);
6368
+ }
6369
+ }
6370
+
7722
6371
  const {
7723
6372
  BUN: BUN$2,
7724
6373
  LOCK_EXT,
@@ -7994,8 +6643,8 @@ function updatePkgJsonField(editablePkgJson, field, value) {
7994
6643
  if (oldValue) {
7995
6644
  // The field already exists so we simply update the field value.
7996
6645
  if (field === PNPM) {
7997
- const isPnpmObj = require$$10.isObject(oldValue);
7998
- if (require$$10.hasKeys(value)) {
6646
+ const isPnpmObj = require$$11.isObject(oldValue);
6647
+ if (require$$11.hasKeys(value)) {
7999
6648
  editablePkgJson.update({
8000
6649
  [field]: {
8001
6650
  ...(isPnpmObj ? oldValue : {}),
@@ -8007,7 +6656,7 @@ function updatePkgJsonField(editablePkgJson, field, value) {
8007
6656
  });
8008
6657
  } else {
8009
6658
  // Properties with undefined values are deleted when saved as JSON.
8010
- editablePkgJson.update(require$$10.hasKeys(oldValue) ? {
6659
+ editablePkgJson.update(require$$11.hasKeys(oldValue) ? {
8011
6660
  [field]: {
8012
6661
  ...(isPnpmObj ? oldValue : {}),
8013
6662
  overrides: undefined
@@ -8019,7 +6668,7 @@ function updatePkgJsonField(editablePkgJson, field, value) {
8019
6668
  } else if (field === OVERRIDES || field === RESOLUTIONS) {
8020
6669
  // Properties with undefined values are deleted when saved as JSON.
8021
6670
  editablePkgJson.update({
8022
- [field]: require$$10.hasKeys(value) ? value : undefined
6671
+ [field]: require$$11.hasKeys(value) ? value : undefined
8023
6672
  });
8024
6673
  } else {
8025
6674
  editablePkgJson.update({
@@ -8028,7 +6677,7 @@ function updatePkgJsonField(editablePkgJson, field, value) {
8028
6677
  }
8029
6678
  return;
8030
6679
  }
8031
- if ((field === OVERRIDES || field === PNPM || field === RESOLUTIONS) && !require$$10.hasKeys(value)) {
6680
+ if ((field === OVERRIDES || field === PNPM || field === RESOLUTIONS) && !require$$11.hasKeys(value)) {
8032
6681
  return;
8033
6682
  }
8034
6683
  // Since the field doesn't exist we want to insert it into the package.json
@@ -8160,7 +6809,7 @@ async function addOverrides(pkgEnvDetails, pkgPath, options) {
8160
6809
  let loggedAddingText = false;
8161
6810
 
8162
6811
  // Chunk package names to process them in parallel 3 at a time.
8163
- await require$$11.pEach(manifestEntries, async ({
6812
+ await require$$12.pEach(manifestEntries, async ({
8164
6813
  1: data
8165
6814
  }) => {
8166
6815
  const {
@@ -8174,11 +6823,11 @@ async function addOverrides(pkgEnvDetails, pkgPath, options) {
8174
6823
  for (const {
8175
6824
  1: depObj
8176
6825
  } of depEntries) {
8177
- const sockSpec = require$$10.hasOwn(depObj, sockRegPkgName) ? depObj[sockRegPkgName] : undefined;
6826
+ const sockSpec = require$$11.hasOwn(depObj, sockRegPkgName) ? depObj[sockRegPkgName] : undefined;
8178
6827
  if (sockSpec) {
8179
6828
  depAliasMap.set(sockRegPkgName, sockSpec);
8180
6829
  }
8181
- const origSpec = require$$10.hasOwn(depObj, origPkgName) ? depObj[origPkgName] : undefined;
6830
+ const origSpec = require$$11.hasOwn(depObj, origPkgName) ? depObj[origPkgName] : undefined;
8182
6831
  if (origSpec) {
8183
6832
  let thisSpec = origSpec;
8184
6833
  // Add package aliases for direct dependencies to avoid npm EOVERRIDE
@@ -8214,11 +6863,11 @@ async function addOverrides(pkgEnvDetails, pkgPath, options) {
8214
6863
  npmExecPath
8215
6864
  });
8216
6865
  // Chunk package names to process them in parallel 3 at a time.
8217
- await require$$11.pEach(overridesDataObjects, async ({
6866
+ await require$$12.pEach(overridesDataObjects, async ({
8218
6867
  overrides,
8219
6868
  type
8220
6869
  }) => {
8221
- const overrideExists = require$$10.hasOwn(overrides, origPkgName);
6870
+ const overrideExists = require$$11.hasOwn(overrides, origPkgName);
8222
6871
  if (overrideExists || thingScanner(pkgEnvDetails, thingToScan, origPkgName, lockName)) {
8223
6872
  const oldSpec = overrideExists ? overrides[origPkgName] : undefined;
8224
6873
  const origDepAlias = depAliasMap.get(origPkgName);
@@ -8272,7 +6921,7 @@ async function addOverrides(pkgEnvDetails, pkgPath, options) {
8272
6921
  });
8273
6922
  if (isWorkspace) {
8274
6923
  // Chunk package names to process them in parallel 3 at a time.
8275
- await require$$11.pEach(workspacePkgJsonPaths, async workspacePkgJsonPath => {
6924
+ await require$$12.pEach(workspacePkgJsonPaths, async workspacePkgJsonPath => {
8276
6925
  const otherState = await addOverrides(pkgEnvDetails, path.dirname(workspacePkgJsonPath), {
8277
6926
  logger,
8278
6927
  pin,
@@ -8295,7 +6944,7 @@ async function addOverrides(pkgEnvDetails, pkgPath, options) {
8295
6944
  overrides,
8296
6945
  type
8297
6946
  } of overridesDataObjects) {
8298
- updateManifest(type, pkgEnvDetails.editablePkgJson, require$$10.toSortedObject(overrides));
6947
+ updateManifest(type, pkgEnvDetails.editablePkgJson, require$$11.toSortedObject(overrides));
8299
6948
  }
8300
6949
  }
8301
6950
  await pkgEnvDetails.editablePkgJson.save();
@@ -13413,8 +12062,14 @@ async function handleScanReach({
13413
12062
  reachabilityOptions,
13414
12063
  targets
13415
12064
  }) {
12065
+ const {
12066
+ spinner
12067
+ } = constants;
12068
+
13416
12069
  // Get supported file names
13417
- const supportedFilesCResult = await fetchSupportedScanFileNames();
12070
+ const supportedFilesCResult = await fetchSupportedScanFileNames({
12071
+ spinner
12072
+ });
13418
12073
  if (!supportedFilesCResult.ok) {
13419
12074
  await outputScanReach(supportedFilesCResult, {
13420
12075
  cwd,
@@ -13422,9 +12077,6 @@ async function handleScanReach({
13422
12077
  });
13423
12078
  return;
13424
12079
  }
13425
- const {
13426
- spinner
13427
- } = constants;
13428
12080
  spinner.start('Searching for local manifest files to include in reachability analysis...');
13429
12081
  const supportedFiles = supportedFilesCResult.data;
13430
12082
  const packagePaths = await utils.getPackageFilesForScan(targets, supportedFiles, {
@@ -15350,5 +14002,5 @@ void (async () => {
15350
14002
  await utils.captureException(e);
15351
14003
  }
15352
14004
  })();
15353
- //# debugId=6b91ffac-2883-43db-b1da-8c6b087473f4
14005
+ //# debugId=11a3cbfe-6b5a-4bf7-afd9-6885b9deef59
15354
14006
  //# sourceMappingURL=cli.js.map