Skip to content

AzureBlob API

github-actions[bot] edited this page Sep 29, 2026 · 1 revision

AzureBlob API

Configuration

import { AzureBlob } from '@tundraconnect/azure-blob';

// Shared Key (primary)
const client = new AzureBlob({
  auth: {
    type: 'CUSTOM',
    account: 'myaccount',
    accountKey: 'base64-shared-key',
  },
  apiVersion: '2021-08-06', // optional, this is the default
});

// Pre-generated SAS token (secondary, pass-through only — this connect
// does not generate SAS tokens)
const sasClient = new AzureBlob({
  auth: {
    type: 'CUSTOM',
    account: 'myaccount',
    sasToken: 'sv=2021-08-06&ss=b&srt=co&sp=rwdlacx&se=...&sig=...',
  },
});

baseURL defaults to https://{account}.blob.core.windows.net (the classic Blob endpoint — not the Data Lake Storage Gen2 .dfs.core.windows.net host). Pass an explicit baseURL to target a local emulator such as Azurite instead.

When both accountKey and sasToken are supplied, sasToken wins — Shared Key signing is skipped entirely and the SAS token's query parameters are appended to every request instead. Supplying neither throws CONFIG_MISSING_CREDENTIALS.

Endpoints

Method Operation Azure REST call
putObject() Put Blob PUT /{container}/{blob}
getObject() Get Blob GET /{container}/{blob}
headObject() Get Blob Properties HEAD /{container}/{blob}
deleteObject() Delete Blob DELETE /{container}/{blob}
listObjects() List Blobs GET /{container}?restype=container&comp=list

The public parameter names are bucket/key (mapped internally onto Azure's own "container"/"blob" terms), matching the naming used across this repo's other object-storage connects.

import { AzureBlob } from '@tundraconnect/azure-blob';

const client = new AzureBlob({
  auth: {
    type: 'CUSTOM',
    account: 'myaccount',
    accountKey: 'base64-shared-key',
  },
});

// Upload
const put = await client.putObject({
  bucket: 'my-container',
  key: 'photos/cat.png',
  body: pngBytes,
  contentType: 'image/png',
  metadata: { uploadedBy: 'ada' },
});
console.log(put.etag, put.lastModified);

// Download
const { body, contentType, metadata } = await client.getObject({
  bucket: 'my-container',
  key: 'photos/cat.png',
});

// Properties only (no download)
const head = await client.headObject({
  bucket: 'my-container',
  key: 'photos/cat.png',
});
console.log(head.contentLength);

// List, one page at a time
let token: string | undefined;
do {
  const page = await client.listObjects({
    bucket: 'my-container',
    prefix: 'photos/',
    continuationToken: token,
  });
  for (const obj of page.objects) console.log(obj.key, obj.size);
  token = page.continuationToken;
} while (token);

// Delete
await client.deleteObject({ bucket: 'my-container', key: 'photos/cat.png' });

See Errors for failure handling and Schemas for response validation.


← Back to AzureBlob

Streaming

putObjectStream(options)

Uploads a large blob from a ReadableStream<Uint8Array> (or a Blob) as Put Block per chunk followed by one Put Block List, so only one block is ever in memory.

Why not a single streamed PUT: fetch sends a stream body with chunked transfer encoding and no Content-Length, which Blob Storage rejects and which Shared Key cannot sign. Committing blocks is Azure's own answer to large uploads, and uncommitted blocks persist for seven days.

Option Type Required Description
bucket, key string yes Container and blob name.
body ReadableStream<Uint8Array> | Blob yes The data.
contentType string no Set on the committed blob via x-ms-blob-content-type.
metadata Record<string,string> no x-ms-meta-* on the committed blob.
blockSize number no Bytes per block. Default 4 MiB; Azure allows up to 4000 MiB and 50,000 blocks.

Returns the same PutObjectResultSchema as putObject. Block ids are the zero-padded block index, base64-encoded (Azure requires equal-length ids). A failed block stops the upload before anything is committed, and the source stream is cancelled (best-effort) so a partially read file doesn't keep its handle open; a fully consumed source is never cancelled.

getObjectStream({ bucket, key, idleTimeout? })

Downloads a blob as an unread ReadableStream<Uint8Array> plus its contentType, contentLength, etag and lastModified. The body is never buffered; the vendor-wide timeout bounds only the wait for headers, after which an idle timer that resets on every chunk governs the transfer — idleTimeout (seconds, default 60) sets how long a stall is tolerated; raise it for very slow or bursty links. You own the stream — consume it or cancel() it.

const { body } = await client.getObjectStream({
  bucket: 'backups',
  key: 'big.bin',
});
await body.pipeTo((await Deno.create('big.bin')).writable);

Clone this wiki locally