strapi-provider-upload-azure-storage-blob
Version:
Strapi provider for uploads to Azure using @azure/storage-blob
155 lines (133 loc) • 5.23 kB
text/typescript
import { DefaultAzureCredential } from '@azure/identity';
import { AnonymousCredential, BlobServiceClient, StorageSharedKeyCredential } from '@azure/storage-blob';
type StorageBlobConfig = {
tenant: string;
client: string;
secret: string;
account: string,
accountKey: string,
containerName: string,
connectionString: string,
sasToken: string,
serviceBaseURL: string,
defaultPath: string
};
type StrapiFile = File & {
path: string;
url: string;
hash: string;
ext: string;
buffer: string;
mime: string;
}
const trimParam = (str:any) => (typeof str === 'string' ? str.trim() : undefined);
// A helper method used to read a Node.js readable stream into a Buffer
async function streamToBuffer(readableStream: NodeJS.ReadableStream): Promise<Buffer> {
return new Promise((resolve, reject) => {
const chunks: Buffer[] = [];
readableStream.on("data", (data: Buffer | string) => {
chunks.push(data instanceof Buffer ? data : Buffer.from(data));
});
readableStream.on("end", () => {
resolve(Buffer.concat(chunks));
});
readableStream.on("error", reject);
});
}
const createClient = (config: StorageBlobConfig) => {
const account = <string>trimParam(config.account);
const accountKey = <string>trimParam(config.accountKey);
const connStr = trimParam(config.connectionString);
const tenant = <string>trimParam(config.tenant);
const client = <string>trimParam(config.client);
const secret = <string>trimParam(config.secret);
const sasToken = <string>trimParam(config.sasToken);
const serviceBaseURL = trimParam(config.serviceBaseURL) || `https://${account}.blob.core.windows.net`;
if (tenant && client && secret && account) { //Azure Active Directory
const defaultCredential = new DefaultAzureCredential();
return new BlobServiceClient(serviceBaseURL, defaultCredential);
} else if (sasToken) {
const anonymousCredential = new AnonymousCredential();
return new BlobServiceClient(`${serviceBaseURL}${sasToken}`, anonymousCredential);
} else if (connStr) {
return BlobServiceClient.fromConnectionString(connStr);
} else if (account && accountKey) {
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
return new BlobServiceClient(serviceBaseURL, sharedKeyCredential);
} else {
throw new Error(
'Error in configuration, please be sure to configure the Azure account and accountKey or the connectionString.'
);
}
}
module.exports = {
provider: 'azure-storage-blob',
auth: {
tenant: {
label: 'Azure Tenant Id',
type: 'text'
},
client: {
label: 'Azure Client Id',
type: 'text',
},
secret: {
label: 'Azure Client Secret',
type: 'text',
},
account: {
label: 'Account Name',
type: 'text',
},
accountKey: {
label: 'Secret Access Key',
type: 'text',
},
connectionString: {
label: 'Connection String',
type: 'text',
},
containerName: {
label: 'Container name',
type: 'text',
},
sasToken: {
label: 'SAS Token',
type: 'text',
},
defaultPath: {
label: 'The path to use when there is none being specified',
type: 'text',
},
},
init: (config:StorageBlobConfig) => {
const defaultPath = trimParam(config.defaultPath) || 'assets';
const containerName = <string>trimParam(config.containerName);
const client = <BlobServiceClient>createClient(config);
return {
upload(file:StrapiFile, customParams = {}){
return new Promise<void>(async(resolve,reject) => {
const containerClient = client.getContainerClient(containerName);
// create blobClient for container
const blobClient = containerClient.getBlockBlobClient(`${defaultPath}/${file.name}`);
// set mimetype as determined from browser with file upload control
const options = { blobHTTPHeaders: { blobContentType: file.mime, ...customParams, } };
// upload file
const result = await blobClient.uploadData(file,options);
file.url = blobClient.url;
resolve();
})
},
delete(file:StrapiFile, customParams = {}){
return new Promise<void>(async(resolve,reject) => {
const containerClient = client.getContainerClient(containerName);
// create blobClient for container
const blobClient = containerClient.getBlobClient(`${defaultPath}/${file.name}`);
await blobClient.delete();
file.url = blobClient.url;
resolve();
})
}
}
}
}