@trupdf/forms
AcroForm + XFA read, FDF / XFDF data round-trip, sandboxed JS engine.
FormManager
const m = new FormManager({ strict: true });
m.add({ kind: 'text', id: 'firstName', name: 'firstName', page: 1, widgets: [], value: 'Bharat' });
m.setValue('firstName', 'Updated');
m.toValueMap(); // { firstName: 'Updated' }
m.fromValueMap({ firstName: 'Loaded' });
m.validate(); // ValidationIssue[]AcroForm IO
readAcroForm(pdf)— walks every Widget annotation in the loaded document and returns typedFormFieldRecord[].readFormScripts(pdf)— collects per-field calculate / format / validate actions as typedFormScripts.writeAcroForm(input, fields, { flatten })— back-writes values directly into the PDF, optionally flattening to a static PDF.readSignatureProperties(pdf)— signature-field metadata.
Form-data wire formats
serializeXFDFFormData(records)/deserializeXFDFFormData(xml)serializeFDF(records)/deserializeFDF(text)
Form JS engine (sandboxed)
FormJSEngine recognises a set of named built-ins (no eval, no
new Function):
AFSimple_Calculate("SUM"|"PRD"|"AVG"|"MIN"|"MAX", fieldList)AFRange_Validate(useLower, lower, useUpper, upper)- Format scripts via
parseFormatScript/applyFormat(number, percent, date, special formats). - Custom calculation expressions run through the safe-expression
evaluator (
parseCalculationScript/evaluateCalculation) — a whitelisted arithmetic subset, never arbitrary JS.
Anything not recognised emits a ValidationIssue but never executes.
XFA
readXFA(rootSubform)— flatten nested subforms intoFormFieldRecord[](read-only by default).unlockStaticXFA(manager)— lift the read-only flag for static XFA forms (host has confirmed no dynamic-flow markers).serializeXFADatasets(manager)— emit an XFA<datasets>fragment for write-back.