eip-cloud-services 1.1.3 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/redis.js +2 -2
- package/src/s3.js +64 -41
package/package.json
CHANGED
package/src/redis.js
CHANGED
|
@@ -212,7 +212,7 @@ exports.multiGet = async ( keys ) => {
|
|
|
212
212
|
if ( Array.isArray ( keys ) ) {
|
|
213
213
|
const client = await getClient ();
|
|
214
214
|
|
|
215
|
-
const fullKeys = ( !config?.redis?.prefix ||
|
|
215
|
+
const fullKeys = keys.map ( key => ( !config?.redis?.prefix || key.startsWith ( config?.redis?.prefix ) ) ? key : config?.redis?.prefix + key );
|
|
216
216
|
|
|
217
217
|
// Use the mget method directly
|
|
218
218
|
const data = await client.mget ( ...fullKeys );
|
|
@@ -313,7 +313,7 @@ exports.multiDel = async ( keys ) => {
|
|
|
313
313
|
const client = await getClient ();
|
|
314
314
|
|
|
315
315
|
// Prepend the Redis prefix to each key if necessary
|
|
316
|
-
const fullKeys = ( !config?.redis?.prefix ||
|
|
316
|
+
const fullKeys = keys.map ( key => ( !config?.redis?.prefix || key.startsWith ( config?.redis?.prefix ) ) ? key : config?.redis?.prefix + key );
|
|
317
317
|
|
|
318
318
|
// Use the del method with multiple keys
|
|
319
319
|
return await client.del ( ...fullKeys );
|
package/src/s3.js
CHANGED
|
@@ -38,8 +38,9 @@
|
|
|
38
38
|
* and ensures the best CWVs performance.
|
|
39
39
|
*/
|
|
40
40
|
|
|
41
|
-
const { S3Client, HeadObjectCommand, GetObjectCommand, PutObjectCommand, DeleteObjectCommand, CopyObjectCommand,
|
|
41
|
+
const { S3Client, HeadObjectCommand, GetObjectCommand, PutObjectCommand, DeleteObjectCommand, CopyObjectCommand, ListObjectsV2Command } = require ( '@aws-sdk/client-s3' );
|
|
42
42
|
const fs = require ( 'fs' );
|
|
43
|
+
const path = require ( 'path' );
|
|
43
44
|
let config = {};
|
|
44
45
|
const configDirPath = `${ process.cwd ()}/config`;
|
|
45
46
|
if ( fs.existsSync ( configDirPath ) && fs.statSync ( configDirPath ).isDirectory () ) {
|
|
@@ -82,14 +83,16 @@ exports.exists = async ( key, bucket = config?.s3?.Bucket ) => {
|
|
|
82
83
|
};
|
|
83
84
|
|
|
84
85
|
/**
|
|
85
|
-
* Get an object from S3.
|
|
86
|
+
* Get an object from S3 and optionally download it to a file.
|
|
86
87
|
*
|
|
87
88
|
* @param {string} key - The object key.
|
|
88
89
|
* @param {string} [bucket=config?.s3?.Bucket] - The bucket name. Defaults to the configured bucket.
|
|
89
|
-
* @
|
|
90
|
-
* @
|
|
90
|
+
* @param {Object} [options] - Optional parameters, including targetFolder for file download.
|
|
91
|
+
* @param {string} [options.targetFolder] - If provided the requested object will be downloaded to this folder instead of being returned. The response will be the file path.
|
|
92
|
+
* @returns {Promise} A promise that resolves to the retrieved object or the path to the downloaded file.
|
|
93
|
+
* @description Retrieves an object from S3 based on the provided key and optionally downloads it to a specified folder.
|
|
91
94
|
*/
|
|
92
|
-
exports.get = async ( key, bucket = config?.s3?.Bucket ) => {
|
|
95
|
+
exports.get = async ( key, bucket = config?.s3?.Bucket, options = {} ) => {
|
|
93
96
|
try {
|
|
94
97
|
const command = new GetObjectCommand ( {
|
|
95
98
|
Bucket: bucket,
|
|
@@ -98,50 +101,70 @@ exports.get = async ( key, bucket = config?.s3?.Bucket ) => {
|
|
|
98
101
|
|
|
99
102
|
if ( config?.s3?.logs === 'verbose' )
|
|
100
103
|
log ( `S3 [GET]: Getting ${bucket}/${key}.` );
|
|
101
|
-
|
|
104
|
+
|
|
102
105
|
const response = await S3.send ( command );
|
|
103
|
-
let data = await streamToBuffer ( response.Body );
|
|
104
106
|
|
|
105
|
-
|
|
107
|
+
// If options.targetFolder is specified, download the file
|
|
108
|
+
if ( options.targetFolder ) {
|
|
109
|
+
const filePath = path.join ( options.targetFolder, key.replace ( /\//g, '_' ) );
|
|
110
|
+
const fileStream = fs.createWriteStream ( filePath );
|
|
111
|
+
response.Body.pipe ( fileStream );
|
|
112
|
+
await new Promise ( ( resolve, reject ) => {
|
|
113
|
+
fileStream.on ( 'finish', resolve );
|
|
114
|
+
fileStream.on ( 'error', reject );
|
|
115
|
+
} );
|
|
106
116
|
|
|
107
|
-
if ( config?.s3?.logs === 'verbose' )
|
|
108
|
-
log ( `S3 [GET]: ${key}
|
|
117
|
+
if ( config?.s3?.logs === 'outputs' || config?.s3?.logs === 'verbose' )
|
|
118
|
+
log ( `S3 [GET]: Downloaded ${key} to ${filePath}.` );
|
|
109
119
|
|
|
110
|
-
|
|
111
|
-
}
|
|
120
|
+
return filePath;
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
|
|
124
|
+
const response = await S3.send ( command );
|
|
125
|
+
let data = await streamToBuffer ( response.Body );
|
|
112
126
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
127
|
+
if ( response.ContentEncoding && response.ContentEncoding === 'gzip' ) {
|
|
128
|
+
|
|
129
|
+
if ( config?.s3?.logs === 'verbose' )
|
|
130
|
+
log ( `S3 [GET]: ${key} on ${bucket} was unzipped (was gzipped).` );
|
|
131
|
+
|
|
132
|
+
data = zlib.unzipSync ( data );
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if ( response.ContentType !== 'application/json' && !response.Metadata[ 'tmg-json' ] ) {
|
|
136
|
+
if ( config?.s3?.logs === 'output' )
|
|
137
|
+
log ( `S3 [GET]: Returned ${response.ContentType} from ${bucket}/${key}.` );
|
|
138
|
+
|
|
139
|
+
return data.toString ( 'utf8' );
|
|
140
|
+
}
|
|
116
141
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
Buffer.from (
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if ( config?.s3?.logs === 'verbose' )
|
|
138
|
-
log ( `S3 [GET]: ${key} on ${bucket} - JSON content was decrypted.` );
|
|
139
|
-
}
|
|
142
|
+
if ( ( response.ContentType === 'application/json' || response.Metadata[ 'tmg-json' ] ) && response.Metadata[ 'tmg-crypt' ] && response.Metadata[ 'tmg-crypt-vec' ] ) {
|
|
143
|
+
const key = await crypto.subtle.importKey (
|
|
144
|
+
'raw',
|
|
145
|
+
Buffer.from ( response.Metadata[ 'tmg-crypt' ], 'base64' ),
|
|
146
|
+
{ name: 'AES-CBC', length: 256 },
|
|
147
|
+
false,
|
|
148
|
+
[ 'decrypt' ]
|
|
149
|
+
);
|
|
150
|
+
const iv = Buffer.from ( response.Metadata[ 'tmg-crypt-vec' ], 'base64' );
|
|
151
|
+
const decryptedArrayBuffer = await crypto.subtle.decrypt (
|
|
152
|
+
{ name: 'AES-CBC', iv },
|
|
153
|
+
key,
|
|
154
|
+
Buffer.from ( data.toString (), 'base64' )
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
data = Buffer.from ( decryptedArrayBuffer ).toString ( 'utf8' );
|
|
158
|
+
|
|
159
|
+
if ( config?.s3?.logs === 'verbose' )
|
|
160
|
+
log ( `S3 [GET]: ${key} on ${bucket} - JSON content was decrypted.` );
|
|
161
|
+
}
|
|
140
162
|
|
|
141
|
-
|
|
142
|
-
|
|
163
|
+
if ( config?.s3?.logs === 'output' )
|
|
164
|
+
log ( `S3 [GET]: ${bucket}/${key} - JSON content was returned.` );
|
|
143
165
|
|
|
144
|
-
|
|
166
|
+
return JSON.parse ( data.toString ( 'utf8' ) );
|
|
167
|
+
}
|
|
145
168
|
}
|
|
146
169
|
catch ( error ) {
|
|
147
170
|
if ( error.Code === 'NoSuchKey' ) {
|