UNPKG

@barchart/common-node-js

Version:

Common classes, utilities, and functions for building Node.js servers

173 lines (134 loc) 3.81 kB
const assert = require('@barchart/common-js/lang/assert'), is = require('@barchart/common-js/lang/is'); const AttributeSerializer = require('./AttributeSerializer'), BooleanSerializer = require('./BooleanSerializer'), NumberSerializer = require('./NumberSerializer'), StringSerializer = require('./StringSerializer'); const DataType = require('./../../definitions/DataType'); module.exports = (() => { 'use strict'; /** * Converts a map into (and back from) the representation used * on a DynamoDB record. * * @public * @extends {AttributeSerializer} */ class MapSerializer extends AttributeSerializer { constructor() { super(); } serialize(map) { assert.argumentIsRequired(map, 'map', Object); const wrapper = { }; const serialized = { }; Object.keys(map).forEach((key) => { const dt = SUPPORTED_DATA_TYPES.find((sdt) => sdt.is(map[key])); if (!dt) { throw new Error(`Failed to serialize list item. Provided type for [ ${map[key]} ] is not supported.`); } serialized[key] = dt.serializer.serialize(map[key]); }); wrapper[DataType.MAP.code] = serialized; return wrapper; } deserialize(wrapper) { const deserialized = { }; const map = wrapper[DataType.MAP.code]; Object.keys(map).forEach((key) => { const dt = SUPPORTED_DATA_TYPES.find((sdt) => !is.undefined(map[key][sdt.type.code])); if (!dt) { throw new Error(`Failed to deserialize list item. Provided type for [ ${map[key]} ] is not supported.`); } deserialized[key] = dt.serializer.deserialize(map[key]); }); return deserialized; } static get INSTANCE() { return instanceMap; } toString() { return '[MapSerializer]'; } } /** * Converts a list into (and back from) the representation used * on a DynamoDB record. * * @public * @extends {AttributeSerializer} */ class ListSerializer extends AttributeSerializer { constructor() { super(); } serialize(list) { assert.argumentIsArray(list, 'list'); const wrapper = { }; const serialized = list.reduce((acc, item) => { const dt = SUPPORTED_DATA_TYPES.find((sdt) => sdt.is(item)); if (!dt) { throw new Error(`Failed to serialize list item. Provided type for [ ${item} ] is not supported.`); } acc.push(dt.serializer.serialize(item)); return acc; }, [ ]); wrapper[DataType.LIST.code] = serialized; return wrapper; } deserialize(wrapper) { const deserialized = wrapper[DataType.LIST.code]; return deserialized.reduce((acc, item) => { const dt = SUPPORTED_DATA_TYPES.find((sdt) => !is.undefined(item[sdt.type.code])); if (!dt) { throw new Error(`Failed to deserialize list item. Provided type for [ ${item} ] is not supported.`); } acc.push(dt.serializer.deserialize(item)); return acc; }, [ ]); } /** * A singleton. * * @public * @static * @returns {ListSerializer} */ static get INSTANCE() { return instanceList; } toString() { return '[ListSerializer]'; } } const instanceList = new ListSerializer(); const instanceMap = new MapSerializer(); const SUPPORTED_DATA_TYPES = [ { type: DataType.BOOLEAN, is: (value) => is.boolean(value), serializer: BooleanSerializer.INSTANCE, }, { type: DataType.LIST, is: (value) => is.array(value), serializer: ListSerializer.INSTANCE, }, { type: DataType.NUMBER, is: (value) => is.number(value), serializer: NumberSerializer.INSTANCE, }, { type: DataType.STRING, is: (value) => is.string(value), serializer: StringSerializer.INSTANCE, }, { type: DataType.MAP, is: (value) => is.object(value) && !is.array(value), serializer: MapSerializer.INSTANCE, }, ]; return { MapSerializer, ListSerializer }; })();