-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconvert.ts
More file actions
48 lines (36 loc) · 1.69 KB
/
convert.ts
File metadata and controls
48 lines (36 loc) · 1.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**
* Reads/parses/validates fieldMap and reads associated data files
*/
import { parse } from 'yaml';
import check from './utils/checks';
import parseFieldMap from './utils/parseFieldMap';
import parseFile from './utils/parseFile';
import rowsToObjects from './utils/rowsToObjects';
const { promises: fs } = require('fs');
export default async (yamlFilePath) => {
const fieldMap = parse(await fs.readFile(yamlFilePath, 'utf8'));
// ensure the right format & required values
check(fieldMap);
// map = fieldMap.fields with nulls cleared
const map = {};
for (const [key, value] of Object.entries(fieldMap.fields)) {
if (value) map[key] = value;
}
return await fieldMap.files.reduce((out: any, fileName: string) => {
// open, check, and parse .csv or .xlsx
let data = parseFile(fileName);
// split header row, which corresponds to spreadsheet column names
const columns = data.shift();
// map matched fields to their column index while separating unmatched fields
// fields.matched[airtable field] = index of corresponding spreadsheet column
// fields.indexes = list of indexes of necessary spreadsheet columns
// fields.unmatched[airtable field] = value to hard-code
// fields.total = max number of fields per object
const fields = parseFieldMap(map, columns);
// filter out rows where too many listed fields are empty
// and turn the array of arrays into an array of objects
data = rowsToObjects(data, fields);
console.log(`Created ${data.length} objects (of up to ${fields.total} fields each) from ${fileName}`);
return [...out, ...data];
}, []);
};