pdf-oxide-fips 0.3.47
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/LICENSE-APACHE +176 -0
- package/LICENSE-MIT +25 -0
- package/README.md +218 -0
- package/lib/builders/annotation-builder.d.ts +198 -0
- package/lib/builders/annotation-builder.js +317 -0
- package/lib/builders/conversion-options-builder.d.ts +106 -0
- package/lib/builders/conversion-options-builder.js +214 -0
- package/lib/builders/document-builder.d.ts +381 -0
- package/lib/builders/document-builder.js +770 -0
- package/lib/builders/index.d.ts +13 -0
- package/lib/builders/index.js +13 -0
- package/lib/builders/metadata-builder.d.ts +201 -0
- package/lib/builders/metadata-builder.js +285 -0
- package/lib/builders/pdf-builder.d.ts +216 -0
- package/lib/builders/pdf-builder.js +350 -0
- package/lib/builders/search-options-builder.d.ts +73 -0
- package/lib/builders/search-options-builder.js +129 -0
- package/lib/builders/streaming-table.d.ts +64 -0
- package/lib/builders/streaming-table.js +140 -0
- package/lib/document-editor-manager.d.ts +139 -0
- package/lib/document-editor-manager.js +256 -0
- package/lib/document-editor.d.ts +124 -0
- package/lib/document-editor.js +318 -0
- package/lib/errors.d.ts +382 -0
- package/lib/errors.js +1115 -0
- package/lib/form-field-manager.d.ts +299 -0
- package/lib/form-field-manager.js +568 -0
- package/lib/hybrid-ml-manager.d.ts +142 -0
- package/lib/hybrid-ml-manager.js +208 -0
- package/lib/index.d.ts +205 -0
- package/lib/index.js +693 -0
- package/lib/managers/accessibility-manager.d.ts +148 -0
- package/lib/managers/accessibility-manager.js +234 -0
- package/lib/managers/annotation-manager.d.ts +219 -0
- package/lib/managers/annotation-manager.js +359 -0
- package/lib/managers/barcode-manager.d.ts +82 -0
- package/lib/managers/barcode-manager.js +263 -0
- package/lib/managers/batch-manager.d.ts +185 -0
- package/lib/managers/batch-manager.js +385 -0
- package/lib/managers/cache-manager.d.ts +181 -0
- package/lib/managers/cache-manager.js +384 -0
- package/lib/managers/compliance-manager.d.ts +103 -0
- package/lib/managers/compliance-manager.js +453 -0
- package/lib/managers/content-manager.d.ts +120 -0
- package/lib/managers/content-manager.js +294 -0
- package/lib/managers/document-utility-manager.d.ts +369 -0
- package/lib/managers/document-utility-manager.js +730 -0
- package/lib/managers/dom-pdf-creator.d.ts +104 -0
- package/lib/managers/dom-pdf-creator.js +299 -0
- package/lib/managers/editing-manager.d.ts +248 -0
- package/lib/managers/editing-manager.js +387 -0
- package/lib/managers/enterprise-manager.d.ts +192 -0
- package/lib/managers/enterprise-manager.js +307 -0
- package/lib/managers/extended-managers.d.ts +122 -0
- package/lib/managers/extended-managers.js +664 -0
- package/lib/managers/extraction-manager.d.ts +246 -0
- package/lib/managers/extraction-manager.js +482 -0
- package/lib/managers/final-utilities.d.ts +127 -0
- package/lib/managers/final-utilities.js +657 -0
- package/lib/managers/hybrid-ml-advanced.d.ts +136 -0
- package/lib/managers/hybrid-ml-advanced.js +722 -0
- package/lib/managers/index.d.ts +64 -0
- package/lib/managers/index.js +69 -0
- package/lib/managers/layer-manager.d.ts +203 -0
- package/lib/managers/layer-manager.js +401 -0
- package/lib/managers/metadata-manager.d.ts +148 -0
- package/lib/managers/metadata-manager.js +280 -0
- package/lib/managers/ocr-manager.d.ts +194 -0
- package/lib/managers/ocr-manager.js +582 -0
- package/lib/managers/optimization-manager.d.ts +102 -0
- package/lib/managers/optimization-manager.js +213 -0
- package/lib/managers/outline-manager.d.ts +101 -0
- package/lib/managers/outline-manager.js +169 -0
- package/lib/managers/page-manager.d.ts +142 -0
- package/lib/managers/page-manager.js +235 -0
- package/lib/managers/pattern-detection.d.ts +169 -0
- package/lib/managers/pattern-detection.js +322 -0
- package/lib/managers/rendering-manager.d.ts +353 -0
- package/lib/managers/rendering-manager.js +679 -0
- package/lib/managers/search-manager.d.ts +235 -0
- package/lib/managers/search-manager.js +329 -0
- package/lib/managers/security-manager.d.ts +161 -0
- package/lib/managers/security-manager.js +292 -0
- package/lib/managers/signature-manager.d.ts +738 -0
- package/lib/managers/signature-manager.js +1509 -0
- package/lib/managers/streams.d.ts +262 -0
- package/lib/managers/streams.js +477 -0
- package/lib/managers/xfa-manager.d.ts +227 -0
- package/lib/managers/xfa-manager.js +539 -0
- package/lib/native-loader.d.ts +7 -0
- package/lib/native-loader.js +62 -0
- package/lib/native.d.ts +16 -0
- package/lib/native.js +69 -0
- package/lib/pdf-creator-manager.d.ts +200 -0
- package/lib/pdf-creator-manager.js +381 -0
- package/lib/properties.d.ts +79 -0
- package/lib/properties.js +454 -0
- package/lib/result-accessors-manager.d.ts +346 -0
- package/lib/result-accessors-manager.js +706 -0
- package/lib/thumbnail-manager.d.ts +121 -0
- package/lib/thumbnail-manager.js +205 -0
- package/lib/timestamp.d.ts +54 -0
- package/lib/timestamp.js +115 -0
- package/lib/tsa-client.d.ts +44 -0
- package/lib/tsa-client.js +67 -0
- package/lib/types/common.d.ts +189 -0
- package/lib/types/common.js +17 -0
- package/lib/types/document-types.d.ts +352 -0
- package/lib/types/document-types.js +82 -0
- package/lib/types/index.d.ts +5 -0
- package/lib/types/index.js +5 -0
- package/lib/types/manager-types.d.ts +179 -0
- package/lib/types/manager-types.js +100 -0
- package/lib/types/native-bindings.d.ts +439 -0
- package/lib/types/native-bindings.js +7 -0
- package/lib/workers/index.d.ts +6 -0
- package/lib/workers/index.js +5 -0
- package/lib/workers/pool.d.ts +64 -0
- package/lib/workers/pool.js +192 -0
- package/lib/workers/worker.d.ts +5 -0
- package/lib/workers/worker.js +99 -0
- package/package.json +79 -0
- package/prebuilds/darwin-arm64/pdf_oxide.node +0 -0
- package/prebuilds/darwin-x64/pdf_oxide.node +0 -0
- package/prebuilds/linux-arm64/pdf_oxide.node +0 -0
- package/prebuilds/linux-x64/pdf_oxide.node +0 -0
- package/prebuilds/win32-x64/pdf_oxide.node +0 -0
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stream API support for PDF Oxide Node.js
|
|
3
|
+
*
|
|
4
|
+
* Provides Readable streams for search results, text extraction, and page metadata.
|
|
5
|
+
* Supports backpressure handling and proper Node.js stream semantics.
|
|
6
|
+
*
|
|
7
|
+
* Phase 2.4 implementation for idiomatic Node.js patterns with Stream API.
|
|
8
|
+
*/
|
|
9
|
+
import { Readable } from 'node:stream';
|
|
10
|
+
/**
|
|
11
|
+
* Readable stream for search results
|
|
12
|
+
*
|
|
13
|
+
* Emits search results one at a time with proper backpressure handling.
|
|
14
|
+
* Supports searching either a specific page or the entire document.
|
|
15
|
+
*
|
|
16
|
+
* Supports both traditional stream API (.on('data')) and async iteration (for await...of).
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* // Traditional stream API
|
|
21
|
+
* const stream = new SearchStream(searchManager, 'keyword');
|
|
22
|
+
* stream.on('data', (result) => {
|
|
23
|
+
* console.log(`Found on page ${result.pageIndex}: ${result.text}`);
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* // Async iteration
|
|
27
|
+
* const stream = new SearchStream(searchManager, 'keyword');
|
|
28
|
+
* for await (const result of stream) {
|
|
29
|
+
* console.log(`Found on page ${result.pageIndex}: ${result.text}`);
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export class SearchStream extends Readable {
|
|
34
|
+
/**
|
|
35
|
+
* Creates a new SearchStream
|
|
36
|
+
* @param searchManager - The search manager instance
|
|
37
|
+
* @param searchTerm - Text to search for
|
|
38
|
+
* @param options - Search options
|
|
39
|
+
* @throws Error if parameters are invalid
|
|
40
|
+
*/
|
|
41
|
+
constructor(searchManager, searchTerm, options = {}) {
|
|
42
|
+
super({ objectMode: true });
|
|
43
|
+
if (!searchManager) {
|
|
44
|
+
throw new Error('SearchManager is required');
|
|
45
|
+
}
|
|
46
|
+
if (!searchTerm || typeof searchTerm !== 'string') {
|
|
47
|
+
throw new Error('Search term must be a non-empty string');
|
|
48
|
+
}
|
|
49
|
+
this.searchManager = searchManager;
|
|
50
|
+
this.searchTerm = searchTerm;
|
|
51
|
+
this.options = options;
|
|
52
|
+
this.pageIndex = options.pageIndex;
|
|
53
|
+
this.caseSensitive = options.caseSensitive ?? false;
|
|
54
|
+
this.wholeWords = options.wholeWords ?? false;
|
|
55
|
+
this.maxResults = options.maxResults ?? Infinity;
|
|
56
|
+
this._results = null;
|
|
57
|
+
this._currentIndex = 0;
|
|
58
|
+
this._resultCount = 0;
|
|
59
|
+
this._initialized = false;
|
|
60
|
+
this._ended = false;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Initialize results (lazy initialization)
|
|
64
|
+
* @private
|
|
65
|
+
*/
|
|
66
|
+
_initialize() {
|
|
67
|
+
if (this._initialized)
|
|
68
|
+
return;
|
|
69
|
+
this._initialized = true;
|
|
70
|
+
try {
|
|
71
|
+
// Perform search
|
|
72
|
+
if (this.pageIndex !== undefined) {
|
|
73
|
+
this._results = (this.searchManager.search(this.searchTerm, this.pageIndex, {
|
|
74
|
+
caseSensitive: this.caseSensitive,
|
|
75
|
+
wholeWords: this.wholeWords,
|
|
76
|
+
}) || []);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
this._results = (this.searchManager.searchAll(this.searchTerm, {
|
|
80
|
+
caseSensitive: this.caseSensitive,
|
|
81
|
+
wholeWords: this.wholeWords,
|
|
82
|
+
}) || []);
|
|
83
|
+
}
|
|
84
|
+
// Apply max results limit
|
|
85
|
+
if (this._results && this._results.length > this.maxResults) {
|
|
86
|
+
this._results = this._results.slice(0, this.maxResults);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
this.destroy(error);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Implement _read() for readable stream
|
|
95
|
+
* @private
|
|
96
|
+
*/
|
|
97
|
+
_read() {
|
|
98
|
+
// Initialize on first read
|
|
99
|
+
if (!this._initialized) {
|
|
100
|
+
this._initialize();
|
|
101
|
+
}
|
|
102
|
+
// Check if we have results to emit
|
|
103
|
+
if (!this._results || this._currentIndex >= this._results.length) {
|
|
104
|
+
// All results emitted
|
|
105
|
+
if (!this._ended) {
|
|
106
|
+
this._ended = true;
|
|
107
|
+
this.push(null);
|
|
108
|
+
}
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
// Emit next result
|
|
112
|
+
const result = this._results[this._currentIndex];
|
|
113
|
+
this._currentIndex++;
|
|
114
|
+
// Format the result
|
|
115
|
+
const data = {
|
|
116
|
+
text: result.text || result.getText?.(),
|
|
117
|
+
pageIndex: result.pageIndex || result.page || 0,
|
|
118
|
+
position: result.position || 0,
|
|
119
|
+
boundingBox: result.boundingBox,
|
|
120
|
+
};
|
|
121
|
+
this.push(data);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Implement async iteration protocol for `for await...of` support
|
|
125
|
+
* @returns AsyncIterator for iterating over search results
|
|
126
|
+
*/
|
|
127
|
+
async *[Symbol.asyncIterator]() {
|
|
128
|
+
// Initialize on first iteration
|
|
129
|
+
if (!this._initialized) {
|
|
130
|
+
this._initialize();
|
|
131
|
+
}
|
|
132
|
+
// Yield results one by one
|
|
133
|
+
while (this._results && this._currentIndex < this._results.length) {
|
|
134
|
+
const result = this._results[this._currentIndex];
|
|
135
|
+
this._currentIndex++;
|
|
136
|
+
const data = {
|
|
137
|
+
text: result.text || result.getText?.(),
|
|
138
|
+
pageIndex: result.pageIndex || result.page || 0,
|
|
139
|
+
position: result.position || 0,
|
|
140
|
+
boundingBox: result.boundingBox,
|
|
141
|
+
};
|
|
142
|
+
yield data;
|
|
143
|
+
}
|
|
144
|
+
if (!this._ended) {
|
|
145
|
+
this._ended = true;
|
|
146
|
+
this.destroy();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Readable stream for text extraction with progress tracking
|
|
152
|
+
*
|
|
153
|
+
* Emits extraction progress for each page with progress percentage.
|
|
154
|
+
* Supports multiple extraction formats: text, markdown, html.
|
|
155
|
+
* Supports both traditional stream API and async iteration.
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```typescript
|
|
159
|
+
* // Traditional stream API
|
|
160
|
+
* const stream = new ExtractionStream(extractionManager, 0, 10, 'markdown');
|
|
161
|
+
* stream.on('data', (progress) => {
|
|
162
|
+
* console.log(`Progress: ${Math.round(progress.progress * 100)}%`);
|
|
163
|
+
* console.log(`Page ${progress.pageIndex + 1}: ${progress.extractedText.length} chars`);
|
|
164
|
+
* });
|
|
165
|
+
*
|
|
166
|
+
* // Async iteration
|
|
167
|
+
* const stream = new ExtractionStream(extractionManager, 0, 10, 'markdown');
|
|
168
|
+
* for await (const progress of stream) {
|
|
169
|
+
* console.log(`Progress: ${Math.round(progress.progress * 100)}%`);
|
|
170
|
+
* }
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
export class ExtractionStream extends Readable {
|
|
174
|
+
/**
|
|
175
|
+
* Creates a new ExtractionStream
|
|
176
|
+
* @param extractionManager - The extraction manager instance
|
|
177
|
+
* @param startPage - Starting page index (inclusive)
|
|
178
|
+
* @param endPage - Ending page index (exclusive)
|
|
179
|
+
* @param extractionType - 'text', 'markdown', or 'html'
|
|
180
|
+
* @param options - Additional extraction options
|
|
181
|
+
* @throws Error if parameters are invalid
|
|
182
|
+
*/
|
|
183
|
+
constructor(extractionManager, startPage, endPage, extractionType = 'text', options = {}) {
|
|
184
|
+
super({ objectMode: true });
|
|
185
|
+
if (!extractionManager) {
|
|
186
|
+
throw new Error('ExtractionManager is required');
|
|
187
|
+
}
|
|
188
|
+
if (typeof startPage !== 'number' || startPage < 0) {
|
|
189
|
+
throw new Error('Start page must be a non-negative number');
|
|
190
|
+
}
|
|
191
|
+
if (typeof endPage !== 'number' || endPage <= startPage) {
|
|
192
|
+
throw new Error('End page must be greater than start page');
|
|
193
|
+
}
|
|
194
|
+
if (!['text', 'markdown', 'html'].includes(extractionType)) {
|
|
195
|
+
throw new Error("Extraction type must be 'text', 'markdown', or 'html'");
|
|
196
|
+
}
|
|
197
|
+
this.extractionManager = extractionManager;
|
|
198
|
+
this.startPage = startPage;
|
|
199
|
+
this.endPage = endPage;
|
|
200
|
+
this.extractionType = extractionType;
|
|
201
|
+
this.options = options;
|
|
202
|
+
this._currentPage = startPage;
|
|
203
|
+
this._totalPages = endPage - startPage;
|
|
204
|
+
this._ended = false;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Implement _read() for readable stream
|
|
208
|
+
* @private
|
|
209
|
+
*/
|
|
210
|
+
_read() {
|
|
211
|
+
// Check if we've processed all pages
|
|
212
|
+
if (this._currentPage >= this.endPage) {
|
|
213
|
+
if (!this._ended) {
|
|
214
|
+
this._ended = true;
|
|
215
|
+
this.push(null);
|
|
216
|
+
}
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
try {
|
|
220
|
+
// Extract current page
|
|
221
|
+
let extractedText;
|
|
222
|
+
if (this.extractionType === 'markdown') {
|
|
223
|
+
extractedText = this.extractionManager.extractMarkdown(this._currentPage, this.options);
|
|
224
|
+
}
|
|
225
|
+
else if (this.extractionType === 'html') {
|
|
226
|
+
extractedText = this.extractionManager.extractHtml(this._currentPage, this.options);
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
extractedText = this.extractionManager.extractText(this._currentPage, this.options);
|
|
230
|
+
}
|
|
231
|
+
// Emit progress object
|
|
232
|
+
const progress = {
|
|
233
|
+
pageIndex: this._currentPage,
|
|
234
|
+
totalPages: this._totalPages,
|
|
235
|
+
extractedText: extractedText || '',
|
|
236
|
+
extractionType: this.extractionType,
|
|
237
|
+
progress: (this._currentPage - this.startPage + 1) / this._totalPages,
|
|
238
|
+
};
|
|
239
|
+
this._currentPage++;
|
|
240
|
+
this.push(progress);
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
this.destroy(error);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Implement async iteration protocol for `for await...of` support
|
|
248
|
+
* @returns AsyncGenerator for iterating over extraction progress
|
|
249
|
+
*/
|
|
250
|
+
async *[Symbol.asyncIterator]() {
|
|
251
|
+
// Process each page
|
|
252
|
+
while (this._currentPage < this.endPage) {
|
|
253
|
+
try {
|
|
254
|
+
// Extract current page
|
|
255
|
+
let extractedText;
|
|
256
|
+
if (this.extractionType === 'markdown') {
|
|
257
|
+
extractedText = this.extractionManager.extractMarkdown(this._currentPage, this.options);
|
|
258
|
+
}
|
|
259
|
+
else if (this.extractionType === 'html') {
|
|
260
|
+
extractedText = this.extractionManager.extractHtml(this._currentPage, this.options);
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
extractedText = this.extractionManager.extractText(this._currentPage, this.options);
|
|
264
|
+
}
|
|
265
|
+
// Create progress object
|
|
266
|
+
const progress = {
|
|
267
|
+
pageIndex: this._currentPage,
|
|
268
|
+
totalPages: this._totalPages,
|
|
269
|
+
extractedText: extractedText || '',
|
|
270
|
+
extractionType: this.extractionType,
|
|
271
|
+
progress: (this._currentPage - this.startPage + 1) / this._totalPages,
|
|
272
|
+
};
|
|
273
|
+
this._currentPage++;
|
|
274
|
+
yield progress;
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
this.destroy(error);
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (!this._ended) {
|
|
282
|
+
this._ended = true;
|
|
283
|
+
this.destroy();
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Readable stream for page metadata retrieval
|
|
289
|
+
*
|
|
290
|
+
* Emits page metadata (dimensions, fonts, images) for each page in range.
|
|
291
|
+
* Supports lazy loading of metadata per page.
|
|
292
|
+
* Supports both traditional stream API and async iteration.
|
|
293
|
+
*
|
|
294
|
+
* @example
|
|
295
|
+
* ```typescript
|
|
296
|
+
* // Traditional stream API
|
|
297
|
+
* const stream = new MetadataStream(renderingManager, 0, 10);
|
|
298
|
+
* stream.on('data', (metadata) => {
|
|
299
|
+
* console.log(`Page ${metadata.pageIndex + 1}: ${metadata.width}x${metadata.height}`);
|
|
300
|
+
* console.log(` Fonts: ${metadata.fontCount}, Images: ${metadata.imageCount}`);
|
|
301
|
+
* });
|
|
302
|
+
*
|
|
303
|
+
* // Async iteration
|
|
304
|
+
* const stream = new MetadataStream(renderingManager, 0, 10);
|
|
305
|
+
* for await (const metadata of stream) {
|
|
306
|
+
* console.log(`Page ${metadata.pageIndex + 1}: ${metadata.width}x${metadata.height}`);
|
|
307
|
+
* }
|
|
308
|
+
* ```
|
|
309
|
+
*/
|
|
310
|
+
export class MetadataStream extends Readable {
|
|
311
|
+
/**
|
|
312
|
+
* Creates a new MetadataStream
|
|
313
|
+
* @param renderingManager - The rendering manager instance
|
|
314
|
+
* @param startPage - Starting page index (inclusive)
|
|
315
|
+
* @param endPage - Ending page index (exclusive)
|
|
316
|
+
* @throws Error if parameters are invalid
|
|
317
|
+
*/
|
|
318
|
+
constructor(renderingManager, startPage, endPage) {
|
|
319
|
+
super({ objectMode: true });
|
|
320
|
+
if (!renderingManager) {
|
|
321
|
+
throw new Error('RenderingManager is required');
|
|
322
|
+
}
|
|
323
|
+
if (typeof startPage !== 'number' || startPage < 0) {
|
|
324
|
+
throw new Error('Start page must be a non-negative number');
|
|
325
|
+
}
|
|
326
|
+
if (typeof endPage !== 'number' || endPage <= startPage) {
|
|
327
|
+
throw new Error('End page must be greater than start page');
|
|
328
|
+
}
|
|
329
|
+
this.renderingManager = renderingManager;
|
|
330
|
+
this.startPage = startPage;
|
|
331
|
+
this.endPage = endPage;
|
|
332
|
+
this._currentPage = startPage;
|
|
333
|
+
this._ended = false;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Implement _read() for readable stream
|
|
337
|
+
* @private
|
|
338
|
+
*/
|
|
339
|
+
_read() {
|
|
340
|
+
// Check if we've processed all pages
|
|
341
|
+
if (this._currentPage >= this.endPage) {
|
|
342
|
+
if (!this._ended) {
|
|
343
|
+
this._ended = true;
|
|
344
|
+
this.push(null);
|
|
345
|
+
}
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
try {
|
|
349
|
+
// Get page dimensions
|
|
350
|
+
const dimensions = this.renderingManager.getPageDimensions(this._currentPage);
|
|
351
|
+
// Get embedded resources
|
|
352
|
+
const fonts = this.renderingManager.getEmbeddedFonts?.(this._currentPage) || [];
|
|
353
|
+
const images = this.renderingManager.getEmbeddedImages?.(this._currentPage) || [];
|
|
354
|
+
// Get rotation
|
|
355
|
+
const rotation = dimensions?.rotation || 0;
|
|
356
|
+
// Emit metadata object
|
|
357
|
+
const metadata = {
|
|
358
|
+
pageIndex: this._currentPage,
|
|
359
|
+
width: dimensions?.width || 0,
|
|
360
|
+
height: dimensions?.height || 0,
|
|
361
|
+
fontCount: Array.isArray(fonts) ? fonts.length : 0,
|
|
362
|
+
imageCount: Array.isArray(images) ? images.length : 0,
|
|
363
|
+
rotation: rotation,
|
|
364
|
+
};
|
|
365
|
+
this._currentPage++;
|
|
366
|
+
this.push(metadata);
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
this.destroy(error);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Implement async iteration protocol for `for await...of` support
|
|
374
|
+
* @returns AsyncGenerator for iterating over page metadata
|
|
375
|
+
*/
|
|
376
|
+
async *[Symbol.asyncIterator]() {
|
|
377
|
+
// Process each page
|
|
378
|
+
while (this._currentPage < this.endPage) {
|
|
379
|
+
try {
|
|
380
|
+
// Get page dimensions
|
|
381
|
+
const dimensions = this.renderingManager.getPageDimensions(this._currentPage);
|
|
382
|
+
// Get embedded resources
|
|
383
|
+
const fonts = this.renderingManager.getEmbeddedFonts?.(this._currentPage) || [];
|
|
384
|
+
const images = this.renderingManager.getEmbeddedImages?.(this._currentPage) || [];
|
|
385
|
+
// Get rotation
|
|
386
|
+
const rotation = dimensions?.rotation || 0;
|
|
387
|
+
// Create metadata object
|
|
388
|
+
const metadata = {
|
|
389
|
+
pageIndex: this._currentPage,
|
|
390
|
+
width: dimensions?.width || 0,
|
|
391
|
+
height: dimensions?.height || 0,
|
|
392
|
+
fontCount: Array.isArray(fonts) ? fonts.length : 0,
|
|
393
|
+
imageCount: Array.isArray(images) ? images.length : 0,
|
|
394
|
+
rotation: rotation,
|
|
395
|
+
};
|
|
396
|
+
this._currentPage++;
|
|
397
|
+
yield metadata;
|
|
398
|
+
}
|
|
399
|
+
catch (error) {
|
|
400
|
+
this.destroy(error);
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
if (!this._ended) {
|
|
405
|
+
this._ended = true;
|
|
406
|
+
this.destroy();
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Creates a readable stream for search results
|
|
412
|
+
*
|
|
413
|
+
* Convenience function to create a SearchStream instance.
|
|
414
|
+
*
|
|
415
|
+
* @param searchManager - The search manager
|
|
416
|
+
* @param searchTerm - Text to search for
|
|
417
|
+
* @param options - Search options
|
|
418
|
+
* @returns A readable stream of search results
|
|
419
|
+
*
|
|
420
|
+
* @example
|
|
421
|
+
* ```typescript
|
|
422
|
+
* createSearchStream(manager, 'error')
|
|
423
|
+
* .pipe(through2.obj((result, enc, cb) => {
|
|
424
|
+
* console.log(`Found: ${result.text}`);
|
|
425
|
+
* cb();
|
|
426
|
+
* }));
|
|
427
|
+
* ```
|
|
428
|
+
*/
|
|
429
|
+
export function createSearchStream(searchManager, searchTerm, options = {}) {
|
|
430
|
+
return new SearchStream(searchManager, searchTerm, options);
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Creates a readable stream for extraction with progress
|
|
434
|
+
*
|
|
435
|
+
* Convenience function to create an ExtractionStream instance.
|
|
436
|
+
*
|
|
437
|
+
* @param extractionManager - The extraction manager
|
|
438
|
+
* @param startPage - Starting page index
|
|
439
|
+
* @param endPage - Ending page index
|
|
440
|
+
* @param extractionType - Extraction format
|
|
441
|
+
* @param options - Additional options
|
|
442
|
+
* @returns A readable stream of extraction progress
|
|
443
|
+
*
|
|
444
|
+
* @example
|
|
445
|
+
* ```typescript
|
|
446
|
+
* createExtractionStream(manager, 0, 10, 'markdown')
|
|
447
|
+
* .pipe(through2.obj((progress, enc, cb) => {
|
|
448
|
+
* console.log(`${Math.round(progress.progress * 100)}% complete`);
|
|
449
|
+
* cb();
|
|
450
|
+
* }));
|
|
451
|
+
* ```
|
|
452
|
+
*/
|
|
453
|
+
export function createExtractionStream(extractionManager, startPage, endPage, extractionType = 'text', options = {}) {
|
|
454
|
+
return new ExtractionStream(extractionManager, startPage, endPage, extractionType, options);
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Creates a readable stream for page metadata
|
|
458
|
+
*
|
|
459
|
+
* Convenience function to create a MetadataStream instance.
|
|
460
|
+
*
|
|
461
|
+
* @param renderingManager - The rendering manager
|
|
462
|
+
* @param startPage - Starting page index
|
|
463
|
+
* @param endPage - Ending page index
|
|
464
|
+
* @returns A readable stream of page metadata
|
|
465
|
+
*
|
|
466
|
+
* @example
|
|
467
|
+
* ```typescript
|
|
468
|
+
* createMetadataStream(manager, 0, 10)
|
|
469
|
+
* .pipe(through2.obj((metadata, enc, cb) => {
|
|
470
|
+
* console.log(`Page ${metadata.pageIndex}: ${metadata.width}x${metadata.height}`);
|
|
471
|
+
* cb();
|
|
472
|
+
* }));
|
|
473
|
+
* ```
|
|
474
|
+
*/
|
|
475
|
+
export function createMetadataStream(renderingManager, startPage, endPage) {
|
|
476
|
+
return new MetadataStream(renderingManager, startPage, endPage);
|
|
477
|
+
}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XfaManager - Canonical XFA Manager (merged from 3 implementations)
|
|
3
|
+
*
|
|
4
|
+
* Consolidates:
|
|
5
|
+
* - src/xfa-manager.ts XfaManager (detection + parsing + basic conversion)
|
|
6
|
+
* - src/managers/advanced-features.ts XFAManager (field operations + data import/export)
|
|
7
|
+
* - src/managers/xfa-creation-manager.ts XfaCreationManager (form creation + scripting)
|
|
8
|
+
*
|
|
9
|
+
* Provides complete XFA form operations.
|
|
10
|
+
*/
|
|
11
|
+
import { EventEmitter } from 'events';
|
|
12
|
+
export declare enum XfaFormType {
|
|
13
|
+
STATIC = "static",
|
|
14
|
+
DYNAMIC = "dynamic"
|
|
15
|
+
}
|
|
16
|
+
export declare enum XfaFieldType {
|
|
17
|
+
TEXT = "text",
|
|
18
|
+
NUMERIC = "numeric",
|
|
19
|
+
DATE = "date",
|
|
20
|
+
TIME = "time",
|
|
21
|
+
DATETIME = "datetime",
|
|
22
|
+
CHECKBOX = "checkbox",
|
|
23
|
+
RADIO = "radio",
|
|
24
|
+
DROPDOWN = "dropdown",
|
|
25
|
+
LISTBOX = "listbox",
|
|
26
|
+
BUTTON = "button",
|
|
27
|
+
SIGNATURE = "signature",
|
|
28
|
+
IMAGE = "image",
|
|
29
|
+
BARCODE = "barcode",
|
|
30
|
+
PASSWORD = "password"
|
|
31
|
+
}
|
|
32
|
+
export declare enum XfaValidationType {
|
|
33
|
+
NONE = "none",
|
|
34
|
+
REQUIRED = "required",
|
|
35
|
+
PATTERN = "pattern",
|
|
36
|
+
RANGE = "range",
|
|
37
|
+
CUSTOM = "custom"
|
|
38
|
+
}
|
|
39
|
+
export declare enum XfaBindingType {
|
|
40
|
+
NORMAL = "normal",
|
|
41
|
+
NONE = "none",
|
|
42
|
+
GLOBAL = "global"
|
|
43
|
+
}
|
|
44
|
+
export interface XfaField {
|
|
45
|
+
readonly name: string;
|
|
46
|
+
readonly fieldType: XfaFieldType;
|
|
47
|
+
readonly value?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface XfaDataset {
|
|
50
|
+
readonly xmlContent: string;
|
|
51
|
+
}
|
|
52
|
+
export interface XFAFormField {
|
|
53
|
+
fieldName: string;
|
|
54
|
+
fieldType: string;
|
|
55
|
+
x: number;
|
|
56
|
+
y: number;
|
|
57
|
+
width: number;
|
|
58
|
+
height: number;
|
|
59
|
+
defaultValue?: string;
|
|
60
|
+
isReadOnly: boolean;
|
|
61
|
+
}
|
|
62
|
+
export interface XfaFieldConfig {
|
|
63
|
+
readonly name: string;
|
|
64
|
+
readonly fieldType: XfaFieldType;
|
|
65
|
+
readonly x: number;
|
|
66
|
+
readonly y: number;
|
|
67
|
+
readonly width: number;
|
|
68
|
+
readonly height: number;
|
|
69
|
+
readonly caption?: string;
|
|
70
|
+
readonly defaultValue?: string;
|
|
71
|
+
readonly tooltip?: string;
|
|
72
|
+
readonly isRequired?: boolean;
|
|
73
|
+
readonly isReadOnly?: boolean;
|
|
74
|
+
readonly isHidden?: boolean;
|
|
75
|
+
readonly maxLength?: number;
|
|
76
|
+
readonly validationType?: XfaValidationType;
|
|
77
|
+
readonly validationPattern?: string;
|
|
78
|
+
readonly validationMessage?: string;
|
|
79
|
+
readonly bindingType?: XfaBindingType;
|
|
80
|
+
readonly bindingPath?: string;
|
|
81
|
+
readonly options?: readonly string[];
|
|
82
|
+
readonly font?: XfaFontConfig;
|
|
83
|
+
readonly border?: XfaBorderConfig;
|
|
84
|
+
readonly margin?: XfaMarginConfig;
|
|
85
|
+
}
|
|
86
|
+
export interface XfaFontConfig {
|
|
87
|
+
readonly family?: string;
|
|
88
|
+
readonly size?: number;
|
|
89
|
+
readonly weight?: 'normal' | 'bold';
|
|
90
|
+
readonly style?: 'normal' | 'italic';
|
|
91
|
+
readonly color?: string;
|
|
92
|
+
}
|
|
93
|
+
export interface XfaBorderConfig {
|
|
94
|
+
readonly style?: 'solid' | 'dashed' | 'dotted' | 'none';
|
|
95
|
+
readonly width?: number;
|
|
96
|
+
readonly color?: string;
|
|
97
|
+
readonly radius?: number;
|
|
98
|
+
}
|
|
99
|
+
export interface XfaMarginConfig {
|
|
100
|
+
readonly top?: number;
|
|
101
|
+
readonly right?: number;
|
|
102
|
+
readonly bottom?: number;
|
|
103
|
+
readonly left?: number;
|
|
104
|
+
}
|
|
105
|
+
export interface XfaTemplateConfig {
|
|
106
|
+
readonly name: string;
|
|
107
|
+
readonly formType: XfaFormType;
|
|
108
|
+
readonly pageWidth?: number;
|
|
109
|
+
readonly pageHeight?: number;
|
|
110
|
+
readonly defaultFont?: XfaFontConfig;
|
|
111
|
+
readonly locale?: string;
|
|
112
|
+
readonly version?: string;
|
|
113
|
+
}
|
|
114
|
+
export interface XfaSubformConfig {
|
|
115
|
+
readonly name: string;
|
|
116
|
+
readonly x?: number;
|
|
117
|
+
readonly y?: number;
|
|
118
|
+
readonly width?: number;
|
|
119
|
+
readonly height?: number;
|
|
120
|
+
readonly layout?: 'position' | 'table' | 'row' | 'lr-tb' | 'rl-tb' | 'tb';
|
|
121
|
+
readonly border?: XfaBorderConfig;
|
|
122
|
+
readonly breakBefore?: 'auto' | 'pageArea' | 'pageEven' | 'pageOdd';
|
|
123
|
+
readonly breakAfter?: 'auto' | 'pageArea' | 'pageEven' | 'pageOdd';
|
|
124
|
+
}
|
|
125
|
+
export interface XfaScriptConfig {
|
|
126
|
+
readonly language: 'JavaScript' | 'FormCalc';
|
|
127
|
+
readonly runAt: 'client' | 'server' | 'both';
|
|
128
|
+
readonly event: string;
|
|
129
|
+
readonly code: string;
|
|
130
|
+
}
|
|
131
|
+
export interface XfaCreationResult {
|
|
132
|
+
readonly success: boolean;
|
|
133
|
+
readonly formId?: string;
|
|
134
|
+
readonly fieldCount?: number;
|
|
135
|
+
readonly error?: string;
|
|
136
|
+
readonly warnings?: readonly string[];
|
|
137
|
+
}
|
|
138
|
+
export interface XfaDataOptions {
|
|
139
|
+
readonly format: 'xml' | 'json' | 'xdp';
|
|
140
|
+
readonly includeEmptyFields?: boolean;
|
|
141
|
+
readonly includeCalculatedFields?: boolean;
|
|
142
|
+
readonly validateOnImport?: boolean;
|
|
143
|
+
}
|
|
144
|
+
export interface XfaFieldHandle {
|
|
145
|
+
readonly fieldId: string;
|
|
146
|
+
readonly name: string;
|
|
147
|
+
readonly fieldType: XfaFieldType;
|
|
148
|
+
readonly pageIndex: number;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Canonical XFA Manager - all XFA operations in one class.
|
|
152
|
+
*/
|
|
153
|
+
export declare class XfaManager extends EventEmitter {
|
|
154
|
+
private readonly document;
|
|
155
|
+
private readonly cache;
|
|
156
|
+
private readonly maxCacheSize;
|
|
157
|
+
private readonly createdFields;
|
|
158
|
+
private formCreated;
|
|
159
|
+
private currentFormId;
|
|
160
|
+
constructor(document: any);
|
|
161
|
+
hasXfa(): boolean;
|
|
162
|
+
parseXfaForm(): any;
|
|
163
|
+
extractFieldData(): Record<string, string | undefined>;
|
|
164
|
+
getDatasetXml(): string;
|
|
165
|
+
convertToAcroForm(): boolean;
|
|
166
|
+
getFieldCount(): Promise<number>;
|
|
167
|
+
getFieldByIndex(index: number): Promise<XFAFormField | null>;
|
|
168
|
+
getFieldValue(fieldName: string): Promise<string | null>;
|
|
169
|
+
setFieldValue(fieldName: string, value: string): Promise<boolean>;
|
|
170
|
+
getFieldType(fieldName: string): Promise<string | null>;
|
|
171
|
+
isFieldReadOnly(fieldName: string): Promise<boolean>;
|
|
172
|
+
getFieldBounds(fieldName: string): Promise<[number, number, number, number] | null>;
|
|
173
|
+
getFormState(): Promise<Record<string, any> | null>;
|
|
174
|
+
exportData(filePath: string): Promise<boolean>;
|
|
175
|
+
importData(filePath: string): Promise<boolean>;
|
|
176
|
+
flattenForm(): Promise<boolean>;
|
|
177
|
+
createXfaForm(config: XfaTemplateConfig): Promise<XfaCreationResult>;
|
|
178
|
+
createFromXdpTemplate(xdpContent: string): Promise<XfaCreationResult>;
|
|
179
|
+
createFromXmlTemplate(xmlTemplate: string): Promise<XfaCreationResult>;
|
|
180
|
+
addSubform(parentPath: string, config: XfaSubformConfig): Promise<boolean>;
|
|
181
|
+
removeXfaForm(): Promise<boolean>;
|
|
182
|
+
addTextField(pageIndex: number, config: XfaFieldConfig): Promise<XfaFieldHandle | null>;
|
|
183
|
+
addNumericField(pageIndex: number, config: Omit<XfaFieldConfig, 'fieldType'>): Promise<XfaFieldHandle | null>;
|
|
184
|
+
addDateField(pageIndex: number, config: Omit<XfaFieldConfig, 'fieldType'>): Promise<XfaFieldHandle | null>;
|
|
185
|
+
addCheckboxField(pageIndex: number, config: Omit<XfaFieldConfig, 'fieldType'>): Promise<XfaFieldHandle | null>;
|
|
186
|
+
addRadioGroup(pageIndex: number, config: Omit<XfaFieldConfig, 'fieldType'> & {
|
|
187
|
+
readonly groupName: string;
|
|
188
|
+
readonly options: readonly string[];
|
|
189
|
+
}): Promise<XfaFieldHandle | null>;
|
|
190
|
+
addDropdownField(pageIndex: number, config: Omit<XfaFieldConfig, 'fieldType'> & {
|
|
191
|
+
readonly options: readonly string[];
|
|
192
|
+
}): Promise<XfaFieldHandle | null>;
|
|
193
|
+
addSignatureField(pageIndex: number, config: Omit<XfaFieldConfig, 'fieldType'>): Promise<XfaFieldHandle | null>;
|
|
194
|
+
addButton(pageIndex: number, config: Omit<XfaFieldConfig, 'fieldType'>): Promise<XfaFieldHandle | null>;
|
|
195
|
+
private addField;
|
|
196
|
+
updateField(fieldId: string, updates: Partial<XfaFieldConfig>): Promise<boolean>;
|
|
197
|
+
removeField(fieldId: string): Promise<boolean>;
|
|
198
|
+
addFieldValidation(fieldName: string, validationType: XfaValidationType, options: {
|
|
199
|
+
pattern?: string;
|
|
200
|
+
message?: string;
|
|
201
|
+
min?: number;
|
|
202
|
+
max?: number;
|
|
203
|
+
script?: string;
|
|
204
|
+
}): Promise<boolean>;
|
|
205
|
+
importXfaData(data: string, options: XfaDataOptions): Promise<boolean>;
|
|
206
|
+
exportXfaData(options: XfaDataOptions): Promise<string | null>;
|
|
207
|
+
exportAsXdp(): Promise<string | null>;
|
|
208
|
+
mergeXfaData(sourceData: string, options?: {
|
|
209
|
+
overwrite?: boolean;
|
|
210
|
+
}): Promise<boolean>;
|
|
211
|
+
addFieldScript(fieldName: string, script: XfaScriptConfig): Promise<boolean>;
|
|
212
|
+
addFormScript(script: XfaScriptConfig): Promise<boolean>;
|
|
213
|
+
removeFieldScript(fieldName: string, event: string): Promise<boolean>;
|
|
214
|
+
validateForm(): Promise<{
|
|
215
|
+
valid: boolean;
|
|
216
|
+
issues: string[];
|
|
217
|
+
}>;
|
|
218
|
+
getCreatedFields(): readonly XfaFieldHandle[];
|
|
219
|
+
hasForm(): boolean;
|
|
220
|
+
clearCache(): void;
|
|
221
|
+
getCacheStats(): Record<string, any>;
|
|
222
|
+
destroy(): void;
|
|
223
|
+
private updateCache;
|
|
224
|
+
}
|
|
225
|
+
/** @deprecated Use XfaManager instead */
|
|
226
|
+
export declare const XFAManager: typeof XfaManager;
|
|
227
|
+
export default XfaManager;
|