const Papa = require("papaparse"); const errors = require("./errors.js"); import { ParseResults, Parsers, RemoteSource } from "./freeDatas2HTMLInterfaces"; interface papaParseOptions { delimiter: string; newline: string; quoteChar: string; escapeChar: string; transformHeader?(field: string, index: number): string; preview: number; comments: false|string, fastMode: boolean|undefined; transform?(value: string): string; } export class ParserForCSV implements Parsers { private _datasRemoteSource: RemoteSource|undefined=undefined; private _datas2Parse:string|undefined=undefined; private _parseResults:ParseResults|undefined=undefined; // Ouverture de certaines options de Papa Parse : // cf. https://www.papaparse.com/docs#config public options: papaParseOptions = { delimiter: "", newline: "", quoteChar: '"', escapeChar: '"', transformHeader: function(field: string, index: number): string { return field.trim() }, preview: 0, comments: "", fastMode: undefined, transform: undefined } set datasRemoteSource(source: RemoteSource) { if(source.url.trim().length === 0) throw new Error(errors.parserNeedUrl); else { source.url=source.url.trim(); this._datasRemoteSource=source; } } set datas2Parse(datas: string) { if(datas.trim().length === 0) throw new Error(errors.parserNeedDatas); else this._datas2Parse=datas.trim(); } get parseResults() : ParseResults|undefined { return this._parseResults; } // async dans le cas d'une source distante // Et création d'une Promise car PapaParse utilise une fonction callback. public async parse(): Promise { const parser=this, options=this.options; return new Promise((resolve,reject) => { let parseContent="", parseDownload=false, parseDownloadRequestHeaders: any=undefined, parseWithCredentials: any=undefined; if(parser._datasRemoteSource !== undefined) { parseContent=parser._datasRemoteSource.url; parseDownload=true; parseWithCredentials=parser._datasRemoteSource.withCredentials; // undefined ok pour PapaParse if(parser._datasRemoteSource.headers !== undefined) { parseDownloadRequestHeaders={}; for (let i in parser._datasRemoteSource.headers) parseDownloadRequestHeaders[parser._datasRemoteSource.headers[Number(i)].key]=parser._datasRemoteSource.headers[Number(i)].value; } } else if(parser._datas2Parse !== undefined) parseContent=parser._datas2Parse; else reject(new Error(errors.parserNeedSource)); Papa.parse(parseContent, { delimiter: options.delimiter, newline: options.newline, quoteChar: options.quoteChar, escapeChar: options.escapeChar, header: true, // nécessaire pour obtenir le nom des champs transformHeader: options.transformHeader, preview: options.preview, comments: options.comments, complete: function(results :any) { // Attention, Papa Parse peut accepter un nom de champ vide let realFields: string[]=[]; for(let i in results.meta.fields) { if(results.meta.fields[i].trim() !== "") realFields.push(results.meta.fields[i]); } if(realFields.length === 0) reject(new Error(errors.parserFail)); else { parser._parseResults={ datas: results.data, errors: results.errors, fields: realFields, }; resolve(true); } }, download: parseDownload, downloadRequestHeaders: parseDownloadRequestHeaders, skipEmptyLines:"greedy", fastMode: options.fastMode, withCredentials: parseWithCredentials, transform: options.transform, }); }); } }