@pi-r/aws 0.5.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 +2 -1
- package/client/index.js +105 -32
- package/package.json +5 -5
- package/types/index.d.ts +2 -2
- package/upload/index.js +5 -11
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");
|
|
@@ -22,7 +22,7 @@ async function setCannedAcl(S3, Bucket, ACL, service = 'aws', recursive) {
|
|
|
22
22
|
}
|
|
23
23
|
else if (!recursive) {
|
|
24
24
|
if (err instanceof Error && err.code === 'OperationAborted') {
|
|
25
|
-
setTimeout(() => setCannedAcl.call(this, S3, Bucket, ACL, service, true), 60000 /* TIME.m */);
|
|
25
|
+
setTimeout(async () => setCannedAcl.call(this, S3, Bucket, ACL, service, true), 60000 /* TIME.m */);
|
|
26
26
|
this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, [`Grant ${ACL} (delayed)`, Bucket], err, { ...Cloud.LOG_CLOUD_DELAYED });
|
|
27
27
|
}
|
|
28
28
|
else {
|
|
@@ -158,11 +158,11 @@ function createDatabaseClient(credential) {
|
|
|
158
158
|
return new aws.DynamoDB.DocumentClient(options);
|
|
159
159
|
}
|
|
160
160
|
exports.createDatabaseClient = createDatabaseClient;
|
|
161
|
-
function createBucket(credential, Bucket, publicRead, service = 'aws', sdk = 'aws-sdk/clients/s3') {
|
|
161
|
+
async function createBucket(credential, Bucket, publicRead, service = 'aws', sdk = 'aws-sdk/clients/s3') {
|
|
162
162
|
return createBucketV2.call(this, credential, Bucket, publicRead ? 'public-read' : undefined, undefined, service, sdk);
|
|
163
163
|
}
|
|
164
164
|
exports.createBucket = createBucket;
|
|
165
|
-
function createBucketV2(credential, Bucket, ACL, options, service = 'aws', sdk = 'aws-sdk/clients/s3') {
|
|
165
|
+
async function createBucketV2(credential, Bucket, ACL, options, service = 'aws', sdk = 'aws-sdk/clients/s3') {
|
|
166
166
|
ACL = ACL === 1 ? 1 : checkBucketCannedACL(ACL);
|
|
167
167
|
const S3 = createStorageClient.call(this, credential, service, sdk);
|
|
168
168
|
return S3.headBucket({ Bucket }).promise()
|
|
@@ -172,7 +172,7 @@ function createBucketV2(credential, Bucket, ACL, options, service = 'aws', sdk =
|
|
|
172
172
|
}
|
|
173
173
|
return true;
|
|
174
174
|
})
|
|
175
|
-
.catch(() => {
|
|
175
|
+
.catch(async () => {
|
|
176
176
|
const input = { ...options, Bucket };
|
|
177
177
|
const region = credential.region;
|
|
178
178
|
if (region && (region !== 'us-east-1' || service !== 'aws')) {
|
|
@@ -202,7 +202,7 @@ function createBucketV2(credential, Bucket, ACL, options, service = 'aws', sdk =
|
|
|
202
202
|
});
|
|
203
203
|
}
|
|
204
204
|
exports.createBucketV2 = createBucketV2;
|
|
205
|
-
function setBucketPolicy(credential, Bucket, options, service = 'aws', sdk = 'aws-sdk/clients/s3') {
|
|
205
|
+
async function setBucketPolicy(credential, Bucket, options, service = 'aws', sdk = 'aws-sdk/clients/s3') {
|
|
206
206
|
const ibm = service === 'ibm';
|
|
207
207
|
const S3 = createStorageClient.call(this, credential, service, sdk);
|
|
208
208
|
options.Bucket = Bucket;
|
|
@@ -223,7 +223,7 @@ function setBucketPolicy(credential, Bucket, options, service = 'aws', sdk = 'aw
|
|
|
223
223
|
});
|
|
224
224
|
}
|
|
225
225
|
exports.setBucketPolicy = setBucketPolicy;
|
|
226
|
-
function setBucketWebsite(credential, Bucket, options, service = 'aws', sdk = 'aws-sdk/clients/s3') {
|
|
226
|
+
async function setBucketWebsite(credential, Bucket, options, service = 'aws', sdk = 'aws-sdk/clients/s3') {
|
|
227
227
|
const S3 = createStorageClient.call(this, credential, service, sdk);
|
|
228
228
|
const WebsiteConfiguration = {};
|
|
229
229
|
const { indexPage: Suffix, errorPage: Key } = options;
|
|
@@ -246,18 +246,18 @@ function setBucketWebsite(credential, Bucket, options, service = 'aws', sdk = 'a
|
|
|
246
246
|
});
|
|
247
247
|
}
|
|
248
248
|
exports.setBucketWebsite = setBucketWebsite;
|
|
249
|
-
function deleteObjects(credential, Bucket, service = 'aws', sdk = 'aws-sdk/clients/s3') {
|
|
249
|
+
async function deleteObjects(credential, Bucket, service = 'aws', sdk = 'aws-sdk/clients/s3') {
|
|
250
250
|
return deleteObjectsV2.call(this, credential, Bucket, true, service, sdk);
|
|
251
251
|
}
|
|
252
252
|
exports.deleteObjects = deleteObjects;
|
|
253
253
|
async function deleteObjectsV2(credential, Bucket, recursive = true, service = 'aws', sdk = 'aws-sdk/clients/s3') {
|
|
254
254
|
const S3 = createStorageClient.call(this, credential, service, sdk);
|
|
255
255
|
return S3.listObjects({ Bucket }).promise()
|
|
256
|
-
.then(({ Contents }) => {
|
|
256
|
+
.then(async ({ Contents }) => {
|
|
257
257
|
if (Contents?.length) {
|
|
258
258
|
let Objects = Contents.map(data => ({ Key: data.Key }));
|
|
259
259
|
if (!recursive) {
|
|
260
|
-
Objects = Objects.filter(value => value.Key.
|
|
260
|
+
Objects = Objects.filter(value => !value.Key.includes('/'));
|
|
261
261
|
}
|
|
262
262
|
return S3.deleteObjects({ Bucket, Delete: { Objects } }).promise()
|
|
263
263
|
.then(data => {
|
|
@@ -284,40 +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
|
-
|
|
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
|
-
|
|
299
|
-
|
|
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
|
-
if (ignoreCache
|
|
305
|
-
|
|
300
|
+
if (ignoreCache !== 1) {
|
|
301
|
+
cacheValue.renewCache = ignoreCache === 0;
|
|
302
|
+
return this.getQueryResult(service, credential, value, cacheValue);
|
|
306
303
|
}
|
|
307
|
-
cacheValue.renewCache = renewCache;
|
|
308
|
-
return this.getQueryResult(service, credential, value, cacheValue);
|
|
309
304
|
};
|
|
310
|
-
|
|
305
|
+
cacheValue.exclusiveOf = Array.isArray(ignoreCache) ? ignoreCache : undefined;
|
|
306
|
+
let rows, queryString = '';
|
|
311
307
|
if (key && (id || (0, types_1.isPlainObject)(key))) {
|
|
312
|
-
if (
|
|
313
|
-
|
|
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) : '');
|
|
314
313
|
if (!update && (rows = getCache(queryString))) {
|
|
315
314
|
result[i] = rows;
|
|
316
315
|
continue;
|
|
317
316
|
}
|
|
318
317
|
}
|
|
319
|
-
const Key = (0, types_1.isPlainObject)(key) ? key : { [key]: id };
|
|
320
|
-
const command = { TableName
|
|
318
|
+
const Key = (0, types_1.isPlainObject)(key) ? key : { [key]: parseAttributeValue(id) };
|
|
319
|
+
const command = { TableName, Key };
|
|
321
320
|
client = createClient();
|
|
322
321
|
if (update) {
|
|
323
322
|
await client.update({ ...command, ...update }).promise();
|
|
@@ -328,19 +327,63 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
328
327
|
}
|
|
329
328
|
}
|
|
330
329
|
else if ((0, types_1.isPlainObject)(query)) {
|
|
331
|
-
if (
|
|
332
|
-
|
|
333
|
-
continue;
|
|
330
|
+
if (TableName) {
|
|
331
|
+
query.TableName = TableName;
|
|
334
332
|
}
|
|
335
|
-
query.TableName = table;
|
|
336
333
|
if (limit > 0) {
|
|
337
334
|
query.Limit = limit;
|
|
338
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
|
+
}
|
|
339
343
|
const { Count, Items } = await createClient().query(query).promise();
|
|
340
344
|
if (Count && Items) {
|
|
341
345
|
rows = Items;
|
|
342
346
|
}
|
|
343
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
|
+
}
|
|
344
387
|
else {
|
|
345
388
|
throw (0, util_1.formatError)(item, "Missing database query" /* ERR_DB.QUERY */);
|
|
346
389
|
}
|
|
@@ -385,6 +428,36 @@ function writeMessageDefaultRetention(bucket, retention, service = 'aws') {
|
|
|
385
428
|
this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ["Bucket configured" /* VAL_CLOUD.CONFIGURE_BUCKET */ + ' (retention policy)', bucket], status.join(' '), { ...Cloud.LOG_CLOUD_COMMAND });
|
|
386
429
|
}
|
|
387
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;
|
|
388
461
|
const getBucketKey = (credential, Bucket, acl, service, sdk) => Module.asString(credential, true) + Bucket + '_' + (acl || '') + service + sdk;
|
|
389
462
|
exports.getBucketKey = getBucketKey;
|
|
390
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.
|
|
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.
|
|
25
|
-
"@e-mc/module": "^0.
|
|
26
|
-
"@e-mc/types": "^0.
|
|
27
|
-
"aws-sdk": "^2.
|
|
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");
|
|
@@ -26,7 +25,7 @@ function upload(credential, service = 'aws', sdk = 'aws-sdk/clients/s3') {
|
|
|
26
25
|
cleanup();
|
|
27
26
|
callback(err);
|
|
28
27
|
};
|
|
29
|
-
const addLog = (err) => err instanceof Error && this.addLog(this.statusType.WARN, err
|
|
28
|
+
const addLog = (err) => err instanceof Error && this.addLog(this.statusType.WARN, err, service, Bucket);
|
|
30
29
|
const configBucket = admin.configBucket;
|
|
31
30
|
if (!BUCKET_SESSION.has(service + Bucket)) {
|
|
32
31
|
const bucketAcl = admin.publicRead ? 'public-read' : admin.acl;
|
|
@@ -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
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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;
|