Skip to content

Commit

Permalink
Cast JsonRPC to Json (#51)
Browse files Browse the repository at this point in the history
* Cast JsonRPC to Json

JsonRpcStruct params was type Record<string, unknown> | 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

* PR review changes

* Nicer JSON validation msg

* Fix lint
  • Loading branch information
ritave authored and Mrtenz committed Dec 2, 2022
1 parent f019ec6 commit 6a78b83
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 8 deletions.
21 changes: 17 additions & 4 deletions 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,
Expand All @@ -13,26 +14,38 @@ import {
NON_SERIALIZABLE_NESTED_OBJECT,
} from './__fixtures__';
import {
assert,
assertIsJsonRpcError,
assertIsJsonRpcFailure,
assertIsJsonRpcNotification,
assertIsJsonRpcRequest,
assertIsJsonRpcResponse,
assertIsJsonRpcSuccess,
assertIsPendingJsonRpcResponse,
getJsonRpcIdValidator,
isJsonRpcError,
isJsonRpcFailure,
isJsonRpcNotification,
isJsonRpcRequest,
isJsonRpcResponse,
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 a valid JSON-serializable 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
Expand Down Expand Up @@ -425,11 +438,11 @@ describe('json', () => {
};

const validateAll = (
validate: ReturnType<typeof getJsonRpcIdValidator>,
validator: ReturnType<typeof getJsonRpcIdValidator>,
inputs: ReturnType<typeof getInputs>,
) => {
for (const input of Object.values(inputs)) {
expect(validate(input.value)).toStrictEqual(input.expected);
expect(validator(input.value)).toStrictEqual(input.expected);
}
};

Expand Down
13 changes: 9 additions & 4 deletions src/json.ts
Expand Up @@ -10,22 +10,26 @@ import {
object,
omit,
optional,
record,
string,
Struct,
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>('Json', (value) => {
const [isValid] = validateJsonAndGetSize(value, true);
return isValid;
if (!isValid) {
return 'Expected a valid JSON-serializable value';
}
return true;
});

/**
Expand Down Expand Up @@ -99,8 +103,9 @@ export type JsonRpcError = OptionalField<
'data'
>;

export const JsonRpcParamsStruct = optional(union([object(), array()]));

export const JsonRpcParamsStruct = optional(
union([record(string(), JsonStruct), array(JsonStruct)]),
);
export type JsonRpcParams = Infer<typeof JsonRpcParamsStruct>;

export const JsonRpcRequestStruct = object({
Expand Down

0 comments on commit 6a78b83

Please sign in to comment.