@@ -329,7 +329,7 @@ export class Flagsmith {
329329 url : string ,
330330 method : string ,
331331 body ?: { [ key : string ] : any }
332- ) : Promise < any > {
332+ ) : Promise < { response : Response ; data : any } > {
333333 const headers : { [ key : string ] : any } = { 'Content-Type' : 'application/json' } ;
334334 if ( this . environmentKey ) {
335335 headers [ 'X-Environment-Key' ] = this . environmentKey as string ;
@@ -361,7 +361,7 @@ export class Flagsmith {
361361 ) ;
362362 }
363363
364- return data . json ( ) ;
364+ return { response : data , data : await data . json ( ) } ;
365365 }
366366
367367 /**
@@ -395,25 +395,41 @@ export class Flagsmith {
395395 const documents : any [ ] = [ ] ;
396396 let url = this . environmentUrl ;
397397 let loggedWarning = false ;
398+
398399 while ( true ) {
399- if ( ! loggedWarning ) {
400- const elapsedMs = Date . now ( ) - startTime ;
401- if ( elapsedMs > this . environmentRefreshIntervalSeconds * 1000 ) {
402- this . logger . warn (
403- `Environment document retrieval exceeded the polling interval of ${ this . environmentRefreshIntervalSeconds } seconds.`
404- ) ;
405- loggedWarning = true ;
400+ try {
401+ if ( ! loggedWarning ) {
402+ const elapsedMs = Date . now ( ) - startTime ;
403+ if ( elapsedMs > this . environmentRefreshIntervalSeconds * 1000 ) {
404+ this . logger . warn (
405+ `Environment document retrieval exceeded the polling interval of ${ this . environmentRefreshIntervalSeconds } seconds.`
406+ ) ;
407+ loggedWarning = true ;
408+ }
406409 }
407- }
408410
409- const response = await this . getJSONResponse ( url , 'GET' ) ;
410- documents . push ( response ) ;
411+ const { response, data } = await this . getJSONResponse ( url , 'GET' ) ;
412+
413+ documents . push ( data ) ;
411414
412- if ( response . links && response . links . next && response . links . next . url ) {
413- url = response . links . next . url ;
414- continue ;
415+ const linkHeader = response . headers . get ( 'link' ) ;
416+ if ( linkHeader ) {
417+ const nextMatch = linkHeader . match ( / < ( [ ^ > ] + ) > ; \s * r e l = " n e x t " / ) ;
418+
419+ if ( nextMatch ) {
420+ const relativeUrl = decodeURIComponent ( nextMatch [ 1 ] ) ;
421+ url = new URL ( relativeUrl , this . apiUrl ) . href ;
422+
423+ continue ;
424+ }
425+ }
426+ break ;
427+ } catch ( error ) {
428+ if ( error instanceof FlagsmithAPIError && error . message . includes ( '502' ) ) {
429+ break ;
430+ }
431+ throw error ;
415432 }
416- break ;
417433 }
418434
419435 // Compile the document
@@ -473,7 +489,7 @@ export class Flagsmith {
473489 if ( ! this . environmentFlagsUrl ) {
474490 throw new Error ( '`apiUrl` argument is missing or invalid.' ) ;
475491 }
476- const apiFlags = await this . getJSONResponse ( this . environmentFlagsUrl , 'GET' ) ;
492+ const { data : apiFlags } = await this . getJSONResponse ( this . environmentFlagsUrl , 'GET' ) ;
477493 const flags = Flags . fromAPIFlags ( {
478494 apiFlags : apiFlags ,
479495 analyticsProcessor : this . analyticsProcessor ,
@@ -494,7 +510,7 @@ export class Flagsmith {
494510 throw new Error ( '`apiUrl` argument is missing or invalid.' ) ;
495511 }
496512 const data = generateIdentitiesData ( identifier , traits , transient ) ;
497- const jsonResponse = await this . getJSONResponse ( this . identitiesUrl , 'POST' , data ) ;
513+ const { data : jsonResponse } = await this . getJSONResponse ( this . identitiesUrl , 'POST' , data ) ;
498514 const flags = Flags . fromAPIFlags ( {
499515 apiFlags : jsonResponse [ 'flags' ] ,
500516 analyticsProcessor : this . analyticsProcessor ,
0 commit comments