@browserless.io/browserless 2.7.1 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/CHANGELOG.md +19 -1
  2. package/README.md +41 -3
  3. package/assets/debugger.png +0 -0
  4. package/bin/browserless.js +8 -4
  5. package/bin/scaffold/README.md +6 -4
  6. package/bin/scaffold/src/hello-world.http.ts +7 -1
  7. package/build/browserless.d.ts +8 -5
  8. package/build/browserless.js +23 -22
  9. package/build/browsers/chrome.cdp.d.ts +2 -2
  10. package/build/browsers/chrome.cdp.js +2 -2
  11. package/build/browsers/chrome.playwright.d.ts +2 -2
  12. package/build/browsers/chrome.playwright.js +2 -2
  13. package/build/browsers/chromium.cdp.d.ts +4 -4
  14. package/build/browsers/chromium.cdp.js +49 -32
  15. package/build/browsers/chromium.playwright.d.ts +4 -4
  16. package/build/browsers/chromium.playwright.js +14 -13
  17. package/build/browsers/firefox.playwright.d.ts +4 -4
  18. package/build/browsers/firefox.playwright.js +14 -13
  19. package/build/browsers/index.d.ts +24 -8
  20. package/build/browsers/index.js +20 -15
  21. package/build/browsers/webkit.playwright.d.ts +4 -4
  22. package/build/browsers/webkit.playwright.js +14 -13
  23. package/build/config.d.ts +3 -0
  24. package/build/config.js +3 -0
  25. package/build/exports.d.ts +1 -0
  26. package/build/exports.js +1 -0
  27. package/build/file-system.d.ts +2 -3
  28. package/build/file-system.js +2 -2
  29. package/build/index.js +7 -7
  30. package/build/limiter.d.ts +2 -3
  31. package/build/limiter.js +11 -11
  32. package/build/logger.d.ts +19 -0
  33. package/build/logger.js +43 -0
  34. package/build/monitoring.d.ts +2 -3
  35. package/build/monitoring.js +4 -4
  36. package/build/router.d.ts +4 -5
  37. package/build/router.js +31 -28
  38. package/build/routes/chrome/http/content.post.body.json +8 -8
  39. package/build/routes/chrome/http/pdf.post.body.json +9 -9
  40. package/build/routes/chrome/http/scrape.post.body.json +8 -8
  41. package/build/routes/chrome/http/screenshot.post.body.json +8 -8
  42. package/build/routes/chromium/http/content.post.body.json +8 -8
  43. package/build/routes/chromium/http/pdf.post.body.json +9 -9
  44. package/build/routes/chromium/http/scrape.post.body.json +8 -8
  45. package/build/routes/chromium/http/screenshot.post.body.json +8 -8
  46. package/build/routes/firefox/ws/playwright.d.ts +2 -2
  47. package/build/routes/firefox/ws/playwright.js +1 -1
  48. package/build/routes/management/http/static.get.d.ts +2 -2
  49. package/build/routes/management/http/static.get.js +8 -10
  50. package/build/routes/management/tests/management.spec.js +9 -0
  51. package/build/routes/webkit/ws/playwright.d.ts +2 -2
  52. package/build/routes/webkit/ws/playwright.js +1 -1
  53. package/build/sdk-utils.js +23 -10
  54. package/build/server.d.ts +4 -5
  55. package/build/server.js +38 -33
  56. package/build/shared/browser.ws.d.ts +2 -2
  57. package/build/shared/browser.ws.js +1 -1
  58. package/build/shared/chromium.playwright.ws.d.ts +2 -2
  59. package/build/shared/chromium.playwright.ws.js +1 -1
  60. package/build/shared/chromium.ws.d.ts +2 -2
  61. package/build/shared/chromium.ws.js +1 -1
  62. package/build/shared/content.http.d.ts +2 -2
  63. package/build/shared/content.http.js +4 -1
  64. package/build/shared/download.http.d.ts +2 -2
  65. package/build/shared/download.http.js +11 -12
  66. package/build/shared/function.http.d.ts +2 -2
  67. package/build/shared/function.http.js +4 -5
  68. package/build/shared/json-protocol.http.d.ts +3 -3
  69. package/build/shared/json-protocol.http.js +2 -2
  70. package/build/shared/json-version.http.d.ts +3 -3
  71. package/build/shared/json-version.http.js +2 -2
  72. package/build/shared/page.ws.d.ts +2 -2
  73. package/build/shared/page.ws.js +1 -1
  74. package/build/shared/pdf.http.d.ts +2 -2
  75. package/build/shared/pdf.http.js +6 -4
  76. package/build/shared/performance.http.d.ts +2 -2
  77. package/build/shared/performance.http.js +2 -1
  78. package/build/shared/scrape.http.d.ts +2 -2
  79. package/build/shared/scrape.http.js +4 -1
  80. package/build/shared/screenshot.http.d.ts +2 -2
  81. package/build/shared/screenshot.http.js +4 -1
  82. package/build/shared/utils/function/handler.d.ts +2 -3
  83. package/build/shared/utils/function/handler.js +8 -8
  84. package/build/shared/utils/performance/child.js +4 -4
  85. package/build/shared/utils/performance/main.d.ts +1 -1
  86. package/build/shared/utils/performance/main.js +5 -7
  87. package/build/shared/utils/performance/types.d.ts +2 -1
  88. package/build/types.d.ts +6 -15
  89. package/build/types.js +1 -10
  90. package/build/utils.d.ts +1 -1
  91. package/build/utils.js +6 -2
  92. package/package.json +18 -15
  93. package/scripts/install-debugger.js +55 -15
  94. package/src/browserless.ts +29 -21
  95. package/src/browsers/chrome.cdp.ts +2 -5
  96. package/src/browsers/chrome.playwright.ts +2 -5
  97. package/src/browsers/chromium.cdp.ts +84 -35
  98. package/src/browsers/chromium.playwright.ts +26 -13
  99. package/src/browsers/firefox.playwright.ts +28 -13
  100. package/src/browsers/index.ts +24 -16
  101. package/src/browsers/webkit.playwright.ts +28 -13
  102. package/src/config.ts +4 -0
  103. package/src/exports.ts +1 -0
  104. package/src/file-system.ts +2 -7
  105. package/src/index.ts +7 -7
  106. package/src/limiter.ts +13 -11
  107. package/src/logger.ts +52 -0
  108. package/src/monitoring.ts +6 -8
  109. package/src/router.ts +29 -27
  110. package/src/routes/firefox/ws/playwright.ts +2 -0
  111. package/src/routes/management/http/static.get.ts +13 -10
  112. package/src/routes/management/tests/management.spec.ts +15 -0
  113. package/src/routes/webkit/ws/playwright.ts +2 -0
  114. package/src/sdk-utils.ts +20 -2
  115. package/src/server.ts +47 -32
  116. package/src/shared/browser.ws.ts +2 -0
  117. package/src/shared/chromium.playwright.ws.ts +2 -0
  118. package/src/shared/chromium.ws.ts +2 -0
  119. package/src/shared/content.http.ts +6 -0
  120. package/src/shared/download.http.ts +14 -11
  121. package/src/shared/function.http.ts +5 -4
  122. package/src/shared/json-protocol.http.ts +8 -3
  123. package/src/shared/json-version.http.ts +8 -4
  124. package/src/shared/page.ws.ts +2 -0
  125. package/src/shared/pdf.http.ts +7 -3
  126. package/src/shared/performance.http.ts +3 -0
  127. package/src/shared/scrape.http.ts +6 -0
  128. package/src/shared/screenshot.http.ts +5 -0
  129. package/src/shared/utils/function/handler.ts +9 -13
  130. package/src/shared/utils/performance/child.ts +4 -4
  131. package/src/shared/utils/performance/main.ts +5 -6
  132. package/src/shared/utils/performance/types.ts +2 -1
  133. package/src/types.ts +5 -9
  134. package/src/utils.ts +7 -2
  135. package/static/docs/swagger.json +11 -11
  136. package/static/docs/swagger.min.json +10 -10
  137. package/static/function/client.js +1656 -2916
  138. package/static/function/index.html +1656 -2916
