unpdf 1.6.2 → 1.7.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 +60 -24
- package/dist/index.cjs +145 -110
- package/dist/index.d.cts +13 -6
- package/dist/index.d.mts +13 -6
- package/dist/index.d.ts +13 -6
- package/dist/index.mjs +145 -110
- package/dist/pdfjs.d.mts +1 -1
- package/dist/pdfjs.d.ts +1 -1
- package/dist/pdfjs.mjs +1 -1
- package/dist/types/src/display/annotation_layer.d.ts +2 -2
- package/dist/types/src/display/text_layer.d.ts +4 -4
- package/dist/types/src/display/xfa_layer.d.ts +3 -3
- package/dist/types/src/display/xfa_text.d.ts +2 -2
- package/dist/types/src/pdf.d.ts +6 -6
- package/dist/types/web/annotation_editor_layer_builder.d.ts +5 -5
- package/dist/types/web/annotation_layer_builder.d.ts +9 -9
- package/dist/types/web/pdf_find_controller.d.ts +4 -4
- package/dist/types/web/pdf_history.d.ts +1 -1
- package/dist/types/web/pdf_link_service.d.ts +2 -2
- package/dist/types/web/pdf_page_view.d.ts +12 -12
- package/dist/types/web/pdf_rendering_queue.d.ts +3 -3
- package/dist/types/web/pdf_scripting_manager.d.ts +1 -1
- package/dist/types/web/pdf_thumbnail_view.d.ts +9 -9
- package/dist/types/web/pdf_thumbnail_viewer.d.ts +7 -7
- package/dist/types/web/pdf_viewer.d.ts +14 -14
- package/dist/types/web/renderable_view.d.ts +2 -2
- package/dist/types/web/struct_tree_layer_builder.d.ts +1 -1
- package/dist/types/web/text_highlighter.d.ts +6 -6
- package/dist/types/web/text_layer_builder.d.ts +6 -6
- package/dist/types/web/xfa_layer_builder.d.ts +6 -6
- package/package.json +3 -2
package/dist/index.mjs
CHANGED
|
@@ -55,7 +55,9 @@ async function getDocumentProxy(data, options = {}) {
|
|
|
55
55
|
const base = import.meta.resolve("pdfjs-dist/package.json");
|
|
56
56
|
nodeDefaults = {
|
|
57
57
|
disableFontFace: true,
|
|
58
|
-
standardFontDataUrl: new URL("./standard_fonts/", base).href
|
|
58
|
+
standardFontDataUrl: new URL("./standard_fonts/", base).href,
|
|
59
|
+
cMapUrl: new URL("./cmaps/", base).href,
|
|
60
|
+
cMapPacked: true
|
|
59
61
|
};
|
|
60
62
|
} catch {
|
|
61
63
|
}
|
|
@@ -70,6 +72,15 @@ async function getDocumentProxy(data, options = {}) {
|
|
|
70
72
|
}).promise;
|
|
71
73
|
return pdf;
|
|
72
74
|
}
|
|
75
|
+
async function withDocument(data, operation, options) {
|
|
76
|
+
const pdf = isPDFDocumentProxy(data) ? data : await getDocumentProxy(data, options);
|
|
77
|
+
try {
|
|
78
|
+
return await operation(pdf);
|
|
79
|
+
} finally {
|
|
80
|
+
if (pdf !== data)
|
|
81
|
+
await pdf.destroy();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
73
84
|
async function getResolvedPDFJS() {
|
|
74
85
|
if (!resolvedModule) {
|
|
75
86
|
await resolvePDFJSImport();
|
|
@@ -175,6 +186,7 @@ class NodeCanvasFactory extends BaseCanvasFactory {
|
|
|
175
186
|
}
|
|
176
187
|
async function resolveCanvasModule(canvasImport) {
|
|
177
188
|
resolvedCanvasModule ??= await interopDefault(canvasImport());
|
|
189
|
+
globalThis[Symbol.for("unpdf.canvasModule")] = resolvedCanvasModule;
|
|
178
190
|
}
|
|
179
191
|
function injectCanvasConstructors() {
|
|
180
192
|
if (!resolvedCanvasModule)
|
|
@@ -187,69 +199,85 @@ function injectCanvasConstructors() {
|
|
|
187
199
|
}
|
|
188
200
|
|
|
189
201
|
async function extractImages$1(data, pageNumber) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
const page = await pdf.getPage(pageNumber);
|
|
195
|
-
const operatorList = await page.getOperatorList();
|
|
196
|
-
const { OPS } = await getResolvedPDFJS();
|
|
197
|
-
const images = [];
|
|
198
|
-
for (let i = 0; i < operatorList.fnArray.length; i++) {
|
|
199
|
-
const op = operatorList.fnArray[i];
|
|
200
|
-
if (op !== OPS.paintImageXObject) {
|
|
201
|
-
continue;
|
|
202
|
-
}
|
|
203
|
-
const imageKey = operatorList.argsArray[i][0];
|
|
204
|
-
const image = await new Promise(
|
|
205
|
-
(resolve) => (imageKey.startsWith("g_") ? page.commonObjs : page.objs).get(imageKey, resolve)
|
|
206
|
-
);
|
|
207
|
-
if (!image || !image.data || !image.width || !image.height) {
|
|
208
|
-
continue;
|
|
202
|
+
return await withDocument(data, async (pdf) => {
|
|
203
|
+
if (pageNumber < 1 || pageNumber > pdf.numPages) {
|
|
204
|
+
throw new Error(`Invalid page number. Must be between 1 and ${pdf.numPages}.`);
|
|
209
205
|
}
|
|
210
|
-
const
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
206
|
+
const page = await pdf.getPage(pageNumber);
|
|
207
|
+
const operatorList = await page.getOperatorList();
|
|
208
|
+
const { OPS } = await getResolvedPDFJS();
|
|
209
|
+
const images = [];
|
|
210
|
+
for (let i = 0; i < operatorList.fnArray.length; i++) {
|
|
211
|
+
const op = operatorList.fnArray[i];
|
|
212
|
+
if (op !== OPS.paintImageXObject) {
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
const imageKey = operatorList.argsArray[i][0];
|
|
216
|
+
const image = await new Promise(
|
|
217
|
+
(resolve) => (imageKey.startsWith("g_") ? page.commonObjs : page.objs).get(imageKey, resolve)
|
|
218
|
+
);
|
|
219
|
+
if (!image || !image.data || !image.width || !image.height) {
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
const { width, height, data: data2 } = image;
|
|
223
|
+
const calculatedChannels = data2.length / (width * height);
|
|
224
|
+
if (![1, 3, 4].includes(calculatedChannels)) {
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
const channels = calculatedChannels;
|
|
228
|
+
images.push({
|
|
229
|
+
data: data2,
|
|
230
|
+
width,
|
|
231
|
+
height,
|
|
232
|
+
channels,
|
|
233
|
+
key: imageKey
|
|
234
|
+
});
|
|
214
235
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
data: data2,
|
|
218
|
-
width,
|
|
219
|
-
height,
|
|
220
|
-
channels,
|
|
221
|
-
key: imageKey
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
return images;
|
|
236
|
+
return images;
|
|
237
|
+
});
|
|
225
238
|
}
|
|
226
239
|
async function renderPageAsImage$1(data, pageNumber, options = {}) {
|
|
227
240
|
const CanvasFactory = await createIsomorphicCanvasFactory(options.canvasImport);
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
241
|
+
return await withDocument(data, async (pdf) => {
|
|
242
|
+
if (pageNumber < 1 || pageNumber > pdf.numPages) {
|
|
243
|
+
throw new Error(`Invalid page number. Must be between 1 and ${pdf.numPages}.`);
|
|
244
|
+
}
|
|
245
|
+
const page = await pdf.getPage(pageNumber);
|
|
246
|
+
const defaultViewport = page.getViewport({ scale: 1 });
|
|
247
|
+
let scale = options.scale || 1;
|
|
248
|
+
if (options.width) {
|
|
249
|
+
scale = options.width / defaultViewport.width;
|
|
250
|
+
} else if (options.height) {
|
|
251
|
+
scale = options.height / defaultViewport.height;
|
|
252
|
+
}
|
|
253
|
+
const viewport = page.getViewport({ scale: Math.max(0, scale) });
|
|
254
|
+
const canvasFactory = new CanvasFactory();
|
|
255
|
+
const drawingContext = canvasFactory.create(viewport.width, viewport.height);
|
|
256
|
+
try {
|
|
257
|
+
await page.render({
|
|
258
|
+
canvas: drawingContext.canvas,
|
|
259
|
+
canvasContext: drawingContext.context,
|
|
260
|
+
viewport
|
|
261
|
+
}).promise;
|
|
262
|
+
const { canvas } = drawingContext;
|
|
263
|
+
if (options.toDataURL) {
|
|
264
|
+
return canvas.toDataURL();
|
|
265
|
+
}
|
|
266
|
+
if ("encode" in canvas) {
|
|
267
|
+
const buffer = await canvas.encode("png");
|
|
268
|
+
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
269
|
+
}
|
|
270
|
+
const blob = await new Promise((resolve) => {
|
|
271
|
+
canvas.toBlob(resolve);
|
|
272
|
+
});
|
|
273
|
+
if (!blob) {
|
|
274
|
+
throw new Error("Failed to encode canvas to a PNG blob.");
|
|
275
|
+
}
|
|
276
|
+
return await blob.arrayBuffer();
|
|
277
|
+
} finally {
|
|
278
|
+
canvasFactory.destroy(drawingContext);
|
|
279
|
+
}
|
|
280
|
+
}, { CanvasFactory });
|
|
253
281
|
}
|
|
254
282
|
async function createIsomorphicCanvasFactory(canvasImport) {
|
|
255
283
|
if (isBrowser)
|
|
@@ -266,14 +294,15 @@ async function createIsomorphicCanvasFactory(canvasImport) {
|
|
|
266
294
|
}
|
|
267
295
|
|
|
268
296
|
async function extractLinks$1(data) {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
297
|
+
return await withDocument(data, async (pdf) => {
|
|
298
|
+
const pageLinks = await Promise.all(
|
|
299
|
+
Array.from({ length: pdf.numPages }, (_, i) => getPageLinks(pdf, i + 1))
|
|
300
|
+
);
|
|
301
|
+
return {
|
|
302
|
+
totalPages: pdf.numPages,
|
|
303
|
+
links: pageLinks.flat()
|
|
304
|
+
};
|
|
305
|
+
});
|
|
277
306
|
}
|
|
278
307
|
async function getPageLinks(document, pageNumber) {
|
|
279
308
|
const page = await document.getPage(pageNumber);
|
|
@@ -296,38 +325,39 @@ const XMP_DATE_PROPERTIES = [
|
|
|
296
325
|
"xap:metadatadate"
|
|
297
326
|
];
|
|
298
327
|
async function getMeta$1(data, options = {}) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
328
|
+
return await withDocument(data, async (pdf) => {
|
|
329
|
+
const meta = await pdf.getMetadata();
|
|
330
|
+
const info = meta?.info || {};
|
|
331
|
+
if (options.parseDates) {
|
|
332
|
+
const { PDFDateString } = await getResolvedPDFJS();
|
|
333
|
+
if (info?.CreationDate) {
|
|
334
|
+
info.CreationDate = PDFDateString.toDateObject(info?.CreationDate);
|
|
335
|
+
}
|
|
336
|
+
if (info?.ModDate) {
|
|
337
|
+
info.ModDate = PDFDateString.toDateObject(info?.ModDate);
|
|
338
|
+
}
|
|
339
|
+
if (meta.metadata) {
|
|
340
|
+
meta.metadata = new Proxy(meta.metadata, {
|
|
341
|
+
get(target, prop) {
|
|
342
|
+
if (prop === "get") {
|
|
343
|
+
return (name) => {
|
|
344
|
+
const value = target.get(name);
|
|
345
|
+
if (XMP_DATE_PROPERTIES.includes(name) && value) {
|
|
346
|
+
return parseISODateString(value);
|
|
347
|
+
}
|
|
348
|
+
return value;
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
return target[prop];
|
|
321
352
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
});
|
|
353
|
+
});
|
|
354
|
+
}
|
|
325
355
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
};
|
|
356
|
+
return {
|
|
357
|
+
info,
|
|
358
|
+
metadata: meta?.metadata || {}
|
|
359
|
+
};
|
|
360
|
+
});
|
|
331
361
|
}
|
|
332
362
|
function parseISODateString(isoDateString) {
|
|
333
363
|
if (!isoDateString)
|
|
@@ -339,11 +369,12 @@ function parseISODateString(isoDateString) {
|
|
|
339
369
|
}
|
|
340
370
|
|
|
341
371
|
async function extractTextItems$1(data) {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
372
|
+
return await withDocument(data, async (pdf) => {
|
|
373
|
+
const items = await Promise.all(
|
|
374
|
+
Array.from({ length: pdf.numPages }, (_, i) => getPageTextItems(pdf, i + 1))
|
|
375
|
+
);
|
|
376
|
+
return { totalPages: pdf.numPages, items };
|
|
377
|
+
});
|
|
347
378
|
}
|
|
348
379
|
async function getPageTextItems(document, pageNumber) {
|
|
349
380
|
const page = await document.getPage(pageNumber);
|
|
@@ -366,20 +397,24 @@ async function getPageTextItems(document, pageNumber) {
|
|
|
366
397
|
}
|
|
367
398
|
async function extractText$1(data, options = {}) {
|
|
368
399
|
const { mergePages = false } = options;
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
400
|
+
return await withDocument(data, async (pdf) => {
|
|
401
|
+
const texts = await Promise.all(
|
|
402
|
+
Array.from({ length: pdf.numPages }, (_, i) => getPageText(pdf, i + 1))
|
|
403
|
+
);
|
|
404
|
+
return {
|
|
405
|
+
totalPages: pdf.numPages,
|
|
406
|
+
text: mergePages ? normalizeMergedText(texts) : texts
|
|
407
|
+
};
|
|
408
|
+
});
|
|
377
409
|
}
|
|
378
410
|
async function getPageText(document, pageNumber) {
|
|
379
411
|
const page = await document.getPage(pageNumber);
|
|
380
412
|
const content = await page.getTextContent();
|
|
381
413
|
return content.items.filter((item) => item.str != null).map((item) => item.str + (item.hasEOL ? "\n" : "")).join("");
|
|
382
414
|
}
|
|
415
|
+
function normalizeMergedText(texts) {
|
|
416
|
+
return texts.join("\n").replace(/[^\S\n]+/g, " ").replace(/ ?\n ?/g, "\n").replace(/\n{3,}/g, "\n\n");
|
|
417
|
+
}
|
|
383
418
|
|
|
384
419
|
async function definePDFJSModule(pdfjs) {
|
|
385
420
|
await resolvePDFJSImport(pdfjs, { reload: true });
|
package/dist/pdfjs.d.mts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './types/src/pdf'
|
|
1
|
+
export * from './types/src/pdf.js'
|
package/dist/pdfjs.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './types/src/pdf'
|
|
1
|
+
export * from './types/src/pdf.js'
|