zynx-pdf 0.1.2 → 0.1.8

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 ADDED
@@ -0,0 +1,7 @@
1
+ Proprietary License
2
+
3
+ Copyright (c) 2026 Hafiz Muhammad Zunnoorain.
4
+
5
+ Zynx PDF is proprietary software. This software may not be copied, modified, distributed, sublicensed, resold, or used for commercial purposes without written permission from the copyright holder.
6
+
7
+ This project uses open-source third-party libraries including Mozilla PDF.js and pdf-lib. Their respective licenses remain applicable to those libraries.
package/README.md CHANGED
@@ -1,20 +1,16 @@
1
1
  # Zynx PDF
2
2
 
3
- **Zynx PDF** is a modern React PDF viewer and editor for web applications. It is built on top of **Mozilla PDF.js** for PDF rendering and **pdf-lib** for PDF export and editing operations.
3
+ **Zynx PDF** is a modern React PDF viewer and editor built with **Mozilla PDF.js** and **pdf-lib**.
4
4
 
5
5
  Developed by **Hafiz Muhammad Zunnoorain**.
6
6
 
7
- ---
8
-
9
7
  ## Install
10
8
 
11
9
  ```bash
12
10
  npm install zynx-pdf
13
11
  ```
14
12
 
15
- ---
16
-
17
- ## Basic Usage
13
+ ## Frontend usage
18
14
 
19
15
  ```tsx
20
16
  import { PdfEditor } from "zynx-pdf";
@@ -24,117 +20,134 @@ export default function App() {
24
20
  return (
25
21
  <PdfEditor
26
22
  height="100vh"
27
- onSave={(pdfBytes, annotations) => {
28
- console.log("Saved PDF:", pdfBytes);
29
- console.log("Annotations:", annotations);
30
- }}
23
+ licenseKey={import.meta.env.VITE_ZYNX_LICENSE_KEY}
24
+ licenseApiUrl={import.meta.env.VITE_ZYNX_LICENSE_API_URL}
25
+ engineApiUrl={import.meta.env.VITE_ZYNX_ENGINE_URL}
26
+ showProTools
27
+ logoSrc="/logo.png"
31
28
  />
32
29
  );
33
30
  }
34
31
  ```
35
32
 
36
- ---
33
+ ## Local test license
37
34
 
38
- ## Features
35
+ ```env
36
+ VITE_ZYNX_LICENSE_KEY=zpx_test_9F2D-7KLA-ZYNX-PRO-2026
37
+ VITE_ZYNX_LICENSE_API_URL=https://cyranix-lab-be-production.up.railway.app/api/zynx/license/validate
38
+ VITE_ZYNX_ENGINE_URL=https://cyranix-lab-be-production.up.railway.app
39
+ ```
39
40
 
40
- - PDF upload and viewing
41
- - Page navigation
42
- - Zoom in and zoom out
43
- - Add new text
44
- - Visually replace existing PDF text
45
- - Add highlights
46
- - Freehand drawing
47
- - Add images
48
- - Add signatures
49
- - Select, move, resize, and delete edits
50
- - Undo and redo support
51
- - Export edited PDF
52
- - TypeScript support
53
- - React component API
54
- - Clean purple SaaS-style editor UI
41
+ ## Frontend dev
55
42
 
56
- ---
43
+ ```bash
44
+ npm install
45
+ npm run dev
46
+ ```
57
47
 
58
- ## Existing Text Editing
48
+ ## Backend engine dev
59
49
 
60
- Zynx PDF supports **visual text replacement**.
50
+ The included backend engine provides local license validation, MongoDB storage, and a server-side PDF text edit endpoint.
61
51
 
62
- This means when you edit existing PDF text:
52
+ Local MongoDB URI:
63
53
 
64
- 1. The original text area is visually covered.
65
- 2. New text is placed on top.
66
- 3. The final exported PDF looks edited.
54
+ ```env
55
+ MONGODB_URI=mongodb://127.0.0.1:27017/zynx_pdf
56
+ ```
67
57
 
