2
2
// Licensed under the MIT license.
3
3
4
4
import { AppConfigurationClient , AppConfigurationClientOptions } from "@azure/app-configuration" ;
5
- import { ConfigurationClientWrapper } from "./ConfigurationClientWrapper"
5
+ import { ConfigurationClientWrapper } from "./ConfigurationClientWrapper" ;
6
6
import { TokenCredential } from "@azure/identity" ;
7
7
import { AzureAppConfigurationOptions , MaxRetries , MaxRetryDelayInMs } from "./AzureAppConfigurationOptions" ;
8
8
import { isFailoverableEnv } from "./requestTracing/utils" ;
@@ -14,18 +14,18 @@ const TCP = "_tcp";
14
14
const EndpointSection = "Endpoint" ;
15
15
const IdSection = "Id" ;
16
16
const SecretSection = "Secret" ;
17
- const AzConfigDomainLabel = ".azconfig."
18
- const AppConfigDomainLabel = ".appconfig."
17
+ const AzConfigDomainLabel = ".azconfig." ;
18
+ const AppConfigDomainLabel = ".appconfig." ;
19
19
const FallbackClientRefreshExpireInterval = 60 * 60 * 1000 ; // 1 hour in milliseconds
20
20
const MinimalClientRefreshInterval = 30 * 1000 ; // 30 seconds in milliseconds
21
21
const SrvQueryTimeout = 5000 ; // 5 seconds
22
22
23
23
interface IConfigurationClientManager {
24
- getClients ( ) : ConfigurationClientWrapper [ ] ;
24
+ getClients ( ) : Promise < ConfigurationClientWrapper [ ] > ;
25
25
refreshClients ( ) : Promise < void > ;
26
26
}
27
27
28
- export class ConfigurationClientManager {
28
+ export class ConfigurationClientManager implements IConfigurationClientManager {
29
29
isFailoverable : boolean ;
30
30
#endpoint: string ;
31
31
#secret : string ;
@@ -55,7 +55,7 @@ export class ConfigurationClientManager {
55
55
this . #id = parseConnectionString ( connectionString , IdSection ) ;
56
56
// TODO: need to check if it's CDN or not
57
57
this . #endpoint = parseConnectionString ( connectionString , EndpointSection ) ;
58
-
58
+
59
59
} else if ( connectionStringOrEndpoint instanceof URL ) {
60
60
const credential = credentialOrOptions as TokenCredential ;
61
61
options = appConfigOptions as AzureAppConfigurationOptions ;
@@ -69,7 +69,7 @@ export class ConfigurationClientManager {
69
69
70
70
this . #staticClients = [ new ConfigurationClientWrapper ( this . #endpoint, staticClient ) ] ;
71
71
this . #validDomain = getValidDomain ( this . #endpoint) ;
72
- this . isFailoverable = ( options ?. replicaDiscoveryEnabled ?? true ) && isFailoverableEnv ( ) ;
72
+ this . isFailoverable = ( options ?. replicaDiscoveryEnabled ?? true ) && isFailoverableEnv ( ) ;
73
73
}
74
74
75
75
async getClients ( ) {
@@ -93,7 +93,7 @@ export class ConfigurationClientManager {
93
93
. filter ( client => client . backoffEndTime <= currentTime ) ) ;
94
94
}
95
95
96
- return availableClients
96
+ return availableClients ;
97
97
}
98
98
99
99
async refreshClients ( ) {
@@ -155,7 +155,7 @@ export class ConfigurationClientManager {
155
155
156
156
#isFallbackClientDiscoveryDue( dateTime ) {
157
157
return dateTime >= this . #lastFallbackClientRefreshAttempt + MinimalClientRefreshInterval
158
- && ( ! this . #dynamicClients
158
+ && ( ! this . #dynamicClients
159
159
|| this . #dynamicClients. every ( client => dateTime < client . backoffEndTime )
160
160
|| dateTime >= this . #lastFallbackClientRefreshTime + FallbackClientRefreshExpireInterval ) ;
161
161
}
@@ -171,7 +171,7 @@ async function querySrvTargetHost(host) {
171
171
let dns ;
172
172
173
173
if ( isFailoverableEnv ( ) ) {
174
- dns = require ( ' dns/promises' ) ;
174
+ dns = require ( " dns/promises" ) ;
175
175
} else {
176
176
return results ;
177
177
}
@@ -184,16 +184,18 @@ async function querySrvTargetHost(host) {
184
184
}
185
185
186
186
// Add the first origin record to results
187
- const originHost = originRecords [ 0 ] . name
187
+ const originHost = originRecords [ 0 ] . name ;
188
188
results . push ( originHost ) ;
189
-
189
+
190
190
// Look up SRV records for alternate hosts
191
191
let index = 0 ;
192
- while ( true ) {
192
+ let moreAltRecordsExist = true ;
193
+ while ( moreAltRecordsExist ) {
193
194
const currentAlt = `${ ALT } ${ index } ` ;
194
195
try {
195
196
const altRecords = await dns . resolveSrv ( `${ currentAlt } .${ TCP } .${ originHost } ` ) ;
196
197
if ( altRecords . length === 0 ) {
198
+ moreAltRecordsExist = false ;
197
199
break ; // No more alternate records, exit loop
198
200
}
199
201
@@ -205,7 +207,7 @@ async function querySrvTargetHost(host) {
205
207
} ) ;
206
208
index ++ ;
207
209
} catch ( err ) {
208
- if ( err . code === ' ENOTFOUND' ) {
210
+ if ( err . code === " ENOTFOUND" ) {
209
211
break ; // No more alternate records, exit loop
210
212
} else {
211
213
throw new Error ( `Failed to lookup alternate SRV records: ${ err . message } ` ) ;
@@ -221,7 +223,7 @@ async function querySrvTargetHost(host) {
221
223
222
224
/**
223
225
* Parses the connection string to extract the value associated with a specific token.
224
- *
226
+ *
225
227
* @param {string } connectionString - The connection string containing tokens.
226
228
* @param {string } token - The token whose value needs to be extracted.
227
229
* @returns {string } The value associated with the token, or an empty string if not found.
@@ -241,7 +243,7 @@ function parseConnectionString(connectionString, token) {
241
243
242
244
// Move startIndex to the beginning of the token value
243
245
const valueStartIndex = startIndex + searchToken . length ;
244
- const endIndex = connectionString . indexOf ( ';' , valueStartIndex ) ;
246
+ const endIndex = connectionString . indexOf ( ";" , valueStartIndex ) ;
245
247
const valueEndIndex = endIndex === - 1 ? connectionString . length : endIndex ;
246
248
247
249
// Extract and return the token value
@@ -251,15 +253,15 @@ function parseConnectionString(connectionString, token) {
251
253
/**
252
254
* Builds a connection string from the given endpoint, secret, and id.
253
255
* Returns an empty string if either secret or id is empty.
254
- *
256
+ *
255
257
* @param {string } endpoint - The endpoint to include in the connection string.
256
258
* @param {string } secret - The secret to include in the connection string.
257
259
* @param {string } id - The ID to include in the connection string.
258
260
* @returns {string } - The formatted connection string or an empty string if invalid input.
259
261
*/
260
262
function buildConnectionString ( endpoint , secret , id ) {
261
263
if ( ! secret || ! id ) {
262
- return '' ;
264
+ return "" ;
263
265
}
264
266
265
267
return `${ EndpointSection } =${ endpoint } ;${ IdSection } =${ id } ;${ SecretSection } =${ secret } ` ;
@@ -276,7 +278,7 @@ function getValidDomain(endpoint) {
276
278
const url = new URL ( endpoint ) ;
277
279
const trustedDomainLabels = [ AzConfigDomainLabel , AppConfigDomainLabel ] ;
278
280
const host = url . hostname . toLowerCase ( ) ;
279
-
281
+
280
282
for ( const label of trustedDomainLabels ) {
281
283
const index = host . lastIndexOf ( label ) ;
282
284
if ( index !== - 1 ) {
@@ -292,7 +294,7 @@ function getValidDomain(endpoint) {
292
294
293
295
/**
294
296
* Checks if the given host ends with the valid domain.
295
- *
297
+ *
296
298
* @param {string } host - The host to be validated.
297
299
* @param {string } validDomain - The valid domain to check against.
298
300
* @returns {boolean } - True if the host ends with the valid domain, false otherwise.
@@ -317,7 +319,7 @@ export function getClientOptions(options?: AzureAppConfigurationOptions): AppCon
317
319
const defaultRetryOptions = {
318
320
maxRetries : MaxRetries ,
319
321
maxRetryDelayInMs : MaxRetryDelayInMs ,
320
- }
322
+ } ;
321
323
const retryOptions = Object . assign ( { } , defaultRetryOptions , options ?. clientOptions ?. retryOptions ) ;
322
324
323
325
return Object . assign ( { } , options ?. clientOptions , {
0 commit comments