UNPKG

botbuilder-azure

Version:

Azure extensions for Microsoft BotBuilder.

72 lines 3.78 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CosmosDbKeyEscape = void 0; /** * @module botbuilder-azure */ /** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ const crypto = require("crypto"); // eslint-disable-next-line @typescript-eslint/no-namespace var CosmosDbKeyEscape; (function (CosmosDbKeyEscape) { // Older libraries had a max key length of 255. // The limit is now 1023. In this library, 255 remains the default for backwards compat. // To override this behavior, and use the longer limit, set cosmosDbPartitionedStorageOptions.compatibilityMode to false. // https://docs.microsoft.com/en-us/azure/cosmos-db/concepts-limits#per-item-limits const maxKeyLength = 255; const illegalKeys = ['\\', '?', '/', '#', '\t', '\n', '\r', '*']; const illegalKeyCharacterReplacementMap = illegalKeys.reduce((map, c) => { map.set(c, `*${c.charCodeAt(0).toString(16)}`); return map; }, new Map()); /** * Converts the key into a DocumentID that can be used safely with CosmosDB. * The following characters are restricted and cannot be used in the Id property: '/', '\', '?', '#' * More information at https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.documents.resource.id?view=azure-dotnet#remarks * * @param key The provided key to be escaped. * @param keySuffix The string to add a the end of all RowKeys. * @param compatibilityMode True if keys should be truncated in order to support previous CosmosDb * max key length of 255. This behavior can be overridden by setting cosmosDbPartitionedStorageOptions.compatibilityMode to false. * @returns An escaped key that can be used safely with CosmosDB. */ function escapeKey(key, keySuffix, compatibilityMode) { if (!key) { throw new Error("The 'key' parameter is required."); } const keySplitted = key.split(''); const firstIllegalCharIndex = keySplitted.findIndex((c) => illegalKeys.some((i) => i === c)); // If there are no illegal characters return immediately and avoid any further processing/allocations if (firstIllegalCharIndex === -1) { return truncateKey(`${key}${keySuffix || ''}`, compatibilityMode); } const sanitizedKey = keySplitted.reduce((result, c) => result + (illegalKeyCharacterReplacementMap.has(c) ? illegalKeyCharacterReplacementMap.get(c) : c), ''); return truncateKey(`${sanitizedKey}${keySuffix || ''}`, compatibilityMode); /** * Truncates the key if it exceeds the max key length to have backwards compatibility with older libraries. * * @param key The key to be truncated. * @param truncateKeysForCompatibility True if keys should be truncated in order to support previous CosmosDb * max key length of 255. False to override this behavior using the longer limit. * @returns The resulting key. */ function truncateKey(key, truncateKeysForCompatibility) { if (truncateKeysForCompatibility === false) { return key; } if (key.length > maxKeyLength) { const hash = crypto.createHash('sha256'); hash.update(key); // combine truncated key with hash of self for extra uniqueness const hex = hash.digest('hex'); key = key.substr(0, maxKeyLength - hex.length) + hex; } return key; } } CosmosDbKeyEscape.escapeKey = escapeKey; })(CosmosDbKeyEscape = exports.CosmosDbKeyEscape || (exports.CosmosDbKeyEscape = {})); //# sourceMappingURL=cosmosDbKeyEscape.js.map