Azure Storage Blob TS
MicrosoftOfficialCreated by Microsoft
- Skill
- Tool integration
- Cloud and DevOps
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The @azure/storage-blob SDK provides a comprehensive interface for interacting with Azure Blob Storage. It supports various authentication methods, including Microsoft Entra ID and connection strings, and facilitates operations such as uploading, downloading, listing, and managing blobs and containers. The library is designed for both Node.js and browser environments, offering specialized features like streaming for large files, SAS token generation for secure access, and support for block, append, and page blobs.
What it does
- Manage storage containers and blobs via a hierarchical client structure.
- Upload and download data using buffers, streams, or direct file paths.
- Generate Service, Account, and User Delegation SAS tokens for secure access.
- Configure blob properties, metadata, and HTTP headers.
- Support for block, append, and page blob types.
- Handle storage errors with specific status code reporting.
When to use it
- When building applications that require cloud-based object storage on Azure.
- When you need to implement secure, time-limited access to storage resources via SAS tokens.
- When handling large file uploads or downloads that require streaming.
- When integrating Azure storage operations into TypeScript or JavaScript projects.
Advantages
- Official Microsoft support for Azure Blob Storage.
- Strong TypeScript support with comprehensive type definitions.
- Flexible authentication options including modern Entra ID integration.
- Optimized for large data transfers with built-in streaming and concurrency controls.
- Cross-platform compatibility for both Node.js and browser environments.
Usage examples
- “How do I upload a local file to Azure Blob Storage using the SDK?”
- The agent provides a code snippet using BlockBlobClient.uploadFile, demonstrating how to initialize the client and perform the upload operation.
- “Show me how to generate a read-only SAS token for a specific blob.”
- The agent provides a function using generateBlobSASQueryParameters, specifying the container, blob name, read permissions, and expiration time.
- “How can I list all blobs in a container that start with a specific prefix?”
- The agent demonstrates using the listBlobsFlat method on a ContainerClient with a prefix filter option.
- “What is the best way to handle errors when creating a container?”
- The agent shows a try-catch block using RestError to check for specific HTTP status codes like 404, 409, or 403.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/microsoft/azure-storage-blob-ts/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip azure-storage-blob-ts.zip -d .agents/skills
Documentation by Microsoft
@azure/storage-blob (TypeScript/JavaScript)
SDK for Azure Blob Storage operations — upload, download, list, and manage blobs and containers.
Installation
npm install @azure/storage-blob @azure/identityCurrent Version: 12.x
Node.js: >= 18.0.0
Environment Variables
AZURE_STORAGE_ACCOUNT_NAME=<account-name>
AZURE_STORAGE_ACCOUNT_KEY=<account-key>
# OR connection string
AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=...
AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in productionAuthentication
Microsoft Entra Token Credential (Recommended)
import { BlobServiceClient } from "@azure/storage-blob";
import { DefaultAzureCredential, ManagedIdentityCredential } from "@azure/identity";
// Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>
const credential = new DefaultAzureCredential({requiredEnvVars: ["AZURE_TOKEN_CREDENTIALS"]});
// Or use a specific credential directly in production:
// See https://learn.microsoft.com/javascript/api/overview/azure/identity-readme?view=azure-node-latest#credential-classes
// const credential = new ManagedIdentityCredential();
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!;
const client = new BlobServiceClient(
`https://${accountName}.blob.core.windows.net`,
credential
);Connection String
import { BlobServiceClient } from "@azure/storage-blob";
const client = BlobServiceClient.fromConnectionString(
process.env.AZURE_STORAGE_CONNECTION_STRING!
);StorageSharedKeyCredential (Node.js only)
import { BlobServiceClient, StorageSharedKeyCredential } from "@azure/storage-blob";
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!;
const accountKey = process.env.AZURE_STORAGE_ACCOUNT_KEY!;
const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);
const client = new BlobServiceClient(
`https://${accountName}.blob.core.windows.net`,
sharedKeyCredential
);SAS Token
import { BlobServiceClient } from "@azure/storage-blob";
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!;
const sasToken = process.env.AZURE_STORAGE_SAS_TOKEN!; // starts with "?"
const client = new BlobServiceClient(
`https://${accountName}.blob.core.windows.net${sasToken}`
);Client Hierarchy
BlobServiceClient (account level)
└── ContainerClient (container level)
└── BlobClient (blob level)
├── BlockBlobClient (block blobs - most common)
├── AppendBlobClient (append-only blobs)
└── PageBlobClient (page blobs - VHDs)Container Operations
Create Container
const containerClient = client.getContainerClient("my-container");
await containerClient.create();
// Or create if not exists
await containerClient.createIfNotExists();List Containers
for await (const container of client.listContainers()) {
console.log(container.name);
}
// With prefix filter
for await (const container of client.listContainers({ prefix: "logs-" })) {
console.log(container.name);
}Delete Container
await containerClient.delete();
// Or delete if exists
await containerClient.deleteIfExists();Blob Operations
Upload Blob (Simple)
const containerClient = client.getContainerClient("my-container");
const blockBlobClient = containerClient.getBlockBlobClient("my-file.txt");
// Upload string
await blockBlobClient.upload("Hello, World!", 13);
// Upload Buffer
const buffer = Buffer.from("Hello, World!");
await blockBlobClient.upload(buffer, buffer.length);Upload from File (Node.js only)
const blockBlobClient = containerClient.getBlockBlobClient("uploaded-file.txt");
await blockBlobClient.uploadFile("/path/to/local/file.txt");Upload from Stream (Node.js only)
import * as fs from "fs";
const blockBlobClient = containerClient.getBlockBlobClient("streamed-file.txt");
const readStream = fs.createReadStream("/path/to/local/file.txt");
await blockBlobClient.uploadStream(readStream, 4 * 1024 * 1024, 5, {
// bufferSize: 4MB, maxConcurrency: 5
onProgress: (progress) => console.log(`Uploaded ${progress.loadedBytes} bytes`),
});Upload from Browser
const blockBlobClient = containerClient.getBlockBlobClient("browser-upload.txt");
// From File input
const fileInput = document.getElementById("fileInput") as HTMLInputElement;
const file = fileInput.files![0];
await blockBlobClient.uploadData(file);
// From Blob/ArrayBuffer
const arrayBuffer = new ArrayBuffer(1024);
await blockBlobClient.uploadData(arrayBuffer);Download Blob
const blobClient = containerClient.getBlobClient("my-file.txt");
const downloadResponse = await blobClient.download();
// Read as string (browser & Node.js)
const downloaded = await streamToText(downloadResponse.readableStreamBody!);
async function streamToText(readable: NodeJS.ReadableStream): Promise<string> {
const chunks: Buffer[] = [];
for await (const chunk of readable) {
chunks.push(Buffer.from(chunk));
}
return Buffer.concat(chunks).toString("utf-8");
}Download to File (Node.js only)
const blockBlobClient = containerClient.getBlockBlobClient("my-file.txt");
await blockBlobClient.downloadToFile("/path/to/local/destination.txt");Download to Buffer (Node.js only)
const blockBlobClient = containerClient.getBlockBlobClient("my-file.txt");
const buffer = await blockBlobClient.downloadToBuffer();
console.log(buffer.toString());List Blobs
// List all blobs
for await (const blob of containerClient.listBlobsFlat()) {
console.log(blob.name, blob.properties.contentLength);
}
// List with prefix
for await (const blob of containerClient.listBlobsFlat({ prefix: "logs/" })) {
console.log(blob.name);
}
// List by hierarchy (virtual directories)
for await (const item of containerClient.listBlobsByHierarchy("/")) {
if (item.kind === "prefix") {
console.log(`Directory: ${item.name}`);
} else {
console.log(`Blob: ${item.name}`);
}
}Delete Blob
const blobClient = containerClient.getBlobClient("my-file.txt");
await blobClient.delete();
// Delete if exists
await blobClient.deleteIfExists();
// Delete with snapshots
await blobClient.delete({ deleteSnapshots: "include" });Copy Blob
const sourceBlobClient = containerClient.getBlobClient("source.txt");
const destBlobClient = containerClient.getBlobClient("destination.txt");
// Start copy operation
const copyPoller = await destBlobClient.beginCopyFromURL(sourceBlobClient.url);
await copyPoller.pollUntilDone();Blob Properties & Metadata
Get Properties
const blobClient = containerClient.getBlobClient("my-file.txt");
const properties = await blobClient.getProperties();
console.log("Content-Type:", properties.contentType);
console.log("Content-Length:", properties.contentLength);
console.log("Last Modified:", properties.lastModified);
console.log("ETag:", properties.etag);Set Metadata
await blobClient.setMetadata({
author: "John Doe",
category: "documents",
});Set HTTP Headers
await blobClient.setHTTPHeaders({
blobContentType: "text/plain",
blobCacheControl: "max-age=3600",
blobContentDisposition: "attachment; filename=download.txt",
});SAS Token Generation (Node.js only)
Generate Blob SAS
import {
BlobSASPermissions,
generateBlobSASQueryParameters,
StorageSharedKeyCredential,
} from "@azure/storage-blob";
const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);
const sasToken = generateBlobSASQueryParameters(
{
containerName: "my-container",
blobName: "my-file.txt",
permissions: BlobSASPermissions.parse("r"), // read only
startsOn: new Date(),
expiresOn: new Date(Date.now() + 3600 * 1000), // 1 hour
},
sharedKeyCredential
).toString();
const sasUrl = `https://${accountName}.blob.core.windows.net/my-container/my-file.txt?${sasToken}`;Generate Container SAS
import { ContainerSASPermissions, generateBlobSASQueryParameters } from "@azure/storage-blob";
const sasToken = generateBlobSASQueryParameters(
{
containerName: "my-container",
permissions: ContainerSASPermissions.parse("racwdl"), // read, add, create, write, delete, list
expiresOn: new Date(Date.now() + 24 * 3600 * 1000), // 24 hours
},
sharedKeyCredential
).toString();Generate Account SAS
import {
AccountSASPermissions,
AccountSASResourceTypes,
AccountSASServices,
generateAccountSASQueryParameters,
} from "@azure/storage-blob";
const sasToken = generateAccountSASQueryParameters(
{
services: AccountSASServices.parse("b").toString(), // blob
resourceTypes: AccountSASResourceTypes.parse("sco").toString(), // service, container, object
permissions: AccountSASPermissions.parse("rwdlacupi"), // all permissions
expiresOn: new Date(Date.now() + 24 * 3600 * 1000),
},
sharedKeyCredential
).toString();Blob Types
Block Blob (Default)
Most common type for text and binary files.
const blockBlobClient = containerClient.getBlockBlobClient("document.pdf");
await blockBlobClient.uploadFile("/path/to/document.pdf");Append Blob
Optimized for append operations (logs, audit trails).
const appendBlobClient = containerClient.getAppendBlobClient("app.log");
// Create the append blob
await appendBlobClient.create();
// Append data
await appendBlobClient.appendBlock("Log entry 1\n", 12);
await appendBlobClient.appendBlock("Log entry 2\n", 12);Page Blob
Fixed-size blobs for random read/write (VHDs).
const pageBlobClient = containerClient.getPageBlobClient("disk.vhd");
// Create 512-byte aligned page blob
await pageBlobClient.create(1024 * 1024); // 1MB
// Write pages (must be 512-byte aligned)
const buffer = Buffer.alloc(512);
await pageBlobClient.uploadPages(buffer, 0, 512);Error Handling
import { RestError } from "@azure/storage-blob";
try {
await containerClient.create();
} catch (error) {
if (error instanceof RestError) {
switch (error.statusCode) {
case 404:
console.log("Container not found");
break;
case 409:
console.log("Container already exists");
break;
case 403:
console.log("Access denied");
break;
default:
console.error(`Storage error ${error.statusCode}: ${error.message}`);
}
}
throw error;
}TypeScript Types Reference
import {
// Clients
BlobServiceClient,
ContainerClient,
BlobClient,
BlockBlobClient,
AppendBlobClient,
PageBlobClient,
// Authentication
StorageSharedKeyCredential,
AnonymousCredential,
// SAS
BlobSASPermissions,
ContainerSASPermissions,
AccountSASPermissions,
AccountSASServices,
AccountSASResourceTypes,
generateBlobSASQueryParameters,
generateAccountSASQueryParameters,
// Options & Responses
BlobDownloadResponseParsed,
BlobUploadCommonResponse,
ContainerCreateResponse,
BlobItem,
ContainerItem,
// Errors
RestError,
} from "@azure/storage-blob";Best Practices
Use
DefaultAzureCredentialfor local development; useManagedIdentityCredentialorWorkloadIdentityCredentialfor productionUse streaming for large files —
uploadStream/downloadToFilefor files > 256MBSet appropriate content types — Use
setHTTPHeadersfor correct MIME typesUse SAS tokens for client access — Generate short-lived tokens for browser uploads
Handle errors gracefully — Check
RestError.statusCodefor specific handlingUse
*IfNotExistsmethods — For idempotent container/blob creationClose clients — Not required but good practice in long-running apps
Platform Differences
| Feature | Node.js | Browser |
|---|---|---|
StorageSharedKeyCredential | ✅ | ❌ |
uploadFile() | ✅ | ❌ |
uploadStream() | ✅ | ❌ |
downloadToFile() | ✅ | ❌ |
downloadToBuffer() | ✅ | ❌ |
uploadData() | ✅ | ✅ |
| SAS generation | ✅ | ❌ |
| DefaultAzureCredential | ✅ | ❌ |
| Anonymous/SAS access | ✅ | ✅ |
Files
- ATTRIBUTION.mdAdded by AutoGineer982 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md12.8 KiB
- references/sas-tokens.md12.7 KiB
- references/streaming.md10.2 KiB
references/streaming.md
@azure/storage-blob - Streaming Patterns
Reference documentation for upload/download streaming in the Azure Blob Storage TypeScript SDK.
Source: Azure SDK for JS - storage-blob
Installation
npm install @azure/storage-blob @azure/identityClient Setup
import {
BlobServiceClient,
ContainerClient,
BlockBlobClient,
} from "@azure/storage-blob";
import { DefaultAzureCredential } from "@azure/identity";
const credential = new DefaultAzureCredential();
const accountUrl = `https://${process.env["STORAGE_ACCOUNT_NAME"]}.blob.core.windows.net`;
const blobServiceClient = new BlobServiceClient(accountUrl, credential);
const containerClient = blobServiceClient.getContainerClient("my-container");
const blobClient = containerClient.getBlockBlobClient("my-blob.txt");Download Streaming
Download to Buffer
const downloadResponse = await blobClient.download(0);
const downloaded = await streamToBuffer(downloadResponse.readableStreamBody!);
async function streamToBuffer(readableStream: NodeJS.ReadableStream): Promise<Buffer> {
return new Promise((resolve, reject) => {
const chunks: Buffer[] = [];
readableStream.on("data", (data) => chunks.push(Buffer.from(data)));
readableStream.on("end", () => resolve(Buffer.concat(chunks)));
readableStream.on("error", reject);
});
}Download to File (Node.js)
import fs from "node:fs";
import { pipeline } from "node:stream/promises";
const downloadResponse = await blobClient.download(0);
await pipeline(
downloadResponse.readableStreamBody!,
fs.createWriteStream("./local-file.txt")
);Download with Range
// Download bytes 100-199 (100 bytes total)
const downloadResponse = await blobClient.download(100, 100);Download with Progress
const downloadResponse = await blobClient.download(0, undefined, {
onProgress: (progress) => {
console.log(`Downloaded ${progress.loadedBytes} bytes`);
},
});Upload Streaming
Upload from Buffer
const content = Buffer.from("Hello, World!");
await blobClient.upload(content, content.length);Upload from Stream (Node.js)
import fs from "node:fs";
const fileStream = fs.createReadStream("./large-file.zip");
const fileSize = fs.statSync("./large-file.zip").size;
await blobClient.uploadStream(fileStream, fileSize, 4, {
onProgress: (progress) => {
const percent = ((progress.loadedBytes / fileSize) * 100).toFixed(2);
console.log(`Upload progress: ${percent}%`);
},
});Upload with Options
await blobClient.uploadStream(fileStream, fileSize, 4, {
// Number of concurrent upload operations
concurrency: 4,
// Size of each block (4MB default, max 4000MB)
bufferSize: 4 * 1024 * 1024,
// Progress tracking
onProgress: (progress) => {
console.log(`Uploaded: ${progress.loadedBytes} bytes`);
},
// HTTP headers
blobHTTPHeaders: {
blobContentType: "application/zip",
blobContentEncoding: "gzip",
},
// Custom metadata
metadata: {
uploadedBy: "my-app",
version: "1.0",
},
// Access tier
tier: "Cool",
});Block Upload (Large Files)
For large files, use staged block uploads for better control:
import { BlockBlobClient, BlockBlobStageBlockOptions } from "@azure/storage-blob";
import { v4 as uuidv4 } from "uuid";
async function uploadLargeFile(
blobClient: BlockBlobClient,
filePath: string,
blockSize = 4 * 1024 * 1024 // 4MB blocks
) {
const fileHandle = await fs.promises.open(filePath, "r");
const fileStats = await fileHandle.stat();
const fileSize = fileStats.size;
const blockIds: string[] = [];
let offset = 0;
let blockIndex = 0;
try {
while (offset < fileSize) {
const chunkSize = Math.min(blockSize, fileSize - offset);
const buffer = Buffer.alloc(chunkSize);
await fileHandle.read(buffer, 0, chunkSize, offset);
// Generate block ID (must be base64 encoded, same length)
const blockId = Buffer.from(
blockIndex.toString().padStart(6, "0")
).toString("base64");
// Stage the block
await blobClient.stageBlock(blockId, buffer, buffer.length);
blockIds.push(blockId);
offset += chunkSize;
blockIndex++;
console.log(`Staged block ${blockIndex}, offset: ${offset}/${fileSize}`);
}
// Commit all blocks
await blobClient.commitBlockList(blockIds, {
blobHTTPHeaders: {
blobContentType: "application/octet-stream",
},
});
console.log("Upload complete!");
} finally {
await fileHandle.close();
}
}Parallel Upload/Download
Parallel Download to File
import { BlobClient } from "@azure/storage-blob";
// Downloads in parallel chunks automatically
await blobClient.downloadToFile("./local-file.zip", 0, undefined, {
// Chunk size for parallel download
blockSize: 4 * 1024 * 1024,
// Number of parallel downloads
concurrency: 4,
onProgress: (progress) => {
console.log(`Downloaded: ${progress.loadedBytes} bytes`);
},
});Parallel Upload from File
// Uploads in parallel chunks automatically
await blobClient.uploadFile("./large-file.zip", {
// Chunk size
blockSize: 4 * 1024 * 1024,
// Parallel uploads
concurrency: 4,
onProgress: (progress) => {
console.log(`Uploaded: ${progress.loadedBytes} bytes`);
},
blobHTTPHeaders: {
blobContentType: "application/zip",
},
});Browser Upload
For browser environments, use uploadBrowserData:
// From File input
const fileInput = document.getElementById("file") as HTMLInputElement;
const file = fileInput.files![0];
await blobClient.uploadBrowserData(file, {
onProgress: (progress) => {
const percent = ((progress.loadedBytes / file.size) * 100).toFixed(2);
document.getElementById("progress")!.textContent = `${percent}%`;
},
blobHTTPHeaders: {
blobContentType: file.type,
},
});
// From ArrayBuffer
const arrayBuffer = await file.arrayBuffer();
await blobClient.uploadBrowserData(arrayBuffer);
// From Blob
const blob = new Blob(["Hello, World!"], { type: "text/plain" });
await blobClient.uploadBrowserData(blob);Abort Operations
Cancel long-running uploads/downloads:
const abortController = new AbortController();
// Set up abort after 30 seconds
setTimeout(() => abortController.abort(), 30000);
try {
await blobClient.uploadFile("./large-file.zip", {
abortSignal: abortController.signal,
onProgress: (progress) => {
console.log(`Progress: ${progress.loadedBytes}`);
},
});
} catch (error) {
if (error.name === "AbortError") {
console.log("Upload was cancelled");
} else {
throw error;
}
}
// Manual abort
document.getElementById("cancel")?.addEventListener("click", () => {
abortController.abort();
});Copy Operations
Copy from URL
const sourceUrl = "https://source-account.blob.core.windows.net/container/blob";
// Start async copy
const copyPoller = await blobClient.beginCopyFromURL(sourceUrl);
// Wait for completion
const result = await copyPoller.pollUntilDone();
console.log(`Copy completed: ${result.copyStatus}`);
// Or copy synchronously (for small blobs)
await blobClient.syncCopyFromURL(sourceUrl);Copy with Progress
const copyPoller = await blobClient.beginCopyFromURL(sourceUrl, {
onProgress: (state) => {
if (state.copyProgress) {
const [copied, total] = state.copyProgress.split("/").map(Number);
console.log(`Copied: ${copied}/${total} bytes`);
}
},
});Complete Example
import {
BlobServiceClient,
ContainerClient,
BlockBlobClient,
} from "@azure/storage-blob";
import { DefaultAzureCredential } from "@azure/identity";
import fs from "node:fs";
import { pipeline } from "node:stream/promises";
async function uploadAndDownload() {
const credential = new DefaultAzureCredential();
const blobServiceClient = new BlobServiceClient(
`https://${process.env["STORAGE_ACCOUNT_NAME"]}.blob.core.windows.net`,
credential
);
const containerClient = blobServiceClient.getContainerClient("demo");
await containerClient.createIfNotExists();
const blobClient = containerClient.getBlockBlobClient("test-file.txt");
// Upload with progress
console.log("Uploading...");
const uploadData = Buffer.from("Hello, Azure Blob Storage!");
await blobClient.upload(uploadData, uploadData.length, {
onProgress: (progress) => {
console.log(`Upload progress: ${progress.loadedBytes} bytes`);
},
});
console.log("Upload complete!");
// Download with progress
console.log("Downloading...");
const downloadResponse = await blobClient.download(0, undefined, {
onProgress: (progress) => {
console.log(`Download progress: ${progress.loadedBytes} bytes`);
},
});
// Stream to file
await pipeline(
downloadResponse.readableStreamBody!,
fs.createWriteStream("./downloaded-file.txt")
);
console.log("Download complete!");
// Get blob properties
const properties = await blobClient.getProperties();
console.log(`Blob size: ${properties.contentLength} bytes`);
console.log(`Content type: ${properties.contentType}`);
console.log(`Last modified: ${properties.lastModified}`);
// Cleanup
await blobClient.delete();
console.log("Blob deleted");
}
uploadAndDownload().catch(console.error);Best Practices
Use parallel operations -
uploadFile/downloadToFileautomatically parallelizeSet appropriate block sizes - 4-8MB for most scenarios, larger for huge files
Implement progress tracking - Use
onProgressfor user feedbackHandle abort signals - Allow users to cancel long operations
Set content types - Always set
blobContentTypefor proper browser handlingUse streams for large files - Avoid loading entire files into memory
Implement retry logic - SDK has built-in retries, configure as needed
See Also
SAS Token Patterns - Generate secure access tokens
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Node.js
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Microsoft
- Publisher
- Microsoft (Official)
- Source
- microsoft/skills · .github/plugins/azure-sdk-typescript/skills/azure-storage-blob-ts · commit 0696600
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Microsoft.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download azure-storage-blob-ts.zip