xlvane 1.2.3 → 1.3.0

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.
package/README.md CHANGED
@@ -26,7 +26,7 @@ From a shell: `npx xlvane inspect orders.xlsx`, then `npx xlvane read orders.xls
26
26
  ## Contents
27
27
 
28
28
  - [Command line in 5 minutes](#command-line-in-5-minutes)
29
- - [Reading a workbook](#reading-a-workbook) · [Writing a workbook](#writing-a-workbook) (rich text, hyperlinks, notes, images, printing, [data validation and conditional formatting](#data-validation-and-conditional-formatting), [tables](#tables))
29
+ - [Reading a workbook](#reading-a-workbook) · [Writing a workbook](#writing-a-workbook) (rich text, hyperlinks, notes, images, [charts](#charts), printing, [data validation and conditional formatting](#data-validation-and-conditional-formatting), [tables](#tables))
30
30
  - [Tasks in one call](#tasks-in-one-call): tables of rows, CSV, JSON, editing files, diff · [inserting and deleting rows](#inserting-and-deleting-rows)
31
31
  - [Large files: streaming](#large-files-streaming)
32
32
  - [Inspecting a workbook](#inspecting-a-workbook) · [Errors and warnings](#errors-and-warnings) · [Untrusted input and limits](#untrusted-input-and-limits)
@@ -172,10 +172,41 @@ for (const picture of read.getSheet('Report').images) console.log(picture.anchor
172
172
  ```
173
173
 
174
174
  - **Adding:** `workbook.addImage(bytes)` takes PNG, JPEG or GIF bytes (recognised from the first bytes; other formats throw `XLV_E_INVALID_IMAGE`) and returns a number; the same image placed many times is stored once. `sheet.addImage(image, anchor, { name?, description?, hyperlink? })` places it over a range (`"E1:G4"`), between two corners (`{ from, to, editAs }`, each a cell or a 0-based `{ col, row }` with fractions) or at a corner with a size in pixels (`{ from, size }`). `sheet.background(image)` sets the sheet background. Pixels are converted at 96 per inch (9525 EMU); fractional positions use the sheet's column widths and row heights.
