Skip to content
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
2 changes: 1 addition & 1 deletion src/event/cloudevent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ See: https://github.com/cloudevents/spec/blob/v1.0/spec.md#type-system`);

set data(value: T | undefined) {
if (isBinary(value)) {
this.data_base64 = asBase64(value);
this.data_base64 = asBase64(value as unknown as Buffer);
}
this.#_data = value;
}
Expand Down
13 changes: 9 additions & 4 deletions src/event/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

import { ErrorObject } from "ajv";

export type TypeArray = Int8Array | Uint8Array | Int16Array | Uint16Array |
Int32Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array;


/**
* An Error class that will be thrown when a CloudEvent
* cannot be properly validated against a specification.
Expand Down Expand Up @@ -36,7 +40,7 @@ export const isDefined = (v: unknown): boolean => v !== null && typeof v !== "un
export const isBoolean = (v: unknown): boolean => typeof v === "boolean";
export const isInteger = (v: unknown): boolean => Number.isInteger(v as number);
export const isDate = (v: unknown): v is Date => v instanceof Date;
export const isBinary = (v: unknown): v is Uint32Array => v instanceof Uint32Array;
export const isBinary = (v: unknown): boolean => ArrayBuffer.isView(v);

export const isStringOrThrow = (v: unknown, t: Error): boolean =>
isString(v)
Expand Down Expand Up @@ -73,7 +77,7 @@ export const isBase64 = (value: unknown): boolean =>

export const isBuffer = (value: unknown): boolean => value instanceof Buffer;

export const asBuffer = (value: string | Buffer | Uint32Array): Buffer =>
export const asBuffer = (value: string | Buffer | TypeArray): Buffer =>
isBinary(value)
? Buffer.from((value as unknown) as string)
: isBuffer(value)
Expand All @@ -82,7 +86,8 @@ export const asBuffer = (value: string | Buffer | Uint32Array): Buffer =>
throw new TypeError("is not buffer or a valid binary");
})();

export const asBase64 = (value: string | Buffer | Uint32Array): string => asBuffer(value).toString("base64");
export const asBase64 =
(value: string | Buffer | TypeArray): string => asBuffer(value).toString("base64");

export const clone = (o: Record<string, unknown>): Record<string, unknown> => JSON.parse(JSON.stringify(o));

Expand All @@ -97,5 +102,5 @@ export const asData = (data: unknown, contentType: string): string => {
return isBinary(maybeJson) ? asBase64(maybeJson) : maybeJson;
};

export const isValidType = (v: boolean | number | string | Date | Uint32Array | unknown): boolean =>
export const isValidType = (v: boolean | number | string | Date | TypeArray | unknown): boolean =>
isBoolean(v) || isInteger(v) || isString(v) || isDate(v) || isBinary(v) || isObject(v);
62 changes: 54 additions & 8 deletions test/integration/spec_1_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,60 @@ describe("CloudEvents Spec v1.0", () => {
expect(typeof ce.data).to.equal("string");
});

it("should be ok when type is 'Uint32Array' for 'Binary'", () => {
const dataString = ")(*~^my data for ce#@#$%";

const dataBinary = Uint32Array.from(dataString, (c) => c.codePointAt(0) as number);
const expected = asBase64(dataBinary);

const ce = cloudevent.cloneWith({ datacontenttype: "text/plain", data: dataBinary });
expect(ce.data_base64).to.equal(expected);
const dataString = ")(*~^my data for ce#@#$%";
const testCases = [
{
type: Int8Array,
data: Int8Array.from(dataString, (c) => c.codePointAt(0) as number),
expected: asBase64(Int8Array.from(dataString, (c) => c.codePointAt(0) as number))
},
{
type: Uint8Array,
data: Uint8Array.from(dataString, (c) => c.codePointAt(0) as number),
expected: asBase64(Uint8Array.from(dataString, (c) => c.codePointAt(0) as number))
},
{
type: Int16Array,
data: Int16Array.from(dataString, (c) => c.codePointAt(0) as number),
expected: asBase64(Int16Array.from(dataString, (c) => c.codePointAt(0) as number))
},
{
type: Uint16Array,
data: Uint16Array.from(dataString, (c) => c.codePointAt(0) as number),
expected: asBase64(Uint16Array.from(dataString, (c) => c.codePointAt(0) as number))
},
{
type: Int32Array,
data: Int32Array.from(dataString, (c) => c.codePointAt(0) as number),
expected: asBase64(Int32Array.from(dataString, (c) => c.codePointAt(0) as number))
},
{
type: Uint32Array,
data: Uint32Array.from(dataString, (c) => c.codePointAt(0) as number),
expected: asBase64(Uint32Array.from(dataString, (c) => c.codePointAt(0) as number))
},
{
type: Uint8ClampedArray,
data: Uint8ClampedArray.from(dataString, (c) => c.codePointAt(0) as number),
expected: asBase64(Uint8ClampedArray.from(dataString, (c) => c.codePointAt(0) as number))
},
{
type: Float32Array,
data: Float32Array.from(dataString, (c) => c.codePointAt(0) as number),
expected: asBase64(Float32Array.from(dataString, (c) => c.codePointAt(0) as number))
},
{
type: Float64Array,
data: Float64Array.from(dataString, (c) => c.codePointAt(0) as number),
expected: asBase64(Float64Array.from(dataString, (c) => c.codePointAt(0) as number))
},
];

testCases.forEach((test) => {
it(`should be ok when type is '${test.type.name}' for 'Binary'`, () => {
const ce = cloudevent.cloneWith({ datacontenttype: "text/plain", data: test.data });
expect(ce.data_base64).to.equal(test.expected);
});
});
});
});