sdk-javascript/lib/bindings/http/v1/spec_1.js

228 lines
4.2 KiB
JavaScript

const { v4: uuidv4 } = require("uuid");
const Ajv = require("ajv");
const ValidationError = require("../validation/validation_error.js");
const {
asData,
isBoolean,
isInteger,
isString,
isDate,
isBinary
} = require("../validation/fun.js");
const isValidType = (v) =>
(isBoolean(v) || isInteger(v) || isString(v) || isDate(v) || isBinary(v));
const RESERVED_ATTRIBUTES = {
type: "type",
specversion: "specversion",
source: "source",
id: "id",
time: "time",
dataschema: "dataschema",
datacontenttype: "datacontenttype",
subject: "subject",
data: "data",
data_base64: "data_base64"
};
const schema = {
$ref: "#/definitions/event",
definitions: {
specversion: {
type: "string",
minLength: 1,
const: "1.0"
},
datacontenttype: {
type: "string"
},
data: {
type: ["object", "string"]
},
data_base64: {
type: "string"
},
event: {
properties: {
specversion: {
$ref: "#/definitions/specversion"
},
datacontenttype: {
$ref: "#/definitions/datacontenttype"
},
data: {
$ref: "#/definitions/data"
},
data_base64: {
$ref: "#/definitions/data_base64"
},
id: {
$ref: "#/definitions/id"
},
time: {
$ref: "#/definitions/time"
},
dataschema: {
$ref: "#/definitions/dataschema"
},
subject: {
$ref: "#/definitions/subject"
},
type: {
$ref: "#/definitions/type"
},
source: {
$ref: "#/definitions/source"
}
},
required: ["specversion", "id", "type", "source"],
type: "object"
},
id: {
type: "string",
minLength: 1
},
time: {
format: "date-time",
type: "string"
},
dataschema: {
type: "string",
format: "uri"
},
subject: {
type: "string",
minLength: 1
},
type: {
type: "string",
minLength: 1
},
source: {
format: "uri-reference",
type: "string"
}
},
type: "object"
};
const ajv = new Ajv({
extendRefs: true
});
const isValidAgainstSchema = ajv.compile(schema);
/** @typedef {import("../../../cloudevent")} CloudEvent */
/**
* Decorates a CloudEvent with the 1.0 specification getters and setters
* @ignore
*/
class Spec1 {
constructor() {
this.payload = {
specversion: schema.definitions.specversion.const,
id: uuidv4(),
time: new Date().toISOString()
};
Object.freeze(this);
}
check() {
if (!isValidAgainstSchema(this.payload)) {
throw new ValidationError("invalid payload", isValidAgainstSchema.errors);
}
}
set id(id) {
this.payload.id = id;
}
get id() {
return this.payload.id;
}
set source(source) {
this.payload.source = source;
}
get source() {
return this.payload.source;
}
get specversion() {
return this.payload.specversion;
}
set type(type) {
this.payload.type = type;
}
get type() {
return this.payload.type;
}
set dataContentType(datacontenttype) {
this.payload.datacontenttype = datacontenttype;
}
get dataContentType() {
return this.payload.datacontenttype;
}
set dataSchema(schema) {
this.payload.dataSchema = schema;
}
get dataSchema() {
return this.payload.dataSchema;
}
set subject(subject) {
this.payload.subject = subject;
}
get subject() {
return this.payload.subject;
}
set time(time) {
this.payload.time = time;
}
get time() {
return this.payload.time;
}
set data(data) {
this.payload.data = data;
}
get data() {
const dct = this.payload.datacontenttype;
if (dct) {
this.payload.data = asData(this.payload.data, dct);
}
return this.payload.data;
}
addExtension(key, value) {
if (!Object.prototype.hasOwnProperty.call(RESERVED_ATTRIBUTES, key)) {
if (isValidType(value)) {
this.payload[key] = value;
} else {
throw new ValidationError("Invalid type of extension value");
}
} else {
throw new ValidationError(`Reserved attribute name: '${key}'`);
}
return this;
}
}
module.exports = Spec1;