UNPKG

@slynova/flydrive-s3

Version:

AWS S3 driver for @slynova/flydrive

221 lines 6.82 kB
"use strict"; /** * @slynova/flydrive * * @license MIT * @copyright Slynova - Romain Lanz <romain.lanz@slynova.ch> */ Object.defineProperty(exports, "__esModule", { value: true }); exports.AmazonWebServicesS3Storage = void 0; const flydrive_1 = require("@slynova/flydrive"); function handleError(err, path, bucket) { switch (err.name) { case 'NoSuchBucket': return new flydrive_1.NoSuchBucket(err, bucket); case 'NoSuchKey': return new flydrive_1.FileNotFound(err, path); case 'AllAccessDisabled': return new flydrive_1.PermissionMissing(err, path); default: return new flydrive_1.UnknownException(err, err.name, path); } } class AmazonWebServicesS3Storage extends flydrive_1.Storage { constructor(config) { super(); // eslint-disable-next-line @typescript-eslint/no-var-requires const S3 = require('aws-sdk/clients/s3'); this.$driver = new S3({ accessKeyId: config.key, secretAccessKey: config.secret, ...config, }); this.$bucket = config.bucket; } /** * Copy a file to a location. */ async copy(src, dest) { const params = { Key: dest, Bucket: this.$bucket, CopySource: `/${this.$bucket}/${src}`, }; try { const result = await this.$driver.copyObject(params).promise(); return { raw: result }; } catch (e) { throw handleError(e, src, this.$bucket); } } /** * Delete existing file. */ async delete(location) { const params = { Key: location, Bucket: this.$bucket }; try { const result = await this.$driver.deleteObject(params).promise(); // Amazon does not inform the client if anything was deleted. return { raw: result, wasDeleted: null }; } catch (e) { throw handleError(e, location, this.$bucket); } } /** * Returns the driver. */ driver() { return this.$driver; } /** * Determines if a file or folder already exists. */ async exists(location) { const params = { Key: location, Bucket: this.$bucket }; try { const result = await this.$driver.headObject(params).promise(); return { exists: true, raw: result }; } catch (e) { if (e.statusCode === 404) { return { exists: false, raw: e }; } else { throw handleError(e, location, this.$bucket); } } } /** * Returns the file contents. */ async get(location, encoding = 'utf-8') { const bufferResult = await this.getBuffer(location); return { content: bufferResult.content.toString(encoding), raw: bufferResult.raw, }; } /** * Returns the file contents as Buffer. */ async getBuffer(location) { const params = { Key: location, Bucket: this.$bucket }; try { const result = await this.$driver.getObject(params).promise(); // S3.getObject returns a Buffer in Node.js const body = result.Body; return { content: body, raw: result }; } catch (e) { throw handleError(e, location, this.$bucket); } } /** * Returns signed url for an existing file */ async getSignedUrl(location, options = {}) { const { expiry = 900 } = options; try { const params = { Key: location, Bucket: this.$bucket, Expires: expiry, }; const result = await this.$driver.getSignedUrlPromise('getObject', params); return { signedUrl: result, raw: result }; } catch (e) { throw handleError(e, location, this.$bucket); } } /** * Returns file's size and modification date. */ async getStat(location) { const params = { Key: location, Bucket: this.$bucket }; try { const result = await this.$driver.headObject(params).promise(); return { size: result.ContentLength, modified: result.LastModified, raw: result, }; } catch (e) { throw handleError(e, location, this.$bucket); } } /** * Returns the stream for the given file. */ getStream(location) { const params = { Key: location, Bucket: this.$bucket }; return this.$driver.getObject(params).createReadStream(); } /** * Returns url for a given key. */ getUrl(location) { const { href } = this.$driver.endpoint; if (href.startsWith('https://s3.amazonaws')) { return `https://${this.$bucket}.s3.amazonaws.com/${location}`; } return `${href}${this.$bucket}/${location}`; } /** * Moves file from one location to another. This * method will call `copy` and `delete` under * the hood. */ async move(src, dest) { await this.copy(src, dest); await this.delete(src); return { raw: undefined }; } /** * Creates a new file. * This method will create missing directories on the fly. */ async put(location, content) { const params = { Key: location, Body: content, Bucket: this.$bucket }; try { const result = await this.$driver.upload(params).promise(); return { raw: result }; } catch (e) { throw handleError(e, location, this.$bucket); } } /** * Iterate over all files in the bucket. */ async *flatList(prefix = '') { let continuationToken; do { try { const response = await this.$driver .listObjectsV2({ Bucket: this.$bucket, Prefix: prefix, ContinuationToken: continuationToken, MaxKeys: 1000, }) .promise(); continuationToken = response.NextContinuationToken; for (const file of response.Contents) { yield { raw: file, path: file.Key, }; } } catch (e) { throw handleError(e, prefix, this.$bucket); } } while (continuationToken); } } exports.AmazonWebServicesS3Storage = AmazonWebServicesS3Storage; //# sourceMappingURL=AmazonWebServicesS3Storage.js.map