---
changelog:
  category: Release
  version: files-sdk@1.3.0
date: '2026-05-15T05:44:08Z'
seo:
  description: >-
    Add Appwrite adapter at files-sdk/appwrite exporting appwrite(), a wrapper
    around the official node-appwrite SDK's Storage API. Auto-loads endpoint…
title: files-sdk@1.3.0
type: changelog
---
### Minor Changes

-   2d3a569: Add Appwrite adapter at `files-sdk/appwrite` exporting `appwrite()`, a wrapper around the official `node-appwrite` SDK's `Storage` API. Auto-loads `endpoint`, `projectId`, and `key` from `APPWRITE_ENDPOINT` / `APPWRITE_PROJECT_ID` / `APPWRITE_API_KEY` (with `NEXT_PUBLIC_*` fallbacks for the first two), or accepts an existing `Client` or `Storage` instance via `client`. `list({ prefix })` is forwarded as a `startsWith("$id", prefix)` query against the canonical file ID — files created outside the adapter where the display `name` differs from `$id` won't be matched by prefix. `upload()` buffers stream bodies up-front since `InputFile.fromBuffer` has no streaming form, throws on `UploadOptions.cacheControl` and non-empty `UploadOptions.metadata` (Appwrite has no equivalent fields), and silently ignores `UploadOptions.contentType` (Appwrite auto-detects mime from the payload). `copy()` is read-then-write — Appwrite has no server-side copy primitive, so it costs an egress + an ingest and is not atomic. `url()` throws by default (Appwrite SDKs cannot mint signed read URLs with API keys); set `public: true` on a public bucket to return the constructed permanent `view` URL. `signedUploadUrl()` throws — Appwrite has no presigned upload primitive; use JWTs or the client SDK for direct uploads. Keys (Appwrite file IDs) must start with `[a-zA-Z0-9]` and use only `[a-zA-Z0-9._-]`, max 36 characters — invalid keys throw a `FilesError("Provider", ...)` before the API call. Errors are relabelled as `Appwrite error`, with `404`/`401`+`403`/`409` mapped to `NotFound`/`Unauthorized`/`Conflict`.
-   ed87e51: Add Backblaze B2 adapter at `files-sdk/backblaze-b2`, a thin S3 wrapper that derives the endpoint from the cluster code (`s3.<region>.backblazeb2.com`), defaults to virtual-hosted-style addressing, and auto-loads credentials from `B2_APPLICATION_KEY_ID` / `B2_APPLICATION_KEY`. Errors are relabelled as `Backblaze B2 error` and `publicBaseUrl` accepts B2's friendly download URL prefix for skipping signing on public buckets.
-   2a35ce1: Add `exists(key)` to the Files API. Returns `true` when the object exists and `false` when the adapter reports a not-found error, without fetching the object body. Implemented across all built-in adapters.
-   8ae51f0: Add Exoscale Object Storage (SOS) adapter at `files-sdk/exoscale`, a thin S3 wrapper that derives the endpoint from the zone code (`sos-<region>.exo.io` — `ch-gva-2`, `ch-dk-2`, `de-fra-1`, `de-muc-1`, `at-vie-1`, `at-vie-2`, `bg-sof-1`), defaults to virtual-hosted-style addressing, and auto-loads credentials from `EXOSCALE_API_KEY` / `EXOSCALE_API_SECRET`. Exoscale calls these zones but they fill the SigV4 region slot. Errors are relabelled as `Exoscale error`.
-   2c52f56: Add `files.file(key)` to return a `FileHandle` bound to a single key. The handle exposes `upload`, `download`, `head`, `exists`, `delete`, `url`, `signedUploadUrl`, `copyTo`, and `copyFrom` without re-passing the key each time. It's a thin wrapper over the same `Files` methods, so adapters do not need to implement anything extra.
-   8ae51f0: Add Filebase adapter at `files-sdk/filebase`, a thin S3 wrapper around Filebase's S3-compatible gateway in front of decentralized storage networks (IPFS, Sia, Storj — the backing network is chosen per-bucket in the dashboard). Uses the fixed `https://s3.filebase.com` endpoint with virtual-hosted-style addressing, defaults the SigV4 region to `"us-east-1"`, and auto-loads credentials from `FILEBASE_ACCESS_KEY_ID` / `FILEBASE_SECRET_ACCESS_KEY`. `publicBaseUrl` accepts an IPFS/Sia/Storj gateway prefix for skipping signing on public objects. Errors are relabelled as `Filebase error`.
-   8ae51f0: Add IBM Cloud Object Storage adapter at `files-sdk/ibm-cos`, a thin S3 wrapper that derives the endpoint from the region code (`s3.<region>.cloud-object-storage.appdomain.cloud` — `us-south`, `us-east`, `eu-de`, `eu-gb`, `jp-tok`, `au-syd`, `br-sao`, `ca-tor`, …), defaults to virtual-hosted-style addressing, and auto-loads credentials from `IBM_COS_ACCESS_KEY_ID` / `IBM_COS_SECRET_ACCESS_KEY`. Auth uses IBM Cloud's HMAC credentials (tick "Include HMAC Credential" in the service-credential Advanced options), not IAM API keys. For direct (no-egress) access from inside the same IBM Cloud region, pass `https://s3.direct.<region>.cloud-object-storage.appdomain.cloud` as an explicit `endpoint`. Errors are relabelled as `IBM Cloud Object Storage error`.
-   8ae51f0: Add iDrive e2 adapter at `files-sdk/idrive-e2`, a thin S3 wrapper that takes an explicit `endpoint` (iDrive e2 hostnames are tied to the provisioned bucket cluster and don't follow a public pattern — copy it from the iDrive e2 dashboard under Access Keys → Endpoint), defaults the SigV4 region to `"us-east-1"`, and auto-loads credentials from `IDRIVE_E2_ACCESS_KEY_ID` / `IDRIVE_E2_SECRET_ACCESS_KEY`. Errors are relabelled as `iDrive e2 error`.
-   8ae51f0: Add Oracle Cloud Infrastructure Object Storage adapter at `files-sdk/oracle-cloud`, a thin S3 wrapper around OCI's S3 compatibility layer. Requires both the tenancy `namespace` and a `region` to derive the endpoint (`<namespace>.compat.objectstorage.<region>.oraclecloud.com`); defaults to path-style addressing since OCI's wildcard TLS cert doesn't cover bucket subdomains under the namespace-prefixed host. Auth uses OCI's HMAC _Customer Secret Keys_ (distinct from regular API signing keys); credentials auto-load from `OCI_ACCESS_KEY_ID` / `OCI_SECRET_ACCESS_KEY`. Errors are relabelled as `Oracle Cloud error`.
-   8ae51f0: Add OVHcloud Object Storage adapter at `files-sdk/ovhcloud`, a thin S3 wrapper that derives the endpoint from the region code (`s3.<region>.io.cloud.ovh.net` — High Performance S3 tier), defaults to virtual-hosted-style addressing, and auto-loads credentials from `OVH_ACCESS_KEY_ID` / `OVH_SECRET_ACCESS_KEY`. For the Standard (Swift-backed) tier, pass `https://s3.<region>.cloud.ovh.net` as an explicit `endpoint`. Errors are relabelled as `OVHcloud error`.
-   8ae51f0: Add Scaleway Object Storage adapter at `files-sdk/scaleway`, a thin S3 wrapper that derives the endpoint from the region code (`s3.<region>.scw.cloud` — `fr-par`, `nl-ams`, `pl-waw`), defaults to virtual-hosted-style addressing, and auto-loads credentials from `SCW_ACCESS_KEY` / `SCW_SECRET_KEY`. Errors are relabelled as `Scaleway error`.
-   ed87e51: Add Tigris adapter at `files-sdk/tigris`, a thin S3 wrapper around Tigris's globally-distributed object storage. Uses the fixed `https://fly.storage.tigris.dev` endpoint with virtual-hosted-style addressing, defaults the SigV4 region to `"auto"` since Tigris doesn't route by region, and auto-loads credentials from `TIGRIS_ACCESS_KEY_ID` / `TIGRIS_SECRET_ACCESS_KEY`. Errors are relabelled as `Tigris error`.
-   8ae51f0: Add Vultr Object Storage adapter at `files-sdk/vultr`, a thin S3 wrapper that derives the endpoint from the region code (`<region>.vultrobjects.com` — `ewr`, `sjc`, `ams`, `blr`, `del`, `sgp`, `lux`), defaults to virtual-hosted-style addressing, and auto-loads credentials from `VULTR_ACCESS_KEY_ID` / `VULTR_SECRET_ACCESS_KEY`. Errors are relabelled as `Vultr error`.
-   ed87e51: Add Wasabi adapter at `files-sdk/wasabi`, a thin S3 wrapper that derives the endpoint from the region code (`s3.<region>.wasabisys.com`), defaults to virtual-hosted-style addressing, and auto-loads credentials from `WASABI_ACCESS_KEY_ID` / `WASABI_SECRET_ACCESS_KEY`. Region names mirror AWS but the endpoints are Wasabi's own; errors are relabelled as `Wasabi error`.

### Patch Changes

-   2aa92e1: URL-encode keys in `joinPublicUrl` to prevent injection attacks via special characters (`?`, `#`, spaces) in file keys. Uses segment-by-segment encoding to preserve `/` as a path separator.

    **Note:** Pass raw keys — this function handles encoding. Pre-encoded keys will be double-encoded (e.g. `%20` becomes `%2520`).

-   8982c51: Expand test coverage for `box`, `fs`, `onedrive`, `supabase`, and `openai/responses` adapters. Adds tests covering `mapBoxError` / `mapGraphError` non-API error shapes, trailing-slash key handling, no-extension content-type inference, cache-miss reuse and non-file conflict paths in Box, trailing-slash URL trimming in Supabase, and ENOENT mid-page plus non-ENOENT walk errors in the fs adapter. No behavior changes.
