@shad0wz7/nestjs-pdf 4.0.0 → 5.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 +96 -5
- package/dist/index.cjs +519 -176
- package/dist/index.d.cts +142 -88
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +142 -88
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +509 -167
- package/dist/index.mjs.map +1 -1
- package/package.json +35 -25
package/README.md
CHANGED
|
@@ -7,12 +7,13 @@
|
|
|
7
7
|
[](https://codecov.io/github/ShadowZ11/nestjs-pdf)
|
|
8
8
|
[](https://www.typescriptlang.org/)
|
|
9
9
|
|
|
10
|
-
A NestJS library to generate and manipulate PDFs
|
|
10
|
+
A NestJS library to generate and manipulate PDFs from multiple template engines (Handlebars, EJS, Pug, MJML, Nunjucks, Eta, Mustache and Liquid), printed by a local Puppeteer browser, a [Gotenberg](https://gotenberg.dev) server or the [Api2Pdf](https://www.api2pdf.com) API.
|
|
11
11
|
|
|
12
12
|
Main features:
|
|
13
13
|
|
|
14
14
|
- Generate PDFs from HTML, Handlebars, EJS, Pug, MJML, Nunjucks, Eta, Mustache or Liquid templates
|
|
15
|
-
-
|
|
15
|
+
- Pluggable PDF providers: local Puppeteer (default), Gotenberg or Api2Pdf, behind the same service API
|
|
16
|
+
- Concurrency limiting for PDF jobs (p-limit)
|
|
16
17
|
- Add signature fields based on a text anchor in an existing PDF
|
|
17
18
|
- Text or image watermarks (centered or tiled) on generated or existing PDFs
|
|
18
19
|
- Simple API (module and service) to integrate easily into a Nest application
|
|
@@ -37,6 +38,18 @@ yarn add @shad0wz7/nestjs-pdf
|
|
|
37
38
|
pnpm add ../path/to/nestjs-pdf
|
|
38
39
|
```
|
|
39
40
|
|
|
41
|
+
### PDF provider
|
|
42
|
+
|
|
43
|
+
Pick who prints the PDFs and install what it needs:
|
|
44
|
+
|
|
45
|
+
| Provider | Install | Notes |
|
|
46
|
+
| --------------------- | ------------------------------------------- | -------------------------------------------------------------------- |
|
|
47
|
+
| `puppeteer` (default) | `npm install puppeteer @puppeteer/browsers` | Local Chromium, downloaded on startup unless `executablePath` is set |
|
|
48
|
+
| `gotenberg` | nothing | Needs a [Gotenberg 8](https://gotenberg.dev) server |
|
|
49
|
+
| `api2pdf` | nothing | Needs an [Api2Pdf](https://www.api2pdf.com) API key |
|
|
50
|
+
|
|
51
|
+
`puppeteer` and `@puppeteer/browsers` are **optional peer dependencies**: with a remote provider, no browser is installed nor downloaded. The `puppeteer` provider needs **both** packages: if either is missing, the application fails on startup with an `EngineNotAvailableException` telling you what to install. With `executablePath`, the browser is not downloaded, so only `puppeteer` is needed. See [PDF providers](#pdf-providers) to configure Gotenberg or Api2Pdf.
|
|
52
|
+
|
|
40
53
|
### Template engines
|
|
41
54
|
|
|
42
55
|
Template engines are **optional peer dependencies**: none of them is installed with the library. Install only the ones you use, as dependencies of your own project:
|
|
@@ -67,6 +80,8 @@ Anchor-based signature placement also relies on `pdfjs-dist`, which needs `@napi
|
|
|
67
80
|
|
|
68
81
|
> **Upgrading from v3:** engines used to be installed automatically. If you relied on that, add the engines you use to your project's dependencies.
|
|
69
82
|
|
|
83
|
+
> **Upgrading from v4:** Puppeteer is no longer installed with the library. If you keep the default provider, add it to your project: `npm install puppeteer @puppeteer/browsers`. `NestjsPdfErrorCode` also gained a `RENDERER_CONFIGURATION_ERROR` member: update any exhaustive `Record<NestjsPdfErrorCode, …>` map. `pdfOptions` is now typed by the library's own `PdfOptions` (same shape as Puppeteer's `PDFOptions`) and `browser` accepts plain strings (`'chromium'`) as well as the `Browser` enum, so the published types no longer depend on Puppeteer.
|
|
84
|
+
|
|
70
85
|
## Quick start
|
|
71
86
|
|
|
72
87
|
Import the module and configure it in your Nest application:
|
|
@@ -234,16 +249,92 @@ Good to know:
|
|
|
234
249
|
- Names are checked by resolving them before the request, so a domain that changes its address between the check and the request (DNS rebinding) can slip through. Use `allowedHosts` (or `javascriptEnabled: false`) when the content is fully untrusted.
|
|
235
250
|
- `window.open` pop-ups are blocked: the library no longer passes `--disable-popup-blocking` to Chrome. If you set `extraPuppeteerArgs`, do not add it back.
|
|
236
251
|
|
|
252
|
+
## PDF providers
|
|
253
|
+
|
|
254
|
+
Templates, watermarks and signatures always run in your application; the provider only turns the rendered HTML into a PDF. Choose it with `provider` in `forRoot` / `forRootAsync` (it is ignored in per-call options):
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
// Gotenberg (self-hosted): docker run --rm -p 3000:3000 gotenberg/gotenberg:8
|
|
258
|
+
NestjsPdfModule.forRoot({
|
|
259
|
+
provider: {
|
|
260
|
+
type: 'gotenberg',
|
|
261
|
+
url: 'http://localhost:3000',
|
|
262
|
+
// optional: when Gotenberg runs with --api-enable-basic-auth
|
|
263
|
+
basicAuth: { username: 'user', password: 'pass' },
|
|
264
|
+
// optional: extra headers, e.g. for an authenticating proxy
|
|
265
|
+
headers: { 'X-Api-Key': '...' },
|
|
266
|
+
},
|
|
267
|
+
pdfOptions: { format: 'A4', printBackground: true },
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
// Api2Pdf (SaaS)
|
|
271
|
+
NestjsPdfModule.forRootAsync({
|
|
272
|
+
inject: [ConfigService],
|
|
273
|
+
useFactory: (config: ConfigService) => ({
|
|
274
|
+
provider: { type: 'api2pdf', apiKey: config.getOrThrow('API2PDF_KEY') },
|
|
275
|
+
}),
|
|
276
|
+
});
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
The service API does not change: `generatePdfFromHtml`, every `generatePdfFrom<Engine>*` method, `watermark` and `signal` work the same with every provider. A missing `url` / `apiKey` or an unknown `type` throws a `RendererConfigurationException` on startup.
|
|
280
|
+
|
|
281
|
+
### Page options
|
|
282
|
+
|
|
283
|
+
Keep using `pdfOptions` (Puppeteer's format). For Gotenberg and Api2Pdf, these fields are translated: `format`, `width`, `height`, `margin` (numbers are pixels; strings in `px`, `in`, `cm` or `mm`), `landscape`, `printBackground`, `omitBackground`, `scale`, `pageRanges`, `displayHeaderFooter` with `headerTemplate` / `footerTemplate`, plus `preferCSSPageSize`, `tagged` and `outline` for Gotenberg. The other fields are ignored. Like the Puppeteer provider, the page is rendered with the `screen` media type, and with zero margins unless you set them.
|
|
284
|
+
|
|
285
|
+
Provider-specific options, per call or in `forRoot`:
|
|
286
|
+
|
|
287
|
+
```ts
|
|
288
|
+
await pdfService.generatePdfFromHtml(
|
|
289
|
+
'<img src="logo.png"><link rel="stylesheet" href="style.css">',
|
|
290
|
+
{
|
|
291
|
+
gotenbergOptions: {
|
|
292
|
+
// files the HTML references by relative name, sent next to index.html
|
|
293
|
+
assets: [
|
|
294
|
+
{
|
|
295
|
+
filename: 'logo.png',
|
|
296
|
+
content: await readFile('logo.png'),
|
|
297
|
+
contentType: 'image/png',
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
filename: 'style.css',
|
|
301
|
+
content: 'body { font-family: sans-serif; }',
|
|
302
|
+
contentType: 'text/css',
|
|
303
|
+
},
|
|
304
|
+
],
|
|
305
|
+
// any Gotenberg Chromium form field (PDF/A, wait...), wins over the derived ones
|
|
306
|
+
formFields: { pdfa: 'PDF/A-2b', waitDelay: '500ms' },
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
);
|
|
310
|
+
|
|
311
|
+
await pdfService.generatePdfFromHtml(html, {
|
|
312
|
+
// any Api2Pdf Chrome option, merged over the derived ones
|
|
313
|
+
api2pdfOptions: { fileName: 'invoice.pdf', options: { delay: 500 } },
|
|
314
|
+
});
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Good to know
|
|
318
|
+
|
|
319
|
+
- **Local files:** a remote provider cannot read your disk. With Gotenberg, send images, fonts and CSS as `assets`; with Api2Pdf, use public URLs or inline them (`data:` URIs).
|
|
320
|
+
- **`security` is Puppeteer-only:** the request filter runs in the local browser, so with a remote provider it throws a `RendererConfigurationException` instead of being silently skipped. With Gotenberg, restrict outbound requests on the server (`--chromium-allow-list`, `--chromium-deny-list`); with Api2Pdf, only render HTML you trust.
|
|
321
|
+
- **With Api2Pdf, data leaves your infrastructure:** the HTML is sent to a third-party service, which matters for personal data (GDPR). Gotenberg stays on your own servers.
|
|
322
|
+
- **Errors:** an HTTP error from the provider becomes a `PdfGenerationException` whose message holds the status and the start of the response body.
|
|
323
|
+
- **Browser options** (`headless`, `browser`, `browserTag`, `buildId`, `useLockedBrowser`, `executablePath`, `extraPuppeteerArgs`, `browserInstallBaseUrl`, `cleanupBrowserCacheOnExit`) only apply to the `puppeteer` provider.
|
|
324
|
+
|
|
237
325
|
## Options and configuration
|
|
238
326
|
|
|
239
|
-
The library exposes
|
|
327
|
+
The library exposes its options via the `PuppeteerParameters` interface (see `src/puppeteer/puppeteer-parameters.interface.ts`). You can configure:
|
|
240
328
|
|
|
241
329
|
| | Description |
|
|
242
330
|
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
243
|
-
| `
|
|
331
|
+
| `provider` | Who prints the PDF: `{ type: 'puppeteer' }` (default), `{ type: 'gotenberg', url, basicAuth?, headers? }` or `{ type: 'api2pdf', apiKey, baseUrl?, headers? }`. Module-level only. See [PDF providers](#pdf-providers) |
|
|
332
|
+
| `pdfOptions` | The pdf options can be found on: https://pptr.dev/api/puppeteer.pdfoptions. Native Puppeteer options for `page.pdf`. Remote providers translate the main ones, see [Page options](#page-options) |
|
|
333
|
+
| `gotenbergOptions` | Gotenberg provider only: `assets` (files sent next to `index.html`) and raw `formFields` |
|
|
334
|
+
| `api2pdfOptions` | Api2Pdf provider only: `fileName` and raw Chrome `options` |
|
|
244
335
|
| `watermark` | Stamps a text or image watermark on the generated PDF: `text` or `image`, `opacity`, `rotation`, `fontSize`, `font`, `color`, `imageWidth`, `position`, `tileSpacing`, `pages`. See [Watermark](#watermark) |
|
|
245
336
|
| `signal` | An `AbortSignal` that cancels the generation, including while it waits for a free slot. The promise rejects with `signal.reason`; use `AbortSignal.timeout(ms)` for a timeout. See [Cancellation and timeout](#cancellation-and-timeout) |
|
|
246
|
-
| `security` | Filters what the rendered HTML may load (SSRF protection): `blockPrivateNetworks`, `allowedHosts`, `allowedFileRoots`, `javascriptEnabled`. Disabled unless set; pass `{}` for the defaults. See [Restricting what the HTML can load](#restricting-what-the-html-can-load-ssrf-protection)
|
|
337
|
+
| `security` | Puppeteer provider only. Filters what the rendered HTML may load (SSRF protection): `blockPrivateNetworks`, `allowedHosts`, `allowedFileRoots`, `javascriptEnabled`. Disabled unless set; pass `{}` for the defaults. See [Restricting what the HTML can load](#restricting-what-the-html-can-load-ssrf-protection) |
|
|
247
338
|
| `hbsOptions` | Handlebars configuration: `templateDirectory` (base dir for `renderFile`), `partialDirectory` (files registered as partials), `compileOptions`, `templateOptions`, and `helpers` (`{ name, fn }[]`). Like the other engines it can be set globally here or overridden per call (`generatePdfFromTemplateHbs*(..., { hbsOptions })`). Helpers/partials run on an isolated Handlebars environment (no global leakage). |
|
|
248
339
|
| `ejsOptions` | The ejs options can be found on [EJS documentation](https://ejs.co/#options) |
|
|
249
340
|
| `pugOptions` | The pug options can be found on [Pug documentation](https://pugjs.org/api/reference.html#options) |
|