@office-kit/xlsx 0.8.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.
Files changed (220) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +319 -0
  3. package/THIRD_PARTY_NOTICES.md +56 -0
  4. package/dist/cell/cell.d.ts +234 -0
  5. package/dist/cell/index.d.ts +4 -0
  6. package/dist/cell/rich-text.d.ts +37 -0
  7. package/dist/cell-D9CaNKnU.mjs +320 -0
  8. package/dist/cell-D9CaNKnU.mjs.map +1 -0
  9. package/dist/cell-style-BEDjMX1y.mjs +1579 -0
  10. package/dist/cell-style-BEDjMX1y.mjs.map +1 -0
  11. package/dist/cell.mjs +2 -0
  12. package/dist/chart/chart-xml.d.ts +16 -0
  13. package/dist/chart/chart.d.ts +735 -0
  14. package/dist/chart/cx/chartex-xml.d.ts +6 -0
  15. package/dist/chart/cx/chartex.d.ts +279 -0
  16. package/dist/chart/index.d.ts +6 -0
  17. package/dist/chart/user-shapes-xml.d.ts +4 -0
  18. package/dist/chart/user-shapes.d.ts +61 -0
  19. package/dist/chart.mjs +232 -0
  20. package/dist/chart.mjs.map +1 -0
  21. package/dist/chartsheet/chartsheet-xml.d.ts +17 -0
  22. package/dist/chartsheet/chartsheet.d.ts +121 -0
  23. package/dist/chartsheet/index.d.ts +2 -0
  24. package/dist/chartsheet-C3-tqkPy.mjs +23 -0
  25. package/dist/chartsheet-C3-tqkPy.mjs.map +1 -0
  26. package/dist/chartsheet.mjs +2 -0
  27. package/dist/colors-ovWAwnZI.mjs +67 -0
  28. package/dist/colors-ovWAwnZI.mjs.map +1 -0
  29. package/dist/compat/numbers.d.ts +14 -0
  30. package/dist/coordinate-96Ecci4d.mjs +276 -0
  31. package/dist/coordinate-96Ecci4d.mjs.map +1 -0
  32. package/dist/datetime-B2ySVlXt.mjs +71 -0
  33. package/dist/datetime-B2ySVlXt.mjs.map +1 -0
  34. package/dist/defined-names-CviWmtQg.mjs +89 -0
  35. package/dist/defined-names-CviWmtQg.mjs.map +1 -0
  36. package/dist/differential-D4dg-qtZ.mjs +37 -0
  37. package/dist/differential-D4dg-qtZ.mjs.map +1 -0
  38. package/dist/drawing/anchor.d.ts +63 -0
  39. package/dist/drawing/dml/colors.d.ts +109 -0
  40. package/dist/drawing/dml/dml-xml.d.ts +35 -0
  41. package/dist/drawing/dml/effect.d.ts +92 -0
  42. package/dist/drawing/dml/fill.d.ts +115 -0
  43. package/dist/drawing/dml/geometry.d.ts +113 -0
  44. package/dist/drawing/dml/line.d.ts +41 -0
  45. package/dist/drawing/dml/shape-properties.d.ts +33 -0
  46. package/dist/drawing/dml/text.d.ts +218 -0
  47. package/dist/drawing/drawing-xml.d.ts +5 -0
  48. package/dist/drawing/drawing.d.ts +117 -0
  49. package/dist/drawing/image.d.ts +40 -0
  50. package/dist/drawing/index.d.ts +14 -0
  51. package/dist/drawing-BxzLuryn.mjs +415 -0
  52. package/dist/drawing-BxzLuryn.mjs.map +1 -0
  53. package/dist/drawing.mjs +119 -0
  54. package/dist/drawing.mjs.map +1 -0
  55. package/dist/escape-DFTE7ZJc.mjs +51 -0
  56. package/dist/escape-DFTE7ZJc.mjs.map +1 -0
  57. package/dist/exceptions-D-CFwxgm.mjs +37 -0
  58. package/dist/exceptions-D-CFwxgm.mjs.map +1 -0
  59. package/dist/formula/tokenizer.d.ts +61 -0
  60. package/dist/formula/translate.d.ts +67 -0
  61. package/dist/inference-B3ES3KEJ.mjs +42 -0
  62. package/dist/inference-B3ES3KEJ.mjs.map +1 -0
  63. package/dist/io/browser.d.ts +41 -0
  64. package/dist/io/index.d.ts +7 -0
  65. package/dist/io/load.d.ts +46 -0
  66. package/dist/io/node-fs.d.ts +62 -0
  67. package/dist/io/node-save.d.ts +3 -0
  68. package/dist/io/node.d.ts +17 -0
  69. package/dist/io/save.d.ts +14 -0
  70. package/dist/io/sink.d.ts +54 -0
  71. package/dist/io/source.d.ts +14 -0
  72. package/dist/io.mjs +212 -0
  73. package/dist/io.mjs.map +1 -0
  74. package/dist/load-D5cbhoGx.mjs +1069 -0
  75. package/dist/load-D5cbhoGx.mjs.map +1 -0
  76. package/dist/manifest-Dps1-OpP.mjs +801 -0
  77. package/dist/manifest-Dps1-OpP.mjs.map +1 -0
  78. package/dist/node.d.ts +3 -0
  79. package/dist/node.mjs +308 -0
  80. package/dist/node.mjs.map +1 -0
  81. package/dist/packaging/core.d.ts +45 -0
  82. package/dist/packaging/custom.d.ts +62 -0
  83. package/dist/packaging/extended.d.ts +45 -0
  84. package/dist/packaging/index.d.ts +10 -0
  85. package/dist/packaging/manifest.d.ts +24 -0
  86. package/dist/packaging/relationships.d.ts +30 -0
  87. package/dist/packaging.mjs +2 -0
  88. package/dist/parser-DuLejQy1.mjs +156 -0
  89. package/dist/parser-DuLejQy1.mjs.map +1 -0
  90. package/dist/reader-D1fNW9k1.mjs +534 -0
  91. package/dist/reader-D1fNW9k1.mjs.map +1 -0
  92. package/dist/save-RohQtgEZ.mjs +745 -0
  93. package/dist/save-RohQtgEZ.mjs.map +1 -0
  94. package/dist/schema/core.d.ts +133 -0
  95. package/dist/schema/index.d.ts +3 -0
  96. package/dist/schema/serialize.d.ts +6 -0
  97. package/dist/schema.mjs +2 -0
  98. package/dist/serialize-55EnT30e.mjs +254 -0
  99. package/dist/serialize-55EnT30e.mjs.map +1 -0
  100. package/dist/serializer-BwbgHYJV.mjs +116 -0
  101. package/dist/serializer-BwbgHYJV.mjs.map +1 -0
  102. package/dist/streaming/index.d.ts +2 -0
  103. package/dist/streaming/read-only.d.ts +38 -0
  104. package/dist/streaming/write-only.d.ts +47 -0
  105. package/dist/streaming.mjs +612 -0
  106. package/dist/streaming.mjs.map +1 -0
  107. package/dist/styles/alignment.d.ts +33 -0
  108. package/dist/styles/alignment.schema.d.ts +3 -0
  109. package/dist/styles/borders.d.ts +40 -0
  110. package/dist/styles/borders.schema.d.ts +4 -0
  111. package/dist/styles/cell-style.d.ts +270 -0
  112. package/dist/styles/colors.d.ts +128 -0
  113. package/dist/styles/colors.schema.d.ts +3 -0
  114. package/dist/styles/differential.d.ts +41 -0
  115. package/dist/styles/fills.d.ts +54 -0
  116. package/dist/styles/fills.schema.d.ts +6 -0
  117. package/dist/styles/fonts.d.ts +44 -0
  118. package/dist/styles/fonts.schema.d.ts +3 -0
  119. package/dist/styles/index.d.ts +21 -0
  120. package/dist/styles/named-styles.d.ts +52 -0
  121. package/dist/styles/numbers.d.ts +39 -0
  122. package/dist/styles/numbers.schema.d.ts +3 -0
  123. package/dist/styles/protection.d.ts +9 -0
  124. package/dist/styles/protection.schema.d.ts +3 -0
  125. package/dist/styles/stylesheet-reader.d.ts +7 -0
  126. package/dist/styles/stylesheet-writer.d.ts +3 -0
  127. package/dist/styles/stylesheet.d.ts +95 -0
  128. package/dist/styles.mjs +4 -0
  129. package/dist/stylesheet-writer-C2eRmn22.mjs +8624 -0
  130. package/dist/stylesheet-writer-C2eRmn22.mjs.map +1 -0
  131. package/dist/table-DkX6UniA.mjs +113 -0
  132. package/dist/table-DkX6UniA.mjs.map +1 -0
  133. package/dist/tree-Bbs1C8Rc.mjs +192 -0
  134. package/dist/tree-Bbs1C8Rc.mjs.map +1 -0
  135. package/dist/units-rOMQqXh2.mjs +41 -0
  136. package/dist/units-rOMQqXh2.mjs.map +1 -0
  137. package/dist/user-shapes-DfmCGKB0.mjs +252 -0
  138. package/dist/user-shapes-DfmCGKB0.mjs.map +1 -0
  139. package/dist/utf8-D91g1XTG.mjs +143 -0
  140. package/dist/utf8-D91g1XTG.mjs.map +1 -0
  141. package/dist/utils/coordinate.d.ts +103 -0
  142. package/dist/utils/css.d.ts +18 -0
  143. package/dist/utils/datetime.d.ts +38 -0
  144. package/dist/utils/escape.d.ts +34 -0
  145. package/dist/utils/exceptions.d.ts +34 -0
  146. package/dist/utils/index.d.ts +11 -0
  147. package/dist/utils/inference.d.ts +24 -0
  148. package/dist/utils/stable-stringify.d.ts +7 -0
  149. package/dist/utils/units.d.ts +14 -0
  150. package/dist/utils/utf8.d.ts +1 -0
  151. package/dist/utils.mjs +39 -0
  152. package/dist/utils.mjs.map +1 -0
  153. package/dist/workbook/calc-properties.d.ts +47 -0
  154. package/dist/workbook/defined-names.d.ts +121 -0
  155. package/dist/workbook/file-recovery.d.ts +11 -0
  156. package/dist/workbook/file-sharing.d.ts +14 -0
  157. package/dist/workbook/file-version.d.ts +13 -0
  158. package/dist/workbook/function-groups.d.ts +10 -0
  159. package/dist/workbook/index.d.ts +24 -0
  160. package/dist/workbook/protection.d.ts +35 -0
  161. package/dist/workbook/shared-strings.d.ts +57 -0
  162. package/dist/workbook/smart-tags.d.ts +13 -0
  163. package/dist/workbook/views.d.ts +89 -0
  164. package/dist/workbook/workbook-properties.d.ts +57 -0
  165. package/dist/workbook/workbook.d.ts +643 -0
  166. package/dist/workbook-HGYNRBlV.mjs +636 -0
  167. package/dist/workbook-HGYNRBlV.mjs.map +1 -0
  168. package/dist/workbook.mjs +58 -0
  169. package/dist/workbook.mjs.map +1 -0
  170. package/dist/worksheet/auto-filter.d.ts +34 -0
  171. package/dist/worksheet/cell-range.d.ts +121 -0
  172. package/dist/worksheet/comments-xml.d.ts +24 -0
  173. package/dist/worksheet/comments.d.ts +13 -0
  174. package/dist/worksheet/conditional-formatting.d.ts +150 -0
  175. package/dist/worksheet/custom-sheet-views.d.ts +43 -0
  176. package/dist/worksheet/data-consolidate.d.ts +29 -0
  177. package/dist/worksheet/data-validations.d.ts +72 -0
  178. package/dist/worksheet/dimensions.d.ts +40 -0
  179. package/dist/worksheet/errors.d.ts +40 -0
  180. package/dist/worksheet/hyperlinks.d.ts +42 -0
  181. package/dist/worksheet/index.d.ts +46 -0
  182. package/dist/worksheet/ole-objects.d.ts +37 -0
  183. package/dist/worksheet/page-setup.d.ts +173 -0
  184. package/dist/worksheet/phonetic.d.ts +11 -0
  185. package/dist/worksheet/properties.d.ts +34 -0
  186. package/dist/worksheet/protected-ranges.d.ts +19 -0
  187. package/dist/worksheet/protection.d.ts +44 -0
  188. package/dist/worksheet/reader.d.ts +38 -0
  189. package/dist/worksheet/scenarios.d.ts +36 -0
  190. package/dist/worksheet/smart-tags.d.ts +23 -0
  191. package/dist/worksheet/sort-state.d.ts +28 -0
  192. package/dist/worksheet/table-xml.d.ts +5 -0
  193. package/dist/worksheet/table.d.ts +80 -0
  194. package/dist/worksheet/views.d.ts +47 -0
  195. package/dist/worksheet/web-publish.d.ts +21 -0
  196. package/dist/worksheet/worksheet.d.ts +935 -0
  197. package/dist/worksheet/writer.d.ts +72 -0
  198. package/dist/worksheet-CmCNoIgD.mjs +1726 -0
  199. package/dist/worksheet-CmCNoIgD.mjs.map +1 -0
  200. package/dist/worksheet.mjs +247 -0
  201. package/dist/worksheet.mjs.map +1 -0
  202. package/dist/writer-DspzfkNA.mjs +221 -0
  203. package/dist/writer-DspzfkNA.mjs.map +1 -0
  204. package/dist/xml/index.d.ts +10 -0
  205. package/dist/xml/iterparse.d.ts +22 -0
  206. package/dist/xml/namespaces.d.ts +91 -0
  207. package/dist/xml/parser.d.ts +7 -0
  208. package/dist/xml/serializer.d.ts +14 -0
  209. package/dist/xml/stream-writer.d.ts +39 -0
  210. package/dist/xml/tree.d.ts +37 -0
  211. package/dist/xml.mjs +140 -0
  212. package/dist/xml.mjs.map +1 -0
  213. package/dist/zip/decompression-guard.d.ts +70 -0
  214. package/dist/zip/index.d.ts +6 -0
  215. package/dist/zip/random-access-reader.d.ts +16 -0
  216. package/dist/zip/reader.d.ts +45 -0
  217. package/dist/zip/writer.d.ts +65 -0
  218. package/dist/zip/zip64-patch.d.ts +12 -0
  219. package/dist/zip.mjs +3 -0
  220. package/package.json +147 -0
