83 lines
2.5 KiB
TypeScript
83 lines
2.5 KiB
TypeScript
import * as plugins from './mod.plugins.js';
|
|
import { FormatContext } from './classes.formatcontext.js';
|
|
import type { IPlannedChange } from './interfaces.format.js';
|
|
import { Project } from '../classes.project.js';
|
|
|
|
export abstract class BaseFormatter {
|
|
protected context: FormatContext;
|
|
protected project: Project;
|
|
protected stats: any; // Will be FormatStats from context
|
|
|
|
constructor(context: FormatContext, project: Project) {
|
|
this.context = context;
|
|
this.project = project;
|
|
this.stats = context.getFormatStats();
|
|
}
|
|
|
|
abstract get name(): string;
|
|
abstract analyze(): Promise<IPlannedChange[]>;
|
|
abstract applyChange(change: IPlannedChange): Promise<void>;
|
|
|
|
async execute(changes: IPlannedChange[]): Promise<void> {
|
|
const startTime = this.stats.moduleStartTime(this.name);
|
|
this.stats.startModule(this.name);
|
|
|
|
try {
|
|
await this.preExecute();
|
|
|
|
for (const change of changes) {
|
|
try {
|
|
await this.applyChange(change);
|
|
this.stats.recordFileOperation(this.name, change.type, true);
|
|
} catch (error) {
|
|
this.stats.recordFileOperation(this.name, change.type, false);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
await this.postExecute();
|
|
} catch (error) {
|
|
// Don't rollback here - let the FormatPlanner handle it
|
|
throw error;
|
|
} finally {
|
|
this.stats.endModule(this.name, startTime);
|
|
}
|
|
}
|
|
|
|
protected async preExecute(): Promise<void> {
|
|
// Override in subclasses if needed
|
|
}
|
|
|
|
protected async postExecute(): Promise<void> {
|
|
// Override in subclasses if needed
|
|
}
|
|
|
|
protected async modifyFile(filepath: string, content: string): Promise<void> {
|
|
// Validate filepath before writing
|
|
if (!filepath || filepath.trim() === '') {
|
|
throw new Error(`Invalid empty filepath in modifyFile`);
|
|
}
|
|
|
|
// Ensure we have a proper path with directory component
|
|
// If the path has no directory component (e.g., "package.json"), prepend "./"
|
|
let normalizedPath = filepath;
|
|
if (!plugins.path.parse(filepath).dir) {
|
|
normalizedPath = './' + filepath;
|
|
}
|
|
|
|
await plugins.smartfile.memory.toFs(content, normalizedPath);
|
|
}
|
|
|
|
protected async createFile(filepath: string, content: string): Promise<void> {
|
|
await plugins.smartfile.memory.toFs(content, filepath);
|
|
}
|
|
|
|
protected async deleteFile(filepath: string): Promise<void> {
|
|
await plugins.smartfile.fs.remove(filepath);
|
|
}
|
|
|
|
protected async shouldProcessFile(filepath: string): Promise<boolean> {
|
|
return true;
|
|
}
|
|
}
|