"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _utils = require("./utils/index.cjs"); var _storageBlob = require("@azure/storage-blob"); var _identity = require("@azure/identity"); const DRIVER_NAME = "azure-storage-blob"; module.exports = (0, _utils.defineDriver)(opts => { let containerClient; const endpointSuffix = opts.endpointSuffix || ".blob.core.windows.net"; const getContainerClient = () => { if (containerClient) { return containerClient; } if (!opts.connectionString && !opts.sasUrl && !opts.accountName) { throw (0, _utils.createError)(DRIVER_NAME, "missing accountName"); } let serviceClient; if (opts.accountKey) { const credential = new _storageBlob.StorageSharedKeyCredential(opts.accountName, opts.accountKey); serviceClient = new _storageBlob.BlobServiceClient(`https://${opts.accountName}${endpointSuffix}`, credential); } else if (opts.sasUrl) { if (opts.containerName && opts.sasUrl.includes(`${opts.containerName}?`)) { containerClient = new _storageBlob.ContainerClient(`${opts.sasUrl}`); return containerClient; } serviceClient = new _storageBlob.BlobServiceClient(opts.sasUrl); } else if (opts.sasKey) { if (opts.containerName) { containerClient = new _storageBlob.ContainerClient(`https://${opts.accountName}${endpointSuffix}/${opts.containerName}?${opts.sasKey}`); return containerClient; } serviceClient = new _storageBlob.BlobServiceClient(`https://${opts.accountName}${endpointSuffix}?${opts.sasKey}`); } else if (opts.connectionString) { serviceClient = _storageBlob.BlobServiceClient.fromConnectionString(opts.connectionString); } else { const credential = new _identity.DefaultAzureCredential(); serviceClient = new _storageBlob.BlobServiceClient(`https://${opts.accountName}${endpointSuffix}`, credential); } containerClient = serviceClient.getContainerClient(opts.containerName || "unstorage"); containerClient.createIfNotExists(); return containerClient; }; return { name: DRIVER_NAME, options: opts, getInstance: getContainerClient, async hasItem(key) { return await getContainerClient().getBlockBlobClient(key).exists(); }, async getItem(key) { try { const blob = await getContainerClient().getBlockBlobClient(key).download(); if (isBrowser) { return blob.blobBody ? await blobToString(await blob.blobBody) : null; } return blob.readableStreamBody ? (await streamToBuffer(blob.readableStreamBody)).toString() : null; } catch { return null; } }, async getItemRaw(key) { try { const blob = await getContainerClient().getBlockBlobClient(key).download(); if (isBrowser) { return blob.blobBody ? await blobToString(await blob.blobBody) : null; } return blob.readableStreamBody ? await streamToBuffer(blob.readableStreamBody) : null; } catch { return null; } }, async setItem(key, value) { await getContainerClient().getBlockBlobClient(key).upload(value, Buffer.byteLength(value)); }, async setItemRaw(key, value) { await getContainerClient().getBlockBlobClient(key).upload(value, Buffer.byteLength(value)); }, async removeItem(key) { await getContainerClient().getBlockBlobClient(key).deleteIfExists({ deleteSnapshots: "include" }); }, async getKeys() { const iterator = getContainerClient().listBlobsFlat().byPage({ maxPageSize: 1e3 }); const keys = []; for await (const page of iterator) { const pageKeys = page.segment.blobItems.map(blob => blob.name); keys.push(...pageKeys); } return keys; }, async getMeta(key) { const blobProperties = await getContainerClient().getBlockBlobClient(key).getProperties(); return { mtime: blobProperties.lastModified, atime: blobProperties.lastAccessed, cr: blobProperties.createdOn, ...blobProperties.metadata }; }, async clear() { const iterator = getContainerClient().listBlobsFlat().byPage({ maxPageSize: 1e3 }); for await (const page of iterator) { await Promise.all(page.segment.blobItems.map(async blob => await getContainerClient().deleteBlob(blob.name, { deleteSnapshots: "include" }))); } } }; }); const isBrowser = typeof window !== "undefined"; async function streamToBuffer(readableStream) { return new Promise((resolve, reject) => { const chunks = []; readableStream.on("data", data => { chunks.push(data instanceof Buffer ? data : Buffer.from(data)); }); readableStream.on("end", () => { resolve(Buffer.concat(chunks)); }); readableStream.on("error", reject); }); } async function blobToString(blob) { const fileReader = new FileReader(); return new Promise((resolve, reject) => { fileReader.onloadend = ev => { resolve(ev.target?.result); }; fileReader.onerror = reject; fileReader.readAsText(blob); }); }