@browserless.io/browserless 2.0.0-beta-4 → 2.0.0-beta-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.
- package/LICENSE +2 -0
- package/README.md +11 -11
- package/bin/browserless.js +155 -11
- package/bin/scaffold/README.md +415 -0
- package/bin/scaffold/package.json +21 -0
- package/bin/scaffold/src/hello-world.http.ts +25 -0
- package/bin/scaffold/tsconfig.json +4 -0
- package/build/browserless.js +18 -15
- package/build/browsers/index.d.ts +2 -18
- package/build/browsers/index.js +43 -14
- package/build/http.d.ts +3 -3
- package/build/http.js +3 -3
- package/build/router.js +2 -4
- package/build/routes/chromium/http/content-post.body.json +8 -8
- package/build/routes/chromium/http/content-post.d.ts +15 -3
- package/build/routes/chromium/http/content-post.js +14 -15
- package/build/routes/chromium/http/download-post.d.ts +16 -3
- package/build/routes/chromium/http/download-post.js +17 -22
- package/build/routes/chromium/http/function-post.d.ts +16 -3
- package/build/routes/chromium/http/function-post.js +17 -22
- package/build/routes/chromium/http/pdf-post.body.json +8 -8
- package/build/routes/chromium/http/pdf-post.d.ts +15 -3
- package/build/routes/chromium/http/pdf-post.js +19 -15
- package/build/routes/chromium/http/performance.d.ts +15 -3
- package/build/routes/chromium/http/performance.js +15 -23
- package/build/routes/chromium/http/scrape-post.body.json +8 -8
- package/build/routes/chromium/http/scrape-post.d.ts +15 -3
- package/build/routes/chromium/http/scrape-post.js +15 -16
- package/build/routes/chromium/http/screenshot-post.body.json +8 -8
- package/build/routes/chromium/http/screenshot-post.d.ts +15 -3
- package/build/routes/chromium/http/screenshot-post.js +18 -15
- package/build/routes/chromium/tests/websocket.spec.js +20 -1
- package/build/routes/chromium/utils/function/handler.js +2 -2
- package/build/routes/chromium/ws/browser.d.ts +13 -3
- package/build/routes/chromium/ws/browser.js +10 -11
- package/build/routes/chromium/ws/cdp-chromium.d.ts +13 -3
- package/build/routes/chromium/ws/cdp-chromium.js +10 -11
- package/build/routes/chromium/ws/page.d.ts +13 -3
- package/build/routes/chromium/ws/page.js +10 -11
- package/build/routes/chromium/ws/playwright-chromium.d.ts +13 -3
- package/build/routes/chromium/ws/playwright-chromium.js +11 -12
- package/build/routes/firefox/ws/playwright-firefox.d.ts +13 -3
- package/build/routes/firefox/ws/playwright-firefox.js +11 -12
- package/build/routes/management/http/config-get.d.ts +15 -3
- package/build/routes/management/http/config-get.js +15 -20
- package/build/routes/management/http/metrics-get.d.ts +15 -3
- package/build/routes/management/http/metrics-get.js +16 -21
- package/build/routes/management/http/metrics-total-get.d.ts +15 -3
- package/build/routes/management/http/metrics-total-get.js +16 -21
- package/build/routes/management/http/sessions-get.d.ts +15 -3
- package/build/routes/management/http/sessions-get.js +16 -20
- package/build/routes/management/http/static-get.d.ts +15 -3
- package/build/routes/management/http/static-get.js +15 -20
- package/build/routes/webkit/ws/playwright-webkit.d.ts +13 -3
- package/build/routes/webkit/ws/playwright-webkit.js +11 -12
- package/build/server.js +0 -1
- package/build/types.d.ts +48 -38
- package/build/types.js +135 -0
- package/extensions/ublock/1p-filters.html +0 -1
- package/extensions/ublock/3p-filters.html +0 -2
- package/extensions/ublock/_locales/bg/messages.json +6 -6
- package/extensions/ublock/_locales/br_FR/messages.json +14 -14
- package/extensions/ublock/_locales/bs/messages.json +8 -8
- package/extensions/ublock/_locales/ca/messages.json +1 -1
- package/extensions/ublock/_locales/da/messages.json +5 -5
- package/extensions/ublock/_locales/fa/messages.json +1 -1
- package/extensions/ublock/_locales/fi/messages.json +6 -6
- package/extensions/ublock/_locales/hr/messages.json +4 -4
- package/extensions/ublock/_locales/nb/messages.json +1 -1
- package/extensions/ublock/_locales/no/messages.json +1 -1
- package/extensions/ublock/_locales/ro/messages.json +2 -2
- package/extensions/ublock/_locales/ru/messages.json +1 -1
- package/extensions/ublock/_locales/sk/messages.json +1 -1
- package/extensions/ublock/_locales/sv/messages.json +2 -2
- package/extensions/ublock/_locales/te/messages.json +17 -17
- package/extensions/ublock/_locales/vi/messages.json +12 -12
- package/extensions/ublock/_locales/zh_TW/messages.json +13 -13
- package/extensions/ublock/assets/assets.json +3 -3
- package/extensions/ublock/assets/resources/scriptlets.js +218 -97
- package/extensions/ublock/assets/thirdparties/easylist/easylist.txt +3010 -2056
- package/extensions/ublock/assets/thirdparties/easylist/easyprivacy.txt +624 -433
- package/extensions/ublock/assets/thirdparties/pgl.yoyo.org/as/serverlist +93 -24
- package/extensions/ublock/assets/thirdparties/publicsuffix.org/list/effective_tld_names.dat +7 -15
- package/extensions/ublock/assets/thirdparties/urlhaus-filter/urlhaus-filter-online.txt +795 -777
- package/extensions/ublock/assets/ublock/badware.min.txt +138 -72
- package/extensions/ublock/assets/ublock/filters.min.txt +1929 -2735
- package/extensions/ublock/assets/ublock/privacy.min.txt +57 -26
- package/extensions/ublock/assets/ublock/quick-fixes.min.txt +125 -74
- package/extensions/ublock/assets/ublock/unbreak.min.txt +46 -53
- package/extensions/ublock/css/codemirror.css +8 -7
- package/extensions/ublock/css/dom-inspector.css +40 -0
- package/extensions/ublock/css/logger-ui-inspector.css +7 -1
- package/extensions/ublock/css/logger-ui.css +12 -5
- package/extensions/ublock/css/popup-fenix.css +1 -1
- package/extensions/ublock/devtools.html +1 -0
- package/extensions/ublock/js/1p-filters.js +4 -3
- package/extensions/ublock/js/3p-filters.js +25 -31
- package/extensions/ublock/js/about.js +1 -1
- package/extensions/ublock/js/advanced-settings.js +1 -1
- package/extensions/ublock/js/asset-viewer.js +1 -1
- package/extensions/ublock/js/assets.js +74 -44
- package/extensions/ublock/js/background.js +9 -3
- package/extensions/ublock/js/base64-custom.js +1 -1
- package/extensions/ublock/js/benchmarks.js +1 -1
- package/extensions/ublock/js/biditrie.js +1 -1
- package/extensions/ublock/js/broadcast.js +75 -0
- package/extensions/ublock/js/cachestorage.js +68 -45
- package/extensions/ublock/js/click2load.js +1 -1
- package/extensions/ublock/js/cloud-ui.js +1 -1
- package/extensions/ublock/js/code-viewer.js +1 -1
- package/extensions/ublock/js/codemirror/search-thread.js +1 -1
- package/extensions/ublock/js/codemirror/search.js +1 -1
- package/extensions/ublock/js/codemirror/ubo-dynamic-filtering.js +1 -1
- package/extensions/ublock/js/codemirror/ubo-static-filtering.js +98 -24
- package/extensions/ublock/js/commands.js +1 -1
- package/extensions/ublock/js/console.js +1 -1
- package/extensions/ublock/js/contentscript-extra.js +1 -1
- package/extensions/ublock/js/contentscript.js +1 -3
- package/extensions/ublock/js/contextmenu.js +1 -1
- package/extensions/ublock/js/cosmetic-filtering.js +4 -4
- package/extensions/ublock/js/dashboard-common.js +1 -1
- package/extensions/ublock/js/dashboard.js +1 -1
- package/extensions/ublock/js/devtools.js +23 -15
- package/extensions/ublock/js/diff-updater.js +3 -3
- package/extensions/ublock/js/document-blocked.js +1 -1
- package/extensions/ublock/js/dom-inspector.js +68 -0
- package/extensions/ublock/js/dom.js +1 -1
- package/extensions/ublock/js/dyna-rules.js +1 -1
- package/extensions/ublock/js/dynamic-net-filtering.js +1 -1
- package/extensions/ublock/js/epicker-ui.js +35 -59
- package/extensions/ublock/js/fa-icons.js +1 -1
- package/extensions/ublock/js/filtering-context.js +1 -1
- package/extensions/ublock/js/filtering-engines.js +1 -1
- package/extensions/ublock/js/hnswitches.js +1 -1
- package/extensions/ublock/js/hntrie.js +1 -1
- package/extensions/ublock/js/html-filtering.js +1 -1
- package/extensions/ublock/js/httpheader-filtering.js +1 -1
- package/extensions/ublock/js/i18n.js +1 -1
- package/extensions/ublock/js/is-webrtc-supported.js +1 -1
- package/extensions/ublock/js/logger-ui-inspector.js +203 -145
- package/extensions/ublock/js/logger-ui.js +21 -5
- package/extensions/ublock/js/logger.js +6 -2
- package/extensions/ublock/js/lz4.js +2 -2
- package/extensions/ublock/js/messaging.js +266 -166
- package/extensions/ublock/js/mrucache.js +58 -0
- package/extensions/ublock/js/pagestore.js +1 -1
- package/extensions/ublock/js/popup-fenix.js +2 -1
- package/extensions/ublock/js/redirect-engine.js +1 -1
- package/extensions/ublock/js/redirect-resources.js +1 -12
- package/extensions/ublock/js/reverselookup-worker.js +1 -1
- package/extensions/ublock/js/reverselookup.js +1 -1
- package/extensions/ublock/js/scriptlet-filtering-core.js +300 -0
- package/extensions/ublock/js/scriptlet-filtering.js +122 -350
- package/extensions/ublock/js/scriptlets/cosmetic-logger.js +36 -47
- package/extensions/ublock/js/scriptlets/cosmetic-off.js +1 -1
- package/extensions/ublock/js/scriptlets/cosmetic-on.js +1 -1
- package/extensions/ublock/js/scriptlets/cosmetic-report.js +1 -1
- package/extensions/ublock/js/scriptlets/dom-inspector.js +341 -323
- package/extensions/ublock/js/scriptlets/dom-survey-elements.js +1 -1
- package/extensions/ublock/js/scriptlets/dom-survey-scripts.js +1 -1
- package/extensions/ublock/js/scriptlets/epicker.js +80 -89
- package/extensions/ublock/js/scriptlets/load-3p-css.js +1 -1
- package/extensions/ublock/js/scriptlets/load-large-media-all.js +1 -1
- package/extensions/ublock/js/scriptlets/load-large-media-interactive.js +1 -1
- package/extensions/ublock/js/scriptlets/noscript-spoof.js +1 -1
- package/extensions/ublock/js/scriptlets/should-inject-contentscript.js +1 -1
- package/extensions/ublock/js/scriptlets/subscriber.js +1 -1
- package/extensions/ublock/js/scriptlets/updater.js +20 -3
- package/extensions/ublock/js/settings.js +1 -1
- package/extensions/ublock/js/start.js +19 -20
- package/extensions/ublock/js/static-dnr-filtering.js +1 -1
- package/extensions/ublock/js/static-ext-filtering-db.js +1 -1
- package/extensions/ublock/js/static-ext-filtering.js +1 -1
- package/extensions/ublock/js/static-filtering-io.js +1 -1
- package/extensions/ublock/js/static-filtering-parser.js +5 -3
- package/extensions/ublock/js/static-net-filtering.js +57 -37
- package/extensions/ublock/js/storage.js +49 -29
- package/extensions/ublock/js/support.js +4 -4
- package/extensions/ublock/js/tab.js +1 -1
- package/extensions/ublock/js/tasks.js +1 -1
- package/extensions/ublock/js/text-encode.js +1 -1
- package/extensions/ublock/js/text-utils.js +1 -1
- package/extensions/ublock/js/theme.js +1 -1
- package/extensions/ublock/js/traffic.js +2 -1
- package/extensions/ublock/js/ublock.js +15 -11
- package/extensions/ublock/js/uri-utils.js +1 -1
- package/extensions/ublock/js/url-net-filtering.js +1 -1
- package/extensions/ublock/js/utils.js +1 -73
- package/extensions/ublock/js/vapi-background-ext.js +1 -1
- package/extensions/ublock/js/vapi-background.js +92 -83
- package/extensions/ublock/js/vapi-client.js +4 -33
- package/extensions/ublock/js/vapi-common.js +16 -30
- package/extensions/ublock/js/vapi.js +1 -1
- package/extensions/ublock/js/wasm/biditrie.wat +1 -1
- package/extensions/ublock/js/wasm/hntrie.wat +1 -1
- package/extensions/ublock/js/webext.js +1 -1
- package/extensions/ublock/js/whitelist.js +1 -1
- package/extensions/ublock/logger-ui.html +2 -2
- package/extensions/ublock/manifest.json +1 -1
- package/extensions/ublock/support.html +0 -1
- package/extensions/ublock/web_accessible_resources/dom-inspector.html +25 -0
- package/extensions/ublock/web_accessible_resources/epicker-ui.html +0 -1
- package/extensions/ublock/web_accessible_resources/googletagservices_gpt.js +1 -0
- package/package.json +10 -20
- package/scripts/build-open-api.js +7 -4
- package/src/browserless.ts +42 -18
- package/src/browsers/index.ts +48 -20
- package/src/http.ts +3 -3
- package/src/router.ts +2 -6
- package/src/routes/chromium/http/content-post.ts +13 -16
- package/src/routes/chromium/http/download-post.ts +16 -27
- package/src/routes/chromium/http/function-post.ts +16 -25
- package/src/routes/chromium/http/pdf-post.ts +19 -15
- package/src/routes/chromium/http/performance.ts +14 -26
- package/src/routes/chromium/http/scrape-post.ts +14 -16
- package/src/routes/chromium/http/screenshot-post.ts +18 -15
- package/src/routes/chromium/tests/websocket.spec.ts +28 -1
- package/src/routes/chromium/utils/function/handler.ts +2 -1
- package/src/routes/chromium/ws/browser.ts +10 -12
- package/src/routes/chromium/ws/cdp-chromium.ts +10 -12
- package/src/routes/chromium/ws/page.ts +10 -12
- package/src/routes/chromium/ws/playwright-chromium.ts +10 -12
- package/src/routes/firefox/ws/playwright-firefox.ts +10 -12
- package/src/routes/management/http/config-get.ts +14 -23
- package/src/routes/management/http/metrics-get.ts +15 -24
- package/src/routes/management/http/metrics-total-get.ts +15 -26
- package/src/routes/management/http/sessions-get.ts +15 -23
- package/src/routes/management/http/static-get.ts +14 -22
- package/src/routes/webkit/ws/playwright-webkit.ts +10 -12
- package/src/server.ts +0 -1
- package/src/types.ts +59 -45
- package/static/docs/browserless-logo-inline.svg +1 -0
- package/static/docs/index.html +27 -0
- package/static/docs/swagger.json +33 -33
- package/static/function/client.js +626 -78
- package/extensions/ublock/js/vapi-client-extra.js +0 -312
- package/extensions/ublock/web_accessible_resources/addthis_widget.js +0 -39
- package/extensions/ublock/web_accessible_resources/ligatus_angular-tag.js +0 -29
- package/extensions/ublock/web_accessible_resources/monkeybroker.js +0 -43
- package/extensions/ublock/web_accessible_resources/mxpnl_mixpanel.js +0 -51
package/package.json
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@browserless.io/browserless",
|
|
3
|
-
"version": "2.0.0-beta-
|
|
3
|
+
"version": "2.0.0-beta-6",
|
|
4
4
|
"license": "SSPL",
|
|
5
5
|
"description": "The browserless platform",
|
|
6
6
|
"author": "browserless.io",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"types": "./src/exports.ts",
|
|
9
9
|
"main": "./build/exports.js",
|
|
10
|
-
"exports":
|
|
10
|
+
"exports": {
|
|
11
|
+
".": "./build/exports.js"
|
|
12
|
+
},
|
|
11
13
|
"bin": {
|
|
12
14
|
"browserless": "./bin/browserless.js"
|
|
13
15
|
},
|
|
@@ -27,7 +29,7 @@
|
|
|
27
29
|
"install:dev": "npm run install:browsers && npm run install:cdp-json",
|
|
28
30
|
"lint": "eslint . --ext .ts --fix",
|
|
29
31
|
"prepack": "npm run build:dev",
|
|
30
|
-
"prettier": "prettier '{src,functions,scripts,bin,external}/**/*.{js,ts,json}' --log-level error --write",
|
|
32
|
+
"prettier": "prettier '{src,functions,scripts,bin,external,bin}/**/*.{js,ts,json}' --log-level error --write",
|
|
31
33
|
"test": "cross-env DEBUG=quiet mocha"
|
|
32
34
|
},
|
|
33
35
|
"files": [
|
|
@@ -69,15 +71,15 @@
|
|
|
69
71
|
"@types/http-proxy": "^1.17.14",
|
|
70
72
|
"@types/micromatch": "^4.0.6",
|
|
71
73
|
"@types/mocha": "^10.0.6",
|
|
72
|
-
"@types/node": "^20.10.
|
|
74
|
+
"@types/node": "^20.10.8",
|
|
73
75
|
"@types/sinon": "^17.0.2",
|
|
74
|
-
"@typescript-eslint/eslint-plugin": "^6.
|
|
75
|
-
"@typescript-eslint/parser": "^6.
|
|
76
|
+
"@typescript-eslint/eslint-plugin": "^6.18.1",
|
|
77
|
+
"@typescript-eslint/parser": "^6.18.1",
|
|
76
78
|
"assert": "^2.0.0",
|
|
77
|
-
"chai": "^
|
|
79
|
+
"chai": "^5.0.0",
|
|
78
80
|
"cross-env": "^7.0.3",
|
|
79
81
|
"env-cmd": "^10.1.0",
|
|
80
|
-
"esbuild": "^0.19.
|
|
82
|
+
"esbuild": "^0.19.11",
|
|
81
83
|
"esbuild-plugin-polyfill-node": "^0.3.0",
|
|
82
84
|
"eslint": "^8.56.0",
|
|
83
85
|
"eslint-plugin-import": "^2.29.1",
|
|
@@ -156,18 +158,6 @@
|
|
|
156
158
|
"timeout": 30000,
|
|
157
159
|
"slow": 5000
|
|
158
160
|
},
|
|
159
|
-
"nodemonConfig": {
|
|
160
|
-
"ignoreRoot": [
|
|
161
|
-
".git",
|
|
162
|
-
".no-git"
|
|
163
|
-
],
|
|
164
|
-
"watch": [
|
|
165
|
-
"src"
|
|
166
|
-
],
|
|
167
|
-
"exec": "npx tsc && node ./build/index.js",
|
|
168
|
-
"ext": "ts json",
|
|
169
|
-
"signal": "SIGTERM"
|
|
170
|
-
},
|
|
171
161
|
"prettier": {
|
|
172
162
|
"semi": true,
|
|
173
163
|
"trailingComma": "all",
|
|
@@ -56,17 +56,19 @@ const buildOpenAPI = async (
|
|
|
56
56
|
const changelog = marked.parse(
|
|
57
57
|
(await fs.readFile('CHANGELOG.md').catch(() => '')).toString(),
|
|
58
58
|
);
|
|
59
|
+
|
|
59
60
|
const [httpRoutes, wsRoutes] = await getRouteFiles(new Config());
|
|
60
61
|
const swaggerJSON = {
|
|
61
62
|
customSiteTitle: 'Browserless Documentation',
|
|
62
63
|
definitions: {},
|
|
63
64
|
info: {
|
|
64
|
-
|
|
65
|
+
// Concatenation necessary for Changelog to show up in sidebar
|
|
66
|
+
description: readme + `\n# Changelog\n` + changelog,
|
|
65
67
|
title: 'Browserless',
|
|
66
68
|
version: JSON.parse(packageJSON.toString()).version,
|
|
67
69
|
'x-logo': {
|
|
68
70
|
altText: 'browserless logo',
|
|
69
|
-
url: './docs/browserless-logo.
|
|
71
|
+
url: './docs/browserless-logo-inline.svg',
|
|
70
72
|
},
|
|
71
73
|
},
|
|
72
74
|
openapi: '3.0.0',
|
|
@@ -86,10 +88,11 @@ const buildOpenAPI = async (
|
|
|
86
88
|
.sort()
|
|
87
89
|
.map(async (routeModule) => {
|
|
88
90
|
const routeImport = `${isWin ? 'file:///' : ''}${routeModule}`;
|
|
89
|
-
const { default:
|
|
90
|
-
if (!
|
|
91
|
+
const { default: Route } = await import(routeImport);
|
|
92
|
+
if (!Route) {
|
|
91
93
|
throw new Error(`Invalid route file to import docs ${routeModule}`);
|
|
92
94
|
}
|
|
95
|
+
const route = new Route();
|
|
93
96
|
const { name } = parse(routeModule);
|
|
94
97
|
const body = routeModule.replace('.js', '.body.json');
|
|
95
98
|
const query = routeModule.replace('.js', '.query.json');
|
package/src/browserless.ts
CHANGED
|
@@ -27,6 +27,10 @@ import { userInfo } from 'os';
|
|
|
27
27
|
|
|
28
28
|
const routeSchemas = ['body', 'query'];
|
|
29
29
|
|
|
30
|
+
type Implements<T> = {
|
|
31
|
+
new (...args: unknown[]): T;
|
|
32
|
+
};
|
|
33
|
+
|
|
30
34
|
export class Browserless {
|
|
31
35
|
protected debug: debug.Debugger = createLogger('index');
|
|
32
36
|
protected browserManager: BrowserManager;
|
|
@@ -181,16 +185,25 @@ export class Browserless {
|
|
|
181
185
|
this.config.getIsWin() ? 'file:///' : ''
|
|
182
186
|
}${httpRoute}`;
|
|
183
187
|
const logger = createLogger(`http:${name}`);
|
|
184
|
-
const {
|
|
188
|
+
const {
|
|
189
|
+
default: Route,
|
|
190
|
+
}: { default: Implements<HTTPRoute> | Implements<BrowserHTTPRoute> } =
|
|
185
191
|
await import(routeImport + `?cb=${Date.now()}`);
|
|
186
|
-
|
|
192
|
+
const route = new Route(
|
|
193
|
+
this.browserManager,
|
|
194
|
+
this.config,
|
|
195
|
+
this.fileSystem,
|
|
196
|
+
logger,
|
|
197
|
+
this.metrics,
|
|
198
|
+
this.monitoring,
|
|
199
|
+
);
|
|
187
200
|
route.bodySchema = safeParse(bodySchema);
|
|
188
201
|
route.querySchema = safeParse(querySchema);
|
|
189
|
-
route.
|
|
190
|
-
route.
|
|
191
|
-
route.
|
|
192
|
-
route.
|
|
193
|
-
route.
|
|
202
|
+
route.config = () => this.config;
|
|
203
|
+
route.metrics = () => this.metrics;
|
|
204
|
+
route.monitoring = () => this.monitoring;
|
|
205
|
+
route.fileSystem = () => this.fileSystem;
|
|
206
|
+
route.debug = () => logger;
|
|
194
207
|
|
|
195
208
|
httpRoutes.push(route);
|
|
196
209
|
}
|
|
@@ -215,17 +228,27 @@ export class Browserless {
|
|
|
215
228
|
}${wsRoute}`;
|
|
216
229
|
const logger = createLogger(`ws:${name}`);
|
|
217
230
|
const {
|
|
218
|
-
default:
|
|
219
|
-
}: {
|
|
220
|
-
|
|
221
|
-
|
|
231
|
+
default: Route,
|
|
232
|
+
}: {
|
|
233
|
+
default:
|
|
234
|
+
| Implements<WebSocketRoute>
|
|
235
|
+
| Implements<BrowserWebsocketRoute>;
|
|
236
|
+
} = await import(wsImport + `?cb=${Date.now()}`);
|
|
222
237
|
|
|
238
|
+
const route = new Route(
|
|
239
|
+
this.browserManager,
|
|
240
|
+
this.config,
|
|
241
|
+
this.fileSystem,
|
|
242
|
+
logger,
|
|
243
|
+
this.metrics,
|
|
244
|
+
this.monitoring,
|
|
245
|
+
);
|
|
223
246
|
route.querySchema = safeParse(querySchema);
|
|
224
|
-
route.
|
|
225
|
-
route.
|
|
226
|
-
route.
|
|
227
|
-
route.
|
|
228
|
-
route.
|
|
247
|
+
route.config = () => this.config;
|
|
248
|
+
route.metrics = () => this.metrics;
|
|
249
|
+
route.monitoring = () => this.monitoring;
|
|
250
|
+
route.fileSystem = () => this.fileSystem;
|
|
251
|
+
route.debug = () => logger;
|
|
229
252
|
|
|
230
253
|
wsRoutes.push(route);
|
|
231
254
|
}
|
|
@@ -234,11 +257,12 @@ export class Browserless {
|
|
|
234
257
|
// Validate that browsers are installed and route paths are unique
|
|
235
258
|
[...httpRoutes, ...wsRoutes].forEach((route) => {
|
|
236
259
|
if (
|
|
260
|
+
'browser' in route &&
|
|
237
261
|
route.browser &&
|
|
238
|
-
!installedBrowsers.some((b) => b.name === route.browser
|
|
262
|
+
!installedBrowsers.some((b) => b.name === route.browser?.name)
|
|
239
263
|
) {
|
|
240
264
|
throw new Error(
|
|
241
|
-
`Couldn't load route "${route.path}" due to missing browser of "${route.browser
|
|
265
|
+
`Couldn't load route "${route.path}" due to missing browser of "${route.browser?.name}"`,
|
|
242
266
|
);
|
|
243
267
|
}
|
|
244
268
|
});
|
package/src/browsers/index.ts
CHANGED
|
@@ -82,27 +82,52 @@ export class BrowserManager {
|
|
|
82
82
|
return dataDirPath;
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
private generateSessionJson = async (
|
|
86
86
|
browser: BrowserInstance,
|
|
87
87
|
session: BrowserlessSession,
|
|
88
88
|
) => {
|
|
89
89
|
const serverAddress = this.config.getExternalAddress();
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
91
|
+
const sessions = [
|
|
92
|
+
{
|
|
93
|
+
...session,
|
|
94
|
+
browser: browser.constructor.name,
|
|
95
|
+
browserId: browser.wsEndpoint()?.split('/').pop(),
|
|
96
|
+
initialConnectURL: new URL(session.initialConnectURL, serverAddress)
|
|
97
|
+
.href,
|
|
98
|
+
killURL: session.id
|
|
99
|
+
? makeExternalURL(
|
|
100
|
+
serverAddress,
|
|
101
|
+
HTTPManagementRoutes.sessions,
|
|
102
|
+
session.id,
|
|
103
|
+
)
|
|
104
|
+
: null,
|
|
105
|
+
running: browser.isRunning(),
|
|
106
|
+
timeAliveMs: Date.now() - session.startedOn,
|
|
107
|
+
type: 'browser',
|
|
108
|
+
},
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
const wsEndpoint = browser.wsEndpoint();
|
|
112
|
+
if (browser.constructor.name === 'CDPChromium' && wsEndpoint) {
|
|
113
|
+
const port = new URL(wsEndpoint).port;
|
|
114
|
+
const response = await fetch(`http://127.0.0.1:${port}/json/list`, {
|
|
115
|
+
headers: {
|
|
116
|
+
Host: '127.0.0.1',
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
if (response.ok) {
|
|
120
|
+
const body = await response.json();
|
|
121
|
+
for (const page of body) {
|
|
122
|
+
sessions.push({
|
|
123
|
+
...sessions[0],
|
|
124
|
+
...page,
|
|
125
|
+
browserWSEndpoint: wsEndpoint,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return sessions;
|
|
106
131
|
};
|
|
107
132
|
|
|
108
133
|
public close = async (
|
|
@@ -129,9 +154,12 @@ export class BrowserManager {
|
|
|
129
154
|
public getAllSessions = async (): Promise<BrowserlessSessionJSON[]> => {
|
|
130
155
|
const sessions = Array.from(this.browsers);
|
|
131
156
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
157
|
+
const formattedSessions: BrowserlessSessionJSON[] = [];
|
|
158
|
+
for (const [browser, session] of sessions) {
|
|
159
|
+
const formattedSession = await this.generateSessionJson(browser, session);
|
|
160
|
+
formattedSessions.push(...formattedSession);
|
|
161
|
+
}
|
|
162
|
+
return formattedSessions;
|
|
135
163
|
};
|
|
136
164
|
|
|
137
165
|
public complete = async (browser: BrowserInstance): Promise<void> => {
|
|
@@ -208,7 +236,7 @@ export class BrowserManager {
|
|
|
208
236
|
const manualUserDataDir =
|
|
209
237
|
launchOptions.args
|
|
210
238
|
?.find((arg) => arg.includes('--user-data-dir='))
|
|
211
|
-
?.split('=')[
|
|
239
|
+
?.split('=')[1] || (launchOptions as CDPLaunchOptions).userDataDir;
|
|
212
240
|
|
|
213
241
|
// Always specify a user-data-dir since plugins can "inject" their own
|
|
214
242
|
// unless it's playwright which takes care of its own data-dirs
|
package/src/http.ts
CHANGED
|
@@ -107,9 +107,9 @@ export enum HTTPManagementRoutes {
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
export enum APITags {
|
|
110
|
-
'browserAPI' = 'Browser APIs',
|
|
111
|
-
'browserWS' = 'Browser
|
|
112
|
-
'management' = 'Management APIs',
|
|
110
|
+
'browserAPI' = 'Browser REST APIs',
|
|
111
|
+
'browserWS' = 'Browser WebSocket APIs',
|
|
112
|
+
'management' = 'Management REST APIs',
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
export interface Request extends http.IncomingMessage {
|
package/src/router.ts
CHANGED
|
@@ -67,7 +67,7 @@ export class Router {
|
|
|
67
67
|
return Promise.resolve();
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
if (route.browser) {
|
|
70
|
+
if ('browser' in route && route.browser) {
|
|
71
71
|
const browser = await this.browserManager.getBrowserForRequest(
|
|
72
72
|
req,
|
|
73
73
|
route,
|
|
@@ -111,7 +111,7 @@ export class Router {
|
|
|
111
111
|
return Promise.resolve();
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
if (route.browser) {
|
|
114
|
+
if ('browser' in route && route.browser) {
|
|
115
115
|
const browser = await this.browserManager.getBrowserForRequest(
|
|
116
116
|
req,
|
|
117
117
|
route,
|
|
@@ -146,8 +146,6 @@ export class Router {
|
|
|
146
146
|
`Registering HTTP ${route.method.toUpperCase()} ${route.path}`,
|
|
147
147
|
);
|
|
148
148
|
|
|
149
|
-
route.getBrowserManager = () => this.browserManager;
|
|
150
|
-
|
|
151
149
|
const bound = route.handler.bind(route);
|
|
152
150
|
const wrapped = this.wrapHTTPHandler(route, bound);
|
|
153
151
|
|
|
@@ -170,8 +168,6 @@ export class Router {
|
|
|
170
168
|
): WebSocketRoute | BrowserWebsocketRoute {
|
|
171
169
|
this.verbose(`Registering WebSocket "${route.path}"`);
|
|
172
170
|
|
|
173
|
-
route.getBrowserManager = () => this.browserManager;
|
|
174
|
-
|
|
175
171
|
const bound = route.handler.bind(route);
|
|
176
172
|
const wrapped = this.wrapWebSocketHandler(route, bound);
|
|
177
173
|
|
|
@@ -61,15 +61,17 @@ export type QuerySchema = SystemQueryParameters & {
|
|
|
61
61
|
launch?: CDPLaunchOptions | string;
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
accepts
|
|
66
|
-
auth
|
|
67
|
-
browser
|
|
68
|
-
concurrency
|
|
69
|
-
contentTypes
|
|
70
|
-
description
|
|
71
|
-
|
|
72
|
-
|
|
64
|
+
export default class ContentPostRoute extends BrowserHTTPRoute {
|
|
65
|
+
accepts = [contentTypes.json];
|
|
66
|
+
auth = true;
|
|
67
|
+
browser = CDPChromium;
|
|
68
|
+
concurrency = true;
|
|
69
|
+
contentTypes = [contentTypes.html];
|
|
70
|
+
description = `A JSON-based API. Given a "url" or "html" field, runs and returns HTML content after the page has loaded and JavaScript has parsed.`;
|
|
71
|
+
method = Methods.post;
|
|
72
|
+
path = HTTPRoutes.content;
|
|
73
|
+
tags = [APITags.browserAPI];
|
|
74
|
+
handler = async (
|
|
73
75
|
req: Request,
|
|
74
76
|
res: ServerResponse,
|
|
75
77
|
browser: BrowserInstance,
|
|
@@ -229,10 +231,5 @@ const route: BrowserHTTPRoute = {
|
|
|
229
231
|
page.close().catch(noop);
|
|
230
232
|
|
|
231
233
|
return writeResponse(res, 200, markup, contentTypes.html);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
path: HTTPRoutes.content,
|
|
235
|
-
tags: [APITags.browserAPI],
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
export default route;
|
|
234
|
+
};
|
|
235
|
+
}
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
Methods,
|
|
9
9
|
NotFound,
|
|
10
10
|
Request,
|
|
11
|
-
ServerError,
|
|
12
11
|
SystemQueryParameters,
|
|
13
12
|
contentTypes,
|
|
14
13
|
dedent,
|
|
@@ -41,35 +40,30 @@ export interface QuerySchema extends SystemQueryParameters {
|
|
|
41
40
|
*/
|
|
42
41
|
export type ResponseSchema = unknown;
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
accepts
|
|
46
|
-
auth
|
|
47
|
-
browser
|
|
48
|
-
concurrency
|
|
49
|
-
contentTypes
|
|
50
|
-
description
|
|
43
|
+
export default class DownloadPost extends BrowserHTTPRoute {
|
|
44
|
+
accepts = [contentTypes.json, contentTypes.javascript];
|
|
45
|
+
auth = true;
|
|
46
|
+
browser = CDPChromium;
|
|
47
|
+
concurrency = true;
|
|
48
|
+
contentTypes = [contentTypes.any];
|
|
49
|
+
description = dedent(`
|
|
51
50
|
A JSON or JavaScript content-type API for returning files Chrome has downloaded during
|
|
52
51
|
the execution of puppeteer code, which is ran inside context of the browser.
|
|
53
52
|
Browserless sets up a blank page, a fresh download directory, injects your puppeteer code, and then executes it.
|
|
54
53
|
You can load external libraries via the "import" syntax, and import ESM-style modules
|
|
55
54
|
that are written for execution inside of the browser. Once your script is finished, any
|
|
56
|
-
downloaded files from Chromium are returned back with the appropriate content-type header.`)
|
|
57
|
-
|
|
55
|
+
downloaded files from Chromium are returned back with the appropriate content-type header.`);
|
|
56
|
+
method = Methods.post;
|
|
57
|
+
path = HTTPRoutes.download;
|
|
58
|
+
tags = [APITags.browserAPI];
|
|
59
|
+
handler = async (
|
|
58
60
|
req: Request,
|
|
59
61
|
res: ServerResponse,
|
|
60
62
|
browser: BrowserInstance,
|
|
61
63
|
): Promise<void> =>
|
|
62
64
|
new Promise(async (resolve, reject) => {
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
if (!getConfig || !getDebug) {
|
|
66
|
-
return reject(
|
|
67
|
-
new ServerError(`Couldn't load configuration for request`),
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const debug = getDebug();
|
|
72
|
-
const config = getConfig();
|
|
65
|
+
const debug = this.debug();
|
|
66
|
+
const config = this.config();
|
|
73
67
|
const downloadPath = path.join(
|
|
74
68
|
await config.getDownloadsDir(),
|
|
75
69
|
`.browserless.download.${id()}`,
|
|
@@ -153,10 +147,5 @@ const route: BrowserHTTPRoute = {
|
|
|
153
147
|
return resolve();
|
|
154
148
|
})
|
|
155
149
|
.pipe(res);
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
path: HTTPRoutes.download,
|
|
159
|
-
tags: [APITags.browserAPI],
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
export default route;
|
|
150
|
+
});
|
|
151
|
+
}
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
HTTPRoutes,
|
|
9
9
|
Methods,
|
|
10
10
|
Request,
|
|
11
|
-
ServerError,
|
|
12
11
|
SystemQueryParameters,
|
|
13
12
|
contentTypes,
|
|
14
13
|
dedent,
|
|
@@ -38,31 +37,28 @@ export interface QuerySchema extends SystemQueryParameters {
|
|
|
38
37
|
*/
|
|
39
38
|
export type ResponseSchema = unknown;
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
accepts
|
|
43
|
-
auth
|
|
44
|
-
browser
|
|
45
|
-
concurrency
|
|
46
|
-
contentTypes
|
|
47
|
-
description
|
|
40
|
+
export default class FunctionPost extends BrowserHTTPRoute {
|
|
41
|
+
accepts = [contentTypes.json, contentTypes.javascript];
|
|
42
|
+
auth = true;
|
|
43
|
+
browser = CDPChromium;
|
|
44
|
+
concurrency = true;
|
|
45
|
+
contentTypes = [contentTypes.any];
|
|
46
|
+
description = dedent(`
|
|
48
47
|
A JSON or JavaScript content-type API for running puppeteer code in the browser's context.
|
|
49
48
|
Browserless sets up a blank page, injects your puppeteer code, and runs it.
|
|
50
49
|
You can optionally load external libraries via the "import" module that are meant for browser usage.
|
|
51
50
|
Values returned from the function are checked and an appropriate content-type and response is sent back
|
|
52
|
-
to your HTTP call.`)
|
|
53
|
-
|
|
51
|
+
to your HTTP call.`);
|
|
52
|
+
method = Methods.post;
|
|
53
|
+
path = HTTPRoutes.function;
|
|
54
|
+
tags = [APITags.browserAPI];
|
|
55
|
+
handler = async (
|
|
54
56
|
req: Request,
|
|
55
57
|
res: ServerResponse,
|
|
56
58
|
browser: BrowserInstance,
|
|
57
59
|
): Promise<void> => {
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
if (!getConfig || !getDebug) {
|
|
61
|
-
throw new ServerError(`Couldn't load configuration for request`);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const debug = getDebug();
|
|
65
|
-
const config = getConfig();
|
|
60
|
+
const debug = this.debug();
|
|
61
|
+
const config = this.config();
|
|
66
62
|
const handler = functionHandler(config, debug);
|
|
67
63
|
const { contentType, payload, page } = await handler(req, browser);
|
|
68
64
|
|
|
@@ -89,10 +85,5 @@ const route: BrowserHTTPRoute = {
|
|
|
89
85
|
}
|
|
90
86
|
|
|
91
87
|
return;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
path: HTTPRoutes.function,
|
|
95
|
-
tags: [APITags.browserAPI],
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
export default route;
|
|
88
|
+
};
|
|
89
|
+
}
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
bestAttempt,
|
|
17
17
|
bestAttemptCatch,
|
|
18
18
|
contentTypes,
|
|
19
|
+
dedent,
|
|
19
20
|
noop,
|
|
20
21
|
rejectRequestPattern,
|
|
21
22
|
rejectResourceTypes,
|
|
@@ -61,14 +62,22 @@ export interface QuerySchema extends SystemQueryParameters {
|
|
|
61
62
|
*/
|
|
62
63
|
export type ResponseSchema = string;
|
|
63
64
|
|
|
64
|
-
|
|
65
|
-
accepts
|
|
66
|
-
auth
|
|
67
|
-
browser
|
|
68
|
-
concurrency
|
|
69
|
-
contentTypes
|
|
70
|
-
description
|
|
71
|
-
|
|
65
|
+
export default class PDFPost extends BrowserHTTPRoute {
|
|
66
|
+
accepts = [contentTypes.json];
|
|
67
|
+
auth = true;
|
|
68
|
+
browser = CDPChromium;
|
|
69
|
+
concurrency = true;
|
|
70
|
+
contentTypes = [contentTypes.pdf];
|
|
71
|
+
description = dedent(`
|
|
72
|
+
A JSON-based API for getting a PDF binary from either a supplied
|
|
73
|
+
"url" or "html" payload in your request. Many options exist for
|
|
74
|
+
injecting cookies, request interceptors, user-agents and waiting for
|
|
75
|
+
selectors, timers and more.
|
|
76
|
+
`);
|
|
77
|
+
method = Methods.post;
|
|
78
|
+
path = HTTPRoutes.pdf;
|
|
79
|
+
tags = [APITags.browserAPI];
|
|
80
|
+
handler = async (
|
|
72
81
|
req: Request,
|
|
73
82
|
res: ServerResponse,
|
|
74
83
|
browser: BrowserInstance,
|
|
@@ -225,10 +234,5 @@ const route: BrowserHTTPRoute = {
|
|
|
225
234
|
});
|
|
226
235
|
|
|
227
236
|
page.close().catch(noop);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
path: HTTPRoutes.pdf,
|
|
231
|
-
tags: [APITags.browserAPI],
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
export default route;
|
|
237
|
+
};
|
|
238
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
2
|
APITags,
|
|
3
|
-
BadRequest,
|
|
4
3
|
BrowserHTTPRoute,
|
|
5
4
|
BrowserInstance,
|
|
6
5
|
CDPChromium,
|
|
@@ -8,7 +7,6 @@ import {
|
|
|
8
7
|
HTTPRoutes,
|
|
9
8
|
Methods,
|
|
10
9
|
Request,
|
|
11
|
-
ServerError,
|
|
12
10
|
SystemQueryParameters,
|
|
13
11
|
contentTypes,
|
|
14
12
|
jsonResponse,
|
|
@@ -34,27 +32,22 @@ export interface QuerySchema extends SystemQueryParameters {
|
|
|
34
32
|
*/
|
|
35
33
|
export type ResponseSchema = object;
|
|
36
34
|
|
|
37
|
-
|
|
38
|
-
accepts
|
|
39
|
-
auth
|
|
40
|
-
browser
|
|
41
|
-
concurrency
|
|
42
|
-
contentTypes
|
|
43
|
-
description
|
|
44
|
-
|
|
35
|
+
export default class PerformancePost extends BrowserHTTPRoute {
|
|
36
|
+
accepts = [contentTypes.json];
|
|
37
|
+
auth = true;
|
|
38
|
+
browser = CDPChromium;
|
|
39
|
+
concurrency = true;
|
|
40
|
+
contentTypes = [contentTypes.json];
|
|
41
|
+
description = `Run lighthouse performance audits with a supplied "url" in your JSON payload.`;
|
|
42
|
+
method = Methods.post;
|
|
43
|
+
path = HTTPRoutes.performance;
|
|
44
|
+
tags = [APITags.browserAPI];
|
|
45
|
+
handler = async (
|
|
45
46
|
req: Request,
|
|
46
47
|
res: ServerResponse,
|
|
47
48
|
browser: BrowserInstance,
|
|
48
49
|
): Promise<void> => {
|
|
49
|
-
const
|
|
50
|
-
if (!req.body) {
|
|
51
|
-
throw new BadRequest(`No JSON body present`);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (!getConfig) {
|
|
55
|
-
throw new ServerError(`Couldn't load configuration for timeouts`);
|
|
56
|
-
}
|
|
57
|
-
const config = getConfig();
|
|
50
|
+
const config = this.config();
|
|
58
51
|
const response = await main({
|
|
59
52
|
browser,
|
|
60
53
|
context: req.body as BodySchema,
|
|
@@ -62,10 +55,5 @@ const route: BrowserHTTPRoute = {
|
|
|
62
55
|
});
|
|
63
56
|
|
|
64
57
|
return jsonResponse(res, 200, response);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
path: HTTPRoutes.performance,
|
|
68
|
-
tags: [APITags.browserAPI],
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
export default route;
|
|
58
|
+
};
|
|
59
|
+
}
|