@pi-r/aws 0.6.6 → 0.7.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/README.md +3 -6
- package/client/index.d.ts +4 -17
- package/client/index.js +86 -156
- package/download/index.js +9 -8
- package/package.json +6 -5
- package/types/index.d.ts +7 -7
- package/upload/index.js +119 -50
package/README.md
CHANGED
package/client/index.d.ts
CHANGED
|
@@ -2,23 +2,14 @@ import type { ICloud, IModule } from '@e-mc/types/lib';
|
|
|
2
2
|
import type { BucketWebsiteOptions, CloudDatabase } from '@e-mc/types/lib/cloud';
|
|
3
3
|
import type { BatchQueryResult, QueryResult } from '@e-mc/types/lib/db';
|
|
4
4
|
|
|
5
|
-
import type {
|
|
5
|
+
import type { BucketCannedACL } from '@pi-r/aws-lib';
|
|
6
|
+
|
|
7
|
+
import type { AWSDatabaseCredential, AWSDatabaseQuery, AWSStorageCredential, ConfigureBucketOptions } from '../types';
|
|
6
8
|
|
|
7
|
-
import type { ConfigurationOptions } from 'aws-sdk/lib/core';
|
|
8
|
-
import type { ServiceConfigurationOptions } from 'aws-sdk/lib/service';
|
|
9
9
|
import type { AttributeValue, DocumentClient } from 'aws-sdk/clients/dynamodb';
|
|
10
|
-
import type {
|
|
11
|
-
import type { CreateBucketRequest, DefaultRetention } from 'aws-sdk/clients/s3';
|
|
10
|
+
import type { CreateBucketRequest } from 'aws-sdk/clients/s3';
|
|
12
11
|
|
|
13
12
|
declare namespace AWS {
|
|
14
|
-
function isAccessDefined(credential: Pick<ConfigurationOptions, "accessKeyId" | "secretAccessKey" | "sessionToken">): boolean;
|
|
15
|
-
function isEnvDefined(): boolean;
|
|
16
|
-
function isSharedCredentialsDefined(): boolean;
|
|
17
|
-
function isProviderChainDefined(): boolean;
|
|
18
|
-
function isDatabaseDefined(credential: AWSDatabaseCredential, data: CloudDatabase): boolean;
|
|
19
|
-
function getPublicReadPolicy(bucket: string, authenticated?: boolean, write?: boolean): string;
|
|
20
|
-
function getBucketPublicReadPolicy(bucket: string): string;
|
|
21
|
-
function getPrivatePolicy(bucket: string): string;
|
|
22
13
|
function validateStorage(credential: AWSStorageCredential): boolean;
|
|
23
14
|
function validateDatabase(credential: AWSDatabaseCredential, data: CloudDatabase): boolean;
|
|
24
15
|
function createStorageClient(this: IModule, credential: AWSStorageCredential, service?: string, sdk?: string): boolean;
|
|
@@ -31,11 +22,7 @@ declare namespace AWS {
|
|
|
31
22
|
function deleteObjectsV2(this: IModule, credential: AWSStorageCredential, Bucket: string, recursive?: boolean, service?: string, sdk?: string): Promise<void>;
|
|
32
23
|
function executeQuery(this: ICloud, credential: AWSDatabaseCredential, data: AWSDatabaseQuery, sessionKey?: string): Promise<QueryResult>;
|
|
33
24
|
function executeBatchQuery(this: ICloud, credential: AWSDatabaseCredential, batch: AWSDatabaseQuery[], sessionKey?: string): Promise<BatchQueryResult>;
|
|
34
|
-
function setDatabaseEndpoint(config: ServiceConfigurationOptions | DynamoDBClientConfig): void;
|
|
35
|
-
function checkBucketCannedACL(value: unknown): BucketCannedACL | undefined;
|
|
36
|
-
function writeMessageDefaultRetention(this: IModule, bucket: string, retention: DefaultRetention, service?: string): void;
|
|
37
25
|
function parseAttributeValue(value: unknown): AttributeValue;
|
|
38
|
-
function getBucketKey(credential: unknown, Bucket: string, acl: string | undefined, service: string, sdk: string): string;
|
|
39
26
|
function isNoSuchBucket(err: unknown): boolean;
|
|
40
27
|
}
|
|
41
28
|
|
package/client/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
exports.
|
|
2
|
+
exports.CLOUD_UPLOAD_CHUNK = exports.CLOUD_UPLOAD_STREAM = exports.isNoSuchBucket = exports.parseAttributeValue = exports.executeBatchQuery = exports.executeQuery = exports.deleteObjectsV2 = exports.deleteObjects = exports.setBucketWebsite = exports.setBucketTagging = exports.setBucketPolicy = exports.createBucketV2 = exports.createBucket = exports.createDatabaseClient = exports.createStorageClient = exports.validateDatabase = exports.validateStorage = void 0;
|
|
3
3
|
const aws = require("aws-sdk");
|
|
4
|
-
const types_1 = require("@e-mc/types");
|
|
5
|
-
const util_1 = require("@e-mc/cloud/util");
|
|
6
|
-
const Module = require("@e-mc/module");
|
|
7
4
|
const Cloud = require("@e-mc/cloud");
|
|
5
|
+
const util_1 = require("@e-mc/cloud/util");
|
|
6
|
+
const types_1 = require("@e-mc/types");
|
|
7
|
+
const aws_lib_1 = require("@pi-r/aws-lib");
|
|
8
8
|
const ACP_AUTHENTICATEDREAD = {
|
|
9
9
|
Grants: [{
|
|
10
10
|
Grantee: { Type: 'Group', URI: 'http://acs.amazonaws.com/groups/global/AuthenticatedUsers' },
|
|
11
11
|
Permission: 'READ'
|
|
12
12
|
}]
|
|
13
13
|
};
|
|
14
|
-
async function setCannedAcl(S3, Bucket, ACL, service =
|
|
15
|
-
if (service ===
|
|
14
|
+
async function setCannedAcl(S3, Bucket, ACL, service = "aws", recursive) {
|
|
15
|
+
if (service === "oci") {
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
18
18
|
const callback = (err) => {
|
|
@@ -30,114 +30,51 @@ async function setCannedAcl(S3, Bucket, ACL, service = 'aws', recursive) {
|
|
|
30
30
|
}
|
|
31
31
|
};
|
|
32
32
|
let promise;
|
|
33
|
-
if (service ===
|
|
33
|
+
if (service === "ibm") {
|
|
34
34
|
if (ACL === 1) {
|
|
35
|
-
ACL =
|
|
35
|
+
ACL = "public-read";
|
|
36
36
|
}
|
|
37
|
-
promise = S3.putBucketAcl(ACL ===
|
|
37
|
+
promise = S3.putBucketAcl(ACL === "authenticated-read" ? { Bucket, AccessControlPolicy: ACP_AUTHENTICATEDREAD } : { Bucket, ACL }).promise();
|
|
38
38
|
}
|
|
39
39
|
else {
|
|
40
40
|
switch (ACL) {
|
|
41
41
|
case 1:
|
|
42
|
-
promise = S3.putBucketPolicy({ Bucket, Policy: getBucketPublicReadPolicy(Bucket) }).promise();
|
|
42
|
+
promise = S3.putBucketPolicy({ Bucket, Policy: (0, aws_lib_1.getBucketPublicReadPolicy)(Bucket) }).promise();
|
|
43
43
|
break;
|
|
44
|
-
case
|
|
45
|
-
promise = S3.putBucketPolicy({ Bucket, Policy: getPublicReadPolicy(Bucket) }).promise();
|
|
44
|
+
case "public-read":
|
|
45
|
+
promise = S3.putBucketPolicy({ Bucket, Policy: (0, aws_lib_1.getPublicReadPolicy)(Bucket) }).promise();
|
|
46
46
|
break;
|
|
47
|
-
case
|
|
48
|
-
promise = S3.putBucketPolicy({ Bucket, Policy: getPublicReadPolicy(Bucket, false, true) }).promise();
|
|
47
|
+
case "public-read-write":
|
|
48
|
+
promise = S3.putBucketPolicy({ Bucket, Policy: (0, aws_lib_1.getPublicReadPolicy)(Bucket, false, true) }).promise();
|
|
49
49
|
break;
|
|
50
|
-
case
|
|
51
|
-
promise = S3.putBucketPolicy({ Bucket, Policy: getPublicReadPolicy(Bucket, true) }).promise();
|
|
50
|
+
case "authenticated-read":
|
|
51
|
+
promise = S3.putBucketPolicy({ Bucket, Policy: (0, aws_lib_1.getPublicReadPolicy)(Bucket, true) }).promise();
|
|
52
52
|
break;
|
|
53
53
|
default:
|
|
54
|
-
promise = S3.putBucketPolicy({ Bucket, Policy: getPrivatePolicy(Bucket) }).promise();
|
|
54
|
+
promise = S3.putBucketPolicy({ Bucket, Policy: (0, aws_lib_1.getPrivatePolicy)(Bucket) }).promise();
|
|
55
55
|
break;
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
-
return promise.then(() => callback(null)).catch(err => callback(err));
|
|
59
|
-
}
|
|
60
|
-
function isAccessDefined(credential) {
|
|
61
|
-
return !!(credential.accessKeyId && credential.secretAccessKey || credential.sessionToken);
|
|
62
|
-
}
|
|
63
|
-
exports.isAccessDefined = isAccessDefined;
|
|
64
|
-
function isSharedCredentialsDefined() {
|
|
65
|
-
return !!process.env.AWS_SDK_LOAD_CONFIG;
|
|
66
|
-
}
|
|
67
|
-
exports.isSharedCredentialsDefined = isSharedCredentialsDefined;
|
|
68
|
-
function isEnvDefined() {
|
|
69
|
-
return !!(process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY);
|
|
70
|
-
}
|
|
71
|
-
exports.isEnvDefined = isEnvDefined;
|
|
72
|
-
function isProviderChainDefined() {
|
|
73
|
-
return isSharedCredentialsDefined() || !!(process.env.AWS_WEB_IDENTITY_TOKEN_FILE || process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI || process.env.AWS_CONTAINER_CREDENTIALS_FULL_URI);
|
|
74
|
-
}
|
|
75
|
-
exports.isProviderChainDefined = isProviderChainDefined;
|
|
76
|
-
function isDatabaseDefined(credential, data) {
|
|
77
|
-
return !!(data.table && (credential.region || credential.endpoint || process.env.AWS_DEFAULT_REGION || process.env.AWS_REGION));
|
|
78
|
-
}
|
|
79
|
-
exports.isDatabaseDefined = isDatabaseDefined;
|
|
80
|
-
function getPublicReadPolicy(bucket, authenticated, write) {
|
|
81
|
-
const Action = ["s3:GetObject", "s3:GetObjectVersion"];
|
|
82
|
-
if (write) {
|
|
83
|
-
Action.push("s3:PutObject", "s3:DeleteObjectVersion");
|
|
84
|
-
}
|
|
85
|
-
return JSON.stringify({
|
|
86
|
-
"Version": "2012-10-17",
|
|
87
|
-
"Statement": [{
|
|
88
|
-
"Sid": (authenticated ? "AuthenticatedRead" : "PublicRead") + (write ? "Write" : ""),
|
|
89
|
-
"Effect": "Allow",
|
|
90
|
-
"Principal": authenticated ? { "AWS": "*" } : "*",
|
|
91
|
-
"Action": Action,
|
|
92
|
-
"Resource": [`arn:aws:s3:::${bucket}/*`]
|
|
93
|
-
}]
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
exports.getPublicReadPolicy = getPublicReadPolicy;
|
|
97
|
-
function getBucketPublicReadPolicy(bucket) {
|
|
98
|
-
return JSON.stringify({
|
|
99
|
-
"Version": "2012-10-17",
|
|
100
|
-
"Statement": [{
|
|
101
|
-
"Sid": "BucketPublicRead",
|
|
102
|
-
"Effect": "Allow",
|
|
103
|
-
"Principal": "*",
|
|
104
|
-
"Action": ["s3:ListBucket", "s3:ListBucketVersions", "s3:ListBucketMultipartUploads"],
|
|
105
|
-
"Resource": [`arn:aws:s3:::${bucket}`]
|
|
106
|
-
}]
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
exports.getBucketPublicReadPolicy = getBucketPublicReadPolicy;
|
|
110
|
-
function getPrivatePolicy(bucket) {
|
|
111
|
-
return JSON.stringify({
|
|
112
|
-
"Version": "2012-10-17",
|
|
113
|
-
"Statement": [{
|
|
114
|
-
"Sid": "Private",
|
|
115
|
-
"Effect": "Deny",
|
|
116
|
-
"Principal": "*",
|
|
117
|
-
"Action": "*",
|
|
118
|
-
"Resource": [`arn:aws:s3:::${bucket}`, `arn:aws:s3:::${bucket}/*`]
|
|
119
|
-
}]
|
|
120
|
-
});
|
|
58
|
+
return promise.then(() => callback(null)).catch((err) => callback(err));
|
|
121
59
|
}
|
|
122
|
-
exports.getPrivatePolicy = getPrivatePolicy;
|
|
123
60
|
function validateStorage(credential) {
|
|
124
|
-
return !!(isAccessDefined(credential) || isEnvDefined() || credential.fromPath || credential.profile || isProviderChainDefined());
|
|
61
|
+
return !!((0, aws_lib_1.isAccessDefined)(credential) || (0, aws_lib_1.isEnvDefined)() || credential.fromPath || credential.profile || (0, aws_lib_1.isProviderChainDefined)());
|
|
125
62
|
}
|
|
126
63
|
exports.validateStorage = validateStorage;
|
|
127
64
|
function validateDatabase(credential, data) {
|
|
128
|
-
return isDatabaseDefined(credential, data) && validateStorage(credential);
|
|
65
|
+
return (0, aws_lib_1.isDatabaseDefined)(credential, data) && validateStorage(credential);
|
|
129
66
|
}
|
|
130
67
|
exports.validateDatabase = validateDatabase;
|
|
131
|
-
function createStorageClient(credential, service =
|
|
68
|
+
function createStorageClient(credential, service = "aws", sdk = "aws-sdk/clients/s3") {
|
|
132
69
|
try {
|
|
133
|
-
if (service ===
|
|
134
|
-
const {
|
|
135
|
-
if (fromPath) {
|
|
70
|
+
if (service === "aws") {
|
|
71
|
+
const { fromPath, profile } = credential;
|
|
72
|
+
if (fromPath && this.canRead(fromPath, { ownPermissionOnly: true })) {
|
|
136
73
|
const client = new aws.S3();
|
|
137
74
|
client.config.loadFromPath(fromPath);
|
|
138
75
|
return client;
|
|
139
76
|
}
|
|
140
|
-
if (profile || isSharedCredentialsDefined() && !isAccessDefined(credential) && !isEnvDefined()) {
|
|
77
|
+
if (profile || (0, aws_lib_1.isSharedCredentialsDefined)() && !(0, aws_lib_1.isAccessDefined)(credential) && !(0, aws_lib_1.isEnvDefined)()) {
|
|
141
78
|
credential = new aws.SharedIniFileCredentials({ profile });
|
|
142
79
|
}
|
|
143
80
|
return new aws.S3(credential);
|
|
@@ -154,23 +91,30 @@ function createDatabaseClient(credential) {
|
|
|
154
91
|
const { profile, fromPath } = credential;
|
|
155
92
|
let options;
|
|
156
93
|
if (fromPath) {
|
|
157
|
-
|
|
94
|
+
try {
|
|
95
|
+
options = JSON.parse(this.readFile(fromPath, { encoding: 'utf-8', ownPermissionOnly: true, cache: false }));
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
}
|
|
158
99
|
}
|
|
159
|
-
else if (profile || isSharedCredentialsDefined() && !isAccessDefined(credential) && !isEnvDefined()) {
|
|
100
|
+
else if (profile || (0, aws_lib_1.isSharedCredentialsDefined)() && !(0, aws_lib_1.isAccessDefined)(credential) && !(0, aws_lib_1.isEnvDefined)()) {
|
|
160
101
|
options = new aws.SharedIniFileCredentials({ profile });
|
|
161
102
|
}
|
|
162
103
|
else {
|
|
163
104
|
options = credential;
|
|
164
105
|
}
|
|
106
|
+
if (options?.endpoint && !options.region) {
|
|
107
|
+
(0, aws_lib_1.setDatabaseEndpoint)(options);
|
|
108
|
+
}
|
|
165
109
|
return new aws.DynamoDB.DocumentClient(options);
|
|
166
110
|
}
|
|
167
111
|
exports.createDatabaseClient = createDatabaseClient;
|
|
168
|
-
async function createBucket(credential, Bucket, publicRead, service =
|
|
169
|
-
return createBucketV2.call(this, credential, Bucket, publicRead ?
|
|
112
|
+
async function createBucket(credential, Bucket, publicRead, service = "aws", sdk = "aws-sdk/clients/s3") {
|
|
113
|
+
return createBucketV2.call(this, credential, Bucket, publicRead ? "public-read" : undefined, undefined, service, sdk);
|
|
170
114
|
}
|
|
171
115
|
exports.createBucket = createBucket;
|
|
172
|
-
async function createBucketV2(credential, Bucket, ACL, options, service =
|
|
173
|
-
ACL = ACL === 1 ? 1 : checkBucketCannedACL(ACL);
|
|
116
|
+
async function createBucketV2(credential, Bucket, ACL, options, service = "aws", sdk = "aws-sdk/clients/s3") {
|
|
117
|
+
ACL = ACL === 1 ? 1 : (0, aws_lib_1.checkBucketCannedACL)(ACL);
|
|
174
118
|
const S3 = createStorageClient.call(this, credential, service, sdk);
|
|
175
119
|
return S3.headBucket({ Bucket }).promise()
|
|
176
120
|
.then(async () => {
|
|
@@ -182,8 +126,8 @@ async function createBucketV2(credential, Bucket, ACL, options, service = 'aws',
|
|
|
182
126
|
.catch(async () => {
|
|
183
127
|
const input = { ...options, Bucket };
|
|
184
128
|
const region = credential.region;
|
|
185
|
-
if (region && (region !==
|
|
186
|
-
input.CreateBucketConfiguration
|
|
129
|
+
if (region && (region !== "us-east-1" || service !== "aws")) {
|
|
130
|
+
input.CreateBucketConfiguration ||= { LocationConstraint: region };
|
|
187
131
|
}
|
|
188
132
|
return S3.createBucket(input).promise()
|
|
189
133
|
.then(async () => {
|
|
@@ -209,11 +153,11 @@ async function createBucketV2(credential, Bucket, ACL, options, service = 'aws',
|
|
|
209
153
|
});
|
|
210
154
|
}
|
|
211
155
|
exports.createBucketV2 = createBucketV2;
|
|
212
|
-
async function setBucketPolicy(credential, Bucket, options, service =
|
|
213
|
-
const ibm = service ===
|
|
156
|
+
async function setBucketPolicy(credential, Bucket, options, service = "aws", sdk = "aws-sdk/clients/s3") {
|
|
157
|
+
const ibm = service === "ibm";
|
|
214
158
|
const S3 = createStorageClient.call(this, credential, service, sdk);
|
|
215
159
|
options.Bucket = Bucket;
|
|
216
|
-
if (ibm && 'ACL' in options && options.ACL ===
|
|
160
|
+
if (ibm && 'ACL' in options && options.ACL === "authenticated-read") {
|
|
217
161
|
options.AccessControlPolicy = ACP_AUTHENTICATEDREAD;
|
|
218
162
|
delete options.ACL;
|
|
219
163
|
}
|
|
@@ -222,7 +166,7 @@ async function setBucketPolicy(credential, Bucket, options, service = 'aws', sdk
|
|
|
222
166
|
this.formatMessage(64, service, ["Bucket policy configured", Bucket], '', { ...Cloud.LOG_CLOUD_COMMAND });
|
|
223
167
|
return true;
|
|
224
168
|
})
|
|
225
|
-
.catch(err => {
|
|
169
|
+
.catch((err) => {
|
|
226
170
|
if (!(0, exports.isNoSuchBucket)(err)) {
|
|
227
171
|
this.formatFail(64, service, ["Unable to update bucket policy", Bucket], err, { ...Cloud.LOG_CLOUD_FAIL, fatal: false });
|
|
228
172
|
}
|
|
@@ -230,7 +174,30 @@ async function setBucketPolicy(credential, Bucket, options, service = 'aws', sdk
|
|
|
230
174
|
});
|
|
231
175
|
}
|
|
232
176
|
exports.setBucketPolicy = setBucketPolicy;
|
|
233
|
-
async function
|
|
177
|
+
async function setBucketTagging(credential, Bucket, options, service = "aws", sdk = "aws-sdk/clients/s3") {
|
|
178
|
+
if (!(0, types_1.isPlainObject)(options) || !Array.isArray(options.Tagging?.TagSet)) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
const S3 = createStorageClient.call(this, credential, service, sdk);
|
|
182
|
+
const deleting = options.Tagging.TagSet.length === 0;
|
|
183
|
+
const command = () => {
|
|
184
|
+
this.formatMessage(64, service, [deleting ? "Tags deleted" : "Tags created", Bucket], null, { ...Cloud.LOG_CLOUD_COMMAND });
|
|
185
|
+
return true;
|
|
186
|
+
};
|
|
187
|
+
const error = (err) => {
|
|
188
|
+
if (!(0, exports.isNoSuchBucket)(err)) {
|
|
189
|
+
this.formatFail(64, service, ["Unable to update bucket tagging", Bucket], err, { ...Cloud.LOG_CLOUD_FAIL, fatal: false });
|
|
190
|
+
}
|
|
191
|
+
return false;
|
|
192
|
+
};
|
|
193
|
+
if (deleting) {
|
|
194
|
+
return S3.deleteBucketTagging({ Bucket, ExpectedBucketOwner: options.ExpectedBucketOwner }).promise().then(command).catch((err) => error(err));
|
|
195
|
+
}
|
|
196
|
+
options.Bucket = Bucket;
|
|
197
|
+
return S3.putBucketTagging(options).promise().then(command).catch((err) => error(err));
|
|
198
|
+
}
|
|
199
|
+
exports.setBucketTagging = setBucketTagging;
|
|
200
|
+
async function setBucketWebsite(credential, Bucket, options, service = "aws", sdk = "aws-sdk/clients/s3") {
|
|
234
201
|
const S3 = createStorageClient.call(this, credential, service, sdk);
|
|
235
202
|
const WebsiteConfiguration = {};
|
|
236
203
|
const { indexPage: Suffix, errorPage: Key } = options;
|
|
@@ -242,22 +209,22 @@ async function setBucketWebsite(credential, Bucket, options, service = 'aws', sd
|
|
|
242
209
|
}
|
|
243
210
|
return S3.putBucketWebsite({ Bucket, WebsiteConfiguration }).promise()
|
|
244
211
|
.then(() => {
|
|
245
|
-
this.formatMessage(64, service, ["Bucket configured", Bucket], WebsiteConfiguration, { ...Cloud.LOG_CLOUD_COMMAND });
|
|
212
|
+
this.formatMessage(64, service, ["Bucket website configured", Bucket], WebsiteConfiguration, { ...Cloud.LOG_CLOUD_COMMAND });
|
|
246
213
|
return true;
|
|
247
214
|
})
|
|
248
|
-
.catch(err => {
|
|
215
|
+
.catch((err) => {
|
|
249
216
|
if (!(0, exports.isNoSuchBucket)(err)) {
|
|
250
|
-
this.formatFail(64, service, ["Unable to
|
|
217
|
+
this.formatFail(64, service, ["Unable to set bucket website", Bucket], err, { ...Cloud.LOG_CLOUD_FAIL, fatal: false });
|
|
251
218
|
}
|
|
252
219
|
return false;
|
|
253
220
|
});
|
|
254
221
|
}
|
|
255
222
|
exports.setBucketWebsite = setBucketWebsite;
|
|
256
|
-
async function deleteObjects(credential, Bucket, service =
|
|
223
|
+
async function deleteObjects(credential, Bucket, service = "aws", sdk = "aws-sdk/clients/s3") {
|
|
257
224
|
return deleteObjectsV2.call(this, credential, Bucket, true, service, sdk);
|
|
258
225
|
}
|
|
259
226
|
exports.deleteObjects = deleteObjects;
|
|
260
|
-
async function deleteObjectsV2(credential, Bucket, recursive = true, service =
|
|
227
|
+
async function deleteObjectsV2(credential, Bucket, recursive = true, service = "aws", sdk = "aws-sdk/clients/s3") {
|
|
261
228
|
const S3 = createStorageClient.call(this, credential, service, sdk);
|
|
262
229
|
return S3.listObjects({ Bucket }).promise()
|
|
263
230
|
.then(async ({ Contents }) => {
|
|
@@ -274,12 +241,12 @@ async function deleteObjectsV2(credential, Bucket, recursive = true, service = '
|
|
|
274
241
|
this.formatMessage(64, service, ["Bucket emptied" + ` (${recursive ? 'recursive' : files})`, Bucket], recursive ? files : '', { ...Cloud.LOG_CLOUD_COMMAND });
|
|
275
242
|
}
|
|
276
243
|
})
|
|
277
|
-
.catch(err => {
|
|
244
|
+
.catch((err) => {
|
|
278
245
|
this.formatFail(64, service, ["Unable to empty bucket", Bucket], err, { ...Cloud.LOG_CLOUD_FAIL, fatal: false });
|
|
279
246
|
});
|
|
280
247
|
}
|
|
281
248
|
})
|
|
282
|
-
.catch(err => {
|
|
249
|
+
.catch((err) => {
|
|
283
250
|
if (!(0, exports.isNoSuchBucket)(err)) {
|
|
284
251
|
this.formatFail(64, service, ["Unable to list bucket", Bucket], err, { ...Cloud.LOG_CLOUD_FAIL, fatal: false });
|
|
285
252
|
}
|
|
@@ -291,17 +258,16 @@ async function executeQuery(credential, data, sessionKey) {
|
|
|
291
258
|
}
|
|
292
259
|
exports.executeQuery = executeQuery;
|
|
293
260
|
async function executeBatchQuery(credential, batch, sessionKey) {
|
|
294
|
-
var _a;
|
|
295
261
|
const length = batch.length;
|
|
296
262
|
const result = new Array(length);
|
|
297
263
|
const caching = length > 0 && this.hasCache(batch[0].service, sessionKey);
|
|
298
264
|
const cacheValue = { value: this.valueOfKey(credential, 'cache'), sessionKey };
|
|
299
265
|
let client;
|
|
300
|
-
const createClient = () => client
|
|
301
|
-
setDatabaseEndpoint(credential);
|
|
266
|
+
const createClient = () => client ||= createDatabaseClient.call(this, credential);
|
|
267
|
+
(0, aws_lib_1.setDatabaseEndpoint)(credential);
|
|
302
268
|
for (let i = 0; i < length; ++i) {
|
|
303
269
|
const item = batch[i];
|
|
304
|
-
let { service, table: TableName, id, query,
|
|
270
|
+
let { service, table: TableName, id, query, key, limit = 0, update, ignoreCache } = item;
|
|
305
271
|
const useCache = caching && ignoreCache !== true;
|
|
306
272
|
const getCache = (value) => {
|
|
307
273
|
if (ignoreCache !== 1) {
|
|
@@ -316,7 +282,7 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
316
282
|
throw (0, util_1.formatError)(item, "Missing database table");
|
|
317
283
|
}
|
|
318
284
|
if (useCache) {
|
|
319
|
-
queryString = TableName + '_' +
|
|
285
|
+
queryString = TableName + '_' + Cloud.asString(key, true) + (id !== undefined ? '_' + Cloud.asString(id, true) : '');
|
|
320
286
|
if (!update && (rows = getCache(queryString))) {
|
|
321
287
|
result[i] = rows;
|
|
322
288
|
continue;
|
|
@@ -343,7 +309,7 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
343
309
|
if (limit > 0) {
|
|
344
310
|
query.Limit = limit;
|
|
345
311
|
}
|
|
346
|
-
if (useCache && (rows = getCache(queryString =
|
|
312
|
+
if (useCache && (rows = getCache(queryString = Cloud.asString(query, true)))) {
|
|
347
313
|
result[i] = rows;
|
|
348
314
|
continue;
|
|
349
315
|
}
|
|
@@ -357,14 +323,14 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
357
323
|
if (!(0, types_1.isPlainObject)(params.RequestItems)) {
|
|
358
324
|
params.RequestItems = {};
|
|
359
325
|
}
|
|
360
|
-
TableName
|
|
326
|
+
TableName ||= Object.keys(params.RequestItems)[0];
|
|
361
327
|
if (!TableName) {
|
|
362
328
|
throw (0, util_1.formatError)(item, "Missing database table");
|
|
363
329
|
}
|
|
364
|
-
const Item =
|
|
330
|
+
const Item = params.RequestItems[TableName] ||= {};
|
|
365
331
|
Item.Keys = query;
|
|
366
332
|
params = { RequestItems: { [TableName]: Item } };
|
|
367
|
-
if (useCache && (rows = getCache(queryString =
|
|
333
|
+
if (useCache && (rows = getCache(queryString = Cloud.asString(params, true)))) {
|
|
368
334
|
result[i] = rows;
|
|
369
335
|
continue;
|
|
370
336
|
}
|
|
@@ -381,7 +347,7 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
381
347
|
else {
|
|
382
348
|
params = { TableName };
|
|
383
349
|
}
|
|
384
|
-
if (useCache && (rows = getCache(queryString =
|
|
350
|
+
if (useCache && (rows = getCache(queryString = Cloud.asString(params, true)))) {
|
|
385
351
|
result[i] = rows;
|
|
386
352
|
continue;
|
|
387
353
|
}
|
|
@@ -398,42 +364,6 @@ async function executeBatchQuery(credential, batch, sessionKey) {
|
|
|
398
364
|
return result;
|
|
399
365
|
}
|
|
400
366
|
exports.executeBatchQuery = executeBatchQuery;
|
|
401
|
-
function setDatabaseEndpoint(config) {
|
|
402
|
-
let region = config.region;
|
|
403
|
-
const endpoint = config.endpoint || (config.endpoint = `https://dynamodb.${(0, types_1.isString)(region) ? region : process.env.AWS_DEFAULT_REGION || process.env.AWS_REGION || 'us-east-1'}.amazonaws.com`);
|
|
404
|
-
if (!region) {
|
|
405
|
-
region = ((0, types_1.isString)(endpoint) && /\bdynamodb\.([^.]+)\./i.exec(endpoint)?.[1] || process.env.AWS_DEFAULT_REGION || process.env.AWS_REGION)?.toLowerCase();
|
|
406
|
-
if (region && region !== 'us-east-1') {
|
|
407
|
-
config.region = region;
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
exports.setDatabaseEndpoint = setDatabaseEndpoint;
|
|
412
|
-
function checkBucketCannedACL(value) {
|
|
413
|
-
switch (value) {
|
|
414
|
-
case 'private':
|
|
415
|
-
case 'public-read':
|
|
416
|
-
case 'public-read-write':
|
|
417
|
-
case 'authenticated-read':
|
|
418
|
-
return value;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
exports.checkBucketCannedACL = checkBucketCannedACL;
|
|
422
|
-
function writeMessageDefaultRetention(bucket, retention, service = 'aws') {
|
|
423
|
-
const { Years = 0, Days = 0, Mode } = retention;
|
|
424
|
-
const status = [];
|
|
425
|
-
if (Years > 0) {
|
|
426
|
-
status.push(Years.toString() + 'Y');
|
|
427
|
-
}
|
|
428
|
-
if (Days > 0) {
|
|
429
|
-
status.push(Days.toString() + 'D');
|
|
430
|
-
}
|
|
431
|
-
if (Mode) {
|
|
432
|
-
status.push(status.length ? `(${Mode})` : Mode);
|
|
433
|
-
}
|
|
434
|
-
this.formatMessage(64, service, ["Bucket configured" + ' (Retention Policy)', bucket], status.join(' '), { ...Cloud.LOG_CLOUD_COMMAND });
|
|
435
|
-
}
|
|
436
|
-
exports.writeMessageDefaultRetention = writeMessageDefaultRetention;
|
|
437
367
|
function parseAttributeValue(value) {
|
|
438
368
|
switch (typeof value) {
|
|
439
369
|
case 'string':
|
|
@@ -464,7 +394,7 @@ function parseAttributeValue(value) {
|
|
|
464
394
|
return { NULL: true };
|
|
465
395
|
}
|
|
466
396
|
exports.parseAttributeValue = parseAttributeValue;
|
|
467
|
-
const getBucketKey = (credential, Bucket, acl, service, sdk) => Module.asString(credential, true) + Bucket + '_' + (acl || '') + service + sdk;
|
|
468
|
-
exports.getBucketKey = getBucketKey;
|
|
469
397
|
const isNoSuchBucket = (err) => err instanceof Error && err.code === 'NoSuchBucket';
|
|
470
398
|
exports.isNoSuchBucket = isNoSuchBucket;
|
|
399
|
+
exports.CLOUD_UPLOAD_STREAM = true;
|
|
400
|
+
exports.CLOUD_UPLOAD_CHUNK = true;
|
package/download/index.js
CHANGED
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const types_1 = require("@e-mc/types");
|
|
3
|
-
const Module = require("@e-mc/module");
|
|
4
3
|
const Cloud = require("@e-mc/cloud");
|
|
5
4
|
const client_1 = require("@pi-r/aws");
|
|
6
|
-
module.exports = function download(credential, service =
|
|
5
|
+
module.exports = function download(credential, service = "aws", sdk = "aws-sdk/clients/s3") {
|
|
7
6
|
const s3 = client_1.createStorageClient.call(this, credential, service, sdk);
|
|
8
7
|
return (data, callback) => {
|
|
9
8
|
const { bucket: Bucket, download: target } = data;
|
|
10
|
-
const Key = target.filename;
|
|
9
|
+
const Key = target.keyname || target.filename;
|
|
11
10
|
if (!Bucket || !Key) {
|
|
12
11
|
callback((0, types_1.errorValue)('Missing property', !Bucket ? 'Bucket' : 'Key'));
|
|
13
12
|
return;
|
|
14
13
|
}
|
|
15
|
-
const location =
|
|
16
|
-
|
|
17
|
-
s3.getObject(params, (err, result) => {
|
|
14
|
+
const location = Cloud.joinPath(Bucket, Key);
|
|
15
|
+
s3.getObject({ ...target.options, Bucket, Key, VersionId: target.versionId }, (err, result) => {
|
|
18
16
|
if (!err) {
|
|
19
17
|
callback(null, result.Body);
|
|
20
|
-
|
|
18
|
+
let deleteObject = target.deleteObject;
|
|
21
19
|
if (deleteObject) {
|
|
22
|
-
|
|
20
|
+
if (!(0, types_1.isPlainObject)(deleteObject)) {
|
|
21
|
+
deleteObject = undefined;
|
|
22
|
+
}
|
|
23
|
+
s3.deleteObject({ ...deleteObject, Bucket, Key, VersionId: target.versionId }, error => {
|
|
23
24
|
if (!error) {
|
|
24
25
|
this.formatMessage(64, service, "Delete success", location, { ...Cloud.LOG_CLOUD_DELETE });
|
|
25
26
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-r/aws",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.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,10 @@
|
|
|
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-
|
|
24
|
+
"@e-mc/cloud": "^0.9.0",
|
|
25
|
+
"@e-mc/module": "^0.9.0",
|
|
26
|
+
"@e-mc/types": "^0.9.0",
|
|
27
|
+
"@pi-r/aws-lib": "^0.7.0",
|
|
28
|
+
"aws-sdk": "^2.1607.0"
|
|
28
29
|
}
|
|
29
30
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
import type { CloudDatabase } from '@e-mc/types/lib/cloud';
|
|
1
|
+
import type { CloudDatabase, CloudStorage } from '@e-mc/types/lib/cloud';
|
|
3
2
|
|
|
4
3
|
import type { ConfigurationOptions } from 'aws-sdk/lib/core';
|
|
5
4
|
import type { ServiceConfigurationOptions } from 'aws-sdk/lib/service';
|
|
6
5
|
import type { DocumentClient } from 'aws-sdk/clients/dynamodb';
|
|
7
6
|
import type { PutBucketAclRequest, PutBucketPolicyRequest, PutPublicAccessBlockRequest } from 'aws-sdk/clients/s3';
|
|
8
7
|
|
|
9
|
-
export type BucketCannedACL = "authenticated-read" | "private" | "public-read" | "public-read-write";
|
|
10
|
-
export type ObjectCannedACL = BucketCannedACL | "aws-exec-read" | "bucket-owner-full-control" | "bucket-owner-read";
|
|
11
8
|
export type ConfigureBucketOptions = PutBucketAclRequest | PutBucketPolicyRequest | PutPublicAccessBlockRequest;
|
|
12
9
|
export type Key = DocumentClient.Key;
|
|
13
10
|
export type GetItemInput = DocumentClient.GetItemInput;
|
|
@@ -16,14 +13,17 @@ export type UpdateItemInput = DocumentClient.UpdateItemInput;
|
|
|
16
13
|
export type ScanInput = DocumentClient.ScanInput;
|
|
17
14
|
export type BatchGetItemInput = DocumentClient.BatchGetItemInput;
|
|
18
15
|
|
|
16
|
+
export type AWSStorage = CloudStorage<AWSStorageCredential, "aws">;
|
|
17
|
+
|
|
19
18
|
export interface AWSStorageCredential extends ConfigurationOptions {
|
|
20
19
|
profile?: string;
|
|
21
20
|
fromPath?: string;
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
export interface AWSDatabaseQuery extends CloudDatabase<QueryInput | Key[],
|
|
23
|
+
export interface AWSDatabaseQuery extends CloudDatabase<QueryInput | Key[], Record<string, unknown>, UpdateItemInput, BatchGetItemInput | ScanInput, AWSDatabaseCredential> {
|
|
24
|
+
source: "cloud";
|
|
25
|
+
service: "aws";
|
|
25
26
|
key?: string | Key;
|
|
26
|
-
partitionKey?: string | Key;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
export interface AWSDatabaseCredential extends AWSStorageCredential, ServiceConfigurationOptions {}
|
|
29
|
+
export interface AWSDatabaseCredential extends AWSStorageCredential, ServiceConfigurationOptions {}
|
package/upload/index.js
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const path = require("path");
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const stream = require("stream");
|
|
5
|
+
const aws = require("aws-sdk");
|
|
6
|
+
const Cloud = require("@e-mc/cloud");
|
|
3
7
|
const util_1 = require("@e-mc/cloud/util");
|
|
4
8
|
const types_1 = require("@e-mc/types");
|
|
5
|
-
const
|
|
6
|
-
const Cloud = require("@e-mc/cloud");
|
|
9
|
+
const aws_lib_1 = require("@pi-r/aws-lib");
|
|
7
10
|
const client_1 = require("@pi-r/aws");
|
|
8
11
|
const BUCKET_SESSION = new Set();
|
|
9
12
|
const BUCKET_RESPONSE = {};
|
|
10
|
-
module.exports = function upload(credential, service =
|
|
13
|
+
module.exports = function upload(credential, service = "aws", sdk = "aws-sdk/clients/s3") {
|
|
11
14
|
const s3 = client_1.createStorageClient.call(this, credential, service, sdk);
|
|
12
15
|
return async (data, callback) => {
|
|
13
|
-
var _a;
|
|
14
16
|
const { bucket: Bucket, localUri } = data;
|
|
15
|
-
const { pathname = '', fileGroup, contentType, metadata, tags, endpoint, active, publicRead, acl, admin = {}, overwrite, options } = data.upload;
|
|
17
|
+
const { pathname = '', flags = 0, fileGroup, contentType, metadata, tags: Tags, endpoint, active, publicRead, acl, admin = {}, overwrite, options } = data.upload;
|
|
16
18
|
let filename = data.upload.filename || path.basename(localUri), bucketKey;
|
|
17
19
|
const cleanup = () => {
|
|
18
20
|
BUCKET_SESSION.delete(service + Bucket);
|
|
19
|
-
if (bucketKey
|
|
21
|
+
if (bucketKey) {
|
|
20
22
|
delete BUCKET_RESPONSE[bucketKey];
|
|
21
23
|
}
|
|
22
24
|
};
|
|
@@ -27,25 +29,73 @@ module.exports = function upload(credential, service = 'aws', sdk = 'aws-sdk/cli
|
|
|
27
29
|
const addLog = (err) => err instanceof Error && this.addLog(this.statusType.WARN, err, service, Bucket);
|
|
28
30
|
const configBucket = admin.configBucket;
|
|
29
31
|
if (!BUCKET_SESSION.has(service + Bucket)) {
|
|
30
|
-
const bucketAcl = admin.publicRead ?
|
|
31
|
-
const response = BUCKET_RESPONSE[
|
|
32
|
+
const bucketAcl = admin.publicRead ? "public-read" : admin.acl;
|
|
33
|
+
const response = BUCKET_RESPONSE[bucketKey = (0, aws_lib_1.getBucketKey)(credential, Bucket, bucketAcl, service, sdk)] ||= 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
|
}
|
|
38
|
-
if (
|
|
39
|
-
const DefaultRetention = configBucket
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
if (configBucket && service !== "oci") {
|
|
41
|
+
const { cors: CORSConfiguration, lifecycle: LifecycleConfiguration, retentionPolicy: DefaultRetention } = configBucket;
|
|
42
|
+
const ExpectedBucketOwner = options?.ExpectedBucketOwner;
|
|
43
|
+
const commandMessage = (feature, message) => this.formatMessage(64, service, ["Bucket configured" + ` (${feature})`, Bucket], message || ExpectedBucketOwner, { ...Cloud[message === 'delete' ? 'LOG_CLOUD_WARN' : 'LOG_CLOUD_COMMAND'] });
|
|
44
|
+
if (service !== "ibm") {
|
|
45
|
+
if ((0, types_1.isPlainObject)(DefaultRetention)) {
|
|
46
|
+
s3.putObjectLockConfiguration({ Bucket, ObjectLockConfiguration: { ObjectLockEnabled: 'Enabled', Rule: { DefaultRetention } }, ExpectedBucketOwner, RequestPayer: options?.RequestPayer }, err => {
|
|
47
|
+
if (!err) {
|
|
48
|
+
this.formatMessage(64, service, ["Bucket configured" + ' (Retention Policy)', Bucket], (0, aws_lib_1.formatDefaultRetention)(DefaultRetention), { ...Cloud.LOG_CLOUD_COMMAND });
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
addLog(err);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (CORSConfiguration && Array.isArray(CORSConfiguration.CORSRules)) {
|
|
57
|
+
if (CORSConfiguration.CORSRules.length === 0) {
|
|
58
|
+
s3.deleteBucketCors({ Bucket, ExpectedBucketOwner }, err => {
|
|
59
|
+
if (!err) {
|
|
60
|
+
commandMessage('CORS', 'delete');
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
addLog(err);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
s3.putBucketCors({ Bucket, CORSConfiguration, ExpectedBucketOwner }, err => {
|
|
69
|
+
if (!err) {
|
|
70
|
+
commandMessage('CORS');
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
addLog(err);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (LifecycleConfiguration && Array.isArray(LifecycleConfiguration.Rules)) {
|
|
79
|
+
if (LifecycleConfiguration.Rules.length === 0) {
|
|
80
|
+
s3.deleteBucketLifecycle({ Bucket, ExpectedBucketOwner }, err => {
|
|
81
|
+
if (!err) {
|
|
82
|
+
commandMessage('Lifecycle', 'delete');
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
addLog(err);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
s3.putBucketLifecycleConfiguration({ Bucket, LifecycleConfiguration, ExpectedBucketOwner }, err => {
|
|
91
|
+
if (!err) {
|
|
92
|
+
commandMessage('Lifecycle');
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
addLog(err);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
49
99
|
}
|
|
50
100
|
}
|
|
51
101
|
if (!overwrite) {
|
|
@@ -59,7 +109,7 @@ module.exports = function upload(credential, service = 'aws', sdk = 'aws-sdk/cli
|
|
|
59
109
|
break;
|
|
60
110
|
}
|
|
61
111
|
}
|
|
62
|
-
exists = await s3.headObject({ Bucket, Key: pathname ?
|
|
112
|
+
exists = await s3.headObject({ Bucket, Key: pathname ? Cloud.joinPath(pathname, filename) : filename }).promise()
|
|
63
113
|
.then(() => true)
|
|
64
114
|
.catch((err) => {
|
|
65
115
|
if (err instanceof Error && err.code !== 'NotFound') {
|
|
@@ -75,14 +125,39 @@ module.exports = function upload(credential, service = 'aws', sdk = 'aws-sdk/cli
|
|
|
75
125
|
if (pathname) {
|
|
76
126
|
await s3.putObject({ Bucket, Key: pathname, Body: Buffer.from(''), ContentLength: 0 }).promise().catch(() => { });
|
|
77
127
|
}
|
|
128
|
+
const partSize = flags & 4 ? (0, types_1.alignSize)(data.upload.chunkSize, 1024) : 0;
|
|
78
129
|
const Key = [filename];
|
|
79
130
|
const Body = [data.buffer];
|
|
131
|
+
const Stream = [];
|
|
80
132
|
const ContentType = [contentType];
|
|
133
|
+
const getPartSize = () => partSize > 0 ? Math.max(partSize, aws.S3.ManagedUpload.minPartSize) : undefined;
|
|
134
|
+
if (Body[0].length === 0) {
|
|
135
|
+
try {
|
|
136
|
+
if ((flags & 2) || partSize > 0) {
|
|
137
|
+
Stream[0] = fs.createReadStream(localUri, { highWaterMark: getPartSize(), signal: this.signal });
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
Body[0] = fs.readFileSync(localUri);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
errorResponse(err);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else if ((flags & 2) || partSize > 0) {
|
|
149
|
+
Stream[0] = stream.Readable.from(Body[0], { highWaterMark: getPartSize() });
|
|
150
|
+
}
|
|
81
151
|
if (fileGroup) {
|
|
82
|
-
const [key, body, type] = (0, util_1.createKeyAndBody)(filename, fileGroup, addLog);
|
|
152
|
+
const [key, body, type] = (0, util_1.createKeyAndBody)(filename, fileGroup, 0, addLog, flags);
|
|
83
153
|
Key.push(...key);
|
|
84
|
-
Body.push(...body);
|
|
85
154
|
ContentType.push(...type);
|
|
155
|
+
if (flags & 2) {
|
|
156
|
+
Stream.push(...body);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
Body.push(...body);
|
|
160
|
+
}
|
|
86
161
|
}
|
|
87
162
|
for (let i = 0; i < Key.length; ++i) {
|
|
88
163
|
const first = i === 0;
|
|
@@ -92,12 +167,13 @@ module.exports = function upload(credential, service = 'aws', sdk = 'aws-sdk/cli
|
|
|
92
167
|
}
|
|
93
168
|
return;
|
|
94
169
|
}
|
|
95
|
-
const params = { ...options, Bucket, Key: pathname + Key[i], Body: Body[i] };
|
|
170
|
+
const params = { ...options, Bucket, Key: pathname + Key[i], Body: Stream[i] || Body[i] };
|
|
96
171
|
const readable = publicRead || active && publicRead !== false && !acl;
|
|
172
|
+
let tags, length = -1;
|
|
97
173
|
if (first) {
|
|
98
|
-
params.ContentType
|
|
174
|
+
params.ContentType ||= ContentType[i];
|
|
99
175
|
if (readable) {
|
|
100
|
-
params.ACL =
|
|
176
|
+
params.ACL = "public-read";
|
|
101
177
|
}
|
|
102
178
|
else if (acl) {
|
|
103
179
|
params.ACL = acl;
|
|
@@ -105,19 +181,30 @@ module.exports = function upload(credential, service = 'aws', sdk = 'aws-sdk/cli
|
|
|
105
181
|
if (metadata) {
|
|
106
182
|
params.Metadata = metadata;
|
|
107
183
|
}
|
|
184
|
+
if (service !== "oci") {
|
|
185
|
+
if ((0, types_1.isPlainObject)(Tags) && (length = Object.keys(Tags).length) > 0) {
|
|
186
|
+
tags = [];
|
|
187
|
+
for (const name in Tags) {
|
|
188
|
+
tags.push({ Key: name, Value: Tags[name] });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
else if (Tags === false) {
|
|
192
|
+
length = 0;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
108
195
|
}
|
|
109
196
|
else {
|
|
110
197
|
params.ContentType = ContentType[i];
|
|
111
198
|
if (!params.ACL) {
|
|
112
199
|
if (readable) {
|
|
113
|
-
params.ACL =
|
|
200
|
+
params.ACL = "public-read";
|
|
114
201
|
}
|
|
115
202
|
else if (acl) {
|
|
116
203
|
params.ACL = acl;
|
|
117
204
|
}
|
|
118
205
|
}
|
|
119
206
|
}
|
|
120
|
-
|
|
207
|
+
new aws.S3.ManagedUpload({ service: s3, params, tags, partSize: getPartSize(), queueSize: partSize > 0 ? data.upload.chunkLimit : undefined }).send((err, result) => {
|
|
121
208
|
if (err) {
|
|
122
209
|
if (first) {
|
|
123
210
|
errorResponse(err);
|
|
@@ -127,28 +214,10 @@ module.exports = function upload(credential, service = 'aws', sdk = 'aws-sdk/cli
|
|
|
127
214
|
}
|
|
128
215
|
return;
|
|
129
216
|
}
|
|
130
|
-
const url = endpoint ?
|
|
217
|
+
const url = endpoint ? Cloud.joinPath(endpoint, result.Key) : result.Location;
|
|
131
218
|
this.formatMessage(64, service, "Upload success", url, { ...Cloud.LOG_CLOUD_UPLOAD });
|
|
132
|
-
if (
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
if (service !== 'oci') {
|
|
136
|
-
let length = -1;
|
|
137
|
-
if ((0, types_1.isPlainObject)(tags) && (length = Object.keys(tags).length) > 0) {
|
|
138
|
-
const TagSet = [];
|
|
139
|
-
for (const name in tags) {
|
|
140
|
-
TagSet.push({ Key: name, Value: tags[name] });
|
|
141
|
-
}
|
|
142
|
-
s3.putObjectTagging({ Bucket, Key: result.Key, Tagging: { TagSet }, ExpectedBucketOwner: params.ExpectedBucketOwner, RequestPayer: params.RequestPayer }, error => {
|
|
143
|
-
if (!error) {
|
|
144
|
-
this.formatMessage(64, service, ["Tags created", Bucket], result.Key, { ...Cloud.LOG_CLOUD_COMMAND });
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
addLog(error);
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
else if (tags === false || length === 0) {
|
|
219
|
+
if (first) {
|
|
220
|
+
if (length === 0) {
|
|
152
221
|
s3.deleteObjectTagging({ Bucket, Key: result.Key, ExpectedBucketOwner: params.ExpectedBucketOwner }, error => {
|
|
153
222
|
if (!error) {
|
|
154
223
|
this.formatMessage(64, service, ["Tags deleted", Bucket], result.Key, { ...Cloud.LOG_CLOUD_COMMAND });
|
|
@@ -158,9 +227,9 @@ module.exports = function upload(credential, service = 'aws', sdk = 'aws-sdk/cli
|
|
|
158
227
|
}
|
|
159
228
|
});
|
|
160
229
|
}
|
|
230
|
+
cleanup();
|
|
231
|
+
callback(null, url);
|
|
161
232
|
}
|
|
162
|
-
cleanup();
|
|
163
|
-
callback(null, url);
|
|
164
233
|
});
|
|
165
234
|
}
|
|
166
235
|
};
|