Drivers

Azure Blob Storage Driver

Upload files to Azure Blob Storage with Shared Key or SAS auth, no Azure SDK

Uploads files to Azure Blob Storage with pure fetch and Web Crypto: Shared Key and SAS signatures are computed in-process, so there is no Azure SDK and it runs on Node.js, Bun, Deno, and edge runtimes.

npm install @fileway/core @fileway/azure
import { FilewayClient } from "@fileway/core";
import { AzureDriver } from "@fileway/azure";

const client = new FilewayClient({
  driver: new AzureDriver({
    container: "uploads",
    accountName: "mystorageaccount",
    accountKey: process.env.AZURE_STORAGE_KEY!,
  }),
});

const result = await client.upload(stream, {
  filename: "report.pdf",
  path: "invoices/2026",
  mimeType: "application/pdf",
});

console.log(result.meta.container);
console.log(result.meta.etag);

Authentication

Pick one:

  • accountName + accountKey: Shared Key auth. Also needed for presigned URLs.
  • sasToken: a SAS token with the permissions you need (read, create, write, delete). Requests carry the token instead of a signature.
  • connectionString: the connection string from the portal. Explicit options override its values.
new AzureDriver({ container: "uploads", connectionString: process.env.AZURE_STORAGE_CONNECTION_STRING! });

Upload strategy

The stream is read one block at a time, so memory stays bounded by blockSize (default 8 MiB) whatever the file size:

  • Fits in one block: a single Put Blob.
  • Larger, or unknown size: Put Block for each block, then Put Block List to commit them.

Staged blocks are invisible until they are committed. If the upload fails, is cancelled, or the stream does not match a declared size, nothing is committed (an existing blob at that path is untouched), and Azure discards the staged blocks after 7 days.

Download and URLs

  • get(path) streams the blob.
  • getUrl(path) returns https://<account>.blob.core.windows.net/<container>/<path>, which works for containers with public read access. Set baseUrl for a CDN or custom domain.
  • getPresignedUrl(path, { expiresIn }) returns a read-only service SAS URL, up to 7 days. It needs accountKey.

Upload status

pathFor, head and isPending are implemented, so getUploadStatus reports complete, pending (blocks staged but not yet committed) or missing, and a lost upload response is recovered without uploading twice.

Azurite

For local development, run Azurite and use its connection string:

docker run -p 10000:10000 mcr.microsoft.com/azure-storage/azurite azurite-blob --blobHost 0.0.0.0
new AzureDriver({ container: "uploads", connectionString: "UseDevelopmentStorage=true" });

The container must exist; create it once with the Azure CLI, Storage Explorer or the portal.

Config

OptionTypeDefaultDescription
containerstringRequiredContainer name
accountNamestringStorage account name
accountKeystringAccount key (Shared Key auth and presigned URLs)
sasTokenstringSAS token, instead of an account key
connectionStringstringConnection string; UseDevelopmentStorage=true targets Azurite
endpointstringhttps://<account>.blob.core.windows.netBlob service endpoint
baseUrlstring<endpoint>/<container>Base URL for getUrl
blockSizenumber8 MiBBlock size, from 1 MiB to 4000 MiB
maxSizeBytesnumberReject larger uploads with size-exceeded

Metadata

AzureDriver implements BaseDriver<AzureMeta>

FieldTypeDescription
meta.containerstringContainer name
meta.etagstring | undefinedBlob ETag

options.metadata is stored as x-ms-meta-* blob metadata. Azure only accepts names made of letters, digits and underscores that do not start with a digit, so a key like user-id throws a validation error. Use userId or user_id.

Errors

All failures are StorageErrors (see the error reference). Codes come from Azure's x-ms-error-code, with an HTTP-status fallback:

CodeWhen
validationMalformed upload options, an unsupported metadata key, a size mismatch, or an invalid expiresIn.
configMissing container, account name or credentials, or a presigned URL without accountKey.
not-foundBlobNotFound, or HTTP 404.
bucket-not-foundContainerNotFound.
auth-failedAuthenticationFailed, AuthorizationFailure and related codes, or HTTP 401/403.
size-exceededOver maxSizeBytes, RequestBodyTooLarge, more than 50,000 blocks, or HTTP 413.
rate-limitedServerBusy, TooManyRequests, or HTTP 429. Safe to retry.
networkfetch failed before a response. Safe to retry.
provider-errorAny other non-2xx response. Safe to retry.

Was this page helpful?

On this page