From d5471a66a0f202746852acef9d77791e4c8571ac Mon Sep 17 00:00:00 2001 From: Adrian Curtin <48138055+AdrianCurtin@users.noreply.github.com> Date: Thu, 16 Jan 2025 18:29:39 -0500 Subject: [PATCH 1/7] Revise createFile logic to preserve key & location - Add error handling for key generation - Standardize return object with location, url, and filename - Add support for optional config parameter - Return s3 response explicitly as a separate variable --- index.js | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index d0589ee..e6ac4d0 100644 --- a/index.js +++ b/index.js @@ -139,16 +139,23 @@ class S3Adapter { // For a given config object, filename, and data, store a file in S3 // Returns a promise containing the S3 object creation response - async createFile(filename, data, contentType, options = {}) { + async createFile(filename, data, contentType, options = {}, config= {}) { + + let key_without_prefix = filename; + if (this._generateKey instanceof Function) { + try { + key_without_prefix = this._generateKey(filename); + }catch(e){ + throw new Error(e); // throw error if generateKey function fails + } + } + const params = { Bucket: this._bucket, - Key: this._bucketPrefix + filename, + Key: this._bucketPrefix + key_without_prefix, Body: data, }; - - if (this._generateKey instanceof Function) { - params.Key = this._bucketPrefix + this._generateKey(filename); - } + if (this._fileAcl) { if (this._fileAcl === 'none') { delete params.ACL; @@ -180,7 +187,14 @@ class S3Adapter { const endpoint = this._endpoint || `https://${this._bucket}.s3.${this._region}.amazonaws.com`; const location = `${endpoint}/${params.Key}`; - return Object.assign(response || {}, { Location: location }); + const url = await this.getFileLocation(config, key_without_prefix); + + return { + location: location, // actual upload location, used for tests + url: url, // optionally signed url (can be returned to client) + filename: key_without_prefix, // filename in storage + s3_response: response // raw s3 response + }; } async deleteFile(filename) { From a9edee2ca2c25ffc36c61d6f07435abf9514abb4 Mon Sep 17 00:00:00 2001 From: Adrian Curtin <48138055+AdrianCurtin@users.noreply.github.com> Date: Thu, 16 Jan 2025 18:42:17 -0500 Subject: [PATCH 2/7] Change to name to be consistent with parse server createFile --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index e6ac4d0..57c8085 100644 --- a/index.js +++ b/index.js @@ -192,7 +192,7 @@ class S3Adapter { return { location: location, // actual upload location, used for tests url: url, // optionally signed url (can be returned to client) - filename: key_without_prefix, // filename in storage + name: key_without_prefix, // filename in storage, consistent with other adapters s3_response: response // raw s3 response }; } From 2592fa82a79b0cfb921bc853362534002cce0205 Mon Sep 17 00:00:00 2001 From: Adrian Curtin <48138055+AdrianCurtin@users.noreply.github.com> Date: Thu, 16 Jan 2025 18:55:36 -0500 Subject: [PATCH 3/7] Update test.spec.js --- spec/test.spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/test.spec.js b/spec/test.spec.js index 28193d0..a75ff73 100644 --- a/spec/test.spec.js +++ b/spec/test.spec.js @@ -696,7 +696,7 @@ describe('S3Adapter tests', () => { const s3 = getMockS3Adapter(options); const fileName = 'randomFileName.txt'; const response = s3.createFile(fileName, 'hello world', 'text/utf8').then(value => { - const url = new URL(value.Location); + const url = new URL(value.location); expect(url.pathname.indexOf(fileName) > 13).toBe(true); }); promises.push(response); @@ -707,7 +707,7 @@ describe('S3Adapter tests', () => { const s3 = getMockS3Adapter(options); const fileName = 'foo/randomFileName.txt'; const response = s3.createFile(fileName, 'hello world', 'text/utf8').then(value => { - const url = new URL(value.Location); + const url = new URL(value.location); expect(url.pathname.substring(1)).toEqual(options.bucketPrefix + fileName); }); promises.push(response); @@ -717,7 +717,7 @@ describe('S3Adapter tests', () => { const s3 = getMockS3Adapter(options); const fileName = 'foo/randomFileName.txt'; const response = s3.createFile(fileName, 'hello world', 'text/utf8').then(value => { - const url = new URL(value.Location); + const url = new URL(value.location); expect(url.pathname.indexOf('foo/')).toEqual(6); expect(url.pathname.indexOf('random') > 13).toBe(true); }); From 5abd18a5002d21fc4fdfa4252fb3cc1fe27c420b Mon Sep 17 00:00:00 2001 From: Adrian Curtin <48138055+AdrianCurtin@users.noreply.github.com> Date: Thu, 16 Jan 2025 19:22:52 -0500 Subject: [PATCH 4/7] Update index.js --- index.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 57c8085..e3bb0e7 100644 --- a/index.js +++ b/index.js @@ -187,13 +187,16 @@ class S3Adapter { const endpoint = this._endpoint || `https://${this._bucket}.s3.${this._region}.amazonaws.com`; const location = `${endpoint}/${params.Key}`; - const url = await this.getFileLocation(config, key_without_prefix); + let url; + if (Object.keys(config).length != 0) { // if config is passed, we can generate a presigned url here + url = await this.getFileLocation(config, key_without_prefix); + } return { location: location, // actual upload location, used for tests - url: url, // optionally signed url (can be returned to client) name: key_without_prefix, // filename in storage, consistent with other adapters - s3_response: response // raw s3 response + s3_response: response, // raw s3 response + ...url? {url: url} : {} // url (optionally presigned) or non-direct access url }; } From 537a5ce9d24e91d191cf9b37c721568410af0362 Mon Sep 17 00:00:00 2001 From: Adrian Curtin <48138055+AdrianCurtin@users.noreply.github.com> Date: Fri, 17 Jan 2025 12:57:59 -0500 Subject: [PATCH 5/7] Correction to make codecov happy --- lib/optionsFromArguments.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/optionsFromArguments.js b/lib/optionsFromArguments.js index f56c9bc..b05c1fc 100644 --- a/lib/optionsFromArguments.js +++ b/lib/optionsFromArguments.js @@ -42,12 +42,12 @@ const optionsFromArguments = function optionsFromArguments(args) { } else if (args.length === 2) { options.bucket = stringOrOptions; if (typeof args[1] !== 'object') { - throw new Error("Failed to configure S3Adapter. Arguments don't make sense"); + throw new Error('Failed to configure S3Adapter. Arguments don\'t make sense'); } otherOptions = args[1]; } else if (args.length > 2) { if (typeof args[1] !== 'string' || typeof args[2] !== 'string') { - throw new Error("Failed to configure S3Adapter. Arguments don't make sense"); + throw new Error('Failed to configure S3Adapter. Arguments don\'t make sense'); } options.accessKey = args[0]; options.secretKey = args[1]; @@ -81,7 +81,7 @@ const optionsFromArguments = function optionsFromArguments(args) { options.bucket = s3overrides.params.Bucket; } } else if (args.length > 2) { - throw new Error("Failed to configure S3Adapter. Arguments don't make sense"); + throw new Error('Failed to configure S3Adapter. Arguments don\'t make sense'); } options = fromOptionsDictionaryOrDefault(options, 's3overrides', s3overrides); From 61ae6b027ca680dc5163caafa0743d7d6c9a577d Mon Sep 17 00:00:00 2001 From: Adrian Curtin <48138055+AdrianCurtin@users.noreply.github.com> Date: Fri, 17 Jan 2025 13:03:46 -0500 Subject: [PATCH 6/7] Remove and add some spaces to make lint happy --- index.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index e3bb0e7..81ed05e 100644 --- a/index.js +++ b/index.js @@ -139,8 +139,8 @@ class S3Adapter { // For a given config object, filename, and data, store a file in S3 // Returns a promise containing the S3 object creation response - async createFile(filename, data, contentType, options = {}, config= {}) { - + async createFile(filename, data, contentType, options = {}, config = {}) { + let key_without_prefix = filename; if (this._generateKey instanceof Function) { try { @@ -149,13 +149,13 @@ class S3Adapter { throw new Error(e); // throw error if generateKey function fails } } - + const params = { Bucket: this._bucket, Key: this._bucketPrefix + key_without_prefix, Body: data, }; - + if (this._fileAcl) { if (this._fileAcl === 'none') { delete params.ACL; @@ -195,8 +195,8 @@ class S3Adapter { return { location: location, // actual upload location, used for tests name: key_without_prefix, // filename in storage, consistent with other adapters - s3_response: response, // raw s3 response - ...url? {url: url} : {} // url (optionally presigned) or non-direct access url + s3_response: response, // raw s3 response + ...url ? { url: url } : {} // url (optionally presigned) or non-direct access url }; } From 87573b9d659f8a02443176ff30d062775b76578d Mon Sep 17 00:00:00 2001 From: Adrian Curtin <48138055+AdrianCurtin@users.noreply.github.com> Date: Fri, 17 Jan 2025 13:23:25 -0500 Subject: [PATCH 7/7] Allow generate key to access certain createfile traits --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 81ed05e..ef1201b 100644 --- a/index.js +++ b/index.js @@ -144,7 +144,7 @@ class S3Adapter { let key_without_prefix = filename; if (this._generateKey instanceof Function) { try { - key_without_prefix = this._generateKey(filename); + key_without_prefix = this._generateKey(filename, contentType, options); }catch(e){ throw new Error(e); // throw error if generateKey function fails }