var parserMgr = require("./parserMgr.js"); var CSVError = require("./CSVError"); var numReg = /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$/; /** * Convert lines of csv array into json * @param {[type]} lines [[col1,col2,col3]] * @param {[type]} params Converter params with _headers field populated * @param {[type]} idx start pos of the lines * @return {[type]} [{err:null,json:obj,index:line,row:[csv row]}] */ module.exports = function (lines, params, idx) { if (params._needParseJson) { if (!params._headers || !Array.isArray(params._headers)) { params._headers = []; } if (!params.parseRules) { var row = params._headers; params.parseRules = parserMgr.initParsers(row, params); } return processRows(lines, params, idx); } else { return justReturnRows(lines, params, idx); } }; function justReturnRows(lines, params, idx) { var rtn = []; for (var i = 0, len = lines.length; i < len; i++) { rtn.push({ err: null, json: {}, index: idx++, row: lines[i] }); } return rtn; } function processRows(csvRows, params, startIndex) { var res = []; for (var i = 0, len = csvRows.length; i < len; i++) { var r = processRow(csvRows[i], params, startIndex++); if (r) { res.push(r); } } return res; } function processRow(row, param, index) { var parseRules = param.parseRules; if (param.checkColumn && row.length !== parseRules.length) { return { err: CSVError.column_mismatched(index) }; } var headRow = param._headers; var resultRow = convertRowToJson(row, headRow, param); if (resultRow) { return { json: resultRow, index: index, row: row }; } else { return null; } } function convertRowToJson(row, headRow, param) { var hasValue = false; var resultRow = {}; for (var i = 0, len = row.length; i < len; i++) { var convertFunc, head, item; item = row[i]; if (param.ignoreEmpty && item === '') { continue; } hasValue = true; head = headRow[i]; if (!head || head === "") { head = headRow[i] = "field" + (i + 1); } var convFunc = getConvFunc(head, i, param); if (convFunc) { var convRes = convFunc(item, head, resultRow,row,i); if (convRes !== undefined) { setPath(resultRow, head, convRes); } } else { var flag = getFlag(head, i, param); if (flag === 'omit') { continue; } if (param.checkType) { convertFunc = checkType(item, head, i, param); item = convertFunc(item); } var title = getTitle(head, i, param); if (flag === 'flat' || param.flatKeys) { resultRow[title] = item; } else { setPath(resultRow, title, item); } } } if (hasValue) { return resultRow; } else { return false; } } var builtInConv={ "string":stringType, "number":numberType, "omit":function(){} } function getConvFunc(head,i,param){ if (param._columnConv[i] !== undefined){ return param._columnConv[i]; }else{ var flag=param.colParser[head]; if (flag === undefined){ return param._columnConv[i]=false; } if (typeof flag ==="string"){ flag=flag.trim().toLowerCase(); var builtInFunc=builtInConv[flag]; if (builtInFunc){ return param._columnConv[i]=builtInFunc; }else{ return param._columnConv[i]=false; } }else if (typeof flag ==="function"){ return param._columnConv[i]=flag; }else{ return param._columnConv[i]=false; } } } function setPath(json, path, value) { var _set = require('lodash/set'); var pathArr = path.split('.'); if (pathArr.length === 1) { json[path] = value; } else { _set(json, path, value); } } function getFlag(head, i, param) { if (typeof param._headerFlag[i] === "string") { return param._headerFlag[i]; } else if (head.indexOf('*omit*') > -1) { return param._headerFlag[i] = 'omit'; } else if (head.indexOf('*flat*') > -1) { return param._headerFlag[i] = 'flat'; } else { return param._headerFlag[i] = ''; } } function getTitle(head, i, param) { if (param._headerTitle[i]) { return param._headerTitle[i]; } var flag = getFlag(head, i, param); var str = head.replace('*flat*', '').replace('string#!', '').replace('number#!', ''); return param._headerTitle[i] = str; } function checkType(item, head, headIdx, param) { if (param._headerType[headIdx]) { return param._headerType[headIdx]; } else if (head.indexOf('number#!') > -1) { return param._headerType[headIdx] = numberType; } else if (head.indexOf('string#!') > -1) { return param._headerType[headIdx] = stringType; } else if (param.checkType) { return param._headerType[headIdx] = dynamicType; } else { return param._headerType[headIdx] = stringType; } } function numberType(item) { var rtn = parseFloat(item); if (isNaN(rtn)) { return item; } return rtn; } function stringType(item) { return item.toString(); } function dynamicType(item) { var trimed = item.trim(); if (trimed === "") { return stringType(item); } if (numReg.test(trimed)) { return numberType(item); } else if (trimed.length === 5 && trimed.toLowerCase() === "false" || trimed.length === 4 && trimed.toLowerCase() === "true") { return booleanType(item); } else if (trimed[0] === "{" && trimed[trimed.length - 1] === "}" || trimed[0] === "[" && trimed[trimed.length - 1] === "]") { return jsonType(item); } else { return stringType(item); } } function booleanType(item) { var trimed = item.trim(); if (trimed.length === 5 && trimed.toLowerCase() === "false") { return false; } else { return true; } } function jsonType(item) { try { return JSON.parse(item); } catch (e) { return item; } }