@pi-r/aws 0.2.2 → 0.5.0

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
@@ -31,6 +31,7 @@ declare namespace AWS {
31
31
  function executeBatchQuery(this: ICloud, credential: AWSDatabaseCredential, batch: AWSDatabaseQuery[], sessionKey?: string): Promise<BatchQueryResult>;
32
32
  function setDatabaseEndpoint(config: ServiceConfigurationOptions | DynamoDBClientConfig): void;
33
33
  function checkBucketCannedACL(value: unknown): BucketCannedACL | undefined;
34
+ function writeMessageDefaultRetention(this: IModule, bucket: string, retention: s3.DefaultRetention, service?: string): void;
34
35
  function getBucketKey(credential: unknown, Bucket: string, acl: string | undefined, service: string, sdk: string): string;
35
36
  function isNoSuchBucket(err: unknown): boolean;
36
37
  }
package/client/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isNoSuchBucket = exports.getBucketKey = 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.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
+ const aws = require("aws-sdk");
4
5
  const types_1 = require("@e-mc/types");
5
6
  const util_1 = require("@e-mc/cloud/util");
6
7
  const Module = require("@e-mc/module");
@@ -123,20 +124,18 @@ exports.validateDatabase = validateDatabase;
123
124
  function createStorageClient(credential, service = 'aws', sdk = 'aws-sdk/clients/s3') {
124
125
  try {
125
126
  if (service === 'aws') {
126
- const S3 = require('aws-sdk/clients/s3');
127
- if (credential.fromPath) {
128
- const client = new S3();
129
- client.config.loadFromPath(credential.fromPath);
127
+ const { profile, fromPath } = credential;
128
+ if (fromPath) {
129
+ const client = new aws.S3();
130
+ client.config.loadFromPath(fromPath);
130
131
  return client;
131
132
  }
132
- if (credential.profile || process.env.AWS_SDK_LOAD_CONFIG === '1' && !isAccessDefined(credential) && !isEnvDefined()) {
133
- const { SharedIniFileCredentials } = require('aws-sdk');
134
- credential = new SharedIniFileCredentials({ profile: credential.profile });
133
+ if (profile || process.env.AWS_SDK_LOAD_CONFIG === '1' && !isAccessDefined(credential) && !isEnvDefined()) {
134
+ credential = new aws.SharedIniFileCredentials({ profile });
135
135
  }
136
- return new S3(credential);
136
+ return new aws.S3(credential);
137
137
  }
138
- const S3 = require(sdk);
139
- return new S3(credential);
138
+ return new (require(sdk))(credential);
140
139
  }
141
140
  catch (err) {
142
141
  this.checkPackage(err, sdk.split('/')[0], { passThrough: true });
@@ -145,26 +144,18 @@ function createStorageClient(credential, service = 'aws', sdk = 'aws-sdk/clients
145
144
  }
146
145
  exports.createStorageClient = createStorageClient;
147
146
  function createDatabaseClient(credential) {
148
- try {
149
- let options;
150
- if (credential.fromPath) {
151
- const AWS = require('aws-sdk');
152
- AWS.config.loadFromPath(credential.fromPath);
153
- }
154
- else if (credential.profile || process.env.AWS_SDK_LOAD_CONFIG === '1' && !isAccessDefined(credential) && !isEnvDefined()) {
155
- const { SharedIniFileCredentials } = require('aws-sdk');
156
- options = new SharedIniFileCredentials({ profile: credential.profile });
157
- }
158
- else {
159
- options = credential;
160
- }
161
- const DynamoDB = require('aws-sdk/clients/dynamodb');
162
- return new DynamoDB.DocumentClient(options);
147
+ const { profile, fromPath } = credential;
148
+ let options;
149
+ if (fromPath) {
150
+ aws.config.loadFromPath(fromPath);
163
151
  }
164
- catch (err) {
165
- this.checkPackage(err, 'aws-sdk', { passThrough: true });
166
- throw err;
152
+ else if (profile || process.env.AWS_SDK_LOAD_CONFIG === '1' && !isAccessDefined(credential) && !isEnvDefined()) {
153
+ options = new aws.SharedIniFileCredentials({ profile });
167
154
  }
155
+ else {
156
+ options = credential;
157
+ }
158
+ return new aws.DynamoDB.DocumentClient(options);
168
159
  }
169
160
  exports.createDatabaseClient = createDatabaseClient;
170
161
  function createBucket(credential, Bucket, publicRead, service = 'aws', sdk = 'aws-sdk/clients/s3') {
@@ -184,8 +175,8 @@ function createBucketV2(credential, Bucket, ACL, options, service = 'aws', sdk =
184
175
  .catch(() => {
185
176
  const input = { ...options, Bucket };
186
177
  const region = credential.region;
187
- if (!input.CreateBucketConfiguration && typeof region === 'string' && (region !== 'us-east-1' || service !== 'aws')) {
188
- input.CreateBucketConfiguration = { LocationConstraint: region };
178
+ if (region && (region !== 'us-east-1' || service !== 'aws')) {
179
+ input.CreateBucketConfiguration || (input.CreateBucketConfiguration = { LocationConstraint: region });
189
180
  }
190
181
  return S3.createBucket(input).promise()
191
182
  .then(async () => {
@@ -212,13 +203,14 @@ function createBucketV2(credential, Bucket, ACL, options, service = 'aws', sdk =
212
203
  }
213
204
  exports.createBucketV2 = createBucketV2;
214
205
  function setBucketPolicy(credential, Bucket, options, service = 'aws', sdk = 'aws-sdk/clients/s3') {
206
+ const ibm = service === 'ibm';
215
207
  const S3 = createStorageClient.call(this, credential, service, sdk);
216
208
  options.Bucket = Bucket;
217
- if (service === 'ibm' && 'ACL' in options && options.ACL === 'authenticated-read') {
209
+ if (ibm && 'ACL' in options && options.ACL === 'authenticated-read') {
218
210
  options.AccessControlPolicy = ACP_AUTHENTICATEDREAD;
219
211
  delete options.ACL;
220
212
  }
221
- return ('Policy' in options && (0, types_1.isString)(options.Policy) && service !== 'ibm' ? S3.putBucketPolicy(options) : S3.putBucketAcl(options)).promise()
213
+ return ('PublicAccessBlockConfiguration' in options ? S3.putPublicAccessBlock(options) : 'Policy' in options && (0, types_1.isString)(options.Policy) && !ibm ? S3.putBucketPolicy(options) : S3.putBucketAcl(options)).promise()
222
214
  .then(() => {
223
215
  this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ["Bucket policy configured" /* VAL_CLOUD.POLICY_BUCKET */, Bucket], '', { ...Cloud.LOG_CLOUD_COMMAND });
224
216
  return true;
@@ -234,11 +226,12 @@ exports.setBucketPolicy = setBucketPolicy;
234
226
  function setBucketWebsite(credential, Bucket, options, service = 'aws', sdk = 'aws-sdk/clients/s3') {
235
227
  const S3 = createStorageClient.call(this, credential, service, sdk);
236
228
  const WebsiteConfiguration = {};
237
- if ((0, types_1.isString)(options.indexPage)) {
238
- WebsiteConfiguration.IndexDocument = { Suffix: options.indexPage };
229
+ const { indexPage: Suffix, errorPage: Key } = options;
230
+ if ((0, types_1.isString)(Suffix)) {
231
+ WebsiteConfiguration.IndexDocument = { Suffix };
239
232
  }
240
- if ((0, types_1.isString)(options.errorPage)) {
241
- WebsiteConfiguration.ErrorDocument = { Key: options.errorPage };
233
+ if ((0, types_1.isString)(Key)) {
234
+ WebsiteConfiguration.ErrorDocument = { Key };
242
235
  }
243
236
  return S3.putBucketWebsite({ Bucket, WebsiteConfiguration }).promise()
244
237
  .then(() => {
@@ -268,8 +261,9 @@ async function deleteObjectsV2(credential, Bucket, recursive = true, service = '
268
261
  }
269
262
  return S3.deleteObjects({ Bucket, Delete: { Objects } }).promise()
270
263
  .then(data => {
271
- if ((0, types_1.isArray)(data.Deleted)) {
272
- const files = data.Deleted.length + ' files';
264
+ const Deleted = data.Deleted;
265
+ if ((0, types_1.isArray)(Deleted)) {
266
+ const files = Deleted.length + ' files';
273
267
  this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ["Bucket emptied" /* VAL_CLOUD.EMPTY_BUCKET */ + ` (${recursive ? 'recursive' : files})`, Bucket], recursive ? files : '', { ...Cloud.LOG_CLOUD_COMMAND });
274
268
  }
275
269
  })
@@ -328,9 +322,9 @@ async function executeBatchQuery(credential, batch, sessionKey) {
328
322
  if (update) {
329
323
  await client.update({ ...command, ...update }).promise();
330
324
  }
331
- const output = await client.get(command).promise();
332
- if (output.Item) {
333
- rows = [output.Item];
325
+ const Item = (await client.get(command).promise()).Item;
326
+ if (Item) {
327
+ rows = [Item];
334
328
  }
335
329
  }
336
330
  else if ((0, types_1.isPlainObject)(query)) {
@@ -342,9 +336,9 @@ async function executeBatchQuery(credential, batch, sessionKey) {
342
336
  if (limit > 0) {
343
337
  query.Limit = limit;
344
338
  }
345
- const output = await createClient().query(query).promise();
346
- if (output.Count && output.Items) {
347
- rows = output.Items;
339
+ const { Count, Items } = await createClient().query(query).promise();
340
+ if (Count && Items) {
341
+ rows = Items;
348
342
  }
349
343
  }
350
344
  else {
@@ -356,9 +350,10 @@ async function executeBatchQuery(credential, batch, sessionKey) {
356
350
  }
357
351
  exports.executeBatchQuery = executeBatchQuery;
358
352
  function setDatabaseEndpoint(config) {
359
- config.endpoint || (config.endpoint = `https://dynamodb.${(0, types_1.isString)(config.region) ? config.region : process.env.AWS_DEFAULT_REGION || 'us-east-1'}.amazonaws.com`);
360
- if (!config.region && (0, types_1.isString)(config.endpoint)) {
361
- const region = (/dynamodb\.([^.]+)\./i.exec(config.endpoint)?.[1] || process.env.AWS_DEFAULT_REGION)?.toLowerCase();
353
+ let region = config.region;
354
+ config.endpoint || (config.endpoint = `https://dynamodb.${(0, types_1.isString)(region) ? region : process.env.AWS_DEFAULT_REGION || 'us-east-1'}.amazonaws.com`);
355
+ if (!region && (0, types_1.isString)(config.endpoint)) {
356
+ region = (/dynamodb\.([^.]+)\./i.exec(config.endpoint)?.[1] || process.env.AWS_DEFAULT_REGION)?.toLowerCase();
362
357
  if (region && region !== 'us-east-1') {
363
358
  config.region = region;
364
359
  }
@@ -375,6 +370,21 @@ function checkBucketCannedACL(value) {
375
370
  }
376
371
  }
377
372
  exports.checkBucketCannedACL = checkBucketCannedACL;
373
+ function writeMessageDefaultRetention(bucket, retention, service = 'aws') {
374
+ const { Years = 0, Days = 0, Mode } = retention;
375
+ const status = [];
376
+ if (Years > 0) {
377
+ status.push(Years.toString() + 'Y');
378
+ }
379
+ if (Days > 0) {
380
+ status.push(Days.toString() + 'D');
381
+ }
382
+ if (Mode) {
383
+ status.push(status.length ? `(${Mode})` : Mode);
384
+ }
385
+ this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ["Bucket configured" /* VAL_CLOUD.CONFIGURE_BUCKET */ + ' (retention policy)', bucket], status.join(' '), { ...Cloud.LOG_CLOUD_COMMAND });
386
+ }
387
+ exports.writeMessageDefaultRetention = writeMessageDefaultRetention;
378
388
  const getBucketKey = (credential, Bucket, acl, service, sdk) => Module.asString(credential, true) + Bucket + '_' + (acl || '') + service + sdk;
379
389
  exports.getBucketKey = getBucketKey;
380
390
  const isNoSuchBucket = (err) => err instanceof Error && err.code === 'NoSuchBucket';
package/download/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const client_1 = require("../client");
4
3
  const types_1 = require("@e-mc/types");
5
4
  const Module = require("@e-mc/module");
6
5
  const Cloud = require("@e-mc/cloud");
6
+ const client_1 = require("../client");
7
7
  function download(credential, service = 'aws', sdk = 'aws-sdk/clients/s3') {
8
8
  const s3 = client_1.createStorageClient.call(this, credential, service, sdk);
9
9
  return (data, callback) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-r/aws",
3
- "version": "0.2.2",
3
+ "version": "0.5.0",
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.5.3",
25
- "@e-mc/module": "^0.5.3",
26
- "@e-mc/types": "^0.5.3",
27
- "aws-sdk": "^2.1380.0"
24
+ "@e-mc/cloud": "^0.7.0",
25
+ "@e-mc/module": "^0.7.0",
26
+ "@e-mc/types": "^0.7.0",
27
+ "aws-sdk": "^2.1514.0"
28
28
  }
29
29
  }
package/types/index.d.ts CHANGED
@@ -4,11 +4,11 @@ import type { CloudDatabase } from '@e-mc/types/lib/cloud';
4
4
  import type { ConfigurationOptions } from 'aws-sdk/lib/core';
5
5
  import type { ServiceConfigurationOptions } from 'aws-sdk/lib/service';
6
6
  import type { Key, QueryInput, UpdateItemInput } from 'aws-sdk/clients/dynamodb';
7
- import type { PutBucketAclRequest, PutBucketPolicyRequest } from 'aws-sdk/clients/s3';
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";
10
10
  export type ObjectCannedACL = BucketCannedACL | "aws-exec-read" | "bucket-owner-full-control" | "bucket-owner-read";
11
- export type ConfigureBucketOptions = PutBucketAclRequest | PutBucketPolicyRequest;
11
+ export type ConfigureBucketOptions = PutBucketAclRequest | PutBucketPolicyRequest | PutPublicAccessBlockRequest;
12
12
 
13
13
  export interface AWSStorageCredential extends ConfigurationOptions {
14
14
  profile?: string;
package/upload/index.js CHANGED
@@ -2,11 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const path = require("path");
4
4
  const fs = require("fs");
5
- const client_1 = require("../client");
6
5
  const util_1 = require("@e-mc/cloud/util");
7
6
  const types_1 = require("@e-mc/types");
8
7
  const Module = require("@e-mc/module");
9
8
  const Cloud = require("@e-mc/cloud");
9
+ const client_1 = require("../client");
10
10
  const BUCKET_SESSION = new Set();
11
11
  const BUCKET_RESPONSE = {};
12
12
  function upload(credential, service = 'aws', sdk = 'aws-sdk/clients/s3') {
@@ -14,7 +14,7 @@ function upload(credential, service = 'aws', sdk = 'aws-sdk/clients/s3') {
14
14
  return async (data, callback) => {
15
15
  var _a;
16
16
  const { bucket: Bucket, localUri } = data;
17
- const { pathname = '', fileGroup, contentType, metadata, endpoint, active, publicRead, acl, admin = {}, overwrite, options } = data.upload;
17
+ const { pathname = '', fileGroup, contentType, metadata, tags, endpoint, active, publicRead, acl, admin = {}, overwrite, options } = data.upload;
18
18
  let filename = data.upload.filename || path.basename(localUri), bucketKey;
19
19
  const cleanup = () => {
20
20
  BUCKET_SESSION.delete(service + Bucket);
@@ -26,15 +26,30 @@ function upload(credential, service = 'aws', sdk = 'aws-sdk/clients/s3') {
26
26
  cleanup();
27
27
  callback(err);
28
28
  };
29
+ const addLog = (err) => err instanceof Error && this.addLog(this.statusType.WARN, err.message, service + ': ' + Bucket);
30
+ const configBucket = admin.configBucket;
29
31
  if (!BUCKET_SESSION.has(service + Bucket)) {
30
32
  const bucketAcl = admin.publicRead ? 'public-read' : admin.acl;
31
- const response = BUCKET_RESPONSE[_a = bucketKey = (0, client_1.getBucketKey)(credential, Bucket, bucketAcl, service, sdk)] || (BUCKET_RESPONSE[_a] = client_1.createBucketV2.call(this, credential, Bucket, bucketAcl, admin.configBucket?.create, service, sdk));
33
+ const response = BUCKET_RESPONSE[_a = bucketKey = (0, client_1.getBucketKey)(credential, Bucket, bucketAcl, service, sdk)] || (BUCKET_RESPONSE[_a] = client_1.createBucketV2.call(this, credential, Bucket, bucketAcl, configBucket?.create, service, sdk));
32
34
  if (!await response) {
33
35
  errorResponse(null);
34
36
  return;
35
37
  }
36
38
  BUCKET_SESSION.add(service + Bucket);
37
39
  }
40
+ if (service !== 'oci') {
41
+ const DefaultRetention = configBucket?.retentionPolicy;
42
+ if ((0, types_1.isPlainObject)(DefaultRetention)) {
43
+ s3.putObjectLockConfiguration({ Bucket, ObjectLockConfiguration: { ObjectLockEnabled: 'Enabled', Rule: { DefaultRetention } }, ExpectedBucketOwner: options?.ExpectedBucketOwner, RequestPayer: options?.RequestPayer }, err => {
44
+ if (!err) {
45
+ client_1.writeMessageDefaultRetention.call(this, Bucket, DefaultRetention, service);
46
+ }
47
+ else {
48
+ addLog(err);
49
+ }
50
+ });
51
+ }
52
+ }
38
53
  if (!overwrite) {
39
54
  const current = filename;
40
55
  const next = (0, util_1.generateFilename)(filename);
@@ -65,7 +80,6 @@ function upload(credential, service = 'aws', sdk = 'aws-sdk/clients/s3') {
65
80
  const Key = [filename];
66
81
  const Body = [data.buffer];
67
82
  const ContentType = [contentType];
68
- const addLog = (err) => err instanceof Error && this.addLog(this.statusType.WARN, err.message, service + ': ' + Bucket);
69
83
  if (fileGroup) {
70
84
  for (const [content, ext, localFile] of fileGroup) {
71
85
  try {
@@ -115,6 +129,32 @@ function upload(credential, service = 'aws', sdk = 'aws-sdk/clients/s3') {
115
129
  const url = endpoint ? Module.joinPath(endpoint, result.Key) : result.Location;
116
130
  this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, "Upload success" /* VAL_CLOUD.UPLOAD_FILE */, url, { ...Cloud.LOG_CLOUD_UPLOAD });
117
131
  if (first) {
132
+ if (service !== 'oci') {
133
+ if ((0, types_1.isPlainObject)(tags)) {
134
+ const TagSet = [];
135
+ for (const name in tags) {
136
+ TagSet.push({ Key: name, Value: tags[name] });
137
+ }
138
+ s3.putObjectTagging({ Bucket, Key: result.Key, Tagging: { TagSet }, ExpectedBucketOwner: params.ExpectedBucketOwner, RequestPayer: params.RequestPayer }, error => {
139
+ if (!error) {
140
+ this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ["Tags created" /* VAL_CLOUD.CREATE_TAG */, Bucket], result.Key, { ...Cloud.LOG_CLOUD_COMMAND });
141
+ }
142
+ else {
143
+ addLog(error);
144
+ }
145
+ });
146
+ }
147
+ else if (tags === false) {
148
+ s3.deleteObjectTagging({ Bucket, Key: result.Key, ExpectedBucketOwner: params.ExpectedBucketOwner }, error => {
149
+ if (!error) {
150
+ this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ["Tags deleted" /* VAL_CLOUD.DELETE_TAG */, Bucket], result.Key, { ...Cloud.LOG_CLOUD_COMMAND });
151
+ }
152
+ else {
153
+ addLog(error);
154
+ }
155
+ });
156
+ }
157
+ }
118
158
  cleanup();
119
159
  callback(null, url);
120
160
  }