gotenberg-client 0.0.0 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 zmzlois
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a
6
+ copy of this software and associated documentation files (the "Software"), to
7
+ deal in the Software without restriction, including without limitation the
8
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9
+ sell 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 ADDED
@@ -0,0 +1,454 @@
1
+ # gotenberg-client
2
+
3
+ Typed, promise-based wrapper for [Project Gotenberg](https://gotenberg.dev/).
4
+
5
+ > You will have to deploy your own Gotenberg server to use this package.
6
+
7
+ - Minimal surface: one entrypoint, one initialization model.
8
+ - Strong request typing built from shared interfaces in `src/types.ts`.
9
+ - Every method returns `Result<T, GotenbergError>`.
10
+
11
+ ## Quick Links
12
+
13
+ - [Install](#install)
14
+ - [Prerequisites Environment Variables](#prerequisites-environment-variables)
15
+ - [Initialization](#initialization)
16
+ - [Where Can You Use This Package](#where-can-you-use-this-package)
17
+ - [Shared Input Types](#shared-input-types)
18
+ - [Response Model](#response-model)
19
+ - [Health and Version](#health-and-version)
20
+ - [Checking service health](#checking-service-health)
21
+ - [Reading server version](#reading-server-version)
22
+ - [Chromium to PDF](#chromium-to-pdf)
23
+ - [Converting URL to PDF](#converting-url-to-pdf)
24
+ - [Converting HTML to PDF](#converting-html-to-pdf)
25
+ - [Converting Markdown to PDF](#converting-markdown-to-pdf)
26
+ - [Chromium to Image](#chromium-to-image)
27
+ - [Taking URL screenshots](#taking-url-screenshots)
28
+ - [Taking HTML screenshots](#taking-html-screenshots)
29
+ - [Taking Markdown screenshots](#taking-markdown-screenshots)
30
+ - [Converting PDF to Images](#converting-pdf-to-images)
31
+ - [LibreOffice](#libreoffice)
32
+ - [Converting Office documents to PDF](#converting-office-documents-to-pdf)
33
+ - [Converting Excel to PDF](#converting-excel-to-pdf)
34
+ - [Converting Word to PDF](#converting-word-to-pdf)
35
+ - [PDF Operations](#pdf-operations)
36
+ - [Merging PDFs](#merging-pdfs)
37
+ - [Splitting PDFs](#splitting-pdfs)
38
+ - [Flattening PDFs](#flattening-pdfs)
39
+ - [Encrypting PDFs](#encrypting-pdfs)
40
+ - [Embedding files in PDFs](#embedding-files-in-pdfs)
41
+ - [Reading PDF metadata](#reading-pdf-metadata)
42
+ - [Writing PDF metadata](#writing-pdf-metadata)
43
+ - [Converting to PDF/A](#converting-to-pdfa)
44
+ - [Error Handling](#error-handling)
45
+ - [Development](#development)
46
+ - [Deploy Your Own Gotenberg Server](#deploy-your-own-gotenberg-server)
47
+
48
+ ## Install
49
+
50
+ ```bash
51
+ npm i gotenberg-client
52
+ ```
53
+
54
+ ```bash
55
+ bun add gotenberg-client
56
+ ```
57
+
58
+ ```bash
59
+ pnpm add gotenberg-client
60
+ ```
61
+
62
+ ## Prerequisites Environment Variables
63
+
64
+ `new Gotenberg()` reads required values from environment variables on construction:
65
+
66
+ - `GOTENBERG_URL`
67
+ - `GOTENBERG_API_BASIC_AUTH_USERNAME`
68
+ - `GOTENBERG_API_BASIC_AUTH_PASSWORD`
69
+
70
+ If any are missing, constructor will throw.
71
+
72
+ ## Initialization
73
+
74
+
75
+ ```ts
76
+ import { Gotenberg } from "gotenberg-client";
77
+
78
+ const gotenberg = new Gotenberg({
79
+ logger: {
80
+ error: (message, meta) => console.error(message, meta),
81
+ warn: (message, meta) => console.warn(message, meta),
82
+ },
83
+ });
84
+ ```
85
+
86
+ Optional logger and limiter are available via `GotenbergOptions`.
87
+
88
+ ## Where Can You Use This Package?
89
+
90
+ This package is built for server-side runtime usage:
91
+
92
+ - Node.js and Bun services
93
+ - serverless functions (if Gotenberg endpoint is accessible)
94
+ - background workers and CLI scripts
95
+ - SSR handlers (for example, Next.js API routes, Nuxt server handlers)
96
+
97
+ It is not intended for browser/client-side frontends because:
98
+
99
+ - credentials are read from environment variables on the server
100
+ - exposing shared secrets in a bundle is unsafe
101
+ - CORS, auth, and network constraints are usually unsuitable for direct browser calls
102
+
103
+ For browser products, call this package from your backend and expose a controlled API to the UI.
104
+
105
+ ### Compatibility Matrix
106
+
107
+ | Runtime | Recommended minimum | `fetch` support | Compatibility notes |
108
+ | --- | --- | --- | --- |
109
+ | **Node.js** | `18+` | Built-in | Recommended runtime. Native `fetch`, `Blob`, `FormData`, `AbortController`, `Headers`, `Request`, and `Response` are available. |
110
+ | **Node.js** | `16.x` (legacy) | Requires polyfill | Use `undici` (or equivalent) to provide global `fetch`, `Request`, `Response`, `Headers`, and streaming body support. |
111
+ | **Bun** | `1.0+` | Built-in | Fully supported with current package APIs. |
112
+ | **Cloudflare Workers / edge runtimes** | Runtime-dependent | Usually built-in | Possible but not officially tested. Ensure runtime provides `fetch` and stream-compatible multipart/form data behavior. |
113
+ | **Browser** | — | Usually built-in | Not recommended for this package because credentials are environment-driven and intended for private/backend use. |
114
+
115
+ ### Runtime Requirements At A Glance
116
+
117
+ - Works best in environments with modern web-fetch globals.
118
+ - If global `fetch` is missing, provide a polyfill before constructing `new Gotenberg()`.
119
+ - In browsers, avoid using env-based credentials directly; add a server proxy instead.
120
+
121
+ ## Shared Input Types
122
+
123
+ Code: type definitions live in [`src/types.ts`](./src/types.ts).
124
+
125
+ Use `GotenbergFile` for any upload field:
126
+
127
+ ```ts
128
+ import type { GotenbergFile } from "gotenberg-client";
129
+
130
+ const index: GotenbergFile = {
131
+ name: "document.docx",
132
+ data: await Bun.file("document.docx").arrayBuffer(),
133
+ contentType:
134
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
135
+ };
136
+ ```
137
+
138
+ ## Response
139
+
140
+ Each method returns:
141
+
142
+ ```ts
143
+ type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };
144
+ ```
145
+
146
+ On success, binary methods return:
147
+
148
+ ```ts
149
+ {
150
+ blob: Blob;
151
+ filename: string | null;
152
+ contentType: string | null;
153
+ trace: string | null;
154
+ }
155
+ ```
156
+
157
+ On failure, inspect `error.type` (`config`, `network`, `http`, `invalid-response`).
158
+
159
+ ## Health and Version
160
+
161
+ ### Checking service health
162
+
163
+ #### `health(signal?)`
164
+
165
+ Warm-starting worker pipelines or running readiness checks. Avoid sending expensive transformation jobs when Gotenberg server is down.
166
+ ```ts
167
+ const result = await gotenberg.health();
168
+ if (result.ok) {
169
+ console.log(result.value.status); // "up" | "down"
170
+ }
171
+ ```
172
+
173
+ ### Reading server version
174
+
175
+ #### `version(signal?)`
176
+
177
+ Validating server compatibility during deployment or in diagnostics. Helps with support and incident triage when output behavior changes across server versions.
178
+ ```ts
179
+ const result = await gotenberg.version();
180
+ if (result.ok) {
181
+ console.log("Gotenberg:", result.value);
182
+ }
183
+ ```
184
+
185
+ ## Chromium to PDF
186
+
187
+ ### Converting URL to PDF
188
+ Gotenberg handles page loading, rendering, and output as PDF, removing browser automation work from your app.
189
+ #### `urlToPdf(input: ConvertUrlInput)`
190
+
191
+
192
+ ```ts
193
+ const result = await gotenberg.urlToPdf({
194
+ url: "https://example.com",
195
+ options: { printBackground: true },
196
+ });
197
+ ```
198
+
199
+ ### Converting HTML to PDF
200
+
201
+ You can generate HTML from templates in your application and need immediate PDF output and convert dynamic HTML directly without writing temporary files.
202
+
203
+ #### `htmlToPdf(input: ConvertHtmlInput)`
204
+
205
+ ```ts
206
+ const result = await gotenberg.htmlToPdf({
207
+ indexHtml: "<html><body>hello</body></html>",
208
+ options: { singlePage: true },
209
+ });
210
+ ```
211
+
212
+ ### Converting Markdown to PDF
213
+
214
+ #### `markdownToPdf(input: ConvertMarkdownInput)`
215
+
216
+ ```ts
217
+ const result = await gotenberg.markdownToPdf({
218
+ indexHtml: { name: "index.md", data: "# notes", contentType: "text/markdown" },
219
+ markdownFiles: [
220
+ { name: "appendix.md", data: "# appendix", contentType: "text/markdown" },
221
+ ],
222
+ });
223
+ ```
224
+
225
+ ## Chromium to Image
226
+
227
+ ### Taking URL screenshots
228
+
229
+ #### `screenshotUrl(input: ScreenshotUrlInput)`
230
+
231
+
232
+ ```ts
233
+ const result = await gotenberg.screenshotUrl({
234
+ url: "https://example.com",
235
+ options: { format: "png", width: 1280, height: 720 },
236
+ });
237
+ ```
238
+
239
+ ### Taking HTML screenshots
240
+
241
+ #### `screenshotHtml(input: ScreenshotHtmlInput)`
242
+
243
+ ```ts
244
+ const result = await gotenberg.screenshotHtml({
245
+ indexHtml: "<html><body>visual diff</body></html>",
246
+ options: { format: "webp", optimizeForSpeed: true },
247
+ });
248
+ ```
249
+
250
+ ### Taking Markdown screenshots
251
+
252
+ #### `screenshotMarkdown(input: ScreenshotMarkdownInput)`
253
+
254
+ ```ts
255
+ const result = await gotenberg.screenshotMarkdown({
256
+ indexHtml: { name: "index.md", data: "# screenshot", contentType: "text/markdown" },
257
+ markdownFiles: [{ name: "notes.md", data: "# note", contentType: "text/markdown" }],
258
+ });
259
+ ```
260
+
261
+
262
+ ### Converting PDF to Images
263
+
264
+ #### `pdfToImage(input: ScreenshotUrlInput)`
265
+
266
+
267
+ Alias for URL screenshot flow for convenience:
268
+
269
+ ```ts
270
+ const result = await gotenberg.pdfToImage({
271
+ url: "https://example.com/my.pdf",
272
+ options: { format: "png" },
273
+ });
274
+ ```
275
+
276
+
277
+ ## LibreOffice
278
+
279
+ ### Converting Office documents to PDF
280
+
281
+ #### `officeToPdf(input: ConvertOfficeInput)`
282
+
283
+ ```ts
284
+ const result = await gotenberg.officeToPdf({
285
+ files: [{ name: "report.docx", data: await Bun.file("report.docx").arrayBuffer() }],
286
+ });
287
+ ```
288
+
289
+ ### Converting Excel to PDF
290
+
291
+ #### `excelToPdf(input: ConvertOfficeInput)`
292
+
293
+
294
+ ```ts
295
+ const result = await gotenberg.excelToPdf({ files: [/* ... */] });
296
+ ```
297
+
298
+
299
+ ### Converting Word to PDF
300
+
301
+ #### `wordToPdf(input: ConvertOfficeInput)`
302
+
303
+ ```ts
304
+ const result = await gotenberg.wordToPdf({ files: [/* ... */] });
305
+ ```
306
+
307
+ ## PDF Operations
308
+
309
+ ### Merging PDFs
310
+
311
+ #### `mergePdf(input: MergePdfInput)`
312
+
313
+ ```ts
314
+ const result = await gotenberg.mergePdf({
315
+ files: [pdfA, pdfB],
316
+ outputFilename: "merged.pdf",
317
+ });
318
+ ```
319
+
320
+ ### Splitting PDFs
321
+
322
+ #### `splitPdf(input: SplitPdfInput)`
323
+
324
+ ```ts
325
+ const result = await gotenberg.splitPdf({
326
+ files: [pdf],
327
+ splitMode: "pages",
328
+ splitSpan: "1",
329
+ });
330
+ ```
331
+
332
+
333
+ ### Flattening PDFs
334
+
335
+ #### `flattenPdf(input: FlattenPdfInput)`
336
+
337
+ ```ts
338
+ const result = await gotenberg.flattenPdf({
339
+ files: [pdf],
340
+ outputFilename: "flattened.pdf",
341
+ });
342
+ ```
343
+
344
+ ### Encrypting PDFs
345
+
346
+ #### `encryptPdf(input: EncryptPdfInput)`
347
+
348
+ ```ts
349
+ const result = await gotenberg.encryptPdf({
350
+ files: [pdf],
351
+ userPassword: "owner-only",
352
+ });
353
+ ```
354
+
355
+ ### Embedding files in PDFs
356
+
357
+ #### `embedFiles(input: EmbedFilesInput)`
358
+
359
+
360
+ ```ts
361
+ const result = await gotenberg.embedFiles({
362
+ files: [pdf],
363
+ embeds: [overlay],
364
+ outputFilename: "embedded.pdf",
365
+ });
366
+ ```
367
+
368
+
369
+ ### Reading PDF metadata
370
+
371
+ #### `readMetadata(input: ReadMetadataInput)`
372
+
373
+
374
+ ```ts
375
+ const result = await gotenberg.readMetadata({ files: [pdf] });
376
+ if (result.ok) {
377
+ console.log(result.value);
378
+ }
379
+ ```
380
+
381
+
382
+ ### Writing PDF metadata
383
+
384
+ #### `writeMetadata(input: WriteMetadataInput)`
385
+
386
+
387
+ ```ts
388
+ const result = await gotenberg.writeMetadata({
389
+ files: [pdf],
390
+ metadata: { Title: "Quarterly Report", Author: "Ops Team" },
391
+ });
392
+ ```
393
+
394
+
395
+ ### Converting to PDF/A
396
+
397
+ #### `convertToPdfa(input: ConvertToPdfaInput)`
398
+
399
+
400
+ ```ts
401
+ const result = await gotenberg.convertToPdfa({
402
+ files: [pdf],
403
+ pdfa: "PDF/A-2b",
404
+ pdfua: true,
405
+ });
406
+ ```
407
+
408
+ ## Error Handling
409
+
410
+ ```ts
411
+ const result = await gotenberg.version();
412
+ if (!result.ok) {
413
+ const error = result.error;
414
+ console.error(error.type, error.message, error.status, error.trace);
415
+ return;
416
+ }
417
+
418
+ console.log("ready");
419
+ ```
420
+
421
+ ## Development
422
+
423
+ ```bash
424
+ bun install
425
+ bun run format
426
+ bun test
427
+ bun run build
428
+ ```
429
+
430
+
431
+ ## Deploy Your Own Gotenberg Server
432
+
433
+ You must run your own Gotenberg instance and point `GOTENBERG_URL` to it.
434
+
435
+ ### Docker example
436
+
437
+ ```bash
438
+ docker run --rm -p 3000:3000 gotenberg/gotenberg:8
439
+ ```
440
+
441
+ ### Docker with basic auth reverse proxy
442
+
443
+ Use a reverse proxy (for example Nginx, Caddy, Traefik) in front of Gotenberg and enforce basic auth there. Then set:
444
+
445
+ - `GOTENBERG_URL` to proxy URL
446
+ - `GOTENBERG_API_BASIC_AUTH_USERNAME` to proxy username
447
+ - `GOTENBERG_API_BASIC_AUTH_PASSWORD` to proxy password
448
+
449
+ ### Production deployment notes
450
+
451
+ - keep Gotenberg inside a public/private network is fine either case - as long as you set the username and password within the environment
452
+ - set request size/time limits at gateway level
453
+ - monitor CPU and memory because Chromium and LibreOffice conversions are workload-heavy
454
+ - run multiple replicas behind a load balancer for high-throughput conversion workloads
@@ -0,0 +1 @@
1
+ export * from "./src/index";
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from "./src/index";
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "gotenberg-client",
3
+ "description": "TypeScript client for the Gotenberg document conversion API.",
4
+ "version": "0.0.2",
5
+ "keywords": [
6
+ "gotenberg",
7
+ "typescript",
8
+ "api-client",
9
+ "pdf",
10
+ "conversion"
11
+ ],
12
+ "license": "MIT",
13
+ "module": "dist/index.js",
14
+ "type": "module",
15
+ "private": false,
16
+ "author": {
17
+ "name": "zmzlois",
18
+ "email": "lois@normal-people.com",
19
+ "url": "https://github.com/zmzlois",
20
+ "x": "https://x.com/zmzlois"
21
+ },
22
+ "homepage": "https://github.com/zmzlois/gotenberg-client#readme",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/zmzlois/gotenberg-client.git",
26
+ "directory": "."
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/zmzlois/gotenberg-client/issues"
30
+ },
31
+ "funding": {
32
+ "type": "github",
33
+ "url": "https://github.com/sponsors/zmzlois/dashboard"
34
+ },
35
+ "main": "dist/index.js",
36
+ "types": "dist/index.d.ts",
37
+ "exports": {
38
+ ".": {
39
+ "import": "./dist/index.js",
40
+ "types": "./dist/index.d.ts"
41
+ }
42
+ },
43
+ "files": [
44
+ "dist",
45
+ "README.md",
46
+ "LICENSE"
47
+ ],
48
+ "scripts": {
49
+ "format": "biome check --write .",
50
+ "format:code": "biome format --write .",
51
+ "build": "bunx tsc -p tsconfig.build.json",
52
+ "typecheck": "bunx tsc -p tsconfig.json --noEmit",
53
+ "test": "bun test"
54
+ },
55
+ "publishConfig": {
56
+ "access": "public",
57
+ "provenance": true
58
+ },
59
+ "devDependencies": {
60
+ "@biomejs/biome": "^2.0.0",
61
+ "@types/bun": "latest",
62
+ "typescript": "^5"
63
+ },
64
+ "peerDependencies": {
65
+ "typescript": "^5"
66
+ }
67
+ }
@@ -0,0 +1,26 @@
1
+ import type { ConvertHtmlInput, ConvertMarkdownInput, ConvertOfficeInput, ConvertToPdfaInput, ConvertUrlInput, EmbedFilesInput, EncryptPdfInput, FlattenPdfInput, GotenbergClient, GotenbergClientOptions, GotenbergHealth, MergePdfInput, ReadMetadataInput, ScreenshotHtmlInput, ScreenshotMarkdownInput, ScreenshotUrlInput, SplitPdfInput, WriteMetadataInput } from "./types";
2
+ /**
3
+ * Internal request layer used by the public `Gotenberg` class.
4
+ * It focuses purely on transport + payload assembly.
5
+ */
6
+ export declare class GotenbergRequestClient implements GotenbergClient {
7
+ private readonly options;
8
+ constructor(options: GotenbergClientOptions);
9
+ health(signal?: AbortSignal): Promise<import("./types").Result<GotenbergHealth, import("./types").GotenbergError>>;
10
+ version(signal?: AbortSignal): Promise<import("./types").Result<string, import("./types").GotenbergError>>;
11
+ convertUrl(input: ConvertUrlInput): Promise<import("./types").Result<import("./types").GotenbergBinaryResponse, import("./types").GotenbergError>>;
12
+ convertHtml(input: ConvertHtmlInput): Promise<import("./types").Result<import("./types").GotenbergBinaryResponse, import("./types").GotenbergError>>;
13
+ convertMarkdown(input: ConvertMarkdownInput): Promise<import("./types").Result<import("./types").GotenbergBinaryResponse, import("./types").GotenbergError>>;
14
+ screenshotUrl(input: ScreenshotUrlInput): Promise<import("./types").Result<import("./types").GotenbergBinaryResponse, import("./types").GotenbergError>>;
15
+ screenshotHtml(input: ScreenshotHtmlInput): Promise<import("./types").Result<import("./types").GotenbergBinaryResponse, import("./types").GotenbergError>>;
16
+ screenshotMarkdown(input: ScreenshotMarkdownInput): Promise<import("./types").Result<import("./types").GotenbergBinaryResponse, import("./types").GotenbergError>>;
17
+ convertOffice(input: ConvertOfficeInput): Promise<import("./types").Result<import("./types").GotenbergBinaryResponse, import("./types").GotenbergError>>;
18
+ mergePdf(input: MergePdfInput): Promise<import("./types").Result<import("./types").GotenbergBinaryResponse, import("./types").GotenbergError>>;
19
+ splitPdf(input: SplitPdfInput): Promise<import("./types").Result<import("./types").GotenbergBinaryResponse, import("./types").GotenbergError>>;
20
+ flattenPdf(input: FlattenPdfInput): Promise<import("./types").Result<import("./types").GotenbergBinaryResponse, import("./types").GotenbergError>>;
21
+ encryptPdf(input: EncryptPdfInput): Promise<import("./types").Result<import("./types").GotenbergBinaryResponse, import("./types").GotenbergError>>;
22
+ embedFiles(input: EmbedFilesInput): Promise<import("./types").Result<import("./types").GotenbergBinaryResponse, import("./types").GotenbergError>>;
23
+ readMetadata(input: ReadMetadataInput): Promise<import("./types").Result<Record<string, Record<string, string>>, import("./types").GotenbergError>>;
24
+ writeMetadata(input: WriteMetadataInput): Promise<import("./types").Result<import("./types").GotenbergBinaryResponse, import("./types").GotenbergError>>;
25
+ convertToPdfa(input: ConvertToPdfaInput): Promise<import("./types").Result<import("./types").GotenbergBinaryResponse, import("./types").GotenbergError>>;
26
+ }