1717
1818import java .nio .file .Paths ;
1919import java .util .Collections ;
20+ import java .util .HashMap ;
2021import java .util .HashSet ;
2122import java .util .List ;
2223import java .util .Map ;
@@ -117,15 +118,41 @@ private void generateEndpointParameters() {
117118 "export interface ClientInputEndpointParameters {" ,
118119 "}" ,
119120 () -> {
120- Map <String , String > clientInputParams = ruleSetParameterFinder .getClientContextParams ();
121- //Omit Endpoint params that should not be a part of the ClientInputEndpointParameters interface
121+ Map <String , String > clientContextParams = ruleSetParameterFinder .getClientContextParams ();
122122 Map <String , String > builtInParams = ruleSetParameterFinder .getBuiltInParams ();
123123 builtInParams .keySet ().removeIf (OmitEndpointParams ::isOmitted );
124- clientInputParams .putAll (builtInParams );
125-
124+ // Known config keys that could collide
125+ Set <String > knownConfigKeys = Set .of (
126+ "apiKey" , "retryStrategy" , "requestHandler" );
127+ // Built-in params that should not be in clientContextParams
128+ Set <String > builtinParamNames = Set .of ("region" , "fips" , "dualstack" , "endpoint" );
129+ // Separate conflicting params into clientContextParams
130+ Map <String , String > nestedParams = new HashMap <>();
131+ Map <String , String > directParams = new HashMap <>(builtInParams );
132+ for (Map .Entry <String , String > entry : clientContextParams .entrySet ()) {
133+ // params that should go in clientContextParams, exclude builtins
134+ if (knownConfigKeys .contains (entry .getKey ())
135+ && !builtinParamNames .contains (entry .getKey ())) {
136+ nestedParams .put (entry .getKey (), entry .getValue ());
137+ } else {
138+ directParams .put (entry .getKey (), entry .getValue ());
139+ }
140+ }
141+ // Add clientContextParams for conflicting params
142+ if (!nestedParams .isEmpty ()) {
143+ writer .write ("clientContextParams?: {" );
144+ writer .indent ();
145+ ObjectNode ruleSet = endpointRuleSetTrait .getRuleSet ().expectObjectNode ();
146+ ruleSet .getObjectMember ("parameters" ).ifPresent (parameters -> {
147+ parameters .accept (new RuleSetParametersVisitor (writer , nestedParams , true ));
148+ });
149+ writer .dedent ();
150+ writer .write ("};" );
151+ }
152+ // Add direct params
126153 ObjectNode ruleSet = endpointRuleSetTrait .getRuleSet ().expectObjectNode ();
127154 ruleSet .getObjectMember ("parameters" ).ifPresent (parameters -> {
128- parameters .accept (new RuleSetParametersVisitor (writer , clientInputParams , true ));
155+ parameters .accept (new RuleSetParametersVisitor (writer , directParams , true ));
129156 });
130157 }
131158 );
@@ -149,6 +176,21 @@ private void generateEndpointParameters() {
149176 "}" ,
150177 () -> {
151178 writer .openBlock ("return Object.assign(options, {" , "});" , () -> {
179+ // Add precedence logic for conflicting params
180+ Map <String , String > clientContextParams =
181+ ruleSetParameterFinder .getClientContextParams ();
182+ Set <String > knownConfigKeys = Set .of (
183+ "apiKey" , "retryStrategy" , "requestHandler" );
184+ Set <String > builtinParamNames = Set .of ("region" , "fips" , "dualstack" , "endpoint" );
185+ for (Map .Entry <String , String > entry
186+ : clientContextParams .entrySet ()) {
187+ // Only use clientContextParams precedence for customer-defined params, not builtins
188+ if (knownConfigKeys .contains (entry .getKey ())
189+ && !builtinParamNames .contains (entry .getKey ())) {
190+ writer .write ("$L: options.clientContextParams?.$L ?? options.$L," ,
191+ entry .getKey (), entry .getKey (), entry .getKey ());
192+ }
193+ }
152194 ObjectNode ruleSet = endpointRuleSetTrait .getRuleSet ().expectObjectNode ();
153195 ruleSet .getObjectMember ("parameters" ).ifPresent (parameters -> {
154196 parameters .accept (new RuleSetParametersVisitor (writer , true ));
0 commit comments