{"id":17806235,"url":"https://github.com/pdsuwwz/puppeteer-server","last_synced_at":"2025-07-11T04:03:07.894Z","repository":{"id":38896366,"uuid":"379801105","full_name":"pdsuwwz/puppeteer-server","owner":"pdsuwwz","description":"🦩 Puppeteer + Node.js 后端模板, 基于 ESM + Koa + Tsup + TypeScript + ESLint (v9)实现后台服务, 快速将任意网页转换为 PDF / 图像快照, 支持爬取合并多个网页自动生成为 PDF 文件，支持 Cookie 注入、PDF 水印和页眉页脚插入","archived":false,"fork":false,"pushed_at":"2025-03-19T10:28:05.000Z","size":954,"stargazers_count":30,"open_issues_count":11,"forks_count":12,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-02T07:05:15.686Z","etag":null,"topics":["babel","combine","es","es6","eslint","esm","esmodule","generator","hmr","injection","merge","module","multiple","node","nodemon","pdf","pm2","rollup","watermark"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pdsuwwz.png","metadata":{"files":{"readme":"README-en.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-06-24T04:17:30.000Z","updated_at":"2025-03-20T01:42:32.000Z","dependencies_parsed_at":"2023-02-09T19:01:00.686Z","dependency_job_id":"b2cef6bb-a6b9-4fb3-8fa9-980a0cc5b7a5","html_url":"https://github.com/pdsuwwz/puppeteer-server","commit_stats":{"total_commits":128,"total_committers":4,"mean_commits":32.0,"dds":0.21875,"last_synced_commit":"0e313197907fadfa36fc73f96972b3718401d0ec"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/pdsuwwz/puppeteer-server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pdsuwwz%2Fpuppeteer-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pdsuwwz%2Fpuppeteer-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pdsuwwz%2Fpuppeteer-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pdsuwwz%2Fpuppeteer-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pdsuwwz","download_url":"https://codeload.github.com/pdsuwwz/puppeteer-server/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pdsuwwz%2Fpuppeteer-server/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264726770,"owners_count":23654494,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["babel","combine","es","es6","eslint","esm","esmodule","generator","hmr","injection","merge","module","multiple","node","nodemon","pdf","pm2","rollup","watermark"],"created_at":"2024-10-27T13:04:57.045Z","updated_at":"2025-07-11T04:03:07.889Z","avatar_url":"https://github.com/pdsuwwz.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Puppeteer Server\n\nEnglish | [中文](README.md)\n\n\u003cimg src=\"https://github.com/pdsuwwz/puppeteer-server/assets/19891724/86177762-8a97-4656-8ee0-5add61c50237\" height=\"100\" align-right /\u003e\n\n\n## 📤 Migrate to Playwright\n\nTo experience enhanced features and broader browser support, the entire codebase of the latest version has seamlessly migrated to Playwright.\n\nPlaywright repo: [koa-playwright-server](https://github.com/pdsuwwz/koa-playwright-server)\n\n## Introduction\n\n🦩 Koa + ESM + TypeScript + Tsup + Nodemon + Puppeteer + ESLint (v9)\n\n\u003e * Fast Generate into PDF and images from any webpage.\n\u003e\n\u003e * Support merge multiple webpages into one PDF file, injection of Cookies, Watermark addition and Header and Footer insertion\n\n\n## ✨ Features\n\n* ✅ Built-in ES Module + TypeScript environment\n\n* 🌈 Separation business logic and Controllers.\n\n* 🛡 Probably the best practice for Puppeteer project.\n\n* 🧩 Configured routing.\n\n* 🚧 Eslint (v9) configuration.\n\n* ⚡ Fast build with ~~Rollup~~ Tsup.\n\n* 🔌 Extensible PDF watermark, header and footer.\n\n* 🧲 Supports merging of multiple PDF files.\n\n* 🔥 Based on Nodemon HMR.\n\n\n## Screenshot\n\n* Merge Combine the two websites into a PDF file\n\u003e 📦 See [Merge Test 1](__test__/axios-browser.html), [Merge Test 2](__test__/axios-node.js)\n\n\n![image](https://user-images.githubusercontent.com/19891724/159743021-e1f9f528-d6d9-4d6b-b63f-4e71c6b72bdb.png)\n\n\n## 🎯 Prerequisites\n\nPlease make sure that [Node.js](https://nodejs.org/) (\u003e= 20.x) is installed on your operating system.\n\n## Project structure\n\n\u003cpre\u003e\n├── src\n│   ├── controllers/ ---  Server controllers\n│   ├── services/    ---  Server services\n│   ├── config.ts    ---  About Environments variable\n│   ├── main.ts      ---  Entry file\n│   └── routes.ts    ---  Configs for routing controllers \u003ca href=\"#Routing\"\u003e👉 Routing\u003c/a\u003e\n\u003c/pre\u003e\n\n## ⚡ Quick Start\n\n### 1. Installation\n\n```bash\npnpm install\n```\n\n### 2. Running Development\n\n```bash\npnpm dev\n```\n\n### 3. Running Production\n\nThe project has built-in a `pm2`, running the `pnpm start` will automatically manage the process by `pm2`.\n\nRun `pnpm build` to build, then run `pnpm start` to start the process managed by `pm2`:\n\n* Build\n\n```bash\npnpm build\n```\n\n* Run\n\n```bash\npnpm start # PORT is 8080\n# or\nnode dist/bundle.esm.js # PORT is 5000\n```\n\n## API\n\n* `GET /image`\n\nGenerate screenshot.\n\n```bash\ncurl --location --request GET \\\n'http://localhost:5000/image?url=https://www.baidu.com' \\\n--output test-image.png\n```\n\n* `GET /simple-pdf`\n\nGenerate pdf.\n\n```bash\ncurl --location --request GET \\\n'http://localhost:5000/simple-pdf?url=https://www.google.com/' \\\n--output test-simple-pdf.pdf\n```\n\n* `POST /pdf`\n\nGenerate pdf with elements such as headers and footers.\n\n```bash\ncurl --location --request POST 'http://localhost:5000/pdf' \\\n--header 'Content-Type: application/x-www-form-urlencoded' \\\n--data-urlencode 'url=http://www.google.com' \\\n--data-urlencode 'cookies[0].name=token' \\\n--data-urlencode 'cookies[0].value=9s2d4c16-f072-16eg-b134-0642ap190006' \\\n--data-urlencode 'cookies[0].domain=www.google.com' --output test-complex-pdf.pdf\n```\n\n👆 /pdf request parameters\n\n| Field | Description | Type | Default Value |\n| -------- | -------- | -------- | -------- |\n| url | Target site url | string | — |\n| cookies | Generally used as a website that requires login to access, you can add this field | Array\u003c{ name, value, domain }\u003e | [] |\n| hasMargin | If this field is set to true, it means that the generated PDF will contain margins | boolean | true |\n| isLandscape | Whether the generated PDF is horizontal | boolean | false |\n| hiddenWatermark | Whether to hide watermark | boolean | false |\n| attachment | Display the custom header and footer, provided that hasMargin is set to true | { header, footer } | — |\n\n\n* `POST /combine-pdf`\n\nMerge multiple PDF files into one file.\n\nSee [Merge Test 1](__test__/axios-browser.html), [Merge Test 2](__test__/axios-node.js)\n\n👆 /combine-pdf request parameters\n\n| Field | Description | Type | Default Value |\n| -------- | -------- | -------- | -------- |\n| pdfList | A collection of target websites, the parameter type is an array, and each item in the array is a parameter required by `/pdf` | Array\u003c{ pdfItem }\u003e | [] |\n\n\n## Routing\n\nIn order to make the routing information more readable and transparent, the form of configuration is adopted here.\n\nYou can create an `array` and then write the routing meta information into the `array`, and reuse it in the [src/routes.ts](src/routes.ts)\n\n```ts\nconst routes: Array\u003cRouteConfig\u003e = [\n  {\n    path: '/',\n    method: 'get',\n    action: homeController.hello\n  },\n  // here...\n]\n```\n\n# License\n\n:v:\n\n[MIT](./LICENSE)\n\n\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fpdsuwwz%2Fpuppeteer-server.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fpdsuwwz%2Fpuppeteer-server?ref=badge_large)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpdsuwwz%2Fpuppeteer-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpdsuwwz%2Fpuppeteer-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpdsuwwz%2Fpuppeteer-server/lists"}