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.
Files changed (127) hide show
  1. package/LICENSE-APACHE +176 -0
  2. package/LICENSE-MIT +25 -0
  3. package/README.md +218 -0
  4. package/lib/builders/annotation-builder.d.ts +198 -0
  5. package/lib/builders/annotation-builder.js +317 -0
  6. package/lib/builders/conversion-options-builder.d.ts +106 -0
  7. package/lib/builders/conversion-options-builder.js +214 -0
  8. package/lib/builders/document-builder.d.ts +381 -0
  9. package/lib/builders/document-builder.js +770 -0
  10. package/lib/builders/index.d.ts +13 -0
  11. package/lib/builders/index.js +13 -0
  12. package/lib/builders/metadata-builder.d.ts +201 -0
  13. package/lib/builders/metadata-builder.js +285 -0
  14. package/lib/builders/pdf-builder.d.ts +216 -0
  15. package/lib/builders/pdf-builder.js +350 -0
  16. package/lib/builders/search-options-builder.d.ts +73 -0
  17. package/lib/builders/search-options-builder.js +129 -0
  18. package/lib/builders/streaming-table.d.ts +64 -0
  19. package/lib/builders/streaming-table.js +140 -0
  20. package/lib/document-editor-manager.d.ts +139 -0
  21. package/lib/document-editor-manager.js +256 -0
  22. package/lib/document-editor.d.ts +124 -0
  23. package/lib/document-editor.js +318 -0
  24. package/lib/errors.d.ts +382 -0
  25. package/lib/errors.js +1115 -0
  26. package/lib/form-field-manager.d.ts +299 -0
  27. package/lib/form-field-manager.js +568 -0
  28. package/lib/hybrid-ml-manager.d.ts +142 -0
  29. package/lib/hybrid-ml-manager.js +208 -0
  30. package/lib/index.d.ts +205 -0
  31. package/lib/index.js +693 -0
  32. package/lib/managers/accessibility-manager.d.ts +148 -0
  33. package/lib/managers/accessibility-manager.js +234 -0
  34. package/lib/managers/annotation-manager.d.ts +219 -0
  35. package/lib/managers/annotation-manager.js +359 -0
  36. package/lib/managers/barcode-manager.d.ts +82 -0
  37. package/lib/managers/barcode-manager.js +263 -0
  38. package/lib/managers/batch-manager.d.ts +185 -0
  39. package/lib/managers/batch-manager.js +385 -0
  40. package/lib/managers/cache-manager.d.ts +181 -0
  41. package/lib/managers/cache-manager.js +384 -0
  42. package/lib/managers/compliance-manager.d.ts +103 -0
  43. package/lib/managers/compliance-manager.js +453 -0
  44. package/lib/managers/content-manager.d.ts +120 -0
  45. package/lib/managers/content-manager.js +294 -0
  46. package/lib/managers/document-utility-manager.d.ts +369 -0
  47. package/lib/managers/document-utility-manager.js +730 -0
  48. package/lib/managers/dom-pdf-creator.d.ts +104 -0
  49. package/lib/managers/dom-pdf-creator.js +299 -0
  50. package/lib/managers/editing-manager.d.ts +248 -0
  51. package/lib/managers/editing-manager.js +387 -0
  52. package/lib/managers/enterprise-manager.d.ts +192 -0
  53. package/lib/managers/enterprise-manager.js +307 -0
  54. package/lib/managers/extended-managers.d.ts +122 -0
  55. package/lib/managers/extended-managers.js +664 -0
  56. package/lib/managers/extraction-manager.d.ts +246 -0
  57. package/lib/managers/extraction-manager.js +482 -0
  58. package/lib/managers/final-utilities.d.ts +127 -0
  59. package/lib/managers/final-utilities.js +657 -0
  60. package/lib/managers/hybrid-ml-advanced.d.ts +136 -0
  61. package/lib/managers/hybrid-ml-advanced.js +722 -0
  62. package/lib/managers/index.d.ts +64 -0
  63. package/lib/managers/index.js +69 -0
  64. package/lib/managers/layer-manager.d.ts +203 -0
  65. package/lib/managers/layer-manager.js +401 -0
  66. package/lib/managers/metadata-manager.d.ts +148 -0
  67. package/lib/managers/metadata-manager.js +280 -0
  68. package/lib/managers/ocr-manager.d.ts +194 -0
  69. package/lib/managers/ocr-manager.js +582 -0
  70. package/lib/managers/optimization-manager.d.ts +102 -0
  71. package/lib/managers/optimization-manager.js +213 -0
  72. package/lib/managers/outline-manager.d.ts +101 -0
  73. package/lib/managers/outline-manager.js +169 -0
  74. package/lib/managers/page-manager.d.ts +142 -0
  75. package/lib/managers/page-manager.js +235 -0
  76. package/lib/managers/pattern-detection.d.ts +169 -0
  77. package/lib/managers/pattern-detection.js +322 -0
  78. package/lib/managers/rendering-manager.d.ts +353 -0
  79. package/lib/managers/rendering-manager.js +679 -0
  80. package/lib/managers/search-manager.d.ts +235 -0
  81. package/lib/managers/search-manager.js +329 -0
  82. package/lib/managers/security-manager.d.ts +161 -0
  83. package/lib/managers/security-manager.js +292 -0
  84. package/lib/managers/signature-manager.d.ts +738 -0
  85. package/lib/managers/signature-manager.js +1509 -0
  86. package/lib/managers/streams.d.ts +262 -0
  87. package/lib/managers/streams.js +477 -0
  88. package/lib/managers/xfa-manager.d.ts +227 -0
  89. package/lib/managers/xfa-manager.js +539 -0
  90. package/lib/native-loader.d.ts +7 -0
  91. package/lib/native-loader.js +62 -0
  92. package/lib/native.d.ts +16 -0
  93. package/lib/native.js +69 -0
  94. package/lib/pdf-creator-manager.d.ts +200 -0
  95. package/lib/pdf-creator-manager.js +381 -0
  96. package/lib/properties.d.ts +79 -0
  97. package/lib/properties.js +454 -0
  98. package/lib/result-accessors-manager.d.ts +346 -0
  99. package/lib/result-accessors-manager.js +706 -0
  100. package/lib/thumbnail-manager.d.ts +121 -0
  101. package/lib/thumbnail-manager.js +205 -0
  102. package/lib/timestamp.d.ts +54 -0
  103. package/lib/timestamp.js +115 -0
  104. package/lib/tsa-client.d.ts +44 -0
  105. package/lib/tsa-client.js +67 -0
  106. package/lib/types/common.d.ts +189 -0
  107. package/lib/types/common.js +17 -0
  108. package/lib/types/document-types.d.ts +352 -0
  109. package/lib/types/document-types.js +82 -0
  110. package/lib/types/index.d.ts +5 -0
  111. package/lib/types/index.js +5 -0
  112. package/lib/types/manager-types.d.ts +179 -0
  113. package/lib/types/manager-types.js +100 -0
  114. package/lib/types/native-bindings.d.ts +439 -0
  115. package/lib/types/native-bindings.js +7 -0
  116. package/lib/workers/index.d.ts +6 -0
  117. package/lib/workers/index.js +5 -0
  118. package/lib/workers/pool.d.ts +64 -0
  119. package/lib/workers/pool.js +192 -0
  120. package/lib/workers/worker.d.ts +5 -0
  121. package/lib/workers/worker.js +99 -0
  122. package/package.json +79 -0
  123. package/prebuilds/darwin-arm64/pdf_oxide.node +0 -0
  124. package/prebuilds/darwin-x64/pdf_oxide.node +0 -0
  125. package/prebuilds/linux-arm64/pdf_oxide.node +0 -0
  126. package/prebuilds/linux-x64/pdf_oxide.node +0 -0
  127. package/prebuilds/win32-x64/pdf_oxide.node +0 -0
