xlsx-for-ai 1.4.1 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +38 -0
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -599,6 +599,23 @@ function dumpSheetJSON(ws, wb, opts = {}) {
599
599
  if (col.hidden) out.hiddenColumns.push(letter);
600
600
  out.columns.push({ letter, width: col.width || null, hidden: !!col.hidden });
601
601
  }
602
+ // Some xlsx files set widths on columns past the populated range (e.g.,
603
+ // columns reserved for future data, or styling-only columns). ExcelJS's
604
+ // columnCount stops at populated cells, so a naive loop misses those widths
605
+ // and they silently drop on round-trip. Walk ws.columns directly to pick up
606
+ // any column metadata beyond endCol.
607
+ try {
608
+ const allCols = ws.columns || [];
609
+ for (let i = endCol; i < allCols.length; i++) {
610
+ const col = allCols[i];
611
+ if (!col) continue;
612
+ if (col.width != null || col.hidden) {
613
+ const letter = colLetter(i + 1);
614
+ if (col.hidden) out.hiddenColumns.push(letter);
615
+ out.columns.push({ letter, width: col.width || null, hidden: !!col.hidden });
616
+ }
617
+ }
618
+ } catch (_) {}
602
619
 
603
620
  if (ws.autoFilter) out.autoFilter = typeof ws.autoFilter === 'string' ? ws.autoFilter : (ws.autoFilter.ref || null);
604
621
  try { if (ws.pageSetup?.printArea) out.printArea = ws.pageSetup.printArea; } catch (_) {}
@@ -1294,6 +1311,20 @@ function buildWorkbook(spec) {
1294
1311
  try { ws.getColumn(colNum(letter)).width = width; } catch (_) {}
1295
1312
  }
1296
1313
  }
1314
+ // Also read widths from the `columns` array — that's the shape `--json`
1315
+ // output produces (`columns: [{letter, width, hidden}, ...]`). Without
1316
+ // this, round-tripping a workbook through `--json` → `write` silently
1317
+ // dropped all column widths, breaking the documented round-trip claim.
1318
+ if (Array.isArray(sheet.columns)) {
1319
+ for (const col of sheet.columns) {
1320
+ if (!col || !col.letter) continue;
1321
+ try {
1322
+ const c = ws.getColumn(colNum(col.letter));
1323
+ if (col.width != null) c.width = col.width;
1324
+ if (col.hidden) c.hidden = true;
1325
+ } catch (_) {}
1326
+ }
1327
+ }
1297
1328
 
1298
1329
  if (Array.isArray(sheet.cells)) {
1299
1330
  // Per-cell mode (round-trip from --json). cells: [{ref, value, ...style}, ...]
@@ -1631,6 +1662,13 @@ async function mainWrite(argv) {
1631
1662
  async function main() {
1632
1663
  const argv = process.argv.slice(2);
1633
1664
 
1665
+ // --version / -v: short-circuit before any file parsing so users can ask
1666
+ // the version without it being treated as a filename. Mirrors --help.
1667
+ if (argv[0] === '--version' || argv[0] === '-v') {
1668
+ console.log(require('./package.json').version);
1669
+ process.exit(0);
1670
+ }
1671
+
1634
1672
  // Sub-command dispatch
1635
1673
  if (argv[0] === 'write') return mainWrite(argv.slice(1));
1636
1674
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xlsx-for-ai",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "description": "CLI that converts .xlsx files into rich text or JSON dumps that AI coding agents (Claude, Cursor, Copilot, ChatGPT, etc.) can read — preserving values, formulas, formatting, colors, column widths, frozen panes, named ranges, tables, and more.",
5
5
  "main": "index.js",
6
6
  "bin": {