DockerERTFF/lib/modules/import.js

129 lines
3.3 KiB
JavaScript

const fs = require('fs-extra');
const { toSystemPath } = require('../core/path');
const { keysToLowerCase } = require('../core/util');
// simple inital implementation
// better implementation at:
// https://github.com/adaltas/node-csv-parse
// https://github.com/mafintosh/csv-parser
function parseCSV(csv, options) {
if (!csv) return [];
if (csv.charCodeAt(0) === 0xFEFF) {
csv = csv.slice(1);
}
let delimiter = options.delimiter.replace('\\t', '\t');
let keys = options.fields;
let line = 1;
let data = [];
if (options.header) {
keys = getcsv();
options.fields.forEach(field => {
if (keys.indexOf(field) == -1) {
throw new Error('parseCSV: ' + field + ' is missing in ' + options.path);
}
});
line++;
}
let size = keys.length;
while (csv.length) {
let values = getcsv();
let o = {};
if (values.length != size) {
throw new Error('parseCSV: columns do not match. keys: ' + size + ', values: ' + values.length + ' at line ' + line);
}
for (let i = 0; i < size; i++) {
o[keys[i]] = values[i];
}
data.push(o);
line++;
}
return data;
function getcsv() {
let data = [''], l = csv.length,
esc = false, escesc = false,
n = 0, i = 0;
while (i < l) {
let s = csv.charAt(i);
if (s == '\n') {
if (esc) {
data[n] += s;
} else {
i++;
break;
}
} else if (s == '\r') {
if (esc) {
data[n] += s;
}
} else if (s == delimiter) {
if (esc) {
data[n] += s;
} else {
data[++n] = '';
esc = false;
escesc = false;
}
} else if (s == '"') {
if (escesc) {
data[n] += s;
escesc = false;
}
if (esc) {
esc = false;
escesc = true;
} else {
esc = true;
escesc = false;
}
} else {
if (escesc) {
data[n] += '"';
escesc = false;
}
data[n] += s;
}
i++;
}
csv = csv.substr(i);
return data;
}
}
module.exports = {
csv: async function(options) {
let path = this.parseRequired(options.path, 'string', 'export.csv: path is required.');
let fields = this.parseOptional(options.fields, 'object', []);
let header = this.parseOptional(options.header, 'boolean', false);
let delimiter = this.parseOptional(options.delimiter, 'string', ',');
let csv = await fs.readFile(toSystemPath(path), 'utf8');
return parseCSV(csv, { fields, header, delimiter });
},
xml: async function(options) {
// TODO: import.xml
throw new Error('import.xml: not implemented.');
},
};