# `@suaveplan/drive-uri/adapter` _(no submodules)_ ## Purpose Defines `DriveStorageLikeAdapter`, the internal shim that exposes a `Drive` instance as a `StorageLike` so it can be registered as the `adapter` of a `UriPlugin` consumed by `@suaveplan/storage-uri`'s `StorageUriResolver`. The shim is the join point between the drive-tier API (which throws on missing files) and the storage-tier contract (which returns `undefined` for missing keys) — every other failure path is preserved unchanged so the resolver can attach its own `STORAGE_URI.ADAPTER_ERROR` wrap. A second export, `isDriveNotFound`, walks the `cause` chain of a thrown value looking for any `SuaveplanError` whose `code` ends in `.NOT_FOUND`. This is the only place that has to know about Drive's not-found vocabulary; every plugin defers the translation to the shim. ## Features - Implements every required member of `StorageLike` (`get`, `set`, `delete`, `exists`, `list`, `clear`) plus the optional `createReadStream` extension used by `StorageUriResolver.open()`'s native-stream fast path. - Translates `Drive.read` not-found rejections into `undefined` from `get()` so the resolver's existing `undefined → STORAGE_URI.NOT_FOUND` mapping applies without modification. - Rejects `clear()` with a `DriveUriError(WRITE_UNSUPPORTED)` whose message names `Drive.delete(path)` as the supported alternative. - Forwards `AbortSignal` to `Drive.createReadStream` so consumers can cancel in-flight streams. ## Usage: Basic ```ts import { DriveStorageLikeAdapter } from "@suaveplan/drive-uri/adapter"; const adapter = new DriveStorageLikeAdapter(drive); const bytes = await adapter.get("folder/file.bin"); if (bytes === undefined) console.log("not found"); ``` ## Usage: Advanced Composing the shim with a custom `UriPlugin` (this is essentially what `driveUriPlugin` does internally): ```ts import { DriveStorageLikeAdapter } from "@suaveplan/drive-uri/adapter"; import type { UriPlugin } from "@suaveplan/storage-uri"; function myPlugin(drive: Drive): UriPlugin { const adapter = new DriveStorageLikeAdapter(drive); return { scheme: "my", adapter, parse(uri: string) { const path = uri.slice("my://".length); return { key: path }; }, }; } ``` ## API Reference - `class DriveStorageLikeAdapter implements StorageLike` — accepts a `Drive` in its constructor. All `StorageLike` methods delegate to the bound drive. - `DriveStorageLikeAdapter.createReadStream(key, signal?)` — forwards directly to `Drive.createReadStream(key, signal)`. - `function isDriveNotFound(err: unknown): boolean` — returns `true` when `err` (or anything in its `cause` chain, up to 8 levels deep with cycle detection) is a `SuaveplanError` whose `code` ends in `.NOT_FOUND`. ## Implementation Notes - The shim does NOT own any chunk codec, manifest fetching, peer discovery, or template validation — that all happens inside `Drive` via its installed middleware (`chunksPlugin`, `drive-mesh`, etc.). - `list()` accepts either of two shapes Drive may return (`{ keys }` vs. `{ entries: [{ path }] }`) and normalises to the `StorageLike` shape, preserving `continuationToken` when present. - `clear()` is intentionally a hard error rather than a soft no-op — wiping a Drive through the URI surface is a footgun, and a silent success would lose data on misuse. The supported path is `resolver.remove(uri)` per file. - `isDriveNotFound` includes cycle detection (depth-limit + self-reference check) so a malicious or accidental self-referential `cause` chain cannot cause an infinite loop.