Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

cloudevent

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cloudevent - npm Package Compare versions

Comparing version 0.6.0 to 0.7.0

17

CHANGELOG.md
# Change Log
## [0.7.0](https://github.com/smartiniOnGitHub/cloudevent.js/releases/tag/0.7.0) (2020-09-20)
Summary Changelog:
- Implement the [v1.0 - CloudEvents Spec](https://github.com/cloudevents/spec/releases/tag/v1.0)
with all breaking changes since its v0.3
- Update dependencies for the development environment
- Update JSON Schema to that of spec v1.0
- Feature: keep compatibility with Node.js 8 (but this is latest release that supports it)
- Breaking change: updated attributes as per spec
- Breaking change: updated my extension/s to be compliant with updated spec
- Breaking change: updated getter method 'payload' to return parsed JSON data
if datacontenttype is default or json-derived, and unparsed data in other cases;
if data_base64 is defined, an uncoded version of it will be returned
- Feature: implement a getter method 'dataType' to tell if data is text or binary encoded
- Feature: added as validation option a user defined function to validate data with dataschema
- General: ensured some CloudEvent serialized instances pass some online validators for this spec version;
for example [this](https://www.itb.ec.europa.eu/json/cloudevents/upload) from its Web UI
## [0.6.0](https://github.com/smartiniOnGitHub/cloudevent.js/releases/tag/0.6.0) (2019-10-23)

@@ -4,0 +21,0 @@ Summary Changelog:

115

example/nodejs-base.js

@@ -41,10 +41,11 @@ /*

// create some sample instances but without mandatory fields (for validation) ...
console.log('\nCreation of some CloudEvent instances, and related diagnostics:')
// create some sample instances but without mandatory fields (so not good for validation) ...
// note that errors will be thrown at instance creation only when strict mode is true
console.log('\nCreation of some CloudEvent (ce) instances, and related diagnostics:')
const ceEmpty = new CloudEvent() // create an empty CloudEvent instance (not valid for the validator, even in default case, when strict mode flag is disabled)
assert(ceEmpty !== null)
console.log(`cloudEvent dump: ${T.dumpObject(ceEmpty, 'ceEmpty')}`)
console.log(`ce dump (but not good for validation): ${T.dumpObject(ceEmpty, 'ceEmpty')}`)
const ceMinimalMandatoryUndefinedNoStrict = new CloudEvent(undefined, undefined, undefined, undefined, { strict: false }) // expected success
assert(ceMinimalMandatoryUndefinedNoStrict !== null)
console.log(`cloudEvent dump: ${T.dumpObject(ceMinimalMandatoryUndefinedNoStrict, 'ceMinimalMandatoryUndefinedNoStrict')}`)
console.log(`ce dump (but not good for validation): ${T.dumpObject(ceMinimalMandatoryUndefinedNoStrict, 'ceMinimalMandatoryUndefinedNoStrict')}`)
// const ceMinimalMandatoryUndefinedStrict = new CloudEvent(undefined, undefined, undefined, undefined, { strict: true }) // expected failure

@@ -55,5 +56,5 @@ // assert(ceMinimalMandatoryUndefinedStrict == null) // no, ReferenceError: ceMinimalMandatoryUndefinedStrict is not defined

const ceCommonOptions = {
time: new Date(),
time: new Date(), // same as default
datacontenttype: 'application/json',
schemaurl: 'http://my-schema.localhost.localdomain/v1/',
dataschema: 'http://my-schema.localhost.localdomain/v1/',
subject: 'subject',

@@ -63,9 +64,11 @@ strict: false // same as default

const ceCommonOptionsStrict = { ...ceCommonOptions, strict: true }
const ceCommonExtensions = { exampleExtension: 'value' }
const ceCommonExtensions = { exampleextension: 'value' }
const ceNamespace = 'com.github.smartiniOnGitHub.cloudeventjs.testevent-v1.0.0'
const ceServerUrl = '/test'
const ceCommonData = { hello: 'world', year: 2019 }
// const ceDataAsString = 'Hello World, 2019'
const ceCommonData = { hello: 'world', year: 2020, enabled: true }
const ceDataAsJSONString = '{ "hello": "world", "year": 2020, "enabled": true }'
const ceDataAsString = 'Hello World, 2020'
const ceDataEncoded = 'SGVsbG8gV29ybGQsIDIwMjA='
// create some sample minimal instances, good even for validation ...
// create a sample minimal instance ...
const ceMinimal = new CloudEvent('1', // id

@@ -77,6 +80,9 @@ ceNamespace, // type

assert(ceMinimal !== null)
console.log(`cloudEvent dump: ${T.dumpObject(ceMinimal, 'ceMinimal')}`)
console.log(`ce dump: ${T.dumpObject(ceMinimal, 'ceMinimal')}`)
// 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 ...
// When creating some instances with an undefined mandatory argument (handled by defaults),
// but with strict flag disabled success is expected, otherwise with strict flag enabled a failure is expected ...
// In JavaScript, null values are not handled as default values, only undefined values ...
// create a sample instance with most common attributes defined ...
const ceFull = new CloudEvent('1/full',

@@ -91,4 +97,4 @@ ceNamespace,

assert(!ceFull.isStrict)
console.log(`cloudEvent dump: ${T.dumpObject(ceFull, 'ceFull')}`)
const ceFullStrict = new CloudEvent('2/full-strict',
console.log(`ce dump: ${T.dumpObject(ceFull, 'ceFull')}`)
const ceFullStrict = new CloudEvent('1/full-strict',
ceNamespace,

@@ -104,3 +110,15 @@ ceServerUrl,

assert(!CloudEvent.isStrictEvent(ceFull)) // the same, but using static method
console.log(`cloudEvent dump: ${T.dumpObject(ceFullStrict, 'ceFullStrict')}`)
console.log(`ce dump: ${T.dumpObject(ceFullStrict, 'ceFullStrict')}`)
// create an instance with a JSON string as data
const ceFullStrictJSONTextData = new CloudEvent('2/full-strict-json-string-data',
ceNamespace,
ceServerUrl,
ceDataAsJSONString, // data
ceCommonOptionsStrict, // use strict options
ceCommonExtensions
)
assert(ceFullStrictJSONTextData !== null)
assert(ceFullStrictJSONTextData.isStrict)
console.log(`ce dump: ${T.dumpObject(ceFullStrictJSONTextData, 'ceFullStrictJSONTextData')}`)
console.log(`ce validation results on ceFullStrictJSONTextData = ${CloudEvent.validateEvent(ceFullStrictJSONTextData)}`)
// create an instance that wrap an Error

@@ -114,3 +132,3 @@ const error = new Error('sample error')

})
const ceErrorStrict = new CloudEvent('2/error-strict',
const ceErrorStrict = new CloudEvent('3/error-strict',
ceNamespace,

@@ -124,5 +142,5 @@ ceServerUrl,

assert(ceErrorStrict.isStrict)
console.log(`cloudEvent dump: ${T.dumpObject(ceErrorStrict, 'ceErrorStrict')}`)
console.log(`ce dump: ${T.dumpObject(ceErrorStrict, 'ceErrorStrict')}`)
// create an instance with a different content type
const ceFullStrictOtherContentType = new CloudEvent('3/full-strict-other-content-type',
const ceFullStrictOtherContentType = new CloudEvent('4/full-strict-other-content-type',
ceNamespace,

@@ -132,3 +150,3 @@ ceServerUrl,

ceCommonData, // data
{ ...ceCommonOptionsStrict, datacontenttype: 'application/xml' }, // use common strict options, but set strict mode to true
{ ...ceCommonOptionsStrict, datacontenttype: 'application/xml' }, // use common strict options
ceCommonExtensions

@@ -140,3 +158,29 @@ )

assert(!CloudEvent.isStrictEvent(ceFull)) // the same, but using static method
console.log(`cloudEvent dump: ${T.dumpObject(ceFullStrictOtherContentType, 'ceFullStrictOtherContentType')}`)
console.log(`ce dump: ${T.dumpObject(ceFullStrictOtherContentType, 'ceFullStrictOtherContentType')}`)
// create an instance with data as a string, but not strict (to validate it even in strict mode)
const ceFullTextData = new CloudEvent('5/no-strict-text-data',
ceNamespace,
ceServerUrl,
ceDataAsString, // data
ceCommonOptions, // use common options
ceCommonExtensions
)
assert(ceFullTextData !== null)
assert(!ceFullTextData.isStrict)
assert(ceFullTextData.payload === ceDataAsString) // returned data is transformed
console.log(`ce dump: ${T.dumpObject(ceFullTextData, 'ceFullTextData')}`)
console.log(`ce validation results on ceFullTextData (no strict validation) = ${CloudEvent.validateEvent(ceFullTextData)}`)
console.log(`ce validation results on ceFullTextData (with strict validation) = ${CloudEvent.validateEvent(ceFullTextData, { strict: true })}`)
// create an instance with data encoded in base64
const ceFullStrictBinaryData = new CloudEvent('6/full-strict-binary-data',
ceNamespace,
ceServerUrl,
null, // data
{ ...ceCommonOptionsStrict, datainbase64: ceDataEncoded }, // use common strict options, and set binary data in base64
ceCommonExtensions
)
assert(ceFullStrictBinaryData !== null)
assert(ceFullStrictBinaryData.isStrict)
assert(ceFullStrictBinaryData.payload === ceDataAsString) // returned data is transformed
console.log(`ce dump: ${T.dumpObject(ceFullStrictBinaryData, 'ceFullStrictBinaryData')}`)

@@ -150,4 +194,8 @@ // validate/check if valid instances (optional)

assert(ceFullStrict.isValid())
assert(ceFullStrictJSONTextData.isValid())
assert(ceErrorStrict.isValid())
assert(ceFullStrictOtherContentType.isValid())
assert(ceFullTextData.isValid())
assert(!ceFullTextData.isValid({ strict: true }))
assert(ceFullStrictBinaryData.isValid())
// the same, but using static method

@@ -159,4 +207,8 @@ assert(!CloudEvent.isValidEvent(ceEmpty))

assert(CloudEvent.isValidEvent(ceFullStrict))
assert(CloudEvent.isValidEvent(ceFullStrictJSONTextData))
assert(CloudEvent.isValidEvent(ceErrorStrict))
assert(CloudEvent.isValidEvent(ceFullStrictOtherContentType))
assert(CloudEvent.isValidEvent(ceFullTextData))
assert(!CloudEvent.isValidEvent(ceFullTextData, { strict: true }))
assert(CloudEvent.isValidEvent(ceFullStrictBinaryData))
assert(CloudEvent.validateEvent(ceEmpty).length === 3)

@@ -172,5 +224,14 @@ assert(CloudEvent.validateEvent(ceEmpty, { strict: true }).length === 5)

assert(CloudEvent.validateEvent(ceFullStrict, { strict: true }).length === 0)
assert(CloudEvent.validateEvent(ceFullStrictJSONTextData).length === 0)
assert(CloudEvent.validateEvent(ceFullStrictJSONTextData, { strict: false }).length === 0)
assert(CloudEvent.validateEvent(ceFullStrictJSONTextData, { strict: true }).length === 0)
assert(CloudEvent.validateEvent(ceFullStrictOtherContentType).length === 0)
assert(CloudEvent.validateEvent(ceFullStrictOtherContentType, { strict: false }).length === 0)
assert(CloudEvent.validateEvent(ceFullStrictOtherContentType, { strict: true }).length === 0)
assert(CloudEvent.validateEvent(ceFullTextData).length === 0)
assert(CloudEvent.validateEvent(ceFullTextData, { strict: false }).length === 0)
assert(CloudEvent.validateEvent(ceFullTextData, { strict: true }).length === 1)
assert(CloudEvent.validateEvent(ceFullStrictBinaryData).length === 0)
assert(CloudEvent.validateEvent(ceFullStrictBinaryData, { strict: false }).length === 0)
assert(CloudEvent.validateEvent(ceFullStrictBinaryData, { strict: true }).length === 0)
// some diagnostic info

@@ -198,3 +259,3 @@ console.log('\nSome expected validation errors:')

// encoder: (data) => '<data "encoder"="sample" />',
encodedData: '<data "hello"="world" "year"="2019" />',
encodedData: '<data "hello"="world" "year"="2020" />',
onlyValid: true

@@ -205,3 +266,3 @@ })

// encoder: (data) => '<data "encoder"="sample" />',
encodedData: '<data "hello"="world" "year"="2019" />',
encodedData: '<data "hello"="world" "year"="2020" />',
onlyValid: true

@@ -223,10 +284,10 @@ })

assert(CloudEvent.isCloudEvent(ceFullDeserialized))
console.log(`cloudEvent dump: ${T.dumpObject(ceFullDeserialized, 'ceFullDeserialized')}`)
console.log(`ce dump: ${T.dumpObject(ceFullDeserialized, 'ceFullDeserialized')}`)
const ceFullStrictDeserializedOnlyValid = CloudEvent.deserializeEvent(ceFullStrictSerialized, { onlyValid: true })
assert(ceFullStrictDeserializedOnlyValid !== null)
console.log(`cloudEvent dump: ${T.dumpObject(ceFullStrictDeserializedOnlyValid, 'ceFullStrictDeserializedOnlyValid')}`)
console.log(`ce dump: ${T.dumpObject(ceFullStrictDeserializedOnlyValid, 'ceFullStrictDeserializedOnlyValid')}`)
// non default contenttype
const ceFullStrictOtherContentTypeDeserialized = CloudEvent.deserializeEvent(ceFullStrictOtherContentTypeSerialized, {
// decoder: (data) => { decoder: 'Sample' },
decodedData: { hello: 'world', year: 2019 },
decodedData: { hello: 'world', year: 2020 },
onlyValid: true

@@ -238,3 +299,3 @@ })

assert(CloudEvent.isCloudEvent(ceFullStrictOtherContentTypeDeserialized))
console.log(`cloudEvent dump: ${T.dumpObject(ceFullStrictOtherContentTypeDeserialized, 'ceFullStrictOtherContentTypeDeserialized')}`)
console.log(`ce dump: ${T.dumpObject(ceFullStrictOtherContentTypeDeserialized, 'ceFullStrictOtherContentTypeDeserialized')}`)

@@ -241,0 +302,0 @@ // then use (validate/send/store/etc) deserialized instances ...

{
"name": "cloudevent",
"version": "0.6.0",
"version": "0.7.0",
"description": "JavaScript/Node.js implementation of the CloudEvents standard format",

@@ -29,8 +29,8 @@ "main": "src/index",

"esdoc-node": "^1.0.5",
"standard": "^14.3.1",
"tap": "^14.8.2"
"standard": "^14.3.4",
"tap": "^14.10.8"
},
"peerDependencies": {},
"engines": {
"node": ">=8.16.2"
"node": ">=8.17.0"
},

@@ -50,3 +50,4 @@ "homepage": "https://github.com/smartiniOnGitHub/cloudevent.js#readme",

"author": "Sandro Martini <sandro.martini@gmail.com>",
"license": "Apache-2.0"
"license": "Apache-2.0",
"snyk": true
}

@@ -14,3 +14,3 @@ # cloudevent / cloudevent.js

Current release implements the v0.3 of the CloudEvents Spec.
Current release implements the v1.0 of the CloudEvents Spec.

@@ -50,3 +50,4 @@ The purpose of this library is to create instances of CloudEvents in a simple way

```js
// create some sample instances but without mandatory fields (for validation) ...
// create some sample instances but without mandatory fields (so not good for validation) ...
// note that errors will be thrown at instance creation only when strict mode is true
const ceEmpty = new CloudEvent() // create an empty CloudEvent instance (not valid for the validator, even in default case, when strict mode flag is disabled)

@@ -58,5 +59,5 @@ const ceMinimalMandatoryUndefinedNoStrict = new CloudEvent(undefined, undefined, undefined, undefined, { strict: false }) // expected success

const ceCommonOptions = {
time: new Date(),
time: new Date(), // same as default
datacontenttype: 'application/json',
schemaurl: 'http://my-schema.localhost.localdomain/v1/',
dataschema: 'http://my-schema.localhost.localdomain/v1/',
subject: 'subject',

@@ -66,8 +67,11 @@ strict: false // same as default

const ceCommonOptionsStrict = { ...ceCommonOptions, strict: true }
const ceCommonExtensions = { exampleExtension: 'value' }
const ceCommonExtensions = { exampleextension: 'value' }
const ceNamespace = 'com.github.smartiniOnGitHub.cloudeventjs.testevent-v1.0.0'
const ceServerUrl = '/test'
const ceCommonData = { hello: 'world', year: 2019 }
const ceCommonData = { hello: 'world', year: 2020, enabled: true }
const ceDataAsJSONString = '{ "hello": "world", "year": 2020, "enabled": true }'
const ceDataAsString = 'Hello World, 2020'
const ceDataEncoded = 'SGVsbG8gV29ybGQsIDIwMjA='
// create some sample minimal instances, good even for validation ...
// create a sample minimal instance ...
const ceMinimal = new CloudEvent('1', // id

@@ -79,4 +83,7 @@ ceNamespace, // type

// 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 ...
// When creating some instances with an undefined mandatory argument (handled by defaults),
// but with strict flag disabled success is expected, otherwise with strict flag enabled a failure is expected ...
// In JavaScript, null values are not handled as default values, only undefined values ...
// create a sample instance with most common attributes defined ...
const ceFull = new CloudEvent('1/full',

@@ -99,2 +106,12 @@ ceNamespace,

assert(!CloudEvent.isStrictEvent(ceFull)) // the same, but using static method
// create an instance with a JSON string as data
const ceFullStrictJSONTextData = new CloudEvent('2/full-strict-json-string-data',
ceNamespace,
ceServerUrl,
ceDataAsJSONString, // data
ceCommonOptionsStrict, // use strict options
ceCommonExtensions
)
assert(ceFullStrictJSONTextData !== null)
assert(ceFullStrictJSONTextData.isStrict)
// create an instance that wrap an Error

@@ -108,3 +125,3 @@ const error = new Error('sample error')

})
const ceErrorStrict = new CloudEvent('2/error-strict',
const ceErrorStrict = new CloudEvent('3/error-strict',
ceNamespace,

@@ -121,3 +138,3 @@ ceServerUrl,

// create an instance with a different content type
const ceFullStrictOtherContentType = new CloudEvent('3/full-strict-other-content-type',
const ceFullStrictOtherContentType = new CloudEvent('4/full-strict-other-content-type',
ceNamespace,

@@ -131,2 +148,24 @@ ceServerUrl,

assert(ceFullStrictOtherContentType.isStrict)
// create an instance with data as a string, but not strict (to validate it even in strict mode)
const ceFullTextData = new CloudEvent('5/no-strict-text-data',
ceNamespace,
ceServerUrl,
ceDataAsString, // data
ceCommonOptions, // use common options
ceCommonExtensions
)
assert(ceFullTextData !== null)
assert(!ceFullTextData.isStrict)
assert(ceFullTextData.payload === ceDataAsString) // returned data is transformed
// create an instance with data encoded in base64
const ceFullStrictBinaryData = new CloudEvent('6/full-strict-binary-data',
ceNamespace,
ceServerUrl,
null, // data
{ ...ceCommonOptionsStrict, datainbase64: ceDataEncoded }, // use common strict options, and set binary data in base64
ceCommonExtensions
)
assert(ceFullStrictBinaryData !== null)
assert(ceFullStrictBinaryData.isStrict)
assert(ceFullStrictBinaryData.payload === ceDataAsString) // returned data is transformed
```

@@ -166,3 +205,3 @@

// encoder: (data) => '<data "encoder"="sample" />',
encodedData: '<data "hello"="world" "year"="2019" />',
encodedData: '<data "hello"="world" "year"="2020" />',
onlyValid: true

@@ -172,3 +211,3 @@ })

// encoder: (data) => '<data "encoder"="sample" />',
encodedData: '<data "hello"="world" "year"="2019" />',
encodedData: '<data "hello"="world" "year"="2020" />',
onlyValid: true

@@ -200,3 +239,3 @@ })

// decoder: (data) => { decoder: 'Sample' },
decodedData: { hello: 'world', year: 2019 },
decodedData: { hello: 'world', year: 2020 },
onlyValid: true

@@ -221,3 +260,3 @@ })

Node.js 8.16.x or later.
Node.js 8 LTS (but recommended 8.17.0) or later.

@@ -228,7 +267,8 @@

Note that in this implementation there is even the ability to validate CloudEvent instances
in a stricter way, by setting to true the attribute 'strict' in options in constructor options;
or specify it during validation.
That attribute when set will be put in the 'extensions' standard attribute of a CloudEvent.
in a stricter way, by setting to true the attribute 'strict' in constructor options;
that attribute (when set) will be put in the extensions of the instance.
Otherwise you can specify it only during validation, in validation options.
You can find Code Documentation for the API of the library [here](https://smartiniongithub.github.io/cloudevent.js/).
You can find Code Documentation for the API of the library
[here](https://smartiniongithub.github.io/cloudevent.js/).

@@ -243,3 +283,3 @@ See the CloudEvents Specification [here](https://github.com/cloudevents/spec).

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) ,
(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

@@ -251,2 +291,6 @@ (like '-v1' or '/v1/' at the end).

but without dots, so like 'com_github_smartiniOnGitHub_cloudevent'.
Since v1.0 of the spec, some properties has been removed/simplified;
extension properties must be simple (no nested properties)
and must contain only lowercase letters and numbers in the name (and less than 20 chars in total);
so for example my strict extension now is 'strictvalidation' with a boolean value.

@@ -253,0 +297,0 @@

@@ -51,16 +51,16 @@ /*

* time (timestamp/date, default now),
* datacontentencoding (string) optional in most cases here,
* datacontenttype (string, default 'application/json') tell how the data attribute must be encoded,
* schemaurl (uri) optional,
* datainbase64 (string) base64 encoded value for the data (data attribute must not be present when this is defined),
* datacontenttype (string, default 'application/json') is the content type of the data attribute,
* dataschema (uri) optional, reference to the schema that data adheres to,
* subject (string) optional, describes the subject of the event in the context of the event producer (identified by source),
* strict (boolean, default false) tell if object instance will be validated in a more strict way
* @param {object} extensions optional, contains extension properties (recommended in nested objects) but if given any object must contain at least 1 property (key/value)
* @param {object} extensions optional, contains extension properties (each extension as a key/value property, and no nested objects) but if given any object must contain at least 1 property
* @throws {Error} if strict is true and id or type is undefined or null
* @throws {Error} if datacontentencoding is defined and data is not a string or if encoding is not 'base64'
* @throws {Error} if data and data_base64 are defined
*/
constructor (id, type, source, data, {
time = new Date(),
datacontentencoding,
datainbase64,
datacontenttype = CloudEvent.datacontenttypeDefault(),
schemaurl,
dataschema,
subject,

@@ -73,4 +73,7 @@ strict = false

if (!id || !type || !source) {
throw new Error('Unable to create CloudEvent instance, mandatory field missing')
throw new Error('Unable to create CloudEvent instance, mandatory attributes missing')
}
if (V.isDefinedAndNotNull(data) && V.isDefinedAndNotNull(datainbase64)) {
throw new Error('Unable to create CloudEvent instance, data and data_base64 attributes are exclusive')
}
}

@@ -120,12 +123,9 @@

this.specversion = this.constructor.version()
/**
* The content encoding for the data attribute
* for when the data field must be encoded as a string.
* This must be set if the data attribute contains string-encoded binary data,
* otherwise it must not be set.
* As (arbitrary) limitation, only 'base64' encoding is supported here.
* The real event data, but encoded in base64 format.
* @type {string}
* @private
*/
this.datacontentencoding = datacontentencoding
this.data_base64 = datainbase64
/**

@@ -138,2 +138,8 @@ * The MIME Type for the encoding of the data attribute, when serialized.

/**
* The URI of the schema for event data, if any.
* @type {uri}
* @private
*/
this.dataschema = dataschema
/**
* The event timestamp.

@@ -147,8 +153,2 @@ * Copy the original object to avoid changing objects that could be shared.

/**
* The URL of schema for the event, if any.
* @type {uri}
* @private
*/
this.schemaurl = schemaurl
/**
* The subject of the event in the context of the event producer.

@@ -184,3 +184,3 @@ * @type {string}

static version () {
return '0.3'
return '1.0'
}

@@ -242,4 +242,4 @@

}
if (V.isDefinedAndNotNull(event.com_github_smartiniOnGitHub_cloudevent)) {
return event.com_github_smartiniOnGitHub_cloudevent.strict === true
if (V.isDefinedAndNotNull(event.strictvalidation)) {
return event.strictvalidation === true
} else {

@@ -268,4 +268,3 @@ return false

}
obj.com_github_smartiniOnGitHub_cloudevent = {}
obj.com_github_smartiniOnGitHub_cloudevent.strict = strict
obj.strictvalidation = strict
}

@@ -283,2 +282,3 @@

* @throws {Error} if obj is undefined or null
* @throws {Error} if strictvalidation property is undefined or null
*/

@@ -289,11 +289,7 @@ static getStrictExtensionOfEvent (obj = {}) {

}
const myExtensions = obj.com_github_smartiniOnGitHub_cloudevent || {}
if (!V.isObjectPlain(myExtensions)) {
throw new TypeError('The property com_github_smartiniOnGitHub_cloudevent is not an object instance')
const myExtensionStrict = obj.strictvalidation || false
if (!V.isBoolean(myExtensionStrict)) {
throw new TypeError("Extension property 'strictvalidation' has not a boolean value")
}
const strict = myExtensions.strict || false
if (!V.isBoolean(strict)) {
throw new TypeError('The given strict flag is not a boolean instance')
}
return strict
return myExtensionStrict
}

@@ -308,3 +304,3 @@

* @param {object} [obj={}] the object to fill, that will be enhanced inplace
* @param {object} [extensions=null] the extensions to fill (maybe already populated)
* @param {object} [extensions=null] the extensions to fill (each extension as a key/value property, and no nested properties)
* @throws {TypeError} if obj is not an object, or strict is not a flag

@@ -367,6 +363,8 @@ * @throws {Error} if obj is undefined or null, or strict is undefined or null

* @param {!object} event the CloudEvent to validate
* @param {object} [options={}] containing: strict (boolean, default false) to validate it in a more strict way
* @param {object} [options={}] containing:
* strict (boolean, default false) to validate it in a more strict way,
* dataschemavalidator (function(data, dataschema) boolean, optional) a function to validate data of current CloudEvent instance with its dataschema
* @return {object[]} an array of (non null) validation errors, or at least an empty array
*/
static validateEvent (event, { strict = false } = {}) {
static validateEvent (event, { strict = false, dataschemavalidator = null } = {}) {
if (V.isUndefinedOrNull(event)) {

@@ -387,4 +385,4 @@ return [new Error('CloudEvent undefined or null')]

ve.push(V.ensureIsStringNotEmpty(event.source, 'source'))
if (V.isDefinedAndNotNull(event.schemaurl)) {
ve.push(V.ensureIsStringNotEmpty(event.schemaurl, 'schemaurl'))
if (V.isDefinedAndNotNull(event.dataschema)) {
ve.push(V.ensureIsStringNotEmpty(event.dataschema, 'dataschema'))
}

@@ -394,4 +392,7 @@ if (V.isDefinedAndNotNull(event.subject)) {

}
if (V.isDefinedAndNotNull(event.datacontentencoding)) {
ve.push(V.ensureIsStringNotEmpty(event.datacontentencoding, 'datacontentencoding'))
if (V.isDefinedAndNotNull(event.data_base64)) {
ve.push(V.ensureIsStringNotEmpty(event.data_base64, 'data_base64'))
if (V.isDefinedAndNotNull(event.data)) {
ve.push(new Error('data and data_base64 attributes are exclusive'))
}
}

@@ -403,12 +404,18 @@

if (V.isDefinedAndNotNull(event.data)) {
if (V.isDefinedAndNotNull(event.datacontentencoding)) {
// ensure data is a string in this case
ve.push(V.ensureIsString(event.data, 'data'))
} else if (event.datacontenttype !== CloudEvent.datacontenttypeDefault()) {
if (event.datacontenttype === CloudEvent.datacontenttypeDefault()) {
// if it's a string, ensure it's a valid JSON representation,
// otherwise ensure data is a plain object or collection, but not a string in this case
if (V.isString(event.data)) {
try {
JSON.parse(event.data)
} catch (e) {
ve.push(new Error('data is not a valid JSON string'))
}
} else {
ve.push(V.ensureIsObjectOrCollectionNotString(event.data, 'data'))
}
} else {
// ensure data is a plain object or collection, or even a string in this case
// because in serialization/deserialization some validation can occur on the transformed object
ve.push(V.ensureIsObjectOrCollectionOrString(event.data, 'data'))
} else {
// ensure data is a plain object or collection, but not a string in this case
ve.push(V.ensureIsObjectOrCollectionNotString(event.data, 'data'))
}

@@ -419,3 +426,11 @@ }

ve.push(V.ensureIsStringNotEmpty(event.datacontenttype, 'datacontenttype'))
ve.push(V.ensureIsURI(event.schemaurl, null, 'schemaurl'))
ve.push(V.ensureIsURI(event.dataschema, null, 'dataschema'))
if (V.isFunction(dataschemavalidator)) {
try {
const success = dataschemavalidator(event.data, event.dataschema)
if (success === false) throw Error()
} catch (e) {
ve.push(new Error('data does not respect the dataschema for the given validator'))
}
}
if (V.isDefinedAndNotNull(event.extensions)) {

@@ -425,2 +440,7 @@ // get extensions via its getter

// error for extensions defined but empty (without properties), moved in constructor
// then check for each extension name and value
for (const [key, value] of Object.entries(event.extensions)) {
if (!CloudEvent.isExtensionNameValid(key)) ve.push(new Error(`extension name '${key}' not valid`))
if (!CloudEvent.isExtensionValueValid(value)) ve.push(new Error(`extension value '${value}' not valid for extension '${key}'`))
}
}

@@ -439,7 +459,9 @@ }

* @param {!object} event the CloudEvent to validate
* @param {object} [options={}] containing: strict (boolean, default false) to validate it in a more strict way
* @param {object} [options={}] containing:
* strict (boolean, default false) to validate it in a more strict way,
* dataschemavalidator (function(data, dataschema) boolean, optional) a function to validate data of current CloudEvent instance with its dataschema
* @return {boolean} true if valid, otherwise false
*/
static isValidEvent (event, { strict = false } = {}) {
const validationErrors = CloudEvent.validateEvent(event, { strict })
static isValidEvent (event, { strict = false, dataschemavalidator = null } = {}) {
const validationErrors = CloudEvent.validateEvent(event, { strict, dataschemavalidator })
const size = V.getSize(validationErrors)

@@ -488,7 +510,2 @@ return (size === 0)

switch (key) {
case 'data':
// return data as is, or encoded or nothing (if not supported)
if (V.isUndefinedOrNull(event.datacontentencoding)) return value
if (event.datacontentencoding === 'Base64') return T.stringToBase64(this.data)
else return undefined
case 'extensions':

@@ -550,2 +567,3 @@ // filtering out top level extensions (if any)

if (!V.isObject(parsed) || V.isArray(parsed)) throw new Error(`Wrong deserialized data: '${ser}' must represent an object and not an array or a string or other.`)
if (!V.isStringNotEmpty(parsed.specversion) || parsed.specversion !== CloudEvent.version()) throw new Error(`Unable to deserialize, not compatible specversion: got '${parsed.specversion}' expected '${CloudEvent.version()}'.`)

@@ -555,9 +573,2 @@ const strict = CloudEvent.getStrictExtensionOfEvent(parsed)

if (V.isDefinedAndNotNull(parsed.datacontentencoding)) {
if (V.isStringNotEmpty(parsed.data)) {
// decode the given data
if (parsed.datacontentencoding === 'Base64') parsed.data = T.stringFromBase64(parsed.data)
}
}
// fill a new CludEvent instance with parsed data

@@ -570,5 +581,5 @@ const ce = new CloudEvent(parsed.id,

time: T.timestampFromString(parsed.time, timezoneOffset),
datacontentencoding: parsed.datacontentencoding,
datainbase64: parsed.data_base64,
datacontenttype: parsed.datacontenttype,
schemaurl: parsed.schemaurl,
dataschema: parsed.dataschema,
subject: parsed.subject,

@@ -628,2 +639,35 @@ strict: strict

/**
* Tell if the given extension name is valid, to respect the spec.
* Should not be used outside CloudEvent.
*
* @private
* @static
* @param {!object|!string} name the name to check
* @return {boolean} true if it's an extension name valid, otherwise false
* @throws {TypeError} if name is not a string
* @throws {Error} if name is undefined or null
*/
static isExtensionNameValid (name) {
if (V.isUndefinedOrNull(name)) throw new Error('Extension name undefined or null')
if (!V.isString(name)) throw new TypeError('Extension name must be a string')
return name.match(/^[a-z0-9]{1,20}$/)
}
/**
* Tell if the given extension value is valid, to respect the spec.
* Should not be used outside CloudEvent.
*
* @private
* @static
* @param {!string|!boolean|!number} value the object to check
* @return {boolean} true if it's an extension value valid, otherwise false
* @throws {Error} if value is undefined
*/
static isExtensionValueValid (value) {
if (V.isUndefined(value)) throw new Error('Extension value undefined')
if (!V.isString(value) && !V.isBoolean(value) && !V.isNumber(value)) return false
return true
}
/**
* Get the JSON Schema for a CloudEvent.

@@ -658,10 +702,9 @@ * Note that it's not used in standard serialization to JSON,

datacontenttype: { type: 'string' },
// data: { type: ['object', 'string'] },
data: { type: ['object', 'string'] },
data_base64: { type: 'string' },
dataschema: { type: 'string', format: 'uri' },
// time: { type: 'string', format: 'date-time' },
schemaurl: { type: 'string', format: 'uri-reference' },
subject: { type: 'string', minLength: 1 }
},
required: [
'specversion', 'id', 'type', 'source'
],
required: ['specversion', 'id', 'type', 'source'],
additionalProperties: true // to handle data, and maybe other (non-standard) properties (extensions)

@@ -690,7 +733,9 @@ }

*
* @param {object} [options={}] containing: strict (boolean, default false) to validate it in a more strict way
* @param {object} [options={}] containing:
* strict (boolean, default false) to validate it in a more strict way,
* dataschemavalidator (function(data, dataschema) boolean, optional) a function to validate data of current CloudEvent instance with its dataschema
* @return {object[]} an array of (non null) validation errors, or at least an empty array
*/
validate ({ strict = false } = {}) {
return this.constructor.validateEvent(this, { strict })
validate ({ strict = false, dataschemavalidator = null } = {}) {
return this.constructor.validateEvent(this, { strict, dataschemavalidator })
}

@@ -703,7 +748,9 @@

*
* @param {object} [options={}] containing: strict (boolean, default false) to validate it in a more strict way
* @param {object} [options={}] containing:
* strict (boolean, default false) to validate it in a more strict way,
* dataschemavalidator (function(data, dataschema) boolean, optional) a function to validate data of current CloudEvent instance with its dataschema
* @return {boolean} true if valid, otherwise false
*/
isValid ({ strict = false } = {}) {
return this.constructor.isValidEvent(this, { strict })
isValid ({ strict = false, dataschemavalidator = null } = {}) {
return this.constructor.isValidEvent(this, { strict, dataschemavalidator })
}

@@ -746,19 +793,52 @@

/**
* Getter method to return a copy of CloudEvent data attribute,
* or original data payload.
* Getter method to return a copy of CloudEvent data attribute (or data_base64 if defined),
* but transformed/decoded if possible.
*
* See {@link CloudEvent.data}.
* See {@link CloudEvent.data}, {@link CloudEvent.data_base64}.
*
* @type {(object|Map|Set)}
* @type {(object|Map|Set|string)}
*/
get payload () {
if (V.isString(this.data)) {
// handle an edge case: if data is a String, I need to clone in a different way ...
return this.data.slice()
if (V.isDefinedAndNotNull(this.data) && !V.isDefinedAndNotNull(this.data_base64)) {
if (this.isDatacontenttypeJSON) {
try {
return JSON.parse(this.data)
} catch (e) {
// fallback in case of bad data (not parseable)
if (V.isString(this.data)) {
return this.data.slice()
} else {
return { ...this.data }
}
}
} else if (V.isString(this.data)) {
// handle an edge case: if data is a String, I need to clone in a different way ...
return this.data.slice()
} else {
return { ...this.data }
}
} else if (V.isDefinedAndNotNull(this.data_base64)) {
return T.stringFromBase64(this.data_base64)
}
// else
return { ...this.data }
// else return the same empty object
return this.data
}
/**
* Getter method to tell if CloudEvent data is text or binary,
* or unknown if not clear.
*
* @type {string}
*/
get dataType () {
if (V.isDefinedAndNotNull(this.data) && !V.isDefinedAndNotNull(this.data_base64)) {
return 'Text'
} else if (V.isDefinedAndNotNull(this.data_base64)) {
return 'Binary'
}
// else return an unknown/wrong data type
return 'Unknown'
}
/**
* Getter method to return a copy of CloudEvent extensions.

@@ -811,6 +891,6 @@ *

'id', 'type', 'source', 'data',
'time', 'datacontentencoding', 'datacontenttype',
'schemaurl', 'subject'
'time', 'data_base64', 'datacontenttype',
'dataschema', 'subject'
]
module.exports = CloudEvent

@@ -307,5 +307,5 @@ /*

time: i.time,
datacontentencoding: i.datacontentencoding,
data_base64: i.data_base64,
datacontenttype: i.datacontenttype,
schemaurl: i.schemaurl,
dataschema: i.dataschema,
subject: i.subject,

@@ -312,0 +312,0 @@ strict: CloudEvent.getStrictExtensionOfEvent(i) || options.strict

@@ -225,3 +225,3 @@ /*

static isFunction (arg) {
return (typeof arg === 'function')
return (Validator.isDefinedAndNotNull(arg) && (typeof arg === 'function'))
}

@@ -364,8 +364,8 @@

} else {
// simple check if it's an URI (or better, a relative URL)
if (arg.startsWith('/')) {
// simple check if it's an URI (or better: a relative URL, or a full URI with scheme etc)
const uriRegex = /^(\w+:|\/)/ // or /^(\w+:|\/)(.*)$/ for full match
if (uriRegex.test(arg)) {
return true
}
try {
// return (new URL(arg) !== null)
const u = new url.URL(arg)

@@ -372,0 +372,0 @@ return (u !== null)

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc