@rsj-de/pdfmergesortsplit 0.1.0 → 0.2.0

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,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 RSJ Software GmbH, Germering, Germany
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,32 +1,67 @@
1
- # @rsj-de/pdfmergesortsplit — RSJ PDF Merge, Sort & Split SDK
2
-
3
- > The editor runs in test mode without a licence: everything works, a banner
4
- > shows that the embedding is unlicensed. See
5
- > [Licensing](https://pdfmerge.rsj.de/docs/licensing).
6
-
7
- Embed the editor of <https://pdfmerge.rsj.de> in your own product. One iframe, a
8
- small SDK, and documents that never leave the browser.
9
-
10
- Two levels, same editor:
11
-
12
- - **Low-level** `PDFMergeSortSplitClass` (`@rsj-de/pdfmergesortsplit`) — any framework.
13
- - **High-level** `<PDFMergeSortSplit>` + `usePdfMergeSortSplit`
14
- (`@rsj-de/pdfmergesortsplit/react`) — React, built on the class.
1
+ # @rsj-de/pdfmergesortsplit
2
+
3
+ Embed the PDF editor of [pdfmerge.rsj.de](https://pdfmerge.rsj.de) in your own
4
+ product: merging, sorting, rotating, splitting and exporting PDFs inside one
5
+ iframe, with the documents never leaving the browser.
6
+
7
+ **Website:** <https://pdfmerge.rsj.de> · **Documentation:**
8
+ <https://pdfmerge.rsj.de/docs> · **Source and samples:**
9
+ <https://github.com/pdfmergesortsplit/pdfmergesortsplit> · **Licence:** MIT
10
+ ([LICENSE](LICENSE))
11
+
12
+ ## Features
13
+
14
+ - **Merge** any number of PDFs, or ZIP archives containing PDFs.
15
+ - **Sort** pages by drag & drop, including multi-selection (Ctrl/Cmd+click,
16
+ Shift+click a range); rotate, duplicate and delete one page or a whole
17
+ selection; undo/redo on every edit.
18
+ - **Split** into parts: every part has a title line, an editable name used as
19
+ the file name, and its own save and print button. Pages can be moved between
20
+ parts, also with the keyboard.
21
+ - **Export** one PDF per part, one merged PDF, or a ZIP of all parts — from your
22
+ own buttons or from the editor's.
23
+ - **Page provenance**: every page keeps the source file and page it came from;
24
+ a source can bring its own provenance, it can be written into exported PDFs,
25
+ and it is restored when such a PDF is imported again.
26
+ - **Google Drive**: open a file from Drive's "Open with" menu, browse Drive in
27
+ the editor's own dialog, and save the result back to Drive.
28
+ - **Your branding**: replace the title and icon, hide any control, inject your
29
+ own buttons into three injection points and receive their clicks as events.
30
+ - **Your product's look**: light and dark theme, a page viewer, seven languages.
31
+ - **Nothing uploaded**: PDFs are parsed, edited and rebuilt in the visitor's
32
+ browser; no document reaches a server.
33
+ - **Two levels**: a framework-agnostic class and a React component with a hook.
34
+
35
+ ## Business model
36
+
37
+ The **code** of this SDK is MIT-licensed (see [LICENSE](LICENSE)): read it, fork
38
+ it, change it, ship it.
39
+
40
+ The **editor it embeds** is a subscription product. An embedded editor asks for a
41
+ licence token (`apiKey`); without a valid one it runs in **test mode** — every
42
+ feature works, a banner marks the embedding as unlicensed. Licences are per
43
+ integration and volume, not per page.
44
+
45
+ - Pricing and the licence model: <https://pdfmerge.rsj.de/docs/licensing>
46
+ - A licence: [info@rsj.de](mailto:info@rsj.de?subject=RSJ%20PDF%20Merge%20SDK%20licence)
47
+
48
+ ## Install
15
49
 
16
50
  ```bash
17
- pnpm add @rsj-de/pdfmergesortsplit
51
+ npm install @rsj-de/pdfmergesortsplit
18
52
  ```
19
53
 
54
+ `react` is an optional peer dependency: the plain class does not import it.
55
+
56
+ ## Quick start
57
+
20
58
  ```js
21
59
  import { PDFMergeSortSplitClass } from '@rsj-de/pdfmergesortsplit';
22
60
 
23
61
  const editor = new PDFMergeSortSplitClass('#editor', {
24
- embedUrl: 'https://pdfmerge.rsj.de', // or your self-hosted deployment
25
- apiKey: '<licence JWT>', // removes the test-mode banner
62
+ apiKey: '<licence JWT>', // test mode without one
26
63
  title: 'Acme Document Suite',
27
- ui: { toolbar: { print: false } },
28
64
  actions: {
29
- // Any number of buttons per injection point; the event carries the key.
30
65
  saveAll: {
31
66
  savePdf: { title: 'Export PDF' },
32
67
  saveZip: { title: 'Export ZIP' },
@@ -36,6 +71,7 @@ const editor = new PDFMergeSortSplitClass('#editor', {
36
71
 
37
72
  await editor.whenReady();
38
73
  await editor.loadDocument({ name: 'contract.pdf', content: file });
74
+
39
75
  const pdf = await editor.exportDocument(0, 'pdf'); // part 0 → Blob
40
76
 
41
77
  editor.on('action', async ({ action, part }) => {
@@ -49,62 +85,70 @@ React:
49
85
  ```jsx
50
86
  import { PDFMergeSortSplit, usePdfMergeSortSplit } from '@rsj-de/pdfmergesortsplit/react';
51
87
 
52
- function App() {
53
- // The hook returns the editor's methods, bound to the instance it creates.
88
+ export function PdfEditor({ apiKey }) {
54
89
  const { ref, exportDocument } = usePdfMergeSortSplit();
55
90
 
56
91
  const handleAction = async ({ action, part }) => {
57
92
  if (action === 'savePdf') download(await exportDocument(part, 'pdf'));
58
93
  };
59
94
 
60
- const handleExport = ({ fileName, blob }) => download(blob, fileName);
61
-
62
95
  return (
63
96
  <PDFMergeSortSplit
64
97
  ref={ref}
65
98
  config={{ apiKey }}
66
99
  style={{ height: 640 }}
67
100
  onAction={handleAction}
68
- onExport={handleExport}
69
101
  />
70
102
  );
71
103
  }
72
104
  ```
73
105
 
106
+ More, including the configuration reference, the events and the provenance
107
+ model: <https://pdfmerge.rsj.de/docs>.
108
+
74
109
  ## API
75
110
 
76
- | member | description |
77
- |---|---|
78
- | `new PDFMergeSortSplitClass(container, config)` | creates the iframe in `container` (element or selector) |
79
- | `whenReady()` | resolves when the editor took the configuration |
80
- | `setConfig(config)` | applies a new configuration to the running editor (no reload) |
81
- | `loadDocument({name, content, provenance})` | adds a PDF (File, Blob, ArrayBuffer, base64, data URL) |
82
- | `getPages()` | the pages with their per-page provenance |
83
- | `exportDocument(reference?, mode?)` | one part (`"pdf"`) or everything (`"zip"`) → `Blob`; `reference` is a part index or name |
84
- | `on("action" \| "export", handler)` | injected buttons and finished exports; returns an unsubscribe function |
85
- | `destroy()` | removes the iframe |
111
+ | Member | Description |
112
+ | --- | --- |
113
+ | `new PDFMergeSortSplitClass(container, config)` | Creates the editor in `container` (element or selector). |
114
+ | `whenReady()` | Resolves when the editor took the configuration. |
115
+ | `setConfig(config)` | Applies a new configuration to the running editor (no reload). |
116
+ | `loadDocument({name, content, provenance})` | Adds a PDF (File, Blob, ArrayBuffer, base64, data URL), optionally with per-page provenance. |
117
+ | `getPages()` | The pages in screen order, each with its provenance. |
118
+ | `exportDocument(reference?, mode?)` | One part (`"pdf"`, by index or name) or everything (`"zip"`) → `Blob`. |
119
+ | `on("action" \| "export" \| "license", handler)` | Injected buttons, finished exports, licence state; returns an unsubscribe function. |
120
+ | `destroy()` | Removes the editor and rejects pending requests. |
86
121
 
87
122
  ## Configuration
88
123
 
89
- `config` is passed to the editor as it is:
90
-
91
- - `embedUrl` — where the editor is served (default `https://pdfmerge.rsj.de`).
92
- - `apiKey` — the licence JWT. Without one the embedded editor shows a
93
- "test mode" banner and stays fully functional.
124
+ - `apiKey` — the licence token; without one the editor runs in test mode.
125
+ - `embedUrl` — where the editor is served (default `https://pdfmerge.rsj.de`,
126
+ or your self-hosted deployment).
94
127
  - `title`, `icon` — replace the title bar of the editor.
95
- - `ui` — hide any combination of the title-bar and toolbar controls and the
96
- part-header buttons (`ui.toolbar`, `ui.partHeader`); everything is shown by
97
- default.
128
+ - `ui` — hide any combination of the title-bar, toolbar and part-header controls.
98
129
  - `actions.loaders` / `actions.saveAll` / `actions.savePart` — buttons injected
99
- into the editor. Their clicks arrive as `on("action", …)` with
130
+ into the editor; their clicks arrive as `on("action", …)` with
100
131
  `{action, where, reference, part}`.
101
132
  - `provenance.attach` — write the page provenance into exported PDFs.
133
+ - `googleClientId` — OAuth client ID of your own Google Cloud project for the
134
+ Drive integration (see <https://pdfmerge.rsj.de/docs/google-drive>).
102
135
 
103
136
  A running editor takes a new configuration with `setConfig(config)`; the React
104
137
  component calls it whenever the `config` prop changes, so the open document
105
- stays. Only a different `embedUrl` needs a new iframe.
138
+ stays. Only a different `embedUrl` needs a new iframe. The full schema is in
139
+ `types/index.d.ts`.
140
+
141
+ ## Samples
106
142
 
107
- The full schema is in `types/index.d.ts`.
143
+ `../sdksimple` (plain JavaScript) and `../sdksample` (React) use this package
144
+ through `link:../sdk`, so build the SDK before starting a sample:
145
+
146
+ ```bash
147
+ pnpm --dir sdk install --ignore-workspace
148
+ pnpm --dir sdk run build
149
+ pnpm --dir sdksimple install --ignore-workspace && pnpm --dir sdksimple run dev
150
+ pnpm --dir sdksample install --ignore-workspace && pnpm --dir sdksample run dev
151
+ ```
108
152
 
109
153
  ## Build and publish
110
154
 
@@ -114,13 +158,8 @@ pnpm run build # dist/index.js, dist/index.cjs, dist/react.
114
158
  npm publish # prepublishOnly builds again
115
159
  ```
116
160
 
117
- `react` is an optional peer dependency: the plain class does not import it.
118
-
119
- ## Samples
120
-
121
- `../sdksimple` (plain JavaScript) and `../sdksample` (React) both use this
122
- package through `link:../sdk`, so build the SDK before starting a sample.
161
+ ## Licence
123
162
 
124
- The published sources live in
125
- <https://github.com/pdfmergesortsplit/pdfmergesortsplit> (mirrored from the
126
- product repository on every release); issues go there.
163
+ MIT — see [LICENSE](LICENSE). The MIT licence covers this SDK's code; operating
164
+ the embedded editor requires a subscription as described under
165
+ [Business model](#business-model).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsj-de/pdfmergesortsplit",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Embed the RSJ PDF Merge, Sort & Split editor in your own product: one iframe, a small SDK, documents never leave the browser.",
5
5
  "keywords": [
6
6
  "pdf",
@@ -40,13 +40,14 @@
40
40
  "files": [
41
41
  "dist",
42
42
  "types",
43
- "README.md"
43
+ "README.md",
44
+ "LICENSE"
44
45
  ],
45
46
  "publishConfig": {
46
47
  "access": "public"
47
48
  },
48
49
  "sideEffects": false,
49
- "license": "UNLICENSED",
50
+ "license": "MIT",
50
51
  "scripts": {
51
52
  "build": "vite build",
52
53
  "prepublishOnly": "pnpm run build"
package/types/index.d.ts CHANGED
@@ -8,6 +8,12 @@ export interface PDFMergeConfig {
8
8
  title?: string;
9
9
  /** Icon (URL) that replaces ours in the title bar. */
10
10
  icon?: string;
11
+ /**
12
+ * OAuth client ID of your own Google Cloud project for the Drive integration.
13
+ * It overrides the one compiled into the editor, so a self-hosted deployment
14
+ * needs no rebuild. Without it the Drive buttons are hidden.
15
+ */
16
+ googleClientId?: string;
11
17
  /** Hide parts of the editor's UI. Everything is shown by default. */
12
18
  ui?: {
13
19
  logo?: boolean;