@browserless.io/browserless 2.4.0 → 2.5.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.
Files changed (51) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/bin/browserless.js +17 -127
  3. package/bin/scaffold/README.md +95 -14
  4. package/build/browserless.d.ts +4 -2
  5. package/build/browserless.js +9 -6
  6. package/build/browsers/index.d.ts +3 -2
  7. package/build/browsers/index.js +6 -4
  8. package/build/data/selectors.json +1 -1
  9. package/build/exports.d.ts +1 -0
  10. package/build/exports.js +1 -0
  11. package/build/file-system.d.ts +2 -3
  12. package/build/file-system.js +10 -21
  13. package/build/file-system.spec.js +35 -18
  14. package/build/hooks.d.ts +9 -4
  15. package/build/hooks.js +26 -8
  16. package/build/limiter.d.ts +3 -2
  17. package/build/limiter.js +5 -3
  18. package/build/limiter.spec.js +45 -26
  19. package/build/routes/chrome/http/content.post.body.json +8 -8
  20. package/build/routes/chrome/http/pdf.post.body.json +8 -8
  21. package/build/routes/chrome/http/scrape.post.body.json +8 -8
  22. package/build/routes/chrome/http/screenshot.post.body.json +8 -8
  23. package/build/routes/chromium/http/content.post.body.json +8 -8
  24. package/build/routes/chromium/http/pdf.post.body.json +8 -8
  25. package/build/routes/chromium/http/scrape.post.body.json +8 -8
  26. package/build/routes/chromium/http/screenshot.post.body.json +8 -8
  27. package/build/routes/management/http/metrics-total.get.js +1 -1
  28. package/build/routes/management/http/metrics.get.js +2 -2
  29. package/build/sdk-utils.d.ts +13 -0
  30. package/build/sdk-utils.js +94 -0
  31. package/build/server.d.ts +3 -2
  32. package/build/server.js +6 -4
  33. package/build/utils.js +2 -1
  34. package/package.json +7 -7
  35. package/src/browserless.ts +20 -3
  36. package/src/browsers/index.ts +7 -5
  37. package/src/exports.ts +1 -0
  38. package/src/file-system.spec.ts +43 -18
  39. package/src/file-system.ts +16 -30
  40. package/src/hooks.ts +32 -8
  41. package/src/limiter.spec.ts +82 -112
  42. package/src/limiter.ts +3 -3
  43. package/src/routes/management/http/metrics-total.get.ts +3 -3
  44. package/src/routes/management/http/metrics.get.ts +2 -2
  45. package/src/sdk-utils.ts +136 -0
  46. package/src/server.ts +4 -3
  47. package/src/shared/content.http.ts +0 -1
  48. package/src/utils.ts +2 -1
  49. package/static/docs/swagger.json +11 -11
  50. package/static/docs/swagger.min.json +10 -10
  51. package/static/function/client.js +76 -63
