@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.
- package/CHANGELOG.md +7 -0
- package/bin/browserless.js +17 -127
- package/bin/scaffold/README.md +95 -14
- package/build/browserless.d.ts +4 -2
- package/build/browserless.js +9 -6
- package/build/browsers/index.d.ts +3 -2
- package/build/browsers/index.js +6 -4
- package/build/data/selectors.json +1 -1
- package/build/exports.d.ts +1 -0
- package/build/exports.js +1 -0
- package/build/file-system.d.ts +2 -3
- package/build/file-system.js +10 -21
- package/build/file-system.spec.js +35 -18
- package/build/hooks.d.ts +9 -4
- package/build/hooks.js +26 -8
- package/build/limiter.d.ts +3 -2
- package/build/limiter.js +5 -3
- package/build/limiter.spec.js +45 -26
- package/build/routes/chrome/http/content.post.body.json +8 -8
- package/build/routes/chrome/http/pdf.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/content.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/routes/management/http/metrics-total.get.js +1 -1
- package/build/routes/management/http/metrics.get.js +2 -2
- package/build/sdk-utils.d.ts +13 -0
- package/build/sdk-utils.js +94 -0
- package/build/server.d.ts +3 -2
- package/build/server.js +6 -4
- package/build/utils.js +2 -1
- package/package.json +7 -7
- package/src/browserless.ts +20 -3
- package/src/browsers/index.ts +7 -5
- package/src/exports.ts +1 -0
- package/src/file-system.spec.ts +43 -18
- package/src/file-system.ts +16 -30
- package/src/hooks.ts +32 -8
- package/src/limiter.spec.ts +82 -112
- package/src/limiter.ts +3 -3
- package/src/routes/management/http/metrics-total.get.ts +3 -3
- package/src/routes/management/http/metrics.get.ts +2 -2
- package/src/sdk-utils.ts +136 -0
- package/src/server.ts +4 -3
- package/src/shared/content.http.ts +0 -1
- package/src/utils.ts +2 -1
- package/static/docs/swagger.json +11 -11
- package/static/docs/swagger.min.json +10 -10
- package/static/function/client.js +76 -63
package/src/sdk-utils.ts
ADDED
|
@@ -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
|
|
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
|
|
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
|
|
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,
|