Skip to content
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
1 change: 1 addition & 0 deletions clients/client-dynamodb/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@aws-crypto/sha256-js": "5.2.0",
"@aws-sdk/core": "*",
"@aws-sdk/credential-provider-node": "*",
"@aws-sdk/dynamodb-codec": "*",
"@aws-sdk/middleware-endpoint-discovery": "*",
"@aws-sdk/middleware-host-header": "*",
"@aws-sdk/middleware-logger": "*",
Expand Down
2 changes: 2 additions & 0 deletions clients/client-dynamodb/src/runtimeConfig.shared.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// smithy-typescript generated code
import { AwsSdkSigV4Signer } from "@aws-sdk/core";
import { AwsJson1_0Protocol } from "@aws-sdk/core/protocols";
import { DynamoDBJsonCodec } from "@aws-sdk/dynamodb-codec";
import { NoOpLogger } from "@smithy/smithy-client";
import { IdentityProviderConfig } from "@smithy/types";
import { parseUrl } from "@smithy/url-parser";
Expand Down Expand Up @@ -37,6 +38,7 @@ export const getRuntimeConfig = (config: DynamoDBClientConfig) => {
defaultNamespace: "com.amazonaws.dynamodb",
serviceTarget: "DynamoDB_20120810",
awsQueryCompatible: false,
jsonCodec: new DynamoDBJsonCodec(),
}),
serviceId: config?.serviceId ?? "DynamoDB",
urlParser: config?.urlParser ?? parseUrl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,18 @@
*/
@SmithyInternalApi
public final class AddProtocolConfig implements TypeScriptIntegration {

static {
init();
}

public static final Map<ShapeId, Consumer<TypeScriptWriter>> CUSTOMIZATIONS = MapUtils.of(
ShapeId.from("com.amazonaws.dynamodb#DynamoDB_20120810"),
writer -> {
writer.addImport("DynamoDBJsonCodec", null, AwsDependency.DYNAMODB_CODEC);
writer.write("jsonCodec: new DynamoDBJsonCodec(),");
}
);

static void init() {
List<ShapeId> allowed = List.of(
AwsJson1_0Trait.ID,
Expand Down Expand Up @@ -114,7 +121,8 @@ public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(
AwsDependency.AWS_SDK_CORE, "/protocols");
writer.write("""
new AwsRestXmlProtocol({
defaultNamespace: $S, xmlNamespace: $S,
defaultNamespace: $S,
xmlNamespace: $S,
})""",
namespace,
xmlns
Expand All @@ -132,7 +140,7 @@ public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(
new AwsQueryProtocol({
defaultNamespace: $S,
xmlNamespace: $S,
version: $S
version: $S,
})""",
namespace,
xmlns,
Expand All @@ -151,7 +159,7 @@ public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(
new AwsEc2QueryProtocol({
defaultNamespace: $S,
xmlNamespace: $S,
version: $S
version: $S,
})""",
namespace,
xmlns,
Expand All @@ -174,16 +182,22 @@ public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(
writer.addImportSubmodule(
"AwsJson1_0Protocol", null,
AwsDependency.AWS_SDK_CORE, "/protocols");
writer.write(
writer.openBlock(
"""
new AwsJson1_0Protocol({
defaultNamespace: $S,
serviceTarget: $S,
awsQueryCompatible: $L
defaultNamespace: $S,
serviceTarget: $S,
awsQueryCompatible: $L,""",
"""
})""",
namespace,
rpcTarget,
awsQueryCompat
awsQueryCompat,
() -> {
if (CUSTOMIZATIONS.containsKey(settings.getService())) {
CUSTOMIZATIONS.get(settings.getService()).accept(writer);
}
}
);
}
);
Expand All @@ -193,16 +207,22 @@ public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(
writer.addImportSubmodule(
"AwsJson1_1Protocol", null,
AwsDependency.AWS_SDK_CORE, "/protocols");
writer.write(
writer.openBlock(
"""
new AwsJson1_1Protocol({
defaultNamespace: $S,
serviceTarget: $S,
awsQueryCompatible: $L
defaultNamespace: $S,
serviceTarget: $S,
awsQueryCompatible: $L,""",
"""
})""",
namespace,
rpcTarget,
awsQueryCompat
awsQueryCompat,
() -> {
if (CUSTOMIZATIONS.containsKey(settings.getService())) {
CUSTOMIZATIONS.get(settings.getService()).accept(writer);
}
}
);
}
);
Expand All @@ -215,8 +235,8 @@ public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(
writer.write(
"""
new AwsSmithyRpcV2CborProtocol({
defaultNamespace: $S,
awsQueryCompatible: $L
defaultNamespace: $S,
awsQueryCompatible: $L,
})""",
namespace,
awsQueryCompat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ public enum AwsDependency implements Dependency {
REGION_CONFIG_RESOLVER(NORMAL_DEPENDENCY, "@aws-sdk/region-config-resolver"),

CLIENT_DYNAMODB_PEER(PEER_DEPENDENCY, "@aws-sdk/client-dynamodb", "^3.0.0"),
UTIL_DYNAMODB(NORMAL_DEPENDENCY, "@aws-sdk/util-dynamodb", "*");

UTIL_DYNAMODB(NORMAL_DEPENDENCY, "@aws-sdk/util-dynamodb", "*"),
DYNAMODB_CODEC(NORMAL_DEPENDENCY, "@aws-sdk/dynamodb-codec");

public final String packageName;
public final String version;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AwsJsonRpcProtocol } from "./AwsJsonRpcProtocol";
import type { JsonCodec } from "./JsonCodec";

/**
* @public
Expand All @@ -9,15 +10,18 @@ export class AwsJson1_0Protocol extends AwsJsonRpcProtocol {
defaultNamespace,
serviceTarget,
awsQueryCompatible,
jsonCodec,
}: {
defaultNamespace: string;
serviceTarget: string;
awsQueryCompatible?: boolean;
jsonCodec?: JsonCodec;
}) {
super({
defaultNamespace,
serviceTarget,
awsQueryCompatible,
jsonCodec,
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AwsJsonRpcProtocol } from "./AwsJsonRpcProtocol";
import type { JsonCodec } from "./JsonCodec";

/**
* @public
Expand All @@ -9,15 +10,18 @@ export class AwsJson1_1Protocol extends AwsJsonRpcProtocol {
defaultNamespace,
serviceTarget,
awsQueryCompatible,
jsonCodec,
}: {
defaultNamespace: string;
serviceTarget: string;
awsQueryCompatible?: boolean;
jsonCodec?: JsonCodec;
}) {
super({
defaultNamespace,
serviceTarget,
awsQueryCompatible,
jsonCodec,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,26 @@ export abstract class AwsJsonRpcProtocol extends RpcProtocol {
defaultNamespace,
serviceTarget,
awsQueryCompatible,
jsonCodec,
}: {
defaultNamespace: string;
serviceTarget: string;
awsQueryCompatible?: boolean;
jsonCodec?: JsonCodec;
}) {
super({
defaultNamespace,
});
this.serviceTarget = serviceTarget;
this.codec = new JsonCodec({
timestampFormat: {
useTrait: true,
default: 7 as const satisfies TimestampEpochSecondsSchema,
},
jsonName: false,
});
this.codec =
jsonCodec ??
new JsonCodec({
timestampFormat: {
useTrait: true,
default: 7 as const satisfies TimestampEpochSecondsSchema,
},
jsonName: false,
});
this.serializer = this.codec.createSerializer();
this.deserializer = this.codec.createDeserializer();
this.awsQueryCompatible = !!awsQueryCompatible;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,49 +42,51 @@ export class JsonShapeDeserializer extends SerdeContextConfig implements ShapeDe
return this._read(schema, data);
}

private _read(schema: Schema, value: unknown): any {
protected _read(schema: Schema, value: unknown): any {
const isObject = value !== null && typeof value === "object";

const ns = NormalizedSchema.of(schema);

// === aggregate types ===
if (ns.isListSchema() && Array.isArray(value)) {
const listMember = ns.getValueSchema();
const out = [] as any[];
const sparse = !!ns.getMergedTraits().sparse;
for (const item of value) {
if (sparse || item != null) {
out.push(this._read(listMember, item));
if (isObject) {
if (ns.isStructSchema()) {
const out = {} as any;
for (const [memberName, memberSchema] of deserializingStructIterator(
ns,
value,
this.settings.jsonName ? "jsonName" : false
)) {
const fromKey = this.settings.jsonName ? memberSchema.getMergedTraits().jsonName ?? memberName : memberName;
const deserializedValue = this._read(memberSchema, (value as any)[fromKey]);
if (deserializedValue != null) {
out[memberName] = deserializedValue;
}
}
return out;
}
return out;
} else if (ns.isMapSchema() && isObject) {
const mapMember = ns.getValueSchema();
const out = {} as any;
const sparse = !!ns.getMergedTraits().sparse;
for (const [_k, _v] of Object.entries(value)) {
if (sparse || _v != null) {
out[_k] = this._read(mapMember, _v);
if (Array.isArray(value) && ns.isListSchema()) {
const listMember = ns.getValueSchema();
const out = [] as any[];
const sparse = !!ns.getMergedTraits().sparse;
for (const item of value) {
if (sparse || item != null) {
out.push(this._read(listMember, item));
}
}
return out;
}
return out;
} else if (ns.isStructSchema() && isObject) {
const out = {} as any;
for (const [memberName, memberSchema] of deserializingStructIterator(
ns,
value,
this.settings.jsonName ? "jsonName" : false
)) {
const fromKey = this.settings.jsonName ? memberSchema.getMergedTraits().jsonName ?? memberName : memberName;
const deserializedValue = this._read(memberSchema, (value as any)[fromKey]);
if (deserializedValue != null) {
out[memberName] = deserializedValue;
if (ns.isMapSchema()) {
const mapMember = ns.getValueSchema();
const out = {} as any;
const sparse = !!ns.getMergedTraits().sparse;
for (const [_k, _v] of Object.entries(value)) {
if (sparse || _v != null) {
out[_k] = this._read(mapMember, _v);
}
}
return out;
}
return out;
}

// === simple types ===
if (ns.isBlobSchema() && typeof value === "string") {
return fromBase64(value);
}
Expand All @@ -95,6 +97,7 @@ export class JsonShapeDeserializer extends SerdeContextConfig implements ShapeDe
if (isJson) {
return LazyJsonString.from(value);
}
return value;
}

if (ns.isTimestampSchema() && value != null) {
Expand Down Expand Up @@ -136,6 +139,7 @@ export class JsonShapeDeserializer extends SerdeContextConfig implements ShapeDe
case "NaN":
return NaN;
}
return value;
}

if (ns.isDocumentSchema()) {
Expand All @@ -154,7 +158,7 @@ export class JsonShapeDeserializer extends SerdeContextConfig implements ShapeDe
}
}

// covers string, numeric, boolean, document, bigDecimal
// covers boolean, bigint (long/BigInt), bigDecimal
return value;
}
}
Loading
Loading