Skip to content

lib: rewrite in TypeScript #226

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
{
"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,
"mocha": true
},
"rules": {
"no-var": "error",
"space-before-function-paren": ["error", "never"],
"standard/no-callback-literal": "off",
"arrow-spacing": "error",
"arrow-parens": ["error", "always"],
Expand All @@ -20,7 +28,7 @@
"no-console": ["error", {
"allow": ["warn", "error"]
}],
"valid-jsdoc": "error",
"valid-jsdoc": "warn",
"semi": ["error", "always"],
"quotes": ["error", "double", { "allowTemplateLiterals": true }]
}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ index.js
/lib
/browser
/bundles
/dist

# Runtime data
pids
Expand Down
7 changes: 7 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
semi: true,
trailingComma: "all",
doubleQuote: true,
printWidth: 120,
tabWidth: 2
}
51 changes: 24 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,73 +36,70 @@ 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({
type, source, data
});

// 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) |
Expand Down
25 changes: 11 additions & 14 deletions examples/express-ex/index.js
Original file line number Diff line number Diff line change
@@ -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!");
});
1 change: 1 addition & 0 deletions examples/typescript-ex/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
28 changes: 13 additions & 15 deletions examples/typescript-ex/src/index.ts
Original file line number Diff line number Diff line change
@@ -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",
Expand All @@ -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;
}
Expand Down
10 changes: 5 additions & 5 deletions examples/websocket/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -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."));
Expand All @@ -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}
------------------------------------------
Expand Down
15 changes: 9 additions & 6 deletions examples/websocket/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
<html>
<head>
<title>CloudEvent Example</title>
<script src="../../bundles/cloudevents-sdk.js"></script>
<script src="../../_bundles/cloudevents-sdk.js"></script>
<script>
const CloudEvent = window['cloudevents-sdk'].CloudEvent;
const Version = window['cloudevents-sdk'].Version;
const socket = new WebSocket("ws://localhost:8080");

function print(weather) {
const data = JSON.parse(weather);
const data = weather;
const summary = `
<h2>Current weather for ${data.name}: ${data.weather[0].main}</h2>
<hr/>
Expand All @@ -23,7 +24,7 @@ <h2>Current weather for ${data.name}: ${data.weather[0].main}</h2>

function initialize() {
socket.onmessage = function(message) {
console.log(message.data)
console.log(message.data);
const event = new CloudEvent(JSON.parse(message.data));
if (event.type === "weather.error") {
console.error(`Error: ${event.data}`);
Expand All @@ -37,11 +38,13 @@ <h2>Current weather for ${data.name}: ${data.weather[0].main}</h2>
input.addEventListener("keyup", function(event) {
if (event.keyCode === 13) {
event.preventDefault();
socket.send(new CloudEvent({
const ce = new CloudEvent({
type: "weather.query",
source: "/weather.client",
data: input.value
}).toString());
data: { zip: input.value }
});
console.log(ce);
socket.send(JSON.stringify(ce));
}
});

Expand Down
27 changes: 16 additions & 11 deletions examples/websocket/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,29 @@ console.log("WebSocket server started. Waiting for events.");
wss.on("connection", function connection(ws) {
console.log("Connection received");
ws.on("message", function incoming(message) {
console.log(`Message received: ${message}`);
const event = new CloudEvent(JSON.parse(message));
console.log(`Message received: ${event.toString()}`);
fetch(event.data)
fetch(event.data.zip)
.then((weather) => {
ws.send(new CloudEvent({
const response = new CloudEvent({
dataContentType: "application/json",
type: "current.weather",
source: "/weather.server",
data: weather
}).toString());
data: weather,
});
ws.send(JSON.stringify(response));
})
.catch((err) => {
console.error(err);
ws.send(new CloudEvent({
type: "weather.error",
source: "/weather.server",
data: err.toString()
}).toString());
ws.send(
JSON.stringify(
new CloudEvent({
type: "weather.error",
source: "/weather.server",
data: err.toString(),
}),
),
);
});
});
});
Expand All @@ -39,7 +44,7 @@ function fetch(zip) {
const query = `${api}?zip=${zip}&appid=${key}&units=imperial`;
return new Promise((resolve, reject) => {
got(query)
.then((response) => resolve(response.body))
.then((response) => resolve(JSON.parse(response.body)))
.catch((err) => reject(err.message));
});
}
Loading