Skip to content

Commit

Permalink
Add utility to support json serializtion/deserialization with JSONBigInt
Browse files Browse the repository at this point in the history
fixes #57

Signed-off-by: Bernd Hufmann <[email protected]>
  • Loading branch information
bhufmann committed Jan 13, 2023
1 parent 30e85df commit e611c16
Show file tree
Hide file tree
Showing 16 changed files with 125 additions and 13 deletions.
2 changes: 1 addition & 1 deletion tsp-typescript-client/src/models/annotation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { array, assertNumber, createNormalizer, record } from '../protocol/serialization';
import { array, assertNumber, createNormalizer, record } from '../utils/serialization';
import { OutputElementStyle } from './styles';

export enum Type {
Expand Down
2 changes: 1 addition & 1 deletion tsp-typescript-client/src/models/bookmark.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createNormalizer } from '../protocol/serialization';
import { createNormalizer } from '../utils/serialization';

export const Bookmark = createNormalizer<Bookmark>({
endTime: BigInt,
Expand Down
2 changes: 1 addition & 1 deletion tsp-typescript-client/src/models/entry.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { array, assertNumber, createNormalizer, Normalizer } from '../protocol/serialization';
import { array, assertNumber, createNormalizer, Normalizer } from '../utils/serialization';
import { OutputElementStyle } from './styles';

export const Entry = createNormalizer<Entry>({
Expand Down
2 changes: 1 addition & 1 deletion tsp-typescript-client/src/models/experiment.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { array, assertNumber, createNormalizer } from '../protocol/serialization';
import { array, assertNumber, createNormalizer } from '../utils/serialization';
import { Trace } from './trace';

export const Experiment = createNormalizer<Experiment>({
Expand Down
2 changes: 1 addition & 1 deletion tsp-typescript-client/src/models/output-descriptor.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createNormalizer } from '../protocol/serialization';
import { createNormalizer } from '../utils/serialization';

export const OutputDescriptor = createNormalizer<OutputDescriptor>({
end: BigInt,
Expand Down
2 changes: 1 addition & 1 deletion tsp-typescript-client/src/models/response/responses.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Deserialized, createNormalizer, Normalizer } from '../../protocol/serialization';
import { Deserialized, createNormalizer, Normalizer } from '../../utils/serialization';

/**
* Response status
Expand Down
2 changes: 1 addition & 1 deletion tsp-typescript-client/src/models/styles.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createNormalizer } from '../protocol/serialization';
import { createNormalizer } from '../utils/serialization';

export const OutputElementStyle = createNormalizer<OutputElementStyle>({
values: undefined,
Expand Down
2 changes: 1 addition & 1 deletion tsp-typescript-client/src/models/table.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { array, assertNumber, createNormalizer } from '../protocol/serialization';
import { array, assertNumber, createNormalizer } from '../utils/serialization';

export const ColumnHeaderEntry = createNormalizer<ColumnHeaderEntry>({
id: assertNumber,
Expand Down
2 changes: 1 addition & 1 deletion tsp-typescript-client/src/models/timegraph.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { array, assertNumber, createNormalizer } from '../protocol/serialization';
import { array, assertNumber, createNormalizer } from '../utils/serialization';
import { Entry } from './entry';
import { OutputElementStyle } from './styles';

Expand Down
2 changes: 1 addition & 1 deletion tsp-typescript-client/src/models/trace.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assertNumber, createNormalizer } from '../protocol/serialization';
import { assertNumber, createNormalizer } from '../utils/serialization';

export const Trace = createNormalizer<Trace>({
end: BigInt,
Expand Down
2 changes: 1 addition & 1 deletion tsp-typescript-client/src/models/xy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { array, assertNumber, createNormalizer, toBigInt } from '../protocol/serialization';
import { array, assertNumber, createNormalizer, toBigInt } from '../utils/serialization';
import { Entry } from './entry';
import { OutputElementStyle } from "./styles";

Expand Down
2 changes: 1 addition & 1 deletion tsp-typescript-client/src/protocol/rest-client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import fetch, { Headers } from 'node-fetch';
import { Deserialized, Normalizer } from './serialization';
import { Deserialized, Normalizer } from '../utils/serialization';
import { TspClientResponse } from './tsp-client-response';
import JSONBigConfig = require('json-bigint');

Expand Down
2 changes: 1 addition & 1 deletion tsp-typescript-client/src/protocol/tsp-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { TspClientResponse } from './tsp-client-response';
import { OutputStyleModel } from '../models/styles';
import { HealthStatus } from '../models/health';
import { MarkerSet } from '../models/markerset';
import { array } from './serialization';
import { array } from '../utils/serialization';

/**
* Trace Server Protocol client
Expand Down
49 changes: 49 additions & 0 deletions tsp-typescript-client/src/utils/serialization-utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// tslint:disable: no-unused-expression

import { Query } from '../models/query/query';
import { HttpRequest, HttpResponse, RestClient } from '../protocol/rest-client';
import { FixtureSet } from '../protocol/test-utils';
import { TspClient } from '../protocol/tsp-client';
import { SerializationUtil } from './serialization-utils';
import { Experiment } from '../models/experiment';

describe('SerializationUtils tests', () => {

const client = new TspClient('not-relevant');
const httpRequestMock = jest.fn<Promise<HttpResponse>, [req: HttpRequest]>();

let fixtures: FixtureSet;

beforeAll(async () => {
fixtures = await FixtureSet.fromFolder(__dirname, '../../fixtures/tsp-client');
RestClient['httpRequest'] = httpRequestMock;
});

beforeEach(() => {
httpRequestMock.mockReset();
httpRequestMock.mockResolvedValue({ text: '', status: 404, statusText: 'Not found' });
});

it('testSerializationUtil', async () => {
httpRequestMock.mockReturnValueOnce(fixtures.asResponse('create-experiment-0.json'));
const response = await client.createExperiment(new Query({}));
const experiment = response.getModel()!;

const input = SerializationUtil.serialize(experiment);
const experiment2 = SerializationUtil.deserialize(input, Experiment);

expect(experiment).toEqual(experiment2);
});

it('testSerializationUtil-no-normalizer', async () => {
const inputObj = 'hallo';
const input = SerializationUtil.serialize(inputObj);
const output = SerializationUtil.deserialize<string>(input);
expect(typeof output).toEqual('string');

let bigIntObj = BigInt("1234567890123456789");
const bigIntInput = SerializationUtil.serialize(bigIntObj);
const bigIntOutput = SerializationUtil.deserialize<bigint>(bigIntInput);
expect(typeof bigIntOutput).toEqual('bigint');
});
});
63 changes: 63 additions & 0 deletions tsp-typescript-client/src/utils/serialization-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Deserialized, Normalizer } from './serialization';
import JSONBigConfig = require('json-bigint');

const JSONBig = JSONBigConfig({
useNativeBigInt: true,
});

/**
* Rest client helper to make request.
* The request response status code indicates if the request is successful.
* The json object in the response may be undefined when an error occurs.
*/
export class SerializationUtil {

static deserialize<T>(url: string): Deserialized<T>;
static deserialize<T>(input: string, normalizer?: Normalizer<T>): T;
/**
* Parse JSON-encoded data using a normalizer. It will create `BigInt'
* values instead of `number` as defined by normalizer.
*
* @template T is the expected type of the json object returned
* @param input Input JSON string to deserialize
* @param normalizer Normalizer to create type T
*/
static deserialize<T>(input: string, normalizer?: Normalizer<T>) {
try {
const parsed = this.jsonParse(input);
try {
if (normalizer) {
return normalizer(parsed) as T;
}
return parsed as T;
} catch (err) {
console.log('Error normalizing parsed input string: ' + err.toString());
}
} catch (err) {
console.log('Error parsing input string: ' + JSON.stringify(err));
}
return null;
}

/**
* Stringify JS objects. Can stringify `BigInt` values.
*/
static serialize(object: any): string {
return this.jsonStringify(object);
}

/**
* Stringify JS objects. Can stringify `BigInt` values.
*/
protected static jsonStringify(data: any): string {
return JSONBig.stringify(data);
}

/**
* Parse JSON-encoded data. If a number is too large to fit into a regular
* `number` then it will be deserialized as `BigInt`.
*/
protected static jsonParse(text: string): any {
return JSONBig.parse(text);
}
}

0 comments on commit e611c16

Please sign in to comment.