generic-csv.mjs
55 lines 1.8 KB
Raw
sha256:8915fe406161f95c1681f9469375e7bae5b28c884f00bedbdef65e4b0cd0738d docs(flow): commit FLOW-V0-SPEC.md hygiene for 7A-INT merge Human 10 hours ago
1 /**
2 * Generic tabular CSV: header row, one Markdown note per data row.
3 * UTF-8; strips BOM. Row cap and field length cap for safety.
4 */
5
6 import fs from 'fs';
7 import path from 'path';
8 import { parseCSVLine } from '../csv-parse-line.mjs';
9 import { importStringMatrixToNotes } from './tabular-import.mjs';
10
11 const MAX_CSV_BYTES = 50 * 1024 * 1024;
12
13 /**
14 * @param {string} input
15 * @param {{ vaultPath: string, outputBase: string, project?: string, tags: string[], dryRun: boolean }} ctx
16 */
17 export async function importGenericCsv(input, ctx) {
18 const absInput = path.isAbsolute(input) ? input : path.resolve(process.cwd(), input);
19 if (!fs.existsSync(absInput) || !fs.statSync(absInput).isFile()) {
20 throw new Error('generic-csv import expects a path to a .csv file.');
21 }
22 if (!absInput.toLowerCase().endsWith('.csv')) {
23 throw new Error('generic-csv import requires a .csv file.');
24 }
25 const stat = fs.statSync(absInput);
26 if (stat.size > MAX_CSV_BYTES) {
27 throw new Error(`CSV file too large (max ${MAX_CSV_BYTES} bytes).`);
28 }
29
30 let raw = fs.readFileSync(absInput, 'utf8');
31 if (raw.charCodeAt(0) === 0xfeff) {
32 raw = raw.slice(1);
33 }
34 const lines = raw.split(/\r?\n/).filter((l) => l.length > 0);
35 if (lines.length < 2) {
36 return { imported: [], count: 0 };
37 }
38
39 const h0 = parseCSVLine(lines[0]).map((h) => h.trim());
40 const headerLabels = h0.map((h) => h || 'column');
41 /** @type {(string|number)[][]} */
42 const matrix = [headerLabels];
43 for (let i = 1; i < lines.length; i++) {
44 const row = parseCSVLine(lines[i]);
45 matrix.push(headerLabels.map((_, j) => (j < row.length ? row[j] : '')));
46 }
47
48 const baseName = path.basename(absInput);
49 return importStringMatrixToNotes(matrix, ctx, {
50 source: 'csv-import',
51 fileLabel: baseName,
52 subdir: 'csv',
53 fileKey: 'csv_file',
54 });
55 }
File History 1 commit
sha256:8915fe406161f95c1681f9469375e7bae5b28c884f00bedbdef65e4b0cd0738d docs(flow): commit FLOW-V0-SPEC.md hygiene for 7A-INT merge Human 10 hours ago