Skip to content

Skip code generation of data filter functions for shapes that do not contain sensitive fields (recursive) #722

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

Merged
merged 10 commits into from
Mar 22, 2023

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,22 @@
import software.amazon.smithy.model.traits.ErrorTrait;
import software.amazon.smithy.typescript.codegen.TypeScriptSettings.RequiredMemberMode;
import software.amazon.smithy.typescript.codegen.integration.HttpProtocolGeneratorUtils;
import software.amazon.smithy.typescript.codegen.validation.SensitiveDataFinder;
import software.amazon.smithy.utils.SmithyInternalApi;

/**
* Generates normal structures and error structures.
*
* Renders structures as interfaces.
*
* <p>A namespace is created with the same name as the structure to
* <p>
* A namespace is created with the same name as the structure to
* provide helper functionality for checking if a given value is
* known to be of the same type as the structure. This will be
* even more useful if/when inheritance is added to Smithy.
*
* <p>Note that the {@code required} trait on structures is used to
* <p>
* Note that the {@code required} trait on structures is used to
* determine whether or not a generated TypeScript interface uses
* required members. This is typically not recommended in other languages
* since it's documented as backward-compatible for a model to migrate a
Expand All @@ -55,7 +58,8 @@
* deserializers will need to set previously required properties to
* undefined too.
*
* <p>The generator will explicitly state that a required property can
* <p>
* The generator will explicitly state that a required property can
* be set to {@code undefined}. This makes it clear that undefined checks
* need to be made when using {@code --strictNullChecks}, but has no
* effect otherwise.
Expand All @@ -69,28 +73,30 @@ final class StructureGenerator implements Runnable {
private final StructureShape shape;
private final boolean includeValidation;
private final RequiredMemberMode requiredMemberMode;
private final SensitiveDataFinder sensitiveDataFinder;

/**
* sets 'includeValidation' to 'false' and requiredMemberMode
* to {@link RequiredMemberMode#NULLABLE}.
*/
StructureGenerator(Model model, SymbolProvider symbolProvider, TypeScriptWriter writer, StructureShape shape) {
this(model, symbolProvider, writer, shape, false,
RequiredMemberMode.NULLABLE);
RequiredMemberMode.NULLABLE);
}

StructureGenerator(Model model,
SymbolProvider symbolProvider,
TypeScriptWriter writer,
StructureShape shape,
boolean includeValidation,
RequiredMemberMode requiredMemberMode) {
SymbolProvider symbolProvider,
TypeScriptWriter writer,
StructureShape shape,
boolean includeValidation,
RequiredMemberMode requiredMemberMode) {
this.model = model;
this.symbolProvider = symbolProvider;
this.writer = writer;
this.shape = shape;
this.includeValidation = includeValidation;
this.requiredMemberMode = requiredMemberMode;
sensitiveDataFinder = new SensitiveDataFinder(model);
}

@Override
Expand All @@ -105,20 +111,24 @@ public void run() {
/**
* Renders a normal, non-error structure.
*
* <p>For example, given the following Smithy model:
* <p>
* For example, given the following Smithy model:
*
* <pre>{@code
* <pre>
* {@code
* namespace smithy.example
*
* structure Person {
* @required
* &#64;required
* name: String,
* @range(min: 1)
* &#64;range(min: 1)
* age: Integer,
* }
* }</pre>
* }
* </pre>
*
* <p>The following TypeScript is rendered:
* <p>
* The following TypeScript is rendered:
*
* <pre>{@code
* export interface Person {
Expand All @@ -129,7 +139,8 @@ public void run() {
* export const PersonFilterSensitiveLog = (obj: Person): any => ({...obj});
* }</pre>
*
* <p>If validation is enabled, it generates the following:
* <p>
* If validation is enabled, it generates the following:
*
* <pre>{@code
* export interface Person {
Expand Down Expand Up @@ -164,7 +175,11 @@ private void renderNonErrorStructure() {
}

StructuredMemberWriter config = new StructuredMemberWriter(
model, symbolProvider, shape.getAllMembers().values(), this.requiredMemberMode);
model,
symbolProvider,
shape.getAllMembers().values(),
this.requiredMemberMode,
sensitiveDataFinder);
config.writeMembers(writer, shape);
writer.closeBlock("}");
writer.write("");
Expand All @@ -174,15 +189,17 @@ private void renderNonErrorStructure() {
private void renderStructureNamespace(StructuredMemberWriter structuredMemberWriter, boolean includeValidation) {
Symbol symbol = symbolProvider.toSymbol(shape);
String objectParam = "obj";
writer.writeDocs("@internal");
writer.openBlock("export const $LFilterSensitiveLog = ($L: $L): any => ({", "})",
symbol.getName(),
objectParam,
symbol.getName(),
() -> {
structuredMemberWriter.writeFilterSensitiveLog(writer, objectParam);
}
);

if (sensitiveDataFinder.findsSensitiveDataIn(shape)) {
writer.writeDocs("@internal");
writer.openBlock("export const $LFilterSensitiveLog = ($L: $L): any => ({", "})",
symbol.getName(),
objectParam,
symbol.getName(),
() -> {
structuredMemberWriter.writeFilterSensitiveLog(writer, objectParam);
});
}

if (!includeValidation) {
return;
Expand Down Expand Up @@ -212,19 +229,23 @@ private void renderStructureNamespace(StructuredMemberWriter structuredMemberWri
* (ServiceException in case of server SDK), and add the appropriate fault
* property.
*
* <p>Given the following Smithy structure:
* <p>
* Given the following Smithy structure:
*
* <pre>{@code
* <pre>
* {@code
* namespace smithy.example
*
* @error("client")
* &#64;error("client")
* structure NoSuchResource {
* @required
* &#64;required
* resourceType: String
* }
* }</pre>
* }
* </pre>
*
* <p>The following TypeScript is generated:
* <p>
* The following TypeScript is generated:
*
* <pre>{@code
* import { ExceptionOptionType as __ExceptionOptionType } from "@aws-sdk/smithy-client";
Expand Down Expand Up @@ -261,8 +282,9 @@ private void renderErrorStructure() {
HttpProtocolGeneratorUtils.writeRetryableTrait(writer, shape, ";");
}
StructuredMemberWriter structuredMemberWriter = new StructuredMemberWriter(model, symbolProvider,
shape.getAllMembers().values(), this.requiredMemberMode);
// since any error interface must extend from JavaScript Error interface, message member is already
shape.getAllMembers().values(), this.requiredMemberMode, sensitiveDataFinder);
// since any error interface must extend from JavaScript Error interface,
// message member is already
// required in the JavaScript Error interface
structuredMemberWriter.skipMembers.add("message");
structuredMemberWriter.writeMembers(writer, shape);
Expand Down
Loading