FreeDatas2HTML/src/freeDatas2HTMLParserForCSV.ts

129 lines
4.5 KiB
TypeScript

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<any>
{
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,
});
});
}
}