docxmlater 10.1.3 → 10.1.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 (371) 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 +50 -50
  6. package/dist/core/Document.d.ts.map +1 -1
  7. package/dist/core/Document.js +483 -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.map +1 -1
  146. package/dist/formatting/NumberingManager.js +9 -9
  147. package/dist/formatting/NumberingManager.js.map +1 -1
  148. package/dist/formatting/Style.d.ts +11 -11
  149. package/dist/formatting/Style.d.ts.map +1 -1
  150. package/dist/formatting/Style.js +219 -247
  151. package/dist/formatting/Style.js.map +1 -1
  152. package/dist/formatting/StylesManager.d.ts +2 -2
  153. package/dist/formatting/StylesManager.d.ts.map +1 -1
  154. package/dist/formatting/StylesManager.js +96 -102
  155. package/dist/formatting/StylesManager.js.map +1 -1
  156. package/dist/helpers/CleanupHelper.d.ts +1 -1
  157. package/dist/helpers/CleanupHelper.d.ts.map +1 -1
  158. package/dist/helpers/CleanupHelper.js +6 -6
  159. package/dist/helpers/CleanupHelper.js.map +1 -1
  160. package/dist/images/ImageOptimizer.js +7 -7
  161. package/dist/images/ImageOptimizer.js.map +1 -1
  162. package/dist/index.d.ts +9 -9
  163. package/dist/index.d.ts.map +1 -1
  164. package/dist/index.js.map +1 -1
  165. package/dist/managers/DrawingManager.js.map +1 -1
  166. package/dist/tracking/DocumentTrackingContext.d.ts.map +1 -1
  167. package/dist/tracking/DocumentTrackingContext.js +23 -7
  168. package/dist/tracking/DocumentTrackingContext.js.map +1 -1
  169. package/dist/tracking/TrackingContext.d.ts.map +1 -1
  170. package/dist/tracking/TrackingContext.js.map +1 -1
  171. package/dist/types/compatibility-types.js.map +1 -1
  172. package/dist/types/formatting.js.map +1 -1
  173. package/dist/types/list-types.d.ts +6 -6
  174. package/dist/types/list-types.js.map +1 -1
  175. package/dist/types/settings-types.js.map +1 -1
  176. package/dist/types/styleConfig.d.ts +2 -2
  177. package/dist/types/styleConfig.js.map +1 -1
  178. package/dist/utils/ChangelogGenerator.d.ts.map +1 -1
  179. package/dist/utils/ChangelogGenerator.js +97 -101
  180. package/dist/utils/ChangelogGenerator.js.map +1 -1
  181. package/dist/utils/CompatibilityUpgrader.d.ts.map +1 -1
  182. package/dist/utils/CompatibilityUpgrader.js +1 -1
  183. package/dist/utils/CompatibilityUpgrader.js.map +1 -1
  184. package/dist/utils/InMemoryRevisionAcceptor.d.ts.map +1 -1
  185. package/dist/utils/InMemoryRevisionAcceptor.js +1 -6
  186. package/dist/utils/InMemoryRevisionAcceptor.js.map +1 -1
  187. package/dist/utils/MoveOperationHelper.d.ts.map +1 -1
  188. package/dist/utils/MoveOperationHelper.js +1 -1
  189. package/dist/utils/MoveOperationHelper.js.map +1 -1
  190. package/dist/utils/RevisionAwareProcessor.d.ts.map +1 -1
  191. package/dist/utils/RevisionAwareProcessor.js +2 -4
  192. package/dist/utils/RevisionAwareProcessor.js.map +1 -1
  193. package/dist/utils/RevisionWalker.d.ts.map +1 -1
  194. package/dist/utils/RevisionWalker.js +4 -12
  195. package/dist/utils/RevisionWalker.js.map +1 -1
  196. package/dist/utils/SelectiveRevisionAcceptor.d.ts.map +1 -1
  197. package/dist/utils/SelectiveRevisionAcceptor.js +2 -6
  198. package/dist/utils/SelectiveRevisionAcceptor.js.map +1 -1
  199. package/dist/utils/ShadingResolver.d.ts.map +1 -1
  200. package/dist/utils/ShadingResolver.js +1 -1
  201. package/dist/utils/ShadingResolver.js.map +1 -1
  202. package/dist/utils/acceptRevisions.d.ts.map +1 -1
  203. package/dist/utils/acceptRevisions.js +23 -12
  204. package/dist/utils/acceptRevisions.js.map +1 -1
  205. package/dist/utils/cnfStyleDecoder.d.ts +1 -1
  206. package/dist/utils/cnfStyleDecoder.d.ts.map +1 -1
  207. package/dist/utils/cnfStyleDecoder.js +40 -40
  208. package/dist/utils/cnfStyleDecoder.js.map +1 -1
  209. package/dist/utils/corruptionDetection.d.ts.map +1 -1
  210. package/dist/utils/corruptionDetection.js.map +1 -1
  211. package/dist/utils/dateFormatting.js.map +1 -1
  212. package/dist/utils/deepClone.js +1 -1
  213. package/dist/utils/deepClone.js.map +1 -1
  214. package/dist/utils/diagnostics.d.ts.map +1 -1
  215. package/dist/utils/diagnostics.js +1 -1
  216. package/dist/utils/diagnostics.js.map +1 -1
  217. package/dist/utils/errorHandling.js.map +1 -1
  218. package/dist/utils/formatting.d.ts.map +1 -1
  219. package/dist/utils/formatting.js +10 -2
  220. package/dist/utils/formatting.js.map +1 -1
  221. package/dist/utils/list-detection.d.ts +2 -2
  222. package/dist/utils/list-detection.d.ts.map +1 -1
  223. package/dist/utils/list-detection.js +21 -23
  224. package/dist/utils/list-detection.js.map +1 -1
  225. package/dist/utils/logger.d.ts.map +1 -1
  226. package/dist/utils/logger.js +12 -7
  227. package/dist/utils/logger.js.map +1 -1
  228. package/dist/utils/parsingHelpers.js.map +1 -1
  229. package/dist/utils/stripTrackedChanges.d.ts.map +1 -1
  230. package/dist/utils/stripTrackedChanges.js +3 -3
  231. package/dist/utils/stripTrackedChanges.js.map +1 -1
  232. package/dist/utils/textDiff.d.ts +1 -1
  233. package/dist/utils/textDiff.js +8 -8
  234. package/dist/utils/textDiff.js.map +1 -1
  235. package/dist/utils/units.js.map +1 -1
  236. package/dist/utils/validation.d.ts.map +1 -1
  237. package/dist/utils/validation.js +24 -7
  238. package/dist/utils/validation.js.map +1 -1
  239. package/dist/utils/xmlSanitization.d.ts.map +1 -1
  240. package/dist/utils/xmlSanitization.js +3 -3
  241. package/dist/utils/xmlSanitization.js.map +1 -1
  242. package/dist/validation/RevisionAutoFixer.d.ts.map +1 -1
  243. package/dist/validation/RevisionAutoFixer.js +5 -5
  244. package/dist/validation/RevisionAutoFixer.js.map +1 -1
  245. package/dist/validation/RevisionValidator.d.ts.map +1 -1
  246. package/dist/validation/RevisionValidator.js +7 -9
  247. package/dist/validation/RevisionValidator.js.map +1 -1
  248. package/dist/validation/ValidationRules.js +3 -3
  249. package/dist/validation/ValidationRules.js.map +1 -1
  250. package/dist/validation/index.js.map +1 -1
  251. package/dist/xml/XMLBuilder.d.ts +1 -1
  252. package/dist/xml/XMLBuilder.d.ts.map +1 -1
  253. package/dist/xml/XMLBuilder.js +98 -100
  254. package/dist/xml/XMLBuilder.js.map +1 -1
  255. package/dist/xml/XMLParser.d.ts.map +1 -1
  256. package/dist/xml/XMLParser.js +61 -66
  257. package/dist/xml/XMLParser.js.map +1 -1
  258. package/dist/zip/ZipHandler.d.ts.map +1 -1
  259. package/dist/zip/ZipHandler.js.map +1 -1
  260. package/dist/zip/ZipReader.d.ts.map +1 -1
  261. package/dist/zip/ZipReader.js +1 -3
  262. package/dist/zip/ZipReader.js.map +1 -1
  263. package/dist/zip/ZipWriter.d.ts +1 -1
  264. package/dist/zip/ZipWriter.d.ts.map +1 -1
  265. package/dist/zip/ZipWriter.js +28 -36
  266. package/dist/zip/ZipWriter.js.map +1 -1
  267. package/dist/zip/types.js +1 -1
  268. package/dist/zip/types.js.map +1 -1
  269. package/package.json +92 -92
  270. package/src/__tests__/helper-methods.test.ts +512 -512
  271. package/src/constants/legacyCompatFlags.ts +138 -138
  272. package/src/constants/limits.ts +50 -50
  273. package/src/core/Document.ts +985 -1145
  274. package/src/core/DocumentContent.ts +461 -467
  275. package/src/core/DocumentGenerator.ts +1133 -1104
  276. package/src/core/DocumentIdManager.ts +158 -158
  277. package/src/core/DocumentParser.ts +2347 -2716
  278. package/src/core/DocumentValidator.ts +363 -372
  279. package/src/core/Relationship.ts +367 -367
  280. package/src/core/RelationshipManager.ts +429 -428
  281. package/src/elements/AlternateContent.ts +42 -42
  282. package/src/elements/Bookmark.ts +212 -210
  283. package/src/elements/BookmarkManager.ts +247 -250
  284. package/src/elements/Comment.ts +356 -359
  285. package/src/elements/CommentManager.ts +499 -502
  286. package/src/elements/CommonTypes.ts +524 -549
  287. package/src/elements/CustomXml.ts +36 -36
  288. package/src/elements/Endnote.ts +221 -217
  289. package/src/elements/EndnoteManager.ts +246 -249
  290. package/src/elements/Field.ts +1292 -1233
  291. package/src/elements/FieldHelpers.ts +329 -333
  292. package/src/elements/FontManager.ts +336 -339
  293. package/src/elements/Footer.ts +269 -269
  294. package/src/elements/Footnote.ts +221 -217
  295. package/src/elements/FootnoteManager.ts +246 -249
  296. package/src/elements/Header.ts +269 -269
  297. package/src/elements/HeaderFooterManager.ts +219 -219
  298. package/src/elements/Hyperlink.ts +1288 -1193
  299. package/src/elements/Image.ts +1982 -1756
  300. package/src/elements/ImageManager.ts +437 -432
  301. package/src/elements/ImageRun.ts +59 -59
  302. package/src/elements/MathElement.ts +65 -65
  303. package/src/elements/Paragraph.ts +4347 -4287
  304. package/src/elements/PreservedElement.ts +53 -53
  305. package/src/elements/PropertyChangeTypes.ts +458 -442
  306. package/src/elements/RangeMarker.ts +382 -400
  307. package/src/elements/Revision.ts +1198 -1217
  308. package/src/elements/RevisionContent.ts +73 -73
  309. package/src/elements/RevisionManager.ts +1070 -1070
  310. package/src/elements/Run.ts +3103 -3073
  311. package/src/elements/Section.ts +1521 -1421
  312. package/src/elements/Shape.ts +884 -873
  313. package/src/elements/StructuredDocumentTag.ts +1176 -1207
  314. package/src/elements/Table.ts +2468 -2524
  315. package/src/elements/TableCell.ts +1617 -1621
  316. package/src/elements/TableGridChange.ts +149 -151
  317. package/src/elements/TableOfContents.ts +701 -691
  318. package/src/elements/TableOfContentsElement.ts +89 -89
  319. package/src/elements/TableRow.ts +960 -929
  320. package/src/elements/TextBox.ts +766 -768
  321. package/src/formatting/AbstractNumbering.ts +580 -579
  322. package/src/formatting/NumberingInstance.ts +295 -299
  323. package/src/formatting/NumberingLevel.ts +981 -1040
  324. package/src/formatting/NumberingManager.ts +833 -827
  325. package/src/formatting/Style.ts +1785 -1879
  326. package/src/formatting/StylesManager.ts +1090 -1130
  327. package/src/helpers/CleanupHelper.ts +524 -524
  328. package/src/images/ImageOptimizer.ts +274 -274
  329. package/src/index.ts +559 -554
  330. package/src/managers/DrawingManager.ts +319 -319
  331. package/src/tracking/DocumentTrackingContext.ts +687 -674
  332. package/src/tracking/TrackingContext.ts +175 -173
  333. package/src/types/compatibility-types.ts +49 -49
  334. package/src/types/formatting.ts +210 -210
  335. package/src/types/list-types.ts +14 -14
  336. package/src/types/settings-types.ts +59 -59
  337. package/src/types/styleConfig.ts +189 -189
  338. package/src/utils/ChangelogGenerator.ts +1583 -1581
  339. package/src/utils/CompatibilityUpgrader.ts +235 -237
  340. package/src/utils/InMemoryRevisionAcceptor.ts +691 -696
  341. package/src/utils/MoveOperationHelper.ts +233 -238
  342. package/src/utils/RevisionAwareProcessor.ts +518 -526
  343. package/src/utils/RevisionWalker.ts +427 -457
  344. package/src/utils/SelectiveRevisionAcceptor.ts +662 -683
  345. package/src/utils/ShadingResolver.ts +105 -107
  346. package/src/utils/acceptRevisions.ts +723 -714
  347. package/src/utils/cnfStyleDecoder.ts +212 -217
  348. package/src/utils/corruptionDetection.ts +346 -345
  349. package/src/utils/dateFormatting.ts +20 -20
  350. package/src/utils/deepClone.ts +77 -78
  351. package/src/utils/diagnostics.ts +125 -129
  352. package/src/utils/errorHandling.ts +80 -80
  353. package/src/utils/formatting.ts +220 -213
  354. package/src/utils/list-detection.ts +32 -42
  355. package/src/utils/logger.ts +412 -404
  356. package/src/utils/parsingHelpers.ts +190 -190
  357. package/src/utils/stripTrackedChanges.ts +356 -353
  358. package/src/utils/textDiff.ts +100 -100
  359. package/src/utils/units.ts +421 -421
  360. package/src/utils/validation.ts +553 -542
  361. package/src/utils/xmlSanitization.ts +179 -182
  362. package/src/validation/RevisionAutoFixer.ts +541 -542
  363. package/src/validation/RevisionValidator.ts +470 -460
  364. package/src/validation/ValidationRules.ts +338 -338
  365. package/src/validation/index.ts +30 -30
  366. package/src/xml/XMLBuilder.ts +857 -871
  367. package/src/xml/XMLParser.ts +877 -919
  368. package/src/zip/ZipHandler.ts +629 -637
  369. package/src/zip/ZipReader.ts +295 -299
  370. package/src/zip/ZipWriter.ts +374 -390
  371. 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
+ }