@pagecrawl/n8n-nodes-pagecrawl 0.3.3 → 0.3.6

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.
@@ -5,6 +5,8 @@ const n8n_workflow_1 = require("n8n-workflow");
5
5
  const PageDescription_1 = require("./descriptions/PageDescription");
6
6
  const CheckDescription_1 = require("./descriptions/CheckDescription");
7
7
  const ScreenshotDescription_1 = require("./descriptions/ScreenshotDescription");
8
+ const package_json_1 = require("../../package.json");
9
+ const API_CLIENT_HEADER = { 'X-Api-Client': `n8n/${package_json_1.version}` };
8
10
  class PageCrawl {
9
11
  constructor() {
10
12
  this.description = {
@@ -31,6 +33,7 @@ class PageCrawl {
31
33
  headers: {
32
34
  Accept: 'application/json',
33
35
  'Content-Type': 'application/json',
36
+ ...API_CLIENT_HEADER,
34
37
  },
35
38
  },
36
39
  properties: [
@@ -99,6 +102,7 @@ class PageCrawl {
99
102
  const response = await this.helpers.httpRequestWithAuthentication.call(this, 'pageCrawlApi', {
100
103
  method: 'GET',
101
104
  url: `${baseUrl}/api/user`,
105
+ headers: API_CLIENT_HEADER,
102
106
  json: true,
103
107
  });
104
108
  // Get available locations from user account
@@ -156,6 +160,7 @@ class PageCrawl {
156
160
  const response = await this.helpers.httpRequestWithAuthentication.call(this, 'pageCrawlApi', {
157
161
  method: 'GET',
158
162
  url: `${baseUrl}/api/user`,
163
+ headers: API_CLIENT_HEADER,
159
164
  json: true,
160
165
  });
161
166
  // Get available frequencies from user account
@@ -177,6 +182,7 @@ class PageCrawl {
177
182
  const response = await this.helpers.httpRequestWithAuthentication.call(this, 'pageCrawlApi', {
178
183
  method: 'GET',
179
184
  url: `${baseUrl}/api/user`,
185
+ headers: API_CLIENT_HEADER,
180
186
  json: true,
181
187
  });
182
188
  // Get available devices from user account
@@ -215,6 +221,7 @@ class PageCrawl {
215
221
  const response = await this.helpers.httpRequestWithAuthentication.call(this, 'pageCrawlApi', {
216
222
  method: 'GET',
217
223
  url: `${baseUrl}/api/workspaces/${workspaceId}/ai/available-models`,
224
+ headers: API_CLIENT_HEADER,
218
225
  json: true,
219
226
  });
220
227
  // Get available AI models
@@ -249,6 +256,7 @@ class PageCrawl {
249
256
  method: 'GET',
250
257
  url: `${baseUrl}/api/pages`,
251
258
  qs: { workspace_id: workspaceId },
259
+ headers: API_CLIENT_HEADER,
252
260
  json: true,
253
261
  });
254
262
  const pages = response.data || response;
@@ -278,6 +286,7 @@ class PageCrawl {
278
286
  method: 'GET',
279
287
  url: `${baseUrl}/api/templates`,
280
288
  qs: { workspace_id: workspaceId },
289
+ headers: API_CLIENT_HEADER,
281
290
  json: true,
282
291
  });
283
292
  // Handle various response formats
@@ -306,6 +315,7 @@ class PageCrawl {
306
315
  const response = await this.helpers.httpRequestWithAuthentication.call(this, 'pageCrawlApi', {
307
316
  method: 'GET',
308
317
  url: `${baseUrl}/api/user`,
318
+ headers: API_CLIENT_HEADER,
309
319
  json: true,
310
320
  });
311
321
  // Extract workspaces from user response (may be nested under user)
@@ -341,6 +351,7 @@ class PageCrawl {
341
351
  method: 'GET',
342
352
  url: `${baseUrl}/api/folders`,
343
353
  qs: { all: true, workspace_id: workspaceId },
354
+ headers: API_CLIENT_HEADER,
344
355
  json: true,
345
356
  });
346
357
  // Handle various response formats
@@ -386,6 +397,7 @@ class PageCrawl {
386
397
  method: 'GET',
387
398
  url: `${baseUrl}/api/auths`,
388
399
  qs: { workspace_id: workspaceId },
400
+ headers: API_CLIENT_HEADER,
389
401
  json: true,
390
402
  });
391
403
  // Handle various response formats
@@ -462,6 +474,7 @@ class PageCrawl {
462
474
  method: 'GET',
463
475
  url: `${baseUrl}/api/pages/${pageId}`,
464
476
  qs,
477
+ headers: API_CLIENT_HEADER,
465
478
  json: true,
466
479
  });
467
480
  }
@@ -487,6 +500,7 @@ class PageCrawl {
487
500
  method: 'POST',
488
501
  url: `${baseUrl}/api/track-simple`,
489
502
  body,
503
+ headers: API_CLIENT_HEADER,
490
504
  json: true,
491
505
  });
492
506
  }
@@ -592,6 +606,7 @@ class PageCrawl {
592
606
  method: 'POST',
593
607
  url: `${baseUrl}/api/pages`,
594
608
  body,
609
+ headers: API_CLIENT_HEADER,
595
610
  json: true,
596
611
  });
