dudu-converter-cli 0.0.0-stage → 1.0.0
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 +225 -2
- package/package.json +60 -4
- package/release/cli.js +8 -0
- package/release/registry-schema.json +220 -0
- package/release/registry.json +841 -0
- package/web/dist/MP_verify_90j11A4PBXwsFIsV.txt +1 -0
- package/web/dist/assets/index-BZqxEIrH.js +32 -0
- package/web/dist/assets/index-DuwKbhiJ.css +1 -0
- package/web/dist/gh-qrcode.png +0 -0
- package/web/dist/index.html +13 -0
- package/web/dist/install.ps1 +72 -0
- package/web/dist/install.sh +53 -0
package/README.md
CHANGED
|
@@ -1,3 +1,226 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 嘟嘟转换器(DuDu Converter)— 本地万能文档转换工具
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
嘟嘟转换器(npm 包 `dudu-converter-cli`,命令 `converter`)是一个本地优先的文件转换工具,由 **Node.js CLI/daemon** 和 **浏览器 Web UI** 组成。文件解析、转换、下载与历史记录都在本机完成,不包含上传服务。
|
|
4
|
+
|
|
5
|
+
- 当前平台目标:**macOS 12+、Windows 10 21H2+/11**;不支持 Linux。
|
|
6
|
+
- Office 转换首选 **LibreOffice**;本期缺失时能力灰显并提示安装,纯代码降级转换保留在后续版本规划。
|
|
7
|
+
- 服务只绑定 `127.0.0.1`,输入和输出路径限制在当前用户主目录内。
|
|
8
|
+
|
|
9
|
+
## 功能范围
|
|
10
|
+
|
|
11
|
+
| 能力 | 引擎 | 说明 |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| 视频转换、视频压缩、GIF、音频转换/提取、音视频压缩 | FFmpeg | MP4/AVI/MKV/MOV/WebM/FLV/WMV 及常用音频格式 |
|
|
14
|
+
| 图片转换、缩放、压缩、水印 | ImageMagick | JPG/PNG/WebP/AVIF/HEIC/TIFF/BMP 等 |
|
|
15
|
+
| 文件压缩为 7z/Zip、压缩包解压 | 7-Zip | 首页能力卡与依赖体检联动 |
|
|
16
|
+
| Office 转 PDF/HTML、Office 家族互转 | LibreOffice | LibreOffice 为首选引擎 |
|
|
17
|
+
| PDF 转图片/文本 | Poppler | 可选依赖 |
|
|
18
|
+
| PDF 合并/拆分/加密解密 | qpdf | 可选依赖 |
|
|
19
|
+
| Markdown 互转 | Pandoc | 可选依赖 |
|
|
20
|
+
|
|
21
|
+
依赖检测按 `src/registry/registry.json` 驱动,支持 `ready / outdated / missing` 状态、推荐版本、平台安装/卸载命令和手动下载地址。Web 面板确认后才会执行安装或卸载;已安装依赖显示【一键卸载】,卸载前必须二次确认。
|
|
22
|
+
|
|
23
|
+
高级参数按所选能力动态展示,由 `CONVERSION_MATRIX` 的参数 schema 驱动:质量类参数提供「小体积 / 标准 / 高清」等档位下拉(自动映射数值),尺寸类参数附带通俗说明文字;无参数的能力(如压缩解压、Office 转换、PDF 拆分)不显示高级设置入口。服务端对提交的参数按同一 schema 做白名单与范围校验。
|
|
24
|
+
|
|
25
|
+
## 环境要求
|
|
26
|
+
|
|
27
|
+
| 项目 | 要求 |
|
|
28
|
+
|---|---|
|
|
29
|
+
| 操作系统 | macOS 12+;Windows 10 21H2+ 或 Windows 11 |
|
|
30
|
+
| Node.js | 18.x 或更高 LTS |
|
|
31
|
+
| npm | 8.x 或更高 |
|
|
32
|
+
| 浏览器 | 本机现代浏览器 |
|
|
33
|
+
| 外部转换工具 | 首次启动后通过 Doctor 检测;可用 Homebrew、winget、Chocolatey 或 Scoop 安装 |
|
|
34
|
+
|
|
35
|
+
## 本地开发与构建
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm ci
|
|
39
|
+
npm run build
|
|
40
|
+
npm start
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`npm run build` 会生成:
|
|
44
|
+
|
|
45
|
+
- `dist/`:Node.js CLI 与本地服务
|
|
46
|
+
- `web/dist/`:生产 Web UI 静态资源
|
|
47
|
+
|
|
48
|
+
开发模式:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm run dev
|
|
52
|
+
npm run lint
|
|
53
|
+
npm run typecheck
|
|
54
|
+
npm run test:unit
|
|
55
|
+
npm run test:web
|
|
56
|
+
npm run test:e2e
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 安装 CLI
|
|
60
|
+
|
|
61
|
+
### 终端用户:从官网一行命令安装
|
|
62
|
+
|
|
63
|
+
官网首页(与转换功能页同一个 Web 项目,路由 `/` 为功能介绍,`/workbench` 为功能页)提供按平台识别的一行安装命令;功能页在浏览器访问时会自动检测本地转换器是否运行,未安装则就地展示安装引导:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# macOS(自动检查/安装 Node.js,安装后自动启动并打开浏览器)
|
|
67
|
+
curl -fsSL https://<官网域名>/install.sh | sh
|
|
68
|
+
|
|
69
|
+
# Windows PowerShell
|
|
70
|
+
irm https://<官网域名>/install.ps1 | iex
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
- 安装脚本默认安装 npm 包 `dudu-converter-cli`,可用环境变量 `CONVERTER_PACKAGE_SPEC` 覆盖(如指向本地 tarball 做发布前验证)
|
|
74
|
+
- `NO_START=1` 可跳过安装后自动启动
|
|
75
|
+
- 安装脚本与官网同源部署:`web/public/install.sh`、`web/public/install.ps1` 随 `npm run build` 一并进入 `web/dist`
|
|
76
|
+
|
|
77
|
+
### 官网部署
|
|
78
|
+
|
|
79
|
+
`web/dist` 是自包含静态产物,可直接上传到任意静态托管(同一份产物同时内置在 daemon 中):
|
|
80
|
+
|
|
81
|
+
1. 部署前把 `web/src/config.ts` 中的 `OFFICIAL_SITE_URL` 改为实际域名(本地运行时安装引导指向该地址)
|
|
82
|
+
2. `npm run build` 后将 `web/dist` 整体上传到静态服务器
|
|
83
|
+
3. 在线形态下功能页通过 `no-cors` 探测 `http://127.0.0.1:3456` 检测本地转换器;检测成功提供「打开本地转换器」入口,失败展示安装引导
|
|
84
|
+
|
|
85
|
+
### 发布新版本(维护者)
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npm publish # 自动触发 prepublishOnly:完整构建 + 混淆 bundle 产出 release/
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
- 发布包内容为**混淆压缩后的单文件 bundle**(`release/cli.js`)+ `web/dist` + README,**不含任何源码**;`npm pack --dry-run` 可自检(包内不应出现 `dist/src`)
|
|
92
|
+
- 官方域名在 bundle 构建时烤入(默认 `https://duduer.com`);如需临时覆盖,构建前设置环境变量 `CONVERTER_OFFICIAL_ORIGIN`
|
|
93
|
+
- daemon 端来源白名单可用环境变量 `CONVERTER_ALLOWED_ORIGINS` 追加(逗号分隔多个域名)
|
|
94
|
+
|
|
95
|
+
### 开发者:本地链接
|
|
96
|
+
|
|
97
|
+
在项目目录执行:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
npm link
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
之后可在终端直接使用 `converter`。Windows 终端会通过 npm 生成的 `converter.cmd` shim 调用入口;macOS/Linux 入口带 Node.js shebang 且构建脚本会设置可执行位。
|
|
104
|
+
|
|
105
|
+
如需移除链接:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npm unlink -g dudu-converter-cli
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## 使用方式
|
|
112
|
+
|
|
113
|
+
### 启动 Web 服务
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
converter start [--port 3456] [--daemon] [--no-open-browser]
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
- 默认端口 `3456`;被占用时自动向后顺延。
|
|
120
|
+
- 服务地址始终是 `http://127.0.0.1:<port>`。
|
|
121
|
+
- 已有实例存活时,重复 `converter start` 只打开现有实例。
|
|
122
|
+
- `--daemon` 后台常驻;`--no-open-browser` 不自动打开浏览器。
|
|
123
|
+
|
|
124
|
+
### 依赖体检
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
converter doctor
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
终端会列出八项依赖、安装状态和版本。存在缺失的核心依赖时退出码为 `1`。Web UI 的「依赖体检」页支持重新检测、一键安装、一键卸载、复制命令和手动下载指引。
|
|
131
|
+
|
|
132
|
+
### 提交转换
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
converter convert <input> <target>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
示例:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
converter convert ~/Desktop/report.docx pdf
|
|
142
|
+
converter convert ~/Desktop/demo.mov mp3
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
CLI 通过当前 daemon 提交任务;真实端口从 `~/.converter/port` 读取。也可以直接在 Web UI 拖拽文件、选择目标格式和高级参数。
|
|
146
|
+
|
|
147
|
+
设置页的默认输出目录既可手工粘贴绝对路径,也可点击【选择文件夹】调用 macOS / Windows 原生目录选择器;保存后新任务使用该目录。
|
|
148
|
+
|
|
149
|
+
### 查看能力
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
converter features
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### 开机自启
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
converter autostart enable
|
|
159
|
+
converter autostart disable
|
|
160
|
+
converter autostart status
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
- macOS:写入并加载 `~/Library/LaunchAgents/com.converter.daemon.plist`,登录启动且 KeepAlive。
|
|
164
|
+
- Windows:创建登录触发的计划任务 `ConverterDaemon`,并保存启动配置。
|
|
165
|
+
- 自启进程使用 `--daemon --no-open-browser`。
|
|
166
|
+
|
|
167
|
+
### 查看版本
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
converter --version
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## 卸载与清理
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
converter uninstall
|
|
177
|
+
npm unlink -g converter
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
`converter uninstall` 会禁用并移除 macOS LaunchAgent 或 Windows 计划任务,清理 `~/.converter` 下的 `pid`、`port` 和临时目录。它不会卸载用户已安装的外部依赖。如需移除 FFmpeg、ImageMagick、7-Zip、LibreOffice、Poppler、qpdf 或 Pandoc,请到 Web「依赖体检」页逐个使用【一键卸载】,并确认二次确认弹窗。
|
|
181
|
+
|
|
182
|
+
运行态数据默认保存在:
|
|
183
|
+
|
|
184
|
+
```text
|
|
185
|
+
~/.converter/
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
可用环境变量 `CONVERTER_HOME` 重定向;测试时建议使用临时目录。
|
|
189
|
+
|
|
190
|
+
## 安全边界
|
|
191
|
+
|
|
192
|
+
- HTTP/WebSocket 仅监听 `127.0.0.1`,不提供局域网入口。
|
|
193
|
+
- **来源绑定**:API 与 WebSocket 校验请求来源——本机页面(同源)、本机 CLI 进程(无 Origin 头)、官方站点(`https://duduer.com`,响应附 CORS 头)之外一律拒绝(403 / 拒绝 WS 握手),防止第三方网页驱动本机转换服务或窥探转换记录。可用环境变量 `CONVERTER_ALLOWED_ORIGINS`(逗号分隔)追加自有域名。
|
|
194
|
+
- **Host 头校验**:API 与 WebSocket 校验 Host 必须为本机地址+端口,封堵 DNS Rebinding。
|
|
195
|
+
- **通道加密(官方站点专用)**:官方域名请求可经 `GET /api/session` 换取临时会话密钥(10 分钟过期、仅存 daemon 内存),之后请求/响应以 AES-256-GCM 信封加密传输并防重放(协议见 `docs/api-channel-protocol.md`);本机 UI 与 CLI 保持明文不受影响。
|
|
196
|
+
- **通道自测**:`npm run test:channel`(或 `node scripts/test-channel.mjs`)——本机脚本以官方来源身份走完整握手/加密往返/防重放流程并逐项报告;本机脚本可携带 Origin 头而浏览器不可伪造,这正是来源绑定的信任边界,自测不影响 daemon 对真实网页的准入判定。
|
|
197
|
+
- 普通转换输入必须在用户主目录内;输出目录在保存前做真实路径校验。
|
|
198
|
+
- PDF 合并的每一个输入都会做主目录、存在性和 PDF 扩展名校验。
|
|
199
|
+
- 任务产物下载与“打开所在目录”只允许访问成功任务、且真实路径位于用户主目录内的输出。
|
|
200
|
+
- 安装命令只来自 registry 白名单;子进程使用参数数组,不拼接 shell。
|
|
201
|
+
- 文件不经远程服务器;Doctor 探测只读本机版本,不做网络请求。
|
|
202
|
+
|
|
203
|
+
## 项目结构
|
|
204
|
+
|
|
205
|
+
```text
|
|
206
|
+
converter/
|
|
207
|
+
├── docs/features/feature-converter-v1/ # Spec、BE/FE Design、Plan、测试与历史
|
|
208
|
+
├── scripts/ # 构建资产与 CLI 入口检查
|
|
209
|
+
├── src/ # CLI、daemon、转换引擎、队列、自启
|
|
210
|
+
├── tests/ # 后端/接口单元与集成测试
|
|
211
|
+
└── web/ # Vue 3 + Pinia + Vite Web UI
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## 当前交付状态
|
|
215
|
+
|
|
216
|
+
- macOS 开发机已完成构建、服务冒烟、自动化测试与本机基础验证。
|
|
217
|
+
- 2026-11-03 增量:新增 7-Zip 检测/安装/卸载、全依赖卸载二次确认、安装完成自动刷新首页能力卡、完整 FFmpeg/ImageMagick 能力卡、图片压缩与水印参数、输出目录原生选择器。
|
|
218
|
+
- Windows 代码分支、安装命令、计划任务与路径处理已实现并静态检查;本期未配置 Windows 真机,因此 Windows 平台验收结论暂缓。
|
|
219
|
+
- 详细验证、CR 与限制见 [`docs/features/feature-converter-v1/plan/test-plan.md`](./docs/features/feature-converter-v1/plan/test-plan.md) 与 [`docs/features/feature-converter-v1/HISTORY.md`](./docs/features/feature-converter-v1/HISTORY.md)。
|
|
220
|
+
|
|
221
|
+
## 文档
|
|
222
|
+
|
|
223
|
+
- 需求:[`docs/features/feature-converter-v1/spec/spec.md`](./docs/features/feature-converter-v1/spec/spec.md)
|
|
224
|
+
- 后端设计:[`docs/features/feature-converter-v1/design/be/tech-design-backend.md`](./docs/features/feature-converter-v1/design/be/tech-design-backend.md)
|
|
225
|
+
- 前端设计:[`docs/features/feature-converter-v1/design/fe/tech-design-frontend.md`](./docs/features/feature-converter-v1/design/fe/tech-design-frontend.md)
|
|
226
|
+
- 实施计划:[`docs/features/feature-converter-v1/plan/plan.md`](./docs/features/feature-converter-v1/plan/plan.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,62 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dudu-converter-cli",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "本地优先的万能文档转换工具:CLI 引擎 + 浏览器 UI,格式转换零上传",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "release/cli.js",
|
|
7
|
+
"files": [
|
|
8
|
+
"release",
|
|
9
|
+
"web/dist",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"bin": {
|
|
13
|
+
"converter": "./release/cli.js"
|
|
14
|
+
},
|
|
15
|
+
"workspaces": [
|
|
16
|
+
"web"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "node scripts/copy-assets.js && tsc -p tsconfig.build.json && node scripts/make-bin-executable.js && npm run build --workspace web",
|
|
20
|
+
"build:release": "npm run build && node scripts/build-release.mjs",
|
|
21
|
+
"prepublishOnly": "npm run build && node scripts/build-release.mjs",
|
|
22
|
+
"copy:assets": "node scripts/copy-assets.js",
|
|
23
|
+
"dev": "tsx watch src/index.ts",
|
|
24
|
+
"start": "node dist/src/index.js start",
|
|
25
|
+
"doctor": "node dist/src/index.js doctor",
|
|
26
|
+
"lint": "eslint src tests && npm run lint --workspace web",
|
|
27
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && npm run typecheck --workspace web",
|
|
28
|
+
"test:unit": "vitest run --exclude 'web/**'",
|
|
29
|
+
"test:web": "npm run test:unit --workspace web",
|
|
30
|
+
"test:e2e": "npm run test:e2e --workspace web",
|
|
31
|
+
"test:channel": "node scripts/test-channel.mjs",
|
|
32
|
+
"test": "npm run lint && npm run typecheck && npm run test:unit && npm run test:web"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"ajv": "^8.20.0",
|
|
36
|
+
"ajv-formats": "^3.0.1",
|
|
37
|
+
"express": "^4.19.2",
|
|
38
|
+
"ws": "^8.18.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/express": "^4.17.21",
|
|
42
|
+
"@types/node": "^20.14.10",
|
|
43
|
+
"@types/supertest": "^6.0.2",
|
|
44
|
+
"@types/ws": "^8.5.10",
|
|
45
|
+
"@typescript-eslint/eslint-plugin": "^7.16.0",
|
|
46
|
+
"@typescript-eslint/parser": "^7.16.0",
|
|
47
|
+
"@vitest/coverage-v8": "^1.6.0",
|
|
48
|
+
"esbuild": "^0.28.2",
|
|
49
|
+
"eslint": "^8.57.0",
|
|
50
|
+
"eslint-config-prettier": "^9.1.0",
|
|
51
|
+
"eslint-plugin-security": "^3.0.0",
|
|
52
|
+
"javascript-obfuscator": "^5.10.0",
|
|
53
|
+
"supertest": "^7.0.0",
|
|
54
|
+
"tsx": "^4.16.2",
|
|
55
|
+
"typescript": "^5.4.5",
|
|
56
|
+
"vitest": "^1.6.0"
|
|
57
|
+
},
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=18"
|
|
60
|
+
},
|
|
61
|
+
"license": "MIT"
|
|
62
|
+
}
|