fix: allow `TypedArray` for binary data (#494)
* 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>
This commit is contained in:
parent
a62eb44669
commit
921e273ede
|
@ -133,7 +133,7 @@ See: https://github.com/cloudevents/spec/blob/v1.0/spec.md#type-system`);
|
||||||
|
|
||||||
set data(value: T | undefined) {
|
set data(value: T | undefined) {
|
||||||
if (isBinary(value)) {
|
if (isBinary(value)) {
|
||||||
this.data_base64 = asBase64(value);
|
this.data_base64 = asBase64(value as unknown as Buffer);
|
||||||
}
|
}
|
||||||
this.#_data = value;
|
this.#_data = value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
|
|
||||||
import { ErrorObject } from "ajv";
|
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
|
* An Error class that will be thrown when a CloudEvent
|
||||||
* cannot be properly validated against a specification.
|
* cannot be properly validated against a specification.
|
||||||
|
@ -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 isBoolean = (v: unknown): boolean => typeof v === "boolean";
|
||||||
export const isInteger = (v: unknown): boolean => Number.isInteger(v as number);
|
export const isInteger = (v: unknown): boolean => Number.isInteger(v as number);
|
||||||
export const isDate = (v: unknown): v is Date => v instanceof Date;
|
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 =>
|
export const isStringOrThrow = (v: unknown, t: Error): boolean =>
|
||||||
isString(v)
|
isString(v)
|
||||||
|
@ -73,7 +77,7 @@ export const isBase64 = (value: unknown): boolean =>
|
||||||
|
|
||||||
export const isBuffer = (value: unknown): boolean => value instanceof Buffer;
|
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)
|
isBinary(value)
|
||||||
? Buffer.from((value as unknown) as string)
|
? Buffer.from((value as unknown) as string)
|
||||||
: isBuffer(value)
|
: isBuffer(value)
|
||||||
|
@ -82,7 +86,8 @@ export const asBuffer = (value: string | Buffer | Uint32Array): Buffer =>
|
||||||
throw new TypeError("is not buffer or a valid binary");
|
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));
|
export const clone = (o: Record<string, unknown>): Record<string, unknown> => JSON.parse(JSON.stringify(o));
|
||||||
|
|
||||||
|
@ -97,5 +102,5 @@ export const asData = (data: unknown, contentType: string): string => {
|
||||||
return isBinary(maybeJson) ? asBase64(maybeJson) : maybeJson;
|
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);
|
isBoolean(v) || isInteger(v) || isString(v) || isDate(v) || isBinary(v) || isObject(v);
|
||||||
|
|
|
@ -173,14 +173,60 @@ describe("CloudEvents Spec v1.0", () => {
|
||||||
expect(typeof ce.data).to.equal("string");
|
expect(typeof ce.data).to.equal("string");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should be ok when type is 'Uint32Array' for 'Binary'", () => {
|
|
||||||
const dataString = ")(*~^my data for ce#@#$%";
|
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))
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const dataBinary = Uint32Array.from(dataString, (c) => c.codePointAt(0) as number);
|
testCases.forEach((test) => {
|
||||||
const expected = asBase64(dataBinary);
|
it(`should be ok when type is '${test.type.name}' for 'Binary'`, () => {
|
||||||
|
const ce = cloudevent.cloneWith({ datacontenttype: "text/plain", data: test.data });
|
||||||
const ce = cloudevent.cloneWith({ datacontenttype: "text/plain", data: dataBinary });
|
expect(ce.data_base64).to.equal(test.expected);
|
||||||
expect(ce.data_base64).to.equal(expected);
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue