n8n-nodes-html-readability 0.1.0 ā 0.1.1
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 +1 -1
- package/dist/nodes/Readability/Readability.node.js +72 -127
- package/package.json +6 -7
- package/dist/package.json +0 -64
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|

|
|
2
2
|
|
|
3
|
-
# n8n-nodes-readability
|
|
3
|
+
# n8n-nodes-html-readability
|
|
4
4
|
|
|
5
5
|
This is an n8n community node. It lets you use Mozilla's Readability in your n8n workflows.
|
|
6
6
|
|
|
@@ -21,81 +21,44 @@ class Readability {
|
|
|
21
21
|
outputs: ["main"],
|
|
22
22
|
properties: [
|
|
23
23
|
{
|
|
24
|
-
displayName: '
|
|
25
|
-
name: 'resource',
|
|
26
|
-
type: 'options',
|
|
27
|
-
noDataExpression: true,
|
|
28
|
-
options: [
|
|
29
|
-
{
|
|
30
|
-
name: 'HTML',
|
|
31
|
-
value: 'html',
|
|
32
|
-
},
|
|
33
|
-
],
|
|
34
|
-
default: 'html',
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
displayName: 'Operation',
|
|
38
|
-
name: 'operation',
|
|
39
|
-
type: 'options',
|
|
40
|
-
noDataExpression: true,
|
|
41
|
-
displayOptions: {
|
|
42
|
-
show: {
|
|
43
|
-
resource: ['html'],
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
options: [
|
|
47
|
-
{
|
|
48
|
-
name: 'Extract Content',
|
|
49
|
-
value: 'extract',
|
|
50
|
-
description: 'Wether to extract readable content from HTML',
|
|
51
|
-
action: 'Extract readable content from HTML',
|
|
52
|
-
},
|
|
53
|
-
],
|
|
54
|
-
default: 'extract',
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
displayName: 'JSON Property',
|
|
24
|
+
displayName: 'HTML Field',
|
|
58
25
|
name: 'htmlField',
|
|
59
26
|
type: 'string',
|
|
60
|
-
default: '
|
|
27
|
+
default: '',
|
|
61
28
|
required: true,
|
|
62
|
-
|
|
63
|
-
show: {
|
|
64
|
-
resource: ['html'],
|
|
65
|
-
operation: ['extract'],
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
description: 'The name of the JSON property containing the HTML content to parse (supports dot notation and expressions)',
|
|
29
|
+
description: 'The field containing the HTML content to parse',
|
|
69
30
|
noDataExpression: false,
|
|
70
31
|
},
|
|
71
32
|
{
|
|
72
|
-
displayName: '
|
|
73
|
-
name: '
|
|
74
|
-
type: '
|
|
75
|
-
placeholder: 'Add Option',
|
|
76
|
-
default: {},
|
|
77
|
-
displayOptions: {
|
|
78
|
-
show: {
|
|
79
|
-
resource: ['html'],
|
|
80
|
-
operation: ['extract'],
|
|
81
|
-
},
|
|
82
|
-
},
|
|
33
|
+
displayName: 'Error Handling',
|
|
34
|
+
name: 'errorHandling',
|
|
35
|
+
type: 'options',
|
|
83
36
|
options: [
|
|
84
37
|
{
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
38
|
+
name: 'Pass Through',
|
|
39
|
+
value: 'passThrough',
|
|
40
|
+
description: 'Pass through the input if HTML is invalid',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'Output Empty',
|
|
44
|
+
value: 'outputEmpty',
|
|
45
|
+
description: 'Output empty content if HTML is invalid',
|
|
90
46
|
},
|
|
91
47
|
{
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
default: false,
|
|
96
|
-
description: 'Whether to return the full response from Readability (includes metadata)',
|
|
48
|
+
name: 'Throw Error',
|
|
49
|
+
value: 'throwError',
|
|
50
|
+
description: 'Stop execution with error if HTML is invalid',
|
|
97
51
|
},
|
|
98
52
|
],
|
|
53
|
+
default: 'throwError',
|
|
54
|
+
description: 'How to handle invalid HTML content',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
displayName: 'Return Full Response',
|
|
58
|
+
name: 'fullResponse',
|
|
59
|
+
type: 'boolean',
|
|
60
|
+
default: false,
|
|
61
|
+
description: 'Whether to return the full response from Readability (includes metadata)',
|
|
99
62
|
},
|
|
100
63
|
],
|
|
101
64
|
};
|
|
@@ -106,72 +69,54 @@ class Readability {
|
|
|
106
69
|
return [[]];
|
|
107
70
|
}
|
|
108
71
|
const returnData = [];
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
htmlContent = item.json;
|
|
124
|
-
for (const part of pathParts) {
|
|
125
|
-
if (htmlContent && typeof htmlContent === 'object' && part in htmlContent) {
|
|
126
|
-
htmlContent = htmlContent[part];
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
htmlContent = undefined;
|
|
130
|
-
break;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
htmlContent = item.json[htmlField];
|
|
136
|
-
}
|
|
137
|
-
if (!htmlContent) {
|
|
138
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `No HTML found in field "${htmlField}" for item ${i}`);
|
|
139
|
-
}
|
|
140
|
-
const dom = new jsdom_1.JSDOM(htmlContent);
|
|
141
|
-
const reader = new readability_1.Readability(dom.window.document);
|
|
142
|
-
const article = reader.parse();
|
|
143
|
-
if (!article) {
|
|
144
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Failed to extract content');
|
|
145
|
-
}
|
|
146
|
-
if (options.fullResponse) {
|
|
147
|
-
returnData.push({
|
|
148
|
-
json: {
|
|
149
|
-
...article,
|
|
150
|
-
},
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
returnData.push({
|
|
155
|
-
json: {
|
|
156
|
-
content: article.content,
|
|
157
|
-
title: article.title,
|
|
158
|
-
excerpt: article.excerpt,
|
|
159
|
-
},
|
|
160
|
-
});
|
|
161
|
-
}
|
|
72
|
+
for (let i = 0; i < items.length; i++) {
|
|
73
|
+
const errorHandling = this.getNodeParameter('errorHandling', i, 'throwError');
|
|
74
|
+
const fullResponse = this.getNodeParameter('fullResponse', i, false);
|
|
75
|
+
try {
|
|
76
|
+
const item = items[i];
|
|
77
|
+
if (!(item === null || item === void 0 ? void 0 : item.json)) {
|
|
78
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Item ${i} has no JSON data`, { itemIndex: i });
|
|
79
|
+
}
|
|
80
|
+
const htmlContent = this.getNodeParameter('htmlField', i);
|
|
81
|
+
const dom = new jsdom_1.JSDOM(htmlContent);
|
|
82
|
+
const reader = new readability_1.Readability(dom.window.document);
|
|
83
|
+
const article = reader.parse();
|
|
84
|
+
if (!article) {
|
|
85
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Failed to extract content');
|
|
162
86
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
87
|
+
if (fullResponse) {
|
|
88
|
+
returnData.push({
|
|
89
|
+
json: {
|
|
90
|
+
...article,
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
returnData.push({
|
|
96
|
+
json: {
|
|
97
|
+
content: article.content,
|
|
98
|
+
title: article.title,
|
|
99
|
+
excerpt: article.excerpt,
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
if (errorHandling === 'passThrough') {
|
|
106
|
+
returnData.push(items[i]);
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (errorHandling === 'outputEmpty') {
|
|
110
|
+
returnData.push({
|
|
111
|
+
json: {
|
|
112
|
+
content: '',
|
|
113
|
+
title: '',
|
|
114
|
+
excerpt: '',
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
continue;
|
|
174
118
|
}
|
|
119
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Error processing HTML: ${error.message}`, { itemIndex: i });
|
|
175
120
|
}
|
|
176
121
|
}
|
|
177
122
|
return [returnData];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-html-readability",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "n8n node to extract readable content from HTML using Mozilla Readability",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"n8n-community-node-package"
|
|
@@ -24,7 +24,9 @@
|
|
|
24
24
|
"scripts": {
|
|
25
25
|
"preinstall": "npx only-allow pnpm",
|
|
26
26
|
"build": "tsc && gulp build:icons",
|
|
27
|
-
"dev": "
|
|
27
|
+
"dev:setup": "pnpm run build && npm link && mkdir -p ~/.n8n/custom && cd ~/.n8n/custom && npm link n8n-nodes-html-readability",
|
|
28
|
+
"dev": "pnpm run dev:setup && echo '\nš Setup complete! Now:\n1. Start debugging in VS Code (F5) to run n8n\n2. Open http://localhost:5678 in your browser\n3. Search for \"Readability\" in the nodes panel' && tsc --watch",
|
|
29
|
+
"watch": "tsc --watch",
|
|
28
30
|
"format": "prettier nodes --write",
|
|
29
31
|
"lint": "eslint nodes package.json",
|
|
30
32
|
"lintfix": "eslint nodes package.json --fix",
|
|
@@ -34,10 +36,7 @@
|
|
|
34
36
|
"dist/nodes/Readability/**/*.js",
|
|
35
37
|
"dist/nodes/Readability/**/*.d.ts",
|
|
36
38
|
"dist/nodes/Readability/**/*.json",
|
|
37
|
-
"dist/nodes/Readability/**/*.svg"
|
|
38
|
-
"dist/package.json",
|
|
39
|
-
"LICENSE.md",
|
|
40
|
-
"README.md"
|
|
39
|
+
"dist/nodes/Readability/**/*.svg"
|
|
41
40
|
],
|
|
42
41
|
"n8n": {
|
|
43
42
|
"n8nNodesApiVersion": 1,
|
|
@@ -46,9 +45,9 @@
|
|
|
46
45
|
]
|
|
47
46
|
},
|
|
48
47
|
"devDependencies": {
|
|
48
|
+
"@types/jsdom": "^21.1.0",
|
|
49
49
|
"@typescript-eslint/parser": "^7.15.0",
|
|
50
50
|
"eslint": "^8.56.0",
|
|
51
|
-
"@types/jsdom": "^21.1.0",
|
|
52
51
|
"eslint-plugin-n8n-nodes-base": "^1.16.1",
|
|
53
52
|
"gulp": "^4.0.2",
|
|
54
53
|
"prettier": "^3.3.2",
|
package/dist/package.json
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "n8n-nodes-html-readability",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"description": "n8n node to extract readable content from HTML using Mozilla Readability",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"n8n-community-node-package"
|
|
7
|
-
],
|
|
8
|
-
"license": "MIT",
|
|
9
|
-
"homepage": "https://github.com/TechupBusiness/n8n-nodes-html-readability",
|
|
10
|
-
"author": {
|
|
11
|
-
"name": "Techup Business",
|
|
12
|
-
"email": "info@techupbusiness.com"
|
|
13
|
-
},
|
|
14
|
-
"repository": {
|
|
15
|
-
"type": "git",
|
|
16
|
-
"url": "https://github.com/TechupBusiness/n8n-nodes-html-readability.git"
|
|
17
|
-
},
|
|
18
|
-
"engines": {
|
|
19
|
-
"node": ">=18.10",
|
|
20
|
-
"pnpm": ">=9.1"
|
|
21
|
-
},
|
|
22
|
-
"packageManager": "pnpm@9.1.4",
|
|
23
|
-
"main": "index.js",
|
|
24
|
-
"scripts": {
|
|
25
|
-
"preinstall": "npx only-allow pnpm",
|
|
26
|
-
"build": "tsc && gulp build:icons",
|
|
27
|
-
"dev": "tsc --watch",
|
|
28
|
-
"format": "prettier nodes --write",
|
|
29
|
-
"lint": "eslint nodes package.json",
|
|
30
|
-
"lintfix": "eslint nodes package.json --fix",
|
|
31
|
-
"prepublishOnly": "pnpm build && pnpm lint -c .eslintrc.prepublish.js nodes package.json"
|
|
32
|
-
},
|
|
33
|
-
"files": [
|
|
34
|
-
"dist/nodes/Readability/**/*.js",
|
|
35
|
-
"dist/nodes/Readability/**/*.d.ts",
|
|
36
|
-
"dist/nodes/Readability/**/*.json",
|
|
37
|
-
"dist/nodes/Readability/**/*.svg",
|
|
38
|
-
"dist/package.json",
|
|
39
|
-
"LICENSE.md",
|
|
40
|
-
"README.md"
|
|
41
|
-
],
|
|
42
|
-
"n8n": {
|
|
43
|
-
"n8nNodesApiVersion": 1,
|
|
44
|
-
"nodes": [
|
|
45
|
-
"dist/nodes/Readability/Readability.node.js"
|
|
46
|
-
]
|
|
47
|
-
},
|
|
48
|
-
"devDependencies": {
|
|
49
|
-
"@typescript-eslint/parser": "^7.15.0",
|
|
50
|
-
"eslint": "^8.56.0",
|
|
51
|
-
"@types/jsdom": "^21.1.0",
|
|
52
|
-
"eslint-plugin-n8n-nodes-base": "^1.16.1",
|
|
53
|
-
"gulp": "^4.0.2",
|
|
54
|
-
"prettier": "^3.3.2",
|
|
55
|
-
"typescript": "^5.5.3"
|
|
56
|
-
},
|
|
57
|
-
"dependencies": {
|
|
58
|
-
"@mozilla/readability": "^0.6.0",
|
|
59
|
-
"jsdom": "^22.1.0"
|
|
60
|
-
},
|
|
61
|
-
"peerDependencies": {
|
|
62
|
-
"n8n-workflow": "*"
|
|
63
|
-
}
|
|
64
|
-
}
|