68
- This is the practical frontend-only method for browser-based PDF editing.
58
+ Install backend dependencies:
69
59
 
70
- > Note: True internal PDF text stream editing is not currently supported. Scanned image PDFs require OCR.
60
+ ```bash
61
+ npm install --prefix server
62
+ ```
63
+
64
+ Run backend:
71
65
 
72
- ---
66
+ ```bash
67
+ npm run dev:server
68
+ ```
73
69
 
74
- ## Component Props
70
+ Run frontend and backend together:
75
71
 
76
- ```tsx
77
- <PdfEditor
78
- file={null}
79
- height="100vh"
80
- defaultScale={1}
81
- enableUpload={true}
82
- showDevJson={false}
83
- onSave={(pdfBytes, annotations) => {}}
84
- onAnnotationsChange={(annotations) => {}}
85
- />
72
+ ```bash
73
+ npm run dev:all
86
74
  ```
87
75
 
88
- | Prop | Type | Description |
89
- |---|---|---|
90
- | `file` | `File \| string \| ArrayBuffer \| Uint8Array \| null` | Optional PDF file source |
91
- | `height` | `string \| number` | Editor height |
92
- | `defaultScale` | `number` | Initial zoom scale |
93
- | `enableUpload` | `boolean` | Show or hide upload option |
94
- | `showDevJson` | `boolean` | Show developer JSON panel |
95
- | `onSave` | `function` | Called when PDF is exported |
96
- | `onAnnotationsChange` | `function` | Called when annotations change |
76
+ ## Features
77
+
78
+ ### Free tools
79
+
80
+ - PDF upload and viewing
81
+ - Page navigation
82
+ - Thumbnail panel
83
+ - Search text on the current page
84
+ - Zoom in and zoom out
85
+ - Fit to width and fit to page
86
+ - Add text
87
+ - Highlight
88
+ - Underline
89
+ - Strikeout
90
+ - Freehand drawing
91
+ - Shapes: rectangle, circle, line, and arrow
92
+ - Sticky notes/comments
93
+ - Add image
94
+ - Add signature
95
+ - Undo and redo
96
+ - Save as custom filename
97
+ - Print edited PDF
98
+ - Export edited PDF
99
+
100
+ ### Pro gated tools
97
101
 
98
- ---
102
+ - True Text Edit with Advanced Engine v1
103
+ - Visual Replace Text fallback
104
+ - Watermark
105
+ - Stamp
106
+ - Redaction box
107
+ - Page tools
108
+ - Merge PDFs
109
+ - Split PDF
110
+ - Crop page
111
+ - Forms
112
+ - Secure flattened redaction export
113
+ - Compress PDF copy
114
+ - Remove metadata
115
+ - Images to PDF
116
+ - PDF page/all pages to PNG
117
+ - Browser-encrypted password package
118
+ - Page reorder: move current page up/down
119
+ - Replace current page
120
+ - OCR slot
121
+ - White-label slot
99
122
 
100
- ## Example with Theme
123
+ ## Phase 3 upgrade
101
124
 
102
- ```tsx
103
- import { PdfEditor } from "zynx-pdf";
104
- import "zynx-pdf/style.css";
125
+ Phase 3 adds security/conversion tools, full-screen workspace by default, a fixed license modal backdrop, compact toolbar layout, and logo image support through `logoSrc` or `/logo.png`.
105
126
 
