-
Notifications
You must be signed in to change notification settings - Fork 0
fix: improve diff conversion for CSV, XML, and file parsing (#77, #78) #121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,7 +59,23 @@ export function inferHeaders(records: Array<Record<string, unknown>>): string[] | |
| export async function parseJsonFile(file: File): Promise<ParsedDataset> { | ||
| const text = await file.text(); | ||
| const parsed = JSON.parse(text) as unknown; | ||
| const records = Array.isArray(parsed) ? parsed : [parsed]; | ||
|
|
||
| // Unwrap metadata-wrapped exports (e.g. { exportedAt, records: [...] }) | ||
| // so that re-importing our own JSON output yields the original records. | ||
| let records: unknown[]; | ||
| if (Array.isArray(parsed)) { | ||
| records = parsed; | ||
| } else if ( | ||
| parsed && | ||
| typeof parsed === 'object' && | ||
| !Array.isArray(parsed) && | ||
| Array.isArray((parsed as Record<string, unknown>).records) | ||
| ) { | ||
| records = (parsed as Record<string, unknown>).records as unknown[]; | ||
|
Comment on lines
+72
to
+74
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When an uploaded JSON document is intended to be one record but has an array-valued field named Useful? React with 馃憤聽/ 馃憥. |
||
| } else { | ||
| records = [parsed]; | ||
| } | ||
|
|
||
| const objects = records | ||
| .filter(r => r && typeof r === 'object') | ||
| .map(r => r as Record<string, unknown>); | ||
|
|
@@ -123,14 +139,24 @@ export async function parseExcelFile(file: File): Promise<ParsedDataset> { | |
| } | ||
| const XLSX = await import(/* webpackChunkName: "xlsx" */ 'xlsx/dist/xlsx.mini.min.js'); | ||
| const buf = await file.arrayBuffer(); | ||
| const wb = XLSX.read(buf, { type: 'array', sheetRows: MAX_EXCEL_ROWS + 1 }); | ||
| // cellDates converts Excel date serial numbers to JS Date objects at read time; | ||
| // raw: true on sheet_to_json preserves numeric precision (avoids scientific notation on long IDs). | ||
| const wb = XLSX.read(buf, { type: 'array', sheetRows: MAX_EXCEL_ROWS + 1, cellDates: true }); | ||
| const sheetName = wb.SheetNames[0]; | ||
| if (!sheetName) throw new Error('Excel file contains no sheets'); | ||
| const sheet = wb.Sheets[sheetName]; | ||
| const rows = XLSX.utils.sheet_to_json<Record<string, unknown>>(sheet, { defval: null, raw: false }); | ||
| if (rows.length > MAX_EXCEL_ROWS) { | ||
| const rawRows = XLSX.utils.sheet_to_json<Record<string, unknown>>(sheet, { defval: null, raw: true }); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When an XLSX column contains numeric identifiers with formatting such as Useful? React with 馃憤聽/ 馃憥. |
||
| if (rawRows.length > MAX_EXCEL_ROWS) { | ||
| throw new Error(`Excel worksheets must contain ${MAX_EXCEL_ROWS.toLocaleString()} rows or fewer`); | ||
| } | ||
| // Convert Date objects to ISO strings for consistent round-trip fidelity. | ||
| const rows = rawRows.map(row => { | ||
| const out: Record<string, unknown> = {}; | ||
| for (const [k, v] of Object.entries(row)) { | ||
| out[k] = v instanceof Date ? v.toISOString() : v; | ||
| } | ||
| return out; | ||
| }); | ||
| return { records: rows, headers: inferHeaders(rows) }; | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When two JSON files contain semantically identical nested objects with different property order, direct
JSON.stringifycalls produce different strings鈥攆or example,{a: 1, b: 2}versus{b: 2, a: 1}. The local Diff flow preserves JSON insertion order and passes these values here, so it incorrectly reports the field and record as changed. Use an order-independent deep comparison or canonical key ordering for objects.Useful? React with 馃憤聽/ 馃憥.