@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.
Files changed (240) hide show
  1. package/LICENSE +2 -0
  2. package/README.md +11 -11
  3. package/bin/browserless.js +155 -11
  4. package/bin/scaffold/README.md +415 -0
  5. package/bin/scaffold/package.json +21 -0
  6. package/bin/scaffold/src/hello-world.http.ts +25 -0
  7. package/bin/scaffold/tsconfig.json +4 -0
  8. package/build/browserless.js +18 -15
  9. package/build/browsers/index.d.ts +2 -18
  10. package/build/browsers/index.js +43 -14
  11. package/build/http.d.ts +3 -3
  12. package/build/http.js +3 -3
  13. package/build/router.js +2 -4
  14. package/build/routes/chromium/http/content-post.body.json +8 -8
  15. package/build/routes/chromium/http/content-post.d.ts +15 -3
  16. package/build/routes/chromium/http/content-post.js +14 -15
  17. package/build/routes/chromium/http/download-post.d.ts +16 -3
  18. package/build/routes/chromium/http/download-post.js +17 -22
  19. package/build/routes/chromium/http/function-post.d.ts +16 -3
  20. package/build/routes/chromium/http/function-post.js +17 -22
  21. package/build/routes/chromium/http/pdf-post.body.json +8 -8
  22. package/build/routes/chromium/http/pdf-post.d.ts +15 -3
  23. package/build/routes/chromium/http/pdf-post.js +19 -15
  24. package/build/routes/chromium/http/performance.d.ts +15 -3
  25. package/build/routes/chromium/http/performance.js +15 -23
  26. package/build/routes/chromium/http/scrape-post.body.json +8 -8
  27. package/build/routes/chromium/http/scrape-post.d.ts +15 -3
  28. package/build/routes/chromium/http/scrape-post.js +15 -16
  29. package/build/routes/chromium/http/screenshot-post.body.json +8 -8
  30. package/build/routes/chromium/http/screenshot-post.d.ts +15 -3
  31. package/build/routes/chromium/http/screenshot-post.js +18 -15
  32. package/build/routes/chromium/tests/websocket.spec.js +20 -1
  33. package/build/routes/chromium/utils/function/handler.js +2 -2
  34. package/build/routes/chromium/ws/browser.d.ts +13 -3
  35. package/build/routes/chromium/ws/browser.js +10 -11
  36. package/build/routes/chromium/ws/cdp-chromium.d.ts +13 -3
  37. package/build/routes/chromium/ws/cdp-chromium.js +10 -11
  38. package/build/routes/chromium/ws/page.d.ts +13 -3
  39. package/build/routes/chromium/ws/page.js +10 -11
  40. package/build/routes/chromium/ws/playwright-chromium.d.ts +13 -3
  41. package/build/routes/chromium/ws/playwright-chromium.js +11 -12
  42. package/build/routes/firefox/ws/playwright-firefox.d.ts +13 -3
  43. package/build/routes/firefox/ws/playwright-firefox.js +11 -12
  44. package/build/routes/management/http/config-get.d.ts +15 -3
  45. package/build/routes/management/http/config-get.js +15 -20
  46. package/build/routes/management/http/metrics-get.d.ts +15 -3
  47. package/build/routes/management/http/metrics-get.js +16 -21
  48. package/build/routes/management/http/metrics-total-get.d.ts +15 -3
  49. package/build/routes/management/http/metrics-total-get.js +16 -21
  50. package/build/routes/management/http/sessions-get.d.ts +15 -3
  51. package/build/routes/management/http/sessions-get.js +16 -20
  52. package/build/routes/management/http/static-get.d.ts +15 -3
  53. package/build/routes/management/http/static-get.js +15 -20
  54. package/build/routes/webkit/ws/playwright-webkit.d.ts +13 -3
  55. package/build/routes/webkit/ws/playwright-webkit.js +11 -12
  56. package/build/server.js +0 -1
  57. package/build/types.d.ts +48 -38
  58. package/build/types.js +135 -0
  59. package/extensions/ublock/1p-filters.html +0 -1
  60. package/extensions/ublock/3p-filters.html +0 -2
  61. package/extensions/ublock/_locales/bg/messages.json +6 -6
  62. package/extensions/ublock/_locales/br_FR/messages.json +14 -14
  63. package/extensions/ublock/_locales/bs/messages.json +8 -8
  64. package/extensions/ublock/_locales/ca/messages.json +1 -1
  65. package/extensions/ublock/_locales/da/messages.json +5 -5
  66. package/extensions/ublock/_locales/fa/messages.json +1 -1
  67. package/extensions/ublock/_locales/fi/messages.json +6 -6
  68. package/extensions/ublock/_locales/hr/messages.json +4 -4
  69. package/extensions/ublock/_locales/nb/messages.json +1 -1
  70. package/extensions/ublock/_locales/no/messages.json +1 -1
  71. package/extensions/ublock/_locales/ro/messages.json +2 -2
  72. package/extensions/ublock/_locales/ru/messages.json +1 -1
  73. package/extensions/ublock/_locales/sk/messages.json +1 -1
  74. package/extensions/ublock/_locales/sv/messages.json +2 -2
  75. package/extensions/ublock/_locales/te/messages.json +17 -17
  76. package/extensions/ublock/_locales/vi/messages.json +12 -12
  77. package/extensions/ublock/_locales/zh_TW/messages.json +13 -13
  78. package/extensions/ublock/assets/assets.json +3 -3
  79. package/extensions/ublock/assets/resources/scriptlets.js +218 -97
  80. package/extensions/ublock/assets/thirdparties/easylist/easylist.txt +3010 -2056
  81. package/extensions/ublock/assets/thirdparties/easylist/easyprivacy.txt +624 -433
  82. package/extensions/ublock/assets/thirdparties/pgl.yoyo.org/as/serverlist +93 -24
  83. package/extensions/ublock/assets/thirdparties/publicsuffix.org/list/effective_tld_names.dat +7 -15
  84. package/extensions/ublock/assets/thirdparties/urlhaus-filter/urlhaus-filter-online.txt +795 -777
  85. package/extensions/ublock/assets/ublock/badware.min.txt +138 -72
  86. package/extensions/ublock/assets/ublock/filters.min.txt +1929 -2735
  87. package/extensions/ublock/assets/ublock/privacy.min.txt +57 -26
  88. package/extensions/ublock/assets/ublock/quick-fixes.min.txt +125 -74
  89. package/extensions/ublock/assets/ublock/unbreak.min.txt +46 -53
  90. package/extensions/ublock/css/codemirror.css +8 -7
  91. package/extensions/ublock/css/dom-inspector.css +40 -0
  92. package/extensions/ublock/css/logger-ui-inspector.css +7 -1
  93. package/extensions/ublock/css/logger-ui.css +12 -5
  94. package/extensions/ublock/css/popup-fenix.css +1 -1
  95. package/extensions/ublock/devtools.html +1 -0
  96. package/extensions/ublock/js/1p-filters.js +4 -3
  97. package/extensions/ublock/js/3p-filters.js +25 -31
  98. package/extensions/ublock/js/about.js +1 -1
  99. package/extensions/ublock/js/advanced-settings.js +1 -1
  100. package/extensions/ublock/js/asset-viewer.js +1 -1
  101. package/extensions/ublock/js/assets.js +74 -44
  102. package/extensions/ublock/js/background.js +9 -3
  103. package/extensions/ublock/js/base64-custom.js +1 -1
  104. package/extensions/ublock/js/benchmarks.js +1 -1
  105. package/extensions/ublock/js/biditrie.js +1 -1
  106. package/extensions/ublock/js/broadcast.js +75 -0
  107. package/extensions/ublock/js/cachestorage.js +68 -45
  108. package/extensions/ublock/js/click2load.js +1 -1
  109. package/extensions/ublock/js/cloud-ui.js +1 -1
  110. package/extensions/ublock/js/code-viewer.js +1 -1
  111. package/extensions/ublock/js/codemirror/search-thread.js +1 -1
  112. package/extensions/ublock/js/codemirror/search.js +1 -1
  113. package/extensions/ublock/js/codemirror/ubo-dynamic-filtering.js +1 -1
  114. package/extensions/ublock/js/codemirror/ubo-static-filtering.js +98 -24
  115. package/extensions/ublock/js/commands.js +1 -1
  116. package/extensions/ublock/js/console.js +1 -1
  117. package/extensions/ublock/js/contentscript-extra.js +1 -1
  118. package/extensions/ublock/js/contentscript.js +1 -3
  119. package/extensions/ublock/js/contextmenu.js +1 -1
  120. package/extensions/ublock/js/cosmetic-filtering.js +4 -4
  121. package/extensions/ublock/js/dashboard-common.js +1 -1
  122. package/extensions/ublock/js/dashboard.js +1 -1
  123. package/extensions/ublock/js/devtools.js +23 -15
  124. package/extensions/ublock/js/diff-updater.js +3 -3
  125. package/extensions/ublock/js/document-blocked.js +1 -1
  126. package/extensions/ublock/js/dom-inspector.js +68 -0
  127. package/extensions/ublock/js/dom.js +1 -1
  128. package/extensions/ublock/js/dyna-rules.js +1 -1
  129. package/extensions/ublock/js/dynamic-net-filtering.js +1 -1
  130. package/extensions/ublock/js/epicker-ui.js +35 -59
  131. package/extensions/ublock/js/fa-icons.js +1 -1
  132. package/extensions/ublock/js/filtering-context.js +1 -1
  133. package/extensions/ublock/js/filtering-engines.js +1 -1
  134. package/extensions/ublock/js/hnswitches.js +1 -1
  135. package/extensions/ublock/js/hntrie.js +1 -1
  136. package/extensions/ublock/js/html-filtering.js +1 -1
  137. package/extensions/ublock/js/httpheader-filtering.js +1 -1
  138. package/extensions/ublock/js/i18n.js +1 -1
  139. package/extensions/ublock/js/is-webrtc-supported.js +1 -1
  140. package/extensions/ublock/js/logger-ui-inspector.js +203 -145
  141. package/extensions/ublock/js/logger-ui.js +21 -5
  142. package/extensions/ublock/js/logger.js +6 -2
  143. package/extensions/ublock/js/lz4.js +2 -2
  144. package/extensions/ublock/js/messaging.js +266 -166
  145. package/extensions/ublock/js/mrucache.js +58 -0
  146. package/extensions/ublock/js/pagestore.js +1 -1
  147. package/extensions/ublock/js/popup-fenix.js +2 -1
  148. package/extensions/ublock/js/redirect-engine.js +1 -1
  149. package/extensions/ublock/js/redirect-resources.js +1 -12
  150. package/extensions/ublock/js/reverselookup-worker.js +1 -1
  151. package/extensions/ublock/js/reverselookup.js +1 -1
  152. package/extensions/ublock/js/scriptlet-filtering-core.js +300 -0
  153. package/extensions/ublock/js/scriptlet-filtering.js +122 -350
  154. package/extensions/ublock/js/scriptlets/cosmetic-logger.js +36 -47
  155. package/extensions/ublock/js/scriptlets/cosmetic-off.js +1 -1
  156. package/extensions/ublock/js/scriptlets/cosmetic-on.js +1 -1
  157. package/extensions/ublock/js/scriptlets/cosmetic-report.js +1 -1
  158. package/extensions/ublock/js/scriptlets/dom-inspector.js +341 -323
  159. package/extensions/ublock/js/scriptlets/dom-survey-elements.js +1 -1
  160. package/extensions/ublock/js/scriptlets/dom-survey-scripts.js +1 -1
  161. package/extensions/ublock/js/scriptlets/epicker.js +80 -89
  162. package/extensions/ublock/js/scriptlets/load-3p-css.js +1 -1
  163. package/extensions/ublock/js/scriptlets/load-large-media-all.js +1 -1
  164. package/extensions/ublock/js/scriptlets/load-large-media-interactive.js +1 -1
  165. package/extensions/ublock/js/scriptlets/noscript-spoof.js +1 -1
  166. package/extensions/ublock/js/scriptlets/should-inject-contentscript.js +1 -1
  167. package/extensions/ublock/js/scriptlets/subscriber.js +1 -1
  168. package/extensions/ublock/js/scriptlets/updater.js +20 -3
  169. package/extensions/ublock/js/settings.js +1 -1
  170. package/extensions/ublock/js/start.js +19 -20
  171. package/extensions/ublock/js/static-dnr-filtering.js +1 -1
  172. package/extensions/ublock/js/static-ext-filtering-db.js +1 -1
  173. package/extensions/ublock/js/static-ext-filtering.js +1 -1
  174. package/extensions/ublock/js/static-filtering-io.js +1 -1
  175. package/extensions/ublock/js/static-filtering-parser.js +5 -3
  176. package/extensions/ublock/js/static-net-filtering.js +57 -37
  177. package/extensions/ublock/js/storage.js +49 -29
  178. package/extensions/ublock/js/support.js +4 -4
  179. package/extensions/ublock/js/tab.js +1 -1
  180. package/extensions/ublock/js/tasks.js +1 -1
  181. package/extensions/ublock/js/text-encode.js +1 -1
  182. package/extensions/ublock/js/text-utils.js +1 -1
  183. package/extensions/ublock/js/theme.js +1 -1
  184. package/extensions/ublock/js/traffic.js +2 -1
  185. package/extensions/ublock/js/ublock.js +15 -11
  186. package/extensions/ublock/js/uri-utils.js +1 -1
  187. package/extensions/ublock/js/url-net-filtering.js +1 -1
  188. package/extensions/ublock/js/utils.js +1 -73
  189. package/extensions/ublock/js/vapi-background-ext.js +1 -1
  190. package/extensions/ublock/js/vapi-background.js +92 -83
  191. package/extensions/ublock/js/vapi-client.js +4 -33
  192. package/extensions/ublock/js/vapi-common.js +16 -30
  193. package/extensions/ublock/js/vapi.js +1 -1
  194. package/extensions/ublock/js/wasm/biditrie.wat +1 -1
  195. package/extensions/ublock/js/wasm/hntrie.wat +1 -1
  196. package/extensions/ublock/js/webext.js +1 -1
  197. package/extensions/ublock/js/whitelist.js +1 -1
  198. package/extensions/ublock/logger-ui.html +2 -2
  199. package/extensions/ublock/manifest.json +1 -1
  200. package/extensions/ublock/support.html +0 -1
  201. package/extensions/ublock/web_accessible_resources/dom-inspector.html +25 -0
  202. package/extensions/ublock/web_accessible_resources/epicker-ui.html +0 -1
  203. package/extensions/ublock/web_accessible_resources/googletagservices_gpt.js +1 -0
  204. package/package.json +10 -20
  205. package/scripts/build-open-api.js +7 -4
  206. package/src/browserless.ts +42 -18
  207. package/src/browsers/index.ts +48 -20
  208. package/src/http.ts +3 -3
  209. package/src/router.ts +2 -6
  210. package/src/routes/chromium/http/content-post.ts +13 -16
  211. package/src/routes/chromium/http/download-post.ts +16 -27
  212. package/src/routes/chromium/http/function-post.ts +16 -25
  213. package/src/routes/chromium/http/pdf-post.ts +19 -15
  214. package/src/routes/chromium/http/performance.ts +14 -26
  215. package/src/routes/chromium/http/scrape-post.ts +14 -16
  216. package/src/routes/chromium/http/screenshot-post.ts +18 -15
  217. package/src/routes/chromium/tests/websocket.spec.ts +28 -1
  218. package/src/routes/chromium/utils/function/handler.ts +2 -1
  219. package/src/routes/chromium/ws/browser.ts +10 -12
  220. package/src/routes/chromium/ws/cdp-chromium.ts +10 -12
  221. package/src/routes/chromium/ws/page.ts +10 -12
  222. package/src/routes/chromium/ws/playwright-chromium.ts +10 -12
  223. package/src/routes/firefox/ws/playwright-firefox.ts +10 -12
  224. package/src/routes/management/http/config-get.ts +14 -23
  225. package/src/routes/management/http/metrics-get.ts +15 -24
  226. package/src/routes/management/http/metrics-total-get.ts +15 -26
  227. package/src/routes/management/http/sessions-get.ts +15 -23
  228. package/src/routes/management/http/static-get.ts +14 -22
  229. package/src/routes/webkit/ws/playwright-webkit.ts +10 -12
  230. package/src/server.ts +0 -1
  231. package/src/types.ts +59 -45
  232. package/static/docs/browserless-logo-inline.svg +1 -0
  233. package/static/docs/index.html +27 -0
  234. package/static/docs/swagger.json +33 -33
  235. package/static/function/client.js +626 -78
  236. package/extensions/ublock/js/vapi-client-extra.js +0 -312
  237. package/extensions/ublock/web_accessible_resources/addthis_widget.js +0 -39
  238. package/extensions/ublock/web_accessible_resources/ligatus_angular-tag.js +0 -29
  239. package/extensions/ublock/web_accessible_resources/monkeybroker.js +0 -43
  240. package/extensions/ublock/web_accessible_resources/mxpnl_mixpanel.js +0 -51
