From 8fe81c9d090ce50496f3150602f19433e7aedd1e Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Tue, 19 Dec 2017 17:22:38 -0500 Subject: Refactor JSON parsing in HttpClient --- .../src/utils/orderbook_channel_message_parser.ts | 40 +++++++++++++++++++++ .../src/utils/orderbook_channel_message_parsers.ts | 40 --------------------- .../src/utils/relayer_response_json_parsers.ts | 42 ++++++++++++++++++++++ packages/connect/src/utils/type_converters.ts | 22 +++++++----- 4 files changed, 95 insertions(+), 49 deletions(-) create mode 100644 packages/connect/src/utils/orderbook_channel_message_parser.ts delete mode 100644 packages/connect/src/utils/orderbook_channel_message_parsers.ts create mode 100644 packages/connect/src/utils/relayer_response_json_parsers.ts (limited to 'packages/connect/src/utils') diff --git a/packages/connect/src/utils/orderbook_channel_message_parser.ts b/packages/connect/src/utils/orderbook_channel_message_parser.ts new file mode 100644 index 000000000..adc565d29 --- /dev/null +++ b/packages/connect/src/utils/orderbook_channel_message_parser.ts @@ -0,0 +1,40 @@ +import {assert} from '@0xproject/assert'; +import {schemas} from '@0xproject/json-schemas'; +import * as _ from 'lodash'; + +import { + OrderbookChannelMessage, + OrderbookChannelMessageTypes, +} from '../types'; + +import {relayerResponseJsonParsers} from './relayer_response_json_parsers'; + +export const orderbookChannelMessageParser = { + parse(utf8Data: string): OrderbookChannelMessage { + const messageObj = JSON.parse(utf8Data); + const type: string = _.get(messageObj, 'type'); + assert.assert(!_.isUndefined(type), `Message is missing a type parameter: ${utf8Data}`); + assert.isString('type', type); + switch (type) { + case (OrderbookChannelMessageTypes.Snapshot): { + assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelSnapshotSchema); + const orderbookJson = messageObj.payload; + const orderbook = relayerResponseJsonParsers.parseOrderbookResponseJson(orderbookJson); + return _.assign(messageObj, {payload: orderbook}); + } + case (OrderbookChannelMessageTypes.Update): { + assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelUpdateSchema); + const orderJson = messageObj.payload; + const order = relayerResponseJsonParsers.parseOrderJson(orderJson); + return _.assign(messageObj, {payload: order}); + } + default: { + return { + type: OrderbookChannelMessageTypes.Unknown, + requestId: 0, + payload: undefined, + }; + } + } + }, +}; diff --git a/packages/connect/src/utils/orderbook_channel_message_parsers.ts b/packages/connect/src/utils/orderbook_channel_message_parsers.ts deleted file mode 100644 index d9a84cca2..000000000 --- a/packages/connect/src/utils/orderbook_channel_message_parsers.ts +++ /dev/null @@ -1,40 +0,0 @@ -import {assert} from '@0xproject/assert'; -import {schemas} from '@0xproject/json-schemas'; -import * as _ from 'lodash'; - -import { - OrderbookChannelMessage, - OrderbookChannelMessageTypes, -} from '../types'; - -import {typeConverters} from './type_converters'; - -export const orderbookChannelMessageParsers = { - parser(utf8Data: string): OrderbookChannelMessage { - const messageObj = JSON.parse(utf8Data); - const type: string = _.get(messageObj, 'type'); - assert.assert(!_.isUndefined(type), `Message is missing a type parameter: ${utf8Data}`); - assert.isString('type', type); - switch (type) { - case (OrderbookChannelMessageTypes.Snapshot): { - assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelSnapshotSchema); - const orderbook = messageObj.payload; - typeConverters.convertOrderbookStringFieldsToBigNumber(orderbook); - return messageObj; - } - case (OrderbookChannelMessageTypes.Update): { - assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelUpdateSchema); - const order = messageObj.payload; - typeConverters.convertOrderStringFieldsToBigNumber(order); - return messageObj; - } - default: { - return { - type: OrderbookChannelMessageTypes.Unknown, - requestId: 0, - payload: undefined, - }; - } - } - }, -}; diff --git a/packages/connect/src/utils/relayer_response_json_parsers.ts b/packages/connect/src/utils/relayer_response_json_parsers.ts new file mode 100644 index 000000000..02d88f26d --- /dev/null +++ b/packages/connect/src/utils/relayer_response_json_parsers.ts @@ -0,0 +1,42 @@ +import {assert} from '@0xproject/assert'; +import {schemas} from '@0xproject/json-schemas'; +import * as _ from 'lodash'; + +import { + FeesResponse, + OrderbookResponse, + SignedOrder, + TokenPairsItem, +} from '../types'; + +import {typeConverters} from './type_converters'; + +export const relayerResponseJsonParsers = { + parseTokenPairsJson(json: any): TokenPairsItem[] { + assert.doesConformToSchema('tokenPairs', json, schemas.relayerApiTokenPairsResponseSchema); + return json.map((tokenPair: any) => { + return typeConverters.convertStringsFieldsToBigNumbers(tokenPair, [ + 'tokenA.minAmount', + 'tokenA.maxAmount', + 'tokenB.minAmount', + 'tokenB.maxAmount', + ]); + }); + }, + parseOrdersJson(json: any): SignedOrder[] { + assert.doesConformToSchema('orders', json, schemas.signedOrdersSchema); + return json.map((order: object) => typeConverters.convertOrderStringFieldsToBigNumber(order)); + }, + parseOrderJson(json: any): SignedOrder { + assert.doesConformToSchema('order', json, schemas.signedOrderSchema); + return typeConverters.convertOrderStringFieldsToBigNumber(json); + }, + parseOrderbookResponseJson(json: any): OrderbookResponse { + assert.doesConformToSchema('orderBook', json, schemas.relayerApiOrderBookResponseSchema); + return typeConverters.convertOrderbookStringFieldsToBigNumber(json); + }, + parseFeesResponseJson(json: any): FeesResponse { + assert.doesConformToSchema('fees', json, schemas.relayerApiFeesResponseSchema); + return typeConverters.convertStringsFieldsToBigNumbers(json, ['makerFee', 'takerFee']); + }, +}; diff --git a/packages/connect/src/utils/type_converters.ts b/packages/connect/src/utils/type_converters.ts index 28810af1a..5ba1b8291 100644 --- a/packages/connect/src/utils/type_converters.ts +++ b/packages/connect/src/utils/type_converters.ts @@ -1,15 +1,17 @@ import {BigNumber} from 'bignumber.js'; import * as _ from 'lodash'; -// TODO: convert all of these to non-mutating, pure functions export const typeConverters = { - convertOrderbookStringFieldsToBigNumber(orderbook: object): void { - _.each(orderbook, (orders: object[]) => { - _.each(orders, (order: object) => this.convertOrderStringFieldsToBigNumber(order)); - }); + convertOrderbookStringFieldsToBigNumber(orderbook: any): any { + const bids = _.get(orderbook, 'bids', []); + const asks = _.get(orderbook, 'asks', []); + return { + bids: bids.map((order: any) => this.convertOrderStringFieldsToBigNumber(order)), + asks: asks.map((order: any) => this.convertOrderStringFieldsToBigNumber(order)), + }; }, - convertOrderStringFieldsToBigNumber(order: object): void { - this.convertStringsFieldsToBigNumbers(order, [ + convertOrderStringFieldsToBigNumber(order: any): any { + return this.convertStringsFieldsToBigNumbers(order, [ 'makerTokenAmount', 'takerTokenAmount', 'makerFee', @@ -18,9 +20,11 @@ export const typeConverters = { 'salt', ]); }, - convertStringsFieldsToBigNumbers(obj: object, fields: string[]): void { + convertStringsFieldsToBigNumbers(obj: any, fields: string[]): any { + const result = _.assign({}, obj); _.each(fields, field => { - _.update(obj, field, (value: string) => new BigNumber(value)); + _.update(result, field, (value: string) => new BigNumber(value)); }); + return result; }, }; -- cgit v1.2.3