77 lines
1.8 KiB
JavaScript
77 lines
1.8 KiB
JavaScript
const {
|
|
HEADER_CONTENT_TYPE,
|
|
MIME_CE,
|
|
MIME_CE_JSON,
|
|
MIME_JSON,
|
|
MIME_OCTET_STREAM
|
|
} = require("./constants.js");
|
|
const Commons = require("./commons.js");
|
|
|
|
const STRUCTURED = "structured";
|
|
const BINARY = "binary";
|
|
|
|
const allowedBinaryContentTypes = [
|
|
MIME_JSON,
|
|
MIME_OCTET_STREAM
|
|
];
|
|
|
|
const allowedStructuredContentTypes = [
|
|
MIME_CE_JSON
|
|
];
|
|
|
|
// Is it binary or structured?
|
|
function resolveBindingName(payload, headers) {
|
|
const contentType =
|
|
Commons.sanityContentType(headers[HEADER_CONTENT_TYPE]);
|
|
|
|
if (contentType.startsWith(MIME_CE)) {
|
|
// Structured
|
|
if (allowedStructuredContentTypes.includes(contentType)) {
|
|
return STRUCTURED;
|
|
}
|
|
throwTypeError("structured+type not allowed", contentType);
|
|
} else {
|
|
// Binary
|
|
if (allowedBinaryContentTypes.includes(contentType)) {
|
|
return BINARY;
|
|
}
|
|
throwTypeError("content type not allowed", contentType);
|
|
}
|
|
}
|
|
|
|
function throwTypeError(msg, contentType) {
|
|
const err = new TypeError(msg);
|
|
err.errors = [contentType];
|
|
throw err;
|
|
}
|
|
|
|
class Unmarshaller {
|
|
constructor(receiverByBinding) {
|
|
this.receiverByBinding = receiverByBinding;
|
|
}
|
|
|
|
unmarshall(payload, headers) {
|
|
if (!payload) {
|
|
throw new TypeError("payload is null or undefined");
|
|
}
|
|
if (!headers) {
|
|
throw new TypeError("headers is null or undefined");
|
|
}
|
|
|
|
// Validation level 1
|
|
const sanityHeaders = Commons.sanityAndClone(headers);
|
|
if (!sanityHeaders[HEADER_CONTENT_TYPE]) {
|
|
throw new TypeError("content-type header not found");
|
|
}
|
|
|
|
// Resolve the binding
|
|
const bindingName = resolveBindingName(payload, sanityHeaders);
|
|
const cloudevent = this.receiverByBinding[bindingName]
|
|
.parse(payload, sanityHeaders);
|
|
|
|
return cloudevent;
|
|
}
|
|
}
|
|
|
|
module.exports = Unmarshaller;
|