teamsync-pdf-viewer 2.2.0 → 2.2.2

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/CHANGELOG.md CHANGED
@@ -2,6 +2,65 @@
2
2
 
3
3
  All notable changes to `teamsync-pdf-viewer` are documented here.
4
4
 
5
+ ## [2.2.2] — 2026-11-05
6
+
7
+ ### Added & Enhanced
8
+ - **AcroForm In-Place Updates & Round-Trip Export (F1)**:
9
+ - Form fields already present in a PDF are updated in-place during export via `form.getFields()` rather than failing with `FieldAlreadyExistsError` or skipping value updates.
10
+ - **Interactive Radio Group Export (F2)**:
11
+ - Radio options are exported into native interactive PDF radio groups using `form.createRadioGroup()` with calculated bounding boxes, Helvetica text labels, and selection state.
12
+ - **Hierarchical Checklist Export (F3)**:
13
+ - Multi-select checklist fields export with standardized hierarchical naming (`fieldName.OptionName`) and drawn text labels.
14
+ - **Clean Signature Page Stream & Flatten Option (F4, F5)**:
15
+ - Unsigned signature placeholders no longer burn permanent ink artifacts onto the PDF content stream unless `flatten: true` is explicitly configured in `getFileData()`.
16
+ - Added `field.readOnly` checkbox in `FormFieldEditorModal` locking fields against modification, and enforced `enableReadOnly()` on AcroForms.
17
+ - Added `{ flatten?: boolean }` export option to flatten interactive fields into static page content when desired.
18
+ - **Duplicate Field Key Collision Prevention (F6)**:
19
+ - Added duplicate name detection banner in the field configuration modal and deterministic suffix naming (`name_1`, `name_2`) during export to prevent collisions.
20
+ - **Electronic vs Digital Signature Clarification (F7, F10)**:
21
+ - Electronic signatures are explicitly labeled `"Signed electronically by ..."` without misrepresenting visual signatures as digital certificates.
22
+ - Removed misleading pseudo-random hex strings; digital certificate signatures now show genuine status indicators.
23
+ - Strict signature value validation rejecting raw strings (e.g. `[object Object]` or `hello`) while accepting structured signature objects and Base64 images.
24
+ - **Manager-Level Role Locking & Security (F8)**:
25
+ - `FormManager` enforces role assignment and read-only checks on `setValue()` and `setValues()`, blocking unauthorized edits unless `{ force: true }` is passed.
26
+ - **Proportional Option Font Scaling (F9)**:
27
+ - Replaced rigid 10px minimum clamp on radio and checklist options with proportional scaling down to 7px, eliminating overflow clipping and scrollbars on zoom-out.
28
+ - **Aligned Validation & Unassigned Role Policies (F11)**:
29
+ - Configurable `unassignedFieldsRole` (`'all' | 'none' | roleId`) ensuring completion counters and `validate()` agree. Validation errors now include role names (e.g., `(Buyer)`).
30
+ - **Native AcroForm & XFDF Form Ingestion (F12, F13)**:
31
+ - Introduced `extractAcroFormFields` to detect and parse existing PDF `Widget` annotations into interactive form field models.
32
+ - Introduced `parseXfdfFormFields` to parse XFDF `<widget>` and `<field>` tags directly into `FormManager` without creating dead grey outline annotations.
33
+ - **Form Role Metadata (F14)**:
34
+ - Added `partyType` (`'signer' | 'viewer' | 'notary'`), `signingOrder`, and custom `metadata` to `FormRole`.
35
+ - **Programmatic Tab Navigation & Granular Events (F15, F18)**:
36
+ - Added `instance.UI.setActiveTab(tab)` and `instance.UI.getActiveTab()` with `tabChanged` event emission.
37
+ - Added granular event hooks: `fieldValueChanged`, `signatureApplied`, `signatureCleared`, `fieldAdded`, `fieldRemoved`, `fieldUpdated`.
38
+ - **Role Field Highlighting (F16)**:
39
+ - Added `instance.highlightRoleFields(roleId)` with accent glow across matching fields.
40
+ - **Adopted Signature Caching & 1-Click Sign All (F17)**:
41
+ - Added session-level adopted signature persistence with 1-click application across all pending signature fields for the active role.
42
+ - **Prop Synchronization & Undo Isolation (F19)**:
43
+ - Props passed to `<TeamSyncViewer>` (`formFields`, `formData`) synchronize cleanly without resetting state or polluting undo history stacks.
44
+ - **Dynamic Schema Versioning (F20)**:
45
+ - Exported field templates now dynamically reflect library version `2.2.2`.
46
+
47
+ ### Security
48
+ - **Cryptographically Secure Identifier Generation**: Replaced pseudo-random number generator routines with cryptographically secure random values (`crypto.randomUUID()` and `crypto.getRandomValues()`) across fallback blob URLs, manual redactions, and form roles, resolving CodeQL alert CWE-338.
49
+ - **Vulnerability Patches & Dependency Updates**:
50
+ - Upgraded `vite` to `^8.3.5` resolving launch-editor command execution and filesystem bypass advisories.
51
+ - Upgraded `vitest` to `^5.0.5` (resolving to `5.1.0`) fixing `@vitest/mocker` code injection and path traversal advisories.
52
+ - Upgraded `vite-plugin-dts` to `^5.1.2` resolving `minimatch` glob amplification denial-of-service advisory.
53
+ - Upgraded `undici` to `^8.12.3` resolving cache poisoning, TLS options dropping, and DoS advisories.
54
+ - Upgraded `fast-uri` to `^3.1.9` and `source-map-js` to `^1.2.2`.
55
+ - Achieved clean `npm audit` with 0 reported vulnerabilities.
56
+
57
+ ## [2.2.0] — 2026-10-20
58
+
59
+ ### Added
60
+ - **Network Authentication Headers**: Added `httpHeaders` and `customHeaders` options to `WebViewerOptions` and `loadDocument(url, options)` allowing authenticated document requests with session tokens and custom HTTP headers.
61
+ - **Progressive Streaming Controls**: Added `rangeChunkSize`, `disableStream`, `disableAutoFetch`, and `disableRange` options to control document downloading behavior and prevent background bandwidth consumption.
62
+ - **Cross-Environment Compatibility**: Enhanced `createBlobUrl` fallback for environments lacking native `URL.createObjectURL(blob)` support (e.g. Node 22 / jsdom).
63
+
5
64
  ## [2.0.0] — 2026-09-26
