pdf-oxide 0.3.24

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 (62) hide show
  1. package/README.md +218 -0
  2. package/binding.gyp +35 -0
  3. package/package.json +78 -0
  4. package/src/builders/annotation-builder.ts +367 -0
  5. package/src/builders/conversion-options-builder.ts +257 -0
  6. package/src/builders/index.ts +12 -0
  7. package/src/builders/metadata-builder.ts +317 -0
  8. package/src/builders/pdf-builder.ts +386 -0
  9. package/src/builders/search-options-builder.ts +151 -0
  10. package/src/document-editor-manager.ts +318 -0
  11. package/src/errors.ts +1629 -0
  12. package/src/form-field-manager.ts +666 -0
  13. package/src/hybrid-ml-manager.ts +283 -0
  14. package/src/index.ts +453 -0
  15. package/src/managers/accessibility-manager.ts +338 -0
  16. package/src/managers/annotation-manager.ts +439 -0
  17. package/src/managers/barcode-manager.ts +235 -0
  18. package/src/managers/batch-manager.ts +533 -0
  19. package/src/managers/cache-manager.ts +486 -0
  20. package/src/managers/compliance-manager.ts +375 -0
  21. package/src/managers/content-manager.ts +339 -0
  22. package/src/managers/document-utility-manager.ts +922 -0
  23. package/src/managers/dom-pdf-creator.ts +365 -0
  24. package/src/managers/editing-manager.ts +514 -0
  25. package/src/managers/enterprise-manager.ts +478 -0
  26. package/src/managers/extended-managers.ts +437 -0
  27. package/src/managers/extraction-manager.ts +583 -0
  28. package/src/managers/final-utilities.ts +429 -0
  29. package/src/managers/hybrid-ml-advanced.ts +479 -0
  30. package/src/managers/index.ts +239 -0
  31. package/src/managers/layer-manager.ts +500 -0
  32. package/src/managers/metadata-manager.ts +303 -0
  33. package/src/managers/ocr-manager.ts +756 -0
  34. package/src/managers/optimization-manager.ts +262 -0
  35. package/src/managers/outline-manager.ts +196 -0
  36. package/src/managers/page-manager.ts +289 -0
  37. package/src/managers/pattern-detection.ts +440 -0
  38. package/src/managers/rendering-manager.ts +863 -0
  39. package/src/managers/search-manager.ts +385 -0
  40. package/src/managers/security-manager.ts +345 -0
  41. package/src/managers/signature-manager.ts +1664 -0
  42. package/src/managers/streams.ts +618 -0
  43. package/src/managers/xfa-manager.ts +500 -0
  44. package/src/pdf-creator-manager.ts +494 -0
  45. package/src/properties.ts +522 -0
  46. package/src/result-accessors-manager.ts +867 -0
  47. package/src/tests/advanced-features.test.ts +414 -0
  48. package/src/tests/advanced.test.ts +266 -0
  49. package/src/tests/extended-managers.test.ts +316 -0
  50. package/src/tests/final-utilities.test.ts +455 -0
  51. package/src/tests/foundation.test.ts +315 -0
  52. package/src/tests/high-demand.test.ts +257 -0
  53. package/src/tests/specialized.test.ts +97 -0
  54. package/src/thumbnail-manager.ts +272 -0
  55. package/src/types/common.ts +142 -0
  56. package/src/types/document-types.ts +457 -0
  57. package/src/types/index.ts +6 -0
  58. package/src/types/manager-types.ts +284 -0
  59. package/src/types/native-bindings.ts +517 -0
  60. package/src/workers/index.ts +7 -0
  61. package/src/workers/pool.ts +274 -0
  62. package/src/workers/worker.ts +131 -0
