@pi-r/aws 0.6.0 → 0.6.1

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/client/index.d.ts CHANGED
@@ -6,7 +6,7 @@ import type { AWSDatabaseCredential, AWSDatabaseQuery, AWSStorageCredential, Buc
6
6
 
7
7
  import type { ConfigurationOptions } from 'aws-sdk/lib/core';
8
8
  import type { ServiceConfigurationOptions } from 'aws-sdk/lib/service';
9
- import type { DocumentClient } from 'aws-sdk/clients/dynamodb';
9
+ import type { AttributeValue, DocumentClient } from 'aws-sdk/clients/dynamodb';
10
10
  import type { DynamoDBClientConfig } from '@aws-sdk/client-dynamodb';
11
11
  import type { CreateBucketRequest } from 'aws-sdk/clients/s3';
12
12
 
@@ -32,6 +32,7 @@ declare namespace AWS {
32
32
  function setDatabaseEndpoint(config: ServiceConfigurationOptions | DynamoDBClientConfig): void;
33
33
  function checkBucketCannedACL(value: unknown): BucketCannedACL | undefined;
34
34
  function writeMessageDefaultRetention(this: IModule, bucket: string, retention: s3.DefaultRetention, service?: string): void;
35
+ function parseAttributeValue(value: unknown): AttributeValue;
35
36
  function getBucketKey(credential: unknown, Bucket: string, acl: string | undefined, service: string, sdk: string): string;
36
37
  function isNoSuchBucket(err: unknown): boolean;
37
38
  }
package/client/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isNoSuchBucket = exports.getBucketKey = exports.writeMessageDefaultRetention = exports.checkBucketCannedACL = exports.setDatabaseEndpoint = exports.executeBatchQuery = exports.executeQuery = exports.deleteObjectsV2 = exports.deleteObjects = exports.setBucketWebsite = exports.setBucketPolicy = exports.createBucketV2 = exports.createBucket = exports.createDatabaseClient = exports.createStorageClient = exports.validateDatabase = exports.validateStorage = exports.getPrivatePolicy = exports.getBucketPublicReadPolicy = exports.getPublicReadPolicy = exports.isDatabaseDefined = exports.isEnvDefined = exports.isAccessDefined = void 0;
3
+ exports.isNoSuchBucket = exports.getBucketKey = exports.parseAttributeValue = exports.writeMessageDefaultRetention = exports.checkBucketCannedACL = exports.setDatabaseEndpoint = exports.executeBatchQuery = exports.executeQuery = exports.deleteObjectsV2 = exports.deleteObjects = exports.setBucketWebsite = exports.setBucketPolicy = exports.createBucketV2 = exports.createBucket = exports.createDatabaseClient = exports.createStorageClient = exports.validateDatabase = exports.validateStorage = exports.getPrivatePolicy = exports.getBucketPublicReadPolicy = exports.getPublicReadPolicy = exports.isDatabaseDefined = exports.isEnvDefined = exports.isAccessDefined = void 0;
4
4
  const aws = require("aws-sdk");
5
5
  const types_1 = require("@e-mc/types");
6
6
  const util_1 = require("@e-mc/cloud/util");
@@ -284,39 +284,39 @@ async function executeQuery(credential, data, sessionKey) {
284
284
  }
285
285
  exports.executeQuery = executeQuery;
286
286
  async function executeBatchQuery(credential, batch, sessionKey) {
287
+ var _a;
287
288
  const length = batch.length;
288
289
  const result = new Array(length);
289
290
  const caching = length > 0 && this.hasCache(batch[0].service, sessionKey);
290
291
  const cacheValue = { value: this.valueOfKey(credential, 'cache'), sessionKey };
291
292
  let client;
292
- const createClient = () => {
293
- setDatabaseEndpoint(credential);
294
- return client || (client = createDatabaseClient.call(this, length === 1 ? credential : { ...credential }));
295
- };
293
+ const createClient = () => client || (client = createDatabaseClient.call(this, credential));
294
+ setDatabaseEndpoint(credential);
296
295
  for (let i = 0; i < length; ++i) {
297
296
  const item = batch[i];
298
- const { service, table, id = '', query, partitionKey, key = partitionKey, limit = 0, update, ignoreCache } = item;
299
- if (!table) {
300
- throw (0, util_1.formatError)(item, "Missing database table" /* ERR_DB.TABLE */);
301
- }
302
- const renewCache = ignoreCache === 0;
297
+ let { service, table: TableName, id, query, partitionKey, key = partitionKey, limit = 0, update, ignoreCache } = item;
298
+ const useCache = caching && ignoreCache !== true;
303
299
  const getCache = (value) => {
304
300
  if (ignoreCache !== 1) {
305
- cacheValue.renewCache = renewCache;
301
+ cacheValue.renewCache = ignoreCache === 0;
306
302
  return this.getQueryResult(service, credential, value, cacheValue);
307
303
  }
308
304
  };
309
- let rows, queryString = caching && ignoreCache !== true || ignoreCache === false || ignoreCache === 1 || renewCache ? table + '_' : '';
305
+ cacheValue.exclusiveOf = Array.isArray(ignoreCache) ? ignoreCache : undefined;
306
+ let rows, queryString = '';
310
307
  if (key && (id || (0, types_1.isPlainObject)(key))) {
311
- if (queryString) {
312
- queryString += Module.asString(key, true) + id;
308
+ if (!TableName) {
309
+ throw (0, util_1.formatError)(item, "Missing database table" /* ERR_DB.TABLE */);
310
+ }
311
+ if (useCache) {
312
+ queryString = TableName + '_' + Module.asString(key, true) + (id !== undefined ? '_' + Module.asString(id, true) : '');
313
313
  if (!update && (rows = getCache(queryString))) {
314
314
  result[i] = rows;
315
315
  continue;
316
316
  }
317
317
  }
318
- const Key = (0, types_1.isPlainObject)(key) ? key : { [key]: id };
319
- const command = { TableName: table, Key };
318
+ const Key = (0, types_1.isPlainObject)(key) ? key : { [key]: parseAttributeValue(id) };
319
+ const command = { TableName, Key };
320
320
  client = createClient();
321
321
  if (update) {
322
322
  await client.update({ ...command, ...update }).promise();
@@ -327,19 +327,63 @@ async function executeBatchQuery(credential, batch, sessionKey) {
327
327
  }
328
328
  }
329
329
  else if ((0, types_1.isPlainObject)(query)) {
330
- if (queryString && (rows = getCache(queryString += Module.asString(query, true) + limit))) {
331
- result[i] = rows;
332
- continue;
330
+ if (TableName) {
331
+ query.TableName = TableName;
333
332
  }
334
- query.TableName = table;
335
333
  if (limit > 0) {
336
334
  query.Limit = limit;
337
335
  }
336
+ if (!TableName) {
337
+ throw (0, util_1.formatError)(item, "Missing database table" /* ERR_DB.TABLE */);
338
+ }
339
+ if (useCache && (rows = getCache(queryString = Module.asString(query, true)))) {
340
+ result[i] = rows;
341
+ continue;
342
+ }
338
343
  const { Count, Items } = await createClient().query(query).promise();
339
344
  if (Count && Items) {
340
345
  rows = Items;
341
346
  }
342
347
  }
348
+ else if ((0, types_1.isArray)(query)) {
349
+ let params = (item.params || {});
350
+ if (!(0, types_1.isPlainObject)(params.RequestItems)) {
351
+ params.RequestItems = {};
352
+ }
353
+ TableName || (TableName = Object.keys(params.RequestItems)[0]);
354
+ if (!TableName) {
355
+ throw (0, util_1.formatError)(item, "Missing database table" /* ERR_DB.TABLE */);
356
+ }
357
+ // @ts-ignore
358
+ const Item = (_a = params.RequestItems)[TableName] || (_a[TableName] = {});
359
+ Item.Keys = query;
360
+ params = { RequestItems: { [TableName]: Item } };
361
+ if (useCache && (rows = getCache(queryString = Module.asString(params, true)))) {
362
+ result[i] = rows;
363
+ continue;
364
+ }
365
+ const { Responses } = await createClient().batchGet(params).promise();
366
+ if (Responses) {
367
+ rows = Responses[TableName];
368
+ }
369
+ }
370
+ else if (TableName) {
371
+ let params = item.params;
372
+ if ((0, types_1.isPlainObject)(params)) {
373
+ params.TableName = TableName;
374
+ }
375
+ else {
376
+ params = { TableName };
377
+ }
378
+ if (useCache && (rows = getCache(queryString = Module.asString(params, true)))) {
379
+ result[i] = rows;
380
+ continue;
381
+ }
382
+ const { Count, Items } = await createClient().scan(params).promise();
383
+ if (Count && Items) {
384
+ rows = Items;
385
+ }
386
+ }
343
387
  else {
344
388
  throw (0, util_1.formatError)(item, "Missing database query" /* ERR_DB.QUERY */);
345
389
  }
@@ -384,6 +428,36 @@ function writeMessageDefaultRetention(bucket, retention, service = 'aws') {
384
428
  this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ["Bucket configured" /* VAL_CLOUD.CONFIGURE_BUCKET */ + ' (retention policy)', bucket], status.join(' '), { ...Cloud.LOG_CLOUD_COMMAND });
385
429
  }
386
430
  exports.writeMessageDefaultRetention = writeMessageDefaultRetention;
431
+ function parseAttributeValue(value) {
432
+ switch (typeof value) {
433
+ case 'string':
434
+ return { S: value };
435
+ case 'number':
436
+ return { N: value.toString() };
437
+ case 'boolean':
438
+ return { BOOL: value };
439
+ case 'object':
440
+ if (value !== null) {
441
+ if ('S' in value || 'N' in value || 'BOOL' in value || 'B' in value || 'SS' in value || 'NS' in value || 'BS' in value || 'L' in value || 'M' in value || 'NULL' in value) {
442
+ return value;
443
+ }
444
+ if (Buffer.isBuffer(value)) {
445
+ return { B: value.toString('base64') };
446
+ }
447
+ if (Array.isArray(value)) {
448
+ return value.every(item => typeof item === 'string') ? { SS: value } : value.every(item => typeof item === 'number') ? { NS: value.map((item) => item.toString()) } : value.every(item => Buffer.isBuffer(item)) ? { BS: value.map((item) => item.toString('base64')) } : { L: value.map(item => parseAttributeValue(item)) };
449
+ }
450
+ const M = {};
451
+ for (const attr in value) {
452
+ M[attr] = parseAttributeValue(value[attr]);
453
+ }
454
+ return { M };
455
+ }
456
+ break;
457
+ }
458
+ return { NULL: true };
459
+ }
460
+ exports.parseAttributeValue = parseAttributeValue;
387
461
  const getBucketKey = (credential, Bucket, acl, service, sdk) => Module.asString(credential, true) + Bucket + '_' + (acl || '') + service + sdk;
388
462
  exports.getBucketKey = getBucketKey;
389
463
  const isNoSuchBucket = (err) => err instanceof Error && err.code === 'NoSuchBucket';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-r/aws",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "AWS V2 cloud functions for E-mc.",
5
5
  "main": "client/index.js",
6
6
  "types": "client/index.d.ts",
@@ -21,9 +21,9 @@
21
21
  "license": "MIT",
22
22
  "homepage": "https://github.com/anpham6/pi-r#readme",
23
23
  "dependencies": {
24
- "@e-mc/cloud": "^0.8.0",
25
- "@e-mc/module": "^0.8.0",
26
- "@e-mc/types": "^0.8.0",
27
- "aws-sdk": "^2.1524.0"
24
+ "@e-mc/cloud": "^0.8.1",
25
+ "@e-mc/module": "^0.8.1",
26
+ "@e-mc/types": "^0.8.1",
27
+ "aws-sdk": "^2.1531.0"
28
28
  }
29
29
  }
package/types/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import type { CloudDatabase } from '@e-mc/types/lib/cloud';
3
3
 
4
4
  import type { ConfigurationOptions } from 'aws-sdk/lib/core';
5
5
  import type { ServiceConfigurationOptions } from 'aws-sdk/lib/service';
6
- import type { Key, QueryInput, UpdateItemInput } from 'aws-sdk/clients/dynamodb';
6
+ import type { Key, BatchGetItemInput, QueryInput, ScanInput, UpdateItemInput } from 'aws-sdk/clients/dynamodb';
7
7
  import type { PutBucketAclRequest, PutBucketPolicyRequest, PutPublicAccessBlockRequest } from 'aws-sdk/clients/s3';
8
8
 
9
9
  export type BucketCannedACL = "authenticated-read" | "private" | "public-read" | "public-read-write";
@@ -15,7 +15,7 @@ export interface AWSStorageCredential extends ConfigurationOptions {
15
15
  fromPath?: string;
16
16
  }
17
17
 
18
- export interface AWSDatabaseQuery extends CloudDatabase<QueryInput, PlainObject, UpdateItemInput> {
18
+ export interface AWSDatabaseQuery extends CloudDatabase<QueryInput | Key[], PlainObject, UpdateItemInput, BatchGetItemInput | ScanInput> {
19
19
  key?: string | Key;
20
20
  partitionKey?: string | Key;
21
21
  }
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 util_1 = require("@e-mc/cloud/util");
6
5
  const types_1 = require("@e-mc/types");
7
6
  const Module = require("@e-mc/module");
@@ -81,15 +80,10 @@ function upload(credential, service = 'aws', sdk = 'aws-sdk/clients/s3') {
81
80
  const Body = [data.buffer];
82
81
  const ContentType = [contentType];
83
82
  if (fileGroup) {
84
- for (const [content, ext, localFile] of fileGroup) {
85
- try {
86
- Body.push(typeof content === 'string' ? fs.readFileSync(content) : content);
87
- Key.push(ext === '.map' && localFile ? path.basename(localFile) : filename + ext);
88
- }
89
- catch (err) {
90
- addLog(err);
91
- }
92
- }
83
+ const [key, body, type] = (0, util_1.createKeyAndBody)(filename, fileGroup, addLog);
84
+ Key.push(...key);
85
+ Body.push(...body);
86
+ ContentType.push(...type);
93
87
  }
94
88
  for (let i = 0; i < Key.length; ++i) {
95
89
  const first = i === 0;