1
0
Fork 0
mirror of synced 2024-09-19 10:48:30 +12:00
budibase/packages/server/src/utilities/csvParser.js

81 lines
1.8 KiB
JavaScript
Raw Normal View History

2020-10-03 04:16:06 +13:00
const csv = require("csvtojson")
const VALIDATORS = {
string: () => true,
number: attribute => !isNaN(Number(attribute)),
datetime: attribute => !isNaN(new Date(attribute).getTime()),
}
const PARSERS = {
datetime: attribute => new Date(attribute).toISOString(),
}
function parse(path, parsers) {
2020-10-05 22:51:58 +13:00
const result = csv({ parsers }).fromFile(path)
2020-10-03 04:16:06 +13:00
const schema = {}
return new Promise((resolve, reject) => {
result.on("header", headers => {
for (let header of headers) {
schema[header] = {
type: parsers[header] ? parsers[header].type : "string",
success: true,
}
}
})
result.fromFile(path).subscribe(row => {
// For each CSV row
// parse all the columns that need parsed
for (let key in parsers) {
2020-10-05 22:51:58 +13:00
// if the parsing has already failed for a column
// skip that column
if (
!schema[key] ||
!schema[key].success ||
schema[key].type === "omit"
) {
continue
}
2020-10-03 04:16:06 +13:00
2020-10-05 22:51:58 +13:00
// get the validator for the column type
2020-10-03 04:16:06 +13:00
const validator = VALIDATORS[parsers[key].type]
try {
schema[key].success = !!validator(row[key])
} catch (err) {
schema[key].success = false
}
}
})
result.on("done", error => {
if (error) {
console.error(error)
reject(error)
}
resolve(schema)
})
})
}
async function transform({ schema, path }) {
const colParser = {}
for (let key in schema) {
2020-10-05 22:51:58 +13:00
colParser[key] = PARSERS[schema[key].type] || schema[key].type
2020-10-03 04:16:06 +13:00
}
try {
const json = await csv({ colParser }).fromFile(path)
return json
} catch (err) {
console.error(`Error transforming CSV to JSON for data import`, err)
}
}
module.exports = {
parse,
transform,
}