174 lines
8.1 KiB
JavaScript
174 lines
8.1 KiB
JavaScript
const fs = require('fs-extra');
|
|
const mime = require('mime-types');
|
|
const { join, basename, dirname } = require('path');
|
|
const { toSystemPath } = require('../core/path');
|
|
|
|
module.exports = {
|
|
|
|
provider: function (options, name) {
|
|
this.setS3Provider(name, options);
|
|
},
|
|
|
|
createBucket: async function (options) {
|
|
const provider = this.parseRequired(options.provider, 'string', 's3.createBucket: provider is required.');
|
|
const Bucket = this.parseRequired(options.bucket, 'string', 's3.createBucket: bucket is required.');
|
|
const ACL = this.parseOptional(options.acl, 'string', undefined);
|
|
const s3 = this.getS3Provider(provider);
|
|
|
|
if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
|
|
|
|
return s3.createBucket({ Bucket, ACL });
|
|
},
|
|
|
|
listBuckets: async function (options) {
|
|
const provider = this.parseRequired(options.provider, 'string', 's3.listBuckets: provider is required.');
|
|
const s3 = this.getS3Provider(provider);
|
|
|
|
if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
|
|
|
|
return s3.listBuckets({});
|
|
},
|
|
|
|
deleteBucket: async function (options) {
|
|
const provider = this.parseRequired(options.provider, 'string', 's3.deleteBucket: provider is required.');
|
|
const Bucket = this.parseRequired(options.bucket, 'string', 's3.deleteBucket: bucket is required.');
|
|
const s3 = this.getS3Provider(provider);
|
|
|
|
if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
|
|
|
|
return s3.deleteBucket({ Bucket });
|
|
},
|
|
|
|
listFiles: async function (options) {
|
|
const provider = this.parseRequired(options.provider, 'string', 's3.listFiles: provider is required.');
|
|
const Bucket = this.parseRequired(options.bucket, 'string', 's3.listFiles: bucket is required.');
|
|
const MaxKeys = this.parseOptional(options.maxKeys, 'number', undefined);
|
|
const Prefix = this.parseOptional(options.prefix, 'string', undefined);
|
|
const ContinuationToken = this.parseOptional(options.continuationToken, 'string', undefined);
|
|
const StartAfter = this.parseOptional(options.startAfter, 'string', undefined);
|
|
const s3 = this.getS3Provider(provider);
|
|
|
|
if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
|
|
|
|
return s3.listObjectsV2({ Bucket, MaxKeys, Prefix, ContinuationToken, StartAfter });
|
|
},
|
|
|
|
putFile: async function (options) {
|
|
const provider = this.parseRequired(options.provider, 'string', 's3.uploadFile: provider is required.');
|
|
const Bucket = this.parseRequired(options.bucket, 'string', 's3.uploadFile: bucket is required.');
|
|
const path = toSystemPath(this.parseRequired(options.path, 'string', 's3.uploadFile: path is required.'));
|
|
const Key = this.parseRequired(options.key, 'string', 's3.uploadFile: key is required.');
|
|
const ContentType = this.parseOptional(options.contentType, 'string', mime.lookup(Key) || 'application/octet-stream');
|
|
const ContentDisposition = this.parseOptional(options.contentDisposition, 'string', undefined);
|
|
const ACL = this.parseOptional(options.acl, 'string', undefined);
|
|
const s3 = this.getS3Provider(provider);
|
|
|
|
if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
|
|
|
|
let Body = fs.createReadStream(path);
|
|
|
|
const result = await s3.putObject({ Bucket, ACL, Key, ContentType, ContentDisposition, Body });
|
|
|
|
try {
|
|
const endpoint = await s3.config.endpoint();
|
|
result.Location = `https://${Bucket}.${endpoint.hostname}/${Key}`;
|
|
} catch (e) {}
|
|
|
|
|
|
return result;
|
|
},
|
|
|
|
getFile: async function (options) {
|
|
const provider = this.parseRequired(options.provider, 'string', 's3.getFile: provider is required.');
|
|
const Bucket = this.parseRequired(options.bucket, 'string', 's3.getFile: bucket is required.');
|
|
const Key = this.parseRequired(options.key, 'string', 's3.getFile: key is required.');
|
|
const path = toSystemPath(this.parseRequired(options.path, 'string', 's3.getFile: path is required.'));
|
|
const stripKeyPath = this.parseOptional(options.stripKeyPath, 'boolean', false);
|
|
const s3 = this.getS3Provider(provider);
|
|
|
|
if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
|
|
|
|
const file = Key;
|
|
if (stripKeyPath) file = basename(file);
|
|
const destination = join(path, file);
|
|
|
|
await fs.ensureDir(dirname(destination));
|
|
|
|
const writer = fs.createWriteStream(destination);
|
|
|
|
const { Body } = await s3.getObject({ Bucket, Key });
|
|
|
|
Body.pipe(writer);
|
|
|
|
return new Promise((resolve, reject) => {
|
|
writer.on('finish', resolve);
|
|
writer.on('error', reject);
|
|
});
|
|
},
|
|
|
|
deleteFile: async function (options) {
|
|
const provider = this.parseRequired(options.provider, 'string', 's3.deleteFile: provider is required.');
|
|
const Bucket = this.parseRequired(options.bucket, 'string', 's3.deleteFile: bucket is required.');
|
|
const Key = this.parseRequired(options.key, 'string', 's3.deleteFile: key is required.');
|
|
const s3 = this.getS3Provider(provider);
|
|
|
|
if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
|
|
|
|
return s3.deleteObject({ Bucket, Key });
|
|
},
|
|
|
|
downloadFile: async function (options) {
|
|
const provider = this.parseRequired(options.provider, 'string', 's3.downloadFile: profider is required.');
|
|
const Bucket = this.parseRequired(options.bucket, 'string', 's3.downloadFile: bucket is required.');
|
|
const Key = this.parseRequired(options.key, 'string', 's3.downloadFile: key is required.');
|
|
const s3 = this.getS3Provider(provider);
|
|
|
|
if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
|
|
|
|
const data = await s3.headObject({ Bucket, Key });
|
|
|
|
this.res.set('Content-Length', data.ContentLength);
|
|
this.res.attachment(basename(Key));
|
|
|
|
const { Body } = await s3.getObject({ Bucket, Key });
|
|
|
|
Body.pipe(this.res);
|
|
|
|
this.noOutput = true;
|
|
},
|
|
|
|
signDownloadUrl: async function (options) {
|
|
const provider = this.parseRequired(options.provider, 'string', 's3.signDownloadUrl: provider is required.');
|
|
const Bucket = this.parseRequired(options.bucket, 'string', 's3.signDownloadUrl: bucket is required.');
|
|
const Key = this.parseRequired(options.key, 'string', 's3.signDownloadUrl: key is required.');
|
|
const expiresIn = this.parseOptional(options.expires, 'number', 300);
|
|
const s3 = this.getS3Provider(provider);
|
|
|
|
if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
|
|
|
|
const { getSignedUrl } = require("@aws-sdk/s3-request-presigner");
|
|
const { GetObjectCommand } = require('@aws-sdk/client-s3');
|
|
const command = new GetObjectCommand({ Bucket, Key });
|
|
|
|
return getSignedUrl(s3, command, { expiresIn });
|
|
},
|
|
|
|
signUploadUrl: async function (options) {
|
|
const provider = this.parseRequired(options.provider, 'string', 's3.signUploadUrl: provider is required.');
|
|
const Bucket = this.parseRequired(options.bucket, 'string', 's3.signUploadUrl: bucket is required.');
|
|
const Key = this.parseRequired(options.key, 'string', 's3.signUploadUrl: key is required.');
|
|
const ContentType = this.parseOptional(options.contentType, 'string', mime.lookup(Key) || 'application/octet-stream');
|
|
const expiresIn = this.parseOptional(options.expires, 'number', 300);
|
|
const ACL = this.parseOptional(options.acl, 'string', undefined);
|
|
const s3 = this.getS3Provider(provider);
|
|
|
|
if (!s3) throw new Error(`S3 provider "${provider}" doesn't exist.`);
|
|
|
|
const { getSignedUrl } = require("@aws-sdk/s3-request-presigner");
|
|
const { PutObjectCommand } = require('@aws-sdk/client-s3');
|
|
const command = new PutObjectCommand({ Bucket, Key, ContentType, ACL });
|
|
|
|
return getSignedUrl(s3, command, { expiresIn });
|
|
}
|
|
|
|
}; |