@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.
- package/CHANGELOG.md +19 -1
- package/README.md +41 -3
- package/assets/debugger.png +0 -0
- package/bin/browserless.js +8 -4
- package/bin/scaffold/README.md +6 -4
- package/bin/scaffold/src/hello-world.http.ts +7 -1
- package/build/browserless.d.ts +8 -5
- package/build/browserless.js +23 -22
- package/build/browsers/chrome.cdp.d.ts +2 -2
- package/build/browsers/chrome.cdp.js +2 -2
- package/build/browsers/chrome.playwright.d.ts +2 -2
- package/build/browsers/chrome.playwright.js +2 -2
- package/build/browsers/chromium.cdp.d.ts +4 -4
- package/build/browsers/chromium.cdp.js +49 -32
- package/build/browsers/chromium.playwright.d.ts +4 -4
- package/build/browsers/chromium.playwright.js +14 -13
- package/build/browsers/firefox.playwright.d.ts +4 -4
- package/build/browsers/firefox.playwright.js +14 -13
- package/build/browsers/index.d.ts +24 -8
- package/build/browsers/index.js +20 -15
- package/build/browsers/webkit.playwright.d.ts +4 -4
- package/build/browsers/webkit.playwright.js +14 -13
- package/build/config.d.ts +3 -0
- package/build/config.js +3 -0
- package/build/exports.d.ts +1 -0
- package/build/exports.js +1 -0
- package/build/file-system.d.ts +2 -3
- package/build/file-system.js +2 -2
- package/build/index.js +7 -7
- package/build/limiter.d.ts +2 -3
- package/build/limiter.js +11 -11
- package/build/logger.d.ts +19 -0
- package/build/logger.js +43 -0
- package/build/monitoring.d.ts +2 -3
- package/build/monitoring.js +4 -4
- package/build/router.d.ts +4 -5
- package/build/router.js +31 -28
- package/build/routes/chrome/http/content.post.body.json +8 -8
- package/build/routes/chrome/http/pdf.post.body.json +9 -9
- package/build/routes/chrome/http/scrape.post.body.json +8 -8
- package/build/routes/chrome/http/screenshot.post.body.json +8 -8
- package/build/routes/chromium/http/content.post.body.json +8 -8
- package/build/routes/chromium/http/pdf.post.body.json +9 -9
- package/build/routes/chromium/http/scrape.post.body.json +8 -8
- package/build/routes/chromium/http/screenshot.post.body.json +8 -8
- package/build/routes/firefox/ws/playwright.d.ts +2 -2
- package/build/routes/firefox/ws/playwright.js +1 -1
- package/build/routes/management/http/static.get.d.ts +2 -2
- package/build/routes/management/http/static.get.js +8 -10
- package/build/routes/management/tests/management.spec.js +9 -0
- package/build/routes/webkit/ws/playwright.d.ts +2 -2
- package/build/routes/webkit/ws/playwright.js +1 -1
- package/build/sdk-utils.js +23 -10
- package/build/server.d.ts +4 -5
- package/build/server.js +38 -33
- package/build/shared/browser.ws.d.ts +2 -2
- package/build/shared/browser.ws.js +1 -1
- package/build/shared/chromium.playwright.ws.d.ts +2 -2
- package/build/shared/chromium.playwright.ws.js +1 -1
- package/build/shared/chromium.ws.d.ts +2 -2
- package/build/shared/chromium.ws.js +1 -1
- package/build/shared/content.http.d.ts +2 -2
- package/build/shared/content.http.js +4 -1
- package/build/shared/download.http.d.ts +2 -2
- package/build/shared/download.http.js +11 -12
- package/build/shared/function.http.d.ts +2 -2
- package/build/shared/function.http.js +4 -5
- package/build/shared/json-protocol.http.d.ts +3 -3
- package/build/shared/json-protocol.http.js +2 -2
- package/build/shared/json-version.http.d.ts +3 -3
- package/build/shared/json-version.http.js +2 -2
- package/build/shared/page.ws.d.ts +2 -2
- package/build/shared/page.ws.js +1 -1
- package/build/shared/pdf.http.d.ts +2 -2
- package/build/shared/pdf.http.js +6 -4
- package/build/shared/performance.http.d.ts +2 -2
- package/build/shared/performance.http.js +2 -1
- package/build/shared/scrape.http.d.ts +2 -2
- package/build/shared/scrape.http.js +4 -1
- package/build/shared/screenshot.http.d.ts +2 -2
- package/build/shared/screenshot.http.js +4 -1
- package/build/shared/utils/function/handler.d.ts +2 -3
- package/build/shared/utils/function/handler.js +8 -8
- package/build/shared/utils/performance/child.js +4 -4
- package/build/shared/utils/performance/main.d.ts +1 -1
- package/build/shared/utils/performance/main.js +5 -7
- package/build/shared/utils/performance/types.d.ts +2 -1
- package/build/types.d.ts +6 -15
- package/build/types.js +1 -10
- package/build/utils.d.ts +1 -1
- package/build/utils.js +6 -2
- package/package.json +18 -15
- package/scripts/install-debugger.js +55 -15
- package/src/browserless.ts +29 -21
- package/src/browsers/chrome.cdp.ts +2 -5
- package/src/browsers/chrome.playwright.ts +2 -5
- package/src/browsers/chromium.cdp.ts +84 -35
- package/src/browsers/chromium.playwright.ts +26 -13
- package/src/browsers/firefox.playwright.ts +28 -13
- package/src/browsers/index.ts +24 -16
- package/src/browsers/webkit.playwright.ts +28 -13
- package/src/config.ts +4 -0
- package/src/exports.ts +1 -0
- package/src/file-system.ts +2 -7
- package/src/index.ts +7 -7
- package/src/limiter.ts +13 -11
- package/src/logger.ts +52 -0
- package/src/monitoring.ts +6 -8
- package/src/router.ts +29 -27
- package/src/routes/firefox/ws/playwright.ts +2 -0
- package/src/routes/management/http/static.get.ts +13 -10
- package/src/routes/management/tests/management.spec.ts +15 -0
- package/src/routes/webkit/ws/playwright.ts +2 -0
- package/src/sdk-utils.ts +20 -2
- package/src/server.ts +47 -32
- package/src/shared/browser.ws.ts +2 -0
- package/src/shared/chromium.playwright.ws.ts +2 -0
- package/src/shared/chromium.ws.ts +2 -0
- package/src/shared/content.http.ts +6 -0
- package/src/shared/download.http.ts +14 -11
- package/src/shared/function.http.ts +5 -4
- package/src/shared/json-protocol.http.ts +8 -3
- package/src/shared/json-version.http.ts +8 -4
- package/src/shared/page.ws.ts +2 -0
- package/src/shared/pdf.http.ts +7 -3
- package/src/shared/performance.http.ts +3 -0
- package/src/shared/scrape.http.ts +6 -0
- package/src/shared/screenshot.http.ts +5 -0
- package/src/shared/utils/function/handler.ts +9 -13
- package/src/shared/utils/performance/child.ts +4 -4
- package/src/shared/utils/performance/main.ts +5 -6
- package/src/shared/utils/performance/types.ts +2 -1
- package/src/types.ts +5 -9
- package/src/utils.ts +7 -2
- package/static/docs/swagger.json +11 -11
- package/static/docs/swagger.min.json +10 -10
- package/static/function/client.js +1656 -2916
- 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
|
-
|
|
75
|
+
logger.info(`Generating a download directory at "${downloadPath}"`);
|
|
75
76
|
await mkdir(downloadPath);
|
|
76
|
-
const handler = functionHandler(config,
|
|
77
|
+
const handler = functionHandler(config, logger, { downloadPath });
|
|
77
78
|
const response = await handler(req, browser).catch((e) => {
|
|
78
|
-
|
|
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
|
-
|
|
89
|
+
logger.info(`Download function has returned, finding downloads...`);
|
|
89
90
|
async function checkIfDownloadComplete(): Promise<string | null> {
|
|
90
91
|
if (res.headersSent) {
|
|
91
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
118
|
+
logger.info(
|
|
116
119
|
`Successfully deleted downloads from disk at "${filePath}"`,
|
|
117
120
|
);
|
|
118
121
|
})
|
|
119
122
|
.catch((err) => {
|
|
120
|
-
|
|
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
|
-
|
|
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,
|
|
65
|
+
const handler = functionHandler(config, logger);
|
|
65
66
|
const { contentType, payload, page } = await handler(req, browser);
|
|
66
67
|
|
|
67
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|
package/src/shared/page.ws.ts
CHANGED
|
@@ -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
|
}
|
package/src/shared/pdf.http.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
125
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
2
|
+
import { Logger } from '@browserless.io/browserless';
|
|
3
3
|
import lighthouse from 'lighthouse';
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const logger = new Logger('http:performance:child');
|
|
6
6
|
|
|
7
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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',
|