6
65
 
7
66
  ### Added
package/README.md CHANGED
@@ -4,30 +4,32 @@
4
4
 
5
5
  ![TeamSync PDF Viewer UI](https://raw.githubusercontent.com/angelbot-ai/TeamSync-PDF-Viewer/main/docs/images/viewer_ui.png)
6
6
 
7
- ### **100% Open Source. 100% Client-Side. Enterprise SDK.**
7
+ ### Advanced Web PDF Viewer, Annotation and PDF Forms with PDF Enterprise SDK.
8
8
 
9
- [![License: CPAL-1.0](https://img.shields.io/badge/License-CPAL--1.0-blue.svg)](LICENSE)
10
9
  [![Live Demo](https://img.shields.io/badge/Live%20Demo-pdfviewer.teamsync.com-000000.svg)](https://pdfviewer.teamsync.com/)
11
10
  [![NPM Version](https://img.shields.io/badge/npm-teamsync--pdf--viewer-blue.svg)](https://www.npmjs.com/package/teamsync-pdf-viewer)
12
11
  [![React 19](https://img.shields.io/badge/React-19-61dafb.svg)](https://reactjs.org/)
13
12
  [![Vite 8](https://img.shields.io/badge/Vite-8.2-646cff.svg)](https://vitejs.dev/)
14
13
  [![TypeScript](https://img.shields.io/badge/TypeScript-6.0-blue.svg)](https://www.typescriptlang.org/)
15
14
 
16
- *No paywalls. No vendor lock-in. No server dependencies.*
17
15
  Try the **[Interactive Live Demo](https://pdfviewer.teamsync.com/)** or integrate the high-performance PDF Viewer SDK directly into your React applications.
18
16
 
19
17
  </div>
20
18
 
21
19
  ---
22
20
 
23
- ## 🚀 Why TeamSync PDF Viewer?
21
+ **TeamSync PDF Viewer** allows developers to embed advanced viewing, annotation, and forms capabilities directly into any web application.
22
+
23
+ ⚡ **Universal Document Viewing**: It accurately renders PDFs, Microsoft Office files (Word, Excel, PowerPoint), CAD drawings, and images directly in the browser. It handles massive, complex files smoothly with vector-based zooming and lightning-fast rendering.
24
+
25
+ • **True Client-Side Processing**: Because it processes everything locally using the browser's resources, sensitive files never leave the user's device. This makes it ideal for highly secure environments (like finance, healthcare, or legal apps) and significantly reduces server infrastructure costs.
26
+
27
+ • **Rich Annotation & Collaboration**: It provides built-in UI tools for highlighting text, adding sticky notes, drawing shapes, stamping, and text callouts. It supports real-time collaboration so multiple users can comment and mark up the same document simultaneously.
24
28
 
25
- Traditional commercial PDF viewers force developers into expensive per-domain licenses, opaque sales calls, and heavy server-side processing dependencies. **TeamSync PDF Viewer** is built from the ground up to solve these pain points.
29
+ • **Interactive Forms & Digital Signatures**: Users can fill out existing PDF forms, build new forms from scratch, and apply secure e-signatures or digital signatures.
30
+
31
+ • **Advanced Text Editing & Redaction**: It allows users to edit underlying text directly within a PDF as if they were in a word processor. It also features programmatic and manual redaction, permanently wiping sensitive data from the document's code.
26
32
 
27
- - 💰 **Zero-Cost, Transparent Licensing**: Uncapped usage, no per-server fees, and no commercial paywalls. 100% free and open-source under CPAL 1.0.
28
- - ⚡ **100% Client-Side PDF Processing**: Documents never leave the browser sandbox. Process, redact, and render PDFs entirely on the client.
29
- - 🔌 **Universal WebViewer API**: Clean, intuitive `WebViewer({...})` API interface that makes integrating into your web applications effortless.
30
- - 🎨 **Headless & Customizable**: Built for modern React 19 SPA lifecycles. No bloated iFrames to fight—customize toolbars, sidebars, context menus, and controls natively.
31
33
 
32
34
  ---
33
35
 
@@ -76,7 +78,7 @@ Explore detailed SDK guides, parameter options, code snippets, and architecture
76
78
 
77
79
  ---
78
80
 
79
- ## ✨ Uncompromised Feature Set
81
+ ## ✨ Feature Set
80
82
 
81
83
  Everything you need to build collaborative, secure document workflows.
82
84
 
@@ -308,6 +310,8 @@ TeamSync-PDF-Viewer/
308
310
  Distributed under the **CPAL 1.0 (Common Public Attribution License)**.
309
311
  100% Free and Open Source for personal and commercial usage.
310
312
 
313
+ [![License: CPAL-1.0](https://img.shields.io/badge/License-CPAL--1.0-blue.svg)](LICENSE)
314
+
311
315
  ---
312
316
 
313
317
  <div align="center">
@@ -31,6 +31,8 @@ export declare class AnnotationManager {
31
31
  private readOnly;
32
32
  private canEditOthers;
33
33
  private resolver;
34
+ private formManager;
35
+ setFormManager(fm: any): void;
34
36
  setDocument(doc: PDFDocumentProxy | null): void;
35
37
  hasDocument(): boolean;
36
38
  setCurrentUser(name: string, id?: string): void;
@@ -3,4 +3,5 @@
3
3
  * Stable, collision-free annotation ids. They double as the XFDF `name` attribute, which hosts use
4
4
  * to match persisted rows to live annotations, so they must never be timestamps.
5
5
  */
6
+ export declare function generateSecureId(prefix?: string): string;
6
7
  export declare function newAnnotationId(): string;
@@ -1,4 +1,5 @@
1
1
  import { Annotation } from './types';
2
+ import { FormField, FormDataRecord } from '../forms/types';
2
3
  import { GeometryResolver } from './geometry';
3
4
  export declare const XFDF_NS = "http://ns.adobe.com/xfdf/";
4
5
  export interface XfdfExportOptions {
@@ -16,3 +17,10 @@ export declare function annotationToXfdfFragment(a: Annotation, resolve: Geometr
16
17
  /** Serialize annotations to a complete XFDF document. */
17
18
  export declare function annotationsToXfdf(annotations: Annotation[], resolve: GeometryResolver, opts?: XfdfExportOptions): Promise<string>;
18
19
  export declare function parseXfdf(xml: string, resolve: GeometryResolver): Promise<Annotation[]>;
20
+ /**
21
+ * Extracts form field definitions (<widget>) and field values (<fields>) from an XFDF document (F13).
22
+ */
23
+ export declare function parseXfdfFormFields(xml: string, resolve?: GeometryResolver, roleMapper?: (customData: Record<string, string>) => string | undefined): Promise<{
24
+ fields: FormField[];
25
+ values: FormDataRecord;
26
+ }>;
@@ -90,6 +90,7 @@ interface DocumentViewerProps {
90
90
  formManager?: FormManager;
91
91
  setActiveTab?: (tab: string) => void;
92
92
  onDownloadFilledPdf?: () => void;
93
+ highlightedRoleId?: string | null;
93
94
  }
94
- export default function DocumentViewer({ leftSidebarOpen, rightSidebarOpen, activeTab, annotationManager, initialDoc, loadNonce, withCredentials, httpHeaders, customHeaders, rangeChunkSize, disableStream, disableAutoFetch, disableRange, password, assets, sidebars, redactions, regexRedactions, scale, setScale, sidebarTab, setSidebarTab, onAnnotationsChange, onRedactionsChange, onRedactionsApplied, onDocumentLoaded, onLoadError, onFirstPageRendered, onPageRendered, onPageChange, pageTransition, pageLayout, rotation, setRotation, watermark, watermarkText, enableAnnotations: _enableAnnotations, initialPage, page, transientHighlights, permissions, hideAnnotationsUntilPageRendered, enableTextSelection, defaultTool, showSelectionTooltip, initialScale, initialWidthRatio, responsive, instance, targetViewer, resolveLinkUrl, onLinkClick, formManager, setActiveTab, onDownloadFilledPdf, }: DocumentViewerProps): React.JSX.Element;
95
+ export default function DocumentViewer({ leftSidebarOpen, rightSidebarOpen, activeTab, annotationManager, initialDoc, loadNonce, withCredentials, httpHeaders, customHeaders, rangeChunkSize, disableStream, disableAutoFetch, disableRange, password, assets, sidebars, redactions, regexRedactions, scale, setScale, sidebarTab, setSidebarTab, onAnnotationsChange, onRedactionsChange, onRedactionsApplied, onDocumentLoaded, onLoadError, onFirstPageRendered, onPageRendered, onPageChange, pageTransition, pageLayout, rotation, setRotation, watermark, watermarkText, enableAnnotations: _enableAnnotations, initialPage, page, transientHighlights, permissions, hideAnnotationsUntilPageRendered, enableTextSelection, defaultTool, showSelectionTooltip, initialScale, initialWidthRatio, responsive, instance, targetViewer, resolveLinkUrl, onLinkClick, formManager, setActiveTab, onDownloadFilledPdf, highlightedRoleId, }: DocumentViewerProps): React.JSX.Element;
95
96
  export {};
@@ -3,6 +3,7 @@ import { FormField, FormRole } from '../forms/types';
3
3
  interface FormFieldEditorModalProps {
4
4
  field: FormField;
5
5
  roles?: FormRole[];
6
+ existingFields?: FormField[];
6
7
  onAddRole?: (role: FormRole) => void;
7
8
  onSave: (updated: Partial<FormField>) => void;
8
9
  onClose: () => void;
@@ -14,6 +14,7 @@ interface FormFieldLayerProps {
14
14
  canFillForms?: boolean;
15
15
  showFlowOrder?: boolean;
16
16
  selectedRoleFilter?: string | null;
17
+ highlightedRoleId?: string | null;
17
18
  }
18
19
  export declare const FormFieldLayer: React.FC<FormFieldLayerProps>;
19
20
  export {};
@@ -6,6 +6,7 @@ interface FormSignatureModalProps {
6
6
  role?: FormRole;
7
7
  currentUser?: ViewerUser | null;
8
8
  currentValue?: FormSignatureValue | any;
9
+ adoptedSignature?: FormSignatureValue | null;
9
10
  defaultSignerName?: string;
10
11
  onSave: (value: FormSignatureValue) => void;
11
12
  onClear?: () => void;
@@ -49,7 +49,8 @@ interface PageRendererProps {
49
49
  canFillForms?: boolean;
50
50
  showFlowOrder?: boolean;
51
51
  selectedRoleFilter?: string | null;
52
+ highlightedRoleId?: string | null;
52
53
  }
53
- declare function PageRendererComponent({ pageNum, pdfDoc, scale, rotation, containerWidth: _containerWidth, containerHeight: _containerHeight, scrollTop: _scrollTop, scrollLeft: _scrollLeft, pageTop, pageLeft, basePageWidth, basePageHeight, activeTab, activeTool, annotations, selectedAnnotationId, activeSearchResult, transientHighlights, onMouseDown, onMouseMove, onMouseUp, onAnnotationClick, onAnnotationDoubleClick, onStartResize, onStartMove, onAnnotationMouseEnter, onClearSelection, watermark, watermarkText, redactions, onDiscardRedaction, onRendered, hideAnnotationsUntilPageRendered, onLinkClick, formManager, activeFormTool, setActiveFormTool, canFillForms, showFlowOrder, selectedRoleFilter }: PageRendererProps): React.JSX.Element;
54
+ declare function PageRendererComponent({ pageNum, pdfDoc, scale, rotation, containerWidth: _containerWidth, containerHeight: _containerHeight, scrollTop: _scrollTop, scrollLeft: _scrollLeft, pageTop, pageLeft, basePageWidth, basePageHeight, activeTab, activeTool, annotations, selectedAnnotationId, activeSearchResult, transientHighlights, onMouseDown, onMouseMove, onMouseUp, onAnnotationClick, onAnnotationDoubleClick, onStartResize, onStartMove, onAnnotationMouseEnter, onClearSelection, watermark, watermarkText, redactions, onDiscardRedaction, onRendered, hideAnnotationsUntilPageRendered, onLinkClick, formManager, activeFormTool, setActiveFormTool, canFillForms, showFlowOrder, selectedRoleFilter, highlightedRoleId }: PageRendererProps): React.JSX.Element;
54
55
  declare const PageRenderer: React.MemoExoticComponent<typeof PageRendererComponent>;
55
56
  export default PageRenderer;
@@ -1,6 +1,7 @@
1
1
  import { default as React } from 'react';
2
2
  import { DocumentLoadErrorInfo } from './DocumentViewer';
3
3
  import { WebViewerInstance } from '../core/ViewerInstance';
4
+ import { FormField, FormDataRecord } from '../forms/types';
4
5
  import { WebViewerOptions, Redaction, TransientHighlight, LinkClickEvent } from '../core/types';
5
6
  import { Annotation } from '../annotations/types';
6
7
  import { OfficeConverterConfig, OfficeFileType } from '../office';
@@ -97,6 +98,16 @@ export interface TeamSyncViewerProps extends Omit<WebViewerOptions, 'path'> {
97
98
  error: Error;
98
99
  url?: string;
99
100
  }) => void;
101
+ /** Initial active UI mode tab: 'View' | 'Annotate' | 'Forms' (default 'View') (F15). */
102
+ initialTab?: string;
103
+ /** Initial form fields definition (F19). */
104
+ initialFormFields?: FormField[];
105
+ /** Initial form data values (F19). */
106
+ initialFormData?: FormDataRecord;
107
+ /** Fires when active UI tab changes (F15). */
108
+ onTabChanged?: (info: {
109
+ tab: string;
110
+ }) => void;
100
111
  className?: string;
101
112
  style?: React.CSSProperties;
102
113
  }
@@ -65,6 +65,7 @@ export interface ViewerBinding {
65
65
  }): void;
66
66
  getTransientHighlights(): TransientHighlight[];
67
67
  setTransientHighlights(highlights: TransientHighlight[]): void;
68
+ getActiveTab?(): string;
68
69
  }
69
70
  export declare class WebViewerInstance {
70
71
  private static instances;
@@ -89,7 +90,15 @@ export declare class WebViewerInstance {
89
90
  private unmountRoot;
90
91
  private destroyed;
91
92
  private targetViewerTarget;
93
+ private currentActiveTab;
92
94
  constructor(bus: ViewerBus, annotationManager?: AnnotationManager, id?: string, formManager?: FormManager);
95
+ /**
96
+ * Visually highlights form fields belonging to a specific role with an accent glow (F16).
97
+ * Pass null to clear active highlights.
98
+ */
99
+ highlightRoleFields(roleId: string | null): void;
100
+ /** Returns current active tab in the viewer (F15). */
101
+ getActiveTab(): string;
93
102
  /** Sets the target viewer instance, ref, getter, or ID to receive cross-document links. */
94
103
  setTargetViewer(target: WebViewerInstance | React.RefObject<WebViewerInstance | null> | (() => WebViewerInstance | null) | string | null): void;
95
104
  /** Resolves the target viewer instance if configured. */
@@ -266,6 +275,10 @@ export declare class WebViewerInstance {
266
275
  */
267
276
  copySelectedText(): Promise<boolean>;
268
277
  readonly UI: {
278
+ /** Sets active UI mode tab: 'View' | 'Annotate' | 'Forms' (F15). */
279
+ setActiveTab: (tab: "View" | "Annotate" | "Forms" | string) => void;
280
+ /** Returns currently active tab (F15). */
281
+ getActiveTab: () => string;
269
282
  /** Theming is not implemented; kept for API compatibility. */
270
283
  setTheme: (_theme: string) => void;
271
284
  goToPage: (pageNumber: number) => void;
@@ -16,11 +16,15 @@ export interface ExportInput {
16
16
  signerName?: string;
17
17
  formFields?: FormField[];
18
18
  formData?: FormDataRecord;
19
+ /** Whether to lock and flatten form fields into static page content on export (F5). */
20
+ flatten?: boolean;
19
21
  }
20
22
  export interface ExportOptions {
21
23
  /** Bake exactly these annotations instead of the live list. */
22
24
  explicitAnnotations?: Annotation[];
23
25
  /** Accepted for API compatibility; annotations are always taken from the live list / explicitAnnotations. */
24
26
  xfdfString?: string;
27
+ /** Whether to lock and flatten form fields into static page content on export (F5). */
28
+ flatten?: boolean;
25
29
  }
26
30
  export declare function buildPdfBytes(input: ExportInput, options?: ExportOptions): Promise<Uint8Array>;
@@ -6,7 +6,7 @@ import { PdfAssetPaths } from './pdfAssets';
6
6
  import { WebViewerInstance } from './ViewerInstance';
7
7
  import { OfficeConverterConfig, OfficeFileType } from '../office/types';
8
8
  import { FormManager } from '../forms/FormManager';
9
- import { FormField, FormDataRecord, FormRole, FormFeatureOptions } from '../forms/types';
9
+ import { FormField, FormDataRecord, FormRole, FormFeatureOptions, FormFieldValueChangedEvent, FormSignatureAppliedEvent, FormSignatureClearedEvent, FormFieldAddedEvent, FormFieldRemovedEvent, FormFieldUpdatedEvent } from '../forms/types';
10
10
  export type { PdfAssetPaths, WebViewerInstance, OfficeConverterConfig, OfficeFileType, FormManager, FormField, FormDataRecord, FormRole, FormFeatureOptions, };
11
11
  export interface SearchBounds {
12
12
  x: number;
@@ -302,6 +302,30 @@ export interface ViewerEventMap {
302
302
  text: string;
303
303
  };
304
304
  linkClicked: LinkClickEvent;
305
+ /** Fires when active UI tab changes (View / Annotate / Forms). */
306
+ tabChanged: {
307
+ tab: string;
308
+ };
309
+ /** Granular form field value change event (F18). */
310
+ fieldValueChanged: FormFieldValueChangedEvent;
311
+ /** Granular signature applied event (F18). */
312
+ signatureApplied: FormSignatureAppliedEvent;
313
+ /** Granular signature cleared event (F18). */
314
+ signatureCleared: FormSignatureClearedEvent;
315
+ /** Form field schema added (F18). */
316
+ fieldAdded: FormFieldAddedEvent;
317
+ /** Form field schema removed (F18). */
318
+ fieldRemoved: FormFieldRemovedEvent;
319
+ /** Form field schema updated (F18). */
320
+ fieldUpdated: FormFieldUpdatedEvent;
321
+ /** Full form data changed event. */
322
+ formDataChanged: {
323
+ data: Record<string, any>;
324
+ };
325
+ /** Full form fields schema changed event. */
326
+ formFieldsChanged: {
327
+ fields: FormField[];
328
+ };
305
329
  /** Fires when an Office document begins conversion. */
306
330
  officeConverting: {
307
331
  fileType: OfficeFileType;
@@ -1,4 +1,4 @@
1
- import { FormField, FormDataRecord, FormValidationResult, FormRole, FormFeatureOptions } from './types';
1
+ import { FormField, FormDataRecord, FormValidationResult, FormRole, FormFeatureOptions, FormSignatureValue, FormFieldValueChangedEvent, FormSignatureAppliedEvent, FormSignatureClearedEvent, FormFieldAddedEvent, FormFieldRemovedEvent, FormFieldUpdatedEvent } from './types';
2
2
  import { ViewerUser } from '../core/types';
3
3
  export declare const DEFAULT_FORM_OPTIONS: FormFeatureOptions;
4
4
  export declare const DEFAULT_ROLES: FormRole[];
@@ -25,10 +25,31 @@ export declare class FormManager {
25
25
  private activeFieldListeners;
26
26
  private optionsListeners;
27
27
  private userListeners;
28
+ private fieldValueListeners;
29
+ private signatureAppliedListeners;
30
+ private signatureClearedListeners;
31
+ private fieldAddedListeners;
32
+ private fieldRemovedListeners;
33
+ private fieldUpdatedListeners;
34
+ private adoptedSignature;
28
35
  private readOnly;
29
36
  constructor(initialFields?: FormField[], initialValues?: FormDataRecord, initialRoles?: FormRole[], initialOptions?: Partial<FormFeatureOptions>, initialUser?: ViewerUser | null);
30
37
  onFieldsChange(listener: FormFieldsChangeListener): () => void;
31
38
  onDataChange(listener: FormDataChangeListener): () => void;
39
+ onFieldValueChanged(listener: (event: FormFieldValueChangedEvent) => void): () => void;
40
+ onSignatureApplied(listener: (event: FormSignatureAppliedEvent) => void): () => void;
41
+ onSignatureCleared(listener: (event: FormSignatureClearedEvent) => void): () => void;
42
+ onFieldAdded(listener: (event: FormFieldAddedEvent) => void): () => void;
43
+ onFieldRemoved(listener: (event: FormFieldRemovedEvent) => void): () => void;
44
+ onFieldUpdated(listener: (event: FormFieldUpdatedEvent) => void): () => void;
45
+ private notifyFieldValueChanged;
46
+ private notifySignatureApplied;
47
+ private notifySignatureCleared;
48
+ private notifyFieldAdded;
49
+ private notifyFieldRemoved;
50
+ private notifyFieldUpdated;
51
+ getAdoptedSignature(): FormSignatureValue | null;
52
+ setAdoptedSignature(sig: FormSignatureValue | null): void;
32
53
  private notifyFieldsChange;
33
54
  private notifyDataChange;
34
55
  private pushHistory;
@@ -40,15 +61,28 @@ export declare class FormManager {
40
61
  getFieldsForPage(pageIndex: number): FormField[];
41
62
  getField(id: string): FormField | undefined;
42
63
  getFieldByName(name: string): FormField | undefined;
43
- setFields(fields: FormField[]): void;
64
+ setFields(fields: FormField[], recordHistory?: boolean): void;
44
65
  addField(field: FormField): void;
45
66
  updateField(id: string, updates: Partial<Omit<FormField, 'id'>>, recordHistory?: boolean): boolean;
46
67
  deleteField(id: string): boolean;
68
+ /** Alias for deleteField (F18). */
69
+ removeField(id: string): boolean;
47
70
  clearFields(): void;
48
71
  getValues(): FormDataRecord;
49
72
  getValue(name: string): any;
50
- setValue(name: string, value: any): void;
51
- setValues(newValues: FormDataRecord): void;
73
+ /**
74
+ * Checks whether a form field can currently be modified based on form read-only state,
75
+ * field-level read-only setting, and the active role assignment (F8).
76
+ */
77
+ canEditField(fieldOrName: FormField | string): boolean;
78
+ setValue(name: string, value: any, options?: {
79
+ force?: boolean;
80
+ source?: 'user' | 'code';
81
+ }): boolean;
82
+ setValues(newValues: FormDataRecord, options?: {
83
+ force?: boolean;
84
+ source?: 'user' | 'code';
85
+ }): void;
52
86
  clearValues(): void;
53
87
  setReadOnly(readOnly: boolean): void;
54
88
  isReadOnly(): boolean;
@@ -0,0 +1,6 @@
1
+ import { FormField, FormDataRecord } from './types';
2
+ import { GeometryResolver } from '../annotations/geometry';
3
+ export declare function extractAcroFormFields(pdfDoc: any, resolver?: GeometryResolver): Promise<{
4
+ fields: FormField[];
5
+ values: FormDataRecord;
6
+ }>;
@@ -98,6 +98,37 @@ export interface FormRole {
98
98
  color: string;
99
99
  /** Optional human-readable description for the role */
100
100
  description?: string;
101
+ /** Optional party type classification (e.g. 'internal', 'external', 'signer', 'viewer') */
102
+ partyType?: 'internal' | 'external' | string;
103
+ /** Optional signing order or sequence index in a multi-party workflow */
104
+ signingOrder?: number;
105
+ /** Optional custom host-specific metadata attributes */
106
+ metadata?: Record<string, any>;
107
+ }
108
+ export interface FormFieldValueChangedEvent {
109
+ fieldName: string;
110
+ oldValue: any;
111
+ newValue: any;
112
+ source: 'user' | 'code';
113
+ }
114
+ export interface FormSignatureAppliedEvent {
115
+ fieldName: string;
116
+ signature: FormSignatureValue;
117
+ signerName?: string;
118
+ }
119
+ export interface FormSignatureClearedEvent {
120
+ fieldName: string;
121
+ }
122
+ export interface FormFieldAddedEvent {
123
+ field: FormField;
124
+ }
125
+ export interface FormFieldRemovedEvent {
126
+ fieldId: string;
127
+ fieldName: string;
128
+ }
129
+ export interface FormFieldUpdatedEvent {
130
+ field: FormField;
131
+ changes: Partial<FormField>;
101
132
  }
102
133
  export type FormDataRecord = Record<string, any>;
103
134
  export interface FormValidationResult {
@@ -176,4 +207,11 @@ export interface FormFeatureOptions {
176
207
  * Controls which fields and signature flags are active for the current user.
177
208
  */
178
209
  currentRole?: string | null;
210
+ /**
211
+ * Defines which role unassigned fields (fields with no roleId) belong to during validation:
212
+ * - 'all': unassigned fields are required for everyone (default)
213
+ * - 'none': unassigned fields are never treated as required for any specific role
214
+ * - string: role ID that unassigned fields belong to
215
+ */
216
+ unassignedFieldsRole?: 'all' | 'none' | string;
179
217
  }
@@ -51,4 +51,6 @@ export type { OfficeConverterConfig, OfficeConversionConfig, OfficeConversionSta
51
51
  export { VERSION } from './version';
52
52
  export { FormManager, DEFAULT_FORM_OPTIONS, DEFAULT_ROLES } from './forms/FormManager';
53
53
  export type { FormFieldsChangeEvent, FormFieldsChangeListener, FormDataChangeListener } from './forms/FormManager';
54
- export type { FormField, FormFieldType, DateTimeFormat, SignatureType, FormSignatureValue, FormRole, FormDataRecord, FormValidationResult, FormToolType, FormFeatureOptions, } from './forms/types';
54
+ export { extractAcroFormFields } from './forms/acroFormIngestion';
55
+ export { parseXfdfFormFields } from './annotations/xfdf';
56
+ export type { FormField, FormFieldType, DateTimeFormat, SignatureType, FormSignatureValue, FormRole, FormDataRecord, FormValidationResult, FormToolType, FormFeatureOptions, FormFieldValueChangedEvent, FormSignatureAppliedEvent, FormSignatureClearedEvent, FormFieldAddedEvent, FormFieldRemovedEvent, FormFieldUpdatedEvent, } from './forms/types';
@@ -1 +1,2 @@
1
1
  export declare const VERSION: string;
2
+ export declare const LIB_VERSION: string;