unpdf 1.0.2 → 1.0.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/README.md +27 -26
- package/dist/index.cjs +12 -9
- package/dist/index.d.cts +2 -4
- package/dist/index.d.mts +2 -4
- package/dist/index.d.ts +2 -4
- package/dist/index.mjs +12 -9
- package/dist/pdfjs.mjs +1 -1
- package/package.json +2 -5
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# unpdf
|
|
2
2
|
|
|
3
|
-
A collection of utilities for PDF extraction and rendering. Designed specifically for
|
|
3
|
+
A collection of utilities for PDF extraction and rendering. Designed specifically for serverless environments, but it also works in Node.js, Deno, Bun and the browser. `unpdf` is particularly useful for serverless AI applications, especially for summarizing PDF documents in document analysis workflows.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This library ships with a serverless build/redistribution of Mozilla's [PDF.js](https://github.com/mozilla/pdf.js) that is optimized for edge environments. Some string replacements, global mocks and inlining the PDF.js worker allow the browser code to become platform agnostic. See [`pdfjs.rollup.config.ts`](./pdfjs.rollup.config.ts) for the details.
|
|
6
6
|
|
|
7
7
|
This library is also intended as a modern alternative to the unmaintained but still popular [`pdf-parse`](https://www.npmjs.com/package/pdf-parse).
|
|
8
8
|
|
|
@@ -11,6 +11,7 @@ This library is also intended as a modern alternative to the unmaintained but st
|
|
|
11
11
|
- 🏗️ Made for Node.js, browser and serverless environments
|
|
12
12
|
- 🪭 Includes serverless build of PDF.js ([`unpdf/pdfjs`](./package.json#L34))
|
|
13
13
|
- 💬 Extract [text](#extract-text-from-pdf) and [images](#extractimages) from PDF files
|
|
14
|
+
- 🧠 Perfect for AI applications and PDF summarization
|
|
14
15
|
- 🧱 Opt-in to legacy PDF.js build
|
|
15
16
|
- 💨 Zero dependencies
|
|
16
17
|
|
|
@@ -19,7 +20,7 @@ This library is also intended as a modern alternative to the unmaintained but st
|
|
|
19
20
|
> [!Tip]
|
|
20
21
|
> The serverless PDF.js bundle provided by `unpdf` is built from PDF.js v5.2.133.
|
|
21
22
|
|
|
22
|
-
You can use an [official PDF.js build](#
|
|
23
|
+
You can use an [official PDF.js build](#official-or-legacy-pdfjs-build) by using the [`definePDFJSModule`](#definepdfjsmodule) method. This is useful if you want to use a specific version or a custom build of PDF.js.
|
|
23
24
|
|
|
24
25
|
## Installation
|
|
25
26
|
|
|
@@ -58,6 +59,25 @@ console.log(`Total pages: ${totalPages}`)
|
|
|
58
59
|
console.log(text)
|
|
59
60
|
```
|
|
60
61
|
|
|
62
|
+
### Official or Legacy PDF.js Build
|
|
63
|
+
|
|
64
|
+
Usually you don't need to worry about the PDF.js build. `unpdf` ships with a serverless build of the latest PDF.js version. However, if you want to use the official PDF.js version or the legacy build, you can define a custom PDF.js module.
|
|
65
|
+
|
|
66
|
+
> [!WARNING]
|
|
67
|
+
> PDF.js v5.x uses `Promise.withResolvers`, which may not be supported in all environments, such as Node < 22. Consider to use the bundled serverless build, which includes a polyfill, or use an older version of PDF.js.
|
|
68
|
+
|
|
69
|
+
For example, if you want to use the official PDF.js build, you can do the following:
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import { definePDFJSModule } from 'unpdf'
|
|
73
|
+
|
|
74
|
+
// Define the PDF.js build before using any other unpdf method
|
|
75
|
+
await definePDFJSModule(() => import('pdfjs-dist'))
|
|
76
|
+
|
|
77
|
+
// Now, you can use all unpdf methods with the official PDF.js build
|
|
78
|
+
const { text } = await extractText(pdf)
|
|
79
|
+
```
|
|
80
|
+
|
|
61
81
|
### PDF.js API
|
|
62
82
|
|
|
63
83
|
`unpdf` provides helpful [methods](#api) to work with PDF files, such as `extractText` and `extractImages`, which should cover most use cases. However, if you need more control over the PDF.js API, you can use the `getResolvedPDFJS` method to get the resolved PDF.js module.
|
|
@@ -80,37 +100,18 @@ import { getResolvedPDFJS } from 'unpdf'
|
|
|
80
100
|
|
|
81
101
|
const { getDocument } = await getResolvedPDFJS()
|
|
82
102
|
const data = Deno.readFileSync('dummy.pdf')
|
|
83
|
-
const
|
|
103
|
+
const document = await getDocument(data).promise
|
|
84
104
|
|
|
85
|
-
console.log(await
|
|
105
|
+
console.log(await document.getMetadata())
|
|
86
106
|
|
|
87
|
-
for (let i = 1; i <=
|
|
88
|
-
const page = await
|
|
107
|
+
for (let i = 1; i <= document.numPages; i++) {
|
|
108
|
+
const page = await document.getPage(i)
|
|
89
109
|
const textContent = await page.getTextContent()
|
|
90
110
|
const contents = textContent.items.map(item => item.str).join(' ')
|
|
91
111
|
console.log(contents)
|
|
92
112
|
}
|
|
93
113
|
```
|
|
94
114
|
|
|
95
|
-
### Use Official or Legacy PDF.js Build
|
|
96
|
-
|
|
97
|
-
Usually you don't need to worry about the PDF.js build. `unpdf` ships with a serverless build of the latest PDF.js version. However, if you want to use the official PDF.js version or the legacy build, you can define a custom PDF.js module.
|
|
98
|
-
|
|
99
|
-
> [!WARNING]
|
|
100
|
-
> Later PDF.js v4.x versions uses `Promise.withResolvers`, which may not be supported in all environments, such as Node < 22. Consider to use the bundled serverless build, which includes a polyfill, or use an older version of PDF.js.
|
|
101
|
-
|
|
102
|
-
For example, if you want to use the official PDF.js build, you can do the following:
|
|
103
|
-
|
|
104
|
-
```ts
|
|
105
|
-
import { definePDFJSModule } from 'unpdf'
|
|
106
|
-
|
|
107
|
-
// Define the PDF.js build before using any other unpdf method
|
|
108
|
-
await definePDFJSModule(() => import('pdfjs-dist'))
|
|
109
|
-
|
|
110
|
-
// Now, you can use all unpdf methods with the official PDF.js build
|
|
111
|
-
const { text } = await extractText(pdf)
|
|
112
|
-
```
|
|
113
|
-
|
|
114
115
|
## API
|
|
115
116
|
|
|
116
117
|
### `definePDFJSModule`
|
package/dist/index.cjs
CHANGED
|
@@ -35,7 +35,7 @@ async function resolvePDFJSImport(pdfjsResolver, { reload = false } = {}) {
|
|
|
35
35
|
try {
|
|
36
36
|
resolvedModule = await import('unpdf/pdfjs');
|
|
37
37
|
} catch (error) {
|
|
38
|
-
throw new Error(`
|
|
38
|
+
throw new Error(`Serverless PDF.js bundle could not be resolved: ${error}`);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
function isPDFDocumentProxy(data) {
|
|
@@ -46,7 +46,7 @@ async function interopDefault(m) {
|
|
|
46
46
|
return resolved.default || resolved;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
let
|
|
49
|
+
let resolvedCanvasModule;
|
|
50
50
|
/**
|
|
51
51
|
* Derived from the PDF.js project by the Mozilla Foundation.
|
|
52
52
|
* @see https://github.com/mozilla/pdf.js/blob/b8de9a372f9bbf7e33adb362eeae5ef1919dba73/src/display/canvas_factory.js#L18
|
|
@@ -110,21 +110,24 @@ class NodeCanvasFactory extends BaseCanvasFactory {
|
|
|
110
110
|
super({ enableHWA });
|
|
111
111
|
}
|
|
112
112
|
_createCanvas(width, height) {
|
|
113
|
-
if (!
|
|
113
|
+
if (!resolvedCanvasModule) {
|
|
114
114
|
throw new Error("@napi-rs/canvas module is not resolved");
|
|
115
115
|
}
|
|
116
|
-
return
|
|
116
|
+
return resolvedCanvasModule.createCanvas(width, height);
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
async function resolveCanvasModule(canvasImport) {
|
|
120
|
-
|
|
120
|
+
resolvedCanvasModule ??= await interopDefault(canvasImport());
|
|
121
121
|
}
|
|
122
122
|
function injectCanvasConstructors() {
|
|
123
|
-
if (!
|
|
123
|
+
if (!resolvedCanvasModule)
|
|
124
124
|
return;
|
|
125
|
-
globalThis.DOMMatrix
|
|
126
|
-
|
|
127
|
-
globalThis.
|
|
125
|
+
if (typeof globalThis.DOMMatrix === "undefined")
|
|
126
|
+
globalThis.DOMMatrix = resolvedCanvasModule.DOMMatrix;
|
|
127
|
+
if (typeof globalThis.ImageData === "undefined")
|
|
128
|
+
globalThis.ImageData = resolvedCanvasModule.ImageData;
|
|
129
|
+
if (typeof globalThis.Path2D === "undefined")
|
|
130
|
+
globalThis.Path2D = resolvedCanvasModule.Path2D;
|
|
128
131
|
}
|
|
129
132
|
|
|
130
133
|
async function extractImages$1(data, pageNumber) {
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _napi_rs_canvas from '@napi-rs/canvas';
|
|
2
2
|
import { DocumentInitParameters, PDFDocumentProxy } from './types/src/display/api';
|
|
3
|
-
import * as
|
|
3
|
+
import * as PDFJS from './types/src/pdf';
|
|
4
4
|
|
|
5
5
|
interface ExtractedImageObject {
|
|
6
6
|
data: Uint8ClampedArray;
|
|
@@ -69,8 +69,6 @@ declare function configureUnPDF(options: {
|
|
|
69
69
|
pdfjs?: () => Promise<any>;
|
|
70
70
|
}): Promise<void>;
|
|
71
71
|
|
|
72
|
-
type PDFJS = typeof _PDFJS;
|
|
73
|
-
|
|
74
72
|
/**
|
|
75
73
|
* Returns a PDFDocumentProxy instance from a given binary data.
|
|
76
74
|
*
|
|
@@ -79,7 +77,7 @@ type PDFJS = typeof _PDFJS;
|
|
|
79
77
|
* - `useSystemFonts: true`
|
|
80
78
|
*/
|
|
81
79
|
declare function getDocumentProxy(data: DocumentInitParameters['data'], options?: DocumentInitParameters): Promise<PDFDocumentProxy>;
|
|
82
|
-
declare function getResolvedPDFJS(): Promise<PDFJS>;
|
|
80
|
+
declare function getResolvedPDFJS(): Promise<typeof PDFJS>;
|
|
83
81
|
declare function resolvePDFJSImport(pdfjsResolver?: () => Promise<any>, { reload }?: {
|
|
84
82
|
reload?: boolean | undefined;
|
|
85
83
|
}): Promise<void>;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _napi_rs_canvas from '@napi-rs/canvas';
|
|
2
2
|
import { DocumentInitParameters, PDFDocumentProxy } from './types/src/display/api';
|
|
3
|
-
import * as
|
|
3
|
+
import * as PDFJS from './types/src/pdf';
|
|
4
4
|
|
|
5
5
|
interface ExtractedImageObject {
|
|
6
6
|
data: Uint8ClampedArray;
|
|
@@ -69,8 +69,6 @@ declare function configureUnPDF(options: {
|
|
|
69
69
|
pdfjs?: () => Promise<any>;
|
|
70
70
|
}): Promise<void>;
|
|
71
71
|
|
|
72
|
-
type PDFJS = typeof _PDFJS;
|
|
73
|
-
|
|
74
72
|
/**
|
|
75
73
|
* Returns a PDFDocumentProxy instance from a given binary data.
|
|
76
74
|
*
|
|
@@ -79,7 +77,7 @@ type PDFJS = typeof _PDFJS;
|
|
|
79
77
|
* - `useSystemFonts: true`
|
|
80
78
|
*/
|
|
81
79
|
declare function getDocumentProxy(data: DocumentInitParameters['data'], options?: DocumentInitParameters): Promise<PDFDocumentProxy>;
|
|
82
|
-
declare function getResolvedPDFJS(): Promise<PDFJS>;
|
|
80
|
+
declare function getResolvedPDFJS(): Promise<typeof PDFJS>;
|
|
83
81
|
declare function resolvePDFJSImport(pdfjsResolver?: () => Promise<any>, { reload }?: {
|
|
84
82
|
reload?: boolean | undefined;
|
|
85
83
|
}): Promise<void>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _napi_rs_canvas from '@napi-rs/canvas';
|
|
2
2
|
import { DocumentInitParameters, PDFDocumentProxy } from './types/src/display/api';
|
|
3
|
-
import * as
|
|
3
|
+
import * as PDFJS from './types/src/pdf';
|
|
4
4
|
|
|
5
5
|
interface ExtractedImageObject {
|
|
6
6
|
data: Uint8ClampedArray;
|
|
@@ -69,8 +69,6 @@ declare function configureUnPDF(options: {
|
|
|
69
69
|
pdfjs?: () => Promise<any>;
|
|
70
70
|
}): Promise<void>;
|
|
71
71
|
|
|
72
|
-
type PDFJS = typeof _PDFJS;
|
|
73
|
-
|
|
74
72
|
/**
|
|
75
73
|
* Returns a PDFDocumentProxy instance from a given binary data.
|
|
76
74
|
*
|
|
@@ -79,7 +77,7 @@ type PDFJS = typeof _PDFJS;
|
|
|
79
77
|
* - `useSystemFonts: true`
|
|
80
78
|
*/
|
|
81
79
|
declare function getDocumentProxy(data: DocumentInitParameters['data'], options?: DocumentInitParameters): Promise<PDFDocumentProxy>;
|
|
82
|
-
declare function getResolvedPDFJS(): Promise<PDFJS>;
|
|
80
|
+
declare function getResolvedPDFJS(): Promise<typeof PDFJS>;
|
|
83
81
|
declare function resolvePDFJSImport(pdfjsResolver?: () => Promise<any>, { reload }?: {
|
|
84
82
|
reload?: boolean | undefined;
|
|
85
83
|
}): Promise<void>;
|
package/dist/index.mjs
CHANGED
|
@@ -33,7 +33,7 @@ async function resolvePDFJSImport(pdfjsResolver, { reload = false } = {}) {
|
|
|
33
33
|
try {
|
|
34
34
|
resolvedModule = await import('unpdf/pdfjs');
|
|
35
35
|
} catch (error) {
|
|
36
|
-
throw new Error(`
|
|
36
|
+
throw new Error(`Serverless PDF.js bundle could not be resolved: ${error}`);
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
function isPDFDocumentProxy(data) {
|
|
@@ -44,7 +44,7 @@ async function interopDefault(m) {
|
|
|
44
44
|
return resolved.default || resolved;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
let
|
|
47
|
+
let resolvedCanvasModule;
|
|
48
48
|
/**
|
|
49
49
|
* Derived from the PDF.js project by the Mozilla Foundation.
|
|
50
50
|
* @see https://github.com/mozilla/pdf.js/blob/b8de9a372f9bbf7e33adb362eeae5ef1919dba73/src/display/canvas_factory.js#L18
|
|
@@ -108,21 +108,24 @@ class NodeCanvasFactory extends BaseCanvasFactory {
|
|
|
108
108
|
super({ enableHWA });
|
|
109
109
|
}
|
|
110
110
|
_createCanvas(width, height) {
|
|
111
|
-
if (!
|
|
111
|
+
if (!resolvedCanvasModule) {
|
|
112
112
|
throw new Error("@napi-rs/canvas module is not resolved");
|
|
113
113
|
}
|
|
114
|
-
return
|
|
114
|
+
return resolvedCanvasModule.createCanvas(width, height);
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
async function resolveCanvasModule(canvasImport) {
|
|
118
|
-
|
|
118
|
+
resolvedCanvasModule ??= await interopDefault(canvasImport());
|
|
119
119
|
}
|
|
120
120
|
function injectCanvasConstructors() {
|
|
121
|
-
if (!
|
|
121
|
+
if (!resolvedCanvasModule)
|
|
122
122
|
return;
|
|
123
|
-
globalThis.DOMMatrix
|
|
124
|
-
|
|
125
|
-
globalThis.
|
|
123
|
+
if (typeof globalThis.DOMMatrix === "undefined")
|
|
124
|
+
globalThis.DOMMatrix = resolvedCanvasModule.DOMMatrix;
|
|
125
|
+
if (typeof globalThis.ImageData === "undefined")
|
|
126
|
+
globalThis.ImageData = resolvedCanvasModule.ImageData;
|
|
127
|
+
if (typeof globalThis.Path2D === "undefined")
|
|
128
|
+
globalThis.Path2D = resolvedCanvasModule.Path2D;
|
|
126
129
|
}
|
|
127
130
|
|
|
128
131
|
async function extractImages$1(data, pageNumber) {
|