@pi-r/aws-v3 0.6.0 → 0.6.2

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/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  ### @pi-r/aws-v3
2
2
 
3
+ https://e-mc.readthedocs.io/en/latest/cloud/aws-v3.html
4
+
3
5
  ### LICENSE
4
6
 
5
7
  MIT
package/client/index.js CHANGED
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.executeBatchQuery = exports.executeQuery = exports.deleteObjectsV2 = exports.deleteObjects = exports.setBucketWebsite = exports.setBucketPolicy = exports.createBucketV2 = exports.createBucket = exports.validateDatabase = exports.validateStorage = exports.createDatabaseClient = exports.createStorageClient = void 0;
4
4
  const Lib = require("@aws-sdk/lib-dynamodb");
5
5
  const Client = require("@aws-sdk/client-dynamodb");
6
+ const Providers = require("@aws-sdk/credential-providers");
6
7
  const aws_1 = require("@pi-r/aws");
7
8
  const util_1 = require("@e-mc/cloud/util");
8
9
  const types_1 = require("@e-mc/types");
@@ -14,11 +15,14 @@ async function setCannedAcl(S3, client, Bucket, ACL, service = 'aws-v3', recursi
14
15
  case 1:
15
16
  Policy = (0, aws_1.getBucketPublicReadPolicy)(Bucket);
16
17
  break;
17
- case 'private':
18
- Policy = (0, aws_1.getPrivatePolicy)(Bucket);
18
+ case 'public-read-write':
19
+ Policy = (0, aws_1.getPublicReadPolicy)(Bucket, false, true);
20
+ break;
21
+ case 'authenticated-read':
22
+ Policy = (0, aws_1.getPublicReadPolicy)(Bucket, true);
19
23
  break;
20
24
  default:
21
- Policy = (0, aws_1.getPublicReadPolicy)(Bucket, ACL === 'authenticated-read', ACL === 'public-read-write');
25
+ Policy = (0, aws_1.getPrivatePolicy)(Bucket);
22
26
  break;
23
27
  }
24
28
  return client.send(new S3.PutBucketPolicyCommand({ Bucket, Policy }))
@@ -54,16 +58,77 @@ function sanitizeCredentials(credential) {
54
58
  }
55
59
  return result;
56
60
  }
61
+ function fromProvider(credential) {
62
+ const from = credential.provider;
63
+ let credentials = credential.credentials;
64
+ if ((0, types_1.isPlainObject)(from)) {
65
+ if (from.http) {
66
+ credentials = Providers.fromHttp((0, types_1.isPlainObject)(from.http) ? from.http : {});
67
+ }
68
+ else if ((0, types_1.isPlainObject)(from.ini)) {
69
+ credentials = Providers.fromIni(from.ini);
70
+ }
71
+ else if ((0, types_1.isPlainObject)(from.cognitoIdentity)) {
72
+ credentials = Providers.fromCognitoIdentity(from.cognitoIdentity);
73
+ }
74
+ else if ((0, types_1.isPlainObject)(from.cognitoIdentityPool)) {
75
+ credentials = Providers.fromCognitoIdentityPool(from.cognitoIdentityPool);
76
+ }
77
+ else if ((0, types_1.isPlainObject)(from.temporaryCredentials)) {
78
+ credentials = Providers.fromTemporaryCredentials(from.temporaryCredentials);
79
+ }
80
+ else if ((0, types_1.isPlainObject)(from.webToken)) {
81
+ credentials = Providers.fromWebToken(from.webToken);
82
+ }
83
+ else if ((0, types_1.isPlainObject)(from.containerMetadata)) {
84
+ credentials = Providers.fromContainerMetadata(from.containerMetadata);
85
+ }
86
+ else if ((0, types_1.isPlainObject)(from.instanceMetadata)) {
87
+ credentials = Providers.fromInstanceMetadata(from.instanceMetadata);
88
+ }
89
+ else if ((0, types_1.isPlainObject)(from.process)) {
90
+ credentials = Providers.fromProcess(from.process);
91
+ }
92
+ else if ((0, types_1.isPlainObject)(from.tokenFile)) {
93
+ credentials = Providers.fromTokenFile(from.tokenFile);
94
+ }
95
+ else if ((0, types_1.isPlainObject)(from.sso)) {
96
+ credentials = Providers.fromSSO(from.sso);
97
+ }
98
+ else if (from.env && (0, aws_1.isEnvDefined)()) {
99
+ credentials = Providers.fromEnv();
100
+ }
101
+ else if (from.ini && (0, aws_1.isSharedCredentialsDefined)()) {
102
+ credentials = Providers.fromIni();
103
+ }
104
+ if ((0, types_1.isPlainObject)(credentials)) {
105
+ if (from.nodeProviderChain) {
106
+ credentials = Providers.fromNodeProviderChain((0, types_1.isPlainObject)(from.nodeProviderChain) ? { ...credentials, ...from.nodeProviderChain } : credentials);
107
+ }
108
+ credential.credentials = credentials;
109
+ }
110
+ delete credential.provider;
111
+ }
112
+ if ((0, types_1.isPlainObject)(credentials)) {
113
+ let expiration = credentials.expiration;
114
+ if (expiration) {
115
+ if ((0, types_1.isString)(expiration)) {
116
+ expiration = new Date(expiration);
117
+ credentials.expiration = expiration;
118
+ }
119
+ if (!(expiration instanceof Date && !isNaN(expiration.getTime()))) {
120
+ delete credentials.expiration;
121
+ }
122
+ }
123
+ }
124
+ return credential;
125
+ }
57
126
  const isNoSuchBucket = (err) => err instanceof Error && err.name === 'NoSuchBucket';
