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.
Files changed (85) hide show
  1. package/dist/commands/audit.d.ts +19 -0
  2. package/dist/commands/audit.d.ts.map +1 -0
  3. package/dist/commands/audit.js +170 -0
  4. package/dist/commands/audit.js.map +1 -0
  5. package/dist/commands/fix.d.ts +10 -3
  6. package/dist/commands/fix.d.ts.map +1 -1
  7. package/dist/commands/fix.js +407 -41
  8. package/dist/commands/fix.js.map +1 -1
  9. package/dist/commands/graph.d.ts +1 -1
  10. package/dist/commands/graph.d.ts.map +1 -1
  11. package/dist/commands/graph.js +17 -12
  12. package/dist/commands/graph.js.map +1 -1
  13. package/dist/commands/login.d.ts.map +1 -1
  14. package/dist/commands/login.js +120 -19
  15. package/dist/commands/login.js.map +1 -1
  16. package/dist/commands/logout.d.ts.map +1 -1
  17. package/dist/commands/logout.js +6 -0
  18. package/dist/commands/logout.js.map +1 -1
  19. package/dist/commands/migrate.d.ts +22 -0
  20. package/dist/commands/migrate.d.ts.map +1 -0
  21. package/dist/commands/migrate.js +874 -0
  22. package/dist/commands/migrate.js.map +1 -0
  23. package/dist/commands/smart.d.ts +23 -0
  24. package/dist/commands/smart.d.ts.map +1 -0
  25. package/dist/commands/smart.js +1024 -0
  26. package/dist/commands/smart.js.map +1 -0
  27. package/dist/commands/whoami.d.ts +14 -0
  28. package/dist/commands/whoami.d.ts.map +1 -0
  29. package/dist/commands/whoami.js +65 -0
  30. package/dist/commands/whoami.js.map +1 -0
  31. package/dist/index.js +165 -40
  32. package/dist/index.js.map +1 -1
  33. package/dist/services/analytics.d.ts +108 -0
  34. package/dist/services/analytics.d.ts.map +1 -0
  35. package/dist/services/analytics.js +305 -0
  36. package/dist/services/analytics.js.map +1 -0
  37. package/dist/services/api-client.d.ts +159 -0
  38. package/dist/services/api-client.d.ts.map +1 -1
  39. package/dist/services/api-client.js +192 -10
  40. package/dist/services/api-client.js.map +1 -1
  41. package/dist/services/auth-manager.d.ts +14 -0
  42. package/dist/services/auth-manager.d.ts.map +1 -1
  43. package/dist/services/auth-manager.js +30 -0
  44. package/dist/services/auth-manager.js.map +1 -1
  45. package/dist/services/cache-manager.d.ts +62 -22
  46. package/dist/services/cache-manager.d.ts.map +1 -1
  47. package/dist/services/cache-manager.js +116 -30
  48. package/dist/services/cache-manager.js.map +1 -1
  49. package/dist/services/device-id.d.ts +20 -0
  50. package/dist/services/device-id.d.ts.map +1 -0
  51. package/dist/services/device-id.js +70 -0
  52. package/dist/services/device-id.js.map +1 -0
  53. package/dist/services/package-json.d.ts +44 -5
  54. package/dist/services/package-json.d.ts.map +1 -1
  55. package/dist/services/package-json.js +273 -20
  56. package/dist/services/package-json.js.map +1 -1
  57. package/dist/services/payment-flow.d.ts +108 -0
  58. package/dist/services/payment-flow.d.ts.map +1 -0
  59. package/dist/services/payment-flow.js +476 -0
  60. package/dist/services/payment-flow.js.map +1 -0
  61. package/dist/services/session-manager.d.ts +92 -0
  62. package/dist/services/session-manager.d.ts.map +1 -0
  63. package/dist/services/session-manager.js +218 -0
  64. package/dist/services/session-manager.js.map +1 -0
  65. package/dist/utils/design-system.d.ts +90 -0
  66. package/dist/utils/design-system.d.ts.map +1 -0
  67. package/dist/utils/design-system.js +338 -0
  68. package/dist/utils/design-system.js.map +1 -0
  69. package/dist/utils/output.d.ts +48 -1
  70. package/dist/utils/output.d.ts.map +1 -1
  71. package/dist/utils/output.js +180 -17
  72. package/dist/utils/output.js.map +1 -1
  73. package/dist/utils/print.d.ts +116 -0
  74. package/dist/utils/print.d.ts.map +1 -0
  75. package/dist/utils/print.js +190 -0
  76. package/dist/utils/print.js.map +1 -0
  77. package/package.json +13 -2
  78. package/dist/commands/analyze.d.ts +0 -18
  79. package/dist/commands/analyze.d.ts.map +0 -1
  80. package/dist/commands/analyze.js +0 -404
  81. package/dist/commands/analyze.js.map +0 -1
  82. package/dist/services/gitignore.d.ts +0 -19
  83. package/dist/services/gitignore.d.ts.map +0 -1
  84. package/dist/services/gitignore.js +0 -64
  85. package/dist/services/gitignore.js.map +0 -1
