UNPKG

azurite

Version:

An open source Azure Storage API compatible server

151 lines 5.96 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getMD5FromStream = exports.getMD5FromString = exports.getURLQueries = exports.truncatedISO8061Date = exports.computeHMACSHA256 = exports.newEtag = exports.convertRawHeadersToMetadata = exports.convertDateTimeStringMsTo7Digital = exports.minDate = exports.rimrafAsync = exports.lfsa = void 0; const tslib_1 = require("tslib"); const crypto_1 = require("crypto"); const rimraf = require("rimraf"); const url_1 = require("url"); const util_1 = require("util"); const StorageErrorFactory_1 = tslib_1.__importDefault(require("../../blob/errors/StorageErrorFactory")); const constants_1 = require("./constants"); // LokiFsStructuredAdapter // tslint:disable-next-line:no-var-requires exports.lfsa = require("lokijs/src/loki-fs-structured-adapter.js"); exports.rimrafAsync = (0, util_1.promisify)(rimraf); function minDate(date1, date2) { return date1 > date2 ? date2 : date1; } exports.minDate = minDate; // Blob Snapshot is has 7 digital for Milliseconds, but Datetime has Milliseconds with 3 digital. So need convert. function convertDateTimeStringMsTo7Digital(dateTimeString) { return dateTimeString.replace("Z", "0000Z"); } exports.convertDateTimeStringMsTo7Digital = convertDateTimeStringMsTo7Digital; function convertRawHeadersToMetadata(rawHeaders = [], contextId = "") { const metadataPrefix = "x-ms-meta-"; const res = {}; let isEmpty = true; for (let i = 0; i < rawHeaders.length; i = i + 2) { const header = rawHeaders[i]; if (header.toLowerCase().startsWith(metadataPrefix) && header.length > metadataPrefix.length) { const key = header.substr(metadataPrefix.length); if (!key.match(constants_1.VALID_CSHARP_IDENTIFIER_REGEX)) { throw StorageErrorFactory_1.default.getInvalidMetadata(contextId); } let value = rawHeaders[i + 1] || ""; if (res[key] !== undefined) { value = `${res[key]},${value}`; } res[key] = value; isEmpty = false; continue; } } return isEmpty ? undefined : res; } exports.convertRawHeadersToMetadata = convertRawHeadersToMetadata; function newEtag() { // Etag should match ^"0x[A-F0-9]{15,}"$ // Date().getTime().toString(16) only has 11 digital // so multiply a number between 70000-100000, can get a 16 based 15+ digital number return ('"0x' + (new Date().getTime() * Math.round(Math.random() * 30000 + 70000)) .toString(16) .toUpperCase() + '"'); } exports.newEtag = newEtag; /** * Generates a hash signature for an HTTP request or for a SAS. * * @param {string} stringToSign * @param {key} key * @returns {string} */ function computeHMACSHA256(stringToSign, key) { return (0, crypto_1.createHmac)("sha256", key) .update(stringToSign, "utf8") .digest("base64"); } exports.computeHMACSHA256 = computeHMACSHA256; /** * Rounds a date off to seconds. * * @export * @param {Date} date * @param {boolean} [withMilliseconds=true] If true, YYYY-MM-DDThh:mm:ss.fffffffZ will be returned; * If false, YYYY-MM-DDThh:mm:ssZ will be returned. * @returns {string} Date string in ISO8061 format, with or without 7 milliseconds component */ function truncatedISO8061Date(date, withMilliseconds = true, hrtimePrecision = false) { // Date.toISOString() will return like "2018-10-29T06:34:36.139Z" const dateString = date.toISOString(); // some clients are very fast, and require more than ms precision available in JS // This is an approximation based on the hrtime function in nodejs. // The nanosecond value is appended to the millisecond value from the datetime // object which gives us a good enough difference in the case of faster high // volume transactions if (hrtimePrecision) { return (dateString.substring(0, dateString.length - 1) + process.hrtime()[1].toString().padStart(4, "0").slice(0, 4) + "Z"); } return withMilliseconds ? dateString.substring(0, dateString.length - 1) + "0000" + "Z" : dateString.substring(0, dateString.length - 5) + "Z"; } exports.truncatedISO8061Date = truncatedISO8061Date; /** * Get URL query key value pairs from an URL string. * * @export * @param {string} url * @returns {{[key: string]: string}} */ function getURLQueries(url) { let queryString = (0, url_1.parse)(url).query; if (!queryString) { return {}; } queryString = queryString.trim(); queryString = queryString.startsWith("?") ? queryString.substr(1) : queryString; let querySubStrings = queryString.split("&"); querySubStrings = querySubStrings.filter((value) => { const indexOfEqual = value.indexOf("="); const lastIndexOfEqual = value.lastIndexOf("="); return indexOfEqual > 0 && indexOfEqual === lastIndexOfEqual; }); const queries = {}; for (const querySubString of querySubStrings) { const splitResults = querySubString.split("="); const key = splitResults[0]; const value = splitResults[1]; queries[key] = value; } return queries; } exports.getURLQueries = getURLQueries; async function getMD5FromString(text) { return (0, crypto_1.createHash)("md5").update(text).digest(); } exports.getMD5FromString = getMD5FromString; async function getMD5FromStream(stream) { const hash = (0, crypto_1.createHash)("md5"); return new Promise((resolve, reject) => { stream .on("data", (data) => { hash.update(data); }) .on("end", () => { resolve(hash.digest()); }) .on("error", (err) => { reject(err); }); }); } exports.getMD5FromStream = getMD5FromStream; //# sourceMappingURL=utils.js.map