pruny 1.12.0 → 1.14.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 +57 -83
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -9230,7 +9230,8 @@ async function scanUnusedFiles(config) {
9230
9230
  "**/*.spec.{ts,tsx,js,jsx}",
9231
9231
  "scripts/**/*.{ts,js}",
9232
9232
  "cypress/**/*.{ts,js,tsx}",
9233
- "public/sw.js"
9233
+ "**/public/sw.js",
9234
+ "**/sw.{js,ts}"
9234
9235
  ];
9235
9236
  for (const file of allFiles) {
9236
9237
  const isEntry = entryPatterns.some((pattern) => {
@@ -10080,21 +10081,21 @@ program2.action(async (options) => {
10080
10081
  `));
10081
10082
  try {
10082
10083
  let result = await scan(config);
10084
+ const getAppName = (filePath) => {
10085
+ if (filePath.startsWith("apps/"))
10086
+ return filePath.split("/").slice(0, 2).join("/");
10087
+ if (filePath.startsWith("packages/"))
10088
+ return filePath.split("/").slice(0, 2).join("/");
10089
+ return "Root";
10090
+ };
10083
10091
  if (options.filter) {
10084
10092
  const filter2 = options.filter.toLowerCase();
10085
10093
  console.log(source_default.blue(`
10086
10094
  \uD83D\uDD0D Filtering results by "${filter2}"...
10087
10095
  `));
10088
- const getAppName2 = (filePath) => {
10089
- if (filePath.startsWith("apps/"))
10090
- return filePath.split("/").slice(0, 2).join("/");
10091
- if (filePath.startsWith("packages/"))
10092
- return filePath.split("/").slice(0, 2).join("/");
10093
- return "Root";
10094
- };
10095
10096
  const matchesFilter = (path2) => {
10096
10097
  const lowerPath = path2.toLowerCase();
10097
- const appName = getAppName2(path2).toLowerCase();
10098
+ const appName = getAppName(path2).toLowerCase();
10098
10099
  if (appName.includes(filter2))
10099
10100
  return true;
10100
10101
  const segments = lowerPath.split("/");
@@ -10185,24 +10186,61 @@ program2.action(async (options) => {
10185
10186
  }
10186
10187
  if (unusedRoutes.length === 0 && partiallyUnusedRoutes.length === 0 && (!result.publicAssets || result.publicAssets.unused === 0)) {
10187
10188
  console.log(source_default.green(`✅ Everything is used! Clean as a whistle.
10189
+ `));
10190
+ }
10191
+ if (options.fix) {
10192
+ if (unusedRoutes.length > 0) {
10193
+ console.log(source_default.yellow.bold(`\uD83D\uDDD1️ Deleting unused routes...
10194
+ `));
10195
+ for (const route of unusedRoutes) {
10196
+ const routeDir = dirname3(join8(config.dir, route.filePath));
10197
+ try {
10198
+ rmSync(routeDir, { recursive: true, force: true });
10199
+ console.log(source_default.red(` Deleted: ${route.filePath}`));
10200
+ } catch (_err) {
10201
+ console.log(source_default.yellow(` Failed to delete: ${route.filePath}`));
10202
+ }
10203
+ }
10204
+ }
10205
+ if (result.unusedExports && result.unusedExports.exports.length > 0) {
10206
+ console.log(source_default.yellow.bold(`\uD83D\uDD27 Fixing unused exports (removing "export" keyword)...
10207
+ `));
10208
+ const exportsByFile = new Map;
10209
+ for (const exp of result.unusedExports.exports) {
10210
+ if (!exportsByFile.has(exp.file)) {
10211
+ exportsByFile.set(exp.file, []);
10212
+ }
10213
+ exportsByFile.get(exp.file).push(exp);
10214
+ }
10215
+ let fixedCount = 0;
10216
+ for (const [file, exports] of exportsByFile.entries()) {
10217
+ const sortedExports = exports.sort((a, b) => b.line - a.line);
10218
+ for (const exp of sortedExports) {
10219
+ if (removeExportFromLine(config.dir, exp)) {
10220
+ console.log(source_default.green(` Fixed: ${exp.name} in ${exp.file}`));
10221
+ fixedCount++;
10222
+ }
10223
+ }
10224
+ }
10225
+ if (fixedCount > 0) {
10226
+ console.log(source_default.green(`
10227
+ ✅ Removed "export" from ${fixedCount} item(s).
10228
+ `));
10229
+ }
10230
+ }
10231
+ } else if (unusedRoutes.length > 0 || result.unusedExports && result.unusedExports.exports.length > 0) {
10232
+ console.log(source_default.dim(`\uD83D\uDCA1 Run with --fix to automatically clean up unused routes and exports.
10188
10233
  `));
10189
10234
  }
10190
10235
  console.log(source_default.bold(`\uD83D\uDCCA Summary Report
10191
10236
  `));
10192
10237
  const summary = [];
10193
- const getAppName = (filePath) => {
10194
- if (filePath.startsWith("apps/"))
10195
- return filePath.split("/").slice(0, 2).join("/");
10196
- if (filePath.startsWith("packages/"))
10197
- return filePath.split("/").slice(0, 2).join("/");
10198
- return "Root";
10199
- };
10200
10238
  const groupedRoutes = new Map;
10201
10239
  for (const route of result.routes) {
10202
- const appName = getAppName(route.filePath);
10203
- const key = `${appName}::${route.type}`;
10240
+ const keyAppName = getAppName(route.filePath);
10241
+ const key = `${keyAppName}::${route.type}`;
10204
10242
  if (!groupedRoutes.has(key)) {
10205
- groupedRoutes.set(key, { type: route.type, app: appName, routes: [] });
10243
+ groupedRoutes.set(key, { type: route.type, app: keyAppName, routes: [] });
10206
10244
  }
10207
10245
  groupedRoutes.get(key).routes.push(route);
10208
10246
  }
@@ -10252,70 +10290,6 @@ program2.action(async (options) => {
10252
10290
  });
10253
10291
  }
10254
10292
  console.table(summary);
10255
- console.log("");
10256
- if (options.verbose) {
10257
- const used = result.routes.filter((r) => r.used);
10258
- if (used.length > 0) {
10259
- console.log(source_default.green.bold(`✅ Used routes (References):
10260
- `));
10261
- for (const route of used) {
10262
- console.log(source_default.green(` ${route.path}`));
10263
- if (route.references.length > 0) {
10264
- for (const ref of route.references.slice(0, 3)) {
10265
- console.log(source_default.dim(` ← ${ref}`));
10266
- }
10267
- if (route.references.length > 3) {
10268
- console.log(source_default.dim(` ... and ${route.references.length - 3} more`));
10269
- }
10270
- }
10271
- }
10272
- console.log("");
10273
- }
10274
- }
10275
- if (options.fix) {
10276
- if (unusedRoutes.length > 0) {
10277
- console.log(source_default.yellow.bold(`\uD83D\uDDD1️ Deleting unused routes...
10278
- `));
10279
- for (const route of unusedRoutes) {
10280
- const routeDir = dirname3(join8(config.dir, route.filePath));
10281
- try {
10282
- rmSync(routeDir, { recursive: true, force: true });
10283
- console.log(source_default.red(` Deleted: ${route.filePath}`));
10284
- } catch (_err) {
10285
- console.log(source_default.yellow(` Failed to delete: ${route.filePath}`));
10286
- }
10287
- }
10288
- }
10289
- if (result.unusedExports && result.unusedExports.exports.length > 0) {
10290
- console.log(source_default.yellow.bold(`\uD83D\uDD27 Fixing unused exports (removing "export" keyword)...
10291
- `));
10292
- const exportsByFile = new Map;
10293
- for (const exp of result.unusedExports.exports) {
10294
- if (!exportsByFile.has(exp.file)) {
10295
- exportsByFile.set(exp.file, []);
10296
- }
10297
- exportsByFile.get(exp.file).push(exp);
10298
- }
10299
- let fixedCount = 0;
10300
- for (const [file, exports] of exportsByFile.entries()) {
10301
- const sortedExports = exports.sort((a, b) => b.line - a.line);
10302
- for (const exp of sortedExports) {
10303
- if (removeExportFromLine(config.dir, exp)) {
10304
- console.log(source_default.green(` Fixed: ${exp.name} in ${exp.file}`));
10305
- fixedCount++;
10306
- }
10307
- }
10308
- }
10309
- if (fixedCount > 0) {
10310
- console.log(source_default.green(`
10311
- ✅ Removed "export" from ${fixedCount} item(s).
10312
- `));
10313
- }
10314
- }
10315
- } else if (unusedRoutes.length > 0 || result.unusedExports && result.unusedExports.exports.length > 0) {
10316
- console.log(source_default.dim(`\uD83D\uDCA1 Run with --fix to automatically clean up unused routes and exports.
10317
- `));
10318
- }
10319
10293
  } catch (_err) {
10320
10294
  console.error(source_default.red("Error scanning:"), _err);
10321
10295
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pruny",
3
- "version": "1.12.0",
3
+ "version": "1.14.0",
4
4
  "description": "Find and remove unused Next.js API routes & Nest.js Controllers",
5
5
  "type": "module",
6
6
  "files": [