Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use FileWriter from TypeScript Delegator to write EndpointV2 files #619

Merged
merged 1 commit into from
Oct 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ private void generateEndpointV2(GenerateServiceDirective<TypeScriptCodegenContex
return;
}

new EndpointsV2Generator(directive.settings(), directive.model(), directive.fileManifest()).run();
new EndpointsV2Generator(directive.context().writerDelegator(), directive.settings(), directive.model()).run();
}

private void generateServiceInterface(GenerateServiceDirective<TypeScriptCodegenContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public enum TypeScriptDependency implements SymbolDependencyContainer {
MIDDLEWARE_RETRY("dependencies", "@aws-sdk/middleware-retry", true),
MIDDLEWARE_STACK("dependencies", "@aws-sdk/middleware-stack", true),
MIDDLEWARE_ENDPOINTS_V2("dependencies", "@aws-sdk/middleware-endpoint", false),
AWS_SDK_UTIL_ENDPOINTS("dependencies", "@aws-sdk/util-endpoints", false),

AWS_CRYPTO_SHA256_BROWSER("dependencies", "@aws-crypto/sha256-browser", "2.0.0", true),
AWS_CRYPTO_SHA256_JS("dependencies", "@aws-crypto/sha256-js", "2.0.0", true),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
import java.util.Map;
import software.amazon.smithy.aws.traits.ServiceTrait;
import software.amazon.smithy.aws.traits.auth.SigV4Trait;
import software.amazon.smithy.build.FileManifest;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.model.node.ObjectNode;
import software.amazon.smithy.model.shapes.ServiceShape;
import software.amazon.smithy.rulesengine.traits.EndpointRuleSetTrait;
import software.amazon.smithy.typescript.codegen.CodegenUtils;
import software.amazon.smithy.typescript.codegen.TypeScriptDelegator;
import software.amazon.smithy.typescript.codegen.TypeScriptDependency;
import software.amazon.smithy.typescript.codegen.TypeScriptSettings;
import software.amazon.smithy.typescript.codegen.TypeScriptWriter;
import software.amazon.smithy.utils.SmithyInternalApi;

/**
Expand All @@ -36,17 +36,20 @@
public final class EndpointsV2Generator implements Runnable {

static final String ENDPOINT_FOLDER = "endpoint";
static final String ENDPOINT_PARAMETERS_FILE = "EndpointParameters.ts";
static final String ENDPOINT_RESOLVER_FILE = "endpointResolver.ts";
static final String ENDPOINT_RULESET_FILE = "ruleset.ts";

private final FileManifest fileManifest;
private final TypeScriptDelegator delegator;
private final EndpointRuleSetTrait endpointRuleSetTrait;
private final ServiceShape service;

public EndpointsV2Generator(
TypeScriptDelegator delegator,
TypeScriptSettings settings,
Model model,
FileManifest fileManifest
Model model
) {
this.fileManifest = fileManifest;
this.delegator = delegator;
service = settings.getService(model);
endpointRuleSetTrait = service.getTrait(EndpointRuleSetTrait.class)
.orElseThrow(() -> new RuntimeException("service missing EndpointRuleSetTrait"));
Expand All @@ -63,140 +66,139 @@ public void run() {
* Generate the EndpointParameters interface file specific to this service.
*/
private void generateEndpointParameters() {
TypeScriptWriter writer = new TypeScriptWriter("");
this.delegator.useFileWriter(
Paths.get(CodegenUtils.SOURCE_FOLDER, ENDPOINT_FOLDER, ENDPOINT_PARAMETERS_FILE).toString(),
writer -> {
writer.addImport("EndpointParameters", "__EndpointParameters", "@aws-sdk/types");
writer.addImport("Provider", null, "@aws-sdk/types");

writer.addImport("EndpointParameters", "__EndpointParameters", "@aws-sdk/types");
writer.addImport("Provider", null, "@aws-sdk/types");
writer.openBlock(
"export interface ClientInputEndpointParameters {",
"}",
() -> {
RuleSetParameterFinder ruleSetParameterFinder = new RuleSetParameterFinder(service);

writer.openBlock(
"export interface ClientInputEndpointParameters {",
"}",
() -> {
RuleSetParameterFinder ruleSetParameterFinder = new RuleSetParameterFinder(service);
Map<String, String> clientInputParams = ruleSetParameterFinder.getClientContextParams();
clientInputParams.putAll(ruleSetParameterFinder.getBuiltInParams());

Map<String, String> clientInputParams = ruleSetParameterFinder.getClientContextParams();
clientInputParams.putAll(ruleSetParameterFinder.getBuiltInParams());
ObjectNode ruleSet = endpointRuleSetTrait.getRuleSet().expectObjectNode();
ruleSet.getObjectMember("parameters").ifPresent(parameters -> {
parameters.accept(new RuleSetParametersVisitor(writer, clientInputParams, true));
});
}
);

ObjectNode ruleSet = endpointRuleSetTrait.getRuleSet().expectObjectNode();
ruleSet.getObjectMember("parameters").ifPresent(parameters -> {
parameters.accept(new RuleSetParametersVisitor(writer, clientInputParams, true));
});
}
);
writer.write("");
writer.openBlock(
"export type ClientResolvedEndpointParameters = ClientInputEndpointParameters & {",
"};",
() -> {
writer.write("defaultSigningName: string;");
}
);
writer.write("");

writer.write("");
writer.openBlock(
"export type ClientResolvedEndpointParameters = ClientInputEndpointParameters & {",
"};",
() -> {
writer.write("defaultSigningName: string;");
}
);
writer.write("");

writer.openBlock(
"export const resolveClientEndpointParameters = "
+ "<T>(options: T & ClientInputEndpointParameters"
+ "): T & ClientResolvedEndpointParameters => {",
"}",
() -> {
writer.openBlock("return {", "}", () -> {
writer.write("...options,");
ObjectNode ruleSet = endpointRuleSetTrait.getRuleSet().expectObjectNode();
ruleSet.getObjectMember("parameters").ifPresent(parameters -> {
parameters.accept(new RuleSetParametersVisitor(writer, true));
});
ServiceTrait serviceTrait = service.getTrait(ServiceTrait.class).get();
writer.write(
"defaultSigningName: \"$L\",",
service.getTrait(SigV4Trait.class).map(SigV4Trait::getName)
.orElse(serviceTrait.getArnNamespace())
);
});
}
);
writer.openBlock(
"export const resolveClientEndpointParameters = "
+ "<T>(options: T & ClientInputEndpointParameters"
+ "): T & ClientResolvedEndpointParameters => {",
"}",
() -> {
writer.openBlock("return {", "}", () -> {
writer.write("...options,");
ObjectNode ruleSet = endpointRuleSetTrait.getRuleSet().expectObjectNode();
ruleSet.getObjectMember("parameters").ifPresent(parameters -> {
parameters.accept(new RuleSetParametersVisitor(writer, true));
});
ServiceTrait serviceTrait = service.getTrait(ServiceTrait.class).get();
writer.write(
"defaultSigningName: \"$L\",",
service.getTrait(SigV4Trait.class).map(SigV4Trait::getName)
.orElse(serviceTrait.getArnNamespace())
);
});
}
);

writer.write("");
writer.openBlock(
"export interface EndpointParameters extends __EndpointParameters {",
"}",
() -> {
ObjectNode ruleSet = endpointRuleSetTrait.getRuleSet().expectObjectNode();
ruleSet.getObjectMember("parameters").ifPresent(parameters -> {
parameters.accept(new RuleSetParametersVisitor(writer));
});
writer.write("");
writer.openBlock(
"export interface EndpointParameters extends __EndpointParameters {",
"}",
() -> {
ObjectNode ruleSet = endpointRuleSetTrait.getRuleSet().expectObjectNode();
ruleSet.getObjectMember("parameters").ifPresent(parameters -> {
parameters.accept(new RuleSetParametersVisitor(writer));
});
}
);
}
);

fileManifest.writeFile(
Paths.get(CodegenUtils.SOURCE_FOLDER, ENDPOINT_FOLDER, "EndpointParameters.ts").toString(),
writer.toString()
);
}

/**
* Generate the resolver function for this service.
*/
private void generateEndpointResolver() {
TypeScriptWriter writer = new TypeScriptWriter("");

writer.addImport("EndpointV2", null, "@aws-sdk/types");
writer.addImport("Logger", null, "@aws-sdk/types");
this.delegator.useFileWriter(
Paths.get(CodegenUtils.SOURCE_FOLDER, ENDPOINT_FOLDER, ENDPOINT_RESOLVER_FILE).toString(),
writer -> {
writer.addImport("EndpointV2", null, "@aws-sdk/types");
writer.addImport("Logger", null, "@aws-sdk/types");

writer.addDependency(TypeScriptDependency.AWS_SDK_UTIL_ENDPOINTS);
writer.addImport("EndpointParams", null, TypeScriptDependency.AWS_SDK_UTIL_ENDPOINTS.packageName);
writer.addImport("resolveEndpoint", null, TypeScriptDependency.AWS_SDK_UTIL_ENDPOINTS.packageName);
writer.addImport("EndpointParameters", null,
Paths.get(".", CodegenUtils.SOURCE_FOLDER, ENDPOINT_FOLDER,
ENDPOINT_PARAMETERS_FILE.replace(".ts", "")).toString());
writer.addImport("ruleSet", null,
Paths.get(".", CodegenUtils.SOURCE_FOLDER, ENDPOINT_FOLDER,
ENDPOINT_RULESET_FILE.replace(".ts", "")).toString());

writer.addImport("EndpointParams", null, "@aws-sdk/util-endpoints");
writer.addImport("resolveEndpoint", null, "@aws-sdk/util-endpoints");
writer.addImport("EndpointParameters", null, "../endpoint/EndpointParameters");
writer.addImport("ruleSet", null, "../endpoint/ruleset");

writer.openBlock(
"export const defaultEndpointResolver = ",
"",
() -> {
writer.openBlock(
"(endpointParams: EndpointParameters, context: { logger?: Logger } = {}): EndpointV2 => {",
"};",
"export const defaultEndpointResolver = ",
"",
() -> {
writer.openBlock(
"return resolveEndpoint(ruleSet, {",
"});",
"(endpointParams: EndpointParameters, context: { logger?: Logger } = {}): EndpointV2 => {",
"};",
() -> {
writer.write("endpointParams: endpointParams as EndpointParams,");
writer.write("logger: context.logger,");
writer.openBlock(
"return resolveEndpoint(ruleSet, {",
"});",
() -> {
writer.write("endpointParams: endpointParams as EndpointParams,");
writer.write("logger: context.logger,");
}
);
}
);
}
);
}
);

fileManifest.writeFile(
Paths.get(CodegenUtils.SOURCE_FOLDER, ENDPOINT_FOLDER, "endpointResolver.ts").toString(),
writer.toString()
);
}

/**
* Generate the ruleset (dynamic resolution only).
*/
private void generateEndpointRuleset() {
TypeScriptWriter writer = new TypeScriptWriter("");

writer.addImport("RuleSetObject", null, "@aws-sdk/util-endpoints");

writer.openBlock(
"export const ruleSet: RuleSetObject = ",
"",
() -> {
new RuleSetSerializer(
endpointRuleSetTrait.getRuleSet(),
writer
).generate();
}
);
this.delegator.useFileWriter(
Paths.get(CodegenUtils.SOURCE_FOLDER, ENDPOINT_FOLDER, ENDPOINT_RULESET_FILE).toString(),
writer -> {
writer.addImport("RuleSetObject", null, "@aws-sdk/util-endpoints");
writer.openBlock(
"export const ruleSet: RuleSetObject = ",
"",
() -> {
new RuleSetSerializer(
endpointRuleSetTrait.getRuleSet(),
writer
).generate();
}
);

fileManifest.writeFile(
Paths.get(CodegenUtils.SOURCE_FOLDER, ENDPOINT_FOLDER, "ruleset.ts").toString(),
writer.toString()
}
);
}
}