docxmlater 10.0.1 → 10.0.3

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 (395) hide show
  1. package/README.md +3 -2
  2. package/dist/constants/legacyCompatFlags.d.ts.map +1 -1
  3. package/dist/constants/legacyCompatFlags.js.map +1 -1
  4. package/dist/constants/limits.d.ts +0 -27
  5. package/dist/constants/limits.d.ts.map +1 -1
  6. package/dist/constants/limits.js +13 -13
  7. package/dist/constants/limits.js.map +1 -1
  8. package/dist/core/Document.d.ts +24 -19
  9. package/dist/core/Document.d.ts.map +1 -1
  10. package/dist/core/Document.js +272 -71
  11. package/dist/core/Document.js.map +1 -1
  12. package/dist/core/DocumentContent.d.ts.map +1 -1
  13. package/dist/core/DocumentContent.js.map +1 -1
  14. package/dist/core/DocumentGenerator.d.ts.map +1 -1
  15. package/dist/core/DocumentGenerator.js +59 -24
  16. package/dist/core/DocumentGenerator.js.map +1 -1
  17. package/dist/core/DocumentIdManager.d.ts.map +1 -1
  18. package/dist/core/DocumentIdManager.js.map +1 -1
  19. package/dist/core/DocumentParser.d.ts +6 -6
  20. package/dist/core/DocumentParser.d.ts.map +1 -1
  21. package/dist/core/DocumentParser.js +60 -54
  22. package/dist/core/DocumentParser.js.map +1 -1
  23. package/dist/core/DocumentValidator.d.ts.map +1 -1
  24. package/dist/core/DocumentValidator.js.map +1 -1
  25. package/dist/core/Relationship.d.ts.map +1 -1
  26. package/dist/core/Relationship.js +1 -1
  27. package/dist/core/Relationship.js.map +1 -1
  28. package/dist/core/RelationshipManager.js +3 -3
  29. package/dist/core/RelationshipManager.js.map +1 -1
  30. package/dist/elements/AlternateContent.js.map +1 -1
  31. package/dist/elements/Bookmark.d.ts.map +1 -1
  32. package/dist/elements/Bookmark.js.map +1 -1
  33. package/dist/elements/BookmarkManager.d.ts.map +1 -1
  34. package/dist/elements/BookmarkManager.js.map +1 -1
  35. package/dist/elements/Comment.js +1 -1
  36. package/dist/elements/Comment.js.map +1 -1
  37. package/dist/elements/CommentManager.d.ts.map +1 -1
  38. package/dist/elements/CommentManager.js +8 -2
  39. package/dist/elements/CommentManager.js.map +1 -1
  40. package/dist/elements/CommonTypes.d.ts.map +1 -1
  41. package/dist/elements/CommonTypes.js +1 -2
  42. package/dist/elements/CommonTypes.js.map +1 -1
  43. package/dist/elements/CustomXml.js.map +1 -1
  44. package/dist/elements/Endnote.d.ts.map +1 -1
  45. package/dist/elements/Endnote.js.map +1 -1
  46. package/dist/elements/EndnoteManager.d.ts.map +1 -1
  47. package/dist/elements/EndnoteManager.js.map +1 -1
  48. package/dist/elements/Field.d.ts.map +1 -1
  49. package/dist/elements/Field.js +31 -28
  50. package/dist/elements/Field.js.map +1 -1
  51. package/dist/elements/FieldHelpers.d.ts.map +1 -1
  52. package/dist/elements/FieldHelpers.js +6 -6
  53. package/dist/elements/FieldHelpers.js.map +1 -1
  54. package/dist/elements/FontManager.d.ts.map +1 -1
  55. package/dist/elements/FontManager.js.map +1 -1
  56. package/dist/elements/Footer.js.map +1 -1
  57. package/dist/elements/Footnote.d.ts.map +1 -1
  58. package/dist/elements/Footnote.js.map +1 -1
  59. package/dist/elements/FootnoteManager.d.ts.map +1 -1
  60. package/dist/elements/FootnoteManager.js.map +1 -1
  61. package/dist/elements/Header.js.map +1 -1
  62. package/dist/elements/HeaderFooterManager.js.map +1 -1
  63. package/dist/elements/Hyperlink.d.ts.map +1 -1
  64. package/dist/elements/Hyperlink.js +5 -5
  65. package/dist/elements/Hyperlink.js.map +1 -1
  66. package/dist/elements/Image.d.ts +2 -2
  67. package/dist/elements/Image.d.ts.map +1 -1
  68. package/dist/elements/Image.js +21 -5
  69. package/dist/elements/Image.js.map +1 -1
  70. package/dist/elements/ImageManager.d.ts.map +1 -1
  71. package/dist/elements/ImageManager.js +2 -2
  72. package/dist/elements/ImageManager.js.map +1 -1
  73. package/dist/elements/ImageRun.js.map +1 -1
  74. package/dist/elements/MathElement.js.map +1 -1
  75. package/dist/elements/Paragraph.d.ts.map +1 -1
  76. package/dist/elements/Paragraph.js +128 -117
  77. package/dist/elements/Paragraph.js.map +1 -1
  78. package/dist/elements/PreservedElement.js.map +1 -1
  79. package/dist/elements/PropertyChangeTypes.js.map +1 -1
  80. package/dist/elements/RangeMarker.js.map +1 -1
  81. package/dist/elements/Revision.d.ts +1 -0
  82. package/dist/elements/Revision.d.ts.map +1 -1
  83. package/dist/elements/Revision.js +44 -5
  84. package/dist/elements/Revision.js.map +1 -1
  85. package/dist/elements/RevisionContent.js.map +1 -1
  86. package/dist/elements/RevisionManager.d.ts.map +1 -1
  87. package/dist/elements/RevisionManager.js.map +1 -1
  88. package/dist/elements/Run.d.ts.map +1 -1
  89. package/dist/elements/Run.js +1 -3
  90. package/dist/elements/Run.js.map +1 -1
  91. package/dist/elements/Section.d.ts.map +1 -1
  92. package/dist/elements/Section.js +127 -118
  93. package/dist/elements/Section.js.map +1 -1
  94. package/dist/elements/Shape.d.ts.map +1 -1
  95. package/dist/elements/Shape.js +21 -0
  96. package/dist/elements/Shape.js.map +1 -1
  97. package/dist/elements/StructuredDocumentTag.d.ts.map +1 -1
  98. package/dist/elements/StructuredDocumentTag.js +20 -8
  99. package/dist/elements/StructuredDocumentTag.js.map +1 -1
  100. package/dist/elements/Table.d.ts +2 -2
  101. package/dist/elements/Table.d.ts.map +1 -1
  102. package/dist/elements/Table.js +29 -35
  103. package/dist/elements/Table.js.map +1 -1
  104. package/dist/elements/TableCell.d.ts +2 -2
  105. package/dist/elements/TableCell.d.ts.map +1 -1
  106. package/dist/elements/TableCell.js +63 -67
  107. package/dist/elements/TableCell.js.map +1 -1
  108. package/dist/elements/TableGridChange.js.map +1 -1
  109. package/dist/elements/TableOfContents.d.ts +6 -6
  110. package/dist/elements/TableOfContents.d.ts.map +1 -1
  111. package/dist/elements/TableOfContents.js.map +1 -1
  112. package/dist/elements/TableOfContentsElement.js.map +1 -1
  113. package/dist/elements/TableRow.d.ts.map +1 -1
  114. package/dist/elements/TableRow.js +65 -47
  115. package/dist/elements/TableRow.js.map +1 -1
  116. package/dist/elements/TextBox.d.ts.map +1 -1
  117. package/dist/elements/TextBox.js +1 -1
  118. package/dist/elements/TextBox.js.map +1 -1
  119. package/dist/formatting/AbstractNumbering.d.ts +1 -1
  120. package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
  121. package/dist/formatting/AbstractNumbering.js +11 -11
  122. package/dist/formatting/AbstractNumbering.js.map +1 -1
  123. package/dist/formatting/NumberingInstance.d.ts.map +1 -1
  124. package/dist/formatting/NumberingInstance.js +4 -4
  125. package/dist/formatting/NumberingInstance.js.map +1 -1
  126. package/dist/formatting/NumberingLevel.d.ts.map +1 -1
  127. package/dist/formatting/NumberingLevel.js +26 -26
  128. package/dist/formatting/NumberingLevel.js.map +1 -1
  129. package/dist/formatting/NumberingManager.d.ts +1 -1
  130. package/dist/formatting/NumberingManager.d.ts.map +1 -1
  131. package/dist/formatting/NumberingManager.js.map +1 -1
  132. package/dist/formatting/Style.d.ts.map +1 -1
  133. package/dist/formatting/Style.js +87 -95
  134. package/dist/formatting/Style.js.map +1 -1
  135. package/dist/formatting/StylesManager.d.ts +3 -3
  136. package/dist/formatting/StylesManager.d.ts.map +1 -1
  137. package/dist/formatting/StylesManager.js.map +1 -1
  138. package/dist/helpers/CleanupHelper.d.ts.map +1 -1
  139. package/dist/helpers/CleanupHelper.js +1 -7
  140. package/dist/helpers/CleanupHelper.js.map +1 -1
  141. package/dist/images/ImageOptimizer.js.map +1 -1
  142. package/dist/index.js.map +1 -1
  143. package/dist/managers/DrawingManager.d.ts.map +1 -1
  144. package/dist/managers/DrawingManager.js.map +1 -1
  145. package/dist/tracking/DocumentTrackingContext.js.map +1 -1
  146. package/dist/tracking/TrackingContext.js.map +1 -1
  147. package/dist/types/compatibility-types.js.map +1 -1
  148. package/dist/types/formatting.js.map +1 -1
  149. package/dist/types/list-types.d.ts +4 -4
  150. package/dist/types/list-types.d.ts.map +1 -1
  151. package/dist/types/list-types.js.map +1 -1
  152. package/dist/types/settings-types.js.map +1 -1
  153. package/dist/types/styleConfig.js.map +1 -1
  154. package/dist/utils/ChangelogGenerator.d.ts.map +1 -1
  155. package/dist/utils/ChangelogGenerator.js.map +1 -1
  156. package/dist/utils/CompatibilityUpgrader.d.ts.map +1 -1
  157. package/dist/utils/CompatibilityUpgrader.js +7 -7
  158. package/dist/utils/CompatibilityUpgrader.js.map +1 -1
  159. package/dist/utils/InMemoryRevisionAcceptor.js +1 -1
  160. package/dist/utils/InMemoryRevisionAcceptor.js.map +1 -1
  161. package/dist/utils/MoveOperationHelper.js.map +1 -1
  162. package/dist/utils/RevisionAwareProcessor.js.map +1 -1
  163. package/dist/utils/RevisionWalker.js.map +1 -1
  164. package/dist/utils/SelectiveRevisionAcceptor.js.map +1 -1
  165. package/dist/utils/ShadingResolver.js +1 -1
  166. package/dist/utils/ShadingResolver.js.map +1 -1
  167. package/dist/utils/acceptRevisions.d.ts +0 -28
  168. package/dist/utils/acceptRevisions.d.ts.map +1 -1
  169. package/dist/utils/acceptRevisions.js +5 -7
  170. package/dist/utils/acceptRevisions.js.map +1 -1
  171. package/dist/utils/cnfStyleDecoder.js +1 -1
  172. package/dist/utils/cnfStyleDecoder.js.map +1 -1
  173. package/dist/utils/corruptionDetection.js.map +1 -1
  174. package/dist/utils/dateFormatting.js.map +1 -1
  175. package/dist/utils/deepClone.d.ts +0 -1
  176. package/dist/utils/deepClone.d.ts.map +1 -1
  177. package/dist/utils/deepClone.js +0 -7
  178. package/dist/utils/deepClone.js.map +1 -1
  179. package/dist/utils/diagnostics.d.ts +2 -2
  180. package/dist/utils/diagnostics.d.ts.map +1 -1
  181. package/dist/utils/diagnostics.js.map +1 -1
  182. package/dist/utils/errorHandling.js.map +1 -1
  183. package/dist/utils/formatting.js.map +1 -1
  184. package/dist/utils/list-detection.d.ts +2 -2
  185. package/dist/utils/list-detection.d.ts.map +1 -1
  186. package/dist/utils/list-detection.js +3 -3
  187. package/dist/utils/list-detection.js.map +1 -1
  188. package/dist/utils/logger.d.ts +2 -4
  189. package/dist/utils/logger.d.ts.map +1 -1
  190. package/dist/utils/logger.js +0 -2
  191. package/dist/utils/logger.js.map +1 -1
  192. package/dist/utils/parsingHelpers.js.map +1 -1
  193. package/dist/utils/stripTrackedChanges.d.ts +0 -19
  194. package/dist/utils/stripTrackedChanges.d.ts.map +1 -1
  195. package/dist/utils/stripTrackedChanges.js +0 -2
  196. package/dist/utils/stripTrackedChanges.js.map +1 -1
  197. package/dist/utils/textDiff.js.map +1 -1
  198. package/dist/utils/units.js.map +1 -1
  199. package/dist/utils/validation.d.ts.map +1 -1
  200. package/dist/utils/validation.js.map +1 -1
  201. package/dist/utils/xmlSanitization.js.map +1 -1
  202. package/dist/validation/RevisionAutoFixer.js.map +1 -1
  203. package/dist/validation/RevisionValidator.js.map +1 -1
  204. package/dist/validation/ValidationRules.js.map +1 -1
  205. package/dist/validation/index.js.map +1 -1
  206. package/dist/xml/XMLBuilder.d.ts.map +1 -1
  207. package/dist/xml/XMLBuilder.js +10 -0
  208. package/dist/xml/XMLBuilder.js.map +1 -1
  209. package/dist/xml/XMLParser.d.ts.map +1 -1
  210. package/dist/xml/XMLParser.js +4 -5
  211. package/dist/xml/XMLParser.js.map +1 -1
  212. package/dist/zip/ZipHandler.js.map +1 -1
  213. package/dist/zip/ZipReader.js.map +1 -1
  214. package/dist/zip/ZipWriter.js.map +1 -1
  215. package/dist/zip/errors.js.map +1 -1
  216. package/dist/zip/types.js.map +1 -1
  217. package/package.json +34 -4
  218. package/src/__tests__/helper-methods.test.ts +512 -0
  219. package/src/constants/legacyCompatFlags.ts +138 -0
  220. package/src/constants/limits.ts +50 -0
  221. package/src/core/CLAUDE.md +109 -0
  222. package/src/core/Document.ts +15569 -0
  223. package/src/core/DocumentContent.ts +467 -0
  224. package/src/core/DocumentGenerator.ts +1104 -0
  225. package/src/core/DocumentIdManager.ts +158 -0
  226. package/src/core/DocumentParser.ts +10107 -0
  227. package/src/core/DocumentValidator.ts +372 -0
  228. package/src/core/Relationship.ts +367 -0
  229. package/src/core/RelationshipManager.ts +428 -0
  230. package/src/elements/AlternateContent.ts +42 -0
  231. package/src/elements/Bookmark.ts +210 -0
  232. package/src/elements/BookmarkManager.ts +250 -0
  233. package/src/elements/CLAUDE.md +126 -0
  234. package/src/elements/Comment.ts +359 -0
  235. package/src/elements/CommentManager.ts +502 -0
  236. package/src/elements/CommonTypes.ts +549 -0
  237. package/src/elements/CustomXml.ts +36 -0
  238. package/src/elements/Endnote.ts +217 -0
  239. package/src/elements/EndnoteManager.ts +249 -0
  240. package/src/elements/Field.ts +1233 -0
  241. package/src/elements/FieldHelpers.ts +333 -0
  242. package/src/elements/FontManager.ts +339 -0
  243. package/src/elements/Footer.ts +269 -0
  244. package/src/elements/Footnote.ts +217 -0
  245. package/src/elements/FootnoteManager.ts +249 -0
  246. package/src/elements/Header.ts +269 -0
  247. package/src/elements/HeaderFooterManager.ts +219 -0
  248. package/src/elements/Hyperlink.ts +1146 -0
  249. package/src/elements/Image.ts +1756 -0
  250. package/src/elements/ImageManager.ts +432 -0
  251. package/src/elements/ImageRun.ts +59 -0
  252. package/src/elements/MathElement.ts +65 -0
  253. package/src/elements/Paragraph.ts +4227 -0
  254. package/src/elements/PreservedElement.ts +53 -0
  255. package/src/elements/PropertyChangeTypes.ts +442 -0
  256. package/src/elements/RangeMarker.ts +400 -0
  257. package/src/elements/Revision.ts +1217 -0
  258. package/src/elements/RevisionContent.ts +73 -0
  259. package/src/elements/RevisionManager.ts +1070 -0
  260. package/src/elements/Run.ts +3068 -0
  261. package/src/elements/Section.ts +1421 -0
  262. package/src/elements/Shape.ts +873 -0
  263. package/src/elements/StructuredDocumentTag.ts +978 -0
  264. package/src/elements/Table.ts +2524 -0
  265. package/src/elements/TableCell.ts +1586 -0
  266. package/src/elements/TableGridChange.ts +151 -0
  267. package/src/elements/TableOfContents.ts +691 -0
  268. package/src/elements/TableOfContentsElement.ts +89 -0
  269. package/src/elements/TableRow.ts +906 -0
  270. package/src/elements/TextBox.ts +768 -0
  271. package/src/formatting/AbstractNumbering.ts +548 -0
  272. package/src/formatting/CLAUDE.md +74 -0
  273. package/src/formatting/NumberingInstance.ts +212 -0
  274. package/src/formatting/NumberingLevel.ts +1006 -0
  275. package/src/formatting/NumberingManager.ts +827 -0
  276. package/src/formatting/Style.ts +1833 -0
  277. package/src/formatting/StylesManager.ts +1005 -0
  278. package/src/helpers/CleanupHelper.ts +524 -0
  279. package/src/images/ImageOptimizer.ts +274 -0
  280. package/src/index.ts +554 -0
  281. package/src/managers/CLAUDE.md +47 -0
  282. package/src/managers/DrawingManager.ts +319 -0
  283. package/src/tracking/DocumentTrackingContext.ts +643 -0
  284. package/src/tracking/TrackingContext.ts +173 -0
  285. package/src/types/compatibility-types.ts +49 -0
  286. package/src/types/formatting.ts +210 -0
  287. package/src/types/list-types.ts +152 -0
  288. package/src/types/settings-types.ts +59 -0
  289. package/src/types/styleConfig.ts +189 -0
  290. package/src/utils/CLAUDE.md +153 -0
  291. package/src/utils/ChangelogGenerator.ts +1581 -0
  292. package/src/utils/CompatibilityUpgrader.ts +237 -0
  293. package/src/utils/InMemoryRevisionAcceptor.ts +668 -0
  294. package/src/utils/MoveOperationHelper.ts +238 -0
  295. package/src/utils/RevisionAwareProcessor.ts +526 -0
  296. package/src/utils/RevisionWalker.ts +457 -0
  297. package/src/utils/SelectiveRevisionAcceptor.ts +613 -0
  298. package/src/utils/ShadingResolver.ts +107 -0
  299. package/src/utils/acceptRevisions.ts +714 -0
  300. package/src/utils/cnfStyleDecoder.ts +217 -0
  301. package/src/utils/corruptionDetection.ts +345 -0
  302. package/src/utils/dateFormatting.ts +20 -0
  303. package/src/utils/deepClone.ts +78 -0
  304. package/src/utils/diagnostics.ts +129 -0
  305. package/src/utils/errorHandling.ts +80 -0
  306. package/src/utils/formatting.ts +213 -0
  307. package/src/utils/list-detection.ts +274 -0
  308. package/src/utils/logger.ts +404 -0
  309. package/src/utils/parsingHelpers.ts +190 -0
  310. package/src/utils/stripTrackedChanges.ts +353 -0
  311. package/src/utils/textDiff.ts +100 -0
  312. package/src/utils/units.ts +421 -0
  313. package/src/utils/validation.ts +542 -0
  314. package/src/utils/xmlSanitization.ts +182 -0
  315. package/src/validation/RevisionAutoFixer.ts +542 -0
  316. package/src/validation/RevisionValidator.ts +460 -0
  317. package/src/validation/ValidationRules.ts +338 -0
  318. package/src/validation/index.ts +30 -0
  319. package/src/xml/CLAUDE.md +65 -0
  320. package/src/xml/XMLBuilder.ts +871 -0
  321. package/src/xml/XMLParser.ts +919 -0
  322. package/src/zip/CLAUDE.md +55 -0
  323. package/src/zip/ZipHandler.ts +637 -0
  324. package/src/zip/ZipReader.ts +299 -0
  325. package/src/zip/ZipWriter.ts +390 -0
  326. package/src/zip/errors.ts +69 -0
  327. package/src/zip/types.ts +116 -0
  328. package/dist/core/ListNormalizer.d.ts +0 -23
  329. package/dist/core/ListNormalizer.d.ts.map +0 -1
  330. package/dist/core/ListNormalizer.js +0 -624
  331. package/dist/core/ListNormalizer.js.map +0 -1
  332. package/dist/images/index.d.ts +0 -2
  333. package/dist/images/index.d.ts.map +0 -1
  334. package/dist/images/index.js +0 -8
  335. package/dist/images/index.js.map +0 -1
  336. package/dist/ms-doc/cfb/CFBReader.d.ts +0 -35
  337. package/dist/ms-doc/cfb/CFBReader.d.ts.map +0 -1
  338. package/dist/ms-doc/cfb/CFBReader.js +0 -360
  339. package/dist/ms-doc/cfb/CFBReader.js.map +0 -1
  340. package/dist/ms-doc/converter/DocToDocxConverter.d.ts +0 -55
  341. package/dist/ms-doc/converter/DocToDocxConverter.d.ts.map +0 -1
  342. package/dist/ms-doc/converter/DocToDocxConverter.js +0 -324
  343. package/dist/ms-doc/converter/DocToDocxConverter.js.map +0 -1
  344. package/dist/ms-doc/fib/FIB.d.ts +0 -18
  345. package/dist/ms-doc/fib/FIB.d.ts.map +0 -1
  346. package/dist/ms-doc/fib/FIB.js +0 -342
  347. package/dist/ms-doc/fib/FIB.js.map +0 -1
  348. package/dist/ms-doc/fields/FieldParser.d.ts +0 -31
  349. package/dist/ms-doc/fields/FieldParser.d.ts.map +0 -1
  350. package/dist/ms-doc/fields/FieldParser.js +0 -266
  351. package/dist/ms-doc/fields/FieldParser.js.map +0 -1
  352. package/dist/ms-doc/images/PictureExtractor.d.ts +0 -22
  353. package/dist/ms-doc/images/PictureExtractor.d.ts.map +0 -1
  354. package/dist/ms-doc/images/PictureExtractor.js +0 -233
  355. package/dist/ms-doc/images/PictureExtractor.js.map +0 -1
  356. package/dist/ms-doc/index.d.ts +0 -20
  357. package/dist/ms-doc/index.d.ts.map +0 -1
  358. package/dist/ms-doc/index.js +0 -59
  359. package/dist/ms-doc/index.js.map +0 -1
  360. package/dist/ms-doc/properties/SPRM.d.ts +0 -210
  361. package/dist/ms-doc/properties/SPRM.d.ts.map +0 -1
  362. package/dist/ms-doc/properties/SPRM.js +0 -633
  363. package/dist/ms-doc/properties/SPRM.js.map +0 -1
  364. package/dist/ms-doc/sections/SectionParser.d.ts +0 -25
  365. package/dist/ms-doc/sections/SectionParser.d.ts.map +0 -1
  366. package/dist/ms-doc/sections/SectionParser.js +0 -214
  367. package/dist/ms-doc/sections/SectionParser.js.map +0 -1
  368. package/dist/ms-doc/styles/StyleSheet.d.ts +0 -23
  369. package/dist/ms-doc/styles/StyleSheet.d.ts.map +0 -1
  370. package/dist/ms-doc/styles/StyleSheet.js +0 -268
  371. package/dist/ms-doc/styles/StyleSheet.js.map +0 -1
  372. package/dist/ms-doc/subdocuments/SubdocumentParser.d.ts +0 -61
  373. package/dist/ms-doc/subdocuments/SubdocumentParser.d.ts.map +0 -1
  374. package/dist/ms-doc/subdocuments/SubdocumentParser.js +0 -208
  375. package/dist/ms-doc/subdocuments/SubdocumentParser.js.map +0 -1
  376. package/dist/ms-doc/tables/TableParser.d.ts +0 -29
  377. package/dist/ms-doc/tables/TableParser.d.ts.map +0 -1
  378. package/dist/ms-doc/tables/TableParser.js +0 -176
  379. package/dist/ms-doc/tables/TableParser.js.map +0 -1
  380. package/dist/ms-doc/text/PieceTable.d.ts +0 -21
  381. package/dist/ms-doc/text/PieceTable.d.ts.map +0 -1
  382. package/dist/ms-doc/text/PieceTable.js +0 -171
  383. package/dist/ms-doc/text/PieceTable.js.map +0 -1
  384. package/dist/ms-doc/types/Constants.d.ts +0 -99
  385. package/dist/ms-doc/types/Constants.d.ts.map +0 -1
  386. package/dist/ms-doc/types/Constants.js +0 -102
  387. package/dist/ms-doc/types/Constants.js.map +0 -1
  388. package/dist/ms-doc/types/DocTypes.d.ts +0 -368
  389. package/dist/ms-doc/types/DocTypes.d.ts.map +0 -1
  390. package/dist/ms-doc/types/DocTypes.js +0 -3
  391. package/dist/ms-doc/types/DocTypes.js.map +0 -1
  392. package/dist/tracking/index.d.ts +0 -3
  393. package/dist/tracking/index.d.ts.map +0 -1
  394. package/dist/tracking/index.js +0 -6
  395. package/dist/tracking/index.js.map +0 -1
