Skip to content

Commit ebd9284

Browse files
committed
chore(refactor): protocol bindings use interfaces
This change modifies the protocol binding interfaces such as `Binding`, `Serializer` and the like to use the `CloudEventV1` interface instead of the implementation class `CloudEvent`. This should make extending the interfaces simpler as this work has grown out of efforts around the implementation of a second transport interface, Kafka. See: cloudevents#455 This commit also includes the addition of a generic type to the `Message` interface, defaulting to `string`. There is also some minor clean up involving what is exported from the `message/http` modules. Now, instead of exporting the entire implementation, only the `HTTP` binding implementation is exported, and it is then reexported by `message`. Also, a static `CloudEvent.cloneWith()` method has been added which the instance methods now use. Signed-off-by: Lance Ball <[email protected]>
1 parent 04c737c commit ebd9284

File tree

4 files changed

+35
-27
lines changed

4 files changed

+35
-27
lines changed

src/event/cloudevent.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ See: https://github.com/cloudevents/spec/blob/v1.0/spec.md#type-system`);
198198
* @throws if the CloudEvent does not conform to the schema
199199
* @return {CloudEvent} returns a new CloudEvent<D>
200200
*/
201-
public cloneWith<D>(options: Partial<CloudEvent<D>>, strict?: boolean): CloudEvent<D>;
201+
public cloneWith<D>(options: Partial<CloudEventV1<D>>, strict?: boolean): CloudEvent<D>;
202202
/**
203203
* Clone a CloudEvent with new/update attributes
204204
* @param {object} options attributes to augment the CloudEvent
@@ -207,7 +207,7 @@ See: https://github.com/cloudevents/spec/blob/v1.0/spec.md#type-system`);
207207
* @return {CloudEvent} returns a new CloudEvent
208208
*/
209209
public cloneWith<D>(options: Partial<CloudEventV1<D>>, strict = true): CloudEvent<D | T> {
210-
return new CloudEvent(Object.assign({}, this.toJSON(), options), strict);
210+
return CloudEvent.cloneWith(this as CloudEvent<T>, options, strict);
211211
}
212212

