@@ -28,6 +28,9 @@ export type MultiEnvironmentFlag = {
28
28
> ;
29
29
} ;
30
30
31
+ // LaunchDarkly API allows maximum of 3 environments per request
32
+ const MAX_ENVIRONMENTS_PER_REQUEST = 3 ;
33
+
31
34
export const useLaunchdarklyMultiEnvironmentFlags = (
32
35
entity : Entity ,
33
36
envs ?: string [ ] ,
@@ -44,22 +47,43 @@ export const useLaunchdarklyMultiEnvironmentFlags = (
44
47
45
48
const url = `${ await discovery . getBaseUrl ( 'proxy' ) } /launchdarkly/api` ;
46
49
47
- const envQueryParams = ( envs ?? [ ] ) . map ( env => `env= ${ env } ` ) . join ( '&' ) ;
48
-
49
- const flagsResponse = await fetch (
50
- ` ${ url } /v2/flags/ ${ projectKey } ?limit=100&offset=0& ${ envQueryParams } ${
51
- query ? `&filter= ${ query } ` : ''
52
- } ` ,
53
- ) ;
54
-
55
- if ( ! flagsResponse . ok ) {
56
- throw new Error (
57
- `Failed to retrieve LaunchDarkly flags for project ${ projectKey } : ${ flagsResponse . statusText } ` ,
50
+ const environments = envs ?? [ ] ;
51
+
52
+ // Split environments into batches of maximum 3
53
+ const environmentBatches = [ ] ;
54
+ for (
55
+ let i = 0 ;
56
+ i < environments . length ;
57
+ i += MAX_ENVIRONMENTS_PER_REQUEST
58
+ ) {
59
+ environmentBatches . push (
60
+ environments . slice ( i , i + MAX_ENVIRONMENTS_PER_REQUEST ) ,
58
61
) ;
59
62
}
60
63
61
- const flags = ( await flagsResponse . json ( ) ) . items || [ ] ;
64
+ // Fetch flags for each batch of environments
65
+ const flagsBatches = await Promise . all (
66
+ environmentBatches . map ( async envBatch => {
67
+ const envQueryParams = envBatch . map ( env => `env=${ env } ` ) . join ( '&' ) ;
68
+
69
+ const flagsResponse = await fetch (
70
+ `${ url } /v2/flags/${ projectKey } ?limit=100&offset=0&${ envQueryParams } ${
71
+ query ? `&filter=${ query } ` : ''
72
+ } `,
73
+ ) ;
74
+
75
+ if ( ! flagsResponse . ok ) {
76
+ throw new Error (
77
+ `Failed to retrieve LaunchDarkly flags for project ${ projectKey } : ${ flagsResponse . statusText } ` ,
78
+ ) ;
79
+ }
80
+
81
+ const flags = ( await flagsResponse . json ( ) ) . items || [ ] ;
82
+ return { flags, environments : envBatch } ;
83
+ } ) ,
84
+ ) ;
62
85
86
+ // Get environments data once
63
87
const environmentsResponse = await fetch (
64
88
`${ url } /v2/projects/${ projectKey } ` ,
65
89
) ;
@@ -71,48 +95,54 @@ export const useLaunchdarklyMultiEnvironmentFlags = (
71
95
}
72
96
73
97
const projectData = await environmentsResponse . json ( ) ;
74
- const environments = projectData . environments || { } ;
98
+ const environmentsData = projectData . environments || { } ;
75
99
100
+ // Merge flags from all batches
76
101
const flagsMap = new Map ( ) ;
77
- flags . forEach ( ( flag : any ) => {
78
- const environmentsData : Record < string , any > = { } ;
79
-
80
- ( envs ?? [ ] ) . forEach ( env => {
81
- const envData = environments [ env ] ;
82
- const envName = envData ?. name || env ;
83
- const link = `https://app.launchdarkly.com/projects/${ projectKey } /flags/${ flag . key } /targeting?env=${ env } &selected-env=${ env } ` ;
84
-
85
- const envFlag = flag . environments ?. [ env ] ;
86
- const isOn = envFlag ?. on ?? false ;
87
-
88
- const flagStatus = envData ?. [ flag . key ] ;
89
102
90
- let status = isOn ? 'Enabled' : 'Disabled' ;
91
- if ( flagStatus && flagStatus . status ) {
92
- status = flagStatus . status ;
93
- }
94
-
95
- environmentsData [ env ] = {
96
- name : envName ,
97
- status,
98
- link,
99
- on : isOn ,
100
- ...( flagStatus && {
101
- lastRequested : flagStatus . lastRequested ,
102
- lastEvaluated : flagStatus . lastEvaluated ,
103
- evaluationCount : flagStatus . evaluationCount ,
104
- } ) ,
103
+ flagsBatches . forEach ( ( { flags, environments : batchEnvs } ) => {
104
+ flags . forEach ( ( flag : any ) => {
105
+ // Get existing flag data or create new entry
106
+ const existingFlag = flagsMap . get ( flag . key ) || {
107
+ name : flag . name ,
108
+ key : flag . key ,
109
+ description : flag . description ,
110
+ tags : flag . tags ,
111
+ maintainer : flag . _maintainer ?. email ,
112
+ variations : flag . variations ,
113
+ environments : { } ,
105
114
} ;
106
- } ) ;
107
115
108
- flagsMap . set ( flag . key , {
109
- name : flag . name ,
110
- key : flag . key ,
111
- description : flag . description ,
112
- tags : flag . tags ,
113
- maintainer : flag . _maintainer ?. email ,
114
- variations : flag . variations ,
115
- environments : environmentsData ,
116
+ // Add environment data for this batch
117
+ batchEnvs . forEach ( env => {
118
+ const envData = environmentsData [ env ] ;
119
+ const envName = envData ?. name || env ;
120
+ const link = `https://app.launchdarkly.com/projects/${ projectKey } /flags/${ flag . key } /targeting?env=${ env } &selected-env=${ env } ` ;
121
+
122
+ const envFlag = flag . environments ?. [ env ] ;
123
+ const isOn = envFlag ?. on ?? false ;
124
+
125
+ const flagStatus = envData ?. [ flag . key ] ;
126
+
127
+ let status = isOn ? 'Enabled' : 'Disabled' ;
128
+ if ( flagStatus && flagStatus . status ) {
129
+ status = flagStatus . status ;
130
+ }
131
+
132
+ existingFlag . environments [ env ] = {
133
+ name : envName ,
134
+ status,
135
+ link,
136
+ on : isOn ,
137
+ ...( flagStatus && {
138
+ lastRequested : flagStatus . lastRequested ,
139
+ lastEvaluated : flagStatus . lastEvaluated ,
140
+ evaluationCount : flagStatus . evaluationCount ,
141
+ } ) ,
142
+ } ;
143
+ } ) ;
144
+
145
+ flagsMap . set ( flag . key , existingFlag ) ;
116
146
} ) ;
117
147
} ) ;
118
148
0 commit comments