Skip to content
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

BREAKING CHANGE: use string instead of enum for Version #561

Merged
merged 1 commit into from
Jul 19, 2023
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
16 changes: 7 additions & 9 deletions src/event/cloudevent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@ import { validateCloudEvent } from "./spec";
import { ValidationError, isBinary, asBase64, isValidType, base64AsBinary } from "./validation";

/**
* An enum representing the CloudEvent specification version
* Constants representing the CloudEvent specification version
*/
export const enum Version {
V1 = "1.0",
V03 = "0.3",
}
export const V1 = "1.0";
export const V03 = "0.3";

/**
* A CloudEvent describes event data in common formats to provide
Expand All @@ -28,7 +26,7 @@ export class CloudEvent<T = undefined> implements CloudEventV1<T> {
id: string;
type: string;
source: string;
specversion: Version;
specversion: string;
datacontenttype?: string;
dataschema?: string;
subject?: string;
Expand Down Expand Up @@ -69,7 +67,7 @@ export class CloudEvent<T = undefined> implements CloudEventV1<T> {
this.source = properties.source as string;
delete (properties as any).source;

this.specversion = (properties.specversion as Version) || Version.V1;
this.specversion = (properties.specversion) || V1;
delete properties.specversion;

this.datacontenttype = properties.datacontenttype;
Expand Down Expand Up @@ -103,9 +101,9 @@ export class CloudEvent<T = undefined> implements CloudEventV1<T> {
delete properties.data;

// sanity checking
if (this.specversion === Version.V1 && this.schemaurl) {
if (this.specversion === V1 && this.schemaurl) {
throw new TypeError("cannot set schemaurl on version 1.0 event");
} else if (this.specversion === Version.V03 && this.dataschema) {
} else if (this.specversion === V03 && this.dataschema) {
throw new TypeError("cannot set dataschema on version 0.3 event");
}

Expand Down
4 changes: 2 additions & 2 deletions src/event/spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
import { ValidationError } from "./validation";

import { CloudEventV1 } from "./interfaces";
import { Version } from "./cloudevent";
import { V1 } from "./cloudevent";
import validate from "../schema/v1";


export function validateCloudEvent<T>(event: CloudEventV1<T>): boolean {
if (event.specversion === Version.V1) {
if (event.specversion === V1) {
if (!validate(event)) {
throw new ValidationError("invalid payload", (validate as any).errors);
}
Expand Down
7 changes: 4 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
SPDX-License-Identifier: Apache-2.0
*/

import { CloudEvent, Version } from "./event/cloudevent";
import { CloudEvent, V1, V03 } from "./event/cloudevent";
import { ValidationError } from "./event/validation";
import { CloudEventV1, CloudEventV1Attributes } from "./event/interfaces";

