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.
- package/LICENSE-APACHE +176 -0
- package/LICENSE-MIT +25 -0
- package/README.md +218 -0
- package/lib/builders/annotation-builder.d.ts +198 -0
- package/lib/builders/annotation-builder.js +317 -0
- package/lib/builders/conversion-options-builder.d.ts +106 -0
- package/lib/builders/conversion-options-builder.js +214 -0
- package/lib/builders/document-builder.d.ts +381 -0
- package/lib/builders/document-builder.js +770 -0
- package/lib/builders/index.d.ts +13 -0
- package/lib/builders/index.js +13 -0
- package/lib/builders/metadata-builder.d.ts +201 -0
- package/lib/builders/metadata-builder.js +285 -0
- package/lib/builders/pdf-builder.d.ts +216 -0
- package/lib/builders/pdf-builder.js +350 -0
- package/lib/builders/search-options-builder.d.ts +73 -0
- package/lib/builders/search-options-builder.js +129 -0
- package/lib/builders/streaming-table.d.ts +64 -0
- package/lib/builders/streaming-table.js +140 -0
- package/lib/document-editor-manager.d.ts +139 -0
- package/lib/document-editor-manager.js +256 -0
- package/lib/document-editor.d.ts +124 -0
- package/lib/document-editor.js +318 -0
- package/lib/errors.d.ts +382 -0
- package/lib/errors.js +1115 -0
- package/lib/form-field-manager.d.ts +299 -0
- package/lib/form-field-manager.js +568 -0
- package/lib/hybrid-ml-manager.d.ts +142 -0
- package/lib/hybrid-ml-manager.js +208 -0
- package/lib/index.d.ts +205 -0
- package/lib/index.js +693 -0
- package/lib/managers/accessibility-manager.d.ts +148 -0
- package/lib/managers/accessibility-manager.js +234 -0
- package/lib/managers/annotation-manager.d.ts +219 -0
- package/lib/managers/annotation-manager.js +359 -0
- package/lib/managers/barcode-manager.d.ts +82 -0
- package/lib/managers/barcode-manager.js +263 -0
- package/lib/managers/batch-manager.d.ts +185 -0
- package/lib/managers/batch-manager.js +385 -0
- package/lib/managers/cache-manager.d.ts +181 -0
- package/lib/managers/cache-manager.js +384 -0
- package/lib/managers/compliance-manager.d.ts +103 -0
- package/lib/managers/compliance-manager.js +453 -0
- package/lib/managers/content-manager.d.ts +120 -0
- package/lib/managers/content-manager.js +294 -0
- package/lib/managers/document-utility-manager.d.ts +369 -0
- package/lib/managers/document-utility-manager.js +730 -0
- package/lib/managers/dom-pdf-creator.d.ts +104 -0
- package/lib/managers/dom-pdf-creator.js +299 -0
- package/lib/managers/editing-manager.d.ts +248 -0
- package/lib/managers/editing-manager.js +387 -0
- package/lib/managers/enterprise-manager.d.ts +192 -0
- package/lib/managers/enterprise-manager.js +307 -0
- package/lib/managers/extended-managers.d.ts +122 -0
- package/lib/managers/extended-managers.js +664 -0
- package/lib/managers/extraction-manager.d.ts +246 -0
- package/lib/managers/extraction-manager.js +482 -0
- package/lib/managers/final-utilities.d.ts +127 -0
- package/lib/managers/final-utilities.js +657 -0
- package/lib/managers/hybrid-ml-advanced.d.ts +136 -0
- package/lib/managers/hybrid-ml-advanced.js +722 -0
- package/lib/managers/index.d.ts +64 -0
- package/lib/managers/index.js +69 -0
- package/lib/managers/layer-manager.d.ts +203 -0
- package/lib/managers/layer-manager.js +401 -0
- package/lib/managers/metadata-manager.d.ts +148 -0
- package/lib/managers/metadata-manager.js +280 -0
- package/lib/managers/ocr-manager.d.ts +194 -0
- package/lib/managers/ocr-manager.js +582 -0
- package/lib/managers/optimization-manager.d.ts +102 -0
- package/lib/managers/optimization-manager.js +213 -0
- package/lib/managers/outline-manager.d.ts +101 -0
- package/lib/managers/outline-manager.js +169 -0
- package/lib/managers/page-manager.d.ts +142 -0
- package/lib/managers/page-manager.js +235 -0
- package/lib/managers/pattern-detection.d.ts +169 -0
- package/lib/managers/pattern-detection.js +322 -0
- package/lib/managers/rendering-manager.d.ts +353 -0
- package/lib/managers/rendering-manager.js +679 -0
- package/lib/managers/search-manager.d.ts +235 -0
- package/lib/managers/search-manager.js +329 -0
- package/lib/managers/security-manager.d.ts +161 -0
- package/lib/managers/security-manager.js +292 -0
- package/lib/managers/signature-manager.d.ts +738 -0
- package/lib/managers/signature-manager.js +1509 -0
- package/lib/managers/streams.d.ts +262 -0
- package/lib/managers/streams.js +477 -0
- package/lib/managers/xfa-manager.d.ts +227 -0
- package/lib/managers/xfa-manager.js +539 -0
- 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.d.ts +200 -0
- package/lib/pdf-creator-manager.js +381 -0
- package/lib/properties.d.ts +79 -0
- package/lib/properties.js +454 -0
- package/lib/result-accessors-manager.d.ts +346 -0
- package/lib/result-accessors-manager.js +706 -0
- package/lib/thumbnail-manager.d.ts +121 -0
- package/lib/thumbnail-manager.js +205 -0
- 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 +189 -0
- package/lib/types/common.js +17 -0
- package/lib/types/document-types.d.ts +352 -0
- package/lib/types/document-types.js +82 -0
- package/lib/types/index.d.ts +5 -0
- package/lib/types/index.js +5 -0
- package/lib/types/manager-types.d.ts +179 -0
- package/lib/types/manager-types.js +100 -0
- package/lib/types/native-bindings.d.ts +439 -0
- package/lib/types/native-bindings.js +7 -0
- package/lib/workers/index.d.ts +6 -0
- package/lib/workers/index.js +5 -0
- package/lib/workers/pool.d.ts +64 -0
- package/lib/workers/pool.js +192 -0
- package/lib/workers/worker.d.ts +5 -0
- package/lib/workers/worker.js +99 -0
- package/package.json +79 -0
- 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
ADDED
|
@@ -0,0 +1,693 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
2
|
+
// PDF Oxide Node.js bindings - Native module loader
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
import { dirname } from 'node:path';
|
|
5
|
+
import { arch, platform } from 'node:process';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import { Align, AnnotationBuilder, ConversionOptionsBuilder, DocumentBuilder, EmbeddedFont, MetadataBuilder, PageBuilder, PdfBuilder, SearchOptionsBuilder, StreamingTable, } from './builders/index.js';
|
|
8
|
+
import { DocumentEditor } from './document-editor.js';
|
|
9
|
+
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';
|
|
10
|
+
import { AnnotationManager, BatchManager, createExtractionStream, createMetadataStream, createSearchStream, ExtractionManager, ExtractionStream, LayerManager, MetadataManager, MetadataStream, OutlineManager, RenderingManager, SearchManager, SearchStream, SecurityManager, } from './managers/index.js';
|
|
11
|
+
import { WorkerPool, workerPool } from './workers/index.js';
|
|
12
|
+
// Create require function for CommonJS modules
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = dirname(__filename);
|
|
15
|
+
const require = createRequire(import.meta.url);
|
|
16
|
+
// Phase 4+ managers (compiled JavaScript - use require for dynamic import)
|
|
17
|
+
// Phase 9: Now imports from canonical consolidated managers in managers/
|
|
18
|
+
const { OcrManager, OcrManager: OCRManager, OcrDetectionMode: OCRDetectionMode, ComplianceManager, PdfALevel, PdfXLevel, PdfUALevel, ComplianceIssueType, IssueSeverity, SignatureManager, SignatureAlgorithm, DigestAlgorithm, BarcodeManager, BarcodeFormat, BarcodeErrorCorrection, FormFieldManager, FormFieldType, FieldVisibility, ResultAccessorsManager, SearchResultProperties, FontProperties, ImageProperties, AnnotationProperties, ThumbnailManager, ThumbnailSize, ImageFormat, HybridMLManager, PageComplexity, ContentType, XfaManager, XfaFormType, XfaFieldType, CacheManager, EditingManager, AccessibilityManager, OptimizationManager, EnterpriseManager, } = require('../lib/managers/index.js');
|
|
19
|
+
// OcrLanguage re-exported from canonical OcrManager
|
|
20
|
+
const { OcrLanguage: OCRLanguage } = require('../lib/managers/ocr-manager.js');
|
|
21
|
+
/**
|
|
22
|
+
* Platform-specific prebuild paths (relative to compiled lib/index.js).
|
|
23
|
+
* At runtime lib/index.js lives at js/lib/index.js, so ../prebuilds/
|
|
24
|
+
* resolves to js/prebuilds/.
|
|
25
|
+
*/
|
|
26
|
+
const PLATFORMS = {
|
|
27
|
+
darwin: {
|
|
28
|
+
x64: '../prebuilds/darwin-x64/pdf_oxide.node',
|
|
29
|
+
arm64: '../prebuilds/darwin-arm64/pdf_oxide.node',
|
|
30
|
+
},
|
|
31
|
+
linux: {
|
|
32
|
+
x64: '../prebuilds/linux-x64/pdf_oxide.node',
|
|
33
|
+
arm64: '../prebuilds/linux-arm64/pdf_oxide.node',
|
|
34
|
+
},
|
|
35
|
+
win32: {
|
|
36
|
+
x64: '../prebuilds/win32-x64/pdf_oxide.node',
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Gets the prebuild path for the current platform and architecture
|
|
41
|
+
* @returns Path to the prebuild .node file (relative to lib/index.js)
|
|
42
|
+
* @throws Error if platform or architecture is not supported
|
|
43
|
+
*/
|
|
44
|
+
function getPrebuildPath() {
|
|
45
|
+
const osPaths = PLATFORMS[platform];
|
|
46
|
+
if (!osPaths) {
|
|
47
|
+
throw new Error(`Unsupported platform: ${platform}. Supported platforms: ${Object.keys(PLATFORMS).join(', ')}`);
|
|
48
|
+
}
|
|
49
|
+
const prebuildPath = osPaths[arch];
|
|
50
|
+
if (!prebuildPath) {
|
|
51
|
+
throw new Error(`Unsupported architecture: ${arch} for ${platform}. Supported architectures: ${Object.keys(osPaths).join(', ')}`);
|
|
52
|
+
}
|
|
53
|
+
return prebuildPath;
|
|
54
|
+
}
|
|
55
|
+
let nativeModule;
|
|
56
|
+
/**
|
|
57
|
+
* Loads the native module dynamically based on platform and architecture.
|
|
58
|
+
* Prebuilt .node files are bundled under prebuilds/<triple>/ in the package.
|
|
59
|
+
* @returns Native module
|
|
60
|
+
* @throws Error if native module cannot be loaded
|
|
61
|
+
*/
|
|
62
|
+
function loadNativeModule() {
|
|
63
|
+
if (nativeModule) {
|
|
64
|
+
return nativeModule;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const prebuildPath = getPrebuildPath();
|
|
68
|
+
try {
|
|
69
|
+
// Load the bundled prebuild .node file
|
|
70
|
+
nativeModule = require(prebuildPath);
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
// Fallback to local build output if in development
|
|
74
|
+
if (process.env.NODE_ENV === 'development' || process.env.NAPI_DEV) {
|
|
75
|
+
try {
|
|
76
|
+
nativeModule = require('./pdf-oxide');
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
throw e;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
throw e;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return nativeModule;
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
throw new Error(`Failed to load native module: ${error.message}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Load native module
|
|
93
|
+
const native = loadNativeModule();
|
|
94
|
+
/**
|
|
95
|
+
* Wraps native class methods to convert errors to proper JavaScript Error subclasses.
|
|
96
|
+
* This ensures that errors thrown from native code are instanceof the appropriate Error class.
|
|
97
|
+
* @param nativeClass - The native class to wrap
|
|
98
|
+
* @param asyncMethods - Names of async methods to wrap specially
|
|
99
|
+
* @returns Wrapped class with error-handling methods
|
|
100
|
+
*/
|
|
101
|
+
function wrapNativeClass(nativeClass, asyncMethods = []) {
|
|
102
|
+
if (!nativeClass)
|
|
103
|
+
return nativeClass;
|
|
104
|
+
// For static methods like PdfDocument.open()
|
|
105
|
+
for (const key of Object.getOwnPropertyNames(nativeClass)) {
|
|
106
|
+
if (key !== 'prototype' &&
|
|
107
|
+
key !== 'length' &&
|
|
108
|
+
key !== 'name' &&
|
|
109
|
+
typeof nativeClass[key] === 'function') {
|
|
110
|
+
const isAsync = asyncMethods.includes(key);
|
|
111
|
+
if (isAsync) {
|
|
112
|
+
nativeClass[key] = wrapAsyncMethod(nativeClass[key], nativeClass);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
nativeClass[key] = wrapMethod(nativeClass[key], nativeClass);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// For instance methods, wrap the prototype
|
|
120
|
+
if (nativeClass.prototype) {
|
|
121
|
+
for (const key of Object.getOwnPropertyNames(nativeClass.prototype)) {
|
|
122
|
+
if (key !== 'constructor' && typeof nativeClass.prototype[key] === 'function') {
|
|
123
|
+
const isAsync = asyncMethods.includes(key);
|
|
124
|
+
const descriptor = Object.getOwnPropertyDescriptor(nativeClass.prototype, key);
|
|
125
|
+
if (descriptor && descriptor.writable) {
|
|
126
|
+
if (isAsync) {
|
|
127
|
+
nativeClass.prototype[key] = wrapAsyncMethod(nativeClass.prototype[key]);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
nativeClass.prototype[key] = wrapMethod(nativeClass.prototype[key]);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return nativeClass;
|
|
137
|
+
}
|
|
138
|
+
class PdfDocumentImpl {
|
|
139
|
+
constructor(handle) {
|
|
140
|
+
this._closed = false;
|
|
141
|
+
/** Promise-cached mutex; single Promise ensures no race on concurrent first calls. */
|
|
142
|
+
this._muPromise = null;
|
|
143
|
+
if (!handle)
|
|
144
|
+
throw new Error('Failed to open document');
|
|
145
|
+
this._handle = handle;
|
|
146
|
+
}
|
|
147
|
+
static open(path) {
|
|
148
|
+
const handle = native.openDocument(path);
|
|
149
|
+
return new PdfDocumentImpl(handle);
|
|
150
|
+
}
|
|
151
|
+
static openFromBuffer(buffer) {
|
|
152
|
+
const handle = native.openFromBuffer(buffer);
|
|
153
|
+
return new PdfDocumentImpl(handle);
|
|
154
|
+
}
|
|
155
|
+
static openWithPassword(path, password) {
|
|
156
|
+
const handle = native.openWithPassword(path, password);
|
|
157
|
+
return new PdfDocumentImpl(handle);
|
|
158
|
+
}
|
|
159
|
+
ensureOpen() {
|
|
160
|
+
if (this._closed)
|
|
161
|
+
throw new Error('Document is closed');
|
|
162
|
+
}
|
|
163
|
+
get handle() {
|
|
164
|
+
return this._handle;
|
|
165
|
+
}
|
|
166
|
+
pageCount() {
|
|
167
|
+
this.ensureOpen();
|
|
168
|
+
return native.getPageCount(this._handle);
|
|
169
|
+
}
|
|
170
|
+
getPageCount() {
|
|
171
|
+
return this.pageCount();
|
|
172
|
+
}
|
|
173
|
+
get PageCount() {
|
|
174
|
+
return this.pageCount();
|
|
175
|
+
}
|
|
176
|
+
extractText(pageIndex) {
|
|
177
|
+
this.ensureOpen();
|
|
178
|
+
return native.extractText(this._handle, pageIndex);
|
|
179
|
+
}
|
|
180
|
+
toMarkdown(pageIndex) {
|
|
181
|
+
this.ensureOpen();
|
|
182
|
+
return native.toMarkdown(this._handle, pageIndex);
|
|
183
|
+
}
|
|
184
|
+
toHtml(pageIndex) {
|
|
185
|
+
this.ensureOpen();
|
|
186
|
+
return native.toHtml(this._handle, pageIndex);
|
|
187
|
+
}
|
|
188
|
+
toPlainText(pageIndex) {
|
|
189
|
+
this.ensureOpen();
|
|
190
|
+
return native.toPlainText(this._handle, pageIndex);
|
|
191
|
+
}
|
|
192
|
+
toMarkdownAll() {
|
|
193
|
+
this.ensureOpen();
|
|
194
|
+
return native.toMarkdownAll(this._handle);
|
|
195
|
+
}
|
|
196
|
+
extractAllText() {
|
|
197
|
+
this.ensureOpen();
|
|
198
|
+
return native.extractAllText(this._handle);
|
|
199
|
+
}
|
|
200
|
+
toHtmlAll() {
|
|
201
|
+
this.ensureOpen();
|
|
202
|
+
return native.toHtmlAll(this._handle);
|
|
203
|
+
}
|
|
204
|
+
toPlainTextAll() {
|
|
205
|
+
this.ensureOpen();
|
|
206
|
+
return native.toPlainTextAll(this._handle);
|
|
207
|
+
}
|
|
208
|
+
getVersion() {
|
|
209
|
+
this.ensureOpen();
|
|
210
|
+
return native.getVersion(this._handle);
|
|
211
|
+
}
|
|
212
|
+
hasStructureTree() {
|
|
213
|
+
this.ensureOpen();
|
|
214
|
+
return native.hasStructureTree(this._handle);
|
|
215
|
+
}
|
|
216
|
+
hasXFA() {
|
|
217
|
+
this.ensureOpen();
|
|
218
|
+
return native.hasXFA(this._handle);
|
|
219
|
+
}
|
|
220
|
+
getPageWidth(pageIndex) {
|
|
221
|
+
this.ensureOpen();
|
|
222
|
+
return native.getPageWidth(this._handle, pageIndex);
|
|
223
|
+
}
|
|
224
|
+
getPageHeight(pageIndex) {
|
|
225
|
+
this.ensureOpen();
|
|
226
|
+
return native.getPageHeight(this._handle, pageIndex);
|
|
227
|
+
}
|
|
228
|
+
getPageRotation(pageIndex) {
|
|
229
|
+
this.ensureOpen();
|
|
230
|
+
return native.getPageRotation(this._handle, pageIndex);
|
|
231
|
+
}
|
|
232
|
+
searchPage(pageIndex, query, caseSensitive = false) {
|
|
233
|
+
this.ensureOpen();
|
|
234
|
+
return native.searchPage(this._handle, pageIndex, query, caseSensitive);
|
|
235
|
+
}
|
|
236
|
+
searchAll(query, caseSensitive = false) {
|
|
237
|
+
this.ensureOpen();
|
|
238
|
+
return native.searchAll(this._handle, query, caseSensitive);
|
|
239
|
+
}
|
|
240
|
+
getFormFields() {
|
|
241
|
+
this.ensureOpen();
|
|
242
|
+
return native.getFormFields(this._handle);
|
|
243
|
+
}
|
|
244
|
+
getOutline() {
|
|
245
|
+
this.ensureOpen();
|
|
246
|
+
return native.getOutline(this._handle);
|
|
247
|
+
}
|
|
248
|
+
getPageAnnotations(pageIndex) {
|
|
249
|
+
this.ensureOpen();
|
|
250
|
+
return native.getPageAnnotations(this._handle, pageIndex);
|
|
251
|
+
}
|
|
252
|
+
getEmbeddedFonts(pageIndex) {
|
|
253
|
+
this.ensureOpen();
|
|
254
|
+
return native.getEmbeddedFonts(this._handle, pageIndex);
|
|
255
|
+
}
|
|
256
|
+
getEmbeddedImages(pageIndex) {
|
|
257
|
+
this.ensureOpen();
|
|
258
|
+
return native.getEmbeddedImages(this._handle, pageIndex);
|
|
259
|
+
}
|
|
260
|
+
extractWords(pageIndex) {
|
|
261
|
+
this.ensureOpen();
|
|
262
|
+
return native.extractWords(this._handle, pageIndex);
|
|
263
|
+
}
|
|
264
|
+
extractTextLines(pageIndex) {
|
|
265
|
+
this.ensureOpen();
|
|
266
|
+
return native.extractTextLines(this._handle, pageIndex);
|
|
267
|
+
}
|
|
268
|
+
extractTables(pageIndex) {
|
|
269
|
+
this.ensureOpen();
|
|
270
|
+
return native.extractTables(this._handle, pageIndex);
|
|
271
|
+
}
|
|
272
|
+
extractPaths(pageIndex) {
|
|
273
|
+
this.ensureOpen();
|
|
274
|
+
return native.extractPaths(this._handle, pageIndex);
|
|
275
|
+
}
|
|
276
|
+
ocrExtractText(pageIndex, engineHandle) {
|
|
277
|
+
this.ensureOpen();
|
|
278
|
+
return native.ocrExtractText(this._handle, pageIndex, engineHandle);
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Render a page with the full Rust `RenderOptions` surface
|
|
282
|
+
* (DPI, format, RGBA background, transparency, annotation toggle,
|
|
283
|
+
* JPEG quality). Returns the image bytes.
|
|
284
|
+
*/
|
|
285
|
+
renderPageWithOptions(pageIndex, options = {}) {
|
|
286
|
+
this.ensureOpen();
|
|
287
|
+
const dpi = options.dpi ?? 150;
|
|
288
|
+
if (dpi <= 0)
|
|
289
|
+
throw new RangeError(`dpi must be > 0, got ${dpi}`);
|
|
290
|
+
const format = options.format === 'jpeg' ? 1 : 0;
|
|
291
|
+
const quality = options.jpegQuality ?? 85;
|
|
292
|
+
if (quality < 1 || quality > 100) {
|
|
293
|
+
throw new RangeError(`jpegQuality must be in 1..=100, got ${quality}`);
|
|
294
|
+
}
|
|
295
|
+
const bg = options.background ?? [1, 1, 1, 1];
|
|
296
|
+
const renderAnnotations = options.renderAnnotations === false ? 0 : 1;
|
|
297
|
+
const transparent = options.transparentBackground ? 1 : 0;
|
|
298
|
+
const imgHandle = native.renderPageWithOptions(this._handle, pageIndex, dpi, format, bg[0], bg[1], bg[2], bg[3], transparent, renderAnnotations, quality);
|
|
299
|
+
try {
|
|
300
|
+
const buf = native.pdfGetRenderedImageData(imgHandle);
|
|
301
|
+
return new Uint8Array(buf);
|
|
302
|
+
}
|
|
303
|
+
finally {
|
|
304
|
+
if (native.freeRenderedImage) {
|
|
305
|
+
native.freeRenderedImage(imgHandle);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Estimate render time (milliseconds) for a page at a given DPI.
|
|
311
|
+
* Thin wrapper around the existing `estimateRenderTime` N-API
|
|
312
|
+
* export — exposed in TS for the first time as part of gap L.
|
|
313
|
+
*/
|
|
314
|
+
estimateRenderTime(pageIndex, dpi = 150) {
|
|
315
|
+
this.ensureOpen();
|
|
316
|
+
return native.estimateRenderTime(this._handle, pageIndex, dpi);
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Render a page to fit inside a `width × height` pixel box, preserving
|
|
320
|
+
* aspect ratio. Picks the largest DPI such that both rendered
|
|
321
|
+
* dimensions are ≤ the target box, so the output may be smaller than
|
|
322
|
+
* `width × height` on one axis. Issue #448.
|
|
323
|
+
*
|
|
324
|
+
* @param pageIndex zero-based page index
|
|
325
|
+
* @param width target box width (pixels, must be > 0)
|
|
326
|
+
* @param height target box height (pixels, must be > 0)
|
|
327
|
+
* @param format `'png'` (default) or `'jpeg'`
|
|
328
|
+
*/
|
|
329
|
+
renderPageFit(pageIndex, width, height, format = 'png') {
|
|
330
|
+
this.ensureOpen();
|
|
331
|
+
if (width <= 0 || height <= 0) {
|
|
332
|
+
throw new RangeError(`width and height must be > 0, got ${width}×${height}`);
|
|
333
|
+
}
|
|
334
|
+
const fmt = format === 'jpeg' ? 1 : 0;
|
|
335
|
+
const imgHandle = native.renderPageFit(this._handle, pageIndex, width, height, fmt);
|
|
336
|
+
try {
|
|
337
|
+
const buf = native.pdfGetRenderedImageData(imgHandle);
|
|
338
|
+
return new Uint8Array(buf);
|
|
339
|
+
}
|
|
340
|
+
finally {
|
|
341
|
+
if (native.freeRenderedImage) {
|
|
342
|
+
native.freeRenderedImage(imgHandle);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/** Lazy-initialises the per-instance Mutex (avoids a hard dep at load time). */
|
|
347
|
+
_getMutex() {
|
|
348
|
+
if (!this._muPromise) {
|
|
349
|
+
this._muPromise = import('async-mutex').then(({ Mutex }) => new Mutex());
|
|
350
|
+
}
|
|
351
|
+
return this._muPromise;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Async variant of {@link renderPageWithOptions} serialised through a
|
|
355
|
+
* per-instance mutex. Use when calling from `worker_threads` or `Promise.all`.
|
|
356
|
+
*/
|
|
357
|
+
async renderPageWithOptionsAsync(pageIndex, options = {}) {
|
|
358
|
+
const mu = await this._getMutex();
|
|
359
|
+
return mu.runExclusive(() => this.renderPageWithOptions(pageIndex, options));
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Async variant of {@link renderPageFit} serialised through a per-instance mutex.
|
|
363
|
+
*/
|
|
364
|
+
async renderPageFitAsync(pageIndex, width, height, format = 'png') {
|
|
365
|
+
const mu = await this._getMutex();
|
|
366
|
+
return mu.runExclusive(() => this.renderPageFit(pageIndex, width, height, format));
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Renders a page as raw premultiplied RGBA8888 pixels. No PNG/JPEG encoding
|
|
370
|
+
* overhead — useful for direct handoff to image-processing libraries.
|
|
371
|
+
* @param pageIndex Zero-based page index.
|
|
372
|
+
* @param dpi Resolution in dots per inch (default 150).
|
|
373
|
+
*/
|
|
374
|
+
renderToPixmap(pageIndex, dpi = 150) {
|
|
375
|
+
this.ensureOpen();
|
|
376
|
+
if (dpi <= 0)
|
|
377
|
+
throw new RangeError(`dpi must be > 0, got ${dpi}`);
|
|
378
|
+
const { imgHandle, width, height } = native.renderPageRaw(this._handle, pageIndex, dpi);
|
|
379
|
+
try {
|
|
380
|
+
const buf = native.pdfGetRenderedImageData(imgHandle);
|
|
381
|
+
return { data: Buffer.from(buf), width, height };
|
|
382
|
+
}
|
|
383
|
+
finally {
|
|
384
|
+
if (native.freeRenderedImage)
|
|
385
|
+
native.freeRenderedImage(imgHandle);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Async variant of {@link renderToPixmap} serialised through a per-instance mutex.
|
|
390
|
+
*/
|
|
391
|
+
async renderToPixmapAsync(pageIndex, dpi = 150) {
|
|
392
|
+
const mu = await this._getMutex();
|
|
393
|
+
return mu.runExclusive(() => this.renderToPixmap(pageIndex, dpi));
|
|
394
|
+
}
|
|
395
|
+
page(index) {
|
|
396
|
+
this.ensureOpen();
|
|
397
|
+
const count = this.pageCount();
|
|
398
|
+
const idx = index < 0 ? count + index : index;
|
|
399
|
+
if (idx < 0 || idx >= count)
|
|
400
|
+
throw new RangeError(`page index ${index} out of range`);
|
|
401
|
+
return new Page(this, idx);
|
|
402
|
+
}
|
|
403
|
+
[Symbol.iterator]() {
|
|
404
|
+
this.ensureOpen();
|
|
405
|
+
const count = this.pageCount();
|
|
406
|
+
let i = 0;
|
|
407
|
+
const doc = this;
|
|
408
|
+
return {
|
|
409
|
+
next() {
|
|
410
|
+
if (i >= count)
|
|
411
|
+
return { value: undefined, done: true };
|
|
412
|
+
return { value: new Page(doc, i++), done: false };
|
|
413
|
+
},
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Async iteration over the document's pages — issue #447. The body
|
|
418
|
+
* is identical to the sync iterator (page handles are constructed
|
|
419
|
+
* synchronously) but exposing this surface lets consumers `for await`
|
|
420
|
+
* uniformly with other async resources without an explicit
|
|
421
|
+
* `Promise.resolve(...)`.
|
|
422
|
+
*/
|
|
423
|
+
[Symbol.asyncIterator]() {
|
|
424
|
+
this.ensureOpen();
|
|
425
|
+
const count = this.pageCount();
|
|
426
|
+
let i = 0;
|
|
427
|
+
const doc = this;
|
|
428
|
+
return {
|
|
429
|
+
async next() {
|
|
430
|
+
if (i >= count)
|
|
431
|
+
return { value: undefined, done: true };
|
|
432
|
+
return { value: new Page(doc, i++), done: false };
|
|
433
|
+
},
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Validate PDF/A conformance at a given level.
|
|
438
|
+
* @param level - "1a"|"1b"|"2a"|"2b"|"2u"|"3a"|"3b"|"3u" (default "2b")
|
|
439
|
+
*/
|
|
440
|
+
validatePdfA(level = '2b') {
|
|
441
|
+
this.ensureOpen();
|
|
442
|
+
const levelMap = {
|
|
443
|
+
'1b': 0,
|
|
444
|
+
'1a': 1,
|
|
445
|
+
'2b': 2,
|
|
446
|
+
'2a': 3,
|
|
447
|
+
'2u': 4,
|
|
448
|
+
'3b': 5,
|
|
449
|
+
'3a': 6,
|
|
450
|
+
'3u': 7,
|
|
451
|
+
};
|
|
452
|
+
const levelInt = levelMap[level];
|
|
453
|
+
if (levelInt === undefined)
|
|
454
|
+
throw new RangeError(`Unknown PDF/A level: "${level}"`);
|
|
455
|
+
return native.validatePdfALevel(this._handle, levelInt);
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Convert document to PDF/A conformance in-place.
|
|
459
|
+
* @param level - "1b"|"2b"|"2u"|"3b" etc. (default "2b")
|
|
460
|
+
* @returns true if the document is fully PDF/A-compliant after conversion (false if errors remain, e.g. fonts not embeddable without the rendering feature)
|
|
461
|
+
*/
|
|
462
|
+
convertToPdfA(level = '2b') {
|
|
463
|
+
this.ensureOpen();
|
|
464
|
+
const levelMap = {
|
|
465
|
+
'1b': 0,
|
|
466
|
+
'1a': 1,
|
|
467
|
+
'2b': 2,
|
|
468
|
+
'2a': 3,
|
|
469
|
+
'2u': 4,
|
|
470
|
+
'3b': 5,
|
|
471
|
+
'3a': 6,
|
|
472
|
+
'3u': 7,
|
|
473
|
+
};
|
|
474
|
+
const levelInt = levelMap[level];
|
|
475
|
+
if (levelInt === undefined)
|
|
476
|
+
throw new RangeError(`Unknown PDF/A level: "${level}"`);
|
|
477
|
+
return native.convertToPdfA(this._handle, levelInt);
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Return the current document bytes (including any in-place modifications
|
|
481
|
+
* made by convertToPdfA).
|
|
482
|
+
*/
|
|
483
|
+
toBuffer() {
|
|
484
|
+
this.ensureOpen();
|
|
485
|
+
return native.documentGetSourceBytes(this._handle);
|
|
486
|
+
}
|
|
487
|
+
close() {
|
|
488
|
+
if (!this._closed && this._handle) {
|
|
489
|
+
native.closeDocument(this._handle);
|
|
490
|
+
this._closed = true;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
[Symbol.dispose]() {
|
|
494
|
+
this.close();
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
class Page {
|
|
498
|
+
constructor(doc, index) {
|
|
499
|
+
this._cache = new Map();
|
|
500
|
+
this._doc = doc;
|
|
501
|
+
this._index = index;
|
|
502
|
+
}
|
|
503
|
+
get index() {
|
|
504
|
+
return this._index;
|
|
505
|
+
}
|
|
506
|
+
get width() {
|
|
507
|
+
if (!this._cache.has('width'))
|
|
508
|
+
this._cache.set('width', this._doc.getPageWidth(this._index));
|
|
509
|
+
return this._cache.get('width');
|
|
510
|
+
}
|
|
511
|
+
get height() {
|
|
512
|
+
if (!this._cache.has('height'))
|
|
513
|
+
this._cache.set('height', this._doc.getPageHeight(this._index));
|
|
514
|
+
return this._cache.get('height');
|
|
515
|
+
}
|
|
516
|
+
get rotation() {
|
|
517
|
+
if (!this._cache.has('rotation'))
|
|
518
|
+
this._cache.set('rotation', this._doc.getPageRotation(this._index));
|
|
519
|
+
return this._cache.get('rotation');
|
|
520
|
+
}
|
|
521
|
+
text() {
|
|
522
|
+
return this._doc.extractText(this._index);
|
|
523
|
+
}
|
|
524
|
+
markdown() {
|
|
525
|
+
return this._doc.toMarkdown(this._index);
|
|
526
|
+
}
|
|
527
|
+
html() {
|
|
528
|
+
return this._doc.toHtml(this._index);
|
|
529
|
+
}
|
|
530
|
+
plainText() {
|
|
531
|
+
return this._doc.toPlainText(this._index);
|
|
532
|
+
}
|
|
533
|
+
words() {
|
|
534
|
+
return this._doc.extractWords(this._index);
|
|
535
|
+
}
|
|
536
|
+
lines() {
|
|
537
|
+
return this._doc.extractTextLines(this._index);
|
|
538
|
+
}
|
|
539
|
+
tables() {
|
|
540
|
+
return this._doc.extractTables(this._index);
|
|
541
|
+
}
|
|
542
|
+
images() {
|
|
543
|
+
return this._doc.getEmbeddedImages(this._index);
|
|
544
|
+
}
|
|
545
|
+
paths() {
|
|
546
|
+
return this._doc.extractPaths(this._index);
|
|
547
|
+
}
|
|
548
|
+
annotations() {
|
|
549
|
+
return this._doc.getPageAnnotations(this._index);
|
|
550
|
+
}
|
|
551
|
+
fonts() {
|
|
552
|
+
return this._doc.getEmbeddedFonts(this._index);
|
|
553
|
+
}
|
|
554
|
+
search(query, caseSensitive = false) {
|
|
555
|
+
return this._doc.searchPage(this._index, query, caseSensitive);
|
|
556
|
+
}
|
|
557
|
+
toString() {
|
|
558
|
+
return `Page(index=${this._index})`;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
class PdfImpl {
|
|
562
|
+
constructor(handle) {
|
|
563
|
+
this._closed = false;
|
|
564
|
+
if (!handle)
|
|
565
|
+
throw new Error('Failed to create PDF');
|
|
566
|
+
this._handle = handle;
|
|
567
|
+
}
|
|
568
|
+
static fromMarkdown(markdown) {
|
|
569
|
+
return new PdfImpl(native.pdfFromMarkdown(markdown));
|
|
570
|
+
}
|
|
571
|
+
static fromHtml(html) {
|
|
572
|
+
return new PdfImpl(native.pdfFromHtml(html));
|
|
573
|
+
}
|
|
574
|
+
static fromText(text) {
|
|
575
|
+
return new PdfImpl(native.pdfFromText(text));
|
|
576
|
+
}
|
|
577
|
+
static fromImage(path) {
|
|
578
|
+
return new PdfImpl(native.pdfFromImage(path));
|
|
579
|
+
}
|
|
580
|
+
static fromImageBytes(data) {
|
|
581
|
+
return new PdfImpl(native.pdfFromImageBytes(data));
|
|
582
|
+
}
|
|
583
|
+
static fromHtmlCss(html, css, fontBytes) {
|
|
584
|
+
return new PdfImpl(native.pdfFromHtmlCss(html, css, fontBytes));
|
|
585
|
+
}
|
|
586
|
+
static fromHtmlCssWithFonts(html, css, families, fonts) {
|
|
587
|
+
if (families.length !== fonts.length) {
|
|
588
|
+
throw new Error(`fromHtmlCssWithFonts: families.length (${families.length}) must equal fonts.length (${fonts.length})`);
|
|
589
|
+
}
|
|
590
|
+
return new PdfImpl(native.pdfFromHtmlCssWithFonts(html, css, families, fonts));
|
|
591
|
+
}
|
|
592
|
+
ensureOpen() {
|
|
593
|
+
if (this._closed)
|
|
594
|
+
throw new Error('PDF handle is closed');
|
|
595
|
+
}
|
|
596
|
+
save(path) {
|
|
597
|
+
this.ensureOpen();
|
|
598
|
+
native.pdfSave(this._handle, path);
|
|
599
|
+
}
|
|
600
|
+
saveToBytes() {
|
|
601
|
+
this.ensureOpen();
|
|
602
|
+
return native.pdfSaveToBytes(this._handle);
|
|
603
|
+
}
|
|
604
|
+
pageCount() {
|
|
605
|
+
this.ensureOpen();
|
|
606
|
+
return native.pdfGetPageCount(this._handle);
|
|
607
|
+
}
|
|
608
|
+
close() {
|
|
609
|
+
if (!this._closed && this._handle) {
|
|
610
|
+
native.pdfFree(this._handle);
|
|
611
|
+
this._closed = true;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
[Symbol.dispose]() {
|
|
615
|
+
this.close();
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
// Generate a 1D barcode as a vector SVG string.
|
|
619
|
+
// format: 0=Code128, 1=Code39, 2=EAN13, 3=EAN8, 4=UPCA, 5=ITF, 6=Code93, 7=Codabar.
|
|
620
|
+
function generateBarcodeSvg(data, format = 0, sizePx = 300) {
|
|
621
|
+
const handle = native.generateBarcode(format, data);
|
|
622
|
+
try {
|
|
623
|
+
return native.barcodeGetSVG(handle, sizePx);
|
|
624
|
+
}
|
|
625
|
+
finally {
|
|
626
|
+
native.freeBarcode(handle);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
// Generate a QR code as a vector SVG string.
|
|
630
|
+
// errorCorrection: 0=Low, 1=Medium, 2=Quartile, 3=High.
|
|
631
|
+
function generateQrCodeSvg(data, errorCorrection = 1, sizePx = 300) {
|
|
632
|
+
const handle = native.generateQRCode(data, errorCorrection);
|
|
633
|
+
try {
|
|
634
|
+
return native.barcodeGetSVG(handle, sizePx);
|
|
635
|
+
}
|
|
636
|
+
finally {
|
|
637
|
+
native.freeBarcode(handle);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
// Export as ES module
|
|
641
|
+
const getVersion = native.getVersion;
|
|
642
|
+
const getPdfOxideVersion = native.getPdfOxideVersion;
|
|
643
|
+
const getActiveCryptoProvider = native.getActiveCryptoProvider;
|
|
644
|
+
const isFipsCryptoAvailable = native.isFipsCryptoAvailable;
|
|
645
|
+
const useFipsCryptoProvider = native.useFipsCryptoProvider;
|
|
646
|
+
const PdfDocument = PdfDocumentImpl;
|
|
647
|
+
const Pdf = PdfImpl;
|
|
648
|
+
const PdfError = PdfException;
|
|
649
|
+
const PageSize = native.PageSize;
|
|
650
|
+
const Rect = native.Rect;
|
|
651
|
+
const Point = native.Point;
|
|
652
|
+
const Color = native.Color;
|
|
653
|
+
const ConversionOptions = native.ConversionOptions;
|
|
654
|
+
const SearchOptions = native.SearchOptions;
|
|
655
|
+
const SearchResult = native.SearchResult;
|
|
656
|
+
const TextSearcher = native.TextSearcher;
|
|
657
|
+
// RFC 3161 Timestamp + TSA Client — standalone, re-exported from
|
|
658
|
+
// their own modules so downstream users get the full API surface.
|
|
659
|
+
export { Timestamp, TimestampHashAlgorithm } from './timestamp.js';
|
|
660
|
+
export { TsaClient } from './tsa-client.js';
|
|
661
|
+
export { AccessibilityException, AccessibilityManager,
|
|
662
|
+
// v0.3.39 — DocumentBuilder tables (#393)
|
|
663
|
+
Align, AnnotationBuilder, AnnotationManager, AnnotationProperties, BarcodeErrorCorrection, BarcodeFormat, BarcodeManager,
|
|
664
|
+
// Phase 2.5: Batch Processing API
|
|
665
|
+
BatchManager, CacheManager, CertificateLoadFailed, Color, ComplianceException, ComplianceIssueType, ComplianceManager, ContentType, ConversionOptions, ConversionOptionsBuilder, createExtractionStream, createMetadataStream, createSearchStream, DigestAlgorithm,
|
|
666
|
+
// Write-side fluent API
|
|
667
|
+
DocumentBuilder,
|
|
668
|
+
// Editor mutation API
|
|
669
|
+
DocumentEditor, EditingManager, EmbeddedFont, EncryptionException, EnterpriseManager,
|
|
670
|
+
// Error utilities
|
|
671
|
+
ErrorCategory, ErrorSeverity, ExtractionManager, ExtractionStream, FieldVisibility, FontProperties, FormFieldManager, FormFieldType, generateBarcodeSvg, generateQrCodeSvg, getActiveCryptoProvider, getPdfOxideVersion,
|
|
672
|
+
// Version info
|
|
673
|
+
getVersion, HybridMLManager, ImageFormat, ImageProperties, InvalidStateException, IoException, IssueSeverity, isFipsCryptoAvailable, LayerManager, MetadataBuilder, MetadataManager, MetadataStream, mapFfiErrorCode, OCRDetectionMode, OCRLanguage, OCRManager, OcrException,
|
|
674
|
+
// Managers (Phase 4+, consolidated in Phase 9)
|
|
675
|
+
OcrManager, OptimizationException, OptimizationManager,
|
|
676
|
+
// Managers (Phase 1-3: Core)
|
|
677
|
+
OutlineManager, Page, PageBuilder, PageComplexity,
|
|
678
|
+
// Types
|
|
679
|
+
PageSize, ParseException, Pdf, PdfALevel,
|
|
680
|
+
// Builders
|
|
681
|
+
PdfBuilder,
|
|
682
|
+
// Main classes
|
|
683
|
+
PdfDocument,
|
|
684
|
+
// Error types
|
|
685
|
+
PdfError, PdfException, PdfUALevel, PdfXLevel, Point, Rect, RedactionException, RenderingException, RenderingManager, ResultAccessorsManager, SearchException, SearchManager, SearchOptions, SearchOptionsBuilder, SearchResult, SearchResultProperties,
|
|
686
|
+
// Phase 2.4: Stream API
|
|
687
|
+
SearchStream, SecurityManager, SignatureAlgorithm, SignatureException, SignatureManager, SigningFailed,
|
|
688
|
+
// v0.3.39 — managed streaming-table adapter (#393)
|
|
689
|
+
StreamingTable,
|
|
690
|
+
// Utilities
|
|
691
|
+
TextSearcher, ThumbnailManager, ThumbnailSize, UnknownError, UnsupportedFeatureException, useFipsCryptoProvider, ValidationException,
|
|
692
|
+
// Worker Threads API
|
|
693
|
+
WorkerPool, workerPool, wrapAsyncMethod, wrapError, wrapMethod, XfaFieldType, XfaFormType, XfaManager, };
|