'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