597
612
  }
@@ -677,6 +692,7 @@ class PageCrawl {
677
692
  url: `${baseUrl}/api/pages/${pageId}`,
678
693
  qs,
679
694
  body,
695
+ headers: API_CLIENT_HEADER,
680
696
  json: true,
681
697
  });
682
698
  }
@@ -687,6 +703,7 @@ class PageCrawl {
687
703
  method: 'DELETE',
688
704
  url: `${baseUrl}/api/pages/${pageId}`,
689
705
  qs: { workspace_id: workspaceId },
706
+ headers: API_CLIENT_HEADER,
690
707
  json: true,
691
708
  });
692
709
  responseData = { success: true, deleted: pageId };
@@ -703,6 +720,7 @@ class PageCrawl {
703
720
  method: 'PUT',
704
721
  url: `${baseUrl}/api/pages/${pageId}/check`,
705
722
  qs,
723
+ headers: API_CLIENT_HEADER,
706
724
  json: true,
707
725
  });
708
726
  responseData = { success: true, message: 'Check triggered', pageId };
@@ -718,13 +736,12 @@ class PageCrawl {
718
736
  if (!options.advanced) {
719
737
  qs.simple = 1;
720
738
  }
721
- if (options.take) {
722
- qs.take = options.take;
723
- }
739
+ qs.take = options.take ?? 2;
724
740
  responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'pageCrawlApi', {
725
741
  method: 'GET',
726
742
  url: `${baseUrl}/api/pages/${pageId}/history`,
727
743
  qs,
744
+ headers: API_CLIENT_HEADER,
728
745
  json: true,
729
746
  });
730
747
  }
@@ -734,6 +751,7 @@ class PageCrawl {
734
751
  method: 'GET',
735
752
  url: `${baseUrl}/api/pages/${pageId}/checks/${checkId}/diff.png`,
736
753
  qs: { workspace_id: workspaceId },
754
+ headers: API_CLIENT_HEADER,
737
755
  encoding: 'arraybuffer',
738
756
  });
739
757
  const binaryData = await this.helpers.prepareBinaryData(response, `diff-${pageId}-${checkId}.png`, 'image/png');
@@ -748,6 +766,7 @@ class PageCrawl {
748
766
  url: `${baseUrl}/api/pages/${pageId}/checks/${checkId}/diff.html`,
749
767
  qs: { workspace_id: workspaceId },
750
768
  headers: {
769
+ ...API_CLIENT_HEADER,
751
770
  Accept: 'text/html',
752
771
  },
753
772
  });
@@ -764,6 +783,7 @@ class PageCrawl {
764
783
  url: `${baseUrl}/api/pages/${pageId}/checks/${checkId}/diff.markdown`,
765
784
  qs: { workspace_id: workspaceId },
766
785
  headers: {
786
+ ...API_CLIENT_HEADER,
767
787
  Accept: 'text/markdown',
768
788
  },
769
789
  });
