manhuagui-cli 1.0.0 → 1.0.2

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.
Files changed (46) hide show
  1. package/README.md +172 -58
  2. package/README_EN.md +172 -56
  3. package/dist/lib/browser.d.ts +4 -0
  4. package/dist/lib/browser.d.ts.map +1 -0
  5. package/dist/lib/browser.js +22 -0
  6. package/dist/lib/browser.js.map +1 -0
  7. package/dist/lib/chapter.d.ts +19 -3
  8. package/dist/lib/chapter.d.ts.map +1 -1
  9. package/dist/lib/chapter.js +142 -63
  10. package/dist/lib/chapter.js.map +1 -1
  11. package/dist/lib/cli.d.ts +20 -0
  12. package/dist/lib/cli.d.ts.map +1 -1
  13. package/dist/lib/cli.js +142 -131
  14. package/dist/lib/cli.js.map +1 -1
  15. package/dist/lib/comic.d.ts.map +1 -1
  16. package/dist/lib/comic.js +26 -17
  17. package/dist/lib/comic.js.map +1 -1
  18. package/dist/lib/config.d.ts +26 -19
  19. package/dist/lib/config.d.ts.map +1 -1
  20. package/dist/lib/config.js +92 -33
  21. package/dist/lib/config.js.map +1 -1
  22. package/dist/lib/logger.d.ts +3 -0
  23. package/dist/lib/logger.d.ts.map +1 -1
  24. package/dist/lib/logger.js +6 -2
  25. package/dist/lib/logger.js.map +1 -1
  26. package/dist/lib/progress.d.ts +11 -5
  27. package/dist/lib/progress.d.ts.map +1 -1
  28. package/dist/lib/progress.js +17 -15
  29. package/dist/lib/progress.js.map +1 -1
  30. package/dist/lib/prompts.d.ts +1 -0
  31. package/dist/lib/prompts.d.ts.map +1 -1
  32. package/dist/lib/prompts.js +9 -12
  33. package/dist/lib/prompts.js.map +1 -1
  34. package/dist/lib/speed.d.ts +16 -0
  35. package/dist/lib/speed.d.ts.map +1 -0
  36. package/dist/lib/speed.js +83 -0
  37. package/dist/lib/speed.js.map +1 -0
  38. package/dist/lib/tasks.d.ts +21 -0
  39. package/dist/lib/tasks.d.ts.map +1 -0
  40. package/dist/lib/tasks.js +124 -0
  41. package/dist/lib/tasks.js.map +1 -0
  42. package/dist/lib/ui.d.ts +33 -0
  43. package/dist/lib/ui.d.ts.map +1 -0
  44. package/dist/lib/ui.js +216 -0
  45. package/dist/lib/ui.js.map +1 -0
  46. package/package.json +5 -3
package/README.md CHANGED
@@ -1,28 +1,72 @@
1
1
  # manhuagui-cli
2
2
 
