@backendkit-labs/document-extract 0.0.0-stage → 0.1.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.
@@ -0,0 +1,259 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.extractDocument = extractDocument;
37
+ const errors_1 = require("./errors");
38
+ const zip_1 = require("./zip");
39
+ const ocr_1 = require("./ocr");
40
+ const types_1 = require("./types");
41
+ /** Fewer visible characters than this in a whole PDF means there is no text layer (a scan), not a short document. */
42
+ const MIN_TEXT_CHARS = 10;
43
+ /**
44
+ * Turns the bytes of a PDF, Word (.docx), Excel (.xlsx), CSV or text file into text. The format comes from the bytes, never
45
+ * from the name. Nothing is interpreted: the result is the content, for whoever reads it to make sense of.
46
+ */
47
+ async function extractDocument(input, options = {}) {
48
+ const limits = { ...types_1.DEFAULT_LIMITS, ...options.limits };
49
+ if (input.byteLength > limits.maxBytes)
50
+ throw new errors_1.DocumentExtractError('TOO_LARGE', `${input.byteLength} bytes, limit ${limits.maxBytes}`);
51
+ if (input.byteLength === 0)
52
+ throw new errors_1.DocumentExtractError('CORRUPT', 'empty file');
53
+ if (options.signal?.aborted)
54
+ throw new errors_1.DocumentExtractError('TIMEOUT'); // before any work starts: nothing is left running
55
+ const format = detect(input, limits, options.filename);
56
+ const ocr = options.ocr ? (options.ocr === true ? {} : options.ocr) : undefined;
57
+ const work = (async () => {
58
+ switch (format) {
59
+ case 'pdf': return fromPdf(input, limits, ocr, options.signal);
60
+ case 'image': return fromImage(input, ocr, options.signal);
61
+ case 'docx': return fromDocx(input);
62
+ case 'xlsx': return fromXlsx(input, limits);
63
+ default: return fromText(input, format);
64
+ }
65
+ })();
66
+ const body = await withAbort(work, options.signal);
67
+ const cut = body.text.length > limits.maxChars;
68
+ return {
69
+ format,
70
+ text: cut ? body.text.slice(0, limits.maxChars) : body.text,
71
+ bytes: input.byteLength,
72
+ ...(body.pages !== undefined ? { pages: body.pages } : {}),
73
+ hasTextLayer: !body.ocr,
74
+ ...(body.ocr ? { ocr: body.ocr } : {}),
75
+ truncated: cut || !!body.truncated,
76
+ };
77
+ }
78
+ function detect(bytes, limits, filename) {
79
+ // The PDF header opens the file (after an optional BOM or blank space); a text file that merely mentions it is text.
80
+ const start = Buffer.from(bytes.subarray(0, 64)).toString('latin1').replace(/^(\xEF\xBB\xBF|\s)+/, '');
81
+ if (/^%PDF-\d/.test(start))
82
+ return 'pdf';
83
+ if (bytes[0] === 0x50 && bytes[1] === 0x4b && bytes[2] === 0x03 && bytes[3] === 0x04) {
84
+ const { names } = (0, zip_1.listZip)(bytes, limits.maxEntries, limits.maxUncompressedBytes);
85
+ if (names.includes('word/document.xml'))
86
+ return 'docx';
87
+ if (names.includes('xl/workbook.xml'))
88
+ return 'xlsx';
89
+ throw new errors_1.DocumentExtractError('UNSUPPORTED_FORMAT', 'a ZIP that is neither Word nor Excel');
90
+ }
91
+ if (bytes[0] === 0xd0 && bytes[1] === 0xcf && bytes[2] === 0x11 && bytes[3] === 0xe0) {
92
+ throw new errors_1.DocumentExtractError('UNSUPPORTED_FORMAT', 'legacy Office (.doc/.xls) or a password-protected Office file');
93
+ }
94
+ if ((0, ocr_1.imageKind)(bytes))
95
+ return 'image';
96
+ if (bytes.subarray(0, 8000).includes(0))
97
+ throw new errors_1.DocumentExtractError('UNSUPPORTED_FORMAT', 'binary content of an unknown kind');
98
+ return filename && /\.csv$/i.test(filename) ? 'csv' : 'text';
99
+ }
100
+ function fromText(bytes, format) {
101
+ try {
102
+ return { text: new TextDecoder('utf-8', { fatal: true }).decode(bytes).replace(/^/, '') };
103
+ }
104
+ catch {
105
+ throw new errors_1.DocumentExtractError('UNSUPPORTED_FORMAT', `${format} that is not UTF-8`);
106
+ }
107
+ }
108
+ /** An image is only readable with OCR; without it the answer is the same as for a scan: there is no text to extract. */
109
+ async function fromImage(bytes, ocr, signal) {
110
+ if (!ocr)
111
+ throw new errors_1.DocumentExtractError('NO_TEXT_LAYER', 'an image has no text and OCR is not enabled');
112
+ const { text, confidence } = await (0, ocr_1.ocrImage)(Buffer.from(bytes), ocr, signal);
113
+ if (!text)
114
+ throw new errors_1.DocumentExtractError('NO_TEXT_LAYER', 'OCR found no text in the image');
115
+ return { text, ocr: { confidence: Math.round(confidence), images: 1 } };
116
+ }
117
+ /** Largest images are the page scans; tiny ones (logos, rules, masks) are not worth reading. */
118
+ const MIN_SCAN_SIDE = 100;
119
+ const MAX_IMAGES_PER_PAGE = 20;
120
+ async function ocrPdfPages(pdf, ocr, signal) {
121
+ const { extractImages } = await Promise.resolve().then(() => __importStar(require('unpdf')));
122
+ const maxPages = ocr.maxPages ?? ocr_1.DEFAULT_OCR.maxPages;
123
+ const out = [];
124
+ let images = 0;
125
+ let confidenceSum = 0;
126
+ const pages = Math.min(pdf.numPages, maxPages);
127
+ const minSide = ocr.minImageSide ?? MIN_SCAN_SIDE;
128
+ let renderMissing = false;
129
+ for (let p = 1; p <= pages; p++) {
130
+ const found = (await extractImages(pdf, p)).filter(i => i.width >= minSide && i.height >= minSide).slice(0, MAX_IMAGES_PER_PAGE);
131
+ // A real scan is a picture per page; some PDFs (e.g. "Print to PDF" of bitmap text) draw the page as hundreds of tiny
132
+ // pieces or as vectors. Those can only be read by drawing the page, which needs the optional @napi-rs/canvas.
133
+ const pictures = found.map(i => (0, ocr_1.encodePng)(i.width, i.height, i.channels, i.data));
134
+ if (!pictures.length) {
135
+ const drawn = await renderPage(pdf, p, ocr.renderScale ?? 2);
136
+ if (drawn)
137
+ pictures.push(drawn);
138
+ else
139
+ renderMissing = true;
140
+ }
141
+ const parts = [];
142
+ for (const picture of pictures) {
143
+ const r = await (0, ocr_1.ocrImage)(picture, ocr, signal);
144
+ images++;
145
+ confidenceSum += r.confidence;
146
+ if (r.text)
147
+ parts.push(r.text);
148
+ }
149
+ out.push(`--- page ${p} ---\n${parts.join('\n')}`);
150
+ }
151
+ if (out.every(page => page.replace(/^--- page \d+ ---\s*/, '') === '')) {
152
+ if (renderMissing)
153
+ throw new errors_1.DocumentExtractError('OCR_UNAVAILABLE', 'this PDF draws its pages without one picture per page; reading it needs @napi-rs/canvas to draw them');
154
+ throw new errors_1.DocumentExtractError('NO_TEXT_LAYER', 'OCR found no text in the scanned pages');
155
+ }
156
+ return { text: out.join('\n\n'), pages: pdf.numPages, truncated: pdf.numPages > pages, ocr: { confidence: images ? Math.round(confidenceSum / images) : 0, images } };
157
+ }
158
+ /** The page drawn as a PNG, or undefined when the optional canvas package is not installed. */
159
+ async function renderPage(pdf, page, scale) {
160
+ const { renderPageAsImage } = await Promise.resolve().then(() => __importStar(require('unpdf')));
161
+ try {
162
+ await Promise.resolve().then(() => __importStar(require('@napi-rs/canvas')));
163
+ }
164
+ catch {
165
+ return undefined;
166
+ }
167
+ return Buffer.from(await renderPageAsImage(pdf, page, { canvasImport: () => Promise.resolve().then(() => __importStar(require('@napi-rs/canvas'))), scale }));
168
+ }
169
+ async function fromPdf(bytes, limits, ocr, signal) {
170
+ const { getDocumentProxy, extractText } = await Promise.resolve().then(() => __importStar(require('unpdf')));
171
+ let pdf;
172
+ try {
173
+ pdf = await getDocumentProxy(new Uint8Array(bytes)); // a copy: the library takes ownership of the buffer it is given
174
+ }
175
+ catch (err) {
176
+ throw pdfError(err);
177
+ }
178
+ try {
179
+ if (pdf.numPages > limits.maxPages)
180
+ throw new errors_1.DocumentExtractError('TOO_MANY_PAGES', `${pdf.numPages} pages, limit ${limits.maxPages}`);
181
+ const { text } = await extractText(pdf, { mergePages: false });
182
+ const pages = text;
183
+ if (pages.join('').replace(/\s/g, '').length < MIN_TEXT_CHARS) {
184
+ if (ocr)
185
+ return await ocrPdfPages(pdf, ocr, signal); // a scan: read the page images
186
+ throw new errors_1.DocumentExtractError('NO_TEXT_LAYER');
187
+ }
188
+ return { text: pages.map((t, i) => `--- page ${i + 1} ---\n${t.trim()}`).join('\n\n'), pages: pdf.numPages };
189
+ }
190
+ catch (err) {
191
+ throw err instanceof errors_1.DocumentExtractError ? err : pdfError(err);
192
+ }
193
+ finally {
194
+ await pdf.destroy?.().catch(() => undefined);
195
+ }
196
+ }
197
+ function pdfError(err) {
198
+ const name = err?.name;
199
+ if (name === 'PasswordException')
200
+ return new errors_1.DocumentExtractError('ENCRYPTED');
201
+ return new errors_1.DocumentExtractError('CORRUPT', `the PDF could not be read (${name ?? 'error'}: ${err?.message ?? ''})`.slice(0, 200));
202
+ }
203
+ async function fromDocx(bytes) {
204
+ const mammoth = await Promise.resolve().then(() => __importStar(require('mammoth')));
205
+ try {
206
+ const { value } = await mammoth.extractRawText({ buffer: Buffer.from(bytes) });
207
+ return { text: value };
208
+ }
209
+ catch {
210
+ throw new errors_1.DocumentExtractError('CORRUPT', 'the Word file could not be read');
211
+ }
212
+ }
213
+ async function fromXlsx(bytes, limits) {
214
+ const { default: readXlsxFile } = await Promise.resolve().then(() => __importStar(require('read-excel-file/universal')));
215
+ let sheets;
216
+ try {
217
+ const buffer = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
218
+ sheets = (await readXlsxFile(buffer));
219
+ }
220
+ catch {
221
+ throw new errors_1.DocumentExtractError('CORRUPT', 'the Excel file could not be read');
222
+ }
223
+ if (sheets.length > limits.maxPages)
224
+ throw new errors_1.DocumentExtractError('TOO_MANY_PAGES', `${sheets.length} sheets, limit ${limits.maxPages}`);
225
+ const out = [];
226
+ let size = 0;
227
+ for (const { sheet, data } of sheets) {
228
+ out.push(`--- sheet "${sheet}" ---`);
229
+ for (const row of data) {
230
+ const line = row.map(cell).join('\t');
231
+ out.push(line);
232
+ size += line.length + 1;
233
+ if (size > limits.maxChars)
234
+ return { text: out.join('\n'), pages: sheets.length }; // already over the cap: the caller cuts and flags it
235
+ }
236
+ }
237
+ return { text: out.join('\n'), pages: sheets.length };
238
+ }
239
+ function cell(value) {
240
+ if (value === null || value === undefined)
241
+ return '';
242
+ if (value instanceof Date)
243
+ return value.toISOString();
244
+ return String(value).replace(/[\t\r\n]+/g, ' ');
245
+ }
246
+ function withAbort(work, signal) {
247
+ if (!signal)
248
+ return work;
249
+ if (signal.aborted)
250
+ return Promise.reject(new errors_1.DocumentExtractError('TIMEOUT'));
251
+ return new Promise((resolve, reject) => {
252
+ // If the caller stops waiting, the work may still fail later: that failure must not surface as an unhandled rejection.
253
+ work.catch(() => undefined);
254
+ const onAbort = () => reject(new errors_1.DocumentExtractError('TIMEOUT'));
255
+ signal.addEventListener('abort', onAbort, { once: true });
256
+ work.then(resolve, reject).finally(() => signal.removeEventListener('abort', onAbort));
257
+ });
258
+ }
259
+ //# sourceMappingURL=extract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.js","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { extractDocument } from './extract';
2
+ export { DocumentExtractError, type DocumentErrorCode } from './errors';
3
+ export { createReadDocumentTool, type ReadDocumentToolOptions } from './tool';
4
+ export { DEFAULT_LIMITS, type DocumentFormat, type ExtractedDocument, type ExtractLimits, type ExtractOptions } from './types';
5
+ export { terminateOcr, type OcrOptions } from './ocr';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,KAAK,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,KAAK,uBAAuB,EAAE,MAAM,QAAQ,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,iBAAiB,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAC/H,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.terminateOcr = exports.DEFAULT_LIMITS = exports.createReadDocumentTool = exports.DocumentExtractError = exports.extractDocument = void 0;
4
+ var extract_1 = require("./extract");
5
+ Object.defineProperty(exports, "extractDocument", { enumerable: true, get: function () { return extract_1.extractDocument; } });
6
+ var errors_1 = require("./errors");
7
+ Object.defineProperty(exports, "DocumentExtractError", { enumerable: true, get: function () { return errors_1.DocumentExtractError; } });
8
+ var tool_1 = require("./tool");
9
+ Object.defineProperty(exports, "createReadDocumentTool", { enumerable: true, get: function () { return tool_1.createReadDocumentTool; } });
10
+ var types_1 = require("./types");
11
+ Object.defineProperty(exports, "DEFAULT_LIMITS", { enumerable: true, get: function () { return types_1.DEFAULT_LIMITS; } });
12
+ var ocr_1 = require("./ocr");
13
+ Object.defineProperty(exports, "terminateOcr", { enumerable: true, get: function () { return ocr_1.terminateOcr; } });
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,qCAA4C;AAAnC,0GAAA,eAAe,OAAA;AACxB,mCAAwE;AAA/D,8GAAA,oBAAoB,OAAA;AAC7B,+BAA8E;AAArE,8GAAA,sBAAsB,OAAA;AAC/B,iCAA+H;AAAtH,uGAAA,cAAc,OAAA;AACvB,6BAAsD;AAA7C,mGAAA,YAAY,OAAA"}
package/dist/ocr.d.ts ADDED
@@ -0,0 +1,41 @@
1
+ /**
2
+ * OCR runs on tesseract.js, loaded only when OCR is asked for. It never downloads anything: the engine and the language
3
+ * data come from installed packages (`tesseract.js`, `@tesseract.js-data/<lang>`) or from paths the host gives. If they
4
+ * are not there the call fails with OCR_UNAVAILABLE instead of reaching for the network.
5
+ */
6
+ export interface OcrOptions {
7
+ /** Tesseract language codes, e.g. ['spa', 'eng']. Default ['eng']. */
8
+ languages?: string[];
9
+ /** Directory holding `<lang>.traineddata(.gz)` for every language. Default: the installed `@tesseract.js-data/<lang>` packages. */
10
+ langPath?: string;
11
+ /** Directory of `tesseract.js-core`. Default: the installed one. */
12
+ corePath?: string;
13
+ /** Pages of a scanned PDF to read; the rest are ignored and `truncated` is set. Default 20. */
14
+ maxPages?: number;
15
+ /** Smallest side (px) of a picture in a PDF page to count as a scan of it; pages without one are drawn instead. Default 100. */
16
+ minImageSide?: number;
17
+ /** Scale used to draw a page that has no scan (needs @napi-rs/canvas). Default 2. */
18
+ renderScale?: number;
19
+ /** An image bigger than this many pixels is refused before decoding (decompression bombs). Default 40 000 000. */
20
+ maxPixels?: number;
21
+ }
22
+ export interface OcrResult {
23
+ text: string;
24
+ confidence: number;
25
+ }
26
+ export declare const DEFAULT_OCR: {
27
+ languages: string[];
28
+ maxPages: number;
29
+ maxPixels: number;
30
+ };
31
+ /** Stops every OCR worker. Call it when the host shuts down (the workers keep a Node process alive). */
32
+ export declare function terminateOcr(): Promise<void>;
33
+ export declare function ocrImage(image: Buffer, options: OcrOptions, signal?: AbortSignal): Promise<OcrResult>;
34
+ export declare function imageKind(bytes: Uint8Array): 'png' | 'jpeg' | undefined;
35
+ /** Width and height from the header, before anything decodes the image. */
36
+ export declare function imageSize(bytes: Uint8Array): {
37
+ width: number;
38
+ height: number;
39
+ } | undefined;
40
+ export declare function encodePng(width: number, height: number, channels: 1 | 3 | 4, pixels: Uint8ClampedArray): Buffer;
41
+ //# sourceMappingURL=ocr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ocr.d.ts","sourceRoot":"","sources":["../src/ocr.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACvB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,mIAAmI;IACnI,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gIAAgI;IAChI,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kHAAkH;IAClH,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE;AAE/D,eAAO,MAAM,WAAW;;;;CAA8D,CAAC;AAYvF,wGAAwG;AACxG,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAIlD;AAED,wBAAsB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAqB3G;AAiED,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAIvE;AAED,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAiB1F;AAmCD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAU/G"}
package/dist/ocr.js ADDED
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DEFAULT_OCR = void 0;
37
+ exports.terminateOcr = terminateOcr;
38
+ exports.ocrImage = ocrImage;
39
+ exports.imageKind = imageKind;
40
+ exports.imageSize = imageSize;
41
+ exports.encodePng = encodePng;
42
+ const fs_1 = require("fs");
43
+ const module_1 = require("module");
44
+ const os_1 = require("os");
45
+ const path_1 = require("path");
46
+ const zlib_1 = require("zlib");
47
+ const errors_1 = require("./errors");
48
+ exports.DEFAULT_OCR = { languages: ['eng'], maxPages: 20, maxPixels: 40_000_000 };
49
+ const DATA_VERSION = '4.0.0_best_int';
50
+ const nodeRequire = (0, module_1.createRequire)(__filename);
51
+ const workers = new Map();
52
+ let queue = Promise.resolve();
53
+ /** Stops every OCR worker. Call it when the host shuts down (the workers keep a Node process alive). */
54
+ async function terminateOcr() {
55
+ const all = [...workers.values()];
56
+ workers.clear();
57
+ await Promise.all(all.map(w => w.then(x => x.terminate()).catch(() => undefined)));
58
+ }
59
+ async function ocrImage(image, options, signal) {
60
+ checkPixels(image, options.maxPixels ?? exports.DEFAULT_OCR.maxPixels);
61
+ const worker = await workerFor(options);
62
+ const key = keyOf(options);
63
+ const run = queue.then(async () => {
64
+ if (signal?.aborted)
65
+ throw new errors_1.DocumentExtractError('TIMEOUT');
66
+ // Aborting is the one way to interrupt a recognition in progress: the worker is stopped and rebuilt next time.
67
+ const stop = () => { workers.delete(key); void worker.terminate().catch(() => undefined); };
68
+ signal?.addEventListener('abort', stop, { once: true });
69
+ try {
70
+ const { data } = await worker.recognize(image);
71
+ return { text: data.text.trim(), confidence: data.confidence };
72
+ }
73
+ catch (err) {
74
+ if (signal?.aborted)
75
+ throw new errors_1.DocumentExtractError('TIMEOUT');
76
+ throw new errors_1.DocumentExtractError('CORRUPT', `OCR failed: ${err?.message ?? err}`.slice(0, 200));
77
+ }
78
+ finally {
79
+ signal?.removeEventListener('abort', stop);
80
+ }
81
+ });
82
+ queue = run.catch(() => undefined);
83
+ return run;
84
+ }
85
+ const keyOf = (o) => JSON.stringify([o.languages ?? exports.DEFAULT_OCR.languages, o.langPath ?? '', o.corePath ?? '']);
86
+ function workerFor(options) {
87
+ const key = keyOf(options);
88
+ let w = workers.get(key);
89
+ if (!w) {
90
+ w = createWorker(options);
91
+ workers.set(key, w);
92
+ w.catch(() => workers.delete(key)); // a failed start is retried by the next call
93
+ }
94
+ return w;
95
+ }
96
+ async function createWorker(options) {
97
+ const languages = options.languages ?? exports.DEFAULT_OCR.languages;
98
+ let tesseract;
99
+ try {
100
+ tesseract = await Promise.resolve().then(() => __importStar(require('tesseract.js')));
101
+ }
102
+ catch {
103
+ throw new errors_1.DocumentExtractError('OCR_UNAVAILABLE', 'the tesseract.js package is not installed');
104
+ }
105
+ const langPath = options.langPath ?? languageDirectory(languages);
106
+ const corePath = options.corePath ?? coreDirectory();
107
+ try {
108
+ // gzip: the packaged data is .gz; cacheMethod none: nothing is written or fetched.
109
+ return (await tesseract.createWorker(languages.join('+'), 1, { langPath, corePath, gzip: !options.langPath, cacheMethod: 'none', logger: () => undefined }));
110
+ }
111
+ catch (err) {
112
+ throw new errors_1.DocumentExtractError('OCR_UNAVAILABLE', `the OCR engine could not start (${err?.message ?? err})`.slice(0, 200));
113
+ }
114
+ }
115
+ function coreDirectory() {
116
+ try {
117
+ let from = [__dirname];
118
+ try {
119
+ from = [(0, path_1.dirname)(nodeRequire.resolve('tesseract.js'))];
120
+ }
121
+ catch { /* resolved from this package instead */ }
122
+ return (0, path_1.dirname)(nodeRequire.resolve('tesseract.js-core/package.json', { paths: from }));
123
+ }
124
+ catch {
125
+ throw new errors_1.DocumentExtractError('OCR_UNAVAILABLE', 'tesseract.js-core is not installed');
126
+ }
127
+ }
128
+ /** One directory with every language: the installed data packages, gathered into a cache directory when they live apart. */
129
+ function languageDirectory(languages) {
130
+ const files = languages.map(lang => {
131
+ if (!/^[a-z_]{2,12}$/i.test(lang))
132
+ throw new errors_1.DocumentExtractError('OCR_UNAVAILABLE', `invalid language code "${lang}"`);
133
+ try {
134
+ return { lang, dir: (0, path_1.join)((0, path_1.dirname)(nodeRequire.resolve(`@tesseract.js-data/${lang}/package.json`)), DATA_VERSION) };
135
+ }
136
+ catch {
137
+ throw new errors_1.DocumentExtractError('OCR_UNAVAILABLE', `no data for language "${lang}": install @tesseract.js-data/${lang} or pass langPath`);
138
+ }
139
+ });
140
+ if (new Set(files.map(f => f.dir)).size === 1)
141
+ return files[0].dir;
142
+ const target = (0, path_1.join)((0, os_1.tmpdir)(), `bk-document-extract-ocr-${DATA_VERSION}`);
143
+ (0, fs_1.mkdirSync)(target, { recursive: true });
144
+ for (const { lang, dir } of files) {
145
+ const name = `${lang}.traineddata.gz`;
146
+ if (!(0, fs_1.existsSync)((0, path_1.join)(target, name)))
147
+ (0, fs_1.copyFileSync)((0, path_1.join)(dir, name), (0, path_1.join)(target, name));
148
+ }
149
+ return target;
150
+ }
151
+ // ── images ─────────────────────────────────────────────────────────────────────────────────────────────────────
152
+ function imageKind(bytes) {
153
+ if (bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4e && bytes[3] === 0x47 && bytes[4] === 0x0d)
154
+ return 'png';
155
+ if (bytes[0] === 0xff && bytes[1] === 0xd8 && bytes[2] === 0xff)
156
+ return 'jpeg';
157
+ return undefined;
158
+ }
159
+ /** Width and height from the header, before anything decodes the image. */
160
+ function imageSize(bytes) {
161
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
162
+ const kind = imageKind(bytes);
163
+ if (kind === 'png')
164
+ return bytes.length >= 24 ? { width: view.getUint32(16), height: view.getUint32(20) } : undefined;
165
+ if (kind === 'jpeg') {
166
+ let at = 2;
167
+ while (at + 9 < bytes.length) {
168
+ if (bytes[at] !== 0xff) {
169
+ at++;
170
+ continue;
171
+ }
172
+ const marker = bytes[at + 1];
173
+ if (marker >= 0xc0 && marker <= 0xcf && marker !== 0xc4 && marker !== 0xc8 && marker !== 0xcc) {
174
+ return { height: view.getUint16(at + 5), width: view.getUint16(at + 7) };
175
+ }
176
+ if (marker === 0xd8 || (marker >= 0xd0 && marker <= 0xd7) || marker === 0x01) {
177
+ at += 2;
178
+ continue;
179
+ }
180
+ at += 2 + view.getUint16(at + 2);
181
+ }
182
+ }
183
+ return undefined;
184
+ }
185
+ function checkPixels(image, maxPixels) {
186
+ const size = imageSize(image);
187
+ if (!size || size.width === 0 || size.height === 0)
188
+ throw new errors_1.DocumentExtractError('CORRUPT', 'the image header is not readable');
189
+ if (size.width * size.height > maxPixels)
190
+ throw new errors_1.DocumentExtractError('TOO_LARGE', `${size.width}x${size.height} pixels, limit ${maxPixels}`);
191
+ }
192
+ // ── raw pixels (what a PDF scan holds) to PNG ──────────────────────────────────────────────────────────────
193
+ const CRC = (() => {
194
+ const table = [];
195
+ for (let n = 0; n < 256; n++) {
196
+ let c = n;
197
+ for (let k = 0; k < 8; k++)
198
+ c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
199
+ table[n] = c >>> 0;
200
+ }
201
+ return table;
202
+ })();
203
+ function crc32(buf) {
204
+ let x = 0xffffffff;
205
+ for (const v of buf)
206
+ x = CRC[(x ^ v) & 255] ^ (x >>> 8);
207
+ return (x ^ 0xffffffff) >>> 0;
208
+ }
209
+ function chunk(type, data) {
210
+ const len = Buffer.alloc(4);
211
+ len.writeUInt32BE(data.length);
212
+ const body = Buffer.concat([Buffer.from(type, 'ascii'), data]);
213
+ const crc = Buffer.alloc(4);
214
+ crc.writeUInt32BE(crc32(body));
215
+ return Buffer.concat([len, body, crc]);
216
+ }
217
+ function encodePng(width, height, channels, pixels) {
218
+ const ihdr = Buffer.alloc(13);
219
+ ihdr.writeUInt32BE(width, 0);
220
+ ihdr.writeUInt32BE(height, 4);
221
+ ihdr[8] = 8;
222
+ ihdr[9] = channels === 1 ? 0 : channels === 3 ? 2 : 6;
223
+ const stride = width * channels;
224
+ const raw = Buffer.alloc((stride + 1) * height); // each row starts with filter type 0
225
+ for (let y = 0; y < height; y++)
226
+ Buffer.from(pixels.buffer, pixels.byteOffset + y * stride, stride).copy(raw, y * (stride + 1) + 1);
227
+ return Buffer.concat([Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]), chunk('IHDR', ihdr), chunk('IDAT', (0, zlib_1.deflateSync)(raw)), chunk('IEND', Buffer.alloc(0))]);
228
+ }
229
+ //# sourceMappingURL=ocr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ocr.js","sourceRoot":"","sources":["../src/ocr.ts"],"names":[],"mappings":"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"}
package/dist/tool.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ import { type ExtractLimits } from './types';
2
+ import type { OcrOptions } from './ocr';
3
+ export interface ReadDocumentToolOptions {
4
+ limits?: Partial<ExtractLimits>;
5
+ /** Read images and scanned PDFs with OCR (needs tesseract.js and language data installed). Off by default. */
6
+ ocr?: boolean | OcrOptions;
7
+ /**
8
+ * Turns what the model asked for into an absolute path, or throws if it is not allowed. The default allows the working
9
+ * directory and `additionalRoots` of the call. Hosts with their own sandbox (or that store uploads by id) pass theirs.
10
+ */
11
+ resolvePath?: (requested: string, ctx: {
12
+ workingDir?: string;
13
+ additionalRoots?: string[];
14
+ }) => string;
15
+ }
16
+ /** The text of a PDF, Word, Excel, CSV or text file. The result is the file's CONTENT, to be read as data and never obeyed. */
17
+ export declare function createReadDocumentTool(options?: ReadDocumentToolOptions): import("@backendkit-labs/agent-core").ToolDefinition;
18
+ //# sourceMappingURL=tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"AAKA,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAExC,MAAM,WAAW,uBAAuB;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAChC,8GAA8G;IAC9G,GAAG,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC3B;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,MAAM,CAAC;CACzG;AAcD,+HAA+H;AAC/H,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,uBAA4B,wDAqC3E"}