chromiumly 5.2.1 → 6.0.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/README.md +663 -360
- package/dist/chromium/converters/html.converter.d.ts +2 -2
- package/dist/chromium/converters/html.converter.js +14 -4
- package/dist/chromium/converters/html.converter.js.map +1 -1
- package/dist/chromium/converters/markdown.converter.d.ts +2 -2
- package/dist/chromium/converters/markdown.converter.js +23 -5
- package/dist/chromium/converters/markdown.converter.js.map +1 -1
- package/dist/chromium/converters/url.converter.d.ts +2 -2
- package/dist/chromium/converters/url.converter.js +14 -4
- package/dist/chromium/converters/url.converter.js.map +1 -1
- package/dist/chromium/interfaces/common.types.d.ts +1 -0
- package/dist/chromium/interfaces/converter.types.d.ts +26 -17
- package/dist/chromium/interfaces/screenshot.types.d.ts +16 -7
- package/dist/chromium/screenshots/html.screenshot.d.ts +1 -2
- package/dist/chromium/screenshots/html.screenshot.js +8 -8
- package/dist/chromium/screenshots/html.screenshot.js.map +1 -1
- package/dist/chromium/screenshots/markdown.screenshot.d.ts +1 -2
- package/dist/chromium/screenshots/markdown.screenshot.js +14 -9
- package/dist/chromium/screenshots/markdown.screenshot.js.map +1 -1
- package/dist/chromium/screenshots/url.screenshot.d.ts +1 -2
- package/dist/chromium/screenshots/url.screenshot.js +4 -8
- package/dist/chromium/screenshots/url.screenshot.js.map +1 -1
- package/dist/chromium/utils/converter.utils.js +69 -43
- package/dist/chromium/utils/converter.utils.js.map +1 -1
- package/dist/chromium/utils/screenshot.utils.d.ts +0 -10
- package/dist/chromium/utils/screenshot.utils.js +6 -44
- package/dist/chromium/utils/screenshot.utils.js.map +1 -1
- package/dist/common/constants.d.ts +1 -0
- package/dist/common/constants.js +1 -0
- package/dist/common/constants.js.map +1 -1
- package/dist/common/factur-x.types.d.ts +24 -0
- package/dist/common/factur-x.types.js +3 -0
- package/dist/common/factur-x.types.js.map +1 -0
- package/dist/common/factur-x.utils.d.ts +6 -0
- package/dist/common/factur-x.utils.js +48 -0
- package/dist/common/factur-x.utils.js.map +1 -0
- package/dist/common/gotenberg.utils.d.ts +16 -2
- package/dist/common/gotenberg.utils.js +39 -6
- package/dist/common/gotenberg.utils.js.map +1 -1
- package/dist/common/index.d.ts +5 -1
- package/dist/common/index.js +5 -1
- package/dist/common/index.js.map +1 -1
- package/dist/common/pdf-engine-encryption.types.d.ts +14 -0
- package/dist/common/pdf-engine-encryption.types.js +3 -0
- package/dist/common/pdf-engine-encryption.types.js.map +1 -0
- package/dist/common/pdf-engine-encryption.utils.d.ts +7 -0
- package/dist/common/pdf-engine-encryption.utils.js +32 -0
- package/dist/common/pdf-engine-encryption.utils.js.map +1 -0
- package/dist/common/types.d.ts +29 -2
- package/dist/libre-office/interfaces/libre-office.types.d.ts +10 -5
- package/dist/libre-office/libre-office.d.ts +2 -2
- package/dist/libre-office/libre-office.js +12 -4
- package/dist/libre-office/libre-office.js.map +1 -1
- package/dist/libre-office/utils/constants.js +0 -2
- package/dist/libre-office/utils/constants.js.map +1 -1
- package/dist/libre-office/utils/libre-office.utils.js +8 -0
- package/dist/libre-office/utils/libre-office.utils.js.map +1 -1
- package/dist/main.config.d.ts +2 -0
- package/dist/main.config.js +2 -0
- package/dist/main.config.js.map +1 -1
- package/dist/pdf-engines/interfaces/pdf-engines.types.d.ts +18 -8
- package/dist/pdf-engines/pdf-engines.d.ts +56 -28
- package/dist/pdf-engines/pdf-engines.js +109 -28
- package/dist/pdf-engines/pdf-engines.js.map +1 -1
- package/dist/system/system.d.ts +20 -5
- package/dist/system/system.js +25 -10
- package/dist/system/system.js.map +1 -1
- package/package.json +85 -82
package/README.md
CHANGED
|
@@ -35,26 +35,26 @@ Once the environment variable is set, Chromiumly will automatically send all req
|
|
|
35
35
|
You can also configure the hosted API programmatically without an endpoint:
|
|
36
36
|
|
|
37
37
|
```typescript
|
|
38
|
-
import { Chromiumly } from
|
|
38
|
+
import { Chromiumly } from 'chromiumly';
|
|
39
39
|
|
|
40
40
|
Chromiumly.configure({
|
|
41
|
-
|
|
41
|
+
apiKey: 'your-api-key'
|
|
42
42
|
});
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
### Minimal usage example (hosted API)
|
|
46
46
|
|
|
47
47
|
```typescript
|
|
48
|
-
import { UrlConverter } from
|
|
48
|
+
import { UrlConverter } from 'chromiumly';
|
|
49
49
|
|
|
50
50
|
async function run() {
|
|
51
|
-
|
|
51
|
+
const urlConverter = new UrlConverter();
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
const buffer = await urlConverter.convert({
|
|
54
|
+
url: 'https://www.example.com/'
|
|
55
|
+
});
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
// Write the buffer to disk, send it over HTTP, etc.
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
run();
|
|
@@ -64,34 +64,41 @@ run();
|
|
|
64
64
|
|
|
65
65
|
1. [API Key Authentication (Hosted API)](#api-key-authentication-hosted-api)
|
|
66
66
|
2. [Getting Started](#getting-started)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
- [Installation](#installation)
|
|
68
|
+
- [Prerequisites](#prerequisites)
|
|
69
|
+
- [Configuration](#configuration)
|
|
70
70
|
3. [Authentication](#authentication)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
- [Basic Authentication](#basic-authentication)
|
|
72
|
+
- [API Key Authentication](#api-key-authentication)
|
|
73
|
+
- [Advanced Authentication](#advanced-authentication)
|
|
74
74
|
4. [Core Features](#core-features)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
75
|
+
- [Chromium](#chromium)
|
|
76
|
+
- [URL](#url)
|
|
77
|
+
- [HTML](#html)
|
|
78
|
+
- [Markdown](#markdown)
|
|
79
|
+
- [Screenshot](#screenshot)
|
|
80
|
+
- [LibreOffice](#libreoffice)
|
|
81
|
+
- [PDF Engines](#pdf-engines)
|
|
82
|
+
- [Format Conversion](#format-conversion)
|
|
83
|
+
- [Merging](#merging)
|
|
84
|
+
- [PDF Rotation](#pdf-rotation)
|
|
85
|
+
- [Watermark and stamp (dedicated routes)](#watermark-and-stamp-dedicated-routes)
|
|
86
|
+
- [Metadata Management](#metadata-management)
|
|
87
|
+
- [Bookmarks Management](#bookmarks-management)
|
|
88
|
+
- [Encryption (dedicated route)](#encryption-dedicated-route)
|
|
89
|
+
- [Embedding Files (dedicated route)](#embedding-files-dedicated-route)
|
|
90
|
+
- [Factur-X / ZUGFeRD (dedicated route)](#factur-x--zugferd-dedicated-route)
|
|
91
|
+
- [File Generation](#file-generation)
|
|
92
|
+
- [System](#system)
|
|
93
|
+
- [PDF Splitting](#pdf-splitting)
|
|
94
|
+
- [PDF Flattening](#pdf-flattening)
|
|
95
|
+
- [PDF Encryption](#pdf-encryption)
|
|
96
|
+
- [PDF Permissions](#pdf-permissions)
|
|
97
|
+
- [Embedding Files](#embedding-files)
|
|
98
|
+
- [Factur-X / ZUGFeRD](#factur-x--zugferd)
|
|
99
|
+
- [Output Filename and Request Tracing](#output-filename-and-request-tracing)
|
|
100
|
+
- [Templates (hosted API only)](#templates-hosted-api-only)
|
|
101
|
+
- [Watermark and stamp](#watermark-and-stamp)
|
|
95
102
|
5. [Usage Example](#snippet)
|
|
96
103
|
|
|
97
104
|
## Getting Started
|
|
@@ -137,18 +144,18 @@ GOTENBERG_ENDPOINT=http://localhost:3000
|
|
|
137
144
|
|
|
138
145
|
```json
|
|
139
146
|
{
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
147
|
+
"gotenberg": {
|
|
148
|
+
"endpoint": "http://localhost:3000"
|
|
149
|
+
}
|
|
143
150
|
}
|
|
144
151
|
```
|
|
145
152
|
|
|
146
153
|
#### code
|
|
147
154
|
|
|
148
155
|
```typescript
|
|
149
|
-
import { Chromiumly } from
|
|
156
|
+
import { Chromiumly } from 'chromiumly';
|
|
150
157
|
|
|
151
|
-
Chromiumly.configure({ endpoint:
|
|
158
|
+
Chromiumly.configure({ endpoint: 'http://localhost:3000' });
|
|
152
159
|
```
|
|
153
160
|
|
|
154
161
|
## Authentication
|
|
@@ -177,15 +184,15 @@ Or
|
|
|
177
184
|
|
|
178
185
|
```json
|
|
179
186
|
{
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
+
"gotenberg": {
|
|
188
|
+
"endpoint": "http://localhost:3000",
|
|
189
|
+
"api": {
|
|
190
|
+
"basicAuth": {
|
|
191
|
+
"username": "user",
|
|
192
|
+
"password": "pass"
|
|
193
|
+
}
|
|
194
|
+
}
|
|
187
195
|
}
|
|
188
|
-
}
|
|
189
196
|
}
|
|
190
197
|
```
|
|
191
198
|
|
|
@@ -193,9 +200,9 @@ Or
|
|
|
193
200
|
|
|
194
201
|
```typescript
|
|
195
202
|
Chromiumly.configure({
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
203
|
+
endpoint: 'http://localhost:3000',
|
|
204
|
+
username: 'user',
|
|
205
|
+
password: 'pass'
|
|
199
206
|
});
|
|
200
207
|
```
|
|
201
208
|
|
|
@@ -213,11 +220,11 @@ For example, you can include a Bearer token for authentication along with a cust
|
|
|
213
220
|
const token = await generateToken();
|
|
214
221
|
|
|
215
222
|
Chromiumly.configure({
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
223
|
+
endpoint: 'http://localhost:3000',
|
|
224
|
+
customHttpHeaders: {
|
|
225
|
+
Authorization: `Bearer ${token}`,
|
|
226
|
+
'X-Custom-Header': 'value'
|
|
227
|
+
}
|
|
221
228
|
});
|
|
222
229
|
```
|
|
223
230
|
|
|
@@ -238,20 +245,20 @@ Similarly, a new set of classes have been added to harness the recently introduc
|
|
|
238
245
|
#### URL
|
|
239
246
|
|
|
240
247
|
```typescript
|
|
241
|
-
import { UrlConverter } from
|
|
248
|
+
import { UrlConverter } from 'chromiumly';
|
|
242
249
|
|
|
243
250
|
const urlConverter = new UrlConverter();
|
|
244
251
|
const buffer = await urlConverter.convert({
|
|
245
|
-
|
|
252
|
+
url: 'https://www.example.com/'
|
|
246
253
|
});
|
|
247
254
|
```
|
|
248
255
|
|
|
249
256
|
```typescript
|
|
250
|
-
import { UrlScreenshot } from
|
|
257
|
+
import { UrlScreenshot } from 'chromiumly';
|
|
251
258
|
|
|
252
259
|
const screenshot = new UrlScreenshot();
|
|
253
260
|
const buffer = await screenshot.capture({
|
|
254
|
-
|
|
261
|
+
url: 'https://www.example.com/'
|
|
255
262
|
});
|
|
256
263
|
```
|
|
257
264
|
|
|
@@ -260,20 +267,20 @@ const buffer = await screenshot.capture({
|
|
|
260
267
|
The only requirement is that the file name should be `index.html`.
|
|
261
268
|
|
|
262
269
|
```typescript
|
|
263
|
-
import { HtmlConverter } from
|
|
270
|
+
import { HtmlConverter } from 'chromiumly';
|
|
264
271
|
|
|
265
272
|
const htmlConverter = new HtmlConverter();
|
|
266
273
|
const buffer = await htmlConverter.convert({
|
|
267
|
-
|
|
274
|
+
html: 'path/to/index.html'
|
|
268
275
|
});
|
|
269
276
|
```
|
|
270
277
|
|
|
271
278
|
```typescript
|
|
272
|
-
import { HtmlScreenshot } from
|
|
279
|
+
import { HtmlScreenshot } from 'chromiumly';
|
|
273
280
|
|
|
274
281
|
const screenshot = new HtmlScreenshot();
|
|
275
282
|
const buffer = await screenshot.capture({
|
|
276
|
-
|
|
283
|
+
html: 'path/to/index.html'
|
|
277
284
|
});
|
|
278
285
|
```
|
|
279
286
|
|
|
@@ -282,22 +289,46 @@ const buffer = await screenshot.capture({
|
|
|
282
289
|
This route accepts an `index.html` file plus a markdown file.
|
|
283
290
|
|
|
284
291
|
```typescript
|
|
285
|
-
import { MarkdownConverter } from
|
|
292
|
+
import { MarkdownConverter } from 'chromiumly';
|
|
286
293
|
|
|
287
294
|
const markdownConverter = new MarkdownConverter();
|
|
288
295
|
const buffer = await markdownConverter.convert({
|
|
289
|
-
|
|
290
|
-
|
|
296
|
+
html: 'path/to/index.html',
|
|
297
|
+
markdown: 'path/to/file.md'
|
|
291
298
|
});
|
|
292
299
|
```
|
|
293
300
|
|
|
294
301
|
```typescript
|
|
295
|
-
import { MarkdownScreenshot } from
|
|
302
|
+
import { MarkdownScreenshot } from 'chromiumly';
|
|
296
303
|
|
|
297
304
|
const screenshot = new MarkdownScreenshot();
|
|
298
305
|
const buffer = await screenshot.capture({
|
|
299
|
-
|
|
300
|
-
|
|
306
|
+
html: 'path/to/index.html',
|
|
307
|
+
markdown: 'path/to/file.md'
|
|
308
|
+
});
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
The `markdown` field on the Markdown convert and screenshot routes also accepts an array of distinctly-named files, all referenced from the same `index.html` template:
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
const buffer = await markdownConverter.convert({
|
|
315
|
+
html: 'path/to/index.html',
|
|
316
|
+
markdown: [
|
|
317
|
+
{ file: 'path/to/chapter1.md', name: 'chapter1.md' },
|
|
318
|
+
{ file: 'path/to/chapter2.md', name: 'chapter2.md' }
|
|
319
|
+
]
|
|
320
|
+
});
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
HTML and Markdown convert/screenshot routes also accept an optional `assets` field for images, stylesheets, or other files referenced from the HTML/markdown content:
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
const buffer = await htmlConverter.convert({
|
|
327
|
+
html: 'path/to/index.html',
|
|
328
|
+
assets: [
|
|
329
|
+
{ file: 'path/to/style.css', name: 'style.css' },
|
|
330
|
+
{ file: 'path/to/logo.png', name: 'logo.png' }
|
|
331
|
+
]
|
|
301
332
|
});
|
|
302
333
|
```
|
|
303
334
|
|
|
@@ -306,38 +337,40 @@ file will look like.
|
|
|
306
337
|
|
|
307
338
|
```typescript
|
|
308
339
|
type PageProperties = {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
340
|
+
singlePage?: boolean; // Print the entire content in one single page (default false)
|
|
341
|
+
size?: {
|
|
342
|
+
width?: number | string; // Paper width (number in inches or string with units: 72pt, 96px, 1in, 25.4mm, 2.54cm, 6pc, default 8.5)
|
|
343
|
+
height?: number | string; // Paper height (number in inches or string with units: 72pt, 96px, 1in, 25.4mm, 2.54cm, 6pc, default 11)
|
|
344
|
+
};
|
|
345
|
+
margins?: {
|
|
346
|
+
top?: number | string; // Top margin (number in inches or string with units: 72pt, 96px, 1in, 25.4mm, 2.54cm, 6pc, default 0.39)
|
|
347
|
+
bottom?: number | string; // Bottom margin (number in inches or string with units: 72pt, 96px, 1in, 25.4mm, 2.54cm, 6pc, default 0.39)
|
|
348
|
+
left?: number | string; // Left margin (number in inches or string with units: 72pt, 96px, 1in, 25.4mm, 2.54cm, 6pc, default 0.39)
|
|
349
|
+
right?: number | string; // Right margin (number in inches or string with units: 72pt, 96px, 1in, 25.4mm, 2.54cm, 6pc, default 0.39)
|
|
350
|
+
};
|
|
351
|
+
preferCssPageSize?: boolean; // Define whether to prefer page size as defined by CSS (default false)
|
|
352
|
+
printBackground?: boolean; // Print the background graphics (default false)
|
|
353
|
+
omitBackground?: boolean; // Hide the default white background and allow generating PDFs with transparency (default false)
|
|
354
|
+
landscape?: boolean; // Set the paper orientation to landscape (default false)
|
|
355
|
+
scale?: number; // The scale of the page rendering (default 1.0)
|
|
356
|
+
nativePageRanges?: { from: number; to: number } | string; // Page ranges to print, either a single range or the free-form syntax "1-5, 8, 11-13"
|
|
326
357
|
};
|
|
327
358
|
```
|
|
328
359
|
|
|
360
|
+
Every field of `size` and `margins` defaults independently, so you can set just one dimension or margin and let Gotenberg fill in the rest.
|
|
361
|
+
|
|
329
362
|
**Page Size and Margins Units**
|
|
330
363
|
|
|
331
364
|
Both `size` and `margins` properties support two formats:
|
|
332
365
|
|
|
333
366
|
1. **Numeric values** (in inches): For backward compatibility, you can continue using numbers which represent inches.
|
|
334
367
|
2. **String values with units**: You can now specify explicit units using the following formats:
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
368
|
+
- `pt` (points): e.g., `"72pt"`
|
|
369
|
+
- `px` (pixels): e.g., `"96px"`
|
|
370
|
+
- `in` (inches): e.g., `"1in"`
|
|
371
|
+
- `mm` (millimeters): e.g., `"25.4mm"`
|
|
372
|
+
- `cm` (centimeters): e.g., `"2.54cm"`
|
|
373
|
+
- `pc` (picas): e.g., `"6pc"`
|
|
341
374
|
|
|
342
375
|
**Examples:**
|
|
343
376
|
|
|
@@ -365,75 +398,104 @@ In addition to the `PageProperties` customization options, the `convert()` metho
|
|
|
365
398
|
|
|
366
399
|
```typescript
|
|
367
400
|
type ConversionOptions = {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
401
|
+
properties?: PageProperties; // Customize the appearance of the generated PDF
|
|
402
|
+
/** @deprecated Chromium no longer supports pdfFormat since Gotenberg 8.0.0; use pdfa instead of pdfFormat. */
|
|
403
|
+
pdfFormat?: PdfFormat;
|
|
404
|
+
pdfUA?: boolean; // Enable PDF for Universal Access for optimal accessibility (default false)
|
|
405
|
+
generateTaggedPdf?: boolean; // Embed PDF/UA accessibility structure tags, independent of pdfUA (default false)
|
|
406
|
+
generateDocumentOutline?: boolean; // Generate a document outline / bookmarks from the page's heading tags (default false)
|
|
407
|
+
userAgent?: string; // Customize the user agent string sent during conversion
|
|
408
|
+
header?: PathLikeOrReadStream; // Specify a custom header for the PDF
|
|
409
|
+
footer?: PathLikeOrReadStream; // Specify a custom footer for the PDF
|
|
410
|
+
emulatedMediaType?: EmulatedMediaType; // Specify the emulated media type for conversion
|
|
411
|
+
emulatedMediaFeatures?: EmulatedMediaFeature[]; // Override CSS media features (e.g., prefers-color-scheme). Default: None.
|
|
412
|
+
waitDelay?: string; // Duration (e.g., '5s') to wait when loading an HTML document before conversion
|
|
413
|
+
waitForExpression?: string; // JavaScript expression to wait before converting an HTML document into PDF
|
|
414
|
+
waitForSelector?: string; // CSS selector to wait for before converting an HTML document into PDF until it matches a node
|
|
415
|
+
extraHttpHeaders?: Record<string, string>; // Include additional HTTP headers in the request
|
|
416
|
+
failOnHttpStatusCodes?: number[]; // List of HTTP status codes triggering a 409 Conflict response (default [499, 599])
|
|
417
|
+
failOnConsoleExceptions?: boolean; // Return a 409 Conflict response if there are exceptions in the Chromium console (default false)
|
|
418
|
+
failOnResourceHttpStatusCodes?: number[]; // Return a 409 Conflict response if resource HTTP status code is in the list (default None)
|
|
419
|
+
ignoreResourceHttpStatusDomains?: string[]; // Domains to exclude from resource HTTP status code checks (matches exact domains or subdomains)
|
|
420
|
+
failOnResourceLoadingFailed?: boolean; // Return a 409 Conflict response if resource loading failed (default false)
|
|
421
|
+
skipNetworkIdleEvent?: boolean; // Do not wait for Chromium network to be idle (default true)
|
|
422
|
+
skipNetworkAlmostIdleEvent?: boolean; // Do not wait for Chromium network to be almost idle (default true)
|
|
423
|
+
metadata?: Metadata; // Metadata to be written.
|
|
424
|
+
cookies?: Cookie[]; // Cookies to be written.
|
|
425
|
+
downloadFrom?: DownloadFrom; // Download a file from one or multiple URLs. Each URL must return a Content-Disposition header with a filename parameter.
|
|
426
|
+
webhook?: WebhookOptions; // Request-level webhook headers for async callbacks.
|
|
427
|
+
outputFilename?: string; // Custom filename for the resulting file; Gotenberg appends the extension.
|
|
428
|
+
trace?: string; // Custom request id to identify the request in the logs, overriding the generated UUID.
|
|
429
|
+
split?: ConvertSplit; // Split the PDF file into multiple files.
|
|
430
|
+
flatten?: boolean; // Flatten the resulting PDF document (default false)
|
|
431
|
+
userPassword?: string; // Password for opening the resulting PDF(s).
|
|
432
|
+
ownerPassword?: string; // Password for full access on the resulting PDF(s).
|
|
433
|
+
allowPrinting?: boolean; // Allow printing the document (default true)
|
|
434
|
+
allowCopying?: boolean; // Allow copying content from the document (default true)
|
|
435
|
+
allowModifying?: boolean; // Allow modifying the document (default true)
|
|
436
|
+
allowAnnotating?: boolean; // Allow adding or modifying annotations (default true)
|
|
437
|
+
allowFillingForms?: boolean; // Allow filling in form fields (default true)
|
|
438
|
+
allowAssembling?: boolean; // Allow document assembly, e.g. inserting, deleting, or rotating pages (default true)
|
|
439
|
+
embeds?: PathLikeOrReadStream[]; // Files to embed in the generated PDF.
|
|
440
|
+
embedsMetadata?: EmbedsMetadata; // Per-attachment metadata keyed by filename, for PDF/A-3 and Factur-X compliance.
|
|
441
|
+
watermark?: PdfEngineWatermark; // Optional PDF-engine post-processing watermark (behind page content).
|
|
442
|
+
stamp?: PdfEngineStamp; // Optional PDF-engine post-processing stamp (on top of page content).
|
|
443
|
+
rotate?: PdfEngineRotate; // Optional PDF-engine post-process page rotation.
|
|
444
|
+
facturx?: FacturXOptions; // Turn the resulting PDF into a Factur-X / ZUGFeRD e-invoice.
|
|
397
445
|
};
|
|
398
446
|
```
|
|
399
447
|
|
|
400
448
|
```typescript
|
|
401
449
|
type DownloadFromEntry = {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
450
|
+
url: string;
|
|
451
|
+
extraHttpHeaders?: Record<string, string>;
|
|
452
|
+
embedded?: boolean; // Legacy flag, prefer field
|
|
453
|
+
field?: 'embedded' | 'watermark' | 'stamp' | '';
|
|
406
454
|
};
|
|
407
455
|
|
|
408
456
|
type DownloadFrom = DownloadFromEntry | DownloadFromEntry[];
|
|
409
457
|
|
|
410
458
|
type WebhookOptions = {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
459
|
+
webhookUrl?: string; // At least one of webhookUrl or webhookErrorUrl is required.
|
|
460
|
+
/** @deprecated Use webhookEventsUrl instead, together with webhookUrl. */
|
|
461
|
+
webhookErrorUrl?: string;
|
|
462
|
+
webhookMethod?: 'POST' | 'PUT' | 'PATCH';
|
|
463
|
+
webhookErrorMethod?: 'POST' | 'PUT' | 'PATCH';
|
|
464
|
+
webhookExtraHttpHeaders?: Record<string, string>;
|
|
465
|
+
webhookEventsUrl?: string;
|
|
417
466
|
};
|
|
467
|
+
|
|
468
|
+
type EmbedsMetadata = Record<
|
|
469
|
+
string, // filename, matching an entry in `embeds`
|
|
470
|
+
{
|
|
471
|
+
mimeType?: string; // Written to the embedded file stream's /Subtype
|
|
472
|
+
relationship?:
|
|
473
|
+
| 'Source'
|
|
474
|
+
| 'Data'
|
|
475
|
+
| 'Alternative'
|
|
476
|
+
| 'Supplement'
|
|
477
|
+
| 'Unspecified'; // The /AFRelationship value
|
|
478
|
+
}
|
|
479
|
+
>;
|
|
418
480
|
```
|
|
419
481
|
|
|
420
482
|
Optional `watermark` and `stamp` use the same multipart field names as [Gotenberg’s PDF-engine watermark/stamp](https://gotenberg.dev/docs/manipulate-pdfs/watermark-pdfs): text, image, or PDF sources, with JSON `options` depending on your configured engine (e.g. pdfcpu). See [Watermark PDFs](https://gotenberg.dev/docs/manipulate-pdfs/watermark-pdfs) and [Stamp PDFs](https://gotenberg.dev/docs/manipulate-pdfs/stamp-pdfs) in the official docs.
|
|
421
483
|
|
|
422
484
|
```typescript
|
|
423
485
|
type PdfEngineWatermark = {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
486
|
+
source?: 'text' | 'image' | 'pdf';
|
|
487
|
+
expression?: string; // Text, or filename of the uploaded asset when source is image or pdf
|
|
488
|
+
pages?: string; // Page ranges (e.g. "1-3"); omit for all pages
|
|
489
|
+
options?: Record<string, unknown>; // Serialized as JSON (engine-specific)
|
|
490
|
+
file?: PathLikeOrReadStream | Buffer; // Required when source is image or pdf
|
|
429
491
|
};
|
|
430
492
|
|
|
431
493
|
type PdfEngineStamp = {
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
494
|
+
source?: 'text' | 'image' | 'pdf';
|
|
495
|
+
expression?: string;
|
|
496
|
+
pages?: string;
|
|
497
|
+
options?: Record<string, unknown>;
|
|
498
|
+
file?: PathLikeOrReadStream | Buffer;
|
|
437
499
|
};
|
|
438
500
|
```
|
|
439
501
|
|
|
@@ -443,42 +505,41 @@ Similarly, the `capture()` method takes an optional `properties` parameter of th
|
|
|
443
505
|
|
|
444
506
|
```typescript
|
|
445
507
|
type ImageProperties = {
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
508
|
+
format: 'png' | 'jpeg' | 'webp'; //The image compression format, either "png", "jpeg" or "webp".
|
|
509
|
+
quality?: number; // The compression quality from range 0 to 100 (jpeg only).
|
|
510
|
+
omitBackground?: boolean; // Hide the default white background and allow generating screenshots with transparency.
|
|
511
|
+
width?: number; // The device screen width in pixels (default 800).
|
|
512
|
+
height?: number; // The device screen height in pixels (default 600).
|
|
513
|
+
clip?: boolean; // Define whether to clip the screenshot according to the device dimensions (default false).
|
|
514
|
+
deviceScaleFactor?: number; // The device scale factor, useful for HiDPI screenshots (default 1).
|
|
452
515
|
};
|
|
453
516
|
```
|
|
454
517
|
|
|
455
|
-
Furthermore, alongside the customization options offered by `ImageProperties`, the `capture()` method accommodates a variety of parameters to expand the versatility of the screenshot process. Below is a comprehensive overview of all parameters available
|
|
518
|
+
Furthermore, alongside the customization options offered by `ImageProperties`, the `capture()` method accommodates a variety of parameters to expand the versatility of the screenshot process. Below is a comprehensive overview of all parameters available. Note that screenshots produce an image rather than a PDF, so PDF-only options like `header`/`footer`, `generateDocumentOutline`, `userPassword`/`ownerPassword`, and `embeds` don't apply here.
|
|
456
519
|
|
|
457
520
|
```typescript
|
|
458
521
|
type ScreenshotOptions = {
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
ownerPassword?: string; // Password for full access on the resulting PDF(s).
|
|
481
|
-
embeds?: PathLikeOrReadStream[]; // Files to embed in the generated PDF.
|
|
522
|
+
properties?: ImageProperties;
|
|
523
|
+
userAgent?: string; // Override the User-Agent header sent by Chromium.
|
|
524
|
+
emulatedMediaType?: EmulatedMediaType;
|
|
525
|
+
emulatedMediaFeatures?: EmulatedMediaFeature[]; // Override CSS media features (e.g., prefers-color-scheme). Default: None.
|
|
526
|
+
waitDelay?: string; // Duration (e.g, '5s') to wait when loading an HTML document before convertion.
|
|
527
|
+
waitForExpression?: string; // JavaScript's expression to wait before converting an HTML document into PDF until it returns true.
|
|
528
|
+
waitForSelector?: string; // CSS selector to wait for before converting an HTML document into PDF until it matches a node.
|
|
529
|
+
extraHttpHeaders?: Record<string, string>;
|
|
530
|
+
failOnHttpStatusCodes?: number[]; // Return a 409 Conflict response if the HTTP status code is in the list (default [499,599])
|
|
531
|
+
failOnConsoleExceptions?: boolean; // Return a 409 Conflict response if there are exceptions in the Chromium console (default false)
|
|
532
|
+
failOnResourceHttpStatusCodes?: number[]; // Return a 409 Conflict response if resource HTTP status code is in the list (default None)
|
|
533
|
+
ignoreResourceHttpStatusDomains?: string[]; // Domains to exclude from resource HTTP status code checks (matches exact domains or subdomains)
|
|
534
|
+
failOnResourceLoadingFailed?: boolean; // Return a 409 Conflict response if resource loading failed (default false)
|
|
535
|
+
skipNetworkIdleEvent?: boolean; // Do not wait for Chromium network to be idle (default true)
|
|
536
|
+
skipNetworkAlmostIdleEvent?: boolean; // Do not wait for Chromium network to be almost idle (default true)
|
|
537
|
+
optimizeForSpeed?: boolean; // Define whether to optimize image encoding for speed, not for resulting size.
|
|
538
|
+
cookies?: Cookie[]; // Cookies to be written.
|
|
539
|
+
downloadFrom?: DownloadFrom; // Download files from one or multiple URLs.
|
|
540
|
+
webhook?: WebhookOptions; // Request-level webhook headers for async callbacks.
|
|
541
|
+
outputFilename?: string; // Custom filename for the resulting file; Gotenberg appends the extension.
|
|
542
|
+
trace?: string; // Custom request id to identify the request in the logs, overriding the generated UUID.
|
|
482
543
|
};
|
|
483
544
|
```
|
|
484
545
|
|
|
@@ -488,21 +549,47 @@ The `LibreOffice` class comes with a single method `convert`. This method intera
|
|
|
488
549
|
accepted [here](https://gotenberg.dev/docs/convert-with-libreoffice/convert-to-pdf).
|
|
489
550
|
|
|
490
551
|
```typescript
|
|
491
|
-
import { LibreOffice } from
|
|
552
|
+
import { LibreOffice } from 'chromiumly';
|
|
492
553
|
|
|
493
554
|
const buffer = await LibreOffice.convert({
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
555
|
+
files: [
|
|
556
|
+
'path/to/file.docx',
|
|
557
|
+
'path/to/file.png',
|
|
558
|
+
{ data: xlsxFileBuffer, ext: 'xlsx' }
|
|
559
|
+
]
|
|
499
560
|
});
|
|
500
561
|
```
|
|
501
562
|
|
|
502
|
-
Similarly to Chromium's route `convert` method, this method takes the following
|
|
563
|
+
Similarly to Chromium's route `convert` method, this method takes an optional `properties` parameter of the following type, which
|
|
564
|
+
also includes a `password` field to open the source document:
|
|
503
565
|
|
|
504
|
-
|
|
505
|
-
|
|
566
|
+
```typescript
|
|
567
|
+
type PageProperties = {
|
|
568
|
+
password?: string; // Password to open the source document
|
|
569
|
+
landscape?: boolean; // Paper orientation landscape (default false)
|
|
570
|
+
nativePageRanges?: { from: number; to: number }; // Page ranges to print
|
|
571
|
+
exportFormFields?: boolean; // Export form fields as interactive widgets, or false to flatten them during conversion (default true)
|
|
572
|
+
singlePageSheets?: boolean; // Render entire spreadsheet as a single page (default false)
|
|
573
|
+
allowDuplicateFieldNames?: boolean; // Allow multiple form fields with the same name
|
|
574
|
+
exportBookmarks?: boolean; // Export bookmarks to the resulting PDF (default true)
|
|
575
|
+
exportBookmarksToPdfDestination?: boolean; // Export bookmarks as Named Destination in the PDF
|
|
576
|
+
exportPlaceholders?: boolean; // Export placeholder fields' visual markings only
|
|
577
|
+
exportNotes?: boolean; // Export notes to the resulting PDF
|
|
578
|
+
exportNotesPages?: boolean; // Export notes pages (Impress documents only)
|
|
579
|
+
exportOnlyNotesPages?: boolean; // Export only notes pages, when exportNotesPages is true
|
|
580
|
+
exportNotesInMargin?: boolean; // Export notes in the margin of the resulting PDF
|
|
581
|
+
convertOooTargetToPdfTarget?: boolean; // Change .od[tpgs] extensions to .pdf in exported links
|
|
582
|
+
exportLinksRelativeFsys?: boolean; // Export file system related hyperlinks as relative
|
|
583
|
+
exportHiddenSlides?: boolean; // Export hidden slides (Impress documents only)
|
|
584
|
+
skipEmptyPages?: boolean; // Suppress the automatic insertion of blank pages (Writer documents only)
|
|
585
|
+
updateIndexes?: boolean; // Update the document's indexes/table of contents before export (default true)
|
|
586
|
+
addOriginalDocumentAsStream?: boolean; // Insert the original file as a stream in the resulting PDF
|
|
587
|
+
};
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
In addition to `properties`, the `convert()` method accepts the following optional parameters:
|
|
591
|
+
|
|
592
|
+
- `pdfa`: PDF format of the conversion resulting file (i.e. `PDF/A-1b`, `PDF/A-2b`, `PDF/A-3b`).
|
|
506
593
|
- `pdfUA`: enables PDF for Universal Access for optimal accessibility.
|
|
507
594
|
- `merge`: merges all the resulting files from the conversion into an individual PDF file.
|
|
508
595
|
- `metadata`: writes metadata to the generated PDF file.
|
|
@@ -526,29 +613,37 @@ Similarly to Chromium's route `convert` method, this method takes the following
|
|
|
526
613
|
- `useTransitionEffects`: use transition effects for Impress slides.
|
|
527
614
|
- `openBookmarkLevels`: number of bookmark levels opened on load (`-1` opens all levels).
|
|
528
615
|
- `downloadFrom`: download files remotely (`DownloadFromEntry` or `DownloadFromEntry[]`).
|
|
529
|
-
- `
|
|
616
|
+
- `split`: split the resulting PDF into multiple files — same shape as Chromium's `split` (`ConvertSplit`, see [PDF Splitting](#pdf-splitting)).
|
|
617
|
+
- `flatten`: a boolean that, when set to true, flattens the resulting PDF's form fields and annotations, making them uneditable.
|
|
530
618
|
- `userPassword`: password for opening the resulting PDF(s).
|
|
531
619
|
- `ownerPassword`: password for full access on the resulting PDF(s).
|
|
620
|
+
- `allowPrinting` / `allowCopying` / `allowModifying` / `allowAnnotating` / `allowFillingForms` / `allowAssembling`: PDF permission booleans, each defaulting to `true` — see [PDF Permissions](#pdf-permissions).
|
|
532
621
|
- `embeds`: files to embed in the generated PDF (repeatable). This feature enables the creation of PDFs compatible with standards like [ZUGFeRD / Factur-X](https://fnfe-mpe.org/factur-x/), which require embedding XML invoices and other files within the PDF.
|
|
622
|
+
- `embedsMetadata`: per-attachment metadata keyed by filename, for PDF/A-3 and Factur-X compliance — see [Embedding Files](#embedding-files).
|
|
623
|
+
- `facturx`: turn the resulting PDF into a Factur-X / ZUGFeRD e-invoice — see [Factur-X / ZUGFeRD](#factur-x--zugferd).
|
|
624
|
+
- `outputFilename` / `trace`: custom output filename and/or request trace id — see [Output Filename and Request Tracing](#output-filename-and-request-tracing).
|
|
533
625
|
- `webhook`: request-level webhook headers for async callbacks.
|
|
534
626
|
- **Native LibreOffice watermarks** (applied during export): `nativeWatermarkText`, `nativeWatermarkColor`, `nativeWatermarkFontHeight`, `nativeWatermarkRotateAngle`, `nativeWatermarkFontName`, `nativeTiledWatermarkText` — see [Convert to PDF](https://gotenberg.dev/docs/convert-with-libreoffice/convert-to-pdf).
|
|
535
627
|
- **PDF-engine watermark/stamp** (post-processing after conversion): `watermark` and `stamp` — same shapes as in Chromium `ConversionOptions` (`PdfEngineWatermark` / `PdfEngineStamp`). For `{ data, ext }` file objects, use the same pattern as in `files`.
|
|
628
|
+
- `rotate`: PDF-engine post-process page rotation — see [PDF Rotation](#pdf-rotation).
|
|
536
629
|
|
|
537
630
|
### PDF Engines
|
|
538
631
|
|
|
539
632
|
The `PDFEngines` class interacts with Gotenberg's [PDF Engines](https://gotenberg.dev/docs/manipulate-pdfs/pdfa-pdfua) routes to manipulate PDF files.
|
|
540
633
|
|
|
634
|
+
Every method below also accepts the optional cross-cutting parameters `downloadFrom`, `webhook`, `outputFilename`, and `trace` (omitted from most examples for brevity). See the `DownloadFrom`/`WebhookOptions` types under [Chromium](#chromium) and [Output Filename and Request Tracing](#output-filename-and-request-tracing).
|
|
635
|
+
|
|
541
636
|
#### Format Conversion
|
|
542
637
|
|
|
543
|
-
This method interacts with [PDF Engines](https://gotenberg.dev/docs/manipulate-pdfs/pdfa-pdfua) convertion route to transform PDF files into the requested PDF/A format and/or PDF/UA.
|
|
638
|
+
This method interacts with [PDF Engines](https://gotenberg.dev/docs/manipulate-pdfs/pdfa-pdfua) convertion route to transform PDF files into the requested PDF/A format and/or PDF/UA. At least one of `pdfa` or `pdfUA` must be provided.
|
|
544
639
|
|
|
545
640
|
```typescript
|
|
546
|
-
import { PDFEngines } from
|
|
641
|
+
import { PDFEngines } from 'chromiumly';
|
|
547
642
|
|
|
548
643
|
const buffer = await PDFEngines.convert({
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
644
|
+
files: ['path/to/file_1.pdf', 'path/to/file_2.pdf'],
|
|
645
|
+
pdfa: PdfFormat.A_2b,
|
|
646
|
+
pdfUA: true
|
|
552
647
|
});
|
|
553
648
|
```
|
|
554
649
|
|
|
@@ -560,15 +655,28 @@ as: [PDFtk](https://gitlab.com/pdftk-java/pdftk), [PDFcpu](https://github.com/pd
|
|
|
560
655
|
and [UNO](https://github.com/unoconv/unoconv).
|
|
561
656
|
|
|
562
657
|
```typescript
|
|
563
|
-
import { PDFEngines } from
|
|
658
|
+
import { PDFEngines } from 'chromiumly';
|
|
564
659
|
|
|
565
660
|
const buffer = await PDFEngines.merge({
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
661
|
+
files: ['path/to/file_1.pdf', 'path/to/file_2.pdf'],
|
|
662
|
+
pdfa: PdfFormat.A_2b,
|
|
663
|
+
pdfUA: true,
|
|
664
|
+
metadata: { Author: 'Taha Cherfia' },
|
|
665
|
+
flatten: true,
|
|
666
|
+
bookmarks: [{ title: 'Section 1', page: 1 }],
|
|
667
|
+
autoIndexBookmarks: false, // auto-extract and offset each input's existing bookmarks (default false)
|
|
668
|
+
userPassword: 'my_user_password',
|
|
669
|
+
ownerPassword: 'my_owner_password',
|
|
670
|
+
allowPrinting: false
|
|
569
671
|
});
|
|
570
672
|
```
|
|
571
673
|
|
|
674
|
+
Optional `metadata` writes metadata to the merged PDF, and `flatten` flattens its form fields and annotations, both matching [Merge PDFs](https://gotenberg.dev/docs/manipulate-pdfs/merge-pdfs) in the Gotenberg docs.
|
|
675
|
+
|
|
676
|
+
Optional `bookmarks` sets a final bookmark list on the merged PDF, or a filename-keyed map applied to each input before merging (its page indexes get offset automatically). Optional `autoIndexBookmarks` instead auto-extracts and offsets each input's existing bookmarks. `bookmarks` and `autoIndexBookmarks` are mutually exclusive strategies for populating the merged PDF's outline.
|
|
677
|
+
|
|
678
|
+
Optional `userPassword`/`ownerPassword` and the six permission booleans (`allowPrinting`, `allowCopying`, `allowModifying`, `allowAnnotating`, `allowFillingForms`, `allowAssembling`) encrypt the merged output — see [PDF Encryption](#pdf-encryption) and [PDF Permissions](#pdf-permissions).
|
|
679
|
+
|
|
572
680
|
Optional `watermark` and `stamp` (`PdfEngineWatermark` / `PdfEngineStamp`) apply PDF-engine post-processing to the merged output, matching [Merge PDFs](https://gotenberg.dev/docs/manipulate-pdfs/merge-pdfs) in the Gotenberg docs.
|
|
573
681
|
|
|
574
682
|
Optional `rotate` (`{ angle: 90 | 180 | 270; pages?: string }`) rotates pages after merge via the PDF engine; omit `pages` or leave it empty to rotate all pages.
|
|
@@ -578,12 +686,12 @@ Optional `rotate` (`{ angle: 90 | 180 | 270; pages?: string }`) rotates pages af
|
|
|
578
686
|
`PDFEngines.rotate()` calls Gotenberg’s [rotate route](https://gotenberg.dev/docs/manipulate-pdfs/rotate-pdfs) to rotate existing PDFs. The same post-processing is available on `PDFEngines.merge()`, `PDFEngines.split()`, and on Chromium and LibreOffice `convert()` through the optional `rotate` property (Gotenberg generates the PDF, then rotates selected pages—an extra pass).
|
|
579
687
|
|
|
580
688
|
```typescript
|
|
581
|
-
import { PDFEngines } from
|
|
689
|
+
import { PDFEngines } from 'chromiumly';
|
|
582
690
|
|
|
583
691
|
const rotated = await PDFEngines.rotate({
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
692
|
+
files: ['path/to/document.pdf'],
|
|
693
|
+
angle: 90,
|
|
694
|
+
pages: '1-3' // optional; omit for all pages
|
|
587
695
|
});
|
|
588
696
|
```
|
|
589
697
|
|
|
@@ -592,24 +700,24 @@ const rotated = await PDFEngines.rotate({
|
|
|
592
700
|
These methods call [`/forms/pdfengines/watermark`](https://gotenberg.dev/docs/manipulate-pdfs/watermark-pdfs) and [`/forms/pdfengines/stamp`](https://gotenberg.dev/docs/manipulate-pdfs/stamp-pdfs).
|
|
593
701
|
|
|
594
702
|
```typescript
|
|
595
|
-
import { PDFEngines } from
|
|
703
|
+
import { PDFEngines } from 'chromiumly';
|
|
596
704
|
|
|
597
705
|
const watermarked = await PDFEngines.watermark({
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
706
|
+
files: ['path/to/document.pdf'],
|
|
707
|
+
watermark: {
|
|
708
|
+
source: 'text',
|
|
709
|
+
expression: 'CONFIDENTIAL',
|
|
710
|
+
options: { opacity: 0.25, rotation: 45 }
|
|
711
|
+
}
|
|
604
712
|
});
|
|
605
713
|
|
|
606
714
|
const stamped = await PDFEngines.stamp({
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
715
|
+
files: ['path/to/document.pdf'],
|
|
716
|
+
stamp: {
|
|
717
|
+
source: 'text',
|
|
718
|
+
expression: 'APPROVED',
|
|
719
|
+
options: { opacity: 0.5, rotation: 0 }
|
|
720
|
+
}
|
|
613
721
|
});
|
|
614
722
|
```
|
|
615
723
|
|
|
@@ -620,12 +728,12 @@ const stamped = await PDFEngines.stamp({
|
|
|
620
728
|
This method reads metadata from the provided PDF files.
|
|
621
729
|
|
|
622
730
|
```typescript
|
|
623
|
-
import { PDFEngines } from
|
|
731
|
+
import { PDFEngines } from 'chromiumly';
|
|
624
732
|
|
|
625
|
-
const metadataBuffer = await PDFEngines.readMetadata(
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
733
|
+
const metadataBuffer = await PDFEngines.readMetadata({
|
|
734
|
+
files: ['path/to/file_1.pdf'],
|
|
735
|
+
downloadFrom: [{ url: 'https://cdn.example.com/file.pdf' }] // optional: read metadata from a remote PDF
|
|
736
|
+
});
|
|
629
737
|
```
|
|
630
738
|
|
|
631
739
|
##### writeMetadata
|
|
@@ -633,15 +741,15 @@ const metadataBuffer = await PDFEngines.readMetadata([
|
|
|
633
741
|
This method writes metadata to the provided PDF files.
|
|
634
742
|
|
|
635
743
|
```typescript
|
|
636
|
-
import { PDFEngines } from
|
|
744
|
+
import { PDFEngines } from 'chromiumly';
|
|
637
745
|
|
|
638
746
|
const buffer = await PDFEngines.writeMetadata({
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
747
|
+
files: ['path/to/file_1.pdf', 'path/to/file_2.pdf'],
|
|
748
|
+
metadata: {
|
|
749
|
+
Author: 'Taha Cherfia',
|
|
750
|
+
Title: 'Chromiumly',
|
|
751
|
+
Keywords: ['pdf', 'html', 'gotenberg']
|
|
752
|
+
}
|
|
645
753
|
});
|
|
646
754
|
```
|
|
647
755
|
|
|
@@ -654,11 +762,11 @@ Please consider referring to [ExifTool](https://exiftool.org/TagNames/XMP.html#p
|
|
|
654
762
|
This method reads bookmarks (outline / table of contents) from the provided PDF files.
|
|
655
763
|
|
|
656
764
|
```typescript
|
|
657
|
-
import { PDFEngines } from
|
|
765
|
+
import { PDFEngines } from 'chromiumly';
|
|
658
766
|
|
|
659
767
|
const bookmarks = await PDFEngines.readBookmarks([
|
|
660
|
-
|
|
661
|
-
|
|
768
|
+
'path/to/file_1.pdf',
|
|
769
|
+
'path/to/file_2.pdf'
|
|
662
770
|
]);
|
|
663
771
|
```
|
|
664
772
|
|
|
@@ -667,20 +775,78 @@ const bookmarks = await PDFEngines.readBookmarks([
|
|
|
667
775
|
This method writes bookmarks to the provided PDF files.
|
|
668
776
|
|
|
669
777
|
```typescript
|
|
670
|
-
import { PDFEngines } from
|
|
778
|
+
import { PDFEngines } from 'chromiumly';
|
|
671
779
|
|
|
672
780
|
const updated = await PDFEngines.writeBookmarks({
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
781
|
+
files: ['path/to/file_1.pdf'],
|
|
782
|
+
bookmarks: [
|
|
783
|
+
{
|
|
784
|
+
title: 'Chapter 1',
|
|
785
|
+
page: 1,
|
|
786
|
+
children: []
|
|
787
|
+
}
|
|
788
|
+
]
|
|
789
|
+
});
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
#### Encryption (dedicated route)
|
|
793
|
+
|
|
794
|
+
`PDFEngines.encrypt()` calls Gotenberg's [encrypt route](https://gotenberg.dev/docs/manipulate-pdfs/encrypt-pdfs) to encrypt existing PDFs directly, without going through a conversion. At least one of `userPassword` or `ownerPassword` is required; since Gotenberg 8.34.0, an owner-password-only request produces an owner-only PDF that opens without a password but still enforces the given permissions.
|
|
795
|
+
|
|
796
|
+
```typescript
|
|
797
|
+
import { PDFEngines } from 'chromiumly';
|
|
798
|
+
|
|
799
|
+
const encrypted = await PDFEngines.encrypt({
|
|
800
|
+
files: ['path/to/document.pdf'],
|
|
801
|
+
options: {
|
|
802
|
+
userPassword: 'my_user_password',
|
|
803
|
+
ownerPassword: 'my_owner_password',
|
|
804
|
+
allowPrinting: false,
|
|
805
|
+
allowCopying: false
|
|
806
|
+
}
|
|
807
|
+
});
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
See [PDF Encryption](#pdf-encryption) and [PDF Permissions](#pdf-permissions) for the full set of encryption and permission fields, also available on Chromium and LibreOffice `convert()`, and on `PDFEngines.merge()`/`PDFEngines.split()`.
|
|
811
|
+
|
|
812
|
+
#### Embedding Files (dedicated route)
|
|
813
|
+
|
|
814
|
+
`PDFEngines.embed()` calls Gotenberg's [embed route](https://gotenberg.dev/docs/manipulate-pdfs/attachments) to attach files to existing PDFs directly, without going through a conversion.
|
|
815
|
+
|
|
816
|
+
```typescript
|
|
817
|
+
import { PDFEngines } from 'chromiumly';
|
|
818
|
+
|
|
819
|
+
const embedded = await PDFEngines.embed({
|
|
820
|
+
files: ['path/to/document.pdf'],
|
|
821
|
+
embeds: ['path/to/invoice.xml', 'path/to/logo.png'],
|
|
822
|
+
embedsMetadata: {
|
|
823
|
+
'invoice.xml': { mimeType: 'text/xml', relationship: 'Data' }
|
|
824
|
+
}
|
|
681
825
|
});
|
|
682
826
|
```
|
|
683
827
|
|
|
828
|
+
See [Embedding Files](#embedding-files) for the `embedsMetadata` shape, also available on Chromium and LibreOffice `convert()`.
|
|
829
|
+
|
|
830
|
+
#### Factur-X / ZUGFeRD (dedicated route)
|
|
831
|
+
|
|
832
|
+
`PDFEngines.facturX()` calls Gotenberg's [Factur-X route](https://gotenberg.dev/docs/manipulate-pdfs/factur-x) to turn existing PDFs into Factur-X / ZUGFeRD e-invoices directly, without going through a conversion: it embeds the CII invoice XML under the canonical `factur-x.xml` name and converts the PDF to PDF/A-3.
|
|
833
|
+
|
|
834
|
+
```typescript
|
|
835
|
+
import { PDFEngines } from 'chromiumly';
|
|
836
|
+
|
|
837
|
+
const invoice = await PDFEngines.facturX({
|
|
838
|
+
files: ['path/to/document.pdf'],
|
|
839
|
+
facturx: {
|
|
840
|
+
facturxXml: 'path/to/invoice.xml',
|
|
841
|
+
facturxConformanceLevel: 'EN 16931',
|
|
842
|
+
facturxDocumentType: 'INVOICE', // optional, defaults to 'INVOICE'
|
|
843
|
+
facturxVersion: '1.0' // optional, defaults to '1.0'
|
|
844
|
+
}
|
|
845
|
+
});
|
|
846
|
+
```
|
|
847
|
+
|
|
848
|
+
See [Factur-X / ZUGFeRD](#factur-x--zugferd) for the full `facturx` field shape, also available on Chromium and LibreOffice `convert()`.
|
|
849
|
+
|
|
684
850
|
#### File Generation
|
|
685
851
|
|
|
686
852
|
It is just a generic complementary method that takes the `buffer` returned by the `convert` method, and a
|
|
@@ -690,41 +856,46 @@ Please note that all the PDF files can be found `__generated__` folder in the ro
|
|
|
690
856
|
|
|
691
857
|
### PDF Splitting
|
|
692
858
|
|
|
693
|
-
Each [Chromium](#chromium) and [LibreOffice](#libreoffice) route has a `split` parameter that allows splitting the PDF
|
|
859
|
+
Each [Chromium](#chromium) and [LibreOffice](#libreoffice) route has a `split` parameter (type `ConvertSplit`) that allows splitting the resulting PDF into multiple files:
|
|
694
860
|
|
|
695
861
|
- `mode`: the mode of the split. It can be `pages` or `intervals`.
|
|
696
862
|
- `span`: the span of the split. It is a string that represents the range of pages to split.
|
|
697
863
|
- `unify`: a boolean that allows unifying the split files. Only works when `mode` is `pages`.
|
|
698
|
-
|
|
864
|
+
|
|
865
|
+
Note that `flatten` is a separate top-level parameter on these routes (see [PDF Flattening](#pdf-flattening)), not part of `split` itself.
|
|
699
866
|
|
|
700
867
|
```typescript
|
|
701
|
-
import { UrlConverter } from
|
|
868
|
+
import { UrlConverter } from 'chromiumly';
|
|
702
869
|
const buffer = await UrlConverter.convert({
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
870
|
+
url: 'https://www.example.com/',
|
|
871
|
+
split: {
|
|
872
|
+
mode: 'pages',
|
|
873
|
+
span: '1-2',
|
|
874
|
+
unify: true
|
|
875
|
+
}
|
|
709
876
|
});
|
|
710
877
|
```
|
|
711
878
|
|
|
712
|
-
On the other hand, PDFEngines' has a `split` method that interacts with [PDF Engines](https://gotenberg.dev/docs/manipulate-pdfs/split-pdfs) split route which splits PDF files into multiple files.
|
|
879
|
+
On the other hand, PDFEngines' has a `split` method that interacts with [PDF Engines](https://gotenberg.dev/docs/manipulate-pdfs/split-pdfs) split route which splits PDF files into multiple files. Here, `options.flatten` is part of the split configuration itself, rather than a separate top-level field:
|
|
713
880
|
|
|
714
881
|
```typescript
|
|
715
|
-
import { PDFEngines } from
|
|
882
|
+
import { PDFEngines } from 'chromiumly';
|
|
716
883
|
|
|
717
884
|
const buffer = await PDFEngines.split({
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
885
|
+
files: ['path/to/file_1.pdf', 'path/to/file_2.pdf'],
|
|
886
|
+
options: {
|
|
887
|
+
mode: 'pages',
|
|
888
|
+
span: '1-2',
|
|
889
|
+
unify: true,
|
|
890
|
+
flatten: true
|
|
891
|
+
},
|
|
892
|
+
metadata: { Author: 'Taha Cherfia' },
|
|
893
|
+
pdfa: PdfFormat.A_2b,
|
|
894
|
+
userPassword: 'my_user_password'
|
|
724
895
|
});
|
|
725
896
|
```
|
|
726
897
|
|
|
727
|
-
`PDFEngines.split` also accepts optional `watermark`, `stamp`, and `rotate` for the same PDF-engine post-processing as merge.
|
|
898
|
+
`PDFEngines.split` also accepts optional `metadata`, `pdfa`/`pdfUA`, `userPassword`/`ownerPassword` and the six permission booleans (see [PDF Permissions](#pdf-permissions)), and `watermark`, `stamp`, and `rotate` for the same PDF-engine post-processing as merge.
|
|
728
899
|
|
|
729
900
|
> ⚠️ **Note**: Gotenberg does not currently validate the `span` value when `mode` is set to `pages`, as the validation depends on the chosen engine for the split feature. See [PDF Engines module configuration](https://gotenberg.dev/docs/configuration#pdf-engines) for more details.
|
|
730
901
|
|
|
@@ -733,28 +904,58 @@ const buffer = await PDFEngines.split({
|
|
|
733
904
|
PDF flattening converts interactive elements like forms and annotations into a static PDF. This ensures the document looks the same everywhere and prevents further edits.
|
|
734
905
|
|
|
735
906
|
```typescript
|
|
736
|
-
import { PDFEngines } from
|
|
907
|
+
import { PDFEngines } from 'chromiumly';
|
|
737
908
|
|
|
738
909
|
const buffer = await PDFEngines.flatten([
|
|
739
|
-
|
|
740
|
-
|
|
910
|
+
'path/to/file_1.pdf',
|
|
911
|
+
'path/to/file_2.pdf'
|
|
741
912
|
]);
|
|
742
913
|
```
|
|
743
914
|
|
|
744
915
|
### PDF Encryption
|
|
745
916
|
|
|
746
|
-
Each [Chromium](#chromium) and [LibreOffice](#libreoffice) route supports PDF encryption through the `userPassword` and `ownerPassword` parameters. The `userPassword` is required to open the PDF, while the `ownerPassword` provides full access permissions.
|
|
917
|
+
Each [Chromium](#chromium) and [LibreOffice](#libreoffice) route, as well as `PDFEngines.merge()` and `PDFEngines.split()`, supports PDF encryption through the `userPassword` and `ownerPassword` parameters. The `userPassword` is required to open the PDF, while the `ownerPassword` provides full access permissions.
|
|
747
918
|
|
|
748
919
|
```typescript
|
|
749
|
-
import { UrlConverter } from
|
|
920
|
+
import { UrlConverter } from 'chromiumly';
|
|
750
921
|
|
|
751
922
|
const buffer = await UrlConverter.convert({
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
923
|
+
url: 'https://www.example.com/',
|
|
924
|
+
userPassword: 'my_user_password',
|
|
925
|
+
ownerPassword: 'my_owner_password'
|
|
755
926
|
});
|
|
756
927
|
```
|
|
757
928
|
|
|
929
|
+
There's also a dedicated `PDFEngines.encrypt()` route for encrypting existing PDFs directly — see [Encryption (dedicated route)](#encryption-dedicated-route). Unlike the routes above, it requires at least one of `userPassword` or `ownerPassword`, and (since Gotenberg 8.34.0) allows an owner-password-only PDF that opens without a password but still enforces permissions.
|
|
930
|
+
|
|
931
|
+
### PDF Permissions
|
|
932
|
+
|
|
933
|
+
Each route in [PDF Encryption](#pdf-encryption) above also accepts six permission booleans, all defaulting to `true`:
|
|
934
|
+
|
|
935
|
+
```typescript
|
|
936
|
+
type PdfEnginePermissions = {
|
|
937
|
+
allowPrinting?: boolean; // Allow printing the document
|
|
938
|
+
allowCopying?: boolean; // Allow copying content from the document
|
|
939
|
+
allowModifying?: boolean; // Allow modifying the document
|
|
940
|
+
allowAnnotating?: boolean; // Allow adding or modifying annotations
|
|
941
|
+
allowFillingForms?: boolean; // Allow filling in form fields
|
|
942
|
+
allowAssembling?: boolean; // Allow document assembly, e.g. inserting, deleting, or rotating pages
|
|
943
|
+
};
|
|
944
|
+
```
|
|
945
|
+
|
|
946
|
+
```typescript
|
|
947
|
+
import { UrlConverter } from 'chromiumly';
|
|
948
|
+
|
|
949
|
+
const buffer = await UrlConverter.convert({
|
|
950
|
+
url: 'https://www.example.com/',
|
|
951
|
+
ownerPassword: 'my_owner_password',
|
|
952
|
+
allowPrinting: false,
|
|
953
|
+
allowCopying: false
|
|
954
|
+
});
|
|
955
|
+
```
|
|
956
|
+
|
|
957
|
+
Permission enforcement depends on the active PDF engine: QPDF honors each permission individually, pdfcpu restricts all permissions if any one is denied, and PDFtk supports neither owner-only encryption nor permission restrictions. Restrictions are advisory: PDF viewers honor them, but they aren't cryptographically enforced once the document opens.
|
|
958
|
+
|
|
758
959
|
### Embedding Files
|
|
759
960
|
|
|
760
961
|
Each [Chromium](#chromium) and [LibreOffice](#libreoffice) route supports embedding files into the generated PDF through the `embeds` parameter. This feature enables the creation of PDFs compatible with standards like [ZUGFeRD / Factur-X](https://fnfe-mpe.org/factur-x/), which require embedding XML invoices and other files within the PDF.
|
|
@@ -762,21 +963,115 @@ Each [Chromium](#chromium) and [LibreOffice](#libreoffice) route supports embedd
|
|
|
762
963
|
You can embed multiple files by passing an array of file paths, buffers, or read streams:
|
|
763
964
|
|
|
764
965
|
```typescript
|
|
765
|
-
import { HtmlConverter } from
|
|
966
|
+
import { HtmlConverter } from 'chromiumly';
|
|
766
967
|
|
|
767
968
|
const htmlConverter = new HtmlConverter();
|
|
768
969
|
const buffer = await htmlConverter.convert({
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
970
|
+
html: 'path/to/index.html',
|
|
971
|
+
embeds: [
|
|
972
|
+
'path/to/invoice.xml',
|
|
973
|
+
'path/to/logo.png',
|
|
974
|
+
Buffer.from('additional data')
|
|
975
|
+
]
|
|
775
976
|
});
|
|
776
977
|
```
|
|
777
978
|
|
|
778
979
|
All embedded files will be attached to the generated PDF and can be extracted using PDF readers that support file attachments.
|
|
779
980
|
|
|
981
|
+
Optional `embedsMetadata` sets per-attachment metadata, keyed by filename, required for PDF/A-3 and Factur-X compliance:
|
|
982
|
+
|
|
983
|
+
```typescript
|
|
984
|
+
type EmbedsMetadata = Record<
|
|
985
|
+
string, // filename, matching an entry in `embeds`
|
|
986
|
+
{
|
|
987
|
+
mimeType?: string; // Written to the embedded file stream's /Subtype
|
|
988
|
+
relationship?:
|
|
989
|
+
| 'Source'
|
|
990
|
+
| 'Data'
|
|
991
|
+
| 'Alternative'
|
|
992
|
+
| 'Supplement'
|
|
993
|
+
| 'Unspecified'; // The /AFRelationship value
|
|
994
|
+
}
|
|
995
|
+
>;
|
|
996
|
+
```
|
|
997
|
+
|
|
998
|
+
```typescript
|
|
999
|
+
const buffer = await htmlConverter.convert({
|
|
1000
|
+
html: 'path/to/index.html',
|
|
1001
|
+
embeds: ['path/to/invoice.xml'],
|
|
1002
|
+
embedsMetadata: {
|
|
1003
|
+
'invoice.xml': { mimeType: 'text/xml', relationship: 'Data' }
|
|
1004
|
+
}
|
|
1005
|
+
});
|
|
1006
|
+
```
|
|
1007
|
+
|
|
1008
|
+
There's also a dedicated `PDFEngines.embed()` route for attaching files to existing PDFs directly — see [Embedding Files (dedicated route)](#embedding-files-dedicated-route).
|
|
1009
|
+
|
|
1010
|
+
### Factur-X / ZUGFeRD
|
|
1011
|
+
|
|
1012
|
+
Each [Chromium](#chromium) and [LibreOffice](#libreoffice) route supports turning the resulting PDF into a [Factur-X / ZUGFeRD](https://fnfe-mpe.org/factur-x/) e-invoice through the `facturx` parameter, which embeds the CII invoice XML under the canonical `factur-x.xml` name and converts the PDF to PDF/A-3:
|
|
1013
|
+
|
|
1014
|
+
```typescript
|
|
1015
|
+
type FacturXOptions = {
|
|
1016
|
+
facturxXml: PathLikeOrReadStream; // The Factur-X CII invoice XML; embedded as factur-x.xml regardless of the given filename.
|
|
1017
|
+
facturxConformanceLevel:
|
|
1018
|
+
| 'MINIMUM'
|
|
1019
|
+
| 'BASIC WL'
|
|
1020
|
+
| 'BASIC'
|
|
1021
|
+
| 'EN 16931'
|
|
1022
|
+
| 'EXTENDED'
|
|
1023
|
+
| 'XRECHNUNG';
|
|
1024
|
+
facturxDocumentType?: 'INVOICE' | 'ORDER' | 'ORDER_RESPONSE' | 'ORDER_CHANGE'; // Defaults to 'INVOICE'.
|
|
1025
|
+
facturxVersion?: string; // Defaults to '1.0'.
|
|
1026
|
+
pdfa?: 'PDF/A-3a' | 'PDF/A-3b' | 'PDF/A-3u';
|
|
1027
|
+
pdfUA?: boolean;
|
|
1028
|
+
};
|
|
1029
|
+
```
|
|
1030
|
+
|
|
1031
|
+
```typescript
|
|
1032
|
+
import { HtmlConverter } from 'chromiumly';
|
|
1033
|
+
|
|
1034
|
+
const htmlConverter = new HtmlConverter();
|
|
1035
|
+
const buffer = await htmlConverter.convert({
|
|
1036
|
+
html: 'path/to/index.html',
|
|
1037
|
+
facturx: {
|
|
1038
|
+
facturxXml: 'path/to/invoice.xml',
|
|
1039
|
+
facturxConformanceLevel: 'EN 16931'
|
|
1040
|
+
}
|
|
1041
|
+
});
|
|
1042
|
+
```
|
|
1043
|
+
|
|
1044
|
+
There's also a dedicated `PDFEngines.facturX()` route for turning existing PDFs into Factur-X e-invoices directly — see [Factur-X / ZUGFeRD (dedicated route)](#factur-x--zugferd-dedicated-route).
|
|
1045
|
+
|
|
1046
|
+
### Output Filename and Request Tracing
|
|
1047
|
+
|
|
1048
|
+
Every route accepts optional `outputFilename` and `trace` parameters, mapping to the `Gotenberg-Output-Filename` and `Gotenberg-Trace` request headers:
|
|
1049
|
+
|
|
1050
|
+
```typescript
|
|
1051
|
+
type OutputOptions = {
|
|
1052
|
+
outputFilename?: string; // Custom filename for the resulting file; Gotenberg appends the extension.
|
|
1053
|
+
trace?: string; // Custom request id to identify the request in the logs, overriding the generated UUID.
|
|
1054
|
+
};
|
|
1055
|
+
```
|
|
1056
|
+
|
|
1057
|
+
```typescript
|
|
1058
|
+
import { UrlConverter } from 'chromiumly';
|
|
1059
|
+
|
|
1060
|
+
const buffer = await UrlConverter.convert({
|
|
1061
|
+
url: 'https://www.example.com/',
|
|
1062
|
+
outputFilename: 'my-document',
|
|
1063
|
+
trace: 'my-correlation-id'
|
|
1064
|
+
});
|
|
1065
|
+
```
|
|
1066
|
+
|
|
1067
|
+
The [System](#system) routes accept `trace` too (there's no resulting file, so no `outputFilename`):
|
|
1068
|
+
|
|
1069
|
+
```typescript
|
|
1070
|
+
import { System } from 'chromiumly';
|
|
1071
|
+
|
|
1072
|
+
const health = await System.getHealth('my-correlation-id');
|
|
1073
|
+
```
|
|
1074
|
+
|
|
780
1075
|
### Templates (hosted API only)
|
|
781
1076
|
|
|
782
1077
|
The `Templates` class is **not** part of open‑source Gotenberg. It generates PDFs from structured payloads on the Chromiumly hosted API and **requires `CHROMIUMLY_API_KEY`**. Hosted API features (including `Templates`) were introduced in `chromiumly@5.0.0` and require Chromiumly `5.0.0+`—pointing Chromiumly at `GOTENBERG_ENDPOINT` (self‑hosted Gotenberg) will not enable this feature.
|
|
@@ -794,48 +1089,48 @@ The following template types are currently available:
|
|
|
794
1089
|
#### Basic Usage
|
|
795
1090
|
|
|
796
1091
|
```typescript
|
|
797
|
-
import { Templates } from
|
|
1092
|
+
import { Templates } from 'chromiumly';
|
|
798
1093
|
|
|
799
1094
|
const templates = new Templates();
|
|
800
1095
|
const buffer = await templates.generate({
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
1096
|
+
type: 'invoice_saas',
|
|
1097
|
+
data: {
|
|
1098
|
+
invoiceNumber: 'INV-319',
|
|
1099
|
+
createdDate: '2026-03-19',
|
|
1100
|
+
dueDate: '2026-04-02',
|
|
1101
|
+
companyLogo: 'https://cdn.acmecloud.com/assets/logo-mark.png',
|
|
1102
|
+
sender: {
|
|
1103
|
+
name: 'Acme Cloud LLC',
|
|
1104
|
+
addressLine1: '450 Madison Ave',
|
|
1105
|
+
addressLine2: 'New York, NY 10022'
|
|
1106
|
+
},
|
|
1107
|
+
receiver: {
|
|
1108
|
+
name: 'Northwind Health Inc.',
|
|
1109
|
+
addressLine1: '221 Harbor Blvd',
|
|
1110
|
+
addressLine2: 'San Diego, CA 92101'
|
|
1111
|
+
},
|
|
1112
|
+
items: [
|
|
1113
|
+
{
|
|
1114
|
+
description: 'Platform Subscription (Annual)',
|
|
1115
|
+
qty: 1,
|
|
1116
|
+
unitPrice: '1500.00',
|
|
1117
|
+
amount: '1500.00'
|
|
1118
|
+
},
|
|
1119
|
+
{
|
|
1120
|
+
description: 'Onboarding',
|
|
1121
|
+
qty: 1,
|
|
1122
|
+
unitPrice: '300.00',
|
|
1123
|
+
amount: '300.00'
|
|
1124
|
+
}
|
|
1125
|
+
],
|
|
1126
|
+
currency: 'USD',
|
|
1127
|
+
subTotal: '1800.00',
|
|
1128
|
+
taxRate: 8.25,
|
|
1129
|
+
taxAmount: '148.50',
|
|
1130
|
+
total: '1948.50',
|
|
1131
|
+
footerNote: 'Payment due in 14 days.',
|
|
1132
|
+
footerDisclaimer: 'Late fees may apply.'
|
|
1133
|
+
}
|
|
839
1134
|
});
|
|
840
1135
|
```
|
|
841
1136
|
|
|
@@ -851,44 +1146,52 @@ const buffer = await templates.generate(request, { validate: true });
|
|
|
851
1146
|
|
|
852
1147
|
```typescript
|
|
853
1148
|
type TemplateRequest<TType extends TemplateType> = {
|
|
854
|
-
|
|
855
|
-
|
|
1149
|
+
type: TType;
|
|
1150
|
+
data: TemplateDataByType[TType];
|
|
856
1151
|
};
|
|
857
1152
|
|
|
858
1153
|
interface InvoiceSaasTemplateData {
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
1154
|
+
invoiceNumber: string;
|
|
1155
|
+
createdDate: string;
|
|
1156
|
+
dueDate: string;
|
|
1157
|
+
companyLogo?: string;
|
|
1158
|
+
sender: TemplateParty;
|
|
1159
|
+
receiver: TemplateParty;
|
|
1160
|
+
items: InvoiceItem[];
|
|
1161
|
+
currency: Currency;
|
|
1162
|
+
subTotal: string;
|
|
1163
|
+
taxRate: number;
|
|
1164
|
+
taxAmount: string;
|
|
1165
|
+
total: string;
|
|
1166
|
+
footerNote: string;
|
|
1167
|
+
footerDisclaimer?: string;
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
// invoice_classic uses this variant instead, where companyLogo is required.
|
|
1171
|
+
interface InvoiceClassicTemplateData
|
|
1172
|
+
extends Omit<InvoiceSaasTemplateData, 'companyLogo'> {
|
|
1173
|
+
companyLogo: string;
|
|
873
1174
|
}
|
|
874
1175
|
|
|
875
1176
|
interface TemplateParty {
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
1177
|
+
name: string;
|
|
1178
|
+
addressLine1: string;
|
|
1179
|
+
addressLine2?: string;
|
|
1180
|
+
tax?: string;
|
|
1181
|
+
iban?: string;
|
|
1182
|
+
bic?: string;
|
|
882
1183
|
}
|
|
883
1184
|
|
|
884
1185
|
interface InvoiceItem {
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
1186
|
+
description: string;
|
|
1187
|
+
qty: number;
|
|
1188
|
+
unitPrice: string;
|
|
1189
|
+
amount: string;
|
|
889
1190
|
}
|
|
890
1191
|
```
|
|
891
1192
|
|
|
1193
|
+
`invoice_saas`, `invoice_freelancer`, `invoice_minimal`, and `invoice_modern` all use `InvoiceSaasTemplateData`; `invoice_classic` uses `InvoiceClassicTemplateData`, the only variant where `companyLogo` is required.
|
|
1194
|
+
|
|
892
1195
|
The `currency` field accepts any [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code exported as the `Currency` type (e.g. `"USD"`, `"EUR"`, `"GBP"`).
|
|
893
1196
|
|
|
894
1197
|
### Watermark and stamp
|
|
@@ -907,16 +1210,17 @@ For image or PDF sources, set `source` to `image` or `pdf`, set `expression` to
|
|
|
907
1210
|
|
|
908
1211
|
### System
|
|
909
1212
|
|
|
910
|
-
The `System` class exposes Gotenberg system endpoints:
|
|
1213
|
+
The `System` class exposes Gotenberg system endpoints. Every method accepts an optional `trace` argument (custom request id, mapped to the `Gotenberg-Trace` header — see [Output Filename and Request Tracing](#output-filename-and-request-tracing)):
|
|
911
1214
|
|
|
912
1215
|
```typescript
|
|
913
|
-
import { System } from
|
|
1216
|
+
import { System } from 'chromiumly';
|
|
914
1217
|
|
|
915
1218
|
const health = await System.getHealth(); // GET /health
|
|
916
1219
|
const heartbeat = await System.headHealth(); // HEAD /health
|
|
917
1220
|
const version = await System.getVersion(); // GET /version
|
|
918
1221
|
const debug = await System.getDebug(); // GET /debug
|
|
919
1222
|
const metrics = await System.getPrometheusMetrics(); // GET /prometheus/metrics
|
|
1223
|
+
const tracedHealth = await System.getHealth('my-correlation-id');
|
|
920
1224
|
```
|
|
921
1225
|
|
|
922
1226
|
## Snippet
|
|
@@ -924,37 +1228,36 @@ const metrics = await System.getPrometheusMetrics(); // GET /prometheus/metrics
|
|
|
924
1228
|
The following is a short snippet of how to use the library.
|
|
925
1229
|
|
|
926
1230
|
```typescript
|
|
927
|
-
import { PDFEngines, UrlConverter } from
|
|
1231
|
+
import { PDFEngines, UrlConverter } from 'chromiumly';
|
|
928
1232
|
|
|
929
1233
|
async function run() {
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
}
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
await PDFEngines.generate("gotenberg.pdf", buffer);
|
|
1234
|
+
const urlConverter = new UrlConverter();
|
|
1235
|
+
const buffer = await urlConverter.convert({
|
|
1236
|
+
url: 'https://gotenberg.dev/',
|
|
1237
|
+
properties: {
|
|
1238
|
+
singlePage: true,
|
|
1239
|
+
size: {
|
|
1240
|
+
width: 8.5,
|
|
1241
|
+
height: 11
|
|
1242
|
+
}
|
|
1243
|
+
},
|
|
1244
|
+
emulatedMediaType: 'screen',
|
|
1245
|
+
emulatedMediaFeatures: [
|
|
1246
|
+
{ name: 'prefers-color-scheme', value: 'dark' },
|
|
1247
|
+
{ name: 'prefers-reduced-motion', value: 'reduce' }
|
|
1248
|
+
],
|
|
1249
|
+
failOnHttpStatusCodes: [404],
|
|
1250
|
+
failOnConsoleExceptions: true,
|
|
1251
|
+
skipNetworkIdleEvent: false,
|
|
1252
|
+
skipNetworkAlmostIdleEvent: false,
|
|
1253
|
+
split: {
|
|
1254
|
+
mode: 'pages',
|
|
1255
|
+
span: '1-2',
|
|
1256
|
+
unify: true
|
|
1257
|
+
}
|
|
1258
|
+
});
|
|
1259
|
+
|
|
1260
|
+
await PDFEngines.generate('gotenberg.pdf', buffer);
|
|
958
1261
|
}
|
|
959
1262
|
|
|
960
1263
|
run();
|