@storybooker/azure
Version:
StoryBooker Adapter for interacting with Azure services.
96 lines (94 loc) • 4.54 kB
JavaScript
const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
let node_stream = require("node:stream");
node_stream = require_rolldown_runtime.__toESM(node_stream);
//#region src/blob-storage.ts
var AzureBlobStorageService = class {
#client;
constructor(client) {
this.createContainer = async (containerId, options) => {
const containerName = genContainerNameFromContainerId(containerId);
await this.#client.createContainer(containerName, { abortSignal: options.abortSignal });
};
this.deleteContainer = async (containerId, options) => {
const containerName = genContainerNameFromContainerId(containerId);
await this.#client.getContainerClient(containerName).deleteIfExists({ abortSignal: options.abortSignal });
};
this.hasContainer = async (containerId, options) => {
const containerName = genContainerNameFromContainerId(containerId);
return await this.#client.getContainerClient(containerName).exists({ abortSignal: options.abortSignal });
};
this.listContainers = async (options) => {
const containers = [];
for await (const item of this.#client.listContainers({ abortSignal: options.abortSignal })) containers.push(item.name);
return containers;
};
this.deleteFiles = async (containerId, filePathsOrPrefix, options) => {
const containerName = genContainerNameFromContainerId(containerId);
const containerClient = this.#client.getContainerClient(containerName);
const blobClientsToDelete = [];
if (typeof filePathsOrPrefix === "string") for await (const blob of containerClient.listBlobsFlat({
abortSignal: options.abortSignal,
prefix: filePathsOrPrefix
})) blobClientsToDelete.push(containerClient.getBlobClient(blob.name));
else for (const filepath of filePathsOrPrefix) blobClientsToDelete.push(containerClient.getBlobClient(filepath));
if (blobClientsToDelete.length === 0) return;
const response = await containerClient.getBlobBatchClient().deleteBlobs(blobClientsToDelete, { abortSignal: options.abortSignal });
if (response.errorCode) throw new Error(`Failed to delete blobs: ${response.errorCode}`);
};
this.uploadFiles = async (containerId, files, options) => {
const containerName = genContainerNameFromContainerId(containerId);
const containerClient = this.#client.getContainerClient(containerName);
const promises = files.map(async ({ content, path, mimeType }) => uploadFileToBlobStorage(containerClient.getBlockBlobClient(path), content, mimeType, options.abortSignal));
await Promise.allSettled(promises);
};
this.hasFile = async (containerId, filepath, options) => {
const containerName = genContainerNameFromContainerId(containerId);
return await this.#client.getContainerClient(containerName).getBlockBlobClient(filepath).exists({ abortSignal: options.abortSignal });
};
this.downloadFile = async (containerId, filepath, options) => {
const containerName = genContainerNameFromContainerId(containerId);
const blockBlobClient = this.#client.getContainerClient(containerName).getBlockBlobClient(filepath);
if (!await blockBlobClient.exists()) throw new Error(`File '${filepath}' not found in container '${containerId}'.`);
const downloadResponse = await blockBlobClient.download(0, void 0, { abortSignal: options.abortSignal });
if (!downloadResponse.readableStreamBody) throw new Error(`File '${filepath}' in container '${containerId}' is not downloadable.`);
return {
content: downloadResponse.readableStreamBody,
mimeType: downloadResponse.contentType,
path: filepath
};
};
this.#client = client;
}
};
function genContainerNameFromContainerId(containerId) {
return containerId.replaceAll(/[^\w-]+/g, "-").slice(0, 255).toLowerCase();
}
async function uploadFileToBlobStorage(client, data, mimeType, abortSignal) {
if (typeof data === "string") {
const blob = new Blob([data], { type: mimeType });
await client.uploadData(blob, {
abortSignal,
blobHTTPHeaders: { blobContentType: mimeType }
});
return;
}
if (data instanceof Blob) {
await client.uploadData(data, {
abortSignal,
blobHTTPHeaders: { blobContentType: mimeType }
});
return;
}
if (data instanceof ReadableStream) {
const stream = data;
await client.uploadStream(node_stream.Readable.fromWeb(stream), void 0, void 0, {
abortSignal,
blobHTTPHeaders: { blobContentType: mimeType }
});
return;
}
throw new Error(`Unknown file type`);
}
//#endregion
exports.AzureBlobStorageService = AzureBlobStorageService;
//# sourceMappingURL=blob-storage.cjs.map