@finlight/n8n-nodes-finlight 0.1.2 → 0.1.4

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,217 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FinlightArticleSearch = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ class FinlightArticleSearch {
6
+ constructor() {
7
+ this.description = {
8
+ displayName: "finlight Article Search",
9
+ name: "finlightArticleSearch",
10
+ group: ["transform"],
11
+ version: 1,
12
+ description: "Search articles using the finlight REST API",
13
+ defaults: {
14
+ name: "finlight Article Search",
15
+ },
16
+ inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
17
+ outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
18
+ icon: "file:../finlight.svg",
19
+ credentials: [
20
+ {
21
+ name: "finlightApi",
22
+ required: true,
23
+ },
24
+ ],
25
+ properties: [
26
+ {
27
+ displayName: "Query",
28
+ name: "query",
29
+ type: "string",
30
+ required: false,
31
+ default: "",
32
+ },
33
+ {
34
+ displayName: "Sources",
35
+ name: "sources",
36
+ type: "fixedCollection",
37
+ placeholder: "Add Source",
38
+ default: {},
39
+ typeOptions: {
40
+ multipleValues: true,
41
+ },
42
+ options: [
43
+ {
44
+ name: "sourceList",
45
+ displayName: "Source List",
46
+ values: [
47
+ {
48
+ displayName: "Source",
49
+ name: "source",
50
+ type: "string",
51
+ default: "",
52
+ },
53
+ ],
54
+ },
55
+ ],
56
+ },
57
+ {
58
+ displayName: "Exclude Sources",
59
+ name: "excludeSources",
60
+ type: "fixedCollection",
61
+ placeholder: "Exclude Source",
62
+ default: {},
63
+ typeOptions: {
64
+ multipleValues: true,
65
+ },
66
+ options: [
67
+ {
68
+ name: "sourceList",
69
+ displayName: "Source List",
70
+ values: [
71
+ {
72
+ displayName: "Source",
73
+ name: "source",
74
+ type: "string",
75
+ default: "",
76
+ },
77
+ ],
78
+ },
79
+ ],
80
+ },
81
+ {
82
+ displayName: "From (ISO date)",
83
+ name: "from",
84
+ type: "string",
85
+ default: "",
86
+ },
87
+ {
88
+ displayName: "To (ISO date)",
89
+ name: "to",
90
+ type: "string",
91
+ default: "",
92
+ },
93
+ {
94
+ displayName: "Language",
95
+ name: "language",
96
+ type: "string",
97
+ default: "en",
98
+ },
99
+ {
100
+ displayName: "Order",
101
+ name: "order",
102
+ type: "options",
103
+ options: [
104
+ { name: "DESC", value: "DESC" },
105
+ { name: "ASC", value: "ASC" },
106
+ ],
107
+ default: "DESC",
108
+ },
109
+ {
110
+ displayName: "Page Size",
111
+ name: "pageSize",
112
+ type: "number",
113
+ default: 20,
114
+ typeOptions: { minValue: 1, maxValue: 100 },
115
+ },
116
+ {
117
+ displayName: "Page",
118
+ name: "page",
119
+ type: "number",
120
+ default: 1,
121
+ typeOptions: { minValue: 1 },
122
+ },
123
+ {
124
+ displayName: "Include Content",
125
+ name: "includeContent",
126
+ type: "boolean",
127
+ default: false,
128
+ },
129
+ {
130
+ displayName: "Include Entities",
131
+ name: "includeEntities",
132
+ type: "boolean",
133
+ default: false,
134
+ },
135
+ {
136
+ displayName: "Exclude Empty Content",
137
+ name: "excludeEmptyContent",
138
+ type: "boolean",
139
+ default: false,
140
+ },
141
+ {
142
+ displayName: "Tickers",
143
+ name: "tickers",
144
+ type: "fixedCollection",
145
+ placeholder: "Add Ticker",
146
+ default: {},
147
+ typeOptions: {
148
+ multipleValues: true,
149
+ },
150
+ options: [
151
+ {
152
+ name: "tickerList",
153
+ displayName: "Ticker List",
154
+ values: [
155
+ {
156
+ displayName: "Ticker",
157
+ name: "ticker",
158
+ type: "string",
159
+ default: "",
160
+ },
161
+ ],
162
+ },
163
+ ],
164
+ },
165
+ ],
166
+ };
167
+ }
168
+ async execute() {
169
+ const items = this.getInputData();
170
+ const returnData = [];
171
+ const apiKey = (await this.getCredentials("finlightApi"));
172
+ for (let i = 0; i < items.length; i++) {
173
+ const body = {};
174
+ const query = this.getNodeParameter("query", i);
175
+ if (query)
176
+ body.query = query;
177
+ const from = this.getNodeParameter("from", i);
178
+ if (from)
179
+ body.from = from;
180
+ const to = this.getNodeParameter("to", i);
181
+ if (to)
182
+ body.to = to;
183
+ const sourcesRaw = this.getNodeParameter("sources.sourceList", i, []);
184
+ if (sourcesRaw.length) {
185
+ body.sources = sourcesRaw.map(s => s.source);
186
+ }
187
+ const excludeSourcesRaw = this.getNodeParameter("excludeSources.sourceList", i, []);
188
+ if (excludeSourcesRaw.length) {
189
+ body.excludeSources = excludeSourcesRaw.map(s => s.source);
190
+ }
191
+ const tickersRaw = this.getNodeParameter("tickers.tickerList", i, []);
192
+ if (tickersRaw.length) {
193
+ body.tickers = tickersRaw.map(t => t.ticker);
194
+ }
195
+ body.language = this.getNodeParameter("language", i);
196
+ body.order = this.getNodeParameter("order", i);
197
+ body.pageSize = this.getNodeParameter("pageSize", i);
198
+ body.page = this.getNodeParameter("page", i);
199
+ body.includeContent = this.getNodeParameter("includeContent", i);
200
+ body.includeEntities = this.getNodeParameter("includeEntities", i);
201
+ body.excludeEmptyContent = this.getNodeParameter("excludeEmptyContent", i);
202
+ const response = await this.helpers.httpRequest({
203
+ method: "POST",
204
+ url: "https://api.finlight.me/v2/articles",
205
+ headers: {
206
+ "Content-Type": "application/json",
207
+ "x-api-key": apiKey.apiKey,
208
+ },
209
+ body,
210
+ json: true,
211
+ });
212
+ returnData.push(...(Array.isArray(response.articles) ? response.articles : [response]));
213
+ }
214
+ return [this.helpers.returnJsonArray(returnData)];
215
+ }
216
+ }
217
+ exports.FinlightArticleSearch = FinlightArticleSearch;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FinlightApi = void 0;
4
+ class FinlightApi {
5
+ constructor() {
6
+ this.name = "finlightApi";
7
+ this.displayName = "finlight API Key";
8
+ this.properties = [
9
+ {
10
+ displayName: "API Key",
11
+ name: "apiKey",
12
+ type: "string",
13
+ default: "",
14
+ },
15
+ ];
16
+ this.test = {
17
+ request: {
18
+ baseURL: "https://api.finlight.me/",
19
+ url: "v2/articles",
20
+ method: "POST",
21
+ headers: {
22
+ "Content-Type": "application/json",
23
+ "x-api-key": "={{$credentials.apiKey}}",
24
+ },
25
+ body: {
26
+ pageSize: 1,
27
+ page: 1,
28
+ },
29
+ },
30
+ };
31
+ }
32
+ }
33
+ exports.FinlightApi = FinlightApi;
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="132.6951 99.9025 29.2313 60.7847" width="29.2313px" height="60.7847px"><g id="Ebene_1-2" transform="matrix(1.95135498046875, 0, 0, 1.95135498046875, 162.93136596679688, 190.97030639648438)"><path d="M -2.045 -45.889 C -3.065 -46.409 -4.545 -46.669 -6.465 -46.669 C -8.235 -46.669 -9.805 -46.389 -11.165 -45.819 C -12.525 -45.249 -13.585 -44.379 -14.345 -43.189 C -15.105 -41.999 -15.495 -40.439 -15.495 -38.519 L -15.495 -17.949 C -15.495 -17.059 -15.255 -16.439 -14.785 -16.069 C -14.315 -15.699 -13.585 -15.519 -12.605 -15.519 C -12.085 -15.519 -11.615 -15.559 -11.185 -15.629 C -10.755 -15.699 -10.425 -15.789 -10.175 -15.879 L -10.175 -31.819 L -3.255 -31.819 C -2.675 -31.819 -2.215 -31.989 -1.885 -32.319 C -1.545 -32.659 -1.385 -33.189 -1.385 -33.919 C -1.385 -34.379 -1.445 -34.779 -1.565 -35.129 C -1.685 -35.479 -1.815 -35.759 -1.935 -35.979 L -10.365 -35.979 L -10.365 -38.269 C -10.365 -39.739 -9.995 -40.779 -9.265 -41.409 C -8.535 -42.039 -7.355 -42.349 -5.735 -42.349 C -4.945 -42.349 -4.175 -42.269 -3.425 -42.119 C -2.675 -41.969 -2.025 -41.769 -1.475 -41.519 C -1.205 -41.759 -0.975 -42.059 -0.785 -42.409 C -0.605 -42.759 -0.515 -43.169 -0.515 -43.619 C -0.515 -44.599 -1.025 -45.349 -2.055 -45.869 L -2.045 -45.889 Z"/></g></svg>
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAuthHeaders = getAuthHeaders;
4
+ function getAuthHeaders(params) {
5
+ const headers = {};
6
+ if (params.authentication === "apiKey" && params.apiKey) {
7
+ headers["x-finlight-key"] = params.apiKey;
8
+ }
9
+ if (params.authentication === "basicAuth" && params.credentials) {
10
+ const token = Buffer.from(`${params.credentials.user}:${params.credentials.password}`).toString("base64");
11
+ headers["Authorization"] = `Basic ${token}`;
12
+ }
13
+ return headers;
14
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.nodes = void 0;
4
+ const FinlightWebhookTrigger_node_1 = require("./triggers/FinlightWebhookTrigger.node");
5
+ const FinlightArticleSearch_node_1 = require("./actions/FinlightArticleSearch.node");
6
+ exports.nodes = [FinlightWebhookTrigger_node_1.FinlightWebhookTrigger, FinlightArticleSearch_node_1.FinlightArticleSearch];
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FinlightWebhookTrigger = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ class FinlightWebhookTrigger {
6
+ constructor() {
7
+ this.description = {
8
+ displayName: "finlight Webhook Trigger",
9
+ name: "finlightWebhookTrigger",
10
+ group: ["trigger"],
11
+ version: 1,
12
+ description: "Triggers on new webhook events from finlight",
13
+ defaults: {
14
+ name: "finlight Webhook Trigger",
15
+ },
16
+ inputs: [],
17
+ outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
18
+ credentials: [
19
+ {
20
+ name: "finlightApi",
21
+ required: true,
22
+ displayOptions: {
23
+ show: {
24
+ authentication: ["apiKey"],
25
+ },
26
+ },
27
+ },
28
+ {
29
+ name: "httpBasicAuth",
30
+ required: true,
31
+ displayOptions: {
32
+ show: {
33
+ authentication: ["basicAuth"],
34
+ },
35
+ },
36
+ },
37
+ ],
38
+ properties: [
39
+ {
40
+ displayName: "Authentication Method",
41
+ name: "authentication",
42
+ type: "options",
43
+ options: [
44
+ { name: "API Key Header (x-finlight-key)", value: "apiKey" },
45
+ { name: "Basic Auth", value: "basicAuth" },
46
+ { name: "None", value: "none" },
47
+ ],
48
+ default: "apiKey",
49
+ },
50
+ ],
51
+ webhooks: [
52
+ {
53
+ name: "default",
54
+ httpMethod: "POST",
55
+ responseMode: "onReceived",
56
+ path: "finlight",
57
+ },
58
+ ],
59
+ documentationUrl: "https://docs.finlight.me",
60
+ icon: "file:../finlight.svg",
61
+ };
62
+ this.webhookMethods = {
63
+ default: {
64
+ async checkExists() {
65
+ return true;
66
+ },
67
+ async create() {
68
+ return true;
69
+ },
70
+ async delete() {
71
+ return true;
72
+ },
73
+ },
74
+ };
75
+ }
76
+ async webhook() {
77
+ const req = this.getRequestObject();
78
+ const headers = req.headers;
79
+ const body = req.body;
80
+ const authMethod = this.getNodeParameter("authentication", "");
81
+ // Auth: API Key Header
82
+ if (authMethod === "apiKey") {
83
+ const expectedKey = this.getNodeParameter("apiKey", "");
84
+ const receivedKey = headers["x-finlight-key"];
85
+ if (!receivedKey || receivedKey !== expectedKey) {
86
+ throw new Error("Unauthorized: Invalid API key");
87
+ }
88
+ }
89
+ // Auth: Basic
90
+ if (authMethod === "basicAuth") {
91
+ const credentials = await this.getCredentials("httpBasicAuth");
92
+ const authHeader = headers["authorization"];
93
+ const expected = "Basic " + Buffer.from(`${credentials.user}:${credentials.password}`).toString("base64");
94
+ if (authHeader !== expected) {
95
+ throw new Error("Unauthorized: Invalid Basic Auth");
96
+ }
97
+ }
98
+ // Build clean output with optional fields
99
+ const payload = body;
100
+ const output = {
101
+ link: payload.link,
102
+ source: payload.source,
103
+ title: payload.title,
104
+ publishDate: payload.publishDate,
105
+ language: payload.language,
106
+ };
107
+ if (payload.summary)
108
+ output.summary = payload.summary;
109
+ if (payload.content)
110
+ output.content = payload.content;
111
+ if (payload.sentiment)
112
+ output.sentiment = payload.sentiment;
113
+ if (payload.confidence)
114
+ output.confidence = payload.confidence;
115
+ if (payload.images?.length)
116
+ output.images = payload.images;
117
+ if (payload.companies?.length)
118
+ output.companies = payload.companies;
119
+ return {
120
+ workflowData: [[{ json: output }]],
121
+ };
122
+ }
123
+ }
124
+ exports.FinlightWebhookTrigger = FinlightWebhookTrigger;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finlight/n8n-nodes-finlight",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Official n8n integration for finlight: real-time finance and news API",
5
5
  "author": {
6
6
  "name": "Ali Büyükkakac",
@@ -16,9 +16,10 @@
16
16
  "license": "MIT",
17
17
  "main": "index.js",
18
18
  "scripts": {
19
- "build": "tsc",
19
+ "build": "tsc && cp nodes/finlight/finlight.svg dist/nodes/finlight/",
20
20
  "lint": "eslint . --ext .ts",
21
- "test": "jest"
21
+ "test": "jest",
22
+ "prepublishOnly": "npm run build"
22
23
  },
23
24
  "dependencies": {},
24
25
  "devDependencies": {