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