@@ -794,6 +814,7 @@ class PageCrawl {
794
814
  method: 'GET',
795
815
  url: `${baseUrl}/api${endpoint}`,
796
816
  qs,
817
+ headers: API_CLIENT_HEADER,
797
818
  encoding: 'arraybuffer',
798
819
  });
799
820
  const binaryData = await this.helpers.prepareBinaryData(response, `screenshot-${pageId}.png`, 'image/png');
@@ -68,16 +68,20 @@ exports.checkFields = [
68
68
  },
69
69
  },
70
70
  {
71
- displayName: 'By Slug',
72
- name: 'slug',
71
+ displayName: 'By URL',
72
+ name: 'url',
73
73
  type: 'string',
74
- placeholder: 'e.g. my-page-name',
74
+ placeholder: 'e.g. https://pagecrawl.io/app/pages/example-domain',
75
+ extractValue: {
76
+ type: 'regex',
77
+ regex: 'https://pagecrawl\\.io/app/pages/([a-z0-9_-]+)',
78
+ },
75
79
  validation: [
76
80
  {
77
81
  type: 'regex',
78
82
  properties: {
79
- regex: '^[a-z0-9-]+$',
80
- errorMessage: 'Slug must contain only lowercase letters, numbers, and hyphens',
83
+ regex: '^https://pagecrawl\\.io/app/pages/[a-z0-9_-]+$',
84
+ errorMessage: 'Must be a valid PageCrawl page URL (e.g. https://pagecrawl.io/app/pages/my-page)',
81
85
  },
82
86
  },
83
87
  ],
@@ -86,16 +90,7 @@ exports.checkFields = [
86
90
  displayName: 'By ID',
87
91
  name: 'id',
88
92
  type: 'string',
89
- placeholder: 'e.g. 12345',
90
- validation: [
91
- {
92
- type: 'regex',
93
- properties: {
94
- regex: '^[0-9]+$',
95
- errorMessage: 'ID must be a number',
96
- },
97
- },
98
- ],
93
+ placeholder: 'e.g. 12345 or my-page-slug',
99
94
  },
100
95
  ],
101
96
  },
@@ -28,10 +28,10 @@ exports.pageOperations = [
28
28
  action: 'Create an advanced page',
29
29
  },
30
30
  {
31
- name: 'Delete',
32
- value: 'delete',
33
- description: 'Delete a tracked page',
34
- action: 'Delete a page',
31
+ name: 'Run Check Now',
32
+ value: 'runCheckNow',
33
+ description: 'Trigger an immediate check for a page',
34
+ action: 'Run check now',
35
35
  },
36
36
  {
37
37
  name: 'Get',
@@ -39,18 +39,18 @@ exports.pageOperations = [
39
39
  description: 'Get a tracked page configuration',
40
40
  action: 'Get a page',
41
41
  },
42
- {
43
- name: 'Run Check Now',
44
- value: 'runCheckNow',
45
- description: 'Trigger an immediate check for a page',
46
- action: 'Run check now',
47
- },
48
42
  {
49
43
  name: 'Update',
50
44
  value: 'update',
51
45
  description: 'Update a tracked page',
52
46
  action: 'Update a page',
53
47
  },
48
+ {
49
+ name: 'Delete',
50
+ value: 'delete',
51
+ description: 'Delete a tracked page',
52
+ action: 'Delete a page',
53
+ },
54
54
  ],
55
55
  default: 'get',
56
56
  },
@@ -83,16 +83,20 @@ exports.pageFields = [
83
83
  },
84
84
  },
