lambda-live-debugger
Version:
Debug Lambda functions locally like it is running in the cloud
1,307 lines (1,286 loc) • 73.1 kB
JavaScript
'use strict';
var cbor = require('@smithy/core/cbor');
var schema = require('@smithy/core/schema');
var smithyClient = require('@smithy/smithy-client');
var protocols = require('@smithy/core/protocols');
var serde = require('@smithy/core/serde');
var utilBase64 = require('@smithy/util-base64');
var utilUtf8 = require('@smithy/util-utf8');
var xmlBuilder = require('@aws-sdk/xml-builder');
class ProtocolLib {
queryCompat;
constructor(queryCompat = false) {
this.queryCompat = queryCompat;
}
resolveRestContentType(defaultContentType, inputSchema) {
const members = inputSchema.getMemberSchemas();
const httpPayloadMember = Object.values(members).find((m) => {
return !!m.getMergedTraits().httpPayload;
});
if (httpPayloadMember) {
const mediaType = httpPayloadMember.getMergedTraits().mediaType;
if (mediaType) {
return mediaType;
}
else if (httpPayloadMember.isStringSchema()) {
return "text/plain";
}
else if (httpPayloadMember.isBlobSchema()) {
return "application/octet-stream";
}
else {
return defaultContentType;
}
}
else if (!inputSchema.isUnitSchema()) {
const hasBody = Object.values(members).find((m) => {
const { httpQuery, httpQueryParams, httpHeader, httpLabel, httpPrefixHeaders } = m.getMergedTraits();
const noPrefixHeaders = httpPrefixHeaders === void 0;
return !httpQuery && !httpQueryParams && !httpHeader && !httpLabel && noPrefixHeaders;
});
if (hasBody) {
return defaultContentType;
}
}
}
async getErrorSchemaOrThrowBaseException(errorIdentifier, defaultNamespace, response, dataObject, metadata, getErrorSchema) {
let namespace = defaultNamespace;
let errorName = errorIdentifier;
if (errorIdentifier.includes("#")) {
[namespace, errorName] = errorIdentifier.split("#");
}
const errorMetadata = {
$metadata: metadata,
$fault: response.statusCode < 500 ? "client" : "server",
};
const registry = schema.TypeRegistry.for(namespace);
try {
const errorSchema = getErrorSchema?.(registry, errorName) ?? registry.getSchema(errorIdentifier);
return { errorSchema, errorMetadata };
}
catch (e) {
dataObject.message = dataObject.message ?? dataObject.Message ?? "UnknownError";
const synthetic = schema.TypeRegistry.for("smithy.ts.sdk.synthetic." + namespace);
const baseExceptionSchema = synthetic.getBaseException();
if (baseExceptionSchema) {
const ErrorCtor = synthetic.getErrorCtor(baseExceptionSchema) ?? Error;
throw this.decorateServiceException(Object.assign(new ErrorCtor({ name: errorName }), errorMetadata), dataObject);
}
throw this.decorateServiceException(Object.assign(new Error(errorName), errorMetadata), dataObject);
}
}
decorateServiceException(exception, additions = {}) {
if (this.queryCompat) {
const msg = exception.Message ?? additions.Message;
const error = smithyClient.decorateServiceException(exception, additions);
if (msg) {
error.message = msg;
}
error.Error = {
...error.Error,
Type: error.Error?.Type,
Code: error.Error?.Code,
Message: error.Error?.message ?? error.Error?.Message ?? msg,
};
const reqId = error.$metadata.requestId;
if (reqId) {
error.RequestId = reqId;
}
return error;
}
return smithyClient.decorateServiceException(exception, additions);
}
setQueryCompatError(output, response) {
const queryErrorHeader = response.headers?.["x-amzn-query-error"];
if (output !== undefined && queryErrorHeader != null) {
const [Code, Type] = queryErrorHeader.split(";");
const entries = Object.entries(output);
const Error = {
Code,
Type,
};
Object.assign(output, Error);
for (const [k, v] of entries) {
Error[k === "message" ? "Message" : k] = v;
}
delete Error.__type;
output.Error = Error;
}
}
queryCompatOutput(queryCompatErrorData, errorData) {
if (queryCompatErrorData.Error) {
errorData.Error = queryCompatErrorData.Error;
}
if (queryCompatErrorData.Type) {
errorData.Type = queryCompatErrorData.Type;
}
if (queryCompatErrorData.Code) {
errorData.Code = queryCompatErrorData.Code;
}
}
findQueryCompatibleError(registry, errorName) {
try {
return registry.getSchema(errorName);
}
catch (e) {
return registry.find((schema$1) => schema.NormalizedSchema.of(schema$1).getMergedTraits().awsQueryError?.[0] === errorName);
}
}
}
class AwsSmithyRpcV2CborProtocol extends cbor.SmithyRpcV2CborProtocol {
awsQueryCompatible;
mixin;
constructor({ defaultNamespace, awsQueryCompatible, }) {
super({ defaultNamespace });
this.awsQueryCompatible = !!awsQueryCompatible;
this.mixin = new ProtocolLib(this.awsQueryCompatible);
}
async serializeRequest(operationSchema, input, context) {
const request = await super.serializeRequest(operationSchema, input, context);
if (this.awsQueryCompatible) {
request.headers["x-amzn-query-mode"] = "true";
}
return request;
}
async handleError(operationSchema, context, response, dataObject, metadata) {
if (this.awsQueryCompatible) {
this.mixin.setQueryCompatError(dataObject, response);
}
const errorName = (() => {
const compatHeader = response.headers["x-amzn-query-error"];
if (compatHeader && this.awsQueryCompatible) {
return compatHeader.split(";")[0];
}
return cbor.loadSmithyRpcV2CborErrorCode(response, dataObject) ?? "Unknown";
})();
const { errorSchema, errorMetadata } = await this.mixin.getErrorSchemaOrThrowBaseException(errorName, this.options.defaultNamespace, response, dataObject, metadata, this.awsQueryCompatible ? this.mixin.findQueryCompatibleError : undefined);
const ns = schema.NormalizedSchema.of(errorSchema);
const message = dataObject.message ?? dataObject.Message ?? "Unknown";
const ErrorCtor = schema.TypeRegistry.for(errorSchema[1]).getErrorCtor(errorSchema) ?? Error;
const exception = new ErrorCtor(message);
const output = {};
for (const [name, member] of ns.structIterator()) {
if (dataObject[name] != null) {
output[name] = this.deserializer.readValue(member, dataObject[name]);
}
}
if (this.awsQueryCompatible) {
this.mixin.queryCompatOutput(dataObject, output);
}
throw this.mixin.decorateServiceException(Object.assign(exception, errorMetadata, {
$fault: ns.getMergedTraits().error,
message,
}, output), dataObject);
}
}
const _toStr = (val) => {
if (val == null) {
return val;
}
if (typeof val === "number" || typeof val === "bigint") {
const warning = new Error(`Received number ${val} where a string was expected.`);
warning.name = "Warning";
console.warn(warning);
return String(val);
}
if (typeof val === "boolean") {
const warning = new Error(`Received boolean ${val} where a string was expected.`);
warning.name = "Warning";
console.warn(warning);
return String(val);
}
return val;
};
const _toBool = (val) => {
if (val == null) {
return val;
}
if (typeof val === "string") {
const lowercase = val.toLowerCase();
if (val !== "" && lowercase !== "false" && lowercase !== "true") {
const warning = new Error(`Received string "${val}" where a boolean was expected.`);
warning.name = "Warning";
console.warn(warning);
}
return val !== "" && lowercase !== "false";
}
return val;
};
const _toNum = (val) => {
if (val == null) {
return val;
}
if (typeof val === "string") {
const num = Number(val);
if (num.toString() !== val) {
const warning = new Error(`Received string "${val}" where a number was expected.`);
warning.name = "Warning";
console.warn(warning);
return val;
}
return num;
}
return val;
};
class SerdeContextConfig {
serdeContext;
setSerdeContext(serdeContext) {
this.serdeContext = serdeContext;
}
}
class UnionSerde {
from;
to;
keys;
constructor(from, to) {
this.from = from;
this.to = to;
this.keys = new Set(Object.keys(this.from).filter((k) => k !== "__type"));
}
mark(key) {
this.keys.delete(key);
}
hasUnknown() {
return this.keys.size === 1 && Object.keys(this.to).length === 0;
}
writeUnknown() {
if (this.hasUnknown()) {
const k = this.keys.values().next().value;
const v = this.from[k];
this.to.$unknown = [k, v];
}
}
}
function jsonReviver(key, value, context) {
if (context?.source) {
const numericString = context.source;
if (typeof value === "number") {
if (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER || numericString !== String(value)) {
const isFractional = numericString.includes(".");
if (isFractional) {
return new serde.NumericValue(numericString, "bigDecimal");
}
else {
return BigInt(numericString);
}
}
}
}
return value;
}
const collectBodyString = (streamBody, context) => smithyClient.collectBody(streamBody, context).then((body) => (context?.utf8Encoder ?? utilUtf8.toUtf8)(body));
const parseJsonBody = (streamBody, context) => collectBodyString(streamBody, context).then((encoded) => {
if (encoded.length) {
try {
return JSON.parse(encoded);
}
catch (e) {
if (e?.name === "SyntaxError") {
Object.defineProperty(e, "$responseBodyText", {
value: encoded,
});
}
throw e;
}
}
return {};
});
const parseJsonErrorBody = async (errorBody, context) => {
const value = await parseJsonBody(errorBody, context);
value.message = value.message ?? value.Message;
return value;
};
const loadRestJsonErrorCode = (output, data) => {
const findKey = (object, key) => Object.keys(object).find((k) => k.toLowerCase() === key.toLowerCase());
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;
};
const headerKey = findKey(output.headers, "x-amzn-errortype");
if (headerKey !== undefined) {
return sanitizeErrorCode(output.headers[headerKey]);
}
if (data && typeof data === "object") {
const codeKey = findKey(data, "code");
if (codeKey && data[codeKey] !== undefined) {
return sanitizeErrorCode(data[codeKey]);
}
if (data["__type"] !== undefined) {
return sanitizeErrorCode(data["__type"]);
}
}
};
class JsonShapeDeserializer extends SerdeContextConfig {
settings;
constructor(settings) {
super();
this.settings = settings;
}
async read(schema, data) {
return this._read(schema, typeof data === "string" ? JSON.parse(data, jsonReviver) : await parseJsonBody(data, this.serdeContext));
}
readObject(schema, data) {
return this._read(schema, data);
}
_read(schema$1, value) {
const isObject = value !== null && typeof value === "object";
const ns = schema.NormalizedSchema.of(schema$1);
if (isObject) {
if (ns.isStructSchema()) {
const record = value;
const union = ns.isUnionSchema();
const out = {};
let nameMap = void 0;
const { jsonName } = this.settings;
if (jsonName) {
nameMap = {};
}
let unionSerde;
if (union) {
unionSerde = new UnionSerde(record, out);
}
for (const [memberName, memberSchema] of ns.structIterator()) {
let fromKey = memberName;
if (jsonName) {
fromKey = memberSchema.getMergedTraits().jsonName ?? fromKey;
nameMap[fromKey] = memberName;
}
if (union) {
unionSerde.mark(fromKey);
}
if (record[fromKey] != null) {
out[memberName] = this._read(memberSchema, record[fromKey]);
}
}
if (union) {
unionSerde.writeUnknown();
}
else if (typeof record.__type === "string") {
for (const [k, v] of Object.entries(record)) {
const t = jsonName ? nameMap[k] ?? k : k;
if (!(t in out)) {
out[t] = v;
}
}
}
return out;
}
if (Array.isArray(value) && ns.isListSchema()) {
const listMember = ns.getValueSchema();
const out = [];
for (const item of value) {
out.push(this._read(listMember, item));
}
return out;
}
if (ns.isMapSchema()) {
const mapMember = ns.getValueSchema();
const out = {};
for (const [_k, _v] of Object.entries(value)) {
out[_k] = this._read(mapMember, _v);
}
return out;
}
}
if (ns.isBlobSchema() && typeof value === "string") {
return utilBase64.fromBase64(value);
}
const mediaType = ns.getMergedTraits().mediaType;
if (ns.isStringSchema() && typeof value === "string" && mediaType) {
const isJson = mediaType === "application/json" || mediaType.endsWith("+json");
if (isJson) {
return serde.LazyJsonString.from(value);
}
return value;
}
if (ns.isTimestampSchema() && value != null) {
const format = protocols.determineTimestampFormat(ns, this.settings);
switch (format) {
case 5:
return serde.parseRfc3339DateTimeWithOffset(value);
case 6:
return serde.parseRfc7231DateTime(value);
case 7:
return serde.parseEpochTimestamp(value);
default:
console.warn("Missing timestamp format, parsing value with Date constructor:", value);
return new Date(value);
}
}
if (ns.isBigIntegerSchema() && (typeof value === "number" || typeof value === "string")) {
return BigInt(value);
}
if (ns.isBigDecimalSchema() && value != undefined) {
if (value instanceof serde.NumericValue) {
return value;
}
const untyped = value;
if (untyped.type === "bigDecimal" && "string" in untyped) {
return new serde.NumericValue(untyped.string, untyped.type);
}
return new serde.NumericValue(String(value), "bigDecimal");
}
if (ns.isNumericSchema() && typeof value === "string") {
switch (value) {
case "Infinity":
return Infinity;
case "-Infinity":
return -Infinity;
case "NaN":
return NaN;
}
return value;
}
if (ns.isDocumentSchema()) {
if (isObject) {
const out = Array.isArray(value) ? [] : {};
for (const [k, v] of Object.entries(value)) {
if (v instanceof serde.NumericValue) {
out[k] = v;
}
else {
out[k] = this._read(ns, v);
}
}
return out;
}
else {
return structuredClone(value);
}
}
return value;
}
}
const NUMERIC_CONTROL_CHAR = String.fromCharCode(925);
class JsonReplacer {
values = new Map();
counter = 0;
stage = 0;
createReplacer() {
if (this.stage === 1) {
throw new Error("@aws-sdk/core/protocols - JsonReplacer already created.");
}
if (this.stage === 2) {
throw new Error("@aws-sdk/core/protocols - JsonReplacer exhausted.");
}
this.stage = 1;
return (key, value) => {
if (value instanceof serde.NumericValue) {
const v = `${NUMERIC_CONTROL_CHAR + "nv" + this.counter++}_` + value.string;
this.values.set(`"${v}"`, value.string);
return v;
}
if (typeof value === "bigint") {
const s = value.toString();
const v = `${NUMERIC_CONTROL_CHAR + "b" + this.counter++}_` + s;
this.values.set(`"${v}"`, s);
return v;
}
return value;
};
}
replaceInJson(json) {
if (this.stage === 0) {
throw new Error("@aws-sdk/core/protocols - JsonReplacer not created yet.");
}
if (this.stage === 2) {
throw new Error("@aws-sdk/core/protocols - JsonReplacer exhausted.");
}
this.stage = 2;
if (this.counter === 0) {
return json;
}
for (const [key, value] of this.values) {
json = json.replace(key, value);
}
return json;
}
}
class JsonShapeSerializer extends SerdeContextConfig {
settings;
buffer;
useReplacer = false;
rootSchema;
constructor(settings) {
super();
this.settings = settings;
}
write(schema$1, value) {
this.rootSchema = schema.NormalizedSchema.of(schema$1);
this.buffer = this._write(this.rootSchema, value);
}
writeDiscriminatedDocument(schema$1, value) {
this.write(schema$1, value);
if (typeof this.buffer === "object") {
this.buffer.__type = schema.NormalizedSchema.of(schema$1).getName(true);
}
}
flush() {
const { rootSchema, useReplacer } = this;
this.rootSchema = undefined;
this.useReplacer = false;
if (rootSchema?.isStructSchema() || rootSchema?.isDocumentSchema()) {
if (!useReplacer) {
return JSON.stringify(this.buffer);
}
const replacer = new JsonReplacer();
return replacer.replaceInJson(JSON.stringify(this.buffer, replacer.createReplacer(), 0));
}
return this.buffer;
}
_write(schema$1, value, container) {
const isObject = value !== null && typeof value === "object";
const ns = schema.NormalizedSchema.of(schema$1);
if (isObject) {
if (ns.isStructSchema()) {
const record = value;
const out = {};
const { jsonName } = this.settings;
let nameMap = void 0;
if (jsonName) {
nameMap = {};
}
for (const [memberName, memberSchema] of ns.structIterator()) {
const serializableValue = this._write(memberSchema, record[memberName], ns);
if (serializableValue !== undefined) {
let targetKey = memberName;
if (jsonName) {
targetKey = memberSchema.getMergedTraits().jsonName ?? memberName;
nameMap[memberName] = targetKey;
}
out[targetKey] = serializableValue;
}
}
if (ns.isUnionSchema() && Object.keys(out).length === 0) {
const { $unknown } = record;
if (Array.isArray($unknown)) {
const [k, v] = $unknown;
out[k] = this._write(15, v);
}
}
else if (typeof record.__type === "string") {
for (const [k, v] of Object.entries(record)) {
const targetKey = jsonName ? nameMap[k] ?? k : k;
if (!(targetKey in out)) {
out[targetKey] = this._write(15, v);
}
}
}
return out;
}
if (Array.isArray(value) && ns.isListSchema()) {
const listMember = ns.getValueSchema();
const out = [];
const sparse = !!ns.getMergedTraits().sparse;
for (const item of value) {
if (sparse || item != null) {
out.push(this._write(listMember, item));
}
}
return out;
}
if (ns.isMapSchema()) {
const mapMember = ns.getValueSchema();
const out = {};
const sparse = !!ns.getMergedTraits().sparse;
for (const [_k, _v] of Object.entries(value)) {
if (sparse || _v != null) {
out[_k] = this._write(mapMember, _v);
}
}
return out;
}
if (value instanceof Uint8Array && (ns.isBlobSchema() || ns.isDocumentSchema())) {
if (ns === this.rootSchema) {
return value;
}
return (this.serdeContext?.base64Encoder ?? utilBase64.toBase64)(value);
}
if (value instanceof Date && (ns.isTimestampSchema() || ns.isDocumentSchema())) {
const format = protocols.determineTimestampFormat(ns, this.settings);
switch (format) {
case 5:
return value.toISOString().replace(".000Z", "Z");
case 6:
return serde.dateToUtcString(value);
case 7:
return value.getTime() / 1000;
default:
console.warn("Missing timestamp format, using epoch seconds", value);
return value.getTime() / 1000;
}
}
if (value instanceof serde.NumericValue) {
this.useReplacer = true;
}
}
if (value === null && container?.isStructSchema()) {
return void 0;
}
if (ns.isStringSchema()) {
if (typeof value === "undefined" && ns.isIdempotencyToken()) {
return serde.generateIdempotencyToken();
}
const mediaType = ns.getMergedTraits().mediaType;
if (value != null && mediaType) {
const isJson = mediaType === "application/json" || mediaType.endsWith("+json");
if (isJson) {
return serde.LazyJsonString.from(value);
}
}
return value;
}
if (typeof value === "number" && ns.isNumericSchema()) {
if (Math.abs(value) === Infinity || isNaN(value)) {
return String(value);
}
return value;
}
if (typeof value === "string" && ns.isBlobSchema()) {
if (ns === this.rootSchema) {
return value;
}
return (this.serdeContext?.base64Encoder ?? utilBase64.toBase64)(value);
}
if (typeof value === "bigint") {
this.useReplacer = true;
}
if (ns.isDocumentSchema()) {
if (isObject) {
const out = Array.isArray(value) ? [] : {};
for (const [k, v] of Object.entries(value)) {
if (v instanceof serde.NumericValue) {
this.useReplacer = true;
out[k] = v;
}
else {
out[k] = this._write(ns, v);
}
}
return out;
}
else {
return structuredClone(value);
}
}
return value;
}
}
class JsonCodec extends SerdeContextConfig {
settings;
constructor(settings) {
super();
this.settings = settings;
}
createSerializer() {
const serializer = new JsonShapeSerializer(this.settings);
serializer.setSerdeContext(this.serdeContext);
return serializer;
}
createDeserializer() {
const deserializer = new JsonShapeDeserializer(this.settings);
deserializer.setSerdeContext(this.serdeContext);
return deserializer;
}
}
class AwsJsonRpcProtocol extends protocols.RpcProtocol {
serializer;
deserializer;
serviceTarget;
codec;
mixin;
awsQueryCompatible;
constructor({ defaultNamespace, serviceTarget, awsQueryCompatible, jsonCodec, }) {
super({
defaultNamespace,
});
this.serviceTarget = serviceTarget;
this.codec =
jsonCodec ??
new JsonCodec({
timestampFormat: {
useTrait: true,
default: 7,
},
jsonName: false,
});
this.serializer = this.codec.createSerializer();
this.deserializer = this.codec.createDeserializer();
this.awsQueryCompatible = !!awsQueryCompatible;
this.mixin = new ProtocolLib(this.awsQueryCompatible);
}
async serializeRequest(operationSchema, input, context) {
const request = await super.serializeRequest(operationSchema, input, context);
if (!request.path.endsWith("/")) {
request.path += "/";
}
Object.assign(request.headers, {
"content-type": `application/x-amz-json-${this.getJsonRpcVersion()}`,
"x-amz-target": `${this.serviceTarget}.${operationSchema.name}`,
});
if (this.awsQueryCompatible) {
request.headers["x-amzn-query-mode"] = "true";
}
if (schema.deref(operationSchema.input) === "unit" || !request.body) {
request.body = "{}";
}
return request;
}
getPayloadCodec() {
return this.codec;
}
async handleError(operationSchema, context, response, dataObject, metadata) {
if (this.awsQueryCompatible) {
this.mixin.setQueryCompatError(dataObject, response);
}
const errorIdentifier = loadRestJsonErrorCode(response, dataObject) ?? "Unknown";
const { errorSchema, errorMetadata } = await this.mixin.getErrorSchemaOrThrowBaseException(errorIdentifier, this.options.defaultNamespace, response, dataObject, metadata, this.awsQueryCompatible ? this.mixin.findQueryCompatibleError : undefined);
const ns = schema.NormalizedSchema.of(errorSchema);
const message = dataObject.message ?? dataObject.Message ?? "Unknown";
const ErrorCtor = schema.TypeRegistry.for(errorSchema[1]).getErrorCtor(errorSchema) ?? Error;
const exception = new ErrorCtor(message);
const output = {};
for (const [name, member] of ns.structIterator()) {
if (dataObject[name] != null) {
output[name] = this.codec.createDeserializer().readObject(member, dataObject[name]);
}
}
if (this.awsQueryCompatible) {
this.mixin.queryCompatOutput(dataObject, output);
}
throw this.mixin.decorateServiceException(Object.assign(exception, errorMetadata, {
$fault: ns.getMergedTraits().error,
message,
}, output), dataObject);
}
}
class AwsJson1_0Protocol extends AwsJsonRpcProtocol {
constructor({ defaultNamespace, serviceTarget, awsQueryCompatible, jsonCodec, }) {
super({
defaultNamespace,
serviceTarget,
awsQueryCompatible,
jsonCodec,
});
}
getShapeId() {
return "aws.protocols#awsJson1_0";
}
getJsonRpcVersion() {
return "1.0";
}
getDefaultContentType() {
return "application/x-amz-json-1.0";
}
}
class AwsJson1_1Protocol extends AwsJsonRpcProtocol {
constructor({ defaultNamespace, serviceTarget, awsQueryCompatible, jsonCodec, }) {
super({
defaultNamespace,
serviceTarget,
awsQueryCompatible,
jsonCodec,
});
}
getShapeId() {
return "aws.protocols#awsJson1_1";
}
getJsonRpcVersion() {
return "1.1";
}
getDefaultContentType() {
return "application/x-amz-json-1.1";
}
}
class AwsRestJsonProtocol extends protocols.HttpBindingProtocol {
serializer;
deserializer;
codec;
mixin = new ProtocolLib();
constructor({ defaultNamespace }) {
super({
defaultNamespace,
});
const settings = {
timestampFormat: {
useTrait: true,
default: 7,
},
httpBindings: true,
jsonName: true,
};
this.codec = new JsonCodec(settings);
this.serializer = new protocols.HttpInterceptingShapeSerializer(this.codec.createSerializer(), settings);
this.deserializer = new protocols.HttpInterceptingShapeDeserializer(this.codec.createDeserializer(), settings);
}
getShapeId() {
return "aws.protocols#restJson1";
}
getPayloadCodec() {
return this.codec;
}
setSerdeContext(serdeContext) {
this.codec.setSerdeContext(serdeContext);
super.setSerdeContext(serdeContext);
}
async serializeRequest(operationSchema, input, context) {
const request = await super.serializeRequest(operationSchema, input, context);
const inputSchema = schema.NormalizedSchema.of(operationSchema.input);
if (!request.headers["content-type"]) {
const contentType = this.mixin.resolveRestContentType(this.getDefaultContentType(), inputSchema);
if (contentType) {
request.headers["content-type"] = contentType;
}
}
if (request.body == null && request.headers["content-type"] === this.getDefaultContentType()) {
request.body = "{}";
}
return request;
}
async deserializeResponse(operationSchema, context, response) {
const output = await super.deserializeResponse(operationSchema, context, response);
const outputSchema = schema.NormalizedSchema.of(operationSchema.output);
for (const [name, member] of outputSchema.structIterator()) {
if (member.getMemberTraits().httpPayload && !(name in output)) {
output[name] = null;
}
}
return output;
}
async handleError(operationSchema, context, response, dataObject, metadata) {
const errorIdentifier = loadRestJsonErrorCode(response, dataObject) ?? "Unknown";
const { errorSchema, errorMetadata } = await this.mixin.getErrorSchemaOrThrowBaseException(errorIdentifier, this.options.defaultNamespace, response, dataObject, metadata);
const ns = schema.NormalizedSchema.of(errorSchema);
const message = dataObject.message ?? dataObject.Message ?? "Unknown";
const ErrorCtor = schema.TypeRegistry.for(errorSchema[1]).getErrorCtor(errorSchema) ?? Error;
const exception = new ErrorCtor(message);
await this.deserializeHttpMessage(errorSchema, context, response, dataObject);
const output = {};
for (const [name, member] of ns.structIterator()) {
const target = member.getMergedTraits().jsonName ?? name;
output[name] = this.codec.createDeserializer().readObject(member, dataObject[target]);
}
throw this.mixin.decorateServiceException(Object.assign(exception, errorMetadata, {
$fault: ns.getMergedTraits().error,
message,
}, output), dataObject);
}
getDefaultContentType() {
return "application/json";
}
}
const awsExpectUnion = (value) => {
if (value == null) {
return undefined;
}
if (typeof value === "object" && "__type" in value) {
delete value.__type;
}
return smithyClient.expectUnion(value);
};
class XmlShapeDeserializer extends SerdeContextConfig {
settings;
stringDeserializer;
constructor(settings) {
super();
this.settings = settings;
this.stringDeserializer = new protocols.FromStringShapeDeserializer(settings);
}
setSerdeContext(serdeContext) {
this.serdeContext = serdeContext;
this.stringDeserializer.setSerdeContext(serdeContext);
}
read(schema$1, bytes, key) {
const ns = schema.NormalizedSchema.of(schema$1);
const memberSchemas = ns.getMemberSchemas();
const isEventPayload = ns.isStructSchema() &&
ns.isMemberSchema() &&
!!Object.values(memberSchemas).find((memberNs) => {
return !!memberNs.getMemberTraits().eventPayload;
});
if (isEventPayload) {
const output = {};
const memberName = Object.keys(memberSchemas)[0];
const eventMemberSchema = memberSchemas[memberName];
if (eventMemberSchema.isBlobSchema()) {
output[memberName] = bytes;
}
else {
output[memberName] = this.read(memberSchemas[memberName], bytes);
}
return output;
}
const xmlString = (this.serdeContext?.utf8Encoder ?? utilUtf8.toUtf8)(bytes);
const parsedObject = this.parseXml(xmlString);
return this.readSchema(schema$1, key ? parsedObject[key] : parsedObject);
}
readSchema(_schema, value) {
const ns = schema.NormalizedSchema.of(_schema);
if (ns.isUnitSchema()) {
return;
}
const traits = ns.getMergedTraits();
if (ns.isListSchema() && !Array.isArray(value)) {
return this.readSchema(ns, [value]);
}
if (value == null) {
return value;
}
if (typeof value === "object") {
const flat = !!traits.xmlFlattened;
if (ns.isListSchema()) {
const listValue = ns.getValueSchema();
const buffer = [];
const sourceKey = listValue.getMergedTraits().xmlName ?? "member";
const source = flat ? value : (value[0] ?? value)[sourceKey];
if (source == null) {
return buffer;
}
const sourceArray = Array.isArray(source) ? source : [source];
for (const v of sourceArray) {
buffer.push(this.readSchema(listValue, v));
}
return buffer;
}
const buffer = {};
if (ns.isMapSchema()) {
const keyNs = ns.getKeySchema();
const memberNs = ns.getValueSchema();
let entries;
if (flat) {
entries = Array.isArray(value) ? value : [value];
}
else {
entries = Array.isArray(value.entry) ? value.entry : [value.entry];
}
const keyProperty = keyNs.getMergedTraits().xmlName ?? "key";
const valueProperty = memberNs.getMergedTraits().xmlName ?? "value";
for (const entry of entries) {
const key = entry[keyProperty];
const value = entry[valueProperty];
buffer[key] = this.readSchema(memberNs, value);
}
return buffer;
}
if (ns.isStructSchema()) {
const union = ns.isUnionSchema();
let unionSerde;
if (union) {
unionSerde = new UnionSerde(value, buffer);
}
for (const [memberName, memberSchema] of ns.structIterator()) {
const memberTraits = memberSchema.getMergedTraits();
const xmlObjectKey = !memberTraits.httpPayload
? memberSchema.getMemberTraits().xmlName ?? memberName
: memberTraits.xmlName ?? memberSchema.getName();
if (union) {
unionSerde.mark(xmlObjectKey);
}
if (value[xmlObjectKey] != null) {
buffer[memberName] = this.readSchema(memberSchema, value[xmlObjectKey]);
}
}
if (union) {
unionSerde.writeUnknown();
}
return buffer;
}
if (ns.isDocumentSchema()) {
return value;
}
throw new Error(`@aws-sdk/core/protocols - xml deserializer unhandled schema type for ${ns.getName(true)}`);
}
if (ns.isListSchema()) {
return [];
}
if (ns.isMapSchema() || ns.isStructSchema()) {
return {};
}
return this.stringDeserializer.read(ns, value);
}
parseXml(xml) {
if (xml.length) {
let parsedObj;
try {
parsedObj = xmlBuilder.parseXML(xml);
}
catch (e) {
if (e && typeof e === "object") {
Object.defineProperty(e, "$responseBodyText", {
value: xml,
});
}
throw e;
}
const textNodeName = "#text";
const key = Object.keys(parsedObj)[0];
const parsedObjToReturn = parsedObj[key];
if (parsedObjToReturn[textNodeName]) {
parsedObjToReturn[key] = parsedObjToReturn[textNodeName];
delete parsedObjToReturn[textNodeName];
}
return smithyClient.getValueFromTextNode(parsedObjToReturn);
}
return {};
}
}
class QueryShapeSerializer extends SerdeContextConfig {
settings;
buffer;
constructor(settings) {
super();
this.settings = settings;
}
write(schema$1, value, prefix = "") {
if (this.buffer === undefined) {
this.buffer = "";
}
const ns = schema.NormalizedSchema.of(schema$1);
if (prefix && !prefix.endsWith(".")) {
prefix += ".";
}
if (ns.isBlobSchema()) {
if (typeof value === "string" || value instanceof Uint8Array) {
this.writeKey(prefix);
this.writeValue((this.serdeContext?.base64Encoder ?? utilBase64.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(serde.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 serde.NumericValue ? value.string : String(value));
}
}
else if (ns.isTimestampSchema()) {
if (value instanceof Date) {
this.writeKey(prefix);
const format = protocols.determineTimestampFormat(ns, this.settings);
switch (format) {
case 5:
this.writeValue(value.toISOString().replace(".000Z", "Z"));
break;
case 6:
this.writeValue(smithyClient.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(`@aws-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 += `&${protocols.extendedEncodeURIComponent(key)}=`;
}
writeValue(value) {
this.buffer += protocols.extendedEncodeURIComponent(value);
}
}
class AwsQueryProtocol extends protocols.RpcProtocol {
options;
serializer;
deserializer;
mixin = new ProtocolLib();
constructor(options) {
super({
defaultNamespace: options.defaultNamespace,
});
this.options = options;
const settings = {
timestampFormat: {
useTrait: true,
default: 5,
},
httpBindings: false,
xmlNamespace: options.xmlNamespace,
serviceNamespace: options.defaultNamespace,
serializeEmptyLists: true,
};
this.serializer = new QueryShapeSerializer(settings);
this.deserializer = new XmlShapeDeserializer(settings);
}
getShapeId() {
return "aws.protocols#awsQuery";
}
setSerdeContext(serdeContext) {
this.serializer.setSerdeContext(serdeContext);
this.deserializer.setSerdeContext(serdeContext);
}
getPayloadCodec() {
throw new Error("AWSQuery protocol has no payload codec.");
}
async serializeRequest(operationSchema, input, context) {
const request = await super.serializeRequest(operationSchema, input, context);
if (!request.path.endsWith("/")) {
request.path += "/";
}
Object.assign(request.headers, {
"content-type": `application/x-www-form-urlencoded`,
});
if (schema.deref(operationSchema.input) === "unit" || !request.body) {
request.body = "";
}
const action = operationSchema.name.split("#")[1] ?? operationSchema.name;
request.body = `Action=${action}&Version=${this.options.version}` + request.body;
if (request.body.endsWith("&")) {
request.body = request.body.slice(-1);
}
return request;
}
async deserializeResponse(operationSchema, context, response) {
const deserializer = this.deserializer;
const ns = schema.NormalizedSchema.of(operationSchema.output);
const dataObject = {};
if (response.statusCode >= 300) {
const bytes = await protocols.collectBody(response.body, context);
if (bytes.byteLength > 0) {
Object.assign(dataObject, await deserializer.read(15, bytes));
}
await this.handleError(operationSchema, context, response, dataObject, this.deserializeMetadata(response));
}
for (const header in response.headers) {
const value = response.headers[header];
delete response.headers[header];
response.headers[header.toLowerCase()]