package/CHANGELOG.md CHANGED
@@ -1,4 +1,22 @@
1
- # [Latest](https://github.com/browserless/chrome/compare/v2.7.1...main)
1
+ # [Latest](https://github.com/browserless/chrome/compare/v2.9.0...main)
2
+ - Dependency updates.
3
+
4
+ # [v2.9.0](https://github.com/browserless/chrome/compare/v2.8.0...v2.9.0)
5
+ - Dependency updates.
6
+ - Debugger is now included and mounted under the `/debugger` path.
7
+ - Browserless now uses the `Logger` utility internally. Better logs for certain classes as well.
8
+ - Fix number of connected clients when using the Page websocket route.
9
+ - Allows "HEAD" requests for most "GET"-based APIs.
10
+ -
11
+
12
+ # [v2.8.0](https://github.com/browserless/chrome/compare/v2.7.1...v2.8.0)
13
+ **April 12, 2024**
14
+ **Potentially Breaking**
15
+ - New `Logger` class and SDK primitives in support of that.
16
+ - Routes now get an instance of `Logger`, before the `browser` argument or as the last argument for HTTP routes.
17
+
18
+ **Updates**
19
+ - Numerous SDK fixes and updates in the CLI.
2
20
  - Dependency updates.
3
21
 
4
22
  # [v2.7.1](https://github.com/browserless/chrome/compare/v2.7.0...v2.7.1)
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- <!-- markdownlint-disable first-line-h1 no-emphasis-as-heading -->
1
+ <!-- markdownlint-disable commands-show-output first-line-h1 no-emphasis-as-heading -->
2
2
 
