@synet/fs-azure
Version:
Azure filesystem abstraction following FileSystem pattern
213 lines (160 loc) • 5.57 kB
Markdown
# @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
```bash
npm install @synet/fs-azure @synet/fs
```
## Quick Start
```typescript
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
```typescript
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
```typescript
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)
```typescript
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
```typescript
const azureAdapter = new AzureBlobFileSystem({
connectionString: process.env.AZURE_STORAGE_CONNECTION_STRING,
containerName: 'mycontainer'
});
```
### With SAS Token
```typescript
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:
```typescript
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 mapping
```
## Environment Variables
```bash
# 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
```typescript
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
```typescript
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](https://github.com/synthetism/fs) ecosystem.