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.
- package/README.md +218 -0
- package/binding.gyp +35 -0
- package/package.json +78 -0
- package/src/builders/annotation-builder.ts +367 -0
- package/src/builders/conversion-options-builder.ts +257 -0
- package/src/builders/index.ts +12 -0
- package/src/builders/metadata-builder.ts +317 -0
- package/src/builders/pdf-builder.ts +386 -0
- package/src/builders/search-options-builder.ts +151 -0
- package/src/document-editor-manager.ts +318 -0
- package/src/errors.ts +1629 -0
- package/src/form-field-manager.ts +666 -0
- package/src/hybrid-ml-manager.ts +283 -0
- package/src/index.ts +453 -0
- package/src/managers/accessibility-manager.ts +338 -0
- package/src/managers/annotation-manager.ts +439 -0
- package/src/managers/barcode-manager.ts +235 -0
- package/src/managers/batch-manager.ts +533 -0
- package/src/managers/cache-manager.ts +486 -0
- package/src/managers/compliance-manager.ts +375 -0
- package/src/managers/content-manager.ts +339 -0
- package/src/managers/document-utility-manager.ts +922 -0
- package/src/managers/dom-pdf-creator.ts +365 -0
- package/src/managers/editing-manager.ts +514 -0
- package/src/managers/enterprise-manager.ts +478 -0
- package/src/managers/extended-managers.ts +437 -0
- package/src/managers/extraction-manager.ts +583 -0
- package/src/managers/final-utilities.ts +429 -0
- package/src/managers/hybrid-ml-advanced.ts +479 -0
- package/src/managers/index.ts +239 -0
- package/src/managers/layer-manager.ts +500 -0
- package/src/managers/metadata-manager.ts +303 -0
- package/src/managers/ocr-manager.ts +756 -0
- package/src/managers/optimization-manager.ts +262 -0
- package/src/managers/outline-manager.ts +196 -0
- package/src/managers/page-manager.ts +289 -0
- package/src/managers/pattern-detection.ts +440 -0
- package/src/managers/rendering-manager.ts +863 -0
- package/src/managers/search-manager.ts +385 -0
- package/src/managers/security-manager.ts +345 -0
- package/src/managers/signature-manager.ts +1664 -0
- package/src/managers/streams.ts +618 -0
- package/src/managers/xfa-manager.ts +500 -0
- package/src/pdf-creator-manager.ts +494 -0
- package/src/properties.ts +522 -0
- package/src/result-accessors-manager.ts +867 -0
- package/src/tests/advanced-features.test.ts +414 -0
- package/src/tests/advanced.test.ts +266 -0
- package/src/tests/extended-managers.test.ts +316 -0
- package/src/tests/final-utilities.test.ts +455 -0
- package/src/tests/foundation.test.ts +315 -0
- package/src/tests/high-demand.test.ts +257 -0
- package/src/tests/specialized.test.ts +97 -0
- package/src/thumbnail-manager.ts +272 -0
- package/src/types/common.ts +142 -0
- package/src/types/document-types.ts +457 -0
- package/src/types/index.ts +6 -0
- package/src/types/manager-types.ts +284 -0
- package/src/types/native-bindings.ts +517 -0
- package/src/workers/index.ts +7 -0
- package/src/workers/pool.ts +274 -0
- package/src/workers/worker.ts +131 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manager for PDF document metadata
|
|
3
|
+
*
|
|
4
|
+
* Provides access to document metadata properties such as title, author,
|
|
5
|
+
* subject, keywords, creation and modification dates, and custom properties.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { MetadataManager } from 'pdf_oxide';
|
|
10
|
+
*
|
|
11
|
+
* const doc = PdfDocument.open('document.pdf');
|
|
12
|
+
* const metadataManager = new MetadataManager(doc);
|
|
13
|
+
*
|
|
14
|
+
* console.log(`Title: ${metadataManager.getTitle()}`);
|
|
15
|
+
* console.log(`Author: ${metadataManager.getAuthor()}`);
|
|
16
|
+
* console.log(`Created: ${metadataManager.getCreationDate()}`);
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export interface MetadataComparison {
|
|
21
|
+
matching: Record<string, any>;
|
|
22
|
+
differing: Record<string, { document1: any; document2: any }>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface ValidationResult {
|
|
26
|
+
isComplete: boolean;
|
|
27
|
+
issues: string[];
|
|
28
|
+
missingFieldCount: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class MetadataManager {
|
|
32
|
+
private _document: any;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Creates a new MetadataManager for the given document
|
|
36
|
+
* @param document - The PDF document
|
|
37
|
+
* @throws Error if document is null or undefined
|
|
38
|
+
*/
|
|
39
|
+
constructor(document: any) {
|
|
40
|
+
if (!document) {
|
|
41
|
+
throw new Error('Document is required');
|
|
42
|
+
}
|
|
43
|
+
this._document = document;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Gets the document title
|
|
48
|
+
* @returns Document title or null if not set
|
|
49
|
+
*/
|
|
50
|
+
getTitle(): string | null {
|
|
51
|
+
try {
|
|
52
|
+
return this._document.documentInfo?.title || null;
|
|
53
|
+
} catch (error) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Gets the document author
|
|
60
|
+
* @returns Document author or null if not set
|
|
61
|
+
*/
|
|
62
|
+
getAuthor(): string | null {
|
|
63
|
+
try {
|
|
64
|
+
return this._document.documentInfo?.author || null;
|
|
65
|
+
} catch (error) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Gets the document subject
|
|
72
|
+
* @returns Document subject or null if not set
|
|
73
|
+
*/
|
|
74
|
+
getSubject(): string | null {
|
|
75
|
+
try {
|
|
76
|
+
return this._document.documentInfo?.subject || null;
|
|
77
|
+
} catch (error) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Gets the document keywords
|
|
84
|
+
* @returns Array of document keywords (empty if none)
|
|
85
|
+
*/
|
|
86
|
+
getKeywords(): string[] {
|
|
87
|
+
try {
|
|
88
|
+
return this._document.documentInfo?.keywords || [];
|
|
89
|
+
} catch (error) {
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Gets the document creator application
|
|
96
|
+
* @returns Creator application or null if not set
|
|
97
|
+
*/
|
|
98
|
+
getCreator(): string | null {
|
|
99
|
+
try {
|
|
100
|
+
return this._document.documentInfo?.creator || null;
|
|
101
|
+
} catch (error) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Gets the document producer application
|
|
108
|
+
* @returns Producer application or null if not set
|
|
109
|
+
*/
|
|
110
|
+
getProducer(): string | null {
|
|
111
|
+
try {
|
|
112
|
+
return this._document.documentInfo?.producer || null;
|
|
113
|
+
} catch (error) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Gets the document creation date
|
|
120
|
+
* @returns Creation date or null if not set
|
|
121
|
+
*/
|
|
122
|
+
getCreationDate(): Date | null {
|
|
123
|
+
try {
|
|
124
|
+
return this._document.documentInfo?.creationDate || null;
|
|
125
|
+
} catch (error) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Gets the document modification date
|
|
132
|
+
* @returns Modification date or null if not set
|
|
133
|
+
*/
|
|
134
|
+
getModificationDate(): Date | null {
|
|
135
|
+
try {
|
|
136
|
+
return this._document.documentInfo?.modificationDate || null;
|
|
137
|
+
} catch (error) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Gets all metadata as a single object
|
|
144
|
+
* @returns Complete metadata object
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* const metadata = manager.getAllMetadata();
|
|
149
|
+
* console.log(JSON.stringify(metadata, null, 2));
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
getAllMetadata(): Record<string, any> {
|
|
153
|
+
try {
|
|
154
|
+
return this._document.documentInfo || {};
|
|
155
|
+
} catch (error) {
|
|
156
|
+
return {};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Checks if metadata has been set
|
|
162
|
+
* @returns True if any metadata is present
|
|
163
|
+
*/
|
|
164
|
+
hasMetadata(): boolean {
|
|
165
|
+
const meta = this.getAllMetadata();
|
|
166
|
+
return Object.keys(meta).length > 0;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Gets a summary of key metadata fields
|
|
171
|
+
* @returns Formatted metadata summary
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```typescript
|
|
175
|
+
* console.log(manager.getMetadataSummary());
|
|
176
|
+
* // Output: Title: My Document, Author: John Doe, Pages: 42
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
getMetadataSummary(): string {
|
|
180
|
+
const parts: string[] = [];
|
|
181
|
+
|
|
182
|
+
const title = this.getTitle();
|
|
183
|
+
if (title) parts.push(`Title: ${title}`);
|
|
184
|
+
|
|
185
|
+
const author = this.getAuthor();
|
|
186
|
+
if (author) parts.push(`Author: ${author}`);
|
|
187
|
+
|
|
188
|
+
try {
|
|
189
|
+
parts.push(`Pages: ${this._document.pageCount}`);
|
|
190
|
+
} catch (e) {
|
|
191
|
+
// Ignore
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const subject = this.getSubject();
|
|
195
|
+
if (subject) parts.push(`Subject: ${subject}`);
|
|
196
|
+
|
|
197
|
+
const keywords = this.getKeywords();
|
|
198
|
+
if (keywords.length > 0) parts.push(`Keywords: ${keywords.join(', ')}`);
|
|
199
|
+
|
|
200
|
+
const created = this.getCreationDate();
|
|
201
|
+
if (created) parts.push(`Created: ${(created as any).toISOString()}`);
|
|
202
|
+
|
|
203
|
+
return parts.join(' | ');
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Checks if a specific keyword is present
|
|
208
|
+
* @param keyword - Keyword to search for
|
|
209
|
+
* @returns True if keyword is found
|
|
210
|
+
*/
|
|
211
|
+
hasKeyword(keyword: string): boolean {
|
|
212
|
+
if (!keyword || typeof keyword !== 'string') {
|
|
213
|
+
throw new Error('Keyword must be a non-empty string');
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const keywords = this.getKeywords();
|
|
217
|
+
return keywords.includes(keyword);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Gets the number of keywords
|
|
222
|
+
* @returns Keyword count
|
|
223
|
+
*/
|
|
224
|
+
getKeywordCount(): number {
|
|
225
|
+
return this.getKeywords().length;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Gets metadata comparison with another document
|
|
230
|
+
* @param otherDocument - Document to compare with
|
|
231
|
+
* @returns Comparison object with matching and differing fields
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```typescript
|
|
235
|
+
* const doc1 = PdfDocument.open('file1.pdf');
|
|
236
|
+
* const doc2 = PdfDocument.open('file2.pdf');
|
|
237
|
+
* const mgr1 = new MetadataManager(doc1);
|
|
238
|
+
* const comparison = mgr1.compareWith(doc2);
|
|
239
|
+
* console.log(comparison.matching); // Fields that match
|
|
240
|
+
* console.log(comparison.differing); // Fields that differ
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
243
|
+
compareWith(otherDocument: any): MetadataComparison {
|
|
244
|
+
if (!otherDocument) {
|
|
245
|
+
throw new Error('Document is required for comparison');
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const otherMgr = new MetadataManager(otherDocument);
|
|
249
|
+
const matching: Record<string, any> = {};
|
|
250
|
+
const differing: Record<string, any> = {};
|
|
251
|
+
|
|
252
|
+
const fields = [
|
|
253
|
+
{ getter: 'getTitle' as const, field: 'title' },
|
|
254
|
+
{ getter: 'getAuthor' as const, field: 'author' },
|
|
255
|
+
{ getter: 'getSubject' as const, field: 'subject' },
|
|
256
|
+
{ getter: 'getCreator' as const, field: 'creator' },
|
|
257
|
+
{ getter: 'getProducer' as const, field: 'producer' },
|
|
258
|
+
];
|
|
259
|
+
|
|
260
|
+
fields.forEach(({ getter, field }) => {
|
|
261
|
+
const val1 = this[getter]();
|
|
262
|
+
const val2 = otherMgr[getter]();
|
|
263
|
+
|
|
264
|
+
if (val1 === val2) {
|
|
265
|
+
matching[field] = val1;
|
|
266
|
+
} else {
|
|
267
|
+
differing[field] = { document1: val1, document2: val2 };
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
return { matching, differing };
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Validates metadata completeness
|
|
276
|
+
* @returns Validation result with issues array
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* ```typescript
|
|
280
|
+
* const validation = manager.validate();
|
|
281
|
+
* if (validation.isComplete) {
|
|
282
|
+
* console.log('Metadata is complete');
|
|
283
|
+
* } else {
|
|
284
|
+
* console.log('Issues:', validation.issues);
|
|
285
|
+
* }
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
validate(): ValidationResult {
|
|
289
|
+
const issues: string[] = [];
|
|
290
|
+
|
|
291
|
+
if (!this.getTitle()) issues.push('Title is missing');
|
|
292
|
+
if (!this.getAuthor()) issues.push('Author is missing');
|
|
293
|
+
if (!this.getSubject()) issues.push('Subject is missing');
|
|
294
|
+
if (this.getKeywordCount() === 0) issues.push('Keywords are missing');
|
|
295
|
+
if (!this.getCreationDate()) issues.push('Creation date is missing');
|
|
296
|
+
|
|
297
|
+
return {
|
|
298
|
+
isComplete: issues.length === 0,
|
|
299
|
+
issues,
|
|
300
|
+
missingFieldCount: issues.length,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
}
|