cd93019: Add first-class NestJS support (#95). New files-sdk/nestjs subpath exports a dynamic FilesModule (forRoot() / forRootAsync()) that configures the gateway, mounts it at a configurable path (default /api/files) through Nest’s middleware layer, and shares the Files instance via DI — @InjectFiles() / FILES token, with the configured router under FILES_API. Works on both the Express adapter (create the app with bodyParser: false) and the Fastify adapter (no parser configuration needed — middleware runs before body parsing). @nestjs/common is a new optional peer dependency.
38317d8: Lightweight aws4fetch-powered engine for Cloudflare R2 (#76). r2({ client: "fetch" }) runs the HTTP adapter on a SigV4-signed fetch core (~2.5 KB gzipped, Web Crypto only) instead of @aws-sdk/client-s3 — no @aws-sdk/* installs needed. It covers upload, download (+ ranges), head, exists, delete, list (+ delimiter), server-side copy, presigned url(), and signedUploadUrl(); multipart/resumable uploads throw with guidance to the default "aws-sdk" client, and stream bodies are buffered before the single PUT. Hybrid binding mode (binding + HTTP credentials) now signs url() / signedUploadUrl() through the same fetch core unconditionally, so binding and hybrid Workers never pull the AWS SDK into their bundle. Adds aws4fetch as a regular (tree-shaken, ~2.5 KB) dependency.
8e6fee9: React Native / Expo support for files-sdk/client and the framework hooks. upload() now accepts a NativeFileRef ({ uri, name, type, size } — the shape Expo pickers return): presigned-POST targets stream the descriptor through React Native’s FormData, and every other path resolves the uri to a Blob automatically. download() falls back to buffering via arrayBuffer() on runtimes whose fetch never exposes Response.body (React Native), instead of returning an empty stream. Byte-body uploads fall back to sending raw bytes when the runtime’s Blob cannot be constructed from ArrayBuffer parts. Adds a React Native docs page under UI → Client.
8992d9a: FilesModule.forRootAsync(): the useFactory return type now excludes global (new FilesModuleFactoryResult type). A global returned from the factory was silently ignored — the DynamicModule needs it before the factory runs, so it only takes effect on FilesModuleAsyncOptions itself. Returning it from the factory is now a type error instead of a no-op.
8992d9a: r2() binding mode: url() and signedUploadUrl() reject again instead of throwing synchronously on misconfiguration (no hybrid credentials, responseContentDisposition without signing). A refactor had made these the only adapter methods that could throw before a .catch handler was attached, breaking direct/plugin adapter callers. Also corrects the R2BindingOptions.bucket doc comment — it is required for hybrid signing, not an error label.
8992d9a: StoredFile.blob() now works on React Native. RN’s Blob cannot be constructed from raw bytes, so blob() on a downloaded file threw at Blob construction — the exact platform the RN client work targets. On runtimes without byte-part Blobs, blob() now consumes the response’s native Response.blob() instead, and later text()/arrayBuffer() calls read back through that Blob (via Blob#arrayBuffer() or FileReader). If bytes were already materialized first, blob() throws a clear FilesError explaining the ordering instead of an opaque platform error.
8992d9a: The fetch S3 client (r2({ client: "fetch" }) and hybrid binding signing) now fails closed on keys containing . or .. path segments. WHATWG URL — used by both the SigV4 signer and fetch itself — collapses dot segments (even percent-encoded ones) before signing, so such keys were silently signed and sent for a different, normalized key, and under path-style addressing a .. segment could escape the bucket entirely. These keys now throw a permanent Provider error with guidance to use the aws-sdk client, which addresses them literally.
8992d9a: The fetch S3 client now maps post-dispatch failures to FilesError like everything else: a download/list/lazy-body read dying mid-stream, and signing errors in url() / signedUploadUrl() (e.g. an invalid contentType header value), previously escaped as raw runtime TypeErrors when the adapter was used directly.
5d83642: Fix useFiles recreating its internal store on every render. The store is now initialized lazily once (matching the abort-controller ref pattern), avoiding the wasted createStore() call and throwaway allocation on each render.