@forinda/kickjs-cli 0.6.0 → 0.7.0

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
@@ -4,6 +4,9 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
4
4
 
5
5
  // src/cli.ts
6
6
  import { Command } from "commander";
7
+ import { readFileSync as readFileSync2 } from "fs";
8
+ import { dirname as dirname3, join as join11 } from "path";
9
+ import { fileURLToPath as fileURLToPath2 } from "url";
7
10
 
8
11
  // src/commands/init.ts
9
12
  import { resolve, basename } from "path";
@@ -11,8 +14,10 @@ import { createInterface } from "readline";
11
14
  import { existsSync, readdirSync, rmSync } from "fs";
12
15
 
13
16
  // src/generators/project.ts
14
- import { join } from "path";
17
+ import { join, dirname as dirname2 } from "path";
15
18
  import { execSync } from "child_process";
19
+ import { readFileSync } from "fs";
20
+ import { fileURLToPath } from "url";
16
21
 
17
22
  // src/utils/fs.ts
18
23
  import { writeFile, mkdir, access, readFile } from "fs/promises";
@@ -35,6 +40,9 @@ async function fileExists(filePath) {
35
40
  __name(fileExists, "fileExists");
36
41
 
37
42
  // src/generators/project.ts
43
+ var __dirname = dirname2(fileURLToPath(import.meta.url));
44
+ var cliPkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
45
+ var KICKJS_VERSION = `^${cliPkg.version}`;
38
46
  async function initProject(options) {
39
47
  const { name, directory, packageManager = "pnpm" } = options;
40
48
  const dir = directory;
@@ -43,7 +51,7 @@ async function initProject(options) {
43
51
  `);
44
52
  await writeFileSafe(join(dir, "package.json"), JSON.stringify({
45
53
  name,
46
- version: "0.1.0",
54
+ version: cliPkg.version,
47
55
  type: "module",
48
56
  scripts: {
49
57
  dev: "kick dev",
@@ -57,10 +65,10 @@ async function initProject(options) {
57
65
  format: "prettier --write src/"
58
66
  },
59
67
  dependencies: {
60
- "@forinda/kickjs-core": "^0.1.0",
61
- "@forinda/kickjs-http": "^0.1.0",
62
- "@forinda/kickjs-config": "^0.1.0",
63
- "@forinda/kickjs-swagger": "^0.1.0",
68
+ "@forinda/kickjs-core": KICKJS_VERSION,
69
+ "@forinda/kickjs-http": KICKJS_VERSION,
70
+ "@forinda/kickjs-config": KICKJS_VERSION,
71
+ "@forinda/kickjs-swagger": KICKJS_VERSION,
64
72
  express: "^5.1.0",
65
73
  "reflect-metadata": "^0.2.2",
66
74
  zod: "^4.3.6",
@@ -68,7 +76,7 @@ async function initProject(options) {
68
76
  "pino-pretty": "^13.1.3"
69
77
  },
70
78
  devDependencies: {
71
- "@forinda/kickjs-cli": "^0.1.0",
79
+ "@forinda/kickjs-cli": KICKJS_VERSION,
72
80
  "@swc/core": "^1.7.28",
73
81
  "@types/express": "^5.0.6",
74
82
  "@types/node": "^24.5.2",
@@ -166,7 +174,7 @@ bootstrap({
166
174
  modules,
167
175
  adapters: [
168
176
  new SwaggerAdapter({
169
- info: { title: '${name}', version: '0.1.0' },
177
+ info: { title: '${name}', version: '${cliPkg.version}' },
170
178
  }),
171
179
  ],
172
180
  })
@@ -1650,6 +1658,161 @@ function registerSingleCommand(program, def) {
1650
1658
  }
1651
1659
  __name(registerSingleCommand, "registerSingleCommand");
1652
1660
 
1661
+ // src/commands/inspect.ts
1662
+ var esc = /* @__PURE__ */ __name((code) => `\x1B[${code}m`, "esc");
1663
+ var reset = esc("0");
1664
+ var bold = /* @__PURE__ */ __name((s) => `${esc("1")}${s}${reset}`, "bold");
1665
+ var dim = /* @__PURE__ */ __name((s) => `${esc("2")}${s}${reset}`, "dim");
1666
+ var green = /* @__PURE__ */ __name((s) => `${esc("32")}${s}${reset}`, "green");
1667
+ var red = /* @__PURE__ */ __name((s) => `${esc("31")}${s}${reset}`, "red");
1668
+ var yellow = /* @__PURE__ */ __name((s) => `${esc("33")}${s}${reset}`, "yellow");
1669
+ var cyan = /* @__PURE__ */ __name((s) => `${esc("36")}${s}${reset}`, "cyan");
1670
+ var magenta = /* @__PURE__ */ __name((s) => `${esc("35")}${s}${reset}`, "magenta");
1671
+ var blue = /* @__PURE__ */ __name((s) => `${esc("34")}${s}${reset}`, "blue");
1672
+ var METHOD_COLORS = {
1673
+ GET: green,
1674
+ POST: cyan,
1675
+ PUT: yellow,
1676
+ PATCH: magenta,
1677
+ DELETE: red
1678
+ };
1679
+ function colorMethod(method) {
1680
+ const fn = METHOD_COLORS[method] ?? dim;
1681
+ return fn(method.padEnd(7));
1682
+ }
1683
+ __name(colorMethod, "colorMethod");
1684
+ function formatUptime(seconds) {
1685
+ const d = Math.floor(seconds / 86400);
1686
+ const h = Math.floor(seconds % 86400 / 3600);
1687
+ const m = Math.floor(seconds % 3600 / 60);
1688
+ const s = seconds % 60;
1689
+ const parts = [];
1690
+ if (d) parts.push(`${d}d`);
1691
+ if (h) parts.push(`${h}h`);
1692
+ if (m) parts.push(`${m}m`);
1693
+ parts.push(`${s}s`);
1694
+ return parts.join(" ");
1695
+ }
1696
+ __name(formatUptime, "formatUptime");
1697
+ async function fetchJson(url) {
1698
+ const res = await fetch(url, {
1699
+ signal: AbortSignal.timeout(5e3)
1700
+ });
1701
+ if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
1702
+ return res.json();
1703
+ }
1704
+ __name(fetchJson, "fetchJson");
1705
+ async function fetchEndpoint(base, path) {
1706
+ try {
1707
+ return await fetchJson(`${base}${path}`);
1708
+ } catch {
1709
+ return null;
1710
+ }
1711
+ }
1712
+ __name(fetchEndpoint, "fetchEndpoint");
1713
+ async function fetchAll(base) {
1714
+ const [health, metrics, routes, container, ws] = await Promise.all([
1715
+ fetchEndpoint(base, "/health"),
1716
+ fetchEndpoint(base, "/metrics"),
1717
+ fetchEndpoint(base, "/routes"),
1718
+ fetchEndpoint(base, "/container"),
1719
+ fetchEndpoint(base, "/ws")
1720
+ ]);
1721
+ return {
1722
+ health,
1723
+ metrics,
1724
+ routes,
1725
+ container,
1726
+ ws
1727
+ };
1728
+ }
1729
+ __name(fetchAll, "fetchAll");
1730
+ function printSummary(base, data) {
1731
+ const { health, metrics, routes, container, ws } = data;
1732
+ const line = dim("\u2500".repeat(60));
1733
+ console.log();
1734
+ console.log(bold(` KickJS Inspector`) + dim(` \u2192 ${base}`));
1735
+ console.log(line);
1736
+ if (health) {
1737
+ const statusText = health.status === "healthy" ? green("\u25CF healthy") : red("\u25CF " + health.status);
1738
+ console.log(` ${bold("Health:")} ${statusText}`);
1739
+ } else {
1740
+ console.log(` ${bold("Health:")} ${red("\u25CF unreachable")}`);
1741
+ }
1742
+ if (metrics) {
1743
+ const rate = ((metrics.errorRate ?? 0) * 100).toFixed(1);
1744
+ const rateColor = metrics.errorRate > 0.1 ? red : metrics.errorRate > 0 ? yellow : green;
1745
+ console.log(` ${bold("Uptime:")} ${formatUptime(metrics.uptimeSeconds)}`);
1746
+ console.log(` ${bold("Requests:")} ${metrics.requests}`);
1747
+ console.log(` ${bold("Errors:")} ${metrics.serverErrors} server, ${metrics.clientErrors ?? 0} client ${dim("(")}${rateColor(rate + "%")}${dim(")")}`);
1748
+ }
1749
+ if (container) {
1750
+ console.log(` ${bold("DI:")} ${container.count} bindings`);
1751
+ }
1752
+ if (ws && ws.enabled) {
1753
+ console.log(` ${bold("WS:")} ${ws.connections ?? 0} connections, ${ws.namespaces ?? 0} namespaces`);
1754
+ }
1755
+ if (routes?.routes?.length) {
1756
+ console.log();
1757
+ console.log(bold(" Routes"));
1758
+ console.log(line);
1759
+ console.log(` ${dim("METHOD")} ${dim("PATH".padEnd(36))} ${dim("CONTROLLER")}`);
1760
+ for (const r of routes.routes) {
1761
+ const path = r.path.length > 36 ? r.path.slice(0, 33) + "..." : r.path.padEnd(36);
1762
+ console.log(` ${colorMethod(r.method)} ${path} ${blue(r.controller)}.${dim(r.handler)}`);
1763
+ }
1764
+ }
1765
+ console.log(line);
1766
+ console.log();
1767
+ }
1768
+ __name(printSummary, "printSummary");
1769
+ function registerInspectCommand(program) {
1770
+ program.command("inspect [url]").description("Connect to a running KickJS app and display debug info").option("-p, --port <port>", "Override port").option("-w, --watch", "Poll every 5 seconds").option("-j, --json", "Output raw JSON").action(async (url, opts) => {
1771
+ let base = url ?? "http://localhost:3000";
1772
+ if (opts.port) {
1773
+ try {
1774
+ const parsed = new URL(base);
1775
+ parsed.port = opts.port;
1776
+ base = parsed.origin;
1777
+ } catch {
1778
+ base = `http://localhost:${opts.port}`;
1779
+ }
1780
+ }
1781
+ const debugBase = `${base.replace(/\/$/, "")}/_debug`;
1782
+ const run = /* @__PURE__ */ __name(async () => {
1783
+ try {
1784
+ const data = await fetchAll(debugBase);
1785
+ if (opts.json) {
1786
+ console.log(JSON.stringify(data, null, 2));
1787
+ } else {
1788
+ printSummary(base, data);
1789
+ }
1790
+ } catch (err) {
1791
+ if (opts.json) {
1792
+ console.log(JSON.stringify({
1793
+ error: String(err)
1794
+ }));
1795
+ } else {
1796
+ console.error(red(` \u2716 Could not connect to ${base}`));
1797
+ console.error(dim(` ${err instanceof Error ? err.message : String(err)}`));
1798
+ }
1799
+ if (!opts.watch) process.exitCode = 1;
1800
+ }
1801
+ }, "run");
1802
+ if (opts.watch) {
1803
+ const poll = /* @__PURE__ */ __name(async () => {
1804
+ process.stdout.write("\x1B[2J\x1B[H");
1805
+ await run();
1806
+ }, "poll");
1807
+ await poll();
1808
+ setInterval(poll, 5e3);
1809
+ } else {
1810
+ await run();
1811
+ }
1812
+ });
1813
+ }
1814
+ __name(registerInspectCommand, "registerInspectCommand");
1815
+
1653
1816
  // src/config.ts
