@synet/fs-azure
v1.0.1
Published
Azure filesystem abstraction following FileSystem pattern
Readme
@synet/fs-azure
Azure Blob Storage adapter for @synet/fs
Store files in Microsoft Azure Blob Storage with the familiar filesystem interface. Perfect for Azure-native applications that need scalable cloud storage without complexity.
Installation
npm install @synet/fs-azure @synet/fsQuick Start
import { AsyncFileSystem } from '@synet/fs';
import { AzureBlobFileSystem } from '@synet/fs-azure';
// Create Azure adapter
const azureAdapter = new AzureBlobFileSystem({
accountName: 'mystorageaccount',
accountKey: process.env.AZURE_STORAGE_KEY,
containerName: 'mycontainer'
});
// Use with AsyncFileSystem
const fs = AsyncFileSystem.create({ adapter: azureAdapter });
// Standard filesystem operations
await fs.writeFile('config.json', JSON.stringify(config));
const data = await fs.readFile('config.json');
const files = await fs.readDir('uploads/');
const exists = await fs.exists('document.pdf');Configuration
interface AzureBlobStorageOptions {
accountName: string; // Azure storage account name
accountKey: string; // Azure storage account key
containerName: string; // Blob container name
prefix?: string; // Optional: namespace all files
connectionString?: string; // Alternative to accountName/accountKey
sasToken?: string; // Alternative authentication
}Usage Examples
Basic Operations
import { AsyncFileSystem } from '@synet/fs';
import { AzureBlobFileSystem } from '@synet/fs-azure';
const azureAdapter = new AzureBlobFileSystem({
accountName: 'mystorageaccount',
accountKey: process.env.AZURE_STORAGE_KEY,
containerName: 'documents'
});
const fs = AsyncFileSystem.create({ adapter: azureAdapter });
// File operations
await fs.writeFile('reports/monthly.pdf', pdfData);
const report = await fs.readFile('reports/monthly.pdf');
// Directory operations
await fs.ensureDir('uploads');
const uploadedFiles = await fs.readDir('uploads');
// Check existence
if (await fs.exists('config/app.json')) {
const config = JSON.parse(await fs.readFile('config/app.json'));
}With Prefix (Namespacing)
const azureAdapter = new AzureBlobFileSystem({
accountName: 'mystorageaccount',
accountKey: process.env.AZURE_STORAGE_KEY,
containerName: 'shared-container',
prefix: 'myapp/' // All files prefixed with 'myapp/'
});
const fs = AsyncFileSystem.create({ adapter: azureAdapter });
// Files stored as: myapp/config.json, myapp/data/users.json
await fs.writeFile('config.json', configData);
await fs.writeFile('data/users.json', userData);Using Connection String
const azureAdapter = new AzureBlobFileSystem({
connectionString: process.env.AZURE_STORAGE_CONNECTION_STRING,
containerName: 'mycontainer'
});With SAS Token
const azureAdapter = new AzureBlobFileSystem({
accountName: 'mystorageaccount',
sasToken: process.env.AZURE_SAS_TOKEN,
containerName: 'mycontainer'
});Multi-Layer Composition
Combine with other filesystem layers for advanced functionality:
import { AsyncFileSystem } from '@synet/fs';
import { AzureBlobFileSystem } from '@synet/fs-azure';
import {
AsyncObservableFileSystem,
AsyncCachedFileSystem,
AsyncWithIdFileSystem
} from '@synet/fs';
const azureAdapter = new AzureBlobFileSystem(azureConfig);
const fs = AsyncFileSystem.create({
adapter: new AsyncObservableFileSystem( // Event monitoring
new AsyncCachedFileSystem( // Intelligent caching
new AsyncWithIdFileSystem(azureAdapter) // Deterministic IDs
)
)
});
// Now you have: Azure storage + caching + observability + ID mappingEnvironment Variables
# Option 1: Account name and key
AZURE_STORAGE_ACCOUNT=mystorageaccount
AZURE_STORAGE_KEY=your-storage-key
# Option 2: Connection string
AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=...
# Option 3: SAS token
AZURE_SAS_TOKEN=sv=2021-06-08&ss=b&srt=sco&sp=rwdlacupx&se=...Testing
import { AsyncFileSystem } from '@synet/fs';
import { AzureBlobFileSystem } from '@synet/fs-azure';
import { MemFileSystem } from '@synet/fs-memory';
// Production
const azureFs = AsyncFileSystem.create({
adapter: new AzureBlobFileSystem(azureConfig)
});
// Testing - same interface, different storage
const testFs = AsyncFileSystem.create({
adapter: new MemFileSystem()
});
// Your service works with both
class DocumentService {
constructor(private fs: AsyncFileSystem) {}
async saveDocument(id: string, content: string) {
await this.fs.writeFile(`documents/${id}.txt`, content);
}
}Features
- Azure Blob Storage Integration: Direct integration with Azure Blob Storage
- Container Management: Automatic container creation and management
- Metadata Support: Full blob metadata and properties support
- SAS Token Support: Secure access with shared access signatures
- Connection String Support: Multiple authentication methods
- Prefix Support: Namespace files within containers
- Error Handling: Comprehensive Azure-specific error handling
- TypeScript: Full TypeScript support with proper types
Error Handling
try {
await fs.readFile('nonexistent.txt');
} catch (error) {
if (error.code === 'BlobNotFound') {
console.log('File does not exist in Azure Blob Storage');
}
}License
MIT
Part of the @synet/fs ecosystem.
