npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@akadenia/azure-storage

v2.7.1

Published

Microsoft Azure storage helper methods

Downloads

503

Readme

A TypeScript library that wraps Azure Blob, Table, and Queue Storage with a clean, consistent API. Supports both connection strings and Managed Identity — so it works the same in local dev and production Azure environments.

Documentation · GitHub · Issues

Features

  • Blob Storage: Upload, download, list, and manage blobs with SAS URL support
  • Table Storage: Complete CRUD operations for Azure Table Storage
  • Queue Storage: Send, receive, and manage queue messages
  • Managed Identity Support: Passwordless authentication using Azure Managed Identity (system-assigned and user-assigned)
  • SAS URL Support: Generate Shared Access Signature URLs — User Delegation SAS with Managed Identity, Service SAS with connection strings
  • TypeScript Support: Full type definitions included
  • Error Handling: Built-in error handling and validation

Table of Contents

Installation

npm install @akadenia/azure-storage --save

Quick Start

Prerequisites

You can authenticate using either:

  • Connection String: Get this from the Azure Portal under your storage account's "Access keys" section
  • Managed Identity: For applications running in Azure (recommended for production)

Option 1: Connection string

import { BlobStorage, TableStorage, QueueStorage } from '@akadenia/azure-storage';

const connectionString = "DefaultEndpointsProtocol=https;AccountName=yourstorageaccount;AccountKey=yourkey;EndpointSuffix=core.windows.net";

const blobStorage  = new BlobStorage(connectionString);
const tableStorage = new TableStorage(connectionString, 'tableName');
const queueStorage = new QueueStorage(connectionString);

Option 2: Managed Identity (recommended for production)

import { BlobStorage, TableStorage, QueueStorage } from '@akadenia/azure-storage';

const blobStorage  = new BlobStorage({ accountName: 'yourstorageaccount' });
const tableStorage = new TableStorage({ accountName: 'yourstorageaccount', tableName: 'tableName' });
const queueStorage = new QueueStorage({ accountName: 'yourstorageaccount' });

Blob Storage

The BlobStorage class provides methods to interact with Azure Blob Storage.

Basic Setup

import { BlobStorage } from '@akadenia/azure-storage';

const blobStorage = new BlobStorage(connectionString);

Container Operations

// Create a container
const containerCreated = await blobStorage.createContainer('my-container');
console.log('Container created:', containerCreated);

// Delete a container
const containerDeleted = await blobStorage.deleteContainer('my-container');
console.log('Container deleted:', containerDeleted);

Upload Operations

// Upload data from Buffer
const data = Buffer.from('Hello, Azure Blob Storage!');
const uploaded = await blobStorage.uploadData('my-container', 'my-blob.txt', data, {
  blobContentType: 'text/plain'
});

// Upload from stream
import { Readable } from 'stream';
const stream = Readable.from(['Stream data content']);
await blobStorage.uploadStream('my-container', 'stream-blob.txt', stream, {
  blobContentType: 'text/plain'
});

// Upload with additional headers
await blobStorage.uploadData('my-container', 'document.pdf', pdfBuffer, {
  blobContentType: 'application/pdf',
  blobCacheControl: 'max-age=3600',
  blobContentEncoding: 'gzip'
});

// Legacy upload method
await blobStorage.upload('my-container', 'file.pdf', buffer, buffer.length, 'application/pdf');

Download Operations

// Download blob as Buffer
const blobData = await blobStorage.downloadBlob('my-container', 'my-blob.txt');
console.log('Downloaded content:', blobData.toString());

// Check if blob exists before downloading
const exists = await blobStorage.blobExists('my-container', 'my-blob.txt');
if (exists) {
  const data = await blobStorage.downloadBlob('my-container', 'my-blob.txt');
}

List Operations

// List all blobs with a prefix
const blobs = await blobStorage.listBlobs('my-container', 'documents/');
blobs.forEach(blob => {
  console.log(`Blob: ${blob.name}, Size: ${blob.properties.contentLength}`);
});

