aab_node_storage_az_blob
v1.0.0
Published
Azure Blob Storage provider for AppSolve Application Blocks - implements StorageProvider interface for managing files in Azure Blob Storage
Maintainers
Readme
AppSolve Application Blocks - Azure Blob Storage Provider
Azure Blob Storage implementation of the StorageProvider interface for AppSolve Application Blocks. This package provides a unified interface for managing files in Azure Blob Storage using the storage core interface.
Installation
npm install aab_node_storage_az_blobPrerequisites
- Node.js: Version 18.0.0 or higher
- Azure Storage Account: You'll need an Azure Storage account with a connection string
- Azure Blob Container: A container in your storage account to store files
Quick Start
import { AzureBlobStorageProvider } from 'aab_node_storage_az_blob';
// Create provider instance
const provider = new AzureBlobStorageProvider({
connectionString: 'DefaultEndpointsProtocol=https;AccountName=youraccount;AccountKey=yourkey==;EndpointSuffix=core.windows.net',
containerName: 'your-container-name'
});
// Use the provider
async function example() {
// Store a file
const data = Buffer.from('Hello, Azure Blob Storage!', 'utf-8');
await provider.put('documents/greeting.txt', data);
// Retrieve the file
const content = await provider.get('documents/greeting.txt');
console.log(content.toString('utf-8')); // "Hello, Azure Blob Storage!"
// List files in a directory
const files = await provider.list('documents/');
console.log(files); // ['greeting.txt']
// Delete the file
await provider.delete('documents/greeting.txt');
}Configuration
AzureBlobStorageConfig
The AzureBlobStorageProvider constructor accepts a configuration object with the following properties:
interface AzureBlobStorageConfig {
/** Azure Storage connection string */
connectionString: string;
/** Container name to use for blob storage */
containerName: string;
}Connection String
You can find your Azure Storage connection string in the Azure Portal:
- Navigate to your Storage Account
- Go to Settings > Access keys
- Copy the connection string from key1 or key2
The connection string format is:
DefaultEndpointsProtocol=https;AccountName=<account-name>;AccountKey=<account-key>;EndpointSuffix=core.windows.netContainer Name
- Must be a valid Azure Blob container name (3-63 characters, lowercase letters, numbers, and hyphens)
- The container will be created automatically if it doesn't exist
- Should not contain uppercase letters or special characters except hyphens
API Reference
The AzureBlobStorageProvider implements the StorageProvider interface from aab_node_storage_core:
Methods
list(path: string): Promise<string[]>
Lists files and directories at the specified path.
Parameters:
path- The path to list contents for (e.g., 'documents/' or 'images/2024/')
Returns:
- Promise resolving to an array of file/directory names
Examples:
// List all files in root
const rootFiles = await provider.list('');
// List files in a specific directory
const docFiles = await provider.list('documents/');
const imageFiles = await provider.list('images/2024/');get(path: string): Promise<Buffer>
Retrieves the contents of a file at the specified path.
Parameters:
path- The path to the file to retrieve (e.g., 'documents/readme.txt')
Returns:
- Promise resolving to the file contents as a Buffer
Throws:
Errorwhen the file is not found or cannot be accessed
Examples:
// Get file contents as Buffer
const content = await provider.get('documents/readme.txt');
// Convert to string
const text = content.toString('utf-8');
// Get binary data (images, etc.)
const imageData = await provider.get('images/photo.jpg');put(path: string, data: Buffer): Promise<void>
Stores data at the specified path.
Parameters:
path- The path where the data should be stored (e.g., 'documents/new-file.txt')data- The data to store as a Buffer
Returns:
- Promise that resolves when the operation is complete
Examples:
// Store text file
const textData = Buffer.from('Hello, World!', 'utf-8');
await provider.put('documents/greeting.txt', textData);
// Store binary data
const fs = require('fs');
const imageData = fs.readFileSync('local-image.jpg');
await provider.put('images/uploaded-image.jpg', imageData);
// Store JSON data
const jsonData = Buffer.from(JSON.stringify({ message: 'Hello' }), 'utf-8');
await provider.put('data/config.json', jsonData);delete(path: string): Promise<void>
Deletes the file at the specified path.
Parameters:
path- The path to delete (e.g., 'documents/old-file.txt')
Returns:
- Promise that resolves when the operation is complete
Throws:
Errorwhen the file is not found or cannot be deleted
Examples:
// Delete a specific file
await provider.delete('documents/old-file.txt');
// Delete files in a loop
const files = await provider.list('temp/');
for (const file of files) {
await provider.delete(`temp/${file}`);
}Error Handling
The provider throws descriptive errors for various scenarios:
try {
const content = await provider.get('non-existent-file.txt');
} catch (error) {
console.error(error.message); // "File not found at path 'non-existent-file.txt'"
}
try {
await provider.put('', Buffer.from('data'));
} catch (error) {
console.error(error.message); // "Path cannot be empty"
}Common error scenarios:
- File not found: When trying to get or delete a file that doesn't exist
- Empty path: When providing an empty string as path for get, put, or delete operations
- Invalid connection string: When the Azure Storage connection string is malformed
- Container access issues: When the container cannot be accessed or created
- Network issues: When Azure Storage is unreachable
Path Handling
The provider automatically normalizes paths for Azure Blob Storage:
- Leading slashes are removed: /documents/file.txt becomes documents/file.txt
- Backslashes are converted: documents\file.txt becomes documents/file.txt
- Mixed slashes are handled: /documents\file.txt becomes documents/file.txt
// All of these are equivalent:
await provider.get('documents/file.txt');
await provider.get('/documents/file.txt');
await provider.get('documents\file.txt');
await provider.get('/documents\file.txt');Environment Variables
For easier configuration management, you can use environment variables:
const provider = new AzureBlobStorageProvider({
connectionString: process.env.AZURE_STORAGE_CONNECTION_STRING!,
containerName: process.env.AZURE_STORAGE_CONTAINER_NAME!
});Set these in your environment:
echo export AZURE_STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=..."
echo export AZURE_STORAGE_CONTAINER_NAME="my-app-storage"TypeScript Support
This package is written in TypeScript and includes full type definitions. No additional @types packages are needed.
import { AzureBlobStorageProvider, AzureBlobStorageConfig, StorageProvider } from 'aab_node_storage_az_blob';
// Full type safety
const config: AzureBlobStorageConfig = {
connectionString: 'your-connection-string',
containerName: 'your-container'
};
const provider: StorageProvider = new AzureBlobStorageProvider(config);Testing
The package includes comprehensive tests:
# Run unit tests
npm test
# Run tests with coverage
npm run test -- --coverage
# Run tests in watch mode
npm run test -- --watchIntegration Tests
Integration tests require real Azure Storage credentials and are skipped by default. To run them:
# Set environment variables
echo export AZURE_STORAGE_CONNECTION_STRING="your-connection-string"
echo export AZURE_STORAGE_CONTAINER_NAME="test-container"
# Run all tests including integration tests
npm testDevelopment
Prerequisites for Development
- Node.js 18+
- Azure Storage account for integration testing
- TypeScript knowledge
Setup
# Clone the repository
git clone https://github.com/cmeegamarachchi/aab_node_storage_az_blob.git
cd aab_node_storage_az_blob
# Install dependencies
npm install
# Build the project
npm run build
# Run tests
npm test
# Run linter
npm run lint
# Format code
npm run formatAvailable Scripts
npm run build- Compile TypeScript to JavaScriptnpm run dev- Build in watch modenpm test- Run testsnpm run lint- Lint TypeScript filesnpm run format- Format code with Prettier
Publishing to npm
Prerequisites
- Create an npm account at npmjs.com
- Login to npm:
npm login - Verify your login:
npm whoami
Publishing Steps
Update the version in
package.json:# For patch releases (bug fixes) npm version patch # For minor releases (new features) npm version minor # For major releases (breaking changes) npm version majorBuild the package:
npm run buildTest the package contents:
npm pack --dry-runPublish to npm:
npm publish
Scoped Publishing (Optional)
To publish under a scope (e.g., @your-org/aab_node_storage_az_blob):
Update package name in
package.json:{ "name": "@your-org/aab_node_storage_az_blob" }Publish with public access:
npm publish --access public
Examples
Basic File Operations
import { AzureBlobStorageProvider } from 'aab_node_storage_az_blob';
const provider = new AzureBlobStorageProvider({
connectionString: process.env.AZURE_STORAGE_CONNECTION_STRING!,
containerName: 'documents'
});
async function fileOperations() {
// Store a document
const document = Buffer.from('# My Document
This is content.', 'utf-8');
await provider.put('docs/readme.md', document);
// Retrieve and display
const content = await provider.get('docs/readme.md');
console.log('Document content:', content.toString('utf-8'));
// List all documents
const files = await provider.list('docs/');
console.log('Documents:', files);
// Clean up
await provider.delete('docs/readme.md');
}Image Upload and Management
import fs from 'fs';
import { AzureBlobStorageProvider } from 'aab_node_storage_az_blob';
const provider = new AzureBlobStorageProvider({
connectionString: process.env.AZURE_STORAGE_CONNECTION_STRING!,
containerName: 'images'
});
async function imageOperations() {
// Upload an image
const imageData = fs.readFileSync('profile.jpg');
await provider.put('users/john/profile.jpg', imageData);
// Create thumbnail path
const thumbnailData = fs.readFileSync('profile-thumb.jpg');
await provider.put('users/john/profile-thumb.jpg', thumbnailData);
// List user images
const userImages = await provider.list('users/john/');
console.log('User images:', userImages);
// Download original image
const originalImage = await provider.get('users/john/profile.jpg');
fs.writeFileSync('downloaded-profile.jpg', originalImage);
}Backup and Sync Operations
import { AzureBlobStorageProvider } from 'aab_node_storage_az_blob';
const sourceProvider = new AzureBlobStorageProvider({
connectionString: process.env.SOURCE_AZURE_CONNECTION!,
containerName: 'source-data'
});
const backupProvider = new AzureBlobStorageProvider({
connectionString: process.env.BACKUP_AZURE_CONNECTION!,
containerName: 'backup-data'
});
async function backupData() {
// List all files in source
const files = await sourceProvider.list('');
for (const file of files) {
try {
// Get file from source
const data = await sourceProvider.get(file);
// Store in backup
await backupProvider.put(file, data);
console.log(`Backed up: ${file}`);
} catch (error) {
console.error(`Failed to backup ${file}:`, error);
}
}
}Related Packages
- aab_node_storage_core - Core storage interfaces
- @azure/storage-blob - Azure Storage Blob SDK (dependency)
License
ISC
Contributing
Issues and pull requests are welcome on GitHub.
Author
Chintana Meegamarachchi
For more information about AppSolve Application Blocks, visit the main repository.
