Skip to content

Commit 84a0075

Browse files
authored
fix(codegen): cbor eventstream codegen (#1731)
1 parent fa019e9 commit 84a0075

File tree

16 files changed

+613
-9
lines changed

16 files changed

+613
-9
lines changed

.changeset/clean-terms-argue.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
---

packages/eventstream-serde-universal/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
"lint": "eslint -c ../../.eslintrc.js \"src/**/*.ts\"",
1313
"format": "prettier --config ../../prettier.config.js --ignore-path ../../.prettierignore --write \"**/*.{ts,md,json}\"",
1414
"test": "yarn g:vitest run",
15-
"test:watch": "yarn g:vitest watch"
15+
"test:watch": "yarn g:vitest watch",
16+
"test:integration": "yarn g:vitest run -c vitest.config.integ.mts",
17+
"test:integration:watch": "yarn g:vitest watch -c vitest.config.integ.mts"
1618
},
1719
"main": "./dist-cjs/index.js",
1820
"module": "./dist-es/index.js",
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import { cbor, dateToTag } from "@smithy/core/cbor";
2+
import { HttpResponse } from "@smithy/protocol-http";
3+
import { requireRequestsFrom } from "@smithy/util-test/src";
4+
import { Readable } from "node:stream";
5+
import { describe, expect, test as it } from "vitest";
6+
import { XYZService } from "xyz";
7+
8+
describe("local model integration test for cbor eventstreams", () => {
9+
it("should read and write cbor event streams", async () => {
10+
const client = new XYZService({
11+
endpoint: "https://localhost",
12+
});
13+
14+
const body = cbor.serialize({
15+
id: "alpha",
16+
timestamp: dateToTag(new Date(0)),
17+
});
18+
19+
function toInt32(n: number): number[] {
20+
const uint32 = new Uint8Array(4);
21+
const dv = new DataView(uint32.buffer, 0, 4);
22+
dv.setUint32(0, n);
23+
return [...uint32];
24+
}
25+
26+
requireRequestsFrom(client)
27+
.toMatch({
28+
hostname: /localhost/,
29+
async body(body) {
30+
const outgoing = [];
31+
for await (const chunk of body) {
32+
outgoing.push(chunk);
33+
}
34+
expect(outgoing).toEqual([
35+
new Uint8Array([
36+
0, 0, 0, 101, 0, 0, 0, 75, 213, 254, 191, 76, 11, 58, 101, 118, 101, 110, 116, 45, 116, 121, 112, 101, 7,
37+
0, 5, 97, 108, 112, 104, 97, 13, 58, 109, 101, 115, 115, 97, 103, 101, 45, 116, 121, 112, 101, 7, 0, 5,
38+
101, 118, 101, 110, 116, 13, 58, 99, 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 7, 0, 16, 97,
39+
112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 99, 98, 111, 114, 161, 98, 105, 100, 101, 97, 108,
40+
112, 104, 97, 32, 93, 69, 236,
41+
]),
42+
new Uint8Array([
43+
0, 0, 0, 91, 0, 0, 0, 74, 188, 232, 137, 61, 11, 58, 101, 118, 101, 110, 116, 45, 116, 121, 112, 101, 7,
44+
0, 4, 98, 101, 116, 97, 13, 58, 109, 101, 115, 115, 97, 103, 101, 45, 116, 121, 112, 101, 7, 0, 5, 101,
45+
118, 101, 110, 116, 13, 58, 99, 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 7, 0, 16, 97, 112,
46+
112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 99, 98, 111, 114, 160, 195, 209, 62, 47,
47+
]),
48+
new Uint8Array([
49+
0, 0, 0, 91, 0, 0, 0, 74, 188, 232, 137, 61, 11, 58, 101, 118, 101, 110, 116, 45, 116, 121, 112, 101, 7,
50+
0, 4, 98, 101, 116, 97, 13, 58, 109, 101, 115, 115, 97, 103, 101, 45, 116, 121, 112, 101, 7, 0, 5, 101,
51+
118, 101, 110, 116, 13, 58, 99, 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 7, 0, 16, 97, 112,
52+
112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 99, 98, 111, 114, 160, 195, 209, 62, 47,
53+
]),
54+
new Uint8Array(),
55+
]);
56+
},
57+
})
58+
.respondWith(
59+
new HttpResponse({
60+
statusCode: 200,
61+
headers: {
62+
"smithy-protocol": "rpc-v2-cbor",
63+
},
64+
body: Readable.from({
65+
async *[Symbol.asyncIterator]() {
66+
yield new Uint8Array([
67+
/* message size */ ...toInt32(91 + body.byteLength),
68+
/* header size */ ...toInt32(75),
69+
/* prelude crc */ ...toInt32(1084132878),
70+
/* headers */
71+
/* :event-type */
72+
11,
73+
...[58, 101, 118, 101, 110, 116, 45, 116, 121, 112, 101],
74+
7,
75+
/* alpha */
76+
0,
77+
5,
78+
...[97, 108, 112, 104, 97],
79+
/* :content-type */
80+
13,
81+
...[58, 99, 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101],
82+
7,
83+
/* application/cbor */
84+
0,
85+
16,
86+
...[97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 99, 98, 111, 114],
87+
/* :message-type */
88+
13,
89+
...[58, 109, 101, 115, 115, 97, 103, 101, 45, 116, 121, 112, 101],
90+
7,
91+
/* event */
92+
0,
93+
5,
94+
...[101, 118, 101, 110, 116],
95+
96+
/* body */
97+
...body,
98+
99+
/* message crc */
100+
...toInt32(1938836882),
101+
]);
102+
},
103+
}),
104+
})
105+
);
106+
107+
const response = await client.tradeEventStream({
108+
eventStream: {
109+
async *[Symbol.asyncIterator]() {
110+
yield {
111+
alpha: {
112+
id: "alpha",
113+
},
114+
};
115+
yield {
116+
beta: {},
117+
};
118+
yield {
119+
gamma: {},
120+
};
121+
},
122+
},
123+
});
124+
125+
const responses = [] as any[];
126+
for await (const event of response.eventStream ?? []) {
127+
responses.push(event);
128+
}
129+
130+
expect(responses).toEqual([
131+
{
132+
alpha: {
133+
id: "alpha",
134+
timestamp: new Date(0),
135+
},
136+
},
137+
]);
138+
});
139+
});
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { defineConfig } from "vitest/config";
2+
3+
export default defineConfig({
4+
test: {
5+
include: ["**/*.integ.spec.ts"],
6+
environment: "node",
7+
},
8+
});

