diff --git a/.eslintrc b/.eslintrc index fcbd09aa..50b266f3 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,5 +1,14 @@ { - "extends": "eslint:recommended", + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 2015, + "sourceType": "module" + }, + "extends": [ + "plugin:@typescript-eslint/recommended", + "prettier/@typescript-eslint", + "plugin:prettier/recommended" + ], "env": { "es6": true, "node": true, @@ -7,7 +16,6 @@ }, "rules": { "no-var": "error", - "space-before-function-paren": ["error", "never"], "standard/no-callback-literal": "off", "arrow-spacing": "error", "arrow-parens": ["error", "always"], @@ -20,7 +28,7 @@ "no-console": ["error", { "allow": ["warn", "error"] }], - "valid-jsdoc": "error", + "valid-jsdoc": "warn", "semi": ["error", "always"], "quotes": ["error", "double", { "allowTemplateLiterals": true }] } diff --git a/.gitignore b/.gitignore index 016ed4a8..8fa1cf23 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ index.js /lib /browser /bundles +/dist # Runtime data pids diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 00000000..64ba7d49 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,7 @@ +module.exports = { + semi: true, + trailingComma: "all", + doubleQuote: true, + printWidth: 120, + tabWidth: 2 +} \ No newline at end of file diff --git a/README.md b/README.md index b2b79b1a..c610a3ce 100644 --- a/README.md +++ b/README.md @@ -36,33 +36,32 @@ binary and structured events in either the 1.0 or 0.3 protocol formats. ```js const { CloudEvent, - HTTPReceiver + Receiver } = require("cloudevents-sdk"); // Create a receiver to accept events over HTTP -const receiver = new HTTPReceiver(); +const receiver = new Receiver(); // body and headers come from an incoming HTTP request, e.g. express.js const receivedEvent = receiver.accept(req.headers, req.body); -console.log(receivedEvent.format()); +console.log(receivedEvent); ``` #### Emitting Events -To emit events, you'll need to decide whether the event should be sent in -binary or structured format, and determine what version of the CloudEvents -specification you want to send the event as. +You can send events over HTTP in either binary or structured format. -By default, the `HTTPEmitter` will emit events over HTTP POST using the -latest supported specification version, in binary mode. You can emit version specific events by providing -the specication version in the constructor to `HTTPEmitter`. To send -structured events, add that string as a parameter to `emitter.send()`. +By default, the `Emitter` will emit events over HTTP POST using the +binary transport protocol. The `Emitter` will examine the `specversion` +of the event being sent, and use the appropriate protocol version. To send +structured events, add `Protocol.HTTPStructured` as a parameter to +`emitter.send()`. ```js -const { CloudEvent, HTTPEmitter } = require("cloudevents-sdk"); +const { CloudEvent, Emitter, Protocol, Version } = require("cloudevents-sdk"); // With only an endpoint URL, this creates a v1 emitter -const v1Emitter = new HTTPEmitter({ +const emitter = new Emitter({ url: "https://cloudevents.io/example" }); const event = new CloudEvent({ @@ -70,39 +69,37 @@ const event = new CloudEvent({ }); // By default, the emitter will send binary events -v1Emitter.send(event).then((response) => { +emitter.send(event).then((response) => { // handle the response }).catch(console.error); // To send a structured event, just add that as an option -v1Emitter.send(event, { mode: "structured" }) +emitter.send(event, { protocol: Protocol.HTTPStructured }) .then((response) => { // handle the response }).catch(console.error); // To send an event to an alternate URL, add that as an option -v1Emitter.send(event, { url: "https://alternate.com/api" }) +emitter.send(event, { url: "https://alternate.com/api" }) .then((response) => { // handle the response }).catch(console.error); -// Sending a v0.3 event works the same, just let the emitter know when -// you create it that you are working with the 0.3 spec -const v03Emitter = new HTTPEmitter({ - url: "https://cloudevents.io/example", - version: "0.3" -}); - -// Again, the default is to send binary events -// To send a structured event or to an alternate URL, provide those -// as parameters in a options object as above -v3Emitter.send(event) +// Sending a v0.3 event works the same, If your event has a +// specversion property of Version.V03, then it will be sent +// using the 0.3 transport protocol +emitter.send(new CloudEvent({ specversion: Version.V03, source, type })) .then((response) => { // handle the response }).catch(console.error); - ``` +### Example Applications + +There are a few trivial example applications in +[the examples folder](https://github.com/cloudevents/sdk-javascript/tree/master/examples). +There you will find Express.js, TypeScript and Websocket examples. + ## Supported specification features | | [v0.3](https://github.com/cloudevents/spec/tree/v0.3) | [v1.0](https://github.com/cloudevents/spec/tree/v1.0) | diff --git a/examples/express-ex/index.js b/examples/express-ex/index.js index 3aa3b0d9..da72cf89 100644 --- a/examples/express-ex/index.js +++ b/examples/express-ex/index.js @@ -1,42 +1,39 @@ /* eslint-disable no-console */ const express = require("express"); -const { HTTPReceiver } = require("cloudevents-sdk"); +const { Receiver } = require("cloudevents-sdk"); const app = express(); -const receiver = new HTTPReceiver(); +const receiver = new Receiver(); app.use((req, res, next) => { let data = ""; req.setEncoding("utf8"); - req.on("data", function(chunk) { + req.on("data", function (chunk) { data += chunk; }); - req.on("end", function() { + req.on("end", function () { req.body = data; next(); }); }); -app.post("/", function(req, res) { - console.log(req.headers); - console.log(req.body); +app.post("/", function (req, res) { + console.log("HEADERS", req.headers); + console.log("BODY", req.body); try { const event = receiver.accept(req.headers, req.body); - const asJSON = event.format(); - console.log(`Accepted event: ${JSON.stringify(event.format(), null, 2)}`); - res.status(201).json(asJSON); + console.log(`Accepted event: ${event}`); + res.status(201).json(event); } catch (err) { console.error(err); - res.status(415) - .header("Content-Type", "application/json") - .send(JSON.stringify(err)); + res.status(415).header("Content-Type", "application/json").send(JSON.stringify(err)); } }); -app.listen(3000, function() { +app.listen(3000, function () { console.log("Example app listening on port 3000!"); }); diff --git a/examples/typescript-ex/package.json b/examples/typescript-ex/package.json index 365267e4..c577e5fb 100644 --- a/examples/typescript-ex/package.json +++ b/examples/typescript-ex/package.json @@ -16,6 +16,7 @@ "check": "gts check", "clean": "gts clean", "compile": "tsc -p .", + "watch": "tsc -p . --watch", "fix": "gts fix", "prepare": "npm run compile", "pretest": "npm run compile", diff --git a/examples/typescript-ex/src/index.ts b/examples/typescript-ex/src/index.ts index 27149f6e..0a871ad3 100644 --- a/examples/typescript-ex/src/index.ts +++ b/examples/typescript-ex/src/index.ts @@ -1,35 +1,33 @@ -import { CloudEvent, HTTPReceiver } from "cloudevents-sdk"; -import { CloudEventV1 } from "cloudevents-sdk/lib/v1"; +import { CloudEvent, CloudEventV1, Receiver } from "cloudevents-sdk"; export function doSomeStuff() { - const receiver = new HTTPReceiver(); + const receiver = new Receiver(); const myevent: CloudEventV1 = new CloudEvent({ source: "/source", type: "type", - dataContentType: "text/plain", - dataSchema: "https://d.schema.com/my.json", + datacontenttype: "text/plain", + dataschema: "https://d.schema.com/my.json", subject: "cha.json", - data: "my-data" + data: "my-data", }); - myevent.addExtension("extension-1", "some extension data"); + myevent.extension1 = "some extension data"; - console.log("My structured event:", myevent.toString()); - console.log("My structured event extensions:", myevent.getExtensions()); + console.log("My structured event:", myevent); // ------ receiver structured // The header names should be standarized to use lowercase const headers = { - "content-type": "application/cloudevents+json" + "content-type": "application/cloudevents+json", }; // Typically used with an incoming HTTP request where myevent.format() is the actual // body of the HTTP - console.log("Received structured event:", receiver.accept(headers, myevent.format()).toString()); + console.log("Received structured event:", receiver.accept(headers, myevent)); // ------ receiver binary const data = { - "data": "dataString" + data: "dataString", }; const attributes = { "ce-type": "type", @@ -39,11 +37,11 @@ export function doSomeStuff() { "ce-time": "2019-06-16T11:42:00Z", "ce-dataschema": "http://schema.registry/v1", "Content-Type": "application/json", - "ce-extension1": "extension1" + "ce-extension1": "extension1", }; - console.log("My binary event:", receiver.accept(attributes, data).toString()); - console.log("My binary event extensions:", receiver.accept(attributes, data).toString()); + console.log("My binary event:", receiver.accept(attributes, data)); + console.log("My binary event extensions:", receiver.accept(attributes, data)); return true; } diff --git a/examples/websocket/client.js b/examples/websocket/client.js index ea4c39f3..eb949c8f 100644 --- a/examples/websocket/client.js +++ b/examples/websocket/client.js @@ -7,7 +7,7 @@ const { CloudEvent } = require("cloudevents-sdk"); const rl = readline.createInterface({ input: process.stdin, - output: process.stdout + output: process.stdout, }); rl.on("close", (_) => console.log("\n\nConnection closed! Press CTL-C to exit.")); @@ -25,16 +25,16 @@ ws.on("message", function incoming(message) { function ask() { rl.question("Would you like to see the current weather? Provide a zip code: ", function (zip) { console.log("Fetching weather data from server..."); - ws.send(new CloudEvent({ + const event = new CloudEvent({ type: "weather.query", source: "/weather.client", - data: zip - }).toString()); + data: { zip }, + }); + ws.send(event.toString()); }); } function print(data) { - data = JSON.parse(data); console.log(` Current weather for ${data.name}: ${data.weather[0].main} ------------------------------------------ diff --git a/examples/websocket/index.html b/examples/websocket/index.html index 4a62c4dc..da6ba43d 100644 --- a/examples/websocket/index.html +++ b/examples/websocket/index.html @@ -2,13 +2,14 @@ CloudEvent Example - +