@browserless.io/browserless 2.0.0-beta-1 → 2.0.0-beta-2
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/bin/browserless.js +128 -8
- package/build/browserless.d.ts +23 -18
- package/build/browserless.js +24 -17
- package/build/browsers/cdp-chromium.d.ts +17 -14
- package/build/browsers/index.d.ts +27 -10
- package/build/browsers/index.js +2 -12
- package/build/browsers/playwright-chromium.d.ts +12 -9
- package/build/browsers/playwright-firefox.d.ts +12 -9
- package/build/browsers/playwright-webkit.d.ts +12 -9
- package/build/config.d.ts +31 -31
- package/build/exports.d.ts +2 -0
- package/build/exports.js +2 -0
- package/build/file-system.d.ts +2 -2
- package/build/limiter.d.ts +34 -11
- package/build/metrics.d.ts +17 -11
- package/build/monitoring.d.ts +3 -2
- package/build/router.d.ts +28 -0
- package/build/router.js +138 -0
- package/build/routes/chromium/http/content-post.body.json +8 -8
- package/build/routes/chromium/http/download-post.js +1 -1
- package/build/routes/chromium/http/function-post.js +1 -1
- package/build/routes/chromium/http/pdf-post.body.json +8 -8
- package/build/routes/chromium/http/performance.js +1 -1
- 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/chromium/utils/function/client.d.ts +3 -3
- package/build/routes/management/http/config-get.js +1 -1
- package/build/routes/management/http/metrics-get.js +1 -1
- package/build/routes/management/http/metrics-total-get.js +1 -1
- package/build/routes/management/http/sessions-get.js +3 -3
- package/build/routes/management/http/static-get.js +1 -1
- package/build/server.d.ts +22 -27
- package/build/server.js +29 -149
- package/build/token.d.ts +6 -0
- package/build/token.js +21 -0
- package/build/types.d.ts +85 -14
- package/build/utils.d.ts +1 -2
- package/build/utils.js +0 -13
- package/build/webhooks.d.ts +2 -2
- package/docker/sdk/Dockerfile +2 -6
- package/package.json +4 -4
- package/src/browserless.ts +44 -32
- package/src/browsers/cdp-chromium.ts +13 -13
- package/src/browsers/index.ts +9 -24
- package/src/browsers/playwright-chromium.ts +9 -9
- package/src/browsers/playwright-firefox.ts +9 -9
- package/src/browsers/playwright-webkit.ts +9 -9
- package/src/config.ts +32 -31
- package/src/exports.ts +2 -0
- package/src/file-system.ts +2 -2
- package/src/limiter.ts +11 -11
- package/src/metrics.ts +11 -11
- package/src/monitoring.ts +2 -2
- package/src/router.ts +234 -0
- package/src/routes/chromium/http/download-post.ts +1 -1
- package/src/routes/chromium/http/function-post.ts +1 -1
- package/src/routes/chromium/http/performance.ts +1 -1
- package/src/routes/chromium/utils/function/client.ts +2 -2
- package/src/routes/management/http/config-get.ts +1 -1
- package/src/routes/management/http/metrics-get.ts +1 -1
- package/src/routes/management/http/metrics-total-get.ts +1 -1
- package/src/routes/management/http/sessions-get.ts +3 -3
- package/src/routes/management/http/static-get.ts +1 -1
- package/src/server.ts +43 -238
- package/src/token.ts +40 -0
- package/src/types.ts +92 -17
- package/src/utils.ts +0 -25
- package/src/webhooks.ts +2 -2
- package/static/docs/swagger.json +9 -9
package/bin/browserless.js
CHANGED
|
@@ -5,6 +5,7 @@ import { Browserless } from '@browserless.io/browserless';
|
|
|
5
5
|
import buildOpenAPI from '../scripts/build-open-api.js';
|
|
6
6
|
import buildSchemas from '../scripts/build-schemas.js';
|
|
7
7
|
|
|
8
|
+
import { createInterface } from 'readline';
|
|
8
9
|
import debug from 'debug';
|
|
9
10
|
import { fileURLToPath } from 'url';
|
|
10
11
|
import fs from 'fs/promises';
|
|
@@ -12,6 +13,7 @@ import path from 'path';
|
|
|
12
13
|
import { spawn } from 'child_process';
|
|
13
14
|
|
|
14
15
|
const log = debug('browserless:sdk:log');
|
|
16
|
+
const promptLog = debug('browserless:prompt');
|
|
15
17
|
|
|
16
18
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
17
19
|
const cmd = process.argv[2];
|
|
@@ -25,6 +27,21 @@ if (!allowedCMDs.includes(cmd)) {
|
|
|
25
27
|
);
|
|
26
28
|
}
|
|
27
29
|
|
|
30
|
+
const prompt = async (question) => {
|
|
31
|
+
const rl = createInterface({
|
|
32
|
+
input: process.stdin,
|
|
33
|
+
output: process.stdout,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
return new Promise((resolve) => {
|
|
37
|
+
promptLog(question);
|
|
38
|
+
rl.question(' > ', (a) => {
|
|
39
|
+
rl.close();
|
|
40
|
+
resolve(a.trim());
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
|
|
28
45
|
const importClassOverride = async (files, className) => {
|
|
29
46
|
const classModuleFile = files.find((f) =>
|
|
30
47
|
path.parse(f).name.endsWith(className),
|
|
@@ -43,6 +60,24 @@ const importClassOverride = async (files, className) => {
|
|
|
43
60
|
return (await import(classModuleFullFilePath)).default;
|
|
44
61
|
};
|
|
45
62
|
|
|
63
|
+
const buildDockerImage = async (cmd) => {
|
|
64
|
+
new Promise((resolve, reject) => {
|
|
65
|
+
const [docker, ...args] = cmd.split(' ');
|
|
66
|
+
spawn(docker, args, {
|
|
67
|
+
cwd,
|
|
68
|
+
stdio: 'inherit',
|
|
69
|
+
}).once('close', (code) => {
|
|
70
|
+
if (code === 0) {
|
|
71
|
+
log(`Successfully built the docker image.`);
|
|
72
|
+
return resolve();
|
|
73
|
+
}
|
|
74
|
+
return reject(
|
|
75
|
+
`Error when building Docker image, see output for more details`,
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
|
|
46
81
|
const buildTypeScript = async () =>
|
|
47
82
|
new Promise((resolve, reject) => {
|
|
48
83
|
spawn('npx', ['tsc', '--outDir', 'build'], {
|
|
@@ -83,6 +118,35 @@ const getSourceFiles = async () => {
|
|
|
83
118
|
};
|
|
84
119
|
};
|
|
85
120
|
|
|
121
|
+
const getArgSwitches = () => {
|
|
122
|
+
return process.argv.reduce((accum, arg, idx) => {
|
|
123
|
+
if (!arg.startsWith('--')) {
|
|
124
|
+
return accum;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (arg.includes('=')) {
|
|
128
|
+
const [parameter, value] = arg.split('=');
|
|
129
|
+
accum[parameter.replace(/-/gi, '')] = value || true;
|
|
130
|
+
return accum;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const nextSwitchOrParameter = process.argv[idx + 1];
|
|
134
|
+
const param = arg.replace(/-/gi, '');
|
|
135
|
+
|
|
136
|
+
if (
|
|
137
|
+
typeof nextSwitchOrParameter === 'undefined' ||
|
|
138
|
+
nextSwitchOrParameter?.startsWith('--')
|
|
139
|
+
) {
|
|
140
|
+
accum[param] = true;
|
|
141
|
+
return accum;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
accum[param] = nextSwitchOrParameter;
|
|
145
|
+
|
|
146
|
+
return accum;
|
|
147
|
+
}, {});
|
|
148
|
+
};
|
|
149
|
+
|
|
86
150
|
/**
|
|
87
151
|
* Build
|
|
88
152
|
* Responsible for compiling TypeScript, generating routes meta-data
|
|
@@ -119,6 +183,7 @@ const start = async (dev = false) => {
|
|
|
119
183
|
: await getSourceFiles();
|
|
120
184
|
|
|
121
185
|
log(`Importing all class overrides if present`);
|
|
186
|
+
|
|
122
187
|
const [
|
|
123
188
|
browserManager,
|
|
124
189
|
config,
|
|
@@ -126,6 +191,8 @@ const start = async (dev = false) => {
|
|
|
126
191
|
limiter,
|
|
127
192
|
metrics,
|
|
128
193
|
monitoring,
|
|
194
|
+
router,
|
|
195
|
+
token,
|
|
129
196
|
webhooks,
|
|
130
197
|
] = await Promise.all([
|
|
131
198
|
importClassOverride(files, 'browser-manager'),
|
|
@@ -134,10 +201,13 @@ const start = async (dev = false) => {
|
|
|
134
201
|
importClassOverride(files, 'limiter'),
|
|
135
202
|
importClassOverride(files, 'metrics'),
|
|
136
203
|
importClassOverride(files, 'monitoring'),
|
|
204
|
+
importClassOverride(files, 'router'),
|
|
205
|
+
importClassOverride(files, 'token'),
|
|
137
206
|
importClassOverride(files, 'webhooks'),
|
|
138
207
|
]);
|
|
139
208
|
|
|
140
209
|
log(`Starting Browserless`);
|
|
210
|
+
|
|
141
211
|
const browserless = new Browserless({
|
|
142
212
|
browserManager,
|
|
143
213
|
config,
|
|
@@ -145,6 +215,8 @@ const start = async (dev = false) => {
|
|
|
145
215
|
limiter,
|
|
146
216
|
metrics,
|
|
147
217
|
monitoring,
|
|
218
|
+
router,
|
|
219
|
+
token,
|
|
148
220
|
webhooks,
|
|
149
221
|
});
|
|
150
222
|
|
|
@@ -191,21 +263,69 @@ const start = async (dev = false) => {
|
|
|
191
263
|
};
|
|
192
264
|
|
|
193
265
|
const buildDocker = async () => {
|
|
194
|
-
const from = process.argv[3] ?? 'ghcr.io/browserless/multi';
|
|
195
|
-
const version = process.argv[4] ?? 'latest';
|
|
196
266
|
const finalDockerPath = path.join(cwd, 'build', 'Dockerfile');
|
|
267
|
+
const argSwitches = getArgSwitches();
|
|
268
|
+
|
|
269
|
+
await build();
|
|
197
270
|
|
|
198
271
|
const dockerContents = (
|
|
199
272
|
await fs.readFile(path.join(__dirname, '..', 'docker', 'sdk', 'Dockerfile'))
|
|
200
273
|
).toString();
|
|
201
274
|
|
|
202
|
-
log(`
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
275
|
+
log(`Generating Dockerfile at "${finalDockerPath}"`);
|
|
276
|
+
|
|
277
|
+
await fs.writeFile(path.join(cwd, 'build', 'Dockerfile'), dockerContents);
|
|
278
|
+
|
|
279
|
+
const from =
|
|
280
|
+
argSwitches.from ||
|
|
281
|
+
(await prompt(
|
|
282
|
+
'Which docker image do you want to use (defaults to: ghcr.io/browserless/multi)?',
|
|
283
|
+
)) ||
|
|
284
|
+
'ghcr.io/browserless/multi';
|
|
285
|
+
|
|
286
|
+
const action =
|
|
287
|
+
argSwitches.action ||
|
|
288
|
+
(await prompt(
|
|
289
|
+
'Do you want to push the image or load it locally (defaults to load)?',
|
|
290
|
+
)) ||
|
|
291
|
+
'load';
|
|
292
|
+
|
|
293
|
+
const tag =
|
|
294
|
+
argSwitches.tag ||
|
|
295
|
+
(await prompt(
|
|
296
|
+
'What do you want to name the resulting image (eg, my-browserless:latest)?',
|
|
297
|
+
));
|
|
207
298
|
|
|
208
|
-
|
|
299
|
+
if (!tag || !tag.includes(':')) {
|
|
300
|
+
throw new Error(`A name for the image is required with a ":" and version.`);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const platformsPrompt =
|
|
304
|
+
action === 'load'
|
|
305
|
+
? `Which platform do you want to build for (defaults to linux/amd64)?`
|
|
306
|
+
: `Which platforms do you want to build? (defaults to "linux/amd64", must be comma-separated)?`;
|
|
307
|
+
|
|
308
|
+
const platforms =
|
|
309
|
+
argSwitches.platform || (await prompt(platformsPrompt)) || 'linux/amd64';
|
|
310
|
+
|
|
311
|
+
if (action === 'load' && platforms.includes(',')) {
|
|
312
|
+
throw new Error(
|
|
313
|
+
`When "load" is specified, only one platform can be built due to limitations in buildx.`,
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const cmd = `docker buildx build --build-arg FROM=${from} --platform ${platforms} --${action} -f ./build/Dockerfile -t ${tag} .`;
|
|
318
|
+
|
|
319
|
+
const proceed =
|
|
320
|
+
argSwitches.proceed ||
|
|
321
|
+
(await prompt(`Will execute "${cmd}" Proceed (y/n)?`)) ||
|
|
322
|
+
'n';
|
|
323
|
+
|
|
324
|
+
if (proceed || !proceed.includes('n')) {
|
|
325
|
+
log(`Starting docker build`);
|
|
326
|
+
await buildDockerImage(cmd);
|
|
327
|
+
process.exit(0);
|
|
328
|
+
}
|
|
209
329
|
};
|
|
210
330
|
|
|
211
331
|
switch (cmd) {
|
package/build/browserless.d.ts
CHANGED
|
@@ -1,29 +1,34 @@
|
|
|
1
|
+
/// <reference types="debug" />
|
|
1
2
|
/// <reference types="node" />
|
|
2
|
-
import { BrowserManager, Config, FileSystem, HTTPServer, Limiter, Metrics, Monitoring, WebHooks } from '@browserless.io/browserless';
|
|
3
|
+
import { BrowserManager, Config, FileSystem, HTTPServer, Limiter, Metrics, Monitoring, Router, Token, WebHooks } from '@browserless.io/browserless';
|
|
3
4
|
export declare class Browserless {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
protected debug: debug.Debugger;
|
|
6
|
+
protected browserManager: BrowserManager;
|
|
7
|
+
protected config: Config;
|
|
8
|
+
protected fileSystem: FileSystem;
|
|
9
|
+
protected limiter: Limiter;
|
|
10
|
+
protected metrics: Metrics;
|
|
11
|
+
protected monitoring: Monitoring;
|
|
12
|
+
protected router: Router;
|
|
13
|
+
protected token: Token;
|
|
14
|
+
protected webhooks: WebHooks;
|
|
12
15
|
webSocketRouteFiles: string[];
|
|
13
16
|
httpRouteFiles: string[];
|
|
14
17
|
server?: HTTPServer;
|
|
15
18
|
metricsSaveInterval: number;
|
|
16
19
|
metricsSaveIntervalID?: NodeJS.Timer;
|
|
17
|
-
constructor({ browserManager, config,
|
|
18
|
-
browserManager?:
|
|
19
|
-
config?:
|
|
20
|
-
fileSystem?:
|
|
21
|
-
limiter?:
|
|
22
|
-
metrics?:
|
|
23
|
-
monitoring?:
|
|
24
|
-
|
|
20
|
+
constructor({ browserManager, config, fileSystem, limiter, metrics, monitoring, router, token, webhooks, }?: {
|
|
21
|
+
browserManager?: Browserless['browserManager'];
|
|
22
|
+
config?: Browserless['config'];
|
|
23
|
+
fileSystem?: Browserless['fileSystem'];
|
|
24
|
+
limiter?: Browserless['limiter'];
|
|
25
|
+
metrics?: Browserless['metrics'];
|
|
26
|
+
monitoring?: Browserless['monitoring'];
|
|
27
|
+
router?: Browserless['router'];
|
|
28
|
+
token?: Browserless['token'];
|
|
29
|
+
webhooks?: Browserless['webhooks'];
|
|
25
30
|
});
|
|
26
|
-
|
|
31
|
+
protected saveMetrics: () => Promise<void>;
|
|
27
32
|
setMetricsSaveInterval: (interval: number) => void;
|
|
28
33
|
addHTTPRoute(httpRouteFilePath: string): void;
|
|
29
34
|
addWebSocketRoute(webSocketRouteFilePath: string): void;
|
package/build/browserless.js
CHANGED
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
import * as path from 'path';
|
|
2
|
-
import { BrowserManager, Config, FileSystem, HTTPServer, Limiter, Metrics, Monitoring, WebHooks, availableBrowsers, createLogger, getRouteFiles, makeExternalURL, printLogo, safeParse, } from '@browserless.io/browserless';
|
|
2
|
+
import { BrowserManager, Config, FileSystem, HTTPServer, Limiter, Metrics, Monitoring, Router, Token, WebHooks, availableBrowsers, createLogger, getRouteFiles, makeExternalURL, printLogo, safeParse, } from '@browserless.io/browserless';
|
|
3
3
|
import { readFile } from 'fs/promises';
|
|
4
4
|
import { userInfo } from 'os';
|
|
5
5
|
const routeSchemas = ['body', 'query'];
|
|
6
6
|
export class Browserless {
|
|
7
|
+
debug = createLogger('index');
|
|
8
|
+
browserManager;
|
|
7
9
|
config;
|
|
8
|
-
monitoring;
|
|
9
|
-
metrics;
|
|
10
10
|
fileSystem;
|
|
11
|
-
browserManager;
|
|
12
11
|
limiter;
|
|
12
|
+
metrics;
|
|
13
|
+
monitoring;
|
|
14
|
+
router;
|
|
15
|
+
token;
|
|
13
16
|
webhooks;
|
|
14
|
-
debug = createLogger('index');
|
|
15
17
|
webSocketRouteFiles = [];
|
|
16
18
|
httpRouteFiles = [];
|
|
17
19
|
server;
|
|
18
20
|
metricsSaveInterval = 5 * 60 * 1000;
|
|
19
21
|
metricsSaveIntervalID;
|
|
20
|
-
constructor({ browserManager, config,
|
|
22
|
+
constructor({ browserManager, config, fileSystem, limiter, metrics, monitoring, router, token, webhooks, } = {}) {
|
|
21
23
|
this.config = config || new Config();
|
|
22
24
|
this.metrics = metrics || new Metrics();
|
|
25
|
+
this.token = token || new Token(this.config);
|
|
23
26
|
this.webhooks = webhooks || new WebHooks(this.config);
|
|
24
27
|
this.browserManager = browserManager || new BrowserManager(this.config);
|
|
25
28
|
this.monitoring = monitoring || new Monitoring(this.config);
|
|
@@ -27,6 +30,8 @@ export class Browserless {
|
|
|
27
30
|
this.limiter =
|
|
28
31
|
limiter ||
|
|
29
32
|
new Limiter(this.config, this.metrics, this.monitoring, this.webhooks);
|
|
33
|
+
this.router =
|
|
34
|
+
router || new Router(this.config, this.browserManager, this.limiter);
|
|
30
35
|
}
|
|
31
36
|
saveMetrics = async () => {
|
|
32
37
|
const metricsPath = this.config.getMetricsJSONPath();
|
|
@@ -101,11 +106,11 @@ export class Browserless {
|
|
|
101
106
|
const { default: route } = await import(routeImport + `?cb=${Date.now()}`);
|
|
102
107
|
route.bodySchema = safeParse(bodySchema);
|
|
103
108
|
route.querySchema = safeParse(querySchema);
|
|
104
|
-
route.
|
|
105
|
-
route.
|
|
106
|
-
route.
|
|
107
|
-
route.
|
|
108
|
-
route.
|
|
109
|
+
route.getConfig = () => this.config;
|
|
110
|
+
route.getMetrics = () => this.metrics;
|
|
111
|
+
route.getMonitoring = () => this.monitoring;
|
|
112
|
+
route.getFileSystem = () => this.fileSystem;
|
|
113
|
+
route.getDebug = () => logger;
|
|
109
114
|
httpRoutes.push(route);
|
|
110
115
|
}
|
|
111
116
|
}
|
|
@@ -122,11 +127,11 @@ export class Browserless {
|
|
|
122
127
|
const logger = createLogger(`ws:${name}`);
|
|
123
128
|
const { default: route, } = await import(wsImport + `?cb=${Date.now()}`);
|
|
124
129
|
route.querySchema = safeParse(querySchema);
|
|
125
|
-
route.
|
|
126
|
-
route.
|
|
127
|
-
route.
|
|
128
|
-
route.
|
|
129
|
-
route.
|
|
130
|
+
route.getConfig = () => this.config;
|
|
131
|
+
route.getMetrics = () => this.metrics;
|
|
132
|
+
route.getMonitoring = () => this.monitoring;
|
|
133
|
+
route.getFileSystem = () => this.fileSystem;
|
|
134
|
+
route.getDebug = () => logger;
|
|
130
135
|
wsRoutes.push(route);
|
|
131
136
|
}
|
|
132
137
|
}
|
|
@@ -137,8 +142,10 @@ export class Browserless {
|
|
|
137
142
|
throw new Error(`Couldn't load route "${route.path}" due to missing browser of "${route.browser.name}"`);
|
|
138
143
|
}
|
|
139
144
|
});
|
|
145
|
+
httpRoutes.forEach((r) => this.router.registerHTTPRoute(r));
|
|
146
|
+
wsRoutes.forEach((r) => this.router.registerWebSocketRoute(r));
|
|
140
147
|
this.debug(`Imported and validated all route files, starting up server.`);
|
|
141
|
-
this.server = new HTTPServer(this.config, this.metrics, this.
|
|
148
|
+
this.server = new HTTPServer(this.config, this.metrics, this.token, this.router);
|
|
142
149
|
await this.server.start();
|
|
143
150
|
this.debug(`Starting metrics collection.`);
|
|
144
151
|
this.metricsSaveIntervalID = setInterval(() => this.saveMetrics(), this.metricsSaveInterval);
|
|
@@ -1,33 +1,36 @@
|
|
|
1
|
+
/// <reference types="debug" />
|
|
2
|
+
/// <reference types="node" />
|
|
1
3
|
/// <reference types="node" />
|
|
2
4
|
/// <reference types="node" />
|
|
3
5
|
/// <reference types="node" />
|
|
4
6
|
/// <reference types="node" />
|
|
5
7
|
import { CDPLaunchOptions, Config, Request } from '@browserless.io/browserless';
|
|
6
|
-
import { Browser, Page } from 'puppeteer-core';
|
|
8
|
+
import { Browser, Page, Target } from 'puppeteer-core';
|
|
7
9
|
import { Duplex } from 'stream';
|
|
8
10
|
import { EventEmitter } from 'events';
|
|
11
|
+
import httpProxy from 'http-proxy';
|
|
9
12
|
export declare class CDPChromium extends EventEmitter {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
protected config: Config;
|
|
14
|
+
protected userDataDir: string | null;
|
|
15
|
+
protected record: boolean;
|
|
16
|
+
protected blockAds: boolean;
|
|
17
|
+
protected running: boolean;
|
|
18
|
+
protected browser: Browser | null;
|
|
19
|
+
protected browserWSEndpoint: string | null;
|
|
20
|
+
protected port?: number;
|
|
21
|
+
protected debug: import("debug").Debugger;
|
|
22
|
+
protected proxy: httpProxy<import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>>;
|
|
20
23
|
constructor({ userDataDir, config, record, blockAds, }: {
|
|
21
24
|
blockAds: boolean;
|
|
22
25
|
config: Config;
|
|
23
26
|
record: boolean;
|
|
24
27
|
userDataDir: CDPChromium['userDataDir'];
|
|
25
28
|
});
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
protected cleanListeners(): void;
|
|
30
|
+
protected setUpEmbeddedAPI: (page: Page, id: string, record: boolean) => Promise<void>;
|
|
28
31
|
getPageId: (page: Page) => string;
|
|
29
32
|
makeLiveURL: (browserId: string, pageId: string) => string;
|
|
30
|
-
|
|
33
|
+
protected onTargetCreated: (target: Target) => Promise<void>;
|
|
31
34
|
isRunning: () => boolean;
|
|
32
35
|
newPage: () => Promise<Page>;
|
|
33
36
|
close: () => Promise<void>;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="debug" />
|
|
2
|
+
import { BrowserHTTPRoute, BrowserInstance, BrowserServerOptions, BrowserWebsocketRoute, BrowserlessSession, BrowserlessSessionJSON, CDPLaunchOptions, Config, Request } from '@browserless.io/browserless';
|
|
2
3
|
export declare class BrowserManager {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
protected config: Config;
|
|
5
|
+
protected browsers: Map<BrowserInstance, BrowserlessSession>;
|
|
6
|
+
protected launching: Map<string, Promise<unknown>>;
|
|
7
|
+
protected timers: Map<string, number>;
|
|
8
|
+
protected debug: import("debug").Debugger;
|
|
8
9
|
constructor(config: Config);
|
|
9
|
-
|
|
10
|
+
protected removeUserDataDir: (userDataDir: string | null) => Promise<void>;
|
|
10
11
|
/**
|
|
11
12
|
* Generates a directory for the user-data-dir contents to be saved in. Uses
|
|
12
13
|
* the provided sessionId, or creates one when omitted,
|
|
@@ -16,10 +17,26 @@ export declare class BrowserManager {
|
|
|
16
17
|
* @param sessionId The ID of the session
|
|
17
18
|
* @returns Promise<string> of the fully-qualified path of the directory
|
|
18
19
|
*/
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
protected generateDataDir: (sessionId?: string) => Promise<string>;
|
|
21
|
+
protected generateSessionJson: (browser: BrowserInstance, session: BrowserlessSession) => {
|
|
22
|
+
browser: string;
|
|
23
|
+
browserId: string | undefined;
|
|
24
|
+
initialConnectURL: string;
|
|
25
|
+
killURL: string | null;
|
|
26
|
+
running: boolean;
|
|
27
|
+
timeAliveMs: number;
|
|
28
|
+
id: string | null;
|
|
29
|
+
isTempDataDir: boolean;
|
|
30
|
+
launchOptions: CDPLaunchOptions | BrowserServerOptions;
|
|
31
|
+
numbConnected: number;
|
|
32
|
+
resolver: (val: unknown) => void;
|
|
33
|
+
routePath: string;
|
|
34
|
+
startedOn: number;
|
|
35
|
+
ttl: number;
|
|
36
|
+
userDataDir: string | null;
|
|
37
|
+
};
|
|
21
38
|
close: (browser: BrowserInstance, session: BrowserlessSession) => Promise<void>;
|
|
22
|
-
getAllSessions: (
|
|
39
|
+
getAllSessions: () => Promise<BrowserlessSessionJSON[]>;
|
|
23
40
|
complete: (browser: BrowserInstance) => Promise<void>;
|
|
24
41
|
getBrowserForRequest: (req: Request, router: BrowserHTTPRoute | BrowserWebsocketRoute) => Promise<BrowserInstance>;
|
|
25
42
|
stop: () => Promise<void>;
|
package/build/browsers/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BadRequest, CDPChromium, HTTPManagementRoutes, NotFound, ServerError, browserHook, convertIfBase64, createLogger, exists,
|
|
1
|
+
import { BadRequest, CDPChromium, HTTPManagementRoutes, NotFound, ServerError, browserHook, convertIfBase64, createLogger, exists, id, makeExternalURL, noop, pageHook, parseBooleanParam, } from '@browserless.io/browserless';
|
|
2
2
|
import path, { join } from 'path';
|
|
3
3
|
import { deleteAsync } from 'del';
|
|
4
4
|
import { mkdir } from 'fs/promises';
|
|
@@ -67,13 +67,8 @@ export class BrowserManager {
|
|
|
67
67
|
}
|
|
68
68
|
await Promise.all(cleanupACtions.map((a) => a()));
|
|
69
69
|
};
|
|
70
|
-
getAllSessions = async (
|
|
70
|
+
getAllSessions = async () => {
|
|
71
71
|
const sessions = Array.from(this.browsers);
|
|
72
|
-
const requestToken = getTokenFromRequest(req);
|
|
73
|
-
const token = this.config.getToken();
|
|
74
|
-
if (token && !requestToken) {
|
|
75
|
-
throw new BadRequest(`Couldn't locate your API token`);
|
|
76
|
-
}
|
|
77
72
|
return sessions.map(([browser, session]) => this.generateSessionJson(browser, session));
|
|
78
73
|
};
|
|
79
74
|
complete = async (browser) => {
|
|
@@ -113,11 +108,6 @@ export class BrowserManager {
|
|
|
113
108
|
catch (err) {
|
|
114
109
|
throw new BadRequest(`Error parsing launch-options: ${err}. Launch options must be a JSON or base64-encoded JSON object`);
|
|
115
110
|
}
|
|
116
|
-
const requestToken = getTokenFromRequest(req);
|
|
117
|
-
const token = this.config.getToken();
|
|
118
|
-
if (token && !requestToken) {
|
|
119
|
-
throw new ServerError(`Error locating authorization token`);
|
|
120
|
-
}
|
|
121
111
|
const routerOptions = typeof router.defaultLaunchOptions === 'function'
|
|
122
112
|
? router.defaultLaunchOptions(req)
|
|
123
113
|
: router.defaultLaunchOptions;
|
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="debug" />
|
|
3
|
+
/// <reference types="node" />
|
|
2
4
|
/// <reference types="node" />
|
|
3
5
|
/// <reference types="node" />
|
|
4
6
|
import { BrowserServerOptions, Config, Request } from '@browserless.io/browserless';
|
|
5
7
|
import playwright, { Page } from 'playwright-core';
|
|
6
8
|
import { Duplex } from 'stream';
|
|
7
9
|
import { EventEmitter } from 'events';
|
|
10
|
+
import httpProxy from 'http-proxy';
|
|
8
11
|
export declare class PlaywrightChromium extends EventEmitter {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
protected config: Config;
|
|
13
|
+
protected userDataDir: string | null;
|
|
14
|
+
protected record: boolean;
|
|
15
|
+
protected running: boolean;
|
|
16
|
+
protected proxy: httpProxy<import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>>;
|
|
17
|
+
protected browser: playwright.BrowserServer | null;
|
|
18
|
+
protected browserWSEndpoint: string | null;
|
|
19
|
+
protected debug: import("debug").Debugger;
|
|
17
20
|
constructor({ config, userDataDir, record, }: {
|
|
18
21
|
config: Config;
|
|
19
22
|
record: boolean;
|
|
20
23
|
userDataDir: PlaywrightChromium['userDataDir'];
|
|
21
24
|
});
|
|
22
|
-
|
|
25
|
+
protected cleanListeners(): void;
|
|
23
26
|
isRunning: () => boolean;
|
|
24
27
|
close: () => Promise<void>;
|
|
25
28
|
pages: () => Promise<[]>;
|
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="debug" />
|
|
3
|
+
/// <reference types="node" />
|
|
2
4
|
/// <reference types="node" />
|
|
3
5
|
/// <reference types="node" />
|
|
4
6
|
import { BrowserServerOptions, Config, Request } from '@browserless.io/browserless';
|
|
5
7
|
import playwright, { Page } from 'playwright-core';
|
|
6
8
|
import { Duplex } from 'stream';
|
|
7
9
|
import { EventEmitter } from 'events';
|
|
10
|
+
import httpProxy from 'http-proxy';
|
|
8
11
|
export declare class PlaywrightFirefox extends EventEmitter {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
protected config: Config;
|
|
13
|
+
protected userDataDir: string | null;
|
|
14
|
+
protected record: boolean;
|
|
15
|
+
protected running: boolean;
|
|
16
|
+
protected proxy: httpProxy<import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>>;
|
|
17
|
+
protected browser: playwright.BrowserServer | null;
|
|
18
|
+
protected browserWSEndpoint: string | null;
|
|
19
|
+
protected debug: import("debug").Debugger;
|
|
17
20
|
constructor({ config, userDataDir, record, }: {
|
|
18
21
|
config: Config;
|
|
19
22
|
record: boolean;
|
|
20
23
|
userDataDir: PlaywrightFirefox['userDataDir'];
|
|
21
24
|
});
|
|
22
|
-
|
|
25
|
+
protected cleanListeners(): void;
|
|
23
26
|
isRunning: () => boolean;
|
|
24
27
|
close: () => Promise<void>;
|
|
25
28
|
pages: () => Promise<[]>;
|
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="debug" />
|
|
3
|
+
/// <reference types="node" />
|
|
2
4
|
/// <reference types="node" />
|
|
3
5
|
/// <reference types="node" />
|
|
4
6
|
import { BrowserServerOptions, Config, Request } from '@browserless.io/browserless';
|
|
5
7
|
import playwright, { Page } from 'playwright-core';
|
|
6
8
|
import { Duplex } from 'stream';
|
|
7
9
|
import { EventEmitter } from 'events';
|
|
10
|
+
import httpProxy from 'http-proxy';
|
|
8
11
|
export declare class PlaywrightWebkit extends EventEmitter {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
protected config: Config;
|
|
13
|
+
protected userDataDir: string | null;
|
|
14
|
+
protected record: boolean;
|
|
15
|
+
protected running: boolean;
|
|
16
|
+
protected proxy: httpProxy<import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>>;
|
|
17
|
+
protected browser: playwright.BrowserServer | null;
|
|
18
|
+
protected browserWSEndpoint: string | null;
|
|
19
|
+
protected debug: import("debug").Debugger;
|
|
17
20
|
constructor({ config, userDataDir, record, }: {
|
|
18
21
|
config: Config;
|
|
19
22
|
record: boolean;
|
|
20
23
|
userDataDir: PlaywrightWebkit['userDataDir'];
|
|
21
24
|
});
|
|
22
|
-
|
|
25
|
+
protected cleanListeners(): void;
|
|
23
26
|
isRunning: () => boolean;
|
|
24
27
|
close: () => Promise<void>;
|
|
25
28
|
pages: () => Promise<[]>;
|