58
127
  function createStorageClient(credential, service = 'aws-v3', sdk = '@aws-sdk/client-s3') {
59
128
  try {
60
129
  sanitizeCredentials(credential);
61
- const expiration = credential.credentials?.expiration;
62
- if (expiration && !(expiration instanceof Date)) {
63
- delete credential.expiration;
64
- }
65
130
  const AWS = require(sdk);
66
- return [new AWS.S3Client(credential), AWS];
131
+ return [new AWS.S3Client(fromProvider(credential)), AWS];
67
132
  }
68
133
  catch (err) {
69
134
  this.checkPackage(err, sdk.split('/')[0], { passThrough: true });
@@ -72,18 +137,17 @@ function createStorageClient(credential, service = 'aws-v3', sdk = '@aws-sdk/cli
72
137
  }
73
138
  exports.createStorageClient = createStorageClient;
74
139
  function createDatabaseClient(credential) {
75
- return [Lib.DynamoDBDocumentClient.from(new Client.DynamoDBClient(credential), credential.translateConfig), Lib];
140
+ return [Lib.DynamoDBDocumentClient.from(new Client.DynamoDBClient(fromProvider(credential)), credential.translateConfig), Lib];
76
141
  }
77
142
  exports.createDatabaseClient = createDatabaseClient;
78
143
  function validateStorage(credential) {
79
144
  const credentials = sanitizeCredentials(credential);
80
145
  const profile = credential.profile;
81
- if (profile || !credentials && process.env.AWS_SDK_LOAD_CONFIG === '1') {
82
- const { fromIni } = require('@aws-sdk/credential-provider-ini');
83
- credential.credentials = fromIni({ profile });
146
+ if (profile || !credentials && !credential.provider && (0, aws_1.isSharedCredentialsDefined)()) {
147
+ credential.credentials = Providers.fromIni({ profile });
84
148
  return true;
85
149
  }
86
- return !!credentials && (typeof credentials === 'function' || (0, aws_1.isAccessDefined)(credentials) || (0, aws_1.isEnvDefined)());
150
+ return !!credentials && (typeof credentials === 'function' || (0, aws_1.isAccessDefined)(credentials)) || (0, types_1.isPlainObject)(credential.provider) || (0, aws_1.isEnvDefined)();
87
151
  }
88
152
  exports.validateStorage = validateStorage;
89
153
  function validateDatabase(credential, data) {
@@ -107,7 +171,7 @@ async function createBucketV2(credential, Bucket, ACL, options, service = 'aws-v
107
171
  .catch(async () => {
108
172
  const input = { ...options, Bucket };
109
173
  const region = credential.region;
110
- if (typeof region === 'string' && region !== 'us-east-1') {
174
+ if ((0, types_1.isString)(region) && region !== 'us-east-1') {
111
175
  input.CreateBucketConfiguration || (input.CreateBucketConfiguration = { LocationConstraint: region });
112
176
  }
113
177
  return client.send(new AWS.CreateBucketCommand(input))
@@ -213,40 +277,42 @@ async function executeQuery(credential, data, sessionKey) {
213
277
  }
214
278
  exports.executeQuery = executeQuery;
215
279
  async function executeBatchQuery(credential, batch, sessionKey) {
280
+ var _a;
216
281
  const length = batch.length;
217
282
  const result = new Array(length);
218
283
  const caching = length > 0 && this.hasCache(batch[0].service, sessionKey);
219
284
  const cacheValue = { value: this.valueOfKey(credential, 'cache'), sessionKey };
220
285
  let client;
221
- const createClient = () => client || (client = createDatabaseClient.call(this, length === 1 ? credential : { ...credential }));
286
+ const createClient = () => client || (client = createDatabaseClient.call(this, credential));
222
287
  const closeClient = () => client?.[0].destroy();
288
+ (0, aws_1.setDatabaseEndpoint)(credential);
223
289
  for (let i = 0; i < length; ++i) {
224
290
  const item = batch[i];
225
- const { service, table, id = '', query, partitionKey, key = partitionKey, limit = 0, update, ignoreCache } = item;
226
- if (!table) {
227
- closeClient();
228
- throw (0, util_1.formatError)(item, "Missing database table" /* ERR_DB.TABLE */);
229
- }
230
- (0, aws_1.setDatabaseEndpoint)(credential);
231
- const renewCache = ignoreCache === 0;
291
+ let { service, table: TableName, id, query, partitionKey, key = partitionKey, limit = 0, update, ignoreCache } = item;
292
+ const useCache = caching && ignoreCache !== true;
232
293
  const getCache = (value) => {
233
294
  if (ignoreCache !== 1) {
234
- cacheValue.renewCache = renewCache;
295
+ cacheValue.renewCache = ignoreCache === 0;
235
296
  return this.getQueryResult(service, credential, value, cacheValue);
236
297
  }
237
298
  };
238
- let rows, queryString = caching && ignoreCache !== true || ignoreCache === false || ignoreCache === 1 || renewCache ? table + '_' : '';
299
+ cacheValue.exclusiveOf = Array.isArray(ignoreCache) ? ignoreCache : undefined;
300
+ let rows, queryString = '';
239
301
  if (key && (id || (0, types_1.isPlainObject)(key))) {
240
- if (queryString) {
241
- queryString += Module.asString(key, true) + id;
302
+ if (!TableName) {
303
+ closeClient();
304
+ throw (0, util_1.formatError)(item, "Missing database table" /* ERR_DB.TABLE */);
305
+ }
306
+ if (useCache) {
307
+ queryString = TableName + '_' + Module.asString(key, true) + (id !== undefined ? '_' + Module.asString(id, true) : '');
242
308
  if (!update && (rows = getCache(queryString))) {
243
309
  result[i] = rows;
244
310
  continue;
245
311
  }
246
312
  }
247
313
  const [db, AWS] = createClient();
248
- const Key = (0, types_1.isPlainObject)(key) ? key : { [key]: id };
249
- const command = { TableName: table, Key };
314
+ const Key = (0, types_1.isPlainObject)(key) ? key : { [key]: (0, aws_1.parseAttributeValue)(id) };
315
+ const command = { TableName, Key };
250
316
  if (update) {
251
317
  await db.send(new AWS.UpdateCommand({ ...command, ...update }));
252
318
  }
@@ -256,18 +322,65 @@ async function executeBatchQuery(credential, batch, sessionKey) {
256
322
  }
257
323
  }
258
324
  else if ((0, types_1.isPlainObject)(query)) {
259
- if (queryString && (rows = getCache(queryString += Module.asString(query, true) + limit))) {
260
- result[i] = rows;
261
- continue;
325
+ if (TableName) {
326
+ query.TableName = TableName;
327
+ }
328
+ if (!query.TableName) {
329
+ closeClient();
330
+ throw (0, util_1.formatError)(item, "Missing database table" /* ERR_DB.TABLE */);
262
331
  }
263
- query.TableName = table;
264
332
  if (limit > 0) {
265
333
  query.Limit = limit;
266
334
  }
335
+ if (useCache && (rows = getCache(queryString = Module.asString(query, true)))) {
336
+ result[i] = rows;
337
+ continue;
338
+ }
339
+ const [db, AWS] = createClient();
340
+ const { Count, Items } = await db.send(new AWS.QueryCommand(query));
341
+ if (Count && Items) {
342
+ rows = Items;
343
+ }
344
+ }
345
+ else if ((0, types_1.isArray)(query)) {
346
+ let params = (item.params || {});
347
+ if (!(0, types_1.isPlainObject)(params.RequestItems)) {
348
+ params.RequestItems = {};
349
+ }
350
+ TableName || (TableName = Object.keys(params.RequestItems)[0]);
351
+ if (!TableName) {
352
+ throw (0, util_1.formatError)(item, "Missing database table" /* ERR_DB.TABLE */);
353
+ }
354
+ // @ts-ignore
355
+ const Item = (_a = params.RequestItems)[TableName] || (_a[TableName] = {});
356
+ Item.Keys = query;
357
+ params = { RequestItems: { [TableName]: Item } };
358
+ if (useCache && (rows = getCache(queryString = Module.asString(params, true)))) {
359
+ result[i] = rows;
360
+ continue;
361
+ }
362
+ const [db, AWS] = createClient();
363
+ const { Responses } = await db.send(new AWS.BatchGetCommand(params));
364
+ if (Responses) {
365
+ rows = Responses[TableName];
366
+ }
367
+ }
368
+ else if (TableName) {
369
+ let params = item.params;
370
+ if ((0, types_1.isPlainObject)(params)) {
371
+ params.TableName = TableName;
372
+ }
373
+ else {
374
+ params = { TableName };
375
+ }
376
+ if (useCache && (rows = getCache(queryString = Module.asString(params, true)))) {
377
+ result[i] = rows;
378
+ continue;
379
+ }
267
380
  const [db, AWS] = createClient();
268
- const output = await db.send(new AWS.QueryCommand(query));
269
- if (output.Count && output.Items) {
270
- rows = output.Items;
381
+ const { Count, Items } = await db.send(new AWS.ScanCommand(params));
382
+ if (Count && Items) {
383
+ rows = Items;
271
384
  }
272
385
  }
273
386
  else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-r/aws-v3",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "AWS V3 cloud functions for E-mc.",
5
5
  "main": "client/index.js",
6
6
  "publishConfig": {
@@ -20,12 +20,13 @@
20
20
  "license": "MIT",
21
21
  "homepage": "https://github.com/anpham6/pi-r#readme",
22
22
  "dependencies": {
23
- "@e-mc/cloud": "^0.8.0",
24
- "@e-mc/module": "^0.8.0",
25
- "@e-mc/types": "^0.8.0",
26
- "@pi-r/aws": "^0.6.0",
27
- "@aws-sdk/client-dynamodb": "^3.478.0",
28
- "@aws-sdk/client-s3": "^3.478.0",
29
- "@aws-sdk/lib-dynamodb": "^3.478.0"
23
+ "@e-mc/cloud": "^0.8.2",
24
+ "@e-mc/module": "^0.8.2",
25
+ "@e-mc/types": "^0.8.2",
26
+ "@pi-r/aws": "^0.6.2",
27
+ "@aws-sdk/client-dynamodb": "^3.501.0",
28
+ "@aws-sdk/client-s3": "^3.501.0",
29
+ "@aws-sdk/credential-providers": "^3.501.0",
30
+ "@aws-sdk/lib-dynamodb": "^3.501.0"
30
31
  }
31
32
  }
package/upload/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const path = require("path");
4
- const fs = require("fs");
5
4
  const stream = require("stream");
6
5
  const util_1 = require("@e-mc/cloud/util");
7
6
  const aws_1 = require("@pi-r/aws");
@@ -80,15 +79,10 @@ function upload(credential, service = 'aws-v3', sdk = '@aws-sdk/client-s3') {
80
79
  const Body = [data.buffer];
81
80
  const ContentType = [contentType];
82
81
  if (fileGroup) {
83
- for (const [content, ext, localFile] of fileGroup) {
84
- try {
85
- Body.push(typeof content === 'string' ? fs.readFileSync(content) : content);
86
- Key.push(ext === '.map' && localFile ? path.basename(localFile) : filename + ext);
87
- }
88
- catch (err) {
89
- addLog(err);
90
- }
91
- }
82
+ const [key, body, type] = (0, util_1.createKeyAndBody)(filename, fileGroup, addLog);
83
+ Key.push(...key);
84
+ Body.push(...body);
85
+ ContentType.push(...type);
92
86
  }
93
87
  for (let i = 0; i < Key.length; ++i) {
94
88
  const first = i === 0;
@@ -140,35 +134,37 @@ function upload(credential, service = 'aws-v3', sdk = '@aws-sdk/client-s3') {
140
134
  client.send(new AWS.PutObjectCommand(params), { abortSignal: this.signal })
141
135
  .then(() => {
142
136
  const url = endpoint ? Module.joinPath(endpoint, objectKey) : Module.joinPath(`https://${Bucket}.s3.${!credential.region || credential.region === 'us-east-1' ? 'us-east-1.' : ''}amazonaws.com`, objectKey);
143
- if (first) {
144
- if ((0, types_1.isPlainObject)(tags)) {
145
- const TagSet = [];
146
- for (const name in tags) {
147
- TagSet.push({ Key: name, Value: tags[name] });
148
- }
149
- client.send(new AWS.PutObjectTaggingCommand({ Bucket, Key: params.Key, ExpectedBucketOwner: params.ExpectedBucketOwner, Tagging: { TagSet }, RequestPayer: params.RequestPayer }), error => {
150
- if (!error) {
151
- this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ["Tags created" /* VAL_CLOUD.CREATE_TAG */, Bucket], params.Key, { ...Cloud.LOG_CLOUD_COMMAND });
152
- }
153
- else {
154
- addLog(error);
155
- }
156
- });
157
- }
158
- else if (tags === false) {
159
- client.send(new AWS.DeleteObjectTaggingCommand({ Bucket, Key: params.Key, ExpectedBucketOwner: params.ExpectedBucketOwner }), error => {
160
- if (!error) {
161
- this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ["Tags deleted" /* VAL_CLOUD.DELETE_TAG */, Bucket], params.Key, { ...Cloud.LOG_CLOUD_COMMAND });
162
- }
163
- else {
164
- addLog(error);
165
- }
166
- });
137
+ this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, "Upload success" /* VAL_CLOUD.UPLOAD_FILE */, url, { ...Cloud.LOG_CLOUD_UPLOAD });
138
+ if (!first) {
139
+ return;
140
+ }
141
+ let length = -1;
142
+ if ((0, types_1.isPlainObject)(tags) && (length = Object.keys(tags).length) > 0) {
143
+ const TagSet = [];
144
+ for (const name in tags) {
145
+ TagSet.push({ Key: name, Value: tags[name] });
167
146
  }
168
- cleanup();
169
- callback(null, url);
147
+ client.send(new AWS.PutObjectTaggingCommand({ Bucket, Key: params.Key, ExpectedBucketOwner: params.ExpectedBucketOwner, Tagging: { TagSet }, RequestPayer: params.RequestPayer }), error => {
148
+ if (!error) {
149
+ this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ["Tags created" /* VAL_CLOUD.CREATE_TAG */, Bucket], params.Key, { ...Cloud.LOG_CLOUD_COMMAND });
150
+ }
151
+ else {
152
+ addLog(error);
153
+ }
154
+ });
170
155
  }
171
- this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, "Upload success" /* VAL_CLOUD.UPLOAD_FILE */, url, { ...Cloud.LOG_CLOUD_UPLOAD });
156
+ else if (tags === false || length === 0) {
157
+ client.send(new AWS.DeleteObjectTaggingCommand({ Bucket, Key: params.Key, ExpectedBucketOwner: params.ExpectedBucketOwner }), error => {
158
+ if (!error) {
159
+ this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ["Tags deleted" /* VAL_CLOUD.DELETE_TAG */, Bucket], params.Key, { ...Cloud.LOG_CLOUD_COMMAND });
160
+ }
161
+ else {
162
+ addLog(error);
163
+ }
164
+ });
165
+ }
166
+ cleanup();
167
+ callback(null, url);
172
168
  })
173
169
  .catch(err => {
174
170
  if (first) {