docxmlater 10.1.4 → 10.1.6

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 (372) hide show
  1. package/README.md +759 -754
  2. package/dist/constants/legacyCompatFlags.js +1 -1
  3. package/dist/constants/legacyCompatFlags.js.map +1 -1
  4. package/dist/constants/limits.js.map +1 -1
  5. package/dist/core/Document.d.ts +51 -50
  6. package/dist/core/Document.d.ts.map +1 -1
  7. package/dist/core/Document.js +486 -471
  8. package/dist/core/Document.js.map +1 -1
  9. package/dist/core/DocumentContent.d.ts +9 -9
  10. package/dist/core/DocumentContent.d.ts.map +1 -1
  11. package/dist/core/DocumentContent.js +1 -1
  12. package/dist/core/DocumentContent.js.map +1 -1
  13. package/dist/core/DocumentGenerator.d.ts +11 -11
  14. package/dist/core/DocumentGenerator.d.ts.map +1 -1
  15. package/dist/core/DocumentGenerator.js +251 -251
  16. package/dist/core/DocumentGenerator.js.map +1 -1
  17. package/dist/core/DocumentIdManager.js.map +1 -1
  18. package/dist/core/DocumentParser.d.ts +15 -15
  19. package/dist/core/DocumentParser.d.ts.map +1 -1
  20. package/dist/core/DocumentParser.js +2123 -2155
  21. package/dist/core/DocumentParser.js.map +1 -1
  22. package/dist/core/DocumentValidator.d.ts.map +1 -1
  23. package/dist/core/DocumentValidator.js +2 -5
  24. package/dist/core/DocumentValidator.js.map +1 -1
  25. package/dist/core/Relationship.js.map +1 -1
  26. package/dist/core/RelationshipManager.d.ts.map +1 -1
  27. package/dist/core/RelationshipManager.js +3 -3
  28. package/dist/core/RelationshipManager.js.map +1 -1
  29. package/dist/elements/AlternateContent.js.map +1 -1
  30. package/dist/elements/Bookmark.d.ts.map +1 -1
  31. package/dist/elements/Bookmark.js +3 -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.d.ts.map +1 -1
  36. package/dist/elements/Comment.js +9 -6
  37. package/dist/elements/Comment.js.map +1 -1
  38. package/dist/elements/CommentManager.d.ts.map +1 -1
  39. package/dist/elements/CommentManager.js +18 -17
  40. package/dist/elements/CommentManager.js.map +1 -1
  41. package/dist/elements/CommonTypes.d.ts +21 -21
  42. package/dist/elements/CommonTypes.d.ts.map +1 -1
  43. package/dist/elements/CommonTypes.js +56 -56
  44. package/dist/elements/CommonTypes.js.map +1 -1
  45. package/dist/elements/CustomXml.js.map +1 -1
  46. package/dist/elements/Endnote.d.ts.map +1 -1
  47. package/dist/elements/Endnote.js +6 -6
  48. package/dist/elements/Endnote.js.map +1 -1
  49. package/dist/elements/EndnoteManager.d.ts.map +1 -1
  50. package/dist/elements/EndnoteManager.js +6 -7
  51. package/dist/elements/EndnoteManager.js.map +1 -1
  52. package/dist/elements/Field.d.ts.map +1 -1
  53. package/dist/elements/Field.js +82 -25
  54. package/dist/elements/Field.js.map +1 -1
  55. package/dist/elements/FieldHelpers.d.ts.map +1 -1
  56. package/dist/elements/FieldHelpers.js.map +1 -1
  57. package/dist/elements/FontManager.d.ts.map +1 -1
  58. package/dist/elements/FontManager.js +1 -1
  59. package/dist/elements/FontManager.js.map +1 -1
  60. package/dist/elements/Footer.js +2 -2
  61. package/dist/elements/Footer.js.map +1 -1
  62. package/dist/elements/Footnote.d.ts.map +1 -1
  63. package/dist/elements/Footnote.js +6 -6
  64. package/dist/elements/Footnote.js.map +1 -1
  65. package/dist/elements/FootnoteManager.d.ts.map +1 -1
  66. package/dist/elements/FootnoteManager.js +6 -7
  67. package/dist/elements/FootnoteManager.js.map +1 -1
  68. package/dist/elements/Header.js +2 -2
  69. package/dist/elements/Header.js.map +1 -1
  70. package/dist/elements/HeaderFooterManager.js.map +1 -1
  71. package/dist/elements/Hyperlink.d.ts +5 -3
  72. package/dist/elements/Hyperlink.d.ts.map +1 -1
  73. package/dist/elements/Hyperlink.js +134 -76
  74. package/dist/elements/Hyperlink.js.map +1 -1
  75. package/dist/elements/Image.d.ts.map +1 -1
  76. package/dist/elements/Image.js +238 -106
  77. package/dist/elements/Image.js.map +1 -1
  78. package/dist/elements/ImageManager.d.ts.map +1 -1
  79. package/dist/elements/ImageManager.js +1 -1
  80. package/dist/elements/ImageManager.js.map +1 -1
  81. package/dist/elements/ImageRun.js +1 -1
  82. package/dist/elements/ImageRun.js.map +1 -1
  83. package/dist/elements/MathElement.js.map +1 -1
  84. package/dist/elements/Paragraph.d.ts +24 -24
  85. package/dist/elements/Paragraph.d.ts.map +1 -1
  86. package/dist/elements/Paragraph.js +181 -188
  87. package/dist/elements/Paragraph.js.map +1 -1
  88. package/dist/elements/PreservedElement.js.map +1 -1
  89. package/dist/elements/PropertyChangeTypes.d.ts.map +1 -1
  90. package/dist/elements/PropertyChangeTypes.js +6 -6
  91. package/dist/elements/PropertyChangeTypes.js.map +1 -1
  92. package/dist/elements/RangeMarker.d.ts.map +1 -1
  93. package/dist/elements/RangeMarker.js.map +1 -1
  94. package/dist/elements/Revision.d.ts.map +1 -1
  95. package/dist/elements/Revision.js +4 -5
  96. package/dist/elements/Revision.js.map +1 -1
  97. package/dist/elements/RevisionContent.js.map +1 -1
  98. package/dist/elements/RevisionManager.d.ts.map +1 -1
  99. package/dist/elements/RevisionManager.js +40 -48
  100. package/dist/elements/RevisionManager.js.map +1 -1
  101. package/dist/elements/Run.d.ts +16 -16
  102. package/dist/elements/Run.d.ts.map +1 -1
  103. package/dist/elements/Run.js +256 -238
  104. package/dist/elements/Run.js.map +1 -1
  105. package/dist/elements/Section.d.ts.map +1 -1
  106. package/dist/elements/Section.js +36 -11
  107. package/dist/elements/Section.js.map +1 -1
  108. package/dist/elements/Shape.d.ts.map +1 -1
  109. package/dist/elements/Shape.js.map +1 -1
  110. package/dist/elements/StructuredDocumentTag.d.ts +6 -6
  111. package/dist/elements/StructuredDocumentTag.d.ts.map +1 -1
  112. package/dist/elements/StructuredDocumentTag.js +99 -104
  113. package/dist/elements/StructuredDocumentTag.js.map +1 -1
  114. package/dist/elements/Table.d.ts +11 -11
  115. package/dist/elements/Table.d.ts.map +1 -1
  116. package/dist/elements/Table.js +102 -107
  117. package/dist/elements/Table.js.map +1 -1
  118. package/dist/elements/TableCell.d.ts +10 -10
  119. package/dist/elements/TableCell.d.ts.map +1 -1
  120. package/dist/elements/TableCell.js +105 -106
  121. package/dist/elements/TableCell.js.map +1 -1
  122. package/dist/elements/TableGridChange.d.ts.map +1 -1
  123. package/dist/elements/TableGridChange.js.map +1 -1
  124. package/dist/elements/TableOfContents.d.ts.map +1 -1
  125. package/dist/elements/TableOfContents.js +4 -4
  126. package/dist/elements/TableOfContents.js.map +1 -1
  127. package/dist/elements/TableOfContentsElement.js.map +1 -1
  128. package/dist/elements/TableRow.d.ts.map +1 -1
  129. package/dist/elements/TableRow.js +13 -6
  130. package/dist/elements/TableRow.js.map +1 -1
  131. package/dist/elements/TextBox.d.ts.map +1 -1
  132. package/dist/elements/TextBox.js +3 -5
  133. package/dist/elements/TextBox.js.map +1 -1
  134. package/dist/formatting/AbstractNumbering.d.ts +4 -4
  135. package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
  136. package/dist/formatting/AbstractNumbering.js +54 -49
  137. package/dist/formatting/AbstractNumbering.js.map +1 -1
  138. package/dist/formatting/NumberingInstance.d.ts.map +1 -1
  139. package/dist/formatting/NumberingInstance.js +1 -3
  140. package/dist/formatting/NumberingInstance.js.map +1 -1
  141. package/dist/formatting/NumberingLevel.d.ts +5 -5
  142. package/dist/formatting/NumberingLevel.d.ts.map +1 -1
  143. package/dist/formatting/NumberingLevel.js +119 -125
  144. package/dist/formatting/NumberingLevel.js.map +1 -1
  145. package/dist/formatting/NumberingManager.d.ts +1 -0
  146. package/dist/formatting/NumberingManager.d.ts.map +1 -1
  147. package/dist/formatting/NumberingManager.js +27 -9
  148. package/dist/formatting/NumberingManager.js.map +1 -1
  149. package/dist/formatting/Style.d.ts +11 -11
  150. package/dist/formatting/Style.d.ts.map +1 -1
  151. package/dist/formatting/Style.js +219 -247
  152. package/dist/formatting/Style.js.map +1 -1
  153. package/dist/formatting/StylesManager.d.ts +2 -2
  154. package/dist/formatting/StylesManager.d.ts.map +1 -1
  155. package/dist/formatting/StylesManager.js +96 -102
  156. package/dist/formatting/StylesManager.js.map +1 -1
  157. package/dist/helpers/CleanupHelper.d.ts +1 -1
  158. package/dist/helpers/CleanupHelper.d.ts.map +1 -1
  159. package/dist/helpers/CleanupHelper.js +6 -6
  160. package/dist/helpers/CleanupHelper.js.map +1 -1
  161. package/dist/images/ImageOptimizer.js +7 -7
  162. package/dist/images/ImageOptimizer.js.map +1 -1
  163. package/dist/index.d.ts +9 -9
  164. package/dist/index.d.ts.map +1 -1
  165. package/dist/index.js.map +1 -1
  166. package/dist/managers/DrawingManager.js.map +1 -1
  167. package/dist/tracking/DocumentTrackingContext.d.ts.map +1 -1
  168. package/dist/tracking/DocumentTrackingContext.js +23 -7
  169. package/dist/tracking/DocumentTrackingContext.js.map +1 -1
  170. package/dist/tracking/TrackingContext.d.ts.map +1 -1
  171. package/dist/tracking/TrackingContext.js.map +1 -1
  172. package/dist/types/compatibility-types.js.map +1 -1
  173. package/dist/types/formatting.js.map +1 -1
  174. package/dist/types/list-types.d.ts +6 -6
  175. package/dist/types/list-types.js.map +1 -1
  176. package/dist/types/settings-types.js.map +1 -1
  177. package/dist/types/styleConfig.d.ts +2 -2
  178. package/dist/types/styleConfig.js.map +1 -1
  179. package/dist/utils/ChangelogGenerator.d.ts.map +1 -1
  180. package/dist/utils/ChangelogGenerator.js +97 -101
  181. package/dist/utils/ChangelogGenerator.js.map +1 -1
  182. package/dist/utils/CompatibilityUpgrader.d.ts.map +1 -1
  183. package/dist/utils/CompatibilityUpgrader.js +1 -1
  184. package/dist/utils/CompatibilityUpgrader.js.map +1 -1
  185. package/dist/utils/InMemoryRevisionAcceptor.d.ts.map +1 -1
  186. package/dist/utils/InMemoryRevisionAcceptor.js +1 -6
  187. package/dist/utils/InMemoryRevisionAcceptor.js.map +1 -1
  188. package/dist/utils/MoveOperationHelper.d.ts.map +1 -1
  189. package/dist/utils/MoveOperationHelper.js +1 -1
  190. package/dist/utils/MoveOperationHelper.js.map +1 -1
  191. package/dist/utils/RevisionAwareProcessor.d.ts.map +1 -1
  192. package/dist/utils/RevisionAwareProcessor.js +2 -4
  193. package/dist/utils/RevisionAwareProcessor.js.map +1 -1
  194. package/dist/utils/RevisionWalker.d.ts.map +1 -1
  195. package/dist/utils/RevisionWalker.js +4 -12
  196. package/dist/utils/RevisionWalker.js.map +1 -1
  197. package/dist/utils/SelectiveRevisionAcceptor.d.ts.map +1 -1
  198. package/dist/utils/SelectiveRevisionAcceptor.js +2 -6
  199. package/dist/utils/SelectiveRevisionAcceptor.js.map +1 -1
  200. package/dist/utils/ShadingResolver.d.ts.map +1 -1
  201. package/dist/utils/ShadingResolver.js +1 -1
  202. package/dist/utils/ShadingResolver.js.map +1 -1
  203. package/dist/utils/acceptRevisions.d.ts.map +1 -1
  204. package/dist/utils/acceptRevisions.js +23 -12
  205. package/dist/utils/acceptRevisions.js.map +1 -1
  206. package/dist/utils/cnfStyleDecoder.d.ts +1 -1
  207. package/dist/utils/cnfStyleDecoder.d.ts.map +1 -1
  208. package/dist/utils/cnfStyleDecoder.js +40 -40
  209. package/dist/utils/cnfStyleDecoder.js.map +1 -1
  210. package/dist/utils/corruptionDetection.d.ts.map +1 -1
  211. package/dist/utils/corruptionDetection.js.map +1 -1
  212. package/dist/utils/dateFormatting.js.map +1 -1
  213. package/dist/utils/deepClone.js +1 -1
  214. package/dist/utils/deepClone.js.map +1 -1
  215. package/dist/utils/diagnostics.d.ts.map +1 -1
  216. package/dist/utils/diagnostics.js +1 -1
  217. package/dist/utils/diagnostics.js.map +1 -1
  218. package/dist/utils/errorHandling.js.map +1 -1
  219. package/dist/utils/formatting.d.ts.map +1 -1
  220. package/dist/utils/formatting.js +10 -2
  221. package/dist/utils/formatting.js.map +1 -1
  222. package/dist/utils/list-detection.d.ts +2 -2
  223. package/dist/utils/list-detection.d.ts.map +1 -1
  224. package/dist/utils/list-detection.js +21 -23
  225. package/dist/utils/list-detection.js.map +1 -1
  226. package/dist/utils/logger.d.ts.map +1 -1
  227. package/dist/utils/logger.js +12 -7
  228. package/dist/utils/logger.js.map +1 -1
  229. package/dist/utils/parsingHelpers.js.map +1 -1
  230. package/dist/utils/stripTrackedChanges.d.ts.map +1 -1
  231. package/dist/utils/stripTrackedChanges.js +3 -3
  232. package/dist/utils/stripTrackedChanges.js.map +1 -1
  233. package/dist/utils/textDiff.d.ts +1 -1
  234. package/dist/utils/textDiff.js +8 -8
  235. package/dist/utils/textDiff.js.map +1 -1
  236. package/dist/utils/units.js.map +1 -1
  237. package/dist/utils/validation.d.ts.map +1 -1
  238. package/dist/utils/validation.js +24 -7
  239. package/dist/utils/validation.js.map +1 -1
  240. package/dist/utils/xmlSanitization.d.ts.map +1 -1
  241. package/dist/utils/xmlSanitization.js +3 -3
  242. package/dist/utils/xmlSanitization.js.map +1 -1
  243. package/dist/validation/RevisionAutoFixer.d.ts.map +1 -1
  244. package/dist/validation/RevisionAutoFixer.js +5 -5
  245. package/dist/validation/RevisionAutoFixer.js.map +1 -1
  246. package/dist/validation/RevisionValidator.d.ts.map +1 -1
  247. package/dist/validation/RevisionValidator.js +7 -9
  248. package/dist/validation/RevisionValidator.js.map +1 -1
  249. package/dist/validation/ValidationRules.js +3 -3
  250. package/dist/validation/ValidationRules.js.map +1 -1
  251. package/dist/validation/index.js.map +1 -1
  252. package/dist/xml/XMLBuilder.d.ts +1 -1
  253. package/dist/xml/XMLBuilder.d.ts.map +1 -1
  254. package/dist/xml/XMLBuilder.js +98 -100
  255. package/dist/xml/XMLBuilder.js.map +1 -1
  256. package/dist/xml/XMLParser.d.ts.map +1 -1
  257. package/dist/xml/XMLParser.js +61 -66
  258. package/dist/xml/XMLParser.js.map +1 -1
  259. package/dist/zip/ZipHandler.d.ts.map +1 -1
  260. package/dist/zip/ZipHandler.js.map +1 -1
  261. package/dist/zip/ZipReader.d.ts.map +1 -1
  262. package/dist/zip/ZipReader.js +1 -3
  263. package/dist/zip/ZipReader.js.map +1 -1
  264. package/dist/zip/ZipWriter.d.ts +1 -1
  265. package/dist/zip/ZipWriter.d.ts.map +1 -1
  266. package/dist/zip/ZipWriter.js +28 -36
  267. package/dist/zip/ZipWriter.js.map +1 -1
  268. package/dist/zip/types.js +1 -1
  269. package/dist/zip/types.js.map +1 -1
  270. package/package.json +92 -92
  271. package/src/__tests__/helper-methods.test.ts +512 -512
  272. package/src/constants/legacyCompatFlags.ts +138 -138
  273. package/src/constants/limits.ts +50 -50
  274. package/src/core/Document.ts +1010 -1145
  275. package/src/core/DocumentContent.ts +461 -467
  276. package/src/core/DocumentGenerator.ts +1133 -1104
  277. package/src/core/DocumentIdManager.ts +158 -158
  278. package/src/core/DocumentParser.ts +2347 -2716
  279. package/src/core/DocumentValidator.ts +363 -372
  280. package/src/core/Relationship.ts +367 -367
  281. package/src/core/RelationshipManager.ts +429 -428
  282. package/src/elements/AlternateContent.ts +42 -42
  283. package/src/elements/Bookmark.ts +212 -210
  284. package/src/elements/BookmarkManager.ts +247 -250
  285. package/src/elements/Comment.ts +356 -359
  286. package/src/elements/CommentManager.ts +499 -502
  287. package/src/elements/CommonTypes.ts +524 -549
  288. package/src/elements/CustomXml.ts +36 -36
  289. package/src/elements/Endnote.ts +221 -217
  290. package/src/elements/EndnoteManager.ts +246 -249
  291. package/src/elements/Field.ts +1292 -1233
  292. package/src/elements/FieldHelpers.ts +329 -333
  293. package/src/elements/FontManager.ts +336 -339
  294. package/src/elements/Footer.ts +269 -269
  295. package/src/elements/Footnote.ts +221 -217
  296. package/src/elements/FootnoteManager.ts +246 -249
  297. package/src/elements/Header.ts +269 -269
  298. package/src/elements/HeaderFooterManager.ts +219 -219
  299. package/src/elements/Hyperlink.ts +1288 -1193
  300. package/src/elements/Image.ts +1982 -1756
  301. package/src/elements/ImageManager.ts +437 -432
  302. package/src/elements/ImageRun.ts +59 -59
  303. package/src/elements/MathElement.ts +65 -65
  304. package/src/elements/Paragraph.ts +4347 -4287
  305. package/src/elements/PreservedElement.ts +53 -53
  306. package/src/elements/PropertyChangeTypes.ts +458 -442
  307. package/src/elements/RangeMarker.ts +382 -400
  308. package/src/elements/Revision.ts +1198 -1217
  309. package/src/elements/RevisionContent.ts +73 -73
  310. package/src/elements/RevisionManager.ts +1070 -1070
  311. package/src/elements/Run.ts +3103 -3073
  312. package/src/elements/Section.ts +1521 -1421
  313. package/src/elements/Shape.ts +884 -873
  314. package/src/elements/StructuredDocumentTag.ts +1176 -1207
  315. package/src/elements/Table.ts +2468 -2524
  316. package/src/elements/TableCell.ts +1617 -1621
  317. package/src/elements/TableGridChange.ts +149 -151
  318. package/src/elements/TableOfContents.ts +701 -691
  319. package/src/elements/TableOfContentsElement.ts +89 -89
  320. package/src/elements/TableRow.ts +960 -929
  321. package/src/elements/TextBox.ts +766 -768
  322. package/src/formatting/AbstractNumbering.ts +580 -579
  323. package/src/formatting/NumberingInstance.ts +295 -299
  324. package/src/formatting/NumberingLevel.ts +981 -1040
  325. package/src/formatting/NumberingManager.ts +875 -827
  326. package/src/formatting/Style.ts +1785 -1879
  327. package/src/formatting/StylesManager.ts +1090 -1130
  328. package/src/helpers/CleanupHelper.ts +524 -524
  329. package/src/images/ImageOptimizer.ts +274 -274
  330. package/src/index.ts +559 -554
  331. package/src/managers/DrawingManager.ts +319 -319
  332. package/src/tracking/DocumentTrackingContext.ts +687 -674
  333. package/src/tracking/TrackingContext.ts +175 -173
  334. package/src/types/compatibility-types.ts +49 -49
  335. package/src/types/formatting.ts +210 -210
  336. package/src/types/list-types.ts +14 -14
  337. package/src/types/settings-types.ts +59 -59
  338. package/src/types/styleConfig.ts +189 -189
  339. package/src/utils/ChangelogGenerator.ts +1583 -1581
  340. package/src/utils/CompatibilityUpgrader.ts +235 -237
  341. package/src/utils/InMemoryRevisionAcceptor.ts +691 -696
  342. package/src/utils/MoveOperationHelper.ts +233 -238
  343. package/src/utils/RevisionAwareProcessor.ts +518 -526
  344. package/src/utils/RevisionWalker.ts +427 -457
  345. package/src/utils/SelectiveRevisionAcceptor.ts +662 -683
  346. package/src/utils/ShadingResolver.ts +105 -107
  347. package/src/utils/acceptRevisions.ts +723 -714
  348. package/src/utils/cnfStyleDecoder.ts +212 -217
  349. package/src/utils/corruptionDetection.ts +346 -345
  350. package/src/utils/dateFormatting.ts +20 -20
  351. package/src/utils/deepClone.ts +77 -78
  352. package/src/utils/diagnostics.ts +125 -129
  353. package/src/utils/errorHandling.ts +80 -80
  354. package/src/utils/formatting.ts +220 -213
  355. package/src/utils/list-detection.ts +32 -42
  356. package/src/utils/logger.ts +412 -404
  357. package/src/utils/parsingHelpers.ts +190 -190
  358. package/src/utils/stripTrackedChanges.ts +356 -353
  359. package/src/utils/textDiff.ts +100 -100
  360. package/src/utils/units.ts +421 -421
  361. package/src/utils/validation.ts +553 -542
  362. package/src/utils/xmlSanitization.ts +179 -182
  363. package/src/validation/RevisionAutoFixer.ts +541 -542
  364. package/src/validation/RevisionValidator.ts +470 -460
  365. package/src/validation/ValidationRules.ts +338 -338
  366. package/src/validation/index.ts +30 -30
  367. package/src/xml/XMLBuilder.ts +857 -871
  368. package/src/xml/XMLParser.ts +877 -919
  369. package/src/zip/ZipHandler.ts +629 -637
  370. package/src/zip/ZipReader.ts +295 -299
  371. package/src/zip/ZipWriter.ts +374 -390
  372. package/src/zip/types.ts +116 -116
