Skip to content

Commit 638f849

Browse files
committed
feat: ✨ Add puppeteer endpoint
1 parent b7cb13a commit 638f849

File tree

4 files changed

+60
-2
lines changed

4 files changed

+60
-2
lines changed

apps/api/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
},
88
"dependencies": {
99
"@hono/node-server": "^1.12.0",
10-
"hono": "^4.5.4"
10+
"hono": "^4.5.4",
11+
"puppeteer": "^22.15.0"
1112
},
1213
"devDependencies": {
1314
"@types/node": "^20.11.17",

apps/api/src/index.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
11
import { serve } from '@hono/node-server'
22
import { Hono } from 'hono'
3+
import { csrf } from 'hono/csrf'
4+
5+
import invoice from './invoice'
36

47
const app = new Hono()
58

9+
// middleware
10+
app.use(
11+
csrf({
12+
origin: ['app.invoicelink.io', 'pay.invoicelink.io', "invoicelink.io"],
13+
})
14+
)
15+
16+
// mount routes
17+
app.route('/invoice', invoice)
18+
619
app.get('/', (c) => {
7-
return c.text('Hello Hono!')
20+
return c.text('Hello from api.invoicelink.io!')
821
})
922

1023
const port = 3000

apps/api/src/invoice.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import puppeteer from 'puppeteer';
2+
import { Hono } from 'hono'
3+
4+
const app = new Hono()
5+
6+
const getBrowser = () => puppeteer.launch({ headless: true });
7+
8+
app.get('/', async (c) => {
9+
const {id, type, download} = c.req.queries()
10+
11+
let browser = null;
12+
13+
try {
14+
browser = await getBrowser();
15+
const page = await browser.newPage();
16+
17+
await page.goto(`https://app.invoicelink.io/invoice?id=${id}&type=${type}&download=${download}`);
18+
const pdf = await page.pdf({
19+
format: 'A4',
20+
printBackground: true
21+
});
22+
23+
return new Response(pdf, {
24+
headers: {
25+
'Content-Type': 'application/pdf',
26+
'Content-Disposition': download ? `attachment; filename="invoice.pdf"` : `inline`
27+
}
28+
});
29+
} catch (error: unknown) {
30+
if (error instanceof Error) {
31+
return c.json({ error: error.message });
32+
}
33+
} finally {
34+
if (browser) {
35+
browser.close();
36+
}
37+
}
38+
return c.text('Hello from invoice!')
39+
})
40+
41+
export default app

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)