cloudevent
Advanced tools
Comparing version 0.4.0 to 0.5.0
# Change Log | ||
## [0.5.0](https://github.com/smartiniOnGitHub/cloudevent.js/releases/tag/0.5.0) (2019-04-28) | ||
Summary Changelog: | ||
- Implement the [v0.2 - CloudEvents Spec](https://github.com/cloudevents/spec/releases/tag/v0.2) with all breaking changes since its v0.1 | ||
- Updated dependencies for the development environment | ||
- Updated documentation and samples to describe/show changes and the new behavior | ||
- Updated Tap unit tests to always run in strict mode, and some refactoring | ||
- Clarify which CloudEvents Spec version is implemented in the current release | ||
## [0.4.0](https://github.com/smartiniOnGitHub/cloudevent.js/releases/tag/0.4.0) (2019-03-15) | ||
@@ -4,0 +12,0 @@ Summary Changelog: |
@@ -47,5 +47,18 @@ /* | ||
// define some common attributes | ||
const ceCommonOptions = { | ||
time: new Date(), | ||
extensions: { 'exampleExtension': 'value' }, | ||
contenttype: 'application/json', | ||
schemaurl: 'http://my-schema.localhost.localdomain/v1/', | ||
strict: false // same as default | ||
} | ||
const ceCommonOptionsStrict = { ...ceCommonOptions, strict: true } | ||
const ceNamespace = 'com.github.smartiniOnGitHub.cloudeventjs.testevent-v1.0.0' | ||
const ceServerUrl = '/test' | ||
const ceCommonData = { 'hello': 'world', year: 2019 } | ||
// create some sample minimal instances, good even for validation ... | ||
const ceMinimal = new CloudEvent('1', // eventID | ||
'com.github.smartiniOnGitHub.cloudeventjs.testevent', // eventType | ||
const ceMinimal = new CloudEvent('1', // id | ||
ceNamespace, // type | ||
'/', // source | ||
@@ -57,19 +70,8 @@ {} // data (empty) // optional, but useful the same in this sample usage | ||
// create some instance with all attributes ... | ||
// define some common attributes | ||
const ceCommonOptions = { | ||
eventTypeVersion: '1.0.0', | ||
eventTime: new Date(), | ||
extensions: { 'exampleExtension': 'value' }, | ||
contentType: 'application/json', | ||
schemaURL: 'http://my-schema.localhost.localdomain', | ||
strict: false // same as default | ||
} | ||
const ceCommonOptionsStrict = { ...ceCommonOptions, strict: true } | ||
// create some instances with an undefined mandatory argument (handled by defaults), but with strict flag disabled: expected success ... | ||
// note that null values are not handled by default values, only undefined values ... | ||
const ceFull = new CloudEvent('1/full', | ||
'com.github.smartiniOnGitHub.cloudeventjs.testevent', | ||
'/test', | ||
{ 'hello': 'world', year: 2018 }, // data | ||
ceNamespace, | ||
ceServerUrl, | ||
ceCommonData, // data | ||
ceCommonOptions | ||
@@ -81,5 +83,5 @@ ) | ||
const ceFullStrict = new CloudEvent('2/full-strict', | ||
'com.github.smartiniOnGitHub.cloudeventjs.testevent', | ||
'/test', | ||
{ 'hello': 'world', year: 2018 }, // data | ||
ceNamespace, | ||
ceServerUrl, | ||
ceCommonData, // data | ||
ceCommonOptionsStrict // use common options, but set strict mode to true | ||
@@ -101,4 +103,4 @@ ) | ||
const ceErrorStrict = new CloudEvent('2/error-strict', | ||
'com.github.smartiniOnGitHub.cloudeventjs.testevent', | ||
'/test', | ||
ceNamespace, | ||
ceServerUrl, | ||
errorToData, // data | ||
@@ -112,6 +114,6 @@ ceCommonOptionsStrict // use common options, but set strict mode to true | ||
const ceFullStrictOtherContentType = new CloudEvent('3/full-strict-other-content-type', | ||
'com.github.smartiniOnGitHub.cloudeventjs.testevent', | ||
'/test', | ||
{ 'hello': 'world', year: 2018 }, // data | ||
{ ...ceCommonOptionsStrict, contentType: 'application/xml' } // use common strict options, but set strict mode to true | ||
ceNamespace, | ||
ceServerUrl, | ||
ceCommonData, // data | ||
{ ...ceCommonOptionsStrict, contenttype: 'application/xml' } // use common strict options, but set strict mode to true | ||
) | ||
@@ -160,3 +162,3 @@ assert(ceFullStrictOtherContentType !== null) | ||
// serialization examples | ||
// default contentType | ||
// default contenttype | ||
console.log(`\nSome serialization examples:`) | ||
@@ -174,6 +176,6 @@ const ceFullSerializedStatic = CloudEvent.serializeEvent(ceFull) | ||
assert(ceFullStrictSerializedOnlyValid !== null) | ||
// non default contentType | ||
// non default contenttype | ||
const ceFullStrictOtherContentTypeSerializedStatic = CloudEvent.serializeEvent(ceFullStrictOtherContentType, { | ||
// encoder: (data) => '<data "encoder"="sample" />', | ||
encodedData: '<data "hello"="world" "year"="2018" />', | ||
encodedData: '<data "hello"="world" "year"="2019" />', | ||
onlyValid: true | ||
@@ -184,3 +186,3 @@ }) | ||
// encoder: (data) => '<data "encoder"="sample" />', | ||
encodedData: '<data "hello"="world" "year"="2018" />', | ||
encodedData: '<data "hello"="world" "year"="2019" />', | ||
onlyValid: true | ||
@@ -195,3 +197,3 @@ }) | ||
// deserialization examples | ||
// default contentType | ||
// default contenttype | ||
console.log(`\nSome deserialization/parse examples:`) | ||
@@ -207,6 +209,6 @@ const ceFullDeserialized = CloudEvent.deserializeEvent(ceFullSerialized) | ||
console.log(`cloudEvent dump: ${T.dumpObject(ceFullStrictDeserializedOnlyValid, 'ceFullStrictDeserializedOnlyValid')}`) | ||
// non default contentType | ||
// non default contenttype | ||
const ceFullStrictOtherContentTypeDeserialized = CloudEvent.deserializeEvent(ceFullStrictOtherContentTypeSerialized, { | ||
// decoder: (data) => { decoder: 'Sample' }, | ||
decodedData: { hello: 'world', year: 2018 }, | ||
decodedData: { hello: 'world', year: 2019 }, | ||
onlyValid: true | ||
@@ -213,0 +215,0 @@ }) |
{ | ||
"name": "cloudevent", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"description": "JavaScript/Node.js implementation of the CloudEvents standard format", | ||
@@ -16,4 +16,4 @@ "main": "src/index", | ||
"license-checker:log": "npm run license-checker | tee ./temp/license-checker.log", | ||
"test:unit": "tap -J test/*.test.js test/*/*.test.js", | ||
"test:unit:debug": "tap -T --strict --node-arg=--inspect-brk test/*.test.js test/*/*.test.js", | ||
"test:unit": "tap -J --comments --strict test/*.test.js", | ||
"test:unit:debug": "tap -T --node-arg=--inspect-brk --comments --strict test/*.test.js", | ||
"test:coverage": "npm run test:unit -- --cov --coverage-report=html", | ||
@@ -29,7 +29,7 @@ "test": "npm run lint && npm run test:unit" | ||
"standard": "^12.0.1", | ||
"tap": "^12.6.0" | ||
"tap": "^12.6.5" | ||
}, | ||
"peerDependencies": {}, | ||
"engines": { | ||
"node": ">=8.15.0" | ||
"node": ">=8.16.0" | ||
}, | ||
@@ -36,0 +36,0 @@ "homepage": "https://github.com/smartiniOnGitHub/cloudevent.js#readme", |
@@ -12,2 +12,4 @@ # cloudevent / cloudevent.js | ||
Current release implements the v0.2 of the CloudEvents Spec. | ||
The purpose of this library is to create instances of CloudEvents in a simple way | ||
@@ -51,32 +53,34 @@ (with some useful defaults), or in a full way (all attributes). | ||
// create some sample minimal instances, good even for validation ... | ||
const ceMinimal = new CloudEvent('1', // eventID | ||
'com.github.smartiniOnGitHub.cloudeventjs.testevent', // eventType | ||
'/', // source | ||
{} // data (empty) // optional, but useful the same in this sample usage | ||
) | ||
// create some instance with all attributes ... | ||
// define some common attributes | ||
const ceCommonOptions = { | ||
eventTypeVersion: '1.0.0', | ||
eventTime: new Date(), | ||
time: new Date(), | ||
extensions: { 'exampleExtension': 'value' }, | ||
contentType: 'application/json', | ||
schemaURL: 'http://my-schema.localhost.localdomain', | ||
contenttype: 'application/json', | ||
schemaurl: 'http://my-schema.localhost.localdomain/v1/', | ||
strict: false // same as default | ||
} | ||
const ceCommonOptionsStrict = { ...ceCommonOptions, strict: true } | ||
const ceNamespace = 'com.github.smartiniOnGitHub.cloudeventjs.testevent-v1.0.0' | ||
const ceServerUrl = '/test' | ||
const ceCommonData = { 'hello': 'world', year: 2019 } | ||
// create some sample minimal instances, good even for validation ... | ||
const ceMinimal = new CloudEvent('1', // id | ||
ceNamespace, // type | ||
'/', // source | ||
{} // data (empty) // optional, but useful the same in this sample usage | ||
) | ||
// create some instances with an undefined mandatory argument (handled by defaults), but with strict flag disabled: expected success ... | ||
// note that null values are not handled by default values, only undefined values ... | ||
const ceFull = new CloudEvent('1/full', | ||
'com.github.smartiniOnGitHub.cloudeventjs.testevent', | ||
'/test', | ||
{ 'hello': 'world', year: 2018 }, // data | ||
ceNamespace, | ||
ceServerUrl, | ||
ceCommonData, // data | ||
ceCommonOptions | ||
) | ||
const ceFullStrict = new CloudEvent('2/full-strict', | ||
'com.github.smartiniOnGitHub.cloudeventjs.testevent', | ||
'/test', | ||
{ 'hello': 'world', year: 2018 }, // data | ||
ceNamespace, | ||
ceServerUrl, | ||
ceCommonData, // data | ||
ceCommonOptionsStrict // use common options, but set strict mode to true | ||
@@ -96,4 +100,4 @@ ) | ||
const ceErrorStrict = new CloudEvent('2/error-strict', | ||
'com.github.smartiniOnGitHub.cloudeventjs.testevent', | ||
'/test', | ||
ceNamespace, | ||
ceServerUrl, | ||
errorToData, // data | ||
@@ -108,6 +112,6 @@ ceCommonOptionsStrict // use common options, but set strict mode to true | ||
const ceFullStrictOtherContentType = new CloudEvent('3/full-strict-other-content-type', | ||
'com.github.smartiniOnGitHub.cloudeventjs.testevent', | ||
'/test', | ||
{ 'hello': 'world', year: 2018 }, // data | ||
{ ...ceCommonOptionsStrict, contentType: 'application/xml' } // use common strict options, but set strict mode to true | ||
ceNamespace, | ||
ceServerUrl, | ||
ceCommonData, // data | ||
{ ...ceCommonOptionsStrict, contenttype: 'application/xml' } // use common strict options, but set strict mode to true | ||
) | ||
@@ -141,3 +145,3 @@ assert(ceFullStrictOtherContentType !== null) | ||
```js | ||
// default contentType | ||
// default contenttype | ||
const ceFullSerializedStatic = CloudEvent.serializeEvent(ceFull) | ||
@@ -148,6 +152,6 @@ const ceFullSerialized = ceFull.serialize() | ||
console.log(`Serialization output for ceFullStrict, details:\n` + ceFullStrictSerialized) | ||
// non default contentType | ||
// non default contenttype | ||
const ceFullStrictOtherContentTypeSerializedStatic = CloudEvent.serializeEvent(ceFullStrictOtherContentType, { | ||
// encoder: (data) => '<data "encoder"="sample" />', | ||
encodedData: '<data "hello"="world" "year"="2018" />', | ||
encodedData: '<data "hello"="world" "year"="2019" />', | ||
onlyValid: true | ||
@@ -157,3 +161,3 @@ }) | ||
// encoder: (data) => '<data "encoder"="sample" />', | ||
encodedData: '<data "hello"="world" "year"="2018" />', | ||
encodedData: '<data "hello"="world" "year"="2019" />', | ||
onlyValid: true | ||
@@ -171,3 +175,3 @@ }) | ||
// deserialization examples | ||
// default contentType | ||
// default contenttype | ||
console.log(`\nSome deserialization/parse examples:`) | ||
@@ -183,6 +187,6 @@ const ceFullDeserialized = CloudEvent.deserializeEvent(ceFullSerialized) | ||
console.log(`cloudEvent dump: ${T.dumpObject(ceFullStrictDeserializedOnlyValid, 'ceFullStrictDeserializedOnlyValid')}`) | ||
// non default contentType | ||
// non default contenttype | ||
const ceFullStrictOtherContentTypeDeserialized = CloudEvent.deserializeEvent(ceFullStrictOtherContentTypeSerialized, { | ||
// decoder: (data) => { decoder: 'Sample' }, | ||
decodedData: { hello: 'world', year: 2018 }, | ||
decodedData: { hello: 'world', year: 2019 }, | ||
onlyValid: true | ||
@@ -206,3 +210,3 @@ }) | ||
Node.js 8.15.x or later. | ||
Node.js 8.16.x or later. | ||
@@ -224,3 +228,10 @@ | ||
Since v0.2 of the spec, there is no more a standard attribute to specify the version | ||
of any specific event type, so the best if to follow their recommendations, | ||
and for example add a version in the 'type' attribute | ||
(for example '-v1.0.0' at the end of its base value, or at the end of its full value) , | ||
or into the 'schemaurl' attribute but only its major version | ||
(like '-v1' or '/v1/' at the end). | ||
## Contributing | ||
@@ -227,0 +238,0 @@ |
@@ -45,25 +45,23 @@ /* | ||
* Create a new instance of a CloudEvent object. | ||
* @param {!string} eventID the ID of the event (unique), mandatory | ||
* @param {!string} eventType the type of the event (usually), mandatory | ||
* @param {!string} id the ID of the event (unique), mandatory | ||
* @param {!string} type the type of the event (usually), mandatory | ||
* @param {!uri} source the source uri of the event (use '/' if empty), mandatory | ||
* @param {(object|Map|Set)} data the real event data | ||
* @param {object} options optional attributes of the event; some has default values chosen here: | ||
* eventTypeVersion (string) optional, | ||
* eventTime (timestamp, default now), | ||
* time (timestamp/date, default now), | ||
* extensions (object) optional but if given must contain at least 1 property (key/value), | ||
* contentType (string, default 'application/json') tell how the data attribute must be encoded, | ||
* schemaURL (uri) optional, | ||
* contenttype (string, default 'application/json') tell how the data attribute must be encoded, | ||
* schemaurl (uri) optional, | ||
* strict (boolean, default false) tell if object instance will be validated in a more strict way | ||
* @throws {Error} if strict is true and eventID or eventType is undefined or null | ||
* @throws {Error} if strict is true and id or type is undefined or null | ||
*/ | ||
constructor (eventID, eventType, source, data, { | ||
eventTypeVersion, | ||
eventTime = new Date(), | ||
constructor (id, type, source, data, { | ||
time = new Date(), | ||
extensions, | ||
contentType = CloudEvent.contentTypeDefault(), | ||
schemaURL, | ||
contenttype = CloudEvent.contenttypeDefault(), | ||
schemaurl, | ||
strict = false } = {} | ||
) { | ||
if (strict === true) { | ||
if (!eventID || !eventType || !source) { | ||
if (!id || !type || !source) { | ||
throw new Error('Unable to create CloudEvent instance, mandatory field missing') | ||
@@ -78,3 +76,3 @@ } | ||
*/ | ||
this.eventID = eventID | ||
this.id = id | ||
/** | ||
@@ -85,3 +83,3 @@ * The event type. | ||
*/ | ||
this.eventType = eventType | ||
this.type = type | ||
/** | ||
@@ -111,3 +109,3 @@ * The source URI of the event. | ||
*/ | ||
this.cloudEventsVersion = this.constructor.version() | ||
this.specversion = this.constructor.version() | ||
/** | ||
@@ -118,17 +116,12 @@ * The MIME Type for the encoding of the data attribute, when serialized. | ||
*/ | ||
this.contentType = contentType | ||
this.contenttype = contenttype | ||
/** | ||
* The event timestamp. | ||
* Copy the original object to avoid changing objects that could be shared. | ||
* @type {timestamp} | ||
* Note that here the object will be transformed into string when serialized. | ||
* @type {object} | ||
* @private | ||
*/ | ||
this.eventTime = new Date(eventTime.valueOf()) | ||
this.time = new Date(time.valueOf()) | ||
/** | ||
* The event version. | ||
* @type {string} | ||
* @private | ||
*/ | ||
this.eventTypeVersion = eventTypeVersion | ||
/** | ||
* Extensions defined for the event. | ||
@@ -145,3 +138,3 @@ * Copy the original object to avoid changing objects that could be shared. | ||
*/ | ||
this.schemaURL = schemaURL | ||
this.schemaurl = schemaurl | ||
@@ -162,3 +155,3 @@ // add strict to extensions, but only when defined | ||
static version () { | ||
return '0.1' | ||
return '0.2' | ||
} | ||
@@ -172,3 +165,3 @@ | ||
*/ | ||
static contentTypeDefault () { | ||
static contenttypeDefault () { | ||
return 'application/json' | ||
@@ -223,13 +216,10 @@ } | ||
// note that some properties are not checked here because I assign a default value, and I check them in strict mode, like: | ||
// data, eventTime, extensions, contentType ... | ||
// ve.push(V.ensureIsStringNotEmpty(event.cloudEventsVersion, 'cloudEventsVersion')) // no more a public attribute | ||
ve.push(V.ensureIsStringNotEmpty(event.eventID, 'eventID')) | ||
ve.push(V.ensureIsStringNotEmpty(event.eventType, 'eventType')) | ||
// data, time, extensions, contenttype ... | ||
// ve.push(V.ensureIsStringNotEmpty(event.specversion, 'specversion')) // no more a public attribute | ||
ve.push(V.ensureIsStringNotEmpty(event.id, 'id')) | ||
ve.push(V.ensureIsStringNotEmpty(event.type, 'type')) | ||
ve.push(V.ensureIsStringNotEmpty(event.source, 'source')) | ||
if (V.isDefinedAndNotNull(event.eventTypeVersion)) { | ||
ve.push(V.ensureIsStringNotEmpty(event.eventTypeVersion, 'eventTypeVersion')) | ||
if (V.isDefinedAndNotNull(event.schemaurl)) { | ||
ve.push(V.ensureIsStringNotEmpty(event.schemaurl, 'schemaurl')) | ||
} | ||
if (V.isDefinedAndNotNull(event.schemaURL)) { | ||
ve.push(V.ensureIsStringNotEmpty(event.schemaURL, 'schemaURL')) | ||
} | ||
@@ -239,5 +229,5 @@ // additional validation if strict mode enabled, or if enabled in the event ... | ||
ve.push(V.ensureIsClass(event, CloudEvent, 'CloudEvent_Subclass')) | ||
ve.push(V.ensureIsVersion(event.cloudEventsVersion, 'cloudEventsVersion')) | ||
ve.push(V.ensureIsVersion(event.specversion, 'specversion')) | ||
if (V.isDefinedAndNotNull(event.data)) { | ||
if (event.contentType === CloudEvent.contentTypeDefault()) { | ||
if (event.contenttype === CloudEvent.contenttypeDefault()) { | ||
ve.push(V.ensureIsObjectOrCollectionNotString(event.data, 'data')) | ||
@@ -249,5 +239,2 @@ } else { | ||
} | ||
if (V.isDefinedAndNotNull(event.eventTypeVersion)) { | ||
ve.push(V.ensureIsVersion(event.eventTypeVersion, 'eventTypeVersion')) | ||
} | ||
ve.push(V.ensureIsURI(event.source, null, 'source')) | ||
@@ -261,5 +248,5 @@ if (V.isDefinedAndNotNull(event.extensions)) { | ||
} | ||
ve.push(V.ensureIsDatePast(event.eventTime, 'eventTime')) | ||
ve.push(V.ensureIsStringNotEmpty(event.contentType, 'contentType')) | ||
ve.push(V.ensureIsURI(event.schemaURL, null, 'schemaURL')) | ||
ve.push(V.ensureIsDatePast(event.time, 'time')) | ||
ve.push(V.ensureIsStringNotEmpty(event.contenttype, 'contenttype')) | ||
ve.push(V.ensureIsURI(event.schemaurl, null, 'schemaurl')) | ||
} | ||
@@ -308,3 +295,3 @@ | ||
* encoder (function, no default) a function that takes data and returns encoded data, | ||
* encodedData (string, no default) already encoded data (but consistency with the contentType is not checked), | ||
* encodedData (string, no default) already encoded data (but consistency with the contenttype is not checked), | ||
* onlyValid (boolean, default false) to serialize only if it's a valid instance, | ||
@@ -318,3 +305,3 @@ * @return {string} the serialized event, as a string | ||
} | ||
if (event.contentType === CloudEvent.contentTypeDefault()) { | ||
if (event.contenttype === CloudEvent.contenttypeDefault()) { | ||
if ((onlyValid === false) || (onlyValid === true && CloudEvent.isValidEvent(event) === true)) { | ||
@@ -329,3 +316,3 @@ return JSON.stringify(event) | ||
if (!V.isFunction(encoder)) { | ||
throw new Error(`Missing or wrong encoder function: '${encoder}' for the given content type: '${event.contentType}'.`) | ||
throw new Error(`Missing or wrong encoder function: '${encoder}' for the given content type: '${event.contenttype}'.`) | ||
} | ||
@@ -336,7 +323,7 @@ encodedData = encoder(event.payload) | ||
if (!V.isDefinedAndNotNull(encodedData)) { | ||
throw new Error(`Missing encoder function: use encoder function or already encoded data with the given content type: '${event.contentType}'.`) | ||
throw new Error(`Missing encoder function: use encoder function or already encoded data with the given content type: '${event.contenttype}'.`) | ||
} | ||
} | ||
if (!V.isStringNotEmpty(encodedData)) { | ||
throw new Error(`Missing or wrong encoded data: '${encodedData}' for the given content type: '${event.contentType}'.`) | ||
throw new Error(`Missing or wrong encoded data: '${encodedData}' for the given content type: '${event.contenttype}'.`) | ||
} | ||
@@ -359,3 +346,3 @@ const newEvent = T.mergeObjects(event, { data: encodedData }) | ||
* decoder (function, no default) a function that takes data and returns decoder data, | ||
* decodedData (object, no default) already decoded data (but consistency with the contentType is not checked), | ||
* decodedData (object, no default) already decoded data (but consistency with the contenttype is not checked), | ||
* onlyValid (boolean, default false) to serialize only if it's a valid instance, | ||
@@ -381,17 +368,16 @@ * @return {object} the deserialized event as a CloudEvent instance | ||
// fill a new CludEvent instance with parsed data | ||
const ce = new CloudEvent(parsed.eventID, | ||
parsed.eventType, | ||
const ce = new CloudEvent(parsed.id, | ||
parsed.type, | ||
parsed.source, | ||
parsed.data, | ||
{ // options | ||
eventTypeVersion: parsed.eventTypeVersion, | ||
eventTime: T.timestampFromString(parsed.eventTime), | ||
time: T.timestampFromString(parsed.time), | ||
extensions: parsed.extensions, | ||
contentType: parsed.contentType, | ||
schemaURL: parsed.schemaURL, | ||
contenttype: parsed.contenttype, | ||
schemaurl: parsed.schemaurl, | ||
strict: parsed.strict | ||
} | ||
) | ||
// depending on the contentType, decode the data attribute (the payload) | ||
if (parsed.contentType === CloudEvent.contentTypeDefault()) { | ||
// depending on the contenttype, decode the data attribute (the payload) | ||
if (parsed.contenttype === CloudEvent.contenttypeDefault()) { | ||
return ce | ||
@@ -402,3 +388,3 @@ } | ||
if (!V.isFunction(decoder)) { | ||
throw new Error(`Missing or wrong decoder function: '${decoder}' for the given content type: '${parsed.contentType}'.`) | ||
throw new Error(`Missing or wrong decoder function: '${decoder}' for the given content type: '${parsed.contenttype}'.`) | ||
} | ||
@@ -409,7 +395,7 @@ decodedData = decoder(parsed.data) | ||
if (!V.isDefinedAndNotNull(decodedData)) { | ||
throw new Error(`Missing decoder function: use decoder function or already decoded data with the given content type: '${parsed.contentType}'.`) | ||
throw new Error(`Missing decoder function: use decoder function or already decoded data with the given content type: '${parsed.contenttype}'.`) | ||
} | ||
} | ||
if (!V.isObject(decodedData) && !V.isStringNotEmpty(decodedData)) { | ||
throw new Error(`Missing or wrong decoded data: '${decodedData}' for the given content type: '${parsed.contentType}'.`) | ||
throw new Error(`Missing or wrong decoded data: '${decodedData}' for the given content type: '${parsed.contenttype}'.`) | ||
} | ||
@@ -430,2 +416,9 @@ // overwrite data with decodedData before returning it | ||
* but only in some serialization libraries. | ||
* Note that schema definitions for data and extensions are right, | ||
* but I need to keep them commented here and to set the flag | ||
* additionalProperties to true, | ||
* or when used both data and extensions will be empty in JSON output. | ||
* Note that for time I had to keep its schema definition commented | ||
* or schema validation on object instances would fail (because in the | ||
* object model I store it as a timestamp/date currently and not as a string). | ||
* | ||
@@ -444,15 +437,14 @@ * See JSON Schema. | ||
properties: { | ||
cloudEventsVersion: { type: 'string' }, | ||
eventID: { type: 'string' }, | ||
eventType: { type: 'string' }, | ||
// data: { type: 'object' }, | ||
eventTypeVersion: { type: 'string' }, | ||
source: { type: 'string' }, | ||
eventTime: { type: 'string' }, | ||
specversion: { type: 'string', minLength: 1 }, | ||
id: { type: 'string', minLength: 1 }, | ||
type: { type: 'string', minLength: 1 }, | ||
// data: { type: ['object', 'string'] }, | ||
source: { type: 'string', format: 'uri-reference' }, | ||
// time: { type: 'string', format: 'date-time' }, | ||
// extensions: { type: 'object' }, | ||
contentType: { type: 'string' }, | ||
schemaURL: { type: 'string' } | ||
contenttype: { type: 'string' }, | ||
schemaurl: { type: 'string', format: 'uri-reference' } | ||
}, | ||
required: ['cloudEventsVersion', 'eventID', 'eventType', | ||
'source', 'contentType' | ||
required: [ | ||
'specversion', 'id', 'type', 'source' | ||
], | ||
@@ -470,3 +462,3 @@ additionalProperties: true // to handle data, extensions, and maybe other (non-standard) properties | ||
* encoder (function, default null) a function that takes data and returns encoded data, | ||
* encodedData (string, default null) already encoded data (but consistency with the contentType is not checked), | ||
* encodedData (string, default null) already encoded data (but consistency with the contenttype is not checked), | ||
* @return {string} the serialized event, as a string | ||
@@ -544,3 +536,3 @@ */ | ||
toString () { | ||
return `CloudEvent[cloudEventsVersion: ${this.cloudEventsVersion}, ${T.dumpObject(this.eventID, 'eventID')}, ${T.dumpObject(this.eventType, 'eventType')}, ${T.dumpObject(this.data, 'data')}, ...]` | ||
return `CloudEvent[specversion: ${this.specversion}, ${T.dumpObject(this.id, 'id')}, ${T.dumpObject(this.type, 'type')}, ${T.dumpObject(this.data, 'data')}, ...]` | ||
} | ||
@@ -547,0 +539,0 @@ |
@@ -106,3 +106,4 @@ /* | ||
* Utility function that return a string representation | ||
* (compatible with the CloudEvent standard) of the given timestamp (Date). | ||
* (compatible with the CloudEvent standard) | ||
* of the given timestamp (Date), or the current one will be used. | ||
* | ||
@@ -112,3 +113,3 @@ * Note that the value returned is in the UTC format. | ||
* @static | ||
* @param {!object} obj the timestamp/date to convert | ||
* @param {object} obj the timestamp/date to convert, or the current one | ||
* @return {string} the string representation of the object | ||
@@ -118,6 +119,10 @@ * @throws {Error} if obj is undefined or null, or is not a Date instance | ||
static timestampToString (obj) { | ||
if (!V.isDateValid(obj)) { | ||
throw new Error(`Missing or wrong timestamp: '${obj}' must be a date and not a: '${typeof obj}'.`) | ||
let timestamp = obj | ||
if (V.isUndefinedOrNull(timestamp)) { | ||
timestamp = new Date() | ||
} | ||
return obj.toISOString() | ||
if (!V.isDateValid(timestamp)) { | ||
throw new Error(`Missing or wrong timestamp: '${timestamp}' must be a date and not a: '${typeof timestamp}'.`) | ||
} | ||
return timestamp.toISOString() | ||
} | ||
@@ -124,0 +129,0 @@ |
91286
240
1590