@cencori/scan 0.4.4 → 0.4.5
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 +106 -67
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +107 -68
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { program } from "commander";
|
|
5
5
|
import chalk from "chalk";
|
|
6
6
|
import ora from "ora";
|
|
7
|
-
import { confirm, password } from "@inquirer/prompts";
|
|
7
|
+
import { confirm, password, select } from "@inquirer/prompts";
|
|
8
8
|
|
|
9
9
|
// src/scanner/index.ts
|
|
10
10
|
import * as fs from "fs";
|
|
@@ -883,24 +883,6 @@ Generate a secure fix.`
|
|
|
883
883
|
}
|
|
884
884
|
return results;
|
|
885
885
|
}
|
|
886
|
-
async function applyFixes(fixes, fileContents) {
|
|
887
|
-
for (const fix of fixes) {
|
|
888
|
-
if (fix.fixedCode === fix.originalCode) {
|
|
889
|
-
continue;
|
|
890
|
-
}
|
|
891
|
-
const content = fileContents.get(fix.issue.file);
|
|
892
|
-
if (!content) {
|
|
893
|
-
continue;
|
|
894
|
-
}
|
|
895
|
-
const newContent = content.replace(fix.originalCode, fix.fixedCode);
|
|
896
|
-
if (newContent !== content) {
|
|
897
|
-
const filePath = path2.resolve(fix.issue.file);
|
|
898
|
-
fs2.writeFileSync(filePath, newContent, "utf-8");
|
|
899
|
-
fix.applied = true;
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
return fixes;
|
|
903
|
-
}
|
|
904
886
|
|
|
905
887
|
// src/telemetry.ts
|
|
906
888
|
var TELEMETRY_URL = "https://api.cencori.com/v1/telemetry/scan";
|
|
@@ -1153,7 +1135,7 @@ No commits found in the specified period.
|
|
|
1153
1135
|
// src/cli.ts
|
|
1154
1136
|
import * as fs3 from "fs";
|
|
1155
1137
|
import * as path3 from "path";
|
|
1156
|
-
var VERSION = "0.4.
|
|
1138
|
+
var VERSION = "0.4.5";
|
|
1157
1139
|
var scoreStyles = {
|
|
1158
1140
|
A: { color: chalk.green },
|
|
1159
1141
|
B: { color: chalk.blue },
|
|
@@ -1388,57 +1370,108 @@ async function handleAutoFix(result, targetPath) {
|
|
|
1388
1370
|
fileContents
|
|
1389
1371
|
);
|
|
1390
1372
|
fixSpinner.succeed(`Generated ${fixes.length} fixes`);
|
|
1391
|
-
const applySpinner = ora({
|
|
1392
|
-
text: "Applying fixes...",
|
|
1393
|
-
color: "cyan"
|
|
1394
|
-
}).start();
|
|
1395
|
-
const appliedFixes = await applyFixes(fixes, fileContents);
|
|
1396
|
-
const appliedCount = appliedFixes.filter((f) => f.applied).length;
|
|
1397
|
-
applySpinner.succeed(`Applied ${appliedCount}/${fixes.length} fixes`);
|
|
1398
1373
|
console.log();
|
|
1399
|
-
const
|
|
1400
|
-
const
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1374
|
+
const acceptedFixes = [];
|
|
1375
|
+
const skippedFixes = [];
|
|
1376
|
+
let applyAll = false;
|
|
1377
|
+
let skipRest = false;
|
|
1378
|
+
for (let i = 0; i < fixes.length; i++) {
|
|
1379
|
+
const fix = fixes[i];
|
|
1380
|
+
if (skipRest) {
|
|
1381
|
+
skippedFixes.push(fix);
|
|
1382
|
+
continue;
|
|
1406
1383
|
}
|
|
1384
|
+
if (applyAll) {
|
|
1385
|
+
acceptedFixes.push(fix);
|
|
1386
|
+
continue;
|
|
1387
|
+
}
|
|
1388
|
+
console.log(chalk.cyan(` \u2500\u2500\u2500 Fix ${i + 1}/${fixes.length}: ${fix.issue.file}:${fix.issue.line} \u2500\u2500\u2500`));
|
|
1389
|
+
console.log(chalk.gray(` Issue: ${fix.issue.name} (${fix.issue.severity})`));
|
|
1407
1390
|
console.log();
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
console.log(`
|
|
1391
|
+
const origLines = fix.originalCode.split("\n");
|
|
1392
|
+
console.log(chalk.red(" - Original:"));
|
|
1393
|
+
origLines.slice(0, 8).forEach((line) => console.log(chalk.red(` ${line}`)));
|
|
1394
|
+
if (origLines.length > 8) {
|
|
1395
|
+
console.log(chalk.gray(` ... (${origLines.length - 8} more lines)`));
|
|
1396
|
+
}
|
|
1397
|
+
console.log();
|
|
1398
|
+
const fixLines = fix.fixedCode.split("\n");
|
|
1399
|
+
console.log(chalk.green(" + Suggested fix:"));
|
|
1400
|
+
fixLines.slice(0, 8).forEach((line) => console.log(chalk.green(` ${line}`)));
|
|
1401
|
+
if (fixLines.length > 8) {
|
|
1402
|
+
console.log(chalk.gray(` ... (${fixLines.length - 8} more lines)`));
|
|
1403
|
+
}
|
|
1411
1404
|
console.log();
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1405
|
+
console.log(chalk.gray(` Explanation: ${fix.explanation}`));
|
|
1406
|
+
console.log();
|
|
1407
|
+
const action = await select({
|
|
1408
|
+
message: "Apply this fix?",
|
|
1409
|
+
choices: [
|
|
1410
|
+
{ name: "Yes - apply this fix", value: "y" },
|
|
1411
|
+
{ name: "No - skip this fix", value: "n" },
|
|
1412
|
+
{ name: "All - apply all remaining fixes", value: "a" },
|
|
1413
|
+
{ name: "Skip rest - save remaining to file", value: "s" },
|
|
1414
|
+
{ name: "Quit - stop reviewing", value: "q" }
|
|
1415
|
+
]
|
|
1416
|
+
});
|
|
1417
|
+
if (action === "y") {
|
|
1418
|
+
acceptedFixes.push(fix);
|
|
1419
|
+
console.log(chalk.green(" \u2714 Fix accepted"));
|
|
1420
|
+
} else if (action === "n") {
|
|
1421
|
+
skippedFixes.push(fix);
|
|
1422
|
+
console.log(chalk.yellow(" \u2298 Fix skipped"));
|
|
1423
|
+
} else if (action === "a") {
|
|
1424
|
+
applyAll = true;
|
|
1425
|
+
acceptedFixes.push(fix);
|
|
1426
|
+
for (let j = i + 1; j < fixes.length; j++) {
|
|
1427
|
+
acceptedFixes.push(fixes[j]);
|
|
1422
1428
|
}
|
|
1423
|
-
console.log();
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
+
console.log(chalk.green(` \u2714 Applying all ${fixes.length - i} remaining fixes`));
|
|
1430
|
+
break;
|
|
1431
|
+
} else if (action === "s") {
|
|
1432
|
+
skipRest = true;
|
|
1433
|
+
skippedFixes.push(fix);
|
|
1434
|
+
for (let j = i + 1; j < fixes.length; j++) {
|
|
1435
|
+
skippedFixes.push(fixes[j]);
|
|
1429
1436
|
}
|
|
1430
|
-
console.log(chalk.
|
|
1431
|
-
|
|
1437
|
+
console.log(chalk.yellow(` \u2298 Skipping ${fixes.length - i} remaining fixes`));
|
|
1438
|
+
break;
|
|
1439
|
+
} else if (action === "q") {
|
|
1440
|
+
skippedFixes.push(fix);
|
|
1441
|
+
for (let j = i + 1; j < fixes.length; j++) {
|
|
1442
|
+
skippedFixes.push(fixes[j]);
|
|
1443
|
+
}
|
|
1444
|
+
console.log(chalk.gray(" Stopped reviewing"));
|
|
1445
|
+
break;
|
|
1432
1446
|
}
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1447
|
+
console.log();
|
|
1448
|
+
}
|
|
1449
|
+
if (acceptedFixes.length > 0) {
|
|
1450
|
+
console.log();
|
|
1451
|
+
const applySpinner = ora({
|
|
1452
|
+
text: `Applying ${acceptedFixes.length} fixes...`,
|
|
1453
|
+
color: "cyan"
|
|
1454
|
+
}).start();
|
|
1455
|
+
let appliedCount = 0;
|
|
1456
|
+
for (const fix of acceptedFixes) {
|
|
1457
|
+
const content = fileContents.get(fix.issue.file);
|
|
1458
|
+
if (!content) continue;
|
|
1459
|
+
const newContent = content.replace(fix.originalCode, fix.fixedCode);
|
|
1460
|
+
if (newContent !== content) {
|
|
1461
|
+
const filePath = path3.resolve(targetPath, fix.issue.file);
|
|
1462
|
+
fs3.writeFileSync(filePath, newContent, "utf-8");
|
|
1463
|
+
fileContents.set(fix.issue.file, newContent);
|
|
1464
|
+
appliedCount++;
|
|
1465
|
+
}
|
|
1436
1466
|
}
|
|
1467
|
+
applySpinner.succeed(`Applied ${appliedCount}/${acceptedFixes.length} fixes to your codebase`);
|
|
1468
|
+
}
|
|
1469
|
+
if (skippedFixes.length > 0) {
|
|
1437
1470
|
const fixesFile = ".cencori-fixes.json";
|
|
1438
1471
|
const fixesData = {
|
|
1439
1472
|
generated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1440
|
-
total_fixes:
|
|
1441
|
-
fixes:
|
|
1473
|
+
total_fixes: skippedFixes.length,
|
|
1474
|
+
fixes: skippedFixes.map((f) => ({
|
|
1442
1475
|
file: f.issue.file,
|
|
1443
1476
|
line: f.issue.line,
|
|
1444
1477
|
issue_type: f.issue.type,
|
|
@@ -1450,16 +1483,22 @@ async function handleAutoFix(result, targetPath) {
|
|
|
1450
1483
|
}))
|
|
1451
1484
|
};
|
|
1452
1485
|
fs3.writeFileSync(fixesFile, JSON.stringify(fixesData, null, 2));
|
|
1453
|
-
console.log(chalk.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
1454
|
-
console.log();
|
|
1455
|
-
console.log(` ${chalk.bold("Next steps:")}`);
|
|
1456
|
-
console.log(chalk.cyan(` 1. Review fixes in ${chalk.bold(fixesFile)}`));
|
|
1457
|
-
console.log(chalk.cyan(` 2. Apply fixes manually to your codebase`));
|
|
1458
|
-
console.log(chalk.cyan(` 3. Run ${chalk.bold("npx @cencori/scan")} again to verify`));
|
|
1459
1486
|
console.log();
|
|
1487
|
+
console.log(chalk.yellow(` ${skippedFixes.length} skipped fixes saved to ${chalk.bold(fixesFile)}`));
|
|
1460
1488
|
}
|
|
1461
|
-
|
|
1462
|
-
|
|
1489
|
+
console.log();
|
|
1490
|
+
console.log(chalk.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
1491
|
+
console.log();
|
|
1492
|
+
console.log(` ${chalk.bold("Summary:")}`);
|
|
1493
|
+
if (acceptedFixes.length > 0) {
|
|
1494
|
+
console.log(chalk.green(` \u2714 ${acceptedFixes.length} fixes applied`));
|
|
1495
|
+
}
|
|
1496
|
+
if (skippedFixes.length > 0) {
|
|
1497
|
+
console.log(chalk.yellow(` \u2298 ${skippedFixes.length} fixes skipped (saved to .cencori-fixes.json)`));
|
|
1498
|
+
}
|
|
1499
|
+
if (acceptedFixes.length > 0) {
|
|
1500
|
+
console.log();
|
|
1501
|
+
console.log(chalk.cyan(` Run ${chalk.bold("npx @cencori/scan")} again to verify your fixes!`));
|
|
1463
1502
|
}
|
|
1464
1503
|
console.log();
|
|
1465
1504
|
} catch (error) {
|