|
| 1 | +import type { ParseError } from "jsonc-parser"; |
1 | 2 | import { FileFormat } from "../../enums/file.enum"; |
2 | 3 |
|
3 | | -const keyExists = (obj: object, key: string) => { |
4 | | - if (!obj || (typeof obj !== "object" && !Array.isArray(obj))) { |
5 | | - return false; |
6 | | - } else if (obj.hasOwnProperty(key)) { |
7 | | - return obj[key]; |
8 | | - } else if (Array.isArray(obj)) { |
9 | | - for (let i = 0; i < obj.length; i++) { |
10 | | - const result = keyExists(obj[i], key); |
| 4 | +export const contentToJson = (value: string, format = FileFormat.JSON): Promise<object> => { |
| 5 | + return new Promise(async (resolve, reject) => { |
| 6 | + try { |
| 7 | + if (!value) return resolve({}); |
11 | 8 |
|
12 | | - if (result) { |
13 | | - return result; |
| 9 | + if (format === FileFormat.JSON) { |
| 10 | + const { parse } = await import("jsonc-parser"); |
| 11 | + const errors: ParseError[] = []; |
| 12 | + const result = parse(value, errors); |
| 13 | + if (errors.length > 0) JSON.parse(value); |
| 14 | + return resolve(result); |
14 | 15 | } |
15 | | - } |
16 | | - } else { |
17 | | - for (const k in obj) { |
18 | | - const result = keyExists(obj[k], key); |
19 | 16 |
|
20 | | - if (result) { |
21 | | - return result; |
| 17 | + if (format === FileFormat.YAML) { |
| 18 | + const { load } = await import("js-yaml"); |
| 19 | + return resolve(load(value) as object); |
22 | 20 | } |
23 | | - } |
24 | | - } |
25 | 21 |
|
26 | | - return false; |
27 | | -}; |
| 22 | + if (format === FileFormat.XML) { |
| 23 | + const { XMLParser } = await import("fast-xml-parser"); |
| 24 | + const parser = new XMLParser({ |
| 25 | + attributeNamePrefix: "$", |
| 26 | + ignoreAttributes: false, |
| 27 | + allowBooleanAttributes: true, |
| 28 | + parseAttributeValue: true, |
| 29 | + trimValues: true, |
| 30 | + parseTagValue: true, |
| 31 | + }); |
| 32 | + return resolve(parser.parse(value)); |
| 33 | + } |
28 | 34 |
|
29 | | -const contentToJson = async (value: string, format = FileFormat.JSON): Promise<object> => { |
30 | | - try { |
31 | | - const { load } = await import("js-yaml"); |
32 | | - const { csv2json } = await import("json-2-csv"); |
33 | | - const { parse } = await import("jsonc-parser"); |
34 | | - const jxon = await import("jxon"); |
35 | | - const toml = await import("toml"); |
| 35 | + if (format === FileFormat.CSV) { |
| 36 | + const { csv2json } = await import("json-2-csv"); |
| 37 | + const result = csv2json(value, { |
| 38 | + trimFieldValues: true, |
| 39 | + trimHeaderFields: true, |
| 40 | + wrapBooleans: true, |
| 41 | + excelBOM: true, |
| 42 | + }); |
| 43 | + return resolve(result); |
| 44 | + } |
36 | 45 |
|
37 | | - let json: object = {}; |
| 46 | + return resolve({}); |
| 47 | + } catch (error) { |
| 48 | + const errorMessage = error instanceof Error ? error.message : "Failed to parse content"; |
| 49 | + return reject(errorMessage); |
| 50 | + } |
| 51 | + }); |
| 52 | +}; |
38 | 53 |
|
39 | | - if (format === FileFormat.JSON) json = parse(value); |
40 | | - if (format === FileFormat.YAML) json = load(value) as object; |
41 | | - if (format === FileFormat.XML) json = jxon.stringToJs(value); |
42 | | - if (format === FileFormat.TOML) json = toml.parse(value); |
43 | | - if (format === FileFormat.CSV) json = await csv2json(value); |
44 | | - if (format === FileFormat.XML && keyExists(json, "parsererror")) throw Error("Unknown error!"); |
| 54 | +export const jsonToContent = async (json: string, format: FileFormat): Promise<string> => { |
| 55 | + return new Promise(async resolve => { |
| 56 | + try { |
| 57 | + if (!json) return resolve(""); |
45 | 58 |
|
46 | | - if (!json) throw Error("Invalid JSON!"); |
| 59 | + if (format === FileFormat.JSON) { |
| 60 | + const parsedJson = JSON.parse(json); |
| 61 | + return resolve(JSON.stringify(parsedJson, null, 2)); |
| 62 | + } |
47 | 63 |
|
48 | | - return Promise.resolve(json); |
49 | | - } catch (error: any) { |
50 | | - throw error; |
51 | | - } |
52 | | -}; |
| 64 | + if (format === FileFormat.YAML) { |
| 65 | + const { dump } = await import("js-yaml"); |
| 66 | + const { parse } = await import("jsonc-parser"); |
| 67 | + return resolve(dump(parse(json))); |
| 68 | + } |
53 | 69 |
|
54 | | -const jsonToContent = async (json: string, format: FileFormat): Promise<string> => { |
55 | | - try { |
56 | | - const { dump } = await import("js-yaml"); |
57 | | - const { json2csv } = await import("json-2-csv"); |
58 | | - const { parse } = await import("jsonc-parser"); |
| 70 | + if (format === FileFormat.XML) { |
| 71 | + const { XMLBuilder } = await import("fast-xml-parser"); |
| 72 | + const builder = new XMLBuilder({ |
| 73 | + format: true, |
| 74 | + attributeNamePrefix: "$", |
| 75 | + ignoreAttributes: false, |
| 76 | + }); |
59 | 77 |
|
60 | | - let contents = json; |
| 78 | + return resolve(builder.build(JSON.parse(json))); |
| 79 | + } |
61 | 80 |
|
62 | | - if (!json) return json; |
63 | | - if (format === FileFormat.JSON) contents = json; |
64 | | - if (format === FileFormat.YAML) contents = dump(parse(json)); |
65 | | - if (format === FileFormat.XML) contents = dump(parse(json)); |
66 | | - if (format === FileFormat.TOML) contents = dump(parse(json)); |
67 | | - if (format === FileFormat.CSV) contents = await json2csv(parse(json)); |
| 81 | + if (format === FileFormat.CSV) { |
| 82 | + const { json2csv } = await import("json-2-csv"); |
| 83 | + const parsedJson = JSON.parse(json); |
68 | 84 |
|
69 | | - return Promise.resolve(contents); |
70 | | - } catch (error: any) { |
71 | | - throw error; |
72 | | - } |
73 | | -}; |
| 85 | + const data = Array.isArray(parsedJson) ? parsedJson : [parsedJson]; |
| 86 | + return resolve( |
| 87 | + json2csv(data, { |
| 88 | + expandArrayObjects: true, |
| 89 | + expandNestedObjects: true, |
| 90 | + excelBOM: true, |
| 91 | + wrapBooleans: true, |
| 92 | + trimFieldValues: true, |
| 93 | + trimHeaderFields: true, |
| 94 | + }) |
| 95 | + ); |
| 96 | + } |
74 | 97 |
|
75 | | -export { contentToJson, jsonToContent }; |
| 98 | + return resolve(json); |
| 99 | + } catch (error) { |
| 100 | + console.error(json, error); |
| 101 | + return resolve(json); |
| 102 | + } |
| 103 | + }); |
| 104 | +}; |
0 commit comments