diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2021-08-16 16:26:01 +0200 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2021-08-16 16:26:01 +0200 |
| commit | bf563861320cf207bb2d788f50b327e4eb37016a (patch) | |
| tree | 7e775216592e1f935fd9a10a6cf59f84c789f7c9 /file_utils.js | |
| parent | 9ae202820b698796f93b929b3e30cd499de796a1 (diff) | |
showing a graph
Diffstat (limited to 'file_utils.js')
| -rw-r--r-- | file_utils.js | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/file_utils.js b/file_utils.js new file mode 100644 index 0000000..16b12cd --- /dev/null +++ b/file_utils.js @@ -0,0 +1,152 @@ +/** + * File system utilities. + * @module app/utils/file_utils + */ + +import filesystem from "fs"; +import parseCSV from "csv-parse"; +import stringifyCSVCallback from "csv-stringify"; + +/** + * Helper function to load CSV from a file + * @param {string} inputFile path to the file + * @return {Promise} promise which will resolve with the parsed CSV + */ + +const csvReadOptions = { + columns: true, +}; + +export const loadCSV = (inputFile, options = {}) => + new Promise((resolve, reject) => { + if (!filesystem.existsSync(inputFile)) { + return reject("inputFile does not exist"); + } + const csvOptions = { + ...csvReadOptions, + ...options, + }; + filesystem.readFile(inputFile, "utf8", (error, text) => { + if (error) { + return reject(`Error reading file: ${error}`); + } + try { + parseCSV(text, csvOptions, function (err, data) { + if (err) { + return reject("Error parsing JSON"); + } + resolve(data); + }); + } catch { + reject("Error parsing JSON"); + } + }); + }); + +/** + * Helper function to stringify an array-of-arrays to a CSV (with Promise interface) + * @param {Array[]} rows array of arrays + * @return {Promise} promise which will resolve with the stringified CSV + */ + +export const stringifyCSV = (rows) => + new Promise((resolve, reject) => { + stringifyCSVCallback(rows, (error, output) => { + if (error) { + reject(error); + } else { + resolve(output); + } + }); + }); + +/** + * Helper function to attempt to mitigate malicious CSV data + * @param {Array[]} rows array of arrays + * @return {Array[]} the sanitized input + */ +export const sanitizeCSV = (rows) => + rows.map((row) => + row.map((cell) => (cell && typeof cell === "string" ? "'" + cell : cell)) + ); + +/** + * Helper function to load JSON from a file + * @param {string} inputFile path to the file + * @return {Promise} promise which will resolve with the parsed JSON + */ +export const loadJSON = (inputFile) => + new Promise((resolve, reject) => { + if (!filesystem.existsSync(inputFile)) { + return reject("inputFile does not exist"); + } + filesystem.readFile(inputFile, "utf8", (error, text) => { + if (error) { + return reject(`Error reading file: ${error}`); + } + try { + const data = JSON.parse(text); + resolve(data); + } catch { + reject("Error parsing JSON"); + } + }); + }); + +const writeFileOptions = { + replace: true, +}; + +/** + * Helper to write a string to a file + * @param {string} outputFile the file to write to + * @param {string|string[]} data the data to write + * @param {Object} options options, by default will overwrite the existing file + * @return {Promise} promise which will resolve when the file is saved + */ +export const writeFile = (outputFile, data, options = {}) => { + options = { ...writeFileOptions, ...options }; + return new Promise((resolve, reject) => { + if (filesystem.existsSync(outputFile) && !options.replace) { + return reject("outputFile exists"); + } + if (Array.isArray(data)) { + data = data.join("\n"); + } + filesystem.writeFile(outputFile, data, { encoding: "utf8" }, (error) => { + if (error) { + return reject(`Error writing file: ${error}`); + } + resolve(); + }); + }); +}; + +const writeJSONOptions = { + ...writeFileOptions, + indent: true, +}; + +/** + * Helper to write JSON data to a file + * @param {string} outputFile the file to write to + * @param {Object} data the data to write + * @param {Object} options options, by default will overwrite the existing file + * @return {Promise} promise which will resolve when the file is saved + */ +export const writeJSON = (outputFile, data, options = {}) => { + options = { ...writeJSONOptions, ...options }; + return new Promise((resolve, reject) => { + let json; + try { + if (options.indent) { + json = JSON.stringify(data, false, 2); + } else { + json = JSON.stringify(data); + } + } catch { + return reject("couldn't stringify JSON"); + } + return writeFile(outputFile, json, options); + }); +}; |
