@browserless.io/browserless 2.4.0-beta-1 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/CHANGELOG.md +14 -1
  2. package/bin/scaffold/README.md +2 -0
  3. package/build/browserless.d.ts +4 -2
  4. package/build/browserless.js +17 -4
  5. package/build/browsers/chromium.cdp.d.ts +1 -5
  6. package/build/browsers/chromium.cdp.js +5 -115
  7. package/build/browsers/chromium.playwright.d.ts +1 -3
  8. package/build/browsers/chromium.playwright.js +1 -6
  9. package/build/browsers/firefox.playwright.d.ts +1 -3
  10. package/build/browsers/firefox.playwright.js +1 -6
  11. package/build/browsers/index.d.ts +5 -1
  12. package/build/browsers/index.js +6 -5
  13. package/build/browsers/webkit.playwright.d.ts +1 -3
  14. package/build/browsers/webkit.playwright.js +1 -6
  15. package/build/config.d.ts +9 -0
  16. package/build/config.js +11 -0
  17. package/build/constants.d.ts +0 -1
  18. package/build/constants.js +0 -1
  19. package/build/file-system.d.ts +12 -1
  20. package/build/file-system.js +14 -1
  21. package/build/http.d.ts +0 -7
  22. package/build/limiter.d.ts +9 -0
  23. package/build/limiter.js +11 -0
  24. package/build/metrics.d.ts +12 -1
  25. package/build/metrics.js +13 -1
  26. package/build/monitoring.d.ts +12 -1
  27. package/build/monitoring.js +14 -1
  28. package/build/router.d.ts +12 -2
  29. package/build/router.js +16 -6
  30. package/build/routes/chrome/http/content.post.body.json +8 -8
  31. package/build/routes/chrome/http/content.post.query.json +0 -4
  32. package/build/routes/chrome/http/download.post.query.json +0 -4
  33. package/build/routes/chrome/http/function.post.query.json +0 -4
  34. package/build/routes/chrome/http/pdf.post.body.json +8 -11
  35. package/build/routes/chrome/http/pdf.post.query.json +0 -4
  36. package/build/routes/chrome/http/performance.post.query.json +0 -4
  37. package/build/routes/chrome/http/scrape.post.body.json +8 -8
  38. package/build/routes/chrome/http/scrape.post.query.json +0 -4
  39. package/build/routes/chrome/http/screenshot.post.body.json +8 -8
  40. package/build/routes/chrome/http/screenshot.post.query.json +0 -4
  41. package/build/routes/chrome/ws/browser.query.json +0 -4
  42. package/build/routes/chrome/ws/cdp.query.json +0 -4
  43. package/build/routes/chrome/ws/page.query.json +0 -4
  44. package/build/routes/chrome/ws/playwright.query.json +0 -4
  45. package/build/routes/chromium/http/content.post.body.json +8 -8
  46. package/build/routes/chromium/http/content.post.query.json +0 -4
  47. package/build/routes/chromium/http/download.post.query.json +0 -4
  48. package/build/routes/chromium/http/function.post.query.json +0 -4
  49. package/build/routes/chromium/http/pdf.post.body.json +8 -11
  50. package/build/routes/chromium/http/pdf.post.query.json +0 -4
  51. package/build/routes/chromium/http/performance.post.query.json +0 -4
  52. package/build/routes/chromium/http/scrape.post.body.json +8 -8
  53. package/build/routes/chromium/http/scrape.post.query.json +0 -4
  54. package/build/routes/chromium/http/screenshot.post.body.json +8 -8
  55. package/build/routes/chromium/http/screenshot.post.query.json +0 -4
  56. package/build/routes/chromium/ws/browser.query.json +0 -4
  57. package/build/routes/chromium/ws/cdp.query.json +0 -4
  58. package/build/routes/chromium/ws/page.query.json +0 -4
  59. package/build/routes/chromium/ws/playwright.query.json +0 -4
  60. package/build/routes/firefox/ws/playwright.query.json +0 -4
  61. package/build/routes/webkit/ws/playwright.query.json +0 -4
  62. package/build/server.d.ts +8 -3
  63. package/build/server.js +15 -13
  64. package/build/shared/content.http.js +1 -1
  65. package/build/shared/pdf.http.d.ts +0 -1
  66. package/build/shared/pdf.http.js +1 -1
  67. package/build/shared/screenshot.http.js +1 -1
  68. package/build/token.d.ts +12 -1
  69. package/build/token.js +14 -1
  70. package/build/types.d.ts +3 -14
  71. package/build/webhooks.d.ts +12 -1
  72. package/build/webhooks.js +14 -1
  73. package/extensions/.gitkeep +0 -0
  74. package/package.json +8 -8
  75. package/src/browserless.ts +17 -4
  76. package/src/browsers/chromium.cdp.ts +10 -157
  77. package/src/browsers/chromium.playwright.ts +0 -8
  78. package/src/browsers/firefox.playwright.ts +0 -8
  79. package/src/browsers/index.ts +7 -6
  80. package/src/browsers/webkit.playwright.ts +0 -8
  81. package/src/config.ts +13 -0
  82. package/src/constants.ts +0 -1
  83. package/src/file-system.ts +16 -1
  84. package/src/http.ts +0 -8
  85. package/src/limiter.ts +13 -0
  86. package/src/metrics.ts +16 -1
  87. package/src/monitoring.ts +18 -2
  88. package/src/router.ts +20 -9
  89. package/src/server.ts +18 -16
  90. package/src/shared/content.http.ts +5 -4
  91. package/src/shared/pdf.http.ts +4 -5
  92. package/src/shared/screenshot.http.ts +4 -4
  93. package/src/token.ts +18 -2
  94. package/src/types.ts +0 -13
  95. package/src/webhooks.ts +18 -2
  96. package/static/docs/swagger.json +10 -192
  97. package/static/docs/swagger.min.json +9 -191
  98. package/extensions/screencast/background.js +0 -143
  99. package/extensions/screencast/content_script.js +0 -18
  100. package/extensions/screencast/manifest.json +0 -19
