Skip to content

Commit bf820e4

Browse files
committed
refactor: migrate downloading logic
1 parent 9b7b51d commit bf820e4

File tree

2 files changed

+22
-43
lines changed

2 files changed

+22
-43
lines changed

packages/core/src/shared/clients/s3.ts

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,22 @@ import { getLogger } from '../logger/logger'
1212
import { bufferToStream, DefaultFileStreams, FileStreams, pipe } from '../utilities/streamUtilities'
1313
import { assertHasProps, InterfaceNoSymbol, isNonNullable, RequiredProps } from '../utilities/tsUtils'
1414
import { Readable } from 'stream'
15-
import globals from '../extensionGlobals'
15+
import globals, { isWeb } from '../extensionGlobals'
1616
import { defaultPartition } from '../regions/regionProvider'
1717
import { AsyncCollection, toCollection } from '../utilities/asyncCollection'
1818
import { toStream } from '../utilities/collectionUtils'
1919
import {
2020
BucketLocationConstraint,
2121
CreateBucketCommand,
2222
DeleteBucketCommand,
23+
GetObjectCommand,
24+
GetObjectCommandInput,
25+
GetObjectCommandOutput,
2326
PutObjectCommand,
2427
S3Client as S3ClientSDK,
2528
} from '@aws-sdk/client-s3'
2629
import { ClientWrapper } from './clientWrapper'
30+
import { ToolkitError } from '../errors'
2731

2832
export const DEFAULT_MAX_KEYS = 300 // eslint-disable-line @typescript-eslint/naming-convention
2933
export const DEFAULT_DELIMITER = '/' // eslint-disable-line @typescript-eslint/naming-convention
@@ -256,12 +260,10 @@ export class S3Client extends ClientWrapper<S3ClientSDK> {
256260
request.key,
257261
request.saveLocation
258262
)
259-
const s3 = await this.createS3()
260-
261-
// https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/requests-using-stream-objects.html
262-
const readStream = s3.getObject({ Bucket: request.bucketName, Key: request.key }).createReadStream()
263263

264+
const readStream = await this.downloadFileStream(request.bucketName, request.key)
264265
const writeStream = this.fileStreams.createWriteStream(request.saveLocation)
266+
265267
await pipe(readStream, writeStream, request.progressListener)
266268

267269
getLogger().debug('DownloadFile succeeded')
@@ -271,8 +273,21 @@ export class S3Client extends ClientWrapper<S3ClientSDK> {
271273
* Lighter version of {@link downloadFile} that just returns the stream.
272274
*/
273275
public async downloadFileStream(bucketName: string, key: string): Promise<Readable> {
274-
const s3 = await this.createS3()
275-
return s3.getObject({ Bucket: bucketName, Key: key }).createReadStream()
276+
// GetObject response body is now a `StreamingBlobPayloadOutputTypes` from @smithy/types.
277+
// this is a general type for web/node streams, therefore we must cast the nodes streaming type.
278+
const response = await this.makeRequest<GetObjectCommandInput, GetObjectCommandOutput, GetObjectCommand>(
279+
GetObjectCommand,
280+
{
281+
Bucket: bucketName,
282+
Key: key,
283+
}
284+
)
285+
286+
if (isWeb()) {
287+
throw new ToolkitError('S3: downloading files is not supported in web.')
288+
}
289+
290+
return (response.Body as Readable) ?? new Readable()
276291
}
277292

278293
public async headObject(request: HeadObjectRequest): Promise<S3.HeadObjectOutput> {

packages/core/src/test/shared/clients/defaultS3Client.test.ts

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -133,42 +133,6 @@ describe('DefaultS3Client', function () {
133133
})
134134
})
135135

136-
describe('downloadFile', function () {
137-
it('downloads a file', async function () {
138-
const s = sinon.stub().returns(success())
139-
mockS3.getObject = s
140-
141-
const fileStreams = new FakeFileStreams({ readData: fileData })
142-
const progressCaptor = new FakeProgressCaptor()
143-
144-
await createClient({ fileStreams }).downloadFile({
145-
bucketName,
146-
key: fileKey,
147-
saveLocation: fileLocation,
148-
progressListener: progressCaptor.listener(),
149-
})
150-
151-
assert(s.calledOnce)
152-
assert.deepStrictEqual(fileStreams.writtenLocation, fileLocation)
153-
assert.strictEqual(fileStreams.writtenData, fileData)
154-
assert.ok(progressCaptor.progress > 0)
155-
})
156-
157-
it('throws an Error on failure', async function () {
158-
const s = sinon.stub().returns(failure())
159-
mockS3.getObject = s
160-
161-
await assert.rejects(
162-
createClient().downloadFile({
163-
bucketName,
164-
key: fileKey,
165-
saveLocation: fileLocation,
166-
}),
167-
error
168-
)
169-
})
170-
})
171-
172136
describe('uploadFile', function () {
173137
it('uploads a file', async function () {
174138
const mockManagedUpload = stub(S3.ManagedUpload)

0 commit comments

Comments
 (0)