@browserless.io/browserless 2.15.0 → 2.16.0-beta-1
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/README.md +7 -6
- package/build/browsers/browsers.cdp.d.ts +1 -1
- package/build/browsers/browsers.cdp.js +12 -10
- package/build/browsers/index.js +1 -1
- package/build/limiter.spec.js +19 -0
- package/build/routes/chrome/http/content.post.body.json +8 -8
- 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/pdf.post.body.json +8 -8
- package/build/routes/chromium/http/scrape.post.body.json +8 -8
- package/build/routes/chromium/http/screenshot.post.body.json +8 -8
- package/build/utils.d.ts +1 -0
- package/build/utils.js +5 -1
- package/package.json +5 -5
- package/scripts/build-schemas.js +7 -3
- package/src/browsers/browsers.cdp.ts +25 -18
- package/src/browsers/browsers.playwright.ts +12 -5
- package/src/browsers/index.ts +1 -1
- package/src/limiter.spec.ts +27 -0
- package/src/utils.ts +8 -2
- package/static/docs/swagger.json +10 -10
- package/static/docs/swagger.min.json +9 -9
package/README.md
CHANGED
|
@@ -39,7 +39,6 @@ If you've been struggling to deploy headless browsers without running into issue
|
|
|
39
39
|
1. [Full documentation site](https://docs.browserless.io/)
|
|
40
40
|
2. [Live Debugger (using browserless.io)](https://chrome.browserless.io/)
|
|
41
41
|
3. [Docker](https://github.com/browserless/browserless/pkgs/container/base)
|
|
42
|
-
4. [Slack](https://join.slack.com/t/browserless/shared_invite/enQtMzA3OTMwNjA3MzY1LTRmMWU5NjQ0MTQ2YTE2YmU3MzdjNmVlMmU4MThjM2UxODNmNzNlZjVkY2U2NjdkMzYyNTgyZTBiMmE3Nzg0MzY)
|
|
43
42
|
|
|
44
43
|
## Features
|
|
45
44
|
|
|
@@ -54,14 +53,16 @@ If you've been struggling to deploy headless browsers without running into issue
|
|
|
54
53
|
- Error tolerant: if Chrome dies it won't.
|
|
55
54
|
- Support for running and development on Apple's M1 machines
|
|
56
55
|
|
|
57
|
-
### Cloud
|
|
56
|
+
### Cloud-only
|
|
58
57
|
|
|
59
58
|
Our [cloud accounts](https://www.browserless.io/pricing/) include all the general features plus extras, such as:
|
|
60
59
|
|
|
61
|
-
- Inbuilt [residential proxy](https://www.browserless.io/blog/
|
|
62
|
-
- [/unblock API](https://www.browserless.io/blog/
|
|
63
|
-
- [
|
|
64
|
-
-
|
|
60
|
+
- Inbuilt [residential proxy](https://www.browserless.io/blog/residential-proxying/)
|
|
61
|
+
- [/unblock API](https://www.browserless.io/blog/unblock-api) for avoiding detectors
|
|
62
|
+
- [Automated captcha solving](https://www.browserless.io/blog/captcha-solving) for getting past mandatory checks
|
|
63
|
+
- [Hybrid automations](https://www.browserless.io/blog/hybrid-automations-for-puppeteer/) for streaming login windows during scripts
|
|
64
|
+
- [/reconnect API](https://www.browserless.io/blog/reconnect-api) for keeping browsers alive for reuse
|
|
65
|
+
- [REST APIs](https://www.browserless.io/feature/rest-apis) for tasks such as retrieving HTML, PDFs or Lighthouse metrics
|
|
65
66
|
- SSO, tokens and user roles
|
|
66
67
|
|
|
67
68
|
## How it works
|
|
@@ -29,7 +29,7 @@ export declare class ChromiumCDP extends EventEmitter {
|
|
|
29
29
|
close(): Promise<void>;
|
|
30
30
|
pages(): Promise<Page[]>;
|
|
31
31
|
process(): import("child_process").ChildProcess | null;
|
|
32
|
-
launch(
|
|
32
|
+
launch({ options, stealth, }: BrowserLauncherOptions): Promise<Browser>;
|
|
33
33
|
wsEndpoint(): string | null;
|
|
34
34
|
publicWSEndpoint(token: string | null): string | null;
|
|
35
35
|
proxyPageWebSocket(req: Request, socket: Duplex, head: Buffer): Promise<void>;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { BLESS_PAGE_IDENTIFIER, ServerError, chromeExecutablePath, noop, once, } from '@browserless.io/browserless';
|
|
1
|
+
import { BLESS_PAGE_IDENTIFIER, ServerError, chromeExecutablePath, noop, once, ublockPath, } from '@browserless.io/browserless';
|
|
2
2
|
import puppeteer from 'puppeteer-core';
|
|
3
3
|
import { EventEmitter } from 'events';
|
|
4
4
|
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
5
|
import getPort from 'get-port';
|
|
7
6
|
import httpProxy from 'http-proxy';
|
|
8
7
|
import path from 'path';
|
|
@@ -111,11 +110,17 @@ export class ChromiumCDP extends EventEmitter {
|
|
|
111
110
|
process() {
|
|
112
111
|
return this.browser?.process() || null;
|
|
113
112
|
}
|
|
114
|
-
async launch(
|
|
115
|
-
const { options, stealth } = laucherOpts;
|
|
113
|
+
async launch({ options, stealth, }) {
|
|
116
114
|
this.port = await getPort();
|
|
117
115
|
this.logger.info(`${this.constructor.name} got open port ${this.port}`);
|
|
118
|
-
const
|
|
116
|
+
const extensionLaunchArgs = options.args?.find((a) => a.startsWith('--load-extension'));
|
|
117
|
+
// Remove extension flags as we recompile them below with our own
|
|
118
|
+
options.args = options.args?.filter((a) => !a.startsWith('--load-extension') &&
|
|
119
|
+
!a.startsWith('--disable-extensions-except'));
|
|
120
|
+
const extensions = [
|
|
121
|
+
this.blockAds ? ublockPath : null,
|
|
122
|
+
extensionLaunchArgs ? extensionLaunchArgs.split('=')[1] : null,
|
|
123
|
+
].filter((_) => !!_);
|
|
119
124
|
const finalOptions = {
|
|
120
125
|
...options,
|
|
121
126
|
args: [
|
|
@@ -126,11 +131,8 @@ export class ChromiumCDP extends EventEmitter {
|
|
|
126
131
|
].filter((_) => !!_),
|
|
127
132
|
executablePath: this.executablePath,
|
|
128
133
|
};
|
|
129
|
-
if (
|
|
130
|
-
|
|
131
|
-
finalOptions.headless = false;
|
|
132
|
-
const loadExtensionPaths = path.join(__dirname, '..', '..', 'extensions', 'ublock');
|
|
133
|
-
finalOptions.args.push('--load-extension=' + loadExtensionPaths, '--disable-extensions-except=' + loadExtensionPaths);
|
|
134
|
+
if (extensions.length) {
|
|
135
|
+
finalOptions.args.push('--load-extension=' + extensions.join(','), '--disable-extensions-except=' + extensions.join(','));
|
|
134
136
|
}
|
|
135
137
|
const launch = stealth
|
|
136
138
|
? puppeteerStealth.launch.bind(puppeteerStealth)
|
package/build/browsers/index.js
CHANGED
package/build/limiter.spec.js
CHANGED
|
@@ -91,6 +91,25 @@ describe(`Limiter`, () => {
|
|
|
91
91
|
await wait;
|
|
92
92
|
expect(handlerTwo.calledOnce).to.be.true;
|
|
93
93
|
});
|
|
94
|
+
it('continues to process jobs even if an earlier job errors', (d) => {
|
|
95
|
+
const config = new Config();
|
|
96
|
+
const monitoring = new Monitoring(config);
|
|
97
|
+
const metrics = new Metrics();
|
|
98
|
+
config.setConcurrent(1);
|
|
99
|
+
config.setQueued(1);
|
|
100
|
+
config.setTimeout(-1);
|
|
101
|
+
const limiter = new Limiter(config, metrics, monitoring, webHooks, hooks);
|
|
102
|
+
const errorJob = () => Promise.reject(new Error('Danger, danger. High voltage!'));
|
|
103
|
+
const okJob = spy();
|
|
104
|
+
const jobOne = limiter.limit(errorJob, asyncNoop, asyncNoop, noop);
|
|
105
|
+
const jobTwo = limiter.limit(okJob, asyncNoop, asyncNoop, noop);
|
|
106
|
+
jobOne();
|
|
107
|
+
jobTwo();
|
|
108
|
+
limiter.addEventListener('end', () => {
|
|
109
|
+
expect(okJob.calledOnce).to.be.true;
|
|
110
|
+
d(undefined);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
94
113
|
it('bubbles up errors', async () => {
|
|
95
114
|
const config = new Config();
|
|
96
115
|
const monitoring = new Monitoring(config);
|
|
@@ -408,14 +408,14 @@
|
|
|
408
408
|
"length": {
|
|
409
409
|
"type": "number"
|
|
410
410
|
},
|
|
411
|
-
"__@toStringTag@
|
|
411
|
+
"__@toStringTag@11070": {
|
|
412
412
|
"type": "string",
|
|
413
413
|
"const": "Uint8Array"
|
|
414
414
|
}
|
|
415
415
|
},
|
|
416
416
|
"required": [
|
|
417
417
|
"BYTES_PER_ELEMENT",
|
|
418
|
-
"__@toStringTag@
|
|
418
|
+
"__@toStringTag@11070",
|
|
419
419
|
"buffer",
|
|
420
420
|
"byteLength",
|
|
421
421
|
"byteOffset",
|
|
@@ -450,13 +450,13 @@
|
|
|
450
450
|
"byteLength": {
|
|
451
451
|
"type": "number"
|
|
452
452
|
},
|
|
453
|
-
"__@toStringTag@
|
|
453
|
+
"__@toStringTag@11070": {
|
|
454
454
|
"type": "string"
|
|
455
455
|
}
|
|
456
456
|
},
|
|
457
457
|
"additionalProperties": false,
|
|
458
458
|
"required": [
|
|
459
|
-
"__@toStringTag@
|
|
459
|
+
"__@toStringTag@11070",
|
|
460
460
|
"byteLength"
|
|
461
461
|
]
|
|
462
462
|
},
|
|
@@ -466,18 +466,18 @@
|
|
|
466
466
|
"byteLength": {
|
|
467
467
|
"type": "number"
|
|
468
468
|
},
|
|
469
|
-
"__@species@
|
|
469
|
+
"__@species@11171": {
|
|
470
470
|
"$ref": "#/definitions/SharedArrayBuffer"
|
|
471
471
|
},
|
|
472
|
-
"__@toStringTag@
|
|
472
|
+
"__@toStringTag@11070": {
|
|
473
473
|
"type": "string",
|
|
474
474
|
"const": "SharedArrayBuffer"
|
|
475
475
|
}
|
|
476
476
|
},
|
|
477
477
|
"additionalProperties": false,
|
|
478
478
|
"required": [
|
|
479
|
-
"__@species@
|
|
480
|
-
"__@toStringTag@
|
|
479
|
+
"__@species@11171",
|
|
480
|
+
"__@toStringTag@11070",
|
|
481
481
|
"byteLength"
|
|
482
482
|
]
|
|
483
483
|
},
|
|
@@ -455,14 +455,14 @@
|
|
|
455
455
|
"length": {
|
|
456
456
|
"type": "number"
|
|
457
457
|
},
|
|
458
|
-
"__@toStringTag@
|
|
458
|
+
"__@toStringTag@110224": {
|
|
459
459
|
"type": "string",
|
|
460
460
|
"const": "Uint8Array"
|
|
461
461
|
}
|
|
462
462
|
},
|
|
463
463
|
"required": [
|
|
464
464
|
"BYTES_PER_ELEMENT",
|
|
465
|
-
"__@toStringTag@
|
|
465
|
+
"__@toStringTag@110224",
|
|
466
466
|
"buffer",
|
|
467
467
|
"byteLength",
|
|
468
468
|
"byteOffset",
|
|
@@ -497,13 +497,13 @@
|
|
|
497
497
|
"byteLength": {
|
|
498
498
|
"type": "number"
|
|
499
499
|
},
|
|
500
|
-
"__@toStringTag@
|
|
500
|
+
"__@toStringTag@110224": {
|
|
501
501
|
"type": "string"
|
|
502
502
|
}
|
|
503
503
|
},
|
|
504
504
|
"additionalProperties": false,
|
|
505
505
|
"required": [
|
|
506
|
-
"__@toStringTag@
|
|
506
|
+
"__@toStringTag@110224",
|
|
507
507
|
"byteLength"
|
|
508
508
|
]
|
|
509
509
|
},
|
|
@@ -513,18 +513,18 @@
|
|
|
513
513
|
"byteLength": {
|
|
514
514
|
"type": "number"
|
|
515
515
|
},
|
|
516
|
-
"__@species@
|
|
516
|
+
"__@species@110325": {
|
|
517
517
|
"$ref": "#/definitions/SharedArrayBuffer"
|
|
518
518
|
},
|
|
519
|
-
"__@toStringTag@
|
|
519
|
+
"__@toStringTag@110224": {
|
|
520
520
|
"type": "string",
|
|
521
521
|
"const": "SharedArrayBuffer"
|
|
522
522
|
}
|
|
523
523
|
},
|
|
524
524
|
"additionalProperties": false,
|
|
525
525
|
"required": [
|
|
526
|
-
"__@species@
|
|
527
|
-
"__@toStringTag@
|
|
526
|
+
"__@species@110325",
|
|
527
|
+
"__@toStringTag@110224",
|
|
528
528
|
"byteLength"
|
|
529
529
|
]
|
|
530
530
|
},
|
|
@@ -498,14 +498,14 @@
|
|
|
498
498
|
"length": {
|
|
499
499
|
"type": "number"
|
|
500
500
|
},
|
|
501
|
-
"__@toStringTag@
|
|
501
|
+
"__@toStringTag@121528": {
|
|
502
502
|
"type": "string",
|
|
503
503
|
"const": "Uint8Array"
|
|
504
504
|
}
|
|
505
505
|
},
|
|
506
506
|
"required": [
|
|
507
507
|
"BYTES_PER_ELEMENT",
|
|
508
|
-
"__@toStringTag@
|
|
508
|
+
"__@toStringTag@121528",
|
|
509
509
|
"buffer",
|
|
510
510
|
"byteLength",
|
|
511
511
|
"byteOffset",
|
|
@@ -540,13 +540,13 @@
|
|
|
540
540
|
"byteLength": {
|
|
541
541
|
"type": "number"
|
|
542
542
|
},
|
|
543
|
-
"__@toStringTag@
|
|
543
|
+
"__@toStringTag@121528": {
|
|
544
544
|
"type": "string"
|
|
545
545
|
}
|
|
546
546
|
},
|
|
547
547
|
"additionalProperties": false,
|
|
548
548
|
"required": [
|
|
549
|
-
"__@toStringTag@
|
|
549
|
+
"__@toStringTag@121528",
|
|
550
550
|
"byteLength"
|
|
551
551
|
]
|
|
552
552
|
},
|
|
@@ -556,18 +556,18 @@
|
|
|
556
556
|
"byteLength": {
|
|
557
557
|
"type": "number"
|
|
558
558
|
},
|
|
559
|
-
"__@species@
|
|
559
|
+
"__@species@121629": {
|
|
560
560
|
"$ref": "#/definitions/SharedArrayBuffer"
|
|
561
561
|
},
|
|
562
|
-
"__@toStringTag@
|
|
562
|
+
"__@toStringTag@121528": {
|
|
563
563
|
"type": "string",
|
|
564
564
|
"const": "SharedArrayBuffer"
|
|
565
565
|
}
|
|
566
566
|
},
|
|
567
567
|
"additionalProperties": false,
|
|
568
568
|
"required": [
|
|
569
|
-
"__@species@
|
|
570
|
-
"__@toStringTag@
|
|
569
|
+
"__@species@121629",
|
|
570
|
+
"__@toStringTag@121528",
|
|
571
571
|
"byteLength"
|
|
572
572
|
]
|
|
573
573
|
},
|
|
@@ -549,14 +549,14 @@
|
|
|
549
549
|
"length": {
|
|
550
550
|
"type": "number"
|
|
551
551
|
},
|
|
552
|
-
"__@toStringTag@
|
|
552
|
+
"__@toStringTag@187784": {
|
|
553
553
|
"type": "string",
|
|
554
554
|
"const": "Uint8Array"
|
|
555
555
|
}
|
|
556
556
|
},
|
|
557
557
|
"required": [
|
|
558
558
|
"BYTES_PER_ELEMENT",
|
|
559
|
-
"__@toStringTag@
|
|
559
|
+
"__@toStringTag@187784",
|
|
560
560
|
"buffer",
|
|
561
561
|
"byteLength",
|
|
562
562
|
"byteOffset",
|
|
@@ -591,13 +591,13 @@
|
|
|
591
591
|
"byteLength": {
|
|
592
592
|
"type": "number"
|
|
593
593
|
},
|
|
594
|
-
"__@toStringTag@
|
|
594
|
+
"__@toStringTag@187784": {
|
|
595
595
|
"type": "string"
|
|
596
596
|
}
|
|
597
597
|
},
|
|
598
598
|
"additionalProperties": false,
|
|
599
599
|
"required": [
|
|
600
|
-
"__@toStringTag@
|
|
600
|
+
"__@toStringTag@187784",
|
|
601
601
|
"byteLength"
|
|
602
602
|
]
|
|
603
603
|
},
|
|
@@ -607,18 +607,18 @@
|
|
|
607
607
|
"byteLength": {
|
|
608
608
|
"type": "number"
|
|
609
609
|
},
|
|
610
|
-
"__@species@
|
|
610
|
+
"__@species@187885": {
|
|
611
611
|
"$ref": "#/definitions/SharedArrayBuffer"
|
|
612
612
|
},
|
|
613
|
-
"__@toStringTag@
|
|
613
|
+
"__@toStringTag@187784": {
|
|
614
614
|
"type": "string",
|
|
615
615
|
"const": "SharedArrayBuffer"
|
|
616
616
|
}
|
|
617
617
|
},
|
|
618
618
|
"additionalProperties": false,
|
|
619
619
|
"required": [
|
|
620
|
-
"__@species@
|
|
621
|
-
"__@toStringTag@
|
|
620
|
+
"__@species@187885",
|
|
621
|
+
"__@toStringTag@187784",
|
|
622
622
|
"byteLength"
|
|
623
623
|
]
|
|
624
624
|
},
|
|
@@ -455,14 +455,14 @@
|
|
|
455
455
|
"length": {
|
|
456
456
|
"type": "number"
|
|
457
457
|
},
|
|
458
|
-
"__@toStringTag@
|
|
458
|
+
"__@toStringTag@231869": {
|
|
459
459
|
"type": "string",
|
|
460
460
|
"const": "Uint8Array"
|
|
461
461
|
}
|
|
462
462
|
},
|
|
463
463
|
"required": [
|
|
464
464
|
"BYTES_PER_ELEMENT",
|
|
465
|
-
"__@toStringTag@
|
|
465
|
+
"__@toStringTag@231869",
|
|
466
466
|
"buffer",
|
|
467
467
|
"byteLength",
|
|
468
468
|
"byteOffset",
|
|
@@ -497,13 +497,13 @@
|
|
|
497
497
|
"byteLength": {
|
|
498
498
|
"type": "number"
|
|
499
499
|
},
|
|
500
|
-
"__@toStringTag@
|
|
500
|
+
"__@toStringTag@231869": {
|
|
501
501
|
"type": "string"
|
|
502
502
|
}
|
|
503
503
|
},
|
|
504
504
|
"additionalProperties": false,
|
|
505
505
|
"required": [
|
|
506
|
-
"__@toStringTag@
|
|
506
|
+
"__@toStringTag@231869",
|
|
507
507
|
"byteLength"
|
|
508
508
|
]
|
|
509
509
|
},
|
|
@@ -513,18 +513,18 @@
|
|
|
513
513
|
"byteLength": {
|
|
514
514
|
"type": "number"
|
|
515
515
|
},
|
|
516
|
-
"__@species@
|
|
516
|
+
"__@species@231970": {
|
|
517
517
|
"$ref": "#/definitions/SharedArrayBuffer"
|
|
518
518
|
},
|
|
519
|
-
"__@toStringTag@
|
|
519
|
+
"__@toStringTag@231869": {
|
|
520
520
|
"type": "string",
|
|
521
521
|
"const": "SharedArrayBuffer"
|
|
522
522
|
}
|
|
523
523
|
},
|
|
524
524
|
"additionalProperties": false,
|
|
525
525
|
"required": [
|
|
526
|
-
"__@species@
|
|
527
|
-
"__@toStringTag@
|
|
526
|
+
"__@species@231970",
|
|
527
|
+
"__@toStringTag@231869",
|
|
528
528
|
"byteLength"
|
|
529
529
|
]
|
|
530
530
|
},
|
|
@@ -498,14 +498,14 @@
|
|
|
498
498
|
"length": {
|
|
499
499
|
"type": "number"
|
|
500
500
|
},
|
|
501
|
-
"__@toStringTag@
|
|
501
|
+
"__@toStringTag@243170": {
|
|
502
502
|
"type": "string",
|
|
503
503
|
"const": "Uint8Array"
|
|
504
504
|
}
|
|
505
505
|
},
|
|
506
506
|
"required": [
|
|
507
507
|
"BYTES_PER_ELEMENT",
|
|
508
|
-
"__@toStringTag@
|
|
508
|
+
"__@toStringTag@243170",
|
|
509
509
|
"buffer",
|
|
510
510
|
"byteLength",
|
|
511
511
|
"byteOffset",
|
|
@@ -540,13 +540,13 @@
|
|
|
540
540
|
"byteLength": {
|
|
541
541
|
"type": "number"
|
|
542
542
|
},
|
|
543
|
-
"__@toStringTag@
|
|
543
|
+
"__@toStringTag@243170": {
|
|
544
544
|
"type": "string"
|
|
545
545
|
}
|
|
546
546
|
},
|
|
547
547
|
"additionalProperties": false,
|
|
548
548
|
"required": [
|
|
549
|
-
"__@toStringTag@
|
|
549
|
+
"__@toStringTag@243170",
|
|
550
550
|
"byteLength"
|
|
551
551
|
]
|
|
552
552
|
},
|
|
@@ -556,18 +556,18 @@
|
|
|
556
556
|
"byteLength": {
|
|
557
557
|
"type": "number"
|
|
558
558
|
},
|
|
559
|
-
"__@species@
|
|
559
|
+
"__@species@243271": {
|
|
560
560
|
"$ref": "#/definitions/SharedArrayBuffer"
|
|
561
561
|
},
|
|
562
|
-
"__@toStringTag@
|
|
562
|
+
"__@toStringTag@243170": {
|
|
563
563
|
"type": "string",
|
|
564
564
|
"const": "SharedArrayBuffer"
|
|
565
565
|
}
|
|
566
566
|
},
|
|
567
567
|
"additionalProperties": false,
|
|
568
568
|
"required": [
|
|
569
|
-
"__@species@
|
|
570
|
-
"__@toStringTag@
|
|
569
|
+
"__@species@243271",
|
|
570
|
+
"__@toStringTag@243170",
|
|
571
571
|
"byteLength"
|
|
572
572
|
]
|
|
573
573
|
},
|
package/build/utils.d.ts
CHANGED
|
@@ -128,4 +128,5 @@ export declare const fetchTimeout: (input: RequestInfo | URL, initWithTimeout?:
|
|
|
128
128
|
export declare const untildify: (path: string) => string;
|
|
129
129
|
export declare const printLogo: (docsLink: string, debugURL?: string | boolean) => string;
|
|
130
130
|
export declare const getCDPClient: (page: Page) => CDPSession;
|
|
131
|
+
export declare const ublockPath: string;
|
|
131
132
|
export {};
|
package/build/utils.js
CHANGED
|
@@ -3,12 +3,14 @@ import { BLESS_PAGE_IDENTIFIER, ChromeCDP, ChromePlaywright, ChromiumCDP, Chromi
|
|
|
3
3
|
import playwright from 'playwright-core';
|
|
4
4
|
import crypto from 'crypto';
|
|
5
5
|
import debug from 'debug';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
6
7
|
import gradient from 'gradient-string';
|
|
7
8
|
import { homedir } from 'os';
|
|
8
9
|
import path from 'path';
|
|
9
10
|
const isHTTP = (writeable) => {
|
|
10
11
|
return writeable.writeHead !== undefined;
|
|
11
12
|
};
|
|
13
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
12
14
|
const getAuthHeaderToken = (header) => {
|
|
13
15
|
if (header.startsWith('Basic')) {
|
|
14
16
|
const username = header.split(/\s+/).pop() || '';
|
|
@@ -332,7 +334,8 @@ export const availableBrowsers = Promise.all([
|
|
|
332
334
|
return availableBrowsers;
|
|
333
335
|
});
|
|
334
336
|
export const queryParamsToObject = (params) => [...params.entries()].reduce((accum, [key, value]) => {
|
|
335
|
-
accum[key] =
|
|
337
|
+
accum[key] =
|
|
338
|
+
value === '' || value === undefined || value === null ? true : value;
|
|
336
339
|
return accum;
|
|
337
340
|
}, {});
|
|
338
341
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
@@ -609,3 +612,4 @@ export const getCDPClient = (page) => {
|
|
|
609
612
|
const c = page._client;
|
|
610
613
|
return typeof c === 'function' ? c.call(page) : c;
|
|
611
614
|
};
|
|
615
|
+
export const ublockPath = path.join(__dirname, '..', 'extensions', 'ublock');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@browserless.io/browserless",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.16.0-beta-1",
|
|
4
4
|
"license": "SSPL",
|
|
5
5
|
"description": "The browserless platform",
|
|
6
6
|
"author": "browserless.io",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"debug": "^4.3.5",
|
|
52
52
|
"del": "^7.0.0",
|
|
53
53
|
"enjoi": "^9.0.1",
|
|
54
|
-
"file-type": "^19.
|
|
54
|
+
"file-type": "^19.1.0",
|
|
55
55
|
"get-port": "^7.1.0",
|
|
56
56
|
"gradient-string": "^2.0.0",
|
|
57
57
|
"http-proxy": "^1.18.1",
|
|
@@ -76,10 +76,10 @@
|
|
|
76
76
|
"@types/http-proxy": "^1.17.14",
|
|
77
77
|
"@types/micromatch": "^4.0.9",
|
|
78
78
|
"@types/mocha": "^10.0.7",
|
|
79
|
-
"@types/node": "^20.14.
|
|
79
|
+
"@types/node": "^20.14.10",
|
|
80
80
|
"@types/sinon": "^17.0.3",
|
|
81
81
|
"@typescript-eslint/eslint-plugin": "^7.15.0",
|
|
82
|
-
"@typescript-eslint/parser": "^7.
|
|
82
|
+
"@typescript-eslint/parser": "^7.16.0",
|
|
83
83
|
"assert": "^2.0.0",
|
|
84
84
|
"chai": "^5.1.1",
|
|
85
85
|
"cross-env": "^7.0.3",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"eslint-plugin-typescript-sort-keys": "^3.2.0",
|
|
91
91
|
"extract-zip": "^2.0.1",
|
|
92
92
|
"gunzip-maybe": "^1.4.2",
|
|
93
|
-
"marked": "^13.0.
|
|
93
|
+
"marked": "^13.0.2",
|
|
94
94
|
"mocha": "^10.6.0",
|
|
95
95
|
"move-file": "^3.1.0",
|
|
96
96
|
"prettier": "^3.3.2",
|
package/scripts/build-schemas.js
CHANGED
|
@@ -12,7 +12,7 @@ const moduleMain = path.normalize(import.meta.url).endsWith(process.argv[1]);
|
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Find an exported interface in a TypeScript AST
|
|
15
|
-
*
|
|
15
|
+
*
|
|
16
16
|
* @param {ts.Node} node The node to search for the exported interface
|
|
17
17
|
* @param {string} interfaceName The name of the interface to search for
|
|
18
18
|
* @returns {ts.InterfaceDeclaration | ts.Identifier | null}
|
|
@@ -29,7 +29,11 @@ const findExportedInterface = (node, interfaceName) => {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
// Check for re-exported interfaces
|
|
32
|
-
if (
|
|
32
|
+
if (
|
|
33
|
+
ts.isExportDeclaration(node) &&
|
|
34
|
+
node.exportClause &&
|
|
35
|
+
ts.isNamedExports(node.exportClause)
|
|
36
|
+
) {
|
|
33
37
|
const elements = node.exportClause.elements;
|
|
34
38
|
for (const element of elements) {
|
|
35
39
|
if (element.name.text === interfaceName) {
|
|
@@ -50,7 +54,7 @@ const findExportedInterface = (node, interfaceName) => {
|
|
|
50
54
|
|
|
51
55
|
/**
|
|
52
56
|
* Creates an standard JSON schema file for each route (see https://json-schema.org/specification)
|
|
53
|
-
*
|
|
57
|
+
*
|
|
54
58
|
* @param {string[]} externalHTTPRoutes Additional HTTP routes to parse
|
|
55
59
|
* @param {string[]} externalWebSocketRoutes Additional WS routes to parse
|
|
56
60
|
*/
|
|
@@ -8,12 +8,12 @@ import {
|
|
|
8
8
|
chromeExecutablePath,
|
|
9
9
|
noop,
|
|
10
10
|
once,
|
|
11
|
+
ublockPath,
|
|
11
12
|
} from '@browserless.io/browserless';
|
|
12
13
|
import puppeteer, { Browser, Page, Target } from 'puppeteer-core';
|
|
13
14
|
import { Duplex } from 'stream';
|
|
14
15
|
import { EventEmitter } from 'events';
|
|
15
16
|
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
|
|
16
|
-
import { fileURLToPath } from 'url';
|
|
17
17
|
import getPort from 'get-port';
|
|
18
18
|
import httpProxy from 'http-proxy';
|
|
19
19
|
import path from 'path';
|
|
@@ -170,11 +170,29 @@ export class ChromiumCDP extends EventEmitter {
|
|
|
170
170
|
return this.browser?.process() || null;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
public async launch(
|
|
174
|
-
|
|
173
|
+
public async launch({
|
|
174
|
+
options,
|
|
175
|
+
stealth,
|
|
176
|
+
}: BrowserLauncherOptions): Promise<Browser> {
|
|
175
177
|
this.port = await getPort();
|
|
176
178
|
this.logger.info(`${this.constructor.name} got open port ${this.port}`);
|
|
177
|
-
|
|
179
|
+
|
|
180
|
+
const extensionLaunchArgs = options.args?.find((a) =>
|
|
181
|
+
a.startsWith('--load-extension'),
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
// Remove extension flags as we recompile them below with our own
|
|
185
|
+
options.args = options.args?.filter(
|
|
186
|
+
(a) =>
|
|
187
|
+
!a.startsWith('--load-extension') &&
|
|
188
|
+
!a.startsWith('--disable-extensions-except'),
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
const extensions = [
|
|
192
|
+
this.blockAds ? ublockPath : null,
|
|
193
|
+
extensionLaunchArgs ? extensionLaunchArgs.split('=')[1] : null,
|
|
194
|
+
].filter((_) => !!_);
|
|
195
|
+
|
|
178
196
|
const finalOptions = {
|
|
179
197
|
...options,
|
|
180
198
|
args: [
|
|
@@ -186,21 +204,10 @@ export class ChromiumCDP extends EventEmitter {
|
|
|
186
204
|
executablePath: this.executablePath,
|
|
187
205
|
};
|
|
188
206
|
|
|
189
|
-
if (
|
|
190
|
-
// Necessary to load extensions
|
|
191
|
-
finalOptions.headless = false;
|
|
192
|
-
|
|
193
|
-
const loadExtensionPaths: string = path.join(
|
|
194
|
-
__dirname,
|
|
195
|
-
'..',
|
|
196
|
-
'..',
|
|
197
|
-
'extensions',
|
|
198
|
-
'ublock',
|
|
199
|
-
);
|
|
200
|
-
|
|
207
|
+
if (extensions.length) {
|
|
201
208
|
finalOptions.args.push(
|
|
202
|
-
'--load-extension=' +
|
|
203
|
-
'--disable-extensions-except=' +
|
|
209
|
+
'--load-extension=' + extensions.join(','),
|
|
210
|
+
'--disable-extensions-except=' + extensions.join(','),
|
|
204
211
|
);
|
|
205
212
|
}
|
|
206
213
|
|