diff --git a/package-lock.json b/package-lock.json index b84fe525..b823dc6a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "ajv": "^8.6.3", "ajv-formats": "^2.1.1", + "json-bigint": "^1.0.0", "util": "^0.12.4", "uuid": "^8.3.2" }, @@ -19,6 +20,7 @@ "@types/chai": "^4.2.11", "@types/cucumber": "^6.0.1", "@types/got": "^9.6.11", + "@types/json-bigint": "^1.0.1", "@types/mocha": "^7.0.2", "@types/node": "^14.14.10", "@types/superagent": "^4.1.10", @@ -985,6 +987,12 @@ "integrity": "sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==", "dev": true }, + "node_modules/@types/json-bigint": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/json-bigint/-/json-bigint-1.0.1.tgz", + "integrity": "sha512-zpchZLNsNuzJHi6v64UBoFWAvQlPhch7XAi36FkH6tL1bbbmimIF+cS7vwkzY4u5RaSWMoflQfu+TshMPPw8uw==", + "dev": true + }, "node_modules/@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -1773,6 +1781,14 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -4603,6 +4619,14 @@ "node": ">=4" } }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -9741,6 +9765,12 @@ "integrity": "sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==", "dev": true }, + "@types/json-bigint": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/json-bigint/-/json-bigint-1.0.1.tgz", + "integrity": "sha512-zpchZLNsNuzJHi6v64UBoFWAvQlPhch7XAi36FkH6tL1bbbmimIF+cS7vwkzY4u5RaSWMoflQfu+TshMPPw8uw==", + "dev": true + }, "@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -10347,6 +10377,11 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==" + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -12443,6 +12478,14 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, + "json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "requires": { + "bignumber.js": "^9.0.0" + } + }, "json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", diff --git a/package.json b/package.json index ba0ab2d8..d8bad166 100644 --- a/package.json +++ b/package.json @@ -112,6 +112,7 @@ "dependencies": { "ajv": "^8.6.3", "ajv-formats": "^2.1.1", + "json-bigint": "^1.0.0", "util": "^0.12.4", "uuid": "^8.3.2" }, @@ -120,6 +121,7 @@ "@types/chai": "^4.2.11", "@types/cucumber": "^6.0.1", "@types/got": "^9.6.11", + "@types/json-bigint": "^1.0.1", "@types/mocha": "^7.0.2", "@types/node": "^14.14.10", "@types/superagent": "^4.1.10", diff --git a/src/message/http/index.ts b/src/message/http/index.ts index e4cd7387..95d06ba1 100644 --- a/src/message/http/index.ts +++ b/src/message/http/index.ts @@ -4,6 +4,7 @@ */ import { types } from "util"; +import JSON from "json-bigint"; import { CloudEvent, CloudEventV1, CONSTANTS, Mode, Version } from "../.."; import { Message, Headers, Binding } from ".."; diff --git a/src/parsers.ts b/src/parsers.ts index 9af91039..92a17926 100644 --- a/src/parsers.ts +++ b/src/parsers.ts @@ -3,6 +3,7 @@ SPDX-License-Identifier: Apache-2.0 */ +import JSON from "json-bigint"; import CONSTANTS from "./constants"; import { isString, isDefinedOrThrow, isStringOrObjectOrThrow, ValidationError } from "./event/validation"; diff --git a/test/integration/message_test.ts b/test/integration/message_test.ts index f4f8e210..be9fe24b 100644 --- a/test/integration/message_test.ts +++ b/test/integration/message_test.ts @@ -41,6 +41,23 @@ const imageData = new Uint32Array(fs.readFileSync(path.join(process.cwd(), "test const image_base64 = asBase64(imageData); describe("HTTP transport", () => { + it("Handles big integers in structured mode", () => { + const ce = HTTP.toEvent({ + headers: { "content-type": "application/cloudevents+json" }, + body: `{"data": 1524831183200260097}` + }) as CloudEvent; + expect(String(ce.data)).to.equal(String(1524831183200260097n)); + }); + + it("Handles big integers in binary mode", () => { + const ce = HTTP.toEvent({ + headers: { "content-type": "application/json", "ce-id": "1234" }, + body: `{"data": 1524831183200260097}` + }) as CloudEvent>; + console.error(ce.data); + expect(String((ce.data as Record).data)).to.equal(String(1524831183200260097n)); + }); + it("Handles events with no content-type and no datacontenttype", () => { const body = "{Something[Not:valid}JSON"; const message: Message = { diff --git a/test/integration/parser_test.ts b/test/integration/parser_test.ts index aa86983b..1a85c468 100644 --- a/test/integration/parser_test.ts +++ b/test/integration/parser_test.ts @@ -56,7 +56,11 @@ describe("JSON Event Format Parser", () => { const parser = new Parser(); // TODO: Should the parser catch the SyntaxError and re-throw a ValidationError? - expect(parser.parse.bind(parser, payload)).to.throw(SyntaxError, "Unexpected token g in JSON at position 1"); + try { + parser.parse(payload); + } catch (error: any) { + expect(error.message).to.equal("Bad string"); + } }); it("Accepts a string as valid JSON", () => { diff --git a/tsconfig.json b/tsconfig.json index a073e029..35a839b9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "ES2016", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ + "target": "ES2020", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ "allowJs": true, /* Allow javascript files to be compiled. */ "checkJs": false, /* Report errors in .js files. */