@browserless.io/browserless 2.15.0 → 2.16.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 CHANGED
@@ -1,6 +1,12 @@
1
- # [Latest](https://github.com/browserless/chrome/compare/v2.15.0...main)
1
+ # [Latest](https://github.com/browserless/chrome/compare/v2.16.0...main)
2
2
  - Dependency updates.
3
3
 
4
+ # [v2.16.0](https://github.com/browserless/chrome/compare/v2.15.0...v2.16.0)
5
+ - Dependency updates.
6
+ - Better extension handling and merging when passing in custom extensions.
7
+ - Fixes a bug where a failed job (error thrown) causes the internal queue to drain.
8
+ - Prettier and other source improvements.
9
+
4
10
  # [v2.15.0](https://github.com/browserless/chrome/compare/v2.14.0...v2.15.0)
5
11
  - Bug fix to avoid removing healthy jobs from limiter when a job fails
6
12
  - Dependency updates.
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/2023/09/24/residential-proxying/)
62
- - [/unblock API](https://www.browserless.io/blog/2024/02/26/unblock-api/) for avoiding detectors
63
- - [Hybrid automations](https://www.browserless.io/blog/2024/03/21/hybrid-automations-for-puppeteer/) for streaming login windows during scripts
64
- - Ability to upload and run extensions _(coming soon)_
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(laucherOpts: BrowserLauncherOptions): Promise<Browser>;
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(laucherOpts) {
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 __dirname = path.dirname(fileURLToPath(import.meta.url));
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 (this.blockAds) {
130
- // Necessary to load extensions
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)
@@ -353,7 +353,7 @@ export class BrowserManager {
353
353
  options: launchOptions,
354
354
  pwVersion,
355
355
  req,
356
- stealth: launchOptions?.stealth
356
+ stealth: launchOptions?.stealth,
357
357
  });
358
358
  await this.hooks.browser({ browser, req });
359
359
  const session = {
@@ -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);
package/build/logger.js CHANGED
@@ -20,7 +20,7 @@ export class Logger {
20
20
  this._fatal = logger.extend('fatal');
21
21
  }
22
22
  get reqInfo() {
23
- return this.request ? this.request.socket.remoteAddress ?? 'Unknown' : '';
23
+ return this.request ? (this.request.socket.remoteAddress ?? 'Unknown') : '';
24
24
  }
25
25
  trace(...messages) {
26
26
  this._trace(this.reqInfo, ...messages);
@@ -408,14 +408,14 @@
408
408
  "length": {
409
409
  "type": "number"
410
410
  },
411
- "__@toStringTag@32994": {
411
+ "__@toStringTag@11061": {
412
412
  "type": "string",
413
413
  "const": "Uint8Array"
414
414
  }
415
415
  },
416
416
  "required": [
417
417
  "BYTES_PER_ELEMENT",
418
- "__@toStringTag@32994",
418
+ "__@toStringTag@11061",
419
419
  "buffer",
420
420
  "byteLength",
421
421
  "byteOffset",
@@ -450,13 +450,13 @@
450
450
  "byteLength": {
451
451
  "type": "number"
452
452
  },
453
- "__@toStringTag@32994": {
453
+ "__@toStringTag@11061": {
454
454
  "type": "string"
455
455
  }
456
456
  },
457
457
  "additionalProperties": false,
458
458
  "required": [
459
- "__@toStringTag@32994",
459
+ "__@toStringTag@11061",
460
460
  "byteLength"
461
461
  ]
462
462
  },
@@ -466,18 +466,18 @@
466
466
  "byteLength": {
467
467
  "type": "number"
468
468
  },
469
- "__@species@33095": {
469
+ "__@species@11100": {
470
470
  "$ref": "#/definitions/SharedArrayBuffer"
471
471
  },
472
- "__@toStringTag@32994": {
472
+ "__@toStringTag@11061": {
473
473
  "type": "string",
474
474
  "const": "SharedArrayBuffer"
475
475
  }
476
476
  },
477
477
  "additionalProperties": false,
478
478
  "required": [
479
- "__@species@33095",
480
- "__@toStringTag@32994",
479
+ "__@species@11100",
480
+ "__@toStringTag@11061",
481
481
  "byteLength"
482
482
  ]
483
483
  },
@@ -474,8 +474,12 @@
474
474
  "type": "boolean"
475
475
  },
476
476
  "timeout": {
477
- "description": "Timeout in milliseconds. Pass `0` to disable timeout.",
477
+ "description": "Timeout in milliseconds. Pass `0` to disable timeout.\n\nThe default value can be changed by using {@link Page.setDefaultTimeout}",
478
478
  "type": "number"
479
+ },
480
+ "waitForFonts": {
481
+ "description": "If true, waits for `document.fonts.ready` to resolve. This might require\nactivating the page using {@link Page.bringToFront} if the page is in the\nbackground.",
482
+ "type": "boolean"
479
483
  }
480
484
  },
481
485
  "additionalProperties": false
@@ -549,14 +553,14 @@
549
553
  "length": {
550
554
  "type": "number"
551
555
  },
552
- "__@toStringTag@88036": {
556
+ "__@toStringTag@76992": {
553
557
  "type": "string",
554
558
  "const": "Uint8Array"
555
559
  }
556
560
  },
557
561
  "required": [
558
562
  "BYTES_PER_ELEMENT",
559
- "__@toStringTag@88036",
563
+ "__@toStringTag@76992",
560
564
  "buffer",
561
565
  "byteLength",
562
566
  "byteOffset",
@@ -591,13 +595,13 @@
591
595
  "byteLength": {
592
596
  "type": "number"
593
597
  },
594
- "__@toStringTag@88036": {
598
+ "__@toStringTag@76992": {
595
599
  "type": "string"
596
600
  }
597
601
  },
598
602
  "additionalProperties": false,
599
603
  "required": [
600
- "__@toStringTag@88036",
604
+ "__@toStringTag@76992",
601
605
  "byteLength"
602
606
  ]
603
607
  },
@@ -607,18 +611,18 @@
607
611
  "byteLength": {
608
612
  "type": "number"
609
613
  },
610
- "__@species@88137": {
614
+ "__@species@77031": {
611
615
  "$ref": "#/definitions/SharedArrayBuffer"
612
616
  },
613
- "__@toStringTag@88036": {
617
+ "__@toStringTag@76992": {
614
618
  "type": "string",
615
619
  "const": "SharedArrayBuffer"
616
620
  }
617
621
  },
618
622
  "additionalProperties": false,
619
623
  "required": [
620
- "__@species@88137",
621
- "__@toStringTag@88036",
624
+ "__@species@77031",
625
+ "__@toStringTag@76992",
622
626
  "byteLength"
623
627
  ]
624
628
  },
@@ -455,14 +455,14 @@
455
455
  "length": {
456
456
  "type": "number"
457
457
  },
458
- "__@toStringTag@121462": {
458
+ "__@toStringTag@110270": {
459
459
  "type": "string",
460
460
  "const": "Uint8Array"
461
461
  }
462
462
  },
463
463
  "required": [
464
464
  "BYTES_PER_ELEMENT",
465
- "__@toStringTag@121462",
465
+ "__@toStringTag@110270",
466
466
  "buffer",
467
467
  "byteLength",
468
468
  "byteOffset",
@@ -497,13 +497,13 @@
497
497
  "byteLength": {
498
498
  "type": "number"
499
499
  },
500
- "__@toStringTag@121462": {
500
+ "__@toStringTag@110270": {
501
501
  "type": "string"
502
502
  }
503
503
  },
504
504
  "additionalProperties": false,
505
505
  "required": [
506
- "__@toStringTag@121462",
506
+ "__@toStringTag@110270",
507
507
  "byteLength"
508
508
  ]
509
509
  },
@@ -513,18 +513,18 @@
513
513
  "byteLength": {
514
514
  "type": "number"
515
515
  },
516
- "__@species@121563": {
516
+ "__@species@110309": {
517
517
  "$ref": "#/definitions/SharedArrayBuffer"
518
518
  },
519
- "__@toStringTag@121462": {
519
+ "__@toStringTag@110270": {
520
520
  "type": "string",
521
521
  "const": "SharedArrayBuffer"
522
522
  }
523
523
  },
524
524
  "additionalProperties": false,
525
525
  "required": [
526
- "__@species@121563",
527
- "__@toStringTag@121462",
526
+ "__@species@110309",
527
+ "__@toStringTag@110270",
528
528
  "byteLength"
529
529
  ]
530
530
  },
@@ -498,14 +498,14 @@
498
498
  "length": {
499
499
  "type": "number"
500
500
  },
501
- "__@toStringTag@110235": {
501
+ "__@toStringTag@99117": {
502
502
  "type": "string",
503
503
  "const": "Uint8Array"
504
504
  }
505
505
  },
506
506
  "required": [
507
507
  "BYTES_PER_ELEMENT",
508
- "__@toStringTag@110235",
508
+ "__@toStringTag@99117",
509
509
  "buffer",
510
510
  "byteLength",
511
511
  "byteOffset",
@@ -540,13 +540,13 @@
540
540
  "byteLength": {
541
541
  "type": "number"
542
542
  },
543
- "__@toStringTag@110235": {
543
+ "__@toStringTag@99117": {
544
544
  "type": "string"
545
545
  }
546
546
  },
547
547
  "additionalProperties": false,
548
548
  "required": [
549
- "__@toStringTag@110235",
549
+ "__@toStringTag@99117",
550
550
  "byteLength"
551
551
  ]
552
552
  },
@@ -556,18 +556,18 @@
556
556
  "byteLength": {
557
557
  "type": "number"
558
558
  },
559
- "__@species@110336": {
559
+ "__@species@99156": {
560
560
  "$ref": "#/definitions/SharedArrayBuffer"
561
561
  },
562
- "__@toStringTag@110235": {
562
+ "__@toStringTag@99117": {
563
563
  "type": "string",
564
564
  "const": "SharedArrayBuffer"
565
565
  }
566
566
  },
567
567
  "additionalProperties": false,
568
568
  "required": [
569
- "__@species@110336",
570
- "__@toStringTag@110235",
569
+ "__@species@99156",
570
+ "__@toStringTag@99117",
571
571
  "byteLength"
572
572
  ]
573
573
  },
@@ -408,14 +408,14 @@
408
408
  "length": {
409
409
  "type": "number"
410
410
  },
411
- "__@toStringTag@132742": {
411
+ "__@toStringTag@121476": {
412
412
  "type": "string",
413
413
  "const": "Uint8Array"
414
414
  }
415
415
  },
416
416
  "required": [
417
417
  "BYTES_PER_ELEMENT",
418
- "__@toStringTag@132742",
418
+ "__@toStringTag@121476",
419
419
  "buffer",
420
420
  "byteLength",
421
421
  "byteOffset",
@@ -450,13 +450,13 @@
450
450
  "byteLength": {
451
451
  "type": "number"
452
452
  },
453
- "__@toStringTag@132742": {
453
+ "__@toStringTag@121476": {
454
454
  "type": "string"
455
455
  }
456
456
  },
457
457
  "additionalProperties": false,
458
458
  "required": [
459
- "__@toStringTag@132742",
459
+ "__@toStringTag@121476",
460
460
  "byteLength"
461
461
  ]
462
462
  },
@@ -466,18 +466,18 @@
466
466
  "byteLength": {
467
467
  "type": "number"
468
468
  },
469
- "__@species@132843": {
469
+ "__@species@121515": {
470
470
  "$ref": "#/definitions/SharedArrayBuffer"
471
471
  },
472
- "__@toStringTag@132742": {
472
+ "__@toStringTag@121476": {
473
473
  "type": "string",
474
474
  "const": "SharedArrayBuffer"
475
475
  }
476
476
  },
477
477
  "additionalProperties": false,
478
478
  "required": [
479
- "__@species@132843",
480
- "__@toStringTag@132742",
479
+ "__@species@121515",
480
+ "__@toStringTag@121476",
481
481
  "byteLength"
482
482
  ]
483
483
  },
@@ -474,8 +474,12 @@
474
474
  "type": "boolean"
475
475
  },
