@ooneex/pdf 1.1.2 → 1.1.4
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/dist/index.d.ts +1 -1
- package/dist/index.js +495 -4
- package/dist/index.js.map +4 -4
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -516,6 +516,6 @@ declare class PDF implements IPDF {
|
|
|
516
516
|
}
|
|
517
517
|
import { Exception } from "@ooneex/exception";
|
|
518
518
|
declare class PDFException extends Exception {
|
|
519
|
-
constructor(message: string, data?: Record<string, unknown>);
|
|
519
|
+
constructor(message: string, key: string, data?: Record<string, unknown>);
|
|
520
520
|
}
|
|
521
521
|
export { PDFUpdateMetadataOptionsType, PDFToImagesOptionsType, PDFSplitResultType, PDFSplitOptionsType, PDFRemovePagesResultType, PDFPageImageResultType, PDFOptionsType, PDFMetadataResultType, PDFGetImagesResultType, PDFGetImagesOptionsType, PDFExtractedImageType, PDFException, PDFCreateResultType, PDFCreateOptionsType, PDFAddPageResultType, PDFAddPageOptionsType, PDF, IPDF };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,497 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
// src/PDF.ts
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { PDFDocument, rgb, StandardFonts } from "pdf-lib";
|
|
5
|
+
import { pdf } from "pdf-to-img";
|
|
6
|
+
import sharp from "sharp";
|
|
7
|
+
import { extractImages, getDocumentProxy } from "unpdf";
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
// src/PDFException.ts
|
|
10
|
+
import { Exception } from "@ooneex/exception";
|
|
11
|
+
import { HttpStatus } from "@ooneex/http-status";
|
|
12
|
+
|
|
13
|
+
class PDFException extends Exception {
|
|
14
|
+
constructor(message, key, data = {}) {
|
|
15
|
+
super(message, {
|
|
16
|
+
key,
|
|
17
|
+
status: HttpStatus.Code.InternalServerError,
|
|
18
|
+
data
|
|
19
|
+
});
|
|
20
|
+
this.name = "PDFException";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// src/PDF.ts
|
|
25
|
+
class PDF {
|
|
26
|
+
source;
|
|
27
|
+
options;
|
|
28
|
+
constructor(source, options = {}) {
|
|
29
|
+
this.source = path.join(...source.split(/[/\\]/));
|
|
30
|
+
this.options = {
|
|
31
|
+
scale: options.scale ?? 3,
|
|
32
|
+
...options.password !== undefined && { password: options.password }
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
async create(options = {}) {
|
|
36
|
+
try {
|
|
37
|
+
const pdfDoc = await PDFDocument.create();
|
|
38
|
+
if (options.title) {
|
|
39
|
+
pdfDoc.setTitle(options.title);
|
|
40
|
+
}
|
|
41
|
+
if (options.author) {
|
|
42
|
+
pdfDoc.setAuthor(options.author);
|
|
43
|
+
}
|
|
44
|
+
if (options.subject) {
|
|
45
|
+
pdfDoc.setSubject(options.subject);
|
|
46
|
+
}
|
|
47
|
+
if (options.keywords) {
|
|
48
|
+
pdfDoc.setKeywords(options.keywords);
|
|
49
|
+
}
|
|
50
|
+
if (options.producer) {
|
|
51
|
+
pdfDoc.setProducer(options.producer);
|
|
52
|
+
}
|
|
53
|
+
if (options.creator) {
|
|
54
|
+
pdfDoc.setCreator(options.creator);
|
|
55
|
+
}
|
|
56
|
+
const pdfBytes = await pdfDoc.save();
|
|
57
|
+
await Bun.write(this.source, pdfBytes);
|
|
58
|
+
return {
|
|
59
|
+
pageCount: pdfDoc.getPageCount()
|
|
60
|
+
};
|
|
61
|
+
} catch (error) {
|
|
62
|
+
if (error instanceof PDFException) {
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
throw new PDFException("Failed to create PDF document", "PDF_CREATE_FAILED", {
|
|
66
|
+
source: this.source,
|
|
67
|
+
error: error instanceof Error ? error.message : String(error)
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async addPage(options = {}) {
|
|
72
|
+
try {
|
|
73
|
+
const sourceBytes = await Bun.file(this.source).arrayBuffer();
|
|
74
|
+
const pdfDoc = await PDFDocument.load(sourceBytes, {
|
|
75
|
+
ignoreEncryption: this.options.password !== undefined
|
|
76
|
+
});
|
|
77
|
+
const page = pdfDoc.addPage();
|
|
78
|
+
if (options.content) {
|
|
79
|
+
const font = await pdfDoc.embedFont(StandardFonts.Helvetica);
|
|
80
|
+
const fontSize = options.fontSize ?? 12;
|
|
81
|
+
const margin = 50;
|
|
82
|
+
const lineHeight = fontSize * 1.2;
|
|
83
|
+
const { height } = page.getSize();
|
|
84
|
+
let y = height - margin;
|
|
85
|
+
const lines = options.content.split(`
|
|
86
|
+
`);
|
|
87
|
+
for (const line of lines) {
|
|
88
|
+
if (y < margin) {
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
page.drawText(line, {
|
|
92
|
+
x: margin,
|
|
93
|
+
y,
|
|
94
|
+
size: fontSize,
|
|
95
|
+
font,
|
|
96
|
+
color: rgb(0, 0, 0)
|
|
97
|
+
});
|
|
98
|
+
y -= lineHeight;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const pdfBytes = await pdfDoc.save();
|
|
102
|
+
await Bun.write(this.source, pdfBytes);
|
|
103
|
+
return {
|
|
104
|
+
pageCount: pdfDoc.getPageCount()
|
|
105
|
+
};
|
|
106
|
+
} catch (error) {
|
|
107
|
+
if (error instanceof PDFException) {
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
throw new PDFException("Failed to add page to PDF", "PDF_ADD_PAGE_FAILED", {
|
|
111
|
+
source: this.source,
|
|
112
|
+
error: error instanceof Error ? error.message : String(error)
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async getMetadata() {
|
|
117
|
+
try {
|
|
118
|
+
const sourceBytes = await Bun.file(this.source).arrayBuffer();
|
|
119
|
+
const pdfDoc = await PDFDocument.load(sourceBytes, {
|
|
120
|
+
ignoreEncryption: this.options.password !== undefined,
|
|
121
|
+
updateMetadata: false
|
|
122
|
+
});
|
|
123
|
+
return {
|
|
124
|
+
title: pdfDoc.getTitle(),
|
|
125
|
+
author: pdfDoc.getAuthor(),
|
|
126
|
+
subject: pdfDoc.getSubject(),
|
|
127
|
+
keywords: pdfDoc.getKeywords(),
|
|
128
|
+
producer: pdfDoc.getProducer(),
|
|
129
|
+
creator: pdfDoc.getCreator(),
|
|
130
|
+
creationDate: pdfDoc.getCreationDate(),
|
|
131
|
+
modificationDate: pdfDoc.getModificationDate(),
|
|
132
|
+
pageCount: pdfDoc.getPageCount()
|
|
133
|
+
};
|
|
134
|
+
} catch (error) {
|
|
135
|
+
if (error instanceof PDFException) {
|
|
136
|
+
throw error;
|
|
137
|
+
}
|
|
138
|
+
throw new PDFException("Failed to get PDF metadata", "PDF_METADATA_GET_FAILED", {
|
|
139
|
+
source: this.source,
|
|
140
|
+
error: error instanceof Error ? error.message : String(error)
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async updateMetadata(options) {
|
|
145
|
+
try {
|
|
146
|
+
const sourceBytes = await Bun.file(this.source).arrayBuffer();
|
|
147
|
+
const pdfDoc = await PDFDocument.load(sourceBytes, {
|
|
148
|
+
ignoreEncryption: this.options.password !== undefined
|
|
149
|
+
});
|
|
150
|
+
if (options.title !== undefined) {
|
|
151
|
+
pdfDoc.setTitle(options.title);
|
|
152
|
+
}
|
|
153
|
+
if (options.author !== undefined) {
|
|
154
|
+
pdfDoc.setAuthor(options.author);
|
|
155
|
+
}
|
|
156
|
+
if (options.subject !== undefined) {
|
|
157
|
+
pdfDoc.setSubject(options.subject);
|
|
158
|
+
}
|
|
159
|
+
if (options.keywords !== undefined) {
|
|
160
|
+
pdfDoc.setKeywords(options.keywords);
|
|
161
|
+
}
|
|
162
|
+
if (options.producer !== undefined) {
|
|
163
|
+
pdfDoc.setProducer(options.producer);
|
|
164
|
+
}
|
|
165
|
+
if (options.creator !== undefined) {
|
|
166
|
+
pdfDoc.setCreator(options.creator);
|
|
167
|
+
}
|
|
168
|
+
if (options.creationDate !== undefined) {
|
|
169
|
+
pdfDoc.setCreationDate(options.creationDate);
|
|
170
|
+
}
|
|
171
|
+
if (options.modificationDate !== undefined) {
|
|
172
|
+
pdfDoc.setModificationDate(options.modificationDate);
|
|
173
|
+
}
|
|
174
|
+
const pdfBytes = await pdfDoc.save();
|
|
175
|
+
await Bun.write(this.source, pdfBytes);
|
|
176
|
+
} catch (error) {
|
|
177
|
+
if (error instanceof PDFException) {
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
throw new PDFException("Failed to update PDF metadata", "PDF_METADATA_UPDATE_FAILED", {
|
|
181
|
+
source: this.source,
|
|
182
|
+
error: error instanceof Error ? error.message : String(error)
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async getPageCount() {
|
|
187
|
+
try {
|
|
188
|
+
const sourceBytes = await Bun.file(this.source).arrayBuffer();
|
|
189
|
+
const pdfDoc = await PDFDocument.load(sourceBytes, {
|
|
190
|
+
ignoreEncryption: this.options.password !== undefined,
|
|
191
|
+
updateMetadata: false
|
|
192
|
+
});
|
|
193
|
+
return pdfDoc.getPageCount();
|
|
194
|
+
} catch (error) {
|
|
195
|
+
throw new PDFException("Failed to get page count", "PDF_PAGE_COUNT_FAILED", {
|
|
196
|
+
source: this.source,
|
|
197
|
+
error: error instanceof Error ? error.message : String(error)
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
async getPageContent(pageNumber) {
|
|
202
|
+
if (pageNumber < 1 || !Number.isInteger(pageNumber)) {
|
|
203
|
+
throw new PDFException("Page number must be a positive integer", "PDF_INVALID_PAGE_NUMBER", {
|
|
204
|
+
pageNumber
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
try {
|
|
208
|
+
const sourceBytes = await Bun.file(this.source).arrayBuffer();
|
|
209
|
+
const document = await getDocumentProxy(new Uint8Array(sourceBytes));
|
|
210
|
+
const totalPages = document.numPages;
|
|
211
|
+
if (pageNumber > totalPages) {
|
|
212
|
+
throw new PDFException("Page number exceeds total pages", "PDF_PAGE_OUT_OF_RANGE", {
|
|
213
|
+
pageNumber,
|
|
214
|
+
totalPages
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
const page = await document.getPage(pageNumber);
|
|
218
|
+
const textContent = await page.getTextContent();
|
|
219
|
+
const text = textContent.items.filter((item) => ("str" in item)).map((item) => ("hasEOL" in item) && item.hasEOL ? `${item.str}
|
|
220
|
+
` : item.str).join("");
|
|
221
|
+
return text.trim();
|
|
222
|
+
} catch (error) {
|
|
223
|
+
if (error instanceof PDFException) {
|
|
224
|
+
throw error;
|
|
225
|
+
}
|
|
226
|
+
throw new PDFException("Failed to get page content", "PDF_PAGE_CONTENT_FAILED", {
|
|
227
|
+
source: this.source,
|
|
228
|
+
pageNumber,
|
|
229
|
+
error: error instanceof Error ? error.message : String(error)
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
async getImages(options) {
|
|
234
|
+
const { pageNumber } = options;
|
|
235
|
+
if (pageNumber !== undefined && (pageNumber < 1 || !Number.isInteger(pageNumber))) {
|
|
236
|
+
throw new PDFException("Page number must be a positive integer", "PDF_INVALID_PAGE_NUMBER", {
|
|
237
|
+
pageNumber
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
const normalizedOutputDir = path.join(...options.outputDir.split(/[/\\]/));
|
|
241
|
+
const prefix = options.prefix ?? "image";
|
|
242
|
+
try {
|
|
243
|
+
const sourceBytes = await Bun.file(this.source).arrayBuffer();
|
|
244
|
+
const document = await getDocumentProxy(new Uint8Array(sourceBytes));
|
|
245
|
+
const totalPages = document.numPages;
|
|
246
|
+
if (pageNumber !== undefined && pageNumber > totalPages) {
|
|
247
|
+
throw new PDFException("Page number exceeds total pages", "PDF_PAGE_OUT_OF_RANGE", {
|
|
248
|
+
pageNumber,
|
|
249
|
+
totalPages
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
const processPage = async (page) => {
|
|
253
|
+
const pageImages = await extractImages(document, page);
|
|
254
|
+
const results = [];
|
|
255
|
+
let imageIndex = 0;
|
|
256
|
+
for (const img of pageImages) {
|
|
257
|
+
imageIndex++;
|
|
258
|
+
const fileName = `${prefix}-p${page}-${imageIndex}.png`;
|
|
259
|
+
const filePath = path.join(normalizedOutputDir, fileName);
|
|
260
|
+
const pngBuffer = await sharp(img.data, {
|
|
261
|
+
raw: {
|
|
262
|
+
width: img.width,
|
|
263
|
+
height: img.height,
|
|
264
|
+
channels: img.channels
|
|
265
|
+
}
|
|
266
|
+
}).png().toBuffer();
|
|
267
|
+
await Bun.write(filePath, pngBuffer);
|
|
268
|
+
results.push({
|
|
269
|
+
page,
|
|
270
|
+
path: filePath,
|
|
271
|
+
width: img.width,
|
|
272
|
+
height: img.height
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
return results;
|
|
276
|
+
};
|
|
277
|
+
if (pageNumber !== undefined) {
|
|
278
|
+
return await processPage(pageNumber);
|
|
279
|
+
}
|
|
280
|
+
const allResults = await Promise.all(Array.from({ length: totalPages }, (_, i) => processPage(i + 1)));
|
|
281
|
+
return allResults.flat();
|
|
282
|
+
} catch (error) {
|
|
283
|
+
if (error instanceof PDFException) {
|
|
284
|
+
throw error;
|
|
285
|
+
}
|
|
286
|
+
throw new PDFException("Failed to extract images from PDF", "PDF_EXTRACT_IMAGES_FAILED", {
|
|
287
|
+
source: this.source,
|
|
288
|
+
outputDir: normalizedOutputDir,
|
|
289
|
+
pageNumber,
|
|
290
|
+
error: error instanceof Error ? error.message : String(error)
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
async* pagesToImages(options) {
|
|
295
|
+
const normalizedOutputDir = path.join(...options.outputDir.split(/[/\\]/));
|
|
296
|
+
const prefix = options.prefix ?? "page";
|
|
297
|
+
const savedWorker = globalThis.pdfjsWorker;
|
|
298
|
+
globalThis.pdfjsWorker = undefined;
|
|
299
|
+
try {
|
|
300
|
+
const document = await pdf(this.source, this.options);
|
|
301
|
+
let pageNumber = 1;
|
|
302
|
+
for await (const image of document) {
|
|
303
|
+
const fileName = `${prefix}-${pageNumber}.png`;
|
|
304
|
+
const filePath = path.join(normalizedOutputDir, fileName);
|
|
305
|
+
await Bun.write(filePath, Buffer.from(image));
|
|
306
|
+
yield {
|
|
307
|
+
page: pageNumber,
|
|
308
|
+
path: filePath
|
|
309
|
+
};
|
|
310
|
+
pageNumber++;
|
|
311
|
+
}
|
|
312
|
+
globalThis.pdfjsWorker = savedWorker;
|
|
313
|
+
} catch (error) {
|
|
314
|
+
globalThis.pdfjsWorker = savedWorker;
|
|
315
|
+
throw new PDFException("Failed to convert PDF to images", "PDF_CONVERT_IMAGES_FAILED", {
|
|
316
|
+
source: this.source,
|
|
317
|
+
outputDir: normalizedOutputDir,
|
|
318
|
+
error: error instanceof Error ? error.message : String(error)
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
async pageToImage(pageNumber, options) {
|
|
323
|
+
if (pageNumber < 1 || !Number.isInteger(pageNumber)) {
|
|
324
|
+
throw new PDFException("Page number must be a positive integer", "PDF_INVALID_PAGE_NUMBER", {
|
|
325
|
+
pageNumber
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
const normalizedOutputDir = path.join(...options.outputDir.split(/[/\\]/));
|
|
329
|
+
const prefix = options.prefix ?? "page";
|
|
330
|
+
const savedWorker = globalThis.pdfjsWorker;
|
|
331
|
+
globalThis.pdfjsWorker = undefined;
|
|
332
|
+
try {
|
|
333
|
+
const document = await pdf(this.source, this.options);
|
|
334
|
+
if (pageNumber > document.length) {
|
|
335
|
+
throw new PDFException("Page number exceeds total pages", "PDF_PAGE_OUT_OF_RANGE", {
|
|
336
|
+
pageNumber,
|
|
337
|
+
totalPages: document.length
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
const image = await document.getPage(pageNumber);
|
|
341
|
+
const fileName = `${prefix}-${pageNumber}.png`;
|
|
342
|
+
const filePath = path.join(normalizedOutputDir, fileName);
|
|
343
|
+
await Bun.write(filePath, Buffer.from(image));
|
|
344
|
+
globalThis.pdfjsWorker = savedWorker;
|
|
345
|
+
return {
|
|
346
|
+
page: pageNumber,
|
|
347
|
+
path: filePath
|
|
348
|
+
};
|
|
349
|
+
} catch (error) {
|
|
350
|
+
globalThis.pdfjsWorker = savedWorker;
|
|
351
|
+
if (error instanceof PDFException) {
|
|
352
|
+
throw error;
|
|
353
|
+
}
|
|
354
|
+
throw new PDFException("Failed to get page image", "PDF_PAGE_IMAGE_FAILED", {
|
|
355
|
+
source: this.source,
|
|
356
|
+
pageNumber,
|
|
357
|
+
outputDir: normalizedOutputDir,
|
|
358
|
+
error: error instanceof Error ? error.message : String(error)
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
async* split(options) {
|
|
363
|
+
const normalizedOutputDir = path.join(...options.outputDir.split(/[/\\]/));
|
|
364
|
+
const prefix = options.prefix ?? "page";
|
|
365
|
+
try {
|
|
366
|
+
const sourceBytes = await Bun.file(this.source).arrayBuffer();
|
|
367
|
+
const sourcePdf = await PDFDocument.load(sourceBytes, {
|
|
368
|
+
ignoreEncryption: this.options.password !== undefined
|
|
369
|
+
});
|
|
370
|
+
const totalPages = sourcePdf.getPageCount();
|
|
371
|
+
if (totalPages === 0) {
|
|
372
|
+
throw new PDFException("PDF has no pages", "PDF_NO_PAGES", {
|
|
373
|
+
source: this.source
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
const ranges = this.normalizeRanges(options.ranges, totalPages);
|
|
377
|
+
for (const { start, end } of ranges) {
|
|
378
|
+
if (start < 1 || end > totalPages || start > end) {
|
|
379
|
+
throw new PDFException("Invalid page range", "PDF_INVALID_PAGE_RANGE", {
|
|
380
|
+
start,
|
|
381
|
+
end,
|
|
382
|
+
totalPages
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
for (const { start, end } of ranges) {
|
|
387
|
+
const newPdf = await PDFDocument.create();
|
|
388
|
+
const pageIndices = Array.from({ length: end - start + 1 }, (_, i) => start - 1 + i);
|
|
389
|
+
const copiedPages = await newPdf.copyPages(sourcePdf, pageIndices);
|
|
390
|
+
for (const page of copiedPages) {
|
|
391
|
+
newPdf.addPage(page);
|
|
392
|
+
}
|
|
393
|
+
const pdfBytes = await newPdf.save();
|
|
394
|
+
const fileName = start === end ? `${prefix}-${start}.pdf` : `${prefix}-${start}-${end}.pdf`;
|
|
395
|
+
const filePath = path.join(normalizedOutputDir, fileName);
|
|
396
|
+
await Bun.write(filePath, pdfBytes);
|
|
397
|
+
yield {
|
|
398
|
+
pages: { start, end },
|
|
399
|
+
path: filePath
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
} catch (error) {
|
|
403
|
+
if (error instanceof PDFException) {
|
|
404
|
+
throw error;
|
|
405
|
+
}
|
|
406
|
+
throw new PDFException("Failed to split PDF", "PDF_SPLIT_FAILED", {
|
|
407
|
+
source: this.source,
|
|
408
|
+
outputDir: normalizedOutputDir,
|
|
409
|
+
error: error instanceof Error ? error.message : String(error)
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
async removePages(pages) {
|
|
414
|
+
try {
|
|
415
|
+
const sourceBytes = await Bun.file(this.source).arrayBuffer();
|
|
416
|
+
const pdfDoc = await PDFDocument.load(sourceBytes, {
|
|
417
|
+
ignoreEncryption: this.options.password !== undefined
|
|
418
|
+
});
|
|
419
|
+
const totalPages = pdfDoc.getPageCount();
|
|
420
|
+
if (totalPages === 0) {
|
|
421
|
+
throw new PDFException("PDF has no pages", "PDF_NO_PAGES", {
|
|
422
|
+
source: this.source
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
const pagesToRemove = this.normalizePageNumbers(pages, totalPages);
|
|
426
|
+
if (pagesToRemove.length === 0) {
|
|
427
|
+
throw new PDFException("No valid pages specified for removal", "PDF_NO_VALID_PAGES", {
|
|
428
|
+
pages
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
if (pagesToRemove.length >= totalPages) {
|
|
432
|
+
throw new PDFException("Cannot remove all pages from PDF", "PDF_CANNOT_REMOVE_ALL_PAGES", {
|
|
433
|
+
pagesToRemove,
|
|
434
|
+
totalPages
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
const sortedDescending = [...pagesToRemove].sort((a, b) => b - a);
|
|
438
|
+
for (const pageNum of sortedDescending) {
|
|
439
|
+
pdfDoc.removePage(pageNum - 1);
|
|
440
|
+
}
|
|
441
|
+
const pdfBytes = await pdfDoc.save();
|
|
442
|
+
await Bun.write(this.source, pdfBytes);
|
|
443
|
+
return {
|
|
444
|
+
remainingPages: pdfDoc.getPageCount()
|
|
445
|
+
};
|
|
446
|
+
} catch (error) {
|
|
447
|
+
if (error instanceof PDFException) {
|
|
448
|
+
throw error;
|
|
449
|
+
}
|
|
450
|
+
throw new PDFException("Failed to remove pages from PDF", "PDF_REMOVE_PAGES_FAILED", {
|
|
451
|
+
source: this.source,
|
|
452
|
+
pages,
|
|
453
|
+
error: error instanceof Error ? error.message : String(error)
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
normalizePageNumbers(pages, totalPages) {
|
|
458
|
+
const pageSet = new Set;
|
|
459
|
+
for (const page of pages) {
|
|
460
|
+
if (typeof page === "number") {
|
|
461
|
+
if (page >= 1 && page <= totalPages && Number.isInteger(page)) {
|
|
462
|
+
pageSet.add(page);
|
|
463
|
+
}
|
|
464
|
+
} else {
|
|
465
|
+
const [start, end] = page;
|
|
466
|
+
if (start <= end) {
|
|
467
|
+
for (let i = Math.max(1, start);i <= Math.min(totalPages, end); i++) {
|
|
468
|
+
if (Number.isInteger(i)) {
|
|
469
|
+
pageSet.add(i);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
return Array.from(pageSet);
|
|
476
|
+
}
|
|
477
|
+
normalizeRanges(ranges, totalPages) {
|
|
478
|
+
if (!ranges || ranges.length === 0) {
|
|
479
|
+
return Array.from({ length: totalPages }, (_, i) => ({
|
|
480
|
+
start: i + 1,
|
|
481
|
+
end: i + 1
|
|
482
|
+
}));
|
|
483
|
+
}
|
|
484
|
+
return ranges.map((range) => {
|
|
485
|
+
if (typeof range === "number") {
|
|
486
|
+
return { start: range, end: range };
|
|
487
|
+
}
|
|
488
|
+
return { start: range[0], end: range[1] };
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
export {
|
|
493
|
+
PDFException,
|
|
494
|
+
PDF
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
//# debugId=50118D49CA2A880B64756E2164756E21
|
package/dist/index.js.map
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["src/PDF.ts", "src/PDFException.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import path from \"node:path\";\nimport { PDFDocument, rgb, StandardFonts } from \"pdf-lib\";\nimport { pdf } from \"pdf-to-img\";\nimport sharp from \"sharp\";\nimport { extractImages, getDocumentProxy } from \"unpdf\";\nimport { PDFException } from \"./PDFException\";\nimport type {\n IPDF,\n PDFAddPageOptionsType,\n PDFAddPageResultType,\n PDFCreateOptionsType,\n PDFCreateResultType,\n PDFExtractedImageType,\n PDFGetImagesOptionsType,\n PDFGetImagesResultType,\n PDFMetadataResultType,\n PDFOptionsType,\n PDFPageImageResultType,\n PDFRemovePagesResultType,\n PDFSplitOptionsType,\n PDFSplitResultType,\n PDFToImagesOptionsType,\n PDFUpdateMetadataOptionsType,\n} from \"./types\";\n\nexport class PDF implements IPDF {\n private readonly source: string;\n private readonly options: PDFOptionsType;\n\n /**\n * Create a new PDF instance\n * @param source - Path to PDF file\n * @param options - Options for PDF processing\n */\n constructor(source: string, options: PDFOptionsType = {}) {\n this.source = path.join(...source.split(/[/\\\\]/));\n this.options = {\n scale: options.scale ?? 3,\n ...(options.password !== undefined && { password: options.password }),\n };\n }\n\n /**\n * Create a new PDF document and save to the source path\n * @param options - Optional content and metadata options for the PDF document\n * @returns Result containing the page count\n *\n * @example\n * ```typescript\n * // Create a simple empty PDF\n * const pdf = new PDF(\"/path/to/output.pdf\");\n * const result = await pdf.create();\n *\n * // Create a PDF with metadata\n * const pdf = new PDF(\"/path/to/output.pdf\");\n * const result = await pdf.create({\n * title: \"My Document\",\n * author: \"John Doe\",\n * subject: \"Example PDF\",\n * keywords: [\"example\", \"pdf\", \"document\"],\n * creator: \"My App\",\n * producer: \"pdf-lib\",\n * });\n * ```\n */\n public async create(options: PDFCreateOptionsType = {}): Promise<PDFCreateResultType> {\n try {\n const pdfDoc = await PDFDocument.create();\n\n // Set metadata if provided\n if (options.title) {\n pdfDoc.setTitle(options.title);\n }\n if (options.author) {\n pdfDoc.setAuthor(options.author);\n }\n if (options.subject) {\n pdfDoc.setSubject(options.subject);\n }\n if (options.keywords) {\n pdfDoc.setKeywords(options.keywords);\n }\n if (options.producer) {\n pdfDoc.setProducer(options.producer);\n }\n if (options.creator) {\n pdfDoc.setCreator(options.creator);\n }\n\n const pdfBytes = await pdfDoc.save();\n\n await Bun.write(this.source, pdfBytes);\n\n return {\n pageCount: pdfDoc.getPageCount(),\n };\n } catch (error) {\n if (error instanceof PDFException) {\n throw error;\n }\n throw new PDFException(\"Failed to create PDF document\", {\n source: this.source,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Add a page to an existing PDF document\n * @param options - Optional content options for the page\n * @returns Result containing the total page count\n *\n * @example\n * ```typescript\n * const pdf = new PDF(\"/path/to/document.pdf\");\n *\n * // Add an empty page\n * await pdf.addPage();\n *\n * // Add a page with content\n * await pdf.addPage({\n * content: \"Hello, World!\",\n * fontSize: 24,\n * });\n * ```\n */\n public async addPage(options: PDFAddPageOptionsType = {}): Promise<PDFAddPageResultType> {\n try {\n const sourceBytes = await Bun.file(this.source).arrayBuffer();\n\n const pdfDoc = await PDFDocument.load(sourceBytes, {\n ignoreEncryption: this.options.password !== undefined,\n });\n\n const page = pdfDoc.addPage();\n\n // Add content if provided\n if (options.content) {\n const font = await pdfDoc.embedFont(StandardFonts.Helvetica);\n const fontSize = options.fontSize ?? 12;\n const margin = 50;\n const lineHeight = fontSize * 1.2;\n\n const { height } = page.getSize();\n let y = height - margin;\n\n const lines = options.content.split(\"\\n\");\n\n for (const line of lines) {\n if (y < margin) {\n break;\n }\n\n page.drawText(line, {\n x: margin,\n y,\n size: fontSize,\n font,\n color: rgb(0, 0, 0),\n });\n\n y -= lineHeight;\n }\n }\n\n const pdfBytes = await pdfDoc.save();\n\n await Bun.write(this.source, pdfBytes);\n\n return {\n pageCount: pdfDoc.getPageCount(),\n };\n } catch (error) {\n if (error instanceof PDFException) {\n throw error;\n }\n throw new PDFException(\"Failed to add page to PDF\", {\n source: this.source,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Get metadata from the PDF document\n * @returns PDF metadata including title, author, dates, and page count\n *\n * @example\n * ```typescript\n * const pdf = new PDF(\"/path/to/document.pdf\");\n * const metadata = await pdf.getMetadata();\n *\n * console.log(metadata.title);\n * console.log(metadata.author);\n * console.log(metadata.pageCount);\n * ```\n */\n public async getMetadata(): Promise<PDFMetadataResultType> {\n try {\n const sourceBytes = await Bun.file(this.source).arrayBuffer();\n\n const pdfDoc = await PDFDocument.load(sourceBytes, {\n ignoreEncryption: this.options.password !== undefined,\n updateMetadata: false,\n });\n\n return {\n title: pdfDoc.getTitle(),\n author: pdfDoc.getAuthor(),\n subject: pdfDoc.getSubject(),\n keywords: pdfDoc.getKeywords(),\n producer: pdfDoc.getProducer(),\n creator: pdfDoc.getCreator(),\n creationDate: pdfDoc.getCreationDate(),\n modificationDate: pdfDoc.getModificationDate(),\n pageCount: pdfDoc.getPageCount(),\n };\n } catch (error) {\n if (error instanceof PDFException) {\n throw error;\n }\n throw new PDFException(\"Failed to get PDF metadata\", {\n source: this.source,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Update metadata of an existing PDF document\n * @param options - Metadata options to update\n *\n * @example\n * ```typescript\n * const pdf = new PDF(\"/path/to/document.pdf\");\n * await pdf.updateMetadata({\n * title: \"Updated Title\",\n * author: \"New Author\",\n * subject: \"Updated Subject\",\n * keywords: [\"updated\", \"keywords\"],\n * producer: \"My App\",\n * creator: \"pdf-lib\",\n * creationDate: new Date(\"2020-01-01\"),\n * modificationDate: new Date(),\n * });\n * ```\n */\n public async updateMetadata(options: PDFUpdateMetadataOptionsType): Promise<void> {\n try {\n const sourceBytes = await Bun.file(this.source).arrayBuffer();\n\n const pdfDoc = await PDFDocument.load(sourceBytes, {\n ignoreEncryption: this.options.password !== undefined,\n });\n\n if (options.title !== undefined) {\n pdfDoc.setTitle(options.title);\n }\n if (options.author !== undefined) {\n pdfDoc.setAuthor(options.author);\n }\n if (options.subject !== undefined) {\n pdfDoc.setSubject(options.subject);\n }\n if (options.keywords !== undefined) {\n pdfDoc.setKeywords(options.keywords);\n }\n if (options.producer !== undefined) {\n pdfDoc.setProducer(options.producer);\n }\n if (options.creator !== undefined) {\n pdfDoc.setCreator(options.creator);\n }\n if (options.creationDate !== undefined) {\n pdfDoc.setCreationDate(options.creationDate);\n }\n if (options.modificationDate !== undefined) {\n pdfDoc.setModificationDate(options.modificationDate);\n }\n\n const pdfBytes = await pdfDoc.save();\n\n await Bun.write(this.source, pdfBytes);\n } catch (error) {\n if (error instanceof PDFException) {\n throw error;\n }\n throw new PDFException(\"Failed to update PDF metadata\", {\n source: this.source,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Get the total number of pages in the PDF\n */\n public async getPageCount(): Promise<number> {\n try {\n const sourceBytes = await Bun.file(this.source).arrayBuffer();\n const pdfDoc = await PDFDocument.load(sourceBytes, {\n ignoreEncryption: this.options.password !== undefined,\n updateMetadata: false,\n });\n return pdfDoc.getPageCount();\n } catch (error) {\n throw new PDFException(\"Failed to get page count\", {\n source: this.source,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Get the text content of a specific page\n * @param pageNumber - Page number (1-indexed)\n * @returns Extracted text content from the page\n *\n * @example\n * ```typescript\n * const pdf = new PDF(\"/path/to/document.pdf\");\n *\n * // Get content from page 1\n * const content = await pdf.getPageContent(1);\n * console.log(content); // \"Lorem ipsum dolor sit amet...\"\n *\n * // Get content from a specific page\n * const page3Content = await pdf.getPageContent(3);\n * console.log(page3Content); // Plain text content\n * ```\n */\n public async getPageContent(pageNumber: number): Promise<string> {\n if (pageNumber < 1 || !Number.isInteger(pageNumber)) {\n throw new PDFException(\"Page number must be a positive integer\", {\n pageNumber,\n });\n }\n\n try {\n const sourceBytes = await Bun.file(this.source).arrayBuffer();\n const document = await getDocumentProxy(new Uint8Array(sourceBytes));\n const totalPages = document.numPages;\n\n if (pageNumber > totalPages) {\n throw new PDFException(\"Page number exceeds total pages\", {\n pageNumber,\n totalPages,\n });\n }\n\n const page = await document.getPage(pageNumber);\n const textContent = await page.getTextContent();\n const text = textContent.items\n .filter((item) => \"str\" in item)\n .map((item) => (\"hasEOL\" in item && item.hasEOL ? `${item.str}\\n` : item.str))\n .join(\"\");\n\n return text.trim();\n } catch (error) {\n if (error instanceof PDFException) {\n throw error;\n }\n throw new PDFException(\"Failed to get page content\", {\n source: this.source,\n pageNumber,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Extract images from PDF pages and save to disk\n * @param options - Options including output directory, optional prefix, and optional page number\n * @returns Result containing total pages and array of extracted images with file paths\n *\n * @example\n * ```typescript\n * const pdf = new PDF(\"/path/to/document.pdf\");\n *\n * // Extract images from all pages\n * const images = await pdf.getImages({ outputDir: \"/output\" });\n * console.log(`Found ${images.length} images`);\n *\n * // Extract images from a specific page\n * const page1Images = await pdf.getImages({ outputDir: \"/output\", prefix: \"doc\", pageNumber: 1 });\n * for (const image of page1Images) {\n * console.log(`Image: ${image.path}, ${image.width}x${image.height}`);\n * }\n * ```\n */\n public async getImages(options: PDFGetImagesOptionsType): Promise<PDFGetImagesResultType> {\n const { pageNumber } = options;\n\n if (pageNumber !== undefined && (pageNumber < 1 || !Number.isInteger(pageNumber))) {\n throw new PDFException(\"Page number must be a positive integer\", {\n pageNumber,\n });\n }\n\n const normalizedOutputDir = path.join(...options.outputDir.split(/[/\\\\]/));\n const prefix = options.prefix ?? \"image\";\n\n try {\n const sourceBytes = await Bun.file(this.source).arrayBuffer();\n const document = await getDocumentProxy(new Uint8Array(sourceBytes));\n const totalPages = document.numPages;\n\n if (pageNumber !== undefined && pageNumber > totalPages) {\n throw new PDFException(\"Page number exceeds total pages\", {\n pageNumber,\n totalPages,\n });\n }\n\n const processPage = async (page: number) => {\n const pageImages = await extractImages(document, page);\n const results: PDFExtractedImageType[] = [];\n let imageIndex = 0;\n for (const img of pageImages) {\n imageIndex++;\n const fileName = `${prefix}-p${page}-${imageIndex}.png`;\n const filePath = path.join(normalizedOutputDir, fileName);\n\n // Convert raw image data to PNG using sharp\n const pngBuffer = await sharp(img.data, {\n raw: {\n width: img.width,\n height: img.height,\n channels: img.channels,\n },\n })\n .png()\n .toBuffer();\n\n await Bun.write(filePath, pngBuffer);\n\n results.push({\n page,\n path: filePath,\n width: img.width,\n height: img.height,\n });\n }\n return results;\n };\n\n if (pageNumber !== undefined) {\n return await processPage(pageNumber);\n }\n\n const allResults = await Promise.all(Array.from({ length: totalPages }, (_, i) => processPage(i + 1)));\n return allResults.flat();\n } catch (error) {\n if (error instanceof PDFException) {\n throw error;\n }\n throw new PDFException(\"Failed to extract images from PDF\", {\n source: this.source,\n outputDir: normalizedOutputDir,\n pageNumber,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Convert all pages to images and save to disk\n * @param options - Options including output directory and optional prefix\n * @returns Array of page image results with page numbers and file paths\n */\n public async *pagesToImages(options: PDFToImagesOptionsType): AsyncGenerator<PDFPageImageResultType, void, unknown> {\n const normalizedOutputDir = path.join(...options.outputDir.split(/[/\\\\]/));\n const prefix = options.prefix ?? \"page\";\n const savedWorker = (globalThis as Record<string, unknown>).pdfjsWorker;\n (globalThis as Record<string, unknown>).pdfjsWorker = undefined;\n\n try {\n const document = await pdf(this.source, this.options);\n let pageNumber = 1;\n\n for await (const image of document) {\n const fileName = `${prefix}-${pageNumber}.png`;\n const filePath = path.join(normalizedOutputDir, fileName);\n\n await Bun.write(filePath, Buffer.from(image));\n\n yield {\n page: pageNumber,\n path: filePath,\n };\n pageNumber++;\n }\n\n (globalThis as Record<string, unknown>).pdfjsWorker = savedWorker;\n } catch (error) {\n (globalThis as Record<string, unknown>).pdfjsWorker = savedWorker;\n throw new PDFException(\"Failed to convert PDF to images\", {\n source: this.source,\n outputDir: normalizedOutputDir,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Convert a specific page to an image and save to disk\n * @param pageNumber - Page number (1-indexed)\n * @param options - Options including output directory and optional prefix\n * @returns Page image result with page number and file path\n */\n public async pageToImage(pageNumber: number, options: PDFToImagesOptionsType): Promise<PDFPageImageResultType> {\n if (pageNumber < 1 || !Number.isInteger(pageNumber)) {\n throw new PDFException(\"Page number must be a positive integer\", {\n pageNumber,\n });\n }\n\n const normalizedOutputDir = path.join(...options.outputDir.split(/[/\\\\]/));\n const prefix = options.prefix ?? \"page\";\n const savedWorker = (globalThis as Record<string, unknown>).pdfjsWorker;\n (globalThis as Record<string, unknown>).pdfjsWorker = undefined;\n\n try {\n const document = await pdf(this.source, this.options);\n\n if (pageNumber > document.length) {\n throw new PDFException(\"Page number exceeds total pages\", {\n pageNumber,\n totalPages: document.length,\n });\n }\n\n const image = await document.getPage(pageNumber);\n\n const fileName = `${prefix}-${pageNumber}.png`;\n const filePath = path.join(normalizedOutputDir, fileName);\n\n await Bun.write(filePath, Buffer.from(image));\n\n (globalThis as Record<string, unknown>).pdfjsWorker = savedWorker;\n\n return {\n page: pageNumber,\n path: filePath,\n };\n } catch (error) {\n (globalThis as Record<string, unknown>).pdfjsWorker = savedWorker;\n if (error instanceof PDFException) {\n throw error;\n }\n throw new PDFException(\"Failed to get page image\", {\n source: this.source,\n pageNumber,\n outputDir: normalizedOutputDir,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Split the PDF into separate documents and save to disk\n * @param options - Split options with output directory, page ranges, and optional prefix\n * @returns Array of split PDF results with page ranges and file paths\n */\n public async *split(options: PDFSplitOptionsType): AsyncGenerator<PDFSplitResultType, void, unknown> {\n const normalizedOutputDir = path.join(...options.outputDir.split(/[/\\\\]/));\n const prefix = options.prefix ?? \"page\";\n\n try {\n const sourceBytes = await Bun.file(this.source).arrayBuffer();\n\n const sourcePdf = await PDFDocument.load(sourceBytes, {\n ignoreEncryption: this.options.password !== undefined,\n });\n\n const totalPages = sourcePdf.getPageCount();\n\n if (totalPages === 0) {\n throw new PDFException(\"PDF has no pages\", {\n source: this.source,\n });\n }\n\n const ranges = this.normalizeRanges(options.ranges, totalPages);\n\n // Validate all ranges first\n for (const { start, end } of ranges) {\n if (start < 1 || end > totalPages || start > end) {\n throw new PDFException(\"Invalid page range\", {\n start,\n end,\n totalPages,\n });\n }\n }\n\n for (const { start, end } of ranges) {\n const newPdf = await PDFDocument.create();\n const pageIndices = Array.from({ length: end - start + 1 }, (_, i) => start - 1 + i);\n const copiedPages = await newPdf.copyPages(sourcePdf, pageIndices);\n\n for (const page of copiedPages) {\n newPdf.addPage(page);\n }\n\n const pdfBytes = await newPdf.save();\n\n const fileName = start === end ? `${prefix}-${start}.pdf` : `${prefix}-${start}-${end}.pdf`;\n const filePath = path.join(normalizedOutputDir, fileName);\n\n await Bun.write(filePath, pdfBytes);\n\n yield {\n pages: { start, end },\n path: filePath,\n };\n }\n } catch (error) {\n if (error instanceof PDFException) {\n throw error;\n }\n throw new PDFException(\"Failed to split PDF\", {\n source: this.source,\n outputDir: normalizedOutputDir,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Remove specified pages from the PDF\n * @param pages - Page numbers to remove (1-indexed). Can be individual numbers or ranges [start, end]\n * @returns Result with remaining page count and PDF buffer\n *\n * @example\n * ```typescript\n * const pdf = new PDF(\"/path/to/document.pdf\");\n *\n * // Remove individual pages (pages 2 and 5)\n * const result1 = await pdf.removePages([2, 5]);\n *\n * // Remove a range of pages (pages 3 to 6)\n * const result2 = await pdf.removePages([[3, 6]]);\n *\n * // Remove mixed: individual pages and ranges (pages 1, 4-6, and 10)\n * const result3 = await pdf.removePages([1, [4, 6], 10]);\n *\n * console.log(result3.remainingPages); // Number of pages left\n * console.log(result3.buffer); // Buffer containing the resulting PDF\n *\n * // Save to file\n * await Bun.write(\"/path/to/output.pdf\", result3.buffer);\n * ```\n */\n public async removePages(pages: (number | [number, number])[]): Promise<PDFRemovePagesResultType> {\n try {\n const sourceBytes = await Bun.file(this.source).arrayBuffer();\n\n const pdfDoc = await PDFDocument.load(sourceBytes, {\n ignoreEncryption: this.options.password !== undefined,\n });\n\n const totalPages = pdfDoc.getPageCount();\n\n if (totalPages === 0) {\n throw new PDFException(\"PDF has no pages\", {\n source: this.source,\n });\n }\n\n // Normalize page numbers to remove into a flat sorted array\n const pagesToRemove = this.normalizePageNumbers(pages, totalPages);\n\n if (pagesToRemove.length === 0) {\n throw new PDFException(\"No valid pages specified for removal\", {\n pages,\n });\n }\n\n if (pagesToRemove.length >= totalPages) {\n throw new PDFException(\"Cannot remove all pages from PDF\", {\n pagesToRemove,\n totalPages,\n });\n }\n\n // Remove pages in reverse order to maintain correct indices\n const sortedDescending = [...pagesToRemove].sort((a, b) => b - a);\n for (const pageNum of sortedDescending) {\n pdfDoc.removePage(pageNum - 1); // Convert to 0-indexed\n }\n\n const pdfBytes = await pdfDoc.save();\n\n await Bun.write(this.source, pdfBytes);\n\n return {\n remainingPages: pdfDoc.getPageCount(),\n };\n } catch (error) {\n if (error instanceof PDFException) {\n throw error;\n }\n throw new PDFException(\"Failed to remove pages from PDF\", {\n source: this.source,\n pages,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Normalize page numbers into a flat array of unique valid page numbers\n */\n private normalizePageNumbers(pages: (number | [number, number])[], totalPages: number): number[] {\n const pageSet = new Set<number>();\n\n for (const page of pages) {\n if (typeof page === \"number\") {\n if (page >= 1 && page <= totalPages && Number.isInteger(page)) {\n pageSet.add(page);\n }\n } else {\n const [start, end] = page;\n if (start <= end) {\n for (let i = Math.max(1, start); i <= Math.min(totalPages, end); i++) {\n if (Number.isInteger(i)) {\n pageSet.add(i);\n }\n }\n }\n }\n }\n\n return Array.from(pageSet);\n }\n\n /**\n * Normalize page ranges for splitting\n * If no ranges provided, creates individual page ranges\n */\n private normalizeRanges(\n ranges: PDFSplitOptionsType[\"ranges\"] | undefined,\n totalPages: number,\n ): { start: number; end: number }[] {\n if (!ranges || ranges.length === 0) {\n return Array.from({ length: totalPages }, (_, i) => ({\n start: i + 1,\n end: i + 1,\n }));\n }\n\n return ranges.map((range) => {\n if (typeof range === \"number\") {\n return { start: range, end: range };\n }\n return { start: range[0], end: range[1] };\n });\n }\n}\n",
|
|
6
|
-
"import { Exception } from \"@ooneex/exception\";\nimport { HttpStatus } from \"@ooneex/http-status\";\n\nexport class PDFException extends Exception {\n constructor(message: string, data: Record<string, unknown> = {}) {\n super(message, {\n status: HttpStatus.Code.InternalServerError,\n data,\n });\n this.name = \"PDFException\";\n }\n}\n"
|
|
5
|
+
"import path from \"node:path\";\nimport { PDFDocument, rgb, StandardFonts } from \"pdf-lib\";\nimport { pdf } from \"pdf-to-img\";\nimport sharp from \"sharp\";\nimport { extractImages, getDocumentProxy } from \"unpdf\";\nimport { PDFException } from \"./PDFException\";\nimport type {\n IPDF,\n PDFAddPageOptionsType,\n PDFAddPageResultType,\n PDFCreateOptionsType,\n PDFCreateResultType,\n PDFExtractedImageType,\n PDFGetImagesOptionsType,\n PDFGetImagesResultType,\n PDFMetadataResultType,\n PDFOptionsType,\n PDFPageImageResultType,\n PDFRemovePagesResultType,\n PDFSplitOptionsType,\n PDFSplitResultType,\n PDFToImagesOptionsType,\n PDFUpdateMetadataOptionsType,\n} from \"./types\";\n\nexport class PDF implements IPDF {\n private readonly source: string;\n private readonly options: PDFOptionsType;\n\n /**\n * Create a new PDF instance\n * @param source - Path to PDF file\n * @param options - Options for PDF processing\n */\n constructor(source: string, options: PDFOptionsType = {}) {\n this.source = path.join(...source.split(/[/\\\\]/));\n this.options = {\n scale: options.scale ?? 3,\n ...(options.password !== undefined && { password: options.password }),\n };\n }\n\n /**\n * Create a new PDF document and save to the source path\n * @param options - Optional content and metadata options for the PDF document\n * @returns Result containing the page count\n *\n * @example\n * ```typescript\n * // Create a simple empty PDF\n * const pdf = new PDF(\"/path/to/output.pdf\");\n * const result = await pdf.create();\n *\n * // Create a PDF with metadata\n * const pdf = new PDF(\"/path/to/output.pdf\");\n * const result = await pdf.create({\n * title: \"My Document\",\n * author: \"John Doe\",\n * subject: \"Example PDF\",\n * keywords: [\"example\", \"pdf\", \"document\"],\n * creator: \"My App\",\n * producer: \"pdf-lib\",\n * });\n * ```\n */\n public async create(options: PDFCreateOptionsType = {}): Promise<PDFCreateResultType> {\n try {\n const pdfDoc = await PDFDocument.create();\n\n // Set metadata if provided\n if (options.title) {\n pdfDoc.setTitle(options.title);\n }\n if (options.author) {\n pdfDoc.setAuthor(options.author);\n }\n if (options.subject) {\n pdfDoc.setSubject(options.subject);\n }\n if (options.keywords) {\n pdfDoc.setKeywords(options.keywords);\n }\n if (options.producer) {\n pdfDoc.setProducer(options.producer);\n }\n if (options.creator) {\n pdfDoc.setCreator(options.creator);\n }\n\n const pdfBytes = await pdfDoc.save();\n\n await Bun.write(this.source, pdfBytes);\n\n return {\n pageCount: pdfDoc.getPageCount(),\n };\n } catch (error) {\n if (error instanceof PDFException) {\n throw error;\n }\n throw new PDFException(\"Failed to create PDF document\", \"PDF_CREATE_FAILED\", {\n source: this.source,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Add a page to an existing PDF document\n * @param options - Optional content options for the page\n * @returns Result containing the total page count\n *\n * @example\n * ```typescript\n * const pdf = new PDF(\"/path/to/document.pdf\");\n *\n * // Add an empty page\n * await pdf.addPage();\n *\n * // Add a page with content\n * await pdf.addPage({\n * content: \"Hello, World!\",\n * fontSize: 24,\n * });\n * ```\n */\n public async addPage(options: PDFAddPageOptionsType = {}): Promise<PDFAddPageResultType> {\n try {\n const sourceBytes = await Bun.file(this.source).arrayBuffer();\n\n const pdfDoc = await PDFDocument.load(sourceBytes, {\n ignoreEncryption: this.options.password !== undefined,\n });\n\n const page = pdfDoc.addPage();\n\n // Add content if provided\n if (options.content) {\n const font = await pdfDoc.embedFont(StandardFonts.Helvetica);\n const fontSize = options.fontSize ?? 12;\n const margin = 50;\n const lineHeight = fontSize * 1.2;\n\n const { height } = page.getSize();\n let y = height - margin;\n\n const lines = options.content.split(\"\\n\");\n\n for (const line of lines) {\n if (y < margin) {\n break;\n }\n\n page.drawText(line, {\n x: margin,\n y,\n size: fontSize,\n font,\n color: rgb(0, 0, 0),\n });\n\n y -= lineHeight;\n }\n }\n\n const pdfBytes = await pdfDoc.save();\n\n await Bun.write(this.source, pdfBytes);\n\n return {\n pageCount: pdfDoc.getPageCount(),\n };\n } catch (error) {\n if (error instanceof PDFException) {\n throw error;\n }\n throw new PDFException(\"Failed to add page to PDF\", \"PDF_ADD_PAGE_FAILED\", {\n source: this.source,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Get metadata from the PDF document\n * @returns PDF metadata including title, author, dates, and page count\n *\n * @example\n * ```typescript\n * const pdf = new PDF(\"/path/to/document.pdf\");\n * const metadata = await pdf.getMetadata();\n *\n * console.log(metadata.title);\n * console.log(metadata.author);\n * console.log(metadata.pageCount);\n * ```\n */\n public async getMetadata(): Promise<PDFMetadataResultType> {\n try {\n const sourceBytes = await Bun.file(this.source).arrayBuffer();\n\n const pdfDoc = await PDFDocument.load(sourceBytes, {\n ignoreEncryption: this.options.password !== undefined,\n updateMetadata: false,\n });\n\n return {\n title: pdfDoc.getTitle(),\n author: pdfDoc.getAuthor(),\n subject: pdfDoc.getSubject(),\n keywords: pdfDoc.getKeywords(),\n producer: pdfDoc.getProducer(),\n creator: pdfDoc.getCreator(),\n creationDate: pdfDoc.getCreationDate(),\n modificationDate: pdfDoc.getModificationDate(),\n pageCount: pdfDoc.getPageCount(),\n };\n } catch (error) {\n if (error instanceof PDFException) {\n throw error;\n }\n throw new PDFException(\"Failed to get PDF metadata\", \"PDF_METADATA_GET_FAILED\", {\n source: this.source,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Update metadata of an existing PDF document\n * @param options - Metadata options to update\n *\n * @example\n * ```typescript\n * const pdf = new PDF(\"/path/to/document.pdf\");\n * await pdf.updateMetadata({\n * title: \"Updated Title\",\n * author: \"New Author\",\n * subject: \"Updated Subject\",\n * keywords: [\"updated\", \"keywords\"],\n * producer: \"My App\",\n * creator: \"pdf-lib\",\n * creationDate: new Date(\"2020-01-01\"),\n * modificationDate: new Date(),\n * });\n * ```\n */\n public async updateMetadata(options: PDFUpdateMetadataOptionsType): Promise<void> {\n try {\n const sourceBytes = await Bun.file(this.source).arrayBuffer();\n\n const pdfDoc = await PDFDocument.load(sourceBytes, {\n ignoreEncryption: this.options.password !== undefined,\n });\n\n if (options.title !== undefined) {\n pdfDoc.setTitle(options.title);\n }\n if (options.author !== undefined) {\n pdfDoc.setAuthor(options.author);\n }\n if (options.subject !== undefined) {\n pdfDoc.setSubject(options.subject);\n }\n if (options.keywords !== undefined) {\n pdfDoc.setKeywords(options.keywords);\n }\n if (options.producer !== undefined) {\n pdfDoc.setProducer(options.producer);\n }\n if (options.creator !== undefined) {\n pdfDoc.setCreator(options.creator);\n }\n if (options.creationDate !== undefined) {\n pdfDoc.setCreationDate(options.creationDate);\n }\n if (options.modificationDate !== undefined) {\n pdfDoc.setModificationDate(options.modificationDate);\n }\n\n const pdfBytes = await pdfDoc.save();\n\n await Bun.write(this.source, pdfBytes);\n } catch (error) {\n if (error instanceof PDFException) {\n throw error;\n }\n throw new PDFException(\"Failed to update PDF metadata\", \"PDF_METADATA_UPDATE_FAILED\", {\n source: this.source,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Get the total number of pages in the PDF\n */\n public async getPageCount(): Promise<number> {\n try {\n const sourceBytes = await Bun.file(this.source).arrayBuffer();\n const pdfDoc = await PDFDocument.load(sourceBytes, {\n ignoreEncryption: this.options.password !== undefined,\n updateMetadata: false,\n });\n return pdfDoc.getPageCount();\n } catch (error) {\n throw new PDFException(\"Failed to get page count\", \"PDF_PAGE_COUNT_FAILED\", {\n source: this.source,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Get the text content of a specific page\n * @param pageNumber - Page number (1-indexed)\n * @returns Extracted text content from the page\n *\n * @example\n * ```typescript\n * const pdf = new PDF(\"/path/to/document.pdf\");\n *\n * // Get content from page 1\n * const content = await pdf.getPageContent(1);\n * console.log(content); // \"Lorem ipsum dolor sit amet...\"\n *\n * // Get content from a specific page\n * const page3Content = await pdf.getPageContent(3);\n * console.log(page3Content); // Plain text content\n * ```\n */\n public async getPageContent(pageNumber: number): Promise<string> {\n if (pageNumber < 1 || !Number.isInteger(pageNumber)) {\n throw new PDFException(\"Page number must be a positive integer\", \"PDF_INVALID_PAGE_NUMBER\", {\n pageNumber,\n });\n }\n\n try {\n const sourceBytes = await Bun.file(this.source).arrayBuffer();\n const document = await getDocumentProxy(new Uint8Array(sourceBytes));\n const totalPages = document.numPages;\n\n if (pageNumber > totalPages) {\n throw new PDFException(\"Page number exceeds total pages\", \"PDF_PAGE_OUT_OF_RANGE\", {\n pageNumber,\n totalPages,\n });\n }\n\n const page = await document.getPage(pageNumber);\n const textContent = await page.getTextContent();\n const text = textContent.items\n .filter((item) => \"str\" in item)\n .map((item) => (\"hasEOL\" in item && item.hasEOL ? `${item.str}\\n` : item.str))\n .join(\"\");\n\n return text.trim();\n } catch (error) {\n if (error instanceof PDFException) {\n throw error;\n }\n throw new PDFException(\"Failed to get page content\", \"PDF_PAGE_CONTENT_FAILED\", {\n source: this.source,\n pageNumber,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Extract images from PDF pages and save to disk\n * @param options - Options including output directory, optional prefix, and optional page number\n * @returns Result containing total pages and array of extracted images with file paths\n *\n * @example\n * ```typescript\n * const pdf = new PDF(\"/path/to/document.pdf\");\n *\n * // Extract images from all pages\n * const images = await pdf.getImages({ outputDir: \"/output\" });\n * console.log(`Found ${images.length} images`);\n *\n * // Extract images from a specific page\n * const page1Images = await pdf.getImages({ outputDir: \"/output\", prefix: \"doc\", pageNumber: 1 });\n * for (const image of page1Images) {\n * console.log(`Image: ${image.path}, ${image.width}x${image.height}`);\n * }\n * ```\n */\n public async getImages(options: PDFGetImagesOptionsType): Promise<PDFGetImagesResultType> {\n const { pageNumber } = options;\n\n if (pageNumber !== undefined && (pageNumber < 1 || !Number.isInteger(pageNumber))) {\n throw new PDFException(\"Page number must be a positive integer\", \"PDF_INVALID_PAGE_NUMBER\", {\n pageNumber,\n });\n }\n\n const normalizedOutputDir = path.join(...options.outputDir.split(/[/\\\\]/));\n const prefix = options.prefix ?? \"image\";\n\n try {\n const sourceBytes = await Bun.file(this.source).arrayBuffer();\n const document = await getDocumentProxy(new Uint8Array(sourceBytes));\n const totalPages = document.numPages;\n\n if (pageNumber !== undefined && pageNumber > totalPages) {\n throw new PDFException(\"Page number exceeds total pages\", \"PDF_PAGE_OUT_OF_RANGE\", {\n pageNumber,\n totalPages,\n });\n }\n\n const processPage = async (page: number) => {\n const pageImages = await extractImages(document, page);\n const results: PDFExtractedImageType[] = [];\n let imageIndex = 0;\n for (const img of pageImages) {\n imageIndex++;\n const fileName = `${prefix}-p${page}-${imageIndex}.png`;\n const filePath = path.join(normalizedOutputDir, fileName);\n\n // Convert raw image data to PNG using sharp\n const pngBuffer = await sharp(img.data, {\n raw: {\n width: img.width,\n height: img.height,\n channels: img.channels,\n },\n })\n .png()\n .toBuffer();\n\n await Bun.write(filePath, pngBuffer);\n\n results.push({\n page,\n path: filePath,\n width: img.width,\n height: img.height,\n });\n }\n return results;\n };\n\n if (pageNumber !== undefined) {\n return await processPage(pageNumber);\n }\n\n const allResults = await Promise.all(Array.from({ length: totalPages }, (_, i) => processPage(i + 1)));\n return allResults.flat();\n } catch (error) {\n if (error instanceof PDFException) {\n throw error;\n }\n throw new PDFException(\"Failed to extract images from PDF\", \"PDF_EXTRACT_IMAGES_FAILED\", {\n source: this.source,\n outputDir: normalizedOutputDir,\n pageNumber,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Convert all pages to images and save to disk\n * @param options - Options including output directory and optional prefix\n * @returns Array of page image results with page numbers and file paths\n */\n public async *pagesToImages(options: PDFToImagesOptionsType): AsyncGenerator<PDFPageImageResultType, void, unknown> {\n const normalizedOutputDir = path.join(...options.outputDir.split(/[/\\\\]/));\n const prefix = options.prefix ?? \"page\";\n const savedWorker = (globalThis as Record<string, unknown>).pdfjsWorker;\n (globalThis as Record<string, unknown>).pdfjsWorker = undefined;\n\n try {\n const document = await pdf(this.source, this.options);\n let pageNumber = 1;\n\n for await (const image of document) {\n const fileName = `${prefix}-${pageNumber}.png`;\n const filePath = path.join(normalizedOutputDir, fileName);\n\n await Bun.write(filePath, Buffer.from(image));\n\n yield {\n page: pageNumber,\n path: filePath,\n };\n pageNumber++;\n }\n\n (globalThis as Record<string, unknown>).pdfjsWorker = savedWorker;\n } catch (error) {\n (globalThis as Record<string, unknown>).pdfjsWorker = savedWorker;\n throw new PDFException(\"Failed to convert PDF to images\", \"PDF_CONVERT_IMAGES_FAILED\", {\n source: this.source,\n outputDir: normalizedOutputDir,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Convert a specific page to an image and save to disk\n * @param pageNumber - Page number (1-indexed)\n * @param options - Options including output directory and optional prefix\n * @returns Page image result with page number and file path\n */\n public async pageToImage(pageNumber: number, options: PDFToImagesOptionsType): Promise<PDFPageImageResultType> {\n if (pageNumber < 1 || !Number.isInteger(pageNumber)) {\n throw new PDFException(\"Page number must be a positive integer\", \"PDF_INVALID_PAGE_NUMBER\", {\n pageNumber,\n });\n }\n\n const normalizedOutputDir = path.join(...options.outputDir.split(/[/\\\\]/));\n const prefix = options.prefix ?? \"page\";\n const savedWorker = (globalThis as Record<string, unknown>).pdfjsWorker;\n (globalThis as Record<string, unknown>).pdfjsWorker = undefined;\n\n try {\n const document = await pdf(this.source, this.options);\n\n if (pageNumber > document.length) {\n throw new PDFException(\"Page number exceeds total pages\", \"PDF_PAGE_OUT_OF_RANGE\", {\n pageNumber,\n totalPages: document.length,\n });\n }\n\n const image = await document.getPage(pageNumber);\n\n const fileName = `${prefix}-${pageNumber}.png`;\n const filePath = path.join(normalizedOutputDir, fileName);\n\n await Bun.write(filePath, Buffer.from(image));\n\n (globalThis as Record<string, unknown>).pdfjsWorker = savedWorker;\n\n return {\n page: pageNumber,\n path: filePath,\n };\n } catch (error) {\n (globalThis as Record<string, unknown>).pdfjsWorker = savedWorker;\n if (error instanceof PDFException) {\n throw error;\n }\n throw new PDFException(\"Failed to get page image\", \"PDF_PAGE_IMAGE_FAILED\", {\n source: this.source,\n pageNumber,\n outputDir: normalizedOutputDir,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Split the PDF into separate documents and save to disk\n * @param options - Split options with output directory, page ranges, and optional prefix\n * @returns Array of split PDF results with page ranges and file paths\n */\n public async *split(options: PDFSplitOptionsType): AsyncGenerator<PDFSplitResultType, void, unknown> {\n const normalizedOutputDir = path.join(...options.outputDir.split(/[/\\\\]/));\n const prefix = options.prefix ?? \"page\";\n\n try {\n const sourceBytes = await Bun.file(this.source).arrayBuffer();\n\n const sourcePdf = await PDFDocument.load(sourceBytes, {\n ignoreEncryption: this.options.password !== undefined,\n });\n\n const totalPages = sourcePdf.getPageCount();\n\n if (totalPages === 0) {\n throw new PDFException(\"PDF has no pages\", \"PDF_NO_PAGES\", {\n source: this.source,\n });\n }\n\n const ranges = this.normalizeRanges(options.ranges, totalPages);\n\n // Validate all ranges first\n for (const { start, end } of ranges) {\n if (start < 1 || end > totalPages || start > end) {\n throw new PDFException(\"Invalid page range\", \"PDF_INVALID_PAGE_RANGE\", {\n start,\n end,\n totalPages,\n });\n }\n }\n\n for (const { start, end } of ranges) {\n const newPdf = await PDFDocument.create();\n const pageIndices = Array.from({ length: end - start + 1 }, (_, i) => start - 1 + i);\n const copiedPages = await newPdf.copyPages(sourcePdf, pageIndices);\n\n for (const page of copiedPages) {\n newPdf.addPage(page);\n }\n\n const pdfBytes = await newPdf.save();\n\n const fileName = start === end ? `${prefix}-${start}.pdf` : `${prefix}-${start}-${end}.pdf`;\n const filePath = path.join(normalizedOutputDir, fileName);\n\n await Bun.write(filePath, pdfBytes);\n\n yield {\n pages: { start, end },\n path: filePath,\n };\n }\n } catch (error) {\n if (error instanceof PDFException) {\n throw error;\n }\n throw new PDFException(\"Failed to split PDF\", \"PDF_SPLIT_FAILED\", {\n source: this.source,\n outputDir: normalizedOutputDir,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Remove specified pages from the PDF\n * @param pages - Page numbers to remove (1-indexed). Can be individual numbers or ranges [start, end]\n * @returns Result with remaining page count and PDF buffer\n *\n * @example\n * ```typescript\n * const pdf = new PDF(\"/path/to/document.pdf\");\n *\n * // Remove individual pages (pages 2 and 5)\n * const result1 = await pdf.removePages([2, 5]);\n *\n * // Remove a range of pages (pages 3 to 6)\n * const result2 = await pdf.removePages([[3, 6]]);\n *\n * // Remove mixed: individual pages and ranges (pages 1, 4-6, and 10)\n * const result3 = await pdf.removePages([1, [4, 6], 10]);\n *\n * console.log(result3.remainingPages); // Number of pages left\n * console.log(result3.buffer); // Buffer containing the resulting PDF\n *\n * // Save to file\n * await Bun.write(\"/path/to/output.pdf\", result3.buffer);\n * ```\n */\n public async removePages(pages: (number | [number, number])[]): Promise<PDFRemovePagesResultType> {\n try {\n const sourceBytes = await Bun.file(this.source).arrayBuffer();\n\n const pdfDoc = await PDFDocument.load(sourceBytes, {\n ignoreEncryption: this.options.password !== undefined,\n });\n\n const totalPages = pdfDoc.getPageCount();\n\n if (totalPages === 0) {\n throw new PDFException(\"PDF has no pages\", \"PDF_NO_PAGES\", {\n source: this.source,\n });\n }\n\n // Normalize page numbers to remove into a flat sorted array\n const pagesToRemove = this.normalizePageNumbers(pages, totalPages);\n\n if (pagesToRemove.length === 0) {\n throw new PDFException(\"No valid pages specified for removal\", \"PDF_NO_VALID_PAGES\", {\n pages,\n });\n }\n\n if (pagesToRemove.length >= totalPages) {\n throw new PDFException(\"Cannot remove all pages from PDF\", \"PDF_CANNOT_REMOVE_ALL_PAGES\", {\n pagesToRemove,\n totalPages,\n });\n }\n\n // Remove pages in reverse order to maintain correct indices\n const sortedDescending = [...pagesToRemove].sort((a, b) => b - a);\n for (const pageNum of sortedDescending) {\n pdfDoc.removePage(pageNum - 1); // Convert to 0-indexed\n }\n\n const pdfBytes = await pdfDoc.save();\n\n await Bun.write(this.source, pdfBytes);\n\n return {\n remainingPages: pdfDoc.getPageCount(),\n };\n } catch (error) {\n if (error instanceof PDFException) {\n throw error;\n }\n throw new PDFException(\"Failed to remove pages from PDF\", \"PDF_REMOVE_PAGES_FAILED\", {\n source: this.source,\n pages,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n /**\n * Normalize page numbers into a flat array of unique valid page numbers\n */\n private normalizePageNumbers(pages: (number | [number, number])[], totalPages: number): number[] {\n const pageSet = new Set<number>();\n\n for (const page of pages) {\n if (typeof page === \"number\") {\n if (page >= 1 && page <= totalPages && Number.isInteger(page)) {\n pageSet.add(page);\n }\n } else {\n const [start, end] = page;\n if (start <= end) {\n for (let i = Math.max(1, start); i <= Math.min(totalPages, end); i++) {\n if (Number.isInteger(i)) {\n pageSet.add(i);\n }\n }\n }\n }\n }\n\n return Array.from(pageSet);\n }\n\n /**\n * Normalize page ranges for splitting\n * If no ranges provided, creates individual page ranges\n */\n private normalizeRanges(\n ranges: PDFSplitOptionsType[\"ranges\"] | undefined,\n totalPages: number,\n ): { start: number; end: number }[] {\n if (!ranges || ranges.length === 0) {\n return Array.from({ length: totalPages }, (_, i) => ({\n start: i + 1,\n end: i + 1,\n }));\n }\n\n return ranges.map((range) => {\n if (typeof range === \"number\") {\n return { start: range, end: range };\n }\n return { start: range[0], end: range[1] };\n });\n }\n}\n",
|
|
6
|
+
"import { Exception } from \"@ooneex/exception\";\nimport { HttpStatus } from \"@ooneex/http-status\";\n\nexport class PDFException extends Exception {\n constructor(message: string, key: string, data: Record<string, unknown> = {}) {\n super(message, {\n key,\n status: HttpStatus.Code.InternalServerError,\n data,\n });\n this.name = \"PDFException\";\n }\n}\n"
|
|
7
7
|
],
|
|
8
|
-
"mappings": "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",
|
|
9
|
-
"debugId": "
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "50118D49CA2A880B64756E2164756E21",
|
|
10
10
|
"names": []
|
|
11
11
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ooneex/pdf",
|
|
3
3
|
"description": "PDF document toolkit for generating, editing, merging, splitting, and converting PDF files to images with page-level content extraction",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.4",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"npm:publish": "bun publish --tolerate-republish --force --production --access public"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@ooneex/exception": "1.1.
|
|
32
|
-
"@ooneex/http-status": "1.1.
|
|
31
|
+
"@ooneex/exception": "1.1.3",
|
|
32
|
+
"@ooneex/http-status": "1.1.3",
|
|
33
33
|
"pdf-lib": "^1.17.1",
|
|
34
34
|
"pdf-to-img": "^5.0.0",
|
|
35
35
|
"sharp": "^0.34.0",
|