xlvane 1.0.1 → 1.1.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
@@ -105,7 +105,7 @@ In Node.js, `writeWorkbookFile(workbook, 'sales.xlsx')` from `xlvane/node` write
105
105
  - Values: numbers, strings, booleans, `Date`s (stored as serial numbers with a `yyyy-mm-dd` or `yyyy-mm-dd hh:mm:ss` format unless the style sets one), `{ error: '#N/A' }`, and `{ formula, result }`, also as an array formula (`{ formula, array: 'A1:A3' }`) or a shared formula (`{ formula, shared: 'B1:B9' }` on the first cell, `{ sharedFormula: 'B1' }` on the others). xlvane writes the formula text and the cached result you give; it does not calculate formulas.
106
106
  - Styles: font (name, size, bold, italic, underline, strike, colour, superscript and subscript, family, scheme, charset, outline, shadow), fill (solid colour, pattern, or linear and path gradient), borders (top, right, bottom, left, diagonal), alignment (horizontal, vertical, wrap, shrink to fit, indent, rotation, reading order), cell protection (`locked`, `hidden`) and number format. Identical styles are stored once. `sheet.style(range, style)` merges a style into every cell of a range.
107
107
  - Layout: column widths and hidden columns, row heights and hidden rows, outline levels of rows and columns (`row(n, { outlineLevel: 1, collapsed })`, `column('B', { outlineLevel: 1 })`), merged ranges, frozen rows and columns, autofilter, hidden and very hidden sheets. `sheet.properties({ defaultRowHeight, outlineLevelRow, outlineLevelCol, summaryBelow, summaryRight })` sets the sheet's format properties.
108
- - Workbook: `workbook.views([{ x, y, width, height, firstSheet, activeTab, visibility }])` sets the workbook windows and `workbook.calculation({ fullCalcOnLoad: true })` asks applications to recalculate when the file is opened.
108
+ - Workbook: `workbook.views([{ x, y, width, height, firstSheet, activeTab, visibility }])` sets the workbook windows (`activeTab` and `firstSheet` are checked against the sheets when the workbook is written) and `workbook.calculation({ fullCalcOnLoad: true })` asks applications to recalculate when the file is opened. `addSheet(name, { sheetId })` sets the sheet's id in the file (1 to 65534, unique; other sheets get the lowest unused ids), and reading gives `sheet.sheetId`.
109
109
  - Writer options: `writeWorkbook(workbook, { sharedStrings: false })` writes text inline instead of in a shared string table; `{ compressionLevel: 0 }` (0–9, default 6) stores or compresses the parts. The same options work for `writeWorkbookFile` and, with `compressionLevel`, `writeWorkbookStream`.
110
110
  - Invalid input is rejected when it is set, with an `XlvError` saying what and where, for example `XLV_E_INVALID_SHEET_NAME` or `XLV_E_INVALID_STYLE` with the allowed values.
111
111
  - The output is deterministic: the same workbook always gives the same bytes. The exception is a protection password (`protect({ password })`), whose verifier gets a random salt; pass a fixed salt through `hashPassword` for identical bytes. The test suite opens written files that use all of these features in LibreOffice and checks the values, styles and layout it sees.
