Merge pull request #5 from cloudevents/develop

Develop
This commit is contained in:
Fabio José 2019-01-18 23:57:55 -02:00 committed by GitHub
commit 14eacd5246
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 684 additions and 235 deletions

View File

@ -1,29 +1,31 @@
language: node_js
node_js:
- 8
- 7
- 6
- 8
- 7
- 6
cache: npm
jobs:
include:
- stage: github release
node_js: "6"
deploy:
provider: releases
api_key:
secure: "ls/IjZdRpFZlEQsZrsmXn7h7QTZuM8x4gZq3r75sOyTWcmKgZLN27hYCtk8SPcuNbt+ZA3otQEQJvDuGTCAwtbU4lxQjfXswP9M/om01hf3J7uTcjtol4XOsmBFqMCktW94pVH4U7Q18IHeP5JBnlfLzAY/YifRKKNWNrsI6bbnfcGgsFJYvICwKL5LEj7bxtJk156lBBJm9TscMX48BFsUBvnCNTDEBYNaaGkoCz6DPM0Da7QPF5exHcNiiF9SoR60WeGI1q+MdZyE+1AG0VpUp7sMxJafXSBbgYquPEZmG9ScZbkVyWP7ps3sgkqDkxtH4kNe9zF4PySRYfxYKJ03ECwbSmj9gxsIc8o2zhrLFinmHydLxoOEh5EygB2euekgMhoEKL0kA8bteaaqmD+3sna8MbXG4HhvIrEAspNtOFZyUm/SmgvXXxaKiDtwTw/5CvPCc7VH51NuC5QZi0UehLzatDpDNsj/ffMwDp5F4SBIZgUUmmIWfnAODNGwSwBKxdPVS3etkTeiBxerw2uzC6qjNW1QJyb9s+iU3rC59IEAuq6u4ymv3caDIHLnJbCMHRHQoIbq86oErqb8DhH6KrTlBnwlGBpUVhdpYMt0QX2Uncu9uHMBZ2CQNZ819PJa4QWvc1Ixoj3auKqvoMfPNQFOskMWnrnxkOokyPZg="
skip_cleanup: true
on:
tags: true
- stage: npm release
node_js: "6"
deploy:
provider: npm
email: fabiojose@gmail.com
api_key:
secure: "o5aF53FTPUSiJBbCZ/anBWQCgEJCctpxuTgGJbO1NpiheOM/xENiSmv+n2a5sGrhhqT0h7k15mE/ZgtL8TnM+45AHOg3EGez5JoR1XMIXnSeCno1GFK4waHDcEn3eLW9P35r1S5/RMTqbEUvqpyK/fzVZ4ecyh9t7dVvJV8MyQGo+r+oO3SLYEIt7YC6vZRh+dV3cK8jr7MHkHmQfZ6tZrALMKsj6QNTUtmk+IU52WHi4oe1iPuypS5dlaVdmanX7ZRtC7gR0Dko2/wja+DPOAKgG/S0aS794cxal7P5k/K34mvqT8iaCl4vN5uIcRsipgsprIahk2G2NgnIVCetBda9LhpMNUdn3j+v4T0lx3jiqP1eq01nk8YFpTV4Xz9VlYHK/E6NYQhUmd7N6WO9vXmOEDGBvWrDfQ1QMx+/TM9r3vzK9ps3sjkDFaAtJ2ZQ0pvFMEQTaLKak24ntWltSWZKvxdjYnS+bcfyIQQGagvqgZsnkKzeudO9N9Atp4OGcst9CAvvykDsfmLlARAiyvpuDVyUivuaOlCB9J7VBt1sbBfsiHpnJcSsMVz1OMRX5EGewbla530guoePhjTUDVit3NyUMz3ZQQTN9VSK3tA+NLyR0Ex8Oel+byHJDYyf+36GCDvoXagaPUVk5M5BINiCw2IWhxDgRGrcEp9JIUI="
skip_cleanup: true
on:
tags: true
- stage: github release
node_js: '6'
deploy:
provider: releases
api_key:
secure: ls/IjZdRpFZlEQsZrsmXn7h7QTZuM8x4gZq3r75sOyTWcmKgZLN27hYCtk8SPcuNbt+ZA3otQEQJvDuGTCAwtbU4lxQjfXswP9M/om01hf3J7uTcjtol4XOsmBFqMCktW94pVH4U7Q18IHeP5JBnlfLzAY/YifRKKNWNrsI6bbnfcGgsFJYvICwKL5LEj7bxtJk156lBBJm9TscMX48BFsUBvnCNTDEBYNaaGkoCz6DPM0Da7QPF5exHcNiiF9SoR60WeGI1q+MdZyE+1AG0VpUp7sMxJafXSBbgYquPEZmG9ScZbkVyWP7ps3sgkqDkxtH4kNe9zF4PySRYfxYKJ03ECwbSmj9gxsIc8o2zhrLFinmHydLxoOEh5EygB2euekgMhoEKL0kA8bteaaqmD+3sna8MbXG4HhvIrEAspNtOFZyUm/SmgvXXxaKiDtwTw/5CvPCc7VH51NuC5QZi0UehLzatDpDNsj/ffMwDp5F4SBIZgUUmmIWfnAODNGwSwBKxdPVS3etkTeiBxerw2uzC6qjNW1QJyb9s+iU3rC59IEAuq6u4ymv3caDIHLnJbCMHRHQoIbq86oErqb8DhH6KrTlBnwlGBpUVhdpYMt0QX2Uncu9uHMBZ2CQNZ819PJa4QWvc1Ixoj3auKqvoMfPNQFOskMWnrnxkOokyPZg=
skip_cleanup: true
on:
tags: true
- stage: npm release
node_js: '6'
deploy:
provider: npm
email: fabiojose@gmail.com
api_key:
secure: o5aF53FTPUSiJBbCZ/anBWQCgEJCctpxuTgGJbO1NpiheOM/xENiSmv+n2a5sGrhhqT0h7k15mE/ZgtL8TnM+45AHOg3EGez5JoR1XMIXnSeCno1GFK4waHDcEn3eLW9P35r1S5/RMTqbEUvqpyK/fzVZ4ecyh9t7dVvJV8MyQGo+r+oO3SLYEIt7YC6vZRh+dV3cK8jr7MHkHmQfZ6tZrALMKsj6QNTUtmk+IU52WHi4oe1iPuypS5dlaVdmanX7ZRtC7gR0Dko2/wja+DPOAKgG/S0aS794cxal7P5k/K34mvqT8iaCl4vN5uIcRsipgsprIahk2G2NgnIVCetBda9LhpMNUdn3j+v4T0lx3jiqP1eq01nk8YFpTV4Xz9VlYHK/E6NYQhUmd7N6WO9vXmOEDGBvWrDfQ1QMx+/TM9r3vzK9ps3sjkDFaAtJ2ZQ0pvFMEQTaLKak24ntWltSWZKvxdjYnS+bcfyIQQGagvqgZsnkKzeudO9N9Atp4OGcst9CAvvykDsfmLlARAiyvpuDVyUivuaOlCB9J7VBt1sbBfsiHpnJcSsMVz1OMRX5EGewbla530guoePhjTUDVit3NyUMz3ZQQTN9VSK3tA+NLyR0Ex8Oel+byHJDYyf+36GCDvoXagaPUVk5M5BINiCw2IWhxDgRGrcEp9JIUI=
skip_cleanup: true
on:
tags: true
env:
global:
secure: t0A5/Fk1Qj8WkAk0ZuQqpFjrpINV6gfL+d1fXgq03EOAG/7FEyyz+AKkYaLT6avp26VWBzLgEoWC3RNmWD0v1/Ruckb95YpQcb5e4JotAce1ZsHgGTgx0UO146tkyGvXBw6MmO2nX2O/sHzkmyR6rlKkBi9LEKokJ9OFd6fi9nNtksgUDxkqNlNTu100fIQAV2RcN47C6iUx+gJIa+H/8QX/Cz02MyheXLe8a763wMQapz5GHrk2KuVY6FpylcAlSi2so+PjEGfKq3MWaQnTPkevkRDLtGcecVtFAq/0VbvoKc97PHoVT0x+nf48k1gj2VnQtYj6EVB74yRvqM9KkNOsfAQ0z9zF5wXMRs11SZywSViLQsnD9Ue6eYbYmodOKn4DFlLtoRyLBUspzLuoL76lERGe2cHU+Ebz2Nb9jL88o+SjfGrSJQEJU7SLZLbzJ7T/3SspWcAlo+Fo9UTCOB4/yL22Yge/SWQkdd1orBhohpjpyrU9Z1+IRvVoU1EICr04zSFUwEwn6Yxbt0ArgTZBEf11bf+YpCo+rBXNAd+XbZ79PGOEppFb+Hxrt9i1S1RnesDJnwC0k7cswU55Rv5gcNCo9lC+N4ZwS5y+5r6DsBfB+12YdsFORFyNbClECro1ODv4STf3rBBnjL8+ziPFjP4d4OwiGY+vG8bvLXY=
script: npm run coverage

