@finlight/n8n-nodes-finlight 0.1.4 → 0.2.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,413 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FinlightApi = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ class FinlightApi {
6
+ constructor() {
7
+ this.description = {
8
+ displayName: 'finlight',
9
+ name: 'finlight',
10
+ group: ['transform'],
11
+ version: 1,
12
+ description: 'Interact with the finlight REST API',
13
+ defaults: {
14
+ name: 'finlight',
15
+ },
16
+ inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
17
+ outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
18
+ icon: 'file:../finlight.svg',
19
+ credentials: [{ name: 'finlightApi', required: true }],
20
+ properties: [
21
+ // ---- Operation ----
22
+ {
23
+ displayName: 'Operation',
24
+ name: 'operation',
25
+ type: 'options',
26
+ options: [
27
+ {
28
+ name: 'Search Articles',
29
+ value: 'search',
30
+ description: 'Search articles using the finlight REST API',
31
+ action: 'Search articles',
32
+ },
33
+ {
34
+ name: 'Get Article by Link',
35
+ value: 'getByLink',
36
+ description: 'Get a specific article by its URL',
37
+ action: 'Get article by link',
38
+ },
39
+ {
40
+ name: 'List Sources',
41
+ value: 'listSources',
42
+ description: 'Get all available news sources',
43
+ action: 'List sources',
44
+ },
45
+ ],
46
+ default: 'search',
47
+ },
48
+ // ---- Get by Link params ----
49
+ {
50
+ displayName: 'Article Link',
51
+ name: 'link',
52
+ type: 'string',
53
+ required: true,
54
+ default: '',
55
+ placeholder: 'https://www.reuters.com/article/...',
56
+ description: 'The URL of the article to retrieve',
57
+ displayOptions: {
58
+ show: { operation: ['getByLink'] },
59
+ },
60
+ },
61
+ {
62
+ displayName: 'Include Content',
63
+ name: 'getByLinkIncludeContent',
64
+ type: 'boolean',
65
+ default: false,
66
+ description: 'Requires a Legacy subscription',
67
+ displayOptions: {
68
+ show: { operation: ['getByLink'] },
69
+ },
70
+ },
71
+ {
72
+ displayName: 'Include Entities',
73
+ name: 'getByLinkIncludeEntities',
74
+ type: 'boolean',
75
+ default: false,
76
+ description: 'Whether to include company entity tagging',
77
+ displayOptions: {
78
+ show: { operation: ['getByLink'] },
79
+ },
80
+ },
81
+ // ---- Search: All optional inputs grouped ----
82
+ {
83
+ displayName: 'Additional Options',
84
+ name: 'additionalOptions',
85
+ type: 'collection',
86
+ placeholder: 'Add option',
87
+ default: {},
88
+ options: [
89
+ {
90
+ displayName: 'Query',
91
+ name: 'query',
92
+ type: 'string',
93
+ default: '',
94
+ placeholder: 'earnings OR guidance AND (NVIDIA OR ticker:NVDA)',
95
+ description: 'Full-text query to filter articles',
96
+ },
97
+ {
98
+ displayName: 'From (ISO date)',
99
+ name: 'from',
100
+ type: 'string',
101
+ default: '',
102
+ description: 'Start of date range, e.g. 2025-09-01T00:00:00Z',
103
+ },
104
+ {
105
+ displayName: 'To (ISO date)',
106
+ name: 'to',
107
+ type: 'string',
108
+ default: '',
109
+ description: 'End of date range, e.g. 2025-09-06T23:59:59Z',
110
+ },
111
+ {
112
+ displayName: 'Sources',
113
+ name: 'sources',
114
+ type: 'fixedCollection',
115
+ placeholder: 'Add Source',
116
+ default: {},
117
+ typeOptions: { multipleValues: true },
118
+ options: [
119
+ {
120
+ name: 'sourceList',
121
+ displayName: 'Source List',
122
+ values: [
123
+ {
124
+ displayName: 'Source',
125
+ name: 'source',
126
+ type: 'string',
127
+ default: '',
128
+ placeholder: 'reuters.com',
129
+ },
130
+ ],
131
+ },
132
+ ],
133
+ },
134
+ {
135
+ displayName: 'Exclude Sources',
136
+ name: 'excludeSources',
137
+ type: 'fixedCollection',
138
+ placeholder: 'Exclude Source',
139
+ default: {},
140
+ typeOptions: { multipleValues: true },
141
+ options: [
142
+ {
143
+ name: 'sourceList',
144
+ displayName: 'Source List',
145
+ values: [
146
+ {
147
+ displayName: 'Source',
148
+ name: 'source',
149
+ type: 'string',
150
+ default: '',
151
+ placeholder: 'example.com',
152
+ },
153
+ ],
154
+ },
155
+ ],
156
+ },
157
+ {
158
+ displayName: 'Opt-In Sources',
159
+ name: 'optInSources',
160
+ type: 'fixedCollection',
161
+ placeholder: 'Add Opt-In Source',
162
+ default: {},
163
+ typeOptions: { multipleValues: true },
164
+ options: [
165
+ {
166
+ name: 'sourceList',
167
+ displayName: 'Source List',
168
+ values: [
169
+ {
170
+ displayName: 'Source',
171
+ name: 'source',
172
+ type: 'string',
173
+ default: '',
174
+ placeholder: 'example.com',
175
+ },
176
+ ],
177
+ },
178
+ ],
179
+ },
180
+ {
181
+ displayName: 'Tickers',
182
+ name: 'tickers',
183
+ type: 'fixedCollection',
184
+ placeholder: 'Add Ticker',
185
+ default: {},
186
+ typeOptions: { multipleValues: true },
187
+ options: [
188
+ {
189
+ name: 'tickerList',
190
+ displayName: 'Ticker List',
191
+ values: [
192
+ {
193
+ displayName: 'Ticker',
194
+ name: 'ticker',
195
+ type: 'string',
196
+ default: '',
197
+ placeholder: 'AAPL',
198
+ },
199
+ ],
200
+ },
201
+ ],
202
+ },
203
+ {
204
+ displayName: 'Countries',
205
+ name: 'countries',
206
+ type: 'fixedCollection',
207
+ placeholder: 'Add Country',
208
+ default: {},
209
+ typeOptions: { multipleValues: true },
210
+ options: [
211
+ {
212
+ name: 'countryList',
213
+ displayName: 'Country List',
214
+ values: [
215
+ {
216
+ displayName: 'Country Code (ISO 3166-1 Alpha-2)',
217
+ name: 'country',
218
+ type: 'string',
219
+ default: '',
220
+ placeholder: 'US',
221
+ },
222
+ ],
223
+ },
224
+ ],
225
+ },
226
+ {
227
+ displayName: 'Categories',
228
+ name: 'categories',
229
+ type: 'multiOptions',
230
+ options: [
231
+ { name: 'Markets', value: 'markets' },
232
+ { name: 'Economy', value: 'economy' },
233
+ { name: 'Business', value: 'business' },
234
+ { name: 'Politics', value: 'politics' },
235
+ { name: 'Geopolitics', value: 'geopolitics' },
236
+ { name: 'Regulation', value: 'regulation' },
237
+ { name: 'Technology', value: 'technology' },
238
+ { name: 'Energy', value: 'energy' },
239
+ { name: 'Commodities', value: 'commodities' },
240
+ { name: 'Crypto', value: 'crypto' },
241
+ { name: 'Health', value: 'health' },
242
+ { name: 'Climate', value: 'climate' },
243
+ { name: 'Security', value: 'security' },
244
+ ],
245
+ default: [],
246
+ },
247
+ {
248
+ displayName: 'Language',
249
+ name: 'language',
250
+ type: 'string',
251
+ default: 'en',
252
+ },
253
+ {
254
+ displayName: 'Order',
255
+ name: 'order',
256
+ type: 'options',
257
+ options: [
258
+ { name: 'DESC', value: 'DESC' },
259
+ { name: 'ASC', value: 'ASC' },
260
+ ],
261
+ default: 'DESC',
262
+ },
263
+ {
264
+ displayName: 'Order By',
265
+ name: 'orderBy',
266
+ type: 'options',
267
+ options: [
268
+ { name: 'Publish Date', value: 'publishDate' },
269
+ { name: 'Created At', value: 'createdAt' },
270
+ { name: 'Updated At', value: 'updatedAt' },
271
+ ],
272
+ default: 'publishDate',
273
+ },
274
+ {
275
+ displayName: 'Page Size',
276
+ name: 'pageSize',
277
+ type: 'number',
278
+ default: 20,
279
+ typeOptions: { minValue: 1, maxValue: 100 },
280
+ },
281
+ {
282
+ displayName: 'Page',
283
+ name: 'page',
284
+ type: 'number',
285
+ default: 1,
286
+ typeOptions: { minValue: 1 },
287
+ },
288
+ {
289
+ displayName: 'Include Content',
290
+ name: 'includeContent',
291
+ type: 'boolean',
292
+ default: false,
293
+ description: 'Requires a Legacy subscription',
294
+ },
295
+ {
296
+ displayName: 'Include Entities',
297
+ name: 'includeEntities',
298
+ type: 'boolean',
299
+ default: false,
300
+ },
301
+ {
302
+ displayName: 'Exclude Empty Content',
303
+ name: 'excludeEmptyContent',
304
+ type: 'boolean',
305
+ default: false,
306
+ },
307
+ ],
308
+ displayOptions: {
309
+ show: { operation: ['search'] },
310
+ },
311
+ },
312
+ ],
313
+ };
314
+ }
315
+ async execute() {
316
+ const items = this.getInputData();
317
+ const returnData = [];
318
+ const apiKey = (await this.getCredentials('finlightApi'));
319
+ const headers = {
320
+ 'Content-Type': 'application/json',
321
+ 'x-api-key': apiKey.apiKey,
322
+ };
323
+ for (let i = 0; i < items.length; i++) {
324
+ const operation = this.getNodeParameter('operation', i);
325
+ if (operation === 'search') {
326
+ const additional = (this.getNodeParameter('additionalOptions', i, {}) || {});
327
+ const body = {};
328
+ if (additional.query)
329
+ body.query = additional.query;
330
+ if (additional.from)
331
+ body.from = additional.from;
332
+ if (additional.to)
333
+ body.to = additional.to;
334
+ const sourcesRaw = additional.sources?.sourceList || [];
335
+ if (sourcesRaw.length)
336
+ body.sources = sourcesRaw.map((s) => s.source);
337
+ const excludeSourcesRaw = additional.excludeSources?.sourceList || [];
338
+ if (excludeSourcesRaw.length)
339
+ body.excludeSources = excludeSourcesRaw.map((s) => s.source);
340
+ const optInSourcesRaw = additional.optInSources?.sourceList || [];
341
+ if (optInSourcesRaw.length)
342
+ body.optInSources = optInSourcesRaw.map((s) => s.source);
343
+ const tickersRaw = additional.tickers?.tickerList || [];
344
+ if (tickersRaw.length)
345
+ body.tickers = tickersRaw.map((t) => t.ticker);
346
+ const countriesRaw = additional.countries?.countryList || [];
347
+ if (countriesRaw.length)
348
+ body.countries = countriesRaw.map((c) => c.country);
349
+ if (Array.isArray(additional.categories) && additional.categories.length) {
350
+ body.categories = additional.categories;
351
+ }
352
+ if (additional.language !== undefined)
353
+ body.language = additional.language;
354
+ if (additional.order !== undefined)
355
+ body.order = additional.order;
356
+ if (additional.orderBy !== undefined)
357
+ body.orderBy = additional.orderBy;
358
+ if (additional.pageSize !== undefined)
359
+ body.pageSize = Number(additional.pageSize);
360
+ if (additional.page !== undefined)
361
+ body.page = Number(additional.page);
362
+ if (typeof additional.includeContent === 'boolean')
363
+ body.includeContent = additional.includeContent;
364
+ if (typeof additional.includeEntities === 'boolean')
365
+ body.includeEntities = additional.includeEntities;
366
+ if (typeof additional.excludeEmptyContent === 'boolean')
367
+ body.excludeEmptyContent = additional.excludeEmptyContent;
368
+ const response = await this.helpers.httpRequest({
369
+ method: 'POST',
370
+ url: 'https://api.finlight.me/v2/articles',
371
+ headers,
372
+ body,
373
+ json: true,
374
+ });
375
+ returnData.push(...(Array.isArray(response?.articles) ? response.articles : [response]));
376
+ }
377
+ else if (operation === 'getByLink') {
378
+ const link = this.getNodeParameter('link', i);
379
+ const includeContent = this.getNodeParameter('getByLinkIncludeContent', i);
380
+ const includeEntities = this.getNodeParameter('getByLinkIncludeEntities', i);
381
+ const qs = { link };
382
+ if (includeContent)
383
+ qs.includeContent = true;
384
+ if (includeEntities)
385
+ qs.includeEntities = true;
386
+ const response = await this.helpers.httpRequest({
387
+ method: 'GET',
388
+ url: 'https://api.finlight.me/v2/articles/by-link',
389
+ headers,
390
+ qs,
391
+ json: true,
392
+ });
393
+ returnData.push(response?.article ?? response);
394
+ }
395
+ else if (operation === 'listSources') {
396
+ const response = await this.helpers.httpRequest({
397
+ method: 'GET',
398
+ url: 'https://api.finlight.me/v2/sources',
399
+ headers,
400
+ json: true,
401
+ });
402
+ if (Array.isArray(response)) {
403
+ returnData.push(...response.map((s) => (typeof s === 'string' ? { source: s } : s)));
404
+ }
405
+ else {
406
+ returnData.push(response);
407
+ }
408
+ }
409
+ }
410
+ return [this.helpers.returnJsonArray(returnData)];
411
+ }
412
+ }
413
+ exports.FinlightApi = FinlightApi;
@@ -3,24 +3,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FinlightApi = void 0;
4
4
  class FinlightApi {
5
5
  constructor() {
6
- this.name = "finlightApi";
7
- this.displayName = "finlight API Key";
6
+ this.name = 'finlightApi';
7
+ this.displayName = 'finlight API Key';
8
8
  this.properties = [
9
9
  {
10
- displayName: "API Key",
11
- name: "apiKey",
12
- type: "string",
13
- default: "",
10
+ displayName: 'API Key',
11
+ name: 'apiKey',
12
+ type: 'credentials',
13
+ default: '',
14
14
  },
15
15
  ];
16
16
  this.test = {
17
17
  request: {
18
- baseURL: "https://api.finlight.me/",
19
- url: "v2/articles",
20
- method: "POST",
18
+ baseURL: 'https://api.finlight.me/',
19
+ url: 'v2/articles',
20
+ method: 'POST',
21
21
  headers: {
22
- "Content-Type": "application/json",
23
- "x-api-key": "={{$credentials.apiKey}}",
22
+ 'Content-Type': 'application/json',
23
+ 'x-api-key': '={{$credentials.apiKey}}',
24
24
  },
25
25
  body: {
26
26
  pageSize: 1,
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FinlightWebhookSecret = void 0;
4
+ class FinlightWebhookSecret {
5
+ constructor() {
6
+ this.name = 'finlightWebhookSecret';
7
+ this.displayName = 'finlight Webhook Secret';
8
+ this.properties = [
9
+ {
10
+ displayName: 'Secret',
11
+ name: 'secret',
12
+ type: 'string',
13
+ typeOptions: { password: true },
14
+ default: '',
15
+ },
16
+ ];
17
+ }
18
+ }
19
+ exports.FinlightWebhookSecret = FinlightWebhookSecret;
@@ -3,12 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getAuthHeaders = getAuthHeaders;
4
4
  function getAuthHeaders(params) {
5
5
  const headers = {};
6
- if (params.authentication === "apiKey" && params.apiKey) {
7
- headers["x-finlight-key"] = params.apiKey;
6
+ if (params.authentication === 'apiKey' && params.apiKey) {
7
+ headers['x-finlight-key'] = params.apiKey;
8
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}`;
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
12
  }
13
13
  return headers;
14
14
  }
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.nodes = void 0;
3
+ exports.credentials = exports.nodes = void 0;
4
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];
5
+ const FinlightApi_node_1 = require("./actions/FinlightApi.node");
6
+ const FinlightWebhookSecret_credentials_1 = require("./credentials/FinlightWebhookSecret.credentials");
7
+ exports.nodes = [FinlightWebhookTrigger_node_1.FinlightWebhookTrigger, FinlightApi_node_1.FinlightApi];
8
+ exports.credentials = [FinlightWebhookSecret_credentials_1.FinlightWebhookSecret];
@@ -5,59 +5,59 @@ const n8n_workflow_1 = require("n8n-workflow");
5
5
  class FinlightWebhookTrigger {
6
6
  constructor() {
7
7
  this.description = {
8
- displayName: "finlight Webhook Trigger",
9
- name: "finlightWebhookTrigger",
10
- group: ["trigger"],
8
+ displayName: 'finlight Webhook Trigger',
9
+ name: 'finlightWebhookTrigger',
10
+ group: ['trigger'],
11
11
  version: 1,
12
- description: "Triggers on new webhook events from finlight",
12
+ description: 'Triggers on new webhook events from finlight',
13
13
  defaults: {
14
- name: "finlight Webhook Trigger",
14
+ name: 'finlight Webhook Trigger',
15
15
  },
16
16
  inputs: [],
17
17
  outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
18
18
  credentials: [
19
19
  {
20
- name: "finlightApi",
20
+ name: 'finlightWebhookSecret',
21
21
  required: true,
22
22
  displayOptions: {
23
23
  show: {
24
- authentication: ["apiKey"],
24
+ authentication: ['apiKey'],
25
25
  },
26
26
  },
27
27
  },
28
28
  {
29
- name: "httpBasicAuth",
29
+ name: 'httpBasicAuth',
30
30
  required: true,
31
31
  displayOptions: {
32
32
  show: {
33
- authentication: ["basicAuth"],
33
+ authentication: ['basicAuth'],
34
34
  },
35
35
  },
36
36
  },
37
37
  ],
38
38
  properties: [
39
39
  {
40
- displayName: "Authentication Method",
41
- name: "authentication",
42
- type: "options",
40
+ displayName: 'Authentication Method',
41
+ name: 'authentication',
42
+ type: 'options',
43
43
  options: [
44
- { name: "API Key Header (x-finlight-key)", value: "apiKey" },
45
- { name: "Basic Auth", value: "basicAuth" },
46
- { name: "None", value: "none" },
44
+ { name: 'Webhook Secret (X-Finlight-Key)', value: 'apiKey' },
45
+ { name: 'Basic Auth', value: 'basicAuth' },
46
+ { name: 'None', value: 'none' },
47
47
  ],
48
- default: "apiKey",
48
+ default: 'apiKey',
49
49
  },
50
50
  ],
51
51
  webhooks: [
52
52
  {
53
- name: "default",
54
- httpMethod: "POST",
55
- responseMode: "onReceived",
56
- path: "finlight",
53
+ name: 'default',
54
+ httpMethod: 'POST',
55
+ responseMode: 'onReceived',
56
+ path: 'finlight',
57
57
  },
58
58
  ],
59
- documentationUrl: "https://docs.finlight.me",
60
- icon: "file:../finlight.svg",
59
+ documentationUrl: 'https://docs.finlight.me',
60
+ icon: 'file:../finlight.svg',
61
61
  };
62
62
  this.webhookMethods = {
63
63
  default: {
@@ -77,22 +77,23 @@ class FinlightWebhookTrigger {
77
77
  const req = this.getRequestObject();
78
78
  const headers = req.headers;
79
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");
80
+ const authMethod = this.getNodeParameter('authentication', '');
81
+ // Auth: Webhook Secret (X-Finlight-Key)
82
+ if (authMethod === 'apiKey') {
83
+ const credentials = await this.getCredentials('finlightWebhookSecret');
84
+ const expectedSecret = credentials.secret;
85
+ const receivedKey = headers['x-finlight-key'];
86
+ if (!receivedKey || receivedKey !== expectedSecret) {
87
+ throw new Error('Unauthorized: Invalid webhook secret');
87
88
  }
88
89
  }
89
90
  // 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");
91
+ if (authMethod === 'basicAuth') {
92
+ const credentials = await this.getCredentials('httpBasicAuth');
93
+ const authHeader = headers['authorization'];
94
+ const expected = 'Basic ' + Buffer.from(`${credentials.user}:${credentials.password}`).toString('base64');
94
95
  if (authHeader !== expected) {
95
- throw new Error("Unauthorized: Invalid Basic Auth");
96
+ throw new Error('Unauthorized: Invalid Basic Auth');
96
97
  }
97
98
  }
98
99
  // Build clean output with optional fields
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finlight/n8n-nodes-finlight",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "description": "Official n8n integration for finlight: real-time finance and news API",
5
5
  "author": {
6
6
  "name": "Ali Büyükkakac",
@@ -19,18 +19,19 @@
19
19
  "build": "tsc && cp nodes/finlight/finlight.svg dist/nodes/finlight/",
20
20
  "lint": "eslint . --ext .ts",
21
21
  "test": "jest",
22
- "prepublishOnly": "npm run build"
22
+ "prepublishOnly": "npm run build",
23
+ "prettier:check": "prettier --check \"**/*.{ts,json,scss,html}\"",
24
+ "prettier:fix": "prettier --write \"**/*.{ts,json,scss,html}\""
23
25
  },
24
- "dependencies": {},
25
26
  "devDependencies": {
26
27
  "@types/node": "^24.1.0",
27
28
  "@typescript-eslint/eslint-plugin": "^8.38.0",
28
29
  "@typescript-eslint/parser": "^8.38.0",
29
30
  "eslint": "^9.32.0",
30
31
  "eslint-plugin-n8n-nodes-base": "^1.16.3",
31
- "n8n-core": "^1.14.1",
32
32
  "jest": "^29.4.0",
33
33
  "n8n-workflow": "*",
34
+ "prettier": "^3.8.3",
34
35
  "ts-jest": "^29.4.0",
35
36
  "typescript": "^5.8.3"
36
37
  },
@@ -47,11 +48,12 @@
47
48
  "n8n": {
48
49
  "n8nNodesApiVersion": 1,
49
50
  "credentials": [
50
- "dist/nodes/finlight/credentials/FinlightApi.credentials.js"
51
+ "dist/nodes/finlight/credentials/FinlightApi.credentials.js",
52
+ "dist/nodes/finlight/credentials/FinlightWebhookSecret.credentials.js"
51
53
  ],
52
54
  "nodes": [
53
55
  "dist/nodes/finlight/triggers/FinlightWebhookTrigger.node.js",
54
- "dist/nodes/finlight/actions/FinlightArticleSearch.node.js"
56
+ "dist/nodes/finlight/actions/FinlightApi.node.js"
55
57
  ]
56
58
  },
57
59
  "peerDependencies": {
@@ -1,217 +0,0 @@
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;