UNPKG

@azure/storage-blob

Version:
1,268 lines • 55.1 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var ContainerClient_exports = {}; __export(ContainerClient_exports, { ContainerClient: () => ContainerClient }); module.exports = __toCommonJS(ContainerClient_exports); var import_core_rest_pipeline = require("@azure/core-rest-pipeline"); var import_core_util = require("@azure/core-util"); var import_core_auth = require("@azure/core-auth"); var import_storage_common = require("@azure/storage-common"); var import_Pipeline = require("./Pipeline.js"); var import_StorageClient = require("./StorageClient.js"); var import_tracing = require("./utils/tracing.js"); var import_utils_common = require("./utils/utils.common.js"); var import_BlobSASSignatureValues = require("./sas/BlobSASSignatureValues.js"); var import_BlobLeaseClient = require("./BlobLeaseClient.js"); var import_Clients = require("./Clients.js"); var import_BlobBatchClient = require("./BlobBatchClient.js"); class ContainerClient extends import_StorageClient.StorageClient { /** * containerContext provided by protocol layer. */ containerContext; _containerName; blobClientConfig; /** * The name of the container. */ get containerName() { return this._containerName; } constructor(urlOrConnectionString, credentialOrPipelineOrContainerName, options) { let pipeline; let url; options = options || {}; if ((0, import_Pipeline.isPipelineLike)(credentialOrPipelineOrContainerName)) { url = urlOrConnectionString; pipeline = credentialOrPipelineOrContainerName; } else if (import_core_util.isNodeLike && credentialOrPipelineOrContainerName instanceof import_storage_common.StorageSharedKeyCredential || credentialOrPipelineOrContainerName instanceof import_storage_common.AnonymousCredential || (0, import_core_auth.isTokenCredential)(credentialOrPipelineOrContainerName)) { url = urlOrConnectionString; pipeline = (0, import_Pipeline.newPipeline)(credentialOrPipelineOrContainerName, options); } else if (!credentialOrPipelineOrContainerName && typeof credentialOrPipelineOrContainerName !== "string") { url = urlOrConnectionString; pipeline = (0, import_Pipeline.newPipeline)(new import_storage_common.AnonymousCredential(), options); } else if (credentialOrPipelineOrContainerName && typeof credentialOrPipelineOrContainerName === "string") { const containerName = credentialOrPipelineOrContainerName; const extractedCreds = (0, import_utils_common.extractConnectionStringParts)(urlOrConnectionString); if (extractedCreds.kind === "AccountConnString") { if (import_core_util.isNodeLike) { const sharedKeyCredential = new import_storage_common.StorageSharedKeyCredential( extractedCreds.accountName, extractedCreds.accountKey ); url = (0, import_utils_common.appendToURLPath)(extractedCreds.url, encodeURIComponent(containerName)); if (!options.proxyOptions) { options.proxyOptions = (0, import_core_rest_pipeline.getDefaultProxySettings)(extractedCreds.proxyUri); } pipeline = (0, import_Pipeline.newPipeline)(sharedKeyCredential, options); } else { throw new Error("Account connection string is only supported in Node.js environment"); } } else if (extractedCreds.kind === "SASConnString") { url = (0, import_utils_common.appendToURLPath)(extractedCreds.url, encodeURIComponent(containerName)) + "?" + extractedCreds.accountSas; pipeline = (0, import_Pipeline.newPipeline)(new import_storage_common.AnonymousCredential(), options); } else { throw new Error( "Connection string must be either an Account connection string or a SAS connection string" ); } } else { throw new Error("Expecting non-empty strings for containerName parameter"); } super(url, pipeline); this._containerName = this.getContainerNameFromUrl(); this.containerContext = this.storageClientContext.container; this.blobClientConfig = options; } /** * Creates a new container under the specified account. If the container with * the same name already exists, the operation fails. * @see https://learn.microsoft.com/rest/api/storageservices/create-container * Naming rules: @see https://learn.microsoft.com/rest/api/storageservices/naming-and-referencing-containers--blobs--and-metadata * * @param options - Options to Container Create operation. * * * Example usage: * * ```ts snippet:ContainerClientCreate * import { BlobServiceClient } from "@azure/storage-blob"; * import { DefaultAzureCredential } from "@azure/identity"; * * const account = "<account>"; * const blobServiceClient = new BlobServiceClient( * `https://${account}.blob.core.windows.net`, * new DefaultAzureCredential(), * ); * * const containerName = "<container name>"; * const containerClient = blobServiceClient.getContainerClient(containerName); * const createContainerResponse = await containerClient.create(); * console.log("Container was created successfully", createContainerResponse.requestId); * ``` */ async create(options = {}) { return import_tracing.tracingClient.withSpan("ContainerClient-create", options, async (updatedOptions) => { return (0, import_utils_common.assertResponse)( await this.containerContext.create(updatedOptions) ); }); } /** * Creates a new container under the specified account. If the container with * the same name already exists, it is not changed. * @see https://learn.microsoft.com/rest/api/storageservices/create-container * Naming rules: @see https://learn.microsoft.com/rest/api/storageservices/naming-and-referencing-containers--blobs--and-metadata * * @param options - */ async createIfNotExists(options = {}) { return import_tracing.tracingClient.withSpan( "ContainerClient-createIfNotExists", options, async (updatedOptions) => { try { const res = await this.create(updatedOptions); return { succeeded: true, ...res, _response: res._response // _response is made non-enumerable }; } catch (e) { if (e.details?.errorCode === "ContainerAlreadyExists") { return { succeeded: false, ...e.response?.parsedHeaders, _response: e.response }; } else { throw e; } } } ); } /** * Returns true if the Azure container resource represented by this client exists; false otherwise. * * NOTE: use this function with care since an existing container might be deleted by other clients or * applications. Vice versa new containers with the same name might be added by other clients or * applications after this function completes. * * @param options - */ async exists(options = {}) { return import_tracing.tracingClient.withSpan("ContainerClient-exists", options, async (updatedOptions) => { try { await this.getProperties({ abortSignal: options.abortSignal, tracingOptions: updatedOptions.tracingOptions }); return true; } catch (e) { if (e.statusCode === 404) { return false; } throw e; } }); } /** * Creates a {@link BlobClient} * * @param blobName - A blob name * @returns A new BlobClient object for the given blob name. */ getBlobClient(blobName) { return new import_Clients.BlobClient( (0, import_utils_common.appendToURLPath)(this.url, (0, import_utils_common.EscapePath)(blobName)), this.pipeline, this.blobClientConfig ); } /** * Creates an {@link AppendBlobClient} * * @param blobName - An append blob name */ getAppendBlobClient(blobName) { return new import_Clients.AppendBlobClient( (0, import_utils_common.appendToURLPath)(this.url, (0, import_utils_common.EscapePath)(blobName)), this.pipeline, this.blobClientConfig ); } /** * Creates a {@link BlockBlobClient} * * @param blobName - A block blob name * * * Example usage: * * ```ts snippet:ClientsUpload * import { BlobServiceClient } from "@azure/storage-blob"; * import { DefaultAzureCredential } from "@azure/identity"; * * const account = "<account>"; * const blobServiceClient = new BlobServiceClient( * `https://${account}.blob.core.windows.net`, * new DefaultAzureCredential(), * ); * * const containerName = "<container name>"; * const blobName = "<blob name>"; * const containerClient = blobServiceClient.getContainerClient(containerName); * const blockBlobClient = containerClient.getBlockBlobClient(blobName); * * const content = "Hello world!"; * const uploadBlobResponse = await blockBlobClient.upload(content, content.length); * ``` */ getBlockBlobClient(blobName) { return new import_Clients.BlockBlobClient( (0, import_utils_common.appendToURLPath)(this.url, (0, import_utils_common.EscapePath)(blobName)), this.pipeline, this.blobClientConfig ); } /** * Creates a {@link PageBlobClient} * * @param blobName - A page blob name */ getPageBlobClient(blobName) { return new import_Clients.PageBlobClient( (0, import_utils_common.appendToURLPath)(this.url, (0, import_utils_common.EscapePath)(blobName)), this.pipeline, this.blobClientConfig ); } /** * Returns all user-defined metadata and system properties for the specified * container. The data returned does not include the container's list of blobs. * @see https://learn.microsoft.com/rest/api/storageservices/get-container-properties * * WARNING: The `metadata` object returned in the response will have its keys in lowercase, even if * they originally contained uppercase characters. This differs from the metadata keys returned by * the `listContainers` method of {@link BlobServiceClient} using the `includeMetadata` option, which * will retain their original casing. * * @param options - Options to Container Get Properties operation. */ async getProperties(options = {}) { if (!options.conditions) { options.conditions = {}; } return import_tracing.tracingClient.withSpan( "ContainerClient-getProperties", options, async (updatedOptions) => { return (0, import_utils_common.assertResponse)( await this.containerContext.getProperties({ abortSignal: options.abortSignal, ...options.conditions, tracingOptions: updatedOptions.tracingOptions }) ); } ); } /** * Marks the specified container for deletion. The container and any blobs * contained within it are later deleted during garbage collection. * @see https://learn.microsoft.com/rest/api/storageservices/delete-container * * @param options - Options to Container Delete operation. */ async delete(options = {}) { if (!options.conditions) { options.conditions = {}; } return import_tracing.tracingClient.withSpan("ContainerClient-delete", options, async (updatedOptions) => { return (0, import_utils_common.assertResponse)( await this.containerContext.delete({ abortSignal: options.abortSignal, leaseAccessConditions: options.conditions, modifiedAccessConditions: options.conditions, tracingOptions: updatedOptions.tracingOptions }) ); }); } /** * Marks the specified container for deletion if it exists. The container and any blobs * contained within it are later deleted during garbage collection. * @see https://learn.microsoft.com/rest/api/storageservices/delete-container * * @param options - Options to Container Delete operation. */ async deleteIfExists(options = {}) { return import_tracing.tracingClient.withSpan( "ContainerClient-deleteIfExists", options, async (updatedOptions) => { try { const res = await this.delete(updatedOptions); return { succeeded: true, ...res, _response: res._response }; } catch (e) { if (e.details?.errorCode === "ContainerNotFound") { return { succeeded: false, ...e.response?.parsedHeaders, _response: e.response }; } throw e; } } ); } /** * Sets one or more user-defined name-value pairs for the specified container. * * If no option provided, or no metadata defined in the parameter, the container * metadata will be removed. * * @see https://learn.microsoft.com/rest/api/storageservices/set-container-metadata * * @param metadata - Replace existing metadata with this value. * If no value provided the existing metadata will be removed. * @param options - Options to Container Set Metadata operation. */ async setMetadata(metadata, options = {}) { if (!options.conditions) { options.conditions = {}; } if (options.conditions.ifUnmodifiedSince) { throw new RangeError( "the IfUnmodifiedSince must have their default values because they are ignored by the blob service" ); } return import_tracing.tracingClient.withSpan( "ContainerClient-setMetadata", options, async (updatedOptions) => { return (0, import_utils_common.assertResponse)( await this.containerContext.setMetadata({ abortSignal: options.abortSignal, leaseAccessConditions: options.conditions, metadata, modifiedAccessConditions: options.conditions, tracingOptions: updatedOptions.tracingOptions }) ); } ); } /** * Gets the permissions for the specified container. The permissions indicate * whether container data may be accessed publicly. * * WARNING: JavaScript Date will potentially lose precision when parsing startsOn and expiresOn strings. * For example, new Date("2018-12-31T03:44:23.8827891Z").toISOString() will get "2018-12-31T03:44:23.882Z". * * @see https://learn.microsoft.com/rest/api/storageservices/get-container-acl * * @param options - Options to Container Get Access Policy operation. */ async getAccessPolicy(options = {}) { if (!options.conditions) { options.conditions = {}; } return import_tracing.tracingClient.withSpan( "ContainerClient-getAccessPolicy", options, async (updatedOptions) => { const response = (0, import_utils_common.assertResponse)( await this.containerContext.getAccessPolicy({ abortSignal: options.abortSignal, leaseAccessConditions: options.conditions, tracingOptions: updatedOptions.tracingOptions }) ); const res = { _response: response._response, blobPublicAccess: response.blobPublicAccess, date: response.date, etag: response.etag, errorCode: response.errorCode, lastModified: response.lastModified, requestId: response.requestId, clientRequestId: response.clientRequestId, signedIdentifiers: [], version: response.version }; for (const identifier of response) { let accessPolicy = void 0; if (identifier.accessPolicy) { accessPolicy = { permissions: identifier.accessPolicy.permissions }; if (identifier.accessPolicy.expiresOn) { accessPolicy.expiresOn = new Date(identifier.accessPolicy.expiresOn); } if (identifier.accessPolicy.startsOn) { accessPolicy.startsOn = new Date(identifier.accessPolicy.startsOn); } } res.signedIdentifiers.push({ accessPolicy, id: identifier.id }); } return res; } ); } /** * Sets the permissions for the specified container. The permissions indicate * whether blobs in a container may be accessed publicly. * * When you set permissions for a container, the existing permissions are replaced. * If no access or containerAcl provided, the existing container ACL will be * removed. * * When you establish a stored access policy on a container, it may take up to 30 seconds to take effect. * During this interval, a shared access signature that is associated with the stored access policy will * fail with status code 403 (Forbidden), until the access policy becomes active. * @see https://learn.microsoft.com/rest/api/storageservices/set-container-acl * * @param access - The level of public access to data in the container. * @param containerAcl - Array of elements each having a unique Id and details of the access policy. * @param options - Options to Container Set Access Policy operation. */ async setAccessPolicy(access, containerAcl, options = {}) { options.conditions = options.conditions || {}; return import_tracing.tracingClient.withSpan( "ContainerClient-setAccessPolicy", options, async (updatedOptions) => { const acl = []; for (const identifier of containerAcl || []) { acl.push({ accessPolicy: { expiresOn: identifier.accessPolicy.expiresOn ? (0, import_utils_common.truncatedISO8061Date)(identifier.accessPolicy.expiresOn) : "", permissions: identifier.accessPolicy.permissions, startsOn: identifier.accessPolicy.startsOn ? (0, import_utils_common.truncatedISO8061Date)(identifier.accessPolicy.startsOn) : "" }, id: identifier.id }); } return (0, import_utils_common.assertResponse)( await this.containerContext.setAccessPolicy({ abortSignal: options.abortSignal, access, containerAcl: acl, leaseAccessConditions: options.conditions, modifiedAccessConditions: options.conditions, tracingOptions: updatedOptions.tracingOptions }) ); } ); } /** * Get a {@link BlobLeaseClient} that manages leases on the container. * * @param proposeLeaseId - Initial proposed lease Id. * @returns A new BlobLeaseClient object for managing leases on the container. */ getBlobLeaseClient(proposeLeaseId) { return new import_BlobLeaseClient.BlobLeaseClient(this, proposeLeaseId); } /** * Creates a new block blob, or updates the content of an existing block blob. * * Updating an existing block blob overwrites any existing metadata on the blob. * Partial updates are not supported; the content of the existing blob is * overwritten with the new content. To perform a partial update of a block blob's, * use {@link BlockBlobClient.stageBlock} and {@link BlockBlobClient.commitBlockList}. * * This is a non-parallel uploading method, please use {@link BlockBlobClient.uploadFile}, * {@link BlockBlobClient.uploadStream} or {@link BlockBlobClient.uploadBrowserData} for better * performance with concurrency uploading. * * @see https://learn.microsoft.com/rest/api/storageservices/put-blob * * @param blobName - Name of the block blob to create or update. * @param body - Blob, string, ArrayBuffer, ArrayBufferView or a function * which returns a new Readable stream whose offset is from data source beginning. * @param contentLength - Length of body in bytes. Use Buffer.byteLength() to calculate body length for a * string including non non-Base64/Hex-encoded characters. * @param options - Options to configure the Block Blob Upload operation. * @returns Block Blob upload response data and the corresponding BlockBlobClient instance. */ async uploadBlockBlob(blobName, body, contentLength, options = {}) { return import_tracing.tracingClient.withSpan( "ContainerClient-uploadBlockBlob", options, async (updatedOptions) => { const blockBlobClient = this.getBlockBlobClient(blobName); const response = await blockBlobClient.upload(body, contentLength, updatedOptions); return { blockBlobClient, response }; } ); } /** * Marks the specified blob or snapshot for deletion. The blob is later deleted * during garbage collection. Note that in order to delete a blob, you must delete * all of its snapshots. You can delete both at the same time with the Delete * Blob operation. * @see https://learn.microsoft.com/rest/api/storageservices/delete-blob * * @param blobName - * @param options - Options to Blob Delete operation. * @returns Block blob deletion response data. */ async deleteBlob(blobName, options = {}) { return import_tracing.tracingClient.withSpan("ContainerClient-deleteBlob", options, async (updatedOptions) => { let blobClient = this.getBlobClient(blobName); if (options.versionId) { blobClient = blobClient.withVersion(options.versionId); } return blobClient.delete(updatedOptions); }); } /** * listBlobFlatSegment returns a single segment of blobs starting from the * specified Marker. Use an empty Marker to start enumeration from the beginning. * After getting a segment, process it, and then call listBlobsFlatSegment again * (passing the the previously-returned Marker) to get the next segment. * @see https://learn.microsoft.com/rest/api/storageservices/list-blobs * * @param marker - A string value that identifies the portion of the list to be returned with the next list operation. * @param options - Options to Container List Blob Flat Segment operation. */ async listBlobFlatSegment(marker, options = {}) { return import_tracing.tracingClient.withSpan( "ContainerClient-listBlobFlatSegment", options, async (updatedOptions) => { const response = (0, import_utils_common.assertResponse)( await this.containerContext.listBlobFlatSegment({ marker, ...options, tracingOptions: updatedOptions.tracingOptions }) ); const wrappedResponse = { ...response, _response: { ...response._response, parsedBody: (0, import_utils_common.ConvertInternalResponseOfListBlobFlat)(response._response.parsedBody) }, // _response is made non-enumerable segment: { ...response.segment, blobItems: response.segment.blobItems.map((blobItemInternal) => { const blobItem = { ...blobItemInternal, name: (0, import_utils_common.BlobNameToString)(blobItemInternal.name), tags: (0, import_utils_common.toTags)(blobItemInternal.blobTags), objectReplicationSourceProperties: (0, import_utils_common.parseObjectReplicationRecord)( blobItemInternal.objectReplicationMetadata ) }; return blobItem; }) } }; return wrappedResponse; } ); } /** * listBlobHierarchySegment returns a single segment of blobs starting from * the specified Marker. Use an empty Marker to start enumeration from the * beginning. After getting a segment, process it, and then call listBlobsHierarchicalSegment * again (passing the the previously-returned Marker) to get the next segment. * @see https://learn.microsoft.com/rest/api/storageservices/list-blobs * * @param delimiter - The character or string used to define the virtual hierarchy * @param marker - A string value that identifies the portion of the list to be returned with the next list operation. * @param options - Options to Container List Blob Hierarchy Segment operation. */ async listBlobHierarchySegment(delimiter, marker, options = {}) { return import_tracing.tracingClient.withSpan( "ContainerClient-listBlobHierarchySegment", options, async (updatedOptions) => { const response = (0, import_utils_common.assertResponse)( await this.containerContext.listBlobHierarchySegment(delimiter, { marker, ...options, tracingOptions: updatedOptions.tracingOptions }) ); const wrappedResponse = { ...response, _response: { ...response._response, parsedBody: (0, import_utils_common.ConvertInternalResponseOfListBlobHierarchy)(response._response.parsedBody) }, // _response is made non-enumerable segment: { ...response.segment, blobItems: response.segment.blobItems.map((blobItemInternal) => { const blobItem = { ...blobItemInternal, name: (0, import_utils_common.BlobNameToString)(blobItemInternal.name), tags: (0, import_utils_common.toTags)(blobItemInternal.blobTags), objectReplicationSourceProperties: (0, import_utils_common.parseObjectReplicationRecord)( blobItemInternal.objectReplicationMetadata ) }; return blobItem; }), blobPrefixes: response.segment.blobPrefixes?.map((blobPrefixInternal) => { const blobPrefix = { ...blobPrefixInternal, name: (0, import_utils_common.BlobNameToString)(blobPrefixInternal.name) }; return blobPrefix; }) } }; return wrappedResponse; } ); } /** * Returns an AsyncIterableIterator for ContainerListBlobFlatSegmentResponse * * @param marker - A string value that identifies the portion of * the list of blobs to be returned with the next listing operation. The * operation returns the ContinuationToken value within the response body if the * listing operation did not return all blobs remaining to be listed * with the current page. The ContinuationToken value can be used as the value for * the marker parameter in a subsequent call to request the next page of list * items. The marker value is opaque to the client. * @param options - Options to list blobs operation. */ async *listSegments(marker, options = {}) { let listBlobsFlatSegmentResponse; if (!!marker || marker === void 0) { do { listBlobsFlatSegmentResponse = await this.listBlobFlatSegment(marker, options); marker = listBlobsFlatSegmentResponse.continuationToken; yield await listBlobsFlatSegmentResponse; } while (marker); } } /** * Returns an AsyncIterableIterator of {@link BlobItem} objects * * @param options - Options to list blobs operation. */ async *listItems(options = {}) { let marker; for await (const listBlobsFlatSegmentResponse of this.listSegments(marker, options)) { yield* listBlobsFlatSegmentResponse.segment.blobItems; } } /** * Returns an async iterable iterator to list all the blobs * under the specified account. * * .byPage() returns an async iterable iterator to list the blobs in pages. * * ```ts snippet:ReadmeSampleListBlobs_Multiple * import { BlobServiceClient } from "@azure/storage-blob"; * import { DefaultAzureCredential } from "@azure/identity"; * * const account = "<account>"; * const blobServiceClient = new BlobServiceClient( * `https://${account}.blob.core.windows.net`, * new DefaultAzureCredential(), * ); * * const containerName = "<container name>"; * const containerClient = blobServiceClient.getContainerClient(containerName); * * // Example using `for await` syntax * let i = 1; * const blobs = containerClient.listBlobsFlat(); * for await (const blob of blobs) { * console.log(`Blob ${i++}: ${blob.name}`); * } * * // Example using `iter.next()` syntax * i = 1; * const iter = containerClient.listBlobsFlat(); * let { value, done } = await iter.next(); * while (!done) { * console.log(`Blob ${i++}: ${value.name}`); * ({ value, done } = await iter.next()); * } * * // Example using `byPage()` syntax * i = 1; * for await (const page of containerClient.listBlobsFlat().byPage({ maxPageSize: 20 })) { * for (const blob of page.segment.blobItems) { * console.log(`Blob ${i++}: ${blob.name}`); * } * } * * // Example using paging with a marker * i = 1; * let iterator = containerClient.listBlobsFlat().byPage({ maxPageSize: 2 }); * let response = (await iterator.next()).value; * // Prints 2 blob names * if (response.segment.blobItems) { * for (const blob of response.segment.blobItems) { * console.log(`Blob ${i++}: ${blob.name}`); * } * } * // Gets next marker * let marker = response.continuationToken; * // Passing next marker as continuationToken * iterator = containerClient.listBlobsFlat().byPage({ continuationToken: marker, maxPageSize: 10 }); * response = (await iterator.next()).value; * // Prints 10 blob names * if (response.segment.blobItems) { * for (const blob of response.segment.blobItems) { * console.log(`Blob ${i++}: ${blob.name}`); * } * } * ``` * * @param options - Options to list blobs. * @returns An asyncIterableIterator that supports paging. */ listBlobsFlat(options = {}) { const include = []; if (options.includeCopy) { include.push("copy"); } if (options.includeDeleted) { include.push("deleted"); } if (options.includeMetadata) { include.push("metadata"); } if (options.includeSnapshots) { include.push("snapshots"); } if (options.includeVersions) { include.push("versions"); } if (options.includeUncommitedBlobs) { include.push("uncommittedblobs"); } if (options.includeTags) { include.push("tags"); } if (options.includeDeletedWithVersions) { include.push("deletedwithversions"); } if (options.includeImmutabilityPolicy) { include.push("immutabilitypolicy"); } if (options.includeLegalHold) { include.push("legalhold"); } if (options.prefix === "") { options.prefix = void 0; } const updatedOptions = { ...options, ...include.length > 0 ? { include } : {} }; const iter = this.listItems(updatedOptions); return { /** * The next method, part of the iteration protocol */ next() { return iter.next(); }, /** * The connection to the async iterator, part of the iteration protocol */ [Symbol.asyncIterator]() { return this; }, /** * Return an AsyncIterableIterator that works a page at a time */ byPage: (settings = {}) => { return this.listSegments(settings.continuationToken, { maxPageSize: settings.maxPageSize, ...updatedOptions }); } }; } /** * Returns an AsyncIterableIterator for ContainerListBlobHierarchySegmentResponse * * @param delimiter - The character or string used to define the virtual hierarchy * @param marker - A string value that identifies the portion of * the list of blobs to be returned with the next listing operation. The * operation returns the ContinuationToken value within the response body if the * listing operation did not return all blobs remaining to be listed * with the current page. The ContinuationToken value can be used as the value for * the marker parameter in a subsequent call to request the next page of list * items. The marker value is opaque to the client. * @param options - Options to list blobs operation. */ async *listHierarchySegments(delimiter, marker, options = {}) { let listBlobsHierarchySegmentResponse; if (!!marker || marker === void 0) { do { listBlobsHierarchySegmentResponse = await this.listBlobHierarchySegment( delimiter, marker, options ); marker = listBlobsHierarchySegmentResponse.continuationToken; yield await listBlobsHierarchySegmentResponse; } while (marker); } } /** * Returns an AsyncIterableIterator for {@link BlobPrefix} and {@link BlobItem} objects. * * @param delimiter - The character or string used to define the virtual hierarchy * @param options - Options to list blobs operation. */ async *listItemsByHierarchy(delimiter, options = {}) { let marker; for await (const listBlobsHierarchySegmentResponse of this.listHierarchySegments( delimiter, marker, options )) { const segment = listBlobsHierarchySegmentResponse.segment; if (segment.blobPrefixes) { for (const prefix of segment.blobPrefixes) { yield { kind: "prefix", ...prefix }; } } for (const blob of segment.blobItems) { yield { kind: "blob", ...blob }; } } } /** * Returns an async iterable iterator to list all the blobs by hierarchy. * under the specified account. * * .byPage() returns an async iterable iterator to list the blobs by hierarchy in pages. * * ```ts snippet:ReadmeSampleListBlobsByHierarchy * import { BlobServiceClient } from "@azure/storage-blob"; * import { DefaultAzureCredential } from "@azure/identity"; * * const account = "<account>"; * const blobServiceClient = new BlobServiceClient( * `https://${account}.blob.core.windows.net`, * new DefaultAzureCredential(), * ); * * const containerName = "<container name>"; * const containerClient = blobServiceClient.getContainerClient(containerName); * * // Example using `for await` syntax * let i = 1; * const blobs = containerClient.listBlobsByHierarchy("/"); * for await (const blob of blobs) { * if (blob.kind === "prefix") { * console.log(`\tBlobPrefix: ${blob.name}`); * } else { * console.log(`\tBlobItem: name - ${blob.name}`); * } * } * * // Example using `iter.next()` syntax * i = 1; * const iter = containerClient.listBlobsByHierarchy("/"); * let { value, done } = await iter.next(); * while (!done) { * if (value.kind === "prefix") { * console.log(`\tBlobPrefix: ${value.name}`); * } else { * console.log(`\tBlobItem: name - ${value.name}`); * } * ({ value, done } = await iter.next()); * } * * // Example using `byPage()` syntax * i = 1; * for await (const page of containerClient.listBlobsByHierarchy("/").byPage({ maxPageSize: 20 })) { * const segment = page.segment; * if (segment.blobPrefixes) { * for (const prefix of segment.blobPrefixes) { * console.log(`\tBlobPrefix: ${prefix.name}`); * } * } * for (const blob of page.segment.blobItems) { * console.log(`\tBlobItem: name - ${blob.name}`); * } * } * * // Example using paging with a marker * i = 1; * let iterator = containerClient.listBlobsByHierarchy("/").byPage({ maxPageSize: 2 }); * let response = (await iterator.next()).value; * // Prints 2 blob names * if (response.blobPrefixes) { * for (const prefix of response.blobPrefixes) { * console.log(`\tBlobPrefix: ${prefix.name}`); * } * } * if (response.segment.blobItems) { * for (const blob of response.segment.blobItems) { * console.log(`\tBlobItem: name - ${blob.name}`); * } * } * // Gets next marker * let marker = response.continuationToken; * // Passing next marker as continuationToken * iterator = containerClient * .listBlobsByHierarchy("/") * .byPage({ continuationToken: marker, maxPageSize: 10 }); * response = (await iterator.next()).value; * // Prints 10 blob names * if (response.blobPrefixes) { * for (const prefix of response.blobPrefixes) { * console.log(`\tBlobPrefix: ${prefix.name}`); * } * } * if (response.segment.blobItems) { * for (const blob of response.segment.blobItems) { * console.log(`Blob ${i++}: ${blob.name}`); * } * } * ``` * * @param delimiter - The character or string used to define the virtual hierarchy * @param options - Options to list blobs operation. */ listBlobsByHierarchy(delimiter, options = {}) { if (delimiter === "") { throw new RangeError("delimiter should contain one or more characters"); } const include = []; if (options.includeCopy) { include.push("copy"); } if (options.includeDeleted) { include.push("deleted"); } if (options.includeMetadata) { include.push("metadata"); } if (options.includeSnapshots) { include.push("snapshots"); } if (options.includeVersions) { include.push("versions"); } if (options.includeUncommitedBlobs) { include.push("uncommittedblobs"); } if (options.includeTags) { include.push("tags"); } if (options.includeDeletedWithVersions) { include.push("deletedwithversions"); } if (options.includeImmutabilityPolicy) { include.push("immutabilitypolicy"); } if (options.includeLegalHold) { include.push("legalhold"); } if (options.prefix === "") { options.prefix = void 0; } const updatedOptions = { ...options, ...include.length > 0 ? { include } : {} }; const iter = this.listItemsByHierarchy(delimiter, updatedOptions); return { /** * The next method, part of the iteration protocol */ async next() { return iter.next(); }, /** * The connection to the async iterator, part of the iteration protocol */ [Symbol.asyncIterator]() { return this; }, /** * Return an AsyncIterableIterator that works a page at a time */ byPage: (settings = {}) => { return this.listHierarchySegments(delimiter, settings.continuationToken, { maxPageSize: settings.maxPageSize, ...updatedOptions }); } }; } /** * The Filter Blobs operation enables callers to list blobs in the container whose tags * match a given search expression. * * @param tagFilterSqlExpression - The where parameter enables the caller to query blobs whose tags match a given expression. * The given expression must evaluate to true for a blob to be returned in the results. * The[OData - ABNF] filter syntax rule defines the formal grammar for the value of the where query parameter; * however, only a subset of the OData filter syntax is supported in the Blob service. * @param marker - A string value that identifies the portion of * the list of blobs to be returned with the next listing operation. The * operation returns the continuationToken value within the response body if the * listing operation did not return all blobs remaining to be listed * with the current page. The continuationToken value can be used as the value for * the marker parameter in a subsequent call to request the next page of list * items. The marker value is opaque to the client. * @param options - Options to find blobs by tags. */ async findBlobsByTagsSegment(tagFilterSqlExpression, marker, options = {}) { return import_tracing.tracingClient.withSpan( "ContainerClient-findBlobsByTagsSegment", options, async (updatedOptions) => { const response = (0, import_utils_common.assertResponse)( await this.containerContext.filterBlobs({ abortSignal: options.abortSignal, where: tagFilterSqlExpression, marker, maxPageSize: options.maxPageSize, tracingOptions: updatedOptions.tracingOptions }) ); const wrappedResponse = { ...response, _response: response._response, // _response is made non-enumerable blobs: response.blobs.map((blob) => { let tagValue = ""; if (blob.tags?.blobTagSet.length === 1) { tagValue = blob.tags.blobTagSet[0].value; } return { ...blob, tags: (0, import_utils_common.toTags)(blob.tags), tagValue }; }) }; return wrappedResponse; } ); } /** * Returns an AsyncIterableIterator for ContainerFindBlobsByTagsSegmentResponse. * * @param tagFilterSqlExpression - The where parameter enables the caller to query blobs whose tags match a given expression. * The given expression must evaluate to true for a blob to be returned in the results. * The[OData - ABNF] filter syntax rule defines the formal grammar for the value of the where query parameter; * however, only a subset of the OData filter syntax is supported in the Blob service. * @param marker - A string value that identifies the portion of * the list of blobs to be returned with the next listing operation. The * operation returns the continuationToken value within the response body if the * listing operation did not return all blobs remaining to be listed * with the current page. The continuationToken value can be used as the value for * the marker parameter in a subsequent call to request the next page of list * items. The marker value is opaque to the client. * @param options - Options to find blobs by tags. */ async *findBlobsByTagsSegments(tagFilterSqlExpression, marker, options = {}) { let response; if (!!marker || marker === void 0) { do { response = await this.findBlobsByTagsSegment(tagFilterSqlExpression, marker, options); response.blobs = response.blobs || []; marker = response.continuationToken; yield response; } while (marker); } } /** * Returns an AsyncIterableIterator for blobs. * * @param tagFilterSqlExpression - The where parameter enables the caller to query blobs whose tags match a given expression. * The given expression must evaluate to true for a blob to be returned in the results. * The[OData - ABNF] filter syntax rule defines the formal grammar for the value of the where query parameter; * however, only a subset of the OData filter syntax is supported in the Blob service. * @param options - Options to findBlobsByTagsItems. */ async *findBlobsByTagsItems(tagFilterSqlExpression, options = {}) { let marker; for await (const segment of this.findBlobsByTagsSegments( tagFilterSqlExpression, marker, options )) { yield* segment.blobs; } } /** * Returns an async iterable iterator to find all blobs with specified tag * under the specified container. * * .byPage() returns an async iterable iterator to list the blobs in pages. * * Example using `for await` syntax: * * ```ts snippet:ReadmeSampleFindBlobsByTags * import { BlobServiceClient } from "@azure/storage-blob"; * import { DefaultAzureCredential } from "@azure/identity"; * * const account = "<account>"; * const blobServiceClient = new BlobServiceClient( * `https://${account}.blob.core.windows.net`, * new DefaultAzureCredential(), * ); * * const containerName = "<container name>"; * const containerClient = blobServiceClient.getContainerClient(containerName); * * // Example using `for await` syntax * let i = 1; * for await (const blob of containerClient.findBlobsByTags("tagkey='tagvalue'")) { * console.log(`Blob ${i++}: ${blob.name}`); * } * * // Example using `iter.next()` syntax * i = 1; * const iter = containerClient.findBlobsByTags("tagkey='tagvalue'"); * let { value, done } = await iter.next(); * while (!done) { * console.log(`Blob ${i++}: ${value.name}`); * ({ value, done } = await iter.next()); * } * * // Example using `byPage()` syntax * i = 1; * for await (const page of containerClient * .findBlobsByTags("tagkey='tagvalue'") * .byPage({ maxPageSize: 20 })) { * for (const blob of page.blobs) { * console.log(`Blob ${i++}: ${blob.name}`); * } * } * * // Example using paging with a marker * i = 1; * let iterator = containerClient.findBlobsByTags("tagkey='tagvalue'").byPage({ maxPageSize: 2 }); * let response = (await iterator.next()).value; * // Prints 2 blob names * if (response.blobs) { * for (const blob of response.blobs) { * console.log(`Blob ${i++}: ${blob.name}`); * } * } * // Gets next marker * let marker = response.continuationToken; * // Passing next marker as continuationToken * iterator = containerClient * .findBlobsByTags("tagkey='tagvalue'") * .byPage({ continuationToken: marker, maxPageSize: 10 }); * response = (await iterator.next()).value; * // Prints 10 blob names * if (response.blobs) { * for (const blob of response.blobs) { * console.log(`Blob ${i++}: ${blob.name}`); * } * } * ``` * * @param tagFilterSqlExpression - The where parameter enables the caller to query blobs whose tags match a given expression. * The given expression must evaluate to true for a blob to be returned in the results. * The[OData - ABNF] filter syntax rule defines the formal grammar for the value of the where query parameter; * however, only a subset of the OData filter syntax is supported in the Blob service. * @param options - Options to find blobs by tags. */ findBlobsByTags(tagFilterSqlExpression, options = {}) { const listSegmentOptions = { ...options }; const iter = this.findBlobsByTagsItems(tagFilterSqlExpression, listSegmentOptions); return { /** * The next method, part of the iteration protocol */ next() { return iter.next(); }, /** * The connection to the async iterator, part of the iteration protocol */ [Symbol.asyncIterator]() { return this; }, /** * Return an AsyncIterableIterator that works a page at a time */ byPage: (settings = {}) => { return this.findBlobsByTagsSegments(tagFilterSqlExpression, settings.continuationToken, { maxPageSize: settings.maxPageSize, ...listSegmentOptions }); } }; } /** * The Get Account Information operation returns the sku name and account kind * for the specified account. * The Get Account Information operation is available on service versions beginning * with version 2018-03-28. * @see https://learn.microsoft.com/rest/api/storageservices/get-account-information * * @param options - Options to the Service Get Account Info operation. * @returns Response data for the Service Get Account Info operation. */ async getAccountInfo(options = {}) { return import_tracing.tracingClient.withSpan( "ContainerClient-getAccountInfo", options, async (updatedOptions) => { return (0, import_utils_common.assertResponse)( await this.containerContext.getAccountInfo({ abortSignal: options.abortSignal, tracingOptions: updatedOptions.tracingOptions }) ); } ); } getContainerNameFromUrl() { let containerName; try { const parsedUrl = new URL(this.url); if (parsedUrl.hostname.split(".")[1] === "blob") { containerName = parsedUrl.pathname.split("/")[1]; } else if ((0, import_utils_common.isIpEndpointStyle)(parsedUrl)) { containerName = parsedUrl.path