VICE / ModuleTests / Azure / node_modules / @azure / data-tables / dist / index.js
index.js
Raw
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var tslib = require('tslib');
var coreAuth = require('@azure/core-auth');
var crypto = require('crypto');
require('@azure/core-paging');
var coreXml = require('@azure/core-xml');
var coreClient = require('@azure/core-client');
var coreTracing = require('@azure/core-tracing');
var url$1 = require('url');
var logger$1 = require('@azure/logger');
var coreRestPipeline = require('@azure/core-rest-pipeline');
var uuid = require('uuid');

/*
 * Copyright (c) Microsoft Corporation.
 * Licensed under the MIT License.
 *
 * Code generated by Microsoft (R) AutoRest Code Generator.
 * Changes may cause incorrect behavior and will be lost if the code is regenerated.
 */
/** Known values of {@link OdataMetadataFormat} that the service accepts. */
var KnownOdataMetadataFormat;
(function (KnownOdataMetadataFormat) {
    KnownOdataMetadataFormat["ApplicationJsonOdataNometadata"] = "application/json;odata=nometadata";
    KnownOdataMetadataFormat["ApplicationJsonOdataMinimalmetadata"] = "application/json;odata=minimalmetadata";
    KnownOdataMetadataFormat["ApplicationJsonOdataFullmetadata"] = "application/json;odata=fullmetadata";
})(KnownOdataMetadataFormat || (KnownOdataMetadataFormat = {}));
/** Known values of {@link ResponseFormat} that the service accepts. */
var KnownResponseFormat;
(function (KnownResponseFormat) {
    KnownResponseFormat["ReturnNoContent"] = "return-no-content";
    KnownResponseFormat["ReturnContent"] = "return-content";
})(KnownResponseFormat || (KnownResponseFormat = {}));
(function (KnownGeoReplicationStatusType) {
    KnownGeoReplicationStatusType["Live"] = "live";
    KnownGeoReplicationStatusType["Bootstrap"] = "bootstrap";
    KnownGeoReplicationStatusType["Unavailable"] = "unavailable";
})(exports.KnownGeoReplicationStatusType || (exports.KnownGeoReplicationStatusType = {}));

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
/**
 * Parse initializes the AccountSASPermissions fields from a string.
 *
 * @param permissions -
 */
function accountSasPermissionsFromString(permissions) {
    const accountSasPermissions = {};
    for (const c of permissions) {
        switch (c) {
            case "r":
                accountSasPermissions.query = true;
                break;
            case "w":
                accountSasPermissions.write = true;
                break;
            case "d":
                accountSasPermissions.delete = true;
                break;
            case "l":
                accountSasPermissions.list = true;
                break;
            case "a":
                accountSasPermissions.add = true;
                break;
            case "u":
                accountSasPermissions.update = true;
                break;
            default:
                throw new RangeError(`Invalid permission character: ${c}`);
        }
    }
    return accountSasPermissions;
}
/**
 * Produces the SAS permissions string for an Azure Storage account.
 * Call this method to set AccountSASSignatureValues Permissions field.
 *
 * Using this method will guarantee the resource types are in
 * an order accepted by the service.
 *
 * @see https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-an-account-sas
 *
 */
function accountSasPermissionsToString(permissions) {
    // The order of the characters should be as specified here to ensure correctness:
    // https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-an-account-sas
    // Use a string array instead of string concatenating += operator for performance
    const permissionString = [];
    if (permissions.query) {
        permissionString.push("r");
    }
    if (permissions.write) {
        permissionString.push("w");
    }
    if (permissions.delete) {
        permissionString.push("d");
    }
    if (permissions.list) {
        permissionString.push("l");
    }
    if (permissions.add) {
        permissionString.push("a");
    }
    if (permissions.update) {
        permissionString.push("u");
    }
    return permissionString.join("");
}

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
/**
 * Creates an {@link AccountSasServices} from the specified services string. This method will throw an
 * Error if it encounters a character that does not correspond to a valid service.
 *
 * @param services -
 */
function accountSasServicesFromString(services) {
    const accountSasServices = {};
    for (const c of services) {
        switch (c) {
            case "b":
                accountSasServices.blob = true;
                break;
            case "f":
                accountSasServices.file = true;
                break;
            case "q":
                accountSasServices.queue = true;
                break;
            case "t":
                accountSasServices.table = true;
                break;
            default:
                throw new RangeError(`Invalid service character: ${c}`);
        }
    }
    return accountSasServices;
}
/**
 * Converts the given services to a string.
 *
 */
function accountSasServicesToString(services = { table: true }) {
    const servicesString = [];
    if (services.blob) {
        servicesString.push("b");
    }
    if (services.table) {
        servicesString.push("t");
    }
    if (services.queue) {
        servicesString.push("q");
    }
    if (services.file) {
        servicesString.push("f");
    }
    return servicesString.join("");
}

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
/**
 * Generate SasIPRange format string. For example:
 *
 * "8.8.8.8" or "1.1.1.1-255.255.255.255"
 *
 * @param ipRange -
 */
function ipRangeToString(ipRange) {
    if (!ipRange) {
        return "";
    }
    return ipRange.end ? `${ipRange.start}-${ipRange.end}` : ipRange.start;
}

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
/**
 * Rounds a date off to seconds.
 *
 * @param date -
 * @param withMilliseconds - If true, YYYY-MM-DDThh:mm:ss.fffffffZ will be returned;
 *                                          If false, YYYY-MM-DDThh:mm:ssZ will be returned.
 * @returns Date string in ISO8061 format, with or without 7 milliseconds component
 */
function truncatedISO8061Date(date, withMilliseconds = true) {
    // Date.toISOString() will return like "2018-10-29T06:34:36.139Z"
    const dateString = date.toISOString();
    return withMilliseconds
        ? dateString.substring(0, dateString.length - 1) + "0000" + "Z"
        : dateString.substring(0, dateString.length - 5) + "Z";
}

// Copyright (c) Microsoft Corporation.
/**
 * Represents the components that make up an Azure SAS' query parameters. This type is not constructed directly
 * by the user; it is only generated by the {@link AccountSasSignatureValues} and {@link TableSasSignatureValues}
 * types. Once generated, it can be encoded into a `string` and appended to a URL directly (though caution should
 * be taken here in case there are existing query parameters, which might affect the appropriate means of appending
 * these query parameters).
 *
 * NOTE: Instances of this class are immutable.
 */
class SasQueryParameters {
    /**
     * Creates an instance of SASQueryParameters.
     *
     * @param version - Representing the table service version
     * @param signature - Representing the signature for the SAS token
     * @param options - Optional. Options to construct the SASQueryParameters.
     */
    constructor(version, signature, options = {}) {
        this.version = version;
        this.signature = signature;
        this.permissions = options.permissions;
        this.services = options.services;
        this.resourceTypes = options.resourceTypes;
        this.protocol = options.protocol;
        this.startsOn = options.startsOn;
        this.expiresOn = options.expiresOn;
        this.ipRangeInner = options.ipRange;
        this.identifier = options.identifier;
        this.tableName = options.tableName;
        if (options.userDelegationKey) {
            this.signedOid = options.userDelegationKey.signedObjectId;
            this.signedTenantId = options.userDelegationKey.signedTenantId;
            this.signedStartsOn = options.userDelegationKey.signedStartsOn;
            this.signedExpiresOn = options.userDelegationKey.signedExpiresOn;
            this.signedService = options.userDelegationKey.signedService;
            this.signedVersion = options.userDelegationKey.signedVersion;
            this.preauthorizedAgentObjectId = options.preauthorizedAgentObjectId;
            this.correlationId = options.correlationId;
        }
    }
    /**
     * Optional. IP range allowed for this SAS.
     *
     * @readonly
     */
    get ipRange() {
        if (this.ipRangeInner) {
            return {
                end: this.ipRangeInner.end,
                start: this.ipRangeInner.start,
            };
        }
        return undefined;
    }
    /**
     * Encodes all SAS query parameters into a string that can be appended to a URL.
     *
     */
    toString() {
        const params = [
            "sv",
            "ss",
            "srt",
            "spr",
            "st",
            "se",
            "sip",
            "si",
            "skoid",
            "sktid",
            "skt",
            "ske",
            "sks",
            "skv",
            "sr",
            "sp",
            "sig",
            "rscc",
            "rscd",
            "rsce",
            "rscl",
            "rsct",
            "saoid",
            "scid",
            "tn", // TableName
        ];
        const queries = [];
        for (const param of params) {
            switch (param) {
                case "sv":
                    this.tryAppendQueryParameter(queries, param, this.version);
                    break;
                case "ss":
                    this.tryAppendQueryParameter(queries, param, this.services);
                    break;
                case "srt":
                    this.tryAppendQueryParameter(queries, param, this.resourceTypes);
                    break;
                case "spr":
                    this.tryAppendQueryParameter(queries, param, this.protocol);
                    break;
                case "st":
                    this.tryAppendQueryParameter(queries, param, this.startsOn ? truncatedISO8061Date(this.startsOn, false) : undefined);
                    break;
                case "se":
                    this.tryAppendQueryParameter(queries, param, this.expiresOn ? truncatedISO8061Date(this.expiresOn, false) : undefined);
                    break;
                case "sip":
                    this.tryAppendQueryParameter(queries, param, this.ipRange ? ipRangeToString(this.ipRange) : undefined);
                    break;
                case "si":
                    this.tryAppendQueryParameter(queries, param, this.identifier);
                    break;
                case "skoid": // Signed object ID
                    this.tryAppendQueryParameter(queries, param, this.signedOid);
                    break;
                case "sktid": // Signed tenant ID
                    this.tryAppendQueryParameter(queries, param, this.signedTenantId);
                    break;
                case "skt": // Signed key start time
                    this.tryAppendQueryParameter(queries, param, this.signedStartsOn ? truncatedISO8061Date(this.signedStartsOn, false) : undefined);
                    break;
                case "ske": // Signed key expiry time
                    this.tryAppendQueryParameter(queries, param, this.signedExpiresOn ? truncatedISO8061Date(this.signedExpiresOn, false) : undefined);
                    break;
                case "sks": // Signed key service
                    this.tryAppendQueryParameter(queries, param, this.signedService);
                    break;
                case "skv": // Signed key version
                    this.tryAppendQueryParameter(queries, param, this.signedVersion);
                    break;
                case "sp":
                    this.tryAppendQueryParameter(queries, param, this.permissions);
                    break;
                case "sig":
                    this.tryAppendQueryParameter(queries, param, this.signature);
                    break;
                case "saoid":
                    this.tryAppendQueryParameter(queries, param, this.preauthorizedAgentObjectId);
                    break;
                case "scid":
                    this.tryAppendQueryParameter(queries, param, this.correlationId);
                    break;
                case "tn":
                    this.tryAppendQueryParameter(queries, param, this.tableName);
                    break;
            }
        }
        return queries.join("&");
    }
    /**
     * A private helper method used to filter and append query key/value pairs into an array.
     *
     * @param queries -
     * @param key -
     * @param value -
     */
    tryAppendQueryParameter(queries, key, value) {
        if (!value) {
            return;
        }
        key = encodeURIComponent(key);
        value = encodeURIComponent(value);
        if (key.length > 0 && value.length > 0) {
            queries.push(`${key}=${value}`);
        }
    }
}

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
/**
 * Creates an {@link accountSasResourceTypesFromString} from the specified resource types string. This method will throw an
 * Error if it encounters a character that does not correspond to a valid resource type.
 *
 * @param resourceTypes -
 */
function accountSasResourceTypesFromString(resourceTypes) {
    const accountSasResourceTypes = {};
    for (const c of resourceTypes) {
        switch (c) {
            case "s":
                accountSasResourceTypes.service = true;
                break;
            case "c":
                accountSasResourceTypes.container = true;
                break;
            case "o":
                accountSasResourceTypes.object = true;
                break;
            default:
                throw new RangeError(`Invalid resource type: ${c}`);
        }
    }
    return accountSasResourceTypes;
}
/**
 * Converts the given resource types to a string.
 *
 * @see https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-an-account-sas
 *
 */
function accountSasResourceTypesToString(resourceTypes) {
    const resourceTypesString = [];
    if (resourceTypes.service) {
        resourceTypesString.push("s");
    }
    if (resourceTypes.container) {
        resourceTypesString.push("c");
    }
    if (resourceTypes.object) {
        resourceTypesString.push("o");
    }
    return resourceTypesString.join("");
}

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
const SERVICE_VERSION = "2019-02-02";
const TRANSACTION_HTTP_VERSION_1_1 = "HTTP/1.1";
const TRANSACTION_HTTP_LINE_ENDING = "\r\n";
const STORAGE_SCOPE = "https://storage.azure.com/.default";
const HeaderConstants = {
    AUTHORIZATION: "authorization",
    CONTENT_LENGTH: "content-length",
    CONTENT_MD5: "content-md5",
    CONTENT_TYPE: "content-type",
    CONTENT_TRANSFER_ENCODING: "content-transfer-encoding",
    DATE: "date",
    X_MS_DATE: "x-ms-date",
    X_MS_VERSION: "x-ms-version",
};
const TablesLoggingAllowedHeaderNames = [
    "Access-Control-Allow-Origin",
    "Cache-Control",
    "Content-Length",
    "Content-Type",
    "Date",
    "Prefer",
    "Preference-Applied",
    "Request-Id",
    "traceparent",
    "Transfer-Encoding",
    "User-Agent",
    "x-ms-client-request-id",
    "x-ms-user-agent",
    "x-ms-date",
    "x-ms-error-code",
    "x-ms-request-id",
    "x-ms-return-client-request-id",
    "x-ms-version",
    "Accept-Ranges",
    "Accept",
    "Content-Disposition",
    "Content-Encoding",
    "Content-Language",
    "Content-MD5",
    "Content-Range",
    "ETag",
    "Last-Modified",
    "Server",
    "Vary",
    "x-ms-content-crc64",
    "x-ms-copy-action",
    "x-ms-copy-completion-time",
    "x-ms-copy-id",
    "x-ms-copy-progress",
    "x-ms-copy-status",
    "x-ms-continuation-NextTableName",
    "x-ms-continuation-NextPartitionKey",
    "x-ms-continuation-NextRowKey",
    "x-ms-has-immutability-policy",
    "x-ms-has-legal-hold",
    "x-ms-lease-state",
    "x-ms-lease-status",
    "x-ms-range",
    "x-ms-request-server-encrypted",
    "x-ms-server-encrypted",
    "x-ms-snapshot",
    "x-ms-source-range",
    "If-Match",
    "If-Modified-Since",
    "If-None-Match",
    "If-Unmodified-Since",
    "x-ms-access-tier",
    "x-ms-access-tier-change-time",
    "x-ms-access-tier-inferred",
    "x-ms-account-kind",
    "x-ms-archive-status",
    "x-ms-copy-destination-snapshot",
    "x-ms-creation-time",
    "x-ms-default-encryption-scope",
    "x-ms-delete-type-permanent",
    "x-ms-deny-encryption-scope-override",
    "x-ms-encryption-algorithm",
    "x-ms-incremental-copy",
    "x-ms-lease-action",
    "x-ms-lease-break-period",
    "x-ms-lease-duration",
    "x-ms-lease-id",
    "x-ms-lease-time",
    "x-ms-page-write",
    "x-ms-proposed-lease-id",
    "x-ms-range-get-content-md5",
    "x-ms-rehydrate-priority",
    "x-ms-sequence-number-action",
    "x-ms-sku-name",
    "x-ms-source-content-md5",
    "x-ms-source-if-match",
    "x-ms-source-if-modified-since",
    "x-ms-source-if-none-match",
    "x-ms-source-if-unmodified-since",
    "x-ms-tag-count",
    "x-ms-encryption-key-sha256",
];

// Copyright (c) Microsoft Corporation.
function computeHMACSHA256(stringToSign, accountKey) {
    const key = Buffer.from(accountKey, "base64");
    return crypto.createHmac("sha256", key).update(stringToSign, "utf8").digest("base64");
}

// Copyright (c) Microsoft Corporation.
/**
 * ONLY AVAILABLE IN NODE.JS RUNTIME.
 *
 * Generates a {@link SasQueryParameters} object which contains all SAS query parameters needed to make an actual
 * REST request.
 *
 * @see https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-an-account-sas
 *
 * @param accountSasSignatureValues -
 * @param sharedKeyCredential -
 */
function generateAccountSasQueryParameters(accountSasSignatureValues, credential) {
    const version = accountSasSignatureValues.version
        ? accountSasSignatureValues.version
        : SERVICE_VERSION;
    const parsedPermissions = accountSasPermissionsToString(accountSasSignatureValues.permissions);
    const parsedServices = accountSasServicesToString(accountSasServicesFromString(accountSasSignatureValues.services));
    // to and from string to guarantee the correct order of resoruce types is generated
    const parsedResourceTypes = accountSasResourceTypesToString(accountSasResourceTypesFromString(accountSasSignatureValues.resourceTypes));
    const stringToSign = [
        credential.name,
        parsedPermissions,
        parsedServices,
        parsedResourceTypes,
        accountSasSignatureValues.startsOn
            ? truncatedISO8061Date(accountSasSignatureValues.startsOn, false)
            : "",
        truncatedISO8061Date(accountSasSignatureValues.expiresOn, false),
        accountSasSignatureValues.ipRange ? ipRangeToString(accountSasSignatureValues.ipRange) : "",
        accountSasSignatureValues.protocol ? accountSasSignatureValues.protocol : "",
        version,
        "", // Account SAS requires an additional newline character
    ].join("\n");
    const signature = computeHMACSHA256(stringToSign, credential.key);
    return new SasQueryParameters(version, signature, {
        permissions: parsedPermissions.toString(),
        services: parsedServices,
        resourceTypes: parsedResourceTypes,
        protocol: accountSasSignatureValues.protocol,
        startsOn: accountSasSignatureValues.startsOn,
        expiresOn: accountSasSignatureValues.expiresOn,
        ipRange: accountSasSignatureValues.ipRange,
    });
}

// Copyright (c) Microsoft Corporation.
/**
 * Generates a Table Account 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://docs.microsoft.com/en-us/rest/api/storageservices/create-account-sas
 *
 * @param options - Optional parameters.
 * @returns An account SAS token
 */
function generateAccountSas(credential, options = {}) {
    const { expiresOn, permissions = accountSasPermissionsFromString("rl"), resourceTypes = "sco", services = accountSasServicesFromString("t") } = options, rest = tslib.__rest(options, ["expiresOn", "permissions", "resourceTypes", "services"]);
    if (!coreAuth.isNamedKeyCredential(credential)) {
        throw RangeError("Can only generate the account SAS when the client is initialized with a shared key credential");
    }
    let expiry = expiresOn;
    if (expiry === undefined) {
        const now = new Date();
        expiry = new Date(now.getTime() + 3600 * 1000);
    }
    const sas = generateAccountSasQueryParameters(Object.assign({ permissions, expiresOn: expiry, resourceTypes, services: accountSasServicesToString(services) }, rest), credential).toString();
    return sas;
}

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
/**
 * Creates a {@link TableSasPermissions} from the specified permissions string. This method will throw an
 * Error if it encounters a character that does not correspond to a valid permission.
 *
 * @param permissions -
 */