476
476
  "timeout": {
477
- "description": "Timeout in milliseconds. Pass `0` to disable timeout.",
477
+ "description": "Timeout in milliseconds. Pass `0` to disable timeout.\n\nThe default value can be changed by using {@link Page.setDefaultTimeout}",
478
478
  "type": "number"
479
+ },
480
+ "waitForFonts": {
481
+ "description": "If true, waits for `document.fonts.ready` to resolve. This might require\nactivating the page using {@link Page.bringToFront} if the page is in the\nbackground.",
482
+ "type": "boolean"
479
483
  }
480
484
  },
481
485
  "additionalProperties": false
@@ -549,14 +553,14 @@
549
553
  "length": {
550
554
  "type": "number"
551
555
  },
552
- "__@toStringTag@220645": {
556
+ "__@toStringTag@198348": {
553
557
  "type": "string",
554
558
  "const": "Uint8Array"
555
559
  }
556
560
  },
557
561
  "required": [
558
562
  "BYTES_PER_ELEMENT",
559
- "__@toStringTag@220645",
563
+ "__@toStringTag@198348",
560
564
  "buffer",
561
565
  "byteLength",
562
566
  "byteOffset",
@@ -591,13 +595,13 @@
591
595
  "byteLength": {
592
596
  "type": "number"
593
597
  },
594
- "__@toStringTag@220645": {
598
+ "__@toStringTag@198348": {
595
599
  "type": "string"
596
600
  }
597
601
  },
598
602
  "additionalProperties": false,
599
603
  "required": [
600
- "__@toStringTag@220645",
604
+ "__@toStringTag@198348",
601
605
  "byteLength"
602
606
  ]
603
607
  },
