Skip to content

Commit 0089b2f

Browse files
authored
chore(lib-storage): narrow types in Upload (#3597)
1 parent 39573c4 commit 0089b2f

File tree

3 files changed

+45
-39
lines changed

3 files changed

+45
-39
lines changed

lib/lib-storage/README.md

+24-22
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,28 @@
88
Upload allows for easy and efficient uploading of buffers, blobs, or streams, using a configurable amount of concurrency to perform multipart uploads where possible. This abstraction enables uploading large files or streams of unknown size due to the use of multipart uploads under the hood.
99

1010
```js
11-
import { Upload } from "@aws-sdk/lib-storage";
12-
import { S3Client, S3 } from "@aws-sdk/client-s3";
13-
14-
const target = { Bucket, Key, Body };
15-
try {
16-
const parallelUploads3 = new Upload({
17-
client: new S3({}) || new S3Client({}),
18-
tags: [...], // optional tags
19-
queueSize: 4, // optional concurrency configuration
20-
partSize: 5MB, // optional size of each part
21-
leavePartsOnError: false, // optional manually handle dropped parts
22-
params: target,
23-
});
24-
25-
parallelUploads3.on("httpUploadProgress", (progress) => {
26-
console.log(progress);
27-
});
28-
29-
await parallelUploads3.done();
30-
} catch (e) {
31-
console.log(e);
32-
}
11+
import { Upload } from "@aws-sdk/lib-storage";
12+
import { S3Client, S3 } from "@aws-sdk/client-s3";
13+
14+
try {
15+
const parallelUploads3 = new Upload({
16+
client: new S3({}) || new S3Client({}),
17+
params: { Bucket, Key, Body },
18+
19+
tags: [
20+
/*...*/
21+
], // optional tags
22+
queueSize: 4, // optional concurrency configuration
23+
partSize: 1024 * 1024 * 5, // optional size of each part, in bytes, at least 5MB
24+
leavePartsOnError: false, // optional manually handle dropped parts
25+
});
26+
27+
parallelUploads3.on("httpUploadProgress", (progress) => {
28+
console.log(progress);
29+
});
30+
31+
await parallelUploads3.done();
32+
} catch (e) {
33+
console.log(e);
34+
}
3335
```

lib/lib-storage/src/Upload.ts

+17-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { AbortController, AbortSignal } from "@aws-sdk/abort-controller";
22
import {
3+
AbortMultipartUploadCommandOutput,
34
CompletedPart,
45
CompleteMultipartUploadCommand,
56
CompleteMultipartUploadCommandOutput,
@@ -8,7 +9,7 @@ import {
89
PutObjectCommand,
910
PutObjectCommandInput,
1011
PutObjectTaggingCommand,
11-
ServiceOutputTypes,
12+
S3Client,
1213
Tag,
1314
UploadPartCommand,
1415
} from "@aws-sdk/client-s3";
@@ -17,7 +18,7 @@ import { EventEmitter } from "events";
1718

1819
import { byteLength } from "./bytelength";
1920
import { getChunk } from "./chunker";
20-
import { BodyDataTypes, Options, Progress, ServiceClients } from "./types";
21+
import { BodyDataTypes, Options, Progress } from "./types";
2122

2223
export interface RawDataPart {
2324
partNumber: number;
@@ -39,7 +40,7 @@ export class Upload extends EventEmitter {
3940
private leavePartsOnError = false;
4041
private tags: Tag[] = [];
4142

42-
private client: ServiceClients;
43+
private client: S3Client;
4344
private params: PutObjectCommandInput;
4445

4546
// used for reporting progress.
@@ -56,7 +57,7 @@ export class Upload extends EventEmitter {
5657
uploadEvent?: string;
5758

5859
private isMultiPart = true;
59-
private putResponse?: CompleteMultipartUploadCommandOutput;
60+
private singleUploadResult?: CompleteMultipartUploadCommandOutput;
6061

6162
constructor(options: Options) {
6263
super();
@@ -86,16 +87,16 @@ export class Upload extends EventEmitter {
8687
this.abortController.abort();
8788
}
8889

89-
async done(): Promise<ServiceOutputTypes> {
90+
public async done(): Promise<CompleteMultipartUploadCommandOutput | AbortMultipartUploadCommandOutput> {
9091
return await Promise.race([this.__doMultipartUpload(), this.__abortTimeout(this.abortController.signal)]);
9192
}
9293

93-
on(event: "httpUploadProgress", listener: (progress: Progress) => void): any {
94+
public on(event: "httpUploadProgress", listener: (progress: Progress) => void): this {
9495
this.uploadEvent = event;
95-
super.on(event, listener);
96+
return super.on(event, listener);
9697
}
9798

98-
async __uploadUsingPut(dataPart: RawDataPart) {
99+
private async __uploadUsingPut(dataPart: RawDataPart): Promise<void> {
99100
this.isMultiPart = false;
100101
const params = { ...this.params, Body: dataPart.data };
101102
const [putResult, endpoint] = await Promise.all([
@@ -113,7 +114,7 @@ export class Upload extends EventEmitter {
113114
? `${endpoint.protocol}//${endpoint.hostname}/${locationBucket}/${locationKey}`
114115
: `${endpoint.protocol}//${locationBucket}.${endpoint.hostname}/${locationKey}`;
115116

116-
this.putResponse = {
117+
this.singleUploadResult = {
117118
...putResult,
118119
Bucket: this.params.Bucket,
119120
Key: this.params.Key,
@@ -129,7 +130,7 @@ export class Upload extends EventEmitter {
129130
});
130131
}
131132

132-
async __createMultipartUpload() {
133+
private async __createMultipartUpload(): Promise<void> {
133134
if (!this.createMultiPartPromise) {
134135
const createCommandParams = { ...this.params, Body: undefined };
135136
this.createMultiPartPromise = this.client.send(new CreateMultipartUploadCommand(createCommandParams));
@@ -138,7 +139,7 @@ export class Upload extends EventEmitter {
138139
this.uploadId = createMultipartUploadResult.UploadId;
139140
}
140141

141-
async __doConcurrentUpload(dataFeeder: AsyncGenerator<RawDataPart, void, undefined>): Promise<void> {
142+
private async __doConcurrentUpload(dataFeeder: AsyncGenerator<RawDataPart, void, undefined>): Promise<void> {
142143
for await (const dataPart of dataFeeder) {
143144
if (this.uploadedParts.length > this.MAX_PARTS) {
144145
throw new Error(
@@ -207,7 +208,7 @@ export class Upload extends EventEmitter {
207208
}
208209
}
209210

210-
async __doMultipartUpload(): Promise<ServiceOutputTypes> {
211+
private async __doMultipartUpload(): Promise<CompleteMultipartUploadCommandOutput> {
211212
// Set up data input chunks.
212213
const dataFeeder = getChunk(this.params.Body, this.partSize);
213214

@@ -237,7 +238,7 @@ export class Upload extends EventEmitter {
237238
};
238239
result = await this.client.send(new CompleteMultipartUploadCommand(uploadCompleteParams));
239240
} else {
240-
result = this.putResponse!;
241+
result = this.singleUploadResult!;
241242
}
242243

243244
// Add tags to the object after it's completed the upload.
@@ -255,13 +256,13 @@ export class Upload extends EventEmitter {
255256
return result;
256257
}
257258

258-
__notifyProgress(progress: Progress) {
259+
private __notifyProgress(progress: Progress): void {
259260
if (this.uploadEvent) {
260261
this.emit(this.uploadEvent, progress);
261262
}
262263
}
263264

264-
async __abortTimeout(abortSignal: AbortSignal): Promise<ServiceOutputTypes> {
265+
private async __abortTimeout(abortSignal: AbortSignal): Promise<AbortMultipartUploadCommandOutput> {
265266
return new Promise((resolve, reject) => {
266267
abortSignal.onabort = () => {
267268
const abortError = new Error("Upload aborted.");
@@ -271,7 +272,7 @@ export class Upload extends EventEmitter {
271272
});
272273
}
273274

274-
__validateInput() {
275+
private __validateInput(): void {
275276
if (!this.params) {
276277
throw new Error(`InputError: Upload requires params to be passed to upload.`);
277278
}

lib/lib-storage/src/types.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ export interface Progress {
1111
// string | Uint8Array | Buffer | Readable | ReadableStream | Blob.
1212
export type BodyDataTypes = PutObjectCommandInput["Body"];
1313

14+
/**
15+
* @deprecated redundant, use {@link S3Client} directly.
16+
*/
1417
export type ServiceClients = S3Client;
1518

1619
export interface Configuration {
@@ -49,5 +52,5 @@ export interface Options extends Partial<Configuration> {
4952
* A service client.
5053
* This the target where we upload data.
5154
*/
52-
client: ServiceClients;
55+
client: S3Client;
5356
}

0 commit comments

Comments
 (0)