View File

@ -1,10 +1,12 @@
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/bd66e7c52002481993cd6d610534b0f7)](https://www.codacy.com/app/fabiojose/sdk-javascript?utm_source=github.com&utm_medium=referral&utm_content=cloudevents/sdk-javascript&utm_campaign=Badge_Grade)
[![Codacy Badge](https://api.codacy.com/project/badge/Coverage/bd66e7c52002481993cd6d610534b0f7)](https://www.codacy.com/app/fabiojose/sdk-javascript?utm_source=github.com&utm_medium=referral&utm_content=cloudevents/sdk-javascript&utm_campaign=Badge_Coverage)
[![Build Status](https://travis-ci.org/cloudevents/sdk-javascript.svg?branch=master)](https://travis-ci.org/cloudevents/sdk-javascript)
# sdk-javascript
Javascript SDK for CloudEvents
> This is a WIP
Official CloudEvents' SDK for JavaScript.
<img src="https://raw.githubusercontent.com/cncf/artwork/master/cloudevents/horizontal/color/cloudevents-horizontal-color.png" width="300" height="58" alt="CloudEvents logo">
## Installation
@ -12,18 +14,19 @@ This CloudEvents SDK requires nodejs 6.11+
### Nodejs
```
```sh
npm install cloudevents-sdk
```
## Specification Support
These are the supported specifications by this version.
| **Specifications** | **v0.1** | **v0.2** |
|----------------------------|----------|----------|
| CloudEvents | yes | yes |
| HTTP Transport Binding | yes | yes |
| JSON Event Format | yes | yes |
| **Specifications** | **v0.1** | **v0.2** |
|---------------------------------------|----------|----------|
| CloudEvents | yes | yes |
| HTTP Transport Binding - Structured | yes | yes |
| HTTP Transport Binding - Binary | yes | yes |
| JSON Event Format | yes | yes |
## How to use
@ -39,7 +42,7 @@ Cloudevent(spec, format);
```
### How to construct instances?
### Usage
```js
var Cloudevent = require("cloudevents-sdk");
@ -59,7 +62,8 @@ cloudevent01
.source("urn:event:from:myapi/resourse/123");
/*
* Backward compatibility by injecting methods from spec implementation to Cloudevent
* Backward compatibility to spec 0.1 by injecting methods from spec implementation
* to Cloudevent
*/
cloudevent01
.eventTypeVersion("1.0");
@ -69,7 +73,7 @@ cloudevent01
* - Spec 0.2
* - JSON Format 0.1
*/
var cloudevent02 = new Cloudevent(Cloudevent.specs['0.2']);
var cloudevent02 = new Cloudevent(Cloudevent.specs["0.2"]);
/*
* Different specs, but the same API.
@ -80,23 +84,27 @@ cloudevent02
```
### How to get the formatted payload?
#### Formatting
```js
var Cloudevent = require("cloudevents-sdk");
var cloudevent = new Cloudevent()
.type("com.github.pull.create")
.source("urn:event:from:myapi/resourse/123");
/*
* Creates an instance with default spec and format
*/
var cloudevent =
new Cloudevent()
.type("com.github.pull.create")
.source("urn:event:from:myapi/resourse/123");
/*
* Format the payload and return it.
* Format the payload and return it
*/
var formatted = cloudevent.format();
```
### How to emit an event?
#### Emitting
```js
var Cloudevent = require("cloudevents-sdk");
@ -108,12 +116,12 @@ var cloudevent = new Cloudevent()
// The binding configuration using POST
var config = {
method: 'POST',
url : 'https://mywebhook.com'
method: "POST",
url : "https://myserver.com"
};
// The binding instance
var binding = Cloudevent.bindings['http-structured0.1'](config);
var binding = Cloudevent.bindings["http-structured0.1"](config);
// Emit the event using Promise
binding.emit(cloudevent)
@ -134,45 +142,20 @@ binding.emit(cloudevent)
├── lib
│   ├── bindings
│   │   └── http
│   │   └── structured_0_1.js
│   ├── cloudevent.js
│   ├── format
│   │   └── json_0_1.js
│   └── specs
│   ├── spec_0_1.js
│   └── spec_0_2.js
├── LICENSE
├── package.json
├── README.md
└── test
├── cloudevent_spec_0_1.js
├── cloudevent_spec_0_2.js
└── http_binding_0_1.js
```
* `index.js`: library exports
* `lib/bindings`: every binding implementation goes here
* `lib/bindings/http`: every http binding implementation goes here
* `lib/bindings/http/structured_0_1.js`: implementation of structured HTTP Binding
* `lib/cloudevent.js`: implementation of Cloudevent, an interface
* `lib/format/`: every format implementation goes here
* `lib/format/json_0_1.js`: implementation for JSON formatting [version 0.1](https://github.com/cloudevents/spec/blob/v0.1/json-format.md)
* `lib/specs/`: every spec implementation goes here
* `lib/specs/spec_0_1.js`: implementation for spec [version 0.1](https://github.com/cloudevents/spec/blob/v0.1/spec.md)
* `lib/specs/spec_0_2.js`: implementation for spec [version 0.2](https://github.com/cloudevents/spec/blob/v0.2/spec.md)
* `test/cloudevent_spec_0_1.js`: unit testing for spec 0.1
* `test/cloudevent_spec_0_2.js`: unit testing for spec 0.2
- `index.js`: library exports
- `lib/bindings`: every binding implementation goes here
- `lib/bindings/http`: every http binding implementation goes here
- `lib/cloudevent.js`: implementation of Cloudevent, an interface
- `lib/format/`: every format implementation goes here
- `lib/specs/`: every spec implementation goes here
## Unit Testing

View File

@ -1,4 +1,3 @@
var Cloudevent = require('./lib/cloudevent.js');
var Cloudevent = require("./lib/cloudevent.js");
module.exports = Cloudevent;

View File

@ -0,0 +1,42 @@
var axios = require("axios");
function HTTPBinary(configuration){
this.config = configuration;
this.config["headers"] = {
"Content-Type":"application/cloudevents+json; charset=utf-8"
};
}
HTTPBinary.prototype.emit = function(cloudevent){
// Create new request object
var _config = JSON.parse(JSON.stringify(this.config));
// Always set stuff in _config
var _headers = _config["headers"];
if(cloudevent.getContenttype()) {
_headers["Content-Type"] = cloudevent.getContenttype();
}
_headers["CE-EventType"] = cloudevent.getType();
if(cloudevent.getEventTypeVersion()) {
_headers["CE-EventTypeVersion"] = cloudevent.getEventTypeVersion();
}
_headers["CE-CloudEventsVersion"] = cloudevent.getSpecversion();
_headers["CE-Source"] = cloudevent.getSource();
_headers["CE-EventID"] = cloudevent.getId();
if(cloudevent.getTime()) {
_headers["CE-EventTime"] = cloudevent.getTime();
}
_headers["CE-SchemaURL"] = cloudevent.getSchemaurl();
// Set the cloudevent payload
_config["data"] = cloudevent.format().data;
// Return the Promise
return axios.request(_config);
};
module.exports = HTTPBinary;

View File

@ -0,0 +1,46 @@
var axios = require("axios");
var empty = require("is-empty");
function HTTPBinary(configuration){
this.config = configuration;
this.config["headers"] = {
"Content-Type":"application/cloudevents+json; charset=utf-8"
};
}
HTTPBinary.prototype.emit = function(cloudevent){
// Create new request object
var _config = JSON.parse(JSON.stringify(this.config));
// Always set stuff in _config
var _headers = _config["headers"];
if(cloudevent.getContenttype()) {
_headers["Content-Type"] = cloudevent.getContenttype();
}
_headers["ce-type"] = cloudevent.getType();
_headers["ce-specversion"] = cloudevent.getSpecversion();
_headers["ce-source"] = cloudevent.getSource();
_headers["ce-id"] = cloudevent.getId();
if(cloudevent.getTime()) {
_headers["ce-time"] = cloudevent.getTime();
}
_headers["ce-schemaurl"] = cloudevent.getSchemaurl();
// Set the cloudevent payload
_config["data"] = cloudevent.format().data;
// Have extensions?
var exts = cloudevent.getExtensions();
for(var ext in exts){
_headers["ce-" + ext] = exts[ext];
}
// Return the Promise
return axios.request(_config);
};
module.exports = HTTPBinary;

View File

@ -3,8 +3,8 @@ var axios = require("axios");
function HTTPStructured(configuration){
this.config = configuration;
this.config['headers'] = {
'Content-Type':'application/cloudevents+json; charset=utf-8'
this.config["headers"] = {
"Content-Type":"application/cloudevents+json; charset=utf-8"
};
}
@ -14,11 +14,10 @@ HTTPStructured.prototype.emit = function(cloudevent){
var _config = JSON.parse(JSON.stringify(this.config));
// Set the cloudevent payload
_config['data'] = cloudevent.format();
_config["data"] = cloudevent.format();
// Return the Promise
return axios.request(_config);
}
};
module.exports = HTTPStructured;

View File

@ -0,0 +1,23 @@
var axios = require("axios");
function HTTPStructured(configuration){
this.config = configuration;
this.config["headers"] = {
"Content-Type":"application/cloudevents+json; charset=utf-8"
};
}
HTTPStructured.prototype.emit = function(cloudevent){
// Create new request object
var _config = JSON.parse(JSON.stringify(this.config));
// Set the cloudevent payload
_config["data"] = cloudevent.format();
// Return the Promise
return axios.request(_config);
};
module.exports = HTTPStructured;

View File

@ -1,7 +1,10 @@
var Spec_0_1 = require('./specs/spec_0_1.js');
var Spec_0_2 = require('./specs/spec_0_2.js');
var JSONFormatter_0_1 = require('./formats/json_0_1.js');
var HTTPStructured_0_1 = require('./bindings/http/structured_0_1.js');
var Spec01 = require("./specs/spec_0_1.js");
var Spec02 = require("./specs/spec_0_2.js");
var JSONFormatter01 = require("./formats/json_0_1.js");
var HTTPStructured01 = require("./bindings/http/structured_0_1.js");
var HTTPStructured02 = require("./bindings/http/structured_0_2.js");
var HTTPBinary01 = require("./bindings/http/binary_0_1.js");
var HTTPBinary02 = require("./bindings/http/binary_0_2.js");
/*
* Class created using the Builder Design Pattern.
@ -9,8 +12,11 @@ var HTTPStructured_0_1 = require('./bindings/http/structured_0_1.js');
* https://en.wikipedia.org/wiki/Builder_pattern
*/
function Cloudevent(_spec, _formatter){
this.spec = (_spec) ? new _spec(Cloudevent) : new Spec_0_1(Cloudevent);
this.formatter = (_formatter) ? _formatter : new JSONFormatter_0_1();
this.spec = (_spec) ? new _spec(Cloudevent) : new Spec01(Cloudevent);
this.formatter = (_formatter) ? _formatter : new JSONFormatter01();
// The map of extensions
this.extensions = {};
}
/*
@ -22,72 +28,115 @@ Cloudevent.prototype.format = function(){
// Then, format
return this.formatter.format(this.spec.payload);
}
};
Cloudevent.prototype.toString = function(){
return this.formatter.toString(this.spec.payload);
}
};
Cloudevent.prototype.type = function(type){
this.spec.type(type);
return this;
}
};
Cloudevent.prototype.getType = function() {
return this.spec.getType();
};
Cloudevent.prototype.getSpecversion = function() {
return this.spec.getSpecversion();
};
Cloudevent.prototype.source = function(_source){
this.spec.source(_source);
return this;
}
};
Cloudevent.prototype.getSource = function(){
return this.spec.getSource();
};
Cloudevent.prototype.id = function(_id){
this.spec.id(_id);
return this;
}
};
Cloudevent.prototype.getId = function() {
return this.spec.getId();
};
Cloudevent.prototype.time = function(_time){
this.spec.time(_time);
return this;
}
};
Cloudevent.prototype.getTime = function() {
return this.spec.getTime();
};
Cloudevent.prototype.schemaurl = function(_schemaurl) {
this.spec.schemaurl(_schemaurl);
return this;
}
};
Cloudevent.prototype.getSchemaurl = function() {
return this.spec.getSchemaurl();
};
Cloudevent.prototype.contenttype = function(_contenttype){
this.spec.contenttype(_contenttype);
return this;
}
};
Cloudevent.prototype.getContenttype = function() {
return this.spec.getContenttype();
};
Cloudevent.prototype.data = function(_data) {
this.spec.data(_data);
return this;
}
};
Cloudevent.prototype.getData = function() {
return this.spec.getData();
};
Cloudevent.prototype.addExtension = function(key, value){
this.spec.addExtension(key, value);
// Stores localy
this.extensions[key] = value;
return this;
}
};
Cloudevent.prototype.getExtensions = function() {
return this.extensions;
};
/*
* Export the specs
*/
Cloudevent.specs = {
'0.1': Spec_0_1,
'0.2': Spec_0_2
"0.1": Spec01,
"0.2": Spec02
};
/*
* Export the formats
*/
Cloudevent.formats = {
'json' : JSONFormatter_0_1,
'json0.1': JSONFormatter_0_1
"json" : JSONFormatter01,
"json0.1": JSONFormatter01
};
Cloudevent.bindings = {
'http-structured' : HTTPStructured_0_1,
'http-structured0.1' : HTTPStructured_0_1
"http-structured" : HTTPStructured01,
"http-structured0.1" : HTTPStructured01,
"http-structured0.2" : HTTPStructured02,
"http-binary0.1" : HTTPBinary01,
"http-binary0.2" : HTTPBinary02
};
module.exports = Cloudevent;

View File

@ -5,10 +5,10 @@ function JSONFormatter(){
JSONFormatter.prototype.format = function(payload){
return payload;
}
};
JSONFormatter.prototype.toString = function(payload){
return JSON.stringify(payload);
}
};
module.exports = JSONFormatter;

View File

@ -1,8 +1,8 @@
var uuid = require('uuid/v4');
var uuid = require("uuid/v4");
function Spec_0_1(_caller){
function Spec01(_caller){
this.payload = {
cloudEventsVersion: '0.1',
cloudEventsVersion: "0.1",
eventID: uuid()
};
@ -15,8 +15,12 @@ function Spec_0_1(_caller){
* Inject the method to set the version related to data attribute.
*/
this.caller.prototype.eventTypeVersion = function(_version){
this.spec.eventTypeVersion(_version);
}
return this.spec.eventTypeVersion(_version);
};
this.caller.prototype.getEventTypeVersion = function(){
return this.spec.getEventTypeVersion();
};
}
/*
@ -24,61 +28,96 @@ function Spec_0_1(_caller){
*
* throw an error if do not pass.
*/
Spec_0_1.prototype.check = function() {
Spec01.prototype.check = function() {
if(!this.payload['eventType']){
if(!this.payload["eventType"]){
throw {message: "'eventType' is invalid"};
}
}
};
Spec_0_1.prototype.type = function(_type){
this.payload['eventType'] = _type;
Spec01.prototype.type = function(_type){
this.payload["eventType"] = _type;
return this;
}
};
Spec_0_1.prototype.eventTypeVersion = function(version){
this.payload['eventTypeVersion'] = version;
Spec01.prototype.getType = function(){
return this.payload["eventType"];
};
Spec01.prototype.getSpecversion = function() {
return this.payload["cloudEventsVersion"];
};
Spec01.prototype.eventTypeVersion = function(version){
this.payload["eventTypeVersion"] = version;
return this;
}
};
Spec_0_1.prototype.source = function(_source){
this.payload['source'] = _source;
Spec01.prototype.getEventTypeVersion = function() {
return this.payload["eventTypeVersion"];
};
Spec01.prototype.source = function(_source){
this.payload["source"] = _source;
return this;
}
};
Spec_0_1.prototype.id = function(_id){
this.payload['eventID'] = _id;
Spec01.prototype.getSource = function() {
return this.payload["source"];
};
Spec01.prototype.id = function(_id){
this.payload["eventID"] = _id;
return this;
}
};
Spec_0_1.prototype.time = function(_time){
this.payload['eventTime'] = _time.toISOString();
Spec01.prototype.getId = function() {
return this.payload["eventID"];
};
Spec01.prototype.time = function(_time){
this.payload["eventTime"] = _time.toISOString();
return this;
}
};
Spec_0_1.prototype.schemaurl = function(_schemaurl){
this.payload['schemaURL'] = _schemaurl;
Spec01.prototype.getTime = function() {
return this.payload["eventTime"];
};
Spec01.prototype.schemaurl = function(_schemaurl){
this.payload["schemaURL"] = _schemaurl;
return this;
}
};
Spec_0_1.prototype.contenttype = function(_contenttype){
this.payload['contentType'] = _contenttype;
Spec01.prototype.getSchemaurl = function() {
return this.payload["schemaURL"];
};
Spec01.prototype.contenttype = function(_contenttype){
this.payload["contentType"] = _contenttype;
return this;
}
};
Spec_0_1.prototype.data = function(_data){
this.payload['data'] = _data;
Spec01.prototype.getContenttype = function() {
return this.payload["contentType"];
};
Spec01.prototype.data = function(_data){
this.payload["data"] = _data;
return this;
}
};
Spec_0_1.prototype.addExtension = function(key, value){
if(!this.payload['extensions']){
this.payload['extensions'] = {};
Spec01.prototype.getData = function() {
return this.payload["data"];
};
Spec01.prototype.addExtension = function(key, value){
if(!this.payload["extensions"]){
this.payload["extensions"] = {};
}
this.payload['extensions'][key] = value;
this.payload["extensions"][key] = value;
return this;
}
module.exports = Spec_0_1;
};
module.exports = Spec01;

View File

@ -1,9 +1,9 @@
var uuid = require('uuid/v4');
var empty = require('is-empty')
var uuid = require("uuid/v4");
var empty = require("is-empty");
function Spec_0_2(){
function Spec02(){
this.payload = {
specversion: '0.2',
specversion: "0.2",
id: uuid()
};
}
@ -11,65 +11,92 @@ function Spec_0_2(){
/*
* Check the spec constraints.
*/
Spec_0_2.prototype.check = function(){
Spec02.prototype.check = function(){
if(empty(this.payload['type'])) {
if(empty(this.payload["type"])) {
throw {message: "'type' is invalid"};
}
if(empty(this.payload['specversion'])) {
if(empty(this.payload["specversion"])) {
throw {message: "'specversion' is invalid"};
}
if(this.payload['specversion'] !== '0.2') {
throw {message: "'specversion' value is invalid: '"
+ this.payload['specversion'] + "'"};
if(this.payload["specversion"] !== "0.2") {
throw {message: "'specversion' value is invalid: '"
+ this.payload["specversion"] + "'"};
}
if(empty(this.payload['id'])) {
if(empty(this.payload["id"])) {
throw {message: "'id' is invalid"};
}
}
};
Spec_0_2.prototype.type = function(_type){
this.payload['type'] = _type;
Spec02.prototype.type = function(_type){
this.payload["type"] = _type;
return this;
}
};
Spec_0_2.prototype.source = function(_source){
this.payload['source'] = _source;
Spec02.prototype.getType = function(){
return this.payload["type"];
};
Spec02.prototype.getSpecversion = function() {
return this.payload["specversion"];
};
Spec02.prototype.source = function(_source){
this.payload["source"] = _source;
return this;
}
};
Spec_0_2.prototype.id = function(_id){
this.payload['id'] = _id;
Spec02.prototype.id = function(_id){
this.payload["id"] = _id;
return this;
}
};
Spec_0_2.prototype.time = function(_time){
this.payload['time'] = _time.toISOString();
Spec02.prototype.getId = function() {
return this.payload["id"];
};
Spec02.prototype.time = function(_time){
this.payload["time"] = _time.toISOString();
return this;
}
};
Spec_0_2.prototype.schemaurl = function(_schemaurl){
this.payload['schemaurl'] = _schemaurl;
Spec02.prototype.getTime = function() {
return this.payload["time"];
};
Spec02.prototype.schemaurl = function(_schemaurl){
this.payload["schemaurl"] = _schemaurl;
return this;
}
};
Spec_0_2.prototype.contenttype = function(_contenttype){
this.payload['contenttype'] = _contenttype;
Spec02.prototype.getSchemaurl = function() {
return this.payload["schemaurl"];
};
Spec02.prototype.contenttype = function(_contenttype){
this.payload["contenttype"] = _contenttype;
return this;
}
};
Spec_0_2.prototype.data = function(_data){
this.payload['data'] = _data;
Spec02.prototype.getContenttype = function() {
return this.payload["contenttype"];
};
Spec02.prototype.data = function(_data){
this.payload["data"] = _data;
return this;
}
};
Spec_0_2.prototype.addExtension = function(key, value){
Spec02.prototype.getData = function() {
return this.payload["data"];
};
Spec02.prototype.addExtension = function(key, value){
this.payload[key] = value;
return this;
}
module.exports = Spec_0_2;
};
module.exports = Spec02;

View File

@ -1,10 +1,11 @@
{
"name": "cloudevents-sdk",
"version": "0.1.0",
"version": "0.2.0",
"description": "CloudEvents SDK for JavaScript",
"main": "index.js",
"scripts": {
"test": "./node_modules/.bin/mocha -C test/*.js"
"test": "./node_modules/.bin/mocha -C test/*.js",
"coverage": "./node_modules/.bin/istanbul cover -x '**/test/**' _mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/.bin/codacy-coverage && rm -rf ./coverage"
},
"repository": {
"type": "git",
@ -38,7 +39,10 @@
"chai": "4.2.0",
"mocha": "5.2.0",
"chai-http": "4.2.0",
"nock": "10.0.2"
"nock": "10.0.2",
"codacy-coverage": "3.3.0",
"mocha-lcov-reporter": "1.3.0",
"istanbul": "0.4.5"
},
"publishConfig": {
"access": "public"

View File

@ -1,10 +1,10 @@
var expect = require("chai").expect;
var Cloudevent = require("../index.js");
const type = "com.github.pull.create";
const source = "urn:event:from:myapi/resourse/123";
const type = "com.github.pull.create01";
const source = "urn:event:from:myapi/resourse/01";
const time = new Date();
const schemaurl = "http://example.com/registry/myschema.json";
const schemaurl = "http://example.com/registry/v01/myschema.json";
const contenttype = "application/json";
const data = {};
const extensions = {};
@ -19,59 +19,59 @@ describe("CloudEvents Spec 0.1 - JavaScript SDK", () => {
describe("Required context attributes", () => {
it("requires 'eventType'", () => {
expect(cloudevent.format()).to.have.property('eventType');
expect(cloudevent.format()).to.have.property("eventType");
});
it("requires 'eventTypeVersion'", () => {
cloudevent.eventTypeVersion("1.0");
expect(cloudevent.format()).to.have.property('eventTypeVersion');
expect(cloudevent.format()).to.have.property("eventTypeVersion");
});
it("requires 'cloudEventsVersion'", () => {
expect(cloudevent.format()).to.have.property('cloudEventsVersion');
expect(cloudevent.format()).to.have.property("cloudEventsVersion");
});
it("requires 'source'", () => {
expect(cloudevent.format()).to.have.property('source');
expect(cloudevent.format()).to.have.property("source");
});
it("requires 'eventID'", () => {
expect(cloudevent.format()).to.have.property('eventID');
expect(cloudevent.format()).to.have.property("eventID");
});
});
describe("Optional context attributes", () => {
it("contains 'eventTime'", () => {
cloudevent.time(time);
expect(cloudevent.format()).to.have.property('eventTime');
expect(cloudevent.format()).to.have.property("eventTime");
});
it("contains 'schemaURL'", () => {
cloudevent.schemaurl(schemaurl);
expect(cloudevent.format()).to.have.property('schemaURL');
expect(cloudevent.format()).to.have.property("schemaURL");
});
it("contains 'contentType'", () => {
cloudevent.contenttype(contenttype);
expect(cloudevent.format()).to.have.property('contentType');
expect(cloudevent.format()).to.have.property("contentType");
});
it("contains 'data'", () => {
cloudevent.data(data);
expect(cloudevent.format()).to.have.property('data');
expect(cloudevent.format()).to.have.property("data");
});
it("contains 'extensions'", () => {
cloudevent.addExtension('foo', 'value');
expect(cloudevent.format()).to.have.property('extensions');
cloudevent.addExtension("foo", "value");
expect(cloudevent.format()).to.have.property("extensions");
});
it("'extensions' should have 'bar' extension", () => {
cloudevent.addExtension('bar', 'value');
cloudevent.addExtension("bar", "value");
expect(cloudevent.format().extensions)
.to.have.property('foo');
.to.have.property("foo");
});
});
describe("The Constraints check", () => {
@ -98,7 +98,7 @@ describe("CloudEvents Spec 0.1 - JavaScript SDK", () => {
describe("'eventTime'", () => {
it("must adhere to the format specified in RFC 3339", () => {
cloudevent.time(time);
expect(cloudevent.format()['eventTime']).to.equal(time.toISOString());
expect(cloudevent.format()["eventTime"]).to.equal(time.toISOString());
});
});
});

View File

@ -9,7 +9,7 @@ const contenttype = "application/json";
const data = {};
const extensions = {};
var cloudevent = new Cloudevent(Cloudevent.specs['0.2'])
var cloudevent = new Cloudevent(Cloudevent.specs["0.2"])
.type(type)
.source(source);
@ -19,51 +19,51 @@ describe("CloudEvents Spec 0.2 - JavaScript SDK", () => {
describe("Required context attributes", () => {
it("requires 'type'", () => {
expect(cloudevent.format()).to.have.property('type');
expect(cloudevent.format()).to.have.property("type");
});
it("requires 'specversion'", () => {
expect(cloudevent.format()).to.have.property('specversion');
expect(cloudevent.format()).to.have.property("specversion");
});
it("requires 'source'", () => {
expect(cloudevent.format()).to.have.property('source');
expect(cloudevent.format()).to.have.property("source");
});
it("requires 'id'", () => {
expect(cloudevent.format()).to.have.property('id');
expect(cloudevent.format()).to.have.property("id");
});
});
describe("Optional context attributes", () => {
it("contains 'time'", () => {
cloudevent.time(time);
expect(cloudevent.format()).to.have.property('time');
expect(cloudevent.format()).to.have.property("time");
});
it("contains 'schemaurl'", () => {
cloudevent.schemaurl(schemaurl);
expect(cloudevent.format()).to.have.property('schemaurl');
expect(cloudevent.format()).to.have.property("schemaurl");
});
it("contains 'contenttype'", () => {
cloudevent.contenttype(contenttype);
expect(cloudevent.format()).to.have.property('contenttype');
expect(cloudevent.format()).to.have.property("contenttype");
});
it("contains 'data'", () => {
cloudevent.data(data);
expect(cloudevent.format()).to.have.property('data');
expect(cloudevent.format()).to.have.property("data");
});
it("contains 'extension1'", () => {
cloudevent.addExtension("extension1", "value1");
expect(cloudevent.format()).to.have.property('extension1');
expect(cloudevent.format()).to.have.property("extension1");
});
it("'extension2' should have value equals to 'value1'", () => {
cloudevent.addExtension("extension2", "value2");
expect(cloudevent.format()['extension2']).to.equal('value2');
expect(cloudevent.format()["extension2"]).to.equal("value2");
});
});
@ -88,7 +88,7 @@ describe("CloudEvents Spec 0.2 - JavaScript SDK", () => {
describe("'specversion'", () => {
it("compliant event producers must use a value of '0.2'", () => {
expect(cloudevent.format()['specversion']).to.equal("0.2");
expect(cloudevent.format()["specversion"]).to.equal("0.2");
});
it("should throw an error when is an empty string", () => {
@ -116,7 +116,7 @@ describe("CloudEvents Spec 0.2 - JavaScript SDK", () => {
describe("'time'", () => {
it("must adhere to the format specified in RFC 3339", () => {
cloudevent.time(time);
expect(cloudevent.format()['time']).to.equal(time.toISOString());
expect(cloudevent.format()["time"]).to.equal(time.toISOString());
});
});
});

View File

@ -6,45 +6,132 @@ const type = "com.github.pull.create";
const source = "urn:event:from:myapi/resourse/123";
const webhook = "https://cloudevents.io/webhook";
const contentType = "application/cloudevents+json; charset=utf-8";
const now = new Date();
const schemaurl = "http://cloudevents.io/schema.json";
var cloudevent = new Cloudevent()
.type(type)
.source(source);
const ceContentType = "application/json";
var httpcfg = {
method : 'POST',
url : webhook + '/json'
const data = {
foo: "bar"
};
var httpstructured_0_1 =
new Cloudevent.bindings['http-structured0.1'](httpcfg);
const Structured01 = Cloudevent.bindings["http-structured0.1"];
const Binary01 = Cloudevent.bindings["http-binary0.1"];
var cloudevent =
new Cloudevent()
.type(type)
.source(source)
.contenttype(ceContentType)
.time(now)
.schemaurl(schemaurl)
.data(data);
cloudevent.eventTypeVersion("1.0.0");
var httpcfg = {
method : "POST",
url : webhook + "/json"
};
var httpstructured01 = new Structured01(httpcfg);
var httpbinary01 = new Binary01(httpcfg);
describe("HTTP Transport Binding - Version 0.1", () => {
beforeEach(() => {
// Mocking the webhook
nock(webhook)
.post("/json")
.reply(201, {status: 'accepted'});
.reply(201, {status: "accepted"});
});
describe("Structured", () => {
describe("JSON Format", () => {
it("requires '" + contentType + "' Content-Type in header", () => {
return httpstructured_0_1.emit(cloudevent)
.then(response => {
expect(response.config.headers['Content-Type'])
it("requires '" + contentType + "' Content-Type in the header", () => {
return httpstructured01.emit(cloudevent)
.then((response) => {
expect(response.config.headers["Content-Type"])
.to.equal(contentType);
});
});
it("the request should be correct", () => {
return httpstructured_0_1.emit(cloudevent)
.then(response => {
it("the request payload should be correct", () => {
return httpstructured01.emit(cloudevent)
.then((response) => {
expect(JSON.parse(response.config.data))
.to.deep.equal(cloudevent.format());
});
});
});
});
});
describe("Binary", () => {
describe("JSON Format", () => {
it("requires '" + cloudevent.getContenttype() + "' Content-Type in the header", () => {
return httpbinary01.emit(cloudevent)
.then((response) => {
expect(response.config.headers["Content-Type"])
.to.equal(cloudevent.getContenttype());
});
});
it("the request payload should be correct", () => {
return httpbinary01.emit(cloudevent)
.then((response) => {
expect(JSON.parse(response.config.data))
.to.deep.equal(cloudevent.getData());
});
});
it("HTTP Header contains 'CE-EventType'", () => {
return httpbinary01.emit(cloudevent)
.then((response) => {
expect(response.config.headers)
.to.have.property("CE-EventType");
});
});
it("HTTP Header contains 'CE-EventTypeVersion'", () => {
return httpbinary01.emit(cloudevent)
.then((response) => {
expect(response.config.headers)
.to.have.property("CE-EventTypeVersion");
});
});
it("HTTP Header contains 'CE-CloudEventsVersion'", () => {
return httpbinary01.emit(cloudevent)
.then((response) => {
expect(response.config.headers)
.to.have.property("CE-CloudEventsVersion");
});
});
it("HTTP Header contains 'CE-Source'", () => {
return httpbinary01.emit(cloudevent)
.then((response) => {
expect(response.config.headers)
.to.have.property("CE-Source");
});
});
it("HTTP Header contains 'CE-EventID'", () => {
return httpbinary01.emit(cloudevent)
.then((response) => {
expect(response.config.headers)
.to.have.property("CE-EventID");
});
});
it("HTTP Header contains 'CE-EventTime'", () => {
return httpbinary01.emit(cloudevent)
.then((response) => {
expect(response.config.headers)
.to.have.property("CE-EventTime");
});
});
it("HTTP Header contains 'CE-SchemaURL'", () => {
return httpbinary01.emit(cloudevent)
.then((response) => {
expect(response.config.headers)
.to.have.property("CE-SchemaURL");
});
});
});
});
});

149
test/http_binding_0_2.js Normal file
View File

@ -0,0 +1,149 @@
var expect = require("chai").expect;
var Cloudevent = require("../index.js");
var nock = require("nock");
const type = "com.github.pull.create";
const source = "urn:event:from:myapi/resourse/123";
const webhook = "https://cloudevents.io/webhook";
const contentType = "application/cloudevents+json; charset=utf-8";
const now = new Date();
const schemaurl = "http://cloudevents.io/schema.json";
const ceContentType = "application/json";
const data = {
foo: "bar"
};
const ext1Name = "extension1";
const ext1Value = "foobar";
const ext2Name = "extension2";
const ext2Value = "acme";
const Structured02 = Cloudevent.bindings["http-structured0.2"];
const Binary02 = Cloudevent.bindings["http-binary0.2"];
var cloudevent =
new Cloudevent()
.type(type)
.source(source)
.contenttype(ceContentType)
.time(now)
.schemaurl(schemaurl)
.data(data)
.addExtension(ext1Name, ext1Value)
.addExtension(ext2Name, ext2Value);
var httpcfg = {
method : "POST",
url : webhook + "/json"
};
var httpstructured02 = new Structured02(httpcfg);
var httpbinary02 = new Binary02(httpcfg);
describe("HTTP Transport Binding - Version 0.2", () => {
beforeEach(() => {
// Mocking the webhook
nock(webhook)
.post("/json")
.reply(201, {status: "accepted"});
});
describe("Structured", () => {
describe("JSON Format", () => {
it("requires '" + contentType + "' Content-Type in the header", () => {
return httpstructured02.emit(cloudevent)
.then((response) => {
expect(response.config.headers["Content-Type"])
.to.equal(contentType);
});
});
it("the request payload should be correct", () => {
return httpstructured02.emit(cloudevent)
.then((response) => {
expect(JSON.parse(response.config.data))
.to.deep.equal(cloudevent.format());
});
});
});
});
describe("Binary", () => {
describe("JSON Format", () => {
it("requires '" + cloudevent.getContenttype() + "' Content-Type in the header", () => {
return httpbinary02.emit(cloudevent)
.then((response) => {
expect(response.config.headers["Content-Type"])
.to.equal(cloudevent.getContenttype());
});
});
it("the request payload should be correct", () => {
return httpbinary02.emit(cloudevent)
.then((response) => {
expect(JSON.parse(response.config.data))
.to.deep.equal(cloudevent.getData());
});
});
it("HTTP Header contains 'ce-type'", () => {
return httpbinary02.emit(cloudevent)
.then((response) => {
expect(response.config.headers)
.to.have.property("ce-type");
});
});
it("HTTP Header contains 'ce-specversion'", () => {
return httpbinary02.emit(cloudevent)
.then((response) => {
expect(response.config.headers)
.to.have.property("ce-specversion");
});
});
it("HTTP Header contains 'ce-source'", () => {
return httpbinary02.emit(cloudevent)
.then((response) => {
expect(response.config.headers)
.to.have.property("ce-source");
});
});
it("HTTP Header contains 'ce-id'", () => {
return httpbinary02.emit(cloudevent)
.then((response) => {
expect(response.config.headers)
.to.have.property("ce-id");
});
});
it("HTTP Header contains 'ce-time'", () => {
return httpbinary02.emit(cloudevent)
.then((response) => {
expect(response.config.headers)
.to.have.property("ce-time");
});
});
it("HTTP Header contains 'ce-schemaurl'", () => {
return httpbinary02.emit(cloudevent)
.then((response) => {
expect(response.config.headers)
.to.have.property("ce-schemaurl");
});
});
it("HTTP Header contains 'ce-" + ext1Name + "'", () => {
return httpbinary02.emit(cloudevent)
.then((response) => {
expect(response.config.headers)
.to.have.property("ce-" + ext1Name);
});
});
it("HTTP Header contains 'ce-" + ext2Name + "'", () => {
return httpbinary02.emit(cloudevent)
.then((response) => {
expect(response.config.headers)
.to.have.property("ce-" + ext2Name);
});
});
});
});
});