Delete Operations

const deleted = await blobStorage.deleteBlob('my-container', 'my-blob.txt');
console.log('Blob deleted:', deleted);

SAS URL Generation

generateSASUrl supports two SAS token types automatically:

  • User Delegation SAS — used with Managed Identity (more secure, no account keys)
  • Service SAS — used with connection string authentication
import { BlobPermissions } from '@akadenia/azure-storage';

// Read-only SAS, 1 hour expiry
const sasUrl = await blobStorage.generateSASUrl('my-container', 'my-blob.txt', {
  startsOn: new Date(),
  expiresOn: new Date(Date.now() + 3600 * 1000),
  permissions: [BlobPermissions.READ]
});
console.log('SAS URL:', sasUrl.fullUrlWithSAS);

// Write-enabled container-level SAS
const containerSas = await blobStorage.generateSASUrl('my-container', undefined, {
  permissions: [BlobPermissions.ADD, BlobPermissions.WRITE],
  expiresOn: new Date(Date.now() + 24 * 3600 * 1000)
});

SAS Permissions

import { BlobPermissions } from '@akadenia/azure-storage';

BlobPermissions.READ    // "r"
BlobPermissions.WRITE   // "w"
BlobPermissions.CREATE  // "c"
BlobPermissions.DELETE  // "d"
BlobPermissions.ADD     // "a"

Table Storage

The TableStorage class provides methods to interact with Azure Table Storage.

Basic Setup

import { TableStorage, ITableEntity } from '@akadenia/azure-storage';

const tableStorage = new TableStorage(connectionString, 'MyTable');

Table Management

const tableCreated = await tableStorage.createTable();
const tableDeleted = await tableStorage.deleteTable();

Entity Operations

interface UserEntity extends ITableEntity {
  partitionKey: string;
  rowKey: string;
  name: string;
  email: string;
  age: number;
  isActive: boolean;
}

// Insert
const user: UserEntity = {
  partitionKey: 'users',
  rowKey: 'user-123',
  name: 'John Doe',
  email: '[email protected]',
  age: 30,
  isActive: true
};
await tableStorage.insert(user);

// Get
const retrievedUser = await tableStorage.get('users', 'user-123');

// Update
user.age = 31;
await tableStorage.update(user);

// Upsert (insert or update)
await tableStorage.upsert(newUser);

// Delete
await tableStorage.delete('users', 'user-123');

List Operations

// List all entities
const allUsers = await tableStorage.list<UserEntity>();

// List with filter
const activeUsers = await tableStorage.list<UserEntity>({
  queryOptions: { filter: "isActive eq true and age gt 25" }
});

// Access underlying TableClient for advanced operations
const tableClient = tableStorage.getTableClient();

Queue Storage

The QueueStorage class provides methods to interact with Azure Queue Storage.

Basic Setup

import { QueueStorage } from '@akadenia/azure-storage';

const queueStorage = new QueueStorage(connectionString);
// or with Managed Identity:
const queueStorage = new QueueStorage({ accountName: 'yourstorageaccount' });

Message Operations

// Send a string message (base64 encoded by default)
await queueStorage.sendMessage('my-queue', 'Hello, Queue!');

// Send an object (auto JSON stringified + base64 encoded)
await queueStorage.sendMessage('my-queue', { orderNumber: '12345', action: 'process' });

// Send without base64 encoding
await queueStorage.sendMessage('my-queue', 'plain text', false);

// Receive messages
const { receivedMessageItems } = await queueStorage.receiveMessages('my-queue', 5, 30);

// Process and delete
for (const message of receivedMessageItems) {
  const decoded = Buffer.from(message.messageText, 'base64').toString('utf-8');
  const data = JSON.parse(decoded);
  // ... process data ...
  await queueStorage.deleteMessage('my-queue', message.messageId, message.popReceipt);
}

