93 lines
3.0 KiB
TypeScript
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);
|
|
});
|
|
});
|