85
85
  {
86
- displayName: 'By Slug',
87
- name: 'slug',
86
+ displayName: 'By URL',
87
+ name: 'url',
88
88
  type: 'string',
89
- placeholder: 'e.g. my-page-name',
89
+ placeholder: 'e.g. https://pagecrawl.io/app/pages/example-domain',
90
+ extractValue: {
91
+ type: 'regex',
92
+ regex: 'https://pagecrawl\\.io/app/pages/([a-z0-9_-]+)',
93
+ },
90
94
  validation: [
91
95
  {
92
96
  type: 'regex',
93
97
  properties: {
94
- regex: '^[a-z0-9-]+$',
95
- errorMessage: 'Slug must contain only lowercase letters, numbers, and hyphens',
98
+ regex: '^https://pagecrawl\\.io/app/pages/[a-z0-9_-]+$',
99
+ errorMessage: 'Must be a valid PageCrawl page URL (e.g. https://pagecrawl.io/app/pages/my-page)',
96
100
  },
97
101
  },
98
102
  ],
@@ -101,16 +105,7 @@ exports.pageFields = [
101
105
  displayName: 'By ID',
102
106
  name: 'id',
103
107
  type: 'string',
104
- placeholder: 'e.g. 12345',
105
- validation: [
106
- {
107
- type: 'regex',
108
- properties: {
109
- regex: '^[0-9]+$',
110
- errorMessage: 'ID must be a number',
111
- },
112
- },
113
- ],
108
+ placeholder: 'e.g. 12345 or my-page-slug',
114
109
  },
115
110
  ],
116
111
  },
@@ -183,6 +178,19 @@ exports.pageFields = [
183
178
  placeholder: 'https://example.com',
184
179
  description: 'The URL to track',
185
180
  },
