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 +1 @@
1
- {"version":3,"file":"errorHandling.js","sourceRoot":"","sources":["../../src/utils/errorHandling.ts"],"names":[],"mappings":";;AAUA,0BAEC;AAQD,0BAiBC;AASD,8BAUC;AASD,0CAcC;AArED,SAAgB,OAAO,CAAC,KAAc;IACpC,OAAO,KAAK,YAAY,KAAK,CAAC;AAChC,CAAC;AAQD,SAAgB,OAAO,CAAC,KAAc;IACpC,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IAGD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAGD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;QAC7D,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1C,CAAC;IAGD,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAClC,CAAC;AASD,SAAgB,SAAS,CAAC,KAAc,EAAE,OAAe;IACvD,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,YAAY,GAAG,IAAI,KAAK,CAAC,GAAG,OAAO,KAAK,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAGvE,IAAI,aAAa,CAAC,KAAK,EAAE,CAAC;QACxB,YAAY,CAAC,KAAK,GAAG,GAAG,YAAY,CAAC,OAAO,gBAAgB,aAAa,CAAC,KAAK,EAAE,CAAC;IACpF,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AASD,SAAgB,eAAe,CAAC,KAAc,EAAE,QAAQ,GAAG,wBAAwB;IACjF,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC,OAAO,CAAC;IACvB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;QAC7D,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["/**\r\n * Error handling utilities for consistent error processing\r\n * Ensures all caught errors are properly typed and handled\r\n */\r\n\r\n/**\r\n * Type guard to check if a value is an Error object\r\n * @param error - The value to check\r\n * @returns True if the value is an Error instance\r\n */\r\nexport function isError(error: unknown): error is Error {\r\n return error instanceof Error;\r\n}\r\n\r\n/**\r\n * Converts unknown error to Error object\r\n * Ensures we always have a proper Error with message property\r\n * @param error - The error to normalize (can be anything)\r\n * @returns Normalized Error object\r\n */\r\nexport function toError(error: unknown): Error {\r\n if (isError(error)) {\r\n return error;\r\n }\r\n\r\n // Handle string errors\r\n if (typeof error === 'string') {\r\n return new Error(error);\r\n }\r\n\r\n // Handle objects with message property\r\n if (error && typeof error === 'object' && 'message' in error) {\r\n return new Error(String(error.message));\r\n }\r\n\r\n // Fallback for any other type\r\n return new Error(String(error));\r\n}\r\n\r\n/**\r\n * Wraps an error with additional context\r\n * Useful for adding file paths, operation names, etc.\r\n * @param error - The original error\r\n * @param context - Additional context to prepend to error message\r\n * @returns New Error with combined message and original stack\r\n */\r\nexport function wrapError(error: unknown, context: string): Error {\r\n const originalError = toError(error);\r\n const wrappedError = new Error(`${context}: ${originalError.message}`);\r\n\r\n // Preserve original stack trace if available\r\n if (originalError.stack) {\r\n wrappedError.stack = `${wrappedError.message}\\nCaused by: ${originalError.stack}`;\r\n }\r\n\r\n return wrappedError;\r\n}\r\n\r\n/**\r\n * Safe error message extraction\r\n * Returns error message or generic fallback\r\n * @param error - The error to extract message from\r\n * @param fallback - Fallback message if extraction fails\r\n * @returns Error message string\r\n */\r\nexport function getErrorMessage(error: unknown, fallback = 'Unknown error occurred'): string {\r\n if (isError(error)) {\r\n return error.message;\r\n }\r\n\r\n if (typeof error === 'string') {\r\n return error;\r\n }\r\n\r\n if (error && typeof error === 'object' && 'message' in error) {\r\n return String(error.message);\r\n }\r\n\r\n return fallback;\r\n}\r\n"]}
1
+ {"version":3,"file":"errorHandling.js","sourceRoot":"","sources":["../../src/utils/errorHandling.ts"],"names":[],"mappings":";;AAUA,0BAEC;AAQD,0BAiBC;AASD,8BAUC;AASD,0CAcC;AArED,SAAgB,OAAO,CAAC,KAAc;IACpC,OAAO,KAAK,YAAY,KAAK,CAAC;AAChC,CAAC;AAQD,SAAgB,OAAO,CAAC,KAAc;IACpC,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IAGD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAGD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;QAC7D,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1C,CAAC;IAGD,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAClC,CAAC;AASD,SAAgB,SAAS,CAAC,KAAc,EAAE,OAAe;IACvD,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,YAAY,GAAG,IAAI,KAAK,CAAC,GAAG,OAAO,KAAK,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAGvE,IAAI,aAAa,CAAC,KAAK,EAAE,CAAC;QACxB,YAAY,CAAC,KAAK,GAAG,GAAG,YAAY,CAAC,OAAO,gBAAgB,aAAa,CAAC,KAAK,EAAE,CAAC;IACpF,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AASD,SAAgB,eAAe,CAAC,KAAc,EAAE,QAAQ,GAAG,wBAAwB;IACjF,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC,OAAO,CAAC;IACvB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;QAC7D,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["/**\n * Error handling utilities for consistent error processing\n * Ensures all caught errors are properly typed and handled\n */\n\n/**\n * Type guard to check if a value is an Error object\n * @param error - The value to check\n * @returns True if the value is an Error instance\n */\nexport function isError(error: unknown): error is Error {\n return error instanceof Error;\n}\n\n/**\n * Converts unknown error to Error object\n * Ensures we always have a proper Error with message property\n * @param error - The error to normalize (can be anything)\n * @returns Normalized Error object\n */\nexport function toError(error: unknown): Error {\n if (isError(error)) {\n return error;\n }\n\n // Handle string errors\n if (typeof error === 'string') {\n return new Error(error);\n }\n\n // Handle objects with message property\n if (error && typeof error === 'object' && 'message' in error) {\n return new Error(String(error.message));\n }\n\n // Fallback for any other type\n return new Error(String(error));\n}\n\n/**\n * Wraps an error with additional context\n * Useful for adding file paths, operation names, etc.\n * @param error - The original error\n * @param context - Additional context to prepend to error message\n * @returns New Error with combined message and original stack\n */\nexport function wrapError(error: unknown, context: string): Error {\n const originalError = toError(error);\n const wrappedError = new Error(`${context}: ${originalError.message}`);\n\n // Preserve original stack trace if available\n if (originalError.stack) {\n wrappedError.stack = `${wrappedError.message}\\nCaused by: ${originalError.stack}`;\n }\n\n return wrappedError;\n}\n\n/**\n * Safe error message extraction\n * Returns error message or generic fallback\n * @param error - The error to extract message from\n * @param fallback - Fallback message if extraction fails\n * @returns Error message string\n */\nexport function getErrorMessage(error: unknown, fallback = 'Unknown error occurred'): string {\n if (isError(error)) {\n return error.message;\n }\n\n if (typeof error === 'string') {\n return error;\n }\n\n if (error && typeof error === 'object' && 'message' in error) {\n return String(error.message);\n }\n\n return fallback;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"formatting.d.ts","sourceRoot":"","sources":["../../src/utils/formatting.ts"],"names":[],"mappings":"AAqBA,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3D,IAAI,EAAE,CAAC,EACP,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,GACnB,CAAC,CAmBH;AAgBD,wBAAgB,eAAe,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,CAEnD;AAeD,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAO1E;AAgBD,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAkBxF;AAmBD,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAsCT;AAiBD,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzD,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,EACtB,QAAQ,EAAE,CAAC,GACV,CAAC,CAeH"}
1
+ {"version":3,"file":"formatting.d.ts","sourceRoot":"","sources":["../../src/utils/formatting.ts"],"names":[],"mappings":"AAqBA,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAgB/F;AAgBD,wBAAgB,eAAe,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,CAEnD;AAeD,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAO1E;AAgBD,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAkBxF;AAmBD,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CA8CT;AAiBD,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzD,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,EACtB,QAAQ,EAAE,CAAC,GACV,CAAC,CAoBH"}
@@ -66,7 +66,12 @@ function isEqualFormatting(format1, format2) {
66
66
  if ((val1 === undefined || val1 === null) !== (val2 === undefined || val2 === null)) {
67
67
  return false;
68
68
  }
69
- if (typeof val1 === 'object' && val1 !== null && typeof val2 === 'object' && val2 !== null && !Array.isArray(val1) && !Array.isArray(val2)) {
69
+ if (typeof val1 === 'object' &&
70
+ val1 !== null &&
71
+ typeof val2 === 'object' &&
72
+ val2 !== null &&
73
+ !Array.isArray(val1) &&
74
+ !Array.isArray(val2)) {
70
75
  if (!isEqualFormatting(val1, val2))
71
76
  return false;
72
77
  }
@@ -80,7 +85,10 @@ function applyDefaults(formatting, defaults) {
80
85
  const result = { ...defaults };
81
86
  for (const [key, value] of Object.entries(formatting)) {
82
87
  if (value !== undefined) {
83
- if (typeof value === 'object' && !Array.isArray(value) && value !== null && typeof defaults[key] === 'object') {
88
+ if (typeof value === 'object' &&
89
+ !Array.isArray(value) &&
90
+ value !== null &&
91
+ typeof defaults[key] === 'object') {
84
92
  result[key] = applyDefaults(value, defaults[key]);
85
93
  }
86
94
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"formatting.js","sourceRoot":"","sources":["../../src/utils/formatting.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * Formatting utilities for deep merging and cloning formatting objects\r\n * Used for style inheritance and applying formatting\r\n */\r\n\r\n/**\r\n * Deep merges two formatting objects, with override taking precedence\r\n * Used for style inheritance and applying formatting\r\n *\r\n * @param base - Base formatting object\r\n * @param override - Override formatting object (takes precedence)\r\n * @returns Merged formatting object\r\n *\r\n * @example\r\n * ```typescript\r\n * const baseFormat = { bold: true, fontSize: 24 };\r\n * const overrideFormat = { fontSize: 28, italic: true };\r\n * const result = mergeFormatting(baseFormat, overrideFormat);\r\n * // Result: { bold: true, fontSize: 28, italic: true }\r\n * ```\r\n */\r\nexport function mergeFormatting<T extends Record<string, any>>(\r\n base: T,\r\n override: Partial<T>\r\n): T {\r\n const result = { ...base };\r\n\r\n for (const [key, value] of Object.entries(override)) {\r\n if (value === undefined) continue;\r\n\r\n if (typeof value === 'object' && !Array.isArray(value) && value !== null) {\r\n // Deep merge nested objects\r\n result[key as keyof T] = mergeFormatting(\r\n result[key as keyof T] || ({} as any),\r\n value\r\n );\r\n } else {\r\n // Direct assignment for primitives\r\n result[key as keyof T] = value;\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Deep clones a formatting object\r\n * Creates a completely independent copy with no shared references\r\n *\r\n * @param formatting - Formatting object to clone\r\n * @returns Cloned formatting object\r\n *\r\n * @example\r\n * ```typescript\r\n * const original = { bold: true, indentation: { left: 100 } };\r\n * const cloned = cloneFormatting(original);\r\n * cloned.indentation.left = 200; // Doesn't affect original\r\n * ```\r\n */\r\nexport function cloneFormatting<T>(formatting: T): T {\r\n return JSON.parse(JSON.stringify(formatting));\r\n}\r\n\r\n/**\r\n * Checks if a formatting object has any defined properties\r\n *\r\n * @param formatting - Formatting object to check\r\n * @returns True if the object has at least one defined property\r\n *\r\n * @example\r\n * ```typescript\r\n * hasFormatting({}) // false\r\n * hasFormatting({ bold: true }) // true\r\n * hasFormatting({ bold: undefined }) // false\r\n * ```\r\n */\r\nexport function hasFormatting(formatting: Record<string, unknown>): boolean {\r\n for (const value of Object.values(formatting)) {\r\n if (value !== undefined && value !== null) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Removes undefined and null properties from a formatting object\r\n * Useful for cleaning up formatting before comparison or serialization\r\n *\r\n * @param formatting - Formatting object to clean\r\n * @returns Cleaned formatting object with no undefined/null values\r\n *\r\n * @example\r\n * ```typescript\r\n * const dirty = { bold: true, italic: undefined, fontSize: null, underline: false };\r\n * const clean = cleanFormatting(dirty);\r\n * // Result: { bold: true, underline: false }\r\n * ```\r\n */\r\nexport function cleanFormatting<T extends Record<string, any>>(formatting: T): Partial<T> {\r\n const cleaned: Partial<T> = {};\r\n\r\n for (const [key, value] of Object.entries(formatting)) {\r\n if (value !== undefined && value !== null) {\r\n if (typeof value === 'object' && !Array.isArray(value)) {\r\n // Recursively clean nested objects\r\n const cleanedNested = cleanFormatting(value);\r\n if (Object.keys(cleanedNested).length > 0) {\r\n cleaned[key as keyof T] = cleanedNested as any;\r\n }\r\n } else {\r\n cleaned[key as keyof T] = value;\r\n }\r\n }\r\n }\r\n\r\n return cleaned;\r\n}\r\n\r\n/**\r\n * Compares two formatting objects for equality\r\n * Performs deep comparison of all properties\r\n *\r\n * @param format1 - First formatting object\r\n * @param format2 - Second formatting object\r\n * @returns True if the formatting objects are equal\r\n *\r\n * @example\r\n * ```typescript\r\n * const a = { bold: true, fontSize: 24 };\r\n * const b = { bold: true, fontSize: 24 };\r\n * const c = { bold: true, fontSize: 28 };\r\n * isEqualFormatting(a, b) // true\r\n * isEqualFormatting(a, c) // false\r\n * ```\r\n */\r\nexport function isEqualFormatting(\r\n format1: Record<string, unknown>,\r\n format2: Record<string, unknown>\r\n): boolean {\r\n // Quick reference check\r\n if (format1 === format2) return true;\r\n\r\n // Null/undefined checks\r\n if (!format1 || !format2) return false;\r\n\r\n // Get all keys from both objects\r\n const keys1 = Object.keys(format1);\r\n const keys2 = Object.keys(format2);\r\n\r\n // Check if they have the same number of properties\r\n if (keys1.length !== keys2.length) return false;\r\n\r\n // Check all properties\r\n for (const key of keys1) {\r\n const val1 = format1[key];\r\n const val2 = format2[key];\r\n\r\n // Both undefined/null - considered equal\r\n if ((val1 === undefined || val1 === null) && (val2 === undefined || val2 === null)) {\r\n continue;\r\n }\r\n\r\n // One is undefined/null and the other isn't\r\n if ((val1 === undefined || val1 === null) !== (val2 === undefined || val2 === null)) {\r\n return false;\r\n }\r\n\r\n // Check nested objects\r\n if (typeof val1 === 'object' && val1 !== null && typeof val2 === 'object' && val2 !== null && !Array.isArray(val1) && !Array.isArray(val2)) {\r\n if (!isEqualFormatting(val1 as Record<string, unknown>, val2 as Record<string, unknown>)) return false;\r\n } else if (val1 !== val2) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * Applies default values to a formatting object for any undefined properties\r\n *\r\n * @param formatting - Formatting object to apply defaults to\r\n * @param defaults - Default values\r\n * @returns Formatting object with defaults applied\r\n *\r\n * @example\r\n * ```typescript\r\n * const format = { bold: true };\r\n * const defaults = { bold: false, italic: false, fontSize: 24 };\r\n * const result = applyDefaults(format, defaults);\r\n * // Result: { bold: true, italic: false, fontSize: 24 }\r\n * ```\r\n */\r\nexport function applyDefaults<T extends Record<string, any>>(\r\n formatting: Partial<T>,\r\n defaults: T\r\n): T {\r\n const result = { ...defaults };\r\n\r\n for (const [key, value] of Object.entries(formatting)) {\r\n if (value !== undefined) {\r\n if (typeof value === 'object' && !Array.isArray(value) && value !== null && typeof defaults[key] === 'object') {\r\n // Deep merge nested objects\r\n result[key as keyof T] = applyDefaults(value, defaults[key]);\r\n } else {\r\n result[key as keyof T] = value;\r\n }\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n"]}
1
+ {"version":3,"file":"formatting.js","sourceRoot":"","sources":["../../src/utils/formatting.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Formatting utilities for deep merging and cloning formatting objects\n * Used for style inheritance and applying formatting\n */\n\n/**\n * Deep merges two formatting objects, with override taking precedence\n * Used for style inheritance and applying formatting\n *\n * @param base - Base formatting object\n * @param override - Override formatting object (takes precedence)\n * @returns Merged formatting object\n *\n * @example\n * ```typescript\n * const baseFormat = { bold: true, fontSize: 24 };\n * const overrideFormat = { fontSize: 28, italic: true };\n * const result = mergeFormatting(baseFormat, overrideFormat);\n * // Result: { bold: true, fontSize: 28, italic: true }\n * ```\n */\nexport function mergeFormatting<T extends Record<string, any>>(base: T, override: Partial<T>): T {\n const result = { ...base };\n\n for (const [key, value] of Object.entries(override)) {\n if (value === undefined) continue;\n\n if (typeof value === 'object' && !Array.isArray(value) && value !== null) {\n // Deep merge nested objects\n result[key as keyof T] = mergeFormatting(result[key as keyof T] || ({} as any), value);\n } else {\n // Direct assignment for primitives\n result[key as keyof T] = value;\n }\n }\n\n return result;\n}\n\n/**\n * Deep clones a formatting object\n * Creates a completely independent copy with no shared references\n *\n * @param formatting - Formatting object to clone\n * @returns Cloned formatting object\n *\n * @example\n * ```typescript\n * const original = { bold: true, indentation: { left: 100 } };\n * const cloned = cloneFormatting(original);\n * cloned.indentation.left = 200; // Doesn't affect original\n * ```\n */\nexport function cloneFormatting<T>(formatting: T): T {\n return JSON.parse(JSON.stringify(formatting));\n}\n\n/**\n * Checks if a formatting object has any defined properties\n *\n * @param formatting - Formatting object to check\n * @returns True if the object has at least one defined property\n *\n * @example\n * ```typescript\n * hasFormatting({}) // false\n * hasFormatting({ bold: true }) // true\n * hasFormatting({ bold: undefined }) // false\n * ```\n */\nexport function hasFormatting(formatting: Record<string, unknown>): boolean {\n for (const value of Object.values(formatting)) {\n if (value !== undefined && value !== null) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Removes undefined and null properties from a formatting object\n * Useful for cleaning up formatting before comparison or serialization\n *\n * @param formatting - Formatting object to clean\n * @returns Cleaned formatting object with no undefined/null values\n *\n * @example\n * ```typescript\n * const dirty = { bold: true, italic: undefined, fontSize: null, underline: false };\n * const clean = cleanFormatting(dirty);\n * // Result: { bold: true, underline: false }\n * ```\n */\nexport function cleanFormatting<T extends Record<string, any>>(formatting: T): Partial<T> {\n const cleaned: Partial<T> = {};\n\n for (const [key, value] of Object.entries(formatting)) {\n if (value !== undefined && value !== null) {\n if (typeof value === 'object' && !Array.isArray(value)) {\n // Recursively clean nested objects\n const cleanedNested = cleanFormatting(value);\n if (Object.keys(cleanedNested).length > 0) {\n cleaned[key as keyof T] = cleanedNested as any;\n }\n } else {\n cleaned[key as keyof T] = value;\n }\n }\n }\n\n return cleaned;\n}\n\n/**\n * Compares two formatting objects for equality\n * Performs deep comparison of all properties\n *\n * @param format1 - First formatting object\n * @param format2 - Second formatting object\n * @returns True if the formatting objects are equal\n *\n * @example\n * ```typescript\n * const a = { bold: true, fontSize: 24 };\n * const b = { bold: true, fontSize: 24 };\n * const c = { bold: true, fontSize: 28 };\n * isEqualFormatting(a, b) // true\n * isEqualFormatting(a, c) // false\n * ```\n */\nexport function isEqualFormatting(\n format1: Record<string, unknown>,\n format2: Record<string, unknown>\n): boolean {\n // Quick reference check\n if (format1 === format2) return true;\n\n // Null/undefined checks\n if (!format1 || !format2) return false;\n\n // Get all keys from both objects\n const keys1 = Object.keys(format1);\n const keys2 = Object.keys(format2);\n\n // Check if they have the same number of properties\n if (keys1.length !== keys2.length) return false;\n\n // Check all properties\n for (const key of keys1) {\n const val1 = format1[key];\n const val2 = format2[key];\n\n // Both undefined/null - considered equal\n if ((val1 === undefined || val1 === null) && (val2 === undefined || val2 === null)) {\n continue;\n }\n\n // One is undefined/null and the other isn't\n if ((val1 === undefined || val1 === null) !== (val2 === undefined || val2 === null)) {\n return false;\n }\n\n // Check nested objects\n if (\n typeof val1 === 'object' &&\n val1 !== null &&\n typeof val2 === 'object' &&\n val2 !== null &&\n !Array.isArray(val1) &&\n !Array.isArray(val2)\n ) {\n if (!isEqualFormatting(val1 as Record<string, unknown>, val2 as Record<string, unknown>))\n return false;\n } else if (val1 !== val2) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Applies default values to a formatting object for any undefined properties\n *\n * @param formatting - Formatting object to apply defaults to\n * @param defaults - Default values\n * @returns Formatting object with defaults applied\n *\n * @example\n * ```typescript\n * const format = { bold: true };\n * const defaults = { bold: false, italic: false, fontSize: 24 };\n * const result = applyDefaults(format, defaults);\n * // Result: { bold: true, italic: false, fontSize: 24 }\n * ```\n */\nexport function applyDefaults<T extends Record<string, any>>(\n formatting: Partial<T>,\n defaults: T\n): T {\n const result = { ...defaults };\n\n for (const [key, value] of Object.entries(formatting)) {\n if (value !== undefined) {\n if (\n typeof value === 'object' &&\n !Array.isArray(value) &&\n value !== null &&\n typeof defaults[key] === 'object'\n ) {\n // Deep merge nested objects\n result[key as keyof T] = applyDefaults(value, defaults[key]);\n } else {\n result[key as keyof T] = value;\n }\n }\n }\n\n return result;\n}\n"]}
@@ -1,5 +1,5 @@
1
- import type { Paragraph } from "../elements/Paragraph";
2
- import type { ListCategory, ListDetectionResult, NumberFormat, BulletFormat } from "../types/list-types";
1
+ import type { Paragraph } from '../elements/Paragraph';
2
+ import type { ListCategory, ListDetectionResult, NumberFormat, BulletFormat } from '../types/list-types';
3
3
  export declare const TYPED_LIST_PATTERNS: Record<string, RegExp>;
4
4
  export declare const PATTERN_TO_CATEGORY: Record<string, ListCategory>;
5
5
  export declare const FORMAT_TO_LEVEL: Record<string, number>;
@@ -1 +1 @@
1
- {"version":3,"file":"list-detection.d.ts","sourceRoot":"","sources":["../../src/utils/list-detection.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACb,MAAM,qBAAqB,CAAC;AAU7B,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAWtD,CAAC;AAGF,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAQ5D,CAAC;AASF,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CASlD,CAAC;AAMF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGhE;AAoBD,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAGrE;AAOD,wBAAgB,iCAAiC,CAAC,mBAAmB,EAAE,MAAM,GAAG,MAAM,CAGrF;AAWD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG;IAC/C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,YAAY,GAAG,YAAY,GAAG,IAAI,CAAC;IAC3C,QAAQ,EAAE,YAAY,CAAC;CACxB,CAwBA;AAKD,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAGpE;AAKD,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,mBAAmB,CA+CxE;AAMD,wBAAgB,oBAAoB,CAClC,UAAU,EAAE;IAAE,SAAS,EAAE,mBAAmB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,GAC7D;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAqCxC;AAMD,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,YAAY,CAgBd"}
1
+ {"version":3,"file":"list-detection.d.ts","sourceRoot":"","sources":["../../src/utils/list-detection.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACb,MAAM,qBAAqB,CAAC;AAU7B,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAWtD,CAAC;AAGF,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAQ5D,CAAC;AASF,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CASlD,CAAC;AAMF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGhE;AAoBD,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAGrE;AAOD,wBAAgB,iCAAiC,CAAC,mBAAmB,EAAE,MAAM,GAAG,MAAM,CAGrF;AAWD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG;IAC/C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,YAAY,GAAG,YAAY,GAAG,IAAI,CAAC;IAC3C,QAAQ,EAAE,YAAY,CAAC;CACxB,CAwBA;AAKD,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAGpE;AAKD,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,mBAAmB,CA+CxE;AAMD,wBAAgB,oBAAoB,CAClC,UAAU,EAAE;IAAE,SAAS,EAAE,mBAAmB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,GAC7D;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAiCxC;AAMD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,CAYlF"}
@@ -19,13 +19,13 @@ exports.TYPED_LIST_PATTERNS = {
19
19
  arrow: /^[►▸▶→]\s+/,
20
20
  };
21
21
  exports.PATTERN_TO_CATEGORY = {
22
- decimal: "numbered",
23
- lowerLetter: "numbered",
24
- upperLetter: "numbered",
25
- lowerRoman: "numbered",
26
- bullet: "bullet",
27
- dash: "bullet",
28
- arrow: "bullet",
22
+ decimal: 'numbered',
23
+ lowerLetter: 'numbered',
24
+ upperLetter: 'numbered',
25
+ lowerRoman: 'numbered',
26
+ bullet: 'bullet',
27
+ dash: 'bullet',
28
+ arrow: 'bullet',
29
29
  };
30
30
  exports.FORMAT_TO_LEVEL = {
31
31
  decimal: 0,
@@ -58,7 +58,7 @@ function detectTypedPrefix(text) {
58
58
  for (const [format, regex] of Object.entries(exports.TYPED_LIST_PATTERNS)) {
59
59
  const match = text.match(regex);
60
60
  if (match) {
61
- if (format === "lowerLetter" || format === "upperLetter") {
61
+ if (format === 'lowerLetter' || format === 'upperLetter') {
62
62
  const remaining = text.substring(match[0].length);
63
63
  if (/^[A-Za-z]\./.test(remaining)) {
64
64
  continue;
@@ -67,11 +67,11 @@ function detectTypedPrefix(text) {
67
67
  return {
68
68
  prefix: match[0],
69
69
  format: format,
70
- category: exports.PATTERN_TO_CATEGORY[format] ?? "none",
70
+ category: exports.PATTERN_TO_CATEGORY[format] ?? 'none',
71
71
  };
72
72
  }
73
73
  }
74
- return { prefix: null, format: null, category: "none" };
74
+ return { prefix: null, format: null, category: 'none' };
75
75
  }
76
76
  function getParagraphIndentation(paragraph) {
77
77
  const formatting = paragraph.getFormatting();
@@ -83,7 +83,7 @@ function detectListType(paragraph) {
83
83
  const numbering = paragraph.getNumbering();
84
84
  if (numbering?.numId !== undefined && numbering.numId !== 0) {
85
85
  return {
86
- category: "numbered",
86
+ category: 'numbered',
87
87
  isWordList: true,
88
88
  typedPrefix: null,
89
89
  inferredLevel: numbering.level ?? 0,
@@ -107,7 +107,7 @@ function detectListType(paragraph) {
107
107
  };
108
108
  }
109
109
  return {
110
- category: "none",
110
+ category: 'none',
111
111
  isWordList: false,
112
112
  typedPrefix: null,
113
113
  inferredLevel: 0,
@@ -120,9 +120,9 @@ function detectListType(paragraph) {
120
120
  function validateListSequence(paragraphs) {
121
121
  const warnings = [];
122
122
  let lastDecimal = 0;
123
- let lastLetter = "";
123
+ let lastLetter = '';
124
124
  for (const { detection } of paragraphs) {
125
- if (!detection.typedPrefix || detection.category !== "numbered")
125
+ if (!detection.typedPrefix || detection.category !== 'numbered')
126
126
  continue;
127
127
  const match = /^(\d+|[a-zA-Z]+)/.exec(detection.typedPrefix);
128
128
  if (!match?.[1])
@@ -137,9 +137,7 @@ function validateListSequence(paragraphs) {
137
137
  }
138
138
  if (/^[a-z]$/i.test(marker)) {
139
139
  const letter = marker.toLowerCase();
140
- if (lastLetter &&
141
- letter.charCodeAt(0) !== lastLetter.charCodeAt(0) + 1 &&
142
- letter !== "a") {
140
+ if (lastLetter && letter.charCodeAt(0) !== lastLetter.charCodeAt(0) + 1 && letter !== 'a') {
143
141
  warnings.push(`Unexpected letter sequence: ${lastLetter} → ${letter}`);
144
142
  }
145
143
  lastLetter = letter;
@@ -149,13 +147,13 @@ function validateListSequence(paragraphs) {
149
147
  }
150
148
  function getListCategoryFromFormat(format) {
151
149
  if (!format)
152
- return "none";
153
- if (["bullet", "dash", "arrow"].includes(format)) {
154
- return "bullet";
150
+ return 'none';
151
+ if (['bullet', 'dash', 'arrow'].includes(format)) {
152
+ return 'bullet';
155
153
  }
156
- if (["decimal", "lowerLetter", "upperLetter", "lowerRoman", "upperRoman"].includes(format)) {
157
- return "numbered";
154
+ if (['decimal', 'lowerLetter', 'upperLetter', 'lowerRoman', 'upperRoman'].includes(format)) {
155
+ return 'numbered';
158
156
  }
159
- return "none";
157
+ return 'none';
160
158
  }
161
159
  //# sourceMappingURL=list-detection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"list-detection.js","sourceRoot":"","sources":["../../src/utils/list-detection.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * List Detection Utilities for docxmlater\n *\n * Provides functions to detect typed list prefixes and analyze\n * paragraph list properties.\n */\n\nimport type { Paragraph } from \"../elements/Paragraph\";\nimport type {\n ListCategory,\n ListDetectionResult,\n NumberFormat,\n BulletFormat,\n} from \"../types/list-types\";\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/**\n * Regex patterns for typed list prefixes.\n * Order matters: more specific patterns first.\n */\nexport const TYPED_LIST_PATTERNS: Record<string, RegExp> = {\n // Numbered patterns (capture the marker for validation)\n decimal: /^(\\d+)[.)]\\s+/,\n lowerLetter: /^([a-z])[.)]\\s+/,\n upperLetter: /^([A-Z])[.)]\\s+/,\n lowerRoman: /^((?:i{1,3}|iv|vi{0,3}|ix|x{1,3}))[.)]\\s+/i,\n\n // Bullet patterns\n bullet: /^[•●○◦▪■□]\\s+/,\n dash: /^[-–—]\\s+/,\n arrow: /^[►▸▶→]\\s+/,\n};\n\n/** Map pattern names to categories */\nexport const PATTERN_TO_CATEGORY: Record<string, ListCategory> = {\n decimal: \"numbered\",\n lowerLetter: \"numbered\",\n upperLetter: \"numbered\",\n lowerRoman: \"numbered\",\n bullet: \"bullet\",\n dash: \"bullet\",\n arrow: \"bullet\",\n};\n\n/**\n * Map typed prefix format to Word numbering level.\n * Word's default multilevel list uses:\n * Level 0: 1., 2., 3. (decimal)\n * Level 1: a., b., c. (lowerLetter)\n * Level 2: i., ii., iii. (lowerRoman)\n */\nexport const FORMAT_TO_LEVEL: Record<string, number> = {\n decimal: 0, // 1., 2., 3.\n lowerLetter: 1, // a., b., c.\n upperLetter: 1, // A., B., C.\n lowerRoman: 2, // i., ii., iii.\n upperRoman: 2, // I., II., III.\n bullet: 0, // Top-level bullet (filled circle)\n dash: 0, // Top-level dash marker\n arrow: 0, // Top-level arrow marker\n};\n\n/**\n * Get the Word numbering level for a given format.\n * Returns 0 (top level) for decimal or unknown formats.\n */\nexport function getLevelFromFormat(format: string | null): number {\n if (!format) return 0;\n return FORMAT_TO_LEVEL[format] ?? 0;\n}\n\n/**\n * Word standard indentation values in twips.\n * Level 0: 720 twips (0.5 inch) left indent\n * Level 1: 1080 twips (0.75 inch) left indent\n * Level 2: 1440 twips (1 inch) left indent\n * Each subsequent level adds 360 twips.\n */\nconst WORD_BASE_INDENT = 720;\nconst INDENT_PER_LEVEL = 360;\n\n// =============================================================================\n// CORE DETECTION FUNCTIONS\n// =============================================================================\n\n/**\n * Infer list level from indentation.\n * Uses standard Word indentation: 720 twips for level 0, +360 per level.\n */\nexport function inferLevelFromIndentation(indentTwips: number): number {\n if (indentTwips < WORD_BASE_INDENT) return 0;\n return Math.floor((indentTwips - WORD_BASE_INDENT) / INDENT_PER_LEVEL);\n}\n\n/**\n * Infer list level from relative indentation (baseline already subtracted).\n * Used when normalizing lists within a table cell where the baseline\n * indentation varies per cell.\n */\nexport function inferLevelFromRelativeIndentation(relativeIndentTwips: number): number {\n if (relativeIndentTwips <= 0) return 0;\n return Math.min(8, Math.floor(relativeIndentTwips / INDENT_PER_LEVEL));\n}\n\n/**\n * Detect typed list prefix in text.\n * Returns the matched prefix and format type.\n *\n * Special handling for abbreviations:\n * - Single letter prefixes (A., B., P.) are NOT treated as list markers\n * if the remaining text also starts with a letter+period pattern,\n * indicating an abbreviation like \"P.O. Box\", \"U.S. Army\", etc.\n */\nexport function detectTypedPrefix(text: string): {\n prefix: string | null;\n format: NumberFormat | BulletFormat | null;\n category: ListCategory;\n} {\n for (const [format, regex] of Object.entries(TYPED_LIST_PATTERNS)) {\n const match = text.match(regex);\n if (match) {\n // Special check for single-letter patterns (lowerLetter, upperLetter)\n // to avoid false positives on abbreviations like \"P.O. Box\", \"U.S.\", \"A.M.\"\n if (format === \"lowerLetter\" || format === \"upperLetter\") {\n const remaining = text.substring(match[0].length);\n // If remaining text starts with another letter followed by period,\n // this is likely an abbreviation, not a list marker\n if (/^[A-Za-z]\\./.test(remaining)) {\n continue; // Skip this pattern, try others\n }\n }\n\n return {\n prefix: match[0],\n format: format as NumberFormat | BulletFormat,\n category: PATTERN_TO_CATEGORY[format] ?? \"none\",\n };\n }\n }\n\n return { prefix: null, format: null, category: \"none\" };\n}\n\n/**\n * Get the left indentation from a paragraph in twips.\n */\nexport function getParagraphIndentation(paragraph: Paragraph): number {\n const formatting = paragraph.getFormatting();\n return formatting?.indentation?.left ?? 0;\n}\n\n/**\n * Main detection function: analyze a single paragraph for list properties.\n */\nexport function detectListType(paragraph: Paragraph): ListDetectionResult {\n const text = paragraph.getText();\n const indentation = getParagraphIndentation(paragraph);\n const numbering = paragraph.getNumbering();\n\n // Priority 1: Real Word list with <w:numPr>\n if (numbering?.numId !== undefined && numbering.numId !== 0) {\n return {\n category: \"numbered\", // Default, caller can refine with NumberingManager lookup\n isWordList: true,\n typedPrefix: null,\n inferredLevel: numbering.level ?? 0,\n format: null, // Would need numbering.xml lookup\n numId: numbering.numId,\n ilvl: numbering.level ?? 0,\n indentationTwips: indentation,\n };\n }\n\n // Priority 2: Typed prefix detection\n const typed = detectTypedPrefix(text);\n if (typed.prefix) {\n return {\n category: typed.category,\n isWordList: false,\n typedPrefix: typed.prefix,\n // Use FORMAT to determine level, not indentation!\n // decimal=0, lowerLetter=1, lowerRoman=2\n inferredLevel: getLevelFromFormat(typed.format),\n format: typed.format,\n numId: null,\n ilvl: null,\n indentationTwips: indentation,\n };\n }\n\n // Priority 3: Not a list\n return {\n category: \"none\",\n isWordList: false,\n typedPrefix: null,\n inferredLevel: 0,\n format: null,\n numId: null,\n ilvl: null,\n indentationTwips: indentation,\n };\n}\n\n/**\n * Validate that a typed prefix sequence is reasonable.\n * E.g., \"1. 2. 3.\" is valid, \"1. 5. 2.\" is suspicious.\n */\nexport function validateListSequence(\n paragraphs: { detection: ListDetectionResult; text: string }[]\n): { valid: boolean; warnings: string[] } {\n const warnings: string[] = [];\n let lastDecimal = 0;\n let lastLetter = \"\";\n\n for (const { detection } of paragraphs) {\n if (!detection.typedPrefix || detection.category !== \"numbered\") continue;\n\n const match = /^(\\d+|[a-zA-Z]+)/.exec(detection.typedPrefix);\n if (!match?.[1]) continue;\n\n const marker = match[1];\n\n // Check decimal sequence\n if (/^\\d+$/.test(marker)) {\n const num = parseInt(marker, 10);\n if (lastDecimal > 0 && num !== lastDecimal + 1 && num !== 1) {\n warnings.push(`Unexpected number sequence: ${lastDecimal} → ${num}`);\n }\n lastDecimal = num;\n }\n\n // Check letter sequence\n if (/^[a-z]$/i.test(marker)) {\n const letter = marker.toLowerCase();\n if (\n lastLetter &&\n letter.charCodeAt(0) !== lastLetter.charCodeAt(0) + 1 &&\n letter !== \"a\"\n ) {\n warnings.push(`Unexpected letter sequence: ${lastLetter} → ${letter}`);\n }\n lastLetter = letter;\n }\n }\n\n return { valid: warnings.length === 0, warnings };\n}\n\n/**\n * Determine the list category for a given numId by checking the abstractNum.\n * This requires access to the NumberingManager.\n */\nexport function getListCategoryFromFormat(\n format: string | undefined\n): ListCategory {\n if (!format) return \"none\";\n\n if ([\"bullet\", \"dash\", \"arrow\"].includes(format)) {\n return \"bullet\";\n }\n\n if (\n [\"decimal\", \"lowerLetter\", \"upperLetter\", \"lowerRoman\", \"upperRoman\"].includes(\n format\n )\n ) {\n return \"numbered\";\n }\n\n return \"none\";\n}\n"]}
1
+ {"version":3,"file":"list-detection.js","sourceRoot":"","sources":["../../src/utils/list-detection.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * List Detection Utilities for docxmlater\n *\n * Provides functions to detect typed list prefixes and analyze\n * paragraph list properties.\n */\n\nimport type { Paragraph } from '../elements/Paragraph';\nimport type {\n ListCategory,\n ListDetectionResult,\n NumberFormat,\n BulletFormat,\n} from '../types/list-types';\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/**\n * Regex patterns for typed list prefixes.\n * Order matters: more specific patterns first.\n */\nexport const TYPED_LIST_PATTERNS: Record<string, RegExp> = {\n // Numbered patterns (capture the marker for validation)\n decimal: /^(\\d+)[.)]\\s+/,\n lowerLetter: /^([a-z])[.)]\\s+/,\n upperLetter: /^([A-Z])[.)]\\s+/,\n lowerRoman: /^((?:i{1,3}|iv|vi{0,3}|ix|x{1,3}))[.)]\\s+/i,\n\n // Bullet patterns\n bullet: /^[•●○◦▪■□]\\s+/,\n dash: /^[-–—]\\s+/,\n arrow: /^[►▸▶→]\\s+/,\n};\n\n/** Map pattern names to categories */\nexport const PATTERN_TO_CATEGORY: Record<string, ListCategory> = {\n decimal: 'numbered',\n lowerLetter: 'numbered',\n upperLetter: 'numbered',\n lowerRoman: 'numbered',\n bullet: 'bullet',\n dash: 'bullet',\n arrow: 'bullet',\n};\n\n/**\n * Map typed prefix format to Word numbering level.\n * Word's default multilevel list uses:\n * Level 0: 1., 2., 3. (decimal)\n * Level 1: a., b., c. (lowerLetter)\n * Level 2: i., ii., iii. (lowerRoman)\n */\nexport const FORMAT_TO_LEVEL: Record<string, number> = {\n decimal: 0, // 1., 2., 3.\n lowerLetter: 1, // a., b., c.\n upperLetter: 1, // A., B., C.\n lowerRoman: 2, // i., ii., iii.\n upperRoman: 2, // I., II., III.\n bullet: 0, // Top-level bullet (filled circle)\n dash: 0, // Top-level dash marker\n arrow: 0, // Top-level arrow marker\n};\n\n/**\n * Get the Word numbering level for a given format.\n * Returns 0 (top level) for decimal or unknown formats.\n */\nexport function getLevelFromFormat(format: string | null): number {\n if (!format) return 0;\n return FORMAT_TO_LEVEL[format] ?? 0;\n}\n\n/**\n * Word standard indentation values in twips.\n * Level 0: 720 twips (0.5 inch) left indent\n * Level 1: 1080 twips (0.75 inch) left indent\n * Level 2: 1440 twips (1 inch) left indent\n * Each subsequent level adds 360 twips.\n */\nconst WORD_BASE_INDENT = 720;\nconst INDENT_PER_LEVEL = 360;\n\n// =============================================================================\n// CORE DETECTION FUNCTIONS\n// =============================================================================\n\n/**\n * Infer list level from indentation.\n * Uses standard Word indentation: 720 twips for level 0, +360 per level.\n */\nexport function inferLevelFromIndentation(indentTwips: number): number {\n if (indentTwips < WORD_BASE_INDENT) return 0;\n return Math.floor((indentTwips - WORD_BASE_INDENT) / INDENT_PER_LEVEL);\n}\n\n/**\n * Infer list level from relative indentation (baseline already subtracted).\n * Used when normalizing lists within a table cell where the baseline\n * indentation varies per cell.\n */\nexport function inferLevelFromRelativeIndentation(relativeIndentTwips: number): number {\n if (relativeIndentTwips <= 0) return 0;\n return Math.min(8, Math.floor(relativeIndentTwips / INDENT_PER_LEVEL));\n}\n\n/**\n * Detect typed list prefix in text.\n * Returns the matched prefix and format type.\n *\n * Special handling for abbreviations:\n * - Single letter prefixes (A., B., P.) are NOT treated as list markers\n * if the remaining text also starts with a letter+period pattern,\n * indicating an abbreviation like \"P.O. Box\", \"U.S. Army\", etc.\n */\nexport function detectTypedPrefix(text: string): {\n prefix: string | null;\n format: NumberFormat | BulletFormat | null;\n category: ListCategory;\n} {\n for (const [format, regex] of Object.entries(TYPED_LIST_PATTERNS)) {\n const match = text.match(regex);\n if (match) {\n // Special check for single-letter patterns (lowerLetter, upperLetter)\n // to avoid false positives on abbreviations like \"P.O. Box\", \"U.S.\", \"A.M.\"\n if (format === 'lowerLetter' || format === 'upperLetter') {\n const remaining = text.substring(match[0].length);\n // If remaining text starts with another letter followed by period,\n // this is likely an abbreviation, not a list marker\n if (/^[A-Za-z]\\./.test(remaining)) {\n continue; // Skip this pattern, try others\n }\n }\n\n return {\n prefix: match[0],\n format: format as NumberFormat | BulletFormat,\n category: PATTERN_TO_CATEGORY[format] ?? 'none',\n };\n }\n }\n\n return { prefix: null, format: null, category: 'none' };\n}\n\n/**\n * Get the left indentation from a paragraph in twips.\n */\nexport function getParagraphIndentation(paragraph: Paragraph): number {\n const formatting = paragraph.getFormatting();\n return formatting?.indentation?.left ?? 0;\n}\n\n/**\n * Main detection function: analyze a single paragraph for list properties.\n */\nexport function detectListType(paragraph: Paragraph): ListDetectionResult {\n const text = paragraph.getText();\n const indentation = getParagraphIndentation(paragraph);\n const numbering = paragraph.getNumbering();\n\n // Priority 1: Real Word list with <w:numPr>\n if (numbering?.numId !== undefined && numbering.numId !== 0) {\n return {\n category: 'numbered', // Default, caller can refine with NumberingManager lookup\n isWordList: true,\n typedPrefix: null,\n inferredLevel: numbering.level ?? 0,\n format: null, // Would need numbering.xml lookup\n numId: numbering.numId,\n ilvl: numbering.level ?? 0,\n indentationTwips: indentation,\n };\n }\n\n // Priority 2: Typed prefix detection\n const typed = detectTypedPrefix(text);\n if (typed.prefix) {\n return {\n category: typed.category,\n isWordList: false,\n typedPrefix: typed.prefix,\n // Use FORMAT to determine level, not indentation!\n // decimal=0, lowerLetter=1, lowerRoman=2\n inferredLevel: getLevelFromFormat(typed.format),\n format: typed.format,\n numId: null,\n ilvl: null,\n indentationTwips: indentation,\n };\n }\n\n // Priority 3: Not a list\n return {\n category: 'none',\n isWordList: false,\n typedPrefix: null,\n inferredLevel: 0,\n format: null,\n numId: null,\n ilvl: null,\n indentationTwips: indentation,\n };\n}\n\n/**\n * Validate that a typed prefix sequence is reasonable.\n * E.g., \"1. 2. 3.\" is valid, \"1. 5. 2.\" is suspicious.\n */\nexport function validateListSequence(\n paragraphs: { detection: ListDetectionResult; text: string }[]\n): { valid: boolean; warnings: string[] } {\n const warnings: string[] = [];\n let lastDecimal = 0;\n let lastLetter = '';\n\n for (const { detection } of paragraphs) {\n if (!detection.typedPrefix || detection.category !== 'numbered') continue;\n\n const match = /^(\\d+|[a-zA-Z]+)/.exec(detection.typedPrefix);\n if (!match?.[1]) continue;\n\n const marker = match[1];\n\n // Check decimal sequence\n if (/^\\d+$/.test(marker)) {\n const num = parseInt(marker, 10);\n if (lastDecimal > 0 && num !== lastDecimal + 1 && num !== 1) {\n warnings.push(`Unexpected number sequence: ${lastDecimal} → ${num}`);\n }\n lastDecimal = num;\n }\n\n // Check letter sequence\n if (/^[a-z]$/i.test(marker)) {\n const letter = marker.toLowerCase();\n if (lastLetter && letter.charCodeAt(0) !== lastLetter.charCodeAt(0) + 1 && letter !== 'a') {\n warnings.push(`Unexpected letter sequence: ${lastLetter} → ${letter}`);\n }\n lastLetter = letter;\n }\n }\n\n return { valid: warnings.length === 0, warnings };\n}\n\n/**\n * Determine the list category for a given numId by checking the abstractNum.\n * This requires access to the NumberingManager.\n */\nexport function getListCategoryFromFormat(format: string | undefined): ListCategory {\n if (!format) return 'none';\n\n if (['bullet', 'dash', 'arrow'].includes(format)) {\n return 'bullet';\n }\n\n if (['decimal', 'lowerLetter', 'upperLetter', 'lowerRoman', 'upperRoman'].includes(format)) {\n return 'numbered';\n }\n\n return 'none';\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
@@ -125,14 +125,14 @@ class CollectingLogger {
125
125
  return [...this.logs];
126
126
  }
127
127
  getLogsByLevel(level) {
128
- return this.logs.filter(log => log.level === level);
128
+ return this.logs.filter((log) => log.level === level);
129
129
  }
130
130
  clear() {
131
131
  this.logs = [];
132
132
  }
133
133
  getCount(level) {
134
134
  if (level) {
135
- return this.logs.filter(log => log.level === level).length;
135
+ return this.logs.filter((log) => log.level === level).length;
136
136
  }
137
137
  return this.logs.length;
138
138
  }
@@ -173,11 +173,16 @@ function parseLogLevel(level) {
173
173
  return undefined;
174
174
  const normalized = level.toLowerCase();
175
175
  switch (normalized) {
176
- case 'debug': return LogLevel.DEBUG;
177
- case 'info': return LogLevel.INFO;
178
- case 'warn': return LogLevel.WARN;
179
- case 'error': return LogLevel.ERROR;
180
- default: return undefined;
176
+ case 'debug':
177
+ return LogLevel.DEBUG;
178
+ case 'info':
179
+ return LogLevel.INFO;
180
+ case 'warn':
181
+ return LogLevel.WARN;
182
+ case 'error':
183
+ return LogLevel.ERROR;
184
+ default:
185
+ return undefined;
181
186
  }
182
187
  }
183
188
  function createLoggerFromEnv() {
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * Logging interface for docXMLater\r\n * Allows library consumers to control logging behavior\r\n */\r\n\r\n/**\r\n * Log severity levels\r\n */\r\nexport enum LogLevel {\r\n /** Debugging information (most verbose) */\r\n DEBUG = 'debug',\r\n /** Informational messages */\r\n INFO = 'info',\r\n /** Warning messages - potential issues that don't prevent operation */\r\n WARN = 'warn',\r\n /** Error messages - serious issues that may cause failures */\r\n ERROR = 'error',\r\n}\r\n\r\n/**\r\n * Log entry structure\r\n */\r\nexport interface LogEntry {\r\n /** Timestamp when log was created */\r\n timestamp: Date;\r\n /** Severity level */\r\n level: LogLevel;\r\n /** Log message */\r\n message: string;\r\n /** Optional context data */\r\n context?: Record<string, any>;\r\n /** Source component that generated the log */\r\n source?: string;\r\n}\r\n\r\n/**\r\n * Logger interface that consumers can implement\r\n * Provides full control over how logs are handled\r\n */\r\nexport interface ILogger {\r\n /**\r\n * Log a debug message\r\n * @param message - Debug message\r\n * @param context - Optional context data\r\n */\r\n debug(message: string, context?: Record<string, any>): void;\r\n\r\n /**\r\n * Log an informational message\r\n * @param message - Info message\r\n * @param context - Optional context data\r\n */\r\n info(message: string, context?: Record<string, any>): void;\r\n\r\n /**\r\n * Log a warning message\r\n * @param message - Warning message\r\n * @param context - Optional context data\r\n */\r\n warn(message: string, context?: Record<string, any>): void;\r\n\r\n /**\r\n * Log an error message\r\n * @param message - Error message\r\n * @param context - Optional context data\r\n */\r\n error(message: string, context?: Record<string, any>): void;\r\n}\r\n\r\n/**\r\n * Console-based logger implementation\r\n * Uses standard console methods for output with timestamps and source prefixes\r\n */\r\nexport class ConsoleLogger implements ILogger {\r\n private showTimestamp: boolean;\r\n\r\n constructor(private minLevel: LogLevel = LogLevel.WARN, options?: { showTimestamp?: boolean }) {\r\n this.showTimestamp = options?.showTimestamp ?? true;\r\n }\r\n\r\n debug(message: string, context?: Record<string, any>): void {\r\n if (this.shouldLog(LogLevel.DEBUG)) {\r\n console.debug(this.formatMessage(LogLevel.DEBUG, message, context));\r\n }\r\n }\r\n\r\n info(message: string, context?: Record<string, any>): void {\r\n if (this.shouldLog(LogLevel.INFO)) {\r\n console.info(this.formatMessage(LogLevel.INFO, message, context));\r\n }\r\n }\r\n\r\n warn(message: string, context?: Record<string, any>): void {\r\n if (this.shouldLog(LogLevel.WARN)) {\r\n console.warn(this.formatMessage(LogLevel.WARN, message, context));\r\n }\r\n }\r\n\r\n error(message: string, context?: Record<string, any>): void {\r\n if (this.shouldLog(LogLevel.ERROR)) {\r\n console.error(this.formatMessage(LogLevel.ERROR, message, context));\r\n }\r\n }\r\n\r\n private shouldLog(level: LogLevel): boolean {\r\n const levels = [LogLevel.DEBUG, LogLevel.INFO, LogLevel.WARN, LogLevel.ERROR];\r\n const minIndex = levels.indexOf(this.minLevel);\r\n const currentIndex = levels.indexOf(level);\r\n return currentIndex >= minIndex;\r\n }\r\n\r\n private formatMessage(level: LogLevel, message: string, context?: Record<string, any>): string {\r\n const parts: string[] = [];\r\n\r\n // Add timestamp if enabled\r\n if (this.showTimestamp) {\r\n const timestamp = new Date().toISOString().slice(11, 23); // HH:mm:ss.SSS\r\n parts.push(timestamp);\r\n }\r\n\r\n // Add level tag\r\n parts.push(`[${level.toUpperCase().padEnd(5)}]`);\r\n\r\n // Add source if present\r\n if (context?.source) {\r\n parts.push(`[${context.source}]`);\r\n }\r\n\r\n // Add message\r\n parts.push(message);\r\n\r\n // Add context (excluding source which is already shown)\r\n if (context && Object.keys(context).length > 0) {\r\n const contextWithoutSource = { ...context };\r\n delete contextWithoutSource.source;\r\n if (Object.keys(contextWithoutSource).length > 0) {\r\n // Format context as key=value pairs for readability\r\n const contextStr = this.formatContext(contextWithoutSource);\r\n if (contextStr) {\r\n parts.push(contextStr);\r\n }\r\n }\r\n }\r\n\r\n return parts.join(' ');\r\n }\r\n\r\n private formatContext(context: Record<string, any>): string {\r\n const pairs: string[] = [];\r\n for (const [key, value] of Object.entries(context)) {\r\n if (value === undefined || value === null) continue;\r\n if (typeof value === 'object' && !Array.isArray(value)) {\r\n // Nested object - use compact JSON\r\n pairs.push(`${key}=${JSON.stringify(value)}`);\r\n } else if (Array.isArray(value)) {\r\n pairs.push(`${key}=[${value.length}]`);\r\n } else {\r\n pairs.push(`${key}=${value}`);\r\n }\r\n }\r\n return pairs.length > 0 ? pairs.join(' ') : '';\r\n }\r\n}\r\n\r\n/**\r\n * Silent logger that discards all log messages\r\n * Useful for testing or when logging is not desired\r\n */\r\nexport class SilentLogger implements ILogger {\r\n debug(): void {\r\n // No-op\r\n }\r\n\r\n info(): void {\r\n // No-op\r\n }\r\n\r\n warn(): void {\r\n // No-op\r\n }\r\n\r\n error(): void {\r\n // No-op\r\n }\r\n}\r\n\r\n/**\r\n * Collecting logger that stores log entries in memory\r\n * Useful for testing and diagnostics\r\n */\r\nexport class CollectingLogger implements ILogger {\r\n private logs: LogEntry[] = [];\r\n\r\n debug(message: string, context?: Record<string, any>): void {\r\n this.addLog(LogLevel.DEBUG, message, context);\r\n }\r\n\r\n info(message: string, context?: Record<string, any>): void {\r\n this.addLog(LogLevel.INFO, message, context);\r\n }\r\n\r\n warn(message: string, context?: Record<string, any>): void {\r\n this.addLog(LogLevel.WARN, message, context);\r\n }\r\n\r\n error(message: string, context?: Record<string, any>): void {\r\n this.addLog(LogLevel.ERROR, message, context);\r\n }\r\n\r\n private addLog(level: LogLevel, message: string, context?: Record<string, any>): void {\r\n this.logs.push({\r\n timestamp: new Date(),\r\n level,\r\n message,\r\n context,\r\n });\r\n }\r\n\r\n /**\r\n * Get all collected log entries\r\n */\r\n getLogs(): readonly LogEntry[] {\r\n return [...this.logs];\r\n }\r\n\r\n /**\r\n * Get logs filtered by level\r\n */\r\n getLogsByLevel(level: LogLevel): readonly LogEntry[] {\r\n return this.logs.filter(log => log.level === level);\r\n }\r\n\r\n /**\r\n * Clear all collected logs\r\n */\r\n clear(): void {\r\n this.logs = [];\r\n }\r\n\r\n /**\r\n * Get count of logs by level\r\n */\r\n getCount(level?: LogLevel): number {\r\n if (level) {\r\n return this.logs.filter(log => log.level === level).length;\r\n }\r\n return this.logs.length;\r\n }\r\n}\r\n\r\n/**\r\n * Default logger instance\r\n * Delegates to the global logger, respecting setGlobalLogger() and environment variables\r\n */\r\nexport const defaultLogger: ILogger = {\r\n debug(message: string, context?: Record<string, any>): void {\r\n getGlobalLogger().debug(message, context);\r\n },\r\n info(message: string, context?: Record<string, any>): void {\r\n getGlobalLogger().info(message, context);\r\n },\r\n warn(message: string, context?: Record<string, any>): void {\r\n getGlobalLogger().warn(message, context);\r\n },\r\n error(message: string, context?: Record<string, any>): void {\r\n getGlobalLogger().error(message, context);\r\n },\r\n};\r\n\r\n/**\r\n * Creates a scoped logger that adds source information\r\n * @param logger - Base logger\r\n * @param source - Source component name\r\n * @returns Scoped logger with source context\r\n */\r\nexport function createScopedLogger(logger: ILogger, source: string): ILogger {\r\n return {\r\n debug(message: string, context?: Record<string, any>): void {\r\n logger.debug(message, { ...context, source });\r\n },\r\n info(message: string, context?: Record<string, any>): void {\r\n logger.info(message, { ...context, source });\r\n },\r\n warn(message: string, context?: Record<string, any>): void {\r\n logger.warn(message, { ...context, source });\r\n },\r\n error(message: string, context?: Record<string, any>): void {\r\n logger.error(message, { ...context, source });\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Parse log level from string\r\n * @param level - Log level string (case-insensitive)\r\n * @returns LogLevel or undefined if invalid\r\n */\r\nfunction parseLogLevel(level: string | undefined): LogLevel | undefined {\r\n if (!level) return undefined;\r\n const normalized = level.toLowerCase();\r\n switch (normalized) {\r\n case 'debug': return LogLevel.DEBUG;\r\n case 'info': return LogLevel.INFO;\r\n case 'warn': return LogLevel.WARN;\r\n case 'error': return LogLevel.ERROR;\r\n default: return undefined;\r\n }\r\n}\r\n\r\n/**\r\n * Create a logger based on environment variables\r\n *\r\n * Environment variables (in order of precedence):\r\n * - DEBUG=docxmlater or DEBUG=docxmlater:* - Enables DEBUG level\r\n * - DOCXMLATER_LOG_LEVEL=debug|info|warn|error|silent - Sets specific level\r\n *\r\n * @returns Logger configured from environment, or SilentLogger if not configured\r\n */\r\nfunction createLoggerFromEnv(): ILogger {\r\n // Check DEBUG environment variable first (highest precedence for debug mode)\r\n const debugEnv = process.env.DEBUG || '';\r\n if (debugEnv.includes('docxmlater')) {\r\n return new ConsoleLogger(LogLevel.DEBUG);\r\n }\r\n\r\n // Check DOCXMLATER_LOG_LEVEL environment variable\r\n const envLevel = process.env.DOCXMLATER_LOG_LEVEL?.toLowerCase();\r\n if (envLevel === 'silent') {\r\n return new SilentLogger();\r\n }\r\n\r\n const parsedLevel = parseLogLevel(envLevel);\r\n if (parsedLevel) {\r\n return new ConsoleLogger(parsedLevel);\r\n }\r\n\r\n // Default: silent (no logging unless explicitly enabled)\r\n return new SilentLogger();\r\n}\r\n\r\n// Global logger instance - initialized from environment\r\nlet globalLogger: ILogger = createLoggerFromEnv();\r\n\r\n/**\r\n * Set the global logger instance\r\n * Use this to configure logging programmatically\r\n *\r\n * @example\r\n * ```typescript\r\n * import { setGlobalLogger, ConsoleLogger, LogLevel } from 'docxmlater';\r\n *\r\n * // Enable info-level logging\r\n * setGlobalLogger(new ConsoleLogger(LogLevel.INFO));\r\n * ```\r\n *\r\n * @param logger - Logger instance to use globally\r\n */\r\nexport function setGlobalLogger(logger: ILogger): void {\r\n globalLogger = logger;\r\n}\r\n\r\n/**\r\n * Get the global logger instance\r\n * Used internally by framework components\r\n *\r\n * @returns Current global logger\r\n */\r\nexport function getGlobalLogger(): ILogger {\r\n return globalLogger;\r\n}\r\n\r\n/**\r\n * Reset the global logger to its default (environment-based) configuration\r\n * Useful for testing cleanup\r\n */\r\nexport function resetGlobalLogger(): void {\r\n globalLogger = createLoggerFromEnv();\r\n}\r\n\r\n/**\r\n * Creates a component-scoped logger using the global logger.\r\n * This is a convenience function that combines getGlobalLogger() and createScopedLogger()\r\n * into a single call, reducing boilerplate in component files.\r\n *\r\n * @param componentName - Name of the component (appears in log output)\r\n * @returns Scoped logger instance\r\n *\r\n * @example\r\n * ```typescript\r\n * // Instead of:\r\n * function getLogger(): ILogger {\r\n * return createScopedLogger(getGlobalLogger(), 'MyComponent');\r\n * }\r\n *\r\n * // You can use:\r\n * const logger = createComponentLogger('MyComponent');\r\n *\r\n * // Or for lazy initialization:\r\n * const getLogger = () => createComponentLogger('MyComponent');\r\n * ```\r\n */\r\nexport function createComponentLogger(componentName: string): ILogger {\r\n return createScopedLogger(getGlobalLogger(), componentName);\r\n}\r\n"]}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Logging interface for docXMLater\n * Allows library consumers to control logging behavior\n */\n\n/**\n * Log severity levels\n */\nexport enum LogLevel {\n /** Debugging information (most verbose) */\n DEBUG = 'debug',\n /** Informational messages */\n INFO = 'info',\n /** Warning messages - potential issues that don't prevent operation */\n WARN = 'warn',\n /** Error messages - serious issues that may cause failures */\n ERROR = 'error',\n}\n\n/**\n * Log entry structure\n */\nexport interface LogEntry {\n /** Timestamp when log was created */\n timestamp: Date;\n /** Severity level */\n level: LogLevel;\n /** Log message */\n message: string;\n /** Optional context data */\n context?: Record<string, any>;\n /** Source component that generated the log */\n source?: string;\n}\n\n/**\n * Logger interface that consumers can implement\n * Provides full control over how logs are handled\n */\nexport interface ILogger {\n /**\n * Log a debug message\n * @param message - Debug message\n * @param context - Optional context data\n */\n debug(message: string, context?: Record<string, any>): void;\n\n /**\n * Log an informational message\n * @param message - Info message\n * @param context - Optional context data\n */\n info(message: string, context?: Record<string, any>): void;\n\n /**\n * Log a warning message\n * @param message - Warning message\n * @param context - Optional context data\n */\n warn(message: string, context?: Record<string, any>): void;\n\n /**\n * Log an error message\n * @param message - Error message\n * @param context - Optional context data\n */\n error(message: string, context?: Record<string, any>): void;\n}\n\n/**\n * Console-based logger implementation\n * Uses standard console methods for output with timestamps and source prefixes\n */\nexport class ConsoleLogger implements ILogger {\n private showTimestamp: boolean;\n\n constructor(\n private minLevel: LogLevel = LogLevel.WARN,\n options?: { showTimestamp?: boolean }\n ) {\n this.showTimestamp = options?.showTimestamp ?? true;\n }\n\n debug(message: string, context?: Record<string, any>): void {\n if (this.shouldLog(LogLevel.DEBUG)) {\n console.debug(this.formatMessage(LogLevel.DEBUG, message, context));\n }\n }\n\n info(message: string, context?: Record<string, any>): void {\n if (this.shouldLog(LogLevel.INFO)) {\n console.info(this.formatMessage(LogLevel.INFO, message, context));\n }\n }\n\n warn(message: string, context?: Record<string, any>): void {\n if (this.shouldLog(LogLevel.WARN)) {\n console.warn(this.formatMessage(LogLevel.WARN, message, context));\n }\n }\n\n error(message: string, context?: Record<string, any>): void {\n if (this.shouldLog(LogLevel.ERROR)) {\n console.error(this.formatMessage(LogLevel.ERROR, message, context));\n }\n }\n\n private shouldLog(level: LogLevel): boolean {\n const levels = [LogLevel.DEBUG, LogLevel.INFO, LogLevel.WARN, LogLevel.ERROR];\n const minIndex = levels.indexOf(this.minLevel);\n const currentIndex = levels.indexOf(level);\n return currentIndex >= minIndex;\n }\n\n private formatMessage(level: LogLevel, message: string, context?: Record<string, any>): string {\n const parts: string[] = [];\n\n // Add timestamp if enabled\n if (this.showTimestamp) {\n const timestamp = new Date().toISOString().slice(11, 23); // HH:mm:ss.SSS\n parts.push(timestamp);\n }\n\n // Add level tag\n parts.push(`[${level.toUpperCase().padEnd(5)}]`);\n\n // Add source if present\n if (context?.source) {\n parts.push(`[${context.source}]`);\n }\n\n // Add message\n parts.push(message);\n\n // Add context (excluding source which is already shown)\n if (context && Object.keys(context).length > 0) {\n const contextWithoutSource = { ...context };\n delete contextWithoutSource.source;\n if (Object.keys(contextWithoutSource).length > 0) {\n // Format context as key=value pairs for readability\n const contextStr = this.formatContext(contextWithoutSource);\n if (contextStr) {\n parts.push(contextStr);\n }\n }\n }\n\n return parts.join(' ');\n }\n\n private formatContext(context: Record<string, any>): string {\n const pairs: string[] = [];\n for (const [key, value] of Object.entries(context)) {\n if (value === undefined || value === null) continue;\n if (typeof value === 'object' && !Array.isArray(value)) {\n // Nested object - use compact JSON\n pairs.push(`${key}=${JSON.stringify(value)}`);\n } else if (Array.isArray(value)) {\n pairs.push(`${key}=[${value.length}]`);\n } else {\n pairs.push(`${key}=${value}`);\n }\n }\n return pairs.length > 0 ? pairs.join(' ') : '';\n }\n}\n\n/**\n * Silent logger that discards all log messages\n * Useful for testing or when logging is not desired\n */\nexport class SilentLogger implements ILogger {\n debug(): void {\n // No-op\n }\n\n info(): void {\n // No-op\n }\n\n warn(): void {\n // No-op\n }\n\n error(): void {\n // No-op\n }\n}\n\n/**\n * Collecting logger that stores log entries in memory\n * Useful for testing and diagnostics\n */\nexport class CollectingLogger implements ILogger {\n private logs: LogEntry[] = [];\n\n debug(message: string, context?: Record<string, any>): void {\n this.addLog(LogLevel.DEBUG, message, context);\n }\n\n info(message: string, context?: Record<string, any>): void {\n this.addLog(LogLevel.INFO, message, context);\n }\n\n warn(message: string, context?: Record<string, any>): void {\n this.addLog(LogLevel.WARN, message, context);\n }\n\n error(message: string, context?: Record<string, any>): void {\n this.addLog(LogLevel.ERROR, message, context);\n }\n\n private addLog(level: LogLevel, message: string, context?: Record<string, any>): void {\n this.logs.push({\n timestamp: new Date(),\n level,\n message,\n context,\n });\n }\n\n /**\n * Get all collected log entries\n */\n getLogs(): readonly LogEntry[] {\n return [...this.logs];\n }\n\n /**\n * Get logs filtered by level\n */\n getLogsByLevel(level: LogLevel): readonly LogEntry[] {\n return this.logs.filter((log) => log.level === level);\n }\n\n /**\n * Clear all collected logs\n */\n clear(): void {\n this.logs = [];\n }\n\n /**\n * Get count of logs by level\n */\n getCount(level?: LogLevel): number {\n if (level) {\n return this.logs.filter((log) => log.level === level).length;\n }\n return this.logs.length;\n }\n}\n\n/**\n * Default logger instance\n * Delegates to the global logger, respecting setGlobalLogger() and environment variables\n */\nexport const defaultLogger: ILogger = {\n debug(message: string, context?: Record<string, any>): void {\n getGlobalLogger().debug(message, context);\n },\n info(message: string, context?: Record<string, any>): void {\n getGlobalLogger().info(message, context);\n },\n warn(message: string, context?: Record<string, any>): void {\n getGlobalLogger().warn(message, context);\n },\n error(message: string, context?: Record<string, any>): void {\n getGlobalLogger().error(message, context);\n },\n};\n\n/**\n * Creates a scoped logger that adds source information\n * @param logger - Base logger\n * @param source - Source component name\n * @returns Scoped logger with source context\n */\nexport function createScopedLogger(logger: ILogger, source: string): ILogger {\n return {\n debug(message: string, context?: Record<string, any>): void {\n logger.debug(message, { ...context, source });\n },\n info(message: string, context?: Record<string, any>): void {\n logger.info(message, { ...context, source });\n },\n warn(message: string, context?: Record<string, any>): void {\n logger.warn(message, { ...context, source });\n },\n error(message: string, context?: Record<string, any>): void {\n logger.error(message, { ...context, source });\n },\n };\n}\n\n/**\n * Parse log level from string\n * @param level - Log level string (case-insensitive)\n * @returns LogLevel or undefined if invalid\n */\nfunction parseLogLevel(level: string | undefined): LogLevel | undefined {\n if (!level) return undefined;\n const normalized = level.toLowerCase();\n switch (normalized) {\n case 'debug':\n return LogLevel.DEBUG;\n case 'info':\n return LogLevel.INFO;\n case 'warn':\n return LogLevel.WARN;\n case 'error':\n return LogLevel.ERROR;\n default:\n return undefined;\n }\n}\n\n/**\n * Create a logger based on environment variables\n *\n * Environment variables (in order of precedence):\n * - DEBUG=docxmlater or DEBUG=docxmlater:* - Enables DEBUG level\n * - DOCXMLATER_LOG_LEVEL=debug|info|warn|error|silent - Sets specific level\n *\n * @returns Logger configured from environment, or SilentLogger if not configured\n */\nfunction createLoggerFromEnv(): ILogger {\n // Check DEBUG environment variable first (highest precedence for debug mode)\n const debugEnv = process.env.DEBUG || '';\n if (debugEnv.includes('docxmlater')) {\n return new ConsoleLogger(LogLevel.DEBUG);\n }\n\n // Check DOCXMLATER_LOG_LEVEL environment variable\n const envLevel = process.env.DOCXMLATER_LOG_LEVEL?.toLowerCase();\n if (envLevel === 'silent') {\n return new SilentLogger();\n }\n\n const parsedLevel = parseLogLevel(envLevel);\n if (parsedLevel) {\n return new ConsoleLogger(parsedLevel);\n }\n\n // Default: silent (no logging unless explicitly enabled)\n return new SilentLogger();\n}\n\n// Global logger instance - initialized from environment\nlet globalLogger: ILogger = createLoggerFromEnv();\n\n/**\n * Set the global logger instance\n * Use this to configure logging programmatically\n *\n * @example\n * ```typescript\n * import { setGlobalLogger, ConsoleLogger, LogLevel } from 'docxmlater';\n *\n * // Enable info-level logging\n * setGlobalLogger(new ConsoleLogger(LogLevel.INFO));\n * ```\n *\n * @param logger - Logger instance to use globally\n */\nexport function setGlobalLogger(logger: ILogger): void {\n globalLogger = logger;\n}\n\n/**\n * Get the global logger instance\n * Used internally by framework components\n *\n * @returns Current global logger\n */\nexport function getGlobalLogger(): ILogger {\n return globalLogger;\n}\n\n/**\n * Reset the global logger to its default (environment-based) configuration\n * Useful for testing cleanup\n */\nexport function resetGlobalLogger(): void {\n globalLogger = createLoggerFromEnv();\n}\n\n/**\n * Creates a component-scoped logger using the global logger.\n * This is a convenience function that combines getGlobalLogger() and createScopedLogger()\n * into a single call, reducing boilerplate in component files.\n *\n * @param componentName - Name of the component (appears in log output)\n * @returns Scoped logger instance\n *\n * @example\n * ```typescript\n * // Instead of:\n * function getLogger(): ILogger {\n * return createScopedLogger(getGlobalLogger(), 'MyComponent');\n * }\n *\n * // You can use:\n * const logger = createComponentLogger('MyComponent');\n *\n * // Or for lazy initialization:\n * const getLogger = () => createComponentLogger('MyComponent');\n * ```\n */\nexport function createComponentLogger(componentName: string): ILogger {\n return createScopedLogger(getGlobalLogger(), componentName);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"parsingHelpers.js","sourceRoot":"","sources":["../../src/utils/parsingHelpers.ts"],"names":[],"mappings":";;AA4BA,oCAYC;AA+BD,8CAiCC;AA0BD,0CAEC;AAkBD,sDAKC;AAeD,kDAmBC;AAjKD,SAAgB,YAAY,CAAC,KAAc,EAAE,YAAY,GAAG,CAAC;IAC3D,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,YAAY,CAAC;IACtB,CAAC;IAGD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IAC3C,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC;AAC/C,CAAC;AA+BD,SAAgB,iBAAiB,CAAC,IAAa;IAE7C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,KAAK,CAAC;IACf,CAAC;IAGD,MAAM,GAAG,GAAI,IAAgC,CAAC,SAAS,CAAC,CAAC;IAIzD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAGD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QACnC,OAAO,QAAQ,KAAK,GAAG,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,IAAI,CAAC;IACtE,CAAC;IAGD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,GAAG,KAAK,CAAC,CAAC;IACnB,CAAC;IAGD,IAAI,OAAO,GAAG,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,GAAG,CAAC;IACb,CAAC;IAGD,OAAO,KAAK,CAAC;AACf,CAAC;AA0BD,SAAgB,eAAe,CAAC,KAAc;IAC5C,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC;AAC/C,CAAC;AAkBD,SAAgB,qBAAqB,CAAC,KAAc,EAAE,YAAoB;IACxE,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;AAC3C,CAAC;AAeD,SAAgB,mBAAmB,CAAC,KAAc,EAAE,YAAY,GAAG,KAAK;IACtE,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QACrC,OAAO,QAAQ,KAAK,GAAG,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,IAAI,CAAC;IACtE,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,KAAK,CAAC,CAAC;IACrB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC","sourcesContent":["/**\r\n * Parsing Helper Functions\r\n *\r\n * Utility functions for safely parsing OOXML values from XML attributes.\r\n * These helpers address common parsing issues:\r\n * - Zero-value handling (0 should not be treated as falsy)\r\n * - NaN validation (malformed values should fall back to defaults)\r\n * - ECMA-376 boolean parsing (self-closing tags, val=\"1\", val=\"true\")\r\n *\r\n * @see https://ecma-international.org/publications-and-standards/standards/ecma-376/\r\n */\r\n\r\n/**\r\n * Safely parse an integer value with NaN handling.\r\n *\r\n * Addresses the issue where parseInt() can return NaN for malformed input,\r\n * which then propagates through the document model causing issues.\r\n *\r\n * @param value - The value to parse (string, number, or any)\r\n * @param defaultValue - Default value if parsing fails (default: 0)\r\n * @returns Parsed integer or default value\r\n *\r\n * @example\r\n * safeParseInt(\"42\") // 42\r\n * safeParseInt(\"invalid\") // 0\r\n * safeParseInt(undefined) // 0\r\n * safeParseInt(\"\", 100) // 100\r\n */\r\nexport function safeParseInt(value: unknown, defaultValue = 0): number {\r\n if (value === undefined || value === null) {\r\n return defaultValue;\r\n }\r\n\r\n // If already a number, return it (handle NaN case)\r\n if (typeof value === 'number') {\r\n return isNaN(value) ? defaultValue : Math.floor(value);\r\n }\r\n\r\n const parsed = parseInt(String(value), 10);\r\n return isNaN(parsed) ? defaultValue : parsed;\r\n}\r\n\r\n/**\r\n * Parse OOXML boolean value per ECMA-376 specification.\r\n *\r\n * OOXML boolean properties follow these rules:\r\n * - Self-closing tag `<w:bold/>` (no w:val attribute) = true\r\n * - `<w:bold w:val=\"1\"/>` = true\r\n * - `<w:bold w:val=\"true\"/>` = true\r\n * - `<w:bold w:val=\"on\"/>` = true\r\n * - `<w:bold w:val=\"0\"/>` = false\r\n * - `<w:bold w:val=\"false\"/>` = false\r\n * - `<w:bold w:val=\"off\"/>` = false\r\n * - Absent element = false (handled by caller checking for property existence)\r\n *\r\n * @param prop - The parsed XML property object (e.g., pPrObj[\"w:bold\"])\r\n * @returns Boolean value\r\n *\r\n * @example\r\n * // For XML: <w:bold/>\r\n * parseOoxmlBoolean({}) // true (self-closing, no @_w:val)\r\n *\r\n * // For XML: <w:bold w:val=\"1\"/>\r\n * parseOoxmlBoolean({ \"@_w:val\": \"1\" }) // true\r\n *\r\n * // For XML: <w:bold w:val=\"0\"/>\r\n * parseOoxmlBoolean({ \"@_w:val\": \"0\" }) // false\r\n *\r\n * // For absent element\r\n * parseOoxmlBoolean(undefined) // false\r\n */\r\nexport function parseOoxmlBoolean(prop: unknown): boolean {\r\n // Absent element = false\r\n if (!prop) {\r\n return false;\r\n }\r\n\r\n // Get the w:val attribute value\r\n const val = (prop as Record<string, unknown>)['@_w:val'];\r\n\r\n // Self-closing tag without w:val attribute = true\r\n // Per ECMA-376, presence of element without val means \"on\"\r\n if (val === undefined) {\r\n return true;\r\n }\r\n\r\n // Handle string values\r\n if (typeof val === 'string') {\r\n const lowerVal = val.toLowerCase();\r\n return lowerVal === '1' || lowerVal === 'true' || lowerVal === 'on';\r\n }\r\n\r\n // Handle numeric values\r\n if (typeof val === 'number') {\r\n return val === 1;\r\n }\r\n\r\n // Handle boolean values (already parsed by XML parser)\r\n if (typeof val === 'boolean') {\r\n return val;\r\n }\r\n\r\n // Unknown type - default to false\r\n return false;\r\n}\r\n\r\n/**\r\n * Check if a value is explicitly set (not undefined or null).\r\n *\r\n * This helper addresses the zero-value handling bug where truthy checks\r\n * incorrectly treat 0 as falsy:\r\n *\r\n * ```typescript\r\n * // WRONG - treats 0 as falsy\r\n * const width = val ? parseInt(val) : defaultWidth;\r\n *\r\n * // CORRECT - only checks for undefined/null\r\n * const width = isExplicitlySet(val) ? parseInt(val) : defaultWidth;\r\n * ```\r\n *\r\n * @param value - The value to check\r\n * @returns true if value is not undefined and not null\r\n *\r\n * @example\r\n * isExplicitlySet(0) // true\r\n * isExplicitlySet(\"\") // true\r\n * isExplicitlySet(false) // true\r\n * isExplicitlySet(undefined) // false\r\n * isExplicitlySet(null) // false\r\n */\r\nexport function isExplicitlySet(value: unknown): boolean {\r\n return value !== undefined && value !== null;\r\n}\r\n\r\n/**\r\n * Parse an OOXML numeric attribute with proper handling of zero values.\r\n *\r\n * Combines isExplicitlySet() and safeParseInt() for common use case\r\n * of parsing numeric attributes from XML.\r\n *\r\n * @param value - The attribute value to parse\r\n * @param defaultValue - Default value if attribute is not set\r\n * @returns Parsed integer or default value\r\n *\r\n * @example\r\n * parseNumericAttribute(\"100\", 50) // 100\r\n * parseNumericAttribute(\"0\", 50) // 0 (not 50!)\r\n * parseNumericAttribute(undefined, 50) // 50\r\n * parseNumericAttribute(\"invalid\", 50) // 50\r\n */\r\nexport function parseNumericAttribute(value: unknown, defaultValue: number): number {\r\n if (!isExplicitlySet(value)) {\r\n return defaultValue;\r\n }\r\n return safeParseInt(value, defaultValue);\r\n}\r\n\r\n/**\r\n * Parse OOXML \"on/off\" attribute (ST_OnOff type).\r\n *\r\n * Some OOXML attributes use the ST_OnOff simple type which can be:\r\n * - \"on\", \"1\", \"true\" = true\r\n * - \"off\", \"0\", \"false\" = false\r\n *\r\n * This is similar to parseOoxmlBoolean but works on attribute values directly.\r\n *\r\n * @param value - The attribute value\r\n * @param defaultValue - Default if value is not set\r\n * @returns Boolean value\r\n */\r\nexport function parseOnOffAttribute(value: unknown, defaultValue = false): boolean {\r\n if (!isExplicitlySet(value)) {\r\n return defaultValue;\r\n }\r\n\r\n if (typeof value === 'string') {\r\n const lowerVal = value.toLowerCase();\r\n return lowerVal === '1' || lowerVal === 'true' || lowerVal === 'on';\r\n }\r\n\r\n if (typeof value === 'number') {\r\n return value === 1;\r\n }\r\n\r\n if (typeof value === 'boolean') {\r\n return value;\r\n }\r\n\r\n return defaultValue;\r\n}\r\n"]}
1
+ {"version":3,"file":"parsingHelpers.js","sourceRoot":"","sources":["../../src/utils/parsingHelpers.ts"],"names":[],"mappings":";;AA4BA,oCAYC;AA+BD,8CAiCC;AA0BD,0CAEC;AAkBD,sDAKC;AAeD,kDAmBC;AAjKD,SAAgB,YAAY,CAAC,KAAc,EAAE,YAAY,GAAG,CAAC;IAC3D,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,YAAY,CAAC;IACtB,CAAC;IAGD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IAC3C,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC;AAC/C,CAAC;AA+BD,SAAgB,iBAAiB,CAAC,IAAa;IAE7C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,KAAK,CAAC;IACf,CAAC;IAGD,MAAM,GAAG,GAAI,IAAgC,CAAC,SAAS,CAAC,CAAC;IAIzD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAGD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QACnC,OAAO,QAAQ,KAAK,GAAG,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,IAAI,CAAC;IACtE,CAAC;IAGD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,GAAG,KAAK,CAAC,CAAC;IACnB,CAAC;IAGD,IAAI,OAAO,GAAG,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,GAAG,CAAC;IACb,CAAC;IAGD,OAAO,KAAK,CAAC;AACf,CAAC;AA0BD,SAAgB,eAAe,CAAC,KAAc;IAC5C,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC;AAC/C,CAAC;AAkBD,SAAgB,qBAAqB,CAAC,KAAc,EAAE,YAAoB;IACxE,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;AAC3C,CAAC;AAeD,SAAgB,mBAAmB,CAAC,KAAc,EAAE,YAAY,GAAG,KAAK;IACtE,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QACrC,OAAO,QAAQ,KAAK,GAAG,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,IAAI,CAAC;IACtE,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,KAAK,CAAC,CAAC;IACrB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC","sourcesContent":["/**\n * Parsing Helper Functions\n *\n * Utility functions for safely parsing OOXML values from XML attributes.\n * These helpers address common parsing issues:\n * - Zero-value handling (0 should not be treated as falsy)\n * - NaN validation (malformed values should fall back to defaults)\n * - ECMA-376 boolean parsing (self-closing tags, val=\"1\", val=\"true\")\n *\n * @see https://ecma-international.org/publications-and-standards/standards/ecma-376/\n */\n\n/**\n * Safely parse an integer value with NaN handling.\n *\n * Addresses the issue where parseInt() can return NaN for malformed input,\n * which then propagates through the document model causing issues.\n *\n * @param value - The value to parse (string, number, or any)\n * @param defaultValue - Default value if parsing fails (default: 0)\n * @returns Parsed integer or default value\n *\n * @example\n * safeParseInt(\"42\") // 42\n * safeParseInt(\"invalid\") // 0\n * safeParseInt(undefined) // 0\n * safeParseInt(\"\", 100) // 100\n */\nexport function safeParseInt(value: unknown, defaultValue = 0): number {\n if (value === undefined || value === null) {\n return defaultValue;\n }\n\n // If already a number, return it (handle NaN case)\n if (typeof value === 'number') {\n return isNaN(value) ? defaultValue : Math.floor(value);\n }\n\n const parsed = parseInt(String(value), 10);\n return isNaN(parsed) ? defaultValue : parsed;\n}\n\n/**\n * Parse OOXML boolean value per ECMA-376 specification.\n *\n * OOXML boolean properties follow these rules:\n * - Self-closing tag `<w:bold/>` (no w:val attribute) = true\n * - `<w:bold w:val=\"1\"/>` = true\n * - `<w:bold w:val=\"true\"/>` = true\n * - `<w:bold w:val=\"on\"/>` = true\n * - `<w:bold w:val=\"0\"/>` = false\n * - `<w:bold w:val=\"false\"/>` = false\n * - `<w:bold w:val=\"off\"/>` = false\n * - Absent element = false (handled by caller checking for property existence)\n *\n * @param prop - The parsed XML property object (e.g., pPrObj[\"w:bold\"])\n * @returns Boolean value\n *\n * @example\n * // For XML: <w:bold/>\n * parseOoxmlBoolean({}) // true (self-closing, no @_w:val)\n *\n * // For XML: <w:bold w:val=\"1\"/>\n * parseOoxmlBoolean({ \"@_w:val\": \"1\" }) // true\n *\n * // For XML: <w:bold w:val=\"0\"/>\n * parseOoxmlBoolean({ \"@_w:val\": \"0\" }) // false\n *\n * // For absent element\n * parseOoxmlBoolean(undefined) // false\n */\nexport function parseOoxmlBoolean(prop: unknown): boolean {\n // Absent element = false\n if (!prop) {\n return false;\n }\n\n // Get the w:val attribute value\n const val = (prop as Record<string, unknown>)['@_w:val'];\n\n // Self-closing tag without w:val attribute = true\n // Per ECMA-376, presence of element without val means \"on\"\n if (val === undefined) {\n return true;\n }\n\n // Handle string values\n if (typeof val === 'string') {\n const lowerVal = val.toLowerCase();\n return lowerVal === '1' || lowerVal === 'true' || lowerVal === 'on';\n }\n\n // Handle numeric values\n if (typeof val === 'number') {\n return val === 1;\n }\n\n // Handle boolean values (already parsed by XML parser)\n if (typeof val === 'boolean') {\n return val;\n }\n\n // Unknown type - default to false\n return false;\n}\n\n/**\n * Check if a value is explicitly set (not undefined or null).\n *\n * This helper addresses the zero-value handling bug where truthy checks\n * incorrectly treat 0 as falsy:\n *\n * ```typescript\n * // WRONG - treats 0 as falsy\n * const width = val ? parseInt(val) : defaultWidth;\n *\n * // CORRECT - only checks for undefined/null\n * const width = isExplicitlySet(val) ? parseInt(val) : defaultWidth;\n * ```\n *\n * @param value - The value to check\n * @returns true if value is not undefined and not null\n *\n * @example\n * isExplicitlySet(0) // true\n * isExplicitlySet(\"\") // true\n * isExplicitlySet(false) // true\n * isExplicitlySet(undefined) // false\n * isExplicitlySet(null) // false\n */\nexport function isExplicitlySet(value: unknown): boolean {\n return value !== undefined && value !== null;\n}\n\n/**\n * Parse an OOXML numeric attribute with proper handling of zero values.\n *\n * Combines isExplicitlySet() and safeParseInt() for common use case\n * of parsing numeric attributes from XML.\n *\n * @param value - The attribute value to parse\n * @param defaultValue - Default value if attribute is not set\n * @returns Parsed integer or default value\n *\n * @example\n * parseNumericAttribute(\"100\", 50) // 100\n * parseNumericAttribute(\"0\", 50) // 0 (not 50!)\n * parseNumericAttribute(undefined, 50) // 50\n * parseNumericAttribute(\"invalid\", 50) // 50\n */\nexport function parseNumericAttribute(value: unknown, defaultValue: number): number {\n if (!isExplicitlySet(value)) {\n return defaultValue;\n }\n return safeParseInt(value, defaultValue);\n}\n\n/**\n * Parse OOXML \"on/off\" attribute (ST_OnOff type).\n *\n * Some OOXML attributes use the ST_OnOff simple type which can be:\n * - \"on\", \"1\", \"true\" = true\n * - \"off\", \"0\", \"false\" = false\n *\n * This is similar to parseOoxmlBoolean but works on attribute values directly.\n *\n * @param value - The attribute value\n * @param defaultValue - Default if value is not set\n * @returns Boolean value\n */\nexport function parseOnOffAttribute(value: unknown, defaultValue = false): boolean {\n if (!isExplicitlySet(value)) {\n return defaultValue;\n }\n\n if (typeof value === 'string') {\n const lowerVal = value.toLowerCase();\n return lowerVal === '1' || lowerVal === 'true' || lowerVal === 'on';\n }\n\n if (typeof value === 'number') {\n return value === 1;\n }\n\n if (typeof value === 'boolean') {\n return value;\n }\n\n return defaultValue;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"stripTrackedChanges.d.ts","sourceRoot":"","sources":["../../src/utils/stripTrackedChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AA6V/C,wBAAsB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/E"}
1
+ {"version":3,"file":"stripTrackedChanges.d.ts","sourceRoot":"","sources":["../../src/utils/stripTrackedChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAgW/C,wBAAsB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/E"}
@@ -40,7 +40,7 @@ class TrackedChangesStripper {
40
40
  /<w:customXmlMoveFromRangeStart[^>]*\/>/g,
41
41
  /<w:customXmlMoveFromRangeEnd[^>]*\/>/g,
42
42
  /<w:customXmlMoveToRangeStart[^>]*\/>/g,
43
- /<w:customXmlMoveToRangeEnd[^>]*\/>/g
43
+ /<w:customXmlMoveToRangeEnd[^>]*\/>/g,
44
44
  ];
45
45
  let result = xml;
46
46
  for (const pattern of patterns) {
@@ -102,7 +102,7 @@ class TrackedChangesStripper {
102
102
  /<w:trPrChange[^>]*>.*?<\/w:trPrChange>/gs,
103
103
  /<w:sectPrChange[^>]*>.*?<\/w:sectPrChange>/gs,
104
104
  /<w:tblGridChange[^>]*>.*?<\/w:tblGridChange>/gs,
105
- /<w:numberingChange[^>]*>.*?<\/w:numberingChange>/gs
105
+ /<w:numberingChange[^>]*>.*?<\/w:numberingChange>/gs,
106
106
  ];
107
107
  let result = xml;
108
108
  for (const pattern of patterns) {
@@ -115,7 +115,7 @@ class TrackedChangesStripper {
115
115
  /<w:ins\s+[^>]*\/>/g,
116
116
  /<w:del\s+[^>]*\/>/g,
117
117
  /<w:moveFrom\s+[^>]*\/>/g,
118
- /<w:moveTo\s+[^>]*\/>/g
118
+ /<w:moveTo\s+[^>]*\/>/g,
119
119
  ];
120
120
  let result = xml;
121
121
  for (const pattern of patterns) {