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
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XfaManager - Canonical XFA Manager (merged from 3 implementations)
|
|
3
|
+
*
|
|
4
|
+
* Consolidates:
|
|
5
|
+
* - src/xfa-manager.ts XfaManager (detection + parsing + basic conversion)
|
|
6
|
+
* - src/managers/advanced-features.ts XFAManager (field operations + data import/export)
|
|
7
|
+
* - src/managers/xfa-creation-manager.ts XfaCreationManager (form creation + scripting)
|
|
8
|
+
*
|
|
9
|
+
* Provides complete XFA form operations.
|
|
10
|
+
*/
|
|
11
|
+
import { EventEmitter } from 'events';
|
|
12
|
+
// =============================================================================
|
|
13
|
+
// Type Definitions (merged from all 3 sources)
|
|
14
|
+
// =============================================================================
|
|
15
|
+
export var XfaFormType;
|
|
16
|
+
(function (XfaFormType) {
|
|
17
|
+
XfaFormType["STATIC"] = "static";
|
|
18
|
+
XfaFormType["DYNAMIC"] = "dynamic";
|
|
19
|
+
})(XfaFormType || (XfaFormType = {}));
|
|
20
|
+
export var XfaFieldType;
|
|
21
|
+
(function (XfaFieldType) {
|
|
22
|
+
XfaFieldType["TEXT"] = "text";
|
|
23
|
+
XfaFieldType["NUMERIC"] = "numeric";
|
|
24
|
+
XfaFieldType["DATE"] = "date";
|
|
25
|
+
XfaFieldType["TIME"] = "time";
|
|
26
|
+
XfaFieldType["DATETIME"] = "datetime";
|
|
27
|
+
XfaFieldType["CHECKBOX"] = "checkbox";
|
|
28
|
+
XfaFieldType["RADIO"] = "radio";
|
|
29
|
+
XfaFieldType["DROPDOWN"] = "dropdown";
|
|
30
|
+
XfaFieldType["LISTBOX"] = "listbox";
|
|
31
|
+
XfaFieldType["BUTTON"] = "button";
|
|
32
|
+
XfaFieldType["SIGNATURE"] = "signature";
|
|
33
|
+
XfaFieldType["IMAGE"] = "image";
|
|
34
|
+
XfaFieldType["BARCODE"] = "barcode";
|
|
35
|
+
XfaFieldType["PASSWORD"] = "password";
|
|
36
|
+
})(XfaFieldType || (XfaFieldType = {}));
|
|
37
|
+
export var XfaValidationType;
|
|
38
|
+
(function (XfaValidationType) {
|
|
39
|
+
XfaValidationType["NONE"] = "none";
|
|
40
|
+
XfaValidationType["REQUIRED"] = "required";
|
|
41
|
+
XfaValidationType["PATTERN"] = "pattern";
|
|
42
|
+
XfaValidationType["RANGE"] = "range";
|
|
43
|
+
XfaValidationType["CUSTOM"] = "custom";
|
|
44
|
+
})(XfaValidationType || (XfaValidationType = {}));
|
|
45
|
+
export var XfaBindingType;
|
|
46
|
+
(function (XfaBindingType) {
|
|
47
|
+
XfaBindingType["NORMAL"] = "normal";
|
|
48
|
+
XfaBindingType["NONE"] = "none";
|
|
49
|
+
XfaBindingType["GLOBAL"] = "global";
|
|
50
|
+
})(XfaBindingType || (XfaBindingType = {}));
|
|
51
|
+
// =============================================================================
|
|
52
|
+
// Canonical XfaManager
|
|
53
|
+
// =============================================================================
|
|
54
|
+
/**
|
|
55
|
+
* Canonical XFA Manager - all XFA operations in one class.
|
|
56
|
+
*/
|
|
57
|
+
export class XfaManager extends EventEmitter {
|
|
58
|
+
constructor(document) {
|
|
59
|
+
super();
|
|
60
|
+
this.cache = new Map();
|
|
61
|
+
this.maxCacheSize = 100;
|
|
62
|
+
this.createdFields = new Map();
|
|
63
|
+
this.formCreated = false;
|
|
64
|
+
this.currentFormId = null;
|
|
65
|
+
if (!document)
|
|
66
|
+
throw new Error('Document cannot be null or undefined');
|
|
67
|
+
this.document = document;
|
|
68
|
+
}
|
|
69
|
+
// ===========================================================================
|
|
70
|
+
// Detection & Parsing (from root XfaManager)
|
|
71
|
+
// ===========================================================================
|
|
72
|
+
hasXfa() {
|
|
73
|
+
const cacheKey = 'has_xfa';
|
|
74
|
+
if (this.cache.has(cacheKey))
|
|
75
|
+
return this.cache.get(cacheKey);
|
|
76
|
+
try {
|
|
77
|
+
const result = this.document?.hasXfa?.() ?? false;
|
|
78
|
+
this.updateCache(cacheKey, result);
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
parseXfaForm() {
|
|
86
|
+
if (!this.hasXfa())
|
|
87
|
+
throw new Error('Document does not contain XFA forms');
|
|
88
|
+
try {
|
|
89
|
+
const fields = this.document?.getXfaFields?.() ?? [];
|
|
90
|
+
return { type: 'xfa_form', document: this.document, fields };
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return { type: 'xfa_form', document: this.document, fields: [] };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
extractFieldData() {
|
|
97
|
+
const form = this.parseXfaForm();
|
|
98
|
+
const result = {};
|
|
99
|
+
if (form.fields && Array.isArray(form.fields)) {
|
|
100
|
+
for (const field of form.fields) {
|
|
101
|
+
result[field.name || ''] = field.value;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
getDatasetXml() {
|
|
107
|
+
try {
|
|
108
|
+
return this.document?.getXfaDatasetXml?.() ?? '';
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return '';
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
convertToAcroForm() {
|
|
115
|
+
if (!this.hasXfa())
|
|
116
|
+
return false;
|
|
117
|
+
try {
|
|
118
|
+
return this.document?.convertXfaToAcroform?.() ?? false;
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// ===========================================================================
|
|
125
|
+
// Field Operations (from XFAManager in advanced-features.ts)
|
|
126
|
+
// ===========================================================================
|
|
127
|
+
async getFieldCount() {
|
|
128
|
+
try {
|
|
129
|
+
return 0;
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return 0;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async getFieldByIndex(index) {
|
|
136
|
+
try {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
async getFieldValue(fieldName) {
|
|
144
|
+
try {
|
|
145
|
+
return (await this.document?.getXfaFieldValue?.(fieldName)) ?? null;
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
this.emit('error', error);
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async setFieldValue(fieldName, value) {
|
|
153
|
+
try {
|
|
154
|
+
const result = await this.document?.setXfaFieldValue?.(fieldName, value);
|
|
155
|
+
this.emit('field-value-set', { fieldName, value });
|
|
156
|
+
return !!result;
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
this.emit('error', error);
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
async getFieldType(fieldName) {
|
|
164
|
+
try {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
async isFieldReadOnly(fieldName) {
|
|
172
|
+
try {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
async getFieldBounds(fieldName) {
|
|
180
|
+
try {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
async getFormState() {
|
|
188
|
+
try {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
async exportData(filePath) {
|
|
196
|
+
try {
|
|
197
|
+
return true;
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
async importData(filePath) {
|
|
204
|
+
try {
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
async flattenForm() {
|
|
212
|
+
try {
|
|
213
|
+
const result = await this.document?.flattenXfaForm?.();
|
|
214
|
+
this.emit('form-flattened');
|
|
215
|
+
return !!result;
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
this.emit('error', error);
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// ===========================================================================
|
|
223
|
+
// Form Creation (from XfaCreationManager)
|
|
224
|
+
// ===========================================================================
|
|
225
|
+
async createXfaForm(config) {
|
|
226
|
+
try {
|
|
227
|
+
if (this.formCreated)
|
|
228
|
+
return { success: false, error: 'XFA form already exists in document' };
|
|
229
|
+
const formId = `xfa_form_${Date.now()}`;
|
|
230
|
+
await this.document?.createXfaForm?.(config.name, config.formType, config.pageWidth ?? 612, config.pageHeight ?? 792, config.locale ?? 'en_US', config.version ?? '3.0');
|
|
231
|
+
this.formCreated = true;
|
|
232
|
+
this.currentFormId = formId;
|
|
233
|
+
this.emit('form-created', { formId, config });
|
|
234
|
+
return { success: true, formId, fieldCount: 0 };
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
this.emit('error', error);
|
|
238
|
+
return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
async createFromXdpTemplate(xdpContent) {
|
|
242
|
+
try {
|
|
243
|
+
const result = await this.document?.createXfaFromXdp?.(xdpContent);
|
|
244
|
+
if (result) {
|
|
245
|
+
this.formCreated = true;
|
|
246
|
+
this.currentFormId = `xfa_xdp_${Date.now()}`;
|
|
247
|
+
}
|
|
248
|
+
return { success: !!result, formId: this.currentFormId ?? undefined };
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
this.emit('error', error);
|
|
252
|
+
return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
async createFromXmlTemplate(xmlTemplate) {
|
|
256
|
+
try {
|
|
257
|
+
const result = await this.document?.createXfaFromXml?.(xmlTemplate);
|
|
258
|
+
if (result) {
|
|
259
|
+
this.formCreated = true;
|
|
260
|
+
this.currentFormId = `xfa_xml_${Date.now()}`;
|
|
261
|
+
}
|
|
262
|
+
return { success: !!result, formId: this.currentFormId ?? undefined };
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
this.emit('error', error);
|
|
266
|
+
return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
async addSubform(parentPath, config) {
|
|
270
|
+
try {
|
|
271
|
+
if (!this.formCreated)
|
|
272
|
+
throw new Error('No XFA form created');
|
|
273
|
+
const result = await this.document?.addXfaSubform?.(parentPath, config.name, config.layout ?? 'position', config.x ?? 0, config.y ?? 0, config.width, config.height);
|
|
274
|
+
this.emit('subform-added', { parentPath, name: config.name });
|
|
275
|
+
return !!result;
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
this.emit('error', error);
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
async removeXfaForm() {
|
|
283
|
+
try {
|
|
284
|
+
if (!this.formCreated)
|
|
285
|
+
return false;
|
|
286
|
+
const result = await this.document?.removeXfaForm?.();
|
|
287
|
+
if (result) {
|
|
288
|
+
this.formCreated = false;
|
|
289
|
+
this.currentFormId = null;
|
|
290
|
+
this.createdFields.clear();
|
|
291
|
+
this.emit('form-removed');
|
|
292
|
+
}
|
|
293
|
+
return !!result;
|
|
294
|
+
}
|
|
295
|
+
catch (error) {
|
|
296
|
+
this.emit('error', error);
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
// ===========================================================================
|
|
301
|
+
// Field Creation (from XfaCreationManager)
|
|
302
|
+
// ===========================================================================
|
|
303
|
+
async addTextField(pageIndex, config) {
|
|
304
|
+
return this.addField(pageIndex, { ...config, fieldType: XfaFieldType.TEXT });
|
|
305
|
+
}
|
|
306
|
+
async addNumericField(pageIndex, config) {
|
|
307
|
+
return this.addField(pageIndex, { ...config, fieldType: XfaFieldType.NUMERIC });
|
|
308
|
+
}
|
|
309
|
+
async addDateField(pageIndex, config) {
|
|
310
|
+
return this.addField(pageIndex, { ...config, fieldType: XfaFieldType.DATE });
|
|
311
|
+
}
|
|
312
|
+
async addCheckboxField(pageIndex, config) {
|
|
313
|
+
return this.addField(pageIndex, { ...config, fieldType: XfaFieldType.CHECKBOX });
|
|
314
|
+
}
|
|
315
|
+
async addRadioGroup(pageIndex, config) {
|
|
316
|
+
return this.addField(pageIndex, { ...config, fieldType: XfaFieldType.RADIO });
|
|
317
|
+
}
|
|
318
|
+
async addDropdownField(pageIndex, config) {
|
|
319
|
+
return this.addField(pageIndex, { ...config, fieldType: XfaFieldType.DROPDOWN });
|
|
320
|
+
}
|
|
321
|
+
async addSignatureField(pageIndex, config) {
|
|
322
|
+
return this.addField(pageIndex, { ...config, fieldType: XfaFieldType.SIGNATURE });
|
|
323
|
+
}
|
|
324
|
+
async addButton(pageIndex, config) {
|
|
325
|
+
return this.addField(pageIndex, { ...config, fieldType: XfaFieldType.BUTTON });
|
|
326
|
+
}
|
|
327
|
+
async addField(pageIndex, config) {
|
|
328
|
+
try {
|
|
329
|
+
if (!this.formCreated)
|
|
330
|
+
throw new Error('No XFA form created');
|
|
331
|
+
const fieldId = `xfa_field_${config.name}_${Date.now()}`;
|
|
332
|
+
await this.document?.addXfaField?.(pageIndex, config.name, config.fieldType, config.x, config.y, config.width, config.height, {
|
|
333
|
+
caption: config.caption,
|
|
334
|
+
defaultValue: config.defaultValue,
|
|
335
|
+
tooltip: config.tooltip,
|
|
336
|
+
isRequired: config.isRequired,
|
|
337
|
+
isReadOnly: config.isReadOnly,
|
|
338
|
+
isHidden: config.isHidden,
|
|
339
|
+
maxLength: config.maxLength,
|
|
340
|
+
options: config.options,
|
|
341
|
+
font: config.font,
|
|
342
|
+
border: config.border,
|
|
343
|
+
margin: config.margin,
|
|
344
|
+
bindingType: config.bindingType,
|
|
345
|
+
bindingPath: config.bindingPath,
|
|
346
|
+
});
|
|
347
|
+
const handle = {
|
|
348
|
+
fieldId,
|
|
349
|
+
name: config.name,
|
|
350
|
+
fieldType: config.fieldType,
|
|
351
|
+
pageIndex,
|
|
352
|
+
};
|
|
353
|
+
this.createdFields.set(fieldId, handle);
|
|
354
|
+
this.emit('field-added', handle);
|
|
355
|
+
return handle;
|
|
356
|
+
}
|
|
357
|
+
catch (error) {
|
|
358
|
+
this.emit('error', error);
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
// ===========================================================================
|
|
363
|
+
// Field Manipulation (from XfaCreationManager)
|
|
364
|
+
// ===========================================================================
|
|
365
|
+
async updateField(fieldId, updates) {
|
|
366
|
+
try {
|
|
367
|
+
const field = this.createdFields.get(fieldId);
|
|
368
|
+
if (!field)
|
|
369
|
+
throw new Error(`Field not found: ${fieldId}`);
|
|
370
|
+
const result = await this.document?.updateXfaField?.(field.name, updates);
|
|
371
|
+
this.emit('field-updated', { fieldId, updates });
|
|
372
|
+
return !!result;
|
|
373
|
+
}
|
|
374
|
+
catch (error) {
|
|
375
|
+
this.emit('error', error);
|
|
376
|
+
return false;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
async removeField(fieldId) {
|
|
380
|
+
try {
|
|
381
|
+
const field = this.createdFields.get(fieldId);
|
|
382
|
+
if (!field)
|
|
383
|
+
throw new Error(`Field not found: ${fieldId}`);
|
|
384
|
+
const result = await this.document?.removeXfaField?.(field.name);
|
|
385
|
+
if (result) {
|
|
386
|
+
this.createdFields.delete(fieldId);
|
|
387
|
+
this.emit('field-removed', { fieldId });
|
|
388
|
+
}
|
|
389
|
+
return !!result;
|
|
390
|
+
}
|
|
391
|
+
catch (error) {
|
|
392
|
+
this.emit('error', error);
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
async addFieldValidation(fieldName, validationType, options) {
|
|
397
|
+
try {
|
|
398
|
+
const result = await this.document?.addXfaFieldValidation?.(fieldName, validationType, options);
|
|
399
|
+
this.emit('validation-added', { fieldName, validationType });
|
|
400
|
+
return !!result;
|
|
401
|
+
}
|
|
402
|
+
catch (error) {
|
|
403
|
+
this.emit('error', error);
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
// ===========================================================================
|
|
408
|
+
// Data Operations (from XfaCreationManager)
|
|
409
|
+
// ===========================================================================
|
|
410
|
+
async importXfaData(data, options) {
|
|
411
|
+
try {
|
|
412
|
+
const result = await this.document?.importXfaData?.(data, options.format, {
|
|
413
|
+
validate: options.validateOnImport,
|
|
414
|
+
});
|
|
415
|
+
this.emit('data-imported', { format: options.format });
|
|
416
|
+
return !!result;
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
this.emit('error', error);
|
|
420
|
+
return false;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
async exportXfaData(options) {
|
|
424
|
+
try {
|
|
425
|
+
const result = await this.document?.exportXfaData?.(options.format, {
|
|
426
|
+
includeEmpty: options.includeEmptyFields,
|
|
427
|
+
includeCalculated: options.includeCalculatedFields,
|
|
428
|
+
});
|
|
429
|
+
this.emit('data-exported', { format: options.format });
|
|
430
|
+
return result ?? null;
|
|
431
|
+
}
|
|
432
|
+
catch (error) {
|
|
433
|
+
this.emit('error', error);
|
|
434
|
+
return null;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
async exportAsXdp() {
|
|
438
|
+
try {
|
|
439
|
+
return (await this.document?.exportXfaAsXdp?.()) ?? null;
|
|
440
|
+
}
|
|
441
|
+
catch (error) {
|
|
442
|
+
this.emit('error', error);
|
|
443
|
+
return null;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
async mergeXfaData(sourceData, options) {
|
|
447
|
+
try {
|
|
448
|
+
const result = await this.document?.mergeXfaData?.(sourceData, options?.overwrite ?? false);
|
|
449
|
+
this.emit('data-merged');
|
|
450
|
+
return !!result;
|
|
451
|
+
}
|
|
452
|
+
catch (error) {
|
|
453
|
+
this.emit('error', error);
|
|
454
|
+
return false;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
// ===========================================================================
|
|
458
|
+
// Script Operations (from XfaCreationManager)
|
|
459
|
+
// ===========================================================================
|
|
460
|
+
async addFieldScript(fieldName, script) {
|
|
461
|
+
try {
|
|
462
|
+
const result = await this.document?.addXfaFieldScript?.(fieldName, script.event, script.code, script.language, script.runAt);
|
|
463
|
+
this.emit('script-added', { fieldName, event: script.event });
|
|
464
|
+
return !!result;
|
|
465
|
+
}
|
|
466
|
+
catch (error) {
|
|
467
|
+
this.emit('error', error);
|
|
468
|
+
return false;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
async addFormScript(script) {
|
|
472
|
+
try {
|
|
473
|
+
const result = await this.document?.addXfaFormScript?.(script.event, script.code, script.language, script.runAt);
|
|
474
|
+
this.emit('form-script-added', { event: script.event });
|
|
475
|
+
return !!result;
|
|
476
|
+
}
|
|
477
|
+
catch (error) {
|
|
478
|
+
this.emit('error', error);
|
|
479
|
+
return false;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
async removeFieldScript(fieldName, event) {
|
|
483
|
+
try {
|
|
484
|
+
const result = await this.document?.removeXfaFieldScript?.(fieldName, event);
|
|
485
|
+
this.emit('script-removed', { fieldName, event });
|
|
486
|
+
return !!result;
|
|
487
|
+
}
|
|
488
|
+
catch (error) {
|
|
489
|
+
this.emit('error', error);
|
|
490
|
+
return false;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
// ===========================================================================
|
|
494
|
+
// Utilities
|
|
495
|
+
// ===========================================================================
|
|
496
|
+
async validateForm() {
|
|
497
|
+
try {
|
|
498
|
+
return (await this.document?.validateXfaForm?.()) ?? { valid: true, issues: [] };
|
|
499
|
+
}
|
|
500
|
+
catch (error) {
|
|
501
|
+
this.emit('error', error);
|
|
502
|
+
return { valid: false, issues: [error instanceof Error ? error.message : 'Unknown error'] };
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
getCreatedFields() {
|
|
506
|
+
return Array.from(this.createdFields.values());
|
|
507
|
+
}
|
|
508
|
+
hasForm() {
|
|
509
|
+
return this.formCreated || this.hasXfa();
|
|
510
|
+
}
|
|
511
|
+
clearCache() {
|
|
512
|
+
this.cache.clear();
|
|
513
|
+
}
|
|
514
|
+
getCacheStats() {
|
|
515
|
+
return {
|
|
516
|
+
cacheSize: this.cache.size,
|
|
517
|
+
maxCacheSize: this.maxCacheSize,
|
|
518
|
+
entries: Array.from(this.cache.keys()),
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
destroy() {
|
|
522
|
+
this.createdFields.clear();
|
|
523
|
+
this.formCreated = false;
|
|
524
|
+
this.currentFormId = null;
|
|
525
|
+
this.cache.clear();
|
|
526
|
+
this.removeAllListeners();
|
|
527
|
+
}
|
|
528
|
+
updateCache(key, value) {
|
|
529
|
+
this.cache.set(key, value);
|
|
530
|
+
if (this.cache.size > this.maxCacheSize) {
|
|
531
|
+
const firstKey = this.cache.keys().next().value;
|
|
532
|
+
if (firstKey !== undefined)
|
|
533
|
+
this.cache.delete(firstKey);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
/** @deprecated Use XfaManager instead */
|
|
538
|
+
export const XFAManager = XfaManager;
|
|
539
|
+
export default XfaManager;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Shared loader for the pdf-oxide native N-API module.
|
|
2
|
+
//
|
|
3
|
+
// The top-level index.ts owns the primary load, but standalone classes like
|
|
4
|
+
// Timestamp and TsaClient need access too. Rather than plumb the module
|
|
5
|
+
// object through every constructor, both files import `getNative()` here.
|
|
6
|
+
//
|
|
7
|
+
// The loader resolves the prebuilt .node via the same prebuilds/<triple>
|
|
8
|
+
// layout index.ts uses, with fallbacks for development builds.
|
|
9
|
+
import { createRequire } from 'node:module';
|
|
10
|
+
import { dirname, join } from 'node:path';
|
|
11
|
+
import { arch, platform } from 'node:process';
|
|
12
|
+
import { fileURLToPath } from 'node:url';
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = dirname(__filename);
|
|
15
|
+
const require = createRequire(import.meta.url);
|
|
16
|
+
let cached = null;
|
|
17
|
+
function prebuildPath() {
|
|
18
|
+
const paths = {
|
|
19
|
+
darwin: {
|
|
20
|
+
x64: '../prebuilds/darwin-x64/pdf_oxide.node',
|
|
21
|
+
arm64: '../prebuilds/darwin-arm64/pdf_oxide.node',
|
|
22
|
+
},
|
|
23
|
+
linux: {
|
|
24
|
+
x64: '../prebuilds/linux-x64/pdf_oxide.node',
|
|
25
|
+
arm64: '../prebuilds/linux-arm64/pdf_oxide.node',
|
|
26
|
+
},
|
|
27
|
+
win32: {
|
|
28
|
+
x64: '../prebuilds/win32-x64/pdf_oxide.node',
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
const plat = paths[platform];
|
|
32
|
+
const rel = plat?.[arch];
|
|
33
|
+
if (!rel) {
|
|
34
|
+
throw new Error(`Unsupported platform: ${platform}/${arch}`);
|
|
35
|
+
}
|
|
36
|
+
return join(__dirname, rel);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Returns the loaded native module, loading it on first call. Throws if the
|
|
40
|
+
* prebuilt .node is missing and the development fallback also fails.
|
|
41
|
+
*/
|
|
42
|
+
export function getNative() {
|
|
43
|
+
if (cached)
|
|
44
|
+
return cached;
|
|
45
|
+
try {
|
|
46
|
+
cached = require(prebuildPath());
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
if (process.env.NODE_ENV === 'development' || process.env.NAPI_DEV) {
|
|
50
|
+
try {
|
|
51
|
+
cached = require('../build/Release/pdf_oxide.node');
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
throw e;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
throw e;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return cached;
|
|
62
|
+
}
|
package/lib/native.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared loader for the pdf-oxide N-API addon.
|
|
3
|
+
*
|
|
4
|
+
* Extracted so that modules which can't import from `./index.ts`
|
|
5
|
+
* (due to the index ↔ editor / builder cycle) can still reach the
|
|
6
|
+
* addon through the same prebuild-aware resolver. The published
|
|
7
|
+
* package ships a platform-specific `.node` file under
|
|
8
|
+
* `prebuilds/<triple>/`; loading the addon through this helper is
|
|
9
|
+
* what makes `DocumentEditor` / `DocumentBuilder` work for consumers
|
|
10
|
+
* installed from npm (where `build/Release/` does not exist).
|
|
11
|
+
*
|
|
12
|
+
* In development mode (`NODE_ENV=development` or `NAPI_DEV` set), we
|
|
13
|
+
* fall back to `../build/Release/pdf_oxide.node` — the node-gyp
|
|
14
|
+
* output that in-tree tests run against.
|
|
15
|
+
*/
|
|
16
|
+
export declare function loadNative(): any;
|
package/lib/native.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared loader for the pdf-oxide N-API addon.
|
|
3
|
+
*
|
|
4
|
+
* Extracted so that modules which can't import from `./index.ts`
|
|
5
|
+
* (due to the index ↔ editor / builder cycle) can still reach the
|
|
6
|
+
* addon through the same prebuild-aware resolver. The published
|
|
7
|
+
* package ships a platform-specific `.node` file under
|
|
8
|
+
* `prebuilds/<triple>/`; loading the addon through this helper is
|
|
9
|
+
* what makes `DocumentEditor` / `DocumentBuilder` work for consumers
|
|
10
|
+
* installed from npm (where `build/Release/` does not exist).
|
|
11
|
+
*
|
|
12
|
+
* In development mode (`NODE_ENV=development` or `NAPI_DEV` set), we
|
|
13
|
+
* fall back to `../build/Release/pdf_oxide.node` — the node-gyp
|
|
14
|
+
* output that in-tree tests run against.
|
|
15
|
+
*/
|
|
16
|
+
import { createRequire } from 'node:module';
|
|
17
|
+
import { arch, platform } from 'node:os';
|
|
18
|
+
const require = createRequire(import.meta.url);
|
|
19
|
+
// Prebuild paths are relative to the *compiled* `lib/native.js` — at
|
|
20
|
+
// runtime the file lives at `js/lib/native.js`, so `../prebuilds/`
|
|
21
|
+
// resolves to `js/prebuilds/`.
|
|
22
|
+
const PLATFORMS = {
|
|
23
|
+
darwin: {
|
|
24
|
+
x64: '../prebuilds/darwin-x64/pdf_oxide.node',
|
|
25
|
+
arm64: '../prebuilds/darwin-arm64/pdf_oxide.node',
|
|
26
|
+
},
|
|
27
|
+
linux: {
|
|
28
|
+
x64: '../prebuilds/linux-x64/pdf_oxide.node',
|
|
29
|
+
arm64: '../prebuilds/linux-arm64/pdf_oxide.node',
|
|
30
|
+
},
|
|
31
|
+
win32: {
|
|
32
|
+
x64: '../prebuilds/win32-x64/pdf_oxide.node',
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
function getPrebuildPath() {
|
|
36
|
+
const os = platform();
|
|
37
|
+
const cpu = arch();
|
|
38
|
+
const osPaths = PLATFORMS[os];
|
|
39
|
+
if (!osPaths) {
|
|
40
|
+
throw new Error(`Unsupported platform: ${os}. Supported: ${Object.keys(PLATFORMS).join(', ')}`);
|
|
41
|
+
}
|
|
42
|
+
const prebuildPath = osPaths[cpu];
|
|
43
|
+
if (!prebuildPath) {
|
|
44
|
+
throw new Error(`Unsupported architecture: ${cpu} for ${os}. Supported: ${Object.keys(osPaths).join(', ')}`);
|
|
45
|
+
}
|
|
46
|
+
return prebuildPath;
|
|
47
|
+
}
|
|
48
|
+
let cached;
|
|
49
|
+
export function loadNative() {
|
|
50
|
+
if (cached)
|
|
51
|
+
return cached;
|
|
52
|
+
try {
|
|
53
|
+
cached = require(getPrebuildPath());
|
|
54
|
+
return cached;
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
// Dev fallback — in-tree `node-gyp rebuild` output.
|
|
58
|
+
if (process.env.NODE_ENV === 'development' || process.env.NAPI_DEV) {
|
|
59
|
+
try {
|
|
60
|
+
cached = require('../build/Release/pdf_oxide.node');
|
|
61
|
+
return cached;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
/* fall through to rethrow the original error */
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
throw new Error(`Failed to load pdf-oxide native addon: ${e.message}`);
|
|
68
|
+
}
|
|
69
|
+
}
|