parse-string-data
Version:
Parse data (object literal / array) from a text string and return a data structure
73 lines (60 loc) • 3.29 kB
JavaScript
;
// Convert strings into a formatted value.
// ---------------------------------------
// - True/False strings into Boolean
// - Null strings to null value
// - Number strings to Number
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
function _formatValues(val) {
var numberVal = Number(val),
valueMap = {
'true': true,
'false': false,
'null': null
};
// Return mapped Value || formatted Number || existing string
return valueMap.hasOwnProperty(val) ? valueMap[val] : !isNaN(numberVal) ? numberVal : val;
}
// Match regex not contined within square or curly brackets
// --------------------------------------------------------
// - Joins regex param with a negative lookahead assertion
function _matchOutsideBrackets(reg) {
var negativeLookaheadForBrackets = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : /(?![^\[]*\]|[^\{]*\})/;
return new RegExp(reg.source + negativeLookaheadForBrackets.source);
}
// Parse an object literal from string
// -----------------------------------
// - Builds a js object manually to avoid using eval() on the server.
// - Used for JS objects that don't conform to JSON spec. i.e. keys that aren't wrapped in a double-quote.
module.exports = function parseStringData() {
var str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var initialValue = arguments[1];
var data = null;
var dataMatch = str.match(_matchOutsideBrackets(/\{(.*)\}|\[(.*)\]/)) || [],
isArray = dataMatch[2] !== undefined,
value = dataMatch[1] || dataMatch[2];
if (value) {
// Regex split on all commas that aren't contained within curly/square brackets.
// Use Array.reduce to reduce array down to a single object literal.
data = value.split(_matchOutsideBrackets(/\,/)).reduce(function () {
var acc = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : isArray ? [] : {};
var item = arguments[1];
var i = arguments[2];
var _ref = Array.isArray(acc) ?
// Assign values to current array index and value
[i, item.trim()]
// Split value on colons to get key:value pairs for objects
: item.split(_matchOutsideBrackets(/\:/)),
_ref2 = _slicedToArray(_ref, 2),
rawKey = _ref2[0],
_ref2$ = _ref2[1],
rawVal = _ref2$ === undefined ? '' : _ref2$;
var key = typeof rawKey === 'string' ? rawKey.trim() : rawKey;
// Recursively check values for data or return a trimmed string
var value = parseStringData(rawVal) || _formatValues(rawVal.trim());
acc[key] = value; // acc.push(parseDataFromString(val) || val);
return acc;
}, initialValue);
}
return data || initialValue || null;
};