depfixer 1.0.0 → 1.1.1
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/dist/commands/audit.d.ts +19 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +170 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/fix.d.ts +10 -3
- package/dist/commands/fix.d.ts.map +1 -1
- package/dist/commands/fix.js +407 -41
- package/dist/commands/fix.js.map +1 -1
- package/dist/commands/graph.d.ts +1 -1
- package/dist/commands/graph.d.ts.map +1 -1
- package/dist/commands/graph.js +17 -12
- package/dist/commands/graph.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +120 -19
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.d.ts.map +1 -1
- package/dist/commands/logout.js +6 -0
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/migrate.d.ts +22 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +874 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/smart.d.ts +23 -0
- package/dist/commands/smart.d.ts.map +1 -0
- package/dist/commands/smart.js +1024 -0
- package/dist/commands/smart.js.map +1 -0
- package/dist/commands/whoami.d.ts +14 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +65 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.js +165 -40
- package/dist/index.js.map +1 -1
- package/dist/services/analytics.d.ts +108 -0
- package/dist/services/analytics.d.ts.map +1 -0
- package/dist/services/analytics.js +305 -0
- package/dist/services/analytics.js.map +1 -0
- package/dist/services/api-client.d.ts +159 -0
- package/dist/services/api-client.d.ts.map +1 -1
- package/dist/services/api-client.js +192 -10
- package/dist/services/api-client.js.map +1 -1
- package/dist/services/auth-manager.d.ts +14 -0
- package/dist/services/auth-manager.d.ts.map +1 -1
- package/dist/services/auth-manager.js +30 -0
- package/dist/services/auth-manager.js.map +1 -1
- package/dist/services/cache-manager.d.ts +62 -22
- package/dist/services/cache-manager.d.ts.map +1 -1
- package/dist/services/cache-manager.js +116 -30
- package/dist/services/cache-manager.js.map +1 -1
- package/dist/services/device-id.d.ts +20 -0
- package/dist/services/device-id.d.ts.map +1 -0
- package/dist/services/device-id.js +70 -0
- package/dist/services/device-id.js.map +1 -0
- package/dist/services/package-json.d.ts +44 -5
- package/dist/services/package-json.d.ts.map +1 -1
- package/dist/services/package-json.js +273 -20
- package/dist/services/package-json.js.map +1 -1
- package/dist/services/payment-flow.d.ts +108 -0
- package/dist/services/payment-flow.d.ts.map +1 -0
- package/dist/services/payment-flow.js +476 -0
- package/dist/services/payment-flow.js.map +1 -0
- package/dist/services/session-manager.d.ts +92 -0
- package/dist/services/session-manager.d.ts.map +1 -0
- package/dist/services/session-manager.js +218 -0
- package/dist/services/session-manager.js.map +1 -0
- package/dist/utils/design-system.d.ts +90 -0
- package/dist/utils/design-system.d.ts.map +1 -0
- package/dist/utils/design-system.js +338 -0
- package/dist/utils/design-system.js.map +1 -0
- package/dist/utils/output.d.ts +48 -1
- package/dist/utils/output.d.ts.map +1 -1
- package/dist/utils/output.js +180 -17
- package/dist/utils/output.js.map +1 -1
- package/dist/utils/print.d.ts +116 -0
- package/dist/utils/print.d.ts.map +1 -0
- package/dist/utils/print.js +190 -0
- package/dist/utils/print.js.map +1 -0
- package/package.json +13 -2
- package/dist/commands/analyze.d.ts +0 -18
- package/dist/commands/analyze.d.ts.map +0 -1
- package/dist/commands/analyze.js +0 -404
- package/dist/commands/analyze.js.map +0 -1
- package/dist/services/gitignore.d.ts +0 -19
- package/dist/services/gitignore.d.ts.map +0 -1
- package/dist/services/gitignore.js +0 -64
- package/dist/services/gitignore.js.map +0 -1
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import * as fs from 'fs/promises';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as crypto from 'crypto';
|
|
4
|
+
import * as os from 'os';
|
|
5
|
+
/**
|
|
6
|
+
* Session Manager
|
|
7
|
+
* Manages CLI session state for the new payment flow.
|
|
8
|
+
*
|
|
9
|
+
* Key features:
|
|
10
|
+
* - Stores session in ~/.depfixer/projects/{projectHash}/session.json
|
|
11
|
+
* - Tracks analysis ID, cost, payment status
|
|
12
|
+
* - Verifies package.json hash for integrity
|
|
13
|
+
* - Supports resume of unpaid analyses
|
|
14
|
+
* - Centralized storage (no .depfixer in project directory)
|
|
15
|
+
*/
|
|
16
|
+
export class SessionManager {
|
|
17
|
+
cacheDir;
|
|
18
|
+
sessionFile;
|
|
19
|
+
projectDir;
|
|
20
|
+
constructor(projectDir = process.cwd()) {
|
|
21
|
+
this.projectDir = projectDir;
|
|
22
|
+
// Use centralized ~/.depfixer/projects/{hash}/ directory
|
|
23
|
+
const projectHash = this.getProjectHash(projectDir);
|
|
24
|
+
this.cacheDir = path.join(os.homedir(), '.depfixer', 'projects', projectHash);
|
|
25
|
+
this.sessionFile = path.join(this.cacheDir, 'session.json');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Generate a short hash from project path for unique folder name
|
|
29
|
+
*/
|
|
30
|
+
getProjectHash(projectDir) {
|
|
31
|
+
// Normalize path and create hash
|
|
32
|
+
const normalizedPath = path.resolve(projectDir).toLowerCase();
|
|
33
|
+
return crypto.createHash('sha256').update(normalizedPath).digest('hex').substring(0, 12);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Calculate SHA256 hash of content
|
|
37
|
+
*/
|
|
38
|
+
calculateHash(content) {
|
|
39
|
+
return crypto.createHash('sha256').update(content).digest('hex');
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Save a new session after analysis
|
|
43
|
+
*/
|
|
44
|
+
async saveSession(data) {
|
|
45
|
+
await this.ensureCacheDir();
|
|
46
|
+
const session = {
|
|
47
|
+
lastSession: {
|
|
48
|
+
...data,
|
|
49
|
+
timestamp: Date.now(),
|
|
50
|
+
projectPath: this.projectDir, // Store project path for reference
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
await fs.writeFile(this.sessionFile, JSON.stringify(session, null, 2), 'utf-8');
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Load the current session
|
|
57
|
+
*/
|
|
58
|
+
async loadSession() {
|
|
59
|
+
try {
|
|
60
|
+
const content = await fs.readFile(this.sessionFile, 'utf-8');
|
|
61
|
+
const session = JSON.parse(content);
|
|
62
|
+
return session.lastSession || null;
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
if (error.code === 'ENOENT') {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Check if a session exists
|
|
73
|
+
*/
|
|
74
|
+
async hasSession() {
|
|
75
|
+
try {
|
|
76
|
+
await fs.access(this.sessionFile);
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Update session status (e.g., mark as PAID)
|
|
85
|
+
*/
|
|
86
|
+
async updateStatus(status) {
|
|
87
|
+
const session = await this.loadSession();
|
|
88
|
+
if (!session) {
|
|
89
|
+
throw new Error('No session to update');
|
|
90
|
+
}
|
|
91
|
+
session.status = status;
|
|
92
|
+
const sessionFile = { lastSession: session };
|
|
93
|
+
await fs.writeFile(this.sessionFile, JSON.stringify(sessionFile, null, 2), 'utf-8');
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Verify that package.json hasn't changed since analysis
|
|
97
|
+
*/
|
|
98
|
+
async verifyHash(currentContent) {
|
|
99
|
+
const session = await this.loadSession();
|
|
100
|
+
if (!session) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
const currentHash = this.calculateHash(currentContent);
|
|
104
|
+
return currentHash === session.originalFileHash;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get human-readable time since analysis
|
|
108
|
+
*/
|
|
109
|
+
getTimeSinceAnalysis(session) {
|
|
110
|
+
const diffMs = Date.now() - session.timestamp;
|
|
111
|
+
const diffMins = Math.floor(diffMs / 60000);
|
|
112
|
+
const diffHours = Math.floor(diffMins / 60);
|
|
113
|
+
const diffDays = Math.floor(diffHours / 24);
|
|
114
|
+
if (diffDays > 0) {
|
|
115
|
+
return `${diffDays} day${diffDays > 1 ? 's' : ''} ago`;
|
|
116
|
+
}
|
|
117
|
+
else if (diffHours > 0) {
|
|
118
|
+
return `${diffHours} hour${diffHours > 1 ? 's' : ''} ago`;
|
|
119
|
+
}
|
|
120
|
+
else if (diffMins > 0) {
|
|
121
|
+
return `${diffMins} minute${diffMins > 1 ? 's' : ''} ago`;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
return 'just now';
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get session description for display
|
|
129
|
+
*/
|
|
130
|
+
getSessionDescription(session) {
|
|
131
|
+
const timeAgo = this.getTimeSinceAnalysis(session);
|
|
132
|
+
switch (session.intent) {
|
|
133
|
+
case 'MIGRATE':
|
|
134
|
+
return `${timeAgo} (MIGRATE → ${session.args?.target || 'unknown'})`;
|
|
135
|
+
case 'AUDIT':
|
|
136
|
+
return `${timeAgo} (AUDIT)`;
|
|
137
|
+
case 'ANALYZE':
|
|
138
|
+
return `${timeAgo} (ANALYZE)`;
|
|
139
|
+
default:
|
|
140
|
+
return timeAgo;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Clear the session (after successful fix or on user request)
|
|
145
|
+
*/
|
|
146
|
+
async clearSession() {
|
|
147
|
+
try {
|
|
148
|
+
await fs.unlink(this.sessionFile);
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
if (error.code !== 'ENOENT') {
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Get the session file path
|
|
158
|
+
*/
|
|
159
|
+
getSessionFilePath() {
|
|
160
|
+
return this.sessionFile;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Ensure cache directory exists
|
|
164
|
+
*/
|
|
165
|
+
async ensureCacheDir() {
|
|
166
|
+
try {
|
|
167
|
+
await fs.mkdir(this.cacheDir, { recursive: true });
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
if (error.code !== 'EEXIST') {
|
|
171
|
+
throw error;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Migrate from old cache format (analysis-history.json) if present
|
|
177
|
+
* This provides backward compatibility with existing installations
|
|
178
|
+
*/
|
|
179
|
+
async migrateFromOldCache() {
|
|
180
|
+
const oldCacheFile = path.join(this.cacheDir, 'analysis-history.json');
|
|
181
|
+
try {
|
|
182
|
+
const content = await fs.readFile(oldCacheFile, 'utf-8');
|
|
183
|
+
const oldCache = JSON.parse(content);
|
|
184
|
+
// Get the most recent entry from the old history
|
|
185
|
+
const history = oldCache.history || [];
|
|
186
|
+
if (history.length === 0) {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
const latest = history[history.length - 1];
|
|
190
|
+
// Convert to new format
|
|
191
|
+
const newSession = {
|
|
192
|
+
analysisId: latest.analysisId,
|
|
193
|
+
timestamp: latest.timestamp,
|
|
194
|
+
intent: latest.mode === 'migrate' ? 'MIGRATE' : 'ANALYZE',
|
|
195
|
+
args: latest.targetVersion ? { target: latest.targetVersion } : undefined,
|
|
196
|
+
originalFileHash: latest.packageJsonHash,
|
|
197
|
+
cost: 0, // Unknown from old format
|
|
198
|
+
status: 'UNPAID', // Assume unpaid
|
|
199
|
+
projectName: latest.projectName || 'unknown',
|
|
200
|
+
packageCount: 0, // Unknown from old format
|
|
201
|
+
tierName: 'Unknown',
|
|
202
|
+
};
|
|
203
|
+
await this.saveSession(newSession);
|
|
204
|
+
// Optionally: rename old file to .bak
|
|
205
|
+
await fs.rename(oldCacheFile, oldCacheFile + '.migrated');
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
if (error.code === 'ENOENT') {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
// Log but don't fail on migration errors
|
|
213
|
+
console.error('Warning: Failed to migrate old cache:', error.message);
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=session-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../src/services/session-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DepFixer CLI Design System
|
|
3
|
+
*
|
|
4
|
+
* A consistent visual language for the premium "hacker-chic" CLI experience.
|
|
5
|
+
*/
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
export declare const colors: {
|
|
8
|
+
brand: import("chalk").ChalkInstance;
|
|
9
|
+
brandBold: import("chalk").ChalkInstance;
|
|
10
|
+
dim: import("chalk").ChalkInstance;
|
|
11
|
+
gray: import("chalk").ChalkInstance;
|
|
12
|
+
white: import("chalk").ChalkInstance;
|
|
13
|
+
whiteBold: import("chalk").ChalkInstance;
|
|
14
|
+
action: import("chalk").ChalkInstance;
|
|
15
|
+
actionBold: import("chalk").ChalkInstance;
|
|
16
|
+
success: import("chalk").ChalkInstance;
|
|
17
|
+
successBold: import("chalk").ChalkInstance;
|
|
18
|
+
danger: import("chalk").ChalkInstance;
|
|
19
|
+
dangerBold: import("chalk").ChalkInstance;
|
|
20
|
+
warning: import("chalk").ChalkInstance;
|
|
21
|
+
warningBold: import("chalk").ChalkInstance;
|
|
22
|
+
version: import("chalk").ChalkInstance;
|
|
23
|
+
versionOld: import("chalk").ChalkInstance;
|
|
24
|
+
major: import("chalk").ChalkInstance;
|
|
25
|
+
minor: import("chalk").ChalkInstance;
|
|
26
|
+
patch: import("chalk").ChalkInstance;
|
|
27
|
+
};
|
|
28
|
+
export declare function printCliHeader(mode?: 'analyze' | 'migrate'): void;
|
|
29
|
+
export declare function printSectionHeader(title: string, icon?: string): void;
|
|
30
|
+
export declare function renderHealthBar(score: number): string;
|
|
31
|
+
export declare function getHealthStatus(score: number): {
|
|
32
|
+
text: string;
|
|
33
|
+
color: typeof chalk;
|
|
34
|
+
};
|
|
35
|
+
export declare function printCostBox(options: {
|
|
36
|
+
cost: number;
|
|
37
|
+
tierName: string;
|
|
38
|
+
prompt?: string;
|
|
39
|
+
isMigration?: boolean;
|
|
40
|
+
hasActivePass?: boolean;
|
|
41
|
+
}): void;
|
|
42
|
+
export declare function printSuccessBox(options: {
|
|
43
|
+
updated: number;
|
|
44
|
+
removed: number;
|
|
45
|
+
backupPath: string;
|
|
46
|
+
enginesUpdated?: number;
|
|
47
|
+
}): void;
|
|
48
|
+
export declare function printProjectHeader(name: string, framework?: string, version?: string): void;
|
|
49
|
+
export declare function printMigrationPlanHeader(framework: string, fromVersion: string, toVersion: string): void;
|
|
50
|
+
export declare function printProjectionStats(options: {
|
|
51
|
+
currentHealth: number;
|
|
52
|
+
projectedHealth: number;
|
|
53
|
+
packageCount: number;
|
|
54
|
+
breakingChanges: number;
|
|
55
|
+
}): void;
|
|
56
|
+
export declare function printDiagnosis(issueCount: number): void;
|
|
57
|
+
export declare function printAccountInfo(options: {
|
|
58
|
+
name?: string;
|
|
59
|
+
email?: string;
|
|
60
|
+
credits: number;
|
|
61
|
+
}): void;
|
|
62
|
+
/**
|
|
63
|
+
* Print user details after login/register
|
|
64
|
+
* Shows name, email, and current credit balance
|
|
65
|
+
*/
|
|
66
|
+
export declare function printUserDetails(options: {
|
|
67
|
+
name?: string;
|
|
68
|
+
email?: string;
|
|
69
|
+
credits: number;
|
|
70
|
+
hasActivePass?: boolean;
|
|
71
|
+
showHeader?: boolean;
|
|
72
|
+
}): void;
|
|
73
|
+
/**
|
|
74
|
+
* Print credit check info showing both needed and available credits
|
|
75
|
+
*/
|
|
76
|
+
export declare function printCreditCheck(options: {
|
|
77
|
+
needed: number;
|
|
78
|
+
available: number;
|
|
79
|
+
hasActivePass?: boolean;
|
|
80
|
+
}): void;
|
|
81
|
+
export declare function printApplyingHeader(): void;
|
|
82
|
+
export declare function printAppliedChange(packageName: string, action: 'updated' | 'removed'): void;
|
|
83
|
+
export declare function printNotes(notes: string[]): void;
|
|
84
|
+
export declare function getSeverityBadge(severity: string): string;
|
|
85
|
+
export declare function getChangeTypeBadge(changeType: string): string;
|
|
86
|
+
/**
|
|
87
|
+
* Truncate text to max length with ellipsis
|
|
88
|
+
*/
|
|
89
|
+
export declare function truncateReason(text: string, maxLength?: number): string;
|
|
90
|
+
//# sourceMappingURL=design-system.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"design-system.d.ts","sourceRoot":"","sources":["../../src/utils/design-system.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DepFixer CLI Design System
|
|
3
|
+
*
|
|
4
|
+
* A consistent visual language for the premium "hacker-chic" CLI experience.
|
|
5
|
+
*/
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import boxen from 'boxen';
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// BRAND COLORS
|
|
10
|
+
// ============================================================================
|
|
11
|
+
export const colors = {
|
|
12
|
+
// Primary brand color (matches web logo)
|
|
13
|
+
brand: chalk.hex('#00D4FF'),
|
|
14
|
+
brandBold: chalk.bold.hex('#00D4FF'),
|
|
15
|
+
// Secondary
|
|
16
|
+
dim: chalk.dim,
|
|
17
|
+
gray: chalk.gray,
|
|
18
|
+
white: chalk.white,
|
|
19
|
+
whiteBold: chalk.bold.white,
|
|
20
|
+
// Actions
|
|
21
|
+
action: chalk.yellow,
|
|
22
|
+
actionBold: chalk.bold.yellow,
|
|
23
|
+
// Status
|
|
24
|
+
success: chalk.green,
|
|
25
|
+
successBold: chalk.bold.green,
|
|
26
|
+
danger: chalk.red,
|
|
27
|
+
dangerBold: chalk.bold.red,
|
|
28
|
+
warning: chalk.yellow,
|
|
29
|
+
warningBold: chalk.bold.yellow,
|
|
30
|
+
// Semantic
|
|
31
|
+
version: chalk.green,
|
|
32
|
+
versionOld: chalk.red,
|
|
33
|
+
major: chalk.red,
|
|
34
|
+
minor: chalk.yellow,
|
|
35
|
+
patch: chalk.blue,
|
|
36
|
+
};
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// HEADER
|
|
39
|
+
// ============================================================================
|
|
40
|
+
// ASCII art logo - DepFixer text (medium size)
|
|
41
|
+
function getDepFixerLogo(tagline) {
|
|
42
|
+
const c = chalk.hex('#00D4FF'); // cyan brand color
|
|
43
|
+
return `
|
|
44
|
+
${c('██████╗ ███████╗ ██████╗ ███████╗██╗██╗ ██╗███████╗██████╗')}
|
|
45
|
+
${c('██╔══██╗ ██╔════╝ ██╔══██╗██╔════╝██║╚██╗██╔╝██╔════╝██╔══██╗')}
|
|
46
|
+
${c('██║ ██║ █████╗ ██████╔╝█████╗ ██║ ╚███╔╝ █████╗ ██████╔╝')}
|
|
47
|
+
${c('██║ ██║ ██╔══╝ ██╔═══╝ ██╔══╝ ██║ ██╔██╗ ██╔══╝ ██╔══██╗')}
|
|
48
|
+
${c('██████╔╝ ███████╗ ██║ ██║ ██║██╔╝ ██╗███████╗██║ ██║')}
|
|
49
|
+
${c('╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝')}
|
|
50
|
+
${chalk.dim(' ' + tagline)}`;
|
|
51
|
+
}
|
|
52
|
+
export function printCliHeader(mode = 'analyze') {
|
|
53
|
+
const tagline = mode === 'migrate'
|
|
54
|
+
? 'Upgrade Fearlessly. We Handle the Rest.'
|
|
55
|
+
: 'Dependency Hell? We\'ve Got the Cure.';
|
|
56
|
+
console.log(getDepFixerLogo(tagline));
|
|
57
|
+
console.log();
|
|
58
|
+
console.log(colors.brandBold('⚡ DepFixer CLI') + colors.gray(' v1.0.0'));
|
|
59
|
+
console.log(colors.gray('─'.repeat(50)));
|
|
60
|
+
}
|
|
61
|
+
export function printSectionHeader(title, icon = '') {
|
|
62
|
+
console.log();
|
|
63
|
+
console.log(colors.whiteBold(`${icon ? icon + ' ' : ''}${title}`));
|
|
64
|
+
console.log(colors.gray('─'.repeat(50)));
|
|
65
|
+
}
|
|
66
|
+
// ============================================================================
|
|
67
|
+
// HEALTH BAR
|
|
68
|
+
// ============================================================================
|
|
69
|
+
export function renderHealthBar(score) {
|
|
70
|
+
const filled = Math.round(score / 10);
|
|
71
|
+
const empty = 10 - filled;
|
|
72
|
+
let barColor;
|
|
73
|
+
if (score >= 70) {
|
|
74
|
+
barColor = chalk.green;
|
|
75
|
+
}
|
|
76
|
+
else if (score >= 40) {
|
|
77
|
+
barColor = chalk.yellow;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
barColor = chalk.red;
|
|
81
|
+
}
|
|
82
|
+
const bar = barColor('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));
|
|
83
|
+
return `[${bar}]`;
|
|
84
|
+
}
|
|
85
|
+
export function getHealthStatus(score) {
|
|
86
|
+
// Thresholds aligned with renderHealthBar: green >= 70, yellow >= 40, red < 40
|
|
87
|
+
if (score >= 70)
|
|
88
|
+
return { text: 'HEALTHY', color: chalk.green };
|
|
89
|
+
if (score >= 40)
|
|
90
|
+
return { text: 'WARNING', color: chalk.yellow };
|
|
91
|
+
if (score >= 20)
|
|
92
|
+
return { text: 'POOR', color: chalk.red };
|
|
93
|
+
return { text: 'CRITICAL', color: chalk.red };
|
|
94
|
+
}
|
|
95
|
+
// ============================================================================
|
|
96
|
+
// COST BOX (The "Receipt")
|
|
97
|
+
// ============================================================================
|
|
98
|
+
export function printCostBox(options) {
|
|
99
|
+
const { cost, tierName, prompt, isMigration, hasActivePass } = options;
|
|
100
|
+
const label = isMigration ? 'MIGRATION COST' : 'COST TO ANALYZE';
|
|
101
|
+
const tierLabel = tierName.includes('Tier') ? tierName : `Tier: ${tierName}`;
|
|
102
|
+
let content;
|
|
103
|
+
if (hasActivePass) {
|
|
104
|
+
// Panic Pass - show unlimited access (gold theme)
|
|
105
|
+
content =
|
|
106
|
+
`🎫 PANIC PASS: ${chalk.yellow.bold('UNLIMITED ACCESS')}\n` +
|
|
107
|
+
`📦 PLAN SIZE: ${colors.white(tierLabel)}\n\n` +
|
|
108
|
+
`${colors.dim('No credits will be deducted.')}`;
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
content =
|
|
112
|
+
`💰 ${label}: ${colors.actionBold(`${cost} CREDITS`)}\n` +
|
|
113
|
+
`📦 PLAN SIZE: ${colors.white(tierLabel)}`;
|
|
114
|
+
}
|
|
115
|
+
console.log();
|
|
116
|
+
console.log(boxen(content, {
|
|
117
|
+
padding: 1,
|
|
118
|
+
margin: { top: 0, bottom: 0, left: 1, right: 1 },
|
|
119
|
+
borderStyle: 'round',
|
|
120
|
+
borderColor: hasActivePass ? 'yellow' : 'cyan',
|
|
121
|
+
}));
|
|
122
|
+
// Add prompt outside the box
|
|
123
|
+
if (prompt) {
|
|
124
|
+
console.log(colors.gray(`[?] ${prompt}`));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// ============================================================================
|
|
128
|
+
// SUCCESS BOX
|
|
129
|
+
// ============================================================================
|
|
130
|
+
export function printSuccessBox(options) {
|
|
131
|
+
const { updated, removed, backupPath, enginesUpdated } = options;
|
|
132
|
+
console.log();
|
|
133
|
+
console.log(colors.successBold('✨ SUCCESS'));
|
|
134
|
+
console.log(colors.gray('─'.repeat(50)));
|
|
135
|
+
console.log();
|
|
136
|
+
if (updated > 0) {
|
|
137
|
+
console.log(colors.success(` ✓ ${updated} Package${updated === 1 ? '' : 's'} Updated`));
|
|
138
|
+
}
|
|
139
|
+
if (removed > 0) {
|
|
140
|
+
console.log(colors.success(` ✓ ${removed} Package${removed === 1 ? '' : 's'} Removed`));
|
|
141
|
+
}
|
|
142
|
+
if (enginesUpdated && enginesUpdated > 0) {
|
|
143
|
+
console.log(colors.success(` ✓ ${enginesUpdated} Engine${enginesUpdated === 1 ? '' : 's'} Updated (Node.js/npm)`));
|
|
144
|
+
}
|
|
145
|
+
console.log(colors.success(` ✓ Backup: `) + colors.dim(backupPath));
|
|
146
|
+
console.log();
|
|
147
|
+
console.log(colors.actionBold(' 👉 NEXT STEP:'));
|
|
148
|
+
console.log(colors.dim(' Run the following command to finalize changes:'));
|
|
149
|
+
console.log();
|
|
150
|
+
console.log(` ${colors.brand('$ npm install')}`);
|
|
151
|
+
console.log();
|
|
152
|
+
}
|
|
153
|
+
// ============================================================================
|
|
154
|
+
// PROJECT INFO
|
|
155
|
+
// ============================================================================
|
|
156
|
+
export function printProjectHeader(name, framework, version) {
|
|
157
|
+
console.log();
|
|
158
|
+
console.log(colors.whiteBold(`📦 PROJECT: ${colors.brand(name)}`));
|
|
159
|
+
if (framework && version) {
|
|
160
|
+
console.log(colors.dim(` Framework: ${framework} ${version}`));
|
|
161
|
+
}
|
|
162
|
+
else if (framework) {
|
|
163
|
+
console.log(colors.dim(` Framework: ${framework}`));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// ============================================================================
|
|
167
|
+
// MIGRATION HEADER
|
|
168
|
+
// ============================================================================
|
|
169
|
+
export function printMigrationPlanHeader(framework, fromVersion, toVersion) {
|
|
170
|
+
console.log();
|
|
171
|
+
console.log(colors.brandBold(`🚀 MIGRATION PLAN: ${framework} ${fromVersion} → ${toVersion}`));
|
|
172
|
+
console.log(colors.gray('─'.repeat(50)));
|
|
173
|
+
}
|
|
174
|
+
// ============================================================================
|
|
175
|
+
// PROJECTION STATS
|
|
176
|
+
// ============================================================================
|
|
177
|
+
export function printProjectionStats(options) {
|
|
178
|
+
const { currentHealth, projectedHealth, packageCount, breakingChanges } = options;
|
|
179
|
+
console.log();
|
|
180
|
+
console.log(colors.whiteBold('📊 Projection:'));
|
|
181
|
+
const currentColor = currentHealth < 40 ? colors.danger : colors.warning;
|
|
182
|
+
const projectedColor = projectedHealth >= 70 ? colors.success : colors.warning;
|
|
183
|
+
console.log(` • Health: ${currentColor(`${currentHealth}/100`)} → ${projectedColor(`${projectedHealth}/100`)} (Estimated)`);
|
|
184
|
+
console.log(` • Packages: ${packageCount} updates`);
|
|
185
|
+
if (breakingChanges > 0) {
|
|
186
|
+
console.log(` • Breaking: ${colors.warning(`⚠️ ${breakingChanges} Major Change${breakingChanges > 1 ? 's' : ''}`)}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// ============================================================================
|
|
190
|
+
// DIAGNOSIS BOX
|
|
191
|
+
// ============================================================================
|
|
192
|
+
export function printDiagnosis(issueCount) {
|
|
193
|
+
console.log();
|
|
194
|
+
console.log(colors.whiteBold('💡 DIAGNOSIS:'));
|
|
195
|
+
console.log(colors.dim(' Deep dependency graph conflicts detected.'));
|
|
196
|
+
console.log(colors.dim(' Manual resolution is likely to fail.'));
|
|
197
|
+
console.log();
|
|
198
|
+
console.log(colors.whiteBold('🔒 SOLUTION:'));
|
|
199
|
+
console.log(colors.success(' ✓ Deterministic fix calculated.'));
|
|
200
|
+
console.log(colors.dim(' [?] Unlock recommended versions?'));
|
|
201
|
+
}
|
|
202
|
+
// ============================================================================
|
|
203
|
+
// ACCOUNT INFO
|
|
204
|
+
// ============================================================================
|
|
205
|
+
export function printAccountInfo(options) {
|
|
206
|
+
const { name, email, credits } = options;
|
|
207
|
+
console.log();
|
|
208
|
+
console.log(colors.whiteBold('👤 ACCOUNT'));
|
|
209
|
+
console.log(colors.gray('─'.repeat(40)));
|
|
210
|
+
if (name) {
|
|
211
|
+
console.log(` Name: ${colors.white(name)}`);
|
|
212
|
+
}
|
|
213
|
+
if (email) {
|
|
214
|
+
console.log(` Email: ${colors.brand(email)}`);
|
|
215
|
+
}
|
|
216
|
+
console.log(` Balance: ${colors.success(`${credits} credits`)}`);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Print user details after login/register
|
|
220
|
+
* Shows name, email, and current credit balance
|
|
221
|
+
*/
|
|
222
|
+
export function printUserDetails(options) {
|
|
223
|
+
const { name, email, credits, hasActivePass, showHeader = true } = options;
|
|
224
|
+
if (showHeader) {
|
|
225
|
+
console.log();
|
|
226
|
+
console.log(colors.successBold('✓ Logged in successfully'));
|
|
227
|
+
}
|
|
228
|
+
console.log();
|
|
229
|
+
console.log(colors.whiteBold('👤 ACCOUNT DETAILS'));
|
|
230
|
+
console.log(colors.gray('─'.repeat(40)));
|
|
231
|
+
if (name) {
|
|
232
|
+
console.log(` Name: ${colors.white(name)}`);
|
|
233
|
+
}
|
|
234
|
+
if (email) {
|
|
235
|
+
console.log(` Email: ${colors.brand(email)}`);
|
|
236
|
+
}
|
|
237
|
+
if (hasActivePass) {
|
|
238
|
+
console.log(` Plan: ${colors.success('24H Unlimited Pass')} ${colors.successBold('✓')}`);
|
|
239
|
+
}
|
|
240
|
+
console.log(` Credits: ${colors.actionBold(`${credits}`)} available`);
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Print credit check info showing both needed and available credits
|
|
244
|
+
*/
|
|
245
|
+
export function printCreditCheck(options) {
|
|
246
|
+
const { needed, available, hasActivePass } = options;
|
|
247
|
+
console.log();
|
|
248
|
+
console.log(colors.whiteBold('💳 CREDITS'));
|
|
249
|
+
console.log(colors.gray('─'.repeat(40)));
|
|
250
|
+
if (hasActivePass) {
|
|
251
|
+
console.log(` Plan: ${colors.success('24H Unlimited Pass')} ${colors.successBold('✓')}`);
|
|
252
|
+
console.log(` Cost: ${colors.dim('Covered by pass')}`);
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
console.log(` Available: ${colors.actionBold(`${available}`)} credits`);
|
|
256
|
+
console.log(` Needed: ${colors.white(`${needed}`)} credits`);
|
|
257
|
+
if (available >= needed) {
|
|
258
|
+
console.log(` Status: ${colors.success('Sufficient balance')} ${colors.successBold('✓')}`);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
console.log(` Status: ${colors.danger('Insufficient balance')} ${colors.dangerBold('✗')}`);
|
|
262
|
+
console.log(` Shortfall: ${colors.danger(`${needed - available}`)} credits`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// ============================================================================
|
|
267
|
+
// APPLYING CHANGES
|
|
268
|
+
// ============================================================================
|
|
269
|
+
export function printApplyingHeader() {
|
|
270
|
+
console.log();
|
|
271
|
+
console.log(colors.whiteBold('🔧 Applying Patches...'));
|
|
272
|
+
}
|
|
273
|
+
export function printAppliedChange(packageName, action) {
|
|
274
|
+
const icon = action === 'updated' ? colors.success('✔') : colors.danger('✗');
|
|
275
|
+
const actionText = action === 'updated' ? 'updated' : 'removed';
|
|
276
|
+
console.log(` ${icon} ${packageName} ${actionText}`);
|
|
277
|
+
}
|
|
278
|
+
// ============================================================================
|
|
279
|
+
// NOTES SECTION
|
|
280
|
+
// ============================================================================
|
|
281
|
+
export function printNotes(notes) {
|
|
282
|
+
if (notes.length === 0)
|
|
283
|
+
return;
|
|
284
|
+
console.log();
|
|
285
|
+
console.log(colors.whiteBold('💡 NOTES:'));
|
|
286
|
+
for (const note of notes) {
|
|
287
|
+
console.log(` ${colors.dim(note)}`);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
// ============================================================================
|
|
291
|
+
// SEVERITY BADGE
|
|
292
|
+
// ============================================================================
|
|
293
|
+
export function getSeverityBadge(severity) {
|
|
294
|
+
switch (severity?.toLowerCase()) {
|
|
295
|
+
case 'critical':
|
|
296
|
+
return colors.dangerBold('CRIT');
|
|
297
|
+
case 'high':
|
|
298
|
+
return colors.danger('HIGH');
|
|
299
|
+
case 'medium':
|
|
300
|
+
return colors.warning('MED ');
|
|
301
|
+
case 'low':
|
|
302
|
+
return colors.dim('LOW ');
|
|
303
|
+
default:
|
|
304
|
+
return colors.dim('INFO');
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
// ============================================================================
|
|
308
|
+
// CHANGE TYPE BADGE
|
|
309
|
+
// ============================================================================
|
|
310
|
+
export function getChangeTypeBadge(changeType) {
|
|
311
|
+
switch (changeType?.toLowerCase()) {
|
|
312
|
+
case 'major':
|
|
313
|
+
return colors.major('Major ⚠️');
|
|
314
|
+
case 'minor':
|
|
315
|
+
return colors.minor('Minor');
|
|
316
|
+
case 'patch':
|
|
317
|
+
return colors.patch('Patch');
|
|
318
|
+
case 'deprec':
|
|
319
|
+
case 'deprecated':
|
|
320
|
+
return colors.warning('Deprec.');
|
|
321
|
+
default:
|
|
322
|
+
return colors.dim(changeType || '');
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
// ============================================================================
|
|
326
|
+
// HELPERS
|
|
327
|
+
// ============================================================================
|
|
328
|
+
/**
|
|
329
|
+
* Truncate text to max length with ellipsis
|
|
330
|
+
*/
|
|
331
|
+
export function truncateReason(text, maxLength = 40) {
|
|
332
|
+
if (!text)
|
|
333
|
+
return '';
|
|
334
|
+
if (text.length <= maxLength)
|
|
335
|
+
return text;
|
|
336
|
+
return text.substring(0, maxLength - 3) + '...';
|
|
337
|
+
}
|
|
338
|
+
//# sourceMappingURL=design-system.js.map
|