@@ -151,7 +151,7 @@ console.log(read.hyperlinks, read.notes, read.cell('B2')?.note?.text, read.tabCo
151
151
 
152
152
  - **Hyperlinks:** `link(range, { url | location, tooltip?, display? })`. A `url` (web page, `mailto:`, file) is stored as an external relationship of the sheet; a `location` (a place in the workbook) is stored without one. The cell text is set with `set`. Reading gives `sheet.hyperlinks` and `cell.hyperlink`; xlvane never opens a target, and `XLV_W_UNUSUAL_HYPERLINK` reports targets other than http(s) or mailto.
153
153
  - **Notes (comments):** `note(cell, text | { text | runs, author?, box? })`; `box` sets the note box: `margins` in millimetres, `autoMargins`, `locked`, `lockText`, `anchor` (`'absolute'`, `'oneCell'`, `'twoCell'`); reading gives the same as `note.box`. The cell needs no value. Notes are written hidden, as spreadsheet applications show them when the pointer rests on the cell. Reading gives `sheet.notes` and `cell.note` (`text`, `author`, and `runs` for rich text). Threaded comments of current Excel versions are not read; their placeholder notes are, with `XLV_W_THREADED_COMMENTS`.
154
- - **Tab colour and view:** `tabColor(color)`, and `view({ zoom, zoomScaleNormal, showGridLines, showRowColHeaders, showRuler, rightToLeft, layout, split, topLeftCell, activeCell })`. Reading gives `sheet.tabColor`, `sheet.view`, `sheet.properties`, `workbook.views` and `workbook.calculation`.
154
+ - **Tab colour and view:** `tabColor(color)`, and `view({ zoom, zoomScaleNormal, showGridLines, showRowColHeaders, showRuler, rightToLeft, layout, split, topLeftCell, activeCell })`; a split window takes `split: { x, y, topLeftCell }` in points, where `topLeftCell` is the first cell shown in the bottom-right pane. Reading gives `sheet.tabColor`, `sheet.view`, `sheet.properties`, `workbook.views` and `workbook.calculation`.
155
155
  - **Streaming:** `writeWorkbookStream` takes `hyperlinks` and `notes` per row (`{ values, hyperlinks: [...], notes: [...] }`, by column position) and `tabColor`/`view` per sheet. `openWorkbookStream` sets `cell.note` on the rows it returns and lists a sheet's notes with `notes(sheet)`; it does not set `cell.hyperlink`.
156
156
  - `editCells` and `appendRows` keep existing links and notes but cannot add new ones yet.
157
157
 
@@ -293,10 +293,10 @@ const { bytes: shorter } = deleteRows(wider, { sheet: 'Orders', at: 10, count: 3
293
293
  ```
294
294
 
295
295
  - Like `editCells`, they change an existing file in place and keep every other part as it was.
296
- - References follow the rows as in a spreadsheet application: formulas on every sheet, merged cells, hyperlinks, notes, the autofilter, conditional formats, data validation, page breaks and defined names. A range grows when rows are inserted inside it and shrinks when some of its rows are deleted; a reference whose cells are all deleted becomes `#REF!`. The rules are in docs/facts/ref-adjust.md (observed in LibreOffice; not yet checked against Excel).
296
+ - References follow the rows as in a spreadsheet application: formulas on every sheet, merged cells, hyperlinks, notes, the autofilter, conditional formats (with their thresholds), data validation, page breaks and defined names. A range grows when rows are inserted inside it and shrinks when some of its rows are deleted; a reference whose cells are all deleted becomes `#REF!`. The rules are in docs/facts/ref-adjust.md (observed in LibreOffice; not yet checked against Excel).
297
297
  - Tables move, grow and shrink with their rows; deleting a table's header row, totals row or all of its data rows is refused.
298
298
  - Pictures move with their rows. Drawings with charts, shapes or form controls, a deletion that would cut a picture, parts xlvane cannot rewrite (charts or pivot tables that may refer to the sheet), and formulas xlvane cannot rewrite safely (for example 3-D references such as `Jan:Mar!A1` that include the sheet) are refused with `XLV_E_NOT_SUPPORTED`. Data that would be pushed past row 1048576 gives `XLV_E_LIMIT_EXCEEDED`.
299
- - They also refuse sheets whose conditional formats use the [MS-XLSX] extension, which xlvane writes for data bars with an extension setting (`gradient`, `borderColor`, `negativeFillColor`, `negativeBorderColor`, `axisPosition`, `axisColor`, `direction`, or an `autoMin`/`autoMax` threshold) and for the icon sets `3Stars`, `3Triangles`, `5Boxes` and `NoIcons`; insert the rows before adding such rules, or add the rules again after the change.
299
+ - Conditional formats and data validations of the [MS-XLSX] extension (extended data bars, the icon sets `3Stars`, `3Triangles`, `5Boxes` and `NoIcons`, and rules written by Excel) move with the rows too, and so do thresholds that refer to cells (`{ type: 'formula', value: '$C$12' }`). Other extended content that refers to cells, such as sparklines or slicers, is refused.
300
300
  - Sheet views (selection, frozen panes) are not changed.
301
301
  - `adjustFormula` and `adjustRange` apply the same rules to formula text you hold yourself.
302
302
 
package/dist/cli.js CHANGED
@@ -1,12 +1,15 @@
1
1
  #!/usr/bin/env node
2
- import { It as suggest, Sn as XlvError, _ as isoDate, an as parseRange, b as readWorkbook, g as inspect } from "./options-B7UhudO_.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-Cwte1t8m.js";
4
- import { i as readInput } from "./node-files-uazELnqk.js";
2
+ import { Bt as suggest, En as XlvError, _ as isoDate, b as readWorkbook, g as inspect, ln as parseRange } from "./options-CwSp2pA4.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-DKwlr0rg.js";
4
+ import { i as readInput } from "./node-files-B0iqSJIJ.js";
5
5
  import { existsSync, readFileSync } from "node:fs";
6
6
  import { chmod, readFile, readdir, rename, rm, stat, writeFile } from "node:fs/promises";
7
7
  import process from "node:process";
8
- import { parseArgs, styleText } from "node:util";
8
+ import { createRequire } from "node:module";
9
9
  import { basename, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
10
+ // src/cli/node-util.ts
11
+ /** The `node:util` module. */
12
+ const nodeUtil = createRequire(import.meta.url)("node:util");
10
13
  // src/cli/args.ts
11
14
  /** Options every command accepts. */
12
15
  const GLOBAL_OPTIONS = {
@@ -64,7 +67,7 @@ function parseCommandArgs(spec, args) {
64
67
  ...o.short ? { short: o.short } : {},
65
68
  ...o.multiple ? { multiple: true } : {}
66
69
  };
67
- const { tokens } = parseArgs({
70
+ const { tokens } = nodeUtil.parseArgs({
68
71
  args: [...args],
69
72
  options: config,
70
73
  strict: false,
@@ -166,6 +169,259 @@ function headerOption(args, command) {
166
169
  option: "--header"
167
170
  });
168
171
  }
172
+ // src/cli/east-asian-width.ts
173
+ /**
174
+ * Code points whose East_Asian_Width is Wide (W) or Fullwidth (F), including the unassigned code
175
+ * points that default to W, as sorted pairs of first and last code point. Unicode 17.0.0.
176
+ */
177
+ const EAST_ASIAN_WIDE = [
178
+ 4352,
179
+ 4447,
180
+ 8986,
181
+ 8987,
182
+ 9001,
183
+ 9002,
184
+ 9193,
185
+ 9196,
186
+ 9200,
187
+ 9200,
188
+ 9203,
189
+ 9203,
190
+ 9725,
191
+ 9726,
192
+ 9748,
193
+ 9749,
194
+ 9776,
195
+ 9783,
196
+ 9800,
197
+ 9811,
198
+ 9855,
199
+ 9855,
200
+ 9866,
201
+ 9871,
202
+ 9875,
203
+ 9875,
204
+ 9889,
205
+ 9889,
206
+ 9898,
207
+ 9899,
208
+ 9917,
209
+ 9918,
210
+ 9924,
211
+ 9925,
212
+ 9934,
213
+ 9934,
214
+ 9940,
215
+ 9940,
216
+ 9962,
217
+ 9962,
218
+ 9970,
219
+ 9971,
220
+ 9973,
221
+ 9973,
222
+ 9978,
223
+ 9978,
224
+ 9981,
225
+ 9981,
226
+ 9989,
227
+ 9989,
228
+ 9994,
229
+ 9995,
230
+ 10024,
231
+ 10024,
232
+ 10060,
233
+ 10060,
234
+ 10062,
235
+ 10062,
236
+ 10067,
237
+ 10069,
238
+ 10071,
239
+ 10071,
240
+ 10133,
241
+ 10135,
242
+ 10160,
243
+ 10160,
244
+ 10175,
245
+ 10175,
246
+ 11035,
247
+ 11036,
248
+ 11088,
249
+ 11088,
250
+ 11093,
251
+ 11093,
252
+ 11904,
253
+ 11929,
254
+ 11931,
255
+ 12019,
256
+ 12032,
257
+ 12245,
258
+ 12272,
259
+ 12350,
260
+ 12353,
261
+ 12438,
262
+ 12441,
263
+ 12543,
264
+ 12549,
265
+ 12591,
266
+ 12593,
267
+ 12686,
268
+ 12688,
269
+ 12773,
270
+ 12783,
271
+ 12830,
272
+ 12832,
273
+ 12871,
274
+ 12880,
275
+ 42124,
276
+ 42128,
277
+ 42182,
278
+ 43360,
279
+ 43388,
280
+ 44032,
281
+ 55203,
282
+ 63744,
283
+ 64255,
284
+ 65040,
285
+ 65049,
286
+ 65072,
287
+ 65106,
288
+ 65108,
289
+ 65126,
290
+ 65128,
291
+ 65131,
292
+ 65281,
293
+ 65376,
294
+ 65504,
295
+ 65510,
296
+ 94176,
297
+ 94180,
298
+ 94192,
299
+ 94198,
300
+ 94208,
301
+ 101589,
302
+ 101631,
303
+ 101662,
304
+ 101760,
305
+ 101874,
306
+ 110576,
307
+ 110579,
308
+ 110581,
309
+ 110587,
310
+ 110589,
311
+ 110590,
312
+ 110592,
313
+ 110882,
314
+ 110898,
315
+ 110898,
316
+ 110928,
317
+ 110930,
318
+ 110933,
319
+ 110933,
320
+ 110948,
321
+ 110951,
322
+ 110960,
323
+ 111355,
324
+ 119552,
325
+ 119638,
326
+ 119648,
327
+ 119670,
328
+ 126980,
329
+ 126980,
330
+ 127183,
331
+ 127183,
332
+ 127374,
333
+ 127374,
334
+ 127377,
335
+ 127386,
336
+ 127488,
337
+ 127490,
338
+ 127504,
339
+ 127547,
340
+ 127552,
341
+ 127560,
342
+ 127568,
343
+ 127569,
344
+ 127584,
345
+ 127589,
346
+ 127744,
347
+ 127776,
348
+ 127789,
349
+ 127797,
350
+ 127799,
351
+ 127868,
352
+ 127870,
353
+ 127891,
354
+ 127904,
355
+ 127946,
356
+ 127951,
357
+ 127955,
358
+ 127968,
359
+ 127984,
360
+ 127988,
361
+ 127988,
362
+ 127992,
363
+ 128062,
364
+ 128064,
365
+ 128064,
366
+ 128066,
367
+ 128252,
368
+ 128255,
369
+ 128317,
370
+ 128331,
371
+ 128334,
372
+ 128336,
373
+ 128359,
374
+ 128378,
375
+ 128378,
376
+ 128405,
377
+ 128406,
378
+ 128420,
379
+ 128420,
380
+ 128507,
381
+ 128591,
382
+ 128640,
383
+ 128709,
384
+ 128716,
385
+ 128716,
386
+ 128720,
387
+ 128722,
388
+ 128725,
389
+ 128728,
390
+ 128732,
391
+ 128735,
392
+ 128747,
393
+ 128748,
394
+ 128756,
395
+ 128764,
396
+ 128992,
397
+ 129003,
398
+ 129008,
399
+ 129008,
400
+ 129292,
401
+ 129338,
402
+ 129340,
403
+ 129349,
404
+ 129351,
405
+ 129535,
406
+ 129648,
407
+ 129660,
408
+ 129664,
409
+ 129674,
410
+ 129678,
411
+ 129734,
412
+ 129736,
413
+ 129736,
414
+ 129741,
415
+ 129756,
416
+ 129759,
417
+ 129770,
418
+ 129775,
419
+ 129784,
420
+ 131072,
421
+ 196605,
422
+ 196608,
423
+ 262141
424
+ ];
169
425
  // src/cli/output.ts
170
426
  /**
171
427
  * Whether to colour a stream. `util.styleText` respects NO_COLOR, NODE_DISABLE_COLORS,
@@ -208,7 +464,7 @@ var Output = class {
208
464
  this.width = width;
209
465
  }
210
466
  style(format, text) {
211
- return this.color && text !== "" ? styleText(format, text, { validateStream: false }) : text;
467
+ return this.color && text !== "" ? nodeUtil.styleText(format, text, { validateStream: false }) : text;
212
468
  }
213
469
  bold(text) {
214
470
  return this.style("bold", text);
@@ -230,11 +486,11 @@ var Output = class {
230
486
  }
231
487
  /**
232
488
  * An aligned table. Columns are cut with "…" to fit `width`; the widest columns shrink first.
233
- * Width is counted in UTF-16 code units, so wide characters may misalign (documented).
489
+ * Widths are display columns ({@link displayWidth}), so CJK text and emoji stay aligned.
234
490
  */
235
491
  table(headers, rows, indent = "", align = []) {
236
492
  const count = headers.length;
237
- const widths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => oneLine(r[i] ?? "").length)));
493
+ const widths = headers.map((h, i) => Math.max(displayWidth(oneLine(h)), ...rows.map((r) => displayWidth(oneLine(r[i] ?? "")))));
238
494
  const gap = 2;
239
495
  const available = Math.max(count * 4, this.width - indent.length - gap * (count - 1));
240
496
  let total = widths.reduce((a, b) => a + b, 0);
@@ -248,7 +504,8 @@ var Output = class {
248
504
  const line = (cells, head) => indent + cells.map((c, i) => {
249
505
  const w = widths[i] ?? 0;
250
506
  const text = fit(oneLine(c), w);
251
- const padded = align[i] === "right" && !head ? text.padStart(w) : i === count - 1 ? text : text.padEnd(w);
507
+ const pad = " ".repeat(Math.max(0, w - displayWidth(text)));
508
+ const padded = align[i] === "right" && !head ? pad + text : i === count - 1 ? text : text + pad;
252
509
  return head ? this.bold(padded) : padded;
253
510
  }).join(" ".repeat(gap)).trimEnd();
254
511
  return [line(headers, true), ...rows.map((r) => line(r, false))].join("\n");
@@ -300,8 +557,70 @@ function terminalSafe(text, keepStyles) {
300
557
  }
301
558
  return start === 0 ? text : result + text.slice(start);
302
559
  }
560
+ /** Cuts text to `width` display columns with "…", between grapheme clusters. */
303
561
  function fit(text, width) {
304
- return text.length <= width ? text : `${text.slice(0, Math.max(0, width - 1))}…`;
562
+ if (displayWidth(text) <= width) return text;
563
+ let result = "";
564
+ let used = 0;
565
+ for (const part of graphemes(text)) {
566
+ const w = displayWidth(part);
567
+ if (used + w > width - 1) break;
568
+ result += part;
569
+ used += w;
570
+ }
571
+ return `${result}…`;
572
+ }
573
+ /**
574
+ * Grapheme clusters of a text (Intl.Segmenter), or its code points when the Node.js build has no
575
+ * Intl support, so that cutting never splits a surrogate pair or a letter from its accent.
576
+ */
577
+ function graphemes(text) {
578
+ if (segmenter === void 0) return Array.from(text);
579
+ return Array.from(segmenter.segment(text), (s) => s.segment);
580
+ }
581
+ const segmenter = typeof Intl === "object" && typeof Intl.Segmenter === "function" ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : void 0;
582
+ /**
583
+ * The number of terminal columns a text takes, counted as Node.js counts them for its own output
584
+ * (src/node_i18n.cc GetColumnWidth, v22.23.4; F-UNICODE-01): East Asian Wide and Fullwidth
585
+ * characters (Unicode East_Asian_Width W and F) and emoji with Emoji_Presentation take two
586
+ * columns; control and format characters (except the soft hyphen), nonspacing and enclosing marks
587
+ * and emoji modifiers that are not Wide take none; every other character, including East Asian
588
+ * Ambiguous ones, takes one. Each code point of an emoji sequence is counted, as Node.js does by
589
+ * default, so a terminal that draws the sequence as one picture shows it narrower. Colour codes
590
+ * (`ESC [ … m`, as `Output` writes them) take no columns, as Node.js strips them first.
591
+ */
592
+ function displayWidth(text) {
593
+ if (text.includes("\x1B")) text = text.replace(/\u001b\[[0-9;]*m/g, "");
594
+ let width = 0;
595
+ for (let i = 0; i < text.length; i++) {
596
+ const code = text.charCodeAt(i);
597
+ if (code >= 32 && code < 127) width++;
598
+ else {
599
+ for (const ch of text.slice(i)) width += codePointWidth(ch.codePointAt(0) ?? 0, ch);
600
+ break;
601
+ }
602
+ }
603
+ return width;
604
+ }
605
+ function codePointWidth(code, ch) {
606
+ if (isEastAsianWide(code) || EMOJI_PRESENTATION.test(ch)) return 2;
607
+ if (code !== 173 && ZERO_WIDTH.test(ch)) return 0;
608
+ return 1;
609
+ }
610
+ const EMOJI_PRESENTATION = /^\p{Emoji_Presentation}$/u;
611
+ const ZERO_WIDTH = /^[\p{Cc}\p{Cf}\p{Me}\p{Mn}\p{Emoji_Modifier}]$/u;
612
+ /** Binary search in the sorted [first, last, first, last, …] ranges of EAST_ASIAN_WIDE. */
613
+ function isEastAsianWide(code) {
614
+ if (code < 4352) return false;
615
+ let lo = 0;
616
+ let hi = EAST_ASIAN_WIDE.length / 2 - 1;
617
+ while (lo <= hi) {
618
+ const mid = lo + hi >> 1;
619
+ if (code < EAST_ASIAN_WIDE[mid * 2]) hi = mid - 1;
620
+ else if (code > EAST_ASIAN_WIDE[mid * 2 + 1]) lo = mid + 1;
621
+ else return true;
622
+ }
623
+ return false;
305
624
  }
306
625
  /** Quotes an argument for a POSIX shell when needed, so "Try:" commands can be copied. */
307
626
  function quoteArg(arg) {
@@ -333,12 +652,12 @@ function humanSize(bytes) {
333
652
  if (bytes < 1e6) return `${(bytes / 1e3).toFixed(1)} kB`;
334
653
  return `${(bytes / 1e6).toFixed(1)} MB`;
335
654
  }
336
- /** Wraps a paragraph at `width` columns; lines after the first start with `indent`. */
655
+ /** Wraps a paragraph at `width` display columns; lines after the first start with `indent`. */
337
656
  function wrap(text, width, indent = "", firstIndent = indent) {
338
657
  const lines = [];
339
658
  let line = "";
340
659
  let prefix = firstIndent;
341
- for (const word of text.split(/\s+/).filter((w) => w !== "")) if (line !== "" && prefix.length + line.length + 1 + word.length > width) {
660
+ for (const word of text.split(/\s+/).filter((w) => w !== "")) if (line !== "" && displayWidth(prefix) + displayWidth(line) + 1 + displayWidth(word) > width) {
342
661
  lines.push(prefix + line);
343
662
  prefix = indent;
344
663
  line = word;
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-Q-sef804.js";
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-GJXORYQ2.js";
2
2
  /**
3
3
  * Options for {@link toCSV}.
4
4
  *
@@ -392,15 +392,14 @@ interface DeleteRowsOptions extends EditOptions {
392
392
  * Inserts empty rows into a sheet of an existing XLSX file and returns the new file. Rows below
393
393
  * move down, and every reference follows them as in a spreadsheet application: formulas on all
394
394
  * sheets (ranges that the new rows fall into grow), merged cells, hyperlinks, notes, the
395
- * autofilter, conditional formats, data validation, page breaks, defined names, tables (which
396
- * grow when rows are inserted inside them) and pictures placed on the sheet. Every other part of
397
- * the file stays exactly as it was.
395
+ * autofilter, conditional formats (also those of the [MS-XLSX] extension, and thresholds that
396
+ * refer to cells), data validation (also of the extension), page breaks, defined names, tables
397
+ * (which grow when rows are inserted inside them) and pictures placed on the sheet. Every other
398
+ * part of the file stays exactly as it was.
398
399
  *
399
400
  * Refused with `XLV_E_NOT_SUPPORTED`, leaving the file unchanged: a drawing that holds charts,
400
401
  * shapes or anything besides pictures; embedded objects, form controls, scenarios, cell watches,
401
- * custom sheet views, extended content that refers to cells (data bars, sparklines, slicers -
402
- * including the extended data bar settings and the icon sets `3Stars`, `3Triangles`, `5Boxes`, `NoIcons`
403
- * that xlvane itself writes) and
402
+ * custom sheet views, other extended content that refers to cells (sparklines, slicers) and
404
403
  * other related parts xlvane does not know; charts or pivot tables anywhere in the workbook that
405
404
  * may refer to the sheet; data tables; an array formula the change would split; and formulas it
406
405
  * cannot rewrite safely (docs/facts/ref-adjust.md).
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Bt as hashPassword, Cn as isXlvError, Ht as verifyPassword, Pt as DEFAULT_READ_LIMITS, Sn as XlvError, Vt as legacyPasswordHash, b as readWorkbook, bn as ERROR_CODES, c as NewSheet, f as createWorkbook, g as inspect, l as NewWorkbook, m as writeWorkbook, qt as imageFormat, s as ERROR_VALUES, xn as WARNING_CODES, z as shiftFormula } from "./options-B7UhudO_.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-Cwte1t8m.js";
3
- import { a as readTableStream, i as openWorkbookStream, n as writeWorkbookStream, r as STREAM_LIMIT_DEFAULTS, t as writeTableStream } from "./stream-write-CTgWff2P.js";
1
+ import { Dn as isXlvError, En as XlvError, Gt as legacyPasswordHash, Kt as verifyPassword, Rt as DEFAULT_READ_LIMITS, Tn as WARNING_CODES, Wt as hashPassword, Zt as imageFormat, b as readWorkbook, c as NewSheet, f as createWorkbook, g as inspect, l as NewWorkbook, m as writeWorkbook, s as ERROR_VALUES, wn as ERROR_CODES, z as shiftFormula } from "./options-CwSp2pA4.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-DKwlr0rg.js";
3
+ import { a as readTableStream, i as openWorkbookStream, n as writeWorkbookStream, r as STREAM_LIMIT_DEFAULTS, t as writeTableStream } from "./stream-write-BKppyMz0.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 { Ft as resolveLimits, Sn as XlvError } from "./options-B7UhudO_.js";
1
+ import { En as XlvError, zt as resolveLimits } from "./options-CwSp2pA4.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. */
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-Q-sef804.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-GJXORYQ2.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 { Ft as resolveLimits, Sn as XlvError, b as readWorkbook, g as inspect, m as writeWorkbook } from "./options-B7UhudO_.js";
2
- import { i as readInput, n as describePath, r as fileError, t as checkFile } from "./node-files-uazELnqk.js";
3
- import { i as openWorkbookStream, n as writeWorkbookStream, r as STREAM_LIMIT_DEFAULTS } from "./stream-write-CTgWff2P.js";
1
+ import { En as XlvError, b as readWorkbook, g as inspect, m as writeWorkbook, zt as resolveLimits } from "./options-CwSp2pA4.js";
2
+ import { i as readInput, n as describePath, r as fileError, t as checkFile } from "./node-files-B0iqSJIJ.js";
3
+ import { i as openWorkbookStream, n as writeWorkbookStream, r as STREAM_LIMIT_DEFAULTS } from "./stream-write-BKppyMz0.js";
4
4
  import { openAsBlob } from "node:fs";
5
5
  import { open, unlink, writeFile } from "node:fs/promises";
6
6
  // src/node.ts