[Tables] Fix docs and case-insensitive ConnectionString (#13954)

* Fix docs and case-insensitive CS

* Hide top query option

* Keep default empty object

* address feedback

* Fix connection string

* test cs with = in value
This commit is contained in:
Jose Manuel Heredia Hidalgo 2021-03-03 19:12:51 -08:00 коммит произвёл GitHub
Родитель 0941b23115
Коммит 96fe07ef95
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 54 добавлений и 14 удалений

Просмотреть файл

@ -272,7 +272,7 @@ export class TableClient {
return this;
},
byPage: (settings) => {
const pageOptions = {
const pageOptions: InternalListTableEntitiesOptions = {
...options,
queryOptions: { ...options.queryOptions, top: settings?.maxPageSize }
};
@ -570,10 +570,11 @@ export class TableClient {
}
}
type InternalQueryOptions = TableEntityQueryOptions & { top?: number };
interface InternalListTableEntitiesOptions extends ListTableEntitiesOptions {
queryOptions?: InternalQueryOptions;
}
function isInternalClientOptions(options: any): options is InternalBatchClientOptions {
return Boolean(options.innerBatchRequest);
}
type InternalListTableEntitiesOptions = ListTableEntitiesOptions & {
queryOptions?: TableEntityQueryOptions & { top?: number };
};

Просмотреть файл

@ -54,11 +54,7 @@ export function extractConnectionStringParts(connectionString: string): Connecti
// (The methods that use `extractConnectionStringParts` expect the url to not have `/` at the end)
tableEndpoint = tableEndpoint.endsWith("/") ? tableEndpoint.slice(0, -1) : tableEndpoint;
const isAccountConnectionString =
connectionString.search("DefaultEndpointsProtocol=") !== -1 &&
connectionString.search("AccountKey=") !== -1;
if (isAccountConnectionString) {
if (isAccountConnectionString(connectionString)) {
return getAccountConnectionString(
getValueInConnString(connectionString, "AccountName"),
getValueInConnString(connectionString, "AccountKey"),
@ -71,6 +67,17 @@ export function extractConnectionStringParts(connectionString: string): Connecti
}
}
/**
* Checks whether a connection string is an Account Connection string or not
*/
function isAccountConnectionString(connectionString: string) {
const lowercaseConnectionString = connectionString.toLowerCase();
return (
lowercaseConnectionString.search("defaultendpointsprotocol=") !== -1 &&
lowercaseConnectionString.search("accountkey=") !== -1
);
}
function getSASConnectionString(connectionString: string, tableEndpoint: string): ConnectionString {
const accountName = getAccountNameFromUrl(tableEndpoint);
const accountSas = getValueInConnString(connectionString, "SharedAccessSignature");
@ -95,15 +102,32 @@ function getValueInConnString(
| "EndpointSuffix"
| "SharedAccessSignature"
): string {
const searchKey = argument.toLowerCase();
const elements = connectionString.split(";");
for (const element of elements) {
if (element.trim().startsWith(argument)) {
return element.trim().match(argument + "=(.*)")![1];
const trimmedElement = element.trim();
const [elementKey, value] = getValuePair(trimmedElement);
const key = elementKey.toLowerCase();
if (key === searchKey) {
return value;
}
}
return "";
}
function getValuePair(kvp: string): string[] {
// 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

Просмотреть файл

@ -29,6 +29,18 @@ describe("Utility Helpers", () => {
});
});
it("should handle case-insensitive string without TableEndpoint", () => {
const validConnectionString =
"deFaultEndpointsPROTOcol=https;accoUNTNAme=testaccount;ACCOUNTkey=REDACTED;endPOintSuffiX=core.windows.net";
const result = extractConnectionStringParts(validConnectionString);
assert.deepEqual(result, {
accountName: "testaccount",
accountKey: Buffer.from([68, 64, 192, 9, 49, 3]),
kind: "AccountConnString",
url: "https://testaccount.table.core.windows.net"
});
});
it("should handle connection string with TableEndpoint", () => {
const validConnectionString =
"DefaultEndpointsProtocol=https;AccountName=testaccount;AccountKey=REDACTED;EndpointSuffix=core.windows.net;TableEndpoint=https://myAccount.table.core.windows.net/";
@ -66,9 +78,12 @@ describe("Utility Helpers", () => {
it("should handle format 'protocol://accountName.table.endpointSuffix'", () => {
const validSAS =
"BlobEndpoint=https://teststorageaccount.blob.core.windows.net/;QueueEndpoint=https://teststorageaccount.queue.core.windows.net/;FileEndpoint=https://teststorageaccount.file.core.windows.net/;TableEndpoint=https://teststorageaccount.table.core.windows.net/;SharedAccessSignature=REDACTED";
"BlobEndpoint=https://teststorageaccount.blob.core.windows.net/;QueueEndpoint=https://teststorageaccount.queue.core.windows.net/;FileEndpoint=https://teststorageaccount.file.core.windows.net/;TableEndpoint=https://teststorageaccount.table.core.windows.net/;SharedAccessSignature=sv=2020-02-10&ss=bfqt";
const connectionStringParts = extractConnectionStringParts(validSAS);
assert.deepEqual(connectionStringParts, expectedConenctionStringParts);
assert.deepEqual(connectionStringParts, {
...expectedConenctionStringParts,
accountSas: "sv=2020-02-10&ss=bfqt"
});
});
it("should handle IPv4/6 format ", () => {