55
66import { CacheOverride } from 'fastly:cache-override' ;
77import { SecretStore } from 'fastly:secret-store' ;
8+ import { Command } from '@smithy/types' ;
89import { FetchHttpHandler } from '@smithy/fetch-http-handler' ;
910import {
1011 GetObjectCommand ,
1112 GetObjectCommandInput ,
1213 GetObjectCommandOutput ,
1314 S3Client ,
14- S3ServiceException
15+ S3ClientResolvedConfig ,
16+ S3ServiceException ,
17+ ServiceInputTypes ,
18+ ServiceOutputTypes ,
1519} from '@aws-sdk/client-s3' ;
1620
1721import {
@@ -107,6 +111,9 @@ export type S3StorageProviderParams = {
107111 s3FastlyBackendName ?: string ,
108112} ;
109113
114+ type S3ClientCommand < InputType extends ServiceInputTypes , OutputType extends ServiceOutputTypes > =
115+ Command < ServiceInputTypes , InputType , ServiceOutputTypes , OutputType , S3ClientResolvedConfig > ;
116+
110117export class S3StorageProvider implements StorageProvider {
111118 constructor (
112119 s3Region : string ,
@@ -124,54 +131,44 @@ export class S3StorageProvider implements StorageProvider {
124131 private readonly s3Endpoint ?: string ;
125132 private readonly s3FastlyBackendName ?: string ;
126133
127- private surrogateKeys ?: string [ ] ;
128-
129- private s3Client ?: S3Client ;
130- async getS3Client ( ) {
131- if ( this . s3Client != null ) {
132- return this . s3Client ;
133- }
134+ async sendS3Command < InputType extends ServiceInputTypes , OutputType extends ServiceOutputTypes > (
135+ command : S3ClientCommand < InputType , OutputType > ,
136+ requestInit ?: RequestInit ,
137+ ) : Promise < OutputType > {
134138 const awsCredentials = await _awsCredentialsBuilder ( ) ;
135- this . s3Client = new S3Client ( {
139+ const s3Client = new S3Client ( {
136140 region : this . s3Region ,
137141 endpoint : this . s3Endpoint ,
138142 forcePathStyle : this . s3Endpoint != null ,
139143 credentials : {
140144 accessKeyId : awsCredentials . accessKeyId ,
141145 secretAccessKey : awsCredentials . secretAccessKey ,
142146 } ,
143- maxAttempts : 1 ,
147+ maxAttempts : 5 ,
144148 requestHandler : new FetchHttpHandler ( {
145- requestInit : ( ) => {
146- return {
147- backend : this . s3FastlyBackendName ?? "aws" ,
148- cacheOverride : new CacheOverride ( {
149- ttl : 3600 ,
150- surrogateKey : ( this . surrogateKeys ?? [ ] ) . join ( ' ' ) || undefined ,
151- } ) ,
152- } ;
149+ requestInit ( ) {
150+ return requestInit ?? { } ;
153151 } ,
154152 } ) ,
155153 } ) ;
156- return this . s3Client ;
154+ return s3Client . send ( command ) ;
157155 }
158156
159157 async getEntry ( key : string , tags ?: string [ ] ) : Promise < StorageEntry | null > {
160-
161158 const input = {
162159 Bucket : this . s3Bucket , // required
163160 Key : key , // required
164161 } satisfies GetObjectCommandInput ;
165162 const command = new GetObjectCommand ( input ) ;
166163 let response : GetObjectCommandOutput ;
167164 try {
168- const s3Client = await this . getS3Client ( ) ;
169- this . surrogateKeys = tags ;
170- try {
171- response = await s3Client . send ( command ) ;
172- } finally {
173- this . surrogateKeys = undefined ;
174- }
165+ response = await this . sendS3Command ( command , {
166+ backend : this . s3FastlyBackendName ?? "aws" ,
167+ cacheOverride : new CacheOverride ( {
168+ ttl : 3600 ,
169+ surrogateKey : ( tags ?? [ ] ) . join ( ' ' ) || undefined ,
170+ } ) ,
171+ } ) ;
175172 } catch ( err ) {
176173 if ( err instanceof S3ServiceException && ( err . name === "NotFound" || err . name === "NoSuchKey" ) ) {
177174 console . log ( "Object does not exist" ) ;
0 commit comments