const Papa=require("papaparse"); const errors= require("./errors.js"); import { RemoteSource } from "./freeDatas2HTMLRemoteSource"; import { ParseResults, Parsers, RemoteSources, RemoteSourceSettings } from "./freeDatas2HTMLInterfaces"; // Options de Papa Parse // cf. https://www.papaparse.com/docs#config interface PublicPapaParseOptions { 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; } interface PrivatePapaParseOptions { header: boolean; download: boolean; downloadRequestHeaders: undefined| { [index: string]:string }; skipEmptyLines: string; withCredentials: boolean|undefined; } export class ParserForCSV implements Parsers { private _datasRemoteSource: RemoteSources; private _datas2Parse:string=""; private _parseResults:ParseResults|undefined=undefined; public options: PublicPapaParseOptions = { delimiter:"", newline:"", quoteChar:'"', escapeChar:'"', transformHeader:function(field: string, index: number): string { return field.trim() }, preview:0, comments:"", fastMode:undefined, transform:undefined } private _privateOptions: PrivatePapaParseOptions = { header:true, download:false, downloadRequestHeaders:undefined, skipEmptyLines:"greedy", withCredentials:undefined } // L'instance d'une autre classe que RemoteSource peut être passée au constructeur constructor(datasRemoteSource?: RemoteSources) { if(datasRemoteSource !== undefined) this._datasRemoteSource=datasRemoteSource; else this._datasRemoteSource=new RemoteSource({ url:"" }); } public setRemoteSource(source: RemoteSourceSettings) { this._datasRemoteSource=new RemoteSource(source); } get datasRemoteSource() : RemoteSources { return this._datasRemoteSource; } set datas2Parse(datas: string) { if(datas.trim().length === 0) throw new Error(errors.parserNeedDatas); else this._datas2Parse=datas.trim(); } get datas2Parse() : string { return this._datas2Parse; } get parseResults() : ParseResults|undefined { return this._parseResults; } get privateOptions() : any { return this._privateOptions; } public async parse(): Promise { const parser=this, options=this.options; let parseContent=""; if(parser._datasRemoteSource.url !== "") { parseContent=parser._datasRemoteSource.url; this._privateOptions.download=true; this._privateOptions.withCredentials=parser._datasRemoteSource.withCredentials; if(parser._datasRemoteSource.headers !== undefined) { this._privateOptions.downloadRequestHeaders={}; for(let header of parser._datasRemoteSource.headers) this._privateOptions.downloadRequestHeaders[header.key]=header.value; } } else if(parser._datas2Parse !== "") parseContent=parser._datas2Parse; else throw new Error(errors.parserNeedSource); return new Promise((resolve,reject) => { Papa.parse(parseContent, { delimiter: options.delimiter, newline: options.newline, quoteChar: options.quoteChar, escapeChar: options.escapeChar, header: true, transformHeader: options.transformHeader, preview: options.preview, comments: options.comments, complete: function(results :any) { // Attention, Papa Parse peut accepter un nom de champ vide ou en doublon ! let realFields: string[]=[]; for(let field of results.meta.fields) { let checkField=field.trim(); if(checkField !== "" && realFields.indexOf(checkField) === -1) realFields.push(checkField); else console.error(errors.parserFieldNameFail); } if(realFields.length === 0) reject(new Error(errors.parserFieldsNotFound)); else { parser._parseResults= { datas: results.data, errors: results.errors, fields: realFields, }; resolve(true); } }, download: this._privateOptions.download, downloadRequestHeaders: this._privateOptions.downloadRequestHeaders, skipEmptyLines:"greedy", fastMode: options.fastMode, withCredentials: this._privateOptions.withCredentials, transform: options.transform }); }); } }