nested_json_to_csv
Version:
98 lines (93 loc) • 3.15 kB
text/typescript
import { isBooleanObject, isNumberObject, isStringObject } from "util/types";
import { IParser, ParserOptions } from "../../interfaces/IParser";
import { Csv } from "../../models/Csv";
export class JsonParserService implements IParser {
#data: Map<any, any>;
#parserOptions: ParserOptions;
constructor(data: any | Map<any, object>, parserOptions?: ParserOptions) {
this.#parserOptions = parserOptions ?? { single: false, hasId: false };
if (this.#parserOptions.single && this.#parserOptions.hasId) {
throw new Error(
"Can't have the options single as true and hasId as true please go and check the documentation at https://www.npmjs.com/package/nested_json_to_csv"
);
}
if (data instanceof Map) this.#data = data;
else this.#data = this.#fromJsonToMap(data);
}
#fromJsonToMap(json: any): Map<any, any> {
let mp = new Map<any, any>();
for (const key in json) {
if (json[key].constructor == {}.constructor) {
const newMp = this.#fromJsonToMap(json[key]);
mp.set(key, newMp);
} else {
mp.set(key, json[key]);
}
}
return mp;
}
parse(headers: string[]): Csv {
const csv: Csv = new Csv(headers);
const body: string = this.#makeBody(csv.getHeaders());
if (headers[0] != "id" && this.#parserOptions.hasId) {
const newHeaders: string[] = csv.getHeaders();
newHeaders.unshift("id");
csv.setHeaders(newHeaders);
}
csv.setbody(body);
return csv;
}
get() {
return this.#data;
}
#makeBody(headers: string[]): string {
let body: string = "";
if (this.#parserOptions.single)
body = this.#getAllData(headers, this.#data);
else {
this.#data.forEach((value, key) => {
if (this.#parserOptions.hasId) {
body = body.concat(key, ",");
}
body = body.concat(this.#getAllData(headers, value), "\n");
});
}
return body;
}
#getAllData(headers: string[], data: Map<any, any>): string {
let body: string = "";
headers.forEach((path: string, index: number) => {
body = body.concat(this.#getData(path, data), ",");
});
return body;
}
#getData(path: string, data: Map<any, any>): string {
if (path.includes(".")) {
const key: string = path.substring(0, path.indexOf("."));
path = path.substring(path.indexOf(".") + 1);
let newData: Map<any, any>;
if (data.has(key)) newData = data.get(key);
else newData = new Map<any, any>();
return this.#getData(path, newData);
}
if (!data.has(path)) {
if (this.#parserOptions.setDefaultValues) {
return "";
}
console.error(path, data);
throw Error("Key was not found in your JSON");
}
const value: any = data.get(path);
if (value == undefined || typeof value == "object") {
throw Error("There is an error in your headers they are not accurate");
}
if (isNumberObject(value) || isBooleanObject(value)) {
return value + ",";
}
if (isStringObject(value)) {
const newValue = value.replace(",", ".");
return newValue;
}
return value;
}
}