@@ -11,17 +11,14 @@ import { ux } from '@oclif/core';
1111import got from 'got' ;
1212import { SfError } from '@salesforce/core' ;
1313import chalk from 'chalk' ;
14- import AWS from 'aws-sdk' ;
15- import { S3 , WebIdentityCredentials } from 'aws-sdk ' ;
16- import { CredentialsOptions } from 'aws-sdk/lib/credentials.js ' ;
14+ import { _Object , ListObjectsV2CommandOutput , S3 , GetObjectRequest , GetObjectOutput } from '@ aws-sdk/client-s3 ' ;
15+ import { NodeHttpHandler } from '@smithy/node-http-handler ' ;
16+ import { AwsCredentialIdentity } from '@smithy/types ' ;
1717import { isString } from '@salesforce/ts-types' ;
1818
19- import { GetObjectRequest , GetObjectOutput } from 'aws-sdk/clients/s3.js' ;
2019import { Channel , CLI , S3Manifest , ServiceAvailability } from './types.js' ;
2120import { api } from './codeSigning/packAndSign.js' ;
2221
23- import ClientConfiguration = WebIdentityCredentials . ClientConfiguration ;
24-
2522const BASE_URL = 'https://developer.salesforce.com' ;
2623const BUCKET = 'dfc-data-production' ;
2724
@@ -32,7 +29,7 @@ type AmazonS3Options = {
3229 cli : CLI ;
3330 channel ?: Channel ;
3431 baseUrl ?: string ;
35- credentials ?: CredentialsOptions ;
32+ credentials ?: AwsCredentialIdentity ;
3633 baseKey ?: string ;
3734} ;
3835
@@ -41,14 +38,15 @@ export class AmazonS3 {
4138
4239 public directory : string ;
4340 private s3 : S3 ;
44- private baseKey : string ;
41+ private readonly baseKey : string ;
4542
4643 public constructor ( private options : AmazonS3Options ) {
4744 this . directory = `https://developer.salesforce.com/media/salesforce-cli/${ this . options . cli ?? '' } ` ;
4845 this . baseKey = this . directory . replace ( BASE_URL , '' ) . replace ( / ^ \/ / , '' ) ;
49- this . s3 = new AWS . S3 ( {
46+ this . s3 = new S3 ( {
47+ region : 'us-east-1' ,
5048 ...resolveCredentials ( options . credentials ) ,
51- ... buildHttpOptions ( ) ,
49+ requestHandler : buildRequestHandler ( ) ,
5250 } ) ;
5351 }
5452
@@ -65,36 +63,31 @@ export class AmazonS3 {
6563 }
6664
6765 public async getObject ( options : GetObjectOption ) : Promise < GetObjectOutput > {
68- const object = ( await this . s3
69- . getObject ( {
70- ...options ,
71- Key : options . Key . replace ( BASE_URL , '' ) . replace ( / ^ \/ / , '' ) ,
72- ...{ Bucket : this . options . bucket ?? BUCKET } ,
73- } )
74- . promise ( ) ) as GetObjectOutput ;
75- return object ;
66+ return this . s3 . getObject ( {
67+ ...options ,
68+ Key : options . Key ?. replace ( BASE_URL , '' ) . replace ( / ^ \/ / , '' ) ,
69+ ...{ Bucket : this . options . bucket ?? BUCKET } ,
70+ } ) ;
7671 }
7772
7873 // Paginates listObjectV2 and returns both Contents and CommonPrefixes
79- public async listAllObjects ( key : string ) : Promise < { contents : S3 . ObjectList ; commonPrefixes : string [ ] } > {
74+ public async listAllObjects ( key : string ) : Promise < { contents : _Object [ ] ; commonPrefixes : string [ ] } > {
8075 const prefix = key . startsWith ( this . baseKey ) ? key : `${ this . baseKey } /${ key } /` ;
8176 const bucket = this . options . bucket ?? BUCKET ;
8277 let continuationToken ;
83- const allContents : S3 . ObjectList = [ ] ;
78+ const allContents : _Object [ ] = [ ] ;
8479 const allCommonPrefixes : string [ ] = [ ] ;
8580
8681 // Use maximum iteration to ensure termination
8782 const MAX_ITERATIONS = 100 ;
8883 for ( let i = 1 ; i <= MAX_ITERATIONS ; i ++ ) {
8984 // eslint-disable-next-line no-await-in-loop
90- const response = await this . s3
91- . listObjectsV2 ( {
92- Bucket : bucket ,
93- Delimiter : '/' ,
94- Prefix : prefix ,
95- ContinuationToken : continuationToken ,
96- } )
97- . promise ( ) ;
85+ const response : ListObjectsV2CommandOutput = await this . s3 . listObjectsV2 ( {
86+ Bucket : bucket ,
87+ Delimiter : '/' ,
88+ Prefix : prefix ,
89+ ContinuationToken : continuationToken ,
90+ } ) ;
9891
9992 if ( response . Contents ) {
10093 allContents . push ( ...response . Contents ) ;
@@ -117,7 +110,7 @@ export class AmazonS3 {
117110 return result . commonPrefixes ;
118111 }
119112
120- public async listKeyContents ( key : string ) : Promise < S3 . ObjectList > {
113+ public async listKeyContents ( key : string ) : Promise < _Object [ ] > {
121114 const result = await this . listAllObjects ( key ) ;
122115 return result . contents ;
123116 }
@@ -157,8 +150,8 @@ const getFileAtUrl = async (url: string): Promise<string> => {
157150} ;
158151
159152const resolveCredentials = (
160- credentialOptions ?: CredentialsOptions
161- ) : { credentials : CredentialsOptions } | Record < string , string > => {
153+ credentialOptions ?: AwsCredentialIdentity
154+ ) : { credentials : AwsCredentialIdentity } | Record < string , string > => {
162155 if ( credentialOptions ) {
163156 return { credentials : credentialOptions } ;
164157 }
@@ -174,7 +167,13 @@ const fileIsAvailable = async (url: string): Promise<ServiceAvailability> => {
174167 return { service : 'file' , name : url , available : statusCode >= 200 && statusCode < 300 } ;
175168} ;
176169
177- const buildHttpOptions = ( ) : { httpOptions : ClientConfiguration [ 'httpOptions' ] } | Record < string , never > => {
170+ const buildRequestHandler = ( ) : NodeHttpHandler => {
178171 const agent = api . getAgentForUri ( 'https://s3.amazonaws.com' ) ;
179- return agent && agent . http ? { httpOptions : { agent : agent . http } } : { } ;
172+ const options =
173+ agent && agent . http
174+ ? {
175+ httpAgent : agent . http ,
176+ }
177+ : { } ;
178+ return new NodeHttpHandler ( options ) ;
180179} ;
0 commit comments