@@ -20,9 +20,6 @@
20
20
  "description": "When bestAttempt is set to true, browserless attempt to proceed\nwhen \"awaited\" events fail or timeout. This includes things like\ngoto, waitForSelector, and more.",
21
21
  "type": "boolean"
22
22
  },
23
- "blockModals": {
24
- "type": "boolean"
25
- },
26
23
  "cookies": {
27
24
  "type": "array",
28
25
  "items": {
@@ -538,14 +535,14 @@
538
535
  "length": {
539
536
  "type": "number"
540
537
  },
541
- "__@toStringTag@217434": {
538
+ "__@toStringTag@195916": {
542
539
  "type": "string",
543
540
  "const": "Uint8Array"
544
541
  }
545
542
  },
546
543
  "required": [
547
544
  "BYTES_PER_ELEMENT",
548
- "__@toStringTag@217434",
545
+ "__@toStringTag@195916",
549
546
  "buffer",
550
547
  "byteLength",
551
548
  "byteOffset",
@@ -580,13 +577,13 @@
580
577
  "byteLength": {
581
578
  "type": "number"
582
579
  },
583
- "__@toStringTag@217434": {
580
+ "__@toStringTag@195916": {
584
581
  "type": "string"
585
582
  }
586
583
  },
587
584
  "additionalProperties": false,
588
585
  "required": [
589
- "__@toStringTag@217434",
586
+ "__@toStringTag@195916",
590
587
  "byteLength"
591
588
  ]
592
589
  },
@@ -596,18 +593,18 @@
596
593
  "byteLength": {
597
594
  "type": "number"
598
595
  },
599
- "__@species@217535": {
596
+ "__@species@196017": {
600
597
  "$ref": "#/definitions/SharedArrayBuffer"
601
598
  },
602
- "__@toStringTag@217434": {
599
+ "__@toStringTag@195916": {
603
600
  "type": "string",
604
601
  "const": "SharedArrayBuffer"
605
602
  }
606
603
  },
607
604
  "additionalProperties": false,
608
605
  "required": [
609
- "__@species@217535",
610
- "__@toStringTag@217434",
606
+ "__@species@196017",
607
+ "__@toStringTag@195916",
611
608
  "byteLength"
612
609
  ]
613
610
  },
@@ -16,10 +16,6 @@
16
16
  "description": "Whether or nor to load ad-blocking extensions for the session.\nThis currently uses uBlock Origin and may cause certain sites\nto not load properly.",
17
17
  "type": "boolean"
18
18
  },
19
- "record": {
20
- "description": "Whether or nor to record the session. The browser will run\nin \"head-full\" mode, and recording is started and closed\nvia the embedded browserless API. Please refer to the \"Recording\"\nsection in the live documentation site for more details.",
21
- "type": "boolean"
22
- },
23
19
  "timeout": {
24
20
  "description": "Override the system-level timeout for this request.\nAccepts a value in milliseconds.",
25
21
  "type": "number"
@@ -16,10 +16,6 @@
16
16
  "description": "Whether or nor to load ad-blocking extensions for the session.\nThis currently uses uBlock Origin and may cause certain sites\nto not load properly.",
17
17
  "type": "boolean"
18
18
  },
19
- "record": {
20
- "description": "Whether or nor to record the session. The browser will run\nin \"head-full\" mode, and recording is started and closed\nvia the embedded browserless API. Please refer to the \"Recording\"\nsection in the live documentation site for more details.",
21
- "type": "boolean"
22
- },
23
19
  "timeout": {
24
20
  "description": "Override the system-level timeout for this request.\nAccepts a value in milliseconds.",
25
21
  "type": "number"
@@ -441,14 +441,14 @@
441
441
  "length": {
442
442
  "type": "number"
443
443
  },
444
- "__@toStringTag@228499": {
444
+ "__@toStringTag@228592": {
445
445
  "type": "string",
446
446
  "const": "Uint8Array"
447
447
  }
448
448
  },
449
449
  "required": [
450
450
  "BYTES_PER_ELEMENT",
451
- "__@toStringTag@228499",
451
+ "__@toStringTag@228592",
452
452
  "buffer",
453
453
  "byteLength",
454
454
  "byteOffset",
@@ -483,13 +483,13 @@
483
483
  "byteLength": {
484
484
  "type": "number"
485
485
  },
486
- "__@toStringTag@228499": {
486
+ "__@toStringTag@228592": {
487
487
  "type": "string"
488
488
  }
489
489
  },
490
490
  "additionalProperties": false,
491
491
  "required": [
492
- "__@toStringTag@228499",
492
+ "__@toStringTag@228592",
493
493
  "byteLength"
494
494
  ]
495
495
  },
@@ -499,18 +499,18 @@
499
499
  "byteLength": {
500
500
  "type": "number"
501
501
  },
502
- "__@species@228600": {
502
+ "__@species@228693": {
503
503
  "$ref": "#/definitions/SharedArrayBuffer"
504
504
  },
505
- "__@toStringTag@228499": {
505
+ "__@toStringTag@228592": {
506
506
  "type": "string",
507
507
  "const": "SharedArrayBuffer"
508
508
  }
509
509
  },
510
510
  "additionalProperties": false,
511
511
  "required": [
512
- "__@species@228600",
513
- "__@toStringTag@228499",
512
+ "__@species@228693",
513
+ "__@toStringTag@228592",
514
514
  "byteLength"
515
515
  ]
516
516
  },
@@ -16,10 +16,6 @@
16
16
  }
17
17
  ]
