@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 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
- function extractPaths(source) {
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(source)) !== null) {
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) => p.startsWith("http") ? p : `${origin.replace(/\/$/, "")}${p.startsWith("/") ? "" : "/"}${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 chainResult = await executeChain(chain, { cdpEndpoint });
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
- const remainderParts = remainder.split(/\s+/).filter(Boolean);
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.includes(" "));
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 {
@@ -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
- function extractPaths(source) {
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(source)) !== null) {
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) => p.startsWith("http") ? p : `${origin.replace(/\/$/, "")}${p.startsWith("/") ? "" : "/"}${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
- function extractPaths(source) {
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(source)) !== null) {
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) => p.startsWith("http") ? p : `${origin.replace(/\/$/, "")}${p.startsWith("/") ? "" : "/"}${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 chainResult = await executeChain(chain, { cdpEndpoint });
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
- const remainderParts = remainder.split(/\s+/).filter(Boolean);
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.includes(" "));
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.5",
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": {