1654
1817
  import { readFile as readFile3, access as access2 } from "fs/promises";
1655
1818
  import { join as join10 } from "path";
@@ -1687,14 +1850,17 @@ async function loadKickConfig(cwd) {
1687
1850
  __name(loadKickConfig, "loadKickConfig");
1688
1851
 
1689
1852
  // src/cli.ts
1853
+ var __dirname2 = dirname3(fileURLToPath2(import.meta.url));
1854
+ var pkg = JSON.parse(readFileSync2(join11(__dirname2, "..", "package.json"), "utf-8"));
1690
1855
  async function main() {
1691
1856
  const program = new Command();
1692
- program.name("kick").description("KickJS \u2014 A production-grade, decorator-driven Node.js framework").version("0.1.0");
1857
+ program.name("kick").description("KickJS \u2014 A production-grade, decorator-driven Node.js framework").version(pkg.version);
1693
1858
  const config = await loadKickConfig(process.cwd());
1694
1859
  registerInitCommand(program);
1695
1860
  registerGenerateCommand(program);
1696
1861
  registerRunCommands(program);
1697
1862
  registerInfoCommand(program);
1863
+ registerInspectCommand(program);
1698
1864
  registerCustomCommands(program, config);
1699
1865
  program.showHelpAfterError();
1700
1866
  await program.parseAsync(process.argv);