* fix: creating an event does not error when the event attribute name is too long
* From the spec, the requirement for the length of attribute names is only a SHOULD, not a MUST. Currently, if the length is over 20 then the sdk throws an error, which I believe is incorrect because the length requirement is not a MUST.
Signed-off-by: Calum Murray <cmurray@redhat.com>
* fix(test): test expects not to throw
Signed-off-by: Calum Murray <cmurray@redhat.com>
---------
Signed-off-by: Calum Murray <cmurray@redhat.com>
TypeScript does not consider enum values equivalent, even if the string
representation is the same. So, when a module imports `cloudevents` and
also has a dependency on `cloudevents` this can cause conflicts where
the `CloudEvent.version` attribute is not considered equal when, in
fact, it is.
Changing the `enum` to a string is pretty straightforward, but should be
considered a breaking change since TypeScript dependents will
potentially fail the build with a change like this.
Signed-off-by: Lance Ball <lball@redhat.com>
* fix: handle big integers in incoming events
An event may have data that contains a BigInt. The builtin `JSON` parser
for JavaScript does not handle the `BigInt` types. The introduced
`json-bigint` dependency (34k) does.
Fixes: https://github.com/cloudevents/sdk-javascript/issues/489
Signed-off-by: Lance Ball <lball@redhat.com>
* feat!: remove node 12 and node 14
Node 12 has been EOL since the end of April 2022 and Node 14 just became EOL at the end of April 2023
Signed-off-by: Lucas Holmquist <lholmqui@redhat.com>
* fix: improve validation on extension attribute
Fixes: https://github.com/cloudevents/sdk-javascript/issues/500
Adds a regular expression check to the attribute name validation code to
ensure that attribute names only use a-z0-9 (except for `data_base64`,
which apparently is an exception to the rule.
Signed-off-by: Lance Ball <lball@redhat.com>
* fix: allow `Uint16|8Array` for binary data
Previously we only considered `Uint32Array` binary data. This was an
oversight. This fixes that issue.
Fixes: https://github.com/cloudevents/sdk-javascript/issues/491
Signed-off-by: Lance Ball <lball@redhat.com>
* fix: HTTP headers for extensions with false values
CloudEvent objects may include extensions that have a defined key and a
`false` value. This change ensures that HTTP messages for CloudEvents
containing these extension values include the appropriate headers.
Signed-off-by: Lance Ball <lball@redhat.com>
* feat: add builtin HTTP emitter
Adds a builtin HTTP event emitter that can be used with `emitterFor()`
to send events over HTTP without pulling in any additional dependencies.
In the past we chose to keep this in our code base by considering axios a
peer dependency - users were required to include it in their projects
explicitly. In working on the HTTP emitter, it became more and more
apparent that the axios emitter was probably no longer needed, and in fact
I doubt it was really used at all. To use it, users would have been required
to do this, since it isn't exported at the top level.
const { axiosEmitter } = require("cloudevents/transport/http");
Based on this, I think the usage in the wild is probably very minimal,
and I like the idea of eliminating this dependency.
Signed-off-by: Lance Ball <lball@redhat.com>
* feat: precompile cloudevent schema
This commit modifies the build pipleline so that the cloudevent schema is
precompiled for runtime validation. This eliminates the need to compile the
schema at runtime, improving both performance and security.
Fixes: https://github.com/cloudevents/sdk-javascript/issues/423
Signed-off-by: Lance Ball <lball@redhat.com>
Add MQTT as a `Message` format.
This commit adds `MQTT` to the supported transport protocols by adding a `Binding` and the `MQTTMessage<T>` type, extending the base `Message` type, adding the MQTT fields for `payload`, `PUBLISH` and `User Properties`. The `payload` field directly maps to `Message#body`, while `User Properties` roughly maps to `Message#headers`, even though the properties here are not formatted with a `ce-` prefix like other transport protocols. This is per the spec. See: https://github.com/cloudevents/spec/blob/v1.0.1/mqtt-protocol-binding.md.
Signed-off-by: Lance Ball <lball@redhat.com>
This commit extends the `message` package to include Kafka transport.
Additionally, some of the type information has changed across the project
to more accurately reflect the type of `Message` (by including `T`).
Related: https://github.com/cloudevents/sdk-javascript/issues/390
Signed-off-by: Lance Ball <lball@redhat.com>
* 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: https://github.com/cloudevents/sdk-javascript/pull/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 <lball@redhat.com>
* fixup: make the `cloneWith()` method is dependent on interfaces
Signed-off-by: Lance Ball <lball@redhat.com>
* fixup: remove unnecessary cast
Signed-off-by: Lance Ball <lball@redhat.com>
The combination of prettier and eslint was causing some conflicting error
messages in formatting between VSCode and using npm in the CLI. For the most
part, there were only a couple of required formatting changes that prettier
was covering, so the change is minor.
The cucumber dependency had a major version bump and was carrying some unsafe
dependencies in the older version. This commit bumps to the new version and
makes appropriate configuration changes.
Signed-off-by: Lance Ball <lball@redhat.com>
Adds a batched content mode for incoming events.
```js
// It's possible for this to return 1:N events
const ceArray = HTTP.toEvent(req.headers, req.body);
```
Signed-off-by: Lance Ball <lball@redhat.com>
The parser for HTTP binary made the assumption that if there was no `content-type`
header in the incoming message, it should inject `application/json`. Discussion
about the rationale for this is in https://github.com/cloudevents/sdk-javascript/issues/441.
This commit, removes that injection and adds a test to ensure the bytes are
simply not parsed, but just passed along untouched.
Fixes: https://github.com/cloudevents/sdk-javascript/issues/441
Signed-off-by: Lance Ball <lball@redhat.com>
It has been nearly two years since 1.0 became final. This change removes
support for 0.3 events in the interest of simplifying the project a little.
Signed-off-by: Lance Ball <lball@redhat.com>
Even if the specversion is totally invalid, we should not change the value
received in an incoming `Message`. Previously we defaulted to 1.0 if we did
not recognize the version number. This commit changes that, leaving the value
unmodified. We default to parsing this mystery event with the 1.0 spec. When
the event is validated with `event.validate()` we return `false`.
One additional small change to eliminate a prettier warning about `parer`
being previously declared.
Fixes: https://github.com/cloudevents/sdk-javascript/issues/332
Fixes: https://github.com/cloudevents/sdk-javascript/issues/333
Signed-off-by: Lance Ball <lball@redhat.com>
Also fixes the case where UPPERCASED extension names were silently changed
to lowercase and then set as undefined. Even though uppercased extension
names are invalid, we should still accept them in incoming messsages and
only throw when validating the event.
Fixes: https://github.com/cloudevents/sdk-javascript/issues/380
Signed-off-by: Lance Ball <lball@redhat.com>
* src: be more forgiving parsing JSON as a string
A simple string is considered valid JSON. However, our parsers do
not accept that unless the string has quotation marks. This commit
modifies the parser to look for strings declared as application/json
which do not begin with '[' '{' or '"' and surrounds them with
quotes.
Signed-off-by: Lance Ball <lball@redhat.com>
The `HTTP.isEvent()` and `HTTP.toEvent()` functions both had some validation
code that violated the principle of loose validation when receiving an
event over HTTP. As discussed, the validation should be managed by the
receiver in this case with `event.validate()`
Signed-off-by: Lance Ball <lball@redhat.com>
* feat!: remove all 4.0 deprecation.
* This removes all the APIs that were deprecated in the 3.x releases and marked as "remove in 4.0".
* Also removes any tests associated with those API's
* squash: remove axios as a dependecy
Signed-off-by: Lucas Holmquist <lholmqui@redhat.com>
This commit extends Node.js IncomingHttpHeaders in our Headers type.
Changes the Headers type to make it more compatible with Node.js TypeScript projects.
Signed-off-by: Lance Ball <lball@redhat.com>
* fix: do not alter an event's data attribute
When setting an event's data attribute we were trying to be really clever
and this is problematic. Instead, keep the data attribute unchanged. Per
the 1.0 specification, the data attribute is still inspected to determine
if it is binary, and if so, a data_base64 attribute is added with the
contents of the data property encoded as base64.
Fixes: https://github.com/cloudevents/sdk-javascript/issues/343
Signed-off-by: Lance Ball <lball@redhat.com>
* feat: add emitterFactory and friends
This commit adds an emitterFactory function that returns an EmitterFunction
object. The EmitterFunction may be used to emit events over a supported
network transport layer. Currently, only HTTP is supported.
Parameters provided to the emitterFactory are the transport Binding (only
HTTP supported), the encoding mode (Mode.BINARY or Mode.STRUCTURED), and
a TransportFunction.
The implementation for emitBinary and emitStructured has been replaced
with this simple pattern and those two functions have been removed.
Example:
```js
// The endpoint URL that will receive the event
const sink = 'https://my-event-sink';
// A function that uses Axios to send a message over HTTP
function axiosEmitter(message: Message, options?: Options): Promise<unknown> {
return axios.post(sink, message.body, { headers: message.headers, ...options });
}
// Create an event emitter
const emit = emitterFactory(HTTP, Mode.BINARY, axiosEmitter);
// Emit an event, sending it to the endpoint URL
emit(new CloudEvent{ source: '/example', type: 'example' });
```
Signed-off-by: Lance Ball <lball@redhat.com>
* feat: add a constructor parameter for loose validation
This commit adds a second, optional boolean parameter to the `CloudEvent`
constructor. When `false` is provided, the event constructor will not
perform validation of the event properties, values and extension names.
This commit also modifies the ValidationError class so that the error message
string includes the JSON.stringified version of any schema validation
errors. It also makes the HTTP.toEvent() function create CloudEvent
objects with loose/no validation.
Incorporates comments from https://github.com/cloudevents/sdk-javascript/pull/328
Fixes: https://github.com/cloudevents/sdk-javascript/issues/325
Signed-off-by: Lance Ball <lball@redhat.com>
Previously, the event's `time` property could be either a string or a date.
this commit modifies that to ensure that the object can only be created with
a timestamp in string format. As long as the string is a valid date, that
can be parsed by `new Date(Date.parse(str))` then whenever the event is
serialized as JSON, the `time` attribute will be formatted as per RFC 3339.
Fixes: https://github.com/cloudevents/sdk-javascript/issues/326
Signed-off-by: Lance Ball <lball@redhat.com>
* lib(messages): Implement a 4.0 Messages and other supporting interfaces
This commit introduces the Message, Serializer and Deserializer, and Binding
interfaces used to convert a CloudEvent into a Message that can be sent across
a transport protocol. The first protocol implemented for this is HTTP, and some
of the functionality formerly in src/transport/http has been simplified,
reduced and/or moved to /src/messages/http.
Test for V1 and V3 events are in place. Conformance tests have been modified to use
these new interfaces vs. the HTTP Receiver class.
Signed-off-by: Lance Ball <lball@redhat.com>
This commit implements 4 of the 6 pending tests that were not completed
during the TypeScript rewrite. The two tests that were not implemented
were (one for each of v1 and v03):
```
it("returns a JSON string even if format is invalid");
```
I don't really know what that's supposed to be/mean, so I removed them.
Fixes: https://github.com/cloudevents/sdk-javascript/issues/232
Signed-off-by: Lance Ball <lball@redhat.com>
* Constants can now be accessed more easily from the top level import/require
users can now do `const { CONSTANTS } = require('cloudevents')`
fixes#298
Signed-off-by: Lucas Holmquist <lholmqui@redhat.com>
The schema incorrectly limits data values to only object and string. This is
incorrect, since JSON can be an array, boolean, a single number or null as well.
This commit modifies the schema to allow for array, boolean and null, and adds
tests.
Fixes: https://github.com/cloudevents/sdk-javascript/issues/280
Signed-off-by: Lance Ball <lball@redhat.com>
This commit modifies the HTTP receivers/parsers to allow for the incoming body
of an HTTP request to be empty if the event message is sent using the binary
mode. In structured mode, a `ValidationError` will still be thrown, since the
entire event must be encoded in the HTTP body.
Signed-off-by: Lance Ball <lball@redhat.com>