You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
You library, along with the reference code, was super helpful.
We ported this to typescript as it is important for us to not only gain the security advantages, but to further flesh out the test suite and allow use of the library in not only Node.js but also in Deno and the browser.
We'd love for you to take a look, and if there are any comments about our friendly fork please do let me know.
Out of curiosity I also copied your most current code over and ran our test suite against it. The following was the output (and will show a couple of the differences in how we're handling certain cases. I went through a number of manual test cases to see how JSON.stringify() is documented to work and tried to get the output to align closely with that.
Some of the differences are the handling of:
BigInt values should throw an Error as JSON.stringify() does. The user would need to call .toString() on the BigInt.
Serialization of function values to in Arrays/Objects to null, not undefined which is not valid JSON
Removal of Object key:value where the value is undefined (e.g. Symbol() values)
Here's the test output.
❯ npm t
> @truestamp/[email protected] test
> jest
PASS tests/testdata.spec.ts
FAIL tests/basics.spec.ts
● serializing › should behave like JSON.stringify() for › BigInt should throw a TypeError
expect(received).toThrow(expected)
Expected substring: "BigInt value can't be serialized in JSON"
Received message: "Do not know how to serialize a BigInt"
2 | export default function canonify(object: any): string | undefined {
3 | if (object === null || typeof object !== 'object') {
> 4 | return JSON.stringify(object);
| ^
5 | }
6 |
7 | if (object.toJSON instanceof Function) {
at canonify (src/index.ts:4:17)
at t (tests/basics.spec.ts:69:17)
at Object.<anonymous> (node_modules/expect/build/toThrowMatchers.js:83:11)
at Object.throwingMatcher [as toThrow] (node_modules/expect/build/index.js:382:21)
at Object.<anonymous> (tests/basics.spec.ts:72:17)
70 | };
71 | expect(t).toThrow(TypeError);
> 72 | expect(t).toThrow("BigInt value can't be serialized in JSON");
| ^
73 | });
74 |
75 | // JSON.stringify('foo')
at Object.<anonymous> (tests/basics.spec.ts:72:17)
● serializing › should behave like JSON.stringify() for › Array
expect(received).toEqual(expected) // deep equality
Expected: "[null,null,true,false,\"foo\",42,\"42\",null,null]"
Received: "[null,null,true,false,\"foo\",42,\"42\",null,undefined]"
93 | test('Array', () => {
94 | const a = [undefined, null, true, false, "foo", 42, BigInt(42).toString(), Symbol('hello'), () => { }]
> 95 | expect(canonify(a)).toEqual('[null,null,true,false,"foo",42,"42",null,null]')
| ^
96 | })
97 |
98 | test('Array with String keys', () => {
at Object.<anonymous> (tests/basics.spec.ts:95:27)
● serializing › should behave like JSON.stringify() for › Object
expect(received).toEqual(expected) // deep equality
Expected: "{\"big\":\"42\",\"f\":false,\"n\":null,\"num\":42,\"s\":\"string\",\"t\":true}"
Received: "{\"big\":\"42\",\"f\":false,\"fun\":undefined,\"n\":null,\"num\":42,\"s\":\"string\",\"t\":true}"
107 | test('Object', () => {
108 | const o = { big: BigInt(42).toString(), f: false, fun: () => { }, n: null, num: 42, s: "string", sym: Symbol('hello'), t: true, u: undefined }
> 109 | expect(canonify(o)).toEqual('{"big":"42","f":false,"n":null,"num":42,"s":"string","t":true}')
| ^
110 | })
111 |
112 | // Standard data structures
at Object.<anonymous> (tests/basics.spec.ts:109:27)
● serializing › should behave like JSON.stringify() for › Symbols
expect(received).toEqual(expected) // deep equality
Expected: "{}"
Received: "{\"y\":undefined}"
146 | // @ts-ignore-next-line
147 | const e1 = { x: undefined, y: Object, z: Symbol('') }
> 148 | expect(canonify(e1)).toEqual('{}')
| ^
149 |
150 | // @ts-ignore-next-line
151 | const e2 = { [Symbol('foo')]: 'foo' }
at Object.<anonymous> (tests/basics.spec.ts:148:28)
● serializing › arrays should handle › a one element function array
expect(received).toEqual(expected) // deep equality
Expected: "[null]"
Received: "[undefined]"
232 | test('a one element function array', () => {
233 | let f = function foo() { }
> 234 | expect(canonify([f])).toEqual('[null]');
| ^
235 | });
236 |
237 | test('a nested array', () => {
at Object.<anonymous> (tests/basics.spec.ts:234:29)
● serializing › objects should handle › an object with a function value
expect(received).toEqual(expected) // deep equality
Expected: "{}"
Received: "{\"test\":undefined}"
291 | test('an object with a function value', () => {
292 | let f = function foo() { }
> 293 | expect(canonify({ test: f })).toEqual('{}');
| ^
294 | });
295 |
296 | test('an object with a toJSON serializer function value', () => {
at Object.<anonymous> (tests/basics.spec.ts:293:37)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.ts | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 failed, 1 passed, 2 total
Tests: 6 failed, 47 passed, 53 total
Snapshots: 0 total
Time: 4.451 s
Ran all test suites.
Cheers.
Glenn
The text was updated successfully, but these errors were encountered:
To any future people who were confused, like me, truestamp's canonify github repo is no longer accessible (I don't know why). Their NPM entry for it is still public: https://www.npmjs.com/package/@truestamp/canonify
Hello, this is not an issue, but just to say thanks for the code which served as part of the base for our Typescript port.
https://github.com/truestamp/truestamp-canonify
You library, along with the reference code, was super helpful.
We ported this to typescript as it is important for us to not only gain the security advantages, but to further flesh out the test suite and allow use of the library in not only Node.js but also in Deno and the browser.
We'd love for you to take a look, and if there are any comments about our friendly fork please do let me know.
Out of curiosity I also copied your most current code over and ran our test suite against it. The following was the output (and will show a couple of the differences in how we're handling certain cases. I went through a number of manual test cases to see how
JSON.stringify()
is documented to work and tried to get the output to align closely with that.Some of the differences are the handling of:
BigInt
values should throw an Error asJSON.stringify()
does. The user would need to call.toString()
on the BigInt.function
values to in Arrays/Objects tonull
, notundefined
which is not valid JSONundefined
(e.g. Symbol() values)Here's the test output.
Cheers.
Glenn
The text was updated successfully, but these errors were encountered: