lambda-live-debugger
Version:
Debug Lambda functions locally like it is running in the cloud
190 lines (189 loc) • 7.66 kB
JavaScript
import { determineTimestampFormat, extendedEncodeURIComponent } from "@smithy/core/protocols";
import { NormalizedSchema } from "@smithy/core/schema";
import { generateIdempotencyToken, NumericValue } from "@smithy/core/serde";
import { dateToUtcString } from "@smithy/smithy-client";
import { toBase64 } from "@smithy/util-base64";
import { SerdeContextConfig } from "../ConfigurableSerdeContext";
export class QueryShapeSerializer extends SerdeContextConfig {
settings;
buffer;
constructor(settings) {
super();
this.settings = settings;
}
write(schema, value, prefix = "") {
if (this.buffer === undefined) {
this.buffer = "";
}
const ns = NormalizedSchema.of(schema);
if (prefix && !prefix.endsWith(".")) {
prefix += ".";
}
if (ns.isBlobSchema()) {
if (typeof value === "string" || value instanceof Uint8Array) {
this.writeKey(prefix);
this.writeValue((this.serdeContext?.base64Encoder ?? toBase64)(value));
}
}
else if (ns.isBooleanSchema() || ns.isNumericSchema() || ns.isStringSchema()) {
if (value != null) {
this.writeKey(prefix);
this.writeValue(String(value));
}
else if (ns.isIdempotencyToken()) {
this.writeKey(prefix);
this.writeValue(generateIdempotencyToken());
}
}
else if (ns.isBigIntegerSchema()) {
if (value != null) {
this.writeKey(prefix);
this.writeValue(String(value));
}
}
else if (ns.isBigDecimalSchema()) {
if (value != null) {
this.writeKey(prefix);
this.writeValue(value instanceof NumericValue ? value.string : String(value));
}
}
else if (ns.isTimestampSchema()) {
if (value instanceof Date) {
this.writeKey(prefix);
const format = determineTimestampFormat(ns, this.settings);
switch (format) {
case 5:
this.writeValue(value.toISOString().replace(".000Z", "Z"));
break;
case 6:
this.writeValue(dateToUtcString(value));
break;
case 7:
this.writeValue(String(value.getTime() / 1000));
break;
}
}
}
else if (ns.isDocumentSchema()) {
if (Array.isArray(value)) {
this.write(64 | 15, value, prefix);
}
else if (value instanceof Date) {
this.write(4, value, prefix);
}
else if (value instanceof Uint8Array) {
this.write(21, value, prefix);
}
else if (value && typeof value === "object") {
this.write(128 | 15, value, prefix);
}
else {
this.writeKey(prefix);
this.writeValue(String(value));
}
}
else if (ns.isListSchema()) {
if (Array.isArray(value)) {
if (value.length === 0) {
if (this.settings.serializeEmptyLists) {
this.writeKey(prefix);
this.writeValue("");
}
}
else {
const member = ns.getValueSchema();
const flat = this.settings.flattenLists || ns.getMergedTraits().xmlFlattened;
let i = 1;
for (const item of value) {
if (item == null) {
continue;
}
const traits = member.getMergedTraits();
const suffix = this.getKey("member", traits.xmlName, traits.ec2QueryName);
const key = flat ? `${prefix}${i}` : `${prefix}${suffix}.${i}`;
this.write(member, item, key);
++i;
}
}
}
}
else if (ns.isMapSchema()) {
if (value && typeof value === "object") {
const keySchema = ns.getKeySchema();
const memberSchema = ns.getValueSchema();
const flat = ns.getMergedTraits().xmlFlattened;
let i = 1;
for (const [k, v] of Object.entries(value)) {
if (v == null) {
continue;
}
const keyTraits = keySchema.getMergedTraits();
const keySuffix = this.getKey("key", keyTraits.xmlName, keyTraits.ec2QueryName);
const key = flat ? `${prefix}${i}.${keySuffix}` : `${prefix}entry.${i}.${keySuffix}`;
const valTraits = memberSchema.getMergedTraits();
const valueSuffix = this.getKey("value", valTraits.xmlName, valTraits.ec2QueryName);
const valueKey = flat ? `${prefix}${i}.${valueSuffix}` : `${prefix}entry.${i}.${valueSuffix}`;
this.write(keySchema, k, key);
this.write(memberSchema, v, valueKey);
++i;
}
}
}
else if (ns.isStructSchema()) {
if (value && typeof value === "object") {
let didWriteMember = false;
for (const [memberName, member] of ns.structIterator()) {
if (value[memberName] == null && !member.isIdempotencyToken()) {
continue;
}
const traits = member.getMergedTraits();
const suffix = this.getKey(memberName, traits.xmlName, traits.ec2QueryName, "struct");
const key = `${prefix}${suffix}`;
this.write(member, value[memberName], key);
didWriteMember = true;
}
if (!didWriteMember && ns.isUnionSchema()) {
const { $unknown } = value;
if (Array.isArray($unknown)) {
const [k, v] = $unknown;
const key = `${prefix}${k}`;
this.write(15, v, key);
}
}
}
}
else if (ns.isUnitSchema()) {
}
else {
throw new Error(`-sdk/core/protocols - QuerySerializer unrecognized schema type ${ns.getName(true)}`);
}
}
flush() {
if (this.buffer === undefined) {
throw new Error("@aws-sdk/core/protocols - QuerySerializer cannot flush with nothing written to buffer.");
}
const str = this.buffer;
delete this.buffer;
return str;
}
getKey(memberName, xmlName, ec2QueryName, keySource) {
const { ec2, capitalizeKeys } = this.settings;
if (ec2 && ec2QueryName) {
return ec2QueryName;
}
const key = xmlName ?? memberName;
if (capitalizeKeys && keySource === "struct") {
return key[0].toUpperCase() + key.slice(1);
}
return key;
}
writeKey(key) {
if (key.endsWith(".")) {
key = key.slice(0, key.length - 1);
}
this.buffer += `&${extendedEncodeURIComponent(key)}=`;
}
writeValue(value) {
this.buffer += extendedEncodeURIComponent(value);
}
}