@@ -1,4 +1,4 @@
1
- import { APITags, BadRequest, CDPChromium, HTTPRoutes, Methods, Timeout, bestAttemptCatch, contentTypes, debugScreenshotOpts, dedent, jsonResponse, noop, waitForEvent as waitForEvt, waitForFunction as waitForFn, } from '@browserless.io/browserless';
1
+ import { APITags, BadRequest, BrowserHTTPRoute, CDPChromium, HTTPRoutes, Methods, Timeout, bestAttemptCatch, contentTypes, debugScreenshotOpts, dedent, jsonResponse, noop, waitForEvent as waitForEvt, waitForFunction as waitForFn, } from '@browserless.io/browserless';
2
2
  const scrape = async (elements) => {
3
3
  const wait = (selector, timeout = 30000) => {
4
4
  return new Promise((resolve, reject) => {
@@ -39,18 +39,21 @@ const scrape = async (elements) => {
39
39
  };
40
40
  });
41
41
  };
42
- const route = {
43
- accepts: [contentTypes.json],
44
- auth: true,
45
- browser: CDPChromium,
46
- concurrency: true,
47
- contentTypes: [contentTypes.json],
48
- description: dedent(`
42
+ export default class ScrapePost extends BrowserHTTPRoute {
43
+ accepts = [contentTypes.json];
44
+ auth = true;
45
+ browser = CDPChromium;
46
+ concurrency = true;
47
+ contentTypes = [contentTypes.json];
48
+ description = dedent(`
49
49
  A JSON-based API that returns text, html, and meta-data from a given list of selectors.
50
50
  Debugging information is available by sending in the appropriate flags in the "debugOpts"
51
51
  property. Responds with an array of JSON objects.
52
- `),
53
- handler: async (req, res, browser) => {
52
+ `);
53
+ method = Methods.post;
54
+ path = HTTPRoutes.scrape;
55
+ tags = [APITags.browserAPI];
56
+ handler = async (req, res, browser) => {
54
57
  const contentType = !req.headers.accept || req.headers.accept?.includes('*')
55
58
  ? contentTypes.html
56
59
  : req.headers.accept;
@@ -197,9 +200,5 @@ const route = {
197
200
  };
198
201
  page.close().catch(noop);
199
202
  return jsonResponse(res, 200, response, false);
200
- },
201
- method: Methods.post,
202
- path: HTTPRoutes.scrape,
203
- tags: [APITags.browserAPI],
204
- };
205
- export default route;
203
+ };
204
+ }
@@ -488,14 +488,14 @@
488
488
  "length": {
489
489
  "type": "number"
490
490
  },
