Skip to content

Commit 20acec0

Browse files
Steven Yuansyall
Steven Yuan
authored andcommitted
feat(experimentalIdentityAndAuth): update code generation
Make code generation changes for `experimentalIdentityAndAuth`. Bug fixes: - fix misused service name when importing the default auth scheme provider - add generic type to resolve config function input and output Updates: - add remove methods to `HttpAuthScheme` builder - update code generation for `ConfigField` (and more code sections) - update `customizeSupportedHttpAuthSchemes()` to include model and settings - add resolve functions codegen for `HttpAuthScheme`s - update various `String` parameters to take `Symbol` instead
1 parent 106487e commit 20acec0

25 files changed

+1491
-406
lines changed

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/ConfigField.java

-103
This file was deleted.

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/RuntimeConfigGenerator.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -213,13 +213,15 @@ private void generateHttpAuthSchemeConfig(
213213
TypeScriptWriter writer,
214214
LanguageTarget target
215215
) {
216-
SupportedHttpAuthSchemesIndex authIndex = new SupportedHttpAuthSchemesIndex(integrations);
216+
SupportedHttpAuthSchemesIndex authIndex = new SupportedHttpAuthSchemesIndex(integrations, model, settings);
217217

218218
// feat(experimentalIdentityAndAuth): write the default imported HttpAuthSchemeProvider
219219
if (target.equals(LanguageTarget.SHARED)) {
220220
configs.put("httpAuthSchemeProvider", w -> {
221221
w.write("$T", Symbol.builder()
222-
.name("default" + service.toShapeId().getName() + "HttpAuthSchemeProvider")
222+
.name("default"
223+
+ CodegenUtils.getServiceName(settings, model, symbolProvider)
224+
+ "HttpAuthSchemeProvider")
223225
.namespace(AuthUtils.AUTH_HTTP_PROVIDER_DEPENDENCY.getPackageName(), "/")
224226
.build());
225227
});

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/ServiceBareBonesClientGenerator.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
* Generates a bare-bones client and configuration for service using plugins.
4949
*/
5050
@SmithyInternalApi
51-
final class ServiceBareBonesClientGenerator implements Runnable {
51+
public final class ServiceBareBonesClientGenerator implements Runnable {
5252

5353
private final TypeScriptSettings settings;
5454
private final Model model;
@@ -88,11 +88,11 @@ final class ServiceBareBonesClientGenerator implements Runnable {
8888
resolvedConfigType = getResolvedConfigTypeName(symbol);
8989
}
9090

91-
static String getConfigTypeName(Symbol symbol) {
91+
public static String getConfigTypeName(Symbol symbol) {
9292
return symbol.getName() + "Config";
9393
}
9494

95-
static String getResolvedConfigTypeName(Symbol symbol) {
95+
public static String getResolvedConfigTypeName(Symbol symbol) {
9696
return symbol.getName() + "ResolvedConfig";
9797
}
9898

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/auth/AuthUtils.java

+33-3
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,19 @@
1313
import java.util.Map;
1414
import java.util.TreeMap;
1515
import software.amazon.smithy.codegen.core.CodegenException;
16+
import software.amazon.smithy.codegen.core.Symbol;
1617
import software.amazon.smithy.codegen.core.SymbolDependency;
1718
import software.amazon.smithy.model.knowledge.ServiceIndex;
1819
import software.amazon.smithy.model.knowledge.ServiceIndex.AuthSchemeMode;
1920
import software.amazon.smithy.model.shapes.ServiceShape;
2021
import software.amazon.smithy.model.shapes.ShapeId;
2122
import software.amazon.smithy.model.traits.Trait;
2223
import software.amazon.smithy.typescript.codegen.CodegenUtils;
23-
import software.amazon.smithy.typescript.codegen.ConfigField;
2424
import software.amazon.smithy.typescript.codegen.Dependency;
25+
import software.amazon.smithy.typescript.codegen.auth.http.ConfigField;
2526
import software.amazon.smithy.typescript.codegen.auth.http.HttpAuthScheme;
2627
import software.amazon.smithy.typescript.codegen.auth.http.HttpAuthSchemeParameter;
28+
import software.amazon.smithy.typescript.codegen.auth.http.ResolveConfigFunction;
2729
import software.amazon.smithy.typescript.codegen.auth.http.SupportedHttpAuthSchemesIndex;
2830
import software.amazon.smithy.utils.SmithyInternalApi;
2931

@@ -110,7 +112,7 @@ public static Map<String, ConfigField> collectConfigFields(Collection<HttpAuthSc
110112
if (configFields.containsKey(configField.name())) {
111113
ConfigField existingConfigField = configFields.get(configField.name());
112114
if (!configField.equals(existingConfigField)) {
113-
throw new CodegenException("Contradicting `ConfigField` defintions for `"
115+
throw new CodegenException("Contradicting `ConfigField` definitions for `"
114116
+ configField.name()
115117
+ "`; existing: "
116118
+ existingConfigField
@@ -125,6 +127,34 @@ public static Map<String, ConfigField> collectConfigFields(Collection<HttpAuthSc
125127
return configFields;
126128
}
127129

130+
public static Map<Symbol, ResolveConfigFunction> collectResolveConfigFunctions(
131+
Collection<HttpAuthScheme> httpAuthSchemes
132+
) {
133+
Map<Symbol, ResolveConfigFunction> resolveConfigFunctions = new HashMap<>();
134+
for (HttpAuthScheme authScheme : httpAuthSchemes) {
135+
if (authScheme == null) {
136+
continue;
137+
}
138+
for (ResolveConfigFunction fn : authScheme.getResolveConfigFunctions()) {
139+
if (resolveConfigFunctions.containsKey(fn.resolveConfigFunction())) {
140+
ResolveConfigFunction existingFn =
141+
resolveConfigFunctions.get(fn.resolveConfigFunction());
142+
if (!fn.equals(existingFn)) {
143+
throw new CodegenException("Contradicting `ResolveConfigFunction` definitions for `"
144+
+ fn.resolveConfigFunction()
145+
+ "`; existing: "
146+
+ existingFn
147+
+ ", conflict: "
148+
+ fn);
149+
}
150+
} else {
151+
resolveConfigFunctions.put(fn.resolveConfigFunction(), fn);
152+
}
153+
}
154+
}
155+
return resolveConfigFunctions;
156+
}
157+
128158
public static Map<String, HttpAuthSchemeParameter> collectHttpAuthSchemeParameters(
129159
Collection<HttpAuthScheme> httpAuthSchemes) {
130160
Map<String, HttpAuthSchemeParameter> httpAuthSchemeParameters = new HashMap<>();
@@ -136,7 +166,7 @@ public static Map<String, HttpAuthSchemeParameter> collectHttpAuthSchemeParamete
136166
if (httpAuthSchemeParameters.containsKey(param.name())) {
137167
HttpAuthSchemeParameter existingParam = httpAuthSchemeParameters.get(param.name());
138168
if (!param.equals(existingParam)) {
139-
throw new CodegenException("Contradicting `HttpAuthSchemeParameter` defintions for `"
169+
throw new CodegenException("Contradicting `HttpAuthSchemeParameter` definitions for `"
140170
+ param.name()
141171
+ "`; existing: "
142172
+ existingParam
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package software.amazon.smithy.typescript.codegen.auth.http;
7+
8+
import java.util.Optional;
9+
import java.util.function.BiConsumer;
10+
import java.util.function.Consumer;
11+
import software.amazon.smithy.codegen.core.Symbol;
12+
import software.amazon.smithy.typescript.codegen.TypeScriptDependency;
13+
import software.amazon.smithy.typescript.codegen.TypeScriptWriter;
14+
import software.amazon.smithy.utils.SmithyBuilder;
15+
import software.amazon.smithy.utils.SmithyInternalApi;
16+
import software.amazon.smithy.utils.SmithyUnstableApi;
17+
import software.amazon.smithy.utils.ToSmithyBuilder;
18+
19+
/**
20+
* Definition of a Config field.
21+
*
22+
* Currently used to populate the ClientDefaults interface in `experimentalIdentityAndAuth`.
23+
*
24+
* @param name name of the config field
25+
* @param type whether the config field is main or auxiliary
26+
* @param inputType writer for the input type of the config field
27+
* @param resolvedType writer for the resolved type of the config field
28+
* @param docs writer for the docs of the config field
29+
*/
30+
@SmithyUnstableApi
31+
public final record ConfigField(
32+
String name,
33+
Type type,
34+
Symbol inputType,
35+
Symbol resolvedType,
36+
BiConsumer<TypeScriptWriter, ConfigField> configFieldWriter,
37+
Optional<Consumer<TypeScriptWriter>> docs
38+
) implements ToSmithyBuilder<ConfigField> {
39+
40+
/**
41+
* Defines the type of the config field.
42+
*/
43+
@SmithyUnstableApi
44+
public enum Type {
45+
/**
46+
* Specifies the property is important, e.g. {@code apiKey} for {@code @httpApiKeyAuth}
47+
*/
48+
MAIN,
49+
/**
50+
* Specifies the property is auxiliary, e.g. {@code region} for {@code @aws.auth#sigv4}
51+
*/
52+
AUXILIARY
53+
}
54+
55+
public static Builder builder() {
56+
return new Builder();
57+
}
58+
59+
@Override
60+
public Builder toBuilder() {
61+
return builder()
62+
.name(name)
63+
.type(type)
64+
.inputType(inputType)
65+
.resolvedType(resolvedType)
66+
.configFieldWriter(configFieldWriter)
67+
.docs(docs.orElse(null));
68+
}
69+
70+
public static final class Builder implements SmithyBuilder<ConfigField> {
71+
private String name;
72+
private Type type;
73+
private Symbol inputType;
74+
private Symbol resolvedType;
75+
private Consumer<TypeScriptWriter> docs;
76+
private BiConsumer<TypeScriptWriter, ConfigField> configFieldWriter;
77+
78+
@Override
79+
public ConfigField build() {
80+
if (configFieldWriter == null) {
81+
configFieldWriter = type.equals(Type.MAIN)
82+
? ConfigField::defaultMainConfigFieldWriter
83+
: ConfigField::defaultAuxiliaryConfigFieldWriter;
84+
}
85+
return new ConfigField(
86+
SmithyBuilder.requiredState("name", name),
87+
SmithyBuilder.requiredState("type", type),
88+
SmithyBuilder.requiredState("inputType", inputType),
89+
SmithyBuilder.requiredState("resolvedType", resolvedType),
90+
SmithyBuilder.requiredState("configFieldWriter", configFieldWriter),
91+
Optional.ofNullable(docs));
92+
}
93+
94+
public Builder name(String name) {
95+
this.name = name;
96+
return this;
97+
}
98+
99+
public Builder type(Type type) {
100+
this.type = type;
101+
return this;
102+
}
103+
104+
public Builder inputType(Symbol inputType) {
105+
this.inputType = inputType;
106+
return this;
107+
}
108+
109+
public Builder resolvedType(Symbol resolvedType) {
110+
this.resolvedType = resolvedType;
111+
return this;
112+
}
113+
114+
public Builder docs(Consumer<TypeScriptWriter> docs) {
115+
this.docs = docs;
116+
return this;
117+
}
118+
119+
public Builder configFieldWriter(BiConsumer<TypeScriptWriter, ConfigField> configFieldWriter) {
120+
this.configFieldWriter = configFieldWriter;
121+
return this;
122+
}
123+
}
124+
125+
@SmithyInternalApi
126+
public static void defaultMainConfigFieldWriter(
127+
TypeScriptWriter w,
128+
ConfigField configField
129+
) {
130+
w.addDependency(TypeScriptDependency.SMITHY_CORE);
131+
w.addImport("memoizeIdentityProvider", null,
132+
TypeScriptDependency.SMITHY_CORE);
133+
w.addImport("isIdentityExpired", null,
134+
TypeScriptDependency.SMITHY_CORE);
135+
w.addImport("doesIdentityRequireRefresh", null,
136+
TypeScriptDependency.SMITHY_CORE);
137+
w.write("""
138+
const $L = memoizeIdentityProvider(config.$L, isIdentityExpired, \
139+
doesIdentityRequireRefresh);""",
140+
configField.name(),
141+
configField.name());
142+
}
143+
144+
@SmithyInternalApi
145+
public static void defaultAuxiliaryConfigFieldWriter(
146+
TypeScriptWriter w,
147+
ConfigField configField
148+
) {
149+
w.addDependency(TypeScriptDependency.UTIL_MIDDLEWARE);
150+
w.addImport("normalizeProvider", null, TypeScriptDependency.UTIL_MIDDLEWARE);
151+
w.write("const $L = config.$L ? normalizeProvider(config.$L) : undefined;",
152+
configField.name(),
153+
configField.name(),
154+
configField.name());
155+
}
156+
}

0 commit comments

Comments
 (0)