@pagecrawl/n8n-nodes-pagecrawl 0.1.2 → 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.
- package/dist/nodes/PageCrawl/PageCrawl.node.d.ts +3 -0
- package/dist/nodes/PageCrawl/PageCrawl.node.js +129 -20
- package/dist/nodes/PageCrawl/descriptions/CheckDescription.js +5 -6
- package/dist/nodes/PageCrawl/descriptions/PageDescription.js +567 -126
- package/dist/nodes/PageCrawl/descriptions/ScreenshotDescription.js +25 -29
- package/dist/nodes/PageCrawl/descriptions/WebhookDescription.js +6 -4
- package/dist/nodes/PageCrawl/types.d.ts +5 -2
- package/dist/nodes/PageCrawl/types.js +20 -20
- package/dist/nodes/PageCrawlTrigger/PageCrawlTrigger.node.js +29 -22
- package/package.json +1 -1
|
@@ -4,6 +4,9 @@ export declare class PageCrawl implements INodeType {
|
|
|
4
4
|
methods: {
|
|
5
5
|
listSearch: {
|
|
6
6
|
pageSearch(this: ILoadOptionsFunctions, filter?: string): Promise<INodeListSearchResult>;
|
|
7
|
+
templateSearch(this: ILoadOptionsFunctions, filter?: string): Promise<INodeListSearchResult>;
|
|
8
|
+
workspaceSearch(this: ILoadOptionsFunctions, filter?: string): Promise<INodeListSearchResult>;
|
|
9
|
+
authSearch(this: ILoadOptionsFunctions, filter?: string): Promise<INodeListSearchResult>;
|
|
7
10
|
};
|
|
8
11
|
};
|
|
9
12
|
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
@@ -97,6 +97,60 @@ class PageCrawl {
|
|
|
97
97
|
}
|
|
98
98
|
return { results };
|
|
99
99
|
},
|
|
100
|
+
async templateSearch(filter) {
|
|
101
|
+
const baseUrl = 'https://pagecrawl.io';
|
|
102
|
+
const response = await this.helpers.httpRequestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
103
|
+
method: 'GET',
|
|
104
|
+
url: `${baseUrl}/api/templates`,
|
|
105
|
+
json: true,
|
|
106
|
+
});
|
|
107
|
+
const templates = response.data || response;
|
|
108
|
+
let results = templates.map((template) => ({
|
|
109
|
+
name: template.name || `Template ${template.id}`,
|
|
110
|
+
value: String(template.id),
|
|
111
|
+
}));
|
|
112
|
+
if (filter) {
|
|
113
|
+
const filterLower = filter.toLowerCase();
|
|
114
|
+
results = results.filter((t) => t.name.toLowerCase().includes(filterLower));
|
|
115
|
+
}
|
|
116
|
+
return { results };
|
|
117
|
+
},
|
|
118
|
+
async workspaceSearch(filter) {
|
|
119
|
+
const baseUrl = 'https://pagecrawl.io';
|
|
120
|
+
const response = await this.helpers.httpRequestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
121
|
+
method: 'GET',
|
|
122
|
+
url: `${baseUrl}/api/workspaces`,
|
|
123
|
+
json: true,
|
|
124
|
+
});
|
|
125
|
+
const workspaces = response.data || response;
|
|
126
|
+
let results = workspaces.map((workspace) => ({
|
|
127
|
+
name: workspace.name || `Workspace ${workspace.id}`,
|
|
128
|
+
value: String(workspace.id),
|
|
129
|
+
}));
|
|
130
|
+
if (filter) {
|
|
131
|
+
const filterLower = filter.toLowerCase();
|
|
132
|
+
results = results.filter((w) => w.name.toLowerCase().includes(filterLower));
|
|
133
|
+
}
|
|
134
|
+
return { results };
|
|
135
|
+
},
|
|
136
|
+
async authSearch(filter) {
|
|
137
|
+
const baseUrl = 'https://pagecrawl.io';
|
|
138
|
+
const response = await this.helpers.httpRequestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
139
|
+
method: 'GET',
|
|
140
|
+
url: `${baseUrl}/api/auths`,
|
|
141
|
+
json: true,
|
|
142
|
+
});
|
|
143
|
+
const auths = response.data || response;
|
|
144
|
+
let results = auths.map((auth) => ({
|
|
145
|
+
name: auth.name || `Auth ${auth.id}`,
|
|
146
|
+
value: String(auth.id),
|
|
147
|
+
}));
|
|
148
|
+
if (filter) {
|
|
149
|
+
const filterLower = filter.toLowerCase();
|
|
150
|
+
results = results.filter((a) => a.name.toLowerCase().includes(filterLower));
|
|
151
|
+
}
|
|
152
|
+
return { results };
|
|
153
|
+
},
|
|
100
154
|
},
|
|
101
155
|
};
|
|
102
156
|
}
|
|
@@ -109,6 +163,17 @@ class PageCrawl {
|
|
|
109
163
|
const pageLocator = this.getNodeParameter('pageId', index);
|
|
110
164
|
return pageLocator.value || '';
|
|
111
165
|
};
|
|
166
|
+
// Helper to transform fixedCollection to array
|
|
167
|
+
const transformFixedCollection = (collection, key) => {
|
|
168
|
+
if (!collection)
|
|
169
|
+
return [];
|
|
170
|
+
if (Array.isArray(collection))
|
|
171
|
+
return collection;
|
|
172
|
+
if (typeof collection === 'object' && collection[key]) {
|
|
173
|
+
return collection[key];
|
|
174
|
+
}
|
|
175
|
+
return [];
|
|
176
|
+
};
|
|
112
177
|
for (let i = 0; i < items.length; i++) {
|
|
113
178
|
const resource = this.getNodeParameter('resource', i);
|
|
114
179
|
const operation = this.getNodeParameter('operation', i);
|
|
@@ -162,8 +227,12 @@ class PageCrawl {
|
|
|
162
227
|
}
|
|
163
228
|
else if (operation === 'createSimple') {
|
|
164
229
|
const url = this.getNodeParameter('url', i);
|
|
230
|
+
const name = this.getNodeParameter('name', i, '');
|
|
165
231
|
const additionalFields = this.getNodeParameter('additionalFields', i);
|
|
166
232
|
const body = { url };
|
|
233
|
+
if (name) {
|
|
234
|
+
body.name = name;
|
|
235
|
+
}
|
|
167
236
|
if (additionalFields.selector) {
|
|
168
237
|
body.selector = additionalFields.selector;
|
|
169
238
|
}
|
|
@@ -198,14 +267,34 @@ class PageCrawl {
|
|
|
198
267
|
if (typeof body.tags === 'string' && body.tags) {
|
|
199
268
|
body.tags = body.tags.split(',').map((tag) => tag.trim()).filter(Boolean);
|
|
200
269
|
}
|
|
201
|
-
//
|
|
202
|
-
if (body.folder_id ===
|
|
270
|
+
// Extract values from resourceLocator fields
|
|
271
|
+
if (body.folder_id && typeof body.folder_id === 'object') {
|
|
272
|
+
body.folder_id = body.folder_id.value || '';
|
|
273
|
+
}
|
|
274
|
+
if (body.template_id && typeof body.template_id === 'object') {
|
|
275
|
+
body.template_id = body.template_id.value || '';
|
|
276
|
+
}
|
|
277
|
+
if (body.auth_id && typeof body.auth_id === 'object') {
|
|
278
|
+
body.auth_id = body.auth_id.value || '';
|
|
279
|
+
}
|
|
280
|
+
// Remove ID fields if empty or 0 (not set)
|
|
281
|
+
if (!body.folder_id || body.folder_id === 0)
|
|
203
282
|
delete body.folder_id;
|
|
204
|
-
if (body.template_id === 0)
|
|
283
|
+
if (!body.template_id || body.template_id === 0)
|
|
205
284
|
delete body.template_id;
|
|
206
|
-
if (body.auth_id === 0)
|
|
285
|
+
if (!body.auth_id || body.auth_id === 0)
|
|
207
286
|
delete body.auth_id;
|
|
208
|
-
//
|
|
287
|
+
// Transform fixedCollection fields to arrays
|
|
288
|
+
if (body.actions && typeof body.actions === 'object') {
|
|
289
|
+
body.actions = transformFixedCollection(body.actions, 'action');
|
|
290
|
+
}
|
|
291
|
+
if (body.rules && typeof body.rules === 'object') {
|
|
292
|
+
body.rules = transformFixedCollection(body.rules, 'rule');
|
|
293
|
+
if (body.rules.length > 0) {
|
|
294
|
+
body.rules_enabled = true;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// Parse JSON fields if they're strings (backwards compatibility)
|
|
209
298
|
if (typeof body.actions === 'string') {
|
|
210
299
|
try {
|
|
211
300
|
body.actions = JSON.parse(body.actions);
|
|
@@ -246,12 +335,22 @@ class PageCrawl {
|
|
|
246
335
|
if (typeof body.tags === 'string' && body.tags) {
|
|
247
336
|
body.tags = body.tags.split(',').map((tag) => tag.trim()).filter(Boolean);
|
|
248
337
|
}
|
|
249
|
-
//
|
|
250
|
-
if (body.folder_id ===
|
|
338
|
+
// Extract values from resourceLocator fields
|
|
339
|
+
if (body.folder_id && typeof body.folder_id === 'object') {
|
|
340
|
+
body.folder_id = body.folder_id.value || '';
|
|
341
|
+
}
|
|
342
|
+
if (body.template_id && typeof body.template_id === 'object') {
|
|
343
|
+
body.template_id = body.template_id.value || '';
|
|
344
|
+
}
|
|
345
|
+
if (body.auth_id && typeof body.auth_id === 'object') {
|
|
346
|
+
body.auth_id = body.auth_id.value || '';
|
|
347
|
+
}
|
|
348
|
+
// Remove ID fields if empty or 0 (not set)
|
|
349
|
+
if (!body.folder_id || body.folder_id === 0)
|
|
251
350
|
delete body.folder_id;
|
|
252
|
-
if (body.template_id === 0)
|
|
351
|
+
if (!body.template_id || body.template_id === 0)
|
|
253
352
|
delete body.template_id;
|
|
254
|
-
if (body.auth_id === 0)
|
|
353
|
+
if (!body.auth_id || body.auth_id === 0)
|
|
255
354
|
delete body.auth_id;
|
|
256
355
|
// Parse JSON fields if they're strings
|
|
257
356
|
if (typeof body.elements === 'string') {
|
|
@@ -262,6 +361,17 @@ class PageCrawl {
|
|
|
262
361
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid JSON in elements field', { itemIndex: i });
|
|
263
362
|
}
|
|
264
363
|
}
|
|
364
|
+
// Transform fixedCollection fields to arrays
|
|
365
|
+
if (body.actions && typeof body.actions === 'object') {
|
|
366
|
+
body.actions = transformFixedCollection(body.actions, 'action');
|
|
367
|
+
}
|
|
368
|
+
if (body.rules && typeof body.rules === 'object') {
|
|
369
|
+
body.rules = transformFixedCollection(body.rules, 'rule');
|
|
370
|
+
if (body.rules.length > 0) {
|
|
371
|
+
body.rules_enabled = true;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
// Parse JSON fields if they're strings (backwards compatibility)
|
|
265
375
|
if (typeof body.actions === 'string') {
|
|
266
376
|
try {
|
|
267
377
|
body.actions = JSON.parse(body.actions);
|
|
@@ -310,7 +420,7 @@ class PageCrawl {
|
|
|
310
420
|
qs.skip_first_notification = 1;
|
|
311
421
|
}
|
|
312
422
|
responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
313
|
-
method: '
|
|
423
|
+
method: 'POST',
|
|
314
424
|
url: `${baseUrl}/api/pages/${pageId}/check`,
|
|
315
425
|
qs,
|
|
316
426
|
json: true,
|
|
@@ -381,24 +491,23 @@ class PageCrawl {
|
|
|
381
491
|
}
|
|
382
492
|
else if (resource === 'screenshot') {
|
|
383
493
|
const pageId = getPageId(i);
|
|
494
|
+
const checkId = this.getNodeParameter('checkId', i, 'latest');
|
|
384
495
|
let endpoint = '';
|
|
385
|
-
if (operation === '
|
|
386
|
-
endpoint = `/pages/${pageId}/checks/latest/screenshot`;
|
|
387
|
-
}
|
|
388
|
-
else if (operation === 'getLatestDiff') {
|
|
389
|
-
endpoint = `/pages/${pageId}/checks/latest/diff`;
|
|
390
|
-
}
|
|
391
|
-
else if (operation === 'getCheckScreenshot') {
|
|
392
|
-
const checkId = this.getNodeParameter('checkId', i);
|
|
496
|
+
if (operation === 'getScreenshot') {
|
|
393
497
|
endpoint = `/pages/${pageId}/checks/${checkId}/screenshot`;
|
|
394
498
|
}
|
|
395
|
-
else if (operation === '
|
|
396
|
-
const checkId = this.getNodeParameter('checkId', i);
|
|
499
|
+
else if (operation === 'getScreenshotDiff') {
|
|
397
500
|
endpoint = `/pages/${pageId}/checks/${checkId}/diff`;
|
|
398
501
|
}
|
|
502
|
+
const previous = operation === 'getScreenshot' ? this.getNodeParameter('previous', i, false) : false;
|
|
503
|
+
const qs = {};
|
|
504
|
+
if (previous) {
|
|
505
|
+
qs.previous = 1;
|
|
506
|
+
}
|
|
399
507
|
const response = await this.helpers.httpRequestWithAuthentication.call(this, 'pageCrawlApi', {
|
|
400
508
|
method: 'GET',
|
|
401
509
|
url: `${baseUrl}/api${endpoint}`,
|
|
510
|
+
qs,
|
|
402
511
|
encoding: 'arraybuffer',
|
|
403
512
|
});
|
|
404
513
|
const binaryData = await this.helpers.prepareBinaryData(response, `screenshot-${pageId}.png`, 'image/png');
|
|
@@ -56,7 +56,7 @@ exports.checkFields = [
|
|
|
56
56
|
},
|
|
57
57
|
},
|
|
58
58
|
default: { mode: 'list', value: '' },
|
|
59
|
-
description: 'Select a page or enter slug/ID.
|
|
59
|
+
description: 'Select a page or enter slug/ID. Find the slug in your page URL (pagecrawl.io/app/pages/{slug}). Enable Debug mode in Settings to see page IDs.',
|
|
60
60
|
modes: [
|
|
61
61
|
{
|
|
62
62
|
displayName: 'From List',
|
|
@@ -116,14 +116,14 @@ exports.checkFields = [
|
|
|
116
116
|
displayName: 'Simple',
|
|
117
117
|
name: 'simple',
|
|
118
118
|
type: 'boolean',
|
|
119
|
-
default:
|
|
119
|
+
default: true,
|
|
120
120
|
description: 'Whether to return simplified response',
|
|
121
121
|
},
|
|
122
122
|
{
|
|
123
123
|
displayName: 'Take',
|
|
124
124
|
name: 'take',
|
|
125
125
|
type: 'number',
|
|
126
|
-
default:
|
|
126
|
+
default: 2,
|
|
127
127
|
description: 'Limit number of checks retrieved',
|
|
128
128
|
typeOptions: {
|
|
129
129
|
minValue: 0,
|
|
@@ -138,14 +138,13 @@ exports.checkFields = [
|
|
|
138
138
|
displayName: 'Check ID',
|
|
139
139
|
name: 'checkId',
|
|
140
140
|
type: 'string',
|
|
141
|
-
required: true,
|
|
142
141
|
displayOptions: {
|
|
143
142
|
show: {
|
|
144
143
|
resource: ['check'],
|
|
145
144
|
operation: ['getDiffHtml', 'getDiffImage', 'getDiffMarkdown'],
|
|
146
145
|
},
|
|
147
146
|
},
|
|
148
|
-
default: '',
|
|
149
|
-
description: 'The check ID (
|
|
147
|
+
default: 'latest',
|
|
148
|
+
description: 'The check ID to get diff for (defaults to "latest" for most recent)',
|
|
150
149
|
},
|
|
151
150
|
];
|