@browserless/function 10.9.16 → 10.9.18
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 +185 -6
- package/package.json +12 -10
package/README.md
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
<div align="center">
|
|
2
|
-
<br>
|
|
3
2
|
<img style="width: 500px; margin:3rem 0 1.5rem;" src="https://github.com/microlinkhq/browserless/raw/master/static/logo-banner.png#gh-light-mode-only" alt="browserless">
|
|
4
3
|
<img style="width: 500px; margin:3rem 0 1.5rem;" src="https://github.com/microlinkhq/browserless/raw/master/static/logo-banner-light.png#gh-dark-mode-only" alt="browserless">
|
|
5
|
-
<br>
|
|
6
|
-
<
|
|
7
|
-
<
|
|
8
|
-
<
|
|
9
|
-
<
|
|
4
|
+
<br><br>
|
|
5
|
+
<a href="https://microlink.io"><img src="https://img.shields.io/badge/powered_by-microlink.io-blue?style=flat-square&color=%23EA407B" alt="Powered by microlink.io"></a>
|
|
6
|
+
<img src="https://img.shields.io/github/tag/microlinkhq/browserless.svg?style=flat-square" alt="Last version">
|
|
7
|
+
<a href="https://coveralls.io/github/microlinkhq/browserless"><img src="https://img.shields.io/coveralls/microlinkhq/browserless.svg?style=flat-square" alt="Coverage Status"></a>
|
|
8
|
+
<a href="https://www.npmjs.org/package/browserless"><img src="https://img.shields.io/npm/dm/browserless.svg?style=flat-square" alt="NPM Status"></a>
|
|
9
|
+
<br><br>
|
|
10
10
|
</div>
|
|
11
11
|
|
|
12
|
+
> @browserless/function: Run abritrary JavaScript inside a browser sandbox.
|
|
13
|
+
|
|
14
|
+
See [function section](https://browserless.js.org/#/?id=function) our website for more information.
|
|
15
|
+
|
|
12
16
|
## Install
|
|
13
17
|
|
|
14
18
|
Using npm:
|
|
@@ -17,6 +21,181 @@ Using npm:
|
|
|
17
21
|
npm install @browserless/function --save
|
|
18
22
|
```
|
|
19
23
|
|
|
24
|
+
## About
|
|
25
|
+
|
|
26
|
+
This package provides a **secure sandbox** for running arbitrary JavaScript code with runtime access to a browser page. It executes user-provided functions in an isolated VM environment, with optional access to Puppeteer's page API.
|
|
27
|
+
|
|
28
|
+
### What this package does
|
|
29
|
+
|
|
30
|
+
The `@browserless/function` package allows you to:
|
|
31
|
+
|
|
32
|
+
- **Execute arbitrary JavaScript** in a secure, isolated VM sandbox
|
|
33
|
+
- **Access the browser page** from within the sandbox for DOM manipulation
|
|
34
|
+
- **Capture console output** and execution profiling data
|
|
35
|
+
- **Pass custom data** to the sandboxed function at runtime
|
|
36
|
+
- **Handle errors gracefully** with structured result objects
|
|
37
|
+
|
|
38
|
+
### Usage
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
const createFunction = require('@browserless/function')
|
|
42
|
+
|
|
43
|
+
// Simple function without page access
|
|
44
|
+
const code = ({ query }) => query.value * 2
|
|
45
|
+
|
|
46
|
+
const myFn = createFunction(code)
|
|
47
|
+
const result = await myFn('https://example.com', { query: { value: 21 } })
|
|
48
|
+
|
|
49
|
+
console.log(result)
|
|
50
|
+
// => { isFulfilled: true, value: 42, profiling: {...}, logging: {...} }
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Accessing the page
|
|
54
|
+
|
|
55
|
+
When your code references `page`, browserless automatically provides access to the Puppeteer page:
|
|
56
|
+
|
|
57
|
+
```js
|
|
58
|
+
const createFunction = require('@browserless/function')
|
|
59
|
+
|
|
60
|
+
// Function with page access
|
|
61
|
+
const code = async ({ page }) => {
|
|
62
|
+
const title = await page.title()
|
|
63
|
+
const content = await page.evaluate(() => document.body.innerText)
|
|
64
|
+
return { title, content }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const scraper = createFunction(code)
|
|
68
|
+
const result = await scraper('https://example.com')
|
|
69
|
+
|
|
70
|
+
console.log(result)
|
|
71
|
+
// => { isFulfilled: true, value: { title: 'Example', content: '...' }, ... }
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Available context
|
|
75
|
+
|
|
76
|
+
The sandboxed function receives these properties:
|
|
77
|
+
|
|
78
|
+
| Property | Description |
|
|
79
|
+
|----------|-------------|
|
|
80
|
+
| `page` | Puppeteer [Page](https://pptr.dev/api/puppeteer.page) object (if referenced in code) |
|
|
81
|
+
| `device` | Device descriptor with `userAgent` and `viewport` |
|
|
82
|
+
| `...opts` | Any custom options passed at runtime |
|
|
83
|
+
|
|
84
|
+
### Result object
|
|
85
|
+
|
|
86
|
+
The function returns a structured result:
|
|
87
|
+
|
|
88
|
+
| Property | Description |
|
|
89
|
+
|----------|-------------|
|
|
90
|
+
| `isFulfilled` | `true` if execution succeeded, `false` if error |
|
|
91
|
+
| `value` | Return value (success) or error object (failure) |
|
|
92
|
+
| `profiling` | Execution timing and performance data |
|
|
93
|
+
| `logging` | Captured console output (`log`, `warn`, `error`, etc.) |
|
|
94
|
+
|
|
95
|
+
### Options
|
|
96
|
+
|
|
97
|
+
```js
|
|
98
|
+
const myFn = createFunction(code, {
|
|
99
|
+
// Browserless instance factory
|
|
100
|
+
getBrowserless: () => require('browserless')(),
|
|
101
|
+
|
|
102
|
+
// Number of retries on failure
|
|
103
|
+
retry: 2,
|
|
104
|
+
|
|
105
|
+
// Execution timeout in milliseconds
|
|
106
|
+
timeout: 30000,
|
|
107
|
+
|
|
108
|
+
// Options passed to browserless.goto()
|
|
109
|
+
gotoOpts: {
|
|
110
|
+
scripts: ['https://cdn.example.com/library.js'],
|
|
111
|
+
waitUntil: 'networkidle0'
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
// VM sandbox options (passed to isolated-function)
|
|
115
|
+
vmOpts: { /* ... */ }
|
|
116
|
+
})
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Examples
|
|
120
|
+
|
|
121
|
+
#### Interact with page elements
|
|
122
|
+
|
|
123
|
+
```js
|
|
124
|
+
const createFunction = require('@browserless/function')
|
|
125
|
+
|
|
126
|
+
const code = async ({ page }) => {
|
|
127
|
+
await page.waitForSelector('button.submit')
|
|
128
|
+
await page.type('input', 'test@test.com', { delay: 200 })
|
|
129
|
+
await page.click('button.submit')
|
|
130
|
+
await page.waitForNavigation()
|
|
131
|
+
return page.title()
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const clickAndGetTitle = createFunction(code)
|
|
135
|
+
const result = await clickAndGetTitle('https://example.com')
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
#### Inject external scripts
|
|
139
|
+
|
|
140
|
+
```js
|
|
141
|
+
const createFunction = require('@browserless/function')
|
|
142
|
+
|
|
143
|
+
const code = ({ page }) => page.evaluate('jQuery.fn.jquery')
|
|
144
|
+
|
|
145
|
+
const getjQueryVersion = createFunction(code, {
|
|
146
|
+
gotoOpts: {
|
|
147
|
+
scripts: ['https://code.jquery.com/jquery-3.6.0.min.js']
|
|
148
|
+
}
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
const result = await getjQueryVersion('https://example.com')
|
|
152
|
+
// => { isFulfilled: true, value: '3.6.0', ... }
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
#### Use npm modules in sandbox
|
|
156
|
+
|
|
157
|
+
```js
|
|
158
|
+
const createFunction = require('@browserless/function')
|
|
159
|
+
|
|
160
|
+
const code = async ({ page }) => {
|
|
161
|
+
const _ = require('lodash')
|
|
162
|
+
const text = await page.evaluate(() => document.body.innerText)
|
|
163
|
+
return _.words(text).length
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const countWords = createFunction(code)
|
|
167
|
+
const result = await countWords('https://example.com')
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
#### Handle errors
|
|
171
|
+
|
|
172
|
+
```js
|
|
173
|
+
const createFunction = require('@browserless/function')
|
|
174
|
+
|
|
175
|
+
const code = () => {
|
|
176
|
+
throw new Error('Something went wrong')
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const myFn = createFunction(code)
|
|
180
|
+
const result = await myFn('https://example.com')
|
|
181
|
+
|
|
182
|
+
console.log(result.isFulfilled) // => false
|
|
183
|
+
console.log(result.value.message) // => 'Something went wrong'
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### How it fits in the monorepo
|
|
187
|
+
|
|
188
|
+
This is an **extended functionality package** for advanced use cases. It makes the repository more extensible and customizable for any edge case you may encounter.
|
|
189
|
+
|
|
190
|
+
### Dependencies
|
|
191
|
+
|
|
192
|
+
| Package | Purpose |
|
|
193
|
+
|---------|---------|
|
|
194
|
+
| `@browserless/errors` | Error normalization and typed errors |
|
|
195
|
+
| `isolated-function` | Secure VM sandbox execution |
|
|
196
|
+
| `require-one-of` | Auto-detects browserless installation |
|
|
197
|
+
| `acorn` / `acorn-walk` | AST parsing to detect page usage in code |
|
|
198
|
+
|
|
20
199
|
## License
|
|
21
200
|
|
|
22
201
|
**@browserless/functions** © [Microlink](https://microlink.io), released under the [MIT](https://github.com/microlinkhq/browserless/blob/master/LICENSE.md) License.<br>
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@browserless/function",
|
|
3
|
-
"description": "
|
|
3
|
+
"description": "Execute arbitrary JavaScript code in a secure browser sandbox with access to page DOM and network.",
|
|
4
4
|
"homepage": "https://browserless.js.org",
|
|
5
|
-
"version": "10.9.
|
|
5
|
+
"version": "10.9.18",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"author": {
|
|
8
8
|
"email": "hello@microlink.io",
|
|
@@ -18,23 +18,25 @@
|
|
|
18
18
|
"url": "https://github.com/microlinkhq/browserless/issues"
|
|
19
19
|
},
|
|
20
20
|
"keywords": [
|
|
21
|
-
"browser",
|
|
22
21
|
"browserless",
|
|
23
|
-
"chrome",
|
|
24
|
-
"chromeless",
|
|
25
|
-
"core",
|
|
26
22
|
"function",
|
|
23
|
+
"javascript",
|
|
27
24
|
"headless",
|
|
25
|
+
"chrome",
|
|
28
26
|
"puppeteer",
|
|
29
|
-
"
|
|
27
|
+
"sandbox",
|
|
28
|
+
"execution",
|
|
29
|
+
"serverless",
|
|
30
|
+
"vm",
|
|
31
|
+
"isolate"
|
|
30
32
|
],
|
|
31
33
|
"dependencies": {
|
|
32
|
-
"@browserless/errors": "^10.9.
|
|
34
|
+
"@browserless/errors": "^10.9.18",
|
|
33
35
|
"isolated-function": "~0.1.48",
|
|
34
36
|
"require-one-of": "~1.0.24"
|
|
35
37
|
},
|
|
36
38
|
"devDependencies": {
|
|
37
|
-
"@browserless/test": "^10.9.
|
|
39
|
+
"@browserless/test": "^10.9.18",
|
|
38
40
|
"acorn": "~8.15.0",
|
|
39
41
|
"acorn-walk": "~8.3.4",
|
|
40
42
|
"ava": "5",
|
|
@@ -55,5 +57,5 @@
|
|
|
55
57
|
"timeout": "2m",
|
|
56
58
|
"workerThreads": false
|
|
57
59
|
},
|
|
58
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "f5e8cd0788e4bad3b3ad9b007943754f96653817"
|
|
59
61
|
}
|