@@ -10,7 +10,6 @@ import { JsonKeyValueAdapter } from "./JsonKeyValueAdapter.js";
1010import { DEFAULT_STARTUP_TIMEOUT_IN_MS } from "./StartupOptions.js" ;
1111import { DEFAULT_REFRESH_INTERVAL_IN_MS , MIN_REFRESH_INTERVAL_IN_MS } from "./refresh/refreshOptions.js" ;
1212import { Disposable } from "./common/disposable.js" ;
13- import { base64Helper , jsonSorter } from "./common/utils.js" ;
1413import {
1514 FEATURE_FLAGS_KEY_NAME ,
1615 FEATURE_MANAGEMENT_KEY_NAME ,
@@ -21,16 +20,9 @@ import {
2120 ETAG_KEY_NAME ,
2221 FEATURE_FLAG_ID_KEY_NAME ,
2322 FEATURE_FLAG_REFERENCE_KEY_NAME ,
24- ALLOCATION_ID_KEY_NAME ,
2523 ALLOCATION_KEY_NAME ,
26- DEFAULT_WHEN_ENABLED_KEY_NAME ,
27- PERCENTILE_KEY_NAME ,
28- FROM_KEY_NAME ,
29- TO_KEY_NAME ,
3024 SEED_KEY_NAME ,
31- VARIANT_KEY_NAME ,
3225 VARIANTS_KEY_NAME ,
33- CONFIGURATION_VALUE_KEY_NAME ,
3426 CONDITIONS_KEY_NAME ,
3527 CLIENT_FILTERS_KEY_NAME
3628} from "./featureManagement/constants.js" ;
@@ -746,15 +738,10 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
746738
747739 if ( featureFlag [ TELEMETRY_KEY_NAME ] && featureFlag [ TELEMETRY_KEY_NAME ] [ ENABLED_KEY_NAME ] === true ) {
748740 const metadata = featureFlag [ TELEMETRY_KEY_NAME ] [ METADATA_KEY_NAME ] ;
749- let allocationId = "" ;
750- if ( featureFlag [ ALLOCATION_KEY_NAME ] !== undefined ) {
751- allocationId = await this . #generateAllocationId( featureFlag ) ;
752- }
753741 featureFlag [ TELEMETRY_KEY_NAME ] [ METADATA_KEY_NAME ] = {
754742 [ ETAG_KEY_NAME ] : setting . etag ,
755743 [ FEATURE_FLAG_ID_KEY_NAME ] : await this . #calculateFeatureFlagId( setting ) ,
756744 [ FEATURE_FLAG_REFERENCE_KEY_NAME ] : this . #createFeatureFlagReference( setting ) ,
757- ...( allocationId !== "" && { [ ALLOCATION_ID_KEY_NAME ] : allocationId } ) ,
758745 ...( metadata || { } )
759746 } ;
760747 }
@@ -838,116 +825,6 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
838825 }
839826 return featureFlagReference ;
840827 }
841-
842- async #generateAllocationId( featureFlag : any ) : Promise < string > {
843- let rawAllocationId = "" ;
844- // Only default variant when enabled and variants allocated by percentile involve in the experimentation
845- // The allocation id is genearted from default variant when enabled and percentile allocation
846- const variantsForExperimentation : string [ ] = [ ] ;
847-
848- rawAllocationId += `seed=${ featureFlag [ ALLOCATION_KEY_NAME ] [ SEED_KEY_NAME ] ?? "" } \ndefault_when_enabled=` ;
849-
850- if ( featureFlag [ ALLOCATION_KEY_NAME ] [ DEFAULT_WHEN_ENABLED_KEY_NAME ] ) {
851- variantsForExperimentation . push ( featureFlag [ ALLOCATION_KEY_NAME ] [ DEFAULT_WHEN_ENABLED_KEY_NAME ] ) ;
852- rawAllocationId += `${ featureFlag [ ALLOCATION_KEY_NAME ] [ DEFAULT_WHEN_ENABLED_KEY_NAME ] } ` ;
853- }
854-
855- rawAllocationId += "\npercentiles=" ;
856-
857- const percentileList = featureFlag [ ALLOCATION_KEY_NAME ] [ PERCENTILE_KEY_NAME ] ;
858- if ( percentileList ) {
859- const sortedPercentileList = percentileList
860- . filter ( p =>
861- ( p [ FROM_KEY_NAME ] !== undefined ) &&
862- ( p [ TO_KEY_NAME ] !== undefined ) &&
863- ( p [ VARIANT_KEY_NAME ] !== undefined ) &&
864- ( p [ FROM_KEY_NAME ] !== p [ TO_KEY_NAME ] ) )
865- . sort ( ( a , b ) => a [ FROM_KEY_NAME ] - b [ FROM_KEY_NAME ] ) ;
866-
867- const percentileAllocation : string [ ] = [ ] ;
868- for ( const percentile of sortedPercentileList ) {
869- variantsForExperimentation . push ( percentile [ VARIANT_KEY_NAME ] ) ;
870- percentileAllocation . push ( `${ percentile [ FROM_KEY_NAME ] } ,${ base64Helper ( percentile [ VARIANT_KEY_NAME ] ) } ,${ percentile [ TO_KEY_NAME ] } ` ) ;
871- }
872- rawAllocationId += percentileAllocation . join ( ";" ) ;
873- }
874-
875- if ( variantsForExperimentation . length === 0 && featureFlag [ ALLOCATION_KEY_NAME ] [ SEED_KEY_NAME ] === undefined ) {
876- // All fields required for generating allocation id are missing, short-circuit and return empty string
877- return "" ;
878- }
879-
880- rawAllocationId += "\nvariants=" ;
881-
882- if ( variantsForExperimentation . length !== 0 ) {
883- const variantsList = featureFlag [ VARIANTS_KEY_NAME ] ;
884- if ( variantsList ) {
885- const sortedVariantsList = variantsList
886- . filter ( v =>
887- ( v [ NAME_KEY_NAME ] !== undefined ) &&
888- variantsForExperimentation . includes ( v [ NAME_KEY_NAME ] ) )
889- . sort ( ( a , b ) => ( a . name > b . name ? 1 : - 1 ) ) ;
890-
891- const variantConfiguration : string [ ] = [ ] ;
892- for ( const variant of sortedVariantsList ) {
893- const configurationValue = JSON . stringify ( variant [ CONFIGURATION_VALUE_KEY_NAME ] , jsonSorter ) ?? "" ;
894- variantConfiguration . push ( `${ base64Helper ( variant [ NAME_KEY_NAME ] ) } ,${ configurationValue } ` ) ;
895- }
896- rawAllocationId += variantConfiguration . join ( ";" ) ;
897- }
898- }
899-
900- let crypto ;
901-
902- // Check for browser environment
903- if ( typeof window !== "undefined" && window . crypto && window . crypto . subtle ) {
904- crypto = window . crypto ;
905- }
906- // Check for Node.js environment
907- else if ( typeof global !== "undefined" && global . crypto ) {
908- crypto = global . crypto ;
909- }
910- // Fallback to native Node.js crypto module
911- else {
912- try {
913- if ( typeof module !== "undefined" && module . exports ) {
914- crypto = require ( "crypto" ) ;
915- }
916- else {
917- crypto = await import ( "crypto" ) ;
918- }
919- } catch ( error ) {
920- console . error ( "Failed to load the crypto module:" , error . message ) ;
921- throw error ;
922- }
923- }
924-
925- // Convert to UTF-8 encoded bytes
926- const data = new TextEncoder ( ) . encode ( rawAllocationId ) ;
927-
928- // In the browser, use crypto.subtle.digest
929- if ( crypto . subtle ) {
930- const hashBuffer = await crypto . subtle . digest ( "SHA-256" , data ) ;
931- const hashArray = new Uint8Array ( hashBuffer ) ;
932-
933- // Only use the first 15 bytes
934- const first15Bytes = hashArray . slice ( 0 , 15 ) ;
935-
936- // btoa/atob is also available in Node.js 18+
937- const base64String = btoa ( String . fromCharCode ( ...first15Bytes ) ) ;
938- const base64urlString = base64String . replace ( / \+ / g, "-" ) . replace ( / \/ / g, "_" ) . replace ( / = + $ / , "" ) ;
939- return base64urlString ;
940- }
941- // In Node.js, use the crypto module's hash function
942- else {
943- const hash = crypto . createHash ( "sha256" ) . update ( data ) . digest ( ) ;
944-
945- // Only use the first 15 bytes
946- const first15Bytes = hash . slice ( 0 , 15 ) ;
947-
948- return first15Bytes . toString ( "base64url" ) ;
949- }
950- }
951828}
952829
953830function getValidSelectors ( selectors : SettingSelector [ ] ) : SettingSelector [ ] {
0 commit comments