@aws-sdk/lib-storage 3.895.0 → 3.899.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/dist-cjs/index.js CHANGED
@@ -184,7 +184,7 @@ var Upload = class _Upload extends import_events.EventEmitter {
184
184
  MAX_PARTS = 1e4;
185
185
  // Defaults.
186
186
  queueSize = 4;
187
- partSize = _Upload.MIN_PART_SIZE;
187
+ partSize;
188
188
  leavePartsOnError = false;
189
189
  tags = [];
190
190
  client;
@@ -199,6 +199,7 @@ var Upload = class _Upload extends import_events.EventEmitter {
199
199
  abortMultipartUploadCommand = null;
200
200
  uploadedParts = [];
201
201
  uploadEnqueuedPartsCount = 0;
202
+ expectedPartsCount;
202
203
  /**
203
204
  * Last UploadId if the upload was done with MultipartUpload and not PutObject.
204
205
  */
@@ -210,15 +211,19 @@ var Upload = class _Upload extends import_events.EventEmitter {
210
211
  constructor(options) {
211
212
  super();
212
213
  this.queueSize = options.queueSize || this.queueSize;
213
- this.partSize = options.partSize || this.partSize;
214
214
  this.leavePartsOnError = options.leavePartsOnError || this.leavePartsOnError;
215
215
  this.tags = options.tags || this.tags;
216
216
  this.client = options.client;
217
217
  this.params = options.params;
218
- this.__validateInput();
218
+ if (!this.params) {
219
+ throw new Error(`InputError: Upload requires params to be passed to upload.`);
220
+ }
219
221
  this.totalBytes = byteLength(this.params.Body);
220
222
  this.bytesUploadedSoFar = 0;
221
223
  this.abortController = options.abortController ?? new import_abort_controller.AbortController();
224
+ this.partSize = options.partSize || Math.max(_Upload.MIN_PART_SIZE, Math.floor((this.totalBytes || 0) / this.MAX_PARTS));
225
+ this.expectedPartsCount = this.totalBytes !== void 0 ? Math.ceil(this.totalBytes / this.partSize) : void 0;
226
+ this.__validateInput();
222
227
  }
223
228
  async abort() {
224
229
  this.abortController.abort();
@@ -364,6 +369,7 @@ var Upload = class _Upload extends import_events.EventEmitter {
364
369
  eventEmitter.on("xhr.upload.progress", uploadEventListener);
365
370
  }
366
371
  this.uploadEnqueuedPartsCount += 1;
372
+ this.__validateUploadPart(dataPart);
367
373
  const partResult = await this.client.send(
368
374
  new import_client_s3.UploadPartCommand({
369
375
  ...this.params,
@@ -426,6 +432,10 @@ var Upload = class _Upload extends import_events.EventEmitter {
426
432
  }
427
433
  let result;
428
434
  if (this.isMultiPart) {
435
+ const { expectedPartsCount, uploadedParts } = this;
436
+ if (expectedPartsCount !== void 0 && uploadedParts.length !== expectedPartsCount) {
437
+ throw new Error(`Expected ${expectedPartsCount} part(s) but uploaded ${uploadedParts.length} part(s).`);
438
+ }
429
439
  this.uploadedParts.sort((a, b) => a.PartNumber - b.PartNumber);
430
440
  const uploadCompleteParams = {
431
441
  ...this.params,
@@ -480,10 +490,23 @@ var Upload = class _Upload extends import_events.EventEmitter {
480
490
  };
481
491
  });
482
492
  }
483
- __validateInput() {
484
- if (!this.params) {
485
- throw new Error(`InputError: Upload requires params to be passed to upload.`);
493
+ __validateUploadPart(dataPart) {
494
+ const actualPartSize = byteLength(dataPart.data);
495
+ if (actualPartSize === void 0) {
496
+ throw new Error(
497
+ `A dataPart was generated without a measurable data chunk size for part number ${dataPart.partNumber}`
498
+ );
499
+ }
500
+ if (dataPart.partNumber === 1 && dataPart.lastPart) {
501
+ return;
502
+ }
503
+ if (!dataPart.lastPart && actualPartSize !== this.partSize) {
504
+ throw new Error(
505
+ `The byte size for part number ${dataPart.partNumber}, size ${actualPartSize} does not match expected size ${this.partSize}`
506
+ );
486
507
  }
508
+ }
509
+ __validateInput() {
487
510
  if (!this.client) {
488
511
  throw new Error(`InputError: Upload requires a AWS client to do uploads with.`);
489
512
  }
package/dist-es/Upload.js CHANGED
@@ -9,7 +9,7 @@ export class Upload extends EventEmitter {
9
9
  static MIN_PART_SIZE = 1024 * 1024 * 5;
10
10
  MAX_PARTS = 10_000;
11
11
  queueSize = 4;
12
- partSize = Upload.MIN_PART_SIZE;
12
+ partSize;
13
13
  leavePartsOnError = false;
14
14
  tags = [];
15
15
  client;
@@ -22,6 +22,7 @@ export class Upload extends EventEmitter {
22
22
  abortMultipartUploadCommand = null;
23
23
  uploadedParts = [];
24
24
  uploadEnqueuedPartsCount = 0;
25
+ expectedPartsCount;
25
26
  uploadId;
26
27
  uploadEvent;
27
28
  isMultiPart = true;
@@ -30,15 +31,20 @@ export class Upload extends EventEmitter {
30
31
  constructor(options) {
31
32
  super();
32
33
  this.queueSize = options.queueSize || this.queueSize;
33
- this.partSize = options.partSize || this.partSize;
34
34
  this.leavePartsOnError = options.leavePartsOnError || this.leavePartsOnError;
35
35
  this.tags = options.tags || this.tags;
36
36
  this.client = options.client;
37
37
  this.params = options.params;
38
- this.__validateInput();
38
+ if (!this.params) {
39
+ throw new Error(`InputError: Upload requires params to be passed to upload.`);
40
+ }
39
41
  this.totalBytes = byteLength(this.params.Body);
40
42
  this.bytesUploadedSoFar = 0;
41
43
  this.abortController = options.abortController ?? new AbortController();
44
+ this.partSize =
45
+ options.partSize || Math.max(Upload.MIN_PART_SIZE, Math.floor((this.totalBytes || 0) / this.MAX_PARTS));
46
+ this.expectedPartsCount = this.totalBytes !== undefined ? Math.ceil(this.totalBytes / this.partSize) : undefined;
47
+ this.__validateInput();
42
48
  }
43
49
  async abort() {
44
50
  this.abortController.abort();
@@ -183,6 +189,7 @@ export class Upload extends EventEmitter {
183
189
  eventEmitter.on("xhr.upload.progress", uploadEventListener);
184
190
  }
185
191
  this.uploadEnqueuedPartsCount += 1;
192
+ this.__validateUploadPart(dataPart);
186
193
  const partResult = await this.client.send(new UploadPartCommand({
187
194
  ...this.params,
188
195
  ContentLength: undefined,
@@ -239,6 +246,10 @@ export class Upload extends EventEmitter {
239
246
  }
240
247
  let result;
241
248
  if (this.isMultiPart) {
249
+ const { expectedPartsCount, uploadedParts } = this;
250
+ if (expectedPartsCount !== undefined && uploadedParts.length !== expectedPartsCount) {
251
+ throw new Error(`Expected ${expectedPartsCount} part(s) but uploaded ${uploadedParts.length} part(s).`);
252
+ }
242
253
  this.uploadedParts.sort((a, b) => a.PartNumber - b.PartNumber);
243
254
  const uploadCompleteParams = {
244
255
  ...this.params,
@@ -287,10 +298,19 @@ export class Upload extends EventEmitter {
287
298
  };
288
299
  });
289
300
  }
290
- __validateInput() {
291
- if (!this.params) {
292
- throw new Error(`InputError: Upload requires params to be passed to upload.`);
301
+ __validateUploadPart(dataPart) {
302
+ const actualPartSize = byteLength(dataPart.data);
303
+ if (actualPartSize === undefined) {
304
+ throw new Error(`A dataPart was generated without a measurable data chunk size for part number ${dataPart.partNumber}`);
305
+ }
306
+ if (dataPart.partNumber === 1 && dataPart.lastPart) {
307
+ return;
293
308
  }
309
+ if (!dataPart.lastPart && actualPartSize !== this.partSize) {
310
+ throw new Error(`The byte size for part number ${dataPart.partNumber}, size ${actualPartSize} does not match expected size ${this.partSize}`);
311
+ }
312
+ }
313
+ __validateInput() {
294
314
  if (!this.client) {
295
315
  throw new Error(`InputError: Upload requires a AWS client to do uploads with.`);
296
316
  }
@@ -30,6 +30,7 @@ export declare class Upload extends EventEmitter {
30
30
  private abortMultipartUploadCommand;
31
31
  private uploadedParts;
32
32
  private uploadEnqueuedPartsCount;
33
+ private expectedPartsCount?;
33
34
  /**
34
35
  * Last UploadId if the upload was done with MultipartUpload and not PutObject.
35
36
  */
@@ -54,5 +55,6 @@ export declare class Upload extends EventEmitter {
54
55
  private markUploadAsAborted;
55
56
  private __notifyProgress;
56
57
  private __abortTimeout;
58
+ private __validateUploadPart;
57
59
  private __validateInput;
58
60
  }
@@ -23,6 +23,7 @@ export declare class Upload extends EventEmitter {
23
23
  private abortMultipartUploadCommand;
24
24
  private uploadedParts;
25
25
  private uploadEnqueuedPartsCount;
26
+ private expectedPartsCount?;
26
27
  uploadId?: string;
27
28
  uploadEvent?: string;
28
29
  private isMultiPart;
@@ -39,5 +40,6 @@ export declare class Upload extends EventEmitter {
39
40
  private markUploadAsAborted;
40
41
  private __notifyProgress;
41
42
  private __abortTimeout;
43
+ private __validateUploadPart;
42
44
  private __validateInput;
43
45
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aws-sdk/lib-storage",
3
- "version": "3.895.0",
3
+ "version": "3.899.0",
4
4
  "description": "Storage higher order operation",
5
5
  "main": "./dist-cjs/index.js",
6
6
  "module": "./dist-es/index.js",
@@ -29,18 +29,18 @@
29
29
  "license": "Apache-2.0",
30
30
  "dependencies": {
31
31
  "@smithy/abort-controller": "^4.1.1",
32
- "@smithy/middleware-endpoint": "^4.2.3",
33
- "@smithy/smithy-client": "^4.6.3",
32
+ "@smithy/middleware-endpoint": "^4.2.5",
33
+ "@smithy/smithy-client": "^4.6.5",
34
34
  "buffer": "5.6.0",
35
35
  "events": "3.3.0",
36
36
  "stream-browserify": "3.0.0",
37
37
  "tslib": "^2.6.2"
38
38
  },
39
39
  "peerDependencies": {
40
- "@aws-sdk/client-s3": "^3.895.0"
40
+ "@aws-sdk/client-s3": "^3.899.0"
41
41
  },
42
42
  "devDependencies": {
43
- "@aws-sdk/client-s3": "3.895.0",
43
+ "@aws-sdk/client-s3": "3.899.0",
44
44
  "@smithy/types": "^4.5.0",
45
45
  "@tsconfig/recommended": "1.0.1",
46
46
  "@types/node": "^18.19.69",