@kne/fastify-puppeteer 1.0.0 → 1.1.1
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 +269 -3
- package/index.js +6 -2
- package/libs/controllers.js +11 -10
- package/libs/core/setup.js +2 -2
- package/libs/core/setup.test.js +1 -1
- package/libs/services.js +18 -2
- package/package.json +11 -9
- package/libs/core/createDeferred.js +0 -30
package/README.md
CHANGED
|
@@ -13,6 +13,54 @@
|
|
|
13
13
|
npm i --save @kne/fastify-puppeteer
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
+
|
|
17
|
+
### 概述
|
|
18
|
+
|
|
19
|
+
### 项目简介
|
|
20
|
+
|
|
21
|
+
fastify-puppeteer 是一个基于 Fastify 的插件,它集成了 Puppeteer 来提供强大的网页内容转换功能。该插件可以将 HTML 内容或 URL 转换为 PDF 文档或图片,支持单个转换和批量转换操作。
|
|
22
|
+
|
|
23
|
+
### 主要特性
|
|
24
|
+
|
|
25
|
+
- HTML 转 PDF:将 HTML 内容直接转换为 PDF 文档
|
|
26
|
+
- HTML 转图片:将 HTML 内容转换为图片
|
|
27
|
+
- URL 转 PDF:将指定 URL 的网页转换为 PDF 文档
|
|
28
|
+
- URL 转图片:将指定 URL 的网页转换为图片
|
|
29
|
+
- 批量处理:支持批量转换多个 HTML 内容或 URL
|
|
30
|
+
- 并发控制:内置任务队列管理,控制最大并发任务数量
|
|
31
|
+
- 缓存机制:支持文件缓存,提高转换效率
|
|
32
|
+
|
|
33
|
+
### 技术架构
|
|
34
|
+
|
|
35
|
+
#### 核心组件
|
|
36
|
+
|
|
37
|
+
- **Fastify 插件**:提供 HTTP 接口和静态文件服务
|
|
38
|
+
- **Puppeteer**:负责网页渲染和内容转换
|
|
39
|
+
- **任务队列**:管理并发任务,防止系统过载
|
|
40
|
+
- **文件缓存**:缓存转换结果,提高响应速度
|
|
41
|
+
|
|
42
|
+
#### 工作流程
|
|
43
|
+
|
|
44
|
+
1. 接收转换请求(HTML内容或URL)
|
|
45
|
+
2. 通过任务队列管理器控制并发
|
|
46
|
+
3. 使用 Puppeteer 打开页面并进行渲染
|
|
47
|
+
4. 执行转换操作(PDF或图片)
|
|
48
|
+
5. 返回转换结果
|
|
49
|
+
|
|
50
|
+
### 配置选项
|
|
51
|
+
|
|
52
|
+
- **maxTaskSize**:最大并发任务数,默认为 100
|
|
53
|
+
- **puppeteerOptions**:Puppeteer 启动选项,用于配置浏览器行为
|
|
54
|
+
- **cacheOptions**:文件缓存配置,控制缓存行为
|
|
55
|
+
|
|
56
|
+
### 使用场景
|
|
57
|
+
|
|
58
|
+
- 网页存档:将网页内容保存为 PDF 文档
|
|
59
|
+
- 报表生成:将动态内容转换为 PDF 报表
|
|
60
|
+
- 网页截图:捕获网页内容生成图片
|
|
61
|
+
- 批量处理:批量转换多个网页或HTML内容
|
|
62
|
+
|
|
63
|
+
|
|
16
64
|
### 示例
|
|
17
65
|
|
|
18
66
|
#### 示例代码
|
|
@@ -21,7 +69,225 @@ npm i --save @kne/fastify-puppeteer
|
|
|
21
69
|
|
|
22
70
|
### API
|
|
23
71
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
72
|
+
### API 接口文档
|
|
73
|
+
|
|
74
|
+
本文档详细描述了 fastify-puppeteer 插件提供的所有 API 接口。
|
|
75
|
+
|
|
76
|
+
#### 接口概览
|
|
77
|
+
|
|
78
|
+
| 接口名称 | 请求方法 | 请求路径 | 描述 |
|
|
79
|
+
|---------|---------|---------|------|
|
|
80
|
+
| parseHtmlToPdf | POST | /parseHtmlToPdf | 将 HTML 内容转换为 PDF 文件 |
|
|
81
|
+
| parseHtmlToPdfBatch | POST | /parseHtmlToPdfBatch | 批量将 HTML 内容转换为 PDF 文件(打包为 ZIP) |
|
|
82
|
+
| parseHtmlToPhoto | POST | /parseHtmlToPhoto | 将 HTML 内容转换为图片 |
|
|
83
|
+
| parseHtmlToPhotoBatch | POST | /parseHtmlToPhotoBatch | 批量将 HTML 内容转换为图片(打包为 ZIP) |
|
|
84
|
+
| parseUrlToPdf | POST | /parseUrlToPdf | 将 URL 网页转换为 PDF 文件 |
|
|
85
|
+
| parseUrlToPdfBatch | POST | /parseUrlToPdfBatch | 批量将 URL 网页转换为 PDF 文件(打包为 ZIP) |
|
|
86
|
+
| parseUrlToPhoto | POST | /parseUrlToPhoto | 将 URL 网页转换为图片 |
|
|
87
|
+
| parseUrlToPhotoBatch | POST | /parseUrlToPhotoBatch | 批量将 URL 网页转换为图片(打包为 ZIP) |
|
|
88
|
+
|
|
89
|
+
#### 接口详情
|
|
90
|
+
|
|
91
|
+
##### HTML 转换接口
|
|
92
|
+
|
|
93
|
+
###### parseHtmlToPdf
|
|
94
|
+
|
|
95
|
+
| 项目 | 说明 |
|
|
96
|
+
|------|------|
|
|
97
|
+
| 接口描述 | 将 HTML 内容转换为 PDF 文件 |
|
|
98
|
+
| 请求方法 | POST |
|
|
99
|
+
| 请求路径 | /parseHtmlToPdf |
|
|
100
|
+
| 认证方式 | 根据配置的 authenticate 函数 |
|
|
101
|
+
| 请求参数 | JSON 对象 |
|
|
102
|
+
|
|
103
|
+
**请求参数详情:**
|
|
104
|
+
|
|
105
|
+
| 参数名 | 类型 | 必填 | 描述 |
|
|
106
|
+
|-------|------|------|------|
|
|
107
|
+
| content | string | 是 | 需要转换的 HTML 内容 |
|
|
108
|
+
| options | object | 否 | PDF 生成选项,参考 Puppeteer API |
|
|
109
|
+
|
|
110
|
+
**响应结果:**
|
|
111
|
+
- 返回生成的 PDF 文件流
|
|
112
|
+
|
|
113
|
+
###### parseHtmlToPdfBatch
|
|
114
|
+
|
|
115
|
+
| 项目 | 说明 |
|
|
116
|
+
|------|------|
|
|
117
|
+
| 接口描述 | 批量将 HTML 内容转换为 PDF 文件(打包为 ZIP) |
|
|
118
|
+
| 请求方法 | POST |
|
|
119
|
+
| 请求路径 | /parseHtmlToPdfBatch |
|
|
120
|
+
| 认证方式 | 根据配置的 authenticate 函数 |
|
|
121
|
+
| 请求参数 | JSON 对象 |
|
|
122
|
+
|
|
123
|
+
**请求参数详情:**
|
|
124
|
+
|
|
125
|
+
| 参数名 | 类型 | 必填 | 描述 |
|
|
126
|
+
|-------|------|------|------|
|
|
127
|
+
| contentList | array | 是 | 需要转换的 HTML 内容列表 |
|
|
128
|
+
| options | object | 否 | PDF 生成选项,参考 Puppeteer API |
|
|
129
|
+
|
|
130
|
+
**响应结果:**
|
|
131
|
+
- 返回包含所有生成 PDF 的 ZIP 文件流
|
|
132
|
+
|
|
133
|
+
###### parseHtmlToPhoto
|
|
134
|
+
|
|
135
|
+
| 项目 | 说明 |
|
|
136
|
+
|------|------|
|
|
137
|
+
| 接口描述 | 将 HTML 内容转换为图片 |
|
|
138
|
+
| 请求方法 | POST |
|
|
139
|
+
| 请求路径 | /parseHtmlToPhoto |
|
|
140
|
+
| 认证方式 | 根据配置的 authenticate 函数 |
|
|
141
|
+
| 请求参数 | JSON 对象 |
|
|
142
|
+
|
|
143
|
+
**请求参数详情:**
|
|
144
|
+
|
|
145
|
+
| 参数名 | 类型 | 必填 | 描述 |
|
|
146
|
+
|-------|------|------|------|
|
|
147
|
+
| content | string | 是 | 需要转换的 HTML 内容 |
|
|
148
|
+
| options | object | 否 | 图片生成选项,参考 Puppeteer API |
|
|
149
|
+
|
|
150
|
+
**响应结果:**
|
|
151
|
+
- 返回生成的图片文件流
|
|
152
|
+
|
|
153
|
+
###### parseHtmlToPhotoBatch
|
|
154
|
+
|
|
155
|
+
| 项目 | 说明 |
|
|
156
|
+
|------|------|
|
|
157
|
+
| 接口描述 | 批量将 HTML 内容转换为图片(打包为 ZIP) |
|
|
158
|
+
| 请求方法 | POST |
|
|
159
|
+
| 请求路径 | /parseHtmlToPhotoBatch |
|
|
160
|
+
| 认证方式 | 根据配置的 authenticate 函数 |
|
|
161
|
+
| 请求参数 | JSON 对象 |
|
|
162
|
+
|
|
163
|
+
**请求参数详情:**
|
|
164
|
+
|
|
165
|
+
| 参数名 | 类型 | 必填 | 描述 |
|
|
166
|
+
|-------|------|------|------|
|
|
167
|
+
| contentList | array | 是 | 需要转换的 HTML 内容列表 |
|
|
168
|
+
| options | object | 否 | 图片生成选项,参考 Puppeteer API |
|
|
169
|
+
|
|
170
|
+
**响应结果:**
|
|
171
|
+
- 返回包含所有生成图片的 ZIP 文件流
|
|
172
|
+
|
|
173
|
+
##### URL 转换接口
|
|
174
|
+
|
|
175
|
+
###### parseUrlToPdf
|
|
176
|
+
|
|
177
|
+
| 项目 | 说明 |
|
|
178
|
+
|------|------|
|
|
179
|
+
| 接口描述 | 将 URL 网页转换为 PDF 文件 |
|
|
180
|
+
| 请求方法 | POST |
|
|
181
|
+
| 请求路径 | /parseUrlToPdf |
|
|
182
|
+
| 认证方式 | 根据配置的 authenticate 函数 |
|
|
183
|
+
| 请求参数 | JSON 对象 |
|
|
184
|
+
|
|
185
|
+
**请求参数详情:**
|
|
186
|
+
|
|
187
|
+
| 参数名 | 类型 | 必填 | 描述 |
|
|
188
|
+
|-------|------|------|------|
|
|
189
|
+
| url | string | 是 | 需要转换的网页 URL |
|
|
190
|
+
| options | object | 否 | PDF 生成选项,参考 Puppeteer API 和 URL 转换特有选项 |
|
|
191
|
+
|
|
192
|
+
**响应结果:**
|
|
193
|
+
- 返回生成的 PDF 文件流
|
|
194
|
+
|
|
195
|
+
###### parseUrlToPdfBatch
|
|
196
|
+
|
|
197
|
+
| 项目 | 说明 |
|
|
198
|
+
|------|------|
|
|
199
|
+
| 接口描述 | 批量将 URL 网页转换为 PDF 文件(打包为 ZIP) |
|
|
200
|
+
| 请求方法 | POST |
|
|
201
|
+
| 请求路径 | /parseUrlToPdfBatch |
|
|
202
|
+
| 认证方式 | 根据配置的 authenticate 函数 |
|
|
203
|
+
| 请求参数 | JSON 对象 |
|
|
204
|
+
|
|
205
|
+
**请求参数详情:**
|
|
206
|
+
|
|
207
|
+
| 参数名 | 类型 | 必填 | 描述 |
|
|
208
|
+
|-------|------|------|------|
|
|
209
|
+
| urlList | array | 是 | 需要转换的网页 URL 列表 |
|
|
210
|
+
| options | object | 否 | PDF 生成选项,参考 Puppeteer API 和 URL 转换特有选项 |
|
|
211
|
+
|
|
212
|
+
**响应结果:**
|
|
213
|
+
- 返回包含所有生成 PDF 的 ZIP 文件流
|
|
214
|
+
|
|
215
|
+
###### parseUrlToPhoto
|
|
216
|
+
|
|
217
|
+
| 项目 | 说明 |
|
|
218
|
+
|------|------|
|
|
219
|
+
| 接口描述 | 将 URL 网页转换为图片 |
|
|
220
|
+
| 请求方法 | POST |
|
|
221
|
+
| 请求路径 | /parseUrlToPhoto |
|
|
222
|
+
| 认证方式 | 根据配置的 authenticate 函数 |
|
|
223
|
+
| 请求参数 | JSON 对象 |
|
|
224
|
+
|
|
225
|
+
**请求参数详情:**
|
|
226
|
+
|
|
227
|
+
| 参数名 | 类型 | 必填 | 描述 |
|
|
228
|
+
|-------|------|------|------|
|
|
229
|
+
| url | string | 是 | 需要转换的网页 URL |
|
|
230
|
+
| selector | string | 否 | 页面元素选择器,指定截图区域。如果提供,将只截取该元素区域 |
|
|
231
|
+
| options | object | 否 | 图片生成选项,参考 Puppeteer API 和 URL 转换特有选项 |
|
|
232
|
+
|
|
233
|
+
**响应结果:**
|
|
234
|
+
- 返回生成的图片文件流
|
|
235
|
+
|
|
236
|
+
###### parseUrlToPhotoBatch
|
|
237
|
+
|
|
238
|
+
| 项目 | 说明 |
|
|
239
|
+
|------|------|
|
|
240
|
+
| 接口描述 | 批量将 URL 网页转换为图片(打包为 ZIP) |
|
|
241
|
+
| 请求方法 | POST |
|
|
242
|
+
| 请求路径 | /parseUrlToPhotoBatch |
|
|
243
|
+
| 认证方式 | 根据配置的 authenticate 函数 |
|
|
244
|
+
| 请求参数 | JSON 对象 |
|
|
245
|
+
|
|
246
|
+
**请求参数详情:**
|
|
247
|
+
|
|
248
|
+
| 参数名 | 类型 | 必填 | 描述 |
|
|
249
|
+
|-------|------|------|------|
|
|
250
|
+
| urlList | array | 是 | 需要转换的网页 URL 列表 |
|
|
251
|
+
| selector | string | 否 | 页面元素选择器,指定截图区域。如果提供,将只截取该元素区域 |
|
|
252
|
+
| options | object | 否 | 图片生成选项,参考 Puppeteer API 和 URL 转换特有选项 |
|
|
253
|
+
|
|
254
|
+
**响应结果:**
|
|
255
|
+
- 返回包含所有生成图片的 ZIP 文件流
|
|
256
|
+
|
|
257
|
+
### 选项参数说明
|
|
258
|
+
|
|
259
|
+
#### PDF 生成选项
|
|
260
|
+
|
|
261
|
+
PDF 生成选项参考 Puppeteer 的 [page.pdf()](https://pptr.dev/api/puppeteer.page.pdf) 方法参数,常用选项包括:
|
|
262
|
+
|
|
263
|
+
| 选项名 | 类型 | 描述 |
|
|
264
|
+
|-------|------|------|
|
|
265
|
+
| format | string | 纸张格式,如 'A4', 'Letter' 等 |
|
|
266
|
+
| width | string | 纸张宽度,如 '8.5in' |
|
|
267
|
+
| height | string | 纸张高度,如 '11in' |
|
|
268
|
+
| margin | object | 页面边距,包含 top, right, bottom, left 属性 |
|
|
269
|
+
| printBackground | boolean | 是否打印背景图形 |
|
|
270
|
+
| landscape | boolean | 是否使用横向打印 |
|
|
271
|
+
|
|
272
|
+
#### 图片生成选项
|
|
273
|
+
|
|
274
|
+
图片生成选项参考 Puppeteer 的 [page.screenshot()](https://pptr.dev/api/puppeteer.page.screenshot) 方法参数,常用选项包括:
|
|
275
|
+
|
|
276
|
+
| 选项名 | 类型 | 描述 |
|
|
277
|
+
|-------|------|------|
|
|
278
|
+
| type | string | 图片格式,如 'png', 'jpeg' |
|
|
279
|
+
| quality | number | 图片质量 (0-100),仅适用于 JPEG |
|
|
280
|
+
| fullPage | boolean | 是否捕获完整页面 |
|
|
281
|
+
| clip | object | 裁剪区域,包含 x, y, width, height 属性 |
|
|
282
|
+
| omitBackground | boolean | 是否隐藏默认白色背景 |
|
|
283
|
+
|
|
284
|
+
#### URL 转换特有选项
|
|
285
|
+
|
|
286
|
+
以下选项适用于 parseUrlToPdf、parseUrlToPdfBatch、parseUrlToPhoto 和 parseUrlToPhotoBatch 接口:
|
|
287
|
+
|
|
288
|
+
| 选项名 | 类型 | 描述 |
|
|
289
|
+
|-------|------|------|
|
|
290
|
+
| waitForSelectors | array | 等待页面中特定元素出现的选择器数组,在继续处理前会等待这些元素加载完成 |
|
|
291
|
+
| waitForVisible | boolean | 是否等待元素可见,默认为 false,仅检查元素是否存在于 DOM 中 |
|
|
292
|
+
| waitForMaxTime | number | 等待元素出现的最大时间(毫秒),默认为 10000(10秒) |
|
|
27
293
|
|
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const fp = require('fastify-plugin');
|
|
2
|
-
const path = require('path');
|
|
2
|
+
const path = require('node:path');
|
|
3
3
|
const packageJson = require('./package.json');
|
|
4
4
|
const merge = require('lodash/merge');
|
|
5
5
|
|
|
@@ -11,6 +11,8 @@ module.exports = fp(
|
|
|
11
11
|
prefix: `/api/v${packageJson.version.split('.')[0]}/puppeteer`,
|
|
12
12
|
maxCacheKeys: 1000,
|
|
13
13
|
maxTaskSize: 100,
|
|
14
|
+
pageWidth: 1366,
|
|
15
|
+
pageHeight: 768,
|
|
14
16
|
puppeteerOptions: {},
|
|
15
17
|
authenticate: []
|
|
16
18
|
},
|
|
@@ -21,8 +23,10 @@ module.exports = fp(
|
|
|
21
23
|
require('@fastify/static'),
|
|
22
24
|
Object.assign({}, options.static, {
|
|
23
25
|
root: options.root,
|
|
26
|
+
prefix: `${options.prefix}/static`,
|
|
24
27
|
index: false,
|
|
25
|
-
list: false
|
|
28
|
+
list: false,
|
|
29
|
+
decorateReply: false
|
|
26
30
|
})
|
|
27
31
|
);
|
|
28
32
|
|
package/libs/controllers.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const fp = require('fastify-plugin');
|
|
2
|
+
const path = require('node:path');
|
|
2
3
|
module.exports = fp(async (fastify, options) => {
|
|
3
4
|
const { services } = fastify.puppeteer;
|
|
4
5
|
fastify.post(
|
|
@@ -20,7 +21,7 @@ module.exports = fp(async (fastify, options) => {
|
|
|
20
21
|
},
|
|
21
22
|
async (request, reply) => {
|
|
22
23
|
const filename = await services.parseHtmlToPdf({ html: request.body.content, options: request.body.options });
|
|
23
|
-
return reply.sendFile(filename);
|
|
24
|
+
return reply.sendFile(filename, { root: options.root });
|
|
24
25
|
}
|
|
25
26
|
);
|
|
26
27
|
|
|
@@ -51,7 +52,7 @@ module.exports = fp(async (fastify, options) => {
|
|
|
51
52
|
htmlList: request.body.contentList,
|
|
52
53
|
options: request.body.options
|
|
53
54
|
});
|
|
54
|
-
return reply.sendFile(filename);
|
|
55
|
+
return reply.sendFile(filename, { root: options.root });
|
|
55
56
|
}
|
|
56
57
|
);
|
|
57
58
|
|
|
@@ -82,7 +83,7 @@ module.exports = fp(async (fastify, options) => {
|
|
|
82
83
|
htmlList: request.body.contentList,
|
|
83
84
|
options: request.body.options
|
|
84
85
|
});
|
|
85
|
-
return reply.sendFile(filename);
|
|
86
|
+
return reply.sendFile(filename, { root: options.root });
|
|
86
87
|
}
|
|
87
88
|
);
|
|
88
89
|
|
|
@@ -108,7 +109,7 @@ module.exports = fp(async (fastify, options) => {
|
|
|
108
109
|
html: request.body.content,
|
|
109
110
|
options: request.body.options
|
|
110
111
|
});
|
|
111
|
-
return reply.sendFile(filename);
|
|
112
|
+
return reply.sendFile(filename, { root: options.root });
|
|
112
113
|
}
|
|
113
114
|
);
|
|
114
115
|
|
|
@@ -131,7 +132,7 @@ module.exports = fp(async (fastify, options) => {
|
|
|
131
132
|
},
|
|
132
133
|
async (request, reply) => {
|
|
133
134
|
const filename = await services.parseUrlToPdf({ url: request.body.url, options: request.body.options });
|
|
134
|
-
return reply.sendFile(filename);
|
|
135
|
+
return reply.sendFile(filename, { root: options.root });
|
|
135
136
|
}
|
|
136
137
|
);
|
|
137
138
|
|
|
@@ -157,7 +158,7 @@ module.exports = fp(async (fastify, options) => {
|
|
|
157
158
|
urlList: request.body.urlList,
|
|
158
159
|
options: request.body.options
|
|
159
160
|
});
|
|
160
|
-
return reply.sendFile(filename);
|
|
161
|
+
return reply.sendFile(filename, { root: options.root });
|
|
161
162
|
}
|
|
162
163
|
);
|
|
163
164
|
|
|
@@ -180,12 +181,12 @@ module.exports = fp(async (fastify, options) => {
|
|
|
180
181
|
}
|
|
181
182
|
},
|
|
182
183
|
async (request, reply) => {
|
|
183
|
-
const
|
|
184
|
+
const filename = await services.parseUrlToPhoto({
|
|
184
185
|
url: request.body.url,
|
|
185
186
|
selector: request.body.selector,
|
|
186
187
|
options: request.body.options
|
|
187
188
|
});
|
|
188
|
-
return reply.sendFile(filename);
|
|
189
|
+
return reply.sendFile(filename, { root: options.root });
|
|
189
190
|
}
|
|
190
191
|
);
|
|
191
192
|
|
|
@@ -209,11 +210,11 @@ module.exports = fp(async (fastify, options) => {
|
|
|
209
210
|
},
|
|
210
211
|
async (request, reply) => {
|
|
211
212
|
const filename = await services.parseUrlToPhotoBatch({
|
|
212
|
-
urlList: request.body.
|
|
213
|
+
urlList: request.body.urlList,
|
|
213
214
|
selector: request.body.selector,
|
|
214
215
|
options: request.body.options
|
|
215
216
|
});
|
|
216
|
-
return reply.sendFile(filename);
|
|
217
|
+
return reply.sendFile(filename, { root: options.root });
|
|
217
218
|
}
|
|
218
219
|
);
|
|
219
220
|
});
|
package/libs/core/setup.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const puppeteer = require('puppeteer');
|
|
2
|
-
const createDeferred = require('
|
|
2
|
+
const createDeferred = require('@kne/create-deferred');
|
|
3
3
|
|
|
4
4
|
module.exports = async options => {
|
|
5
5
|
options = Object.assign({ maxTaskSize: 100 }, options);
|
|
@@ -9,7 +9,7 @@ module.exports = async options => {
|
|
|
9
9
|
task: async callback => {
|
|
10
10
|
return await deferred(async () => {
|
|
11
11
|
const page = await browser.newPage();
|
|
12
|
-
await page.setViewport({ width:
|
|
12
|
+
await page.setViewport({ width: options.pageWidth, height: options.pageHeight });
|
|
13
13
|
const output = await (async () => {
|
|
14
14
|
try {
|
|
15
15
|
return {
|
package/libs/core/setup.test.js
CHANGED
|
@@ -2,7 +2,7 @@ const setup = require('./setup');
|
|
|
2
2
|
(async () => {
|
|
3
3
|
const puppeteerPage = await setup({
|
|
4
4
|
puppeteerOptions: {
|
|
5
|
-
executablePath: '
|
|
5
|
+
executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
|
|
6
6
|
}
|
|
7
7
|
});
|
|
8
8
|
|
package/libs/services.js
CHANGED
|
@@ -73,11 +73,19 @@ module.exports = fp(async (fastify, options) => {
|
|
|
73
73
|
});
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
-
const parseUrlToPdf = memoCache('parseUrlToPdf', async ({ url, options }) => {
|
|
76
|
+
const parseUrlToPdf = memoCache('parseUrlToPdf', async ({ url, options = {} }) => {
|
|
77
77
|
return await puppeteerPage.task(async ({ page }) => {
|
|
78
78
|
await page.goto(url, {
|
|
79
79
|
waitUntil: 'networkidle2'
|
|
80
80
|
});
|
|
81
|
+
await Promise.all(
|
|
82
|
+
(options.waitForSelectors || []).map(waitForSelector => {
|
|
83
|
+
return page.waitForSelector(waitForSelector, {
|
|
84
|
+
visible: options.waitForVisible || false,
|
|
85
|
+
timeout: options.waitForMaxTime || 10000
|
|
86
|
+
});
|
|
87
|
+
})
|
|
88
|
+
);
|
|
81
89
|
return await page.pdf(
|
|
82
90
|
Object.assign(
|
|
83
91
|
{},
|
|
@@ -98,11 +106,19 @@ module.exports = fp(async (fastify, options) => {
|
|
|
98
106
|
});
|
|
99
107
|
});
|
|
100
108
|
|
|
101
|
-
const parseUrlToPhoto = memoCache('parseUrlToPhoto', async ({ url, selector, options }) => {
|
|
109
|
+
const parseUrlToPhoto = memoCache('parseUrlToPhoto', async ({ url, selector, options = {} }) => {
|
|
102
110
|
return await puppeteerPage.task(async ({ page }) => {
|
|
103
111
|
await page.goto(url, {
|
|
104
112
|
waitUntil: 'networkidle2'
|
|
105
113
|
});
|
|
114
|
+
await Promise.all(
|
|
115
|
+
(options.waitForSelectors || []).map(waitForSelector => {
|
|
116
|
+
return page.waitForSelector(waitForSelector, {
|
|
117
|
+
visible: options.waitForVisible || false,
|
|
118
|
+
timeout: options.waitForMaxTime || 10000
|
|
119
|
+
});
|
|
120
|
+
})
|
|
121
|
+
);
|
|
106
122
|
if (selector) {
|
|
107
123
|
await page.locator(selector).wait();
|
|
108
124
|
const element = await page.$(selector);
|
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kne/fastify-puppeteer",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "用于操作无头浏览器截图保存pdf等",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"init": "husky",
|
|
8
8
|
"dev": "nodemon ./tests/server.js",
|
|
9
9
|
"start": "node ./index.js",
|
|
10
|
-
"doc": "node ./open-api.js",
|
|
11
10
|
"build:md": "npx @kne/md-doc",
|
|
12
11
|
"start:md": "npx @kne/md-doc --watch",
|
|
13
12
|
"prettier": "prettier --config .prettierrc --write '{libs/**/*,index}.{js,jsx,ts,tsx,json,css,scss}'",
|
|
@@ -37,12 +36,14 @@
|
|
|
37
36
|
"url": "https://github.com/kne-union/fastify-puppeteer/issues"
|
|
38
37
|
},
|
|
39
38
|
"homepage": "https://github.com/kne-union/fastify-puppeteer#readme",
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"@kne/fastify-namespace": "*",
|
|
41
|
+
"fastify-plugin": ">=5"
|
|
42
|
+
},
|
|
40
43
|
"dependencies": {
|
|
41
|
-
"@fastify/static": "^
|
|
42
|
-
"@kne/
|
|
44
|
+
"@fastify/static": "^8.2.0",
|
|
45
|
+
"@kne/create-deferred": "^0.1.1",
|
|
43
46
|
"compressing": "^1.10.1",
|
|
44
|
-
"fastify": "^4.27.0",
|
|
45
|
-
"fastify-plugin": "^4.5.1",
|
|
46
47
|
"file-type": "^16.5.4",
|
|
47
48
|
"fs-extra": "^11.2.0",
|
|
48
49
|
"lodash": "^4.17.21",
|
|
@@ -53,11 +54,12 @@
|
|
|
53
54
|
"uuid": "^10.0.0"
|
|
54
55
|
},
|
|
55
56
|
"devDependencies": {
|
|
56
|
-
"@fastify
|
|
57
|
+
"@kne/fastify-namespace": "^1.1.2",
|
|
58
|
+
"fastify": "^5.4.0",
|
|
59
|
+
"fastify-plugin": "^5.0.1",
|
|
57
60
|
"husky": "^9.0.11",
|
|
58
61
|
"nodemon": "^3.1.3",
|
|
59
62
|
"prettier": "^3.2.5",
|
|
60
|
-
"qs": "^6.
|
|
61
|
-
"sqlite3": "^5.1.7"
|
|
63
|
+
"qs": "^6.14.0"
|
|
62
64
|
}
|
|
63
65
|
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
const createDeferred = size => {
|
|
2
|
-
const queue = [];
|
|
3
|
-
let runningCount = 0;
|
|
4
|
-
const checkRun = () => {
|
|
5
|
-
if (queue.length === 0) {
|
|
6
|
-
runningCount = 0;
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
if (runningCount < size) {
|
|
10
|
-
const callback = queue.shift();
|
|
11
|
-
runningCount += 1;
|
|
12
|
-
callback().finally(() => {
|
|
13
|
-
runningCount -= 1;
|
|
14
|
-
checkRun();
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
return callback => {
|
|
19
|
-
return new Promise(resolve => {
|
|
20
|
-
queue.push(() => {
|
|
21
|
-
const promise = Promise.resolve().then(() => callback());
|
|
22
|
-
resolve(promise);
|
|
23
|
-
return promise;
|
|
24
|
-
});
|
|
25
|
-
checkRun();
|
|
26
|
-
});
|
|
27
|
-
};
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
module.exports = createDeferred;
|