@magnaboy/r2-client
v0.0.2
Published
Cloudflare R2 client with uploads, retries, signed URLs, and CORS management.
Readme
@magnaboy/r2-client
Node.js client for Cloudflare R2. Supports paginated listing, concurrent uploads and deletes with retries, signed upload URLs, object metadata, and bucket CORS.
Import R2Client from '@magnaboy/r2-client'. Configure accountId, accessKeyId, secretAccessKey, and bucketName in the constructor.
Requires Node.js 25+. Concurrency defaults to 15 and retries to 3. Folder and file name are concatenated directly. Include a trailing slash in the folder when needed.
Upload and delete return false and emit an error event after retries fail. List errors emit an error event and throw. Attach an error listener to handle failures.
Throwing object operations
R2ObjectStore provides head, getBuffer, getText, snapshot, put,
putFile, and destroy. Configure endpoint, bucket, accessKeyId, and
secretAccessKey. Call destroy() when finished to close SDK connections.
head and getText return null only for HTTP 404. snapshot returns
{ text, etag }, or two nulls for an absent object. Signed GETs request identity encoding;
snapshot rejects missing or weak ETags. Buffer/text reads retain the complete object in memory.
Writes accept contentType, cacheControl, signal, and optional expectedEtag:
omit the property for unconditional writes, pass null to create only, or pass the exact strong
quoted ETag to replace a matching object. HTTP errors throw ObjectStoreError with a
status and original cause; 412 never becomes an unconditional retry. If a response is
lost after the server commits, a retry can return 412: re-read and reconcile at the application
level. Do not assume the first write failed or blindly overwrite the object.
putFile streams a file and reopens it on each attempt, hashing its payload before upload.
Keep the file unchanged until completion. Defaults are three total attempts, exponential delays
starting at 500 ms, and one 120-second deadline across hashing, requests, body reads and retries.
Configure attempts, retryDelayMs, and timeoutMs; each operation also accepts an
AbortSignal. SDK retries are disabled so the object API owns the attempt budget. Only temporary
HTTP and selected transport failures retry. Invalid arguments, permission failures and conflicts
do not retry. The older boolean-returning R2Client upload API remains available unchanged.
pnpm test:unit tests the object API against a local HTTP server with fake credentials.
The coverage configuration covers the new R2ObjectStore API; legacy R2Client coverage is not claimed.
Application storage port
createR2ObjectStore({ accountId, accessKeyId, secretAccessKey, bucketName, publicUrl })
returns an ObjectStore with throwing put, delete, head, getBytes,
signedUploadUrl, and publicUrl operations. Call destroy() when finished.
Transfers share a concurrency limit (15 by default) and use the throwing object
API's retry rules. retries counts retries after the first attempt (default 3).
An optional endpoint supports other S3 services and local tests.
head returns { size, contentType } or null for 404. getBytes returns bytes
or null for 404. Permission errors throw. Signed uploads default to 300 seconds,
accept a lifetime of 1 to 604800 seconds, and can bind a nonnegative content length.
publicUrl joins the configured base and key, preserving the application's key convention.
The ObjectStore port and input/result types are also exported from
@magnaboy/r2-client/object-store, which has no Node or AWS imports.
R2ObjectStore exposes the added operations directly as headObject, getBytes,
delete, and signedUploadUrl. Its existing head return shape is unchanged.
