@@ -118,19 +118,48 @@ export default function gsAdapter(conf: GsConfig): StorageAdapter {
118118 ? dir
119119 : dir + '/' ;
120120
121- const options = {
122- prefix : normalisedPath
123- } ;
124-
125121 try {
126- const results = await getClient ( ) . bucket ( bucketName ) . getFiles ( options ) ;
122+ const collected : { name : string } [ ] = [ ] ;
123+ let pageToken : string | undefined ;
124+
125+ do {
126+ const requestPageToken = pageToken ;
127+ const options : {
128+ prefix : string ;
129+ autoPaginate : false ;
130+ pageToken ?: string ;
131+ } = {
132+ prefix : normalisedPath ,
133+ autoPaginate : false
134+ } ;
135+ if ( requestPageToken ) {
136+ options . pageToken = requestPageToken ;
137+ }
138+
139+ const results = await getClient ( )
140+ . bucket ( bucketName )
141+ . getFiles ( options ) ;
142+ const files = results [ 0 ] ?? [ ] ;
143+ const nextQuery = results [ 1 ] as { pageToken ?: string } | undefined ;
144+
145+ for ( const file of files ) {
146+ collected . push ( file ) ;
147+ }
148+
149+ const nextPageToken = nextQuery ?. pageToken ;
150+ if ( nextPageToken && nextPageToken === requestPageToken ) {
151+ throw new Error (
152+ 'GCS getFiles returned an unchanged pageToken; aborting to avoid an infinite loop'
153+ ) ;
154+ }
155+ pageToken = nextPageToken ;
156+ } while ( pageToken ) ;
127157
128- const files = results [ 0 ] ;
129- if ( files . length === 0 ) {
158+ if ( collected . length === 0 ) {
130159 throw 'no files' ;
131160 }
132161
133- const result = files
162+ const result = collected
134163 //remove prefix
135164 . map ( file => file . name . replace ( normalisedPath , '' ) )
136165 // only get files that aren't in root directory
@@ -258,11 +287,41 @@ export default function gsAdapter(conf: GsConfig): StorageAdapter {
258287 ? dir
259288 : `${ dir } /` ;
260289
261- const [ files ] = await getClient ( )
262- . bucket ( bucketName )
263- . getFiles ( { prefix : normalisedPath } ) ;
290+ const collected : { delete : ( ) => Promise < unknown > } [ ] = [ ] ;
291+ let pageToken : string | undefined ;
292+
293+ do {
294+ const requestPageToken = pageToken ;
295+ const options : {
296+ prefix : string ;
297+ autoPaginate : false ;
298+ pageToken ?: string ;
299+ } = {
300+ prefix : normalisedPath ,
301+ autoPaginate : false
302+ } ;
303+ if ( requestPageToken ) {
304+ options . pageToken = requestPageToken ;
305+ }
306+
307+ const results = await getClient ( )
308+ . bucket ( bucketName )
309+ . getFiles ( options ) ;
310+ const files = results [ 0 ] ?? [ ] ;
311+ const nextQuery = results [ 1 ] as { pageToken ?: string } | undefined ;
312+
313+ for ( const file of files ) {
314+ collected . push ( file as { delete : ( ) => Promise < unknown > } ) ;
315+ }
316+
317+ const nextPageToken = nextQuery ?. pageToken ;
318+ if ( nextPageToken && nextPageToken === requestPageToken ) {
319+ throw new Error ( 'GCS getFiles returned an unchanged pageToken; aborting to avoid an infinite loop' ) ;
320+ }
321+ pageToken = nextPageToken ;
322+ } while ( pageToken ) ;
264323
265- return Promise . all ( files . map ( file => file . delete ( ) ) ) ;
324+ return Promise . all ( collected . map ( file => file . delete ( ) ) ) ;
266325 } ;
267326
268327 return removeFromContainer ( ) ;
0 commit comments