refactor: inject CLI I/O and diagnostics

This commit is contained in:
vorotamoroz
2026-07-17 16:01:48 +00:00
parent 1b4a0d76dd
commit 97964fddf1
23 changed files with 422 additions and 236 deletions
@@ -7,6 +7,7 @@ import { NodeStorageAdapter } from "@vrtmrz/livesync-commonlib/node";
import { NodeVaultAdapter } from "./NodeVaultAdapter";
import type { NodeFile, NodeFolder, NodeStat } from "./NodeTypes";
import { fsPromises as fs, path } from "@vrtmrz/livesync-commonlib/node";
import type { CliDiagnosticReporter } from "@/apps/cli/cliOutput";
/**
* Complete file system adapter implementation for Node.js
@@ -20,7 +21,10 @@ export class NodeFileSystemAdapter implements IFileSystemAdapter<NodeFile, NodeF
private fileCache = new Map<string, NodeFile>();
constructor(private basePath: string) {
constructor(
private basePath: string,
private reportDiagnostic: CliDiagnosticReporter = () => undefined
) {
this.path = new NodePathAdapter();
this.typeGuard = new NodeTypeGuardAdapter();
this.conversion = new NodeConversionAdapter();
@@ -33,7 +37,7 @@ export class NodeFileSystemAdapter implements IFileSystemAdapter<NodeFile, NodeF
}
private normalisePath(p: FilePath | string): string {
return this.path.normalisePath(p as string);
return this.path.normalisePath(p);
}
private async hasExactPathCase(pathStr: string): Promise<boolean> {
@@ -169,7 +173,7 @@ export class NodeFileSystemAdapter implements IFileSystemAdapter<NodeFile, NodeF
}
} catch (error) {
// Directory doesn't exist or is not readable
console.error(`Error scanning directory ${fullPath}:`, error);
this.reportDiagnostic(`Error scanning directory ${fullPath}:`, error);
}
}
}
@@ -1,5 +1,5 @@
import { fsPromises, os, path } from "@vrtmrz/livesync-commonlib/node";
import { describe, expect, it } from "vitest";
import { describe, expect, it, vi } from "vitest";
import type { FilePath } from "@vrtmrz/livesync-commonlib/compat/common/types";
import { NodeFileSystemAdapter } from "./NodeFileSystemAdapter";
import { NodeVaultAdapter } from "./NodeVaultAdapter";
@@ -46,4 +46,22 @@ describe("NodeFileSystemAdapter path case", () => {
await fsPromises.rm(directory, { recursive: true, force: true });
}
});
it("reports directory scan failures through the injected diagnostic callback", async () => {
const directory = await fsPromises.mkdtemp(path.join(os.tmpdir(), "livesync-scan-diagnostic-"));
const missingDirectory = path.join(directory, "missing");
const reportDiagnostic = vi.fn();
try {
const adapter = new NodeFileSystemAdapter(missingDirectory, reportDiagnostic);
await adapter.scanDirectory();
expect(reportDiagnostic).toHaveBeenCalledWith(
`Error scanning directory ${missingDirectory}:`,
expect.any(Error)
);
} finally {
await fsPromises.rm(directory, { recursive: true, force: true });
}
});
});