private/my-local-model/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
"@aws-sdk/types": "latest",
2222
"@smithy/config-resolver": "workspace:^",
2323
"@smithy/core": "workspace:^",
24+
"@smithy/eventstream-serde-browser": "workspace:^",
25+
"@smithy/eventstream-serde-config-resolver": "workspace:^",
26+
"@smithy/eventstream-serde-node": "workspace:^",
2427
"@smithy/fetch-http-handler": "workspace:^",
2528
"@smithy/hash-node": "workspace:^",
2629
"@smithy/invalid-dependency": "workspace:^",

private/my-local-model/src/XYZService.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
// smithy-typescript generated code
22
import { XYZServiceClient, XYZServiceClientConfig } from "./XYZServiceClient";
33
import { GetNumbersCommand, GetNumbersCommandInput, GetNumbersCommandOutput } from "./commands/GetNumbersCommand";
4+
import {
5+
TradeEventStreamCommand,
6+
TradeEventStreamCommandInput,
7+
TradeEventStreamCommandOutput,
8+
} from "./commands/TradeEventStreamCommand";
49
import { createAggregatedClient } from "@smithy/smithy-client";
510
import { HttpHandlerOptions as __HttpHandlerOptions } from "@smithy/types";
611

712
const commands = {
813
GetNumbersCommand,
14+
TradeEventStreamCommand,
915
};
1016

1117
export interface XYZService {
@@ -20,6 +26,24 @@ export interface XYZService {
2026
options: __HttpHandlerOptions,
2127
cb: (err: any, data?: GetNumbersCommandOutput) => void
2228
): void;
29+
30+
/**
31+
* @see {@link TradeEventStreamCommand}
32+
*/
33+
tradeEventStream(): Promise<TradeEventStreamCommandOutput>;
34+
tradeEventStream(
35+
args: TradeEventStreamCommandInput,
36+
options?: __HttpHandlerOptions
37+
): Promise<TradeEventStreamCommandOutput>;
38+
tradeEventStream(
39+
args: TradeEventStreamCommandInput,
40+
cb: (err: any, data?: TradeEventStreamCommandOutput) => void
41+
): void;
42+
tradeEventStream(
43+
args: TradeEventStreamCommandInput,
44+
options: __HttpHandlerOptions,
45+
cb: (err: any, data?: TradeEventStreamCommandOutput) => void
46+
): void;
2347
}
2448