18
18
  },
19
- "record": {
20
- "description": "Whether or nor to record the session. The browser will run\nin \"head-full\" mode, and recording is started and closed\nvia the embedded browserless API. Please refer to the \"Recording\"\nsection in the live documentation site for more details.",
21
- "type": "boolean"
22
- },
23
19
  "timeout": {
24
20
  "description": "Override the system-level timeout for this request.\nAccepts a value in milliseconds.",
25
21
  "type": "number"
@@ -484,14 +484,14 @@
484
484
  "length": {
485
485
  "type": "number"
486
486
  },
487
- "__@toStringTag@239641": {
487
+ "__@toStringTag@239738": {
488
488
  "type": "string",
489
489
  "const": "Uint8Array"
490
490
  }
491
491
  },
492
492
  "required": [
493
493
  "BYTES_PER_ELEMENT",
494
- "__@toStringTag@239641",
494
+ "__@toStringTag@239738",
495
495
  "buffer",
496
496
  "byteLength",
497
497
  "byteOffset",
@@ -526,13 +526,13 @@
526
526
  "byteLength": {
527
527
  "type": "number"
528
528
  },
529
- "__@toStringTag@239641": {
529
+ "__@toStringTag@239738": {
530
530
  "type": "string"
531
531
  }
532
532
  },
533
533
  "additionalProperties": false,
534
534
  "required": [
535
- "__@toStringTag@239641",
535
+ "__@toStringTag@239738",
536
536
  "byteLength"
537
537
  ]
538
538
  },
@@ -542,18 +542,18 @@
542
542
  "byteLength": {
543
543
  "type": "number"
544
544
  },
545
- "__@species@239742": {
545
+ "__@species@239839": {
546
546
  "$ref": "#/definitions/SharedArrayBuffer"
547
547
  },
548
- "__@toStringTag@239641": {
548
+ "__@toStringTag@239738": {
549
549
  "type": "string",
550
550
  "const": "SharedArrayBuffer"
551
551
  }
552
552
  },
553
553
  "additionalProperties": false,
554
554
  "required": [
555
- "__@species@239742",
556
- "__@toStringTag@239641",
555
+ "__@species@239839",
556
+ "__@toStringTag@239738",
557
557
  "byteLength"
558
558
  ]
559
559
  },
@@ -16,10 +16,6 @@
16
16
  "description": "Whether or nor to load ad-blocking extensions for the session.\nThis currently uses uBlock Origin and may cause certain sites\nto not load properly.",
17
17
  "type": "boolean"
18
18
  },
