@cj-tech-master/excelts 9.5.4 → 9.5.5

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 (767) hide show
  1. package/dist/browser/modules/archive/compression/streaming-compress.browser.js +29 -0
  2. package/dist/browser/modules/archive/compression/streaming-compress.js +9 -0
  3. package/dist/browser/modules/archive/compression/worker-pool/pool.browser.js +26 -1
  4. package/dist/browser/modules/archive/fs/archive-file.d.ts +8 -5
  5. package/dist/browser/modules/archive/fs/archive-file.js +78 -16
  6. package/dist/browser/modules/archive/unzip/stream.browser.js +43 -2
  7. package/dist/browser/modules/excel/chart/chart-ex-builder.js +7 -2
  8. package/dist/browser/modules/excel/chart/chart-ex-renderer.js +4 -9
  9. package/dist/browser/modules/excel/chart/chart-ex-types.d.ts +0 -12
  10. package/dist/browser/modules/excel/chart/chart.d.ts +1 -5
  11. package/dist/browser/modules/excel/chart/chart.js +1 -7
  12. package/dist/browser/modules/excel/chart/types.d.ts +0 -6
  13. package/dist/browser/modules/excel/stream/workbook-reader.browser.js +25 -1
  14. package/dist/browser/modules/excel/stream/workbook-reader.js +9 -0
  15. package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +40 -0
  16. package/dist/browser/modules/excel/stream/workbook-writer.browser.js +228 -13
  17. package/dist/browser/modules/excel/utils/string-buf.d.ts +5 -26
  18. package/dist/browser/modules/excel/utils/string-buf.js +4 -81
  19. package/dist/browser/modules/excel/workbook.browser.js +135 -25
  20. package/dist/browser/modules/excel/xlsx/xform/chart/chart-space-xform.js +6 -20
  21. package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +19 -9
  22. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +32 -8
  23. package/dist/browser/modules/excel/xlsx/xlsx.d.ts +10 -2
  24. package/dist/browser/modules/excel/xlsx/xlsx.js +9 -1
  25. package/dist/browser/modules/pdf/excel-bridge.d.ts +30 -1
  26. package/dist/browser/modules/pdf/excel-bridge.js +32 -0
  27. package/dist/browser/modules/pdf/font/metrics.d.ts +3 -52
  28. package/dist/browser/modules/pdf/font/metrics.js +3 -237
  29. package/dist/browser/modules/pdf/index.d.ts +1 -1
  30. package/dist/browser/modules/pdf/index.js +1 -1
  31. package/dist/browser/modules/pdf/render-layout-to-pdf.d.ts +66 -0
  32. package/dist/browser/modules/pdf/render-layout-to-pdf.js +647 -0
  33. package/dist/browser/modules/pdf/word-bridge.d.ts +80 -12
  34. package/dist/browser/modules/pdf/word-bridge.js +122 -274
  35. package/dist/browser/modules/stream/index.base.d.ts +2 -0
  36. package/dist/browser/modules/stream/index.base.js +2 -1
  37. package/dist/browser/modules/stream/internal/sink-adapter.d.ts +65 -0
  38. package/dist/browser/modules/stream/internal/sink-adapter.js +198 -0
  39. package/dist/browser/modules/stream/pull-stream.d.ts +19 -2
  40. package/dist/browser/modules/stream/pull-stream.js +51 -5
  41. package/dist/browser/modules/stream/types.d.ts +13 -1
  42. package/dist/browser/modules/word/advanced/diff.d.ts +61 -0
  43. package/dist/browser/modules/word/advanced/diff.js +167 -0
  44. package/dist/browser/modules/word/advanced/drawing-shapes.d.ts +269 -0
  45. package/dist/browser/modules/word/advanced/drawing-shapes.js +268 -0
  46. package/dist/browser/modules/word/advanced/field-engine.d.ts +43 -0
  47. package/dist/browser/modules/word/advanced/field-engine.js +1225 -0
  48. package/dist/browser/modules/word/advanced/glossary.d.ts +86 -0
  49. package/dist/browser/modules/word/advanced/glossary.js +79 -0
  50. package/dist/browser/modules/word/advanced/math-convert.d.ts +30 -0
  51. package/dist/browser/modules/word/advanced/math-convert.js +595 -0
  52. package/dist/browser/modules/word/advanced/ole-objects.d.ts +115 -0
  53. package/dist/browser/modules/word/advanced/ole-objects.js +271 -0
  54. package/dist/browser/modules/word/advanced/style-map.d.ts +105 -0
  55. package/dist/browser/modules/word/advanced/style-map.js +322 -0
  56. package/dist/browser/modules/word/advanced/validation.d.ts +56 -0
  57. package/dist/browser/modules/word/advanced/validation.js +1065 -0
  58. package/dist/browser/modules/word/advanced/vba-project.d.ts +91 -0
  59. package/dist/browser/modules/word/advanced/vba-project.js +265 -0
  60. package/dist/browser/modules/word/bridge/excel-bridge.d.ts +127 -0
  61. package/dist/browser/modules/word/bridge/excel-bridge.js +980 -0
  62. package/dist/browser/modules/word/builder/document-handle.d.ts +151 -0
  63. package/dist/browser/modules/word/builder/document-handle.js +664 -0
  64. package/dist/browser/modules/word/builder/paragraph-builders.d.ts +61 -0
  65. package/dist/browser/modules/word/builder/paragraph-builders.js +90 -0
  66. package/dist/browser/modules/word/builder/run-builders.d.ts +374 -0
  67. package/dist/browser/modules/word/builder/run-builders.js +600 -0
  68. package/dist/browser/modules/word/builder/table-builders.d.ts +23 -0
  69. package/dist/browser/modules/word/builder/table-builders.js +45 -0
  70. package/dist/browser/modules/word/constants.d.ts +39 -1
  71. package/dist/browser/modules/word/constants.js +109 -1
  72. package/dist/browser/modules/word/convert/conversion-ir.d.ts +210 -0
  73. package/dist/browser/modules/word/convert/conversion-ir.js +31 -0
  74. package/dist/browser/modules/word/convert/docx-to-semantic.d.ts +39 -0
  75. package/dist/browser/modules/word/convert/docx-to-semantic.js +499 -0
  76. package/dist/browser/modules/word/convert/flat-opc.d.ts +44 -0
  77. package/dist/browser/modules/word/convert/flat-opc.js +385 -0
  78. package/dist/browser/modules/word/convert/html/html-import.d.ts +50 -0
  79. package/dist/browser/modules/word/convert/html/html-import.js +1907 -0
  80. package/dist/{types/modules/word → browser/modules/word/convert/html}/html-renderer.d.ts +14 -1
  81. package/dist/{esm/modules/word → browser/modules/word/convert/html}/html-renderer.js +420 -69
  82. package/dist/browser/modules/word/convert/html/html.d.ts +15 -0
  83. package/dist/browser/modules/word/convert/html/html.js +15 -0
  84. package/dist/browser/modules/word/convert/markdown/markdown-import.d.ts +68 -0
  85. package/dist/browser/modules/word/convert/markdown/markdown-import.js +1325 -0
  86. package/dist/browser/modules/word/convert/markdown/markdown-renderer.d.ts +25 -0
  87. package/dist/browser/modules/word/convert/markdown/markdown-renderer.js +634 -0
  88. package/dist/browser/modules/word/convert/markdown/markdown.d.ts +15 -0
  89. package/dist/browser/modules/word/convert/markdown/markdown.js +15 -0
  90. package/dist/browser/modules/word/convert/odt/odt.d.ts +41 -0
  91. package/dist/browser/modules/word/convert/odt/odt.js +1932 -0
  92. package/dist/browser/modules/word/{color-utils.d.ts → core/color-utils.d.ts} +8 -1
  93. package/dist/browser/modules/word/core/color-utils.js +43 -0
  94. package/dist/browser/modules/word/core/internal-utils.d.ts +90 -0
  95. package/dist/browser/modules/word/core/internal-utils.js +209 -0
  96. package/dist/browser/modules/word/core/mapper.d.ts +44 -0
  97. package/dist/browser/modules/word/core/mapper.js +427 -0
  98. package/dist/browser/modules/word/core/opc-paths.d.ts +33 -0
  99. package/dist/browser/modules/word/core/opc-paths.js +48 -0
  100. package/dist/browser/modules/word/core/text-utils.d.ts +38 -0
  101. package/dist/browser/modules/word/core/text-utils.js +202 -0
  102. package/dist/browser/modules/word/core/walker.d.ts +119 -0
  103. package/dist/browser/modules/word/core/walker.js +570 -0
  104. package/dist/browser/modules/word/crypto.d.ts +14 -9
  105. package/dist/browser/modules/word/crypto.js +13 -7
  106. package/dist/browser/modules/word/document-io.d.ts +59 -27
  107. package/dist/browser/modules/word/document-io.js +80 -197
  108. package/dist/browser/modules/word/errors.d.ts +44 -1
  109. package/dist/browser/modules/word/errors.js +54 -2
  110. package/dist/browser/modules/word/excel.d.ts +14 -0
  111. package/dist/browser/modules/word/excel.js +13 -0
  112. package/dist/browser/modules/word/font/font-embed.d.ts +112 -0
  113. package/dist/browser/modules/word/font/font-embed.js +646 -0
  114. package/dist/{esm/modules/word → browser/modules/word/font}/font-obfuscation.js +4 -9
  115. package/dist/browser/modules/word/font/hyphenation.d.ts +65 -0
  116. package/dist/browser/modules/word/font/hyphenation.js +4210 -0
  117. package/dist/browser/modules/word/font/text-shaping.d.ts +58 -0
  118. package/dist/browser/modules/word/font/text-shaping.js +635 -0
  119. package/dist/browser/modules/word/html.d.ts +7 -6
  120. package/dist/browser/modules/word/html.js +6 -5
  121. package/dist/browser/modules/word/incremental-edit.d.ts +123 -0
  122. package/dist/browser/modules/word/incremental-edit.js +361 -0
  123. package/dist/browser/modules/word/index.base.d.ts +194 -10
  124. package/dist/browser/modules/word/index.base.js +138 -29
  125. package/dist/browser/modules/word/layout/layout-constants.d.ts +17 -0
  126. package/dist/browser/modules/word/layout/layout-constants.js +17 -0
  127. package/dist/browser/modules/word/layout/layout-full.d.ts +53 -0
  128. package/dist/browser/modules/word/layout/layout-full.js +1696 -0
  129. package/dist/browser/modules/word/layout/layout-model.d.ts +344 -0
  130. package/dist/browser/modules/word/layout/layout-model.js +16 -0
  131. package/dist/browser/modules/word/layout/layout.d.ts +63 -0
  132. package/dist/browser/modules/word/layout/layout.js +1167 -0
  133. package/dist/browser/modules/word/layout/render-page.d.ts +57 -0
  134. package/dist/browser/modules/word/layout/render-page.js +1238 -0
  135. package/dist/browser/modules/word/markdown.d.ts +14 -0
  136. package/dist/browser/modules/word/markdown.js +13 -0
  137. package/dist/browser/modules/word/patcher.d.ts +62 -0
  138. package/dist/browser/modules/word/patcher.js +537 -0
  139. package/dist/browser/modules/word/query/compat.d.ts +25 -0
  140. package/dist/browser/modules/word/query/compat.js +58 -0
  141. package/dist/browser/modules/word/query/data-binding.d.ts +22 -0
  142. package/dist/browser/modules/word/query/data-binding.js +392 -0
  143. package/dist/browser/modules/word/query/form-fields.d.ts +41 -0
  144. package/dist/browser/modules/word/query/form-fields.js +268 -0
  145. package/dist/browser/modules/word/query/format-search.d.ts +99 -0
  146. package/dist/browser/modules/word/query/format-search.js +329 -0
  147. package/dist/browser/modules/word/query/mail-merge.d.ts +25 -0
  148. package/dist/browser/modules/word/query/mail-merge.js +111 -0
  149. package/dist/browser/modules/word/query/merge.d.ts +50 -0
  150. package/dist/browser/modules/word/query/merge.js +617 -0
  151. package/dist/browser/modules/word/query/replace.d.ts +47 -0
  152. package/dist/browser/modules/word/query/replace.js +301 -0
  153. package/dist/browser/modules/word/query/revisions.d.ts +67 -0
  154. package/dist/browser/modules/word/query/revisions.js +879 -0
  155. package/dist/browser/modules/word/query/search.d.ts +129 -0
  156. package/dist/browser/modules/word/query/search.js +346 -0
  157. package/dist/browser/modules/word/query/split.d.ts +44 -0
  158. package/dist/browser/modules/word/query/split.js +135 -0
  159. package/dist/browser/modules/word/query/style-resolve.d.ts +104 -0
  160. package/dist/browser/modules/word/query/style-resolve.js +368 -0
  161. package/dist/browser/modules/word/reader/chart-parser.d.ts +20 -0
  162. package/dist/browser/modules/word/reader/chart-parser.js +810 -0
  163. package/dist/browser/modules/word/reader/comments-parser.d.ts +26 -0
  164. package/dist/browser/modules/word/reader/comments-parser.js +92 -0
  165. package/dist/browser/modules/word/reader/doc-props-parsers.d.ts +15 -0
  166. package/dist/browser/modules/word/reader/doc-props-parsers.js +190 -0
  167. package/dist/browser/modules/word/reader/docx-reader.d.ts +27 -0
  168. package/dist/browser/modules/word/reader/docx-reader.js +2557 -0
  169. package/dist/browser/modules/word/reader/drawing-helpers.d.ts +27 -0
  170. package/dist/browser/modules/word/reader/drawing-helpers.js +84 -0
  171. package/dist/browser/modules/word/reader/form-field-parser.d.ts +21 -0
  172. package/dist/browser/modules/word/reader/form-field-parser.js +82 -0
  173. package/dist/browser/modules/word/reader/image-parsers.d.ts +11 -0
  174. package/dist/browser/modules/word/reader/image-parsers.js +291 -0
  175. package/dist/browser/modules/word/reader/math-parser.d.ts +12 -0
  176. package/dist/browser/modules/word/reader/math-parser.js +422 -0
  177. package/dist/browser/modules/word/reader/metadata-parsers.d.ts +17 -0
  178. package/dist/browser/modules/word/reader/metadata-parsers.js +87 -0
  179. package/dist/browser/modules/word/reader/numbering-parser.d.ts +13 -0
  180. package/dist/browser/modules/word/reader/numbering-parser.js +166 -0
  181. package/dist/browser/modules/word/reader/paragraph-section-parsers.d.ts +12 -0
  182. package/dist/browser/modules/word/reader/paragraph-section-parsers.js +503 -0
  183. package/dist/browser/modules/word/reader/parse-utils.d.ts +91 -0
  184. package/dist/browser/modules/word/reader/parse-utils.js +249 -0
  185. package/dist/browser/modules/word/reader/properties-parsers.d.ts +21 -0
  186. package/dist/browser/modules/word/reader/properties-parsers.js +332 -0
  187. package/dist/browser/modules/word/reader/reader-context.d.ts +69 -0
  188. package/dist/browser/modules/word/reader/reader-context.js +61 -0
  189. package/dist/browser/modules/word/reader/sdt-helpers.d.ts +29 -0
  190. package/dist/browser/modules/word/reader/sdt-helpers.js +111 -0
  191. package/dist/browser/modules/word/reader/settings-parser.d.ts +8 -0
  192. package/dist/browser/modules/word/reader/settings-parser.js +263 -0
  193. package/dist/browser/modules/word/reader/styles-parser.d.ts +12 -0
  194. package/dist/browser/modules/word/reader/styles-parser.js +147 -0
  195. package/dist/browser/modules/word/reader/table-properties-parsers.d.ts +12 -0
  196. package/dist/browser/modules/word/reader/table-properties-parsers.js +234 -0
  197. package/dist/browser/modules/word/reader/theme-parser.d.ts +8 -0
  198. package/dist/browser/modules/word/reader/theme-parser.js +167 -0
  199. package/dist/browser/modules/word/reader/watermark-parser.d.ts +15 -0
  200. package/dist/browser/modules/word/reader/watermark-parser.js +110 -0
  201. package/dist/browser/modules/word/security/cfb-reader.d.ts +37 -0
  202. package/dist/browser/modules/word/security/cfb-reader.js +410 -0
  203. package/dist/browser/modules/word/{digital-signatures.d.ts → security/digital-signatures.d.ts} +19 -11
  204. package/dist/browser/modules/word/{digital-signatures.js → security/digital-signatures.js} +34 -34
  205. package/dist/browser/modules/word/security/document-protection.d.ts +93 -0
  206. package/dist/browser/modules/word/security/document-protection.js +201 -0
  207. package/dist/{types/modules/word → browser/modules/word/security}/encryption.d.ts +51 -4
  208. package/dist/browser/modules/word/security/encryption.js +602 -0
  209. package/dist/browser/modules/word/security/policy.d.ts +80 -0
  210. package/dist/browser/modules/word/security/policy.js +102 -0
  211. package/dist/browser/modules/word/template/template-chart.d.ts +56 -0
  212. package/dist/browser/modules/word/template/template-chart.js +167 -0
  213. package/dist/browser/modules/word/template/template-datasource.d.ts +154 -0
  214. package/dist/browser/modules/word/template/template-datasource.js +541 -0
  215. package/dist/browser/modules/word/template/template-engine.d.ts +121 -0
  216. package/dist/browser/modules/word/template/template-engine.js +1435 -0
  217. package/dist/browser/modules/word/types.d.ts +224 -25
  218. package/dist/browser/modules/word/units.d.ts +26 -0
  219. package/dist/browser/modules/word/units.js +43 -14
  220. package/dist/browser/modules/word/{writers → writer}/chart-writer.js +164 -23
  221. package/dist/browser/modules/word/writer/checkbox-writer.d.ts +17 -0
  222. package/dist/browser/modules/word/writer/checkbox-writer.js +79 -0
  223. package/dist/{types/modules/word/writers → browser/modules/word/writer}/comment-writer.d.ts +2 -1
  224. package/dist/browser/modules/word/{writers → writer}/comment-writer.js +8 -6
  225. package/dist/browser/modules/word/writer/common-parts.d.ts +57 -0
  226. package/dist/browser/modules/word/writer/common-parts.js +101 -0
  227. package/dist/{types/modules/word → browser/modules/word/writer}/content-types.d.ts +2 -2
  228. package/dist/{esm/modules/word → browser/modules/word/writer}/content-types.js +14 -6
  229. package/dist/browser/modules/word/writer/document-writer.d.ts +24 -0
  230. package/dist/browser/modules/word/writer/document-writer.js +473 -0
  231. package/dist/browser/modules/word/writer/docx-packager.d.ts +35 -0
  232. package/dist/browser/modules/word/writer/docx-packager.js +1515 -0
  233. package/dist/{types/modules/word/writers → browser/modules/word/writer}/footnote-writer.d.ts +3 -2
  234. package/dist/{esm/modules/word/writers → browser/modules/word/writer}/footnote-writer.js +13 -10
  235. package/dist/{types/modules/word/writers → browser/modules/word/writer}/header-footer-writer.d.ts +3 -2
  236. package/dist/{esm/modules/word/writers → browser/modules/word/writer}/header-footer-writer.js +39 -21
  237. package/dist/{types/modules/word/writers → browser/modules/word/writer}/image-writer.d.ts +1 -1
  238. package/dist/browser/modules/word/{writers → writer}/image-writer.js +11 -7
  239. package/dist/browser/modules/word/writer/math-writer.d.ts +20 -0
  240. package/dist/{esm/modules/word/writers → browser/modules/word/writer}/math-writer.js +21 -1
  241. package/dist/browser/modules/word/{writers → writer}/numbering-writer.d.ts +1 -1
  242. package/dist/{esm/modules/word/writers → browser/modules/word/writer}/numbering-writer.js +11 -4
  243. package/dist/browser/modules/word/{writers → writer}/paragraph-writer.d.ts +2 -1
  244. package/dist/browser/modules/word/{writers → writer}/paragraph-writer.js +73 -38
  245. package/dist/browser/modules/word/{writers → writer}/parts-writer.d.ts +3 -3
  246. package/dist/{esm/modules/word/writers → browser/modules/word/writer}/parts-writer.js +91 -12
  247. package/dist/browser/modules/word/writer/reference-scanners.d.ts +42 -0
  248. package/dist/browser/modules/word/writer/reference-scanners.js +111 -0
  249. package/dist/browser/modules/word/writer/relationships.d.ts +52 -0
  250. package/dist/browser/modules/word/writer/relationships.js +117 -0
  251. package/dist/browser/modules/word/writer/render-context.d.ts +124 -0
  252. package/dist/browser/modules/word/writer/render-context.js +46 -0
  253. package/dist/browser/modules/word/{writers → writer}/run-writer.d.ts +10 -1
  254. package/dist/{esm/modules/word/writers → browser/modules/word/writer}/run-writer.js +126 -24
  255. package/dist/browser/modules/word/writer/sdt-writer.d.ts +25 -0
  256. package/dist/browser/modules/word/writer/sdt-writer.js +189 -0
  257. package/dist/browser/modules/word/writer/stream-buf.d.ts +37 -0
  258. package/dist/browser/modules/word/writer/stream-buf.js +73 -0
  259. package/dist/browser/modules/word/writer/streaming-writer.d.ts +344 -0
  260. package/dist/browser/modules/word/writer/streaming-writer.js +1382 -0
  261. package/dist/browser/modules/word/writer/string-buf.d.ts +8 -0
  262. package/dist/browser/modules/word/writer/string-buf.js +7 -0
  263. package/dist/browser/modules/word/{writers → writer}/styles-writer.js +32 -1
  264. package/dist/browser/modules/word/{writers → writer}/table-writer.d.ts +2 -1
  265. package/dist/browser/modules/word/{writers → writer}/table-writer.js +94 -11
  266. package/dist/browser/modules/xml/types.d.ts +22 -0
  267. package/dist/browser/utils/crypto.browser.d.ts +3 -1
  268. package/dist/browser/utils/crypto.browser.js +3 -1
  269. package/dist/browser/utils/crypto.d.ts +4 -1
  270. package/dist/browser/utils/crypto.js +4 -1
  271. package/dist/browser/utils/font-metrics.d.ts +63 -0
  272. package/dist/browser/utils/font-metrics.js +293 -0
  273. package/dist/browser/utils/string-buf.d.ts +42 -0
  274. package/dist/browser/utils/string-buf.js +89 -0
  275. package/dist/browser/utils/theme-colors.d.ts +55 -0
  276. package/dist/browser/utils/theme-colors.js +120 -0
  277. package/dist/cjs/modules/archive/compression/streaming-compress.browser.js +29 -0
  278. package/dist/cjs/modules/archive/compression/streaming-compress.js +9 -0
  279. package/dist/cjs/modules/archive/compression/worker-pool/pool.browser.js +26 -1
  280. package/dist/cjs/modules/archive/fs/archive-file.js +78 -16
  281. package/dist/cjs/modules/archive/unzip/stream.browser.js +43 -2
  282. package/dist/cjs/modules/excel/chart/chart-ex-builder.js +7 -2
  283. package/dist/cjs/modules/excel/chart/chart-ex-renderer.js +4 -9
  284. package/dist/cjs/modules/excel/chart/chart.js +1 -7
  285. package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +25 -1
  286. package/dist/cjs/modules/excel/stream/workbook-reader.js +9 -0
  287. package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +228 -13
  288. package/dist/cjs/modules/excel/utils/string-buf.js +5 -81
  289. package/dist/cjs/modules/excel/workbook.browser.js +135 -25
  290. package/dist/cjs/modules/excel/xlsx/xform/chart/chart-space-xform.js +6 -20
  291. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +32 -8
  292. package/dist/cjs/modules/excel/xlsx/xlsx.js +9 -1
  293. package/dist/cjs/modules/pdf/excel-bridge.js +33 -0
  294. package/dist/cjs/modules/pdf/font/metrics.js +11 -244
  295. package/dist/cjs/modules/pdf/index.js +2 -1
  296. package/dist/cjs/modules/pdf/render-layout-to-pdf.js +651 -0
  297. package/dist/cjs/modules/pdf/word-bridge.js +155 -274
  298. package/dist/cjs/modules/stream/index.base.js +4 -2
  299. package/dist/cjs/modules/stream/internal/sink-adapter.js +202 -0
  300. package/dist/cjs/modules/stream/pull-stream.js +51 -5
  301. package/dist/cjs/modules/word/advanced/diff.js +170 -0
  302. package/dist/cjs/modules/word/advanced/drawing-shapes.js +279 -0
  303. package/dist/cjs/modules/word/advanced/field-engine.js +1229 -0
  304. package/dist/cjs/modules/word/advanced/glossary.js +87 -0
  305. package/dist/cjs/modules/word/advanced/math-convert.js +599 -0
  306. package/dist/cjs/modules/word/advanced/ole-objects.js +277 -0
  307. package/dist/cjs/modules/word/advanced/style-map.js +329 -0
  308. package/dist/cjs/modules/word/advanced/validation.js +1068 -0
  309. package/dist/cjs/modules/word/advanced/vba-project.js +274 -0
  310. package/dist/cjs/modules/word/bridge/excel-bridge.js +1020 -0
  311. package/dist/cjs/modules/word/builder/document-handle.js +667 -0
  312. package/dist/cjs/modules/word/builder/paragraph-builders.js +109 -0
  313. package/dist/cjs/modules/word/builder/run-builders.js +676 -0
  314. package/dist/cjs/modules/word/builder/table-builders.js +53 -0
  315. package/dist/cjs/modules/word/constants.js +111 -2
  316. package/dist/cjs/modules/word/convert/conversion-ir.js +34 -0
  317. package/dist/cjs/modules/word/convert/docx-to-semantic.js +502 -0
  318. package/dist/cjs/modules/word/convert/flat-opc.js +390 -0
  319. package/dist/cjs/modules/word/convert/html/html-import.js +1910 -0
  320. package/dist/cjs/modules/word/{html-renderer.js → convert/html/html-renderer.js} +420 -69
  321. package/dist/cjs/modules/word/convert/html/html.js +20 -0
  322. package/dist/cjs/modules/word/convert/markdown/markdown-import.js +1329 -0
  323. package/dist/cjs/modules/word/convert/markdown/markdown-renderer.js +637 -0
  324. package/dist/cjs/modules/word/convert/markdown/markdown.js +21 -0
  325. package/dist/cjs/modules/word/convert/odt/odt.js +1936 -0
  326. package/dist/cjs/modules/word/core/color-utils.js +47 -0
  327. package/dist/cjs/modules/word/core/internal-utils.js +219 -0
  328. package/dist/cjs/modules/word/core/mapper.js +430 -0
  329. package/dist/cjs/modules/word/core/opc-paths.js +53 -0
  330. package/dist/cjs/modules/word/core/text-utils.js +210 -0
  331. package/dist/cjs/modules/word/core/walker.js +577 -0
  332. package/dist/cjs/modules/word/crypto.js +19 -8
  333. package/dist/cjs/modules/word/document-io.js +117 -197
  334. package/dist/cjs/modules/word/errors.js +59 -13
  335. package/dist/cjs/modules/word/excel.js +22 -0
  336. package/dist/cjs/modules/word/font/font-embed.js +652 -0
  337. package/dist/cjs/modules/word/{font-obfuscation.js → font/font-obfuscation.js} +4 -9
  338. package/dist/cjs/modules/word/font/hyphenation.js +4216 -0
  339. package/dist/cjs/modules/word/font/text-shaping.js +640 -0
  340. package/dist/cjs/modules/word/html.js +9 -7
  341. package/dist/cjs/modules/word/incremental-edit.js +366 -0
  342. package/dist/cjs/modules/word/index.base.js +370 -137
  343. package/dist/cjs/modules/word/layout/layout-constants.js +20 -0
  344. package/dist/cjs/modules/word/layout/layout-full.js +1699 -0
  345. package/dist/cjs/modules/word/layout/layout-model.js +17 -0
  346. package/dist/cjs/modules/word/layout/layout.js +1170 -0
  347. package/dist/cjs/modules/word/layout/render-page.js +1243 -0
  348. package/dist/cjs/modules/word/markdown.js +19 -0
  349. package/dist/cjs/modules/word/patcher.js +539 -0
  350. package/dist/cjs/modules/word/query/compat.js +61 -0
  351. package/dist/cjs/modules/word/query/data-binding.js +395 -0
  352. package/dist/cjs/modules/word/query/form-fields.js +272 -0
  353. package/dist/cjs/modules/word/query/format-search.js +334 -0
  354. package/dist/cjs/modules/word/query/mail-merge.js +114 -0
  355. package/dist/cjs/modules/word/query/merge.js +620 -0
  356. package/dist/cjs/modules/word/query/replace.js +304 -0
  357. package/dist/cjs/modules/word/query/revisions.js +885 -0
  358. package/dist/cjs/modules/word/query/search.js +361 -0
  359. package/dist/cjs/modules/word/query/split.js +138 -0
  360. package/dist/cjs/modules/word/query/style-resolve.js +374 -0
  361. package/dist/cjs/modules/word/reader/chart-parser.js +814 -0
  362. package/dist/cjs/modules/word/reader/comments-parser.js +96 -0
  363. package/dist/cjs/modules/word/reader/doc-props-parsers.js +194 -0
  364. package/dist/cjs/modules/word/reader/docx-reader.js +2560 -0
  365. package/dist/cjs/modules/word/reader/drawing-helpers.js +90 -0
  366. package/dist/cjs/modules/word/reader/form-field-parser.js +85 -0
  367. package/dist/cjs/modules/word/reader/image-parsers.js +293 -0
  368. package/dist/cjs/modules/word/reader/math-parser.js +424 -0
  369. package/dist/cjs/modules/word/reader/metadata-parsers.js +93 -0
  370. package/dist/cjs/modules/word/reader/numbering-parser.js +168 -0
  371. package/dist/cjs/modules/word/reader/paragraph-section-parsers.js +505 -0
  372. package/dist/cjs/modules/word/reader/parse-utils.js +271 -0
  373. package/dist/cjs/modules/word/reader/properties-parsers.js +338 -0
  374. package/dist/cjs/modules/word/reader/reader-context.js +66 -0
  375. package/dist/cjs/modules/word/reader/sdt-helpers.js +114 -0
  376. package/dist/cjs/modules/word/reader/settings-parser.js +265 -0
  377. package/dist/cjs/modules/word/reader/styles-parser.js +149 -0
  378. package/dist/cjs/modules/word/reader/table-properties-parsers.js +237 -0
  379. package/dist/cjs/modules/word/reader/theme-parser.js +169 -0
  380. package/dist/cjs/modules/word/reader/watermark-parser.js +113 -0
  381. package/dist/cjs/modules/word/security/cfb-reader.js +414 -0
  382. package/dist/cjs/modules/word/{digital-signatures.js → security/digital-signatures.js} +34 -34
  383. package/dist/cjs/modules/word/security/document-protection.js +208 -0
  384. package/dist/cjs/modules/word/security/encryption.js +612 -0
  385. package/dist/cjs/modules/word/security/policy.js +106 -0
  386. package/dist/cjs/modules/word/template/template-chart.js +170 -0
  387. package/dist/cjs/modules/word/template/template-datasource.js +549 -0
  388. package/dist/cjs/modules/word/template/template-engine.js +1430 -0
  389. package/dist/cjs/modules/word/units.js +44 -14
  390. package/dist/cjs/modules/word/{writers → writer}/chart-writer.js +163 -22
  391. package/dist/cjs/modules/word/writer/checkbox-writer.js +82 -0
  392. package/dist/cjs/modules/word/{writers → writer}/comment-writer.js +8 -6
  393. package/dist/cjs/modules/word/writer/common-parts.js +104 -0
  394. package/dist/cjs/modules/word/{content-types.js → writer/content-types.js} +14 -6
  395. package/dist/cjs/modules/word/writer/document-writer.js +478 -0
  396. package/dist/cjs/modules/word/writer/docx-packager.js +1551 -0
  397. package/dist/cjs/modules/word/{writers → writer}/footnote-writer.js +13 -10
  398. package/dist/cjs/modules/word/{writers → writer}/header-footer-writer.js +38 -20
  399. package/dist/cjs/modules/word/{writers → writer}/image-writer.js +11 -7
  400. package/dist/cjs/modules/word/{writers → writer}/math-writer.js +21 -1
  401. package/dist/cjs/modules/word/{writers → writer}/numbering-writer.js +11 -4
  402. package/dist/cjs/modules/word/{writers → writer}/paragraph-writer.js +72 -37
  403. package/dist/cjs/modules/word/{writers → writer}/parts-writer.js +91 -12
  404. package/dist/cjs/modules/word/writer/reference-scanners.js +120 -0
  405. package/dist/cjs/modules/word/writer/relationships.js +124 -0
  406. package/dist/cjs/modules/word/writer/render-context.js +51 -0
  407. package/dist/cjs/modules/word/{writers → writer}/run-writer.js +127 -24
  408. package/dist/cjs/modules/word/writer/sdt-writer.js +192 -0
  409. package/dist/cjs/modules/word/writer/stream-buf.js +76 -0
  410. package/dist/cjs/modules/word/writer/streaming-writer.js +1387 -0
  411. package/dist/cjs/modules/word/writer/string-buf.js +11 -0
  412. package/dist/cjs/modules/word/{writers → writer}/styles-writer.js +32 -1
  413. package/dist/cjs/modules/word/{writers → writer}/table-writer.js +94 -11
  414. package/dist/cjs/utils/crypto.browser.js +3 -1
  415. package/dist/cjs/utils/crypto.js +4 -1
  416. package/dist/cjs/utils/font-metrics.js +303 -0
  417. package/dist/cjs/utils/string-buf.js +92 -0
  418. package/dist/cjs/utils/theme-colors.js +126 -0
  419. package/dist/esm/modules/archive/compression/streaming-compress.browser.js +29 -0
  420. package/dist/esm/modules/archive/compression/streaming-compress.js +9 -0
  421. package/dist/esm/modules/archive/compression/worker-pool/pool.browser.js +26 -1
  422. package/dist/esm/modules/archive/fs/archive-file.js +78 -16
  423. package/dist/esm/modules/archive/unzip/stream.browser.js +43 -2
  424. package/dist/esm/modules/excel/chart/chart-ex-builder.js +7 -2
  425. package/dist/esm/modules/excel/chart/chart-ex-renderer.js +4 -9
  426. package/dist/esm/modules/excel/chart/chart.js +1 -7
  427. package/dist/esm/modules/excel/stream/workbook-reader.browser.js +25 -1
  428. package/dist/esm/modules/excel/stream/workbook-reader.js +9 -0
  429. package/dist/esm/modules/excel/stream/workbook-writer.browser.js +228 -13
  430. package/dist/esm/modules/excel/utils/string-buf.js +4 -81
  431. package/dist/esm/modules/excel/workbook.browser.js +135 -25
  432. package/dist/esm/modules/excel/xlsx/xform/chart/chart-space-xform.js +6 -20
  433. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +32 -8
  434. package/dist/esm/modules/excel/xlsx/xlsx.js +9 -1
  435. package/dist/esm/modules/pdf/excel-bridge.js +32 -0
  436. package/dist/esm/modules/pdf/font/metrics.js +3 -237
  437. package/dist/esm/modules/pdf/index.js +1 -1
  438. package/dist/esm/modules/pdf/render-layout-to-pdf.js +647 -0
  439. package/dist/esm/modules/pdf/word-bridge.js +122 -274
  440. package/dist/esm/modules/stream/index.base.js +2 -1
  441. package/dist/esm/modules/stream/internal/sink-adapter.js +198 -0
  442. package/dist/esm/modules/stream/pull-stream.js +51 -5
  443. package/dist/esm/modules/word/advanced/diff.js +167 -0
  444. package/dist/esm/modules/word/advanced/drawing-shapes.js +268 -0
  445. package/dist/esm/modules/word/advanced/field-engine.js +1225 -0
  446. package/dist/esm/modules/word/advanced/glossary.js +79 -0
  447. package/dist/esm/modules/word/advanced/math-convert.js +595 -0
  448. package/dist/esm/modules/word/advanced/ole-objects.js +271 -0
  449. package/dist/esm/modules/word/advanced/style-map.js +322 -0
  450. package/dist/esm/modules/word/advanced/validation.js +1065 -0
  451. package/dist/esm/modules/word/advanced/vba-project.js +265 -0
  452. package/dist/esm/modules/word/bridge/excel-bridge.js +980 -0
  453. package/dist/esm/modules/word/builder/document-handle.js +664 -0
  454. package/dist/esm/modules/word/builder/paragraph-builders.js +90 -0
  455. package/dist/esm/modules/word/builder/run-builders.js +600 -0
  456. package/dist/esm/modules/word/builder/table-builders.js +45 -0
  457. package/dist/esm/modules/word/constants.js +109 -1
  458. package/dist/esm/modules/word/convert/conversion-ir.js +31 -0
  459. package/dist/esm/modules/word/convert/docx-to-semantic.js +499 -0
  460. package/dist/esm/modules/word/convert/flat-opc.js +385 -0
  461. package/dist/esm/modules/word/convert/html/html-import.js +1907 -0
  462. package/dist/{browser/modules/word → esm/modules/word/convert/html}/html-renderer.js +420 -69
  463. package/dist/esm/modules/word/convert/html/html.js +15 -0
  464. package/dist/esm/modules/word/convert/markdown/markdown-import.js +1325 -0
  465. package/dist/esm/modules/word/convert/markdown/markdown-renderer.js +634 -0
  466. package/dist/esm/modules/word/convert/markdown/markdown.js +15 -0
  467. package/dist/esm/modules/word/convert/odt/odt.js +1932 -0
  468. package/dist/esm/modules/word/core/color-utils.js +43 -0
  469. package/dist/esm/modules/word/core/internal-utils.js +209 -0
  470. package/dist/esm/modules/word/core/mapper.js +427 -0
  471. package/dist/esm/modules/word/core/opc-paths.js +48 -0
  472. package/dist/esm/modules/word/core/text-utils.js +202 -0
  473. package/dist/esm/modules/word/core/walker.js +570 -0
  474. package/dist/esm/modules/word/crypto.js +13 -7
  475. package/dist/esm/modules/word/document-io.js +80 -197
  476. package/dist/esm/modules/word/errors.js +54 -2
  477. package/dist/esm/modules/word/excel.js +13 -0
  478. package/dist/esm/modules/word/font/font-embed.js +646 -0
  479. package/dist/{browser/modules/word → esm/modules/word/font}/font-obfuscation.js +4 -9
  480. package/dist/esm/modules/word/font/hyphenation.js +4210 -0
  481. package/dist/esm/modules/word/font/text-shaping.js +635 -0
  482. package/dist/esm/modules/word/html.js +6 -5
  483. package/dist/esm/modules/word/incremental-edit.js +361 -0
  484. package/dist/esm/modules/word/index.base.js +138 -29
  485. package/dist/esm/modules/word/layout/layout-constants.js +17 -0
  486. package/dist/esm/modules/word/layout/layout-full.js +1696 -0
  487. package/dist/esm/modules/word/layout/layout-model.js +16 -0
  488. package/dist/esm/modules/word/layout/layout.js +1167 -0
  489. package/dist/esm/modules/word/layout/render-page.js +1238 -0
  490. package/dist/esm/modules/word/markdown.js +13 -0
  491. package/dist/esm/modules/word/patcher.js +537 -0
  492. package/dist/esm/modules/word/query/compat.js +58 -0
  493. package/dist/esm/modules/word/query/data-binding.js +392 -0
  494. package/dist/esm/modules/word/query/form-fields.js +268 -0
  495. package/dist/esm/modules/word/query/format-search.js +329 -0
  496. package/dist/esm/modules/word/query/mail-merge.js +111 -0
  497. package/dist/esm/modules/word/query/merge.js +617 -0
  498. package/dist/esm/modules/word/query/replace.js +301 -0
  499. package/dist/esm/modules/word/query/revisions.js +879 -0
  500. package/dist/esm/modules/word/query/search.js +346 -0
  501. package/dist/esm/modules/word/query/split.js +135 -0
  502. package/dist/esm/modules/word/query/style-resolve.js +368 -0
  503. package/dist/esm/modules/word/reader/chart-parser.js +810 -0
  504. package/dist/esm/modules/word/reader/comments-parser.js +92 -0
  505. package/dist/esm/modules/word/reader/doc-props-parsers.js +190 -0
  506. package/dist/esm/modules/word/reader/docx-reader.js +2557 -0
  507. package/dist/esm/modules/word/reader/drawing-helpers.js +84 -0
  508. package/dist/esm/modules/word/reader/form-field-parser.js +82 -0
  509. package/dist/esm/modules/word/reader/image-parsers.js +291 -0
  510. package/dist/esm/modules/word/reader/math-parser.js +422 -0
  511. package/dist/esm/modules/word/reader/metadata-parsers.js +87 -0
  512. package/dist/esm/modules/word/reader/numbering-parser.js +166 -0
  513. package/dist/esm/modules/word/reader/paragraph-section-parsers.js +503 -0
  514. package/dist/esm/modules/word/reader/parse-utils.js +249 -0
  515. package/dist/esm/modules/word/reader/properties-parsers.js +332 -0
  516. package/dist/esm/modules/word/reader/reader-context.js +61 -0
  517. package/dist/esm/modules/word/reader/sdt-helpers.js +111 -0
  518. package/dist/esm/modules/word/reader/settings-parser.js +263 -0
  519. package/dist/esm/modules/word/reader/styles-parser.js +147 -0
  520. package/dist/esm/modules/word/reader/table-properties-parsers.js +234 -0
  521. package/dist/esm/modules/word/reader/theme-parser.js +167 -0
  522. package/dist/esm/modules/word/reader/watermark-parser.js +110 -0
  523. package/dist/esm/modules/word/security/cfb-reader.js +410 -0
  524. package/dist/esm/modules/word/{digital-signatures.js → security/digital-signatures.js} +34 -34
  525. package/dist/esm/modules/word/security/document-protection.js +201 -0
  526. package/dist/esm/modules/word/security/encryption.js +602 -0
  527. package/dist/esm/modules/word/security/policy.js +102 -0
  528. package/dist/esm/modules/word/template/template-chart.js +167 -0
  529. package/dist/esm/modules/word/template/template-datasource.js +541 -0
  530. package/dist/esm/modules/word/template/template-engine.js +1435 -0
  531. package/dist/esm/modules/word/units.js +43 -14
  532. package/dist/esm/modules/word/{writers → writer}/chart-writer.js +164 -23
  533. package/dist/esm/modules/word/writer/checkbox-writer.js +79 -0
  534. package/dist/esm/modules/word/{writers → writer}/comment-writer.js +8 -6
  535. package/dist/esm/modules/word/writer/common-parts.js +101 -0
  536. package/dist/{browser/modules/word → esm/modules/word/writer}/content-types.js +14 -6
  537. package/dist/esm/modules/word/writer/document-writer.js +473 -0
  538. package/dist/esm/modules/word/writer/docx-packager.js +1515 -0
  539. package/dist/{browser/modules/word/writers → esm/modules/word/writer}/footnote-writer.js +13 -10
  540. package/dist/{browser/modules/word/writers → esm/modules/word/writer}/header-footer-writer.js +39 -21
  541. package/dist/esm/modules/word/{writers → writer}/image-writer.js +11 -7
  542. package/dist/{browser/modules/word/writers → esm/modules/word/writer}/math-writer.js +21 -1
  543. package/dist/{browser/modules/word/writers → esm/modules/word/writer}/numbering-writer.js +11 -4
  544. package/dist/esm/modules/word/{writers → writer}/paragraph-writer.js +73 -38
  545. package/dist/{browser/modules/word/writers → esm/modules/word/writer}/parts-writer.js +91 -12
  546. package/dist/esm/modules/word/writer/reference-scanners.js +111 -0
  547. package/dist/esm/modules/word/writer/relationships.js +117 -0
  548. package/dist/esm/modules/word/writer/render-context.js +46 -0
  549. package/dist/{browser/modules/word/writers → esm/modules/word/writer}/run-writer.js +126 -24
  550. package/dist/esm/modules/word/writer/sdt-writer.js +189 -0
  551. package/dist/esm/modules/word/writer/stream-buf.js +73 -0
  552. package/dist/esm/modules/word/writer/streaming-writer.js +1382 -0
  553. package/dist/esm/modules/word/writer/string-buf.js +7 -0
  554. package/dist/esm/modules/word/{writers → writer}/styles-writer.js +32 -1
  555. package/dist/esm/modules/word/{writers → writer}/table-writer.js +94 -11
  556. package/dist/esm/utils/crypto.browser.js +3 -1
  557. package/dist/esm/utils/crypto.js +4 -1
  558. package/dist/esm/utils/font-metrics.js +293 -0
  559. package/dist/esm/utils/string-buf.js +89 -0
  560. package/dist/esm/utils/theme-colors.js +120 -0
  561. package/dist/iife/excelts.iife.js +70692 -70337
  562. package/dist/iife/excelts.iife.js.map +1 -1
  563. package/dist/iife/excelts.iife.min.js +57 -57
  564. package/dist/types/modules/archive/fs/archive-file.d.ts +8 -5
  565. package/dist/types/modules/excel/chart/chart-ex-types.d.ts +0 -12
  566. package/dist/types/modules/excel/chart/chart.d.ts +1 -5
  567. package/dist/types/modules/excel/chart/types.d.ts +0 -6
  568. package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +40 -0
  569. package/dist/types/modules/excel/utils/string-buf.d.ts +5 -26
  570. package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +19 -9
  571. package/dist/types/modules/excel/xlsx/xlsx.d.ts +10 -2
  572. package/dist/types/modules/pdf/excel-bridge.d.ts +30 -1
  573. package/dist/types/modules/pdf/font/metrics.d.ts +3 -52
  574. package/dist/types/modules/pdf/index.d.ts +1 -1
  575. package/dist/types/modules/pdf/render-layout-to-pdf.d.ts +66 -0
  576. package/dist/types/modules/pdf/word-bridge.d.ts +80 -12
  577. package/dist/types/modules/stream/index.base.d.ts +2 -0
  578. package/dist/types/modules/stream/internal/sink-adapter.d.ts +65 -0
  579. package/dist/types/modules/stream/pull-stream.d.ts +19 -2
  580. package/dist/types/modules/stream/types.d.ts +13 -1
  581. package/dist/types/modules/word/advanced/diff.d.ts +61 -0
  582. package/dist/types/modules/word/advanced/drawing-shapes.d.ts +269 -0
  583. package/dist/types/modules/word/advanced/field-engine.d.ts +43 -0
  584. package/dist/types/modules/word/advanced/glossary.d.ts +86 -0
  585. package/dist/types/modules/word/advanced/math-convert.d.ts +30 -0
  586. package/dist/types/modules/word/advanced/ole-objects.d.ts +115 -0
  587. package/dist/types/modules/word/advanced/style-map.d.ts +105 -0
  588. package/dist/types/modules/word/advanced/validation.d.ts +56 -0
  589. package/dist/types/modules/word/advanced/vba-project.d.ts +91 -0
  590. package/dist/types/modules/word/bridge/excel-bridge.d.ts +127 -0
  591. package/dist/types/modules/word/builder/document-handle.d.ts +151 -0
  592. package/dist/types/modules/word/builder/paragraph-builders.d.ts +61 -0
  593. package/dist/types/modules/word/builder/run-builders.d.ts +374 -0
  594. package/dist/types/modules/word/builder/table-builders.d.ts +23 -0
  595. package/dist/types/modules/word/constants.d.ts +39 -1
  596. package/dist/types/modules/word/convert/conversion-ir.d.ts +210 -0
  597. package/dist/types/modules/word/convert/docx-to-semantic.d.ts +39 -0
  598. package/dist/types/modules/word/convert/flat-opc.d.ts +44 -0
  599. package/dist/types/modules/word/convert/html/html-import.d.ts +50 -0
  600. package/dist/{browser/modules/word → types/modules/word/convert/html}/html-renderer.d.ts +14 -1
  601. package/dist/types/modules/word/convert/html/html.d.ts +15 -0
  602. package/dist/types/modules/word/convert/markdown/markdown-import.d.ts +68 -0
  603. package/dist/types/modules/word/convert/markdown/markdown-renderer.d.ts +25 -0
  604. package/dist/types/modules/word/convert/markdown/markdown.d.ts +15 -0
  605. package/dist/types/modules/word/convert/odt/odt.d.ts +41 -0
  606. package/dist/types/modules/word/{color-utils.d.ts → core/color-utils.d.ts} +8 -1
  607. package/dist/types/modules/word/core/internal-utils.d.ts +90 -0
  608. package/dist/types/modules/word/core/mapper.d.ts +44 -0
  609. package/dist/types/modules/word/core/opc-paths.d.ts +33 -0
  610. package/dist/types/modules/word/core/text-utils.d.ts +38 -0
  611. package/dist/types/modules/word/core/walker.d.ts +119 -0
  612. package/dist/types/modules/word/crypto.d.ts +14 -9
  613. package/dist/types/modules/word/document-io.d.ts +59 -27
  614. package/dist/types/modules/word/errors.d.ts +44 -1
  615. package/dist/types/modules/word/excel.d.ts +14 -0
  616. package/dist/types/modules/word/font/font-embed.d.ts +112 -0
  617. package/dist/types/modules/word/font/hyphenation.d.ts +65 -0
  618. package/dist/types/modules/word/font/text-shaping.d.ts +58 -0
  619. package/dist/types/modules/word/html.d.ts +7 -6
  620. package/dist/types/modules/word/incremental-edit.d.ts +123 -0
  621. package/dist/types/modules/word/index.base.d.ts +194 -10
  622. package/dist/types/modules/word/layout/layout-constants.d.ts +17 -0
  623. package/dist/types/modules/word/layout/layout-full.d.ts +53 -0
  624. package/dist/types/modules/word/layout/layout-model.d.ts +344 -0
  625. package/dist/types/modules/word/layout/layout.d.ts +63 -0
  626. package/dist/types/modules/word/layout/render-page.d.ts +57 -0
  627. package/dist/types/modules/word/markdown.d.ts +14 -0
  628. package/dist/types/modules/word/patcher.d.ts +62 -0
  629. package/dist/types/modules/word/query/compat.d.ts +25 -0
  630. package/dist/types/modules/word/query/data-binding.d.ts +22 -0
  631. package/dist/types/modules/word/query/form-fields.d.ts +41 -0
  632. package/dist/types/modules/word/query/format-search.d.ts +99 -0
  633. package/dist/types/modules/word/query/mail-merge.d.ts +25 -0
  634. package/dist/types/modules/word/query/merge.d.ts +50 -0
  635. package/dist/types/modules/word/query/replace.d.ts +47 -0
  636. package/dist/types/modules/word/query/revisions.d.ts +67 -0
  637. package/dist/types/modules/word/query/search.d.ts +129 -0
  638. package/dist/types/modules/word/query/split.d.ts +44 -0
  639. package/dist/types/modules/word/query/style-resolve.d.ts +104 -0
  640. package/dist/types/modules/word/reader/chart-parser.d.ts +20 -0
  641. package/dist/types/modules/word/reader/comments-parser.d.ts +26 -0
  642. package/dist/types/modules/word/reader/doc-props-parsers.d.ts +15 -0
  643. package/dist/types/modules/word/reader/docx-reader.d.ts +27 -0
  644. package/dist/types/modules/word/reader/drawing-helpers.d.ts +27 -0
  645. package/dist/types/modules/word/reader/form-field-parser.d.ts +21 -0
  646. package/dist/types/modules/word/reader/image-parsers.d.ts +11 -0
  647. package/dist/types/modules/word/reader/math-parser.d.ts +12 -0
  648. package/dist/types/modules/word/reader/metadata-parsers.d.ts +17 -0
  649. package/dist/types/modules/word/reader/numbering-parser.d.ts +13 -0
  650. package/dist/types/modules/word/reader/paragraph-section-parsers.d.ts +12 -0
  651. package/dist/types/modules/word/reader/parse-utils.d.ts +91 -0
  652. package/dist/types/modules/word/reader/properties-parsers.d.ts +21 -0
  653. package/dist/types/modules/word/reader/reader-context.d.ts +69 -0
  654. package/dist/types/modules/word/reader/sdt-helpers.d.ts +29 -0
  655. package/dist/types/modules/word/reader/settings-parser.d.ts +8 -0
  656. package/dist/types/modules/word/reader/styles-parser.d.ts +12 -0
  657. package/dist/types/modules/word/reader/table-properties-parsers.d.ts +12 -0
  658. package/dist/types/modules/word/reader/theme-parser.d.ts +8 -0
  659. package/dist/types/modules/word/reader/watermark-parser.d.ts +15 -0
  660. package/dist/types/modules/word/security/cfb-reader.d.ts +37 -0
  661. package/dist/types/modules/word/{digital-signatures.d.ts → security/digital-signatures.d.ts} +19 -11
  662. package/dist/types/modules/word/security/document-protection.d.ts +93 -0
  663. package/dist/{browser/modules/word → types/modules/word/security}/encryption.d.ts +51 -4
  664. package/dist/types/modules/word/security/policy.d.ts +80 -0
  665. package/dist/types/modules/word/template/template-chart.d.ts +56 -0
  666. package/dist/types/modules/word/template/template-datasource.d.ts +154 -0
  667. package/dist/types/modules/word/template/template-engine.d.ts +121 -0
  668. package/dist/types/modules/word/types.d.ts +224 -25
  669. package/dist/types/modules/word/units.d.ts +26 -0
  670. package/dist/types/modules/word/writer/checkbox-writer.d.ts +17 -0
  671. package/dist/{browser/modules/word/writers → types/modules/word/writer}/comment-writer.d.ts +2 -1
  672. package/dist/types/modules/word/writer/common-parts.d.ts +57 -0
  673. package/dist/{browser/modules/word → types/modules/word/writer}/content-types.d.ts +2 -2
  674. package/dist/types/modules/word/writer/document-writer.d.ts +24 -0
  675. package/dist/types/modules/word/writer/docx-packager.d.ts +35 -0
  676. package/dist/{browser/modules/word/writers → types/modules/word/writer}/footnote-writer.d.ts +3 -2
  677. package/dist/{browser/modules/word/writers → types/modules/word/writer}/header-footer-writer.d.ts +3 -2
  678. package/dist/{browser/modules/word/writers → types/modules/word/writer}/image-writer.d.ts +1 -1
  679. package/dist/types/modules/word/writer/math-writer.d.ts +20 -0
  680. package/dist/types/modules/word/{writers → writer}/numbering-writer.d.ts +1 -1
  681. package/dist/types/modules/word/{writers → writer}/paragraph-writer.d.ts +2 -1
  682. package/dist/types/modules/word/{writers → writer}/parts-writer.d.ts +3 -3
  683. package/dist/types/modules/word/writer/reference-scanners.d.ts +42 -0
  684. package/dist/types/modules/word/writer/relationships.d.ts +52 -0
  685. package/dist/types/modules/word/writer/render-context.d.ts +124 -0
  686. package/dist/types/modules/word/{writers → writer}/run-writer.d.ts +10 -1
  687. package/dist/types/modules/word/writer/sdt-writer.d.ts +25 -0
  688. package/dist/types/modules/word/writer/stream-buf.d.ts +37 -0
  689. package/dist/types/modules/word/writer/streaming-writer.d.ts +344 -0
  690. package/dist/types/modules/word/writer/string-buf.d.ts +8 -0
  691. package/dist/types/modules/word/{writers → writer}/table-writer.d.ts +2 -1
  692. package/dist/types/modules/xml/types.d.ts +22 -0
  693. package/dist/types/utils/crypto.browser.d.ts +3 -1
  694. package/dist/types/utils/crypto.d.ts +4 -1
  695. package/dist/types/utils/font-metrics.d.ts +63 -0
  696. package/dist/types/utils/string-buf.d.ts +42 -0
  697. package/dist/types/utils/theme-colors.d.ts +55 -0
  698. package/package.json +121 -39
  699. package/dist/browser/modules/word/color-utils.js +0 -94
  700. package/dist/browser/modules/word/document.d.ts +0 -657
  701. package/dist/browser/modules/word/document.js +0 -1533
  702. package/dist/browser/modules/word/docx-packager.d.ts +0 -14
  703. package/dist/browser/modules/word/docx-packager.js +0 -822
  704. package/dist/browser/modules/word/docx-reader.d.ts +0 -11
  705. package/dist/browser/modules/word/docx-reader.js +0 -4929
  706. package/dist/browser/modules/word/encryption.js +0 -274
  707. package/dist/browser/modules/word/internal-utils.d.ts +0 -23
  708. package/dist/browser/modules/word/internal-utils.js +0 -54
  709. package/dist/browser/modules/word/namespaces.d.ts +0 -159
  710. package/dist/browser/modules/word/namespaces.js +0 -189
  711. package/dist/browser/modules/word/relationships.d.ts +0 -30
  712. package/dist/browser/modules/word/relationships.js +0 -48
  713. package/dist/browser/modules/word/writers/checkbox-writer.d.ts +0 -9
  714. package/dist/browser/modules/word/writers/checkbox-writer.js +0 -42
  715. package/dist/browser/modules/word/writers/document-writer.d.ts +0 -16
  716. package/dist/browser/modules/word/writers/document-writer.js +0 -461
  717. package/dist/browser/modules/word/writers/math-writer.d.ts +0 -9
  718. package/dist/cjs/modules/word/color-utils.js +0 -97
  719. package/dist/cjs/modules/word/document.js +0 -1645
  720. package/dist/cjs/modules/word/docx-packager.js +0 -825
  721. package/dist/cjs/modules/word/docx-reader.js +0 -4932
  722. package/dist/cjs/modules/word/encryption.js +0 -282
  723. package/dist/cjs/modules/word/internal-utils.js +0 -59
  724. package/dist/cjs/modules/word/namespaces.js +0 -192
  725. package/dist/cjs/modules/word/relationships.js +0 -55
  726. package/dist/cjs/modules/word/writers/checkbox-writer.js +0 -45
  727. package/dist/cjs/modules/word/writers/document-writer.js +0 -465
  728. package/dist/esm/modules/word/color-utils.js +0 -94
  729. package/dist/esm/modules/word/document.js +0 -1533
  730. package/dist/esm/modules/word/docx-packager.js +0 -822
  731. package/dist/esm/modules/word/docx-reader.js +0 -4929
  732. package/dist/esm/modules/word/encryption.js +0 -274
  733. package/dist/esm/modules/word/internal-utils.js +0 -54
  734. package/dist/esm/modules/word/namespaces.js +0 -189
  735. package/dist/esm/modules/word/relationships.js +0 -48
  736. package/dist/esm/modules/word/writers/checkbox-writer.js +0 -42
  737. package/dist/esm/modules/word/writers/document-writer.js +0 -461
  738. package/dist/types/modules/word/document.d.ts +0 -657
  739. package/dist/types/modules/word/docx-packager.d.ts +0 -14
  740. package/dist/types/modules/word/docx-reader.d.ts +0 -11
  741. package/dist/types/modules/word/internal-utils.d.ts +0 -23
  742. package/dist/types/modules/word/namespaces.d.ts +0 -159
  743. package/dist/types/modules/word/relationships.d.ts +0 -30
  744. package/dist/types/modules/word/writers/checkbox-writer.d.ts +0 -9
  745. package/dist/types/modules/word/writers/document-writer.d.ts +0 -16
  746. package/dist/types/modules/word/writers/math-writer.d.ts +0 -9
  747. /package/dist/browser/modules/word/{font-obfuscation.d.ts → font/font-obfuscation.d.ts} +0 -0
  748. /package/dist/browser/modules/word/{writers → writer}/chart-writer.d.ts +0 -0
  749. /package/dist/browser/modules/word/{writers → writer}/section-writer.d.ts +0 -0
  750. /package/dist/browser/modules/word/{writers → writer}/section-writer.js +0 -0
  751. /package/dist/browser/modules/word/{writers → writer}/styles-writer.d.ts +0 -0
  752. /package/dist/browser/modules/word/{writers → writer}/textbox-writer.d.ts +0 -0
  753. /package/dist/browser/modules/word/{writers → writer}/textbox-writer.js +0 -0
  754. /package/dist/browser/modules/word/{writers → writer}/toc-writer.d.ts +0 -0
  755. /package/dist/browser/modules/word/{writers → writer}/toc-writer.js +0 -0
  756. /package/dist/cjs/modules/word/{writers → writer}/section-writer.js +0 -0
  757. /package/dist/cjs/modules/word/{writers → writer}/textbox-writer.js +0 -0
  758. /package/dist/cjs/modules/word/{writers → writer}/toc-writer.js +0 -0
  759. /package/dist/esm/modules/word/{writers → writer}/section-writer.js +0 -0
  760. /package/dist/esm/modules/word/{writers → writer}/textbox-writer.js +0 -0
  761. /package/dist/esm/modules/word/{writers → writer}/toc-writer.js +0 -0
  762. /package/dist/types/modules/word/{font-obfuscation.d.ts → font/font-obfuscation.d.ts} +0 -0
  763. /package/dist/types/modules/word/{writers → writer}/chart-writer.d.ts +0 -0
  764. /package/dist/types/modules/word/{writers → writer}/section-writer.d.ts +0 -0
  765. /package/dist/types/modules/word/{writers → writer}/styles-writer.d.ts +0 -0
  766. /package/dist/types/modules/word/{writers → writer}/textbox-writer.d.ts +0 -0
  767. /package/dist/types/modules/word/{writers → writer}/toc-writer.d.ts +0 -0
