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,386 @@
1
+ /**
2
+ * Fluent builder for creating PDF documents with configuration
3
+ *
4
+ * Provides a fluent API for configuring PDF document metadata and options
5
+ * before document creation.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { PdfBuilder } from 'pdf_oxide';
10
+ *
11
+ * const pdf = PdfBuilder.create()
12
+ * .title('My Document')
13
+ * .author('John Doe')
14
+ * .subject('PDF Creation')
15
+ * .keywords(['pdf', 'document', 'example'])
16
+ * .fromMarkdown('# Content\n\nMarkdown text here');
17
+ *
18
+ * pdf.save('output.pdf');
19
+ * ```
20
+ */
21
+
22
+ interface PdfBuilderConfig {
23
+ title?: string;
24
+ author?: string;
25
+ subject?: string;
26
+ keywords: string[];
27
+ pageSize?: string;
28
+ margins: {
29
+ top: number;
30
+ right: number;
31
+ bottom: number;
32
+ left: number;
33
+ };
34
+ }
35
+
36
+ export class PdfBuilder {
37
+ private _title?: string;
38
+ private _author?: string;
39
+ private _subject?: string;
40
+ private _keywords: string[] = [];
41
+ private _pageSize?: string;
42
+ private _margins: { top: number; right: number; bottom: number; left: number } = {
43
+ top: 36,
44
+ bottom: 36,
45
+ left: 36,
46
+ right: 36,
47
+ };
48
+
49
+ /**
50
+ * Creates a new PdfBuilder instance
51
+ * @private
52
+ */
53
+ private constructor() {}
54
+
55
+ /**
56
+ * Creates a new PdfBuilder instance
57
+ * @returns New builder instance
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * const builder = PdfBuilder.create();
62
+ * ```
63
+ */
64
+ static create(): PdfBuilder {
65
+ return new PdfBuilder();
66
+ }
67
+
68
+ /**
69
+ * Sets the document title
70
+ * @param title - The document title
71
+ * @returns This builder for chaining
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * builder.title('My Document Title');
76
+ * ```
77
+ */
78
+ title(title: string): this {
79
+ if (typeof title !== 'string' || title.length === 0) {
80
+ throw new Error('Title must be a non-empty string');
81
+ }
82
+ this._title = title;
83
+ return this;
84
+ }
85
+
86
+ /**
87
+ * Sets the document author
88
+ * @param author - The author name
89
+ * @returns This builder for chaining
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * builder.author('Jane Doe');
94
+ * ```
95
+ */
96
+ author(author: string): this {
97
+ if (typeof author !== 'string' || author.length === 0) {
98
+ throw new Error('Author must be a non-empty string');
99
+ }
100
+ this._author = author;
101
+ return this;
102
+ }
103
+
104
+ /**
105
+ * Sets the document subject
106
+ * @param subject - The document subject
107
+ * @returns This builder for chaining
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * builder.subject('Technical Documentation');
112
+ * ```
113
+ */
114
+ subject(subject: string): this {
115
+ if (typeof subject !== 'string' || subject.length === 0) {
116
+ throw new Error('Subject must be a non-empty string');
117
+ }
118
+ this._subject = subject;
119
+ return this;
120
+ }
121
+
122
+ /**
123
+ * Sets the document keywords
124
+ * @param keywords - Array of keywords
125
+ * @returns This builder for chaining
126
+ *
127
+ * @example
128
+ * ```typescript
129
+ * builder.keywords(['PDF', 'Document', 'Generation']);
130
+ * ```
131
+ */
132
+ keywords(keywords: string[]): this {
133
+ if (!Array.isArray(keywords)) {
134
+ throw new Error('Keywords must be an array');
135
+ }
136
+ if (!keywords.every((k) => typeof k === 'string')) {
137
+ throw new Error('All keywords must be strings');
138
+ }
139
+ this._keywords = keywords;
140
+ return this;
141
+ }
142
+
143
+ /**
144
+ * Adds a single keyword to the document
145
+ * @param keyword - A keyword to add
146
+ * @returns This builder for chaining
147
+ *
148
+ * @example
149
+ * ```typescript
150
+ * builder.addKeyword('Important').addKeyword('Urgent');
151
+ * ```
152
+ */
153
+ addKeyword(keyword: string): this {
154
+ if (typeof keyword !== 'string' || keyword.length === 0) {
155
+ throw new Error('Keyword must be a non-empty string');
156
+ }
157
+ this._keywords.push(keyword);
158
+ return this;
159
+ }
160
+
161
+ /**
162
+ * Sets the default page size
163
+ * @param pageSize - Page size name (e.g., 'Letter', 'A4', 'Legal')
164
+ * @returns This builder for chaining
165
+ *
166
+ * @example
167
+ * ```typescript
168
+ * builder.pageSize('A4');
169
+ * ```
170
+ */
171
+ pageSize(pageSize: string): this {
172
+ const validSizes = ['Letter', 'Legal', 'A4', 'A3', 'A5', 'B4', 'B5'];
173
+ if (!validSizes.includes(pageSize)) {
174
+ throw new Error(`Invalid page size. Must be one of: ${validSizes.join(', ')}`);
175
+ }
176
+ this._pageSize = pageSize;
177
+ return this;
178
+ }
179
+
180
+ /**
181
+ * Sets page margins
182
+ * @param top - Top margin in points
183
+ * @param right - Right margin in points
184
+ * @param bottom - Bottom margin in points
185
+ * @param left - Left margin in points
186
+ * @returns This builder for chaining
187
+ *
188
+ * @example
189
+ * ```typescript
190
+ * builder.margins(36, 36, 36, 36); // 0.5 inches on all sides
191
+ * ```
192
+ */
193
+ margins(top: number, right: number, bottom: number, left: number): this {
194
+ if (![top, right, bottom, left].every((m) => typeof m === 'number' && m >= 0)) {
195
+ throw new Error('All margins must be non-negative numbers');
196
+ }
197
+ this._margins = { top, right, bottom, left };
198
+ return this;
199
+ }
200
+
201
+ /**
202
+ * Creates a PDF document from Markdown content
203
+ * @param markdown - Markdown formatted content
204
+ * @returns The created PDF document
205
+ * @throws PdfError if PDF creation fails
206
+ *
207
+ * @example
208
+ * ```typescript
209
+ * const pdf = builder.fromMarkdown('# Title\n\nContent here');
210
+ * ```
211
+ */
212
+ fromMarkdown(markdown: string): any {
213
+ // Note: Using any for Pdf type to avoid circular dependency
214
+ const { Pdf } = require('../index.js');
215
+
216
+ if (typeof markdown !== 'string') {
217
+ throw new Error('Markdown must be a string');
218
+ }
219
+
220
+ const pdf = Pdf.fromMarkdown(markdown);
221
+ this._applyConfiguration(pdf);
222
+ return pdf;
223
+ }
224
+
225
+ /**
226
+ * Creates a PDF document from HTML content
227
+ * @param html - HTML formatted content
228
+ * @returns The created PDF document
229
+ * @throws PdfError if PDF creation fails
230
+ *
231
+ * @example
232
+ * ```typescript
233
+ * const pdf = builder.fromHtml('<h1>Title</h1><p>Content</p>');
234
+ * ```
235
+ */
236
+ fromHtml(html: string): any {
237
+ const { Pdf } = require('../index.js');
238
+
239
+ if (typeof html !== 'string') {
240
+ throw new Error('HTML must be a string');
241
+ }
242
+
243
+ const pdf = Pdf.fromHtml(html);
244
+ this._applyConfiguration(pdf);
245
+ return pdf;
246
+ }
247
+
248
+ /**
249
+ * Creates a PDF document from plain text content
250
+ * @param text - Plain text content
251
+ * @returns The created PDF document
252
+ * @throws PdfError if PDF creation fails
253
+ *
254
+ * @example
255
+ * ```typescript
256
+ * const pdf = builder.fromText('Plain text content');
257
+ * ```
258
+ */
259
+ fromText(text: string): any {
260
+ const { Pdf } = require('../index.js');
261
+
262
+ if (typeof text !== 'string') {
263
+ throw new Error('Text must be a string');
264
+ }
265
+
266
+ const pdf = Pdf.fromText(text);
267
+ this._applyConfiguration(pdf);
268
+ return pdf;
269
+ }
270
+
271
+ /**
272
+ * Asynchronously creates a PDF document from Markdown content
273
+ * @param markdown - Markdown formatted content
274
+ * @returns Promise that resolves to the created PDF document
275
+ * @throws PdfError if PDF creation fails
276
+ *
277
+ * @example
278
+ * ```typescript
279
+ * const pdf = await builder.fromMarkdownAsync('# Title\n\nContent');
280
+ * ```
281
+ */
282
+ async fromMarkdownAsync(markdown: string): Promise<any> {
283
+ const { Pdf } = require('../index.js');
284
+
285
+ if (typeof markdown !== 'string') {
286
+ throw new Error('Markdown must be a string');
287
+ }
288
+
289
+ const pdf = await Pdf.fromMarkdownAsync(markdown);
290
+ this._applyConfiguration(pdf);
291
+ return pdf;
292
+ }
293
+
294
+ /**
295
+ * Asynchronously creates a PDF document from HTML content
296
+ * @param html - HTML formatted content
297
+ * @returns Promise that resolves to the created PDF document
298
+ * @throws PdfError if PDF creation fails
299
+ *
300
+ * @example
301
+ * ```typescript
302
+ * const pdf = await builder.fromHtmlAsync('<h1>Title</h1>');
303
+ * ```
304
+ */
305
+ async fromHtmlAsync(html: string): Promise<any> {
306
+ const { Pdf } = require('../index.js');
307
+
308
+ if (typeof html !== 'string') {
309
+ throw new Error('HTML must be a string');
310
+ }
311
+
312
+ const pdf = await Pdf.fromHtmlAsync(html);
313
+ this._applyConfiguration(pdf);
314
+ return pdf;
315
+ }
316
+
317
+ /**
318
+ * Asynchronously creates a PDF document from plain text content
319
+ * @param text - Plain text content
320
+ * @returns Promise that resolves to the created PDF document
321
+ * @throws PdfError if PDF creation fails
322
+ *
323
+ * @example
324
+ * ```typescript
325
+ * const pdf = await builder.fromTextAsync('Plain text');
326
+ * ```
327
+ */
328
+ async fromTextAsync(text: string): Promise<any> {
329
+ const { Pdf } = require('../index.js');
330
+
331
+ if (typeof text !== 'string') {
332
+ throw new Error('Text must be a string');
333
+ }
334
+
335
+ const pdf = await Pdf.fromTextAsync(text);
336
+ this._applyConfiguration(pdf);
337
+ return pdf;
338
+ }
339
+
340
+ /**
341
+ * Gets the current configuration as a plain object
342
+ * @returns Configuration object with title, author, subject, keywords
343
+ *
344
+ * @private
345
+ */
346
+ private _getConfiguration(): PdfBuilderConfig {
347
+ return {
348
+ title: this._title,
349
+ author: this._author,
350
+ subject: this._subject,
351
+ keywords: this._keywords,
352
+ pageSize: this._pageSize,
353
+ margins: this._margins,
354
+ };
355
+ }
356
+
357
+ /**
358
+ * Applies builder configuration to a PDF document
359
+ * @param pdf - The PDF document to configure
360
+ * @private
361
+ */
362
+ private _applyConfiguration(pdf: any): void {
363
+ // Apply metadata properties if set
364
+ if (this._title !== undefined) {
365
+ pdf.title = this._title;
366
+ }
367
+ if (this._author !== undefined) {
368
+ pdf.author = this._author;
369
+ }
370
+ if (this._subject !== undefined) {
371
+ pdf.subject = this._subject;
372
+ }
373
+ if (this._keywords.length > 0) {
374
+ pdf.keywords = [...this._keywords];
375
+ }
376
+ }
377
+ }
378
+
379
+ /**
380
+ * Create a new PdfBuilder with static factory
381
+ * @deprecated Use PdfBuilder.create() instead
382
+ * @returns New builder instance
383
+ */
384
+ export function createPdfBuilder(): PdfBuilder {
385
+ return PdfBuilder.create();
386
+ }
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Builder for text search options
3
+ *
4
+ * Configures how text search is performed in PDF documents,
5
+ * including case sensitivity, whole word matching, and regex support.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { SearchOptionsBuilder } from 'pdf_oxide';
10
+ *
11
+ * const options = SearchOptionsBuilder.create()
12
+ * .caseSensitive(false)
13
+ * .wholeWords(true)
14
+ * .useRegex(false)
15
+ * .build();
16
+ *
17
+ * const results = doc.search('pattern', 0, options);
18
+ * ```
19
+ */
20
+
21
+ export interface SearchOptions {
22
+ caseSensitive: boolean;
23
+ wholeWords: boolean;
24
+ useRegex: boolean;
25
+ ignoreAccents: boolean;
26
+ maxResults: number;
27
+ searchAnnotations: boolean;
28
+ }
29
+
30
+ export class SearchOptionsBuilder {
31
+ private _caseSensitive: boolean = false;
32
+ private _wholeWords: boolean = false;
33
+ private _useRegex: boolean = false;
34
+ private _ignoreAccents: boolean = false;
35
+ private _maxResults: number = 1000;
36
+ private _searchAnnotations: boolean = false;
37
+
38
+ /**
39
+ * Creates a new SearchOptionsBuilder instance
40
+ * @private
41
+ */
42
+ private constructor() {}
43
+
44
+ /**
45
+ * Creates a new SearchOptionsBuilder instance
46
+ * @returns New builder instance
47
+ */
48
+ static create(): SearchOptionsBuilder {
49
+ return new SearchOptionsBuilder();
50
+ }
51
+
52
+ /**
53
+ * Creates options with default search settings (case-insensitive, no regex)
54
+ * @returns Search options with default preset
55
+ */
56
+ static default(): SearchOptions {
57
+ return SearchOptionsBuilder.create().build();
58
+ }
59
+
60
+ /**
61
+ * Creates options with strict search settings (case-sensitive, whole words, no regex)
62
+ * @returns Search options with strict preset
63
+ */
64
+ static strict(): SearchOptions {
65
+ return SearchOptionsBuilder.create()
66
+ .caseSensitive(true)
67
+ .wholeWords(true)
68
+ .useRegex(false)
69
+ .build();
70
+ }
71
+
72
+ /**
73
+ * Creates options with regex search settings
74
+ * @returns Search options with regex preset
75
+ */
76
+ static regex(): SearchOptions {
77
+ return SearchOptionsBuilder.create()
78
+ .useRegex(true)
79
+ .caseSensitive(false)
80
+ .wholeWords(false)
81
+ .build();
82
+ }
83
+
84
+ caseSensitive(sensitive: boolean): this {
85
+ if (typeof sensitive !== 'boolean') {
86
+ throw new Error('caseSensitive must be a boolean');
87
+ }
88
+ this._caseSensitive = sensitive;
89
+ return this;
90
+ }
91
+
92
+ wholeWords(wholeOnly: boolean): this {
93
+ if (typeof wholeOnly !== 'boolean') {
94
+ throw new Error('wholeWords must be a boolean');
95
+ }
96
+ this._wholeWords = wholeOnly;
97
+ return this;
98
+ }
99
+
100
+ useRegex(regex: boolean): this {
101
+ if (typeof regex !== 'boolean') {
102
+ throw new Error('useRegex must be a boolean');
103
+ }
104
+ this._useRegex = regex;
105
+ return this;
106
+ }
107
+
108
+ ignoreAccents(ignore: boolean): this {
109
+ if (typeof ignore !== 'boolean') {
110
+ throw new Error('ignoreAccents must be a boolean');
111
+ }
112
+ this._ignoreAccents = ignore;
113
+ return this;
114
+ }
115
+
116
+ maxResults(max: number): this {
117
+ if (typeof max !== 'number' || max <= 0) {
118
+ throw new Error('maxResults must be a positive number');
119
+ }
120
+ this._maxResults = Math.floor(max);
121
+ return this;
122
+ }
123
+
124
+ searchAnnotations(search: boolean): this {
125
+ if (typeof search !== 'boolean') {
126
+ throw new Error('searchAnnotations must be a boolean');
127
+ }
128
+ this._searchAnnotations = search;
129
+ return this;
130
+ }
131
+
132
+ build(): SearchOptions {
133
+ return {
134
+ caseSensitive: this._caseSensitive,
135
+ wholeWords: this._wholeWords,
136
+ useRegex: this._useRegex,
137
+ ignoreAccents: this._ignoreAccents,
138
+ maxResults: this._maxResults,
139
+ searchAnnotations: this._searchAnnotations,
140
+ };
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Create a new SearchOptionsBuilder with static factory
146
+ * @deprecated Use SearchOptionsBuilder.create() instead
147
+ * @returns New builder instance
148
+ */
149
+ export function createSearchOptionsBuilder(): SearchOptionsBuilder {
150
+ return SearchOptionsBuilder.create();
151
+ }