3
3
  ![browserless.io logo](/assets/logo.png)
4
4
 
@@ -28,6 +28,8 @@ If you've been struggling to deploy headless browsers without running into issue
28
28
  - [Puppeteer](#puppeteer)
29
29
  - [Playwright](#playwright)
30
30
  - [Extending (NodeJS SDK)](#extending-nodejs-sdk)
31
+ - [Debugger](#debugger)
32
+ - [Install debugger](#install-debugger)
31
33
  - [Usage with other libraries](#usage-with-other-libraries)
32
34
  - [Motivations](#motivations)
33
35
  - [Licensing](#licensing)
@@ -70,7 +72,7 @@ You still execute the script itself which gives you total control over what libr
70
72
 
71
73
  ### Docker
72
74
 
73
- > [!TIP]
75
+ > [!TIP]
74
76
  > See more options on our [full documentation site](https://docs.browserless.io/Docker/docker-quickstart).
75
77
 
76
78
  1. `docker run -p 3000:3000 ghcr.io/browserless/chromium`
@@ -107,7 +109,7 @@ const browser = await puppeteer.connect({
107
109
 
108
110
  ### Playwright
109
111
 
110
- We support running with playwright via their their browser's remot connection protocols interface out of the box. Just make sure that your Docker image, playwright browser type _and_ endpoint match:
112
+ We support running with playwright via their their browser's remote connection protocols interface out of the box. Just make sure that your Docker image, playwright browser type _and_ endpoint match:
111
113
 
112
114
  **Before**
113
115
 
@@ -137,6 +139,42 @@ After that, the rest of your code remains the same with no other changes require
137
139
 
138
140
  Browserless comes with built-in extension capabilities, and allows for extending nearly any aspect of the system (for Version 2+). For more details on how to write your own routes, build docker images, and more, [see our SDK README.md](/bin/scaffold/README.md) or simply run "npx @browserless.io/browserless create" in a terminal and follow the onscreen prompts.
139
141
 
142
+ ## Debugger
143
+
144
+ You can install a first-party interactive debugger for Browserless, that makes writing scripts faster and interactive. You can take advantage of things like `debugger;` calls and the page's console output to see what's happening on the page while your script is running. All of the Chrome devtools are there at your disposal.
145
+
146
+ ![browserless.io logo](/assets/debugger.png)
147
+
148
+ A small list of features includes:
149
+
150
+ - Running `debugger;` and `console.log` calls
151
+ - Errors in the script are caught and show up in the console tab
152
+ - DOM inspection, watch network requests, and even see how the page is rendering
153
+ - Exporting you debugging script as a Node project
154
+ - Everything included in Chrome DevTools
155
+
156
+ ### Install debugger
157
+
158
+ Installing the debugger is as simple as running the `install:debugger` script _after_ the project has been built. This way:
159
+
160
+ ```sh
161
+ $ npm run build
162
+ $ npm run install:debugger #or npm install:dev
163
+ ```
164
+
165
+ You will then see the debugger url during the startup process.
166
+
167
+ ```log
168
+ ---------------------------------------------------------
169
+ | browserless.io
170
+ | To read documentation and more, load in your browser:
171
+ |
172
+ | OpenAPI: http://localhost:3000/docs
173
+ | Full Documentation: https://docs.browserless.io/
174
+ | Debbuger: http://localhost:3000/debugger/?token=6R0W53R135510
175
+ ---------------------------------------------------------
176
+ ```
177
+
140
178
  ## Usage with other libraries
141
179
 
142
180
  Most libraries allow you to specify a remote instance of Chrome to interact with. They are either looking for a websocket endpoint, a host and port, or some address. Browserless supports these by default, however if you're having issues please make an issue in this project and we'll try and work with the library authors to get them integrated with browserless. Please note that in V2 we no longer support selenium or webdriver integrations.
Binary file
@@ -27,7 +27,7 @@ if (typeof process.env.DEBUG === 'undefined') {
27
27
  const log = debug('browserless.io:sdk:log');
28
28
 
29
29
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
30
- const cmd = process.argv[2];
30
+ const cmd = process.argv[2] ?? 'help';
31
31
  const subCMD = process.argv[3];
32
32
  const allowedCMDs = [
33
33
  'build',
@@ -143,7 +143,7 @@ const isConstructor = (reference) => typeof reference === 'function';
143
143
  const start = async (dev = false) => {
144
144
  const { httpRoutes, webSocketRoutes, files } = dev
145
145
  ? await build()
146
- : await getSourceFiles();
146
+ : await getSourceFiles(projectDir);
147
147
 
148
148
  log(`Importing all class overrides if present`);
149
149
 
@@ -152,6 +152,7 @@ const start = async (dev = false) => {
152
152
  Config,
153
153
  FileSystem,
154
154
  Limiter,
155
+ Logger,
155
156
  Metrics,
156
157
  Monitoring,
157
158
  Router,
@@ -164,6 +165,7 @@ const start = async (dev = false) => {
164
165
  importDefault(files, 'config'),
165
166
  importDefault(files, 'file-system'),
166
167
  importDefault(files, 'limiter'),
168
+ importDefault(files, 'logger'),
167
169
  importDefault(files, 'metrics'),
168
170
  importDefault(files, 'monitoring'),
169
171
  importDefault(files, 'router'),
@@ -197,6 +199,7 @@ const start = async (dev = false) => {
197
199
  : Router;
198
200
 
199
201
  const browserless = new Browserless({
202
+ Logger,
200
203
  browserManager,
201
204
  config,
202
205
  fileSystem,
@@ -369,7 +372,7 @@ const create = async () => {
369
372
  }
370
373
  }
371
374
 
372
- log(`Installing npm modules...`);
375
+ log(`Installing browsers and npm modules, this might take a few minutes...`);
373
376
  await installDependencies(installPath);
374
377
 
375
378
  log(
@@ -377,7 +380,8 @@ const create = async () => {
377
380
  );
378
381
  };
379
382
 
380
- const help = () => {
383
+ const help = async () => {
384
+ console.log(`Version: ${(await browserlessPackageJSON).version}`);
381
385
  if (subCMD) {
382
386
  if (!allowedCMDs.includes(subCMD)) {
383
387
  throw new Error(`Unknown command of "${subCMD}" passed.`);
@@ -128,6 +128,7 @@ Internally, we use this same class-based system, so feel free to see how those w
128
128
  import {
129
129
  APITags,
130
130
  HTTPRoute,
131
+ Logger,
131
132
  Methods,
132
133
  contentTypes,
133
134
  writeResponse,
@@ -174,7 +175,7 @@ export default class HelloWorldRoute extends HTTPRoute {
174
175
  // Handler is a function, getting the request and response objects, and is where you'll write the
175
176
  // core logic behind this route. Use utilities like writeResponse or writeJSONResponse to help
176
177
  // return the appropriate response.
177
- handler = async (_req, res): Promise<void> => {
178
+ handler = async (_req, res, _logger: Logger): Promise<void> => {
178
179
  const response: ResponseSchema = 'Hello World!';
179
180
  return writeResponse(res, 200, ResponseSchema, contentTypes.text);
180
181
  };
@@ -189,6 +190,7 @@ import {
189
190
  BrowserWebsocketRoute,
190
191
  ChromiumCDP,
191
192
  CDPLaunchOptions,
193
+ Logger,
192
194
  Request,
193
195
  SystemQueryParameters,
194
196
  WebsocketRoutes,
@@ -226,7 +228,7 @@ export default class ChromiumWebSocketRoute extends BrowserWebsocketRoute {
226
228
  // Routes with a browser type get a browser argument of the Browser instance, otherwise
227
229
  // request, socket, and head are the other 3 arguments. Here we pass them through
228
230
  // and proxy the request into Chromium to handle.
229
- handler = async (req, socket, head, chromium): Promise<void> =>
231
+ handler = async (req, socket, head, logger, chromium): Promise<void> =>
230
232
  chromium.proxyWebSocket(req, socket, head);
231
233
  }
232
234
  ```
@@ -293,7 +295,7 @@ Then, later, in your route you can define some functionality and load the config
293
295
 
294
296
  ```ts
295
297
  // src/pdf.http.ts
296
- import { BrowserHTTPRoute } from '@browserless.io/browserless';
298
+ import { BrowserHTTPRoute, Logger } from '@browserless.io/browserless';
297
299
  import MyConfig from './config';
298
300
 
299
301
  // Export the BodySchema for documentation site to parse, plus
@@ -342,7 +344,7 @@ export default class PDFToS3Route extends BrowserHTTPRoute {
342
344
  tags = [APITags.browserAPI];
343
345
 
344
346
  // Handler's are where we embed the logic that facilitates this route.
345
- handler = async (req, res, browser): Promise<void> => {
347
+ handler = async (req, res, logger, browser): Promise<void> => {
346
348
  // Modules like Config are injected via this internal methods.
347
349
  // Use them to load core modules within the platform.
348
350
  const config = this.config() as MyConfig;
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  APITags,
3
3
  HTTPRoute,
4
+ Logger,
4
5
  Methods,
5
6
  Request,
6
7
  Response,
@@ -21,7 +22,12 @@ export default class HelloWorldHTTPRoute extends HTTPRoute {
21
22
  method = Methods.get;
22
23
  path = '/hello';
23
24
  tags = [APITags.management];
24
- handler = async (_req: Request, res: Response): Promise<void> => {
25
+ handler = async (
26
+ req: Request,
27
+ res: Response,
28
+ logger: Logger,
29
+ ): Promise<void> => {
30
+ logger.verbose(`${req.method} /hello was called!`);
25
31
  const response: ResponseSchema = 'Hello World!';
26
32
  return writeResponse(res, 200, response, contentTypes.text);
27
33
  };
@@ -1,15 +1,16 @@
1
- /// <reference types="debug" />
2
1
  /// <reference types="node" />
3
2
  /// <reference types="node" />
4
- import { BrowserManager, Config, FileSystem, HTTPServer, Hooks, Limiter, Metrics, Monitoring, Router, Token, WebHooks } from '@browserless.io/browserless';
3
+ import { Logger as BlessLogger, BrowserHTTPRoute, BrowserManager, BrowserWebsocketRoute, Config, FileSystem, HTTPRoute, HTTPServer, Hooks, Limiter, Metrics, Monitoring, Router, Token, WebHooks, WebSocketRoute } from '@browserless.io/browserless';
5
4
  import { EventEmitter } from 'events';
5
+ type routeInstances = HTTPRoute | BrowserHTTPRoute | WebSocketRoute | BrowserWebsocketRoute;
6
6
  export declare class Browserless extends EventEmitter {
7
- protected debug: debug.Debugger;
7
+ protected logger: BlessLogger;
8
8
  protected browserManager: BrowserManager;
9
9
  protected config: Config;
10
10
  protected fileSystem: FileSystem;
11
11
  protected hooks: Hooks;
12
12
  protected limiter: Limiter;
13
+ protected Logger: typeof BlessLogger;
13
14
  protected metrics: Metrics;
14
15
  protected monitoring: Monitoring;
15
16
  protected router: Router;
@@ -22,7 +23,8 @@ export declare class Browserless extends EventEmitter {
22
23
  server?: HTTPServer;
23
24
  metricsSaveInterval: number;
24
25
  metricsSaveIntervalID?: NodeJS.Timer;
25
- constructor({ browserManager, config, fileSystem, hooks, limiter, metrics, monitoring, router, token, webhooks, }?: {
26
+ constructor({ browserManager, config, fileSystem, hooks, limiter, Logger: LoggerOverride, metrics, monitoring, router, token, webhooks, }?: {
27
+ Logger?: Browserless['Logger'];
26
28
  browserManager?: Browserless['browserManager'];
27
29
  config?: Browserless['config'];
28
30
  fileSystem?: Browserless['fileSystem'];
@@ -36,7 +38,7 @@ export declare class Browserless extends EventEmitter {
36
38
  });
37
39
  protected saveMetrics: () => Promise<void>;
38
40
  setMetricsSaveInterval: (interval: number) => void;
39
- private routeIsDisabled;
41
+ protected routeIsDisabled(route: routeInstances): boolean;
40
42
  setStaticSDKDir(dir: string): void;
41
43
  disableRoutes(...routeNames: string[]): void;
42
44
  addHTTPRoute(httpRouteFilePath: string): void;
@@ -45,3 +47,4 @@ export declare class Browserless extends EventEmitter {
45
47
  stop(): Promise<[void | undefined, void, void, void, void, void, void, void, void, void, void]>;
46
48
  start(): Promise<void>;
47
49
  }
50
+ export {};
@@ -1,16 +1,17 @@
1
1
  import * as path from 'path';
2
- import { BrowserManager, ChromeCDP, ChromiumCDP, ChromiumPlaywright, Config, FileSystem, FirefoxPlaywright, HTTPServer, Hooks, Limiter, Metrics, Monitoring, Router, Token, WebHooks, WebkitPlaywright, availableBrowsers, createLogger, getRouteFiles, makeExternalURL, printLogo, safeParse, } from '@browserless.io/browserless';
2
+ import { Logger as BlessLogger, BrowserManager, ChromeCDP, ChromiumCDP, ChromiumPlaywright, Config, FileSystem, FirefoxPlaywright, HTTPServer, Hooks, Limiter, Metrics, Monitoring, Router, Token, WebHooks, WebkitPlaywright, availableBrowsers, getRouteFiles, makeExternalURL, printLogo, safeParse, } from '@browserless.io/browserless';
3
3
  import { EventEmitter } from 'events';
4
4
  import { readFile } from 'fs/promises';
5
5
  import { userInfo } from 'os';
6
6
  const routeSchemas = ['body', 'query'];
7
7
  export class Browserless extends EventEmitter {
8
- debug = createLogger('index');
8
+ logger;
9
9
  browserManager;
10
10
  config;
11
11
  fileSystem;
12
12
  hooks;
13
13
  limiter;
14
+ Logger;
14
15
  metrics;
15
16
  monitoring;
16
17
  router;
@@ -23,8 +24,10 @@ export class Browserless extends EventEmitter {
23
24
  server;
24
25
  metricsSaveInterval = 5 * 60 * 1000;
25
26
  metricsSaveIntervalID;
26
- constructor({ browserManager, config, fileSystem, hooks, limiter, metrics, monitoring, router, token, webhooks, } = {}) {
27
+ constructor({ browserManager, config, fileSystem, hooks, limiter, Logger: LoggerOverride, metrics, monitoring, router, token, webhooks, } = {}) {
27
28
  super();
29
+ this.Logger = LoggerOverride ?? BlessLogger;
30
+ this.logger = new this.Logger('index');
28
31
  this.config = config || new Config();
29
32
  this.metrics = metrics || new Metrics();
30
33
  this.token = token || new Token(this.config);
@@ -38,7 +41,8 @@ export class Browserless extends EventEmitter {
38
41
  limiter ||
39
42
  new Limiter(this.config, this.metrics, this.monitoring, this.webhooks, this.hooks);
40
43
  this.router =
41
- router || new Router(this.config, this.browserManager, this.limiter);
44
+ router ||
45
+ new Router(this.config, this.browserManager, this.limiter, this.Logger);
42
46
  }
43
47
  saveMetrics = async () => {
44
48
  const metricsPath = this.config.getMetricsJSONPath();
@@ -50,7 +54,7 @@ export class Browserless extends EventEmitter {
50
54
  memory,
51
55
  };
52
56
  this.metrics.reset();
53
- this.debug(`Current period usage: ${JSON.stringify({
57
+ this.logger.info(`Current period usage: ${JSON.stringify({
54
58
  date: aggregatedStats.date,
55
59
  error: aggregatedStats.error,
56
60
  maxConcurrent: aggregatedStats.maxConcurrent,
@@ -64,7 +68,7 @@ export class Browserless extends EventEmitter {
64
68
  units: aggregatedStats.units,
65
69
  })}`);
66
70
  if (metricsPath) {
67
- this.debug(`Saving metrics to "${metricsPath}"`);
71
+ this.logger.info(`Saving metrics to "${metricsPath}"`);
68
72
  this.fileSystem.append(metricsPath, JSON.stringify(aggregatedStats), false);
69
73
  }
70
74
  };
@@ -124,25 +128,26 @@ export class Browserless extends EventEmitter {
124
128
  WebkitPlaywright,
125
129
  ];
126
130
  const [[internalHttpRouteFiles, internalWsRouteFiles], installedBrowsers] = await Promise.all([getRouteFiles(this.config), availableBrowsers]);
131
+ const hasDebugger = await this.config.hasDebugger();
132
+ const debuggerURL = hasDebugger &&
133
+ makeExternalURL(this.config.getExternalAddress(), `/debugger/?token=${this.config.getToken()}`);
127
134
  const docsLink = makeExternalURL(this.config.getExternalAddress(), '/docs');
128
- this.debug(printLogo(docsLink));
129
- this.debug(`Running as user "${userInfo().username}"`);
130
- this.debug('Starting import of HTTP Routes');
135
+ this.logger.info(printLogo(docsLink, debuggerURL));
136
+ this.logger.info(`Running as user "${userInfo().username}"`);
137
+ this.logger.info('Starting import of HTTP Routes');
131
138
  for (const httpRoute of [
132
139
  ...this.httpRouteFiles,
133
140
  ...internalHttpRouteFiles,
134
141
  ]) {
135
142
  if (httpRoute.endsWith('js')) {
136
- const { name } = path.parse(httpRoute);
137
143
  const [bodySchema, querySchema] = await Promise.all(routeSchemas.map(async (schemaType) => {
138
144
  const schemaPath = path.parse(httpRoute);
139
145
  schemaPath.base = `${schemaPath.name}.${schemaType}.json`;
140
146
  return await readFile(path.format(schemaPath), 'utf-8').catch(() => '');
141
147
  }));
142
148
  const routeImport = `${this.config.getIsWin() ? 'file:///' : ''}${httpRoute}`;
143
- const logger = createLogger(`http:${name}`);
144
149
  const { default: Route, } = await import(routeImport + `?cb=${Date.now()}`);
145
- const route = new Route(this.browserManager, this.config, this.fileSystem, logger, this.metrics, this.monitoring, this.staticSDKDir);
150
+ const route = new Route(this.browserManager, this.config, this.fileSystem, this.metrics, this.monitoring, this.staticSDKDir);
146
151
  if (!this.routeIsDisabled(route)) {
147
152
  route.bodySchema = safeParse(bodySchema);
148
153
  route.querySchema = safeParse(querySchema);
@@ -150,35 +155,31 @@ export class Browserless extends EventEmitter {
150
155
  route.metrics = () => this.metrics;
151
156
  route.monitoring = () => this.monitoring;
152
157
  route.fileSystem = () => this.fileSystem;
153
- route.debug = () => logger;
154
158
  route.staticSDKDir = () => this.staticSDKDir;
155
159
  httpRoutes.push(route);
156
160
  }
157
161
  }
158
162
  }
159
- this.debug('Starting import of WebSocket Routes');
163
+ this.logger.info('Starting import of WebSocket Routes');
160
164
  for (const wsRoute of [
161
165
  ...this.webSocketRouteFiles,
162
166
  ...internalWsRouteFiles,
163
167
  ]) {
164
168
  if (wsRoute.endsWith('js')) {
165
- const { name } = path.parse(wsRoute);
166
169
  const [, querySchema] = await Promise.all(routeSchemas.map(async (schemaType) => {
167
170
  const schemaPath = path.parse(wsRoute);
168
171
  schemaPath.base = `${schemaPath.name}.${schemaType}.json`;
169
172
  return await readFile(path.format(schemaPath), 'utf-8').catch(() => '');
170
173
  }));
171
174
  const wsImport = `${this.config.getIsWin() ? 'file:///' : ''}${wsRoute}`;
172
- const logger = createLogger(`ws:${name}`);
173
175
  const { default: Route, } = await import(wsImport + `?cb=${Date.now()}`);
174
- const route = new Route(this.browserManager, this.config, this.fileSystem, logger, this.metrics, this.monitoring, this.staticSDKDir);
176
+ const route = new Route(this.browserManager, this.config, this.fileSystem, this.metrics, this.monitoring, this.staticSDKDir);
175
177
  if (!this.routeIsDisabled(route)) {
176
178
  route.querySchema = safeParse(querySchema);
177
179
  route.config = () => this.config;
178
180
  route.metrics = () => this.metrics;
179
181
  route.monitoring = () => this.monitoring;
180
182
  route.fileSystem = () => this.fileSystem;
181
- route.debug = () => logger;
182
183
  route.staticSDKDir = () => this.staticSDKDir;
183
184
  wsRoutes.push(route);
184
185
  }
@@ -198,14 +199,14 @@ export class Browserless extends EventEmitter {
198
199
  .filter((e, i, a) => a.findIndex((r) => r.name === e.name) !== i)
199
200
  .map((r) => r.name);
200
201
  if (duplicateNamedRoutes.length) {
201
- this.debug(`Found duplicate routing names. Route names must be unique:`, duplicateNamedRoutes);
202
+ this.logger.warn(`Found duplicate routing names. Route names must be unique:`, duplicateNamedRoutes);
202
203
  }
203
204
  httpRoutes.forEach((r) => this.router.registerHTTPRoute(r));
204
205
  wsRoutes.forEach((r) => this.router.registerWebSocketRoute(r));
205
- this.debug(`Imported and validated all route files, starting up server.`);
206
- this.server = new HTTPServer(this.config, this.metrics, this.token, this.router, this.hooks);
206
+ this.logger.info(`Imported and validated all route files, starting up server.`);
207
+ this.server = new HTTPServer(this.config, this.metrics, this.token, this.router, this.hooks, this.Logger);
207
208
  await this.server.start();
208
- this.debug(`Starting metrics collection.`);
209
+ this.logger.info(`Starting metrics collection.`);
209
210
  this.metricsSaveIntervalID = setInterval(() => this.saveMetrics(), this.metricsSaveInterval);
210
211
  }
211
212
  }
@@ -1,6 +1,6 @@
1
- /// <reference types="debug" />
1
+ import { Logger } from '@browserless.io/browserless';
2
2
  import { ChromiumCDP } from './chromium.cdp.js';
3
3
  export declare class ChromeCDP extends ChromiumCDP {
4
4
  protected executablePath: string;
5
- protected debug: import("debug").Debugger;
5
+ protected logger: Logger;
6
6
  }
@@ -1,6 +1,6 @@
1
- import { chromeExecutablePath, createLogger, } from '@browserless.io/browserless';
1
+ import { Logger, chromeExecutablePath } from '@browserless.io/browserless';
2
2
  import { ChromiumCDP } from './chromium.cdp.js';
3
3
  export class ChromeCDP extends ChromiumCDP {
4
4
  executablePath = chromeExecutablePath();
5
- debug = createLogger('browsers:chrome:cdp');
5
+ logger = new Logger('browsers:chrome:cdp');
6
6
  }
@@ -1,6 +1,6 @@
1
- /// <reference types="debug" />
1
+ import { Logger } from '@browserless.io/browserless';
2
2
  import { ChromiumPlaywright } from './chromium.playwright.js';
3
3
  export declare class ChromePlaywright extends ChromiumPlaywright {
4
4
  protected executablePath: string;
5
- protected debug: import("debug").Debugger;
5
+ protected logger: Logger;
6
6
  }
@@ -1,6 +1,6 @@
1
- import { chromeExecutablePath, createLogger, } from '@browserless.io/browserless';
1
+ import { Logger, chromeExecutablePath } from '@browserless.io/browserless';
2
2
  import { ChromiumPlaywright } from './chromium.playwright.js';
3
3
  export class ChromePlaywright extends ChromiumPlaywright {
4
4
  executablePath = chromeExecutablePath();
5
- debug = createLogger('browsers:chrome:playwright');
5
+ logger = new Logger('browsers:chrome:playwright');
6
6
  }
@@ -1,10 +1,9 @@
1
- /// <reference types="debug" />
2
1
  /// <reference types="node" />
3
2
  /// <reference types="node" />
4
3
  /// <reference types="node" />
5
4
  /// <reference types="node" />
6
5
  /// <reference types="node" />
7
- import { CDPLaunchOptions, Config, Request } from '@browserless.io/browserless';
6
+ import { CDPLaunchOptions, Config, Logger, Request } from '@browserless.io/browserless';
8
7
  import { Browser, Page, Target } from 'puppeteer-core';
9
8
  import { Duplex } from 'stream';
10
9
  import { EventEmitter } from 'events';
@@ -17,12 +16,13 @@ export declare class ChromiumCDP extends EventEmitter {
17
16
  protected browser: Browser | null;
18
17
  protected browserWSEndpoint: string | null;
19
18
  protected port?: number;
20
- protected debug: import("debug").Debugger;
19
+ protected logger: Logger;
21
20
  protected proxy: httpProxy<import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>>;
22
21
  protected executablePath: string;
23
- constructor({ blockAds, config, userDataDir, }: {
22
+ constructor({ blockAds, config, userDataDir, logger, }: {
24
23
  blockAds: boolean;
25
24
  config: Config;
25
+ logger: Logger;
26
26
  userDataDir: ChromiumCDP['userDataDir'];
27
27
  });
28
28
  protected cleanListeners(): void;