single-file-cli 2.0.75 → 2.0.77
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 +1 -1
- package/build.sh +1 -1
- package/deno.json +3 -3
- package/deno.lock +56 -21
- package/lib/browser.js +0 -3
- package/lib/cdp-client.js +88 -22
- package/lib/single-file-bundle.js +1 -1
- package/lib/single-file-script.js +59 -28
- package/lib/version.js +1 -1
- package/options.js +3 -0
- package/package.json +4 -4
- package/single-file-cli-api.js +1 -1
package/README.MD
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Introduction
|
|
4
4
|
|
|
5
|
-
[SingleFile](https://
|
|
5
|
+
[SingleFile](https://www.getsinglefile.com) can be launched from the command line by running it into a (headless) browser.
|
|
6
6
|
|
|
7
7
|
It runs through Deno as a standalone script injected into the web page via the Chrome DevTools Protocol instead of being embedded into a WebExtension.
|
|
8
8
|
|
package/build.sh
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
mv package.json package.json.tmp
|
|
4
4
|
mv deno.json deno.json.tmp
|
|
5
5
|
mv deno.lock deno.lock.tmp
|
|
6
|
-
deno install --vendor --quiet "npm:single-file-core@1.5.
|
|
6
|
+
deno install --vendor --quiet "npm:single-file-core@1.5.57"
|
|
7
7
|
mv package.json.tmp package.json
|
|
8
8
|
mv deno.json.tmp deno.json
|
|
9
9
|
mv deno.lock.tmp deno.lock
|
package/deno.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@single-file/single-file-cli",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.77",
|
|
4
4
|
"description": "SingleFile CLI",
|
|
5
5
|
"nodeModulesDir": "auto",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": "./single-file-cli-api.js"
|
|
8
8
|
},
|
|
9
9
|
"imports": {
|
|
10
|
-
"simple-cdp": "jsr:@simple-cdp/simple-cdp@^1.8.
|
|
11
|
-
"path": "jsr:@std/path@^
|
|
10
|
+
"simple-cdp": "jsr:@simple-cdp/simple-cdp@^1.8.6",
|
|
11
|
+
"path": "jsr:@std/path@^1.1.2"
|
|
12
12
|
}
|
|
13
13
|
}
|
package/deno.lock
CHANGED
|
@@ -1,48 +1,83 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "
|
|
2
|
+
"version": "5",
|
|
3
3
|
"specifiers": {
|
|
4
|
-
"jsr:@
|
|
5
|
-
"jsr:@
|
|
6
|
-
"jsr:@std/
|
|
7
|
-
"
|
|
8
|
-
"npm
|
|
9
|
-
"npm:
|
|
4
|
+
"jsr:@b-fuze/deno-dom@*": "0.1.56",
|
|
5
|
+
"jsr:@simple-cdp/simple-cdp@^1.8.6": "1.8.6",
|
|
6
|
+
"jsr:@std/internal@^1.0.10": "1.0.12",
|
|
7
|
+
"jsr:@std/path@^1.1.2": "1.1.2",
|
|
8
|
+
"npm:@eslint/js@^9.39.0": "9.39.0",
|
|
9
|
+
"npm:simple-cdp@^1.8.6": "1.8.6",
|
|
10
|
+
"npm:ws@^8.18.3": "8.18.3"
|
|
10
11
|
},
|
|
11
12
|
"jsr": {
|
|
13
|
+
"@b-fuze/deno-dom@0.1.56": {
|
|
14
|
+
"integrity": "8030e2dc1d8750f1682b53462ab893d9c3470f2287feecbe22f44a88c54ab148"
|
|
15
|
+
},
|
|
12
16
|
"@simple-cdp/simple-cdp@1.8.6": {
|
|
13
17
|
"integrity": "beabfb0dd8cb8c964f09249b94ef23334d65a583f622f43d6302222b25ee3af8"
|
|
14
18
|
},
|
|
15
|
-
"@std/
|
|
16
|
-
"integrity": "
|
|
19
|
+
"@std/internal@1.0.12": {
|
|
20
|
+
"integrity": "972a634fd5bc34b242024402972cd5143eac68d8dffaca5eaa4dba30ce17b027"
|
|
17
21
|
},
|
|
18
|
-
"@std/path@
|
|
19
|
-
"integrity": "
|
|
22
|
+
"@std/path@1.1.2": {
|
|
23
|
+
"integrity": "c0b13b97dfe06546d5e16bf3966b1cadf92e1cc83e56ba5476ad8b498d9e3038",
|
|
20
24
|
"dependencies": [
|
|
21
|
-
"jsr:@std/
|
|
25
|
+
"jsr:@std/internal"
|
|
22
26
|
]
|
|
23
27
|
}
|
|
24
28
|
},
|
|
25
29
|
"npm": {
|
|
26
|
-
"@eslint/js@9.
|
|
27
|
-
"integrity": "sha512-
|
|
30
|
+
"@eslint/js@9.39.0": {
|
|
31
|
+
"integrity": "sha512-BIhe0sW91JGPiaF1mOuPy5v8NflqfjIcDNpC+LbW9f609WVRX1rArrhi6Z2ymvrAry9jw+5POTj4t2t62o8Bmw=="
|
|
28
32
|
},
|
|
29
33
|
"simple-cdp@1.8.6": {
|
|
30
34
|
"integrity": "sha512-c33zKvBOOIBfdfDCr++N8Dv6kY03wD+cGuu3MEiBJHC4LtHE5aSwjw5E+dOSeuXolS+8MoDzYuWrJdT+IFp8bw=="
|
|
31
35
|
},
|
|
32
|
-
"ws@8.18.
|
|
33
|
-
"integrity": "sha512-
|
|
36
|
+
"ws@8.18.3": {
|
|
37
|
+
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="
|
|
34
38
|
}
|
|
35
39
|
},
|
|
40
|
+
"remote": {
|
|
41
|
+
"https://deno.land/std@0.200.0/assert/_constants.ts": "8a9da298c26750b28b326b297316cdde860bc237533b07e1337c021379e6b2a9",
|
|
42
|
+
"https://deno.land/std@0.200.0/assert/_diff.ts": "1a3c044aedf77647d6cac86b798c6417603361b66b54c53331b312caeb447aea",
|
|
43
|
+
"https://deno.land/std@0.200.0/assert/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7",
|
|
44
|
+
"https://deno.land/std@0.200.0/assert/assert.ts": "9a97dad6d98c238938e7540736b826440ad8c1c1e54430ca4c4e623e585607ee",
|
|
45
|
+
"https://deno.land/std@0.200.0/assert/assert_almost_equals.ts": "e15ca1f34d0d5e0afae63b3f5d975cbd18335a132e42b0c747d282f62ad2cd6c",
|
|
46
|
+
"https://deno.land/std@0.200.0/assert/assert_array_includes.ts": "6856d7f2c3544bc6e62fb4646dfefa3d1df5ff14744d1bca19f0cbaf3b0d66c9",
|
|
47
|
+
"https://deno.land/std@0.200.0/assert/assert_equals.ts": "d8ec8a22447fbaf2fc9d7c3ed2e66790fdb74beae3e482855d75782218d68227",
|
|
48
|
+
"https://deno.land/std@0.200.0/assert/assert_exists.ts": "407cb6b9fb23a835cd8d5ad804e2e2edbbbf3870e322d53f79e1c7a512e2efd7",
|
|
49
|
+
"https://deno.land/std@0.200.0/assert/assert_false.ts": "a9962749f4bf5844e3fa494257f1de73d69e4fe0e82c34d0099287552163a2dc",
|
|
50
|
+
"https://deno.land/std@0.200.0/assert/assert_instance_of.ts": "09fd297352a5b5bbb16da2b5e1a0d8c6c44da5447772648622dcc7df7af1ddb8",
|
|
51
|
+
"https://deno.land/std@0.200.0/assert/assert_is_error.ts": "b4eae4e5d182272efc172bf28e2e30b86bb1650cd88aea059e5d2586d4160fb9",
|
|
52
|
+
"https://deno.land/std@0.200.0/assert/assert_match.ts": "c4083f80600bc190309903c95e397a7c9257ff8b5ae5c7ef91e834704e672e9b",
|
|
53
|
+
"https://deno.land/std@0.200.0/assert/assert_not_equals.ts": "9f1acab95bd1f5fc9a1b17b8027d894509a745d91bac1718fdab51dc76831754",
|
|
54
|
+
"https://deno.land/std@0.200.0/assert/assert_not_instance_of.ts": "0c14d3dfd9ab7a5276ed8ed0b18c703d79a3d106102077ec437bfe7ed912bd22",
|
|
55
|
+
"https://deno.land/std@0.200.0/assert/assert_not_match.ts": "3796a5b0c57a1ce6c1c57883dd4286be13a26f715ea662318ab43a8491a13ab0",
|
|
56
|
+
"https://deno.land/std@0.200.0/assert/assert_not_strict_equals.ts": "ca6c6d645e95fbc873d25320efeb8c4c6089a9a5e09f92d7c1c4b6e935c2a6ad",
|
|
57
|
+
"https://deno.land/std@0.200.0/assert/assert_object_match.ts": "d8fc2867cfd92eeacf9cea621e10336b666de1874a6767b5ec48988838370b54",
|
|
58
|
+
"https://deno.land/std@0.200.0/assert/assert_rejects.ts": "45c59724de2701e3b1f67c391d6c71c392363635aad3f68a1b3408f9efca0057",
|
|
59
|
+
"https://deno.land/std@0.200.0/assert/assert_strict_equals.ts": "b1f538a7ea5f8348aeca261d4f9ca603127c665e0f2bbfeb91fa272787c87265",
|
|
60
|
+
"https://deno.land/std@0.200.0/assert/assert_string_includes.ts": "b821d39ebf5cb0200a348863c86d8c4c4b398e02012ce74ad15666fc4b631b0c",
|
|
61
|
+
"https://deno.land/std@0.200.0/assert/assert_throws.ts": "63784e951475cb7bdfd59878cd25a0931e18f6dc32a6077c454b2cd94f4f4bcd",
|
|
62
|
+
"https://deno.land/std@0.200.0/assert/assertion_error.ts": "4d0bde9b374dfbcbe8ac23f54f567b77024fb67dbb1906a852d67fe050d42f56",
|
|
63
|
+
"https://deno.land/std@0.200.0/assert/equal.ts": "9f1a46d5993966d2596c44e5858eec821859b45f783a5ee2f7a695dfc12d8ece",
|
|
64
|
+
"https://deno.land/std@0.200.0/assert/fail.ts": "c36353d7ae6e1f7933d45f8ea51e358c8c4b67d7e7502028598fe1fea062e278",
|
|
65
|
+
"https://deno.land/std@0.200.0/assert/mod.ts": "08d55a652c22c5da0215054b21085cec25a5da47ce4a6f9de7d9ad36df35bdee",
|
|
66
|
+
"https://deno.land/std@0.200.0/assert/unimplemented.ts": "d56fbeecb1f108331a380f72e3e010a1f161baa6956fd0f7cf3e095ae1a4c75a",
|
|
67
|
+
"https://deno.land/std@0.200.0/assert/unreachable.ts": "4600dc0baf7d9c15a7f7d234f00c23bca8f3eba8b140286aaca7aa998cf9a536",
|
|
68
|
+
"https://deno.land/std@0.200.0/fmt/colors.ts": "a7eecffdf3d1d54db890723b303847b6e0a1ab4b528ba6958b8f2e754cf1b3bc",
|
|
69
|
+
"https://deno.land/std@0.200.0/testing/asserts.ts": "b4e4b1359393aeff09e853e27901a982c685cb630df30426ed75496961931946"
|
|
70
|
+
},
|
|
36
71
|
"workspace": {
|
|
37
72
|
"dependencies": [
|
|
38
|
-
"jsr:@simple-cdp/simple-cdp@^1.8.
|
|
39
|
-
"jsr:@std/path
|
|
73
|
+
"jsr:@simple-cdp/simple-cdp@^1.8.6",
|
|
74
|
+
"jsr:@std/path@^1.1.2"
|
|
40
75
|
],
|
|
41
76
|
"packageJson": {
|
|
42
77
|
"dependencies": [
|
|
43
|
-
"npm:@eslint/js@^9.
|
|
44
|
-
"npm:simple-cdp@^1.8.
|
|
45
|
-
"npm:ws@^8.18.
|
|
78
|
+
"npm:@eslint/js@^9.39.0",
|
|
79
|
+
"npm:simple-cdp@^1.8.6",
|
|
80
|
+
"npm:ws@^8.18.3"
|
|
46
81
|
]
|
|
47
82
|
}
|
|
48
83
|
}
|
package/lib/browser.js
CHANGED
|
@@ -48,9 +48,6 @@ async function launchBrowser(options = {}, indexPath = 0) {
|
|
|
48
48
|
if (options.debug) {
|
|
49
49
|
args.push("--auto-open-devtools-for-tabs");
|
|
50
50
|
}
|
|
51
|
-
if (options.disableWebSecurity) {
|
|
52
|
-
args.push("--disable-web-security");
|
|
53
|
-
}
|
|
54
51
|
if (options.width && options.height) {
|
|
55
52
|
args.push("--window-size=" + options.width + "," + options.height);
|
|
56
53
|
}
|
package/lib/cdp-client.js
CHANGED
|
@@ -21,10 +21,16 @@
|
|
|
21
21
|
* Source.
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
/* global setTimeout, clearTimeout, URL, fetch, AbortController, window, top, singlefile */
|
|
24
|
+
/* global setTimeout, clearTimeout, URL, fetch, AbortController, window, top, singlefile, btoa, Headers, Deno */
|
|
25
25
|
|
|
26
26
|
import { launchBrowser, closeBrowser } from "./browser.js";
|
|
27
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
FETCH_FUNCTION_NAME,
|
|
29
|
+
RESOLVE_FETCH_FUNCTION_NAME,
|
|
30
|
+
REJECT_FETCH_FUNCTION_NAME,
|
|
31
|
+
getScriptSource,
|
|
32
|
+
getHookScriptSource
|
|
33
|
+
} from "./single-file-script.js";
|
|
28
34
|
import { CDP, options } from "simple-cdp";
|
|
29
35
|
|
|
30
36
|
const LOAD_TIMEOUT_ERROR = "ERR_LOAD_TIMEOUT";
|
|
@@ -42,6 +48,41 @@ const REDIRECT_STATUS_CODES = [301, 302, 303, 307, 308];
|
|
|
42
48
|
|
|
43
49
|
export { initialize, getPageData, closeBrowser };
|
|
44
50
|
|
|
51
|
+
async function fetchWithFileSupport(url, fetchOptions = {}) {
|
|
52
|
+
if (url.startsWith("file://")) {
|
|
53
|
+
const filePath = decodeURIComponent(url.replace(/^file:\/\//, ""));
|
|
54
|
+
let fileData;
|
|
55
|
+
if (typeof Deno !== "undefined") {
|
|
56
|
+
const response = await fetch(url, fetchOptions);
|
|
57
|
+
return response;
|
|
58
|
+
} else {
|
|
59
|
+
const { readFile } = await import("node:fs/promises");
|
|
60
|
+
try {
|
|
61
|
+
fileData = await readFile(filePath);
|
|
62
|
+
return {
|
|
63
|
+
status: 200,
|
|
64
|
+
headers: new Headers({
|
|
65
|
+
"content-type": "application/octet-stream",
|
|
66
|
+
"content-length": fileData.length.toString()
|
|
67
|
+
}),
|
|
68
|
+
arrayBuffer: async () => fileData.buffer
|
|
69
|
+
};
|
|
70
|
+
} catch {
|
|
71
|
+
return {
|
|
72
|
+
status: 404,
|
|
73
|
+
headers: new Headers({
|
|
74
|
+
"content-type": "text/plain",
|
|
75
|
+
"content-length": "0"
|
|
76
|
+
}),
|
|
77
|
+
arrayBuffer: async () => new ArrayBuffer(0)
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
return await fetch(url, fetchOptions);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
45
86
|
async function initialize(singleFileOptions) {
|
|
46
87
|
if (singleFileOptions.browserServer) {
|
|
47
88
|
options.apiUrl = singleFileOptions.browserServer;
|
|
@@ -85,12 +126,6 @@ async function getPageData(options) {
|
|
|
85
126
|
}
|
|
86
127
|
await Security.setIgnoreCertificateErrors({ ignore: true });
|
|
87
128
|
}
|
|
88
|
-
if (options.browserByPassCSP === undefined || options.browserByPassCSP) {
|
|
89
|
-
if (options.debugMessagesFile) {
|
|
90
|
-
debugMessages.push([Date.now(), ["Bypassing CSP"]]);
|
|
91
|
-
}
|
|
92
|
-
await Page.setBypassCSP({ enabled: true });
|
|
93
|
-
}
|
|
94
129
|
if (options.browserMobileEmulation || options.browserDeviceWidth || options.browserDeviceHeight || options.browserDeviceScaleFactor || options.platform || options.acceptLanguage) {
|
|
95
130
|
if (options.browserMobileEmulation || options.browserDeviceWidth || options.browserDeviceHeight || options.browserDeviceScaleFactor) {
|
|
96
131
|
let browserDeviceWidth;
|
|
@@ -295,6 +330,41 @@ async function getPageData(options) {
|
|
|
295
330
|
}
|
|
296
331
|
});
|
|
297
332
|
}
|
|
333
|
+
await Runtime.addBinding({ name: FETCH_FUNCTION_NAME, executionContextId: contextId });
|
|
334
|
+
Runtime.addEventListener("bindingCalled", async ({ params }) => {
|
|
335
|
+
if (params.name === FETCH_FUNCTION_NAME) {
|
|
336
|
+
let { payload } = params;
|
|
337
|
+
payload = JSON.parse(payload);
|
|
338
|
+
const { requestId, url, options: fetchOptions } = payload;
|
|
339
|
+
if (options.debugMessagesFile) {
|
|
340
|
+
debugMessages.push([Date.now(), ["Fetching URL", url]]);
|
|
341
|
+
}
|
|
342
|
+
try {
|
|
343
|
+
const response = await fetchWithFileSupport(url, fetchOptions);
|
|
344
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
345
|
+
const uint8Array = new Uint8Array(arrayBuffer);
|
|
346
|
+
const data = btoa(String.fromCharCode.apply(null, uint8Array));
|
|
347
|
+
const result = {
|
|
348
|
+
status: response.status,
|
|
349
|
+
headers: Object.fromEntries(response.headers.entries()),
|
|
350
|
+
data
|
|
351
|
+
};
|
|
352
|
+
await Runtime.evaluate({
|
|
353
|
+
expression: `globalThis.${RESOLVE_FETCH_FUNCTION_NAME}(${JSON.stringify(requestId)}, ${JSON.stringify(result)})`,
|
|
354
|
+
contextId
|
|
355
|
+
});
|
|
356
|
+
} catch (error) {
|
|
357
|
+
const errorResult = {
|
|
358
|
+
error: error.message,
|
|
359
|
+
code: error.code
|
|
360
|
+
};
|
|
361
|
+
await Runtime.evaluate({
|
|
362
|
+
expression: `globalThis.${REJECT_FETCH_FUNCTION_NAME}(${JSON.stringify(requestId)}, ${JSON.stringify(errorResult)})`,
|
|
363
|
+
contextId
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
});
|
|
298
368
|
const pageDataPromise = new Promise(resolve => {
|
|
299
369
|
let pageDataResponse = "";
|
|
300
370
|
Runtime.addEventListener("bindingCalled", ({ params }) => {
|
|
@@ -597,20 +667,16 @@ function waitForTimeout(abortSignal, maxDelay, errorMessage, errorCode) {
|
|
|
597
667
|
|
|
598
668
|
async function waitForDebuggerReady({ Debugger }) {
|
|
599
669
|
await Debugger.enable();
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
Debugger.addEventListener(RESUMED_EVENT, onResumed);
|
|
670
|
+
await Debugger.pause();
|
|
671
|
+
await new Promise(resolve => {
|
|
672
|
+
const RESUMED_EVENT = "resumed";
|
|
673
|
+
Debugger.addEventListener(RESUMED_EVENT, onResumed);
|
|
605
674
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
} finally {
|
|
612
|
-
await Debugger.disable();
|
|
613
|
-
}
|
|
675
|
+
function onResumed() {
|
|
676
|
+
Debugger.removeEventListener(RESUMED_EVENT, onResumed);
|
|
677
|
+
resolve();
|
|
678
|
+
}
|
|
679
|
+
});
|
|
614
680
|
}
|
|
615
681
|
|
|
616
682
|
function getBrowserOptions(options) {
|
|
@@ -619,7 +685,7 @@ function getBrowserOptions(options) {
|
|
|
619
685
|
browserOptions.headless = options.browserHeadless;
|
|
620
686
|
browserOptions.executablePath = options.browserExecutablePath;
|
|
621
687
|
browserOptions.debug = options.browserDebug;
|
|
622
|
-
browserOptions.disableWebSecurity = options.browserDisableWebSecurity
|
|
688
|
+
browserOptions.disableWebSecurity = options.browserDisableWebSecurity;
|
|
623
689
|
browserOptions.width = options.browserWidth;
|
|
624
690
|
browserOptions.height = options.browserHeight;
|
|
625
691
|
browserOptions.userAgent = options.userAgent;
|