@@ -0,0 +1,51 @@
1
+ //#region src/utils/escape.ts
2
+ const ILLEGAL_RE = /[\x00-\x1F\ud800-\udfff]/g;
3
+ const ESCAPED_PATTERN_RE = /(_)(x[0-9A-Fa-f]{4}_)/g;
4
+ const toHex4 = (n) => n.toString(16).toUpperCase().padStart(4, "0");
5
+ /**
6
+ * Escape a string for safe storage in an OOXML cell. Already-escaped
7
+ * sequences (`_xHHHH_`) are protected by escaping their leading
8
+ * underscore; illegal codepoints are replaced with their `_xHHHH_`
9
+ * representation.
10
+ */
11
+ function escapeCellString(s) {
12
+ return s.replace(ESCAPED_PATTERN_RE, "_x005F_$2").replace(ILLEGAL_RE, (ch) => `_x${toHex4(ch.charCodeAt(0))}_`);
13
+ }
14
+ const UNESCAPE_RE = /_x([0-9A-Fa-f]{4})_/g;
15
+ /**
16
+ * Inverse of {@link escapeCellString}. Looking from left to right
17
+ * we replace any `_xHHHH_` sequence with the corresponding code unit;
18
+ * the protected `_x005F_` becomes a literal underscore which the
19
+ * subsequent replacements skip safely (replace's regex is non-overlapping).
20
+ */
21
+ function unescapeCellString(s) {
22
+ return s.replace(UNESCAPE_RE, (_full, hex) => String.fromCharCode(Number.parseInt(hex, 16)));
23
+ }
24
+ /**
25
+ * Escape a string for safe placement in an XML text node. Replaces the three
26
+ * codepoints that would otherwise terminate the text region or open a markup
27
+ * sequence (`&`, `<`, `>`); `"` and `'` are not legal markup terminators
28
+ * inside text and stay verbatim.
29
+ */
30
+ function escapeXmlText(s) {
31
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
32
+ }
33
+ /**
34
+ * Escape a string for safe placement inside a `"`-quoted XML attribute.
35
+ * Handles `&`, `<`, `>` and the `"` that would otherwise close the value.
36
+ *
37
+ * Note: this deliberately does NOT escape `\r` / `\n` / `\t` to numeric
38
+ * character references. XML 1.0 attribute-value normalisation would
39
+ * collapse them to spaces in theory, but the parser used on the read side
40
+ * (fast-xml-parser) does not decode numeric character references, so a
41
+ * write-then-read round-trip would surface the literal `&#9;` instead of
42
+ * recovering the original tab. Leaving the whitespace bytes literal keeps
43
+ * the round-trip stable and matches what Excel itself emits.
44
+ */
45
+ function escapeXmlAttr(s) {
46
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
47
+ }
48
+ //#endregion
49
+ export { unescapeCellString as i, escapeXmlAttr as n, escapeXmlText as r, escapeCellString as t };
50
+
51
+ //# sourceMappingURL=escape-DFTE7ZJc.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escape-DFTE7ZJc.mjs","names":[],"sources":["../src/utils/escape.ts"],"sourcesContent":["// XML 1.0 cell-string escaping. Mirrors openpyxl/openpyxl/utils/escape.py.\n//\n// Excel emits cell strings with control characters and other illegal\n// XML 1.0 codepoints encoded as `_xHHHH_` (uppercase hex). The\n// underscore itself is a literal in normal text but a sequence opener\n// in escape position; an existing `_xHHHH_` in the input is therefore\n// re-escaped to `_x005F_xHHHH_` so it round-trips losslessly.\n\n// Escape every C0 control character (U+0000 through U+001F) plus the\n// surrogate range U+D800–U+DFFF. NUL is invalid in XML 1.0 entirely.\n// This range deliberately covers `\\t` (U+0009), `\\n` (U+000A) and `\\r`\n// (U+000D) even though XML 1.0 considers them legal whitespace — XML\n// parsers normalise CRLF / lone CR to LF on read, so a cell string\n// containing `\\r` would silently lose its CR without the `_x000D_`\n// encoding. openpyxl escapes the same `\\x01-\\x19` range; we add NUL\n// to keep the writer well-formed when callers feed in binary data.\nconst ILLEGAL_RE =\n // biome-ignore lint/suspicious/noControlCharactersInRegex: by design — these are the codepoints we replace\n /[\\x00-\\x1F\\ud800-\\udfff]/g;\nconst ESCAPED_PATTERN_RE = /(_)(x[0-9A-Fa-f]{4}_)/g;\n\nconst toHex4 = (n: number): string => n.toString(16).toUpperCase().padStart(4, '0');\n\n/**\n * Escape a string for safe storage in an OOXML cell. Already-escaped\n * sequences (`_xHHHH_`) are protected by escaping their leading\n * underscore; illegal codepoints are replaced with their `_xHHHH_`\n * representation.\n */\nexport function escapeCellString(s: string): string {\n // Re-escape any existing `_xHHHH_` so it round-trips; the underscore\n // becomes `_x005F_` and the rest of the sequence is left as-is.\n const protectedString = s.replace(ESCAPED_PATTERN_RE, '_x005F_$2');\n return protectedString.replace(ILLEGAL_RE, (ch) => `_x${toHex4(ch.charCodeAt(0))}_`);\n}\n\nconst UNESCAPE_RE = /_x([0-9A-Fa-f]{4})_/g;\n\n/**\n * Inverse of {@link escapeCellString}. Looking from left to right\n * we replace any `_xHHHH_` sequence with the corresponding code unit;\n * the protected `_x005F_` becomes a literal underscore which the\n * subsequent replacements skip safely (replace's regex is non-overlapping).\n */\nexport function unescapeCellString(s: string): string {\n return s.replace(UNESCAPE_RE, (_full, hex: string) => String.fromCharCode(Number.parseInt(hex, 16)));\n}\n\n// ---- XML escape helpers ----------------------------------------------------\n//\n// One canonical implementation for text-node and attribute escaping. The\n// previous codebase carried three near-identical copies (one each in save.ts,\n// xml/serializer.ts, xml/stream-writer.ts); they disagreed about `>`-in-attribute\n// handling and would have drifted further apart over time. Keeping them in a\n// single place also makes future fixes (e.g. surrogate-pair scrubbing) land\n// once rather than three times.\n\n/**\n * Escape a string for safe placement in an XML text node. Replaces the three\n * codepoints that would otherwise terminate the text region or open a markup\n * sequence (`&`, `<`, `>`); `\"` and `'` are not legal markup terminators\n * inside text and stay verbatim.\n */\nexport function escapeXmlText(s: string): string {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n}\n\n/**\n * Escape a string for safe placement inside a `\"`-quoted XML attribute.\n * Handles `&`, `<`, `>` and the `\"` that would otherwise close the value.\n *\n * Note: this deliberately does NOT escape `\\r` / `\\n` / `\\t` to numeric\n * character references. XML 1.0 attribute-value normalisation would\n * collapse them to spaces in theory, but the parser used on the read side\n * (fast-xml-parser) does not decode numeric character references, so a\n * write-then-read round-trip would surface the literal `&#9;` instead of\n * recovering the original tab. Leaving the whitespace bytes literal keeps\n * the round-trip stable and matches what Excel itself emits.\n */\nexport function escapeXmlAttr(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n"],"mappings":";AAgBA,MAAM,aAEJ;AACF,MAAM,qBAAqB;AAE3B,MAAM,UAAU,MAAsB,EAAE,SAAS,EAAE,EAAE,YAAY,EAAE,SAAS,GAAG,GAAG;;;;;;;AAQlF,SAAgB,iBAAiB,GAAmB;CAIlD,OADwB,EAAE,QAAQ,oBAAoB,WACjC,EAAE,QAAQ,aAAa,OAAO,KAAK,OAAO,GAAG,WAAW,CAAC,CAAC,EAAE,EAAE;AACrF;AAEA,MAAM,cAAc;;;;;;;AAQpB,SAAgB,mBAAmB,GAAmB;CACpD,OAAO,EAAE,QAAQ,cAAc,OAAO,QAAgB,OAAO,aAAa,OAAO,SAAS,KAAK,EAAE,CAAC,CAAC;AACrG;;;;;;;AAiBA,SAAgB,cAAc,GAAmB;CAC/C,OAAO,EAAE,QAAQ,MAAM,OAAO,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM;AAC5E;;;;;;;;;;;;;AAcA,SAAgB,cAAc,GAAmB;CAC/C,OAAO,EACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ;AAC3B"}
@@ -0,0 +1,37 @@
1
+ //#region src/utils/exceptions.ts
2
+ var OpenXmlError = class extends Error {
3
+ name = "OpenXmlError";
4
+ constructor(message, options) {
5
+ super(message, options);
6
+ }
7
+ };
8
+ /** Thrown for ZIP, file system, network or stream-level failures. */
9
+ var OpenXmlIoError = class extends OpenXmlError {
10
+ name = "OpenXmlIoError";
11
+ };
12
+ /** Thrown when an OOXML payload violates structural / schema invariants. */
13
+ var OpenXmlSchemaError = class extends OpenXmlError {
14
+ name = "OpenXmlSchemaError";
15
+ };
16
+ /** Thrown when a workbook is structurally valid OOXML but semantically broken. */
17
+ var OpenXmlInvalidWorkbookError = class extends OpenXmlError {
18
+ name = "OpenXmlInvalidWorkbookError";
19
+ };
20
+ /** Thrown for features the port has chosen not to implement (yet). */
21
+ var OpenXmlNotImplementedError = class extends OpenXmlError {
22
+ name = "OpenXmlNotImplementedError";
23
+ };
24
+ /**
25
+ * Thrown when an archive trips the decompression-bomb safeguards configured on
26
+ * {@link openZip} / {@link loadWorkbook} / {@link loadWorkbookStream}. Subclass
27
+ * of {@link OpenXmlIoError} so existing `catch (OpenXmlIoError)` paths still
28
+ * see it, while letting callers branch on bomb-specific recovery (reject the
29
+ * upload, log a security event, etc.).
30
+ */
31
+ var OpenXmlDecompressionBombError = class extends OpenXmlIoError {
32
+ name = "OpenXmlDecompressionBombError";
33
+ };
34
+ //#endregion
35
+ export { OpenXmlNotImplementedError as a, OpenXmlIoError as i, OpenXmlError as n, OpenXmlSchemaError as o, OpenXmlInvalidWorkbookError as r, OpenXmlDecompressionBombError as t };
36
+
37
+ //# sourceMappingURL=exceptions-D-CFwxgm.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exceptions-D-CFwxgm.mjs","names":[],"sources":["../src/utils/exceptions.ts"],"sourcesContent":["// Error hierarchy for @office-kit/xlsx. Public APIs throw subclasses of OpenXmlError;\n// internals chain via the `cause` option (Node 18+ / modern browsers all\n// support Error.cause).\n//\n// Class is the one explicitly allowed exception to the no-class rule because\n// Error subclasses are how `instanceof` discrimination is expressed in JS.\n\nexport interface OpenXmlErrorOptions {\n /** Underlying cause; preserved on the standard `cause` property. */\n cause?: unknown;\n}\n\nexport class OpenXmlError extends Error {\n override readonly name: string = 'OpenXmlError';\n\n constructor(message: string, options?: OpenXmlErrorOptions) {\n super(message, options as ErrorOptions);\n }\n}\n\n/** Thrown for ZIP, file system, network or stream-level failures. */\nexport class OpenXmlIoError extends OpenXmlError {\n override readonly name: string = 'OpenXmlIoError';\n}\n\n/** Thrown when an OOXML payload violates structural / schema invariants. */\nexport class OpenXmlSchemaError extends OpenXmlError {\n override readonly name = 'OpenXmlSchemaError';\n}\n\n/** Thrown when a workbook is structurally valid OOXML but semantically broken. */\nexport class OpenXmlInvalidWorkbookError extends OpenXmlError {\n override readonly name = 'OpenXmlInvalidWorkbookError';\n}\n\n/** Thrown for features the port has chosen not to implement (yet). */\nexport class OpenXmlNotImplementedError extends OpenXmlError {\n override readonly name = 'OpenXmlNotImplementedError';\n}\n\n/**\n * Thrown when an archive trips the decompression-bomb safeguards configured on\n * {@link openZip} / {@link loadWorkbook} / {@link loadWorkbookStream}. Subclass\n * of {@link OpenXmlIoError} so existing `catch (OpenXmlIoError)` paths still\n * see it, while letting callers branch on bomb-specific recovery (reject the\n * upload, log a security event, etc.).\n */\nexport class OpenXmlDecompressionBombError extends OpenXmlIoError {\n override readonly name = 'OpenXmlDecompressionBombError';\n}\n"],"mappings":";AAYA,IAAa,eAAb,cAAkC,MAAM;CACtC,OAAiC;CAEjC,YAAY,SAAiB,SAA+B;EAC1D,MAAM,SAAS,OAAuB;CACxC;AACF;;AAGA,IAAa,iBAAb,cAAoC,aAAa;CAC/C,OAAiC;AACnC;;AAGA,IAAa,qBAAb,cAAwC,aAAa;CACnD,OAAyB;AAC3B;;AAGA,IAAa,8BAAb,cAAiD,aAAa;CAC5D,OAAyB;AAC3B;;AAGA,IAAa,6BAAb,cAAgD,aAAa;CAC3D,OAAyB;AAC3B;;;;;;;;AASA,IAAa,gCAAb,cAAmD,eAAe;CAChE,OAAyB;AAC3B"}
@@ -0,0 +1,61 @@
1
+ import { OpenXmlError } from '../utils/exceptions';
2
+ export declare class TokenizerError extends OpenXmlError {
3
+ readonly name = "TokenizerError";
4
+ }
5
+ export declare const LITERAL = "LITERAL";
6
+ export declare const OPERAND = "OPERAND";
7
+ export declare const FUNC = "FUNC";
8
+ export declare const ARRAY = "ARRAY";
9
+ export declare const PAREN = "PAREN";
10
+ export declare const SEP = "SEP";
11
+ export declare const OP_PRE = "OPERATOR-PREFIX";
12
+ export declare const OP_IN = "OPERATOR-INFIX";
13
+ export declare const OP_POST = "OPERATOR-POSTFIX";
14
+ export declare const WSPACE = "WHITE-SPACE";
15
+ type TokenType = typeof LITERAL | typeof OPERAND | typeof FUNC | typeof ARRAY | typeof PAREN | typeof SEP | typeof OP_PRE | typeof OP_IN | typeof OP_POST | typeof WSPACE;
16
+ export declare const TEXT = "TEXT";
17
+ export declare const NUMBER = "NUMBER";
18
+ export declare const LOGICAL = "LOGICAL";
19
+ export declare const ERROR = "ERROR";
20
+ export declare const RANGE = "RANGE";
21
+ export declare const OPEN = "OPEN";
22
+ export declare const CLOSE = "CLOSE";
23
+ export declare const ARG = "ARG";
24
+ export declare const ROW = "ROW";
25
+ type TokenSubtype = '' | typeof TEXT | typeof NUMBER | typeof LOGICAL | typeof ERROR | typeof RANGE | typeof OPEN | typeof CLOSE | typeof ARG | typeof ROW;
26
+ export interface Token {
27
+ value: string;
28
+ type: TokenType;
29
+ subtype: TokenSubtype;
30
+ }
31
+ /** Build an OPERAND token, deriving the subtype from the value's shape. */
32
+ export declare function makeOperand(value: string): Token;
33
+ /**
34
+ * Build a "subexpression" token (FUNC / PAREN / ARRAY, OPEN or CLOSE).
35
+ *
36
+ * `value` must end with one of `{ } ( )`. If `func` is true, the type is forced
37
+ * to FUNC regardless of the bare-bracket heuristic — mirrors the `func=True`
38
+ * overload in openpyxl `Token.make_subexp`.
39
+ */
40
+ export declare function makeSubexp(value: string, func?: boolean): Token;
41
+ /** Build a SEP token (',' → ARG, ';' → ROW). */
42
+ export declare function makeSeparator(value: ',' | ';'): Token;
43
+ /** Scientific-notation guard: matches a coefficient ending in `[Ee]`. */
44
+ export declare const SN_RE: RegExp;
45
+ /** Whitespace run (space + LF, per Excel formula whitespace rules). */
46
+ export declare const WSPACE_RE: RegExp;
47
+ /** "..."-delimited string literal. Internal `""` is an escaped quote. */
48
+ export declare const STRING_DOUBLE_RE: RegExp;
49
+ /** '...'-delimited link / sheet name. Internal `''` is an escaped apostrophe. */
50
+ export declare const STRING_SINGLE_RE: RegExp;
51
+ /**
52
+ * Tokenize a formula string into a flat list of `Token`s.
53
+ *
54
+ * Mirrors `openpyxl.formula.tokenizer.Tokenizer(formula).items`. A formula that
55
+ * does not start with `=` becomes a single LITERAL token. Empty input yields
56
+ * the empty array.
57
+ */
58
+ export declare function tokenize(formula: string): Token[];
59
+ /** Render a token list back into the original formula string. */
60
+ export declare function renderTokens(items: ReadonlyArray<Token>): string;
61
+ export {};
@@ -0,0 +1,67 @@
1
+ import { OpenXmlError } from '../utils/exceptions';
2
+ import { type Token } from './tokenizer';
3
+ export declare class TranslatorError extends OpenXmlError {
4
+ readonly name = "TranslatorError";
5
+ }
6
+ /** `1:1`, `$1234:78910`, etc. — pure-row range. */
7
+ export declare const ROW_RANGE_RE: RegExp;
8
+ /** `A:A`, `$ABC:AZZ` — pure-column range. */
9
+ export declare const COL_RANGE_RE: RegExp;
10
+ /** `A1`, `$AB$15` — single cell ref. */
11
+ export declare const CELL_REF_RE: RegExp;
12
+ /**
13
+ * Shift a row-snippet (`"3"` or `"$3"`) by `rdelta` rows. Absolute
14
+ * anchors return verbatim; falling below row 1 raises `TranslatorError`.
15
+ */
16
+ export declare function translateRow(rowStr: string, rdelta: number): string;
17
+ /**
18
+ * Shift a column-snippet (`"A"` or `"$A"`) by `cdelta` columns. Absolute
19
+ * anchors return verbatim; out-of-range raises `TranslatorError`.
20
+ */
21
+ export declare function translateCol(colStr: string, cdelta: number): string;
22
+ /**
23
+ * Split `Sheet!A1` into `["Sheet!", "A1"]`. Multi-`!` sheet names are not
24
+ * supported by Excel itself, so we just `rsplit('!', 1)`.
25
+ */
26
+ export declare function stripWsName(rangeStr: string): [string, string];
27
+ /**
28
+ * Translate an A1-style range reference (potentially worksheet-prefixed,
29
+ * potentially a named range) by `(rdelta, cdelta)`. Mirrors openpyxl
30
+ * `Translator.translate_range` exactly:
31
+ *
32
+ * - `1:1` / `$1234:78910` → row-range, only rows shift
33
+ * - `A:A` / `$ABC:AZZ` → col-range, only cols shift
34
+ * - `A1:B2` (with `:`) → recurse on each side, allowing named-range endpoints
35
+ * - `A1` → cell ref
36
+ * - anything else → assumed named range, returned verbatim
37
+ */
38
+ export declare function translateRange(rangeStr: string, rdelta: number, cdelta: number): string;
39
+ export interface TranslateOptions {
40
+ /** Destination cell address ("B2"). When set, derives `rowDelta`/`colDelta` from `origin`. */
41
+ dest?: string;
42
+ /** Explicit row delta. Ignored if `dest` is provided. */
43
+ rowDelta?: number;
44
+ /** Explicit col delta. Ignored if `dest` is provided. */
45
+ colDelta?: number;
46
+ }
47
+ /**
48
+ * Translate `formula` (defined at `origin`, e.g. "A1") to its destination
49
+ * cell. Pass either `{ dest }` or `{ rowDelta, colDelta }`. LITERAL
50
+ * formulas (input that does not start with `=`) and empty input pass
51
+ * through untouched.
52
+ */
53
+ export declare function translateFormula(formula: string, origin: string, opts?: TranslateOptions): string;
54
+ /**
55
+ * Convenience: tokenize once, expose the parsed list + the same translate
56
+ * helpers bound to a fixed origin. Mirrors openpyxl's `Translator` object.
57
+ */
58
+ export interface Translator {
59
+ formula: string;
60
+ origin: string;
61
+ row: number;
62
+ col: number;
63
+ tokens: Token[];
64
+ }
65
+ export declare function makeTranslator(formula: string, origin: string): Translator;
66
+ /** Render the translator's tokens back to the source string (sanity check). */
67
+ export declare function translatorRender(t: Translator): string;
@@ -0,0 +1,42 @@
1
+ //#region src/utils/inference.ts
2
+ /** Excel error tokens. Anything outside this set is treated as a string. */
3
+ const ERROR_CODES = new Set([
4
+ "#NULL!",
5
+ "#DIV/0!",
6
+ "#VALUE!",
7
+ "#REF!",
8
+ "#NAME?",
9
+ "#NUM!",
10
+ "#N/A",
11
+ "#GETTING_DATA"
12
+ ]);
13
+ /**
14
+ * Infer the cell `t` attribute for a runtime value.
15
+ *
16
+ * - `boolean` → 'b'
17
+ * - `number` → 'n' (incl. integer numerics; date inference is left to
18
+ * the caller because Excel decides on type via the cell's number
19
+ * format, not the raw value)
20
+ * - `Date` → 'd'
21
+ * - string starting with `=` → 'f' (formula)
22
+ * - string in {@link ERROR_CODES} → 'e'
23
+ * - any other string → 's'
24
+ * - `null` / `undefined` → 'n' (empty)
25
+ *
26
+ * Throws nothing — returns 'n' as the no-information fallback.
27
+ */
28
+ function inferCellType(value) {
29
+ if (typeof value === "boolean") return "b";
30
+ if (typeof value === "number") return "n";
31
+ if (value instanceof Date) return "d";
32
+ if (typeof value === "string") {
33
+ if (value.length > 0 && value.charCodeAt(0) === 61) return "f";
34
+ if (ERROR_CODES.has(value)) return "e";
35
+ return "s";
36
+ }
37
+ return "n";
38
+ }
39
+ //#endregion
40
+ export { inferCellType as n, ERROR_CODES as t };
41
+
42
+ //# sourceMappingURL=inference-B3ES3KEJ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inference-B3ES3KEJ.mjs","names":[],"sources":["../src/utils/inference.ts"],"sourcesContent":["// Cell-value type inference. Maps a JS runtime value to the OOXML cell\n// `t` attribute value. Mirrors openpyxl's `Cell._bind_value` /\n// `_TYPES` / error-code path in openpyxl/openpyxl/cell/cell.py.\n\n/**\n * OOXML `t` attribute values. Note that 'inlineStr' is treated\n * separately — the writer chooses between 's' (shared string) and\n * 'inlineStr' based on workbook settings, not the value itself.\n */\nexport type CellDataType = 'n' | 's' | 'b' | 'd' | 'f' | 'e';\n\n/** Excel error tokens. Anything outside this set is treated as a string. */\nexport const ERROR_CODES: ReadonlySet<string> = new Set([\n '#NULL!',\n '#DIV/0!',\n '#VALUE!',\n '#REF!',\n '#NAME?',\n '#NUM!',\n '#N/A',\n '#GETTING_DATA',\n]);\n\n/**\n * Infer the cell `t` attribute for a runtime value.\n *\n * - `boolean` → 'b'\n * - `number` → 'n' (incl. integer numerics; date inference is left to\n * the caller because Excel decides on type via the cell's number\n * format, not the raw value)\n * - `Date` → 'd'\n * - string starting with `=` → 'f' (formula)\n * - string in {@link ERROR_CODES} → 'e'\n * - any other string → 's'\n * - `null` / `undefined` → 'n' (empty)\n *\n * Throws nothing — returns 'n' as the no-information fallback.\n */\nexport function inferCellType(value: unknown): CellDataType {\n if (typeof value === 'boolean') return 'b';\n if (typeof value === 'number') return 'n';\n if (value instanceof Date) return 'd';\n if (typeof value === 'string') {\n if (value.length > 0 && value.charCodeAt(0) === 61 /* '=' */) return 'f';\n if (ERROR_CODES.has(value)) return 'e';\n return 's';\n }\n return 'n';\n}\n"],"mappings":";;AAYA,MAAa,cAAmC,IAAI,IAAI;CACtD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;;;;;;;;;;;;;;;AAiBD,SAAgB,cAAc,OAA8B;CAC1D,IAAI,OAAO,UAAU,WAAW,OAAO;CACvC,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI,iBAAiB,MAAM,OAAO;CAClC,IAAI,OAAO,UAAU,UAAU;EAC7B,IAAI,MAAM,SAAS,KAAK,MAAM,WAAW,CAAC,MAAM,IAAc,OAAO;EACrE,IAAI,YAAY,IAAI,KAAK,GAAG,OAAO;EACnC,OAAO;CACT;CACA,OAAO;AACT"}
@@ -0,0 +1,41 @@
1
+ import type { BufferedSinkWriter, XlsxSink } from './sink';
2
+ import type { XlsxSource } from './source';
3
+ /**
4
+ * Wrap a Blob (or File, since File extends Blob) as an XlsxSource. The
5
+ * source materialises bytes lazily on the first {@link XlsxSource.toBytes}
6
+ * call.
7
+ */
8
+ export declare function fromBlob(blob: Blob): XlsxSource;
9
+ /**
10
+ * Wrap a fetch {@link Response} as an XlsxSource. `toBytes` collects
11
+ * the entire response body via `Response.arrayBuffer()`; `toStream`
12
+ * returns `response.body` directly so the ZIP reader can pull chunks
13
+ * lazily from the network. The Response can have been fetched with
14
+ * any method and content-type; this helper does no validation.
15
+ */
16
+ export declare function fromResponse(response: Response): XlsxSource;
17
+ /**
18
+ * Wrap a Web {@link ReadableStream} of bytes as an XlsxSource. `toStream`
19
+ * returns the stream directly; `toBytes` drains it once and caches the
20
+ * bytes. Streams can only be consumed once — calling `toBytes` after
21
+ * `toStream` (or vice versa) on the same source throws.
22
+ */
23
+ export declare function fromStream(stream: ReadableStream<Uint8Array>): XlsxSource;
24
+ /**
25
+ * Wrap an ArrayBuffer or Uint8Array. The bytes are referenced (Uint8Array
26
+ * input) or wrapped without copy (ArrayBuffer input).
27
+ */
28
+ export declare function fromArrayBuffer(buf: ArrayBuffer | Uint8Array): XlsxSource;
29
+ /**
30
+ * In-memory Blob sink. Convenience `result()` returns the accumulated
31
+ * payload as a Blob with the supplied MIME type.
32
+ */
33
+ export declare function toBlob(mime?: string): XlsxSink & {
34
+ toBytes(): BufferedSinkWriter;
35
+ result(): Blob;
36
+ };
37
+ /** In-memory ArrayBuffer sink. */
38
+ export declare function toArrayBuffer(): XlsxSink & {
39
+ toBytes(): BufferedSinkWriter;
40
+ result(): ArrayBuffer;
41
+ };
@@ -0,0 +1,7 @@
1
+ export type { BufferedSinkWriter, XlsxSink } from './sink';
2
+ export type { XlsxSource } from './source';
3
+ export { fromArrayBuffer, fromBlob, fromResponse, fromStream, toArrayBuffer, toBlob, } from './browser';
4
+ export type { LoadOptions } from './load';
5
+ export { loadWorkbook } from './load';
6
+ export type { SaveOptions } from './save';
7
+ export { saveWorkbook, workbookToBytes } from './save';
@@ -0,0 +1,46 @@
1
+ import type { XlsxSource } from '../io/source';
2
+ import { type SheetState, type Workbook } from '../workbook/workbook';
3
+ import { type XmlNode } from '../xml/tree';
4
+ import type { DecompressionLimits } from '../zip/decompression-guard';
5
+ /**
6
+ * Options for {@link loadWorkbook}. Earlier drafts exposed `readOnly` /
7
+ * `keepLinks` / `keepVba` / `dataOnly` / `richText` placeholders that the
8
+ * loader silently ignored; those were removed to keep the surface honest.
9
+ * Future toggles land here once their behavior is implemented.
10
+ */
11
+ export interface LoadOptions {
12
+ /**
13
+ * Decompression-bomb safeguards applied while inflating zip entries.
14
+ * Defaults to limits that fit any legitimate xlsx; pass `false` to disable
15
+ * (only safe for fully trusted sources). See
16
+ * {@link DecompressionLimits} for the individual knobs.
17
+ */
18
+ decompressionLimits?: DecompressionLimits | false;
19
+ }
20
+ /**
21
+ * Resolve an OPC relationship target against its source part path.
22
+ *
23
+ * - Targets starting with `/` are package-absolute.
24
+ * - Otherwise the target is relative to the source part's parent directory.
25
+ * - `..` segments collapse normally.
26
+ */
27
+ export declare function resolveRelTarget(sourcePartPath: string, target: string): string;
28
+ interface SheetEntry {
29
+ /** Display name (`sheet/@name`). */
30
+ name: string;
31
+ /** Workbook-scope sheetId (`sheet/@sheetId`). */
32
+ sheetId: number;
33
+ /** Workbook rels Id (`sheet/@r:id`). */
34
+ rId: string;
35
+ /** Visibility state — defaults to `'visible'` when the attribute is absent. */
36
+ state: SheetState;
37
+ }
38
+ /** Extract the `<sheets>/<sheet>` entries from a parsed `xl/workbook.xml`. */
39
+ export declare function parseSheetEntries(workbookRoot: XmlNode): SheetEntry[];
40
+ /**
41
+ * Load a workbook from any {@link XlsxSource}. Currently produces a scaffold
42
+ * Workbook: each Worksheet is empty (no cells / styles / shared strings / theme
43
+ * yet). The next phase-3 iterations layer those in atop the same skeleton.
44
+ */
45
+ export declare function loadWorkbook(source: XlsxSource, opts?: LoadOptions): Promise<Workbook>;
46
+ export {};
@@ -0,0 +1,62 @@
1
+ import { Readable, Writable } from 'node:stream';
2
+ import type { BufferedSinkWriter, XlsxSink } from './sink';
3
+ import type { XlsxSource } from './source';
4
+ /**
5
+ * Wrap a filesystem path as an XlsxSource. `toBytes` reads the whole file into
6
+ * memory; `toStream` opens a `fs.createReadStream` and bridges it to a Web
7
+ * {@link ReadableStream} via `Readable.toWeb` so the ZIP reader can iterate
8
+ * without loading the entire xlsx up front.
9
+ */
10
+ export declare function fromFile(path: string): XlsxSource;
11
+ /**
12
+ * Synchronous variant of {@link fromFile}. Convenience for tooling / scripts
13
+ * where the cost of `await fs.readFile` outweighs the ergonomic gain. The
14
+ * returned source's `toBytes` resolves immediately with the bytes already in
15
+ * memory.
16
+ */
17
+ export declare function fromFileSync(path: string): XlsxSource;
18
+ /**
19
+ * Filesystem sink. Each `write(chunk)` call streams the bytes to disk via
20
+ * `fs.createWriteStream`, honouring backpressure: the actual `writable.write`
21
+ * for each chunk is queued behind any pending `drain`, so the writable's
22
+ * internal buffer never grows past its `highWaterMark` (default 16 KB) no
23
+ * matter how fast the producer hands chunks over.
24
+ *
25
+ * Note on the producer-side memory budget: the sink contract is
26
+ * intentionally synchronous (`write(chunk): void`), so a producer that races
27
+ * ahead without yielding will let chunk references pile up in the queue.
28
+ * That keeps `writable`'s buffer bounded but does not bound the queue
29
+ * itself. Producers that need a hard ceiling should yield between writes
30
+ * (`await new Promise(setImmediate)` is enough) or use a sink with an async
31
+ * write contract.
32
+ *
33
+ * `result()` returns the destination path; `finish()` resolves with an empty
34
+ * `Uint8Array` once the stream has flushed. Callers that need the on-disk
35
+ * bytes should `readFile()` the returned path themselves — re-reading inside
36
+ * `finish()` would defeat the "streamed to disk, never resident" guarantee.
37
+ */
38
+ export declare function toFile(path: string): XlsxSink & {
39
+ toBytes(): BufferedSinkWriter;
40
+ result(): string;
41
+ };
42
+ /**
43
+ * Wrap a Node.js {@link Readable} as an XlsxSource. `toBytes` consumes the
44
+ * entire stream synchronously (collecting chunks); `toStream` bridges to a Web
45
+ * ReadableStream via `Readable.toWeb` so the ZIP reader can pull chunks lazily.
46
+ */
47
+ export declare function fromReadable(readable: Readable): XlsxSource;
48
+ /**
49
+ * Wrap a Node.js {@link Writable} as an XlsxSink. The actual
50
+ * `writable.write` for each chunk is queued behind any pending `drain`, so
51
+ * the writable's internal buffer never exceeds its `highWaterMark` regardless
52
+ * of how fast the producer is. See {@link toFile} for the same caveat about
53
+ * producer-side memory: the synchronous `write(chunk)` API does not let
54
+ * backpressure flow back to the caller, so a tight non-yielding producer can
55
+ * still let chunk references accumulate in the queue.
56
+ *
57
+ * `result()` returns the writable itself for downstream chaining.
58
+ */
59
+ export declare function toWritable(writable: Writable): XlsxSink & {
60
+ toBytes(): BufferedSinkWriter;
61
+ result(): Writable;
62
+ };
@@ -0,0 +1,3 @@
1
+ import type { Workbook } from '../workbook/workbook';
2
+ import { type SaveOptions } from './save';
3
+ export declare function workbookToBuffer(wb: Workbook, opts?: SaveOptions): Promise<Buffer>;
@@ -0,0 +1,17 @@
1
+ import type { BufferedSinkWriter, XlsxSink } from './sink';
2
+ import type { XlsxSource } from './source';
3
+ /**
4
+ * Wrap a Buffer or Uint8Array as an XlsxSource. The underlying bytes are
5
+ * referenced — no copy — so callers must not mutate them while the source is in
6
+ * use.
7
+ */
8
+ export declare function fromBuffer(buf: Buffer | Uint8Array): XlsxSource;
9
+ /**
10
+ * In-memory Buffer sink. The buffered path concatenates appended chunks into a
11
+ * single allocation when {@link BufferedSinkWriter.finish} resolves; the
12
+ * convenience `result()` returns it as a Node Buffer.
13
+ */
14
+ export declare function toBuffer(): XlsxSink & {
15
+ toBytes(): BufferedSinkWriter;
16
+ result(): Buffer;
17
+ };
@@ -0,0 +1,14 @@
1
+ import type { XlsxSink } from '../io/sink';
2
+ import { type Workbook } from '../workbook/workbook';
3
+ export interface SaveOptions {
4
+ /** Reserved — passes through to the underlying ZIP writer when implemented. */
5
+ compressionLevel?: number;
6
+ }
7
+ /** Convenience: serialise a Workbook to an in-memory `Uint8Array` xlsx.
8
+ *
9
+ * Browser-safe: this path uses an in-memory `Uint8Array` sink and never
10
+ * touches Node's `Buffer` global, so it works unchanged in browser bundles.
11
+ */
12
+ export declare function workbookToBytes(wb: Workbook, opts?: SaveOptions): Promise<Uint8Array>;
13
+ /** Save a workbook through the given sink. Returns once `finalize()` resolves. */
14
+ export declare function saveWorkbook(wb: Workbook, sink: XlsxSink, _opts?: SaveOptions): Promise<void>;
@@ -0,0 +1,54 @@
1
+ export interface BufferedSinkWriter {
2
+ /** Append a chunk. Must not throw under normal use; errors surface in {@link finish}. */
3
+ write(chunk: Uint8Array): void;
4
+ /**
5
+ * Signal that no more chunks are coming. For in-memory sinks (`toBuffer` /
6
+ * `toBlob` / `toArrayBuffer`) the resolved `Uint8Array` is the full payload;
7
+ * for streaming sinks (`toFile` / `toWritable`) the resolved value is an
8
+ * empty `Uint8Array(0)` once the underlying writable has flushed — the bytes
9
+ * have already been forwarded to disk / the wrapped Writable and are
10
+ * deliberately not buffered for re-emission here. Read the destination via
11
+ * the sink's own `result()` instead.
12
+ */
13
+ finish(): Promise<Uint8Array>;
14
+ /**
15
+ * Abandon the writer. Called by the ZIP writer (and `saveWorkbook` /
16
+ * `loadWorkbookStream` writers) when the surrounding pipeline throws before
17
+ * `finish()` runs. Implementations must release any underlying resource:
18
+ * `toFile` destroys the Node `WriteStream` and best-effort removes the
19
+ * half-written file; `toWritable` destroys the wrapped Writable; in-memory
20
+ * sinks simply drop their buffered chunks.
21
+ *
22
+ * Idempotent. Must not throw — the surrounding catch already has the cause
23
+ * the caller cares about; obscuring it with a cleanup error helps nobody.
24
+ * Optional for backwards compatibility, but writers should provide it.
25
+ */
26
+ abort?(cause?: unknown): void | Promise<void>;
27
+ }
28
+ export interface XlsxSink {
29
+ /**
30
+ * Chunked-write API. Returns a writer with `write(chunk)` + `finish()`.
31
+ *
32
+ * The name is historical: this is the only entry the ZIP writer drives, and
33
+ * the underlying object can either accumulate chunks in memory (buffered
34
+ * sinks) or forward them to disk / a Writable as they arrive (streaming
35
+ * sinks). The ZIP writer never holds the full archive itself, so the choice
36
+ * of sink decides whether peak memory is "compressed archive size" or
37
+ * "single chunk + deflate scratch".
38
+ *
39
+ * Required: `createZipWriter` calls this on every sink. The method stayed
40
+ * `?:` historically while a `toStream()` alternative was being prototyped,
41
+ * but the streaming-WritableStream variant never landed and leaving it
42
+ * optional only masked the runtime "sink does not expose toBytes()" error
43
+ * behind a missing-property exception.
44
+ */
45
+ toBytes(): BufferedSinkWriter;
46
+ /**
47
+ * Streaming mode: returns a WritableStream into which the writer pipes
48
+ * chunks. Backpressure is honoured by the underlying sink. Currently
49
+ * unused by the ZIP writer (see {@link toBytes}); kept optional so that
50
+ * future writer paths can opt into a `WritableStream`-shaped backend
51
+ * without breaking existing sink implementations.
52
+ */
53
+ toStream?(): WritableStream<Uint8Array>;
54
+ }
@@ -0,0 +1,14 @@
1
+ export interface XlsxSource {
2
+ /**
3
+ * Resolve the full payload as a single Uint8Array. Memory-bounded; acceptable
4
+ * for all xlsx parts up to ~hundreds of MB. For larger payloads use {@link
5
+ * toStream}.
6
+ */
7
+ toBytes(): Promise<Uint8Array>;
8
+ /**
9
+ * Sequential byte stream. Optional — implementations that have no cheap
10
+ * streaming representation may omit it. Consumers should fall back to {@link
11
+ * toBytes} when undefined.
12
+ */
13
+ toStream?(): ReadableStream<Uint8Array>;
14
+ }