491
- "__@toStringTag@75317": {
491
+ "__@toStringTag@75362": {
492
492
  "type": "string",
493
493
  "const": "Uint8Array"
494
494
  }
495
495
  },
496
496
  "required": [
497
497
  "BYTES_PER_ELEMENT",
498
- "__@toStringTag@75317",
498
+ "__@toStringTag@75362",
499
499
  "buffer",
500
500
  "byteLength",
501
501
  "byteOffset",
@@ -530,13 +530,13 @@
530
530
  "byteLength": {
531
531
  "type": "number"
532
532
  },
533
- "__@toStringTag@75317": {
533
+ "__@toStringTag@75362": {
534
534
  "type": "string"
535
535
  }
536
536
  },
537
537
  "additionalProperties": false,
538
538
  "required": [
539
- "__@toStringTag@75317",
539
+ "__@toStringTag@75362",
540
540
  "byteLength"
541
541
  ]
542
542
  },
@@ -546,18 +546,18 @@
546
546
  "byteLength": {
547
547
  "type": "number"
548
548
  },
549
- "__@species@75418": {
549
+ "__@species@75463": {
550
550
  "$ref": "#/definitions/SharedArrayBuffer"
551
551
  },
552
- "__@toStringTag@75317": {
552
+ "__@toStringTag@75362": {
553
553
  "type": "string",
554
554
  "const": "SharedArrayBuffer"
555
555
  }
556
556
  },
557
557
  "additionalProperties": false,
558
558
  "required": [
559
- "__@species@75418",
560
- "__@toStringTag@75317",
559
+ "__@species@75463",
560
+ "__@toStringTag@75362",
561
561
  "byteLength"
562
562
  ]
563
563
  },
