@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
@@ -198,18 +198,21 @@ const scrape = async (elements: ScrapeElementSelector[]) => {
198
198
  });
199
199
  };
200
200
 
201
- const route: BrowserHTTPRoute = {
202
- accepts: [contentTypes.json],
203
- auth: true,
204
- browser: CDPChromium,
205
- concurrency: true,
206
- contentTypes: [contentTypes.json],
207
- description: dedent(`
201
+ export default class ScrapePost extends BrowserHTTPRoute {
202
+ accepts = [contentTypes.json];
203
+ auth = true;
204
+ browser = CDPChromium;
205
+ concurrency = true;
206
+ contentTypes = [contentTypes.json];
207
+ description = dedent(`
208
208
  A JSON-based API that returns text, html, and meta-data from a given list of selectors.
209
209
  Debugging information is available by sending in the appropriate flags in the "debugOpts"
210
210
  property. Responds with an array of JSON objects.
211
- `),
212
- handler: async (
211
+ `);
212
+ method = Methods.post;
213
+ path = HTTPRoutes.scrape;
214
+ tags = [APITags.browserAPI];
215
+ handler = async (
213
216
  req: Request,
214
217
  res: ServerResponse,
215
218
  browser: BrowserInstance,
@@ -430,10 +433,5 @@ const route: BrowserHTTPRoute = {
430
433
  page.close().catch(noop);
431
434
 
432
435
  return jsonResponse(res, 200, response, false);
433
- },
434
- method: Methods.post,
435
- path: HTTPRoutes.scrape,
436
- tags: [APITags.browserAPI],
437
- };
438
-
439
- export default route;
436
+ };
437
+ }
@@ -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,
@@ -64,14 +65,21 @@ export interface BodySchema {
64
65
  waitForTimeout?: Parameters<Page['waitForTimeout']>[0];
65
66
  }
66
67
 
