Skip to content

Commit 44bc516

Browse files
committed
rework schemas
1 parent 367616d commit 44bc516

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1553
-889
lines changed

packages/core/src/submodules/cbor/CborCodec.ts

+48-42
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
1-
import { deref, ListSchema, MapSchema, StructureSchema } from "@smithy/core/schema";
1+
import { NormalizedSchema } from "@smithy/core/schema";
22
import { copyDocumentWithTransform, parseEpochTimestamp } from "@smithy/core/serde";
3-
import {
4-
Codec,
5-
MemberSchema,
6-
Schema,
7-
SchemaRef,
8-
SerdeContext,
9-
ShapeDeserializer,
10-
ShapeSerializer,
11-
TraitsSchema,
12-
} from "@smithy/types";
3+
import { Codec, Schema, SchemaRef, SerdeContext, ShapeDeserializer, ShapeSerializer } from "@smithy/types";
134

145
import { cbor } from "./cbor";
156
import { dateToTag } from "./parseCborBody";
@@ -22,6 +13,7 @@ export class CborCodec implements Codec<Uint8Array, Uint8Array> {
2213
serializer.setSerdeContext(this.serdeContext!);
2314
return serializer;
2415
}
16+
2517
public createDeserializer(): CborShapeDeserializer {
2618
const deserializer = new CborShapeDeserializer();
2719
deserializer.setSerdeContext(this.serdeContext!);
@@ -46,17 +38,19 @@ export class CborShapeSerializer implements ShapeSerializer<Uint8Array> {
4638
if (_ instanceof Date) {
4739
return dateToTag(_);
4840
}
49-
const schema = deref((schemaRef as MemberSchema)?.[0] ?? schemaRef);
5041
if (_ instanceof Uint8Array) {
5142
return _;
5243
}
53-
const sparse = (schema as TraitsSchema)?.traits?.sparse;
44+
45+
const ns = NormalizedSchema.of(schemaRef);
46+
const sparse = !!ns.getMergedTraits().sparse;
47+
5448
if (Array.isArray(_)) {
5549
if (!sparse) {
5650
return _.filter((item) => item != null);
5751
}
5852
} else if (_ && typeof _ === "object") {
59-
if (!sparse) {
53+
if (!sparse || ns.isStructSchema()) {
6054
for (const [k, v] of Object.entries(_)) {
6155
if (v == null) {
6256
delete _[k];
@@ -65,6 +59,7 @@ export class CborShapeSerializer implements ShapeSerializer<Uint8Array> {
6559
return _;
6660
}
6761
}
62+
6863
return _;
6964
});
7065
}
@@ -88,15 +83,20 @@ export class CborShapeDeserializer implements ShapeDeserializer {
8883
return this.readValue(schema, data);
8984
}
9085

91-
private readValue(schema: Schema, value: any): any {
92-
if (typeof schema === "string") {
93-
if (schema === "time" || schema === "epoch-seconds" || schema === "date-time") {
86+
private readValue(_schema: Schema, value: any): any {
87+
const ns = NormalizedSchema.of(_schema);
88+
const schema = ns.getSchema();
89+
90+
if (typeof schema === "number") {
91+
if (ns.isTimestampSchema()) {
92+
// format is ignored.
9493
return parseEpochTimestamp(value);
9594
}
96-
if (schema === "blob" || schema === "streaming-blob") {
95+
if (ns.isBlobSchema()) {
9796
return value;
9897
}
9998
}
99+
100100
switch (typeof value) {
101101
case "undefined":
102102
case "boolean":
@@ -116,38 +116,44 @@ export class CborShapeDeserializer implements ShapeDeserializer {
116116
if (value instanceof Date) {
117117
return value;
118118
}
119-
const traits =
120-
Array.isArray(schema) && schema.length >= 2
121-
? {
122-
...(deref((schema as MemberSchema)[0]) as TraitsSchema)?.traits,
123-
...(schema as MemberSchema)[1],
124-
}
125-
: (deref(schema) as TraitsSchema)?.traits;
126-
127-
if (Array.isArray(value)) {
119+
if (ns.isDocumentSchema()) {
120+
return value;
121+
}
122+
123+
if (ns.isListSchema()) {
128124
const newArray = [];
125+
const memberSchema = ns.getValueSchema();
126+
const sparse = ns.isListSchema() && !!ns.getMergedTraits().sparse;
127+
129128
for (const item of value) {
130-
newArray.push(this.readValue(schema instanceof ListSchema ? deref(schema.valueSchema) : void 0, item));
131-
if (!traits?.sparse) {
132-
if (newArray[newArray.length - 1] == null) {
133-
newArray.pop();
134-
}
129+
newArray.push(this.readValue(memberSchema, item));
130+
if (!sparse && newArray[newArray.length - 1] == null) {
131+
newArray.pop();
135132
}
136133
}
137134
return newArray;
138135
}
139136

140137
const newObject = {} as any;
141-
for (const key of Object.keys(value)) {
142-
const targetSchema =
143-
schema instanceof StructureSchema
144-
? deref(schema.members[key]?.[0])
145-
: schema instanceof MapSchema
146-
? deref(schema.valueSchema)
147-
: void 0;
148-
newObject[key] = this.readValue(targetSchema, value[key]);
149-
if (!traits?.sparse && newObject[key] == null) {
150-
delete newObject[key];
138+
139+
if (ns.isMapSchema()) {
140+
const sparse = ns.getMergedTraits().sparse;
141+
const targetSchema = ns.getValueSchema();
142+
143+
for (const key of Object.keys(value)) {
144+
newObject[key] = this.readValue(targetSchema, value[key]);
145+
146+
if (newObject[key] == null && !sparse) {
147+
delete newObject[key];
148+
}
149+
}
150+
} else if (ns.isStructSchema()) {
151+
for (const key of Object.keys(value)) {
152+
const targetSchema = ns.getMemberSchema(key);
153+
if (targetSchema === undefined) {
154+
continue;
155+
}
156+
newObject[key] = this.readValue(targetSchema, value[key]);
151157
}
152158
}
153159
return newObject;

packages/core/src/submodules/cbor/SmithyRpcV2CborProtocol.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,10 @@ describe(SmithyRpcV2CborProtocol.name, () => {
154154
const protocol = new SmithyRpcV2CborProtocol();
155155
const httpRequest = await protocol.serializeRequest(
156156
{
157+
name: "dummy",
157158
input: testCase.schema,
158159
output: void 0,
159160
traits: {},
160-
errors: [],
161161
},
162162
testCase.input,
163163
{
@@ -249,10 +249,10 @@ describe(SmithyRpcV2CborProtocol.name, () => {
249249
const protocol = new SmithyRpcV2CborProtocol();
250250
const output = await protocol.deserializeResponse(
251251
{
252+
name: "dummy",
252253
input: void 0,
253254
output: testCase.schema,
254255
traits: {},
255-
errors: [],
256256
},
257257
{},
258258
new HttpResponse({

packages/core/src/submodules/cbor/SmithyRpcV2CborProtocol.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { HttpInterceptingShapeSerializer,HttpProtocol } from "@smithy/core/protocols";
1+
import { HttpInterceptingShapeSerializer, RpcProtocol } from "@smithy/core/protocols";
22
import { deref, ErrorSchema, OperationSchema, TypeRegistry } from "@smithy/core/schema";
33
import type {
44
HandlerExecutionContext,
@@ -12,7 +12,7 @@ import { getSmithyContext } from "@smithy/util-middleware";
1212
import { CborCodec, CborShapeSerializer } from "./CborCodec";
1313
import { loadSmithyRpcV2CborErrorCode } from "./parseCborBody";
1414

15-
export class SmithyRpcV2CborProtocol extends HttpProtocol {
15+
export class SmithyRpcV2CborProtocol extends RpcProtocol {
1616
private codec = new CborCodec();
1717
protected serializer = new HttpInterceptingShapeSerializer<CborShapeSerializer>(this.codec.createSerializer());
1818
protected deserializer = this.codec.createDeserializer();
@@ -36,6 +36,10 @@ export class SmithyRpcV2CborProtocol extends HttpProtocol {
3636
delete request.body;
3737
delete request.headers["content-type"];
3838
} else {
39+
if (!request.body) {
40+
this.serializer.write(15, {});
41+
request.body = this.serializer.flush();
42+
}
3943
try {
4044
request.headers["content-length"] = String((request.body as Uint8Array).byteLength);
4145
} catch (e) {}
@@ -82,6 +86,7 @@ export class SmithyRpcV2CborProtocol extends HttpProtocol {
8286
// TODO(schema) throw client base exception using the dataObject.
8387
throw new Error("schema not found for " + error);
8488
}
89+
8590
const message = dataObject.message ?? dataObject.Message ?? "Unknown";
8691
const exception = new errorSchema.ctor(message);
8792
Object.assign(exception, {

0 commit comments

Comments
 (0)