sdk-javascript/lib/specs/spec_0_3.js

228 lines
5.2 KiB
JavaScript

const { v4: uuidv4 } = require("uuid");
const Ajv = require("ajv");
const {
isBase64,
clone,
asData
} = require("../utils/fun.js");
const RESERVED_ATTRIBUTES = {
type: "type",
specversion: "specversion",
source: "source",
id: "id",
time: "time",
schemaurl: "schemaurl",
datacontentencoding: "datacontentencoding",
datacontenttype: "datacontenttype",
subject: "subject",
data: "data"
};
const SUPPORTED_CONTENT_ENCODING = {};
SUPPORTED_CONTENT_ENCODING.base64 = {
check: (data) => isBase64(data)
};
const schema = require("../../ext/spec_0_3.json");
const ajv = new Ajv({
extendRefs: true
});
const isValidAgainstSchema = ajv.compile(schema);
function Spec03(_caller) {
this.payload = {
specversion: "0.3",
id: uuidv4()
};
if (!_caller) {
_caller = require("../cloudevent.js");
}
/*
* Used to inject compatibility methods or attributes
*/
this.caller = _caller;
/*
* Inject compatibility methods
*/
this.caller.prototype.dataContentEncoding = function(encoding) {
this.spec.dataContentEncoding(encoding);
return this;
};
this.caller.prototype.getDataContentEncoding = function() {
return this.spec.getDataContentEncoding();
};
this.caller.prototype.dataContentType = function(contentType) {
this.spec.dataContentType(contentType);
return this;
};
this.caller.prototype.getDataContentType = function() {
return this.spec.getDataContentType();
};
this.caller.prototype.subject = function(_subject) {
this.spec.subject(_subject);
return this;
};
this.caller.prototype.getSubject = function() {
return this.spec.getSubject();
};
}
/*
* Check the spec constraints
*/
Spec03.prototype.check = function(ce) {
const toCheck = (!ce ? this.payload : ce);
if (!isValidAgainstSchema(toCheck)) {
const err = new TypeError("invalid payload");
err.errors = isValidAgainstSchema.errors;
throw err;
}
Array.of(toCheck)
.filter((tc) => tc.datacontentencoding)
.map((tc) => tc.datacontentencoding.toLocaleLowerCase("en-US"))
.filter((dce) => !Object.keys(SUPPORTED_CONTENT_ENCODING).includes(dce))
.forEach((dce) => {
const err = new TypeError("invalid payload");
err.errors = [
`Unsupported content encoding: ${dce}`
];
throw err;
});
Array.of(toCheck)
.filter((tc) => tc.datacontentencoding)
.filter((tc) => (typeof tc.data) === "string")
.map((tc) => {
const newtc = clone(tc);
newtc.datacontentencoding =
newtc.datacontentencoding.toLocaleLowerCase("en-US");
return newtc;
})
.filter((tc) => Object.keys(SUPPORTED_CONTENT_ENCODING)
.includes(tc.datacontentencoding))
.filter((tc) => !SUPPORTED_CONTENT_ENCODING[tc.datacontentencoding]
.check(tc.data))
.forEach((tc) => {
const err = new TypeError("invalid payload");
err.errors = [
`Invalid content encoding of data: ${tc.data}`
];
throw err;
});
};
Spec03.prototype.id = function(_id) {
this.payload.id = _id;
return this;
};
Spec03.prototype.getId = function() {
return this.payload.id;
};
Spec03.prototype.source = function(_source) {
this.payload.source = _source;
return this;
};
Spec03.prototype.getSource = function() {
return this.payload.source;
};
Spec03.prototype.specversion = function() {
// does not set! This is right
return this;
};
Spec03.prototype.getSpecversion = function() {
return this.payload.specversion;
};
Spec03.prototype.type = function(_type) {
this.payload.type = _type;
return this;
};
Spec03.prototype.getType = function() {
return this.payload.type;
};
Spec03.prototype.dataContentEncoding = function(encoding) {
this.payload.datacontentencoding = encoding;
return this;
};
Spec03.prototype.getDataContentEncoding = function() {
return this.payload.datacontentencoding;
};
Spec03.prototype.dataContentType = function(_contenttype) {
this.payload.datacontenttype = _contenttype;
return this;
};
Spec03.prototype.getDataContentType = function() {
return this.payload.datacontenttype;
};
Spec03.prototype.schemaurl = function(_schemaurl) {
this.payload.schemaurl = _schemaurl;
return this;
};
Spec03.prototype.getSchemaurl = function() {
return this.payload.schemaurl;
};
Spec03.prototype.subject = function(_subject) {
this.payload.subject = _subject;
return this;
};
Spec03.prototype.getSubject = function() {
return this.payload.subject;
};
Spec03.prototype.time = function(_time) {
this.payload.time = _time.toISOString();
return this;
};
Spec03.prototype.getTime = function() {
return this.payload.time;
};
Spec03.prototype.data = function(_data) {
this.payload.data = _data;
return this;
};
Spec03.prototype.getData = function() {
const dct = this.payload.datacontenttype;
const dce = this.payload.datacontentencoding;
if (dct && !dce) {
this.payload.data = asData(this.payload.data, dct);
}
return this.payload.data;
};
Spec03.prototype.addExtension = function(key, value) {
if (!Object.prototype.hasOwnProperty.call(RESERVED_ATTRIBUTES, key)) {
this.payload[key] = value;
} else {
throw new TypeError(`Reserved attribute name: '${key}'`);
}
return this;
};
module.exports = Spec03;