67
- const route: BrowserHTTPRoute = {
68
- accepts: [contentTypes.json],
69
- auth: true,
70
- browser: CDPChromium,
71
- concurrency: true,
72
- contentTypes: [contentTypes.png, contentTypes.jpeg, contentTypes.text],
73
- description: `A JSON-based API for getting a screenshot binary from either a supplied "url" or "html" payload in your request.`,
74
- handler: async (
68
+ export default class ScreenshotPost extends BrowserHTTPRoute {
69
+ accepts = [contentTypes.json];
70
+ auth = true;
71
+ browser = CDPChromium;
72
+ concurrency = true;
73
+ contentTypes = [contentTypes.png, contentTypes.jpeg, contentTypes.text];
74
+ description = dedent(`
75
+ A JSON-based API for getting a screenshot binary from either a supplied
76
+ "url" or "html" payload in your request. Many options exist including
77
+ cookies, user-agents, setting timers and network mocks.
78
+ `);
79
+ method = Methods.post;
80
+ path = HTTPRoutes.screenshot;
81
+ tags = [APITags.browserAPI];
82
+ handler = async (
75
83
  req: Request,
76
84
  res: ServerResponse,
77
85
  browser: BrowserInstance,
@@ -253,10 +261,5 @@ const route: BrowserHTTPRoute = {
253
261
  await new Promise((r) => readStream.pipe(res).once('close', r));
254
262
 
255
263
  page.close().catch(noop);
256
- },
257
- method: Methods.post,
258
- path: HTTPRoutes.screenshot,
259
- tags: [APITags.browserAPI],
260
- };
261
-
262
- export default route;
264
+ };
265
+ }
@@ -170,6 +170,33 @@ describe('WebSocket API', function () {
170
170
  expect(await exists(userDataDir)).to.be.false;
171
171
  });
172
172
 
173
+ it('allows specified user-data-dirs', async () => {
174
+ const dataDir = '/tmp/data-dir';
175
+ const config = new Config();
176
+ config.setToken('browserless');
177
+ const metrics = new Metrics();
178
+ await start({ config, metrics });
179
+ const launch = JSON.stringify({
180
+ args: [`--user-data-dir=${dataDir}`],
181
+ });
182
+
183
+ const browser = await puppeteer.connect({
184
+ browserWSEndpoint: `ws://localhost:3000?token=browserless&launch=${launch}`,
185
+ });
186
+
187
+ const [{ userDataDir }] = await fetch(
188
+ 'http://localhost:3000/sessions?token=browserless',
189
+ ).then((r) => r.json());
190
+
191
+ expect(await exists(userDataDir)).to.be.true;
192
+ expect(userDataDir).to.equal(dataDir);
193
+
194
+ await browser.disconnect();
195
+ await sleep(1000);
196
+
197
+ expect(await exists(userDataDir)).to.be.true;
198
+ });
199
+
173
200
  it('creates user-data-dirs with userDataDir options', async () => {
174
201
  const dataDirLocation = '/tmp/browserless-test-dir';
175
202
  const launch = JSON.stringify({
@@ -201,7 +228,7 @@ describe('WebSocket API', function () {
201
228
  it('creates user-data-dirs with CLI flags', async () => {
202
229
  const dataDirLocation = '/tmp/browserless-test-dir';
203
230
  const launch = JSON.stringify({
204
- args: [`--user-data-dir==${dataDirLocation}`],
231
+ args: [`--user-data-dir=${dataDirLocation}`],
205
232
  });
206
233
  const config = new Config();
207
234
  config.setToken('browserless');
@@ -9,6 +9,7 @@ import {
9
9
  contentTypes,
10
10
  convertIfBase64,
11
11
  exists,
12
+ getTokenFromRequest,
12
13
  id,
13
14
  makeExternalURL,
14
15
  mimeTypes,
@@ -66,7 +67,7 @@ export default (
66
67
  const context = JSON.stringify(rawContext);
67
68
  const code = convertIfBase64(rawCode);
68
69
  const browserWSEndpoint = browser.publicWSEndpoint(
69
- req.parsed.searchParams.get('token') ?? '',
70
+ getTokenFromRequest(req) ?? '',
70
71
  );
71
72
 
72
73
  if (!browserWSEndpoint) {
@@ -13,19 +13,17 @@ export interface QuerySchema extends SystemQueryParameters {
13
13
  launch?: CDPLaunchOptions | string;
14
14
  }
15
15
 
16
- const route: BrowserWebsocketRoute = {
17
- auth: true,
18
- browser: CDPChromium,
19
- concurrency: false,
20
- description: `Connect to an already-running Chromium with a library like puppeteer, or others, that work over chrome-devtools-protocol.`,
21
- handler: async (
16
+ export default class CDPExistingBrowser extends BrowserWebsocketRoute {
17
+ auth = true;
18
+ browser = CDPChromium;
19
+ concurrency = false;
20
+ description = `Connect to an already-running Chromium with a library like puppeteer, or others, that work over chrome-devtools-protocol.`;
21
+ path = WebsocketRoutes.browser;
22
+ tags = [APITags.browserWS];
23
+ handler = async (
22
24
  req: Request,
23
25
  socket: Duplex,
24
26
  head: Buffer,
25
27
  chrome: CDPChromium,
26
- ): Promise<void> => chrome.proxyWebSocket(req, socket, head),
27
- path: WebsocketRoutes.browser,
28
- tags: [APITags.browserWS],
29
- };
30
-
31
- export default route;
28
+ ): Promise<void> => chrome.proxyWebSocket(req, socket, head);
29
+ }
@@ -13,19 +13,17 @@ export interface QuerySchema extends SystemQueryParameters {
13
13
  launch?: CDPLaunchOptions | string;
14
14
  }
15
15
 
16
- const route: BrowserWebsocketRoute = {
17
- auth: true,
18
- browser: CDPChromium,
19
- concurrency: true,
20
- description: `Launch and connect to Chromium with a library like puppeteer or others that work over chrome-devtools-protocol.`,
21
- handler: async (
16
+ export default class CDPChromiumRoute extends BrowserWebsocketRoute {
17
+ auth = true;
18
+ browser = CDPChromium;
19
+ concurrency = true;
20
+ description = `Launch and connect to Chromium with a library like puppeteer or others that work over chrome-devtools-protocol.`;
21
+ path = WebsocketRoutes['/'];
22
+ tags = [APITags.browserWS];
23
+ handler = async (
22
24
  req: Request,
23
25
  socket: Duplex,
24
26
  head: Buffer,
25
27
  chrome: CDPChromium,
26
- ): Promise<void> => chrome.proxyWebSocket(req, socket, head),
27
- path: WebsocketRoutes['/'],
28
- tags: [APITags.browserWS],
29
- };
30
-
31
- export default route;
28
+ ): Promise<void> => chrome.proxyWebSocket(req, socket, head);
29
+ }
@@ -13,19 +13,17 @@ export interface QuerySchema extends SystemQueryParameters {
13
13
  launch?: CDPLaunchOptions | string;
14
14
  }
15
15
 
16
- const route: BrowserWebsocketRoute = {
17
- auth: true,
18
- browser: CDPChromium,
19
- concurrency: false,
20
- description: `Connect to Chromium with a library like chrome-remote-interface or others that work over JSON chrome-devtools-protocol.`,
21
- handler: async (
16
+ export default class PageWebSocketRoute extends BrowserWebsocketRoute {
17
+ auth = true;
18
+ browser = CDPChromium;
19
+ concurrency = false;
20
+ description = `Connect to Chromium with a library like chrome-remote-interface or others that work over JSON chrome-devtools-protocol.`;
21
+ path = WebsocketRoutes.page;
22
+ tags = [APITags.browserWS];
23
+ handler = async (
22
24
  req: Request,
23
25
  socket: Duplex,
24
26
  head: Buffer,
25
27
  chrome: CDPChromium,
26
- ): Promise<void> => chrome.proxyPageWebSocket(req, socket, head),
27
- path: WebsocketRoutes.page,
28
- tags: [APITags.browserWS],
29
- };
30
-
31
- export default route;
28
+ ): Promise<void> => chrome.proxyPageWebSocket(req, socket, head);
29
+ }
@@ -14,12 +14,14 @@ export interface QuerySchema extends SystemQueryParameters {
14
14
  launch?: BrowserServerOptions | string;
15
15
  }
16
16
 
17
- const route: BrowserWebsocketRoute = {
18
- auth: true,
19
- browser: PlaywrightChromium,
20
- concurrency: true,
21
- description: `Connect to Chromium with any playwright-compliant library.`,
22
- handler: async (
17
+ export default class PlaywrightChromiumRoute extends BrowserWebsocketRoute {
18
+ auth = true;
19
+ browser = PlaywrightChromium;
20
+ concurrency = true;
21
+ description = `Connect to Chromium with any playwright style library.`;
22
+ path = WebsocketRoutes.playwrightChromium;
23
+ tags = [APITags.browserWS];
24
+ handler = async (
23
25
  req: Request,
24
26
  socket: Duplex,
25
27
  head: Buffer,
@@ -36,9 +38,5 @@ const route: BrowserWebsocketRoute = {
36
38
  }
37
39
 
38
40
  return browser.proxyWebSocket(req, socket, head);
39
- },
40
- path: WebsocketRoutes.playwrightChromium,
41
- tags: [APITags.browserWS],
42
- };
43
-
44
- export default route;
41
+ };
42
+ }
@@ -14,12 +14,14 @@ export interface QuerySchema extends SystemQueryParameters {
14
14
  launch?: BrowserServerOptions | string;
15
15
  }
16
16
 
17
- const route: BrowserWebsocketRoute = {
18
- auth: true,
19
- browser: PlaywrightFirefox,
20
- concurrency: true,
21
- description: `Connect to Firefox with any playwright-compliant library.`,
22
- handler: async (
17
+ export default class PlayWrightFirefoxRoute extends BrowserWebsocketRoute {
18
+ auth = true;
19
+ browser = PlaywrightFirefox;
20
+ concurrency = true;
21
+ description = `Connect to Firefox with any playwright-compliant library.`;
22
+ path = WebsocketRoutes.playwrightFirefox;
23
+ tags = [APITags.browserWS];
24
+ handler = async (
23
25
  req: Request,
24
26
  socket: Duplex,
25
27
  head: Buffer,
@@ -36,9 +38,5 @@ const route: BrowserWebsocketRoute = {
36
38
  }
37
39
 
38
40
  return browser.proxyWebSocket(req, socket, head);
39
- },
40
- path: WebsocketRoutes.playwrightFirefox,
41
- tags: [APITags.browserWS],
42
- };
43
-
44
- export default route;
41
+ };
42
+ }
@@ -4,7 +4,6 @@ import {
4
4
  HTTPRoute,
5
5
  Methods,
6
6
  Request,
7
- ServerError,
8
7
  contentTypes,
9
8
  jsonResponse,
10
9
  } from '@browserless.io/browserless';
@@ -33,21 +32,18 @@ export interface ResponseSchema {
33
32
  token: string | null;
34
33
  }
35
34
 
36
- const route: HTTPRoute = {
37
- accepts: [contentTypes.any],
38
- auth: true,
39
- browser: null,
40
- concurrency: false,
41
- contentTypes: [contentTypes.json],
42
- description: `Returns a JSON payload of the current system configuration.`,
43
- handler: async (_req: Request, res: ServerResponse): Promise<void> => {
44
- const { getConfig: getConfig } = route;
45
-
46
- if (!getConfig) {
47
- throw new ServerError(`Couldn't locate the config object`);
48
- }
49
-
50
- const config = getConfig();
35
+ export default class ConfigGetRoute extends HTTPRoute {
36
+ accepts = [contentTypes.any];
37
+ auth = true;
38
+ browser = null;
39
+ concurrency = false;
40
+ contentTypes = [contentTypes.json];
41
+ description = `Returns a JSON payload of the current system configuration.`;
42
+ method = Methods.get;
43
+ path = HTTPManagementRoutes.config;
44
+ tags = [APITags.management];
45
+ handler = async (_req: Request, res: ServerResponse): Promise<void> => {
46
+ const config = this.config();
51
47
 
52
48
  const response: ResponseSchema = {
53
49
  allowCORS: config.getAllowCORS(),
@@ -73,10 +69,5 @@ const route: HTTPRoute = {
73
69
  };
74
70
 
75
71
  return jsonResponse(res, 200, response);
76
- },
77
- method: Methods.get,
78
- path: HTTPManagementRoutes.config,
79
- tags: [APITags.management],
80
- };
81
-
82
- export default route;
72
+ };
73
+ }
@@ -5,7 +5,6 @@ import {
5
5
  IBrowserlessStats,
6
6
  Methods,
7
7
  Request,
8
- ServerError,
9
8
  contentTypes,
10
9
  writeResponse,
11
10
  } from '@browserless.io/browserless';
@@ -13,31 +12,23 @@ import { ServerResponse } from 'http';
13
12
 
14
13
  export type ResponseSchema = Array<IBrowserlessStats>;
15
14
 
16
- const route: HTTPRoute = {
17
- accepts: [contentTypes.any],
18
- auth: true,
19
- browser: null,
20
- concurrency: false,
21
- contentTypes: [contentTypes.json],
22
- description: `Gets total metric details from the time the server started.`,
23
- handler: async (_req: Request, res: ServerResponse): Promise<void> => {
24
- const { getFileSystem: _fileSystem, getConfig: _config } = route;
25
-
26
- if (!_fileSystem || !_config) {
27
- throw new ServerError(`Couldn't locate the file-system or config module`);
28
- }
29
-
30
- const fileSystem = _fileSystem();
31
- const config = _config();
15
+ export default class MetricsGetRoute extends HTTPRoute {
16
+ accepts = [contentTypes.any];
17
+ auth = true;
18
+ browser = null;
19
+ concurrency = false;
20
+ contentTypes = [contentTypes.json];
21
+ description = `Gets total metric details from the time the server started.`;
22
+ method = Methods.get;
23
+ path = HTTPManagementRoutes.metrics;
24
+ tags = [APITags.management];
25
+ handler = async (_req: Request, res: ServerResponse): Promise<void> => {
26
+ const fileSystem = this.fileSystem();
27
+ const config = this.config();
32
28
 
33
29
  const stats = await fileSystem.read(config.getMetricsJSONPath());
34
30
  const response = `[${stats.join(',')}]`;
35
31
 
36
32
  return writeResponse(res, 200, response, contentTypes.json);
37
- },
38
- method: Methods.get,
39
- path: HTTPManagementRoutes.metrics,
40
- tags: [APITags.management],
41
- };
42
-
43
- export default route;
33
+ };
34
+ }
@@ -5,7 +5,6 @@ import {
5
5
  IBrowserlessMetricTotals,
6
6
  Methods,
7
7
  Request,
8
- ServerError,
9
8
  contentTypes,
10
9
  writeResponse,
11
10
  } from '@browserless.io/browserless';
@@ -15,28 +14,23 @@ export type ResponseSchema = IBrowserlessMetricTotals;
15
14
 
16
15
  const fiveMinuteIntervalsInAMonth = 8640;
17
16
 
18
- const route: HTTPRoute = {
19
- accepts: [contentTypes.any],
20
- auth: true,
21
- browser: null,
22
- concurrency: false,
23
- contentTypes: [contentTypes.json],
24
- description: `Gets total metric details summed from the time the server started.`,
25
- handler: async (_req: Request, res: ServerResponse): Promise<void> => {
26
- const { getFileSystem: _fileSystem, getConfig: _config } = route;
27
-
28
- if (!_fileSystem || !_config) {
29
- throw new ServerError(`Couldn't locate the file-system or config module`);
30
- }
31
-
32
- const fileSystem = _fileSystem();
33
- const config = _config();
34
-
17
+ export default class MetricsTotalGetRoute extends HTTPRoute {
18
+ accepts = [contentTypes.any];
19
+ auth = true;
20
+ browser = null;
21
+ concurrency = false;
22
+ contentTypes = [contentTypes.json];
23
+ description = `Gets total metric details summed from the time the server started.`;
24
+ method = Methods.get;
25
+ path = HTTPManagementRoutes.metricsTotal;
26
+ tags = [APITags.management];
27
+ handler = async (_req: Request, res: ServerResponse): Promise<void> => {
28
+ const fileSystem = this.fileSystem();
29
+ const config = this.config();
35
30
  const metrics = (await fileSystem.read(config.getMetricsJSONPath())).map(
36
31
  (m) => JSON.parse(m),
37
32
  );
38
33
  const availableMetrics = metrics.length;
39
-
40
34
  const totals: IBrowserlessMetricTotals = metrics.reduce(
41
35
  (accum, metric) => ({
42
36
  error: accum.error + metric.error,
@@ -80,10 +74,5 @@ const route: HTTPRoute = {
80
74
  );
81
75
 
82
76
  return writeResponse(res, 200, JSON.stringify(totals), contentTypes.json);
83
- },
84
- method: Methods.get,
85
- path: HTTPManagementRoutes.metricsTotal,
86
- tags: [APITags.management],
87
- };
88
-
89
- export default route;
77
+ };
78
+ }
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  APITags,
3
- BadRequest,
4
3
  BrowserlessSessionJSON,
5
4
  HTTPManagementRoutes,
6
5
  HTTPRoute,
@@ -13,27 +12,20 @@ import { ServerResponse } from 'http';
13
12
 
14
13
  export type ResponseSchema = BrowserlessSessionJSON[];
15
14
 
16
- const route: HTTPRoute = {
17
- accepts: [contentTypes.any],
18
- auth: true,
19
- browser: null,
20
- concurrency: false,
21
- contentTypes: [contentTypes.json],
22
- description: `Lists all currently running sessions and relevant meta-data excluding potentially open pages.`,
23
- handler: async (_req: Request, res: ServerResponse): Promise<void> => {
24
- const { getBrowserManager: browserManager } = route;
25
-
26
- if (!browserManager) {
27
- throw new BadRequest(`Couldn't load browsers running`);
28
- }
29
-
30
- const response: ResponseSchema = await browserManager().getAllSessions();
15
+ export default class SessionsGetRoute extends HTTPRoute {
16
+ accepts = [contentTypes.any];
17
+ auth = true;
18
+ browser = null;
19
+ concurrency = false;
20
+ contentTypes = [contentTypes.json];
21
+ description = `Lists all currently running sessions and relevant meta-data excluding potentially open pages.`;
22
+ method = Methods.get;
23
+ path = HTTPManagementRoutes.sessions;
24
+ tags = [APITags.management];
25
+ handler = async (_req: Request, res: ServerResponse): Promise<void> => {
26
+ const browserManager = this.browserManager();
27
+ const response: ResponseSchema = await browserManager.getAllSessions();
31
28
 
32
29
  return jsonResponse(res, 200, response);
33
- },
34
- method: Methods.get,
35
- path: HTTPManagementRoutes.sessions,
36
- tags: [APITags.management],
37
- };
38
-
39
- export default route;
30
+ };
31
+ }
@@ -5,7 +5,6 @@ import {
5
5
  Methods,
6
6
  NotFound,
7
7
  Request,
8
- ServerError,
9
8
  contentTypes,
10
9
  createLogger,
11
10
  fileExists,
@@ -47,15 +46,17 @@ const streamFile = (res: ServerResponse, file: string, contentType?: string) =>
47
46
  .pipe(res);
48
47
  });
49
48
 
50
- const route: HTTPRoute = {
51
- accepts: [contentTypes.any],
52
- auth: false,
53
- browser: null,
54
- concurrency: false,
55
- contentTypes: [contentTypes.any],
56
- description: `Serves static files inside of this "static" directory. Content-types will vary depending on the type of file being returned.`,
57
- handler: async (req: Request, res: ServerResponse): Promise<unknown> => {
58
- const { getConfig: getConfig } = route;
49
+ export default class StaticGetRoute extends HTTPRoute {
50
+ accepts = [contentTypes.any];
51
+ auth = false;
52
+ browser = null;
53
+ concurrency = false;
54
+ contentTypes = [contentTypes.any];
55
+ description = `Serves static files inside of this "static" directory. Content-types will vary depending on the type =of file being returned.`;
56
+ method = Methods.get;
57
+ path = HTTPManagementRoutes.static;
58
+ tags = [APITags.management];
59
+ handler = async (req: Request, res: ServerResponse): Promise<unknown> => {
59
60
  const { pathname } = req.parsed;
60
61
  const fileCache = pathMap.get(pathname);
61
62
 
@@ -63,11 +64,7 @@ const route: HTTPRoute = {
63
64
  return streamFile(res, fileCache.path, fileCache.contentType);
64
65
  }
65
66
 
66
- if (!getConfig) {
67
- throw new ServerError(`Couldn't load configuration for request`);
68
- }
69
-
70
- const config = getConfig();
67
+ const config = this.config();
71
68
  const file = path.join(config.getStatic(), pathname);
72
69
  const indexFile = path.join(file, 'index.html');
73
70
 
@@ -100,10 +97,5 @@ const route: HTTPRoute = {
100
97
  });
101
98
 
102
99
  return streamFile(res, filePath, contentType);
103
- },
104
- method: Methods.get,
105
- path: HTTPManagementRoutes.static,
106
- tags: [APITags.management],
107
- };
108
-
109
- export default route;
100
+ };
101
+ }
@@ -14,12 +14,14 @@ export interface QuerySchema extends SystemQueryParameters {
14
14
  launch?: BrowserServerOptions | string;
15
15
  }
16
16
 
17
- const route: BrowserWebsocketRoute = {
18
- auth: true,
19
- browser: PlaywrightWebkit,
20
- concurrency: true,
21
- description: `Connect to Webkit with any playwright-compliant library.`,
22
- handler: async (
17
+ export default class PlaywrightWebkitRoute extends BrowserWebsocketRoute {
18
+ auth = true;
19
+ browser = PlaywrightWebkit;
20
+ concurrency = true;
21
+ description = `Connect to Webkit with any playwright-compliant library.`;
22
+ path = WebsocketRoutes.playwrightWebkit;
23
+ tags = [APITags.browserWS];
24
+ handler = async (
23
25
  req: Request,
24
26
  socket: Duplex,
25
27
  head: Buffer,
@@ -36,9 +38,5 @@ const route: BrowserWebsocketRoute = {
36
38
  }
37
39
 
38
40
  return browser.proxyWebSocket(req, socket, head);
39
- },
40
- path: WebsocketRoutes.playwrightWebkit,
41
- tags: [APITags.browserWS],
42
- };
43
-
44
- export default route;
41
+ };
42
+ }
package/src/server.ts CHANGED
@@ -298,7 +298,6 @@ export class HTTPServer {
298
298
  return writeResponse(res, 408, e.message);
299
299
  }
300
300
 
301
- this.log(`Error handling request at "${route.path}": ${e}`);
302
301
  return writeResponse(res, 500, e.toString());
303
302
  });
304
303
  };