// Peek without consuming
const { peekedMessageItems } = await queueStorage.peekMessages('my-queue', 5);

Queue Management

await queueStorage.createQueue('my-new-queue');

const exists = await queueStorage.queueExists('my-queue');
const count  = await queueStorage.getMessageCount('my-queue');

await queueStorage.clearMessages('my-queue');
await queueStorage.deleteQueue('old-queue');

// Access underlying QueueClient for advanced options
const queueClient = queueStorage.getQueueClient('my-queue');
await queueClient.sendMessage('Custom', {
  visibilityTimeoutInSeconds: 30,
  timeToLiveInSeconds: 3600
});

Integration Example: Order Processing Pipeline

class OrderProcessor {
  private queueStorage: QueueStorage;

  constructor(connectionString: string) {
    this.queueStorage = new QueueStorage(connectionString);
  }

  async queueOrder(orderNumber: string): Promise<void> {
    await this.queueStorage.sendMessage('orders-to-process', { orderNumber, timestamp: Date.now() });
  }

  async processOrders(): Promise<void> {
    const { receivedMessageItems } = await this.queueStorage.receiveMessages('orders-to-process', 10);

    for (const message of receivedMessageItems) {
      try {
        const decoded = Buffer.from(message.messageText, 'base64').toString('utf-8');
        const order = JSON.parse(decoded);
        console.log(`Processing order ${order.orderNumber}`);
        await this.queueStorage.deleteMessage('orders-to-process', message.messageId, message.popReceipt);
      } catch (error) {
        console.error('Failed to process message:', error);
        // Message will become visible again after visibility timeout
      }
    }
  }
}

Configuration

Environment Variables

const connectionString = process.env.AZURE_STORAGE_CONNECTION_STRING;
if (!connectionString) throw new Error('AZURE_STORAGE_CONNECTION_STRING is required');

Local Development with Azurite

const blobStorage  = new BlobStorage("UseDevelopmentStorage=true");
const tableStorage = new TableStorage("UseDevelopmentStorage=true", 'MyTable');
const queueStorage = new QueueStorage("UseDevelopmentStorage=true");

Managed Identity Authentication

System-Assigned (Most Common)

Automatically created when you enable managed identity on your Azure resource — no client ID needed.

const blobStorage  = new BlobStorage({ accountName: 'yourstorageaccount' });
const tableStorage = new TableStorage({ accountName: 'yourstorageaccount', tableName: 'MyTable' });
const queueStorage = new QueueStorage({ accountName: 'yourstorageaccount' });

User-Assigned

A standalone identity shared across multiple Azure resources. Requires the client ID.

const blobStorage = new BlobStorage({
  accountName: 'yourstorageaccount',
  managedIdentityClientId: 'your-client-id'
});

Environment-Based Configuration

const blobStorage = process.env.NODE_ENV === 'production'
  ? new BlobStorage({ accountName: process.env.AZURE_STORAGE_ACCOUNT_NAME! })
  : new BlobStorage(process.env.AZURE_STORAGE_CONNECTION_STRING!);

Note: When using Managed Identity, ensure your Azure resource has the appropriate role assignments:

  • Storage Blob Data Contributor for Blob Storage
  • Storage Table Data Contributor for Table Storage
  • Storage Queue Data Contributor for Queue Storage

Error Handling

try {
  const blobData = await blobStorage.downloadBlob('container', 'non-existent.txt');
} catch (error) {
  if (error.statusCode === 404) {
    console.log('Blob not found');
  } else {
    console.error('Error downloading blob:', error);
  }
}

Best Practices

1. Use Managed Identity in Production

const blobStorage = process.env.NODE_ENV === 'production'
  ? new BlobStorage({ accountName: process.env.AZURE_STORAGE_ACCOUNT_NAME! })
  : new BlobStorage(process.env.AZURE_STORAGE_CONNECTION_STRING!);

2. Short-Lived SAS URLs

