@firecrawl/pdf-inspector 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,99 @@
1
+ # firecrawl-pdf-inspector
2
+
3
+ Fast PDF classification and region-based text extraction for Node.js/Bun. Native Rust performance via [napi-rs](https://napi.rs).
4
+
5
+ Built by [Firecrawl](https://firecrawl.dev) for hybrid OCR pipelines — extract text from PDF structure where possible, fall back to OCR only when needed.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install firecrawl-pdf-inspector
11
+ # or
12
+ bun add firecrawl-pdf-inspector
13
+ ```
14
+
15
+ Prebuilt binaries included for **linux-x64** and **macOS ARM64**. No Rust toolchain needed.
16
+
17
+ ## API
18
+
19
+ ### `classifyPdf(buffer: Buffer): PdfClassification`
20
+
21
+ Classify a PDF as TextBased, Scanned, Mixed, or ImageBased (~10-50ms). Returns which pages need OCR.
22
+
23
+ ```typescript
24
+ import { classifyPdf } from 'firecrawl-pdf-inspector'
25
+ import { readFileSync } from 'fs'
26
+
27
+ const pdf = readFileSync('document.pdf')
28
+ const result = classifyPdf(pdf)
29
+
30
+ console.log(result.pdfType) // "TextBased" | "Scanned" | "Mixed" | "ImageBased"
31
+ console.log(result.pageCount) // 42
32
+ console.log(result.pagesNeedingOcr) // [5, 12, 15] (0-indexed)
33
+ console.log(result.confidence) // 0.875
34
+ ```
35
+
36
+ ### `extractTextInRegions(buffer: Buffer, pageRegions: PageRegions[]): PageRegionTexts[]`
37
+
38
+ Extract text within bounding-box regions from a PDF. Designed for hybrid OCR pipelines where a layout model detects regions in rendered page images, and this function extracts text from the PDF structure for text-based pages — skipping GPU OCR.
39
+
40
+ Each region result includes a `needsOcr` flag that signals unreliable extraction (empty text, GID-encoded fonts, garbage text, encoding issues).
41
+
42
+ ```typescript
43
+ import { extractTextInRegions } from 'firecrawl-pdf-inspector'
44
+
45
+ const result = extractTextInRegions(pdf, [
46
+ {
47
+ page: 0, // 0-indexed
48
+ regions: [
49
+ [0, 0, 300, 400], // [x1, y1, x2, y2] in PDF points, top-left origin
50
+ [300, 0, 612, 400],
51
+ ]
52
+ }
53
+ ])
54
+
55
+ for (const region of result[0].regions) {
56
+ if (region.needsOcr) {
57
+ // Unreliable text — send this region to OCR instead
58
+ } else {
59
+ console.log(region.text) // Extracted text in reading order
60
+ }
61
+ }
62
+ ```
63
+
64
+ ## Types
65
+
66
+ ```typescript
67
+ interface PdfClassification {
68
+ pdfType: string // "TextBased" | "Scanned" | "Mixed" | "ImageBased"
69
+ pageCount: number
70
+ pagesNeedingOcr: number[] // 0-indexed page numbers
71
+ confidence: number // 0.0 - 1.0
72
+ }
73
+
74
+ interface PageRegions {
75
+ page: number // 0-indexed
76
+ regions: number[][] // [[x1, y1, x2, y2], ...] in PDF points, top-left origin
77
+ }
78
+
79
+ interface PageRegionTexts {
80
+ page: number
81
+ regions: RegionText[]
82
+ }
83
+
84
+ interface RegionText {
85
+ text: string
86
+ needsOcr: boolean // true when text is unreliable
87
+ }
88
+ ```
89
+
90
+ ## Platforms
91
+
92
+ | Platform | Architecture | Supported |
93
+ |----------|-------------|-----------|
94
+ | Linux | x64 | Yes |
95
+ | macOS | ARM64 | Yes |
96
+
97
+ ## License
98
+
99
+ MIT
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { readFileSync, writeFileSync } from "fs";
4
+ import { createRequire } from "module";
5
+
6
+ const require = createRequire(import.meta.url);
7
+ const { version } = require("../package.json");
8
+
9
+ const HELP = `pdf-inspector v${version} — Fast PDF text extraction to Markdown
10
+
11
+ Usage:
12
+ pdf-inspector <file> Extract markdown (default)
13
+ pdf-inspector detect <file> Classify PDF type
14
+
15
+ Options:
16
+ --json Output as JSON
17
+ --pages <pages> Comma-separated page numbers (e.g. 1,3,5)
18
+ -o, --output <file> Write output to file instead of stdout
19
+ -h, --help Show this help
20
+ -v, --version Show version
21
+
22
+ Examples:
23
+ pdf-inspector document.pdf
24
+ pdf-inspector document.pdf --json
25
+ pdf-inspector document.pdf --pages 1,2,3
26
+ pdf-inspector detect document.pdf --json
27
+ cat document.pdf | pdf-inspector -`;
28
+
29
+ function die(msg) {
30
+ process.stderr.write(`error: ${msg}\n`);
31
+ process.exit(1);
32
+ }
33
+
34
+ function parseArgs(argv) {
35
+ const opts = { json: false, pages: null, output: null, file: null, command: "extract" };
36
+ let i = 0;
37
+
38
+ // Check for subcommand
39
+ if (argv[0] === "detect") {
40
+ opts.command = "detect";
41
+ i = 1;
42
+ }
43
+
44
+ while (i < argv.length) {
45
+ const arg = argv[i];
46
+ if (arg === "-h" || arg === "--help") {
47
+ process.stdout.write(HELP + "\n");
48
+ process.exit(0);
49
+ } else if (arg === "-v" || arg === "--version") {
50
+ process.stdout.write(`${version}\n`);
51
+ process.exit(0);
52
+ } else if (arg === "--json") {
53
+ opts.json = true;
54
+ } else if (arg === "--pages") {
55
+ i++;
56
+ if (!argv[i]) die("--pages requires a value (e.g. 1,3,5)");
57
+ opts.pages = argv[i].split(",").map((p) => {
58
+ const n = parseInt(p.trim(), 10);
59
+ if (Number.isNaN(n) || n < 1) die(`invalid page number: ${p}`);
60
+ return n;
61
+ });
62
+ } else if (arg === "-o" || arg === "--output") {
63
+ i++;
64
+ if (!argv[i]) die("-o requires a filename");
65
+ opts.output = argv[i];
66
+ } else if (arg === "-" || !arg.startsWith("-")) {
67
+ if (opts.file) die(`unexpected argument: ${arg}`);
68
+ opts.file = arg;
69
+ } else {
70
+ die(`unknown option: ${arg}`);
71
+ }
72
+ i++;
73
+ }
74
+
75
+ return opts;
76
+ }
77
+
78
+ function readInput(file) {
79
+ if (file === "-") {
80
+ return readFileSync(0); // stdin fd
81
+ }
82
+ try {
83
+ return readFileSync(file);
84
+ } catch (err) {
85
+ if (err.code === "ENOENT") die(`file not found: ${file}`);
86
+ die(err.message);
87
+ }
88
+ }
89
+
90
+ function output(text, outputPath) {
91
+ if (outputPath) {
92
+ writeFileSync(outputPath, text);
93
+ } else {
94
+ process.stdout.write(text);
95
+ }
96
+ }
97
+
98
+ // ---- main ----
99
+
100
+ const opts = parseArgs(process.argv.slice(2));
101
+
102
+ if (!opts.file) {
103
+ // Check if stdin is piped
104
+ if (process.stdin.isTTY !== false) {
105
+ process.stderr.write(HELP + "\n");
106
+ process.exit(1);
107
+ }
108
+ opts.file = "-";
109
+ }
110
+
111
+ const { processPdf, classifyPdf } = await import("../index.js");
112
+ const buffer = readInput(opts.file);
113
+
114
+ if (opts.command === "detect") {
115
+ const result = classifyPdf(buffer);
116
+ if (opts.json) {
117
+ output(JSON.stringify(result, null, 2) + "\n", opts.output);
118
+ } else {
119
+ const ocr = result.pagesNeedingOcr.length > 0
120
+ ? `, ${result.pagesNeedingOcr.length} pages need OCR`
121
+ : "";
122
+ output(`${result.pdfType} (${result.pageCount} pages, confidence: ${result.confidence.toFixed(2)}${ocr})\n`, opts.output);
123
+ }
124
+ } else {
125
+ const result = processPdf(buffer, opts.pages ?? undefined);
126
+ if (opts.json) {
127
+ output(JSON.stringify(result, null, 2) + "\n", opts.output);
128
+ } else {
129
+ output((result.markdown ?? "") + "\n", opts.output);
130
+ }
131
+ }
package/index.d.ts ADDED
@@ -0,0 +1,108 @@
1
+ /* auto-generated by NAPI-RS */
2
+ /* eslint-disable */
3
+ /**
4
+ * Lightweight PDF classification — returns type, page count, and OCR pages.
5
+ * Faster than detectPdf as it skips building the full PdfResult.
6
+ * Pages in pagesNeedingOcr are 0-indexed.
7
+ */
8
+ export declare function classifyPdf(buffer: Buffer): PdfClassification
9
+
10
+ /** Fast detection only — no text extraction or markdown. */
11
+ export declare function detectPdf(buffer: Buffer): PdfResult
12
+
13
+ /**
14
+ * Extract markdown tables within bounding-box regions from a PDF.
15
+ *
16
+ * Like `extractTextInRegions` but runs table detection on items within each
17
+ * region and returns markdown pipe-tables instead of flat text.
18
+ *
19
+ * When table structure is detected, `text` contains a markdown pipe-table and
20
+ * `needsOcr` is `false`. When no table is found, `text` is empty and
21
+ * `needsOcr` is `true` so the caller can fall back to GPU OCR.
22
+ *
23
+ * Coordinates are PDF points with top-left origin.
24
+ */
25
+ export declare function extractTablesInRegions(buffer: Buffer, pageRegions: Array<PageRegions>): Array<PageRegionTexts>
26
+
27
+ /** Extract plain text from a PDF Buffer. */
28
+ export declare function extractText(buffer: Buffer): string
29
+
30
+ /**
31
+ * Extract text within bounding-box regions from a PDF.
32
+ *
33
+ * For hybrid OCR: layout model detects regions in rendered images,
34
+ * this extracts PDF text within those regions — skipping GPU OCR
35
+ * for text-based pages.
36
+ *
37
+ * Each region result includes `needsOcr` — set when the extracted text
38
+ * is unreliable (empty, GID-encoded fonts, garbage, encoding issues).
39
+ *
40
+ * Coordinates are PDF points with top-left origin.
41
+ */
42
+ export declare function extractTextInRegions(buffer: Buffer, pageRegions: Array<PageRegions>): Array<PageRegionTexts>
43
+
44
+ /** Extract text with position information from a PDF Buffer. */
45
+ export declare function extractTextWithPositions(buffer: Buffer, pages?: Array<number> | undefined | null): Array<TextItem>
46
+
47
+ /** A page's regions for text extraction: (page_index_0based, bboxes). */
48
+ export interface PageRegions {
49
+ page: number
50
+ /** Each bbox is [x1, y1, x2, y2] in PDF points, top-left origin. */
51
+ regions: Array<Array<number>>
52
+ }
53
+
54
+ /** Extracted text for one page's regions. */
55
+ export interface PageRegionTexts {
56
+ page: number
57
+ regions: Array<RegionText>
58
+ }
59
+
60
+ /** Lightweight PDF classification result. */
61
+ export interface PdfClassification {
62
+ pdfType: string
63
+ pageCount: number
64
+ /** 0-indexed page numbers that need OCR. */
65
+ pagesNeedingOcr: Array<number>
66
+ confidence: number
67
+ }
68
+
69
+ /** Full PDF processing result with markdown and metadata. */
70
+ export interface PdfResult {
71
+ pdfType: string
72
+ markdown?: string
73
+ pageCount: number
74
+ processingTimeMs: number
75
+ /** 1-indexed page numbers that need OCR. */
76
+ pagesNeedingOcr: Array<number>
77
+ title?: string
78
+ confidence: number
79
+ isComplexLayout: boolean
80
+ pagesWithTables: Array<number>
81
+ pagesWithColumns: Array<number>
82
+ hasEncodingIssues: boolean
83
+ }
84
+
85
+ /** Process a PDF from a Buffer: detect type, extract text, and convert to Markdown. */
86
+ export declare function processPdf(buffer: Buffer, pages?: Array<number> | undefined | null): PdfResult
87
+
88
+ /** Extracted text for a single region. */
89
+ export interface RegionText {
90
+ text: string
91
+ /** `true` when the text should not be trusted (empty, GID fonts, garbage, encoding issues). */
92
+ needsOcr: boolean
93
+ }
94
+
95
+ /** A positioned text item extracted from a PDF. */
96
+ export interface TextItem {
97
+ text: string
98
+ x: number
99
+ y: number
100
+ width: number
101
+ height: number
102
+ font: string
103
+ fontSize: number
104
+ page: number
105
+ isBold: boolean
106
+ isItalic: boolean
107
+ itemType: string
108
+ }
package/index.js ADDED
@@ -0,0 +1,585 @@
1
+ // prettier-ignore
2
+ /* eslint-disable */
3
+ // @ts-nocheck
4
+ /* auto-generated by NAPI-RS */
5
+
6
+ const { readFileSync } = require('node:fs')
7
+ let nativeBinding = null
8
+ const loadErrors = []
9
+
10
+ const isMusl = () => {
11
+ let musl = false
12
+ if (process.platform === 'linux') {
13
+ musl = isMuslFromFilesystem()
14
+ if (musl === null) {
15
+ musl = isMuslFromReport()
16
+ }
17
+ if (musl === null) {
18
+ musl = isMuslFromChildProcess()
19
+ }
20
+ }
21
+ return musl
22
+ }
23
+
24
+ const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')
25
+
26
+ const isMuslFromFilesystem = () => {
27
+ try {
28
+ return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
29
+ } catch {
30
+ return null
31
+ }
32
+ }
33
+
34
+ const isMuslFromReport = () => {
35
+ let report = null
36
+ if (typeof process.report?.getReport === 'function') {
37
+ process.report.excludeNetwork = true
38
+ report = process.report.getReport()
39
+ }
40
+ if (!report) {
41
+ return null
42
+ }
43
+ if (report.header && report.header.glibcVersionRuntime) {
44
+ return false
45
+ }
46
+ if (Array.isArray(report.sharedObjects)) {
47
+ if (report.sharedObjects.some(isFileMusl)) {
48
+ return true
49
+ }
50
+ }
51
+ return false
52
+ }
53
+
54
+ const isMuslFromChildProcess = () => {
55
+ try {
56
+ return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl')
57
+ } catch (e) {
58
+ // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
59
+ return false
60
+ }
61
+ }
62
+
63
+ function requireNative() {
64
+ if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) {
65
+ try {
66
+ return require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH);
67
+ } catch (err) {
68
+ loadErrors.push(err)
69
+ }
70
+ } else if (process.platform === 'android') {
71
+ if (process.arch === 'arm64') {
72
+ try {
73
+ return require('./pdf-inspector.android-arm64.node')
74
+ } catch (e) {
75
+ loadErrors.push(e)
76
+ }
77
+ try {
78
+ const binding = require('firecrawl-pdf-inspector-android-arm64')
79
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-android-arm64/package.json').version
80
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
81
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
82
+ }
83
+ return binding
84
+ } catch (e) {
85
+ loadErrors.push(e)
86
+ }
87
+ } else if (process.arch === 'arm') {
88
+ try {
89
+ return require('./pdf-inspector.android-arm-eabi.node')
90
+ } catch (e) {
91
+ loadErrors.push(e)
92
+ }
93
+ try {
94
+ const binding = require('firecrawl-pdf-inspector-android-arm-eabi')
95
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-android-arm-eabi/package.json').version
96
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
97
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
98
+ }
99
+ return binding
100
+ } catch (e) {
101
+ loadErrors.push(e)
102
+ }
103
+ } else {
104
+ loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`))
105
+ }
106
+ } else if (process.platform === 'win32') {
107
+ if (process.arch === 'x64') {
108
+ if (process.config?.variables?.shlib_suffix === 'dll.a' || process.config?.variables?.node_target_type === 'shared_library') {
109
+ try {
110
+ return require('./pdf-inspector.win32-x64-gnu.node')
111
+ } catch (e) {
112
+ loadErrors.push(e)
113
+ }
114
+ try {
115
+ const binding = require('firecrawl-pdf-inspector-win32-x64-gnu')
116
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-win32-x64-gnu/package.json').version
117
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
118
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
119
+ }
120
+ return binding
121
+ } catch (e) {
122
+ loadErrors.push(e)
123
+ }
124
+ } else {
125
+ try {
126
+ return require('./pdf-inspector.win32-x64-msvc.node')
127
+ } catch (e) {
128
+ loadErrors.push(e)
129
+ }
130
+ try {
131
+ const binding = require('firecrawl-pdf-inspector-win32-x64-msvc')
132
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-win32-x64-msvc/package.json').version
133
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
134
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
135
+ }
136
+ return binding
137
+ } catch (e) {
138
+ loadErrors.push(e)
139
+ }
140
+ }
141
+ } else if (process.arch === 'ia32') {
142
+ try {
143
+ return require('./pdf-inspector.win32-ia32-msvc.node')
144
+ } catch (e) {
145
+ loadErrors.push(e)
146
+ }
147
+ try {
148
+ const binding = require('firecrawl-pdf-inspector-win32-ia32-msvc')
149
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-win32-ia32-msvc/package.json').version
150
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
151
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
152
+ }
153
+ return binding
154
+ } catch (e) {
155
+ loadErrors.push(e)
156
+ }
157
+ } else if (process.arch === 'arm64') {
158
+ try {
159
+ return require('./pdf-inspector.win32-arm64-msvc.node')
160
+ } catch (e) {
161
+ loadErrors.push(e)
162
+ }
163
+ try {
164
+ const binding = require('firecrawl-pdf-inspector-win32-arm64-msvc')
165
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-win32-arm64-msvc/package.json').version
166
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
167
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
168
+ }
169
+ return binding
170
+ } catch (e) {
171
+ loadErrors.push(e)
172
+ }
173
+ } else {
174
+ loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`))
175
+ }
176
+ } else if (process.platform === 'darwin') {
177
+ try {
178
+ return require('./pdf-inspector.darwin-universal.node')
179
+ } catch (e) {
180
+ loadErrors.push(e)
181
+ }
182
+ try {
183
+ const binding = require('firecrawl-pdf-inspector-darwin-universal')
184
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-darwin-universal/package.json').version
185
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
186
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
187
+ }
188
+ return binding
189
+ } catch (e) {
190
+ loadErrors.push(e)
191
+ }
192
+ if (process.arch === 'x64') {
193
+ try {
194
+ return require('./pdf-inspector.darwin-x64.node')
195
+ } catch (e) {
196
+ loadErrors.push(e)
197
+ }
198
+ try {
199
+ const binding = require('firecrawl-pdf-inspector-darwin-x64')
200
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-darwin-x64/package.json').version
201
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
202
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
203
+ }
204
+ return binding
205
+ } catch (e) {
206
+ loadErrors.push(e)
207
+ }
208
+ } else if (process.arch === 'arm64') {
209
+ try {
210
+ return require('./pdf-inspector.darwin-arm64.node')
211
+ } catch (e) {
212
+ loadErrors.push(e)
213
+ }
214
+ try {
215
+ const binding = require('firecrawl-pdf-inspector-darwin-arm64')
216
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-darwin-arm64/package.json').version
217
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
218
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
219
+ }
220
+ return binding
221
+ } catch (e) {
222
+ loadErrors.push(e)
223
+ }
224
+ } else {
225
+ loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`))
226
+ }
227
+ } else if (process.platform === 'freebsd') {
228
+ if (process.arch === 'x64') {
229
+ try {
230
+ return require('./pdf-inspector.freebsd-x64.node')
231
+ } catch (e) {
232
+ loadErrors.push(e)
233
+ }
234
+ try {
235
+ const binding = require('firecrawl-pdf-inspector-freebsd-x64')
236
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-freebsd-x64/package.json').version
237
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
238
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
239
+ }
240
+ return binding
241
+ } catch (e) {
242
+ loadErrors.push(e)
243
+ }
244
+ } else if (process.arch === 'arm64') {
245
+ try {
246
+ return require('./pdf-inspector.freebsd-arm64.node')
247
+ } catch (e) {
248
+ loadErrors.push(e)
249
+ }
250
+ try {
251
+ const binding = require('firecrawl-pdf-inspector-freebsd-arm64')
252
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-freebsd-arm64/package.json').version
253
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
254
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
255
+ }
256
+ return binding
257
+ } catch (e) {
258
+ loadErrors.push(e)
259
+ }
260
+ } else {
261
+ loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`))
262
+ }
263
+ } else if (process.platform === 'linux') {
264
+ if (process.arch === 'x64') {
265
+ if (isMusl()) {
266
+ try {
267
+ return require('./pdf-inspector.linux-x64-musl.node')
268
+ } catch (e) {
269
+ loadErrors.push(e)
270
+ }
271
+ try {
272
+ const binding = require('firecrawl-pdf-inspector-linux-x64-musl')
273
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-linux-x64-musl/package.json').version
274
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
275
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
276
+ }
277
+ return binding
278
+ } catch (e) {
279
+ loadErrors.push(e)
280
+ }
281
+ } else {
282
+ try {
283
+ return require('./pdf-inspector.linux-x64-gnu.node')
284
+ } catch (e) {
285
+ loadErrors.push(e)
286
+ }
287
+ try {
288
+ const binding = require('firecrawl-pdf-inspector-linux-x64-gnu')
289
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-linux-x64-gnu/package.json').version
290
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
291
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
292
+ }
293
+ return binding
294
+ } catch (e) {
295
+ loadErrors.push(e)
296
+ }
297
+ }
298
+ } else if (process.arch === 'arm64') {
299
+ if (isMusl()) {
300
+ try {
301
+ return require('./pdf-inspector.linux-arm64-musl.node')
302
+ } catch (e) {
303
+ loadErrors.push(e)
304
+ }
305
+ try {
306
+ const binding = require('firecrawl-pdf-inspector-linux-arm64-musl')
307
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-linux-arm64-musl/package.json').version
308
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
309
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
310
+ }
311
+ return binding
312
+ } catch (e) {
313
+ loadErrors.push(e)
314
+ }
315
+ } else {
316
+ try {
317
+ return require('./pdf-inspector.linux-arm64-gnu.node')
318
+ } catch (e) {
319
+ loadErrors.push(e)
320
+ }
321
+ try {
322
+ const binding = require('firecrawl-pdf-inspector-linux-arm64-gnu')
323
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-linux-arm64-gnu/package.json').version
324
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
325
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
326
+ }
327
+ return binding
328
+ } catch (e) {
329
+ loadErrors.push(e)
330
+ }
331
+ }
332
+ } else if (process.arch === 'arm') {
333
+ if (isMusl()) {
334
+ try {
335
+ return require('./pdf-inspector.linux-arm-musleabihf.node')
336
+ } catch (e) {
337
+ loadErrors.push(e)
338
+ }
339
+ try {
340
+ const binding = require('firecrawl-pdf-inspector-linux-arm-musleabihf')
341
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-linux-arm-musleabihf/package.json').version
342
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
343
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
344
+ }
345
+ return binding
346
+ } catch (e) {
347
+ loadErrors.push(e)
348
+ }
349
+ } else {
350
+ try {
351
+ return require('./pdf-inspector.linux-arm-gnueabihf.node')
352
+ } catch (e) {
353
+ loadErrors.push(e)
354
+ }
355
+ try {
356
+ const binding = require('firecrawl-pdf-inspector-linux-arm-gnueabihf')
357
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-linux-arm-gnueabihf/package.json').version
358
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
359
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
360
+ }
361
+ return binding
362
+ } catch (e) {
363
+ loadErrors.push(e)
364
+ }
365
+ }
366
+ } else if (process.arch === 'loong64') {
367
+ if (isMusl()) {
368
+ try {
369
+ return require('./pdf-inspector.linux-loong64-musl.node')
370
+ } catch (e) {
371
+ loadErrors.push(e)
372
+ }
373
+ try {
374
+ const binding = require('firecrawl-pdf-inspector-linux-loong64-musl')
375
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-linux-loong64-musl/package.json').version
376
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
377
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
378
+ }
379
+ return binding
380
+ } catch (e) {
381
+ loadErrors.push(e)
382
+ }
383
+ } else {
384
+ try {
385
+ return require('./pdf-inspector.linux-loong64-gnu.node')
386
+ } catch (e) {
387
+ loadErrors.push(e)
388
+ }
389
+ try {
390
+ const binding = require('firecrawl-pdf-inspector-linux-loong64-gnu')
391
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-linux-loong64-gnu/package.json').version
392
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
393
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
394
+ }
395
+ return binding
396
+ } catch (e) {
397
+ loadErrors.push(e)
398
+ }
399
+ }
400
+ } else if (process.arch === 'riscv64') {
401
+ if (isMusl()) {
402
+ try {
403
+ return require('./pdf-inspector.linux-riscv64-musl.node')
404
+ } catch (e) {
405
+ loadErrors.push(e)
406
+ }
407
+ try {
408
+ const binding = require('firecrawl-pdf-inspector-linux-riscv64-musl')
409
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-linux-riscv64-musl/package.json').version
410
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
411
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
412
+ }
413
+ return binding
414
+ } catch (e) {
415
+ loadErrors.push(e)
416
+ }
417
+ } else {
418
+ try {
419
+ return require('./pdf-inspector.linux-riscv64-gnu.node')
420
+ } catch (e) {
421
+ loadErrors.push(e)
422
+ }
423
+ try {
424
+ const binding = require('firecrawl-pdf-inspector-linux-riscv64-gnu')
425
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-linux-riscv64-gnu/package.json').version
426
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
427
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
428
+ }
429
+ return binding
430
+ } catch (e) {
431
+ loadErrors.push(e)
432
+ }
433
+ }
434
+ } else if (process.arch === 'ppc64') {
435
+ try {
436
+ return require('./pdf-inspector.linux-ppc64-gnu.node')
437
+ } catch (e) {
438
+ loadErrors.push(e)
439
+ }
440
+ try {
441
+ const binding = require('firecrawl-pdf-inspector-linux-ppc64-gnu')
442
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-linux-ppc64-gnu/package.json').version
443
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
444
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
445
+ }
446
+ return binding
447
+ } catch (e) {
448
+ loadErrors.push(e)
449
+ }
450
+ } else if (process.arch === 's390x') {
451
+ try {
452
+ return require('./pdf-inspector.linux-s390x-gnu.node')
453
+ } catch (e) {
454
+ loadErrors.push(e)
455
+ }
456
+ try {
457
+ const binding = require('firecrawl-pdf-inspector-linux-s390x-gnu')
458
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-linux-s390x-gnu/package.json').version
459
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
460
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
461
+ }
462
+ return binding
463
+ } catch (e) {
464
+ loadErrors.push(e)
465
+ }
466
+ } else {
467
+ loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`))
468
+ }
469
+ } else if (process.platform === 'openharmony') {
470
+ if (process.arch === 'arm64') {
471
+ try {
472
+ return require('./pdf-inspector.openharmony-arm64.node')
473
+ } catch (e) {
474
+ loadErrors.push(e)
475
+ }
476
+ try {
477
+ const binding = require('firecrawl-pdf-inspector-openharmony-arm64')
478
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-openharmony-arm64/package.json').version
479
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
480
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
481
+ }
482
+ return binding
483
+ } catch (e) {
484
+ loadErrors.push(e)
485
+ }
486
+ } else if (process.arch === 'x64') {
487
+ try {
488
+ return require('./pdf-inspector.openharmony-x64.node')
489
+ } catch (e) {
490
+ loadErrors.push(e)
491
+ }
492
+ try {
493
+ const binding = require('firecrawl-pdf-inspector-openharmony-x64')
494
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-openharmony-x64/package.json').version
495
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
496
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
497
+ }
498
+ return binding
499
+ } catch (e) {
500
+ loadErrors.push(e)
501
+ }
502
+ } else if (process.arch === 'arm') {
503
+ try {
504
+ return require('./pdf-inspector.openharmony-arm.node')
505
+ } catch (e) {
506
+ loadErrors.push(e)
507
+ }
508
+ try {
509
+ const binding = require('firecrawl-pdf-inspector-openharmony-arm')
510
+ const bindingPackageVersion = require('firecrawl-pdf-inspector-openharmony-arm/package.json').version
511
+ if (bindingPackageVersion !== '0.4.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
512
+ throw new Error(`Native binding package version mismatch, expected 0.4.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
513
+ }
514
+ return binding
515
+ } catch (e) {
516
+ loadErrors.push(e)
517
+ }
518
+ } else {
519
+ loadErrors.push(new Error(`Unsupported architecture on OpenHarmony: ${process.arch}`))
520
+ }
521
+ } else {
522
+ loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`))
523
+ }
524
+ }
525
+
526
+ nativeBinding = requireNative()
527
+
528
+ if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
529
+ let wasiBinding = null
530
+ let wasiBindingError = null
531
+ try {
532
+ wasiBinding = require('./pdf-inspector.wasi.cjs')
533
+ nativeBinding = wasiBinding
534
+ } catch (err) {
535
+ if (process.env.NAPI_RS_FORCE_WASI) {
536
+ wasiBindingError = err
537
+ }
538
+ }
539
+ if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
540
+ try {
541
+ wasiBinding = require('firecrawl-pdf-inspector-wasm32-wasi')
542
+ nativeBinding = wasiBinding
543
+ } catch (err) {
544
+ if (process.env.NAPI_RS_FORCE_WASI) {
545
+ if (!wasiBindingError) {
546
+ wasiBindingError = err
547
+ } else {
548
+ wasiBindingError.cause = err
549
+ }
550
+ loadErrors.push(err)
551
+ }
552
+ }
553
+ }
554
+ if (process.env.NAPI_RS_FORCE_WASI === 'error' && !wasiBinding) {
555
+ const error = new Error('WASI binding not found and NAPI_RS_FORCE_WASI is set to error')
556
+ error.cause = wasiBindingError
557
+ throw error
558
+ }
559
+ }
560
+
561
+ if (!nativeBinding) {
562
+ if (loadErrors.length > 0) {
563
+ throw new Error(
564
+ `Cannot find native binding. ` +
565
+ `npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` +
566
+ 'Please try `npm i` again after removing both package-lock.json and node_modules directory.',
567
+ {
568
+ cause: loadErrors.reduce((err, cur) => {
569
+ cur.cause = err
570
+ return cur
571
+ }),
572
+ },
573
+ )
574
+ }
575
+ throw new Error(`Failed to load native binding`)
576
+ }
577
+
578
+ module.exports = nativeBinding
579
+ module.exports.classifyPdf = nativeBinding.classifyPdf
580
+ module.exports.detectPdf = nativeBinding.detectPdf
581
+ module.exports.extractTablesInRegions = nativeBinding.extractTablesInRegions
582
+ module.exports.extractText = nativeBinding.extractText
583
+ module.exports.extractTextInRegions = nativeBinding.extractTextInRegions
584
+ module.exports.extractTextWithPositions = nativeBinding.extractTextWithPositions
585
+ module.exports.processPdf = nativeBinding.processPdf
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@firecrawl/pdf-inspector",
3
+ "version": "1.0.0",
4
+ "description": "Fast PDF classification and text extraction. Detect text-based vs scanned PDFs, extract text by region with quality checks. Native Rust performance via napi-rs.",
5
+ "main": "index.js",
6
+ "types": "index.d.ts",
7
+ "bin": {
8
+ "pdf-inspector": "bin/pdf-inspector.mjs"
9
+ },
10
+ "license": "MIT",
11
+ "keywords": [
12
+ "pdf",
13
+ "pdf-extraction",
14
+ "pdf-parser",
15
+ "text-extraction",
16
+ "ocr",
17
+ "pdf-classification",
18
+ "napi",
19
+ "rust",
20
+ "firecrawl"
21
+ ],
22
+ "files": [
23
+ "index.js",
24
+ "index.d.ts",
25
+ "*.node",
26
+ "bin/",
27
+ "README.md"
28
+ ],
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/firecrawl/pdf-inspector"
32
+ },
33
+ "homepage": "https://github.com/firecrawl/pdf-inspector",
34
+ "publishConfig": {
35
+ "access": "public"
36
+ },
37
+ "napi": {
38
+ "binaryName": "pdf-inspector",
39
+ "targets": [
40
+ "x86_64-unknown-linux-gnu",
41
+ "aarch64-apple-darwin"
42
+ ],
43
+ "package": {
44
+ "name": "@firecrawl/pdf-inspector-js"
45
+ }
46
+ },
47
+ "scripts": {
48
+ "build": "napi build --platform --release",
49
+ "build:debug": "napi build --platform"
50
+ },
51
+ "devDependencies": {
52
+ "@napi-rs/cli": "^3.4.1"
53
+ }
54
+ }
Binary file