175
- - **Reading:** `sheet.images` lists the pictures (`anchor` in EMU with the cell of each corner, `image` with `format`, `contentType` and `bytes`, `description`, `hyperlink`), `sheet.backgroundImage` the background, and `workbook.images` every image once. Charts, shapes and other drawing objects are not read; `XLV_W_DRAWING_CONTENT_NOT_READ` reports them, and `editCells` keeps them unchanged.
175
+ - **Reading:** `sheet.images` lists the pictures (`anchor` in EMU with the cell of each corner, `image` with `format`, `contentType` and `bytes`, `description`, `hyperlink`), `sheet.backgroundImage` the background, and `workbook.images` every image once. Charts are read into `sheet.charts` (see [Charts](#charts)); shapes and other drawing objects are not read: `XLV_W_DRAWING_CONTENT_NOT_READ` reports them, and `editCells` keeps them unchanged.
176
176
  - **Rows:** `insertRows` and `deleteRows` move pictures with their rows. A deletion that would cut a picture, and a drawing with charts or shapes, are refused with `XLV_E_NOT_SUPPORTED`.
177
177
  - **Streaming:** `writeWorkbookStream({ images: [png], sheets: [{ images: [{ image: 0, anchor: 'B2:D6' }], background: 0, rows }] })`.
178
178
 
179
+ ### Charts
180
+
181
+ ```ts
182
+ import { createWorkbook, readWorkbook, writeWorkbook } from 'xlvane';
183
+
184
+ const workbook = createWorkbook();
185
+ const sales = workbook.addSheet('Sales').set('A1', 'Month').set('B1', 'North').set('C1', 'South');
186
+ ['Jan', 'Feb', 'Mar'].forEach((month, i) => sales.set(`A${String(i + 2)}`, month).set(`B${String(i + 2)}`, 10 + i).set(`C${String(i + 2)}`, 20 - i));
187
+ sales.addChart({
188
+ type: 'column',
189
+ anchor: 'E2:L18',
190
+ title: 'Sales by month',
191
+ series: [
192
+ { name: 'Sales!B1', categories: 'Sales!A2:A4', values: 'Sales!B2:B4' },
193
+ { name: 'Sales!C1', categories: 'Sales!A2:A4', values: 'Sales!C2:C4', color: 'C00000' },
194
+ ],
195
+ legend: 'bottom',
196
+ axes: { y: { title: 'Units', min: 0 } },
197
+ });
198
+
199
+ const chart = readWorkbook(writeWorkbook(workbook)).getSheet('Sales').charts[0];
200
+ console.log(chart?.types, chart?.title, chart?.series.map((s) => s.values)); // ['column'] { text: 'Sales by month' } ['Sales!$B$2:$B$4', 'Sales!$C$2:$C$4']
201
+ ```
202
+
203
+ - **Adding:** `sheet.addChart({ type, anchor, series, title?, legend?, stacked?, axes?, name?, description? })` with `type` `column`, `bar`, `line`, `pie`, `scatter` or `area`; `anchor` as for pictures. Each series has `values` and optional `categories` (for scatter: the y and x values), each a sheet-qualified range of one row or one column such as `'Sales Data'!B2:B13`, an optional `name` (literal text, or a one-cell reference such as `Sales!B1`) and an optional `color` (`RRGGBB`). `stacked` is `true` or `'percent'` (not for pie and scatter); `legend` is `'right'` (default), `'bottom'`, `'top'`, `'left'` or `false`; `axes.x.title`, `axes.y.title`, `axes.y.min`, `axes.y.max`. A chart has 1 to 255 series; a pie exactly one, with at most 1 000 values. The sheets named in the ranges must exist when the workbook is written. Errors: `XLV_E_INVALID_CHART`.
204
+ - **What is written:** a chart part per chart with the series colours from a fixed palette (the accent colours of Excel's Office theme), since xlvane writes no theme part, and with the current cell values as caches, as Excel writes them. Combination charts, secondary axes, trendlines, data labels and chart sheets are not written.
205
+ - **Reading:** `sheet.charts` lists each chart's `name`, `description`, `anchor`, `types` (the chart groups in order, for example `['column', 'line']` for a combination chart; other chart types as `other:` and the element name), `stacked`, `title` (`{ text }`, `{ ref }` or `null`), `legend`, `axes` (`title`, `min`, `max`) and `series` (`type`, `name`, `categories`, `values` as reference text). References are never evaluated and cached values are not read. Charts on chart sheets are not read. `openWorkbookStream` does not report pictures or charts.
206
+ - **Streaming:** `writeWorkbookStream({ sheets: [{ name: 'Sales', rows, charts: [{ type: 'line', anchor: 'E2:L18', series: [...] }] }] })`. The streaming writer keeps no cell values, so its charts have no caches. LibreOffice draws such charts from the cells; whether Excel does is not verified.
207
+ - **Rows:** `insertRows` and `deleteRows` refuse sheets with charts, and workbooks whose charts may refer to the sheet, with `XLV_E_NOT_SUPPORTED`.
208
+ - **Checked with:** a copy of the ECMA-376 chart schema and LibreOffice 24.2.7.2, not with Excel. In the repository, `node scripts/chart-samples.mjs <directory>` (after `npm run build`) writes one sample file per type and variant.
209
+
179
210
  ### Sheet rules and printing
180
211
 
181
212
  ```ts
@@ -387,7 +418,7 @@ Limits can be changed per call, for example `readWorkbook(bytes, { limits: { max
387
418
  | `maxXmlNameLength` | 1 024 | huge element or attribute names |
388
419
  | `maxXmlTextLength` | 8 Mi characters | huge text nodes, attribute values, comments or processing instructions |
389
420
  | `maxXmlTreeElements` | 1 000 000 | huge workbook, styles or relationship parts (elements plus attributes) |
390
- | `maxCells` | 5 000 000 | workbooks too large to hold in memory (measured: about 180 bytes per numeric cell, Node.js 26); also bounds the output of `toCSV`, `readTable`, `toJSON` and `readTableStream` to `max(maxCells, 16 × cells read)` positions, and of `fromCSV`, `fromJSON` and `writeTable` to `max(maxCells, 16 × cells written)` |
421
+ | `maxCells` | 5 000 000 | workbooks too large to hold in memory (measured: about 180 bytes per numeric cell, Node.js 26); also bounds the output of `toCSV`, `readTable`, `toJSON` and `readTableStream` to `max(maxCells, 16 × cells read)` positions, and of `fromCSV`, `fromJSON` and `writeTable` to `max(maxCells, 16 × cells written)`; for `editCells` and `appendRows`, the cells of the workbook plus the new cells, and at most 1 000 000 cells written per call unless `maxCells` is given; for `insertRows` with `style`, the copied cell formats plus the cells of the workbook |
391
422
  | `maxSharedStringChars` | 512 Mi characters | many cells pointing at one huge shared string (a few MB that become many GB when values are copied); counted separately, the same for cells sharing one huge formula and for header names repeated in every row object of `readTable` and `toJSON` |
392
423
 
393
424
  ## Package size
@@ -398,7 +429,7 @@ Limits can be changed per call, for example `readWorkbook(bytes, { limits: { max
398
429
 
399
430
  - xlvane does not calculate formulas. It reads and writes formula text and the cached results stored in the file; edited files ask spreadsheet applications to recalculate when they are opened.
400
431
  - Password-protected (encrypted) workbooks and legacy `.xls` files are rejected with `XLV_E_UNSUPPORTED_CONTAINER`. A sheet protection password is not encryption and is supported.
401
- - Charts, shapes, pivot tables, slicers and form controls are not modelled: reading skips them (with a warning for drawings), `editCells` keeps them unchanged, and row operations refuse sheets where they would have to move.
432
+ - Shapes, pivot tables, slicers and form controls are not modelled: reading skips them (with a warning for drawings), `editCells` keeps them unchanged, and row operations refuse sheets where they would have to move. Charts are read and written for six types (see [Charts](#charts)); row operations refuse them too.
402
433
  - The command line reads files, not standard input.
403
434
 
404
435
  ## Links
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { Ut as suggest, _ as isoDate, b as readWorkbook, g as inspect, jn as XlvError, pn as parseRange } from "./options-Cw7OraxE.js";
3
- import { a as appendRows, c as fromCSV, d as fromJSON, f as pickSheet, h as toJSON, l as inferValue, n as insertRows, o as editCells, p as readTable, s as diff, t as deleteRows, u as toCSV } from "./rows-DnlfBgme.js";
4
- import { i as readInput } from "./node-files-Bxzv7THG.js";
2
+ import { Vt as suggest, _ as inspect, v as isoDate, x as readWorkbook, yn as parseRange, zn as XlvError } from "./options-Cxt-LJE4.js";
3
+ import { a as appendRows, c as fromCSV, d as fromJSON, f as pickSheet, h as toJSON, l as inferValue, n as insertRows, o as editCells, p as readTable, s as diff, t as deleteRows, u as toCSV } from "./rows-DltZ-hiW.js";
4
+ import { i as readInput } from "./node-files-SVg17pky.js";
5
5
  import { existsSync, readFileSync } from "node:fs";
6
6
  import { lstat, open, readFile, readdir, rename, rm, stat, writeFile } from "node:fs/promises";
7
7
  import process from "node:process";
@@ -523,14 +523,15 @@ function oneLine(text) {
523
523
  }
524
524
  /**
525
525
  * Control characters that a terminal would act on (C0 except tab and line feed, DEL, and C1,
526
- * which includes the 8-bit CSI U+009B) written as `\x1b`, and bidirectional formatting characters
527
- * written as `\u202e`, so text from a file, such as a cell
526
+ * which includes the 8-bit CSI U+009B) written as `\x1b`, bidirectional formatting characters
527
+ * written as `\u202e`, and line feeds written as `⏎` (so a name from a file cannot add lines of its
528
+ * own to the output, D-K04), so text from a file, such as a cell
528
529
  * holding `_x001B_]0;title_x0007_`, cannot move the cursor, change the window title or hide
529
530
  * output (docs/decisions.md D-R02). Used for all human-readable output; `--json` writes the same
530
531
  * characters as `\uXXXX` escapes instead (D-H01).
531
532
  */
532
533
  function escapeControls(text) {
533
- return text.replace(/[\u0000-\u0008\u000b-\u001f\u007f-\u009f]/g, (c) => `\\x${c.charCodeAt(0).toString(16).padStart(2, "0")}`).replace(BIDI, (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`);
534
+ return text.replace(/\n/g, "⏎").replace(/[\u0000-\u0008\u000b-\u001f\u007f-\u009f]/g, (c) => `\\x${c.charCodeAt(0).toString(16).padStart(2, "0")}`).replace(BIDI, (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`);
534
535
  }
535
536
  /**
536
537
  * The characters with the Unicode property Bidi_Control (checked against `/\p{Bidi_Control}/u` in
@@ -817,8 +818,8 @@ function withPath(error, path) {
817
818
  }
818
819
  /**
819
820
  * For a missing file, suggests a file with a similar name in the same directory: only a name the
820
- * command can read (`accept`), and never a file that another argument of the command already
821
- * names, such as the other side of a diff (D-R08).
821
+ * command can read (`accept`), and never the path itself or a file that another argument of the
822
+ * command already names, such as the other side of a diff (D-R08, D-K04).
822
823
  */
823
824
  async function withFileHint(ctx, path, error, accept) {
824
825
  if (!(error instanceof XlvError) || error.details["code"] !== "ENOENT") return error;
@@ -829,6 +830,7 @@ async function withFileHint(ctx, path, error, accept) {
829
830
  return error;
830
831
  }
831
832
  const others = new Set(ctx.argv.filter((a) => a !== path && !a.startsWith("-")).map((a) => resolvePath(ctx, a)));
833
+ others.add(resolvePath(ctx, path));
832
834
  const candidates = names.filter((n) => accept(n) && !others.has(resolvePath(ctx, join(dirname(path), n))));
833
835
  const close = suggest(basename(path), candidates, 1);
834
836
  if (close.length === 0) return error;
@@ -856,16 +858,26 @@ async function writeOutput(ctx, path, data, options) {
856
858
  let exists = false;
857
859
  let mode = null;
858
860
  try {
859
- const info = await stat(target);
861
+ const link = await lstat(target);
860
862
  exists = true;
861
- mode = info.mode & 511;
862
- if (!info.isFile()) throw new XlvError("XLV_E_FILE_WRITE", `"${path}" is a directory.`, {
863
- hint: "Give a file name for the output.",
864
- details: {
865
- path,
866
- code: "EISDIR"
867
- }
868
- });
863
+ const info = link.isSymbolicLink() ? await stat(target).catch(() => null) : link;
864
+ if (info !== null) {
865
+ mode = info.mode & 511;
866
+ if (info.isDirectory()) throw new XlvError("XLV_E_FILE_WRITE", `"${path}" is a directory.`, {
867
+ hint: "Give a file name for the output.",
868
+ details: {
869
+ path,
870
+ code: "EISDIR"
871
+ }
872
+ });
873
+ if (!info.isFile()) throw new XlvError("XLV_E_FILE_WRITE", `"${path}" is not a regular file.`, {
874
+ hint: "Give the name of a regular file for the output.",
875
+ details: {
876
+ path,
877
+ code: "ENOTREG"
878
+ }
879
+ });
880
+ }
869
881
  } catch (error) {
870
882
  if (error instanceof XlvError) throw error;
871
883
  }
@@ -882,10 +894,10 @@ async function writeOutput(ctx, path, data, options) {
882
894
  try {
883
895
  if (exists) {
884
896
  const random = Array.from(globalThis.crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(8)), (b) => b.toString(16).padStart(2, "0")).join("");
885
- const temp = join(dirname(target), `.${basename(target)}.xlvane-${random}.tmp`);
897
+ const temp = join(dirname(target), `.${shortName(basename(target))}.xlvane-${random}.tmp`);
886
898
  let created = false;
887
899
  try {
888
- const handle = await open(temp, "wx", 384);
900
+ const handle = await open(temp, "wx", mode === null ? void 0 : 384);
889
901
  created = true;
890
902
  try {
891
903
  await handle.writeFile(bytes);
@@ -922,6 +934,21 @@ async function writeOutput(ctx, path, data, options) {
922
934
  replaced: exists
923
935
  };
924
936
  }
937
+ /**
938
+ * The start of a file name, at most 100 bytes of UTF-8 and never cut inside a character, for the
939
+ * name of a temporary file next to it (file systems limit names in bytes, D-K03).
940
+ */
941
+ function shortName(name) {
942
+ let bytes = 0;
943
+ let end = 0;
944
+ for (const ch of name) {
945
+ const size = new TextEncoder().encode(ch).length;
946
+ if (bytes + size > 100) break;
947
+ bytes += size;
948
+ end += ch.length;
949
+ }
950
+ return name.slice(0, end);
951
+ }
925
952
  /** The line every writing command ends with; green when something was written. */
926
953
  function wroteLine(w, out) {
927
954
  if (!w.written) {
@@ -1714,10 +1741,10 @@ const editCommand = {
1714
1741
  render: (out) => {
1715
1742
  if (ctx.quiet && w.written) return "";
1716
1743
  const done = [
1717
- insert !== null ? `inserted ${plural(insert.count, "row")} before row ${String(insert.at)} of "${sheetOption ?? ""}"` : "",
1718
- remove !== null ? `deleted ${remove.count === 1 ? `row ${String(remove.at)}` : `rows ${String(remove.at)}–${String(remove.at + remove.count - 1)}`} of "${sheetOption ?? ""}"` : "",
1744
+ insert !== null ? `inserted ${plural(insert.count, "row")} before row ${String(insert.at)} of "${escapeControls(sheetOption ?? "")}"` : "",
1745
+ remove !== null ? `deleted ${remove.count === 1 ? `row ${String(remove.at)}` : `rows ${String(remove.at)}–${String(remove.at + remove.count - 1)}`} of "${escapeControls(sheetOption ?? "")}"` : "",
1719
1746
  parsed.length > 0 ? `set ${plural(parsed.length, "cell")}` : "",
1720
- rows.length > 0 ? `appended ${plural(rows.length, "row")} to "${appendSheet ?? ""}"` : ""
1747
+ rows.length > 0 ? `appended ${plural(rows.length, "row")} to "${escapeControls(appendSheet ?? "")}"` : ""
1721
1748
  ].filter((p) => p !== "").join(", ");
1722
1749
  return [
1723
1750
  `${done.charAt(0).toUpperCase()}${done.slice(1)}.`,
@@ -1861,6 +1888,10 @@ function renderReport(out, file, r, verbose) {
1861
1888
  lines.push(` Hyperlinks: ${plural(s.hyperlinkCount, "link")} (${shown.join(", ")}${s.hyperlinkCount > 3 ? ", …" : ""})`);
1862
1889
  }
1863
1890
  if (s.imageCount > 0) lines.push(` Images: ${plural(s.imageCount, "picture")} (${s.images.slice(0, 5).map((i) => `${i.cell ?? "absolute"} ${i.format ?? "other"}`).join(", ")}${s.imageCount > 5 ? ", …" : ""})`);
1891
+ if (s.chartCount > 0) {
1892
+ const shown = s.charts.slice(0, 5).map((c) => `${c.cell ?? "absolute"} ${escapeControls(c.types.join("+") || "empty")}${c.typesTruncated ? "+…" : ""}${c.title === null ? "" : "text" in c.title ? ` "${escapeControls(c.title.text)}"` : ` =${escapeControls(c.title.ref)}`}`);
1893
+ lines.push(` Charts: ${plural(s.chartCount, "chart")} (${shown.join(", ")}${s.chartCount > 5 ? ", …" : ""})`);
1894
+ }
1864
1895
  if (s.noteCount > 0) lines.push(` Notes: ${plural(s.noteCount, "note")} (${s.notes.slice(0, 5).join(", ")}${s.noteCount > 5 ? ", …" : ""})`);
1865
1896
  if (s.tables.length > 0) lines.push(` Tables: ${s.tables.slice(0, 5).map((table) => `${escapeControls(table.name)} ${escapeControls(table.ref)}`).join(", ")}${s.tables.length > 5 ? ", …" : ""}`);
1866
1897
  if (s.dataValidationCount > 0 || s.conditionalFormatCount > 0) {
@@ -2184,12 +2215,12 @@ async function run$1(ctx) {
2184
2215
  else if (alreadyMigrated) lines.push(`${pkgPath} already uses ${ALIAS} for "exceljs".`);
2185
2216
  else {
2186
2217
  lines.push(`${out.bold("Change in")} ${pkgPath}:`);
2187
- for (const c of changes) lines.push(` ${c.section}: ${out.red(`- "exceljs": "${c.from}"`)}`, ` ${" ".repeat(c.section.length)} ${out.green(`+ "exceljs": "${c.to}"`)}`);
2218
+ for (const c of changes) lines.push(` ${c.section}: ${out.red(`- "exceljs": "${escapeControls(c.from)}"`)}`, ` ${" ".repeat(c.section.length)} ${out.green(`+ "exceljs": "${escapeControls(c.to)}"`)}`);
2188
2219
  }
2189
- lines.push(`Node.js: require('exceljs') of @xlvane/compat needs Node.js 22.12 or later (package.json engines.node: ${typeof engines === "string" ? `"${engines}"` : "not set"}).`);
2220
+ lines.push(`Node.js: require('exceljs') of @xlvane/compat needs Node.js 22.12 or later (package.json engines.node: ${typeof engines === "string" ? `"${escapeControls(engines)}"` : "not set"}).`);
2190
2221
  lines.push("", `Scanned ${plural(files.length, "source file")}${limited ? ` (stopped at ${String(MAX_FILES)})` : ""} for exceljs API that @xlvane/compat does not fully support:`);
2191
2222
  if (findings.length === 0) lines.push(" none found.");
2192
- for (const f of findings.slice(0, 200)) lines.push(` ${f.status === "partly" ? out.yellow("partly ") : out.red("not supported")} ${f.file}:${String(f.line)}:${String(f.column)} ${f.api}`);
2223
+ for (const f of findings.slice(0, 200)) lines.push(` ${f.status === "partly" ? out.yellow("partly ") : out.red("not supported")} ${escapeControls(f.file)}:${String(f.line)}:${String(f.column)} ${escapeControls(f.api)}`);
2193
2224
  if (findings.length > 200) lines.push(out.dim(` … ${String(findings.length - 200)} more; use --json for all`));
2194
2225
  lines.push(" Details: docs/exceljs-compat.md. Unsupported calls throw XLV_E_NOT_SUPPORTED at run time.");
2195
2226
  lines.push("");
@@ -2351,7 +2382,7 @@ const readCommand = {
2351
2382
  result,
2352
2383
  exitCode: 0,
2353
2384
  render: (out) => {
2354
- if (table.columns.length === 0) return `Sheet "${table.sheet}" has no data${table.range ? ` in ${table.range}` : ""}.`;
2385
+ if (table.columns.length === 0) return `Sheet "${escapeControls(table.sheet)}" has no data${table.range ? ` in ${table.range}` : ""}.`;
2355
2386
  const numeric = table.columns.map((c) => shown.length > 0 && shown.every((row) => row[c.key] === null || typeof row[c.key] === "number") ? "right" : "left");
2356
2387
  return out.table(table.columns.map((c) => c.header ?? c.key), shown.map((row) => table.columns.map((c) => showValue(row[c.key]))), "", numeric);
2357
2388
  }
@@ -2461,6 +2492,8 @@ const COMMANDS = [
2461
2492
  const problems = [];
2462
2493
  let sheetName = null;
2463
2494
  let rowsChecked = 0;
2495
+ const named = str(ctx.args, "sheet");
2496
+ if (named !== void 0) workbook.getSheet(named);
2464
2497
  if (rules.length > 0) {
2465
2498
  const sheet = str(ctx.args, "sheet");
2466
2499
  const table = readTable(workbook, {
@@ -2532,7 +2565,7 @@ const COMMANDS = [
2532
2565
  lines.push("");
2533
2566
  }
2534
2567
  if (warnings.length > 0) lines.push(...warningsBlock(out, warnings), "");
2535
- const checked = sheetName !== null ? `, ${plural(rowsChecked, "row")} of sheet "${sheetName}" checked against ${plural(rules.length, "column rule")}` : "";
2568
+ const checked = sheetName !== null ? `, ${plural(rowsChecked, "row")} of sheet "${escapeControls(sheetName)}" checked against ${plural(rules.length, "column rule")}` : "";
2536
2569
  if (ok && warnings.length > 0) lines.push(`${out.yellow(`OK with ${plural(warnings.length, "warning")}`)}: ${file}${checked}. Use --strict to fail on warnings.`);
2537
2570
  else if (ok) lines.push(`${out.green("OK")}: ${file}${checked}.`);
2538
2571
  else lines.push(`${out.red("Failed")}: ${file}${checked}${strict && problems.length === 0 ? " (warnings count with --strict)" : ""}.`);
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as InspectOptions, $n as verifyPassword, $t as DataValidationOperator, A as toJSON, An as Hyperlink, At as Workbook, B as FormulaResult, Bn as PrintErrors, Bt as CfValue, C as TableRow, Cn as ImageAnchorInput, Ct as Sheet, D as fromJSON, Dn as SheetImage, Dt as SheetState, E as WriteTableOptions, En as ImagePositionInput, Et as SheetProperties, F as CellInput, Fn as PageOrder, Ft as TableDefinitionColumn, G as SheetPropertiesOptions, Gn as SheetProtectionOptions, Gt as ConditionalFormatRule, H as NewSheet, Hn as PrintTitles, Ht as CfValueType, I as ColumnOptions, In as PageOrientation, It as TableInput, J as WriteWorkbookOptions, Jn as HashPasswordOptions, Jt as DataBarAxisPosition, K as SheetViewOptions, Kn as WorkbookProtection, Kt as ConditionalFormatRuleInput, L as CreateWorkbookOptions, Ln as PageSetup, Lt as TableStyleOptions, M as StandardSchemaV1, Mn as HeaderFooter, Mt as WorkbookView, N as AddSheetOptions, Nn as PageBreaks, Nt as TableColumnInput, O as readTable, On as WorkbookImage, Ot as SheetView, P as CalculationOptions, Pn as PageMargins, Pt as TableDefinition, Q as InspectDefinedName, Qn as legacyPasswordHash, Qt as DataValidationImeMode, R as ERROR_VALUES, Rn as PageSetupOptions, Rt as TotalsRowFunction, S as TableResult, Sn as ImageAnchor, St as RowInfo, T as ToJSONOptions, Tn as ImageOptions, Tt as SheetLayout, U as NewWorkbook, Un as SheetProtection, Ut as ConditionalFormat, V as FreezeOptions, Vn as PrintOptions, Vt as CfValueInput, W as RowOptions, Wn as SheetProtectionFlags, Wt as ConditionalFormatOperator, X as writeWorkbook, Xn as PasswordVerifier, Xt as DataValidation, Y as createWorkbook, Yn as PasswordHash, Yt as DataBarDirection, Z as InspectColumn, Zn as hashPassword, Zt as DataValidationErrorStyle, _ as JsonTable, _n as ReadingOrder, _r as DefinedNameOptions, _t as DateSystem, a as WriteWorkbookStreamOptions, an as BorderEdge, ar as XlvDetails, at as ReadOptions, b as TableColumnSpec, bn as VerticalAlignment, bt as FrozenPanes, c as OpenWorkbookStreamOptions, cn as CellStyle, cr as XlvErrorInit, ct as NoteBox, d as StreamRow, dn as FontScheme, dr as XlvWarning, dt as NoteMargins, en as DataValidationRule, er as ShaAlgorithm, et as InspectReport, f as StreamSheetInfo, fn as FontStyle, fr as XlvWarningCode, ft as Cell, g as readTableStream, gn as ProtectionStyle, gr as DefinedName, gt as Conformance, h as openWorkbookStream, hn as PatternType, hr as ReadLimits, ht as ColumnInfo, i as WriteTableStreamOptions, in as AlignmentStyle, ir as XlvDetailValue, it as inspect, j as writeTable, jn as HyperlinkTarget, jt as WorkbookFormat, k as readTableAsync, kn as imageFormat, kt as SplitPanes, l as ReadTableStreamOptions, ln as Color, lr as XlvErrorJSON, lt as NoteBoxInput, m as WorkbookStream, mn as HorizontalAlignment, mr as DEFAULT_READ_LIMITS, mt as CellValue, n as StreamRowInput, nn as IconSetType, nr as ERROR_CODES, nt as InspectTypeCounts, o as writeTableStream, on as BorderLineStyle, or as XlvError, ot as readWorkbook, p as TableStreamItem, pn as GradientFill, pr as isXlvError, pt as CellType, q as WorkbookViewOptions, qn as WorkbookProtectionOptions, qt as ConditionalFormatType, r as StreamSheetSpec, rn as TimePeriod, rr as WARNING_CODES, rt as InspectValue, s as writeWorkbookStream, sn as BorderStyle, sr as XlvErrorCode, st as Note, t as StreamDefinedName, tn as DataValidationType, tr as WorkbookProperties, tt as InspectSheet, u as STREAM_LIMIT_DEFAULTS, un as FillStyle, ur as XlvLocation, ut as NoteInput, v as ReadTableOptions, vn as UnderlineStyle, vt as Formula, w as TableValue, wn as ImageFormat, wt as SheetKind, x as TableIssue, xn as AnchorMarker, xt as RichTextRun, y as TableColumn, yn as VerticalAlignRun, yt as FormulaKind, z as ErrorValue, zn as PrintCellComments, zt as CfIcon } from "./stream-write-y52KUDW8.js";
1
+ import { $ as InspectOptions, $n as SheetProtection, $t as DataValidationOperator, A as toJSON, An as SheetChart, At as Workbook, B as FormulaResult, Bn as Hyperlink, Bt as CfValue, C as TableRow, Cn as ChartInput, Cr as isXlvError, Ct as Sheet, D as fromJSON, Dn as ChartSeriesInput, Dr as DefinedNameOptions, Dt as SheetState, E as WriteTableOptions, En as ChartSeries, Er as DefinedName, Et as SheetProperties, F as CellInput, Fn as ImageOptions, Ft as TableDefinitionColumn, G as SheetPropertiesOptions, Gn as PageOrder, Gt as ConditionalFormatRule, H as NewSheet, Hn as HeaderFooter, Ht as CfValueType, I as ColumnOptions, In as ImagePositionInput, It as TableInput, J as WriteWorkbookOptions, Jn as PageSetupOptions, Jt as DataBarAxisPosition, K as SheetViewOptions, Kn as PageOrientation, Kt as ConditionalFormatRuleInput, L as CreateWorkbookOptions, Ln as SheetImage, Lt as TableStyleOptions, M as StandardSchemaV1, Mn as ImageAnchor, Mt as WorkbookView, N as AddSheetOptions, Nn as ImageAnchorInput, Nt as TableColumnInput, O as readTable, On as ChartText, Ot as SheetView, P as CalculationOptions, Pn as ImageFormat, Pt as TableDefinition, Q as InspectDefinedName, Qn as PrintTitles, Qt as DataValidationImeMode, R as ERROR_VALUES, Rn as WorkbookImage, Rt as TotalsRowFunction, S as TableResult, Sn as ChartAxisInput, Sr as XlvWarningCode, St as RowInfo, T as ToJSONOptions, Tn as ChartLegendPosition, Tr as ReadLimits, Tt as SheetLayout, U as NewWorkbook, Un as PageBreaks, Ut as ConditionalFormat, V as FreezeOptions, Vn as HyperlinkTarget, Vt as CfValueInput, W as RowOptions, Wn as PageMargins, Wt as ConditionalFormatOperator, X as writeWorkbook, Xn as PrintErrors, Xt as DataValidation, Y as createWorkbook, Yn as PrintCellComments, Yt as DataBarDirection, Z as InspectColumn, Zn as PrintOptions, Zt as DataValidationErrorStyle, _ as JsonTable, _n as ReadingOrder, _r as XlvErrorCode, _t as DateSystem, a as WriteWorkbookStreamOptions, an as BorderEdge, ar as PasswordHash, at as ReadOptions, b as TableColumnSpec, bn as VerticalAlignment, br as XlvLocation, bt as FrozenPanes, c as OpenWorkbookStreamOptions, cn as CellStyle, cr as legacyPasswordHash, ct as NoteBox, d as StreamRow, dn as FontScheme, dr as WorkbookProperties, dt as NoteMargins, en as DataValidationRule, er as SheetProtectionFlags, et as InspectReport, f as StreamSheetInfo, fn as FontStyle, fr as ERROR_CODES, ft as Cell, g as readTableStream, gn as ProtectionStyle, gr as XlvError, gt as Conformance, h as openWorkbookStream, hn as PatternType, hr as XlvDetails, ht as ColumnInfo, i as WriteTableStreamOptions, in as AlignmentStyle, ir as HashPasswordOptions, it as inspect, j as writeTable, jn as AnchorMarker, jt as WorkbookFormat, k as readTableAsync, kn as ChartType, kt as SplitPanes, l as ReadTableStreamOptions, ln as Color, lr as verifyPassword, lt as NoteBoxInput, m as WorkbookStream, mn as HorizontalAlignment, mr as XlvDetailValue, mt as CellValue, n as StreamRowInput, nn as IconSetType, nr as WorkbookProtection, nt as InspectTypeCounts, o as writeTableStream, on as BorderLineStyle, or as PasswordVerifier, ot as readWorkbook, p as TableStreamItem, pn as GradientFill, pr as WARNING_CODES, pt as CellType, q as WorkbookViewOptions, qn as PageSetup, qt as ConditionalFormatType, r as StreamSheetSpec, rn as TimePeriod, rr as WorkbookProtectionOptions, rt as InspectValue, s as writeWorkbookStream, sn as BorderStyle, sr as hashPassword, st as Note, t as StreamDefinedName, tn as DataValidationType, tr as SheetProtectionOptions, tt as InspectSheet, u as STREAM_LIMIT_DEFAULTS, un as FillStyle, ur as ShaAlgorithm, ut as NoteInput, v as ReadTableOptions, vn as UnderlineStyle, vr as XlvErrorInit, vt as Formula, w as TableValue, wn as ChartKind, wr as DEFAULT_READ_LIMITS, wt as SheetKind, x as TableIssue, xn as ChartAxis, xr as XlvWarning, xt as RichTextRun, y as TableColumn, yn as VerticalAlignRun, yr as XlvErrorJSON, yt as FormulaKind, z as ErrorValue, zn as imageFormat, zt as CfIcon } from "./stream-write-XnCyLdOy.js";
2
2
  /**
3
3
  * Options for {@link toCSV}.
4
4
  *
@@ -26,7 +26,8 @@ interface ToCSVOptions {
26
26
  readonly bom?: boolean;
27
27
  /**
28
28
  * `"escape"` (default): text cells that start with `=`, `+`, `-`, `@`, their full-width or small
29
- * forms, or a control character (tab, CR, LF, NUL, …) get a leading `'` and quotes, so
29
+ * forms, a control character (tab, CR, LF, NUL, …) or a byte order mark (U+FEFF, U+FFFE, which
30
+ * spreadsheet applications drop at the start of a file) get a leading `'` and quotes, so
30
31
  * spreadsheet applications show them as text instead of running them as formulas (OWASP CSV
31
32
  * Injection). `"off"`: write them as is.
32
33
  */
@@ -37,8 +38,9 @@ interface ToCSVOptions {
37
38
  readonly onWarning?: (warning: XlvWarning) => void;
38
39
  }
39
40
  /**
40
- * Converts a sheet to CSV text. Fields that contain the delimiter, a quote, CR or LF are
41
- * enclosed in quotes, and quotes are doubled (RFC 4180). Numbers are written in JavaScript's
41
+ * Converts a sheet to CSV text. Fields that contain the delimiter, a quote, CR, LF, or one of
42
+ * the common separators `,`, `;`, tab and `|` (whatever the delimiter, CSV-14) are enclosed in
43
+ * quotes, and quotes are doubled (RFC 4180). Numbers are written in JavaScript's
42
44
  * shortest form, booleans as `TRUE`/`FALSE`, dates as ISO 8601, error cells as their code and
43
45
  * formula cells as their cached value. By default, text that a spreadsheet would run as a
44
46
  * formula is escaped (`formulaInjection: "escape"`).
@@ -270,7 +272,12 @@ interface CellEdit {
270
272
  * ```
271
273
  */
272
274
  interface EditOptions {
273
- /** Read limits for the input file; see `ReadLimits`. */
275
+ /**
276
+ * Read limits for the input file; see `ReadLimits`. For `editCells` and `appendRows`,
277
+ * `maxCells` also bounds the edit: the cells of the edited sheets plus the new cells must not
278
+ * exceed it, and one call writes at most 1 000 000 cells unless `maxCells` is given, in which
279
+ * case it writes at most `maxCells` (`XLV_E_LIMIT_EXCEEDED`, `details.limit` `"maxCells"`).
280
+ */
274
281
  readonly limits?: Partial<ReadLimits>;
275
282
  }
276
283
  /**
@@ -333,10 +340,14 @@ export declare function editCells(input: Uint8Array | ArrayBuffer, edits: readon
333
340
  * Appends rows below the last used row of a sheet (the rows of merged ranges count as used) in
334
341
  * an existing XLSX file, editing the file surgically like {@link editCells}. Object rows are
335
342
  * placed under the matching header columns (unknown keys throw `XLV_E_INVALID_ROWS` with
336
- * suggestions); array rows start at the first used column. A table whose last row is the sheet's last used row grows to include the new
337
- * rows (its range and filter); if that table has a totals row the call is refused with
343
+ * suggestions). Array rows start at the first used column, or, when the new rows extend a table
344
+ * (one that reaches the last used row), at that table's first column; when several such tables
345
+ * start in different columns the call is refused with `XLV_E_INVALID_ARGUMENT` (pass object rows
346
+ * instead). A table whose last row is the sheet's last used row grows to include the new rows
347
+ * (its range and filter); if that table has a totals row the call is refused with
338
348
  * `XLV_E_NOT_SUPPORTED` and a hint to insert the rows above the totals row with `insertRows`.
339
- * Calculated columns are not filled in the new rows.
349
+ * Calculated columns are not filled in the new rows. One call writes at most 1 000 000 cells
350
+ * unless `limits.maxCells` is given (see `EditOptions`).
340
351
  *
341
352
  * @example
342
353
  * ```ts
@@ -347,6 +358,9 @@ export declare function editCells(input: Uint8Array | ArrayBuffer, edits: readon
347
358
  * { Customer: 'Alice', Total: 120.5 },
348
359
  * { Customer: 'Bob', Total: 80 },
349
360
  * ]);
361
+ * // Array rows that extend a table start at the table's first column.
362
+ * const { bytes: more } = appendRows(updated, 'Orders', [['Carol', 64]]);
363
+ * console.log(more.length);
350
364
  * ```
351
365
  */
352
366
  export declare function appendRows(input: Uint8Array | ArrayBuffer, sheet: string, rows: readonly (readonly CellInput[])[] | readonly Readonly<Record<string, CellInput>>[], options?: AppendRowsOptions): EditResult;
@@ -371,6 +385,8 @@ interface InsertRowsOptions extends EditOptions {
371
385
  /**
372
386
  * Formatting of the new rows: `'above'` copies the row format, height and cell formats of the row
373
387
  * above, `'below'` those of the row that is pushed down, `'none'` (default) leaves them empty.
388
+ * The copied cell formats are cells that count against `limits.maxCells` with the cells of the
389
+ * workbook (`XLV_E_LIMIT_EXCEEDED` above it).
374
390
  */
375
391
  readonly style?: "above" | "below" | "none";
376
392
  }
@@ -407,7 +423,9 @@ interface DeleteRowsOptions extends EditOptions {
407
423
  * custom sheet views, other extended content that refers to cells (sparklines, slicers) and
408
424
  * other related parts xlvane does not know; charts or pivot tables anywhere in the workbook that
409
425
  * may refer to the sheet; data tables; an array formula the change would split; and formulas it
410
- * cannot rewrite safely (docs/facts/ref-adjust.md).
426
+ * cannot rewrite safely (docs/facts/ref-adjust.md). Rows formatted with `style` add a formatted
427
+ * cell for each formatted cell of the row they copy; when the workbook would then hold more cells
428
+ * than `limits.maxCells`, the call throws `XLV_E_LIMIT_EXCEEDED` before building them.
411
429
  *
412
430
  * @example
413
431
  * ```ts
@@ -521,4 +539,4 @@ export declare function adjustRange(sqref: string, change: ReferenceChange): str
521
539
  * ```
522
540
  */
523
541
  export declare function shiftFormula(text: string, dRow: number, dCol: number): string | null;
524
- export { type AddSheetOptions, type AlignmentStyle, type AnchorMarker, type AppendRowsOptions, type BorderEdge, type BorderLineStyle, type BorderStyle, type CalculationOptions, type Cell, type CellChange, type CellEdit, type CellInput, type CellStyle, type CellType, type CellValue, type CfIcon, type CfValue, type CfValueInput, type CfValueType, type Color, type ColumnInfo, type ColumnOptions, type ConditionalFormat, type ConditionalFormatOperator, type ConditionalFormatRule, type ConditionalFormatRuleInput, type ConditionalFormatType, type Conformance, type CreateWorkbookOptions, DEFAULT_READ_LIMITS, type DataBarAxisPosition, type DataBarDirection, type DataValidation, type DataValidationErrorStyle, type DataValidationImeMode, type DataValidationOperator, type DataValidationRule, type DataValidationType, type DateSystem, type DefinedName, type DefinedNameOptions, type DeleteRowsOptions, type DiffCell, type DiffOptions, ERROR_CODES, ERROR_VALUES, type EditOptions, type EditResult, type ErrorValue, type FillStyle, type FontScheme, type FontStyle, type Formula, type FormulaKind, type FormulaResult, type FreezeOptions, type FromCSVOptions, type FrozenPanes, type GradientFill, type HashPasswordOptions, type HeaderFooter, type HorizontalAlignment, type Hyperlink, type HyperlinkTarget, type IconSetType, type ImageAnchor, type ImageAnchorInput, type ImageFormat, type ImageOptions, type ImagePositionInput, type InsertRowsOptions, type InspectColumn, type InspectDefinedName, type InspectOptions, type InspectReport, type InspectSheet, type InspectTypeCounts, type InspectValue, type JsonTable, NewSheet, NewWorkbook, type Note, type NoteBox, type NoteBoxInput, type NoteInput, type NoteMargins, type OpenWorkbookStreamOptions, type PageBreaks, type PageMargins, type PageOrder, type PageOrientation, type PageSetup, type PageSetupOptions, type PasswordHash, type PasswordVerifier, type PatternType, type PrintCellComments, type PrintErrors, type PrintOptions, type PrintTitles, type ProtectionStyle, type ReadLimits, type ReadOptions, type ReadTableOptions, type ReadTableStreamOptions, type ReadingOrder, type ReferenceChange, type RichTextRun, type RowInfo, type RowOptions, STREAM_LIMIT_DEFAULTS, type ShaAlgorithm, type Sheet, type SheetDiff, type SheetImage, type SheetKind, type SheetLayout, type SheetProperties, type SheetPropertiesOptions, type SheetProtection, type SheetProtectionFlags, type SheetProtectionOptions, type SheetState, type SheetView, type SheetViewOptions, type SplitPanes, type StandardSchemaV1, type StreamDefinedName, type StreamRow, type StreamRowInput, type StreamSheetInfo, type StreamSheetSpec, type TableColumn, type TableColumnInput, type TableColumnSpec, type TableDefinition, type TableDefinitionColumn, type TableInput, type TableIssue, type TableResult, type TableRow, type TableStreamItem, type TableStyleOptions, type TableValue, type TimePeriod, type ToCSVOptions, type ToJSONOptions, type TotalsRowFunction, type UnderlineStyle, type VerticalAlignRun, type VerticalAlignment, WARNING_CODES, type Workbook, type WorkbookDiff, type WorkbookFormat, type WorkbookImage, type WorkbookProperties, type WorkbookProtection, type WorkbookProtectionOptions, type WorkbookStream, type WorkbookView, type WorkbookViewOptions, type WriteTableOptions, type WriteTableStreamOptions, type WriteWorkbookOptions, type WriteWorkbookStreamOptions, type XlvDetailValue, type XlvDetails, XlvError, type XlvErrorCode, type XlvErrorInit, type XlvErrorJSON, type XlvLocation, type XlvWarning, type XlvWarningCode, createWorkbook, fromJSON, hashPassword, imageFormat, inspect, isXlvError, legacyPasswordHash, openWorkbookStream, readTable, readTableAsync, readTableStream, readWorkbook, toJSON, verifyPassword, writeTable, writeTableStream, writeWorkbook, writeWorkbookStream };
542
+ export { type AddSheetOptions, type AlignmentStyle, type AnchorMarker, type AppendRowsOptions, type BorderEdge, type BorderLineStyle, type BorderStyle, type CalculationOptions, type Cell, type CellChange, type CellEdit, type CellInput, type CellStyle, type CellType, type CellValue, type CfIcon, type CfValue, type CfValueInput, type CfValueType, type ChartAxis, type ChartAxisInput, type ChartInput, type ChartKind, type ChartLegendPosition, type ChartSeries, type ChartSeriesInput, type ChartText, type ChartType, type Color, type ColumnInfo, type ColumnOptions, type ConditionalFormat, type ConditionalFormatOperator, type ConditionalFormatRule, type ConditionalFormatRuleInput, type ConditionalFormatType, type Conformance, type CreateWorkbookOptions, DEFAULT_READ_LIMITS, type DataBarAxisPosition, type DataBarDirection, type DataValidation, type DataValidationErrorStyle, type DataValidationImeMode, type DataValidationOperator, type DataValidationRule, type DataValidationType, type DateSystem, type DefinedName, type DefinedNameOptions, type DeleteRowsOptions, type DiffCell, type DiffOptions, ERROR_CODES, ERROR_VALUES, type EditOptions, type EditResult, type ErrorValue, type FillStyle, type FontScheme, type FontStyle, type Formula, type FormulaKind, type FormulaResult, type FreezeOptions, type FromCSVOptions, type FrozenPanes, type GradientFill, type HashPasswordOptions, type HeaderFooter, type HorizontalAlignment, type Hyperlink, type HyperlinkTarget, type IconSetType, type ImageAnchor, type ImageAnchorInput, type ImageFormat, type ImageOptions, type ImagePositionInput, type InsertRowsOptions, type InspectColumn, type InspectDefinedName, type InspectOptions, type InspectReport, type InspectSheet, type InspectTypeCounts, type InspectValue, type JsonTable, NewSheet, NewWorkbook, type Note, type NoteBox, type NoteBoxInput, type NoteInput, type NoteMargins, type OpenWorkbookStreamOptions, type PageBreaks, type PageMargins, type PageOrder, type PageOrientation, type PageSetup, type PageSetupOptions, type PasswordHash, type PasswordVerifier, type PatternType, type PrintCellComments, type PrintErrors, type PrintOptions, type PrintTitles, type ProtectionStyle, type ReadLimits, type ReadOptions, type ReadTableOptions, type ReadTableStreamOptions, type ReadingOrder, type ReferenceChange, type RichTextRun, type RowInfo, type RowOptions, STREAM_LIMIT_DEFAULTS, type ShaAlgorithm, type Sheet, type SheetChart, type SheetDiff, type SheetImage, type SheetKind, type SheetLayout, type SheetProperties, type SheetPropertiesOptions, type SheetProtection, type SheetProtectionFlags, type SheetProtectionOptions, type SheetState, type SheetView, type SheetViewOptions, type SplitPanes, type StandardSchemaV1, type StreamDefinedName, type StreamRow, type StreamRowInput, type StreamSheetInfo, type StreamSheetSpec, type TableColumn, type TableColumnInput, type TableColumnSpec, type TableDefinition, type TableDefinitionColumn, type TableInput, type TableIssue, type TableResult, type TableRow, type TableStreamItem, type TableStyleOptions, type TableValue, type TimePeriod, type ToCSVOptions, type ToJSONOptions, type TotalsRowFunction, type UnderlineStyle, type VerticalAlignRun, type VerticalAlignment, WARNING_CODES, type Workbook, type WorkbookDiff, type WorkbookFormat, type WorkbookImage, type WorkbookProperties, type WorkbookProtection, type WorkbookProtectionOptions, type WorkbookStream, type WorkbookView, type WorkbookViewOptions, type WriteTableOptions, type WriteTableStreamOptions, type WriteWorkbookOptions, type WriteWorkbookStreamOptions, type XlvDetailValue, type XlvDetails, XlvError, type XlvErrorCode, type XlvErrorInit, type XlvErrorJSON, type XlvLocation, type XlvWarning, type XlvWarningCode, createWorkbook, fromJSON, hashPassword, imageFormat, inspect, isXlvError, legacyPasswordHash, openWorkbookStream, readTable, readTableAsync, readTableStream, readWorkbook, toJSON, verifyPassword, writeTable, writeTableStream, writeWorkbook, writeWorkbookStream };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { An as WARNING_CODES, Jt as legacyPasswordHash, Mn as isXlvError, Yt as verifyPassword, b as readWorkbook, c as NewSheet, en as imageFormat, f as createWorkbook, g as inspect, jn as XlvError, kn as ERROR_CODES, l as NewWorkbook, m as writeWorkbook, qt as hashPassword, s as ERROR_VALUES, z as shiftFormula, zt as DEFAULT_READ_LIMITS } from "./options-Cw7OraxE.js";
2
- import { a as appendRows, c as fromCSV, d as fromJSON, g as writeTable, h as toJSON, i as adjustRange, m as readTableAsync, n as insertRows, o as editCells, p as readTable, r as adjustFormula, s as diff, t as deleteRows, u as toCSV } from "./rows-DnlfBgme.js";
3
- import { a as readTableStream, i as openWorkbookStream, n as writeWorkbookStream, r as STREAM_LIMIT_DEFAULTS, t as writeTableStream } from "./stream-write-DWD8Pflj.js";
1
+ import { Bn as isXlvError, Gt as hashPassword, Kt as legacyPasswordHash, Ln as ERROR_CODES, Lt as DEFAULT_READ_LIMITS, Qt as imageFormat, Rn as WARNING_CODES, _ as inspect, c as NewSheet, dn as shiftFormula, f as createWorkbook, l as NewWorkbook, m as writeWorkbook, qt as verifyPassword, s as ERROR_VALUES, x as readWorkbook, zn as XlvError } from "./options-Cxt-LJE4.js";
2
+ import { a as appendRows, c as fromCSV, d as fromJSON, g as writeTable, h as toJSON, i as adjustRange, m as readTableAsync, n as insertRows, o as editCells, p as readTable, r as adjustFormula, s as diff, t as deleteRows, u as toCSV } from "./rows-DltZ-hiW.js";
3
+ import { a as readTableStream, i as openWorkbookStream, n as writeWorkbookStream, r as STREAM_LIMIT_DEFAULTS, t as writeTableStream } from "./stream-write-D573ewpr.js";
4
4
  export { DEFAULT_READ_LIMITS, ERROR_CODES, ERROR_VALUES, NewSheet, NewWorkbook, STREAM_LIMIT_DEFAULTS, WARNING_CODES, XlvError, adjustFormula, adjustRange, appendRows, createWorkbook, deleteRows, diff, editCells, fromCSV, fromJSON, hashPassword, imageFormat, insertRows, inspect, isXlvError, legacyPasswordHash, openWorkbookStream, readTable, readTableAsync, readTableStream, readWorkbook, shiftFormula, toCSV, toJSON, verifyPassword, writeTable, writeTableStream, writeWorkbook, writeWorkbookStream };
@@ -1,4 +1,4 @@
1
- import { Ht as resolveLimits, jn as XlvError } from "./options-Cw7OraxE.js";
1
+ import { Bt as resolveLimits, zn as XlvError } from "./options-Cxt-LJE4.js";
2
2
  import { readFile, stat } from "node:fs/promises";
3
3
  // src/util/node-files.ts
4
4
  /** The path as shown in messages. */
@@ -12,7 +12,7 @@ async function checkFile(path, limits) {
12
12
  const info = await stat(path);
13
13
  if (!info.isFile()) throw new XlvError("XLV_E_FILE_READ", `"${shown}" is not a file.`, {
14
14
  location: {},
15
- hint: "Pass the path of an .xlsx file, not a directory.",
15
+ hint: info.isDirectory() ? "Pass the path of an .xlsx file, not a directory." : "Pass the path of an .xlsx file, not a pipe, device or other special file.",
16
16
  details: { path: shown }
17
17
  });
18
18
  size = info.size;
package/dist/node.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as InspectOptions, At as Workbook, J as WriteWorkbookOptions, U as NewWorkbook, a as WriteWorkbookStreamOptions, at as ReadOptions, c as OpenWorkbookStreamOptions, et as InspectReport, m as WorkbookStream } from "./stream-write-y52KUDW8.js";
1
+ import { $ as InspectOptions, At as Workbook, J as WriteWorkbookOptions, U as NewWorkbook, a as WriteWorkbookStreamOptions, at as ReadOptions, c as OpenWorkbookStreamOptions, et as InspectReport, m as WorkbookStream } from "./stream-write-XnCyLdOy.js";
2
2
  /**
3
3
  * Reads an XLSX file from disk. Node.js only; in other runtimes pass the bytes to
4
4
  * `readWorkbook` from `xlvane`. The file size is checked against `limits.maxInputBytes`
package/dist/node.js CHANGED
@@ -1,6 +1,6 @@
1
- import { Ht as resolveLimits, b as readWorkbook, g as inspect, jn as XlvError, m as writeWorkbook } from "./options-Cw7OraxE.js";
2
- import { i as readInput, n as describePath, r as fileError, t as checkFile } from "./node-files-Bxzv7THG.js";
3
- import { i as openWorkbookStream, n as writeWorkbookStream, r as STREAM_LIMIT_DEFAULTS } from "./stream-write-DWD8Pflj.js";
1
+ import { Bt as resolveLimits, _ as inspect, m as writeWorkbook, x as readWorkbook, zn as XlvError } from "./options-Cxt-LJE4.js";
2
+ import { i as readInput, n as describePath, r as fileError, t as checkFile } from "./node-files-SVg17pky.js";
3
+ import { i as openWorkbookStream, n as writeWorkbookStream, r as STREAM_LIMIT_DEFAULTS } from "./stream-write-D573ewpr.js";
4
4
  import { openAsBlob } from "node:fs";
5
5
  import { open, unlink, writeFile } from "node:fs/promises";
6
6
  // src/node.ts