@socketsecurity/cli-with-sentry 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +465 -404
- package/dist/cli.js.map +1 -1
- package/dist/constants.js +3 -3
- package/dist/constants.js.map +1 -1
- package/dist/flags.js +5 -6
- package/dist/flags.js.map +1 -1
- package/dist/shadow-npm-bin.js +4 -4
- package/dist/shadow-npm-bin.js.map +1 -1
- package/dist/shadow-npm-inject.js +5 -8
- package/dist/shadow-npm-inject.js.map +1 -1
- package/dist/socket-completion.bash +1 -1
- package/dist/tsconfig.dts.tsbuildinfo +1 -1
- package/dist/types/commands/fix/cmd-fix.d.mts.map +1 -1
- package/dist/types/commands/fix/coana-fix.d.mts.map +1 -1
- package/dist/types/commands/fix/{fix-env-helpers.d.mts → env-helpers.d.mts} +1 -1
- package/dist/types/commands/fix/env-helpers.d.mts.map +1 -0
- package/dist/types/commands/fix/git.d.mts +13 -0
- package/dist/types/commands/fix/git.d.mts.map +1 -0
- package/dist/types/commands/fix/pull-request.d.mts +10 -53
- package/dist/types/commands/fix/pull-request.d.mts.map +1 -1
- package/dist/types/commands/patch/cmd-patch.d.mts.map +1 -1
- package/dist/types/commands/patch/handle-patch.d.mts +1 -1
- package/dist/types/commands/patch/handle-patch.d.mts.map +1 -1
- package/dist/types/commands/patch/manifest-schema.d.mts +34 -0
- package/dist/types/commands/patch/manifest-schema.d.mts.map +1 -0
- package/dist/types/commands/scan/fetch-supported-scan-file-names.d.mts +2 -0
- package/dist/types/commands/scan/fetch-supported-scan-file-names.d.mts.map +1 -1
- package/dist/types/flags.d.mts +9 -8
- package/dist/types/flags.d.mts.map +1 -1
- package/dist/types/shadow/npm/arborist/lib/arborist/index.d.mts.map +1 -1
- package/dist/types/shadow/npm/paths.d.mts +0 -1
- package/dist/types/shadow/npm/paths.d.mts.map +1 -1
- package/dist/types/utils/fs.d.mts +0 -1
- package/dist/types/utils/fs.d.mts.map +1 -1
- package/dist/types/utils/github.d.mts +38 -0
- package/dist/types/utils/github.d.mts.map +1 -0
- package/dist/types/utils/glob.d.mts +0 -1
- package/dist/types/utils/glob.d.mts.map +1 -1
- package/dist/utils.js +205 -18
- package/dist/utils.js.map +1 -1
- package/dist/vendor.js +3460 -140
- package/external/@socketsecurity/registry/external/libnpmpack.js +96569 -41361
- package/external/@socketsecurity/registry/external/pacote.js +77357 -68133
- package/external/@socketsecurity/registry/lib/fs.js +13 -27
- package/external/@socketsecurity/registry/lib/json.js +42 -0
- package/external/@socketsecurity/registry/manifest.json +4 -4
- package/package.json +9 -8
- package/dist/types/commands/fix/fix-branch-helpers.d.mts +0 -4
- package/dist/types/commands/fix/fix-branch-helpers.d.mts.map +0 -1
- package/dist/types/commands/fix/fix-env-helpers.d.mts.map +0 -1
- package/dist/types/commands/fix/socket-git.d.mts +0 -32
- package/dist/types/commands/fix/socket-git.d.mts.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -18,13 +18,14 @@ 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
21
|
var path$1 = require('../external/@socketsecurity/registry/lib/path');
|
|
23
22
|
var shadowNpmBin = require('./shadow-npm-bin.js');
|
|
24
|
-
var require$$
|
|
23
|
+
var require$$11 = require('../external/@socketsecurity/registry/lib/objects');
|
|
25
24
|
var registry = require('../external/@socketsecurity/registry');
|
|
26
25
|
var packages = require('../external/@socketsecurity/registry/lib/packages');
|
|
27
|
-
var require$$
|
|
26
|
+
var require$$12 = require('../external/@socketsecurity/registry/lib/promises');
|
|
27
|
+
var regexps = require('../external/@socketsecurity/registry/lib/regexps');
|
|
28
|
+
var require$$0$1 = require('node:crypto');
|
|
28
29
|
var require$$1 = require('node:util');
|
|
29
30
|
var os = require('node:os');
|
|
30
31
|
var promises = require('node:stream/promises');
|
|
@@ -923,7 +924,8 @@ async function fetchCreateOrgFullScan(packagePaths, orgSlug, config, options) {
|
|
|
923
924
|
|
|
924
925
|
async function fetchSupportedScanFileNames(options) {
|
|
925
926
|
const {
|
|
926
|
-
sdkOpts
|
|
927
|
+
sdkOpts,
|
|
928
|
+
spinner
|
|
927
929
|
} = {
|
|
928
930
|
__proto__: null,
|
|
929
931
|
...options
|
|
@@ -934,7 +936,8 @@ async function fetchSupportedScanFileNames(options) {
|
|
|
934
936
|
}
|
|
935
937
|
const sockSdk = sockSdkCResult.data;
|
|
936
938
|
return await utils.handleApiCall(sockSdk.getSupportedScanFiles(), {
|
|
937
|
-
desc: 'supported scan file types'
|
|
939
|
+
desc: 'supported scan file types',
|
|
940
|
+
spinner
|
|
938
941
|
});
|
|
939
942
|
}
|
|
940
943
|
|
|
@@ -2154,7 +2157,12 @@ async function handleCreateNewScan({
|
|
|
2154
2157
|
});
|
|
2155
2158
|
logger.logger.info('Auto-generation finished. Proceeding with Scan creation.');
|
|
2156
2159
|
}
|
|
2157
|
-
const
|
|
2160
|
+
const {
|
|
2161
|
+
spinner
|
|
2162
|
+
} = constants;
|
|
2163
|
+
const supportedFilesCResult = await fetchSupportedScanFileNames({
|
|
2164
|
+
spinner
|
|
2165
|
+
});
|
|
2158
2166
|
if (!supportedFilesCResult.ok) {
|
|
2159
2167
|
await outputCreateNewScan(supportedFilesCResult, {
|
|
2160
2168
|
interactive,
|
|
@@ -2162,9 +2170,6 @@ async function handleCreateNewScan({
|
|
|
2162
2170
|
});
|
|
2163
2171
|
return;
|
|
2164
2172
|
}
|
|
2165
|
-
const {
|
|
2166
|
-
spinner
|
|
2167
|
-
} = constants;
|
|
2168
2173
|
spinner.start('Searching for local files to include in scan...');
|
|
2169
2174
|
const supportedFiles = supportedFilesCResult.data;
|
|
2170
2175
|
const packagePaths = await utils.getPackageFilesForScan(targets, supportedFiles, {
|
|
@@ -3165,210 +3170,76 @@ const cmdConfig = {
|
|
|
3165
3170
|
}
|
|
3166
3171
|
};
|
|
3167
3172
|
|
|
3168
|
-
|
|
3169
|
-
|
|
3173
|
+
const GITHUB_ADVISORIES_URL = 'https://github.com/advisories';
|
|
3174
|
+
function getSocketFixBranchName(ghsaId) {
|
|
3175
|
+
return `socket/fix/${ghsaId}`;
|
|
3170
3176
|
}
|
|
3171
|
-
function
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
+
function getSocketFixBranchPattern(ghsaId) {
|
|
3178
|
+
return new RegExp(`^socket/fix/(${ghsaId ?? '.+'})$`);
|
|
3179
|
+
}
|
|
3180
|
+
function getSocketFixCommitMessage(ghsaId, details) {
|
|
3181
|
+
const summary = details?.summary;
|
|
3182
|
+
return `fix: ${ghsaId}${summary ? ` - ${summary}` : ''}`;
|
|
3183
|
+
}
|
|
3184
|
+
function getSocketFixPullRequestBody(ghsaIds, ghsaDetails) {
|
|
3185
|
+
const vulnCount = ghsaIds.length;
|
|
3186
|
+
if (vulnCount === 1) {
|
|
3187
|
+
const ghsaId = ghsaIds[0];
|
|
3188
|
+
const details = ghsaDetails?.get(ghsaId);
|
|
3189
|
+
const body = `[Socket](${constants.SOCKET_WEBSITE_URL}) fix for [${ghsaId}](${GITHUB_ADVISORIES_URL}/${ghsaId}).`;
|
|
3190
|
+
if (!details) {
|
|
3191
|
+
return body;
|
|
3177
3192
|
}
|
|
3178
|
-
const {
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
+
const packages = details.vulnerabilities.nodes.map(v => `${v.package.name} (${v.package.ecosystem})`);
|
|
3194
|
+
return [body, '', '', `**Vulnerability Summary:** ${details.summary}`, '', `**Severity:** ${details.severity}`, '', `**Affected Packages:** ${arrays.joinAnd(packages)}`].join('\n');
|
|
3195
|
+
}
|
|
3196
|
+
return [`[Socket](${constants.SOCKET_WEBSITE_URL}) fixes for ${vulnCount} GHSAs.`, '', '**Fixed Vulnerabilities:**', ...ghsaIds.map(id => {
|
|
3197
|
+
const details = ghsaDetails?.get(id);
|
|
3198
|
+
const item = `- [${id}](${GITHUB_ADVISORIES_URL}/${id})`;
|
|
3199
|
+
if (details) {
|
|
3200
|
+
const packages = details.vulnerabilities.nodes.map(v => `${v.package.name}`);
|
|
3201
|
+
return `${item} - ${details.summary} (${arrays.joinAnd(packages)})`;
|
|
3202
|
+
}
|
|
3203
|
+
return item;
|
|
3204
|
+
})].join('\n');
|
|
3205
|
+
}
|
|
3206
|
+
function getSocketFixPullRequestTitle(ghsaIds) {
|
|
3207
|
+
const vulnCount = ghsaIds.length;
|
|
3208
|
+
return vulnCount === 1 ? `Fix for ${ghsaIds[0]}` : `Fixes for ${vulnCount} GHSAs`;
|
|
3193
3209
|
}
|
|
3194
|
-
|
|
3195
|
-
function
|
|
3210
|
+
|
|
3211
|
+
async function openSocketFixPr(owner, repo, branch, ghsaIds, options) {
|
|
3196
3212
|
const {
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
workspace
|
|
3213
|
+
baseBranch = 'main',
|
|
3214
|
+
ghsaDetails
|
|
3200
3215
|
} = {
|
|
3201
3216
|
__proto__: null,
|
|
3202
3217
|
...options
|
|
3203
3218
|
};
|
|
3204
|
-
const
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
let _octokit;
|
|
3215
|
-
function getOctokit() {
|
|
3216
|
-
if (_octokit === undefined) {
|
|
3217
|
-
const {
|
|
3218
|
-
SOCKET_CLI_GITHUB_TOKEN
|
|
3219
|
-
} = constants.ENV;
|
|
3220
|
-
if (!SOCKET_CLI_GITHUB_TOKEN) {
|
|
3221
|
-
require$$9.debugFn('notice', 'miss: SOCKET_CLI_GITHUB_TOKEN env var');
|
|
3222
|
-
}
|
|
3223
|
-
const octokitOptions = {
|
|
3224
|
-
auth: SOCKET_CLI_GITHUB_TOKEN,
|
|
3225
|
-
baseUrl: constants.ENV.GITHUB_API_URL
|
|
3219
|
+
const octokit = utils.getOctokit();
|
|
3220
|
+
try {
|
|
3221
|
+
const octokitPullsCreateParams = {
|
|
3222
|
+
owner,
|
|
3223
|
+
repo,
|
|
3224
|
+
title: getSocketFixPullRequestTitle(ghsaIds),
|
|
3225
|
+
head: branch,
|
|
3226
|
+
base: baseBranch,
|
|
3227
|
+
body: getSocketFixPullRequestBody(ghsaIds, ghsaDetails)
|
|
3226
3228
|
};
|
|
3227
3229
|
require$$9.debugDir('inspect', {
|
|
3228
|
-
|
|
3229
|
-
});
|
|
3230
|
-
_octokit = new vendor.Octokit(octokitOptions);
|
|
3231
|
-
}
|
|
3232
|
-
return _octokit;
|
|
3233
|
-
}
|
|
3234
|
-
let _octokitGraphql;
|
|
3235
|
-
function getOctokitGraphql() {
|
|
3236
|
-
if (!_octokitGraphql) {
|
|
3237
|
-
const {
|
|
3238
|
-
SOCKET_CLI_GITHUB_TOKEN
|
|
3239
|
-
} = constants.ENV;
|
|
3240
|
-
if (!SOCKET_CLI_GITHUB_TOKEN) {
|
|
3241
|
-
require$$9.debugFn('notice', 'miss: SOCKET_CLI_GITHUB_TOKEN env var');
|
|
3242
|
-
}
|
|
3243
|
-
_octokitGraphql = vendor.graphql2.defaults({
|
|
3244
|
-
headers: {
|
|
3245
|
-
authorization: `token ${SOCKET_CLI_GITHUB_TOKEN}`
|
|
3246
|
-
}
|
|
3247
|
-
});
|
|
3248
|
-
}
|
|
3249
|
-
return _octokitGraphql;
|
|
3250
|
-
}
|
|
3251
|
-
async function readCache(key,
|
|
3252
|
-
// 5 minute in milliseconds time to live (TTL).
|
|
3253
|
-
ttlMs = 5 * 60 * 1000) {
|
|
3254
|
-
const cacheJsonPath = path.join(constants.githubCachePath, `${key}.json`);
|
|
3255
|
-
const stat = fs$2.safeStatsSync(cacheJsonPath);
|
|
3256
|
-
if (stat) {
|
|
3257
|
-
const isExpired = Date.now() - stat.mtimeMs > ttlMs;
|
|
3258
|
-
if (!isExpired) {
|
|
3259
|
-
return await fs$2.readJson(cacheJsonPath);
|
|
3260
|
-
}
|
|
3261
|
-
}
|
|
3262
|
-
return null;
|
|
3263
|
-
}
|
|
3264
|
-
async function writeCache(key, data) {
|
|
3265
|
-
const {
|
|
3266
|
-
githubCachePath
|
|
3267
|
-
} = constants;
|
|
3268
|
-
const cacheJsonPath = path.join(githubCachePath, `${key}.json`);
|
|
3269
|
-
if (!fs$1.existsSync(githubCachePath)) {
|
|
3270
|
-
await fs$1.promises.mkdir(githubCachePath, {
|
|
3271
|
-
recursive: true
|
|
3272
|
-
});
|
|
3273
|
-
}
|
|
3274
|
-
await fs$2.writeJson(cacheJsonPath, data);
|
|
3275
|
-
}
|
|
3276
|
-
async function cacheFetch(key, fetcher, ttlMs) {
|
|
3277
|
-
// Optionally disable cache.
|
|
3278
|
-
if (constants.ENV.DISABLE_GITHUB_CACHE) {
|
|
3279
|
-
return await fetcher();
|
|
3280
|
-
}
|
|
3281
|
-
let data = await readCache(key, ttlMs);
|
|
3282
|
-
if (!data) {
|
|
3283
|
-
data = await fetcher();
|
|
3284
|
-
await writeCache(key, data);
|
|
3285
|
-
}
|
|
3286
|
-
return data;
|
|
3287
|
-
}
|
|
3288
|
-
async function fetchGhsaDetails(ids) {
|
|
3289
|
-
const results = new Map();
|
|
3290
|
-
if (!ids.length) {
|
|
3291
|
-
return results;
|
|
3292
|
-
}
|
|
3293
|
-
const octokitGraphql = getOctokitGraphql();
|
|
3294
|
-
try {
|
|
3295
|
-
const gqlCacheKey = `${ids.join('-')}-graphql-snapshot`;
|
|
3296
|
-
const aliases = ids.map((id, index) => `advisory${index}: securityAdvisory(ghsaId: "${id}") {
|
|
3297
|
-
ghsaId
|
|
3298
|
-
summary
|
|
3299
|
-
severity
|
|
3300
|
-
publishedAt
|
|
3301
|
-
withdrawnAt
|
|
3302
|
-
vulnerabilities(first: 10) {
|
|
3303
|
-
nodes {
|
|
3304
|
-
package {
|
|
3305
|
-
ecosystem
|
|
3306
|
-
name
|
|
3307
|
-
}
|
|
3308
|
-
vulnerableVersionRange
|
|
3309
|
-
}
|
|
3310
|
-
}
|
|
3311
|
-
}`).join('\n');
|
|
3312
|
-
const gqlResp = await cacheFetch(gqlCacheKey, () => octokitGraphql(`
|
|
3313
|
-
query {
|
|
3314
|
-
${aliases}
|
|
3315
|
-
}
|
|
3316
|
-
`));
|
|
3317
|
-
for (let i = 0, {
|
|
3318
|
-
length
|
|
3319
|
-
} = ids; i < length; i += 1) {
|
|
3320
|
-
const id = ids[i];
|
|
3321
|
-
const advisoryKey = `advisory${i}`;
|
|
3322
|
-
const advisory = gqlResp?.[advisoryKey];
|
|
3323
|
-
if (advisory && advisory.ghsaId) {
|
|
3324
|
-
results.set(id, advisory);
|
|
3325
|
-
} else {
|
|
3326
|
-
require$$9.debugFn('notice', `miss: no advisory found for ${id}`);
|
|
3327
|
-
}
|
|
3328
|
-
}
|
|
3329
|
-
} catch (e) {
|
|
3330
|
-
require$$9.debugFn('error', `Failed to fetch GHSA details: ${e?.message || 'Unknown error'}`);
|
|
3331
|
-
}
|
|
3332
|
-
return results;
|
|
3333
|
-
}
|
|
3334
|
-
async function enablePrAutoMerge({
|
|
3335
|
-
node_id: prId
|
|
3336
|
-
}) {
|
|
3337
|
-
const octokitGraphql = getOctokitGraphql();
|
|
3338
|
-
try {
|
|
3339
|
-
const gqlResp = await octokitGraphql(`
|
|
3340
|
-
mutation EnableAutoMerge($pullRequestId: ID!) {
|
|
3341
|
-
enablePullRequestAutoMerge(input: {
|
|
3342
|
-
pullRequestId: $pullRequestId,
|
|
3343
|
-
mergeMethod: SQUASH
|
|
3344
|
-
}) {
|
|
3345
|
-
pullRequest {
|
|
3346
|
-
number
|
|
3347
|
-
}
|
|
3348
|
-
}
|
|
3349
|
-
}`, {
|
|
3350
|
-
pullRequestId: prId
|
|
3230
|
+
octokitPullsCreateParams
|
|
3351
3231
|
});
|
|
3352
|
-
|
|
3353
|
-
if (respPrNumber) {
|
|
3354
|
-
return {
|
|
3355
|
-
enabled: true
|
|
3356
|
-
};
|
|
3357
|
-
}
|
|
3232
|
+
return await octokit.pulls.create(octokitPullsCreateParams);
|
|
3358
3233
|
} catch (e) {
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
enabled: false,
|
|
3365
|
-
details
|
|
3366
|
-
};
|
|
3234
|
+
let message = `Failed to open pull request`;
|
|
3235
|
+
const errors = e instanceof vendor.RequestError ? e.response?.data?.['errors'] : undefined;
|
|
3236
|
+
if (Array.isArray(errors) && errors.length) {
|
|
3237
|
+
const details = errors.map(d => `- ${d.message?.trim() ?? `${d.resource}.${d.field} (${d.code})`}`).join('\n');
|
|
3238
|
+
message += `:\n${details}`;
|
|
3367
3239
|
}
|
|
3240
|
+
require$$9.debugFn('error', message);
|
|
3368
3241
|
}
|
|
3369
|
-
return
|
|
3370
|
-
enabled: false
|
|
3371
|
-
};
|
|
3242
|
+
return null;
|
|
3372
3243
|
}
|
|
3373
3244
|
async function getSocketPrs(owner, repo, options) {
|
|
3374
3245
|
return (await getSocketPrsWithContext(owner, repo, options)).map(d => d.match);
|
|
@@ -3376,22 +3247,23 @@ async function getSocketPrs(owner, repo, options) {
|
|
|
3376
3247
|
async function getSocketPrsWithContext(owner, repo, options) {
|
|
3377
3248
|
const {
|
|
3378
3249
|
author,
|
|
3250
|
+
ghsaId,
|
|
3379
3251
|
states: statesValue = 'all'
|
|
3380
3252
|
} = {
|
|
3381
3253
|
__proto__: null,
|
|
3382
3254
|
...options
|
|
3383
3255
|
};
|
|
3384
|
-
const branchPattern =
|
|
3256
|
+
const branchPattern = getSocketFixBranchPattern(ghsaId);
|
|
3385
3257
|
const checkAuthor = strings.isNonEmptyString(author);
|
|
3386
|
-
const octokit = getOctokit();
|
|
3387
|
-
const octokitGraphql = getOctokitGraphql();
|
|
3258
|
+
const octokit = utils.getOctokit();
|
|
3259
|
+
const octokitGraphql = utils.getOctokitGraphql();
|
|
3388
3260
|
const contextualMatches = [];
|
|
3389
3261
|
const states = (typeof statesValue === 'string' ? statesValue.toLowerCase() === 'all' ? ['OPEN', 'CLOSED', 'MERGED'] : [statesValue] : statesValue).map(s => s.toUpperCase());
|
|
3390
3262
|
try {
|
|
3391
3263
|
// Optimistically fetch only the first 50 open PRs using GraphQL to minimize
|
|
3392
3264
|
// API quota usage. Fallback to REST if no matching PRs are found.
|
|
3393
3265
|
const gqlCacheKey = `${repo}-pr-graphql-snapshot`;
|
|
3394
|
-
const gqlResp = await cacheFetch(gqlCacheKey, () => octokitGraphql(`
|
|
3266
|
+
const gqlResp = await utils.cacheFetch(gqlCacheKey, () => octokitGraphql(`
|
|
3395
3267
|
query($owner: String!, $repo: String!, $states: [PullRequestState!]) {
|
|
3396
3268
|
repository(owner: $owner, name: $repo) {
|
|
3397
3269
|
pullRequests(first: 50, states: $states, orderBy: {field: CREATED_AT, direction: DESC}) {
|
|
@@ -3448,7 +3320,7 @@ async function getSocketPrsWithContext(owner, repo, options) {
|
|
|
3448
3320
|
let allPrs;
|
|
3449
3321
|
const cacheKey = `${repo}-pull-requests`;
|
|
3450
3322
|
try {
|
|
3451
|
-
allPrs = await cacheFetch(cacheKey, async () => await octokit.paginate(octokit.pulls.list, {
|
|
3323
|
+
allPrs = await utils.cacheFetch(cacheKey, async () => await octokit.paginate(octokit.pulls.list, {
|
|
3452
3324
|
owner,
|
|
3453
3325
|
repo,
|
|
3454
3326
|
state: 'all',
|
|
@@ -3497,83 +3369,6 @@ async function getSocketPrsWithContext(owner, repo, options) {
|
|
|
3497
3369
|
}
|
|
3498
3370
|
return contextualMatches;
|
|
3499
3371
|
}
|
|
3500
|
-
async function openCoanaPr(owner, repo, branch, ghsaIds, options) {
|
|
3501
|
-
const {
|
|
3502
|
-
baseBranch = 'main',
|
|
3503
|
-
ghsaDetails
|
|
3504
|
-
} = {
|
|
3505
|
-
__proto__: null,
|
|
3506
|
-
...options
|
|
3507
|
-
};
|
|
3508
|
-
const octokit = getOctokit();
|
|
3509
|
-
const vulnCount = ghsaIds.length;
|
|
3510
|
-
const prTitle = vulnCount === 1 ? `Fix for ${ghsaIds[0]}` : `Fixes for ${vulnCount} GHSAs`;
|
|
3511
|
-
let prBody = '';
|
|
3512
|
-
if (vulnCount === 1) {
|
|
3513
|
-
const ghsaId = ghsaIds[0];
|
|
3514
|
-
const details = ghsaDetails?.get(ghsaId);
|
|
3515
|
-
prBody = `[Socket](https://socket.dev/) fix for [${ghsaId}](https://github.com/advisories/${ghsaId}).`;
|
|
3516
|
-
if (details) {
|
|
3517
|
-
const packages = details.vulnerabilities.nodes.map(v => `${v.package.name} (${v.package.ecosystem})`);
|
|
3518
|
-
prBody += ['', '', `**Vulnerability Summary:** ${details.summary}`, '', `**Severity:** ${details.severity}`, '', `**Affected Packages:** ${arrays.joinAnd(packages)}`].join('\n');
|
|
3519
|
-
}
|
|
3520
|
-
} else {
|
|
3521
|
-
prBody = [`[Socket](https://socket.dev/) fixes for ${vulnCount} GHSAs.`, '', '**Fixed Vulnerabilities:**', ...ghsaIds.map(id => {
|
|
3522
|
-
const details = ghsaDetails?.get(id);
|
|
3523
|
-
const item = `- [${id}](https://github.com/advisories/${id})`;
|
|
3524
|
-
if (details) {
|
|
3525
|
-
const packages = details.vulnerabilities.nodes.map(v => `${v.package.name}`);
|
|
3526
|
-
return `${item} - ${details.summary} (${arrays.joinAnd(packages)})`;
|
|
3527
|
-
}
|
|
3528
|
-
return item;
|
|
3529
|
-
})].join('\n');
|
|
3530
|
-
}
|
|
3531
|
-
try {
|
|
3532
|
-
const octokitPullsCreateParams = {
|
|
3533
|
-
owner,
|
|
3534
|
-
repo,
|
|
3535
|
-
title: prTitle,
|
|
3536
|
-
head: branch,
|
|
3537
|
-
base: baseBranch,
|
|
3538
|
-
body: prBody
|
|
3539
|
-
};
|
|
3540
|
-
require$$9.debugDir('inspect', {
|
|
3541
|
-
octokitPullsCreateParams
|
|
3542
|
-
});
|
|
3543
|
-
return await octokit.pulls.create(octokitPullsCreateParams);
|
|
3544
|
-
} catch (e) {
|
|
3545
|
-
let message = `Failed to open pull request`;
|
|
3546
|
-
const errors = e instanceof vendor.RequestError ? e.response?.data?.['errors'] : undefined;
|
|
3547
|
-
if (Array.isArray(errors) && errors.length) {
|
|
3548
|
-
const details = errors.map(d => `- ${d.message?.trim() ?? `${d.resource}.${d.field} (${d.code})`}`).join('\n');
|
|
3549
|
-
message += `:\n${details}`;
|
|
3550
|
-
}
|
|
3551
|
-
require$$9.debugFn('error', message);
|
|
3552
|
-
}
|
|
3553
|
-
return null;
|
|
3554
|
-
}
|
|
3555
|
-
async function setGitRemoteGithubRepoUrl(owner, repo, token, cwd = process.cwd()) {
|
|
3556
|
-
const {
|
|
3557
|
-
host
|
|
3558
|
-
} = new URL(constants.ENV.GITHUB_SERVER_URL);
|
|
3559
|
-
const url = `https://x-access-token:${token}@${host}/${owner}/${repo}`;
|
|
3560
|
-
const stdioIgnoreOptions = {
|
|
3561
|
-
cwd,
|
|
3562
|
-
stdio: require$$9.isDebug('stdio') ? 'inherit' : 'ignore'
|
|
3563
|
-
};
|
|
3564
|
-
const quotedCmd = `\`git remote set-url origin ${url}\``;
|
|
3565
|
-
require$$9.debugFn('stdio', `spawn: ${quotedCmd}`);
|
|
3566
|
-
try {
|
|
3567
|
-
await spawn.spawn('git', ['remote', 'set-url', 'origin', url], stdioIgnoreOptions);
|
|
3568
|
-
return true;
|
|
3569
|
-
} catch (e) {
|
|
3570
|
-
require$$9.debugFn('error', `caught: ${quotedCmd} failed`);
|
|
3571
|
-
require$$9.debugDir('inspect', {
|
|
3572
|
-
error: e
|
|
3573
|
-
});
|
|
3574
|
-
}
|
|
3575
|
-
return false;
|
|
3576
|
-
}
|
|
3577
3372
|
|
|
3578
3373
|
function ciRepoInfo() {
|
|
3579
3374
|
const {
|
|
@@ -3652,7 +3447,9 @@ async function coanaFix(fixConfig) {
|
|
|
3652
3447
|
return sockSdkCResult;
|
|
3653
3448
|
}
|
|
3654
3449
|
const sockSdk = sockSdkCResult.data;
|
|
3655
|
-
const supportedFilesCResult = await fetchSupportedScanFileNames(
|
|
3450
|
+
const supportedFilesCResult = await fetchSupportedScanFileNames({
|
|
3451
|
+
spinner
|
|
3452
|
+
});
|
|
3656
3453
|
if (!supportedFilesCResult.ok) {
|
|
3657
3454
|
return supportedFilesCResult;
|
|
3658
3455
|
}
|
|
@@ -3731,7 +3528,7 @@ async function coanaFix(fixConfig) {
|
|
|
3731
3528
|
};
|
|
3732
3529
|
}
|
|
3733
3530
|
require$$9.debugFn('notice', `fetch: ${ids.length} GHSA details for ${arrays.joinAnd(ids)}`);
|
|
3734
|
-
const ghsaDetails = await fetchGhsaDetails(ids);
|
|
3531
|
+
const ghsaDetails = await utils.fetchGhsaDetails(ids);
|
|
3735
3532
|
const scanBaseNames = new Set(scanFilepaths.map(p => path.basename(p)));
|
|
3736
3533
|
require$$9.debugFn('notice', `found: ${ghsaDetails.size} GHSA details`);
|
|
3737
3534
|
let count = 0;
|
|
@@ -3741,18 +3538,18 @@ async function coanaFix(fixConfig) {
|
|
|
3741
3538
|
ghsaLoop: for (let i = 0, {
|
|
3742
3539
|
length
|
|
3743
3540
|
} = ids; i < length; i += 1) {
|
|
3744
|
-
const
|
|
3745
|
-
require$$9.debugFn('notice', `check: ${
|
|
3541
|
+
const ghsaId = ids[i];
|
|
3542
|
+
require$$9.debugFn('notice', `check: ${ghsaId}`);
|
|
3746
3543
|
|
|
3747
3544
|
// Apply fix for single GHSA ID.
|
|
3748
3545
|
// eslint-disable-next-line no-await-in-loop
|
|
3749
|
-
const fixCResult = await utils.spawnCoana(['compute-fixes-and-upgrade-purls', cwd, '--manifests-tar-hash', tarHash, '--apply-fixes-to',
|
|
3546
|
+
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, {
|
|
3750
3547
|
cwd,
|
|
3751
3548
|
spinner,
|
|
3752
3549
|
stdio: 'inherit'
|
|
3753
3550
|
});
|
|
3754
3551
|
if (!fixCResult.ok) {
|
|
3755
|
-
logger.logger.error(`Update failed for ${
|
|
3552
|
+
logger.logger.error(`Update failed for ${ghsaId}: ${fixCResult.message || 'Unknown error'}`);
|
|
3756
3553
|
continue ghsaLoop;
|
|
3757
3554
|
}
|
|
3758
3555
|
|
|
@@ -3761,11 +3558,11 @@ async function coanaFix(fixConfig) {
|
|
|
3761
3558
|
const unstagedCResult = await utils.gitUnstagedModifiedFiles(cwd);
|
|
3762
3559
|
const modifiedFiles = unstagedCResult.ok ? unstagedCResult.data.filter(relPath => scanBaseNames.has(path.basename(relPath))) : [];
|
|
3763
3560
|
if (!modifiedFiles.length) {
|
|
3764
|
-
require$$9.debugFn('notice', `skip: no changes for ${
|
|
3561
|
+
require$$9.debugFn('notice', `skip: no changes for ${ghsaId}`);
|
|
3765
3562
|
continue ghsaLoop;
|
|
3766
3563
|
}
|
|
3767
3564
|
overallFixed = true;
|
|
3768
|
-
const branch =
|
|
3565
|
+
const branch = getSocketFixBranchName(ghsaId);
|
|
3769
3566
|
try {
|
|
3770
3567
|
// Check if branch already exists.
|
|
3771
3568
|
// eslint-disable-next-line no-await-in-loop
|
|
@@ -3773,17 +3570,16 @@ async function coanaFix(fixConfig) {
|
|
|
3773
3570
|
require$$9.debugFn('notice', `skip: remote branch "${branch}" exists`);
|
|
3774
3571
|
continue ghsaLoop;
|
|
3775
3572
|
}
|
|
3776
|
-
require$$9.debugFn('notice', `pr: creating for ${
|
|
3777
|
-
const details = ghsaDetails.get(
|
|
3778
|
-
|
|
3779
|
-
require$$9.debugFn('notice', `ghsa: ${id} details ${details ? 'found' : 'missing'}`);
|
|
3573
|
+
require$$9.debugFn('notice', `pr: creating for ${ghsaId}`);
|
|
3574
|
+
const details = ghsaDetails.get(ghsaId);
|
|
3575
|
+
require$$9.debugFn('notice', `ghsa: ${ghsaId} details ${details ? 'found' : 'missing'}`);
|
|
3780
3576
|
const pushed =
|
|
3781
3577
|
// eslint-disable-next-line no-await-in-loop
|
|
3782
3578
|
(await utils.gitCreateBranch(branch, cwd)) && (
|
|
3783
3579
|
// eslint-disable-next-line no-await-in-loop
|
|
3784
3580
|
await utils.gitCheckoutBranch(branch, cwd)) && (
|
|
3785
3581
|
// eslint-disable-next-line no-await-in-loop
|
|
3786
|
-
await utils.gitCommit(
|
|
3582
|
+
await utils.gitCommit(getSocketFixCommitMessage(ghsaId, details), modifiedFiles, {
|
|
3787
3583
|
cwd,
|
|
3788
3584
|
email: fixEnv.gitEmail,
|
|
3789
3585
|
user: fixEnv.gitUser
|
|
@@ -3791,7 +3587,7 @@ async function coanaFix(fixConfig) {
|
|
|
3791
3587
|
// eslint-disable-next-line no-await-in-loop
|
|
3792
3588
|
await utils.gitPushBranch(branch, cwd));
|
|
3793
3589
|
if (!pushed) {
|
|
3794
|
-
logger.logger.warn(`Push failed for ${
|
|
3590
|
+
logger.logger.warn(`Push failed for ${ghsaId}, skipping PR creation.`);
|
|
3795
3591
|
// eslint-disable-next-line no-await-in-loop
|
|
3796
3592
|
await utils.gitResetAndClean(fixEnv.baseBranch, cwd);
|
|
3797
3593
|
// eslint-disable-next-line no-await-in-loop
|
|
@@ -3803,12 +3599,12 @@ async function coanaFix(fixConfig) {
|
|
|
3803
3599
|
|
|
3804
3600
|
// Set up git remote.
|
|
3805
3601
|
// eslint-disable-next-line no-await-in-loop
|
|
3806
|
-
await setGitRemoteGithubRepoUrl(fixEnv.repoInfo.owner, fixEnv.repoInfo.repo, fixEnv.githubToken, cwd);
|
|
3602
|
+
await utils.setGitRemoteGithubRepoUrl(fixEnv.repoInfo.owner, fixEnv.repoInfo.repo, fixEnv.githubToken, cwd);
|
|
3807
3603
|
|
|
3808
3604
|
// eslint-disable-next-line no-await-in-loop
|
|
3809
|
-
const prResponse = await
|
|
3605
|
+
const prResponse = await openSocketFixPr(fixEnv.repoInfo.owner, fixEnv.repoInfo.repo, branch,
|
|
3810
3606
|
// Single GHSA ID.
|
|
3811
|
-
[
|
|
3607
|
+
[ghsaId], {
|
|
3812
3608
|
baseBranch: fixEnv.baseBranch,
|
|
3813
3609
|
cwd,
|
|
3814
3610
|
ghsaDetails
|
|
@@ -3818,7 +3614,7 @@ async function coanaFix(fixConfig) {
|
|
|
3818
3614
|
data
|
|
3819
3615
|
} = prResponse;
|
|
3820
3616
|
const prRef = `PR #${data.number}`;
|
|
3821
|
-
logger.logger.success(`Opened ${prRef} for ${
|
|
3617
|
+
logger.logger.success(`Opened ${prRef} for ${ghsaId}.`);
|
|
3822
3618
|
if (autoMerge) {
|
|
3823
3619
|
logger.logger.indent();
|
|
3824
3620
|
spinner?.indent();
|
|
@@ -3826,7 +3622,7 @@ async function coanaFix(fixConfig) {
|
|
|
3826
3622
|
const {
|
|
3827
3623
|
details,
|
|
3828
3624
|
enabled
|
|
3829
|
-
} = await enablePrAutoMerge(data);
|
|
3625
|
+
} = await utils.enablePrAutoMerge(data);
|
|
3830
3626
|
if (enabled) {
|
|
3831
3627
|
logger.logger.info(`Auto-merge enabled for ${prRef}.`);
|
|
3832
3628
|
} else {
|
|
@@ -3844,7 +3640,7 @@ async function coanaFix(fixConfig) {
|
|
|
3844
3640
|
// eslint-disable-next-line no-await-in-loop
|
|
3845
3641
|
await utils.gitCheckoutBranch(fixEnv.baseBranch, cwd);
|
|
3846
3642
|
} catch (e) {
|
|
3847
|
-
logger.logger.warn(`Unexpected condition: Push failed for ${
|
|
3643
|
+
logger.logger.warn(`Unexpected condition: Push failed for ${ghsaId}, skipping PR creation.`);
|
|
3848
3644
|
require$$9.debugDir('inspect', {
|
|
3849
3645
|
error: e
|
|
3850
3646
|
});
|
|
@@ -3921,69 +3717,27 @@ const cmdFix = {
|
|
|
3921
3717
|
hidden: hidden$q,
|
|
3922
3718
|
run: run$I
|
|
3923
3719
|
};
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
ghsa: {
|
|
3946
|
-
type: 'string',
|
|
3947
|
-
default: [],
|
|
3948
|
-
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.`,
|
|
3949
|
-
isMultiple: true,
|
|
3950
|
-
hidden: true
|
|
3951
|
-
},
|
|
3952
|
-
limit: {
|
|
3953
|
-
type: 'number',
|
|
3954
|
-
default: DEFAULT_LIMIT,
|
|
3955
|
-
description: `The number of fixes to attempt at a time (default ${DEFAULT_LIMIT})`
|
|
3956
|
-
},
|
|
3957
|
-
maxSatisfying: {
|
|
3958
|
-
type: 'boolean',
|
|
3959
|
-
default: true,
|
|
3960
|
-
description: 'Use the maximum satisfying version for dependency updates',
|
|
3961
|
-
hidden: true
|
|
3962
|
-
},
|
|
3963
|
-
minSatisfying: {
|
|
3964
|
-
type: 'boolean',
|
|
3965
|
-
default: false,
|
|
3966
|
-
description: 'Constrain dependency updates to the minimum satisfying version',
|
|
3967
|
-
hidden: true
|
|
3968
|
-
},
|
|
3969
|
-
prCheck: {
|
|
3970
|
-
type: 'boolean',
|
|
3971
|
-
default: true,
|
|
3972
|
-
description: 'Check for an existing PR before attempting a fix',
|
|
3973
|
-
hidden: true
|
|
3974
|
-
},
|
|
3975
|
-
purl: {
|
|
3976
|
-
type: 'string',
|
|
3977
|
-
default: [],
|
|
3978
|
-
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`,
|
|
3979
|
-
isMultiple: true,
|
|
3980
|
-
shortFlag: 'p',
|
|
3981
|
-
hidden: true
|
|
3982
|
-
},
|
|
3983
|
-
rangeStyle: {
|
|
3984
|
-
type: 'string',
|
|
3985
|
-
default: 'preserve',
|
|
3986
|
-
description: `
|
|
3720
|
+
const generalFlags$2 = {
|
|
3721
|
+
autoMerge: {
|
|
3722
|
+
type: 'boolean',
|
|
3723
|
+
default: false,
|
|
3724
|
+
description: `Enable auto-merge for pull requests that Socket opens.\nSee ${vendor.terminalLinkExports('GitHub documentation', 'https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-auto-merge-for-pull-requests-in-your-repository')} for managing auto-merge for pull requests in your repository.`
|
|
3725
|
+
},
|
|
3726
|
+
id: {
|
|
3727
|
+
type: 'string',
|
|
3728
|
+
default: [],
|
|
3729
|
+
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`,
|
|
3730
|
+
isMultiple: true
|
|
3731
|
+
},
|
|
3732
|
+
limit: {
|
|
3733
|
+
type: 'number',
|
|
3734
|
+
default: DEFAULT_LIMIT,
|
|
3735
|
+
description: `The number of fixes to attempt at a time (default ${DEFAULT_LIMIT})`
|
|
3736
|
+
},
|
|
3737
|
+
rangeStyle: {
|
|
3738
|
+
type: 'string',
|
|
3739
|
+
default: 'preserve',
|
|
3740
|
+
description: `
|
|
3987
3741
|
Define how dependency version ranges are updated in package.json (default 'preserve').
|
|
3988
3742
|
Available styles:
|
|
3989
3743
|
* caret - Use ^ range for compatible updates (e.g. ^1.2.3)
|
|
@@ -3995,17 +3749,70 @@ Available styles:
|
|
|
3995
3749
|
* preserve - Retain the existing version range style as-is
|
|
3996
3750
|
* tilde - Use ~ range for patch/minor updates (e.g. ~1.2.3)
|
|
3997
3751
|
`.trim()
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
3752
|
+
}
|
|
3753
|
+
};
|
|
3754
|
+
const hiddenFlags = {
|
|
3755
|
+
autopilot: {
|
|
3756
|
+
type: 'boolean',
|
|
3757
|
+
default: false,
|
|
3758
|
+
description: `Shorthand for --auto-merge --test`,
|
|
3759
|
+
hidden: true
|
|
3760
|
+
},
|
|
3761
|
+
ghsa: {
|
|
3762
|
+
...generalFlags$2['id'],
|
|
3763
|
+
hidden: true
|
|
3764
|
+
},
|
|
3765
|
+
maxSatisfying: {
|
|
3766
|
+
type: 'boolean',
|
|
3767
|
+
default: true,
|
|
3768
|
+
description: 'Use the maximum satisfying version for dependency updates',
|
|
3769
|
+
hidden: true
|
|
3770
|
+
},
|
|
3771
|
+
minSatisfying: {
|
|
3772
|
+
type: 'boolean',
|
|
3773
|
+
default: false,
|
|
3774
|
+
description: 'Constrain dependency updates to the minimum satisfying version',
|
|
3775
|
+
hidden: true
|
|
3776
|
+
},
|
|
3777
|
+
prCheck: {
|
|
3778
|
+
type: 'boolean',
|
|
3779
|
+
default: true,
|
|
3780
|
+
description: 'Check for an existing PR before attempting a fix',
|
|
3781
|
+
hidden: true
|
|
3782
|
+
},
|
|
3783
|
+
purl: {
|
|
3784
|
+
type: 'string',
|
|
3785
|
+
default: [],
|
|
3786
|
+
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`,
|
|
3787
|
+
isMultiple: true,
|
|
3788
|
+
shortFlag: 'p',
|
|
3789
|
+
hidden: true
|
|
3790
|
+
},
|
|
3791
|
+
test: {
|
|
3792
|
+
type: 'boolean',
|
|
3793
|
+
default: false,
|
|
3794
|
+
description: 'Verify the fix by running unit tests',
|
|
3795
|
+
hidden: true
|
|
3796
|
+
},
|
|
3797
|
+
testScript: {
|
|
3798
|
+
type: 'string',
|
|
3799
|
+
default: 'test',
|
|
3800
|
+
description: "The test script to run for fix attempts (default 'test')",
|
|
3801
|
+
hidden: true
|
|
3802
|
+
}
|
|
3803
|
+
};
|
|
3804
|
+
async function run$I(argv, importMeta, {
|
|
3805
|
+
parentName
|
|
3806
|
+
}) {
|
|
3807
|
+
const config = {
|
|
3808
|
+
commandName: CMD_NAME$r,
|
|
3809
|
+
description: description$x,
|
|
3810
|
+
hidden: hidden$q,
|
|
3811
|
+
flags: {
|
|
3812
|
+
...flags.commonFlags,
|
|
3813
|
+
...flags.outputFlags,
|
|
3814
|
+
...generalFlags$2,
|
|
3815
|
+
...hiddenFlags
|
|
4009
3816
|
},
|
|
4010
3817
|
help: (command, config) => `
|
|
4011
3818
|
Usage
|
|
@@ -4093,7 +3900,7 @@ Available styles:
|
|
|
4093
3900
|
// We patched in this feature with `npx custompatch meow` at
|
|
4094
3901
|
// socket-cli/patches/meow#13.2.0.patch.
|
|
4095
3902
|
const unknownFlags = cli.unknownFlags ?? [];
|
|
4096
|
-
const ghsas = utils.cmdFlagValueToArray(cli.flags['ghsa']);
|
|
3903
|
+
const ghsas = arrays.arrayUnique([...utils.cmdFlagValueToArray(cli.flags['id']), ...utils.cmdFlagValueToArray(cli.flags['ghsa'])]);
|
|
4097
3904
|
const limit = Number(cli.flags['limit']) || DEFAULT_LIMIT;
|
|
4098
3905
|
const maxSatisfying = Boolean(cli.flags['maxSatisfying']);
|
|
4099
3906
|
const minSatisfying = Boolean(cli.flags['minSatisfying']) || !maxSatisfying;
|
|
@@ -6847,8 +6654,8 @@ function updatePkgJsonField(editablePkgJson, field, value) {
|
|
|
6847
6654
|
if (oldValue) {
|
|
6848
6655
|
// The field already exists so we simply update the field value.
|
|
6849
6656
|
if (field === PNPM) {
|
|
6850
|
-
const isPnpmObj = require$$
|
|
6851
|
-
if (require$$
|
|
6657
|
+
const isPnpmObj = require$$11.isObject(oldValue);
|
|
6658
|
+
if (require$$11.hasKeys(value)) {
|
|
6852
6659
|
editablePkgJson.update({
|
|
6853
6660
|
[field]: {
|
|
6854
6661
|
...(isPnpmObj ? oldValue : {}),
|
|
@@ -6860,7 +6667,7 @@ function updatePkgJsonField(editablePkgJson, field, value) {
|
|
|
6860
6667
|
});
|
|
6861
6668
|
} else {
|
|
6862
6669
|
// Properties with undefined values are deleted when saved as JSON.
|
|
6863
|
-
editablePkgJson.update(require$$
|
|
6670
|
+
editablePkgJson.update(require$$11.hasKeys(oldValue) ? {
|
|
6864
6671
|
[field]: {
|
|
6865
6672
|
...(isPnpmObj ? oldValue : {}),
|
|
6866
6673
|
overrides: undefined
|
|
@@ -6872,7 +6679,7 @@ function updatePkgJsonField(editablePkgJson, field, value) {
|
|
|
6872
6679
|
} else if (field === OVERRIDES || field === RESOLUTIONS) {
|
|
6873
6680
|
// Properties with undefined values are deleted when saved as JSON.
|
|
6874
6681
|
editablePkgJson.update({
|
|
6875
|
-
[field]: require$$
|
|
6682
|
+
[field]: require$$11.hasKeys(value) ? value : undefined
|
|
6876
6683
|
});
|
|
6877
6684
|
} else {
|
|
6878
6685
|
editablePkgJson.update({
|
|
@@ -6881,7 +6688,7 @@ function updatePkgJsonField(editablePkgJson, field, value) {
|
|
|
6881
6688
|
}
|
|
6882
6689
|
return;
|
|
6883
6690
|
}
|
|
6884
|
-
if ((field === OVERRIDES || field === PNPM || field === RESOLUTIONS) && !require$$
|
|
6691
|
+
if ((field === OVERRIDES || field === PNPM || field === RESOLUTIONS) && !require$$11.hasKeys(value)) {
|
|
6885
6692
|
return;
|
|
6886
6693
|
}
|
|
6887
6694
|
// Since the field doesn't exist we want to insert it into the package.json
|
|
@@ -7013,7 +6820,7 @@ async function addOverrides(pkgEnvDetails, pkgPath, options) {
|
|
|
7013
6820
|
let loggedAddingText = false;
|
|
7014
6821
|
|
|
7015
6822
|
// Chunk package names to process them in parallel 3 at a time.
|
|
7016
|
-
await require$$
|
|
6823
|
+
await require$$12.pEach(manifestEntries, async ({
|
|
7017
6824
|
1: data
|
|
7018
6825
|
}) => {
|
|
7019
6826
|
const {
|
|
@@ -7027,11 +6834,11 @@ async function addOverrides(pkgEnvDetails, pkgPath, options) {
|
|
|
7027
6834
|
for (const {
|
|
7028
6835
|
1: depObj
|
|
7029
6836
|
} of depEntries) {
|
|
7030
|
-
const sockSpec = require$$
|
|
6837
|
+
const sockSpec = require$$11.hasOwn(depObj, sockRegPkgName) ? depObj[sockRegPkgName] : undefined;
|
|
7031
6838
|
if (sockSpec) {
|
|
7032
6839
|
depAliasMap.set(sockRegPkgName, sockSpec);
|
|
7033
6840
|
}
|
|
7034
|
-
const origSpec = require$$
|
|
6841
|
+
const origSpec = require$$11.hasOwn(depObj, origPkgName) ? depObj[origPkgName] : undefined;
|
|
7035
6842
|
if (origSpec) {
|
|
7036
6843
|
let thisSpec = origSpec;
|
|
7037
6844
|
// Add package aliases for direct dependencies to avoid npm EOVERRIDE
|
|
@@ -7067,11 +6874,11 @@ async function addOverrides(pkgEnvDetails, pkgPath, options) {
|
|
|
7067
6874
|
npmExecPath
|
|
7068
6875
|
});
|
|
7069
6876
|
// Chunk package names to process them in parallel 3 at a time.
|
|
7070
|
-
await require$$
|
|
6877
|
+
await require$$12.pEach(overridesDataObjects, async ({
|
|
7071
6878
|
overrides,
|
|
7072
6879
|
type
|
|
7073
6880
|
}) => {
|
|
7074
|
-
const overrideExists = require$$
|
|
6881
|
+
const overrideExists = require$$11.hasOwn(overrides, origPkgName);
|
|
7075
6882
|
if (overrideExists || thingScanner(pkgEnvDetails, thingToScan, origPkgName, lockName)) {
|
|
7076
6883
|
const oldSpec = overrideExists ? overrides[origPkgName] : undefined;
|
|
7077
6884
|
const origDepAlias = depAliasMap.get(origPkgName);
|
|
@@ -7125,7 +6932,7 @@ async function addOverrides(pkgEnvDetails, pkgPath, options) {
|
|
|
7125
6932
|
});
|
|
7126
6933
|
if (isWorkspace) {
|
|
7127
6934
|
// Chunk package names to process them in parallel 3 at a time.
|
|
7128
|
-
await require$$
|
|
6935
|
+
await require$$12.pEach(workspacePkgJsonPaths, async workspacePkgJsonPath => {
|
|
7129
6936
|
const otherState = await addOverrides(pkgEnvDetails, path.dirname(workspacePkgJsonPath), {
|
|
7130
6937
|
logger,
|
|
7131
6938
|
pin,
|
|
@@ -7148,7 +6955,7 @@ async function addOverrides(pkgEnvDetails, pkgPath, options) {
|
|
|
7148
6955
|
overrides,
|
|
7149
6956
|
type
|
|
7150
6957
|
} of overridesDataObjects) {
|
|
7151
|
-
updateManifest(type, pkgEnvDetails.editablePkgJson, require$$
|
|
6958
|
+
updateManifest(type, pkgEnvDetails.editablePkgJson, require$$11.toSortedObject(overrides));
|
|
7152
6959
|
}
|
|
7153
6960
|
}
|
|
7154
6961
|
await pkgEnvDetails.editablePkgJson.save();
|
|
@@ -8866,6 +8673,30 @@ const cmdPackage = {
|
|
|
8866
8673
|
}
|
|
8867
8674
|
};
|
|
8868
8675
|
|
|
8676
|
+
const PatchRecordSchema = vendor.object({
|
|
8677
|
+
exportedAt: vendor.string(),
|
|
8678
|
+
files: vendor.record(vendor.string(),
|
|
8679
|
+
// File path
|
|
8680
|
+
vendor.object({
|
|
8681
|
+
beforeHash: vendor.string(),
|
|
8682
|
+
afterHash: vendor.string()
|
|
8683
|
+
})),
|
|
8684
|
+
vulnerabilities: vendor.record(vendor.string(),
|
|
8685
|
+
// Vulnerability ID like "GHSA-jrhj-2j3q-xf3v"
|
|
8686
|
+
vendor.object({
|
|
8687
|
+
cves: vendor.array(vendor.string()),
|
|
8688
|
+
summary: vendor.string(),
|
|
8689
|
+
severity: vendor.string(),
|
|
8690
|
+
description: vendor.string(),
|
|
8691
|
+
patchExplanation: vendor.string()
|
|
8692
|
+
}))
|
|
8693
|
+
});
|
|
8694
|
+
const PatchManifestSchema = vendor.object({
|
|
8695
|
+
patches: vendor.record(
|
|
8696
|
+
// Package identifier like "npm:simplehttpserver@0.0.6".
|
|
8697
|
+
vendor.string(), PatchRecordSchema)
|
|
8698
|
+
});
|
|
8699
|
+
|
|
8869
8700
|
async function outputPatchResult(result, outputKind) {
|
|
8870
8701
|
if (!result.ok) {
|
|
8871
8702
|
process.exitCode = result.code ?? 1;
|
|
@@ -8893,21 +8724,220 @@ async function outputPatchResult(result, outputKind) {
|
|
|
8893
8724
|
logger.logger.success('Patch command completed!');
|
|
8894
8725
|
}
|
|
8895
8726
|
|
|
8727
|
+
async function applyNPMPatches(patches, dryRun, socketDir, packages) {
|
|
8728
|
+
const patchLookup = new Map();
|
|
8729
|
+
for (const patchInfo of patches) {
|
|
8730
|
+
const {
|
|
8731
|
+
purl
|
|
8732
|
+
} = patchInfo;
|
|
8733
|
+
const fullName = purl.namespace ? `@${purl.namespace}/${purl.name}` : purl.name;
|
|
8734
|
+
const lookupKey = `${fullName}@${purl.version}`;
|
|
8735
|
+
patchLookup.set(lookupKey, patchInfo);
|
|
8736
|
+
}
|
|
8737
|
+
const nodeModulesFolders = await findNodeModulesFolders(process.cwd());
|
|
8738
|
+
logger.logger.log(`Found ${nodeModulesFolders.length} node_modules folders`);
|
|
8739
|
+
for (const nodeModulesPath of nodeModulesFolders) {
|
|
8740
|
+
try {
|
|
8741
|
+
// eslint-disable-next-line no-await-in-loop
|
|
8742
|
+
const entries = await fs$1.promises.readdir(nodeModulesPath);
|
|
8743
|
+
for (const entry of entries) {
|
|
8744
|
+
const entryPath = path.join(nodeModulesPath, entry);
|
|
8745
|
+
if (entry.startsWith('@')) {
|
|
8746
|
+
try {
|
|
8747
|
+
// eslint-disable-next-line no-await-in-loop
|
|
8748
|
+
const scopedEntries = await fs$1.promises.readdir(entryPath);
|
|
8749
|
+
for (const scopedEntry of scopedEntries) {
|
|
8750
|
+
const packagePath = path.join(entryPath, scopedEntry);
|
|
8751
|
+
// eslint-disable-next-line no-await-in-loop
|
|
8752
|
+
const pkg = await readPackageJson(packagePath);
|
|
8753
|
+
if (pkg) {
|
|
8754
|
+
// Skip if specific packages requested and this isn't one of them
|
|
8755
|
+
if (packages.length > 0 && !packages.includes(pkg.name)) {
|
|
8756
|
+
continue;
|
|
8757
|
+
}
|
|
8758
|
+
const lookupKey = `${pkg.name}@${pkg.version}`;
|
|
8759
|
+
const patchInfo = patchLookup.get(lookupKey);
|
|
8760
|
+
if (patchInfo) {
|
|
8761
|
+
logger.logger.log(`Found match: ${pkg.name}@${pkg.version} at ${packagePath}`);
|
|
8762
|
+
logger.logger.log(` Patch key: ${patchInfo.key}`);
|
|
8763
|
+
logger.logger.log(` Processing files:`);
|
|
8764
|
+
for (const [fileName, fileInfo] of Object.entries(patchInfo.patch.files)) {
|
|
8765
|
+
// eslint-disable-next-line no-await-in-loop
|
|
8766
|
+
await processFilePatch(packagePath, fileName, fileInfo, dryRun, socketDir);
|
|
8767
|
+
}
|
|
8768
|
+
}
|
|
8769
|
+
}
|
|
8770
|
+
}
|
|
8771
|
+
} catch {
|
|
8772
|
+
// Ignore errors reading scoped packages
|
|
8773
|
+
}
|
|
8774
|
+
} else {
|
|
8775
|
+
// eslint-disable-next-line no-await-in-loop
|
|
8776
|
+
const pkg = await readPackageJson(entryPath);
|
|
8777
|
+
if (pkg) {
|
|
8778
|
+
// Skip if specific packages requested and this isn't one of them
|
|
8779
|
+
if (packages.length > 0 && !packages.includes(pkg.name)) {
|
|
8780
|
+
continue;
|
|
8781
|
+
}
|
|
8782
|
+
const lookupKey = `${pkg.name}@${pkg.version}`;
|
|
8783
|
+
const patchInfo = patchLookup.get(lookupKey);
|
|
8784
|
+
if (patchInfo) {
|
|
8785
|
+
logger.logger.log(`Found match: ${pkg.name}@${pkg.version} at ${entryPath}`);
|
|
8786
|
+
logger.logger.log(` Patch key: ${patchInfo.key}`);
|
|
8787
|
+
logger.logger.log(` Processing files:`);
|
|
8788
|
+
for (const [fileName, fileInfo] of Object.entries(patchInfo.patch.files)) {
|
|
8789
|
+
// eslint-disable-next-line no-await-in-loop
|
|
8790
|
+
await processFilePatch(entryPath, fileName, fileInfo, dryRun, socketDir);
|
|
8791
|
+
}
|
|
8792
|
+
}
|
|
8793
|
+
}
|
|
8794
|
+
}
|
|
8795
|
+
}
|
|
8796
|
+
} catch (error) {
|
|
8797
|
+
logger.logger.error(`Error processing ${nodeModulesPath}:`, error);
|
|
8798
|
+
}
|
|
8799
|
+
}
|
|
8800
|
+
}
|
|
8801
|
+
async function computeSHA256(filePath) {
|
|
8802
|
+
try {
|
|
8803
|
+
const content = await fs$1.promises.readFile(filePath);
|
|
8804
|
+
const hash = require$$0$1.createHash('sha256');
|
|
8805
|
+
hash.update(content);
|
|
8806
|
+
return hash.digest('hex');
|
|
8807
|
+
} catch {
|
|
8808
|
+
return null;
|
|
8809
|
+
}
|
|
8810
|
+
}
|
|
8811
|
+
async function findNodeModulesFolders(rootDir) {
|
|
8812
|
+
const nodeModulesPaths = [];
|
|
8813
|
+
async function searchDir(dir) {
|
|
8814
|
+
try {
|
|
8815
|
+
const entries = await fs$1.promises.readdir(dir);
|
|
8816
|
+
for (const entry of entries) {
|
|
8817
|
+
if (entry.startsWith('.') || entry === 'dist' || entry === 'build') {
|
|
8818
|
+
continue;
|
|
8819
|
+
}
|
|
8820
|
+
const fullPath = path.join(dir, entry);
|
|
8821
|
+
// eslint-disable-next-line no-await-in-loop
|
|
8822
|
+
const stats = await fs$1.promises.stat(fullPath);
|
|
8823
|
+
if (stats.isDirectory()) {
|
|
8824
|
+
if (entry === 'node_modules') {
|
|
8825
|
+
nodeModulesPaths.push(fullPath);
|
|
8826
|
+
} else {
|
|
8827
|
+
// eslint-disable-next-line no-await-in-loop
|
|
8828
|
+
await searchDir(fullPath);
|
|
8829
|
+
}
|
|
8830
|
+
}
|
|
8831
|
+
}
|
|
8832
|
+
} catch (error) {
|
|
8833
|
+
// Ignore permission errors or missing directories
|
|
8834
|
+
}
|
|
8835
|
+
}
|
|
8836
|
+
await searchDir(rootDir);
|
|
8837
|
+
return nodeModulesPaths;
|
|
8838
|
+
}
|
|
8839
|
+
function parsePURL(purlString) {
|
|
8840
|
+
const [ecosystem, rest] = purlString.split(':', 2);
|
|
8841
|
+
const [nameAndNamespace, version] = (rest ?? '').split('@', 2);
|
|
8842
|
+
let namespace;
|
|
8843
|
+
let name;
|
|
8844
|
+
if (ecosystem === 'npm' && nameAndNamespace?.startsWith('@')) {
|
|
8845
|
+
const parts = nameAndNamespace.split('/');
|
|
8846
|
+
namespace = parts[0]?.substring(1);
|
|
8847
|
+
name = parts.slice(1).join('/');
|
|
8848
|
+
} else {
|
|
8849
|
+
name = nameAndNamespace ?? '';
|
|
8850
|
+
}
|
|
8851
|
+
return {
|
|
8852
|
+
type: ecosystem ?? 'unknown',
|
|
8853
|
+
namespace: namespace ?? '',
|
|
8854
|
+
name: name ?? '',
|
|
8855
|
+
version: version ?? '0.0.0'
|
|
8856
|
+
};
|
|
8857
|
+
}
|
|
8858
|
+
async function processFilePatch(packagePath, fileName, fileInfo, dryRun, socketDir) {
|
|
8859
|
+
const filePath = path.join(packagePath, fileName);
|
|
8860
|
+
if (!fs$1.existsSync(filePath)) {
|
|
8861
|
+
logger.logger.log(`File not found: ${fileName}`);
|
|
8862
|
+
return;
|
|
8863
|
+
}
|
|
8864
|
+
const currentHash = await computeSHA256(filePath);
|
|
8865
|
+
if (!currentHash) {
|
|
8866
|
+
logger.logger.log(`Failed to compute hash for: ${fileName}`);
|
|
8867
|
+
return;
|
|
8868
|
+
}
|
|
8869
|
+
if (currentHash === fileInfo.beforeHash) {
|
|
8870
|
+
logger.logger.success(`File matches expected hash: ${fileName}`);
|
|
8871
|
+
logger.logger.log(`Current hash: ${currentHash}`);
|
|
8872
|
+
logger.logger.log(`Ready to patch to: ${fileInfo.afterHash}`);
|
|
8873
|
+
{
|
|
8874
|
+
const blobPath = path.join(socketDir, 'blobs', fileInfo.afterHash);
|
|
8875
|
+
if (!fs$1.existsSync(blobPath)) {
|
|
8876
|
+
logger.logger.fail(`Error: Patch file not found at ${blobPath}`);
|
|
8877
|
+
return;
|
|
8878
|
+
}
|
|
8879
|
+
try {
|
|
8880
|
+
await fs$1.promises.copyFile(blobPath, filePath);
|
|
8881
|
+
logger.logger.success(`Patch applied successfully`);
|
|
8882
|
+
} catch (error) {
|
|
8883
|
+
logger.logger.log(`Error applying patch: ${error}`);
|
|
8884
|
+
}
|
|
8885
|
+
}
|
|
8886
|
+
} else if (currentHash === fileInfo.afterHash) {
|
|
8887
|
+
logger.logger.success(`File already patched: ${fileName}`);
|
|
8888
|
+
logger.logger.log(`Current hash: ${currentHash}`);
|
|
8889
|
+
} else {
|
|
8890
|
+
logger.logger.fail(`File hash mismatch: ${fileName}`);
|
|
8891
|
+
logger.logger.log(`Expected: ${fileInfo.beforeHash}`);
|
|
8892
|
+
logger.logger.log(`Current: ${currentHash}`);
|
|
8893
|
+
logger.logger.log(`Target: ${fileInfo.afterHash}`);
|
|
8894
|
+
}
|
|
8895
|
+
}
|
|
8896
|
+
async function readPackageJson(packagePath) {
|
|
8897
|
+
const pkgJsonPath = path.join(packagePath, 'package.json');
|
|
8898
|
+
const pkg = await fs$2.readJson(pkgJsonPath, {
|
|
8899
|
+
throws: false
|
|
8900
|
+
});
|
|
8901
|
+
if (pkg) {
|
|
8902
|
+
return {
|
|
8903
|
+
name: pkg.name || '',
|
|
8904
|
+
version: pkg.version || ''
|
|
8905
|
+
};
|
|
8906
|
+
}
|
|
8907
|
+
return null;
|
|
8908
|
+
}
|
|
8896
8909
|
async function handlePatch({
|
|
8910
|
+
cwd,
|
|
8897
8911
|
outputKind,
|
|
8898
8912
|
packages,
|
|
8899
8913
|
spinner
|
|
8900
8914
|
}) {
|
|
8901
|
-
|
|
8915
|
+
const dryRun = false; // TODO: Add dryRun support via config
|
|
8916
|
+
|
|
8902
8917
|
try {
|
|
8903
|
-
|
|
8904
|
-
|
|
8905
|
-
|
|
8906
|
-
|
|
8907
|
-
|
|
8908
|
-
|
|
8918
|
+
const dotSocketDirPath = path.join(cwd, '.socket');
|
|
8919
|
+
const manifestPath = path.join(dotSocketDirPath, 'manifest.json');
|
|
8920
|
+
|
|
8921
|
+
// Read the manifest file
|
|
8922
|
+
const manifestContent = await fs$1.promises.readFile(manifestPath, 'utf-8');
|
|
8923
|
+
const manifestData = JSON.parse(manifestContent);
|
|
8924
|
+
|
|
8925
|
+
// Validate the schema
|
|
8926
|
+
const validated = PatchManifestSchema.parse(manifestData);
|
|
8927
|
+
|
|
8928
|
+
// Parse PURLs and group by ecosystem
|
|
8929
|
+
const patchesByEcosystem = {};
|
|
8930
|
+
for (const [key, patch] of Object.entries(validated.patches)) {
|
|
8931
|
+
const purl = parsePURL(key);
|
|
8932
|
+
if (!patchesByEcosystem[purl.type]) {
|
|
8933
|
+
patchesByEcosystem[purl.type] = [];
|
|
8909
8934
|
}
|
|
8910
|
-
|
|
8935
|
+
patchesByEcosystem[purl.type]?.push({
|
|
8936
|
+
key,
|
|
8937
|
+
purl,
|
|
8938
|
+
patch
|
|
8939
|
+
});
|
|
8940
|
+
}
|
|
8911
8941
|
spinner.stop();
|
|
8912
8942
|
logger.logger.log('');
|
|
8913
8943
|
if (packages.length > 0) {
|
|
@@ -8916,14 +8946,32 @@ async function handlePatch({
|
|
|
8916
8946
|
logger.logger.info('Scanning all dependencies for available patches');
|
|
8917
8947
|
}
|
|
8918
8948
|
logger.logger.log('');
|
|
8949
|
+
if (patchesByEcosystem['npm']) {
|
|
8950
|
+
await applyNPMPatches(patchesByEcosystem['npm'], dryRun, dotSocketDirPath, packages);
|
|
8951
|
+
}
|
|
8952
|
+
const result = {
|
|
8953
|
+
ok: true,
|
|
8954
|
+
data: {
|
|
8955
|
+
patchedPackages: packages.length > 0 ? packages : ['patched successfully']
|
|
8956
|
+
}
|
|
8957
|
+
};
|
|
8919
8958
|
await outputPatchResult(result, outputKind);
|
|
8920
8959
|
} catch (e) {
|
|
8921
8960
|
spinner.stop();
|
|
8961
|
+
let message = 'Failed to apply patches';
|
|
8962
|
+
let cause = e?.message || 'Unknown error';
|
|
8963
|
+
if (e instanceof SyntaxError) {
|
|
8964
|
+
message = 'Invalid JSON in manifest.json';
|
|
8965
|
+
cause = e.message;
|
|
8966
|
+
} else if (e instanceof Error && 'issues' in e) {
|
|
8967
|
+
message = 'Schema validation failed';
|
|
8968
|
+
cause = String(e);
|
|
8969
|
+
}
|
|
8922
8970
|
const result = {
|
|
8923
8971
|
ok: false,
|
|
8924
8972
|
code: 1,
|
|
8925
|
-
message
|
|
8926
|
-
cause
|
|
8973
|
+
message,
|
|
8974
|
+
cause
|
|
8927
8975
|
};
|
|
8928
8976
|
await outputPatchResult(result, outputKind);
|
|
8929
8977
|
}
|
|
@@ -8997,11 +9045,21 @@ async function run$k(argv, importMeta, {
|
|
|
8997
9045
|
// Note: path.resolve vs .join:
|
|
8998
9046
|
// If given path is absolute then cwd should not affect it.
|
|
8999
9047
|
cwd = path.resolve(process.cwd(), cwd);
|
|
9048
|
+
const dotSocketDirPath = path.join(cwd, '.socket');
|
|
9049
|
+
if (!fs$1.existsSync(dotSocketDirPath)) {
|
|
9050
|
+
logger.logger.error('Error: No .socket directory found in current directory');
|
|
9051
|
+
return;
|
|
9052
|
+
}
|
|
9053
|
+
const manifestPath = path.join(dotSocketDirPath, 'manifest.json');
|
|
9054
|
+
if (!fs$1.existsSync(manifestPath)) {
|
|
9055
|
+
logger.logger.error('Error: No manifest.json found in .socket directory');
|
|
9056
|
+
}
|
|
9000
9057
|
const {
|
|
9001
9058
|
spinner
|
|
9002
9059
|
} = constants;
|
|
9003
|
-
const packages =
|
|
9060
|
+
const packages = utils.cmdFlagValueToArray(cli.flags['package']);
|
|
9004
9061
|
await handlePatch({
|
|
9062
|
+
cwd,
|
|
9005
9063
|
outputKind,
|
|
9006
9064
|
packages,
|
|
9007
9065
|
spinner
|
|
@@ -12266,8 +12324,14 @@ async function handleScanReach({
|
|
|
12266
12324
|
reachabilityOptions,
|
|
12267
12325
|
targets
|
|
12268
12326
|
}) {
|
|
12327
|
+
const {
|
|
12328
|
+
spinner
|
|
12329
|
+
} = constants;
|
|
12330
|
+
|
|
12269
12331
|
// Get supported file names
|
|
12270
|
-
const supportedFilesCResult = await fetchSupportedScanFileNames(
|
|
12332
|
+
const supportedFilesCResult = await fetchSupportedScanFileNames({
|
|
12333
|
+
spinner
|
|
12334
|
+
});
|
|
12271
12335
|
if (!supportedFilesCResult.ok) {
|
|
12272
12336
|
await outputScanReach(supportedFilesCResult, {
|
|
12273
12337
|
cwd,
|
|
@@ -12275,9 +12339,6 @@ async function handleScanReach({
|
|
|
12275
12339
|
});
|
|
12276
12340
|
return;
|
|
12277
12341
|
}
|
|
12278
|
-
const {
|
|
12279
|
-
spinner
|
|
12280
|
-
} = constants;
|
|
12281
12342
|
spinner.start('Searching for local manifest files to include in reachability analysis...');
|
|
12282
12343
|
const supportedFiles = supportedFilesCResult.data;
|
|
12283
12344
|
const packagePaths = await utils.getPackageFilesForScan(targets, supportedFiles, {
|
|
@@ -14203,5 +14264,5 @@ void (async () => {
|
|
|
14203
14264
|
await utils.captureException(e);
|
|
14204
14265
|
}
|
|
14205
14266
|
})();
|
|
14206
|
-
//# debugId=
|
|
14267
|
+
//# debugId=41b305c0-5c97-4685-a7f1-88a4cbb5e41c
|
|
14207
14268
|
//# sourceMappingURL=cli.js.map
|