n8n-nodes-deep-ocr 1.11.1 → 1.12.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 +13 -13
- package/dist/nodes/DeepOcr/DeepOcr.node.d.ts +1 -1
- package/dist/nodes/DeepOcr/DeepOcr.node.d.ts.map +1 -1
- package/dist/nodes/DeepOcr/DeepOcr.node.js +170 -31
- package/dist/nodes/DeepOcr/DeepOcr.node.js.map +1 -1
- package/dist/utils/errors.d.ts +9 -2
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +14 -6
- package/dist/utils/errors.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -34,15 +34,15 @@ You hand it a document, it hands you back clean JSON. No regex, no template matc
|
|
|
34
34
|
}
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
(Every response also includes `
|
|
37
|
+
(Every response also includes `document_type` and a `metadata` object — see [Output Examples](#-output-examples) below for the full shape.)
|
|
38
38
|
|
|
39
39
|
Drop it into any workflow that needs accounting, expense tracking, KYC, or document classification.
|
|
40
40
|
|
|
41
41
|
## 🚀 Features
|
|
42
42
|
|
|
43
43
|
- **Structured Data Extraction**: Receive a structured JSON object with the fields relevant to the document type
|
|
44
|
-
- **Document Types & Auto Detection**: Invoice, Receipt, Contract, Delivery Note, Bank Statement, Payslip, Purchase Order, ID Document, Handwriting, Generic, and automatic type detection (`auto`)
|
|
45
|
-
- **Multiple Format Support**: PDF, PNG, JPG, JPEG, WebP (up to
|
|
44
|
+
- **Document Types & Auto Detection**: Invoice, Receipt, Contract, Delivery Note, Bank Statement, Payslip, Purchase Order, ID Document, Handwriting, Full-Text, Generic, and automatic type detection (`auto`)
|
|
45
|
+
- **Multiple Format Support**: PDF, PNG, JPG, JPEG, WebP, TIFF (up to 100MB)
|
|
46
46
|
- **Secure Authentication**: API key stored securely using n8n credentials
|
|
47
47
|
|
|
48
48
|
## 📦 Installation
|
|
@@ -82,7 +82,7 @@ npm install n8n-nodes-deep-ocr
|
|
|
82
82
|
|
|
83
83
|
| Type | Description |
|
|
84
84
|
|---|---|
|
|
85
|
-
| `
|
|
85
|
+
| `generic` | Flexible extraction for any document — adapts structure to the content. Cheap default; pick a specific type below when you know it |
|
|
86
86
|
| `invoice` | Vendor, customer, line items, tax breakdown, totals, IBAN, payment terms |
|
|
87
87
|
| `receipt` | Merchant, items, per-item tax rate, tax breakdown, totals, payment method |
|
|
88
88
|
| `contract` | Parties (role/name/address), dates, obligations, governing law, signatures |
|
|
@@ -92,7 +92,8 @@ npm install n8n-nodes-deep-ocr
|
|
|
92
92
|
| `purchase_order` | Buyer, supplier, delivery address, line items, totals |
|
|
93
93
|
| `id_document` | Type, document number, personal data, MRZ lines |
|
|
94
94
|
| `handwriting` | Full transcription with unclear-word markers, confidence rating, language |
|
|
95
|
-
| `
|
|
95
|
+
| `fulltext` | Transcribe the entire document as Markdown — billed at 10× a structured extraction |
|
|
96
|
+
| `auto` | Classify the document first and then extract — costs more than picking a specific type. Use only when the type is genuinely unknown |
|
|
96
97
|
|
|
97
98
|
## 📤 Output Examples
|
|
98
99
|
|
|
@@ -111,7 +112,6 @@ npm install n8n-nodes-deep-ocr
|
|
|
111
112
|
"tax_amount": 228.00,
|
|
112
113
|
"total": 1428.00,
|
|
113
114
|
"iban": "DE89 3704 0044 0532 0130 00",
|
|
114
|
-
"filename": "invoice.pdf",
|
|
115
115
|
"document_type": "invoice",
|
|
116
116
|
"metadata": { "pages": 1 }
|
|
117
117
|
}
|
|
@@ -130,7 +130,6 @@ npm install n8n-nodes-deep-ocr
|
|
|
130
130
|
"tax_breakdown": [{ "rate": 7, "amount": 0.42 }],
|
|
131
131
|
"total": 6.90,
|
|
132
132
|
"payment_method": "EC-Karte",
|
|
133
|
-
"filename": "receipt.jpg",
|
|
134
133
|
"document_type": "receipt",
|
|
135
134
|
"metadata": { "pages": 1 }
|
|
136
135
|
}
|
|
@@ -164,18 +163,19 @@ npm install n8n-nodes-deep-ocr
|
|
|
164
163
|
|
|
165
164
|
| Format | MIME Type | Max Size |
|
|
166
165
|
| -------- | --------------- | -------- |
|
|
167
|
-
| PDF | application/pdf |
|
|
168
|
-
| PNG | image/png |
|
|
169
|
-
| JPG/JPEG | image/jpeg |
|
|
170
|
-
| WebP | image/webp |
|
|
166
|
+
| PDF | application/pdf | 100MB |
|
|
167
|
+
| PNG | image/png | 100MB |
|
|
168
|
+
| JPG/JPEG | image/jpeg | 100MB |
|
|
169
|
+
| WebP | image/webp | 100MB |
|
|
170
|
+
| TIFF | image/tiff | 100MB |
|
|
171
171
|
|
|
172
172
|
## 🔧 Troubleshooting
|
|
173
173
|
|
|
174
174
|
### "Unsupported file type" error
|
|
175
|
-
The node only accepts PDF, PNG, JPG, JPEG, and
|
|
175
|
+
The node only accepts PDF, PNG, JPG, JPEG, WebP, and TIFF files. Make sure the upstream node sets the correct MIME type. If you're using **HTTP Request** to download a file, check that the response has a proper `Content-Type` header.
|
|
176
176
|
|
|
177
177
|
### "File size exceeds maximum allowed size"
|
|
178
|
-
The Deep-OCR API accepts files up to **
|
|
178
|
+
The Deep-OCR API accepts files up to **100MB**. For larger PDFs, consider compressing them first or splitting them into individual pages.
|
|
179
179
|
|
|
180
180
|
### "Connection tested successfully" but processing fails
|
|
181
181
|
Your API key is valid, but the key may not have enough quota remaining. Check your usage in the [Deep-OCR Dashboard](https://deep-ocr.com).
|
|
@@ -4,7 +4,7 @@ import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescrip
|
|
|
4
4
|
*
|
|
5
5
|
* AI-powered OCR for invoices, receipts, contracts, IDs, bank statements
|
|
6
6
|
* and more — returns structured JSON ready to use.
|
|
7
|
-
* Supports PDF, PNG, JPG, JPEG, and
|
|
7
|
+
* Supports PDF, PNG, JPG, JPEG, WebP, and TIFF formats up to 100MB.
|
|
8
8
|
*/
|
|
9
9
|
export declare class DeepOcr implements INodeType {
|
|
10
10
|
description: INodeTypeDescription;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeepOcr.node.d.ts","sourceRoot":"","sources":["../../../src/nodes/DeepOcr/DeepOcr.node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,SAAS,EACT,oBAAoB,EAErB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"DeepOcr.node.d.ts","sourceRoot":"","sources":["../../../src/nodes/DeepOcr/DeepOcr.node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,SAAS,EACT,oBAAoB,EAErB,MAAM,cAAc,CAAC;AAiKtB;;;;;;GAMG;AACH,qBAAa,OAAQ,YAAW,SAAS;IACvC,WAAW,EAAE,oBAAoB,CA0G/B;IAEI,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;CA+MxE"}
|
|
@@ -7,8 +7,57 @@ const errors_1 = require("../../utils/errors");
|
|
|
7
7
|
// identifier strings in lockstep with semantic-release bumps without a
|
|
8
8
|
// hardcoded version literal anywhere.
|
|
9
9
|
const package_json_1 = require("../../../package.json");
|
|
10
|
-
/** Deep-OCR API
|
|
11
|
-
const
|
|
10
|
+
/** Deep-OCR API base URL */
|
|
11
|
+
const API_BASE = 'https://api.deep-ocr.com';
|
|
12
|
+
/** POST a new extraction job */
|
|
13
|
+
const EXTRACTIONS_URL = `${API_BASE}/v1/extractions`;
|
|
14
|
+
/**
|
|
15
|
+
* GET the status of a single extraction by id (contract format: `ext_<uuid>`).
|
|
16
|
+
* `encodeURIComponent` escapes the id as a single path segment so the call
|
|
17
|
+
* still works if a future id format ever contains a `/` — though the
|
|
18
|
+
* `ext_<uuid>` form documented in EXTRACTIONS_API_CONTRACT has no reserved
|
|
19
|
+
* characters and round-trips unchanged.
|
|
20
|
+
*/
|
|
21
|
+
const extractionUrl = (jobId) => `${API_BASE}/v1/extractions/${encodeURIComponent(jobId)}`;
|
|
22
|
+
/**
|
|
23
|
+
* Tightened object check that rejects null AND arrays. Plain `typeof x === 'object'`
|
|
24
|
+
* accepts both — an `[]` poll body would otherwise sail past the shape check, have
|
|
25
|
+
* `polled.status === undefined`, and only fail via the 5-min timeout instead of
|
|
26
|
+
* surfacing the malformed response immediately.
|
|
27
|
+
*/
|
|
28
|
+
const isPlainObject = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
29
|
+
/**
|
|
30
|
+
* Pure parser for the `Retry-After` header (seconds, per the contract).
|
|
31
|
+
* Returns the parsed value in milliseconds, or undefined when:
|
|
32
|
+
* - the header is absent
|
|
33
|
+
* - the value is not a finite positive number
|
|
34
|
+
* - the value is an HTTP-date string (intentionally not supported;
|
|
35
|
+
* the contract documents seconds-only)
|
|
36
|
+
* Header lookup checks the lowercased key first (n8n normalises) with the
|
|
37
|
+
* canonical-case key as a mock-friendly fallback.
|
|
38
|
+
*/
|
|
39
|
+
const parseRetryAfterMs = (headers) => {
|
|
40
|
+
if (!isPlainObject(headers))
|
|
41
|
+
return undefined;
|
|
42
|
+
const raw = headers['retry-after'] ?? headers['Retry-After'];
|
|
43
|
+
if (typeof raw !== 'string' && typeof raw !== 'number')
|
|
44
|
+
return undefined;
|
|
45
|
+
const seconds = Number(raw);
|
|
46
|
+
if (!Number.isFinite(seconds) || seconds <= 0)
|
|
47
|
+
return undefined;
|
|
48
|
+
return Math.floor(seconds * 1000);
|
|
49
|
+
};
|
|
50
|
+
/** Poll cadence: start short, grow gently, cap, give up after a sane bound. */
|
|
51
|
+
const POLL_INITIAL_MS = 1_000;
|
|
52
|
+
const POLL_MAX_MS = 5_000;
|
|
53
|
+
const POLL_BACKOFF = 1.5;
|
|
54
|
+
const POLL_TIMEOUT_MS = 5 * 60_000; // 5 minutes total wall-clock
|
|
55
|
+
/**
|
|
56
|
+
* Hard upper bound on a server-provided Retry-After (in ms). Protects against
|
|
57
|
+
* a buggy or pathological header value that would otherwise stall the workflow
|
|
58
|
+
* past POLL_TIMEOUT_MS in a single sleep.
|
|
59
|
+
*/
|
|
60
|
+
const RETRY_AFTER_MAX_MS = 30_000;
|
|
12
61
|
/**
|
|
13
62
|
* Client identifier the API logs and attributes traffic by.
|
|
14
63
|
* Format pinned with deep-ocr-api: `deep-ocr-n8n/<semver>` (e.g.
|
|
@@ -18,27 +67,37 @@ const API_ENDPOINT = 'https://api.deep-ocr.com/v1/ocr';
|
|
|
18
67
|
* case a future n8n version resets the UA)
|
|
19
68
|
* The API parser uses X-Deep-OCR-Client as the authoritative source, with
|
|
20
69
|
* User-Agent as the fallback for callers that can't set custom headers.
|
|
70
|
+
*
|
|
71
|
+
* Frozen + spread-at-call-site (two-layer defence). n8n-core's auth pipeline
|
|
72
|
+
* is implemented outside this repo and historically merges the credential's
|
|
73
|
+
* Authorization header into requestOptions.headers via Object.assign in some
|
|
74
|
+
* code paths. If CLIENT_HEADERS were passed by reference into that pipeline,
|
|
75
|
+
* an Authorization header could accumulate on the shared module-level
|
|
76
|
+
* constant — leaking across executions and credentials. Two layers:
|
|
77
|
+
* 1. Object.freeze — any direct mutation throws under strict mode rather
|
|
78
|
+
* than silently polluting the constant.
|
|
79
|
+
* 2. The call site uses `headers: { ...CLIENT_HEADERS }` — n8n's pipeline
|
|
80
|
+
* mutates the per-call copy, not the canonical source.
|
|
81
|
+
*
|
|
82
|
+
* The constant is applied to BOTH async call sites — the POST submit AND
|
|
83
|
+
* every GET poll — so every wire byte the node sends to deep-ocr-api
|
|
84
|
+
* carries the attribution.
|
|
21
85
|
*/
|
|
22
86
|
const CLIENT_ID = `deep-ocr-n8n/${package_json_1.version}`;
|
|
23
|
-
// Frozen + spread-at-call-site (two-layer defence). n8n-core's auth pipeline
|
|
24
|
-
// is implemented outside this repo and historically merges the credential's
|
|
25
|
-
// Authorization header into requestOptions.headers via Object.assign in some
|
|
26
|
-
// code paths. If CLIENT_HEADERS were passed by reference into that pipeline,
|
|
27
|
-
// an Authorization header could accumulate on the shared module-level
|
|
28
|
-
// constant — leaking across executions and credentials. Two layers:
|
|
29
|
-
// 1. Object.freeze — any direct mutation throws under strict mode rather
|
|
30
|
-
// than silently polluting the constant.
|
|
31
|
-
// 2. The call site uses `headers: { ...CLIENT_HEADERS }` — n8n's pipeline
|
|
32
|
-
// mutates the per-call copy, not the canonical source.
|
|
33
87
|
const CLIENT_HEADERS = Object.freeze({
|
|
34
88
|
'User-Agent': CLIENT_ID,
|
|
35
89
|
'X-Deep-OCR-Client': CLIENT_ID,
|
|
36
90
|
});
|
|
91
|
+
// Mirrors the closed 12-value DocumentType enum from the API contract — every
|
|
92
|
+
// value (including `auto` and `fulltext`) is sent verbatim as the
|
|
93
|
+
// `document_type` form field; the field is required at submit. The validator
|
|
94
|
+
// below runs on the UI value to guard against crafted workflow JSON.
|
|
37
95
|
const ALLOWED_DOCUMENT_TYPES = [
|
|
38
96
|
'auto',
|
|
39
97
|
'bank_statement',
|
|
40
98
|
'contract',
|
|
41
99
|
'delivery_note',
|
|
100
|
+
'fulltext',
|
|
42
101
|
'generic',
|
|
43
102
|
'handwriting',
|
|
44
103
|
'id_document',
|
|
@@ -52,7 +111,7 @@ const ALLOWED_DOCUMENT_TYPES = [
|
|
|
52
111
|
*
|
|
53
112
|
* AI-powered OCR for invoices, receipts, contracts, IDs, bank statements
|
|
54
113
|
* and more — returns structured JSON ready to use.
|
|
55
|
-
* Supports PDF, PNG, JPG, JPEG, and
|
|
114
|
+
* Supports PDF, PNG, JPG, JPEG, WebP, and TIFF formats up to 100MB.
|
|
56
115
|
*/
|
|
57
116
|
class DeepOcr {
|
|
58
117
|
description = {
|
|
@@ -93,7 +152,7 @@ class DeepOcr {
|
|
|
93
152
|
{
|
|
94
153
|
name: 'Auto-Detect',
|
|
95
154
|
value: 'auto',
|
|
96
|
-
description: 'Let the API classify the document
|
|
155
|
+
description: 'Let the API classify the document first and then extract — costs more than picking a specific type. Use only when the document type is genuinely unknown.',
|
|
97
156
|
},
|
|
98
157
|
{
|
|
99
158
|
name: 'Bank Statement',
|
|
@@ -110,6 +169,11 @@ class DeepOcr {
|
|
|
110
169
|
value: 'delivery_note',
|
|
111
170
|
description: 'Extract sender, recipient, items, quantities, and tracking info',
|
|
112
171
|
},
|
|
172
|
+
{
|
|
173
|
+
name: 'Full-Text',
|
|
174
|
+
value: 'fulltext',
|
|
175
|
+
description: 'Transcribe the entire document as Markdown — billed at 10× a structured extraction',
|
|
176
|
+
},
|
|
113
177
|
{
|
|
114
178
|
name: 'Generic',
|
|
115
179
|
value: 'generic',
|
|
@@ -146,7 +210,10 @@ class DeepOcr {
|
|
|
146
210
|
description: 'Extract merchant, items, tax breakdown, totals, and payment method',
|
|
147
211
|
},
|
|
148
212
|
],
|
|
149
|
-
|
|
213
|
+
// Default to 'generic' (cheap, no classification step). Never default
|
|
214
|
+
// to 'auto' (deliberate classify-then-extract, extra cost) or 'fulltext'
|
|
215
|
+
// (×10 billing) — those must be explicit opt-in choices.
|
|
216
|
+
default: 'generic',
|
|
150
217
|
description: 'Type of document — determines the extraction schema',
|
|
151
218
|
},
|
|
152
219
|
],
|
|
@@ -157,7 +224,7 @@ class DeepOcr {
|
|
|
157
224
|
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
|
158
225
|
try {
|
|
159
226
|
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', itemIndex, 'data');
|
|
160
|
-
const documentType = this.getNodeParameter('documentType', itemIndex, '
|
|
227
|
+
const documentType = this.getNodeParameter('documentType', itemIndex, 'generic');
|
|
161
228
|
// Validate documentType against known values (guards against crafted workflow JSON)
|
|
162
229
|
if (!ALLOWED_DOCUMENT_TYPES.includes(documentType)) {
|
|
163
230
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid document type: "${documentType}"`, { itemIndex });
|
|
@@ -187,32 +254,104 @@ class DeepOcr {
|
|
|
187
254
|
}
|
|
188
255
|
// Sanitize filename to prevent path traversal and homograph attacks in multipart headers
|
|
189
256
|
const safeFilename = (0, errors_1.sanitizeFilename)(binaryData.fileName ?? 'document');
|
|
190
|
-
//
|
|
191
|
-
//
|
|
192
|
-
//
|
|
257
|
+
// Submit extraction job — multipart-only per the EXTRACTIONS_API_CONTRACT.
|
|
258
|
+
// `document_type` is a REQUIRED form field. The closed 12-value enum
|
|
259
|
+
// includes 'auto' as an explicit choice (deliberate classify-then-extract,
|
|
260
|
+
// priced higher than picking a specific schema) — never default to it,
|
|
261
|
+
// but always send whatever the user picked.
|
|
193
262
|
const form = new FormData();
|
|
194
263
|
form.append('file', new Blob([buffer], { type: binaryData.mimeType }), safeFilename);
|
|
195
|
-
|
|
264
|
+
form.append('document_type', documentType);
|
|
265
|
+
// Step 1: POST → 202 + Extraction { id, … }
|
|
266
|
+
const submitResponse = await this.helpers.httpRequestWithAuthentication.call(this, 'deepOcrApi', {
|
|
196
267
|
method: 'POST',
|
|
197
|
-
url:
|
|
198
|
-
qs: documentType !== 'auto' ? { document_type: documentType } : {},
|
|
268
|
+
url: EXTRACTIONS_URL,
|
|
199
269
|
body: form,
|
|
200
270
|
// Fresh per-call copy — see CLIENT_HEADERS for the rationale.
|
|
201
271
|
headers: { ...CLIENT_HEADERS },
|
|
202
272
|
});
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
273
|
+
if (!isPlainObject(submitResponse)) {
|
|
274
|
+
throw new n8n_workflow_1.NodeApiError(this.getNode(), { message: 'Unexpected response format from Deep-OCR API (expected 202 + Extraction)' }, { itemIndex });
|
|
275
|
+
}
|
|
276
|
+
const submitted = submitResponse;
|
|
277
|
+
const jobId = typeof submitted.id === 'string' ? submitted.id : undefined;
|
|
278
|
+
if (typeof jobId !== 'string' || jobId.length === 0) {
|
|
279
|
+
throw new n8n_workflow_1.NodeApiError(this.getNode(), { message: 'Deep-OCR API did not return an extraction id' }, { itemIndex });
|
|
280
|
+
}
|
|
281
|
+
// Step 2: poll GET /v1/extractions/{id} until terminal — honour the
|
|
282
|
+
// server's Retry-After header (seconds) when present, otherwise fall
|
|
283
|
+
// back to a local 1s→5s backoff. HTTP 200 is not success on its own:
|
|
284
|
+
// an HTTP-200 poll response with status='failed' must surface as an
|
|
285
|
+
// error, hence the explicit status check. Polling order is GET-first,
|
|
286
|
+
// sleep-after: a job that completes synchronously on the submit (small
|
|
287
|
+
// docs often do) returns immediately on the first poll without eating
|
|
288
|
+
// a full POLL_INITIAL_MS of latency.
|
|
289
|
+
const startedAt = Date.now();
|
|
290
|
+
let pollDelay = POLL_INITIAL_MS;
|
|
291
|
+
let polled;
|
|
292
|
+
while (true) {
|
|
293
|
+
const pollResponse = await this.helpers.httpRequestWithAuthentication.call(this, 'deepOcrApi', {
|
|
294
|
+
method: 'GET',
|
|
295
|
+
url: extractionUrl(jobId),
|
|
296
|
+
returnFullResponse: true,
|
|
297
|
+
// Fresh per-call copy — see CLIENT_HEADERS for the rationale.
|
|
298
|
+
headers: { ...CLIENT_HEADERS },
|
|
299
|
+
});
|
|
300
|
+
// Strict full-response shape check: a regression that drops
|
|
301
|
+
// `returnFullResponse: true` (or a flat-out malformed reply) must
|
|
302
|
+
// surface immediately, not silently disable Retry-After parsing.
|
|
303
|
+
if (!isPlainObject(pollResponse) ||
|
|
304
|
+
!('body' in pollResponse) ||
|
|
305
|
+
!('headers' in pollResponse)) {
|
|
306
|
+
throw new n8n_workflow_1.NodeApiError(this.getNode(), {
|
|
307
|
+
message: `Deep-OCR poll response for extraction ${jobId} is missing the body/headers wrapper (expected returnFullResponse output)`,
|
|
308
|
+
}, { itemIndex });
|
|
309
|
+
}
|
|
310
|
+
const pollRaw = pollResponse.body;
|
|
311
|
+
const retryAfterMs = parseRetryAfterMs(pollResponse.headers);
|
|
312
|
+
if (!isPlainObject(pollRaw)) {
|
|
313
|
+
throw new n8n_workflow_1.NodeApiError(this.getNode(), { message: `Unexpected poll response shape for extraction ${jobId}` }, { itemIndex });
|
|
314
|
+
}
|
|
315
|
+
polled = pollRaw;
|
|
316
|
+
const status = polled.status;
|
|
317
|
+
if (status === 'completed' || status === 'failed') {
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
if (Date.now() - startedAt > POLL_TIMEOUT_MS) {
|
|
321
|
+
throw new n8n_workflow_1.NodeApiError(this.getNode(), {
|
|
322
|
+
message: `Deep-OCR extraction ${jobId} did not reach a terminal state within ${POLL_TIMEOUT_MS / 1000}s (last status: ${typeof status === 'string' ? status : 'unknown'})`,
|
|
323
|
+
}, { itemIndex });
|
|
324
|
+
}
|
|
325
|
+
if (retryAfterMs !== undefined) {
|
|
326
|
+
// Honour the server's hint, clamped so a buggy header can't stall
|
|
327
|
+
// the workflow past the wall-clock timeout in a single sleep.
|
|
328
|
+
await (0, n8n_workflow_1.sleep)(Math.min(retryAfterMs, RETRY_AFTER_MAX_MS));
|
|
329
|
+
// Reset local backoff so a transient Retry-After spike doesn't
|
|
330
|
+
// permanently push subsequent fallback polls to the cap.
|
|
331
|
+
pollDelay = POLL_INITIAL_MS;
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
await (0, n8n_workflow_1.sleep)(pollDelay);
|
|
335
|
+
pollDelay = Math.min(Math.floor(pollDelay * POLL_BACKOFF), POLL_MAX_MS);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// Step 3: dispatch on terminal status.
|
|
339
|
+
if (polled.status === 'failed') {
|
|
340
|
+
const err = polled.error ?? {};
|
|
341
|
+
const code = typeof err.code === 'string' && err.code.length > 0 ? err.code : 'failed';
|
|
342
|
+
const message = typeof err.message === 'string' && err.message.length > 0
|
|
343
|
+
? err.message
|
|
344
|
+
: `Deep-OCR extraction ${jobId} failed`;
|
|
345
|
+
throw new n8n_workflow_1.NodeApiError(this.getNode(), { message: `[${code}] ${message}` }, { itemIndex });
|
|
206
346
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const content =
|
|
347
|
+
// status === 'completed' — unwrap $.result (defensive: tolerate missing fields)
|
|
348
|
+
const result = polled.result ?? {};
|
|
349
|
+
const content = result.content ?? {};
|
|
210
350
|
returnData.push({
|
|
211
351
|
json: {
|
|
212
352
|
...content,
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
metadata: response.metadata,
|
|
353
|
+
document_type: result.document_type,
|
|
354
|
+
metadata: result.metadata,
|
|
216
355
|
},
|
|
217
356
|
pairedItem: { item: itemIndex },
|
|
218
357
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeepOcr.node.js","sourceRoot":"","sources":["../../../src/nodes/DeepOcr/DeepOcr.node.ts"],"names":[],"mappings":";;;AAOA,+
|
|
1
|
+
{"version":3,"file":"DeepOcr.node.js","sourceRoot":"","sources":["../../../src/nodes/DeepOcr/DeepOcr.node.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/errors.d.ts
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import { NodeApiError, NodeOperationError } from 'n8n-workflow';
|
|
2
2
|
import type { INode } from 'n8n-workflow';
|
|
3
3
|
/**
|
|
4
|
-
* Maximum file size in bytes (
|
|
4
|
+
* Maximum file size in bytes (100MB) — mirrors the API's documented
|
|
5
|
+
* upload limit from EXTRACTIONS_API_CONTRACT (`104_857_600 bytes`).
|
|
6
|
+
* Keep this in lockstep with the API: rejecting locally what the API
|
|
7
|
+
* would accept is exactly the contract drift this constant exists to
|
|
8
|
+
* avoid.
|
|
5
9
|
*/
|
|
6
10
|
export declare const MAX_FILE_SIZE: number;
|
|
11
|
+
/** MAX_FILE_SIZE rendered as a "100MB" string for error messages. */
|
|
12
|
+
export declare const MAX_FILE_SIZE_MB: number;
|
|
7
13
|
/**
|
|
8
14
|
* Maximum safe filename length in characters (enforced on UTF-16 code units, not bytes)
|
|
9
15
|
*/
|
|
10
16
|
export declare const MAX_FILENAME_LENGTH = 255;
|
|
11
17
|
/**
|
|
12
|
-
* Allowed MIME types for document processing
|
|
18
|
+
* Allowed MIME types for document processing. Mirrors the API allowlist
|
|
19
|
+
* (PDF + PNG / JPEG / WebP / TIFF).
|
|
13
20
|
*/
|
|
14
21
|
export declare const ALLOWED_MIME_TYPES: string[];
|
|
15
22
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,QAAoB,CAAC;AAE/C,qEAAqE;AACrE,eAAO,MAAM,gBAAgB,QAA0C,CAAC;AAExE;;GAEG;AACH,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC;;;GAGG;AACH,eAAO,MAAM,kBAAkB,UAO9B,CAAC;AAEF;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,KAAK,EACX,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,kBAAkB,CASpB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,KAAK,EACX,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACjB,kBAAkB,CAUpB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAKrE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CASzD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,SAAM,GAAG,MAAM,CAK7E;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,OAAO,EACd,SAAS,CAAC,EAAE,MAAM,GACjB,YAAY,GAAG,kBAAkB,CASnC"}
|
package/dist/utils/errors.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ALLOWED_MIME_TYPES = exports.MAX_FILENAME_LENGTH = exports.MAX_FILE_SIZE = void 0;
|
|
3
|
+
exports.ALLOWED_MIME_TYPES = exports.MAX_FILENAME_LENGTH = exports.MAX_FILE_SIZE_MB = exports.MAX_FILE_SIZE = void 0;
|
|
4
4
|
exports.createFileTypeError = createFileTypeError;
|
|
5
5
|
exports.createFileSizeError = createFileSizeError;
|
|
6
6
|
exports.isValidMimeType = isValidMimeType;
|
|
@@ -10,15 +10,22 @@ exports.truncateErrorMessage = truncateErrorMessage;
|
|
|
10
10
|
exports.wrapUnknownError = wrapUnknownError;
|
|
11
11
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
12
12
|
/**
|
|
13
|
-
* Maximum file size in bytes (
|
|
13
|
+
* Maximum file size in bytes (100MB) — mirrors the API's documented
|
|
14
|
+
* upload limit from EXTRACTIONS_API_CONTRACT (`104_857_600 bytes`).
|
|
15
|
+
* Keep this in lockstep with the API: rejecting locally what the API
|
|
16
|
+
* would accept is exactly the contract drift this constant exists to
|
|
17
|
+
* avoid.
|
|
14
18
|
*/
|
|
15
|
-
exports.MAX_FILE_SIZE =
|
|
19
|
+
exports.MAX_FILE_SIZE = 100 * 1024 * 1024;
|
|
20
|
+
/** MAX_FILE_SIZE rendered as a "100MB" string for error messages. */
|
|
21
|
+
exports.MAX_FILE_SIZE_MB = Math.round(exports.MAX_FILE_SIZE / 1024 / 1024);
|
|
16
22
|
/**
|
|
17
23
|
* Maximum safe filename length in characters (enforced on UTF-16 code units, not bytes)
|
|
18
24
|
*/
|
|
19
25
|
exports.MAX_FILENAME_LENGTH = 255;
|
|
20
26
|
/**
|
|
21
|
-
* Allowed MIME types for document processing
|
|
27
|
+
* Allowed MIME types for document processing. Mirrors the API allowlist
|
|
28
|
+
* (PDF + PNG / JPEG / WebP / TIFF).
|
|
22
29
|
*/
|
|
23
30
|
exports.ALLOWED_MIME_TYPES = [
|
|
24
31
|
'application/pdf',
|
|
@@ -26,12 +33,13 @@ exports.ALLOWED_MIME_TYPES = [
|
|
|
26
33
|
'image/jpeg',
|
|
27
34
|
'image/jpg',
|
|
28
35
|
'image/webp',
|
|
36
|
+
'image/tiff',
|
|
29
37
|
];
|
|
30
38
|
/**
|
|
31
39
|
* Creates a NodeOperationError for invalid file types
|
|
32
40
|
*/
|
|
33
41
|
function createFileTypeError(node, mimeType, itemIndex) {
|
|
34
|
-
return new n8n_workflow_1.NodeOperationError(node, `Unsupported file type: ${mimeType}. Supported types: PDF, PNG, JPG, JPEG, WebP`, {
|
|
42
|
+
return new n8n_workflow_1.NodeOperationError(node, `Unsupported file type: ${mimeType}. Supported types: PDF, PNG, JPG, JPEG, WebP, TIFF`, {
|
|
35
43
|
itemIndex,
|
|
36
44
|
description: `The file has MIME type "${mimeType}" which is not supported by the Deep-OCR API.`,
|
|
37
45
|
});
|
|
@@ -41,7 +49,7 @@ function createFileTypeError(node, mimeType, itemIndex) {
|
|
|
41
49
|
*/
|
|
42
50
|
function createFileSizeError(node, sizeBytes, itemIndex) {
|
|
43
51
|
const sizeMB = Math.round(sizeBytes / 1024 / 1024);
|
|
44
|
-
return new n8n_workflow_1.NodeOperationError(node, `File size (${sizeMB}MB) exceeds maximum allowed size of
|
|
52
|
+
return new n8n_workflow_1.NodeOperationError(node, `File size (${sizeMB}MB) exceeds maximum allowed size of ${exports.MAX_FILE_SIZE_MB}MB`, {
|
|
45
53
|
itemIndex,
|
|
46
54
|
description: 'Please reduce the file size or use a smaller document.',
|
|
47
55
|
});
|
package/dist/utils/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED