n8n-nodes-deep-ocr 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.
- package/LICENSE +21 -0
- package/README.md +149 -0
- package/dist/credentials/DeepOcrApi.credentials.d.ts +16 -0
- package/dist/credentials/DeepOcrApi.credentials.d.ts.map +1 -0
- package/dist/credentials/DeepOcrApi.credentials.js +44 -0
- package/dist/credentials/DeepOcrApi.credentials.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/nodes/DeepOcr/DeepOcr.node.d.ts +12 -0
- package/dist/nodes/DeepOcr/DeepOcr.node.d.ts.map +1 -0
- package/dist/nodes/DeepOcr/DeepOcr.node.js +191 -0
- package/dist/nodes/DeepOcr/DeepOcr.node.js.map +1 -0
- package/dist/nodes/DeepOcr/DeepOcr.node.json +14 -0
- package/dist/nodes/DeepOcr/deepocr.svg +22 -0
- package/dist/utils/errors.d.ts +41 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +78 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +18 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +89 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Deep-OCR n8n Node Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# n8n-nodes-deep-ocr
|
|
2
|
+
|
|
3
|
+
N8N Community Node for the [Deep-OCR Service](https://deep-ocr.com) - Extract text and structured data from documents using AI-powered OCR.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/n8n-nodes-deep-ocr)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## 🚀 Features
|
|
9
|
+
|
|
10
|
+
- **Full Text Extraction**: Extract complete text content from documents
|
|
11
|
+
- **Structured Data Extraction**: Specify fields to extract and receive JSON with those values
|
|
12
|
+
- **Multiple Format Support**: PDF, PNG, JPG, JPEG, WebP (up to 10MB)
|
|
13
|
+
- **Secure Authentication**: API key stored securely using n8n credentials
|
|
14
|
+
|
|
15
|
+
## 📦 Installation
|
|
16
|
+
|
|
17
|
+
### Community Nodes (Recommended)
|
|
18
|
+
|
|
19
|
+
1. Go to **Settings** → **Community Nodes**
|
|
20
|
+
2. Click **Install a community node**
|
|
21
|
+
3. Enter `n8n-nodes-deep-ocr`
|
|
22
|
+
4. Click **Install**
|
|
23
|
+
|
|
24
|
+
### Manual Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install n8n-nodes-deep-ocr
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 🔧 Configuration
|
|
31
|
+
|
|
32
|
+
### Setting Up Credentials
|
|
33
|
+
|
|
34
|
+
1. Get your API key from [Deep-OCR Dashboard](https://app.deep-ocr.com)
|
|
35
|
+
2. In n8n, go to **Credentials** → **Add Credential**
|
|
36
|
+
3. Search for "Deep-OCR API"
|
|
37
|
+
4. Enter your API key and save
|
|
38
|
+
|
|
39
|
+
## 📖 Usage
|
|
40
|
+
|
|
41
|
+
### Extract Full Text
|
|
42
|
+
|
|
43
|
+
1. Add the **Deep-OCR** node to your workflow
|
|
44
|
+
2. Connect a node that provides binary data (e.g., Read Binary File, HTTP Request)
|
|
45
|
+
3. Configure:
|
|
46
|
+
- **Binary Property**: Name of the property containing your document (default: `data`)
|
|
47
|
+
- **Output Format**: Select `Text`
|
|
48
|
+
4. Execute to receive the extracted text
|
|
49
|
+
|
|
50
|
+
### Extract Structured Data
|
|
51
|
+
|
|
52
|
+
1. Add the **Deep-OCR** node to your workflow
|
|
53
|
+
2. Connect a node that provides binary data
|
|
54
|
+
3. Configure:
|
|
55
|
+
- **Binary Property**: Name of the property containing your document
|
|
56
|
+
- **Output Format**: Select `Structured`
|
|
57
|
+
- **Fields**: Comma-separated list of fields to extract (e.g., `sender, amount, date`)
|
|
58
|
+
4. Execute to receive a JSON object with the extracted fields
|
|
59
|
+
|
|
60
|
+
## 📋 Example Workflow
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"nodes": [
|
|
65
|
+
{
|
|
66
|
+
"name": "Read Invoice PDF",
|
|
67
|
+
"type": "n8n-nodes-base.readBinaryFile",
|
|
68
|
+
"parameters": {
|
|
69
|
+
"filePath": "/path/to/invoice.pdf"
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"name": "Extract Invoice Data",
|
|
74
|
+
"type": "n8n-nodes-deep-ocr.deepOcr",
|
|
75
|
+
"parameters": {
|
|
76
|
+
"binaryPropertyName": "data",
|
|
77
|
+
"outputFormat": "structured",
|
|
78
|
+
"fields": "sender, recipient, amount, date, invoice_number"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## 🔒 Supported File Types
|
|
86
|
+
|
|
87
|
+
| Format | MIME Type | Max Size |
|
|
88
|
+
| -------- | --------------- | -------- |
|
|
89
|
+
| PDF | application/pdf | 10MB |
|
|
90
|
+
| PNG | image/png | 10MB |
|
|
91
|
+
| JPG/JPEG | image/jpeg | 10MB |
|
|
92
|
+
| WebP | image/webp | 10MB |
|
|
93
|
+
|
|
94
|
+
## 🛠️ Development
|
|
95
|
+
|
|
96
|
+
This project was developed using [GitHub Spec-kit](https://github.com/github/spec-kit) (Spec-Driven Development).
|
|
97
|
+
|
|
98
|
+
### Prerequisites
|
|
99
|
+
|
|
100
|
+
- Node.js 18.10+
|
|
101
|
+
- pnpm 9.1+
|
|
102
|
+
|
|
103
|
+
### Setup
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Clone the repository
|
|
107
|
+
git clone https://github.com/h-teske/deep-ocr-n8n.git
|
|
108
|
+
cd deep-ocr-n8n
|
|
109
|
+
|
|
110
|
+
# Install dependencies
|
|
111
|
+
pnpm install
|
|
112
|
+
|
|
113
|
+
# Build
|
|
114
|
+
pnpm build
|
|
115
|
+
|
|
116
|
+
# Run tests
|
|
117
|
+
pnpm test
|
|
118
|
+
|
|
119
|
+
# Run linter
|
|
120
|
+
pnpm lint
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Project Structure
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
src/
|
|
127
|
+
├── credentials/
|
|
128
|
+
│ └── DeepOcrApi.credentials.ts # API key credential type
|
|
129
|
+
├── nodes/
|
|
130
|
+
│ └── DeepOcr/
|
|
131
|
+
│ ├── DeepOcr.node.ts # Main node implementation
|
|
132
|
+
│ └── deepocr.svg # Node icon
|
|
133
|
+
├── utils/
|
|
134
|
+
│ └── errors.ts # Error handling utilities
|
|
135
|
+
└── index.ts # Package entry point
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## 📄 License
|
|
139
|
+
|
|
140
|
+
MIT
|
|
141
|
+
|
|
142
|
+
## 🤝 Contributing
|
|
143
|
+
|
|
144
|
+
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.
|
|
145
|
+
|
|
146
|
+
## 📞 Support
|
|
147
|
+
|
|
148
|
+
- [GitHub Issues](https://github.com/h-teske/deep-ocr-n8n/issues)
|
|
149
|
+
- [Deep-OCR Documentation](https://docs.deep-ocr.com)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ICredentialType, INodeProperties, ICredentialTestRequest, IAuthenticateGeneric } from 'n8n-workflow';
|
|
2
|
+
/**
|
|
3
|
+
* Deep-OCR API Credentials
|
|
4
|
+
*
|
|
5
|
+
* Manages authentication with the Deep-OCR API using Bearer token.
|
|
6
|
+
* The API key is stored securely and sent in the Authorization header.
|
|
7
|
+
*/
|
|
8
|
+
export declare class DeepOcrApi implements ICredentialType {
|
|
9
|
+
name: string;
|
|
10
|
+
displayName: string;
|
|
11
|
+
documentationUrl: string;
|
|
12
|
+
properties: INodeProperties[];
|
|
13
|
+
authenticate: IAuthenticateGeneric;
|
|
14
|
+
test: ICredentialTestRequest;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=DeepOcrApi.credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeepOcrApi.credentials.d.ts","sourceRoot":"","sources":["../../src/credentials/DeepOcrApi.credentials.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,cAAc,CAAC;AAEtB;;;;;GAKG;AACH,qBAAa,UAAW,YAAW,eAAe;IAChD,IAAI,SAAgB;IACpB,WAAW,SAAkB;IAC7B,gBAAgB,SAA+B;IAE/C,UAAU,EAAE,eAAe,EAAE,CAY3B;IAEF,YAAY,EAAE,oBAAoB,CAOhC;IAEF,IAAI,EAAE,sBAAsB,CAM1B;CACH"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DeepOcrApi = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Deep-OCR API Credentials
|
|
6
|
+
*
|
|
7
|
+
* Manages authentication with the Deep-OCR API using Bearer token.
|
|
8
|
+
* The API key is stored securely and sent in the Authorization header.
|
|
9
|
+
*/
|
|
10
|
+
class DeepOcrApi {
|
|
11
|
+
name = 'deepOcrApi';
|
|
12
|
+
displayName = 'Deep-OCR API';
|
|
13
|
+
documentationUrl = 'https://docs.deep-ocr.com';
|
|
14
|
+
properties = [
|
|
15
|
+
{
|
|
16
|
+
displayName: 'API Key',
|
|
17
|
+
name: 'apiKey',
|
|
18
|
+
type: 'string',
|
|
19
|
+
typeOptions: {
|
|
20
|
+
password: true,
|
|
21
|
+
},
|
|
22
|
+
default: '',
|
|
23
|
+
required: true,
|
|
24
|
+
description: 'The API key for authenticating with Deep-OCR service',
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
authenticate = {
|
|
28
|
+
type: 'generic',
|
|
29
|
+
properties: {
|
|
30
|
+
headers: {
|
|
31
|
+
Authorization: '=Bearer {{$credentials.apiKey}}',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
test = {
|
|
36
|
+
request: {
|
|
37
|
+
baseURL: 'https://api.deep-ocr.com',
|
|
38
|
+
url: '/health',
|
|
39
|
+
method: 'GET',
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
exports.DeepOcrApi = DeepOcrApi;
|
|
44
|
+
//# sourceMappingURL=DeepOcrApi.credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeepOcrApi.credentials.js","sourceRoot":"","sources":["../../src/credentials/DeepOcrApi.credentials.ts"],"names":[],"mappings":";;;AAOA;;;;;GAKG;AACH,MAAa,UAAU;IACrB,IAAI,GAAG,YAAY,CAAC;IACpB,WAAW,GAAG,cAAc,CAAC;IAC7B,gBAAgB,GAAG,2BAA2B,CAAC;IAE/C,UAAU,GAAsB;QAC9B;YACE,WAAW,EAAE,SAAS;YACtB,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE;gBACX,QAAQ,EAAE,IAAI;aACf;YACD,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,sDAAsD;SACpE;KACF,CAAC;IAEF,YAAY,GAAyB;QACnC,IAAI,EAAE,SAAS;QACf,UAAU,EAAE;YACV,OAAO,EAAE;gBACP,aAAa,EAAE,iCAAiC;aACjD;SACF;KACF,CAAC;IAEF,IAAI,GAA2B;QAC7B,OAAO,EAAE;YACP,OAAO,EAAE,0BAA0B;YACnC,GAAG,EAAE,SAAS;YACd,MAAM,EAAE,KAAK;SACd;KACF,CAAC;CACH;AAnCD,gCAmCC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* n8n-nodes-deep-ocr
|
|
3
|
+
*
|
|
4
|
+
* Entry point for the Deep-OCR n8n community node package.
|
|
5
|
+
* Exports the node and credentials for n8n to discover.
|
|
6
|
+
*/
|
|
7
|
+
export { DeepOcr } from './nodes/DeepOcr/DeepOcr.node';
|
|
8
|
+
export { DeepOcrApi } from './credentials/DeepOcrApi.credentials';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAGvD,OAAO,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* n8n-nodes-deep-ocr
|
|
4
|
+
*
|
|
5
|
+
* Entry point for the Deep-OCR n8n community node package.
|
|
6
|
+
* Exports the node and credentials for n8n to discover.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.DeepOcrApi = exports.DeepOcr = void 0;
|
|
10
|
+
// Node exports
|
|
11
|
+
var DeepOcr_node_1 = require("./nodes/DeepOcr/DeepOcr.node");
|
|
12
|
+
Object.defineProperty(exports, "DeepOcr", { enumerable: true, get: function () { return DeepOcr_node_1.DeepOcr; } });
|
|
13
|
+
// Credential exports
|
|
14
|
+
var DeepOcrApi_credentials_1 = require("./credentials/DeepOcrApi.credentials");
|
|
15
|
+
Object.defineProperty(exports, "DeepOcrApi", { enumerable: true, get: function () { return DeepOcrApi_credentials_1.DeepOcrApi; } });
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,eAAe;AACf,6DAAuD;AAA9C,uGAAA,OAAO,OAAA;AAEhB,qBAAqB;AACrB,+EAAkE;AAAzD,oHAAA,UAAU,OAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
/**
|
|
3
|
+
* Deep-OCR Node
|
|
4
|
+
*
|
|
5
|
+
* Extract structured data from documents using the Deep-OCR API.
|
|
6
|
+
* Supports PDF, PNG, JPG, JPEG, and WebP formats up to 10MB.
|
|
7
|
+
*/
|
|
8
|
+
export declare class DeepOcr implements INodeType {
|
|
9
|
+
description: INodeTypeDescription;
|
|
10
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=DeepOcr.node.d.ts.map
|
|
@@ -0,0 +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,EAGrB,MAAM,cAAc,CAAC;AAgCtB;;;;;GAKG;AACH,qBAAa,OAAQ,YAAW,SAAS;IACvC,WAAW,EAAE,oBAAoB,CAyE/B;IAEI,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;CAqHxE"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DeepOcr = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const errors_1 = require("../../utils/errors");
|
|
6
|
+
const ALLOWED_DOCUMENT_TYPES = [
|
|
7
|
+
'contract',
|
|
8
|
+
'delivery_note',
|
|
9
|
+
'generic',
|
|
10
|
+
'handwriting',
|
|
11
|
+
'id_document',
|
|
12
|
+
'invoice',
|
|
13
|
+
'receipt',
|
|
14
|
+
];
|
|
15
|
+
/**
|
|
16
|
+
* Deep-OCR Node
|
|
17
|
+
*
|
|
18
|
+
* Extract structured data from documents using the Deep-OCR API.
|
|
19
|
+
* Supports PDF, PNG, JPG, JPEG, and WebP formats up to 10MB.
|
|
20
|
+
*/
|
|
21
|
+
class DeepOcr {
|
|
22
|
+
description = {
|
|
23
|
+
displayName: 'Deep-OCR',
|
|
24
|
+
name: 'deepOcr',
|
|
25
|
+
icon: 'file:deepocr.svg',
|
|
26
|
+
group: ['transform'],
|
|
27
|
+
version: 1,
|
|
28
|
+
subtitle: '={{$parameter["documentType"]}}',
|
|
29
|
+
description: 'Extract structured data from documents using Deep-OCR API',
|
|
30
|
+
defaults: {
|
|
31
|
+
name: 'Deep-OCR',
|
|
32
|
+
},
|
|
33
|
+
inputs: ['main'],
|
|
34
|
+
outputs: ['main'],
|
|
35
|
+
credentials: [
|
|
36
|
+
{
|
|
37
|
+
name: 'deepOcrApi',
|
|
38
|
+
required: true,
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
properties: [
|
|
42
|
+
{
|
|
43
|
+
displayName: 'Binary Property',
|
|
44
|
+
name: 'binaryPropertyName',
|
|
45
|
+
type: 'string',
|
|
46
|
+
default: 'data',
|
|
47
|
+
required: true,
|
|
48
|
+
description: 'Name of the binary property containing the document to process',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
displayName: 'Document Type',
|
|
52
|
+
name: 'documentType',
|
|
53
|
+
type: 'options',
|
|
54
|
+
options: [
|
|
55
|
+
{
|
|
56
|
+
name: 'Contract',
|
|
57
|
+
value: 'contract',
|
|
58
|
+
description: 'Extract parties, terms, and obligations from contracts',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: 'Delivery Note',
|
|
62
|
+
value: 'delivery_note',
|
|
63
|
+
description: 'Extract items, quantities, and delivery info from delivery notes',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'Generic',
|
|
67
|
+
value: 'generic',
|
|
68
|
+
description: 'Extract all detectable content from any document',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: 'Handwriting',
|
|
72
|
+
value: 'handwriting',
|
|
73
|
+
description: 'Transcribe handwritten text',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: 'ID Document',
|
|
77
|
+
value: 'id_document',
|
|
78
|
+
description: 'Extract personal data from passports and ID cards',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: 'Invoice',
|
|
82
|
+
value: 'invoice',
|
|
83
|
+
description: 'Extract vendor, line items, totals, and payment terms from invoices',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: 'Receipt',
|
|
87
|
+
value: 'receipt',
|
|
88
|
+
description: 'Extract merchant, items, and totals from receipts',
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
default: 'invoice',
|
|
92
|
+
description: 'Type of document — determines the extraction schema',
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
};
|
|
96
|
+
async execute() {
|
|
97
|
+
const items = this.getInputData();
|
|
98
|
+
const returnData = [];
|
|
99
|
+
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
|
100
|
+
try {
|
|
101
|
+
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', itemIndex, 'data');
|
|
102
|
+
const documentType = this.getNodeParameter('documentType', itemIndex, 'invoice');
|
|
103
|
+
// Validate documentType against known values (guards against crafted workflow JSON)
|
|
104
|
+
if (!ALLOWED_DOCUMENT_TYPES.includes(documentType)) {
|
|
105
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid document type: "${documentType}"`, { itemIndex });
|
|
106
|
+
}
|
|
107
|
+
// Get binary data
|
|
108
|
+
const binaryData = this.helpers.assertBinaryData(itemIndex, binaryPropertyName);
|
|
109
|
+
// Validate MIME type — reject undefined/empty to prevent silent bypass
|
|
110
|
+
if (!(0, errors_1.isValidMimeType)(binaryData.mimeType)) {
|
|
111
|
+
throw (0, errors_1.createFileTypeError)(this.getNode(), binaryData.mimeType ?? 'unknown', itemIndex);
|
|
112
|
+
}
|
|
113
|
+
// Early size check from metadata before loading the full buffer into memory (DoS prevention)
|
|
114
|
+
const metaSize = parseInt(binaryData.fileSize ?? '0', 10);
|
|
115
|
+
if (metaSize > 0 && !(0, errors_1.isValidFileSize)(metaSize)) {
|
|
116
|
+
throw (0, errors_1.createFileSizeError)(this.getNode(), metaSize, itemIndex);
|
|
117
|
+
}
|
|
118
|
+
// Load buffer
|
|
119
|
+
const buffer = await this.helpers.getBinaryDataBuffer(itemIndex, binaryPropertyName);
|
|
120
|
+
// Authoritative size check on actual buffer length
|
|
121
|
+
if (!(0, errors_1.isValidFileSize)(buffer.length)) {
|
|
122
|
+
throw (0, errors_1.createFileSizeError)(this.getNode(), buffer.length, itemIndex);
|
|
123
|
+
}
|
|
124
|
+
// Sanitize filename to prevent path traversal sequences in multipart headers
|
|
125
|
+
const rawFilename = binaryData.fileName ?? 'document';
|
|
126
|
+
const safeFilename = rawFilename
|
|
127
|
+
.replace(/\.\./g, '')
|
|
128
|
+
.replace(/[/\\]/g, '_')
|
|
129
|
+
.replace(/[<>:"|?*\x00-\x1f]/g, '')
|
|
130
|
+
.substring(0, 255) || 'document';
|
|
131
|
+
// Make API request — document_type as query param, file as multipart
|
|
132
|
+
// requestWithAuthentication (request-library) is used because httpRequestWithAuthentication
|
|
133
|
+
// (IHttpRequestOptions) does not support the formData property for multipart uploads.
|
|
134
|
+
const rawResponse = await this.helpers.requestWithAuthentication.call(this, 'deepOcrApi', {
|
|
135
|
+
method: 'POST',
|
|
136
|
+
url: 'https://api.deep-ocr.com/v1/ocr',
|
|
137
|
+
qs: { document_type: documentType },
|
|
138
|
+
formData: {
|
|
139
|
+
file: {
|
|
140
|
+
value: buffer,
|
|
141
|
+
options: {
|
|
142
|
+
filename: safeFilename,
|
|
143
|
+
contentType: binaryData.mimeType,
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
json: true,
|
|
148
|
+
});
|
|
149
|
+
// Validate response structure before accessing fields
|
|
150
|
+
if (rawResponse === null || rawResponse === undefined || typeof rawResponse !== 'object') {
|
|
151
|
+
throw new n8n_workflow_1.NodeApiError(this.getNode(), { message: 'Unexpected response format from Deep-OCR API' }, { itemIndex });
|
|
152
|
+
}
|
|
153
|
+
const response = rawResponse;
|
|
154
|
+
// API always returns structured JSON in response.content
|
|
155
|
+
const content = response.content ?? {};
|
|
156
|
+
returnData.push({
|
|
157
|
+
json: {
|
|
158
|
+
...content,
|
|
159
|
+
filename: response.filename,
|
|
160
|
+
document_type: response.document_type,
|
|
161
|
+
metadata: response.metadata,
|
|
162
|
+
},
|
|
163
|
+
pairedItem: { item: itemIndex },
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
if (this.continueOnFail()) {
|
|
168
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
169
|
+
returnData.push({
|
|
170
|
+
json: { error: errorMessage },
|
|
171
|
+
pairedItem: { item: itemIndex },
|
|
172
|
+
});
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (error instanceof n8n_workflow_1.NodeApiError || error instanceof n8n_workflow_1.NodeOperationError) {
|
|
176
|
+
throw error;
|
|
177
|
+
}
|
|
178
|
+
const errorObject = {
|
|
179
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
180
|
+
};
|
|
181
|
+
throw new n8n_workflow_1.NodeApiError(this.getNode(), errorObject, {
|
|
182
|
+
message: 'Failed to process document with Deep-OCR API',
|
|
183
|
+
itemIndex,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return [returnData];
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
exports.DeepOcr = DeepOcr;
|
|
191
|
+
//# sourceMappingURL=DeepOcr.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeepOcr.node.js","sourceRoot":"","sources":["../../../src/nodes/DeepOcr/DeepOcr.node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"node": "n8n-nodes-deep-ocr.deepOcr",
|
|
3
|
+
"nodeVersion": "1.0",
|
|
4
|
+
"codexVersion": "1.0",
|
|
5
|
+
"categories": ["AI", "Utility"],
|
|
6
|
+
"alias": ["OCR", "document", "invoice", "receipt", "scan", "extract", "pdf"],
|
|
7
|
+
"resources": {
|
|
8
|
+
"primaryDocumentation": [
|
|
9
|
+
{
|
|
10
|
+
"url": "https://docs.deep-ocr.com"
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
4
|
+
<stop offset="0%" style="stop-color:#4A90D9;stop-opacity:1" />
|
|
5
|
+
<stop offset="100%" style="stop-color:#2E5C8A;stop-opacity:1" />
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
<!-- Document background -->
|
|
9
|
+
<rect x="8" y="4" width="40" height="52" rx="3" ry="3" fill="#ffffff" stroke="#2E5C8A" stroke-width="2"/>
|
|
10
|
+
<!-- Document fold -->
|
|
11
|
+
<polygon points="38,4 48,14 38,14" fill="#E8F0F8" stroke="#2E5C8A" stroke-width="1"/>
|
|
12
|
+
<!-- Text lines -->
|
|
13
|
+
<rect x="14" y="20" width="28" height="3" fill="#4A90D9" rx="1"/>
|
|
14
|
+
<rect x="14" y="27" width="24" height="3" fill="#4A90D9" rx="1"/>
|
|
15
|
+
<rect x="14" y="34" width="26" height="3" fill="#4A90D9" rx="1"/>
|
|
16
|
+
<rect x="14" y="41" width="20" height="3" fill="#4A90D9" rx="1"/>
|
|
17
|
+
<!-- OCR scanning effect -->
|
|
18
|
+
<rect x="12" y="18" width="32" height="28" fill="none" stroke="url(#grad1)" stroke-width="2" stroke-dasharray="4,2" rx="2"/>
|
|
19
|
+
<!-- AI/Deep learning symbol -->
|
|
20
|
+
<circle cx="50" cy="46" r="12" fill="url(#grad1)"/>
|
|
21
|
+
<text x="50" y="51" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="white" text-anchor="middle">AI</text>
|
|
22
|
+
</svg>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { NodeApiError, NodeOperationError } from 'n8n-workflow';
|
|
2
|
+
import type { INode, JsonObject } from 'n8n-workflow';
|
|
3
|
+
/**
|
|
4
|
+
* Error codes for Deep-OCR operations
|
|
5
|
+
*/
|
|
6
|
+
export declare enum DeepOcrErrorCode {
|
|
7
|
+
INVALID_FILE_TYPE = "INVALID_FILE_TYPE",
|
|
8
|
+
FILE_TOO_LARGE = "FILE_TOO_LARGE",
|
|
9
|
+
MISSING_BINARY_DATA = "MISSING_BINARY_DATA",
|
|
10
|
+
API_ERROR = "API_ERROR",
|
|
11
|
+
AUTH_ERROR = "AUTH_ERROR"
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Maximum file size in bytes (10MB)
|
|
15
|
+
*/
|
|
16
|
+
export declare const MAX_FILE_SIZE: number;
|
|
17
|
+
/**
|
|
18
|
+
* Allowed MIME types for document processing
|
|
19
|
+
*/
|
|
20
|
+
export declare const ALLOWED_MIME_TYPES: string[];
|
|
21
|
+
/**
|
|
22
|
+
* Creates a NodeOperationError for invalid file types
|
|
23
|
+
*/
|
|
24
|
+
export declare function createFileTypeError(node: INode, mimeType: string, itemIndex?: number): NodeOperationError;
|
|
25
|
+
/**
|
|
26
|
+
* Creates a NodeOperationError for files exceeding size limit
|
|
27
|
+
*/
|
|
28
|
+
export declare function createFileSizeError(node: INode, sizeBytes: number, itemIndex?: number): NodeOperationError;
|
|
29
|
+
/**
|
|
30
|
+
* Creates a NodeApiError for API failures
|
|
31
|
+
*/
|
|
32
|
+
export declare function createApiError(node: INode, error: Error | JsonObject, itemIndex?: number): NodeApiError;
|
|
33
|
+
/**
|
|
34
|
+
* Validates MIME type against allowed types
|
|
35
|
+
*/
|
|
36
|
+
export declare function isValidMimeType(mimeType: string | undefined): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Validates file size against maximum limit
|
|
39
|
+
*/
|
|
40
|
+
export declare function isValidFileSize(sizeBytes: number): boolean;
|
|
41
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +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,UAAU,EAAE,MAAM,cAAc,CAAC;AAEtD;;GAEG;AACH,oBAAY,gBAAgB;IAC1B,iBAAiB,sBAAsB;IACvC,cAAc,mBAAmB;IACjC,mBAAmB,wBAAwB;IAC3C,SAAS,cAAc;IACvB,UAAU,eAAe;CAC1B;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,QAAmB,CAAC;AAE9C;;GAEG;AACH,eAAO,MAAM,kBAAkB,UAM9B,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;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,KAAK,GAAG,UAAU,EACzB,SAAS,CAAC,EAAE,MAAM,GACjB,YAAY,CAKd;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAKrE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE1D"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ALLOWED_MIME_TYPES = exports.MAX_FILE_SIZE = exports.DeepOcrErrorCode = void 0;
|
|
4
|
+
exports.createFileTypeError = createFileTypeError;
|
|
5
|
+
exports.createFileSizeError = createFileSizeError;
|
|
6
|
+
exports.createApiError = createApiError;
|
|
7
|
+
exports.isValidMimeType = isValidMimeType;
|
|
8
|
+
exports.isValidFileSize = isValidFileSize;
|
|
9
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
10
|
+
/**
|
|
11
|
+
* Error codes for Deep-OCR operations
|
|
12
|
+
*/
|
|
13
|
+
var DeepOcrErrorCode;
|
|
14
|
+
(function (DeepOcrErrorCode) {
|
|
15
|
+
DeepOcrErrorCode["INVALID_FILE_TYPE"] = "INVALID_FILE_TYPE";
|
|
16
|
+
DeepOcrErrorCode["FILE_TOO_LARGE"] = "FILE_TOO_LARGE";
|
|
17
|
+
DeepOcrErrorCode["MISSING_BINARY_DATA"] = "MISSING_BINARY_DATA";
|
|
18
|
+
DeepOcrErrorCode["API_ERROR"] = "API_ERROR";
|
|
19
|
+
DeepOcrErrorCode["AUTH_ERROR"] = "AUTH_ERROR";
|
|
20
|
+
})(DeepOcrErrorCode || (exports.DeepOcrErrorCode = DeepOcrErrorCode = {}));
|
|
21
|
+
/**
|
|
22
|
+
* Maximum file size in bytes (10MB)
|
|
23
|
+
*/
|
|
24
|
+
exports.MAX_FILE_SIZE = 10 * 1024 * 1024;
|
|
25
|
+
/**
|
|
26
|
+
* Allowed MIME types for document processing
|
|
27
|
+
*/
|
|
28
|
+
exports.ALLOWED_MIME_TYPES = [
|
|
29
|
+
'application/pdf',
|
|
30
|
+
'image/png',
|
|
31
|
+
'image/jpeg',
|
|
32
|
+
'image/jpg',
|
|
33
|
+
'image/webp',
|
|
34
|
+
];
|
|
35
|
+
/**
|
|
36
|
+
* Creates a NodeOperationError for invalid file types
|
|
37
|
+
*/
|
|
38
|
+
function createFileTypeError(node, mimeType, itemIndex) {
|
|
39
|
+
return new n8n_workflow_1.NodeOperationError(node, `Unsupported file type: ${mimeType}. Supported types: PDF, PNG, JPG, JPEG, WebP`, {
|
|
40
|
+
itemIndex,
|
|
41
|
+
description: `The file has MIME type "${mimeType}" which is not supported by the Deep-OCR API.`,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Creates a NodeOperationError for files exceeding size limit
|
|
46
|
+
*/
|
|
47
|
+
function createFileSizeError(node, sizeBytes, itemIndex) {
|
|
48
|
+
const sizeMB = Math.round(sizeBytes / 1024 / 1024);
|
|
49
|
+
return new n8n_workflow_1.NodeOperationError(node, `File size (${sizeMB}MB) exceeds maximum allowed size of 10MB`, {
|
|
50
|
+
itemIndex,
|
|
51
|
+
description: 'Please reduce the file size or use a smaller document.',
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Creates a NodeApiError for API failures
|
|
56
|
+
*/
|
|
57
|
+
function createApiError(node, error, itemIndex) {
|
|
58
|
+
return new n8n_workflow_1.NodeApiError(node, error, {
|
|
59
|
+
message: 'Failed to process document with Deep-OCR API',
|
|
60
|
+
itemIndex,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Validates MIME type against allowed types
|
|
65
|
+
*/
|
|
66
|
+
function isValidMimeType(mimeType) {
|
|
67
|
+
if (mimeType === undefined || mimeType.trim() === '') {
|
|
68
|
+
return false; // Reject files with no declared MIME type
|
|
69
|
+
}
|
|
70
|
+
return exports.ALLOWED_MIME_TYPES.includes(mimeType);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Validates file size against maximum limit
|
|
74
|
+
*/
|
|
75
|
+
function isValidFileSize(sizeBytes) {
|
|
76
|
+
return sizeBytes <= exports.MAX_FILE_SIZE;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":";;;AAiCA,kDAaC;AAKD,kDAcC;AAKD,wCASC;AAKD,0CAKC;AAKD,0CAEC;AAhGD,+CAAgE;AAGhE;;GAEG;AACH,IAAY,gBAMX;AAND,WAAY,gBAAgB;IAC1B,2DAAuC,CAAA;IACvC,qDAAiC,CAAA;IACjC,+DAA2C,CAAA;IAC3C,2CAAuB,CAAA;IACvB,6CAAyB,CAAA;AAC3B,CAAC,EANW,gBAAgB,gCAAhB,gBAAgB,QAM3B;AAED;;GAEG;AACU,QAAA,aAAa,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAE9C;;GAEG;AACU,QAAA,kBAAkB,GAAG;IAChC,iBAAiB;IACjB,WAAW;IACX,YAAY;IACZ,WAAW;IACX,YAAY;CACb,CAAC;AAEF;;GAEG;AACH,SAAgB,mBAAmB,CACjC,IAAW,EACX,QAAgB,EAChB,SAAkB;IAElB,OAAO,IAAI,iCAAkB,CAC3B,IAAI,EACJ,0BAA0B,QAAQ,8CAA8C,EAChF;QACE,SAAS;QACT,WAAW,EAAE,2BAA2B,QAAQ,+CAA+C;KAChG,CACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CACjC,IAAW,EACX,SAAiB,EACjB,SAAkB;IAElB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;IACnD,OAAO,IAAI,iCAAkB,CAC3B,IAAI,EACJ,cAAc,MAAM,0CAA0C,EAC9D;QACE,SAAS;QACT,WAAW,EAAE,wDAAwD;KACtE,CACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAC5B,IAAW,EACX,KAAyB,EACzB,SAAkB;IAElB,OAAO,IAAI,2BAAY,CAAC,IAAI,EAAE,KAAmB,EAAE;QACjD,OAAO,EAAE,8CAA8C;QACvD,SAAS;KACV,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,QAA4B;IAC1D,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,OAAO,KAAK,CAAC,CAAC,0CAA0C;IAC1D,CAAC;IACD,OAAO,0BAAkB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,SAAiB;IAC/C,OAAO,SAAS,IAAI,qBAAa,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./errors"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB"}
|
package/package.json
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "n8n-nodes-deep-ocr",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "n8n community node for Deep-OCR document processing API",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"n8n-community-node-package",
|
|
7
|
+
"n8n",
|
|
8
|
+
"ocr",
|
|
9
|
+
"deep-ocr",
|
|
10
|
+
"document-processing",
|
|
11
|
+
"text-extraction",
|
|
12
|
+
"structured-data"
|
|
13
|
+
],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"homepage": "https://github.com/h-teske/deep-ocr-n8n",
|
|
16
|
+
"author": {
|
|
17
|
+
"name": "Deep-OCR n8n Node Contributors"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/h-teske/deep-ocr-n8n.git"
|
|
22
|
+
},
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=22.0",
|
|
25
|
+
"pnpm": ">=9.1"
|
|
26
|
+
},
|
|
27
|
+
"packageManager": "pnpm@10.32.1",
|
|
28
|
+
"main": "dist/index.js",
|
|
29
|
+
"types": "dist/index.d.ts",
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsc && gulp build:icons && gulp build:codex",
|
|
32
|
+
"dev": "tsc --watch",
|
|
33
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
34
|
+
"lint": "eslint src",
|
|
35
|
+
"lint:fix": "eslint src --fix",
|
|
36
|
+
"lint:n8n": "npx @n8n/scan-community-package ./dist",
|
|
37
|
+
"test": "jest",
|
|
38
|
+
"test:watch": "jest --watch",
|
|
39
|
+
"test:coverage": "jest --coverage",
|
|
40
|
+
"prepublishOnly": "pnpm run build"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"dist"
|
|
44
|
+
],
|
|
45
|
+
"n8n": {
|
|
46
|
+
"n8nNodesApiVersion": 1,
|
|
47
|
+
"credentials": [
|
|
48
|
+
"dist/credentials/DeepOcrApi.credentials.js"
|
|
49
|
+
],
|
|
50
|
+
"nodes": [
|
|
51
|
+
"dist/nodes/DeepOcr/DeepOcr.node.js"
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@eslint/eslintrc": "^3.0.0",
|
|
56
|
+
"@types/jest": "^30.0.0",
|
|
57
|
+
"@types/node": "^24.0.0",
|
|
58
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
59
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
60
|
+
"eslint": "^9.0.0",
|
|
61
|
+
"eslint-config-prettier": "^10.0.0",
|
|
62
|
+
"eslint-plugin-n8n-nodes-base": "^1.16.0",
|
|
63
|
+
"gulp": "^5.0.0",
|
|
64
|
+
"jest": "^30.0.0",
|
|
65
|
+
"jest-mock-extended": "^4.0.0",
|
|
66
|
+
"n8n-core": "^2.0.0",
|
|
67
|
+
"n8n-workflow": "^2.0.0",
|
|
68
|
+
"prettier": "^3.2.0",
|
|
69
|
+
"ts-jest": "^29.1.2",
|
|
70
|
+
"typescript": "^5.4.0"
|
|
71
|
+
},
|
|
72
|
+
"peerDependencies": {
|
|
73
|
+
"n8n-workflow": "^1.0.0 || ^2.0.0"
|
|
74
|
+
},
|
|
75
|
+
"pnpm": {
|
|
76
|
+
"overrides": {
|
|
77
|
+
"form-data": ">=4.0.4",
|
|
78
|
+
"fast-xml-parser": ">=4.5.4",
|
|
79
|
+
"minimatch": ">=3.1.4 <11.0.0",
|
|
80
|
+
"braces": ">=3.0.3",
|
|
81
|
+
"micromatch": ">=4.0.8",
|
|
82
|
+
"axios": ">=1.13.6",
|
|
83
|
+
"ajv": ">=6.14.0 <9.0.0",
|
|
84
|
+
"jws": ">=3.2.3",
|
|
85
|
+
"qs": ">=6.14.1",
|
|
86
|
+
"lodash": ">=4.17.23"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|