From 6692668d19d6f8d478f6ae3b428a3f408eeb6523 Mon Sep 17 00:00:00 2001 From: Olaf Tomalka Date: Fri, 4 Nov 2022 15:37:06 +0100 Subject: [PATCH 1/4] Cast JsonRPC to Json JsonRpcStruct params was type Record | unknown[], but in other parts of the code we use Json to denote such structures. unknown is not castable to Json because of undefined and classes. This commit solves the compatibillity issue with other parts of the code --- src/json.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/json.ts b/src/json.ts index 7847b932..caf92118 100644 --- a/src/json.ts +++ b/src/json.ts @@ -15,13 +15,13 @@ import { union, unknown, } from 'superstruct'; +import { AssertionErrorConstructor, assertStruct } from './assert'; import { calculateNumberSize, calculateStringSize, isPlainObject, JsonSize, } from './misc'; -import { AssertionErrorConstructor, assertStruct } from './assert'; export const JsonStruct = define('Json', (value) => { const [isValid] = validateJsonAndGetSize(value, true); @@ -99,7 +99,10 @@ export type JsonRpcError = OptionalField< 'data' >; -export const JsonRpcParamsStruct = optional(union([object(), array()])); +export const JsonRpcParamsStruct = optional< + Record | Json[], + null +>(union([object(), array()]) as Struct | Json[], null>); export type JsonRpcParams = Infer; From 4a67c5b6da09464e940278cebfa2d79013634cef Mon Sep 17 00:00:00 2001 From: Olaf Tomalka Date: Mon, 7 Nov 2022 14:08:59 +0100 Subject: [PATCH 2/4] PR review changes --- src/json.test.ts | 19 +++++++++++++++---- src/json.ts | 14 ++++++++------ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/json.test.ts b/src/json.test.ts index dc947c09..b8ccdf7b 100644 --- a/src/json.test.ts +++ b/src/json.test.ts @@ -1,4 +1,5 @@ import * as superstructModule from 'superstruct'; +import { validate } from 'superstruct'; import { ARRAY_OF_DIFFRENT_KINDS_OF_NUMBERS, COMPLEX_OBJECT, @@ -13,6 +14,8 @@ import { NON_SERIALIZABLE_NESTED_OBJECT, } from './__fixtures__'; import { + assert, + assertIsJsonRpcError, assertIsJsonRpcFailure, assertIsJsonRpcNotification, assertIsJsonRpcRequest, @@ -20,6 +23,7 @@ import { assertIsJsonRpcSuccess, assertIsPendingJsonRpcResponse, getJsonRpcIdValidator, + isJsonRpcError, isJsonRpcFailure, isJsonRpcNotification, isJsonRpcRequest, @@ -27,12 +31,19 @@ import { isJsonRpcSuccess, isPendingJsonRpcResponse, isValidJson, + JsonStruct, validateJsonAndGetSize, - isJsonRpcError, - assertIsJsonRpcError, } from '.'; describe('json', () => { + describe('JsonStruct', () => { + it('returns error message', () => { + const [error] = validate(undefined, JsonStruct); + assert(error !== undefined); + expect(error.message).toStrictEqual('Expected valid JSON value'); + }); + }); + // TODO: Make this test suite exhaustive. // The current implementation is guaranteed to be correct, but in the future // we may opt for a bespoke implementation that is more performant, but may @@ -425,11 +436,11 @@ describe('json', () => { }; const validateAll = ( - validate: ReturnType, + validator: ReturnType, inputs: ReturnType, ) => { for (const input of Object.values(inputs)) { - expect(validate(input.value)).toStrictEqual(input.expected); + expect(validator(input.value)).toStrictEqual(input.expected); } }; diff --git a/src/json.ts b/src/json.ts index caf92118..b3f7bee8 100644 --- a/src/json.ts +++ b/src/json.ts @@ -10,6 +10,7 @@ import { object, omit, optional, + record, string, Struct, union, @@ -25,7 +26,10 @@ import { export const JsonStruct = define('Json', (value) => { const [isValid] = validateJsonAndGetSize(value, true); - return isValid; + if (!isValid) { + return 'Expected valid JSON value'; + } + return true; }); /** @@ -99,11 +103,9 @@ export type JsonRpcError = OptionalField< 'data' >; -export const JsonRpcParamsStruct = optional< - Record | Json[], - null ->(union([object(), array()]) as Struct | Json[], null>); - +export const JsonRpcParamsStruct = optional( + union([record(string(), JsonStruct), array(JsonStruct)]), +); export type JsonRpcParams = Infer; export const JsonRpcRequestStruct = object({ From 9ea19be96596afc34c31ff350e55ab209e26245f Mon Sep 17 00:00:00 2001 From: Olaf Tomalka Date: Mon, 7 Nov 2022 14:33:55 +0100 Subject: [PATCH 3/4] Nicer JSON validation msg --- src/json.test.ts | 2 +- src/json.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/json.test.ts b/src/json.test.ts index b8ccdf7b..dc2706d1 100644 --- a/src/json.test.ts +++ b/src/json.test.ts @@ -40,7 +40,7 @@ describe('json', () => { it('returns error message', () => { const [error] = validate(undefined, JsonStruct); assert(error !== undefined); - expect(error.message).toStrictEqual('Expected valid JSON value'); + expect(error.message).toStrictEqual('Expected a valid JSON-serializable value'); }); }); diff --git a/src/json.ts b/src/json.ts index b3f7bee8..745d0ea8 100644 --- a/src/json.ts +++ b/src/json.ts @@ -27,7 +27,7 @@ import { export const JsonStruct = define('Json', (value) => { const [isValid] = validateJsonAndGetSize(value, true); if (!isValid) { - return 'Expected valid JSON value'; + return 'Expected a valid JSON-serializable value'; } return true; }); From 97a77575b5951cabbceb7869ab26b79461b9bd6d Mon Sep 17 00:00:00 2001 From: Olaf Tomalka Date: Mon, 7 Nov 2022 14:39:01 +0100 Subject: [PATCH 4/4] Fix lint --- src/json.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/json.test.ts b/src/json.test.ts index dc2706d1..817e37fa 100644 --- a/src/json.test.ts +++ b/src/json.test.ts @@ -40,7 +40,9 @@ describe('json', () => { it('returns error message', () => { const [error] = validate(undefined, JsonStruct); assert(error !== undefined); - expect(error.message).toStrictEqual('Expected a valid JSON-serializable value'); + expect(error.message).toStrictEqual( + 'Expected a valid JSON-serializable value', + ); }); });