@aws-sdk/lib-storage 3.894.0 → 3.896.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,16 @@ 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();
219
218
  this.totalBytes = byteLength(this.params.Body);
220
219
  this.bytesUploadedSoFar = 0;
221
220
  this.abortController = options.abortController ?? new import_abort_controller.AbortController();
221
+ this.partSize = Math.max(_Upload.MIN_PART_SIZE, Math.floor((this.totalBytes || 0) / this.MAX_PARTS));
222
+ this.expectedPartsCount = this.totalBytes !== void 0 ? Math.ceil(this.totalBytes / this.partSize) : void 0;
223
+ this.__validateInput();
222
224
  }
223
225
  async abort() {
224
226
  this.abortController.abort();
@@ -364,6 +366,7 @@ var Upload = class _Upload extends import_events.EventEmitter {
364
366
  eventEmitter.on("xhr.upload.progress", uploadEventListener);
365
367
  }
366
368
  this.uploadEnqueuedPartsCount += 1;
369
+ this.__validateUploadPart(dataPart);
367
370
  const partResult = await this.client.send(
368
371
  new import_client_s3.UploadPartCommand({
369
372
  ...this.params,
@@ -426,6 +429,10 @@ var Upload = class _Upload extends import_events.EventEmitter {
426
429
  }
427
430
  let result;
428
431
  if (this.isMultiPart) {
432
+ const { expectedPartsCount, uploadedParts } = this;
433
+ if (expectedPartsCount !== void 0 && uploadedParts.length !== expectedPartsCount) {
434
+ throw new Error(`Expected ${expectedPartsCount} part(s) but uploaded ${uploadedParts.length} part(s).`);
435
+ }
429
436
  this.uploadedParts.sort((a, b) => a.PartNumber - b.PartNumber);
430
437
  const uploadCompleteParams = {
431
438
  ...this.params,
@@ -480,6 +487,22 @@ var Upload = class _Upload extends import_events.EventEmitter {
480
487
  };
481
488
  });
482
489
  }
490
+ __validateUploadPart(dataPart) {
491
+ const actualPartSize = byteLength(dataPart.data);
492
+ if (actualPartSize === void 0) {
493
+ throw new Error(
494
+ `A dataPart was generated without a measurable data chunk size for part number ${dataPart.partNumber}`
495
+ );
496
+ }
497
+ if (dataPart.partNumber === 1 && dataPart.lastPart) {
498
+ return;
499
+ }
500
+ if (!dataPart.lastPart && actualPartSize !== this.partSize) {
501
+ throw new Error(
502
+ `The byte size for part number ${dataPart.partNumber}, size ${actualPartSize} does not match expected size ${this.partSize}`
503
+ );
504
+ }
505
+ }
483
506
  __validateInput() {
484
507
  if (!this.params) {
485
508
  throw new Error(`InputError: Upload requires params to be passed to upload.`);
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,16 @@ 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();
39
38
  this.totalBytes = byteLength(this.params.Body);
40
39
  this.bytesUploadedSoFar = 0;
41
40
  this.abortController = options.abortController ?? new AbortController();
41
+ this.partSize = Math.max(Upload.MIN_PART_SIZE, Math.floor((this.totalBytes || 0) / this.MAX_PARTS));
42
+ this.expectedPartsCount = this.totalBytes !== undefined ? Math.ceil(this.totalBytes / this.partSize) : undefined;
43
+ this.__validateInput();
42
44
  }
43
45
  async abort() {
44
46
  this.abortController.abort();
@@ -183,6 +185,7 @@ export class Upload extends EventEmitter {
183
185
  eventEmitter.on("xhr.upload.progress", uploadEventListener);
184
186
  }
185
187
  this.uploadEnqueuedPartsCount += 1;
188
+ this.__validateUploadPart(dataPart);
186
189
  const partResult = await this.client.send(new UploadPartCommand({
187
190
  ...this.params,
188
191
  ContentLength: undefined,
@@ -239,6 +242,10 @@ export class Upload extends EventEmitter {
239
242
  }
240
243
  let result;
241
244
  if (this.isMultiPart) {
245
+ const { expectedPartsCount, uploadedParts } = this;
246
+ if (expectedPartsCount !== undefined && uploadedParts.length !== expectedPartsCount) {
247
+ throw new Error(`Expected ${expectedPartsCount} part(s) but uploaded ${uploadedParts.length} part(s).`);
248
+ }
242
249
  this.uploadedParts.sort((a, b) => a.PartNumber - b.PartNumber);
243
250
  const uploadCompleteParams = {
244
251
  ...this.params,
@@ -287,6 +294,18 @@ export class Upload extends EventEmitter {
287
294
  };
288
295
  });
289
296
  }
297
+ __validateUploadPart(dataPart) {
298
+ const actualPartSize = byteLength(dataPart.data);
299
+ if (actualPartSize === undefined) {
300
+ throw new Error(`A dataPart was generated without a measurable data chunk size for part number ${dataPart.partNumber}`);
301
+ }
302
+ if (dataPart.partNumber === 1 && dataPart.lastPart) {
303
+ return;
304
+ }
305
+ if (!dataPart.lastPart && actualPartSize !== this.partSize) {
306
+ throw new Error(`The byte size for part number ${dataPart.partNumber}, size ${actualPartSize} does not match expected size ${this.partSize}`);
307
+ }
308
+ }
290
309
  __validateInput() {
291
310
  if (!this.params) {
292
311
  throw new Error(`InputError: Upload requires params to be passed to upload.`);
@@ -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.894.0",
3
+ "version": "3.896.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.4",
33
+ "@smithy/smithy-client": "^4.6.4",
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.894.0"
40
+ "@aws-sdk/client-s3": "^3.896.0"
41
41
  },
42
42
  "devDependencies": {
43
- "@aws-sdk/client-s3": "3.894.0",
43
+ "@aws-sdk/client-s3": "3.896.0",
44
44
  "@smithy/types": "^4.5.0",
45
45
  "@tsconfig/recommended": "1.0.1",
46
46
  "@types/node": "^18.19.69",