{"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"]}