@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
@@ -7,6 +7,7 @@ import {
7
7
  CDPLaunchOptions,
8
8
  ChromiumCDP,
9
9
  HTTPRoutes,
10
+ Logger,
10
11
  Methods,
11
12
  Request,
12
13
  SystemQueryParameters,
@@ -77,8 +78,10 @@ export default class ChromiumContentPostRoute extends BrowserHTTPRoute {
77
78
  handler = async (
78
79
  req: Request,
79
80
  res: ServerResponse,
81
+ logger: Logger,
80
82
  browser: BrowserInstance,
81
83
  ): Promise<void> => {
84
+ logger.info('Content API invoked with body:', req.body);
82
85
  const contentType =
83
86
  !req.headers.accept || req.headers.accept?.includes('*')
84
87
  ? contentTypes.html
@@ -164,6 +167,7 @@ export default class ChromiumContentPostRoute extends BrowserHTTPRoute {
164
167
  !!rejectRequestPattern.find((pattern) => req.url().match(pattern)) ||
165
168
  rejectResourceTypes.includes(req.resourceType())
166
169
  ) {
170
+ logger.debug(`Aborting request ${req.method()}: ${req.url()}`);
167
171
  return req.abort();
168
172
  }
169
173
  const interceptor = requestInterceptors.find((r) =>
@@ -231,6 +235,8 @@ export default class ChromiumContentPostRoute extends BrowserHTTPRoute {
231
235
 
232
236
  page.close().catch(noop);
233
237
 
238
+ logger.info('Content API request completed');
239
+
234
240
  return writeResponse(res, 200, markup, contentTypes.html);
235
241
  };
236
242
  }
@@ -6,6 +6,7 @@ import {
6
6
  CDPLaunchOptions,
7
7
  ChromiumCDP,
8
8
  HTTPRoutes,
9
+ Logger,
9
10
  Methods,
10
11
  NotFound,
11
12
  Request,
@@ -61,21 +62,21 @@ export default class ChromiumDownloadPostRoute extends BrowserHTTPRoute {
61
62
  handler = async (
62
63
  req: Request,
63
64
  res: ServerResponse,
65
+ logger: Logger,
64
66
  browser: BrowserInstance,
65
67
  ): Promise<void> =>
66
68
  new Promise(async (resolve, reject) => {
67
- const debug = this.debug();
68
69
  const config = this.config();
69
70
  const downloadPath = path.join(
70
71
  await config.getDownloadsDir(),
71
72
  `.browserless.download.${id()}`,
72
73
  );
73
74
 
74
- debug(`Generating a download directory at "${downloadPath}"`);
75
+ logger.info(`Generating a download directory at "${downloadPath}"`);
75
76
  await mkdir(downloadPath);
76
- const handler = functionHandler(config, debug, { downloadPath });
77
+ const handler = functionHandler(config, logger, { downloadPath });
77
78
  const response = await handler(req, browser).catch((e) => {
78
- debug(`Error running download code handler: "${e}"`);
79
+ logger.error(`Error running download code handler: "${e}"`);
79
80
  reject(e);
80
81
  return null;
81
82
  });
@@ -85,10 +86,12 @@ export default class ChromiumDownloadPostRoute extends BrowserHTTPRoute {
85
86
  }
86
87
 
87
88
  const { page } = response;
88
- debug(`Download function has returned, finding downloads...`);
89
+ logger.info(`Download function has returned, finding downloads...`);
89
90
  async function checkIfDownloadComplete(): Promise<string | null> {
90
91
  if (res.headersSent) {
91
- debug(`Request headers have been sent, terminating download watch.`);
92
+ logger.trace(
93
+ `Request headers have been sent, terminating download watch.`,
94
+ );
92
95
  return null;
93
96
  }
94
97
  const [fileName] = await readdir(downloadPath);
@@ -97,13 +100,13 @@ export default class ChromiumDownloadPostRoute extends BrowserHTTPRoute {
97
100
  return checkIfDownloadComplete();
98
101
  }
99
102
 
100
- debug(`All files have finished downloading`);
103
+ logger.info(`All files have finished downloading`);
101
104
 
102
105
  return path.join(downloadPath, fileName);
103
106
  }
104
107
 
105
108
  const filePath = await checkIfDownloadComplete();
106
- debug(`Closing pages.`);
109
+ logger.info(`Closing pages.`);
107
110
  page.close();
108
111
  page.removeAllListeners();
109
112
 
@@ -112,12 +115,12 @@ export default class ChromiumDownloadPostRoute extends BrowserHTTPRoute {
112
115
  filePath &&
113
116
  deleteAsync(filePath, { force: true })
114
117
  .then(() => {
115
- debug(
118
+ logger.info(
116
119
  `Successfully deleted downloads from disk at "${filePath}"`,
117
120
  );
118
121
  })
119
122
  .catch((err) => {
120
- debug(
123
+ logger.error(
121
124
  `Error cleaning up downloaded files: "${err}" at "${filePath}"`,
122
125
  );
123
126
  }),
@@ -144,7 +147,7 @@ export default class ChromiumDownloadPostRoute extends BrowserHTTPRoute {
144
147
  }
145
148
  })
146
149
  .on('end', () => {
147
- debug(`Downloads successfully sent`);
150
+ logger.info(`Downloads successfully sent`);
148
151
  rmDownload();
149
152
  return resolve();
150
153
  })
@@ -7,6 +7,7 @@ import {
7
7
  CDPLaunchOptions,
8
8
  ChromiumCDP,
9
9
  HTTPRoutes,
10
+ Logger,
10
11
  Methods,
11
12
  Request,
12
13
  SystemQueryParameters,
@@ -57,14 +58,14 @@ export default class ChromiumFunctionPostRoute extends BrowserHTTPRoute {
57
58
  handler = async (
58
59
  req: Request,
59
60
  res: ServerResponse,
61
+ logger: Logger,
60
62
  browser: BrowserInstance,
61
63
  ): Promise<void> => {
62
- const debug = this.debug();
63
64
  const config = this.config();
64
- const handler = functionHandler(config, debug);
65
+ const handler = functionHandler(config, logger);
65
66
  const { contentType, payload, page } = await handler(req, browser);
66
67
 
67
- debug(`Got function response of "${contentType}"`);
68
+ logger.info(`Got function response of "${contentType}"`);
68
69
  page.close();
69
70
  page.removeAllListeners();
70
71
 
@@ -76,7 +77,7 @@ export default class ChromiumFunctionPostRoute extends BrowserHTTPRoute {
76
77
  if (!type) {
77
78
  throw new BadRequest(`Couldn't determine function's response type.`);
78
79
  } else {
79
- debug(`Sending file-type response of "${type}"`);
80
+ logger.info(`Sending file-type response of "${type}"`);
80
81
  const readStream = new Stream.PassThrough();
81
82
  readStream.end(response);
82
83
  res.setHeader('Content-Type', type);
@@ -3,6 +3,7 @@ import {
3
3
  BrowserlessRoutes,
4
4
  HTTPRoute,
5
5
  HTTPRoutes,
6
+ Logger,
6
7
  Methods,
7
8
  Request,
8
9
  Response,
@@ -13,7 +14,7 @@ import {
13
14
  export type ResponseSchema = object;
14
15
 
15
16
  export default class ChromiumJSONProtocolGetRoute extends HTTPRoute {
16
- private cachedProtocol: object | undefined;
17
+ protected cachedProtocol: object | undefined;
17
18
 
18
19
  name = BrowserlessRoutes.ChromiumJSONProtocolGetRoute;
19
20
  accepts = [contentTypes.any];
@@ -26,11 +27,15 @@ export default class ChromiumJSONProtocolGetRoute extends HTTPRoute {
26
27
  path = HTTPRoutes.jsonProtocol;
27
28
  tags = [APITags.browserAPI];
28
29
 
29
- handler = async (_req: Request, res: Response): Promise<void> => {
30
+ handler = async (
31
+ _req: Request,
32
+ res: Response,
33
+ logger: Logger,
34
+ ): Promise<void> => {
30
35
  const browserManager = this.browserManager();
31
36
 
32
37
  if (!this.cachedProtocol) {
33
- this.cachedProtocol = await browserManager.getProtocolJSON();
38
+ this.cachedProtocol = await browserManager.getProtocolJSON(logger);
34
39
  }
35
40
 
36
41
  return jsonResponse(res, 200, this.cachedProtocol);
@@ -4,6 +4,7 @@ import {
4
4
  BrowserlessRoutes,
5
5
  HTTPRoute,
6
6
  HTTPRoutes,
7
+ Logger,
7
8
  Methods,
8
9
  Request,
9
10
  Response,
@@ -18,7 +19,7 @@ export type ResponseSchema = UnwrapPromise<
18
19
  >;
19
20
 
20
21
  export default class ChromiumJSONVersionGetRoute extends HTTPRoute {
21
- private cachedJSON: ResponseSchema | undefined;
22
+ protected cachedJSON: ResponseSchema | undefined;
22
23
 
23
24
  name = BrowserlessRoutes.ChromiumJSONVersionGetRoute;
24
25
  accepts = [contentTypes.any];
@@ -30,8 +31,11 @@ export default class ChromiumJSONVersionGetRoute extends HTTPRoute {
30
31
  method = Methods.get;
31
32
  path = HTTPRoutes.jsonVersion;
32
33
  tags = [APITags.browserAPI];
33
-
34
- handler = async (req: Request, res: Response): Promise<void> => {
34
+ handler = async (
35
+ req: Request,
36
+ res: Response,
37
+ logger: Logger,
38
+ ): Promise<void> => {
35
39
  const baseUrl = req.parsed.host;
36
40
  const protocol = req.parsed.protocol.includes('s') ? 'wss' : 'ws';
37
41
 
@@ -39,7 +43,7 @@ export default class ChromiumJSONVersionGetRoute extends HTTPRoute {
39
43
  if (!this.cachedJSON) {
40
44
  const browserManager = this.browserManager();
41
45
  this.cachedJSON = {
42
- ...(await browserManager.getVersionJSON()),
46
+ ...(await browserManager.getVersionJSON(logger)),
43
47
  webSocketDebuggerUrl: `${protocol}://${baseUrl}`,
44
48
  };
45
49
  }
@@ -4,6 +4,7 @@ import {
4
4
  BrowserlessRoutes,
5
5
  CDPLaunchOptions,
6
6
  ChromiumCDP,
7
+ Logger,
7
8
  Request,
8
9
  SystemQueryParameters,
9
10
  WebsocketRoutes,
@@ -32,6 +33,7 @@ export default class ChromiumPageWebSocketRoute extends BrowserWebsocketRoute {
32
33
  req: Request,
33
34
  socket: Duplex,
34
35
  head: Buffer,
36
+ _logger: Logger,
35
37
  browser: ChromiumCDP,
36
38
  ): Promise<void> => browser.proxyPageWebSocket(req, socket, head);
37
39
  }
@@ -7,6 +7,7 @@ import {
7
7
  CDPLaunchOptions,
8
8
  ChromiumCDP,
9
9
  HTTPRoutes,
10
+ Logger,
10
11
  Methods,
11
12
  Request,
12
13
  SystemQueryParameters,
@@ -25,7 +26,6 @@ import {
25
26
  sleep,
26
27
  waitForEvent as waitForEvt,
27
28
  waitForFunction as waitForFn,
28
- writeResponse,
29
29
  } from '@browserless.io/browserless';
30
30
  import { Page } from 'puppeteer-core';
31
31
  import { ServerResponse } from 'http';
@@ -83,16 +83,17 @@ export default class ChromiumPDFPostRoute extends BrowserHTTPRoute {
83
83
  handler = async (
84
84
  req: Request,
85
85
  res: ServerResponse,
86
+ logger: Logger,
86
87
  browser: BrowserInstance,
87
88
  ): Promise<void> => {
89
+ logger.info('PDF API invoked with body:', req.body);
88
90
  const contentType =
89
91
  !req.headers.accept || req.headers.accept?.includes('*')
90
92
  ? 'application/pdf'
91
93
  : req.headers.accept;
92
94
 
93
95
  if (!req.body) {
94
- writeResponse(res, 400, `Couldn't parse JSON body`);
95
- return;
96
+ throw new BadRequest(`Couldn't parse JSON body`);
96
97
  }
97
98
 
98
99
  res.setHeader('Content-Type', contentType);
@@ -172,6 +173,7 @@ export default class ChromiumPDFPostRoute extends BrowserHTTPRoute {
172
173
  !!rejectRequestPattern.find((pattern) => req.url().match(pattern)) ||
173
174
  rejectResourceTypes.includes(req.resourceType())
174
175
  ) {
176
+ logger.debug(`Aborting request ${req.method()}: ${req.url()}`);
175
177
  return req.abort();
176
178
  }
177
179
  const interceptor = requestInterceptors.find((r) =>
@@ -242,5 +244,7 @@ export default class ChromiumPDFPostRoute extends BrowserHTTPRoute {
242
244
  await new Promise((r) => readStream.pipe(res).once('close', r));
243
245
 
244
246
  page.close().catch(noop);
247
+
248
+ logger.info('PDF API request completed');
245
249
  };
246
250
  }
@@ -6,6 +6,7 @@ import {
6
6
  CDPLaunchOptions,
7
7
  ChromiumCDP,
8
8
  HTTPRoutes,
9
+ Logger,
9
10
  Methods,
10
11
  Request,
11
12
  SystemQueryParameters,
@@ -47,12 +48,14 @@ export default class PerformancePost extends BrowserHTTPRoute {
47
48
  handler = async (
48
49
  req: Request,
49
50
  res: ServerResponse,
51
+ _logger: Logger,
50
52
  browser: BrowserInstance,
51
53
  ): Promise<void> => {
52
54
  const config = this.config();
53
55
  const response = await main({
54
56
  browser,
55
57
  context: req.body as BodySchema,
58
+ logger: _logger,
56
59
  timeout: config.getTimeout(),
57
60
  });
58
61
 
@@ -8,6 +8,7 @@ import {
8
8
  ChromiumCDP,
9
9
  HTTPRoutes,
10
10
  InBoundRequest,
11
+ Logger,
11
12
  Methods,
12
13
  OutBoundRequest,
13
14
  Request,
@@ -218,8 +219,10 @@ export default class ChromiumScrapePostRoute extends BrowserHTTPRoute {
218
219
  handler = async (
219
220
  req: Request,
220
221
  res: ServerResponse,
222
+ logger: Logger,
221
223
  browser: BrowserInstance,
222
224
  ) => {
225
+ logger.info('Scrape API invoked with body:', req.body);
223
226
  const contentType =
224
227
  !req.headers.accept || req.headers.accept?.includes('*')
225
228
  ? contentTypes.html
@@ -335,6 +338,7 @@ export default class ChromiumScrapePostRoute extends BrowserHTTPRoute {
335
338
  !!rejectRequestPattern.find((pattern) => req.url().match(pattern)) ||
336
339
  rejectResourceTypes.includes(req.resourceType())
337
340
  ) {
341
+ logger.debug(`Aborting request ${req.method()}: ${req.url()}`);
338
342
  return req.abort();
339
343
  }
340
344
  const interceptor = requestInterceptors.find((r) =>
@@ -433,6 +437,8 @@ export default class ChromiumScrapePostRoute extends BrowserHTTPRoute {
433
437
 
434
438
  page.close().catch(noop);
435
439
 
440
+ logger.info('Scrape API request completed');
441
+
436
442
  return jsonResponse(res, 200, response, false);
437
443
  };
438
444
  }
@@ -7,6 +7,7 @@ import {
7
7
  CDPLaunchOptions,
8
8
  ChromiumCDP,
9
9
  HTTPRoutes,
10
+ Logger,
10
11
  Methods,
11
12
  Request,
12
13
  SystemQueryParameters,
@@ -85,8 +86,10 @@ export default class ScreenshotPost extends BrowserHTTPRoute {
85
86
  handler = async (
86
87
  req: Request,
87
88
  res: ServerResponse,
89
+ logger: Logger,
88
90
  browser: BrowserInstance,
89
91
  ): Promise<void> => {
92
+ logger.info('Screenshot API invoked with body:', req.body);
90
93
  const contentType =
91
94
  !req.headers.accept || req.headers.accept?.includes('*')
92
95
  ? 'image/png'
@@ -179,6 +182,7 @@ export default class ScreenshotPost extends BrowserHTTPRoute {
179
182
  !!rejectRequestPattern.find((pattern) => req.url().match(pattern)) ||
180
183
  rejectResourceTypes.includes(req.resourceType())
181
184
  ) {
185
+ logger.debug(`Aborting request ${req.method()}: ${req.url()}`);
182
186
  return req.abort();
183
187
  }
184
188
  const interceptor = requestInterceptors.find((r) =>
@@ -262,5 +266,6 @@ export default class ScreenshotPost extends BrowserHTTPRoute {
262
266
  await new Promise((r) => readStream.pipe(res).once('close', r));
263
267
 
264
268
  page.close().catch(noop);
269
+ logger.info('Screenshot API request completed');
265
270
  };
266
271
  }
@@ -4,6 +4,7 @@ import {
4
4
  ChromiumCDP,
5
5
  Config,
6
6
  HTTPRoutes,
7
+ Logger,
7
8
  Request,
8
9
  UnwrapPromise,
9
10
  contentTypes,
@@ -16,7 +17,6 @@ import {
16
17
  } from '@browserless.io/browserless';
17
18
  import { FunctionRunner } from './client.js';
18
19
  import { Page } from 'puppeteer-core';
19
- import debug from 'debug';
20
20
  import fs from 'fs';
21
21
  import path from 'path';
22
22
 
@@ -35,11 +35,7 @@ interface HandlerOptions {
35
35
  downloadPath?: string;
36
36
  }
37
37
 
38
- export default (
39
- config: Config,
40
- debug: debug.Debugger,
41
- options: HandlerOptions = {},
42
- ) =>
38
+ export default (config: Config, logger: Logger, options: HandlerOptions = {}) =>
43
39
  async (
44
40
  req: Request,
45
41
  browser: BrowserInstance,
@@ -88,7 +84,7 @@ export default (
88
84
  */
89
85
  page.on('request', async (request) => {
90
86
  const requestUrl = request.url();
91
- debug(`Outbound Page Request: "${requestUrl}"`);
87
+ logger.info(`Outbound Page Request: "${requestUrl}"`);
92
88
  if (requestUrl.startsWith(functionRequestPath)) {
93
89
  const filename = path.basename(requestUrl);
94
90
  if (filename === functionCodeJS) {
@@ -107,7 +103,7 @@ export default (
107
103
  status: 200,
108
104
  });
109
105
  }
110
- debug(
106
+ logger.warn(
111
107
  `Static asset request to "${requestUrl}" couldn't be found, 404-ing`,
112
108
  );
113
109
  return request.respond({
@@ -116,18 +112,18 @@ export default (
116
112
  status: 404,
117
113
  });
118
114
  }
119
- debug(`Request: "${requestUrl}" no responder found, continuing...`);
115
+ logger.info(`Request: "${requestUrl}" no responder found, continuing...`);
120
116
  return request.continue();
121
117
  });
122
118
 
123
119
  page.on('response', (res) => {
124
- if (res.status() !== 200) {
125
- debug(`Received a non-200 response for request "${res.url()}"`);
120
+ if (!res.ok()) {
121
+ logger.warn(`Received a non-200 response for request "${res.url()}"`);
126
122
  }
127
123
  });
128
124
 
129
125
  page.on('console', (event) => {
130
- debug(`${event.type()}: ${event.text()}`);
126
+ logger.trace(`${event.type()}: ${event.text()}`);
131
127
  });
132
128
 
133
129
  await page.goto(functionIndexHTML);
@@ -164,7 +160,7 @@ export default (
164
160
  JSON.stringify(options),
165
161
  )
166
162
  .catch((e) => {
167
- debug(`Error running code: ${e}`);
163
+ logger.error(`Error running code: ${e}`);
168
164
  throw new BadRequest(e.message);
169
165
  });
170
166
 
@@ -1,16 +1,16 @@
1
1
  import { Message, start } from './types.js';
2
- import { createLogger } from '@browserless.io/browserless';
2
+ import { Logger } from '@browserless.io/browserless';
3
3
  import lighthouse from 'lighthouse';
4
4
 
5
- const debug = createLogger('http:performance:child');
5
+ const logger = new Logger('http:performance:child');
6
6
 
7
- debug(`Child init`);
7
+ logger.info(`Child init`);
8
8
 
9
9
  const send = (msg: Message) => process.send && process.send(msg);
10
10
 
11
11
  const start = async ({ url, config, options }: start) => {
12
12
  try {
13
- debug(`Child got payload, starting lighthouse`);
13
+ logger.info(`Child got payload, starting lighthouse`);
14
14
  const results = await lighthouse(url, options, config);
15
15
 
16
16
  send({
@@ -1,5 +1,4 @@
1
1
  import { Message, mainOptions } from './types.js';
2
- import { createLogger } from '@browserless.io/browserless';
3
2
  import { fork } from 'child_process';
4
3
  import path from 'path';
5
4
 
@@ -10,10 +9,10 @@ const DEFAULT_AUDIT_CONFIG = {
10
9
  export default async ({
11
10
  browser,
12
11
  context,
12
+ logger,
13
13
  timeout,
14
14
  }: mainOptions): Promise<unknown> => {
15
15
  return new Promise((resolve, reject) => {
16
- const debug = createLogger('http:performance:main');
17
16
  const childPath = path.join(
18
17
  './',
19
18
  'build',
@@ -23,7 +22,7 @@ export default async ({
23
22
  'child.js',
24
23
  );
25
24
 
26
- debug(`Starting up child at ${childPath}`);
25
+ logger.trace(`Starting up child at ${childPath}`);
27
26
 
28
27
  const child = fork(childPath);
29
28
  const port = new URL(browser.wsEndpoint() || '').port;
@@ -54,14 +53,14 @@ export default async ({
54
53
  };
55
54
 
56
55
  child.on('error', (err) => {
57
- debug(`Error in child process`, err);
56
+ logger.error(`Error in child process`, err);
58
57
  reject('Performance run error: ' + err.message);
59
58
  close(child.pid);
60
59
  });
61
60
 
62
61
  child.on('message', (payload: Message) => {
63
62
  if (payload.event === 'created') {
64
- debug(`Child process is up, sending performance request`);
63
+ logger.info(`Child process is up, sending performance request`);
65
64
  return child.send({
66
65
  config,
67
66
  event: 'start',
@@ -71,7 +70,7 @@ export default async ({
71
70
  }
72
71
 
73
72
  if (payload.event === 'complete') {
74
- debug(`Performance gathered, closing and resolving request`);
73
+ logger.info(`Performance gathered, closing and resolving request`);
75
74
  close(child.pid);
76
75
  return resolve({
77
76
  data: payload.data,
@@ -1,5 +1,5 @@
1
+ import { BrowserInstance, Logger } from '@browserless.io/browserless';
1
2
  import { Config, Flags } from 'lighthouse';
2
- import { BrowserInstance } from '@browserless.io/browserless';
3
3
 
4
4
  export interface Message {
5
5
  data?: unknown;
@@ -14,6 +14,7 @@ export interface mainOptions {
14
14
  config?: unknown;
15
15
  url: string;
16
16
  };
17
+ logger: Logger;
17
18
  timeout: number;
18
19
  }
19
20
 
package/src/types.ts CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  FirefoxPlaywright,
10
10
  HTTPManagementRoutes,
11
11
  HTTPRoutes,
12
+ Logger,
12
13
  Methods,
13
14
  Metrics,
14
15
  Request,
@@ -99,7 +100,6 @@ abstract class Route {
99
100
  protected _browserManager: Browserless['browserManager'],
100
101
  protected _config: Browserless['config'],
101
102
  protected _fileSystem: Browserless['fileSystem'],
102
- protected _debug: Browserless['debug'],
103
103
  protected _metrics: Browserless['metrics'],
104
104
  protected _monitoring: Browserless['monitoring'],
105
105
  protected _staticSDKDir: Browserless['staticSDKDir'],
@@ -164,14 +164,6 @@ abstract class Route {
164
164
  */
165
165
  config = () => this._config;
166
166
 
167
- /**
168
- * Helper function that loads the debug module, useful
169
- * for logging messages scoped to the routes path. Defined
170
- * and injected by browserless after initialization.
171
- * @returns Debug
172
- */
173
- debug = () => this._debug;
174
-
175
167
  /**
176
168
  * Helper function that loads the file-system module
177
169
  * for interacting with file-systems. Defined and injected by
@@ -254,6 +246,7 @@ export abstract class HTTPRoute extends BasicHTTPRoute {
254
246
  abstract handler: (
255
247
  req: Request,
256
248
  res: http.ServerResponse,
249
+ logger: Logger,
257
250
  ) => Promise<unknown>;
258
251
  }
259
252
 
@@ -274,6 +267,7 @@ export abstract class BrowserHTTPRoute extends BasicHTTPRoute {
274
267
  abstract handler: (
275
268
  req: Request,
276
269
  res: http.ServerResponse,
270
+ logger: Logger,
277
271
  browser: BrowserInstance,
278
272
  ) => Promise<unknown>;
279
273
 
@@ -298,6 +292,7 @@ export abstract class WebSocketRoute extends Route {
298
292
  req: Request,
299
293
  socket: stream.Duplex,
300
294
  head: Buffer,
295
+ logger: Logger,
301
296
  ) => Promise<unknown>;
302
297
  }
303
298
 
@@ -319,6 +314,7 @@ export abstract class BrowserWebsocketRoute extends Route {
319
314
  req: Request,
320
315
  socket: stream.Duplex,
321
316
  head: Buffer,
317
+ logger: Logger,
322
318
  browser: BrowserInstance,
323
319
  ): Promise<unknown>;
324
320
 
package/src/utils.ts CHANGED
@@ -790,12 +790,17 @@ export const untildify = (path: string) => {
790
790
  return homeDir ? path.replace(/^~(?=$|\/|\\)/, homeDir) : path;
791
791
  };
792
792
 
793
- export const printLogo = (docsLink: string) => `
793
+ export const printLogo = (docsLink: string, debugURL?: string | boolean) => `
794
794
  ---------------------------------------------------------
795
795
  | browserless.io
796
796
  | To read documentation and more, load in your browser:
797
797
  |
798
- | ${docsLink}
798
+ | OpenAPI: ${docsLink}
799
+ | Full Documentation: https://docs.browserless.io/ ${
800
+ /*prettier-ignore*/
801
+ debugURL ? `
802
+ | Debbuger: ${debugURL}` : ""
803
+ }
799
804
  ---------------------------------------------------------
800
805
  ${gradient(
801
806
  '#ff1a8c',