@@ -0,0 +1,730 @@
1
+ /**
2
+ * Document Utility Manager - Document optimization and manipulation utilities
3
+ *
4
+ * Provides comprehensive document utilities:
5
+ * - Document optimization and compression
6
+ * - PDF linearization (fast web view)
7
+ * - Font optimization and subsetting
8
+ * - Image optimization and recompression
9
+ * - Page manipulation utilities
10
+ * - Document repair
11
+ * - Resource cleanup
12
+ *
13
+ * This completes the document utility coverage for 100% FFI parity.
14
+ */
15
+ import { EventEmitter } from 'events';
16
+ import { promises as fs } from 'fs';
17
+ import { dirname } from 'path';
18
+ // ============================================================================
19
+ // Type Definitions
20
+ // ============================================================================
21
+ /**
22
+ * Optimization level enumeration
23
+ */
24
+ export var OptimizationLevel;
25
+ (function (OptimizationLevel) {
26
+ /** No optimization */
27
+ OptimizationLevel["NONE"] = "none";
28
+ /** Light optimization - fast, minimal size reduction */
29
+ OptimizationLevel["LIGHT"] = "light";
30
+ /** Balanced optimization - good balance of speed and size */
31
+ OptimizationLevel["BALANCED"] = "balanced";
32
+ /** Aggressive optimization - maximum size reduction, slower */
33
+ OptimizationLevel["AGGRESSIVE"] = "aggressive";
34
+ /** Maximum optimization - smallest possible size */
35
+ OptimizationLevel["MAXIMUM"] = "maximum";
36
+ })(OptimizationLevel || (OptimizationLevel = {}));
37
+ /**
38
+ * Image compression type
39
+ */
40
+ export var ImageCompressionType;
41
+ (function (ImageCompressionType) {
42
+ ImageCompressionType["NONE"] = "none";
43
+ ImageCompressionType["JPEG"] = "jpeg";
44
+ ImageCompressionType["JPEG2000"] = "jpeg2000";
45
+ ImageCompressionType["JBIG2"] = "jbig2";
46
+ ImageCompressionType["FLATE"] = "flate";
47
+ ImageCompressionType["LZW"] = "lzw";
48
+ ImageCompressionType["RUN_LENGTH"] = "run_length";
49
+ ImageCompressionType["CCITT_FAX"] = "ccitt_fax";
50
+ })(ImageCompressionType || (ImageCompressionType = {}));
51
+ /**
52
+ * Color space type
53
+ */
54
+ export var ColorSpaceType;
55
+ (function (ColorSpaceType) {
56
+ ColorSpaceType["RGB"] = "rgb";
57
+ ColorSpaceType["CMYK"] = "cmyk";
58
+ ColorSpaceType["GRAYSCALE"] = "grayscale";
59
+ ColorSpaceType["INDEXED"] = "indexed";
60
+ })(ColorSpaceType || (ColorSpaceType = {}));
61
+ /**
62
+ * Font embedding mode
63
+ */
64
+ export var FontEmbeddingMode;
65
+ (function (FontEmbeddingMode) {
66
+ /** Embed full fonts */
67
+ FontEmbeddingMode["FULL"] = "full";
68
+ /** Embed subset of used glyphs only */
69
+ FontEmbeddingMode["SUBSET"] = "subset";
70
+ /** Remove all font embedding */
71
+ FontEmbeddingMode["REMOVE"] = "remove";
72
+ })(FontEmbeddingMode || (FontEmbeddingMode = {}));
73
+ // ============================================================================
74
+ // Document Utility Manager
75
+ // ============================================================================
76
+ /**
77
+ * Document Utility Manager - Complete document optimization and manipulation
78
+ *
79
+ * Provides 35 functions for document utilities.
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * const doc = await PdfDocument.open('large-document.pdf');
84
+ * const utilityManager = new DocumentUtilityManager(doc);
85
+ *
86
+ * // Optimize document
87
+ * const result = await utilityManager.optimizeDocument({
88
+ * level: OptimizationLevel.AGGRESSIVE,
89
+ * compressImages: true,
90
+ * imageQuality: 75,
91
+ * linearize: true,
92
+ * });
93
+ *
94
+ * console.log(`Reduced by ${result.reductionPercent}%`);
95
+ *
96
+ * // Save optimized document
97
+ * await utilityManager.saveOptimized('optimized.pdf');
98
+ * ```
99
+ */
100
+ export class DocumentUtilityManager extends EventEmitter {
101
+ constructor(document) {
102
+ super();
103
+ this.lastOptimizationResult = null;
104
+ if (!document) {
105
+ throw new Error('Document cannot be null or undefined');
106
+ }
107
+ this.document = document;
108
+ }
109
+ // ==========================================================================
110
+ // Optimization Functions (8 functions)
111
+ // ==========================================================================
112
+ /**
113
+ * Optimizes the document with specified options
114
+ */
115
+ async optimizeDocument(options) {
116
+ const startTime = Date.now();
117
+ try {
118
+ const originalSize = await this.getFileSize();
119
+ const result = await this.document?.optimizeDocument?.({
120
+ level: options?.level ?? OptimizationLevel.BALANCED,
121
+ compressImages: options?.compressImages ?? true,
122
+ imageQuality: options?.imageQuality ?? 85,
123
+ imageCompression: options?.imageCompression ?? ImageCompressionType.JPEG,
124
+ downsampleImages: options?.downsampleImages ?? true,
125
+ maxImageDpi: options?.maxImageDpi ?? 150,
126
+ removeUnusedObjects: options?.removeUnusedObjects ?? true,
127
+ removeMetadata: options?.removeMetadata ?? false,
128
+ removeThumbnails: options?.removeThumbnails ?? true,
129
+ removeBookmarks: options?.removeBookmarks ?? false,
130
+ removeAnnotations: options?.removeAnnotations ?? false,
131
+ removeJavaScript: options?.removeJavaScript ?? false,
132
+ removeFormFields: options?.removeFormFields ?? false,
133
+ removeEmbeddedFiles: options?.removeEmbeddedFiles ?? false,
134
+ linearize: options?.linearize ?? false,
135
+ fontEmbedding: options?.fontEmbedding ?? FontEmbeddingMode.SUBSET,
136
+ convertColorSpace: options?.convertColorSpace,
137
+ flattenTransparency: options?.flattenTransparency ?? false,
138
+ });
139
+ const optimizedSize = await this.getFileSize();
140
+ const reductionBytes = originalSize - optimizedSize;
141
+ const reductionPercent = originalSize > 0 ? (reductionBytes / originalSize) * 100 : 0;
142
+ const duration = Date.now() - startTime;
143
+ const optimizationResult = {
144
+ success: true,
145
+ originalSize,
146
+ optimizedSize,
147
+ reductionPercent: Math.round(reductionPercent * 100) / 100,
148
+ reductionBytes,
149
+ duration,
150
+ details: result?.details,
151
+ warnings: result?.warnings,
152
+ };
153
+ this.lastOptimizationResult = optimizationResult;
154
+ this.emit('optimization-complete', optimizationResult);
155
+ return optimizationResult;
156
+ }
157
+ catch (error) {
158
+ const duration = Date.now() - startTime;
159
+ const errorResult = {
160
+ success: false,
161
+ originalSize: 0,
162
+ optimizedSize: 0,
163
+ reductionPercent: 0,
164
+ reductionBytes: 0,
165
+ duration,
166
+ error: error instanceof Error ? error.message : 'Unknown error',
167
+ };
168
+ this.emit('error', error);
169
+ return errorResult;
170
+ }
171
+ }
172
+ /**
173
+ * Compresses document streams
174
+ */
175
+ async compressStreams(options) {
176
+ try {
177
+ const result = await this.document?.compressStreams?.({
178
+ algorithm: options?.algorithm ?? 'flate',
179
+ level: options?.level ?? 6,
180
+ });
181
+ this.emit('streams-compressed');
182
+ return !!result;
183
+ }
184
+ catch (error) {
185
+ this.emit('error', error);
186
+ return false;
187
+ }
188
+ }
189
+ /**
190
+ * Optimizes images in the document
191
+ */
192
+ async optimizeImages(options) {
193
+ try {
194
+ const result = await this.document?.optimizeImages?.({
195
+ maxDpi: options?.maxDpi ?? 150,
196
+ minDpi: options?.minDpi ?? 72,
197
+ targetQuality: options?.targetQuality ?? 85,
198
+ targetFormat: options?.targetFormat ?? ImageCompressionType.JPEG,
199
+ convertColor: options?.convertColor,
200
+ removeIccProfiles: options?.removeIccProfiles ?? false,
201
+ });
202
+ const count = result?.optimizedCount ?? 0;
203
+ this.emit('images-optimized', { count });
204
+ return count;
205
+ }
206
+ catch (error) {
207
+ this.emit('error', error);
208
+ return 0;
209
+ }
210
+ }
211
+ /**
212
+ * Optimizes fonts in the document
213
+ */
214
+ async optimizeFonts(options) {
215
+ try {
216
+ const result = await this.document?.optimizeFonts?.({
217
+ mode: options?.mode ?? FontEmbeddingMode.SUBSET,
218
+ removeUnusedFonts: options?.removeUnusedFonts ?? true,
219
+ mergeSubsets: options?.mergeSubsets ?? true,
220
+ convertToType1: options?.convertToType1 ?? false,
221
+ convertToOpenType: options?.convertToOpenType ?? false,
222
+ });
223
+ const count = result?.optimizedCount ?? 0;
224
+ this.emit('fonts-optimized', { count });
225
+ return count;
226
+ }
227
+ catch (error) {
228
+ this.emit('error', error);
229
+ return 0;
230
+ }
231
+ }
232
+ /**
233
+ * Linearizes the document for fast web view
234
+ */
235
+ async linearize(options) {
236
+ try {
237
+ const result = await this.document?.linearize?.({
238
+ firstPageEnd: options?.firstPageEnd,
239
+ primaryHint: options?.primaryHint ?? true,
240
+ overflowHint: options?.overflowHint ?? true,
241
+ });
242
+ this.emit('document-linearized');
243
+ return !!result;
244
+ }
245
+ catch (error) {
246
+ this.emit('error', error);
247
+ return false;
248
+ }
249
+ }
250
+ /**
251
+ * Removes unused objects from the document
252
+ */
253
+ async removeUnusedObjects() {
254
+ try {
255
+ const result = await this.document?.removeUnusedObjects?.();
256
+ const count = result ?? 0;
257
+ this.emit('unused-objects-removed', { count });
258
+ return count;
259
+ }
260
+ catch (error) {
261
+ this.emit('error', error);
262
+ return 0;
263
+ }
264
+ }
265
+ /**
266
+ * Flattens transparency in the document
267
+ */
268
+ async flattenTransparency() {
269
+ try {
270
+ const result = await this.document?.flattenTransparency?.();
271
+ this.emit('transparency-flattened');
272
+ return !!result;
273
+ }
274
+ catch (error) {
275
+ this.emit('error', error);
276
+ return false;
277
+ }
278
+ }
279
+ /**
280
+ * Converts color space
281
+ */
282
+ async convertColorSpace(targetColorSpace) {
283
+ try {
284
+ const result = await this.document?.convertColorSpace?.(targetColorSpace);
285
+ this.emit('color-space-converted', { targetColorSpace });
286
+ return !!result;
287
+ }
288
+ catch (error) {
289
+ this.emit('error', error);
290
+ return false;
291
+ }
292
+ }
293
+ // ==========================================================================
294
+ // Page Manipulation (8 functions)
295
+ // ==========================================================================
296
+ /**
297
+ * Rotates pages
298
+ */
299
+ async rotatePages(pageRange, degrees) {
300
+ try {
301
+ const range = pageRange === 'all' ? null : pageRange;
302
+ const result = await this.document?.rotatePages?.(range, degrees);
303
+ const count = result ?? 0;
304
+ this.emit('pages-rotated', { count, degrees });
305
+ return count;
306
+ }
307
+ catch (error) {
308
+ this.emit('error', error);
309
+ return 0;
310
+ }
311
+ }
312
+ /**
313
+ * Scales pages
314
+ */
315
+ async scalePages(pageRange, scaleX, scaleY) {
316
+ try {
317
+ const range = pageRange === 'all' ? null : pageRange;
318
+ const result = await this.document?.scalePages?.(range, scaleX, scaleY);
319
+ const count = result ?? 0;
320
+ this.emit('pages-scaled', { count, scaleX, scaleY });
321
+ return count;
322
+ }
323
+ catch (error) {
324
+ this.emit('error', error);
325
+ return 0;
326
+ }
327
+ }
328
+ /**
329
+ * Crops pages
330
+ */
331
+ async cropPages(pageRange, cropBox) {
332
+ try {
333
+ const range = pageRange === 'all' ? null : pageRange;
334
+ const result = await this.document?.cropPages?.(range, cropBox);
335
+ const count = result ?? 0;
336
+ this.emit('pages-cropped', { count });
337
+ return count;
338
+ }
339
+ catch (error) {
340
+ this.emit('error', error);
341
+ return 0;
342
+ }
343
+ }
344
+ /**
345
+ * Removes pages
346
+ */
347
+ async removePages(pageIndices) {
348
+ try {
349
+ const result = await this.document?.removePages?.(pageIndices);
350
+ this.emit('pages-removed', { count: pageIndices.length });
351
+ return !!result;
352
+ }
353
+ catch (error) {
354
+ this.emit('error', error);
355
+ return false;
356
+ }
357
+ }
358
+ /**
359
+ * Reorders pages
360
+ */
361
+ async reorderPages(newOrder) {
362
+ try {
363
+ const result = await this.document?.reorderPages?.(newOrder);
364
+ this.emit('pages-reordered');
365
+ return !!result;
366
+ }
367
+ catch (error) {
368
+ this.emit('error', error);
369
+ return false;
370
+ }
371
+ }
372
+ /**
373
+ * Duplicates pages
374
+ */
375
+ async duplicatePages(pageIndices, times = 1) {
376
+ try {
377
+ const result = await this.document?.duplicatePages?.(pageIndices, times);
378
+ this.emit('pages-duplicated', { count: pageIndices.length * times });
379
+ return !!result;
380
+ }
381
+ catch (error) {
382
+ this.emit('error', error);
383
+ return false;
384
+ }
385
+ }
386
+ /**
387
+ * Extracts pages to a new document
388
+ */
389
+ async extractPages(pageIndices) {
390
+ try {
391
+ const result = await this.document?.extractPages?.(pageIndices);
392
+ this.emit('pages-extracted', { count: pageIndices.length });
393
+ return result ?? null;
394
+ }
395
+ catch (error) {
396
+ this.emit('error', error);
397
+ return null;
398
+ }
399
+ }
400
+ /**
401
+ * Inserts blank pages
402
+ */
403
+ async insertBlankPages(afterPageIndex, count, width, height) {
404
+ try {
405
+ const result = await this.document?.insertBlankPages?.(afterPageIndex, count, width ?? 612, height ?? 792);
406
+ this.emit('blank-pages-inserted', { afterPageIndex, count });
407
+ return !!result;
408
+ }
409
+ catch (error) {
410
+ this.emit('error', error);
411
+ return false;
412
+ }
413
+ }
414
+ // ==========================================================================
415
+ // Document Information (6 functions)
416
+ // ==========================================================================
417
+ /**
418
+ * Gets document statistics
419
+ */
420
+ async getDocumentStatistics() {
421
+ try {
422
+ const stats = await this.document?.getDocumentStatistics?.();
423
+ return (stats ?? {
424
+ pageCount: await this.getPageCount(),
425
+ fileSize: await this.getFileSize(),
426
+ objectCount: 0,
427
+ streamCount: 0,
428
+ imageCount: 0,
429
+ fontCount: 0,
430
+ annotationCount: 0,
431
+ bookmarkCount: 0,
432
+ embeddedFileCount: 0,
433
+ formFieldCount: 0,
434
+ signatureCount: 0,
435
+ hasJavaScript: false,
436
+ hasXfa: false,
437
+ isLinearized: false,
438
+ isEncrypted: false,
439
+ pdfVersion: '1.7',
440
+ });
441
+ }
442
+ catch (error) {
443
+ this.emit('error', error);
444
+ return null;
445
+ }
446
+ }
447
+ /**
448
+ * Gets page information
449
+ */
450
+ async getPageInfo(pageIndex) {
451
+ try {
452
+ const info = await this.document?.getPageInfo?.(pageIndex);
453
+ return info ?? null;
454
+ }
455
+ catch (error) {
456
+ this.emit('error', error);
457
+ return null;
458
+ }
459
+ }
460
+ /**
461
+ * Gets page count
462
+ */
463
+ async getPageCount() {
464
+ try {
465
+ return (await this.document?.getPageCount?.()) ?? 0;
466
+ }
467
+ catch (error) {
468
+ this.emit('error', error);
469
+ return 0;
470
+ }
471
+ }
472
+ /**
473
+ * Gets file size in bytes
474
+ */
475
+ async getFileSize() {
476
+ try {
477
+ return (await this.document?.getFileSize?.()) ?? 0;
478
+ }
479
+ catch (error) {
480
+ this.emit('error', error);
481
+ return 0;
482
+ }
483
+ }
484
+ /**
485
+ * Checks if document is linearized
486
+ */
487
+ async isLinearized() {
488
+ try {
489
+ return (await this.document?.isLinearized?.()) ?? false;
490
+ }
491
+ catch (error) {
492
+ this.emit('error', error);
493
+ return false;
494
+ }
495
+ }
496
+ /**
497
+ * Gets last optimization result
498
+ */
499
+ getLastOptimizationResult() {
500
+ return this.lastOptimizationResult;
501
+ }
502
+ // ==========================================================================
503
+ // Repair and Cleanup (5 functions)
504
+ // ==========================================================================
505
+ /**
506
+ * Repairs the document
507
+ */
508
+ async repairDocument() {
509
+ try {
510
+ const result = await this.document?.repairDocument?.();
511
+ const repairResult = {
512
+ success: result?.success ?? true,
513
+ issuesFound: result?.issuesFound ?? 0,
514
+ issuesFixed: result?.issuesFixed ?? 0,
515
+ issues: result?.issues ?? [],
516
+ error: result?.error,
517
+ };
518
+ this.emit('document-repaired', repairResult);
519
+ return repairResult;
520
+ }
521
+ catch (error) {
522
+ this.emit('error', error);
523
+ return {
524
+ success: false,
525
+ issuesFound: 0,
526
+ issuesFixed: 0,
527
+ issues: [error instanceof Error ? error.message : 'Unknown error'],
528
+ error: error instanceof Error ? error.message : 'Unknown error',
529
+ };
530
+ }
531
+ }
532
+ /**
533
+ * Removes all metadata
534
+ */
535
+ async removeAllMetadata() {
536
+ try {
537
+ const result = await this.document?.removeAllMetadata?.();
538
+ this.emit('metadata-removed');
539
+ return !!result;
540
+ }
541
+ catch (error) {
542
+ this.emit('error', error);
543
+ return false;
544
+ }
545
+ }
546
+ /**
547
+ * Removes all JavaScript
548
+ */
549
+ async removeAllJavaScript() {
550
+ try {
551
+ const result = await this.document?.removeAllJavaScript?.();
552
+ this.emit('javascript-removed');
553
+ return !!result;
554
+ }
555
+ catch (error) {
556
+ this.emit('error', error);
557
+ return false;
558
+ }
559
+ }
560
+ /**
561
+ * Removes all annotations
562
+ */
563
+ async removeAllAnnotations() {
564
+ try {
565
+ const result = await this.document?.removeAllAnnotations?.();
566
+ const count = result ?? 0;
567
+ this.emit('annotations-removed', { count });
568
+ return count;
569
+ }
570
+ catch (error) {
571
+ this.emit('error', error);
572
+ return 0;
573
+ }
574
+ }
575
+ /**
576
+ * Removes all embedded files
577
+ */
578
+ async removeAllEmbeddedFiles() {
579
+ try {
580
+ const result = await this.document?.removeAllEmbeddedFiles?.();
581
+ const count = result ?? 0;
582
+ this.emit('embedded-files-removed', { count });
583
+ return count;
584
+ }
585
+ catch (error) {
586
+ this.emit('error', error);
587
+ return 0;
588
+ }
589
+ }
590
+ // ==========================================================================
591
+ // Save Functions (5 functions)
592
+ // ==========================================================================
593
+ /**
594
+ * Saves the optimized document to a file
595
+ */
596
+ async saveOptimized(filePath) {
597
+ try {
598
+ await fs.mkdir(dirname(filePath), { recursive: true });
599
+ const result = await this.document?.save?.(filePath);
600
+ this.emit('document-saved', { filePath });
601
+ return !!result;
602
+ }
603
+ catch (error) {
604
+ this.emit('error', error);
605
+ return false;
606
+ }
607
+ }
608
+ /**
609
+ * Saves the document to bytes
610
+ */
611
+ async saveToBytes() {
612
+ try {
613
+ return (await this.document?.saveToBytes?.()) ?? null;
614
+ }
615
+ catch (error) {
616
+ this.emit('error', error);
617
+ return null;
618
+ }
619
+ }
620
+ /**
621
+ * Saves with incremental update
622
+ */
623
+ async saveIncremental(filePath) {
624
+ try {
625
+ await fs.mkdir(dirname(filePath), { recursive: true });
626
+ const result = await this.document?.saveIncremental?.(filePath);
627
+ this.emit('document-saved-incremental', { filePath });
628
+ return !!result;
629
+ }
630
+ catch (error) {
631
+ this.emit('error', error);
632
+ return false;
633
+ }
634
+ }
635
+ /**
636
+ * Saves with specific PDF version
637
+ */
638
+ async saveWithVersion(filePath, version) {
639
+ try {
640
+ await fs.mkdir(dirname(filePath), { recursive: true });
641
+ const result = await this.document?.saveWithVersion?.(filePath, version);
642
+ this.emit('document-saved', { filePath, version });
643
+ return !!result;
644
+ }
645
+ catch (error) {
646
+ this.emit('error', error);
647
+ return false;
648
+ }
649
+ }
650
+ /**
651
+ * Exports pages as separate PDFs
652
+ */
653
+ async exportPagesAsSeparateFiles(outputDir, prefix = 'page') {
654
+ try {
655
+ await fs.mkdir(outputDir, { recursive: true });
656
+ const pageCount = await this.getPageCount();
657
+ let exported = 0;
658
+ for (let i = 0; i < pageCount; i++) {
659
+ const pageBuffer = await this.extractPages([i]);
660
+ if (pageBuffer) {
661
+ const filePath = `${outputDir}/${prefix}_${i + 1}.pdf`;
662
+ await fs.writeFile(filePath, pageBuffer);
663
+ exported++;
664
+ }
665
+ }
666
+ this.emit('pages-exported-as-files', { count: exported, outputDir });
667
+ return exported;
668
+ }
669
+ catch (error) {
670
+ this.emit('error', error);
671
+ return 0;
672
+ }
673
+ }
674
+ // ==========================================================================
675
+ // Merge Functions (3 functions)
676
+ // ==========================================================================
677
+ /**
678
+ * Merges another PDF into this document
679
+ */
680
+ async mergePdf(otherPdfBuffer, atPageIndex) {
681
+ try {
682
+ const result = await this.document?.mergePdf?.(otherPdfBuffer, atPageIndex);
683
+ this.emit('pdf-merged');
684
+ return !!result;
685
+ }
686
+ catch (error) {
687
+ this.emit('error', error);
688
+ return false;
689
+ }
690
+ }
691
+ /**
692
+ * Merges multiple PDFs
693
+ */
694
+ async mergeMultiplePdfs(pdfBuffers) {
695
+ try {
696
+ for (const buffer of pdfBuffers) {
697
+ const success = await this.mergePdf(buffer);
698
+ if (!success)
699
+ return false;
700
+ }
701
+ return true;
702
+ }
703
+ catch (error) {
704
+ this.emit('error', error);
705
+ return false;
706
+ }
707
+ }
708
+ /**
709
+ * Appends pages from another PDF
710
+ */
711
+ async appendPagesFromPdf(otherPdfBuffer, pageIndices) {
712
+ try {
713
+ const result = await this.document?.appendPagesFromPdf?.(otherPdfBuffer, pageIndices);
714
+ this.emit('pages-appended');
715
+ return !!result;
716
+ }
717
+ catch (error) {
718
+ this.emit('error', error);
719
+ return false;
720
+ }
721
+ }
722
+ /**
723
+ * Cleanup resources
724
+ */
725
+ destroy() {
726
+ this.lastOptimizationResult = null;
727
+ this.removeAllListeners();
728
+ }
729
+ }
730
+ export default DocumentUtilityManager;