@@ -607,18 +611,18 @@
607
611
  "byteLength": {
608
612
  "type": "number"
609
613
  },
610
- "__@species@220746": {
614
+ "__@species@198387": {
611
615
  "$ref": "#/definitions/SharedArrayBuffer"
612
616
  },
613
- "__@toStringTag@220645": {
617
+ "__@toStringTag@198348": {
614
618
  "type": "string",
615
619
  "const": "SharedArrayBuffer"
616
620
  }
617
621
  },
618
622
  "additionalProperties": false,
619
623
  "required": [
620
- "__@species@220746",
621
- "__@toStringTag@220645",
624
+ "__@species@198387",
625
+ "__@toStringTag@198348",
622
626
  "byteLength"
623
627
  ]
624
628
  },
@@ -455,14 +455,14 @@
455
455
  "length": {
456
456
  "type": "number"
457
457
  },
458
- "__@toStringTag@254051": {
458
+ "__@toStringTag@209498": {
459
459
  "type": "string",
460
460
  "const": "Uint8Array"
461
461
  }
462
462
  },
463
463
  "required": [
464
464
  "BYTES_PER_ELEMENT",
465
- "__@toStringTag@254051",
465
+ "__@toStringTag@209498",
466
466
  "buffer",
467
467
  "byteLength",
468
468
  "byteOffset",
@@ -497,13 +497,13 @@
497
497
  "byteLength": {
498
498
  "type": "number"
499
499
  },
500
- "__@toStringTag@254051": {
500
+ "__@toStringTag@209498": {
501
501
  "type": "string"
502
502
  }
503
503
  },
504
504
  "additionalProperties": false,
505
505
  "required": [
506
- "__@toStringTag@254051",
506
+ "__@toStringTag@209498",
507
507
  "byteLength"
508
508
  ]
509
509
  },
