appclean 1.9.0 โ 2.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.
- package/GUI_IMPLEMENTATION_STATUS.md +143 -0
- package/MD_Files/INDEX.md +51 -0
- package/PHASE2_COMPLETION.md +281 -0
- package/PHASE3_COMPLETION.md +364 -0
- package/README.md +411 -91
- package/assets/logo.svg +34 -0
- package/dist/core/appUpdateChecker.js +12 -16
- package/dist/core/appUpdateChecker.js.map +1 -1
- package/dist/core/detector.js +14 -18
- package/dist/core/detector.js.map +1 -1
- package/dist/core/duplicateFileFinder.js +12 -19
- package/dist/core/duplicateFileFinder.js.map +1 -1
- package/dist/core/orphanedDependencyDetector.js +19 -26
- package/dist/core/orphanedDependencyDetector.js.map +1 -1
- package/dist/core/performanceOptimizer.js +6 -10
- package/dist/core/performanceOptimizer.js.map +1 -1
- package/dist/core/permissionHandler.js +21 -25
- package/dist/core/permissionHandler.js.map +1 -1
- package/dist/core/pluginSystem.js +9 -13
- package/dist/core/pluginSystem.js.map +1 -1
- package/dist/core/removalRecorder.js +12 -19
- package/dist/core/removalRecorder.js.map +1 -1
- package/dist/core/remover.js +59 -66
- package/dist/core/remover.js.map +1 -1
- package/dist/core/reportGenerator.d.ts +1 -1
- package/dist/core/reportGenerator.d.ts.map +1 -1
- package/dist/core/reportGenerator.js +27 -34
- package/dist/core/reportGenerator.js.map +1 -1
- package/dist/core/scheduledCleanup.js +23 -30
- package/dist/core/scheduledCleanup.js.map +1 -1
- package/dist/core/serviceFileDetector.js +24 -31
- package/dist/core/serviceFileDetector.js.map +1 -1
- package/dist/core/verificationModule.js +10 -14
- package/dist/core/verificationModule.js.map +1 -1
- package/dist/index.js +118 -156
- package/dist/index.js.map +1 -1
- package/dist/managers/brewManager.js +30 -37
- package/dist/managers/brewManager.js.map +1 -1
- package/dist/managers/customManager.js +23 -30
- package/dist/managers/customManager.js.map +1 -1
- package/dist/managers/linuxManager.js +29 -36
- package/dist/managers/linuxManager.js.map +1 -1
- package/dist/managers/npmManager.js +27 -34
- package/dist/managers/npmManager.js.map +1 -1
- package/dist/types/index.js +1 -2
- package/dist/ui/client/api/client.d.ts +24 -0
- package/dist/ui/client/api/client.d.ts.map +1 -0
- package/dist/ui/client/api/client.js +96 -0
- package/dist/ui/client/api/client.js.map +1 -0
- package/dist/ui/client/app.d.ts +7 -0
- package/dist/ui/client/app.d.ts.map +1 -0
- package/dist/ui/client/app.js +71 -0
- package/dist/ui/client/app.js.map +1 -0
- package/dist/ui/client/index.html +107 -0
- package/dist/ui/client/pages/appDetails.d.ts +8 -0
- package/dist/ui/client/pages/appDetails.d.ts.map +1 -0
- package/dist/ui/client/pages/appDetails.js +287 -0
- package/dist/ui/client/pages/appDetails.js.map +1 -0
- package/dist/ui/client/pages/appSearch.d.ts +2 -0
- package/dist/ui/client/pages/appSearch.d.ts.map +1 -0
- package/dist/ui/client/pages/appSearch.js +210 -0
- package/dist/ui/client/pages/appSearch.js.map +1 -0
- package/dist/ui/client/pages/dashboard.d.ts +2 -0
- package/dist/ui/client/pages/dashboard.d.ts.map +1 -0
- package/dist/ui/client/pages/dashboard.js +154 -0
- package/dist/ui/client/pages/dashboard.js.map +1 -0
- package/dist/ui/client/pages/settings.d.ts +7 -0
- package/dist/ui/client/pages/settings.d.ts.map +1 -0
- package/dist/ui/client/pages/settings.js +279 -0
- package/dist/ui/client/pages/settings.js.map +1 -0
- package/dist/ui/client/state/appStore.d.ts +38 -0
- package/dist/ui/client/state/appStore.d.ts.map +1 -0
- package/dist/ui/client/state/appStore.js +121 -0
- package/dist/ui/client/state/appStore.js.map +1 -0
- package/dist/ui/client/state/dashboardStore.d.ts +31 -0
- package/dist/ui/client/state/dashboardStore.d.ts.map +1 -0
- package/dist/ui/client/state/dashboardStore.js +70 -0
- package/dist/ui/client/state/dashboardStore.js.map +1 -0
- package/dist/ui/client/state/uiStore.d.ts +43 -0
- package/dist/ui/client/state/uiStore.d.ts.map +1 -0
- package/dist/ui/client/state/uiStore.js +109 -0
- package/dist/ui/client/state/uiStore.js.map +1 -0
- package/dist/ui/client/styles/animations.css +327 -0
- package/dist/ui/client/styles/base.css +214 -0
- package/dist/ui/client/styles/components.css +400 -0
- package/dist/ui/client/styles/layout.css +224 -0
- package/dist/ui/client/styles/variables.css +140 -0
- package/dist/ui/client/utils/events.d.ts +19 -0
- package/dist/ui/client/utils/events.d.ts.map +1 -0
- package/dist/ui/client/utils/events.js +54 -0
- package/dist/ui/client/utils/events.js.map +1 -0
- package/dist/ui/client/utils/formatting.d.ts +11 -0
- package/dist/ui/client/utils/formatting.d.ts.map +1 -0
- package/dist/ui/client/utils/formatting.js +104 -0
- package/dist/ui/client/utils/formatting.js.map +1 -0
- package/dist/ui/client/utils/router.d.ts +25 -0
- package/dist/ui/client/utils/router.d.ts.map +1 -0
- package/dist/ui/client/utils/router.js +90 -0
- package/dist/ui/client/utils/router.js.map +1 -0
- package/dist/ui/guiServer.d.ts +8 -5
- package/dist/ui/guiServer.d.ts.map +1 -1
- package/dist/ui/guiServer.js +137 -505
- package/dist/ui/guiServer.js.map +1 -1
- package/dist/ui/menu.js +18 -27
- package/dist/ui/menu.js.map +1 -1
- package/dist/ui/prompts.js +34 -47
- package/dist/ui/prompts.js.map +1 -1
- package/dist/ui/server/middleware/errorHandler.d.ts +19 -0
- package/dist/ui/server/middleware/errorHandler.d.ts.map +1 -0
- package/dist/ui/server/middleware/errorHandler.js +100 -0
- package/dist/ui/server/middleware/errorHandler.js.map +1 -0
- package/dist/ui/server/routes/apps.d.ts +8 -0
- package/dist/ui/server/routes/apps.d.ts.map +1 -0
- package/dist/ui/server/routes/apps.js +74 -0
- package/dist/ui/server/routes/apps.js.map +1 -0
- package/dist/ui/server/routes/dashboard.d.ts +4 -0
- package/dist/ui/server/routes/dashboard.d.ts.map +1 -0
- package/dist/ui/server/routes/dashboard.js +57 -0
- package/dist/ui/server/routes/dashboard.js.map +1 -0
- package/dist/ui/server/routes/settings.d.ts +6 -0
- package/dist/ui/server/routes/settings.d.ts.map +1 -0
- package/dist/ui/server/routes/settings.js +31 -0
- package/dist/ui/server/routes/settings.js.map +1 -0
- package/dist/ui/server/services/appService.d.ts +45 -0
- package/dist/ui/server/services/appService.d.ts.map +1 -0
- package/dist/ui/server/services/appService.js +114 -0
- package/dist/ui/server/services/appService.js.map +1 -0
- package/dist/ui/server/services/removalService.d.ts +24 -0
- package/dist/ui/server/services/removalService.d.ts.map +1 -0
- package/dist/ui/server/services/removalService.js +83 -0
- package/dist/ui/server/services/removalService.js.map +1 -0
- package/dist/utils/filesystem.js +32 -49
- package/dist/utils/filesystem.js.map +1 -1
- package/dist/utils/logger.js +9 -18
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/platform.js +10 -22
- package/dist/utils/platform.js.map +1 -1
- package/dist/utils/upgrade.js +10 -14
- package/dist/utils/upgrade.js.map +1 -1
- package/package.json +4 -2
- package/src/core/appUpdateChecker.ts +1 -1
- package/src/core/detector.ts +6 -6
- package/src/core/duplicateFileFinder.ts +1 -1
- package/src/core/orphanedDependencyDetector.ts +2 -2
- package/src/core/performanceOptimizer.ts +1 -1
- package/src/core/permissionHandler.ts +2 -2
- package/src/core/pluginSystem.ts +1 -1
- package/src/core/removalRecorder.ts +2 -2
- package/src/core/remover.ts +11 -11
- package/src/core/reportGenerator.ts +2 -2
- package/src/core/scheduledCleanup.ts +2 -2
- package/src/core/serviceFileDetector.ts +2 -2
- package/src/core/verificationModule.ts +2 -2
- package/src/index.ts +8 -8
- package/src/managers/brewManager.ts +3 -3
- package/src/managers/customManager.ts +2 -2
- package/src/managers/linuxManager.ts +3 -3
- package/src/managers/npmManager.ts +3 -3
- package/src/ui/client/api/client.ts +163 -0
- package/src/ui/client/app.ts +121 -0
- package/src/ui/client/index.html +107 -0
- package/src/ui/client/pages/appDetails.ts +356 -0
- package/src/ui/client/pages/appSearch.ts +270 -0
- package/src/ui/client/pages/dashboard.ts +189 -0
- package/src/ui/client/pages/settings.ts +342 -0
- package/src/ui/client/state/appStore.ts +169 -0
- package/src/ui/client/state/dashboardStore.ts +113 -0
- package/src/ui/client/state/uiStore.ts +166 -0
- package/src/ui/client/styles/animations.css +327 -0
- package/src/ui/client/styles/base.css +214 -0
- package/src/ui/client/styles/components.css +400 -0
- package/src/ui/client/styles/layout.css +224 -0
- package/src/ui/client/styles/variables.css +140 -0
- package/src/ui/client/utils/events.ts +74 -0
- package/src/ui/client/utils/formatting.ts +157 -0
- package/src/ui/client/utils/router.ts +161 -0
- package/src/ui/guiServer.ts +183 -502
- package/src/ui/prompts.ts +1 -1
- package/src/ui/server/middleware/errorHandler.ts +174 -0
- package/src/ui/server/routes/apps.ts +132 -0
- package/src/ui/server/routes/dashboard.ts +93 -0
- package/src/ui/server/routes/settings.ts +63 -0
- package/src/ui/server/services/appService.ts +184 -0
- package/src/ui/server/services/removalService.ts +138 -0
- package/src/utils/upgrade.ts +1 -1
- package/tsconfig.json +3 -2
- package/INDEX.md +0 -165
- /package/{ACTION_CHECKLIST.md โ MD_Files/ACTION_CHECKLIST.md} +0 -0
- /package/{APPCLEAN_SUMMARY.md โ MD_Files/APPCLEAN_SUMMARY.md} +0 -0
- /package/{CHANGELOG.md โ MD_Files/CHANGELOG.md} +0 -0
- /package/{CODE_OF_CONDUCT.md โ MD_Files/CODE_OF_CONDUCT.md} +0 -0
- /package/{CODE_REVIEW_REPORT.md โ MD_Files/CODE_REVIEW_REPORT.md} +0 -0
- /package/{COMMUNITY_POSTS.md โ MD_Files/COMMUNITY_POSTS.md} +0 -0
- /package/{DEPLOYMENT_GUIDE.md โ MD_Files/DEPLOYMENT_GUIDE.md} +0 -0
- /package/{DEPLOYMENT_STATUS.md โ MD_Files/DEPLOYMENT_STATUS.md} +0 -0
- /package/{EXECUTIVE_REPORT.md โ MD_Files/EXECUTIVE_REPORT.md} +0 -0
- /package/{GITHUB_OPTIMIZATION.md โ MD_Files/GITHUB_OPTIMIZATION.md} +0 -0
- /package/{MARKETING_SUMMARY.md โ MD_Files/MARKETING_SUMMARY.md} +0 -0
- /package/{NPM_PACKAGE_OPTIMIZATION.md โ MD_Files/NPM_PACKAGE_OPTIMIZATION.md} +0 -0
- /package/{NPM_PUBLISH.md โ MD_Files/NPM_PUBLISH.md} +0 -0
- /package/{PROJECT_SUMMARY.txt โ MD_Files/PROJECT_SUMMARY.txt} +0 -0
- /package/{PUBLICATION_SUCCESS_REPORT.md โ MD_Files/PUBLICATION_SUCCESS_REPORT.md} +0 -0
- /package/{QUICKSTART.md โ MD_Files/QUICKSTART.md} +0 -0
- /package/{SETUP_GITHUB.md โ MD_Files/SETUP_GITHUB.md} +0 -0
- /package/{TESTING_SUMMARY.md โ MD_Files/TESTING_SUMMARY.md} +0 -0
- /package/{setup-github.sh โ MD_Files/setup-github.sh} +0 -0
package/dist/utils/upgrade.js
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const child_process_1 = require("child_process");
|
|
5
|
-
const logger_1 = require("./logger");
|
|
6
|
-
class UpgradeManager {
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import { Logger } from './logger.js';
|
|
3
|
+
export class UpgradeManager {
|
|
7
4
|
constructor() {
|
|
8
5
|
this.packageName = 'appclean';
|
|
9
6
|
this.currentVersion = '1.9.0';
|
|
10
7
|
}
|
|
11
8
|
async getVersionInfo() {
|
|
12
9
|
try {
|
|
13
|
-
const output =
|
|
10
|
+
const output = execSync(`npm view ${this.packageName} version --json`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
14
11
|
const latestVersion = output.replace(/"/g, '');
|
|
15
12
|
const isUpdateAvailable = this.compareVersions(this.currentVersion, latestVersion);
|
|
16
13
|
return {
|
|
@@ -20,7 +17,7 @@ class UpgradeManager {
|
|
|
20
17
|
};
|
|
21
18
|
}
|
|
22
19
|
catch (error) {
|
|
23
|
-
|
|
20
|
+
Logger.debug('Failed to check npm registry: ' + error.message);
|
|
24
21
|
return {
|
|
25
22
|
current: this.currentVersion,
|
|
26
23
|
latest: this.currentVersion,
|
|
@@ -43,7 +40,7 @@ class UpgradeManager {
|
|
|
43
40
|
}
|
|
44
41
|
async upgrade() {
|
|
45
42
|
try {
|
|
46
|
-
|
|
43
|
+
Logger.info('Checking for updates...');
|
|
47
44
|
const versionInfo = await this.getVersionInfo();
|
|
48
45
|
if (!versionInfo.isUpdateAvailable) {
|
|
49
46
|
return {
|
|
@@ -51,8 +48,8 @@ class UpgradeManager {
|
|
|
51
48
|
message: `AppClean is already up to date (v${versionInfo.current})`,
|
|
52
49
|
};
|
|
53
50
|
}
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
Logger.info(`Upgrading from v${versionInfo.current} to v${versionInfo.latest}...`);
|
|
52
|
+
execSync(`npm install -g ${this.packageName}@latest`, {
|
|
56
53
|
stdio: 'inherit',
|
|
57
54
|
});
|
|
58
55
|
return {
|
|
@@ -76,8 +73,8 @@ class UpgradeManager {
|
|
|
76
73
|
}
|
|
77
74
|
async uninstall() {
|
|
78
75
|
try {
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
Logger.info('Uninstalling AppClean...');
|
|
77
|
+
execSync(`npm uninstall -g ${this.packageName}`, {
|
|
81
78
|
stdio: 'inherit',
|
|
82
79
|
});
|
|
83
80
|
return {
|
|
@@ -94,5 +91,4 @@ class UpgradeManager {
|
|
|
94
91
|
}
|
|
95
92
|
}
|
|
96
93
|
}
|
|
97
|
-
exports.UpgradeManager = UpgradeManager;
|
|
98
94
|
//# sourceMappingURL=upgrade.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../src/utils/upgrade.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../src/utils/upgrade.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "appclean",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"description": "A powerful CLI tool to intelligently find and safely uninstall applications from your system with all their artifacts",
|
|
5
6
|
"main": "dist/index.js",
|
|
6
7
|
"bin": {
|
|
7
8
|
"appclean": "dist/index.js"
|
|
8
9
|
},
|
|
9
10
|
"scripts": {
|
|
10
|
-
"build": "tsc",
|
|
11
|
+
"build": "tsc && npm run copy-assets",
|
|
12
|
+
"copy-assets": "mkdir -p dist/ui/client/styles && cp src/ui/client/index.html dist/ui/client/ && cp src/ui/client/styles/*.css dist/ui/client/styles/",
|
|
11
13
|
"dev": "ts-node src/index.ts",
|
|
12
14
|
"start": "node dist/index.js",
|
|
13
15
|
"test": "jest",
|
package/src/core/detector.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { NpmManager } from '../managers/npmManager';
|
|
2
|
-
import { BrewManager } from '../managers/brewManager';
|
|
3
|
-
import { LinuxManager } from '../managers/linuxManager';
|
|
4
|
-
import { CustomManager } from '../managers/customManager';
|
|
5
|
-
import { isMacOS, isLinux } from '../utils/platform';
|
|
1
|
+
import { NpmManager } from '../managers/npmManager.js';
|
|
2
|
+
import { BrewManager } from '../managers/brewManager.js';
|
|
3
|
+
import { LinuxManager } from '../managers/linuxManager.js';
|
|
4
|
+
import { CustomManager } from '../managers/customManager.js';
|
|
5
|
+
import { isMacOS, isLinux } from '../utils/platform.js';
|
|
6
6
|
import { InstalledApp, ArtifactPath, SearchOptions } from '../types';
|
|
7
|
-
import { getFileSize } from '../utils/filesystem';
|
|
7
|
+
import { getFileSize } from '../utils/filesystem.js';
|
|
8
8
|
|
|
9
9
|
export class Detector {
|
|
10
10
|
private npmManager: NpmManager;
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { execSync } from 'child_process';
|
|
8
|
-
import { getHomeDir } from '../utils/platform';
|
|
8
|
+
import { getHomeDir } from '../utils/platform.js';
|
|
9
9
|
import path from 'path';
|
|
10
10
|
import fs from 'fs';
|
|
11
|
-
import { Logger } from '../utils/logger';
|
|
11
|
+
import { Logger } from '../utils/logger.js';
|
|
12
12
|
|
|
13
13
|
export interface OrphanedPackage {
|
|
14
14
|
name: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { execSync } from 'child_process';
|
|
2
|
-
import { isMacOS, isLinux, isWindows } from '../utils/platform';
|
|
3
|
-
import { Logger } from '../utils/logger';
|
|
2
|
+
import { isMacOS, isLinux, isWindows } from '../utils/platform.js';
|
|
3
|
+
import { Logger } from '../utils/logger.js';
|
|
4
4
|
|
|
5
5
|
export class PermissionHandler {
|
|
6
6
|
/**
|
package/src/core/pluginSystem.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import { getHomeDir } from '../utils/platform';
|
|
3
|
+
import { getHomeDir } from '../utils/platform.js';
|
|
4
4
|
import { ArtifactPath } from '../types';
|
|
5
|
-
import { formatDate, formatBytes } from '../utils/logger';
|
|
5
|
+
import { formatDate, formatBytes } from '../utils/logger.js';
|
|
6
6
|
|
|
7
7
|
export interface RemovalRecord {
|
|
8
8
|
timestamp: Date;
|
package/src/core/remover.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import { execSync } from 'child_process';
|
|
3
|
-
import { getHomeDir } from '../utils/platform';
|
|
3
|
+
import { getHomeDir } from '../utils/platform.js';
|
|
4
4
|
import {
|
|
5
5
|
deleteFile,
|
|
6
6
|
deleteDirectory,
|
|
7
7
|
pathExists,
|
|
8
8
|
getDirectorySize,
|
|
9
|
-
} from '../utils/filesystem';
|
|
9
|
+
} from '../utils/filesystem.js';
|
|
10
10
|
import { ArtifactPath, RemovalOptions, RemovalResult } from '../types';
|
|
11
|
-
import { Logger, formatBytes } from '../utils/logger';
|
|
12
|
-
import { NpmManager } from '../managers/npmManager';
|
|
13
|
-
import { BrewManager } from '../managers/brewManager';
|
|
14
|
-
import { LinuxManager } from '../managers/linuxManager';
|
|
15
|
-
import { PermissionHandler } from './permissionHandler';
|
|
16
|
-
import { ServiceFileDetector } from './serviceFileDetector';
|
|
17
|
-
import { RemovalRecorder, RemovalRecord } from './removalRecorder';
|
|
18
|
-
import { ReportGenerator } from './reportGenerator';
|
|
19
|
-
import { VerificationModule } from './verificationModule';
|
|
11
|
+
import { Logger, formatBytes } from '../utils/logger.js';
|
|
12
|
+
import { NpmManager } from '../managers/npmManager.js';
|
|
13
|
+
import { BrewManager } from '../managers/brewManager.js';
|
|
14
|
+
import { LinuxManager } from '../managers/linuxManager.js';
|
|
15
|
+
import { PermissionHandler } from './permissionHandler.js';
|
|
16
|
+
import { ServiceFileDetector } from './serviceFileDetector.js';
|
|
17
|
+
import { RemovalRecorder, RemovalRecord } from './removalRecorder.js';
|
|
18
|
+
import { ReportGenerator } from './reportGenerator.js';
|
|
19
|
+
import { VerificationModule } from './verificationModule.js';
|
|
20
20
|
|
|
21
21
|
export class Remover {
|
|
22
22
|
async previewRemoval(artifacts: ArtifactPath[]): Promise<void> {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
|
-
import { RemovalRecord, DeletedArtifact } from './removalRecorder';
|
|
5
|
-
import { formatBytes, formatDate } from '../utils/logger';
|
|
4
|
+
import { RemovalRecord, DeletedArtifact } from './removalRecorder.js';
|
|
5
|
+
import { formatBytes, formatDate } from '../utils/logger.js';
|
|
6
6
|
|
|
7
7
|
export const REMOVAL_DISCLAIMER = `
|
|
8
8
|
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* v1.6.0 Feature
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { getHomeDir } from '../utils/platform';
|
|
7
|
+
import { getHomeDir } from '../utils/platform.js';
|
|
8
8
|
import path from 'path';
|
|
9
9
|
import fs from 'fs';
|
|
10
|
-
import { Logger } from '../utils/logger';
|
|
10
|
+
import { Logger } from '../utils/logger.js';
|
|
11
11
|
|
|
12
12
|
export type CleanupFrequency = 'daily' | 'weekly' | 'monthly' | 'custom';
|
|
13
13
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
-
import { isMacOS, isLinux, getHomeDir } from '../utils/platform';
|
|
3
|
-
import { pathExists, readFile, listDirectory } from '../utils/filesystem';
|
|
2
|
+
import { isMacOS, isLinux, getHomeDir } from '../utils/platform.js';
|
|
3
|
+
import { pathExists, readFile, listDirectory } from '../utils/filesystem.js';
|
|
4
4
|
import { ArtifactPath } from '../types';
|
|
5
5
|
|
|
6
6
|
export interface ServiceFile {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { execSync } from 'child_process';
|
|
2
|
-
import { isMacOS, isLinux, isWindows } from '../utils/platform';
|
|
3
|
-
import { pathExists } from '../utils/filesystem';
|
|
2
|
+
import { isMacOS, isLinux, isWindows } from '../utils/platform.js';
|
|
3
|
+
import { pathExists } from '../utils/filesystem.js';
|
|
4
4
|
|
|
5
5
|
export type VerificationStatus = 'verified_removed' | 'still_exists' | 'partial_removal' | 'unknown';
|
|
6
6
|
|
package/src/index.ts
CHANGED
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import ora from 'ora';
|
|
6
|
-
import { Detector } from './core/detector';
|
|
7
|
-
import { Remover } from './core/remover';
|
|
8
|
-
import { GUIServer } from './ui/guiServer';
|
|
6
|
+
import { Detector } from './core/detector.js';
|
|
7
|
+
import { Remover } from './core/remover.js';
|
|
8
|
+
import { GUIServer } from './ui/guiServer.js';
|
|
9
9
|
import {
|
|
10
10
|
showMainMenu,
|
|
11
11
|
showAppMenu,
|
|
12
12
|
showHeader,
|
|
13
13
|
showHelp,
|
|
14
|
-
} from './ui/menu';
|
|
14
|
+
} from './ui/menu.js';
|
|
15
15
|
import {
|
|
16
16
|
promptSearchQuery,
|
|
17
17
|
promptSelectApp,
|
|
@@ -21,12 +21,12 @@ import {
|
|
|
21
21
|
promptSortBy,
|
|
22
22
|
displayAppDetails,
|
|
23
23
|
promptFinalConfirmation,
|
|
24
|
-
} from './ui/prompts';
|
|
25
|
-
import { Logger, formatBytes } from './utils/logger';
|
|
26
|
-
import { UpgradeManager } from './utils/upgrade';
|
|
24
|
+
} from './ui/prompts.js';
|
|
25
|
+
import { Logger, formatBytes } from './utils/logger.js';
|
|
26
|
+
import { UpgradeManager } from './utils/upgrade.js';
|
|
27
27
|
import { InstalledApp } from './types';
|
|
28
28
|
|
|
29
|
-
const VERSION = '
|
|
29
|
+
const VERSION = '2.0.0';
|
|
30
30
|
|
|
31
31
|
async function interactiveMode(): Promise<void> {
|
|
32
32
|
showHeader();
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { execSync } from 'child_process';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import { getHomeDir } from '../utils/platform';
|
|
4
|
-
import { pathExists, listDirectory } from '../utils/filesystem';
|
|
3
|
+
import { getHomeDir } from '../utils/platform.js';
|
|
4
|
+
import { pathExists, listDirectory } from '../utils/filesystem.js';
|
|
5
5
|
import { InstalledApp, ArtifactPath } from '../types';
|
|
6
|
-
import { Logger } from '../utils/logger';
|
|
6
|
+
import { Logger } from '../utils/logger.js';
|
|
7
7
|
|
|
8
8
|
export class BrewManager {
|
|
9
9
|
private brewPrefix: string;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
-
import { getHomeDir } from '../utils/platform';
|
|
2
|
+
import { getHomeDir } from '../utils/platform.js';
|
|
3
3
|
import {
|
|
4
4
|
pathExists,
|
|
5
5
|
listDirectory,
|
|
6
6
|
readFile,
|
|
7
7
|
listDirectoryDeep,
|
|
8
|
-
} from '../utils/filesystem';
|
|
8
|
+
} from '../utils/filesystem.js';
|
|
9
9
|
import { InstalledApp, ArtifactPath } from '../types';
|
|
10
10
|
|
|
11
11
|
export class CustomManager {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { execSync } from 'child_process';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import { getHomeDir } from '../utils/platform';
|
|
4
|
-
import { pathExists, listDirectory } from '../utils/filesystem';
|
|
3
|
+
import { getHomeDir } from '../utils/platform.js';
|
|
4
|
+
import { pathExists, listDirectory } from '../utils/filesystem.js';
|
|
5
5
|
import { InstalledApp, ArtifactPath } from '../types';
|
|
6
|
-
import { Logger } from '../utils/logger';
|
|
6
|
+
import { Logger } from '../utils/logger.js';
|
|
7
7
|
|
|
8
8
|
export class LinuxManager {
|
|
9
9
|
private packageManager: 'apt' | 'yum' | 'dnf' | 'unknown' = 'unknown';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { execSync } from 'child_process';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import { getHomeDir } from '../utils/platform';
|
|
4
|
-
import { pathExists, listDirectory, readFile } from '../utils/filesystem';
|
|
3
|
+
import { getHomeDir } from '../utils/platform.js';
|
|
4
|
+
import { pathExists, listDirectory, readFile } from '../utils/filesystem.js';
|
|
5
5
|
import { InstalledApp, ArtifactPath } from '../types';
|
|
6
|
-
import { Logger } from '../utils/logger';
|
|
6
|
+
import { Logger } from '../utils/logger.js';
|
|
7
7
|
|
|
8
8
|
export class NpmManager {
|
|
9
9
|
private globalNpmPath: string;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Client - Wrapper for HTTP requests to AppClean server
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface ApiResponse<T> {
|
|
6
|
+
success: boolean;
|
|
7
|
+
data?: T;
|
|
8
|
+
error?: string;
|
|
9
|
+
message?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class ApiClient {
|
|
13
|
+
private baseUrl = '';
|
|
14
|
+
private timeout = 30000; // 30 seconds
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Make a GET request
|
|
18
|
+
*/
|
|
19
|
+
async get<T = any>(endpoint: string, options?: RequestInit): Promise<T> {
|
|
20
|
+
return this.request<T>(endpoint, { ...options, method: 'GET' });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Make a POST request
|
|
25
|
+
*/
|
|
26
|
+
async post<T = any>(
|
|
27
|
+
endpoint: string,
|
|
28
|
+
body?: any,
|
|
29
|
+
options?: RequestInit
|
|
30
|
+
): Promise<T> {
|
|
31
|
+
return this.request<T>(endpoint, {
|
|
32
|
+
...options,
|
|
33
|
+
method: 'POST',
|
|
34
|
+
headers: {
|
|
35
|
+
'Content-Type': 'application/json',
|
|
36
|
+
...options?.headers,
|
|
37
|
+
},
|
|
38
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Make a PUT request
|
|
44
|
+
*/
|
|
45
|
+
async put<T = any>(
|
|
46
|
+
endpoint: string,
|
|
47
|
+
body?: any,
|
|
48
|
+
options?: RequestInit
|
|
49
|
+
): Promise<T> {
|
|
50
|
+
return this.request<T>(endpoint, {
|
|
51
|
+
...options,
|
|
52
|
+
method: 'PUT',
|
|
53
|
+
headers: {
|
|
54
|
+
'Content-Type': 'application/json',
|
|
55
|
+
...options?.headers,
|
|
56
|
+
},
|
|
57
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Make a DELETE request
|
|
63
|
+
*/
|
|
64
|
+
async delete<T = any>(endpoint: string, options?: RequestInit): Promise<T> {
|
|
65
|
+
return this.request<T>(endpoint, { ...options, method: 'DELETE' });
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Generic request method
|
|
70
|
+
*/
|
|
71
|
+
private async request<T = any>(
|
|
72
|
+
endpoint: string,
|
|
73
|
+
options: RequestInit = {}
|
|
74
|
+
): Promise<T> {
|
|
75
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
76
|
+
const controller = new AbortController();
|
|
77
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
const response = await fetch(url, {
|
|
81
|
+
...options,
|
|
82
|
+
signal: controller.signal,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
clearTimeout(timeoutId);
|
|
86
|
+
|
|
87
|
+
if (!response.ok) {
|
|
88
|
+
const errorData = await this.parseErrorResponse(response);
|
|
89
|
+
throw new ApiError(
|
|
90
|
+
errorData.message || `HTTP ${response.status}`,
|
|
91
|
+
response.status,
|
|
92
|
+
errorData
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return await this.parseResponse<T>(response);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
clearTimeout(timeoutId);
|
|
99
|
+
|
|
100
|
+
if (error instanceof ApiError) {
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (error instanceof Error) {
|
|
105
|
+
if (error.name === 'AbortError') {
|
|
106
|
+
throw new ApiError('Request timeout', 408);
|
|
107
|
+
}
|
|
108
|
+
throw new ApiError(error.message, 0);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
throw new ApiError('Unknown error occurred', 0);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Parse successful response
|
|
117
|
+
*/
|
|
118
|
+
private async parseResponse<T>(response: Response): Promise<T> {
|
|
119
|
+
const contentType = response.headers.get('content-type');
|
|
120
|
+
|
|
121
|
+
if (contentType?.includes('application/json')) {
|
|
122
|
+
return response.json();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (contentType?.includes('text/')) {
|
|
126
|
+
return (await response.text()) as any;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return undefined as any;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Parse error response
|
|
134
|
+
*/
|
|
135
|
+
private async parseErrorResponse(response: Response): Promise<any> {
|
|
136
|
+
try {
|
|
137
|
+
const contentType = response.headers.get('content-type');
|
|
138
|
+
if (contentType?.includes('application/json')) {
|
|
139
|
+
return await response.json();
|
|
140
|
+
}
|
|
141
|
+
return { message: response.statusText };
|
|
142
|
+
} catch {
|
|
143
|
+
return { message: 'Unknown error' };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Custom API Error class
|
|
150
|
+
*/
|
|
151
|
+
export class ApiError extends Error {
|
|
152
|
+
constructor(
|
|
153
|
+
message: string,
|
|
154
|
+
public status: number,
|
|
155
|
+
public data?: any
|
|
156
|
+
) {
|
|
157
|
+
super(message);
|
|
158
|
+
this.name = 'ApiError';
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Export singleton instance
|
|
163
|
+
export const apiClient = new ApiClient();
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AppClean GUI - Main SPA Controller
|
|
3
|
+
* Initializes router, stores, and pages
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { router } from './utils/router.js';
|
|
7
|
+
import { appStore } from './state/appStore.js';
|
|
8
|
+
import { dashboardStore } from './state/dashboardStore.js';
|
|
9
|
+
import { uiStore } from './state/uiStore.js';
|
|
10
|
+
|
|
11
|
+
// Import page modules
|
|
12
|
+
import { renderDashboard } from './pages/dashboard.js';
|
|
13
|
+
import { renderAppSearch } from './pages/appSearch.js';
|
|
14
|
+
import { renderAppDetails } from './pages/appDetails.js';
|
|
15
|
+
import { renderSettings } from './pages/settings.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Initialize the SPA
|
|
19
|
+
*/
|
|
20
|
+
export function initApp(): void {
|
|
21
|
+
console.log('๐งน AppClean GUI v1.0.0 initializing...');
|
|
22
|
+
|
|
23
|
+
// Register routes
|
|
24
|
+
registerRoutes();
|
|
25
|
+
|
|
26
|
+
// Initialize stores
|
|
27
|
+
initializeStores();
|
|
28
|
+
|
|
29
|
+
// Setup UI listeners
|
|
30
|
+
setupUIListeners();
|
|
31
|
+
|
|
32
|
+
// Navigate to initial route
|
|
33
|
+
router.navigate('');
|
|
34
|
+
|
|
35
|
+
console.log('โ AppClean GUI ready');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Register all routes
|
|
40
|
+
*/
|
|
41
|
+
function registerRoutes(): void {
|
|
42
|
+
router.register('', () => {
|
|
43
|
+
uiStore.navigateTo('dashboard');
|
|
44
|
+
renderDashboard();
|
|
45
|
+
}, 'AppClean - Dashboard');
|
|
46
|
+
|
|
47
|
+
router.register('apps', () => {
|
|
48
|
+
uiStore.navigateTo('apps');
|
|
49
|
+
renderAppSearch();
|
|
50
|
+
}, 'AppClean - Apps');
|
|
51
|
+
|
|
52
|
+
router.register('apps/:appName', (params) => {
|
|
53
|
+
uiStore.navigateTo('app-details');
|
|
54
|
+
renderAppDetails(params.appName);
|
|
55
|
+
}, 'AppClean - App Details');
|
|
56
|
+
|
|
57
|
+
router.register('settings', () => {
|
|
58
|
+
uiStore.navigateTo('settings');
|
|
59
|
+
renderSettings();
|
|
60
|
+
}, 'AppClean - Settings');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Initialize stores with data
|
|
65
|
+
*/
|
|
66
|
+
async function initializeStores(): Promise<void> {
|
|
67
|
+
try {
|
|
68
|
+
// Load dashboard stats
|
|
69
|
+
await dashboardStore.loadStats();
|
|
70
|
+
|
|
71
|
+
// Load initial app list
|
|
72
|
+
await appStore.loadApps();
|
|
73
|
+
} catch (error) {
|
|
74
|
+
console.error('Failed to initialize stores:', error);
|
|
75
|
+
uiStore.showError('Failed to load application data');
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Setup UI event listeners
|
|
81
|
+
*/
|
|
82
|
+
function setupUIListeners(): void {
|
|
83
|
+
// Subscribe to UI store changes
|
|
84
|
+
uiStore.subscribe((state) => {
|
|
85
|
+
console.log('UI State changed:', state.currentView);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Subscribe to app store changes
|
|
89
|
+
appStore.subscribe((state) => {
|
|
90
|
+
console.log(`Apps loaded: ${state.apps.length}`);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Subscribe to dashboard store changes
|
|
94
|
+
dashboardStore.subscribe((state) => {
|
|
95
|
+
if (state.stats) {
|
|
96
|
+
console.log(`Dashboard stats: ${state.stats.totalApps} apps, ${state.stats.totalSpaceUsed} bytes`);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Handle route changes
|
|
101
|
+
router.onchange((route) => {
|
|
102
|
+
console.log('Navigated to:', route.path);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Theme toggle listener
|
|
106
|
+
document.addEventListener('theme-toggle', () => {
|
|
107
|
+
uiStore.toggleTheme();
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Export for consumption in HTML
|
|
113
|
+
*/
|
|
114
|
+
export { appStore, dashboardStore, uiStore, router };
|
|
115
|
+
|
|
116
|
+
// Initialize on DOM ready
|
|
117
|
+
if (document.readyState === 'loading') {
|
|
118
|
+
document.addEventListener('DOMContentLoaded', initApp);
|
|
119
|
+
} else {
|
|
120
|
+
initApp();
|
|
121
|
+
}
|