@sudu-cli/fronted-preview-mcp 1.0.0-beta.4 → 1.0.0-beta.5
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/handlers/autoFixLoop.d.ts +3 -10
- package/dist/handlers/autoFixLoop.js +10 -49
- package/dist/handlers/autoFixLoop.js.map +1 -1
- package/dist/handlers/typescriptDiagnostics.d.ts +9 -0
- package/dist/strategies/baseStrategy.d.ts +27 -0
- package/dist/strategies/baseStrategy.js +23 -0
- package/dist/strategies/baseStrategy.js.map +1 -0
- package/dist/strategies/index.d.ts +9 -0
- package/dist/strategies/index.js +22 -0
- package/dist/strategies/index.js.map +1 -0
- package/dist/strategies/missingImport.d.ts +16 -0
- package/dist/strategies/missingImport.js +156 -0
- package/dist/strategies/missingImport.js.map +1 -0
- package/dist/strategies/missingProperty.d.ts +13 -0
- package/dist/strategies/missingProperty.js +134 -0
- package/dist/strategies/missingProperty.js.map +1 -0
- package/dist/strategies/networkError.d.ts +10 -0
- package/dist/strategies/networkError.js +56 -0
- package/dist/strategies/networkError.js.map +1 -0
- package/dist/strategies/nullCheckInsertion.d.ts +14 -0
- package/dist/strategies/nullCheckInsertion.js +138 -0
- package/dist/strategies/nullCheckInsertion.js.map +1 -0
- package/dist/strategies/typeAssignment.d.ts +13 -0
- package/dist/strategies/typeAssignment.js +121 -0
- package/dist/strategies/typeAssignment.js.map +1 -0
- package/dist/strategies/unusedImportRemoval.d.ts +11 -0
- package/dist/strategies/unusedImportRemoval.js +138 -0
- package/dist/strategies/unusedImportRemoval.js.map +1 -0
- package/package.json +1 -1
|
@@ -2,7 +2,8 @@ import { ToolContext } from '../types.js';
|
|
|
2
2
|
export interface FixStrategy {
|
|
3
3
|
errorType: 'typescript' | 'console' | 'network';
|
|
4
4
|
pattern: RegExp;
|
|
5
|
-
|
|
5
|
+
canFix(error: any): boolean;
|
|
6
|
+
fix(context: any, error: any): Promise<FixResult>;
|
|
6
7
|
}
|
|
7
8
|
export interface FixResult {
|
|
8
9
|
success: boolean;
|
|
@@ -29,20 +30,12 @@ export interface AutoFixResult {
|
|
|
29
30
|
errors: string[];
|
|
30
31
|
fixesApplied: FixResult[];
|
|
31
32
|
}
|
|
32
|
-
interface ConsoleError {
|
|
33
|
+
export interface ConsoleError {
|
|
33
34
|
type: string;
|
|
34
35
|
message: string;
|
|
35
36
|
url?: string;
|
|
36
37
|
lineNumber?: number;
|
|
37
38
|
stackTrace?: string;
|
|
38
39
|
}
|
|
39
|
-
interface TSDiagnostic {
|
|
40
|
-
message: string;
|
|
41
|
-
severity: string;
|
|
42
|
-
file?: string;
|
|
43
|
-
line?: number;
|
|
44
|
-
column?: number;
|
|
45
|
-
}
|
|
46
40
|
export declare function autoFixLoop(context: ToolContext, options?: AutoFixOptions): Promise<AutoFixResult>;
|
|
47
41
|
export declare function handleAutoFixLoop(context: ToolContext, options?: AutoFixOptions): Promise<AutoFixResult>;
|
|
48
|
-
export {};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { handleCheckPageErrors } from './checkPageErrors.js';
|
|
2
2
|
import { handleGetTypeScriptDiagnostics } from './typescriptDiagnostics.js';
|
|
3
3
|
import { TIMEOUTS } from '../constants.js';
|
|
4
|
+
import { createFixContext, defaultFixStrategies } from '../strategies/index.js';
|
|
5
|
+
import * as path from 'node:path';
|
|
4
6
|
function parseCheckPageErrorsResponse(response) {
|
|
5
7
|
try {
|
|
6
8
|
const text = response.content[0]?.text || '{}';
|
|
@@ -38,58 +40,13 @@ export async function autoFixLoop(context, options = {}) {
|
|
|
38
40
|
errors: [],
|
|
39
41
|
fixesApplied: []
|
|
40
42
|
};
|
|
41
|
-
//
|
|
42
|
-
const defaultStrategies =
|
|
43
|
-
{
|
|
44
|
-
errorType: 'typescript',
|
|
45
|
-
pattern: /Unused variable|unused import/i,
|
|
46
|
-
fix: async (ctx, error) => {
|
|
47
|
-
// Remove unused imports/variables via ts-morph
|
|
48
|
-
return { success: false, message: 'Unused import removal requires ts-morph integration' };
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
errorType: 'typescript',
|
|
53
|
-
pattern: /Property '(.+)' does not exist on type/i,
|
|
54
|
-
fix: async (ctx, error) => {
|
|
55
|
-
// Suggest adding missing property or type assertion
|
|
56
|
-
return { success: false, message: 'Missing property fix requires AST manipulation' };
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
errorType: 'typescript',
|
|
61
|
-
pattern: /Type '(.+)' is not assignable to type/i,
|
|
62
|
-
fix: async (ctx, error) => {
|
|
63
|
-
return { success: false, message: 'Type assignment fix requires type inference' };
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
errorType: 'console',
|
|
68
|
-
pattern: /Cannot read propert(?:y|ies) of (?:null|undefined)/i,
|
|
69
|
-
fix: async (ctx, error) => {
|
|
70
|
-
return { success: false, message: 'Null check insertion requires AST analysis' };
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
errorType: 'console',
|
|
75
|
-
pattern: /is not defined/i,
|
|
76
|
-
fix: async (ctx, error) => {
|
|
77
|
-
return { success: false, message: 'Missing import/definition fix requires module analysis' };
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
errorType: 'network',
|
|
82
|
-
pattern: /Failed to fetch|Network Error|ECONNREFUSED/i,
|
|
83
|
-
fix: async (ctx, error) => {
|
|
84
|
-
return { success: false, message: 'Network errors typically require backend/server fixes' };
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
];
|
|
43
|
+
// Use real fix strategies instead of stubs
|
|
44
|
+
const defaultStrategies = defaultFixStrategies;
|
|
88
45
|
const strategies = [...defaultStrategies, ...fixStrategies];
|
|
89
46
|
// Helper to find matching strategy
|
|
90
47
|
const findStrategy = (error) => {
|
|
91
48
|
const errorMsg = error.message || String(error);
|
|
92
|
-
return strategies.find(s => s.pattern.test(errorMsg));
|
|
49
|
+
return strategies.find(s => s.pattern.test(errorMsg) && s.canFix(error));
|
|
93
50
|
};
|
|
94
51
|
// Helper to apply fix strategies
|
|
95
52
|
const applyFixes = async (errors) => {
|
|
@@ -98,7 +55,11 @@ export async function autoFixLoop(context, options = {}) {
|
|
|
98
55
|
const strategy = findStrategy(error);
|
|
99
56
|
if (strategy && fixAction !== 'none') {
|
|
100
57
|
try {
|
|
101
|
-
|
|
58
|
+
// Create fix context for ts-morph strategies
|
|
59
|
+
const projectDir = context.projectDir || process.cwd();
|
|
60
|
+
const tsConfigPath = path.resolve(projectDir, 'tsconfig.json');
|
|
61
|
+
const fixContext = createFixContext(projectDir, tsConfigPath);
|
|
62
|
+
const fixResult = await strategy.fix(fixContext, error);
|
|
102
63
|
fixes.push(fixResult);
|
|
103
64
|
if (fixResult.success) {
|
|
104
65
|
result.messages.push(`✅ Fixed: ${fixResult.message}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autoFixLoop.js","sourceRoot":"","sources":["../../src/handlers/autoFixLoop.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,8BAA8B,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"autoFixLoop.js","sourceRoot":"","sources":["../../src/handlers/autoFixLoop.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,5 +5,14 @@ interface GetTypeScriptDiagnosticsArgs {
|
|
|
5
5
|
files?: string[];
|
|
6
6
|
includeWarnings?: boolean;
|
|
7
7
|
}
|
|
8
|
+
export interface DiagnosticInfo {
|
|
9
|
+
file: string;
|
|
10
|
+
line: number;
|
|
11
|
+
column: number;
|
|
12
|
+
code: number;
|
|
13
|
+
message: string;
|
|
14
|
+
severity: 'error' | 'warning' | 'suggestion' | 'message';
|
|
15
|
+
category: 'typescript' | 'semantic' | 'syntactic' | 'declaration' | 'global' | 'config';
|
|
16
|
+
}
|
|
8
17
|
declare function handleGetTypeScriptDiagnostics(args: GetTypeScriptDiagnosticsArgs): Promise<MCPToolResponse>;
|
|
9
18
|
export { handleGetTypeScriptDiagnostics };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Project, SourceFile } from 'ts-morph';
|
|
2
|
+
import { DiagnosticInfo } from '../handlers/typescriptDiagnostics.js';
|
|
3
|
+
import { ConsoleError } from '../handlers/autoFixLoop.js';
|
|
4
|
+
export interface FixContext {
|
|
5
|
+
projectDir: string;
|
|
6
|
+
project: Project;
|
|
7
|
+
tsConfigPath: string;
|
|
8
|
+
}
|
|
9
|
+
export interface FixResult {
|
|
10
|
+
success: boolean;
|
|
11
|
+
message: string;
|
|
12
|
+
changes: Array<{
|
|
13
|
+
file: string;
|
|
14
|
+
description: string;
|
|
15
|
+
diff?: string;
|
|
16
|
+
}>;
|
|
17
|
+
}
|
|
18
|
+
export interface FixStrategy {
|
|
19
|
+
errorType: 'typescript' | 'console' | 'network';
|
|
20
|
+
pattern: RegExp;
|
|
21
|
+
canFix(error: DiagnosticInfo | ConsoleError): boolean;
|
|
22
|
+
fix(context: FixContext, error: DiagnosticInfo | ConsoleError): Promise<FixResult>;
|
|
23
|
+
}
|
|
24
|
+
export declare function createFixContext(projectDir: string, tsConfigPath: string): FixContext;
|
|
25
|
+
export declare function saveChanges(context: FixContext): void;
|
|
26
|
+
export declare function getSourceFile(context: FixContext, filePath: string): SourceFile | undefined;
|
|
27
|
+
export declare function getRelativePath(context: FixContext, filePath: string): string;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Project } from 'ts-morph';
|
|
2
|
+
export function createFixContext(projectDir, tsConfigPath) {
|
|
3
|
+
const project = new Project({
|
|
4
|
+
tsConfigFilePath: tsConfigPath,
|
|
5
|
+
skipAddingFilesFromTsConfig: false,
|
|
6
|
+
skipFileDependencyResolution: true,
|
|
7
|
+
skipLoadingLibFiles: true,
|
|
8
|
+
});
|
|
9
|
+
return { projectDir, project, tsConfigPath };
|
|
10
|
+
}
|
|
11
|
+
export function saveChanges(context) {
|
|
12
|
+
context.project.saveSync();
|
|
13
|
+
}
|
|
14
|
+
export function getSourceFile(context, filePath) {
|
|
15
|
+
const fullPath = filePath.startsWith('/') ? filePath : `${context.projectDir}/${filePath}`;
|
|
16
|
+
return context.project.getSourceFile(fullPath);
|
|
17
|
+
}
|
|
18
|
+
export function getRelativePath(context, filePath) {
|
|
19
|
+
const fullPath = filePath.startsWith('/') ? filePath : `${context.projectDir}/${filePath}`;
|
|
20
|
+
const relative = fullPath.replace(context.projectDir + '/', '');
|
|
21
|
+
return relative;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=baseStrategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseStrategy.js","sourceRoot":"","sources":["../../src/strategies/baseStrategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAA2N,MAAM,UAAU,CAAC;AAuB5P,MAAM,UAAU,gBAAgB,CAAC,UAAkB,EAAE,YAAoB;IACvE,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC;QAC1B,gBAAgB,EAAE,YAAY;QAC9B,2BAA2B,EAAE,KAAK;QAClC,4BAA4B,EAAE,IAAI;QAClC,mBAAmB,EAAE,IAAI;KAC1B,CAAC,CAAC;IACH,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAmB;IAC7C,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAmB,EAAE,QAAgB;IACjE,MAAM,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,UAAU,IAAI,QAAQ,EAAE,CAAC;IAC3F,OAAO,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAmB,EAAE,QAAgB;IACnE,MAAM,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,UAAU,IAAI,QAAQ,EAAE,CAAC;IAC3F,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;IAChE,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './baseStrategy.js';
|
|
2
|
+
export { unusedImportRemovalStrategy } from './unusedImportRemoval.js';
|
|
3
|
+
export { missingPropertyStrategy } from './missingProperty.js';
|
|
4
|
+
export { typeAssignmentStrategy } from './typeAssignment.js';
|
|
5
|
+
export { nullCheckInsertionStrategy } from './nullCheckInsertion.js';
|
|
6
|
+
export { missingImportStrategy } from './missingImport.js';
|
|
7
|
+
export { networkErrorStrategy } from './networkError.js';
|
|
8
|
+
import { FixStrategy } from './baseStrategy.js';
|
|
9
|
+
export declare const defaultFixStrategies: FixStrategy[];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export * from './baseStrategy.js';
|
|
2
|
+
export { unusedImportRemovalStrategy } from './unusedImportRemoval.js';
|
|
3
|
+
export { missingPropertyStrategy } from './missingProperty.js';
|
|
4
|
+
export { typeAssignmentStrategy } from './typeAssignment.js';
|
|
5
|
+
export { nullCheckInsertionStrategy } from './nullCheckInsertion.js';
|
|
6
|
+
export { missingImportStrategy } from './missingImport.js';
|
|
7
|
+
export { networkErrorStrategy } from './networkError.js';
|
|
8
|
+
import { unusedImportRemovalStrategy } from './unusedImportRemoval.js';
|
|
9
|
+
import { missingPropertyStrategy } from './missingProperty.js';
|
|
10
|
+
import { typeAssignmentStrategy } from './typeAssignment.js';
|
|
11
|
+
import { nullCheckInsertionStrategy } from './nullCheckInsertion.js';
|
|
12
|
+
import { missingImportStrategy } from './missingImport.js';
|
|
13
|
+
import { networkErrorStrategy } from './networkError.js';
|
|
14
|
+
export const defaultFixStrategies = [
|
|
15
|
+
unusedImportRemovalStrategy,
|
|
16
|
+
missingPropertyStrategy,
|
|
17
|
+
typeAssignmentStrategy,
|
|
18
|
+
nullCheckInsertionStrategy,
|
|
19
|
+
missingImportStrategy,
|
|
20
|
+
networkErrorStrategy,
|
|
21
|
+
];
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/strategies/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAGzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,MAAM,CAAC,MAAM,oBAAoB,GAAkB;IACjD,2BAA2B;IAC3B,uBAAuB;IACvB,sBAAsB;IACtB,0BAA0B;IAC1B,qBAAqB;IACrB,oBAAoB;CACrB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { FixStrategy, FixContext, FixResult } from './baseStrategy.js';
|
|
2
|
+
import { DiagnosticInfo } from '../handlers/typescriptDiagnostics.js';
|
|
3
|
+
import { ConsoleError } from '../handlers/autoFixLoop.js';
|
|
4
|
+
export declare class MissingImportStrategy implements FixStrategy {
|
|
5
|
+
errorType: "typescript";
|
|
6
|
+
pattern: RegExp;
|
|
7
|
+
canFix(error: DiagnosticInfo | ConsoleError): boolean;
|
|
8
|
+
fix(context: FixContext, error: DiagnosticInfo | ConsoleError): Promise<FixResult>;
|
|
9
|
+
private addImportFromModule;
|
|
10
|
+
private findAndAddImport;
|
|
11
|
+
private getExportedSymbols;
|
|
12
|
+
private getModuleSpecifier;
|
|
13
|
+
private getRelativeImportPath;
|
|
14
|
+
private generateDiff;
|
|
15
|
+
}
|
|
16
|
+
export declare const missingImportStrategy: MissingImportStrategy;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { SyntaxKind } from 'ts-morph';
|
|
2
|
+
import { getSourceFile, getRelativePath, saveChanges } from './baseStrategy.js';
|
|
3
|
+
export class MissingImportStrategy {
|
|
4
|
+
errorType = 'typescript';
|
|
5
|
+
pattern = /(?:Cannot find name|'([^']+)' is not defined|is not defined|Module '([^']+)' has no exported member)/i;
|
|
6
|
+
canFix(error) {
|
|
7
|
+
return this.pattern.test(error.message) && error.severity === 'error';
|
|
8
|
+
}
|
|
9
|
+
async fix(context, error) {
|
|
10
|
+
const changes = [];
|
|
11
|
+
const file = error.file;
|
|
12
|
+
if (!file) {
|
|
13
|
+
return { success: false, message: 'No file path in error', changes };
|
|
14
|
+
}
|
|
15
|
+
// Extract the missing identifier name
|
|
16
|
+
const match = error.message.match(/(?:Cannot find name|'([^']+)' is not defined|is not defined|Module '([^']+)' has no exported member '([^']+)')/i);
|
|
17
|
+
if (!match) {
|
|
18
|
+
return { success: false, message: 'Could not parse missing identifier from error', changes };
|
|
19
|
+
}
|
|
20
|
+
const missingName = match[1] || match[3];
|
|
21
|
+
const moduleName = match[2];
|
|
22
|
+
const sourceFile = getSourceFile(context, file);
|
|
23
|
+
if (!sourceFile) {
|
|
24
|
+
return { success: false, message: `Source file not found: ${file}`, changes };
|
|
25
|
+
}
|
|
26
|
+
const originalText = sourceFile.getFullText();
|
|
27
|
+
try {
|
|
28
|
+
let importAdded = false;
|
|
29
|
+
if (moduleName) {
|
|
30
|
+
// Missing export from specific module
|
|
31
|
+
importAdded = await this.addImportFromModule(sourceFile, missingName, moduleName);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
// Search for the symbol in the project
|
|
35
|
+
importAdded = await this.findAndAddImport(context, sourceFile, missingName);
|
|
36
|
+
}
|
|
37
|
+
if (!importAdded) {
|
|
38
|
+
return { success: false, message: `Could not find source for '${missingName}'`, changes };
|
|
39
|
+
}
|
|
40
|
+
saveChanges(context);
|
|
41
|
+
const newText = sourceFile.getFullText();
|
|
42
|
+
const diff = this.generateDiff(originalText, newText, file);
|
|
43
|
+
changes.push({
|
|
44
|
+
file: getRelativePath(context, file),
|
|
45
|
+
description: `Added missing import for '${missingName}'`,
|
|
46
|
+
diff,
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
success: true,
|
|
50
|
+
message: `Added missing import for '${missingName}'`,
|
|
51
|
+
changes,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
56
|
+
return { success: false, message: `Fix failed: ${msg}`, changes };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async addImportFromModule(sourceFile, name, module) {
|
|
60
|
+
try {
|
|
61
|
+
// Check if import already exists
|
|
62
|
+
const existingImport = sourceFile.getImportDeclarations().find(imp => imp.getModuleSpecifierValue() === module);
|
|
63
|
+
if (existingImport) {
|
|
64
|
+
// Add to existing import
|
|
65
|
+
const namedImports = existingImport.getNamedImports();
|
|
66
|
+
const alreadyImported = namedImports.some(spec => spec.getName() === name);
|
|
67
|
+
if (!alreadyImported) {
|
|
68
|
+
existingImport.addNamedImport(name);
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
return true; // Already imported
|
|
72
|
+
}
|
|
73
|
+
// Add new import declaration
|
|
74
|
+
sourceFile.addImportDeclaration({
|
|
75
|
+
moduleSpecifier: module,
|
|
76
|
+
namedImports: [name],
|
|
77
|
+
});
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async findAndAddImport(context, sourceFile, name) {
|
|
85
|
+
// Search all source files in the project for an export matching the name
|
|
86
|
+
const allSourceFiles = context.project.getSourceFiles();
|
|
87
|
+
for (const sf of allSourceFiles) {
|
|
88
|
+
if (sf === sourceFile)
|
|
89
|
+
continue; // Don't import from self
|
|
90
|
+
const exports = this.getExportedSymbols(sf, name);
|
|
91
|
+
if (exports.length > 0) {
|
|
92
|
+
const exportInfo = exports[0];
|
|
93
|
+
const moduleSpecifier = this.getModuleSpecifier(sourceFile, sf);
|
|
94
|
+
return this.addImportFromModule(sourceFile, name, moduleSpecifier);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
getExportedSymbols(sourceFile, name) {
|
|
100
|
+
const results = [];
|
|
101
|
+
// Check exported functions, classes, interfaces, types, variables
|
|
102
|
+
const exportedDeclarations = sourceFile.getExportedDeclarations();
|
|
103
|
+
for (const [exportName, declarations] of exportedDeclarations) {
|
|
104
|
+
if (exportName === name) {
|
|
105
|
+
const decl = declarations[0];
|
|
106
|
+
let isDefault = false;
|
|
107
|
+
if (decl.getKind() === SyntaxKind.FunctionDeclaration ||
|
|
108
|
+
decl.getKind() === SyntaxKind.ClassDeclaration ||
|
|
109
|
+
decl.getKind() === SyntaxKind.VariableDeclaration ||
|
|
110
|
+
decl.getKind() === SyntaxKind.InterfaceDeclaration ||
|
|
111
|
+
decl.getKind() === SyntaxKind.TypeAliasDeclaration) {
|
|
112
|
+
isDefault = decl.hasDefaultKeyword?.() ?? false;
|
|
113
|
+
}
|
|
114
|
+
results.push({ name: exportName, isDefault });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return results;
|
|
118
|
+
}
|
|
119
|
+
getModuleSpecifier(fromFile, toFile) {
|
|
120
|
+
const fromDir = fromFile.getDirectoryPath();
|
|
121
|
+
const toPath = toFile.getFilePath();
|
|
122
|
+
// Calculate relative path
|
|
123
|
+
const relative = this.getRelativeImportPath(fromDir, toPath);
|
|
124
|
+
return relative;
|
|
125
|
+
}
|
|
126
|
+
getRelativeImportPath(fromDir, toPath) {
|
|
127
|
+
const path = require('path');
|
|
128
|
+
let relative = path.relative(fromDir, toPath);
|
|
129
|
+
// Remove extension
|
|
130
|
+
relative = relative.replace(/\.ts$/, '').replace(/\.tsx$/, '');
|
|
131
|
+
// Ensure it starts with ./ or ../
|
|
132
|
+
if (!relative.startsWith('.')) {
|
|
133
|
+
relative = './' + relative;
|
|
134
|
+
}
|
|
135
|
+
return relative;
|
|
136
|
+
}
|
|
137
|
+
generateDiff(oldText, newText, fileName) {
|
|
138
|
+
const oldLines = oldText.split('\n');
|
|
139
|
+
const newLines = newText.split('\n');
|
|
140
|
+
let diff = `--- ${fileName}\n+++ ${fileName}\n`;
|
|
141
|
+
const maxLen = Math.max(oldLines.length, newLines.length);
|
|
142
|
+
for (let i = 0; i < maxLen; i++) {
|
|
143
|
+
const oldLine = oldLines[i];
|
|
144
|
+
const newLine = newLines[i];
|
|
145
|
+
if (oldLine !== newLine) {
|
|
146
|
+
if (oldLine !== undefined)
|
|
147
|
+
diff += `-${oldLine}\n`;
|
|
148
|
+
if (newLine !== undefined)
|
|
149
|
+
diff += `+${newLine}\n`;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return diff;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
export const missingImportStrategy = new MissingImportStrategy();
|
|
156
|
+
//# sourceMappingURL=missingImport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"missingImport.js","sourceRoot":"","sources":["../../src/strategies/missingImport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { FixStrategy, FixContext, FixResult } from './baseStrategy.js';
|
|
2
|
+
import { DiagnosticInfo } from '../handlers/typescriptDiagnostics.js';
|
|
3
|
+
export declare class MissingPropertyStrategy implements FixStrategy {
|
|
4
|
+
errorType: "typescript";
|
|
5
|
+
pattern: RegExp;
|
|
6
|
+
canFix(error: DiagnosticInfo): boolean;
|
|
7
|
+
fix(context: FixContext, error: DiagnosticInfo): Promise<FixResult>;
|
|
8
|
+
private findTypeDeclaration;
|
|
9
|
+
private getProperty;
|
|
10
|
+
private addProperty;
|
|
11
|
+
private generateDiff;
|
|
12
|
+
}
|
|
13
|
+
export declare const missingPropertyStrategy: MissingPropertyStrategy;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { SyntaxKind } from 'ts-morph';
|
|
2
|
+
import { getSourceFile, getRelativePath, saveChanges } from './baseStrategy.js';
|
|
3
|
+
export class MissingPropertyStrategy {
|
|
4
|
+
errorType = 'typescript';
|
|
5
|
+
pattern = /Property '([^']+)' does not exist on type '([^']+)'/i;
|
|
6
|
+
canFix(error) {
|
|
7
|
+
return this.pattern.test(error.message) && error.severity === 'error';
|
|
8
|
+
}
|
|
9
|
+
async fix(context, error) {
|
|
10
|
+
const changes = [];
|
|
11
|
+
if (!error.file) {
|
|
12
|
+
return { success: false, message: 'No file path in error', changes };
|
|
13
|
+
}
|
|
14
|
+
const match = error.message.match(this.pattern);
|
|
15
|
+
if (!match) {
|
|
16
|
+
return { success: false, message: 'Could not parse missing property error', changes };
|
|
17
|
+
}
|
|
18
|
+
const propertyName = match[1];
|
|
19
|
+
const typeName = match[2];
|
|
20
|
+
const sourceFile = getSourceFile(context, error.file);
|
|
21
|
+
if (!sourceFile) {
|
|
22
|
+
return { success: false, message: `Source file not found: ${error.file}`, changes };
|
|
23
|
+
}
|
|
24
|
+
const originalText = sourceFile.getFullText();
|
|
25
|
+
try {
|
|
26
|
+
// Find the interface or type alias with the given name
|
|
27
|
+
const targetType = this.findTypeDeclaration(sourceFile, typeName);
|
|
28
|
+
if (!targetType) {
|
|
29
|
+
return { success: false, message: `Type '${typeName}' not found in ${error.file}`, changes };
|
|
30
|
+
}
|
|
31
|
+
// Check if property already exists
|
|
32
|
+
const existingProp = this.getProperty(targetType, propertyName);
|
|
33
|
+
if (existingProp) {
|
|
34
|
+
return { success: false, message: `Property '${propertyName}' already exists on '${typeName}'`, changes };
|
|
35
|
+
}
|
|
36
|
+
// Add the missing property as optional with 'any' type (safe default)
|
|
37
|
+
this.addProperty(targetType, propertyName);
|
|
38
|
+
saveChanges(context);
|
|
39
|
+
const newText = sourceFile.getFullText();
|
|
40
|
+
const diff = this.generateDiff(originalText, newText, error.file);
|
|
41
|
+
changes.push({
|
|
42
|
+
file: getRelativePath(context, error.file),
|
|
43
|
+
description: `Added missing property '${propertyName}' to '${typeName}'`,
|
|
44
|
+
diff,
|
|
45
|
+
});
|
|
46
|
+
return {
|
|
47
|
+
success: true,
|
|
48
|
+
message: `Added missing property '${propertyName}' to type '${typeName}'`,
|
|
49
|
+
changes,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
54
|
+
return { success: false, message: `Fix failed: ${msg}`, changes };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
findTypeDeclaration(sourceFile, typeName) {
|
|
58
|
+
// Check interfaces
|
|
59
|
+
const interfaces = sourceFile.getInterfaces();
|
|
60
|
+
for (const iface of interfaces) {
|
|
61
|
+
if (iface.getName() === typeName) {
|
|
62
|
+
return iface;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Check type aliases
|
|
66
|
+
const typeAliases = sourceFile.getTypeAliases();
|
|
67
|
+
for (const typeAlias of typeAliases) {
|
|
68
|
+
if (typeAlias.getName() === typeName) {
|
|
69
|
+
return typeAlias;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
getProperty(type, propertyName) {
|
|
75
|
+
if (type.getKind() === SyntaxKind.InterfaceDeclaration) {
|
|
76
|
+
return type.getProperty(propertyName);
|
|
77
|
+
}
|
|
78
|
+
// For type aliases, we need to check the type literal
|
|
79
|
+
const typeLiteral = type.getTypeNode();
|
|
80
|
+
if (typeLiteral && typeLiteral.getKind() === SyntaxKind.TypeLiteral) {
|
|
81
|
+
const members = typeLiteral.getMembers?.() || [];
|
|
82
|
+
for (const member of members) {
|
|
83
|
+
if (member.getKind() === SyntaxKind.PropertySignature) {
|
|
84
|
+
const prop = member;
|
|
85
|
+
if (prop.getName() === propertyName) {
|
|
86
|
+
return prop;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
addProperty(type, propertyName) {
|
|
94
|
+
if (type.getKind() === SyntaxKind.InterfaceDeclaration) {
|
|
95
|
+
type.addProperty({
|
|
96
|
+
name: propertyName,
|
|
97
|
+
type: 'any',
|
|
98
|
+
hasQuestionToken: true, // Make it optional
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
// For type aliases with type literal, we need to recreate the type
|
|
103
|
+
const typeAlias = type;
|
|
104
|
+
const typeLiteral = typeAlias.getTypeNode();
|
|
105
|
+
if (typeLiteral && typeLiteral.getKind() === SyntaxKind.TypeLiteral) {
|
|
106
|
+
const members = typeLiteral.getMembers?.() || [];
|
|
107
|
+
const memberTexts = members.map((m) => m.getText());
|
|
108
|
+
const newMember = ` ${propertyName}?: any;`;
|
|
109
|
+
// Replace the type literal with updated members
|
|
110
|
+
const newTypeLiteral = `{${memberTexts.length > 0 ? '\n' : ''}${memberTexts.join(';\n')}${memberTexts.length > 0 ? ';\n' : ''}${newMember}\n}`;
|
|
111
|
+
typeAlias.setType(newTypeLiteral);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
generateDiff(oldText, newText, fileName) {
|
|
116
|
+
const oldLines = oldText.split('\n');
|
|
117
|
+
const newLines = newText.split('\n');
|
|
118
|
+
let diff = `--- ${fileName}\n+++ ${fileName}\n`;
|
|
119
|
+
const maxLen = Math.max(oldLines.length, newLines.length);
|
|
120
|
+
for (let i = 0; i < maxLen; i++) {
|
|
121
|
+
const oldLine = oldLines[i];
|
|
122
|
+
const newLine = newLines[i];
|
|
123
|
+
if (oldLine !== newLine) {
|
|
124
|
+
if (oldLine !== undefined)
|
|
125
|
+
diff += `-${oldLine}\n`;
|
|
126
|
+
if (newLine !== undefined)
|
|
127
|
+
diff += `+${newLine}\n`;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return diff;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export const missingPropertyStrategy = new MissingPropertyStrategy();
|
|
134
|
+
//# sourceMappingURL=missingProperty.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"missingProperty.js","sourceRoot":"","sources":["../../src/strategies/missingProperty.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { FixStrategy, FixResult } from './baseStrategy.js';
|
|
2
|
+
import { ConsoleError } from '../handlers/autoFixLoop.js';
|
|
3
|
+
export declare class NetworkErrorStrategy implements FixStrategy {
|
|
4
|
+
errorType: "network";
|
|
5
|
+
pattern: RegExp;
|
|
6
|
+
canFix(error: ConsoleError): boolean;
|
|
7
|
+
fix(_context: any, error: ConsoleError): Promise<FixResult>;
|
|
8
|
+
private analyzeNetworkError;
|
|
9
|
+
}
|
|
10
|
+
export declare const networkErrorStrategy: NetworkErrorStrategy;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export class NetworkErrorStrategy {
|
|
2
|
+
errorType = 'network';
|
|
3
|
+
pattern = /Failed to fetch|Network Error|ECONNREFUSED|ERR_CONNECTION_REFUSED|404|500|502|503|504|CORS|Cross-Origin/i;
|
|
4
|
+
canFix(error) {
|
|
5
|
+
return this.pattern.test(error.message);
|
|
6
|
+
}
|
|
7
|
+
async fix(_context, error) {
|
|
8
|
+
const changes = [];
|
|
9
|
+
// Network errors typically require backend/server fixes, not frontend code changes
|
|
10
|
+
// We provide diagnostic suggestions instead
|
|
11
|
+
const suggestions = this.analyzeNetworkError(error);
|
|
12
|
+
return {
|
|
13
|
+
success: false, // Network errors can't be auto-fixed in frontend code
|
|
14
|
+
message: `Network error detected: ${error.message}\n\nSuggestions:\n${suggestions.map(s => ` • ${s}`).join('\n')}`,
|
|
15
|
+
changes,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
analyzeNetworkError(error) {
|
|
19
|
+
const suggestions = [];
|
|
20
|
+
const message = error.message.toLowerCase();
|
|
21
|
+
const url = error.url || '';
|
|
22
|
+
if (message.includes('failed to fetch') || message.includes('network error')) {
|
|
23
|
+
suggestions.push('Check if the backend server is running');
|
|
24
|
+
suggestions.push('Verify the API base URL in your frontend config');
|
|
25
|
+
suggestions.push('Check for CORS issues - ensure backend allows your frontend origin');
|
|
26
|
+
}
|
|
27
|
+
if (message.includes('econnrefused') || message.includes('connection refused')) {
|
|
28
|
+
suggestions.push('Backend server is not running or not accessible on the expected port');
|
|
29
|
+
suggestions.push('Check docker/proxy configuration if using containerized backend');
|
|
30
|
+
}
|
|
31
|
+
if (message.includes('404')) {
|
|
32
|
+
suggestions.push(`API endpoint not found: ${url}`);
|
|
33
|
+
suggestions.push('Verify the API route matches backend routes');
|
|
34
|
+
suggestions.push('Check for typos in the request path');
|
|
35
|
+
}
|
|
36
|
+
if (message.includes('500') || message.includes('502') || message.includes('503') || message.includes('504')) {
|
|
37
|
+
suggestions.push('Backend server error - check backend logs');
|
|
38
|
+
suggestions.push('May be temporary - try retrying the request');
|
|
39
|
+
}
|
|
40
|
+
if (message.includes('cors') || message.includes('cross-origin')) {
|
|
41
|
+
suggestions.push('CORS policy blocking request');
|
|
42
|
+
suggestions.push('Configure backend to allow your frontend origin (Access-Control-Allow-Origin)');
|
|
43
|
+
suggestions.push('For development, consider using a proxy (Vite proxy, Next.js rewrites)');
|
|
44
|
+
}
|
|
45
|
+
if (url.includes('localhost') || url.includes('127.0.0.1')) {
|
|
46
|
+
suggestions.push('Using localhost - ensure backend runs on the same machine/port');
|
|
47
|
+
}
|
|
48
|
+
if (suggestions.length === 0) {
|
|
49
|
+
suggestions.push('Check browser Network tab for detailed request/response');
|
|
50
|
+
suggestions.push('Verify API endpoint and request parameters');
|
|
51
|
+
}
|
|
52
|
+
return suggestions;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export const networkErrorStrategy = new NetworkErrorStrategy();
|
|
56
|
+
//# sourceMappingURL=networkError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"networkError.js","sourceRoot":"","sources":["../../src/strategies/networkError.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { FixStrategy, FixContext, FixResult } from './baseStrategy.js';
|
|
2
|
+
import { ConsoleError } from '../handlers/autoFixLoop.js';
|
|
3
|
+
export declare class NullCheckInsertionStrategy implements FixStrategy {
|
|
4
|
+
errorType: "console";
|
|
5
|
+
pattern: RegExp;
|
|
6
|
+
canFix(error: ConsoleError): boolean;
|
|
7
|
+
fix(context: FixContext, error: ConsoleError): Promise<FixResult>;
|
|
8
|
+
private extractFilePathFromUrl;
|
|
9
|
+
private findPropertyAccessAtLine;
|
|
10
|
+
private addOptionalChaining;
|
|
11
|
+
private wrapWithNullCheck;
|
|
12
|
+
private generateDiff;
|
|
13
|
+
}
|
|
14
|
+
export declare const nullCheckInsertionStrategy: NullCheckInsertionStrategy;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { Block, SyntaxKind } from 'ts-morph';
|
|
2
|
+
import { getSourceFile, getRelativePath, saveChanges } from './baseStrategy.js';
|
|
3
|
+
export class NullCheckInsertionStrategy {
|
|
4
|
+
errorType = 'console';
|
|
5
|
+
pattern = /Cannot read propert(?:y|ies) of (?:null|undefined)|Cannot read property '([^']+)' of (?:null|undefined)|is (?:null|undefined) and has no property/i;
|
|
6
|
+
canFix(error) {
|
|
7
|
+
return this.pattern.test(error.message);
|
|
8
|
+
}
|
|
9
|
+
async fix(context, error) {
|
|
10
|
+
const changes = [];
|
|
11
|
+
if (!error.url) {
|
|
12
|
+
return { success: false, message: 'No URL in console error', changes };
|
|
13
|
+
}
|
|
14
|
+
// Extract file path from URL (e.g., http://localhost:3000/src/main.ts -> src/main.ts)
|
|
15
|
+
const filePath = this.extractFilePathFromUrl(error.url);
|
|
16
|
+
if (!filePath) {
|
|
17
|
+
return { success: false, message: 'Could not extract file path from URL', changes };
|
|
18
|
+
}
|
|
19
|
+
const sourceFile = getSourceFile(context, filePath);
|
|
20
|
+
if (!sourceFile) {
|
|
21
|
+
return { success: false, message: `Source file not found: ${filePath}`, changes };
|
|
22
|
+
}
|
|
23
|
+
const originalText = sourceFile.getFullText();
|
|
24
|
+
const targetLine = error.lineNumber || 1;
|
|
25
|
+
try {
|
|
26
|
+
// Find the problematic property access at the error line
|
|
27
|
+
const propertyAccess = this.findPropertyAccessAtLine(sourceFile, targetLine);
|
|
28
|
+
if (!propertyAccess) {
|
|
29
|
+
return { success: false, message: `No property access found at line ${targetLine}`, changes };
|
|
30
|
+
}
|
|
31
|
+
// Strategy 1: Try to add optional chaining (?.) - modern and clean
|
|
32
|
+
const addedOptionalChaining = this.addOptionalChaining(propertyAccess);
|
|
33
|
+
if (!addedOptionalChaining) {
|
|
34
|
+
// Strategy 2: Wrap with null check if statement
|
|
35
|
+
const wrapped = this.wrapWithNullCheck(propertyAccess);
|
|
36
|
+
if (!wrapped) {
|
|
37
|
+
return { success: false, message: 'Could not add null check or optional chaining', changes };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
saveChanges(context);
|
|
41
|
+
const newText = sourceFile.getFullText();
|
|
42
|
+
const diff = this.generateDiff(originalText, newText, filePath);
|
|
43
|
+
changes.push({
|
|
44
|
+
file: getRelativePath(context, filePath),
|
|
45
|
+
description: `Added null/undefined check for property access at line ${targetLine}`,
|
|
46
|
+
diff,
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
success: true,
|
|
50
|
+
message: `Fixed null/undefined property access at line ${targetLine}`,
|
|
51
|
+
changes,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
56
|
+
return { success: false, message: `Fix failed: ${msg}`, changes };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
extractFilePathFromUrl(url) {
|
|
60
|
+
try {
|
|
61
|
+
const urlObj = new URL(url);
|
|
62
|
+
const pathname = urlObj.pathname;
|
|
63
|
+
// Remove leading slash and common prefixes
|
|
64
|
+
return pathname.replace(/^\//, '').replace(/^src\//, '').replace(/^app\//, '');
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
findPropertyAccessAtLine(sourceFile, line) {
|
|
71
|
+
const propertyAccesses = sourceFile.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression);
|
|
72
|
+
for (const propAccess of propertyAccesses) {
|
|
73
|
+
const startLine = propAccess.getStartLineNumber();
|
|
74
|
+
const endLine = propAccess.getEndLineNumber();
|
|
75
|
+
if (startLine <= line && endLine >= line) {
|
|
76
|
+
return propAccess;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
addOptionalChaining(propAccess) {
|
|
82
|
+
try {
|
|
83
|
+
// Check if it already has optional chaining
|
|
84
|
+
const expression = propAccess.getExpression();
|
|
85
|
+
if (expression.getKind() === SyntaxKind.NonNullExpression) {
|
|
86
|
+
return false; // Already has !
|
|
87
|
+
}
|
|
88
|
+
// Add optional chaining by replacing the dot with ?.
|
|
89
|
+
// We need to replace the entire property access expression
|
|
90
|
+
const exprText = propAccess.getExpression().getText();
|
|
91
|
+
const name = propAccess.getName();
|
|
92
|
+
const newText = `${exprText}?.${name}`;
|
|
93
|
+
propAccess.replaceWithText(newText);
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
wrapWithNullCheck(propAccess) {
|
|
101
|
+
try {
|
|
102
|
+
const statement = propAccess.getFirstAncestorByKind(SyntaxKind.ExpressionStatement);
|
|
103
|
+
if (!statement)
|
|
104
|
+
return false;
|
|
105
|
+
const parent = statement.getParent();
|
|
106
|
+
if (!parent || !Block.isBlock(parent))
|
|
107
|
+
return false;
|
|
108
|
+
const exprText = statement.getText().trim();
|
|
109
|
+
const checkExpr = propAccess.getExpression().getText();
|
|
110
|
+
// Create if statement: if (obj != null) { obj.prop = ...; }
|
|
111
|
+
const ifStatement = `if (${checkExpr} != null) {\n ${exprText}\n}`;
|
|
112
|
+
statement.replaceWithText(ifStatement);
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
generateDiff(oldText, newText, fileName) {
|
|
120
|
+
const oldLines = oldText.split('\n');
|
|
121
|
+
const newLines = newText.split('\n');
|
|
122
|
+
let diff = `--- ${fileName}\n+++ ${fileName}\n`;
|
|
123
|
+
const maxLen = Math.max(oldLines.length, newLines.length);
|
|
124
|
+
for (let i = 0; i < maxLen; i++) {
|
|
125
|
+
const oldLine = oldLines[i];
|
|
126
|
+
const newLine = newLines[i];
|
|
127
|
+
if (oldLine !== newLine) {
|
|
128
|
+
if (oldLine !== undefined)
|
|
129
|
+
diff += `-${oldLine}\n`;
|
|
130
|
+
if (newLine !== undefined)
|
|
131
|
+
diff += `+${newLine}\n`;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return diff;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
export const nullCheckInsertionStrategy = new NullCheckInsertionStrategy();
|
|
138
|
+
//# sourceMappingURL=nullCheckInsertion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nullCheckInsertion.js","sourceRoot":"","sources":["../../src/strategies/nullCheckInsertion.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsG,KAAK,EAAE,UAAU,EAAc,MAAM,UAAU,CAAC;AAC7J,OAAO,EAAsC,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGpH,MAAM,OAAO,0BAA0B;IACrC,SAAS,GAAG,SAAkB,CAAC;IAC/B,OAAO,GAAG,oJAAoJ,CAAC;IAE/J,MAAM,CAAC,KAAmB;QACxB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,OAAmB,EAAE,KAAmB;QAChD,MAAM,OAAO,GAAgE,EAAE,CAAC;QAEhF,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,yBAAyB,EAAE,OAAO,EAAE,CAAC;QACzE,CAAC;QAED,sFAAsF;QACtF,MAAM,QAAQ,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,sCAAsC,EAAE,OAAO,EAAE,CAAC;QACtF,CAAC;QAED,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACpD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,0BAA0B,QAAQ,EAAE,EAAE,OAAO,EAAE,CAAC;QACpF,CAAC;QAED,MAAM,YAAY,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;QAC9C,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC;QAEzC,IAAI,CAAC;YACH,yDAAyD;YACzD,MAAM,cAAc,GAAG,IAAI,CAAC,wBAAwB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAC7E,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,oCAAoC,UAAU,EAAE,EAAE,OAAO,EAAE,CAAC;YAChG,CAAC;YAED,mEAAmE;YACnE,MAAM,qBAAqB,GAAG,IAAI,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC;YAEvE,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAC3B,gDAAgD;gBAChD,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC;gBACvD,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,+CAA+C,EAAE,OAAO,EAAE,CAAC;gBAC/F,CAAC;YACH,CAAC;YAED,WAAW,CAAC,OAAO,CAAC,CAAC;YACrB,MAAM,OAAO,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;YAEhE,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC;gBACxC,WAAW,EAAE,0DAA0D,UAAU,EAAE;gBACnF,IAAI;aACL,CAAC,CAAC;YAEH,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,gDAAgD,UAAU,EAAE;gBACrE,OAAO;aACR,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC;QACpE,CAAC;IACH,CAAC;IAEO,sBAAsB,CAAC,GAAW;QACxC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;YAC5B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;YACjC,2CAA2C;YAC3C,OAAO,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACjF,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAEO,wBAAwB,CAAC,UAAsB,EAAE,IAAY;QACnE,MAAM,gBAAgB,GAAG,UAAU,CAAC,oBAAoB,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC;QAE9F,KAAK,MAAM,UAAU,IAAI,gBAAgB,EAAE,CAAC;YAC1C,MAAM,SAAS,GAAG,UAAU,CAAC,kBAAkB,EAAE,CAAC;YAClD,MAAM,OAAO,GAAG,UAAU,CAAC,gBAAgB,EAAE,CAAC;YAE9C,IAAI,SAAS,IAAI,IAAI,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;gBACzC,OAAO,UAAU,CAAC;YACpB,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,mBAAmB,CAAC,UAAoC;QAC9D,IAAI,CAAC;YACH,4CAA4C;YAC5C,MAAM,UAAU,GAAG,UAAU,CAAC,aAAa,EAAE,CAAC;YAC9C,IAAI,UAAU,CAAC,OAAO,EAAE,KAAK,UAAU,CAAC,iBAAiB,EAAE,CAAC;gBAC1D,OAAO,KAAK,CAAC,CAAC,gBAAgB;YAChC,CAAC;YAED,qDAAqD;YACrD,2DAA2D;YAC3D,MAAM,QAAQ,GAAG,UAAU,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,CAAC;YACtD,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC;YAClC,MAAM,OAAO,GAAG,GAAG,QAAQ,KAAK,IAAI,EAAE,CAAC;YAEvC,UAAU,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAEO,iBAAiB,CAAC,UAAoC;QAC5D,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,UAAU,CAAC,sBAAsB,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;YACpF,IAAI,CAAC,SAAS;gBAAE,OAAO,KAAK,CAAC;YAE7B,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC;YACrC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBAAE,OAAO,KAAK,CAAC;YAEpD,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC;YAC5C,MAAM,SAAS,GAAG,UAAU,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,CAAC;YAEvD,4DAA4D;YAC5D,MAAM,WAAW,GAAG,OAAO,SAAS,kBAAkB,QAAQ,KAAK,CAAC;YAEpE,SAAS,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;YACvC,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAEO,YAAY,CAAC,OAAe,EAAE,OAAe,EAAE,QAAgB;QACrE,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,IAAI,GAAG,OAAO,QAAQ,SAAS,QAAQ,IAAI,CAAC;QAEhD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC1D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC5B,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC5B,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;gBACxB,IAAI,OAAO,KAAK,SAAS;oBAAE,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC;gBACnD,IAAI,OAAO,KAAK,SAAS;oBAAE,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC;YACrD,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAI,0BAA0B,EAAE,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { FixStrategy, FixContext, FixResult } from './baseStrategy.js';
|
|
2
|
+
import { DiagnosticInfo } from '../handlers/typescriptDiagnostics.js';
|
|
3
|
+
export declare class TypeAssignmentStrategy implements FixStrategy {
|
|
4
|
+
errorType: "typescript";
|
|
5
|
+
pattern: RegExp;
|
|
6
|
+
canFix(error: DiagnosticInfo): boolean;
|
|
7
|
+
fix(context: FixContext, error: DiagnosticInfo): Promise<FixResult>;
|
|
8
|
+
private findExpressionAtLine;
|
|
9
|
+
private isFixableExpression;
|
|
10
|
+
private addTypeAssertion;
|
|
11
|
+
private generateDiff;
|
|
12
|
+
}
|
|
13
|
+
export declare const typeAssignmentStrategy: TypeAssignmentStrategy;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { SyntaxKind } from 'ts-morph';
|
|
2
|
+
import { getSourceFile, getRelativePath, saveChanges } from './baseStrategy.js';
|
|
3
|
+
export class TypeAssignmentStrategy {
|
|
4
|
+
errorType = 'typescript';
|
|
5
|
+
pattern = /Type '([^']+)' is not assignable to type '([^']+)'/i;
|
|
6
|
+
canFix(error) {
|
|
7
|
+
return this.pattern.test(error.message) && error.severity === 'error';
|
|
8
|
+
}
|
|
9
|
+
async fix(context, error) {
|
|
10
|
+
const changes = [];
|
|
11
|
+
if (!error.file || error.line === undefined) {
|
|
12
|
+
return { success: false, message: 'No file path or line number in error', changes };
|
|
13
|
+
}
|
|
14
|
+
const match = error.message.match(this.pattern);
|
|
15
|
+
if (!match) {
|
|
16
|
+
return { success: false, message: 'Could not parse type assignment error', changes };
|
|
17
|
+
}
|
|
18
|
+
const sourceType = match[1];
|
|
19
|
+
const targetType = match[2];
|
|
20
|
+
const sourceFile = getSourceFile(context, error.file);
|
|
21
|
+
if (!sourceFile) {
|
|
22
|
+
return { success: false, message: `Source file not found: ${error.file}`, changes };
|
|
23
|
+
}
|
|
24
|
+
const originalText = sourceFile.getFullText();
|
|
25
|
+
try {
|
|
26
|
+
// Find the expression at the error location
|
|
27
|
+
const expression = this.findExpressionAtLine(sourceFile, error.line);
|
|
28
|
+
if (!expression) {
|
|
29
|
+
return { success: false, message: `No expression found at line ${error.line}`, changes };
|
|
30
|
+
}
|
|
31
|
+
// Strategy: Add type assertion (as targetType) to the expression
|
|
32
|
+
const fixed = this.addTypeAssertion(expression, targetType);
|
|
33
|
+
if (!fixed) {
|
|
34
|
+
return { success: false, message: 'Could not add type assertion to expression', changes };
|
|
35
|
+
}
|
|
36
|
+
saveChanges(context);
|
|
37
|
+
const newText = sourceFile.getFullText();
|
|
38
|
+
const diff = this.generateDiff(originalText, newText, error.file);
|
|
39
|
+
changes.push({
|
|
40
|
+
file: getRelativePath(context, error.file),
|
|
41
|
+
description: `Added type assertion 'as ${targetType}' to fix assignment`,
|
|
42
|
+
diff,
|
|
43
|
+
});
|
|
44
|
+
return {
|
|
45
|
+
success: true,
|
|
46
|
+
message: `Fixed type assignment: added 'as ${targetType}' assertion`,
|
|
47
|
+
changes,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
52
|
+
return { success: false, message: `Fix failed: ${msg}`, changes };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
findExpressionAtLine(sourceFile, line) {
|
|
56
|
+
// Get all expressions in the file and find one at the target line
|
|
57
|
+
const expressions = sourceFile.getDescendantsOfKind(SyntaxKind.Identifier);
|
|
58
|
+
for (const expr of expressions) {
|
|
59
|
+
const startLine = expr.getStartLineNumber();
|
|
60
|
+
const endLine = expr.getEndLineNumber();
|
|
61
|
+
if (startLine <= line && endLine >= line) {
|
|
62
|
+
// Prefer variable declarations, call expressions, property access
|
|
63
|
+
if (this.isFixableExpression(expr)) {
|
|
64
|
+
return expr;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
isFixableExpression(expr) {
|
|
71
|
+
const kind = expr.getKind();
|
|
72
|
+
return (kind === SyntaxKind.VariableDeclaration ||
|
|
73
|
+
kind === SyntaxKind.CallExpression ||
|
|
74
|
+
kind === SyntaxKind.PropertyAccessExpression ||
|
|
75
|
+
kind === SyntaxKind.Identifier ||
|
|
76
|
+
kind === SyntaxKind.AsExpression);
|
|
77
|
+
}
|
|
78
|
+
addTypeAssertion(expr, targetType) {
|
|
79
|
+
// If it's already an AsExpression, update the type
|
|
80
|
+
if (expr.getKind() === SyntaxKind.AsExpression) {
|
|
81
|
+
const asExpr = expr;
|
|
82
|
+
asExpr.setType(targetType);
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
// For other expressions, wrap with AsExpression
|
|
86
|
+
// We need to replace the expression with an AsExpression
|
|
87
|
+
const parent = expr.getParent();
|
|
88
|
+
if (!parent)
|
|
89
|
+
return false;
|
|
90
|
+
try {
|
|
91
|
+
// Create the new as expression text
|
|
92
|
+
const exprText = expr.getText();
|
|
93
|
+
const newText = `(${exprText} as ${targetType})`;
|
|
94
|
+
// Replace the expression in the parent
|
|
95
|
+
expr.replaceWithText(newText);
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
generateDiff(oldText, newText, fileName) {
|
|
103
|
+
const oldLines = oldText.split('\n');
|
|
104
|
+
const newLines = newText.split('\n');
|
|
105
|
+
let diff = `--- ${fileName}\n+++ ${fileName}\n`;
|
|
106
|
+
const maxLen = Math.max(oldLines.length, newLines.length);
|
|
107
|
+
for (let i = 0; i < maxLen; i++) {
|
|
108
|
+
const oldLine = oldLines[i];
|
|
109
|
+
const newLine = newLines[i];
|
|
110
|
+
if (oldLine !== newLine) {
|
|
111
|
+
if (oldLine !== undefined)
|
|
112
|
+
diff += `-${oldLine}\n`;
|
|
113
|
+
if (newLine !== undefined)
|
|
114
|
+
diff += `+${newLine}\n`;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return diff;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
export const typeAssignmentStrategy = new TypeAssignmentStrategy();
|
|
121
|
+
//# sourceMappingURL=typeAssignment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typeAssignment.js","sourceRoot":"","sources":["../../src/strategies/typeAssignment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FixStrategy, FixContext, FixResult } from './baseStrategy.js';
|
|
2
|
+
import { DiagnosticInfo } from '../handlers/typescriptDiagnostics.js';
|
|
3
|
+
export declare class UnusedImportRemovalStrategy implements FixStrategy {
|
|
4
|
+
errorType: "typescript";
|
|
5
|
+
pattern: RegExp;
|
|
6
|
+
canFix(error: DiagnosticInfo): boolean;
|
|
7
|
+
fix(context: FixContext, error: DiagnosticInfo): Promise<FixResult>;
|
|
8
|
+
private isSymbolUsedInFile;
|
|
9
|
+
private generateDiff;
|
|
10
|
+
}
|
|
11
|
+
export declare const unusedImportRemovalStrategy: UnusedImportRemovalStrategy;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { SyntaxKind } from 'ts-morph';
|
|
2
|
+
import { saveChanges, getSourceFile, getRelativePath } from './baseStrategy.js';
|
|
3
|
+
export class UnusedImportRemovalStrategy {
|
|
4
|
+
errorType = 'typescript';
|
|
5
|
+
pattern = /(?:Unused variable|unused import|is declared but its value is never read|'([^']+)' is defined but never used)/i;
|
|
6
|
+
canFix(error) {
|
|
7
|
+
return this.pattern.test(error.message) && error.severity === 'error';
|
|
8
|
+
}
|
|
9
|
+
async fix(context, error) {
|
|
10
|
+
const changes = [];
|
|
11
|
+
let fixedCount = 0;
|
|
12
|
+
if (!error.file) {
|
|
13
|
+
return { success: false, message: 'No file path in error', changes };
|
|
14
|
+
}
|
|
15
|
+
const sourceFile = getSourceFile(context, error.file);
|
|
16
|
+
if (!sourceFile) {
|
|
17
|
+
return { success: false, message: `Source file not found: ${error.file}`, changes };
|
|
18
|
+
}
|
|
19
|
+
const originalText = sourceFile.getFullText();
|
|
20
|
+
try {
|
|
21
|
+
// Handle unused imports
|
|
22
|
+
const importDecls = sourceFile.getImportDeclarations();
|
|
23
|
+
for (const importDecl of importDecls) {
|
|
24
|
+
const namedImports = importDecl.getNamedImports();
|
|
25
|
+
const unusedSpecifiers = [];
|
|
26
|
+
for (const specifier of namedImports) {
|
|
27
|
+
const symbol = specifier.getSymbol();
|
|
28
|
+
if (symbol && !this.isSymbolUsedInFile(symbol, sourceFile)) {
|
|
29
|
+
unusedSpecifiers.push(specifier);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (unusedSpecifiers.length > 0) {
|
|
33
|
+
if (unusedSpecifiers.length === namedImports.length) {
|
|
34
|
+
// All imports unused - remove entire declaration
|
|
35
|
+
const declText = importDecl.getText();
|
|
36
|
+
importDecl.remove();
|
|
37
|
+
changes.push({
|
|
38
|
+
file: getRelativePath(context, error.file),
|
|
39
|
+
description: `Removed unused import: ${declText.trim()}`,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
// Remove only unused specifiers
|
|
44
|
+
for (const spec of unusedSpecifiers) {
|
|
45
|
+
const specText = spec.getText();
|
|
46
|
+
spec.remove();
|
|
47
|
+
changes.push({
|
|
48
|
+
file: getRelativePath(context, error.file),
|
|
49
|
+
description: `Removed unused import specifier: ${specText}`,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// Fix formatting if needed
|
|
53
|
+
const syntaxList = importDecl.getFirstChildByKind(SyntaxKind.NamedImports)?.getFirstChildByKind(SyntaxKind.SyntaxList);
|
|
54
|
+
if (syntaxList) {
|
|
55
|
+
syntaxList.forEach?.(() => { });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
fixedCount += unusedSpecifiers.length;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Handle unused variables (const/let/var declarations)
|
|
62
|
+
const variableDecls = sourceFile.getVariableDeclarations();
|
|
63
|
+
for (const varDecl of variableDecls) {
|
|
64
|
+
const symbol = varDecl.getSymbol();
|
|
65
|
+
if (symbol && !this.isSymbolUsedInFile(symbol, sourceFile)) {
|
|
66
|
+
// Check if it's a simple unused variable (not part of destructuring used elsewhere)
|
|
67
|
+
const parent = varDecl.getParent();
|
|
68
|
+
if (parent && parent.getKind() === SyntaxKind.VariableDeclarationList) {
|
|
69
|
+
const declarations = parent.getDeclarations?.() || [];
|
|
70
|
+
if (declarations.length === 1) {
|
|
71
|
+
// Single declaration - remove entire statement
|
|
72
|
+
const statement = parent.getParent();
|
|
73
|
+
if (statement) {
|
|
74
|
+
const stmtText = statement.getText();
|
|
75
|
+
statement.remove();
|
|
76
|
+
changes.push({
|
|
77
|
+
file: getRelativePath(context, error.file),
|
|
78
|
+
description: `Removed unused variable declaration: ${stmtText.trim()}`,
|
|
79
|
+
});
|
|
80
|
+
fixedCount++;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (fixedCount > 0) {
|
|
87
|
+
saveChanges(context);
|
|
88
|
+
const newText = sourceFile.getFullText();
|
|
89
|
+
const diff = this.generateDiff(originalText, newText, error.file);
|
|
90
|
+
if (changes.length > 0) {
|
|
91
|
+
changes[changes.length - 1].diff = diff;
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
success: true,
|
|
95
|
+
message: `Removed ${fixedCount} unused import(s)/variable(s)`,
|
|
96
|
+
changes,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
return { success: false, message: 'No unused imports/variables found to remove', changes };
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
103
|
+
return { success: false, message: `Fix failed: ${msg}`, changes };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
isSymbolUsedInFile(symbol, sourceFile) {
|
|
107
|
+
try {
|
|
108
|
+
const references = symbol.getReferences();
|
|
109
|
+
return references.some((ref) => {
|
|
110
|
+
const node = ref.getNode();
|
|
111
|
+
return node && node.getSourceFile() === sourceFile && node !== symbol.getDeclarations()[0];
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
generateDiff(oldText, newText, fileName) {
|
|
119
|
+
const oldLines = oldText.split('\n');
|
|
120
|
+
const newLines = newText.split('\n');
|
|
121
|
+
let diff = `--- ${fileName}\n+++ ${fileName}\n`;
|
|
122
|
+
// Simple line-by-line diff
|
|
123
|
+
const maxLen = Math.max(oldLines.length, newLines.length);
|
|
124
|
+
for (let i = 0; i < maxLen; i++) {
|
|
125
|
+
const oldLine = oldLines[i];
|
|
126
|
+
const newLine = newLines[i];
|
|
127
|
+
if (oldLine !== newLine) {
|
|
128
|
+
if (oldLine !== undefined)
|
|
129
|
+
diff += `-${oldLine}\n`;
|
|
130
|
+
if (newLine !== undefined)
|
|
131
|
+
diff += `+${newLine}\n`;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return diff;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
export const unusedImportRemovalStrategy = new UnusedImportRemovalStrategy();
|
|
138
|
+
//# sourceMappingURL=unusedImportRemoval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unusedImportRemoval.js","sourceRoot":"","sources":["../../src/strategies/unusedImportRemoval.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sudu-cli/fronted-preview-mcp",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.5",
|
|
4
4
|
"description": "MCP server for frontend project detection, dev server management, and preview workflow. Pairs with chrome-devtools-mcp for automated frontend checking.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|