@@ -1,299 +1,295 @@
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
- }
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((path) => !this.zip!.files[path]!.dir);
108
+
109
+ // Extract each file
110
+ for (const filePath of filePaths) {
111
+ const normalizedPath = normalizePath(filePath);
112
+ const zipObject = this.zip.files[filePath];
113
+
114
+ if (!zipObject) {
115
+ continue;
116
+ }
117
+
118
+ const isBinary = isBinaryFile(normalizedPath);
119
+
120
+ // Extract content based on type
121
+ // For text files: JSZip's async('string') automatically uses UTF-8 decoding
122
+ // For binary files: async('nodebuffer') preserves exact bytes
123
+ let content;
124
+ if (isBinary) {
125
+ content = await zipObject.async('nodebuffer');
126
+ } else {
127
+ // Text files are extracted as UTF-8 strings
128
+ // JSZip automatically handles UTF-8 decoding for 'string' type
129
+ content = await zipObject.async('string');
130
+ }
131
+
132
+ // Get file metadata
133
+ const date = zipObject.date;
134
+
135
+ // Store file information
136
+ this.files.set(normalizedPath, {
137
+ path: normalizedPath,
138
+ content,
139
+ isBinary,
140
+ size: isBinary ? (content as Buffer).length : (content as string).length,
141
+ date,
142
+ });
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Validates the DOCX structure
148
+ * @throws {MissingRequiredFileError} If required files are missing
149
+ */
150
+ private validate(): void {
151
+ const filePaths = Array.from(this.files.keys());
152
+ validateDocxStructure(filePaths);
153
+ }
154
+
155
+ /**
156
+ * Gets a specific file from the archive
157
+ * @param filePath - Path to the file within the archive
158
+ * @returns The file data, or undefined if not found
159
+ */
160
+ getFile(filePath: string): ZipFile | undefined {
161
+ this.ensureLoaded();
162
+ const normalizedPath = normalizePath(filePath);
163
+ return this.files.get(normalizedPath);
164
+ }
165
+
166
+ /**
167
+ * Gets the content of a specific file as a string
168
+ * @param filePath - Path to the file within the archive
169
+ * @returns The file content as a UTF-8 string, or undefined if not found
170
+ *
171
+ * **Encoding Note:**
172
+ * - Returns UTF-8 decoded string content
173
+ * - For binary files, converts the Buffer to UTF-8 string
174
+ * - Assumes all text content is UTF-8 encoded (per OpenXML standard)
175
+ */
176
+ getFileAsString(filePath: string): string | undefined {
177
+ const file = this.getFile(filePath);
178
+ if (!file) {
179
+ return undefined;
180
+ }
181
+
182
+ // Check actual content type instead of flag (Issue #4)
183
+ // Content is Buffer for binary files, string for text files
184
+ if (Buffer.isBuffer(file.content)) {
185
+ // Convert binary buffer to UTF-8 string
186
+ return file.content.toString('utf8');
187
+ }
188
+
189
+ return file.content;
190
+ }
191
+
192
+ /**
193
+ * Gets the content of a specific file as a buffer
194
+ * @param filePath - Path to the file within the archive
195
+ * @returns The file content as a Buffer, or undefined if not found
196
+ *
197
+ * **Encoding Note:**
198
+ * - Returns Buffer with UTF-8 encoded content for text files
199
+ * - For binary files, returns raw bytes
200
+ * - String content is explicitly encoded as UTF-8
201
+ */
202
+ getFileAsBuffer(filePath: string): Buffer | undefined {
203
+ const file = this.getFile(filePath);
204
+ if (!file) {
205
+ return undefined;
206
+ }
207
+
208
+ // Check actual content type instead of flag (Issue #4)
209
+ // Content is Buffer for binary files, string for text files
210
+ if (Buffer.isBuffer(file.content)) {
211
+ return file.content;
212
+ }
213
+
214
+ // Encode string content as UTF-8 Buffer
215
+ return Buffer.from(file.content, 'utf8');
216
+ }
217
+
218
+ /**
219
+ * Gets all files from the archive
220
+ * @returns Map of file paths to file data
221
+ */
222
+ getAllFiles(): FileMap {
223
+ this.ensureLoaded();
224
+ return new Map(this.files);
225
+ }
226
+
227
+ /**
228
+ * Gets a list of all file paths in the archive
229
+ * @returns Array of file paths
230
+ */
231
+ getFilePaths(): string[] {
232
+ this.ensureLoaded();
233
+ return Array.from(this.files.keys());
234
+ }
235
+
236
+ /**
237
+ * Checks if a file exists in the archive
238
+ * @param filePath - Path to check
239
+ * @returns True if the file exists
240
+ */
241
+ hasFile(filePath: string): boolean {
242
+ this.ensureLoaded();
243
+ const normalizedPath = normalizePath(filePath);
244
+ return this.files.has(normalizedPath);
245
+ }
246
+
247
+ /**
248
+ * Gets files matching a pattern (simple glob)
249
+ * @param pattern - Pattern to match (supports * wildcard)
250
+ * @returns Array of matching files
251
+ */
252
+ getFilesByPattern(pattern: string): ZipFile[] {
253
+ this.ensureLoaded();
254
+
255
+ // Convert simple glob pattern to regex
256
+ const regexPattern = pattern.replace(/\*/g, '.*').replace(/\?/g, '.');
257
+ const regex = new RegExp(`^${regexPattern}$`);
258
+
259
+ const matchingFiles: ZipFile[] = [];
260
+ for (const [path, file] of this.files) {
261
+ if (regex.test(path)) {
262
+ matchingFiles.push(file);
263
+ }
264
+ }
265
+
266
+ return matchingFiles;
267
+ }
268
+
269
+ /**
270
+ * Ensures the archive is loaded before operations
271
+ * @throws {Error} If archive is not loaded
272
+ */
273
+ private ensureLoaded(): void {
274
+ if (!this.loaded) {
275
+ throw new Error('Archive not loaded. Call loadFromFile() or loadFromBuffer() first.');
276
+ }
277
+ }
278
+
279
+ /**
280
+ * Checks if the archive is loaded
281
+ * @returns True if loaded
282
+ */
283
+ isLoaded(): boolean {
284
+ return this.loaded;
285
+ }
286
+
287
+ /**
288
+ * Clears all loaded data
289
+ */
290
+ clear(): void {
291
+ this.zip = null;
292
+ this.files.clear();
293
+ this.loaded = false;
294
+ }
295
+ }