|
Add this skill
npx mdskills install sickn33/azure-storage-file-share-tsComprehensive Azure File Share SDK reference with excellent code examples and authentication patterns
1---2name: azure-storage-file-share-ts3description: |4 Azure File Share JavaScript/TypeScript SDK (@azure/storage-file-share) for SMB file share operations. Use for creating shares, managing directories, uploading/downloading files, and handling file metadata. Supports Azure Files SMB protocol scenarios. Triggers: "file share", "@azure/storage-file-share", "ShareServiceClient", "ShareClient", "SMB", "Azure Files".5package: "@azure/storage-file-share"6---78# @azure/storage-file-share (TypeScript/JavaScript)910SDK for Azure File Share operations — SMB file shares, directories, and file operations.1112## Installation1314```bash15npm install @azure/storage-file-share @azure/identity16```1718**Current Version**: 12.x19**Node.js**: >= 18.0.02021## Environment Variables2223```bash24AZURE_STORAGE_ACCOUNT_NAME=<account-name>25AZURE_STORAGE_ACCOUNT_KEY=<account-key>26# OR connection string27AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=...28```2930## Authentication3132### Connection String (Simplest)3334```typescript35import { ShareServiceClient } from "@azure/storage-file-share";3637const client = ShareServiceClient.fromConnectionString(38 process.env.AZURE_STORAGE_CONNECTION_STRING!39);40```4142### StorageSharedKeyCredential (Node.js only)4344```typescript45import { ShareServiceClient, StorageSharedKeyCredential } from "@azure/storage-file-share";4647const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!;48const accountKey = process.env.AZURE_STORAGE_ACCOUNT_KEY!;4950const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);51const client = new ShareServiceClient(52 `https://${accountName}.file.core.windows.net`,53 sharedKeyCredential54);55```5657### DefaultAzureCredential5859```typescript60import { ShareServiceClient } from "@azure/storage-file-share";61import { DefaultAzureCredential } from "@azure/identity";6263const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!;64const client = new ShareServiceClient(65 `https://${accountName}.file.core.windows.net`,66 new DefaultAzureCredential()67);68```6970### SAS Token7172```typescript73import { ShareServiceClient } from "@azure/storage-file-share";7475const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!;76const sasToken = process.env.AZURE_STORAGE_SAS_TOKEN!;7778const client = new ShareServiceClient(79 `https://${accountName}.file.core.windows.net${sasToken}`80);81```8283## Client Hierarchy8485```86ShareServiceClient (account level)87└── ShareClient (share level)88 └── ShareDirectoryClient (directory level)89 └── ShareFileClient (file level)90```9192## Share Operations9394### Create Share9596```typescript97const shareClient = client.getShareClient("my-share");98await shareClient.create();99100// Create with quota (in GB)101await shareClient.create({ quota: 100 });102```103104### List Shares105106```typescript107for await (const share of client.listShares()) {108 console.log(share.name, share.properties.quota);109}110111// With prefix filter112for await (const share of client.listShares({ prefix: "logs-" })) {113 console.log(share.name);114}115```116117### Delete Share118119```typescript120await shareClient.delete();121122// Delete if exists123await shareClient.deleteIfExists();124```125126### Get Share Properties127128```typescript129const properties = await shareClient.getProperties();130console.log("Quota:", properties.quota, "GB");131console.log("Last Modified:", properties.lastModified);132```133134### Set Share Quota135136```typescript137await shareClient.setQuota(200); // 200 GB138```139140## Directory Operations141142### Create Directory143144```typescript145const directoryClient = shareClient.getDirectoryClient("my-directory");146await directoryClient.create();147148// Create nested directory149const nestedDir = shareClient.getDirectoryClient("parent/child/grandchild");150await nestedDir.create();151```152153### List Directories and Files154155```typescript156const directoryClient = shareClient.getDirectoryClient("my-directory");157158for await (const item of directoryClient.listFilesAndDirectories()) {159 if (item.kind === "directory") {160 console.log(`[DIR] ${item.name}`);161 } else {162 console.log(`[FILE] ${item.name} (${item.properties.contentLength} bytes)`);163 }164}165```166167### Delete Directory168169```typescript170await directoryClient.delete();171172// Delete if exists173await directoryClient.deleteIfExists();174```175176### Check if Directory Exists177178```typescript179const exists = await directoryClient.exists();180if (!exists) {181 await directoryClient.create();182}183```184185## File Operations186187### Upload File (Simple)188189```typescript190const fileClient = shareClient191 .getDirectoryClient("my-directory")192 .getFileClient("my-file.txt");193194// Upload string195const content = "Hello, World!";196await fileClient.create(content.length);197await fileClient.uploadRange(content, 0, content.length);198```199200### Upload File (Node.js - from local file)201202```typescript203import * as fs from "fs";204import * as path from "path";205206const fileClient = shareClient.rootDirectoryClient.getFileClient("uploaded.txt");207const localFilePath = "/path/to/local/file.txt";208const fileSize = fs.statSync(localFilePath).size;209210await fileClient.create(fileSize);211await fileClient.uploadFile(localFilePath);212```213214### Upload File (Buffer)215216```typescript217const buffer = Buffer.from("Hello, Azure Files!");218const fileClient = shareClient.rootDirectoryClient.getFileClient("buffer-file.txt");219220await fileClient.create(buffer.length);221await fileClient.uploadRange(buffer, 0, buffer.length);222```223224### Upload File (Stream)225226```typescript227import * as fs from "fs";228229const fileClient = shareClient.rootDirectoryClient.getFileClient("streamed.txt");230const readStream = fs.createReadStream("/path/to/local/file.txt");231const fileSize = fs.statSync("/path/to/local/file.txt").size;232233await fileClient.create(fileSize);234await fileClient.uploadStream(readStream, fileSize, 4 * 1024 * 1024, 4); // 4MB buffer, 4 concurrency235```236237### Download File238239```typescript240const fileClient = shareClient241 .getDirectoryClient("my-directory")242 .getFileClient("my-file.txt");243244const downloadResponse = await fileClient.download();245246// Read as string247const chunks: Buffer[] = [];248for await (const chunk of downloadResponse.readableStreamBody!) {249 chunks.push(Buffer.from(chunk));250}251const content = Buffer.concat(chunks).toString("utf-8");252```253254### Download to File (Node.js)255256```typescript257const fileClient = shareClient.rootDirectoryClient.getFileClient("my-file.txt");258await fileClient.downloadToFile("/path/to/local/destination.txt");259```260261### Download to Buffer (Node.js)262263```typescript264const fileClient = shareClient.rootDirectoryClient.getFileClient("my-file.txt");265const buffer = await fileClient.downloadToBuffer();266console.log(buffer.toString());267```268269### Delete File270271```typescript272const fileClient = shareClient.rootDirectoryClient.getFileClient("my-file.txt");273await fileClient.delete();274275// Delete if exists276await fileClient.deleteIfExists();277```278279### Copy File280281```typescript282const sourceUrl = "https://account.file.core.windows.net/share/source.txt";283const destFileClient = shareClient.rootDirectoryClient.getFileClient("destination.txt");284285// Start copy operation286const copyPoller = await destFileClient.startCopyFromURL(sourceUrl);287await copyPoller.pollUntilDone();288```289290## File Properties & Metadata291292### Get File Properties293294```typescript295const fileClient = shareClient.rootDirectoryClient.getFileClient("my-file.txt");296const properties = await fileClient.getProperties();297298console.log("Content-Length:", properties.contentLength);299console.log("Content-Type:", properties.contentType);300console.log("Last Modified:", properties.lastModified);301console.log("ETag:", properties.etag);302```303304### Set Metadata305306```typescript307await fileClient.setMetadata({308 author: "John Doe",309 category: "documents",310});311```312313### Set HTTP Headers314315```typescript316await fileClient.setHttpHeaders({317 fileContentType: "text/plain",318 fileCacheControl: "max-age=3600",319 fileContentDisposition: "attachment; filename=download.txt",320});321```322323## Range Operations324325### Upload Range326327```typescript328const data = Buffer.from("partial content");329await fileClient.uploadRange(data, 100, data.length); // Write at offset 100330```331332### Download Range333334```typescript335const downloadResponse = await fileClient.download(100, 50); // offset 100, length 50336```337338### Clear Range339340```typescript341await fileClient.clearRange(0, 100); // Clear first 100 bytes342```343344## Snapshot Operations345346### Create Snapshot347348```typescript349const snapshotResponse = await shareClient.createSnapshot();350console.log("Snapshot:", snapshotResponse.snapshot);351```352353### Access Snapshot354355```typescript356const snapshotShareClient = shareClient.withSnapshot(snapshotResponse.snapshot!);357const snapshotFileClient = snapshotShareClient.rootDirectoryClient.getFileClient("file.txt");358const content = await snapshotFileClient.downloadToBuffer();359```360361### Delete Snapshot362363```typescript364await shareClient.delete({ deleteSnapshots: "include" });365```366367## SAS Token Generation (Node.js only)368369### Generate File SAS370371```typescript372import {373 generateFileSASQueryParameters,374 FileSASPermissions,375 StorageSharedKeyCredential,376} from "@azure/storage-file-share";377378const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);379380const sasToken = generateFileSASQueryParameters(381 {382 shareName: "my-share",383 filePath: "my-directory/my-file.txt",384 permissions: FileSASPermissions.parse("r"), // read only385 expiresOn: new Date(Date.now() + 3600 * 1000), // 1 hour386 },387 sharedKeyCredential388).toString();389390const sasUrl = `https://${accountName}.file.core.windows.net/my-share/my-directory/my-file.txt?${sasToken}`;391```392393### Generate Share SAS394395```typescript396import { ShareSASPermissions, generateFileSASQueryParameters } from "@azure/storage-file-share";397398const sasToken = generateFileSASQueryParameters(399 {400 shareName: "my-share",401 permissions: ShareSASPermissions.parse("rcwdl"), // read, create, write, delete, list402 expiresOn: new Date(Date.now() + 24 * 3600 * 1000), // 24 hours403 },404 sharedKeyCredential405).toString();406```407408## Error Handling409410```typescript411import { RestError } from "@azure/storage-file-share";412413try {414 await shareClient.create();415} catch (error) {416 if (error instanceof RestError) {417 switch (error.statusCode) {418 case 404:419 console.log("Share not found");420 break;421 case 409:422 console.log("Share already exists");423 break;424 case 403:425 console.log("Access denied");426 break;427 default:428 console.error(`Storage error ${error.statusCode}: ${error.message}`);429 }430 }431 throw error;432}433```434435## TypeScript Types Reference436437```typescript438import {439 // Clients440 ShareServiceClient,441 ShareClient,442 ShareDirectoryClient,443 ShareFileClient,444445 // Authentication446 StorageSharedKeyCredential,447 AnonymousCredential,448449 // SAS450 FileSASPermissions,451 ShareSASPermissions,452 AccountSASPermissions,453 AccountSASServices,454 AccountSASResourceTypes,455 generateFileSASQueryParameters,456 generateAccountSASQueryParameters,457458 // Options & Responses459 ShareCreateResponse,460 FileDownloadResponseModel,461 DirectoryItem,462 FileItem,463 ShareProperties,464 FileProperties,465466 // Errors467 RestError,468} from "@azure/storage-file-share";469```470471## Best Practices4724731. **Use connection strings for simplicity** — Easiest setup for development4742. **Use DefaultAzureCredential for production** — Enable managed identity in Azure4753. **Set quotas on shares** — Prevent unexpected storage costs4764. **Use streaming for large files** — `uploadStream`/`downloadToFile` for files > 256MB4775. **Use ranges for partial updates** — More efficient than full file replacement4786. **Create snapshots before major changes** — Point-in-time recovery4797. **Handle errors gracefully** — Check `RestError.statusCode` for specific handling4808. **Use `*IfExists` methods** — For idempotent operations481482## Platform Differences483484| Feature | Node.js | Browser |485|---------|---------|---------|486| `StorageSharedKeyCredential` | ✅ | ❌ |487| `uploadFile()` | ✅ | ❌ |488| `uploadStream()` | ✅ | ❌ |489| `downloadToFile()` | ✅ | ❌ |490| `downloadToBuffer()` | ✅ | ❌ |491| SAS generation | ✅ | ❌ |492| DefaultAzureCredential | ✅ | ❌ |493| Anonymous/SAS access | ✅ | ✅ |494
Full transparency — inspect the skill content before installing.