@@ -0,0 +1,455 @@
1
+ /**
2
+ * Comprehensive test suite for Phase 8 Final Utilities.
3
+ * Tests: EventManager, EncryptionManager, CompressionManager, CustomAnnotationManager, ContentSecurityManager
4
+ */
5
+
6
+ import { describe, it, expect, beforeEach } from '@jest/globals';
7
+
8
+ import EventManager from '../managers/event-manager';
9
+ import EncryptionManager from '../managers/encryption-manager';
10
+ import CompressionManager from '../managers/compression-manager';
11
+ import CustomAnnotationManager from '../managers/custom-annotation-manager';
12
+ import ContentSecurityManager from '../managers/content-security-manager';
13
+
14
+ describe('Phase 8 Final Utilities', () => {
15
+ describe('EventManager', () => {
16
+ let manager: EventManager;
17
+
18
+ beforeEach(() => {
19
+ manager = new EventManager();
20
+ });
21
+
22
+ it('should add event listener and return true', () => {
23
+ const handler = (e: any) => {};
24
+ const result = manager.addEventListener('PAGE_LOADED', handler);
25
+ expect(result).toBe(true);
26
+ });
27
+
28
+ it('should remove event listener and return true', () => {
29
+ const handler = (e: any) => {};
30
+ manager.addEventListener('PAGE_LOADED', handler);
31
+ const result = manager.removeEventListener('PAGE_LOADED', handler);
32
+ expect(result).toBe(true);
33
+ });
34
+
35
+ it('should check if listener exists', () => {
36
+ const handler = (e: any) => {};
37
+ manager.addEventListener('CONTENT_PARSED', handler);
38
+ const result = manager.hasListener('CONTENT_PARSED');
39
+ expect(result).toBe(true);
40
+ });
41
+
42
+ it('should return false for non-existent listener', () => {
43
+ const result = manager.hasListener('ERROR_OCCURRED');
44
+ expect(result).toBe(false);
45
+ });
46
+
47
+ it('should count listeners correctly', () => {
48
+ manager.addEventListener('PAGE_RENDERED', (e: any) => {});
49
+ manager.addEventListener('PAGE_RENDERED', (e: any) => {});
50
+ const count = manager.getListenerCount('PAGE_RENDERED');
51
+ expect(count).toBe(2);
52
+ });
53
+
54
+ it('should clear listeners for event', () => {
55
+ manager.addEventListener('SEARCH_COMPLETED', (e: any) => {});
56
+ const result = manager.clearListeners('SEARCH_COMPLETED');
57
+ expect(result).toBe(true);
58
+ expect(manager.getListenerCount('SEARCH_COMPLETED')).toBe(0);
59
+ });
60
+
61
+ it('should get event statistics as object', () => {
62
+ manager.addEventListener('PAGE_LOADED', (e: any) => {});
63
+ manager.addEventListener('CONTENT_PARSED', (e: any) => {});
64
+ const stats = manager.getEventStatistics();
65
+ expect(typeof stats).toBe('object');
66
+ });
67
+
68
+ it('should enable event logging and return boolean', () => {
69
+ const result = manager.enableEventLogging(true);
70
+ expect(typeof result).toBe('boolean');
71
+ });
72
+
73
+ it('should emit event and call handlers', () => {
74
+ let called = false;
75
+ const handler = (e: any) => {
76
+ called = true;
77
+ };
78
+ manager.addEventListener('PAGE_LOADED', handler);
79
+ // Event emission would be tested in integration
80
+ });
81
+ });
82
+
83
+ describe('EncryptionManager', () => {
84
+ let manager: EncryptionManager;
85
+
86
+ beforeEach(() => {
87
+ manager = new EncryptionManager();
88
+ });
89
+
90
+ it('should encrypt document with settings and return boolean', () => {
91
+ const settings = {
92
+ algorithm: 'AES_256',
93
+ user_password: 'user123',
94
+ owner_password: 'owner123',
95
+ allow_printing: true,
96
+ allow_copying: false,
97
+ allow_modification: false,
98
+ };
99
+ const result = manager.encryptDocument(settings);
100
+ expect(typeof result).toBe('boolean');
101
+ });
102
+
103
+ it('should decrypt document and return boolean', () => {
104
+ const result = manager.decryptDocument('password123');
105
+ expect(typeof result).toBe('boolean');
106
+ });
107
+
108
+ it('should change encryption settings and return boolean', () => {
109
+ const settings = { algorithm: 'AES_256' };
110
+ const result = manager.changeEncryption(settings);
111
+ expect(typeof result).toBe('boolean');
112
+ });
113
+
114
+ it('should check encryption status and return boolean', () => {
115
+ const result = manager.isDocumentEncrypted();
116
+ expect(typeof result).toBe('boolean');
117
+ });
118
+
119
+ it('should set user password and return boolean', () => {
120
+ const result = manager.setUserPassword('newpass123');
121
+ expect(typeof result).toBe('boolean');
122
+ });
123
+
124
+ it('should set owner password and return boolean', () => {
125
+ const result = manager.setOwnerPassword('ownerpass123');
126
+ expect(typeof result).toBe('boolean');
127
+ });
128
+
129
+ it('should validate password and return boolean', () => {
130
+ const result = manager.validatePassword('testpass');
131
+ expect(typeof result).toBe('boolean');
132
+ });
133
+
134
+ it('should get permissions as object', () => {
135
+ const perms = manager.getPermissions();
136
+ expect(typeof perms).toBe('object');
137
+ });
138
+
139
+ it('should set permissions and return boolean', () => {
140
+ const perms = { allow_print: true, allow_copy: false };
141
+ const result = manager.setPermissions(perms);
142
+ expect(typeof result).toBe('boolean');
143
+ });
144
+
145
+ it('should remove encryption and return boolean', () => {
146
+ const result = manager.removeEncryption('ownerpass');
147
+ expect(typeof result).toBe('boolean');
148
+ });
149
+
150
+ it('should support all encryption algorithms', () => {
151
+ const algorithms = ['AES_128', 'AES_256', 'RC4_40', 'RC4_128'];
152
+
153
+ for (const algo of algorithms) {
154
+ const settings = {
155
+ algorithm: algo,
156
+ user_password: 'user',
157
+ owner_password: 'owner',
158
+ };
159
+ const result = manager.encryptDocument(settings);
160
+ expect(typeof result).toBe('boolean');
161
+ }
162
+ });
163
+ });
164
+
165
+ describe('CompressionManager', () => {
166
+ let manager: CompressionManager;
167
+
168
+ beforeEach(() => {
169
+ manager = new CompressionManager();
170
+ });
171
+
172
+ it('should compress document with settings and return boolean', () => {
173
+ const settings = {
174
+ level: 'BALANCED',
175
+ compress_images: true,
176
+ compress_streams: true,
177
+ compress_fonts: true,
178
+ remove_duplicates: true,
179
+ };
180
+ const result = manager.compressDocument(settings);
181
+ expect(typeof result).toBe('boolean');
182
+ });
183
+
184
+ it('should compress images with quality and return boolean', () => {
185
+ const result = manager.compressImages(85);
186
+ expect(typeof result).toBe('boolean');
187
+ });
188
+
189
+ it('should compress streams and return boolean', () => {
190
+ const result = manager.compressStreams();
191
+ expect(typeof result).toBe('boolean');
192
+ });
193
+
194
+ it('should compress specific page and return boolean', () => {
195
+ const settings = { level: 'BALANCED' };
196
+ const result = manager.compressPage(0, settings);
197
+ expect(typeof result).toBe('boolean');
198
+ });
199
+
200
+ it('should check compression status and return boolean', () => {
201
+ const result = manager.isCompressed();
202
+ expect(typeof result).toBe('boolean');
203
+ });
204
+
205
+ it('should decompress document and return boolean', () => {
206
+ const result = manager.decompressDocument();
207
+ expect(typeof result).toBe('boolean');
208
+ });
209
+
210
+ it('should get compression ratio as number or null', () => {
211
+ const ratio = manager.getCompressionRatio();
212
+ expect(ratio === null || typeof ratio === 'number').toBe(true);
213
+ });
214
+
215
+ it('should get compression report as object', () => {
216
+ const report = manager.getCompressionReport();
217
+ expect(typeof report).toBe('object');
218
+ });
219
+
220
+ it('should optimize for web and return boolean', () => {
221
+ const result = manager.optimizeForWeb();
222
+ expect(typeof result).toBe('boolean');
223
+ });
224
+
225
+ it('should optimize for print and return boolean', () => {
226
+ const result = manager.optimizeForPrint();
227
+ expect(typeof result).toBe('boolean');
228
+ });
229
+
230
+ it('should support all compression levels', () => {
231
+ const levels = ['NONE', 'FAST', 'BALANCED', 'BEST'];
232
+
233
+ for (const level of levels) {
234
+ const settings = {
235
+ level,
236
+ compress_images: true,
237
+ compress_streams: true,
238
+ compress_fonts: true,
239
+ remove_duplicates: true,
240
+ };
241
+ manager.compressDocument(settings);
242
+ }
243
+ });
244
+ });
245
+
246
+ describe('CustomAnnotationManager', () => {
247
+ let manager: CustomAnnotationManager;
248
+
249
+ beforeEach(() => {
250
+ manager = new CustomAnnotationManager();
251
+ });
252
+
253
+ it('should create custom annotation and return ID or null', () => {
254
+ const props = { color: 'red', opacity: 0.5 };
255
+ const result = manager.createCustomAnnotation('highlight', props);
256
+ expect(result === null || typeof result === 'string').toBe(true);
257
+ });
258
+
259
+ it('should modify annotation and return boolean', () => {
260
+ const props = { color: 'blue' };
261
+ const result = manager.modifyAnnotation('anno_1', props);
262
+ expect(typeof result).toBe('boolean');
263
+ });
264
+
265
+ it('should delete annotation and return boolean', () => {
266
+ const result = manager.deleteCustomAnnotation('anno_1');
267
+ expect(typeof result).toBe('boolean');
268
+ });
269
+
270
+ it('should register annotation type and return boolean', () => {
271
+ const handler = (e: any) => {};
272
+ const result = manager.registerAnnotationType('custom_type', handler);
273
+ expect(typeof result).toBe('boolean');
274
+ });
275
+
276
+ it('should set annotation visibility and return boolean', () => {
277
+ const result = manager.setAnnotationVisibility('anno_1', true);
278
+ expect(typeof result).toBe('boolean');
279
+ });
280
+
281
+ it('should export annotations and return boolean', () => {
282
+ const result = manager.exportAnnotations('/output.json');
283
+ expect(typeof result).toBe('boolean');
284
+ });
285
+
286
+ it('should import annotations and return boolean', () => {
287
+ const result = manager.importAnnotations('/input.json');
288
+ expect(typeof result).toBe('boolean');
289
+ });
290
+
291
+ it('should apply annotation style and return boolean', () => {
292
+ const style = { font_size: 12, color: 'red' };
293
+ const result = manager.applyAnnotationStyle('anno_1', style);
294
+ expect(typeof result).toBe('boolean');
295
+ });
296
+
297
+ it('should reply to annotation and return boolean', () => {
298
+ const result = manager.replyToAnnotation('anno_1', 'This is a reply');
299
+ expect(typeof result).toBe('boolean');
300
+ });
301
+
302
+ it('should get annotation replies as array', () => {
303
+ const replies = manager.getAnnotationReplies('anno_1');
304
+ expect(Array.isArray(replies)).toBe(true);
305
+ });
306
+
307
+ it('should flatten annotations and return boolean', () => {
308
+ const result = manager.flattenAnnotations();
309
+ expect(typeof result).toBe('boolean');
310
+ });
311
+
312
+ it('should convert annotations and return boolean', () => {
313
+ const result = manager.convertAnnotations('xfdf');
314
+ expect(typeof result).toBe('boolean');
315
+ });
316
+
317
+ it('should complete annotation lifecycle', () => {
318
+ // Create
319
+ const annoId = manager.createCustomAnnotation('note', { text: 'Important' });
320
+ // Modify
321
+ if (annoId) {
322
+ manager.modifyAnnotation(annoId, { color: 'yellow' });
323
+ // Reply
324
+ manager.replyToAnnotation(annoId, 'Updated');
325
+ // Get replies
326
+ const replies = manager.getAnnotationReplies(annoId);
327
+ expect(Array.isArray(replies)).toBe(true);
328
+ }
329
+ });
330
+ });
331
+
332
+ describe('ContentSecurityManager', () => {
333
+ let manager: ContentSecurityManager;
334
+
335
+ beforeEach(() => {
336
+ manager = new ContentSecurityManager();
337
+ });
338
+
339
+ it('should set access control and return boolean', () => {
340
+ const restrictions = { role: 'admin', action: 'read' };
341
+ const result = manager.setAccessControl('admin_policy', restrictions);
342
+ expect(typeof result).toBe('boolean');
343
+ });
344
+
345
+ it('should validate access and return boolean', () => {
346
+ const result = manager.validateAccess('admin', 'read');
347
+ expect(typeof result).toBe('boolean');
348
+ });
349
+
350
+ it('should apply digital rights and return boolean', () => {
351
+ const rights = { can_print: true, can_copy: false, can_modify: false };
352
+ const result = manager.applyDigitalRights(rights);
353
+ expect(typeof result).toBe('boolean');
354
+ });
355
+
356
+ it('should sanitize content and return boolean', () => {
357
+ const result = manager.sanitizeContent(true, true);
358
+ expect(typeof result).toBe('boolean');
359
+ });
360
+
361
+ it('should detect suspicious content and return array', () => {
362
+ const results = manager.detectSuspiciousContent();
363
+ expect(Array.isArray(results)).toBe(true);
364
+ });
365
+
366
+ it('should get access log as array', () => {
367
+ const log = manager.getAccessLog();
368
+ expect(Array.isArray(log)).toBe(true);
369
+ });
370
+
371
+ it('should set expiration date and return boolean', () => {
372
+ const result = manager.setExpirationDate('2025-12-31');
373
+ expect(typeof result).toBe('boolean');
374
+ });
375
+
376
+ it('should enable watermarking and return boolean', () => {
377
+ const result = manager.enableWatermarking('CONFIDENTIAL');
378
+ expect(typeof result).toBe('boolean');
379
+ });
380
+
381
+ it('should track document usage and return boolean', () => {
382
+ const result = manager.trackDocumentUsage(true);
383
+ expect(typeof result).toBe('boolean');
384
+ });
385
+
386
+ it('should get security audit as object', () => {
387
+ const audit = manager.getSecurityAudit();
388
+ expect(typeof audit).toBe('object');
389
+ });
390
+
391
+ it('should complete security policy enforcement', () => {
392
+ // Set access control
393
+ manager.setAccessControl('strict', { role: 'viewer', action: 'read_only' });
394
+ // Apply rights
395
+ manager.applyDigitalRights({ can_print: false, can_copy: false });
396
+ // Enable watermarking
397
+ manager.enableWatermarking('RESTRICTED');
398
+ // Sanitize
399
+ manager.sanitizeContent(true, true);
400
+ // Get audit
401
+ const audit = manager.getSecurityAudit();
402
+ expect(typeof audit).toBe('object');
403
+ });
404
+ });
405
+
406
+ describe('Phase 8 Integration Tests', () => {
407
+ it('should complete document protection workflow', () => {
408
+ const eventMgr = new EventManager();
409
+ const encryptionMgr = new EncryptionManager();
410
+ const securityMgr = new ContentSecurityManager();
411
+
412
+ // Register event listeners
413
+ eventMgr.addEventListener('PROCESSING_STARTED', (e: any) => {
414
+ console.log('Started');
415
+ });
416
+
417
+ // Set up encryption
418
+ const settings = {
419
+ algorithm: 'AES_256',
420
+ user_password: 'user',
421
+ owner_password: 'owner',
422
+ allow_printing: true,
423
+ allow_copying: false,
424
+ allow_modification: false,
425
+ };
426
+ encryptionMgr.encryptDocument(settings);
427
+
428
+ // Apply security
429
+ securityMgr.setAccessControl('restricted', { action: 'read_only' });
430
+ securityMgr.enableWatermarking('CONFIDENTIAL');
431
+ });
432
+
433
+ it('should complete document optimization workflow', () => {
434
+ const compressionMgr = new CompressionManager();
435
+ const annotationMgr = new CustomAnnotationManager();
436
+ const securityMgr = new ContentSecurityManager();
437
+
438
+ // Compress
439
+ const settings = {
440
+ level: 'BALANCED',
441
+ compress_images: true,
442
+ compress_streams: true,
443
+ compress_fonts: true,
444
+ remove_duplicates: true,
445
+ };
446
+ compressionMgr.compressDocument(settings);
447
+
448
+ // Manage annotations
449
+ const annoId = annotationMgr.createCustomAnnotation('note', { text: 'Optimized' });
450
+
451
+ // Secure
452
+ securityMgr.sanitizeContent(true, true);
453
+ });
454
+ });
455
+ });