@cj-tech-master/excelts 4.2.0 → 4.2.1
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/dist/browser/modules/archive/compress.base.d.ts +1 -0
- package/dist/browser/modules/archive/compress.base.js +1 -0
- package/dist/browser/modules/archive/compress.browser.d.ts +8 -0
- package/dist/browser/modules/archive/compress.browser.js +16 -9
- package/dist/browser/modules/archive/parse.base.d.ts +22 -1
- package/dist/browser/modules/archive/parse.base.js +38 -4
- package/dist/browser/modules/archive/parse.browser.js +6 -1
- package/dist/browser/modules/archive/parse.js +1 -1
- package/dist/browser/modules/excel/form-control.d.ts +2 -0
- package/dist/browser/modules/excel/form-control.js +54 -16
- package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +17 -3
- package/dist/browser/modules/stream/streams.browser.d.ts +2 -0
- package/dist/browser/modules/stream/streams.browser.js +58 -25
- package/dist/cjs/modules/archive/compress.base.js +1 -0
- package/dist/cjs/modules/archive/compress.browser.js +15 -8
- package/dist/cjs/modules/archive/parse.base.js +38 -4
- package/dist/cjs/modules/archive/parse.browser.js +6 -1
- package/dist/cjs/modules/archive/parse.js +1 -1
- package/dist/cjs/modules/excel/form-control.js +54 -16
- package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +17 -3
- package/dist/cjs/modules/stream/streams.browser.js +58 -25
- package/dist/esm/modules/archive/compress.base.js +1 -0
- package/dist/esm/modules/archive/compress.browser.js +16 -9
- package/dist/esm/modules/archive/parse.base.js +38 -4
- package/dist/esm/modules/archive/parse.browser.js +6 -1
- package/dist/esm/modules/archive/parse.js +1 -1
- package/dist/esm/modules/excel/form-control.js +54 -16
- package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +17 -3
- package/dist/esm/modules/stream/streams.browser.js +58 -25
- package/dist/iife/THIRD_PARTY_NOTICES.md +112 -0
- package/dist/iife/excelts.iife.js +162 -38
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +19 -19
- package/dist/types/modules/archive/compress.base.d.ts +1 -0
- package/dist/types/modules/archive/compress.browser.d.ts +8 -0
- package/dist/types/modules/archive/parse.base.d.ts +22 -1
- package/dist/types/modules/excel/form-control.d.ts +2 -0
- package/dist/types/modules/stream/streams.browser.d.ts +2 -0
- package/package.json +6 -6
- /package/dist/{LICENSE → iife/LICENSE} +0 -0
|
@@ -290,8 +290,10 @@ class WorkSheetXform extends BaseXform {
|
|
|
290
290
|
for (const control of model.formControls) {
|
|
291
291
|
const globalCtrlPropId = options.formControlRefs.length + 1;
|
|
292
292
|
control.ctrlPropId = globalCtrlPropId;
|
|
293
|
+
const relId = nextRid(rels);
|
|
294
|
+
control.ctrlPropRelId = relId;
|
|
293
295
|
rels.push({
|
|
294
|
-
Id:
|
|
296
|
+
Id: relId,
|
|
295
297
|
Type: RelType.CtrlProp,
|
|
296
298
|
Target: ctrlPropRelTargetFromWorksheet(globalCtrlPropId)
|
|
297
299
|
});
|
|
@@ -354,15 +356,27 @@ class WorkSheetXform extends BaseXform {
|
|
|
354
356
|
this.map.drawing.render(xmlStream, model.drawing); // Note: must be after rowBreaks/colBreaks
|
|
355
357
|
this.map.picture.render(xmlStream, model.background); // Note: must be after drawing
|
|
356
358
|
this.map.tableParts.render(xmlStream, model.tables);
|
|
357
|
-
|
|
359
|
+
// Controls section for legacy form controls (checkboxes, etc.)
|
|
360
|
+
// Excel expects <controls> entries that reference ctrlProp relationships.
|
|
361
|
+
if (model.formControls && model.formControls.length > 0) {
|
|
362
|
+
xmlStream.openNode("controls");
|
|
363
|
+
for (const control of model.formControls) {
|
|
364
|
+
if (control.ctrlPropRelId) {
|
|
365
|
+
xmlStream.leafNode("control", { shapeId: control.shapeId, "r:id": control.ctrlPropRelId });
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
xmlStream.closeNode();
|
|
369
|
+
}
|
|
358
370
|
if (model.rels) {
|
|
359
|
-
//
|
|
371
|
+
// Add a <legacyDrawing /> node for each VML drawing relationship (comments and/or form controls).
|
|
360
372
|
model.rels.forEach(rel => {
|
|
361
373
|
if (rel.Type === RelType.VmlDrawing) {
|
|
362
374
|
xmlStream.leafNode("legacyDrawing", { "r:id": rel.Id });
|
|
363
375
|
}
|
|
364
376
|
});
|
|
365
377
|
}
|
|
378
|
+
// extLst should be the last element in the worksheet.
|
|
379
|
+
this.map.extLst.render(xmlStream, model);
|
|
366
380
|
xmlStream.closeNode();
|
|
367
381
|
}
|
|
368
382
|
parseOpen(node) {
|
|
@@ -384,55 +384,58 @@ export class Readable extends EventEmitter {
|
|
|
384
384
|
// causing `instanceof Transform/Writable/Duplex` to fail even when the object
|
|
385
385
|
// is a valid destination.
|
|
386
386
|
const dest = destination;
|
|
387
|
-
//
|
|
388
|
-
//
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
const
|
|
392
|
-
const
|
|
393
|
-
const
|
|
394
|
-
const
|
|
395
|
-
|
|
387
|
+
// For event handling (drain, once, off), we need the object that emits events.
|
|
388
|
+
// For write/end, we must call the destination's own write()/end() methods,
|
|
389
|
+
// NOT the internal _writable, because Transform.write() has important logic
|
|
390
|
+
// (like auto-consume) that _writable.write() bypasses.
|
|
391
|
+
const eventTarget = dest;
|
|
392
|
+
const hasWrite = typeof dest?.write === "function";
|
|
393
|
+
const hasEnd = typeof dest?.end === "function";
|
|
394
|
+
const hasOn = typeof eventTarget?.on === "function";
|
|
395
|
+
const hasOnce = typeof eventTarget?.once === "function";
|
|
396
|
+
const hasOff = typeof eventTarget?.off === "function";
|
|
397
|
+
if (!hasWrite || !hasEnd || (!hasOnce && !hasOn) || (!hasOff && !eventTarget?.removeListener)) {
|
|
396
398
|
throw new Error("Readable.pipe: invalid destination");
|
|
397
399
|
}
|
|
398
|
-
|
|
399
|
-
this._pipeTo.push(target);
|
|
400
|
+
this._pipeTo.push(dest);
|
|
400
401
|
// Create listeners that we can later remove
|
|
401
402
|
const dataListener = (chunk) => {
|
|
402
|
-
|
|
403
|
+
// Call destination's write() method (not internal _writable.write())
|
|
404
|
+
// This ensures Transform.write() logic runs properly
|
|
405
|
+
const canWrite = dest.write(chunk);
|
|
403
406
|
if (!canWrite) {
|
|
404
407
|
this.pause();
|
|
405
|
-
if (typeof
|
|
406
|
-
|
|
408
|
+
if (typeof eventTarget.once === "function") {
|
|
409
|
+
eventTarget.once("drain", () => this.resume());
|
|
407
410
|
}
|
|
408
411
|
else {
|
|
409
412
|
const resumeOnce = () => {
|
|
410
|
-
if (typeof
|
|
411
|
-
|
|
413
|
+
if (typeof eventTarget.off === "function") {
|
|
414
|
+
eventTarget.off("drain", resumeOnce);
|
|
412
415
|
}
|
|
413
|
-
else if (typeof
|
|
414
|
-
|
|
416
|
+
else if (typeof eventTarget.removeListener === "function") {
|
|
417
|
+
eventTarget.removeListener("drain", resumeOnce);
|
|
415
418
|
}
|
|
416
419
|
this.resume();
|
|
417
420
|
};
|
|
418
|
-
|
|
421
|
+
eventTarget.on("drain", resumeOnce);
|
|
419
422
|
}
|
|
420
423
|
}
|
|
421
424
|
};
|
|
422
425
|
const endListener = () => {
|
|
423
|
-
|
|
426
|
+
dest.end();
|
|
424
427
|
};
|
|
425
428
|
const errorListener = (err) => {
|
|
426
|
-
if (typeof
|
|
427
|
-
|
|
429
|
+
if (typeof dest.destroy === "function") {
|
|
430
|
+
dest.destroy(err);
|
|
428
431
|
}
|
|
429
432
|
else {
|
|
430
433
|
// Best-effort: forward error to the destination if it supports events.
|
|
431
|
-
|
|
434
|
+
eventTarget.emit?.("error", err);
|
|
432
435
|
}
|
|
433
436
|
};
|
|
434
437
|
// Store listeners for later removal in unpipe
|
|
435
|
-
this._pipeListeners.set(
|
|
438
|
+
this._pipeListeners.set(dest, {
|
|
436
439
|
data: dataListener,
|
|
437
440
|
end: endListener,
|
|
438
441
|
error: errorListener
|
|
@@ -1358,6 +1361,8 @@ export class Transform extends EventEmitter {
|
|
|
1358
1361
|
this._autoConsumeEnded = false;
|
|
1359
1362
|
/** @internal - promise that resolves when auto-consume finishes */
|
|
1360
1363
|
this._autoConsumePromise = null;
|
|
1364
|
+
/** @internal - list of piped destinations for forwarding auto-consumed data */
|
|
1365
|
+
this._pipeDestinations = [];
|
|
1361
1366
|
this.objectMode = options?.objectMode ?? false;
|
|
1362
1367
|
const userTransform = options?.transform;
|
|
1363
1368
|
const userFlush = options?.flush;
|
|
@@ -1624,10 +1629,18 @@ export class Transform extends EventEmitter {
|
|
|
1624
1629
|
for await (const chunk of this._readable) {
|
|
1625
1630
|
// Buffer the data for later retrieval
|
|
1626
1631
|
this._autoConsumedBuffer.push(chunk);
|
|
1632
|
+
// Forward to any piped destinations
|
|
1633
|
+
for (const dest of this._pipeDestinations) {
|
|
1634
|
+
dest.write(chunk);
|
|
1635
|
+
}
|
|
1627
1636
|
// Also emit data event for listeners
|
|
1628
1637
|
this.emit("data", chunk);
|
|
1629
1638
|
}
|
|
1630
1639
|
this._autoConsumeEnded = true;
|
|
1640
|
+
// End all piped destinations
|
|
1641
|
+
for (const dest of this._pipeDestinations) {
|
|
1642
|
+
dest.end();
|
|
1643
|
+
}
|
|
1631
1644
|
this.emit("end");
|
|
1632
1645
|
}
|
|
1633
1646
|
catch (err) {
|
|
@@ -1677,8 +1690,28 @@ export class Transform extends EventEmitter {
|
|
|
1677
1690
|
* Pipe to another stream (writable, transform, or duplex)
|
|
1678
1691
|
*/
|
|
1679
1692
|
pipe(destination) {
|
|
1680
|
-
// Mark as having consumer to prevent auto-consume
|
|
1693
|
+
// Mark as having consumer to prevent new auto-consume from starting
|
|
1681
1694
|
this._hasDataConsumer = true;
|
|
1695
|
+
// Get the writable target - handle both Transform (with internal _writable) and plain Writable
|
|
1696
|
+
const dest = destination;
|
|
1697
|
+
const target = dest?._writable ?? dest;
|
|
1698
|
+
// Register destination for forwarding
|
|
1699
|
+
this._pipeDestinations.push(target);
|
|
1700
|
+
// If auto-consume is running or has run, we need to handle buffered data ourselves
|
|
1701
|
+
if (this._readableConsuming) {
|
|
1702
|
+
// Forward any buffered data from auto-consume to the destination
|
|
1703
|
+
for (let i = 0; i < this._autoConsumedBuffer.length; i++) {
|
|
1704
|
+
target.write(this._autoConsumedBuffer[i]);
|
|
1705
|
+
}
|
|
1706
|
+
// If auto-consume has ended, end the destination too
|
|
1707
|
+
if (this._autoConsumeEnded) {
|
|
1708
|
+
target.end();
|
|
1709
|
+
}
|
|
1710
|
+
// Don't call _readable.pipe() - auto-consume already consumed _readable
|
|
1711
|
+
// Future data will be forwarded via the 'data' event listener below
|
|
1712
|
+
return destination;
|
|
1713
|
+
}
|
|
1714
|
+
// No auto-consume running - use normal pipe through _readable
|
|
1682
1715
|
return this._readable.pipe(destination);
|
|
1683
1716
|
}
|
|
1684
1717
|
/**
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Third-Party Notices
|
|
2
|
+
|
|
3
|
+
This project includes software developed by third parties. The following notices are provided for attribution and license compliance.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Third-party component
|
|
8
|
+
|
|
9
|
+
ExcelJS is licensed under the MIT License:
|
|
10
|
+
|
|
11
|
+
The MIT License (MIT)
|
|
12
|
+
|
|
13
|
+
Copyright (c) 2014-2019 Guyon Roche
|
|
14
|
+
|
|
15
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
16
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
17
|
+
in the Software without restriction, including without limitation the rights
|
|
18
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
19
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
20
|
+
furnished to do so, subject to the following conditions:
|
|
21
|
+
|
|
22
|
+
The above copyright notice and this permission notice shall be included in all
|
|
23
|
+
copies or substantial portions of the Software.
|
|
24
|
+
|
|
25
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
26
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
27
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
28
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
29
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
30
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
31
|
+
SOFTWARE.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Third-party component
|
|
36
|
+
|
|
37
|
+
fast-csv is licensed under the MIT License:
|
|
38
|
+
|
|
39
|
+
The MIT License (MIT)
|
|
40
|
+
|
|
41
|
+
Copyright (c) 2011-2025 C2FO
|
|
42
|
+
|
|
43
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
44
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
45
|
+
in the Software without restriction, including without limitation the rights
|
|
46
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
47
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
48
|
+
furnished to do so, subject to the following conditions:
|
|
49
|
+
|
|
50
|
+
The above copyright notice and this permission notice shall be included in all
|
|
51
|
+
copies or substantial portions of the Software.
|
|
52
|
+
|
|
53
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
54
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
55
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
56
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
57
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
58
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
59
|
+
SOFTWARE.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Third-party component
|
|
64
|
+
|
|
65
|
+
unzipper is licensed under the MIT License:
|
|
66
|
+
|
|
67
|
+
The MIT License (MIT)
|
|
68
|
+
|
|
69
|
+
Copyright (c) 2012 - 2013 Near Infinity Corporation
|
|
70
|
+
|
|
71
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
72
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
73
|
+
in the Software without restriction, including without limitation the rights
|
|
74
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
75
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
76
|
+
furnished to do so, subject to the following conditions:
|
|
77
|
+
|
|
78
|
+
The above copyright notice and this permission notice shall be included in all
|
|
79
|
+
copies or substantial portions of the Software.
|
|
80
|
+
|
|
81
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
82
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
83
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
84
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
85
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
86
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
87
|
+
SOFTWARE.
|
|
88
|
+
|
|
89
|
+
Commits in this fork are (c) Ziggy Jonsson (ziggy.jonsson.nyc@gmail.com) and
|
|
90
|
+
fall under same licence structure as the original repo (MIT).
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Third-party component
|
|
95
|
+
|
|
96
|
+
saxes is licensed under the ISC License:
|
|
97
|
+
|
|
98
|
+
The ISC License
|
|
99
|
+
|
|
100
|
+
Copyright (c) Contributors
|
|
101
|
+
|
|
102
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
103
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
104
|
+
copyright notice and this permission notice appear in all copies.
|
|
105
|
+
|
|
106
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
107
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
108
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
109
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
110
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
111
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
|
112
|
+
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @cj-tech-master/excelts v4.2.
|
|
2
|
+
* @cj-tech-master/excelts v4.2.1
|
|
3
3
|
* TypeScript Excel Workbook Manager - Read and Write xlsx and csv Files.
|
|
4
4
|
* (c) 2026 cjnoname
|
|
5
5
|
* Released under the MIT License
|
|
@@ -2767,9 +2767,24 @@ var ExcelTS = (function(exports) {
|
|
|
2767
2767
|
_parseRange(range$1) {
|
|
2768
2768
|
let tl;
|
|
2769
2769
|
let br;
|
|
2770
|
-
if (typeof range$1 === "string") {
|
|
2770
|
+
if (typeof range$1 === "string") if (range$1.includes(":")) {
|
|
2771
2771
|
const decoded = colCache.decode(range$1);
|
|
2772
|
-
if ("top" in decoded) {
|
|
2772
|
+
if ("top" in decoded) if (decoded.left === decoded.right && decoded.top === decoded.bottom) {
|
|
2773
|
+
const col = decoded.left - 1;
|
|
2774
|
+
const row = decoded.top - 1;
|
|
2775
|
+
tl = {
|
|
2776
|
+
col,
|
|
2777
|
+
colOff: DEFAULT_COL_OFF,
|
|
2778
|
+
row,
|
|
2779
|
+
rowOff: DEFAULT_ROW_OFF
|
|
2780
|
+
};
|
|
2781
|
+
br = {
|
|
2782
|
+
col: col + 2,
|
|
2783
|
+
colOff: DEFAULT_END_COL_OFF,
|
|
2784
|
+
row: row + 1,
|
|
2785
|
+
rowOff: DEFAULT_END_ROW_OFF
|
|
2786
|
+
};
|
|
2787
|
+
} else {
|
|
2773
2788
|
tl = {
|
|
2774
2789
|
col: decoded.left - 1,
|
|
2775
2790
|
colOff: DEFAULT_COL_OFF,
|
|
@@ -2782,7 +2797,8 @@ var ExcelTS = (function(exports) {
|
|
|
2782
2797
|
row: decoded.bottom - 1,
|
|
2783
2798
|
rowOff: DEFAULT_END_ROW_OFF
|
|
2784
2799
|
};
|
|
2785
|
-
}
|
|
2800
|
+
}
|
|
2801
|
+
else {
|
|
2786
2802
|
tl = {
|
|
2787
2803
|
col: decoded.col - 1,
|
|
2788
2804
|
colOff: DEFAULT_COL_OFF,
|
|
@@ -2796,7 +2812,22 @@ var ExcelTS = (function(exports) {
|
|
|
2796
2812
|
rowOff: DEFAULT_END_ROW_OFF
|
|
2797
2813
|
};
|
|
2798
2814
|
}
|
|
2799
|
-
} else
|
|
2815
|
+
} else {
|
|
2816
|
+
const decoded = colCache.decodeAddress(range$1);
|
|
2817
|
+
tl = {
|
|
2818
|
+
col: decoded.col - 1,
|
|
2819
|
+
colOff: DEFAULT_COL_OFF,
|
|
2820
|
+
row: decoded.row - 1,
|
|
2821
|
+
rowOff: DEFAULT_ROW_OFF
|
|
2822
|
+
};
|
|
2823
|
+
br = {
|
|
2824
|
+
col: decoded.col + 1,
|
|
2825
|
+
colOff: DEFAULT_END_COL_OFF,
|
|
2826
|
+
row: decoded.row,
|
|
2827
|
+
rowOff: DEFAULT_END_ROW_OFF
|
|
2828
|
+
};
|
|
2829
|
+
}
|
|
2830
|
+
else if ("startCol" in range$1) {
|
|
2800
2831
|
tl = {
|
|
2801
2832
|
col: range$1.startCol,
|
|
2802
2833
|
colOff: range$1.startColOff ?? DEFAULT_COL_OFF,
|
|
@@ -3550,37 +3581,36 @@ var ExcelTS = (function(exports) {
|
|
|
3550
3581
|
*/
|
|
3551
3582
|
pipe(destination) {
|
|
3552
3583
|
const dest = destination;
|
|
3553
|
-
const
|
|
3554
|
-
const hasWrite = typeof
|
|
3555
|
-
const hasEnd = typeof
|
|
3556
|
-
const hasOn = typeof
|
|
3557
|
-
const hasOnce = typeof
|
|
3558
|
-
const hasOff = typeof
|
|
3559
|
-
if (!hasWrite || !hasEnd || !hasOnce && !hasOn || !hasOff && !
|
|
3560
|
-
|
|
3561
|
-
this._pipeTo.push(target);
|
|
3584
|
+
const eventTarget = dest;
|
|
3585
|
+
const hasWrite = typeof dest?.write === "function";
|
|
3586
|
+
const hasEnd = typeof dest?.end === "function";
|
|
3587
|
+
const hasOn = typeof eventTarget?.on === "function";
|
|
3588
|
+
const hasOnce = typeof eventTarget?.once === "function";
|
|
3589
|
+
const hasOff = typeof eventTarget?.off === "function";
|
|
3590
|
+
if (!hasWrite || !hasEnd || !hasOnce && !hasOn || !hasOff && !eventTarget?.removeListener) throw new Error("Readable.pipe: invalid destination");
|
|
3591
|
+
this._pipeTo.push(dest);
|
|
3562
3592
|
const dataListener = (chunk) => {
|
|
3563
|
-
if (!
|
|
3593
|
+
if (!dest.write(chunk)) {
|
|
3564
3594
|
this.pause();
|
|
3565
|
-
if (typeof
|
|
3595
|
+
if (typeof eventTarget.once === "function") eventTarget.once("drain", () => this.resume());
|
|
3566
3596
|
else {
|
|
3567
3597
|
const resumeOnce = () => {
|
|
3568
|
-
if (typeof
|
|
3569
|
-
else if (typeof
|
|
3598
|
+
if (typeof eventTarget.off === "function") eventTarget.off("drain", resumeOnce);
|
|
3599
|
+
else if (typeof eventTarget.removeListener === "function") eventTarget.removeListener("drain", resumeOnce);
|
|
3570
3600
|
this.resume();
|
|
3571
3601
|
};
|
|
3572
|
-
|
|
3602
|
+
eventTarget.on("drain", resumeOnce);
|
|
3573
3603
|
}
|
|
3574
3604
|
}
|
|
3575
3605
|
};
|
|
3576
3606
|
const endListener = () => {
|
|
3577
|
-
|
|
3607
|
+
dest.end();
|
|
3578
3608
|
};
|
|
3579
3609
|
const errorListener = (err) => {
|
|
3580
|
-
if (typeof
|
|
3581
|
-
else
|
|
3610
|
+
if (typeof dest.destroy === "function") dest.destroy(err);
|
|
3611
|
+
else eventTarget.emit?.("error", err);
|
|
3582
3612
|
};
|
|
3583
|
-
this._pipeListeners.set(
|
|
3613
|
+
this._pipeListeners.set(dest, {
|
|
3584
3614
|
data: dataListener,
|
|
3585
3615
|
end: endListener,
|
|
3586
3616
|
error: errorListener
|
|
@@ -4299,6 +4329,7 @@ var ExcelTS = (function(exports) {
|
|
|
4299
4329
|
this._autoConsumedBufferIndex = 0;
|
|
4300
4330
|
this._autoConsumeEnded = false;
|
|
4301
4331
|
this._autoConsumePromise = null;
|
|
4332
|
+
this._pipeDestinations = [];
|
|
4302
4333
|
this.objectMode = options?.objectMode ?? false;
|
|
4303
4334
|
const userTransform = options?.transform;
|
|
4304
4335
|
const userFlush = options?.flush;
|
|
@@ -4473,9 +4504,11 @@ var ExcelTS = (function(exports) {
|
|
|
4473
4504
|
try {
|
|
4474
4505
|
for await (const chunk of this._readable) {
|
|
4475
4506
|
this._autoConsumedBuffer.push(chunk);
|
|
4507
|
+
for (const dest of this._pipeDestinations) dest.write(chunk);
|
|
4476
4508
|
this.emit("data", chunk);
|
|
4477
4509
|
}
|
|
4478
4510
|
this._autoConsumeEnded = true;
|
|
4511
|
+
for (const dest of this._pipeDestinations) dest.end();
|
|
4479
4512
|
this.emit("end");
|
|
4480
4513
|
} catch (err) {
|
|
4481
4514
|
this.emit("error", err);
|
|
@@ -4509,6 +4542,14 @@ var ExcelTS = (function(exports) {
|
|
|
4509
4542
|
*/
|
|
4510
4543
|
pipe(destination) {
|
|
4511
4544
|
this._hasDataConsumer = true;
|
|
4545
|
+
const dest = destination;
|
|
4546
|
+
const target = dest?._writable ?? dest;
|
|
4547
|
+
this._pipeDestinations.push(target);
|
|
4548
|
+
if (this._readableConsuming) {
|
|
4549
|
+
for (let i = 0; i < this._autoConsumedBuffer.length; i++) target.write(this._autoConsumedBuffer[i]);
|
|
4550
|
+
if (this._autoConsumeEnded) target.end();
|
|
4551
|
+
return destination;
|
|
4552
|
+
}
|
|
4512
4553
|
return this._readable.pipe(destination);
|
|
4513
4554
|
}
|
|
4514
4555
|
/**
|
|
@@ -5008,6 +5049,68 @@ var ExcelTS = (function(exports) {
|
|
|
5008
5049
|
if (callback) promise.then(() => callback(null)).catch((err) => callback(err));
|
|
5009
5050
|
return promise;
|
|
5010
5051
|
}
|
|
5052
|
+
/**
|
|
5053
|
+
* Wait for a stream to finish, close, or error.
|
|
5054
|
+
* Node.js compatible with support for options and callbacks.
|
|
5055
|
+
*
|
|
5056
|
+
* @example
|
|
5057
|
+
* // Promise usage
|
|
5058
|
+
* await finished(stream);
|
|
5059
|
+
*
|
|
5060
|
+
* @example
|
|
5061
|
+
* // With options
|
|
5062
|
+
* await finished(stream, { readable: false }); // Only wait for writable side
|
|
5063
|
+
*
|
|
5064
|
+
* @example
|
|
5065
|
+
* // Callback usage
|
|
5066
|
+
* finished(stream, (err) => {
|
|
5067
|
+
* if (err) console.error('Stream error', err);
|
|
5068
|
+
* });
|
|
5069
|
+
*/
|
|
5070
|
+
function finished(stream, optionsOrCallback, callback) {
|
|
5071
|
+
let options = {};
|
|
5072
|
+
let cb;
|
|
5073
|
+
if (typeof optionsOrCallback === "function") cb = optionsOrCallback;
|
|
5074
|
+
else if (optionsOrCallback) {
|
|
5075
|
+
options = optionsOrCallback;
|
|
5076
|
+
cb = callback;
|
|
5077
|
+
}
|
|
5078
|
+
const promise = new Promise((resolve, reject) => {
|
|
5079
|
+
const normalizedStream = toBrowserPipelineStream(stream);
|
|
5080
|
+
let resolved = false;
|
|
5081
|
+
const done = (err) => {
|
|
5082
|
+
if (resolved) return;
|
|
5083
|
+
resolved = true;
|
|
5084
|
+
if (err && !options.error) reject(err);
|
|
5085
|
+
else resolve();
|
|
5086
|
+
};
|
|
5087
|
+
if (options.signal) {
|
|
5088
|
+
if (options.signal.aborted) {
|
|
5089
|
+
done(/* @__PURE__ */ new Error("Aborted"));
|
|
5090
|
+
return;
|
|
5091
|
+
}
|
|
5092
|
+
options.signal.addEventListener("abort", () => {
|
|
5093
|
+
done(/* @__PURE__ */ new Error("Aborted"));
|
|
5094
|
+
});
|
|
5095
|
+
}
|
|
5096
|
+
const checkReadable = options.readable !== false;
|
|
5097
|
+
const checkWritable = options.writable !== false;
|
|
5098
|
+
if (checkReadable && normalizedStream.readableEnded) {
|
|
5099
|
+
done();
|
|
5100
|
+
return;
|
|
5101
|
+
}
|
|
5102
|
+
if (checkWritable && normalizedStream.writableFinished) {
|
|
5103
|
+
done();
|
|
5104
|
+
return;
|
|
5105
|
+
}
|
|
5106
|
+
if (checkWritable) normalizedStream.on("finish", () => done());
|
|
5107
|
+
if (checkReadable) normalizedStream.on("end", () => done());
|
|
5108
|
+
normalizedStream.on("error", (err) => done(err));
|
|
5109
|
+
normalizedStream.on("close", () => done());
|
|
5110
|
+
});
|
|
5111
|
+
if (cb) promise.then(() => cb(null)).catch((err) => cb(err));
|
|
5112
|
+
return promise;
|
|
5113
|
+
}
|
|
5011
5114
|
|
|
5012
5115
|
//#endregion
|
|
5013
5116
|
//#region src/modules/excel/utils/encryptor.browser.ts
|
|
@@ -13625,8 +13728,10 @@ var ExcelTS = (function(exports) {
|
|
|
13625
13728
|
for (const control of model.formControls) {
|
|
13626
13729
|
const globalCtrlPropId = options.formControlRefs.length + 1;
|
|
13627
13730
|
control.ctrlPropId = globalCtrlPropId;
|
|
13731
|
+
const relId = nextRid(rels);
|
|
13732
|
+
control.ctrlPropRelId = relId;
|
|
13628
13733
|
rels.push({
|
|
13629
|
-
Id:
|
|
13734
|
+
Id: relId,
|
|
13630
13735
|
Type: RelType.CtrlProp,
|
|
13631
13736
|
Target: ctrlPropRelTargetFromWorksheet(globalCtrlPropId)
|
|
13632
13737
|
});
|
|
@@ -13679,10 +13784,18 @@ var ExcelTS = (function(exports) {
|
|
|
13679
13784
|
this.map.drawing.render(xmlStream, model.drawing);
|
|
13680
13785
|
this.map.picture.render(xmlStream, model.background);
|
|
13681
13786
|
this.map.tableParts.render(xmlStream, model.tables);
|
|
13682
|
-
|
|
13787
|
+
if (model.formControls && model.formControls.length > 0) {
|
|
13788
|
+
xmlStream.openNode("controls");
|
|
13789
|
+
for (const control of model.formControls) if (control.ctrlPropRelId) xmlStream.leafNode("control", {
|
|
13790
|
+
shapeId: control.shapeId,
|
|
13791
|
+
"r:id": control.ctrlPropRelId
|
|
13792
|
+
});
|
|
13793
|
+
xmlStream.closeNode();
|
|
13794
|
+
}
|
|
13683
13795
|
if (model.rels) model.rels.forEach((rel) => {
|
|
13684
13796
|
if (rel.Type === RelType.VmlDrawing) xmlStream.leafNode("legacyDrawing", { "r:id": rel.Id });
|
|
13685
13797
|
});
|
|
13798
|
+
this.map.extLst.render(xmlStream, model);
|
|
13686
13799
|
xmlStream.closeNode();
|
|
13687
13800
|
}
|
|
13688
13801
|
parseOpen(node) {
|
|
@@ -17886,17 +17999,10 @@ var ExcelTS = (function(exports) {
|
|
|
17886
17999
|
* Default threshold (in bytes) to choose the lower-overhead path.
|
|
17887
18000
|
*
|
|
17888
18001
|
* This is a performance knob, not a correctness requirement.
|
|
18002
|
+
* Default: 8MB.
|
|
17889
18003
|
*/
|
|
17890
18004
|
const DEFAULT_COMPRESS_THRESHOLD_BYTES = 8 * 1024 * 1024;
|
|
17891
18005
|
/**
|
|
17892
|
-
* Resolve the effective threshold bytes.
|
|
17893
|
-
*/
|
|
17894
|
-
function resolveCompressThresholdBytes(options) {
|
|
17895
|
-
const value = options.thresholdBytes;
|
|
17896
|
-
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return DEFAULT_COMPRESS_THRESHOLD_BYTES;
|
|
17897
|
-
return value;
|
|
17898
|
-
}
|
|
17899
|
-
/**
|
|
17900
18006
|
* Non-cached probe for CompressionStream("deflate-raw") support.
|
|
17901
18007
|
*
|
|
17902
18008
|
* Prefer this in code paths that want up-to-date environment checks
|
|
@@ -18775,12 +18881,16 @@ var ExcelTS = (function(exports) {
|
|
|
18775
18881
|
/**
|
|
18776
18882
|
* Decompress data using browser's native DecompressionStream or JS fallback
|
|
18777
18883
|
*
|
|
18884
|
+
* Note: We always prefer native DecompressionStream when available because
|
|
18885
|
+
* it's significantly faster than pure JS implementation, regardless of data size.
|
|
18886
|
+
* The threshold is only useful for compression where the overhead matters more.
|
|
18887
|
+
*
|
|
18778
18888
|
* @param data - Compressed data (deflate-raw format)
|
|
18889
|
+
* @param options - Decompression options (kept for API parity; currently unused in browser)
|
|
18779
18890
|
* @returns Decompressed data
|
|
18780
18891
|
*/
|
|
18781
18892
|
async function decompress(data, options = {}) {
|
|
18782
|
-
|
|
18783
|
-
if (hasDeflateRawDecompressionStream() && data.byteLength > thresholdBytes) return decompressWithStream(data);
|
|
18893
|
+
if (hasDeflateRawDecompressionStream()) return decompressWithStream(data);
|
|
18784
18894
|
return inflateRaw(data);
|
|
18785
18895
|
}
|
|
18786
18896
|
/**
|
|
@@ -19483,8 +19593,13 @@ var ExcelTS = (function(exports) {
|
|
|
19483
19593
|
queueMicrotask(pull);
|
|
19484
19594
|
return output;
|
|
19485
19595
|
}
|
|
19596
|
+
/**
|
|
19597
|
+
* Default threshold for small file optimization (5MB).
|
|
19598
|
+
*/
|
|
19599
|
+
const DEFAULT_PARSE_THRESHOLD_BYTES = 5 * 1024 * 1024;
|
|
19486
19600
|
const endDirectorySignature = writeUint32LE(END_OF_CENTRAL_DIR_SIG);
|
|
19487
|
-
async function runParseLoop(opts, io, emitter, inflateFactory, state) {
|
|
19601
|
+
async function runParseLoop(opts, io, emitter, inflateFactory, state, inflateRawSync) {
|
|
19602
|
+
const thresholdBytes = opts.thresholdBytes ?? DEFAULT_PARSE_THRESHOLD_BYTES;
|
|
19488
19603
|
while (true) {
|
|
19489
19604
|
const sigBytes = await io.pull(4);
|
|
19490
19605
|
if (sigBytes.length === 0) {
|
|
@@ -19498,7 +19613,7 @@ var ExcelTS = (function(exports) {
|
|
|
19498
19613
|
continue;
|
|
19499
19614
|
}
|
|
19500
19615
|
if (signature === LOCAL_FILE_HEADER_SIG) {
|
|
19501
|
-
await readFileRecord(opts, io, emitter, inflateFactory, state);
|
|
19616
|
+
await readFileRecord(opts, io, emitter, inflateFactory, state, thresholdBytes, inflateRawSync);
|
|
19502
19617
|
continue;
|
|
19503
19618
|
}
|
|
19504
19619
|
if (signature === CENTRAL_DIR_HEADER_SIG) {
|
|
@@ -19524,7 +19639,7 @@ var ExcelTS = (function(exports) {
|
|
|
19524
19639
|
return;
|
|
19525
19640
|
}
|
|
19526
19641
|
}
|
|
19527
|
-
async function readFileRecord(opts, io, emitter, inflateFactory, state) {
|
|
19642
|
+
async function readFileRecord(opts, io, emitter, inflateFactory, state, thresholdBytes, inflateRawSync) {
|
|
19528
19643
|
const { vars: headerVars, fileNameBuffer, extraFieldData } = await readLocalFileHeader(async (l) => io.pull(l));
|
|
19529
19644
|
const vars = headerVars;
|
|
19530
19645
|
if (state.crxHeader) vars.crxHeader = state.crxHeader;
|
|
@@ -19564,6 +19679,15 @@ var ExcelTS = (function(exports) {
|
|
|
19564
19679
|
vars,
|
|
19565
19680
|
extraFields: entry.extraFields
|
|
19566
19681
|
});
|
|
19682
|
+
const sizesTrusted = !hasDataDescriptorFlag(vars.flags);
|
|
19683
|
+
const compressedSize = vars.compressedSize || 0;
|
|
19684
|
+
const uncompressedSize = vars.uncompressedSize || 0;
|
|
19685
|
+
if (sizesTrusted && fileSizeKnown && inflateRawSync && vars.compressionMethod !== 0 && !autodraining && compressedSize <= thresholdBytes && uncompressedSize <= thresholdBytes) {
|
|
19686
|
+
const decompressedData = inflateRawSync(await io.pull(compressedSize));
|
|
19687
|
+
entry.end(decompressedData);
|
|
19688
|
+
await finished(entry, { readable: false });
|
|
19689
|
+
return;
|
|
19690
|
+
}
|
|
19567
19691
|
const inflater = vars.compressionMethod && !autodraining ? inflateFactory() : new PassThrough();
|
|
19568
19692
|
if (fileSizeKnown) {
|
|
19569
19693
|
await pipeline(io.stream(vars.compressedSize || 0), inflater, entry);
|