213213
/**
@@ -217,4 +217,11 @@ See: https://github.com/cloudevents/spec/blob/v1.0/spec.md#type-system`);
217217
[Symbol.for("nodejs.util.inspect.custom")](): string {
218218
return this.toString();
219219
}
220+
221+
public static cloneWith(
222+
event: CloudEvent<any>, // Must be a concrete CloudEvent class
223+
options: Partial<CloudEventV1<any>>, // May take any
224+
strict = true): CloudEvent<any> {
225+
return new CloudEvent(Object.assign({}, event.toJSON(), options), strict);
226+
}
220227
}

src/message/http/headers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
import { PassThroughParser, DateParser, MappedParser } from "../../parsers";
7-
import { CloudEvent } from "../..";
7+
import { CloudEventV1 } from "../..";
88
import { Headers } from "../";
99
import { Version } from "../../event/cloudevent";
1010
import CONSTANTS from "../../constants";
@@ -24,7 +24,7 @@ export const requiredHeaders = [
2424
* @param {CloudEvent} event a CloudEvent
2525
* @returns {Object} the headers that will be sent for the event
2626
*/
27-
export function headersFor<T>(event: CloudEvent<T>): Headers {
27+
export function headersFor<T>(event: CloudEventV1<T>): Headers {
2828
const headers: Headers = {};
2929
let headerMap: Readonly<{ [key: string]: MappedParser }>;
3030
if (event.specversion === Version.V1) {

src/message/http/index.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
import { CloudEvent, CloudEventV1, CONSTANTS, Mode, Version } from "../..";
7-
import { Message, Headers } from "..";
7+
import { Message, Headers, Binding } from "..";
88

99
import {
1010
headersFor,
@@ -25,7 +25,7 @@ import { JSONParser, MappedParser, Parser, parserByContentType } from "../../par
2525
* @param {CloudEvent} event The event to serialize
2626
* @returns {Message} a Message object with headers and body
2727
*/
28-
export function binary<T>(event: CloudEvent<T>): Message {
28+
function binary<T>(event: CloudEventV1<T>): Message {
2929
const contentType: Headers = { [CONSTANTS.HEADER_CONTENT_TYPE]: CONSTANTS.DEFAULT_CONTENT_TYPE };
3030
const headers: Headers = { ...contentType, ...headersFor(event) };
3131
let body = event.data;
@@ -47,10 +47,10 @@ export function binary<T>(event: CloudEvent<T>): Message {
4747
* @param {CloudEvent} event the CloudEvent to be serialized
4848
* @returns {Message} a Message object with headers and body
4949
*/
50-
export function structured<T>(event: CloudEvent<T>): Message {
50+
function structured<T>(event: CloudEventV1<T>): Message {
5151
if (event.data_base64) {
5252
// The event's data is binary - delete it
53-
event = event.cloneWith({ data: undefined });
53+
event = (event as CloudEvent).cloneWith({ data: undefined });
5454
}
5555
return {
5656
headers: {
@@ -67,7 +67,7 @@ export function structured<T>(event: CloudEvent<T>): Message {
6767
* @param {Message} message an incoming Message object
6868
* @returns {boolean} true if this Message is a CloudEvent
6969
*/
70-
export function isEvent(message: Message): boolean {
70+
function isEvent(message: Message): boolean {
7171
// TODO: this could probably be optimized
7272
try {
7373
deserialize(message);
@@ -84,7 +84,7 @@ export function isEvent(message: Message): boolean {
8484
* @param {Message} message the incoming message
8585
* @return {CloudEvent} A new {CloudEvent} instance
8686
*/
87-
export function deserialize<T>(message: Message): CloudEvent<T> | CloudEvent<T>[] {
87+
function deserialize<T>(message: Message): CloudEvent<T> | CloudEvent<T>[] {
8888
const cleanHeaders: Headers = sanitize(message.headers);
8989
const mode: Mode = getMode(cleanHeaders);
9090
const version = getVersion(mode, cleanHeaders, message.body);
@@ -261,3 +261,14 @@ function parseBatched<T>(message: Message): CloudEvent<T> | CloudEvent<T>[] {
261261
});
262262
return ret;
263263
}
264+
265+
/**
266+
* Bindings for HTTP transport support
267+
* @implements {@linkcode Binding}
268+
*/
269+
export const HTTP: Binding = {
270+
binary,
271+
structured,
272+
toEvent: deserialize,
273+
isEvent: isEvent,
274+
};

src/message/index.ts

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
*/
55

66
import { IncomingHttpHeaders } from "http";
7-
import { CloudEvent } from "..";
8-
import { binary, deserialize, structured, isEvent } from "./http";
7+
import { CloudEventV1 } from "..";
8+
9+
// reexport the protocol bindings
10+
export * from "./http";
11+
export * from "./kafka";
912

1013
/**
1114
* Binding is an interface for transport protocols to implement,
@@ -62,7 +65,7 @@ export enum Mode {
6265
* @interface
6366
*/
6467
export interface Serializer {
65-
<T>(event: CloudEvent<T>): Message;
68+
<T>(event: CloudEventV1<T>): Message;
6669
}
6770

6871
/**
@@ -71,7 +74,7 @@ export interface Serializer {
7174
* @interface
7275
*/
7376
export interface Deserializer {
74-
<T>(message: Message): CloudEvent<T> | CloudEvent<T>[];
77+
<T>(message: Message): CloudEventV1<T> | CloudEventV1<T>[];
7578
}
7679

7780
/**
@@ -82,16 +85,3 @@ export interface Deserializer {
8285
export interface Detector {
8386
(message: Message): boolean;
8487
}
85-
86-
/**
87-
* Bindings for HTTP transport support
88-
* @implements {@linkcode Binding}
89-
*/
90-
export const HTTP: Binding = {
91-
binary: binary as Serializer,
92-
structured: structured as Serializer,
93-
toEvent: deserialize as Deserializer,
94-
isEvent: isEvent as Detector,
95-
};
96-
97-
export * from "./kafka";

0 commit comments

Comments
 (0)