3
- > 漫画柜 (manhuagui.com) 漫画下载命令行工具
3
+ <p align="center">
4
+ <a href="https://www.npmjs.com/package/manhuagui-cli"><img src="https://img.shields.io/npm/v/manhuagui-cli" alt="npm version"></a>
5
+ <a href="https://nodejs.org/"><img src="https://img.shields.io/badge/node-%3E%3D22-brightgreen" alt="Node.js >= 22"></a>
6
+ <a href="./LICENSE"><img src="https://img.shields.io/npm/l/manhuagui-cli" alt="License: MIT"></a>
7
+ </p>
8
+
9
+ <p align="center">漫画柜 (manhuagui.com) 漫画下载命令行工具</p>
10
+
11
+ ---
12
+
13
+ ## 目录
14
+
15
+ - [快速开始](#快速开始)
16
+ - [功能特性](#功能特性)
17
+ - [安装](#安装)
18
+ - [使用方法](#使用方法)
19
+ - [交互模式](#交互模式)
20
+ - [命令行模式](#命令行模式)
21
+ - [选项](#选项)
22
+ - [配置](#配置)
23
+ - [优先级](#优先级)
24
+ - [配置文件](#配置文件)
25
+ - [环境变量](#环境变量)
26
+ - [输出目录结构](#输出目录结构)
27
+ - [开发](#开发)
28
+ - [变更日志](#变更日志)
29
+ - [许可协议](#许可协议)
30
+ - [免责声明](#免责声明)
31
+
32
+ ## 快速开始
4
33
 
5
- [English](README_EN.md)
34
+ ```bash
35
+ # 全局安装
36
+ npm install -g manhuagui-cli
6
37
 
7
- ## 功能特性
38
+ # 下载漫画,按提示操作
39
+ manhuagui-cli
8
40
 
9
- - 交互式命令行界面,也支持命令行参数直接运行
10
- - 自动解析漫画页面,列出所有章节与卷
11
- - 使用 Playwright 模拟浏览器请求,绕过反爬检测
12
- - 随机 User-Agent 和视口大小,模拟真实用户行为
13
- - CDN 节点自动轮换,图片下载失败时自动重试(最多 3 次)
14
- - 章节内图片并发下载,章节之间顺序处理并添加随机延迟
15
- - 断点续传:进度保存到 `progress.json`,中断后可通过 `--resume` / `-r` 继续
16
- - 下载目录结构清晰:`output/<漫画名>/<章节组>/<章节>/001.webp`
41
+ # 或者在命令行直接指定 URL
42
+ manhuagui-cli <URL>
17
43
 
18
- ## 系统要求
44
+ # 指定章节组
45
+ manhuagui-cli <URL> -s "单行本"
19
46
 
20
- - **Node.js** >= 22
21
- - **pnpm**(推荐)或 npm
47
+ # 预览模式,仅列出章节不下载
48
+ manhuagui-cli <URL> --dry-run
49
+
50
+ # 断点续传
51
+ manhuagui-cli <URL> --resume
52
+ ```
53
+
54
+ ## 功能特性
55
+
56
+ - **交互式界面**:无参数运行时进入交互提示模式,引导输入 URL、选择章节组
57
+ - **命令行模式**:支持完整 CLI 参数,适合脚本化和自动化场景
58
+ - **反爬虫绕过**:基于 Playwright 无头 Chromium 模拟浏览器请求,绕过反爬检测
59
+ - **身份伪装**:随机切换 User-Agent 和视口大小,模拟真实用户行为
60
+ - **CDN 容错**:图片下载时自动轮换 CDN 节点,失败自动重试(默认 3 次)
61
+ - **并发控制**:章节内图片并发下载,章节间顺序处理并加入随机延迟
62
+ - **实时进度显示**:终端进度条,展示下载速度、章节进度、整体进度及预计剩余时间
63
+ - **预览模式** (`--dry-run`):列出待下载章节而不实际下载,适合制定下载计划
64
+ - **断点续传**:进度自动保存至 `progress.json`,中断后通过 `--resume` / `-r` 继续
65
+ - **清晰目录结构**:`output/<漫画名>/<章节组>/<章节>/001.webp`
22
66
 
23
67
  ## 安装
24
68
 
25
- ### npm(推荐)
69
+ ### npm 全局安装(推荐)
26
70
 
27
71
  ```bash
28
72
  npm install -g manhuagui-cli
@@ -44,61 +88,127 @@ pnpm link --global
44
88
 
45
89
  ### 交互模式
46
90
 
91
+ 不带参数运行,工具会引导你完成每一步操作:
92
+
47
93
  ```bash
48
- pnpm dev
49
- # 或编译后:
50
- pnpm build
51
- node dist/index.js
94
+ manhuagui-cli
52
95
  ```
53
96
 
54
- 按提示输入漫画 URL,选择要下载的章节组,确认后开始下载。
97
+ 交互流程:
98
+
99
+ 1. 输入漫画 URL
100
+ 2. 工具自动解析漫画信息(标题、章节组、章节列表)
101
+ 3. 选择要下载的章节组(支持多选)
102
+ 4. 确认后开始下载
103
+
104
+ ```text
105
+ manhuagui-cli v1.0.1
106
+
107
+ Input comic URL:
108
+ https://www.manhuagui.com/comic/12345/
109
+
110
+ Parsing comic page...
111
+ 某个漫画
112
+
113
+ Which sections to download?
114
+ [x] 单行本 (12 chapters)
115
+ [ ] 单话 (200 chapters)
116
+ [x] 番外 (3 chapters)
117
+ Confirm
118
+
119
+ Overall 3/4 ch · 6/8 pg · 45s elapsed · ~15s
120
+ [====================> ] 50%
121
+ Ch.3 2/2 pg · 单行本 · 93.5 KB/s · ~15s
122
+ ```
55
123
 
56
124
  ### 命令行模式
57
125
 
58
126
  ```bash
59
- node dist/index.js <URL> [选项]
60
- # 或全局安装后:
61
- manhuagui-cli <URL> [选项]
62
-
63
127
  # 查看帮助
64
- node dist/index.js --help
128
+ manhuagui-cli --help
65
129
 
66
- # 示例:下载指定章节组
67
- node dist/index.js https://www.manhuagui.com/comic/12345/ -s "单行本"
130
+ # 下载指定章节组
131
+ manhuagui-cli https://www.manhuagui.com/comic/12345/ -s "单行本"
68
132
 
69
- # 示例:下载指定章节
70
- node dist/index.js https://www.manhuagui.com/comic/12345/ -s "单话" -c "第01话"
133
+ # 下载指定章节
134
+ manhuagui-cli https://www.manhuagui.com/comic/12345/ -s "单话" -c "第01话"
71
135
 
72
- # 示例:断点续传
73
- node dist/index.js https://www.manhuagui.com/comic/12345/ --resume
136
+ # 指定输出目录
137
+ manhuagui-cli https://www.manhuagui.com/comic/12345/ -o ./my-comics
138
+
139
+ # 断点续传
140
+ manhuagui-cli https://www.manhuagui.com/comic/12345/ --resume
141
+
142
+ # 预览模式
143
+ manhuagui-cli https://www.manhuagui.com/comic/12345/ --dry-run
74
144
  ```
75
145
 
76
146
  ### 选项
77
147
 
78
- | 选项 | 简写 | 说明 |
79
- | ------------------ | ---- | ------------------------------------ |
80
- | `--section <name>` | `-s` | 指定要下载的章节组名称(默认:全部) |
81
- | `--chapter <name>` | `-c` | 指定要下载的章节名称 |
82
- | `--resume` | `-r` | 断点续传模式 |
83
- | `--help` | `-h` | 显示帮助信息 |
84
- | `--version` | `-v` | 显示版本号 |
148
+ | 选项 | 简写 | 默认值 | 说明 |
149
+ | ---------------------- | ----- | ------- | --------------------------------------------- |
150
+ | `--section <name>` | `-s` | 全部 | 指定要下载的章节组名称 |
151
+ | `--chapter <name>` | `-c` | | 指定要下载的章节名称 |
152
+ | `--output <dir>` | `-o` | `./output` | 下载输出目录 |
153
+ | `--concurrency <n>` | `-C` | `2` | 章节内图片并发下载数 |
154
+ | `--retry <n>` | | `3` | 图片下载重试次数 |
155
+ | `--log-level <level>` | | `info` | 日志级别:`debug` / `info` / `warn` / `error` |
156
+ | `--resume` | `-r` | — | 断点续传模式 |
157
+ | `--dry-run` | `-d` | — | 预览模式(不实际下载) |
158
+ | `--help` | `-h` | — | 显示帮助信息 |
159
+ | `--version` | `-v` | — | 显示版本号 |
85
160
 
86
- ## 环境变量
161
+ ## 配置
87
162
 
88
- 复制 `.env.example` 为 `.env`,根据需要修改:
163
+ CLI 参数外,还支持通过配置文件和环境变量调整行为。
89
164
 
90
- | 变量 | 默认值 | 说明 |
91
- | ------------------- | ---------- | ---------------------------------- |
92
- | `OUTPUT_BASE` | `./output` | 下载输出目录 |
93
- | `IMAGE_CONCURRENCY` | `2` | 章节内图片并发下载数 |
94
- | `DOWNLOAD_DELAY` | `3000` | 图片批次之间延迟(毫秒,0 禁用) |
95
- | `CHAPTER_DELAY_MIN` | `5000` | 章节间最小延迟(毫秒) |
96
- | `CHAPTER_DELAY_MAX` | `15000` | 章节间最大延迟(毫秒) |
97
- | `USER_AGENTS` | — | 自定义 User-Agent 列表(每行一个) |
165
+ ### 优先级
98
166
 
99
- ## 输出目录结构
167
+ ```
168
+ CLI 参数 > 配置文件 > 环境变量 > 默认值
169
+ ```
100
170
 
171
+ ### 配置文件
172
+
173
+ 支持两个位置的 JSON 配置文件,按需创建。项目级会覆盖全局级中相同的字段。
174
+
175
+ | 位置 | 路径 |
176
+ | ---------- | ---------------------------------------------------------------------------- |
177
+ | 项目级 | `<当前目录>/.manhuaguirc.json` |
178
+ | 全局 | `~/.config/manhuagui-cli/config.json` |
179
+ | (Windows) | `%USERPROFILE%\.config\manhuagui-cli\config.json` |
180
+
181
+ ```json
182
+ {
183
+ "outputBase": "./downloads",
184
+ "imageConcurrency": 4,
185
+ "retryCount": 5,
186
+ "logLevel": "debug"
187
+ }
101
188
  ```
189
+
190
+ 所有字段均为可选,未指定的字段将沿用默认值。
191
+
192
+ ### 环境变量
193
+
194
+ 将 `.env.example` 复制为 `.env`,根据需要修改。也支持直接设置系统环境变量。
195
+
196
+ | 变量 | 默认值 | 说明 |
197
+ | --------------------- | ---------- | -------------------------------------------- |
198
+ | `OUTPUT_BASE` | `./output` | 下载输出目录 |
199
+ | `IMAGE_CONCURRENCY` | `2` | 章节内图片并发下载数 |
200
+ | `DOWNLOAD_DELAY` | `3000` | 图片批次间延迟(毫秒,设为 0 禁用) |
201
+ | `CHAPTER_DELAY_MIN` | `3000` | 章节间最小延迟(毫秒) |
202
+ | `CHAPTER_DELAY_MAX` | `6000` | 章节间最大延迟(毫秒) |
203
+ | `RETRY_COUNT` | `3` | 图片下载重试次数 |
204
+ | `RETRY_BACKOFF_BASE` | `1000` | 重试退避基值(毫秒),第 N 次重试等待 N * base |
205
+ | `IMAGE_LOAD_DELAY` | `200` | 翻页后等待图片加载时间(毫秒) |
206
+ | `LOG_LEVEL` | `info` | 日志级别:`debug` / `info` / `warn` / `error` |
207
+ | `USER_AGENTS` | — | 自定义 User-Agent 列表(每行一个) |
208
+
209
+ ## 输出目录结构
210
+
211
+ ```text
102
212
  output/
103
213
  └── <漫画名>/
104
214
  ├── urls.json # 章节图片 URL 清单
@@ -113,18 +223,22 @@ output/
113
223
  ## 开发
114
224
 
115
225
  ```bash
116
- pnpm install # 安装依赖
117
- pnpm dev # 开发模式运行(直接运行 TypeScript)
118
- pnpm build # 编译 TypeScript
119
- pnpm typecheck # 类型检查
120
- pnpm test # 运行测试
121
- pnpm check # 代码检查和格式化检查
122
- pnpm format # 自动格式化
226
+ pnpm install # 安装依赖
227
+ pnpm dev # 开发模式运行(直接运行 TypeScript)
228
+ pnpm build # 编译 TypeScript
229
+ pnpm typecheck # 类型检查
230
+ pnpm test # 运行测试
231
+ pnpm check # 代码检查和格式化检查(Biome)
232
+ pnpm format # 自动格式化
123
233
  ```
124
234
 
125
- ## License
235
+ ## 变更日志
236
+
237
+ 详见 [CHANGELOG.md](./CHANGELOG.md)。
238
+
239
+ ## 许可协议
126
240
 
127
- [MIT](LICENSE)
241
+ [MIT](./LICENSE)
128
242
 
129
243
  ## 免责声明
130
244
 
package/README_EN.md CHANGED
@@ -1,28 +1,74 @@
1
1
  # manhuagui-cli
2
2
 
3
- > CLI tool for downloading manhua from manhuagui.com
3
+ <p align="center">
4
+ <a href="https://www.npmjs.com/package/manhuagui-cli"><img src="https://img.shields.io/npm/v/manhuagui-cli" alt="npm version"></a>
5
+ <a href="https://nodejs.org/"><img src="https://img.shields.io/badge/node-%3E%3D22-brightgreen" alt="Node.js >= 22"></a>
6
+ <a href="./LICENSE"><img src="https://img.shields.io/npm/l/manhuagui-cli" alt="License: MIT"></a>
7
+ </p>
8
+
9
+ <p align="center">CLI tool for downloading manhua from manhuagui.com</p>
4
10
 
5
11
  [中文](README.md)
6
12
 
7
- ## Features
13
+ ---
14
+
15
+ ## Table of Contents
16
+
17
+ - [Quick Start](#quick-start)
18
+ - [Features](#features)
19
+ - [Installation](#installation)
20
+ - [Usage](#usage)
21
+ - [Interactive Mode](#interactive-mode)
22
+ - [CLI Mode](#cli-mode)
23
+ - [Options](#options)
24
+ - [Configuration](#configuration)
25
+ - [Priority](#priority)
26
+ - [Config Files](#config-files)
27
+ - [Environment Variables](#environment-variables)
28
+ - [Output Structure](#output-structure)
29
+ - [Development](#development)
30
+ - [Changelog](#changelog)
31
+ - [License](#license)
32
+ - [Disclaimer](#disclaimer)
33
+
34
+ ## Quick Start
35
+
36
+ ```bash
37
+ # Install globally
38
+ npm install -g manhuagui-cli
8
39
 
9
- - Interactive CLI with prompts, also supports direct CLI args
10
- - Auto-parses comic pages, lists all sections and chapters
11
- - Uses Playwright headless browser to bypass anti-bot measures
12
- - Random User-Agent and viewport rotation to simulate real users
13
- - CDN host rotation with automatic retry (up to 3 attempts) on image download failure
14
- - Concurrent image downloads within a chapter, sequential chapters with human-like delays
15
- - Resumable downloads: progress saved to `progress.json`, resume with `--resume` / `-r`
16
- - Clean output structure: `output/<comic-title>/<section>/<chapter>/001.webp`
40
+ # Download a comic, follow the prompts
41
+ manhuagui-cli
17
42
 
18
- ## Requirements
43
+ # Or specify a URL directly
44
+ manhuagui-cli <URL>
19
45
 
20
- - **Node.js** >= 22
21
- - **pnpm** (recommended) or npm
46
+ # Filter by section name
47
+ manhuagui-cli <URL> -s "Single Volumes"
48
+
49
+ # Preview mode, list chapters without downloading
50
+ manhuagui-cli <URL> --dry-run
51
+
52
+ # Resume interrupted download
53
+ manhuagui-cli <URL> --resume
54
+ ```
55
+
56
+ ## Features
57
+
58
+ - **Interactive mode**: Running without arguments launches an interactive prompt that guides you through URL input and section selection
59
+ - **CLI mode**: Full CLI argument support for scripting and automation
60
+ - **Anti-bot evasion**: Uses Playwright headless Chromium to mimic real browser requests and bypass anti-bot measures
61
+ - **Identity rotation**: Randomly switches User-Agent and viewport size to simulate real user behavior
62
+ - **CDN resilience**: Automatically rotates CDN hosts on image download failure with retry (default 3 attempts)
63
+ - **Concurrency control**: Concurrent image downloads within a chapter, sequential chapters with randomized delays
64
+ - **Real-time progress**: Terminal progress bars displaying speed, per-chapter progress, overall progress, and ETA
65
+ - **Preview mode** (`--dry-run`): Lists pending chapters without downloading, useful for planning
66
+ - **Resumable downloads**: Progress automatically saved to `progress.json`, resume with `--resume` / `-r`
67
+ - **Clean directory structure**: `output/<comic-title>/<section>/<chapter>/001.webp`
22
68
 
23
69
  ## Installation
24
70
 
25
- ### npm (Recommended)
71
+ ### npm Global Install (Recommended)
26
72
 
27
73
  ```bash
28
74
  npm install -g manhuagui-cli
@@ -44,61 +90,127 @@ pnpm link --global
44
90
 
45
91
  ### Interactive Mode
46
92
 
93
+ Run without arguments and the tool will guide you through each step:
94
+
47
95
  ```bash
48
- pnpm dev
49
- # or build first:
50
- pnpm build
51
- node dist/index.js
96
+ manhuagui-cli
52
97
  ```
53
98
 
54
- Follow prompts to enter comic URL, select sections, and confirm download.
99
+ Interactive flow:
100
+
101
+ 1. Enter the comic URL
102
+ 2. The tool parses comic metadata (title, sections, chapter list)
103
+ 3. Select which sections to download (multi-select supported)
104
+ 4. Confirm and start downloading
105
+
106
+ ```text
107
+ manhuagui-cli v1.0.1
108
+
109
+ Input comic URL:
110
+ https://www.manhuagui.com/comic/12345/
111
+
112
+ Parsing comic page...
113
+ Some Comic Title
114
+
115
+ Which sections to download?
116
+ [x] Single Volumes (12 chapters)
117
+ [ ] Serialized (200 chapters)
118
+ [x] Extras (3 chapters)
119
+ Confirm
120
+
121
+ Overall 3/4 ch · 6/8 pg · 45s elapsed · ~15s
122
+ [====================> ] 50%
123
+ Ch.3 2/2 pg · Single Volumes · 93.5 KB/s · ~15s
124
+ ```
55
125
 
56
126
  ### CLI Mode
57
127
 
58
128
  ```bash
59
- node dist/index.js <URL> [options]
60
- # or if linked globally:
61
- manhuagui-cli <URL> [options]
62
-
63
129
  # Show help
64
- node dist/index.js --help
130
+ manhuagui-cli --help
131
+
132
+ # Download a specific section
133
+ manhuagui-cli https://www.manhuagui.com/comic/12345/ -s "Single Volumes"
65
134
 
66
- # Example: download specific section
67
- node dist/index.js https://www.manhuagui.com/comic/12345/ -s "单行本"
135
+ # Download a specific chapter
136
+ manhuagui-cli https://www.manhuagui.com/comic/12345/ -s "Serialized" -c "Chapter 01"
68
137
 
69
- # Example: download specific chapter
70
- node dist/index.js https://www.manhuagui.com/comic/12345/ -s "单话" -c "第01话"
138
+ # Specify output directory
139
+ manhuagui-cli https://www.manhuagui.com/comic/12345/ -o ./my-comics
71
140
 
72
- # Example: resume interrupted download
73
- node dist/index.js https://www.manhuagui.com/comic/12345/ --resume
141
+ # Resume interrupted download
142
+ manhuagui-cli https://www.manhuagui.com/comic/12345/ --resume
143
+
144
+ # Preview mode
145
+ manhuagui-cli https://www.manhuagui.com/comic/12345/ --dry-run
74
146
  ```
75
147
 
76
148
  ### Options
77
149
 
78
- | Option | Alias | Description |
79
- | ------------------ | ----- | ---------------------------------------------- |
80
- | `--section <name>` | `-s` | Download only the named section (default: all) |
81
- | `--chapter <name>` | `-c` | Download only the named chapter |
82
- | `--resume` | `-r` | Resume from previous interrupted download |
83
- | `--help` | `-h` | Show help |
84
- | `--version` | `-v` | Show version |
150
+ | Option | Alias | Default | Description |
151
+ | --------------------- | ----- | -------- | -------------------------------------------------------------- |
152
+ | `--section <name>` | `-s` | All | Download only the named section |
153
+ | `--chapter <name>` | `-c` | — | Download only the named chapter |
154
+ | `--output <dir>` | `-o` | `./output` | Download output directory |
155
+ | `--concurrency <n>` | `-C` | `2` | Concurrent image downloads per chapter |
156
+ | `--retry <n>` | | `3` | Retry count per image download |
157
+ | `--log-level <level>` | | `info` | Log level: `debug` / `info` / `warn` / `error` |
158
+ | `--resume` | `-r` | — | Resume from previous interrupted download |
159
+ | `--dry-run` | `-d` | — | Preview mode (list chapters without downloading) |
160
+ | `--help` | `-h` | — | Show help |
161
+ | `--version` | `-v` | — | Show version |
85
162
 
86
- ## Environment Variables
163
+ ## Configuration
87
164
 
88
- Copy `.env.example` to `.env` and modify as needed:
165
+ In addition to CLI arguments, behavior can be customized via config files and environment variables.
89
166
 
90
- | Variable | Default | Description |
91
- | ------------------- | ---------- | -------------------------------------- |
92
- | `OUTPUT_BASE` | `./output` | Download output directory |
93
- | `IMAGE_CONCURRENCY` | `2` | Concurrent image downloads per chapter |
94
- | `DOWNLOAD_DELAY` | `3000` | Delay between image batches (ms) |
95
- | `CHAPTER_DELAY_MIN` | `5000` | Min delay between chapters (ms) |
96
- | `CHAPTER_DELAY_MAX` | `15000` | Max delay between chapters (ms) |
97
- | `USER_AGENTS` | — | Custom User-Agent pool, one per line |
167
+ ### Priority
98
168
 
99
- ## Output Structure
169
+ ```
170
+ CLI args > config files > environment variables > defaults
171
+ ```
172
+
173
+ ### Config Files
174
+
175
+ Two JSON config file locations are supported. Project-level overrides global-level fields.
176
+
177
+ | Location | Path |
178
+ | ------------ | ---------------------------------------------------------------------------- |
179
+ | Project | `<cwd>/.manhuaguirc.json` |
180
+ | Global | `~/.config/manhuagui-cli/config.json` |
181
+ | (Windows) | `%USERPROFILE%\.config\manhuagui-cli\config.json` |
100
182
 
183
+ ```json
184
+ {
185
+ "outputBase": "./downloads",
186
+ "imageConcurrency": 4,
187
+ "retryCount": 5,
188
+ "logLevel": "debug"
189
+ }
101
190
  ```
191
+
192
+ All fields are optional; defaults are used for any omitted field.
193
+
194
+ ### Environment Variables
195
+
196
+ Copy `.env.example` to `.env` and modify as needed. System environment variables are also supported.
197
+
198
+ | Variable | Default | Description |
199
+ | --------------------- | ---------- | ------------------------------------------------------- |
200
+ | `OUTPUT_BASE` | `./output` | Download output directory |
201
+ | `IMAGE_CONCURRENCY` | `2` | Concurrent image downloads per chapter |
202
+ | `DOWNLOAD_DELAY` | `3000` | Delay between image batches (ms, 0 to disable) |
203
+ | `CHAPTER_DELAY_MIN` | `3000` | Min delay between chapters (ms) |
204
+ | `CHAPTER_DELAY_MAX` | `6000` | Max delay between chapters (ms) |
205
+ | `RETRY_COUNT` | `3` | Retry count per image download |
206
+ | `RETRY_BACKOFF_BASE` | `1000` | Retry backoff base (ms), wait `N * base` on Nth retry |
207
+ | `IMAGE_LOAD_DELAY` | `200` | Wait after page turn for image to load (ms) |
208
+ | `LOG_LEVEL` | `info` | Log level: `debug` / `info` / `warn` / `error` |
209
+ | `USER_AGENTS` | — | Custom User-Agent pool, one per line |
210
+
211
+ ## Output Structure
212
+
213
+ ```text
102
214
  output/
103
215
  └── <comic-title>/
104
216
  ├── urls.json # Chapter image URL manifest
@@ -113,18 +225,22 @@ output/
113
225
  ## Development
114
226
 
115
227
  ```bash
116
- pnpm install # Install dependencies
117
- pnpm dev # Run in dev mode (TypeScript directly)
118
- pnpm build # Compile TypeScript
119
- pnpm typecheck # Type check
120
- pnpm test # Run tests
121
- pnpm check # Lint and format check
122
- pnpm format # Auto-fix formatting
228
+ pnpm install # Install dependencies
229
+ pnpm dev # Run in dev mode (TypeScript directly)
230
+ pnpm build # Compile TypeScript
231
+ pnpm typecheck # Type check
232
+ pnpm test # Run tests
233
+ pnpm check # Lint and format check (Biome)
234
+ pnpm format # Auto-fix formatting
123
235
  ```
124
236
 
237
+ ## Changelog
238
+
239
+ See [CHANGELOG.md](./CHANGELOG.md).
240
+
125
241
  ## License
126
242
 
127
- [MIT](LICENSE)
243
+ [MIT](./LICENSE)
128
244
 
129
245
  ## Disclaimer
130
246
 
@@ -0,0 +1,4 @@
1
+ import type { Browser, BrowserContext, Page } from "playwright";
2
+ export declare function createBrowserContext(browser: Browser): Promise<BrowserContext>;
3
+ export declare function handleAdultCheck(page: Page, waitFor?: string): Promise<void>;
4
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/lib/browser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAIhE,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,CAQpF;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASlF"}
@@ -0,0 +1,22 @@
1
+ import { config, pickUserAgent } from "./config.js";
2
+ import { randInt } from "./utils.js";
3
+ export async function createBrowserContext(browser) {
4
+ return browser.newContext({
5
+ userAgent: pickUserAgent(),
6
+ viewport: {
7
+ width: randInt(config.viewportMinWidth, config.viewportMaxWidth),
8
+ height: randInt(config.viewportMinHeight, config.viewportMaxHeight),
9
+ },
10
+ });
11
+ }
12
+ export async function handleAdultCheck(page, waitFor) {
13
+ const checkAdult = await page.$("#checkAdult");
14
+ if (checkAdult) {
15
+ await checkAdult.click();
16
+ if (waitFor) {
17
+ await page.waitForSelector(waitFor, { timeout: config.adultSelectorTimeout });
18
+ await page.waitForTimeout(config.adultClickSettleDelay);
19
+ }
20
+ }
21
+ }
22
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/lib/browser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAAgB;IACzD,OAAO,OAAO,CAAC,UAAU,CAAC;QACxB,SAAS,EAAE,aAAa,EAAE;QAC1B,QAAQ,EAAE;YACR,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,CAAC;YAChE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,CAAC;SACpE;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAU,EAAE,OAAgB;IACjE,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAC/C,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,oBAAoB,EAAE,CAAC,CAAC;YAC9E,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -1,6 +1,22 @@
1
- import type { Browser } from "playwright";
1
+ import type { Browser, Page as PlaywrightPage, Response } from "playwright";
2
+ import type { SpeedTracker } from "./speed.js";
2
3
  export declare function computePadLength(count: number): number;
3
4
  export declare function extractExtension(url: string): string;
4
- export declare function buildFilePath(outputDir: string, index: number, padLen: number, ext: string): string;
5
- export declare function extractChapterImages(chapterUrl: string, browser: Browser, outputDir: string): Promise<string[]>;
5
+ export declare function buildFilePath(opts: {
6
+ outputDir: string;
7
+ index: number;
8
+ padLen: number;
9
+ ext: string;
10
+ }): string;
11
+ export declare function getPageCount(page: PlaywrightPage): Promise<number>;
12
+ export declare function getSubPageUrls(page: PlaywrightPage): Promise<string[]>;
13
+ export declare function collectImageUrls(page: PlaywrightPage, pageCount: number): Promise<string[]>;
14
+ export declare function validateImageResponse(response: Response | null): void;
15
+ export declare function extractChapterImages(opts: {
16
+ chapterUrl: string;
17
+ browser: Browser;
18
+ outputDir: string;
19
+ tracker: SpeedTracker;
20
+ onProgress?: (downloaded: number, total: number, bytes: number) => void;
21
+ }): Promise<string[]>;
6
22
  //# sourceMappingURL=chapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chapter.d.ts","sourceRoot":"","sources":["../../src/lib/chapter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAA0C,MAAM,YAAY,CAAC;AAqBlF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGpD;AAED,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,GACV,MAAM,CAGR;AAmID,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC,CAgCnB"}
1
+ {"version":3,"file":"chapter.d.ts","sourceRoot":"","sources":["../../src/lib/chapter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAkB,IAAI,IAAI,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAK5F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGpD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb,GAAG,MAAM,CAGT;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAaxE;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAa5E;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA8BjG;AAYD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,GAAG,IAAI,CAQrE;AAsID,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAwCpB"}