@@ -0,0 +1,136 @@
1
+ import { createInterface } from 'readline';
2
+ import debug from 'debug';
3
+ import fs from 'fs/promises';
4
+ import path from 'path';
5
+ import { spawn } from 'child_process';
6
+
7
+ export const getArgSwitches = () => {
8
+ return process.argv.reduce(
9
+ (accum, arg, idx) => {
10
+ if (!arg.startsWith('--')) {
11
+ return accum;
12
+ }
13
+
14
+ if (arg.includes('=')) {
15
+ const [parameter, value] = arg.split('=');
16
+ accum[parameter.replace(/-/gi, '')] = value || true;
17
+ return accum;
18
+ }
19
+
20
+ const nextSwitchOrParameter = process.argv[idx + 1];
21
+ const param = arg.replace(/-/gi, '');
22
+
23
+ if (
24
+ typeof nextSwitchOrParameter === 'undefined' ||
25
+ nextSwitchOrParameter?.startsWith('--')
26
+ ) {
27
+ accum[param] = true;
28
+ return accum;
29
+ }
30
+
31
+ accum[param] = nextSwitchOrParameter;
32
+
33
+ return accum;
34
+ },
35
+ {} as { [key: string]: string | true },
36
+ );
37
+ };
38
+
39
+ export const getSourceFiles = async (cwd: string) => {
40
+ const buildDir = path.join(cwd, 'build');
41
+ const files = await fs.readdir(buildDir, { recursive: true });
42
+ const [httpRoutes, webSocketRoutes] = files.reduce(
43
+ ([httpRoutes, webSocketRoutes], file) => {
44
+ const parsed = path.parse(file);
45
+ if (parsed.name.endsWith('http')) {
46
+ httpRoutes.push(path.join(buildDir, file));
47
+ }
48
+
49
+ if (parsed.name.endsWith('ws')) {
50
+ webSocketRoutes.push(path.join(buildDir, file));
51
+ }
52
+
53
+ return [httpRoutes, webSocketRoutes];
54
+ },
55
+ [[] as string[], [] as string[]],
56
+ );
57
+
58
+ return {
59
+ files,
60
+ httpRoutes,
61
+ webSocketRoutes,
62
+ };
63
+ };
64
+
65
+ export const camelCase = (str: string) =>
66
+ str.replace(/-([a-z])/g, (_, w) => w.toUpperCase());
67
+
68
+ export const prompt = async (question: string) => {
69
+ const promptLog = debug('browserless.io:prompt');
70
+ const rl = createInterface({
71
+ input: process.stdin,
72
+ output: process.stdout,
73
+ });
74
+
75
+ return new Promise((resolve) => {
76
+ promptLog(question);
77
+ rl.question(' > ', (a) => {
78
+ rl.close();
79
+ resolve(a.trim());
80
+ });
81
+ });
82
+ };
83
+
84
+ export const installDependencies = async (
85
+ workingDirectory: string,
86
+ ): Promise<void> =>
87
+ new Promise((resolve, reject) => {
88
+ spawn('npm', ['i'], {
89
+ cwd: workingDirectory,
90
+ stdio: 'inherit',
91
+ }).once('close', (code) => {
92
+ if (code === 0) {
93
+ return resolve();
94
+ }
95
+ return reject(
96
+ `Error when installing dependencies, see output for more details`,
97
+ );
98
+ });
99
+ });
100
+
101
+ export const buildDockerImage = async (
102
+ cmd: string,
103
+ projectDir: string,
104
+ ): Promise<void> =>
105
+ new Promise((resolve, reject) => {
106
+ const [docker, ...args] = cmd.split(' ');
107
+ spawn(docker, args, {
108
+ cwd: projectDir,
109
+ stdio: 'inherit',
110
+ }).once('close', (code) => {
111
+ if (code === 0) {
112
+ return resolve();
113
+ }
114
+ return reject(
115
+ `Error when building Docker image, see output for more details`,
116
+ );
117
+ });
118
+ });
119
+
120
+ export const buildTypeScript = async (
121
+ buildDir: string,
122
+ projectDir: string,
123
+ ): Promise<void> =>
124
+ new Promise((resolve, reject) => {
125
+ spawn('npx', ['tsc', '--outDir', buildDir], {
126
+ cwd: projectDir,
127
+ stdio: 'inherit',
128
+ }).once('close', (code) => {
129
+ if (code === 0) {
130
+ return resolve();
131
+ }
132
+ return reject(
133
+ `Error in building TypeScript, see output for more details`,
134
+ );
135
+ });
136
+ });
package/src/server.ts CHANGED
@@ -4,6 +4,7 @@ import {
4
4
  BadRequest,
5
5
  Config,
6
6
  HTTPRoute,
7
+ Hooks,
7
8
  Metrics,
8
9
  NotFound,
9
10
  Request,
@@ -14,7 +15,6 @@ import {
14
15
  TooManyRequests,
15
16
  Unauthorized,
16
17
  WebSocketRoute,
17
- beforeRequest,
18
18
  contentTypes,
19
19
  convertPathToURL,
20
20
  createLogger,
@@ -48,6 +48,7 @@ export class HTTPServer extends EventEmitter {
48
48
  protected metrics: Metrics,
49
49
  protected token: Token,
50
50
  protected router: Router,
51
+ protected hooks: Hooks,
51
52
  ) {
52
53
  super();
53
54
  this.host = config.getHost();
@@ -111,7 +112,7 @@ export class HTTPServer extends EventEmitter {
111
112
  );
112
113
 
113
114
  const req = request as Request;
114
- const proceed = await beforeRequest({ req, res });
115
+ const proceed = await this.hooks.before({ req, res });
115
116
  req.parsed = convertPathToURL(request.url || '', this.config);
116
117
  shimLegacyRequests(req.parsed);
117
118
 
@@ -297,7 +298,7 @@ export class HTTPServer extends EventEmitter {
297
298
  this.verbose(`Handling inbound WebSocket request on "${request.url}"`);
298
299
 
299
300
  const req = request as Request;
300
- const proceed = await beforeRequest({ head, req, socket });
301
+ const proceed = await this.hooks.before({ head, req, socket });
301
302
  req.parsed = convertPathToURL(request.url || '', this.config);
302
303
  shimLegacyRequests(req.parsed);
303
304
 
@@ -180,7 +180,6 @@ export default class ChromiumContentPostRoute extends BrowserHTTPRoute {
180
180
  bestAttemptCatch(bestAttempt),
181
181
  );
182
182
 
183
-
184
183
  if (addStyleTag.length) {
185
184
  for (const tag in addStyleTag) {
186
185
  await page.addStyleTag(addStyleTag[tag]);
package/src/utils.ts CHANGED
@@ -745,7 +745,8 @@ export const encrypt = (text: string, secret: Buffer) => {
745
745
  };
746
746
 
747
747
  export const decrypt = (encryptedText: string, secret: Buffer) => {
748
- const [encrypted, iv] = encryptedText.split(encryptionSep);
748
+ const [encrypted, iv] = encryptedText.toString().split(encryptionSep);
749
+ console.log('>>', encryptedText.toString());
749
750
  if (!iv) throw new ServerError('Bad or invalid encrypted format');
750
751
  const decipher = crypto.createDecipheriv(
751
752
  encryptionAlgo,