|
17 | 17 |
|
18 | 18 | import java.nio.file.Paths; |
19 | 19 | import java.util.Collections; |
| 20 | +import java.util.HashMap; |
20 | 21 | import java.util.HashSet; |
21 | 22 | import java.util.List; |
22 | 23 | import java.util.Map; |
23 | 24 | import java.util.Set; |
24 | 25 | import java.util.stream.Collectors; |
25 | 26 | import software.amazon.smithy.codegen.core.SymbolDependency; |
26 | 27 | import software.amazon.smithy.model.Model; |
| 28 | +import software.amazon.smithy.model.node.Node; |
27 | 29 | import software.amazon.smithy.model.node.ObjectNode; |
28 | 30 | import software.amazon.smithy.model.shapes.ServiceShape; |
29 | 31 | import software.amazon.smithy.rulesengine.traits.EndpointRuleSetTrait; |
@@ -117,31 +119,125 @@ private void generateEndpointParameters() { |
117 | 119 | "export interface ClientInputEndpointParameters {", |
118 | 120 | "}", |
119 | 121 | () -> { |
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(); |
122 | 124 | Map<String, String> builtInParams = ruleSetParameterFinder.getBuiltInParams(); |
123 | 125 | 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 | + } |
126 | 155 | ObjectNode ruleSet = endpointRuleSetTrait.getRuleSet().expectObjectNode(); |
127 | 156 | ruleSet.getObjectMember("parameters").ifPresent(parameters -> { |
128 | | - parameters.accept(new RuleSetParametersVisitor(writer, clientInputParams, true)); |
| 157 | + parameters.accept(new RuleSetParametersVisitor(writer, directParams, true)); |
129 | 158 | }); |
130 | 159 | } |
131 | 160 | ); |
132 | 161 |
|
133 | 162 | writer.write(""); |
134 | | - writer.openBlock( |
| 163 | + writer.openBlock( |
135 | 164 | """ |
136 | 165 | export type ClientResolvedEndpointParameters = Omit<ClientInputEndpointParameters, "endpoint"> & { |
137 | 166 | """, |
138 | 167 | "};", |
139 | 168 | () -> { |
140 | 169 | writer.write("defaultSigningName: string;"); |
| 170 | + // Add clientContextParams with same structure as input |
| 171 | + Map<String, String> clientContextParams = ruleSetParameterFinder.getClientContextParams(); |
| 172 | + Map<String, String> customerContextParams = new HashMap<>(); |
| 173 | + Map<String, String> builtInParams = ruleSetParameterFinder.getBuiltInParams(); |
| 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 | + writer.write("clientContextParams: {"); |
| 181 | + writer.indent(); |
| 182 | + ObjectNode ruleSet = endpointRuleSetTrait.getRuleSet().expectObjectNode(); |
| 183 | + ruleSet.getObjectMember("parameters").ifPresent(parameters -> { |
| 184 | + parameters.accept(new RuleSetParametersVisitor( |
| 185 | + writer, customerContextParams, false)); |
| 186 | + }); |
| 187 | + writer.dedent(); |
| 188 | + writer.write("};"); |
| 189 | + } |
141 | 190 | } |
142 | 191 | ); |
| 192 | + // Generate clientContextParamDefaults only if there are customer context params |
| 193 | + Map<String, String> clientContextParams = ruleSetParameterFinder.getClientContextParams(); |
| 194 | + Map<String, String> builtInParams = ruleSetParameterFinder.getBuiltInParams(); |
| 195 | + Map<String, String> customerContextParams = new HashMap<>(); |
| 196 | + for (Map.Entry<String, String> entry : clientContextParams.entrySet()) { |
| 197 | + if (!builtInParams.containsKey(entry.getKey())) { |
| 198 | + customerContextParams.put(entry.getKey(), entry.getValue()); |
| 199 | + } |
| 200 | + } |
| 201 | + if (!customerContextParams.isEmpty()) { |
| 202 | + // Check if any parameters have default values |
| 203 | + boolean hasDefaults = false; |
| 204 | + ObjectNode ruleSet = endpointRuleSetTrait.getRuleSet().expectObjectNode(); |
| 205 | + if (ruleSet.getObjectMember("parameters").isPresent()) { |
| 206 | + ObjectNode parameters = ruleSet.getObjectMember("parameters").get().expectObjectNode(); |
| 207 | + for (Map.Entry<String, String> entry : customerContextParams.entrySet()) { |
| 208 | + String paramName = entry.getKey(); |
| 209 | + ObjectNode paramNode = parameters.getObjectMember(paramName).orElse(null); |
| 210 | + if (paramNode != null && paramNode.containsMember("default")) { |
| 211 | + hasDefaults = true; |
| 212 | + break; |
| 213 | + } |
| 214 | + } |
| 215 | + } |
| 216 | + if (hasDefaults) { |
| 217 | + writer.write(""); |
| 218 | + writer.writeDocs("@internal"); |
| 219 | + writer.openBlock("const clientContextParamDefaults = {", "} as const;", () -> { |
| 220 | + ruleSet.getObjectMember("parameters").ifPresent(parameters -> { |
| 221 | + for (Map.Entry<String, String> entry : customerContextParams.entrySet()) { |
| 222 | + String paramName = entry.getKey(); |
| 223 | + ObjectNode paramNode = parameters.expectObjectNode() |
| 224 | + .getObjectMember(paramName).orElse(null); |
| 225 | + if (paramNode != null && paramNode.containsMember("default")) { |
| 226 | + Node defaultValue = paramNode.getMember("default").get(); |
| 227 | + if (defaultValue.isStringNode()) { |
| 228 | + writer.write("$L: \"$L\",", paramName, |
| 229 | + defaultValue.expectStringNode().getValue()); |
| 230 | + } else if (defaultValue.isBooleanNode()) { |
| 231 | + writer.write("$L: $L,", paramName, |
| 232 | + defaultValue.expectBooleanNode().getValue()); |
| 233 | + } |
| 234 | + } |
| 235 | + } |
| 236 | + }); |
| 237 | + }); |
| 238 | + } |
| 239 | + } |
143 | 240 | writer.write(""); |
144 | | - |
145 | 241 | writer.openBlock( |
146 | 242 | "export const resolveClientEndpointParameters = " |
147 | 243 | + "<T>(options: T & ClientInputEndpointParameters" |
|
0 commit comments