106
- export default function App() {
107
- return (
108
- <PdfEditor
109
- height="90vh"
110
- theme={{
111
- primary: "#6d5dfc",
112
- background: "#f6f3ff",
113
- surface: "#ffffff",
114
- border: "#e4def8",
115
- text: "#16142f"
116
- }}
117
- />
118
- );
119
- }
120
- ```
127
+ Note: Acrobat-compatible PDF password encryption still needs a dedicated PDF security engine. The current Password Package tool uses browser AES-GCM encryption and exports `.zynxpdf`.
121
128
 
122
- ---
129
+ ## Advanced Engine v1 note
123
130
 
124
- ## Keyboard Shortcuts
131
+ The **True Text Edit** tool does not create a frontend overlay layer. It sends the selected text to the backend engine. Advanced Engine v1 tries to decode the page content stream, find the matching `Tj` or `TJ` text operator, remove that original operator, and insert the updated text into the PDF.
125
132
 
126
- | Shortcut | Action |
127
- |---|---|
128
- | `Ctrl + Z` | Undo |
129
- | `Ctrl + Y` | Redo |
130
- | `Ctrl + Shift + Z` | Redo |
131
- | `Ctrl + S` | Export PDF |
132
- | `Delete` | Delete selected edit |
133
+ Supported in v1: literal strings, hex strings, basic escaped strings, basic `TJ` arrays, basic `ToUnicode` CMap decoding, and coordinate-assisted matching.
133
134
 
134
- ---
135
+ If the engine cannot locate editable text in the content stream, it returns a clear error and does not fake a visual layer. Use `/api/pdf/debug-text-spans` to inspect how the page text is stored.
136
+
137
+ ## Build library
138
+
139
+ ```bash
140
+ npm run build:lib
141
+ ```
142
+
143
+ ## Publish update
144
+
145
+ ```bash
146
+ npm run release
147
+ ```
135
148
 
136
149
  ## License
137
150
 
138
151
  Zynx PDF is proprietary software.
139
152
 
140
- This package uses open-source third-party libraries including Mozilla PDF.js and pdf-lib. Their respective licenses remain applicable to those libraries.
153
+ This project uses open-source third-party libraries including Mozilla PDF.js and pdf-lib. Their respective licenses remain applicable to those libraries.
@@ -0,0 +1,19 @@
1
+ import type { TextReplaceAnnotation, TrueTextEditDraft } from '../types/annotations';
2
+ export declare const ENGINE_API_URL_LOCAL = "https://cyranix-lab-be-production.up.railway.app";
3
+ export declare const ENGINE_API_URL_LIVE = "https://cyranix-lab-be-production.up.railway.app";
4
+ type EngineTextEditPayload = TextReplaceAnnotation | TrueTextEditDraft;
5
+ type ApplyTrueTextEditArgs = {
6
+ engineApiUrl?: string;
7
+ licenseKey?: string;
8
+ originalBytes: Uint8Array;
9
+ annotation: EngineTextEditPayload;
10
+ };
11
+ type DebugTextSpansArgs = {
12
+ engineApiUrl?: string;
13
+ licenseKey?: string;
14
+ originalBytes: Uint8Array;
15
+ pageIndex: number;
16
+ };
17
+ export declare function applyTrueTextEditWithEngine({ engineApiUrl, licenseKey, originalBytes, annotation }: ApplyTrueTextEditArgs): Promise<Uint8Array>;
18
+ export declare function debugTextSpansWithEngine({ engineApiUrl, licenseKey, originalBytes, pageIndex }: DebugTextSpansArgs): Promise<any>;
19
+ export {};
@@ -1,4 +1,4 @@
1
- import type { AnnotationPatch, PdfAnnotation, PdfTextItem, PdfTool } from '../types/annotations';
1
+ import type { AnnotationPatch, PdfAnnotation, PdfTextItem, PdfTool, TrueTextEditDraft } from '../types/annotations';
2
2
  type PendingImage = {
3
3
  type: 'image' | 'signature';
4
4
  dataUrl: string;
@@ -23,6 +23,14 @@ type AnnotationLayerProps = {
23
23
  onCommitHistoryTransaction: () => void;
24
24
  onCancelHistoryTransaction: () => void;
25
25
  onSelect: (id: string | null) => void;
26
+ onTrueTextItemSelect?: (item: PdfTextItem) => void;
27
+ trueTextDraft?: TrueTextEditDraft | null;
28
+ onUpdateTrueTextDraft?: (patch: Partial<TrueTextEditDraft>) => void;
29
+ onCommitTrueTextDraft?: (draft: TrueTextEditDraft) => void;
30
+ onClearTrueTextDraft?: () => void;
31
+ isApplyingTrueTextEdit?: boolean;
32
+ searchQuery?: string;
33
+ searchActiveTextId?: string | null;
26
34
  };
27
35
  export declare function AnnotationLayer(props: AnnotationLayerProps): import("react").JSX.Element;
28
36
  export {};
@@ -1,3 +1,3 @@
1
1
  import type { PdfEditorProps } from '../types/annotations';
2
2
  import '../styles.css';
3
- export declare function PdfEditor({ file, height, defaultScale, enableUpload, showDevJson, theme, onSave, onAnnotationsChange }: PdfEditorProps): import("react").JSX.Element;
3
+ export declare function PdfEditor({ file, height, defaultScale, enableUpload, showDevJson, theme, licenseKey, licenseApiUrl, engineApiUrl, preferBackendTextEdit, showProTools, autoFocusOnUpload, logoSrc, onSave, onAnnotationsChange, onLicenseChange }: PdfEditorProps): import("react").JSX.Element;
@@ -1,9 +1,19 @@
1
- import type { AnnotationPatch, PdfAnnotation } from '../types/annotations';
1
+ import type { AnnotationPatch, PdfAnnotation, TextReplaceAnnotation, TrueTextEditDraft } from '../types/annotations';
2
2
  type PropertiesPanelProps = {
3
3
  annotation: PdfAnnotation | null;
4
+ trueTextDraft?: TrueTextEditDraft | null;
4
5
  onUpdate: (id: string, patch: AnnotationPatch, recordHistory?: boolean) => void;
5
6
  onDelete: () => void;
7
+ onDuplicate: () => void;
6
8
  onClose?: () => void;
9
+ canApplyBackendTextEdit?: boolean;
10
+ isApplyingBackendTextEdit?: boolean;
11
+ onApplyBackendTextEdit?: (annotation: TextReplaceAnnotation) => void;
12
+ onUpdateTrueTextDraft?: (patch: Partial<TrueTextEditDraft>) => void;
13
+ onApplyTrueTextDraft?: (draft: TrueTextEditDraft) => void;
14
+ onDebugTrueTextDraft?: (draft: TrueTextEditDraft) => void;
15
+ onClearTrueTextDraft?: () => void;
16
+ engineStatus?: string;
7
17
  };
8
- export declare function PropertiesPanel({ annotation, onUpdate, onDelete, onClose }: PropertiesPanelProps): import("react").JSX.Element | null;
18
+ export declare function PropertiesPanel({ annotation, trueTextDraft, onUpdate, onDelete, onDuplicate, onClose, canApplyBackendTextEdit, isApplyingBackendTextEdit, onApplyBackendTextEdit, onUpdateTrueTextDraft, onApplyTrueTextDraft, onDebugTrueTextDraft, onClearTrueTextDraft, engineStatus }: PropertiesPanelProps): import("react").JSX.Element | null;
9
19
  export {};
@@ -0,0 +1,31 @@
1
+ import type { PageAction } from '../utils/pdfPageTools';
2
+ import type { PdfFeature, PdfTool, ZynxLicenseState } from '../types/annotations';
3
+ type ToolSidebarProps = {
4
+ tool: PdfTool;
5
+ defaultText: string;
6
+ showProTools: boolean;
7
+ licenseState: ZynxLicenseState;
8
+ pageIndex: number;
9
+ pageCount: number;
10
+ canUseDocument: boolean;
11
+ processingTool: PdfTool | 'pageAction' | 'engineTextEdit' | 'conversion' | 'security' | null;
12
+ onToolChange: (tool: PdfTool) => void;
13
+ onLockedToolClick: (tool: PdfTool, feature: PdfFeature) => void;
14
+ onDefaultTextChange: (text: string) => void;
15
+ onUploadImage: (file: File, type: 'image' | 'signature') => void;
16
+ onMergePdfs: (files: File[]) => void;
17
+ onSplitCurrentPage: () => void;
18
+ onPageAction: (action: PageAction) => void;
19
+ onCompressPdf: () => void;
20
+ onSecureRedactedExport: () => void;
21
+ onRemoveMetadata: () => void;
22
+ onImagesToPdf: (files: File[]) => void;
23
+ onExportCurrentPageImage: () => void;
24
+ onExportAllPagesImages: () => void;
25
+ onPasswordProtect: () => void;
26
+ onReplaceCurrentPage: (file: File) => void;
27
+ collapsed?: boolean;
28
+ onToggleCollapsed?: () => void;
29
+ };
30
+ export declare function ToolSidebar(props: ToolSidebarProps): import("react").JSX.Element;
31
+ export {};
@@ -1,26 +1,37 @@
1
- import type { PdfTool } from '../types/annotations';
2
1
  type ToolbarProps = {
3
- tool: PdfTool;
4
2
  scale: number;
5
3
  pageIndex: number;
6
4
  pageCount: number;
7
- defaultText: string;
8
5
  canExport: boolean;
9
6
  canUndo: boolean;
10
7
  canRedo: boolean;
11
8
  enableUpload: boolean;
12
- onToolChange: (tool: PdfTool) => void;
9
+ isFocusMode: boolean;
10
+ isProActive: boolean;
11
+ isLicenseLoading: boolean;
12
+ licenseStatusLabel: string;
13
+ searchQuery: string;
14
+ searchMatchCount: number;
15
+ searchActiveIndex: number;
16
+ thumbnailsOpen: boolean;
13
17
  onScaleChange: (scale: number) => void;
18
+ onFitWidth: () => void;
19
+ onFitPage: () => void;
14
20
  onPageChange: (pageIndex: number) => void;
15
- onDefaultTextChange: (text: string) => void;
16
21
  onUploadPdf: (file: File) => void;
17
- onUploadImage: (file: File, type: 'image' | 'signature') => void;
18
- onDeleteSelected: () => void;
19
22
  onUndo: () => void;
20
23
  onRedo: () => void;
21
24
  onExport: () => void;
22
- selectedId?: string | null;
25
+ onSaveAs: () => void;
26
+ onPrint: () => void;
27
+ onSearchChange: (query: string) => void;
28
+ onSearchNext: () => void;
29
+ onSearchPrevious: () => void;
30
+ onToggleThumbnails: () => void;
31
+ onEnterFocusMode: () => void;
32
+ onExitFocusMode: () => void;
33
+ onOpenLicenseModal: () => void;
34
+ logoSrc?: string;
23
35
  };
24
- declare function fileToDataUrl(file: File): Promise<string>;
25
36
  export declare function Toolbar(props: ToolbarProps): import("react").JSX.Element;
26
- export { fileToDataUrl };
37
+ export {};
package/dist/index.d.ts CHANGED
@@ -2,6 +2,12 @@ export { PdfEditor } from './components/PdfEditor';
2
2
  export { Toolbar } from './components/Toolbar';
3
3
  export { AnnotationLayer } from './components/AnnotationLayer';
4
4
  export { PdfCanvas } from './components/PdfCanvas';
5
- export type { PdfAnnotation, PdfEditorProps, PdfEditorTheme, PdfPoint, PdfTool, TextAnnotation, TextReplaceAnnotation, PdfTextItem, HighlightAnnotation, ImageAnnotation, DrawAnnotation } from './types/annotations';
5
+ export type { PdfAnnotation, PdfEditorProps, PdfEditorTheme, PdfFeature, PdfPoint, PdfTool, ZynxLicensePlan, ZynxLicenseState, ZynxLicenseStatus, TextAnnotation, TextReplaceAnnotation, PdfTextItem, HighlightAnnotation, ImageAnnotation, DrawAnnotation, WatermarkAnnotation, StampAnnotation, RedactionAnnotation, CropAnnotation, FormTextAnnotation, FormCheckboxAnnotation } from './types/annotations';
6
+ export { FREE_FEATURES, PRO_FEATURES, ZYNX_TEST_LICENSE_KEY, getToolFeature, hasFeature, validateZynxLicense } from './utils/license';
6
7
  export { exportPdfWithAnnotations } from './utils/pdfExport';
7
8
  export { downloadBytes } from './utils/file';
9
+ export { mergePdfFiles, extractSinglePage, applyPageAction, optimizePdfBytes, replaceCurrentPage } from './utils/pdfPageTools';
10
+ export type { PageAction } from './utils/pdfPageTools';
11
+ export { applyTrueTextEditWithEngine } from './api/engineClient';
12
+ export { rasterizePdfToImagePdf, imagesToPdf, pdfPageToImage, pdfAllPagesToImages, encryptBytesWithPassword } from './utils/pdfConversion';
13
+ export { removePdfMetadata } from './utils/pdfMetadata';
package/dist/logo.png ADDED
Binary file
@@ -1,4 +1,15 @@
1
- export type PdfTool = 'select' | 'replaceText' | 'text' | 'highlight' | 'draw' | 'image' | 'signature';
1
+ export type PdfFeature = 'basic_edit' | 'advanced_text' | 'true_text_edit' | 'page_tools' | 'watermark' | 'stamps' | 'forms' | 'redaction' | 'ocr' | 'compression' | 'conversion' | 'security' | 'metadata' | 'white_label';
2
+ export type PdfTool = 'select' | 'replaceText' | 'trueTextEdit' | 'text' | 'highlight' | 'underline' | 'strikeout' | 'draw' | 'rectangle' | 'ellipse' | 'line' | 'arrow' | 'stickyNote' | 'image' | 'signature' | 'watermark' | 'stamp' | 'redaction' | 'pageTools' | 'forms' | 'formText' | 'formCheckbox' | 'ocr' | 'compress' | 'merge' | 'split' | 'crop' | 'password' | 'removeMetadata' | 'imagesToPdf' | 'pdfToImages' | 'secureRedact' | 'whiteLabel';
3
+ export type ZynxLicensePlan = 'free' | 'pro' | 'enterprise';
4
+ export type ZynxLicenseStatus = 'loading' | 'free' | 'valid' | 'invalid' | 'expired';
5
+ export type ZynxLicenseState = {
6
+ status: ZynxLicenseStatus;
7
+ plan: ZynxLicensePlan;
8
+ licenseKey?: string;
9
+ features: PdfFeature[];
10
+ message?: string;
11
+ expiresAt?: string;
12
+ };
2
13
  export type PdfPoint = {
3
14
  x: number;
4
15
  y: number;
@@ -12,6 +23,21 @@ export type PdfTextItem = {
12
23
  width: number;
13
24
  height: number;
14
25
  fontSize: number;
26
+ fontFamily?: string;
27
+ fontName?: string;
28
+ };
29
+ export type TrueTextEditDraft = {
30
+ sourceTextId: string;
31
+ pageIndex: number;
32
+ originalText: string;
33
+ text: string;
34
+ x: number;
35
+ y: number;
36
+ width: number;
37
+ height: number;
38
+ fontSize: number;
39
+ fontFamily?: string;
40
+ fontName?: string;
15
41
  };
16
42
  export type BaseAnnotation = {
17
43
  id: string;
@@ -26,20 +52,52 @@ export type TextAnnotation = BaseAnnotation & {
26
52
  text: string;
27
53
  fontSize: number;
28
54
  color: string;
55
+ fontFamily?: string;
29
56
  };
30
57
  export type TextReplaceAnnotation = BaseAnnotation & {
31
58
  type: 'text-replace';
59
+ sourceTextId?: string;
32
60
  originalText: string;
33
61
  text: string;
34
62
  fontSize: number;
35
63
  color: string;
36
64
  backgroundColor: string;
65
+ fontFamily?: string;
37
66
  };
38
67
  export type HighlightAnnotation = BaseAnnotation & {
39
68
  type: 'highlight';
40
69
  color: string;
41
70
  opacity: number;
42
71
  };
72
+ export type TextMarkupAnnotation = BaseAnnotation & {
73
+ type: 'underline' | 'strikeout';
74
+ color: string;
75
+ strokeWidth: number;
76
+ opacity: number;
77
+ };
78
+ export type ShapeAnnotation = BaseAnnotation & {
79
+ type: 'rectangle' | 'ellipse';
80
+ borderColor: string;
81
+ backgroundColor: string;
82
+ strokeWidth: number;
83
+ opacity: number;
84
+ };
85
+ export type LineAnnotation = BaseAnnotation & {
86
+ type: 'line' | 'arrow';
87
+ x2: number;
88
+ y2: number;
89
+ color: string;
90
+ strokeWidth: number;
91
+ opacity: number;
92
+ };
93
+ export type StickyNoteAnnotation = BaseAnnotation & {
94
+ type: 'sticky-note';
95
+ text: string;
96
+ fontSize: number;
97
+ color: string;
98
+ backgroundColor: string;
99
+ borderColor: string;
100
+ };
43
101
  export type ImageAnnotation = BaseAnnotation & {
44
102
  type: 'image' | 'signature';
45
103
  dataUrl: string;
@@ -50,21 +108,75 @@ export type DrawAnnotation = BaseAnnotation & {
50
108
  color: string;
51
109
  strokeWidth: number;
52
110
  };
53
- export type PdfAnnotation = TextAnnotation | TextReplaceAnnotation | HighlightAnnotation | ImageAnnotation | DrawAnnotation;
111
+ export type WatermarkAnnotation = BaseAnnotation & {
112
+ type: 'watermark';
113
+ text: string;
114
+ fontSize: number;
115
+ color: string;
116
+ opacity: number;
117
+ rotation: number;
118
+ fontFamily?: string;
119
+ };
120
+ export type StampAnnotation = BaseAnnotation & {
121
+ type: 'stamp';
122
+ text: string;
123
+ fontSize: number;
124
+ color: string;
125
+ backgroundColor: string;
126
+ opacity: number;
127
+ };
128
+ export type RedactionAnnotation = BaseAnnotation & {
129
+ type: 'redaction';
130
+ color: string;
131
+ opacity: number;
132
+ };
133
+ export type CropAnnotation = BaseAnnotation & {
134
+ type: 'crop';
135
+ borderColor: string;
136
+ backgroundColor: string;
137
+ opacity: number;
138
+ };
139
+ export type FormTextAnnotation = BaseAnnotation & {
140
+ type: 'form-text';
141
+ name: string;
142
+ value: string;
143
+ fontSize: number;
144
+ color: string;
145
+ backgroundColor: string;
146
+ borderColor: string;
147
+ };
148
+ export type FormCheckboxAnnotation = BaseAnnotation & {
149
+ type: 'form-checkbox';
150
+ name: string;
151
+ checked: boolean;
152
+ color: string;
153
+ backgroundColor: string;
154
+ borderColor: string;
155
+ };
156
+ export type PdfAnnotation = TextAnnotation | TextReplaceAnnotation | HighlightAnnotation | TextMarkupAnnotation | ShapeAnnotation | LineAnnotation | StickyNoteAnnotation | ImageAnnotation | DrawAnnotation | WatermarkAnnotation | StampAnnotation | RedactionAnnotation | CropAnnotation | FormTextAnnotation | FormCheckboxAnnotation;
54
157
  export type AnnotationPatch = Partial<{
55
158
  x: number;
56
159
  y: number;
160
+ x2: number;
161
+ y2: number;
57
162
  width: number;
58
163
  height: number;
59
164
  text: string;
165
+ sourceTextId: string;
60
166
  originalText: string;
61
167
  fontSize: number;
168
+ fontFamily: string;
62
169
  color: string;
63
170
  backgroundColor: string;
171
+ borderColor: string;
64
172
  opacity: number;
65
173
  dataUrl: string;
66
174
  points: PdfPoint[];
67
175
  strokeWidth: number;
176
+ rotation: number;
177
+ name: string;
178
+ value: string;
179
+ checked: boolean;
68
180
  }>;
69
181
  export type PdfEditorTheme = {
70
182
  primary?: string;
@@ -80,6 +192,14 @@ export type PdfEditorProps = {
80
192
  enableUpload?: boolean;
81
193
  showDevJson?: boolean;
82
194
  theme?: PdfEditorTheme;
195
+ licenseKey?: string;
196
+ licenseApiUrl?: string;
197
+ engineApiUrl?: string;
198
+ preferBackendTextEdit?: boolean;
199
+ showProTools?: boolean;
200
+ autoFocusOnUpload?: boolean;
201
+ logoSrc?: string;
83
202
  onSave?: (pdfBytes: Uint8Array, annotations: PdfAnnotation[]) => void;
84
203
  onAnnotationsChange?: (annotations: PdfAnnotation[]) => void;
204
+ onLicenseChange?: (license: ZynxLicenseState) => void;
85
205
  };
@@ -0,0 +1,2 @@
1
+ export declare const DEFAULT_ENGINE_API_URL = "https://cyranix-lab-be-production.up.railway.app";
2
+ export declare const DEFAULT_LICENSE_API_URL = "https://cyranix-lab-be-production.up.railway.app/api/zynx/license/validate";
@@ -0,0 +1,9 @@
1
+ import type { PdfFeature, PdfTool, ZynxLicenseState } from '../types/annotations';
2
+ export declare const ZYNX_TEST_LICENSE_KEY = "zpx_test_9F2D-7KLA-ZYNX-PRO-2026";
3
+ export declare const FREE_FEATURES: PdfFeature[];
4
+ export declare const PRO_FEATURES: PdfFeature[];
5
+ export declare const FREE_LICENSE_STATE: ZynxLicenseState;
6
+ export declare const TEST_PRO_LICENSE_STATE: ZynxLicenseState;
7
+ export declare function getToolFeature(tool: PdfTool): PdfFeature | null;
8
+ export declare function hasFeature(license: ZynxLicenseState, feature: PdfFeature | null | undefined): boolean;
9
+ export declare function validateZynxLicense(licenseKey?: string, licenseApiUrl?: string): Promise<ZynxLicenseState>;
@@ -0,0 +1,11 @@
1
+ export type RasterizePdfOptions = {
2
+ scale?: number;
3
+ imageType?: 'image/jpeg' | 'image/png';
4
+ quality?: number;
5
+ flattenMessage?: string;
6
+ };
7
+ export declare function rasterizePdfToImagePdf(pdfBytes: Uint8Array, options?: RasterizePdfOptions): Promise<Uint8Array>;
8
+ export declare function imagesToPdf(files: File[]): Promise<Uint8Array>;
9
+ export declare function pdfPageToImage(pdfBytes: Uint8Array, pageIndex: number, scale?: number): Promise<Uint8Array>;
10
+ export declare function pdfAllPagesToImages(pdfBytes: Uint8Array, scale?: number): Promise<Uint8Array[]>;
11
+ export declare function encryptBytesWithPassword(bytes: Uint8Array, password: string): Promise<Uint8Array>;
@@ -0,0 +1 @@
1
+ export declare function removePdfMetadata(pdfBytes: Uint8Array): Promise<Uint8Array>;
@@ -0,0 +1,12 @@
1
+ export type PageAction = 'rotate' | 'delete' | 'duplicate' | 'insertBlank' | 'moveUp' | 'moveDown';
2
+ export declare function mergePdfFiles(currentBytes: Uint8Array, files: File[]): Promise<Uint8Array>;
3
+ export declare function extractSinglePage(currentBytes: Uint8Array, pageIndex: number): Promise<Uint8Array>;
4
+ export declare function replaceCurrentPage(currentBytes: Uint8Array, pageIndex: number, replacementFile: File): Promise<{
5
+ bytes: Uint8Array;
6
+ pageIndex: number;
7
+ }>;
8
+ export declare function applyPageAction(currentBytes: Uint8Array, pageIndex: number, action: PageAction): Promise<{
9
+ bytes: Uint8Array;
10
+ pageIndex: number;
11
+ }>;
12
+ export declare function optimizePdfBytes(currentBytes: Uint8Array): Promise<Uint8Array>;