@@ -513,18 +513,18 @@
513
513
  "byteLength": {
514
514
  "type": "number"
515
515
  },
516
- "__@species@254152": {
516
+ "__@species@209537": {
517
517
  "$ref": "#/definitions/SharedArrayBuffer"
518
518
  },
519
- "__@toStringTag@254051": {
519
+ "__@toStringTag@209498": {
520
520
  "type": "string",
521
521
  "const": "SharedArrayBuffer"
522
522
  }
523
523
  },
524
524
  "additionalProperties": false,
525
525
  "required": [
526
- "__@species@254152",
527
- "__@toStringTag@254051",
526
+ "__@species@209537",
527
+ "__@toStringTag@209498",
528
528
  "byteLength"
529
529
  ]
530
530
  },
@@ -498,14 +498,14 @@
498
498
  "length": {
499
499
  "type": "number"
500
500
  },
501
- "__@toStringTag@231880": {
501
+ "__@toStringTag@242645": {
502
502
  "type": "string",
503
503
  "const": "Uint8Array"
504
504
  }
505
505
  },
506
506
  "required": [
507
507
  "BYTES_PER_ELEMENT",
508
- "__@toStringTag@231880",
508
+ "__@toStringTag@242645",
509
509
  "buffer",
510
510
  "byteLength",
511
511
  "byteOffset",
@@ -540,13 +540,13 @@
540
540
  "byteLength": {
541
541
  "type": "number"
542
542
  },
543
- "__@toStringTag@231880": {
543
+ "__@toStringTag@242645": {
544
544
  "type": "string"
545
545
  }
546
546
  },
547
547
  "additionalProperties": false,
548
548
  "required": [
549
- "__@toStringTag@231880",
549
+ "__@toStringTag@242645",
550
550
  "byteLength"
551
551
  ]
552
552
  },
@@ -556,18 +556,18 @@
556
556
  "byteLength": {
557
557
  "type": "number"
558
558
  },
559
- "__@species@231981": {
559
+ "__@species@242684": {
560
560
  "$ref": "#/definitions/SharedArrayBuffer"
561
561
  },
562
- "__@toStringTag@231880": {
562
+ "__@toStringTag@242645": {
563
563
  "type": "string",
564
564
  "const": "SharedArrayBuffer"
565
565
  }
566
566
  },
567
567
  "additionalProperties": false,
568
568
  "required": [
569
- "__@species@231981",
570
- "__@toStringTag@231880",
569
+ "__@species@242684",
570
+ "__@toStringTag@242645",
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] = value;
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');