Skip to content

Instantly share code, notes, and snippets.

@zelaznik
Created November 11, 2023 00:42
Show Gist options
  • Save zelaznik/3d37c80e04f9db46252652ecb092a42f to your computer and use it in GitHub Desktop.
Save zelaznik/3d37c80e04f9db46252652ecb092a42f to your computer and use it in GitHub Desktop.
Webpack Plugin, From CSV To Typescript
var file_path = "/Users/stevezelaznik/src/gnar/aarp-foundation-pta/app/javascript/src/tools/mn-2023/tables/renters_refund_table.csv"
var fs = require("fs");
var Papa = require("papaparse");
var sourceText = fs.readFileSync(file_path).toString();
function hydrateType(types, cell, column_index) {
const type = typeof cell
switch(type) {
case 'string':
types[column_index]['string'] = true;
break;
case 'number':
types[column_index]['number'] = true;
break;
default:
throw new Error(`Unsupported type ${type}`);
}
}
function makeType(type_columns) {
var lines = [];
return '[' + type_columns.map(col => {
var keys = Object.keys(col);
if (keys.length > 1) {
var col_type = keys.sort().join(" | ");
return '(' + col_type + ')';
} else {
return keys[0];
}
}).join(', ') + ']';
}
function process(sourceText, /*sourePath, options*/) {
var data = Papa.parse(sourceText, {
dynamicTyping: true,
skipEmptyLines: true
}).data
// Create an array of empty object [ {}, {}, {}, {} ]
// those will be used to get a unique set of types used across all rows
// something like [ { string: true }, { string: true, number: true } ]
var header_types = data[0].map(() => ({}));
var value_types = data[1].map(() => ({}));
// get the header types
data[0].forEach((cell, i) => hydrateType(header_types, cell, i));
// get the types for each column in the data
data.slice(1).forEach((row) => {
row.forEach((cell, i) => hydrateType(value_types, cell, i));
});
var code = [
`type CsvHeader = [${header_types.map(t => Object.keys(t).sort().join(" | ")).join(', ')}]`,
`type CsvRow = [${value_types.map(t => Object.keys(t).sort().join(" | ")).join(', ')}]`,
"",
"type CsvFile = [CsvHeader, ...CsvRow[]]",
"",
"const data: CsvFile = [",
data.slice(0, 20).map(row => " " + JSON.stringify(row) + ",").join("\n"),
"];",
"",
"export default data;"
]
return {
code: code.join("\n")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment