{"version":3,"file":"ngx-data-to-csv.mjs","sources":["../../../projects/ngx-data-to-csv/src/lib/model.ts","../../../projects/ngx-data-to-csv/src/lib/ngx-data-to-csv.service.ts","../../../projects/ngx-data-to-csv/src/public-api.ts","../../../projects/ngx-data-to-csv/src/ngx-data-to-csv.ts"],"sourcesContent":["export interface Config {\r\n    filename?: string;\r\n    fieldSeparator?: string;\r\n    showTitle?: boolean;\r\n    title?: string;\r\n    useByteOrderMark?: boolean;\r\n    noDownload?: boolean;\r\n}\r\n\r\nexport class CsvConfigConsts {\r\n\r\n    public static END_OF_LINE = \"\\r\\n\";\r\n    public static ByteOrderMark = \"\\ufeff\";\r\n    public static DEFAULT_FIELD_SEPARATOR = ',';\r\n    public static DEFAULT_SHOW_TITLE = false;\r\n    public static DEFAULT_TITLE = 'CSV';\r\n    public static DEFAULT_FILENAME = 'csv.csv';\r\n    public static DEFAULT_USE_BOM = true;\r\n    public static DEFAULT_NO_DOWNLOAD = false;\r\n}\r\n\r\nexport const ConfigDefaults: Config = {\r\n    filename: CsvConfigConsts.DEFAULT_FILENAME,\r\n    fieldSeparator: CsvConfigConsts.DEFAULT_FIELD_SEPARATOR,\r\n    showTitle: CsvConfigConsts.DEFAULT_SHOW_TITLE,\r\n    title: CsvConfigConsts.DEFAULT_TITLE,\r\n    useByteOrderMark: CsvConfigConsts.DEFAULT_USE_BOM,\r\n    noDownload: CsvConfigConsts.DEFAULT_NO_DOWNLOAD,\r\n};","import { Injectable } from '@angular/core';\r\nimport { Config, ConfigDefaults, CsvConfigConsts } from './model';\r\n\r\ntype GenericObject = {\r\n  [key: string]: bigint | boolean | null | number | string;\r\n};\r\ninterface DataObject {\r\n  [key: string]: string | number | boolean | null;\r\n}\r\n/**\r\n * \r\n * # Ngx Data To CSV\r\n * \r\n * usage:\r\n * \r\n * ```ts\r\n *  private service: NgxDataToCsvService = inject(NgxDataToCsvService);\r\n *  // or using constructor\r\n *  constructor(private service: NgxDataToCsvService) {}\r\n * \r\n *  onClick(data: MyDataType[]): void {\r\n *    this.service.toCsv(data, 'filename');\r\n *  }\r\n * ```\r\n * ## Description\r\n *\r\n * The NgxDataToCsvService class provides a service to transform data into CSV format.\r\n * \r\n * It provides methods to convert data (in the form of an object or a JSON string) into CSV format,\r\n * extract values from nested objects, extract unique keys from an array of objects,\r\n * parse a JSON string into an object, format cell values for inclusion in a CSV file, \r\n * and to initiate the download of a CSV file.\r\n *\r\n * The class maintains a private property `data` to hold the data to be transformed,\r\n * a private property `options` to hold the configuration for the CSV output,\r\n * and a private property `csv` to hold the resulting CSV string.\r\n *\r\n * The main method `toCsv` is public and can be used to transform data into CSV format.\r\n * It takes the data to be transformed, the desired filename for the CSV file, \r\n * and an optional configuration object as arguments. The configuration object allows for customizing\r\n * the CSV output, such as setting the field separator, showing a title, prepending a byte order mark, \r\n * and deciding whether to download the CSV file or return it as a string. The `toCsv` method also\r\n * orchestrates the extraction of unique keys, the formatting of cell values, and the downloading of the CSV file.\r\n *\r\n * The other methods are private helper methods used by the `toCsv` method.\r\n */\r\n@Injectable({\r\n  providedIn: 'root'\r\n})\r\nexport class NgxDataToCsvService {\r\n\r\n  private data: GenericObject[] | undefined | null;\r\n  private options!: Config;\r\n  private csv = '';\r\n\r\n  /**\r\n   * This method transforms the provided data into a CSV format.\r\n   *\r\n   * @param {any} dataToTransform - The data to be transformed. This can be either a JavaScript object or a JSON string.\r\n   * @param {string} filename - The desired name for the resulting CSV file.\r\n   * @param {Config} config - An optional configuration object for customizing the CSV output.\r\n   *\r\n   * The configuration object can contain the following keys:\r\n   * - filename: the name of the CSV file.\r\n   * - fieldSeparator: the character used to separate fields in the CSV.\r\n   * - showTitle: a boolean that determines whether to display a title in the CSV.\r\n   * - title: the title to display in the CSV.\r\n   * - useByteOrderMark: a boolean that determines whether to prepend a byte order mark to the CSV.\r\n   * - noDownload: a boolean that determines whether to download the CSV or return it as a string.\r\n   *\r\n   * @returns {string | void} - If noDownload is set to true in the config, returns the CSV as a string. Otherwise, triggers a download of the CSV file and returns void.\r\n   */\r\n  public toCsv(dataToTransform: DataObject[], filename: string, config?: Config): string | void {\r\n    this.csv = '';\r\n\r\n    this.data = typeof dataToTransform != 'object' ? this.parseJson(dataToTransform) : dataToTransform;\r\n    if (!this.data) {\r\n      return;\r\n    }\r\n    this.options = { ...ConfigDefaults, ...config };\r\n\r\n    if (filename) {\r\n      this.options.filename = filename;\r\n    }\r\n\r\n    this.addByteOrderMarkAndTitle();\r\n\r\n    const keys = this.extractUniqueKeys(this.data);\r\n\r\n    // Add CSV header directly to the CSV string\r\n    this.generateCsvHeader(keys);\r\n\r\n    // Process each row individually and add it to the CSV string\r\n    for (const obj of this.data) {\r\n      this.generateCsvRow(obj, keys);\r\n    }\r\n\r\n    if (this.csv == '') {\r\n      throw new Error(\"Invalid data\");\r\n    }\r\n\r\n    if (this.options?.noDownload) {\r\n      return this.csv;\r\n    }\r\n\r\n    this.downloadCsvFile();\r\n  }\r\n\r\n  /**\r\n   * This method retrieves the value of a nested object property.\r\n   *\r\n   * @param {GenericObject} obj - The object from which to retrieve the value.\r\n   * @param {string} key - The key used to locate the value. It supports a nested key in the form 'key1.key2.key3' or 'key1[index].key2'.\r\n   *                        For example, for an object like `{ key1: { key2: { key3: 'value' }}}`, the method can be called with the key 'key1.key2.key3'.\r\n   *                        Similarly, for an object like `{ key1: [{ key2: 'value' }] }`, the method can be called with the key 'key1[0].key2'.\r\n   * @returns {any} - Returns the value of the specified key in the object. If the key is not found, it returns `undefined`.\r\n   */\r\n  private getNestedObjectValue(obj: GenericObject, key: string): any {\r\n    const keys = key.split('.');\r\n    let current: any = obj;\r\n\r\n    for (const key of keys) {\r\n      const match = key.match(/(\\w+)\\[(\\d+)\\]/);\r\n      if (match) {\r\n        current = current[match[1]][match[2]];\r\n      } else {\r\n        current = current[key];\r\n      }\r\n    }\r\n\r\n    return current;\r\n  }\r\n\r\n  /**\r\n   * This method extracts the unique keys from an array of objects.\r\n   * It is designed to handle nested objects and arrays as well.\r\n   *\r\n   * @param {GenericObject[]} arr - The array of objects from which to extract the keys.\r\n   * @param {string} keyPrefix - An optional prefix to prepend to each key. Defaults to an empty string.\r\n   *\r\n   * The function operates recursively to handle nested structures. If a key points to an array,\r\n   * it recursively extracts keys from each item in the array. If a key points to an object, it recursively\r\n   * extracts keys from the object. In the base case, when a key points to a primitive value, it adds the key \r\n   * (with the current prefix) to the set of unique keys.\r\n   *\r\n   * @returns {string[]} - Returns an array of unique keys from the input array of objects.\r\n   */\r\n  private extractUniqueKeys(arr: GenericObject[], keyPrefix = ''): string[] {\r\n    const keys = new Set<string>();\r\n\r\n    function extract(obj: GenericObject, currentKeyPrefix: string): void {\r\n      for (const key in obj) {\r\n        if (Array.isArray(obj[key])) {\r\n          (obj[key] as any).forEach((item: GenericObject, index: number) => {\r\n            extract(item, `${currentKeyPrefix}${key}[${index}].`);\r\n          });\r\n        } else if (typeof obj[key] === 'object' && obj[key] !== null) {\r\n          extract(obj[key] as any, `${currentKeyPrefix}${key}.`);\r\n        } else {\r\n          keys.add(`${currentKeyPrefix}${key}`);\r\n        }\r\n      }\r\n    }\r\n\r\n    arr.forEach((item: GenericObject) => extract(item, keyPrefix));\r\n\r\n    return Array.from(keys);\r\n  }\r\n\r\n  /**\r\n   * This method attempts to parse a JSON string into an object.\r\n   *\r\n   * @param {string} jsonString - The JSON string to parse.\r\n   *\r\n   * The method uses the JSON.parse function to attempt to parse the input string.\r\n   * If the parsing is successful and the result is an object, it returns the parsed object.\r\n   * If the parsing fails or the result is not an object, it logs an error and returns null.\r\n   *\r\n   * @returns {GenericObject[] | null} - Returns the parsed object if the parsing is successful; otherwise, returns null.\r\n   */\r\n  private parseJson(jsonString: string): GenericObject[] | null {\r\n    try {\r\n      const parsedData = JSON.parse(jsonString);\r\n      if (typeof parsedData === 'object' && parsedData !== null) {\r\n        return parsedData;\r\n      }\r\n      throw new Error('Parsed data is not an object or is null');\r\n    } catch (error: any) {\r\n      throw new Error(`Invalid JSON: ${error.message}`);\r\n    }\r\n  }\r\n  /**\r\n   * This method formats a cell value for inclusion in a CSV.\r\n   *\r\n   * @param {GenericObject} obj - The object containing the cell value.\r\n   * @param {string} key - The key identifying the cell value within the object.\r\n   *\r\n   * The method retrieves the value from the object using the provided key.\r\n   * If the value is an object itself, it stringifies it using JSON.stringify.\r\n   * If the value contains any double-quote characters (\"), it replaces them with two double-quote characters (\"\") to escape them in the CSV.\r\n   * The method then wraps the value in double-quote characters and returns it.\r\n   *\r\n   * @returns {string} - Returns the cell value formatted for inclusion in a CSV.\r\n   */\r\n  private formatCellValue(obj: GenericObject, key: string): string {\r\n    let value = this.getNestedObjectValue(obj, key);\r\n    if (typeof value === 'object' && value !== null) {\r\n      value = JSON.stringify(value);\r\n    }\r\n\r\n    const strValue = String(value);\r\n    // Only do the replacement if necessary\r\n    const finalValue = strValue.includes('\"') ? strValue.replace(/\"/g, '\"\"') : strValue;\r\n\r\n    return `\"${finalValue}\"`;\r\n  }\r\n\r\n  /**\r\n   * This method initiates the download of the CSV file.\r\n   *\r\n   * It first creates a new Blob object from the CSV string stored in this.csv, setting the Blob's MIME type to \"text/csv;charset=utf8;\".\r\n   * It then creates a new 'a' element and sets its href attribute to a URL representing the Blob object.\r\n   * The 'a' element's target attribute is set to '_blank' to open the download in a new tab or window, and its visibility is set to 'hidden' to avoid displaying it.\r\n   * The 'a' element's download attribute is set to the filename specified in the options, with spaces replaced by underscores, and the extension \".csv\" appended.\r\n   * The 'a' element is then added to the document's body and its click method is called to start the download.\r\n   * Finally, the 'a' element is removed from the document's body after the download has started.\r\n   */\r\n  private downloadCsvFile(): void {\r\n    const blob = new Blob([this.csv], { type: \"text/csv;charset=utf8;\" });\r\n    const link = document.createElement(\"a\");\r\n\r\n    link.href = URL.createObjectURL(blob);\r\n    link.setAttribute('target', '_blank');\r\n    link.setAttribute('visibility', 'hidden');\r\n    link.download = this.options?.filename?.replace(/ /g, \"_\") + \".csv\";\r\n\r\n    document.body.appendChild(link);\r\n    link.click();\r\n    document.body.removeChild(link);\r\n  }\r\n\r\n  /**\r\n   * Adds the Byte Order Mark and title to the CSV string if specified in the options.\r\n   *\r\n   * The Byte Order Mark (BOM) is a Unicode character used to signal the endianness \r\n   * (byte order) of a text. It's optional and not all CSV parsers require or understand it.\r\n   *\r\n   * The title is a user-defined string that will be placed at the top of the CSV file,\r\n   * separated from the rest of the data by two newline characters.\r\n   */\r\n  private addByteOrderMarkAndTitle() {\r\n    if (this.options?.useByteOrderMark) {\r\n      this.csv += CsvConfigConsts.ByteOrderMark;\r\n    }\r\n\r\n    if (this.options?.showTitle) {\r\n      this.csv += this.options?.title + '\\r\\n\\n';\r\n    }\r\n  }\r\n\r\n\r\n  /**\r\n   * Generates the CSV header row and appends it to the CSV string.\r\n   * \r\n   * This method takes an array of keys, which represent the column headers in the CSV file,\r\n   * and joins them together into a single string with the field separator defined in the options.\r\n   * The field separator is typically a comma (,), but it could be any character.\r\n   * \r\n   * After joining the keys, an end of line marker is appended to complete the header row.\r\n   *\r\n   * @param keys An array of strings representing the column headers for the CSV file.\r\n   */\r\n  private generateCsvHeader(keys: string[]) {\r\n    this.csv += keys.join(this.options.fieldSeparator) + CsvConfigConsts.END_OF_LINE;\r\n  }\r\n\r\n  /**\r\n   * Generates a CSV row from a given object and appends it to the CSV string.\r\n   *\r\n   * This method takes an object and an array of keys. The keys represent the fields\r\n   * of the object that will be included in the CSV row. For each key, it retrieves \r\n   * the corresponding value from the object, formats it using the `formatCellValue` method,\r\n   * and then joins these formatted values into a single string with the field separator defined in the options.\r\n   *\r\n   * After joining the values, an end of line marker is appended to complete the row.\r\n   *\r\n   * @param obj The object to convert into a CSV row.\r\n   * @param keys An array of strings representing the fields of the object to include in the CSV row.\r\n   */\r\n  private generateCsvRow(obj: GenericObject, keys: string[]) {\r\n    const row = keys.map(key => this.formatCellValue(obj, key));\r\n    this.csv += row.join(this.options.fieldSeparator) + CsvConfigConsts.END_OF_LINE;\r\n  }\r\n\r\n}","/*\r\n * Public API Surface of ngx-data-to-csv\r\n */\r\n\r\nexport * from './lib/ngx-data-to-csv.service';\r\nexport * from './lib/model';","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}