Read-only
Lock a Files instance to reads only with `readonly: true` or `files.readonly()`, and make every write surface fail consistently with `FilesError { code: "ReadOnly" }`.
When a caller should be able to inspect storage but never mutate it, lock the client at construction:
const files = new Files({
adapter: s3({ bucket: "uploads" }),
readonly: true,
});Or derive a read-only view from an existing configured client:
const files = new Files({
adapter: s3({ bucket: "uploads" }),
prefix: "users",
timeout: 10_000,
});
const readOnlyFiles = files.readonly();The derived view reuses the same adapter, prefix, timeout, retries, and hooks. It does not clone storage state or create a second provider client.
What is still allowed
Read-only instances still support every read surface:
downloadheadexistslistlistAllurlfile(key)for a key-scoped read handle
What is blocked
Every write surface throws FilesError with code: "ReadOnly":
uploaddeletecopymovesignedUploadUrl- The equivalent
file(key)helpers:upload,delete,copyTo,copyFrom,moveTo,moveFrom,signedUploadUrl
try {
await readOnlyFiles.upload("avatars/123.png", file);
} catch (err) {
if (err instanceof FilesError && err.code === "ReadOnly") {
// switch to a writable Files instance
}
}What it does not lock down
Read-only applies to the unified Files API only. The raw escape hatch still exposes the underlying provider client unchanged, so code that writes through files.raw bypasses the guard by design.
Prefixes
Pass a prefix to the constructor and every key is resolved relative to it - prepended on the way in, stripped on the way out - so application code works in its own namespace.
Resumable uploads
Pause, resume, and abort a large upload through a control handle — and resume it in a later process from a serializable session token. A per-call option on upload, for the adapters whose provider exposes a resumable session.