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.
- package/README.md +5 -5
- package/dist/cli.js +227 -168
- package/package.json +10 -12
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# pdf-fetch(CLI:
|
|
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
|
-
|
|
21
|
+
pdf-fetch
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
转换整个 PDF:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
|
|
27
|
+
pdf-fetch "name.pdf"
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
指定分辨率/质量:
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
|
|
33
|
+
pdf-fetch "name.pdf" -d 200 -q 100
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
指定输出文件名前缀 + 指定页码:
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
-
|
|
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
var
|
|
8
|
-
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
));
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
23
|
+
const text = `
|
|
24
|
+
用法:
|
|
25
|
+
pdf-fetch "文件.pdf" [选项]
|
|
38
26
|
|
|
39
|
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
27
|
+
说明:
|
|
28
|
+
- 在 PDF 所在目录创建同名文件夹(去掉 .pdf 扩展名)
|
|
29
|
+
- 将指定页面导出为 JPG,文件名规则:前缀 + 序号(从 01 开始)
|
|
42
30
|
|
|
43
|
-
|
|
44
|
-
-d, --dpi
|
|
45
|
-
-q, --quality
|
|
46
|
-
-n, --name
|
|
47
|
-
-p, --pages
|
|
48
|
-
-p 10
|
|
49
|
-
-p 10,12,13
|
|
50
|
-
-p 10-15
|
|
51
|
-
-p 10-15,20
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
-
|
|
81
|
-
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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
|
-
|
|
123
|
-
|
|
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
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
-
|
|
195
|
-
|
|
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
|
|
4
|
-
"description": "使用 ImageMagick 将 PDF 页面批量导出为 JPG 的命令行工具(CLI 命令:
|
|
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
|
-
"
|
|
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
|
+
}
|