Files
suaveplan/packages/networking/drive/drive-uri/tests/integration/compose-with-storage-uri.test.ts
2026-05-27 23:47:53 +01:00

93 lines
3.0 KiB
TypeScript

import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { Drive } from "@suaveplan/drive";
import { createNodeFsStorage } from "@suaveplan/storage-file";
import {
createStorageUriResolver,
type UriPlugin,
} from "@suaveplan/storage-uri";
import {
afterEach,
beforeEach,
describe,
expect,
it,
} from "@suaveplan/testing/runner";
import { driveUriPlugin } from "../../src/plugins/drive/drive.js";
interface FileUriOptions {
readonly rootDir: string;
}
function fileUriPlugin(options: FileUriOptions): UriPlugin {
const adapter = createNodeFsStorage({
rootDir: options.rootDir,
mkdirp: true,
});
return {
scheme: "file",
adapter,
parse(uri: string) {
// file:///some/path -> key = "some/path"
const idx = uri.indexOf("://");
const after = uri.slice(idx + 3);
const pathStart = after.indexOf("/");
const path = pathStart >= 0 ? after.slice(pathStart + 1) : after;
return { key: path };
},
build(key: string) {
return `file:///${key.replace(/^\//, "")}`;
},
};
}
describe("compose-with-storage-uri integration", () => {
let rootDir: string;
let driveRoot: string;
let drive: Drive;
beforeEach(async () => {
rootDir = mkdtempSync(join(tmpdir(), "drive-uri-file-"));
driveRoot = mkdtempSync(join(tmpdir(), "drive-uri-drive-"));
const driveStorage = Object.assign(
createNodeFsStorage({ rootDir: driveRoot, mkdirp: true }),
{ id: "default" }
);
drive = new Drive(driveStorage);
await drive.initialize();
});
afterEach(async () => {
await drive.dispose();
rmSync(rootDir, { recursive: true, force: true });
rmSync(driveRoot, { recursive: true, force: true });
});
it("file:// and drive:// resolve through one StorageUriResolver", {
timeout: 30000,
}, async () => {
const resolver = createStorageUriResolver([
fileUriPlugin({ rootDir }),
driveUriPlugin({ drive, driveId: "primary" }),
]);
// Seed both backends with distinct bytes.
await drive.write("a.bin", new Uint8Array([0xaa]));
// Use the file plugin directly to write — the resolver rejects
// writes for drive:// (by design) so we exercise the file side via
// resolver.write to confirm it works.
await resolver.write("file:///b.bin", new Uint8Array([0xbb]));
const fileBytes = await resolver.read("file:///b.bin");
const driveBytes = await resolver.read("drive://primary/a.bin");
expect(Array.from(fileBytes)).toEqual([0xbb]);
expect(Array.from(driveBytes)).toEqual([0xaa]);
// Neither plugin sees the other's state.
expect(resolver.hasScheme("file")).toBe(true);
expect(resolver.hasScheme("drive")).toBe(true);
expect(resolver.schemeCount).toBe(2);
});
});