@@ -0,0 +1,299 @@
1
+ /**
2
+ * ZipReader - Handles reading ZIP archives (DOCX files)
3
+ */
4
+
5
+ import JSZip from 'jszip';
6
+ import { promises as fs } from 'fs';
7
+ import { ZipFile, FileMap, LoadOptions } from './types';
8
+ import {
9
+ DocxNotFoundError,
10
+ InvalidDocxError,
11
+ CorruptedArchiveError,
12
+ FileOperationError,
13
+ } from './errors';
14
+ import {
15
+ validateDocxStructure,
16
+ isBinaryFile,
17
+ normalizePath,
18
+ isValidZipBuffer,
19
+ } from '../utils/validation';
20
+
21
+ /**
22
+ * Handles reading operations on ZIP archives
23
+ */
24
+ export class ZipReader {
25
+ private zip: JSZip | null = null;
26
+ private files: FileMap = new Map();
27
+ private loaded = false;
28
+
29
+ /**
30
+ * Loads a DOCX file from the filesystem
31
+ * @param filePath - Path to the DOCX file
32
+ * @param options - Load options
33
+ */
34
+ async loadFromFile(filePath: string, options: LoadOptions = {}): Promise<void> {
35
+ try {
36
+ // Check if file exists
37
+ try {
38
+ await fs.access(filePath);
39
+ } catch {
40
+ throw new DocxNotFoundError(filePath);
41
+ }
42
+
43
+ // Read file as buffer
44
+ const buffer = await fs.readFile(filePath);
45
+ await this.loadFromBuffer(buffer, options);
46
+ } catch (error: unknown) {
47
+ if (error instanceof DocxNotFoundError) {
48
+ throw error;
49
+ }
50
+ const message = error instanceof Error ? error.message : String(error);
51
+ throw new FileOperationError('read', message);
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Loads a DOCX file from a buffer
57
+ * @param buffer - Buffer containing the DOCX data
58
+ * @param options - Load options
59
+ */
60
+ async loadFromBuffer(buffer: Buffer, options: LoadOptions = {}): Promise<void> {
61
+ const { validate = true } = options;
62
+
63
+ try {
64
+ // Validate ZIP signature
65
+ if (!isValidZipBuffer(buffer)) {
66
+ throw new InvalidDocxError('File is not a valid ZIP archive');
67
+ }
68
+
69
+ // Load ZIP archive
70
+ this.zip = await JSZip.loadAsync(buffer);
71
+
72
+ // Extract all files
73
+ await this.extractFiles();
74
+
75
+ // Validate DOCX structure if requested
76
+ if (validate) {
77
+ this.validate();
78
+ }
79
+
80
+ this.loaded = true;
81
+ } catch (error: unknown) {
82
+ if (error instanceof InvalidDocxError) {
83
+ throw error;
84
+ }
85
+ const message = error instanceof Error ? error.message : String(error);
86
+ throw new CorruptedArchiveError(message);
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Extracts all files from the ZIP archive into memory
92
+ *
93
+ * **Encoding Note:**
94
+ * - Text files (XML, etc.) are extracted as UTF-8 strings using `async('string')`
95
+ * - JSZip automatically decodes UTF-8 when extracting as 'string'
96
+ * - Binary files are extracted as Buffers to preserve exact content
97
+ * - All text content is guaranteed to be valid UTF-8
98
+ */
99
+ private async extractFiles(): Promise<void> {
100
+ if (!this.zip) {
101
+ throw new Error('ZIP archive not loaded');
102
+ }
103
+
104
+ this.files.clear();
105
+
106
+ // Get all file paths
107
+ const filePaths = Object.keys(this.zip.files).filter(
108
+ (path) => !this.zip!.files[path]!.dir
109
+ );
110
+
111
+ // Extract each file
112
+ for (const filePath of filePaths) {
113
+ const normalizedPath = normalizePath(filePath);
114
+ const zipObject = this.zip.files[filePath];
115
+
116
+ if (!zipObject) {
117
+ continue;
118
+ }
119
+
120
+ const isBinary = isBinaryFile(normalizedPath);
121
+
122
+ // Extract content based on type
123
+ // For text files: JSZip's async('string') automatically uses UTF-8 decoding
124
+ // For binary files: async('nodebuffer') preserves exact bytes
125
+ let content;
126
+ if (isBinary) {
127
+ content = await zipObject.async('nodebuffer');
128
+ } else {
129
+ // Text files are extracted as UTF-8 strings
130
+ // JSZip automatically handles UTF-8 decoding for 'string' type
131
+ content = await zipObject.async('string');
132
+ }
133
+
134
+ // Get file metadata
135
+ const date = zipObject.date;
136
+
137
+ // Store file information
138
+ this.files.set(normalizedPath, {
139
+ path: normalizedPath,
140
+ content,
141
+ isBinary,
142
+ size: isBinary ? (content as Buffer).length : (content as string).length,
143
+ date,
144
+ });
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Validates the DOCX structure
150
+ * @throws {MissingRequiredFileError} If required files are missing
151
+ */
152
+ private validate(): void {
153
+ const filePaths = Array.from(this.files.keys());
154
+ validateDocxStructure(filePaths);
155
+ }
156
+
157
+ /**
158
+ * Gets a specific file from the archive
159
+ * @param filePath - Path to the file within the archive
160
+ * @returns The file data, or undefined if not found
161
+ */
162
+ getFile(filePath: string): ZipFile | undefined {
163
+ this.ensureLoaded();
164
+ const normalizedPath = normalizePath(filePath);
165
+ return this.files.get(normalizedPath);
166
+ }
167
+
168
+ /**
169
+ * Gets the content of a specific file as a string
170
+ * @param filePath - Path to the file within the archive
171
+ * @returns The file content as a UTF-8 string, or undefined if not found
172
+ *
173
+ * **Encoding Note:**
174
+ * - Returns UTF-8 decoded string content
175
+ * - For binary files, converts the Buffer to UTF-8 string
176
+ * - Assumes all text content is UTF-8 encoded (per OpenXML standard)
177
+ */
178
+ getFileAsString(filePath: string): string | undefined {
179
+ const file = this.getFile(filePath);
180
+ if (!file) {
181
+ return undefined;
182
+ }
183
+
184
+ // Check actual content type instead of flag (Issue #4)
185
+ // Content is Buffer for binary files, string for text files
186
+ if (Buffer.isBuffer(file.content)) {
187
+ // Convert binary buffer to UTF-8 string
188
+ return file.content.toString('utf8');
189
+ }
190
+
191
+ return file.content;
192
+ }
193
+
194
+ /**
195
+ * Gets the content of a specific file as a buffer
196
+ * @param filePath - Path to the file within the archive
197
+ * @returns The file content as a Buffer, or undefined if not found
198
+ *
199
+ * **Encoding Note:**
200
+ * - Returns Buffer with UTF-8 encoded content for text files
201
+ * - For binary files, returns raw bytes
202
+ * - String content is explicitly encoded as UTF-8
203
+ */
204
+ getFileAsBuffer(filePath: string): Buffer | undefined {
205
+ const file = this.getFile(filePath);
206
+ if (!file) {
207
+ return undefined;
208
+ }
209
+
210
+ // Check actual content type instead of flag (Issue #4)
211
+ // Content is Buffer for binary files, string for text files
212
+ if (Buffer.isBuffer(file.content)) {
213
+ return file.content;
214
+ }
215
+
216
+ // Encode string content as UTF-8 Buffer
217
+ return Buffer.from(file.content, 'utf8');
218
+ }
219
+
220
+ /**
221
+ * Gets all files from the archive
222
+ * @returns Map of file paths to file data
223
+ */
224
+ getAllFiles(): FileMap {
225
+ this.ensureLoaded();
226
+ return new Map(this.files);
227
+ }
228
+
229
+ /**
230
+ * Gets a list of all file paths in the archive
231
+ * @returns Array of file paths
232
+ */
233
+ getFilePaths(): string[] {
234
+ this.ensureLoaded();
235
+ return Array.from(this.files.keys());
236
+ }
237
+
238
+ /**
239
+ * Checks if a file exists in the archive
240
+ * @param filePath - Path to check
241
+ * @returns True if the file exists
242
+ */
243
+ hasFile(filePath: string): boolean {
244
+ this.ensureLoaded();
245
+ const normalizedPath = normalizePath(filePath);
246
+ return this.files.has(normalizedPath);
247
+ }
248
+
249
+ /**
250
+ * Gets files matching a pattern (simple glob)
251
+ * @param pattern - Pattern to match (supports * wildcard)
252
+ * @returns Array of matching files
253
+ */
254
+ getFilesByPattern(pattern: string): ZipFile[] {
255
+ this.ensureLoaded();
256
+
257
+ // Convert simple glob pattern to regex
258
+ const regexPattern = pattern
259
+ .replace(/\*/g, '.*')
260
+ .replace(/\?/g, '.');
261
+ const regex = new RegExp(`^${regexPattern}$`);
262
+
263
+ const matchingFiles: ZipFile[] = [];
264
+ for (const [path, file] of this.files) {
265
+ if (regex.test(path)) {
266
+ matchingFiles.push(file);
267
+ }
268
+ }
269
+
270
+ return matchingFiles;
271
+ }
272
+
273
+ /**
274
+ * Ensures the archive is loaded before operations
275
+ * @throws {Error} If archive is not loaded
276
+ */
277
+ private ensureLoaded(): void {
278
+ if (!this.loaded) {
279
+ throw new Error('Archive not loaded. Call loadFromFile() or loadFromBuffer() first.');
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Checks if the archive is loaded
285
+ * @returns True if loaded
286
+ */
287
+ isLoaded(): boolean {
288
+ return this.loaded;
289
+ }
290
+
291
+ /**
292
+ * Clears all loaded data
293
+ */
294
+ clear(): void {
295
+ this.zip = null;
296
+ this.files.clear();
297
+ this.loaded = false;
298
+ }
299
+ }
@@ -0,0 +1,390 @@
1
+ /**
2
+ * ZipWriter - Handles writing ZIP archives (DOCX files)
3
+ *
4
+ * DOCX Compliance Notes:
5
+ * - [Content_Types].xml MUST be the first entry in the ZIP
6
+ * - [Content_Types].xml MUST use STORE compression (uncompressed)
7
+ * - File order matters for Microsoft Word compatibility
8
+ */
9
+
10
+ import JSZip from "jszip";
11
+ import { promises as fs } from "fs";
12
+ import { ZipFile, FileMap, SaveOptions, AddFileOptions } from "./types";
13
+ import { FileOperationError } from "./errors";
14
+ import { validateDocxStructure, normalizePath } from "../utils/validation";
15
+
16
+ /**
17
+ * Handles writing operations on ZIP archives with DOCX-specific compliance
18
+ */
19
+ export class ZipWriter {
20
+ private zip: JSZip;
21
+ private files: FileMap = new Map();
22
+
23
+ constructor() {
24
+ this.zip = new JSZip();
25
+ }
26
+
27
+ /**
28
+ * Adds a file to the archive
29
+ * @param filePath - Path where the file will be stored in the archive
30
+ * @param content - File content (string or Buffer)
31
+ * @param options - Options for adding the file
32
+ *
33
+ * **Encoding Note:**
34
+ * - String content is always encoded as UTF-8 per DOCX/OpenXML standard
35
+ * - Buffer content is stored as-is (should already be UTF-8 encoded for text)
36
+ * - XML files must use UTF-8 encoding as specified in their XML declaration
37
+ *
38
+ * **DOCX Compliance:**
39
+ * - [Content_Types].xml is automatically set to STORE compression
40
+ */
41
+ /**
42
+ * Validates a file path for security issues
43
+ * @param path - Normalized file path
44
+ * @throws {Error} If path contains path traversal or other security issues
45
+ * @private
46
+ */
47
+ private validatePathSecurity(path: string): void {
48
+ // Check for path traversal attacks
49
+ if (path.includes("..")) {
50
+ throw new Error(
51
+ `Security error: Path "${path}" contains path traversal sequence "..". ` +
52
+ `This could be an attempt to write files outside the archive.`
53
+ );
54
+ }
55
+
56
+ // Check for absolute paths (even after normalization)
57
+ if (path.startsWith("/") || /^[a-zA-Z]:/.test(path)) {
58
+ throw new Error(
59
+ `Security error: Path "${path}" is an absolute path. ` +
60
+ `Only relative paths are allowed in ZIP archives.`
61
+ );
62
+ }
63
+
64
+ // Check for null bytes (can be used to truncate paths)
65
+ if (path.includes("\0")) {
66
+ throw new Error(
67
+ `Security error: Path "${path}" contains null byte. ` +
68
+ `This could be an attempt to exploit path handling.`
69
+ );
70
+ }
71
+
72
+ // Check for excessively long paths (potential DoS)
73
+ const MAX_PATH_LENGTH = 260; // Windows MAX_PATH
74
+ if (path.length > MAX_PATH_LENGTH) {
75
+ throw new Error(
76
+ `Security error: Path "${path}" exceeds maximum length of ${MAX_PATH_LENGTH} characters.`
77
+ );
78
+ }
79
+ }
80
+
81
+ addFile(
82
+ filePath: string,
83
+ content: string | Buffer,
84
+ options: AddFileOptions = {}
85
+ ): void {
86
+ const {
87
+ binary = Buffer.isBuffer(content),
88
+ compression = 6,
89
+ date = new Date(),
90
+ } = options;
91
+
92
+ const normalizedPath = normalizePath(filePath);
93
+
94
+ // Security: Validate path for traversal and other attacks
95
+ this.validatePathSecurity(normalizedPath);
96
+
97
+ // Convert string content to UTF-8 Buffer if not already binary
98
+ // This ensures consistent UTF-8 encoding regardless of system locale
99
+ let processedContent = content;
100
+ if (typeof content === "string") {
101
+ // Explicitly encode string as UTF-8 Buffer
102
+ processedContent = Buffer.from(content, "utf8");
103
+ }
104
+
105
+ // DOCX REQUIREMENT: [Content_Types].xml MUST be uncompressed (STORE)
106
+ const isContentTypes = normalizedPath === "[Content_Types].xml";
107
+ const useCompression = isContentTypes
108
+ ? "STORE"
109
+ : compression > 0
110
+ ? "DEFLATE"
111
+ : "STORE";
112
+ const compressionLevel = isContentTypes ? 0 : compression;
113
+
114
+ // For text content (XML), this ensures UTF-8 encoding is preserved
115
+ this.zip.file(normalizedPath, processedContent, {
116
+ binary: true, // Always treat as binary since we're using Buffers
117
+ compression: useCompression,
118
+ compressionOptions: {
119
+ level: compressionLevel,
120
+ },
121
+ date,
122
+ });
123
+
124
+ // Store in our file map
125
+ // IMPORTANT: Store the PROCESSED content (Buffer), not the original
126
+ // This ensures consistency with what was added to this.zip and prevents
127
+ // double UTF-8 conversion in toBuffer() method (Issue #1)
128
+ this.files.set(normalizedPath, {
129
+ path: normalizedPath,
130
+ content: processedContent, // Store Buffer, not original string
131
+ isBinary: binary,
132
+ size: processedContent.length, // Buffer.length is always correct (Issue #3)
133
+ date,
134
+ });
135
+ }
136
+
137
+ /**
138
+ * Adds multiple files to the archive
139
+ * @param files - Map of file paths to contents
140
+ * @param options - Options for adding files
141
+ */
142
+ addFiles(files: FileMap, options: AddFileOptions = {}): void {
143
+ for (const [path, file] of files) {
144
+ this.addFile(path, file.content, {
145
+ ...options,
146
+ binary: file.isBinary,
147
+ date: file.date,
148
+ });
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Removes a file from the archive
154
+ * @param filePath - Path to the file to remove
155
+ * @returns True if the file was removed, false if it didn't exist
156
+ */
157
+ removeFile(filePath: string): boolean {
158
+ const normalizedPath = normalizePath(filePath);
159
+
160
+ // Remove from JSZip
161
+ const zipFile = this.zip.file(normalizedPath);
162
+ if (zipFile) {
163
+ this.zip.remove(normalizedPath);
164
+ this.files.delete(normalizedPath);
165
+ return true;
166
+ }
167
+
168
+ return false;
169
+ }
170
+
171
+ /**
172
+ * Checks if a file exists in the archive
173
+ * @param filePath - Path to check
174
+ * @returns True if the file exists
175
+ */
176
+ hasFile(filePath: string): boolean {
177
+ const normalizedPath = normalizePath(filePath);
178
+ return this.files.has(normalizedPath);
179
+ }
180
+
181
+ /**
182
+ * Gets a file from the archive
183
+ * @param filePath - Path to the file
184
+ * @returns The file data, or undefined if not found
185
+ */
186
+ getFile(filePath: string): ZipFile | undefined {
187
+ const normalizedPath = normalizePath(filePath);
188
+ return this.files.get(normalizedPath);
189
+ }
190
+
191
+ /**
192
+ * Gets all files in the archive
193
+ * @returns Map of file paths to file data
194
+ */
195
+ getAllFiles(): FileMap {
196
+ return new Map(this.files);
197
+ }
198
+
199
+ /**
200
+ * Gets a list of all file paths in the archive
201
+ * @returns Array of file paths
202
+ */
203
+ getFilePaths(): string[] {
204
+ return Array.from(this.files.keys());
205
+ }
206
+
207
+ /**
208
+ * Validates the DOCX structure before saving
209
+ * @throws {MissingRequiredFileError} If required files are missing
210
+ */
211
+ validate(): void {
212
+ const filePaths = this.getFilePaths();
213
+ validateDocxStructure(filePaths);
214
+ }
215
+
216
+ /**
217
+ * Sorts files according to DOCX best practices
218
+ * Microsoft Word expects files in a specific order for optimal compatibility
219
+ *
220
+ * @returns Sorted array of file paths
221
+ *
222
+ * **DOCX File Order (CRITICAL):**
223
+ * 1. [Content_Types].xml - MUST be first
224
+ * 2. _rels/.rels - Root relationships
225
+ * 3. docProps/* - Document properties
226
+ * 4. word/_rels/document.xml.rels - Document relationships
227
+ * 5. word/document.xml - Main document
228
+ * 6. word/* - Other word files (styles, numbering, etc.)
229
+ * 7. Everything else - Media, custom XML, etc.
230
+ */
231
+ private getSortedFilePaths(): string[] {
232
+ const paths = Array.from(this.files.keys());
233
+
234
+ return paths.sort((a, b) => {
235
+ // Priority 1: [Content_Types].xml MUST be first (CRITICAL for MS Word)
236
+ if (a === "[Content_Types].xml") return -1;
237
+ if (b === "[Content_Types].xml") return 1;
238
+
239
+ // Priority 2: Root relationships
240
+ if (a === "_rels/.rels") return -1;
241
+ if (b === "_rels/.rels") return 1;
242
+
243
+ // Priority 3: Document properties
244
+ const aIsDocProps = a.startsWith("docProps/");
245
+ const bIsDocProps = b.startsWith("docProps/");
246
+ if (aIsDocProps && !bIsDocProps) return -1;
247
+ if (!aIsDocProps && bIsDocProps) return 1;
248
+
249
+ // Priority 4: word/_rels/document.xml.rels
250
+ if (a === "word/_rels/document.xml.rels") return -1;
251
+ if (b === "word/_rels/document.xml.rels") return 1;
252
+
253
+ // Priority 5: word/document.xml
254
+ if (a === "word/document.xml") return -1;
255
+ if (b === "word/document.xml") return 1;
256
+
257
+ // Priority 6: Other word/ folder files (before relationships)
258
+ const aIsWordRels = a.startsWith("word/_rels/");
259
+ const bIsWordRels = b.startsWith("word/_rels/");
260
+ const aIsWord = a.startsWith("word/") && !aIsWordRels;
261
+ const bIsWord = b.startsWith("word/") && !bIsWordRels;
262
+
263
+ if (aIsWord && !bIsWord && !bIsWordRels) return -1;
264
+ if (!aIsWord && bIsWord && !aIsWordRels) return 1;
265
+
266
+ // Priority 7: word/_rels/ files
267
+ if (aIsWordRels && !bIsWordRels) return -1;
268
+ if (!aIsWordRels && bIsWordRels) return 1;
269
+
270
+ // Alphabetical for same priority
271
+ return a.localeCompare(b);
272
+ });
273
+ }
274
+
275
+ /**
276
+ * Generates the ZIP archive as a buffer
277
+ * @param options - Save options
278
+ * @returns Buffer containing the ZIP archive
279
+ *
280
+ * **Encoding Note:**
281
+ * The generated buffer contains UTF-8 encoded XML and text files.
282
+ * All string content within files has been explicitly UTF-8 encoded
283
+ * before being added to the archive to ensure consistency.
284
+ *
285
+ * **DOCX Compliance:**
286
+ * - Files are ordered with [Content_Types].xml first (REQUIRED)
287
+ * - [Content_Types].xml uses STORE compression (uncompressed)
288
+ * - All other files use DEFLATE compression by default
289
+ */
290
+ async toBuffer(options: SaveOptions = {}): Promise<Buffer> {
291
+ const { compression = 6, validate = true } = options;
292
+
293
+ // Validate structure if requested
294
+ if (validate) {
295
+ this.validate();
296
+ }
297
+
298
+ try {
299
+ // Create a new JSZip instance with proper file ordering
300
+ const orderedZip = new JSZip();
301
+ const sortedPaths = this.getSortedFilePaths();
302
+
303
+ // Add files in the correct order
304
+ for (const path of sortedPaths) {
305
+ const file = this.files.get(path);
306
+ if (!file) continue;
307
+
308
+ // Content is already a Buffer from addFile() - no re-conversion needed (Issue #2)
309
+ const processedContent = file.content as Buffer;
310
+
311
+ // DOCX REQUIREMENT: [Content_Types].xml MUST be uncompressed
312
+ const isContentTypes = path === "[Content_Types].xml";
313
+ const useCompression = isContentTypes
314
+ ? "STORE"
315
+ : compression > 0
316
+ ? "DEFLATE"
317
+ : "STORE";
318
+ const compressionLevel = isContentTypes ? 0 : compression;
319
+
320
+ orderedZip.file(path, processedContent, {
321
+ binary: true,
322
+ compression: useCompression,
323
+ compressionOptions: {
324
+ level: compressionLevel,
325
+ },
326
+ date: file.date,
327
+ });
328
+ }
329
+
330
+ // Generate ZIP with the ordered files
331
+ const buffer = await orderedZip.generateAsync({
332
+ type: "nodebuffer",
333
+ compression: compression > 0 ? "DEFLATE" : "STORE",
334
+ compressionOptions: {
335
+ level: compression,
336
+ },
337
+ streamFiles: true,
338
+ });
339
+
340
+ return buffer;
341
+ } catch (error: unknown) {
342
+ const err = error instanceof Error ? error : new Error(String(error));
343
+ throw new FileOperationError("generate", err.message);
344
+ }
345
+ }
346
+
347
+ /**
348
+ * Saves the archive to a file
349
+ * @param filePath - Path where the file will be saved
350
+ * @param options - Save options
351
+ */
352
+ async saveToFile(filePath: string, options: SaveOptions = {}): Promise<void> {
353
+ try {
354
+ const buffer = await this.toBuffer(options);
355
+ await fs.writeFile(filePath, buffer);
356
+ } catch (error: unknown) {
357
+ if (error instanceof FileOperationError) {
358
+ throw error;
359
+ }
360
+ const err = error instanceof Error ? error : new Error(String(error));
361
+ throw new FileOperationError("save", err.message);
362
+ }
363
+ }
364
+
365
+ /**
366
+ * Creates a new empty archive
367
+ */
368
+ clear(): void {
369
+ this.zip = new JSZip();
370
+ this.files.clear();
371
+ }
372
+
373
+ /**
374
+ * Gets the number of files in the archive
375
+ * @returns Number of files
376
+ */
377
+ getFileCount(): number {
378
+ return this.files.size;
379
+ }
380
+
381
+ /**
382
+ * Creates a clone of this writer with all its files
383
+ * @returns A new ZipWriter instance with the same files
384
+ */
385
+ clone(): ZipWriter {
386
+ const newWriter = new ZipWriter();
387
+ newWriter.addFiles(this.files);
388
+ return newWriter;
389
+ }
390
+ }