import { mkdtemp, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { createNodeFsStorage } from "@suaveplan/storage-file"; import { createHttpStorage } from "@suaveplan/storage-http"; import { afterEach, beforeEach, describe, expect, it, } from "@suaveplan/testing/runner"; import type { StorageLike } from "@suaveplan/types"; import { createStorageUriResolver } from "../../src/index.js"; import type { UriPlugin } from "../../src/types/plugin.types.js"; function fileUriPlugin(adapter: StorageLike, rootDir: string): UriPlugin { return { scheme: "file", adapter, parse(uri) { // file:///abs/path → key relative to rootDir. const prefix = "file://"; const rest = uri.startsWith(prefix) ? uri.slice(prefix.length) : uri; const abs = rest.startsWith("/") ? rest : `/${rest}`; const root = rootDir.endsWith("/") ? rootDir : `${rootDir}/`; const key = abs.startsWith(root) ? abs.slice(root.length) : abs.replace(/^\//, ""); return { key }; }, build(key) { const root = rootDir.endsWith("/") ? rootDir : `${rootDir}/`; return `file://${root}${key}`; }, }; } function httpsUriPlugin(adapter: StorageLike): UriPlugin { return { scheme: "https", adapter, parse(uri) { const url = new URL(uri); return { key: url.pathname.replace(/^\//, ""), meta: { host: url.host }, }; }, }; } describe("cross-scheme integration", () => { let root: string; beforeEach(async () => { root = await mkdtemp(join(tmpdir(), "storage-uri-int-")); }); afterEach(async () => { await rm(root, { recursive: true, force: true }); }); it("composes a resolver with real storage-file and storage-http adapters", { timeout: 15000, }, async () => { const fileAdapter = createNodeFsStorage({ rootDir: root }); // In-process fetch stub serving a single payload at a known URL. const payload = new TextEncoder().encode("from-http"); const httpAdapter = createHttpStorage({ baseUrl: "https://origin.test/", fetch: async (input: unknown) => { const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input instanceof Request ? input.url : String((input as { url?: string }).url ?? input); if (url.endsWith("/poster.bin")) { return new Response(payload, { status: 200 }); } return new Response("not found", { status: 404 }); }, }); const resolver = createStorageUriResolver([ fileUriPlugin(fileAdapter, root), httpsUriPlugin(httpAdapter), ]); // HTTP read. const httpBytes = await resolver.read("https://origin.test/poster.bin"); expect(new TextDecoder().decode(httpBytes)).toBe("from-http"); // File round-trip via resolver. const fileUri = `file://${root}/cache/copy.bin`; await resolver.write(fileUri, httpBytes); const back = await resolver.read(fileUri); expect(new TextDecoder().decode(back)).toBe("from-http"); expect(await resolver.exists(fileUri)).toBe(true); }); });