@smithy/eventstream-codec 4.1.0 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.js +372 -457
- package/dist-es/EventStreamCodec.js +3 -0
- package/dist-es/HeaderMarshaller.js +2 -0
- package/dist-es/Int64.js +2 -1
- package/dist-es/MessageDecoderStream.js +1 -0
- package/dist-es/MessageEncoderStream.js +1 -0
- package/dist-es/SmithyMessageDecoderStream.js +1 -0
- package/dist-es/SmithyMessageEncoderStream.js +1 -0
- package/package.json +4 -4
- package/dist-cjs/EventStreamCodec.js +0 -1
- package/dist-cjs/HeaderMarshaller.js +0 -1
- package/dist-cjs/Int64.js +0 -1
- package/dist-cjs/Message.js +0 -1
- package/dist-cjs/MessageDecoderStream.js +0 -1
- package/dist-cjs/MessageEncoderStream.js +0 -1
- package/dist-cjs/SmithyMessageDecoderStream.js +0 -1
- package/dist-cjs/SmithyMessageEncoderStream.js +0 -1
- package/dist-cjs/TestVectors.fixture.js +0 -1
- package/dist-cjs/splitMessage.js +0 -1
- package/dist-cjs/vectorTypes.fixture.js +0 -1
package/dist-cjs/index.js
CHANGED
|
@@ -1,473 +1,388 @@
|
|
|
1
|
-
|
|
2
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
-
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
1
|
+
'use strict';
|
|
19
2
|
|
|
20
|
-
|
|
21
|
-
var
|
|
22
|
-
__export(index_exports, {
|
|
23
|
-
EventStreamCodec: () => EventStreamCodec,
|
|
24
|
-
HeaderMarshaller: () => HeaderMarshaller,
|
|
25
|
-
Int64: () => Int64,
|
|
26
|
-
MessageDecoderStream: () => MessageDecoderStream,
|
|
27
|
-
MessageEncoderStream: () => MessageEncoderStream,
|
|
28
|
-
SmithyMessageDecoderStream: () => SmithyMessageDecoderStream,
|
|
29
|
-
SmithyMessageEncoderStream: () => SmithyMessageEncoderStream
|
|
30
|
-
});
|
|
31
|
-
module.exports = __toCommonJS(index_exports);
|
|
3
|
+
var crc32 = require('@aws-crypto/crc32');
|
|
4
|
+
var utilHexEncoding = require('@smithy/util-hex-encoding');
|
|
32
5
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
*/
|
|
67
|
-
valueOf() {
|
|
68
|
-
const bytes = this.bytes.slice(0);
|
|
69
|
-
const negative = bytes[0] & 128;
|
|
70
|
-
if (negative) {
|
|
71
|
-
negate(bytes);
|
|
72
|
-
}
|
|
73
|
-
return parseInt((0, import_util_hex_encoding.toHex)(bytes), 16) * (negative ? -1 : 1);
|
|
74
|
-
}
|
|
75
|
-
toString() {
|
|
76
|
-
return String(this.valueOf());
|
|
77
|
-
}
|
|
78
|
-
};
|
|
6
|
+
class Int64 {
|
|
7
|
+
bytes;
|
|
8
|
+
constructor(bytes) {
|
|
9
|
+
this.bytes = bytes;
|
|
10
|
+
if (bytes.byteLength !== 8) {
|
|
11
|
+
throw new Error("Int64 buffers must be exactly 8 bytes");
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
static fromNumber(number) {
|
|
15
|
+
if (number > 9_223_372_036_854_775_807 || number < -9223372036854776e3) {
|
|
16
|
+
throw new Error(`${number} is too large (or, if negative, too small) to represent as an Int64`);
|
|
17
|
+
}
|
|
18
|
+
const bytes = new Uint8Array(8);
|
|
19
|
+
for (let i = 7, remaining = Math.abs(Math.round(number)); i > -1 && remaining > 0; i--, remaining /= 256) {
|
|
20
|
+
bytes[i] = remaining;
|
|
21
|
+
}
|
|
22
|
+
if (number < 0) {
|
|
23
|
+
negate(bytes);
|
|
24
|
+
}
|
|
25
|
+
return new Int64(bytes);
|
|
26
|
+
}
|
|
27
|
+
valueOf() {
|
|
28
|
+
const bytes = this.bytes.slice(0);
|
|
29
|
+
const negative = bytes[0] & 0b10000000;
|
|
30
|
+
if (negative) {
|
|
31
|
+
negate(bytes);
|
|
32
|
+
}
|
|
33
|
+
return parseInt(utilHexEncoding.toHex(bytes), 16) * (negative ? -1 : 1);
|
|
34
|
+
}
|
|
35
|
+
toString() {
|
|
36
|
+
return String(this.valueOf());
|
|
37
|
+
}
|
|
38
|
+
}
|
|
79
39
|
function negate(bytes) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
40
|
+
for (let i = 0; i < 8; i++) {
|
|
41
|
+
bytes[i] ^= 0xff;
|
|
42
|
+
}
|
|
43
|
+
for (let i = 7; i > -1; i--) {
|
|
44
|
+
bytes[i]++;
|
|
45
|
+
if (bytes[i] !== 0)
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
87
48
|
}
|
|
88
|
-
__name(negate, "negate");
|
|
89
49
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const bytes = this.fromUtf8(headerName);
|
|
103
|
-
chunks.push(Uint8Array.from([bytes.byteLength]), bytes, this.formatHeaderValue(headers[headerName]));
|
|
104
|
-
}
|
|
105
|
-
const out = new Uint8Array(chunks.reduce((carry, bytes) => carry + bytes.byteLength, 0));
|
|
106
|
-
let position = 0;
|
|
107
|
-
for (const chunk of chunks) {
|
|
108
|
-
out.set(chunk, position);
|
|
109
|
-
position += chunk.byteLength;
|
|
110
|
-
}
|
|
111
|
-
return out;
|
|
112
|
-
}
|
|
113
|
-
formatHeaderValue(header) {
|
|
114
|
-
switch (header.type) {
|
|
115
|
-
case "boolean":
|
|
116
|
-
return Uint8Array.from([header.value ? 0 /* boolTrue */ : 1 /* boolFalse */]);
|
|
117
|
-
case "byte":
|
|
118
|
-
return Uint8Array.from([2 /* byte */, header.value]);
|
|
119
|
-
case "short":
|
|
120
|
-
const shortView = new DataView(new ArrayBuffer(3));
|
|
121
|
-
shortView.setUint8(0, 3 /* short */);
|
|
122
|
-
shortView.setInt16(1, header.value, false);
|
|
123
|
-
return new Uint8Array(shortView.buffer);
|
|
124
|
-
case "integer":
|
|
125
|
-
const intView = new DataView(new ArrayBuffer(5));
|
|
126
|
-
intView.setUint8(0, 4 /* integer */);
|
|
127
|
-
intView.setInt32(1, header.value, false);
|
|
128
|
-
return new Uint8Array(intView.buffer);
|
|
129
|
-
case "long":
|
|
130
|
-
const longBytes = new Uint8Array(9);
|
|
131
|
-
longBytes[0] = 5 /* long */;
|
|
132
|
-
longBytes.set(header.value.bytes, 1);
|
|
133
|
-
return longBytes;
|
|
134
|
-
case "binary":
|
|
135
|
-
const binView = new DataView(new ArrayBuffer(3 + header.value.byteLength));
|
|
136
|
-
binView.setUint8(0, 6 /* byteArray */);
|
|
137
|
-
binView.setUint16(1, header.value.byteLength, false);
|
|
138
|
-
const binBytes = new Uint8Array(binView.buffer);
|
|
139
|
-
binBytes.set(header.value, 3);
|
|
140
|
-
return binBytes;
|
|
141
|
-
case "string":
|
|
142
|
-
const utf8Bytes = this.fromUtf8(header.value);
|
|
143
|
-
const strView = new DataView(new ArrayBuffer(3 + utf8Bytes.byteLength));
|
|
144
|
-
strView.setUint8(0, 7 /* string */);
|
|
145
|
-
strView.setUint16(1, utf8Bytes.byteLength, false);
|
|
146
|
-
const strBytes = new Uint8Array(strView.buffer);
|
|
147
|
-
strBytes.set(utf8Bytes, 3);
|
|
148
|
-
return strBytes;
|
|
149
|
-
case "timestamp":
|
|
150
|
-
const tsBytes = new Uint8Array(9);
|
|
151
|
-
tsBytes[0] = 8 /* timestamp */;
|
|
152
|
-
tsBytes.set(Int64.fromNumber(header.value.valueOf()).bytes, 1);
|
|
153
|
-
return tsBytes;
|
|
154
|
-
case "uuid":
|
|
155
|
-
if (!UUID_PATTERN.test(header.value)) {
|
|
156
|
-
throw new Error(`Invalid UUID received: ${header.value}`);
|
|
50
|
+
class HeaderMarshaller {
|
|
51
|
+
toUtf8;
|
|
52
|
+
fromUtf8;
|
|
53
|
+
constructor(toUtf8, fromUtf8) {
|
|
54
|
+
this.toUtf8 = toUtf8;
|
|
55
|
+
this.fromUtf8 = fromUtf8;
|
|
56
|
+
}
|
|
57
|
+
format(headers) {
|
|
58
|
+
const chunks = [];
|
|
59
|
+
for (const headerName of Object.keys(headers)) {
|
|
60
|
+
const bytes = this.fromUtf8(headerName);
|
|
61
|
+
chunks.push(Uint8Array.from([bytes.byteLength]), bytes, this.formatHeaderValue(headers[headerName]));
|
|
157
62
|
}
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
};
|
|
63
|
+
const out = new Uint8Array(chunks.reduce((carry, bytes) => carry + bytes.byteLength, 0));
|
|
64
|
+
let position = 0;
|
|
65
|
+
for (const chunk of chunks) {
|
|
66
|
+
out.set(chunk, position);
|
|
67
|
+
position += chunk.byteLength;
|
|
68
|
+
}
|
|
69
|
+
return out;
|
|
70
|
+
}
|
|
71
|
+
formatHeaderValue(header) {
|
|
72
|
+
switch (header.type) {
|
|
73
|
+
case "boolean":
|
|
74
|
+
return Uint8Array.from([header.value ? 0 : 1]);
|
|
75
|
+
case "byte":
|
|
76
|
+
return Uint8Array.from([2, header.value]);
|
|
77
|
+
case "short":
|
|
78
|
+
const shortView = new DataView(new ArrayBuffer(3));
|
|
79
|
+
shortView.setUint8(0, 3);
|
|
80
|
+
shortView.setInt16(1, header.value, false);
|
|
81
|
+
return new Uint8Array(shortView.buffer);
|
|
82
|
+
case "integer":
|
|
83
|
+
const intView = new DataView(new ArrayBuffer(5));
|
|
84
|
+
intView.setUint8(0, 4);
|
|
85
|
+
intView.setInt32(1, header.value, false);
|
|
86
|
+
return new Uint8Array(intView.buffer);
|
|
87
|
+
case "long":
|
|
88
|
+
const longBytes = new Uint8Array(9);
|
|
89
|
+
longBytes[0] = 5;
|
|
90
|
+
longBytes.set(header.value.bytes, 1);
|
|
91
|
+
return longBytes;
|
|
92
|
+
case "binary":
|
|
93
|
+
const binView = new DataView(new ArrayBuffer(3 + header.value.byteLength));
|
|
94
|
+
binView.setUint8(0, 6);
|
|
95
|
+
binView.setUint16(1, header.value.byteLength, false);
|
|
96
|
+
const binBytes = new Uint8Array(binView.buffer);
|
|
97
|
+
binBytes.set(header.value, 3);
|
|
98
|
+
return binBytes;
|
|
99
|
+
case "string":
|
|
100
|
+
const utf8Bytes = this.fromUtf8(header.value);
|
|
101
|
+
const strView = new DataView(new ArrayBuffer(3 + utf8Bytes.byteLength));
|
|
102
|
+
strView.setUint8(0, 7);
|
|
103
|
+
strView.setUint16(1, utf8Bytes.byteLength, false);
|
|
104
|
+
const strBytes = new Uint8Array(strView.buffer);
|
|
105
|
+
strBytes.set(utf8Bytes, 3);
|
|
106
|
+
return strBytes;
|
|
107
|
+
case "timestamp":
|
|
108
|
+
const tsBytes = new Uint8Array(9);
|
|
109
|
+
tsBytes[0] = 8;
|
|
110
|
+
tsBytes.set(Int64.fromNumber(header.value.valueOf()).bytes, 1);
|
|
111
|
+
return tsBytes;
|
|
112
|
+
case "uuid":
|
|
113
|
+
if (!UUID_PATTERN.test(header.value)) {
|
|
114
|
+
throw new Error(`Invalid UUID received: ${header.value}`);
|
|
115
|
+
}
|
|
116
|
+
const uuidBytes = new Uint8Array(17);
|
|
117
|
+
uuidBytes[0] = 9;
|
|
118
|
+
uuidBytes.set(utilHexEncoding.fromHex(header.value.replace(/\-/g, "")), 1);
|
|
119
|
+
return uuidBytes;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
parse(headers) {
|
|
123
|
+
const out = {};
|
|
124
|
+
let position = 0;
|
|
125
|
+
while (position < headers.byteLength) {
|
|
126
|
+
const nameLength = headers.getUint8(position++);
|
|
127
|
+
const name = this.toUtf8(new Uint8Array(headers.buffer, headers.byteOffset + position, nameLength));
|
|
128
|
+
position += nameLength;
|
|
129
|
+
switch (headers.getUint8(position++)) {
|
|
130
|
+
case 0:
|
|
131
|
+
out[name] = {
|
|
132
|
+
type: BOOLEAN_TAG,
|
|
133
|
+
value: true,
|
|
134
|
+
};
|
|
135
|
+
break;
|
|
136
|
+
case 1:
|
|
137
|
+
out[name] = {
|
|
138
|
+
type: BOOLEAN_TAG,
|
|
139
|
+
value: false,
|
|
140
|
+
};
|
|
141
|
+
break;
|
|
142
|
+
case 2:
|
|
143
|
+
out[name] = {
|
|
144
|
+
type: BYTE_TAG,
|
|
145
|
+
value: headers.getInt8(position++),
|
|
146
|
+
};
|
|
147
|
+
break;
|
|
148
|
+
case 3:
|
|
149
|
+
out[name] = {
|
|
150
|
+
type: SHORT_TAG,
|
|
151
|
+
value: headers.getInt16(position, false),
|
|
152
|
+
};
|
|
153
|
+
position += 2;
|
|
154
|
+
break;
|
|
155
|
+
case 4:
|
|
156
|
+
out[name] = {
|
|
157
|
+
type: INT_TAG,
|
|
158
|
+
value: headers.getInt32(position, false),
|
|
159
|
+
};
|
|
160
|
+
position += 4;
|
|
161
|
+
break;
|
|
162
|
+
case 5:
|
|
163
|
+
out[name] = {
|
|
164
|
+
type: LONG_TAG,
|
|
165
|
+
value: new Int64(new Uint8Array(headers.buffer, headers.byteOffset + position, 8)),
|
|
166
|
+
};
|
|
167
|
+
position += 8;
|
|
168
|
+
break;
|
|
169
|
+
case 6:
|
|
170
|
+
const binaryLength = headers.getUint16(position, false);
|
|
171
|
+
position += 2;
|
|
172
|
+
out[name] = {
|
|
173
|
+
type: BINARY_TAG,
|
|
174
|
+
value: new Uint8Array(headers.buffer, headers.byteOffset + position, binaryLength),
|
|
175
|
+
};
|
|
176
|
+
position += binaryLength;
|
|
177
|
+
break;
|
|
178
|
+
case 7:
|
|
179
|
+
const stringLength = headers.getUint16(position, false);
|
|
180
|
+
position += 2;
|
|
181
|
+
out[name] = {
|
|
182
|
+
type: STRING_TAG,
|
|
183
|
+
value: this.toUtf8(new Uint8Array(headers.buffer, headers.byteOffset + position, stringLength)),
|
|
184
|
+
};
|
|
185
|
+
position += stringLength;
|
|
186
|
+
break;
|
|
187
|
+
case 8:
|
|
188
|
+
out[name] = {
|
|
189
|
+
type: TIMESTAMP_TAG,
|
|
190
|
+
value: new Date(new Int64(new Uint8Array(headers.buffer, headers.byteOffset + position, 8)).valueOf()),
|
|
191
|
+
};
|
|
192
|
+
position += 8;
|
|
193
|
+
break;
|
|
194
|
+
case 9:
|
|
195
|
+
const uuidBytes = new Uint8Array(headers.buffer, headers.byteOffset + position, 16);
|
|
196
|
+
position += 16;
|
|
197
|
+
out[name] = {
|
|
198
|
+
type: UUID_TAG,
|
|
199
|
+
value: `${utilHexEncoding.toHex(uuidBytes.subarray(0, 4))}-${utilHexEncoding.toHex(uuidBytes.subarray(4, 6))}-${utilHexEncoding.toHex(uuidBytes.subarray(6, 8))}-${utilHexEncoding.toHex(uuidBytes.subarray(8, 10))}-${utilHexEncoding.toHex(uuidBytes.subarray(10))}`,
|
|
200
|
+
};
|
|
201
|
+
break;
|
|
202
|
+
default:
|
|
203
|
+
throw new Error(`Unrecognized header type tag`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return out;
|
|
207
|
+
}
|
|
304
208
|
}
|
|
305
|
-
|
|
209
|
+
const BOOLEAN_TAG = "boolean";
|
|
210
|
+
const BYTE_TAG = "byte";
|
|
211
|
+
const SHORT_TAG = "short";
|
|
212
|
+
const INT_TAG = "integer";
|
|
213
|
+
const LONG_TAG = "long";
|
|
214
|
+
const BINARY_TAG = "binary";
|
|
215
|
+
const STRING_TAG = "string";
|
|
216
|
+
const TIMESTAMP_TAG = "timestamp";
|
|
217
|
+
const UUID_TAG = "uuid";
|
|
218
|
+
const UUID_PATTERN = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/;
|
|
306
219
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
return isEndOfStream;
|
|
332
|
-
}
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
getAvailableMessages() {
|
|
336
|
-
const messages = this.messageBuffer;
|
|
337
|
-
this.messageBuffer = [];
|
|
338
|
-
const isEndOfStream = this.isEndOfStream;
|
|
220
|
+
const PRELUDE_MEMBER_LENGTH = 4;
|
|
221
|
+
const PRELUDE_LENGTH = PRELUDE_MEMBER_LENGTH * 2;
|
|
222
|
+
const CHECKSUM_LENGTH = 4;
|
|
223
|
+
const MINIMUM_MESSAGE_LENGTH = PRELUDE_LENGTH + CHECKSUM_LENGTH * 2;
|
|
224
|
+
function splitMessage({ byteLength, byteOffset, buffer }) {
|
|
225
|
+
if (byteLength < MINIMUM_MESSAGE_LENGTH) {
|
|
226
|
+
throw new Error("Provided message too short to accommodate event stream message overhead");
|
|
227
|
+
}
|
|
228
|
+
const view = new DataView(buffer, byteOffset, byteLength);
|
|
229
|
+
const messageLength = view.getUint32(0, false);
|
|
230
|
+
if (byteLength !== messageLength) {
|
|
231
|
+
throw new Error("Reported message length does not match received message length");
|
|
232
|
+
}
|
|
233
|
+
const headerLength = view.getUint32(PRELUDE_MEMBER_LENGTH, false);
|
|
234
|
+
const expectedPreludeChecksum = view.getUint32(PRELUDE_LENGTH, false);
|
|
235
|
+
const expectedMessageChecksum = view.getUint32(byteLength - CHECKSUM_LENGTH, false);
|
|
236
|
+
const checksummer = new crc32.Crc32().update(new Uint8Array(buffer, byteOffset, PRELUDE_LENGTH));
|
|
237
|
+
if (expectedPreludeChecksum !== checksummer.digest()) {
|
|
238
|
+
throw new Error(`The prelude checksum specified in the message (${expectedPreludeChecksum}) does not match the calculated CRC32 checksum (${checksummer.digest()})`);
|
|
239
|
+
}
|
|
240
|
+
checksummer.update(new Uint8Array(buffer, byteOffset + PRELUDE_LENGTH, byteLength - (PRELUDE_LENGTH + CHECKSUM_LENGTH)));
|
|
241
|
+
if (expectedMessageChecksum !== checksummer.digest()) {
|
|
242
|
+
throw new Error(`The message checksum (${checksummer.digest()}) did not match the expected value of ${expectedMessageChecksum}`);
|
|
243
|
+
}
|
|
339
244
|
return {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
},
|
|
343
|
-
isEndOfStream() {
|
|
344
|
-
return isEndOfStream;
|
|
345
|
-
}
|
|
245
|
+
headers: new DataView(buffer, byteOffset + PRELUDE_LENGTH + CHECKSUM_LENGTH, headerLength),
|
|
246
|
+
body: new Uint8Array(buffer, byteOffset + PRELUDE_LENGTH + CHECKSUM_LENGTH + headerLength, messageLength - headerLength - (PRELUDE_LENGTH + CHECKSUM_LENGTH + CHECKSUM_LENGTH)),
|
|
346
247
|
};
|
|
347
|
-
|
|
348
|
-
/**
|
|
349
|
-
* Convert a structured JavaScript object with tagged headers into a binary
|
|
350
|
-
* event stream message.
|
|
351
|
-
*/
|
|
352
|
-
encode({ headers: rawHeaders, body }) {
|
|
353
|
-
const headers = this.headerMarshaller.format(rawHeaders);
|
|
354
|
-
const length = headers.byteLength + body.byteLength + 16;
|
|
355
|
-
const out = new Uint8Array(length);
|
|
356
|
-
const view = new DataView(out.buffer, out.byteOffset, out.byteLength);
|
|
357
|
-
const checksum = new import_crc322.Crc32();
|
|
358
|
-
view.setUint32(0, length, false);
|
|
359
|
-
view.setUint32(4, headers.byteLength, false);
|
|
360
|
-
view.setUint32(8, checksum.update(out.subarray(0, 8)).digest(), false);
|
|
361
|
-
out.set(headers, 12);
|
|
362
|
-
out.set(body, headers.byteLength + 12);
|
|
363
|
-
view.setUint32(length - 4, checksum.update(out.subarray(8, length - 4)).digest(), false);
|
|
364
|
-
return out;
|
|
365
|
-
}
|
|
366
|
-
/**
|
|
367
|
-
* Convert a binary event stream message into a JavaScript object with an
|
|
368
|
-
* opaque, binary body and tagged, parsed headers.
|
|
369
|
-
*/
|
|
370
|
-
decode(message) {
|
|
371
|
-
const { headers, body } = splitMessage(message);
|
|
372
|
-
return { headers: this.headerMarshaller.parse(headers), body };
|
|
373
|
-
}
|
|
374
|
-
/**
|
|
375
|
-
* Convert a structured JavaScript object with tagged headers into a binary
|
|
376
|
-
* event stream message header.
|
|
377
|
-
*/
|
|
378
|
-
formatHeaders(rawHeaders) {
|
|
379
|
-
return this.headerMarshaller.format(rawHeaders);
|
|
380
|
-
}
|
|
381
|
-
};
|
|
248
|
+
}
|
|
382
249
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
250
|
+
class EventStreamCodec {
|
|
251
|
+
headerMarshaller;
|
|
252
|
+
messageBuffer;
|
|
253
|
+
isEndOfStream;
|
|
254
|
+
constructor(toUtf8, fromUtf8) {
|
|
255
|
+
this.headerMarshaller = new HeaderMarshaller(toUtf8, fromUtf8);
|
|
256
|
+
this.messageBuffer = [];
|
|
257
|
+
this.isEndOfStream = false;
|
|
258
|
+
}
|
|
259
|
+
feed(message) {
|
|
260
|
+
this.messageBuffer.push(this.decode(message));
|
|
261
|
+
}
|
|
262
|
+
endOfStream() {
|
|
263
|
+
this.isEndOfStream = true;
|
|
264
|
+
}
|
|
265
|
+
getMessage() {
|
|
266
|
+
const message = this.messageBuffer.pop();
|
|
267
|
+
const isEndOfStream = this.isEndOfStream;
|
|
268
|
+
return {
|
|
269
|
+
getMessage() {
|
|
270
|
+
return message;
|
|
271
|
+
},
|
|
272
|
+
isEndOfStream() {
|
|
273
|
+
return isEndOfStream;
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
getAvailableMessages() {
|
|
278
|
+
const messages = this.messageBuffer;
|
|
279
|
+
this.messageBuffer = [];
|
|
280
|
+
const isEndOfStream = this.isEndOfStream;
|
|
281
|
+
return {
|
|
282
|
+
getMessages() {
|
|
283
|
+
return messages;
|
|
284
|
+
},
|
|
285
|
+
isEndOfStream() {
|
|
286
|
+
return isEndOfStream;
|
|
287
|
+
},
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
encode({ headers: rawHeaders, body }) {
|
|
291
|
+
const headers = this.headerMarshaller.format(rawHeaders);
|
|
292
|
+
const length = headers.byteLength + body.byteLength + 16;
|
|
293
|
+
const out = new Uint8Array(length);
|
|
294
|
+
const view = new DataView(out.buffer, out.byteOffset, out.byteLength);
|
|
295
|
+
const checksum = new crc32.Crc32();
|
|
296
|
+
view.setUint32(0, length, false);
|
|
297
|
+
view.setUint32(4, headers.byteLength, false);
|
|
298
|
+
view.setUint32(8, checksum.update(out.subarray(0, 8)).digest(), false);
|
|
299
|
+
out.set(headers, 12);
|
|
300
|
+
out.set(body, headers.byteLength + 12);
|
|
301
|
+
view.setUint32(length - 4, checksum.update(out.subarray(8, length - 4)).digest(), false);
|
|
302
|
+
return out;
|
|
303
|
+
}
|
|
304
|
+
decode(message) {
|
|
305
|
+
const { headers, body } = splitMessage(message);
|
|
306
|
+
return { headers: this.headerMarshaller.parse(headers), body };
|
|
307
|
+
}
|
|
308
|
+
formatHeaders(rawHeaders) {
|
|
309
|
+
return this.headerMarshaller.format(rawHeaders);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
401
312
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
}
|
|
418
|
-
if (this.options.includeEndFrame) {
|
|
419
|
-
yield new Uint8Array(0);
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
};
|
|
313
|
+
class MessageDecoderStream {
|
|
314
|
+
options;
|
|
315
|
+
constructor(options) {
|
|
316
|
+
this.options = options;
|
|
317
|
+
}
|
|
318
|
+
[Symbol.asyncIterator]() {
|
|
319
|
+
return this.asyncIterator();
|
|
320
|
+
}
|
|
321
|
+
async *asyncIterator() {
|
|
322
|
+
for await (const bytes of this.options.inputStream) {
|
|
323
|
+
const decoded = this.options.decoder.decode(bytes);
|
|
324
|
+
yield decoded;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
423
328
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
};
|
|
329
|
+
class MessageEncoderStream {
|
|
330
|
+
options;
|
|
331
|
+
constructor(options) {
|
|
332
|
+
this.options = options;
|
|
333
|
+
}
|
|
334
|
+
[Symbol.asyncIterator]() {
|
|
335
|
+
return this.asyncIterator();
|
|
336
|
+
}
|
|
337
|
+
async *asyncIterator() {
|
|
338
|
+
for await (const msg of this.options.messageStream) {
|
|
339
|
+
const encoded = this.options.encoder.encode(msg);
|
|
340
|
+
yield encoded;
|
|
341
|
+
}
|
|
342
|
+
if (this.options.includeEndFrame) {
|
|
343
|
+
yield new Uint8Array(0);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
443
347
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
};
|
|
462
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
348
|
+
class SmithyMessageDecoderStream {
|
|
349
|
+
options;
|
|
350
|
+
constructor(options) {
|
|
351
|
+
this.options = options;
|
|
352
|
+
}
|
|
353
|
+
[Symbol.asyncIterator]() {
|
|
354
|
+
return this.asyncIterator();
|
|
355
|
+
}
|
|
356
|
+
async *asyncIterator() {
|
|
357
|
+
for await (const message of this.options.messageStream) {
|
|
358
|
+
const deserialized = await this.options.deserializer(message);
|
|
359
|
+
if (deserialized === undefined)
|
|
360
|
+
continue;
|
|
361
|
+
yield deserialized;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
463
365
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
366
|
+
class SmithyMessageEncoderStream {
|
|
367
|
+
options;
|
|
368
|
+
constructor(options) {
|
|
369
|
+
this.options = options;
|
|
370
|
+
}
|
|
371
|
+
[Symbol.asyncIterator]() {
|
|
372
|
+
return this.asyncIterator();
|
|
373
|
+
}
|
|
374
|
+
async *asyncIterator() {
|
|
375
|
+
for await (const chunk of this.options.inputStream) {
|
|
376
|
+
const payloadBuf = this.options.serializer(chunk);
|
|
377
|
+
yield payloadBuf;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
473
381
|
|
|
382
|
+
exports.EventStreamCodec = EventStreamCodec;
|
|
383
|
+
exports.HeaderMarshaller = HeaderMarshaller;
|
|
384
|
+
exports.Int64 = Int64;
|
|
385
|
+
exports.MessageDecoderStream = MessageDecoderStream;
|
|
386
|
+
exports.MessageEncoderStream = MessageEncoderStream;
|
|
387
|
+
exports.SmithyMessageDecoderStream = SmithyMessageDecoderStream;
|
|
388
|
+
exports.SmithyMessageEncoderStream = SmithyMessageEncoderStream;
|
|
@@ -2,6 +2,9 @@ import { Crc32 } from "@aws-crypto/crc32";
|
|
|
2
2
|
import { HeaderMarshaller } from "./HeaderMarshaller";
|
|
3
3
|
import { splitMessage } from "./splitMessage";
|
|
4
4
|
export class EventStreamCodec {
|
|
5
|
+
headerMarshaller;
|
|
6
|
+
messageBuffer;
|
|
7
|
+
isEndOfStream;
|
|
5
8
|
constructor(toUtf8, fromUtf8) {
|
|
6
9
|
this.headerMarshaller = new HeaderMarshaller(toUtf8, fromUtf8);
|
|
7
10
|
this.messageBuffer = [];
|
package/dist-es/Int64.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { toHex } from "@smithy/util-hex-encoding";
|
|
2
2
|
export class Int64 {
|
|
3
|
+
bytes;
|
|
3
4
|
constructor(bytes) {
|
|
4
5
|
this.bytes = bytes;
|
|
5
6
|
if (bytes.byteLength !== 8) {
|
|
@@ -7,7 +8,7 @@ export class Int64 {
|
|
|
7
8
|
}
|
|
8
9
|
}
|
|
9
10
|
static fromNumber(number) {
|
|
10
|
-
if (number >
|
|
11
|
+
if (number > 9_223_372_036_854_775_807 || number < -9_223_372_036_854_775_808) {
|
|
11
12
|
throw new Error(`${number} is too large (or, if negative, too small) to represent as an Int64`);
|
|
12
13
|
}
|
|
13
14
|
const bytes = new Uint8Array(8);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smithy/eventstream-codec",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"build": "concurrently 'yarn:build:cjs' 'yarn:build:es' 'yarn:build:types && yarn build:types:downlevel'",
|
|
6
6
|
"build:cjs": "node ../../scripts/inline eventstream-codec",
|
|
@@ -25,12 +25,12 @@
|
|
|
25
25
|
"sideEffects": false,
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@aws-crypto/crc32": "5.2.0",
|
|
28
|
-
"@smithy/types": "^4.
|
|
29
|
-
"@smithy/util-hex-encoding": "^4.
|
|
28
|
+
"@smithy/types": "^4.6.0",
|
|
29
|
+
"@smithy/util-hex-encoding": "^4.2.0",
|
|
30
30
|
"tslib": "^2.6.2"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@smithy/util-utf8": "^4.
|
|
33
|
+
"@smithy/util-utf8": "^4.2.0",
|
|
34
34
|
"@types/node": "^18.11.9",
|
|
35
35
|
"concurrently": "7.0.0",
|
|
36
36
|
"downlevel-dts": "0.10.1",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("./index.js");
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("./index.js");
|
package/dist-cjs/Int64.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("./index.js");
|
package/dist-cjs/Message.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("./index.js");
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("./index.js");
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("./index.js");
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("./index.js");
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("./index.js");
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("./index.js");
|
package/dist-cjs/splitMessage.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("./index.js");
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require("./index.js");
|