pruny 1.13.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 +55 -82
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -10081,21 +10081,21 @@ program2.action(async (options) => {
10081
10081
  `));
10082
10082
  try {
10083
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
+ };
10084
10091
  if (options.filter) {
10085
10092
  const filter2 = options.filter.toLowerCase();
10086
10093
  console.log(source_default.blue(`
10087
10094
  \uD83D\uDD0D Filtering results by "${filter2}"...
10088
10095
  `));
10089
- const getAppName2 = (filePath) => {
10090
- if (filePath.startsWith("apps/"))
10091
- return filePath.split("/").slice(0, 2).join("/");
10092
- if (filePath.startsWith("packages/"))
10093
- return filePath.split("/").slice(0, 2).join("/");
10094
- return "Root";
10095
- };
10096
10096
  const matchesFilter = (path2) => {
10097
10097
  const lowerPath = path2.toLowerCase();
10098
- const appName = getAppName2(path2).toLowerCase();
10098
+ const appName = getAppName(path2).toLowerCase();
10099
10099
  if (appName.includes(filter2))
10100
10100
  return true;
10101
10101
  const segments = lowerPath.split("/");
@@ -10186,24 +10186,61 @@ program2.action(async (options) => {
10186
10186
  }
10187
10187
  if (unusedRoutes.length === 0 && partiallyUnusedRoutes.length === 0 && (!result.publicAssets || result.publicAssets.unused === 0)) {
10188
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.
10189
10233
  `));
10190
10234
  }
10191
10235
  console.log(source_default.bold(`\uD83D\uDCCA Summary Report
10192
10236
  `));
10193
10237
  const summary = [];
10194
- const getAppName = (filePath) => {
10195
- if (filePath.startsWith("apps/"))
10196
- return filePath.split("/").slice(0, 2).join("/");
10197
- if (filePath.startsWith("packages/"))
10198
- return filePath.split("/").slice(0, 2).join("/");
10199
- return "Root";
10200
- };
10201
10238
  const groupedRoutes = new Map;
10202
10239
  for (const route of result.routes) {
10203
- const appName = getAppName(route.filePath);
10204
- const key = `${appName}::${route.type}`;
10240
+ const keyAppName = getAppName(route.filePath);
10241
+ const key = `${keyAppName}::${route.type}`;
10205
10242
  if (!groupedRoutes.has(key)) {
10206
- groupedRoutes.set(key, { type: route.type, app: appName, routes: [] });
10243
+ groupedRoutes.set(key, { type: route.type, app: keyAppName, routes: [] });
10207
10244
  }
10208
10245
  groupedRoutes.get(key).routes.push(route);
10209
10246
  }
@@ -10253,70 +10290,6 @@ program2.action(async (options) => {
10253
10290
  });
10254
10291
  }
10255
10292
  console.table(summary);
10256
- console.log("");
10257
- if (options.verbose) {
10258
- const used = result.routes.filter((r) => r.used);
10259
- if (used.length > 0) {
10260
- console.log(source_default.green.bold(`✅ Used routes (References):
10261
- `));
10262
- for (const route of used) {
10263
- console.log(source_default.green(` ${route.path}`));
10264
- if (route.references.length > 0) {
10265
- for (const ref of route.references.slice(0, 3)) {
10266
- console.log(source_default.dim(` ← ${ref}`));
10267
- }
10268
- if (route.references.length > 3) {
10269
- console.log(source_default.dim(` ... and ${route.references.length - 3} more`));
10270
- }
10271
- }
10272
- }
10273
- console.log("");
10274
- }
10275
- }
10276
- if (options.fix) {
10277
- if (unusedRoutes.length > 0) {
10278
- console.log(source_default.yellow.bold(`\uD83D\uDDD1️ Deleting unused routes...
10279
- `));
10280
- for (const route of unusedRoutes) {
10281
- const routeDir = dirname3(join8(config.dir, route.filePath));
10282
- try {
10283
- rmSync(routeDir, { recursive: true, force: true });
10284
- console.log(source_default.red(` Deleted: ${route.filePath}`));
10285
- } catch (_err) {
10286
- console.log(source_default.yellow(` Failed to delete: ${route.filePath}`));
10287
- }
10288
- }
10289
- }
10290
- if (result.unusedExports && result.unusedExports.exports.length > 0) {
10291
- console.log(source_default.yellow.bold(`\uD83D\uDD27 Fixing unused exports (removing "export" keyword)...
10292
- `));
10293
- const exportsByFile = new Map;
10294
- for (const exp of result.unusedExports.exports) {
10295
- if (!exportsByFile.has(exp.file)) {
10296
- exportsByFile.set(exp.file, []);
10297
- }
10298
- exportsByFile.get(exp.file).push(exp);
10299
- }
10300
- let fixedCount = 0;
10301
- for (const [file, exports] of exportsByFile.entries()) {
10302
- const sortedExports = exports.sort((a, b) => b.line - a.line);
10303
- for (const exp of sortedExports) {
10304
- if (removeExportFromLine(config.dir, exp)) {
10305
- console.log(source_default.green(` Fixed: ${exp.name} in ${exp.file}`));
10306
- fixedCount++;
10307
- }
10308
- }
10309
- }
10310
- if (fixedCount > 0) {
10311
- console.log(source_default.green(`
10312
- ✅ Removed "export" from ${fixedCount} item(s).
10313
- `));
10314
- }
10315
- }
10316
- } else if (unusedRoutes.length > 0 || result.unusedExports && result.unusedExports.exports.length > 0) {
10317
- console.log(source_default.dim(`\uD83D\uDCA1 Run with --fix to automatically clean up unused routes and exports.
10318
- `));
10319
- }
10320
10293
  } catch (_err) {
10321
10294
  console.error(source_default.red("Error scanning:"), _err);
10322
10295
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pruny",
3
- "version": "1.13.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": [