@fin.cx/einvoice 5.0.2
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/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/classes.decoder.d.ts +40 -0
- package/dist_ts/classes.decoder.js +320 -0
- package/dist_ts/classes.encoder.d.ts +51 -0
- package/dist_ts/classes.encoder.js +293 -0
- package/dist_ts/classes.xinvoice.d.ts +136 -0
- package/dist_ts/classes.xinvoice.js +352 -0
- package/dist_ts/einvoice.d.ts +217 -0
- package/dist_ts/einvoice.js +505 -0
- package/dist_ts/errors.d.ts +121 -0
- package/dist_ts/errors.js +241 -0
- package/dist_ts/formats/base/base.decoder.d.ts +32 -0
- package/dist_ts/formats/base/base.decoder.js +52 -0
- package/dist_ts/formats/base/base.encoder.d.ts +13 -0
- package/dist_ts/formats/base/base.encoder.js +7 -0
- package/dist_ts/formats/base/base.validator.d.ts +44 -0
- package/dist_ts/formats/base/base.validator.js +39 -0
- package/dist_ts/formats/base.decoder.d.ts +19 -0
- package/dist_ts/formats/base.decoder.js +130 -0
- package/dist_ts/formats/base.validator.d.ts +44 -0
- package/dist_ts/formats/base.validator.js +39 -0
- package/dist_ts/formats/cii/cii.decoder.d.ts +61 -0
- package/dist_ts/formats/cii/cii.decoder.js +111 -0
- package/dist_ts/formats/cii/cii.encoder.d.ts +43 -0
- package/dist_ts/formats/cii/cii.encoder.js +48 -0
- package/dist_ts/formats/cii/cii.types.d.ts +31 -0
- package/dist_ts/formats/cii/cii.types.js +40 -0
- package/dist_ts/formats/cii/cii.validator.d.ts +56 -0
- package/dist_ts/formats/cii/cii.validator.js +146 -0
- package/dist_ts/formats/cii/facturx/facturx.decoder.d.ts +43 -0
- package/dist_ts/formats/cii/facturx/facturx.decoder.js +207 -0
- package/dist_ts/formats/cii/facturx/facturx.encoder.d.ts +82 -0
- package/dist_ts/formats/cii/facturx/facturx.encoder.js +400 -0
- package/dist_ts/formats/cii/facturx/facturx.types.d.ts +10 -0
- package/dist_ts/formats/cii/facturx/facturx.types.js +15 -0
- package/dist_ts/formats/cii/facturx/facturx.validator.d.ts +32 -0
- package/dist_ts/formats/cii/facturx/facturx.validator.js +138 -0
- package/dist_ts/formats/cii/zugferd/zugferd.decoder.d.ts +43 -0
- package/dist_ts/formats/cii/zugferd/zugferd.decoder.js +218 -0
- package/dist_ts/formats/cii/zugferd/zugferd.encoder.d.ts +97 -0
- package/dist_ts/formats/cii/zugferd/zugferd.encoder.js +550 -0
- package/dist_ts/formats/cii/zugferd/zugferd.types.d.ts +10 -0
- package/dist_ts/formats/cii/zugferd/zugferd.types.js +15 -0
- package/dist_ts/formats/cii/zugferd/zugferd.v1.decoder.d.ts +49 -0
- package/dist_ts/formats/cii/zugferd/zugferd.v1.decoder.js +229 -0
- package/dist_ts/formats/cii/zugferd/zugferd.validator.d.ts +16 -0
- package/dist_ts/formats/cii/zugferd/zugferd.validator.js +29 -0
- package/dist_ts/formats/decoder.factory.d.ts +15 -0
- package/dist_ts/formats/decoder.factory.js +46 -0
- package/dist_ts/formats/factories/decoder.factory.d.ts +13 -0
- package/dist_ts/formats/factories/decoder.factory.js +56 -0
- package/dist_ts/formats/factories/encoder.factory.d.ts +14 -0
- package/dist_ts/formats/factories/encoder.factory.js +40 -0
- package/dist_ts/formats/factories/validator.factory.d.ts +12 -0
- package/dist_ts/formats/factories/validator.factory.js +110 -0
- package/dist_ts/formats/factorx.decoder.d.ts +18 -0
- package/dist_ts/formats/factorx.decoder.js +178 -0
- package/dist_ts/formats/factorx.encoder.d.ts +51 -0
- package/dist_ts/formats/factorx.encoder.js +293 -0
- package/dist_ts/formats/facturx.decoder.d.ts +18 -0
- package/dist_ts/formats/facturx.decoder.js +210 -0
- package/dist_ts/formats/facturx.encoder.d.ts +51 -0
- package/dist_ts/formats/facturx.encoder.js +293 -0
- package/dist_ts/formats/facturx.validator.d.ts +67 -0
- package/dist_ts/formats/facturx.validator.js +266 -0
- package/dist_ts/formats/pdf/extractors/associated.extractor.d.ts +14 -0
- package/dist_ts/formats/pdf/extractors/associated.extractor.js +68 -0
- package/dist_ts/formats/pdf/extractors/base.extractor.d.ts +92 -0
- package/dist_ts/formats/pdf/extractors/base.extractor.js +319 -0
- package/dist_ts/formats/pdf/extractors/index.d.ts +4 -0
- package/dist_ts/formats/pdf/extractors/index.js +5 -0
- package/dist_ts/formats/pdf/extractors/standard.extractor.d.ts +13 -0
- package/dist_ts/formats/pdf/extractors/standard.extractor.js +74 -0
- package/dist_ts/formats/pdf/extractors/text.extractor.d.ts +45 -0
- package/dist_ts/formats/pdf/extractors/text.extractor.js +151 -0
- package/dist_ts/formats/pdf/pdf.embedder.d.ts +69 -0
- package/dist_ts/formats/pdf/pdf.embedder.js +183 -0
- package/dist_ts/formats/pdf/pdf.extractor.d.ts +49 -0
- package/dist_ts/formats/pdf/pdf.extractor.js +98 -0
- package/dist_ts/formats/pdf/robust-pdf.extractor.d.ts +40 -0
- package/dist_ts/formats/pdf/robust-pdf.extractor.js +324 -0
- package/dist_ts/formats/ubl/en16931.ubl.validator.d.ts +18 -0
- package/dist_ts/formats/ubl/en16931.ubl.validator.js +169 -0
- package/dist_ts/formats/ubl/generic/ubl.encoder.d.ts +151 -0
- package/dist_ts/formats/ubl/generic/ubl.encoder.js +892 -0
- package/dist_ts/formats/ubl/ubl.decoder.d.ts +61 -0
- package/dist_ts/formats/ubl/ubl.decoder.js +95 -0
- package/dist_ts/formats/ubl/ubl.encoder.d.ts +38 -0
- package/dist_ts/formats/ubl/ubl.encoder.js +46 -0
- package/dist_ts/formats/ubl/ubl.types.d.ts +16 -0
- package/dist_ts/formats/ubl/ubl.types.js +21 -0
- package/dist_ts/formats/ubl/ubl.validator.d.ts +50 -0
- package/dist_ts/formats/ubl/ubl.validator.js +112 -0
- package/dist_ts/formats/ubl/xrechnung/xrechnung.decoder.d.ts +34 -0
- package/dist_ts/formats/ubl/xrechnung/xrechnung.decoder.js +424 -0
- package/dist_ts/formats/ubl/xrechnung/xrechnung.encoder.d.ts +75 -0
- package/dist_ts/formats/ubl/xrechnung/xrechnung.encoder.js +555 -0
- package/dist_ts/formats/ubl/xrechnung.validator.d.ts +15 -0
- package/dist_ts/formats/ubl/xrechnung.validator.js +107 -0
- package/dist_ts/formats/ubl.validator.d.ts +82 -0
- package/dist_ts/formats/ubl.validator.js +306 -0
- package/dist_ts/formats/utils/format.detector.d.ts +62 -0
- package/dist_ts/formats/utils/format.detector.js +249 -0
- package/dist_ts/formats/validation/en16931.validator.d.ts +23 -0
- package/dist_ts/formats/validation/en16931.validator.js +119 -0
- package/dist_ts/formats/validator.factory.d.ts +18 -0
- package/dist_ts/formats/validator.factory.js +78 -0
- package/dist_ts/formats/xinvoice.decoder.d.ts +28 -0
- package/dist_ts/formats/xinvoice.decoder.js +332 -0
- package/dist_ts/formats/xinvoice.encoder.d.ts +19 -0
- package/dist_ts/formats/xinvoice.encoder.js +282 -0
- package/dist_ts/index.d.ts +51 -0
- package/dist_ts/index.js +90 -0
- package/dist_ts/interfaces/common.d.ts +79 -0
- package/dist_ts/interfaces/common.js +24 -0
- package/dist_ts/interfaces.d.ts +87 -0
- package/dist_ts/interfaces.js +23 -0
- package/dist_ts/plugins.d.ts +14 -0
- package/dist_ts/plugins.js +31 -0
- package/npmextra.json +35 -0
- package/package.json +71 -0
- package/readme.hints.md +1107 -0
- package/readme.howtofixtests.md +38 -0
- package/readme.literature.md +1 -0
- package/readme.md +998 -0
- package/readme.plan.md +481 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/einvoice.ts +603 -0
- package/ts/errors.ts +341 -0
- package/ts/formats/base/base.decoder.ts +68 -0
- package/ts/formats/base/base.encoder.ts +14 -0
- package/ts/formats/base/base.validator.ts +64 -0
- package/ts/formats/cii/cii.decoder.ts +139 -0
- package/ts/formats/cii/cii.encoder.ts +64 -0
- package/ts/formats/cii/cii.types.ts +44 -0
- package/ts/formats/cii/cii.validator.ts +171 -0
- package/ts/formats/cii/facturx/facturx.decoder.ts +243 -0
- package/ts/formats/cii/facturx/facturx.encoder.ts +483 -0
- package/ts/formats/cii/facturx/facturx.types.ts +18 -0
- package/ts/formats/cii/facturx/facturx.validator.ts +180 -0
- package/ts/formats/cii/zugferd/zugferd.decoder.ts +256 -0
- package/ts/formats/cii/zugferd/zugferd.encoder.ts +661 -0
- package/ts/formats/cii/zugferd/zugferd.types.ts +18 -0
- package/ts/formats/cii/zugferd/zugferd.v1.decoder.ts +267 -0
- package/ts/formats/cii/zugferd/zugferd.validator.ts +31 -0
- package/ts/formats/factories/decoder.factory.ts +62 -0
- package/ts/formats/factories/encoder.factory.ts +47 -0
- package/ts/formats/factories/validator.factory.ts +134 -0
- package/ts/formats/pdf/extractors/associated.extractor.ts +78 -0
- package/ts/formats/pdf/extractors/base.extractor.ts +355 -0
- package/ts/formats/pdf/extractors/index.ts +4 -0
- package/ts/formats/pdf/extractors/standard.extractor.ts +86 -0
- package/ts/formats/pdf/extractors/text.extractor.ts +162 -0
- package/ts/formats/pdf/pdf.embedder.ts +242 -0
- package/ts/formats/pdf/pdf.extractor.ts +141 -0
- package/ts/formats/ubl/en16931.ubl.validator.ts +216 -0
- package/ts/formats/ubl/generic/ubl.encoder.ts +1041 -0
- package/ts/formats/ubl/ubl.decoder.ts +121 -0
- package/ts/formats/ubl/ubl.encoder.ts +63 -0
- package/ts/formats/ubl/ubl.types.ts +22 -0
- package/ts/formats/ubl/ubl.validator.ts +133 -0
- package/ts/formats/ubl/xrechnung/xrechnung.decoder.ts +471 -0
- package/ts/formats/ubl/xrechnung/xrechnung.encoder.ts +619 -0
- package/ts/formats/ubl/xrechnung.validator.ts +185 -0
- package/ts/formats/utils/format.detector.ts +306 -0
- package/ts/formats/validation/en16931.validator.ts +135 -0
- package/ts/index.ts +164 -0
- package/ts/interfaces/common.ts +90 -0
- package/ts/interfaces.ts +98 -0
- package/ts/plugins.ts +61 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { BaseXMLExtractor } from './base.extractor.js';
|
|
2
|
+
/**
|
|
3
|
+
* Text-based XML extractor for PDF documents
|
|
4
|
+
* Extracts XML by searching for XML patterns in the PDF text
|
|
5
|
+
* Used as a fallback when other extraction methods fail
|
|
6
|
+
*/
|
|
7
|
+
export class TextXMLExtractor extends BaseXMLExtractor {
|
|
8
|
+
constructor() {
|
|
9
|
+
super(...arguments);
|
|
10
|
+
// Maximum chunk size to process at once (4MB)
|
|
11
|
+
this.CHUNK_SIZE = 4 * 1024 * 1024;
|
|
12
|
+
// Maximum number of chunks to check (effective 20MB search limit)
|
|
13
|
+
this.MAX_CHUNKS = 5;
|
|
14
|
+
// Common XML patterns to look for
|
|
15
|
+
this.XML_PATTERNS = [
|
|
16
|
+
'<?xml',
|
|
17
|
+
'<CrossIndustryInvoice',
|
|
18
|
+
'<CrossIndustryDocument',
|
|
19
|
+
'<Invoice',
|
|
20
|
+
'<CreditNote',
|
|
21
|
+
'<rsm:CrossIndustryInvoice',
|
|
22
|
+
'<rsm:CrossIndustryDocument',
|
|
23
|
+
'<ram:CrossIndustryDocument',
|
|
24
|
+
'<ubl:Invoice',
|
|
25
|
+
'<ubl:CreditNote',
|
|
26
|
+
'<FatturaElettronica'
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Extract XML from a PDF buffer by searching for XML patterns in the text
|
|
31
|
+
* Uses a chunked approach to handle large files efficiently
|
|
32
|
+
* @param pdfBuffer PDF buffer
|
|
33
|
+
* @returns XML content or null if not found
|
|
34
|
+
*/
|
|
35
|
+
async extractXml(pdfBuffer) {
|
|
36
|
+
try {
|
|
37
|
+
console.log('Attempting text-based XML extraction from PDF...');
|
|
38
|
+
// Convert Buffer to Uint8Array if needed
|
|
39
|
+
const buffer = Buffer.isBuffer(pdfBuffer) ? new Uint8Array(pdfBuffer) : pdfBuffer;
|
|
40
|
+
// Try extracting XML using the chunked approach
|
|
41
|
+
return this.extractXmlFromBufferChunked(buffer);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
console.error('Error in text-based extraction:', error);
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Extract XML from buffer using a chunked approach
|
|
50
|
+
* This helps avoid memory issues with large PDFs
|
|
51
|
+
* @param buffer Buffer to search in
|
|
52
|
+
* @returns XML content or null if not found
|
|
53
|
+
*/
|
|
54
|
+
extractXmlFromBufferChunked(buffer) {
|
|
55
|
+
// Process the PDF in chunks
|
|
56
|
+
for (let chunkIndex = 0; chunkIndex < this.MAX_CHUNKS; chunkIndex++) {
|
|
57
|
+
const startPos = chunkIndex * this.CHUNK_SIZE;
|
|
58
|
+
if (startPos >= buffer.length)
|
|
59
|
+
break;
|
|
60
|
+
const endPos = Math.min(startPos + this.CHUNK_SIZE, buffer.length);
|
|
61
|
+
const chunk = buffer.slice(startPos, endPos);
|
|
62
|
+
// Try to extract XML from this chunk
|
|
63
|
+
const chunkResult = this.processChunk(chunk, startPos);
|
|
64
|
+
if (chunkResult) {
|
|
65
|
+
return chunkResult;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
console.warn('No valid XML found in any chunk of the PDF');
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Process a single chunk of the PDF buffer
|
|
73
|
+
* @param chunk Chunk buffer to process
|
|
74
|
+
* @param chunkOffset Offset position of the chunk in the original buffer
|
|
75
|
+
* @returns XML content or null if not found
|
|
76
|
+
*/
|
|
77
|
+
processChunk(chunk, chunkOffset) {
|
|
78
|
+
try {
|
|
79
|
+
// First try UTF-8 encoding for this chunk
|
|
80
|
+
const utf8String = this.decodeBufferToString(chunk, 'utf-8');
|
|
81
|
+
let xmlContent = this.searchForXmlInString(utf8String);
|
|
82
|
+
if (xmlContent) {
|
|
83
|
+
console.log(`Found XML content in chunk at offset ${chunkOffset} using UTF-8 encoding`);
|
|
84
|
+
return xmlContent;
|
|
85
|
+
}
|
|
86
|
+
// If UTF-8 fails, try Latin-1 (ISO-8859-1) which can handle binary better
|
|
87
|
+
const latin1String = this.decodeBufferToString(chunk, 'latin1');
|
|
88
|
+
xmlContent = this.searchForXmlInString(latin1String);
|
|
89
|
+
if (xmlContent) {
|
|
90
|
+
console.log(`Found XML content in chunk at offset ${chunkOffset} using Latin-1 encoding`);
|
|
91
|
+
return xmlContent;
|
|
92
|
+
}
|
|
93
|
+
// No XML found in this chunk
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
console.warn(`Error processing chunk at offset ${chunkOffset}:`, error);
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Safely decode a buffer to string using the specified encoding
|
|
103
|
+
* @param buffer Buffer to decode
|
|
104
|
+
* @param encoding Encoding to use ('utf-8' or 'latin1')
|
|
105
|
+
* @returns Decoded string
|
|
106
|
+
*/
|
|
107
|
+
decodeBufferToString(buffer, encoding) {
|
|
108
|
+
try {
|
|
109
|
+
if (encoding === 'utf-8') {
|
|
110
|
+
return new TextDecoder('utf-8', { fatal: false }).decode(buffer);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
// For Latin-1 we can use a direct mapping (bytes 0-255 map directly to code points 0-255)
|
|
114
|
+
// This is more reliable for binary data than TextDecoder for legacy encodings
|
|
115
|
+
return Array.from(buffer)
|
|
116
|
+
.map(byte => String.fromCharCode(byte))
|
|
117
|
+
.join('');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
console.warn(`Error decoding buffer using ${encoding}:`, error);
|
|
122
|
+
// Return empty string on error to allow processing to continue
|
|
123
|
+
return '';
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Search for XML patterns in a string
|
|
128
|
+
* @param content String to search in
|
|
129
|
+
* @returns XML content or null if not found
|
|
130
|
+
*/
|
|
131
|
+
searchForXmlInString(content) {
|
|
132
|
+
if (!content)
|
|
133
|
+
return null;
|
|
134
|
+
// Search for each XML pattern
|
|
135
|
+
for (const pattern of this.XML_PATTERNS) {
|
|
136
|
+
const patternIndex = content.indexOf(pattern);
|
|
137
|
+
if (patternIndex !== -1) {
|
|
138
|
+
console.log(`Found XML pattern "${pattern}" at position ${patternIndex}`);
|
|
139
|
+
// Try to extract the XML content starting from the pattern position
|
|
140
|
+
const xmlContent = this.extractXmlFromString(content, patternIndex);
|
|
141
|
+
// Validate the extracted content
|
|
142
|
+
if (xmlContent && this.isValidXml(xmlContent)) {
|
|
143
|
+
console.log('Successfully extracted and validated XML from text');
|
|
144
|
+
return xmlContent;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC5leHRyYWN0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90cy9mb3JtYXRzL3BkZi9leHRyYWN0b3JzL3RleHQuZXh0cmFjdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXZEOzs7O0dBSUc7QUFDSCxNQUFNLE9BQU8sZ0JBQWlCLFNBQVEsZ0JBQWdCO0lBQXREOztRQUNFLDhDQUE4QztRQUM3QixlQUFVLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7UUFFOUMsa0VBQWtFO1FBQ2pELGVBQVUsR0FBRyxDQUFDLENBQUM7UUFFaEMsa0NBQWtDO1FBQ2pCLGlCQUFZLEdBQUc7WUFDOUIsT0FBTztZQUNQLHVCQUF1QjtZQUN2Qix3QkFBd0I7WUFDeEIsVUFBVTtZQUNWLGFBQWE7WUFDYiwyQkFBMkI7WUFDM0IsNEJBQTRCO1lBQzVCLDRCQUE0QjtZQUM1QixjQUFjO1lBQ2QsaUJBQWlCO1lBQ2pCLHFCQUFxQjtTQUN0QixDQUFDO0lBc0lKLENBQUM7SUFwSUM7Ozs7O09BS0c7SUFDSSxLQUFLLENBQUMsVUFBVSxDQUFDLFNBQThCO1FBQ3BELElBQUksQ0FBQztZQUNILE9BQU8sQ0FBQyxHQUFHLENBQUMsa0RBQWtELENBQUMsQ0FBQztZQUVoRSx5Q0FBeUM7WUFDekMsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUVsRixnREFBZ0Q7WUFDaEQsT0FBTyxJQUFJLENBQUMsMkJBQTJCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbEQsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPLENBQUMsS0FBSyxDQUFDLGlDQUFpQyxFQUFFLEtBQUss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
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { IPdf } from '../../interfaces/common.js';
|
|
2
|
+
/**
|
|
3
|
+
* Error types for PDF embedding operations
|
|
4
|
+
*/
|
|
5
|
+
export declare enum PDFEmbedError {
|
|
6
|
+
LOAD_ERROR = "PDF loading failed",
|
|
7
|
+
EMBED_ERROR = "XML embedding failed",
|
|
8
|
+
SAVE_ERROR = "PDF saving failed",
|
|
9
|
+
INVALID_INPUT = "Invalid input parameters"
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Result of a PDF embedding operation
|
|
13
|
+
*/
|
|
14
|
+
export interface PDFEmbedResult {
|
|
15
|
+
success: boolean;
|
|
16
|
+
data?: Uint8Array;
|
|
17
|
+
pdf?: IPdf;
|
|
18
|
+
error?: {
|
|
19
|
+
type: PDFEmbedError;
|
|
20
|
+
message: string;
|
|
21
|
+
originalError?: Error;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Class for embedding XML into PDF files
|
|
26
|
+
* Provides robust error handling and support for different PDF formats
|
|
27
|
+
*/
|
|
28
|
+
export declare class PDFEmbedder {
|
|
29
|
+
/**
|
|
30
|
+
* Embeds XML into a PDF
|
|
31
|
+
* @param pdfBuffer PDF buffer
|
|
32
|
+
* @param xmlContent XML content to embed
|
|
33
|
+
* @param filename Filename for the embedded XML
|
|
34
|
+
* @param description Description for the embedded XML
|
|
35
|
+
* @returns Result with either modified PDF buffer or error information
|
|
36
|
+
*/
|
|
37
|
+
embedXml(pdfBuffer: Uint8Array | Buffer, xmlContent: string, filename?: string, description?: string): Promise<PDFEmbedResult>;
|
|
38
|
+
/**
|
|
39
|
+
* Creates an IPdf object with embedded XML
|
|
40
|
+
* @param pdfBuffer PDF buffer
|
|
41
|
+
* @param xmlContent XML content to embed
|
|
42
|
+
* @param filename Filename for the embedded XML
|
|
43
|
+
* @param description Description for the embedded XML
|
|
44
|
+
* @param pdfName Name for the PDF
|
|
45
|
+
* @param pdfId ID for the PDF
|
|
46
|
+
* @returns Result with either IPdf object or error information
|
|
47
|
+
*/
|
|
48
|
+
createPdfWithXml(pdfBuffer: Uint8Array | Buffer, xmlContent: string, filename?: string, description?: string, pdfName?: string, pdfId?: string): Promise<PDFEmbedResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Ensures the filename is normalized according to PDF/A requirements
|
|
51
|
+
* @param filename Filename to normalize
|
|
52
|
+
* @returns Normalized filename
|
|
53
|
+
*/
|
|
54
|
+
private normalizeFilename;
|
|
55
|
+
/**
|
|
56
|
+
* Tries to detect the format of the XML content
|
|
57
|
+
* @param xmlContent XML content
|
|
58
|
+
* @returns Format string or undefined
|
|
59
|
+
*/
|
|
60
|
+
private detectPdfFormat;
|
|
61
|
+
/**
|
|
62
|
+
* Creates an error result object
|
|
63
|
+
* @param type Error type
|
|
64
|
+
* @param message Error message
|
|
65
|
+
* @param originalError Original error object
|
|
66
|
+
* @returns Error result
|
|
67
|
+
*/
|
|
68
|
+
private createErrorResult;
|
|
69
|
+
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { PDFDocument, AFRelationship } from '../../plugins.js';
|
|
2
|
+
/**
|
|
3
|
+
* Error types for PDF embedding operations
|
|
4
|
+
*/
|
|
5
|
+
export var PDFEmbedError;
|
|
6
|
+
(function (PDFEmbedError) {
|
|
7
|
+
PDFEmbedError["LOAD_ERROR"] = "PDF loading failed";
|
|
8
|
+
PDFEmbedError["EMBED_ERROR"] = "XML embedding failed";
|
|
9
|
+
PDFEmbedError["SAVE_ERROR"] = "PDF saving failed";
|
|
10
|
+
PDFEmbedError["INVALID_INPUT"] = "Invalid input parameters";
|
|
11
|
+
})(PDFEmbedError || (PDFEmbedError = {}));
|
|
12
|
+
/**
|
|
13
|
+
* Class for embedding XML into PDF files
|
|
14
|
+
* Provides robust error handling and support for different PDF formats
|
|
15
|
+
*/
|
|
16
|
+
export class PDFEmbedder {
|
|
17
|
+
/**
|
|
18
|
+
* Embeds XML into a PDF
|
|
19
|
+
* @param pdfBuffer PDF buffer
|
|
20
|
+
* @param xmlContent XML content to embed
|
|
21
|
+
* @param filename Filename for the embedded XML
|
|
22
|
+
* @param description Description for the embedded XML
|
|
23
|
+
* @returns Result with either modified PDF buffer or error information
|
|
24
|
+
*/
|
|
25
|
+
async embedXml(pdfBuffer, xmlContent, filename = 'invoice.xml', description = 'XML Invoice') {
|
|
26
|
+
try {
|
|
27
|
+
// Validate inputs
|
|
28
|
+
if (!pdfBuffer || pdfBuffer.length === 0) {
|
|
29
|
+
return this.createErrorResult(PDFEmbedError.INVALID_INPUT, 'PDF buffer is empty or undefined');
|
|
30
|
+
}
|
|
31
|
+
if (!xmlContent) {
|
|
32
|
+
return this.createErrorResult(PDFEmbedError.INVALID_INPUT, 'XML content is empty or undefined');
|
|
33
|
+
}
|
|
34
|
+
// Ensure buffer is Uint8Array
|
|
35
|
+
const pdfBufferArray = Buffer.isBuffer(pdfBuffer) ? new Uint8Array(pdfBuffer) : pdfBuffer;
|
|
36
|
+
// Load the PDF
|
|
37
|
+
let pdfDoc;
|
|
38
|
+
try {
|
|
39
|
+
pdfDoc = await PDFDocument.load(pdfBufferArray, {
|
|
40
|
+
ignoreEncryption: true, // Try to load encrypted PDFs
|
|
41
|
+
updateMetadata: false // Don't automatically update metadata
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
return this.createErrorResult(PDFEmbedError.LOAD_ERROR, `Failed to load PDF: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : undefined);
|
|
46
|
+
}
|
|
47
|
+
// Normalize filename (lowercase with XML extension)
|
|
48
|
+
filename = this.normalizeFilename(filename);
|
|
49
|
+
// Convert the XML string to a Uint8Array
|
|
50
|
+
const xmlBuffer = new TextEncoder().encode(xmlContent);
|
|
51
|
+
try {
|
|
52
|
+
// Use pdf-lib's .attach() to embed the XML
|
|
53
|
+
pdfDoc.attach(xmlBuffer, filename, {
|
|
54
|
+
mimeType: 'text/xml',
|
|
55
|
+
description: description,
|
|
56
|
+
creationDate: new Date(),
|
|
57
|
+
modificationDate: new Date(),
|
|
58
|
+
afRelationship: AFRelationship.Alternative,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
return this.createErrorResult(PDFEmbedError.EMBED_ERROR, `Failed to embed XML: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : undefined);
|
|
63
|
+
}
|
|
64
|
+
// Save the modified PDF
|
|
65
|
+
let modifiedPdfBytes;
|
|
66
|
+
try {
|
|
67
|
+
modifiedPdfBytes = await pdfDoc.save({
|
|
68
|
+
addDefaultPage: false, // Don't add a page if the document is empty
|
|
69
|
+
useObjectStreams: false, // Better compatibility with older PDF readers
|
|
70
|
+
updateFieldAppearances: false // Don't update form fields
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
return this.createErrorResult(PDFEmbedError.SAVE_ERROR, `Failed to save modified PDF: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : undefined);
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
success: true,
|
|
78
|
+
data: modifiedPdfBytes
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
// Catch any uncaught errors
|
|
83
|
+
return this.createErrorResult(PDFEmbedError.EMBED_ERROR, `Unexpected error during XML embedding: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : undefined);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Creates an IPdf object with embedded XML
|
|
88
|
+
* @param pdfBuffer PDF buffer
|
|
89
|
+
* @param xmlContent XML content to embed
|
|
90
|
+
* @param filename Filename for the embedded XML
|
|
91
|
+
* @param description Description for the embedded XML
|
|
92
|
+
* @param pdfName Name for the PDF
|
|
93
|
+
* @param pdfId ID for the PDF
|
|
94
|
+
* @returns Result with either IPdf object or error information
|
|
95
|
+
*/
|
|
96
|
+
async createPdfWithXml(pdfBuffer, xmlContent, filename = 'invoice.xml', description = 'XML Invoice', pdfName = 'invoice.pdf', pdfId = `invoice-${Date.now()}`) {
|
|
97
|
+
// Embed XML into PDF
|
|
98
|
+
const embedResult = await this.embedXml(pdfBuffer, xmlContent, filename, description);
|
|
99
|
+
// If embedding failed, return the error
|
|
100
|
+
if (!embedResult.success || !embedResult.data) {
|
|
101
|
+
return embedResult;
|
|
102
|
+
}
|
|
103
|
+
// Create IPdf object
|
|
104
|
+
const pdfObject = {
|
|
105
|
+
name: pdfName,
|
|
106
|
+
id: pdfId,
|
|
107
|
+
metadata: {
|
|
108
|
+
textExtraction: '',
|
|
109
|
+
format: this.detectPdfFormat(xmlContent),
|
|
110
|
+
embeddedXml: {
|
|
111
|
+
filename: filename,
|
|
112
|
+
description: description
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
buffer: embedResult.data
|
|
116
|
+
};
|
|
117
|
+
return {
|
|
118
|
+
success: true,
|
|
119
|
+
pdf: pdfObject
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Ensures the filename is normalized according to PDF/A requirements
|
|
124
|
+
* @param filename Filename to normalize
|
|
125
|
+
* @returns Normalized filename
|
|
126
|
+
*/
|
|
127
|
+
normalizeFilename(filename) {
|
|
128
|
+
// Convert to lowercase
|
|
129
|
+
let normalized = filename.toLowerCase();
|
|
130
|
+
// Ensure it has .xml extension
|
|
131
|
+
if (!normalized.endsWith('.xml')) {
|
|
132
|
+
normalized = normalized.replace(/\.[^/.]+$/, '') + '.xml';
|
|
133
|
+
}
|
|
134
|
+
// Replace invalid characters
|
|
135
|
+
normalized = normalized.replace(/[^a-z0-9_.-]/g, '_');
|
|
136
|
+
return normalized;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Tries to detect the format of the XML content
|
|
140
|
+
* @param xmlContent XML content
|
|
141
|
+
* @returns Format string or undefined
|
|
142
|
+
*/
|
|
143
|
+
detectPdfFormat(xmlContent) {
|
|
144
|
+
if (xmlContent.includes('factur-x.eu') || xmlContent.includes('factur-x.xml')) {
|
|
145
|
+
return 'factur-x';
|
|
146
|
+
}
|
|
147
|
+
else if (xmlContent.includes('zugferd') || xmlContent.includes('ZUGFeRD')) {
|
|
148
|
+
return 'zugferd';
|
|
149
|
+
}
|
|
150
|
+
else if (xmlContent.includes('xrechnung')) {
|
|
151
|
+
return 'xrechnung';
|
|
152
|
+
}
|
|
153
|
+
else if (xmlContent.includes('<Invoice') || xmlContent.includes('<CreditNote')) {
|
|
154
|
+
return 'ubl';
|
|
155
|
+
}
|
|
156
|
+
else if (xmlContent.includes('FatturaElettronica')) {
|
|
157
|
+
return 'fatturapa';
|
|
158
|
+
}
|
|
159
|
+
return undefined;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Creates an error result object
|
|
163
|
+
* @param type Error type
|
|
164
|
+
* @param message Error message
|
|
165
|
+
* @param originalError Original error object
|
|
166
|
+
* @returns Error result
|
|
167
|
+
*/
|
|
168
|
+
createErrorResult(type, message, originalError) {
|
|
169
|
+
console.error(`PDF Embedder Error (${type}): ${message}`);
|
|
170
|
+
if (originalError) {
|
|
171
|
+
console.error(originalError);
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
success: false,
|
|
175
|
+
error: {
|
|
176
|
+
type,
|
|
177
|
+
message,
|
|
178
|
+
originalError
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGRmLmVtYmVkZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvZm9ybWF0cy9wZGYvcGRmLmVtYmVkZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFHL0Q7O0dBRUc7QUFDSCxNQUFNLENBQU4sSUFBWSxhQUtYO0FBTEQsV0FBWSxhQUFhO0lBQ3ZCLGtEQUFpQyxDQUFBO0lBQ2pDLHFEQUFvQyxDQUFBO0lBQ3BDLGlEQUFnQyxDQUFBO0lBQ2hDLDJEQUEwQyxDQUFBO0FBQzVDLENBQUMsRUFMVyxhQUFhLEtBQWIsYUFBYSxRQUt4QjtBQWdCRDs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sV0FBVztJQUN0Qjs7Ozs7OztPQU9HO0lBQ0ksS0FBSyxDQUFDLFFBQVEsQ0FDbkIsU0FBOEIsRUFDOUIsVUFBa0IsRUFDbEIsV0FBbUIsYUFBYSxFQUNoQyxjQUFzQixhQUFhO1FBRW5DLElBQUksQ0FBQztZQUNILGtCQUFrQjtZQUNsQixJQUFJLENBQUMsU0FBUyxJQUFJLFNBQVMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3pDLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDLGFBQWEsQ0FBQyxhQUFhLEVBQUUsa0NBQWtDLENBQUMsQ0FBQztZQUNqRyxDQUFDO1lBRUQsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUNoQixPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLENBQUMsYUFBYSxFQUFFLG1DQUFtQyxDQUFDLENBQUM7WUFDbEcsQ0FBQztZQUVELDhCQUE4QjtZQUM5QixNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBRTFGLGVBQWU7WUFDZixJ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
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { InvoiceFormat } from '../../interfaces/common.js';
|
|
2
|
+
/**
|
|
3
|
+
* Error types for PDF extraction operations
|
|
4
|
+
*/
|
|
5
|
+
export declare enum PDFExtractError {
|
|
6
|
+
EXTRACT_ERROR = "XML extraction failed",
|
|
7
|
+
INVALID_INPUT = "Invalid input parameters",
|
|
8
|
+
NO_XML_FOUND = "No XML found in PDF"
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Result of a PDF extraction operation
|
|
12
|
+
*/
|
|
13
|
+
export interface PDFExtractResult {
|
|
14
|
+
success: boolean;
|
|
15
|
+
xml?: string;
|
|
16
|
+
format?: InvoiceFormat;
|
|
17
|
+
extractorUsed?: string;
|
|
18
|
+
error?: {
|
|
19
|
+
type: PDFExtractError;
|
|
20
|
+
message: string;
|
|
21
|
+
originalError?: Error;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Main PDF extractor class that orchestrates the extraction process
|
|
26
|
+
* Uses multiple specialized extractors in sequence to maximize success rate
|
|
27
|
+
*/
|
|
28
|
+
export declare class PDFExtractor {
|
|
29
|
+
private extractors;
|
|
30
|
+
/**
|
|
31
|
+
* Constructor initializes the chain of extractors
|
|
32
|
+
*/
|
|
33
|
+
constructor();
|
|
34
|
+
/**
|
|
35
|
+
* Extract XML from a PDF buffer
|
|
36
|
+
* Tries multiple extraction methods in sequence
|
|
37
|
+
* @param pdfBuffer PDF buffer
|
|
38
|
+
* @returns Result with either the extracted XML or error information
|
|
39
|
+
*/
|
|
40
|
+
extractXml(pdfBuffer: Uint8Array | Buffer): Promise<PDFExtractResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Create a PDF extract result with error information
|
|
43
|
+
* @param type Error type
|
|
44
|
+
* @param message Error message
|
|
45
|
+
* @param originalError Original error object
|
|
46
|
+
* @returns Error result
|
|
47
|
+
*/
|
|
48
|
+
private createErrorResult;
|
|
49
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { BaseXMLExtractor, StandardXMLExtractor, AssociatedFilesExtractor, TextXMLExtractor } from './extractors/index.js';
|
|
2
|
+
import { FormatDetector } from '../utils/format.detector.js';
|
|
3
|
+
import { InvoiceFormat } from '../../interfaces/common.js';
|
|
4
|
+
/**
|
|
5
|
+
* Error types for PDF extraction operations
|
|
6
|
+
*/
|
|
7
|
+
export var PDFExtractError;
|
|
8
|
+
(function (PDFExtractError) {
|
|
9
|
+
PDFExtractError["EXTRACT_ERROR"] = "XML extraction failed";
|
|
10
|
+
PDFExtractError["INVALID_INPUT"] = "Invalid input parameters";
|
|
11
|
+
PDFExtractError["NO_XML_FOUND"] = "No XML found in PDF";
|
|
12
|
+
})(PDFExtractError || (PDFExtractError = {}));
|
|
13
|
+
/**
|
|
14
|
+
* Main PDF extractor class that orchestrates the extraction process
|
|
15
|
+
* Uses multiple specialized extractors in sequence to maximize success rate
|
|
16
|
+
*/
|
|
17
|
+
export class PDFExtractor {
|
|
18
|
+
/**
|
|
19
|
+
* Constructor initializes the chain of extractors
|
|
20
|
+
*/
|
|
21
|
+
constructor() {
|
|
22
|
+
this.extractors = [];
|
|
23
|
+
// Add extractors in order of preference/likelihood of success
|
|
24
|
+
this.extractors.push(new StandardXMLExtractor(), // Standard PDF/A-3 embedded files
|
|
25
|
+
new AssociatedFilesExtractor(), // Associated files (ZUGFeRD v1, some Factur-X)
|
|
26
|
+
new TextXMLExtractor() // Text-based extraction (fallback)
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Extract XML from a PDF buffer
|
|
31
|
+
* Tries multiple extraction methods in sequence
|
|
32
|
+
* @param pdfBuffer PDF buffer
|
|
33
|
+
* @returns Result with either the extracted XML or error information
|
|
34
|
+
*/
|
|
35
|
+
async extractXml(pdfBuffer) {
|
|
36
|
+
try {
|
|
37
|
+
console.log('Starting XML extraction from PDF...');
|
|
38
|
+
// Validate input
|
|
39
|
+
if (!pdfBuffer || pdfBuffer.length === 0) {
|
|
40
|
+
return this.createErrorResult(PDFExtractError.INVALID_INPUT, 'PDF buffer is empty or undefined');
|
|
41
|
+
}
|
|
42
|
+
// Ensure buffer is Uint8Array
|
|
43
|
+
const pdfBufferArray = Buffer.isBuffer(pdfBuffer) ? new Uint8Array(pdfBuffer) : pdfBuffer;
|
|
44
|
+
// Try each extractor in sequence
|
|
45
|
+
for (const extractor of this.extractors) {
|
|
46
|
+
const extractorName = extractor.constructor.name;
|
|
47
|
+
console.log(`Trying extraction with ${extractorName}...`);
|
|
48
|
+
try {
|
|
49
|
+
const xml = await extractor.extractXml(pdfBufferArray);
|
|
50
|
+
if (xml) {
|
|
51
|
+
console.log(`Successfully extracted XML using ${extractorName}`);
|
|
52
|
+
// Detect format of the extracted XML
|
|
53
|
+
const format = FormatDetector.detectFormat(xml);
|
|
54
|
+
return {
|
|
55
|
+
success: true,
|
|
56
|
+
xml,
|
|
57
|
+
format,
|
|
58
|
+
extractorUsed: extractorName
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
console.log(`Extraction with ${extractorName} failed, trying next method...`);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
// Log error but continue with next extractor
|
|
65
|
+
console.warn(`Error using ${extractorName}: ${error instanceof Error ? error.message : String(error)}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// If all extractors fail, return a no XML found error
|
|
69
|
+
return this.createErrorResult(PDFExtractError.NO_XML_FOUND, 'All extraction methods failed, no valid XML found in PDF');
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
// Handle any unexpected errors
|
|
73
|
+
return this.createErrorResult(PDFExtractError.EXTRACT_ERROR, `Unexpected error during XML extraction: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : undefined);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Create a PDF extract result with error information
|
|
78
|
+
* @param type Error type
|
|
79
|
+
* @param message Error message
|
|
80
|
+
* @param originalError Original error object
|
|
81
|
+
* @returns Error result
|
|
82
|
+
*/
|
|
83
|
+
createErrorResult(type, message, originalError) {
|
|
84
|
+
console.error(`PDF Extractor Error (${type}): ${message}`);
|
|
85
|
+
if (originalError) {
|
|
86
|
+
console.error(originalError);
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
success: false,
|
|
90
|
+
error: {
|
|
91
|
+
type,
|
|
92
|
+
message,
|
|
93
|
+
originalError
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGRmLmV4dHJhY3Rvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL2Zvcm1hdHMvcGRmL3BkZi5leHRyYWN0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLGdCQUFnQixFQUNoQixvQkFBb0IsRUFDcEIsd0JBQXdCLEVBQ3hCLGdCQUFnQixFQUNqQixNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFM0Q7O0dBRUc7QUFDSCxNQUFNLENBQU4sSUFBWSxlQUlYO0FBSkQsV0FBWSxlQUFlO0lBQ3pCLDBEQUF1QyxDQUFBO0lBQ3ZDLDZEQUEwQyxDQUFBO0lBQzFDLHVEQUFvQyxDQUFBO0FBQ3RDLENBQUMsRUFKVyxlQUFlLEtBQWYsZUFBZSxRQUkxQjtBQWlCRDs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sWUFBWTtJQUd2Qjs7T0FFRztJQUNIO1FBTFEsZUFBVSxHQUF1QixFQUFFLENBQUM7UUFNMUMsOERBQThEO1FBQzlELElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUNsQixJQUFJLG9CQUFvQixFQUFFLEVBQU8sa0NBQWtDO1FBQ25FLElBQUksd0JBQXdCLEVBQUUsRUFBRywrQ0FBK0M7UUFDaEYsSUFBSSxnQkFBZ0IsRUFBRSxDQUFXLG1DQUFtQztTQUNyRSxDQUFDO0lBQ0osQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ksS0FBSyxDQUFDLFVBQVUsQ0FBQyxTQUE4QjtRQUNwRCxJQUFJLENBQUM7WUFDSCxPQUFPLENBQUMsR0FBRyxDQUFDLHFDQUFxQyxDQUFDLENBQUM7WUFFbkQsaUJBQWlCO1lBQ2pCLElBQUksQ0FBQyxTQUFTLElBQUksU0FBUyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDekMsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENB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
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Class for extracting XML from PDF files with robust error handling
|
|
3
|
+
*/
|
|
4
|
+
export declare class RobustPDFExtractor {
|
|
5
|
+
/**
|
|
6
|
+
* Extracts XML from a PDF buffer
|
|
7
|
+
* @param pdfBuffer PDF buffer
|
|
8
|
+
* @returns XML content or null if not found
|
|
9
|
+
*/
|
|
10
|
+
extractXml(pdfBuffer: Uint8Array | Buffer): Promise<string | null>;
|
|
11
|
+
/**
|
|
12
|
+
* Standard extraction method using PDF-lib
|
|
13
|
+
* @param pdfBuffer PDF buffer
|
|
14
|
+
* @returns XML content or null if not found
|
|
15
|
+
*/
|
|
16
|
+
private standardExtraction;
|
|
17
|
+
/**
|
|
18
|
+
* Alternative extraction method using a more robust approach
|
|
19
|
+
* @param pdfBuffer PDF buffer
|
|
20
|
+
* @returns XML content or null if not found
|
|
21
|
+
*/
|
|
22
|
+
private alternativeExtraction;
|
|
23
|
+
/**
|
|
24
|
+
* Extracts XML from a string
|
|
25
|
+
* @param pdfString PDF string
|
|
26
|
+
* @returns XML content or null if not found
|
|
27
|
+
*/
|
|
28
|
+
private extractXmlFromString;
|
|
29
|
+
/**
|
|
30
|
+
* Checks if an XML string is valid
|
|
31
|
+
* @param xmlString XML string to check
|
|
32
|
+
* @returns True if the XML is valid
|
|
33
|
+
*/
|
|
34
|
+
private isValidXml;
|
|
35
|
+
/**
|
|
36
|
+
* Extracts a sample XML file for testing
|
|
37
|
+
* @returns Sample XML content
|
|
38
|
+
*/
|
|
39
|
+
private extractSampleXml;
|
|
40
|
+
}
|