docxmlater 10.4.1 → 11.0.4
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.
- package/README.md +3 -3
- package/dist/constants/legacyCompatFlags.d.ts +1 -1
- package/dist/constants/legacyCompatFlags.d.ts.map +1 -1
- package/dist/constants/legacyCompatFlags.js.map +1 -1
- package/dist/core/Document.d.ts +74 -67
- package/dist/core/Document.d.ts.map +1 -1
- package/dist/core/Document.js +605 -414
- package/dist/core/Document.js.map +1 -1
- package/dist/core/DocumentContent.d.ts +11 -10
- package/dist/core/DocumentContent.d.ts.map +1 -1
- package/dist/core/DocumentContent.js +19 -19
- package/dist/core/DocumentContent.js.map +1 -1
- package/dist/core/DocumentEvents.d.ts +39 -0
- package/dist/core/DocumentEvents.d.ts.map +1 -0
- package/dist/core/DocumentEvents.js +51 -0
- package/dist/core/DocumentEvents.js.map +1 -0
- package/dist/core/DocumentGenerator.d.ts +11 -11
- package/dist/core/DocumentGenerator.d.ts.map +1 -1
- package/dist/core/DocumentGenerator.js +72 -52
- package/dist/core/DocumentGenerator.js.map +1 -1
- package/dist/core/DocumentParser.d.ts +15 -15
- package/dist/core/DocumentParser.d.ts.map +1 -1
- package/dist/core/DocumentParser.js +2056 -1073
- package/dist/core/DocumentParser.js.map +1 -1
- package/dist/core/DocumentValidator.d.ts +3 -3
- package/dist/core/DocumentValidator.d.ts.map +1 -1
- package/dist/core/DocumentValidator.js +31 -31
- package/dist/core/DocumentValidator.js.map +1 -1
- package/dist/core/ElementRegistry.d.ts +22 -0
- package/dist/core/ElementRegistry.d.ts.map +1 -0
- package/dist/core/ElementRegistry.js +27 -0
- package/dist/core/ElementRegistry.js.map +1 -0
- package/dist/core/Relationship.js +4 -4
- package/dist/core/Relationship.js.map +1 -1
- package/dist/core/RelationshipManager.d.ts +1 -1
- package/dist/core/RelationshipManager.d.ts.map +1 -1
- package/dist/core/RelationshipManager.js +32 -32
- package/dist/core/RelationshipManager.js.map +1 -1
- package/dist/elements/AlternateContent.d.ts +1 -1
- package/dist/elements/AlternateContent.d.ts.map +1 -1
- package/dist/elements/AlternateContent.js.map +1 -1
- package/dist/elements/Bookmark.d.ts +6 -1
- package/dist/elements/Bookmark.d.ts.map +1 -1
- package/dist/elements/Bookmark.js +19 -3
- package/dist/elements/Bookmark.js.map +1 -1
- package/dist/elements/BookmarkManager.d.ts +1 -1
- package/dist/elements/BookmarkManager.d.ts.map +1 -1
- package/dist/elements/BookmarkManager.js +7 -7
- package/dist/elements/BookmarkManager.js.map +1 -1
- package/dist/elements/Comment.d.ts +2 -2
- package/dist/elements/Comment.d.ts.map +1 -1
- package/dist/elements/Comment.js +4 -4
- package/dist/elements/Comment.js.map +1 -1
- package/dist/elements/CommentManager.d.ts +2 -2
- package/dist/elements/CommentManager.d.ts.map +1 -1
- package/dist/elements/CommentManager.js +9 -9
- package/dist/elements/CommentManager.js.map +1 -1
- package/dist/elements/CommonTypes.d.ts +9 -4
- package/dist/elements/CommonTypes.d.ts.map +1 -1
- package/dist/elements/CommonTypes.js +1 -0
- package/dist/elements/CommonTypes.js.map +1 -1
- package/dist/elements/CustomXml.d.ts +1 -1
- package/dist/elements/CustomXml.d.ts.map +1 -1
- package/dist/elements/CustomXml.js.map +1 -1
- package/dist/elements/Endnote.d.ts +2 -2
- package/dist/elements/Endnote.d.ts.map +1 -1
- package/dist/elements/Endnote.js +9 -9
- package/dist/elements/Endnote.js.map +1 -1
- package/dist/elements/EndnoteManager.d.ts +1 -1
- package/dist/elements/EndnoteManager.d.ts.map +1 -1
- package/dist/elements/EndnoteManager.js +11 -11
- package/dist/elements/EndnoteManager.js.map +1 -1
- package/dist/elements/Field.d.ts +9 -5
- package/dist/elements/Field.d.ts.map +1 -1
- package/dist/elements/Field.js +21 -9
- package/dist/elements/Field.js.map +1 -1
- package/dist/elements/FieldHelpers.d.ts +1 -1
- package/dist/elements/FieldHelpers.d.ts.map +1 -1
- package/dist/elements/FieldHelpers.js +10 -10
- package/dist/elements/FieldHelpers.js.map +1 -1
- package/dist/elements/Footer.d.ts +3 -3
- package/dist/elements/Footer.d.ts.map +1 -1
- package/dist/elements/Footer.js +5 -5
- package/dist/elements/Footer.js.map +1 -1
- package/dist/elements/Footnote.d.ts +2 -2
- package/dist/elements/Footnote.d.ts.map +1 -1
- package/dist/elements/Footnote.js +9 -9
- package/dist/elements/Footnote.js.map +1 -1
- package/dist/elements/FootnoteManager.d.ts +1 -1
- package/dist/elements/FootnoteManager.d.ts.map +1 -1
- package/dist/elements/FootnoteManager.js +11 -11
- package/dist/elements/FootnoteManager.js.map +1 -1
- package/dist/elements/Header.d.ts +3 -3
- package/dist/elements/Header.d.ts.map +1 -1
- package/dist/elements/Header.js +5 -5
- package/dist/elements/Header.js.map +1 -1
- package/dist/elements/HeaderFooterManager.d.ts +2 -2
- package/dist/elements/HeaderFooterManager.d.ts.map +1 -1
- package/dist/elements/HeaderFooterManager.js.map +1 -1
- package/dist/elements/Hyperlink.d.ts +5 -5
- package/dist/elements/Hyperlink.d.ts.map +1 -1
- package/dist/elements/Hyperlink.js +29 -29
- package/dist/elements/Hyperlink.js.map +1 -1
- package/dist/elements/Image.d.ts +1 -1
- package/dist/elements/Image.d.ts.map +1 -1
- package/dist/elements/Image.js +67 -67
- package/dist/elements/Image.js.map +1 -1
- package/dist/elements/ImageManager.d.ts +1 -1
- package/dist/elements/ImageManager.d.ts.map +1 -1
- package/dist/elements/ImageManager.js +4 -4
- package/dist/elements/ImageManager.js.map +1 -1
- package/dist/elements/ImageRun.d.ts +3 -3
- package/dist/elements/ImageRun.d.ts.map +1 -1
- package/dist/elements/ImageRun.js +2 -2
- package/dist/elements/ImageRun.js.map +1 -1
- package/dist/elements/MathElement.d.ts +1 -1
- package/dist/elements/MathElement.d.ts.map +1 -1
- package/dist/elements/MathElement.js.map +1 -1
- package/dist/elements/Paragraph.d.ts +34 -19
- package/dist/elements/Paragraph.d.ts.map +1 -1
- package/dist/elements/Paragraph.js +286 -231
- package/dist/elements/Paragraph.js.map +1 -1
- package/dist/elements/PreservedElement.d.ts +1 -1
- package/dist/elements/PreservedElement.d.ts.map +1 -1
- package/dist/elements/PreservedElement.js.map +1 -1
- package/dist/elements/PropertyChangeTypes.d.ts +2 -2
- package/dist/elements/PropertyChangeTypes.d.ts.map +1 -1
- package/dist/elements/PropertyChangeTypes.js.map +1 -1
- package/dist/elements/RangeMarker.d.ts +14 -1
- package/dist/elements/RangeMarker.d.ts.map +1 -1
- package/dist/elements/RangeMarker.js +46 -8
- package/dist/elements/RangeMarker.js.map +1 -1
- package/dist/elements/RegisteredBodyElement.d.ts +15 -0
- package/dist/elements/RegisteredBodyElement.d.ts.map +1 -0
- package/dist/elements/RegisteredBodyElement.js +44 -0
- package/dist/elements/RegisteredBodyElement.js.map +1 -0
- package/dist/elements/Revision.d.ts +8 -8
- package/dist/elements/Revision.d.ts.map +1 -1
- package/dist/elements/Revision.js +12 -12
- package/dist/elements/Revision.js.map +1 -1
- package/dist/elements/RevisionContent.d.ts +3 -3
- package/dist/elements/RevisionContent.d.ts.map +1 -1
- package/dist/elements/RevisionContent.js.map +1 -1
- package/dist/elements/RevisionManager.d.ts +2 -2
- package/dist/elements/RevisionManager.d.ts.map +1 -1
- package/dist/elements/RevisionManager.js +2 -2
- package/dist/elements/RevisionManager.js.map +1 -1
- package/dist/elements/Run.d.ts +16 -10
- package/dist/elements/Run.d.ts.map +1 -1
- package/dist/elements/Run.js +199 -173
- package/dist/elements/Run.js.map +1 -1
- package/dist/elements/Section.d.ts +4 -2
- package/dist/elements/Section.d.ts.map +1 -1
- package/dist/elements/Section.js +152 -145
- package/dist/elements/Section.js.map +1 -1
- package/dist/elements/Shape.d.ts +3 -3
- package/dist/elements/Shape.d.ts.map +1 -1
- package/dist/elements/Shape.js +12 -12
- package/dist/elements/Shape.js.map +1 -1
- package/dist/elements/StructuredDocumentTag.d.ts +3 -3
- package/dist/elements/StructuredDocumentTag.d.ts.map +1 -1
- package/dist/elements/StructuredDocumentTag.js +39 -39
- package/dist/elements/StructuredDocumentTag.js.map +1 -1
- package/dist/elements/Table.d.ts +16 -10
- package/dist/elements/Table.d.ts.map +1 -1
- package/dist/elements/Table.js +118 -89
- package/dist/elements/Table.js.map +1 -1
- package/dist/elements/TableCell.d.ts +11 -11
- package/dist/elements/TableCell.d.ts.map +1 -1
- package/dist/elements/TableCell.js +108 -78
- package/dist/elements/TableCell.js.map +1 -1
- package/dist/elements/TableGridChange.d.ts +1 -1
- package/dist/elements/TableGridChange.d.ts.map +1 -1
- package/dist/elements/TableGridChange.js +3 -3
- package/dist/elements/TableGridChange.js.map +1 -1
- package/dist/elements/TableOfContents.d.ts +1 -1
- package/dist/elements/TableOfContents.d.ts.map +1 -1
- package/dist/elements/TableOfContents.js +2 -2
- package/dist/elements/TableOfContents.js.map +1 -1
- package/dist/elements/TableOfContentsElement.d.ts +2 -2
- package/dist/elements/TableOfContentsElement.d.ts.map +1 -1
- package/dist/elements/TableOfContentsElement.js +5 -5
- package/dist/elements/TableOfContentsElement.js.map +1 -1
- package/dist/elements/TableRow.d.ts +18 -7
- package/dist/elements/TableRow.d.ts.map +1 -1
- package/dist/elements/TableRow.js +127 -74
- package/dist/elements/TableRow.js.map +1 -1
- package/dist/elements/TextBox.d.ts +4 -4
- package/dist/elements/TextBox.d.ts.map +1 -1
- package/dist/elements/TextBox.js +6 -6
- package/dist/elements/TextBox.js.map +1 -1
- package/dist/esm/constants/legacyCompatFlags.js +97 -0
- package/dist/esm/constants/legacyCompatFlags.js.map +1 -0
- package/dist/esm/constants/limits.js +36 -0
- package/dist/esm/constants/limits.js.map +1 -0
- package/dist/esm/core/Document.js +8498 -0
- package/dist/esm/core/Document.js.map +1 -0
- package/dist/esm/core/DocumentContent.js +190 -0
- package/dist/esm/core/DocumentContent.js.map +1 -0
- package/dist/esm/core/DocumentEvents.js +47 -0
- package/dist/esm/core/DocumentEvents.js.map +1 -0
- package/dist/esm/core/DocumentGenerator.js +764 -0
- package/dist/esm/core/DocumentGenerator.js.map +1 -0
- package/dist/esm/core/DocumentIdManager.js +67 -0
- package/dist/esm/core/DocumentIdManager.js.map +1 -0
- package/dist/esm/core/DocumentParser.js +8760 -0
- package/dist/esm/core/DocumentParser.js.map +1 -0
- package/dist/esm/core/DocumentValidator.js +222 -0
- package/dist/esm/core/DocumentValidator.js.map +1 -0
- package/dist/esm/core/ElementRegistry.js +24 -0
- package/dist/esm/core/ElementRegistry.js.map +1 -0
- package/dist/esm/core/Relationship.js +177 -0
- package/dist/esm/core/Relationship.js.map +1 -0
- package/dist/esm/core/RelationshipManager.js +202 -0
- package/dist/esm/core/RelationshipManager.js.map +1 -0
- package/dist/esm/elements/AlternateContent.js +19 -0
- package/dist/esm/elements/AlternateContent.js.map +1 -0
- package/dist/esm/elements/Bookmark.js +115 -0
- package/dist/esm/elements/Bookmark.js.map +1 -0
- package/dist/esm/elements/BookmarkManager.js +99 -0
- package/dist/esm/elements/BookmarkManager.js.map +1 -0
- package/dist/esm/elements/Comment.js +181 -0
- package/dist/esm/elements/Comment.js.map +1 -0
- package/dist/esm/elements/CommentManager.js +233 -0
- package/dist/esm/elements/CommentManager.js.map +1 -0
- package/dist/esm/elements/CommonTypes.js +106 -0
- package/dist/esm/elements/CommonTypes.js.map +1 -0
- package/dist/esm/elements/CustomXml.js +19 -0
- package/dist/esm/elements/CustomXml.js.map +1 -0
- package/dist/esm/elements/Endnote.js +107 -0
- package/dist/esm/elements/Endnote.js.map +1 -0
- package/dist/esm/elements/EndnoteManager.js +119 -0
- package/dist/esm/elements/EndnoteManager.js.map +1 -0
- package/dist/esm/elements/Field.js +856 -0
- package/dist/esm/elements/Field.js.map +1 -0
- package/dist/esm/elements/FieldHelpers.js +134 -0
- package/dist/esm/elements/FieldHelpers.js.map +1 -0
- package/dist/esm/elements/FontManager.js +158 -0
- package/dist/esm/elements/FontManager.js.map +1 -0
- package/dist/esm/elements/Footer.js +141 -0
- package/dist/esm/elements/Footer.js.map +1 -0
- package/dist/esm/elements/Footnote.js +107 -0
- package/dist/esm/elements/Footnote.js.map +1 -0
- package/dist/esm/elements/FootnoteManager.js +119 -0
- package/dist/esm/elements/FootnoteManager.js.map +1 -0
- package/dist/esm/elements/Header.js +141 -0
- package/dist/esm/elements/Header.js.map +1 -0
- package/dist/esm/elements/HeaderFooterManager.js +87 -0
- package/dist/esm/elements/HeaderFooterManager.js.map +1 -0
- package/dist/esm/elements/Hyperlink.js +586 -0
- package/dist/esm/elements/Hyperlink.js.map +1 -0
- package/dist/esm/elements/Image.js +1288 -0
- package/dist/esm/elements/Image.js.map +1 -0
- package/dist/esm/elements/ImageManager.js +223 -0
- package/dist/esm/elements/ImageManager.js.map +1 -0
- package/dist/esm/elements/ImageRun.js +29 -0
- package/dist/esm/elements/ImageRun.js.map +1 -0
- package/dist/esm/elements/MathElement.js +37 -0
- package/dist/esm/elements/MathElement.js.map +1 -0
- package/dist/esm/elements/Paragraph.js +2308 -0
- package/dist/esm/elements/Paragraph.js.map +1 -0
- package/dist/esm/elements/PreservedElement.js +29 -0
- package/dist/esm/elements/PreservedElement.js.map +1 -0
- package/dist/esm/elements/PropertyChangeTypes.js +53 -0
- package/dist/esm/elements/PropertyChangeTypes.js.map +1 -0
- package/dist/esm/elements/RangeMarker.js +219 -0
- package/dist/esm/elements/RangeMarker.js.map +1 -0
- package/dist/esm/elements/RegisteredBodyElement.js +40 -0
- package/dist/esm/elements/RegisteredBodyElement.js.map +1 -0
- package/dist/esm/elements/Revision.js +498 -0
- package/dist/esm/elements/Revision.js.map +1 -0
- package/dist/esm/elements/RevisionContent.js +18 -0
- package/dist/esm/elements/RevisionContent.js.map +1 -0
- package/dist/esm/elements/RevisionManager.js +486 -0
- package/dist/esm/elements/RevisionManager.js.map +1 -0
- package/dist/esm/elements/Run.js +1465 -0
- package/dist/esm/elements/Run.js.map +1 -0
- package/dist/esm/elements/Section.js +978 -0
- package/dist/esm/elements/Section.js.map +1 -0
- package/dist/esm/elements/Shape.js +493 -0
- package/dist/esm/elements/Shape.js.map +1 -0
- package/dist/esm/elements/StructuredDocumentTag.js +471 -0
- package/dist/esm/elements/StructuredDocumentTag.js.map +1 -0
- package/dist/esm/elements/Table.js +1456 -0
- package/dist/esm/elements/Table.js.map +1 -0
- package/dist/esm/elements/TableCell.js +835 -0
- package/dist/esm/elements/TableCell.js.map +1 -0
- package/dist/esm/elements/TableGridChange.js +52 -0
- package/dist/esm/elements/TableGridChange.js.map +1 -0
- package/dist/esm/elements/TableOfContents.js +389 -0
- package/dist/esm/elements/TableOfContents.js.map +1 -0
- package/dist/esm/elements/TableOfContentsElement.js +29 -0
- package/dist/esm/elements/TableOfContentsElement.js.map +1 -0
- package/dist/esm/elements/TableRow.js +555 -0
- package/dist/esm/elements/TableRow.js.map +1 -0
- package/dist/esm/elements/TextBox.js +459 -0
- package/dist/esm/elements/TextBox.js.map +1 -0
- package/dist/esm/formatting/AbstractNumbering.js +325 -0
- package/dist/esm/formatting/AbstractNumbering.js.map +1 -0
- package/dist/esm/formatting/NumberingInstance.js +150 -0
- package/dist/esm/formatting/NumberingInstance.js.map +1 -0
- package/dist/esm/formatting/NumberingLevel.js +608 -0
- package/dist/esm/formatting/NumberingLevel.js.map +1 -0
- package/dist/esm/formatting/NumberingManager.js +423 -0
- package/dist/esm/formatting/NumberingManager.js.map +1 -0
- package/dist/esm/formatting/Style.js +1151 -0
- package/dist/esm/formatting/Style.js.map +1 -0
- package/dist/esm/formatting/StylesManager.js +557 -0
- package/dist/esm/formatting/StylesManager.js.map +1 -0
- package/dist/esm/helpers/CleanupHelper.js +350 -0
- package/dist/esm/helpers/CleanupHelper.js.map +1 -0
- package/dist/esm/images/ImageOptimizer.js +161 -0
- package/dist/esm/images/ImageOptimizer.js.map +1 -0
- package/dist/esm/index.js +75 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal.js +16 -0
- package/dist/esm/internal.js.map +1 -0
- package/dist/esm/managers/DrawingManager.js +163 -0
- package/dist/esm/managers/DrawingManager.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/processors/ChangelogGenerator.js +970 -0
- package/dist/esm/processors/ChangelogGenerator.js.map +1 -0
- package/dist/esm/processors/CompatibilityUpgrader.js +130 -0
- package/dist/esm/processors/CompatibilityUpgrader.js.map +1 -0
- package/dist/esm/processors/InMemoryRevisionAcceptor.js +530 -0
- package/dist/esm/processors/InMemoryRevisionAcceptor.js.map +1 -0
- package/dist/esm/processors/MoveOperationHelper.js +57 -0
- package/dist/esm/processors/MoveOperationHelper.js.map +1 -0
- package/dist/esm/processors/RevisionAwareProcessor.js +232 -0
- package/dist/esm/processors/RevisionAwareProcessor.js.map +1 -0
- package/dist/esm/processors/RevisionWalker.js +278 -0
- package/dist/esm/processors/RevisionWalker.js.map +1 -0
- package/dist/{utils → esm/processors}/SelectiveRevisionAcceptor.js +81 -42
- package/dist/esm/processors/SelectiveRevisionAcceptor.js.map +1 -0
- package/dist/esm/processors/ShadingResolver.js +66 -0
- package/dist/esm/processors/ShadingResolver.js.map +1 -0
- package/dist/esm/processors/acceptRevisions.js +416 -0
- package/dist/esm/processors/acceptRevisions.js.map +1 -0
- package/dist/esm/processors/cnfStyleDecoder.js +89 -0
- package/dist/esm/processors/cnfStyleDecoder.js.map +1 -0
- package/dist/esm/processors/stripTrackedChanges.js +201 -0
- package/dist/esm/processors/stripTrackedChanges.js.map +1 -0
- package/dist/esm/tracking/DocumentTrackingContext.js +531 -0
- package/dist/esm/tracking/DocumentTrackingContext.js.map +1 -0
- package/dist/esm/tracking/TrackingContext.js +2 -0
- package/dist/esm/tracking/TrackingContext.js.map +1 -0
- package/dist/esm/types/compatibility-types.js +8 -0
- package/dist/esm/types/compatibility-types.js.map +1 -0
- package/dist/esm/types/document-types.js +2 -0
- package/dist/esm/types/document-types.js.map +1 -0
- package/dist/esm/types/formatting.js +2 -0
- package/dist/esm/types/formatting.js.map +1 -0
- package/dist/esm/types/list-types.js +2 -0
- package/dist/esm/types/list-types.js.map +1 -0
- package/dist/esm/types/settings-types.js +2 -0
- package/dist/esm/types/settings-types.js.map +1 -0
- package/dist/esm/types/styleConfig.js +2 -0
- package/dist/esm/types/styleConfig.js.map +1 -0
- package/dist/esm/utils/KeyedRegistry.js +32 -0
- package/dist/esm/utils/KeyedRegistry.js.map +1 -0
- package/dist/esm/utils/corruptionDetection.js +155 -0
- package/dist/esm/utils/corruptionDetection.js.map +1 -0
- package/dist/esm/utils/dateFormatting.js +4 -0
- package/dist/esm/utils/dateFormatting.js.map +1 -0
- package/dist/esm/utils/deepClone.js +40 -0
- package/dist/esm/utils/deepClone.js.map +1 -0
- package/dist/esm/utils/deepEqual.js +47 -0
- package/dist/esm/utils/deepEqual.js.map +1 -0
- package/dist/esm/utils/diagnostics.js +69 -0
- package/dist/esm/utils/diagnostics.js.map +1 -0
- package/dist/esm/utils/errorHandling.js +36 -0
- package/dist/esm/utils/errorHandling.js.map +1 -0
- package/dist/esm/utils/formatting.js +93 -0
- package/dist/esm/utils/formatting.js.map +1 -0
- package/dist/esm/utils/list-detection.js +148 -0
- package/dist/esm/utils/list-detection.js.map +1 -0
- package/dist/esm/utils/logger.js +205 -0
- package/dist/esm/utils/logger.js.map +1 -0
- package/dist/esm/utils/parsingHelpers.js +56 -0
- package/dist/esm/utils/parsingHelpers.js.map +1 -0
- package/dist/esm/utils/textDiff.js +42 -0
- package/dist/esm/utils/textDiff.js.map +1 -0
- package/dist/esm/utils/units.js +152 -0
- package/dist/esm/utils/units.js.map +1 -0
- package/dist/esm/utils/validation.js +285 -0
- package/dist/esm/utils/validation.js.map +1 -0
- package/dist/esm/utils/xmlSanitization.js +54 -0
- package/dist/esm/utils/xmlSanitization.js.map +1 -0
- package/dist/esm/validation/RevisionAutoFixer.js +340 -0
- package/dist/esm/validation/RevisionAutoFixer.js.map +1 -0
- package/dist/esm/validation/RevisionValidator.js +240 -0
- package/dist/esm/validation/RevisionValidator.js.map +1 -0
- package/dist/esm/validation/ValidationRuleRegistry.js +40 -0
- package/dist/esm/validation/ValidationRuleRegistry.js.map +1 -0
- package/dist/esm/validation/ValidationRules.js +92 -0
- package/dist/esm/validation/ValidationRules.js.map +1 -0
- package/dist/esm/validation/index.js +4 -0
- package/dist/esm/validation/index.js.map +1 -0
- package/dist/esm/xml/XMLBuilder.js +434 -0
- package/dist/esm/xml/XMLBuilder.js.map +1 -0
- package/dist/esm/xml/XMLParser.js +486 -0
- package/dist/esm/xml/XMLParser.js.map +1 -0
- package/dist/esm/zip/ZipHandler.js +298 -0
- package/dist/esm/zip/ZipHandler.js.map +1 -0
- package/dist/esm/zip/ZipReader.js +147 -0
- package/dist/esm/zip/ZipReader.js.map +1 -0
- package/dist/esm/zip/ZipWriter.js +199 -0
- package/dist/esm/zip/ZipWriter.js.map +1 -0
- package/dist/esm/zip/errors.js +43 -0
- package/dist/esm/zip/errors.js.map +1 -0
- package/dist/esm/zip/types.js +31 -0
- package/dist/esm/zip/types.js.map +1 -0
- package/dist/formatting/AbstractNumbering.d.ts +2 -2
- package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
- package/dist/formatting/AbstractNumbering.js +33 -33
- package/dist/formatting/AbstractNumbering.js.map +1 -1
- package/dist/formatting/NumberingInstance.d.ts +2 -2
- package/dist/formatting/NumberingInstance.d.ts.map +1 -1
- package/dist/formatting/NumberingInstance.js +7 -7
- package/dist/formatting/NumberingInstance.js.map +1 -1
- package/dist/formatting/NumberingLevel.d.ts +11 -2
- package/dist/formatting/NumberingLevel.d.ts.map +1 -1
- package/dist/formatting/NumberingLevel.js +111 -25
- package/dist/formatting/NumberingLevel.js.map +1 -1
- package/dist/formatting/NumberingManager.d.ts +4 -4
- package/dist/formatting/NumberingManager.d.ts.map +1 -1
- package/dist/formatting/NumberingManager.js +28 -28
- package/dist/formatting/NumberingManager.js.map +1 -1
- package/dist/formatting/Style.d.ts +14 -7
- package/dist/formatting/Style.d.ts.map +1 -1
- package/dist/formatting/Style.js +309 -112
- package/dist/formatting/Style.js.map +1 -1
- package/dist/formatting/StylesManager.d.ts +2 -2
- package/dist/formatting/StylesManager.d.ts.map +1 -1
- package/dist/formatting/StylesManager.js +52 -52
- package/dist/formatting/StylesManager.js.map +1 -1
- package/dist/helpers/CleanupHelper.d.ts +1 -1
- package/dist/helpers/CleanupHelper.d.ts.map +1 -1
- package/dist/helpers/CleanupHelper.js +15 -15
- package/dist/helpers/CleanupHelper.js.map +1 -1
- package/dist/index.d.ts +81 -90
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +286 -317
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +16 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +42 -0
- package/dist/internal.js.map +1 -0
- package/dist/managers/DrawingManager.d.ts +3 -3
- package/dist/managers/DrawingManager.d.ts.map +1 -1
- package/dist/managers/DrawingManager.js +12 -12
- package/dist/managers/DrawingManager.js.map +1 -1
- package/dist/{utils → processors}/ChangelogGenerator.d.ts +2 -2
- package/dist/processors/ChangelogGenerator.d.ts.map +1 -0
- package/dist/{utils → processors}/ChangelogGenerator.js +2 -2
- package/dist/processors/ChangelogGenerator.js.map +1 -0
- package/dist/processors/CompatibilityUpgrader.d.ts.map +1 -0
- package/dist/{utils → processors}/CompatibilityUpgrader.js +10 -10
- package/dist/processors/CompatibilityUpgrader.js.map +1 -0
- package/dist/{utils → processors}/InMemoryRevisionAcceptor.d.ts +3 -3
- package/dist/processors/InMemoryRevisionAcceptor.d.ts.map +1 -0
- package/dist/{utils → processors}/InMemoryRevisionAcceptor.js +84 -27
- package/dist/processors/InMemoryRevisionAcceptor.js.map +1 -0
- package/dist/{utils → processors}/MoveOperationHelper.d.ts +4 -4
- package/dist/processors/MoveOperationHelper.d.ts.map +1 -0
- package/dist/{utils → processors}/MoveOperationHelper.js +10 -10
- package/dist/processors/MoveOperationHelper.js.map +1 -0
- package/dist/{utils → processors}/RevisionAwareProcessor.d.ts +3 -3
- package/dist/processors/RevisionAwareProcessor.d.ts.map +1 -0
- package/dist/{utils → processors}/RevisionAwareProcessor.js +2 -2
- package/dist/processors/RevisionAwareProcessor.js.map +1 -0
- package/dist/{utils → processors}/RevisionWalker.d.ts +2 -1
- package/dist/processors/RevisionWalker.d.ts.map +1 -0
- package/dist/{utils → processors}/RevisionWalker.js +28 -0
- package/dist/processors/RevisionWalker.js.map +1 -0
- package/dist/{utils → processors}/SelectiveRevisionAcceptor.d.ts +4 -3
- package/dist/processors/SelectiveRevisionAcceptor.d.ts.map +1 -0
- package/dist/processors/SelectiveRevisionAcceptor.js +402 -0
- package/dist/processors/SelectiveRevisionAcceptor.js.map +1 -0
- package/dist/processors/ShadingResolver.d.ts +6 -0
- package/dist/processors/ShadingResolver.d.ts.map +1 -0
- package/dist/{utils → processors}/ShadingResolver.js +2 -2
- package/dist/processors/ShadingResolver.js.map +1 -0
- package/dist/{utils → processors}/acceptRevisions.d.ts +1 -1
- package/dist/processors/acceptRevisions.d.ts.map +1 -0
- package/dist/{utils → processors}/acceptRevisions.js +24 -4
- package/dist/processors/acceptRevisions.js.map +1 -0
- package/dist/{utils → processors}/cnfStyleDecoder.d.ts +1 -1
- package/dist/processors/cnfStyleDecoder.d.ts.map +1 -0
- package/dist/processors/cnfStyleDecoder.js.map +1 -0
- package/dist/processors/stripTrackedChanges.d.ts +3 -0
- package/dist/processors/stripTrackedChanges.d.ts.map +1 -0
- package/dist/{utils → processors}/stripTrackedChanges.js +16 -6
- package/dist/processors/stripTrackedChanges.js.map +1 -0
- package/dist/tracking/DocumentTrackingContext.d.ts +4 -4
- package/dist/tracking/DocumentTrackingContext.d.ts.map +1 -1
- package/dist/tracking/DocumentTrackingContext.js +38 -43
- package/dist/tracking/DocumentTrackingContext.js.map +1 -1
- package/dist/tracking/TrackingContext.d.ts +8 -8
- package/dist/tracking/TrackingContext.d.ts.map +1 -1
- package/dist/tracking/TrackingContext.js.map +1 -1
- package/dist/types/document-types.d.ts +28 -0
- package/dist/types/document-types.d.ts.map +1 -0
- package/dist/types/document-types.js +3 -0
- package/dist/types/document-types.js.map +1 -0
- package/dist/types/formatting.d.ts +4 -4
- package/dist/types/formatting.d.ts.map +1 -1
- package/dist/types/formatting.js.map +1 -1
- package/dist/types/settings-types.d.ts +6 -0
- package/dist/types/settings-types.d.ts.map +1 -1
- package/dist/types/settings-types.js.map +1 -1
- package/dist/utils/KeyedRegistry.d.ts +13 -0
- package/dist/utils/KeyedRegistry.d.ts.map +1 -0
- package/dist/utils/KeyedRegistry.js +36 -0
- package/dist/utils/KeyedRegistry.js.map +1 -0
- package/dist/utils/corruptionDetection.d.ts +1 -1
- package/dist/utils/corruptionDetection.d.ts.map +1 -1
- package/dist/utils/corruptionDetection.js +4 -4
- package/dist/utils/corruptionDetection.js.map +1 -1
- package/dist/utils/deepEqual.d.ts +2 -0
- package/dist/utils/deepEqual.d.ts.map +1 -0
- package/dist/utils/deepEqual.js +50 -0
- package/dist/utils/deepEqual.js.map +1 -0
- package/dist/utils/list-detection.d.ts +2 -2
- package/dist/utils/list-detection.d.ts.map +1 -1
- package/dist/utils/list-detection.js.map +1 -1
- package/dist/utils/parsingHelpers.d.ts +1 -1
- package/dist/utils/parsingHelpers.d.ts.map +1 -1
- package/dist/utils/parsingHelpers.js +2 -2
- package/dist/utils/parsingHelpers.js.map +1 -1
- package/dist/utils/validation.js +7 -7
- package/dist/utils/validation.js.map +1 -1
- package/dist/utils/xmlSanitization.js +2 -2
- package/dist/utils/xmlSanitization.js.map +1 -1
- package/dist/validation/RevisionAutoFixer.d.ts +4 -4
- package/dist/validation/RevisionAutoFixer.d.ts.map +1 -1
- package/dist/validation/RevisionAutoFixer.js +11 -11
- package/dist/validation/RevisionAutoFixer.js.map +1 -1
- package/dist/validation/RevisionValidator.d.ts +5 -4
- package/dist/validation/RevisionValidator.d.ts.map +1 -1
- package/dist/validation/RevisionValidator.js +29 -30
- package/dist/validation/RevisionValidator.js.map +1 -1
- package/dist/validation/ValidationRuleRegistry.d.ts +27 -0
- package/dist/validation/ValidationRuleRegistry.d.ts.map +1 -0
- package/dist/validation/ValidationRuleRegistry.js +43 -0
- package/dist/validation/ValidationRuleRegistry.js.map +1 -0
- package/dist/validation/index.d.ts +3 -3
- package/dist/validation/index.d.ts.map +1 -1
- package/dist/validation/index.js +10 -10
- package/dist/validation/index.js.map +1 -1
- package/dist/xml/XMLBuilder.d.ts +6 -1
- package/dist/xml/XMLBuilder.d.ts.map +1 -1
- package/dist/xml/XMLBuilder.js +11 -6
- package/dist/xml/XMLBuilder.js.map +1 -1
- package/dist/xml/XMLParser.js +6 -6
- package/dist/xml/XMLParser.js.map +1 -1
- package/dist/zip/ZipHandler.d.ts +1 -1
- package/dist/zip/ZipHandler.d.ts.map +1 -1
- package/dist/zip/ZipHandler.js +8 -8
- package/dist/zip/ZipHandler.js.map +1 -1
- package/dist/zip/ZipReader.d.ts +1 -1
- package/dist/zip/ZipReader.d.ts.map +1 -1
- package/dist/zip/ZipReader.js +14 -14
- package/dist/zip/ZipReader.js.map +1 -1
- package/dist/zip/ZipWriter.d.ts +1 -1
- package/dist/zip/ZipWriter.d.ts.map +1 -1
- package/dist/zip/ZipWriter.js +10 -10
- package/dist/zip/ZipWriter.js.map +1 -1
- package/package.json +20 -4
- package/src/constants/legacyCompatFlags.ts +1 -1
- package/src/core/Document.ts +461 -167
- package/src/core/DocumentContent.ts +14 -11
- package/src/core/DocumentEvents.ts +90 -0
- package/src/core/DocumentGenerator.ts +49 -22
- package/src/core/DocumentParser.ts +2180 -617
- package/src/core/DocumentValidator.ts +7 -7
- package/src/core/ElementRegistry.ts +69 -0
- package/src/core/Relationship.ts +1 -1
- package/src/core/RelationshipManager.ts +4 -4
- package/src/elements/AlternateContent.ts +1 -1
- package/src/elements/Bookmark.ts +52 -4
- package/src/elements/BookmarkManager.ts +2 -2
- package/src/elements/Comment.ts +3 -3
- package/src/elements/CommentManager.ts +4 -4
- package/src/elements/CommonTypes.ts +45 -7
- package/src/elements/CustomXml.ts +1 -1
- package/src/elements/Endnote.ts +2 -2
- package/src/elements/EndnoteManager.ts +3 -3
- package/src/elements/Field.ts +44 -10
- package/src/elements/FieldHelpers.ts +2 -2
- package/src/elements/Footer.ts +4 -4
- package/src/elements/Footnote.ts +2 -2
- package/src/elements/FootnoteManager.ts +3 -3
- package/src/elements/Header.ts +4 -4
- package/src/elements/HeaderFooterManager.ts +2 -2
- package/src/elements/Hyperlink.ts +16 -12
- package/src/elements/Image.ts +3 -3
- package/src/elements/ImageManager.ts +2 -2
- package/src/elements/ImageRun.ts +3 -3
- package/src/elements/MathElement.ts +1 -1
- package/src/elements/Paragraph.ts +221 -88
- package/src/elements/PreservedElement.ts +1 -1
- package/src/elements/PropertyChangeTypes.ts +2 -2
- package/src/elements/RangeMarker.ts +153 -12
- package/src/elements/RegisteredBodyElement.ts +52 -0
- package/src/elements/Revision.ts +14 -14
- package/src/elements/RevisionContent.ts +3 -3
- package/src/elements/RevisionManager.ts +3 -3
- package/src/elements/Run.ts +221 -94
- package/src/elements/Section.ts +136 -69
- package/src/elements/Shape.ts +4 -4
- package/src/elements/StructuredDocumentTag.ts +3 -3
- package/src/elements/Table.ts +91 -27
- package/src/elements/TableCell.ts +62 -34
- package/src/elements/TableGridChange.ts +1 -1
- package/src/elements/TableOfContents.ts +1 -1
- package/src/elements/TableOfContentsElement.ts +2 -2
- package/src/elements/TableRow.ts +192 -48
- package/src/elements/TextBox.ts +5 -5
- package/src/formatting/AbstractNumbering.ts +3 -3
- package/src/formatting/NumberingInstance.ts +2 -2
- package/src/formatting/NumberingLevel.ts +201 -10
- package/src/formatting/NumberingManager.ts +5 -5
- package/src/formatting/Style.ts +382 -86
- package/src/formatting/StylesManager.ts +4 -4
- package/src/helpers/CleanupHelper.ts +6 -6
- package/src/index.ts +118 -127
- package/src/internal.ts +79 -0
- package/src/managers/DrawingManager.ts +3 -3
- package/src/{utils → processors}/ChangelogGenerator.ts +3 -3
- package/src/{utils → processors}/CompatibilityUpgrader.ts +2 -2
- package/src/{utils → processors}/InMemoryRevisionAcceptor.ts +100 -12
- package/src/{utils → processors}/MoveOperationHelper.ts +5 -5
- package/src/{utils → processors}/RevisionAwareProcessor.ts +3 -3
- package/src/{utils → processors}/RevisionWalker.ts +42 -1
- package/src/{utils → processors}/SelectiveRevisionAcceptor.ts +98 -39
- package/src/{utils → processors}/ShadingResolver.ts +5 -5
- package/src/{utils → processors}/acceptRevisions.ts +77 -9
- package/src/{utils → processors}/cnfStyleDecoder.ts +1 -1
- package/src/{utils → processors}/stripTrackedChanges.ts +35 -10
- package/src/tracking/DocumentTrackingContext.ts +12 -14
- package/src/tracking/TrackingContext.ts +8 -8
- package/src/types/document-types.ts +53 -0
- package/src/types/formatting.ts +4 -4
- package/src/types/settings-types.ts +32 -0
- package/src/utils/KeyedRegistry.ts +41 -0
- package/src/utils/corruptionDetection.ts +2 -2
- package/src/utils/deepEqual.ts +58 -0
- package/src/utils/list-detection.ts +2 -2
- package/src/utils/parsingHelpers.ts +11 -3
- package/src/utils/validation.ts +3 -3
- package/src/utils/xmlSanitization.ts +1 -1
- package/src/validation/RevisionAutoFixer.ts +5 -5
- package/src/validation/RevisionValidator.ts +39 -28
- package/src/validation/ValidationRuleRegistry.ts +86 -0
- package/src/validation/index.ts +3 -3
- package/src/xml/XMLBuilder.ts +13 -3
- package/src/xml/XMLParser.ts +2 -2
- package/src/zip/ZipHandler.ts +4 -4
- package/src/zip/ZipReader.ts +3 -3
- package/src/zip/ZipWriter.ts +3 -3
- package/dist/utils/ChangelogGenerator.d.ts.map +0 -1
- package/dist/utils/ChangelogGenerator.js.map +0 -1
- package/dist/utils/CompatibilityUpgrader.d.ts.map +0 -1
- package/dist/utils/CompatibilityUpgrader.js.map +0 -1
- package/dist/utils/InMemoryRevisionAcceptor.d.ts.map +0 -1
- package/dist/utils/InMemoryRevisionAcceptor.js.map +0 -1
- package/dist/utils/MoveOperationHelper.d.ts.map +0 -1
- package/dist/utils/MoveOperationHelper.js.map +0 -1
- package/dist/utils/RevisionAwareProcessor.d.ts.map +0 -1
- package/dist/utils/RevisionAwareProcessor.js.map +0 -1
- package/dist/utils/RevisionWalker.d.ts.map +0 -1
- package/dist/utils/RevisionWalker.js.map +0 -1
- package/dist/utils/SelectiveRevisionAcceptor.d.ts.map +0 -1
- package/dist/utils/SelectiveRevisionAcceptor.js.map +0 -1
- package/dist/utils/ShadingResolver.d.ts +0 -6
- package/dist/utils/ShadingResolver.d.ts.map +0 -1
- package/dist/utils/ShadingResolver.js.map +0 -1
- package/dist/utils/acceptRevisions.d.ts.map +0 -1
- package/dist/utils/acceptRevisions.js.map +0 -1
- package/dist/utils/cnfStyleDecoder.d.ts.map +0 -1
- package/dist/utils/cnfStyleDecoder.js.map +0 -1
- package/dist/utils/stripTrackedChanges.d.ts +0 -3
- package/dist/utils/stripTrackedChanges.d.ts.map +0 -1
- package/dist/utils/stripTrackedChanges.js.map +0 -1
- package/src/__tests__/helper-methods.test.ts +0 -512
- package/src/constants/CLAUDE.md +0 -28
- package/src/core/CLAUDE.md +0 -113
- package/src/elements/CLAUDE.md +0 -142
- package/src/formatting/CLAUDE.md +0 -78
- package/src/managers/CLAUDE.md +0 -47
- package/src/tracking/CLAUDE.md +0 -30
- package/src/types/CLAUDE.md +0 -39
- package/src/utils/CLAUDE.md +0 -168
- package/src/validation/CLAUDE.md +0 -40
- package/src/xml/CLAUDE.md +0 -65
- package/src/zip/CLAUDE.md +0 -55
- /package/dist/{utils → processors}/CompatibilityUpgrader.d.ts +0 -0
- /package/dist/{utils → processors}/cnfStyleDecoder.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-types.d.ts","sourceRoot":"","sources":["../../src/types/settings-types.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,gBAAgB,GAAG,OAAO,CAAC;IAC3D,WAAW,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"settings-types.d.ts","sourceRoot":"","sources":["../../src/types/settings-types.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,gBAAgB,GAAG,OAAO,CAAC;IAC3D,WAAW,EAAE,OAAO,CAAC;IAQrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IAWd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAKD,MAAM,WAAW,oBAAoB;IACnC,0BAA0B,EAAE,OAAO,CAAC;IACpC,cAAc,EAAE,OAAO,CAAC;IACxB,kBAAkB,EAAE,OAAO,CAAC;IAM5B,UAAU,CAAC,EAAE,OAAO,CAAC;IAKrB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAKD,MAAM,WAAW,oBAAoB;IACnC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC;AAKD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-types.js","sourceRoot":"","sources":["../../src/types/settings-types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Shared type definitions for document settings (settings.xml)\n *\n * These types are used by both Document.ts (in-memory state) and\n * DocumentGenerator.ts (XML generation) to ensure consistency.\n */\n\n/**\n * Document protection settings per ECMA-376 CT_DocProtect\n */\nexport interface DocumentProtection {\n edit: 'readOnly' | 'comments' | 'trackedChanges' | 'forms';\n enforcement: boolean;\n cryptProviderType?: string;\n cryptAlgorithmClass?: string;\n cryptAlgorithmType?: string;\n cryptAlgorithmSid?: number;\n cryptSpinCount?: number;\n hash?: string;\n salt?: string;\n}\n\n/**\n * Revision view settings per ECMA-376 CT_TrackChangesView\n */\nexport interface RevisionViewSettings {\n showInsertionsAndDeletions: boolean;\n showFormatting: boolean;\n showInkAnnotations: boolean;\n}\n\n/**\n * Track changes and related settings passed to DocumentGenerator.generateSettings()\n */\nexport interface TrackChangesSettings {\n trackChangesEnabled?: boolean;\n trackFormatting?: boolean;\n revisionView?: RevisionViewSettings;\n rsidRoot?: string;\n rsids?: string[];\n documentProtection?: DocumentProtection;\n}\n\n/**\n * Information about webSettings.xml per ECMA-376 CT_WebSettings\n */\nexport interface WebSettingsInfo {\n divCount: number;\n optimizeForBrowser: boolean;\n allowPNG: boolean;\n relyOnVML: boolean;\n doNotRelyOnCSS: boolean;\n doNotSaveAsSingleFile: boolean;\n doNotOrganizeInFolder: boolean;\n doNotUseLongFileNames: boolean;\n pixelsPerInch?: number;\n targetScreenSz?: string;\n encoding?: string;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"settings-types.js","sourceRoot":"","sources":["../../src/types/settings-types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Shared type definitions for document settings (settings.xml)\n *\n * These types are used by both Document.ts (in-memory state) and\n * DocumentGenerator.ts (XML generation) to ensure consistency.\n */\n\n/**\n * Document protection settings per ECMA-376 CT_DocProtect\n */\nexport interface DocumentProtection {\n edit: 'readOnly' | 'comments' | 'trackedChanges' | 'forms';\n enforcement: boolean;\n /**\n * `w:formatting` per CT_DocProtect §17.15.1.29 — when true, formatting\n * changes are still allowed even when edit protection is enforced.\n * Directly relevant to the tracked-changes workflow: combined with\n * `edit: 'trackedChanges'`, this forces all content edits to be tracked\n * while still permitting formatting adjustments.\n */\n formatting?: boolean;\n cryptProviderType?: string;\n cryptAlgorithmClass?: string;\n cryptAlgorithmType?: string;\n cryptAlgorithmSid?: number;\n cryptSpinCount?: number;\n hash?: string;\n salt?: string;\n /**\n * Modern crypto attributes per ISO/IEC 29500-4 §13 (Word 2013+):\n * - `algorithmName` names the strong hash algorithm (e.g. \"SHA-512\"),\n * replacing the legacy `cryptAlgorithmSid` lookup-table reference.\n * - `hashValue` is the base64-encoded password hash.\n * - `saltValue` is the base64-encoded salt.\n *\n * These are emitted alongside / instead of the legacy `hash` / `salt`\n * / `cryptAlgorithmSid` attributes. Previously dropped on round-trip.\n */\n algorithmName?: string;\n hashValue?: string;\n saltValue?: string;\n}\n\n/**\n * Revision view settings per ECMA-376 CT_TrackChangesView\n */\nexport interface RevisionViewSettings {\n showInsertionsAndDeletions: boolean;\n showFormatting: boolean;\n showInkAnnotations: boolean;\n /**\n * `w:markup` per CT_TrackChangesView §17.15.1.77 — when false, all\n * revision markup is hidden in the reviewer pane (no balloons, no\n * strikethrough/inserted styling). Defaults to true when absent.\n */\n showMarkup?: boolean;\n /**\n * `w:comments` per CT_TrackChangesView §17.15.1.77 — when false,\n * comment balloons are hidden. Defaults to true when absent.\n */\n showComments?: boolean;\n}\n\n/**\n * Track changes and related settings passed to DocumentGenerator.generateSettings()\n */\nexport interface TrackChangesSettings {\n trackChangesEnabled?: boolean;\n trackFormatting?: boolean;\n revisionView?: RevisionViewSettings;\n rsidRoot?: string;\n rsids?: string[];\n documentProtection?: DocumentProtection;\n}\n\n/**\n * Information about webSettings.xml per ECMA-376 CT_WebSettings\n */\nexport interface WebSettingsInfo {\n divCount: number;\n optimizeForBrowser: boolean;\n allowPNG: boolean;\n relyOnVML: boolean;\n doNotRelyOnCSS: boolean;\n doNotSaveAsSingleFile: boolean;\n doNotOrganizeInFolder: boolean;\n doNotUseLongFileNames: boolean;\n pixelsPerInch?: number;\n targetScreenSz?: string;\n encoding?: string;\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare class KeyedRegistry<V> {
|
|
2
|
+
private readonly label;
|
|
3
|
+
private readonly entries;
|
|
4
|
+
constructor(label: string);
|
|
5
|
+
register(key: string, value: V): void;
|
|
6
|
+
unregister(key: string): boolean;
|
|
7
|
+
has(key: string): boolean;
|
|
8
|
+
get(key: string): V | undefined;
|
|
9
|
+
keys(): string[];
|
|
10
|
+
values(): V[];
|
|
11
|
+
clear(): void;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=KeyedRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KeyedRegistry.d.ts","sourceRoot":"","sources":["../../src/utils/KeyedRegistry.ts"],"names":[],"mappings":"AAKA,qBAAa,aAAa,CAAC,CAAC;IAGd,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFlC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;gBAEnB,KAAK,EAAE,MAAM;IAE1C,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAOrC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIhC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAI/B,IAAI,IAAI,MAAM,EAAE;IAIhB,MAAM,IAAI,CAAC,EAAE;IAIb,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KeyedRegistry = void 0;
|
|
4
|
+
class KeyedRegistry {
|
|
5
|
+
label;
|
|
6
|
+
entries = new Map();
|
|
7
|
+
constructor(label) {
|
|
8
|
+
this.label = label;
|
|
9
|
+
}
|
|
10
|
+
register(key, value) {
|
|
11
|
+
if (this.entries.has(key)) {
|
|
12
|
+
throw new Error(`${this.label}: "${key}" is already registered`);
|
|
13
|
+
}
|
|
14
|
+
this.entries.set(key, value);
|
|
15
|
+
}
|
|
16
|
+
unregister(key) {
|
|
17
|
+
return this.entries.delete(key);
|
|
18
|
+
}
|
|
19
|
+
has(key) {
|
|
20
|
+
return this.entries.has(key);
|
|
21
|
+
}
|
|
22
|
+
get(key) {
|
|
23
|
+
return this.entries.get(key);
|
|
24
|
+
}
|
|
25
|
+
keys() {
|
|
26
|
+
return [...this.entries.keys()];
|
|
27
|
+
}
|
|
28
|
+
values() {
|
|
29
|
+
return [...this.entries.values()];
|
|
30
|
+
}
|
|
31
|
+
clear() {
|
|
32
|
+
this.entries.clear();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.KeyedRegistry = KeyedRegistry;
|
|
36
|
+
//# sourceMappingURL=KeyedRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KeyedRegistry.js","sourceRoot":"","sources":["../../src/utils/KeyedRegistry.ts"],"names":[],"mappings":";;;AAKA,MAAa,aAAa;IAGK;IAFZ,OAAO,GAAG,IAAI,GAAG,EAAa,CAAC;IAEhD,YAA6B,KAAa;QAAb,UAAK,GAAL,KAAK,CAAQ;IAAG,CAAC;IAE9C,QAAQ,CAAC,GAAW,EAAE,KAAQ;QAC5B,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,MAAM,GAAG,yBAAyB,CAAC,CAAC;QACnE,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,UAAU,CAAC,GAAW;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,MAAM;QACJ,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;CACF;AAnCD,sCAmCC","sourcesContent":["/**\n * Map-backed keyed registry shared by ElementRegistry and ValidationRuleRegistry.\n * Throws on duplicate `register()` so callers cannot silently overwrite a\n * pre-existing entry.\n */\nexport class KeyedRegistry<V> {\n private readonly entries = new Map<string, V>();\n\n constructor(private readonly label: string) {}\n\n register(key: string, value: V): void {\n if (this.entries.has(key)) {\n throw new Error(`${this.label}: \"${key}\" is already registered`);\n }\n this.entries.set(key, value);\n }\n\n unregister(key: string): boolean {\n return this.entries.delete(key);\n }\n\n has(key: string): boolean {\n return this.entries.has(key);\n }\n\n get(key: string): V | undefined {\n return this.entries.get(key);\n }\n\n keys(): string[] {\n return [...this.entries.keys()];\n }\n\n values(): V[] {\n return [...this.entries.values()];\n }\n\n clear(): void {\n this.entries.clear();\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"corruptionDetection.d.ts","sourceRoot":"","sources":["../../src/utils/corruptionDetection.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"corruptionDetection.d.ts","sourceRoot":"","sources":["../../src/utils/corruptionDetection.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAIrD,UAAU,YAAY;IACpB,gBAAgB,CAAC,IAAI,SAAS,EAAE,CAAC;CAClC;AAKD,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,UAAU,GACV,UAAU,GACV,OAAO,CAAC;AAKZ,MAAM,WAAW,kBAAkB;IAEjC,cAAc,EAAE,MAAM,CAAC;IAEvB,QAAQ,EAAE,MAAM,CAAC;IAEjB,IAAI,EAAE,MAAM,CAAC;IAEb,cAAc,EAAE,cAAc,CAAC;IAE/B,YAAY,EAAE,MAAM,CAAC;IAErB,MAAM,EAAE,MAAM,CAAC;CAChB;AAKD,MAAM,WAAW,gBAAgB;IAE/B,WAAW,EAAE,OAAO,CAAC;IAErB,cAAc,EAAE,MAAM,CAAC;IAEvB,SAAS,EAAE,kBAAkB,EAAE,CAAC;IAEhC,OAAO,EAAE,MAAM,CAAC;IAEhB,UAAU,EAAE;QACV,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAwBD,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,YAAY,GAAG,gBAAgB,CAkE9E;AAKD,UAAU,oBAAoB;IAC5B,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,cAAc,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAoBD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,CA4DzE;AAiBD,wBAAgB,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CA2BxD;AAiDD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAWpD"}
|
|
@@ -4,8 +4,8 @@ exports.detectCorruptionInDocument = detectCorruptionInDocument;
|
|
|
4
4
|
exports.detectCorruptionInText = detectCorruptionInText;
|
|
5
5
|
exports.suggestFix = suggestFix;
|
|
6
6
|
exports.looksCorrupted = looksCorrupted;
|
|
7
|
-
const
|
|
8
|
-
const
|
|
7
|
+
const Paragraph_js_1 = require("../elements/Paragraph.js");
|
|
8
|
+
const Run_js_1 = require("../elements/Run.js");
|
|
9
9
|
function detectCorruptionInDocument(doc) {
|
|
10
10
|
const locations = [];
|
|
11
11
|
const stats = {
|
|
@@ -17,13 +17,13 @@ function detectCorruptionInDocument(doc) {
|
|
|
17
17
|
const paragraphs = doc.getAllParagraphs ? doc.getAllParagraphs() : [];
|
|
18
18
|
for (let pIdx = 0; pIdx < paragraphs.length; pIdx++) {
|
|
19
19
|
const paragraph = paragraphs[pIdx];
|
|
20
|
-
if (!paragraph || !(paragraph instanceof
|
|
20
|
+
if (!paragraph || !(paragraph instanceof Paragraph_js_1.Paragraph)) {
|
|
21
21
|
continue;
|
|
22
22
|
}
|
|
23
23
|
const runs = paragraph.getRuns();
|
|
24
24
|
for (let rIdx = 0; rIdx < runs.length; rIdx++) {
|
|
25
25
|
const run = runs[rIdx];
|
|
26
|
-
if (!run || !(run instanceof
|
|
26
|
+
if (!run || !(run instanceof Run_js_1.Run)) {
|
|
27
27
|
continue;
|
|
28
28
|
}
|
|
29
29
|
const text = run.getText();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"corruptionDetection.js","sourceRoot":"","sources":["../../src/utils/corruptionDetection.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Corruption Detection - Utilities to detect and diagnose XML corruption in documents\n *\n * This module helps users identify when they've accidentally passed XML-like strings\n * to text methods instead of using the proper API. This is a common mistake that\n * results in escaped XML tags being displayed as literal text in Word.\n */\n\nimport { Paragraph } from '../elements/Paragraph';\nimport { Run } from '../elements/Run';\n\n/** Minimal interface for document corruption scanning (avoids circular import) */\ninterface DocumentLike {\n getAllParagraphs?(): Paragraph[];\n}\n\n/**\n * Types of corruption that can be detected\n */\nexport type CorruptionType =\n | 'escaped-xml' // <w:t> style escaping\n | 'xml-tags' // <w:t> tags in text\n | 'entities' // " ' etc.\n | 'mixed'; // Multiple types\n\n/**\n * Location of corruption within a document\n */\nexport interface CorruptionLocation {\n /** Index of the paragraph containing corruption */\n paragraphIndex: number;\n /** Index of the run within the paragraph */\n runIndex: number;\n /** The corrupted text content */\n text: string;\n /** Type of corruption detected */\n corruptionType: CorruptionType;\n /** Suggested fix for the corruption */\n suggestedFix: string;\n /** Length of corrupted text */\n length: number;\n}\n\n/**\n * Comprehensive corruption report for a document\n */\nexport interface CorruptionReport {\n /** Whether any corruption was found */\n isCorrupted: boolean;\n /** Total number of corrupted locations */\n totalLocations: number;\n /** Detailed list of corruption locations */\n locations: CorruptionLocation[];\n /** Human-readable summary */\n summary: string;\n /** Statistics about corruption types */\n statistics: {\n escapedXml: number;\n xmlTags: number;\n entities: number;\n mixed: number;\n };\n}\n\n/**\n * Detects XML corruption in a document\n *\n * Scans all paragraphs and runs to find text that contains escaped XML\n * or XML-like patterns that suggest the user passed XML strings to text methods.\n *\n * @param doc - The document to scan\n * @returns Corruption report with locations and suggested fixes\n *\n * @example\n * ```typescript\n * const doc = await Document.load('corrupted.docx');\n * const report = detectCorruptionInDocument(doc);\n *\n * if (report.isCorrupted) {\n * console.log(report.summary);\n * report.locations.forEach(loc => {\n * console.log(`Paragraph ${loc.paragraphIndex}, Run ${loc.runIndex}: ${loc.suggestedFix}`);\n * });\n * }\n * ```\n */\nexport function detectCorruptionInDocument(doc: DocumentLike): CorruptionReport {\n const locations: CorruptionLocation[] = [];\n const stats = {\n escapedXml: 0,\n xmlTags: 0,\n entities: 0,\n mixed: 0,\n };\n\n // Get all paragraphs from the document\n const paragraphs = doc.getAllParagraphs ? doc.getAllParagraphs() : [];\n\n // Scan each paragraph\n for (let pIdx = 0; pIdx < paragraphs.length; pIdx++) {\n const paragraph = paragraphs[pIdx];\n if (!paragraph || !(paragraph instanceof Paragraph)) {\n continue;\n }\n\n // Get runs from paragraph\n const runs = paragraph.getRuns();\n\n // Scan each run\n for (let rIdx = 0; rIdx < runs.length; rIdx++) {\n const run = runs[rIdx];\n if (!run || !(run instanceof Run)) {\n continue;\n }\n\n const text = run.getText();\n if (!text || text.length === 0) {\n continue;\n }\n\n // Check for corruption in this text\n const corruption = detectCorruptionInText(text);\n\n if (corruption.isCorrupted) {\n locations.push({\n paragraphIndex: pIdx,\n runIndex: rIdx,\n text: text,\n corruptionType: corruption.type,\n suggestedFix: corruption.suggestedFix,\n length: text.length,\n });\n\n // Update statistics\n if (corruption.type === 'escaped-xml') stats.escapedXml++;\n else if (corruption.type === 'xml-tags') stats.xmlTags++;\n else if (corruption.type === 'entities') stats.entities++;\n else if (corruption.type === 'mixed') stats.mixed++;\n }\n }\n }\n\n // Generate summary\n const summary = generateSummary(locations, stats);\n\n return {\n isCorrupted: locations.length > 0,\n totalLocations: locations.length,\n locations,\n summary,\n statistics: stats,\n };\n}\n\n/**\n * Internal result from text corruption detection\n */\ninterface TextCorruptionResult {\n isCorrupted: boolean;\n type: CorruptionType;\n suggestedFix: string;\n}\n\n/**\n * Detects XML corruption in a single text string\n *\n * Checks for common patterns that indicate the user passed XML strings\n * instead of plain text.\n *\n * @param text - Text to check\n * @returns True if corruption detected\n *\n * @example\n * ```typescript\n * const corrupted = detectCorruptionInText('Hello <w:t>World');\n * // Returns: true\n *\n * const clean = detectCorruptionInText('Hello World');\n * // Returns: false\n * ```\n */\nexport function detectCorruptionInText(text: string): TextCorruptionResult {\n if (!text || typeof text !== 'string') {\n return { isCorrupted: false, type: 'mixed', suggestedFix: String(text || '') };\n }\n\n let hasEscapedXml = false;\n let hasXmlTags = false;\n let hasEntities = false;\n\n // Pattern 1: Escaped XML tags (most common corruption)\n // Matches: <w:t>, </w:t>, <w:r>, etc.\n const escapedXmlPattern = /<\\/?w:[a-z]+[^&]*>/i;\n if (escapedXmlPattern.test(text)) {\n hasEscapedXml = true;\n }\n\n // Pattern 2: Raw XML tags (less common, but possible)\n // Matches: <w:t>, </w:t>, <w:r>, etc.\n const xmlTagPattern = /<\\/?w:[a-z]+[^>]*>/i;\n if (xmlTagPattern.test(text)) {\n hasXmlTags = true;\n }\n\n // Pattern 3: Escaped entities combined with Word XML attributes\n // ONLY flag if we see Word-specific patterns, not just any entities\n // This avoids false positives from legitimate escaped characters\n // Matches all OOXML namespaces: w: (word), a: (drawingML), pic: (picture), r: (relationships), wp: (word drawing)\n const wordXmlAttributePattern =\n /(<(?:w|a|r|pic|wp|m|mc|wpc|wps|wpg|c|dgm|o|v):|xml:space="preserve")/i;\n if (wordXmlAttributePattern.test(text)) {\n hasEntities = true;\n }\n\n // Determine corruption type\n const corruptionCount = [hasEscapedXml, hasXmlTags, hasEntities].filter(Boolean).length;\n\n if (corruptionCount === 0) {\n return { isCorrupted: false, type: 'mixed', suggestedFix: text };\n }\n\n // More precise type detection - check primary indicator first\n let type: CorruptionType;\n if (hasEscapedXml && (hasEntities || hasXmlTags)) {\n // Escaped XML combined with other patterns - this is the classic corruption case\n type = 'escaped-xml';\n } else if (hasXmlTags && hasEntities) {\n type = 'xml-tags';\n } else if (corruptionCount > 1) {\n type = 'mixed';\n } else if (hasEscapedXml) {\n type = 'escaped-xml';\n } else if (hasXmlTags) {\n type = 'xml-tags';\n } else {\n type = 'entities';\n }\n\n const suggestedFix = suggestFix(text);\n\n return { isCorrupted: true, type, suggestedFix };\n}\n\n/**\n * Suggests a fix for corrupted text\n *\n * Attempts to clean XML patterns from text to restore the intended content.\n * Uses the same cleaning logic as cleanXmlFromText() from validation.ts.\n *\n * @param corruptedText - Text containing XML corruption\n * @returns Cleaned text with XML patterns removed\n *\n * @example\n * ```typescript\n * const fixed = suggestFix('Hello <w:t>World</w:t>');\n * // Returns: 'Hello World'\n * ```\n */\nexport function suggestFix(corruptedText: string): string {\n if (!corruptedText || typeof corruptedText !== 'string') {\n return corruptedText;\n }\n\n let cleaned = corruptedText;\n\n // Step 1: Unescape XML entities first\n cleaned = cleaned\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/&/g, '&');\n\n // Step 2: Remove Word XML tags\n // Matches: <w:t xml:space=\"preserve\">, </w:t>, <w:r>, etc.\n cleaned = cleaned.replace(/<w:[^>]+>/g, '');\n cleaned = cleaned.replace(/<\\/w:[^>]+>/g, '');\n\n // Step 3: Remove any remaining XML-like tags\n cleaned = cleaned.replace(/<[^>]+>/g, '');\n\n // Step 4: Clean up whitespace\n cleaned = cleaned.replace(/\\s+/g, ' ').trim();\n\n return cleaned;\n}\n\n/**\n * Generates a human-readable summary of corruption\n */\nfunction generateSummary(\n locations: CorruptionLocation[],\n stats: { escapedXml: number; xmlTags: number; entities: number; mixed: number }\n): string {\n if (locations.length === 0) {\n return 'No corruption detected. Document is clean.';\n }\n\n const lines: string[] = [];\n lines.push(`Found ${locations.length} corrupted text location(s) in the document.`);\n lines.push('');\n lines.push('Corruption breakdown:');\n\n if (stats.escapedXml > 0) {\n lines.push(` - Escaped XML: ${stats.escapedXml} location(s)`);\n }\n if (stats.xmlTags > 0) {\n lines.push(` - XML Tags: ${stats.xmlTags} location(s)`);\n }\n if (stats.entities > 0) {\n lines.push(` - XML Entities: ${stats.entities} location(s)`);\n }\n if (stats.mixed > 0) {\n lines.push(` - Mixed: ${stats.mixed} location(s)`);\n }\n\n lines.push('');\n lines.push('This corruption typically occurs when XML strings are passed to text methods.');\n lines.push('Instead of: paragraph.addText(\"Text<w:t>1</w:t>\")');\n lines.push('Use: paragraph.addText(\"Text\"); paragraph.addText(\"1\");');\n lines.push('');\n lines.push('To automatically clean text, use: new Run(text, { cleanXmlFromText: true })');\n\n return lines.join('\\n');\n}\n\n/**\n * Checks if text looks like it might be corrupted (less strict check)\n *\n * This is a quick check that can be used for warnings without full analysis.\n *\n * @param text - Text to check\n * @returns True if text might be corrupted\n */\nexport function looksCorrupted(text: string): boolean {\n if (!text || typeof text !== 'string') {\n return false;\n }\n\n // Quick regex checks for common corruption patterns\n return (\n /<\\/?(w|r|p):[a-z]+/i.test(text) ||\n /<\\/?(w|r|p):[a-z]+/i.test(text) ||\n /xml:space="/i.test(text)\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"corruptionDetection.js","sourceRoot":"","sources":["../../src/utils/corruptionDetection.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Corruption Detection - Utilities to detect and diagnose XML corruption in documents\n *\n * This module helps users identify when they've accidentally passed XML-like strings\n * to text methods instead of using the proper API. This is a common mistake that\n * results in escaped XML tags being displayed as literal text in Word.\n */\n\nimport { Paragraph } from '../elements/Paragraph.js';\nimport { Run } from '../elements/Run.js';\n\n/** Minimal interface for document corruption scanning (avoids circular import) */\ninterface DocumentLike {\n getAllParagraphs?(): Paragraph[];\n}\n\n/**\n * Types of corruption that can be detected\n */\nexport type CorruptionType =\n | 'escaped-xml' // <w:t> style escaping\n | 'xml-tags' // <w:t> tags in text\n | 'entities' // " ' etc.\n | 'mixed'; // Multiple types\n\n/**\n * Location of corruption within a document\n */\nexport interface CorruptionLocation {\n /** Index of the paragraph containing corruption */\n paragraphIndex: number;\n /** Index of the run within the paragraph */\n runIndex: number;\n /** The corrupted text content */\n text: string;\n /** Type of corruption detected */\n corruptionType: CorruptionType;\n /** Suggested fix for the corruption */\n suggestedFix: string;\n /** Length of corrupted text */\n length: number;\n}\n\n/**\n * Comprehensive corruption report for a document\n */\nexport interface CorruptionReport {\n /** Whether any corruption was found */\n isCorrupted: boolean;\n /** Total number of corrupted locations */\n totalLocations: number;\n /** Detailed list of corruption locations */\n locations: CorruptionLocation[];\n /** Human-readable summary */\n summary: string;\n /** Statistics about corruption types */\n statistics: {\n escapedXml: number;\n xmlTags: number;\n entities: number;\n mixed: number;\n };\n}\n\n/**\n * Detects XML corruption in a document\n *\n * Scans all paragraphs and runs to find text that contains escaped XML\n * or XML-like patterns that suggest the user passed XML strings to text methods.\n *\n * @param doc - The document to scan\n * @returns Corruption report with locations and suggested fixes\n *\n * @example\n * ```typescript\n * const doc = await Document.load('corrupted.docx');\n * const report = detectCorruptionInDocument(doc);\n *\n * if (report.isCorrupted) {\n * console.log(report.summary);\n * report.locations.forEach(loc => {\n * console.log(`Paragraph ${loc.paragraphIndex}, Run ${loc.runIndex}: ${loc.suggestedFix}`);\n * });\n * }\n * ```\n */\nexport function detectCorruptionInDocument(doc: DocumentLike): CorruptionReport {\n const locations: CorruptionLocation[] = [];\n const stats = {\n escapedXml: 0,\n xmlTags: 0,\n entities: 0,\n mixed: 0,\n };\n\n // Get all paragraphs from the document\n const paragraphs = doc.getAllParagraphs ? doc.getAllParagraphs() : [];\n\n // Scan each paragraph\n for (let pIdx = 0; pIdx < paragraphs.length; pIdx++) {\n const paragraph = paragraphs[pIdx];\n if (!paragraph || !(paragraph instanceof Paragraph)) {\n continue;\n }\n\n // Get runs from paragraph\n const runs = paragraph.getRuns();\n\n // Scan each run\n for (let rIdx = 0; rIdx < runs.length; rIdx++) {\n const run = runs[rIdx];\n if (!run || !(run instanceof Run)) {\n continue;\n }\n\n const text = run.getText();\n if (!text || text.length === 0) {\n continue;\n }\n\n // Check for corruption in this text\n const corruption = detectCorruptionInText(text);\n\n if (corruption.isCorrupted) {\n locations.push({\n paragraphIndex: pIdx,\n runIndex: rIdx,\n text: text,\n corruptionType: corruption.type,\n suggestedFix: corruption.suggestedFix,\n length: text.length,\n });\n\n // Update statistics\n if (corruption.type === 'escaped-xml') stats.escapedXml++;\n else if (corruption.type === 'xml-tags') stats.xmlTags++;\n else if (corruption.type === 'entities') stats.entities++;\n else if (corruption.type === 'mixed') stats.mixed++;\n }\n }\n }\n\n // Generate summary\n const summary = generateSummary(locations, stats);\n\n return {\n isCorrupted: locations.length > 0,\n totalLocations: locations.length,\n locations,\n summary,\n statistics: stats,\n };\n}\n\n/**\n * Internal result from text corruption detection\n */\ninterface TextCorruptionResult {\n isCorrupted: boolean;\n type: CorruptionType;\n suggestedFix: string;\n}\n\n/**\n * Detects XML corruption in a single text string\n *\n * Checks for common patterns that indicate the user passed XML strings\n * instead of plain text.\n *\n * @param text - Text to check\n * @returns True if corruption detected\n *\n * @example\n * ```typescript\n * const corrupted = detectCorruptionInText('Hello <w:t>World');\n * // Returns: true\n *\n * const clean = detectCorruptionInText('Hello World');\n * // Returns: false\n * ```\n */\nexport function detectCorruptionInText(text: string): TextCorruptionResult {\n if (!text || typeof text !== 'string') {\n return { isCorrupted: false, type: 'mixed', suggestedFix: String(text || '') };\n }\n\n let hasEscapedXml = false;\n let hasXmlTags = false;\n let hasEntities = false;\n\n // Pattern 1: Escaped XML tags (most common corruption)\n // Matches: <w:t>, </w:t>, <w:r>, etc.\n const escapedXmlPattern = /<\\/?w:[a-z]+[^&]*>/i;\n if (escapedXmlPattern.test(text)) {\n hasEscapedXml = true;\n }\n\n // Pattern 2: Raw XML tags (less common, but possible)\n // Matches: <w:t>, </w:t>, <w:r>, etc.\n const xmlTagPattern = /<\\/?w:[a-z]+[^>]*>/i;\n if (xmlTagPattern.test(text)) {\n hasXmlTags = true;\n }\n\n // Pattern 3: Escaped entities combined with Word XML attributes\n // ONLY flag if we see Word-specific patterns, not just any entities\n // This avoids false positives from legitimate escaped characters\n // Matches all OOXML namespaces: w: (word), a: (drawingML), pic: (picture), r: (relationships), wp: (word drawing)\n const wordXmlAttributePattern =\n /(<(?:w|a|r|pic|wp|m|mc|wpc|wps|wpg|c|dgm|o|v):|xml:space="preserve")/i;\n if (wordXmlAttributePattern.test(text)) {\n hasEntities = true;\n }\n\n // Determine corruption type\n const corruptionCount = [hasEscapedXml, hasXmlTags, hasEntities].filter(Boolean).length;\n\n if (corruptionCount === 0) {\n return { isCorrupted: false, type: 'mixed', suggestedFix: text };\n }\n\n // More precise type detection - check primary indicator first\n let type: CorruptionType;\n if (hasEscapedXml && (hasEntities || hasXmlTags)) {\n // Escaped XML combined with other patterns - this is the classic corruption case\n type = 'escaped-xml';\n } else if (hasXmlTags && hasEntities) {\n type = 'xml-tags';\n } else if (corruptionCount > 1) {\n type = 'mixed';\n } else if (hasEscapedXml) {\n type = 'escaped-xml';\n } else if (hasXmlTags) {\n type = 'xml-tags';\n } else {\n type = 'entities';\n }\n\n const suggestedFix = suggestFix(text);\n\n return { isCorrupted: true, type, suggestedFix };\n}\n\n/**\n * Suggests a fix for corrupted text\n *\n * Attempts to clean XML patterns from text to restore the intended content.\n * Uses the same cleaning logic as cleanXmlFromText() from validation.ts.\n *\n * @param corruptedText - Text containing XML corruption\n * @returns Cleaned text with XML patterns removed\n *\n * @example\n * ```typescript\n * const fixed = suggestFix('Hello <w:t>World</w:t>');\n * // Returns: 'Hello World'\n * ```\n */\nexport function suggestFix(corruptedText: string): string {\n if (!corruptedText || typeof corruptedText !== 'string') {\n return corruptedText;\n }\n\n let cleaned = corruptedText;\n\n // Step 1: Unescape XML entities first\n cleaned = cleaned\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/&/g, '&');\n\n // Step 2: Remove Word XML tags\n // Matches: <w:t xml:space=\"preserve\">, </w:t>, <w:r>, etc.\n cleaned = cleaned.replace(/<w:[^>]+>/g, '');\n cleaned = cleaned.replace(/<\\/w:[^>]+>/g, '');\n\n // Step 3: Remove any remaining XML-like tags\n cleaned = cleaned.replace(/<[^>]+>/g, '');\n\n // Step 4: Clean up whitespace\n cleaned = cleaned.replace(/\\s+/g, ' ').trim();\n\n return cleaned;\n}\n\n/**\n * Generates a human-readable summary of corruption\n */\nfunction generateSummary(\n locations: CorruptionLocation[],\n stats: { escapedXml: number; xmlTags: number; entities: number; mixed: number }\n): string {\n if (locations.length === 0) {\n return 'No corruption detected. Document is clean.';\n }\n\n const lines: string[] = [];\n lines.push(`Found ${locations.length} corrupted text location(s) in the document.`);\n lines.push('');\n lines.push('Corruption breakdown:');\n\n if (stats.escapedXml > 0) {\n lines.push(` - Escaped XML: ${stats.escapedXml} location(s)`);\n }\n if (stats.xmlTags > 0) {\n lines.push(` - XML Tags: ${stats.xmlTags} location(s)`);\n }\n if (stats.entities > 0) {\n lines.push(` - XML Entities: ${stats.entities} location(s)`);\n }\n if (stats.mixed > 0) {\n lines.push(` - Mixed: ${stats.mixed} location(s)`);\n }\n\n lines.push('');\n lines.push('This corruption typically occurs when XML strings are passed to text methods.');\n lines.push('Instead of: paragraph.addText(\"Text<w:t>1</w:t>\")');\n lines.push('Use: paragraph.addText(\"Text\"); paragraph.addText(\"1\");');\n lines.push('');\n lines.push('To automatically clean text, use: new Run(text, { cleanXmlFromText: true })');\n\n return lines.join('\\n');\n}\n\n/**\n * Checks if text looks like it might be corrupted (less strict check)\n *\n * This is a quick check that can be used for warnings without full analysis.\n *\n * @param text - Text to check\n * @returns True if text might be corrupted\n */\nexport function looksCorrupted(text: string): boolean {\n if (!text || typeof text !== 'string') {\n return false;\n }\n\n // Quick regex checks for common corruption patterns\n return (\n /<\\/?(w|r|p):[a-z]+/i.test(text) ||\n /<\\/?(w|r|p):[a-z]+/i.test(text) ||\n /xml:space="/i.test(text)\n );\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deepEqual.d.ts","sourceRoot":"","sources":["../../src/utils/deepEqual.ts"],"names":[],"mappings":"AAYA,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CA6CzD"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deepEqual = deepEqual;
|
|
4
|
+
function deepEqual(a, b) {
|
|
5
|
+
if (a === b)
|
|
6
|
+
return true;
|
|
7
|
+
if (typeof a === 'number' && typeof b === 'number' && Number.isNaN(a) && Number.isNaN(b)) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
if (a == null || b == null)
|
|
11
|
+
return a === b;
|
|
12
|
+
const typeA = typeof a;
|
|
13
|
+
const typeB = typeof b;
|
|
14
|
+
if (typeA !== typeB)
|
|
15
|
+
return false;
|
|
16
|
+
if (typeA !== 'object')
|
|
17
|
+
return false;
|
|
18
|
+
if (a instanceof Date || b instanceof Date) {
|
|
19
|
+
return a instanceof Date && b instanceof Date && a.getTime() === b.getTime();
|
|
20
|
+
}
|
|
21
|
+
const aIsArr = Array.isArray(a);
|
|
22
|
+
const bIsArr = Array.isArray(b);
|
|
23
|
+
if (aIsArr !== bIsArr)
|
|
24
|
+
return false;
|
|
25
|
+
if (aIsArr && bIsArr) {
|
|
26
|
+
const arrA = a;
|
|
27
|
+
const arrB = b;
|
|
28
|
+
if (arrA.length !== arrB.length)
|
|
29
|
+
return false;
|
|
30
|
+
for (let i = 0; i < arrA.length; i++) {
|
|
31
|
+
if (!deepEqual(arrA[i], arrB[i]))
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
const objA = a;
|
|
37
|
+
const objB = b;
|
|
38
|
+
const keysA = Object.keys(objA);
|
|
39
|
+
const keysB = Object.keys(objB);
|
|
40
|
+
if (keysA.length !== keysB.length)
|
|
41
|
+
return false;
|
|
42
|
+
for (const k of keysA) {
|
|
43
|
+
if (!Object.prototype.hasOwnProperty.call(objB, k))
|
|
44
|
+
return false;
|
|
45
|
+
if (!deepEqual(objA[k], objB[k]))
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=deepEqual.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deepEqual.js","sourceRoot":"","sources":["../../src/utils/deepEqual.ts"],"names":[],"mappings":";;AAYA,8BA6CC;AA7CD,SAAgB,SAAS,CAAC,CAAU,EAAE,CAAU;IAC9C,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAIzB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACzF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAE3C,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC;IACvB,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC;IACvB,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAClC,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAGrC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;QAC3C,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;IAC/E,CAAC;IAGD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAChC,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACpC,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,CAAC,CAAC;QACf,MAAM,IAAI,GAAG,CAAC,CAAC;QACf,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;QACjD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAGD,MAAM,IAAI,GAAG,CAA4B,CAAC;IAC1C,MAAM,IAAI,GAAG,CAA4B,CAAC;IAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAChD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QACjE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;IACjD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["/**\n * Structural equality check for OOXML formatting objects.\n *\n * Replaces `JSON.stringify(a) === JSON.stringify(b)` in hot equality paths\n * (paragraph property merging, tracking-context consolidation). Avoids\n * allocating two large strings per comparison and short-circuits on the\n * first inequality.\n *\n * Handles the value shapes seen in formatting objects: primitives, plain\n * objects, arrays, Date, null/undefined. Symbols and class instances are\n * not part of the formatting model and are compared by reference.\n */\nexport function deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n // NaN === NaN is false in JS; treat structurally as equal so a parse\n // failure that produced two NaNs in equivalent slots doesn't dirty the\n // tracking-context consolidation pass.\n if (typeof a === 'number' && typeof b === 'number' && Number.isNaN(a) && Number.isNaN(b)) {\n return true;\n }\n if (a == null || b == null) return a === b;\n\n const typeA = typeof a;\n const typeB = typeof b;\n if (typeA !== typeB) return false;\n if (typeA !== 'object') return false;\n\n // Date values\n if (a instanceof Date || b instanceof Date) {\n return a instanceof Date && b instanceof Date && a.getTime() === b.getTime();\n }\n\n // Arrays: same length, element-wise equality.\n const aIsArr = Array.isArray(a);\n const bIsArr = Array.isArray(b);\n if (aIsArr !== bIsArr) return false;\n if (aIsArr && bIsArr) {\n const arrA = a;\n const arrB = b;\n if (arrA.length !== arrB.length) return false;\n for (let i = 0; i < arrA.length; i++) {\n if (!deepEqual(arrA[i], arrB[i])) return false;\n }\n return true;\n }\n\n // Plain objects: same key set, deep-equal values.\n const objA = a as Record<string, unknown>;\n const objB = b as Record<string, unknown>;\n const keysA = Object.keys(objA);\n const keysB = Object.keys(objB);\n if (keysA.length !== keysB.length) return false;\n for (const k of keysA) {\n if (!Object.prototype.hasOwnProperty.call(objB, k)) return false;\n if (!deepEqual(objA[k], objB[k])) return false;\n }\n return true;\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.js';
|
|
2
|
+
import type { ListCategory, ListDetectionResult, NumberFormat, BulletFormat } from '../types/list-types.js';
|
|
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,
|
|
1
|
+
{"version":3,"file":"list-detection.d.ts","sourceRoot":"","sources":["../../src/utils/list-detection.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACb,MAAM,wBAAwB,CAAC;AAUhC,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"}
|
|
@@ -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 (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
|
+
{"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.js';\nimport type {\n ListCategory,\n ListDetectionResult,\n NumberFormat,\n BulletFormat,\n} from '../types/list-types.js';\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,5 +1,5 @@
|
|
|
1
1
|
export declare function safeParseInt(value: unknown, defaultValue?: number): number;
|
|
2
|
-
export declare function parseOoxmlBoolean(prop: unknown): boolean;
|
|
2
|
+
export declare function parseOoxmlBoolean(prop: unknown, valAttr?: string): boolean;
|
|
3
3
|
export declare function isExplicitlySet(value: unknown): boolean;
|
|
4
4
|
export declare function parseNumericAttribute(value: unknown, defaultValue: number): number;
|
|
5
5
|
export declare function parseOnOffAttribute(value: unknown, defaultValue?: boolean): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parsingHelpers.d.ts","sourceRoot":"","sources":["../../src/utils/parsingHelpers.ts"],"names":[],"mappings":"AA4BA,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,SAAI,GAAG,MAAM,CAYrE;
|
|
1
|
+
{"version":3,"file":"parsingHelpers.d.ts","sourceRoot":"","sources":["../../src/utils/parsingHelpers.ts"],"names":[],"mappings":"AA4BA,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,SAAI,GAAG,MAAM,CAYrE;AAsCD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,SAAY,GAAG,OAAO,CAkC7E;AA0BD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEvD;AAkBD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAKlF;AAeD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,UAAQ,GAAG,OAAO,CAmBjF"}
|
|
@@ -15,11 +15,11 @@ function safeParseInt(value, defaultValue = 0) {
|
|
|
15
15
|
const parsed = parseInt(String(value), 10);
|
|
16
16
|
return isNaN(parsed) ? defaultValue : parsed;
|
|
17
17
|
}
|
|
18
|
-
function parseOoxmlBoolean(prop) {
|
|
18
|
+
function parseOoxmlBoolean(prop, valAttr = '@_w:val') {
|
|
19
19
|
if (!prop) {
|
|
20
20
|
return false;
|
|
21
21
|
}
|
|
22
|
-
const val = prop[
|
|
22
|
+
const val = prop[valAttr];
|
|
23
23
|
if (val === undefined) {
|
|
24
24
|
return true;
|
|
25
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parsingHelpers.js","sourceRoot":"","sources":["../../src/utils/parsingHelpers.ts"],"names":[],"mappings":";;AA4BA,oCAYC;
|
|
1
|
+
{"version":3,"file":"parsingHelpers.js","sourceRoot":"","sources":["../../src/utils/parsingHelpers.ts"],"names":[],"mappings":";;AA4BA,oCAYC;AAsCD,8CAkCC;AA0BD,0CAEC;AAkBD,sDAKC;AAeD,kDAmBC;AAzKD,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;AAsCD,SAAgB,iBAAiB,CAAC,IAAa,EAAE,OAAO,GAAG,SAAS;IAElE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,KAAK,CAAC;IACf,CAAC;IAID,MAAM,GAAG,GAAI,IAAgC,CAAC,OAAO,CAAC,CAAC;IAIvD,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 * @param valAttr - The attribute key that carries the ST_OnOff literal.\n * Defaults to `\"@_w:val\"` for the main WordprocessingML namespace.\n * Pass `\"@_w14:val\"` for w14 extension elements such as\n * `<w14:checked w14:val=\"1\"/>` (CT_OnOff in the Word 2010+ namespace).\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 XML: <w14:checked w14:val=\"on\"/>\n * parseOoxmlBoolean({ \"@_w14:val\": \"on\" }, \"@_w14:val\") // true\n *\n * // For absent element\n * parseOoxmlBoolean(undefined) // false\n */\nexport function parseOoxmlBoolean(prop: unknown, valAttr = '@_w:val'): boolean {\n // Absent element = false\n if (!prop) {\n return false;\n }\n\n // Get the val attribute value (w:val by default, w14:val or similar for\n // extension namespaces).\n const val = (prop as Record<string, unknown>)[valAttr];\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"]}
|
package/dist/utils/validation.js
CHANGED
|
@@ -20,14 +20,14 @@ exports.detectXmlInText = detectXmlInText;
|
|
|
20
20
|
exports.cleanXmlFromText = cleanXmlFromText;
|
|
21
21
|
exports.validateRunText = validateRunText;
|
|
22
22
|
exports.sanitizeHyperlinkUrl = sanitizeHyperlinkUrl;
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
23
|
+
const types_js_1 = require("../zip/types.js");
|
|
24
|
+
const errors_js_1 = require("../zip/errors.js");
|
|
25
|
+
const logger_js_1 = require("./logger.js");
|
|
26
26
|
function validateDocxStructure(filePaths) {
|
|
27
27
|
const fileSet = new Set(filePaths);
|
|
28
|
-
for (const requiredFile of
|
|
28
|
+
for (const requiredFile of types_js_1.REQUIRED_DOCX_FILES) {
|
|
29
29
|
if (!fileSet.has(requiredFile)) {
|
|
30
|
-
throw new
|
|
30
|
+
throw new errors_js_1.MissingRequiredFileError(requiredFile);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
}
|
|
@@ -268,8 +268,8 @@ function validateRunText(text, options = {}) {
|
|
|
268
268
|
}
|
|
269
269
|
if (warnToConsole && result.warnings.length > 0 && typeof console !== 'undefined') {
|
|
270
270
|
const contextStr = context ? ` [${context}]` : '';
|
|
271
|
-
|
|
272
|
-
result.warnings.forEach((warning) =>
|
|
271
|
+
logger_js_1.defaultLogger.warn(`DocXML Text Validation Warning${contextStr}:`);
|
|
272
|
+
result.warnings.forEach((warning) => logger_js_1.defaultLogger.warn(` - ${warning}`));
|
|
273
273
|
}
|
|
274
274
|
return result;
|
|
275
275
|
}
|