Skip to content

Commit 4982522

Browse files
committed
fix codegen
1 parent 767c7b0 commit 4982522

File tree

123 files changed

+18593
-4588
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

123 files changed

+18593
-4588
lines changed

Diff for: .eslintrc.js

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
/**
2+
* @type {import('@types/eslint').ESLint.ConfigData}
3+
*/
14
module.exports = {
25
root: true,
36

@@ -8,17 +11,14 @@ module.exports = {
811
},
912

1013
parser: '@typescript-eslint/parser',
14+
1115
parserOptions: {
1216
project: ['./tsconfig.json'],
1317
sourceType: 'module',
1418
extraFileExtensions: ['.json'],
1519
},
16-
ignorePatterns: [
17-
'.eslintrc.js',
18-
'**/*.js',
19-
'**/node_modules/**',
20-
'**/dist/**',
21-
],
20+
21+
ignorePatterns: ['.eslintrc.js', '**/*.js', '**/node_modules/**', '**/dist/**'],
2222

2323
overrides: [
2424
{
@@ -27,7 +27,7 @@ module.exports = {
2727
extends: ['plugin:n8n-nodes-base/community'],
2828
rules: {
2929
'n8n-nodes-base/community-package-json-name-still-default': 'off',
30-
}
30+
},
3131
},
3232
{
3333
files: ['./credentials/**/*.ts'],
@@ -46,8 +46,6 @@ module.exports = {
4646
'n8n-nodes-base/node-execute-block-missing-continue-on-fail': 'off',
4747
'n8n-nodes-base/node-resource-description-filename-against-convention': 'off',
4848
'n8n-nodes-base/node-param-fixed-collection-type-unsorted-items': 'off',
49-
'n8n-nodes-base/node-execute-block-operation-missing-singular-pairing': 'off',
50-
'n8n-nodes-base/node-execute-block-operation-missing-plural-pairing': 'off',
5149
},
5250
},
5351
],

Diff for: .eslintrc.prepublish.js

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
/**
2+
* @type {import('@types/eslint').ESLint.ConfigData}
3+
*/
14
module.exports = {
25
extends: "./.eslintrc.js",
6+
37
overrides: [
48
{
59
files: ['package.json'],

Diff for: README.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
<img src="https://user-images.githubusercontent.com/11575076/202373912-a90e5cc0-9dd2-4873-b782-6f86c78f00eb.png" />
66
</p>
77

8+
#### New Updates: 🎉 **Browserless** API V2 is now supported.
9+
810

911
This is an n8n community node. It lets you interact with [browserless](https://github.com/browserless/chrome) instance in your `n8n` workflows.
1012

@@ -46,9 +48,9 @@ You've been tried to do browser related tasks with `n8n` for example `web scrap
4648
$ docker run \
4749
--rm \
4850
-p 3000:3000 \
49-
-e "MAX_CONCURRENT_SESSIONS=10" \
50-
-e "TOKEN=YOUR-SECURE-TOKEN" \
51-
browserless/chrome:latest
51+
-e "CONCURRENT=10" \
52+
-e "TOKEN=6R0W53R135510" \
53+
ghcr.io/browserless/chromium
5254
```
5355

5456
- Visit your n8n running instance > setttings > community nodes > install `n8n-nodes-browserless`
@@ -111,4 +113,4 @@ With strong support form `browserless` we can have greate `anti-bot-detector` by
111113
- `0.3.0` Fixed [#1](https://github.com/minhlucvan/n8n-nodes-browserless/issues/1), implement tests
112114
- `0.4.0` Adding browser options, adding no-cache as default header
113115
- `0.5.0` Implement anti-bot-detector
114-
116+
- `1.0.0` Support for `browserless` API v2

Diff for: credentials/BrowserlessApi.credentials.ts

-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
import {
2-
IAuthenticate,
3-
IAuthenticateBase,
42
IAuthenticateGeneric,
53
ICredentialTestRequest,
64
ICredentialType,

Diff for: nodes.config.js

+30-3
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,25 @@ const path = require('path');
22

33
module.exports = {
44
packageName: 'n8n-nodes-browserless',
5+
credentials: {
6+
browserlessApi: {
7+
displayName: 'Browserless API',
8+
name: 'browserlessApi',
9+
className: 'BrowserlessApi',
10+
},
11+
},
512
nodes: {
613
browserless: {
714
displayName: 'Browserless',
815
name: 'Browserless',
916
preset: 'versioned',
1017
description: 'Browserless API',
1118
openapi: path.resolve(__dirname, 'openapi.yml'),
12-
icon: './icons/firewrawl.png',
13-
baseUrl: '=\{\{$credentials.baseUrl\}\}',
19+
icon: 'file:browserless.svg',
20+
baseUrl: '=\{\{$credentials.url\}\}',
1421
targetDir: path.resolve(__dirname, 'nodes/Browserless/v2'),
1522
version: 2,
23+
tags: ['Browser REST APIs'],
1624
credentials: [{
1725
displayName: 'Browserless API',
1826
name: 'browserlessApi',
@@ -21,8 +29,27 @@ module.exports = {
2129
},
2230
},
2331
overwrites: {
24-
operations: [],
32+
operations: [
33+
// remove all token
34+
{
35+
match: {
36+
name: 'token',
37+
},
38+
set: false,
39+
}
40+
],
2541
},
2642
deleteFolders: [''],
43+
normalizeFn: (s) => {
44+
// /a /b => /b
45+
// /abc /def => /def
46+
const slugs = s.split(' ');
47+
// only if both slugs are single words and start with a slash
48+
if (slugs.every(slug => slug.startsWith('/'))) {
49+
return slugs[slugs.length - 1];
50+
}
51+
52+
return s;
53+
}
2754
};
2855

Diff for: nodes/Browserless/Browserless.node.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ export class Browserless extends VersionedNodeType {
88
constructor() {
99
const baseDescription: INodeTypeBaseDescription = {
1010
displayName: 'Browserless',
11-
name: 'Browserless',
12-
icon: 'file:Browserless.svg',
11+
name: 'browserless',
12+
icon: 'file:browserless.svg',
1313
group: ['transform'],
1414
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
1515
description: 'Interact with Browserless API',
16-
defaultVersion: 1,
16+
// @ts-ignore
17+
version: [1, 2, 3],
18+
defaultVersion: 2,
1719
};
1820

1921
const nodeVersions: IVersionedNodeType['nodeVersions'] = {

Diff for: nodes/Browserless/v1/Browserless.node.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
IDataObject,
23
IExecuteFunctions,
34
INodeExecutionData,
45
INodeType,
@@ -25,7 +26,6 @@ import {
2526
getCommonOptions,
2627
getNodeCommoonOptions,
2728
parseCollectionOptions,
28-
parseFixedCollectionOptions,
2929
} from './GenericFunctions';
3030
import { browserlessFields, browserlessImageOptionsFields, browserlessOperations } from './BrowserlessDescriptions';
3131

@@ -36,8 +36,8 @@ export class Browserless implements INodeType {
3636
this.description = {
3737
...baseDescription,
3838
displayName: 'Browserless',
39-
name: 'Browserless',
40-
icon: 'file:Browserless.svg',
39+
name: 'browserless',
40+
icon: 'file:browserless.svg',
4141
group: ['transform'],
4242
version: 1,
4343
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
@@ -180,7 +180,7 @@ export class Browserless implements INodeType {
180180
if (resource === 'screenshot') {
181181
const url = this.getNodeParameter('url', i) as string;
182182
const imageOptionsRaw = this.getNodeParameter('imageOptions', i);
183-
const imageOptions = parseCollectionOptions(browserlessImageOptionsFields, imageOptionsRaw);
183+
const imageOptions = parseCollectionOptions(browserlessImageOptionsFields, imageOptionsRaw as IDataObject);
184184

185185
const options: BrowserlessApiRequestScreenshotOptions = {
186186
common,
@@ -218,7 +218,7 @@ export class Browserless implements INodeType {
218218
}
219219

220220
const executionData = this.helpers.constructExecutionMetaData(
221-
this.helpers.returnJsonArray(responseData),
221+
this.helpers.returnJsonArray(responseData as IDataObject[]),
222222
{ itemData: { item: i } },
223223
);
224224

Diff for: nodes/Browserless/v1/Browserless.svg

-2
This file was deleted.

Diff for: nodes/Browserless/v1/GenericFunctions.ts

+25-24
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
IExecuteFunctions,
55
IHttpRequestMethods,
66
IHttpRequestOptions,
7-
ILoadOptionsFunctions,
87
IN8nHttpFullResponse,
98
IN8nHttpResponse,
109
INodeProperties,
@@ -26,8 +25,8 @@ import {
2625
BrowserlessCommonOptions,
2726
BrowserlessCredentials,
2827
} from './types';
29-
import { content, fn, pdf, scrape, screenshot } from './V1/interfaces';
30-
import * as schems from './V1/chemas/browserless-api.schema';
28+
import { content, fn, pdf, scrape, screenshot } from './interfaces';
29+
import * as schems from './chemas/browserless-api.schema';
3130
import {
3231
browserlessBrowserOptionsFields,
3332
browserlessPageOptionsFileds,
@@ -40,7 +39,7 @@ export async function browserlessApiRequest(
4039
this: IAllExecuteFunctions,
4140
method: IHttpRequestMethods,
4241
endpoint: string,
43-
body: any = {},
42+
body: IDataObject = {},
4443
qs: IDataObject = {},
4544
extradOptions: Partial<IHttpRequestOptions> = {},
4645
): Promise<IN8nHttpFullResponse | IN8nHttpResponse> {
@@ -241,27 +240,27 @@ export async function browserlessApiRequestScreenshot(
241240
* Get common node inputs
242241
*/
243242
export function getCommonOptions(this: IExecuteFunctions, i: number) {
244-
let options = {} as any;
243+
let options = {} as IDataObject;
245244
try {
246-
const addition = this.getNodeParameter('addition', i) as any;
245+
const addition = this.getNodeParameter('addition', i) as IDataObject;
247246
options = parseCollectionOptions(browserlessPageOptionsFileds, addition);
248247

249248
if (options['setExtraHTTPHeaders']) {
250249
options['setExtraHTTPHeaders'] = composeArrayToMap(
251-
options['setExtraHTTPHeaders'],
250+
options['setExtraHTTPHeaders'] as IDataObject[],
252251
'name',
253252
'value',
254253
);
255254
}
256255

257256
options['setExtraHTTPHeaders'] = {
258-
...options['setExtraHTTPHeaders'],
257+
...options['setExtraHTTPHeaders'] as IDataObject,
259258
'cache-control': 'no-cache',
260259
};
261260

262261
if (options['addScriptTag']) {
263-
options['addScriptTag'] = Array.from(options['addScriptTag']).map((tag) =>
264-
omitEmptyProps(tag),
262+
options['addScriptTag'] = Array.from(options['addScriptTag'] as string[]).map((tag) =>
263+
omitEmptyProps(tag as unknown as IDataObject),
265264
);
266265
}
267266

@@ -281,7 +280,7 @@ export function getCommonOptions(this: IExecuteFunctions, i: number) {
281280
* Get common node inputs
282281
*/
283282
export function getNodeCommoonOptions(this: IExecuteFunctions): BrowserlessCommonOptions {
284-
const browserOptionsRaw = this.getNodeParameter('browserOptions', 0) as any;
283+
const browserOptionsRaw = this.getNodeParameter('browserOptions', 0) as IDataObject;
285284
const browserOptions = parseBrowserOptions(browserOptionsRaw);
286285
return {
287286
browserOptions,
@@ -291,19 +290,21 @@ export function getNodeCommoonOptions(this: IExecuteFunctions): BrowserlessCommo
291290
/**
292291
* compose key - value to object
293292
*/
294-
export function composeArrayToMap(array: any[], key: string, value: string) {
295-
const options = {} as any;
293+
export function composeArrayToMap(array: IDataObject[], key: string, value: string) {
294+
const options: IDataObject = {};
296295
for (const item of array) {
297-
options[item[key]] = item[value];
296+
if (typeof item[key] === 'string') {
297+
options[item[key]] = item[value];
298+
}
298299
}
299300
return options;
300301
}
301302

302303
/**
303304
* compose key - value to object
304305
*/
305-
export function omitEmptyProps(obj: any) {
306-
const options = {} as any;
306+
export function omitEmptyProps(obj: IDataObject) {
307+
const options = {} as IDataObject;
307308
for (const [key, value] of Object.entries(obj)) {
308309
if (!!value) {
309310
options[key] = value;
@@ -320,15 +321,15 @@ export async function prepareBinaryResponse(
320321
res: IN8nHttpFullResponse,
321322
key: string,
322323
) {
323-
const binaryData = await this.helpers.prepareBinaryData(res.body as unknown as ArrayBuffer);
324+
const binaryData = await this.helpers.prepareBinaryData(Buffer.from(res.body as ArrayBuffer));
324325
return binaryData;
325326
}
326327

327328
/**
328329
* Parse browser options
329330
*/
330-
export function parseBrowserOptions(rawOption: any) {
331-
const options = {} as any;
331+
export function parseBrowserOptions(rawOption: IDataObject) {
332+
const options = {} as IDataObject;
332333
for (const option of browserlessBrowserOptionsFields?.options ?? []) {
333334
if (typeof rawOption[option.name] === 'boolean') {
334335
options[option.name] = rawOption[option.name] ? 'true' : 'false';
@@ -342,7 +343,7 @@ export function parseBrowserOptions(rawOption: any) {
342343
/**
343344
* Parse fixed collection options
344345
*/
345-
export function parseFixedCollectionOptions(descriptor: INodeProperties, rawOption: any) {
346+
export function parseFixedCollectionOptions(descriptor: INodeProperties, rawOption: IDataObject) {
346347
if (descriptor.type !== 'fixedCollection') {
347348
return rawOption;
348349
}
@@ -352,7 +353,7 @@ export function parseFixedCollectionOptions(descriptor: INodeProperties, rawOpti
352353
}
353354

354355
if (descriptor.typeOptions && !descriptor.typeOptions.multipleValues) {
355-
return rawOption[descriptor.name];
356+
return rawOption[descriptor.name] || {};
356357
}
357358

358359
return rawOption;
@@ -361,8 +362,8 @@ export function parseFixedCollectionOptions(descriptor: INodeProperties, rawOpti
361362
/**
362363
* Parse collection options
363364
*/
364-
export function parseCollectionOptions(descriptor: INodeProperties, rawOption: any) {
365-
const results = {} as any;
365+
export function parseCollectionOptions(descriptor: INodeProperties, rawOption: IDataObject) {
366+
const results = {} as IDataObject;
366367
if (descriptor.type !== 'collection') {
367368
return rawOption;
368369
}
@@ -371,7 +372,7 @@ export function parseCollectionOptions(descriptor: INodeProperties, rawOption: a
371372
continue;
372373
}
373374
if (isINodeProperties(option) && option?.type === 'fixedCollection') {
374-
results[option.name] = parseFixedCollectionOptions(option, rawOption[option.name]);
375+
results[option.name] = parseFixedCollectionOptions(option, rawOption[option.name] as IDataObject);
375376
} else {
376377
results[option.name] = rawOption[option.name];
377378
}

Diff for: nodes/Browserless/v1/__test__/GenericFunctions.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { describe, expect, it } from '@jest/globals';
2-
import { browserlessPageOptionsFileds } from '../../BrowserlessDescriptions';
2+
import { browserlessPageOptionsFileds } from '../BrowserlessDescriptions';
33
import { content } from '../chemas/browserless-api.schema';
4-
import { parseCollectionOptions } from '../../GenericFunctions';
4+
import { parseCollectionOptions } from '../GenericFunctions';
55

66
describe('parseFixedCollectionOptions', () => {
77
it('should parse cookies as an array', () => {

Diff for: nodes/Browserless/v1/types.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { content, fn, pdf, scrape, screenshot, } from "./V1/interfaces";
1+
import { content, fn, pdf, scrape, screenshot, } from "./interfaces";
22

33
export type BrowserlessCredentials = {
44
token?: string;
@@ -68,11 +68,11 @@ export type BrowserlessApiResponseScrapeResultFlat = BrowserlessApiResponseScrap
6868
export type BrowserlessApiResponseScrapeDataFlat = BrowserlessApiResponseScrapeResultFlat[];
6969

7070
export type BrowserlessApiResponseScrapeDebug = {
71-
screenshot?: any,
72-
console?: any,
73-
network?: any,
74-
cookies?: any,
75-
html?: any
71+
screenshot?: unknown,
72+
console?: unknown,
73+
network?: unknown,
74+
cookies?: unknown,
75+
html?: unknown
7676
};
7777

7878
export type BrowserlessApiResponseScrape = {

0 commit comments

Comments
 (0)