convert-csv-to-json2
Version:
Convert CSV to JSON
1 lines • 14.1 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts","../src/util/fileUtils.ts","../src/util/jsonUtils.ts","../src/util/stringUtils.ts"],"sourcesContent":["import { PathOrFileDescriptor } from 'fs';\nimport { ENCODING } from './common/constants';\nimport { readFile, writeFile } from './util/fileUtils';\nimport { validateJson } from './util/jsonUtils';\nimport { getValueFormatByType } from './util/stringUtils';\n\nexport type CsvJsonRow = Record<\n string,\n string | number | boolean | (string | number | boolean)[]\n>;\n\nexport class ConvertCsvToJson {\n printValueFormatByType?: boolean;\n isSupportQuotedField?: boolean;\n delimiter?: string;\n isTrimHeaderFieldWhiteSpace?: boolean;\n _indexHeader?: number;\n parseSubArrayDelimiter?: string;\n parseSubArraySeparator?: string;\n encoding: ENCODING = ENCODING.utf8;\n\n formatValueByType(active: boolean = true): this {\n this.printValueFormatByType = active;\n return this;\n }\n\n supportQuotedField(active: boolean = false): this {\n this.isSupportQuotedField = active;\n return this;\n }\n\n fieldDelimiter(delimiter: string): this {\n this.delimiter = delimiter;\n return this;\n }\n\n trimHeaderFieldWhiteSpace(active: boolean = false): this {\n this.isTrimHeaderFieldWhiteSpace = active;\n return this;\n }\n\n indexHeader(indexHeader: number): this {\n if (isNaN(indexHeader)) {\n throw new Error('The index Header must be a Number!');\n }\n this._indexHeader = indexHeader;\n return this;\n }\n\n parseSubArray(delimiter: string = '*', separator: string = ','): this {\n this.parseSubArrayDelimiter = delimiter;\n this.parseSubArraySeparator = separator;\n return this;\n }\n\n customEncoding(encoding: ENCODING): this {\n this.encoding = encoding;\n return this;\n }\n\n utf8Encoding(): this {\n this.encoding = ENCODING.utf8;\n return this;\n }\n\n ucs2Encoding(): this {\n this.encoding = ENCODING.ucs2;\n return this;\n }\n\n utf16leEncoding(): this {\n this.encoding = ENCODING.utf16le;\n return this;\n }\n\n latin1Encoding(): this {\n this.encoding = ENCODING.latin1;\n return this;\n }\n\n asciiEncoding(): this {\n this.encoding = ENCODING.ascii;\n return this;\n }\n\n base64Encoding(): this {\n this.encoding = ENCODING.base64;\n return this;\n }\n\n hexEncoding(): this {\n this.encoding = ENCODING.hex;\n return this;\n }\n\n generateJsonFileFromCsv(\n fileInputName: PathOrFileDescriptor,\n fileOutputName: string\n ): void {\n const jsonStringified = this.getJsonFromCsvStringified(fileInputName);\n writeFile(jsonStringified, fileOutputName);\n }\n\n getJsonFromCsvStringified(fileInputName: PathOrFileDescriptor): string {\n const json = this.getJsonFromCsv(fileInputName);\n const jsonStringified = JSON.stringify(json, undefined, 1);\n\n validateJson(jsonStringified);\n\n return jsonStringified;\n }\n\n getJsonFromCsv(fileInputName: PathOrFileDescriptor): CsvJsonRow[] {\n const parsedCsv = readFile(fileInputName, this.encoding);\n return this.csvToJson(parsedCsv);\n }\n\n csvStringToJson(csvString: string): CsvJsonRow[] {\n return this.csvToJson(csvString);\n }\n\n csvToJson(parsedCsv: string): CsvJsonRow[] {\n this.validateInputConfig();\n const newLine = /\\r?\\n/;\n const defaultFieldDelimiter = ',';\n let lines = parsedCsv.split(newLine);\n const fieldDelimiter = this.delimiter || defaultFieldDelimiter;\n let index = this._indexHeader ?? 0;\n let headers: string[] = [];\n\n lines = lines.filter((line) => line !== undefined && line.trim() !== '');\n\n if (this.isSupportQuotedField) {\n headers = this.split(lines[index]);\n } else {\n headers = lines[index].split(fieldDelimiter);\n }\n\n while (headers.length === 0 && index <= lines.length) {\n index = index + 1;\n headers = lines[index].split(fieldDelimiter);\n }\n\n const jsonResult: CsvJsonRow[] = [];\n for (let i = index + 1; i < lines.length; i++) {\n let currentLine: string[] = [];\n if (this.isSupportQuotedField) {\n currentLine = this.split(lines[i]);\n } else {\n currentLine = lines[i].split(fieldDelimiter);\n }\n if (currentLine.length > 0) {\n jsonResult.push(this.buildJsonResult(headers, currentLine));\n }\n }\n return jsonResult;\n }\n\n buildJsonResult(headers: string[], currentLine: string[]): CsvJsonRow {\n const jsonObject: CsvJsonRow = {};\n for (let j = 0; j < headers.length; j++) {\n const propertyName = this.isTrimHeaderFieldWhiteSpace\n ? headers[j].replace(/\\s/g, '')\n : headers[j].trim();\n let value: string | number | boolean | (string | number | boolean)[] =\n currentLine[j];\n if (\n this.parseSubArrayDelimiter &&\n value &&\n typeof value === 'string' &&\n value.indexOf(this.parseSubArrayDelimiter) === 0 &&\n value.lastIndexOf(this.parseSubArrayDelimiter) === value.length - 1\n ) {\n value = value\n .substring(\n value.indexOf(this.parseSubArrayDelimiter) + 1,\n value.lastIndexOf(this.parseSubArrayDelimiter)\n )\n .trim()\n .split(this.parseSubArraySeparator!);\n }\n if (this.printValueFormatByType && !Array.isArray(value)) {\n value = getValueFormatByType(value);\n }\n jsonObject[propertyName] = value;\n }\n return jsonObject;\n }\n\n hasQuotes(line: string): boolean {\n return line.includes('\"');\n }\n\n split(line: string): string[] {\n if (line.length == 0) {\n return [];\n }\n const delim = this.delimiter || ',';\n const subSplits: string[] = [''];\n if (this.hasQuotes(line)) {\n const chars = line.split('');\n let subIndex = 0;\n let startQuote = false;\n let isDouble = false;\n chars.forEach((c, i, arr) => {\n if (isDouble) {\n subSplits[subIndex] += c;\n isDouble = false;\n return;\n }\n if (c != '\"' && c != delim) {\n subSplits[subIndex] += c;\n } else if (c == delim && startQuote) {\n subSplits[subIndex] += c;\n } else if (c == delim) {\n subIndex++;\n subSplits[subIndex] = '';\n return;\n } else {\n if (arr[i + 1] === '\"') {\n isDouble = true;\n } else {\n if (!startQuote) {\n startQuote = true;\n } else {\n startQuote = false;\n }\n }\n }\n });\n if (startQuote) {\n throw new Error('Row contains mismatched quotes!');\n }\n return subSplits;\n } else {\n return line.split(delim);\n }\n }\n\n validateInputConfig() {\n if (this.isSupportQuotedField) {\n if (this.delimiter === '\"') {\n throw new Error(\n 'When SupportQuotedFields is enabled you cannot defined the field delimiter as quote -> [\"]'\n );\n }\n if (this.parseSubArraySeparator === '\"') {\n throw new Error(\n 'When SupportQuotedFields is enabled you cannot defined the field parseSubArraySeparator as quote -> [\"]'\n );\n }\n if (this.parseSubArrayDelimiter === '\"') {\n throw new Error(\n 'When SupportQuotedFields is enabled you cannot defined the field parseSubArrayDelimiter as quote -> [\"]'\n );\n }\n }\n }\n\n /**\n * @deprecated Use generateJsonFileFromCsv()\n */\n jsonToCsv(inputFileName: PathOrFileDescriptor, outputFileName: string): void {\n this.generateJsonFileFromCsv(inputFileName, outputFileName);\n }\n}\n\nexport default new ConvertCsvToJson();\n","import {\n readFileSync,\n writeFile as fsWriteFile,\n PathOrFileDescriptor,\n} from 'fs';\nimport { ENCODING } from '../common/constants';\n\nexport function readFile(\n fileInputName: PathOrFileDescriptor,\n encoding: ENCODING = ENCODING.utf8\n): string {\n return readFileSync(fileInputName, encoding).toString();\n}\n\nexport function writeFile(jsonString: string, fileOutputName: string): void {\n fsWriteFile(fileOutputName, jsonString, function (err) {\n if (err) {\n throw err;\n } else {\n console.log('File saved: ' + fileOutputName);\n }\n });\n}\n\nexport default {\n readFile,\n writeFile,\n};\n","export function validateJson(jsonString: string) {\n try {\n JSON.parse(jsonString);\n } catch (err) {\n throw Error('Parsed csv has generated an invalid json!!!\\n' + err);\n }\n}\n\nexport default {\n validateJson,\n};\n","export function trimPropertyName(\n isTrimHeaderFieldWhiteSpace: boolean,\n value: string\n): string {\n if (isTrimHeaderFieldWhiteSpace) {\n return value.replace(/\\s/g, '');\n }\n return value.trim();\n}\n\nexport function getValueFormatByType(\n value: string | undefined\n): string | number | boolean {\n let retVal: string | number | boolean | undefined = value;\n if (value === undefined || value === '') {\n retVal = '';\n } else if (\n !isNaN(Number(value)) &&\n typeof value === 'string' &&\n value.trim() !== ''\n ) {\n retVal = Number(value);\n } else if (value === 'true' || value === 'false') {\n retVal = value === 'true';\n }\n return retVal!;\n}\n\nexport default {\n trimPropertyName,\n getValueFormatByType,\n};\n"],"mappings":"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","names":["fsWriteFile"]}