UNPKG

@ts-common/azure-js-dev-tools

Version:

Developer dependencies for TypeScript related projects

1,120 lines (1,119 loc) 64.9 kB
"use strict"; /** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for * license information. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.AzureBlobStorage = exports.getAzureContainerAccessPermissions = exports.validateBlobName = exports.InMemoryBlobStorage = exports.constructBlobStorageCredentials = exports.getStorageAccountName = exports.constructBlobStorageURL = exports.BlobStorage = exports.BlobStorageAppendBlob = exports.BlobStorageBlockBlob = exports.BlobStorageBlob = exports.BlobStorageContainer = exports.BlobStoragePrefix = exports.BlobPath = exports.getFileLengthInBytes = void 0; var tslib_1 = require("tslib"); var storage_blob_1 = require("@azure/storage-blob"); var fs = tslib_1.__importStar(require("fs")); var arrays_1 = require("./arrays"); var common_1 = require("./common"); var url_1 = require("./url"); var defaultEncoding = "utf8"; /** * Get the number of bytes in the provided file. * @param filePath The path to the file. */ function getFileLengthInBytes(filePath) { return new Promise(function (resolve, reject) { fs.lstat(filePath, function (error, stats) { if (error) { reject(error); } else { resolve(stats.size); } }); }); } exports.getFileLengthInBytes = getFileLengthInBytes; /** * A path to a blob. */ var BlobPath = /** @class */ (function () { function BlobPath(containerName, blobName) { this.containerName = containerName; this.blobName = blobName; } /** * Concatenate the provided blobName onto this BlobPath. * @param blobName The blobName to concatenate to this BlobPath. */ BlobPath.prototype.concatenate = function (blobName) { return !blobName ? this : new BlobPath(this.containerName, this.blobName + blobName); }; /** * Get the string representation of this BlobPath object. */ BlobPath.prototype.toString = function () { return this.containerName + "/" + this.blobName; }; /** * Parse a BlobPath object from the provided blobPath. The blobPath string must contain a forward * slash. * @param blobPath The blob path to parse. */ BlobPath.parse = function (blobPath) { var result; if (blobPath instanceof BlobPath) { result = blobPath; } else if (!blobPath) { result = new BlobPath("", ""); } else { if (blobPath.startsWith("/")) { blobPath = blobPath.substring(1); } var firstSlashIndex = blobPath.indexOf("/"); if (firstSlashIndex === -1) { result = new BlobPath(blobPath, ""); } else { result = new BlobPath(blobPath.substring(0, firstSlashIndex), blobPath.substring(firstSlashIndex + 1)); } } return result; }; return BlobPath; }()); exports.BlobPath = BlobPath; /** * A prefix to other BlobStorageBlobs. */ var BlobStoragePrefix = /** @class */ (function () { /** * Create a new prefix within the provided BlobStorage system. * @param storage The BlobStorage system that this prefix targets. * @param path The path of this prefix. */ function BlobStoragePrefix(storage, path) { this.storage = storage; this.path = typeof path === "string" ? BlobPath.parse(path) : path; } /** * Get the URL for this prefix. */ BlobStoragePrefix.prototype.getURL = function (options) { if (options === void 0) { options = {}; } return this.storage.getBlobURL(this.path, options); }; /** * Get the container that this prefix belongs to. */ BlobStoragePrefix.prototype.getContainer = function () { return this.storage.getContainer(this.path.containerName); }; /** * Get a blob with the provided name relative to this prefix. * @param blobName The name to append to this prefix. */ BlobStoragePrefix.prototype.getBlob = function (blobName) { return this.storage.getBlob(this.path.concatenate(blobName)); }; /** * Get a block blob with the provided name relative to this prefix. * @param blockBlobName The name to append to this prefix. */ BlobStoragePrefix.prototype.getBlockBlob = function (blockBlobName) { return this.storage.getBlockBlob(this.path.concatenate(blockBlobName)); }; /** * Get an append blob with the provided name relative to this prefix. * @param appendBlobName The name to append to this prefix. */ BlobStoragePrefix.prototype.getAppendBlob = function (appendBlobName) { return this.storage.getAppendBlob(this.path.concatenate(appendBlobName)); }; /** * Get a prefix that can be used to perform blob operations relative to the provided path. * @param blobName The path to the prefix. */ BlobStoragePrefix.prototype.getPrefix = function (blobName) { return !blobName ? this : this.storage.getPrefix(this.path.concatenate(blobName)); }; /** * Create a block blob relative to this container with the provided name. * @param blockBlobName The name of the blob relative to this container. */ BlobStoragePrefix.prototype.createBlockBlob = function (blockBlobName, options) { if (options === void 0) { options = {}; } return this.storage.createBlockBlob(this.path.concatenate(blockBlobName), options); }; /** * Create an append blob relative to this container with the provided name. * @param appendBlobName The name of the append blob relative to this container. */ BlobStoragePrefix.prototype.createAppendBlob = function (appendBlobName, options) { if (options === void 0) { options = {}; } return this.storage.createAppendBlob(this.path.concatenate(appendBlobName), options); }; /** * Get whether or not a blob exists with the provided name relative to this prefix. * @param blobName The name of the blob relative to this prefix. */ BlobStoragePrefix.prototype.blobExists = function (blobName) { return this.storage.blobExists(this.path.concatenate(blobName)); }; /** * Get the properties for the blob at the provided path. * @param blobPath The path to the blob. */ BlobStoragePrefix.prototype.getBlobProperties = function (blobName) { return this.storage.getBlobProperties(this.path.concatenate(blobName)); }; /** * Get the content type that has been assigned to the provided blob. * @param blobName The name of to the blob. */ BlobStoragePrefix.prototype.getBlobContentType = function (blobName) { return this.storage.getBlobContentType(this.path.concatenate(blobName)); }; /** * Assign the provided content type to the provided blob. * @param blobName The name of the blob. * @param contentType The content type to assign to the provided blob. */ BlobStoragePrefix.prototype.setBlobContentType = function (blobName, contentType) { return this.storage.setBlobContentType(this.path.concatenate(blobName), contentType); }; /** * Get the contents of the blob with the provided name relative to this prefix. * @param blobName The name of the blob relative to this prefix. */ BlobStoragePrefix.prototype.getBlobContentsAsString = function (blobName) { return this.storage.getBlobContentsAsString(this.path.concatenate(blobName)); }; /** * Set the contents of the blob with the provided name relative to this prefix. * @param blockBlobName The name of the blob relative to this prefix. * @param blobContents The contents to set. */ BlobStoragePrefix.prototype.setBlockBlobContentsFromString = function (blockBlobName, blobContents, options) { return this.storage.setBlockBlobContentsFromString(this.path.concatenate(blockBlobName), blobContents, options); }; /** * Add the provided blob contents to append to the append blob with the provided name relative to * this container. * @param appendBlobName The name of the append blob relative to this container. * @param blobContentsToAppend The contents to add the append blob. */ BlobStoragePrefix.prototype.addToAppendBlobContentsFromString = function (appendBlobName, blobContentsToAppend, options) { return this.storage.addToAppendBlobContentsFromString(this.path.concatenate(appendBlobName), blobContentsToAppend, options); }; /** * Delete the blob with the provided name relative to this prefix. This method returns whether or * not the blob was deleted. Returning false means that the blob didn't exist before this method * was called. * @param blobPath The path to the blob to delete relative to this prefix. */ BlobStoragePrefix.prototype.deleteBlob = function (blobName) { return this.storage.deleteBlob(this.path.concatenate(blobName)); }; return BlobStoragePrefix; }()); exports.BlobStoragePrefix = BlobStoragePrefix; var BlobStorageContainer = /** @class */ (function (_super) { tslib_1.__extends(BlobStorageContainer, _super); /** * Create a new reference to a container within the provided BlobStorage system. * @param storage The BlobStorage system that this container belongs to. * @param name The name of the container. */ function BlobStorageContainer(storage, name) { var _this = _super.call(this, storage, new BlobPath(name, "")) || this; _this.name = name; return _this; } /** * Get the URL for this prefix. */ BlobStorageContainer.prototype.getURL = function (options) { if (options === void 0) { options = {}; } return this.storage.getContainerURL(this.name, options); }; /** * Get the container that this prefix belongs to. */ BlobStorageContainer.prototype.getContainer = function () { return this; }; /** * Create this container. This method will return false when the container already exists. */ BlobStorageContainer.prototype.create = function (options) { if (options === void 0) { options = {}; } return this.storage.createContainer(this.name, options); }; /** * Get whether or not this container exists. */ BlobStorageContainer.prototype.exists = function () { return this.storage.containerExists(this.name); }; /** * Get the access policy for this container. */ BlobStorageContainer.prototype.getAccessPolicy = function () { return this.storage.getContainerAccessPolicy(this.name); }; /** * Set the access policy for this container. * @param policy The new access policy for this container. */ BlobStorageContainer.prototype.setAccessPolicy = function (policy) { return this.storage.setContainerAccessPolicy(this.name, policy); }; /** * Delete this container. This method returns whether or not the container was deleted. Returning * false means that the container didn't exist before this method was called. */ BlobStorageContainer.prototype.delete = function () { return this.storage.deleteContainer(this.name); }; return BlobStorageContainer; }(BlobStoragePrefix)); exports.BlobStorageContainer = BlobStorageContainer; /** * An class that describes the common functions between the different types of blobs in a * BlobStorage system. */ var BlobStorageBlob = /** @class */ (function () { /** * Create a new reference to a block blob within the provided BlobStorage system. * @param storage The BlobStorage system that this blob belongs to. * @param path The path to this block blob. */ function BlobStorageBlob(storage, path) { this.storage = storage; this.path = typeof path === "string" ? BlobPath.parse(path) : path; } /** * Get the URL for this blob. */ BlobStorageBlob.prototype.getURL = function (options) { if (options === void 0) { options = {}; } return this.storage.getBlobURL(this.path, options); }; /** * Get the container that contains this blob. */ BlobStorageBlob.prototype.getContainer = function () { return this.storage.getContainer(this.path.containerName); }; /** * Get whether or not this blob exists. */ BlobStorageBlob.prototype.exists = function () { return this.storage.blobExists(this.path); }; /** * Get the properties for this blob. */ BlobStorageBlob.prototype.getProperties = function () { return this.storage.getBlobProperties(this.path); }; /** * Delete this blob. This method returns whether or not the blob was deleted. Returning false * means that the blob didn't exist before this method was called. */ BlobStorageBlob.prototype.delete = function () { return this.storage.deleteBlob(this.path); }; /** * Get the contents of this blob as a UTF-8 decoded string. */ BlobStorageBlob.prototype.getContentsAsString = function () { return this.storage.getBlobContentsAsString(this.path); }; /** * Get the content type that has been assigned to this blob. */ BlobStorageBlob.prototype.getContentType = function () { return this.storage.getBlobContentType(this.path); }; /** * Assign the provided content type to this blob. * @param contentType The content type to assign to this blob. */ BlobStorageBlob.prototype.setContentType = function (contentType) { return this.storage.setBlobContentType(this.path, contentType); }; return BlobStorageBlob; }()); exports.BlobStorageBlob = BlobStorageBlob; /** * A class that can be used to interact with a block blob in a BlobStorage system. */ var BlobStorageBlockBlob = /** @class */ (function (_super) { tslib_1.__extends(BlobStorageBlockBlob, _super); function BlobStorageBlockBlob() { return _super !== null && _super.apply(this, arguments) || this; } /** * Create this block blob. This method will return false when the block blob already exists. */ BlobStorageBlockBlob.prototype.create = function (options) { if (options === void 0) { options = {}; } return this.storage.createBlockBlob(this.path, options); }; /** * Set the contents of this block blob to be the provided UTF-8 encoded string. * @param blockBlobContents The contents to set. This will be UTF-8 encoded. */ BlobStorageBlockBlob.prototype.setContentsFromString = function (blockBlobContents, options) { if (options === void 0) { options = {}; } return this.storage.setBlockBlobContentsFromString(this.path, blockBlobContents, options); }; /** * Upload the file at the provided path to this block blob. * @param filePath The path to the file that contains the block blob's contents. * @param options Options that will be applied to the block blob. */ BlobStorageBlockBlob.prototype.setContentsFromFile = function (filePath, options) { if (options === void 0) { options = {}; } return this.storage.setBlockBlobContentsFromFile(this.path, filePath, options); }; return BlobStorageBlockBlob; }(BlobStorageBlob)); exports.BlobStorageBlockBlob = BlobStorageBlockBlob; /** * A class that can be used to interact with an append blob in a BlobStorage system. */ var BlobStorageAppendBlob = /** @class */ (function (_super) { tslib_1.__extends(BlobStorageAppendBlob, _super); function BlobStorageAppendBlob() { return _super !== null && _super.apply(this, arguments) || this; } /** * Create this append blob. This method will return false when the append blob already exists. */ BlobStorageAppendBlob.prototype.create = function (options) { if (options === void 0) { options = {}; } return this.storage.createAppendBlob(this.path, options); }; /** * Append the provided UTF-8 encoded contents to this append blob. * @param contentsToAppend The contents to append to this append blob. This will be UTF-8 encoded. */ BlobStorageAppendBlob.prototype.addToContents = function (contentsToAppend) { return this.storage.addToAppendBlobContentsFromString(this.path, contentsToAppend); }; return BlobStorageAppendBlob; }(BlobStorageBlob)); exports.BlobStorageAppendBlob = BlobStorageAppendBlob; /** * A class for interacting with a blob storage system. */ var BlobStorage = /** @class */ (function () { function BlobStorage() { } /** * Get a reference to a blob at the provided path. This will not modify the BlobStorage system at * all. This simply gets a reference to the blob. * @param blobPath The path to the blob. */ BlobStorage.prototype.getBlob = function (blobPath) { return new BlobStorageBlob(this, blobPath); }; /** * Get a reference to a block blob at the provided path. This will not modify the BlobStorage * system at all. This simply gets a reference to the block blob. * @param blockBlobPath The path to the block blob. */ BlobStorage.prototype.getBlockBlob = function (blockBlobPath) { return new BlobStorageBlockBlob(this, blockBlobPath); }; /** * Get a reference to an append blob at the provided path. This will not modify the BlobStorage * system at all. This simply gets a reference to the append blob. * @param appendBlobPath The path to the blob. */ BlobStorage.prototype.getAppendBlob = function (appendBlobPath) { return new BlobStorageAppendBlob(this, appendBlobPath); }; /** * Get a prefix that can be used to perform blob operations relative to the provided prefix. * @param prefix The path to the prefix. */ BlobStorage.prototype.getPrefix = function (prefix) { return new BlobStoragePrefix(this, prefix); }; /** * Get a reference to a container with the provided name. This will not modify the BlobStorage * system at all. This simply gets a reference to the container. * @param containerName The name of the container. */ BlobStorage.prototype.getContainer = function (containerName) { return new BlobStorageContainer(this, containerName); }; return BlobStorage; }()); exports.BlobStorage = BlobStorage; function encodeBlobName(blobName) { return !blobName ? blobName : encodeURIComponent(blobName); } function decodeBlobName(blobName) { return !blobName ? blobName : decodeURIComponent(blobName); } function processBlobUrl(url, options, credentials) { if (options.sasToken !== true || options.encodeBlobName) { url = processBlobUrlBuilder(url_1.URLBuilder.parse(url), options, credentials); } return url; } function processBlobUrlBuilder(urlBuilder, options, credentials) { if (options.sasToken !== true) { urlBuilder.removeQuery(); if (options.sasToken && typeof options.sasToken !== "boolean") { if (!(credentials instanceof storage_blob_1.SharedKeyCredential)) { throw new Error("Cannot create a new SAS token if the BlobStorage credentials are not a SharedKeyCredential."); } else { var urlPath = urlBuilder.getPath(); if (!urlPath) { throw new Error("Cannot create a new SAS token when the provided URL does not contain a path."); } else { var blobPath = BlobPath.parse(urlPath); var sasSignatureValues = { blobName: blobPath.blobName, containerName: blobPath.containerName, expiryTime: options.sasToken.endTime, startTime: options.sasToken.startTime, permissions: "r", }; var sasQueryParameters = storage_blob_1.generateBlobSASQueryParameters(sasSignatureValues, credentials); if (sasQueryParameters.cacheControl) { urlBuilder.setQueryParameter("rscc", sasQueryParameters.cacheControl); } if (sasQueryParameters.contentDisposition) { urlBuilder.setQueryParameter("rscd", sasQueryParameters.contentDisposition); } if (sasQueryParameters.contentEncoding) { urlBuilder.setQueryParameter("rsce", sasQueryParameters.contentEncoding); } if (sasQueryParameters.contentLanguage) { urlBuilder.setQueryParameter("rscl", sasQueryParameters.contentLanguage); } if (sasQueryParameters.contentType) { urlBuilder.setQueryParameter("rsct", sasQueryParameters.contentType); } if (sasQueryParameters.expiryTime) { urlBuilder.setQueryParameter("se", sasQueryParameters.expiryTime.toISOString()); } if (sasQueryParameters.identifier) { urlBuilder.setQueryParameter("si", sasQueryParameters.identifier); } if (sasQueryParameters.permissions) { urlBuilder.setQueryParameter("sp", sasQueryParameters.permissions); } if (sasQueryParameters.protocol) { urlBuilder.setQueryParameter("spr", sasQueryParameters.protocol); } if (sasQueryParameters.resource) { urlBuilder.setQueryParameter("sr", sasQueryParameters.resource); } if (sasQueryParameters.services) { urlBuilder.setQueryParameter("ss", sasQueryParameters.services); } if (sasQueryParameters.signature) { urlBuilder.setQueryParameter("sig", sasQueryParameters.signature); } if (sasQueryParameters.startTime) { urlBuilder.setQueryParameter("st", sasQueryParameters.startTime.toISOString()); } if (sasQueryParameters.version) { urlBuilder.setQueryParameter("sv", sasQueryParameters.version); } } } } } if (options.encodeBlobName) { var path = urlBuilder.getPath(); if (path) { var blobPath = BlobPath.parse(path); urlBuilder.setPath(blobPath.containerName + "/" + encodeBlobName(blobPath.blobName)); } } return urlBuilder.toString(); } function constructBlobStorageURL(storageAccountNameOrUrl) { var urlBuilder = typeof storageAccountNameOrUrl === "string" ? url_1.URLBuilder.parse(storageAccountNameOrUrl) : storageAccountNameOrUrl; if (!urlBuilder.getScheme()) { urlBuilder.setScheme("https"); } var host = urlBuilder.getHost(); if (!host) { throw new Error("Cannot construct a storage account URL with an empty or undefined storage account name or URL argument."); } var hostDotIndex = host.indexOf("."); if (hostDotIndex === -1) { urlBuilder.setHost(host + ".blob.core.windows.net"); } return urlBuilder.toString(); } exports.constructBlobStorageURL = constructBlobStorageURL; function getStorageAccountName(storageAccountNameOrUrl) { var urlBuilder = url_1.URLBuilder.parse(storageAccountNameOrUrl); var host = urlBuilder.getHost(); if (!host) { throw new Error("Cannot get a storage account's name with an storage account URL argument with an empty or undefined host."); } var hostDotIndex = host.indexOf("."); return host.substring(0, hostDotIndex); } exports.getStorageAccountName = getStorageAccountName; function constructBlobStorageCredentials(storageAccountUrl, credentials) { if (!credentials) { credentials = new storage_blob_1.AnonymousCredential(); } else if (typeof credentials === "string") { var storageAccountName = getStorageAccountName(storageAccountUrl); credentials = new storage_blob_1.SharedKeyCredential(storageAccountName, credentials); } return credentials; } exports.constructBlobStorageCredentials = constructBlobStorageCredentials; function bumpETag(etag) { return (Number.parseInt(etag) + 1).toString(); } /** * A BlobStorage system that is stored in memory. */ var InMemoryBlobStorage = /** @class */ (function (_super) { tslib_1.__extends(InMemoryBlobStorage, _super); function InMemoryBlobStorage(storageAccountNameOrUrl, credentials) { if (storageAccountNameOrUrl === void 0) { storageAccountNameOrUrl = "https://fake.storage.com/"; } var _this = _super.call(this) || this; _this.containers = {}; _this.url = constructBlobStorageURL(storageAccountNameOrUrl); _this.credentials = constructBlobStorageCredentials(_this.url, credentials); return _this; } InMemoryBlobStorage.prototype.getInMemoryContainer = function (containerName) { containerName = typeof containerName === "string" ? containerName : containerName.containerName; var result; if (!containerName || containerName !== containerName.toLowerCase()) { result = Promise.reject(new Error("InvalidResourceName: The specifed resource name contains invalid characters.")); } else { var container = this.containers[containerName]; if (!container) { result = Promise.reject(new Error("ContainerNotFound: The specified container does not exist.")); } else { result = Promise.resolve(container); } } return result; }; InMemoryBlobStorage.prototype.getInMemoryBlob = function (blobPath) { blobPath = BlobPath.parse(blobPath); var blobName = blobPath.blobName; return this.getInMemoryContainer(blobPath.containerName) .then(function (container) { return validateBlobName(blobPath) .then(function () { return blobName in container.blobs ? Promise.resolve(container.blobs[blobName]) : Promise.reject(new Error("BlobNotFound: The specified blob does not exist.")); }); }); }; InMemoryBlobStorage.prototype.getURL = function (options) { if (options === void 0) { options = {}; } return processBlobUrl(this.url, options, this.credentials); }; InMemoryBlobStorage.prototype.getContainerURL = function (containerName, options) { if (options === void 0) { options = {}; } var urlBuilder = url_1.URLBuilder.parse(this.url); urlBuilder.setPath(containerName); return processBlobUrlBuilder(urlBuilder, options, this.credentials); }; InMemoryBlobStorage.prototype.getBlobURL = function (blobPath, options) { if (options === void 0) { options = {}; } blobPath = BlobPath.parse(blobPath); var urlBuilder = url_1.URLBuilder.parse(this.url); urlBuilder.setPath(blobPath.toString()); return processBlobUrlBuilder(urlBuilder, options, this.credentials); }; InMemoryBlobStorage.prototype.createInMemoryBlob = function (blobPath, blobType, options) { if (options === void 0) { options = {}; } return tslib_1.__awaiter(this, void 0, void 0, function () { var blobName, container, blob, created, etag, result; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: blobPath = BlobPath.parse(blobPath); blobName = blobPath.blobName; return [4 /*yield*/, this.getInMemoryContainer(blobPath)]; case 1: container = _a.sent(); if (!blobName) { throw new Error("InvalidUri: The requested URI does not represent any resource on the server."); } blob = container.blobs[blobName]; created = !blob; if (created) { etag = "1"; container.blobs[blobName] = { blobType: blobType, contents: "", contentType: options.contentType || "application/octet-stream", etag: etag, }; } result = { created: created }; if (etag) { result.etag = etag; } return [2 /*return*/, result]; } }); }); }; InMemoryBlobStorage.prototype.createBlockBlob = function (blobPath, options) { if (options === void 0) { options = {}; } return this.createInMemoryBlob(blobPath, "block", options); }; InMemoryBlobStorage.prototype.createAppendBlob = function (appendBlobPath, options) { if (options === void 0) { options = {}; } return this.createInMemoryBlob(appendBlobPath, "append", options); }; InMemoryBlobStorage.prototype.blobExists = function (blobPath) { return tslib_1.__awaiter(this, void 0, void 0, function () { var result, error_1; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: blobPath = BlobPath.parse(blobPath); _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4 /*yield*/, this.getBlobProperties(blobPath)]; case 2: _a.sent(); result = true; return [3 /*break*/, 4]; case 3: error_1 = _a.sent(); if (error_1.message.includes("BlobNotFound")) { result = false; } else { throw error_1; } return [3 /*break*/, 4]; case 4: return [2 /*return*/, result]; } }); }); }; InMemoryBlobStorage.prototype.getBlobProperties = function (blobPath) { return tslib_1.__awaiter(this, void 0, void 0, function () { var result, blob, error_2; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: blobPath = BlobPath.parse(blobPath); _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4 /*yield*/, this.getInMemoryBlob(blobPath)]; case 2: blob = _a.sent(); result = { etag: blob.etag, }; return [3 /*break*/, 4]; case 3: error_2 = _a.sent(); if (error_2.message.includes("ContainerNotFound")) { throw new Error("BlobNotFound: The specified blob does not exist."); } else { throw error_2; } return [3 /*break*/, 4]; case 4: return [2 /*return*/, result]; } }); }); }; InMemoryBlobStorage.prototype.getBlobContentsAsString = function (blobPath) { return tslib_1.__awaiter(this, void 0, void 0, function () { var result, blob, error_3; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); return [4 /*yield*/, this.getInMemoryBlob(blobPath)]; case 1: blob = _a.sent(); result = { contents: blob.contents.toString(), etag: blob.etag, }; return [3 /*break*/, 3]; case 2: error_3 = _a.sent(); if (error_3.message.includes("ContainerNotFound")) { throw new Error("BlobNotFound: The specified blob does not exist."); } else { throw error_3; } return [3 /*break*/, 3]; case 3: return [2 /*return*/, result]; } }); }); }; InMemoryBlobStorage.prototype.setBlockBlobContentsFromString = function (blobPath, blobContents, options) { if (options === void 0) { options = {}; } return tslib_1.__awaiter(this, void 0, void 0, function () { var blobName, container, blob, etag, result; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: blobPath = BlobPath.parse(blobPath); blobName = blobPath.blobName; return [4 /*yield*/, this.getInMemoryContainer(blobPath)]; case 1: container = _a.sent(); blob = container.blobs[blobName]; if (options.etag && (!blob || blob.etag !== options.etag)) { throw new Error("ConditionNotMet: The condition specified using HTTP conditional header(s) is not met."); } if (!blob) { etag = "1"; container.blobs[blobName] = { contents: blobContents, contentType: options.contentType || "application/octet-stream", blobType: "block", etag: etag, }; } else { etag = bumpETag(blob.etag); blob.contents = blobContents; blob.contentType = options.contentType || "application/octet-stream"; blob.etag = etag; } result = { created: !blob, etag: etag, }; return [2 /*return*/, result]; } }); }); }; InMemoryBlobStorage.prototype.setBlockBlobContentsFromFile = function (blockBlobPath, filePath, options) { if (options === void 0) { options = {}; } return tslib_1.__awaiter(this, void 0, void 0, function () { var blockBlobName, container, blockBlob, etag, result; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: blockBlobPath = BlobPath.parse(blockBlobPath); blockBlobName = blockBlobPath.blobName; return [4 /*yield*/, this.getInMemoryContainer(blockBlobPath)]; case 1: container = _a.sent(); blockBlob = container.blobs[blockBlobName]; if (options.etag && (!blockBlob || blockBlob.etag !== options.etag)) { throw new Error("ConditionNotMet: The condition specified using HTTP conditional header(s) is not met."); } if (!blockBlob) { etag = "1"; container.blobs[blockBlobName] = { contents: fs.readFileSync(filePath, defaultEncoding), contentType: options.contentType || "application/octet-stream", blobType: "block", etag: etag, }; } else { etag = bumpETag(blockBlob.etag); blockBlob.contents = fs.readFileSync(filePath, defaultEncoding); blockBlob.contentType = options.contentType || "application/octet-stream"; blockBlob.etag = etag; } result = { created: !blockBlob, etag: etag, }; return [2 /*return*/, result]; } }); }); }; InMemoryBlobStorage.prototype.addToAppendBlobContentsFromString = function (appendBlobPath, blobContentsToAppend, options) { if (options === void 0) { options = {}; } return tslib_1.__awaiter(this, void 0, void 0, function () { var appendBlob, result; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getInMemoryBlob(appendBlobPath)]; case 1: appendBlob = _a.sent(); if (options.etag && appendBlob.etag !== options.etag) { throw new Error("ConditionNotMet: The condition specified using HTTP conditional header(s) is not met."); } appendBlob.contents += blobContentsToAppend; appendBlob.etag = bumpETag(appendBlob.etag); result = { etag: appendBlob.etag }; return [2 /*return*/, result]; } }); }); }; InMemoryBlobStorage.prototype.getBlobContentType = function (blobPath) { return this.getInMemoryBlob(blobPath) .then(function (blob) { return blob.contentType; }); }; InMemoryBlobStorage.prototype.setBlobContentType = function (blobPath, contentType) { return this.getInMemoryBlob(blobPath) .then(function (blob) { blob.contentType = contentType; }); }; InMemoryBlobStorage.prototype.deleteBlob = function (blobPath) { var _this = this; blobPath = BlobPath.parse(blobPath); var blobName = blobPath.blobName; return validateBlobName(blobPath) .then(function () { return _this.getInMemoryContainer(blobPath) .then(function (container) { var result = false; if (blobName in container.blobs) { result = true; delete container.blobs[blobName]; } return result; }); }); }; InMemoryBlobStorage.prototype.createContainer = function (containerName, options) { var _this = this; if (options === void 0) { options = {}; } return this.getInMemoryContainer(containerName) .catch(function (error) { return resolveIfErrorMessageContains(error, "ContainerNotFound", undefined); }) .then(function () { var result = !(containerName in _this.containers); if (result) { _this.containers[containerName] = { name: containerName, blobs: {}, accessPolicy: options.accessPolicy || "private" }; } return result; }); }; InMemoryBlobStorage.prototype.containerExists = function (containerName) { return this.getInMemoryContainer(containerName) .then(function () { return true; }) .catch(function (error) { return resolveIfErrorMessageContains(error, "ContainerNotFound", false); }); }; InMemoryBlobStorage.prototype.getContainerAccessPolicy = function (containerName) { return this.getInMemoryContainer(containerName) .then(function (container) { return container.accessPolicy; }); }; InMemoryBlobStorage.prototype.setContainerAccessPolicy = function (containerName, permissions) { return this.getInMemoryContainer(containerName) .then(function (container) { container.accessPolicy = permissions; }); }; InMemoryBlobStorage.prototype.deleteContainer = function (containerName) { var _this = this; return this.getInMemoryContainer(containerName) .then(function () { delete _this.containers[containerName]; return true; }) .catch(function (error) { return resolveIfErrorMessageContains(error, "ContainerNotFound", false); }); }; InMemoryBlobStorage.prototype.listContainers = function () { var e_1, _a; var result = []; try { for (var _b = tslib_1.__values(Object.keys(this.containers)), _c = _b.next(); !_c.done; _c = _b.next()) { var containerName = _c.value; result.push(this.getContainer(containerName)); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_1) throw e_1.error; } } return Promise.resolve(result); }; return InMemoryBlobStorage; }(BlobStorage)); exports.InMemoryBlobStorage = InMemoryBlobStorage; /** * Validate that the provided BlobPath's blobName is defined and not-empty. * @param blobPath The blob path to validate. */ function validateBlobName(blobPath) { blobPath = BlobPath.parse(blobPath); return !blobPath.blobName ? Promise.reject(new Error("InvalidUri: The requested URI does not represent any resource on the server.")) : Promise.resolve(); } exports.validateBlobName = validateBlobName; function getAzureContainerAccessPermissions(permissions) { return permissions && permissions !== "private" ? permissions : undefined; } exports.getAzureContainerAccessPermissions = getAzureContainerAccessPermissions; /** * The maximum number of bytes that can be uploaded in a single AppendBlob block. */ var maximumAppendBlobUploadSize = 4 * 1024 * 1024; /** * A BlobStorage system that uses Azure Blob Storage to store data. */ var AzureBlobStorage = /** @class */ (function (_super) { tslib_1.__extends(AzureBlobStorage, _super); function AzureBlobStorage(storageAccountNameOrUrl, credentials) { var _this = _super.call(this) || this; _this.url = constructBlobStorageURL(storageAccountNameOrUrl); _this.credentials = constructBlobStorageCredentials(_this.url, credentials); var pipeline = storage_blob_1.StorageURL.newPipeline(_this.credentials); _this.serviceUrl = new storage_blob_1.ServiceURL(_this.url, pipeline); return _this; } AzureBlobStorage.prototype.getAzureContainerURL = function (containerName) { return storage_blob_1.ContainerURL.fromServiceURL(this.serviceUrl, containerName); }; AzureBlobStorage.prototype.getBlockBlobURL = function (blockBlobPath) { blockBlobPath = BlobPath.parse(blockBlobPath); var containerUrl = this.getAzureContainerURL(blockBlobPath.containerName); return storage_blob_1.BlockBlobURL.fromContainerURL(containerUrl, blockBlobPath.blobName); }; AzureBlobStorage.prototype.getAppendBlobURL = function (appendBlobPath) { appendBlobPath = BlobPath.parse(appendBlobPath); var containerUrl = this.getAzureContainerURL(appendBlobPath.containerName); return storage_blob_1.AppendBlobURL.fromContainerURL(containerUrl, appendBlobPath.blobName); }; AzureBlobStorage.prototype.getURL = function (options) { if (options === void 0) { options = {}; } return processBlobUrl(this.url, options, this.credentials); }; AzureBlobStorage.prototype.getContainerURL = function (containerName, options) { if (options === void 0) { options = {}; } var containerUrl = this.getAzureContainerURL(containerName); return processBlobUrl(containerUrl.url, options, this.credentials); }; AzureBlobStorage.prototype.getBlobURL = function (blobPath, options) { if (options === void 0) { options = {}; } var blobUrl = this.getBlockBlobURL(blobPath); var urlBuilder = url_1.URLBuilder.parse(blobUrl.url); var path = urlBuilder.getPath(); if (path) { var blobPath_1 = BlobPath.parse(path); if (blobPath_1.blobName) { urlBuilder.setPath(blobPath_1.containerName + "/" + decodeBlobName(blobPath_1.blobName)); } } return processBlobUrlBuilder(urlBuilder, options, this.credentials); }; AzureBlobStorage.prototype.blobExists = function (blobPath) { return tslib_1.__awaiter(this, void 0, void 0, function () { var result, error_4; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); return [4 /*yield*/, this.getBlobProperties(blobPath)]; case 1: _a.sent(); result = true; return [3 /*break*/, 3]; case 2: error_4 = _a.sent(); if (error_4.message.includes("BlobNotFound")) { result = false; } else { throw error_4; } return [3 /*break*/, 3]; case 3: return [2 /*return*/, result]; } }); }); }; AzureBlobStorage.prototype.getBlobProperties = function (blobPath) { return tslib_1.__awaiter(this, void 0, void 0, function () { var blockBlobUrl, result, getPropertiesResult, error_5; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: blockBlobUrl = this.getBlockBlobURL(blobPath); _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4 /*yield*/, blockBlobUrl.getProperties(storage_blob_1.Aborter.none)]; case 2: getPropertiesResult = _a.sent(); result = { etag: getPropertiesResult.eTag, }; return [3 /*break*/, 4]; case 3: error_5 = _a.sent(); if (error_5.statusCode === 404) { throw new Error("BlobNotFound: The specified blob does not exist."); } else { throw error_5; } return [3 /*break*/, 4]; case 4: return [2 /*return*/, result]; } }); }); }; AzureBlobStorage.prototype.getBlobContentsAsString = function (blobPath) { return tslib_1.__awaiter(this, void 0, void 0, function () { var blockBlobUrl, result, blobDownloadResponse, _a, error_6; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, validateBlobName(blobPath)]; case 1: _b.sent(); blockBlobUrl = this.getBlockBlobURL(blobPath); _b.label = 2; case 2: _b.trys.push([2, 5, , 6]); return [4 /*yield*/, blockBlobUrl.download(storage_blob_1.Aborter.none, 0, undefined)]; case 3: blobDownloadResponse = _b.sent(); _a = {}; return [4 /*yield*/, common_1.readEntireString(blobDownloadResponse.readableStreamBody)]; case 4: result = (_a.contents = (_b.sent()), _a.etag = blobDownloadResponse.eTag, _a); return [3 /*break*/, 6]; case 5: error_6 = _b.sent(); if (error_6.statusCode === 404) { throw new Error("BlobNotFound: The specified blob does not exist."); } else { throw error_6; }