@starpak/cli 0.0.0-stage → 1.0.5

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.
Files changed (44) hide show
  1. package/LICENSE +22 -0
  2. package/bin/spak.js +6 -0
  3. package/lib/cli/firewall.d.ts +20 -0
  4. package/lib/cli/firewall.d.ts.map +1 -0
  5. package/lib/cli/firewall.js +207 -0
  6. package/lib/cli/firewall.js.map +1 -0
  7. package/lib/cli/index.d.ts +2 -0
  8. package/lib/cli/index.d.ts.map +1 -0
  9. package/lib/cli/index.js +76 -0
  10. package/lib/cli/index.js.map +1 -0
  11. package/lib/cli/registry.d.ts +10 -0
  12. package/lib/cli/registry.d.ts.map +1 -0
  13. package/lib/cli/registry.js +207 -0
  14. package/lib/cli/registry.js.map +1 -0
  15. package/lib/cli/start.d.ts +4 -0
  16. package/lib/cli/start.d.ts.map +1 -0
  17. package/lib/cli/start.js +301 -0
  18. package/lib/cli/start.js.map +1 -0
  19. package/lib/cli/types.d.ts +2 -0
  20. package/lib/cli/types.d.ts.map +1 -0
  21. package/lib/cli/types.js +3 -0
  22. package/lib/cli/types.js.map +1 -0
  23. package/lib/commands/check.d.ts +4 -0
  24. package/lib/commands/check.d.ts.map +1 -0
  25. package/lib/commands/check.js +84 -0
  26. package/lib/commands/check.js.map +1 -0
  27. package/lib/commands/config.d.ts +4 -0
  28. package/lib/commands/config.d.ts.map +1 -0
  29. package/lib/commands/config.js +79 -0
  30. package/lib/commands/config.js.map +1 -0
  31. package/lib/commands/cpc.d.ts +41 -0
  32. package/lib/commands/cpc.d.ts.map +1 -0
  33. package/lib/commands/cpc.js +801 -0
  34. package/lib/commands/cpc.js.map +1 -0
  35. package/lib/index.d.ts +32 -0
  36. package/lib/index.d.ts.map +1 -0
  37. package/lib/index.js +95 -0
  38. package/lib/index.js.map +1 -0
  39. package/lib/version.d.ts +2 -0
  40. package/lib/version.d.ts.map +1 -0
  41. package/lib/version.js +16 -0
  42. package/lib/version.js.map +1 -0
  43. package/package.json +47 -3
  44. package/README.md +0 -3
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-present Spak Team
4
+ Copyright (c) 2019-present Shigma
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/bin/spak.js ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @starpak/cli — spak executable.
4
+ * Runs the cac-based CLI: serve / config / cpc.
5
+ */
6
+ require('../lib/cli/index.js')
@@ -0,0 +1,20 @@
1
+ export interface FirewallRule {
2
+ action: 'allow' | 'deny';
3
+ target: string;
4
+ }
5
+ export declare function parseFirewallRule(str: string): FirewallRule | null;
6
+ /**
7
+ * (重)安装防火墙规则。默认规则为允许回环 + 拒绝外部。
8
+ */
9
+ export declare function installFirewall(newRules?: FirewallRule[]): void;
10
+ /** 追加一条 CLI 格式规则:"allow: localhost" / "deny: example.com:443"。 */
11
+ export declare function addFirewallRule(cliRule: string): {
12
+ ok: boolean;
13
+ rule?: FirewallRule;
14
+ };
15
+ export declare function resetFirewallRules(): void;
16
+ export declare function getFirewallRules(): FirewallRule[];
17
+ export declare function isFirewallInstalled(): boolean;
18
+ /** 沙箱子进程入口:从 SPAK_FIREWALL_RULES 环境变量安装同等规则。 */
19
+ export declare function applyFirewallFromEnv(): void;
20
+ //# sourceMappingURL=firewall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firewall.d.ts","sourceRoot":"","sources":["../../src/cli/firewall.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,OAAO,GAAG,MAAM,CAAA;IACxB,MAAM,EAAE,MAAM,CAAA;CACf;AAUD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAIlE;AA+FD;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,CAAC,EAAE,YAAY,EAAE,GAAG,IAAI,CAG/D;AAED,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,YAAY,CAAA;CAAE,CAOrF;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED,wBAAgB,gBAAgB,IAAI,YAAY,EAAE,CAEjD;AAED,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED,gDAAgD;AAChD,wBAAgB,oBAAoB,IAAI,IAAI,CAW3C"}
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ // ===== cli/firewall.ts — CPC 防火墙引擎(net 层真拦截,非 stub)=====
3
+ //
4
+ // 在 net.Socket.connect 层打补丁,按规则集 allow/deny 出站连接。
5
+ // 规则格式(与 CLI 面一致):"action: target"
6
+ // action = allow | deny
7
+ // target = localhost | external | <hostname> | <ip>[:port]
8
+ //
9
+ // 策略:fail-closed——没有规则命中时默认 deny。默认安装
10
+ // ["allow: localhost", "deny: external"],放行回环、拒绝其余出站。
11
+ // 兼容 http/https/ws 等一切最终走 net.connect 的上层模块。
12
+ //
13
+ // 支持向沙箱子进程传递:SPAK_FIREWALL_RULES=<JSON array>,子进程
14
+ // 内 applyFirewallFromEnv() 即装同等规则。
15
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ var desc = Object.getOwnPropertyDescriptor(m, k);
18
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
+ desc = { enumerable: true, get: function() { return m[k]; } };
20
+ }
21
+ Object.defineProperty(o, k2, desc);
22
+ }) : (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ o[k2] = m[k];
25
+ }));
26
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
28
+ }) : function(o, v) {
29
+ o["default"] = v;
30
+ });
31
+ var __importStar = (this && this.__importStar) || (function () {
32
+ var ownKeys = function(o) {
33
+ ownKeys = Object.getOwnPropertyNames || function (o) {
34
+ var ar = [];
35
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
+ return ar;
37
+ };
38
+ return ownKeys(o);
39
+ };
40
+ return function (mod) {
41
+ if (mod && mod.__esModule) return mod;
42
+ var result = {};
43
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
+ __setModuleDefault(result, mod);
45
+ return result;
46
+ };
47
+ })();
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ exports.parseFirewallRule = parseFirewallRule;
50
+ exports.installFirewall = installFirewall;
51
+ exports.addFirewallRule = addFirewallRule;
52
+ exports.resetFirewallRules = resetFirewallRules;
53
+ exports.getFirewallRules = getFirewallRules;
54
+ exports.isFirewallInstalled = isFirewallInstalled;
55
+ exports.applyFirewallFromEnv = applyFirewallFromEnv;
56
+ const net = __importStar(require("net"));
57
+ const tls = __importStar(require("tls"));
58
+ const DEFAULT_RULES = [
59
+ { action: 'allow', target: 'localhost' },
60
+ { action: 'deny', target: 'external' },
61
+ ];
62
+ let rules = [];
63
+ let patched = false;
64
+ function parseFirewallRule(str) {
65
+ const m = /^(allow|deny):\s*(.+)$/i.exec(str.trim());
66
+ if (!m)
67
+ return null;
68
+ return { action: m[1].toLowerCase(), target: m[2].trim().toLowerCase() };
69
+ }
70
+ /** 判断 host 是否回环地址(127.x / ::1 / localhost)。 */
71
+ function isLoopback(host) {
72
+ const h = (host || '').toLowerCase();
73
+ if (!h || h === 'localhost')
74
+ return true;
75
+ if (h === '::1' || h === '[::1]' || h === '0:0:0:0:0:0:0:1' || h === '[0:0:0:0:0:0:0:1]')
76
+ return true;
77
+ if (h.startsWith('127.'))
78
+ return true;
79
+ if (h === '::' || h === '0.0.0.0')
80
+ return true;
81
+ return false;
82
+ }
83
+ function targetMatches(rule, host, port) {
84
+ const t = rule.target;
85
+ const h = (host || '').toLowerCase();
86
+ if (t === 'localhost')
87
+ return isLoopback(h);
88
+ if (t === 'external')
89
+ return !isLoopback(h);
90
+ // 形如 "example.com:443" 或 "example.com" 或 "1.2.3.4:80"
91
+ const [hostPart, portPart] = t.split(':');
92
+ if (portPart !== undefined) {
93
+ const hp = Number(portPart);
94
+ return (hostPart ? h === hostPart : true) && port === hp;
95
+ }
96
+ return h === t;
97
+ }
98
+ /** 判定某连接是否被放行。fail-closed:无命中规则 → deny。 */
99
+ function decide(host, port) {
100
+ // UNIX socket / 无目标主机的连接(如 IPC)不在出站网络范畴,放行。
101
+ if (!host && (!port || port === 0))
102
+ return { allowed: true };
103
+ for (const rule of rules) {
104
+ if (targetMatches(rule, host, port)) {
105
+ return { allowed: rule.action === 'allow', rule };
106
+ }
107
+ }
108
+ return { allowed: false };
109
+ }
110
+ function check(host, port) {
111
+ const { allowed, rule } = decide(host, port);
112
+ if (!allowed) {
113
+ const denied = new Error(`CFW-DENY: outbound connection to ${host || '?'}:${port ?? '?'} blocked ` +
114
+ `(rule: ${rule ? `${rule.action}:${rule.target}` : 'no-match(default deny)'})`);
115
+ denied.code = 'ECFWACCESS';
116
+ throw denied;
117
+ }
118
+ }
119
+ function patchTls() {
120
+ const origTlsConnect = tls.connect;
121
+ const wrapped = function (...args) {
122
+ const opts = (args[0] || {});
123
+ const host = opts.host;
124
+ const port = typeof opts.port === 'number' ? opts.port : (typeof args[0] === 'number' ? args[0] : undefined);
125
+ check(host, port);
126
+ return origTlsConnect.apply(this, args);
127
+ };
128
+ // module namespace 属性通常是 getter-only,defineProperty 失败则依赖
129
+ // net.Socket 层拦截兜底(TLS 底层同样经过 net 建立连接)。
130
+ try {
131
+ Object.defineProperty(tls, 'connect', { value: wrapped, writable: true, configurable: true });
132
+ }
133
+ catch {
134
+ try {
135
+ tls.connect = wrapped;
136
+ }
137
+ catch { /* net 层兜底 */ }
138
+ }
139
+ }
140
+ function patchNet() {
141
+ if (patched)
142
+ return;
143
+ patched = true;
144
+ const origConnect = net.Socket.prototype.connect;
145
+ net.Socket.prototype.connect = function (...args) {
146
+ const first = args[0];
147
+ let host;
148
+ let port;
149
+ if (typeof first === 'number') {
150
+ port = first;
151
+ host = typeof args[1] === 'string' ? args[1] : 'localhost';
152
+ }
153
+ else if (typeof first === 'object' && first !== null) {
154
+ const o = first;
155
+ host = o.host;
156
+ port = typeof o.port === 'number' ? o.port : undefined;
157
+ }
158
+ else if (typeof first === 'string') {
159
+ // path 形式(UNIX socket/pipe)→ 放行
160
+ }
161
+ check(host, port);
162
+ return origConnect.apply(this, args);
163
+ };
164
+ patchTls();
165
+ }
166
+ /**
167
+ * (重)安装防火墙规则。默认规则为允许回环 + 拒绝外部。
168
+ */
169
+ function installFirewall(newRules) {
170
+ rules = newRules && newRules.length > 0 ? newRules : [...DEFAULT_RULES];
171
+ patchNet();
172
+ }
173
+ /** 追加一条 CLI 格式规则:"allow: localhost" / "deny: example.com:443"。 */
174
+ function addFirewallRule(cliRule) {
175
+ const rule = parseFirewallRule(cliRule);
176
+ if (!rule)
177
+ return { ok: false };
178
+ rules = rules.filter(r => !(r.action === rule.action && r.target === rule.target));
179
+ rules.unshift(rule);
180
+ patchNet();
181
+ return { ok: true, rule };
182
+ }
183
+ function resetFirewallRules() {
184
+ rules = [];
185
+ }
186
+ function getFirewallRules() {
187
+ return [...rules];
188
+ }
189
+ function isFirewallInstalled() {
190
+ return patched;
191
+ }
192
+ /** 沙箱子进程入口:从 SPAK_FIREWALL_RULES 环境变量安装同等规则。 */
193
+ function applyFirewallFromEnv() {
194
+ const raw = process.env.SPAK_FIREWALL_RULES;
195
+ if (!raw)
196
+ return;
197
+ try {
198
+ const parsed = JSON.parse(raw);
199
+ if (Array.isArray(parsed)) {
200
+ installFirewall(parsed.filter((r) => r && (r.action === 'allow' || r.action === 'deny') && typeof r.target === 'string'));
201
+ }
202
+ }
203
+ catch {
204
+ /* 含混规则直接忽略,保持进程可启动 */
205
+ }
206
+ }
207
+ //# sourceMappingURL=firewall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firewall.js","sourceRoot":"","sources":["../../src/cli/firewall.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const cac_1 = require("cac");
7
+ const kleur_1 = __importDefault(require("kleur"));
8
+ // Force ANSI colors regardless of TTY detection, so the CLI stays colorized
9
+ // in real terminals (and is visible even when piped).
10
+ kleur_1.default.enabled = true;
11
+ const registry_1 = require("./registry");
12
+ const start_1 = __importDefault(require("./start"));
13
+ const config_1 = __importDefault(require("../commands/config"));
14
+ const cpc_1 = __importDefault(require("../commands/cpc"));
15
+ const package_json_1 = require("../../package.json");
16
+ const log_1 = require("@starpak/log");
17
+ // Initialize CLI logger with simple formatter (normal mode)
18
+ (0, log_1.setGlobalFormatter)(log_1.simpleFormatter);
19
+ const cli = (0, cac_1.cac)('spak').help().version(package_json_1.version);
20
+ // Collect all package command declarations
21
+ const declarations = [
22
+ ...start_1.default,
23
+ ...config_1.default,
24
+ ...cpc_1.default,
25
+ ];
26
+ (0, registry_1.registerDeclarations)(cli, declarations);
27
+ // Intercept --help for subcommands before cac parses them
28
+ // Extract full subcommand path from argv (e.g. 'config list', 'cpc check')
29
+ const helpIndex = process.argv.findIndex(a => a === '--help' || a === '-h');
30
+ if (helpIndex > 0) {
31
+ // Collect all args before --help that aren't flags
32
+ const subArgs = [];
33
+ for (let i = 2; i < helpIndex; i++) {
34
+ const arg = process.argv[i];
35
+ if (!arg.startsWith('-'))
36
+ subArgs.push(arg);
37
+ }
38
+ if (subArgs.length > 0) {
39
+ const fullPath = subArgs.join(' ');
40
+ const help = (0, registry_1.generateCommandHelp)(fullPath, declarations) || (0, registry_1.generateCommandHelp)(subArgs[0], declarations);
41
+ if (help) {
42
+ console.log(help);
43
+ process.exit(0);
44
+ }
45
+ }
46
+ }
47
+ // Version shortcut: spak -v / spak --version should print ONLY the version
48
+ // line and exit (before cac gets a chance to print its own banner + help).
49
+ const hasVersionFlag = process.argv.slice(2).some(a => a === '-v' || a === '--version');
50
+ if (hasVersionFlag) {
51
+ const platform = `${process.platform} ${process.arch}`;
52
+ // Colorized version banner: spak name bright cyan + bold, version green,
53
+ // platform yellow (higher contrast than gray).
54
+ console.log(`${kleur_1.default.bold().cyan('spak')}/${kleur_1.default.green(package_json_1.version)} ${kleur_1.default.yellow(platform)} node-${process.version}`);
55
+ process.exit(0);
56
+ }
57
+ const argv = cli.parse();
58
+ // Friendly banner when spak is run without any command (instead of raw help).
59
+ if (!cli.matchedCommand && !argv.options.help) {
60
+ const gotFlags = process.argv.slice(2).some(a => a.startsWith('-'));
61
+ if (!gotFlags) {
62
+ // Check if there are unknown positional args (i.e. an unrecognized command)
63
+ const positionalArgs = process.argv.slice(2).filter(a => !a.startsWith('-'));
64
+ if (positionalArgs.length > 0) {
65
+ // Unknown command — show error, not the banner
66
+ console.error(kleur_1.default.red(`spak: 未知命令 "${positionalArgs[0]}"`));
67
+ console.error(kleur_1.default.dim(` 试试 'spak --help' 查看可用命令`));
68
+ process.exit(1);
69
+ }
70
+ const banner = ` ${kleur_1.default.bold().cyan('spak')} v${kleur_1.default.green(package_json_1.version)} · 多文件服务框架`;
71
+ console.log(banner);
72
+ process.exit(0);
73
+ }
74
+ cli.outputHelp();
75
+ }
76
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { CAC } from 'cac';
2
+ import { CommandDeclaration } from './types';
3
+ /**
4
+ * Register all commands as flat commands (does not support cac nested subcommands).
5
+ * Uses allowUnknownOptions + manual matching to support subcommand routing.
6
+ */
7
+ /** Exposed for index.ts to generate help text early */
8
+ export declare function generateCommandHelp(rootName: string, declarations: CommandDeclaration[], binName?: string): string;
9
+ export declare function registerDeclarations(cli: CAC, declarations: CommandDeclaration[], binName?: string): void;
10
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/cli/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AACzB,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAE5C;;;GAGG;AAEH,uDAAuD;AACvD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,kBAAkB,EAAE,EAClC,OAAO,GAAE,MAAe,GACvB,MAAM,CAIR;AAqFD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,GAAG,EAAE,YAAY,EAAE,kBAAkB,EAAE,EAAE,OAAO,GAAE,MAAe,QA6G1G"}
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateCommandHelp = generateCommandHelp;
4
+ exports.registerDeclarations = registerDeclarations;
5
+ /**
6
+ * Register all commands as flat commands (does not support cac nested subcommands).
7
+ * Uses allowUnknownOptions + manual matching to support subcommand routing.
8
+ */
9
+ /** Exposed for index.ts to generate help text early */
10
+ function generateCommandHelp(rootName, declarations, binName = 'spak') {
11
+ const rootDecl = declarations.find(d => d.command === rootName);
12
+ const children = declarations.filter(d => d.command.startsWith(rootName + ' ') && d.command !== rootName);
13
+ return generateHelp(binName, rootName, rootDecl, children);
14
+ }
15
+ /** Generate help text for subcommands */
16
+ function generateHelp(binName, rootName, rootDecl, children) {
17
+ // When the root command itself has options (e.g. `serve` with --port/--host),
18
+ // it is a functional leaf command — show its own usage/args/options first,
19
+ // and list subcommands as a supplement below. Only fall back to a pure
20
+ // subcommand listing when the root has no options of its own.
21
+ if (children.length > 0 && !rootDecl?.options?.length) {
22
+ let text = `\nUsage:\n $ ${binName} ${rootName} <command>\n\nCommands:\n`;
23
+ for (const child of children) {
24
+ const parts = child.command.split(' ').slice(1);
25
+ const usage = parts.map(p => {
26
+ if (p.startsWith('<'))
27
+ return p;
28
+ if (p.startsWith('['))
29
+ return p;
30
+ return p;
31
+ }).join(' ');
32
+ const display = `${rootName} ${usage}`;
33
+ const padding = display.length > 28 ? 1 : 28 - display.length;
34
+ text += ` ${display}${' '.repeat(padding)}${child.description}\n`;
35
+ }
36
+ text += `\nOptions:\n -h, --help Display this message\n`;
37
+ return text;
38
+ }
39
+ if (rootDecl) {
40
+ // Has args/options, so it is a leaf command; or just a description-only command
41
+ let text = `\nUsage:\n $ ${binName} ${rootName}`;
42
+ if (rootDecl.args) {
43
+ for (const arg of rootDecl.args) {
44
+ text += arg.required ? ` <${arg.name}>` : ` [${arg.name}]`;
45
+ }
46
+ }
47
+ if (rootDecl.options?.length)
48
+ text += ' [options]';
49
+ text += '\n';
50
+ if (rootDecl.description)
51
+ text += `\n${rootDecl.description}\n`;
52
+ if (rootDecl.args?.length) {
53
+ text += '\nArguments:\n';
54
+ for (const arg of rootDecl.args) {
55
+ text += ` ${arg.name}${' '.repeat(Math.max(1, 20 - arg.name.length))}${arg.description}`;
56
+ if (arg.required)
57
+ text += '(必填)';
58
+ text += '\n';
59
+ }
60
+ }
61
+ if (rootDecl.options?.length) {
62
+ text += '\nOptions:\n';
63
+ for (const opt of rootDecl.options) {
64
+ const flag = opt.alias ? `-${opt.alias}, --${opt.name}` : ` --${opt.name}`;
65
+ const left = `${flag}${opt.value ? ` <${opt.value}>` : ''}`;
66
+ text += ` ${left}${' '.repeat(Math.max(1, 30 - left.length))}${opt.description}`;
67
+ if (opt.required)
68
+ text += '(必填)';
69
+ if (opt.default)
70
+ text += ` (default: ${opt.default})`;
71
+ text += '\n';
72
+ }
73
+ text += ' -h, --help Display this message\n';
74
+ }
75
+ else {
76
+ text += '\nOptions:\n -h, --help Display this message\n';
77
+ }
78
+ if (rootDecl.examples?.length) {
79
+ text += '\nExamples:\n';
80
+ for (const example of rootDecl.examples)
81
+ text += ` ${example}\n`;
82
+ }
83
+ // Append subcommands (if any) as a supplement for leaf commands that
84
+ // also have children (e.g. `serve` + `serve status`).
85
+ if (children.length > 0) {
86
+ text += '\nSubcommands:\n';
87
+ for (const child of children) {
88
+ const parts = child.command.split(' ').slice(1);
89
+ const usage = parts.join(' ');
90
+ const display = `${rootName} ${usage}`;
91
+ const padding = display.length > 28 ? 1 : 28 - display.length;
92
+ text += ` ${display}${' '.repeat(padding)}${child.description}\n`;
93
+ }
94
+ }
95
+ return text;
96
+ }
97
+ return '';
98
+ }
99
+ function registerDeclarations(cli, declarations, binName = 'spak') {
100
+ // Collect root commands (each top-level command has one entry)
101
+ const rootCmdNames = new Set();
102
+ for (const decl of declarations) {
103
+ const root = decl.command.split(' ')[0];
104
+ rootCmdNames.add(root);
105
+ }
106
+ // Pre-generate help text mapping
107
+ const helpTexts = new Map();
108
+ for (const rootName of rootCmdNames) {
109
+ const rootDecl = declarations.find(d => d.command === rootName);
110
+ const children = declarations.filter(d => d.command.startsWith(rootName + ' ') && d.command !== rootName);
111
+ helpTexts.set(rootName, generateHelp(binName, rootName, rootDecl, children));
112
+ }
113
+ for (const rootName of rootCmdNames) {
114
+ const rootDecl = declarations.find(d => d.command === rootName);
115
+ const children = declarations.filter(d => d.command.startsWith(rootName + ' ') && d.command !== rootName);
116
+ const helpText = helpTexts.get(rootName) || '';
117
+ const cmd = cli.command(rootName, rootDecl?.description || '');
118
+ cmd.allowUnknownOptions();
119
+ // Register options
120
+ const allOptions = new Map();
121
+ for (const decl of [rootDecl, ...children].filter(Boolean)) {
122
+ if (decl?.options) {
123
+ for (const opt of decl.options) {
124
+ if (!allOptions.has(opt.name)) {
125
+ allOptions.set(opt.name, opt.description);
126
+ cmd.option(`--${opt.name} [${opt.name}]`, opt.description);
127
+ }
128
+ }
129
+ }
130
+ }
131
+ cmd.action((...args) => {
132
+ // cac puts options as the last arg, positional args come before
133
+ const rawOpts = args[args.length - 1] || {};
134
+ const options = rawOpts?.options || rawOpts;
135
+ const positional = args.slice(0, -1).filter((a) => typeof a === 'string');
136
+ // Extract subcommand from process.argv
137
+ const argv = process.argv;
138
+ const rootIdx = argv.indexOf(rootName);
139
+ // Positional extraction: skip flags and their following values.
140
+ const rest = rootIdx >= 0 ? argv.slice(rootIdx + 1) : [];
141
+ const subArgs = [];
142
+ for (let i = 0; i < rest.length; i++) {
143
+ const a = rest[i];
144
+ if (a.startsWith('-')) {
145
+ // skip the option value if the next token is not a flag
146
+ if (i + 1 < rest.length && !rest[i + 1].startsWith('-'))
147
+ i++;
148
+ continue;
149
+ }
150
+ subArgs.push(a);
151
+ }
152
+ const subCmd = subArgs.join(' ');
153
+ // Handle --help
154
+ const helpFlags = ['--help', '-h'];
155
+ const hasHelp = argv.slice(rootIdx + 1).some(a => helpFlags.includes(a));
156
+ if (hasHelp || (subArgs.length === 0 && children.length > 0 && !rootDecl?.args?.length)) {
157
+ console.log(helpText);
158
+ return;
159
+ }
160
+ // Find matching command declaration (longest match first)
161
+ let matchedDecl;
162
+ let matchedLen = 0;
163
+ for (const decl of declarations) {
164
+ const parts = decl.command.split(' ');
165
+ if (parts[0] !== rootName)
166
+ continue;
167
+ if (parts.length === 1)
168
+ continue; // Root command, fallback later
169
+ // Check if it matches the subcommand path
170
+ const subParts = parts.slice(1);
171
+ let match = true;
172
+ for (let i = 0; i < subParts.length; i++) {
173
+ // If argument placeholder (<xxx> or [xxx]), match any value
174
+ if (subParts[i].startsWith('<') || subParts[i].startsWith('['))
175
+ continue;
176
+ if (subParts[i] !== subArgs[i]) {
177
+ match = false;
178
+ break;
179
+ }
180
+ }
181
+ if (match && parts.length > matchedLen) {
182
+ matchedDecl = decl;
183
+ matchedLen = parts.length;
184
+ }
185
+ }
186
+ // If no subcommand matched, fall back to root command
187
+ if (!matchedDecl)
188
+ matchedDecl = rootDecl;
189
+ if (!matchedDecl)
190
+ return;
191
+ // Extract named arguments from declaration's args array
192
+ // subArgs includes subcommand tokens (e.g. ['set', 'language', 'en']),
193
+ // so skip the subcommand word count to get to actual argument values
194
+ const namedArgs = {};
195
+ if (matchedDecl.args) {
196
+ const declParts = matchedDecl.command.split(' ');
197
+ const subCmdWordCount = declParts.length - 1; // number of subcommand words
198
+ for (let i = 0; i < matchedDecl.args.length; i++) {
199
+ const arg = matchedDecl.args[i];
200
+ namedArgs[arg.name] = subArgs[subCmdWordCount + i] || '';
201
+ }
202
+ }
203
+ matchedDecl.action(namedArgs, options);
204
+ });
205
+ }
206
+ }
207
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/cli/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { CommandDeclaration } from './types';
2
+ declare const serveDeclarations: CommandDeclaration[];
3
+ export default serveDeclarations;
4
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAmM5C,QAAA,MAAM,iBAAiB,EAAE,kBAAkB,EA8D1C,CAAA;AAED,eAAe,iBAAiB,CAAA"}