import { Options, TransportFunction, EmitterFunction, emitterFor, Emitter } from "./transport/emitter";
import { httpTransport } from "./transport/http";
import {
import {
Headers, Mode, Binding, HTTP, Kafka, KafkaEvent, KafkaMessage, Message, MQTT, MQTTMessage, MQTTMessageFactory,
Serializer, Deserializer } from "./message";

Expand All @@ -18,7 +18,8 @@ import CONSTANTS from "./constants";
export {
// From event
CloudEvent,
Version,
V1,
V03,
ValidationError,
Mode,
HTTP,
Expand Down
4 changes: 2 additions & 2 deletions src/message/http/headers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { PassThroughParser, DateParser, MappedParser } from "../../parsers";
import { CloudEventV1 } from "../..";
import { Headers } from "../";
import { Version } from "../../event/cloudevent";
import { V1 } from "../../event/cloudevent";
import CONSTANTS from "../../constants";

export const allowedContentTypes = [CONSTANTS.DEFAULT_CONTENT_TYPE, CONSTANTS.MIME_JSON, CONSTANTS.MIME_OCTET_STREAM];
Expand All @@ -27,7 +27,7 @@ export const requiredHeaders = [
export function headersFor<T>(event: CloudEventV1<T>): Headers {
const headers: Headers = {};
let headerMap: Readonly<{ [key: string]: MappedParser }>;
if (event.specversion === Version.V1) {
if (event.specversion === V1) {
headerMap = v1headerMap;
} else {
headerMap = v03headerMap;
Expand Down
16 changes: 8 additions & 8 deletions src/message/http/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { types } from "util";

import { CloudEvent, CloudEventV1, CONSTANTS, Mode, Version } from "../..";
import { CloudEvent, CloudEventV1, CONSTANTS, Mode, V1, V03 } from "../..";
import { Message, Headers, Binding } from "..";

import {
Expand Down Expand Up @@ -147,19 +147,19 @@ function getVersion(mode: Mode, headers: Headers, body: string | Record<string,
return (body as Record<string, string>).specversion;
}
}
return Version.V1;
return V1;
}

/**
* Parses an incoming HTTP Message, converting it to a {CloudEvent}
* instance if it conforms to the Cloud Event specification for this receiver.
*
* @param {Message} message the incoming HTTP Message
* @param {Version} version the spec version of the incoming event
* @param {string} version the spec version of the incoming event
* @returns {CloudEvent} an instance of CloudEvent representing the incoming request
* @throws {ValidationError} of the event does not conform to the spec
*/
function parseBinary<T>(message: Message, version: Version): CloudEvent<T> {
function parseBinary<T>(message: Message, version: string): CloudEvent<T> {
const headers = { ...message.headers };
let body = message.body;

Expand All @@ -169,7 +169,7 @@ function parseBinary<T>(message: Message, version: Version): CloudEvent<T> {
const sanitizedHeaders = sanitize(headers);

const eventObj: { [key: string]: unknown | string | Record<string, unknown> } = {};
const parserMap: Record<string, MappedParser> = version === Version.V03 ? v03binaryParsers : v1binaryParsers;
const parserMap: Record<string, MappedParser> = version === V03 ? v03binaryParsers : v1binaryParsers;

for (const header in parserMap) {
if (sanitizedHeaders[header]) {
Expand Down Expand Up @@ -206,11 +206,11 @@ function parseBinary<T>(message: Message, version: Version): CloudEvent<T> {
* Creates a new CloudEvent instance based on the provided payload and headers.
*
* @param {Message} message the incoming Message
* @param {Version} version the spec version of this message (v1 or v03)
* @param {string} version the spec version of this message (v1 or v03)
* @returns {CloudEvent} a new CloudEvent instance for the provided headers and payload
* @throws {ValidationError} if the payload and header combination do not conform to the spec
*/
function parseStructured<T>(message: Message, version: Version): CloudEvent<T> {
function parseStructured<T>(message: Message, version: string): CloudEvent<T> {
const payload = message.body;
const headers = message.headers;

Expand All @@ -227,7 +227,7 @@ function parseStructured<T>(message: Message, version: Version): CloudEvent<T> {
const incoming = { ...(parser.parse(payload as string) as Record<string, unknown>) };

const eventObj: { [key: string]: unknown } = {};
const parserMap: Record<string, MappedParser> = version === Version.V03 ? v03structuredParsers : v1structuredParsers;
const parserMap: Record<string, MappedParser> = version === V03 ? v03structuredParsers : v1structuredParsers;

for (const key in parserMap) {
const property = incoming[key];
Expand Down
8 changes: 4 additions & 4 deletions test/integration/cloud_event_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import path from "path";
import fs from "fs";

import { expect } from "chai";
import { CloudEvent, CloudEventV1, ValidationError, Version } from "../../src";
import { CloudEvent, CloudEventV1, ValidationError, V1 } from "../../src";
import { asBase64 } from "../../src/event/validation";

const type = "org.cncf.cloudevents.example";
Expand All @@ -16,7 +16,7 @@ const id = "b46cf653-d48a-4b90-8dfa-355c01061361";

const fixture = Object.freeze({
id,
specversion: Version.V1,
specversion: V1,
source,
type,
data: `"some data"`
Expand Down Expand Up @@ -165,7 +165,7 @@ describe("A 1.0 CloudEvent", () => {
});

it("can be constructed with an ID", () => {
const ce = new CloudEvent({ id: "1234", specversion: Version.V1, source, type });
const ce = new CloudEvent({ id: "1234", specversion: V1, source, type });
expect(ce.id).to.equal("1234");
});

Expand Down Expand Up @@ -280,7 +280,7 @@ describe("A 1.0 CloudEvent", () => {
const obj = JSON.parse(json as string);
expect(obj.type).to.equal(type);
expect(obj.source).to.equal(source);
expect(obj.specversion).to.equal(Version.V1);
expect(obj.specversion).to.equal(V1);
});

it("throws if the provded source is empty string", () => {
Expand Down
8 changes: 4 additions & 4 deletions test/integration/kafka_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import path from "path";
import fs from "fs";

import { expect } from "chai";
import { CloudEvent, CONSTANTS, Version } from "../../src";
import { CloudEvent, CONSTANTS, V1 } from "../../src";
import { asBase64 } from "../../src/event/validation";
import { Message, Kafka, KafkaMessage, KafkaEvent } from "../../src/message";
import { KAFKA_CE_HEADERS } from "../../src/message/kafka/headers";
Expand Down Expand Up @@ -43,7 +43,7 @@ const imageData = new Uint32Array(fs.readFileSync(path.join(process.cwd(), "test
const image_base64 = asBase64(imageData);

const fixture = new CloudEvent({
specversion: Version.V1,
specversion: V1,
id,
type,
source,
Expand Down Expand Up @@ -233,7 +233,7 @@ describe("Kafka transport", () => {
expect(message.body).to.equal(data);
// validate all headers
expect(message.headers[CONSTANTS.HEADER_CONTENT_TYPE]).to.equal(datacontenttype);
expect(message.headers[KAFKA_CE_HEADERS.SPEC_VERSION]).to.equal(Version.V1);
expect(message.headers[KAFKA_CE_HEADERS.SPEC_VERSION]).to.equal(V1);
expect(message.headers[KAFKA_CE_HEADERS.ID]).to.equal(id);
expect(message.headers[KAFKA_CE_HEADERS.TYPE]).to.equal(type);
expect(message.headers[KAFKA_CE_HEADERS.SOURCE]).to.equal(source);
Expand All @@ -249,7 +249,7 @@ describe("Kafka transport", () => {
expect(message.headers[CONSTANTS.HEADER_CONTENT_TYPE]).to.equal(CONSTANTS.DEFAULT_CE_CONTENT_TYPE);
// Parse the message body as JSON, then validate the attributes
const body = JSON.parse(message.body as string);
expect(body[CONSTANTS.CE_ATTRIBUTES.SPEC_VERSION]).to.equal(Version.V1);
expect(body[CONSTANTS.CE_ATTRIBUTES.SPEC_VERSION]).to.equal(V1);
expect(body[CONSTANTS.CE_ATTRIBUTES.ID]).to.equal(id);
expect(body[CONSTANTS.CE_ATTRIBUTES.TYPE]).to.equal(type);
expect(body[CONSTANTS.CE_ATTRIBUTES.SOURCE]).to.equal(source);
Expand Down
18 changes: 9 additions & 9 deletions test/integration/message_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import fs from "fs";

import { expect } from "chai";
import { IncomingHttpHeaders } from "http";
import { CloudEvent, CONSTANTS, Version } from "../../src";
import { CloudEvent, CONSTANTS, V1, V03 } from "../../src";
import { asBase64 } from "../../src/event/validation";
import { Message, HTTP } from "../../src/message";

Expand Down Expand Up @@ -154,7 +154,7 @@ describe("HTTP transport", () => {
[CONSTANTS.CE_HEADERS.ID]: "1234",
[CONSTANTS.CE_HEADERS.SOURCE]: "test",
[CONSTANTS.CE_HEADERS.TYPE]: "test.event",
[CONSTANTS.CE_HEADERS.SPEC_VERSION]: Version.V1,
[CONSTANTS.CE_HEADERS.SPEC_VERSION]: V1,
"ce-LUNCH": "tacos",
},
};
Expand Down Expand Up @@ -237,7 +237,7 @@ describe("HTTP transport", () => {
id,
type,
source,
specversion: Version.V1,
specversion: V1,
data: { lunch: "tacos" },
});
const message: Message<undefined> = {
Expand All @@ -250,7 +250,7 @@ describe("HTTP transport", () => {

describe("Specification version V1", () => {
const fixture = new CloudEvent({
specversion: Version.V1,
specversion: V1,
id,
type,
source,
Expand All @@ -268,7 +268,7 @@ describe("HTTP transport", () => {
expect(message.body).to.equal(JSON.stringify(data));
// validate all headers
expect(message.headers[CONSTANTS.HEADER_CONTENT_TYPE]).to.equal(datacontenttype);
expect(message.headers[CONSTANTS.CE_HEADERS.SPEC_VERSION]).to.equal(Version.V1);
expect(message.headers[CONSTANTS.CE_HEADERS.SPEC_VERSION]).to.equal(V1);
expect(message.headers[CONSTANTS.CE_HEADERS.ID]).to.equal(id);
expect(message.headers[CONSTANTS.CE_HEADERS.TYPE]).to.equal(type);
expect(message.headers[CONSTANTS.CE_HEADERS.SOURCE]).to.equal(source);
Expand All @@ -284,7 +284,7 @@ describe("HTTP transport", () => {
expect(message.headers[CONSTANTS.HEADER_CONTENT_TYPE]).to.equal(CONSTANTS.DEFAULT_CE_CONTENT_TYPE);
// Parse the message body as JSON, then validate the attributes
const body = JSON.parse(message.body as string);
expect(body[CONSTANTS.CE_ATTRIBUTES.SPEC_VERSION]).to.equal(Version.V1);
expect(body[CONSTANTS.CE_ATTRIBUTES.SPEC_VERSION]).to.equal(V1);
expect(body[CONSTANTS.CE_ATTRIBUTES.ID]).to.equal(id);
expect(body[CONSTANTS.CE_ATTRIBUTES.TYPE]).to.equal(type);
expect(body[CONSTANTS.CE_ATTRIBUTES.SOURCE]).to.equal(source);
Expand Down Expand Up @@ -353,7 +353,7 @@ describe("HTTP transport", () => {

describe("Specification version V03", () => {
const fixture = new CloudEvent({
specversion: Version.V03,
specversion: V03,
id,
type,
source,
Expand All @@ -371,7 +371,7 @@ describe("HTTP transport", () => {
expect(message.body).to.equal(JSON.stringify(data));
// validate all headers
expect(message.headers[CONSTANTS.HEADER_CONTENT_TYPE]).to.equal(datacontenttype);
expect(message.headers[CONSTANTS.CE_HEADERS.SPEC_VERSION]).to.equal(Version.V03);
expect(message.headers[CONSTANTS.CE_HEADERS.SPEC_VERSION]).to.equal(V03);
expect(message.headers[CONSTANTS.CE_HEADERS.ID]).to.equal(id);
expect(message.headers[CONSTANTS.CE_HEADERS.TYPE]).to.equal(type);
expect(message.headers[CONSTANTS.CE_HEADERS.SOURCE]).to.equal(source);
Expand All @@ -387,7 +387,7 @@ describe("HTTP transport", () => {
expect(message.headers[CONSTANTS.HEADER_CONTENT_TYPE]).to.equal(CONSTANTS.DEFAULT_CE_CONTENT_TYPE);
// Parse the message body as JSON, then validate the attributes
const body = JSON.parse(message.body as string);
expect(body[CONSTANTS.CE_ATTRIBUTES.SPEC_VERSION]).to.equal(Version.V03);
expect(body[CONSTANTS.CE_ATTRIBUTES.SPEC_VERSION]).to.equal(V03);
expect(body[CONSTANTS.CE_ATTRIBUTES.ID]).to.equal(id);
expect(body[CONSTANTS.CE_ATTRIBUTES.TYPE]).to.equal(type);
expect(body[CONSTANTS.CE_ATTRIBUTES.SOURCE]).to.equal(source);
Expand Down
10 changes: 5 additions & 5 deletions test/integration/mqtt_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import path from "path";
import fs from "fs";

import { expect } from "chai";
import { CloudEvent, CONSTANTS, Version, Headers } from "../../src";
import { CloudEvent, CONSTANTS, V1, Headers } from "../../src";
import { asBase64 } from "../../src/event/validation";
import { Message, MQTT, MQTTMessage } from "../../src/message";

Expand Down Expand Up @@ -43,7 +43,7 @@ const image_base64 = asBase64(imageData);
const PUBLISH = {"Content Type": "application/json; charset=utf-8"};

const fixture = new CloudEvent({
specversion: Version.V1,
specversion: V1,
id,
type,
source,
Expand Down Expand Up @@ -216,7 +216,7 @@ describe("MQTT transport", () => {
expect(message.body).to.equal(data);
// validate all headers
expect(message.headers.datacontenttype).to.equal(datacontenttype);
expect(message.headers.specversion).to.equal(Version.V1);
expect(message.headers.specversion).to.equal(V1);
expect(message.headers.id).to.equal(id);
expect(message.headers.type).to.equal(type);
expect(message.headers.source).to.equal(source);
Expand All @@ -232,7 +232,7 @@ describe("MQTT transport", () => {
expect(message.body).to.equal(data);
// validate all headers
expect(message["User Properties"]?.datacontenttype).to.equal(datacontenttype);
expect(message["User Properties"]?.specversion).to.equal(Version.V1);
expect(message["User Properties"]?.specversion).to.equal(V1);
expect(message["User Properties"]?.id).to.equal(id);
expect(message["User Properties"]?.type).to.equal(type);
expect(message["User Properties"]?.source).to.equal(source);
Expand All @@ -249,7 +249,7 @@ describe("MQTT transport", () => {
expect(message.body).to.deep.equal(message.payload);
expect(message.payload).to.deep.equal(fixture.toJSON());
const body = message.body as Record<string, string>;
expect(body[CONSTANTS.CE_ATTRIBUTES.SPEC_VERSION]).to.equal(Version.V1);
expect(body[CONSTANTS.CE_ATTRIBUTES.SPEC_VERSION]).to.equal(V1);
expect(body[CONSTANTS.CE_ATTRIBUTES.ID]).to.equal(id);
expect(body[CONSTANTS.CE_ATTRIBUTES.TYPE]).to.equal(type);
expect(body[CONSTANTS.CE_ATTRIBUTES.SOURCE]).to.equal(source);
Expand Down
Loading
Loading