1// Copyright 2022 Google LLC
2
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6
7//     http://www.apache.org/licenses/LICENSE-2.0
8
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.import { exec } from 'child_process';
14
15import { exec } from 'child_process';
16import { parse } from 'csv-parse';
17import { promises as fs } from 'fs';
18import jsdom from 'jsdom';
19
20const DOMParser = new jsdom.JSDOM('').window.DOMParser as typeof window.DOMParser;
21
22type TFileList = string[];
23
24export type TCSVRecord = Array<string | boolean | number>;
25
26class _FileIO {
27    public parser = new DOMParser();
28    public saved: string[] = [];
29
30    public loadXML = async (path: string): Promise<XMLDocument> => {
31        try {
32            const src = await this.loadFileAsText(path);
33            return this.parser.parseFromString(src, 'text/xml') as XMLDocument;
34        } catch (error) {
35            console.log(`Failed to parse XML file '${path}'.`, error);
36            process.exit();
37        }
38    };
39
40    public loadFileAsText = async (path: string): Promise<string> => {
41        try {
42            return await fs.readFile(path, { encoding: 'utf8' });
43        } catch (error) {
44            console.log(`Failed to read file '${path}'.`, error);
45            process.exit();
46        }
47    };
48
49    public saveFile = async (data: string, path: string) => {
50        try {
51            await fs.writeFile(path, data, { encoding: 'utf8' });
52            this.saved.push(path);
53        } catch (error) {
54            console.log(error);
55            console.log(`Failed to write file '${path}'.`);
56            process.exit();
57        }
58    };
59
60    public loadFileList = async (path: string): Promise<TFileList> => {
61        const src = await this.loadFileAsText(path);
62
63        try {
64            return JSON.parse(src) as TFileList;
65        } catch (error) {
66            console.log(error);
67            console.log(`Failed to parse JSON file '${path}'.`);
68            process.exit();
69        }
70    };
71
72    public loadCSV = (path: string): Promise<Array<TCSVRecord>> => {
73        return new Promise((resolve, reject) => {
74            this.loadFileAsText(path).then((src) => {
75                parse(
76                    src,
77                    {
78                        delimiter: '	',
79                    },
80                    (err, records) => {
81                        if (err) {
82                            reject(err);
83                            return;
84                        }
85
86                        resolve(records);
87                    }
88                );
89            });
90        });
91    };
92
93    formatSaved = () => {
94        const cmd = `idea format ${this.saved.join(' ')}`;
95
96        exec(cmd, (error, out, stderr) => {
97            if (error) {
98                console.log(error.message);
99                return;
100            }
101
102            if (stderr) {
103                console.log(stderr);
104                return;
105            }
106
107            console.log(out);
108        });
109    };
110}
111
112export const FileIO = new _FileIO();
113