@@ -1,5 +1,7 @@
1
- import { BrowserHTTPRoute, CDPLaunchOptions, SystemQueryParameters, WaitForEventOptions, WaitForFunctionOptions, WaitForSelectorOptions, bestAttempt, rejectRequestPattern, rejectResourceTypes, requestInterceptors } from '@browserless.io/browserless';
1
+ /// <reference types="node" />
2
+ import { APITags, BrowserHTTPRoute, BrowserInstance, CDPChromium, CDPLaunchOptions, HTTPRoutes, Methods, Request, SystemQueryParameters, WaitForEventOptions, WaitForFunctionOptions, WaitForSelectorOptions, bestAttempt, contentTypes, rejectRequestPattern, rejectResourceTypes, requestInterceptors } from '@browserless.io/browserless';
2
3
  import { Page } from 'puppeteer-core';
4
+ import { ServerResponse } from 'http';
3
5
  export interface QuerySchema extends SystemQueryParameters {
4
6
  launch?: CDPLaunchOptions | string;
5
7
  }
@@ -33,5 +35,15 @@ export interface BodySchema {
33
35
  waitForSelector?: WaitForSelectorOptions;
34
36
  waitForTimeout?: Parameters<Page['waitForTimeout']>[0];
35
37
  }
36
- declare const route: BrowserHTTPRoute;
37
- export default route;
38
+ export default class ScreenshotPost extends BrowserHTTPRoute {
39
+ accepts: contentTypes[];
40
+ auth: boolean;
41
+ browser: typeof CDPChromium;
42
+ concurrency: boolean;
43
+ contentTypes: contentTypes[];
44
+ description: string;
45
+ method: Methods;
46
+ path: HTTPRoutes;
47
+ tags: APITags[];
48
+ handler: (req: Request, res: ServerResponse, browser: BrowserInstance) => Promise<void>;
49
+ }
@@ -1,13 +1,20 @@
1
- import { APITags, BadRequest, CDPChromium, HTTPRoutes, Methods, bestAttemptCatch, contentTypes, noop, scrollThroughPage, waitForEvent as waitForEvt, waitForFunction as waitForFn, } from '@browserless.io/browserless';
1
+ import { APITags, BadRequest, BrowserHTTPRoute, CDPChromium, HTTPRoutes, Methods, bestAttemptCatch, contentTypes, dedent, noop, scrollThroughPage, waitForEvent as waitForEvt, waitForFunction as waitForFn, } from '@browserless.io/browserless';
2
2
  import Stream from 'stream';