const sasUrl = await blobStorage.generateSASUrl('container', 'blob', {
  permissions: [BlobPermissions.READ],
  expiresOn: new Date(Date.now() + 3600 * 1000) // 1 hour max
});

3. Always Handle Errors

async function safeUpload(container: string, name: string, data: Buffer) {
  try {
    return await blobStorage.uploadData(container, name, data);
  } catch (error) {
    console.error('Upload failed:', error);
    throw error;
  }
}

4. Clean Up Temporary Resources

async function cleanup() {
  try {
    await blobStorage.deleteContainer('temp-container');
    await tableStorage.deleteTable();
  } catch (error) {
    console.error('Cleanup failed:', error);
  }
}

API Reference

BlobStorage

| Method | Description | Returns | |---|---|---| | createContainer(containerName) | Creates a container if it doesn't exist | Promise<boolean> | | deleteContainer(containerName) | Deletes a container | Promise<boolean> | | upload(container, blob, buffer, length, contentType) | Uploads a buffer (legacy) | Promise<boolean> | | uploadData(container, blob, data, headers?) | Uploads a Buffer with optional headers | Promise<boolean> | | uploadStream(container, blob, stream, headers?) | Uploads a readable stream | Promise<boolean> | | downloadBlob(container, blob) | Downloads a blob as Buffer | Promise<Buffer> | | blobExists(container, blob) | Checks if a blob exists | Promise<boolean> | | listBlobs(container, prefix) | Lists blobs with a prefix | Promise<BlobItem[]> | | deleteBlob(container, blob) | Deletes a blob | Promise<boolean> | | generateSASUrl(container, blob?, options?) | Generates a SAS URL | Promise<SASUrlComponents> |

TableStorage

| Method | Description | Returns | |---|---|---| | createTable() | Creates the table | Promise<boolean> | | deleteTable() | Deletes the table | Promise<boolean> | | insert(entity) | Inserts an entity | Promise<boolean> | | update(entity) | Updates an entity | Promise<boolean> | | upsert(entity) | Inserts or updates an entity | Promise<boolean> | | get(partitionKey, rowKey) | Gets an entity | Promise<GetTableEntityResponse> | | delete(partitionKey, rowKey) | Deletes an entity | Promise<boolean> | | list(options?) | Lists entities with optional filter | Promise<T[]> | | getTableClient() | Returns the underlying TableClient | TableClient |

QueueStorage

| Method | Description | Returns | |---|---|---| | getQueueClient(queueName) | Gets a QueueClient | QueueClient | | sendMessage(queue, message, base64Encode?) | Sends a message | Promise<QueueSendMessageResponse> | | receiveMessages(queue, maxMessages?, visibilityTimeout?) | Receives messages | Promise<any> | | deleteMessage(queue, messageId, popReceipt) | Deletes a message | Promise<void> | | peekMessages(queue, maxMessages?) | Peeks messages without consuming | Promise<any> | | clearMessages(queue) | Clears all messages | Promise<void> | | createQueue(queue) | Creates a queue | Promise<void> | | deleteQueue(queue) | Deletes a queue | Promise<void> | | queueExists(queue) | Checks if a queue exists | Promise<boolean> | | getMessageCount(queue) | Gets approximate message count | Promise<number> |


Contributing

We welcome contributions! Please feel free to submit a Pull Request.

Development Setup

git clone https://github.com/akadenia/AkadeniaAzureStorage.git
cd AkadeniaAzureStorage
pnpm install
pnpm run build
pnpm test:with-azurite  # requires Azurite running locally

Commit Message Guidelines

We follow Conventional Commits. Scope is required.

type(scope): description

Common scopes: blob · table · queue · docs · deps · test · build · ci

Types: feat · fix · docs · style · refactor · test · chore

Requirements

  • Node.js >= 20
  • Azure Storage account (or Azurite for local development)

License

MIT

Support

For support, please open an issue on GitHub.