n8n-nodes-browser-cli 0.1.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/README.md +87 -0
- package/dist/credentials/BrowserCliApi.credentials.d.ts +21 -0
- package/dist/credentials/BrowserCliApi.credentials.js +65 -0
- package/dist/credentials/BrowserCliApi.credentials.js.map +1 -0
- package/dist/nodes/BrowserCli/BrowserCli.node.d.ts +5 -0
- package/dist/nodes/BrowserCli/BrowserCli.node.js +314 -0
- package/dist/nodes/BrowserCli/BrowserCli.node.js.map +1 -0
- package/dist/nodes/BrowserCli/browserCli.svg +31 -0
- package/dist/nodes/BrowserCli/request.d.ts +40 -0
- package/dist/nodes/BrowserCli/request.js +139 -0
- package/dist/nodes/BrowserCli/request.js.map +1 -0
- package/package.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# n8n-nodes-browser-cli
|
|
2
|
+
|
|
3
|
+
An [n8n](https://n8n.io) community node that controls a **real, visible browser**
|
|
4
|
+
from your workflows via [browser-cli](https://chromewebstore.google.com/detail/browser-cli/hekaebjhbhhdbmakimmaklbblbmccahp).
|
|
5
|
+
|
|
6
|
+
browser-cli drives a running browser through a native-messaging host and a
|
|
7
|
+
browser extension — it **cannot be installed inside the n8n container**. So this
|
|
8
|
+
node is a thin HTTP client for the `browser-cli serve-http` gateway running on
|
|
9
|
+
the machine that actually has the browser. n8n → HTTP → remote gateway → browser.
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
n8n workflow ──HTTP(S)──▶ browser-cli serve-http (remote host) ──▶ browser
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Remote setup (on the browser machine)
|
|
16
|
+
|
|
17
|
+
Install and start the gateway where the browser runs, opening exactly the
|
|
18
|
+
command tiers you need (it is **safe-only by default**):
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
uv tool install real-browser-cli
|
|
22
|
+
browser-cli install brave # one-time: register the extension/native host
|
|
23
|
+
|
|
24
|
+
# Expose the gateway. Open only what your workflow needs:
|
|
25
|
+
browser-cli serve-http --host 0.0.0.0 --port 8766 --allow-read-page --allow-control
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
It prints a **token** — copy it into the n8n credential.
|
|
29
|
+
|
|
30
|
+
> ⚠️ The gateway speaks **plain HTTP** and sends the token in clear text. Never
|
|
31
|
+
> expose it directly on an untrusted network. Put a TLS-terminating reverse
|
|
32
|
+
> proxy in front and point the credential **Base URL** at the HTTPS endpoint.
|
|
33
|
+
|
|
34
|
+
## n8n credential — "Browser CLI API"
|
|
35
|
+
|
|
36
|
+
| Field | Description |
|
|
37
|
+
|-------|-------------|
|
|
38
|
+
| Base URL | `https://browser-host.example` (proxy) or `http://127.0.0.1:8766` (loopback/tunnel) |
|
|
39
|
+
| Token | the token printed by `serve-http` (leave empty only for `--no-auth` loopback) |
|
|
40
|
+
| Ignore SSL Issues | enable for a self-signed reverse-proxy cert |
|
|
41
|
+
|
|
42
|
+
The credential test calls `GET /health`.
|
|
43
|
+
|
|
44
|
+
## Operations
|
|
45
|
+
|
|
46
|
+
Every operation maps to one gateway route. Convenience operations are typed
|
|
47
|
+
wrappers around `POST /command`, so each needs the matching server policy tier.
|
|
48
|
+
|
|
49
|
+
| Resource | Operation | Command / route | Server flag needed |
|
|
50
|
+
|----------|-----------|-----------------|--------------------|
|
|
51
|
+
| Tab | List | `GET /tabs` | safe (default) |
|
|
52
|
+
| Tab | Open | `navigate.open` | `--allow-control` |
|
|
53
|
+
| Tab | Close | `tabs.close` (ids / inactive / duplicates) | `--allow-control` |
|
|
54
|
+
| Tab | Get HTML | `tabs.html` | `--allow-read-page` |
|
|
55
|
+
| Page | Get Info | `page.info` | safe (default) |
|
|
56
|
+
| Page | Extract Text / Links / Images / HTML / Markdown | `extract.*` | `--allow-read-page` |
|
|
57
|
+
| DOM | Query | `dom.query` | `--allow-read-page` |
|
|
58
|
+
| DOM | Click / Type | `dom.click` / `dom.type` | `--allow-control` |
|
|
59
|
+
| DOM | Eval | `dom.eval` | `--allow-dangerous` |
|
|
60
|
+
| Client | List | `GET /clients` | safe (default) |
|
|
61
|
+
| Command | Execute | `POST /command` (raw command + JSON args) | per command |
|
|
62
|
+
| Gateway | Health | `GET /health` | none |
|
|
63
|
+
|
|
64
|
+
**Command → Execute** is the escape hatch: any command string the gateway's
|
|
65
|
+
policy allows (`tabs.query`, `session.save`, `windows.list`, …) with a JSON args
|
|
66
|
+
object. Use it for anything the typed operations don't cover.
|
|
67
|
+
|
|
68
|
+
> Note: the gateway returns the **raw** command result (no SDK post-processing).
|
|
69
|
+
> `extract.markdown` therefore returns the page payload as the extension hands it
|
|
70
|
+
> back, not the CLI's rendered Markdown. For clean text use **Extract Text**.
|
|
71
|
+
|
|
72
|
+
## Develop / build
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
cd n8n-nodes-browser-cli
|
|
76
|
+
npm install # add --ignore-scripts if a transitive native dep
|
|
77
|
+
# (isolated-vm) fails to compile on your Node version
|
|
78
|
+
npm test # pure request-mapping unit tests (node:test + esbuild)
|
|
79
|
+
npm run build # tsc -> dist/, copies the icon
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Then install into n8n as a [community node](https://docs.n8n.io/integrations/community-nodes/installation/)
|
|
83
|
+
(`n8n-nodes-browser-cli`), or symlink `dist/` into `~/.n8n/custom` for local testing.
|
|
84
|
+
|
|
85
|
+
## License
|
|
86
|
+
|
|
87
|
+
PolyForm Noncommercial License 1.0.0 — same as browser-cli.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
/**
|
|
3
|
+
* Credentials for a remote `browser-cli serve-http` gateway.
|
|
4
|
+
*
|
|
5
|
+
* browser-cli cannot be installed inside n8n, so the node talks to a gateway
|
|
6
|
+
* running on the machine that actually drives the browser. Start it there with:
|
|
7
|
+
*
|
|
8
|
+
* browser-cli serve-http --host 0.0.0.0 --port 8766 --allow-read-page --allow-control
|
|
9
|
+
*
|
|
10
|
+
* The token it prints goes into this credential. The gateway speaks plain HTTP
|
|
11
|
+
* and sends the token in clear text, so expose it only behind a TLS-terminating
|
|
12
|
+
* reverse proxy and point the Base URL at the HTTPS endpoint.
|
|
13
|
+
*/
|
|
14
|
+
export declare class BrowserCliApi implements ICredentialType {
|
|
15
|
+
name: string;
|
|
16
|
+
displayName: string;
|
|
17
|
+
documentationUrl: string;
|
|
18
|
+
properties: INodeProperties[];
|
|
19
|
+
authenticate: IAuthenticateGeneric;
|
|
20
|
+
test: ICredentialTestRequest;
|
|
21
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BrowserCliApi = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Credentials for a remote `browser-cli serve-http` gateway.
|
|
6
|
+
*
|
|
7
|
+
* browser-cli cannot be installed inside n8n, so the node talks to a gateway
|
|
8
|
+
* running on the machine that actually drives the browser. Start it there with:
|
|
9
|
+
*
|
|
10
|
+
* browser-cli serve-http --host 0.0.0.0 --port 8766 --allow-read-page --allow-control
|
|
11
|
+
*
|
|
12
|
+
* The token it prints goes into this credential. The gateway speaks plain HTTP
|
|
13
|
+
* and sends the token in clear text, so expose it only behind a TLS-terminating
|
|
14
|
+
* reverse proxy and point the Base URL at the HTTPS endpoint.
|
|
15
|
+
*/
|
|
16
|
+
class BrowserCliApi {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.name = 'browserCliApi';
|
|
19
|
+
this.displayName = 'Browser CLI API';
|
|
20
|
+
this.documentationUrl = 'https://chromewebstore.google.com/detail/browser-cli/hekaebjhbhhdbmakimmaklbblbmccahp';
|
|
21
|
+
this.properties = [
|
|
22
|
+
{
|
|
23
|
+
displayName: 'Base URL',
|
|
24
|
+
name: 'baseUrl',
|
|
25
|
+
type: 'string',
|
|
26
|
+
default: 'http://127.0.0.1:8766',
|
|
27
|
+
placeholder: 'https://browser-host.example',
|
|
28
|
+
required: true,
|
|
29
|
+
description: 'Base URL of the remote browser-cli serve-http gateway. Prefer an HTTPS endpoint behind a reverse proxy — the gateway itself is plain HTTP.',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
displayName: 'Token',
|
|
33
|
+
name: 'token',
|
|
34
|
+
type: 'string',
|
|
35
|
+
typeOptions: { password: true },
|
|
36
|
+
default: '',
|
|
37
|
+
description: 'Bearer token printed by `browser-cli serve-http`. Leave empty only for a `--no-auth` loopback gateway.',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
displayName: 'Ignore SSL Issues',
|
|
41
|
+
name: 'allowUnauthorizedCerts',
|
|
42
|
+
type: 'boolean',
|
|
43
|
+
default: false,
|
|
44
|
+
description: 'Whether to connect even when the TLS certificate cannot be verified (e.g. a self-signed reverse proxy).',
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
this.authenticate = {
|
|
48
|
+
type: 'generic',
|
|
49
|
+
properties: {
|
|
50
|
+
headers: {
|
|
51
|
+
Authorization: '=Bearer {{$credentials.token}}',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
this.test = {
|
|
56
|
+
request: {
|
|
57
|
+
baseURL: '={{$credentials.baseUrl}}',
|
|
58
|
+
url: '/health',
|
|
59
|
+
skipSslCertificateValidation: '={{$credentials.allowUnauthorizedCerts}}',
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.BrowserCliApi = BrowserCliApi;
|
|
65
|
+
//# sourceMappingURL=BrowserCliApi.credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrowserCliApi.credentials.js","sourceRoot":"","sources":["../../credentials/BrowserCliApi.credentials.ts"],"names":[],"mappings":";;;AAOA;;;;;;;;;;;GAWG;AACH,MAAa,aAAa;IAA1B;QACE,SAAI,GAAG,eAAe,CAAC;QAEvB,gBAAW,GAAG,iBAAiB,CAAC;QAEhC,qBAAgB,GAAG,uFAAuF,CAAC;QAE3G,eAAU,GAAsB;YAC9B;gBACE,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,uBAAuB;gBAChC,WAAW,EAAE,8BAA8B;gBAC3C,QAAQ,EAAE,IAAI;gBACd,WAAW,EACT,4IAA4I;aAC/I;YACD;gBACE,WAAW,EAAE,OAAO;gBACpB,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,WAAW,EACT,wGAAwG;aAC3G;YACD;gBACE,WAAW,EAAE,mBAAmB;gBAChC,IAAI,EAAE,wBAAwB;gBAC9B,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,KAAK;gBACd,WAAW,EAAE,yGAAyG;aACvH;SACF,CAAC;QAEF,iBAAY,GAAyB;YACnC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACV,OAAO,EAAE;oBACP,aAAa,EAAE,gCAAgC;iBAChD;aACF;SACF,CAAC;QAEF,SAAI,GAA2B;YAC7B,OAAO,EAAE;gBACP,OAAO,EAAE,2BAA2B;gBACpC,GAAG,EAAE,SAAS;gBACd,4BAA4B,EAAE,0CAA0C;aACzE;SACF,CAAC;IACJ,CAAC;CAAA;AApDD,sCAoDC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
export declare class BrowserCli implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BrowserCli = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const request_1 = require("./request");
|
|
6
|
+
/** Only show a property for the given resource/operation combinations. */
|
|
7
|
+
function showFor(resource, operations) {
|
|
8
|
+
return { resource: [resource], operation: operations };
|
|
9
|
+
}
|
|
10
|
+
class BrowserCli {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.description = {
|
|
13
|
+
displayName: 'Browser CLI',
|
|
14
|
+
name: 'browserCli',
|
|
15
|
+
icon: 'file:browserCli.svg',
|
|
16
|
+
group: ['transform'],
|
|
17
|
+
version: 1,
|
|
18
|
+
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
|
19
|
+
description: 'Control a remote browser through a browser-cli serve-http gateway',
|
|
20
|
+
defaults: { name: 'Browser CLI' },
|
|
21
|
+
inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
22
|
+
outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
23
|
+
usableAsTool: true,
|
|
24
|
+
credentials: [{ name: 'browserCliApi', required: true }],
|
|
25
|
+
properties: [
|
|
26
|
+
{
|
|
27
|
+
displayName: 'Resource',
|
|
28
|
+
name: 'resource',
|
|
29
|
+
type: 'options',
|
|
30
|
+
noDataExpression: true,
|
|
31
|
+
options: [
|
|
32
|
+
{ name: 'Tab', value: 'tab' },
|
|
33
|
+
{ name: 'Page', value: 'page' },
|
|
34
|
+
{ name: 'DOM', value: 'dom' },
|
|
35
|
+
{ name: 'Client', value: 'client' },
|
|
36
|
+
{ name: 'Command', value: 'command' },
|
|
37
|
+
{ name: 'Gateway', value: 'gateway' },
|
|
38
|
+
],
|
|
39
|
+
default: 'tab',
|
|
40
|
+
},
|
|
41
|
+
// --- Tab operations ---------------------------------------------------
|
|
42
|
+
{
|
|
43
|
+
displayName: 'Operation',
|
|
44
|
+
name: 'operation',
|
|
45
|
+
type: 'options',
|
|
46
|
+
noDataExpression: true,
|
|
47
|
+
displayOptions: { show: { resource: ['tab'] } },
|
|
48
|
+
options: [
|
|
49
|
+
{ name: 'List', value: 'list', action: 'List open tabs', description: 'GET /tabs (safe)' },
|
|
50
|
+
{ name: 'Open', value: 'open', action: 'Open a URL in a new tab', description: 'navigate.open (needs --allow-control)' },
|
|
51
|
+
{ name: 'Close', value: 'close', action: 'Close tabs', description: 'tabs.close (needs --allow-control)' },
|
|
52
|
+
{ name: 'Get HTML', value: 'getHtml', action: 'Get a tab raw HTML', description: 'tabs.html (needs --allow-read-page)' },
|
|
53
|
+
],
|
|
54
|
+
default: 'list',
|
|
55
|
+
},
|
|
56
|
+
// --- Page operations --------------------------------------------------
|
|
57
|
+
{
|
|
58
|
+
displayName: 'Operation',
|
|
59
|
+
name: 'operation',
|
|
60
|
+
type: 'options',
|
|
61
|
+
noDataExpression: true,
|
|
62
|
+
displayOptions: { show: { resource: ['page'] } },
|
|
63
|
+
options: [
|
|
64
|
+
{ name: 'Get Info', value: 'info', action: 'Get page info', description: 'page.info (safe)' },
|
|
65
|
+
{ name: 'Extract Text', value: 'extractText', action: 'Extract visible text', description: 'extract.text (needs --allow-read-page)' },
|
|
66
|
+
{ name: 'Extract Links', value: 'extractLinks', action: 'Extract links', description: 'extract.links (needs --allow-read-page)' },
|
|
67
|
+
{ name: 'Extract Images', value: 'extractImages', action: 'Extract images', description: 'extract.images (needs --allow-read-page)' },
|
|
68
|
+
{ name: 'Extract HTML', value: 'extractHtml', action: 'Extract HTML', description: 'extract.html (needs --allow-read-page)' },
|
|
69
|
+
{ name: 'Extract Markdown', value: 'extractMarkdown', action: 'Extract Markdown payload', description: 'extract.markdown — returns the raw page payload (not SDK-rendered) (needs --allow-read-page)' },
|
|
70
|
+
],
|
|
71
|
+
default: 'extractText',
|
|
72
|
+
},
|
|
73
|
+
// --- DOM operations ---------------------------------------------------
|
|
74
|
+
{
|
|
75
|
+
displayName: 'Operation',
|
|
76
|
+
name: 'operation',
|
|
77
|
+
type: 'options',
|
|
78
|
+
noDataExpression: true,
|
|
79
|
+
displayOptions: { show: { resource: ['dom'] } },
|
|
80
|
+
options: [
|
|
81
|
+
{ name: 'Query', value: 'query', action: 'Query elements by selector', description: 'dom.query (needs --allow-read-page)' },
|
|
82
|
+
{ name: 'Click', value: 'click', action: 'Click an element', description: 'dom.click (needs --allow-control)' },
|
|
83
|
+
{ name: 'Type', value: 'type', action: 'Type into an element', description: 'dom.type (needs --allow-control)' },
|
|
84
|
+
{ name: 'Eval', value: 'eval', action: 'Evaluate JavaScript', description: 'dom.eval (needs --allow-dangerous)' },
|
|
85
|
+
],
|
|
86
|
+
default: 'query',
|
|
87
|
+
},
|
|
88
|
+
// --- Client operations ------------------------------------------------
|
|
89
|
+
{
|
|
90
|
+
displayName: 'Operation',
|
|
91
|
+
name: 'operation',
|
|
92
|
+
type: 'options',
|
|
93
|
+
noDataExpression: true,
|
|
94
|
+
displayOptions: { show: { resource: ['client'] } },
|
|
95
|
+
options: [
|
|
96
|
+
{ name: 'List', value: 'list', action: 'List connected browser clients', description: 'GET /clients (safe)' },
|
|
97
|
+
],
|
|
98
|
+
default: 'list',
|
|
99
|
+
},
|
|
100
|
+
// --- Command operations -----------------------------------------------
|
|
101
|
+
{
|
|
102
|
+
displayName: 'Operation',
|
|
103
|
+
name: 'operation',
|
|
104
|
+
type: 'options',
|
|
105
|
+
noDataExpression: true,
|
|
106
|
+
displayOptions: { show: { resource: ['command'] } },
|
|
107
|
+
options: [
|
|
108
|
+
{ name: 'Execute', value: 'execute', action: 'Execute a raw browser-cli command', description: 'POST /command (subject to server policy)' },
|
|
109
|
+
],
|
|
110
|
+
default: 'execute',
|
|
111
|
+
},
|
|
112
|
+
// --- Gateway operations -----------------------------------------------
|
|
113
|
+
{
|
|
114
|
+
displayName: 'Operation',
|
|
115
|
+
name: 'operation',
|
|
116
|
+
type: 'options',
|
|
117
|
+
noDataExpression: true,
|
|
118
|
+
displayOptions: { show: { resource: ['gateway'] } },
|
|
119
|
+
options: [
|
|
120
|
+
{ name: 'Health', value: 'health', action: 'Check gateway health', description: 'GET /health (ungated)' },
|
|
121
|
+
],
|
|
122
|
+
default: 'health',
|
|
123
|
+
},
|
|
124
|
+
// --- Shared parameter fields -----------------------------------------
|
|
125
|
+
{
|
|
126
|
+
displayName: 'URL',
|
|
127
|
+
name: 'url',
|
|
128
|
+
type: 'string',
|
|
129
|
+
default: '',
|
|
130
|
+
required: true,
|
|
131
|
+
placeholder: 'https://example.com',
|
|
132
|
+
displayOptions: { show: showFor('tab', ['open']) },
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
displayName: 'Focus Tab',
|
|
136
|
+
name: 'focus',
|
|
137
|
+
type: 'boolean',
|
|
138
|
+
default: false,
|
|
139
|
+
description: 'Whether to focus the new tab/window (steals OS focus). Off opens in the background.',
|
|
140
|
+
displayOptions: { show: showFor('tab', ['open']) },
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
displayName: 'Close By',
|
|
144
|
+
name: 'mode',
|
|
145
|
+
type: 'options',
|
|
146
|
+
default: 'ids',
|
|
147
|
+
options: [
|
|
148
|
+
{ name: 'Tab IDs', value: 'ids' },
|
|
149
|
+
{ name: 'Inactive Tabs', value: 'inactive' },
|
|
150
|
+
{ name: 'Duplicate Tabs', value: 'duplicates' },
|
|
151
|
+
],
|
|
152
|
+
displayOptions: { show: showFor('tab', ['close']) },
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
displayName: 'Tab IDs',
|
|
156
|
+
name: 'tabIds',
|
|
157
|
+
type: 'string',
|
|
158
|
+
default: '',
|
|
159
|
+
placeholder: '123, 456',
|
|
160
|
+
description: 'Comma/space separated tab IDs, or a JSON array',
|
|
161
|
+
displayOptions: { show: { resource: ['tab'], operation: ['close'], mode: ['ids'] } },
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
displayName: 'Tab ID',
|
|
165
|
+
name: 'tabId',
|
|
166
|
+
type: 'number',
|
|
167
|
+
default: 0,
|
|
168
|
+
description: 'Target tab ID. Leave 0 for the active tab.',
|
|
169
|
+
displayOptions: { show: { resource: ['tab'], operation: ['getHtml'] } },
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
displayName: 'Selector',
|
|
173
|
+
name: 'selector',
|
|
174
|
+
type: 'string',
|
|
175
|
+
default: '',
|
|
176
|
+
placeholder: '#main, .content',
|
|
177
|
+
description: 'CSS selector. Leave empty on extract operations to use the whole page.',
|
|
178
|
+
displayOptions: {
|
|
179
|
+
show: {
|
|
180
|
+
resource: ['dom', 'page'],
|
|
181
|
+
operation: ['query', 'click', 'type', 'extractText', 'extractLinks', 'extractImages', 'extractHtml', 'extractMarkdown'],
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
displayName: 'Text',
|
|
187
|
+
name: 'text',
|
|
188
|
+
type: 'string',
|
|
189
|
+
default: '',
|
|
190
|
+
required: true,
|
|
191
|
+
displayOptions: { show: showFor('dom', ['type']) },
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
displayName: 'JavaScript',
|
|
195
|
+
name: 'code',
|
|
196
|
+
type: 'string',
|
|
197
|
+
typeOptions: { rows: 4 },
|
|
198
|
+
default: '',
|
|
199
|
+
required: true,
|
|
200
|
+
placeholder: 'return document.title',
|
|
201
|
+
description: 'Evaluated in the page (dom.eval). The gateway must be started with --allow-dangerous.',
|
|
202
|
+
displayOptions: { show: showFor('dom', ['eval']) },
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
displayName: 'Tab ID',
|
|
206
|
+
name: 'tabId',
|
|
207
|
+
type: 'number',
|
|
208
|
+
default: 0,
|
|
209
|
+
description: 'Target tab ID. Leave 0 for the active tab.',
|
|
210
|
+
displayOptions: { show: { resource: ['dom'], operation: ['eval'] } },
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
displayName: 'Command',
|
|
214
|
+
name: 'command',
|
|
215
|
+
type: 'string',
|
|
216
|
+
default: '',
|
|
217
|
+
required: true,
|
|
218
|
+
placeholder: 'tabs.list',
|
|
219
|
+
description: 'Raw browser-cli command name, e.g. tabs.list, navigate.open, extract.markdown',
|
|
220
|
+
displayOptions: { show: showFor('command', ['execute']) },
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
displayName: 'Arguments',
|
|
224
|
+
name: 'args',
|
|
225
|
+
type: 'json',
|
|
226
|
+
default: '{}',
|
|
227
|
+
description: 'JSON object of command arguments',
|
|
228
|
+
displayOptions: { show: showFor('command', ['execute']) },
|
|
229
|
+
},
|
|
230
|
+
],
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
async execute() {
|
|
234
|
+
const items = this.getInputData();
|
|
235
|
+
const returnData = [];
|
|
236
|
+
const baseUrl = String((await this.getCredentials('browserCliApi')).baseUrl || '').replace(/\/+$/, '');
|
|
237
|
+
for (let i = 0; i < items.length; i++) {
|
|
238
|
+
try {
|
|
239
|
+
const resource = this.getNodeParameter('resource', i);
|
|
240
|
+
const operation = this.getNodeParameter('operation', i);
|
|
241
|
+
const params = collectParams(this, resource, operation, i);
|
|
242
|
+
const request = (0, request_1.buildGatewayRequest)(resource, operation, params);
|
|
243
|
+
const options = {
|
|
244
|
+
method: request.method,
|
|
245
|
+
url: `${baseUrl}${request.path}`,
|
|
246
|
+
json: true,
|
|
247
|
+
};
|
|
248
|
+
if (request.body)
|
|
249
|
+
options.body = request.body;
|
|
250
|
+
const response = await this.helpers.httpRequestWithAuthentication.call(this, 'browserCliApi', options);
|
|
251
|
+
const rows = Array.isArray(response) ? response : [response];
|
|
252
|
+
for (const row of rows) {
|
|
253
|
+
returnData.push({
|
|
254
|
+
json: isObject(row) ? row : { result: row },
|
|
255
|
+
pairedItem: { item: i },
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
if (this.continueOnFail()) {
|
|
261
|
+
returnData.push({ json: { error: error.message }, pairedItem: { item: i } });
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error, { itemIndex: i });
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return [returnData];
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
exports.BrowserCli = BrowserCli;
|
|
271
|
+
function isObject(value) {
|
|
272
|
+
return typeof value === 'object' && value !== null;
|
|
273
|
+
}
|
|
274
|
+
/** Read the UI fields relevant to this operation into a plain params object. */
|
|
275
|
+
function collectParams(ctx, resource, operation, i) {
|
|
276
|
+
const get = (name, fallback = undefined) => ctx.getNodeParameter(name, i, fallback);
|
|
277
|
+
const key = `${resource}:${operation}`;
|
|
278
|
+
switch (key) {
|
|
279
|
+
case 'command:execute': {
|
|
280
|
+
const raw = get('args', {});
|
|
281
|
+
let args = {};
|
|
282
|
+
if (typeof raw === 'string') {
|
|
283
|
+
const trimmed = raw.trim();
|
|
284
|
+
args = trimmed ? JSON.parse(trimmed) : {};
|
|
285
|
+
}
|
|
286
|
+
else if (isObject(raw)) {
|
|
287
|
+
args = raw;
|
|
288
|
+
}
|
|
289
|
+
return { command: get('command'), args };
|
|
290
|
+
}
|
|
291
|
+
case 'tab:open':
|
|
292
|
+
return { url: get('url'), focus: get('focus', false) };
|
|
293
|
+
case 'tab:close':
|
|
294
|
+
return { mode: get('mode', 'ids'), tabIds: get('tabIds', '') };
|
|
295
|
+
case 'tab:getHtml':
|
|
296
|
+
return { tabId: get('tabId', 0) };
|
|
297
|
+
case 'dom:query':
|
|
298
|
+
case 'dom:click':
|
|
299
|
+
return { selector: get('selector', '') };
|
|
300
|
+
case 'dom:type':
|
|
301
|
+
return { selector: get('selector', ''), text: get('text', '') };
|
|
302
|
+
case 'dom:eval':
|
|
303
|
+
return { code: get('code', ''), tabId: get('tabId', 0) };
|
|
304
|
+
case 'page:extractText':
|
|
305
|
+
case 'page:extractLinks':
|
|
306
|
+
case 'page:extractImages':
|
|
307
|
+
case 'page:extractHtml':
|
|
308
|
+
case 'page:extractMarkdown':
|
|
309
|
+
return { selector: get('selector', '') };
|
|
310
|
+
default:
|
|
311
|
+
return {};
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
//# sourceMappingURL=BrowserCli.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrowserCli.node.js","sourceRoot":"","sources":["../../../nodes/BrowserCli/BrowserCli.node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-labelledby="title">
|
|
2
|
+
<title>browser-cli icon</title>
|
|
3
|
+
<defs>
|
|
4
|
+
<linearGradient id="bg" x1="16" y1="16" x2="112" y2="112" gradientUnits="userSpaceOnUse">
|
|
5
|
+
<stop offset="0" stop-color="#0f766e" />
|
|
6
|
+
<stop offset="1" stop-color="#0f172a" />
|
|
7
|
+
</linearGradient>
|
|
8
|
+
<linearGradient id="panel" x1="32" y1="29" x2="96" y2="99" gradientUnits="userSpaceOnUse">
|
|
9
|
+
<stop offset="0" stop-color="#f8fafc" />
|
|
10
|
+
<stop offset="1" stop-color="#cbd5e1" />
|
|
11
|
+
</linearGradient>
|
|
12
|
+
</defs>
|
|
13
|
+
|
|
14
|
+
<!-- Chrome Web Store compliant: 96x96 artwork centered in 128x128 canvas. -->
|
|
15
|
+
<rect x="16" y="16" width="96" height="96" rx="24" fill="url(#bg)" />
|
|
16
|
+
<rect x="17" y="17" width="94" height="94" rx="23" fill="none" stroke="#ccfbf1" stroke-opacity="0.55" stroke-width="2" />
|
|
17
|
+
|
|
18
|
+
<rect x="32" y="31" width="64" height="54" rx="11" fill="url(#panel)" />
|
|
19
|
+
<path d="M32 42c0-6.075 4.925-11 11-11h42c6.075 0 11 4.925 11 11v3H32z" fill="#94a3b8" />
|
|
20
|
+
<circle cx="42" cy="38.5" r="2.2" fill="#f8fafc" />
|
|
21
|
+
<circle cx="49" cy="38.5" r="2.2" fill="#f8fafc" opacity="0.85" />
|
|
22
|
+
<circle cx="56" cy="38.5" r="2.2" fill="#f8fafc" opacity="0.7" />
|
|
23
|
+
|
|
24
|
+
<path d="M49 57 40 64l9 7" fill="none" stroke="#0f172a" stroke-linecap="round" stroke-linejoin="round" stroke-width="7" />
|
|
25
|
+
<path d="M62 55h17" fill="none" stroke="#0f766e" stroke-linecap="round" stroke-width="7" />
|
|
26
|
+
<path d="M62 67h23" fill="none" stroke="#0f766e" stroke-linecap="round" stroke-width="7" />
|
|
27
|
+
|
|
28
|
+
<rect x="70" y="78" width="22" height="15" rx="5" fill="#14b8a6" />
|
|
29
|
+
<rect x="59" y="84" width="22" height="15" rx="5" fill="#2dd4bf" />
|
|
30
|
+
<rect x="48" y="90" width="22" height="15" rx="5" fill="#99f6e4" />
|
|
31
|
+
</svg>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure request mapping for the browser-cli serve-http gateway.
|
|
3
|
+
*
|
|
4
|
+
* This module deliberately imports nothing from n8n so it can be unit-tested
|
|
5
|
+
* with a plain TypeScript/esbuild toolchain. The node layer collects UI
|
|
6
|
+
* parameters into a plain object and asks here for the HTTP request to make.
|
|
7
|
+
*
|
|
8
|
+
* The gateway only exposes four routes:
|
|
9
|
+
* GET /health -> {ok: true} (ungated)
|
|
10
|
+
* GET /tabs -> Tab[] (safe)
|
|
11
|
+
* GET /clients -> Client[] (safe)
|
|
12
|
+
* POST /command -> {result: <raw command output>}
|
|
13
|
+
*
|
|
14
|
+
* Every convenience operation below is just a typed wrapper around POST
|
|
15
|
+
* /command, so what the gateway returns is the *raw* extension result for that
|
|
16
|
+
* command (no SDK-side rendering). The command itself is still subject to the
|
|
17
|
+
* server's --allow-* policy, so each operation lists the policy tier it needs.
|
|
18
|
+
*/
|
|
19
|
+
export type HttpMethod = 'GET' | 'POST';
|
|
20
|
+
export interface GatewayRequest {
|
|
21
|
+
method: HttpMethod;
|
|
22
|
+
/** Path appended to the credential base URL, e.g. "/tabs" or "/command". */
|
|
23
|
+
path: string;
|
|
24
|
+
/** JSON body, only present for POST /command. */
|
|
25
|
+
body?: {
|
|
26
|
+
command: string;
|
|
27
|
+
args: Record<string, unknown>;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export type GatewayParams = Record<string, unknown>;
|
|
31
|
+
/** Build a POST /command request for a raw browser-cli command. */
|
|
32
|
+
export declare function commandRequest(command: string, args?: Record<string, unknown>): GatewayRequest;
|
|
33
|
+
/**
|
|
34
|
+
* Map a (resource, operation) pair plus collected parameters to a single
|
|
35
|
+
* gateway HTTP request. Throws on an unknown pairing so the node fails loudly
|
|
36
|
+
* rather than silently issuing a wrong call.
|
|
37
|
+
*/
|
|
38
|
+
export declare function buildGatewayRequest(resource: string, operation: string, params: GatewayParams): GatewayRequest;
|
|
39
|
+
/** Accept an array, a JSON array string, or a comma/space separated list. */
|
|
40
|
+
export declare function parseTabIds(value: unknown): number[];
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pure request mapping for the browser-cli serve-http gateway.
|
|
4
|
+
*
|
|
5
|
+
* This module deliberately imports nothing from n8n so it can be unit-tested
|
|
6
|
+
* with a plain TypeScript/esbuild toolchain. The node layer collects UI
|
|
7
|
+
* parameters into a plain object and asks here for the HTTP request to make.
|
|
8
|
+
*
|
|
9
|
+
* The gateway only exposes four routes:
|
|
10
|
+
* GET /health -> {ok: true} (ungated)
|
|
11
|
+
* GET /tabs -> Tab[] (safe)
|
|
12
|
+
* GET /clients -> Client[] (safe)
|
|
13
|
+
* POST /command -> {result: <raw command output>}
|
|
14
|
+
*
|
|
15
|
+
* Every convenience operation below is just a typed wrapper around POST
|
|
16
|
+
* /command, so what the gateway returns is the *raw* extension result for that
|
|
17
|
+
* command (no SDK-side rendering). The command itself is still subject to the
|
|
18
|
+
* server's --allow-* policy, so each operation lists the policy tier it needs.
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.commandRequest = commandRequest;
|
|
22
|
+
exports.buildGatewayRequest = buildGatewayRequest;
|
|
23
|
+
exports.parseTabIds = parseTabIds;
|
|
24
|
+
/** Build a POST /command request for a raw browser-cli command. */
|
|
25
|
+
function commandRequest(command, args = {}) {
|
|
26
|
+
return { method: 'POST', path: '/command', body: { command, args } };
|
|
27
|
+
}
|
|
28
|
+
function str(params, key) {
|
|
29
|
+
const value = params[key];
|
|
30
|
+
return value === undefined || value === null ? '' : String(value);
|
|
31
|
+
}
|
|
32
|
+
/** Drop keys whose value is undefined/null/"" so we don't send empty args. */
|
|
33
|
+
function compact(args) {
|
|
34
|
+
const out = {};
|
|
35
|
+
for (const [key, value] of Object.entries(args)) {
|
|
36
|
+
if (value !== undefined && value !== null && value !== '')
|
|
37
|
+
out[key] = value;
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Map a (resource, operation) pair plus collected parameters to a single
|
|
43
|
+
* gateway HTTP request. Throws on an unknown pairing so the node fails loudly
|
|
44
|
+
* rather than silently issuing a wrong call.
|
|
45
|
+
*/
|
|
46
|
+
function buildGatewayRequest(resource, operation, params) {
|
|
47
|
+
const key = `${resource}:${operation}`;
|
|
48
|
+
switch (key) {
|
|
49
|
+
// --- Raw escape hatch -------------------------------------------------
|
|
50
|
+
case 'command:execute': {
|
|
51
|
+
const command = str(params, 'command');
|
|
52
|
+
const args = params.args ?? {};
|
|
53
|
+
return commandRequest(command, args);
|
|
54
|
+
}
|
|
55
|
+
// --- Tabs -------------------------------------------------------------
|
|
56
|
+
case 'tab:list':
|
|
57
|
+
return { method: 'GET', path: '/tabs' };
|
|
58
|
+
case 'tab:open': {
|
|
59
|
+
const focus = Boolean(params.focus);
|
|
60
|
+
return commandRequest('navigate.open', compact({
|
|
61
|
+
url: str(params, 'url'),
|
|
62
|
+
focus,
|
|
63
|
+
background: !focus,
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
case 'tab:close': {
|
|
67
|
+
const mode = str(params, 'mode') || 'ids';
|
|
68
|
+
if (mode === 'inactive')
|
|
69
|
+
return commandRequest('tabs.close', { inactive: true });
|
|
70
|
+
if (mode === 'duplicates')
|
|
71
|
+
return commandRequest('tabs.close', { duplicates: true });
|
|
72
|
+
const ids = parseTabIds(params.tabIds);
|
|
73
|
+
return commandRequest('tabs.close', { tab_ids: ids });
|
|
74
|
+
}
|
|
75
|
+
case 'tab:getHtml':
|
|
76
|
+
return commandRequest('tabs.html', compact({ tabId: tabIdArg(params.tabId) }));
|
|
77
|
+
// --- Page / extraction ------------------------------------------------
|
|
78
|
+
case 'page:info':
|
|
79
|
+
return commandRequest('page.info', {});
|
|
80
|
+
case 'page:extractText':
|
|
81
|
+
return commandRequest('extract.text', compact({ selector: str(params, 'selector') }));
|
|
82
|
+
case 'page:extractLinks':
|
|
83
|
+
return commandRequest('extract.links', compact({ selector: str(params, 'selector') }));
|
|
84
|
+
case 'page:extractImages':
|
|
85
|
+
return commandRequest('extract.images', compact({ selector: str(params, 'selector') }));
|
|
86
|
+
case 'page:extractHtml':
|
|
87
|
+
return commandRequest('extract.html', compact({ selector: str(params, 'selector') }));
|
|
88
|
+
case 'page:extractMarkdown':
|
|
89
|
+
return commandRequest('extract.markdown', compact({ selector: str(params, 'selector') }));
|
|
90
|
+
// --- DOM --------------------------------------------------------------
|
|
91
|
+
case 'dom:query':
|
|
92
|
+
return commandRequest('dom.query', { selector: str(params, 'selector') });
|
|
93
|
+
case 'dom:click':
|
|
94
|
+
return commandRequest('dom.click', { selector: str(params, 'selector') });
|
|
95
|
+
case 'dom:type':
|
|
96
|
+
return commandRequest('dom.type', { selector: str(params, 'selector'), text: str(params, 'text') });
|
|
97
|
+
case 'dom:eval':
|
|
98
|
+
return commandRequest('dom.eval', compact({ code: str(params, 'code'), tabId: tabIdArg(params.tabId) }));
|
|
99
|
+
// --- Clients / gateway ------------------------------------------------
|
|
100
|
+
case 'client:list':
|
|
101
|
+
return { method: 'GET', path: '/clients' };
|
|
102
|
+
case 'gateway:health':
|
|
103
|
+
return { method: 'GET', path: '/health' };
|
|
104
|
+
default:
|
|
105
|
+
throw new Error(`Unsupported operation "${operation}" for resource "${resource}"`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/** A tab ID arg; 0 (the UI default) means "active tab", so it is omitted. */
|
|
109
|
+
function tabIdArg(value) {
|
|
110
|
+
if (value === undefined || value === null || value === '')
|
|
111
|
+
return undefined;
|
|
112
|
+
const n = Number(value);
|
|
113
|
+
return Number.isFinite(n) && n > 0 ? n : undefined;
|
|
114
|
+
}
|
|
115
|
+
/** Accept an array, a JSON array string, or a comma/space separated list. */
|
|
116
|
+
function parseTabIds(value) {
|
|
117
|
+
if (Array.isArray(value))
|
|
118
|
+
return value.map(Number).filter(Number.isFinite);
|
|
119
|
+
if (typeof value === 'number')
|
|
120
|
+
return [value];
|
|
121
|
+
const raw = String(value ?? '').trim();
|
|
122
|
+
if (!raw)
|
|
123
|
+
return [];
|
|
124
|
+
if (raw.startsWith('[')) {
|
|
125
|
+
try {
|
|
126
|
+
const parsed = JSON.parse(raw);
|
|
127
|
+
if (Array.isArray(parsed))
|
|
128
|
+
return parsed.map(Number).filter(Number.isFinite);
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
/* fall through to split */
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return raw
|
|
135
|
+
.split(/[\s,]+/)
|
|
136
|
+
.map((part) => Number(part))
|
|
137
|
+
.filter(Number.isFinite);
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=request.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../../nodes/BrowserCli/request.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "n8n-nodes-browser-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "n8n community node that controls a remote browser through a browser-cli serve-http gateway",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"n8n-community-node-package",
|
|
7
|
+
"browser-cli",
|
|
8
|
+
"browser",
|
|
9
|
+
"automation",
|
|
10
|
+
"n8n"
|
|
11
|
+
],
|
|
12
|
+
"license": "PolyForm-Noncommercial-1.0.0",
|
|
13
|
+
"homepage": "https://chromewebstore.google.com/detail/browser-cli/hekaebjhbhhdbmakimmaklbblbmccahp",
|
|
14
|
+
"author": "Daniel Dolezal",
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc && node scripts/copy-assets.mjs",
|
|
17
|
+
"dev": "tsc --watch",
|
|
18
|
+
"test": "node scripts/run-tests.mjs",
|
|
19
|
+
"prepublishOnly": "npm run build"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"n8n": {
|
|
25
|
+
"n8nNodesApiVersion": 1,
|
|
26
|
+
"credentials": [
|
|
27
|
+
"dist/credentials/BrowserCliApi.credentials.js"
|
|
28
|
+
],
|
|
29
|
+
"nodes": [
|
|
30
|
+
"dist/nodes/BrowserCli/BrowserCli.node.js"
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^22.0.0",
|
|
35
|
+
"esbuild": "^0.28.0",
|
|
36
|
+
"n8n-workflow": "*",
|
|
37
|
+
"typescript": "^5.6.0"
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"n8n-workflow": "*"
|
|
41
|
+
}
|
|
42
|
+
}
|