19
- "record": {
20
- "description": "Whether or nor to record the session. The browser will run\nin \"head-full\" mode, and recording is started and closed\nvia the embedded browserless API. Please refer to the \"Recording\"\nsection in the live documentation site for more details.",
21
- "type": "boolean"
22
- },
23
19
  "timeout": {
24
20
  "description": "Override the system-level timeout for this request.\nAccepts a value in milliseconds.",
25
21
  "type": "number"
@@ -16,10 +16,6 @@
16
16
  "description": "Whether or nor to load ad-blocking extensions for the session.\nThis currently uses uBlock Origin and may cause certain sites\nto not load properly.",
17
17
  "type": "boolean"
18
18
  },
19
- "record": {
20
- "description": "Whether or nor to record the session. The browser will run\nin \"head-full\" mode, and recording is started and closed\nvia the embedded browserless API. Please refer to the \"Recording\"\nsection in the live documentation site for more details.",
21
- "type": "boolean"
22
- },
23
19
  "timeout": {
24
20
  "description": "Override the system-level timeout for this request.\nAccepts a value in milliseconds.",
25
21
  "type": "number"
@@ -16,10 +16,6 @@
16
16
  "description": "Whether or nor to load ad-blocking extensions for the session.\nThis currently uses uBlock Origin and may cause certain sites\nto not load properly.",
17
17
  "type": "boolean"
18
18
  },
19
- "record": {
20
- "description": "Whether or nor to record the session. The browser will run\nin \"head-full\" mode, and recording is started and closed\nvia the embedded browserless API. Please refer to the \"Recording\"\nsection in the live documentation site for more details.",
21
- "type": "boolean"
22
- },
23
19
  "timeout": {
24
20
  "description": "Override the system-level timeout for this request.\nAccepts a value in milliseconds.",
25
21
  "type": "number"
@@ -16,10 +16,6 @@
16
16
  "description": "Whether or nor to load ad-blocking extensions for the session.\nThis currently uses uBlock Origin and may cause certain sites\nto not load properly.",
17
17
  "type": "boolean"
18
18
  },
19
- "record": {
20
- "description": "Whether or nor to record the session. The browser will run\nin \"head-full\" mode, and recording is started and closed\nvia the embedded browserless API. Please refer to the \"Recording\"\nsection in the live documentation site for more details.",
21
- "type": "boolean"
22
- },
23
19
  "timeout": {
24
20
  "description": "Override the system-level timeout for this request.\nAccepts a value in milliseconds.",
25
21
  "type": "number"
@@ -16,10 +16,6 @@
16
16
  "description": "Whether or nor to load ad-blocking extensions for the session.\nThis currently uses uBlock Origin and may cause certain sites\nto not load properly.",
17
17
  "type": "boolean"
18
18
  },
19
- "record": {
20
- "description": "Whether or nor to record the session. The browser will run\nin \"head-full\" mode, and recording is started and closed\nvia the embedded browserless API. Please refer to the \"Recording\"\nsection in the live documentation site for more details.",
21
- "type": "boolean"
22
- },
23
19
  "timeout": {
24
20
  "description": "Override the system-level timeout for this request.\nAccepts a value in milliseconds.",
25
21
  "type": "number"
@@ -80,10 +80,6 @@
80
80
  "description": "Whether or nor to load ad-blocking extensions for the session.\nThis currently uses uBlock Origin and may cause certain sites\nto not load properly.",
81
81
  "type": "boolean"
82
82
  },
