node-janitor 1.0.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 (54) hide show
  1. package/README.md +259 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +337 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/core/cleaner.d.ts +10 -0
  7. package/dist/core/cleaner.d.ts.map +1 -0
  8. package/dist/core/cleaner.js +107 -0
  9. package/dist/core/cleaner.js.map +1 -0
  10. package/dist/core/deep-cleaner.d.ts +10 -0
  11. package/dist/core/deep-cleaner.d.ts.map +1 -0
  12. package/dist/core/deep-cleaner.js +228 -0
  13. package/dist/core/deep-cleaner.js.map +1 -0
  14. package/dist/core/scanner.d.ts +35 -0
  15. package/dist/core/scanner.d.ts.map +1 -0
  16. package/dist/core/scanner.js +172 -0
  17. package/dist/core/scanner.js.map +1 -0
  18. package/dist/index.d.ts +3 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +5 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/types/index.d.ts +183 -0
  23. package/dist/types/index.d.ts.map +1 -0
  24. package/dist/types/index.js +5 -0
  25. package/dist/types/index.js.map +1 -0
  26. package/dist/ui/progress.d.ts +20 -0
  27. package/dist/ui/progress.d.ts.map +1 -0
  28. package/dist/ui/progress.js +29 -0
  29. package/dist/ui/progress.js.map +1 -0
  30. package/dist/ui/prompts.d.ts +40 -0
  31. package/dist/ui/prompts.d.ts.map +1 -0
  32. package/dist/ui/prompts.js +106 -0
  33. package/dist/ui/prompts.js.map +1 -0
  34. package/dist/ui/spinner.d.ts +15 -0
  35. package/dist/ui/spinner.d.ts.map +1 -0
  36. package/dist/ui/spinner.js +30 -0
  37. package/dist/ui/spinner.js.map +1 -0
  38. package/dist/ui/table.d.ts +38 -0
  39. package/dist/ui/table.d.ts.map +1 -0
  40. package/dist/ui/table.js +117 -0
  41. package/dist/ui/table.js.map +1 -0
  42. package/dist/utils/formatter.d.ts +40 -0
  43. package/dist/utils/formatter.d.ts.map +1 -0
  44. package/dist/utils/formatter.js +103 -0
  45. package/dist/utils/formatter.js.map +1 -0
  46. package/dist/utils/fs-utils.d.ts +53 -0
  47. package/dist/utils/fs-utils.d.ts.map +1 -0
  48. package/dist/utils/fs-utils.js +155 -0
  49. package/dist/utils/fs-utils.js.map +1 -0
  50. package/dist/utils/logger.d.ts +26 -0
  51. package/dist/utils/logger.d.ts.map +1 -0
  52. package/dist/utils/logger.js +77 -0
  53. package/dist/utils/logger.js.map +1 -0
  54. package/package.json +72 -0
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Type definitions for node-janitor
3
+ */
4
+ export interface NodeModulesInfo {
5
+ /** Full path to node_modules folder */
6
+ path: string;
7
+ /** Path to parent project folder */
8
+ projectPath: string;
9
+ /** Size in bytes */
10
+ size: number;
11
+ /** Last modified date */
12
+ lastModified: Date;
13
+ /** Number of packages inside */
14
+ packageCount: number;
15
+ /** Whether package-lock.json exists */
16
+ hasPackageLock: boolean;
17
+ /** Whether yarn.lock exists */
18
+ hasYarnLock: boolean;
19
+ /** Whether pnpm-lock.yaml exists */
20
+ hasPnpmLock: boolean;
21
+ /** Age in days */
22
+ ageDays: number;
23
+ /** Git status if available */
24
+ gitStatus?: GitStatus;
25
+ }
26
+ export interface GitStatus {
27
+ /** Whether the folder is in a git repo */
28
+ isGitRepo: boolean;
29
+ /** Whether there are uncommitted changes */
30
+ isDirty: boolean;
31
+ /** Current branch name */
32
+ branch?: string;
33
+ }
34
+ export interface ScanOptions {
35
+ /** Directory to scan */
36
+ path: string;
37
+ /** Maximum depth to scan */
38
+ depth?: number;
39
+ /** Skip size calculation for speed */
40
+ quick?: boolean;
41
+ /** Patterns to exclude */
42
+ excludePatterns?: string[];
43
+ /** Include patterns */
44
+ includePatterns?: string[];
45
+ }
46
+ export interface CleanOptions {
47
+ /** Delete folders older than (e.g., "30d", "3m", "1y") */
48
+ olderThan?: string;
49
+ /** Delete folders in age range (e.g., "30d-90d") */
50
+ between?: string;
51
+ /** Only delete folders larger than this */
52
+ minSize?: string;
53
+ /** Only delete folders smaller than this */
54
+ maxSize?: string;
55
+ /** Preview only, don't delete */
56
+ dryRun?: boolean;
57
+ /** Use native OS commands for faster deletion */
58
+ fast?: boolean;
59
+ /** Number of parallel deletions */
60
+ parallel?: number;
61
+ /** Create backup before deletion */
62
+ backup?: boolean;
63
+ /** Only delete if lockfile exists */
64
+ lockCheck?: boolean;
65
+ /** Skip folders with uncommitted git changes */
66
+ skipDirtyGit?: boolean;
67
+ }
68
+ export interface DeepCleanOptions {
69
+ /** Preview only, don't delete */
70
+ dryRun?: boolean;
71
+ /** Show detailed output */
72
+ verbose?: boolean;
73
+ }
74
+ export interface CleanResult {
75
+ /** Number of folders deleted */
76
+ deletedCount: number;
77
+ /** Total bytes freed */
78
+ freedBytes: number;
79
+ /** List of deleted paths */
80
+ deletedPaths: string[];
81
+ /** List of failed deletions */
82
+ errors: CleanError[];
83
+ /** Backup file path if created */
84
+ backupPath?: string;
85
+ }
86
+ export interface DeepCleanResult {
87
+ /** Number of files deleted */
88
+ deletedFileCount: number;
89
+ /** Number of folders processed */
90
+ processedFolders: number;
91
+ /** Total bytes freed */
92
+ freedBytes: number;
93
+ /** Detailed file list if verbose */
94
+ deletedFiles?: string[];
95
+ }
96
+ export interface CleanError {
97
+ /** Path that failed to delete */
98
+ path: string;
99
+ /** Error message */
100
+ message: string;
101
+ }
102
+ export interface BackupInfo {
103
+ /** Backup file name */
104
+ filename: string;
105
+ /** Full path to backup file */
106
+ path: string;
107
+ /** Timestamp of backup */
108
+ timestamp: Date;
109
+ /** Number of folders backed up */
110
+ folderCount: number;
111
+ /** Total size of backed up folders */
112
+ totalSize: number;
113
+ }
114
+ export interface BackupData {
115
+ /** Backup creation timestamp */
116
+ timestamp: string;
117
+ /** Tool version */
118
+ version: string;
119
+ /** List of backed up folders */
120
+ folders: BackupFolderInfo[];
121
+ /** Total size in bytes */
122
+ totalSize: number;
123
+ /** Total folder count */
124
+ totalFolders: number;
125
+ }
126
+ export interface BackupFolderInfo {
127
+ /** Path to node_modules */
128
+ path: string;
129
+ /** Size in bytes */
130
+ size: number;
131
+ /** Path to package.json */
132
+ packageJsonPath: string;
133
+ /** Lockfile type if exists */
134
+ lockfileType?: 'npm' | 'yarn' | 'pnpm';
135
+ }
136
+ export interface ReportData {
137
+ /** Scan timestamp */
138
+ timestamp: Date;
139
+ /** Total folders found */
140
+ totalFolders: number;
141
+ /** Total size in bytes */
142
+ totalSize: number;
143
+ /** Breakdown by age */
144
+ byAge: {
145
+ recent: NodeModulesInfo[];
146
+ medium: NodeModulesInfo[];
147
+ old: NodeModulesInfo[];
148
+ };
149
+ /** Top 10 largest folders */
150
+ topBySize: NodeModulesInfo[];
151
+ /** Top 10 oldest folders */
152
+ topByAge: NodeModulesInfo[];
153
+ }
154
+ export interface Config {
155
+ /** Paths to always exclude */
156
+ exclude?: string[];
157
+ /** Glob patterns to exclude */
158
+ excludePattern?: string[];
159
+ /** Default older than value */
160
+ defaultOlderThan?: string;
161
+ /** Default scan path */
162
+ defaultPath?: string;
163
+ /** Default scan depth */
164
+ defaultDepth?: number;
165
+ /** Language preference */
166
+ lang?: string;
167
+ }
168
+ export type OutputFormat = 'table' | 'json' | 'csv';
169
+ export interface GlobalOptions {
170
+ /** Verbose output */
171
+ verbose?: boolean;
172
+ /** Debug mode */
173
+ debug?: boolean;
174
+ /** Output format */
175
+ format?: OutputFormat;
176
+ /** Language */
177
+ lang?: string;
178
+ /** Config file path */
179
+ config?: string;
180
+ /** Log file path */
181
+ logFile?: string;
182
+ }
183
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Type definitions for node-janitor
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,20 @@
1
+ import cliProgress from 'cli-progress';
2
+ /**
3
+ * Create a progress bar for scanning/deleting operations
4
+ */
5
+ export declare function createProgressBar(total: number, label?: string): cliProgress.SingleBar;
6
+ /**
7
+ * Update progress bar with status
8
+ */
9
+ export declare function updateProgress(bar: cliProgress.SingleBar, value: number, status: string): void;
10
+ /**
11
+ * Stop and clean up progress bar
12
+ */
13
+ export declare function stopProgress(bar: cliProgress.SingleBar): void;
14
+ declare const _default: {
15
+ createProgressBar: typeof createProgressBar;
16
+ updateProgress: typeof updateProgress;
17
+ stopProgress: typeof stopProgress;
18
+ };
19
+ export default _default;
20
+ //# sourceMappingURL=progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/ui/progress.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,cAAc,CAAC;AAGvC;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAa,GAAG,WAAW,CAAC,SAAS,CAU1F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC1B,GAAG,EAAE,WAAW,CAAC,SAAS,EAC1B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACf,IAAI,CAEN;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,WAAW,CAAC,SAAS,GAAG,IAAI,CAE7D;;;;;;AAED,wBAAmE"}
@@ -0,0 +1,29 @@
1
+ import cliProgress from 'cli-progress';
2
+ import chalk from 'chalk';
3
+ /**
4
+ * Create a progress bar for scanning/deleting operations
5
+ */
6
+ export function createProgressBar(total, label = 'Progress') {
7
+ const bar = new cliProgress.SingleBar({
8
+ format: `${chalk.cyan(label)} |${chalk.cyan('{bar}')}| {percentage}% | {value}/{total} | {status}`,
9
+ barCompleteChar: '█',
10
+ barIncompleteChar: '░',
11
+ hideCursor: true,
12
+ });
13
+ bar.start(total, 0, { status: 'Starting...' });
14
+ return bar;
15
+ }
16
+ /**
17
+ * Update progress bar with status
18
+ */
19
+ export function updateProgress(bar, value, status) {
20
+ bar.update(value, { status });
21
+ }
22
+ /**
23
+ * Stop and clean up progress bar
24
+ */
25
+ export function stopProgress(bar) {
26
+ bar.stop();
27
+ }
28
+ export default { createProgressBar, updateProgress, stopProgress };
29
+ //# sourceMappingURL=progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/ui/progress.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,cAAc,CAAC;AACvC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAa,EAAE,KAAK,GAAG,UAAU;IAC/D,MAAM,GAAG,GAAG,IAAI,WAAW,CAAC,SAAS,CAAC;QAClC,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,8CAA8C;QAClG,eAAe,EAAE,GAAG;QACpB,iBAAiB,EAAE,GAAG;QACtB,UAAU,EAAE,IAAI;KACnB,CAAC,CAAC;IAEH,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;IAC/C,OAAO,GAAG,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAC1B,GAA0B,EAC1B,KAAa,EACb,MAAc;IAEd,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,GAA0B;IACnD,GAAG,CAAC,IAAI,EAAE,CAAC;AACf,CAAC;AAED,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC"}
@@ -0,0 +1,40 @@
1
+ import type { NodeModulesInfo } from '../types/index.js';
2
+ /**
3
+ * Prompt for scan path
4
+ */
5
+ export declare function promptPath(defaultPath: string): Promise<string>;
6
+ /**
7
+ * Prompt for age filter
8
+ */
9
+ export declare function promptAge(): Promise<string | undefined>;
10
+ /**
11
+ * Prompt for confirmation
12
+ */
13
+ export declare function promptConfirm(message: string, defaultValue?: boolean): Promise<boolean>;
14
+ /**
15
+ * Prompt to view list
16
+ */
17
+ export declare function promptViewList(): Promise<boolean>;
18
+ /**
19
+ * Prompt to delete
20
+ */
21
+ export declare function promptDelete(count: number, size: number): Promise<boolean>;
22
+ /**
23
+ * Prompt for folder selection
24
+ */
25
+ export declare function promptSelectFolders(folders: NodeModulesInfo[]): Promise<NodeModulesInfo[]>;
26
+ /**
27
+ * Prompt for action selection
28
+ */
29
+ export declare function promptAction(): Promise<'scan' | 'clean' | 'deep-clean' | 'report' | 'exit'>;
30
+ declare const _default: {
31
+ promptPath: typeof promptPath;
32
+ promptAge: typeof promptAge;
33
+ promptConfirm: typeof promptConfirm;
34
+ promptViewList: typeof promptViewList;
35
+ promptDelete: typeof promptDelete;
36
+ promptSelectFolders: typeof promptSelectFolders;
37
+ promptAction: typeof promptAction;
38
+ };
39
+ export default _default;
40
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/ui/prompts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGzD;;GAEG;AACH,wBAAsB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUrE;AAED;;GAEG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAU7D;AAED;;GAEG;AACH,wBAAsB,aAAa,CAC/B,OAAO,EAAE,MAAM,EACf,YAAY,UAAQ,GACrB,OAAO,CAAC,OAAO,CAAC,CAUlB;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAEvD;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAKhF;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACrC,OAAO,EAAE,eAAe,EAAE,GAC3B,OAAO,CAAC,eAAe,EAAE,CAAC,CAkB5B;AAED;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,OAAO,GAAG,YAAY,GAAG,QAAQ,GAAG,MAAM,CAAC,CAgBjG;;;;;;;;;;AAED,wBAQE"}
@@ -0,0 +1,106 @@
1
+ import inquirer from 'inquirer';
2
+ import { formatBytes } from '../utils/formatter.js';
3
+ /**
4
+ * Prompt for scan path
5
+ */
6
+ export async function promptPath(defaultPath) {
7
+ const { path } = await inquirer.prompt([
8
+ {
9
+ type: 'input',
10
+ name: 'path',
11
+ message: '📂 Bạn muốn quét ở đâu?',
12
+ default: defaultPath,
13
+ },
14
+ ]);
15
+ return path;
16
+ }
17
+ /**
18
+ * Prompt for age filter
19
+ */
20
+ export async function promptAge() {
21
+ const { age } = await inquirer.prompt([
22
+ {
23
+ type: 'input',
24
+ name: 'age',
25
+ message: '📅 Chỉ xóa folder cũ hơn bao nhiêu ngày? (Enter = tất cả)',
26
+ default: '',
27
+ },
28
+ ]);
29
+ return age ? `${age}d` : undefined;
30
+ }
31
+ /**
32
+ * Prompt for confirmation
33
+ */
34
+ export async function promptConfirm(message, defaultValue = false) {
35
+ const { confirmed } = await inquirer.prompt([
36
+ {
37
+ type: 'confirm',
38
+ name: 'confirmed',
39
+ message,
40
+ default: defaultValue,
41
+ },
42
+ ]);
43
+ return confirmed;
44
+ }
45
+ /**
46
+ * Prompt to view list
47
+ */
48
+ export async function promptViewList() {
49
+ return promptConfirm('👀 Bạn có muốn xem danh sách?', true);
50
+ }
51
+ /**
52
+ * Prompt to delete
53
+ */
54
+ export async function promptDelete(count, size) {
55
+ return promptConfirm(`🗑️ Xóa ${count} folders (${formatBytes(size)})?`, false);
56
+ }
57
+ /**
58
+ * Prompt for folder selection
59
+ */
60
+ export async function promptSelectFolders(folders) {
61
+ const choices = folders.map((folder, index) => ({
62
+ name: `${folder.projectPath} (${formatBytes(folder.size)}, ${folder.ageDays}d)`,
63
+ value: index,
64
+ checked: true,
65
+ }));
66
+ const { selected } = await inquirer.prompt([
67
+ {
68
+ type: 'checkbox',
69
+ name: 'selected',
70
+ message: '📋 Chọn folders để xóa:',
71
+ choices,
72
+ pageSize: 15,
73
+ },
74
+ ]);
75
+ return selected.map((i) => folders[i]);
76
+ }
77
+ /**
78
+ * Prompt for action selection
79
+ */
80
+ export async function promptAction() {
81
+ const { action } = await inquirer.prompt([
82
+ {
83
+ type: 'list',
84
+ name: 'action',
85
+ message: '🎯 Bạn muốn làm gì?',
86
+ choices: [
87
+ { name: '🔍 Quét và xem danh sách node_modules', value: 'scan' },
88
+ { name: '🧹 Xóa node_modules', value: 'clean' },
89
+ { name: '🧼 Deep clean (xóa file rác)', value: 'deep-clean' },
90
+ { name: '📊 Xem báo cáo', value: 'report' },
91
+ { name: '👋 Thoát', value: 'exit' },
92
+ ],
93
+ },
94
+ ]);
95
+ return action;
96
+ }
97
+ export default {
98
+ promptPath,
99
+ promptAge,
100
+ promptConfirm,
101
+ promptViewList,
102
+ promptDelete,
103
+ promptSelectFolders,
104
+ promptAction,
105
+ };
106
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/ui/prompts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { Ora } from 'ora';
2
+ /**
3
+ * Create a spinner with consistent styling
4
+ */
5
+ export declare function createSpinner(text: string): Ora;
6
+ /**
7
+ * Run async operation with spinner
8
+ */
9
+ export declare function withSpinner<T>(text: string, operation: () => Promise<T>, successText?: string, failText?: string): Promise<T>;
10
+ declare const _default: {
11
+ createSpinner: typeof createSpinner;
12
+ withSpinner: typeof withSpinner;
13
+ };
14
+ export default _default;
15
+ //# sourceMappingURL=spinner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/ui/spinner.ts"],"names":[],"mappings":"AAAA,OAAY,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAG/B;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAM/C;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,CAAC,EAC/B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,WAAW,CAAC,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,CAAC,CAAC,CAYZ;;;;;AAED,wBAA8C"}
@@ -0,0 +1,30 @@
1
+ import ora from 'ora';
2
+ import chalk from 'chalk';
3
+ /**
4
+ * Create a spinner with consistent styling
5
+ */
6
+ export function createSpinner(text) {
7
+ return ora({
8
+ text,
9
+ spinner: 'dots',
10
+ color: 'cyan',
11
+ });
12
+ }
13
+ /**
14
+ * Run async operation with spinner
15
+ */
16
+ export async function withSpinner(text, operation, successText, failText) {
17
+ const spinner = createSpinner(text);
18
+ spinner.start();
19
+ try {
20
+ const result = await operation();
21
+ spinner.succeed(successText || chalk.green('Done'));
22
+ return result;
23
+ }
24
+ catch (error) {
25
+ spinner.fail(failText || chalk.red('Failed'));
26
+ throw error;
27
+ }
28
+ }
29
+ export default { createSpinner, withSpinner };
30
+ //# sourceMappingURL=spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/ui/spinner.ts"],"names":[],"mappings":"AAAA,OAAO,GAAY,MAAM,KAAK,CAAC;AAC/B,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACtC,OAAO,GAAG,CAAC;QACP,IAAI;QACJ,OAAO,EAAE,MAAM;QACf,KAAK,EAAE,MAAM;KAChB,CAAC,CAAC;AACP,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC7B,IAAY,EACZ,SAA2B,EAC3B,WAAoB,EACpB,QAAiB;IAEjB,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACpC,OAAO,CAAC,KAAK,EAAE,CAAC;IAEhB,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,OAAO,CAAC,OAAO,CAAC,WAAW,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QACpD,OAAO,MAAM,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9C,MAAM,KAAK,CAAC;IAChB,CAAC;AACL,CAAC;AAED,eAAe,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,38 @@
1
+ import type { NodeModulesInfo } from '../types/index.js';
2
+ /**
3
+ * Create a table showing node_modules folders
4
+ */
5
+ export declare function createFoldersTable(folders: NodeModulesInfo[]): string;
6
+ /**
7
+ * Create a summary table
8
+ */
9
+ export declare function createSummaryTable(data: {
10
+ totalFolders: number;
11
+ totalSize: number;
12
+ oldestAge: number;
13
+ newestAge: number;
14
+ }): string;
15
+ /**
16
+ * Create a report breakdown table
17
+ */
18
+ export declare function createBreakdownTable(data: {
19
+ recent: {
20
+ count: number;
21
+ size: number;
22
+ };
23
+ medium: {
24
+ count: number;
25
+ size: number;
26
+ };
27
+ old: {
28
+ count: number;
29
+ size: number;
30
+ };
31
+ }): string;
32
+ declare const _default: {
33
+ createFoldersTable: typeof createFoldersTable;
34
+ createSummaryTable: typeof createSummaryTable;
35
+ createBreakdownTable: typeof createBreakdownTable;
36
+ };
37
+ export default _default;
38
+ //# sourceMappingURL=table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/ui/table.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGzD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAmCrE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CAgBT;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACvC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACxC,GAAG,MAAM,CAsCT;;;;;;AA2BD,wBAIE"}
@@ -0,0 +1,117 @@
1
+ import Table from 'cli-table3';
2
+ import chalk from 'chalk';
3
+ import { formatBytes } from '../utils/formatter.js';
4
+ /**
5
+ * Create a table showing node_modules folders
6
+ */
7
+ export function createFoldersTable(folders) {
8
+ const table = new Table({
9
+ head: [
10
+ chalk.cyan('#'),
11
+ chalk.cyan('Path'),
12
+ chalk.cyan('Size'),
13
+ chalk.cyan('Age'),
14
+ chalk.cyan('Packages'),
15
+ chalk.cyan('Lock'),
16
+ ],
17
+ style: {
18
+ head: [],
19
+ border: ['gray'],
20
+ },
21
+ colWidths: [5, 50, 12, 15, 10, 8],
22
+ wordWrap: true,
23
+ });
24
+ folders.forEach((folder, index) => {
25
+ const ageColor = getAgeColor(folder.ageDays);
26
+ const lockType = folder.hasPackageLock ? 'npm' :
27
+ folder.hasYarnLock ? 'yarn' :
28
+ folder.hasPnpmLock ? 'pnpm' : '-';
29
+ table.push([
30
+ chalk.gray((index + 1).toString()),
31
+ chalk.white(shortenPath(folder.projectPath)),
32
+ chalk.yellow(formatBytes(folder.size)),
33
+ ageColor(`${folder.ageDays}d`),
34
+ chalk.magenta(folder.packageCount.toString()),
35
+ chalk.gray(lockType),
36
+ ]);
37
+ });
38
+ return table.toString();
39
+ }
40
+ /**
41
+ * Create a summary table
42
+ */
43
+ export function createSummaryTable(data) {
44
+ const table = new Table({
45
+ style: {
46
+ head: [],
47
+ border: ['gray'],
48
+ },
49
+ });
50
+ table.push([chalk.cyan('Total Folders'), chalk.white(data.totalFolders.toString())], [chalk.cyan('Total Size'), chalk.yellow(formatBytes(data.totalSize))], [chalk.cyan('Oldest'), chalk.red(`${data.oldestAge} days`)], [chalk.cyan('Newest'), chalk.green(`${data.newestAge} days`)]);
51
+ return table.toString();
52
+ }
53
+ /**
54
+ * Create a report breakdown table
55
+ */
56
+ export function createBreakdownTable(data) {
57
+ const table = new Table({
58
+ head: [
59
+ chalk.cyan('Age Range'),
60
+ chalk.cyan('Count'),
61
+ chalk.cyan('Size'),
62
+ chalk.cyan('% of Total'),
63
+ ],
64
+ style: {
65
+ head: [],
66
+ border: ['gray'],
67
+ },
68
+ });
69
+ const total = data.recent.size + data.medium.size + data.old.size;
70
+ table.push([
71
+ chalk.green('0-30 days'),
72
+ data.recent.count.toString(),
73
+ formatBytes(data.recent.size),
74
+ `${((data.recent.size / total) * 100).toFixed(1)}%`,
75
+ ], [
76
+ chalk.yellow('30-90 days'),
77
+ data.medium.count.toString(),
78
+ formatBytes(data.medium.size),
79
+ `${((data.medium.size / total) * 100).toFixed(1)}%`,
80
+ ], [
81
+ chalk.red('90+ days'),
82
+ data.old.count.toString(),
83
+ formatBytes(data.old.size),
84
+ `${((data.old.size / total) * 100).toFixed(1)}%`,
85
+ ]);
86
+ return table.toString();
87
+ }
88
+ /**
89
+ * Get color based on age
90
+ */
91
+ function getAgeColor(days) {
92
+ if (days < 30)
93
+ return chalk.green;
94
+ if (days < 90)
95
+ return chalk.yellow;
96
+ return chalk.red;
97
+ }
98
+ /**
99
+ * Shorten path for display
100
+ */
101
+ function shortenPath(p, maxLength = 45) {
102
+ if (p.length <= maxLength)
103
+ return p;
104
+ const home = process.env.HOME || process.env.USERPROFILE || '';
105
+ let shortened = p.replace(home, '~');
106
+ if (shortened.length <= maxLength)
107
+ return shortened;
108
+ // Truncate from the middle
109
+ const half = Math.floor((maxLength - 3) / 2);
110
+ return shortened.slice(0, half) + '...' + shortened.slice(-half);
111
+ }
112
+ export default {
113
+ createFoldersTable,
114
+ createSummaryTable,
115
+ createBreakdownTable,
116
+ };
117
+ //# sourceMappingURL=table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.js","sourceRoot":"","sources":["../../src/ui/table.ts"],"names":[],"mappings":"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"}