@@ -9,7 +9,6 @@ import { IKeyValueAdapter } from "./IKeyValueAdapter.js";
99import { JsonKeyValueAdapter } from "./JsonKeyValueAdapter.js" ;
1010import { DEFAULT_REFRESH_INTERVAL_IN_MS , MIN_REFRESH_INTERVAL_IN_MS } from "./RefreshOptions.js" ;
1111import { Disposable } from "./common/disposable.js" ;
12- import { base64Helper , jsonSorter } from "./common/utils.js" ;
1312import {
1413 FEATURE_FLAGS_KEY_NAME ,
1514 FEATURE_MANAGEMENT_KEY_NAME ,
@@ -20,16 +19,9 @@ import {
2019 ETAG_KEY_NAME ,
2120 FEATURE_FLAG_ID_KEY_NAME ,
2221 FEATURE_FLAG_REFERENCE_KEY_NAME ,
23- ALLOCATION_ID_KEY_NAME ,
2422 ALLOCATION_KEY_NAME ,
25- DEFAULT_WHEN_ENABLED_KEY_NAME ,
26- PERCENTILE_KEY_NAME ,
27- FROM_KEY_NAME ,
28- TO_KEY_NAME ,
2923 SEED_KEY_NAME ,
30- VARIANT_KEY_NAME ,
3124 VARIANTS_KEY_NAME ,
32- CONFIGURATION_VALUE_KEY_NAME ,
3325 CONDITIONS_KEY_NAME ,
3426 CLIENT_FILTERS_KEY_NAME
3527} from "./featureManagement/constants.js" ;
@@ -677,15 +669,10 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
677669
678670 if ( featureFlag [ TELEMETRY_KEY_NAME ] && featureFlag [ TELEMETRY_KEY_NAME ] [ ENABLED_KEY_NAME ] === true ) {
679671 const metadata = featureFlag [ TELEMETRY_KEY_NAME ] [ METADATA_KEY_NAME ] ;
680- let allocationId = "" ;
681- if ( featureFlag [ ALLOCATION_KEY_NAME ] !== undefined ) {
682- allocationId = await this . #generateAllocationId( featureFlag ) ;
683- }
684672 featureFlag [ TELEMETRY_KEY_NAME ] [ METADATA_KEY_NAME ] = {
685673 [ ETAG_KEY_NAME ] : setting . etag ,
686674 [ FEATURE_FLAG_ID_KEY_NAME ] : await this . #calculateFeatureFlagId( setting ) ,
687675 [ FEATURE_FLAG_REFERENCE_KEY_NAME ] : this . #createFeatureFlagReference( setting ) ,
688- ...( allocationId !== "" && { [ ALLOCATION_ID_KEY_NAME ] : allocationId } ) ,
689676 ...( metadata || { } )
690677 } ;
691678 }
@@ -769,116 +756,6 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
769756 }
770757 return featureFlagReference ;
771758 }
772-
773- async #generateAllocationId( featureFlag : any ) : Promise < string > {
774- let rawAllocationId = "" ;
775- // Only default variant when enabled and variants allocated by percentile involve in the experimentation
776- // The allocation id is genearted from default variant when enabled and percentile allocation
777- const variantsForExperimentation : string [ ] = [ ] ;
778-
779- rawAllocationId += `seed=${ featureFlag [ ALLOCATION_KEY_NAME ] [ SEED_KEY_NAME ] ?? "" } \ndefault_when_enabled=` ;
780-
781- if ( featureFlag [ ALLOCATION_KEY_NAME ] [ DEFAULT_WHEN_ENABLED_KEY_NAME ] ) {
782- variantsForExperimentation . push ( featureFlag [ ALLOCATION_KEY_NAME ] [ DEFAULT_WHEN_ENABLED_KEY_NAME ] ) ;
783- rawAllocationId += `${ featureFlag [ ALLOCATION_KEY_NAME ] [ DEFAULT_WHEN_ENABLED_KEY_NAME ] } ` ;
784- }
785-
786- rawAllocationId += "\npercentiles=" ;
787-
788- const percentileList = featureFlag [ ALLOCATION_KEY_NAME ] [ PERCENTILE_KEY_NAME ] ;
789- if ( percentileList ) {
790- const sortedPercentileList = percentileList
791- . filter ( p =>
792- ( p [ FROM_KEY_NAME ] !== undefined ) &&
793- ( p [ TO_KEY_NAME ] !== undefined ) &&
794- ( p [ VARIANT_KEY_NAME ] !== undefined ) &&
795- ( p [ FROM_KEY_NAME ] !== p [ TO_KEY_NAME ] ) )
796- . sort ( ( a , b ) => a [ FROM_KEY_NAME ] - b [ FROM_KEY_NAME ] ) ;
797-
798- const percentileAllocation : string [ ] = [ ] ;
799- for ( const percentile of sortedPercentileList ) {
800- variantsForExperimentation . push ( percentile [ VARIANT_KEY_NAME ] ) ;
801- percentileAllocation . push ( `${ percentile [ FROM_KEY_NAME ] } ,${ base64Helper ( percentile [ VARIANT_KEY_NAME ] ) } ,${ percentile [ TO_KEY_NAME ] } ` ) ;
802- }
803- rawAllocationId += percentileAllocation . join ( ";" ) ;
804- }
805-
806- if ( variantsForExperimentation . length === 0 && featureFlag [ ALLOCATION_KEY_NAME ] [ SEED_KEY_NAME ] === undefined ) {
807- // All fields required for generating allocation id are missing, short-circuit and return empty string
808- return "" ;
809- }
810-
811- rawAllocationId += "\nvariants=" ;
812-
813- if ( variantsForExperimentation . length !== 0 ) {
814- const variantsList = featureFlag [ VARIANTS_KEY_NAME ] ;
815- if ( variantsList ) {
816- const sortedVariantsList = variantsList
817- . filter ( v =>
818- ( v [ NAME_KEY_NAME ] !== undefined ) &&
819- variantsForExperimentation . includes ( v [ NAME_KEY_NAME ] ) )
820- . sort ( ( a , b ) => ( a . name > b . name ? 1 : - 1 ) ) ;
821-
822- const variantConfiguration : string [ ] = [ ] ;
823- for ( const variant of sortedVariantsList ) {
824- const configurationValue = JSON . stringify ( variant [ CONFIGURATION_VALUE_KEY_NAME ] , jsonSorter ) ?? "" ;
825- variantConfiguration . push ( `${ base64Helper ( variant [ NAME_KEY_NAME ] ) } ,${ configurationValue } ` ) ;
826- }
827- rawAllocationId += variantConfiguration . join ( ";" ) ;
828- }
829- }
830-
831- let crypto ;
832-
833- // Check for browser environment
834- if ( typeof window !== "undefined" && window . crypto && window . crypto . subtle ) {
835- crypto = window . crypto ;
836- }
837- // Check for Node.js environment
838- else if ( typeof global !== "undefined" && global . crypto ) {
839- crypto = global . crypto ;
840- }
841- // Fallback to native Node.js crypto module
842- else {
843- try {
844- if ( typeof module !== "undefined" && module . exports ) {
845- crypto = require ( "crypto" ) ;
846- }
847- else {
848- crypto = await import ( "crypto" ) ;
849- }
850- } catch ( error ) {
851- console . error ( "Failed to load the crypto module:" , error . message ) ;
852- throw error ;
853- }
854- }
855-
856- // Convert to UTF-8 encoded bytes
857- const data = new TextEncoder ( ) . encode ( rawAllocationId ) ;
858-
859- // In the browser, use crypto.subtle.digest
860- if ( crypto . subtle ) {
861- const hashBuffer = await crypto . subtle . digest ( "SHA-256" , data ) ;
862- const hashArray = new Uint8Array ( hashBuffer ) ;
863-
864- // Only use the first 15 bytes
865- const first15Bytes = hashArray . slice ( 0 , 15 ) ;
866-
867- // btoa/atob is also available in Node.js 18+
868- const base64String = btoa ( String . fromCharCode ( ...first15Bytes ) ) ;
869- const base64urlString = base64String . replace ( / \+ / g, "-" ) . replace ( / \/ / g, "_" ) . replace ( / = + $ / , "" ) ;
870- return base64urlString ;
871- }
872- // In Node.js, use the crypto module's hash function
873- else {
874- const hash = crypto . createHash ( "sha256" ) . update ( data ) . digest ( ) ;
875-
876- // Only use the first 15 bytes
877- const first15Bytes = hash . slice ( 0 , 15 ) ;
878-
879- return first15Bytes . toString ( "base64url" ) ;
880- }
881- }
882759}
883760
884761function getValidSelectors ( selectors : SettingSelector [ ] ) : SettingSelector [ ] {
0 commit comments