@slynova/flydrive-gcs
Version:
Google Cloud Storage driver for @slynova/flydrive
214 lines • 6.13 kB
JavaScript
;
/**
* @slynova/flydrive
*
* @license MIT
* @copyright Slynova - Romain Lanz <romain.lanz@slynova.ch>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.GoogleCloudStorage = void 0;
const flydrive_1 = require("@slynova/flydrive");
function handleError(err, path) {
switch (err.code) {
case 401:
return new flydrive_1.AuthorizationRequired(err, path);
case 403:
return new flydrive_1.PermissionMissing(err, path);
case 404:
return new flydrive_1.FileNotFound(err, path);
case 'ENOENT':
return new flydrive_1.WrongKeyPath(err, path);
default:
return new flydrive_1.UnknownException(err, String(err.code), path);
}
}
class GoogleCloudStorage extends flydrive_1.Storage {
constructor(config) {
super();
this.$config = config;
const GCSStorage = require('@google-cloud/storage').Storage;
this.$driver = new GCSStorage(config);
this.$bucket = this.$driver.bucket(config.bucket);
}
_file(path) {
return this.$bucket.file(path);
}
/**
* Copy a file to a location.
*/
async copy(src, dest) {
const srcFile = this._file(src);
const destFile = this._file(dest);
try {
const result = await srcFile.copy(destFile);
return { raw: result };
}
catch (e) {
throw handleError(e, src);
}
}
/**
* Delete existing file.
*/
async delete(location) {
try {
const result = await this._file(location).delete();
return { raw: result, wasDeleted: true };
}
catch (e) {
e = handleError(e, location);
if (e instanceof flydrive_1.FileNotFound) {
return { raw: undefined, wasDeleted: false };
}
throw e;
}
}
/**
* Returns the driver.
*/
driver() {
return this.$driver;
}
/**
* Determines if a file or folder already exists.
*/
async exists(location) {
try {
const result = await this._file(location).exists();
return { exists: result[0], raw: result };
}
catch (e) {
throw handleError(e, location);
}
}
/**
* Returns the file contents.
*/
async get(location, encoding = 'utf-8') {
try {
const result = await this._file(location).download();
return { content: result[0].toString(encoding), raw: result };
}
catch (e) {
throw handleError(e, location);
}
}
/**
* Returns the file contents as Buffer.
*/
async getBuffer(location) {
try {
const result = await this._file(location).download();
return { content: result[0], raw: result };
}
catch (e) {
throw handleError(e, location);
}
}
/**
* Returns signed url for an existing file.
*/
async getSignedUrl(location, options = {}) {
const { expiry = 900 } = options;
try {
const result = await this._file(location).getSignedUrl({
action: 'read',
expires: Date.now() + expiry * 1000,
});
return { signedUrl: result[0], raw: result };
}
catch (e) {
throw handleError(e, location);
}
}
/**
* Returns file's size and modification date.
*/
async getStat(location) {
try {
const result = await this._file(location).getMetadata();
return {
size: Number(result[0].size),
modified: new Date(result[0].updated),
raw: result,
};
}
catch (e) {
throw handleError(e, location);
}
}
/**
* Returns the stream for the given file.
*/
getStream(location) {
return this._file(location).createReadStream();
}
/**
* Returns URL for a given location. Note this method doesn't
* validates the existence of file or it's visibility
* status.
*/
getUrl(location) {
return `https://storage.googleapis.com/${this.$bucket.name}/${location}`;
}
/**
* Move file to a new location.
*/
async move(src, dest) {
const srcFile = this._file(src);
const destFile = this._file(dest);
try {
const result = await srcFile.move(destFile);
return { raw: result };
}
catch (e) {
throw handleError(e, src);
}
}
/**
* Creates a new file.
* This method will create missing directories on the fly.
*/
async put(location, content) {
const file = this._file(location);
try {
if (flydrive_1.isReadableStream(content)) {
const destStream = file.createWriteStream();
await flydrive_1.pipeline(content, destStream);
return { raw: undefined };
}
const result = await file.save(content, { resumable: false });
return { raw: result };
}
catch (e) {
throw handleError(e, location);
}
}
/**
* Iterate over all files in the bucket.
*/
async *flatList(prefix = '') {
let nextQuery = {
prefix,
autoPaginate: false,
maxResults: 1000,
};
do {
try {
const result = (await this.$bucket.getFiles(nextQuery));
nextQuery = result[1];
for (const file of result[0]) {
yield {
raw: file.metadata,
path: file.name,
};
}
}
catch (e) {
throw handleError(e, prefix);
}
} while (nextQuery);
}
}
exports.GoogleCloudStorage = GoogleCloudStorage;
//# sourceMappingURL=GoogleCloudStorage.js.map