function tableSasPermissionsFromString(permissions) {
    const tableSasPermissions = {};
    for (const char of permissions) {
        switch (char) {
            case "r":
                tableSasPermissions.query = true;
                break;
            case "a":
                tableSasPermissions.add = true;
                break;
            case "u":
                tableSasPermissions.update = true;
                break;
            case "d":
                tableSasPermissions.delete = true;
                break;
            default:
                throw new RangeError(`Invalid permission: ${char}`);
        }
    }
    return tableSasPermissions;
}
/**
 * Converts the given permissions to a string. Using this method will guarantee the permissions are in an
 * order accepted by the service.
 *
 * @returns A string which represents the TableSasPermissions
 */
function tableSasPermissionsToString(permissions) {
    if (!permissions) {
        return "";
    }
    const permissionsString = [];
    if (permissions.query) {
        permissionsString.push("r");
    }
    if (permissions.add) {
        permissionsString.push("a");
    }
    if (permissions.update) {
        permissionsString.push("u");
    }
    if (permissions.delete) {
        permissionsString.push("d");
    }
    return permissionsString.join("");
}

// Copyright (c) Microsoft Corporation.
/**
 * ONLY AVAILABLE IN NODE.JS RUNTIME.
 *
 * Creates an instance of SASQueryParameters.
 *
 * **Note**: When identifier is not provided, permissions has a default value of "read" and expiresOn of one hour from the time the token is generated.
 */
function generateTableSasQueryParameters(tableName, credential, tableSasSignatureValues) {
    var _a, _b, _c, _d, _e, _f;
    const version = (_a = tableSasSignatureValues.version) !== null && _a !== void 0 ? _a : SERVICE_VERSION;
    if (credential === undefined) {
        throw TypeError("Invalid NamedKeyCredential");
    }
    if (!tableName) {
        throw new Error("Must provide a 'tableName'");
    }
    const signedPermissions = tableSasPermissionsToString(tableSasSignatureValues.permissions);
    const signedStart = tableSasSignatureValues.startsOn
        ? truncatedISO8061Date(tableSasSignatureValues.startsOn, false /** withMilliseconds */)
        : "";
    const signedExpiry = tableSasSignatureValues.expiresOn
        ? truncatedISO8061Date(tableSasSignatureValues.expiresOn, false /** withMilliseconds */)
        : "";
    const canonicalizedResource = getCanonicalName(credential.name, tableName);
    const signedIdentifier = (_b = tableSasSignatureValues.identifier) !== null && _b !== void 0 ? _b : "";
    const signedIP = ipRangeToString(tableSasSignatureValues.ipRange);
    const signedProtocol = tableSasSignatureValues.protocol || "";
    const startingPartitionKey = (_c = tableSasSignatureValues.startPartitionKey) !== null && _c !== void 0 ? _c : "";
    const startingRowKey = (_d = tableSasSignatureValues.startRowKey) !== null && _d !== void 0 ? _d : "";
    const endingPartitionKey = (_e = tableSasSignatureValues.endPartitionKey) !== null && _e !== void 0 ? _e : "";
    const endingRowKey = (_f = tableSasSignatureValues.endRowKey) !== null && _f !== void 0 ? _f : "";
    const stringToSign = [
        signedPermissions,
        signedStart,
        signedExpiry,
        canonicalizedResource,
        signedIdentifier,
        signedIP,
        signedProtocol,
        version,
        startingPartitionKey,
        startingRowKey,
        endingPartitionKey,
        endingRowKey,
    ].join("\n");
    const signature = computeHMACSHA256(stringToSign, credential.key);
    return new SasQueryParameters(version, signature, {
        permissions: signedPermissions,
        protocol: tableSasSignatureValues.protocol,
        startsOn: tableSasSignatureValues.startsOn,
        expiresOn: tableSasSignatureValues.expiresOn,
        ipRange: tableSasSignatureValues.ipRange,
        identifier: tableSasSignatureValues.identifier,
        tableName,
    });
}
function getCanonicalName(accountName, tableName) {
    // Sample CanonicalName for URL = https://myaccount.table.core.windows.net/Employees(PartitionKey='Jeff',RowKey='Price'):
    //   canonicalizedResource = "/table/myaccount/employees"
    return `/table/${accountName}/${tableName.toLowerCase()}`;
}

// Copyright (c) Microsoft Corporation.
/**
 * Generates a Table 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://docs.microsoft.com/en-us/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.
 */
function generateTableSas(tableName, credential, options = {}) {
    let { expiresOn, permissions } = options;
    if (!coreAuth.isNamedKeyCredential(credential)) {
        throw RangeError("Can only generate the account SAS when the client is initialized with a shared key credential");
    }
    // expiresOn and permissions are optional if an identifier is provided
    // set defaults when no identifier and no values were provided
    if (!options.identifier) {
        if (!permissions) {
            permissions = tableSasPermissionsFromString("r");
        }
        if (expiresOn === undefined) {
            const now = new Date();
            expiresOn = new Date(now.getTime() + 3600 * 1000);
        }
    }
    const sas = generateTableSasQueryParameters(tableName, credential, Object.assign(Object.assign({}, options), { expiresOn,
        permissions })).toString();
    return sas;
}

/*
 * Copyright (c) Microsoft Corporation.
 * Licensed under the MIT License.
 *
 * Code generated by Microsoft (R) AutoRest Code Generator.
 * Changes may cause incorrect behavior and will be lost if the code is regenerated.
 */
