diff --git a/sdk/storage/storage-blob/README.md b/sdk/storage/storage-blob/README.md index 371ccf39f7a1..4137fea40cd4 100644 --- a/sdk/storage/storage-blob/README.md +++ b/sdk/storage/storage-blob/README.md @@ -383,6 +383,7 @@ For a complete sample on iterating blobs please see [samples/v12/typescript/src/ ```ts snippet:ReadmeSampleDownloadBlob_Node import { BlobServiceClient } from "@azure/storage-blob"; import { DefaultAzureCredential } from "@azure/identity"; +import { buffer } from "node:stream/consumers"; const account = ""; const blobServiceClient = new BlobServiceClient( @@ -399,22 +400,10 @@ const blobClient = containerClient.getBlobClient(blobName); // In Node.js, get downloaded data by accessing downloadBlockBlobResponse.readableStreamBody const downloadBlockBlobResponse = await blobClient.download(); if (downloadBlockBlobResponse.readableStreamBody) { - const downloaded = await streamToString(downloadBlockBlobResponse.readableStreamBody); - console.log(`Downloaded blob content: ${downloaded}`); -} - -async function streamToString(stream: NodeJS.ReadableStream): Promise { - const result = await new Promise>((resolve, reject) => { - const chunks: Buffer[] = []; - stream.on("data", (data) => { - chunks.push(Buffer.isBuffer(data) ? data : Buffer.from(data)); - }); - stream.on("end", () => { - resolve(Buffer.concat(chunks)); - }); - stream.on("error", reject); - }); - return result.toString(); + // Download the raw bytes of the blob. Use `text` from "node:stream/consumers" + // instead if you want to read the content as a string directly. + const downloaded = await buffer(downloadBlockBlobResponse.readableStreamBody); + console.log(`Downloaded blob content: ${downloaded.toString()}`); } ``` diff --git a/sdk/storage/storage-blob/samples-dev/errorsAndResponses.ts b/sdk/storage/storage-blob/samples-dev/errorsAndResponses.ts index e720e79db7cb..c3b417a96c28 100644 --- a/sdk/storage/storage-blob/samples-dev/errorsAndResponses.ts +++ b/sdk/storage/storage-blob/samples-dev/errorsAndResponses.ts @@ -8,7 +8,9 @@ import { BlobServiceClient } from "@azure/storage-blob"; -import { streamToBuffer } from "./utils/stream.js"; +import { buffer } from "node:stream/consumers"; +// Use `text` from "node:stream/consumers" if you want the content as a string directly. +// import { text } from "node:stream/consumers"; // Load the .env file if it exists import "dotenv/config"; @@ -92,11 +94,10 @@ async function main(): Promise { console.log("// Download blob content..."); blockBlobClient = containerClient.getBlockBlobClient(blobName); const downloadBlockBlobResponse = await blockBlobClient.download(); - console.log( - `Downloaded blob content - ${( - await streamToBuffer(downloadBlockBlobResponse.readableStreamBody!) - ).toString()},`, - ); + // Download the raw bytes of the blob. Use `text(...)` from "node:stream/consumers" + // instead if you want to read the content as a string directly. + const downloaded = await buffer(downloadBlockBlobResponse.readableStreamBody!); + console.log(`Downloaded blob content - ${downloaded.toString()},`); console.log( `requestId - ${downloadBlockBlobResponse.requestId}, statusCode - ${downloadBlockBlobResponse._response.status}\n`, ); diff --git a/sdk/storage/storage-blob/samples-dev/snapshots.ts b/sdk/storage/storage-blob/samples-dev/snapshots.ts index 8c18caf1c393..e46941614cbf 100644 --- a/sdk/storage/storage-blob/samples-dev/snapshots.ts +++ b/sdk/storage/storage-blob/samples-dev/snapshots.ts @@ -23,7 +23,9 @@ import { ContainerClient, StorageSharedKeyCredential } from "@azure/storage-blob"; -import { streamToBuffer } from "./utils/stream.js"; +import { buffer } from "node:stream/consumers"; +// Use `text` from "node:stream/consumers" if you want the content as a string directly. +// import { text } from "node:stream/consumers"; // Load the .env file if it exists import "dotenv/config"; @@ -65,10 +67,10 @@ async function main(): Promise { (await blobSnapshotClient.getProperties()).contentLength, ); - console.log( - "Downloaded blob content", - (await streamToBuffer(response.readableStreamBody!)).toString(), - ); + // Download the raw bytes of the blob. Use `text(response.readableStreamBody!)` + // instead if you want to read the content as a string directly. + const downloaded = await buffer(response.readableStreamBody!); + console.log("Downloaded blob content", downloaded.toString()); // Delete container await containerClient.delete(); diff --git a/sdk/storage/storage-blob/samples-dev/utils/stream.ts b/sdk/storage/storage-blob/samples-dev/utils/stream.ts deleted file mode 100644 index 9225d1101a51..000000000000 --- a/sdk/storage/storage-blob/samples-dev/utils/stream.ts +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -// A helper method used to read a Node.js readable stream into a Buffer -export function streamToBuffer(stream: NodeJS.ReadableStream): Promise { - return new Promise((resolve, reject) => { - const chunks: Buffer[] = []; - stream.on("data", (data) => { - chunks.push(Buffer.isBuffer(data) ? data : Buffer.from(data)); - }); - stream.on("end", () => { - resolve(Buffer.concat(chunks)); - }); - stream.on("error", reject); - }); -} diff --git a/sdk/storage/storage-blob/samples/v12/javascript/README.md b/sdk/storage/storage-blob/samples/v12/javascript/README.md index d1c12ad8903d..81cf28690de7 100644 --- a/sdk/storage/storage-blob/samples/v12/javascript/README.md +++ b/sdk/storage/storage-blob/samples/v12/javascript/README.md @@ -58,10 +58,10 @@ npm install node sharedKeyAuth.js ``` -Alternatively, run a single sample with the correct environment variables set (setting up the `.env` file is not required if you do this), for example (cross-platform): +Alternatively, run a single sample with the required environment variables set (setting up the `.env` file is not required if you do this), for example (cross-platform): ```bash -cross-env ACCOUNT_NAME="" ACCOUNT_KEY="" node sharedKeyAuth.js +npx cross-env ACCOUNT_NAME="" ACCOUNT_KEY="" node sharedKeyAuth.js ``` ## Next Steps diff --git a/sdk/storage/storage-blob/samples/v12/javascript/advancedRequestOptions.js b/sdk/storage/storage-blob/samples/v12/javascript/advancedRequestOptions.js index a1837339b99e..0d2f0380c2b0 100644 --- a/sdk/storage/storage-blob/samples/v12/javascript/advancedRequestOptions.js +++ b/sdk/storage/storage-blob/samples/v12/javascript/advancedRequestOptions.js @@ -5,14 +5,12 @@ * @summary use advanced HTTP pipeline and request options for several methods */ -const fs = require("fs"); +const fs = require("node:fs"); -const { AbortController } = require("@azure/abort-controller"); const { AnonymousCredential, BlobServiceClient, newPipeline } = require("@azure/storage-blob"); // Load the .env file if it exists -require("dotenv").config(); - +require("dotenv/config"); // Enabling logging may help uncover useful information about failures. // In order to see a log of HTTP requests and responses, set the `AZURE_LOG_LEVEL` environment variable to `info`. // Alternatively, logging can be enabled at runtime by calling `setLogLevel("info");` @@ -28,8 +26,8 @@ async function main() { const pipeline = newPipeline(new AnonymousCredential(), { // httpClient: MyHTTPClient, // A customized HTTP client implementing IHttpClient interface - retryOptions: { maxTries: 4 }, - userAgentOptions: { userAgentPrefix: "AdvancedSample V1.0.0" }, + retryOptions: { maxTries: 4 }, // Retry options + userAgentOptions: { userAgentPrefix: "AdvancedSample V1.0.0" }, // Customized telemetry string keepAliveOptions: { // Keep alive is enabled by default, disable keep alive by setting false enable: false, @@ -37,8 +35,8 @@ async function main() { }); const blobServiceClient = new BlobServiceClient( - `https://${account}.blob.core.windows.net?${accountSas}`, - pipeline + `https://${account}.blob.core.windows.net${accountSas}`, + pipeline, ); // Create a container @@ -48,7 +46,7 @@ async function main() { await containerClient.create(); } catch (err) { console.log( - `Creating a container failed, requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}` + `Creating a container failed, requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`, ); } @@ -60,14 +58,14 @@ async function main() { // BlockBlobClient.uploadFile() is only available in Node.js try { await blockBlobClient.uploadFile(localFilePath, { - blockSize: 4 * 1024 * 1024, - concurrency: 20, + blockSize: 4 * 1024 * 1024, // 4MB block size + concurrency: 20, // 20 concurrency onProgress: (ev) => console.log(ev), }); console.log("Successfully uploaded file:", blockBlobClient.name); } catch (err) { console.log( - `uploadFile failed, requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}` + `uploadFile failed, requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`, ); } @@ -75,13 +73,13 @@ async function main() { // BlockBlobClient.uploadStream() is only available in Node.js try { await blockBlobClient.uploadStream(fs.createReadStream(localFilePath), 4 * 1024 * 1024, 20, { - abortSignal: AbortSignal.timeout(30 * 60 * 1000), + abortSignal: AbortSignal.timeout(30 * 60 * 1000), // Abort uploading with timeout in 30mins onProgress: (ev) => console.log(ev), }); console.log("uploadStream succeeds"); } catch (err) { console.log( - `uploadStream failed, requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}` + `uploadStream failed, requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`, ); } @@ -102,15 +100,15 @@ async function main() { const buffer = Buffer.alloc(fileSize); try { await blockBlobClient.downloadToBuffer(buffer, 0, undefined, { - abortSignal: AbortSignal.timeout(30 * 60 * 1000), - blockSize: 4 * 1024 * 1024, - concurrency: 20, + abortSignal: AbortSignal.timeout(30 * 60 * 1000), // Abort uploading with timeout in 30mins + blockSize: 4 * 1024 * 1024, // 4MB block size + concurrency: 20, // 20 concurrency onProgress: (ev) => console.log(ev), }); console.log("downloadToBuffer succeeds"); } catch (err) { console.log( - `downloadToBuffer failed, requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}` + `downloadToBuffer failed, requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`, ); } @@ -123,7 +121,7 @@ async function main() { } catch (err) { // BlobArchived Conflict (409) This operation is not permitted on an archived blob. console.log( - `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}` + `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`, ); console.log(`error message - ${err.details.message}\n`); } diff --git a/sdk/storage/storage-blob/samples/v12/javascript/anonymousAuth.js b/sdk/storage/storage-blob/samples/v12/javascript/anonymousAuth.js index afbba1a95a4e..8224a1e8828f 100644 --- a/sdk/storage/storage-blob/samples/v12/javascript/anonymousAuth.js +++ b/sdk/storage/storage-blob/samples/v12/javascript/anonymousAuth.js @@ -8,7 +8,7 @@ const { BlobServiceClient, AnonymousCredential } = require("@azure/storage-blob"); // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Enter your storage account name and SAS @@ -18,8 +18,8 @@ async function main() { // List containers const blobServiceClient = new BlobServiceClient( // When using AnonymousCredential, following url should include a valid SAS or support public access - `https://${account}.blob.core.windows.net?${accountSas}`, - new AnonymousCredential() + `https://${account}.blob.core.windows.net${accountSas}`, + new AnonymousCredential(), ); console.log("Containers:"); diff --git a/sdk/storage/storage-blob/samples/v12/javascript/azureAdAuth.js b/sdk/storage/storage-blob/samples/v12/javascript/azureAdAuth.js index 6478cc326940..d5761264af51 100644 --- a/sdk/storage/storage-blob/samples/v12/javascript/azureAdAuth.js +++ b/sdk/storage/storage-blob/samples/v12/javascript/azureAdAuth.js @@ -29,7 +29,7 @@ const { BlobServiceClient } = require("@azure/storage-blob"); const { DefaultAzureCredential } = require("@azure/identity"); // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Enter your storage account name @@ -50,7 +50,7 @@ async function main() { const blobServiceClient = new BlobServiceClient( `https://${account}.blob.core.windows.net`, - new DefaultAzureCredential() + new DefaultAzureCredential(), ); // Create a container diff --git a/sdk/storage/storage-blob/samples/v12/javascript/connectionStringAuth.js b/sdk/storage/storage-blob/samples/v12/javascript/connectionStringAuth.js index 12981b4bb3b7..07f251031870 100644 --- a/sdk/storage/storage-blob/samples/v12/javascript/connectionStringAuth.js +++ b/sdk/storage/storage-blob/samples/v12/javascript/connectionStringAuth.js @@ -8,7 +8,7 @@ const { BlobServiceClient } = require("@azure/storage-blob"); // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Create Blob Service Client from Account connection string or SAS connection string diff --git a/sdk/storage/storage-blob/samples/v12/javascript/customPipeline.js b/sdk/storage/storage-blob/samples/v12/javascript/customPipeline.js index 3108b81bebc8..d24dd130ac9d 100644 --- a/sdk/storage/storage-blob/samples/v12/javascript/customPipeline.js +++ b/sdk/storage/storage-blob/samples/v12/javascript/customPipeline.js @@ -12,7 +12,7 @@ const { } = require("@azure/storage-blob"); // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Enter your storage account name and shared key @@ -26,14 +26,14 @@ async function main() { // Use sharedKeyCredential, tokenCredential or anonymousCredential to create a pipeline const pipeline = newPipeline(sharedKeyCredential, { // httpClient: MyHTTPClient, // A customized HTTP client implementing IHttpClient interface - retryOptions: { maxTries: 4 }, + retryOptions: { maxTries: 4 }, // Retry options userAgentOptions: { userAgentPrefix: "Sample V1.0.0" }, // Customized telemetry string }); // List containers const blobServiceClient = new BlobServiceClient( `https://${account}.blob.core.windows.net`, - pipeline + pipeline, ); let i = 1; diff --git a/sdk/storage/storage-blob/samples/v12/javascript/customizedClientHeaders.js b/sdk/storage/storage-blob/samples/v12/javascript/customizedClientHeaders.js index b088ff19c557..64bf95ce8b45 100644 --- a/sdk/storage/storage-blob/samples/v12/javascript/customizedClientHeaders.js +++ b/sdk/storage/storage-blob/samples/v12/javascript/customizedClientHeaders.js @@ -20,8 +20,7 @@ const { } = require("@azure/storage-blob"); // Load the .env file if it exists -require("dotenv").config(); - +require("dotenv/config"); // Create a policy factory with create() method provided class RequestIDPolicyFactory { prefix; @@ -50,7 +49,7 @@ class RequestIDPolicy extends BaseRequestPolicy { // Customize client request ID header request.headers.set( "x-ms-client-request-id", - `${this.prefix}_SOME_PATTERN_${new Date().getTime()}` + `${this.prefix}_SOME_PATTERN_${new Date().getTime()}`, ); // response is HttpOperationResponse type @@ -71,11 +70,11 @@ async function main() { const pipeline = newPipeline(new AnonymousCredential()); // Inject customized factory into default pipeline - pipeline.factories.unshift(new RequestIDPolicyFactory("Prefix")); + await pipeline.factories.unshift(new RequestIDPolicyFactory("Prefix")); const blobServiceClient = new BlobServiceClient( - `https://${account}.blob.core.windows.net?${accountSas}`, - pipeline + `https://${account}.blob.core.windows.net${accountSas}`, + pipeline, ); const result = await blobServiceClient.listContainers().byPage().next(); diff --git a/sdk/storage/storage-blob/samples/v12/javascript/errorsAndResponses.js b/sdk/storage/storage-blob/samples/v12/javascript/errorsAndResponses.js index e57285d231ad..ef06efeba73a 100644 --- a/sdk/storage/storage-blob/samples/v12/javascript/errorsAndResponses.js +++ b/sdk/storage/storage-blob/samples/v12/javascript/errorsAndResponses.js @@ -7,10 +7,12 @@ const { BlobServiceClient } = require("@azure/storage-blob"); -const { streamToBuffer } = require("./utils/stream"); +const { buffer } = require("node:stream/consumers"); +// Use `text` from "node:stream/consumers" if you want the content as a string directly. +// import { text } from "node:stream/consumers"; // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Create Blob Service Client from Account connection string or SAS connection string @@ -28,7 +30,7 @@ async function main() { let createContainerResponse = await containerClient.create(); console.log(`Created container ${containerName} successfully,`); console.log( - `requestId - ${createContainerResponse.requestId}, statusCode - ${createContainerResponse._response.status}\n` + `requestId - ${createContainerResponse.requestId}, statusCode - ${createContainerResponse._response.status}\n`, ); try { @@ -37,7 +39,7 @@ async function main() { createContainerResponse = await containerClient.create(); } catch (err) { console.log( - `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}\n` + `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}\n`, ); } @@ -53,7 +55,7 @@ async function main() { } catch (err) { console.log(`getProperties() failed as expected,`); console.log( - `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}\n` + `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}\n`, ); // Create a new block blob @@ -61,7 +63,7 @@ async function main() { const uploadBlobResponse = await blockBlobClient.upload(content, Buffer.byteLength(content)); console.log(`Uploaded block blob ${blobName} successfully,`); console.log( - `requestId - ${uploadBlobResponse.requestId}, statusCode - ${uploadBlobResponse._response.status}\n` + `requestId - ${uploadBlobResponse.requestId}, statusCode - ${uploadBlobResponse._response.status}\n`, ); } @@ -70,10 +72,10 @@ async function main() { blockBlobClient = containerClient.getBlockBlobClient(blobName); const blobProperties = await blockBlobClient.getProperties(); console.log( - `getProperties() on blob - ${blobName}, blobType = ${blobProperties.blobType}, accessTier = ${blobProperties.accessTier} ` + `getProperties() on blob - ${blobName}, blobType = ${blobProperties.blobType}, accessTier = ${blobProperties.accessTier} `, ); console.log( - `requestId - ${blobProperties.requestId}, statusCode - ${blobProperties._response.status}\n` + `requestId - ${blobProperties.requestId}, statusCode - ${blobProperties._response.status}\n`, ); try { @@ -84,20 +86,19 @@ async function main() { } catch (err) { console.log(`download() failed as expected,`); console.log( - `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}\n` + `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}\n`, ); // Download blob content console.log("// Download blob content..."); blockBlobClient = containerClient.getBlockBlobClient(blobName); const downloadBlockBlobResponse = await blockBlobClient.download(); + // Download the raw bytes of the blob. Use `text(...)` from "node:stream/consumers" + // instead if you want to read the content as a string directly. + const downloaded = await buffer(downloadBlockBlobResponse.readableStreamBody); + console.log(`Downloaded blob content - ${downloaded.toString()},`); console.log( - `Downloaded blob content - ${( - await streamToBuffer(downloadBlockBlobResponse.readableStreamBody) - ).toString()},` - ); - console.log( - `requestId - ${downloadBlockBlobResponse.requestId}, statusCode - ${downloadBlockBlobResponse._response.status}\n` + `requestId - ${downloadBlockBlobResponse.requestId}, statusCode - ${downloadBlockBlobResponse._response.status}\n`, ); } @@ -111,7 +112,7 @@ async function main() { } catch (err) { // BlobArchived Conflict (409) This operation is not permitted on an archived blob. console.log( - `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}` + `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`, ); console.log(`error message - ${err.details.message}\n`); } @@ -125,7 +126,7 @@ async function main() { } catch (err) { console.log(`Deleting a non-existing container fails as expected`); console.log( - `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}` + `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`, ); console.log(`error message - \n${err.details.message}\n`); @@ -134,7 +135,7 @@ async function main() { const deleteContainerResponse = await containerClient.delete(); console.log("Deleted container successfully -"); console.log( - `requestId - ${deleteContainerResponse.requestId}, statusCode - ${deleteContainerResponse._response.status}\n` + `requestId - ${deleteContainerResponse.requestId}, statusCode - ${deleteContainerResponse._response.status}\n`, ); } } diff --git a/sdk/storage/storage-blob/samples/v12/javascript/listBlobsByHierarchy.js b/sdk/storage/storage-blob/samples/v12/javascript/listBlobsByHierarchy.js index d43114023658..0fc43d5ef5a7 100644 --- a/sdk/storage/storage-blob/samples/v12/javascript/listBlobsByHierarchy.js +++ b/sdk/storage/storage-blob/samples/v12/javascript/listBlobsByHierarchy.js @@ -8,7 +8,7 @@ const { ContainerClient, StorageSharedKeyCredential } = require("@azure/storage-blob"); // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Enter your storage account name and shared key @@ -23,7 +23,7 @@ async function main() { const containerName = `newcontainer${new Date().getTime()}`; const containerClient = new ContainerClient( `https://${account}.blob.core.windows.net/${containerName}`, - sharedKeyCredential + sharedKeyCredential, ); const createContainerResponse = await containerClient.create(); @@ -55,7 +55,7 @@ async function main() { console.log(`\tBlobPrefix: ${item.name}`); } else { console.log( - `\tBlobItem: name - ${item.name}, last modified - ${item.properties.lastModified}` + `\tBlobItem: name - ${item.name}, last modified - ${item.properties.lastModified}`, ); } } @@ -68,7 +68,7 @@ async function main() { console.log(`\tBlobPrefix: ${item.name}`); } else { console.log( - `\tBlobItem: name - ${item.name}, last modified - ${item.properties.lastModified}` + `\tBlobItem: name - ${item.name}, last modified - ${item.properties.lastModified}`, ); } } @@ -85,7 +85,7 @@ async function main() { } for (const blob of page.segment.blobItems) { console.log( - `\tBlobItem: name - ${blob.name}, last modified - ${blob.properties.lastModified}` + `\tBlobItem: name - ${blob.name}, last modified - ${blob.properties.lastModified}`, ); } } diff --git a/sdk/storage/storage-blob/samples/v12/javascript/listBlobsFlat.js b/sdk/storage/storage-blob/samples/v12/javascript/listBlobsFlat.js index 0398e8cd34ea..391d19530d5e 100644 --- a/sdk/storage/storage-blob/samples/v12/javascript/listBlobsFlat.js +++ b/sdk/storage/storage-blob/samples/v12/javascript/listBlobsFlat.js @@ -8,7 +8,7 @@ const { ContainerClient, StorageSharedKeyCredential } = require("@azure/storage-blob"); // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Enter your storage account name and shared key @@ -23,7 +23,7 @@ async function main() { const containerName = `newcontainer${new Date().getTime()}`; const containerClient = new ContainerClient( `https://${account}.blob.core.windows.net/${containerName}`, - sharedKeyCredential + sharedKeyCredential, ); const createContainerResponse = await containerClient.create(); @@ -73,7 +73,7 @@ async function main() { if (!continuationToken) { throw new Error( - "Expected a continuation token from the blob service, but one was not returned." + "Expected a continuation token from the blob service, but one was not returned.", ); } diff --git a/sdk/storage/storage-blob/samples/v12/javascript/listContainers.js b/sdk/storage/storage-blob/samples/v12/javascript/listContainers.js index 570aef77da46..112575bdf81b 100644 --- a/sdk/storage/storage-blob/samples/v12/javascript/listContainers.js +++ b/sdk/storage/storage-blob/samples/v12/javascript/listContainers.js @@ -8,7 +8,7 @@ const { BlobServiceClient, StorageSharedKeyCredential } = require("@azure/storage-blob"); // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Enter your storage account name and shared key @@ -22,7 +22,7 @@ async function main() { // List containers const blobServiceClient = new BlobServiceClient( `https://${account}.blob.core.windows.net`, - sharedKeyCredential + sharedKeyCredential, ); // Iterate over all containers in the account diff --git a/sdk/storage/storage-blob/samples/v12/javascript/package.json b/sdk/storage/storage-blob/samples/v12/javascript/package.json index c3e11e6c32e8..005dc1ffc0b2 100644 --- a/sdk/storage/storage-blob/samples/v12/javascript/package.json +++ b/sdk/storage/storage-blob/samples/v12/javascript/package.json @@ -30,8 +30,10 @@ "dependencies": { "@azure/storage-blob": "latest", "dotenv": "latest", - "@azure/abort-controller": "^2.1.2", - "@azure/logger": "^1.0.0", - "@azure/identity": "^4.2.1" + "@azure/logger": "^1.1.4", + "@azure/identity": "^4.13.0" + }, + "devDependencies": { + "cross-env": "latest" } } diff --git a/sdk/storage/storage-blob/samples/v12/javascript/proxyAuth.js b/sdk/storage/storage-blob/samples/v12/javascript/proxyAuth.js index 825ea4b0733a..4c8dfd063d6b 100644 --- a/sdk/storage/storage-blob/samples/v12/javascript/proxyAuth.js +++ b/sdk/storage/storage-blob/samples/v12/javascript/proxyAuth.js @@ -8,7 +8,7 @@ const { BlobServiceClient, StorageSharedKeyCredential } = require("@azure/storage-blob"); // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Enter your storage account name and shared key @@ -40,7 +40,7 @@ async function main() { password: "" } */ - } + }, ); // Create a container diff --git a/sdk/storage/storage-blob/samples/v12/javascript/sample.env b/sdk/storage/storage-blob/samples/v12/javascript/sample.env index c3a35d59d8b6..62966df58815 100644 --- a/sdk/storage/storage-blob/samples/v12/javascript/sample.env +++ b/sdk/storage/storage-blob/samples/v12/javascript/sample.env @@ -8,13 +8,5 @@ STORAGE_CONNECTION_STRING= # Used for the advanced and anonymousCred tests. Create a SAS token for a storage account in the Azure Portal. ACCOUNT_SAS= -# Used to authenticate using Azure AD as a service principal for role-based authentication. -# -# See the documentation for `EnvironmentCredential` at the following link: -# https://learn.microsoft.com/javascript/api/@azure/identity/environmentcredential -AZURE_TENANT_ID= -AZURE_CLIENT_ID= -AZURE_CLIENT_SECRET= - # To run the proxyAuth sample, set up an HTTP proxy and enter your information: # HTTP_PROXY=http://localhost:3128 diff --git a/sdk/storage/storage-blob/samples/v12/javascript/sharedKeyAuth.js b/sdk/storage/storage-blob/samples/v12/javascript/sharedKeyAuth.js index cf706be1e3ef..ce13f3be8ef1 100644 --- a/sdk/storage/storage-blob/samples/v12/javascript/sharedKeyAuth.js +++ b/sdk/storage/storage-blob/samples/v12/javascript/sharedKeyAuth.js @@ -8,7 +8,7 @@ const { BlobServiceClient, StorageSharedKeyCredential } = require("@azure/storage-blob"); // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Enter your storage account name and shared key @@ -22,7 +22,7 @@ async function main() { // List containers const blobServiceClient = new BlobServiceClient( `https://${account}.blob.core.windows.net`, - sharedKeyCredential + sharedKeyCredential, ); let i = 1; diff --git a/sdk/storage/storage-blob/samples/v12/javascript/snapshots.js b/sdk/storage/storage-blob/samples/v12/javascript/snapshots.js index e5f8d72501dc..f1dea65c5e1d 100644 --- a/sdk/storage/storage-blob/samples/v12/javascript/snapshots.js +++ b/sdk/storage/storage-blob/samples/v12/javascript/snapshots.js @@ -22,10 +22,12 @@ const { ContainerClient, StorageSharedKeyCredential } = require("@azure/storage-blob"); -const { streamToBuffer } = require("./utils/stream"); +const { buffer } = require("node:stream/consumers"); +// Use `text` from "node:stream/consumers" if you want the content as a string directly. +// import { text } from "node:stream/consumers"; // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Enter your storage account name and shared key @@ -40,7 +42,7 @@ async function main() { const containerName = `newcontainer${new Date().getTime()}`; const containerClient = new ContainerClient( `https://${account}.blob.core.windows.net/${containerName}`, - sharedKeyCredential + sharedKeyCredential, ); const createContainerResponse = await containerClient.create(); @@ -61,13 +63,13 @@ async function main() { const response = await blobSnapshotClient.download(0); console.log( "Reading response to string...", - (await blobSnapshotClient.getProperties()).contentLength + (await blobSnapshotClient.getProperties()).contentLength, ); - console.log( - "Downloaded blob content", - (await streamToBuffer(response.readableStreamBody)).toString() - ); + // Download the raw bytes of the blob. Use `text(response.readableStreamBody!)` + // instead if you want to read the content as a string directly. + const downloaded = await buffer(response.readableStreamBody); + console.log("Downloaded blob content", downloaded.toString()); // Delete container await containerClient.delete(); diff --git a/sdk/storage/storage-blob/samples/v12/javascript/utils/stream.js b/sdk/storage/storage-blob/samples/v12/javascript/utils/stream.js deleted file mode 100644 index 1ceac6da4c8e..000000000000 --- a/sdk/storage/storage-blob/samples/v12/javascript/utils/stream.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -// A helper method used to read a Node.js readable stream into a Buffer -function streamToBuffer(stream) { - return new Promise((resolve, reject) => { - const chunks = []; - stream.on("data", (data) => { - chunks.push(Buffer.isBuffer(data) ? data : Buffer.from(data)); - }); - stream.on("end", () => { - resolve(Buffer.concat(chunks)); - }); - stream.on("error", reject); - }); -} - -module.exports = { streamToBuffer }; diff --git a/sdk/storage/storage-blob/samples/v12/typescript/README.md b/sdk/storage/storage-blob/samples/v12/typescript/README.md index 81ce100f7f51..3ca4cdd4c6a6 100644 --- a/sdk/storage/storage-blob/samples/v12/typescript/README.md +++ b/sdk/storage/storage-blob/samples/v12/typescript/README.md @@ -70,10 +70,10 @@ npm run build node dist/sharedKeyAuth.js ``` -Alternatively, run a single sample with the correct environment variables set (setting up the `.env` file is not required if you do this), for example (cross-platform): +Alternatively, run a single sample with the required environment variables set (setting up the `.env` file is not required if you do this), for example (cross-platform): ```bash -cross-env ACCOUNT_NAME="" ACCOUNT_KEY="" node dist/sharedKeyAuth.js +npx cross-env ACCOUNT_NAME="" ACCOUNT_KEY="" node dist/sharedKeyAuth.js ``` ## Next Steps diff --git a/sdk/storage/storage-blob/samples/v12/typescript/package.json b/sdk/storage/storage-blob/samples/v12/typescript/package.json index 9b8337484794..95e9278d38a2 100644 --- a/sdk/storage/storage-blob/samples/v12/typescript/package.json +++ b/sdk/storage/storage-blob/samples/v12/typescript/package.json @@ -34,13 +34,13 @@ "dependencies": { "@azure/storage-blob": "latest", "dotenv": "latest", - "@azure/abort-controller": "^2.1.2", - "@azure/logger": "^1.0.0", - "@azure/identity": "^4.2.1" + "@azure/logger": "^1.1.4", + "@azure/identity": "^4.13.0" }, "devDependencies": { "@types/node": "^20.0.0", - "typescript": "~5.8.2", - "rimraf": "latest" + "cross-env": "latest", + "rimraf": "latest", + "typescript": "~6.0.2" } } diff --git a/sdk/storage/storage-blob/samples/v12/typescript/sample.env b/sdk/storage/storage-blob/samples/v12/typescript/sample.env index c3a35d59d8b6..62966df58815 100644 --- a/sdk/storage/storage-blob/samples/v12/typescript/sample.env +++ b/sdk/storage/storage-blob/samples/v12/typescript/sample.env @@ -8,13 +8,5 @@ STORAGE_CONNECTION_STRING= # Used for the advanced and anonymousCred tests. Create a SAS token for a storage account in the Azure Portal. ACCOUNT_SAS= -# Used to authenticate using Azure AD as a service principal for role-based authentication. -# -# See the documentation for `EnvironmentCredential` at the following link: -# https://learn.microsoft.com/javascript/api/@azure/identity/environmentcredential -AZURE_TENANT_ID= -AZURE_CLIENT_ID= -AZURE_CLIENT_SECRET= - # To run the proxyAuth sample, set up an HTTP proxy and enter your information: # HTTP_PROXY=http://localhost:3128 diff --git a/sdk/storage/storage-blob/samples/v12/typescript/src/advancedRequestOptions.ts b/sdk/storage/storage-blob/samples/v12/typescript/src/advancedRequestOptions.ts index 6b4b7c33b17a..f17ada5eeba6 100644 --- a/sdk/storage/storage-blob/samples/v12/typescript/src/advancedRequestOptions.ts +++ b/sdk/storage/storage-blob/samples/v12/typescript/src/advancedRequestOptions.ts @@ -35,8 +35,8 @@ async function main(): Promise { }); const blobServiceClient = new BlobServiceClient( - `https://${account}.blob.core.windows.net?${accountSas}`, - pipeline + `https://${account}.blob.core.windows.net${accountSas}`, + pipeline, ); // Create a container @@ -46,7 +46,7 @@ async function main(): Promise { await containerClient.create(); } catch (err: any) { console.log( - `Creating a container failed, requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}` + `Creating a container failed, requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`, ); } @@ -65,7 +65,7 @@ async function main(): Promise { console.log("Successfully uploaded file:", blockBlobClient.name); } catch (err: any) { console.log( - `uploadFile failed, requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}` + `uploadFile failed, requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`, ); } @@ -79,7 +79,7 @@ async function main(): Promise { console.log("uploadStream succeeds"); } catch (err: any) { console.log( - `uploadStream failed, requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}` + `uploadStream failed, requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`, ); } @@ -108,7 +108,7 @@ async function main(): Promise { console.log("downloadToBuffer succeeds"); } catch (err: any) { console.log( - `downloadToBuffer failed, requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}` + `downloadToBuffer failed, requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`, ); } @@ -121,7 +121,7 @@ async function main(): Promise { } catch (err: any) { // BlobArchived Conflict (409) This operation is not permitted on an archived blob. console.log( - `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}` + `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`, ); console.log(`error message - ${err.details.message}\n`); } diff --git a/sdk/storage/storage-blob/samples/v12/typescript/src/anonymousAuth.ts b/sdk/storage/storage-blob/samples/v12/typescript/src/anonymousAuth.ts index 1de260e77e91..0ca0ccd019eb 100644 --- a/sdk/storage/storage-blob/samples/v12/typescript/src/anonymousAuth.ts +++ b/sdk/storage/storage-blob/samples/v12/typescript/src/anonymousAuth.ts @@ -18,8 +18,8 @@ async function main(): Promise { // List containers const blobServiceClient = new BlobServiceClient( // When using AnonymousCredential, following url should include a valid SAS or support public access - `https://${account}.blob.core.windows.net?${accountSas}`, - new AnonymousCredential() + `https://${account}.blob.core.windows.net${accountSas}`, + new AnonymousCredential(), ); console.log("Containers:"); diff --git a/sdk/storage/storage-blob/samples/v12/typescript/src/azureAdAuth.ts b/sdk/storage/storage-blob/samples/v12/typescript/src/azureAdAuth.ts index 2f7c2ff20941..2ffa33289d8b 100644 --- a/sdk/storage/storage-blob/samples/v12/typescript/src/azureAdAuth.ts +++ b/sdk/storage/storage-blob/samples/v12/typescript/src/azureAdAuth.ts @@ -50,7 +50,7 @@ async function main(): Promise { const blobServiceClient = new BlobServiceClient( `https://${account}.blob.core.windows.net`, - new DefaultAzureCredential() + new DefaultAzureCredential(), ); // Create a container diff --git a/sdk/storage/storage-blob/samples/v12/typescript/src/customPipeline.ts b/sdk/storage/storage-blob/samples/v12/typescript/src/customPipeline.ts index 064a477efffb..6612d8b3e300 100644 --- a/sdk/storage/storage-blob/samples/v12/typescript/src/customPipeline.ts +++ b/sdk/storage/storage-blob/samples/v12/typescript/src/customPipeline.ts @@ -23,13 +23,13 @@ async function main(): Promise { const pipeline = newPipeline(sharedKeyCredential, { // httpClient: MyHTTPClient, // A customized HTTP client implementing IHttpClient interface retryOptions: { maxTries: 4 }, // Retry options - userAgentOptions: { userAgentPrefix: "Sample V1.0.0" } // Customized telemetry string + userAgentOptions: { userAgentPrefix: "Sample V1.0.0" }, // Customized telemetry string }); // List containers const blobServiceClient = new BlobServiceClient( `https://${account}.blob.core.windows.net`, - pipeline + pipeline, ); let i = 1; diff --git a/sdk/storage/storage-blob/samples/v12/typescript/src/customizedClientHeaders.ts b/sdk/storage/storage-blob/samples/v12/typescript/src/customizedClientHeaders.ts index aa22c9ca584f..841b6ce60b0a 100644 --- a/sdk/storage/storage-blob/samples/v12/typescript/src/customizedClientHeaders.ts +++ b/sdk/storage/storage-blob/samples/v12/typescript/src/customizedClientHeaders.ts @@ -12,14 +12,12 @@ * @summary customize request headers such as `X-Ms-Client-Request-Id` using an HTTP policy **/ +import type { WebResource, RequestPolicy, RequestPolicyOptions } from "@azure/storage-blob"; import { newPipeline, AnonymousCredential, BlobServiceClient, BaseRequestPolicy, - WebResource, - RequestPolicy, - RequestPolicyOptions } from "@azure/storage-blob"; // Load the .env file if it exists @@ -52,7 +50,7 @@ class RequestIDPolicy extends BaseRequestPolicy { // Customize client request ID header request.headers.set( "x-ms-client-request-id", - `${this.prefix}_SOME_PATTERN_${new Date().getTime()}` + `${this.prefix}_SOME_PATTERN_${new Date().getTime()}`, ); // response is HttpOperationResponse type @@ -73,17 +71,14 @@ async function main(): Promise { const pipeline = newPipeline(new AnonymousCredential()); // Inject customized factory into default pipeline - pipeline.factories.unshift(new RequestIDPolicyFactory("Prefix")); + await pipeline.factories.unshift(new RequestIDPolicyFactory("Prefix")); const blobServiceClient = new BlobServiceClient( - `https://${account}.blob.core.windows.net?${accountSas}`, - pipeline + `https://${account}.blob.core.windows.net${accountSas}`, + pipeline, ); - const result = await blobServiceClient - .listContainers() - .byPage() - .next(); + const result = await blobServiceClient.listContainers().byPage().next(); if (result.done) { throw new Error("Expected at least one page of containers."); diff --git a/sdk/storage/storage-blob/samples/v12/typescript/src/errorsAndResponses.ts b/sdk/storage/storage-blob/samples/v12/typescript/src/errorsAndResponses.ts index c2da4cb4687c..209968e0bcc3 100644 --- a/sdk/storage/storage-blob/samples/v12/typescript/src/errorsAndResponses.ts +++ b/sdk/storage/storage-blob/samples/v12/typescript/src/errorsAndResponses.ts @@ -7,7 +7,9 @@ import { BlobServiceClient } from "@azure/storage-blob"; -import { streamToBuffer } from "./utils/stream.js"; +import { buffer } from "node:stream/consumers"; +// Use `text` from "node:stream/consumers" if you want the content as a string directly. +// import { text } from "node:stream/consumers"; // Load the .env file if it exists import "dotenv/config"; @@ -28,7 +30,7 @@ async function main(): Promise { let createContainerResponse = await containerClient.create(); console.log(`Created container ${containerName} successfully,`); console.log( - `requestId - ${createContainerResponse.requestId}, statusCode - ${createContainerResponse._response.status}\n` + `requestId - ${createContainerResponse.requestId}, statusCode - ${createContainerResponse._response.status}\n`, ); try { @@ -37,7 +39,7 @@ async function main(): Promise { createContainerResponse = await containerClient.create(); } catch (err: any) { console.log( - `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}\n` + `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}\n`, ); } @@ -53,7 +55,7 @@ async function main(): Promise { } catch (err: any) { console.log(`getProperties() failed as expected,`); console.log( - `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}\n` + `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}\n`, ); // Create a new block blob @@ -61,7 +63,7 @@ async function main(): Promise { const uploadBlobResponse = await blockBlobClient.upload(content, Buffer.byteLength(content)); console.log(`Uploaded block blob ${blobName} successfully,`); console.log( - `requestId - ${uploadBlobResponse.requestId}, statusCode - ${uploadBlobResponse._response.status}\n` + `requestId - ${uploadBlobResponse.requestId}, statusCode - ${uploadBlobResponse._response.status}\n`, ); } @@ -70,10 +72,10 @@ async function main(): Promise { blockBlobClient = containerClient.getBlockBlobClient(blobName); const blobProperties = await blockBlobClient.getProperties(); console.log( - `getProperties() on blob - ${blobName}, blobType = ${blobProperties.blobType}, accessTier = ${blobProperties.accessTier} ` + `getProperties() on blob - ${blobName}, blobType = ${blobProperties.blobType}, accessTier = ${blobProperties.accessTier} `, ); console.log( - `requestId - ${blobProperties.requestId}, statusCode - ${blobProperties._response.status}\n` + `requestId - ${blobProperties.requestId}, statusCode - ${blobProperties._response.status}\n`, ); try { @@ -84,20 +86,19 @@ async function main(): Promise { } catch (err: any) { console.log(`download() failed as expected,`); console.log( - `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}\n` + `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}\n`, ); // Download blob content console.log("// Download blob content..."); blockBlobClient = containerClient.getBlockBlobClient(blobName); const downloadBlockBlobResponse = await blockBlobClient.download(); + // Download the raw bytes of the blob. Use `text(...)` from "node:stream/consumers" + // instead if you want to read the content as a string directly. + const downloaded = await buffer(downloadBlockBlobResponse.readableStreamBody!); + console.log(`Downloaded blob content - ${downloaded.toString()},`); console.log( - `Downloaded blob content - ${( - await streamToBuffer(downloadBlockBlobResponse.readableStreamBody!) - ).toString()},` - ); - console.log( - `requestId - ${downloadBlockBlobResponse.requestId}, statusCode - ${downloadBlockBlobResponse._response.status}\n` + `requestId - ${downloadBlockBlobResponse.requestId}, statusCode - ${downloadBlockBlobResponse._response.status}\n`, ); } @@ -111,7 +112,7 @@ async function main(): Promise { } catch (err: any) { // BlobArchived Conflict (409) This operation is not permitted on an archived blob. console.log( - `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}` + `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`, ); console.log(`error message - ${err.details.message}\n`); } @@ -125,7 +126,7 @@ async function main(): Promise { } catch (err: any) { console.log(`Deleting a non-existing container fails as expected`); console.log( - `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}` + `requestId - ${err.request.requestId}, statusCode - ${err.statusCode}, errorCode - ${err.details.errorCode}`, ); console.log(`error message - \n${err.details.message}\n`); @@ -134,7 +135,7 @@ async function main(): Promise { const deleteContainerResponse = await containerClient.delete(); console.log("Deleted container successfully -"); console.log( - `requestId - ${deleteContainerResponse.requestId}, statusCode - ${deleteContainerResponse._response.status}\n` + `requestId - ${deleteContainerResponse.requestId}, statusCode - ${deleteContainerResponse._response.status}\n`, ); } } diff --git a/sdk/storage/storage-blob/samples/v12/typescript/src/listBlobsByHierarchy.ts b/sdk/storage/storage-blob/samples/v12/typescript/src/listBlobsByHierarchy.ts index 2cc8484c4a97..08c5553fa54f 100644 --- a/sdk/storage/storage-blob/samples/v12/typescript/src/listBlobsByHierarchy.ts +++ b/sdk/storage/storage-blob/samples/v12/typescript/src/listBlobsByHierarchy.ts @@ -23,7 +23,7 @@ async function main(): Promise { const containerName = `newcontainer${new Date().getTime()}`; const containerClient = new ContainerClient( `https://${account}.blob.core.windows.net/${containerName}`, - sharedKeyCredential + sharedKeyCredential, ); const createContainerResponse = await containerClient.create(); @@ -41,7 +41,7 @@ async function main(): Promise { "prefix1/b2", "prefix2/sub1/c", "prefix2/sub1/d", - "prefix2/sub1/e" + "prefix2/sub1/e", ]) { const blockBlobClient = containerClient.getBlockBlobClient(blobName); const { requestId } = await blockBlobClient.upload(content, contentByteLength); @@ -55,7 +55,7 @@ async function main(): Promise { console.log(`\tBlobPrefix: ${item.name}`); } else { console.log( - `\tBlobItem: name - ${item.name}, last modified - ${item.properties.lastModified}` + `\tBlobItem: name - ${item.name}, last modified - ${item.properties.lastModified}`, ); } } @@ -68,7 +68,7 @@ async function main(): Promise { console.log(`\tBlobPrefix: ${item.name}`); } else { console.log( - `\tBlobItem: name - ${item.name}, last modified - ${item.properties.lastModified}` + `\tBlobItem: name - ${item.name}, last modified - ${item.properties.lastModified}`, ); } } @@ -85,7 +85,7 @@ async function main(): Promise { } for (const blob of page.segment.blobItems) { console.log( - `\tBlobItem: name - ${blob.name}, last modified - ${blob.properties.lastModified}` + `\tBlobItem: name - ${blob.name}, last modified - ${blob.properties.lastModified}`, ); } } diff --git a/sdk/storage/storage-blob/samples/v12/typescript/src/listBlobsFlat.ts b/sdk/storage/storage-blob/samples/v12/typescript/src/listBlobsFlat.ts index 212631fa1d9e..864daf39868f 100644 --- a/sdk/storage/storage-blob/samples/v12/typescript/src/listBlobsFlat.ts +++ b/sdk/storage/storage-blob/samples/v12/typescript/src/listBlobsFlat.ts @@ -23,7 +23,7 @@ async function main(): Promise { const containerName = `newcontainer${new Date().getTime()}`; const containerClient = new ContainerClient( `https://${account}.blob.core.windows.net/${containerName}`, - sharedKeyCredential + sharedKeyCredential, ); const createContainerResponse = await containerClient.create(); @@ -73,7 +73,7 @@ async function main(): Promise { if (!continuationToken) { throw new Error( - "Expected a continuation token from the blob service, but one was not returned." + "Expected a continuation token from the blob service, but one was not returned.", ); } diff --git a/sdk/storage/storage-blob/samples/v12/typescript/src/listContainers.ts b/sdk/storage/storage-blob/samples/v12/typescript/src/listContainers.ts index 00abfd3a7205..9434bb6e7d78 100644 --- a/sdk/storage/storage-blob/samples/v12/typescript/src/listContainers.ts +++ b/sdk/storage/storage-blob/samples/v12/typescript/src/listContainers.ts @@ -22,7 +22,7 @@ async function main(): Promise { // List containers const blobServiceClient = new BlobServiceClient( `https://${account}.blob.core.windows.net`, - sharedKeyCredential + sharedKeyCredential, ); // Iterate over all containers in the account @@ -34,7 +34,7 @@ async function main(): Promise { // The iterator also supports iteration by page with a configurable (and optional) `maxPageSize` setting. console.log("Containers (by page):"); for await (const response of blobServiceClient.listContainers().byPage({ - maxPageSize: 20 + maxPageSize: 20, })) { console.log("- Page:"); if (response.containerItems) { diff --git a/sdk/storage/storage-blob/samples/v12/typescript/src/proxyAuth.ts b/sdk/storage/storage-blob/samples/v12/typescript/src/proxyAuth.ts index c257e7f95b33..6fa642c5a5ef 100644 --- a/sdk/storage/storage-blob/samples/v12/typescript/src/proxyAuth.ts +++ b/sdk/storage/storage-blob/samples/v12/typescript/src/proxyAuth.ts @@ -40,7 +40,7 @@ async function main(): Promise { password: "" } */ - } + }, ); // Create a container diff --git a/sdk/storage/storage-blob/samples/v12/typescript/src/sharedKeyAuth.ts b/sdk/storage/storage-blob/samples/v12/typescript/src/sharedKeyAuth.ts index bf80eaeefd8f..6edf1f9af82e 100644 --- a/sdk/storage/storage-blob/samples/v12/typescript/src/sharedKeyAuth.ts +++ b/sdk/storage/storage-blob/samples/v12/typescript/src/sharedKeyAuth.ts @@ -22,7 +22,7 @@ async function main(): Promise { // List containers const blobServiceClient = new BlobServiceClient( `https://${account}.blob.core.windows.net`, - sharedKeyCredential + sharedKeyCredential, ); let i = 1; diff --git a/sdk/storage/storage-blob/samples/v12/typescript/src/snapshots.ts b/sdk/storage/storage-blob/samples/v12/typescript/src/snapshots.ts index 385602f01752..6b4ea3c0637e 100644 --- a/sdk/storage/storage-blob/samples/v12/typescript/src/snapshots.ts +++ b/sdk/storage/storage-blob/samples/v12/typescript/src/snapshots.ts @@ -22,7 +22,9 @@ import { ContainerClient, StorageSharedKeyCredential } from "@azure/storage-blob"; -import { streamToBuffer } from "./utils/stream.js"; +import { buffer } from "node:stream/consumers"; +// Use `text` from "node:stream/consumers" if you want the content as a string directly. +// import { text } from "node:stream/consumers"; // Load the .env file if it exists import "dotenv/config"; @@ -40,7 +42,7 @@ async function main(): Promise { const containerName = `newcontainer${new Date().getTime()}`; const containerClient = new ContainerClient( `https://${account}.blob.core.windows.net/${containerName}`, - sharedKeyCredential + sharedKeyCredential, ); const createContainerResponse = await containerClient.create(); @@ -61,13 +63,13 @@ async function main(): Promise { const response = await blobSnapshotClient.download(0); console.log( "Reading response to string...", - (await blobSnapshotClient.getProperties()).contentLength + (await blobSnapshotClient.getProperties()).contentLength, ); - console.log( - "Downloaded blob content", - (await streamToBuffer(response.readableStreamBody!)).toString() - ); + // Download the raw bytes of the blob. Use `text(response.readableStreamBody!)` + // instead if you want to read the content as a string directly. + const downloaded = await buffer(response.readableStreamBody!); + console.log("Downloaded blob content", downloaded.toString()); // Delete container await containerClient.delete(); diff --git a/sdk/storage/storage-blob/samples/v12/typescript/src/utils/stream.ts b/sdk/storage/storage-blob/samples/v12/typescript/src/utils/stream.ts deleted file mode 100644 index 9225d1101a51..000000000000 --- a/sdk/storage/storage-blob/samples/v12/typescript/src/utils/stream.ts +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -// A helper method used to read a Node.js readable stream into a Buffer -export function streamToBuffer(stream: NodeJS.ReadableStream): Promise { - return new Promise((resolve, reject) => { - const chunks: Buffer[] = []; - stream.on("data", (data) => { - chunks.push(Buffer.isBuffer(data) ? data : Buffer.from(data)); - }); - stream.on("end", () => { - resolve(Buffer.concat(chunks)); - }); - stream.on("error", reject); - }); -} diff --git a/sdk/storage/storage-blob/samples/v12/typescript/tsconfig.json b/sdk/storage/storage-blob/samples/v12/typescript/tsconfig.json index ad5ff9a19d36..7b5fa3986736 100644 --- a/sdk/storage/storage-blob/samples/v12/typescript/tsconfig.json +++ b/sdk/storage/storage-blob/samples/v12/typescript/tsconfig.json @@ -1,17 +1,25 @@ { "compilerOptions": { - "target": "ES2018", - "module": "commonjs", - "moduleResolution": "node", + "target": "ES2023", + "module": "nodenext", + "lib": [ + "ESNext" + ], + "importHelpers": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "types": [ + "node" + ], + "allowJs": true, + "outDir": "./dist", + "rootDir": "./src", "resolveJsonModule": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "alwaysStrict": true, - "outDir": "dist", - "rootDir": "src" + "moduleResolution": "nodenext" }, "include": [ - "src/**/*.ts" + "./src" ] } diff --git a/sdk/storage/storage-blob/src/Clients.ts b/sdk/storage/storage-blob/src/Clients.ts index c4e707cdd769..8df76d8f6b60 100644 --- a/sdk/storage/storage-blob/src/Clients.ts +++ b/sdk/storage/storage-blob/src/Clients.ts @@ -1217,6 +1217,7 @@ export class BlobClient extends StorageClient { * ```ts snippet:ReadmeSampleDownloadBlob_Node * import { BlobServiceClient } from "@azure/storage-blob"; * import { DefaultAzureCredential } from "@azure/identity"; + * import { buffer } from "node:stream/consumers"; * * const account = ""; * const blobServiceClient = new BlobServiceClient( @@ -1233,22 +1234,10 @@ export class BlobClient extends StorageClient { * // In Node.js, get downloaded data by accessing downloadBlockBlobResponse.readableStreamBody * const downloadBlockBlobResponse = await blobClient.download(); * if (downloadBlockBlobResponse.readableStreamBody) { - * const downloaded = await streamToString(downloadBlockBlobResponse.readableStreamBody); - * console.log(`Downloaded blob content: ${downloaded}`); - * } - * - * async function streamToString(stream: NodeJS.ReadableStream): Promise { - * const result = await new Promise>((resolve, reject) => { - * const chunks: Buffer[] = []; - * stream.on("data", (data) => { - * chunks.push(Buffer.isBuffer(data) ? data : Buffer.from(data)); - * }); - * stream.on("end", () => { - * resolve(Buffer.concat(chunks)); - * }); - * stream.on("error", reject); - * }); - * return result.toString(); + * // Download the raw bytes of the blob. Use `text` from "node:stream/consumers" + * // instead if you want to read the content as a string directly. + * const downloaded = await buffer(downloadBlockBlobResponse.readableStreamBody); + * console.log(`Downloaded blob content: ${downloaded.toString()}`); * } * ``` * @@ -3970,6 +3959,7 @@ export class BlockBlobClient extends BlobClient { * ```ts snippet:ClientsQuery * import { BlobServiceClient } from "@azure/storage-blob"; * import { DefaultAzureCredential } from "@azure/identity"; + * import { buffer } from "node:stream/consumers"; * * const account = ""; * const blobServiceClient = new BlobServiceClient( @@ -3985,22 +3975,10 @@ export class BlockBlobClient extends BlobClient { * // Query and convert a blob to a string * const queryBlockBlobResponse = await blockBlobClient.query("select from BlobStorage"); * if (queryBlockBlobResponse.readableStreamBody) { - * const downloadedBuffer = await streamToBuffer(queryBlockBlobResponse.readableStreamBody); - * const downloaded = downloadedBuffer.toString(); - * console.log(`Query blob content: ${downloaded}`); - * } - * - * async function streamToBuffer(readableStream: NodeJS.ReadableStream): Promise { - * return new Promise((resolve, reject) => { - * const chunks: Buffer[] = []; - * readableStream.on("data", (data) => { - * chunks.push(data instanceof Buffer ? data : Buffer.from(data)); - * }); - * readableStream.on("end", () => { - * resolve(Buffer.concat(chunks)); - * }); - * readableStream.on("error", reject); - * }); + * // Read the response bytes. Use `text` from "node:stream/consumers" instead + * // if you want the response as a string directly. + * const downloadedBuffer = await buffer(queryBlockBlobResponse.readableStreamBody); + * console.log(`Query blob content: ${downloadedBuffer.toString()}`); * } * ``` * diff --git a/sdk/storage/storage-blob/test/snippets.spec.ts b/sdk/storage/storage-blob/test/snippets.spec.ts index 2749051d14fd..fd3f5c723424 100644 --- a/sdk/storage/storage-blob/test/snippets.spec.ts +++ b/sdk/storage/storage-blob/test/snippets.spec.ts @@ -12,6 +12,7 @@ import { SASProtocol, StorageSharedKeyCredential, } from "../src/index.js"; +import { buffer } from "node:stream/consumers"; import { describe, it } from "vitest"; describe("snippets", () => { @@ -376,22 +377,10 @@ describe("snippets", () => { // In Node.js, get downloaded data by accessing downloadBlockBlobResponse.readableStreamBody const downloadBlockBlobResponse = await blobClient.download(); if (downloadBlockBlobResponse.readableStreamBody) { - const downloaded = await streamToString(downloadBlockBlobResponse.readableStreamBody); - console.log(`Downloaded blob content: ${downloaded}`); - } - // @ts-preserve-whitespace - async function streamToString(stream: NodeJS.ReadableStream): Promise { - const result = await new Promise>((resolve, reject) => { - const chunks: Buffer[] = []; - stream.on("data", (data) => { - chunks.push(Buffer.isBuffer(data) ? data : Buffer.from(data)); - }); - stream.on("end", () => { - resolve(Buffer.concat(chunks)); - }); - stream.on("error", reject); - }); - return result.toString(); + // Download the raw bytes of the blob. Use `text` from "node:stream/consumers" + // instead if you want to read the content as a string directly. + const downloaded = await buffer(downloadBlockBlobResponse.readableStreamBody); + console.log(`Downloaded blob content: ${downloaded.toString()}`); } }); @@ -714,22 +703,10 @@ describe("snippets", () => { // Query and convert a blob to a string const queryBlockBlobResponse = await blockBlobClient.query("select from BlobStorage"); if (queryBlockBlobResponse.readableStreamBody) { - const downloadedBuffer = await streamToBuffer(queryBlockBlobResponse.readableStreamBody); - const downloaded = downloadedBuffer.toString(); - console.log(`Query blob content: ${downloaded}`); - } - // @ts-preserve-whitespace - async function streamToBuffer(readableStream: NodeJS.ReadableStream): Promise { - return new Promise((resolve, reject) => { - const chunks: Buffer[] = []; - readableStream.on("data", (data) => { - chunks.push(data instanceof Buffer ? data : Buffer.from(data)); - }); - readableStream.on("end", () => { - resolve(Buffer.concat(chunks)); - }); - readableStream.on("error", reject); - }); + // Read the response bytes. Use `text` from "node:stream/consumers" instead + // if you want the response as a string directly. + const downloadedBuffer = await buffer(queryBlockBlobResponse.readableStreamBody); + console.log(`Query blob content: ${downloadedBuffer.toString()}`); } }); diff --git a/sdk/storage/storage-file-datalake/README.md b/sdk/storage/storage-file-datalake/README.md index 202272e6e101..22d9866fae85 100644 --- a/sdk/storage/storage-file-datalake/README.md +++ b/sdk/storage/storage-file-datalake/README.md @@ -423,6 +423,7 @@ for await (const path of paths) { ```ts snippet:ReadmeSampleDownloadFile_Node import { DataLakeServiceClient } from "@azure/storage-file-datalake"; import { DefaultAzureCredential } from "@azure/identity"; +import { buffer } from "node:stream/consumers"; const account = ""; const datalakeServiceClient = new DataLakeServiceClient( @@ -439,23 +440,11 @@ const fileClient = fileSystemClient.getFileClient(fileName); // In Node.js, get downloaded data by accessing downloadResponse.readableStreamBody const downloadResponse = await fileClient.read(); if (downloadResponse.readableStreamBody) { - const downloaded = await streamToBuffer(downloadResponse.readableStreamBody); + // Download the raw bytes of the file. Use `text` from "node:stream/consumers" + // instead if you want to read the content as a string directly. + const downloaded = await buffer(downloadResponse.readableStreamBody); console.log("Downloaded file content:", downloaded.toString()); } - -// [Node.js only] A helper method used to read a Node.js readable stream into a Buffer. -async function streamToBuffer(readableStream: NodeJS.ReadableStream): Promise { - return new Promise((resolve, reject) => { - const chunks: Buffer[] = []; - readableStream.on("data", (data) => { - chunks.push(data instanceof Buffer ? data : Buffer.from(data)); - }); - readableStream.on("end", () => { - resolve(Buffer.concat(chunks)); - }); - readableStream.on("error", reject); - }); -} ``` ### Download a file and convert it to a string (Browsers) diff --git a/sdk/storage/storage-file-datalake/samples-dev/dataLakeServiceClient.ts b/sdk/storage/storage-file-datalake/samples-dev/dataLakeServiceClient.ts index 6aced46e096d..81b7ddb27896 100644 --- a/sdk/storage/storage-file-datalake/samples-dev/dataLakeServiceClient.ts +++ b/sdk/storage/storage-file-datalake/samples-dev/dataLakeServiceClient.ts @@ -7,6 +7,10 @@ import { DataLakeServiceClient, StorageSharedKeyCredential } from "@azure/storage-file-datalake"; +import { buffer } from "node:stream/consumers"; +// Use `text` from "node:stream/consumers" if you want the content as a string directly. +// import { text } from "node:stream/consumers"; + // Load the .env file if it exists import "dotenv/config"; @@ -83,9 +87,11 @@ export async function main(): Promise { throw new Error("Expected a readable stream body, but none was returned."); } - const readFileContent = (await streamToBuffer(readFileResponse.readableStreamBody)).toString(); + // Download the raw bytes of the file. Use `text(...)` from "node:stream/consumers" + // instead if you want to read the content as a string directly. + const readFileContent = await buffer(readFileResponse.readableStreamBody); - console.log(`Downloaded file content: ${readFileContent}`); + console.log(`Downloaded file content: ${readFileContent.toString()}`); // Finally, delete the example file system. await fileSystemClient.delete(); @@ -93,20 +99,6 @@ export async function main(): Promise { console.log(`Deleted file system ${fileSystemClient.name}.`); } -// A helper method used to read a Node.js readable stream into a Buffer -async function streamToBuffer(readableStream: NodeJS.ReadableStream): Promise { - return new Promise((resolve, reject) => { - const chunks: Buffer[] = []; - readableStream.on("data", (data: Buffer | string) => { - chunks.push(typeof data === "string" ? Buffer.from(data) : data); - }); - readableStream.on("end", () => { - resolve(Buffer.concat(chunks)); - }); - readableStream.on("error", reject); - }); -} - main().catch((error) => { console.error(error); process.exit(1); diff --git a/sdk/storage/storage-file-datalake/samples/v12/javascript/README.md b/sdk/storage/storage-file-datalake/samples/v12/javascript/README.md index d60da30a6b8b..619b30f880d2 100644 --- a/sdk/storage/storage-file-datalake/samples/v12/javascript/README.md +++ b/sdk/storage/storage-file-datalake/samples/v12/javascript/README.md @@ -46,10 +46,10 @@ npm install node dataLakeServiceClient.js ``` -Alternatively, run a single sample with the correct environment variables set (setting up the `.env` file is not required if you do this), for example (cross-platform): +Alternatively, run a single sample with the required environment variables set (setting up the `.env` file is not required if you do this), for example (cross-platform): ```bash -cross-env ACCOUNT_NAME="" ACCOUNT_KEY="" node dataLakeServiceClient.js +npx cross-env ACCOUNT_NAME="" ACCOUNT_KEY="" node dataLakeServiceClient.js ``` ## Next Steps diff --git a/sdk/storage/storage-file-datalake/samples/v12/javascript/dataLakeServiceClient.js b/sdk/storage/storage-file-datalake/samples/v12/javascript/dataLakeServiceClient.js index 1fa5ac17d189..39061ee51a58 100644 --- a/sdk/storage/storage-file-datalake/samples/v12/javascript/dataLakeServiceClient.js +++ b/sdk/storage/storage-file-datalake/samples/v12/javascript/dataLakeServiceClient.js @@ -10,8 +10,12 @@ const { StorageSharedKeyCredential, } = require("@azure/storage-file-datalake"); +const { buffer } = require("node:stream/consumers"); +// Use `text` from "node:stream/consumers" if you want the content as a string directly. +// import { text } from "node:stream/consumers"; + // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Enter your storage account name and shared key @@ -19,7 +23,7 @@ async function main() { const accountKey = process.env.ACCOUNT_KEY || ""; // Use StorageSharedKeyCredential with storage account and account key - // StorageSharedKeyCredential is only avaiable in Node.js runtime, not in browsers + // StorageSharedKeyCredential is only available in Node.js runtime, not in browsers const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey); // ONLY AVAILABLE IN NODE.JS RUNTIME @@ -46,7 +50,7 @@ async function main() { const serviceClient = new DataLakeServiceClient( // When using AnonymousCredential, following url should include a valid SAS or support public access `https://${account}.dfs.core.windows.net`, - sharedKeyCredential + sharedKeyCredential, ); console.log("File Systems:"); @@ -60,7 +64,7 @@ async function main() { const fileSystemResponse = await fileSystemClient.create(); console.log( - `Created file system ${fileSystemClient.name} successfully, request ID: ${fileSystemResponse.requestId}` + `Created file system ${fileSystemClient.name} successfully, request ID: ${fileSystemResponse.requestId}`, ); // Create a file @@ -86,9 +90,11 @@ async function main() { throw new Error("Expected a readable stream body, but none was returned."); } - const readFileContent = (await streamToBuffer(readFileResponse.readableStreamBody)).toString(); + // Download the raw bytes of the file. Use `text(...)` from "node:stream/consumers" + // instead if you want to read the content as a string directly. + const readFileContent = await buffer(readFileResponse.readableStreamBody); - console.log(`Downloaded file content: ${readFileContent}`); + console.log(`Downloaded file content: ${readFileContent.toString()}`); // Finally, delete the example file system. await fileSystemClient.delete(); @@ -96,20 +102,6 @@ async function main() { console.log(`Deleted file system ${fileSystemClient.name}.`); } -// A helper method used to read a Node.js readable stream into a Buffer -async function streamToBuffer(readableStream) { - return new Promise((resolve, reject) => { - const chunks = []; - readableStream.on("data", (data) => { - chunks.push(Buffer.isBuffer(data) ? data : Buffer.from(data)); - }); - readableStream.on("end", () => { - resolve(Buffer.concat(chunks)); - }); - readableStream.on("error", reject); - }); -} - main().catch((error) => { console.error(error); process.exit(1); diff --git a/sdk/storage/storage-file-datalake/samples/v12/javascript/package.json b/sdk/storage/storage-file-datalake/samples/v12/javascript/package.json index 751ecb4654fe..f7b7146d04d8 100644 --- a/sdk/storage/storage-file-datalake/samples/v12/javascript/package.json +++ b/sdk/storage/storage-file-datalake/samples/v12/javascript/package.json @@ -32,5 +32,8 @@ "dependencies": { "@azure/storage-file-datalake": "latest", "dotenv": "latest" + }, + "devDependencies": { + "cross-env": "latest" } } diff --git a/sdk/storage/storage-file-datalake/samples/v12/typescript/README.md b/sdk/storage/storage-file-datalake/samples/v12/typescript/README.md index 151947ddd8bb..8680121a598c 100644 --- a/sdk/storage/storage-file-datalake/samples/v12/typescript/README.md +++ b/sdk/storage/storage-file-datalake/samples/v12/typescript/README.md @@ -58,10 +58,10 @@ npm run build node dist/dataLakeServiceClient.js ``` -Alternatively, run a single sample with the correct environment variables set (setting up the `.env` file is not required if you do this), for example (cross-platform): +Alternatively, run a single sample with the required environment variables set (setting up the `.env` file is not required if you do this), for example (cross-platform): ```bash -cross-env ACCOUNT_NAME="" ACCOUNT_KEY="" node dist/dataLakeServiceClient.js +npx cross-env ACCOUNT_NAME="" ACCOUNT_KEY="" node dist/dataLakeServiceClient.js ``` ## Next Steps diff --git a/sdk/storage/storage-file-datalake/samples/v12/typescript/package.json b/sdk/storage/storage-file-datalake/samples/v12/typescript/package.json index a89b17892515..05989c9c16ce 100644 --- a/sdk/storage/storage-file-datalake/samples/v12/typescript/package.json +++ b/sdk/storage/storage-file-datalake/samples/v12/typescript/package.json @@ -39,7 +39,8 @@ }, "devDependencies": { "@types/node": "^20.0.0", - "typescript": "~5.8.2", - "rimraf": "latest" + "cross-env": "latest", + "rimraf": "latest", + "typescript": "~6.0.2" } } diff --git a/sdk/storage/storage-file-datalake/samples/v12/typescript/src/dataLakeServiceClient.ts b/sdk/storage/storage-file-datalake/samples/v12/typescript/src/dataLakeServiceClient.ts index ffb2867a9c37..81b7ddb27896 100644 --- a/sdk/storage/storage-file-datalake/samples/v12/typescript/src/dataLakeServiceClient.ts +++ b/sdk/storage/storage-file-datalake/samples/v12/typescript/src/dataLakeServiceClient.ts @@ -7,6 +7,10 @@ import { DataLakeServiceClient, StorageSharedKeyCredential } from "@azure/storage-file-datalake"; +import { buffer } from "node:stream/consumers"; +// Use `text` from "node:stream/consumers" if you want the content as a string directly. +// import { text } from "node:stream/consumers"; + // Load the .env file if it exists import "dotenv/config"; @@ -16,7 +20,7 @@ export async function main(): Promise { const accountKey = process.env.ACCOUNT_KEY || ""; // Use StorageSharedKeyCredential with storage account and account key - // StorageSharedKeyCredential is only avaiable in Node.js runtime, not in browsers + // StorageSharedKeyCredential is only available in Node.js runtime, not in browsers const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey); // ONLY AVAILABLE IN NODE.JS RUNTIME @@ -43,7 +47,7 @@ export async function main(): Promise { const serviceClient = new DataLakeServiceClient( // When using AnonymousCredential, following url should include a valid SAS or support public access `https://${account}.dfs.core.windows.net`, - sharedKeyCredential + sharedKeyCredential, ); console.log("File Systems:"); @@ -57,7 +61,7 @@ export async function main(): Promise { const fileSystemResponse = await fileSystemClient.create(); console.log( - `Created file system ${fileSystemClient.name} successfully, request ID: ${fileSystemResponse.requestId}` + `Created file system ${fileSystemClient.name} successfully, request ID: ${fileSystemResponse.requestId}`, ); // Create a file @@ -83,9 +87,11 @@ export async function main(): Promise { throw new Error("Expected a readable stream body, but none was returned."); } - const readFileContent = (await streamToBuffer(readFileResponse.readableStreamBody)).toString(); + // Download the raw bytes of the file. Use `text(...)` from "node:stream/consumers" + // instead if you want to read the content as a string directly. + const readFileContent = await buffer(readFileResponse.readableStreamBody); - console.log(`Downloaded file content: ${readFileContent}`); + console.log(`Downloaded file content: ${readFileContent.toString()}`); // Finally, delete the example file system. await fileSystemClient.delete(); @@ -93,20 +99,6 @@ export async function main(): Promise { console.log(`Deleted file system ${fileSystemClient.name}.`); } -// A helper method used to read a Node.js readable stream into a Buffer -async function streamToBuffer(readableStream: NodeJS.ReadableStream): Promise { - return new Promise((resolve, reject) => { - const chunks: Buffer[] = []; - readableStream.on("data", (data: Buffer | string) => { - chunks.push(typeof data === "string" ? Buffer.from(data) : data); - }); - readableStream.on("end", () => { - resolve(Buffer.concat(chunks)); - }); - readableStream.on("error", reject); - }); -} - main().catch((error) => { console.error(error); process.exit(1); diff --git a/sdk/storage/storage-file-datalake/samples/v12/typescript/tsconfig.json b/sdk/storage/storage-file-datalake/samples/v12/typescript/tsconfig.json index ad5ff9a19d36..4f7c3f6e72dc 100644 --- a/sdk/storage/storage-file-datalake/samples/v12/typescript/tsconfig.json +++ b/sdk/storage/storage-file-datalake/samples/v12/typescript/tsconfig.json @@ -1,17 +1,24 @@ { "compilerOptions": { - "target": "ES2018", - "module": "commonjs", - "moduleResolution": "node", + "target": "ES2023", + "module": "nodenext", + "lib": [ + "ESNext" + ], + "importHelpers": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "types": [ + "node" + ], + "outDir": "./dist", + "rootDir": "./src", "resolveJsonModule": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "alwaysStrict": true, - "outDir": "dist", - "rootDir": "src" + "moduleResolution": "nodenext" }, "include": [ - "src/**/*.ts" + "./src" ] } diff --git a/sdk/storage/storage-file-datalake/src/clients.ts b/sdk/storage/storage-file-datalake/src/clients.ts index c58caebbd0b1..79af40292b20 100644 --- a/sdk/storage/storage-file-datalake/src/clients.ts +++ b/sdk/storage/storage-file-datalake/src/clients.ts @@ -1291,6 +1291,7 @@ export class DataLakeFileClient extends DataLakePathClient { * ```ts snippet:ReadmeSampleDownloadFile_Node * import { DataLakeServiceClient } from "@azure/storage-file-datalake"; * import { DefaultAzureCredential } from "@azure/identity"; + * import { buffer } from "node:stream/consumers"; * * const account = ""; * const datalakeServiceClient = new DataLakeServiceClient( @@ -1307,23 +1308,11 @@ export class DataLakeFileClient extends DataLakePathClient { * // In Node.js, get downloaded data by accessing downloadResponse.readableStreamBody * const downloadResponse = await fileClient.read(); * if (downloadResponse.readableStreamBody) { - * const downloaded = await streamToBuffer(downloadResponse.readableStreamBody); + * // Download the raw bytes of the file. Use `text` from "node:stream/consumers" + * // instead if you want to read the content as a string directly. + * const downloaded = await buffer(downloadResponse.readableStreamBody); * console.log("Downloaded file content:", downloaded.toString()); * } - * - * // [Node.js only] A helper method used to read a Node.js readable stream into a Buffer. - * async function streamToBuffer(readableStream: NodeJS.ReadableStream): Promise { - * return new Promise((resolve, reject) => { - * const chunks: Buffer[] = []; - * readableStream.on("data", (data) => { - * chunks.push(data instanceof Buffer ? data : Buffer.from(data)); - * }); - * readableStream.on("end", () => { - * resolve(Buffer.concat(chunks)); - * }); - * readableStream.on("error", reject); - * }); - * } * ``` * * Example usage (browser): @@ -1903,6 +1892,7 @@ export class DataLakeFileClient extends DataLakePathClient { * * ```ts snippet:ReadmeSampleQueryFile_Node * import { DataLakeServiceClient } from "@azure/storage-file-datalake"; + * import { buffer } from "node:stream/consumers"; * * const account = ""; * const sas = ""; @@ -1918,22 +1908,10 @@ export class DataLakeFileClient extends DataLakePathClient { * // Query and convert a file to a string * const queryResponse = await fileClient.query("select * from BlobStorage"); * if (queryResponse.readableStreamBody) { - * const responseBuffer = await streamToBuffer(queryResponse.readableStreamBody); - * const downloaded = responseBuffer.toString(); - * console.log(`Query file content: ${downloaded}`); - * } - * - * async function streamToBuffer(readableStream: NodeJS.ReadableStream): Promise { - * return new Promise((resolve, reject) => { - * const chunks: Buffer[] = []; - * readableStream.on("data", (data) => { - * chunks.push(data instanceof Buffer ? data : Buffer.from(data)); - * }); - * readableStream.on("end", () => { - * resolve(Buffer.concat(chunks)); - * }); - * readableStream.on("error", reject); - * }); + * // Read the response bytes. Use `text` from "node:stream/consumers" instead + * // if you want the response as a string directly. + * const responseBuffer = await buffer(queryResponse.readableStreamBody); + * console.log(`Query file content: ${responseBuffer.toString()}`); * } * ``` * diff --git a/sdk/storage/storage-file-datalake/test/snippets.spec.ts b/sdk/storage/storage-file-datalake/test/snippets.spec.ts index 1d9befc287f8..29c854d5c9bc 100644 --- a/sdk/storage/storage-file-datalake/test/snippets.spec.ts +++ b/sdk/storage/storage-file-datalake/test/snippets.spec.ts @@ -10,6 +10,7 @@ import { SASProtocol, StorageSharedKeyCredential, } from "../src/index.js"; +import { buffer } from "node:stream/consumers"; import { describe, it } from "vitest"; describe("snippets", () => { @@ -383,23 +384,11 @@ describe("snippets", () => { // In Node.js, get downloaded data by accessing downloadResponse.readableStreamBody const downloadResponse = await fileClient.read(); if (downloadResponse.readableStreamBody) { - const downloaded = await streamToBuffer(downloadResponse.readableStreamBody); + // Download the raw bytes of the file. Use `text` from "node:stream/consumers" + // instead if you want to read the content as a string directly. + const downloaded = await buffer(downloadResponse.readableStreamBody); console.log("Downloaded file content:", downloaded.toString()); } - // @ts-preserve-whitespace - // [Node.js only] A helper method used to read a Node.js readable stream into a Buffer. - async function streamToBuffer(readableStream: NodeJS.ReadableStream): Promise { - return new Promise((resolve, reject) => { - const chunks: Buffer[] = []; - readableStream.on("data", (data) => { - chunks.push(data instanceof Buffer ? data : Buffer.from(data)); - }); - readableStream.on("end", () => { - resolve(Buffer.concat(chunks)); - }); - readableStream.on("error", reject); - }); - } }); it("ReadmeSampleDownloadFile_Browser", async () => { @@ -439,22 +428,10 @@ describe("snippets", () => { // Query and convert a file to a string const queryResponse = await fileClient.query("select * from BlobStorage"); if (queryResponse.readableStreamBody) { - const responseBuffer = await streamToBuffer(queryResponse.readableStreamBody); - const downloaded = responseBuffer.toString(); - console.log(`Query file content: ${downloaded}`); - } - // @ts-preserve-whitespace - async function streamToBuffer(readableStream: NodeJS.ReadableStream): Promise { - return new Promise((resolve, reject) => { - const chunks: Buffer[] = []; - readableStream.on("data", (data) => { - chunks.push(data instanceof Buffer ? data : Buffer.from(data)); - }); - readableStream.on("end", () => { - resolve(Buffer.concat(chunks)); - }); - readableStream.on("error", reject); - }); + // Read the response bytes. Use `text` from "node:stream/consumers" instead + // if you want the response as a string directly. + const responseBuffer = await buffer(queryResponse.readableStreamBody); + console.log(`Query file content: ${responseBuffer.toString()}`); } }); diff --git a/sdk/storage/storage-file-share/README.md b/sdk/storage/storage-file-share/README.md index b9d4bbc3b464..b8fe157305bf 100644 --- a/sdk/storage/storage-file-share/README.md +++ b/sdk/storage/storage-file-share/README.md @@ -366,6 +366,7 @@ For a complete sample on iterating please see [samples/v12/typescript/src/listFi ```ts snippet:ReadmeSampleDownloadFileAndConvertToString_Node import { StorageSharedKeyCredential, ShareServiceClient } from "@azure/storage-file-share"; +import { buffer } from "node:stream/consumers"; const account = ""; const accountKey = ""; @@ -386,22 +387,10 @@ const fileClient = serviceClient // In Node.js, get downloaded data by accessing downloadFileResponse.readableStreamBody const downloadFileResponse = await fileClient.download(); if (downloadFileResponse.readableStreamBody) { - const buffer = await streamToBuffer(downloadFileResponse.readableStreamBody); - console.log(`Downloaded file content: ${buffer.toString()}`); -} - -// [Node.js only] A helper method used to read a Node.js readable stream into a Buffer -async function streamToBuffer(readableStream: NodeJS.ReadableStream): Promise { - return new Promise((resolve, reject) => { - const chunks: Buffer[] = []; - readableStream.on("data", (data) => { - chunks.push(data instanceof Buffer ? data : Buffer.from(data)); - }); - readableStream.on("end", () => { - resolve(Buffer.concat(chunks)); - }); - readableStream.on("error", reject); - }); + // Download the raw bytes of the file. Use `text` from "node:stream/consumers" + // instead if you want to read the content as a string directly. + const downloaded = await buffer(downloadFileResponse.readableStreamBody); + console.log(`Downloaded file content: ${downloaded.toString()}`); } ``` diff --git a/sdk/storage/storage-file-share/samples-dev/shareServiceClient.ts b/sdk/storage/storage-file-share/samples-dev/shareServiceClient.ts index 5561ea41d906..e1bbcc199b13 100644 --- a/sdk/storage/storage-file-share/samples-dev/shareServiceClient.ts +++ b/sdk/storage/storage-file-share/samples-dev/shareServiceClient.ts @@ -8,6 +8,10 @@ import { ShareServiceClient, StorageSharedKeyCredential } from "@azure/storage-file-share"; +import { buffer } from "node:stream/consumers"; +// Use `text` from "node:stream/consumers" if you want the content as a string directly. +// import { text } from "node:stream/consumers"; + // Load the .env file if it exists import "dotenv/config"; @@ -75,31 +79,17 @@ export async function main(): Promise { throw new Error("Expected a readable stream, but none was returned."); } - const downloadedContent = ( - await streamToBuffer(downloadFileResponse.readableStreamBody) - ).toString(); + // Download the raw bytes of the file. Use `text(...)` from "node:stream/consumers" + // instead if you want to read the content as a string directly. + const downloadedContent = await buffer(downloadFileResponse.readableStreamBody); - console.log(`Downloaded file content: ${downloadedContent}`); + console.log(`Downloaded file content: ${downloadedContent.toString()}`); // Finally, delete the example share await shareClient.delete(); console.log(`Deleted share ${shareClient.name}`); } -// A helper method used to read a Node.js readable stream into a Buffer -async function streamToBuffer(readableStream: NodeJS.ReadableStream): Promise { - return new Promise((resolve, reject) => { - const chunks: Buffer[] = []; - readableStream.on("data", (data: Buffer | string) => { - chunks.push(typeof data === "string" ? Buffer.from(data) : data); - }); - readableStream.on("end", () => { - resolve(Buffer.concat(chunks)); - }); - readableStream.on("error", reject); - }); -} - main().catch((error) => { console.error(error); process.exit(1); diff --git a/sdk/storage/storage-file-share/samples/v12/javascript/README.md b/sdk/storage/storage-file-share/samples/v12/javascript/README.md index 690a550e1d11..fe0f8dbde617 100644 --- a/sdk/storage/storage-file-share/samples/v12/javascript/README.md +++ b/sdk/storage/storage-file-share/samples/v12/javascript/README.md @@ -55,10 +55,10 @@ npm install node sharedKeyAuth.js ``` -Alternatively, run a single sample with the correct environment variables set (setting up the `.env` file is not required if you do this), for example (cross-platform): +Alternatively, run a single sample with the required environment variables set (setting up the `.env` file is not required if you do this), for example (cross-platform): ```bash -cross-env ACCOUNT_NAME="" ACCOUNT_KEY="" node sharedKeyAuth.js +npx cross-env ACCOUNT_NAME="" ACCOUNT_KEY="" node sharedKeyAuth.js ``` ## Next Steps diff --git a/sdk/storage/storage-file-share/samples/v12/javascript/advancedRequestOptions.js b/sdk/storage/storage-file-share/samples/v12/javascript/advancedRequestOptions.js index 820c83ec9d0e..4d2bc17ab47e 100644 --- a/sdk/storage/storage-file-share/samples/v12/javascript/advancedRequestOptions.js +++ b/sdk/storage/storage-file-share/samples/v12/javascript/advancedRequestOptions.js @@ -5,9 +5,7 @@ * @summary use advanced HTTP pipeline and request options for several methods */ -const fs = require("fs"); - -const { AbortController } = require("@azure/abort-controller"); +const fs = require("node:fs"); const { AnonymousCredential, ShareServiceClient, @@ -15,7 +13,7 @@ const { } = require("@azure/storage-file-share"); // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Fill in following settings before running this sample @@ -25,8 +23,8 @@ async function main() { const pipeline = newPipeline(new AnonymousCredential(), { // httpClient: MyHTTPClient, // A customized HTTP client implementing IHttpClient interface - retryOptions: { maxTries: 4 }, - userAgentOptions: { userAgentPrefix: "AdvancedSample V1.0.0" }, + retryOptions: { maxTries: 4 }, // Retry options + userAgentOptions: { userAgentPrefix: "AdvancedSample V1.0.0" }, // Customized user-agent string keepAliveOptions: { // Keep alive is enabled by default, disable keep alive by setting false enable: false, @@ -34,8 +32,8 @@ async function main() { }); const serviceClient = new ShareServiceClient( - `https://${account}.file.core.windows.net?${accountSas}`, - pipeline + `https://${account}.file.core.windows.net${accountSas}`, + pipeline, ); // Create a share @@ -58,8 +56,8 @@ async function main() { // Parallel uploading with ShareFileClient.uploadFile() in Node.js runtime // ShareFileClient.uploadFile() is only available in Node.js await fileClient.uploadFile(localFilePath, { - rangeSize: 4 * 1024 * 1024, - concurrency: 20, + rangeSize: 4 * 1024 * 1024, // 4MB range size + concurrency: 20, // 20 concurrency onProgress: (ev) => console.log(ev), }); console.log("uploadFile succeeded"); @@ -67,7 +65,7 @@ async function main() { // Parallel uploading a Readable stream with ShareFileClient.uploadStream() in Node.js runtime // ShareFileClient.uploadStream() is only available in Node.js await fileClient.uploadStream(fs.createReadStream(localFilePath), fileSize, 4 * 1024 * 1024, 20, { - abortSignal: AbortSignal.timeout(30 * 60 * 1000), + abortSignal: AbortSignal.timeout(30 * 60 * 1000), // Abort uploading with timeout in 30mins onProgress: (ev) => console.log(ev), }); console.log("uploadStream succeeded"); @@ -88,8 +86,8 @@ async function main() { const buffer = Buffer.alloc(fileSize); await fileClient.downloadToBuffer(buffer, undefined, undefined, { abortSignal: AbortSignal.timeout(30 * 60 * 1000), - rangeSize: 4 * 1024 * 1024, - concurrency: 20, + rangeSize: 4 * 1024 * 1024, // 4MB range size + concurrency: 20, // 20 concurrency onProgress: (ev) => console.log(ev), }); console.log("downloadToBuffer succeeded"); diff --git a/sdk/storage/storage-file-share/samples/v12/javascript/anonymousAuth.js b/sdk/storage/storage-file-share/samples/v12/javascript/anonymousAuth.js index 017ca9b43a11..12534cd81002 100644 --- a/sdk/storage/storage-file-share/samples/v12/javascript/anonymousAuth.js +++ b/sdk/storage/storage-file-share/samples/v12/javascript/anonymousAuth.js @@ -8,7 +8,7 @@ const { ShareServiceClient, AnonymousCredential } = require("@azure/storage-file-share"); // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Enter your storage account name and SAS @@ -21,8 +21,8 @@ async function main() { // List shares const serviceClient = new ShareServiceClient( // When using AnonymousCredential, following url should include a valid SAS - `https://${account}.file.core.windows.net?${accountSas}`, - anonymousCredential + `https://${account}.file.core.windows.net${accountSas}`, + anonymousCredential, ); console.log("Shares:"); diff --git a/sdk/storage/storage-file-share/samples/v12/javascript/connectionStringAuth.js b/sdk/storage/storage-file-share/samples/v12/javascript/connectionStringAuth.js index 7cbf821bbe18..baeba65a772c 100644 --- a/sdk/storage/storage-file-share/samples/v12/javascript/connectionStringAuth.js +++ b/sdk/storage/storage-file-share/samples/v12/javascript/connectionStringAuth.js @@ -8,7 +8,7 @@ const { ShareServiceClient } = require("@azure/storage-file-share"); // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Create File Service Client from Account connection string or SAS connection string diff --git a/sdk/storage/storage-file-share/samples/v12/javascript/customPipeline.js b/sdk/storage/storage-file-share/samples/v12/javascript/customPipeline.js index f1e1443ff3a6..7c5831bc4e32 100644 --- a/sdk/storage/storage-file-share/samples/v12/javascript/customPipeline.js +++ b/sdk/storage/storage-file-share/samples/v12/javascript/customPipeline.js @@ -12,7 +12,7 @@ const { } = require("@azure/storage-file-share"); // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Enter your storage account name and shared key @@ -26,14 +26,14 @@ async function main() { // Use sharedKeyCredential or anonymousCredential to create a pipeline const pipeline = newPipeline(sharedKeyCredential, { // httpClient: MyHTTPClient, // A customized HTTP client implementing IHttpClient interface - retryOptions: { maxTries: 4 }, + retryOptions: { maxTries: 4 }, // Retry options userAgentOptions: { userAgentPrefix: "AdvancedSample V1.0.0" }, // Customized telemetry string }); // List shares const serviceClient = new ShareServiceClient( `https://${account}.file.core.windows.net`, - pipeline + pipeline, ); console.log("Shares:"); diff --git a/sdk/storage/storage-file-share/samples/v12/javascript/listFilesAndDirectories.js b/sdk/storage/storage-file-share/samples/v12/javascript/listFilesAndDirectories.js index 0b081af67a58..bd86c6e13914 100644 --- a/sdk/storage/storage-file-share/samples/v12/javascript/listFilesAndDirectories.js +++ b/sdk/storage/storage-file-share/samples/v12/javascript/listFilesAndDirectories.js @@ -8,7 +8,7 @@ const { ShareServiceClient, StorageSharedKeyCredential } = require("@azure/storage-file-share"); // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Enter your storage account name and shared key @@ -22,7 +22,7 @@ async function main() { const serviceClient = new ShareServiceClient( // When using AnonymousCredential, following url should include a valid SAS `https://${account}.file.core.windows.net`, - sharedKeyCredential + sharedKeyCredential, ); // Create a share diff --git a/sdk/storage/storage-file-share/samples/v12/javascript/listHandles.js b/sdk/storage/storage-file-share/samples/v12/javascript/listHandles.js index 6fd33b0ac1bd..02347f08332b 100644 --- a/sdk/storage/storage-file-share/samples/v12/javascript/listHandles.js +++ b/sdk/storage/storage-file-share/samples/v12/javascript/listHandles.js @@ -8,7 +8,7 @@ const { ShareServiceClient, StorageSharedKeyCredential } = require("@azure/storage-file-share"); // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Enter your storage account name, shared key, share name, and directory name. @@ -23,7 +23,7 @@ async function main() { if (shareName === "" || dirName === "") { console.warn( - "Share/directory information not provided, but it is required to run this sample. Exiting." + "Share/directory information not provided, but it is required to run this sample. Exiting.", ); return; } @@ -34,7 +34,7 @@ async function main() { const serviceClient = new ShareServiceClient( `https://${account}.file.core.windows.net`, - sharedKeyCredential + sharedKeyCredential, ); const shareClient = serviceClient.getShareClient(shareName); diff --git a/sdk/storage/storage-file-share/samples/v12/javascript/listShares.js b/sdk/storage/storage-file-share/samples/v12/javascript/listShares.js index 870b02f85dbc..a6cfae99f1dd 100644 --- a/sdk/storage/storage-file-share/samples/v12/javascript/listShares.js +++ b/sdk/storage/storage-file-share/samples/v12/javascript/listShares.js @@ -8,7 +8,7 @@ const { ShareServiceClient, StorageSharedKeyCredential } = require("@azure/storage-file-share"); // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Enter your storage account name and shared key @@ -21,7 +21,7 @@ async function main() { const serviceClient = new ShareServiceClient( `https://${account}.file.core.windows.net`, - sharedKeyCredential + sharedKeyCredential, ); console.log("Shares:"); diff --git a/sdk/storage/storage-file-share/samples/v12/javascript/package.json b/sdk/storage/storage-file-share/samples/v12/javascript/package.json index e561361eee3e..0de7379b80ce 100644 --- a/sdk/storage/storage-file-share/samples/v12/javascript/package.json +++ b/sdk/storage/storage-file-share/samples/v12/javascript/package.json @@ -29,7 +29,9 @@ "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/storage/storage-file-share", "dependencies": { "@azure/storage-file-share": "latest", - "dotenv": "latest", - "@azure/abort-controller": "^2.1.2" + "dotenv": "latest" + }, + "devDependencies": { + "cross-env": "latest" } } diff --git a/sdk/storage/storage-file-share/samples/v12/javascript/proxyAuth.js b/sdk/storage/storage-file-share/samples/v12/javascript/proxyAuth.js index 15d521f04673..4a47c38e7344 100644 --- a/sdk/storage/storage-file-share/samples/v12/javascript/proxyAuth.js +++ b/sdk/storage/storage-file-share/samples/v12/javascript/proxyAuth.js @@ -8,7 +8,7 @@ const { StorageSharedKeyCredential, ShareServiceClient } = require("@azure/storage-file-share"); // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Enter your storage account name and shared key @@ -40,7 +40,7 @@ async function main() { password: "" } */ - } + }, ); // Create a share diff --git a/sdk/storage/storage-file-share/samples/v12/javascript/shareServiceClient.js b/sdk/storage/storage-file-share/samples/v12/javascript/shareServiceClient.js index 7debecbced2a..3d4a7a5d76cd 100644 --- a/sdk/storage/storage-file-share/samples/v12/javascript/shareServiceClient.js +++ b/sdk/storage/storage-file-share/samples/v12/javascript/shareServiceClient.js @@ -7,8 +7,12 @@ const { ShareServiceClient, StorageSharedKeyCredential } = require("@azure/storage-file-share"); +const { buffer } = require("node:stream/consumers"); +// Use `text` from "node:stream/consumers" if you want the content as a string directly. +// import { text } from "node:stream/consumers"; + // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Enter your storage account name and shared key @@ -26,7 +30,7 @@ async function main() { const serviceClient = new ShareServiceClient( // When using AnonymousCredential, following url should include a valid SAS `https://${account}.file.core.windows.net`, - sharedKeyCredential + sharedKeyCredential, ); console.log("Shares:"); @@ -74,31 +78,17 @@ async function main() { throw new Error("Expected a readable stream, but none was returned."); } - const downloadedContent = ( - await streamToBuffer(downloadFileResponse.readableStreamBody) - ).toString(); + // Download the raw bytes of the file. Use `text(...)` from "node:stream/consumers" + // instead if you want to read the content as a string directly. + const downloadedContent = await buffer(downloadFileResponse.readableStreamBody); - console.log(`Downloaded file content: ${downloadedContent}`); + console.log(`Downloaded file content: ${downloadedContent.toString()}`); // Finally, delete the example share await shareClient.delete(); console.log(`Deleted share ${shareClient.name}`); } -// A helper method used to read a Node.js readable stream into a Buffer -async function streamToBuffer(readableStream) { - return new Promise((resolve, reject) => { - const chunks = []; - readableStream.on("data", (data) => { - chunks.push(Buffer.isBuffer(data) ? data : Buffer.from(data)); - }); - readableStream.on("end", () => { - resolve(Buffer.concat(chunks)); - }); - readableStream.on("error", reject); - }); -} - main().catch((error) => { console.error(error); process.exit(1); diff --git a/sdk/storage/storage-file-share/samples/v12/javascript/sharedKeyAuth.js b/sdk/storage/storage-file-share/samples/v12/javascript/sharedKeyAuth.js index 2d064502de5e..48a45dbd190e 100644 --- a/sdk/storage/storage-file-share/samples/v12/javascript/sharedKeyAuth.js +++ b/sdk/storage/storage-file-share/samples/v12/javascript/sharedKeyAuth.js @@ -8,7 +8,7 @@ const { ShareServiceClient, StorageSharedKeyCredential } = require("@azure/storage-file-share"); // Load the .env file if it exists -require("dotenv").config(); +require("dotenv/config"); async function main() { // Enter your storage account name and shared key @@ -22,7 +22,7 @@ async function main() { // List shares const serviceClient = new ShareServiceClient( `https://${account}.file.core.windows.net`, - sharedKeyCredential + sharedKeyCredential, ); console.log("Shares:"); diff --git a/sdk/storage/storage-file-share/samples/v12/typescript/README.md b/sdk/storage/storage-file-share/samples/v12/typescript/README.md index ee42100de5c2..b4b01e459dcc 100644 --- a/sdk/storage/storage-file-share/samples/v12/typescript/README.md +++ b/sdk/storage/storage-file-share/samples/v12/typescript/README.md @@ -67,10 +67,10 @@ npm run build node dist/sharedKeyAuth.js ``` -Alternatively, run a single sample with the correct environment variables set (setting up the `.env` file is not required if you do this), for example (cross-platform): +Alternatively, run a single sample with the required environment variables set (setting up the `.env` file is not required if you do this), for example (cross-platform): ```bash -cross-env ACCOUNT_NAME="" ACCOUNT_KEY="" node dist/sharedKeyAuth.js +npx cross-env ACCOUNT_NAME="" ACCOUNT_KEY="" node dist/sharedKeyAuth.js ``` ## Next Steps diff --git a/sdk/storage/storage-file-share/samples/v12/typescript/package.json b/sdk/storage/storage-file-share/samples/v12/typescript/package.json index 6705e823d14b..6c19250496eb 100644 --- a/sdk/storage/storage-file-share/samples/v12/typescript/package.json +++ b/sdk/storage/storage-file-share/samples/v12/typescript/package.json @@ -33,12 +33,12 @@ "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/storage/storage-file-share", "dependencies": { "@azure/storage-file-share": "latest", - "dotenv": "latest", - "@azure/abort-controller": "^2.1.2" + "dotenv": "latest" }, "devDependencies": { "@types/node": "^20.0.0", - "typescript": "~5.8.2", - "rimraf": "latest" + "cross-env": "latest", + "rimraf": "latest", + "typescript": "~6.0.2" } } diff --git a/sdk/storage/storage-file-share/samples/v12/typescript/src/advancedRequestOptions.ts b/sdk/storage/storage-file-share/samples/v12/typescript/src/advancedRequestOptions.ts index 796a5e728e47..4f629f0dca8b 100644 --- a/sdk/storage/storage-file-share/samples/v12/typescript/src/advancedRequestOptions.ts +++ b/sdk/storage/storage-file-share/samples/v12/typescript/src/advancedRequestOptions.ts @@ -6,7 +6,6 @@ */ import fs from "node:fs"; - import { AnonymousCredential, ShareServiceClient, newPipeline } from "@azure/storage-file-share"; // Load the .env file if it exists @@ -24,13 +23,13 @@ export async function main(): Promise { userAgentOptions: { userAgentPrefix: "AdvancedSample V1.0.0" }, // Customized user-agent string keepAliveOptions: { // Keep alive is enabled by default, disable keep alive by setting false - enable: false - } + enable: false, + }, }); const serviceClient = new ShareServiceClient( - `https://${account}.file.core.windows.net?${accountSas}`, - pipeline + `https://${account}.file.core.windows.net${accountSas}`, + pipeline, ); // Create a share @@ -55,7 +54,7 @@ export async function main(): Promise { await fileClient.uploadFile(localFilePath, { rangeSize: 4 * 1024 * 1024, // 4MB range size concurrency: 20, // 20 concurrency - onProgress: (ev) => console.log(ev) + onProgress: (ev) => console.log(ev), }); console.log("uploadFile succeeded"); @@ -63,7 +62,7 @@ export async function main(): Promise { // ShareFileClient.uploadStream() is only available in Node.js await fileClient.uploadStream(fs.createReadStream(localFilePath), fileSize, 4 * 1024 * 1024, 20, { abortSignal: AbortSignal.timeout(30 * 60 * 1000), // Abort uploading with timeout in 30mins - onProgress: (ev: any) => console.log(ev) + onProgress: (ev: any) => console.log(ev), }); console.log("uploadStream succeeded"); @@ -85,7 +84,7 @@ export async function main(): Promise { abortSignal: AbortSignal.timeout(30 * 60 * 1000), rangeSize: 4 * 1024 * 1024, // 4MB range size concurrency: 20, // 20 concurrency - onProgress: (ev) => console.log(ev) + onProgress: (ev) => console.log(ev), }); console.log("downloadToBuffer succeeded"); diff --git a/sdk/storage/storage-file-share/samples/v12/typescript/src/anonymousAuth.ts b/sdk/storage/storage-file-share/samples/v12/typescript/src/anonymousAuth.ts index 1f55518bb55b..06fc960ec745 100644 --- a/sdk/storage/storage-file-share/samples/v12/typescript/src/anonymousAuth.ts +++ b/sdk/storage/storage-file-share/samples/v12/typescript/src/anonymousAuth.ts @@ -21,8 +21,8 @@ export async function main(): Promise { // List shares const serviceClient = new ShareServiceClient( // When using AnonymousCredential, following url should include a valid SAS - `https://${account}.file.core.windows.net?${accountSas}`, - anonymousCredential + `https://${account}.file.core.windows.net${accountSas}`, + anonymousCredential, ); console.log("Shares:"); diff --git a/sdk/storage/storage-file-share/samples/v12/typescript/src/customPipeline.ts b/sdk/storage/storage-file-share/samples/v12/typescript/src/customPipeline.ts index f560eb9923ed..3c9ce5f1dab3 100644 --- a/sdk/storage/storage-file-share/samples/v12/typescript/src/customPipeline.ts +++ b/sdk/storage/storage-file-share/samples/v12/typescript/src/customPipeline.ts @@ -8,7 +8,7 @@ import { newPipeline, ShareServiceClient, - StorageSharedKeyCredential + StorageSharedKeyCredential, } from "@azure/storage-file-share"; // Load the .env file if it exists @@ -27,13 +27,13 @@ export async function main(): Promise { const pipeline = newPipeline(sharedKeyCredential, { // httpClient: MyHTTPClient, // A customized HTTP client implementing IHttpClient interface retryOptions: { maxTries: 4 }, // Retry options - userAgentOptions: { userAgentPrefix: "AdvancedSample V1.0.0" } // Customized telemetry string + userAgentOptions: { userAgentPrefix: "AdvancedSample V1.0.0" }, // Customized telemetry string }); // List shares const serviceClient = new ShareServiceClient( `https://${account}.file.core.windows.net`, - pipeline + pipeline, ); console.log("Shares:"); diff --git a/sdk/storage/storage-file-share/samples/v12/typescript/src/listFilesAndDirectories.ts b/sdk/storage/storage-file-share/samples/v12/typescript/src/listFilesAndDirectories.ts index 255d8b44f513..6a45b8fc2b0c 100644 --- a/sdk/storage/storage-file-share/samples/v12/typescript/src/listFilesAndDirectories.ts +++ b/sdk/storage/storage-file-share/samples/v12/typescript/src/listFilesAndDirectories.ts @@ -22,7 +22,7 @@ export async function main(): Promise { const serviceClient = new ShareServiceClient( // When using AnonymousCredential, following url should include a valid SAS `https://${account}.file.core.windows.net`, - sharedKeyCredential + sharedKeyCredential, ); // Create a share diff --git a/sdk/storage/storage-file-share/samples/v12/typescript/src/listHandles.ts b/sdk/storage/storage-file-share/samples/v12/typescript/src/listHandles.ts index a725d4a276c4..abdd9be67288 100644 --- a/sdk/storage/storage-file-share/samples/v12/typescript/src/listHandles.ts +++ b/sdk/storage/storage-file-share/samples/v12/typescript/src/listHandles.ts @@ -23,7 +23,7 @@ export async function main(): Promise { if (shareName === "" || dirName === "") { console.warn( - "Share/directory information not provided, but it is required to run this sample. Exiting." + "Share/directory information not provided, but it is required to run this sample. Exiting.", ); return; } @@ -34,7 +34,7 @@ export async function main(): Promise { const serviceClient = new ShareServiceClient( `https://${account}.file.core.windows.net`, - sharedKeyCredential + sharedKeyCredential, ); const shareClient = serviceClient.getShareClient(shareName); diff --git a/sdk/storage/storage-file-share/samples/v12/typescript/src/listShares.ts b/sdk/storage/storage-file-share/samples/v12/typescript/src/listShares.ts index 8c0397c7eaf7..13b244f533e3 100644 --- a/sdk/storage/storage-file-share/samples/v12/typescript/src/listShares.ts +++ b/sdk/storage/storage-file-share/samples/v12/typescript/src/listShares.ts @@ -21,7 +21,7 @@ export async function main(): Promise { const serviceClient = new ShareServiceClient( `https://${account}.file.core.windows.net`, - sharedKeyCredential + sharedKeyCredential, ); console.log("Shares:"); diff --git a/sdk/storage/storage-file-share/samples/v12/typescript/src/proxyAuth.ts b/sdk/storage/storage-file-share/samples/v12/typescript/src/proxyAuth.ts index cbee932f635e..024424aa8477 100644 --- a/sdk/storage/storage-file-share/samples/v12/typescript/src/proxyAuth.ts +++ b/sdk/storage/storage-file-share/samples/v12/typescript/src/proxyAuth.ts @@ -40,7 +40,7 @@ export async function main(): Promise { password: "" } */ - } + }, ); // Create a share diff --git a/sdk/storage/storage-file-share/samples/v12/typescript/src/shareServiceClient.ts b/sdk/storage/storage-file-share/samples/v12/typescript/src/shareServiceClient.ts index 42ec61df51bb..8c3282745ea6 100644 --- a/sdk/storage/storage-file-share/samples/v12/typescript/src/shareServiceClient.ts +++ b/sdk/storage/storage-file-share/samples/v12/typescript/src/shareServiceClient.ts @@ -7,6 +7,10 @@ import { ShareServiceClient, StorageSharedKeyCredential } from "@azure/storage-file-share"; +import { buffer } from "node:stream/consumers"; +// Use `text` from "node:stream/consumers" if you want the content as a string directly. +// import { text } from "node:stream/consumers"; + // Load the .env file if it exists import "dotenv/config"; @@ -26,7 +30,7 @@ export async function main(): Promise { const serviceClient = new ShareServiceClient( // When using AnonymousCredential, following url should include a valid SAS `https://${account}.file.core.windows.net`, - sharedKeyCredential + sharedKeyCredential, ); console.log("Shares:"); @@ -74,31 +78,17 @@ export async function main(): Promise { throw new Error("Expected a readable stream, but none was returned."); } - const downloadedContent = ( - await streamToBuffer(downloadFileResponse.readableStreamBody) - ).toString(); + // Download the raw bytes of the file. Use `text(...)` from "node:stream/consumers" + // instead if you want to read the content as a string directly. + const downloadedContent = await buffer(downloadFileResponse.readableStreamBody); - console.log(`Downloaded file content: ${downloadedContent}`); + console.log(`Downloaded file content: ${downloadedContent.toString()}`); // Finally, delete the example share await shareClient.delete(); console.log(`Deleted share ${shareClient.name}`); } -// A helper method used to read a Node.js readable stream into a Buffer -async function streamToBuffer(readableStream: NodeJS.ReadableStream): Promise { - return new Promise((resolve, reject) => { - const chunks: Buffer[] = []; - readableStream.on("data", (data: Buffer | string) => { - chunks.push(typeof data === "string" ? Buffer.from(data) : data); - }); - readableStream.on("end", () => { - resolve(Buffer.concat(chunks)); - }); - readableStream.on("error", reject); - }); -} - main().catch((error) => { console.error(error); process.exit(1); diff --git a/sdk/storage/storage-file-share/samples/v12/typescript/src/sharedKeyAuth.ts b/sdk/storage/storage-file-share/samples/v12/typescript/src/sharedKeyAuth.ts index eb234e765e6f..ef7dec392878 100644 --- a/sdk/storage/storage-file-share/samples/v12/typescript/src/sharedKeyAuth.ts +++ b/sdk/storage/storage-file-share/samples/v12/typescript/src/sharedKeyAuth.ts @@ -22,7 +22,7 @@ export async function main(): Promise { // List shares const serviceClient = new ShareServiceClient( `https://${account}.file.core.windows.net`, - sharedKeyCredential + sharedKeyCredential, ); console.log("Shares:"); diff --git a/sdk/storage/storage-file-share/samples/v12/typescript/tsconfig.json b/sdk/storage/storage-file-share/samples/v12/typescript/tsconfig.json index ad5ff9a19d36..4f7c3f6e72dc 100644 --- a/sdk/storage/storage-file-share/samples/v12/typescript/tsconfig.json +++ b/sdk/storage/storage-file-share/samples/v12/typescript/tsconfig.json @@ -1,17 +1,24 @@ { "compilerOptions": { - "target": "ES2018", - "module": "commonjs", - "moduleResolution": "node", + "target": "ES2023", + "module": "nodenext", + "lib": [ + "ESNext" + ], + "importHelpers": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "types": [ + "node" + ], + "outDir": "./dist", + "rootDir": "./src", "resolveJsonModule": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "alwaysStrict": true, - "outDir": "dist", - "rootDir": "src" + "moduleResolution": "nodenext" }, "include": [ - "src/**/*.ts" + "./src" ] } diff --git a/sdk/storage/storage-file-share/src/Clients.ts b/sdk/storage/storage-file-share/src/Clients.ts index 009b3cd934e8..5cc6d57681e9 100644 --- a/sdk/storage/storage-file-share/src/Clients.ts +++ b/sdk/storage/storage-file-share/src/Clients.ts @@ -4164,6 +4164,7 @@ export class ShareFileClient extends StorageClient { * * ```ts snippet:ReadmeSampleDownloadFileAndConvertToString_Node * import { StorageSharedKeyCredential, ShareServiceClient } from "@azure/storage-file-share"; + * import { buffer } from "node:stream/consumers"; * * const account = ""; * const accountKey = ""; @@ -4184,22 +4185,10 @@ export class ShareFileClient extends StorageClient { * // In Node.js, get downloaded data by accessing downloadFileResponse.readableStreamBody * const downloadFileResponse = await fileClient.download(); * if (downloadFileResponse.readableStreamBody) { - * const buffer = await streamToBuffer(downloadFileResponse.readableStreamBody); - * console.log(`Downloaded file content: ${buffer.toString()}`); - * } - * - * // [Node.js only] A helper method used to read a Node.js readable stream into a Buffer - * async function streamToBuffer(readableStream: NodeJS.ReadableStream): Promise { - * return new Promise((resolve, reject) => { - * const chunks: Buffer[] = []; - * readableStream.on("data", (data) => { - * chunks.push(data instanceof Buffer ? data : Buffer.from(data)); - * }); - * readableStream.on("end", () => { - * resolve(Buffer.concat(chunks)); - * }); - * readableStream.on("error", reject); - * }); + * // Download the raw bytes of the file. Use `text` from "node:stream/consumers" + * // instead if you want to read the content as a string directly. + * const downloaded = await buffer(downloadFileResponse.readableStreamBody); + * console.log(`Downloaded file content: ${downloaded.toString()}`); * } * ``` * diff --git a/sdk/storage/storage-file-share/test/snippets.spec.ts b/sdk/storage/storage-file-share/test/snippets.spec.ts index 25b0f9ffe87b..1e5c8179b62a 100644 --- a/sdk/storage/storage-file-share/test/snippets.spec.ts +++ b/sdk/storage/storage-file-share/test/snippets.spec.ts @@ -3,6 +3,7 @@ import { setLogLevel } from "@azure/logger"; import { ShareServiceClient, StorageSharedKeyCredential } from "../src/index.js"; +import { buffer } from "node:stream/consumers"; import { describe, it } from "vitest"; describe("snippets", () => { @@ -484,22 +485,10 @@ describe("snippets", () => { // In Node.js, get downloaded data by accessing downloadFileResponse.readableStreamBody const downloadFileResponse = await fileClient.download(); if (downloadFileResponse.readableStreamBody) { - const buffer = await streamToBuffer(downloadFileResponse.readableStreamBody); - console.log(`Downloaded file content: ${buffer.toString()}`); - } - // @ts-preserve-whitespace - // [Node.js only] A helper method used to read a Node.js readable stream into a Buffer - async function streamToBuffer(readableStream: NodeJS.ReadableStream): Promise { - return new Promise((resolve, reject) => { - const chunks: Buffer[] = []; - readableStream.on("data", (data) => { - chunks.push(data instanceof Buffer ? data : Buffer.from(data)); - }); - readableStream.on("end", () => { - resolve(Buffer.concat(chunks)); - }); - readableStream.on("error", reject); - }); + // Download the raw bytes of the file. Use `text` from "node:stream/consumers" + // instead if you want to read the content as a string directly. + const downloaded = await buffer(downloadFileResponse.readableStreamBody); + console.log(`Downloaded file content: ${downloaded.toString()}`); } });