@atmaticai/agent-tools-core 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 +742 -0
- package/dist/archive/index.d.mts +1 -0
- package/dist/archive/index.d.ts +1 -0
- package/dist/archive/index.js +90 -0
- package/dist/archive/index.js.map +1 -0
- package/dist/archive/index.mjs +80 -0
- package/dist/archive/index.mjs.map +1 -0
- package/dist/color/index.d.mts +1 -0
- package/dist/color/index.d.ts +1 -0
- package/dist/color/index.js +347 -0
- package/dist/color/index.js.map +1 -0
- package/dist/color/index.mjs +336 -0
- package/dist/color/index.mjs.map +1 -0
- package/dist/crypto/index.d.mts +1 -0
- package/dist/crypto/index.d.ts +1 -0
- package/dist/crypto/index.js +116 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/crypto/index.mjs +108 -0
- package/dist/crypto/index.mjs.map +1 -0
- package/dist/csv/index.d.mts +1 -0
- package/dist/csv/index.d.ts +1 -0
- package/dist/csv/index.js +371 -0
- package/dist/csv/index.js.map +1 -0
- package/dist/csv/index.mjs +348 -0
- package/dist/csv/index.mjs.map +1 -0
- package/dist/datetime/index.d.mts +1 -0
- package/dist/datetime/index.d.ts +1 -0
- package/dist/datetime/index.js +234 -0
- package/dist/datetime/index.js.map +1 -0
- package/dist/datetime/index.mjs +224 -0
- package/dist/datetime/index.mjs.map +1 -0
- package/dist/diff/index.d.mts +2 -0
- package/dist/diff/index.d.ts +2 -0
- package/dist/diff/index.js +84 -0
- package/dist/diff/index.js.map +1 -0
- package/dist/diff/index.mjs +78 -0
- package/dist/diff/index.mjs.map +1 -0
- package/dist/excel/index.d.mts +1 -0
- package/dist/excel/index.d.ts +1 -0
- package/dist/excel/index.js +163 -0
- package/dist/excel/index.js.map +1 -0
- package/dist/excel/index.mjs +153 -0
- package/dist/excel/index.mjs.map +1 -0
- package/dist/image/index.d.mts +1 -0
- package/dist/image/index.d.ts +1 -0
- package/dist/image/index.js +123 -0
- package/dist/image/index.js.map +1 -0
- package/dist/image/index.mjs +107 -0
- package/dist/image/index.mjs.map +1 -0
- package/dist/index--vbnYfdE.d.mts +142 -0
- package/dist/index--vbnYfdE.d.ts +142 -0
- package/dist/index-7FZQloN-.d.mts +62 -0
- package/dist/index-7FZQloN-.d.ts +62 -0
- package/dist/index-7XgaTVH5.d.mts +93 -0
- package/dist/index-7XgaTVH5.d.ts +93 -0
- package/dist/index-7bvFmh45.d.mts +87 -0
- package/dist/index-7bvFmh45.d.ts +87 -0
- package/dist/index-BDZcIVCU.d.mts +53 -0
- package/dist/index-BDZcIVCU.d.ts +53 -0
- package/dist/index-BN00EnUU.d.mts +55 -0
- package/dist/index-BN00EnUU.d.ts +55 -0
- package/dist/index-CQ1EukC4.d.mts +59 -0
- package/dist/index-CQ1EukC4.d.ts +59 -0
- package/dist/index-CgRVnFOt.d.mts +91 -0
- package/dist/index-CgRVnFOt.d.ts +91 -0
- package/dist/index-DjBDZzuj.d.mts +54 -0
- package/dist/index-DjBDZzuj.d.ts +54 -0
- package/dist/index-FFrvmr-n.d.mts +50 -0
- package/dist/index-FFrvmr-n.d.ts +50 -0
- package/dist/index-QWC8yIgW.d.mts +106 -0
- package/dist/index-QWC8yIgW.d.ts +106 -0
- package/dist/index-RVqNunxE.d.mts +193 -0
- package/dist/index-RVqNunxE.d.ts +193 -0
- package/dist/index-fJD8SORm.d.mts +61 -0
- package/dist/index-fJD8SORm.d.ts +61 -0
- package/dist/index-pPy_XDQU.d.mts +56 -0
- package/dist/index-pPy_XDQU.d.ts +56 -0
- package/dist/index-rwh9hdD9.d.mts +68 -0
- package/dist/index-rwh9hdD9.d.ts +68 -0
- package/dist/index-uXdkAfea.d.mts +93 -0
- package/dist/index-uXdkAfea.d.ts +93 -0
- package/dist/index.d.mts +17 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +3744 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3694 -0
- package/dist/index.mjs.map +1 -0
- package/dist/json/index.d.mts +1 -0
- package/dist/json/index.d.ts +1 -0
- package/dist/json/index.js +599 -0
- package/dist/json/index.js.map +1 -0
- package/dist/json/index.mjs +552 -0
- package/dist/json/index.mjs.map +1 -0
- package/dist/markdown/index.d.mts +1 -0
- package/dist/markdown/index.d.ts +1 -0
- package/dist/markdown/index.js +151 -0
- package/dist/markdown/index.js.map +1 -0
- package/dist/markdown/index.mjs +139 -0
- package/dist/markdown/index.mjs.map +1 -0
- package/dist/math/index.d.mts +1 -0
- package/dist/math/index.d.ts +1 -0
- package/dist/math/index.js +247 -0
- package/dist/math/index.js.map +1 -0
- package/dist/math/index.mjs +240 -0
- package/dist/math/index.mjs.map +1 -0
- package/dist/pdf/index.d.mts +1 -0
- package/dist/pdf/index.d.ts +1 -0
- package/dist/pdf/index.js +546 -0
- package/dist/pdf/index.js.map +1 -0
- package/dist/pdf/index.mjs +518 -0
- package/dist/pdf/index.mjs.map +1 -0
- package/dist/regex/index.d.mts +1 -0
- package/dist/regex/index.d.ts +1 -0
- package/dist/regex/index.js +93 -0
- package/dist/regex/index.js.map +1 -0
- package/dist/regex/index.mjs +88 -0
- package/dist/regex/index.mjs.map +1 -0
- package/dist/settings/index.d.mts +41 -0
- package/dist/settings/index.d.ts +41 -0
- package/dist/settings/index.js +146 -0
- package/dist/settings/index.js.map +1 -0
- package/dist/settings/index.mjs +139 -0
- package/dist/settings/index.mjs.map +1 -0
- package/dist/sql/index.d.mts +1 -0
- package/dist/sql/index.d.ts +1 -0
- package/dist/sql/index.js +146 -0
- package/dist/sql/index.js.map +1 -0
- package/dist/sql/index.mjs +139 -0
- package/dist/sql/index.mjs.map +1 -0
- package/dist/text/index.d.mts +1 -0
- package/dist/text/index.d.ts +1 -0
- package/dist/text/index.js +250 -0
- package/dist/text/index.js.map +1 -0
- package/dist/text/index.mjs +242 -0
- package/dist/text/index.mjs.map +1 -0
- package/dist/xml/index.d.mts +1 -0
- package/dist/xml/index.d.ts +1 -0
- package/dist/xml/index.js +188 -0
- package/dist/xml/index.js.map +1 -0
- package/dist/xml/index.mjs +180 -0
- package/dist/xml/index.mjs.map +1 -0
- package/package.json +150 -0
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var pdfLib = require('pdf-lib');
|
|
4
|
+
|
|
5
|
+
// src/pdf/utils.ts
|
|
6
|
+
function parsePageRanges(rangeStr, totalPages) {
|
|
7
|
+
const pages = /* @__PURE__ */ new Set();
|
|
8
|
+
const parts = rangeStr.split(",").map((s) => s.trim());
|
|
9
|
+
for (const part of parts) {
|
|
10
|
+
if (part.toLowerCase() === "all") {
|
|
11
|
+
for (let i = 1; i <= totalPages; i++) {
|
|
12
|
+
pages.add(i);
|
|
13
|
+
}
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (part.includes("-")) {
|
|
17
|
+
const [startStr, endStr] = part.split("-").map((s) => s.trim());
|
|
18
|
+
const start = parseInt(startStr, 10) || 1;
|
|
19
|
+
const end = parseInt(endStr, 10) || totalPages;
|
|
20
|
+
for (let i = Math.max(1, start); i <= Math.min(totalPages, end); i++) {
|
|
21
|
+
pages.add(i);
|
|
22
|
+
}
|
|
23
|
+
} else {
|
|
24
|
+
const page = parseInt(part, 10);
|
|
25
|
+
if (page >= 1 && page <= totalPages) {
|
|
26
|
+
pages.add(page);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return [...pages].sort((a, b) => a - b);
|
|
31
|
+
}
|
|
32
|
+
function parseRangesToGroups(rangeStr, totalPages) {
|
|
33
|
+
const ranges = [];
|
|
34
|
+
const parts = rangeStr.split(",").map((s) => s.trim());
|
|
35
|
+
for (const part of parts) {
|
|
36
|
+
if (part.toLowerCase() === "all") {
|
|
37
|
+
ranges.push({ start: 1, end: totalPages });
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (part.includes("-")) {
|
|
41
|
+
const [startStr, endStr] = part.split("-").map((s) => s.trim());
|
|
42
|
+
const start = parseInt(startStr, 10) || 1;
|
|
43
|
+
const end = parseInt(endStr, 10) || totalPages;
|
|
44
|
+
ranges.push({
|
|
45
|
+
start: Math.max(1, start),
|
|
46
|
+
end: Math.min(totalPages, end)
|
|
47
|
+
});
|
|
48
|
+
} else {
|
|
49
|
+
const page = parseInt(part, 10);
|
|
50
|
+
if (page >= 1 && page <= totalPages) {
|
|
51
|
+
ranges.push({ start: page, end: page });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return ranges;
|
|
56
|
+
}
|
|
57
|
+
function formatBytes(bytes) {
|
|
58
|
+
if (bytes === 0) return "0 B";
|
|
59
|
+
const k = 1024;
|
|
60
|
+
const sizes = ["B", "KB", "MB", "GB"];
|
|
61
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
62
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
|
|
63
|
+
}
|
|
64
|
+
function toUint8Array(data) {
|
|
65
|
+
if (data instanceof Uint8Array) {
|
|
66
|
+
return data;
|
|
67
|
+
}
|
|
68
|
+
if (data instanceof ArrayBuffer) {
|
|
69
|
+
return new Uint8Array(data);
|
|
70
|
+
}
|
|
71
|
+
if (Buffer.isBuffer(data)) {
|
|
72
|
+
return new Uint8Array(data);
|
|
73
|
+
}
|
|
74
|
+
throw new Error("Invalid data type");
|
|
75
|
+
}
|
|
76
|
+
async function merge(files, options = {}) {
|
|
77
|
+
const { pageRanges } = options;
|
|
78
|
+
const mergedPdf = await pdfLib.PDFDocument.create();
|
|
79
|
+
for (let i = 0; i < files.length; i++) {
|
|
80
|
+
const fileData = toUint8Array(files[i]);
|
|
81
|
+
const sourcePdf = await pdfLib.PDFDocument.load(fileData);
|
|
82
|
+
const totalPages = sourcePdf.getPageCount();
|
|
83
|
+
let pagesToCopy;
|
|
84
|
+
if (pageRanges && pageRanges[i]) {
|
|
85
|
+
pagesToCopy = parsePageRanges(pageRanges[i], totalPages);
|
|
86
|
+
} else {
|
|
87
|
+
pagesToCopy = Array.from({ length: totalPages }, (_, j) => j + 1);
|
|
88
|
+
}
|
|
89
|
+
const pageIndices = pagesToCopy.map((p) => p - 1);
|
|
90
|
+
const copiedPages = await mergedPdf.copyPages(sourcePdf, pageIndices);
|
|
91
|
+
for (const page of copiedPages) {
|
|
92
|
+
mergedPdf.addPage(page);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return mergedPdf.save();
|
|
96
|
+
}
|
|
97
|
+
async function mergeAll(files) {
|
|
98
|
+
return merge(files);
|
|
99
|
+
}
|
|
100
|
+
async function appendPages(target, source, pageRange) {
|
|
101
|
+
const targetPdf = await pdfLib.PDFDocument.load(toUint8Array(target));
|
|
102
|
+
const sourcePdf = await pdfLib.PDFDocument.load(toUint8Array(source));
|
|
103
|
+
const totalPages = sourcePdf.getPageCount();
|
|
104
|
+
const pagesToCopy = pageRange ? parsePageRanges(pageRange, totalPages) : Array.from({ length: totalPages }, (_, i) => i + 1);
|
|
105
|
+
const pageIndices = pagesToCopy.map((p) => p - 1);
|
|
106
|
+
const copiedPages = await targetPdf.copyPages(sourcePdf, pageIndices);
|
|
107
|
+
for (const page of copiedPages) {
|
|
108
|
+
targetPdf.addPage(page);
|
|
109
|
+
}
|
|
110
|
+
return targetPdf.save();
|
|
111
|
+
}
|
|
112
|
+
async function split(file, options) {
|
|
113
|
+
const { ranges } = options;
|
|
114
|
+
const fileData = toUint8Array(file);
|
|
115
|
+
const sourcePdf = await pdfLib.PDFDocument.load(fileData);
|
|
116
|
+
const totalPages = sourcePdf.getPageCount();
|
|
117
|
+
const rangeGroups = parseRangesToGroups(ranges, totalPages);
|
|
118
|
+
const results = [];
|
|
119
|
+
for (const range of rangeGroups) {
|
|
120
|
+
const newPdf = await pdfLib.PDFDocument.create();
|
|
121
|
+
const pageIndices = [];
|
|
122
|
+
for (let i = range.start; i <= range.end; i++) {
|
|
123
|
+
pageIndices.push(i - 1);
|
|
124
|
+
}
|
|
125
|
+
const copiedPages = await newPdf.copyPages(sourcePdf, pageIndices);
|
|
126
|
+
for (const page of copiedPages) {
|
|
127
|
+
newPdf.addPage(page);
|
|
128
|
+
}
|
|
129
|
+
results.push(await newPdf.save());
|
|
130
|
+
}
|
|
131
|
+
return results;
|
|
132
|
+
}
|
|
133
|
+
async function extractPages(file, pageRange) {
|
|
134
|
+
const fileData = toUint8Array(file);
|
|
135
|
+
const sourcePdf = await pdfLib.PDFDocument.load(fileData);
|
|
136
|
+
const totalPages = sourcePdf.getPageCount();
|
|
137
|
+
const pages = parsePageRanges(pageRange, totalPages);
|
|
138
|
+
const newPdf = await pdfLib.PDFDocument.create();
|
|
139
|
+
const pageIndices = pages.map((p) => p - 1);
|
|
140
|
+
const copiedPages = await newPdf.copyPages(sourcePdf, pageIndices);
|
|
141
|
+
for (const page of copiedPages) {
|
|
142
|
+
newPdf.addPage(page);
|
|
143
|
+
}
|
|
144
|
+
return newPdf.save();
|
|
145
|
+
}
|
|
146
|
+
async function splitEveryN(file, n) {
|
|
147
|
+
const fileData = toUint8Array(file);
|
|
148
|
+
const sourcePdf = await pdfLib.PDFDocument.load(fileData);
|
|
149
|
+
const totalPages = sourcePdf.getPageCount();
|
|
150
|
+
const ranges = [];
|
|
151
|
+
for (let i = 1; i <= totalPages; i += n) {
|
|
152
|
+
const end = Math.min(i + n - 1, totalPages);
|
|
153
|
+
ranges.push(`${i}-${end}`);
|
|
154
|
+
}
|
|
155
|
+
return split(file, { ranges: ranges.join(",") });
|
|
156
|
+
}
|
|
157
|
+
async function splitIntoSingle(file) {
|
|
158
|
+
return splitEveryN(file, 1);
|
|
159
|
+
}
|
|
160
|
+
async function getInfo(file) {
|
|
161
|
+
const fileData = toUint8Array(file);
|
|
162
|
+
const pdf = await pdfLib.PDFDocument.load(fileData, { ignoreEncryption: true });
|
|
163
|
+
return {
|
|
164
|
+
pageCount: pdf.getPageCount(),
|
|
165
|
+
metadata: {
|
|
166
|
+
title: pdf.getTitle(),
|
|
167
|
+
author: pdf.getAuthor(),
|
|
168
|
+
subject: pdf.getSubject(),
|
|
169
|
+
keywords: pdf.getKeywords()?.split(",").map((k) => k.trim()),
|
|
170
|
+
creator: pdf.getCreator(),
|
|
171
|
+
producer: pdf.getProducer(),
|
|
172
|
+
creationDate: pdf.getCreationDate(),
|
|
173
|
+
modificationDate: pdf.getModificationDate()
|
|
174
|
+
},
|
|
175
|
+
encrypted: false,
|
|
176
|
+
version: "PDF-1.7"
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
async function getMetadata(file) {
|
|
180
|
+
const info = await getInfo(file);
|
|
181
|
+
return info.metadata;
|
|
182
|
+
}
|
|
183
|
+
async function setMetadata(file, metadata) {
|
|
184
|
+
const fileData = toUint8Array(file);
|
|
185
|
+
const pdf = await pdfLib.PDFDocument.load(fileData);
|
|
186
|
+
if (metadata.title !== void 0) pdf.setTitle(metadata.title);
|
|
187
|
+
if (metadata.author !== void 0) pdf.setAuthor(metadata.author);
|
|
188
|
+
if (metadata.subject !== void 0) pdf.setSubject(metadata.subject);
|
|
189
|
+
if (metadata.keywords !== void 0) pdf.setKeywords(metadata.keywords);
|
|
190
|
+
if (metadata.creator !== void 0) pdf.setCreator(metadata.creator);
|
|
191
|
+
if (metadata.producer !== void 0) pdf.setProducer(metadata.producer);
|
|
192
|
+
return pdf.save();
|
|
193
|
+
}
|
|
194
|
+
async function getPageInfo(file) {
|
|
195
|
+
const fileData = toUint8Array(file);
|
|
196
|
+
const pdf = await pdfLib.PDFDocument.load(fileData);
|
|
197
|
+
const pages = pdf.getPages();
|
|
198
|
+
return pages.map((page, index) => ({
|
|
199
|
+
index,
|
|
200
|
+
width: page.getWidth(),
|
|
201
|
+
height: page.getHeight(),
|
|
202
|
+
rotation: page.getRotation().angle
|
|
203
|
+
}));
|
|
204
|
+
}
|
|
205
|
+
async function getPageCount(file) {
|
|
206
|
+
const fileData = toUint8Array(file);
|
|
207
|
+
const pdf = await pdfLib.PDFDocument.load(fileData);
|
|
208
|
+
return pdf.getPageCount();
|
|
209
|
+
}
|
|
210
|
+
async function rotate(file, options) {
|
|
211
|
+
const { pages: pageRange, degrees: deg } = options;
|
|
212
|
+
const fileData = toUint8Array(file);
|
|
213
|
+
const pdf = await pdfLib.PDFDocument.load(fileData);
|
|
214
|
+
const allPages = pdf.getPages();
|
|
215
|
+
const pagesToRotate = pageRange ? parsePageRanges(pageRange.join(","), allPages.length) : Array.from({ length: allPages.length }, (_, i) => i + 1);
|
|
216
|
+
for (const pageNum of pagesToRotate) {
|
|
217
|
+
const page = allPages[pageNum - 1];
|
|
218
|
+
if (page) {
|
|
219
|
+
const currentRotation = page.getRotation().angle;
|
|
220
|
+
page.setRotation(pdfLib.degrees(currentRotation + deg));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return pdf.save();
|
|
224
|
+
}
|
|
225
|
+
async function addWatermark(file, options) {
|
|
226
|
+
const {
|
|
227
|
+
text = "WATERMARK",
|
|
228
|
+
opacity = 0.3,
|
|
229
|
+
rotation = -45,
|
|
230
|
+
position = "center",
|
|
231
|
+
fontSize = 50,
|
|
232
|
+
color = { r: 0.5, g: 0.5, b: 0.5 }
|
|
233
|
+
} = options;
|
|
234
|
+
const fileData = toUint8Array(file);
|
|
235
|
+
const pdf = await pdfLib.PDFDocument.load(fileData);
|
|
236
|
+
const font = await pdf.embedFont(pdfLib.StandardFonts.Helvetica);
|
|
237
|
+
const pages = pdf.getPages();
|
|
238
|
+
for (const page of pages) {
|
|
239
|
+
const { width, height } = page.getSize();
|
|
240
|
+
const textWidth = font.widthOfTextAtSize(text, fontSize);
|
|
241
|
+
const x = (width - textWidth) / 2;
|
|
242
|
+
let y = height / 2;
|
|
243
|
+
if (position === "top") {
|
|
244
|
+
y = height - fontSize - 20;
|
|
245
|
+
} else if (position === "bottom") {
|
|
246
|
+
y = 20;
|
|
247
|
+
}
|
|
248
|
+
page.drawText(text, {
|
|
249
|
+
x,
|
|
250
|
+
y,
|
|
251
|
+
size: fontSize,
|
|
252
|
+
font,
|
|
253
|
+
color: pdfLib.rgb(color.r, color.g, color.b),
|
|
254
|
+
opacity,
|
|
255
|
+
rotate: pdfLib.degrees(rotation)
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
return pdf.save();
|
|
259
|
+
}
|
|
260
|
+
async function reorderPages(file, newOrder) {
|
|
261
|
+
const fileData = toUint8Array(file);
|
|
262
|
+
const sourcePdf = await pdfLib.PDFDocument.load(fileData);
|
|
263
|
+
const newPdf = await pdfLib.PDFDocument.create();
|
|
264
|
+
const pageIndices = newOrder.map((p) => p - 1);
|
|
265
|
+
const copiedPages = await newPdf.copyPages(sourcePdf, pageIndices);
|
|
266
|
+
for (const page of copiedPages) {
|
|
267
|
+
newPdf.addPage(page);
|
|
268
|
+
}
|
|
269
|
+
return newPdf.save();
|
|
270
|
+
}
|
|
271
|
+
async function deletePage(file, pageNumbers) {
|
|
272
|
+
const fileData = toUint8Array(file);
|
|
273
|
+
const pdf = await pdfLib.PDFDocument.load(fileData);
|
|
274
|
+
const totalPages = pdf.getPageCount();
|
|
275
|
+
const sortedPageNumbers = [...pageNumbers].sort((a, b) => b - a);
|
|
276
|
+
for (const pageNum of sortedPageNumbers) {
|
|
277
|
+
if (pageNum >= 1 && pageNum <= totalPages) {
|
|
278
|
+
pdf.removePage(pageNum - 1);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return pdf.save();
|
|
282
|
+
}
|
|
283
|
+
async function compress(file, _options = { quality: "medium" }) {
|
|
284
|
+
const fileData = toUint8Array(file);
|
|
285
|
+
const pdf = await pdfLib.PDFDocument.load(fileData);
|
|
286
|
+
return pdf.save({
|
|
287
|
+
useObjectStreams: true,
|
|
288
|
+
addDefaultPage: false
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// src/pdf/extract.ts
|
|
293
|
+
async function extractText(file, options = {}) {
|
|
294
|
+
const { pages: pageNums } = options;
|
|
295
|
+
const fileData = toUint8Array(file);
|
|
296
|
+
try {
|
|
297
|
+
const pdfParse = await import('pdf-parse');
|
|
298
|
+
const parser = pdfParse.default || pdfParse;
|
|
299
|
+
if (pageNums && pageNums.length > 0) {
|
|
300
|
+
const result2 = await parser(Buffer.from(fileData), {
|
|
301
|
+
max: Math.max(...pageNums)
|
|
302
|
+
});
|
|
303
|
+
return result2.text;
|
|
304
|
+
}
|
|
305
|
+
const result = await parser(Buffer.from(fileData));
|
|
306
|
+
return result.text;
|
|
307
|
+
} catch (error) {
|
|
308
|
+
throw new Error(`Failed to extract text: ${error.message}`);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
async function extractTextFromPages(file, pageRange) {
|
|
312
|
+
const fileData = toUint8Array(file);
|
|
313
|
+
try {
|
|
314
|
+
const pdfParse = await import('pdf-parse');
|
|
315
|
+
const parser = pdfParse.default || pdfParse;
|
|
316
|
+
const result = await parser(Buffer.from(fileData));
|
|
317
|
+
const totalPages = result.numpages;
|
|
318
|
+
const pages = parsePageRanges(pageRange, totalPages);
|
|
319
|
+
const pageTexts = {};
|
|
320
|
+
const fullText = result.text;
|
|
321
|
+
const textPerPage = fullText.length / totalPages;
|
|
322
|
+
for (const pageNum of pages) {
|
|
323
|
+
const start = (pageNum - 1) * textPerPage;
|
|
324
|
+
const end = pageNum * textPerPage;
|
|
325
|
+
pageTexts[pageNum] = fullText.slice(start, end).trim();
|
|
326
|
+
}
|
|
327
|
+
return pageTexts;
|
|
328
|
+
} catch (error) {
|
|
329
|
+
throw new Error(`Failed to extract text: ${error.message}`);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
async function hasText(file) {
|
|
333
|
+
try {
|
|
334
|
+
const text = await extractText(file);
|
|
335
|
+
return text.trim().length > 0;
|
|
336
|
+
} catch {
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
var PLACEHOLDER_REGEX = /\{\{(\w+)\}\}/g;
|
|
341
|
+
function extractFieldName(content) {
|
|
342
|
+
const match = content.match(/^\{\{(\w+)\}\}$/);
|
|
343
|
+
return match ? match[1] : void 0;
|
|
344
|
+
}
|
|
345
|
+
function resolveContent(content, data, missingFieldBehavior, fields) {
|
|
346
|
+
return content.replace(PLACEHOLDER_REGEX, (match, fieldName) => {
|
|
347
|
+
if (fieldName in data) {
|
|
348
|
+
return data[fieldName];
|
|
349
|
+
}
|
|
350
|
+
switch (missingFieldBehavior) {
|
|
351
|
+
case "use_default": {
|
|
352
|
+
const field = fields.find((f) => f.name === fieldName);
|
|
353
|
+
return field?.defaultValue ?? "";
|
|
354
|
+
}
|
|
355
|
+
case "empty_string":
|
|
356
|
+
return "";
|
|
357
|
+
case "leave_placeholder":
|
|
358
|
+
default:
|
|
359
|
+
return match;
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
function resolveFont(font, defaults) {
|
|
364
|
+
return font ?? defaults?.font ?? { name: "Helvetica", size: 12 };
|
|
365
|
+
}
|
|
366
|
+
async function pdfToTemplate(file, options = {}) {
|
|
367
|
+
const fileData = toUint8Array(file);
|
|
368
|
+
const pdfDoc = await pdfLib.PDFDocument.load(fileData, { ignoreEncryption: true });
|
|
369
|
+
const pageCount = pdfDoc.getPageCount();
|
|
370
|
+
const pdfPages = pdfDoc.getPages();
|
|
371
|
+
let fullText = "";
|
|
372
|
+
try {
|
|
373
|
+
const pdfParse = await import('pdf-parse');
|
|
374
|
+
const parser = pdfParse.default || pdfParse;
|
|
375
|
+
const parsed = await parser(Buffer.from(fileData));
|
|
376
|
+
fullText = parsed.text;
|
|
377
|
+
} catch {
|
|
378
|
+
fullText = "";
|
|
379
|
+
}
|
|
380
|
+
const textPerPage = pageCount > 0 ? fullText.length / pageCount : 0;
|
|
381
|
+
const fieldsMap = /* @__PURE__ */ new Map();
|
|
382
|
+
const fonts = {};
|
|
383
|
+
const defaultFont = { name: "Helvetica", size: 12 };
|
|
384
|
+
fonts["Helvetica-12"] = defaultFont;
|
|
385
|
+
const pages = pdfPages.map((page, pageIndex) => {
|
|
386
|
+
const { width, height } = page.getSize();
|
|
387
|
+
const start = Math.floor(pageIndex * textPerPage);
|
|
388
|
+
const end = Math.floor((pageIndex + 1) * textPerPage);
|
|
389
|
+
const pageText = fullText.slice(start, end).trim();
|
|
390
|
+
const elements = [];
|
|
391
|
+
if (pageText) {
|
|
392
|
+
const lines = pageText.split("\n").filter((l) => l.trim());
|
|
393
|
+
const lineHeight = 14;
|
|
394
|
+
let yPos = height - 40;
|
|
395
|
+
for (const line of lines) {
|
|
396
|
+
const hasPlaceholder = PLACEHOLDER_REGEX.test(line);
|
|
397
|
+
PLACEHOLDER_REGEX.lastIndex = 0;
|
|
398
|
+
const element = {
|
|
399
|
+
type: hasPlaceholder ? "placeholder" : "text",
|
|
400
|
+
content: line.trim(),
|
|
401
|
+
x: 40,
|
|
402
|
+
y: yPos,
|
|
403
|
+
font: defaultFont
|
|
404
|
+
};
|
|
405
|
+
if (hasPlaceholder) {
|
|
406
|
+
const fieldName = extractFieldName(line.trim());
|
|
407
|
+
if (fieldName) {
|
|
408
|
+
element.fieldName = fieldName;
|
|
409
|
+
}
|
|
410
|
+
let match;
|
|
411
|
+
PLACEHOLDER_REGEX.lastIndex = 0;
|
|
412
|
+
while ((match = PLACEHOLDER_REGEX.exec(line)) !== null) {
|
|
413
|
+
const name = match[1];
|
|
414
|
+
if (!fieldsMap.has(name)) {
|
|
415
|
+
fieldsMap.set(name, { pages: /* @__PURE__ */ new Set(), defaultValue: "" });
|
|
416
|
+
}
|
|
417
|
+
fieldsMap.get(name).pages.add(pageIndex + 1);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
elements.push(element);
|
|
421
|
+
yPos -= lineHeight;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
return { width, height, elements };
|
|
425
|
+
});
|
|
426
|
+
const fields = [];
|
|
427
|
+
for (const [name, info] of fieldsMap) {
|
|
428
|
+
fields.push({
|
|
429
|
+
name,
|
|
430
|
+
defaultValue: info.defaultValue,
|
|
431
|
+
pages: [...info.pages].sort((a, b) => a - b)
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
return {
|
|
435
|
+
version: "1.0",
|
|
436
|
+
metadata: {
|
|
437
|
+
name: options.name,
|
|
438
|
+
description: options.description,
|
|
439
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
440
|
+
sourcePageCount: pageCount
|
|
441
|
+
},
|
|
442
|
+
pages,
|
|
443
|
+
fields,
|
|
444
|
+
fonts,
|
|
445
|
+
defaults: {
|
|
446
|
+
font: defaultFont,
|
|
447
|
+
color: { r: 0, g: 0, b: 0 },
|
|
448
|
+
missingFieldBehavior: "leave_placeholder"
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
async function templateToPdf(template, data = {}, options = {}) {
|
|
453
|
+
validateTemplate(template);
|
|
454
|
+
const pdfDoc = await pdfLib.PDFDocument.create();
|
|
455
|
+
const font = await pdfDoc.embedFont(pdfLib.StandardFonts.Helvetica);
|
|
456
|
+
const boldFont = await pdfDoc.embedFont(pdfLib.StandardFonts.HelveticaBold);
|
|
457
|
+
const missingFieldBehavior = options.missingFieldBehavior ?? template.defaults?.missingFieldBehavior ?? "leave_placeholder";
|
|
458
|
+
const defaultColor = template.defaults?.color ?? { r: 0, g: 0, b: 0 };
|
|
459
|
+
for (const templatePage of template.pages) {
|
|
460
|
+
const page = pdfDoc.addPage([templatePage.width, templatePage.height]);
|
|
461
|
+
for (const element of templatePage.elements) {
|
|
462
|
+
const resolvedFont = resolveFont(element.font, template.defaults);
|
|
463
|
+
const color = element.color ?? defaultColor;
|
|
464
|
+
const pdfFont = resolvedFont.weight === "bold" ? boldFont : font;
|
|
465
|
+
const fontSize = resolvedFont.size;
|
|
466
|
+
const content = element.type === "placeholder" ? resolveContent(element.content, data, missingFieldBehavior, template.fields) : element.content;
|
|
467
|
+
page.drawText(content, {
|
|
468
|
+
x: element.x,
|
|
469
|
+
y: element.y,
|
|
470
|
+
size: fontSize,
|
|
471
|
+
font: pdfFont,
|
|
472
|
+
color: pdfLib.rgb(color.r, color.g, color.b)
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
return pdfDoc.save();
|
|
477
|
+
}
|
|
478
|
+
function validateTemplate(template) {
|
|
479
|
+
if (!template) {
|
|
480
|
+
throw new Error("Template is required");
|
|
481
|
+
}
|
|
482
|
+
if (template.version !== "1.0") {
|
|
483
|
+
throw new Error(`Unsupported template version: ${template.version}`);
|
|
484
|
+
}
|
|
485
|
+
if (!Array.isArray(template.pages) || template.pages.length === 0) {
|
|
486
|
+
throw new Error("Template must have at least one page");
|
|
487
|
+
}
|
|
488
|
+
if (!template.metadata) {
|
|
489
|
+
throw new Error("Template metadata is required");
|
|
490
|
+
}
|
|
491
|
+
if (typeof template.metadata.sourcePageCount !== "number" || template.metadata.sourcePageCount < 1) {
|
|
492
|
+
throw new Error("Template metadata.sourcePageCount must be a positive number");
|
|
493
|
+
}
|
|
494
|
+
if (!Array.isArray(template.fields)) {
|
|
495
|
+
throw new Error("Template fields must be an array");
|
|
496
|
+
}
|
|
497
|
+
for (const page of template.pages) {
|
|
498
|
+
if (typeof page.width !== "number" || typeof page.height !== "number") {
|
|
499
|
+
throw new Error("Each page must have numeric width and height");
|
|
500
|
+
}
|
|
501
|
+
if (!Array.isArray(page.elements)) {
|
|
502
|
+
throw new Error("Each page must have an elements array");
|
|
503
|
+
}
|
|
504
|
+
for (const element of page.elements) {
|
|
505
|
+
if (element.type !== "text" && element.type !== "placeholder") {
|
|
506
|
+
throw new Error(`Invalid element type: ${element.type}`);
|
|
507
|
+
}
|
|
508
|
+
if (typeof element.content !== "string") {
|
|
509
|
+
throw new Error("Element content must be a string");
|
|
510
|
+
}
|
|
511
|
+
if (typeof element.x !== "number" || typeof element.y !== "number") {
|
|
512
|
+
throw new Error("Element x and y must be numbers");
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
exports.addWatermark = addWatermark;
|
|
519
|
+
exports.appendPages = appendPages;
|
|
520
|
+
exports.compress = compress;
|
|
521
|
+
exports.deletePage = deletePage;
|
|
522
|
+
exports.extractPages = extractPages;
|
|
523
|
+
exports.extractText = extractText;
|
|
524
|
+
exports.extractTextFromPages = extractTextFromPages;
|
|
525
|
+
exports.formatBytes = formatBytes;
|
|
526
|
+
exports.getInfo = getInfo;
|
|
527
|
+
exports.getMetadata = getMetadata;
|
|
528
|
+
exports.getPageCount = getPageCount;
|
|
529
|
+
exports.getPageInfo = getPageInfo;
|
|
530
|
+
exports.hasText = hasText;
|
|
531
|
+
exports.merge = merge;
|
|
532
|
+
exports.mergeAll = mergeAll;
|
|
533
|
+
exports.parsePageRanges = parsePageRanges;
|
|
534
|
+
exports.parseRangesToGroups = parseRangesToGroups;
|
|
535
|
+
exports.pdfToTemplate = pdfToTemplate;
|
|
536
|
+
exports.reorderPages = reorderPages;
|
|
537
|
+
exports.rotate = rotate;
|
|
538
|
+
exports.setMetadata = setMetadata;
|
|
539
|
+
exports.split = split;
|
|
540
|
+
exports.splitEveryN = splitEveryN;
|
|
541
|
+
exports.splitIntoSingle = splitIntoSingle;
|
|
542
|
+
exports.templateToPdf = templateToPdf;
|
|
543
|
+
exports.toUint8Array = toUint8Array;
|
|
544
|
+
exports.validateTemplate = validateTemplate;
|
|
545
|
+
//# sourceMappingURL=index.js.map
|
|
546
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/pdf/utils.ts","../../src/pdf/merge.ts","../../src/pdf/split.ts","../../src/pdf/metadata.ts","../../src/pdf/transform.ts","../../src/pdf/extract.ts","../../src/pdf/template.ts"],"names":["PDFDocument","degrees","StandardFonts","rgb","result"],"mappings":"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","file":"index.js","sourcesContent":["import type { PageRange } from './types';\n\nexport function parsePageRanges(rangeStr: string, totalPages: number): number[] {\n const pages: Set<number> = new Set();\n const parts = rangeStr.split(',').map((s) => s.trim());\n\n for (const part of parts) {\n if (part.toLowerCase() === 'all') {\n for (let i = 1; i <= totalPages; i++) {\n pages.add(i);\n }\n continue;\n }\n\n if (part.includes('-')) {\n const [startStr, endStr] = part.split('-').map((s) => s.trim());\n const start = parseInt(startStr, 10) || 1;\n const end = parseInt(endStr, 10) || totalPages;\n\n for (let i = Math.max(1, start); i <= Math.min(totalPages, end); i++) {\n pages.add(i);\n }\n } else {\n const page = parseInt(part, 10);\n if (page >= 1 && page <= totalPages) {\n pages.add(page);\n }\n }\n }\n\n return [...pages].sort((a, b) => a - b);\n}\n\nexport function parseRangesToGroups(\n rangeStr: string,\n totalPages: number\n): PageRange[] {\n const ranges: PageRange[] = [];\n const parts = rangeStr.split(',').map((s) => s.trim());\n\n for (const part of parts) {\n if (part.toLowerCase() === 'all') {\n ranges.push({ start: 1, end: totalPages });\n continue;\n }\n\n if (part.includes('-')) {\n const [startStr, endStr] = part.split('-').map((s) => s.trim());\n const start = parseInt(startStr, 10) || 1;\n const end = parseInt(endStr, 10) || totalPages;\n ranges.push({\n start: Math.max(1, start),\n end: Math.min(totalPages, end),\n });\n } else {\n const page = parseInt(part, 10);\n if (page >= 1 && page <= totalPages) {\n ranges.push({ start: page, end: page });\n }\n }\n }\n\n return ranges;\n}\n\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B';\n\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\n}\n\nexport function toUint8Array(data: Buffer | Uint8Array | ArrayBuffer): Uint8Array {\n if (data instanceof Uint8Array) {\n return data;\n }\n if (data instanceof ArrayBuffer) {\n return new Uint8Array(data);\n }\n if (Buffer.isBuffer(data)) {\n return new Uint8Array(data);\n }\n throw new Error('Invalid data type');\n}\n","import { PDFDocument } from 'pdf-lib';\nimport type { MergeOptions } from './types';\nimport { parsePageRanges, toUint8Array } from './utils';\n\nexport async function merge(\n files: (Buffer | Uint8Array)[],\n options: MergeOptions = {}\n): Promise<Uint8Array> {\n const { pageRanges } = options;\n\n const mergedPdf = await PDFDocument.create();\n\n for (let i = 0; i < files.length; i++) {\n const fileData = toUint8Array(files[i]);\n const sourcePdf = await PDFDocument.load(fileData);\n const totalPages = sourcePdf.getPageCount();\n\n let pagesToCopy: number[];\n\n if (pageRanges && pageRanges[i]) {\n pagesToCopy = parsePageRanges(pageRanges[i], totalPages);\n } else {\n pagesToCopy = Array.from({ length: totalPages }, (_, j) => j + 1);\n }\n\n const pageIndices = pagesToCopy.map((p) => p - 1);\n const copiedPages = await mergedPdf.copyPages(sourcePdf, pageIndices);\n\n for (const page of copiedPages) {\n mergedPdf.addPage(page);\n }\n }\n\n return mergedPdf.save();\n}\n\nexport async function mergeAll(files: (Buffer | Uint8Array)[]): Promise<Uint8Array> {\n return merge(files);\n}\n\nexport async function appendPages(\n target: Buffer | Uint8Array,\n source: Buffer | Uint8Array,\n pageRange?: string\n): Promise<Uint8Array> {\n const targetPdf = await PDFDocument.load(toUint8Array(target));\n const sourcePdf = await PDFDocument.load(toUint8Array(source));\n\n const totalPages = sourcePdf.getPageCount();\n const pagesToCopy = pageRange\n ? parsePageRanges(pageRange, totalPages)\n : Array.from({ length: totalPages }, (_, i) => i + 1);\n\n const pageIndices = pagesToCopy.map((p) => p - 1);\n const copiedPages = await targetPdf.copyPages(sourcePdf, pageIndices);\n\n for (const page of copiedPages) {\n targetPdf.addPage(page);\n }\n\n return targetPdf.save();\n}\n","import { PDFDocument } from 'pdf-lib';\nimport type { SplitOptions } from './types';\nimport { parsePageRanges, parseRangesToGroups, toUint8Array } from './utils';\n\nexport async function split(\n file: Buffer | Uint8Array,\n options: SplitOptions\n): Promise<Uint8Array[]> {\n const { ranges } = options;\n const fileData = toUint8Array(file);\n const sourcePdf = await PDFDocument.load(fileData);\n const totalPages = sourcePdf.getPageCount();\n\n const rangeGroups = parseRangesToGroups(ranges, totalPages);\n const results: Uint8Array[] = [];\n\n for (const range of rangeGroups) {\n const newPdf = await PDFDocument.create();\n const pageIndices: number[] = [];\n\n for (let i = range.start; i <= range.end; i++) {\n pageIndices.push(i - 1);\n }\n\n const copiedPages = await newPdf.copyPages(sourcePdf, pageIndices);\n for (const page of copiedPages) {\n newPdf.addPage(page);\n }\n\n results.push(await newPdf.save());\n }\n\n return results;\n}\n\nexport async function extractPages(\n file: Buffer | Uint8Array,\n pageRange: string\n): Promise<Uint8Array> {\n const fileData = toUint8Array(file);\n const sourcePdf = await PDFDocument.load(fileData);\n const totalPages = sourcePdf.getPageCount();\n\n const pages = parsePageRanges(pageRange, totalPages);\n const newPdf = await PDFDocument.create();\n\n const pageIndices = pages.map((p) => p - 1);\n const copiedPages = await newPdf.copyPages(sourcePdf, pageIndices);\n\n for (const page of copiedPages) {\n newPdf.addPage(page);\n }\n\n return newPdf.save();\n}\n\nexport async function splitEveryN(\n file: Buffer | Uint8Array,\n n: number\n): Promise<Uint8Array[]> {\n const fileData = toUint8Array(file);\n const sourcePdf = await PDFDocument.load(fileData);\n const totalPages = sourcePdf.getPageCount();\n\n const ranges: string[] = [];\n for (let i = 1; i <= totalPages; i += n) {\n const end = Math.min(i + n - 1, totalPages);\n ranges.push(`${i}-${end}`);\n }\n\n return split(file, { ranges: ranges.join(',') });\n}\n\nexport async function splitIntoSingle(\n file: Buffer | Uint8Array\n): Promise<Uint8Array[]> {\n return splitEveryN(file, 1);\n}\n","import { PDFDocument } from 'pdf-lib';\nimport type { PDFMetadata, PDFInfo, PageInfo } from './types';\nimport { toUint8Array } from './utils';\n\nexport async function getInfo(file: Buffer | Uint8Array): Promise<PDFInfo> {\n const fileData = toUint8Array(file);\n const pdf = await PDFDocument.load(fileData, { ignoreEncryption: true });\n\n return {\n pageCount: pdf.getPageCount(),\n metadata: {\n title: pdf.getTitle(),\n author: pdf.getAuthor(),\n subject: pdf.getSubject(),\n keywords: pdf.getKeywords()?.split(',').map((k) => k.trim()),\n creator: pdf.getCreator(),\n producer: pdf.getProducer(),\n creationDate: pdf.getCreationDate(),\n modificationDate: pdf.getModificationDate(),\n },\n encrypted: false,\n version: 'PDF-1.7',\n };\n}\n\nexport async function getMetadata(file: Buffer | Uint8Array): Promise<PDFMetadata> {\n const info = await getInfo(file);\n return info.metadata;\n}\n\nexport async function setMetadata(\n file: Buffer | Uint8Array,\n metadata: Partial<PDFMetadata>\n): Promise<Uint8Array> {\n const fileData = toUint8Array(file);\n const pdf = await PDFDocument.load(fileData);\n\n if (metadata.title !== undefined) pdf.setTitle(metadata.title);\n if (metadata.author !== undefined) pdf.setAuthor(metadata.author);\n if (metadata.subject !== undefined) pdf.setSubject(metadata.subject);\n if (metadata.keywords !== undefined) pdf.setKeywords(metadata.keywords);\n if (metadata.creator !== undefined) pdf.setCreator(metadata.creator);\n if (metadata.producer !== undefined) pdf.setProducer(metadata.producer);\n\n return pdf.save();\n}\n\nexport async function getPageInfo(file: Buffer | Uint8Array): Promise<PageInfo[]> {\n const fileData = toUint8Array(file);\n const pdf = await PDFDocument.load(fileData);\n\n const pages = pdf.getPages();\n return pages.map((page, index) => ({\n index,\n width: page.getWidth(),\n height: page.getHeight(),\n rotation: page.getRotation().angle,\n }));\n}\n\nexport async function getPageCount(file: Buffer | Uint8Array): Promise<number> {\n const fileData = toUint8Array(file);\n const pdf = await PDFDocument.load(fileData);\n return pdf.getPageCount();\n}\n","import { PDFDocument, degrees, rgb, StandardFonts } from 'pdf-lib';\nimport type { RotateOptions, WatermarkOptions, CompressOptions } from './types';\nimport { parsePageRanges, toUint8Array } from './utils';\n\nexport async function rotate(\n file: Buffer | Uint8Array,\n options: RotateOptions\n): Promise<Uint8Array> {\n const { pages: pageRange, degrees: deg } = options;\n const fileData = toUint8Array(file);\n const pdf = await PDFDocument.load(fileData);\n\n const allPages = pdf.getPages();\n const pagesToRotate = pageRange\n ? parsePageRanges(pageRange.join(','), allPages.length)\n : Array.from({ length: allPages.length }, (_, i) => i + 1);\n\n for (const pageNum of pagesToRotate) {\n const page = allPages[pageNum - 1];\n if (page) {\n const currentRotation = page.getRotation().angle;\n page.setRotation(degrees(currentRotation + deg));\n }\n }\n\n return pdf.save();\n}\n\nexport async function addWatermark(\n file: Buffer | Uint8Array,\n options: WatermarkOptions\n): Promise<Uint8Array> {\n const {\n text = 'WATERMARK',\n opacity = 0.3,\n rotation = -45,\n position = 'center',\n fontSize = 50,\n color = { r: 0.5, g: 0.5, b: 0.5 },\n } = options;\n\n const fileData = toUint8Array(file);\n const pdf = await PDFDocument.load(fileData);\n const font = await pdf.embedFont(StandardFonts.Helvetica);\n\n const pages = pdf.getPages();\n\n for (const page of pages) {\n const { width, height } = page.getSize();\n const textWidth = font.widthOfTextAtSize(text, fontSize);\n\n const x = (width - textWidth) / 2;\n let y = height / 2;\n\n if (position === 'top') {\n y = height - fontSize - 20;\n } else if (position === 'bottom') {\n y = 20;\n }\n\n page.drawText(text, {\n x,\n y,\n size: fontSize,\n font,\n color: rgb(color.r, color.g, color.b),\n opacity,\n rotate: degrees(rotation),\n });\n }\n\n return pdf.save();\n}\n\nexport async function reorderPages(\n file: Buffer | Uint8Array,\n newOrder: number[]\n): Promise<Uint8Array> {\n const fileData = toUint8Array(file);\n const sourcePdf = await PDFDocument.load(fileData);\n const newPdf = await PDFDocument.create();\n\n const pageIndices = newOrder.map((p) => p - 1);\n const copiedPages = await newPdf.copyPages(sourcePdf, pageIndices);\n\n for (const page of copiedPages) {\n newPdf.addPage(page);\n }\n\n return newPdf.save();\n}\n\nexport async function deletePage(\n file: Buffer | Uint8Array,\n pageNumbers: number[]\n): Promise<Uint8Array> {\n const fileData = toUint8Array(file);\n const pdf = await PDFDocument.load(fileData);\n const totalPages = pdf.getPageCount();\n\n const sortedPageNumbers = [...pageNumbers].sort((a, b) => b - a);\n\n for (const pageNum of sortedPageNumbers) {\n if (pageNum >= 1 && pageNum <= totalPages) {\n pdf.removePage(pageNum - 1);\n }\n }\n\n return pdf.save();\n}\n\nexport async function compress(\n file: Buffer | Uint8Array,\n _options: CompressOptions = { quality: 'medium' }\n): Promise<Uint8Array> {\n const fileData = toUint8Array(file);\n const pdf = await PDFDocument.load(fileData);\n\n return pdf.save({\n useObjectStreams: true,\n addDefaultPage: false,\n });\n}\n","import type { ExtractTextOptions } from './types';\nimport { toUint8Array, parsePageRanges } from './utils';\n\nexport async function extractText(\n file: Buffer | Uint8Array,\n options: ExtractTextOptions = {}\n): Promise<string> {\n const { pages: pageNums } = options;\n const fileData = toUint8Array(file);\n\n try {\n const pdfParse = await import('pdf-parse');\n const parser = pdfParse.default || pdfParse;\n\n if (pageNums && pageNums.length > 0) {\n const result = await parser(Buffer.from(fileData), {\n max: Math.max(...pageNums),\n });\n\n return result.text;\n }\n\n const result = await parser(Buffer.from(fileData));\n return result.text;\n } catch (error) {\n throw new Error(`Failed to extract text: ${(error as Error).message}`);\n }\n}\n\nexport async function extractTextFromPages(\n file: Buffer | Uint8Array,\n pageRange: string\n): Promise<Record<number, string>> {\n const fileData = toUint8Array(file);\n\n try {\n const pdfParse = await import('pdf-parse');\n const parser = pdfParse.default || pdfParse;\n\n const result = await parser(Buffer.from(fileData));\n const totalPages = result.numpages;\n const pages = parsePageRanges(pageRange, totalPages);\n\n const pageTexts: Record<number, string> = {};\n\n const fullText = result.text;\n const textPerPage = fullText.length / totalPages;\n\n for (const pageNum of pages) {\n const start = (pageNum - 1) * textPerPage;\n const end = pageNum * textPerPage;\n pageTexts[pageNum] = fullText.slice(start, end).trim();\n }\n\n return pageTexts;\n } catch (error) {\n throw new Error(`Failed to extract text: ${(error as Error).message}`);\n }\n}\n\nexport async function hasText(file: Buffer | Uint8Array): Promise<boolean> {\n try {\n const text = await extractText(file);\n return text.trim().length > 0;\n } catch {\n return false;\n }\n}\n","import { PDFDocument, StandardFonts, rgb } from 'pdf-lib';\nimport type {\n PDFTemplate,\n TemplatePage,\n TemplateElement,\n TemplateField,\n TemplateFont,\n PdfToTemplateOptions,\n TemplateToPdfOptions,\n} from './types';\nimport { toUint8Array } from './utils';\n\nconst PLACEHOLDER_REGEX = /\\{\\{(\\w+)\\}\\}/g;\n\nfunction extractFieldName(content: string): string | undefined {\n const match = content.match(/^\\{\\{(\\w+)\\}\\}$/);\n return match ? match[1] : undefined;\n}\n\nfunction resolveContent(\n content: string,\n data: Record<string, string>,\n missingFieldBehavior: 'leave_placeholder' | 'use_default' | 'empty_string',\n fields: TemplateField[]\n): string {\n return content.replace(PLACEHOLDER_REGEX, (match, fieldName) => {\n if (fieldName in data) {\n return data[fieldName];\n }\n switch (missingFieldBehavior) {\n case 'use_default': {\n const field = fields.find((f) => f.name === fieldName);\n return field?.defaultValue ?? '';\n }\n case 'empty_string':\n return '';\n case 'leave_placeholder':\n default:\n return match;\n }\n });\n}\n\nfunction resolveFont(\n font: TemplateFont | undefined,\n defaults: PDFTemplate['defaults']\n): TemplateFont {\n return font ?? defaults?.font ?? { name: 'Helvetica', size: 12 };\n}\n\nexport async function pdfToTemplate(\n file: Buffer | Uint8Array,\n options: PdfToTemplateOptions = {}\n): Promise<PDFTemplate> {\n const fileData = toUint8Array(file);\n const pdfDoc = await PDFDocument.load(fileData, { ignoreEncryption: true });\n const pageCount = pdfDoc.getPageCount();\n const pdfPages = pdfDoc.getPages();\n\n let fullText = '';\n try {\n const pdfParse = await import('pdf-parse');\n const parser = pdfParse.default || pdfParse;\n const parsed = await parser(Buffer.from(fileData));\n fullText = parsed.text;\n } catch {\n fullText = '';\n }\n\n const textPerPage = pageCount > 0 ? fullText.length / pageCount : 0;\n const fieldsMap = new Map<string, { pages: Set<number>; defaultValue: string }>();\n const fonts: Record<string, TemplateFont> = {};\n const defaultFont: TemplateFont = { name: 'Helvetica', size: 12 };\n\n fonts['Helvetica-12'] = defaultFont;\n\n const pages: TemplatePage[] = pdfPages.map((page, pageIndex) => {\n const { width, height } = page.getSize();\n\n const start = Math.floor(pageIndex * textPerPage);\n const end = Math.floor((pageIndex + 1) * textPerPage);\n const pageText = fullText.slice(start, end).trim();\n\n const elements: TemplateElement[] = [];\n\n if (pageText) {\n const lines = pageText.split('\\n').filter((l) => l.trim());\n const lineHeight = 14;\n let yPos = height - 40;\n\n for (const line of lines) {\n const hasPlaceholder = PLACEHOLDER_REGEX.test(line);\n PLACEHOLDER_REGEX.lastIndex = 0;\n\n const element: TemplateElement = {\n type: hasPlaceholder ? 'placeholder' : 'text',\n content: line.trim(),\n x: 40,\n y: yPos,\n font: defaultFont,\n };\n\n if (hasPlaceholder) {\n const fieldName = extractFieldName(line.trim());\n if (fieldName) {\n element.fieldName = fieldName;\n }\n\n let match;\n PLACEHOLDER_REGEX.lastIndex = 0;\n while ((match = PLACEHOLDER_REGEX.exec(line)) !== null) {\n const name = match[1];\n if (!fieldsMap.has(name)) {\n fieldsMap.set(name, { pages: new Set(), defaultValue: '' });\n }\n fieldsMap.get(name)!.pages.add(pageIndex + 1);\n }\n }\n\n elements.push(element);\n yPos -= lineHeight;\n }\n }\n\n return { width, height, elements };\n });\n\n const fields: TemplateField[] = [];\n for (const [name, info] of fieldsMap) {\n fields.push({\n name,\n defaultValue: info.defaultValue,\n pages: [...info.pages].sort((a, b) => a - b),\n });\n }\n\n return {\n version: '1.0',\n metadata: {\n name: options.name,\n description: options.description,\n createdAt: new Date().toISOString(),\n sourcePageCount: pageCount,\n },\n pages,\n fields,\n fonts,\n defaults: {\n font: defaultFont,\n color: { r: 0, g: 0, b: 0 },\n missingFieldBehavior: 'leave_placeholder',\n },\n };\n}\n\nexport async function templateToPdf(\n template: PDFTemplate,\n data: Record<string, string> = {},\n options: TemplateToPdfOptions = {}\n): Promise<Uint8Array> {\n validateTemplate(template);\n\n const pdfDoc = await PDFDocument.create();\n const font = await pdfDoc.embedFont(StandardFonts.Helvetica);\n const boldFont = await pdfDoc.embedFont(StandardFonts.HelveticaBold);\n\n const missingFieldBehavior =\n options.missingFieldBehavior ??\n template.defaults?.missingFieldBehavior ??\n 'leave_placeholder';\n\n const defaultColor = template.defaults?.color ?? { r: 0, g: 0, b: 0 };\n\n for (const templatePage of template.pages) {\n const page = pdfDoc.addPage([templatePage.width, templatePage.height]);\n\n for (const element of templatePage.elements) {\n const resolvedFont = resolveFont(element.font, template.defaults);\n const color = element.color ?? defaultColor;\n const pdfFont = resolvedFont.weight === 'bold' ? boldFont : font;\n const fontSize = resolvedFont.size;\n\n const content =\n element.type === 'placeholder'\n ? resolveContent(element.content, data, missingFieldBehavior, template.fields)\n : element.content;\n\n page.drawText(content, {\n x: element.x,\n y: element.y,\n size: fontSize,\n font: pdfFont,\n color: rgb(color.r, color.g, color.b),\n });\n }\n }\n\n return pdfDoc.save();\n}\n\nexport function validateTemplate(template: PDFTemplate): void {\n if (!template) {\n throw new Error('Template is required');\n }\n\n if (template.version !== '1.0') {\n throw new Error(`Unsupported template version: ${template.version}`);\n }\n\n if (!Array.isArray(template.pages) || template.pages.length === 0) {\n throw new Error('Template must have at least one page');\n }\n\n if (!template.metadata) {\n throw new Error('Template metadata is required');\n }\n\n if (typeof template.metadata.sourcePageCount !== 'number' || template.metadata.sourcePageCount < 1) {\n throw new Error('Template metadata.sourcePageCount must be a positive number');\n }\n\n if (!Array.isArray(template.fields)) {\n throw new Error('Template fields must be an array');\n }\n\n for (const page of template.pages) {\n if (typeof page.width !== 'number' || typeof page.height !== 'number') {\n throw new Error('Each page must have numeric width and height');\n }\n if (!Array.isArray(page.elements)) {\n throw new Error('Each page must have an elements array');\n }\n for (const element of page.elements) {\n if (element.type !== 'text' && element.type !== 'placeholder') {\n throw new Error(`Invalid element type: ${element.type}`);\n }\n if (typeof element.content !== 'string') {\n throw new Error('Element content must be a string');\n }\n if (typeof element.x !== 'number' || typeof element.y !== 'number') {\n throw new Error('Element x and y must be numbers');\n }\n }\n }\n}\n"]}
|