v1.3.0

Minor
  • 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.

  • 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.

  • 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.

  • 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.ioch-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.

  • 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.

  • 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.

  • 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.cloudus-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.

  • 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.

  • 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.

  • 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.

  • Add Scaleway Object Storage adapter at files-sdk/scaleway, a thin S3 wrapper that derives the endpoint from the region code (s3.<region>.scw.cloudfr-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.

  • 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.

  • Add Vultr Object Storage adapter at files-sdk/vultr, a thin S3 wrapper that derives the endpoint from the region code (<region>.vultrobjects.comewr, 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.

  • 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
  • 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).

  • 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.