const TableQueryResponse = {
    serializedName: "TableQueryResponse",
    type: {
        name: "Composite",
        className: "TableQueryResponse",
        modelProperties: {
            odataMetadata: {
                serializedName: "odata\\.metadata",
                xmlName: "odata\\.metadata",
                type: {
                    name: "String"
                }
            },
            value: {
                serializedName: "value",
                xmlName: "value",
                xmlElementName: "TableResponseProperties",
                type: {
                    name: "Sequence",
                    element: {
                        type: {
                            name: "Composite",
                            className: "TableResponseProperties"
                        }
                    }
                }
            }
        }
    }
};
const TableResponseProperties = {
    serializedName: "TableResponseProperties",
    type: {
        name: "Composite",
        className: "TableResponseProperties",
        modelProperties: {
            name: {
                serializedName: "TableName",
                xmlName: "TableName",
                type: {
                    name: "String"
                }
            },
            odataType: {
                serializedName: "odata\\.type",
                xmlName: "odata\\.type",
                type: {
                    name: "String"
                }
            },
            odataId: {
                serializedName: "odata\\.id",
                xmlName: "odata\\.id",
                type: {
                    name: "String"
                }
            },
            odataEditLink: {
                serializedName: "odata\\.editLink",
                xmlName: "odata\\.editLink",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableServiceError = {
    serializedName: "TableServiceError",
    type: {
        name: "Composite",
        className: "TableServiceError",
        modelProperties: {
            odataError: {
                serializedName: "odata\\.error",
                xmlName: "odata\\.error",
                type: {
                    name: "Composite",
                    className: "TableServiceErrorOdataError"
                }
            }
        }
    }
};
const TableServiceErrorOdataError = {
    serializedName: "TableServiceErrorOdataError",
    type: {
        name: "Composite",
        className: "TableServiceErrorOdataError",
        modelProperties: {
            code: {
                serializedName: "code",
                xmlName: "code",
                type: {
                    name: "String"
                }
            },
            message: {
                serializedName: "message",
                xmlName: "message",
                type: {
                    name: "Composite",
                    className: "TableServiceErrorOdataErrorMessage"
                }
            }
        }
    }
};
const TableServiceErrorOdataErrorMessage = {
    serializedName: "TableServiceErrorOdataErrorMessage",
    type: {
        name: "Composite",
        className: "TableServiceErrorOdataErrorMessage",
        modelProperties: {
            lang: {
                serializedName: "lang",
                xmlName: "lang",
                type: {
                    name: "String"
                }
            },
            value: {
                serializedName: "value",
                xmlName: "value",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableProperties = {
    serializedName: "TableProperties",
    type: {
        name: "Composite",
        className: "TableProperties",
        modelProperties: {
            name: {
                serializedName: "TableName",
                xmlName: "TableName",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableEntityQueryResponse = {
    serializedName: "TableEntityQueryResponse",
    type: {
        name: "Composite",
        className: "TableEntityQueryResponse",
        modelProperties: {
            odataMetadata: {
                serializedName: "odata\\.metadata",
                xmlName: "odata\\.metadata",
                type: {
                    name: "String"
                }
            },
            value: {
                serializedName: "value",
                xmlName: "value",
                xmlElementName: "TableEntityProperties",
                type: {
                    name: "Sequence",
                    element: {
                        type: {
                            name: "Dictionary",
                            value: { type: { name: "any" } }
                        }
                    }
                }
            }
        }
    }
};
const SignedIdentifier = {
    serializedName: "SignedIdentifier",
    xmlName: "SignedIdentifier",
    type: {
        name: "Composite",
        className: "SignedIdentifier",
        modelProperties: {
            id: {
                serializedName: "Id",
                required: true,
                xmlName: "Id",
                type: {
                    name: "String"
                }
            },
            accessPolicy: {
                serializedName: "AccessPolicy",
                xmlName: "AccessPolicy",
                type: {
                    name: "Composite",
                    className: "AccessPolicy"
                }
            }
        }
    }
};
const AccessPolicy = {
    serializedName: "AccessPolicy",
    xmlName: "AccessPolicy",
    type: {
        name: "Composite",
        className: "AccessPolicy",
        modelProperties: {
            start: {
                serializedName: "Start",
                xmlName: "Start",
                type: {
                    name: "String"
                }
            },
            expiry: {
                serializedName: "Expiry",
                xmlName: "Expiry",
                type: {
                    name: "String"
                }
            },
            permission: {
                serializedName: "Permission",
                xmlName: "Permission",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableServiceProperties = {
    serializedName: "TableServiceProperties",
    xmlName: "StorageServiceProperties",
    type: {
        name: "Composite",
        className: "TableServiceProperties",
        modelProperties: {
            logging: {
                serializedName: "Logging",
                xmlName: "Logging",
                type: {
                    name: "Composite",
                    className: "Logging"
                }
            },
            hourMetrics: {
                serializedName: "HourMetrics",
                xmlName: "HourMetrics",
                type: {
                    name: "Composite",
                    className: "Metrics"
                }
            },
            minuteMetrics: {
                serializedName: "MinuteMetrics",
                xmlName: "MinuteMetrics",
                type: {
                    name: "Composite",
                    className: "Metrics"
                }
            },
            cors: {
                serializedName: "Cors",
                xmlName: "Cors",
                xmlIsWrapped: true,
                xmlElementName: "CorsRule",
                type: {
                    name: "Sequence",
                    element: {
                        type: {
                            name: "Composite",
                            className: "CorsRule"
                        }
                    }
                }
            }
        }
    }
};
const Logging = {
    serializedName: "Logging",
    xmlName: "Logging",
    type: {
        name: "Composite",
        className: "Logging",
        modelProperties: {
            version: {
                serializedName: "Version",
                required: true,
                xmlName: "Version",
                type: {
                    name: "String"
                }
            },
            delete: {
                serializedName: "Delete",
                required: true,
                xmlName: "Delete",
                type: {
                    name: "Boolean"
                }
            },
            read: {
                serializedName: "Read",
                required: true,
                xmlName: "Read",
                type: {
                    name: "Boolean"
                }
            },
            write: {
                serializedName: "Write",
                required: true,
                xmlName: "Write",
                type: {
                    name: "Boolean"
                }
            },
            retentionPolicy: {
                serializedName: "RetentionPolicy",
                xmlName: "RetentionPolicy",
                type: {
                    name: "Composite",
                    className: "RetentionPolicy"
                }
            }
        }
    }
};
const RetentionPolicy = {
    serializedName: "RetentionPolicy",
    xmlName: "RetentionPolicy",
    type: {
        name: "Composite",
        className: "RetentionPolicy",
        modelProperties: {
            enabled: {
                serializedName: "Enabled",
                required: true,
                xmlName: "Enabled",
                type: {
                    name: "Boolean"
                }
            },
            days: {
                constraints: {
                    InclusiveMinimum: 1
                },
                serializedName: "Days",
                xmlName: "Days",
                type: {
                    name: "Number"
                }
            }
        }
    }
};
const Metrics = {
    serializedName: "Metrics",
    type: {
        name: "Composite",
        className: "Metrics",
        modelProperties: {
            version: {
                serializedName: "Version",
                xmlName: "Version",
                type: {
                    name: "String"
                }
            },
            enabled: {
                serializedName: "Enabled",
                required: true,
                xmlName: "Enabled",
                type: {
                    name: "Boolean"
                }
            },
            includeAPIs: {
                serializedName: "IncludeAPIs",
                xmlName: "IncludeAPIs",
                type: {
                    name: "Boolean"
                }
            },
            retentionPolicy: {
                serializedName: "RetentionPolicy",
                xmlName: "RetentionPolicy",
                type: {
                    name: "Composite",
                    className: "RetentionPolicy"
                }
            }
        }
    }
};
const CorsRule = {
    serializedName: "CorsRule",
    xmlName: "CorsRule",
    type: {
        name: "Composite",
        className: "CorsRule",
        modelProperties: {
            allowedOrigins: {
                serializedName: "AllowedOrigins",
                required: true,
                xmlName: "AllowedOrigins",
                type: {
                    name: "String"
                }
            },
            allowedMethods: {
                serializedName: "AllowedMethods",
                required: true,
                xmlName: "AllowedMethods",
                type: {
                    name: "String"
                }
            },
            allowedHeaders: {
                serializedName: "AllowedHeaders",
                required: true,
                xmlName: "AllowedHeaders",
                type: {
                    name: "String"
                }
            },
            exposedHeaders: {
                serializedName: "ExposedHeaders",
                required: true,
                xmlName: "ExposedHeaders",
                type: {
                    name: "String"
                }
            },
            maxAgeInSeconds: {
                constraints: {
                    InclusiveMinimum: 0
                },
                serializedName: "MaxAgeInSeconds",
                required: true,
                xmlName: "MaxAgeInSeconds",
                type: {
                    name: "Number"
                }
            }
        }
    }
};
const TableServiceStats = {
    serializedName: "TableServiceStats",
    xmlName: "StorageServiceStats",
    type: {
        name: "Composite",
        className: "TableServiceStats",
        modelProperties: {
            geoReplication: {
                serializedName: "GeoReplication",
                xmlName: "GeoReplication",
                type: {
                    name: "Composite",
                    className: "GeoReplication"
                }
            }
        }
    }
};
const GeoReplication = {
    serializedName: "GeoReplication",
    xmlName: "GeoReplication",
    type: {
        name: "Composite",
        className: "GeoReplication",
        modelProperties: {
            status: {
                serializedName: "Status",
                required: true,
                xmlName: "Status",
                type: {
                    name: "String"
                }
            },
            lastSyncTime: {
                serializedName: "LastSyncTime",
                required: true,
                xmlName: "LastSyncTime",
                type: {
                    name: "DateTimeRfc1123"
                }
            }
        }
    }
};
const TableResponse = {
    serializedName: "TableResponse",
    type: {
        name: "Composite",
        className: "TableResponse",
        modelProperties: Object.assign(Object.assign({}, TableResponseProperties.type.modelProperties), { odataMetadata: {
                serializedName: "odata\\.metadata",
                xmlName: "odata\\.metadata",
                type: {
                    name: "String"
                }
            } })
    }
};
const TableQueryHeaders = {
    serializedName: "Table_queryHeaders",
    type: {
        name: "Composite",
        className: "TableQueryHeaders",
        modelProperties: {
            clientRequestId: {
                serializedName: "x-ms-client-request-id",
                xmlName: "x-ms-client-request-id",
                type: {
                    name: "String"
                }
            },
            requestId: {
                serializedName: "x-ms-request-id",
                xmlName: "x-ms-request-id",
                type: {
                    name: "String"
                }
            },
            version: {
                serializedName: "x-ms-version",
                xmlName: "x-ms-version",
                type: {
                    name: "String"
                }
            },
            date: {
                serializedName: "date",
                xmlName: "date",
                type: {
                    name: "DateTimeRfc1123"
                }
            },
            xMsContinuationNextTableName: {
                serializedName: "x-ms-continuation-nexttablename",
                xmlName: "x-ms-continuation-nexttablename",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableQueryExceptionHeaders = {
    serializedName: "Table_queryExceptionHeaders",
    type: {
        name: "Composite",
        className: "TableQueryExceptionHeaders",
        modelProperties: {
            errorCode: {
                serializedName: "x-ms-error-code",
                xmlName: "x-ms-error-code",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableCreateHeaders = {
    serializedName: "Table_createHeaders",
    type: {
        name: "Composite",
        className: "TableCreateHeaders",
        modelProperties: {
            clientRequestId: {
                serializedName: "x-ms-client-request-id",
                xmlName: "x-ms-client-request-id",
                type: {
                    name: "String"
                }
            },
            requestId: {
                serializedName: "x-ms-request-id",
                xmlName: "x-ms-request-id",
                type: {
                    name: "String"
                }
            },
            version: {
                serializedName: "x-ms-version",
                xmlName: "x-ms-version",
                type: {
                    name: "String"
                }
            },
            date: {
                serializedName: "date",
                xmlName: "date",
                type: {
                    name: "DateTimeRfc1123"
                }
            },
            preferenceApplied: {
                serializedName: "preference-applied",
                xmlName: "preference-applied",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableCreateExceptionHeaders = {
    serializedName: "Table_createExceptionHeaders",
    type: {
        name: "Composite",
        className: "TableCreateExceptionHeaders",
        modelProperties: {
            errorCode: {
                serializedName: "x-ms-error-code",
                xmlName: "x-ms-error-code",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableDeleteHeaders = {
    serializedName: "Table_deleteHeaders",
    type: {
        name: "Composite",
        className: "TableDeleteHeaders",
        modelProperties: {
            clientRequestId: {
                serializedName: "x-ms-client-request-id",
                xmlName: "x-ms-client-request-id",
                type: {
                    name: "String"
                }
            },
            requestId: {
                serializedName: "x-ms-request-id",
                xmlName: "x-ms-request-id",
                type: {
                    name: "String"
                }
            },
            version: {
                serializedName: "x-ms-version",
                xmlName: "x-ms-version",
                type: {
                    name: "String"
                }
            },
            date: {
                serializedName: "date",
                xmlName: "date",
                type: {
                    name: "DateTimeRfc1123"
                }
            }
        }
    }
};
const TableDeleteExceptionHeaders = {
    serializedName: "Table_deleteExceptionHeaders",
    type: {
        name: "Composite",
        className: "TableDeleteExceptionHeaders",
        modelProperties: {
            errorCode: {
                serializedName: "x-ms-error-code",
                xmlName: "x-ms-error-code",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableQueryEntitiesHeaders = {
    serializedName: "Table_queryEntitiesHeaders",
    type: {
        name: "Composite",
        className: "TableQueryEntitiesHeaders",
        modelProperties: {
            clientRequestId: {
                serializedName: "x-ms-client-request-id",
                xmlName: "x-ms-client-request-id",
                type: {
                    name: "String"
                }
            },
            requestId: {
                serializedName: "x-ms-request-id",
                xmlName: "x-ms-request-id",
                type: {
                    name: "String"
                }
            },
            version: {
                serializedName: "x-ms-version",
                xmlName: "x-ms-version",
                type: {
                    name: "String"
                }
            },
            date: {
                serializedName: "date",
                xmlName: "date",
                type: {
                    name: "DateTimeRfc1123"
                }
            },
            xMsContinuationNextPartitionKey: {
                serializedName: "x-ms-continuation-nextpartitionkey",
                xmlName: "x-ms-continuation-nextpartitionkey",
                type: {
                    name: "String"
                }
            },
            xMsContinuationNextRowKey: {
                serializedName: "x-ms-continuation-nextrowkey",
                xmlName: "x-ms-continuation-nextrowkey",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableQueryEntitiesExceptionHeaders = {
    serializedName: "Table_queryEntitiesExceptionHeaders",
    type: {
        name: "Composite",
        className: "TableQueryEntitiesExceptionHeaders",
        modelProperties: {
            errorCode: {
                serializedName: "x-ms-error-code",
                xmlName: "x-ms-error-code",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableQueryEntitiesWithPartitionAndRowKeyHeaders = {
    serializedName: "Table_queryEntitiesWithPartitionAndRowKeyHeaders",
    type: {
        name: "Composite",
        className: "TableQueryEntitiesWithPartitionAndRowKeyHeaders",
        modelProperties: {
            clientRequestId: {
                serializedName: "x-ms-client-request-id",
                xmlName: "x-ms-client-request-id",
                type: {
                    name: "String"
                }
            },
            requestId: {
                serializedName: "x-ms-request-id",
                xmlName: "x-ms-request-id",
                type: {
                    name: "String"
                }
            },
            version: {
                serializedName: "x-ms-version",
                xmlName: "x-ms-version",
                type: {
                    name: "String"
                }
            },
            date: {
                serializedName: "date",
                xmlName: "date",
                type: {
                    name: "DateTimeRfc1123"
                }
            },
            etag: {
                serializedName: "etag",
                xmlName: "etag",
                type: {
                    name: "String"
                }
            },
            xMsContinuationNextPartitionKey: {
                serializedName: "x-ms-continuation-nextpartitionkey",
                xmlName: "x-ms-continuation-nextpartitionkey",
                type: {
                    name: "String"
                }
            },
            xMsContinuationNextRowKey: {
                serializedName: "x-ms-continuation-nextrowkey",
                xmlName: "x-ms-continuation-nextrowkey",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableQueryEntitiesWithPartitionAndRowKeyExceptionHeaders = {
    serializedName: "Table_queryEntitiesWithPartitionAndRowKeyExceptionHeaders",
    type: {
        name: "Composite",
        className: "TableQueryEntitiesWithPartitionAndRowKeyExceptionHeaders",
        modelProperties: {
            errorCode: {
                serializedName: "x-ms-error-code",
                xmlName: "x-ms-error-code",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableUpdateEntityHeaders = {
    serializedName: "Table_updateEntityHeaders",
    type: {
        name: "Composite",
        className: "TableUpdateEntityHeaders",
        modelProperties: {
            clientRequestId: {
                serializedName: "x-ms-client-request-id",
                xmlName: "x-ms-client-request-id",
                type: {
                    name: "String"
                }
            },
            requestId: {
                serializedName: "x-ms-request-id",
                xmlName: "x-ms-request-id",
                type: {
                    name: "String"
                }
            },
            version: {
                serializedName: "x-ms-version",
                xmlName: "x-ms-version",
                type: {
                    name: "String"
                }
            },
            date: {
                serializedName: "date",
                xmlName: "date",
                type: {
                    name: "DateTimeRfc1123"
                }
            },
            etag: {
                serializedName: "etag",
                xmlName: "etag",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableUpdateEntityExceptionHeaders = {
    serializedName: "Table_updateEntityExceptionHeaders",
    type: {
        name: "Composite",
        className: "TableUpdateEntityExceptionHeaders",
        modelProperties: {
            errorCode: {
                serializedName: "x-ms-error-code",
                xmlName: "x-ms-error-code",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableMergeEntityHeaders = {
    serializedName: "Table_mergeEntityHeaders",
    type: {
        name: "Composite",
        className: "TableMergeEntityHeaders",
        modelProperties: {
            clientRequestId: {
                serializedName: "x-ms-client-request-id",
                xmlName: "x-ms-client-request-id",
                type: {
                    name: "String"
                }
            },
            requestId: {
                serializedName: "x-ms-request-id",
                xmlName: "x-ms-request-id",
                type: {
                    name: "String"
                }
            },
            version: {
                serializedName: "x-ms-version",
                xmlName: "x-ms-version",
                type: {
                    name: "String"
                }
            },
            date: {
                serializedName: "date",
                xmlName: "date",
                type: {
                    name: "DateTimeRfc1123"
                }
            },
            etag: {
                serializedName: "etag",
                xmlName: "etag",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableMergeEntityExceptionHeaders = {
    serializedName: "Table_mergeEntityExceptionHeaders",
    type: {
        name: "Composite",
        className: "TableMergeEntityExceptionHeaders",
        modelProperties: {
            errorCode: {
                serializedName: "x-ms-error-code",
                xmlName: "x-ms-error-code",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableDeleteEntityHeaders = {
    serializedName: "Table_deleteEntityHeaders",
    type: {
        name: "Composite",
        className: "TableDeleteEntityHeaders",
        modelProperties: {
            clientRequestId: {
                serializedName: "x-ms-client-request-id",
                xmlName: "x-ms-client-request-id",
                type: {
                    name: "String"
                }
            },
            requestId: {
                serializedName: "x-ms-request-id",
                xmlName: "x-ms-request-id",
                type: {
                    name: "String"
                }
            },
            version: {
                serializedName: "x-ms-version",
                xmlName: "x-ms-version",
                type: {
                    name: "String"
                }
            },
            date: {
                serializedName: "date",
                xmlName: "date",
                type: {
                    name: "DateTimeRfc1123"
                }
            }
        }
    }
};
const TableDeleteEntityExceptionHeaders = {
    serializedName: "Table_deleteEntityExceptionHeaders",
    type: {
        name: "Composite",
        className: "TableDeleteEntityExceptionHeaders",
        modelProperties: {
            errorCode: {
                serializedName: "x-ms-error-code",
                xmlName: "x-ms-error-code",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableInsertEntityHeaders = {
    serializedName: "Table_insertEntityHeaders",
    type: {
        name: "Composite",
        className: "TableInsertEntityHeaders",
        modelProperties: {
            clientRequestId: {
                serializedName: "x-ms-client-request-id",
                xmlName: "x-ms-client-request-id",
                type: {
                    name: "String"
                }
            },
            requestId: {
                serializedName: "x-ms-request-id",
                xmlName: "x-ms-request-id",
                type: {
                    name: "String"
                }
            },
            version: {
                serializedName: "x-ms-version",
                xmlName: "x-ms-version",
                type: {
                    name: "String"
                }
            },
            date: {
                serializedName: "date",
                xmlName: "date",
                type: {
                    name: "DateTimeRfc1123"
                }
            },
            etag: {
                serializedName: "etag",
                xmlName: "etag",
                type: {
                    name: "String"
                }
            },
            preferenceApplied: {
                serializedName: "preference-applied",
                xmlName: "preference-applied",
                type: {
                    name: "String"
                }
            },
            contentType: {
                serializedName: "content-type",
                xmlName: "content-type",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableInsertEntityExceptionHeaders = {
    serializedName: "Table_insertEntityExceptionHeaders",
    type: {
        name: "Composite",
        className: "TableInsertEntityExceptionHeaders",
        modelProperties: {
            errorCode: {
                serializedName: "x-ms-error-code",
                xmlName: "x-ms-error-code",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableGetAccessPolicyHeaders = {
    serializedName: "Table_getAccessPolicyHeaders",
    type: {
        name: "Composite",
        className: "TableGetAccessPolicyHeaders",
        modelProperties: {
            clientRequestId: {
                serializedName: "x-ms-client-request-id",
                xmlName: "x-ms-client-request-id",
                type: {
                    name: "String"
                }
            },
            requestId: {
                serializedName: "x-ms-request-id",
                xmlName: "x-ms-request-id",
                type: {
                    name: "String"
                }
            },
            version: {
                serializedName: "x-ms-version",
                xmlName: "x-ms-version",
                type: {
                    name: "String"
                }
            },
            date: {
                serializedName: "date",
                xmlName: "date",
                type: {
                    name: "DateTimeRfc1123"
                }
            }
        }
    }
};
const TableGetAccessPolicyExceptionHeaders = {
    serializedName: "Table_getAccessPolicyExceptionHeaders",
    type: {
        name: "Composite",
        className: "TableGetAccessPolicyExceptionHeaders",
        modelProperties: {
            errorCode: {
                serializedName: "x-ms-error-code",
                xmlName: "x-ms-error-code",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const TableSetAccessPolicyHeaders = {
    serializedName: "Table_setAccessPolicyHeaders",
    type: {
        name: "Composite",
        className: "TableSetAccessPolicyHeaders",
        modelProperties: {
            clientRequestId: {
                serializedName: "x-ms-client-request-id",
                xmlName: "x-ms-client-request-id",
                type: {
                    name: "String"
                }
            },
            requestId: {
                serializedName: "x-ms-request-id",
                xmlName: "x-ms-request-id",
                type: {
                    name: "String"
                }
            },
            version: {
                serializedName: "x-ms-version",
                xmlName: "x-ms-version",
                type: {
                    name: "String"
                }
            },
            date: {
                serializedName: "date",
                xmlName: "date",
                type: {
                    name: "DateTimeRfc1123"
                }
            }
        }
    }
};
const TableSetAccessPolicyExceptionHeaders = {
    serializedName: "Table_setAccessPolicyExceptionHeaders",
    type: {
        name: "Composite",
        className: "TableSetAccessPolicyExceptionHeaders",
        modelProperties: {
            errorCode: {
                serializedName: "x-ms-error-code",
                xmlName: "x-ms-error-code",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const ServiceSetPropertiesHeaders = {
    serializedName: "Service_setPropertiesHeaders",
    type: {
        name: "Composite",
        className: "ServiceSetPropertiesHeaders",
        modelProperties: {
            clientRequestId: {
                serializedName: "x-ms-client-request-id",
                xmlName: "x-ms-client-request-id",
                type: {
                    name: "String"
                }
            },
            requestId: {
                serializedName: "x-ms-request-id",
                xmlName: "x-ms-request-id",
                type: {
                    name: "String"
                }
            },
            version: {
                serializedName: "x-ms-version",
                xmlName: "x-ms-version",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const ServiceSetPropertiesExceptionHeaders = {
    serializedName: "Service_setPropertiesExceptionHeaders",
    type: {
        name: "Composite",
        className: "ServiceSetPropertiesExceptionHeaders",
        modelProperties: {
            errorCode: {
                serializedName: "x-ms-error-code",
                xmlName: "x-ms-error-code",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const ServiceGetPropertiesHeaders = {
    serializedName: "Service_getPropertiesHeaders",
    type: {
        name: "Composite",
        className: "ServiceGetPropertiesHeaders",
        modelProperties: {
            clientRequestId: {
                serializedName: "x-ms-client-request-id",
                xmlName: "x-ms-client-request-id",
                type: {
                    name: "String"
                }
            },
            requestId: {
                serializedName: "x-ms-request-id",
                xmlName: "x-ms-request-id",
                type: {
                    name: "String"
                }
            },
            version: {
                serializedName: "x-ms-version",
                xmlName: "x-ms-version",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const ServiceGetPropertiesExceptionHeaders = {
    serializedName: "Service_getPropertiesExceptionHeaders",
    type: {
        name: "Composite",
        className: "ServiceGetPropertiesExceptionHeaders",
        modelProperties: {
            errorCode: {
                serializedName: "x-ms-error-code",
                xmlName: "x-ms-error-code",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const ServiceGetStatisticsHeaders = {
    serializedName: "Service_getStatisticsHeaders",
    type: {
        name: "Composite",
        className: "ServiceGetStatisticsHeaders",
        modelProperties: {
            clientRequestId: {
                serializedName: "x-ms-client-request-id",
                xmlName: "x-ms-client-request-id",
                type: {
                    name: "String"
                }
            },
            requestId: {
                serializedName: "x-ms-request-id",
                xmlName: "x-ms-request-id",
                type: {
                    name: "String"
                }
            },
            version: {
                serializedName: "x-ms-version",
                xmlName: "x-ms-version",
                type: {
                    name: "String"
                }
            },
            date: {
                serializedName: "date",
                xmlName: "date",
                type: {
                    name: "DateTimeRfc1123"
                }
            }
        }
    }
};
const ServiceGetStatisticsExceptionHeaders = {
    serializedName: "Service_getStatisticsExceptionHeaders",
    type: {
        name: "Composite",
        className: "ServiceGetStatisticsExceptionHeaders",
        modelProperties: {
            errorCode: {
                serializedName: "x-ms-error-code",
                xmlName: "x-ms-error-code",
                type: {
                    name: "String"
                }
            }
        }
    }
};

var Mappers = /*#__PURE__*/Object.freeze({
    __proto__: null,
    TableQueryResponse: TableQueryResponse,
    TableResponseProperties: TableResponseProperties,
    TableServiceError: TableServiceError,
    TableServiceErrorOdataError: TableServiceErrorOdataError,
    TableServiceErrorOdataErrorMessage: TableServiceErrorOdataErrorMessage,
    TableProperties: TableProperties,
    TableEntityQueryResponse: TableEntityQueryResponse,
    SignedIdentifier: SignedIdentifier,
    AccessPolicy: AccessPolicy,
    TableServiceProperties: TableServiceProperties,
    Logging: Logging,
    RetentionPolicy: RetentionPolicy,
    Metrics: Metrics,
    CorsRule: CorsRule,
    TableServiceStats: TableServiceStats,
    GeoReplication: GeoReplication,
    TableResponse: TableResponse,
    TableQueryHeaders: TableQueryHeaders,
    TableQueryExceptionHeaders: TableQueryExceptionHeaders,
    TableCreateHeaders: TableCreateHeaders,
    TableCreateExceptionHeaders: TableCreateExceptionHeaders,
    TableDeleteHeaders: TableDeleteHeaders,
    TableDeleteExceptionHeaders: TableDeleteExceptionHeaders,
    TableQueryEntitiesHeaders: TableQueryEntitiesHeaders,
    TableQueryEntitiesExceptionHeaders: TableQueryEntitiesExceptionHeaders,
    TableQueryEntitiesWithPartitionAndRowKeyHeaders: TableQueryEntitiesWithPartitionAndRowKeyHeaders,
    TableQueryEntitiesWithPartitionAndRowKeyExceptionHeaders: TableQueryEntitiesWithPartitionAndRowKeyExceptionHeaders,
    TableUpdateEntityHeaders: TableUpdateEntityHeaders,
    TableUpdateEntityExceptionHeaders: TableUpdateEntityExceptionHeaders,
    TableMergeEntityHeaders: TableMergeEntityHeaders,
    TableMergeEntityExceptionHeaders: TableMergeEntityExceptionHeaders,
    TableDeleteEntityHeaders: TableDeleteEntityHeaders,
    TableDeleteEntityExceptionHeaders: TableDeleteEntityExceptionHeaders,
    TableInsertEntityHeaders: TableInsertEntityHeaders,
    TableInsertEntityExceptionHeaders: TableInsertEntityExceptionHeaders,
    TableGetAccessPolicyHeaders: TableGetAccessPolicyHeaders,
    TableGetAccessPolicyExceptionHeaders: TableGetAccessPolicyExceptionHeaders,
    TableSetAccessPolicyHeaders: TableSetAccessPolicyHeaders,
    TableSetAccessPolicyExceptionHeaders: TableSetAccessPolicyExceptionHeaders,
    ServiceSetPropertiesHeaders: ServiceSetPropertiesHeaders,
    ServiceSetPropertiesExceptionHeaders: ServiceSetPropertiesExceptionHeaders,
    ServiceGetPropertiesHeaders: ServiceGetPropertiesHeaders,
    ServiceGetPropertiesExceptionHeaders: ServiceGetPropertiesExceptionHeaders,
    ServiceGetStatisticsHeaders: ServiceGetStatisticsHeaders,
    ServiceGetStatisticsExceptionHeaders: ServiceGetStatisticsExceptionHeaders
});

/*
 * Copyright (c) Microsoft Corporation.
 * Licensed under the MIT License.
 *
 * Code generated by Microsoft (R) AutoRest Code Generator.
 * Changes may cause incorrect behavior and will be lost if the code is regenerated.
 */
const accept = {
    parameterPath: "accept",
    mapper: {
        defaultValue: "application/json;odata=minimalmetadata",
        isConstant: true,
        serializedName: "Accept",
        type: {
            name: "String"
        }
    }
};
const url = {
    parameterPath: "url",
    mapper: {
        serializedName: "url",
        required: true,
        xmlName: "url",
        type: {
            name: "String"
        }
    },
    skipEncoding: true
};
const version = {
    parameterPath: "version",
    mapper: {
        defaultValue: "2019-02-02",
        isConstant: true,
        serializedName: "x-ms-version",
        type: {
            name: "String"
        }
    }
};
const requestId = {
    parameterPath: ["options", "requestId"],
    mapper: {
        serializedName: "x-ms-client-request-id",
        xmlName: "x-ms-client-request-id",
        type: {
            name: "String"
        }
    }
};
const dataServiceVersion = {
    parameterPath: "dataServiceVersion",
    mapper: {
        defaultValue: "3.0",
        isConstant: true,
        serializedName: "DataServiceVersion",
        type: {
            name: "String"
        }
    }
};
const format = {
    parameterPath: ["options", "queryOptions", "format"],
    mapper: {
        serializedName: "$format",
        xmlName: "$format",
        type: {
            name: "String"
        }
    }
};
const top = {
    parameterPath: ["options", "queryOptions", "top"],
    mapper: {
        constraints: {
            InclusiveMinimum: 0
        },
        serializedName: "$top",
        xmlName: "$top",
        type: {
            name: "Number"
        }
    }
};
const select = {
    parameterPath: ["options", "queryOptions", "select"],
    mapper: {
        serializedName: "$select",
        xmlName: "$select",
        type: {
            name: "String"
        }
    }
};
const filter = {
    parameterPath: ["options", "queryOptions", "filter"],
    mapper: {
        serializedName: "$filter",
        xmlName: "$filter",
        type: {
            name: "String"
        }
    }
};
const nextTableName = {
    parameterPath: ["options", "nextTableName"],
    mapper: {
        serializedName: "NextTableName",
        xmlName: "NextTableName",
        type: {
            name: "String"
        }
    }
};
const contentType = {
    parameterPath: ["options", "contentType"],
    mapper: {
        defaultValue: "application/json;odata=nometadata",
        isConstant: true,
        serializedName: "Content-Type",
        type: {
            name: "String"
        }
    }
};
const tableProperties = {
    parameterPath: "tableProperties",
    mapper: TableProperties
};
const responsePreference = {
    parameterPath: ["options", "responsePreference"],
    mapper: {
        serializedName: "Prefer",
        xmlName: "Prefer",
        type: {
            name: "String"
        }
    }
};
const accept1 = {
    parameterPath: "accept",
    mapper: {
        defaultValue: "application/json",
        isConstant: true,
        serializedName: "Accept",
        type: {
            name: "String"
        }
    }
};
const table = {
    parameterPath: "table",
    mapper: {
        serializedName: "table",
        required: true,
        xmlName: "table",
        type: {
            name: "String"
        }
    }
};
const timeout = {
    parameterPath: ["options", "timeout"],
    mapper: {
        constraints: {
            InclusiveMinimum: 0
        },
        serializedName: "timeout",
        xmlName: "timeout",
        type: {
            name: "Number"
        }
    }
};
const nextPartitionKey = {
    parameterPath: ["options", "nextPartitionKey"],
    mapper: {
        serializedName: "NextPartitionKey",
        xmlName: "NextPartitionKey",
        type: {
            name: "String"
        }
    }
};
const nextRowKey = {
    parameterPath: ["options", "nextRowKey"],
    mapper: {
        serializedName: "NextRowKey",
        xmlName: "NextRowKey",
        type: {
            name: "String"
        }
    }
};
const partitionKey = {
    parameterPath: "partitionKey",
    mapper: {
        serializedName: "partitionKey",
        required: true,
        xmlName: "partitionKey",
        type: {
            name: "String"
        }
    }
};
const rowKey = {
    parameterPath: "rowKey",
    mapper: {
        serializedName: "rowKey",
        required: true,
        xmlName: "rowKey",
        type: {
            name: "String"
        }
    }
};
const contentType1 = {
    parameterPath: ["options", "contentType"],
    mapper: {
        defaultValue: "application/json",
        isConstant: true,
        serializedName: "Content-Type",
        type: {
            name: "String"
        }
    }
};
const tableEntityProperties = {
    parameterPath: ["options", "tableEntityProperties"],
    mapper: {
        serializedName: "tableEntityProperties",
        xmlName: "tableEntityProperties",
        type: {
            name: "Dictionary",
            value: { type: { name: "any" } }
        }
    }
};
const ifMatch = {
    parameterPath: ["options", "ifMatch"],
    mapper: {
        serializedName: "If-Match",
        xmlName: "If-Match",
        type: {
            name: "String"
        }
    }
};
const ifMatch1 = {
    parameterPath: "ifMatch",
    mapper: {
        serializedName: "If-Match",
        required: true,
        xmlName: "If-Match",
        type: {
            name: "String"
        }
    }
};
const accept2 = {
    parameterPath: "accept",
    mapper: {
        defaultValue: "application/xml",
        isConstant: true,
        serializedName: "Accept",
        type: {
            name: "String"
        }
    }
};
const comp = {
    parameterPath: "comp",
    mapper: {
        defaultValue: "acl",
        isConstant: true,
        serializedName: "comp",
        type: {
            name: "String"
        }
    }
};
const contentType2 = {
    parameterPath: ["options", "contentType"],
    mapper: {
        defaultValue: "application/xml",
        isConstant: true,
        serializedName: "Content-Type",
        type: {
            name: "String"
        }
    }
};
const tableAcl = {
    parameterPath: ["options", "tableAcl"],
    mapper: {
        serializedName: "tableAcl",
        xmlName: "SignedIdentifiers",
        xmlIsWrapped: true,
        xmlElementName: "SignedIdentifier",
        type: {
            name: "Sequence",
            element: {
                type: {
                    name: "Composite",
                    className: "SignedIdentifier"
                }
            }
        }
    }
};
const accept3 = {
    parameterPath: "accept",
    mapper: {
        defaultValue: "application/xml",
        isConstant: true,
        serializedName: "Accept",
        type: {
            name: "String"
        }
    }
};
const tableServiceProperties = {
    parameterPath: "tableServiceProperties",
    mapper: TableServiceProperties
};
const restype = {
    parameterPath: "restype",
    mapper: {
        defaultValue: "service",
        isConstant: true,
        serializedName: "restype",
        type: {
            name: "String"
        }
    }
};
const comp1 = {
    parameterPath: "comp",
    mapper: {
        defaultValue: "properties",
        isConstant: true,
        serializedName: "comp",
        type: {
            name: "String"
        }
    }
};
const comp2 = {
    parameterPath: "comp",
    mapper: {
        defaultValue: "stats",
        isConstant: true,
        serializedName: "comp",
        type: {
            name: "String"
        }
    }
};

/*
 * Copyright (c) Microsoft Corporation.
 * Licensed under the MIT License.
 *
 * Code generated by Microsoft (R) AutoRest Code Generator.
 * Changes may cause incorrect behavior and will be lost if the code is regenerated.
 */
/** Class representing a Table. */
class TableImpl {
    /**
     * Initialize a new instance of the class Table class.
     * @param client Reference to the service client
     */
    constructor(client) {
        this.client = client;
    }
    /**
     * Queries tables under the given account.
     * @param options The options parameters.
     */
    query(options) {
        return this.client.sendOperationRequest({ options }, queryOperationSpec);
    }
    /**
     * Creates a new table under the given account.
     * @param tableProperties The Table properties.
     * @param options The options parameters.
     */
    create(tableProperties, options) {
        return this.client.sendOperationRequest({ tableProperties, options }, createOperationSpec);
    }
    /**
     * Operation permanently deletes the specified table.
     * @param table The name of the table.
     * @param options The options parameters.
     */
    delete(table, options) {
        return this.client.sendOperationRequest({ table, options }, deleteOperationSpec);
    }
    /**
     * Queries entities in a table.
     * @param table The name of the table.
     * @param options The options parameters.
     */
    queryEntities(table, options) {
        return this.client.sendOperationRequest({ table, options }, queryEntitiesOperationSpec);
    }
    /**
     * Queries entities in a table.
     * @param table The name of the table.
     * @param partitionKey The partition key of the entity.
     * @param rowKey The row key of the entity.
     * @param options The options parameters.
     */
    queryEntitiesWithPartitionAndRowKey(table, partitionKey, rowKey, options) {
        return this.client.sendOperationRequest({ table, partitionKey, rowKey, options }, queryEntitiesWithPartitionAndRowKeyOperationSpec);
    }
    /**
     * Update entity in a table.
     * @param table The name of the table.
     * @param partitionKey The partition key of the entity.
     * @param rowKey The row key of the entity.
     * @param options The options parameters.
     */
    updateEntity(table, partitionKey, rowKey, options) {
        return this.client.sendOperationRequest({ table, partitionKey, rowKey, options }, updateEntityOperationSpec);
    }
    /**
     * Merge entity in a table.
     * @param table The name of the table.
     * @param partitionKey The partition key of the entity.
     * @param rowKey The row key of the entity.
     * @param options The options parameters.
     */
    mergeEntity(table, partitionKey, rowKey, options) {
        return this.client.sendOperationRequest({ table, partitionKey, rowKey, options }, mergeEntityOperationSpec);
    }
    /**
     * Deletes the specified entity in a table.
     * @param table The name of the table.
     * @param partitionKey The partition key of the entity.
     * @param rowKey The row key of the entity.
     * @param ifMatch Match condition for an entity to be deleted. If specified and a matching entity is
     *                not found, an error will be raised. To force an unconditional delete, set to the wildcard character
     *                (*).
     * @param options The options parameters.
     */
    deleteEntity(table, partitionKey, rowKey, ifMatch, options) {
        return this.client.sendOperationRequest({ table, partitionKey, rowKey, ifMatch, options }, deleteEntityOperationSpec);
    }
    /**
     * Insert entity in a table.
     * @param table The name of the table.
     * @param options The options parameters.
     */
    insertEntity(table, options) {
        return this.client.sendOperationRequest({ table, options }, insertEntityOperationSpec);
    }
    /**
     * Retrieves details about any stored access policies specified on the table that may be used with
     * Shared Access Signatures.
     * @param table The name of the table.
     * @param options The options parameters.
     */
    getAccessPolicy(table, options) {
        return this.client.sendOperationRequest({ table, options }, getAccessPolicyOperationSpec);
    }
    /**
     * Sets stored access policies for the table that may be used with Shared Access Signatures.
     * @param table The name of the table.
     * @param options The options parameters.
     */
    setAccessPolicy(table, options) {
        return this.client.sendOperationRequest({ table, options }, setAccessPolicyOperationSpec);
    }
}
// Operation Specifications
const xmlSerializer = coreClient.createSerializer(Mappers, /* isXml */ true);
const serializer = coreClient.createSerializer(Mappers, /* isXml */ false);
const queryOperationSpec = {
    path: "/Tables",
    httpMethod: "GET",
    responses: {
        200: {
            bodyMapper: TableQueryResponse,
            headersMapper: TableQueryHeaders
        },
        default: {
            bodyMapper: TableServiceError,
            headersMapper: TableQueryExceptionHeaders
        }
    },
    queryParameters: [
        format,
        top,
        select,
        filter,
        nextTableName
    ],
    urlParameters: [url],
    headerParameters: [
        accept,
        version,
        requestId,
        dataServiceVersion
    ],
    serializer
};
const createOperationSpec = {
    path: "/Tables",
    httpMethod: "POST",
    responses: {
        201: {
            bodyMapper: TableResponse,
            headersMapper: TableCreateHeaders
        },
        204: {
            headersMapper: TableCreateHeaders
        },
        default: {
            bodyMapper: TableServiceError,
            headersMapper: TableCreateExceptionHeaders
        }
    },
    requestBody: tableProperties,
    queryParameters: [format],
    urlParameters: [url],
    headerParameters: [
        accept,
        version,
        requestId,
        dataServiceVersion,
        contentType,
        responsePreference
    ],
    mediaType: "json",
    serializer
};
const deleteOperationSpec = {
    path: "/Tables('{table}')",
    httpMethod: "DELETE",
    responses: {
        204: {
            headersMapper: TableDeleteHeaders
        },
        default: {
            bodyMapper: TableServiceError,
            headersMapper: TableDeleteExceptionHeaders
        }
    },
    urlParameters: [url, table],
    headerParameters: [
        version,
        requestId,
        accept1
    ],
    serializer
};
const queryEntitiesOperationSpec = {
    path: "/{table}()",
    httpMethod: "GET",
    responses: {
        200: {
            bodyMapper: TableEntityQueryResponse,
            headersMapper: TableQueryEntitiesHeaders
        },
        default: {
            bodyMapper: TableServiceError,
            headersMapper: TableQueryEntitiesExceptionHeaders
        }
    },
    queryParameters: [
        format,
        top,
        select,
        filter,
        timeout,
        nextPartitionKey,
        nextRowKey
    ],
    urlParameters: [url, table],
    headerParameters: [
        accept,
        version,
        requestId,
        dataServiceVersion
    ],
    serializer
};
const queryEntitiesWithPartitionAndRowKeyOperationSpec = {
    path: "/{table}(PartitionKey='{partitionKey}',RowKey='{rowKey}')",
    httpMethod: "GET",
    responses: {
        200: {
            bodyMapper: {
                type: { name: "Dictionary", value: { type: { name: "any" } } }
            },
            headersMapper: TableQueryEntitiesWithPartitionAndRowKeyHeaders
        },
        default: {
            bodyMapper: TableServiceError,
            headersMapper: TableQueryEntitiesWithPartitionAndRowKeyExceptionHeaders
        }
    },
    queryParameters: [
        format,
        select,
        filter,
        timeout
    ],
    urlParameters: [
        url,
        table,
        partitionKey,
        rowKey
    ],
    headerParameters: [
        accept,
        version,
        requestId,
        dataServiceVersion
    ],
    serializer
};
const updateEntityOperationSpec = {
    path: "/{table}(PartitionKey='{partitionKey}',RowKey='{rowKey}')",
    httpMethod: "PUT",
    responses: {
        204: {
            headersMapper: TableUpdateEntityHeaders
        },
        default: {
            bodyMapper: TableServiceError,
            headersMapper: TableUpdateEntityExceptionHeaders
        }
    },
    requestBody: tableEntityProperties,
    queryParameters: [format, timeout],
    urlParameters: [
        url,
        table,
        partitionKey,
        rowKey
    ],
    headerParameters: [
        version,
        requestId,
        dataServiceVersion,
        accept1,
        contentType1,
        ifMatch
    ],
    mediaType: "json",
    serializer
};
const mergeEntityOperationSpec = {
    path: "/{table}(PartitionKey='{partitionKey}',RowKey='{rowKey}')",
    httpMethod: "PATCH",
    responses: {
        204: {
            headersMapper: TableMergeEntityHeaders
        },
        default: {
            bodyMapper: TableServiceError,
            headersMapper: TableMergeEntityExceptionHeaders
        }
    },
    requestBody: tableEntityProperties,
    queryParameters: [format, timeout],
    urlParameters: [
        url,
        table,
        partitionKey,
        rowKey
    ],
    headerParameters: [
        version,
        requestId,
        dataServiceVersion,
        accept1,
        contentType1,
        ifMatch
    ],
    mediaType: "json",
    serializer
};
const deleteEntityOperationSpec = {
    path: "/{table}(PartitionKey='{partitionKey}',RowKey='{rowKey}')",
    httpMethod: "DELETE",
    responses: {
        204: {
            headersMapper: TableDeleteEntityHeaders
        },
        default: {
            bodyMapper: TableServiceError,
            headersMapper: TableDeleteEntityExceptionHeaders
        }
    },
    queryParameters: [format, timeout],
    urlParameters: [
        url,
        table,
        partitionKey,
        rowKey
    ],
    headerParameters: [
        accept,
        version,
        requestId,
        dataServiceVersion,
        ifMatch1
    ],
    serializer
};
const insertEntityOperationSpec = {
    path: "/{table}",
    httpMethod: "POST",
    responses: {
        201: {
            bodyMapper: {
                type: { name: "Dictionary", value: { type: { name: "any" } } }
            },
            headersMapper: TableInsertEntityHeaders
        },
        204: {
            headersMapper: TableInsertEntityHeaders
        },
        default: {
            bodyMapper: TableServiceError,
            headersMapper: TableInsertEntityExceptionHeaders
        }
    },
    requestBody: tableEntityProperties,
    queryParameters: [format, timeout],
    urlParameters: [url, table],
    headerParameters: [
        accept,
        version,
        requestId,
        dataServiceVersion,
        contentType,
        responsePreference
    ],
    mediaType: "json",
    serializer
};
const getAccessPolicyOperationSpec = {
    path: "/{table}",
    httpMethod: "GET",
    responses: {
        200: {
            bodyMapper: {
                type: {
                    name: "Sequence",
                    element: {
                        type: { name: "Composite", className: "SignedIdentifier" }
                    }
                },
                serializedName: "SignedIdentifiers",
                xmlName: "SignedIdentifiers",
                xmlIsWrapped: true,
                xmlElementName: "SignedIdentifier"
            },
            headersMapper: TableGetAccessPolicyHeaders
        },
        default: {
            bodyMapper: TableServiceError,
            headersMapper: TableGetAccessPolicyExceptionHeaders
        }
    },
    queryParameters: [timeout, comp],
    urlParameters: [url, table],
    headerParameters: [
        version,
        requestId,
        accept2
    ],
    isXML: true,
    serializer: xmlSerializer
};
const setAccessPolicyOperationSpec = {
    path: "/{table}",
    httpMethod: "PUT",
    responses: {
        204: {
            headersMapper: TableSetAccessPolicyHeaders
        },
        default: {
            bodyMapper: TableServiceError,
            headersMapper: TableSetAccessPolicyExceptionHeaders
        }
    },
    requestBody: tableAcl,
    queryParameters: [timeout, comp],
    urlParameters: [url, table],
    headerParameters: [
        version,
        requestId,
        contentType2,
        accept3
    ],
    isXML: true,
    contentType: "application/xml; charset=utf-8",
    mediaType: "xml",
    serializer: xmlSerializer
};

/*
 * Copyright (c) Microsoft Corporation.
 * Licensed under the MIT License.
 *
 * Code generated by Microsoft (R) AutoRest Code Generator.
 * Changes may cause incorrect behavior and will be lost if the code is regenerated.
 */
/** Class representing a Service. */
class ServiceImpl {
    /**
     * Initialize a new instance of the class Service class.
     * @param client Reference to the service client
     */
    constructor(client) {
        this.client = client;
    }
    /**
     * Sets properties for an account's Table service endpoint, including properties for Analytics and CORS
     * (Cross-Origin Resource Sharing) rules.
     * @param tableServiceProperties The Table Service properties.
     * @param options The options parameters.
     */
    setProperties(tableServiceProperties, options) {
        return this.client.sendOperationRequest({ tableServiceProperties, options }, setPropertiesOperationSpec);
    }
    /**
     * Gets the properties of an account's Table service, including properties for Analytics and CORS
     * (Cross-Origin Resource Sharing) rules.
     * @param options The options parameters.
     */
    getProperties(options) {
        return this.client.sendOperationRequest({ options }, getPropertiesOperationSpec);
    }
    /**
     * Retrieves statistics related to replication for the Table service. It is only available on the
     * secondary location endpoint when read-access geo-redundant replication is enabled for the account.
     * @param options The options parameters.
     */
    getStatistics(options) {
        return this.client.sendOperationRequest({ options }, getStatisticsOperationSpec);
    }
}
// Operation Specifications
const xmlSerializer$1 = coreClient.createSerializer(Mappers, /* isXml */ true);
const setPropertiesOperationSpec = {
    path: "/",
    httpMethod: "PUT",
    responses: {
        202: {
            headersMapper: ServiceSetPropertiesHeaders
        },
        default: {
            bodyMapper: TableServiceError,
            headersMapper: ServiceSetPropertiesExceptionHeaders
        }
    },
    requestBody: tableServiceProperties,
    queryParameters: [timeout, restype, comp1],
    urlParameters: [url],
    headerParameters: [
        version,
        requestId,
        contentType2,
        accept3
    ],
    isXML: true,
    contentType: "application/xml; charset=utf-8",
    mediaType: "xml",
    serializer: xmlSerializer$1
};
const getPropertiesOperationSpec = {
    path: "/",
    httpMethod: "GET",
    responses: {
        200: {
            bodyMapper: TableServiceProperties,
            headersMapper: ServiceGetPropertiesHeaders
        },
        default: {
            bodyMapper: TableServiceError,
            headersMapper: ServiceGetPropertiesExceptionHeaders
        }
    },
    queryParameters: [timeout, restype, comp1],
    urlParameters: [url],
    headerParameters: [
        version,
        requestId,
        accept2
    ],
    isXML: true,
    serializer: xmlSerializer$1
};
const getStatisticsOperationSpec = {
    path: "/",
    httpMethod: "GET",
    responses: {
        200: {
            bodyMapper: TableServiceStats,
            headersMapper: ServiceGetStatisticsHeaders
        },
        default: {
            bodyMapper: TableServiceError,
            headersMapper: ServiceGetStatisticsExceptionHeaders
        }
    },
    queryParameters: [timeout, restype, comp2],
    urlParameters: [url],
    headerParameters: [
        version,
        requestId,
        accept2
    ],
    isXML: true,
    serializer: xmlSerializer$1
};

/*
 * Copyright (c) Microsoft Corporation.
 * Licensed under the MIT License.
 *
 * Code generated by Microsoft (R) AutoRest Code Generator.
 * Changes may cause incorrect behavior and will be lost if the code is regenerated.
 */
/** @internal */
class GeneratedClientContext extends coreClient.ServiceClient {
    /**
     * Initializes a new instance of the GeneratedClientContext class.
     * @param url The URL of the service account or table that is the target of the desired operation.
     * @param options The parameter options
     */
    constructor(url, options) {
        if (url === undefined) {
            throw new Error("'url' cannot be null");
        }
        // Initializing default values for options
        if (!options) {
            options = {};
        }
        const defaults = {
            requestContentType: "application/json; charset=utf-8"
        };
        const packageDetails = `azsdk-js-data-tables/13.0.1`;
        const userAgentPrefix = options.userAgentOptions && options.userAgentOptions.userAgentPrefix
            ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`
            : `${packageDetails}`;
        const optionsWithDefaults = Object.assign(Object.assign(Object.assign({}, defaults), options), { userAgentOptions: {
                userAgentPrefix
            }, baseUri: options.endpoint || "{url}" });
        super(optionsWithDefaults);
        // Parameter assignments
        this.url = url;
        // Assigning values to Constant parameters
        this.version = options.version || "2019-02-02";
    }
}

/*
 * Copyright (c) Microsoft Corporation.
 * Licensed under the MIT License.
 *
 * Code generated by Microsoft (R) AutoRest Code Generator.
 * Changes may cause incorrect behavior and will be lost if the code is regenerated.
 */
/** @internal */
class GeneratedClient extends GeneratedClientContext {
    /**
     * Initializes a new instance of the GeneratedClient class.
     * @param url The URL of the service account or table that is the target of the desired operation.
     * @param options The parameter options
     */
    constructor(url, options) {
        super(url, options);
        this.table = new TableImpl(this);
        this.service = new ServiceImpl(this);
    }
}

// Copyright (c) Microsoft Corporation.
/**
 * Creates a span using the global tracer.
 * @internal
 */
const createSpan = coreTracing.createSpanFunction({
    packagePrefix: "Azure.Data.Tables",
    namespace: "Microsoft.Data.Tables",
});

// Copyright (c) Microsoft Corporation.
/**
 * Gets client parameters from an Account Connection String
 * Only supported in Node.js not supported for Browsers
 * @param extractedCreds - parsed connection string
 * @param options - TablesServiceClient options
 */
function fromAccountConnectionString(extractedCreds, options = {}) {
    const sharedKeyCredential = new coreAuth.AzureNamedKeyCredential(extractedCreds.accountName, extractedCreds.accountKey);
    return {
        url: extractedCreds.url,
        options,
        credential: sharedKeyCredential,
    };
}
function getAccountConnectionString(accountName, accountKey, defaultEndpointsProtocol, endpointSuffix, tableEndpoint) {
    if (!tableEndpoint) {
        // TableEndpoint is not present in the Account connection string
        // Can be obtained from `${defaultEndpointsProtocol}://${accountName}.table.${endpointSuffix}`
        const protocol = defaultEndpointsProtocol.toLowerCase();
        if (protocol !== "https" && protocol !== "http") {
            throw new Error("Invalid DefaultEndpointsProtocol in the provided Connection String. Expecting 'https' or 'http'");
        }
        if (!endpointSuffix) {
            throw new Error("Invalid EndpointSuffix in the provided Connection String");
        }
        tableEndpoint = `${defaultEndpointsProtocol}://${accountName}.table.${endpointSuffix}`;
    }
    if (!accountName) {
        throw new Error("Invalid AccountName in the provided Connection String");
    }
    else if (accountKey.length === 0) {
        throw new Error("Invalid AccountKey in the provided Connection String");
    }
    return {
        kind: "AccountConnString",
        url: tableEndpoint,
        accountName,
        accountKey,
    };
}

// Copyright (c) Microsoft Corporation.
const DevelopmentConnectionString = "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;TableEndpoint=http://127.0.0.1:10002/devstoreaccount1";
/**
 * This function parses a connection string into a set of
 * parameters to pass to be passed to TableClientService,
 * depending on the connection string type these parameter would
 * contain:
 * - Account Connection String:  A pipeline to sign the request with a SharedKey
 * - SAS Connection String: Attach a SAS token to the storage account url for authentication
 * @param connectionString - Connection string to parse
 * @param options - TableService client options
 */
function getClientParamsFromConnectionString(connectionString, options = {}) {
    if (connectionString.toLowerCase().indexOf("usedevelopmentstorage=true") !== -1) {
        connectionString = DevelopmentConnectionString;
        options.allowInsecureConnection = true;
    }
    const extractedCreds = extractConnectionStringParts(connectionString);
    if (extractedCreds.kind === "AccountConnString") {
        return fromAccountConnectionString(extractedCreds, options);
    }
    else if (extractedCreds.kind === "SASConnString") {
        return {
            url: `${extractedCreds.url}?${extractedCreds.accountSas}`,
            options,
        };
    }
    else {
        throw new Error("Connection string must be either an Account connection string or a SAS connection string");
    }
}
/**
 * Extracts the parts of an Storage account connection string.
 *
 * @param connectionString - Connection string.
 * @returns String key value pairs of the storage account's url and credentials.
 */
function extractConnectionStringParts(connectionString) {
    // Matching TableEndpoint in the Account connection string
    let tableEndpoint = getValueInConnString(connectionString, "TableEndpoint");
    // Slicing off '/' at the end if exists
    // (The methods that use `extractConnectionStringParts` expect the url to not have `/` at the end)
    tableEndpoint = tableEndpoint.endsWith("/") ? tableEndpoint.slice(0, -1) : tableEndpoint;
    if (isAccountConnectionString(connectionString)) {
        return getAccountConnectionString(getValueInConnString(connectionString, "AccountName"), getValueInConnString(connectionString, "AccountKey"), getValueInConnString(connectionString, "DefaultEndpointsProtocol"), getValueInConnString(connectionString, "EndpointSuffix"), tableEndpoint);
    }
    else {
        return getSASConnectionString(connectionString, tableEndpoint);
    }
}
/**
 * Checks whether a connection string is an Account Connection string or not
 */
function isAccountConnectionString(connectionString) {
    const lowercaseConnectionString = connectionString.toLowerCase();
    return (lowercaseConnectionString.search("defaultendpointsprotocol=") !== -1 &&
        lowercaseConnectionString.search("accountkey=") !== -1);
}
function getSASConnectionString(connectionString, tableEndpoint) {
    const accountName = getAccountNameFromUrl(tableEndpoint);
    const accountSas = getValueInConnString(connectionString, "SharedAccessSignature");
    if (!tableEndpoint) {
        throw new Error("Invalid TableEndpoint in the provided SAS Connection String");
    }
    else if (!accountSas) {
        throw new Error("Invalid SharedAccessSignature in the provided SAS Connection String");
    }
    else if (!accountName) {
        throw new Error("Invalid AccountName in the provided SAS Connection String");
    }
    return { kind: "SASConnString", url: tableEndpoint, accountName, accountSas };
}
function getValueInConnString(connectionString, argument) {
    const searchKey = argument.toLowerCase();
    const elements = connectionString.split(";").filter((e) => Boolean(e));
    for (const element of elements) {
        const trimmedElement = element.trim();
        const [elementKey, value] = getValuePair(trimmedElement);
        const key = elementKey.toLowerCase();
        if (key === searchKey) {
            return value;
        }
    }
    return "";
}
function getValuePair(kvp) {
    // If the string is not in kvp format <key>=<valye> return an empty array
    if (!kvp || kvp.indexOf("=") === -1) {
        return [];
    }
    // Get the substring before the first '='
    const key = kvp.substr(0, kvp.indexOf("="));
    // Get the substring after the first '='
    const value = kvp.substr(kvp.indexOf("=") + 1);
    return [key, value];
}
/**
 * Extracts account name from the url
 * @param url - URL to extract the account name from
 * @returns The account name
 */
function getAccountNameFromUrl(url) {
    if (!url) {
        return url;
    }
    const parsedUrl = new url$1.URL(url);
    let accountName;
    const host = parsedUrl.host || "";
    const path = parsedUrl.pathname || "";
    const hostParts = host.split(".");
    const pathParts = path.split("/");
    if (hostParts.length >= 1 && hostParts[1] === "table") {
        // `${defaultEndpointsProtocol}://${accountName}.table.${endpointSuffix}`;
        // Slicing off '/' at the end if exists
        url = url.endsWith("/") ? url.slice(0, -1) : url;
        accountName = host.split(".")[0];
    }
    else if (pathParts.length >= 1) {
        // IPv4/IPv6 address hosts... Example - http://192.0.0.10:10001/devstoreaccount1/
        // Single word domain without a [dot] in the endpoint... Example - http://localhost:10001/devstoreaccount1/
        // .getPath() -> /devstoreaccount1/
        accountName = pathParts[1];
    }
    else {
        throw new Error("Unable to extract accountName with provided information.");
    }
    return accountName;
}

// Copyright (c) Microsoft Corporation.
function handleTableAlreadyExists(error, options = {}) {
    var _a, _b, _c;
    const responseError = getErrorResponse(error);
    if (responseError &&
        responseError.status === 409 &&
        ((_a = responseError.parsedBody.odataError) === null || _a === void 0 ? void 0 : _a.code) === "TableAlreadyExists") {
        (_b = options.logger) === null || _b === void 0 ? void 0 : _b.info(`Table ${options.tableName} already Exists`);
        if (options.onResponse) {
            options.onResponse(responseError, {});
        }
    }
    else {
        options === null || options === void 0 ? void 0 : options.span.setStatus({ code: coreTracing.SpanStatusCode.ERROR, message: (_c = error) === null || _c === void 0 ? void 0 : _c.message });
        throw error;
    }
}
function getErrorResponse(error) {
    if (!isRestError(error)) {
        return undefined;
    }
    const errorResponse = error.response;
    if (!errorResponse || !isTableServiceErrorResponse(errorResponse.parsedBody)) {
        return undefined;
    }
    return errorResponse;
}
function isRestError(error) {
    return error.name === "RestError";
}
function isTableServiceErrorResponse(errorResponseBody) {
    return Boolean(errorResponseBody === null || errorResponseBody === void 0 ? void 0 : errorResponseBody.odataError);
}

// Copyright (c) Microsoft Corporation.
function isCredential(credential) {
    return (coreAuth.isSASCredential(credential) || coreAuth.isNamedKeyCredential(credential) || coreAuth.isTokenCredential(credential));
}

// Copyright (c) Microsoft Corporation.
/**
 * The \@azure/logger configuration for this package.
 */
const logger = logger$1.createClientLogger("data-tables");

// Copyright (c) Microsoft Corporation.
/**
 * The programmatic identifier of the tablesNamedKeyCredentialPolicy.
 */
const tablesNamedKeyCredentialPolicyName = "tablesNamedKeyCredentialPolicy";
/**
 * tablesNamedKeyCredentialPolicy is a policy used to sign HTTP request with a shared key.
 */
function tablesNamedKeyCredentialPolicy(credential) {
    function signRequest(request) {
        const headerValue = getAuthorizationHeader(request, credential);
        request.headers.set(HeaderConstants.AUTHORIZATION, headerValue);
    }
    return {
        name: tablesNamedKeyCredentialPolicyName,
        async sendRequest(request, next) {
            signRequest(request);
            return next(request);
        },
    };
}
function getAuthorizationHeader(request, credential) {
    if (!request.headers.has(HeaderConstants.X_MS_DATE)) {
        request.headers.set(HeaderConstants.X_MS_DATE, new Date().toUTCString());
    }
    if (request.body && typeof request.body === "string" && request.body.length > 0) {
        request.headers.set(HeaderConstants.CONTENT_LENGTH, Buffer.byteLength(request.body));
    }
    // If x-ms-date is present, use it otherwise date
    const dateHeader = getHeaderValueToSign(request, HeaderConstants.X_MS_DATE);
    if (!dateHeader) {
        throw new Error("Failed to sign request: x-ms-date or date header must be present");
    }
    const stringToSign = [
        dateHeader,
        getCanonicalizedResourceString(request, credential),
    ].join("\n");
    const signature = computeHMACSHA256(stringToSign, credential.key);
    return `SharedKeyLite ${credential.name}:${signature}`;
}
function getHeaderValueToSign(request, headerName) {
    const value = request.headers.get(headerName);
    if (!value) {
        return "";
    }
    return value;
}
function getCanonicalizedResourceString(request, credential) {
    // https://docs.microsoft.com/rest/api/storageservices/authorize-with-shared-key#shared-key-lite-and-table-service-format-for-2009-09-19-and-later
    const url = new url$1.URL(request.url);
    const path = url.pathname || "/";
    let canonicalizedResourceString = "/" + credential.name + path;
    // The query string should include the question mark and the comp parameter (for example, ?comp=metadata). No other parameters should be included on the query string.
    const comp = url.searchParams.get("comp");
    if (comp) {
        canonicalizedResourceString = `${canonicalizedResourceString}?comp=${comp}`;
    }
    return canonicalizedResourceString;
}

// Copyright (c) Microsoft Corporation.
/**
 * The programmatic identifier of the tablesSASTokenPolicy.
 */
const tablesSASTokenPolicyName = "tablesSASTokenPolicy";
/**
 * tablesSASTokenPolicy is a policy used to sign HTTP request with a shared key.
 */
function tablesSASTokenPolicy(credential) {
    return {
        name: tablesSASTokenPolicyName,
        async sendRequest(request, next) {
            signURLWithSAS(request, credential);
            return next(request);
        },
    };
}
function signURLWithSAS(request, credential) {
    const sasParams = new url$1.URLSearchParams(credential.signature);
    const url = new url$1.URL(request.url);
    for (const [name, value] of sasParams) {
        url.searchParams.append(name, value);
    }
    request.url = url.toString();
}

// Copyright (c) Microsoft Corporation.
/**
 * A TableServiceClient represents a Client to the Azure Tables service allowing you
 * to perform operations on the tables and the entities.
 */
class TableServiceClient {
    constructor(url, credentialOrOptions, options) {
        this.url = url;
        const credential = isCredential(credentialOrOptions) ? credentialOrOptions : undefined;
        const clientOptions = (!isCredential(credentialOrOptions) ? credentialOrOptions : options) || {};
        clientOptions.endpoint = clientOptions.endpoint || this.url;
        const internalPipelineOptions = Object.assign(Object.assign(Object.assign({}, clientOptions), {
            loggingOptions: {
                logger: logger.info,
                additionalAllowedHeaderNames: [...TablesLoggingAllowedHeaderNames],
            },
            deserializationOptions: {
                parseXML: coreXml.parseXML,
            },
            serializationOptions: {
                stringifyXML: coreXml.stringifyXML,
            },
        }), (coreAuth.isTokenCredential(credential) && { credential, credentialScopes: STORAGE_SCOPE }));
        const client = new GeneratedClient(this.url, internalPipelineOptions);
        if (coreAuth.isNamedKeyCredential(credential)) {
            client.pipeline.addPolicy(tablesNamedKeyCredentialPolicy(credential));
        }
        else if (coreAuth.isSASCredential(credential)) {
            client.pipeline.addPolicy(tablesSASTokenPolicy(credential));
        }
        this.pipeline = client.pipeline;
        this.table = client.table;
        this.service = client.service;
    }
    /**
     * Retrieves statistics related to replication for the Table service. It is only available on the
     * secondary location endpoint when read-access geo-redundant replication is enabled for the account.
     * @param options - The options parameters.
     */
    async getStatistics(options = {}) {
        const { span, updatedOptions } = createSpan("TableServiceClient-getStatistics", options);
        try {
            return await this.service.getStatistics(updatedOptions);
        }
        catch (e) {
            span.setStatus({ code: coreTracing.SpanStatusCode.ERROR, message: e.message });
            throw e;
        }
        finally {
            span.end();
        }
    }
    /**
     * Gets the properties of an account's Table service, including properties for Analytics and CORS
     * (Cross-Origin Resource Sharing) rules.
     * @param options - The options parameters.
     */
    async getProperties(options = {}) {
        const { span, updatedOptions } = createSpan("TableServiceClient-getProperties", options);
        try {
            return await this.service.getProperties(updatedOptions);
        }
        catch (e) {
            span.setStatus({ code: coreTracing.SpanStatusCode.ERROR, message: e.message });
            throw e;
        }
        finally {
            span.end();
        }
    }
    /**
     * Sets properties for an account's Table service endpoint, including properties for Analytics and CORS
     * (Cross-Origin Resource Sharing) rules.
     * @param properties - The Table Service properties.
     * @param options - The options parameters.
     */
    async setProperties(properties, options = {}) {
        const { span, updatedOptions } = createSpan("TableServiceClient-setProperties", options);
        try {
            return await this.service.setProperties(properties, updatedOptions);
        }
        catch (e) {
            span.setStatus({ code: coreTracing.SpanStatusCode.ERROR, message: e.message });
            throw e;
        }
        finally {
            span.end();
        }
    }
    /**
     * Creates a new table under the given account.
     * @param name - The name of the table.
     * @param options - The options parameters.
     */
    async createTable(name, options = {}) {
        const { span, updatedOptions } = createSpan("TableServiceClient-createTable", options);
        try {
            await this.table.create({ name }, Object.assign({}, updatedOptions));
        }
        catch (e) {
            handleTableAlreadyExists(e, Object.assign(Object.assign({}, updatedOptions), { span, logger, tableName: name }));
        }
        finally {
            span.end();
        }
    }
    /**
     * Operation permanently deletes the specified table.
     * @param name - The name of the table.
     * @param options - The options parameters.
     */
    async deleteTable(name, options = {}) {
        const { span, updatedOptions } = createSpan("TableServiceClient-deleteTable", options);
        try {
            await this.table.delete(name, updatedOptions);
        }
        catch (e) {
            if (e.statusCode === 404) {
                logger.info("TableServiceClient-deleteTable: Table doesn't exist");
            }
            else {
                span.setStatus({ code: coreTracing.SpanStatusCode.ERROR, message: e.message });
                throw e;
            }
        }
        finally {
            span.end();
        }
    }
    /**
     * Queries tables under the given account.
     * @param options - The options parameters.
     */
    listTables(
    // eslint-disable-next-line @azure/azure-sdk/ts-naming-options
    options) {
        const iter = this.listTablesAll(options);
        return {
            next() {
                return iter.next();
            },
            [Symbol.asyncIterator]() {
                return this;
            },
            byPage: (settings) => {
                const pageOptions = Object.assign(Object.assign({}, options), { queryOptions: { top: settings === null || settings === void 0 ? void 0 : settings.maxPageSize } });
                if (settings === null || settings === void 0 ? void 0 : settings.continuationToken) {
                    pageOptions.continuationToken = settings.continuationToken;
                }
                return this.listTablesPage(pageOptions);
            },
        };
    }
    listTablesAll(options) {
        return tslib.__asyncGenerator(this, arguments, function* listTablesAll_1() {
            var e_1, _a;
            const firstPage = yield tslib.__await(this._listTables(options));
            const { continuationToken } = firstPage;
            yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(firstPage)));
            if (continuationToken) {
                const optionsWithContinuation = Object.assign(Object.assign({}, options), { continuationToken });
                try {
                    for (var _b = tslib.__asyncValues(this.listTablesPage(optionsWithContinuation)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
                        const page = _c.value;
                        yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
                    }
                }
                catch (e_1_1) { e_1 = { error: e_1_1 }; }
                finally {
                    try {
                        if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
                    }
                    finally { if (e_1) throw e_1.error; }
                }
            }
        });
    }
    listTablesPage(options = {}) {
        return tslib.__asyncGenerator(this, arguments, function* listTablesPage_1() {
            const { span, updatedOptions } = createSpan("TableServiceClient-listTablesPage", options);
            try {
                let result = yield tslib.__await(this._listTables(updatedOptions));
                yield yield tslib.__await(result);
                while (result.continuationToken) {
                    const optionsWithContinuation = Object.assign(Object.assign({}, updatedOptions), { continuationToken: result.continuationToken });
                    result = yield tslib.__await(this._listTables(optionsWithContinuation));
                    yield yield tslib.__await(result);
                }
            }
            catch (e) {
                span.setStatus({ code: coreTracing.SpanStatusCode.ERROR, message: e.message });
                throw e;
            }
            finally {
                span.end();
            }
        });
    }
    async _listTables(options = {}) {
        const { continuationToken: nextTableName } = options, listOptions = tslib.__rest(options, ["continuationToken"]);
        const { xMsContinuationNextTableName: continuationToken, value = [] } = await this.table.query(Object.assign(Object.assign({}, listOptions), { nextTableName }));
        return Object.assign([...value], { continuationToken });
    }
    /**
     *
     * Creates an instance of TableServiceClient from connection string.
     *
     * @param connectionString - Account connection string or a SAS connection string of an Azure storage account.
     *                           [ Note - Account connection string can only be used in NODE.JS runtime. ]
     *                           Account connection string example -
     *                           `DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=accountKey;EndpointSuffix=core.windows.net`
     *                           SAS connection string example -
     *                           `BlobEndpoint=https://myaccount.table.core.windows.net/;QueueEndpoint=https://myaccount.queue.core.windows.net/;FileEndpoint=https://myaccount.file.core.windows.net/;TableEndpoint=https://myaccount.table.core.windows.net/;SharedAccessSignature=sasString`
     * @param options - Options to configure the HTTP pipeline.
     * @returns A new TableServiceClient from the given connection string.
     */
    static fromConnectionString(connectionString, 
    // eslint-disable-next-line @azure/azure-sdk/ts-naming-options
    options) {
        const { url, options: clientOptions, credential, } = getClientParamsFromConnectionString(connectionString, options);
        if (credential) {
            return new TableServiceClient(url, credential, clientOptions);
        }
        else {
            return new TableServiceClient(url, clientOptions);
        }
    }
}

// Copyright (c) Microsoft Corporation.
/**
 * Builds a transaction change set boundary to be added to the transaction request body
 * @param changesetId - Id of the transaction changeset
 */
function getChangeSetBoundary(changesetId) {
    return `changeset_${changesetId}`;
}
/**
 * Builds a transaction boundary to be added to the transaction request body
 * @param transactionId - Id of the transaction
 */
function getTransactionBoundary(transactionId) {
    return `batch_${transactionId}`;
}
/**
 * Returns an initial representation of the Transaction body.
 * @param transactionId - Id of the transaction
 * @param changesetId - Id of the transaction changeset
 */
function getInitialTransactionBody(transactionId, changesetId) {
    const transactionBoundary = `batch_${transactionId}`;
    return [
        `--${transactionBoundary}${TRANSACTION_HTTP_LINE_ENDING}${HeaderConstants.CONTENT_TYPE}: multipart/mixed; boundary=changeset_${changesetId}${TRANSACTION_HTTP_LINE_ENDING}${TRANSACTION_HTTP_LINE_ENDING}`,
    ];
}
/**
 * Build the Transaction http request body to send to the service.
 * @param bodyParts - Parts of the transaction body, containing information about the actions to be included in the transaction request
 * @param transactionId - Id of the transaction
 * @param changesetId - Id of the transaction changeset
 */
function getTransactionHttpRequestBody(bodyParts, transactionId, changesetId) {
    const transactionBoundary = getTransactionBoundary(transactionId);
    const changesetBoundary = getChangeSetBoundary(changesetId);
    const changesetEnding = `--${changesetBoundary}--`;
    const transactionEnding = `--${transactionBoundary}--`;
    const bodyContent = bodyParts.join(TRANSACTION_HTTP_LINE_ENDING);
    return `${bodyContent}${TRANSACTION_HTTP_LINE_ENDING}${changesetEnding}${TRANSACTION_HTTP_LINE_ENDING}${transactionEnding}${TRANSACTION_HTTP_LINE_ENDING}`;
}

// Copyright (c) Microsoft Corporation.
const transactionRequestAssemblePolicyName = "transactionRequestAssemblePolicy";
const dummyResponse = {
    request: coreRestPipeline.createPipelineRequest({ url: "FAKE" }),
    status: 200,
    headers: coreRestPipeline.createHttpHeaders(),
};
function transactionRequestAssemblePolicy(bodyParts, changesetId) {
    return {
        name: transactionRequestAssemblePolicyName,
        async sendRequest(request) {
            const subRequest = getNextSubrequestBodyPart(request, changesetId);
            bodyParts.push(subRequest);
            // Intercept request from going to wire
            return dummyResponse;
        },
    };
}
const transactionHeaderFilterPolicyName = "transactionHeaderFilterPolicy";
function transactionHeaderFilterPolicy() {
    return {
        name: transactionHeaderFilterPolicyName,
        async sendRequest(request, next) {
            // The subrequests should not have the x-ms-version header.
            request.headers.delete(HeaderConstants.X_MS_VERSION);
            return next(request);
        },
    };
}
function getSubRequestUrl(url) {
    const sasTokenParts = ["sv", "ss", "srt", "sp", "se", "st", "spr", "sig"];
    const urlParsed = new url$1.URL(url);
    sasTokenParts.forEach((part) => urlParsed.searchParams.delete(part));
    return urlParsed.toString();
}
function getNextSubrequestBodyPart(request, changesetId) {
    const changesetBoundary = getChangeSetBoundary(changesetId);
    const subRequestPrefix = `--${changesetBoundary}${TRANSACTION_HTTP_LINE_ENDING}${HeaderConstants.CONTENT_TYPE}: application/http${TRANSACTION_HTTP_LINE_ENDING}${HeaderConstants.CONTENT_TRANSFER_ENCODING}: binary`;
    const subRequestUrl = getSubRequestUrl(request.url);
    // Start to assemble sub request
    const subRequest = [
        subRequestPrefix,
        "",
        `${request.method.toString()} ${subRequestUrl} ${TRANSACTION_HTTP_VERSION_1_1}`, // sub request start line with method,
    ];
    // Add required headers
    for (const [name, value] of request.headers) {
        subRequest.push(`${name}: ${value}`);
    }
    // Append sub-request body
    subRequest.push(`${TRANSACTION_HTTP_LINE_ENDING}`); // sub request's headers need end with an empty line
    if (request.body) {
        subRequest.push(String(request.body));
    }
    // Add subrequest to transaction body
    return subRequest.join(TRANSACTION_HTTP_LINE_ENDING);
}

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
const cosmosPatchPolicyName = "cosmosPatchPolicy";
function cosmosPatchPolicy() {
    return {
        name: cosmosPatchPolicyName,
        sendRequest: (request, next) => {
            if (request.method === "PATCH") {
                request.method = "POST";
                request.headers.set("X-HTTP-Method", "MERGE");
            }
            return next(request);
        },
    };
}

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
/**
 * @internal
 * Builds an object with the required headers for a Transaction request. For both Node and Browser
 */
function getBaseTransactionHeaders(transactionGuid) {
    return {
        accept: "application/json",
        "x-ms-version": "2019-02-02",
        DataServiceVersion: "3.0;",
        MaxDataServiceVersion: "3.0;NetFx",
        "Content-Type": `multipart/mixed; boundary=batch_${transactionGuid}`,
    };
}

// Copyright (c) Microsoft Corporation.
/**
 * @internal
 * Builds an object with the required headers for a Transaction request. For Node
 */
function getTransactionHeaders(transactionGuid) {
    const baseHeaders = getBaseTransactionHeaders(transactionGuid);
    return Object.assign(Object.assign({}, baseHeaders), { 
        // The below headers are not supported in the browser as they are flagged as "unsafe headers"
        "Accept-Charset": "UTF-8", Connection: "Keep-Alive" });
}

// Copyright (c) Microsoft Corporation.
function isCosmosEndpoint(url) {
    const parsedURL = new url$1.URL(url);
    if (parsedURL.hostname.indexOf(".table.cosmosdb.") !== -1) {
        return true;
    }
    if (parsedURL.hostname.indexOf(".table.cosmos.") !== -1) {
        return true;
    }
    if (parsedURL.hostname === "localhost" && parsedURL.port !== "10002") {
        return true;
    }
    return false;
}

// Copyright (c) Microsoft Corporation.
/**
 * Helper to build a list of transaction actions
 */
class TableTransaction {
    constructor(actions) {
        this.actions = actions !== null && actions !== void 0 ? actions : [];
    }
    /**
     * Adds a create action to the transaction
     * @param entity - entity to create
     */
    createEntity(entity) {
        this.actions.push(["create", entity]);
    }
    /**
     * Adds a delete action to the transaction
     * @param partitionKey - partition key of the entity to delete
     * @param rowKey - rowKey of the entity to delete
     */
    deleteEntity(partitionKey, rowKey) {
        this.actions.push(["delete", { partitionKey, rowKey }]);
    }
    /**
     * Adds an update action to the transaction
     * @param entity - entity to update
     * @param updateMode - update mode
     */
    updateEntity(entity, updateMode = "Merge") {
        this.actions.push(["update", entity, updateMode]);
    }
    /**
     * Adds an upsert action to the transaction, which inserts if the entity doesn't exist or updates the existing one
     * @param entity - entity to upsert
     * @param updateMode - update mode
     */
    upsertEntity(entity, updateMode = "Merge") {
        this.actions.push(["upsert", entity, updateMode]);
    }
}
/**
 * TableTransaction collects sub-operations that can be submitted together via submitTransaction
 */
class InternalTableTransaction {
    /**
     * @param url - Tables account url
     * @param partitionKey - partition key
     * @param credential - credential to authenticate the transaction request
     */
    constructor(url, partitionKey, transactionId, changesetId, clientOptions, interceptClient, credential, allowInsecureConnection = false) {
        this.clientOptions = clientOptions;
        this.credential = credential;
        this.url = url;
        this.interceptClient = interceptClient;
        this.allowInsecureConnection = allowInsecureConnection;
        // Initialize Reset-able properties
        this.resetableState = this.initializeSharedState(transactionId, changesetId, partitionKey);
        // Depending on the auth method used we need to build the url
        if (!credential) {
            // When the SAS token is provided as part of the URL we need to move it after $batch
            const urlParts = url.split("?");
            this.url = urlParts[0];
            const sas = urlParts.length > 1 ? `?${urlParts[1]}` : "";
            this.url = `${this.getUrlWithSlash()}$batch${sas}`;
        }
        else {
            // When using a SharedKey credential no SAS token is needed
            this.url = `${this.getUrlWithSlash()}$batch`;
        }
    }
    /**
     * Resets the state of the Transaction.
     */
    reset(transactionId, changesetId, partitionKey) {
        this.resetableState = this.initializeSharedState(transactionId, changesetId, partitionKey);
    }
    initializeSharedState(transactionId, changesetId, partitionKey) {
        const pendingOperations = [];
        const bodyParts = getInitialTransactionBody(transactionId, changesetId);
        const isCosmos = isCosmosEndpoint(this.url);
        prepateTransactionPipeline(this.interceptClient.pipeline, bodyParts, changesetId, isCosmos);
        return {
            transactionId,
            changesetId,
            partitionKey,
            pendingOperations,
            bodyParts,
        };
    }
    /**
     * Adds a createEntity operation to the transaction
     * @param entity - Entity to create
     */
    createEntity(entity) {
        this.checkPartitionKey(entity.partitionKey);
        this.resetableState.pendingOperations.push(this.interceptClient.createEntity(entity));
    }
    /**
     * Adds a createEntity operation to the transaction per each entity in the entities array
     * @param entities - Array of entities to create
     */
    createEntities(entities) {
        for (const entity of entities) {
            this.checkPartitionKey(entity.partitionKey);
            this.resetableState.pendingOperations.push(this.interceptClient.createEntity(entity));
        }
    }
    /**
     * Adds a deleteEntity operation to the transaction
     * @param partitionKey - Partition key of the entity to delete
     * @param rowKey - Row key of the entity to delete
     * @param options - Options for the delete operation
     */
    deleteEntity(partitionKey, rowKey, options) {
        this.checkPartitionKey(partitionKey);
        this.resetableState.pendingOperations.push(this.interceptClient.deleteEntity(partitionKey, rowKey, options));
    }
    /**
     * Adds an updateEntity operation to the transaction
     * @param entity - Entity to update
     * @param mode - Update mode (Merge or Replace)
     * @param options - Options for the update operation
     */
    updateEntity(entity, mode, options) {
        this.checkPartitionKey(entity.partitionKey);
        this.resetableState.pendingOperations.push(this.interceptClient.updateEntity(entity, mode, options));
    }
    /**
     * Adds an upsertEntity operation to the transaction
     * @param entity - The properties for the table entity.
     * @param mode   - The different modes for updating the entity:
     *               - Merge: Updates an entity by updating the entity's properties without replacing the existing entity.
     *               - Replace: Updates an existing entity by replacing the entire entity.
     * @param options - The options parameters.
     */
    upsertEntity(entity, mode, options) {
        this.checkPartitionKey(entity.partitionKey);
        this.resetableState.pendingOperations.push(this.interceptClient.upsertEntity(entity, mode, options));
    }
    /**
     * Submits the operations in the transaction
     */
    async submitTransaction() {
        await Promise.all(this.resetableState.pendingOperations);
        const body = getTransactionHttpRequestBody(this.resetableState.bodyParts, this.resetableState.transactionId, this.resetableState.changesetId);
        const options = this.clientOptions;
        if (coreAuth.isTokenCredential(this.credential)) {
            options.credentialScopes = STORAGE_SCOPE;
            options.credential = this.credential;
        }
        const client = new coreClient.ServiceClient(options);
        const headers = getTransactionHeaders(this.resetableState.transactionId);
        const { span, updatedOptions } = createSpan("TableTransaction-submitTransaction", {});
        const request = coreRestPipeline.createPipelineRequest({
            url: this.url,
            method: "POST",
            body,
            headers: coreRestPipeline.createHttpHeaders(headers),
            tracingOptions: updatedOptions.tracingOptions,
            allowInsecureConnection: this.allowInsecureConnection,
        });
        if (coreAuth.isNamedKeyCredential(this.credential)) {
            const authHeader = getAuthorizationHeader(request, this.credential);
            request.headers.set("Authorization", authHeader);
        }
        else if (coreAuth.isSASCredential(this.credential)) {
            signURLWithSAS(request, this.credential);
        }
        try {
            const rawTransactionResponse = await client.sendRequest(request);
            return parseTransactionResponse(rawTransactionResponse);
        }
        catch (error) {
            span.setStatus({
                code: coreTracing.SpanStatusCode.ERROR,
                message: error.message,
            });
            throw error;
        }
        finally {
            span.end();
        }
    }
    checkPartitionKey(partitionKey) {
        if (this.resetableState.partitionKey !== partitionKey) {
            throw new Error("All operations in a transaction must target the same partitionKey");
        }
    }
    getUrlWithSlash() {
        return this.url.endsWith("/") ? this.url : `${this.url}/`;
    }
}
function parseTransactionResponse(transactionResponse) {
    const subResponsePrefix = `--changesetresponse_`;
    const status = transactionResponse.status;
    const rawBody = transactionResponse.bodyAsText || "";
    const splitBody = rawBody.split(subResponsePrefix);
    const isSuccessByStatus = 200 <= status && status < 300;
    if (!isSuccessByStatus) {
        handleBodyError(rawBody, status, transactionResponse.request, transactionResponse);
    }
    // Dropping the first and last elements as they are the boundaries
    // we just care about sub request content
    const subResponses = splitBody.slice(1, splitBody.length - 1);
    const responses = subResponses.map((subResponse) => {
        const statusMatch = subResponse.match(/HTTP\/1.1 ([0-9]*)/);
        if ((statusMatch === null || statusMatch === void 0 ? void 0 : statusMatch.length) !== 2) {
            throw new Error(`Couldn't extract status from sub-response:\n ${subResponse}`);
        }
        const subResponseStatus = Number.parseInt(statusMatch[1]);
        if (!Number.isInteger(subResponseStatus)) {
            throw new Error(`Expected sub-response status to be an integer ${subResponseStatus}`);
        }
        const bodyMatch = subResponse.match(/\{(.*)\}/);
        if ((bodyMatch === null || bodyMatch === void 0 ? void 0 : bodyMatch.length) === 2) {
            handleBodyError(bodyMatch[0], subResponseStatus, transactionResponse.request, transactionResponse);
        }
        const etagMatch = subResponse.match(/ETag: (.*)/);
        const rowKeyMatch = subResponse.match(/RowKey='(.*)'/);
        return Object.assign(Object.assign({ status: subResponseStatus }, ((rowKeyMatch === null || rowKeyMatch === void 0 ? void 0 : rowKeyMatch.length) === 2 && { rowKey: rowKeyMatch[1] })), ((etagMatch === null || etagMatch === void 0 ? void 0 : etagMatch.length) === 2 && { etag: etagMatch[1] }));
    });
    return {
        status,
        subResponses: responses,
        getResponseForEntity: (rowKey) => responses.find((r) => r.rowKey === rowKey),
    };
}
function handleBodyError(bodyAsText, statusCode, request, response) {
    var _a, _b;
    let parsedError;
    try {
        parsedError = JSON.parse(bodyAsText);
    }
    catch (_c) {
        parsedError = {};
    }
    let message = "Transaction Failed";
    let code;
    // Only transaction sub-responses return body
    if (parsedError && parsedError["odata.error"]) {
        const error = parsedError["odata.error"];
        message = (_b = (_a = error.message) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : message;
        code = error.code;
    }
    throw new coreRestPipeline.RestError(message, {
        code,
        statusCode,
        request,
        response,
    });
}
/**
 * Prepares the transaction pipeline to intercept operations
 * @param pipeline - Client pipeline
 */
function prepateTransactionPipeline(pipeline, bodyParts, changesetId, isCosmos) {
    // Fist, we need to clear all the existing policies to make sure we start
    // with a fresh state.
    const policies = pipeline.getOrderedPolicies();
    for (const policy of policies) {
        pipeline.removePolicy({
            name: policy.name,
        });
    }
    // With the clear state we now initialize the pipelines required for intercepting the requests.
    // Use transaction assemble policy to assemble request and intercept request from going to wire
    pipeline.addPolicy(coreClient.serializationPolicy(), { phase: "Serialize" });
    pipeline.addPolicy(transactionHeaderFilterPolicy());
    pipeline.addPolicy(transactionRequestAssemblePolicy(bodyParts, changesetId));
    if (isCosmos) {
        pipeline.addPolicy(cosmosPatchPolicy(), {
            afterPolicies: [transactionHeaderFilterPolicyName],
            beforePolicies: [coreClient.serializationPolicyName, transactionRequestAssemblePolicyName],
        });
    }
}

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
/**
 * Encodes a byte array in base64 format.
 * @param value - The Uint8Aray or string to encode
 */
function base64Encode(value) {
    if (value instanceof Uint8Array) {
        const bufferValue = value instanceof Buffer ? value : Buffer.from(value.buffer);
        return bufferValue.toString("base64");
    }
    else {
        return Buffer.from(value).toString("base64");
    }
}
/**
 * Decodes a base64 string into a byte array.
 * @param value - The base64 string to decode
 */
function base64Decode(value) {
    return Buffer.from(value, "base64");
}

// Copyright (c) Microsoft Corporation.
/**
 * Encodes the nextPartitionKey and nextRowKey into a single continuation token
 */
function encodeContinuationToken(nextPartitionKey = "", nextRowKey = "") {
    if (!nextPartitionKey && !nextRowKey) {
        return undefined;
    }
    const continuationToken = JSON.stringify({
        nextPartitionKey,
        nextRowKey,
    });
    return base64Encode(continuationToken);
}
/**
 * Decodes a continuationToken into an object containing a nextPartitionKey and nextRowKey
 */
function decodeContinuationToken(encodedToken) {
    const decodedToken = base64Decode(encodedToken);
    let tokenStr = "";
    for (const byte of decodedToken) {
        tokenStr += String.fromCharCode(byte);
    }
    const continuationToken = JSON.parse(tokenStr);
    return continuationToken;
}

// Copyright (c) Microsoft Corporation.
const propertyCaseMap = new Map([
    ["PartitionKey", "partitionKey"],
    ["RowKey", "rowKey"],
    ["odata.etag", "etag"],
    ["Timestamp", "timestamp"],
]);
const Edm = {
    Binary: "Edm.Binary",
    Boolean: "Edm.Boolean",
    DateTime: "Edm.DateTime",
    Double: "Edm.Double",
    Guid: "Edm.Guid",
    Int32: "Edm.Int32",
    Int64: "Edm.Int64",
    String: "Edm.String",
};
function serializePrimitive(value) {
    const serializedValue = { value };
    if (value === undefined ||
        value === null ||
        typeof value === "boolean" ||
        typeof value === "string" ||
        typeof value === "number") {
        serializedValue.value = value;
    }
    else if (typeof value === "bigint") {
        serializedValue.value = value.toString();
        serializedValue.type = Edm.Int64;
    }
    else if (value instanceof Date) {
        serializedValue.value = value;
        serializedValue.type = Edm.DateTime;
    }
    else if (value instanceof Uint8Array) {
        serializedValue.value = base64Encode(value);
        serializedValue.type = Edm.Binary;
    }
    else {
        throw new Error(`Unknown EDM type ${typeof value}`);
    }
    return serializedValue;
}
function serializeObject(obj) {
    const serializedValue = { value: obj.value };
    if (obj.type === "Boolean" ||
        obj.type === "DateTime" ||
        obj.type === "Double" ||
        obj.type === "Guid" ||
        obj.type === "Int32" ||
        obj.type === "Int64" ||
        obj.type === "String" ||
        obj.type === "Binary") {
        serializedValue.value = obj.value;
        serializedValue.type = Edm[obj.type];
    }
    else {
        throw new Error(`Unknown EDM type ${typeof obj.value}`);
    }
    return serializedValue;
}
function getSerializedValue(value) {
    if (typeof value === "object" && (value === null || value === void 0 ? void 0 : value.value) !== undefined && (value === null || value === void 0 ? void 0 : value.type) !== undefined) {
        return serializeObject(value);
    }
    else {
        return serializePrimitive(value);
    }
}
function translatePropertyNameForSerialization(propertyName) {
    for (const [original, internal] of propertyCaseMap) {
        if (internal === propertyName) {
            return original;
        }
    }
    return propertyName;
}
function serialize(obj) {
    const serialized = {};
    for (const [propertyName, propertyValue] of Object.entries(obj)) {
        const transformedKey = translatePropertyNameForSerialization(propertyName);
        const serializedVal = getSerializedValue(propertyValue);
        serialized[transformedKey] = serializedVal.value;
        if (serializedVal.type) {
            serialized[`${transformedKey}@odata.type`] = serializedVal.type;
        }
    }
    return serialized;
}
function getTypedObject(value, type, disableTypeConversion) {
    switch (type) {
        case Edm.Boolean:
            return disableTypeConversion ? { value, type: "Boolean" } : value;
        case Edm.Double:
            return disableTypeConversion ? { value, type: "Double" } : value;
        case Edm.Int32:
            return disableTypeConversion ? { value, type: "Int32" } : value;
        case Edm.String:
            return disableTypeConversion ? { value, type: "String" } : value;
        case Edm.DateTime:
            return disableTypeConversion ? { value, type: "DateTime" } : new Date(value);
        case Edm.Int64:
            return disableTypeConversion ? { value, type: "Int64" } : BigInt(value);
        case Edm.Guid:
            return { value, type: "Guid" };
        case Edm.Binary:
            return disableTypeConversion ? { value, type: "Binary" } : base64Decode(value);
        default:
            throw new Error(`Unknown EDM type ${type}`);
    }
}
function deserialize(obj, disableTypeConversion = false) {
    var _a;
    const deserialized = {};
    for (const [key, value] of Object.entries(obj)) {
        if (key.indexOf("@odata.type") === -1) {
            const transformedKey = (_a = propertyCaseMap.get(key)) !== null && _a !== void 0 ? _a : key;
            let typedValue = value;
            if (`${key}@odata.type` in obj) {
                const type = obj[`${key}@odata.type`];
                typedValue = getTypedObject(value, type, disableTypeConversion);
            }
            else if (disableTypeConversion && ["number", "string", "boolean"].includes(typeof value)) {
                // The service, doesn't return type metadata for number, strings or booleans
                // if automatic type conversion is disabled we'll infer the EDM object
                typedValue = inferTypedObject(key, value);
            }
            deserialized[transformedKey] = typedValue;
        }
    }
    return deserialized;
}
function inferTypedObject(propertyName, value) {
    // We need to skip service metadata fields such as partitionKey and rowKey and use the same value returned by the service
    if (propertyCaseMap.has(propertyName)) {
        return value;
    }
    switch (typeof value) {
        case "boolean":
            return { value: String(value), type: "Boolean" };
        case "number":
            return getTypedNumber(value);
        case "string":
            return { value, type: "String" };
        default:
            return value;
    }
}
/**
 * Returns the number when typeConversion is enabled or the EDM object with the correct number format Double or Int32 if disabled
 */
function getTypedNumber(value) {
    const valueStr = String(value);
    if (Number.isSafeInteger(value)) {
        return { value: valueStr, type: "Int32" };
    }
    else {
        return { value: valueStr, type: "Double" };
    }
}
function deserializeObjectsArray(objArray, disableTypeConversion) {
    return objArray.map((obj) => deserialize(obj, disableTypeConversion));
}
/**
 * For ACL endpoints the Tables Service takes an ISO Date without decimals however
 * serializing a JavaScript date gives us a date with decimals 2021-07-08T09:10:09.000Z
 * which makes the XML request body invalid, these 2 functions serialize and deserialize the
 * dates so that they are in the expected format
 */
function serializeSignedIdentifiers(signedIdentifiers) {
    return signedIdentifiers.map((acl) => {
        const { id, accessPolicy } = acl;
        const _a = accessPolicy !== null && accessPolicy !== void 0 ? accessPolicy : {}, { start, expiry } = _a, rest = tslib.__rest(_a, ["start", "expiry"]);
        const serializedStart = start
            ? truncatedISO8061Date(start, false /** withMilliseconds */)
            : undefined;
        const serializedExpiry = expiry
            ? truncatedISO8061Date(expiry, false /** withMilliseconds */)
            : undefined;
        return {
            id,
            accessPolicy: Object.assign(Object.assign(Object.assign({}, (serializedExpiry && { expiry: serializedExpiry })), (serializedStart && { start: serializedStart })), rest),
        };
    });
}
function deserializeSignedIdentifier(signedIdentifiers) {
    return signedIdentifiers.map((si) => {
        const { id, accessPolicy } = si;
        const _a = accessPolicy !== null && accessPolicy !== void 0 ? accessPolicy : {}, { start, expiry } = _a, restAcl = tslib.__rest(_a, ["start", "expiry"]);
        const deserializedStart = start ? new Date(start) : undefined;
        const deserializedExpiry = expiry ? new Date(expiry) : undefined;
        return {
            id,
            accessPolicy: Object.assign(Object.assign(Object.assign({}, (deserializedExpiry && { expiry: deserializedExpiry })), (deserializedStart && { start: deserializedStart })), restAcl),
        };
    });
}
function serializeQueryOptions(query) {
    const { select } = query, queryOptions = tslib.__rest(query, ["select"]);
    const mappedQuery = Object.assign({}, queryOptions);
    // Properties that are always returned by the service but are not allowed in select
    const excludeFromSelect = ["etag", "odata.etag"];
    if (select) {
        mappedQuery.select = select
            .filter((p) => !excludeFromSelect.includes(p))
            .map(translatePropertyNameForSerialization)
            .join(",");
    }
    return mappedQuery;
}

// Copyright (c) Microsoft Corporation.
// This is used as a workaround to be able to stub generateUuid
// during testing.
class Uuid {
    static generateUuid() {
        return uuid.v4();
    }
}

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
function escapeQuotesIfString(input, previous) {
    let result = input;
    if (typeof input === "string") {
        result = escapeQuotes(input);
        // check if we need to escape this literal
        if (!previous.trim().endsWith("'")) {
            result = `'${result}'`;
        }
    }
    return result;
}
function escapeQuotes(input) {
    return input.replace(/'/g, "''");
}
/**
 * Escapes an odata filter expression to avoid errors with quoting string literals.
 */
function odata(strings, ...values) {
    const results = [];
    for (let i = 0; i < strings.length; i++) {
        results.push(strings[i]);
        if (i < values.length) {
            results.push(escapeQuotesIfString(values[i], strings[i]));
        }
    }
    return results.join("");
}

// Copyright (c) Microsoft Corporation.
/**
 * A TableClient represents a Client to the Azure Tables service allowing you
 * to perform operations on a single table.
 */
class TableClient {
    constructor(url, tableName, credentialOrOptions, options = {}) {
        var _a;
        this.url = url;
        this.tableName = tableName;
        const credential = isCredential(credentialOrOptions) ? credentialOrOptions : undefined;
        this.credential = credential;
        this.clientOptions = (!isCredential(credentialOrOptions) ? credentialOrOptions : options) || {};
        this.allowInsecureConnection = (_a = this.clientOptions.allowInsecureConnection) !== null && _a !== void 0 ? _a : false;
        this.clientOptions.endpoint = this.clientOptions.endpoint || this.url;
        const internalPipelineOptions = Object.assign(Object.assign(Object.assign({}, this.clientOptions), { loggingOptions: {
                logger: logger.info,
                additionalAllowedHeaderNames: [...TablesLoggingAllowedHeaderNames],
            }, deserializationOptions: {
                parseXML: coreXml.parseXML,
            }, serializationOptions: {
                stringifyXML: coreXml.stringifyXML,
            } }), (coreAuth.isTokenCredential(this.credential) && {
            credential: this.credential,
            credentialScopes: STORAGE_SCOPE,
        }));
        const generatedClient = new GeneratedClient(this.url, internalPipelineOptions);
        if (coreAuth.isNamedKeyCredential(credential)) {
            generatedClient.pipeline.addPolicy(tablesNamedKeyCredentialPolicy(credential));
        }
        else if (coreAuth.isSASCredential(credential)) {
            generatedClient.pipeline.addPolicy(tablesSASTokenPolicy(credential));
        }
        if (isCosmosEndpoint(this.url)) {
            generatedClient.pipeline.addPolicy(cosmosPatchPolicy());
        }
        this.table = generatedClient.table;
        this.pipeline = generatedClient.pipeline;
    }
    /**
     * Permanently deletes the current table with all of its entities.
     * @param options - The options parameters.
     *
     * ### Example deleting a table
     * ```js
     * const { AzureNamedKeyCredential, TableClient } = require("@azure/data-tables")
     * const account = "<storage account name>";
     * const accountKey = "<account key>"
     * const tableName = "<table name>";
     * const sharedKeyCredential = new AzureNamedKeyCredential(account, accountKey);
     *
     * const client = new TableClient(
     *   `https://${account}.table.core.windows.net`,
     *   `${tableName}`,
     *   sharedKeyCredential
     * );
     *
     * // calling deleteTable will delete the table used
     * // to instantiate the TableClient.
     * // Note: If the table doesn't exist this function doesn't fail.
     * await client.deleteTable();
     * ```
     */
    // eslint-disable-next-line @azure/azure-sdk/ts-naming-options
    async deleteTable(options = {}) {
        const { span, updatedOptions } = createSpan("TableClient-deleteTable", options);
        try {
            await this.table.delete(this.tableName, updatedOptions);
        }
        catch (e) {
            if (e.statusCode === 404) {
                logger.info("TableClient-deleteTable: Table doesn't exist");
            }
            else {
                span.setStatus({ code: coreTracing.SpanStatusCode.ERROR, message: e.message });
                throw e;
            }
        }
        finally {
            span.end();
        }
    }
    /**
     *  Creates a table with the tableName passed to the client constructor
     * @param options - The options parameters.
     *
     * ### Example creating a table
     * ```js
     * const { AzureNamedKeyCredential, TableClient } = require("@azure/data-tables")
     * const account = "<storage account name>";
     * const accountKey = "<account key>"
     * const tableName = "<table name>";
     * const sharedKeyCredential = new AzureNamedKeyCredential(account, accountKey);
     *
     * const client = new TableClient(
     *   `https://${account}.table.core.windows.net`,
     *   `${tableName}`,
     *   sharedKeyCredential
     * );
     *
     * // calling create table will create the table used
     * // to instantiate the TableClient.
     * // Note: If the table already
     * // exists this function doesn't throw.
     * await client.createTable();
     * ```
     */
    // eslint-disable-next-line @azure/azure-sdk/ts-naming-options
    async createTable(options = {}) {
        const { span, updatedOptions } = createSpan("TableClient-createTable", options);
        try {
            await this.table.create({ name: this.tableName }, updatedOptions);
        }
        catch (e) {
            handleTableAlreadyExists(e, Object.assign(Object.assign({}, updatedOptions), { span, logger, tableName: this.tableName }));
        }
        finally {
            span.end();
        }
    }
    /**
     * Returns a single entity in the table.
     * @param partitionKey - The partition key of the entity.
     * @param rowKey - The row key of the entity.
     * @param options - The options parameters.
     *
     * ### Example getting an entity
     * ```js
     * const { AzureNamedKeyCredential, TableClient } = require("@azure/data-tables")
     * const account = "<storage account name>";
     * const accountKey = "<account key>"
     * const tableName = "<table name>";
     * const sharedKeyCredential = new AzureNamedKeyCredential(account, accountKey);
     *
     * const client = new TableClient(
     *   `https://${account}.table.core.windows.net`,
     *   `${tableName}`,
     *   sharedKeyCredential
     * );
     *
     * // getEntity will get a single entity stored in the service that
     * // matches exactly the partitionKey and rowKey used as parameters
     * // to the method.
     * const entity = await client.getEntity("<partitionKey>", "<rowKey>");
     * console.log(entity);
     * ```
     */
    async getEntity(partitionKey, rowKey, 
    // eslint-disable-next-line @azure/azure-sdk/ts-naming-options
    options = {}) {
        const { span, updatedOptions } = createSpan("TableClient-getEntity", options);
        let parsedBody;
        function onResponse(rawResponse, flatResponse) {
            parsedBody = rawResponse.parsedBody;
            if (updatedOptions.onResponse) {
                updatedOptions.onResponse(rawResponse, flatResponse);
            }
        }
        try {
            const _a = updatedOptions || {}, { disableTypeConversion, queryOptions } = _a, getEntityOptions = tslib.__rest(_a, ["disableTypeConversion", "queryOptions"]);
            await this.table.queryEntitiesWithPartitionAndRowKey(this.tableName, escapeQuotes(partitionKey), escapeQuotes(rowKey), Object.assign(Object.assign({}, getEntityOptions), { queryOptions: serializeQueryOptions(queryOptions || {}), onResponse }));
            const tableEntity = deserialize(parsedBody, disableTypeConversion !== null && disableTypeConversion !== void 0 ? disableTypeConversion : false);
            return tableEntity;
        }
        catch (e) {
            span.setStatus({ code: coreTracing.SpanStatusCode.ERROR, message: e.message });
            throw e;
        }
        finally {
            span.end();
        }
    }
    /**
     * Queries entities in a table.
     * @param options - The options parameters.
     *
     * Example listing entities
     * ```js
     * const { AzureNamedKeyCredential, TableClient } = require("@azure/data-tables")
     * const account = "<storage account name>";
     * const accountKey = "<account key>"
     * const tableName = "<table name>";
     * const sharedKeyCredential = new AzureNamedKeyCredential(account, accountKey);
     *
     * const client = new TableClient(
     *   `https://${account}.table.core.windows.net`,
     *   `${tableName}`,
     *   sharedKeyCredential
     * );
     *
     * // list entities returns a AsyncIterableIterator
     * // this helps consuming paginated responses by
     * // automatically handling getting the next pages
     * const entities = client.listEntities();
     *
     * // this loop will get all the entities from all the pages
     * // returned by the service
     * for await (const entity of entities) {
     *    console.log(entity);
     * }
     * ```
     */
    listEntities(
    // eslint-disable-next-line @azure/azure-sdk/ts-naming-options
    options = {}) {
        const tableName = this.tableName;
        const iter = this.listEntitiesAll(tableName, options);
        return {
            next() {
                return iter.next();
            },
            [Symbol.asyncIterator]() {
                return this;
            },
            byPage: (settings) => {
                const pageOptions = Object.assign(Object.assign({}, options), { queryOptions: Object.assign(Object.assign({}, options.queryOptions), { top: settings === null || settings === void 0 ? void 0 : settings.maxPageSize }) });
                if (settings === null || settings === void 0 ? void 0 : settings.continuationToken) {
                    pageOptions.continuationToken = settings.continuationToken;
                }
                return this.listEntitiesPage(tableName, pageOptions);
            },
        };
    }
    listEntitiesAll(tableName, options) {
        return tslib.__asyncGenerator(this, arguments, function* listEntitiesAll_1() {
            var e_1, _a;
            const firstPage = yield tslib.__await(this._listEntities(tableName, options));
            yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(firstPage)));
            if (firstPage.continuationToken) {
                const optionsWithContinuation = Object.assign(Object.assign({}, options), { continuationToken: firstPage.continuationToken });
                try {
                    for (var _b = tslib.__asyncValues(this.listEntitiesPage(tableName, optionsWithContinuation)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
                        const page = _c.value;
                        yield tslib.__await(yield* tslib.__asyncDelegator(tslib.__asyncValues(page)));
                    }
                }
                catch (e_1_1) { e_1 = { error: e_1_1 }; }
                finally {
                    try {
                        if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
                    }
                    finally { if (e_1) throw e_1.error; }
                }
            }
        });
    }
    listEntitiesPage(tableName, options = {}) {
        return tslib.__asyncGenerator(this, arguments, function* listEntitiesPage_1() {
            const { span, updatedOptions } = createSpan("TableClient-listEntitiesPage", options);
            try {
                let result = yield tslib.__await(this._listEntities(tableName, updatedOptions));
                yield yield tslib.__await(result);
                while (result.continuationToken) {
                    const optionsWithContinuation = Object.assign(Object.assign({}, updatedOptions), { continuationToken: result.continuationToken });
                    result = yield tslib.__await(this._listEntities(tableName, optionsWithContinuation));
                    yield yield tslib.__await(result);
                }
            }
            catch (e) {
                span.setStatus({
                    code: coreTracing.SpanStatusCode.ERROR,
                    message: e.message,
                });
                throw e;
            }
            finally {
                span.end();
            }
        });
    }
    async _listEntities(tableName, options = {}) {
        const { disableTypeConversion = false } = options;
        const queryOptions = serializeQueryOptions(options.queryOptions || {});
        const listEntitiesOptions = Object.assign(Object.assign({}, options), { queryOptions });
        // If a continuation token is used, decode it and set the next row and partition key
        if (options.continuationToken) {
            const continuationToken = decodeContinuationToken(options.continuationToken);
            listEntitiesOptions.nextRowKey = continuationToken.nextRowKey;
            listEntitiesOptions.nextPartitionKey = continuationToken.nextPartitionKey;
        }
        const { xMsContinuationNextPartitionKey: nextPartitionKey, xMsContinuationNextRowKey: nextRowKey, value, } = await this.table.queryEntities(tableName, listEntitiesOptions);
        const tableEntities = deserializeObjectsArray(value !== null && value !== void 0 ? value : [], disableTypeConversion);
        // Encode nextPartitionKey and nextRowKey as a single continuation token and add it as a
        // property to the page.
        const continuationToken = encodeContinuationToken(nextPartitionKey, nextRowKey);
        const page = Object.assign([...tableEntities], {
            continuationToken,
        });
        return page;
    }
    /**
     * Insert entity in the table.
     * @param entity - The properties for the table entity.
     * @param options - The options parameters.
     *
     * ### Example creating an entity
     * ```js
     * const { AzureNamedKeyCredential, TableClient } = require("@azure/data-tables")
     * const account = "<storage account name>";
     * const accountKey = "<account key>"
     * const tableName = "<table name>";
     * const sharedKeyCredential = new AzureNamedKeyCredential(account, accountKey);
     *
     * const client = new TableClient(
     *   `https://${account}.table.core.windows.net`,
     *   `${tableName}`,
     *   sharedKeyCredential
     * );
     *
     * // partitionKey and rowKey are required properties of the entity to create
     * // and accepts any other properties
     * await client.createEntity({partitionKey: "p1", rowKey: "r1", foo: "Hello!"});
     * ```
     */
    async createEntity(entity, 
    // eslint-disable-next-line @azure/azure-sdk/ts-naming-options
    options = {}) {
        const { span, updatedOptions } = createSpan("TableClient-createEntity", options);
        try {
            const createTableEntity = tslib.__rest(updatedOptions || {}, []);
            return await this.table.insertEntity(this.tableName, Object.assign(Object.assign({}, createTableEntity), { tableEntityProperties: serialize(entity), responsePreference: "return-no-content" }));
        }
        catch (e) {
            span.setStatus({ code: coreTracing.SpanStatusCode.ERROR, message: e.message });
            throw e;
        }
        finally {
            span.end();
        }
    }
    /**
     * Deletes the specified entity in the table.
     * @param partitionKey - The partition key of the entity.
     * @param rowKey - The row key of the entity.
     * @param options - The options parameters.
     *
     * ### Example deleting an entity
     * ```js
     * const { AzureNamedKeyCredential, TableClient } = require("@azure/data-tables")
     * const account = "<storage account name>";
     * const accountKey = "<account key>"
     * const tableName = "<table name>";
     * const sharedKeyCredential = new AzureNamedKeyCredential(account, accountKey);
     *
     * const client = new TableClient(
     *   `https://${account}.table.core.windows.net`,
     *   `${tableName}`,
     *   sharedKeyCredential
     * );
     *
     * // deleteEntity deletes the entity that matches
     * // exactly the partitionKey and rowKey passed as parameters
     * await client.deleteEntity("<partitionKey>", "<rowKey>")
     * ```
     */
    async deleteEntity(partitionKey, rowKey, 
    // eslint-disable-next-line @azure/azure-sdk/ts-naming-options
    options = {}) {
        const { span, updatedOptions } = createSpan("TableClient-deleteEntity", options);
        try {
            const _a = updatedOptions || {}, { etag = "*" } = _a, rest = tslib.__rest(_a, ["etag"]);
            const deleteOptions = Object.assign({}, rest);
            return await this.table.deleteEntity(this.tableName, escapeQuotes(partitionKey), escapeQuotes(rowKey), etag, deleteOptions);
        }
        catch (e) {
            span.setStatus({ code: coreTracing.SpanStatusCode.ERROR, message: e.message });
            throw e;
        }
        finally {
            span.end();
        }
    }
    /**
     * Update an entity in the table.
     * @param entity - The properties of the entity to be updated.
     * @param mode - The different modes for updating the entity:
     *               - Merge: Updates an entity by updating the entity's properties without replacing the existing entity.
     *               - Replace: Updates an existing entity by replacing the entire entity.
     * @param options - The options parameters.
     *
     * ### Example updating an entity
     * ```js
     * const { AzureNamedKeyCredential, TableClient } = require("@azure/data-tables")
     * const account = "<storage account name>";
     * const accountKey = "<account key>"
     * const tableName = "<table name>";
     * const sharedKeyCredential = new AzureNamedKeyCredential(account, accountKey);
     *
     * const client = new TableClient(
     *   `https://${account}.table.core.windows.net`,
     *   `${tableName}`,
     *   sharedKeyCredential
     * );
     *
     * const entity = {partitionKey: "p1", rowKey: "r1", bar: "updatedBar"};
     *
     * // Update uses update mode "Merge" as default
     * // merge means that update will match a stored entity
     * // that has the same partitionKey and rowKey as the entity
     * // passed to the method and then will only update the properties present in it.
     * // Any other properties that are not defined in the entity passed to updateEntity
     * // will remain as they are in the service
     * await client.updateEntity(entity)
     *
     * // We can also set the update mode to Replace, which will match the entity passed
     * // to updateEntity with one stored in the service and replace with the new one.
     * // If there are any missing properties in the entity passed to updateEntity, they
     * // will be removed from the entity stored in the service
     * await client.updateEntity(entity, "Replace")
     * ```
     */
    async updateEntity(entity, mode = "Merge", 
    // eslint-disable-next-line @azure/azure-sdk/ts-naming-options
    options = {}) {
        const { span, updatedOptions } = createSpan(`TableClient-updateEntity-${mode}`, options);
        try {
            const partitionKey = escapeQuotes(entity.partitionKey);
            const rowKey = escapeQuotes(entity.rowKey);
            const _a = updatedOptions || {}, { etag = "*" } = _a, updateEntityOptions = tslib.__rest(_a, ["etag"]);
            if (mode === "Merge") {
                return await this.table.mergeEntity(this.tableName, partitionKey, rowKey, Object.assign({ tableEntityProperties: serialize(entity), ifMatch: etag }, updateEntityOptions));
            }
            if (mode === "Replace") {
                return await this.table.updateEntity(this.tableName, partitionKey, rowKey, Object.assign({ tableEntityProperties: serialize(entity), ifMatch: etag }, updateEntityOptions));
            }
            throw new Error(`Unexpected value for update mode: ${mode}`);
        }
        catch (e) {
            span.setStatus({ code: coreTracing.SpanStatusCode.ERROR, message: e.message });
            throw e;
        }
        finally {
            span.end();
        }
    }
    /**
     * Upsert an entity in the table.
     * @param entity - The properties for the table entity.
     * @param mode - The different modes for updating the entity:
     *               - Merge: Updates an entity by updating the entity's properties without replacing the existing entity.
     *               - Replace: Updates an existing entity by replacing the entire entity.
     * @param options - The options parameters.
     *
     * ### Example upserting an entity
     * ```js
     * const { AzureNamedKeyCredential, TableClient } = require("@azure/data-tables")
     * const account = "<storage account name>";
     * const accountKey = "<account key>"
     * const tableName = "<table name>";
     * const sharedKeyCredential = new AzureNamedKeyCredential(account, accountKey);
     *
     * const client = new TableClient(
     *   `https://${account}.table.core.windows.net`,
     *   `${tableName}`,
     *   sharedKeyCredential
     * );
     *
     * const entity = {partitionKey: "p1", rowKey: "r1", bar: "updatedBar"};
     *
     * // Upsert uses update mode "Merge" as default.
     * // This behaves similarly to update but creates the entity
     * // if it doesn't exist in the service
     * await client.upsertEntity(entity)
     *
     * // We can also set the update mode to Replace.
     * // This behaves similarly to update but creates the entity
     * // if it doesn't exist in the service
     * await client.upsertEntity(entity, "Replace")
     * ```
     */
    async upsertEntity(entity, mode = "Merge", 
    // eslint-disable-next-line @azure/azure-sdk/ts-naming-options
    options = {}) {
        const { span, updatedOptions } = createSpan(`TableClient-upsertEntity-${mode}`, options);
        try {
            const partitionKey = escapeQuotes(entity.partitionKey);
            const rowKey = escapeQuotes(entity.rowKey);
            if (mode === "Merge") {
                return await this.table.mergeEntity(this.tableName, partitionKey, rowKey, Object.assign({ tableEntityProperties: serialize(entity) }, updatedOptions));
            }
            if (mode === "Replace") {
                return await this.table.updateEntity(this.tableName, partitionKey, rowKey, Object.assign({ tableEntityProperties: serialize(entity) }, updatedOptions));
            }
            throw new Error(`Unexpected value for update mode: ${mode}`);
        }
        catch (e) {
            span.setStatus({ code: coreTracing.SpanStatusCode.ERROR, message: e.message });
            throw e;
        }
        finally {
            span.end();
        }
    }
    /**
     * Retrieves details about any stored access policies specified on the table that may be used with
     * Shared Access Signatures.
     * @param options - The options parameters.
     */
    async getAccessPolicy(options = {}) {
        const { span, updatedOptions } = createSpan("TableClient-getAccessPolicy", options);
        try {
            const signedIdentifiers = await this.table.getAccessPolicy(this.tableName, updatedOptions);
            return deserializeSignedIdentifier(signedIdentifiers);
        }
        catch (e) {
            span.setStatus({ code: coreTracing.SpanStatusCode.ERROR, message: e.message });
            throw e;
        }
        finally {
            span.end();
        }
    }
    /**
     * Sets stored access policies for the table that may be used with Shared Access Signatures.
     * @param tableAcl - The Access Control List for the table.
     * @param options - The options parameters.
     */
    async setAccessPolicy(tableAcl, options = {}) {
        const { span, updatedOptions } = createSpan("TableClient-setAccessPolicy", options);
        try {
            const serlializedAcl = serializeSignedIdentifiers(tableAcl);
            return await this.table.setAccessPolicy(this.tableName, Object.assign(Object.assign({}, updatedOptions), { tableAcl: serlializedAcl }));
        }
        catch (e) {
            span.setStatus({ code: coreTracing.SpanStatusCode.ERROR, message: e.message });
            throw e;
        }
        finally {
            span.end();
        }
    }
    /**
     * Submits a Transaction which is composed of a set of actions. You can provide the actions as a list
     * or you can use {@link TableTransaction} to help building the transaction.
     *
     * Example usage:
     * ```typescript
     * const { TableClient } = require("@azure/data-tables");
     * const connectionString = "<connection-string>"
     * const tableName = "<tableName>"
     * const client = TableClient.fromConnectionString(connectionString, tableName);
     * const actions = [
     *    ["create", {partitionKey: "p1", rowKey: "1", data: "test1"}],
     *    ["delete", {partitionKey: "p1", rowKey: "2"}],
     *    ["update", {partitionKey: "p1", rowKey: "3", data: "newTest"}, "Merge"]
     * ]
     * const result = await client.submitTransaction(actions);
     * ```
     *
     * Example usage with TableTransaction:
     * ```js
     * const { TableClient } = require("@azure/data-tables");
     * const connectionString = "<connection-string>"
     * const tableName = "<tableName>"
     * const client = TableClient.fromConnectionString(connectionString, tableName);
     * const transaction = new TableTransaction();
     * // Call the available action in the TableTransaction object
     * transaction.create({partitionKey: "p1", rowKey: "1", data: "test1"});
     * transaction.delete("p1", "2");
     * transaction.update({partitionKey: "p1", rowKey: "3", data: "newTest"}, "Merge")
     * // submitTransaction with the actions list on the transaction.
     * const result = await client.submitTransaction(transaction.actions);
     * ```
     *
     * @param actions - tuple that contains the action to perform, and the entity to perform the action with
     */
    async submitTransaction(actions) {
        const partitionKey = actions[0][1].partitionKey;
        const transactionId = Uuid.generateUuid();
        const changesetId = Uuid.generateUuid();
        if (!this.transactionClient) {
            // Add pipeline
            this.transactionClient = new InternalTableTransaction(this.url, partitionKey, transactionId, changesetId, this.clientOptions, new TableClient(this.url, this.tableName), this.credential, this.allowInsecureConnection);
        }
        else {
            this.transactionClient.reset(transactionId, changesetId, partitionKey);
        }
        for (const item of actions) {
            const [action, entity, updateMode = "Merge"] = item;
            switch (action) {
                case "create":
                    this.transactionClient.createEntity(entity);
                    break;
                case "delete":
                    this.transactionClient.deleteEntity(entity.partitionKey, entity.rowKey);
                    break;
                case "update":
                    this.transactionClient.updateEntity(entity, updateMode);
                    break;
                case "upsert":
                    this.transactionClient.upsertEntity(entity, updateMode);
            }
        }
        return this.transactionClient.submitTransaction();
    }
    /**
     *
     * Creates an instance of TableClient from connection string.
     *
     * @param connectionString - Account connection string or a SAS connection string of an Azure storage account.
     *                           [ Note - Account connection string can only be used in NODE.JS runtime. ]
     *                           Account connection string example -
     *                           `DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=accountKey;EndpointSuffix=core.windows.net`
     *                           SAS connection string example -
     *                           `BlobEndpoint=https://myaccount.table.core.windows.net/;QueueEndpoint=https://myaccount.queue.core.windows.net/;FileEndpoint=https://myaccount.file.core.windows.net/;TableEndpoint=https://myaccount.table.core.windows.net/;SharedAccessSignature=sasString`
     * @param options - Options to configure the HTTP pipeline.
     * @returns A new TableClient from the given connection string.
     */
    static fromConnectionString(connectionString, tableName, 
    // eslint-disable-next-line @azure/azure-sdk/ts-naming-options
    options) {
        const { url, options: clientOptions, credential, } = getClientParamsFromConnectionString(connectionString, options);
        if (credential) {
            return new TableClient(url, tableName, credential, clientOptions);
        }
        else {
            return new TableClient(url, tableName, clientOptions);
        }
    }
}

Object.defineProperty(exports, 'AzureNamedKeyCredential', {
    enumerable: true,
    get: function () {
        return coreAuth.AzureNamedKeyCredential;
    }
});
Object.defineProperty(exports, 'AzureSASCredential', {
    enumerable: true,
    get: function () {
        return coreAuth.AzureSASCredential;
    }
});
Object.defineProperty(exports, 'RestError', {
    enumerable: true,
    get: function () {
        return coreRestPipeline.RestError;
    }
});
exports.TableClient = TableClient;
exports.TableServiceClient = TableServiceClient;
exports.TableTransaction = TableTransaction;
exports.generateAccountSas = generateAccountSas;
exports.generateTableSas = generateTableSas;
exports.odata = odata;
//# sourceMappingURL=index.js.map