Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 7 additions & 0 deletions .changeset/tame-suns-carry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@smithy/util-base64": minor
"@smithy/util-stream": minor
"@smithy/core": minor
---

refactoring to reduce code size
4 changes: 2 additions & 2 deletions packages/core/src/submodules/cbor/CborCodec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NormalizedSchema } from "@smithy/core/schema";
import { generateIdempotencyToken, parseEpochTimestamp } from "@smithy/core/serde";
import { _parseEpochTimestamp, generateIdempotencyToken } from "@smithy/core/serde";
import type { Codec, Schema, SerdeFunctions, ShapeDeserializer, ShapeSerializer } from "@smithy/types";
import { fromBase64 } from "@smithy/util-base64";

Expand Down Expand Up @@ -148,7 +148,7 @@ export class CborShapeDeserializer implements ShapeDeserializer {

if (ns.isTimestampSchema() && typeof value === "number") {
// format is ignored.
return parseEpochTimestamp(value);
return _parseEpochTimestamp(value);
}

if (ns.isBlobSchema()) {
Expand Down
43 changes: 26 additions & 17 deletions packages/core/src/submodules/cbor/SmithyRpcV2CborProtocol.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import type { ErrorSchema } from "@smithy/core/schema";
import { error, list, map, op, SCHEMA, struct, TypeRegistry } from "@smithy/core/schema";
import { HttpRequest, HttpResponse } from "@smithy/protocol-http";
import type { ResponseMetadata, RetryableTrait, SchemaRef } from "@smithy/types";
import type {
BlobSchema,
BooleanSchema,
MapSchemaModifier,
NumericSchema,
ResponseMetadata,
RetryableTrait,
SchemaRef,
StringSchema,
TimestampDefaultSchema,
} from "@smithy/types";
import { beforeEach, describe, expect, test as it } from "vitest";

import { cbor } from "./cbor";
Expand Down Expand Up @@ -29,8 +38,8 @@ describe(SmithyRpcV2CborProtocol.name, () => {
{},
["timestamp", "blob"],
[
[SCHEMA.TIMESTAMP_DEFAULT, 0],
[SCHEMA.BLOB, 0],
[4 satisfies TimestampDefaultSchema, 0],
[21 satisfies BlobSchema, 0],
]
),
input: {
Expand All @@ -56,11 +65,11 @@ describe(SmithyRpcV2CborProtocol.name, () => {
{},
["bool", "timestamp", "blob", "prefixHeaders", "searchParams"],
[
[SCHEMA.BOOLEAN, { httpQuery: "bool" }],
[SCHEMA.TIMESTAMP_DEFAULT, { httpHeader: "timestamp" }],
[SCHEMA.BLOB, { httpHeader: "blob" }],
[SCHEMA.MAP_MODIFIER | SCHEMA.STRING, { httpPrefixHeaders: "anti-" }],
[SCHEMA.MAP_MODIFIER | SCHEMA.STRING, { httpQueryParams: 1 }],
[2 satisfies BooleanSchema, { httpQuery: "bool" }],
[4 satisfies TimestampDefaultSchema, { httpHeader: "timestamp" }],
[21 satisfies BlobSchema, { httpHeader: "blob" }],
[(128 satisfies MapSchemaModifier) | (0 satisfies StringSchema), { httpPrefixHeaders: "anti-" }],
[(128 satisfies MapSchemaModifier) | (0 satisfies StringSchema), { httpQueryParams: 1 }],
]
),
input: {
Expand Down Expand Up @@ -104,10 +113,10 @@ describe(SmithyRpcV2CborProtocol.name, () => {
0,
["mySparseList", "myRegularList", "mySparseMap", "myRegularMap"],
[
[() => list("", "MySparseList", { sparse: 1 }, SCHEMA.NUMERIC), {}],
[() => list("", "MyList", {}, SCHEMA.NUMERIC), {}],
[() => map("", "MySparseMap", { sparse: 1 }, SCHEMA.STRING, SCHEMA.NUMERIC), {}],
[() => map("", "MyMap", {}, SCHEMA.STRING, SCHEMA.NUMERIC), {}],
[() => list("", "MySparseList", { sparse: 1 }, 1 satisfies NumericSchema), {}],
[() => list("", "MyList", {}, 1 satisfies NumericSchema), {}],
[() => map("", "MySparseMap", { sparse: 1 }, 0 satisfies StringSchema, 1 satisfies NumericSchema), {}],
[() => map("", "MyMap", {}, 0 satisfies StringSchema, 1 satisfies NumericSchema), {}],
]
),
input: {
Expand Down Expand Up @@ -207,10 +216,10 @@ describe(SmithyRpcV2CborProtocol.name, () => {
0,
["mySparseList", "myRegularList", "mySparseMap", "myRegularMap"],
[
[() => list("", "MyList", { sparse: 1 }, SCHEMA.NUMERIC), {}],
[() => list("", "MyList", {}, SCHEMA.NUMERIC), {}],
[() => map("", "MyMap", { sparse: 1 }, SCHEMA.STRING, SCHEMA.NUMERIC), {}],
[() => map("", "MyMap", {}, SCHEMA.STRING, SCHEMA.NUMERIC), {}],
[() => list("", "MyList", { sparse: 1 }, 1 satisfies NumericSchema), {}],
[() => list("", "MyList", {}, 1 satisfies NumericSchema), {}],
[() => map("", "MyMap", { sparse: 1 }, 0 satisfies StringSchema, 1 satisfies NumericSchema), {}],
[() => map("", "MyMap", {}, 0 satisfies StringSchema, 1 satisfies NumericSchema), {}],
]
),
mockOutput: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { cbor, CborCodec, dateToTag } from "@smithy/core/cbor";
import { NormalizedSchema, SCHEMA, sim, struct } from "@smithy/core/schema";
import { NormalizedSchema, sim, struct } from "@smithy/core/schema";
import { EventStreamMarshaller } from "@smithy/eventstream-serde-node";
import { HttpResponse } from "@smithy/protocol-http";
import type { Message as EventMessage } from "@smithy/types";
import type {
BlobSchema,
Message as EventMessage,
StreamingBlobSchema,
StringSchema,
TimestampEpochSecondsSchema,
} from "@smithy/types";
import { fromUtf8, toUtf8 } from "@smithy/util-utf8";
import { describe, expect, test as it } from "vitest";

Expand Down Expand Up @@ -53,9 +59,15 @@ describe(EventStreamSerde.name, () => {
"Payload",
0,
["payload"],
[sim("ns", "StreamingBlobPayload", SCHEMA.STREAMING_BLOB, { eventPayload: 1 })]
[sim("ns", "StreamingBlobPayload", 42 satisfies StreamingBlobSchema, { eventPayload: 1 })]
),
struct(
"ns",
"TextPayload",
0,
["payload"],
[sim("ns", "TextPayload", 0 satisfies StringSchema, { eventPayload: 1 })]
),
struct("ns", "TextPayload", 0, ["payload"], [sim("ns", "TextPayload", SCHEMA.STRING, { eventPayload: 1 })]),
struct(
"ns",
"CustomHeaders",
Expand All @@ -73,7 +85,7 @@ describe(EventStreamSerde.name, () => {
// here the non-eventstream members form an initial-request
// or initial-response when present.
["eventStreamMember", "dateMember", "blobMember"],
[eventStreamUnionSchema, SCHEMA.TIMESTAMP_EPOCH_SECONDS, SCHEMA.BLOB]
[eventStreamUnionSchema, 7 satisfies TimestampEpochSecondsSchema, 21 satisfies BlobSchema]
);

describe("serialization", () => {
Expand Down
11 changes: 7 additions & 4 deletions packages/core/src/submodules/event-streams/EventStreamSerde.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { NormalizedSchema } from "@smithy/core/schema";
import { SCHEMA } from "@smithy/core/schema";
import type { NormalizedSchema, StructureSchema } from "@smithy/core/schema";
import type {
DocumentSchema,
EventStreamMarshaller,
HttpRequest as IHttpRequest,
HttpResponse as IHttpResponse,
Expand Down Expand Up @@ -232,14 +232,17 @@ export class EventStreamSerde {
let explicitPayloadMember = null as null | string;
let explicitPayloadContentType: undefined | string;

const isKnownSchema = unionSchema.hasMemberSchema(unionMember);
const isKnownSchema = (() => {
const struct = unionSchema.getSchema() as StructureSchema;
return struct.memberNames.includes(unionMember);
})();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the only call to hasMemberSchema, so I inlined the function here and removed it from the alpha API.

const additionalHeaders: MessageHeaders = {};

if (!isKnownSchema) {
// $unknown member
const [type, value] = event[unionMember];
eventType = type;
serializer.write(SCHEMA.DOCUMENT, value);
serializer.write(15 satisfies DocumentSchema, value);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

importing even a numeric constant creates a lot of code under certain bundling conditions.

Rather than having a "magic number" 15, the TS satisfies keyword is useful to indicate and type-check the number, allowing usage-finding.

} else {
const eventSchema = unionSchema.getMemberSchema(unionMember);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import { map, op, SCHEMA, struct } from "@smithy/core/schema";
import { map, op, struct } from "@smithy/core/schema";
import { HttpResponse } from "@smithy/protocol-http";
import type {
Codec,
CodecSettings,
HandlerExecutionContext,
HttpResponse as IHttpResponse,
ListSchemaModifier,
MapSchemaModifier,
MetadataBearer,
OperationSchema,
ResponseMetadata,
Schema,
SerdeFunctions,
ShapeDeserializer,
ShapeSerializer,
StringSchema,
TimestampDefaultSchema,
TimestampEpochSecondsSchema,
} from "@smithy/types";
import { parseUrl } from "@smithy/url-parser/src";
import { describe, expect, test as it } from "vitest";
Expand All @@ -32,7 +37,7 @@ describe(HttpBindingProtocol.name, () => {
const settings: CodecSettings = {
timestampFormat: {
useTrait: true,
default: SCHEMA.TIMESTAMP_EPOCH_SECONDS,
default: 7 satisfies TimestampEpochSecondsSchema,
},
httpBindings: true,
};
Expand Down Expand Up @@ -82,7 +87,7 @@ describe(HttpBindingProtocol.name, () => {
["timestampList"],
[
[
SCHEMA.LIST_MODIFIER | SCHEMA.TIMESTAMP_DEFAULT,
(64 satisfies ListSchemaModifier) | (4 satisfies TimestampDefaultSchema),
{
httpHeader: "x-timestamplist",
},
Expand Down Expand Up @@ -122,7 +127,7 @@ describe(HttpBindingProtocol.name, () => {
["httpPrefixHeaders"],
[
[
SCHEMA.MAP_MODIFIER | SCHEMA.STRING,
(128 satisfies MapSchemaModifier) | (0 satisfies StringSchema),
{
httpPrefixHeaders: "",
},
Expand Down Expand Up @@ -175,7 +180,7 @@ describe(HttpBindingProtocol.name, () => {
httpBindings: true,
timestampFormat: {
useTrait: true,
default: SCHEMA.TIMESTAMP_EPOCH_SECONDS,
default: 7 satisfies TimestampEpochSecondsSchema,
},
}),
}
Expand Down
10 changes: 6 additions & 4 deletions packages/core/src/submodules/protocols/HttpBindingProtocol.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { NormalizedSchema, SCHEMA } from "@smithy/core/schema";
import { NormalizedSchema, translateTraits } from "@smithy/core/schema";
import { splitEvery, splitHeader } from "@smithy/core/serde";
import { HttpRequest } from "@smithy/protocol-http";
import type {
DocumentSchema,
Endpoint,
EndpointBearer,
HandlerExecutionContext,
Expand All @@ -11,6 +12,7 @@ import type {
OperationSchema,
Schema,
SerdeFunctions,
TimestampDefaultSchema,
} from "@smithy/types";
import { sdkStreamMixin } from "@smithy/util-stream";

Expand Down Expand Up @@ -58,7 +60,7 @@ export abstract class HttpBindingProtocol extends HttpProtocol {
if (endpoint) {
this.updateServiceEndpoint(request, endpoint);
this.setHostPrefix(request, operationSchema, input);
const opTraits = NormalizedSchema.translateTraits(operationSchema.traits);
const opTraits = translateTraits(operationSchema.traits);
if (opTraits.http) {
request.method = opTraits.http[0];
const [path, search] = opTraits.http[1].split("?");
Expand Down Expand Up @@ -203,7 +205,7 @@ export abstract class HttpBindingProtocol extends HttpProtocol {
if (response.statusCode >= 300) {
const bytes: Uint8Array = await collectBody(response.body, context);
if (bytes.byteLength > 0) {
Object.assign(dataObject, await deserializer.read(SCHEMA.DOCUMENT, bytes));
Object.assign(dataObject, await deserializer.read(15 satisfies DocumentSchema, bytes));
}
await this.handleError(operationSchema, context, response, dataObject, this.deserializeMetadata(response));
throw new Error("@smithy/core/protocols - HTTP Protocol error handler failed to throw.");
Expand Down Expand Up @@ -304,7 +306,7 @@ export abstract class HttpBindingProtocol extends HttpProtocol {
let sections: string[];
if (
headerListValueSchema.isTimestampSchema() &&
headerListValueSchema.getSchema() === SCHEMA.TIMESTAMP_DEFAULT
headerListValueSchema.getSchema() === (4 satisfies TimestampDefaultSchema)
) {
sections = splitEvery(value, ",", 2);
} else {
Expand Down
12 changes: 9 additions & 3 deletions packages/core/src/submodules/protocols/HttpProtocol.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { map, SCHEMA, struct } from "@smithy/core/schema";
import type { HandlerExecutionContext, HttpResponse as IHttpResponse, Schema, SerdeFunctions } from "@smithy/types";
import { map, struct } from "@smithy/core/schema";
import type {
HandlerExecutionContext,
HttpResponse as IHttpResponse,
Schema,
SerdeFunctions,
TimestampEpochSecondsSchema,
} from "@smithy/types";
import { describe, expect, test as it } from "vitest";

import { HttpProtocol } from "./HttpProtocol";
Expand All @@ -18,7 +24,7 @@ describe(HttpProtocol.name, () => {
httpBindings: true,
timestampFormat: {
useTrait: true,
default: SCHEMA.TIMESTAMP_EPOCH_SECONDS,
default: 7 satisfies TimestampEpochSecondsSchema,
},
}),
});
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/submodules/protocols/HttpProtocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ export abstract class HttpProtocol implements ClientProtocol<IHttpRequest, IHttp
request.fragment = endpoint.url.hash || void 0;
request.username = endpoint.url.username || void 0;
request.password = endpoint.url.password || void 0;
if (!request.query) {
request.query = {};
}
for (const [k, v] of endpoint.url.searchParams.entries()) {
if (!request.query) {
request.query = {};
}
request.query[k] = v;
}
return request;
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/submodules/protocols/RpcProtocol.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { NormalizedSchema, SCHEMA } from "@smithy/core/schema";
import { NormalizedSchema } from "@smithy/core/schema";
import { HttpRequest } from "@smithy/protocol-http";
import type {
DocumentSchema,
Endpoint,
EndpointBearer,
HandlerExecutionContext,
Expand Down Expand Up @@ -101,7 +102,7 @@ export abstract class RpcProtocol extends HttpProtocol {
if (response.statusCode >= 300) {
const bytes: Uint8Array = await collectBody(response.body, context as SerdeFunctions);
if (bytes.byteLength > 0) {
Object.assign(dataObject, await deserializer.read(SCHEMA.DOCUMENT, bytes));
Object.assign(dataObject, await deserializer.read(15 satisfies DocumentSchema, bytes));
}
await this.handleError(operationSchema, context, response, dataObject, this.deserializeMetadata(response));
throw new Error("@smithy/core/protocols - RPC Protocol error handler failed to throw.");
Expand Down
Loading