appclean 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 (154) hide show
  1. package/.github/workflows/publish.yml +41 -0
  2. package/.github/workflows/test.yml +37 -0
  3. package/ACTION_CHECKLIST.md +342 -0
  4. package/APPCLEAN_SUMMARY.md +309 -0
  5. package/CHANGELOG.md +205 -0
  6. package/CODE_OF_CONDUCT.md +49 -0
  7. package/CODE_REVIEW_REPORT.md +447 -0
  8. package/COMMUNITY_POSTS.md +307 -0
  9. package/CONTRIBUTING.md +121 -0
  10. package/DEPLOYMENT_GUIDE.md +345 -0
  11. package/DEPLOYMENT_STATUS.md +182 -0
  12. package/EXECUTIVE_REPORT.md +393 -0
  13. package/GITHUB_OPTIMIZATION.md +383 -0
  14. package/INDEX.md +165 -0
  15. package/LICENSE +21 -0
  16. package/MARKETING_SUMMARY.md +352 -0
  17. package/NPM_PACKAGE_OPTIMIZATION.md +281 -0
  18. package/NPM_PUBLISH.md +116 -0
  19. package/PROJECT_SUMMARY.txt +249 -0
  20. package/QUICKSTART.md +219 -0
  21. package/README.md +548 -0
  22. package/SECURITY.md +104 -0
  23. package/SETUP_GITHUB.md +237 -0
  24. package/TESTING_SUMMARY.md +379 -0
  25. package/dist/core/appUpdateChecker.d.ts +23 -0
  26. package/dist/core/appUpdateChecker.d.ts.map +1 -0
  27. package/dist/core/appUpdateChecker.js +159 -0
  28. package/dist/core/appUpdateChecker.js.map +1 -0
  29. package/dist/core/detector.d.ts +13 -0
  30. package/dist/core/detector.d.ts.map +1 -0
  31. package/dist/core/detector.js +99 -0
  32. package/dist/core/detector.js.map +1 -0
  33. package/dist/core/duplicateFileFinder.d.ts +14 -0
  34. package/dist/core/duplicateFileFinder.d.ts.map +1 -0
  35. package/dist/core/duplicateFileFinder.js +80 -0
  36. package/dist/core/duplicateFileFinder.js.map +1 -0
  37. package/dist/core/orphanedDependencyDetector.d.ts +19 -0
  38. package/dist/core/orphanedDependencyDetector.d.ts.map +1 -0
  39. package/dist/core/orphanedDependencyDetector.js +148 -0
  40. package/dist/core/orphanedDependencyDetector.js.map +1 -0
  41. package/dist/core/performanceOptimizer.d.ts +37 -0
  42. package/dist/core/performanceOptimizer.d.ts.map +1 -0
  43. package/dist/core/performanceOptimizer.js +128 -0
  44. package/dist/core/performanceOptimizer.js.map +1 -0
  45. package/dist/core/permissionHandler.d.ts +9 -0
  46. package/dist/core/permissionHandler.d.ts.map +1 -0
  47. package/dist/core/permissionHandler.js +89 -0
  48. package/dist/core/permissionHandler.js.map +1 -0
  49. package/dist/core/pluginSystem.d.ts +39 -0
  50. package/dist/core/pluginSystem.d.ts.map +1 -0
  51. package/dist/core/pluginSystem.js +120 -0
  52. package/dist/core/pluginSystem.js.map +1 -0
  53. package/dist/core/removalRecorder.d.ts +32 -0
  54. package/dist/core/removalRecorder.d.ts.map +1 -0
  55. package/dist/core/removalRecorder.js +79 -0
  56. package/dist/core/removalRecorder.js.map +1 -0
  57. package/dist/core/remover.d.ts +15 -0
  58. package/dist/core/remover.d.ts.map +1 -0
  59. package/dist/core/remover.js +225 -0
  60. package/dist/core/remover.js.map +1 -0
  61. package/dist/core/reportGenerator.d.ts +9 -0
  62. package/dist/core/reportGenerator.d.ts.map +1 -0
  63. package/dist/core/reportGenerator.js +328 -0
  64. package/dist/core/reportGenerator.js.map +1 -0
  65. package/dist/core/scheduledCleanup.d.ts +38 -0
  66. package/dist/core/scheduledCleanup.d.ts.map +1 -0
  67. package/dist/core/scheduledCleanup.js +127 -0
  68. package/dist/core/scheduledCleanup.js.map +1 -0
  69. package/dist/core/serviceFileDetector.d.ts +18 -0
  70. package/dist/core/serviceFileDetector.d.ts.map +1 -0
  71. package/dist/core/serviceFileDetector.js +136 -0
  72. package/dist/core/serviceFileDetector.js.map +1 -0
  73. package/dist/core/verificationModule.d.ts +14 -0
  74. package/dist/core/verificationModule.d.ts.map +1 -0
  75. package/dist/core/verificationModule.js +102 -0
  76. package/dist/core/verificationModule.js.map +1 -0
  77. package/dist/index.d.ts +3 -0
  78. package/dist/index.d.ts.map +1 -0
  79. package/dist/index.js +333 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/managers/brewManager.d.ts +10 -0
  82. package/dist/managers/brewManager.d.ts.map +1 -0
  83. package/dist/managers/brewManager.js +130 -0
  84. package/dist/managers/brewManager.js.map +1 -0
  85. package/dist/managers/customManager.d.ts +8 -0
  86. package/dist/managers/customManager.d.ts.map +1 -0
  87. package/dist/managers/customManager.js +139 -0
  88. package/dist/managers/customManager.js.map +1 -0
  89. package/dist/managers/linuxManager.d.ts +10 -0
  90. package/dist/managers/linuxManager.d.ts.map +1 -0
  91. package/dist/managers/linuxManager.js +191 -0
  92. package/dist/managers/linuxManager.js.map +1 -0
  93. package/dist/managers/npmManager.d.ts +10 -0
  94. package/dist/managers/npmManager.d.ts.map +1 -0
  95. package/dist/managers/npmManager.js +119 -0
  96. package/dist/managers/npmManager.js.map +1 -0
  97. package/dist/types/index.d.ts +44 -0
  98. package/dist/types/index.d.ts.map +1 -0
  99. package/dist/types/index.js +3 -0
  100. package/dist/types/index.js.map +1 -0
  101. package/dist/ui/guiServer.d.ts +10 -0
  102. package/dist/ui/guiServer.d.ts.map +1 -0
  103. package/dist/ui/guiServer.js +134 -0
  104. package/dist/ui/guiServer.js.map +1 -0
  105. package/dist/ui/menu.d.ts +6 -0
  106. package/dist/ui/menu.d.ts.map +1 -0
  107. package/dist/ui/menu.js +93 -0
  108. package/dist/ui/menu.js.map +1 -0
  109. package/dist/ui/prompts.d.ts +13 -0
  110. package/dist/ui/prompts.d.ts.map +1 -0
  111. package/dist/ui/prompts.js +161 -0
  112. package/dist/ui/prompts.js.map +1 -0
  113. package/dist/utils/filesystem.d.ts +13 -0
  114. package/dist/utils/filesystem.d.ts.map +1 -0
  115. package/dist/utils/filesystem.js +152 -0
  116. package/dist/utils/filesystem.js.map +1 -0
  117. package/dist/utils/logger.d.ts +12 -0
  118. package/dist/utils/logger.d.ts.map +1 -0
  119. package/dist/utils/logger.js +49 -0
  120. package/dist/utils/logger.js.map +1 -0
  121. package/dist/utils/platform.d.ts +9 -0
  122. package/dist/utils/platform.d.ts.map +1 -0
  123. package/dist/utils/platform.js +75 -0
  124. package/dist/utils/platform.js.map +1 -0
  125. package/jest.config.js +20 -0
  126. package/logo.svg +60 -0
  127. package/package.json +55 -0
  128. package/setup-github.sh +125 -0
  129. package/src/core/appUpdateChecker.ts +220 -0
  130. package/src/core/detector.ts +133 -0
  131. package/src/core/duplicateFileFinder.ts +113 -0
  132. package/src/core/orphanedDependencyDetector.ts +195 -0
  133. package/src/core/performanceOptimizer.ts +209 -0
  134. package/src/core/permissionHandler.ts +121 -0
  135. package/src/core/pluginSystem.ts +194 -0
  136. package/src/core/removalRecorder.ts +146 -0
  137. package/src/core/remover.ts +280 -0
  138. package/src/core/reportGenerator.ts +354 -0
  139. package/src/core/scheduledCleanup.ts +204 -0
  140. package/src/core/serviceFileDetector.ts +181 -0
  141. package/src/core/verificationModule.ts +140 -0
  142. package/src/index.ts +449 -0
  143. package/src/managers/brewManager.ts +149 -0
  144. package/src/managers/customManager.ts +167 -0
  145. package/src/managers/linuxManager.ts +210 -0
  146. package/src/managers/npmManager.ts +137 -0
  147. package/src/types/index.ts +59 -0
  148. package/src/ui/guiServer.ts +155 -0
  149. package/src/ui/menu.ts +100 -0
  150. package/src/ui/prompts.ts +177 -0
  151. package/src/utils/filesystem.ts +145 -0
  152. package/src/utils/logger.ts +48 -0
  153. package/src/utils/platform.ts +75 -0
  154. package/tsconfig.json +20 -0
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Remover = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const child_process_1 = require("child_process");
9
+ const platform_1 = require("../utils/platform");
10
+ const filesystem_1 = require("../utils/filesystem");
11
+ const logger_1 = require("../utils/logger");
12
+ const npmManager_1 = require("../managers/npmManager");
13
+ const brewManager_1 = require("../managers/brewManager");
14
+ const linuxManager_1 = require("../managers/linuxManager");
15
+ const permissionHandler_1 = require("./permissionHandler");
16
+ const serviceFileDetector_1 = require("./serviceFileDetector");
17
+ const removalRecorder_1 = require("./removalRecorder");
18
+ const reportGenerator_1 = require("./reportGenerator");
19
+ const verificationModule_1 = require("./verificationModule");
20
+ class Remover {
21
+ async previewRemoval(artifacts) {
22
+ logger_1.Logger.info('Files to be removed:');
23
+ logger_1.Logger.space();
24
+ let totalSize = 0;
25
+ for (const artifact of artifacts) {
26
+ const size = artifact.size || 0;
27
+ totalSize += size;
28
+ console.log(` ${artifact.type.padEnd(8)} ${(0, logger_1.formatBytes)(size).padEnd(10)} ${artifact.path}`);
29
+ }
30
+ logger_1.Logger.space();
31
+ logger_1.Logger.info(`Total space to be freed: ${(0, logger_1.formatBytes)(totalSize)}`);
32
+ }
33
+ async createBackup(appName, artifacts) {
34
+ const home = (0, platform_1.getHomeDir)();
35
+ const backupDir = path_1.default.join(home, '.appclean-backups');
36
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
37
+ const backupPath = path_1.default.join(backupDir, `${appName}-${timestamp}.tar.gz`);
38
+ try {
39
+ (0, child_process_1.execSync)(`mkdir -p "${backupDir}"`);
40
+ const filePaths = artifacts.map((a) => `"${a.path}"`).join(' ');
41
+ (0, child_process_1.execSync)(`tar -czf "${backupPath}" ${filePaths} 2>/dev/null || true`);
42
+ logger_1.Logger.success(`Backup created: ${backupPath}`);
43
+ return backupPath;
44
+ }
45
+ catch (error) {
46
+ logger_1.Logger.warn(`Failed to create backup: ${error.message}`);
47
+ return '';
48
+ }
49
+ }
50
+ async removeArtifacts(artifacts, options) {
51
+ const errors = [];
52
+ let success = 0;
53
+ let failed = 0;
54
+ for (const artifact of artifacts) {
55
+ try {
56
+ if (!(0, filesystem_1.pathExists)(artifact.path)) {
57
+ continue;
58
+ }
59
+ const isDirectory = this.isDirectory(artifact.path);
60
+ if (isDirectory) {
61
+ const deleted = (0, filesystem_1.deleteDirectory)(artifact.path);
62
+ if (deleted) {
63
+ success++;
64
+ }
65
+ else {
66
+ failed++;
67
+ errors.push(`Failed to delete directory: ${artifact.path}`);
68
+ }
69
+ }
70
+ else {
71
+ const deleted = (0, filesystem_1.deleteFile)(artifact.path);
72
+ if (deleted) {
73
+ success++;
74
+ }
75
+ else {
76
+ failed++;
77
+ errors.push(`Failed to delete file: ${artifact.path}`);
78
+ }
79
+ }
80
+ }
81
+ catch (error) {
82
+ failed++;
83
+ errors.push(`Error removing ${artifact.path}: ${error.message}`);
84
+ }
85
+ }
86
+ return { success, failed, errors };
87
+ }
88
+ async removeApp(appName, installMethod, artifacts, options = {}) {
89
+ const result = {
90
+ success: false,
91
+ appName,
92
+ removedFiles: 0,
93
+ freedSpace: 0,
94
+ errors: [],
95
+ };
96
+ const recorder = new removalRecorder_1.RemovalRecorder();
97
+ const verificationModule = new verificationModule_1.VerificationModule();
98
+ const serviceDetector = new serviceFileDetector_1.ServiceFileDetector();
99
+ const reportGenerator = new reportGenerator_1.ReportGenerator();
100
+ let removalRecord = null;
101
+ const artifactPaths = artifacts.map((a) => a.path);
102
+ try {
103
+ const requiresElevation = permissionHandler_1.PermissionHandler.installationRequiresElevation(installMethod, artifactPaths);
104
+ if (requiresElevation && !permissionHandler_1.PermissionHandler.isElevated()) {
105
+ await permissionHandler_1.PermissionHandler.requestElevatedPermissions();
106
+ logger_1.Logger.warn('Please run this command with sudo for complete removal of system packages');
107
+ }
108
+ const serviceFiles = await serviceDetector.findServiceFiles(appName);
109
+ if (serviceFiles.length > 0) {
110
+ logger_1.Logger.info('\n⚠️ Manual Cleanup Required:');
111
+ logger_1.Logger.info('The following service files require manual cleanup:');
112
+ serviceFiles.forEach((file, index) => {
113
+ console.log(`\n${index + 1}. ${file.type.toUpperCase()}`);
114
+ console.log(` Path: ${file.path}`);
115
+ console.log(` Command: ${file.manualCleanupInstructions}`);
116
+ });
117
+ }
118
+ if (options.dryRun) {
119
+ await this.previewRemoval(artifacts);
120
+ result.success = true;
121
+ return result;
122
+ }
123
+ removalRecord = recorder.createRecord(appName, installMethod, options.userConsent ?? true);
124
+ if (options.createBackup) {
125
+ result.backupPath = await this.createBackup(appName, artifacts);
126
+ }
127
+ const removed = await this.removeViaPackageManager(appName, installMethod);
128
+ if (!removed) {
129
+ logger_1.Logger.warn(`Package manager removal failed, attempting manual file removal...`);
130
+ }
131
+ const removalResult = await this.removeArtifacts(artifacts, options);
132
+ artifacts.forEach((artifact, index) => {
133
+ const status = index < removalResult.success ? 'deleted' : 'failed';
134
+ const errorMsg = removalResult.errors.find((e) => e.includes(artifact.path));
135
+ recorder.addDeletedArtifact(removalRecord, artifact, status, errorMsg);
136
+ });
137
+ result.removedFiles = removalResult.success;
138
+ result.errors = removalResult.errors;
139
+ result.freedSpace = artifacts.reduce((total, a) => total + (a.size || 0), 0);
140
+ const verificationResult = await verificationModule.verifyRemoval(appName, artifactPaths);
141
+ recorder.updateVerificationStatus(removalRecord, verificationResult.status);
142
+ logger_1.Logger.info(`\n${verificationModule.getStatusMessage(verificationResult.status)}`);
143
+ if (removalResult.failed === 0) {
144
+ result.success = true;
145
+ recorder.updateCompletionStatus(removalRecord, 'success');
146
+ logger_1.Logger.success(`Successfully removed ${appName}`);
147
+ }
148
+ else {
149
+ recorder.updateCompletionStatus(removalRecord, removalResult.failed === removalResult.success + removalResult.failed ? 'partial' : 'failed');
150
+ logger_1.Logger.warn(`Removed ${appName} with ${removalResult.failed} errors`);
151
+ }
152
+ if (removalRecord) {
153
+ const recordPath = recorder.saveRecord(removalRecord);
154
+ logger_1.Logger.debug(`Removal record saved to: ${recordPath}`);
155
+ const reportPath = reportGenerator_1.ReportGenerator.saveReport(removalRecord, options.reportFormat ?? 'html');
156
+ logger_1.Logger.success(`Report generated: ${reportPath}`);
157
+ reportGenerator_1.ReportGenerator.displayReport(removalRecord);
158
+ }
159
+ }
160
+ catch (error) {
161
+ result.success = false;
162
+ result.errors?.push(error.message);
163
+ logger_1.Logger.error(`Failed to remove ${appName}: ${error.message}`);
164
+ if (removalRecord) {
165
+ recorder.updateCompletionStatus(removalRecord, 'failed');
166
+ const recordPath = recorder.saveRecord(removalRecord);
167
+ logger_1.Logger.debug(`Failed removal record saved to: ${recordPath}`);
168
+ }
169
+ }
170
+ return result;
171
+ }
172
+ async removeViaPackageManager(appName, installMethod) {
173
+ try {
174
+ switch (installMethod) {
175
+ case 'npm': {
176
+ const npm = new npmManager_1.NpmManager();
177
+ return await npm.removePackage(appName);
178
+ }
179
+ case 'brew': {
180
+ const brew = new brewManager_1.BrewManager();
181
+ return await brew.removePackage(appName);
182
+ }
183
+ case 'apt':
184
+ case 'yum':
185
+ case 'dnf': {
186
+ const linux = new linuxManager_1.LinuxManager();
187
+ return await linux.removePackage(appName);
188
+ }
189
+ default:
190
+ return false;
191
+ }
192
+ }
193
+ catch (error) {
194
+ logger_1.Logger.debug(`Package manager removal failed: ${error.message}`);
195
+ return false;
196
+ }
197
+ }
198
+ isDirectory(filePath) {
199
+ try {
200
+ const fs = require('fs');
201
+ return fs.statSync(filePath).isDirectory();
202
+ }
203
+ catch {
204
+ return false;
205
+ }
206
+ }
207
+ async rollback(backupPath) {
208
+ try {
209
+ if (!(0, filesystem_1.pathExists)(backupPath)) {
210
+ logger_1.Logger.error(`Backup file not found: ${backupPath}`);
211
+ return false;
212
+ }
213
+ logger_1.Logger.info('Restoring from backup...');
214
+ (0, child_process_1.execSync)(`tar -xzf "${backupPath}" -C /`);
215
+ logger_1.Logger.success('Backup restored successfully');
216
+ return true;
217
+ }
218
+ catch (error) {
219
+ logger_1.Logger.error(`Failed to restore backup: ${error.message}`);
220
+ return false;
221
+ }
222
+ }
223
+ }
224
+ exports.Remover = Remover;
225
+ //# sourceMappingURL=remover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remover.js","sourceRoot":"","sources":["../../src/core/remover.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { RemovalRecord } from './removalRecorder';
2
+ export declare const REMOVAL_DISCLAIMER = "\n\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557\n\u2551 \u2551\n\u2551 \u26A0\uFE0F IMPORTANT DISCLAIMER \u26A0\uFE0F \u2551\n\u2551 \u2551\n\u2551 AppClean is provided \"AS IS\" without any warranties or representations. \u2551\n\u2551 \u2551\n\u2551 By using this tool, you acknowledge and agree that: \u2551\n\u2551 \u2551\n\u2551 1. AppClean provides functionality to detect and remove applications \u2551\n\u2551 and their associated files from your system. \u2551\n\u2551 \u2551\n\u2551 2. Data deletion is PERMANENT and IRREVERSIBLE. Please ensure you have \u2551\n\u2551 created backups of any important data before using this tool. \u2551\n\u2551 \u2551\n\u2551 3. While AppClean aims to be accurate, it may not detect all files \u2551\n\u2551 or may encounter errors during deletion. Some files may remain \u2551\n\u2551 orphaned on your system despite successful removal. \u2551\n\u2551 \u2551\n\u2551 4. AppClean developers and maintainers assume NO LIABILITY or \u2551\n\u2551 RESPONSIBILITY for any data loss, system damage, or any other \u2551\n\u2551 consequences arising from the use of this tool. \u2551\n\u2551 \u2551\n\u2551 5. You are solely responsible for verifying the safety of removal \u2551\n\u2551 operations before execution and for maintaining your own backups. \u2551\n\u2551 \u2551\n\u2551 6. By proceeding with app removal, you confirm that you understand \u2551\n\u2551 and accept these terms and conditions. \u2551\n\u2551 \u2551\n\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D\n";
3
+ export declare class ReportGenerator {
4
+ static generateHTMLReport(record: RemovalRecord): string;
5
+ static generateTextReport(record: RemovalRecord): string;
6
+ static saveReport(record: RemovalRecord, format?: 'html' | 'text'): string;
7
+ static displayReport(record: RemovalRecord): void;
8
+ }
9
+ //# sourceMappingURL=reportGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reportGenerator.d.ts","sourceRoot":"","sources":["../../src/core/reportGenerator.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAmB,MAAM,mBAAmB,CAAC;AAGnE,eAAO,MAAM,kBAAkB,2zGA8B9B,CAAC;AAEF,qBAAa,eAAe;IAI1B,MAAM,CAAC,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM;IA+NxD,MAAM,CAAC,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM;IAqDxD,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,GAAE,MAAM,GAAG,MAAe,GAAG,MAAM;IAyBlF,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;CAUlD"}
@@ -0,0 +1,328 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ReportGenerator = exports.REMOVAL_DISCLAIMER = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const chalk_1 = __importDefault(require("chalk"));
10
+ const logger_1 = require("../utils/logger");
11
+ exports.REMOVAL_DISCLAIMER = `
12
+ ╔════════════════════════════════════════════════════════════════════════════╗
13
+ ║ ║
14
+ ║ ⚠️ IMPORTANT DISCLAIMER ⚠️ ║
15
+ ║ ║
16
+ ║ AppClean is provided "AS IS" without any warranties or representations. ║
17
+ ║ ║
18
+ ║ By using this tool, you acknowledge and agree that: ║
19
+ ║ ║
20
+ ║ 1. AppClean provides functionality to detect and remove applications ║
21
+ ║ and their associated files from your system. ║
22
+ ║ ║
23
+ ║ 2. Data deletion is PERMANENT and IRREVERSIBLE. Please ensure you have ║
24
+ ║ created backups of any important data before using this tool. ║
25
+ ║ ║
26
+ ║ 3. While AppClean aims to be accurate, it may not detect all files ║
27
+ ║ or may encounter errors during deletion. Some files may remain ║
28
+ ║ orphaned on your system despite successful removal. ║
29
+ ║ ║
30
+ ║ 4. AppClean developers and maintainers assume NO LIABILITY or ║
31
+ ║ RESPONSIBILITY for any data loss, system damage, or any other ║
32
+ ║ consequences arising from the use of this tool. ║
33
+ ║ ║
34
+ ║ 5. You are solely responsible for verifying the safety of removal ║
35
+ ║ operations before execution and for maintaining your own backups. ║
36
+ ║ ║
37
+ ║ 6. By proceeding with app removal, you confirm that you understand ║
38
+ ║ and accept these terms and conditions. ║
39
+ ║ ║
40
+ ╚════════════════════════════════════════════════════════════════════════════╝
41
+ `;
42
+ class ReportGenerator {
43
+ static generateHTMLReport(record) {
44
+ const timestamp = (0, logger_1.formatDate)(record.timestamp);
45
+ const totalFreed = (0, logger_1.formatBytes)(record.totalSpaceFreed);
46
+ let html = `
47
+ <!DOCTYPE html>
48
+ <html lang="en">
49
+ <head>
50
+ <meta charset="UTF-8">
51
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
52
+ <title>AppClean Removal Report - ${record.appName}</title>
53
+ <style>
54
+ body {
55
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
56
+ margin: 0;
57
+ padding: 20px;
58
+ background: #f5f5f5;
59
+ color: #333;
60
+ }
61
+ .container {
62
+ max-width: 900px;
63
+ margin: 0 auto;
64
+ background: white;
65
+ padding: 30px;
66
+ border-radius: 8px;
67
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
68
+ }
69
+ h1 {
70
+ color: #2c3e50;
71
+ border-bottom: 3px solid #3b82f6;
72
+ padding-bottom: 10px;
73
+ }
74
+ h2 {
75
+ color: #34495e;
76
+ margin-top: 30px;
77
+ }
78
+ .summary {
79
+ background: #f8f9fa;
80
+ padding: 20px;
81
+ border-left: 4px solid #3b82f6;
82
+ margin: 20px 0;
83
+ border-radius: 4px;
84
+ }
85
+ .summary-item {
86
+ margin: 10px 0;
87
+ }
88
+ .summary-label {
89
+ font-weight: bold;
90
+ color: #2c3e50;
91
+ }
92
+ table {
93
+ width: 100%;
94
+ border-collapse: collapse;
95
+ margin: 20px 0;
96
+ }
97
+ th {
98
+ background: #3b82f6;
99
+ color: white;
100
+ padding: 12px;
101
+ text-align: left;
102
+ font-weight: 600;
103
+ }
104
+ td {
105
+ padding: 12px;
106
+ border-bottom: 1px solid #e0e0e0;
107
+ }
108
+ tr:hover {
109
+ background: #f5f5f5;
110
+ }
111
+ .status-deleted {
112
+ background: #d4edda;
113
+ color: #155724;
114
+ padding: 4px 8px;
115
+ border-radius: 4px;
116
+ }
117
+ .status-failed {
118
+ background: #f8d7da;
119
+ color: #721c24;
120
+ padding: 4px 8px;
121
+ border-radius: 4px;
122
+ }
123
+ .status-skipped {
124
+ background: #fff3cd;
125
+ color: #856404;
126
+ padding: 4px 8px;
127
+ border-radius: 4px;
128
+ }
129
+ .disclaimer {
130
+ background: #fff3cd;
131
+ border: 2px solid #ff6b6b;
132
+ padding: 20px;
133
+ margin: 20px 0;
134
+ border-radius: 4px;
135
+ color: #721c24;
136
+ }
137
+ .disclaimer h3 {
138
+ margin-top: 0;
139
+ color: #721c24;
140
+ }
141
+ .footer {
142
+ text-align: center;
143
+ color: #7f8c8d;
144
+ font-size: 12px;
145
+ margin-top: 40px;
146
+ padding-top: 20px;
147
+ border-top: 1px solid #e0e0e0;
148
+ }
149
+ .success {
150
+ color: #27ae60;
151
+ }
152
+ .warning {
153
+ color: #e67e22;
154
+ }
155
+ .error {
156
+ color: #e74c3c;
157
+ }
158
+ </style>
159
+ </head>
160
+ <body>
161
+ <div class="container">
162
+ <h1>📋 AppClean Removal Report</h1>
163
+
164
+ <div class="summary">
165
+ <div class="summary-item">
166
+ <span class="summary-label">Application:</span> ${record.appName}
167
+ </div>
168
+ <div class="summary-item">
169
+ <span class="summary-label">Installation Method:</span> ${record.installMethod}
170
+ </div>
171
+ <div class="summary-item">
172
+ <span class="summary-label">Removal Date:</span> ${timestamp}
173
+ </div>
174
+ <div class="summary-item">
175
+ <span class="summary-label">User Consent:</span>
176
+ <span class="${record.userConsent ? 'success' : 'error'}">
177
+ ${record.userConsent ? '✓ Yes' : '✗ No'}
178
+ </span>
179
+ </div>
180
+ <div class="summary-item">
181
+ <span class="summary-label">Completion Status:</span>
182
+ <span class="${record.completionStatus === 'success' ? 'success' : record.completionStatus === 'partial' ? 'warning' : 'error'}">
183
+ ${record.completionStatus.toUpperCase()}
184
+ </span>
185
+ </div>
186
+ <div class="summary-item">
187
+ <span class="summary-label">Verification Status:</span>
188
+ <span class="${record.verificationStatus === 'verified_removed' ? 'success' : 'warning'}">
189
+ ${record.verificationStatus.replace(/_/g, ' ').toUpperCase()}
190
+ </span>
191
+ </div>
192
+ <div class="summary-item">
193
+ <span class="summary-label">Total Space Freed:</span>
194
+ <span class="success">${totalFreed}</span>
195
+ </div>
196
+ </div>
197
+
198
+ <h2>Deletion Details</h2>
199
+ <table>
200
+ <thead>
201
+ <tr>
202
+ <th>File/Folder</th>
203
+ <th>Type</th>
204
+ <th>Size</th>
205
+ <th>Status</th>
206
+ </tr>
207
+ </thead>
208
+ <tbody>
209
+ ${record.artifactsDeleted
210
+ .map((artifact) => `
211
+ <tr>
212
+ <td><code>${artifact.path}</code></td>
213
+ <td>${artifact.type}</td>
214
+ <td>${(0, logger_1.formatBytes)(artifact.size)}</td>
215
+ <td>
216
+ <span class="status-${artifact.status}">
217
+ ${artifact.status.toUpperCase()}
218
+ ${artifact.errorMessage ? ` - ${artifact.errorMessage}` : ''}
219
+ </span>
220
+ </td>
221
+ </tr>
222
+ `)
223
+ .join('')}
224
+ </tbody>
225
+ </table>
226
+
227
+ <div class="disclaimer">
228
+ <h3>⚠️ DISCLAIMER & NO LIABILITY NOTICE</h3>
229
+ <p>
230
+ <strong>IMPORTANT:</strong> AppClean is provided "AS IS" without any warranties or representations.
231
+ This report documents the data removal operations performed by AppClean.
232
+ </p>
233
+ <p>
234
+ <strong>By using AppClean, you acknowledge that:</strong>
235
+ </p>
236
+ <ol>
237
+ <li>Data deletion is PERMANENT and IRREVERSIBLE</li>
238
+ <li>AppClean developers assume NO LIABILITY for any data loss</li>
239
+ <li>You are responsible for maintaining your own backups</li>
240
+ <li>Some files may remain orphaned despite successful removal</li>
241
+ <li>You have reviewed and consented to all removal operations</li>
242
+ </ol>
243
+ <p>
244
+ <strong>AppClean is NOT responsible for any consequences arising from the use of this tool.</strong>
245
+ </p>
246
+ </div>
247
+
248
+ <div class="footer">
249
+ <p>Generated by AppClean v1.1.0 | Report timestamp: ${new Date().toISOString()}</p>
250
+ <p>For support, visit: https://github.com/praveenkay/AppClean</p>
251
+ </div>
252
+ </div>
253
+ </body>
254
+ </html>
255
+ `;
256
+ return html;
257
+ }
258
+ static generateTextReport(record) {
259
+ const timestamp = (0, logger_1.formatDate)(record.timestamp);
260
+ const totalFreed = (0, logger_1.formatBytes)(record.totalSpaceFreed);
261
+ let report = `
262
+ ═══════════════════════════════════════════════════════════════════════════════
263
+ 📋 APPCLEAN REMOVAL REPORT
264
+ ═══════════════════════════════════════════════════════════════════════════════
265
+
266
+ SUMMARY
267
+ ──────────────────────────────────────────────────────────────────────────────
268
+ Application: ${record.appName}
269
+ Installation Method: ${record.installMethod}
270
+ Removal Date: ${timestamp}
271
+ User Consent: ${record.userConsent ? '✓ Yes' : '✗ No'}
272
+ Completion Status: ${record.completionStatus.toUpperCase()}
273
+ Verification Status: ${record.verificationStatus.replace(/_/g, ' ').toUpperCase()}
274
+ Total Space Freed: ${totalFreed}
275
+
276
+ DELETED FILES & FOLDERS
277
+ ──────────────────────────────────────────────────────────────────────────────
278
+ `;
279
+ record.artifactsDeleted.forEach((artifact, index) => {
280
+ report += `\n${index + 1}. ${artifact.path}
281
+ Type: ${artifact.type}
282
+ Size: ${(0, logger_1.formatBytes)(artifact.size)}
283
+ Status: ${artifact.status.toUpperCase()}`;
284
+ if (artifact.errorMessage) {
285
+ report += `\n Error: ${artifact.errorMessage}`;
286
+ }
287
+ });
288
+ report += `\n\n${exports.REMOVAL_DISCLAIMER}`;
289
+ report += `
290
+
291
+ ═══════════════════════════════════════════════════════════════════════════════
292
+ END OF REPORT
293
+ ═══════════════════════════════════════════════════════════════════════════════
294
+
295
+ Generated by AppClean v1.1.0
296
+ Timestamp: ${new Date().toISOString()}
297
+ For support, visit: https://github.com/praveenkay/AppClean
298
+ `;
299
+ return report;
300
+ }
301
+ static saveReport(record, format = 'html') {
302
+ const home = path_1.default.resolve(process.env.HOME || '/root');
303
+ const reportsDir = path_1.default.join(home, '.appclean-reports');
304
+ if (!fs_1.default.existsSync(reportsDir)) {
305
+ fs_1.default.mkdirSync(reportsDir, { recursive: true });
306
+ }
307
+ const timestamp = record.timestamp.getTime();
308
+ const filename = `${record.appName}-removal-${timestamp}.${format === 'html' ? 'html' : 'txt'}`;
309
+ const filepath = path_1.default.join(reportsDir, filename);
310
+ const content = format === 'html'
311
+ ? this.generateHTMLReport(record)
312
+ : this.generateTextReport(record);
313
+ fs_1.default.writeFileSync(filepath, content, 'utf-8');
314
+ return filepath;
315
+ }
316
+ static displayReport(record) {
317
+ console.log(chalk_1.default.cyan(exports.REMOVAL_DISCLAIMER));
318
+ console.log('\n' + chalk_1.default.bold('Removal Summary:'));
319
+ console.log(chalk_1.default.gray(` App: ${record.appName}`));
320
+ console.log(chalk_1.default.gray(` Method: ${record.installMethod}`));
321
+ console.log(chalk_1.default.gray(` Timestamp: ${(0, logger_1.formatDate)(record.timestamp)}`));
322
+ console.log(chalk_1.default.gray(` Space Freed: ${(0, logger_1.formatBytes)(record.totalSpaceFreed)}`));
323
+ console.log(chalk_1.default.gray(` Status: ${record.completionStatus.toUpperCase()}`));
324
+ console.log(chalk_1.default.gray(` Verification: ${record.verificationStatus.replace(/_/g, ' ').toUpperCase()}`));
325
+ }
326
+ }
327
+ exports.ReportGenerator = ReportGenerator;
328
+ //# sourceMappingURL=reportGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reportGenerator.js","sourceRoot":"","sources":["../../src/core/reportGenerator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ export type CleanupFrequency = 'daily' | 'weekly' | 'monthly' | 'custom';
2
+ export interface CleanupSchedule {
3
+ id: string;
4
+ appName: string;
5
+ frequency: CleanupFrequency;
6
+ enabled: boolean;
7
+ lastRun?: Date;
8
+ nextRun?: Date;
9
+ customCron?: string;
10
+ dryRun: boolean;
11
+ createBackup: boolean;
12
+ }
13
+ export interface CleanupResult {
14
+ scheduleId: string;
15
+ appName: string;
16
+ timestamp: Date;
17
+ success: boolean;
18
+ filesRemoved: number;
19
+ spaceFreed: number;
20
+ errors: string[];
21
+ }
22
+ export declare class ScheduledCleanup {
23
+ private schedules;
24
+ private schedulesFile;
25
+ constructor();
26
+ createSchedule(appName: string, frequency: CleanupFrequency, options?: Partial<CleanupSchedule>): CleanupSchedule;
27
+ deleteSchedule(scheduleId: string): boolean;
28
+ getSchedules(): CleanupSchedule[];
29
+ getSchedule(scheduleId: string): CleanupSchedule | null;
30
+ updateSchedule(scheduleId: string, updates: Partial<CleanupSchedule>): boolean;
31
+ setScheduleEnabled(scheduleId: string, enabled: boolean): void;
32
+ calculateNextRun(schedule: CleanupSchedule): Date;
33
+ getSchedulesDue(): CleanupSchedule[];
34
+ recordResult(result: CleanupResult): void;
35
+ private loadSchedules;
36
+ private saveSchedules;
37
+ }
38
+ //# sourceMappingURL=scheduledCleanup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduledCleanup.d.ts","sourceRoot":"","sources":["../../src/core/scheduledCleanup.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEzE,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAA2C;IAC5D,OAAO,CAAC,aAAa,CAAS;;IAW9B,cAAc,CACZ,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,gBAAgB,EAC3B,OAAO,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GACjC,eAAe;IAsBlB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAY3C,YAAY,IAAI,eAAe,EAAE;IAOjC,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;IAOvD,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,OAAO;IAc9E,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAY9D,gBAAgB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAqBjD,eAAe,IAAI,eAAe,EAAE;IAYpC,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAkBzC,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,aAAa;CAQtB"}