pdf-fetch 0.1.0 → 0.2.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.
Files changed (3) hide show
  1. package/README.md +5 -5
  2. package/dist/cli.js +227 -168
  3. package/package.json +10 -12
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # pdf-fetch(CLI:pdf2jpg
1
+ # pdf-fetch(CLI:pdf-fetch
2
2
 
3
3
  一个简单的命令行工具:使用 **ImageMagick(magick)** 从 PDF 中提取页面并导出为 JPG。
4
4
 
@@ -18,25 +18,25 @@ pnpm add -g pdf-fetch
18
18
  无参数时会输出中文使用说明:
19
19
 
20
20
  ```bash
21
- pdf2jpg
21
+ pdf-fetch
22
22
  ```
23
23
 
24
24
  转换整个 PDF:
25
25
 
26
26
  ```bash
27
- pdf2jpg "name.pdf"
27
+ pdf-fetch "name.pdf"
28
28
  ```
29
29
 
30
30
  指定分辨率/质量:
31
31
 
32
32
  ```bash
33
- pdf2jpg "name.pdf" -d 200 -q 100
33
+ pdf-fetch "name.pdf" -d 200 -q 100
34
34
  ```
35
35
 
36
36
  指定输出文件名前缀 + 指定页码:
37
37
 
38
38
  ```bash
39
- pdf2jpg "name.pdf" -n "new" -p 10-15,20
39
+ pdf-fetch "name.pdf" -n "new" -p 10-15,20
40
40
  ```
41
41
 
42
42
  ## 行为规则
package/dist/cli.js CHANGED
@@ -1,197 +1,256 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (let key of __getOwnPropNames(from))
12
- if (!__hasOwnProp.call(to, key) && key !== except)
13
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
- }
15
- return to;
3
+ /**
4
+ * pdf-fetch CLI 入口
5
+ * 功能:使用已安装的 ImageMagick(magick)从 PDF 中提取页面并保存为 JPG。
6
+ */
7
+ var __importDefault = (this && this.__importDefault) || function (mod) {
8
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
9
  };
