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 +7 -0
- package/README.md +101 -88
- package/dist/api/engineClient.d.ts +19 -0
- package/dist/components/AnnotationLayer.d.ts +9 -1
- package/dist/components/PdfEditor.d.ts +1 -1
- package/dist/components/PropertiesPanel.d.ts +12 -2
- package/dist/components/ToolSidebar.d.ts +31 -0
- package/dist/components/Toolbar.d.ts +21 -10
- package/dist/index.d.ts +7 -1
- package/dist/logo.png +0 -0
- package/dist/types/annotations.d.ts +122 -2
- package/dist/utils/apiConstants.d.ts +2 -0
- package/dist/utils/license.d.ts +9 -0
- package/dist/utils/pdfConversion.d.ts +11 -0
- package/dist/utils/pdfMetadata.d.ts +1 -0
- package/dist/utils/pdfPageTools.d.ts +12 -0
- package/dist/zynx-pdf.css +1 -1
- package/dist/zynx-pdf.js +3197 -673
- package/dist/zynx-pdf.umd.cjs +1 -1
- package/package.json +14 -5
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
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
48
|
+
## Backend engine dev
|
|
59
49
|
|
|
60
|
-
|
|
50
|
+
The included backend engine provides local license validation, MongoDB storage, and a server-side PDF text edit endpoint.
|
|
61
51
|
|
|
62
|
-
|
|
52
|
+
Local MongoDB URI:
|
|
63
53
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
54
|
+
```env
|
|
55
|
+
MONGODB_URI=mongodb://127.0.0.1:27017/zynx_pdf
|
|
56
|
+
```
|
|
67
57
|
|
|
68
|
-
|
|
58
|
+
Install backend dependencies:
|
|
69
59
|
|
|
70
|
-
|
|
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
|
-
|
|
70
|
+
Run frontend and backend together:
|
|
75
71
|
|
|
76
|
-
```
|
|
77
|
-
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
##
|
|
123
|
+
## Phase 3 upgrade
|
|
101
124
|
|
|
102
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
|
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
|
|
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,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>;
|