pdf-oxide 0.3.37 → 0.3.38
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/lib/builders/document-builder.d.ts +199 -0
- package/lib/builders/document-builder.js +434 -0
- package/lib/builders/index.d.ts +3 -2
- package/lib/builders/index.js +3 -2
- package/lib/document-editor.d.ts +57 -0
- package/lib/document-editor.js +184 -0
- package/lib/errors.js +3 -4
- package/lib/form-field-manager.js +3 -1
- package/lib/index.d.ts +40 -6
- package/lib/index.js +253 -90
- package/lib/managers/accessibility-manager.js +19 -8
- package/lib/managers/annotation-manager.js +9 -9
- package/lib/managers/barcode-manager.js +18 -7
- package/lib/managers/batch-manager.js +2 -5
- package/lib/managers/cache-manager.js +1 -3
- package/lib/managers/compliance-manager.js +58 -19
- package/lib/managers/document-utility-manager.js +6 -6
- package/lib/managers/dom-pdf-creator.js +9 -9
- package/lib/managers/enterprise-manager.js +4 -1
- package/lib/managers/extended-managers.js +8 -1
- package/lib/managers/extraction-manager.js +7 -2
- package/lib/managers/final-utilities.d.ts +3 -3
- package/lib/managers/final-utilities.js +9 -4
- package/lib/managers/hybrid-ml-advanced.js +22 -6
- package/lib/managers/index.d.ts +22 -22
- package/lib/managers/index.js +23 -23
- package/lib/managers/layer-manager.js +20 -21
- package/lib/managers/ocr-manager.d.ts +2 -2
- package/lib/managers/ocr-manager.js +7 -7
- package/lib/managers/optimization-manager.js +24 -4
- package/lib/managers/page-manager.js +5 -6
- package/lib/managers/pattern-detection.d.ts +1 -1
- package/lib/managers/pattern-detection.js +4 -6
- package/lib/managers/search-manager.js +3 -3
- package/lib/managers/signature-manager.js +149 -40
- package/lib/managers/streams.js +8 -2
- package/lib/managers/xfa-manager.js +69 -19
- 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.js +4 -1
- package/lib/result-accessors-manager.js +3 -1
- 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 +1 -1
- package/lib/types/index.d.ts +1 -1
- package/lib/types/index.js +1 -1
- package/lib/types/manager-types.js +4 -2
- package/lib/workers/index.d.ts +1 -1
- package/lib/workers/pool.js +2 -4
- package/package.json +16 -10
- 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
package/lib/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// PDF Oxide Node.js bindings - Native module loader
|
|
2
|
-
import { platform, arch } from 'node:process';
|
|
3
2
|
import { createRequire } from 'node:module';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
3
|
import { dirname } from 'node:path';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
4
|
+
import { arch, platform } from 'node:process';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { AnnotationBuilder, ConversionOptionsBuilder, DocumentBuilder, EmbeddedFont, MetadataBuilder, PageBuilder, PdfBuilder, SearchOptionsBuilder, } from './builders/index.js';
|
|
7
|
+
import { DocumentEditor } from './document-editor.js';
|
|
8
|
+
import { AccessibilityException, CertificateLoadFailed, ComplianceException, EncryptionException, ErrorCategory, ErrorSeverity, InvalidStateException, IoException, mapFfiErrorCode, OcrException, OptimizationException, ParseException, PdfException, RedactionException, RenderingException, SearchException, SignatureException, SigningFailed, UnknownError, UnsupportedFeatureException, ValidationException, wrapAsyncMethod, wrapError, wrapMethod, } from './errors.js';
|
|
9
|
+
import { AnnotationManager, BatchManager, createExtractionStream, createMetadataStream, createSearchStream, ExtractionManager, ExtractionStream, LayerManager, MetadataManager, MetadataStream, OutlineManager, RenderingManager, SearchManager, SearchStream, SecurityManager, } from './managers/index.js';
|
|
9
10
|
import { WorkerPool, workerPool } from './workers/index.js';
|
|
10
11
|
// Create require function for CommonJS modules
|
|
11
12
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -22,16 +23,16 @@ const { OcrLanguage: OCRLanguage } = require('../lib/managers/ocr-manager.js');
|
|
|
22
23
|
* resolves to js/prebuilds/.
|
|
23
24
|
*/
|
|
24
25
|
const PLATFORMS = {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
darwin: {
|
|
27
|
+
x64: '../prebuilds/darwin-x64/pdf_oxide.node',
|
|
28
|
+
arm64: '../prebuilds/darwin-arm64/pdf_oxide.node',
|
|
28
29
|
},
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
linux: {
|
|
31
|
+
x64: '../prebuilds/linux-x64/pdf_oxide.node',
|
|
32
|
+
arm64: '../prebuilds/linux-arm64/pdf_oxide.node',
|
|
32
33
|
},
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
win32: {
|
|
35
|
+
x64: '../prebuilds/win32-x64/pdf_oxide.node',
|
|
35
36
|
},
|
|
36
37
|
};
|
|
37
38
|
/**
|
|
@@ -101,7 +102,10 @@ function wrapNativeClass(nativeClass, asyncMethods = []) {
|
|
|
101
102
|
return nativeClass;
|
|
102
103
|
// For static methods like PdfDocument.open()
|
|
103
104
|
for (const key of Object.getOwnPropertyNames(nativeClass)) {
|
|
104
|
-
if (key !== 'prototype' &&
|
|
105
|
+
if (key !== 'prototype' &&
|
|
106
|
+
key !== 'length' &&
|
|
107
|
+
key !== 'name' &&
|
|
108
|
+
typeof nativeClass[key] === 'function') {
|
|
105
109
|
const isAsync = asyncMethods.includes(key);
|
|
106
110
|
if (isAsync) {
|
|
107
111
|
nativeClass[key] = wrapAsyncMethod(nativeClass[key], nativeClass);
|
|
@@ -130,15 +134,6 @@ function wrapNativeClass(nativeClass, asyncMethods = []) {
|
|
|
130
134
|
}
|
|
131
135
|
return nativeClass;
|
|
132
136
|
}
|
|
133
|
-
// ---------------------------------------------------------------------------
|
|
134
|
-
// JS wrapper classes around native loose-function exports.
|
|
135
|
-
//
|
|
136
|
-
// The binding.cc addon exports flat C functions (openDocument, extractText,
|
|
137
|
-
// pdfFromMarkdown, …) not N-API class constructors. These TS classes provide
|
|
138
|
-
// the idiomatic JS/TS API that users import. They mirror the Go binding's
|
|
139
|
-
// PdfDocument / PdfCreator / DocumentEditor pattern exactly — a handle-based
|
|
140
|
-
// lifecycle wrapping the same FFI surface.
|
|
141
|
-
// ---------------------------------------------------------------------------
|
|
142
137
|
class PdfDocumentImpl {
|
|
143
138
|
constructor(handle) {
|
|
144
139
|
this._closed = false;
|
|
@@ -162,24 +157,75 @@ class PdfDocumentImpl {
|
|
|
162
157
|
if (this._closed)
|
|
163
158
|
throw new Error('Document is closed');
|
|
164
159
|
}
|
|
165
|
-
get handle() {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
160
|
+
get handle() {
|
|
161
|
+
return this._handle;
|
|
162
|
+
}
|
|
163
|
+
pageCount() {
|
|
164
|
+
this.ensureOpen();
|
|
165
|
+
return native.getPageCount(this._handle);
|
|
166
|
+
}
|
|
167
|
+
getPageCount() {
|
|
168
|
+
return this.pageCount();
|
|
169
|
+
}
|
|
170
|
+
get PageCount() {
|
|
171
|
+
return this.pageCount();
|
|
172
|
+
}
|
|
173
|
+
extractText(pageIndex) {
|
|
174
|
+
this.ensureOpen();
|
|
175
|
+
return native.extractText(this._handle, pageIndex);
|
|
176
|
+
}
|
|
177
|
+
toMarkdown(pageIndex) {
|
|
178
|
+
this.ensureOpen();
|
|
179
|
+
return native.toMarkdown(this._handle, pageIndex);
|
|
180
|
+
}
|
|
181
|
+
toHtml(pageIndex) {
|
|
182
|
+
this.ensureOpen();
|
|
183
|
+
return native.toHtml(this._handle, pageIndex);
|
|
184
|
+
}
|
|
185
|
+
toPlainText(pageIndex) {
|
|
186
|
+
this.ensureOpen();
|
|
187
|
+
return native.toPlainText(this._handle, pageIndex);
|
|
188
|
+
}
|
|
189
|
+
toMarkdownAll() {
|
|
190
|
+
this.ensureOpen();
|
|
191
|
+
return native.toMarkdownAll(this._handle);
|
|
192
|
+
}
|
|
193
|
+
extractAllText() {
|
|
194
|
+
this.ensureOpen();
|
|
195
|
+
return native.extractAllText(this._handle);
|
|
196
|
+
}
|
|
197
|
+
toHtmlAll() {
|
|
198
|
+
this.ensureOpen();
|
|
199
|
+
return native.toHtmlAll(this._handle);
|
|
200
|
+
}
|
|
201
|
+
toPlainTextAll() {
|
|
202
|
+
this.ensureOpen();
|
|
203
|
+
return native.toPlainTextAll(this._handle);
|
|
204
|
+
}
|
|
205
|
+
getVersion() {
|
|
206
|
+
this.ensureOpen();
|
|
207
|
+
return native.getVersion(this._handle);
|
|
208
|
+
}
|
|
209
|
+
hasStructureTree() {
|
|
210
|
+
this.ensureOpen();
|
|
211
|
+
return native.hasStructureTree(this._handle);
|
|
212
|
+
}
|
|
213
|
+
hasXFA() {
|
|
214
|
+
this.ensureOpen();
|
|
215
|
+
return native.hasXFA(this._handle);
|
|
216
|
+
}
|
|
217
|
+
getPageWidth(pageIndex) {
|
|
218
|
+
this.ensureOpen();
|
|
219
|
+
return native.getPageWidth(this._handle, pageIndex);
|
|
220
|
+
}
|
|
221
|
+
getPageHeight(pageIndex) {
|
|
222
|
+
this.ensureOpen();
|
|
223
|
+
return native.getPageHeight(this._handle, pageIndex);
|
|
224
|
+
}
|
|
225
|
+
getPageRotation(pageIndex) {
|
|
226
|
+
this.ensureOpen();
|
|
227
|
+
return native.getPageRotation(this._handle, pageIndex);
|
|
228
|
+
}
|
|
183
229
|
searchPage(pageIndex, query, caseSensitive = false) {
|
|
184
230
|
this.ensureOpen();
|
|
185
231
|
return native.searchPage(this._handle, pageIndex, query, caseSensitive);
|
|
@@ -188,16 +234,84 @@ class PdfDocumentImpl {
|
|
|
188
234
|
this.ensureOpen();
|
|
189
235
|
return native.searchAll(this._handle, query, caseSensitive);
|
|
190
236
|
}
|
|
191
|
-
getFormFields() {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
237
|
+
getFormFields() {
|
|
238
|
+
this.ensureOpen();
|
|
239
|
+
return native.getFormFields(this._handle);
|
|
240
|
+
}
|
|
241
|
+
getOutline() {
|
|
242
|
+
this.ensureOpen();
|
|
243
|
+
return native.getOutline(this._handle);
|
|
244
|
+
}
|
|
245
|
+
getPageAnnotations(pageIndex) {
|
|
246
|
+
this.ensureOpen();
|
|
247
|
+
return native.getPageAnnotations(this._handle, pageIndex);
|
|
248
|
+
}
|
|
249
|
+
getEmbeddedFonts(pageIndex) {
|
|
250
|
+
this.ensureOpen();
|
|
251
|
+
return native.getEmbeddedFonts(this._handle, pageIndex);
|
|
252
|
+
}
|
|
253
|
+
getEmbeddedImages(pageIndex) {
|
|
254
|
+
this.ensureOpen();
|
|
255
|
+
return native.getEmbeddedImages(this._handle, pageIndex);
|
|
256
|
+
}
|
|
257
|
+
extractWords(pageIndex) {
|
|
258
|
+
this.ensureOpen();
|
|
259
|
+
return native.extractWords(this._handle, pageIndex);
|
|
260
|
+
}
|
|
261
|
+
extractTextLines(pageIndex) {
|
|
262
|
+
this.ensureOpen();
|
|
263
|
+
return native.extractTextLines(this._handle, pageIndex);
|
|
264
|
+
}
|
|
265
|
+
extractTables(pageIndex) {
|
|
266
|
+
this.ensureOpen();
|
|
267
|
+
return native.extractTables(this._handle, pageIndex);
|
|
268
|
+
}
|
|
269
|
+
extractPaths(pageIndex) {
|
|
270
|
+
this.ensureOpen();
|
|
271
|
+
return native.extractPaths(this._handle, pageIndex);
|
|
272
|
+
}
|
|
273
|
+
ocrExtractText(pageIndex, engineHandle) {
|
|
274
|
+
this.ensureOpen();
|
|
275
|
+
return native.ocrExtractText(this._handle, pageIndex, engineHandle);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Render a page with the full Rust `RenderOptions` surface
|
|
279
|
+
* (DPI, format, RGBA background, transparency, annotation toggle,
|
|
280
|
+
* JPEG quality). Returns the image bytes.
|
|
281
|
+
*/
|
|
282
|
+
renderPageWithOptions(pageIndex, options = {}) {
|
|
283
|
+
this.ensureOpen();
|
|
284
|
+
const dpi = options.dpi ?? 150;
|
|
285
|
+
if (dpi <= 0)
|
|
286
|
+
throw new RangeError(`dpi must be > 0, got ${dpi}`);
|
|
287
|
+
const format = options.format === 'jpeg' ? 1 : 0;
|
|
288
|
+
const quality = options.jpegQuality ?? 85;
|
|
289
|
+
if (quality < 1 || quality > 100) {
|
|
290
|
+
throw new RangeError(`jpegQuality must be in 1..=100, got ${quality}`);
|
|
291
|
+
}
|
|
292
|
+
const bg = options.background ?? [1, 1, 1, 1];
|
|
293
|
+
const renderAnnotations = options.renderAnnotations === false ? 0 : 1;
|
|
294
|
+
const transparent = options.transparentBackground ? 1 : 0;
|
|
295
|
+
const imgHandle = native.renderPageWithOptions(this._handle, pageIndex, dpi, format, bg[0], bg[1], bg[2], bg[3], transparent, renderAnnotations, quality);
|
|
296
|
+
try {
|
|
297
|
+
const buf = native.pdfGetRenderedImageData(imgHandle);
|
|
298
|
+
return new Uint8Array(buf);
|
|
299
|
+
}
|
|
300
|
+
finally {
|
|
301
|
+
if (native.freeRenderedImage) {
|
|
302
|
+
native.freeRenderedImage(imgHandle);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Estimate render time (milliseconds) for a page at a given DPI.
|
|
308
|
+
* Thin wrapper around the existing `estimateRenderTime` N-API
|
|
309
|
+
* export — exposed in TS for the first time as part of gap L.
|
|
310
|
+
*/
|
|
311
|
+
estimateRenderTime(pageIndex, dpi = 150) {
|
|
312
|
+
this.ensureOpen();
|
|
313
|
+
return native.estimateRenderTime(this._handle, pageIndex, dpi);
|
|
314
|
+
}
|
|
201
315
|
page(index) {
|
|
202
316
|
this.ensureOpen();
|
|
203
317
|
const count = this.pageCount();
|
|
@@ -225,7 +339,9 @@ class PdfDocumentImpl {
|
|
|
225
339
|
this._closed = true;
|
|
226
340
|
}
|
|
227
341
|
}
|
|
228
|
-
[Symbol.dispose]() {
|
|
342
|
+
[Symbol.dispose]() {
|
|
343
|
+
this.close();
|
|
344
|
+
}
|
|
229
345
|
}
|
|
230
346
|
class Page {
|
|
231
347
|
constructor(doc, index) {
|
|
@@ -233,7 +349,9 @@ class Page {
|
|
|
233
349
|
this._doc = doc;
|
|
234
350
|
this._index = index;
|
|
235
351
|
}
|
|
236
|
-
get index() {
|
|
352
|
+
get index() {
|
|
353
|
+
return this._index;
|
|
354
|
+
}
|
|
237
355
|
get width() {
|
|
238
356
|
if (!this._cache.has('width'))
|
|
239
357
|
this._cache.set('width', this._doc.getPageWidth(this._index));
|
|
@@ -249,19 +367,45 @@ class Page {
|
|
|
249
367
|
this._cache.set('rotation', this._doc.getPageRotation(this._index));
|
|
250
368
|
return this._cache.get('rotation');
|
|
251
369
|
}
|
|
252
|
-
text() {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
370
|
+
text() {
|
|
371
|
+
return this._doc.extractText(this._index);
|
|
372
|
+
}
|
|
373
|
+
markdown() {
|
|
374
|
+
return this._doc.toMarkdown(this._index);
|
|
375
|
+
}
|
|
376
|
+
html() {
|
|
377
|
+
return this._doc.toHtml(this._index);
|
|
378
|
+
}
|
|
379
|
+
plainText() {
|
|
380
|
+
return this._doc.toPlainText(this._index);
|
|
381
|
+
}
|
|
382
|
+
words() {
|
|
383
|
+
return this._doc.extractWords(this._index);
|
|
384
|
+
}
|
|
385
|
+
lines() {
|
|
386
|
+
return this._doc.extractTextLines(this._index);
|
|
387
|
+
}
|
|
388
|
+
tables() {
|
|
389
|
+
return this._doc.extractTables(this._index);
|
|
390
|
+
}
|
|
391
|
+
images() {
|
|
392
|
+
return this._doc.getEmbeddedImages(this._index);
|
|
393
|
+
}
|
|
394
|
+
paths() {
|
|
395
|
+
return this._doc.extractPaths(this._index);
|
|
396
|
+
}
|
|
397
|
+
annotations() {
|
|
398
|
+
return this._doc.getPageAnnotations(this._index);
|
|
399
|
+
}
|
|
400
|
+
fonts() {
|
|
401
|
+
return this._doc.getEmbeddedFonts(this._index);
|
|
402
|
+
}
|
|
403
|
+
search(query, caseSensitive = false) {
|
|
404
|
+
return this._doc.searchPage(this._index, query, caseSensitive);
|
|
405
|
+
}
|
|
406
|
+
toString() {
|
|
407
|
+
return `Page(index=${this._index})`;
|
|
408
|
+
}
|
|
265
409
|
}
|
|
266
410
|
class PdfImpl {
|
|
267
411
|
constructor(handle) {
|
|
@@ -289,16 +433,27 @@ class PdfImpl {
|
|
|
289
433
|
if (this._closed)
|
|
290
434
|
throw new Error('PDF handle is closed');
|
|
291
435
|
}
|
|
292
|
-
save(path) {
|
|
293
|
-
|
|
294
|
-
|
|
436
|
+
save(path) {
|
|
437
|
+
this.ensureOpen();
|
|
438
|
+
native.pdfSave(this._handle, path);
|
|
439
|
+
}
|
|
440
|
+
saveToBytes() {
|
|
441
|
+
this.ensureOpen();
|
|
442
|
+
return native.pdfSaveToBytes(this._handle);
|
|
443
|
+
}
|
|
444
|
+
pageCount() {
|
|
445
|
+
this.ensureOpen();
|
|
446
|
+
return native.pdfGetPageCount(this._handle);
|
|
447
|
+
}
|
|
295
448
|
close() {
|
|
296
449
|
if (!this._closed && this._handle) {
|
|
297
450
|
native.pdfFree(this._handle);
|
|
298
451
|
this._closed = true;
|
|
299
452
|
}
|
|
300
453
|
}
|
|
301
|
-
[Symbol.dispose]() {
|
|
454
|
+
[Symbol.dispose]() {
|
|
455
|
+
this.close();
|
|
456
|
+
}
|
|
302
457
|
}
|
|
303
458
|
// Export as ES module
|
|
304
459
|
const getVersion = native.getVersion;
|
|
@@ -314,28 +469,36 @@ const ConversionOptions = native.ConversionOptions;
|
|
|
314
469
|
const SearchOptions = native.SearchOptions;
|
|
315
470
|
const SearchResult = native.SearchResult;
|
|
316
471
|
const TextSearcher = native.TextSearcher;
|
|
317
|
-
|
|
472
|
+
// RFC 3161 Timestamp + TSA Client — standalone, re-exported from
|
|
473
|
+
// their own modules so downstream users get the full API surface.
|
|
474
|
+
export { Timestamp, TimestampHashAlgorithm } from './timestamp.js';
|
|
475
|
+
export { TsaClient } from './tsa-client.js';
|
|
476
|
+
export { AccessibilityException, AccessibilityManager, AnnotationBuilder, AnnotationManager, AnnotationProperties, BarcodeErrorCorrection, BarcodeFormat, BarcodeManager,
|
|
477
|
+
// Phase 2.5: Batch Processing API
|
|
478
|
+
BatchManager, CacheManager, CertificateLoadFailed, Color, ComplianceException, ComplianceIssueType, ComplianceManager, ContentType, ConversionOptions, ConversionOptionsBuilder, createExtractionStream, createMetadataStream, createSearchStream, DigestAlgorithm,
|
|
479
|
+
// Write-side fluent API
|
|
480
|
+
DocumentBuilder,
|
|
481
|
+
// Editor mutation API
|
|
482
|
+
DocumentEditor, EditingManager, EmbeddedFont, EncryptionException, EnterpriseManager,
|
|
483
|
+
// Error utilities
|
|
484
|
+
ErrorCategory, ErrorSeverity, ExtractionManager, ExtractionStream, FieldVisibility, FontProperties, FormFieldManager, FormFieldType, getPdfOxideVersion,
|
|
318
485
|
// Version info
|
|
319
|
-
getVersion,
|
|
320
|
-
//
|
|
321
|
-
|
|
322
|
-
//
|
|
323
|
-
|
|
486
|
+
getVersion, HybridMLManager, ImageFormat, ImageProperties, InvalidStateException, IoException, IssueSeverity, LayerManager, MetadataBuilder, MetadataManager, MetadataStream, mapFfiErrorCode, OCRDetectionMode, OCRLanguage, OCRManager, OcrException,
|
|
487
|
+
// Managers (Phase 4+, consolidated in Phase 9)
|
|
488
|
+
OcrManager, OptimizationException, OptimizationManager,
|
|
489
|
+
// Managers (Phase 1-3: Core)
|
|
490
|
+
OutlineManager, Page, PageBuilder, PageComplexity,
|
|
324
491
|
// Types
|
|
325
|
-
PageSize,
|
|
326
|
-
// Utilities
|
|
327
|
-
TextSearcher,
|
|
328
|
-
// Error utilities
|
|
329
|
-
ErrorCategory, ErrorSeverity, wrapError, wrapMethod, wrapAsyncMethod, mapFfiErrorCode,
|
|
492
|
+
PageSize, ParseException, Pdf, PdfALevel,
|
|
330
493
|
// Builders
|
|
331
|
-
PdfBuilder,
|
|
332
|
-
//
|
|
333
|
-
|
|
334
|
-
//
|
|
335
|
-
|
|
494
|
+
PdfBuilder,
|
|
495
|
+
// Main classes
|
|
496
|
+
PdfDocument,
|
|
497
|
+
// Error types
|
|
498
|
+
PdfError, PdfException, PdfUALevel, PdfXLevel, Point, Rect, RedactionException, RenderingException, RenderingManager, ResultAccessorsManager, SearchException, SearchManager, SearchOptions, SearchOptionsBuilder, SearchResult, SearchResultProperties,
|
|
336
499
|
// Phase 2.4: Stream API
|
|
337
|
-
SearchStream,
|
|
338
|
-
//
|
|
339
|
-
|
|
500
|
+
SearchStream, SecurityManager, SignatureAlgorithm, SignatureException, SignatureManager, SigningFailed,
|
|
501
|
+
// Utilities
|
|
502
|
+
TextSearcher, ThumbnailManager, ThumbnailSize, UnknownError, UnsupportedFeatureException, ValidationException,
|
|
340
503
|
// Worker Threads API
|
|
341
|
-
WorkerPool, workerPool, };
|
|
504
|
+
WorkerPool, workerPool, wrapAsyncMethod, wrapError, wrapMethod, XfaFieldType, XfaFormType, XfaManager, };
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* @since 1.0.0
|
|
12
12
|
*/
|
|
13
13
|
import { EventEmitter } from 'events';
|
|
14
|
-
import {
|
|
14
|
+
import { AccessibilityException, mapFfiErrorCode } from '../errors.js';
|
|
15
15
|
// =============================================================================
|
|
16
16
|
// AccessibilityManager
|
|
17
17
|
// =============================================================================
|
|
@@ -98,9 +98,7 @@ export class AccessibilityManager extends EventEmitter {
|
|
|
98
98
|
throw mapFfiErrorCode(code, 'Failed to get structure tree');
|
|
99
99
|
}
|
|
100
100
|
try {
|
|
101
|
-
const tree = typeof resultPtr === 'string'
|
|
102
|
-
? JSON.parse(resultPtr)
|
|
103
|
-
: resultPtr;
|
|
101
|
+
const tree = typeof resultPtr === 'string' ? JSON.parse(resultPtr) : resultPtr;
|
|
104
102
|
this.emit('structure-tree-retrieved', { totalElements: tree.totalElements });
|
|
105
103
|
// Free native handle if needed
|
|
106
104
|
if (this.native.pdf_structure_tree_free && typeof resultPtr !== 'string') {
|
|
@@ -138,12 +136,25 @@ export class AccessibilityManager extends EventEmitter {
|
|
|
138
136
|
}
|
|
139
137
|
let result;
|
|
140
138
|
try {
|
|
141
|
-
result =
|
|
142
|
-
|
|
143
|
-
|
|
139
|
+
result =
|
|
140
|
+
typeof resultPtr === 'string'
|
|
141
|
+
? JSON.parse(resultPtr)
|
|
142
|
+
: (resultPtr ?? {
|
|
143
|
+
success: true,
|
|
144
|
+
elementsTagged: 0,
|
|
145
|
+
imagesFound: 0,
|
|
146
|
+
headingsDetected: 0,
|
|
147
|
+
warnings: [],
|
|
148
|
+
});
|
|
144
149
|
}
|
|
145
150
|
catch {
|
|
146
|
-
result = {
|
|
151
|
+
result = {
|
|
152
|
+
success: true,
|
|
153
|
+
elementsTagged: 0,
|
|
154
|
+
imagesFound: 0,
|
|
155
|
+
headingsDetected: 0,
|
|
156
|
+
warnings: [],
|
|
157
|
+
};
|
|
147
158
|
}
|
|
148
159
|
this.emit('auto-tagged', { language, elementsTagged: result.elementsTagged });
|
|
149
160
|
return result;
|
|
@@ -89,7 +89,7 @@ export class AnnotationManager {
|
|
|
89
89
|
throw new Error(`Invalid annotation type: ${type}`);
|
|
90
90
|
}
|
|
91
91
|
const annotations = this.getAnnotations();
|
|
92
|
-
return annotations.filter(ann => ann.type === type.toLowerCase());
|
|
92
|
+
return annotations.filter((ann) => ann.type === type.toLowerCase());
|
|
93
93
|
}
|
|
94
94
|
/**
|
|
95
95
|
* Gets number of annotations on page
|
|
@@ -113,7 +113,7 @@ export class AnnotationManager {
|
|
|
113
113
|
throw new Error('Author must be a non-empty string');
|
|
114
114
|
}
|
|
115
115
|
const annotations = this.getAnnotations();
|
|
116
|
-
return annotations.filter(ann => ann.author === author);
|
|
116
|
+
return annotations.filter((ann) => ann.author === author);
|
|
117
117
|
}
|
|
118
118
|
/**
|
|
119
119
|
* Gets unique authors of annotations
|
|
@@ -122,7 +122,7 @@ export class AnnotationManager {
|
|
|
122
122
|
getAnnotationAuthors() {
|
|
123
123
|
const annotations = this.getAnnotations();
|
|
124
124
|
const authors = new Set();
|
|
125
|
-
annotations.forEach(ann => {
|
|
125
|
+
annotations.forEach((ann) => {
|
|
126
126
|
if (ann.author) {
|
|
127
127
|
authors.add(ann.author);
|
|
128
128
|
}
|
|
@@ -144,7 +144,7 @@ export class AnnotationManager {
|
|
|
144
144
|
throw new Error('Date must be a Date object');
|
|
145
145
|
}
|
|
146
146
|
const annotations = this.getAnnotations();
|
|
147
|
-
return annotations.filter(ann => ann.modificationDate && new Date(ann.modificationDate) > date);
|
|
147
|
+
return annotations.filter((ann) => ann.modificationDate && new Date(ann.modificationDate) > date);
|
|
148
148
|
}
|
|
149
149
|
/**
|
|
150
150
|
* Gets annotations modified before a date
|
|
@@ -156,7 +156,7 @@ export class AnnotationManager {
|
|
|
156
156
|
throw new Error('Date must be a Date object');
|
|
157
157
|
}
|
|
158
158
|
const annotations = this.getAnnotations();
|
|
159
|
-
return annotations.filter(ann => ann.modificationDate && new Date(ann.modificationDate) < date);
|
|
159
|
+
return annotations.filter((ann) => ann.modificationDate && new Date(ann.modificationDate) < date);
|
|
160
160
|
}
|
|
161
161
|
/**
|
|
162
162
|
* Gets annotations with specific content
|
|
@@ -174,7 +174,7 @@ export class AnnotationManager {
|
|
|
174
174
|
}
|
|
175
175
|
const annotations = this.getAnnotations();
|
|
176
176
|
const fragment = contentFragment.toLowerCase();
|
|
177
|
-
return annotations.filter(ann => ann.content && ann.content.toLowerCase().includes(fragment));
|
|
177
|
+
return annotations.filter((ann) => ann.content && ann.content.toLowerCase().includes(fragment));
|
|
178
178
|
}
|
|
179
179
|
/**
|
|
180
180
|
* Gets highlights (most common annotation type)
|
|
@@ -230,7 +230,7 @@ export class AnnotationManager {
|
|
|
230
230
|
const annotations = this.getAnnotations();
|
|
231
231
|
const byType = {};
|
|
232
232
|
const byAuthor = {};
|
|
233
|
-
annotations.forEach(ann => {
|
|
233
|
+
annotations.forEach((ann) => {
|
|
234
234
|
// Count by type
|
|
235
235
|
byType[ann.type] = (byType[ann.type] || 0) + 1;
|
|
236
236
|
// Count by author
|
|
@@ -244,8 +244,8 @@ export class AnnotationManager {
|
|
|
244
244
|
byAuthor,
|
|
245
245
|
authors: Object.keys(byAuthor),
|
|
246
246
|
types: Object.keys(byType),
|
|
247
|
-
hasComments: annotations.some(ann => ann.type === 'text'),
|
|
248
|
-
hasHighlights: annotations.some(ann => ann.type === 'highlight'),
|
|
247
|
+
hasComments: annotations.some((ann) => ann.type === 'text'),
|
|
248
|
+
hasHighlights: annotations.some((ann) => ann.type === 'highlight'),
|
|
249
249
|
averageOpacity: this.getAverageOpacity(),
|
|
250
250
|
recentModifications: this.getRecentAnnotations(7).length,
|
|
251
251
|
};
|
|
@@ -69,7 +69,8 @@ export class BarcodeManager extends EventEmitter {
|
|
|
69
69
|
if (this.native?.detect_barcodes) {
|
|
70
70
|
try {
|
|
71
71
|
const barcodesJson = this.native.detect_barcodes(pageIndex) ?? [];
|
|
72
|
-
barcodes =
|
|
72
|
+
barcodes =
|
|
73
|
+
barcodesJson.length > 0 ? barcodesJson.map((json) => JSON.parse(json)) : [];
|
|
73
74
|
}
|
|
74
75
|
catch {
|
|
75
76
|
barcodes = [];
|
|
@@ -89,7 +90,7 @@ export class BarcodeManager extends EventEmitter {
|
|
|
89
90
|
const barcodesJson = this.native.detect_all_barcodes();
|
|
90
91
|
const parsed = JSON.parse(barcodesJson);
|
|
91
92
|
for (const [page, barcodesArray] of Object.entries(parsed)) {
|
|
92
|
-
barcodes.set(parseInt(page), barcodesArray.map(b => JSON.parse(typeof b === 'string' ? b : JSON.stringify(b))));
|
|
93
|
+
barcodes.set(parseInt(page), barcodesArray.map((b) => JSON.parse(typeof b === 'string' ? b : JSON.stringify(b))));
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
catch {
|
|
@@ -101,7 +102,9 @@ export class BarcodeManager extends EventEmitter {
|
|
|
101
102
|
return barcodes;
|
|
102
103
|
}
|
|
103
104
|
async getBarcodesOfFormat(format, pageIndex) {
|
|
104
|
-
const cacheKey = pageIndex
|
|
105
|
+
const cacheKey = pageIndex
|
|
106
|
+
? `barcodes:format:${format}:${pageIndex}`
|
|
107
|
+
: `barcodes:format:${format}:all`;
|
|
105
108
|
if (this.resultCache.has(cacheKey))
|
|
106
109
|
return this.resultCache.get(cacheKey);
|
|
107
110
|
let barcodes = [];
|
|
@@ -109,7 +112,8 @@ export class BarcodeManager extends EventEmitter {
|
|
|
109
112
|
try {
|
|
110
113
|
const page = pageIndex ?? -1;
|
|
111
114
|
const barcodesJson = this.native.get_barcodes_of_format(format, page) ?? [];
|
|
112
|
-
barcodes =
|
|
115
|
+
barcodes =
|
|
116
|
+
barcodesJson.length > 0 ? barcodesJson.map((json) => JSON.parse(json)) : [];
|
|
113
117
|
}
|
|
114
118
|
catch {
|
|
115
119
|
barcodes = [];
|
|
@@ -168,7 +172,7 @@ export class BarcodeManager extends EventEmitter {
|
|
|
168
172
|
if (sizePx < 1 || sizePx > 10000)
|
|
169
173
|
throw new Error('Size must be between 1 and 10000 pixels');
|
|
170
174
|
const barcodeData = await this.document?.generateQrCode?.(data, errorCorrection, sizePx);
|
|
171
|
-
this.emit('
|
|
175
|
+
this.emit('barcodeGenerated', { format: 'qr', size: sizePx });
|
|
172
176
|
return barcodeData || Buffer.alloc(0);
|
|
173
177
|
}
|
|
174
178
|
catch (error) {
|
|
@@ -209,9 +213,16 @@ export class BarcodeManager extends EventEmitter {
|
|
|
209
213
|
// ===========================================================================
|
|
210
214
|
// Cache
|
|
211
215
|
// ===========================================================================
|
|
212
|
-
clearCache() {
|
|
216
|
+
clearCache() {
|
|
217
|
+
this.resultCache.clear();
|
|
218
|
+
this.emit('cacheCleared');
|
|
219
|
+
}
|
|
213
220
|
getCacheStats() {
|
|
214
|
-
return {
|
|
221
|
+
return {
|
|
222
|
+
cacheSize: this.resultCache.size,
|
|
223
|
+
maxCacheSize: this.maxCacheSize,
|
|
224
|
+
entries: Array.from(this.resultCache.keys()),
|
|
225
|
+
};
|
|
215
226
|
}
|
|
216
227
|
setCached(key, value) {
|
|
217
228
|
this.resultCache.set(key, value);
|
|
@@ -96,9 +96,7 @@ export class BatchManager {
|
|
|
96
96
|
const elapsedTime = Date.now() - startTime;
|
|
97
97
|
const completedDocs = completed + failed;
|
|
98
98
|
const avgTimePerDoc = completedDocs > 0 ? elapsedTime / completedDocs : 0;
|
|
99
|
-
const eta = completedDocs > 0
|
|
100
|
-
? (this.documents.length - completedDocs) * avgTimePerDoc
|
|
101
|
-
: 0;
|
|
99
|
+
const eta = completedDocs > 0 ? (this.documents.length - completedDocs) * avgTimePerDoc : 0;
|
|
102
100
|
if (options.onProgress) {
|
|
103
101
|
options.onProgress({
|
|
104
102
|
total: this.documents.length,
|
|
@@ -180,8 +178,7 @@ export class BatchManager {
|
|
|
180
178
|
this.stats.totalTime = totalTime;
|
|
181
179
|
this.stats.completed = completed;
|
|
182
180
|
this.stats.failed = failed;
|
|
183
|
-
this.stats.averageTime =
|
|
184
|
-
completed > 0 ? totalTime / completed : 0;
|
|
181
|
+
this.stats.averageTime = completed > 0 ? totalTime / completed : 0;
|
|
185
182
|
this.stats.throughput = totalTime > 0 ? (completed / totalTime) * 1000 : 0;
|
|
186
183
|
return results.filter((r) => r !== undefined);
|
|
187
184
|
}
|
|
@@ -216,9 +216,7 @@ export class CacheManager extends EventEmitter {
|
|
|
216
216
|
totalSize,
|
|
217
217
|
hitCount: this.hitCount,
|
|
218
218
|
missCount: this.missCount,
|
|
219
|
-
hitRate: this.hitCount + this.missCount > 0
|
|
220
|
-
? this.hitCount / (this.hitCount + this.missCount)
|
|
221
|
-
: 0,
|
|
219
|
+
hitRate: this.hitCount + this.missCount > 0 ? this.hitCount / (this.hitCount + this.missCount) : 0,
|
|
222
220
|
evictionCount: this.evictionCount,
|
|
223
221
|
oldestEntry: timestamps.length > 0 ? Math.min(...timestamps) : undefined,
|
|
224
222
|
newestEntry: timestamps.length > 0 ? Math.max(...timestamps) : undefined,
|