17
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
- // If the importer is in node compatibility mode or this is not an ESM
19
- // file that has been converted to a CommonJS file using a Babel-
20
- // compatible transform (i.e. "__esModule" has not been set), then set
21
- // "default" to the CommonJS "module.exports" for node compatibility.
22
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
- mod
24
- ));
25
-
26
- // src/cli.ts
27
- var import_commander = require("commander");
28
- var import_node_child_process = require("child_process");
29
- var import_node_fs = require("fs");
30
- var import_promises = require("fs/promises");
31
- var import_node_path = __toESM(require("path"));
32
- var import_node_util = require("util");
33
- var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ const commander_1 = require("commander");
12
+ const node_child_process_1 = require("node:child_process");
13
+ const node_fs_1 = require("node:fs");
14
+ const promises_1 = require("node:fs/promises");
15
+ const node_path_1 = __importDefault(require("node:path"));
16
+ const node_util_1 = require("node:util");
17
+ const execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
18
+ /**
19
+ * 输出中文使用说明(无参数时)。
20
+ * @returns {void}
21
+ */
34
22
  function printChineseUsage() {
35
- const text = `
36
- \u7528\u6CD5\uFF1A
37
- pdf2jpg "\u6587\u4EF6.pdf" [\u9009\u9879]
23
+ const text = `
24
+ 用法:
25
+ pdf-fetch "文件.pdf" [选项]
38
26
 
39
- \u8BF4\u660E\uFF1A
40
- - \u5728 PDF \u6240\u5728\u76EE\u5F55\u521B\u5EFA\u540C\u540D\u6587\u4EF6\u5939\uFF08\u53BB\u6389 .pdf \u6269\u5C55\u540D\uFF09
41
- - \u5C06\u6307\u5B9A\u9875\u9762\u5BFC\u51FA\u4E3A JPG\uFF0C\u6587\u4EF6\u540D\u89C4\u5219\uFF1A\u524D\u7F00 + \u5E8F\u53F7\uFF08\u4ECE 01 \u5F00\u59CB\uFF09
27
+ 说明:
28
+ - PDF 所在目录创建同名文件夹(去掉 .pdf 扩展名)
29
+ - 将指定页面导出为 JPG,文件名规则:前缀 + 序号(从 01 开始)
42
30
 
43
- \u9009\u9879\uFF1A
44
- -d, --dpi <\u6570\u5B57> \u5206\u8FA8\u7387\uFF08DPI\uFF09\uFF0C\u9ED8\u8BA4 150
45
- -q, --quality <\u6570\u5B57> JPG \u8D28\u91CF\uFF0C\u9ED8\u8BA4 95
46
- -n, --name <\u524D\u7F00> \u6587\u4EF6\u540D\u524D\u7F00\uFF0C\u9ED8\u8BA4 p\uFF08\u793A\u4F8B\uFF1Ap01.jpg\uFF09
47
- -p, --pages <\u8303\u56F4> \u9009\u62E9\u9875\u9762\uFF1A
48
- -p 10 \u7B2C 10 \u9875
49
- -p 10,12,13 \u7B2C 10/12/13 \u9875
50
- -p 10-15 \u7B2C 10 \u5230 15 \u9875
51
- -p 10-15,20 \u7B2C 10-15 \u9875\u548C\u7B2C 20 \u9875
31
+ 选项:
32
+ -d, --dpi <数字> 分辨率(DPI),默认 150
33
+ -q, --quality <数字> JPG 质量,默认 95
34
+ -n, --name <前缀> 文件名前缀,默认 p(示例:p01.jpg
35
+ -p, --pages <范围> 选择页面:
36
+ -p 10 10
37
+ -p 10,12,13 10/12/13
38
+ -p 10-15 10 15
39
+ -p 10-15,20 10-15 页和第 20
52
40
 
53
- \u793A\u4F8B\uFF1A
54
- pdf2jpg "name.pdf"
55
- pdf2jpg "name.pdf" -d 200 -q 100
56
- pdf2jpg "name.pdf" -n "new" -p 10-15,20
41
+ 示例:
42
+ pdf-fetch "name.pdf"
43
+ pdf-fetch "name.pdf" -d 200 -q 100
44
+ pdf-fetch "name.pdf" -n "new" -p 10-15,20
57
45
  `;
58
- console.log(text.trim());
46
+ console.log(text.trim());
59
47
  }
48
+ /**
49
+ * 将数字按指定宽度补零。
50
+ * @param {number} n 数字
51
+ * @param {number} width 宽度
52
+ * @returns {string} 补零后的字符串
53
+ */
60
54
  function padNumber(n, width) {
61
- return String(n).padStart(width, "0");
55
+ return String(n).padStart(width, "0");
62
56
  }
57
+ /**
58
+ * 解析页码参数(如:10 / 10,12,13 / 10-15 / 10-15,20)。
59
+ * @param {string} spec 页码表达式
60
+ * @returns {number[]} 页码数组(从 1 开始)
61
+ */
63
62
  function parsePagesSpec(spec) {
64
- const raw = spec.split(",").map((s) => s.trim()).filter(Boolean);
65
- const pages = [];
66
- for (const part of raw) {
67
- const rangeMatch = part.match(/^(\d+)\s*-\s*(\d+)$/);
68
- if (rangeMatch) {
69
- const start = Number(rangeMatch[1]);
70
- const end = Number(rangeMatch[2]);
71
- if (!Number.isInteger(start) || !Number.isInteger(end) || start <= 0 || end <= 0) {
72
- throw new Error(`\u9875\u7801\u8303\u56F4\u975E\u6CD5\uFF1A${part}`);
73
- }
74
- if (start > end) {
75
- throw new Error(`\u9875\u7801\u8303\u56F4\u8D77\u6B62\u987A\u5E8F\u9519\u8BEF\uFF1A${part}`);
76
- }
77
- for (let i = start; i <= end; i += 1) pages.push(i);
78
- continue;
63
+ const raw = spec
64
+ .split(",")
65
+ .map((s) => s.trim())
66
+ .filter(Boolean);
67
+ const pages = [];
68
+ for (const part of raw) {
69
+ const rangeMatch = part.match(/^(\d+)\s*-\s*(\d+)$/);
70
+ if (rangeMatch) {
71
+ const start = Number(rangeMatch[1]);
72
+ const end = Number(rangeMatch[2]);
73
+ if (!Number.isInteger(start) || !Number.isInteger(end) || start <= 0 || end <= 0) {
74
+ throw new Error(`页码范围非法:${part}`);
75
+ }
76
+ if (start > end) {
77
+ throw new Error(`页码范围起止顺序错误:${part}`);
78
+ }
79
+ for (let i = start; i <= end; i += 1)
80
+ pages.push(i);
81
+ continue;
82
+ }
83
+ const singleMatch = part.match(/^\d+$/);
84
+ if (singleMatch) {
85
+ const v = Number(part);
86
+ if (!Number.isInteger(v) || v <= 0)
87
+ throw new Error(`页码非法:${part}`);
88
+ pages.push(v);
89
+ continue;
90
+ }
91
+ throw new Error(`无法解析页码参数:${part}`);
92
+ }
93
+ // 去重 + 排序(保证输出顺序稳定)
94
+ return Array.from(new Set(pages)).sort((a, b) => a - b);
95
+ }
96
+ /**
97
+ * 读取当前包版本号(用于 -v/--version 以及运行时展示)。
98
+ * @returns {string} 版本号(读取失败则返回 unknown)
99
+ */
100
+ function getPackageVersion() {
101
+ try {
102
+ const pkgPath = node_path_1.default.resolve(__dirname, "..", "package.json");
103
+ const raw = (0, node_fs_1.readFileSync)(pkgPath, "utf8");
104
+ const pkg = JSON.parse(raw);
105
+ return pkg.version ?? "unknown";
79
106
  }
80
- const singleMatch = part.match(/^\d+$/);
81
- if (singleMatch) {
82
- const v = Number(part);
83
- if (!Number.isInteger(v) || v <= 0) throw new Error(`\u9875\u7801\u975E\u6CD5\uFF1A${part}`);
84
- pages.push(v);
85
- continue;
107
+ catch {
108
+ return "unknown";
86
109
  }
87
- throw new Error(`\u65E0\u6CD5\u89E3\u6790\u9875\u7801\u53C2\u6570\uFF1A${part}`);
88
- }
89
- return Array.from(new Set(pages)).sort((a, b) => a - b);
90
110
  }
111
+ /**
112
+ * 检查 magick 命令是否可用。
113
+ * @returns {Promise<void>}
114
+ */
91
115
  async function ensureMagickAvailable() {
92
- try {
93
- await execFileAsync("magick", ["-version"]);
94
- } catch {
95
- throw new Error("\u672A\u68C0\u6D4B\u5230 ImageMagick \u7684 magick \u547D\u4EE4\u3002\u8BF7\u786E\u8BA4\u5DF2\u5B89\u88C5\u5E76\u4E14\u5728 PATH \u4E2D\u53EF\u7528\u3002");
96
- }
116
+ try {
117
+ await execFileAsync("magick", ["-version"]);
118
+ }
119
+ catch {
120
+ throw new Error("未检测到 ImageMagick 的 magick 命令。请确认已安装并且在 PATH 中可用。");
121
+ }
97
122
  }
123
+ /**
124
+ * 获取 PDF 页数。
125
+ * 实现:通过 `magick identify -ping file.pdf` 输出行数判断。
126
+ * @param {string} pdfPath PDF 路径
127
+ * @returns {Promise<number>} 页数
128
+ */
98
129
  async function getPdfPageCount(pdfPath) {
99
- const { stdout } = await execFileAsync("magick", ["identify", "-ping", pdfPath], {
100
- maxBuffer: 10 * 1024 * 1024
101
- });
102
- const lines = stdout.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
103
- if (lines.length === 0) throw new Error("\u65E0\u6CD5\u8BC6\u522B PDF \u9875\u6570\uFF08magick identify \u8F93\u51FA\u4E3A\u7A7A\uFF09\u3002");
104
- return lines.length;
130
+ const { stdout } = await execFileAsync("magick", ["identify", "-ping", pdfPath], {
131
+ maxBuffer: 10 * 1024 * 1024,
132
+ });
133
+ const lines = stdout
134
+ .split(/\r?\n/)
135
+ .map((s) => s.trim())
136
+ .filter(Boolean);
137
+ if (lines.length === 0)
138
+ throw new Error("无法识别 PDF 页数(magick identify 输出为空)。");
139
+ return lines.length;
105
140
  }
141
+ /**
142
+ * 将指定 PDF 页面导出为 JPG。
143
+ * @param {object} params 参数
144
+ * @param {string} params.pdfPath PDF 路径
145
+ * @param {number} params.pageNumber PDF 页码(从 1 开始)
146
+ * @param {number} params.dpi 分辨率 DPI
147
+ * @param {number} params.quality JPG 质量
148
+ * @param {string} params.outputPath 输出文件路径
149
+ * @returns {Promise<void>}
150
+ */
106
151
  async function convertSinglePageToJpg(params) {
107
- const magickPageIndex = params.pageNumber - 1;
108
- await execFileAsync(
109
- "magick",
110
- [
111
- "-density",
112
- String(params.dpi),
113
- `${params.pdfPath}[${magickPageIndex}]`,
114
- "-quality",
115
- String(params.quality),
116
- params.outputPath
117
- ],
118
- { maxBuffer: 10 * 1024 * 1024 }
119
- );
152
+ const magickPageIndex = params.pageNumber - 1; // ImageMagick 以 0 为第一页索引
153
+ await execFileAsync("magick", [
154
+ "-density",
155
+ String(params.dpi),
156
+ `${params.pdfPath}[${magickPageIndex}]`,
157
+ "-quality",
158
+ String(params.quality),
159
+ params.outputPath,
160
+ ], { maxBuffer: 10 * 1024 * 1024 });
120
161
  }
162
+ /**
163
+ * 主流程:解析参数并执行转换。
164
+ * @param {string} inputPdf 用户输入的 PDF 路径(可相对/绝对)
165
+ * @param {Options} options 命令行选项
166
+ * @returns {Promise<void>}
167
+ */
121
168
  async function run(inputPdf, options) {
122
- if (!(0, import_node_fs.existsSync)(inputPdf)) {
123
- throw new Error(`\u627E\u4E0D\u5230\u6587\u4EF6\uFF1A${inputPdf}`);
124
- }
125
- await ensureMagickAvailable();
126
- const pdfAbsPath = import_node_path.default.resolve(process.cwd(), inputPdf);
127
- const pdfDir = import_node_path.default.dirname(pdfAbsPath);
128
- const pdfBaseName = import_node_path.default.basename(pdfAbsPath, import_node_path.default.extname(pdfAbsPath));
129
- const outputDir = import_node_path.default.join(pdfDir, pdfBaseName);
130
- if ((0, import_node_fs.existsSync)(outputDir)) {
131
- const st = await (0, import_promises.stat)(outputDir);
132
- if (!st.isDirectory()) {
133
- throw new Error(`\u8F93\u51FA\u8DEF\u5F84\u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u6587\u4EF6\u5939\uFF1A${outputDir}`);
169
+ if (!(0, node_fs_1.existsSync)(inputPdf)) {
170
+ throw new Error(`找不到文件:${inputPdf}`);
134
171
  }
135
- } else {
136
- await (0, import_promises.mkdir)(outputDir, { recursive: true });
137
- }
138
- const pageCount = await getPdfPageCount(pdfAbsPath);
139
- const selectedPages = options.pages ? parsePagesSpec(options.pages) : [];
140
- const pages = selectedPages.length > 0 ? selectedPages : Array.from({ length: pageCount }, (_, i) => i + 1);
141
- const invalidPage = pages.find((p) => p < 1 || p > pageCount);
142
- if (invalidPage) {
143
- throw new Error(`\u9875\u7801\u8D85\u51FA\u8303\u56F4\uFF1A${invalidPage}\uFF08PDF \u603B\u9875\u6570\uFF1A${pageCount}\uFF09`);
144
- }
145
- const width = Math.max(2, String(pages.length).length);
146
- for (let i = 0; i < pages.length; i += 1) {
147
- const outIndex = i + 1;
148
- const fileName = `${options.name}${padNumber(outIndex, width)}.jpg`;
149
- const outputPath = import_node_path.default.join(outputDir, fileName);
150
- if ((0, import_node_fs.existsSync)(outputPath)) {
151
- throw new Error(`\u8F93\u51FA\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u5DF2\u6309\u8981\u6C42\u4E2D\u6B62\uFF1A${outputPath}`);
172
+ await ensureMagickAvailable();
173
+ const pdfAbsPath = node_path_1.default.resolve(process.cwd(), inputPdf);
174
+ const pdfDir = node_path_1.default.dirname(pdfAbsPath);
175
+ const pdfBaseName = node_path_1.default.basename(pdfAbsPath, node_path_1.default.extname(pdfAbsPath));
176
+ const outputDir = node_path_1.default.join(pdfDir, pdfBaseName);
177
+ if ((0, node_fs_1.existsSync)(outputDir)) {
178
+ const st = await (0, promises_1.stat)(outputDir);
179
+ if (!st.isDirectory()) {
180
+ throw new Error(`输出路径已存在但不是文件夹:${outputDir}`);
181
+ }
152
182
  }
153
- const pageNumber = pages[i];
154
- console.log(`\u6B63\u5728\u8F6C\u6362\uFF1A\u7B2C ${pageNumber} \u9875 -> ${fileName}`);
155
- await convertSinglePageToJpg({
156
- pdfPath: pdfAbsPath,
157
- pageNumber,
158
- dpi: options.dpi,
159
- quality: options.quality,
160
- outputPath
161
- });
162
- }
163
- console.log(`\u5B8C\u6210\uFF1A\u5171\u5BFC\u51FA ${pages.length} \u5F20 JPG\uFF0C\u8F93\u51FA\u76EE\u5F55\uFF1A${outputDir}`);
183
+ else {
184
+ await (0, promises_1.mkdir)(outputDir, { recursive: true });
185
+ }
186
+ const pageCount = await getPdfPageCount(pdfAbsPath);
187
+ const selectedPages = options.pages ? parsePagesSpec(options.pages) : [];
188
+ const pages = selectedPages.length > 0 ? selectedPages : Array.from({ length: pageCount }, (_, i) => i + 1);
189
+ const invalidPage = pages.find((p) => p < 1 || p > pageCount);
190
+ if (invalidPage) {
191
+ throw new Error(`页码超出范围:${invalidPage}(PDF 总页数:${pageCount})`);
192
+ }
193
+ const width = Math.max(2, String(pages.length).length);
194
+ for (let i = 0; i < pages.length; i += 1) {
195
+ const outIndex = i + 1; // 输出序号从 1 开始
196
+ const fileName = `${options.name}${padNumber(outIndex, width)}.jpg`;
197
+ const outputPath = node_path_1.default.join(outputDir, fileName);
198
+ if ((0, node_fs_1.existsSync)(outputPath)) {
199
+ throw new Error(`输出文件已存在,已按要求中止:${outputPath}`);
200
+ }
201
+ const pageNumber = pages[i];
202
+ console.log(`正在转换:第 ${pageNumber} 页 -> ${fileName}`);
203
+ await convertSinglePageToJpg({
204
+ pdfPath: pdfAbsPath,
205
+ pageNumber,
206
+ dpi: options.dpi,
207
+ quality: options.quality,
208
+ outputPath,
209
+ });
210
+ }
211
+ console.log(`完成:共导出 ${pages.length} 张 JPG,输出目录:${outputDir}`);
164
212
  }
165
213
  async function main() {
166
- if (process.argv.slice(2).length === 0) {
167
- printChineseUsage();
168
- process.exit(0);
169
- }
170
- const program = new import_commander.Command();
171
- program.name("pdf2jpg").description("\u4ECE PDF \u4E2D\u63D0\u53D6\u9875\u9762\u5E76\u4FDD\u5B58\u4E3A JPG\uFF08\u4F9D\u8D56 ImageMagick\uFF1Amagick\uFF09").argument("<pdf>", "PDF \u6587\u4EF6\u8DEF\u5F84").option("-d, --dpi <number>", "\u5206\u8FA8\u7387\uFF08DPI\uFF09\uFF0C\u9ED8\u8BA4 150", "150").option("-q, --quality <number>", "JPG \u8D28\u91CF\uFF0C\u9ED8\u8BA4 95", "95").option("-n, --name <string>", "\u8F93\u51FA\u6587\u4EF6\u540D\u524D\u7F00\uFF0C\u9ED8\u8BA4 p", "p").option("-p, --pages <string>", "\u9875\u7801\u9009\u62E9\uFF08\u5982 10-15,20\uFF09");
172
- program.parse(process.argv);
173
- const inputPdf = program.args[0];
174
- if (!inputPdf) {
175
- printChineseUsage();
176
- process.exit(1);
177
- }
178
- const opts = program.opts();
179
- const dpi = Number(opts.dpi);
180
- const quality = Number(opts.quality);
181
- if (!Number.isFinite(dpi) || dpi <= 0) throw new Error("dpi \u5FC5\u987B\u662F\u5927\u4E8E 0 \u7684\u6570\u5B57\u3002");
182
- if (!Number.isFinite(quality) || quality < 1 || quality > 100) {
183
- throw new Error("quality \u5FC5\u987B\u662F 1-100 \u4E4B\u95F4\u7684\u6570\u5B57\u3002");
184
- }
185
- if (!opts.name || opts.name.trim().length === 0) throw new Error("name \u4E0D\u80FD\u4E3A\u7A7A\u3002");
186
- await run(inputPdf, {
187
- dpi,
188
- quality,
189
- name: opts.name.trim(),
190
- pages: opts.pages?.trim()
191
- });
214
+ if (process.argv.slice(2).length === 0) {
215
+ printChineseUsage();
216
+ process.exit(0);
217
+ }
218
+ const version = getPackageVersion();
219
+ const program = new commander_1.Command();
220
+ program
221
+ .name("pdf-fetch")
222
+ .description("从 PDF 中提取页面并保存为 JPG(依赖 ImageMagick:magick)")
223
+ .version(version, "-v, --version", "显示版本号")
224
+ .argument("<pdf>", "PDF 文件路径")
225
+ .option("-d, --dpi <number>", "分辨率(DPI),默认 150", "150")
226
+ .option("-q, --quality <number>", "JPG 质量,默认 95", "95")
227
+ .option("-n, --name <string>", "输出文件名前缀,默认 p", "p")
228
+ .option("-p, --pages <string>", "页码选择(如 10-15,20)");
229
+ program.parse(process.argv);
230
+ const inputPdf = program.args[0];
231
+ if (!inputPdf) {
232
+ printChineseUsage();
233
+ process.exit(1);
234
+ }
235
+ const opts = program.opts();
236
+ const dpi = Number(opts.dpi);
237
+ const quality = Number(opts.quality);
238
+ if (!Number.isFinite(dpi) || dpi <= 0)
239
+ throw new Error("dpi 必须是大于 0 的数字。");
240
+ if (!Number.isFinite(quality) || quality < 1 || quality > 100) {
241
+ throw new Error("quality 必须是 1-100 之间的数字。");
242
+ }
243
+ if (!opts.name || opts.name.trim().length === 0)
244
+ throw new Error("name 不能为空。");
245
+ console.log(`pdf-fetch v${version}`);
246
+ await run(inputPdf, {
247
+ dpi,
248
+ quality,
249
+ name: opts.name.trim(),
250
+ pages: opts.pages?.trim(),
251
+ });
192
252
  }
193
253
  main().catch((err) => {
194
- console.error(`\u9519\u8BEF\uFF1A${err instanceof Error ? err.message : String(err)}`);
195
- process.exit(1);
254
+ console.error(`错误:${err instanceof Error ? err.message : String(err)}`);
255
+ process.exit(1);
196
256
  });
197
- //# sourceMappingURL=cli.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pdf-fetch",
3
- "version": "0.1.0",
4
- "description": "使用 ImageMagick 将 PDF 页面批量导出为 JPG 的命令行工具(CLI 命令:pdf2jpg)",
3
+ "version": "0.2.1",
4
+ "description": "使用 ImageMagick 将 PDF 页面批量导出为 JPG 的命令行工具(CLI 命令:pdf-fetch)",
5
5
  "keywords": [
6
6
  "pdf",
7
7
  "jpg",
@@ -20,20 +20,13 @@
20
20
  },
21
21
  "main": "dist/cli.js",
22
22
  "bin": {
23
- "pdf2jpg": "dist/cli.js"
23
+ "pdf-fetch": "dist/cli.js"
24
24
  },
25
25
  "files": [
26
26
  "dist",
27
27
  "README.md",
28
28
  "LICENSE"
29
29
  ],
30
- "scripts": {
31
- "build": "tsup",
32
- "typecheck": "tsc -p tsconfig.json --noEmit",
33
- "lint": "eslint .",
34
- "format": "prettier -w .",
35
- "prepublishOnly": "pnpm run lint && pnpm run typecheck && pnpm run build"
36
- },
37
30
  "engines": {
38
31
  "node": ">=18"
39
32
  },
@@ -46,8 +39,13 @@
46
39
  "eslint": "^9.20.0",
47
40
  "eslint-config-prettier": "^10.0.1",
48
41
  "prettier": "^3.5.1",
49
- "tsup": "^8.4.0",
50
42
  "typescript": "^5.7.3",
51
43
  "typescript-eslint": "^8.24.0"
44
+ },
45
+ "scripts": {
46
+ "build": "tsc -p tsconfig.json && node scripts/add-shebang.cjs dist/cli.js",
47
+ "typecheck": "tsc -p tsconfig.json --noEmit",
48
+ "lint": "eslint .",
49
+ "format": "prettier -w ."
52
50
  }
53
- }
51
+ }