pdfn 0.6.1 → 0.6.3

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 CHANGED
@@ -26,6 +26,19 @@ npx pdfn dev --open # Start and open browser
26
26
  | `--open` | `false` | Open browser on start |
27
27
  | `--no-open` | - | Don't open browser |
28
28
 
29
+ **Server API:**
30
+
31
+ ```
32
+ POST /v1/generate # HTML → PDF
33
+ GET /health # Health check
34
+ ```
35
+
36
+ Use with `generate()` by setting `PDFN_HOST`:
37
+
38
+ ```bash
39
+ PDFN_HOST=http://localhost:3456 node your-app.js
40
+ ```
41
+
29
42
  ### `pdfn add`
30
43
 
31
44
  Add starter templates to your project.
@@ -45,11 +58,22 @@ npx pdfn add --list # Show all templates
45
58
  | `poster` | Event poster (landscape) |
46
59
  | `report` | Sales report with charts (requires recharts) |
47
60
 
48
- ## Production PDFs
61
+ ## PDF Generation
49
62
 
50
- For production PDF generation, choose based on your infrastructure:
63
+ For PDF generation, choose based on your infrastructure:
64
+
65
+ **Option 1: Local dev server**
66
+
67
+ Use `pdfn dev` for development with `generate()`:
68
+
69
+ ```tsx
70
+ import { generate } from '@pdfn/react';
71
+
72
+ // Set PDFN_HOST=http://localhost:3456
73
+ const pdf = await generate(<Invoice />);
74
+ ```
51
75
 
52
- **Option 1: Self-host with Puppeteer/Playwright**
76
+ **Option 2: Self-host with Puppeteer/Playwright**
53
77
 
54
78
  Use `render()` to get print-ready HTML, then convert with your own browser:
55
79
 
@@ -69,20 +93,20 @@ await browser.close();
69
93
 
70
94
  Works with Puppeteer, Playwright, Browserless, @sparticuz/chromium, or any Chromium setup.
71
95
 
72
- **Option 2: pdfn Cloud**
96
+ **Option 3: pdfn Cloud**
73
97
 
74
98
  Let pdfn manage the browser infrastructure:
75
99
 
76
100
  ```tsx
77
101
  import { generate } from '@pdfn/react';
78
102
 
79
- // Set PDFN_API_KEY environment variable
103
+ // Set PDFN_API_KEY=pdfn_live_...
80
104
  const pdf = await generate(<Invoice />);
81
105
  ```
82
106
 
83
107
  Get your API key at [console.pdfn.dev](https://console.pdfn.dev).
84
108
 
85
- **Both produce identical PDFs** — same templates, same output.
109
+ **All options produce identical PDFs** — same templates, same output.
86
110
 
87
111
  ## License
88
112
 
package/dist/cli.js CHANGED
@@ -1463,7 +1463,6 @@ import chokidar from "chokidar";
1463
1463
  import { createServer as createHttpServer } from "http";
1464
1464
  import { spawn } from "child_process";
1465
1465
  import puppeteer2 from "puppeteer";
1466
- import multer from "multer";
1467
1466
 
1468
1467
  // src/server/base.ts
1469
1468
  import express from "express";
@@ -1826,7 +1825,7 @@ function createBaseServer(options = {}) {
1826
1825
  res.on("finish", () => {
1827
1826
  const duration = performance.now() - start;
1828
1827
  let extra;
1829
- if (req.path === "/generate" && res.statusCode === 200) {
1828
+ if (req.path === "/v1/generate" && res.statusCode === 200) {
1830
1829
  const pages = res.getHeader("X-PDFN-Page-Count");
1831
1830
  const size = Number(res.getHeader("X-PDFN-PDF-Size")) || 0;
1832
1831
  const sizeKB = (size / 1024).toFixed(1);
@@ -1850,7 +1849,7 @@ function createBaseServer(options = {}) {
1850
1849
  });
1851
1850
  });
1852
1851
  app.post(
1853
- "/generate",
1852
+ "/v1/generate",
1854
1853
  createGenerateHandler(browserManager, {
1855
1854
  timeout,
1856
1855
  onSuccess: options.onSuccess,
@@ -3257,45 +3256,6 @@ async function startDevServer(options) {
3257
3256
  res.status(500).json({ error: `Error generating PDF: ${error}` });
3258
3257
  }
3259
3258
  });
3260
- const upload = multer({ storage: multer.memoryStorage() });
3261
- app.post(
3262
- "/forms/chromium/convert/html",
3263
- upload.any(),
3264
- async (req, res) => {
3265
- try {
3266
- const files = req.files;
3267
- const htmlFile = files?.find(
3268
- (f) => f.originalname === "index.html" || f.fieldname === "files"
3269
- );
3270
- if (!htmlFile) {
3271
- res.status(400).send("Missing index.html file");
3272
- return;
3273
- }
3274
- const html = htmlFile.buffer.toString("utf-8");
3275
- const result = await browserManager.withPage(async (page) => {
3276
- return generatePdf(page, html, { timeout: 3e4 });
3277
- });
3278
- const { metrics } = result;
3279
- console.log(
3280
- chalk.green(" \u2713"),
3281
- chalk.dim("API \u2192"),
3282
- "PDF",
3283
- chalk.dim("\u2022"),
3284
- chalk.cyan(`${metrics.total}ms`),
3285
- chalk.dim("\u2022"),
3286
- formatBytes(metrics.pdfSize),
3287
- chalk.dim(`\u2022 ${metrics.pageCount} page${metrics.pageCount > 1 ? "s" : ""}`)
3288
- );
3289
- res.setHeader("Content-Type", "application/pdf");
3290
- res.send(result.buffer);
3291
- } catch (error) {
3292
- const message = error instanceof Error ? error.message : String(error);
3293
- console.log(chalk.red(" \u2717"), chalk.dim("API \u2192"), chalk.red("PDF generation failed"));
3294
- console.error(chalk.dim(" "), message);
3295
- res.status(500).send(message);
3296
- }
3297
- }
3298
- );
3299
3259
  await new Promise((resolve3, reject) => {
3300
3260
  server.on("error", (err) => {
3301
3261
  if (err.code === "EADDRINUSE") {