@aws-sdk/eventstream-codec
Advanced tools
+8
-0
@@ -6,2 +6,10 @@ # Change Log | ||
| # [3.186.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.185.0...v3.186.0) (2022-10-06) | ||
| **Note:** Version bump only for package @aws-sdk/eventstream-codec | ||
| # [3.183.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.182.0...v3.183.0) (2022-10-03) | ||
@@ -8,0 +16,0 @@ |
| import { Crc32 } from "@aws-crypto/crc32"; | ||
| import { HeaderMarshaller } from "./HeaderMarshaller"; | ||
| import { splitMessage } from "./splitMessage"; | ||
| export class EventStreamCodec { | ||
| constructor(toUtf8, fromUtf8) { | ||
| var EventStreamCodec = (function () { | ||
| function EventStreamCodec(toUtf8, fromUtf8) { | ||
| this.headerMarshaller = new HeaderMarshaller(toUtf8, fromUtf8); | ||
| } | ||
| encode({ headers: rawHeaders, body }) { | ||
| const headers = this.headerMarshaller.format(rawHeaders); | ||
| const length = headers.byteLength + body.byteLength + 16; | ||
| const out = new Uint8Array(length); | ||
| const view = new DataView(out.buffer, out.byteOffset, out.byteLength); | ||
| const checksum = new Crc32(); | ||
| EventStreamCodec.prototype.encode = function (_a) { | ||
| var rawHeaders = _a.headers, body = _a.body; | ||
| var headers = this.headerMarshaller.format(rawHeaders); | ||
| var length = headers.byteLength + body.byteLength + 16; | ||
| var out = new Uint8Array(length); | ||
| var view = new DataView(out.buffer, out.byteOffset, out.byteLength); | ||
| var checksum = new Crc32(); | ||
| view.setUint32(0, length, false); | ||
@@ -21,10 +22,12 @@ view.setUint32(4, headers.byteLength, false); | ||
| return out; | ||
| } | ||
| decode(message) { | ||
| const { headers, body } = splitMessage(message); | ||
| return { headers: this.headerMarshaller.parse(headers), body }; | ||
| } | ||
| formatHeaders(rawHeaders) { | ||
| }; | ||
| EventStreamCodec.prototype.decode = function (message) { | ||
| var _a = splitMessage(message), headers = _a.headers, body = _a.body; | ||
| return { headers: this.headerMarshaller.parse(headers), body: body }; | ||
| }; | ||
| EventStreamCodec.prototype.formatHeaders = function (rawHeaders) { | ||
| return this.headerMarshaller.format(rawHeaders); | ||
| } | ||
| } | ||
| }; | ||
| return EventStreamCodec; | ||
| }()); | ||
| export { EventStreamCodec }; |
@@ -0,23 +1,45 @@ | ||
| import { __values } from "tslib"; | ||
| import { fromHex, toHex } from "@aws-sdk/util-hex-encoding"; | ||
| import { Int64 } from "./Int64"; | ||
| export class HeaderMarshaller { | ||
| constructor(toUtf8, fromUtf8) { | ||
| var HeaderMarshaller = (function () { | ||
| function HeaderMarshaller(toUtf8, fromUtf8) { | ||
| this.toUtf8 = toUtf8; | ||
| this.fromUtf8 = fromUtf8; | ||
| } | ||
| format(headers) { | ||
| const chunks = []; | ||
| for (const headerName of Object.keys(headers)) { | ||
| const bytes = this.fromUtf8(headerName); | ||
| chunks.push(Uint8Array.from([bytes.byteLength]), bytes, this.formatHeaderValue(headers[headerName])); | ||
| HeaderMarshaller.prototype.format = function (headers) { | ||
| var e_1, _a, e_2, _b; | ||
| var chunks = []; | ||
| try { | ||
| for (var _c = __values(Object.keys(headers)), _d = _c.next(); !_d.done; _d = _c.next()) { | ||
| var headerName = _d.value; | ||
| var bytes = this.fromUtf8(headerName); | ||
| chunks.push(Uint8Array.from([bytes.byteLength]), bytes, this.formatHeaderValue(headers[headerName])); | ||
| } | ||
| } | ||
| const out = new Uint8Array(chunks.reduce((carry, bytes) => carry + bytes.byteLength, 0)); | ||
| let position = 0; | ||
| for (const chunk of chunks) { | ||
| out.set(chunk, position); | ||
| position += chunk.byteLength; | ||
| catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
| finally { | ||
| try { | ||
| if (_d && !_d.done && (_a = _c.return)) _a.call(_c); | ||
| } | ||
| finally { if (e_1) throw e_1.error; } | ||
| } | ||
| var out = new Uint8Array(chunks.reduce(function (carry, bytes) { return carry + bytes.byteLength; }, 0)); | ||
| var position = 0; | ||
| try { | ||
| for (var chunks_1 = __values(chunks), chunks_1_1 = chunks_1.next(); !chunks_1_1.done; chunks_1_1 = chunks_1.next()) { | ||
| var chunk = chunks_1_1.value; | ||
| out.set(chunk, position); | ||
| position += chunk.byteLength; | ||
| } | ||
| } | ||
| catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
| finally { | ||
| try { | ||
| if (chunks_1_1 && !chunks_1_1.done && (_b = chunks_1.return)) _b.call(chunks_1); | ||
| } | ||
| finally { if (e_2) throw e_2.error; } | ||
| } | ||
| return out; | ||
| } | ||
| formatHeaderValue(header) { | ||
| }; | ||
| HeaderMarshaller.prototype.formatHeaderValue = function (header) { | ||
| switch (header.type) { | ||
@@ -29,3 +51,3 @@ case "boolean": | ||
| case "short": | ||
| const shortView = new DataView(new ArrayBuffer(3)); | ||
| var shortView = new DataView(new ArrayBuffer(3)); | ||
| shortView.setUint8(0, 3); | ||
@@ -35,3 +57,3 @@ shortView.setInt16(1, header.value, false); | ||
| case "integer": | ||
| const intView = new DataView(new ArrayBuffer(5)); | ||
| var intView = new DataView(new ArrayBuffer(5)); | ||
| intView.setUint8(0, 4); | ||
@@ -41,3 +63,3 @@ intView.setInt32(1, header.value, false); | ||
| case "long": | ||
| const longBytes = new Uint8Array(9); | ||
| var longBytes = new Uint8Array(9); | ||
| longBytes[0] = 5; | ||
@@ -47,18 +69,18 @@ longBytes.set(header.value.bytes, 1); | ||
| case "binary": | ||
| const binView = new DataView(new ArrayBuffer(3 + header.value.byteLength)); | ||
| var binView = new DataView(new ArrayBuffer(3 + header.value.byteLength)); | ||
| binView.setUint8(0, 6); | ||
| binView.setUint16(1, header.value.byteLength, false); | ||
| const binBytes = new Uint8Array(binView.buffer); | ||
| var binBytes = new Uint8Array(binView.buffer); | ||
| binBytes.set(header.value, 3); | ||
| return binBytes; | ||
| case "string": | ||
| const utf8Bytes = this.fromUtf8(header.value); | ||
| const strView = new DataView(new ArrayBuffer(3 + utf8Bytes.byteLength)); | ||
| var utf8Bytes = this.fromUtf8(header.value); | ||
| var strView = new DataView(new ArrayBuffer(3 + utf8Bytes.byteLength)); | ||
| strView.setUint8(0, 7); | ||
| strView.setUint16(1, utf8Bytes.byteLength, false); | ||
| const strBytes = new Uint8Array(strView.buffer); | ||
| var strBytes = new Uint8Array(strView.buffer); | ||
| strBytes.set(utf8Bytes, 3); | ||
| return strBytes; | ||
| case "timestamp": | ||
| const tsBytes = new Uint8Array(9); | ||
| var tsBytes = new Uint8Array(9); | ||
| tsBytes[0] = 8; | ||
@@ -69,5 +91,5 @@ tsBytes.set(Int64.fromNumber(header.value.valueOf()).bytes, 1); | ||
| if (!UUID_PATTERN.test(header.value)) { | ||
| throw new Error(`Invalid UUID received: ${header.value}`); | ||
| throw new Error("Invalid UUID received: ".concat(header.value)); | ||
| } | ||
| const uuidBytes = new Uint8Array(17); | ||
| var uuidBytes = new Uint8Array(17); | ||
| uuidBytes[0] = 9; | ||
@@ -77,13 +99,13 @@ uuidBytes.set(fromHex(header.value.replace(/\-/g, "")), 1); | ||
| } | ||
| } | ||
| parse(headers) { | ||
| const out = {}; | ||
| let position = 0; | ||
| }; | ||
| HeaderMarshaller.prototype.parse = function (headers) { | ||
| var out = {}; | ||
| var position = 0; | ||
| while (position < headers.byteLength) { | ||
| const nameLength = headers.getUint8(position++); | ||
| const name = this.toUtf8(new Uint8Array(headers.buffer, headers.byteOffset + position, nameLength)); | ||
| var nameLength = headers.getUint8(position++); | ||
| var name_1 = this.toUtf8(new Uint8Array(headers.buffer, headers.byteOffset + position, nameLength)); | ||
| position += nameLength; | ||
| switch (headers.getUint8(position++)) { | ||
| case 0: | ||
| out[name] = { | ||
| out[name_1] = { | ||
| type: BOOLEAN_TAG, | ||
@@ -94,3 +116,3 @@ value: true, | ||
| case 1: | ||
| out[name] = { | ||
| out[name_1] = { | ||
| type: BOOLEAN_TAG, | ||
@@ -101,3 +123,3 @@ value: false, | ||
| case 2: | ||
| out[name] = { | ||
| out[name_1] = { | ||
| type: BYTE_TAG, | ||
@@ -108,3 +130,3 @@ value: headers.getInt8(position++), | ||
| case 3: | ||
| out[name] = { | ||
| out[name_1] = { | ||
| type: SHORT_TAG, | ||
@@ -116,3 +138,3 @@ value: headers.getInt16(position, false), | ||
| case 4: | ||
| out[name] = { | ||
| out[name_1] = { | ||
| type: INT_TAG, | ||
@@ -124,3 +146,3 @@ value: headers.getInt32(position, false), | ||
| case 5: | ||
| out[name] = { | ||
| out[name_1] = { | ||
| type: LONG_TAG, | ||
@@ -132,5 +154,5 @@ value: new Int64(new Uint8Array(headers.buffer, headers.byteOffset + position, 8)), | ||
| case 6: | ||
| const binaryLength = headers.getUint16(position, false); | ||
| var binaryLength = headers.getUint16(position, false); | ||
| position += 2; | ||
| out[name] = { | ||
| out[name_1] = { | ||
| type: BINARY_TAG, | ||
@@ -142,5 +164,5 @@ value: new Uint8Array(headers.buffer, headers.byteOffset + position, binaryLength), | ||
| case 7: | ||
| const stringLength = headers.getUint16(position, false); | ||
| var stringLength = headers.getUint16(position, false); | ||
| position += 2; | ||
| out[name] = { | ||
| out[name_1] = { | ||
| type: STRING_TAG, | ||
@@ -152,3 +174,3 @@ value: this.toUtf8(new Uint8Array(headers.buffer, headers.byteOffset + position, stringLength)), | ||
| case 8: | ||
| out[name] = { | ||
| out[name_1] = { | ||
| type: TIMESTAMP_TAG, | ||
@@ -160,16 +182,18 @@ value: new Date(new Int64(new Uint8Array(headers.buffer, headers.byteOffset + position, 8)).valueOf()), | ||
| case 9: | ||
| const uuidBytes = new Uint8Array(headers.buffer, headers.byteOffset + position, 16); | ||
| var uuidBytes = new Uint8Array(headers.buffer, headers.byteOffset + position, 16); | ||
| position += 16; | ||
| out[name] = { | ||
| out[name_1] = { | ||
| type: UUID_TAG, | ||
| value: `${toHex(uuidBytes.subarray(0, 4))}-${toHex(uuidBytes.subarray(4, 6))}-${toHex(uuidBytes.subarray(6, 8))}-${toHex(uuidBytes.subarray(8, 10))}-${toHex(uuidBytes.subarray(10))}`, | ||
| value: "".concat(toHex(uuidBytes.subarray(0, 4)), "-").concat(toHex(uuidBytes.subarray(4, 6)), "-").concat(toHex(uuidBytes.subarray(6, 8)), "-").concat(toHex(uuidBytes.subarray(8, 10)), "-").concat(toHex(uuidBytes.subarray(10))), | ||
| }; | ||
| break; | ||
| default: | ||
| throw new Error(`Unrecognized header type tag`); | ||
| throw new Error("Unrecognized header type tag"); | ||
| } | ||
| } | ||
| return out; | ||
| } | ||
| } | ||
| }; | ||
| return HeaderMarshaller; | ||
| }()); | ||
| export { HeaderMarshaller }; | ||
| var HEADER_VALUE_TYPE; | ||
@@ -188,11 +212,11 @@ (function (HEADER_VALUE_TYPE) { | ||
| })(HEADER_VALUE_TYPE || (HEADER_VALUE_TYPE = {})); | ||
| const BOOLEAN_TAG = "boolean"; | ||
| const BYTE_TAG = "byte"; | ||
| const SHORT_TAG = "short"; | ||
| const INT_TAG = "integer"; | ||
| const LONG_TAG = "long"; | ||
| const BINARY_TAG = "binary"; | ||
| const STRING_TAG = "string"; | ||
| const TIMESTAMP_TAG = "timestamp"; | ||
| const UUID_TAG = "uuid"; | ||
| const UUID_PATTERN = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/; | ||
| var BOOLEAN_TAG = "boolean"; | ||
| var BYTE_TAG = "byte"; | ||
| var SHORT_TAG = "short"; | ||
| var INT_TAG = "integer"; | ||
| var LONG_TAG = "long"; | ||
| var BINARY_TAG = "binary"; | ||
| var STRING_TAG = "string"; | ||
| var TIMESTAMP_TAG = "timestamp"; | ||
| var UUID_TAG = "uuid"; | ||
| var UUID_PATTERN = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/; |
+18
-16
| import { toHex } from "@aws-sdk/util-hex-encoding"; | ||
| export class Int64 { | ||
| constructor(bytes) { | ||
| var Int64 = (function () { | ||
| function Int64(bytes) { | ||
| this.bytes = bytes; | ||
@@ -9,8 +9,8 @@ if (bytes.byteLength !== 8) { | ||
| } | ||
| static fromNumber(number) { | ||
| Int64.fromNumber = function (number) { | ||
| if (number > 9223372036854776000 || number < -9223372036854776000) { | ||
| throw new Error(`${number} is too large (or, if negative, too small) to represent as an Int64`); | ||
| throw new Error("".concat(number, " is too large (or, if negative, too small) to represent as an Int64")); | ||
| } | ||
| const bytes = new Uint8Array(8); | ||
| for (let i = 7, remaining = Math.abs(Math.round(number)); i > -1 && remaining > 0; i--, remaining /= 256) { | ||
| var bytes = new Uint8Array(8); | ||
| for (var i = 7, remaining = Math.abs(Math.round(number)); i > -1 && remaining > 0; i--, remaining /= 256) { | ||
| bytes[i] = remaining; | ||
@@ -22,6 +22,6 @@ } | ||
| return new Int64(bytes); | ||
| } | ||
| valueOf() { | ||
| const bytes = this.bytes.slice(0); | ||
| const negative = bytes[0] & 0b10000000; | ||
| }; | ||
| Int64.prototype.valueOf = function () { | ||
| var bytes = this.bytes.slice(0); | ||
| var negative = bytes[0] & 128; | ||
| if (negative) { | ||
@@ -31,12 +31,14 @@ negate(bytes); | ||
| return parseInt(toHex(bytes), 16) * (negative ? -1 : 1); | ||
| } | ||
| toString() { | ||
| }; | ||
| Int64.prototype.toString = function () { | ||
| return String(this.valueOf()); | ||
| } | ||
| } | ||
| }; | ||
| return Int64; | ||
| }()); | ||
| export { Int64 }; | ||
| function negate(bytes) { | ||
| for (let i = 0; i < 8; i++) { | ||
| for (var i = 0; i < 8; i++) { | ||
| bytes[i] ^= 0xff; | ||
| } | ||
| for (let i = 7; i > -1; i--) { | ||
| for (var i = 7; i > -1; i--) { | ||
| bytes[i]++; | ||
@@ -43,0 +45,0 @@ if (bytes[i] !== 0) |
+14
-13
| import { Crc32 } from "@aws-crypto/crc32"; | ||
| const PRELUDE_MEMBER_LENGTH = 4; | ||
| const PRELUDE_LENGTH = PRELUDE_MEMBER_LENGTH * 2; | ||
| const CHECKSUM_LENGTH = 4; | ||
| const MINIMUM_MESSAGE_LENGTH = PRELUDE_LENGTH + CHECKSUM_LENGTH * 2; | ||
| export function splitMessage({ byteLength, byteOffset, buffer }) { | ||
| var PRELUDE_MEMBER_LENGTH = 4; | ||
| var PRELUDE_LENGTH = PRELUDE_MEMBER_LENGTH * 2; | ||
| var CHECKSUM_LENGTH = 4; | ||
| var MINIMUM_MESSAGE_LENGTH = PRELUDE_LENGTH + CHECKSUM_LENGTH * 2; | ||
| export function splitMessage(_a) { | ||
| var byteLength = _a.byteLength, byteOffset = _a.byteOffset, buffer = _a.buffer; | ||
| if (byteLength < MINIMUM_MESSAGE_LENGTH) { | ||
| throw new Error("Provided message too short to accommodate event stream message overhead"); | ||
| } | ||
| const view = new DataView(buffer, byteOffset, byteLength); | ||
| const messageLength = view.getUint32(0, false); | ||
| var view = new DataView(buffer, byteOffset, byteLength); | ||
| var messageLength = view.getUint32(0, false); | ||
| if (byteLength !== messageLength) { | ||
| throw new Error("Reported message length does not match received message length"); | ||
| } | ||
| const headerLength = view.getUint32(PRELUDE_MEMBER_LENGTH, false); | ||
| const expectedPreludeChecksum = view.getUint32(PRELUDE_LENGTH, false); | ||
| const expectedMessageChecksum = view.getUint32(byteLength - CHECKSUM_LENGTH, false); | ||
| const checksummer = new Crc32().update(new Uint8Array(buffer, byteOffset, PRELUDE_LENGTH)); | ||
| var headerLength = view.getUint32(PRELUDE_MEMBER_LENGTH, false); | ||
| var expectedPreludeChecksum = view.getUint32(PRELUDE_LENGTH, false); | ||
| var expectedMessageChecksum = view.getUint32(byteLength - CHECKSUM_LENGTH, false); | ||
| var checksummer = new Crc32().update(new Uint8Array(buffer, byteOffset, PRELUDE_LENGTH)); | ||
| if (expectedPreludeChecksum !== checksummer.digest()) { | ||
| throw new Error(`The prelude checksum specified in the message (${expectedPreludeChecksum}) does not match the calculated CRC32 checksum (${checksummer.digest()})`); | ||
| throw new Error("The prelude checksum specified in the message (".concat(expectedPreludeChecksum, ") does not match the calculated CRC32 checksum (").concat(checksummer.digest(), ")")); | ||
| } | ||
| checksummer.update(new Uint8Array(buffer, byteOffset + PRELUDE_LENGTH, byteLength - (PRELUDE_LENGTH + CHECKSUM_LENGTH))); | ||
| if (expectedMessageChecksum !== checksummer.digest()) { | ||
| throw new Error(`The message checksum (${checksummer.digest()}) did not match the expected value of ${expectedMessageChecksum}`); | ||
| throw new Error("The message checksum (".concat(checksummer.digest(), ") did not match the expected value of ").concat(expectedMessageChecksum)); | ||
| } | ||
@@ -26,0 +27,0 @@ return { |
| import { Int64 } from "./Int64"; | ||
| export const vectors = { | ||
| export var vectors = { | ||
| all_headers: { | ||
@@ -4,0 +4,0 @@ expectation: "success", |
+5
-5
| { | ||
| "name": "@aws-sdk/eventstream-codec", | ||
| "version": "3.183.0", | ||
| "version": "3.186.0", | ||
| "scripts": { | ||
@@ -24,9 +24,9 @@ "build": "concurrently 'yarn:build:cjs' 'yarn:build:es' 'yarn:build:types'", | ||
| "@aws-crypto/crc32": "2.0.0", | ||
| "@aws-sdk/types": "3.183.0", | ||
| "@aws-sdk/util-hex-encoding": "3.183.0", | ||
| "@aws-sdk/types": "3.186.0", | ||
| "@aws-sdk/util-hex-encoding": "3.186.0", | ||
| "tslib": "^2.3.1" | ||
| }, | ||
| "devDependencies": { | ||
| "@aws-sdk/util-utf8-browser": "3.183.0", | ||
| "@aws-sdk/util-utf8-node": "3.183.0", | ||
| "@aws-sdk/util-utf8-browser": "3.186.0", | ||
| "@aws-sdk/util-utf8-node": "3.186.0", | ||
| "@tsconfig/recommended": "1.0.1", | ||
@@ -33,0 +33,0 @@ "@types/node": "^10.0.0", |
62627
2.75%1119
2.75%+ Added
+ Added
- Removed
- Removed
Updated