83
- "record": {
84
- "description": "Whether or nor to record the session. The browser will run\nin \"head-full\" mode, and recording is started and closed\nvia the embedded browserless API. Please refer to the \"Recording\"\nsection in the live documentation site for more details.",
85
- "type": "boolean"
86
- },
87
83
  "timeout": {
88
84
  "description": "Override the system-level timeout for this request.\nAccepts a value in milliseconds.",
89
85
  "type": "number"
@@ -16,10 +16,6 @@
16
16
  "description": "Whether or nor to load ad-blocking extensions for the session.\nThis currently uses uBlock Origin and may cause certain sites\nto not load properly.",
17
17
  "type": "boolean"
18
18
  },
19
- "record": {
20
- "description": "Whether or nor to record the session. The browser will run\nin \"head-full\" mode, and recording is started and closed\nvia the embedded browserless API. Please refer to the \"Recording\"\nsection in the live documentation site for more details.",
21
- "type": "boolean"
22
- },
23
19
  "timeout": {
24
20
  "description": "Override the system-level timeout for this request.\nAccepts a value in milliseconds.",
25
21
  "type": "number"
package/build/server.d.ts CHANGED
@@ -2,9 +2,11 @@
2
2
  /// <reference types="debug" />
3
3
  /// <reference types="node" />
4
4
  /// <reference types="node" />
5
+ /// <reference types="node" />
5
6
  import * as http from 'http';
6
7
  import * as stream from 'stream';
7
8
  import { Config, Metrics, Request, Response, Router, Token } from '@browserless.io/browserless';
9
+ import { EventEmitter } from 'events';
8
10
  export interface HTTPServerOptions {
9
11
  concurrent: number;
10
12
  host: string;
@@ -12,7 +14,7 @@ export interface HTTPServerOptions {
12
14
  queued: number;
13
15
  timeout: number;
14
16
  }
15
- export declare class HTTPServer {
17
+ export declare class HTTPServer extends EventEmitter {
16
18
  protected config: Config;
17
19
  protected metrics: Metrics;
18
20
  protected token: Token;
@@ -26,8 +28,11 @@ export declare class HTTPServer {
26
28
  protected onHTTPUnauthorized: (_req: Request, res: Response) => void;
27
29
  protected onWebsocketUnauthorized: (_req: Request, socket: stream.Duplex) => void;
28
30
  start(): Promise<void>;
29
- stop(): Promise<void>;
30
- protected tearDown(): void;
31
31
  protected handleRequest: (request: http.IncomingMessage, res: http.ServerResponse) => Promise<void | http.ServerResponse<http.IncomingMessage>>;
32
32
  protected handleWebSocket: (request: http.IncomingMessage, socket: stream.Duplex, head: Buffer) => Promise<void>;
33
+ shutdown(): Promise<void>;
34
+ /**
35
+ * Left blank for downstream SDK modules to optionally implement.
36
+ */
37
+ stop: () => void;
33
38
  }
package/build/server.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import * as http from 'http';
2
2
  import { BadRequest, NotFound, Timeout, TooManyRequests, Unauthorized, beforeRequest, contentTypes, convertPathToURL, createLogger, queryParamsToObject, readBody, shimLegacyRequests, writeResponse, } from '@browserless.io/browserless';
3
+ import { EventEmitter } from 'events';
3
4
  // @ts-ignore
4
5
  import Enjoi from 'enjoi';
5
- export class HTTPServer {
6
+ export class HTTPServer extends EventEmitter {
6
7
  config;
7
8
  metrics;
8
9
  token;
@@ -13,6 +14,7 @@ export class HTTPServer {
13
14
  log = createLogger('server');
14
15
  verbose = createLogger('server:verbose');
15
16
  constructor(config, metrics, token, router) {
17
+ super();
16
18
  this.config = config;
17
19
  this.metrics = metrics;
18
20
  this.token = token;
@@ -49,18 +51,6 @@ export class HTTPServer {
49
51
  });
50
52
  });
51
53
  }
52
- async stop() {
53
- this.log(`HTTP Server is shutting down`);
54
- await new Promise((r) => this.server.close(r));
55
- await Promise.all([this.tearDown(), this.router.teardown()]);
56
- this.log(`HTTP Server shutdown complete`);
57
- }
58
- tearDown() {
59
- this.log(`Tearing down all listeners and internal routes`);
60
- this.server && this.server.removeAllListeners();
61
- // @ts-ignore garbage collect this reference
62
- this.server = null;
63
- }
64
54
  handleRequest = async (request, res) => {
65
55
  this.verbose(`Handling inbound HTTP request on "${request.method}: ${request.url}"`);
66
56
  const req = request;
@@ -241,4 +231,16 @@ export class HTTPServer {
241
231
  this.log(`No matching WebSocket route handler for "${req.parsed.href}"`);
242
232
  return writeResponse(socket, 404, 'Not Found');
243
233
  };
234
+ async shutdown() {
235
+ this.log(`HTTP Server is shutting down`);
236
+ await new Promise((r) => this.server.close(r));
237
+ this.server && this.server.removeAllListeners();
238
+ // @ts-ignore garbage collect this reference
239
+ this.server = null;
240
+ this.log(`HTTP Server shutdown complete`);
241
+ }
242
+ /**
243
+ * Left blank for downstream SDK modules to optionally implement.
244
+ */
245
+ stop = () => { };
244
246
  }
@@ -62,6 +62,7 @@ export default class ChromiumContentPostRoute extends BrowserHTTPRoute {
62
62
  return req.continue();
63
63
  });
64
64
  }
65
+ const gotoResponse = await gotoCall(content, gotoOptions).catch(bestAttemptCatch(bestAttempt));
65
66
  if (addStyleTag.length) {
66
67
  for (const tag in addStyleTag) {
67
68
  await page.addStyleTag(addStyleTag[tag]);
@@ -72,7 +73,6 @@ export default class ChromiumContentPostRoute extends BrowserHTTPRoute {
72
73
  await page.addScriptTag(addScriptTag[tag]);
73
74
  }
74
75
  }
75
- const gotoResponse = await gotoCall(content, gotoOptions).catch(bestAttemptCatch(bestAttempt));
76
76
  if (waitForTimeout) {
77
77
  await sleep(waitForTimeout).catch(bestAttemptCatch(bestAttempt));
78
78
  }
@@ -7,7 +7,6 @@ export interface BodySchema {
7
7
  addStyleTag?: Array<Parameters<Page['addStyleTag']>[0]>;
8
8
  authenticate?: Parameters<Page['authenticate']>[0];
9
9
  bestAttempt?: bestAttempt;
10
- blockModals?: boolean;
11
10
  cookies?: Array<Parameters<Page['setCookie']>[0]>;
12
11
  emulateMediaType?: Parameters<Page['emulateMediaType']>[0];
13
12
  gotoOptions?: Parameters<Page['goto']>[1];
@@ -69,6 +69,7 @@ export default class ChromiumPDFPostRoute extends BrowserHTTPRoute {
69
69
  return req.continue();
70
70
  });
71
71
  }
72
+ const gotoResponse = await gotoCall(content, gotoOptions).catch(bestAttemptCatch(bestAttempt));
72
73
  if (addStyleTag.length) {
73
74
  for (const tag in addStyleTag) {
74
75
  await page.addStyleTag(addStyleTag[tag]);
@@ -79,7 +80,6 @@ export default class ChromiumPDFPostRoute extends BrowserHTTPRoute {
79
80
  await page.addScriptTag(addScriptTag[tag]);
80
81
  }
81
82
  }
82
- const gotoResponse = await gotoCall(content, gotoOptions).catch(bestAttemptCatch(bestAttempt));
83
83
  if (waitForTimeout) {
84
84
  await sleep(waitForTimeout).catch(bestAttemptCatch(bestAttempt));
85
85
  }
@@ -70,6 +70,7 @@ export default class ScreenshotPost extends BrowserHTTPRoute {
70
70
  return req.continue();
71
71
  });
72
72
  }
73
+ const gotoResponse = await gotoCall(content, gotoOptions).catch(bestAttemptCatch(bestAttempt));
73
74
  if (addStyleTag.length) {
74
75
  for (const tag in addStyleTag) {
75
76
  await page.addStyleTag(addStyleTag[tag]);
@@ -80,7 +81,6 @@ export default class ScreenshotPost extends BrowserHTTPRoute {
80
81
  await page.addScriptTag(addScriptTag[tag]);
81
82
  }
82
83
  }
83
- const gotoResponse = await gotoCall(content, gotoOptions).catch(bestAttemptCatch(bestAttempt));
84
84
  if (waitForTimeout) {
85
85
  await sleep(waitForTimeout).catch(bestAttemptCatch(bestAttempt));
86
86
  }
package/build/token.d.ts CHANGED
@@ -1,6 +1,17 @@
1
+ /// <reference types="node" />
1
2
  import { BrowserHTTPRoute, BrowserWebsocketRoute, Config, HTTPRoute, Request, WebSocketRoute } from '@browserless.io/browserless';
2
- export declare class Token {
3
+ import { EventEmitter } from 'events';
4
+ export declare class Token extends EventEmitter {
3
5
  protected config: Config;
4
6
  constructor(config: Config);
5
7
  isAuthorized: (req: Request, route: BrowserHTTPRoute | BrowserWebsocketRoute | HTTPRoute | WebSocketRoute) => Promise<boolean>;
8
+ /**
9
+ * Implement any browserless-core-specific shutdown logic here.
10
+ * Calls the empty-SDK stop method for downstream implementations.
11
+ */
12
+ shutdown: () => Promise<void>;
13
+ /**
14
+ * Left blank for downstream SDK modules to optionally implement.
15
+ */
16
+ stop: () => void;
6
17
  }
package/build/token.js CHANGED
@@ -1,7 +1,9 @@
1
1
  import { getTokenFromRequest, } from '@browserless.io/browserless';
2
- export class Token {
2
+ import { EventEmitter } from 'events';
3
+ export class Token extends EventEmitter {
3
4
  config;
4
5
  constructor(config) {
6
+ super();
5
7
  this.config = config;
6
8
  }
7
9
  isAuthorized = async (req, route) => {
@@ -18,4 +20,15 @@ export class Token {
18
20
  }
19
21
  return (Array.isArray(token) ? token : [token]).includes(requestToken);
20
22
  };
23
+ /**
24
+ * Implement any browserless-core-specific shutdown logic here.
25
+ * Calls the empty-SDK stop method for downstream implementations.
26
+ */
27
+ shutdown = async () => {
28
+ await this.stop();
29
+ };
30
+ /**
31
+ * Left blank for downstream SDK modules to optionally implement.
32
+ */
33
+ stop = () => { };
21
34
  }
package/build/types.d.ts CHANGED
@@ -100,7 +100,7 @@ declare abstract class Route {
100
100
  * and injected by browserless after initialization.
101
101
  * @returns BrowserManager
102
102
  */
103
- browserManager: () => import("@browserless.io/browserless").BrowserManager;
103
+ browserManager: () => import("src/browsers").BrowserManager;
104
104
  /**
105
105
  * Helper function that loads the config module. Defined and injected by
106
106
  * browserless after initialization.
@@ -120,7 +120,7 @@ declare abstract class Route {
120
120
  * browserless after initialization.
121
121
  * @returns FileSystem
122
122
  */
123
- fileSystem: () => import("@browserless.io/browserless").FileSystem;
123
+ fileSystem: () => import("src/file-system").FileSystem;
124
124
  /**
125
125
  * Helper function that loads the metrics module for
126
126
  * collecting and aggregating statistics. Defined and injected by
@@ -134,7 +134,7 @@ declare abstract class Route {
134
134
  * browserless after initialization.
135
135
  * @returns Monitor
136
136
  */
137
- monitoring: () => import("@browserless.io/browserless").Monitoring;
137
+ monitoring: () => import("src/monitoring").Monitoring;
138
138
  /**
139
139
  * When running in an SDK environment, this returns the fully-qualified
140
140
  * directory of that static directory. When "null" then no SDK directory
@@ -362,17 +362,6 @@ export interface InBoundRequest {
362
362
  url: string;
363
363
  }
364
364
  export declare const debugScreenshotOpts: ScreenshotOptions;
365
- declare global {
366
- interface Window {
367
- browserless: BrowserlessEmbeddedAPI;
368
- }
369
- }
370
- export interface BrowserlessEmbeddedAPI {
371
- getRecording: () => Promise<string>;
372
- liveUrl: () => string;
373
- saveRecording: () => Promise<boolean>;
374
- startRecording: () => void;
375
- }
376
365
  /**
377
366
  * When bestAttempt is set to true, browserless attempt to proceed
378
367
  * when "awaited" events fail or timeout. This includes things like
@@ -1,5 +1,7 @@
1
+ /// <reference types="node" />
1
2
  import { Config } from '@browserless.io/browserless';
2
- export declare class WebHooks {
3
+ import { EventEmitter } from 'events';
4
+ export declare class WebHooks extends EventEmitter {
3
5
  protected config: Config;
4
6
  constructor(config: Config);
5
7
  protected callURL(url: string | null): Promise<void | Response> | undefined;
@@ -8,4 +10,13 @@ export declare class WebHooks {
8
10
  callRejectAlertURL(): Promise<void | Response> | undefined;
9
11
  callTimeoutAlertURL(): Promise<void | Response> | undefined;
10
12
  callErrorAlertURL(message: string): void | Promise<void | Response>;
13
+ /**
14
+ * Implement any browserless-core-specific shutdown logic here.
15
+ * Calls the empty-SDK stop method for downstream implementations.
16
+ */
17
+ shutdown: () => Promise<void>;
18
+ /**
19
+ * Left blank for downstream SDK modules to optionally implement.
20
+ */
21
+ stop: () => void;
11
22
  }
package/build/webhooks.js CHANGED
@@ -1,7 +1,9 @@
1
1
  import { fetchTimeout, noop } from '@browserless.io/browserless';
2
- export class WebHooks {
2
+ import { EventEmitter } from 'events';
3
+ export class WebHooks extends EventEmitter {
3
4
  config;
4
5
  constructor(config) {
6
+ super();
5
7
  this.config = config;
6
8
  }
7
9
  callURL(url) {
@@ -40,4 +42,15 @@ export class WebHooks {
40
42
  return console.error(`Issue calling error hook: "${err}". Did you set a working ERROR_ALERT_URL env variable?`);
41
43
  }
42
44
  }
45
+ /**
46
+ * Implement any browserless-core-specific shutdown logic here.
47
+ * Calls the empty-SDK stop method for downstream implementations.
48
+ */
49
+ shutdown = async () => {
50
+ await this.stop();
51
+ };
52
+ /**
53
+ * Left blank for downstream SDK modules to optionally implement.
54
+ */
55
+ stop = () => { };
43
56
  }
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@browserless.io/browserless",
3
- "version": "2.4.0-beta-1",
3
+ "version": "2.4.0",
4
4
  "license": "SSPL",
5
5
  "description": "The browserless platform",
6
6
  "author": "browserless.io",
@@ -57,8 +57,8 @@
57
57
  "http-proxy": "^1.18.1",
58
58
  "lighthouse": "^11.1.0",
59
59
  "micromatch": "^4.0.4",
60
- "playwright-core": "^1.42.1",
61
- "puppeteer-core": "^22.3.0",
60
+ "playwright-core": "1.42.1",
61
+ "puppeteer-core": "^22.4.0",
62
62
  "puppeteer-extra": "^3.3.6",
63
63
  "puppeteer-extra-plugin-stealth": "^2.11.2",
64
64
  "queue": "^7.0.0",
@@ -71,10 +71,10 @@
71
71
  "@types/http-proxy": "^1.17.14",
72
72
  "@types/micromatch": "^4.0.6",
73
73
  "@types/mocha": "^10.0.6",
74
- "@types/node": "^20.11.24",
74
+ "@types/node": "^20.11.25",
75
75
  "@types/sinon": "^17.0.3",
76
- "@typescript-eslint/eslint-plugin": "^7.1.0",
77
- "@typescript-eslint/parser": "^7.1.0",
76
+ "@typescript-eslint/eslint-plugin": "^7.1.1",
77
+ "@typescript-eslint/parser": "^7.1.1",
78
78
  "assert": "^2.0.0",
79
79
  "chai": "^5.1.0",
80
80
  "cross-env": "^7.0.3",
@@ -84,13 +84,13 @@
84
84
  "eslint": "^8.57.0",
85
85
  "eslint-plugin-typescript-sort-keys": "^3.2.0",
86
86
  "extract-zip": "^2.0.1",
87
- "marked": "^12.0.0",
87
+ "marked": "^12.0.1",
88
88
  "mocha": "^10.3.0",
89
89
  "move-file": "^3.1.0",
90
90
  "prettier": "^3.2.5",
91
91
  "sinon": "^17.0.1",
92
92
  "ts-node": "^10.9.2",
93
- "typescript": "^5.3.3",
93
+ "typescript": "^5.4.2",
94
94
  "typescript-json-schema": "^0.63.0"
95
95
  },
96
96
  "eslintConfig": {