3
- const route = {
4
- accepts: [contentTypes.json],
5
- auth: true,
6
- browser: CDPChromium,
7
- concurrency: true,
8
- contentTypes: [contentTypes.png, contentTypes.jpeg, contentTypes.text],
9
- description: `A JSON-based API for getting a screenshot binary from either a supplied "url" or "html" payload in your request.`,
10
- handler: async (req, res, browser) => {
3
+ export default class ScreenshotPost extends BrowserHTTPRoute {
4
+ accepts = [contentTypes.json];
5
+ auth = true;
6
+ browser = CDPChromium;
7
+ concurrency = true;
8
+ contentTypes = [contentTypes.png, contentTypes.jpeg, contentTypes.text];
9
+ description = dedent(`
10
+ A JSON-based API for getting a screenshot binary from either a supplied
11
+ "url" or "html" payload in your request. Many options exist including
12
+ cookies, user-agents, setting timers and network mocks.
13
+ `);
14
+ method = Methods.post;
15
+ path = HTTPRoutes.screenshot;
16
+ tags = [APITags.browserAPI];
17
+ handler = async (req, res, browser) => {
11
18
  const contentType = !req.headers.accept || req.headers.accept?.includes('*')
12
19
  ? 'image/png'
13
20
  : req.headers.accept;
@@ -116,9 +123,5 @@ const route = {
116
123
  readStream.end(buffer);
117
124
  await new Promise((r) => readStream.pipe(res).once('close', r));
118
125
  page.close().catch(noop);
119
- },
120
- method: Methods.post,
121
- path: HTTPRoutes.screenshot,
122
- tags: [APITags.browserAPI],
123
- };
124
- export default route;
126
+ };
127
+ }
@@ -123,6 +123,25 @@ describe('WebSocket API', function () {
123
123
  await sleep(1000);
124
124
  expect(await exists(userDataDir)).to.be.false;
125
125
  });
126
+ it('allows specified user-data-dirs', async () => {
127
+ const dataDir = '/tmp/data-dir';
128
+ const config = new Config();
129
+ config.setToken('browserless');
130
+ const metrics = new Metrics();
131
+ await start({ config, metrics });
132
+ const launch = JSON.stringify({
133
+ args: [`--user-data-dir=${dataDir}`],
134
+ });
135
+ const browser = await puppeteer.connect({
136
+ browserWSEndpoint: `ws://localhost:3000?token=browserless&launch=${launch}`,
137
+ });
138
+ const [{ userDataDir }] = await fetch('http://localhost:3000/sessions?token=browserless').then((r) => r.json());
139
+ expect(await exists(userDataDir)).to.be.true;
140
+ expect(userDataDir).to.equal(dataDir);
141
+ await browser.disconnect();
142
+ await sleep(1000);
143
+ expect(await exists(userDataDir)).to.be.true;
144
+ });
126
145
  it('creates user-data-dirs with userDataDir options', async () => {
127
146
  const dataDirLocation = '/tmp/browserless-test-dir';
128
147
  const launch = JSON.stringify({
@@ -146,7 +165,7 @@ describe('WebSocket API', function () {
146
165
  it('creates user-data-dirs with CLI flags', async () => {
147
166
  const dataDirLocation = '/tmp/browserless-test-dir';
148
167
  const launch = JSON.stringify({
149
- args: [`--user-data-dir==${dataDirLocation}`],
168
+ args: [`--user-data-dir=${dataDirLocation}`],
150
169
  });
151
170
  const config = new Config();
152
171
  config.setToken('browserless');
@@ -1,4 +1,4 @@
1
- import { BadRequest, HTTPRoutes, contentTypes, convertIfBase64, exists, id, makeExternalURL, mimeTypes, } from '@browserless.io/browserless';
1
+ import { BadRequest, HTTPRoutes, contentTypes, convertIfBase64, exists, getTokenFromRequest, id, makeExternalURL, mimeTypes, } from '@browserless.io/browserless';
2
2
  import fs from 'fs';
3
3
  import path from 'path';
4
4
  export default (config, debug, options = {}) => async (req, browser) => {
@@ -14,7 +14,7 @@ export default (config, debug, options = {}) => async (req, browser) => {
14
14
  };
15
15
  const context = JSON.stringify(rawContext);
16
16
  const code = convertIfBase64(rawCode);
17
- const browserWSEndpoint = browser.publicWSEndpoint(req.parsed.searchParams.get('token') ?? '');
17
+ const browserWSEndpoint = browser.publicWSEndpoint(getTokenFromRequest(req) ?? '');
18
18
  if (!browserWSEndpoint) {
19
19
  throw new Error(`No browser endpoint was found, is the browser running?`);
20
20
  }
@@ -1,6 +1,16 @@
1
- import { BrowserWebsocketRoute, CDPLaunchOptions, SystemQueryParameters } from '@browserless.io/browserless';
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { APITags, BrowserWebsocketRoute, CDPChromium, CDPLaunchOptions, Request, SystemQueryParameters, WebsocketRoutes } from '@browserless.io/browserless';
4
+ import { Duplex } from 'stream';
2
5
  export interface QuerySchema extends SystemQueryParameters {
3
6
  launch?: CDPLaunchOptions | string;
4
7
  }
5
- declare const route: BrowserWebsocketRoute;
6
- export default route;
8
+ export default class CDPExistingBrowser extends BrowserWebsocketRoute {
9
+ auth: boolean;
10
+ browser: typeof CDPChromium;
11
+ concurrency: boolean;
12
+ description: string;
13
+ path: WebsocketRoutes;
14
+ tags: APITags[];
15
+ handler: (req: Request, socket: Duplex, head: Buffer, chrome: CDPChromium) => Promise<void>;
16
+ }
@@ -1,11 +1,10 @@
1
- import { APITags, CDPChromium, WebsocketRoutes, } from '@browserless.io/browserless';
2
- const route = {
3
- auth: true,
4
- browser: CDPChromium,
5
- concurrency: false,
6
- description: `Connect to an already-running Chromium with a library like puppeteer, or others, that work over chrome-devtools-protocol.`,
7
- handler: async (req, socket, head, chrome) => chrome.proxyWebSocket(req, socket, head),
8
- path: WebsocketRoutes.browser,
9
- tags: [APITags.browserWS],
10
- };
11
- export default route;
1
+ import { APITags, BrowserWebsocketRoute, CDPChromium, WebsocketRoutes, } from '@browserless.io/browserless';
2
+ export default class CDPExistingBrowser extends BrowserWebsocketRoute {
3
+ auth = true;
4
+ browser = CDPChromium;
5
+ concurrency = false;
6
+ description = `Connect to an already-running Chromium with a library like puppeteer, or others, that work over chrome-devtools-protocol.`;
7
+ path = WebsocketRoutes.browser;
8
+ tags = [APITags.browserWS];
9
+ handler = async (req, socket, head, chrome) => chrome.proxyWebSocket(req, socket, head);
10
+ }
@@ -1,6 +1,16 @@
1
- import { BrowserWebsocketRoute, CDPLaunchOptions, SystemQueryParameters } from '@browserless.io/browserless';
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { APITags, BrowserWebsocketRoute, CDPChromium, CDPLaunchOptions, Request, SystemQueryParameters, WebsocketRoutes } from '@browserless.io/browserless';
4
+ import { Duplex } from 'stream';
2
5
  export interface QuerySchema extends SystemQueryParameters {
3
6
  launch?: CDPLaunchOptions | string;
4
7
  }
5
- declare const route: BrowserWebsocketRoute;
6
- export default route;
8
+ export default class CDPChromiumRoute extends BrowserWebsocketRoute {
9
+ auth: boolean;
10
+ browser: typeof CDPChromium;
11
+ concurrency: boolean;
12
+ description: string;
13
+ path: WebsocketRoutes;
14
+ tags: APITags[];
15
+ handler: (req: Request, socket: Duplex, head: Buffer, chrome: CDPChromium) => Promise<void>;
16
+ }
@@ -1,11 +1,10 @@
1
- import { APITags, CDPChromium, WebsocketRoutes, } from '@browserless.io/browserless';
2
- const route = {
3
- auth: true,
4
- browser: CDPChromium,
5
- concurrency: true,
6
- description: `Launch and connect to Chromium with a library like puppeteer or others that work over chrome-devtools-protocol.`,
7
- handler: async (req, socket, head, chrome) => chrome.proxyWebSocket(req, socket, head),
8
- path: WebsocketRoutes['/'],
9
- tags: [APITags.browserWS],
10
- };
11
- export default route;
1
+ import { APITags, BrowserWebsocketRoute, CDPChromium, WebsocketRoutes, } from '@browserless.io/browserless';
2
+ export default class CDPChromiumRoute extends BrowserWebsocketRoute {
3
+ auth = true;
4
+ browser = CDPChromium;
5
+ concurrency = true;
6
+ description = `Launch and connect to Chromium with a library like puppeteer or others that work over chrome-devtools-protocol.`;
7
+ path = WebsocketRoutes['/'];
8
+ tags = [APITags.browserWS];
9
+ handler = async (req, socket, head, chrome) => chrome.proxyWebSocket(req, socket, head);
10
+ }
@@ -1,6 +1,16 @@
1
- import { BrowserWebsocketRoute, CDPLaunchOptions, SystemQueryParameters } from '@browserless.io/browserless';
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { APITags, BrowserWebsocketRoute, CDPChromium, CDPLaunchOptions, Request, SystemQueryParameters, WebsocketRoutes } from '@browserless.io/browserless';
4
+ import { Duplex } from 'stream';
2
5
  export interface QuerySchema extends SystemQueryParameters {
3
6
  launch?: CDPLaunchOptions | string;
4
7
  }
5
- declare const route: BrowserWebsocketRoute;
6
- export default route;
8
+ export default class PageWebSocketRoute extends BrowserWebsocketRoute {
9
+ auth: boolean;
10
+ browser: typeof CDPChromium;
11
+ concurrency: boolean;
12
+ description: string;
13
+ path: WebsocketRoutes;
14
+ tags: APITags[];
15
+ handler: (req: Request, socket: Duplex, head: Buffer, chrome: CDPChromium) => Promise<void>;
16
+ }
@@ -1,11 +1,10 @@
1
- import { APITags, CDPChromium, WebsocketRoutes, } from '@browserless.io/browserless';
2
- const route = {
3
- auth: true,
4
- browser: CDPChromium,
5
- concurrency: false,
6
- description: `Connect to Chromium with a library like chrome-remote-interface or others that work over JSON chrome-devtools-protocol.`,
7
- handler: async (req, socket, head, chrome) => chrome.proxyPageWebSocket(req, socket, head),
8
- path: WebsocketRoutes.page,
9
- tags: [APITags.browserWS],
10
- };
11
- export default route;
1
+ import { APITags, BrowserWebsocketRoute, CDPChromium, WebsocketRoutes, } from '@browserless.io/browserless';
2
+ export default class PageWebSocketRoute extends BrowserWebsocketRoute {
3
+ auth = true;
4
+ browser = CDPChromium;
5
+ concurrency = false;
6
+ description = `Connect to Chromium with a library like chrome-remote-interface or others that work over JSON chrome-devtools-protocol.`;
7
+ path = WebsocketRoutes.page;
8
+ tags = [APITags.browserWS];
9
+ handler = async (req, socket, head, chrome) => chrome.proxyPageWebSocket(req, socket, head);
10
+ }
@@ -1,6 +1,16 @@
1
- import { BrowserServerOptions, BrowserWebsocketRoute, SystemQueryParameters } from '@browserless.io/browserless';
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { APITags, BrowserServerOptions, BrowserWebsocketRoute, PlaywrightChromium, Request, SystemQueryParameters, WebsocketRoutes } from '@browserless.io/browserless';
4
+ import { Duplex } from 'stream';
2
5
  export interface QuerySchema extends SystemQueryParameters {
3
6
  launch?: BrowserServerOptions | string;
4
7
  }
5
- declare const route: BrowserWebsocketRoute;
6
- export default route;
8
+ export default class PlaywrightChromiumRoute extends BrowserWebsocketRoute {
9
+ auth: boolean;
10
+ browser: typeof PlaywrightChromium;
11
+ concurrency: boolean;
12
+ description: string;
13
+ path: WebsocketRoutes;
14
+ tags: APITags[];
15
+ handler: (req: Request, socket: Duplex, head: Buffer, browser: PlaywrightChromium) => Promise<void>;
16
+ }
@@ -1,10 +1,12 @@
1
- import { APITags, BadRequest, PlaywrightChromium, WebsocketRoutes, } from '@browserless.io/browserless';
2
- const route = {
3
- auth: true,
4
- browser: PlaywrightChromium,
5
- concurrency: true,
6
- description: `Connect to Chromium with any playwright-compliant library.`,
7
- handler: async (req, socket, head, browser) => {
1
+ import { APITags, BadRequest, BrowserWebsocketRoute, PlaywrightChromium, WebsocketRoutes, } from '@browserless.io/browserless';
2
+ export default class PlaywrightChromiumRoute extends BrowserWebsocketRoute {
3
+ auth = true;
4
+ browser = PlaywrightChromium;
5
+ concurrency = true;
6
+ description = `Connect to Chromium with any playwright style library.`;
7
+ path = WebsocketRoutes.playwrightChromium;
8
+ tags = [APITags.browserWS];
9
+ handler = async (req, socket, head, browser) => {
8
10
  const isPlaywright = req.headers['user-agent']
9
11
  ?.toLowerCase()
10
12
  .includes('playwright');
@@ -12,8 +14,5 @@ const route = {
12
14
  throw new BadRequest(`Only playwright is allowed to work with this route`);
13
15
  }
14
16
  return browser.proxyWebSocket(req, socket, head);
15
- },
16
- path: WebsocketRoutes.playwrightChromium,
17
- tags: [APITags.browserWS],
18
- };
19
- export default route;
17
+ };
18
+ }
@@ -1,6 +1,16 @@
1
- import { BrowserServerOptions, BrowserWebsocketRoute, SystemQueryParameters } from '@browserless.io/browserless';
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { APITags, BrowserServerOptions, BrowserWebsocketRoute, PlaywrightFirefox, Request, SystemQueryParameters, WebsocketRoutes } from '@browserless.io/browserless';
4
+ import { Duplex } from 'stream';
2
5
  export interface QuerySchema extends SystemQueryParameters {
3
6
  launch?: BrowserServerOptions | string;
4
7
  }
5
- declare const route: BrowserWebsocketRoute;
6
- export default route;
8
+ export default class PlayWrightFirefoxRoute extends BrowserWebsocketRoute {
9
+ auth: boolean;
10
+ browser: typeof PlaywrightFirefox;
11
+ concurrency: boolean;
12
+ description: string;
13
+ path: WebsocketRoutes;
14
+ tags: APITags[];
15
+ handler: (req: Request, socket: Duplex, head: Buffer, browser: PlaywrightFirefox) => Promise<void>;
16
+ }
@@ -1,10 +1,12 @@
1
- import { APITags, BadRequest, PlaywrightFirefox, WebsocketRoutes, } from '@browserless.io/browserless';
2
- const route = {
3
- auth: true,
4
- browser: PlaywrightFirefox,
5
- concurrency: true,
6
- description: `Connect to Firefox with any playwright-compliant library.`,
7
- handler: async (req, socket, head, browser) => {
1
+ import { APITags, BadRequest, BrowserWebsocketRoute, PlaywrightFirefox, WebsocketRoutes, } from '@browserless.io/browserless';
2
+ export default class PlayWrightFirefoxRoute extends BrowserWebsocketRoute {
3
+ auth = true;
4
+ browser = PlaywrightFirefox;
5
+ concurrency = true;
6
+ description = `Connect to Firefox with any playwright-compliant library.`;
7
+ path = WebsocketRoutes.playwrightFirefox;
8
+ tags = [APITags.browserWS];
9
+ handler = async (req, socket, head, browser) => {
8
10
  const isPlaywright = req.headers['user-agent']
9
11
  ?.toLowerCase()
10
12
  .includes('playwright');
@@ -12,8 +14,5 @@ const route = {
12
14
  throw new BadRequest(`Only playwright is allowed to work with this route`);
13
15
  }
14
16
  return browser.proxyWebSocket(req, socket, head);
15
- },
16
- path: WebsocketRoutes.playwrightFirefox,
17
- tags: [APITags.browserWS],
18
- };
19
- export default route;
17
+ };
18
+ }
@@ -1,4 +1,6 @@
1
- import { HTTPRoute } from '@browserless.io/browserless';
1
+ /// <reference types="node" />
2
+ import { APITags, HTTPManagementRoutes, HTTPRoute, Methods, Request, contentTypes } from '@browserless.io/browserless';
3
+ import { ServerResponse } from 'http';
2
4
  export interface ResponseSchema {
3
5
  allowCORS: boolean;
4
6
  allowFileProtocol: boolean;
@@ -21,5 +23,15 @@ export interface ResponseSchema {
21
23
  timeoutAlertURL: string | null;
22
24
  token: string | null;
23
25
  }
24
- declare const route: HTTPRoute;
25
- export default route;
26
+ export default class ConfigGetRoute extends HTTPRoute {
27
+ accepts: contentTypes[];
28
+ auth: boolean;
29
+ browser: null;
30
+ concurrency: boolean;
31
+ contentTypes: contentTypes[];
32
+ description: string;
33
+ method: Methods;
34
+ path: HTTPManagementRoutes;
35
+ tags: APITags[];
36
+ handler: (_req: Request, res: ServerResponse) => Promise<void>;
37
+ }
@@ -1,17 +1,16 @@
1
- import { APITags, HTTPManagementRoutes, Methods, ServerError, contentTypes, jsonResponse, } from '@browserless.io/browserless';
2
- const route = {
3
- accepts: [contentTypes.any],
4
- auth: true,
5
- browser: null,
6
- concurrency: false,
7
- contentTypes: [contentTypes.json],
8
- description: `Returns a JSON payload of the current system configuration.`,
9
- handler: async (_req, res) => {
10
- const { getConfig: getConfig } = route;
11
- if (!getConfig) {
12
- throw new ServerError(`Couldn't locate the config object`);
13
- }
14
- const config = getConfig();
1
+ import { APITags, HTTPManagementRoutes, HTTPRoute, Methods, contentTypes, jsonResponse, } from '@browserless.io/browserless';
2
+ export default class ConfigGetRoute extends HTTPRoute {
3
+ accepts = [contentTypes.any];
4
+ auth = true;
5
+ browser = null;
6
+ concurrency = false;
7
+ contentTypes = [contentTypes.json];
8
+ description = `Returns a JSON payload of the current system configuration.`;
9
+ method = Methods.get;
10
+ path = HTTPManagementRoutes.config;
11
+ tags = [APITags.management];
12
+ handler = async (_req, res) => {
13
+ const config = this.config();
15
14
  const response = {
16
15
  allowCORS: config.getAllowCORS(),
17
16
  allowFileProtocol: config.getAllowFileProtocol(),
@@ -35,9 +34,5 @@ const route = {
35
34
  token: config.getToken(),
36
35
  };
37
36
  return jsonResponse(res, 200, response);
38
- },
39
- method: Methods.get,
40
- path: HTTPManagementRoutes.config,
41
- tags: [APITags.management],
42
- };
43
- export default route;
37
+ };
38
+ }
@@ -1,4 +1,16 @@
1
- import { HTTPRoute, IBrowserlessStats } from '@browserless.io/browserless';
1
+ /// <reference types="node" />
2
+ import { APITags, HTTPManagementRoutes, HTTPRoute, IBrowserlessStats, Methods, Request, contentTypes } from '@browserless.io/browserless';
3
+ import { ServerResponse } from 'http';
2
4
  export type ResponseSchema = Array<IBrowserlessStats>;
3
- declare const route: HTTPRoute;
4
- export default route;
5
+ export default class MetricsGetRoute extends HTTPRoute {
6
+ accepts: contentTypes[];
7
+ auth: boolean;
8
+ browser: null;
9
+ concurrency: boolean;
10
+ contentTypes: contentTypes[];
11
+ description: string;
12
+ method: Methods;
13
+ path: HTTPManagementRoutes;
14
+ tags: APITags[];
15
+ handler: (_req: Request, res: ServerResponse) => Promise<void>;
16
+ }
@@ -1,24 +1,19 @@
1
- import { APITags, HTTPManagementRoutes, Methods, ServerError, contentTypes, writeResponse, } from '@browserless.io/browserless';
2
- const route = {
3
- accepts: [contentTypes.any],
4
- auth: true,
5
- browser: null,
6
- concurrency: false,
7
- contentTypes: [contentTypes.json],
8
- description: `Gets total metric details from the time the server started.`,
9
- handler: async (_req, res) => {
10
- const { getFileSystem: _fileSystem, getConfig: _config } = route;
11
- if (!_fileSystem || !_config) {
12
- throw new ServerError(`Couldn't locate the file-system or config module`);
13
- }
14
- const fileSystem = _fileSystem();
15
- const config = _config();
1
+ import { APITags, HTTPManagementRoutes, HTTPRoute, Methods, contentTypes, writeResponse, } from '@browserless.io/browserless';
2
+ export default class MetricsGetRoute extends HTTPRoute {
3
+ accepts = [contentTypes.any];
4
+ auth = true;
5
+ browser = null;
6
+ concurrency = false;
7
+ contentTypes = [contentTypes.json];
8
+ description = `Gets total metric details from the time the server started.`;
9
+ method = Methods.get;
10
+ path = HTTPManagementRoutes.metrics;
11
+ tags = [APITags.management];
12
+ handler = async (_req, res) => {
13
+ const fileSystem = this.fileSystem();
14
+ const config = this.config();
16
15
  const stats = await fileSystem.read(config.getMetricsJSONPath());
17
16
  const response = `[${stats.join(',')}]`;
18
17
  return writeResponse(res, 200, response, contentTypes.json);
19
- },
20
- method: Methods.get,
21
- path: HTTPManagementRoutes.metrics,
22
- tags: [APITags.management],
23
- };
24
- export default route;
18
+ };
19
+ }
@@ -1,4 +1,16 @@
1
- import { HTTPRoute, IBrowserlessMetricTotals } from '@browserless.io/browserless';
1
+ /// <reference types="node" />
2
+ import { APITags, HTTPManagementRoutes, HTTPRoute, IBrowserlessMetricTotals, Methods, Request, contentTypes } from '@browserless.io/browserless';
3
+ import { ServerResponse } from 'http';
2
4
  export type ResponseSchema = IBrowserlessMetricTotals;
3
- declare const route: HTTPRoute;
4
- export default route;
5
+ export default class MetricsTotalGetRoute extends HTTPRoute {
6
+ accepts: contentTypes[];
7
+ auth: boolean;
8
+ browser: null;
9
+ concurrency: boolean;
10
+ contentTypes: contentTypes[];
11
+ description: string;
12
+ method: Methods;
13
+ path: HTTPManagementRoutes;
14
+ tags: APITags[];
15
+ handler: (_req: Request, res: ServerResponse) => Promise<void>;
16
+ }