@@ -0,0 +1,1387 @@
1
+ "use strict";
2
+ /**
3
+ * DOCX Module - Streaming Writer
4
+ *
5
+ * A DOCX generator that serializes body content incrementally and pushes it
6
+ * through a streaming compression pipeline. Uses the same streaming ZIP
7
+ * infrastructure as the Excel module:
8
+ *
9
+ * - `Zip` (StreamingZip) — streams ZIP entries to output
10
+ * - `ZipDeflate` — per-entry deflate compression
11
+ * - `StreamBuf` — event-driven pipe from XML to ZIP
12
+ * - `StringBuf` — efficient XML string builder with buffer reuse
13
+ *
14
+ * Data flow with sink (true end-to-end streaming):
15
+ * ```
16
+ * add(paragraph) → XML → StreamBuf → ZipDeflate → Zip
17
+ * ↓ (per-chunk callback)
18
+ * await SinkAdapter.write(chunk)
19
+ * ↓
20
+ * user-supplied WritableStream /
21
+ * Node Writable / duck-typed sink
22
+ * ```
23
+ *
24
+ * Memory profile:
25
+ * - Body model is never retained: each element is serialised and
26
+ * compressed as it arrives, so peak per-element memory is
27
+ * O(largest_single_element).
28
+ * - When `options.sink` is provided, compressed bytes are pushed
29
+ * into the sink as soon as they are produced (with backpressure
30
+ * awaited via {@link SinkAdapter}). Total writer-side memory then
31
+ * stays O(largest_part) regardless of final DOCX size.
32
+ * - When `options.sink` is omitted, compressed bytes accumulate in
33
+ * `_outputChunks` and `finalize()` returns the assembled
34
+ * `Uint8Array`. Total memory is O(compressed_docx_size).
35
+ */
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.StreamingDocxWriter = void 0;
38
+ exports.createDocxStream = createDocxStream;
39
+ const stream_1 = require("../../archive/zip/stream.js");
40
+ const sink_adapter_1 = require("../../stream/internal/sink-adapter.js");
41
+ const encode_1 = require("../../xml/encode.js");
42
+ const writer_1 = require("../../xml/writer.js");
43
+ const constants_1 = require("../constants");
44
+ const internal_utils_1 = require("../core/internal-utils");
45
+ const opc_paths_1 = require("../core/opc-paths");
46
+ const walker_1 = require("../core/walker");
47
+ const errors_1 = require("../errors");
48
+ const chart_writer_1 = require("./chart-writer");
49
+ const comment_writer_1 = require("./comment-writer");
50
+ const common_parts_1 = require("./common-parts");
51
+ const content_types_1 = require("./content-types");
52
+ const document_writer_1 = require("./document-writer");
53
+ const header_footer_writer_1 = require("./header-footer-writer");
54
+ const reference_scanners_1 = require("./reference-scanners");
55
+ const relationships_1 = require("./relationships");
56
+ const render_context_1 = require("./render-context");
57
+ const section_writer_1 = require("./section-writer");
58
+ const stream_buf_1 = require("./stream-buf");
59
+ const string_buf_1 = require("./string-buf");
60
+ // Per-instance StringBuf is created in the constructor (see _xmlBuffer field below).
61
+ // Previously this was a module-level singleton which caused data races with concurrent instances.
62
+ const EMPTY_U8 = new Uint8Array(0);
63
+ // =============================================================================
64
+ // Streaming DOCX Writer
65
+ // =============================================================================
66
+ /**
67
+ * Streaming DOCX writer. Body elements are serialized to XML and compressed
68
+ * into the ZIP pipeline as they arrive, so the body **model** is not retained
69
+ * after each `add()`.
70
+ *
71
+ * When constructed with `options.sink`, compressed bytes are pushed into
72
+ * the sink as soon as the ZIP layer produces them, with backpressure
73
+ * awaited via {@link SinkAdapter}; in this mode peak memory is
74
+ * O(largest_part) and `finalize()` resolves to a zero-length
75
+ * `Uint8Array` (the bytes are already in the sink). Without a sink,
76
+ * compressed bytes accumulate in `_outputChunks` and `finalize()`
77
+ * returns the assembled `Uint8Array` (peak memory
78
+ * O(compressed_docx_size)).
79
+ *
80
+ * Use {@link addAsync} (instead of {@link add}) when driving the sink
81
+ * variant to obtain true end-to-end backpressure: each call awaits all
82
+ * pending sink writes before resolving.
83
+ */
84
+ class StreamingDocxWriter {
85
+ constructor(options = {}) {
86
+ this._elementCount = 0;
87
+ this._finalized = false;
88
+ // Per-instance XML buffer (avoids module-level singleton data race)
89
+ this._xmlBuffer = new string_buf_1.StringBuf({ size: 65536 });
90
+ /** Compressed-byte accumulator used when no `sink` is supplied. */
91
+ this._outputChunks = [];
92
+ /**
93
+ * Promise chain serialising every sink write. The `Zip` callback fires
94
+ * synchronously, so we queue chunks via `.then(...)` and let
95
+ * `addAsync` / `finalize` await the chain.
96
+ */
97
+ this._pendingDrain = Promise.resolve();
98
+ this._headerWritten = false;
99
+ /**
100
+ * Whether the previously-written body element was a `<w:tbl>`. Tracked
101
+ * so we can insert a separator `<w:p>` between adjacent tables — Word
102
+ * rejects (and silently merges) two `<w:tbl>` blocks that share no
103
+ * paragraph between them per ECMA-376 §17.13.5.34.
104
+ */
105
+ this._prevWasTable = false;
106
+ /**
107
+ * First error reported by the underlying ZIP stream (compression failure,
108
+ * write-after-end, etc.). Stored synchronously by the `Zip` callback and
109
+ * surfaced from `finalize()` so callers receive a rejection instead of an
110
+ * indefinitely-pending promise.
111
+ */
112
+ this._streamError = null;
113
+ /** Charts encountered in body content; rendered to `word/charts/chartN.xml` at finalize time. */
114
+ this._bodyCharts = [];
115
+ /** ChartEx items encountered in body content. */
116
+ this._bodyChartEx = [];
117
+ /**
118
+ * Per-chart sequence numbers fixed at registration time. Both classes
119
+ * use independent monotonic counters; the writer emits
120
+ * `word/charts/chart{n}.xml` for the regular chart family and
121
+ * `word/charts/chartEx{n}.xml` for the chartEx family.
122
+ *
123
+ * The previous scheme used `chartCount + chartExCount + 1` as the
124
+ * sequence number for both classes, which made the rId path encoded in
125
+ * documentRels disagree with the path used at finalize when the writer
126
+ * iterated the two arrays separately. The result was relationships
127
+ * pointing at non-existent chart parts.
128
+ */
129
+ this._chartNum = new WeakMap();
130
+ this._nextChartSeq = 0;
131
+ this._nextChartExSeq = 0;
132
+ /** Hyperlink object identities already registered (to keep one rId per object). */
133
+ this._registeredHyperlinks = new WeakSet();
134
+ /** Image rIds already registered to documentRels (avoid duplicates). */
135
+ this._registeredImageRIds = new Set();
136
+ /** header map key → newly allocated rId. Populated by `_allocateHeaderFooterRIds`. */
137
+ this._headerKeyToRid = new Map();
138
+ /** footer map key → newly allocated rId. */
139
+ this._footerKeyToRid = new Map();
140
+ // Sanitize image/font file names up-front. They get embedded into
141
+ // ZIP entry paths and into rels Target attributes; a hostile name
142
+ // (e.g. `../../etc/passwd.png` from a round-tripped untrusted DOCX)
143
+ // would otherwise produce a zipslip-shaped output. Mirrors what
144
+ // `packageDocx` does in `shallowCopyDocForPackaging`.
145
+ const sanitized = sanitizeStreamingOptions(options);
146
+ this._options = sanitized;
147
+ this._initZip();
148
+ }
149
+ /** Set a progress callback. */
150
+ onProgress(cb) {
151
+ this._onProgress = cb;
152
+ return this;
153
+ }
154
+ /**
155
+ * Add a single body element. The element is immediately serialized to XML
156
+ * and pushed into the ZIP compression pipeline. After this call, the element
157
+ * can be garbage collected — it is not retained.
158
+ */
159
+ add(element) {
160
+ if (this._finalized) {
161
+ throw new errors_1.DocxWriteError("StreamingDocxWriter: cannot add elements after finalize()");
162
+ }
163
+ // Sink-mode early failure: if a previous chunk already failed to
164
+ // reach the sink, surface that immediately rather than letting the
165
+ // caller keep streaming work that will be discarded. Buffered mode
166
+ // keeps the legacy behaviour of deferring all error reporting to
167
+ // `finalize()` because there is no live consumer that could be
168
+ // disrupted by silent queueing.
169
+ if (this._sinkAdapter && this._streamError) {
170
+ throw new errors_1.DocxWriteError(`StreamingDocxWriter: sink already failed (${this._streamError.message})`, { cause: this._streamError });
171
+ }
172
+ // Write document.xml header on first element
173
+ if (!this._headerWritten) {
174
+ this._writeDocumentHeader();
175
+ this._headerWritten = true;
176
+ }
177
+ // Register any chart/hyperlink/image references this element introduces
178
+ // BEFORE serializing it, so the per-element renderBodyContent call has a
179
+ // populated WordRenderContext (chart rIds, hyperlink rIds, image remap).
180
+ this._registerElementReferences(element);
181
+ // ECMA-376 §17.13.5.34: a `<w:tbl>` must be followed by a paragraph
182
+ // (or section break) before the next `<w:tbl>` may begin. When the
183
+ // caller streams two adjacent tables we synthesise an empty
184
+ // separator paragraph between them so Word does not collapse them
185
+ // into a single malformed tbl.
186
+ if (element.type === "table" && this._prevWasTable) {
187
+ this._writeSeparatorParagraph();
188
+ }
189
+ // Serialize this single element to XML and push to stream
190
+ this._writeBodyElement(element);
191
+ this._elementCount++;
192
+ this._prevWasTable = element.type === "table";
193
+ if (this._onProgress && this._elementCount % (this._options.chunkSize ?? 1000) === 0) {
194
+ this._onProgress({ elementsWritten: this._elementCount, phase: "body" });
195
+ }
196
+ return this;
197
+ }
198
+ /** Add multiple body elements at once. */
199
+ addMany(elements) {
200
+ for (const el of elements) {
201
+ this.add(el);
202
+ }
203
+ return this;
204
+ }
205
+ /**
206
+ * Async variant of {@link add}. After serialising the element, awaits
207
+ * any pending writes to the configured `sink` so callers driving large
208
+ * input get true end-to-end backpressure rather than letting the
209
+ * sink-write queue grow unbounded inside the writer.
210
+ *
211
+ * Without `options.sink` this is equivalent to `add` (resolving
212
+ * synchronously after element serialisation).
213
+ *
214
+ * Throws if the sink reports an error: previous queued writes whose
215
+ * rejection was captured into `_streamError` surface here.
216
+ */
217
+ async addAsync(element) {
218
+ this.add(element);
219
+ if (this._sinkAdapter) {
220
+ await this._pendingDrain;
221
+ if (this._streamError) {
222
+ throw new errors_1.DocxWriteError(`StreamingDocxWriter: sink write failed (${this._streamError.message})`, { cause: this._streamError });
223
+ }
224
+ }
225
+ return this;
226
+ }
227
+ /**
228
+ * Async variant of {@link addMany}. Awaits `addAsync` for each element
229
+ * so backpressure is honoured between every body element.
230
+ */
231
+ async addManyAsync(elements) {
232
+ for (const el of elements) {
233
+ await this.addAsync(el);
234
+ }
235
+ return this;
236
+ }
237
+ /** Add a paragraph with simple text content. */
238
+ addText(content, properties) {
239
+ return this.add({
240
+ type: "paragraph",
241
+ children: [{ content: [{ type: "text", text: content }] }],
242
+ properties
243
+ });
244
+ }
245
+ /** Get the count of body elements written so far. */
246
+ get elementCount() {
247
+ return this._elementCount;
248
+ }
249
+ /**
250
+ * Finalize the document.
251
+ *
252
+ * - Without `options.sink`: returns the assembled `Uint8Array`
253
+ * containing the full DOCX file.
254
+ * - With `options.sink`: drains any pending sink writes, calls
255
+ * `sink.end()`, and resolves to a zero-length `Uint8Array`. The
256
+ * DOCX bytes have already been delivered to the sink — the empty
257
+ * return is a sentinel signalling "writer is done; consumer keeps
258
+ * the data".
259
+ */
260
+ async finalize() {
261
+ if (this._finalized) {
262
+ throw new errors_1.DocxWriteError("StreamingDocxWriter: already finalized");
263
+ }
264
+ this._finalized = true;
265
+ if (this._onProgress) {
266
+ this._onProgress({ elementsWritten: this._elementCount, phase: "finalizing" });
267
+ }
268
+ // If no elements were added, still write a minimal document
269
+ if (!this._headerWritten) {
270
+ this._writeDocumentHeader();
271
+ }
272
+ // Allocate header/footer rIds NOW so the section properties we render
273
+ // into document.xml can use the same rIds the auxiliary parts will
274
+ // register later. Without this the section refs and the .rels file
275
+ // would disagree and Word treats the references as dangling.
276
+ this._allocateHeaderFooterRIds();
277
+ // Write document.xml footer (close </w:body></w:document>)
278
+ this._writeDocumentFooter();
279
+ // End the document.xml stream → finalizes its ZIP entry
280
+ await this._endStream(this._documentStream);
281
+ // Add all auxiliary parts (styles, settings, etc.)
282
+ await this._addAuxiliaryParts();
283
+ // Finalize the ZIP archive. Any compression errors during the trailing
284
+ // central-directory write are reported via the `Zip` callback into
285
+ // `_streamError`; surface them as a rejection.
286
+ this._zip.end();
287
+ // In sink mode the Zip callback queued every chunk onto _pendingDrain;
288
+ // wait for that promise chain to complete before declaring the writer
289
+ // finished. In buffered mode this is a no-op (resolved promise).
290
+ await this._pendingDrain;
291
+ if (this._streamError) {
292
+ throw new errors_1.DocxWriteError(`StreamingDocxWriter: ZIP finalization failed (${this._streamError.message})`, { cause: this._streamError });
293
+ }
294
+ if (this._sinkAdapter) {
295
+ // Close the sink so the consumer knows the byte stream is complete.
296
+ // Errors raised during close (e.g. underlying file system) propagate.
297
+ await this._sinkAdapter.end();
298
+ return EMPTY_U8;
299
+ }
300
+ // Buffered mode: assemble and return the DOCX bytes.
301
+ return this._assembleOutput();
302
+ }
303
+ /** Reset the writer for reuse. */
304
+ /**
305
+ * Reset the writer for reuse.
306
+ *
307
+ * Throws when the writer was constructed with an `options.sink`: a
308
+ * sink can only be `end()`ed once, so reusing the same writer would
309
+ * produce an undefined byte stream. Construct a new writer (with a
310
+ * new sink) for each document instead.
311
+ */
312
+ reset() {
313
+ if (this._sinkAdapter) {
314
+ throw new errors_1.DocxWriteError("StreamingDocxWriter: reset() is not supported in sink mode; create a new writer instance per document.");
315
+ }
316
+ this._elementCount = 0;
317
+ this._finalized = false;
318
+ this._headerWritten = false;
319
+ this._prevWasTable = false;
320
+ this._outputChunks = [];
321
+ this._bodyCharts.length = 0;
322
+ this._bodyChartEx.length = 0;
323
+ this._nextChartSeq = 0;
324
+ this._nextChartExSeq = 0;
325
+ this._registeredImageRIds.clear();
326
+ this._headerKeyToRid.clear();
327
+ this._footerKeyToRid.clear();
328
+ this._watermarkHeaderRid = undefined;
329
+ // _registeredHyperlinks is a WeakSet; old entries become unreachable
330
+ // along with the body model objects they referenced — no manual clear
331
+ // is necessary. _chartNum is a WeakMap with the same property.
332
+ this._initZip();
333
+ return this;
334
+ }
335
+ // ===========================================================================
336
+ // Private: ZIP infrastructure
337
+ // ===========================================================================
338
+ _initZip() {
339
+ this._outputChunks = [];
340
+ this._streamError = null;
341
+ this._pendingDrain = Promise.resolve();
342
+ if (this._options.sink && !this._sinkAdapter) {
343
+ this._sinkAdapter = new sink_adapter_1.SinkAdapter(this._options.sink);
344
+ }
345
+ this._documentRels = (0, relationships_1.createRelationships)();
346
+ this._renderCtx = (0, render_context_1.createRenderContext)({
347
+ securityPolicy: this._options.securityPolicy,
348
+ chartRIds: new Map(),
349
+ imageRIdRemap: new Map(),
350
+ hyperlinkRIds: new WeakMap()
351
+ });
352
+ this._zip = new stream_1.Zip((err, data, _final) => {
353
+ // The ZIP callback reports compression / framing errors out-of-band.
354
+ // Capture only the first error; subsequent callbacks may still be
355
+ // dispatched as the pipeline drains. Surfaced from `finalize()`.
356
+ if (err && !this._streamError) {
357
+ this._streamError = err;
358
+ // Wake up any pending `_endStream` waiter so callers don't hang.
359
+ this._documentStream?.emit("error", err);
360
+ }
361
+ if (data && data.length > 0) {
362
+ if (this._sinkAdapter) {
363
+ // The Zip callback runs synchronously and cannot await, so we
364
+ // chain each sink write onto a single drain promise. Producers
365
+ // either:
366
+ // (a) call `addAsync()` / `finalize()` which await the chain,
367
+ // (b) ignore backpressure and let chunks queue in memory until
368
+ // the next await point, capped by the sink's own queueing.
369
+ // First-error capture: a rejected write is collapsed into
370
+ // `_streamError` so subsequent writes are skipped quickly.
371
+ this._pendingDrain = this._pendingDrain.then(() => {
372
+ if (this._streamError) {
373
+ return;
374
+ }
375
+ return this._sinkAdapter.write(data).catch((e) => {
376
+ if (!this._streamError) {
377
+ this._streamError = e instanceof Error ? e : new Error(String(e));
378
+ }
379
+ });
380
+ });
381
+ }
382
+ else {
383
+ this._outputChunks.push(data);
384
+ }
385
+ }
386
+ });
387
+ // Create the document.xml ZIP entry and stream
388
+ const level = this._options.compressionLevel ?? 6;
389
+ this._documentZipFile = new stream_1.ZipDeflate(constants_1.PartPath.Document, { level });
390
+ this._zip.add(this._documentZipFile);
391
+ this._documentStream = new stream_buf_1.StreamBuf({ bufSize: 65536 });
392
+ this._documentStream.on("data", (chunk) => {
393
+ this._documentZipFile.push(chunk);
394
+ });
395
+ this._documentStream.once("finish", () => {
396
+ this._documentZipFile.push(EMPTY_U8, true);
397
+ this._documentStream.emit("zipped");
398
+ });
399
+ }
400
+ _write(text) {
401
+ this._xmlBuffer.reset();
402
+ this._xmlBuffer.addText(text);
403
+ this._documentStream.write(this._xmlBuffer);
404
+ }
405
+ // ===========================================================================
406
+ // Private: Document XML generation
407
+ // ===========================================================================
408
+ _writeDocumentHeader() {
409
+ // XML declaration
410
+ let header = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>`;
411
+ header += `<w:document`;
412
+ for (const [key, value] of Object.entries(constants_1.DOCUMENT_NAMESPACES)) {
413
+ header += ` ${key}="${value}"`;
414
+ }
415
+ header += `>`;
416
+ // Background
417
+ if (this._options.background) {
418
+ const bg = this._options.background;
419
+ header += `<w:background w:color="${(0, encode_1.xmlEncodeAttr)(bg.color ?? "FFFFFF")}"`;
420
+ if (bg.themeColor) {
421
+ header += ` w:themeColor="${(0, encode_1.xmlEncodeAttr)(bg.themeColor)}"`;
422
+ }
423
+ header += `/>`;
424
+ }
425
+ header += `<w:body>`;
426
+ this._write(header);
427
+ }
428
+ _writeBodyElement(element) {
429
+ // Serialize a single body element using the shared renderBodyContent
430
+ // function. We pass the writer's accumulated render context so r:embed,
431
+ // chart and hyperlink rIds resolve correctly. Without this, charts throw
432
+ // "Chart content was not registered with a relationship id" and hyperlink
433
+ // / image references would be missing or wrong.
434
+ const writer = new writer_1.XmlWriter();
435
+ (0, document_writer_1.renderBodyContent)(writer, element, this._renderCtx);
436
+ this._write(writer.xml);
437
+ }
438
+ /**
439
+ * Emit an empty `<w:p/>` to separate two adjacent tables. Required by
440
+ * ECMA-376 §17.13.5.34 — Word rejects packages where two `<w:tbl>`
441
+ * elements appear without a paragraph between them.
442
+ */
443
+ _writeSeparatorParagraph() {
444
+ this._write("<w:p/>");
445
+ }
446
+ /**
447
+ * Scan a single body element and register any chart / hyperlink / image
448
+ * references it introduces against the writer's accumulated state. This
449
+ * must run before the element is serialized so the render context already
450
+ * carries the relationships the renderer will look up.
451
+ */
452
+ _registerElementReferences(element) {
453
+ // Direct top-level chart entries
454
+ if (element.type === "chart") {
455
+ this._registerChart(element);
456
+ return;
457
+ }
458
+ if (element.type === "chartEx") {
459
+ this._registerChartEx(element);
460
+ return;
461
+ }
462
+ // For paragraph-like containers we descend with the shared walker so
463
+ // track-change wrappers (InsertedRun / MovedToRun / hyperlink children)
464
+ // are also covered.
465
+ if (element.type === "paragraph" ||
466
+ element.type === "table" ||
467
+ element.type === "sdt" ||
468
+ element.type === "textBox") {
469
+ (0, walker_1.walkBlocks)([element], {
470
+ enterParagraph: para => {
471
+ this._registerParagraphReferences(para);
472
+ },
473
+ enterRun: run => {
474
+ for (const c of run.content) {
475
+ if (c.type === "image" && c.rId) {
476
+ this._registerImageRId(c.rId);
477
+ if (c.svgRId) {
478
+ this._registerImageRId(c.svgRId);
479
+ }
480
+ }
481
+ }
482
+ },
483
+ enterHyperlink: h => {
484
+ this._registerHyperlink(h);
485
+ }
486
+ });
487
+ return;
488
+ }
489
+ if (element.type === "floatingImage" && element.rId) {
490
+ this._registerImageRId(element.rId);
491
+ if (element.svgRId) {
492
+ this._registerImageRId(element.svgRId);
493
+ }
494
+ }
495
+ }
496
+ _registerParagraphReferences(_para) {
497
+ // Per-paragraph property registration is not needed today — image and
498
+ // hyperlink registration is handled by enterRun / enterHyperlink. This
499
+ // hook exists so future paragraph-level relationships (numPicBullet,
500
+ // tabLeader image, …) can be added without changing call sites.
501
+ }
502
+ _registerChart(chart) {
503
+ if (this._renderCtx.chartRIds.has(chart)) {
504
+ return;
505
+ }
506
+ const num = ++this._nextChartSeq;
507
+ const rId = (0, relationships_1.addRelationship)(this._documentRels, constants_1.RelType.Chart, `charts/chart${num}.xml`);
508
+ this._renderCtx.chartRIds.set(chart, rId);
509
+ this._chartNum.set(chart, num);
510
+ this._bodyCharts.push(chart);
511
+ }
512
+ _registerChartEx(chart) {
513
+ if (this._renderCtx.chartRIds.has(chart)) {
514
+ return;
515
+ }
516
+ const num = ++this._nextChartExSeq;
517
+ const rId = (0, relationships_1.addRelationship)(this._documentRels, constants_1.RelType.ChartEx, `charts/chartEx${num}.xml`);
518
+ this._renderCtx.chartRIds.set(chart, rId);
519
+ this._chartNum.set(chart, num);
520
+ this._bodyChartEx.push(chart);
521
+ }
522
+ _registerHyperlink(h) {
523
+ if (!h.url || h.rId || this._registeredHyperlinks.has(h)) {
524
+ return;
525
+ }
526
+ // Drop dangerous schemes (javascript:, vbscript:, data:, file:, …) before
527
+ // they reach document.xml.rels. Mark the link as registered either way so
528
+ // we don't keep re-evaluating it on every flush.
529
+ const safe = (0, internal_utils_1.sanitizeUrl)(h.url);
530
+ if (!safe) {
531
+ this._registeredHyperlinks.add(h);
532
+ return;
533
+ }
534
+ const rId = (0, relationships_1.addRelationship)(this._documentRels, constants_1.RelType.Hyperlink, safe, "External");
535
+ this._renderCtx.hyperlinkRIds.set(h, rId);
536
+ this._registeredHyperlinks.add(h);
537
+ }
538
+ _registerImageRId(rId) {
539
+ if (this._registeredImageRIds.has(rId)) {
540
+ return;
541
+ }
542
+ const img = this._lookupImage(rId);
543
+ if (!img) {
544
+ // Image reference points at a binary the caller did not provide. The
545
+ // previous behaviour was to silently skip and emit an invalid DOCX —
546
+ // see the policy field on StreamingDocxOptions.
547
+ const policy = this._options.missingImagePolicy ?? "throw";
548
+ if (policy === "warn") {
549
+ console.warn(`[StreamingDocxWriter] image rId "${rId}" referenced by content ` +
550
+ `but not present in options.images. Output will be missing this ` +
551
+ `relationship and may not open in Word.`);
552
+ return;
553
+ }
554
+ throw new errors_1.DocxWriteError(`Streaming writer: image rId "${rId}" referenced by content but ` +
555
+ `not present in options.images. Add the image to options.images, ` +
556
+ `remove the reference, or set missingImagePolicy: "warn" to ` +
557
+ `accept a broken document.`);
558
+ }
559
+ (0, relationships_1.addRelationshipWithId)(this._documentRels, rId, constants_1.RelType.Image, `media/${img.fileName}`);
560
+ this._registeredImageRIds.add(rId);
561
+ }
562
+ _lookupImage(rId) {
563
+ if (!this._options.images) {
564
+ return undefined;
565
+ }
566
+ for (const img of this._options.images) {
567
+ if (img.rId === rId) {
568
+ return img;
569
+ }
570
+ // Round-tripped models may surface alias rIds populated by the
571
+ // reader for header/footer-local references that pointed at the
572
+ // same physical media file. Match those too so a header that uses
573
+ // its own rId still resolves to the binary.
574
+ if (img.aliasRIds && img.aliasRIds.includes(rId)) {
575
+ return img;
576
+ }
577
+ }
578
+ return undefined;
579
+ }
580
+ _writeDocumentFooter() {
581
+ // Word rejects a `<w:body/>` that contains no `<w:p>`. Synthesise an
582
+ // empty paragraph when the caller streamed zero elements so the
583
+ // package opens cleanly. (Bulk packager handles this implicitly via
584
+ // `Document.build`'s default body element list.)
585
+ if (this._elementCount === 0) {
586
+ this._write("<w:p/>");
587
+ }
588
+ // Write final section properties if provided. Header/footer references
589
+ // are rewritten so they refer to the rIds we just allocated in
590
+ // `_allocateHeaderFooterRIds`. References whose target type cannot
591
+ // be resolved (e.g. a custom rId for a header that isn't in the
592
+ // options map) are dropped rather than emitted dangling.
593
+ const sectIn = this._options.sectionProperties;
594
+ let sect = sectIn ? this._rewireSectionRefs(sectIn) : undefined;
595
+ // Auto-fill: if the caller provided headers/footers but no section
596
+ // references, synthesize one per type. Mirrors what the bulk
597
+ // packager does for builder-style usage.
598
+ if (this._options.headers &&
599
+ this._options.headers.size > 0 &&
600
+ (!sect?.headers || sect.headers.length === 0)) {
601
+ const synth = this._synthesizeHeaderRefs();
602
+ if (synth.length > 0) {
603
+ sect = { ...(sect ?? {}), headers: synth };
604
+ }
605
+ }
606
+ if (this._options.footers &&
607
+ this._options.footers.size > 0 &&
608
+ (!sect?.footers || sect.footers.length === 0)) {
609
+ const synth = this._synthesizeFooterRefs();
610
+ if (synth.length > 0) {
611
+ sect = { ...(sect ?? {}), footers: synth };
612
+ }
613
+ }
614
+ // Watermark always needs its own header reference, but Word resolves
615
+ // multiple `<w:headerReference w:type="default">` children
616
+ // implementation-defined, so we replace any existing default-type
617
+ // ref instead of stacking them. (User-supplied first/even refs stay.)
618
+ if (this._watermarkHeaderRid) {
619
+ const headers = sect?.headers ? [...sect.headers] : [];
620
+ const filtered = headers.filter(h => h.type !== "default");
621
+ filtered.push({ type: "default", rId: this._watermarkHeaderRid });
622
+ sect = { ...(sect ?? {}), headers: filtered };
623
+ }
624
+ if (sect) {
625
+ const writer = new writer_1.XmlWriter();
626
+ (0, section_writer_1.renderSectionProperties)(writer, sect);
627
+ this._write(writer.xml);
628
+ }
629
+ else {
630
+ // OOXML CT_Body requires a final <w:sectPr> so Word knows the page
631
+ // geometry. When the caller didn't provide one, fall back to the
632
+ // same default that Document.build() uses (US Letter, 1" margins).
633
+ const writer = new writer_1.XmlWriter();
634
+ (0, section_writer_1.renderSectionProperties)(writer, {
635
+ pageSize: { width: 12240, height: 15840 },
636
+ margins: { top: 1440, right: 1440, bottom: 1440, left: 1440 }
637
+ });
638
+ this._write(writer.xml);
639
+ }
640
+ // Close body and document
641
+ this._write(`</w:body></w:document>`);
642
+ }
643
+ /**
644
+ * Allocate header/footer relationship IDs deterministically (in the same
645
+ * order auxiliary parts will be emitted). Called once during finalize so
646
+ * `_writeDocumentFooter` and `_addAuxiliaryParts` agree on which rId
647
+ * points at which header/footer XML part.
648
+ */
649
+ _allocateHeaderFooterRIds() {
650
+ if (this._options.headers) {
651
+ let idx = 1;
652
+ for (const [key] of this._options.headers) {
653
+ const rId = (0, relationships_1.addRelationship)(this._documentRels, constants_1.RelType.Header, `header${idx}.xml`);
654
+ this._headerKeyToRid.set(key, rId);
655
+ idx++;
656
+ }
657
+ // Watermark consumes the next header slot.
658
+ if (this._options.watermark) {
659
+ this._watermarkHeaderRid = (0, relationships_1.addRelationship)(this._documentRels, constants_1.RelType.Header, `header${idx}.xml`);
660
+ }
661
+ }
662
+ else if (this._options.watermark) {
663
+ this._watermarkHeaderRid = (0, relationships_1.addRelationship)(this._documentRels, constants_1.RelType.Header, "header1.xml");
664
+ }
665
+ if (this._options.footers) {
666
+ let idx = 1;
667
+ for (const [key] of this._options.footers) {
668
+ const rId = (0, relationships_1.addRelationship)(this._documentRels, constants_1.RelType.Footer, `footer${idx}.xml`);
669
+ this._footerKeyToRid.set(key, rId);
670
+ idx++;
671
+ }
672
+ }
673
+ }
674
+ _rewireSectionRefs(sect) {
675
+ const allowedHeader = new Set(this._headerKeyToRid.values());
676
+ const allowedFooter = new Set(this._footerKeyToRid.values());
677
+ const resolveByTypeHeader = (type) => {
678
+ // Try direct map key match first (e.g. user passed map key === rId).
679
+ // Then fall back to a same-type lookup for the common builder case
680
+ // where keys are "default" / "first" / "even".
681
+ if (this._headerKeyToRid.has(type)) {
682
+ return this._headerKeyToRid.get(type);
683
+ }
684
+ return undefined;
685
+ };
686
+ const resolveByTypeFooter = (type) => {
687
+ if (this._footerKeyToRid.has(type)) {
688
+ return this._footerKeyToRid.get(type);
689
+ }
690
+ return undefined;
691
+ };
692
+ let out = sect;
693
+ if (sect.headers) {
694
+ const resolved = [];
695
+ for (const ref of sect.headers) {
696
+ if (ref.rId && allowedHeader.has(ref.rId)) {
697
+ resolved.push(ref);
698
+ continue;
699
+ }
700
+ if (ref.rId && this._headerKeyToRid.has(ref.rId)) {
701
+ resolved.push({ ...ref, rId: this._headerKeyToRid.get(ref.rId) });
702
+ continue;
703
+ }
704
+ const byType = resolveByTypeHeader(ref.type);
705
+ if (byType) {
706
+ resolved.push({ ...ref, rId: byType });
707
+ }
708
+ // else drop — no matching part part, do not emit dangling rId.
709
+ }
710
+ if (resolved.length !== sect.headers.length ||
711
+ resolved.some((r, i) => r !== sect.headers[i])) {
712
+ out = { ...out, headers: resolved };
713
+ }
714
+ }
715
+ if (sect.footers) {
716
+ const resolved = [];
717
+ for (const ref of sect.footers) {
718
+ if (ref.rId && allowedFooter.has(ref.rId)) {
719
+ resolved.push(ref);
720
+ continue;
721
+ }
722
+ if (ref.rId && this._footerKeyToRid.has(ref.rId)) {
723
+ resolved.push({ ...ref, rId: this._footerKeyToRid.get(ref.rId) });
724
+ continue;
725
+ }
726
+ const byType = resolveByTypeFooter(ref.type);
727
+ if (byType) {
728
+ resolved.push({ ...ref, rId: byType });
729
+ }
730
+ }
731
+ if (resolved.length !== sect.footers.length ||
732
+ resolved.some((r, i) => r !== sect.footers[i])) {
733
+ out = { ...out, footers: resolved };
734
+ }
735
+ }
736
+ return out;
737
+ }
738
+ /**
739
+ * Synthesise section-property header references for every header part
740
+ * the caller registered. Recognised type keys (`default`/`first`/`even`)
741
+ * keep their semantics; any other key (round-tripped rId names from
742
+ * readDocx, custom strings) falls back to `"default"` so the header is
743
+ * actually referenced — without this fallback header parts can sit in
744
+ * the package as dangling content.
745
+ *
746
+ * If multiple keys map to the same logical type, only the first one is
747
+ * kept so we don't emit two `<w:headerReference w:type="default">`
748
+ * children (Word's behaviour with duplicates is implementation-defined).
749
+ */
750
+ _synthesizeHeaderRefs() {
751
+ const out = [];
752
+ const seenTypes = new Set();
753
+ for (const [key, rId] of this._headerKeyToRid) {
754
+ const type = key === "default" || key === "first" || key === "even" ? key : "default";
755
+ if (seenTypes.has(type)) {
756
+ continue;
757
+ }
758
+ seenTypes.add(type);
759
+ out.push({ type, rId });
760
+ }
761
+ return out;
762
+ }
763
+ _synthesizeFooterRefs() {
764
+ const out = [];
765
+ const seenTypes = new Set();
766
+ for (const [key, rId] of this._footerKeyToRid) {
767
+ const type = key === "default" || key === "first" || key === "even" ? key : "default";
768
+ if (seenTypes.has(type)) {
769
+ continue;
770
+ }
771
+ seenTypes.add(type);
772
+ out.push({ type, rId });
773
+ }
774
+ return out;
775
+ }
776
+ // ===========================================================================
777
+ // Private: Auxiliary parts
778
+ // ===========================================================================
779
+ async _addAuxiliaryParts() {
780
+ const level = this._options.compressionLevel ?? 6;
781
+ // Helper: add a complete XML file to the ZIP
782
+ const addXmlFile = (path, renderFn) => {
783
+ const writer = new writer_1.XmlWriter();
784
+ renderFn(writer);
785
+ const data = internal_utils_1.utf8Encoder.encode(writer.xml);
786
+ const file = new stream_1.ZipDeflate(path, { level });
787
+ this._zip.add(file);
788
+ file.push(data, true);
789
+ };
790
+ // Content types and relationships
791
+ const contentTypes = (0, content_types_1.createContentTypes)();
792
+ const packageRels = (0, relationships_1.createRelationships)();
793
+ // Reuse the document relationships state we have been populating during
794
+ // add() (charts, hyperlinks, images). Adding the standard parts below
795
+ // augments this state.
796
+ const documentRels = this._documentRels;
797
+ // Package relationships
798
+ (0, relationships_1.addRelationship)(packageRels, constants_1.RelType.OfficeDocument, "word/document.xml");
799
+ (0, relationships_1.addRelationship)(packageRels, constants_1.RelType.CoreProperties, "docProps/core.xml");
800
+ (0, relationships_1.addRelationship)(packageRels, constants_1.RelType.ExtendedProperties, "docProps/app.xml");
801
+ // [Content_Types].xml MUST declare every part. The package
802
+ // relationships file references docProps/core.xml + docProps/app.xml
803
+ // even when the caller didn't supply explicit metadata, so we must
804
+ // register their content types up-front; otherwise Word/LibreOffice
805
+ // refuse to open the file (rejected at the OPC layer before any
806
+ // schema validation).
807
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${constants_1.PartPath.CoreProps}`, constants_1.ContentType.CoreProperties);
808
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${constants_1.PartPath.AppProps}`, constants_1.ContentType.ExtendedProperties);
809
+ // Document relationships
810
+ (0, relationships_1.addRelationship)(documentRels, constants_1.RelType.Styles, "styles.xml");
811
+ (0, relationships_1.addRelationship)(documentRels, constants_1.RelType.Settings, "settings.xml");
812
+ (0, relationships_1.addRelationship)(documentRels, constants_1.RelType.FontTable, "fontTable.xml");
813
+ (0, relationships_1.addRelationship)(documentRels, constants_1.RelType.Theme, "theme/theme1.xml");
814
+ // Numbering
815
+ const hasNumbering = (this._options.abstractNumberings && this._options.abstractNumberings.length > 0) ||
816
+ (this._options.numberingInstances && this._options.numberingInstances.length > 0);
817
+ if (hasNumbering) {
818
+ (0, relationships_1.addRelationship)(documentRels, constants_1.RelType.Numbering, "numbering.xml");
819
+ }
820
+ // Footnotes — including their own .rels for in-note hyperlinks/images.
821
+ if (this._options.footnotes && this._options.footnotes.length > 0) {
822
+ (0, relationships_1.addRelationship)(documentRels, constants_1.RelType.Footnotes, "footnotes.xml");
823
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${constants_1.PartPath.Footnotes}`, constants_1.ContentType.Footnotes);
824
+ const fnRels = (0, relationships_1.createRelationships)();
825
+ const fnLinks = (0, reference_scanners_1.collectHyperlinksFromNotes)(this._options.footnotes);
826
+ for (const link of fnLinks) {
827
+ if (link.url) {
828
+ const safe = (0, internal_utils_1.sanitizeUrl)(link.url);
829
+ if (!safe) {
830
+ continue;
831
+ }
832
+ const linkRId = (0, relationships_1.addRelationship)(fnRels, constants_1.RelType.Hyperlink, safe, "External");
833
+ this._renderCtx.hyperlinkRIds.set(link, linkRId);
834
+ }
835
+ }
836
+ const fnImgs = (0, reference_scanners_1.collectImageRidsFromNotes)(this._options.footnotes);
837
+ for (const oldRid of fnImgs) {
838
+ const img = this._lookupImage(oldRid);
839
+ if (img) {
840
+ (0, relationships_1.addRelationshipWithId)(fnRels, oldRid, constants_1.RelType.Image, `media/${img.fileName}`);
841
+ }
842
+ }
843
+ if ((0, relationships_1.getRelationshipCount)(fnRels) > 0) {
844
+ addXmlFile(`word/_rels/footnotes.xml.rels`, xml => (0, relationships_1.renderRelationships)(fnRels, xml));
845
+ }
846
+ // Footnote XML rendering itself happens in buildCommonAuxiliaryParts.
847
+ }
848
+ // Endnotes — same treatment as footnotes.
849
+ if (this._options.endnotes && this._options.endnotes.length > 0) {
850
+ (0, relationships_1.addRelationship)(documentRels, constants_1.RelType.Endnotes, "endnotes.xml");
851
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${constants_1.PartPath.Endnotes}`, constants_1.ContentType.Endnotes);
852
+ const enRels = (0, relationships_1.createRelationships)();
853
+ const enLinks = (0, reference_scanners_1.collectHyperlinksFromNotes)(this._options.endnotes);
854
+ for (const link of enLinks) {
855
+ if (link.url) {
856
+ const safe = (0, internal_utils_1.sanitizeUrl)(link.url);
857
+ if (!safe) {
858
+ continue;
859
+ }
860
+ const linkRId = (0, relationships_1.addRelationship)(enRels, constants_1.RelType.Hyperlink, safe, "External");
861
+ this._renderCtx.hyperlinkRIds.set(link, linkRId);
862
+ }
863
+ }
864
+ const enImgs = (0, reference_scanners_1.collectImageRidsFromNotes)(this._options.endnotes);
865
+ for (const oldRid of enImgs) {
866
+ const img = this._lookupImage(oldRid);
867
+ if (img) {
868
+ (0, relationships_1.addRelationshipWithId)(enRels, oldRid, constants_1.RelType.Image, `media/${img.fileName}`);
869
+ }
870
+ }
871
+ if ((0, relationships_1.getRelationshipCount)(enRels) > 0) {
872
+ addXmlFile(`word/_rels/endnotes.xml.rels`, xml => (0, relationships_1.renderRelationships)(enRels, xml));
873
+ }
874
+ }
875
+ // Comments — including their own .rels for in-comment hyperlinks/images.
876
+ if (this._options.comments && this._options.comments.length > 0) {
877
+ (0, relationships_1.addRelationship)(documentRels, constants_1.RelType.Comments, "comments.xml");
878
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${constants_1.PartPath.Comments}`, constants_1.ContentType.Comments);
879
+ // Register hyperlink/image rels BEFORE rendering comments.xml so the
880
+ // emitted r:id values match the per-part .rels we are about to write.
881
+ const cmtRels = (0, relationships_1.createRelationships)();
882
+ const commentBodies = this._options.comments.map(c => ({ content: c.content }));
883
+ const cmtLinks = (0, reference_scanners_1.collectHyperlinksFromNotes)(commentBodies);
884
+ for (const link of cmtLinks) {
885
+ if (link.url) {
886
+ const safe = (0, internal_utils_1.sanitizeUrl)(link.url);
887
+ if (!safe) {
888
+ continue;
889
+ }
890
+ const linkRId = (0, relationships_1.addRelationship)(cmtRels, constants_1.RelType.Hyperlink, safe, "External");
891
+ this._renderCtx.hyperlinkRIds.set(link, linkRId);
892
+ }
893
+ }
894
+ const cmtImgs = (0, reference_scanners_1.collectImageRidsFromNotes)(commentBodies);
895
+ for (const oldRid of cmtImgs) {
896
+ const img = this._lookupImage(oldRid);
897
+ if (img) {
898
+ (0, relationships_1.addRelationshipWithId)(cmtRels, oldRid, constants_1.RelType.Image, `media/${img.fileName}`);
899
+ }
900
+ }
901
+ if ((0, relationships_1.getRelationshipCount)(cmtRels) > 0) {
902
+ addXmlFile(`word/_rels/comments.xml.rels`, xml => (0, relationships_1.renderRelationships)(cmtRels, xml));
903
+ }
904
+ addXmlFile(constants_1.PartPath.Comments, xml => (0, comment_writer_1.renderComments)(xml, this._options.comments, {
905
+ imageRemap: this._renderCtx.imageRIdRemap,
906
+ hyperlinkRIds: this._renderCtx.hyperlinkRIds,
907
+ rawXmlPolicy: this._renderCtx.rawXmlPolicy
908
+ }));
909
+ // Also write commentsExtended if any have done/parentId
910
+ const hasExtended = this._options.comments.some(c => c.done != null || c.parentId != null);
911
+ if (hasExtended) {
912
+ (0, relationships_1.addRelationship)(documentRels, constants_1.RelType.CommentsExtended, "commentsExtended.xml");
913
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${constants_1.PartPath.CommentsExtended}`, constants_1.ContentType.CommentsExtended);
914
+ addXmlFile(constants_1.PartPath.CommentsExtended, xml => (0, comment_writer_1.renderCommentsExtended)(xml, this._options.comments));
915
+ }
916
+ }
917
+ // Headers
918
+ //
919
+ // Each header part has its own .rels file. Image / hyperlink / chart
920
+ // references inside header content must register against THAT part's
921
+ // .rels — they are not document.xml.rels relationships, so we mirror
922
+ // the bulk packager's behaviour here to avoid producing dangling
923
+ // r:embed / r:id values inside header XML.
924
+ //
925
+ // The document-level rId for each header was already allocated during
926
+ // `_allocateHeaderFooterRIds` so that section properties and header
927
+ // parts agree.
928
+ let nextHeaderIdx = 1;
929
+ if (this._options.headers) {
930
+ for (const [, headerDef] of this._options.headers) {
931
+ const headerIdx = nextHeaderIdx++;
932
+ const headerPath = constants_1.PartPath.header(headerIdx);
933
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${headerPath}`, constants_1.ContentType.Header);
934
+ // Register relationships BEFORE rendering the header XML, otherwise
935
+ // the writer cannot resolve the freshly-allocated hyperlink rIds and
936
+ // emits dangling r:id values. addXmlFile() invokes the render
937
+ // callback synchronously, so the order matters.
938
+ const hRels = (0, relationships_1.createRelationships)();
939
+ // Images: register every rId referenced inside this header that the
940
+ // caller supplied a binary for. Header XML emits `r:embed` using the
941
+ // model rId, so we register under the same id.
942
+ const imgRids = (0, reference_scanners_1.collectImageRidsFromContent)(headerDef.content);
943
+ for (const oldRid of imgRids) {
944
+ const img = this._lookupImage(oldRid);
945
+ if (img) {
946
+ (0, relationships_1.addRelationshipWithId)(hRels, oldRid, constants_1.RelType.Image, `media/${img.fileName}`);
947
+ }
948
+ }
949
+ // Hyperlinks: same scheme as bulk packager — assign a fresh rId per
950
+ // header for any URL-bearing hyperlink and surface it via
951
+ // hyperlinkRIds so the writer emits matching r:id.
952
+ const hLinks = (0, reference_scanners_1.collectHyperlinksFromHeaderFooter)(headerDef.content);
953
+ for (const link of hLinks) {
954
+ if (link.url) {
955
+ const safe = (0, internal_utils_1.sanitizeUrl)(link.url);
956
+ if (!safe) {
957
+ continue;
958
+ }
959
+ const linkRId = (0, relationships_1.addRelationship)(hRels, constants_1.RelType.Hyperlink, safe, "External");
960
+ this._renderCtx.hyperlinkRIds.set(link, linkRId);
961
+ }
962
+ }
963
+ // Charts: collect into _bodyCharts so a chart part is generated, and
964
+ // register the rel against the header's own .rels.
965
+ const headerCharts = [];
966
+ (0, reference_scanners_1.collectChartsFromHeaderFooter)(headerDef.content, headerCharts);
967
+ for (const chartContent of headerCharts) {
968
+ if (this._renderCtx.chartRIds.has(chartContent)) {
969
+ continue;
970
+ }
971
+ const num = ++this._nextChartSeq;
972
+ const rId = (0, relationships_1.addRelationship)(hRels, constants_1.RelType.Chart, `charts/chart${num}.xml`);
973
+ this._renderCtx.chartRIds.set(chartContent, rId);
974
+ this._chartNum.set(chartContent, num);
975
+ this._bodyCharts.push(chartContent);
976
+ }
977
+ addXmlFile(headerPath, xml => (0, header_footer_writer_1.renderHeader)(xml, headerDef.content, {
978
+ imageRemap: this._renderCtx.imageRIdRemap,
979
+ hyperlinkRIds: this._renderCtx.hyperlinkRIds,
980
+ rawXmlPolicy: this._renderCtx.rawXmlPolicy
981
+ }));
982
+ if ((0, relationships_1.getRelationshipCount)(hRels) > 0) {
983
+ addXmlFile(`word/_rels/header${headerIdx}.xml.rels`, xml => (0, relationships_1.renderRelationships)(hRels, xml));
984
+ }
985
+ }
986
+ }
987
+ // Watermark — always rendered as its own header part appended after any
988
+ // user-supplied headers. Its rId was allocated during
989
+ // `_allocateHeaderFooterRIds`.
990
+ if (this._options.watermark) {
991
+ const watermarkIdx = nextHeaderIdx++;
992
+ const watermarkPath = constants_1.PartPath.header(watermarkIdx);
993
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${watermarkPath}`, constants_1.ContentType.Header);
994
+ addXmlFile(watermarkPath, xml => (0, header_footer_writer_1.renderWatermarkHeader)(xml, this._options.watermark));
995
+ // Image watermarks need a per-header relationship to the image binary.
996
+ if (this._options.watermark.type === "image") {
997
+ const wmRId = this._options.watermark.rId;
998
+ const img = this._lookupImage(wmRId);
999
+ if (img) {
1000
+ const wmRels = (0, relationships_1.createRelationships)();
1001
+ (0, relationships_1.addRelationshipWithId)(wmRels, wmRId, constants_1.RelType.Image, `media/${img.fileName}`);
1002
+ addXmlFile(`word/_rels/header${watermarkIdx}.xml.rels`, xml => (0, relationships_1.renderRelationships)(wmRels, xml));
1003
+ }
1004
+ }
1005
+ }
1006
+ // Footers — document-level rIds already allocated during
1007
+ // `_allocateHeaderFooterRIds`.
1008
+ if (this._options.footers) {
1009
+ let footerIdx = 1;
1010
+ for (const [, footerDef] of this._options.footers) {
1011
+ const footerPath = constants_1.PartPath.footer(footerIdx);
1012
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${footerPath}`, constants_1.ContentType.Footer);
1013
+ // Register relationships BEFORE rendering. addXmlFile() runs the
1014
+ // callback synchronously so any hyperlink rIds the renderer needs
1015
+ // must already be in this._renderCtx.hyperlinkRIds.
1016
+ const fRels = (0, relationships_1.createRelationships)();
1017
+ const imgRids = (0, reference_scanners_1.collectImageRidsFromContent)(footerDef.content);
1018
+ for (const oldRid of imgRids) {
1019
+ const img = this._lookupImage(oldRid);
1020
+ if (img) {
1021
+ (0, relationships_1.addRelationshipWithId)(fRels, oldRid, constants_1.RelType.Image, `media/${img.fileName}`);
1022
+ }
1023
+ }
1024
+ const fLinks = (0, reference_scanners_1.collectHyperlinksFromHeaderFooter)(footerDef.content);
1025
+ for (const link of fLinks) {
1026
+ if (link.url) {
1027
+ const safe = (0, internal_utils_1.sanitizeUrl)(link.url);
1028
+ if (!safe) {
1029
+ continue;
1030
+ }
1031
+ const linkRId = (0, relationships_1.addRelationship)(fRels, constants_1.RelType.Hyperlink, safe, "External");
1032
+ this._renderCtx.hyperlinkRIds.set(link, linkRId);
1033
+ }
1034
+ }
1035
+ const footerCharts = [];
1036
+ (0, reference_scanners_1.collectChartsFromHeaderFooter)(footerDef.content, footerCharts);
1037
+ for (const chartContent of footerCharts) {
1038
+ if (this._renderCtx.chartRIds.has(chartContent)) {
1039
+ continue;
1040
+ }
1041
+ const num = ++this._nextChartSeq;
1042
+ const rId = (0, relationships_1.addRelationship)(fRels, constants_1.RelType.Chart, `charts/chart${num}.xml`);
1043
+ this._renderCtx.chartRIds.set(chartContent, rId);
1044
+ this._chartNum.set(chartContent, num);
1045
+ this._bodyCharts.push(chartContent);
1046
+ }
1047
+ addXmlFile(footerPath, xml => (0, header_footer_writer_1.renderFooter)(xml, footerDef.content, {
1048
+ imageRemap: this._renderCtx.imageRIdRemap,
1049
+ hyperlinkRIds: this._renderCtx.hyperlinkRIds,
1050
+ rawXmlPolicy: this._renderCtx.rawXmlPolicy
1051
+ }));
1052
+ if ((0, relationships_1.getRelationshipCount)(fRels) > 0) {
1053
+ addXmlFile(`word/_rels/footer${footerIdx}.xml.rels`, xml => (0, relationships_1.renderRelationships)(fRels, xml));
1054
+ }
1055
+ footerIdx++;
1056
+ }
1057
+ }
1058
+ // Custom properties
1059
+ if (this._options.customProperties && this._options.customProperties.length > 0) {
1060
+ (0, relationships_1.addRelationship)(packageRels, constants_1.RelType.CustomProperties, "docProps/custom.xml");
1061
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${constants_1.PartPath.CustomProps}`, constants_1.ContentType.CustomProperties);
1062
+ // XML rendering handled by buildCommonAuxiliaryParts below
1063
+ }
1064
+ // Images. Only register images here that were not already registered
1065
+ // by `_registerImageRId` during add(). For round-tripped models, the
1066
+ // image's `aliasRIds` may have been registered earlier (when a
1067
+ // header/footer body referenced the image under one of those alias
1068
+ // names) — treat any of those aliases as "already registered" so we
1069
+ // don't duplicate the relationship under the canonical rId. Images
1070
+ // supplied via options but never referenced in body content also get
1071
+ // registered (since the user clearly intended them to be part of the
1072
+ // document) but with an anonymous rId.
1073
+ if (this._options.images) {
1074
+ const extensions = new Set();
1075
+ for (const img of this._options.images) {
1076
+ const ext = (0, opc_paths_1.getFileExt)(img.fileName);
1077
+ if (ext) {
1078
+ extensions.add(ext);
1079
+ }
1080
+ const alreadyRegistered = (img.rId && this._registeredImageRIds.has(img.rId)) ||
1081
+ (img.aliasRIds && img.aliasRIds.some(a => this._registeredImageRIds.has(a)));
1082
+ if (alreadyRegistered) {
1083
+ continue;
1084
+ }
1085
+ if (img.rId) {
1086
+ (0, relationships_1.addRelationshipWithId)(documentRels, img.rId, constants_1.RelType.Image, `media/${img.fileName}`);
1087
+ this._registeredImageRIds.add(img.rId);
1088
+ }
1089
+ else {
1090
+ (0, relationships_1.addRelationship)(documentRels, constants_1.RelType.Image, `media/${img.fileName}`);
1091
+ }
1092
+ }
1093
+ (0, content_types_1.addImageContentTypeDefaults)(contentTypes, extensions);
1094
+ }
1095
+ // Custom XML parts (for SDT data binding)
1096
+ if (this._options.customXmlParts && this._options.customXmlParts.length > 0) {
1097
+ this._options.customXmlParts.forEach((part, i) => {
1098
+ const num = i + 1;
1099
+ const itemPath = `word/customXml/item${num}.xml`;
1100
+ const propsPath = `word/customXml/itemProps${num}.xml`;
1101
+ // Write the XML content
1102
+ const itemData = internal_utils_1.utf8Encoder.encode(part.xmlContent);
1103
+ const itemFile = new stream_1.ZipDeflate(itemPath, { level });
1104
+ this._zip.add(itemFile);
1105
+ itemFile.push(itemData, true);
1106
+ // Write itemProps*.xml
1107
+ const propsWriter = new writer_1.XmlWriter();
1108
+ propsWriter.openXml(constants_1.STD_DOC_ATTRIBUTES);
1109
+ propsWriter.openNode("ds:datastoreItem", {
1110
+ "ds:itemID": `{${part.itemId}}`,
1111
+ "xmlns:ds": "http://schemas.openxmlformats.org/officeDocument/2006/customXml"
1112
+ });
1113
+ if (part.schemaReferences && part.schemaReferences.length > 0) {
1114
+ propsWriter.openNode("ds:schemaRefs");
1115
+ for (const uri of part.schemaReferences) {
1116
+ propsWriter.leafNode("ds:schemaRef", { "ds:uri": uri });
1117
+ }
1118
+ propsWriter.closeNode();
1119
+ }
1120
+ else {
1121
+ propsWriter.leafNode("ds:schemaRefs");
1122
+ }
1123
+ propsWriter.closeNode();
1124
+ const propsData = internal_utils_1.utf8Encoder.encode(propsWriter.xml);
1125
+ const propsFile = new stream_1.ZipDeflate(propsPath, { level });
1126
+ this._zip.add(propsFile);
1127
+ propsFile.push(propsData, true);
1128
+ // Write item rels (links itemN.xml → itemPropsN.xml)
1129
+ const itemRels = (0, relationships_1.createRelationships)();
1130
+ (0, relationships_1.addRelationship)(itemRels, constants_1.RelType.CustomXmlProps, `itemProps${num}.xml`);
1131
+ addXmlFile(`word/customXml/_rels/item${num}.xml.rels`, xml => (0, relationships_1.renderRelationships)(itemRels, xml));
1132
+ // Register content types
1133
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/word/customXml/itemProps${num}.xml`, "application/vnd.openxmlformats-officedocument.customXmlProperties+xml");
1134
+ // Add to document rels
1135
+ (0, relationships_1.addRelationship)(documentRels, constants_1.RelType.CustomXml, `customXml/item${num}.xml`);
1136
+ });
1137
+ }
1138
+ // Embedded fonts
1139
+ if (this._options.embeddedFonts && this._options.embeddedFonts.length > 0) {
1140
+ const fontTableRels = (0, relationships_1.createRelationships)();
1141
+ for (const ef of this._options.embeddedFonts) {
1142
+ const partPath = `word/fonts/${ef.fileName}`;
1143
+ const fontFile = new stream_1.ZipDeflate(partPath, { level: 0 });
1144
+ this._zip.add(fontFile);
1145
+ fontFile.push(ef.data, true);
1146
+ // Register relationship from fontTable.xml
1147
+ (0, relationships_1.addRelationshipWithId)(fontTableRels, ef.rId, constants_1.RelType.Font, `fonts/${ef.fileName}`);
1148
+ // Register content type for .odttf / .ttf / .otf
1149
+ const ext = (0, opc_paths_1.getFileExt)(ef.fileName);
1150
+ if (ext === "odttf") {
1151
+ (0, content_types_1.addContentTypeDefault)(contentTypes, "odttf", constants_1.ContentType.ObfuscatedFont);
1152
+ }
1153
+ else if (ext === "ttf") {
1154
+ (0, content_types_1.addContentTypeDefault)(contentTypes, "ttf", "application/x-font-ttf");
1155
+ }
1156
+ else if (ext === "otf") {
1157
+ (0, content_types_1.addContentTypeDefault)(contentTypes, "otf", "application/x-font-otf");
1158
+ }
1159
+ }
1160
+ // Write fontTable.xml.rels
1161
+ addXmlFile("word/_rels/fontTable.xml.rels", xml => (0, relationships_1.renderRelationships)(fontTableRels, xml));
1162
+ }
1163
+ // Opaque (unrecognized) parts for round-trip preservation
1164
+ if (this._options.opaqueParts) {
1165
+ const preserveOle = this._options.securityPolicy?.preserveOleObjects !== false;
1166
+ const dropSignatures = this._options.securityPolicy?.dropSignaturesOnModify !== false;
1167
+ for (const part of this._options.opaqueParts) {
1168
+ // Honour `preserveOleObjects`: skip OLE binaries when disabled.
1169
+ if (!preserveOle &&
1170
+ (part.path.startsWith("word/embeddings/") ||
1171
+ (part.path.endsWith(".bin") && part.path.includes("embed")))) {
1172
+ continue;
1173
+ }
1174
+ // Honour `dropSignaturesOnModify`: signatures cease to be valid the
1175
+ // moment the document is re-serialised, so by default we drop them.
1176
+ if (dropSignatures && part.path.startsWith("_xmlsignatures/")) {
1177
+ continue;
1178
+ }
1179
+ const opaqueFile = new stream_1.ZipDeflate(part.path, { level });
1180
+ this._zip.add(opaqueFile);
1181
+ opaqueFile.push(part.data, true);
1182
+ // Register content type
1183
+ if (part.contentType) {
1184
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${part.path}`, part.contentType);
1185
+ }
1186
+ // Write part relationships if any
1187
+ if (part.relationships && part.relationships.length > 0) {
1188
+ const partRels = (0, relationships_1.createRelationships)();
1189
+ for (const rel of part.relationships) {
1190
+ (0, relationships_1.addRelationshipWithId)(partRels, rel.id, rel.type, rel.target, rel.targetMode);
1191
+ }
1192
+ const relsPath = (0, opc_paths_1.getPartRelsPath)(part.path);
1193
+ addXmlFile(relsPath, xml => (0, relationships_1.renderRelationships)(partRels, xml));
1194
+ }
1195
+ }
1196
+ }
1197
+ // Content type overrides
1198
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${constants_1.PartPath.Document}`, constants_1.ContentType.Document);
1199
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${constants_1.PartPath.Styles}`, constants_1.ContentType.Styles);
1200
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${constants_1.PartPath.Settings}`, constants_1.ContentType.Settings);
1201
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${constants_1.PartPath.FontTable}`, constants_1.ContentType.FontTable);
1202
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${constants_1.PartPath.Theme}`, constants_1.ContentType.Theme);
1203
+ if (hasNumbering) {
1204
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${constants_1.PartPath.Numbering}`, constants_1.ContentType.Numbering);
1205
+ }
1206
+ // Write common auxiliary parts (styles, settings, fontTable, theme, numbering, properties)
1207
+ // using the shared builder to avoid duplicating render logic with docx-packager.
1208
+ const commonParts = (0, common_parts_1.buildCommonAuxiliaryParts)({
1209
+ docDefaults: this._options.docDefaults,
1210
+ styles: this._options.styles,
1211
+ settings: this._options.settings,
1212
+ fonts: this._options.fonts,
1213
+ theme: this._options.theme,
1214
+ abstractNumberings: this._options.abstractNumberings,
1215
+ numberingInstances: this._options.numberingInstances,
1216
+ footnotes: this._options.footnotes,
1217
+ endnotes: this._options.endnotes,
1218
+ coreProperties: this._options.coreProperties,
1219
+ appProperties: this._options.appProperties,
1220
+ customProperties: this._options.customProperties,
1221
+ rawXmlPolicy: this._renderCtx.rawXmlPolicy,
1222
+ // Pass the shared rId tables so in-note hyperlinks (registered earlier
1223
+ // against footnotes.xml.rels / endnotes.xml.rels) resolve to the same
1224
+ // rIds the renderer is about to emit.
1225
+ notesHelpers: {
1226
+ imageRemap: this._renderCtx.imageRIdRemap,
1227
+ hyperlinkRIds: this._renderCtx.hyperlinkRIds,
1228
+ rawXmlPolicy: this._renderCtx.rawXmlPolicy
1229
+ }
1230
+ });
1231
+ for (const part of commonParts) {
1232
+ const data = internal_utils_1.utf8Encoder.encode(part.content);
1233
+ const file = new stream_1.ZipDeflate(part.path, { level });
1234
+ this._zip.add(file);
1235
+ file.push(data, true);
1236
+ }
1237
+ // Write images
1238
+ if (this._options.images) {
1239
+ for (const img of this._options.images) {
1240
+ const file = new stream_1.ZipDeflate(constants_1.PartPath.media(img.fileName), { level: 0 });
1241
+ this._zip.add(file);
1242
+ file.push(img.data, true);
1243
+ }
1244
+ }
1245
+ // Write chart parts (chartN.xml + content type) for body charts
1246
+ // registered during add(). Use the per-chart sequence number captured
1247
+ // at registration time so the rId target encoded in documentRels and
1248
+ // the actual ZIP entry name agree.
1249
+ for (const chartContent of this._bodyCharts) {
1250
+ const num = this._chartNum.get(chartContent);
1251
+ if (num === undefined) {
1252
+ continue; // shouldn't happen; defensive
1253
+ }
1254
+ const chartPath = `word/charts/chart${num}.xml`;
1255
+ const w = new writer_1.XmlWriter();
1256
+ (0, chart_writer_1.renderChartPart)(w, chartContent.chart);
1257
+ const data = internal_utils_1.utf8Encoder.encode(w.xml);
1258
+ const file = new stream_1.ZipDeflate(chartPath, { level });
1259
+ this._zip.add(file);
1260
+ file.push(data, true);
1261
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${chartPath}`, constants_1.ContentType.Chart);
1262
+ }
1263
+ // Write ChartEx parts (raw cx:chartSpace XML preserved on the model)
1264
+ for (const cxContent of this._bodyChartEx) {
1265
+ const num = this._chartNum.get(cxContent);
1266
+ if (num === undefined) {
1267
+ continue;
1268
+ }
1269
+ const cxPath = `word/charts/chartEx${num}.xml`;
1270
+ const data = internal_utils_1.utf8Encoder.encode(cxContent.chartExXml);
1271
+ const file = new stream_1.ZipDeflate(cxPath, { level });
1272
+ this._zip.add(file);
1273
+ file.push(data, true);
1274
+ (0, content_types_1.addContentTypeOverride)(contentTypes, `/${cxPath}`, constants_1.ContentType.ChartEx);
1275
+ }
1276
+ // Write document.xml.rels
1277
+ addXmlFile(constants_1.PartPath.DocumentRels, xml => (0, relationships_1.renderRelationships)(documentRels, xml));
1278
+ // Write _rels/.rels
1279
+ addXmlFile(constants_1.PartPath.PackageRels, xml => (0, relationships_1.renderRelationships)(packageRels, xml));
1280
+ // Write [Content_Types].xml
1281
+ addXmlFile(constants_1.PartPath.ContentTypes, xml => (0, content_types_1.renderContentTypes)(contentTypes, xml));
1282
+ }
1283
+ _endStream(stream) {
1284
+ return new Promise((resolve, reject) => {
1285
+ // If a prior callback already reported an error, surface it
1286
+ // synchronously instead of waiting for an event that won't fire.
1287
+ if (this._streamError) {
1288
+ reject(this._streamError);
1289
+ return;
1290
+ }
1291
+ stream.once("zipped", () => resolve());
1292
+ stream.once("error", (err) => reject(err));
1293
+ stream.end();
1294
+ });
1295
+ }
1296
+ _assembleOutput() {
1297
+ if (this._outputChunks.length === 1) {
1298
+ return this._outputChunks[0];
1299
+ }
1300
+ const total = this._outputChunks.reduce((sum, c) => sum + c.length, 0);
1301
+ const result = new Uint8Array(total);
1302
+ let offset = 0;
1303
+ for (const chunk of this._outputChunks) {
1304
+ result.set(chunk, offset);
1305
+ offset += chunk.length;
1306
+ }
1307
+ return result;
1308
+ }
1309
+ }
1310
+ exports.StreamingDocxWriter = StreamingDocxWriter;
1311
+ /**
1312
+ * Create a new streaming DOCX writer.
1313
+ *
1314
+ * @example
1315
+ * ```ts
1316
+ * const writer = createDocxStream({
1317
+ * styles: [{ type: "paragraph", styleId: "Normal", name: "Normal" }]
1318
+ * });
1319
+ *
1320
+ * for (let i = 0; i < 100000; i++) {
1321
+ * writer.addText(`Paragraph ${i}`);
1322
+ * }
1323
+ *
1324
+ * const buffer = await writer.finalize();
1325
+ * ```
1326
+ */
1327
+ function createDocxStream(options) {
1328
+ return new StreamingDocxWriter(options);
1329
+ }
1330
+ /**
1331
+ * Replace any image/font file names in `options` with a leaf form that's
1332
+ * safe to embed into a ZIP entry path. A new options object is returned;
1333
+ * the caller's input is not mutated.
1334
+ *
1335
+ * Names are deduplicated within their respective collection so two
1336
+ * different inputs that sanitise to the same string don't silently
1337
+ * overwrite each other in the output package.
1338
+ */
1339
+ function sanitizeStreamingOptions(options) {
1340
+ let next = options;
1341
+ if (options.images && options.images.length > 0) {
1342
+ const used = new Set();
1343
+ let mutated = false;
1344
+ const images = options.images.map(img => {
1345
+ const safe = uniqueSanitizedName(img.fileName, used, "image.bin");
1346
+ if (safe !== img.fileName) {
1347
+ mutated = true;
1348
+ return { ...img, fileName: safe };
1349
+ }
1350
+ return img;
1351
+ });
1352
+ if (mutated) {
1353
+ next = { ...next, images };
1354
+ }
1355
+ }
1356
+ if (options.embeddedFonts && options.embeddedFonts.length > 0) {
1357
+ const used = new Set();
1358
+ let mutated = false;
1359
+ const embeddedFonts = options.embeddedFonts.map(ef => {
1360
+ const safe = uniqueSanitizedName(ef.fileName, used, "font.bin");
1361
+ if (safe !== ef.fileName) {
1362
+ mutated = true;
1363
+ return { ...ef, fileName: safe };
1364
+ }
1365
+ return ef;
1366
+ });
1367
+ if (mutated) {
1368
+ next = { ...next, embeddedFonts };
1369
+ }
1370
+ }
1371
+ return next;
1372
+ }
1373
+ function uniqueSanitizedName(raw, used, fallback) {
1374
+ let candidate = (0, internal_utils_1.sanitizeMediaFileName)(raw, fallback);
1375
+ if (used.has(candidate)) {
1376
+ const dot = candidate.lastIndexOf(".");
1377
+ const stem = dot >= 0 ? candidate.slice(0, dot) : candidate;
1378
+ const ext = dot >= 0 ? candidate.slice(dot) : "";
1379
+ let n = 2;
1380
+ while (used.has(`${stem}_${n}${ext}`)) {
1381
+ n++;
1382
+ }
1383
+ candidate = `${stem}_${n}${ext}`;
1384
+ }
1385
+ used.add(candidate);
1386
+ return candidate;
1387
+ }