pruny 1.7.0 → 1.8.0

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 (2) hide show
  1. package/dist/index.js +47 -33
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -9351,8 +9351,15 @@ async function scanUnusedExports(config) {
9351
9351
  let allExportsCount = 0;
9352
9352
  const inlineExportRegex = /^export\s+(?:async\s+)?(?:const|let|var|function|type|interface|enum|class)\s+([a-zA-Z0-9_$]+)/gm;
9353
9353
  const blockExportRegex = /^export\s*\{([^}]+)\}/gm;
9354
+ console.log(`\uD83D\uDCDD Scanning ${allFiles.length} files for exports...`);
9355
+ let processedFiles = 0;
9354
9356
  for (const file of allFiles) {
9355
9357
  try {
9358
+ processedFiles++;
9359
+ if (processedFiles % 50 === 0) {
9360
+ const percent = Math.round(processedFiles / allFiles.length * 100);
9361
+ process.stdout.write(`\r Progress: ${processedFiles}/${allFiles.length} files (${percent}%)...`);
9362
+ }
9356
9363
  const content = readFileSync3(join3(cwd, file), "utf-8");
9357
9364
  totalContents.set(file, content);
9358
9365
  const lines = content.split(`
@@ -9381,6 +9388,9 @@ async function scanUnusedExports(config) {
9381
9388
  }
9382
9389
  } catch {}
9383
9390
  }
9391
+ if (processedFiles > 0) {
9392
+ process.stdout.write("\r" + " ".repeat(60) + "\r");
9393
+ }
9384
9394
  function addExport(file, name, line) {
9385
9395
  if (name && !IGNORED_EXPORT_NAMES.has(name)) {
9386
9396
  if (!exportMap.has(file))
@@ -9391,6 +9401,7 @@ async function scanUnusedExports(config) {
9391
9401
  return false;
9392
9402
  }
9393
9403
  const unusedExports = [];
9404
+ console.log(`\uD83D\uDD0D Checking usage of ${allExportsCount} exports...`);
9394
9405
  for (const [file, exports] of exportMap.entries()) {
9395
9406
  for (const exp of exports) {
9396
9407
  let isUsed = false;
@@ -9403,13 +9414,16 @@ async function scanUnusedExports(config) {
9403
9414
  if (i === exp.line - 1)
9404
9415
  continue;
9405
9416
  const line = lines[i];
9406
- if (isCommentOrString(line))
9417
+ const trimmed = line.trim();
9418
+ if (trimmed.startsWith("//") || trimmed.startsWith("/*") || trimmed.startsWith("*"))
9407
9419
  continue;
9408
- const cleanLine = stripStringsAndComments(line);
9409
9420
  const referenceRegex = new RegExp(`\\b${exp.name}\\b`);
9410
- if (referenceRegex.test(cleanLine)) {
9411
- usedInternally = true;
9412
- break;
9421
+ if (referenceRegex.test(line)) {
9422
+ const codePattern = new RegExp(`\\b${exp.name}\\s*[({.,;)]|\\b${exp.name}\\s*\\)|\\s+${exp.name}\\b`);
9423
+ if (codePattern.test(line)) {
9424
+ usedInternally = true;
9425
+ break;
9426
+ }
9413
9427
  }
9414
9428
  }
9415
9429
  }
@@ -9417,23 +9431,41 @@ async function scanUnusedExports(config) {
9417
9431
  if (file === otherFile)
9418
9432
  continue;
9419
9433
  const jsxPattern = new RegExp(`<${exp.name}[\\s/>]`);
9434
+ if (jsxPattern.test(content)) {
9435
+ isUsed = true;
9436
+ break;
9437
+ }
9420
9438
  const importPattern = new RegExp(`import.*\\b${exp.name}\\b.*from`);
9421
- const destructurePattern = new RegExp(`\\{[^}]*\\b${exp.name}\\b[^}]*\\}`);
9422
- if (jsxPattern.test(content) || importPattern.test(content)) {
9439
+ if (importPattern.test(content)) {
9423
9440
  isUsed = true;
9424
9441
  break;
9425
9442
  }
9426
- if (!isUsed) {
9443
+ const wordBoundaryPattern = new RegExp(`\\b${exp.name}\\b`);
9444
+ if (wordBoundaryPattern.test(content)) {
9427
9445
  const lines = content.split(`
9428
9446
  `);
9447
+ let inMultilineComment = false;
9448
+ let inTemplate = false;
9429
9449
  for (const line of lines) {
9430
- if (isCommentOrString(line))
9450
+ const trimmed = line.trim();
9451
+ if (trimmed.includes("/*"))
9452
+ inMultilineComment = true;
9453
+ if (trimmed.includes("*/")) {
9454
+ inMultilineComment = false;
9431
9455
  continue;
9432
- const cleanLine = stripStringsAndComments(line);
9433
- const codeUsagePattern = new RegExp(`\\b${exp.name}\\s*[({]|\\b${exp.name}\\s*\\.|\\b${exp.name}\\s*,|\\b${exp.name}\\s*;|\\b${exp.name}\\s*\\)`);
9434
- if (codeUsagePattern.test(cleanLine)) {
9435
- isUsed = true;
9436
- break;
9456
+ }
9457
+ if (inMultilineComment)
9458
+ continue;
9459
+ if (trimmed.startsWith("//"))
9460
+ continue;
9461
+ if (trimmed.includes("{/*") || trimmed.includes("*/}"))
9462
+ continue;
9463
+ if (wordBoundaryPattern.test(line)) {
9464
+ const codePattern = new RegExp(`\\b${exp.name}\\s*[({.,;)]|\\b${exp.name}\\s*\\)|\\s+${exp.name}\\b`);
9465
+ if (codePattern.test(line)) {
9466
+ isUsed = true;
9467
+ break;
9468
+ }
9437
9469
  }
9438
9470
  }
9439
9471
  }
@@ -9452,24 +9484,6 @@ async function scanUnusedExports(config) {
9452
9484
  exports: unusedExports
9453
9485
  };
9454
9486
  }
9455
- function isCommentOrString(line) {
9456
- const trimmed = line.trim();
9457
- if (trimmed.startsWith("//"))
9458
- return true;
9459
- if (trimmed.startsWith("/*") || trimmed.startsWith("*"))
9460
- return true;
9461
- if (trimmed.includes("{/*") || trimmed.includes("*/}"))
9462
- return true;
9463
- return false;
9464
- }
9465
- function stripStringsAndComments(line) {
9466
- let result = line;
9467
- result = result.replace(/\/\/.*$/g, "");
9468
- result = result.replace(/'([^'\\]|\\.)*'/g, "''");
9469
- result = result.replace(/"([^"\\]|\\.)*"/g, '""');
9470
- result = result.replace(/`([^`\\]|\\.)*`/g, "``");
9471
- return result;
9472
- }
9473
9487
 
9474
9488
  // src/scanner.ts
9475
9489
  function extractRoutePath(filePath) {
@@ -9686,7 +9700,7 @@ var DEFAULT_CONFIG = {
9686
9700
  dir: "./",
9687
9701
  ignore: {
9688
9702
  routes: [],
9689
- folders: ["node_modules", ".next", "dist", ".git", "coverage", ".turbo"],
9703
+ folders: ["node_modules", ".next", "dist", ".git", "coverage", ".turbo", "build", "out", ".cache", ".vercel", ".contentlayer", ".docusaurus", "target", "vendor"],
9690
9704
  files: [
9691
9705
  "*.test.ts",
9692
9706
  "*.spec.ts",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pruny",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "Find and remove unused Next.js API routes & Nest.js Controllers",
5
5
  "type": "module",
6
6
  "files": [