UNPKG

@azure/storage-blob

Version:
1,558 lines • 61.9 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_blobListArrowParser = require("./utils/blobListArrowParser.js");
var import_blobListXmlParser = require("./utils/blobListXmlParser.js");
var import_constants = require("./utils/constants.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");
function mapBlobItemInternal(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;
}
function mapBlobPrefixInternal(blobPrefixInternal) {
  const blobPrefix = {
    ...blobPrefixInternal,
    name: (0, import_utils_common.BlobNameToString)(blobPrefixInternal.name)
  };
  return blobPrefix;
}
function isApacheArrow(contentType) {
  return (contentType ?? "").split(";")[0].trim().toLowerCase() === import_constants.ApacheArrowContentType;
}
function withListSegmentResponseMetadata(base, rawResponse, parsedBody, bodyAsText = "") {
  return {
    ...base,
    clientRequestId: rawResponse.clientRequestId,
    requestId: rawResponse.requestId,
    version: rawResponse.version,
    date: rawResponse.date,
    contentType: rawResponse.contentType,
    _response: {
      ...rawResponse._response,
      bodyAsText,
      parsedBody
    }
  };
}
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) => {
        if ((0, import_utils_common.resolveResponseFormat)(options.responseFormat) === import_storage_common.StorageResponseFormat.Arrow) {
          return this.listBlobFlatSegmentApacheArrow(marker, {
            ...options,
            tracingOptions: updatedOptions.tracingOptions
          });
        }
        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(mapBlobItemInternal)
          }
        };
        return wrappedResponse;
      }
    );
  }
  /**
   * Lists a single segment of blobs using the Apache Arrow response format. The service
   * returns a raw stream that is either Apache Arrow or XML (when the account does not
   * support Apache Arrow); both formats are parsed here and produce the same result.
   *
   * @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 listBlobFlatSegmentApacheArrow(marker, options) {
    const rawResponse = (0, import_utils_common.assertResponse)(
      await this.containerContext.listBlobFlatSegmentApacheArrow({
        marker,
        ...options
      })
    );
    if (!isApacheArrow(rawResponse.contentType)) {
      const { parsed: internalResponse2, bodyAsText } = await (0, import_blobListXmlParser.deserializeListBlobFlatSegmentXml)(rawResponse);
      return withListSegmentResponseMetadata(
        {
          ...internalResponse2,
          segment: {
            ...internalResponse2.segment,
            blobItems: (internalResponse2.segment?.blobItems ?? []).map(mapBlobItemInternal)
          }
        },
        rawResponse,
        (0, import_utils_common.ConvertInternalResponseOfListBlobFlat)(internalResponse2),
        bodyAsText
      );
    }
    const parsed = await (0, import_blobListArrowParser.parseBlobListArrowResponse)(rawResponse);
    const serviceUrl = new URL(this.url);
    const containerPath = serviceUrl.pathname.replace(/\/+$/, "");
    serviceUrl.pathname = containerPath.slice(0, containerPath.lastIndexOf("/") + 1);
    serviceUrl.search = "";
    serviceUrl.hash = "";
    const serviceEndpoint = serviceUrl.toString();
    const internalResponse = {
      serviceEndpoint,
      containerName: this.containerName,
      prefix: options.prefix,
      marker,
      maxPageSize: options.maxPageSize,
      segment: { blobItems: parsed.blobItems },
      continuationToken: parsed.nextMarker
    };
    return withListSegmentResponseMetadata(
      {
        serviceEndpoint,
        containerName: this.containerName,
        prefix: options.prefix,
        marker,
        maxPageSize: options.maxPageSize,
        segment: {
          blobItems: parsed.blobItems.map(mapBlobItemInternal)
        },
        continuationToken: parsed.nextMarker
      },
      rawResponse,
      (0, import_utils_common.ConvertInternalResponseOfListBlobFlat)(internalResponse)
    );
  }
  /**
   * 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) => {
        if ((0, import_utils_common.resolveResponseFormat)(options.responseFormat) === import_storage_common.StorageResponseFormat.Arrow) {
          return this.listBlobHierarchySegmentApacheArrow(delimiter, marker, {
            ...options,
            tracingOptions: updatedOptions.tracingOptions
          });
        }
        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(mapBlobItemInternal),
            blobPrefixes: response.segment.blobPrefixes?.map(mapBlobPrefixInternal)
          }
        };
        return wrappedResponse;
      }
    );
  }
  /**
   * Lists a single segment of blobs by hierarchy using the Apache Arrow response format.
   * The service returns a raw stream that is either Apache Arrow or XML (when the account
   * does not support Apache Arrow); both formats are parsed here and produce the same result.
   *
   * @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 listBlobHierarchySegmentApacheArrow(delimiter, marker, options) {
    const rawResponse = (0, import_utils_common.assertResponse)(
      await this.containerContext.listBlobHierarchySegmentApacheArrow(delimiter, {
        marker,
        ...options
      })
    );
    if (!isApacheArrow(rawResponse.contentType)) {
      const { parsed: internalResponse2, bodyAsText } = await (0, import_blobListXmlParser.deserializeListBlobHierarchySegmentXml)(rawResponse);
      return withListSegmentResponseMetadata(
        {
          ...internalResponse2,
          segment: {
            ...internalResponse2.segment,
            blobItems: (internalResponse2.segment?.blobItems ?? []).map(mapBlobItemInternal),
            blobPrefixes: internalResponse2.segment?.blobPrefixes?.map(mapBlobPrefixInternal)
          }
        },
        rawResponse,
        (0, import_utils_common.ConvertInternalResponseOfListBlobHierarchy)(internalResponse2),
        bodyAsText
      );
    }
    const parsed = await (0, import_blobListArrowParser.parseBlobListArrowResponse)(rawResponse);
    const serviceUrl = new URL(this.url);
    const containerPath = serviceUrl.pathname.replace(/\/+$/, "");
    serviceUrl.pathname = containerPath.slice(0, containerPath.lastIndexOf("/") + 1);
    serviceUrl.search = "";
    serviceUrl.hash = "";
    const serviceEndpoint = serviceUrl.toString();
    const internalResponse = {
      serviceEndpoint,
      containerName: this.containerName,
      prefix: options.prefix,
      marker,
      maxPageSize: options.maxPageSize,
      delimiter,
      segment: { blobItems: parsed.blobItems, blobPrefixes: parsed.blobPrefixes },
      continuationToken: parsed.nextMarker
    };
    return withListSegmentResponseMetadata(
      {
        serviceEndpoint,
        containerName: this.containerName,
        prefix: options.prefix,
        marker,
        maxPageSize: options.maxPageSize,
        delimiter,
        segment: {
          blobItems: parsed.blobItems.map(mapBlobItemInternal),
          blobPrefixes: parsed.blobPrefixes.map(mapBlobPrefixInternal)
        },
        continuationToken: parsed.nextMarker
      },
      rawResponse,
      (0, import_utils_common.ConvertInternalResponseOfListBlobHierarchy)(internalResponse)
    );
  }
  /**
   * 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 = {}) {
    if (options.endBefore !== void 0 && (0, import_utils_common.resolveResponseFormat)(options.responseFormat) !== import_storage_common.StorageResponseFormat.Arrow) {
      throw new RangeError(
        "The 'endBefore' option is only supported when 'responseFormat' is StorageResponseFormat.Arrow."
      );
    }
    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");
    }
    if (options.endBefore !== void 0 && (0, import_utils_common.resolveResponseFormat)(options.responseFormat) !== import_storage_common.StorageResponseFormat.Arrow) {
      throw new RangeError(
        "The 'endBefore' option is only supported when 'responseFormat' is StorageResponseFormat.Arrow."
      );
    }
    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.pathname.split("/")[2];
      } else {
        containerName = parsedUrl.pathname.split("/")[1];
      }
      containerName = decodeURIComponent(containerName);
      if (!containerName) {
        throw new Error("Provided containerName is invalid.");
      }
      return containerName;
    } catch (error) {
      throw new Error("Unable to extract containerName with provided information.");
    }
  }
  /**
   * Only available for ContainerClient constructed with a shared key credential.
   *
   * Generates a Blob Container Service Shared Access Signature (SAS) URI based on the client properties
   * and parameters passed in. The SAS is signed by the shared key credential of the client.
   *
   * @see https://learn.microsoft.com/rest/api/storageservices/constructing-a-service-sas
   *
   * @param options - Optional parameters.
   * @returns The SAS URI consisting of the URI to the resource represented by this client, followed by the generated SAS token.
   */
  generateSasUrl(options) {
    return new Promise((resolve) => {
      if (!(this.credential instanceof import_storage_common.StorageSharedKeyCredential)) {
        throw new RangeError(
          "Can only generate the SAS when the client is initialized with a shared key credential"
        );
      }
      const sas = (0, import_BlobSASSignatureValues.generateBlobSASQueryParameters)(
        {
          containerName: this._containerName,
          ...options
        },
        this.credential
      ).toString();
      resolve((0, import_utils_common.appendToURLQuery)(this.url, sas));
    });
  }
  /**
   * Only available for ContainerClient constructed with a shared key credential.
   *
   * Generates string to sign for a Blob Container Service Shared Access Signature (SAS) URI
   * based on the client properties and parameters passed in. The SAS is signed by the shared key credential of the client.
   *
   * @see https://learn.microsoft.com/rest/api/storageservices/constructing-a-service-sas
   *
   * @param options - Optional parameters.
   * @returns The SAS URI consisting of the URI to the resource represented by this client, followed by the generated SAS token.
   */
  /* eslint-disable-next-line @azure/azure-sdk/ts-naming-options*/
  generateSasStringToSign(options) {
    if (!(this.credential instanceof import_storage_common.StorageSharedKeyCredential)) {
      throw new RangeError(
        "Can only generate the SAS when the client is initialized with a shared key credential"
      );
    }
    return (0, import_BlobSASSignatureValues.generateBlobSASQueryParametersInternal)(
      {
        containerName: this._containerName,
        ...options
      },
      this.credential
    ).stringToSign;
  }
  /**
   * Generates a Blob Container Service Shared Access Signature (SAS) URI based on the client properties
   * and parameters passed in. The SAS is signed by the input user delegation key.
   *
   * @see https://learn.microsoft.com/rest/api/storageservices/constructing-a-service-sas
   *
   * @param options - Optional parameters.
   * @param userDelegationKey -  Return value of `blobServiceClient.getUserDelegationKey()`
   * @returns The SAS URI consisting of the URI to the resource represented by this client, followed by the generated SAS token.
   */
  generateUserDelegationSasUrl(options, userDelegationKey) {
    return new Promise((resolve) => {
      const sas = (0, import_BlobSASSignatureValues.generateBlobSASQueryParameters)(
        {
          containerName: this._containerName,
          ...options
        },
        userDelegationKey,
        this.accountName
      ).toString();
      resolve((0, import_utils_common.appendToURLQuery)(this.url, sas));
    });
  }
  /**
   * Generates string to sign for a Blob Container Service Shared Access Signature (SAS) URI
   * based on the client properties and parameters passed in. The SAS is signed by the input user delegation key.
   *
   * @see https://learn.microsoft.com/rest/api/storageservices/constructing-a-service-sas
   *
   * @param options - Optional parameters.
   * @param userDelegationKey -  Return value of `blobServiceClient.getUserDelegationKey()`
   * @returns The SAS URI consisting of the URI to the resource represented by this client, followed by the generated SAS token.
   */
  generateUserDelegationSasStringToSign(options, userDelegationKey) {
    return (0, import_BlobSASSignatureValues.generateBlobSASQueryParametersInternal)(
      {
        containerName: this._containerName,
        ...options
      },
      userDelegationKey,
      this.accountName
    ).stringToSign;
  }
  /**
   * Creates a BlobBatchClient object to conduct batch operations.
   *
   * @see https://learn.microsoft.com/rest/api/storageservices/blob-batch
   *
   * @returns A new BlobBatchClient object for this container.
   */
  getBlobBatchClient() {
    return new import_BlobBatchClient.BlobBatchClient(this.url, this.pipeline);
  }
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  ContainerClient
});
//# sourceMappingURL=ContainerClient.js.map