@xbrowser/cli 1.7.5 → 1.7.7
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/dist/cli.js +14 -69
- package/dist/daemon-main.js +7 -65
- package/dist/index.js +14 -69
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2798,78 +2798,19 @@ async function detectSpaRoutes(page, origin) {
|
|
|
2798
2798
|
const routeSet = /* @__PURE__ */ new Set();
|
|
2799
2799
|
const pathRegex = /['"`](\/[a-zA-Z0-9_\-/]+)['"`]/g;
|
|
2800
2800
|
const isParamRoute = (p) => p.includes(":") || p.includes("*");
|
|
2801
|
-
|
|
2801
|
+
try {
|
|
2802
|
+
const inlineContent = await page.evaluate(() => {
|
|
2803
|
+
return Array.from(document.querySelectorAll("script")).map((s) => s.textContent || "").join("\n");
|
|
2804
|
+
});
|
|
2802
2805
|
let match;
|
|
2803
|
-
while ((match = pathRegex.exec(
|
|
2806
|
+
while ((match = pathRegex.exec(inlineContent)) !== null) {
|
|
2804
2807
|
const path3 = match[1];
|
|
2805
2808
|
if (!isParamRoute(path3)) routeSet.add(path3);
|
|
2806
2809
|
}
|
|
2807
|
-
}
|
|
2808
|
-
const scriptData = await page.evaluate(() => {
|
|
2809
|
-
const scripts = Array.from(document.querySelectorAll("script"));
|
|
2810
|
-
return {
|
|
2811
|
-
inlineContent: scripts.map((s) => s.textContent || "").join("\n"),
|
|
2812
|
-
externalUrls: scripts.map((s) => s.src).filter((src) => src && !src.includes("analytics") && !src.includes("google") && !src.includes("baidu"))
|
|
2813
|
-
};
|
|
2814
|
-
});
|
|
2815
|
-
const { inlineContent, externalUrls } = scriptData;
|
|
2816
|
-
extractPaths(inlineContent);
|
|
2817
|
-
for (const src of externalUrls) {
|
|
2818
|
-
try {
|
|
2819
|
-
const absoluteSrc = src.startsWith("http") ? src : new URL(src, page.url()).href;
|
|
2820
|
-
const resp = await fetch(absoluteSrc, { signal: AbortSignal.timeout(5e3) });
|
|
2821
|
-
if (resp.ok) {
|
|
2822
|
-
const text = await resp.text();
|
|
2823
|
-
extractPaths(text);
|
|
2824
|
-
}
|
|
2825
|
-
} catch {
|
|
2826
|
-
}
|
|
2827
|
-
}
|
|
2828
|
-
try {
|
|
2829
|
-
const vueRoutes = await page.evaluate((evalOrigin) => {
|
|
2830
|
-
const routes2 = [];
|
|
2831
|
-
const win = window;
|
|
2832
|
-
const vue3App = win.__vue_app__;
|
|
2833
|
-
const vue3Router = vue3App?.config?.globalProperties?.$router;
|
|
2834
|
-
let router = vue3Router;
|
|
2835
|
-
if (!router) {
|
|
2836
|
-
let vm;
|
|
2837
|
-
const appById = document.getElementById("app");
|
|
2838
|
-
if (appById) {
|
|
2839
|
-
vm = appById.__vue__;
|
|
2840
|
-
}
|
|
2841
|
-
if (!vm) {
|
|
2842
|
-
let walkVue2 = function(node) {
|
|
2843
|
-
const prop = node.__vue__;
|
|
2844
|
-
if (prop) return prop;
|
|
2845
|
-
for (let i = 0; i < node.children.length; i++) {
|
|
2846
|
-
const found = walkVue2(node.children[i]);
|
|
2847
|
-
if (found) return found;
|
|
2848
|
-
}
|
|
2849
|
-
return void 0;
|
|
2850
|
-
};
|
|
2851
|
-
var walkVue = walkVue2;
|
|
2852
|
-
vm = walkVue2(document.body);
|
|
2853
|
-
}
|
|
2854
|
-
const vmRouter = vm?.$router;
|
|
2855
|
-
const vmRootRouter = vm?.$root?.$router;
|
|
2856
|
-
if (!router) router = vmRouter || vmRootRouter;
|
|
2857
|
-
}
|
|
2858
|
-
const routeList = router?.options?.routes;
|
|
2859
|
-
if (routeList) {
|
|
2860
|
-
for (const r of routeList) {
|
|
2861
|
-
if (r.path && !r.path.includes(":") && r.path !== "/" && r.path !== "") {
|
|
2862
|
-
routes2.push(`${evalOrigin.replace(/\/$/, "")}/#${r.path}`);
|
|
2863
|
-
}
|
|
2864
|
-
}
|
|
2865
|
-
}
|
|
2866
|
-
return routes2;
|
|
2867
|
-
}, origin);
|
|
2868
|
-
for (const r of vueRoutes) routeSet.add(r);
|
|
2869
2810
|
} catch {
|
|
2870
2811
|
}
|
|
2871
2812
|
return Array.from(routeSet).map(
|
|
2872
|
-
(p) =>
|
|
2813
|
+
(p) => `${origin.replace(/\/$/, "")}${p.startsWith("/") ? "" : "/"}${p}`
|
|
2873
2814
|
);
|
|
2874
2815
|
}
|
|
2875
2816
|
function parseRobotsTxt(text) {
|
|
@@ -5604,6 +5545,7 @@ registerCommandDefinition("actions", ["url"]);
|
|
|
5604
5545
|
registerCommandDefinition("find", ["strategy", "value", "operation"]);
|
|
5605
5546
|
registerCommandDefinition("addinitscript", ["script"]);
|
|
5606
5547
|
registerCommandDefinition("tab", ["subcommand"]);
|
|
5548
|
+
registerCommandDefinition("mouse", ["action", "x", "y"]);
|
|
5607
5549
|
|
|
5608
5550
|
// src/commands/addinitscript.ts
|
|
5609
5551
|
var InitScriptParams = z24.object({
|
|
@@ -7728,7 +7670,7 @@ async function executeChain(input, options) {
|
|
|
7728
7670
|
}
|
|
7729
7671
|
}
|
|
7730
7672
|
function isChainInput(input) {
|
|
7731
|
-
return /\s&&\s|\|\|\s|\s;\s|\s,\s|\s\+\s|\s->\s/.test(input);
|
|
7673
|
+
return /\s&&\s|\|\|\s|\s;\s|;\s|\s,\s|\s\+\s|\s->\s/.test(input);
|
|
7732
7674
|
}
|
|
7733
7675
|
|
|
7734
7676
|
// src/session/session-client.ts
|
|
@@ -12640,7 +12582,9 @@ async function handleEvalMode(argv) {
|
|
|
12640
12582
|
if (evalCommands.length === 0) return;
|
|
12641
12583
|
const chain = evalCommands.join(" ; ");
|
|
12642
12584
|
const cdpEndpoint = extractCdpFromArgv(argv);
|
|
12643
|
-
const
|
|
12585
|
+
const sessionArgIdx = argv.indexOf("--session");
|
|
12586
|
+
const sessionName = sessionArgIdx >= 0 && argv[sessionArgIdx + 1] ? argv[sessionArgIdx + 1] : process.env.XBROWSER_SESSION || "default";
|
|
12587
|
+
const chainResult = await executeChain(chain, { cdpEndpoint, sessionName });
|
|
12644
12588
|
printChainResult(chainResult);
|
|
12645
12589
|
if (!chainResult.success) throw new Error("Command failed");
|
|
12646
12590
|
}
|
|
@@ -12701,7 +12645,8 @@ async function routeCommand(argvIn, stdinCommands) {
|
|
|
12701
12645
|
const possibleCmd = chainArg.substring(0, spaceIdx);
|
|
12702
12646
|
if (/^[a-zA-Z][\w-]*$/.test(possibleCmd)) {
|
|
12703
12647
|
const remainder = chainArg.substring(spaceIdx + 1);
|
|
12704
|
-
|
|
12648
|
+
let remainderParts = remainder.split(/\s+/).filter(Boolean);
|
|
12649
|
+
remainderParts = remainderParts.flatMap((part) => part.split(";").filter(Boolean));
|
|
12705
12650
|
argv = [...argv.slice(0, chainArgIdx), possibleCmd, ...remainderParts, ...argv.slice(chainArgIdx + 1)];
|
|
12706
12651
|
}
|
|
12707
12652
|
}
|
|
@@ -12723,7 +12668,7 @@ async function routeCommand(argvIn, stdinCommands) {
|
|
|
12723
12668
|
return;
|
|
12724
12669
|
}
|
|
12725
12670
|
if (positional.length === 0) {
|
|
12726
|
-
const chainHints = [options.json, options.yaml, options.session, options.cdp].filter(Boolean).find((v) => typeof v === "string" && v
|
|
12671
|
+
const chainHints = [options.json, options.yaml, options.session, options.cdp].filter(Boolean).find((v) => typeof v === "string" && /^[a-zA-Z]/.test(v));
|
|
12727
12672
|
if (chainHints) {
|
|
12728
12673
|
positional.push(chainHints);
|
|
12729
12674
|
} else {
|
package/dist/daemon-main.js
CHANGED
|
@@ -2765,78 +2765,19 @@ async function detectSpaRoutes(page, origin) {
|
|
|
2765
2765
|
const routeSet = /* @__PURE__ */ new Set();
|
|
2766
2766
|
const pathRegex = /['"`](\/[a-zA-Z0-9_\-/]+)['"`]/g;
|
|
2767
2767
|
const isParamRoute = (p) => p.includes(":") || p.includes("*");
|
|
2768
|
-
|
|
2768
|
+
try {
|
|
2769
|
+
const inlineContent = await page.evaluate(() => {
|
|
2770
|
+
return Array.from(document.querySelectorAll("script")).map((s) => s.textContent || "").join("\n");
|
|
2771
|
+
});
|
|
2769
2772
|
let match;
|
|
2770
|
-
while ((match = pathRegex.exec(
|
|
2773
|
+
while ((match = pathRegex.exec(inlineContent)) !== null) {
|
|
2771
2774
|
const path2 = match[1];
|
|
2772
2775
|
if (!isParamRoute(path2)) routeSet.add(path2);
|
|
2773
2776
|
}
|
|
2774
|
-
}
|
|
2775
|
-
const scriptData = await page.evaluate(() => {
|
|
2776
|
-
const scripts = Array.from(document.querySelectorAll("script"));
|
|
2777
|
-
return {
|
|
2778
|
-
inlineContent: scripts.map((s) => s.textContent || "").join("\n"),
|
|
2779
|
-
externalUrls: scripts.map((s) => s.src).filter((src) => src && !src.includes("analytics") && !src.includes("google") && !src.includes("baidu"))
|
|
2780
|
-
};
|
|
2781
|
-
});
|
|
2782
|
-
const { inlineContent, externalUrls } = scriptData;
|
|
2783
|
-
extractPaths(inlineContent);
|
|
2784
|
-
for (const src of externalUrls) {
|
|
2785
|
-
try {
|
|
2786
|
-
const absoluteSrc = src.startsWith("http") ? src : new URL(src, page.url()).href;
|
|
2787
|
-
const resp = await fetch(absoluteSrc, { signal: AbortSignal.timeout(5e3) });
|
|
2788
|
-
if (resp.ok) {
|
|
2789
|
-
const text = await resp.text();
|
|
2790
|
-
extractPaths(text);
|
|
2791
|
-
}
|
|
2792
|
-
} catch {
|
|
2793
|
-
}
|
|
2794
|
-
}
|
|
2795
|
-
try {
|
|
2796
|
-
const vueRoutes = await page.evaluate((evalOrigin) => {
|
|
2797
|
-
const routes = [];
|
|
2798
|
-
const win = window;
|
|
2799
|
-
const vue3App = win.__vue_app__;
|
|
2800
|
-
const vue3Router = vue3App?.config?.globalProperties?.$router;
|
|
2801
|
-
let router = vue3Router;
|
|
2802
|
-
if (!router) {
|
|
2803
|
-
let vm;
|
|
2804
|
-
const appById = document.getElementById("app");
|
|
2805
|
-
if (appById) {
|
|
2806
|
-
vm = appById.__vue__;
|
|
2807
|
-
}
|
|
2808
|
-
if (!vm) {
|
|
2809
|
-
let walkVue2 = function(node) {
|
|
2810
|
-
const prop = node.__vue__;
|
|
2811
|
-
if (prop) return prop;
|
|
2812
|
-
for (let i = 0; i < node.children.length; i++) {
|
|
2813
|
-
const found = walkVue2(node.children[i]);
|
|
2814
|
-
if (found) return found;
|
|
2815
|
-
}
|
|
2816
|
-
return void 0;
|
|
2817
|
-
};
|
|
2818
|
-
var walkVue = walkVue2;
|
|
2819
|
-
vm = walkVue2(document.body);
|
|
2820
|
-
}
|
|
2821
|
-
const vmRouter = vm?.$router;
|
|
2822
|
-
const vmRootRouter = vm?.$root?.$router;
|
|
2823
|
-
if (!router) router = vmRouter || vmRootRouter;
|
|
2824
|
-
}
|
|
2825
|
-
const routeList = router?.options?.routes;
|
|
2826
|
-
if (routeList) {
|
|
2827
|
-
for (const r of routeList) {
|
|
2828
|
-
if (r.path && !r.path.includes(":") && r.path !== "/" && r.path !== "") {
|
|
2829
|
-
routes.push(`${evalOrigin.replace(/\/$/, "")}/#${r.path}`);
|
|
2830
|
-
}
|
|
2831
|
-
}
|
|
2832
|
-
}
|
|
2833
|
-
return routes;
|
|
2834
|
-
}, origin);
|
|
2835
|
-
for (const r of vueRoutes) routeSet.add(r);
|
|
2836
2777
|
} catch {
|
|
2837
2778
|
}
|
|
2838
2779
|
return Array.from(routeSet).map(
|
|
2839
|
-
(p) =>
|
|
2780
|
+
(p) => `${origin.replace(/\/$/, "")}${p.startsWith("/") ? "" : "/"}${p}`
|
|
2840
2781
|
);
|
|
2841
2782
|
}
|
|
2842
2783
|
function parseRobotsTxt(text) {
|
|
@@ -5571,6 +5512,7 @@ registerCommandDefinition("actions", ["url"]);
|
|
|
5571
5512
|
registerCommandDefinition("find", ["strategy", "value", "operation"]);
|
|
5572
5513
|
registerCommandDefinition("addinitscript", ["script"]);
|
|
5573
5514
|
registerCommandDefinition("tab", ["subcommand"]);
|
|
5515
|
+
registerCommandDefinition("mouse", ["action", "x", "y"]);
|
|
5574
5516
|
|
|
5575
5517
|
// src/commands/addinitscript.ts
|
|
5576
5518
|
var InitScriptParams = z24.object({
|
package/dist/index.js
CHANGED
|
@@ -2838,78 +2838,19 @@ async function detectSpaRoutes(page, origin) {
|
|
|
2838
2838
|
const routeSet = /* @__PURE__ */ new Set();
|
|
2839
2839
|
const pathRegex = /['"`](\/[a-zA-Z0-9_\-/]+)['"`]/g;
|
|
2840
2840
|
const isParamRoute = (p) => p.includes(":") || p.includes("*");
|
|
2841
|
-
|
|
2841
|
+
try {
|
|
2842
|
+
const inlineContent = await page.evaluate(() => {
|
|
2843
|
+
return Array.from(document.querySelectorAll("script")).map((s) => s.textContent || "").join("\n");
|
|
2844
|
+
});
|
|
2842
2845
|
let match;
|
|
2843
|
-
while ((match = pathRegex.exec(
|
|
2846
|
+
while ((match = pathRegex.exec(inlineContent)) !== null) {
|
|
2844
2847
|
const path5 = match[1];
|
|
2845
2848
|
if (!isParamRoute(path5)) routeSet.add(path5);
|
|
2846
2849
|
}
|
|
2847
|
-
}
|
|
2848
|
-
const scriptData = await page.evaluate(() => {
|
|
2849
|
-
const scripts = Array.from(document.querySelectorAll("script"));
|
|
2850
|
-
return {
|
|
2851
|
-
inlineContent: scripts.map((s) => s.textContent || "").join("\n"),
|
|
2852
|
-
externalUrls: scripts.map((s) => s.src).filter((src) => src && !src.includes("analytics") && !src.includes("google") && !src.includes("baidu"))
|
|
2853
|
-
};
|
|
2854
|
-
});
|
|
2855
|
-
const { inlineContent, externalUrls } = scriptData;
|
|
2856
|
-
extractPaths(inlineContent);
|
|
2857
|
-
for (const src of externalUrls) {
|
|
2858
|
-
try {
|
|
2859
|
-
const absoluteSrc = src.startsWith("http") ? src : new URL(src, page.url()).href;
|
|
2860
|
-
const resp = await fetch(absoluteSrc, { signal: AbortSignal.timeout(5e3) });
|
|
2861
|
-
if (resp.ok) {
|
|
2862
|
-
const text = await resp.text();
|
|
2863
|
-
extractPaths(text);
|
|
2864
|
-
}
|
|
2865
|
-
} catch {
|
|
2866
|
-
}
|
|
2867
|
-
}
|
|
2868
|
-
try {
|
|
2869
|
-
const vueRoutes = await page.evaluate((evalOrigin) => {
|
|
2870
|
-
const routes2 = [];
|
|
2871
|
-
const win = window;
|
|
2872
|
-
const vue3App = win.__vue_app__;
|
|
2873
|
-
const vue3Router = vue3App?.config?.globalProperties?.$router;
|
|
2874
|
-
let router = vue3Router;
|
|
2875
|
-
if (!router) {
|
|
2876
|
-
let vm;
|
|
2877
|
-
const appById = document.getElementById("app");
|
|
2878
|
-
if (appById) {
|
|
2879
|
-
vm = appById.__vue__;
|
|
2880
|
-
}
|
|
2881
|
-
if (!vm) {
|
|
2882
|
-
let walkVue2 = function(node) {
|
|
2883
|
-
const prop = node.__vue__;
|
|
2884
|
-
if (prop) return prop;
|
|
2885
|
-
for (let i = 0; i < node.children.length; i++) {
|
|
2886
|
-
const found = walkVue2(node.children[i]);
|
|
2887
|
-
if (found) return found;
|
|
2888
|
-
}
|
|
2889
|
-
return void 0;
|
|
2890
|
-
};
|
|
2891
|
-
var walkVue = walkVue2;
|
|
2892
|
-
vm = walkVue2(document.body);
|
|
2893
|
-
}
|
|
2894
|
-
const vmRouter = vm?.$router;
|
|
2895
|
-
const vmRootRouter = vm?.$root?.$router;
|
|
2896
|
-
if (!router) router = vmRouter || vmRootRouter;
|
|
2897
|
-
}
|
|
2898
|
-
const routeList = router?.options?.routes;
|
|
2899
|
-
if (routeList) {
|
|
2900
|
-
for (const r of routeList) {
|
|
2901
|
-
if (r.path && !r.path.includes(":") && r.path !== "/" && r.path !== "") {
|
|
2902
|
-
routes2.push(`${evalOrigin.replace(/\/$/, "")}/#${r.path}`);
|
|
2903
|
-
}
|
|
2904
|
-
}
|
|
2905
|
-
}
|
|
2906
|
-
return routes2;
|
|
2907
|
-
}, origin);
|
|
2908
|
-
for (const r of vueRoutes) routeSet.add(r);
|
|
2909
2850
|
} catch {
|
|
2910
2851
|
}
|
|
2911
2852
|
return Array.from(routeSet).map(
|
|
2912
|
-
(p) =>
|
|
2853
|
+
(p) => `${origin.replace(/\/$/, "")}${p.startsWith("/") ? "" : "/"}${p}`
|
|
2913
2854
|
);
|
|
2914
2855
|
}
|
|
2915
2856
|
function parseRobotsTxt(text) {
|
|
@@ -5921,6 +5862,7 @@ registerCommandDefinition("actions", ["url"]);
|
|
|
5921
5862
|
registerCommandDefinition("find", ["strategy", "value", "operation"]);
|
|
5922
5863
|
registerCommandDefinition("addinitscript", ["script"]);
|
|
5923
5864
|
registerCommandDefinition("tab", ["subcommand"]);
|
|
5865
|
+
registerCommandDefinition("mouse", ["action", "x", "y"]);
|
|
5924
5866
|
|
|
5925
5867
|
// src/commands/addinitscript.ts
|
|
5926
5868
|
var InitScriptParams = z24.object({
|
|
@@ -8048,7 +7990,7 @@ async function executeChain(input, options) {
|
|
|
8048
7990
|
}
|
|
8049
7991
|
}
|
|
8050
7992
|
function isChainInput(input) {
|
|
8051
|
-
return /\s&&\s|\|\|\s|\s;\s|\s,\s|\s\+\s|\s->\s/.test(input);
|
|
7993
|
+
return /\s&&\s|\|\|\s|\s;\s|;\s|\s,\s|\s\+\s|\s->\s/.test(input);
|
|
8052
7994
|
}
|
|
8053
7995
|
|
|
8054
7996
|
// src/context.ts
|
|
@@ -12963,7 +12905,9 @@ async function handleEvalMode(argv) {
|
|
|
12963
12905
|
if (evalCommands.length === 0) return;
|
|
12964
12906
|
const chain = evalCommands.join(" ; ");
|
|
12965
12907
|
const cdpEndpoint = extractCdpFromArgv(argv);
|
|
12966
|
-
const
|
|
12908
|
+
const sessionArgIdx = argv.indexOf("--session");
|
|
12909
|
+
const sessionName = sessionArgIdx >= 0 && argv[sessionArgIdx + 1] ? argv[sessionArgIdx + 1] : process.env.XBROWSER_SESSION || "default";
|
|
12910
|
+
const chainResult = await executeChain(chain, { cdpEndpoint, sessionName });
|
|
12967
12911
|
printChainResult(chainResult);
|
|
12968
12912
|
if (!chainResult.success) throw new Error("Command failed");
|
|
12969
12913
|
}
|
|
@@ -13024,7 +12968,8 @@ async function routeCommand(argvIn, stdinCommands) {
|
|
|
13024
12968
|
const possibleCmd = chainArg.substring(0, spaceIdx);
|
|
13025
12969
|
if (/^[a-zA-Z][\w-]*$/.test(possibleCmd)) {
|
|
13026
12970
|
const remainder = chainArg.substring(spaceIdx + 1);
|
|
13027
|
-
|
|
12971
|
+
let remainderParts = remainder.split(/\s+/).filter(Boolean);
|
|
12972
|
+
remainderParts = remainderParts.flatMap((part) => part.split(";").filter(Boolean));
|
|
13028
12973
|
argv = [...argv.slice(0, chainArgIdx), possibleCmd, ...remainderParts, ...argv.slice(chainArgIdx + 1)];
|
|
13029
12974
|
}
|
|
13030
12975
|
}
|
|
@@ -13046,7 +12991,7 @@ async function routeCommand(argvIn, stdinCommands) {
|
|
|
13046
12991
|
return;
|
|
13047
12992
|
}
|
|
13048
12993
|
if (positional.length === 0) {
|
|
13049
|
-
const chainHints = [options.json, options.yaml, options.session, options.cdp].filter(Boolean).find((v) => typeof v === "string" && v
|
|
12994
|
+
const chainHints = [options.json, options.yaml, options.session, options.cdp].filter(Boolean).find((v) => typeof v === "string" && /^[a-zA-Z]/.test(v));
|
|
13050
12995
|
if (chainHints) {
|
|
13051
12996
|
positional.push(chainHints);
|
|
13052
12997
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xbrowser/cli",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.7",
|
|
4
4
|
"description": "Browser automation CLI for web scraping, headless browsing, SEO analysis, and AI agent workflows. A command-line alternative to Playwright, Puppeteer, and Selenium.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|