2549
/**

private/my-local-model/src/XYZServiceClient.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
resolveHttpAuthSchemeConfig,
77
} from "./auth/httpAuthSchemeProvider";
88
import { GetNumbersCommandInput, GetNumbersCommandOutput } from "./commands/GetNumbersCommand";
9+
import { TradeEventStreamCommandInput, TradeEventStreamCommandOutput } from "./commands/TradeEventStreamCommand";
910
import {
1011
ClientInputEndpointParameters,
1112
ClientResolvedEndpointParameters,
@@ -19,6 +20,11 @@ import {
1920
getHttpAuthSchemeEndpointRuleSetPlugin,
2021
getHttpSigningPlugin,
2122
} from "@smithy/core";
23+
import {
24+
EventStreamSerdeInputConfig,
25+
EventStreamSerdeResolvedConfig,
26+
resolveEventStreamSerdeConfig,
27+
} from "@smithy/eventstream-serde-config-resolver";
2228
import { getContentLengthPlugin } from "@smithy/middleware-content-length";
2329
import {
2430
EndpointInputConfig,
@@ -42,6 +48,7 @@ import {
4248
ChecksumConstructor as __ChecksumConstructor,
4349
Decoder as __Decoder,
4450
Encoder as __Encoder,
51+
EventStreamSerdeProvider as __EventStreamSerdeProvider,
4552
HashConstructor as __HashConstructor,
4653
HttpHandlerOptions as __HttpHandlerOptions,
4754
Logger as __Logger,
@@ -55,12 +62,12 @@ export { __Client };
5562
/**
5663
* @public
5764
*/
58-
export type ServiceInputTypes = GetNumbersCommandInput;
65+
export type ServiceInputTypes = GetNumbersCommandInput | TradeEventStreamCommandInput;
5966

6067
/**
6168
* @public
6269
*/
63-
export type ServiceOutputTypes = GetNumbersCommandOutput;
70+
export type ServiceOutputTypes = GetNumbersCommandOutput | TradeEventStreamCommandOutput;
6471

6572
/**
6673
* @public
@@ -154,6 +161,11 @@ export interface ClientDefaults extends Partial<__SmithyConfiguration<__HttpHand
154161
*/
155162
extensions?: RuntimeExtension[];
156163

164+
/**
165+
* The function that provides necessary utilities for generating and parsing event stream
166+
*/
167+
eventStreamSerdeProvider?: __EventStreamSerdeProvider;
168+
157169
/**
158170
* The {@link @smithy/smithy-client#DefaultsMode} that will be used to determine how certain default configuration options are resolved in the SDK.
159171
*/
@@ -168,6 +180,7 @@ export type XYZServiceClientConfigType = Partial<__SmithyConfiguration<__HttpHan
168180
RetryInputConfig &
169181
EndpointInputConfig<EndpointParameters> &
170182
EndpointRequiredInputConfig &
183+
EventStreamSerdeInputConfig &
171184
HttpAuthSchemeInputConfig &
172185
ClientInputEndpointParameters;
173186
/**
@@ -186,6 +199,7 @@ export type XYZServiceClientResolvedConfigType = __SmithyResolvedConfiguration<_
186199
RetryResolvedConfig &
187200
EndpointResolvedConfig<EndpointParameters> &
188201
EndpointRequiredResolvedConfig &
202+
EventStreamSerdeResolvedConfig &
189203
HttpAuthSchemeResolvedConfig &
190204
ClientResolvedEndpointParameters;
191205
/**
@@ -218,9 +232,10 @@ export class XYZServiceClient extends __Client<
218232
let _config_2 = resolveRetryConfig(_config_1);
219233
let _config_3 = resolveEndpointConfig(_config_2);
220234
let _config_4 = resolveEndpointRequiredConfig(_config_3);
221-
let _config_5 = resolveHttpAuthSchemeConfig(_config_4);
222-
let _config_6 = resolveRuntimeExtensions(_config_5, configuration?.extensions || []);
223-
this.config = _config_6;
235+
let _config_5 = resolveEventStreamSerdeConfig(_config_4);
236+
let _config_6 = resolveHttpAuthSchemeConfig(_config_5);
237+
let _config_7 = resolveRuntimeExtensions(_config_6, configuration?.extensions || []);
238+
this.config = _config_7;
224239
this.middlewareStack.use(getRetryPlugin(this.config));
225240
this.middlewareStack.use(getContentLengthPlugin(this.config));
226241
this.middlewareStack.use(

0 commit comments

Comments
 (0)