depfixer 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +128 -0
- package/dist/commands/analyze.d.ts +18 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +404 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/fix.d.ts +14 -0
- package/dist/commands/fix.d.ts.map +1 -0
- package/dist/commands/fix.js +82 -0
- package/dist/commands/fix.js.map +1 -0
- package/dist/commands/graph.d.ts +12 -0
- package/dist/commands/graph.d.ts.map +1 -0
- package/dist/commands/graph.js +58 -0
- package/dist/commands/graph.js.map +1 -0
- package/dist/commands/login.d.ts +11 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +109 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +7 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +22 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +108 -0
- package/dist/index.js.map +1 -0
- package/dist/services/api-client.d.ts +89 -0
- package/dist/services/api-client.d.ts.map +1 -0
- package/dist/services/api-client.js +162 -0
- package/dist/services/api-client.js.map +1 -0
- package/dist/services/auth-manager.d.ts +30 -0
- package/dist/services/auth-manager.d.ts.map +1 -0
- package/dist/services/auth-manager.js +82 -0
- package/dist/services/auth-manager.js.map +1 -0
- package/dist/services/cache-manager.d.ts +52 -0
- package/dist/services/cache-manager.d.ts.map +1 -0
- package/dist/services/cache-manager.js +87 -0
- package/dist/services/cache-manager.js.map +1 -0
- package/dist/services/gitignore.d.ts +19 -0
- package/dist/services/gitignore.d.ts.map +1 -0
- package/dist/services/gitignore.js +64 -0
- package/dist/services/gitignore.js.map +1 -0
- package/dist/services/package-json.d.ts +39 -0
- package/dist/services/package-json.d.ts.map +1 -0
- package/dist/services/package-json.js +106 -0
- package/dist/services/package-json.js.map +1 -0
- package/dist/utils/hash.d.ts +6 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +9 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/output.d.ts +91 -0
- package/dist/utils/output.d.ts.map +1 -0
- package/dist/utils/output.js +222 -0
- package/dist/utils/output.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { AuthManager } from './auth-manager.js';
|
|
3
|
+
/**
|
|
4
|
+
* API Client for communicating with DepFixer server
|
|
5
|
+
*/
|
|
6
|
+
export class ApiClient {
|
|
7
|
+
client;
|
|
8
|
+
authManager;
|
|
9
|
+
constructor() {
|
|
10
|
+
const baseURL = process.env.DEPFIXER_API_URL || 'https://api.depfixer.com/api/v1';
|
|
11
|
+
const debug = process.env.DEPFIXER_DEBUG === 'true';
|
|
12
|
+
if (debug)
|
|
13
|
+
console.log('[DEBUG] API baseURL:', baseURL);
|
|
14
|
+
this.client = axios.create({
|
|
15
|
+
baseURL,
|
|
16
|
+
timeout: 30000,
|
|
17
|
+
headers: {
|
|
18
|
+
'Content-Type': 'application/json',
|
|
19
|
+
'User-Agent': 'depfixer-cli/1.0.0',
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
this.authManager = new AuthManager();
|
|
23
|
+
// Add auth interceptor
|
|
24
|
+
this.client.interceptors.request.use(async (config) => {
|
|
25
|
+
const token = await this.authManager.getAccessToken();
|
|
26
|
+
if (token) {
|
|
27
|
+
config.headers.Authorization = `Bearer ${token}`;
|
|
28
|
+
}
|
|
29
|
+
if (debug)
|
|
30
|
+
console.log('[DEBUG] Request:', config.method?.toUpperCase(), config.url);
|
|
31
|
+
return config;
|
|
32
|
+
});
|
|
33
|
+
// Add response error handler
|
|
34
|
+
this.client.interceptors.response.use((response) => {
|
|
35
|
+
if (debug)
|
|
36
|
+
console.log('[DEBUG] Response:', response.status, JSON.stringify(response.data).slice(0, 200));
|
|
37
|
+
return response;
|
|
38
|
+
}, (error) => {
|
|
39
|
+
if (debug) {
|
|
40
|
+
console.log('[DEBUG] Error:', error.response?.status, error.message);
|
|
41
|
+
console.log('[DEBUG] Error data:', JSON.stringify(error.response?.data));
|
|
42
|
+
}
|
|
43
|
+
return this.handleError(error);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Audit analysis (FREE - no auth required)
|
|
48
|
+
*/
|
|
49
|
+
async analyzeAudit(packageJson, framework) {
|
|
50
|
+
const debug = process.env.DEPFIXER_DEBUG === 'true';
|
|
51
|
+
if (debug) {
|
|
52
|
+
console.log('[DEBUG] analyzeAudit called');
|
|
53
|
+
console.log('[DEBUG] packageJson keys:', Object.keys(packageJson));
|
|
54
|
+
console.log('[DEBUG] framework:', framework);
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const response = await this.client.post('/cli/analyze/audit', {
|
|
58
|
+
packageJson,
|
|
59
|
+
framework,
|
|
60
|
+
});
|
|
61
|
+
return response.data;
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
if (debug) {
|
|
65
|
+
console.log('[DEBUG] analyzeAudit error:', err.message);
|
|
66
|
+
console.log('[DEBUG] full error:', JSON.stringify(err.response?.data || err, null, 2));
|
|
67
|
+
}
|
|
68
|
+
throw err;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Full analysis (PAID - auth required)
|
|
73
|
+
*/
|
|
74
|
+
async analyzeFull(packageJson, framework) {
|
|
75
|
+
if (!await this.authManager.isAuthenticated()) {
|
|
76
|
+
throw new Error('Authentication required. Run `npx depfixer login` first.');
|
|
77
|
+
}
|
|
78
|
+
const response = await this.client.post('/cli/analyze/full', {
|
|
79
|
+
packageJson,
|
|
80
|
+
framework,
|
|
81
|
+
});
|
|
82
|
+
return response.data;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Migration analysis (PAID - auth required)
|
|
86
|
+
*/
|
|
87
|
+
async analyzeMigrate(packageJson, targetVersion, framework) {
|
|
88
|
+
if (!await this.authManager.isAuthenticated()) {
|
|
89
|
+
throw new Error('Authentication required. Run `npx depfixer login` first.');
|
|
90
|
+
}
|
|
91
|
+
const response = await this.client.post('/cli/analyze/migrate', {
|
|
92
|
+
packageJson,
|
|
93
|
+
targetVersion,
|
|
94
|
+
framework,
|
|
95
|
+
});
|
|
96
|
+
return response.data;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Generate device code for login
|
|
100
|
+
*/
|
|
101
|
+
async createDeviceCode() {
|
|
102
|
+
const response = await this.client.post('/cli/auth/device-code');
|
|
103
|
+
return response.data;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Poll device code status
|
|
107
|
+
*/
|
|
108
|
+
async pollDeviceCode(deviceCode) {
|
|
109
|
+
const response = await this.client.get(`/cli/auth/device-poll/${deviceCode}`);
|
|
110
|
+
return response.data;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Poll prefetch status (uses existing analyze endpoint)
|
|
114
|
+
* CLI polls this until isComplete=true && reanalysisStatus='completed'
|
|
115
|
+
*/
|
|
116
|
+
async pollPrefetchStatus(prefetchId) {
|
|
117
|
+
const response = await this.client.get(`/analyze/prefetch-status/${prefetchId}`);
|
|
118
|
+
return response.data;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get analysis by ID (uses existing analyze endpoint)
|
|
122
|
+
* Called after prefetch completes to get updated results
|
|
123
|
+
*/
|
|
124
|
+
async getAnalysisById(analysisId) {
|
|
125
|
+
const response = await this.client.get(`/analyze/analysis/${analysisId}`);
|
|
126
|
+
return response.data;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Handle API errors
|
|
130
|
+
*/
|
|
131
|
+
handleError(error) {
|
|
132
|
+
if (error.response) {
|
|
133
|
+
const data = error.response.data;
|
|
134
|
+
const status = error.response.status;
|
|
135
|
+
// Handle specific error cases
|
|
136
|
+
if (status === 401) {
|
|
137
|
+
throw new Error('Authentication expired. Run `npx depfixer login` to re-authenticate.');
|
|
138
|
+
}
|
|
139
|
+
if (status === 403) {
|
|
140
|
+
if (data?.error === 'INSUFFICIENT_CREDITS') {
|
|
141
|
+
throw new Error('Insufficient credits. Purchase more at https://app.depfixer.com/pricing');
|
|
142
|
+
}
|
|
143
|
+
if (data?.error === 'RATE_LIMIT_EXCEEDED') {
|
|
144
|
+
throw new Error(`Rate limit exceeded. Try again in ${Math.ceil(data.retryAfter / 60)} minutes.`);
|
|
145
|
+
}
|
|
146
|
+
throw new Error(data?.message || 'Access forbidden');
|
|
147
|
+
}
|
|
148
|
+
if (status === 429) {
|
|
149
|
+
throw new Error('Too many requests. Please wait before trying again.');
|
|
150
|
+
}
|
|
151
|
+
throw new Error(data?.message || `API error: ${status}`);
|
|
152
|
+
}
|
|
153
|
+
if (error.code === 'ECONNREFUSED') {
|
|
154
|
+
throw new Error('Cannot connect to DepFixer server. Please check your internet connection.');
|
|
155
|
+
}
|
|
156
|
+
if (error.code === 'ETIMEDOUT') {
|
|
157
|
+
throw new Error('Request timed out. Please try again.');
|
|
158
|
+
}
|
|
159
|
+
throw new Error(error.message || 'Unknown error occurred');
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/services/api-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Manager
|
|
3
|
+
* Handles storing and retrieving authentication tokens
|
|
4
|
+
* Tokens are stored in ~/.depfixer/credentials.json
|
|
5
|
+
*/
|
|
6
|
+
export declare class AuthManager {
|
|
7
|
+
private credentialsPath;
|
|
8
|
+
constructor();
|
|
9
|
+
/**
|
|
10
|
+
* Check if user is authenticated
|
|
11
|
+
*/
|
|
12
|
+
isAuthenticated(): Promise<boolean>;
|
|
13
|
+
/**
|
|
14
|
+
* Get access token (returns null if not authenticated or expired)
|
|
15
|
+
*/
|
|
16
|
+
getAccessToken(): Promise<string | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Save authentication tokens
|
|
19
|
+
*/
|
|
20
|
+
saveTokens(accessToken: string, refreshToken: string, expiresIn: number): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Clear stored credentials (logout)
|
|
23
|
+
*/
|
|
24
|
+
clearCredentials(): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Read credentials from file
|
|
27
|
+
*/
|
|
28
|
+
private readCredentials;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=auth-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-manager.d.ts","sourceRoot":"","sources":["../../src/services/auth-manager.ts"],"names":[],"mappings":"AAUA;;;;GAIG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,eAAe,CAAS;;IAOhC;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAKzC;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAkB9C;;OAEG;IACG,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB7F;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAQvC;;OAEG;YACW,eAAe;CAQ9B"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import * as fs from 'fs/promises';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as os from 'os';
|
|
4
|
+
/**
|
|
5
|
+
* Auth Manager
|
|
6
|
+
* Handles storing and retrieving authentication tokens
|
|
7
|
+
* Tokens are stored in ~/.depfixer/credentials.json
|
|
8
|
+
*/
|
|
9
|
+
export class AuthManager {
|
|
10
|
+
credentialsPath;
|
|
11
|
+
constructor() {
|
|
12
|
+
const depfixerDir = path.join(os.homedir(), '.depfixer');
|
|
13
|
+
this.credentialsPath = path.join(depfixerDir, 'credentials.json');
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Check if user is authenticated
|
|
17
|
+
*/
|
|
18
|
+
async isAuthenticated() {
|
|
19
|
+
const token = await this.getAccessToken();
|
|
20
|
+
return !!token;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Get access token (returns null if not authenticated or expired)
|
|
24
|
+
*/
|
|
25
|
+
async getAccessToken() {
|
|
26
|
+
try {
|
|
27
|
+
const credentials = await this.readCredentials();
|
|
28
|
+
if (!credentials)
|
|
29
|
+
return null;
|
|
30
|
+
// Check if token is expired (with 5 minute buffer)
|
|
31
|
+
const bufferMs = 5 * 60 * 1000;
|
|
32
|
+
if (Date.now() > credentials.expiresAt - bufferMs) {
|
|
33
|
+
// Token expired - user needs to re-login
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
return credentials.accessToken;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Save authentication tokens
|
|
44
|
+
*/
|
|
45
|
+
async saveTokens(accessToken, refreshToken, expiresIn) {
|
|
46
|
+
const credentials = {
|
|
47
|
+
accessToken,
|
|
48
|
+
refreshToken,
|
|
49
|
+
expiresAt: Date.now() + expiresIn * 1000,
|
|
50
|
+
};
|
|
51
|
+
// Ensure directory exists
|
|
52
|
+
const dir = path.dirname(this.credentialsPath);
|
|
53
|
+
await fs.mkdir(dir, { recursive: true });
|
|
54
|
+
// Write credentials file with restricted permissions
|
|
55
|
+
await fs.writeFile(this.credentialsPath, JSON.stringify(credentials, null, 2), { mode: 0o600 } // Owner read/write only
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Clear stored credentials (logout)
|
|
60
|
+
*/
|
|
61
|
+
async clearCredentials() {
|
|
62
|
+
try {
|
|
63
|
+
await fs.unlink(this.credentialsPath);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
// File might not exist, that's fine
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Read credentials from file
|
|
71
|
+
*/
|
|
72
|
+
async readCredentials() {
|
|
73
|
+
try {
|
|
74
|
+
const data = await fs.readFile(this.credentialsPath, 'utf-8');
|
|
75
|
+
return JSON.parse(data);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=auth-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-manager.js","sourceRoot":"","sources":["../../src/services/auth-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAQzB;;;;GAIG;AACH,MAAM,OAAO,WAAW;IACd,eAAe,CAAS;IAEhC;QACE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;QACzD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;IACpE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe;QACnB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAC1C,OAAO,CAAC,CAAC,KAAK,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc;QAClB,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YACjD,IAAI,CAAC,WAAW;gBAAE,OAAO,IAAI,CAAC;YAE9B,mDAAmD;YACnD,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;YAC/B,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC,SAAS,GAAG,QAAQ,EAAE,CAAC;gBAClD,yCAAyC;gBACzC,OAAO,IAAI,CAAC;YACd,CAAC;YAED,OAAO,WAAW,CAAC,WAAW,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,WAAmB,EAAE,YAAoB,EAAE,SAAiB;QAC3E,MAAM,WAAW,GAAgB;YAC/B,WAAW;YACX,YAAY;YACZ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,IAAI;SACzC,CAAC;QAEF,0BAA0B;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC/C,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEzC,qDAAqD;QACrD,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,eAAe,EACpB,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EACpC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,wBAAwB;SACzC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB;QACpB,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,oCAAoC;QACtC,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,eAAe;QAC3B,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAgB,CAAC;QACzC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
interface CacheData {
|
|
2
|
+
timestamp: number;
|
|
3
|
+
originalFileHash: string;
|
|
4
|
+
framework?: string;
|
|
5
|
+
healthScore: number;
|
|
6
|
+
solution: {
|
|
7
|
+
dependencies: Record<string, string>;
|
|
8
|
+
devDependencies: Record<string, string>;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Cache Manager
|
|
13
|
+
* Handles local caching of analysis results for the fix command
|
|
14
|
+
*
|
|
15
|
+
* Cache is stored in .depfixer/last-run.json in the project directory
|
|
16
|
+
* Hash verification ensures fixes are only applied to unchanged package.json
|
|
17
|
+
*/
|
|
18
|
+
export declare class CacheManager {
|
|
19
|
+
private cacheDir;
|
|
20
|
+
private cacheFile;
|
|
21
|
+
constructor(projectDir?: string);
|
|
22
|
+
/**
|
|
23
|
+
* Save analysis result to cache
|
|
24
|
+
*/
|
|
25
|
+
saveCache(packageJsonContent: string, framework: string | undefined, healthScore: number, solution: {
|
|
26
|
+
dependencies: Record<string, string>;
|
|
27
|
+
devDependencies: Record<string, string>;
|
|
28
|
+
}): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Load cached analysis result
|
|
31
|
+
* Returns null if no cache exists
|
|
32
|
+
*/
|
|
33
|
+
loadCache(): Promise<CacheData | null>;
|
|
34
|
+
/**
|
|
35
|
+
* Verify that package.json hasn't changed since analysis
|
|
36
|
+
*/
|
|
37
|
+
verifyHash(packageJsonContent: string): Promise<boolean>;
|
|
38
|
+
/**
|
|
39
|
+
* Get cache file path (for display purposes)
|
|
40
|
+
*/
|
|
41
|
+
getCacheFilePath(): string;
|
|
42
|
+
/**
|
|
43
|
+
* Check if cache exists
|
|
44
|
+
*/
|
|
45
|
+
cacheExists(): Promise<boolean>;
|
|
46
|
+
/**
|
|
47
|
+
* Clear cache
|
|
48
|
+
*/
|
|
49
|
+
clearCache(): Promise<void>;
|
|
50
|
+
}
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=cache-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-manager.d.ts","sourceRoot":"","sources":["../../src/services/cache-manager.ts"],"names":[],"mappings":"AAIA,UAAU,SAAS;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE;QACR,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACzC,CAAC;CACH;AAED;;;;;;GAMG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;gBAEd,UAAU,GAAE,MAAsB;IAK9C;;OAEG;IACG,SAAS,CACb,kBAAkB,EAAE,MAAM,EAC1B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE;QACR,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACzC,GACA,OAAO,CAAC,IAAI,CAAC;IAoBhB;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAS5C;;OAEG;IACG,UAAU,CAAC,kBAAkB,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ9D;;OAEG;IACH,gBAAgB,IAAI,MAAM;IAI1B;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IASrC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAOlC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import * as fs from 'fs/promises';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { calculateHash } from '../utils/hash.js';
|
|
4
|
+
/**
|
|
5
|
+
* Cache Manager
|
|
6
|
+
* Handles local caching of analysis results for the fix command
|
|
7
|
+
*
|
|
8
|
+
* Cache is stored in .depfixer/last-run.json in the project directory
|
|
9
|
+
* Hash verification ensures fixes are only applied to unchanged package.json
|
|
10
|
+
*/
|
|
11
|
+
export class CacheManager {
|
|
12
|
+
cacheDir;
|
|
13
|
+
cacheFile;
|
|
14
|
+
constructor(projectDir = process.cwd()) {
|
|
15
|
+
this.cacheDir = path.join(projectDir, '.depfixer');
|
|
16
|
+
this.cacheFile = path.join(this.cacheDir, 'last-run.json');
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Save analysis result to cache
|
|
20
|
+
*/
|
|
21
|
+
async saveCache(packageJsonContent, framework, healthScore, solution) {
|
|
22
|
+
const cacheData = {
|
|
23
|
+
timestamp: Date.now(),
|
|
24
|
+
originalFileHash: calculateHash(packageJsonContent),
|
|
25
|
+
framework,
|
|
26
|
+
healthScore,
|
|
27
|
+
solution,
|
|
28
|
+
};
|
|
29
|
+
// Ensure directory exists
|
|
30
|
+
await fs.mkdir(this.cacheDir, { recursive: true });
|
|
31
|
+
// Write cache file
|
|
32
|
+
await fs.writeFile(this.cacheFile, JSON.stringify(cacheData, null, 2), 'utf-8');
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Load cached analysis result
|
|
36
|
+
* Returns null if no cache exists
|
|
37
|
+
*/
|
|
38
|
+
async loadCache() {
|
|
39
|
+
try {
|
|
40
|
+
const data = await fs.readFile(this.cacheFile, 'utf-8');
|
|
41
|
+
return JSON.parse(data);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Verify that package.json hasn't changed since analysis
|
|
49
|
+
*/
|
|
50
|
+
async verifyHash(packageJsonContent) {
|
|
51
|
+
const cache = await this.loadCache();
|
|
52
|
+
if (!cache)
|
|
53
|
+
return false;
|
|
54
|
+
const currentHash = calculateHash(packageJsonContent);
|
|
55
|
+
return currentHash === cache.originalFileHash;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get cache file path (for display purposes)
|
|
59
|
+
*/
|
|
60
|
+
getCacheFilePath() {
|
|
61
|
+
return this.cacheFile;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Check if cache exists
|
|
65
|
+
*/
|
|
66
|
+
async cacheExists() {
|
|
67
|
+
try {
|
|
68
|
+
await fs.access(this.cacheFile);
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Clear cache
|
|
77
|
+
*/
|
|
78
|
+
async clearCache() {
|
|
79
|
+
try {
|
|
80
|
+
await fs.unlink(this.cacheFile);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// File might not exist
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=cache-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-manager.js","sourceRoot":"","sources":["../../src/services/cache-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAajD;;;;;;GAMG;AACH,MAAM,OAAO,YAAY;IACf,QAAQ,CAAS;IACjB,SAAS,CAAS;IAE1B,YAAY,aAAqB,OAAO,CAAC,GAAG,EAAE;QAC5C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QACnD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IAC7D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS,CACb,kBAA0B,EAC1B,SAA6B,EAC7B,WAAmB,EACnB,QAGC;QAED,MAAM,SAAS,GAAc;YAC3B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,gBAAgB,EAAE,aAAa,CAAC,kBAAkB,CAAC;YACnD,SAAS;YACT,WAAW;YACX,QAAQ;SACT,CAAC;QAEF,0BAA0B;QAC1B,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEnD,mBAAmB;QACnB,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,EAClC,OAAO,CACR,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,SAAS;QACb,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YACxD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAc,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,kBAA0B;QACzC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACrC,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QAEzB,MAAM,WAAW,GAAG,aAAa,CAAC,kBAAkB,CAAC,CAAC;QACtD,OAAO,WAAW,KAAK,KAAK,CAAC,gBAAgB,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAChC,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU;QACd,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,uBAAuB;QACzB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gitignore Service
|
|
3
|
+
* Handles adding .depfixer/* to .gitignore
|
|
4
|
+
*/
|
|
5
|
+
export declare class GitignoreService {
|
|
6
|
+
private gitignorePath;
|
|
7
|
+
private pattern;
|
|
8
|
+
constructor(projectDir?: string);
|
|
9
|
+
/**
|
|
10
|
+
* Check if .depfixer/* is already in .gitignore
|
|
11
|
+
*/
|
|
12
|
+
isIgnored(): Promise<boolean>;
|
|
13
|
+
/**
|
|
14
|
+
* Add .depfixer/* to .gitignore if not already present
|
|
15
|
+
* Returns true if it was added, false if already present
|
|
16
|
+
*/
|
|
17
|
+
addToGitignore(): Promise<boolean>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=gitignore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitignore.d.ts","sourceRoot":"","sources":["../../src/services/gitignore.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,OAAO,CAAiB;gBAEpB,UAAU,GAAE,MAAsB;IAI9C;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAenC;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;CA+BzC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as fs from 'fs/promises';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Gitignore Service
|
|
5
|
+
* Handles adding .depfixer/* to .gitignore
|
|
6
|
+
*/
|
|
7
|
+
export class GitignoreService {
|
|
8
|
+
gitignorePath;
|
|
9
|
+
pattern = '.depfixer/*';
|
|
10
|
+
constructor(projectDir = process.cwd()) {
|
|
11
|
+
this.gitignorePath = path.join(projectDir, '.gitignore');
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Check if .depfixer/* is already in .gitignore
|
|
15
|
+
*/
|
|
16
|
+
async isIgnored() {
|
|
17
|
+
try {
|
|
18
|
+
const content = await fs.readFile(this.gitignorePath, 'utf-8');
|
|
19
|
+
const lines = content.split('\n').map(line => line.trim());
|
|
20
|
+
return lines.some(line => line === this.pattern ||
|
|
21
|
+
line === '.depfixer/' ||
|
|
22
|
+
line === '.depfixer');
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
// File doesn't exist
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Add .depfixer/* to .gitignore if not already present
|
|
31
|
+
* Returns true if it was added, false if already present
|
|
32
|
+
*/
|
|
33
|
+
async addToGitignore() {
|
|
34
|
+
const alreadyIgnored = await this.isIgnored();
|
|
35
|
+
if (alreadyIgnored) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
// Read existing content
|
|
40
|
+
let content = '';
|
|
41
|
+
try {
|
|
42
|
+
content = await fs.readFile(this.gitignorePath, 'utf-8');
|
|
43
|
+
// Ensure file ends with newline
|
|
44
|
+
if (!content.endsWith('\n')) {
|
|
45
|
+
content += '\n';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
// File doesn't exist, will create it
|
|
50
|
+
}
|
|
51
|
+
// Add our pattern with a comment
|
|
52
|
+
const addition = `\n# DepFixer cache\n${this.pattern}\n`;
|
|
53
|
+
content += addition;
|
|
54
|
+
// Write back
|
|
55
|
+
await fs.writeFile(this.gitignorePath, content, 'utf-8');
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
// Non-fatal - silently continue
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=gitignore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitignore.js","sourceRoot":"","sources":["../../src/services/gitignore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;;GAGG;AACH,MAAM,OAAO,gBAAgB;IACnB,aAAa,CAAS;IACtB,OAAO,GAAG,aAAa,CAAC;IAEhC,YAAY,aAAqB,OAAO,CAAC,GAAG,EAAE;QAC5C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAC3D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS;QACb,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;YAC/D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAC3D,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACvB,IAAI,KAAK,IAAI,CAAC,OAAO;gBACrB,IAAI,KAAK,YAAY;gBACrB,IAAI,KAAK,WAAW,CACrB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,qBAAqB;YACrB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,cAAc;QAClB,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QAC9C,IAAI,cAAc,EAAE,CAAC;YACnB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC;YACH,wBAAwB;YACxB,IAAI,OAAO,GAAG,EAAE,CAAC;YACjB,IAAI,CAAC;gBACH,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;gBACzD,gCAAgC;gBAChC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC5B,OAAO,IAAI,IAAI,CAAC;gBAClB,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,qCAAqC;YACvC,CAAC;YAED,iCAAiC;YACjC,MAAM,QAAQ,GAAG,uBAAuB,IAAI,CAAC,OAAO,IAAI,CAAC;YACzD,OAAO,IAAI,QAAQ,CAAC;YAEpB,aAAa;YACb,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YACzD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,gCAAgC;YAChC,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package.json Service
|
|
3
|
+
* Handles reading, sanitizing, and writing package.json files
|
|
4
|
+
*/
|
|
5
|
+
export declare class PackageJsonService {
|
|
6
|
+
/**
|
|
7
|
+
* Read package.json from directory
|
|
8
|
+
*/
|
|
9
|
+
read(dir?: string): Promise<{
|
|
10
|
+
content: string;
|
|
11
|
+
parsed: any;
|
|
12
|
+
path: string;
|
|
13
|
+
}>;
|
|
14
|
+
/**
|
|
15
|
+
* Sanitize package.json for sending to server
|
|
16
|
+
* Removes sensitive/irrelevant fields, keeps only dependency-related data
|
|
17
|
+
*/
|
|
18
|
+
sanitize(pkg: any): any;
|
|
19
|
+
/**
|
|
20
|
+
* Apply solution to package.json (creates package.json.fixed)
|
|
21
|
+
*/
|
|
22
|
+
applyFixes(dir: string, solution: {
|
|
23
|
+
dependencies: Record<string, string>;
|
|
24
|
+
devDependencies: Record<string, string>;
|
|
25
|
+
}): Promise<string>;
|
|
26
|
+
/**
|
|
27
|
+
* Get list of changes that would be applied
|
|
28
|
+
*/
|
|
29
|
+
getChanges(original: any, solution: {
|
|
30
|
+
dependencies: Record<string, string>;
|
|
31
|
+
devDependencies: Record<string, string>;
|
|
32
|
+
}): Array<{
|
|
33
|
+
package: string;
|
|
34
|
+
from: string;
|
|
35
|
+
to: string;
|
|
36
|
+
type: 'dependency' | 'devDependency';
|
|
37
|
+
}>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=package-json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-json.d.ts","sourceRoot":"","sources":["../../src/services/package-json.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,qBAAa,kBAAkB;IAC7B;;OAEG;IACG,IAAI,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC;QAC/C,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,GAAG,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IAkBF;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG;IAcvB;;OAEG;IACG,UAAU,CACd,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE;QACR,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACzC,GACA,OAAO,CAAC,MAAM,CAAC;IAiClB;;OAEG;IACH,UAAU,CACR,QAAQ,EAAE,GAAG,EACb,QAAQ,EAAE;QACR,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACzC,GACA,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,YAAY,GAAG,eAAe,CAAA;KAAE,CAAC;CAiC9F"}
|