181
+ {
182
+ displayName: 'Title',
183
+ name: 'name',
184
+ type: 'string',
185
+ displayOptions: {
186
+ show: {
187
+ resource: ['page'],
188
+ operation: ['createSimple'],
189
+ },
190
+ },
191
+ default: '',
192
+ description: 'Optional title for this page (defaults to page title if empty)',
193
+ },
186
194
  {
187
195
  displayName: 'Tracking Type',
188
196
  name: 'trackingType',
@@ -355,10 +363,9 @@ exports.pageFields = [
355
363
  description: 'The URL to track',
356
364
  },
357
365
  {
358
- displayName: 'Name',
366
+ displayName: 'Title',
359
367
  name: 'name',
360
368
  type: 'string',
361
- required: true,
362
369
  displayOptions: {
363
370
  show: {
364
371
  resource: ['page'],
@@ -366,7 +373,7 @@ exports.pageFields = [
366
373
  },
367
374
  },
368
375
  default: '',
369
- description: 'Label for the page',
376
+ description: 'Optional title for this page (defaults to page title if empty)',
370
377
  },
371
378
  {
372
379
  displayName: 'Tracked Elements',
@@ -1094,11 +1101,11 @@ exports.pageFields = [
1094
1101
  description: 'How often to check for changes',
1095
1102
  },
1096
1103
  {
1097
- displayName: 'Name',
1104
+ displayName: 'Title',
1098
1105
  name: 'name',
1099
1106
  type: 'string',
1100
1107
  default: '',
1101
- description: 'Label for the page',
1108
+ description: 'Title for this page',
1102
1109
  },
1103
1110
  {
1104
1111
  displayName: 'URL',
@@ -56,16 +56,20 @@ exports.screenshotFields = [
56
56
  },
57
57
  },
58
58
  {
59
- displayName: 'By Slug',
60
- name: 'slug',
59
+ displayName: 'By URL',
60
+ name: 'url',
61
61
  type: 'string',
62
- placeholder: 'e.g. my-page-name',
62
+ placeholder: 'e.g. https://pagecrawl.io/app/pages/example-domain',
63
+ extractValue: {
64
+ type: 'regex',
65
+ regex: 'https://pagecrawl\\.io/app/pages/([a-z0-9_-]+)',
66
+ },
63
67
  validation: [
64
68
  {
65
69
  type: 'regex',
66
70
  properties: {
67
- regex: '^[a-z0-9-]+$',
68
- errorMessage: 'Slug must contain only lowercase letters, numbers, and hyphens',
71
+ regex: '^https://pagecrawl\\.io/app/pages/[a-z0-9_-]+$',
72
+ errorMessage: 'Must be a valid PageCrawl page URL (e.g. https://pagecrawl.io/app/pages/my-page)',
69
73
  },
70
74
  },
71
75
  ],
@@ -74,16 +78,7 @@ exports.screenshotFields = [
74
78
  displayName: 'By ID',
75
79
  name: 'id',
76
80
  type: 'string',
77
- placeholder: 'e.g. 12345',
78
- validation: [
79
- {
80
- type: 'regex',
81
- properties: {
82
- regex: '^[0-9]+$',
83
- errorMessage: 'ID must be a number',
84
- },
85
- },
86
- ],
81
+ placeholder: 'e.g. 12345 or my-page-slug',
87
82
  },
88
83
  ],
89
84
  },
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PageCrawlTrigger = void 0;
4
4
  const types_1 = require("../PageCrawl/types");
5
+ const package_json_1 = require("../../package.json");
6
+ const API_CLIENT_HEADER = { 'X-Api-Client': `n8n/${package_json_1.version}` };
5
7
  class PageCrawlTrigger {
6
8
  constructor() {
7
9
  this.description = {
@@ -74,16 +76,20 @@ class PageCrawlTrigger {
74
76
  },
75
77
  },
76
78
  {
77
- displayName: 'By Slug',
78
- name: 'slug',
79
+ displayName: 'By URL',
80
+ name: 'url',
79
81
  type: 'string',
80
- placeholder: 'e.g. my-page-name',
82
+ placeholder: 'e.g. https://pagecrawl.io/app/pages/example-domain',
83
+ extractValue: {
84
+ type: 'regex',
85
+ regex: 'https://pagecrawl\\.io/app/pages/([a-z0-9_-]+)',
86
+ },
81
87
  validation: [
82
88
  {
83
89
  type: 'regex',
84
90
  properties: {
85
- regex: '^[a-z0-9-]+$',
86
- errorMessage: 'Slug must contain only lowercase letters, numbers, and hyphens',
91
+ regex: '^https://pagecrawl\\.io/app/pages/[a-z0-9_-]+$',
92
+ errorMessage: 'Must be a valid PageCrawl page URL (e.g. https://pagecrawl.io/app/pages/my-page)',
87
93
  },
88
94
  },
89
95
  ],
@@ -92,16 +98,7 @@ class PageCrawlTrigger {
92
98
  displayName: 'By ID',
93
99
  name: 'id',
94
100
  type: 'string',
95
- placeholder: 'e.g. 12345',
96
- validation: [
97
- {
98
- type: 'regex',
99
- properties: {
100
- regex: '^[0-9]+$',
101
- errorMessage: 'ID must be a number',
102
- },
103
- },
104
- ],
101
+ placeholder: 'e.g. 12345 or my-page-slug',
105
102
  },
106
103
  ],
107
104
  },
@@ -146,6 +143,7 @@ class PageCrawlTrigger {
146
143
  const response = await this.helpers.httpRequestWithAuthentication.call(this, 'pageCrawlApi', {
147
144
  method: 'GET',
148
145
  url: `${baseUrl}/api/user`,
146
+ headers: API_CLIENT_HEADER,
149
147
  json: true,
150
148
  });
151
149
  // Extract workspaces from user response (may be nested under user)
@@ -179,6 +177,7 @@ class PageCrawlTrigger {
179
177
  method: 'GET',
180
178
  url: `${baseUrl}/api/pages`,
181
179
  qs: { workspace_id: workspaceId },
180
+ headers: API_CLIENT_HEADER,
182
181
  json: true,
183
182
  });
184
183
  const pages = response.data || response;
@@ -213,6 +212,7 @@ class PageCrawlTrigger {
213
212
  method: 'GET',
214
213
  url: `${baseUrl}/api/hooks`,
215
214
  qs: workspaceId ? { workspace_id: workspaceId } : {},
215
+ headers: API_CLIENT_HEADER,
216
216
  json: true,
217
217
  });
218
218
  const existingWebhook = response.find((webhook) => webhook.id === webhookData.webhookId);
@@ -264,6 +264,7 @@ class PageCrawlTrigger {
264
264
  method: 'POST',
265
265
  url: `${baseUrl}/api/hooks`,
266
266
  body,
267
+ headers: API_CLIENT_HEADER,
267
268
  json: true,
268
269
  });
269
270
  if (!response.id) {
@@ -276,6 +277,7 @@ class PageCrawlTrigger {
276
277
  await this.helpers.httpRequestWithAuthentication.call(this, 'pageCrawlApi', {
277
278
  method: 'PUT',
278
279
  url: `${baseUrl}/api/hooks/${response.id}/test`,
280
+ headers: API_CLIENT_HEADER,
279
281
  json: true,
280
282
  });
281
283
  }
@@ -301,6 +303,7 @@ class PageCrawlTrigger {
301
303
  await this.helpers.httpRequestWithAuthentication.call(this, 'pageCrawlApi', {
302
304
  method: 'DELETE',
303
305
  url: `${baseUrl}/api/hooks/${webhookData.webhookId}`,
306
+ headers: API_CLIENT_HEADER,
304
307
  json: true,
305
308
  });
306
309
  }
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@pagecrawl/n8n-nodes-pagecrawl",
3
+ "version": "0.3.5",
4
+ "description": "n8n node for PageCrawl.io - Website monitoring and change detection",
5
+ "keywords": [
6
+ "n8n",
7
+ "n8n-community-node-package",
8
+ "website-monitoring",
9
+ "change-detection",
10
+ "web-scraping",
11
+ "pagecrawl",
12
+ "automation"
13
+ ],
14
+ "license": "MIT",
15
+ "homepage": "https://pagecrawl.io",
16
+ "author": {
17
+ "name": "PageCrawl.io",
18
+ "email": "support@pagecrawl.io"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/pagecrawl/n8n-nodes-pagecrawl.git"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/pagecrawl/n8n-nodes-pagecrawl/issues"
26
+ },
27
+ "main": "index.js",
28
+ "scripts": {
29
+ "build": "tsc && cp nodes/PageCrawl/pagecrawl.svg dist/nodes/PageCrawl/ && cp nodes/PageCrawlTrigger/pagecrawl.svg dist/nodes/PageCrawlTrigger/",
30
+ "dev": "npm run build && npx n8n start",
31
+ "dev:build": "npm run build",
32
+ "n8n:start": "npx n8n start",
33
+ "lint": "eslint nodes credentials --ext .ts",
34
+ "lint:fix": "eslint nodes credentials --ext .ts --fix",
35
+ "link": "npm run build && npm link",
36
+ "test": "jest --testPathIgnorePatterns=integration",
37
+ "test:integration": "jest --testPathPattern=integration --testTimeout=60000"
38
+ },
39
+ "files": [
40
+ "dist"
41
+ ],
42
+ "n8n": {
43
+ "n8nNodesApiVersion": 1,
44
+ "credentials": [
45
+ "dist/credentials/PageCrawlApi.credentials.js"
46
+ ],
47
+ "nodes": [
48
+ "dist/nodes/PageCrawl/PageCrawl.node.js",
49
+ "dist/nodes/PageCrawlTrigger/PageCrawlTrigger.node.js"
50
+ ]
51
+ },
52
+ "devDependencies": {
53
+ "@types/jest": "^30.0.0",
54
+ "@types/node": "^20.0.0",
55
+ "@typescript-eslint/eslint-plugin": "^7.0.0",
56
+ "@typescript-eslint/parser": "^7.0.0",
57
+ "axios": "^1.6.0",
58
+ "dotenv": "^17.2.3",
59
+ "eslint": "^8.56.0",
60
+ "eslint-plugin-n8n-nodes-base": "^1.16.0",
61
+ "jest": "^29.7.0",
62
+ "n8n": "^2.2.0",
63
+ "n8n-workflow": "^2.2.2",
64
+ "ts-jest": "^29.4.6",
65
+ "typescript": "^5.0.0"
66
+ },
67
+ "peerDependencies": {
68
+ "n8n-workflow": ">=1.0.0"
69
+ }
70
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pagecrawl/n8n-nodes-pagecrawl",
3
- "version": "0.3.3",
3
+ "version": "0.3.6",
4
4
  "description": "n8n node for PageCrawl.io - Website monitoring and change detection",
5
5
  "keywords": [
6
6
  "n8n",
@@ -60,7 +60,7 @@
60
60
  "eslint-plugin-n8n-nodes-base": "^1.16.0",
61
61
  "jest": "^29.7.0",
62
62
  "n8n": "^2.2.0",
63
- "n8n-workflow": "~2.2.0",
63
+ "n8n-workflow": "^2.2.2",
64
64
  "ts-jest": "^29.4.6",
65
65
  "typescript": "^5.0.0"
66
66
  },