diff --git a/web/package.json b/web/package.json index e7d059c0e..9ca65ebb7 100644 --- a/web/package.json +++ b/web/package.json @@ -122,6 +122,7 @@ "moment-timezone": "^0.5.34", "notificar": "^1.0.1", "notistack": "^3.0.1", + "papaparse": "^5.5.2", "path-fx": "^2.0.0", "postcss": "^8.4.31", "rc-dock": "^3.2.9", diff --git a/web/pgadmin/static/js/utils.js b/web/pgadmin/static/js/utils.js index 3fd6d91de..139ac963c 100644 --- a/web/pgadmin/static/js/utils.js +++ b/web/pgadmin/static/js/utils.js @@ -11,6 +11,7 @@ import _ from 'lodash'; import gettext from 'sources/gettext'; import { hasTrojanSource } from 'anti-trojan-source'; import convert from 'convert-units'; +import Papa from 'papaparse'; import getApiInstance from './api_instance'; import usePreferences from '../../preferences/static/js/store'; import pgAdmin from 'sources/pgadmin'; @@ -261,74 +262,17 @@ export function sprintf(i_str) { } } -// Modified ref: http://stackoverflow.com/a/1293163/2343 to suite pgAdmin. // This will parse a delimited string into an array of arrays. export function CSVToArray(strData, strDelimiter, quoteChar){ - strDelimiter = strDelimiter || ','; - quoteChar = quoteChar || '"'; - // Create a regular expression to parse the CSV values. - let objPattern = new RegExp( - ( - // Delimiters. - '(\\' + strDelimiter + '|\\r?\\n|\\r|^)' + - // Quoted fields. - (quoteChar == '"' ? '(?:"([^"]*(?:""[^"]*)*)"|' : '(?:\'([^\']*(?:\'\'[^\']*)*)\'|') + - // Standard fields. - (quoteChar == '"' ? '([^"\\' + strDelimiter + '\\r\\n]*))': '([^\'\\' + strDelimiter + '\\r\\n]*))') - ), - 'gi' - ); + // Use papaparse to parse the CSV data + const parsedResult = Papa.parse(strData, { + delimiter: strDelimiter, + quoteChar: quoteChar, + }); - // Create an array to hold our data. Give the array - // a default empty first row. - let arrData = [[]]; - - // The regex doesn't handle and skips start value if - // string starts with delimiter - if(strData.startsWith(strDelimiter)) { - arrData[ arrData.length - 1 ].push(null); - } - - // Create an array to hold our individual pattern - // matching groups. - let arrMatches = null; - - // Keep looping over the regular expression matches - // until we can no longer find a match. - while ((arrMatches = objPattern.exec( strData ))){ - // Get the delimiter that was found. - let strMatchedDelimiter = arrMatches[ 1 ]; - - // Check to see if the given delimiter has a length - // (is not the start of string) and if it matches - // field delimiter. If id does not, then we know - // that this delimiter is a row delimiter. - if (strMatchedDelimiter.length && strMatchedDelimiter !== strDelimiter){ - // Since we have reached a new row of data, - // add an empty row to our data array. - arrData.push( [] ); - } - - let strMatchedValue; - - // Now that we have our delimiter out of the way, - // let's check to see which kind of value we - // captured (quoted or unquoted). - if (arrMatches[ 2 ]){ - // We found a quoted value. When we capture - // this value, unescape any quotes. - strMatchedValue = arrMatches[ 2 ].replace(new RegExp( quoteChar+quoteChar, 'g' ), quoteChar); - } else { - // We found a non-quoted value. - strMatchedValue = arrMatches[ 3 ]; - } - // Now that we have our value string, let's add - // it to the data array. - arrData[ arrData.length - 1 ].push( strMatchedValue ); - } // Return the parsed data. - return arrData; + return parsedResult.data; } export function hasBinariesConfiguration(pgBrowser, serverInformation) { diff --git a/web/yarn.lock b/web/yarn.lock index 988a04823..ad181804f 100644 --- a/web/yarn.lock +++ b/web/yarn.lock @@ -11663,6 +11663,13 @@ __metadata: languageName: node linkType: hard +"papaparse@npm:^5.5.2": + version: 5.5.2 + resolution: "papaparse@npm:5.5.2" + checksum: 59d5c6aca4fe1621cc12f66c024d0ea651bb4aad77d50c2d66a3e3c1ba60e992e2f52762f783fc2531348120c302ab272d8e448d853652232c9c742cdb666fb8 + languageName: node + linkType: hard + "parent-module@npm:^1.0.0": version: 1.0.1 resolution: "parent-module@npm:1.0.1" @@ -13671,6 +13678,7 @@ __metadata: moment-timezone: ^0.5.34 notificar: ^1.0.1 notistack: ^3.0.1 + papaparse: ^5.5.2 path-fx: ^2.0.0 postcss: ^8.4.31 postcss-loader: ^8.1.1