UNPKG

@graperank/storage-s3

Version:

The S3 Storage plugin provides GrapeRank the means to store and retrieve scorecards from any S3 compatible simple storage service.

169 lines (168 loc) 6.91 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.s3Api = void 0; // Adapted apiS3.ts from nostrmeet.me // FIXME env depends on being run inside svelte const client_s3_1 = require("@aws-sdk/client-s3"); class s3Api { bucket; client; constructor(config) { if (!config) throw ('GrapeRank : Storage : missing config required for s3 client'); let clientconfig = { forcePathStyle: false, // Configures to use subdomain/virtual calling format. region: config.region, // Must be "us-east-1" when creating new Spaces. Otherwise, use the region in your endpoint (for example, nyc3). endpoint: config.endpoint, // Find your endpoint in the control panel, under Settings. Prepend "https://". credentials: { accessKeyId: config.key, // Access key pair. You can create access key pairs using the control panel or API. secretAccessKey: config.secret // Secret access key defined through an environment variable. } }; this.client = new client_s3_1.S3Client(clientconfig); if (!config.bucket) throw ('missing bucket required for s3 client'); this.bucket = config.bucket; } async send(op, objectinput) { let data; let path; try { // let command : GetObjectCommand | PutObjectCommand | ListObjectsCommand; switch (op) { case 'get': if ("Key" in objectinput) path = objectinput.Key; data = await this.client.send(new client_s3_1.GetObjectCommand(objectinput)); break; case 'put': if ("Key" in objectinput && "Body" in objectinput) path = objectinput.Key; data = await this.client.send(new client_s3_1.PutObjectCommand(objectinput)); break; case 'list': if ("Marker" in objectinput || "Prefix" in objectinput) path = "Marker" in objectinput ? objectinput.Marker : objectinput.Prefix; data = await this.client.send(new client_s3_1.ListObjectsCommand(objectinput)); break; default: throw ('invalid command requested'); } if (!data) throw ('no data returned'); console.log("Success s3.send('" + op + "') to : " + path); // console.log("s3.send() response : ", data); } catch (err) { console.log("WARNING s3.send('" + op + "') request failed: ", path, err); // console.log("s3.send('"+op+"') input : ", objectinput); // console.log("s3.send('"+op+"') response : ", data); // throw('s3.send() request failed'); } return data; } async get(Key) { try { // if(!this.bucket) throw('s3 Bucket not specified') let input = { Bucket: this.bucket, Key }; // console.log('s3.get('+type+','+userid+','+objid+') calling s3.send() : ',input); return await this.send('get', input).then(async (output) => { let getoutput = output; if (!getoutput) throw ('not found'); console.log('s3.get() output recieved from s3.send()'); return JSON.parse(await getoutput?.Body?.transformToString()); //Api.verify(JSON.parse(apievent)); }); } catch (e) { console.log('unable to get data from storage : ', Key, e); return undefined; } } // validate data BEFORE sending to s3.put() async put(Key, data, overwrite = false) { let input; try { if (!this.bucket) throw ('s3 Bucket not specified'); // confirm allowed overwrite if (!overwrite) { let existing = await this.get(Key).then(data => { try { return data === undefined ? false : true; } catch { return false; } }); if (existing) throw ('overwrite is not permitted'); } // send to storage input = { Bucket: this.bucket, Key, Body: JSON.stringify(data), ACL: "private", Metadata: {} }; // console.log('s3.put() recieved apievent : ',apievent); // console.log('s3,put() passing command input to s3.send() : ',input); return await this.send('put', input).then(() => true).catch(() => false); } catch (e) { console.log('unable to put data to storage : ', Key, e); // console.log('InputObject : ',input) return false; } } /** * Returns S3FileList * containing a`filenames` array of items found. * if `nextKey` is a string, use its value to get more items * @param type * @param userid * @returns s3ListObjectOutput {IsTruncated : boolean, Keys : string[]} */ async list(Key) { let input; let output; try { if (!this.bucket) throw ('s3 Bucket not specified'); if (!Key.endsWith('/')) Key = Key + '/'; let filenames = []; input = { Bucket: this.bucket, Marker: Key, Prefix: Key, }; output = await this.send('list', input).then(s3 => { let s3output = s3; if (!s3output) throw ('not found'); if (!s3output.Contents) throw ('no list content'); let objid, next; console.log('s3.list() found ', s3output.Contents.length, ' files matching :', Key); s3output.Contents.forEach((obj) => { if ("Key" in obj && typeof (obj.Key) == 'string') { // console.log('s3.list() file : ', obj.Key); objid = obj.Key.replace(Key, '').replace('.json', ''); filenames.push(objid); if (!s3output?.IsTruncated) next = objid; } }); return { next, list: filenames }; }); return output; } catch (e) { // log details to server console.log('unable to list data in storage : ', Key, e); // console.log('InputObject : ',input) return undefined; } } } exports.s3Api = s3Api;