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 ;
2324import java .util .Set ;
2425import java .util .stream .Collectors ;
2526import software .amazon .smithy .codegen .core .SymbolDependency ;
2627import software .amazon .smithy .model .Model ;
28+ import software .amazon .smithy .model .node .Node ;
2729import software .amazon .smithy .model .node .ObjectNode ;
2830import software .amazon .smithy .model .shapes .ServiceShape ;
2931import software .amazon .smithy .rulesengine .traits .EndpointRuleSetTrait ;
@@ -117,15 +119,42 @@ private void generateEndpointParameters() {
117119 "export interface ClientInputEndpointParameters {" ,
118120 "}" ,
119121 () -> {
120- Map <String , String > clientInputParams = ruleSetParameterFinder . getClientContextParams ();
121- //Omit Endpoint params that should not be a part of the ClientInputEndpointParameters interface
122+ Map <String , String > clientContextParams =
123+ ruleSetParameterFinder . getClientContextParams ();
122124 Map <String , String > builtInParams = ruleSetParameterFinder .getBuiltInParams ();
123125 builtInParams .keySet ().removeIf (OmitEndpointParams ::isOmitted );
124- clientInputParams .putAll (builtInParams );
125-
126+ Set <String > knownConfigKeys = Set .of (
127+ "apiKey" , "retryStrategy" , "requestHandler" );
128+ // Generate clientContextParams with all params excluding built-ins
129+ Map <String , String > customerContextParams = new HashMap <>();
130+ for (Map .Entry <String , String > entry : clientContextParams .entrySet ()) {
131+ if (!builtInParams .containsKey (entry .getKey ())) {
132+ customerContextParams .put (entry .getKey (), entry .getValue ());
133+ }
134+ }
135+ if (!customerContextParams .isEmpty ()) {
136+ writer .write ("clientContextParams: {" );
137+ writer .indent ();
138+ ObjectNode ruleSet = endpointRuleSetTrait .getRuleSet ().expectObjectNode ();
139+ ruleSet .getObjectMember ("parameters" ).ifPresent (parameters -> {
140+ parameters .accept (new RuleSetParametersVisitor (
141+ writer , customerContextParams , true ));
142+ });
143+ writer .dedent ();
144+ writer .write ("};" );
145+ }
146+ // Add direct params (built-ins + non-conflicting client context params)
147+ Map <String , String > directParams = new HashMap <>(builtInParams );
148+ for (Map .Entry <String , String > entry : clientContextParams .entrySet ()) {
149+ // Only add non-conflicting client context params that aren't built-ins
150+ if (!knownConfigKeys .contains (entry .getKey ())
151+ && !builtInParams .containsKey (entry .getKey ())) {
152+ directParams .put (entry .getKey (), entry .getValue ());
153+ }
154+ }
126155 ObjectNode ruleSet = endpointRuleSetTrait .getRuleSet ().expectObjectNode ();
127156 ruleSet .getObjectMember ("parameters" ).ifPresent (parameters -> {
128- parameters .accept (new RuleSetParametersVisitor (writer , clientInputParams , true ));
157+ parameters .accept (new RuleSetParametersVisitor (writer , directParams , true ));
129158 });
130159 }
131160 );
@@ -138,6 +167,54 @@ private void generateEndpointParameters() {
138167 defaultSigningName: string;
139168 };"""
140169 );
170+ // Generate clientContextParamDefaults only if there are customer context params
171+ Map <String , String > clientContextParams = ruleSetParameterFinder .getClientContextParams ();
172+ Map <String , String > builtInParams = ruleSetParameterFinder .getBuiltInParams ();
173+ Map <String , String > customerContextParams = new HashMap <>();
174+ for (Map .Entry <String , String > entry : clientContextParams .entrySet ()) {
175+ if (!builtInParams .containsKey (entry .getKey ())) {
176+ customerContextParams .put (entry .getKey (), entry .getValue ());
177+ }
178+ }
179+ if (!customerContextParams .isEmpty ()) {
180+ // Check if any parameters have default values
181+ boolean hasDefaults = false ;
182+ ObjectNode ruleSet = endpointRuleSetTrait .getRuleSet ().expectObjectNode ();
183+ if (ruleSet .getObjectMember ("parameters" ).isPresent ()) {
184+ ObjectNode parameters = ruleSet .getObjectMember ("parameters" ).get ().expectObjectNode ();
185+ for (Map .Entry <String , String > entry : customerContextParams .entrySet ()) {
186+ String paramName = entry .getKey ();
187+ ObjectNode paramNode = parameters .getObjectMember (paramName ).orElse (null );
188+ if (paramNode != null && paramNode .containsMember ("default" )) {
189+ hasDefaults = true ;
190+ break ;
191+ }
192+ }
193+ }
194+ if (hasDefaults ) {
195+ writer .write ("" );
196+ writer .writeDocs ("@internal" );
197+ writer .openBlock ("const clientContextParamDefaults = {" , "} as const;" , () -> {
198+ ruleSet .getObjectMember ("parameters" ).ifPresent (parameters -> {
199+ for (Map .Entry <String , String > entry : customerContextParams .entrySet ()) {
200+ String paramName = entry .getKey ();
201+ ObjectNode paramNode = parameters .expectObjectNode ()
202+ .getObjectMember (paramName ).orElse (null );
203+ if (paramNode != null && paramNode .containsMember ("default" )) {
204+ Node defaultValue = paramNode .getMember ("default" ).get ();
205+ if (defaultValue .isStringNode ()) {
206+ writer .write ("$L: \" $L\" ," , paramName ,
207+ defaultValue .expectStringNode ().getValue ());
208+ } else if (defaultValue .isBooleanNode ()) {
209+ writer .write ("$L: $L," , paramName ,
210+ defaultValue .expectBooleanNode ().getValue ());
211+ }
212+ }
213+ }
214+ });
215+ });
216+ }
217+ }
141218 writer .write ("" );
142219
143220 writer .writeDocs ("@internal" );
0 commit comments