UNPKG

lambda-live-debugger

Version:

Debug Lambda functions locally like it is running in the cloud

1,256 lines (1,247 loc) 43 kB
const { nv, NumericValue, calculateBodyLength, _parseEpochTimestamp, fromBase64, generateIdempotencyToken } = require("@smithy/core/serde"); const { HttpRequest, collectBody, SerdeContext, RpcProtocol } = require("@smithy/core/protocols"); const { NormalizedSchema, deref, TypeRegistry } = require("@smithy/core/schema"); const { getSmithyContext } = require("@smithy/core/transport"); const majorUint64 = 0; const majorNegativeInt64 = 1; const majorUnstructuredByteString = 2; const majorUtf8String = 3; const majorList = 4; const majorMap = 5; const majorTag = 6; const majorSpecial = 7; const specialFalse = 20; const specialTrue = 21; const specialNull = 22; const specialUndefined = 23; const extendedOneByte = 24; const extendedFloat16 = 25; const extendedFloat32 = 26; const extendedFloat64 = 27; const minorIndefinite = 31; function alloc(size) { return typeof Buffer !== "undefined" ? Buffer.alloc(size) : new Uint8Array(size); } const tagSymbol = Symbol("@smithy/core/cbor::tagSymbol"); function tag(data) { data[tagSymbol] = true; return data; } const USE_BUFFER$1 = typeof Buffer !== "undefined"; const textDecoder = new TextDecoder(); let payload = alloc(0); let isBuffer = false; let dataView$1 = new DataView(payload.buffer, payload.byteOffset, payload.byteLength); let _offset = 0; function setPayload(bytes) { payload = bytes; isBuffer = USE_BUFFER$1 && payload instanceof Buffer; dataView$1 = new DataView(payload.buffer, payload.byteOffset, payload.byteLength); } function decode(at, to) { if (at >= to) { throw new Error("unexpected end of (decode) payload."); } const major = (payload[at] & 0b1110_0000) >> 5; const minor = payload[at] & 0b0001_1111; if (minor === minorIndefinite && 2 <= major && major <= 5) { return decodeIndefinite(at, to); } switch (major) { case majorUint64: case majorNegativeInt64: case majorTag: { let unsignedInt; let offset; if (minor < 24) { unsignedInt = minor; offset = 1; } else { switch (minor) { case extendedOneByte: if (to - at < 2) { overflow(1); } unsignedInt = payload[at + 1]; offset = 2; break; case extendedFloat16: if (to - at < 3) { overflow(2); } unsignedInt = dataView$1.getUint16(at + 1); offset = 3; break; case extendedFloat32: if (to - at < 5) { overflow(4); } unsignedInt = dataView$1.getUint32(at + 1); offset = 5; break; case extendedFloat64: if (to - at < 9) { overflow(8); } { const hi = dataView$1.getUint32(at + 1); if (hi < 0x00200000) { unsignedInt = hi * 4294967296 + dataView$1.getUint32(at + 5); } else { unsignedInt = dataView$1.getBigUint64(at + 1); } } offset = 9; break; default: unexpectedMinor(minor); } } if (major === majorUint64) { _offset = offset; return castBigInt(unsignedInt); } else if (major === majorNegativeInt64) { let negativeInt; if (typeof unsignedInt === "bigint") { negativeInt = BigInt(-1) - unsignedInt; } else { negativeInt = -1 - unsignedInt; } _offset = offset; return castBigInt(negativeInt); } else { return decodeTagValue(at, to, minor, unsignedInt, offset); } } case majorUtf8String: return decodeUtf8String(at, to); case majorMap: return decodeMap(at, to); case majorList: return decodeList(at, to); case majorUnstructuredByteString: return decodeUnstructuredByteString(at, to); default: return decodeSpecial(at, to); } } function decodeIndefinite(at, to) { const major = (payload[at] & 0b1110_0000) >> 5; const minor = payload[at] & 0b0001_1111; if (minor === minorIndefinite) { switch (major) { case majorUtf8String: return decodeUtf8StringIndefinite(at, to); case majorMap: return decodeMapIndefinite(at, to); case majorList: return decodeListIndefinite(at, to); case majorUnstructuredByteString: return decodeUnstructuredByteStringIndefinite(at, to); } } } function bytesToFloat16(a, b) { const sign = a >> 7; const exponent = (a & 0b0111_1100) >> 2; const fraction = ((a & 0b0000_0011) << 8) | b; const scalar = sign === 0 ? 1 : -1; if (exponent === 0b00000) { if (fraction === 0) { return 0; } return scalar * (Math.pow(2, 1 - 15) * (fraction / 1024)); } else if (exponent === 0b11111) { if (fraction === 0) { return scalar * Infinity; } return NaN; } return scalar * (Math.pow(2, exponent - 15) * (1 + fraction / 1024)); } function decodeMap(at, to) { const mapDataLength = decodeCount(at, to); if (mapDataLength < 15) { return decodeMapSmall(at, to, mapDataLength); } return decodeMapLarge(at, to, mapDataLength); } function decodeMapLarge(at, to, mapDataLength) { const offset = _offset; at += offset; const base = at; const map = Object.create(null); for (let i = 0; i < mapDataLength; ++i) { const key = decodeUtf8String(at, to); at += _offset; const valMajor = (payload[at] & 0b1110_0000) >> 5; if (valMajor === majorUtf8String) { map[key] = decodeUtf8String(at, to); } else { map[key] = decode(at, to); } at += _offset; } _offset = offset + (at - base); Object.setPrototypeOf(map, Object.prototype); return map; } function decodeMapSmall(at, to, mapDataLength) { const offset = _offset; at += offset; const base = at; const map = {}; for (let i = 0; i < mapDataLength; ++i) { const key = decodeUtf8String(at, to); at += _offset; map[key] = decode(at, to); at += _offset; } _offset = offset + (at - base); return map; } function decodeList(at, to) { const listDataLength = decodeCount(at, to); const offset = _offset; at += offset; const base = at; const list = Array(listDataLength); for (let i = 0; i < listDataLength; ++i) { list[i] = decode(at, to); at += _offset; } _offset = offset + (at - base); return list; } function decodeUtf8String(at, to) { const length = decodeCount(at, to); const offset = _offset; at += offset; if (to - at < length) { overflow(length); } _offset = offset + length; if (length < 24) { return decodeUtf8StringCached(at, length); } if (isBuffer) { return payload.toString("utf-8", at, at + length); } return textDecoder.decode(payload.subarray(at, at + length)); } const stringCache = new Array(2048); const stringCacheEpochs = new Uint16Array(2048); let cacheEpoch = 0; function advanceDecodingEpoch() { cacheEpoch = (cacheEpoch + 1) & 0b1111_1111_1111_1111; } function decodeUtf8StringCached(at, length) { let h = length; for (let i = 0; i < length; ++i) { h = (h * 31 + payload[at + i]) | 0; } const slot = (h >>> 0) & 2047; const cached = stringCache[slot]; if (cached !== undefined) { if (cached.length === length) { let match = true; for (let i = 0; i < length; ++i) { if (cached.charCodeAt(i) !== payload[at + i]) { match = false; break; } } if (match) { stringCacheEpochs[slot] = cacheEpoch; return cached; } } } const result = isBuffer ? payload.toString("utf-8", at, at + length) : textDecoder.decode(payload.subarray(at, at + length)); if (stringCacheEpochs[slot] !== cacheEpoch) { stringCache[slot] = result; stringCacheEpochs[slot] = cacheEpoch; } return result; } function decodeUnstructuredByteString(at, to) { const length = decodeCount(at, to); const offset = _offset; at += offset; if (to - at < length) { overflow(length); } const value = payload.subarray(at, at + length); _offset = offset + length; return value; } function decodeTagValue(at, to, minor, unsignedInt, offset) { if (minor === 2 || minor === 3) { const length = decodeCount(at + offset, to); let b = BigInt(0); const start = at + offset + _offset; for (let i = start; i < start + length; ++i) { b = (b << BigInt(8)) | BigInt(payload[i]); } _offset = offset + _offset + length; return minor === 3 ? -b - BigInt(1) : b; } else if (minor === 4) { const decimalFraction = decode(at + offset, to); const [exponent, mantissa] = decimalFraction; const normalizer = mantissa < 0 ? -1 : 1; const mantissaStr = "0".repeat(Math.abs(exponent) + 1) + String(BigInt(normalizer) * BigInt(mantissa)); let numericString; const sign = mantissa < 0 ? "-" : ""; numericString = exponent === 0 ? mantissaStr : mantissaStr.slice(0, mantissaStr.length + exponent) + "." + mantissaStr.slice(exponent); numericString = numericString.replace(/^0+/g, ""); if (numericString === "") { numericString = "0"; } if (numericString[0] === ".") { numericString = "0" + numericString; } numericString = sign + numericString; _offset = offset + _offset; return nv(numericString); } else { const value = decode(at + offset, to); const valueOffset = _offset; _offset = offset + valueOffset; return tag({ tag: castBigInt(unsignedInt), value }); } } function decodeSpecial(at, to) { const minor = payload[at] & 0b0001_1111; switch (minor) { case specialTrue: case specialFalse: _offset = 1; return minor === specialTrue; case specialNull: _offset = 1; return null; case specialUndefined: _offset = 1; return null; case extendedFloat16: if (to - at < 3) { throw new Error("incomplete float16 at end of buf."); } _offset = 3; return bytesToFloat16(payload[at + 1], payload[at + 2]); case extendedFloat32: if (to - at < 5) { throw new Error("incomplete float32 at end of buf."); } _offset = 5; return dataView$1.getFloat32(at + 1); case extendedFloat64: if (to - at < 9) { throw new Error("incomplete float64 at end of buf."); } _offset = 9; return dataView$1.getFloat64(at + 1); default: unexpectedMinor(minor); } } function decodeCount(at, to) { const minor = payload[at] & 0b0001_1111; if (minor < 24) { _offset = 1; return minor; } switch (minor) { case extendedOneByte: if (to - at < 2) { overflow(1); } _offset = 2; return payload[at + 1]; case extendedFloat16: if (to - at < 3) { overflow(2); } _offset = 3; return dataView$1.getUint16(at + 1); case extendedFloat32: if (to - at < 5) { overflow(4); } _offset = 5; return dataView$1.getUint32(at + 1); case extendedFloat64: if (to - at < 9) { overflow(8); } _offset = 9; return demote(dataView$1.getBigUint64(at + 1)); default: unexpectedMinor(minor); } } function decodeMapIndefinite(at, to) { at += 1; const base = at; const map = {}; for (; at < to;) { if (payload[at] === 0b1111_1111) { _offset = at - base + 2; return map; } const key = decodeUtf8String(at, to); at += _offset; map[key] = decode(at, to); at += _offset; } throw new Error("expected break marker."); } function decodeListIndefinite(at, to) { at += 1; const list = []; for (const base = at; at < to;) { if (payload[at] === 0b1111_1111) { _offset = at - base + 2; return list; } list.push(decode(at, to)); at += _offset; } throw new Error("expected break marker."); } function decodeUtf8StringIndefinite(at, to) { at += 1; const vector = []; for (const base = at; at < to;) { if (payload[at] === 0b1111_1111) { const data = alloc(vector.length); data.set(vector, 0); _offset = at - base + 2; if (USE_BUFFER$1) { return data.toString("utf-8", 0, data.length); } return textDecoder.decode(data); } const major = (payload[at] & 0b1110_0000) >> 5; const minor = payload[at] & 0b0001_1111; if (major !== majorUtf8String) { unexpectedMajorInIndefiniteString(major); } if (minor === minorIndefinite) { throw new Error("nested indefinite string."); } const bytes = decodeUnstructuredByteString(at, to); const length = _offset; at += length; for (let i = 0; i < bytes.length; ++i) { vector.push(bytes[i]); } } throw new Error("expected break marker."); } function decodeUnstructuredByteStringIndefinite(at, to) { at += 1; const vector = []; for (const base = at; at < to;) { if (payload[at] === 0b1111_1111) { const data = alloc(vector.length); data.set(vector, 0); _offset = at - base + 2; return data; } const major = (payload[at] & 0b1110_0000) >> 5; const minor = payload[at] & 0b0001_1111; if (major !== majorUnstructuredByteString) { unexpectedMajorInIndefiniteString(major); } if (minor === minorIndefinite) { throw new Error("nested indefinite string."); } const bytes = decodeUnstructuredByteString(at, to); const length = _offset; at += length; for (let i = 0; i < bytes.length; ++i) { vector.push(bytes[i]); } } throw new Error("expected break marker."); } function castBigInt(bigInt) { if (typeof bigInt === "number") { return bigInt; } const num = Number(bigInt); if (Number.MIN_SAFE_INTEGER <= num && num <= Number.MAX_SAFE_INTEGER) { return num; } return bigInt; } function demote(bigInteger) { const num = Number(bigInteger); if (num < Number.MIN_SAFE_INTEGER || Number.MAX_SAFE_INTEGER < num) { console.warn(new Error(`@smithy/core/cbor - truncating BigInt(${bigInteger}) to ${num} with loss of precision.`)); } return num; } function overflow(n) { throw new Error(`length ${n} greater than remaining buf len.`); } function unexpectedMinor(minor) { throw new Error(`unexpected minor value ${minor}.`); } function unexpectedMajorInIndefiniteString(major) { throw new Error(`unexpected major type ${major} in indefinite string.`); } const USE_BUFFER = typeof Buffer !== "undefined"; const encodeStringCache = new Map(); let encodeCacheEpoch = 0; let encodeCacheSaturated = false; const initialSize = 2048; let data = alloc(initialSize); let dataView = new DataView(data.buffer, data.byteOffset, data.byteLength); let cursor = 0; function encode(_input) { const encodeStack = [_input]; while (encodeStack.length) { const input = encodeStack.pop(); if (typeof input === "string") { const len = input.length; if (USE_BUFFER) { ensureSpace(len * 3 + 9); if (len > 23) { encodeHeader(majorUtf8String, Buffer.byteLength(input)); cursor += data.write(input, cursor); } else { encodeStringCached(input); } } else { const maxBytes = len * 3; ensureSpace(maxBytes + 9); const headerPos = cursor; const result = new TextEncoder().encodeInto(input, data.subarray(cursor + 9)); const byteLen = result.written; let headerSize; if (byteLen < 24) { headerSize = 1; } else if (byteLen < 256) { headerSize = 2; } else if (byteLen < 65536) { headerSize = 3; } else if (byteLen < 4294967296) { headerSize = 5; } else { headerSize = 9; } if (headerSize < 9) { data.copyWithin(headerPos + headerSize, headerPos + 9, headerPos + 9 + byteLen); } cursor = headerPos; encodeInteger(majorUtf8String, byteLen); cursor += byteLen; } continue; } if (data.byteLength - cursor < 9) { ensureSpace(64); } if (typeof input === "number") { if (Number.isInteger(input)) { const nonNegative = input >= 0; const major = nonNegative ? majorUint64 : majorNegativeInt64; const value = nonNegative ? input : -input - 1; if (value < 24) { data[cursor++] = (major << 5) | value; } else if (value < 256) { data[cursor++] = (major << 5) | 24; data[cursor++] = value; } else if (value < 65536) { data[cursor++] = (major << 5) | extendedFloat16; data[cursor++] = value >> 8; data[cursor++] = value & 0xff; } else if (value < 4294967296) { data[cursor++] = (major << 5) | extendedFloat32; dataView.setUint32(cursor, value); cursor += 4; } else { data[cursor++] = (major << 5) | extendedFloat64; const hi = (value / 4294967296) | 0; const lo = (value - hi * 4294967296) | 0; dataView.setUint32(cursor, hi); dataView.setUint32(cursor + 4, lo); cursor += 8; } continue; } data[cursor++] = (majorSpecial << 5) | extendedFloat64; dataView.setFloat64(cursor, input); cursor += 8; continue; } else if (typeof input === "bigint") { const nonNegative = input >= 0; const major = nonNegative ? majorUint64 : majorNegativeInt64; const value = nonNegative ? input : -input - BigInt(1); if (value < BigInt("18446744073709551616")) { const n = Number(value); if (n < 4294967296) { encodeInteger(major, n); } else { data[cursor++] = (major << 5) | extendedFloat64; dataView.setBigUint64(cursor, value); cursor += 8; } } else { const binaryBigInt = value.toString(2); const bigIntBytes = new Uint8Array(Math.ceil(binaryBigInt.length / 8)); let b = value; let i = 0; while (bigIntBytes.byteLength - ++i >= 0) { bigIntBytes[bigIntBytes.byteLength - i] = Number(b & BigInt(255)); b >>= BigInt(8); } ensureSpace(bigIntBytes.byteLength * 2 + 16); data[cursor++] = nonNegative ? 0b110_00010 : 0b110_00011; encodeHeader(majorUnstructuredByteString, bigIntBytes.byteLength); data.set(bigIntBytes, cursor); cursor += bigIntBytes.byteLength; } continue; } else if (input === null) { data[cursor++] = (majorSpecial << 5) | specialNull; continue; } else if (typeof input === "boolean") { data[cursor++] = (majorSpecial << 5) | (input ? specialTrue : specialFalse); continue; } else if (typeof input === "undefined") { throw new Error("@smithy/core/cbor: client may not serialize undefined value."); } else if (Array.isArray(input)) { encodeInteger(majorList, input.length); ensureSpace(input.length * 9 + 64); for (let i = input.length - 1; i >= 0; --i) { encodeStack.push(input[i]); } continue; } else if (typeof input.byteLength === "number") { ensureSpace(input.length * 2 + 9); encodeInteger(majorUnstructuredByteString, input.length); data.set(input, cursor); cursor += input.byteLength; continue; } else if (typeof input === "object") { if (input instanceof NumericValue) { const decimalIndex = input.string.indexOf("."); const exponent = decimalIndex === -1 ? 0 : decimalIndex - input.string.length + 1; const mantissa = BigInt(input.string.replace(".", "")); data[cursor++] = 0b110_00100; encodeInteger(majorList, 2); encodeStack.push(mantissa); encodeStack.push(exponent); continue; } if (input[tagSymbol]) { if ("tag" in input && "value" in input) { encodeStack.push(input.value); encodeHeader(majorTag, input.tag); continue; } else { throw new Error("tag encountered with missing fields, need 'tag' and 'value', found: " + JSON.stringify(input)); } } const keys = Object.keys(input); const len = keys.length; encodeInteger(majorMap, len); for (let i = len - 1; i >= 0; --i) { encodeStack.push(input[keys[i]]); encodeStack.push(keys[i]); } continue; } throw new Error(`data type ${input?.constructor?.name ?? typeof input} not compatible for encoding.`); } } function advanceEncodingEpoch() { encodeCacheEpoch = (encodeCacheEpoch + 1) & 0b1111_1111_1111_1111; encodeCacheSaturated = false; } function toUint8Array() { const out = alloc(cursor); out.set(data.subarray(0, cursor), 0); cursor = 0; return out; } function resize(size) { const old = data; data = alloc(size); if (old) { if (old.copy) { old.copy(data, 0, 0, old.byteLength); } else { data.set(old, 0); } } dataView = new DataView(data.buffer, data.byteOffset, data.byteLength); } function encodeStringCached(input) { const cached = encodeStringCache.get(input); if (cached !== undefined) { data.set(cached.bytes, cursor); cursor += cached.bytes.length; cached.epoch = encodeCacheEpoch; return; } const start = cursor; const byteLen = Buffer.byteLength(input); encodeInteger(majorUtf8String, byteLen); cursor += data.write(input, cursor); const bytes = Uint8Array.prototype.slice.call(data, start, cursor); if (encodeStringCache.size >= 2048) { if (encodeCacheSaturated) { return; } let evicted = 0; for (const [key, entry] of encodeStringCache) { if (evicted >= 1024) { break; } if (entry.epoch !== encodeCacheEpoch) { encodeStringCache.delete(key); evicted++; } } if (evicted === 0) { encodeCacheSaturated = true; return; } } if (encodeStringCache.size < 2048) { encodeStringCache.set(input, { epoch: encodeCacheEpoch, bytes }); } } function ensureSpace(bytes) { const remaining = data.byteLength - cursor; if (remaining < bytes) { if (cursor < 16_000_000) { resize(Math.max(data.byteLength * 4, data.byteLength + bytes)); } else { resize(data.byteLength + bytes + 16_000_000); } } } function encodeHeader(major, value) { if (value < 24) { data[cursor++] = (major << 5) | value; } else if (value < 256) { data[cursor++] = (major << 5) | 24; data[cursor++] = value; } else if (value < 65536) { data[cursor++] = (major << 5) | extendedFloat16; dataView.setUint16(cursor, value); cursor += 2; } else if (value < 4294967296) { data[cursor++] = (major << 5) | extendedFloat32; dataView.setUint32(cursor, value); cursor += 4; } else { data[cursor++] = (major << 5) | extendedFloat64; dataView.setBigUint64(cursor, typeof value === "bigint" ? value : BigInt(value)); cursor += 8; } } function encodeInteger(major, value) { if (value < 24) { data[cursor++] = (major << 5) | value; } else if (value < 256) { data[cursor++] = (major << 5) | 24; data[cursor++] = value; } else if (value < 65536) { data[cursor++] = (major << 5) | extendedFloat16; data[cursor++] = value >> 8; data[cursor++] = value & 0xff; } else if (value < 4294967296) { data[cursor++] = (major << 5) | extendedFloat32; dataView.setUint32(cursor, value); cursor += 4; } else { data[cursor++] = (major << 5) | extendedFloat64; const hi = (value / 4294967296) | 0; const lo = (value - hi * 4294967296) | 0; dataView.setUint32(cursor, hi); dataView.setUint32(cursor + 4, lo); cursor += 8; } } const cbor = { deserialize(payload) { advanceDecodingEpoch(); setPayload(payload); return decode(0, payload.length); }, serialize(input) { advanceEncodingEpoch(); try { encode(input); return toUint8Array(); } catch (e) { toUint8Array(); throw e; } }, resizeEncodingBuffer(size) { resize(size); }, }; const parseCborBody = (streamBody, context) => { return collectBody(streamBody, context).then(async (bytes) => { if (bytes.length) { try { return cbor.deserialize(bytes); } catch (e) { Object.defineProperty(e, "$responseBodyText", { value: context.utf8Encoder(bytes), }); throw e; } } return {}; }); }; const dateToTag = (date) => { return tag({ tag: 1, value: date.getTime() / 1000, }); }; const parseCborErrorBody = async (errorBody, context) => { const value = await parseCborBody(errorBody, context); value.message = value.message ?? value.Message; return value; }; const loadSmithyRpcV2CborErrorCode = (output, data) => { const sanitizeErrorCode = (rawValue) => { let cleanValue = rawValue; if (typeof cleanValue === "number") { cleanValue = cleanValue.toString(); } if (cleanValue.indexOf(",") >= 0) { cleanValue = cleanValue.split(",")[0]; } if (cleanValue.indexOf(":") >= 0) { cleanValue = cleanValue.split(":")[0]; } if (cleanValue.indexOf("#") >= 0) { cleanValue = cleanValue.split("#")[1]; } return cleanValue; }; if (data["__type"] !== undefined) { return sanitizeErrorCode(data["__type"]); } let codeKey; for (const key in data) { if (key.toLowerCase() === "code") { codeKey = key; break; } } if (codeKey && data[codeKey] !== undefined) { return sanitizeErrorCode(data[codeKey]); } }; const checkCborResponse = (response) => { if (String(response.headers["smithy-protocol"]).toLowerCase() !== "rpc-v2-cbor") { throw new Error("Malformed RPCv2 CBOR response, status: " + response.statusCode); } }; const buildHttpRpcRequest = async (context, headers, path, resolvedHostname, body) => { const endpoint = await context.endpoint(); const { hostname, protocol = "https", port, path: basePath } = endpoint; const contents = { protocol, hostname, port, method: "POST", path: basePath.endsWith("/") ? basePath.slice(0, -1) + path : basePath + path, headers: { ...headers, }, }; if (resolvedHostname !== undefined) { contents.hostname = resolvedHostname; } if (endpoint.headers) { for (const name in endpoint.headers) { contents.headers[name] = endpoint.headers[name]; } } if (body !== undefined) { contents.body = body; try { contents.headers["content-length"] = String(calculateBodyLength(body)); } catch (e) { } } return new HttpRequest(contents); }; class CborCodec extends SerdeContext { createSerializer() { const serializer = new CborShapeSerializer(); serializer.setSerdeContext(this.serdeContext); return serializer; } createDeserializer() { const deserializer = new CborShapeDeserializer(); deserializer.setSerdeContext(this.serdeContext); return deserializer; } } class CborShapeSerializer extends SerdeContext { value; write(schema, value) { this.value = this.serialize(schema, value); } serialize(schema, source) { const ns = NormalizedSchema.of(schema); if (source == null) { if (ns.isIdempotencyToken()) { return generateIdempotencyToken(); } return source; } if (ns.isBlobSchema()) { if (typeof source === "string") { return (this.serdeContext?.base64Decoder ?? fromBase64)(source); } return source; } if (ns.isTimestampSchema()) { if (typeof source === "number" || typeof source === "bigint") { return dateToTag(new Date((Number(source) / 1000) | 0)); } return dateToTag(source); } if (typeof source === "function" || typeof source === "object") { const sourceObject = source; if (ns.isListSchema() && Array.isArray(sourceObject)) { const sparse = !!ns.getMergedTraits().sparse; const newArray = []; let i = 0; for (const item of sourceObject) { const value = this.serialize(ns.getValueSchema(), item); if (value != null || sparse) { newArray[i++] = value; } } return newArray; } if (sourceObject instanceof Date) { return dateToTag(sourceObject); } const newObject = {}; if (ns.isMapSchema()) { const sparse = !!ns.getMergedTraits().sparse; for (const key in sourceObject) { const value = this.serialize(ns.getValueSchema(), sourceObject[key]); if (value != null || sparse) { newObject[key] = value; } } } else if (ns.isStructSchema()) { for (const [key, memberSchema] of ns.structIterator()) { const value = this.serialize(memberSchema, sourceObject[key]); if (value != null) { newObject[key] = value; } } const isUnion = ns.isUnionSchema(); if (isUnion && Array.isArray(sourceObject.$unknown)) { const [k, v] = sourceObject.$unknown; newObject[k] = v; } else if (typeof sourceObject.__type === "string") { for (const k in sourceObject) { if (!(k in newObject)) { newObject[k] = this.serialize(15, sourceObject[k]); } } } } else if (ns.isDocumentSchema()) { for (const key in sourceObject) { newObject[key] = this.serialize(ns.getValueSchema(), sourceObject[key]); } } else if (ns.isBigDecimalSchema()) { return sourceObject; } return newObject; } return source; } flush() { const buffer = cbor.serialize(this.value); this.value = undefined; return buffer; } } class CborShapeDeserializer extends SerdeContext { read(schema, bytes) { const data = cbor.deserialize(bytes); return this.readValue(schema, data); } readValue(_schema, value) { const ns = NormalizedSchema.of(_schema); if (ns.isTimestampSchema()) { if (typeof value === "number") { return _parseEpochTimestamp(value); } if (typeof value === "object") { if (value.tag === 1 && "value" in value) { return _parseEpochTimestamp(value.value); } } } if (ns.isBlobSchema()) { if (typeof value === "string") { return (this.serdeContext?.base64Decoder ?? fromBase64)(value); } return value; } if (typeof value === "undefined" || typeof value === "boolean" || typeof value === "number" || typeof value === "string" || typeof value === "bigint" || typeof value === "symbol") { return value; } else if (typeof value === "object") { if (value === null) { return null; } if ("byteLength" in value) { return value; } if (value instanceof Date) { return value; } if (ns.isDocumentSchema()) { return value; } if (ns.isListSchema()) { const newArray = []; const memberSchema = ns.getValueSchema(); for (const item of value) { const itemValue = this.readValue(memberSchema, item); newArray.push(itemValue); } return newArray; } const newObject = {}; if (ns.isMapSchema()) { const targetSchema = ns.getValueSchema(); for (const key in value) { const itemValue = this.readValue(targetSchema, value[key]); newObject[key] = itemValue; } } else if (ns.isStructSchema()) { const isUnion = ns.isUnionSchema(); let keys; if (isUnion) { keys = new Set(); for (const k in value) { if (k !== "__type") { keys.add(k); } } } for (const [key, memberSchema] of ns.structIterator()) { if (isUnion) { keys.delete(key); } if (value[key] != null) { newObject[key] = this.readValue(memberSchema, value[key]); } } if (isUnion && keys?.size === 1) { let newObjectEmpty = true; for (const _ in newObject) { newObjectEmpty = false; break; } if (newObjectEmpty) { const k = keys.values().next().value; newObject.$unknown = [k, value[k]]; } } else if (typeof value.__type === "string") { for (const k in value) { if (!(k in newObject)) { newObject[k] = value[k]; } } } } else if (value instanceof NumericValue) { return value; } return newObject; } else { return value; } } } class SmithyRpcV2CborProtocol extends RpcProtocol { codec = new CborCodec(); serializer = this.codec.createSerializer(); deserializer = this.codec.createDeserializer(); constructor({ defaultNamespace, errorTypeRegistries, }) { super({ defaultNamespace, errorTypeRegistries }); } getShapeId() { return "smithy.protocols#rpcv2Cbor"; } getPayloadCodec() { return this.codec; } async serializeRequest(operationSchema, input, context) { const request = await super.serializeRequest(operationSchema, input, context); Object.assign(request.headers, { "content-type": this.getDefaultContentType(), "smithy-protocol": "rpc-v2-cbor", accept: this.getDefaultContentType(), }); if (deref(operationSchema.input) === "unit") { delete request.body; delete request.headers["content-type"]; } else { if (!request.body) { this.serializer.write(15, {}); request.body = this.serializer.flush(); } try { request.headers["content-length"] = String(request.body.byteLength); } catch (e) { } } const { service, operation } = getSmithyContext(context); const path = `/service/${service}/operation/${operation}`; if (request.path.endsWith("/")) { request.path += path.slice(1); } else { request.path += path; } return request; } async deserializeResponse(operationSchema, context, response) { return super.deserializeResponse(operationSchema, context, response); } async handleError(operationSchema, context, response, dataObject, metadata) { const errorName = loadSmithyRpcV2CborErrorCode(response, dataObject) ?? "Unknown"; const errorMetadata = { $metadata: metadata, $fault: response.statusCode <= 500 ? "client" : "server", }; let namespace = this.options.defaultNamespace; if (errorName.includes("#")) { [namespace] = errorName.split("#"); } const registry = this.compositeErrorRegistry; const nsRegistry = TypeRegistry.for(namespace); registry.copyFrom(nsRegistry); let errorSchema; try { errorSchema = registry.getSchema(errorName); } catch (e) { if (dataObject.Message) { dataObject.message = dataObject.Message; } const syntheticRegistry = TypeRegistry.for("smithy.ts.sdk.synthetic." + namespace); registry.copyFrom(syntheticRegistry); const baseExceptionSchema = registry.getBaseException(); if (baseExceptionSchema) { const ErrorCtor = registry.getErrorCtor(baseExceptionSchema); throw Object.assign(new ErrorCtor({ name: errorName }), errorMetadata, dataObject); } throw Object.assign(new Error(errorName), errorMetadata, dataObject); } const ns = NormalizedSchema.of(errorSchema); const ErrorCtor = registry.getErrorCtor(errorSchema); const message = dataObject.message ?? dataObject.Message ?? "Unknown"; const exception = new ErrorCtor({}); const output = {}; for (const [name, member] of ns.structIterator()) { output[name] = this.deserializer.readValue(member, dataObject[name]); } throw Object.assign(exception, errorMetadata, { $fault: ns.getMergedTraits().error, message, }, output); } getDefaultContentType() { return "application/cbor"; } } exports.CborCodec = CborCodec; exports.CborShapeDeserializer = CborShapeDeserializer; exports.CborShapeSerializer = CborShapeSerializer; exports.SmithyRpcV2CborProtocol = SmithyRpcV2CborProtocol; exports.buildHttpRpcRequest = buildHttpRpcRequest; exports.cbor = cbor; exports.checkCborResponse = checkCborResponse; exports.dateToTag = dateToTag; exports.loadSmithyRpcV2CborErrorCode = loadSmithyRpcV2CborErrorCode; exports.parseCborBody = parseCborBody; exports.parseCborErrorBody = parseCborErrorBody; exports.tag = tag; exports.tagSymbol = tagSymbol;