@@ -284,7 +284,9 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
284284 }
285285
286286 // parse feature flags
287- const featureFlags = Array . from ( featureFlagsMap . values ( ) ) . map ( setting => this . #parseFeatureflag( setting ) ) ;
287+ const featureFlags = await Promise . all (
288+ Array . from ( featureFlagsMap . values ( ) ) . map ( setting => this . #parseFeatureFlag( setting ) )
289+ ) ;
288290
289291 // feature_management is a reserved key, and feature_flags is an array of feature flags
290292 this . #configMap. set ( FEATURE_MANAGEMENT_KEY_NAME , { [ FEATURE_FLAGS_KEY_NAME ] : featureFlags } ) ;
@@ -536,7 +538,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
536538 return response ;
537539 }
538540
539- #parseFeatureflag ( setting : ConfigurationSetting < string > ) : any {
541+ async #parseFeatureFlag ( setting : ConfigurationSetting < string > ) : Promise < any > {
540542 const rawFlag = setting . value ;
541543 if ( rawFlag === undefined ) {
542544 throw new Error ( "The value of configuration setting cannot be undefined." ) ;
@@ -546,20 +548,63 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
546548 if ( featureFlag [ TELEMETRY_KEY_NAME ] ) {
547549 const metadata = featureFlag [ TELEMETRY_KEY_NAME ] [ METADATA_KEY_NAME ] ;
548550 featureFlag [ TELEMETRY_KEY_NAME ] [ METADATA_KEY_NAME ] = {
549- ETAG_KEY_NAME : setting . etag ,
550- FEATURE_FLAG_ID_KEY_NAME : "1" ,
551- FEATURE_FLAG_REFERENCE_KEY_NAME : this . #createFeatureFlagReference( setting ) ,
551+ [ ETAG_KEY_NAME ] : setting . etag ,
552+ [ FEATURE_FLAG_ID_KEY_NAME ] : await this . #calculateFeatureFlagId ( setting ) ,
553+ [ FEATURE_FLAG_REFERENCE_KEY_NAME ] : this . #createFeatureFlagReference( setting ) ,
552554 ...( metadata || { } )
553555 } ;
554556 }
555-
556- console . log ( featureFlag ) ;
557557
558558 return featureFlag ;
559559 }
560560
561- #calculateFeatureFlagId( setting : ConfigurationSetting < string > ) : string {
562- return ""
561+ async #calculateFeatureFlagId( setting : ConfigurationSetting < string > ) : Promise < string > {
562+ let crypto ;
563+
564+ // Check for browser environment
565+ if ( typeof window !== "undefined" && window . crypto && window . crypto . subtle ) {
566+ crypto = window . crypto ;
567+ }
568+ // Check for Node.js environment
569+ else if ( typeof global !== "undefined" && global . crypto ) {
570+ crypto = global . crypto ;
571+ }
572+ // Fallback to native Node.js crypto module
573+ else {
574+ try {
575+ if ( typeof module !== "undefined" && module . exports ) {
576+ crypto = require ( "crypto" ) ;
577+ }
578+ else {
579+ crypto = await import ( "crypto" ) ;
580+ }
581+ } catch ( error ) {
582+ console . error ( "Failed to load the crypto module:" , error . message ) ;
583+ throw error ;
584+ }
585+ }
586+
587+ let baseString = `${ setting . key } \n` ;
588+ if ( setting . label && setting . label . trim ( ) . length !== 0 ) {
589+ baseString += `${ setting . label } ` ;
590+ }
591+
592+ // Convert to UTF-8 encoded bytes
593+ const data = new TextEncoder ( ) . encode ( baseString ) ;
594+
595+ // In the browser, use crypto.subtle.digest
596+ if ( crypto . subtle ) {
597+ const hashBuffer = await crypto . subtle . digest ( "SHA-256" , data ) ;
598+ const hashArray = new Uint8Array ( hashBuffer ) ;
599+ const base64String = btoa ( String . fromCharCode ( ...hashArray ) ) ;
600+ const base64urlString = base64String . replace ( / \+ / g, '-' ) . replace ( / \/ / g, '_' ) . replace ( / = + $ / , '' ) ;
601+ return base64urlString
602+ }
603+ // In Node.js, use the crypto module's hash function
604+ else {
605+ const hash = crypto . createHash ( "sha256" ) . update ( data ) . digest ( ) ;
606+ return hash . toString ( "base64url" )
607+ }
563608 }
564609
565610 #createFeatureFlagReference( setting : ConfigurationSetting < string > ) : string {
0 commit comments