@@ -1,58 +1,108 @@
1
1
  import * as fs from 'fs/promises';
2
2
  import * as path from 'path';
3
+ import * as os from 'os';
4
+ import * as crypto from 'crypto';
3
5
  import { calculateHash } from '../utils/hash.js';
4
6
  /**
5
7
  * Cache Manager
6
- * Handles local caching of analysis results for the fix command
8
+ * Handles local caching of analysis history for the fix command
7
9
  *
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
+ * Cache is stored in ~/.depfixer/projects/{projectHash}/analysis-history.json
11
+ * Stores history of all analyses - solution is fetched from server when fixing
12
+ * Centralized storage (no .depfixer in project directory)
10
13
  */
11
14
  export class CacheManager {
12
15
  cacheDir;
13
16
  cacheFile;
17
+ maxEntries = 20; // Keep last 20 analyses
18
+ projectDir;
14
19
  constructor(projectDir = process.cwd()) {
15
- this.cacheDir = path.join(projectDir, '.depfixer');
16
- this.cacheFile = path.join(this.cacheDir, 'last-run.json');
20
+ this.projectDir = projectDir;
21
+ // Use centralized ~/.depfixer/projects/{hash}/ directory
22
+ const projectHash = this.getProjectHash(projectDir);
23
+ this.cacheDir = path.join(os.homedir(), '.depfixer', 'projects', projectHash);
24
+ this.cacheFile = path.join(this.cacheDir, 'analysis-history.json');
17
25
  }
18
26
  /**
19
- * Save analysis result to cache
27
+ * Generate a short hash from project path for unique folder name
20
28
  */
21
- async saveCache(packageJsonContent, framework, healthScore, solution) {
22
- const cacheData = {
29
+ getProjectHash(projectDir) {
30
+ // Normalize path and create hash
31
+ const normalizedPath = path.resolve(projectDir).toLowerCase();
32
+ return crypto.createHash('sha256').update(normalizedPath).digest('hex').substring(0, 12);
33
+ }
34
+ /**
35
+ * Add analysis to history
36
+ * Stores analysisId, projectName, and hash - no solution content
37
+ */
38
+ async saveAnalysis(packageJsonContent, analysisId, projectName, mode, targetVersion) {
39
+ const history = await this.loadHistory();
40
+ const entry = {
41
+ analysisId,
42
+ projectName,
43
+ packageJsonHash: calculateHash(packageJsonContent),
23
44
  timestamp: Date.now(),
24
- originalFileHash: calculateHash(packageJsonContent),
25
- framework,
26
- healthScore,
27
- solution,
45
+ mode,
46
+ targetVersion,
47
+ projectPath: this.projectDir, // Store project path for reference
28
48
  };
49
+ // Add to beginning (most recent first)
50
+ history.entries.unshift(entry);
51
+ // Keep only last N entries
52
+ if (history.entries.length > this.maxEntries) {
53
+ history.entries = history.entries.slice(0, this.maxEntries);
54
+ }
29
55
  // Ensure directory exists
30
56
  await fs.mkdir(this.cacheDir, { recursive: true });
31
57
  // Write cache file
32
- await fs.writeFile(this.cacheFile, JSON.stringify(cacheData, null, 2), 'utf-8');
58
+ await fs.writeFile(this.cacheFile, JSON.stringify(history, null, 2), 'utf-8');
33
59
  }
34
60
  /**
35
- * Load cached analysis result
36
- * Returns null if no cache exists
61
+ * Load analysis history
37
62
  */
38
- async loadCache() {
63
+ async loadHistory() {
39
64
  try {
40
65
  const data = await fs.readFile(this.cacheFile, 'utf-8');
41
66
  return JSON.parse(data);
42
67
  }
43
68
  catch (error) {
44
- return null;
69
+ return { entries: [] };
45
70
  }
46
71
  }
72
+ /**
73
+ * Get the latest analysis entry
74
+ * Returns null if no history exists
75
+ */
76
+ async getLatestAnalysis() {
77
+ const history = await this.loadHistory();
78
+ return history.entries.length > 0 ? history.entries[0] : null;
79
+ }
80
+ /**
81
+ * Get analysis by ID
82
+ * Returns null if not found
83
+ */
84
+ async getAnalysisById(analysisId) {
85
+ const history = await this.loadHistory();
86
+ return history.entries.find(e => e.analysisId === analysisId) || null;
87
+ }
88
+ /**
89
+ * Get all analyses (for listing)
90
+ */
91
+ async getAllAnalyses() {
92
+ const history = await this.loadHistory();
93
+ return history.entries;
94
+ }
47
95
  /**
48
96
  * Verify that package.json hasn't changed since analysis
49
97
  */
50
- async verifyHash(packageJsonContent) {
51
- const cache = await this.loadCache();
52
- if (!cache)
98
+ async verifyHash(packageJsonContent, analysisId) {
99
+ const entry = analysisId
100
+ ? await this.getAnalysisById(analysisId)
101
+ : await this.getLatestAnalysis();
102
+ if (!entry)
53
103
  return false;
54
104
  const currentHash = calculateHash(packageJsonContent);
55
- return currentHash === cache.originalFileHash;
105
+ return currentHash === entry.packageJsonHash;
56
106
  }
57
107
  /**
58
108
  * Get cache file path (for display purposes)
@@ -61,27 +111,63 @@ export class CacheManager {
61
111
  return this.cacheFile;
62
112
  }
63
113
  /**
64
- * Check if cache exists
114
+ * Check if any analysis history exists
65
115
  */
66
- async cacheExists() {
116
+ async hasHistory() {
117
+ const history = await this.loadHistory();
118
+ return history.entries.length > 0;
119
+ }
120
+ /**
121
+ * Clear all history
122
+ */
123
+ async clearHistory() {
67
124
  try {
68
- await fs.access(this.cacheFile);
69
- return true;
125
+ await fs.unlink(this.cacheFile);
70
126
  }
71
127
  catch {
72
- return false;
128
+ // File might not exist
73
129
  }
74
130
  }
131
+ // Legacy compatibility methods (for backward compatibility)
75
132
  /**
76
- * Clear cache
133
+ * @deprecated Use saveAnalysis instead
77
134
  */
78
- async clearCache() {
135
+ async saveCache(packageJsonContent, analysisId) {
136
+ // Extract project name from package.json
137
+ let projectName = 'unknown';
79
138
  try {
80
- await fs.unlink(this.cacheFile);
139
+ const parsed = JSON.parse(packageJsonContent);
140
+ projectName = parsed.name || 'unknown';
81
141
  }
82
142
  catch {
83
- // File might not exist
143
+ // Ignore parse errors
84
144
  }
145
+ await this.saveAnalysis(packageJsonContent, analysisId, projectName, 'full');
146
+ }
147
+ /**
148
+ * @deprecated Use getLatestAnalysis instead
149
+ */
150
+ async loadCache() {
151
+ const latest = await this.getLatestAnalysis();
152
+ if (!latest)
153
+ return null;
154
+ return {
155
+ analysisId: latest.analysisId,
156
+ originalFileHash: latest.packageJsonHash,
157
+ timestamp: latest.timestamp,
158
+ };
159
+ }
160
+ /**
161
+ * @deprecated Use hasHistory instead
162
+ */
163
+ async cacheExists() {
164
+ return this.hasHistory();
165
+ }
166
+ /**
167
+ * @deprecated Use clearHistory instead
168
+ */
169
+ async clearCache() {
170
+ return this.clearHistory();
85
171
  }
86
172
  }
87
173
  //# sourceMappingURL=cache-manager.js.map
@@ -1 +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"}
1
+ {"version":3,"file":"cache-manager.js","sourceRoot":"","sources":["../../src/services/cache-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ interface DeviceData {
2
+ deviceId: string;
3
+ createdAt: string;
4
+ }
5
+ /**
6
+ * Get or generate the device ID.
7
+ * Creates ~/.depfixer/device.json if it doesn't exist.
8
+ *
9
+ * @returns The persistent device ID for this machine
10
+ */
11
+ export declare function getDeviceId(): string;
12
+ /**
13
+ * Get device info including creation date.
14
+ * Useful for debugging and admin display.
15
+ *
16
+ * @returns Device data or null if not found
17
+ */
18
+ export declare function getDeviceInfo(): DeviceData | null;
19
+ export {};
20
+ //# sourceMappingURL=device-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-id.d.ts","sourceRoot":"","sources":["../../src/services/device-id.ts"],"names":[],"mappings":"AAuBA,UAAU,UAAU;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,IAAI,MAAM,CA4BpC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,UAAU,GAAG,IAAI,CAUjD"}
@@ -0,0 +1,70 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as os from 'os';
4
+ import * as crypto from 'crypto';
5
+ /**
6
+ * Device ID Service
7
+ *
8
+ * Generates and persists a unique device identifier in the user's home directory.
9
+ * This ID is used to track anonymous CLI audits and link them to a user account
10
+ * when they log in.
11
+ *
12
+ * Storage: ~/.depfixer/device.json (same location as credentials)
13
+ * - Same device ID for ALL projects on this machine
14
+ * - Persists across CLI sessions
15
+ * - Enables conversion funnel tracking
16
+ */
17
+ // Store in USER HOME directory (same location as credentials)
18
+ // ~/.depfixer/device.json on Unix, C:\Users\xxx\.depfixer\device.json on Windows
19
+ const CONFIG_DIR = path.join(os.homedir(), '.depfixer');
20
+ const DEVICE_FILE = path.join(CONFIG_DIR, 'device.json');
21
+ /**
22
+ * Get or generate the device ID.
23
+ * Creates ~/.depfixer/device.json if it doesn't exist.
24
+ *
25
+ * @returns The persistent device ID for this machine
26
+ */
27
+ export function getDeviceId() {
28
+ // Ensure config dir exists
29
+ if (!fs.existsSync(CONFIG_DIR)) {
30
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
31
+ }
32
+ // Read existing device ID
33
+ if (fs.existsSync(DEVICE_FILE)) {
34
+ try {
35
+ const data = JSON.parse(fs.readFileSync(DEVICE_FILE, 'utf-8'));
36
+ if (data.deviceId) {
37
+ return data.deviceId;
38
+ }
39
+ }
40
+ catch {
41
+ // File corrupted, regenerate
42
+ }
43
+ }
44
+ // Generate new device ID
45
+ const deviceId = `dev_${crypto.randomUUID()}`;
46
+ const deviceData = {
47
+ deviceId,
48
+ createdAt: new Date().toISOString(),
49
+ };
50
+ fs.writeFileSync(DEVICE_FILE, JSON.stringify(deviceData, null, 2));
51
+ return deviceId;
52
+ }
53
+ /**
54
+ * Get device info including creation date.
55
+ * Useful for debugging and admin display.
56
+ *
57
+ * @returns Device data or null if not found
58
+ */
59
+ export function getDeviceInfo() {
60
+ if (!fs.existsSync(DEVICE_FILE)) {
61
+ return null;
62
+ }
63
+ try {
64
+ return JSON.parse(fs.readFileSync(DEVICE_FILE, 'utf-8'));
65
+ }
66
+ catch {
67
+ return null;
68
+ }
69
+ }
70
+ //# sourceMappingURL=device-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-id.js","sourceRoot":"","sources":["../../src/services/device-id.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAEjC;;;;;;;;;;;GAWG;AAEH,8DAA8D;AAC9D,iFAAiF;AACjF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AACxD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAOzD;;;;;GAKG;AACH,MAAM,UAAU,WAAW;IACzB,2BAA2B;IAC3B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,0BAA0B;IAC1B,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,IAAI,GAAe,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;YAC3E,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,OAAO,IAAI,CAAC,QAAQ,CAAC;YACvB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,6BAA6B;QAC/B,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,MAAM,QAAQ,GAAG,OAAO,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC;IAC9C,MAAM,UAAU,GAAe;QAC7B,QAAQ;QACR,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IAEF,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAEnE,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa;IAC3B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -17,14 +17,53 @@ export declare class PackageJsonService {
17
17
  */
18
18
  sanitize(pkg: any): any;
19
19
  /**
20
- * Apply solution to package.json (creates package.json.fixed)
20
+ * Apply surgical fixes to package.json
21
+ * Only modifies version strings, preserves all formatting
22
+ * Creates backup before modifying
23
+ * Also handles package removals (deprecated packages) and engine updates
21
24
  */
22
- applyFixes(dir: string, solution: {
23
- dependencies: Record<string, string>;
24
- devDependencies: Record<string, string>;
25
- }): Promise<string>;
25
+ applySurgicalFixes(dir: string, changes: Array<{
26
+ package: string;
27
+ from: string;
28
+ to: string;
29
+ type: 'dependency' | 'devDependency';
30
+ }>, removals?: Array<{
31
+ package: string;
32
+ reason: string;
33
+ type: 'dependency' | 'devDependency';
34
+ }>, engines?: {
35
+ node?: string;
36
+ npm?: string;
37
+ }): Promise<{
38
+ backupPath: string;
39
+ applied: number;
40
+ removed: number;
41
+ enginesUpdated: number;
42
+ }>;
43
+ /**
44
+ * Replace a package version within a specific section of package.json
45
+ * Preserves all formatting and only changes the version string
46
+ */
47
+ private replaceVersionInSection;
48
+ /**
49
+ * Remove a package entry from a specific section of package.json
50
+ * Preserves all formatting and removes only the package line
51
+ */
52
+ private removePackageFromSection;
53
+ /**
54
+ * Update or add engines section in package.json
55
+ * Preserves formatting when updating existing engines
56
+ * Adds engines section after version field if not present
57
+ */
58
+ private updateEngines;
59
+ /**
60
+ * Write a modified package.json to package.json.fixed
61
+ * Preserves original file, allows user to review before applying
62
+ */
63
+ writeFixed(dir: string, packageJson: any): Promise<string>;
26
64
  /**
27
65
  * Get list of changes that would be applied
66
+ * Skips unknown versions and REMOVE versions (matches web algorithm)
28
67
  */
29
68
  getChanges(original: any, solution: {
30
69
  dependencies: Record<string, string>;
@@ -1 +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"}
1
+ {"version":3,"file":"package-json.d.ts","sourceRoot":"","sources":["../../src/services/package-json.ts"],"names":[],"mappings":"AAIA;;;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;;;;;OAKG;IACG,kBAAkB,CACtB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,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,EACnG,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,YAAY,GAAG,eAAe,CAAA;KAAE,CAAC,EAC3F,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GACxC,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IA+C5F;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IA8D/B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IA+DhC;;;;OAIG;IACH,OAAO,CAAC,aAAa;IA4HrB;;;OAGG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;IAOhE;;;OAGG;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;CA2C9F"}