@aws-amplify/storage 4.4.3 → 4.4.4-in-app-messaging.35
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/CHANGELOG.md +28 -352
- package/dist/aws-amplify-storage.js +6523 -5062
- package/dist/aws-amplify-storage.js.map +1 -1
- package/dist/aws-amplify-storage.min.js +5 -5
- package/dist/aws-amplify-storage.min.js.map +1 -1
- package/lib/Storage.d.ts +3 -1
- package/lib/Storage.js +25 -21
- package/lib/Storage.js.map +1 -1
- package/lib/common/S3ClientUtils.d.ts +33 -0
- package/lib/common/S3ClientUtils.js +179 -0
- package/lib/common/S3ClientUtils.js.map +1 -0
- package/lib/common/StorageConstants.d.ts +4 -0
- package/lib/common/StorageConstants.js +10 -0
- package/lib/common/StorageConstants.js.map +1 -0
- package/lib/common/StorageErrorStrings.d.ts +5 -1
- package/lib/common/StorageErrorStrings.js +5 -0
- package/lib/common/StorageErrorStrings.js.map +1 -1
- package/lib/common/StorageUtils.d.ts +4 -0
- package/lib/common/StorageUtils.js +41 -0
- package/lib/common/StorageUtils.js.map +1 -0
- package/lib/providers/AWSS3Provider.d.ts +9 -6
- package/lib/providers/AWSS3Provider.js +197 -149
- package/lib/providers/AWSS3Provider.js.map +1 -1
- package/lib/providers/AWSS3ProviderManagedUpload.d.ts +3 -10
- package/lib/providers/AWSS3ProviderManagedUpload.js +41 -109
- package/lib/providers/AWSS3ProviderManagedUpload.js.map +1 -1
- package/lib/providers/AWSS3UploadTask.d.ts +107 -0
- package/lib/providers/AWSS3UploadTask.js +610 -0
- package/lib/providers/AWSS3UploadTask.js.map +1 -0
- package/lib/providers/axios-http-handler.d.ts +5 -1
- package/lib/providers/axios-http-handler.js +28 -5
- package/lib/providers/axios-http-handler.js.map +1 -1
- package/lib/types/AWSS3Provider.d.ts +24 -4
- package/lib/types/Provider.d.ts +7 -1
- package/lib/types/Storage.d.ts +8 -8
- package/lib-esm/Storage.d.ts +3 -1
- package/lib-esm/Storage.js +25 -21
- package/lib-esm/Storage.js.map +1 -1
- package/lib-esm/common/S3ClientUtils.d.ts +33 -0
- package/lib-esm/common/S3ClientUtils.js +177 -0
- package/lib-esm/common/S3ClientUtils.js.map +1 -0
- package/lib-esm/common/StorageConstants.d.ts +4 -0
- package/lib-esm/common/StorageConstants.js +8 -0
- package/lib-esm/common/StorageConstants.js.map +1 -0
- package/lib-esm/common/StorageErrorStrings.d.ts +5 -1
- package/lib-esm/common/StorageErrorStrings.js +5 -0
- package/lib-esm/common/StorageErrorStrings.js.map +1 -1
- package/lib-esm/common/StorageUtils.d.ts +4 -0
- package/lib-esm/common/StorageUtils.js +39 -0
- package/lib-esm/common/StorageUtils.js.map +1 -0
- package/lib-esm/providers/AWSS3Provider.d.ts +9 -6
- package/lib-esm/providers/AWSS3Provider.js +192 -144
- package/lib-esm/providers/AWSS3Provider.js.map +1 -1
- package/lib-esm/providers/AWSS3ProviderManagedUpload.d.ts +3 -10
- package/lib-esm/providers/AWSS3ProviderManagedUpload.js +44 -112
- package/lib-esm/providers/AWSS3ProviderManagedUpload.js.map +1 -1
- package/lib-esm/providers/AWSS3UploadTask.d.ts +107 -0
- package/lib-esm/providers/AWSS3UploadTask.js +605 -0
- package/lib-esm/providers/AWSS3UploadTask.js.map +1 -0
- package/lib-esm/providers/axios-http-handler.d.ts +5 -1
- package/lib-esm/providers/axios-http-handler.js +28 -5
- package/lib-esm/providers/axios-http-handler.js.map +1 -1
- package/lib-esm/types/AWSS3Provider.d.ts +24 -4
- package/lib-esm/types/Provider.d.ts +7 -1
- package/lib-esm/types/Storage.d.ts +8 -8
- package/package.json +3 -3
- package/src/Storage.ts +85 -27
- package/src/common/S3ClientUtils.ts +168 -0
- package/src/common/StorageConstants.ts +10 -0
- package/src/common/StorageErrorStrings.ts +5 -0
- package/src/common/StorageUtils.ts +51 -0
- package/src/providers/AWSS3Provider.ts +251 -88
- package/src/providers/AWSS3ProviderManagedUpload.ts +346 -397
- package/src/providers/AWSS3UploadTask.ts +543 -0
- package/src/providers/axios-http-handler.ts +221 -186
- package/src/types/AWSS3Provider.ts +48 -7
- package/src/types/Provider.ts +18 -3
- package/src/types/Storage.ts +9 -9
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Hub } from '@aws-amplify/core';
|
|
2
|
+
import { AMPLIFY_SYMBOL } from './StorageConstants';
|
|
3
|
+
|
|
4
|
+
export const byteLength = (x: unknown) => {
|
|
5
|
+
if (typeof x === 'string') {
|
|
6
|
+
return x.length;
|
|
7
|
+
} else if (isArrayBuffer(x)) {
|
|
8
|
+
return x.byteLength;
|
|
9
|
+
} else if (isBlob(x)) {
|
|
10
|
+
return x.size;
|
|
11
|
+
} else {
|
|
12
|
+
throw new Error('Cannot determine byte length of ' + x);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const dispatchStorageEvent = (
|
|
17
|
+
track: boolean,
|
|
18
|
+
event: string,
|
|
19
|
+
attrs: any,
|
|
20
|
+
metrics: any,
|
|
21
|
+
message: string
|
|
22
|
+
): void => {
|
|
23
|
+
if (track) {
|
|
24
|
+
const data = { attrs };
|
|
25
|
+
if (metrics) {
|
|
26
|
+
data['metrics'] = metrics;
|
|
27
|
+
}
|
|
28
|
+
Hub.dispatch(
|
|
29
|
+
'storage',
|
|
30
|
+
{
|
|
31
|
+
event,
|
|
32
|
+
data,
|
|
33
|
+
message,
|
|
34
|
+
},
|
|
35
|
+
'Storage',
|
|
36
|
+
AMPLIFY_SYMBOL
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const isFile = (x: unknown): x is File => {
|
|
42
|
+
return typeof x !== 'undefined' && x instanceof File;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const isBlob = (x: unknown): x is Blob => {
|
|
46
|
+
return typeof x !== 'undefined' && x instanceof Blob;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const isArrayBuffer = (x: unknown): x is ArrayBuffer => {
|
|
50
|
+
return typeof x !== 'undefined' && x instanceof ArrayBuffer;
|
|
51
|
+
};
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import {
|
|
14
14
|
ConsoleLogger as Logger,
|
|
15
|
-
Hub,
|
|
16
15
|
Credentials,
|
|
17
16
|
Parser,
|
|
18
|
-
getAmplifyUserAgent,
|
|
19
17
|
ICredentials,
|
|
18
|
+
StorageHelper,
|
|
19
|
+
Hub,
|
|
20
20
|
} from '@aws-amplify/core';
|
|
21
21
|
import {
|
|
22
22
|
S3Client,
|
|
@@ -33,7 +33,10 @@ import {
|
|
|
33
33
|
import { formatUrl } from '@aws-sdk/util-format-url';
|
|
34
34
|
import { createRequest } from '@aws-sdk/util-create-request';
|
|
35
35
|
import { S3RequestPresigner } from '@aws-sdk/s3-request-presigner';
|
|
36
|
-
import {
|
|
36
|
+
import {
|
|
37
|
+
SEND_DOWNLOAD_PROGRESS_EVENT,
|
|
38
|
+
SEND_UPLOAD_PROGRESS_EVENT,
|
|
39
|
+
} from './axios-http-handler';
|
|
37
40
|
import {
|
|
38
41
|
StorageOptions,
|
|
39
42
|
StorageProvider,
|
|
@@ -43,7 +46,6 @@ import {
|
|
|
43
46
|
S3ProviderRemoveConfig,
|
|
44
47
|
S3ProviderListOutput,
|
|
45
48
|
S3ProviderListConfig,
|
|
46
|
-
S3ProviderPutOutput,
|
|
47
49
|
S3ProviderCopyConfig,
|
|
48
50
|
S3ProviderCopyOutput,
|
|
49
51
|
S3CopySource,
|
|
@@ -51,41 +53,41 @@ import {
|
|
|
51
53
|
StorageAccessLevel,
|
|
52
54
|
CustomPrefix,
|
|
53
55
|
S3ProviderRemoveOutput,
|
|
56
|
+
S3ProviderPutOutput,
|
|
57
|
+
ResumableUploadConfig,
|
|
58
|
+
UploadTask,
|
|
54
59
|
} from '../types';
|
|
55
60
|
import { StorageErrorStrings } from '../common/StorageErrorStrings';
|
|
61
|
+
import { dispatchStorageEvent } from '../common/StorageUtils';
|
|
62
|
+
import {
|
|
63
|
+
createPrefixMiddleware,
|
|
64
|
+
prefixMiddlewareOptions,
|
|
65
|
+
getPrefix,
|
|
66
|
+
autoAdjustClockskewMiddleware,
|
|
67
|
+
autoAdjustClockskewMiddlewareOptions,
|
|
68
|
+
createS3Client,
|
|
69
|
+
} from '../common/S3ClientUtils';
|
|
56
70
|
import { AWSS3ProviderManagedUpload } from './AWSS3ProviderManagedUpload';
|
|
71
|
+
import { AWSS3UploadTask, TaskEvents } from './AWSS3UploadTask';
|
|
72
|
+
import { UPLOADS_STORAGE_KEY } from '../common/StorageConstants';
|
|
57
73
|
import * as events from 'events';
|
|
58
74
|
import { CancelTokenSource } from 'axios';
|
|
59
75
|
|
|
60
76
|
const logger = new Logger('AWSS3Provider');
|
|
61
77
|
|
|
62
|
-
const AMPLIFY_SYMBOL = (typeof Symbol !== 'undefined' && typeof Symbol.for === 'function'
|
|
63
|
-
? Symbol.for('amplify_default')
|
|
64
|
-
: '@@amplify_default') as Symbol;
|
|
65
|
-
const SET_CONTENT_LENGTH_HEADER = 'contentLengthMiddleware';
|
|
66
78
|
const DEFAULT_STORAGE_LEVEL = 'public';
|
|
67
79
|
const DEFAULT_PRESIGN_EXPIRATION = 900;
|
|
68
80
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
event,
|
|
79
|
-
data,
|
|
80
|
-
message,
|
|
81
|
-
},
|
|
82
|
-
'Storage',
|
|
83
|
-
AMPLIFY_SYMBOL
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
};
|
|
81
|
+
interface AddTaskInput {
|
|
82
|
+
accessLevel: StorageAccessLevel;
|
|
83
|
+
file: Blob;
|
|
84
|
+
bucket: string;
|
|
85
|
+
emitter: events.EventEmitter;
|
|
86
|
+
key: string;
|
|
87
|
+
s3Client: S3Client;
|
|
88
|
+
params?: PutObjectCommandInput;
|
|
89
|
+
}
|
|
87
90
|
|
|
88
|
-
const localTestingStorageEndpoint = 'http://localhost:20005';
|
|
89
91
|
/**
|
|
90
92
|
* Provide storage methods to use AWS S3
|
|
91
93
|
*/
|
|
@@ -93,6 +95,7 @@ export class AWSS3Provider implements StorageProvider {
|
|
|
93
95
|
static readonly CATEGORY = 'Storage';
|
|
94
96
|
static readonly PROVIDER_NAME = 'AWSS3';
|
|
95
97
|
private _config: StorageOptions;
|
|
98
|
+
private _storage: Storage;
|
|
96
99
|
|
|
97
100
|
/**
|
|
98
101
|
* Initialize Storage with AWS configurations
|
|
@@ -100,6 +103,13 @@ export class AWSS3Provider implements StorageProvider {
|
|
|
100
103
|
*/
|
|
101
104
|
constructor(config?: StorageOptions) {
|
|
102
105
|
this._config = config ? config : {};
|
|
106
|
+
this._storage = new StorageHelper().getStorage();
|
|
107
|
+
Hub.listen('auth', data => {
|
|
108
|
+
const { payload } = data;
|
|
109
|
+
if (payload.event === 'signOut' || payload.event === 'signIn') {
|
|
110
|
+
this._storage.removeItem(UPLOADS_STORAGE_KEY);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
103
113
|
logger.debug('Storage Options', this._config);
|
|
104
114
|
}
|
|
105
115
|
|
|
@@ -133,6 +143,95 @@ export class AWSS3Provider implements StorageProvider {
|
|
|
133
143
|
return this._config;
|
|
134
144
|
}
|
|
135
145
|
|
|
146
|
+
private startResumableUpload(
|
|
147
|
+
addTaskInput: AddTaskInput,
|
|
148
|
+
config: S3ProviderPutConfig & ResumableUploadConfig
|
|
149
|
+
): UploadTask {
|
|
150
|
+
const { s3Client, emitter, key, file, params } = addTaskInput;
|
|
151
|
+
const {
|
|
152
|
+
progressCallback,
|
|
153
|
+
completeCallback,
|
|
154
|
+
errorCallback,
|
|
155
|
+
track = false,
|
|
156
|
+
} = config;
|
|
157
|
+
if (!(file instanceof Blob)) {
|
|
158
|
+
throw new Error(StorageErrorStrings.INVALID_BLOB);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
emitter.on(TaskEvents.UPLOAD_PROGRESS, event => {
|
|
162
|
+
if (progressCallback) {
|
|
163
|
+
if (typeof progressCallback === 'function') {
|
|
164
|
+
progressCallback(event);
|
|
165
|
+
} else {
|
|
166
|
+
logger.warn(
|
|
167
|
+
'progressCallback should be a function, not a ' +
|
|
168
|
+
typeof progressCallback
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
emitter.on(TaskEvents.UPLOAD_COMPLETE, event => {
|
|
175
|
+
if (completeCallback) {
|
|
176
|
+
if (typeof completeCallback === 'function') {
|
|
177
|
+
completeCallback(event);
|
|
178
|
+
} else {
|
|
179
|
+
logger.warn(
|
|
180
|
+
'completeCallback should be a function, not a ' +
|
|
181
|
+
typeof completeCallback
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
emitter.on(TaskEvents.ERROR, err => {
|
|
188
|
+
if (errorCallback) {
|
|
189
|
+
if (typeof errorCallback === 'function') {
|
|
190
|
+
errorCallback(err);
|
|
191
|
+
} else {
|
|
192
|
+
logger.warn(
|
|
193
|
+
'errorCallback should be a function, not a ' + typeof errorCallback
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
// we want to keep this function sync so we defer this promise to AWSS3UploadTask to resolve when it's needed
|
|
200
|
+
// when its doing a final check with _listSingleFile function
|
|
201
|
+
const prefixPromise: Promise<string> = Credentials.get().then(
|
|
202
|
+
(credentials: any) => {
|
|
203
|
+
const cred = Credentials.shear(credentials);
|
|
204
|
+
return getPrefix({
|
|
205
|
+
...config,
|
|
206
|
+
credentials: cred,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
const task = new AWSS3UploadTask({
|
|
212
|
+
s3Client,
|
|
213
|
+
file,
|
|
214
|
+
emitter,
|
|
215
|
+
level: config.level,
|
|
216
|
+
storage: this._storage,
|
|
217
|
+
params,
|
|
218
|
+
prefixPromise,
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
dispatchStorageEvent(
|
|
222
|
+
track,
|
|
223
|
+
'upload',
|
|
224
|
+
{ method: 'put', result: 'success' },
|
|
225
|
+
null,
|
|
226
|
+
`Upload Task created successfully for ${key}`
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
// automatically start the upload task
|
|
230
|
+
task.resume();
|
|
231
|
+
|
|
232
|
+
return task;
|
|
233
|
+
}
|
|
234
|
+
|
|
136
235
|
/**
|
|
137
236
|
* Copy an object from a source object to a new object within the same bucket. Can optionally copy files across
|
|
138
237
|
* different level or identityId (if source object's level is 'protected').
|
|
@@ -165,7 +264,11 @@ export class AWSS3Provider implements StorageProvider {
|
|
|
165
264
|
SSECustomerKeyMD5,
|
|
166
265
|
SSEKMSKeyId,
|
|
167
266
|
} = opt;
|
|
168
|
-
const {
|
|
267
|
+
const {
|
|
268
|
+
level: srcLevel = DEFAULT_STORAGE_LEVEL,
|
|
269
|
+
identityId: srcIdentityId,
|
|
270
|
+
key: srcKey,
|
|
271
|
+
} = src;
|
|
169
272
|
const { level: destLevel = DEFAULT_STORAGE_LEVEL, key: destKey } = dest;
|
|
170
273
|
if (!srcKey || typeof srcKey !== 'string') {
|
|
171
274
|
throw new Error(StorageErrorStrings.NO_SRC_KEY);
|
|
@@ -216,7 +319,6 @@ export class AWSS3Provider implements StorageProvider {
|
|
|
216
319
|
if (acl) params.ACL = acl;
|
|
217
320
|
|
|
218
321
|
const s3 = this._createNewS3Client(opt);
|
|
219
|
-
s3.middlewareStack.remove(SET_CONTENT_LENGTH_HEADER);
|
|
220
322
|
try {
|
|
221
323
|
await s3.send(new CopyObjectCommand(params));
|
|
222
324
|
dispatchStorageEvent(
|
|
@@ -261,7 +363,7 @@ export class AWSS3Provider implements StorageProvider {
|
|
|
261
363
|
): Promise<S3ProviderGetOuput<T>>;
|
|
262
364
|
public async get(
|
|
263
365
|
key: string,
|
|
264
|
-
config?: S3ProviderGetConfig
|
|
366
|
+
config?: S3ProviderGetConfig
|
|
265
367
|
): Promise<string | GetObjectCommandOutput> {
|
|
266
368
|
const credentialsOK = await this._ensureCredentials();
|
|
267
369
|
if (!credentialsOK || !this._isWithCredentials(this._config)) {
|
|
@@ -296,7 +398,8 @@ export class AWSS3Provider implements StorageProvider {
|
|
|
296
398
|
|
|
297
399
|
// See: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property
|
|
298
400
|
if (cacheControl) params.ResponseCacheControl = cacheControl;
|
|
299
|
-
if (contentDisposition)
|
|
401
|
+
if (contentDisposition)
|
|
402
|
+
params.ResponseContentDisposition = contentDisposition;
|
|
300
403
|
if (contentEncoding) params.ResponseContentEncoding = contentEncoding;
|
|
301
404
|
if (contentLanguage) params.ResponseContentLanguage = contentLanguage;
|
|
302
405
|
if (contentType) params.ResponseContentType = contentType;
|
|
@@ -319,7 +422,10 @@ export class AWSS3Provider implements StorageProvider {
|
|
|
319
422
|
progressCallback(progress);
|
|
320
423
|
});
|
|
321
424
|
} else {
|
|
322
|
-
logger.warn(
|
|
425
|
+
logger.warn(
|
|
426
|
+
'progressCallback should be a function, not a ' +
|
|
427
|
+
typeof progressCallback
|
|
428
|
+
);
|
|
323
429
|
}
|
|
324
430
|
}
|
|
325
431
|
const response = await s3.send(getObjectCommand);
|
|
@@ -353,8 +459,18 @@ export class AWSS3Provider implements StorageProvider {
|
|
|
353
459
|
const signer = new S3RequestPresigner({ ...s3.config });
|
|
354
460
|
const request = await createRequest(s3, new GetObjectCommand(params));
|
|
355
461
|
// Default is 15 mins as defined in V2 AWS SDK
|
|
356
|
-
const url = formatUrl(
|
|
357
|
-
|
|
462
|
+
const url = formatUrl(
|
|
463
|
+
await signer.presign(request, {
|
|
464
|
+
expiresIn: expires || DEFAULT_PRESIGN_EXPIRATION,
|
|
465
|
+
})
|
|
466
|
+
);
|
|
467
|
+
dispatchStorageEvent(
|
|
468
|
+
track,
|
|
469
|
+
'getSignedUrl',
|
|
470
|
+
{ method: 'get', result: 'success' },
|
|
471
|
+
null,
|
|
472
|
+
`Signed URL: ${url}`
|
|
473
|
+
);
|
|
358
474
|
return url;
|
|
359
475
|
} catch (error) {
|
|
360
476
|
logger.warn('get signed url error', error);
|
|
@@ -371,33 +487,41 @@ export class AWSS3Provider implements StorageProvider {
|
|
|
371
487
|
|
|
372
488
|
/**
|
|
373
489
|
* Put a file in S3 bucket specified to configure method
|
|
374
|
-
* @param
|
|
375
|
-
* @param
|
|
376
|
-
* @param
|
|
377
|
-
* @return
|
|
490
|
+
* @param key - key of the object
|
|
491
|
+
* @param object - File to be put in Amazon S3 bucket
|
|
492
|
+
* @param [config] - Optional configuration for the underlying S3 command
|
|
493
|
+
* @return an instance of AWSS3UploadTask or a promise that resolves to an object with the new object's key on
|
|
494
|
+
* success.
|
|
378
495
|
*/
|
|
379
|
-
public
|
|
496
|
+
public put<T extends S3ProviderPutConfig>(
|
|
380
497
|
key: string,
|
|
381
498
|
object: PutObjectCommandInput['Body'],
|
|
382
|
-
config?:
|
|
383
|
-
):
|
|
384
|
-
const credentialsOK = await this._ensureCredentials();
|
|
385
|
-
if (!credentialsOK || !this._isWithCredentials(this._config)) {
|
|
386
|
-
throw new Error(StorageErrorStrings.NO_CREDENTIALS);
|
|
387
|
-
}
|
|
499
|
+
config?: T
|
|
500
|
+
): S3ProviderPutOutput<T> {
|
|
388
501
|
const opt = Object.assign({}, this._config, config);
|
|
389
|
-
const { bucket, track, progressCallback } = opt;
|
|
390
|
-
const {
|
|
391
|
-
|
|
502
|
+
const { bucket, track, progressCallback, level, resumable } = opt;
|
|
503
|
+
const {
|
|
504
|
+
contentType,
|
|
505
|
+
contentDisposition,
|
|
506
|
+
contentEncoding,
|
|
507
|
+
cacheControl,
|
|
508
|
+
expires,
|
|
509
|
+
metadata,
|
|
510
|
+
tagging,
|
|
511
|
+
acl,
|
|
512
|
+
} = opt;
|
|
513
|
+
const {
|
|
514
|
+
serverSideEncryption,
|
|
515
|
+
SSECustomerAlgorithm,
|
|
516
|
+
SSECustomerKey,
|
|
517
|
+
SSECustomerKeyMD5,
|
|
518
|
+
SSEKMSKeyId,
|
|
519
|
+
} = opt;
|
|
392
520
|
const type = contentType ? contentType : 'binary/octet-stream';
|
|
393
521
|
|
|
394
|
-
const prefix = this._prefix(opt);
|
|
395
|
-
const final_key = prefix + key;
|
|
396
|
-
logger.debug('put ' + key + ' to ' + final_key);
|
|
397
|
-
|
|
398
522
|
const params: PutObjectCommandInput = {
|
|
399
523
|
Bucket: bucket,
|
|
400
|
-
Key:
|
|
524
|
+
Key: key,
|
|
401
525
|
Body: object,
|
|
402
526
|
ContentType: type,
|
|
403
527
|
};
|
|
@@ -442,6 +566,30 @@ export class AWSS3Provider implements StorageProvider {
|
|
|
442
566
|
params.ACL = acl;
|
|
443
567
|
}
|
|
444
568
|
|
|
569
|
+
if (resumable === true) {
|
|
570
|
+
const s3Client = this._createNewS3Client(opt);
|
|
571
|
+
// we are using aws sdk middleware to inject the prefix to key, this way we don't have to call
|
|
572
|
+
// this._ensureCredentials() which allows us to make this function sync so we can return non-Promise like UploadTask
|
|
573
|
+
s3Client.middlewareStack.add(
|
|
574
|
+
createPrefixMiddleware(opt, key),
|
|
575
|
+
prefixMiddlewareOptions
|
|
576
|
+
);
|
|
577
|
+
const addTaskInput: AddTaskInput = {
|
|
578
|
+
bucket,
|
|
579
|
+
key,
|
|
580
|
+
s3Client,
|
|
581
|
+
file: object as Blob,
|
|
582
|
+
emitter,
|
|
583
|
+
accessLevel: level,
|
|
584
|
+
params,
|
|
585
|
+
};
|
|
586
|
+
// explicitly asserting the type here as Typescript could not infer that resumable is of type true
|
|
587
|
+
return this.startResumableUpload(
|
|
588
|
+
addTaskInput,
|
|
589
|
+
config as typeof config & { resumable: true }
|
|
590
|
+
) as S3ProviderPutOutput<T>;
|
|
591
|
+
}
|
|
592
|
+
|
|
445
593
|
try {
|
|
446
594
|
if (progressCallback) {
|
|
447
595
|
if (typeof progressCallback === 'function') {
|
|
@@ -449,20 +597,33 @@ export class AWSS3Provider implements StorageProvider {
|
|
|
449
597
|
progressCallback(progress);
|
|
450
598
|
});
|
|
451
599
|
} else {
|
|
452
|
-
logger.warn(
|
|
600
|
+
logger.warn(
|
|
601
|
+
'progressCallback should be a function, not a ' +
|
|
602
|
+
typeof progressCallback
|
|
603
|
+
);
|
|
453
604
|
}
|
|
454
605
|
}
|
|
455
606
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
607
|
+
return uploader.upload().then(response => {
|
|
608
|
+
logger.debug('upload result', response);
|
|
609
|
+
dispatchStorageEvent(
|
|
610
|
+
track,
|
|
611
|
+
'upload',
|
|
612
|
+
{ method: 'put', result: 'success' },
|
|
613
|
+
null,
|
|
614
|
+
`Upload success for ${key}`
|
|
615
|
+
);
|
|
616
|
+
return { key };
|
|
617
|
+
}) as S3ProviderPutOutput<T>;
|
|
463
618
|
} catch (error) {
|
|
464
619
|
logger.warn('error uploading', error);
|
|
465
|
-
dispatchStorageEvent(
|
|
620
|
+
dispatchStorageEvent(
|
|
621
|
+
track,
|
|
622
|
+
'upload',
|
|
623
|
+
{ method: 'put', result: 'failed' },
|
|
624
|
+
null,
|
|
625
|
+
`Error uploading ${key}`
|
|
626
|
+
);
|
|
466
627
|
throw error;
|
|
467
628
|
}
|
|
468
629
|
}
|
|
@@ -473,7 +634,10 @@ export class AWSS3Provider implements StorageProvider {
|
|
|
473
634
|
* @param {S3ProviderRemoveConfig} [config] - Optional configuration for the underlying S3 command
|
|
474
635
|
* @return {Promise<S3ProviderRemoveOutput>} - Promise resolves upon successful removal of the object
|
|
475
636
|
*/
|
|
476
|
-
public async remove(
|
|
637
|
+
public async remove(
|
|
638
|
+
key: string,
|
|
639
|
+
config?: S3ProviderRemoveConfig
|
|
640
|
+
): Promise<S3ProviderRemoveOutput> {
|
|
477
641
|
const credentialsOK = await this._ensureCredentials();
|
|
478
642
|
if (!credentialsOK || !this._isWithCredentials(this._config)) {
|
|
479
643
|
throw new Error(StorageErrorStrings.NO_CREDENTIALS);
|
|
@@ -522,7 +686,10 @@ export class AWSS3Provider implements StorageProvider {
|
|
|
522
686
|
* @return {Promise<S3ProviderListOutput>} - Promise resolves to list of keys, eTags, lastModified and file size for
|
|
523
687
|
* all objects in path
|
|
524
688
|
*/
|
|
525
|
-
public async list(
|
|
689
|
+
public async list(
|
|
690
|
+
path: string,
|
|
691
|
+
config?: S3ProviderListConfig
|
|
692
|
+
): Promise<S3ProviderListOutput> {
|
|
526
693
|
const credentialsOK = await this._ensureCredentials();
|
|
527
694
|
if (!credentialsOK || !this._isWithCredentials(this._config)) {
|
|
528
695
|
throw new Error(StorageErrorStrings.NO_CREDENTIALS);
|
|
@@ -593,7 +760,9 @@ export class AWSS3Provider implements StorageProvider {
|
|
|
593
760
|
}
|
|
594
761
|
}
|
|
595
762
|
|
|
596
|
-
private _isWithCredentials(
|
|
763
|
+
private _isWithCredentials(
|
|
764
|
+
config: StorageOptions
|
|
765
|
+
): config is StorageOptions & { credentials: ICredentials } {
|
|
597
766
|
return typeof config === 'object' && config.hasOwnProperty('credentials');
|
|
598
767
|
}
|
|
599
768
|
|
|
@@ -607,10 +776,18 @@ export class AWSS3Provider implements StorageProvider {
|
|
|
607
776
|
|
|
608
777
|
const customPrefix = config.customPrefix || {};
|
|
609
778
|
const identityId = config.identityId || credentials.identityId;
|
|
610
|
-
const privatePath =
|
|
779
|
+
const privatePath =
|
|
780
|
+
(customPrefix.private !== undefined ? customPrefix.private : 'private/') +
|
|
781
|
+
identityId +
|
|
782
|
+
'/';
|
|
611
783
|
const protectedPath =
|
|
612
|
-
(customPrefix.protected !== undefined
|
|
613
|
-
|
|
784
|
+
(customPrefix.protected !== undefined
|
|
785
|
+
? customPrefix.protected
|
|
786
|
+
: 'protected/') +
|
|
787
|
+
identityId +
|
|
788
|
+
'/';
|
|
789
|
+
const publicPath =
|
|
790
|
+
customPrefix.public !== undefined ? customPrefix.public : 'public/';
|
|
614
791
|
|
|
615
792
|
switch (level) {
|
|
616
793
|
case 'private':
|
|
@@ -627,32 +804,18 @@ export class AWSS3Provider implements StorageProvider {
|
|
|
627
804
|
*/
|
|
628
805
|
private _createNewS3Client(
|
|
629
806
|
config: {
|
|
630
|
-
credentials: ICredentials;
|
|
631
807
|
region?: string;
|
|
632
808
|
cancelTokenSource?: CancelTokenSource;
|
|
633
809
|
dangerouslyConnectToHttpEndpointForTesting?: boolean;
|
|
810
|
+
useAccelerateEndpoint?: boolean;
|
|
634
811
|
},
|
|
635
812
|
emitter?: events.EventEmitter
|
|
636
813
|
): S3Client {
|
|
637
|
-
const
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
endpoint: localTestingStorageEndpoint,
|
|
643
|
-
tls: false,
|
|
644
|
-
bucketEndpoint: false,
|
|
645
|
-
forcePathStyle: true,
|
|
646
|
-
};
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
const s3client = new S3Client({
|
|
650
|
-
region,
|
|
651
|
-
credentials,
|
|
652
|
-
customUserAgent: getAmplifyUserAgent(),
|
|
653
|
-
...localTestingConfig,
|
|
654
|
-
requestHandler: new AxiosHttpHandler({}, emitter, cancelTokenSource),
|
|
655
|
-
});
|
|
814
|
+
const s3client = createS3Client(config, emitter);
|
|
815
|
+
s3client.middlewareStack.add(
|
|
816
|
+
autoAdjustClockskewMiddleware(s3client.config),
|
|
817
|
+
autoAdjustClockskewMiddlewareOptions
|
|
818
|
+
);
|
|
656
819
|
return s3client;
|
|
657
820
|
}
|
|
658
821
|
}
|