@docyrus/docyrus 0.0.23 → 0.0.24

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docyrus/docyrus",
3
- "version": "0.0.23",
3
+ "version": "0.0.24",
4
4
  "private": false,
5
5
  "description": "Docyrus API CLI",
6
6
  "main": "./main.js",
package/server-loader.js CHANGED
@@ -3135,13 +3135,19 @@ async function buildTree(params) {
3135
3135
  entries.sort((a, b) => {
3136
3136
  const aIsDir = a.isDirectory();
3137
3137
  const bIsDir = b.isDirectory();
3138
- if (aIsDir !== bIsDir) return aIsDir ? -1 : 1;
3138
+ if (aIsDir !== bIsDir) {
3139
+ return aIsDir ? -1 : 1;
3140
+ }
3139
3141
  return a.name.localeCompare(b.name);
3140
3142
  });
3141
3143
  const result = [];
3142
3144
  for (const entry of entries) {
3143
- if (counter.value >= maxFiles) break;
3144
- if (ignore.has(entry.name)) continue;
3145
+ if (counter.value >= maxFiles) {
3146
+ break;
3147
+ }
3148
+ if (ignore.has(entry.name)) {
3149
+ continue;
3150
+ }
3145
3151
  const fullPath = (0, import_node_path2.join)(dir, entry.name);
3146
3152
  const relativePath = (0, import_node_path2.relative)(cwd, fullPath);
3147
3153
  if (entry.isDirectory()) {
@@ -3164,7 +3170,9 @@ async function buildTree(params) {
3164
3170
  }
3165
3171
  async function walkFiles(params) {
3166
3172
  const { dir, cwd, pattern, ignore, maxResults, results } = params;
3167
- if (results.length >= maxResults) return;
3173
+ if (results.length >= maxResults) {
3174
+ return;
3175
+ }
3168
3176
  let entries;
3169
3177
  try {
3170
3178
  entries = await (0, import_promises2.readdir)(dir, { withFileTypes: true });
@@ -3172,8 +3180,12 @@ async function walkFiles(params) {
3172
3180
  return;
3173
3181
  }
3174
3182
  for (const entry of entries) {
3175
- if (results.length >= maxResults) break;
3176
- if (ignore.has(entry.name)) continue;
3183
+ if (results.length >= maxResults) {
3184
+ break;
3185
+ }
3186
+ if (ignore.has(entry.name)) {
3187
+ continue;
3188
+ }
3177
3189
  const fullPath = (0, import_node_path2.join)(dir, entry.name);
3178
3190
  const relativePath = (0, import_node_path2.relative)(cwd, fullPath);
3179
3191
  if (entry.isDirectory()) {
@@ -3479,6 +3491,53 @@ async function createAgentServer(params) {
3479
3491
  return null;
3480
3492
  }
3481
3493
  }
3494
+ async function detectDevPort(cwd) {
3495
+ try {
3496
+ const pkg = JSON.parse(await (0, import_promises2.readFile)((0, import_node_path2.join)(cwd, "package.json"), "utf-8"));
3497
+ const devScript = pkg.scripts?.dev;
3498
+ if (devScript) {
3499
+ const portFlag = devScript.match(/--port\s+(\d+)/);
3500
+ if (portFlag) {
3501
+ return Number(portFlag[1]);
3502
+ }
3503
+ const dashP = devScript.match(/(?:^|\s)-p\s+(\d+)/);
3504
+ if (dashP) {
3505
+ return Number(dashP[1]);
3506
+ }
3507
+ }
3508
+ } catch {
3509
+ }
3510
+ for (const name of ["vite.config.ts", "vite.config.mts", "vite.config.js"]) {
3511
+ try {
3512
+ const content = await (0, import_promises2.readFile)((0, import_node_path2.join)(cwd, name), "utf-8");
3513
+ const portMatch = content.match(/port\s*:\s*(\d+)/);
3514
+ if (portMatch) {
3515
+ return Number(portMatch[1]);
3516
+ }
3517
+ } catch {
3518
+ }
3519
+ }
3520
+ for (const name of ["next.config.ts", "next.config.mts", "next.config.js", "next.config.mjs"]) {
3521
+ try {
3522
+ await (0, import_promises2.stat)((0, import_node_path2.join)(cwd, name));
3523
+ return 3e3;
3524
+ } catch {
3525
+ }
3526
+ }
3527
+ try {
3528
+ await (0, import_promises2.stat)((0, import_node_path2.join)(cwd, "angular.json"));
3529
+ return 4200;
3530
+ } catch {
3531
+ }
3532
+ for (const name of ["nuxt.config.ts", "nuxt.config.js"]) {
3533
+ try {
3534
+ await (0, import_promises2.stat)((0, import_node_path2.join)(cwd, name));
3535
+ return 3e3;
3536
+ } catch {
3537
+ }
3538
+ }
3539
+ return null;
3540
+ }
3482
3541
  app.get("/api/env/status", async (c) => {
3483
3542
  if (devProcess && devProcess.exitCode === null && devUrl) {
3484
3543
  const httpStatus = await probeUrl(devUrl);
@@ -3496,14 +3555,28 @@ async function createAgentServer(params) {
3496
3555
  devUrl = null;
3497
3556
  return c.json({ status: "stopped", url: stoppedUrl, exitCode, managed: true });
3498
3557
  }
3499
- const commonPorts = [5173, 5174, 3e3, 3001, 4321, 8080, 8e3];
3500
- for (const devPort of commonPorts) {
3501
- const candidate = `http://localhost:${devPort}`;
3502
- const httpStatus = await probeUrl(candidate);
3503
- if (httpStatus !== null) {
3504
- return c.json({ status: "running", url: candidate, httpStatus, managed: false });
3558
+ const explicitUrl = c.req.query("url");
3559
+ const explicitPort = c.req.query("port");
3560
+ let probeTarget = null;
3561
+ if (explicitUrl) {
3562
+ probeTarget = explicitUrl;
3563
+ } else if (explicitPort) {
3564
+ probeTarget = `http://localhost:${explicitPort}`;
3565
+ } else {
3566
+ const detected = await detectDevPort(context.cwd);
3567
+ if (detected) {
3568
+ probeTarget = `http://localhost:${detected}`;
3505
3569
  }
3506
3570
  }
3571
+ if (probeTarget) {
3572
+ const httpStatus = await probeUrl(probeTarget);
3573
+ return c.json({
3574
+ status: httpStatus !== null ? "running" : "stopped",
3575
+ url: probeTarget,
3576
+ httpStatus: httpStatus ?? void 0,
3577
+ managed: false
3578
+ });
3579
+ }
3507
3580
  return c.json({ status: "stopped", url: null, managed: false });
3508
3581
  });
3509
3582
  app.post("/api/env/serve", (c) => {
@@ -3521,7 +3594,9 @@ async function createAgentServer(params) {
3521
3594
  let stderr = "";
3522
3595
  let resolved = false;
3523
3596
  function settle(response) {
3524
- if (resolved) return;
3597
+ if (resolved) {
3598
+ return;
3599
+ }
3525
3600
  resolved = true;
3526
3601
  resolveResponse(response);
3527
3602
  }
@@ -3562,6 +3637,105 @@ async function createAgentServer(params) {
3562
3637
  devUrl = null;
3563
3638
  return c.json({ status: "stopped", url: stoppedUrl, pid });
3564
3639
  });
3640
+ const CLI_EXEC = process.env.DOCYRUS_CLI_EXECUTABLE || process.execPath;
3641
+ const CLI_ENTRY = process.env.DOCYRUS_CLI_ENTRY;
3642
+ const CLI_SCOPE = process.env.DOCYRUS_CLI_SCOPE;
3643
+ const CLI_TIMEOUT_MS = 3e4;
3644
+ const BOOLEAN_CLI_FLAGS = /* @__PURE__ */ new Set(["json", "verbose", "global", "noAuth", "expand", "i"]);
3645
+ function buildCliArgs(pathSegments, query, body) {
3646
+ const args = [...pathSegments, "--json"];
3647
+ for (const [key, value] of Object.entries(query)) {
3648
+ if (key === "json") {
3649
+ continue;
3650
+ }
3651
+ const flag = key.length === 1 ? `-${key}` : `--${key}`;
3652
+ if (BOOLEAN_CLI_FLAGS.has(key) || value === "" || value === "true") {
3653
+ args.push(flag);
3654
+ } else {
3655
+ args.push(flag, value);
3656
+ }
3657
+ }
3658
+ if (body) {
3659
+ if (body.data !== void 0) {
3660
+ args.push("--data", typeof body.data === "string" ? body.data : JSON.stringify(body.data));
3661
+ }
3662
+ if (typeof body.fromFile === "string") {
3663
+ args.push("--from-file", body.fromFile);
3664
+ }
3665
+ for (const [key, value] of Object.entries(body)) {
3666
+ if (key === "data" || key === "fromFile") {
3667
+ continue;
3668
+ }
3669
+ const flag = key.length === 1 ? `-${key}` : `--${key}`;
3670
+ if (typeof value === "boolean") {
3671
+ if (value) {
3672
+ args.push(flag);
3673
+ }
3674
+ } else if (value !== void 0 && value !== null) {
3675
+ args.push(flag, String(value));
3676
+ }
3677
+ }
3678
+ }
3679
+ return args;
3680
+ }
3681
+ app.all("/api/cli/*", async (c) => {
3682
+ if (!CLI_ENTRY) {
3683
+ return c.json({ error: "CLI entry path not available (DOCYRUS_CLI_ENTRY not set)" }, 500);
3684
+ }
3685
+ const pathSegments = c.req.path.replace(/^\/api\/cli\/?/, "").split("/").filter(Boolean);
3686
+ if (pathSegments.length === 0) {
3687
+ return c.json({ error: "No command specified. Usage: /api/cli/<command>/[subcommand]/[args...]" }, 400);
3688
+ }
3689
+ const query = {};
3690
+ for (const [key, value] of Object.entries(c.req.query())) {
3691
+ if (typeof value === "string") {
3692
+ query[key] = value;
3693
+ }
3694
+ }
3695
+ let body;
3696
+ if (c.req.method === "POST" || c.req.method === "PUT") {
3697
+ try {
3698
+ body = await c.req.json();
3699
+ } catch {
3700
+ }
3701
+ }
3702
+ const cliArgs = buildCliArgs(pathSegments, query, body);
3703
+ return new Promise((resolveResponse) => {
3704
+ const scopeArgs = CLI_SCOPE ? ["--scope", CLI_SCOPE] : [];
3705
+ const proc = (0, import_node_child_process.spawn)(CLI_EXEC, [CLI_ENTRY, ...scopeArgs, ...cliArgs], {
3706
+ cwd: context.cwd,
3707
+ stdio: ["ignore", "pipe", "pipe"],
3708
+ timeout: CLI_TIMEOUT_MS
3709
+ });
3710
+ let stdout = "";
3711
+ let stderr = "";
3712
+ proc.stdout?.on("data", (chunk) => {
3713
+ stdout += chunk.toString();
3714
+ });
3715
+ proc.stderr?.on("data", (chunk) => {
3716
+ stderr += chunk.toString();
3717
+ });
3718
+ proc.on("close", (code) => {
3719
+ if (code !== 0) {
3720
+ resolveResponse(c.json({
3721
+ error: stderr.trim() || `Command exited with code ${code}`,
3722
+ command: `docyrus ${cliArgs.join(" ")}`,
3723
+ exitCode: code
3724
+ }, 500));
3725
+ return;
3726
+ }
3727
+ try {
3728
+ const parsed = JSON.parse(stdout);
3729
+ resolveResponse(c.json(parsed));
3730
+ } catch {
3731
+ resolveResponse(c.json({ output: stdout.trim(), command: `docyrus ${cliArgs.join(" ")}` }));
3732
+ }
3733
+ });
3734
+ proc.on("error", (err) => {
3735
+ resolveResponse(c.json({ error: err.message, command: `docyrus ${cliArgs.join(" ")}` }, 500));
3736
+ });
3737
+ });
3738
+ });
3565
3739
  const { serve: serve2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
3566
3740
  serve2({
3567
3741
  fetch: app.fetch,
@@ -3606,6 +3780,8 @@ async function createAgentServer(params) {
3606
3780
  process.stderr.write(` POST /api/env/serve \u2014 start dev server (pnpm dev)
3607
3781
  `);
3608
3782
  process.stderr.write(` POST /api/env/stop \u2014 stop dev server
3783
+ `);
3784
+ process.stderr.write(` * /api/cli/** \u2014 proxy any docyrus CLI command
3609
3785
 
3610
3786
  `);
3611
3787
  });