padrone 1.0.0 → 1.2.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/CHANGELOG.md +51 -0
- package/LICENSE +1 -1
- package/README.md +92 -49
- package/dist/args-CKNh7Dm9.mjs +175 -0
- package/dist/args-CKNh7Dm9.mjs.map +1 -0
- package/dist/chunk-y_GBKt04.mjs +5 -0
- package/dist/codegen/index.d.mts +305 -0
- package/dist/codegen/index.d.mts.map +1 -0
- package/dist/codegen/index.mjs +1348 -0
- package/dist/codegen/index.mjs.map +1 -0
- package/dist/completion.d.mts +64 -0
- package/dist/completion.d.mts.map +1 -0
- package/dist/completion.mjs +417 -0
- package/dist/completion.mjs.map +1 -0
- package/dist/docs/index.d.mts +34 -0
- package/dist/docs/index.d.mts.map +1 -0
- package/dist/docs/index.mjs +404 -0
- package/dist/docs/index.mjs.map +1 -0
- package/dist/formatter-Dvx7jFXr.d.mts +82 -0
- package/dist/formatter-Dvx7jFXr.d.mts.map +1 -0
- package/dist/help-mUIX0T0V.mjs +1195 -0
- package/dist/help-mUIX0T0V.mjs.map +1 -0
- package/dist/index.d.mts +122 -438
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1240 -1161
- package/dist/index.mjs.map +1 -1
- package/dist/test.d.mts +112 -0
- package/dist/test.d.mts.map +1 -0
- package/dist/test.mjs +138 -0
- package/dist/test.mjs.map +1 -0
- package/dist/types-qrtt0135.d.mts +1037 -0
- package/dist/types-qrtt0135.d.mts.map +1 -0
- package/dist/update-check-EbNDkzyV.mjs +146 -0
- package/dist/update-check-EbNDkzyV.mjs.map +1 -0
- package/package.json +61 -20
- package/src/args.ts +365 -0
- package/src/cli/completions.ts +29 -0
- package/src/cli/docs.ts +86 -0
- package/src/cli/doctor.ts +312 -0
- package/src/cli/index.ts +159 -0
- package/src/cli/init.ts +135 -0
- package/src/cli/link.ts +320 -0
- package/src/cli/wrap.ts +152 -0
- package/src/codegen/README.md +118 -0
- package/src/codegen/code-builder.ts +226 -0
- package/src/codegen/discovery.ts +232 -0
- package/src/codegen/file-emitter.ts +73 -0
- package/src/codegen/generators/barrel-file.ts +16 -0
- package/src/codegen/generators/command-file.ts +184 -0
- package/src/codegen/generators/command-tree.ts +124 -0
- package/src/codegen/index.ts +33 -0
- package/src/codegen/parsers/fish.ts +163 -0
- package/src/codegen/parsers/help.ts +378 -0
- package/src/codegen/parsers/merge.ts +158 -0
- package/src/codegen/parsers/zsh.ts +221 -0
- package/src/codegen/schema-to-code.ts +199 -0
- package/src/codegen/template.ts +69 -0
- package/src/codegen/types.ts +143 -0
- package/src/colorizer.ts +2 -2
- package/src/command-utils.ts +501 -0
- package/src/completion.ts +110 -97
- package/src/create.ts +1044 -284
- package/src/docs/index.ts +607 -0
- package/src/errors.ts +131 -0
- package/src/formatter.ts +149 -63
- package/src/help.ts +151 -55
- package/src/index.ts +13 -15
- package/src/interactive.ts +169 -0
- package/src/parse.ts +31 -16
- package/src/repl-loop.ts +317 -0
- package/src/runtime.ts +304 -0
- package/src/shell-utils.ts +83 -0
- package/src/test.ts +285 -0
- package/src/type-helpers.ts +12 -12
- package/src/type-utils.ts +124 -14
- package/src/types.ts +803 -144
- package/src/update-check.ts +244 -0
- package/src/wrap.ts +185 -0
- package/src/zod.d.ts +2 -2
- package/src/options.ts +0 -180
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
import { a as commandSymbol, n as getHelpInfo } from "../help-mUIX0T0V.mjs";
|
|
2
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join, resolve } from "node:path";
|
|
4
|
+
//#region src/docs/index.ts
|
|
5
|
+
function collectAllHelpInfo(cmd, includeHidden) {
|
|
6
|
+
const result = [getHelpInfo(cmd, "standard")];
|
|
7
|
+
if (cmd.commands) for (const sub of cmd.commands) {
|
|
8
|
+
if (!includeHidden && sub.hidden) continue;
|
|
9
|
+
result.push(...collectAllHelpInfo(sub, includeHidden));
|
|
10
|
+
}
|
|
11
|
+
return result;
|
|
12
|
+
}
|
|
13
|
+
function generateFrontmatter(data) {
|
|
14
|
+
const lines = ["---"];
|
|
15
|
+
for (const [key, value] of Object.entries(data)) if (typeof value === "string") lines.push(`${key}: "${value.replace(/"/g, "\\\"")}"`);
|
|
16
|
+
else if (typeof value === "number" || typeof value === "boolean") lines.push(`${key}: ${value}`);
|
|
17
|
+
else if (Array.isArray(value)) {
|
|
18
|
+
lines.push(`${key}:`);
|
|
19
|
+
for (const item of value) lines.push(` - "${String(item).replace(/"/g, "\\\"")}"`);
|
|
20
|
+
}
|
|
21
|
+
lines.push("---");
|
|
22
|
+
return lines.join("\n");
|
|
23
|
+
}
|
|
24
|
+
function formatMarkdownPositional(arg) {
|
|
25
|
+
const parts = [];
|
|
26
|
+
parts.push(`- \`${arg.name}\``);
|
|
27
|
+
if (arg.type) parts.push(`*(${arg.type})*`);
|
|
28
|
+
if (arg.optional) parts.push("*(optional)*");
|
|
29
|
+
if (arg.default !== void 0) parts.push(`— default: \`${String(arg.default)}\``);
|
|
30
|
+
if (arg.description) parts.push(`— ${arg.description}`);
|
|
31
|
+
return parts.join(" ");
|
|
32
|
+
}
|
|
33
|
+
function formatMarkdownArgument(arg) {
|
|
34
|
+
const lines = [];
|
|
35
|
+
const flagName = arg.negatable ? `--[no-]${arg.name}` : `--${arg.name}`;
|
|
36
|
+
const header = `#### \`${arg.aliases?.length ? `${arg.aliases.map((a) => `-${a}`).join(", ")}, ` : ""}${flagName}\``;
|
|
37
|
+
lines.push(header);
|
|
38
|
+
lines.push("");
|
|
39
|
+
if (arg.description) {
|
|
40
|
+
lines.push(arg.description);
|
|
41
|
+
lines.push("");
|
|
42
|
+
}
|
|
43
|
+
const meta = [];
|
|
44
|
+
if (arg.type) meta.push(`**Type:** \`${arg.type}\``);
|
|
45
|
+
if (arg.optional) meta.push("**Optional**");
|
|
46
|
+
else meta.push("**Required**");
|
|
47
|
+
if (arg.default !== void 0) meta.push(`**Default:** \`${String(arg.default)}\``);
|
|
48
|
+
if (arg.enum) meta.push(`**Choices:** ${arg.enum.map((v) => `\`${v}\``).join(", ")}`);
|
|
49
|
+
if (arg.variadic) meta.push("**Repeatable**");
|
|
50
|
+
if (arg.deprecated) {
|
|
51
|
+
const msg = typeof arg.deprecated === "string" ? arg.deprecated : "";
|
|
52
|
+
meta.push(`**Deprecated**${msg ? `: ${msg}` : ""}`);
|
|
53
|
+
}
|
|
54
|
+
if (meta.length > 0) {
|
|
55
|
+
lines.push(meta.join(" | "));
|
|
56
|
+
lines.push("");
|
|
57
|
+
}
|
|
58
|
+
if (arg.env) {
|
|
59
|
+
const envVars = typeof arg.env === "string" ? [arg.env] : arg.env;
|
|
60
|
+
lines.push(`**Environment:** ${envVars.map((v) => `\`${v}\``).join(", ")}`);
|
|
61
|
+
lines.push("");
|
|
62
|
+
}
|
|
63
|
+
if (arg.configKey) {
|
|
64
|
+
lines.push(`**Config key:** \`${arg.configKey}\``);
|
|
65
|
+
lines.push("");
|
|
66
|
+
}
|
|
67
|
+
if (arg.examples?.length) {
|
|
68
|
+
lines.push(`**Examples:** ${arg.examples.map((e) => `\`${typeof e === "string" ? e : JSON.stringify(e)}\``).join(", ")}`);
|
|
69
|
+
lines.push("");
|
|
70
|
+
}
|
|
71
|
+
return lines;
|
|
72
|
+
}
|
|
73
|
+
function formatMarkdownSubcommand(sub) {
|
|
74
|
+
const parts = [];
|
|
75
|
+
const suffix = sub.hasSubcommands ? " ..." : "";
|
|
76
|
+
parts.push(`| \`${sub.name}${suffix}\``);
|
|
77
|
+
const aliases = sub.aliases?.filter((a) => a !== "[default]");
|
|
78
|
+
parts.push(`| ${aliases?.length ? aliases.map((a) => `\`${a}\``).join(", ") : ""}`);
|
|
79
|
+
const desc = sub.title ?? sub.description ?? "";
|
|
80
|
+
parts.push(`| ${desc}`);
|
|
81
|
+
parts.push("|");
|
|
82
|
+
return parts.join(" ");
|
|
83
|
+
}
|
|
84
|
+
function generateMarkdownPage(info, depth, frontmatterFn) {
|
|
85
|
+
const lines = [];
|
|
86
|
+
if (frontmatterFn) {
|
|
87
|
+
const fm = frontmatterFn(info, depth);
|
|
88
|
+
if (Object.keys(fm).length > 0) {
|
|
89
|
+
lines.push(generateFrontmatter(fm));
|
|
90
|
+
lines.push("");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const displayName = info.name === "<root>" || !info.name ? "CLI Reference" : info.name;
|
|
94
|
+
lines.push(`# ${displayName}`);
|
|
95
|
+
lines.push("");
|
|
96
|
+
if (info.deprecated) {
|
|
97
|
+
const msg = typeof info.deprecated === "string" ? info.deprecated : "This command is deprecated.";
|
|
98
|
+
lines.push(`> **Deprecated:** ${msg}`);
|
|
99
|
+
lines.push("");
|
|
100
|
+
}
|
|
101
|
+
if (info.title) {
|
|
102
|
+
lines.push(`> ${info.title}`);
|
|
103
|
+
lines.push("");
|
|
104
|
+
}
|
|
105
|
+
if (info.description) {
|
|
106
|
+
lines.push(info.description);
|
|
107
|
+
lines.push("");
|
|
108
|
+
}
|
|
109
|
+
if (info.aliases?.length) {
|
|
110
|
+
const realAliases = info.aliases.filter((a) => a !== "[default]");
|
|
111
|
+
if (realAliases.length > 0) {
|
|
112
|
+
lines.push(`**Aliases:** ${realAliases.map((a) => `\`${a}\``).join(", ")}`);
|
|
113
|
+
lines.push("");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const usageParts = [info.usage.command];
|
|
117
|
+
if (info.usage.hasSubcommands) usageParts.push("[command]");
|
|
118
|
+
if (info.positionals?.length) for (const arg of info.positionals) usageParts.push(arg.optional ? `[${arg.name}]` : `<${arg.name}>`);
|
|
119
|
+
if (info.usage.hasArguments) usageParts.push("[options]");
|
|
120
|
+
lines.push("## Usage");
|
|
121
|
+
lines.push("");
|
|
122
|
+
lines.push("```");
|
|
123
|
+
lines.push(usageParts.join(" "));
|
|
124
|
+
lines.push("```");
|
|
125
|
+
lines.push("");
|
|
126
|
+
if (info.subcommands?.length) {
|
|
127
|
+
const visibleSubs = info.subcommands.filter((s) => !s.hidden);
|
|
128
|
+
if (visibleSubs.length > 0) {
|
|
129
|
+
lines.push("## Commands");
|
|
130
|
+
lines.push("");
|
|
131
|
+
lines.push("| Command | Aliases | Description |");
|
|
132
|
+
lines.push("| --- | --- | --- |");
|
|
133
|
+
for (const sub of visibleSubs) lines.push(formatMarkdownSubcommand(sub));
|
|
134
|
+
lines.push("");
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (info.positionals?.length) {
|
|
138
|
+
lines.push("## Arguments");
|
|
139
|
+
lines.push("");
|
|
140
|
+
for (const arg of info.positionals) lines.push(formatMarkdownPositional(arg));
|
|
141
|
+
lines.push("");
|
|
142
|
+
}
|
|
143
|
+
if (info.arguments?.length) {
|
|
144
|
+
lines.push("## Options");
|
|
145
|
+
lines.push("");
|
|
146
|
+
for (const arg of info.arguments) lines.push(...formatMarkdownArgument(arg));
|
|
147
|
+
}
|
|
148
|
+
return `${lines.join("\n").trimEnd()}\n`;
|
|
149
|
+
}
|
|
150
|
+
function escapeHtml(text) {
|
|
151
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
152
|
+
}
|
|
153
|
+
function generateHtmlPage(info, depth) {
|
|
154
|
+
const displayName = info.name === "<root>" || !info.name ? "CLI Reference" : escapeHtml(info.name);
|
|
155
|
+
const sections = [];
|
|
156
|
+
sections.push(`<article class="padrone-docs-page" data-command="${escapeHtml(info.name)}" data-depth="${depth}">`);
|
|
157
|
+
sections.push(` <h1>${displayName}</h1>`);
|
|
158
|
+
if (info.deprecated) {
|
|
159
|
+
const msg = typeof info.deprecated === "string" ? escapeHtml(info.deprecated) : "This command is deprecated.";
|
|
160
|
+
sections.push(` <div class="deprecated-warning"><strong>Deprecated:</strong> ${msg}</div>`);
|
|
161
|
+
}
|
|
162
|
+
if (info.title) sections.push(` <p class="command-title">${escapeHtml(info.title)}</p>`);
|
|
163
|
+
if (info.description) sections.push(` <p class="command-description">${escapeHtml(info.description)}</p>`);
|
|
164
|
+
if (info.aliases?.length) {
|
|
165
|
+
const realAliases = info.aliases.filter((a) => a !== "[default]");
|
|
166
|
+
if (realAliases.length > 0) sections.push(` <p><strong>Aliases:</strong> ${realAliases.map((a) => `<code>${escapeHtml(a)}</code>`).join(", ")}</p>`);
|
|
167
|
+
}
|
|
168
|
+
const usageParts = [info.usage.command];
|
|
169
|
+
if (info.usage.hasSubcommands) usageParts.push("[command]");
|
|
170
|
+
if (info.positionals?.length) for (const arg of info.positionals) usageParts.push(arg.optional ? `[${arg.name}]` : `<${arg.name}>`);
|
|
171
|
+
if (info.usage.hasArguments) usageParts.push("[options]");
|
|
172
|
+
sections.push(" <h2>Usage</h2>");
|
|
173
|
+
sections.push(` <pre><code>${escapeHtml(usageParts.join(" "))}</code></pre>`);
|
|
174
|
+
if (info.subcommands?.length) {
|
|
175
|
+
const visibleSubs = info.subcommands.filter((s) => !s.hidden);
|
|
176
|
+
if (visibleSubs.length > 0) {
|
|
177
|
+
sections.push(" <h2>Commands</h2>");
|
|
178
|
+
sections.push(" <table>");
|
|
179
|
+
sections.push(" <thead><tr><th>Command</th><th>Aliases</th><th>Description</th></tr></thead>");
|
|
180
|
+
sections.push(" <tbody>");
|
|
181
|
+
for (const sub of visibleSubs) {
|
|
182
|
+
const aliases = sub.aliases?.filter((a) => a !== "[default]");
|
|
183
|
+
const desc = sub.title ?? sub.description ?? "";
|
|
184
|
+
const suffix = sub.hasSubcommands ? " ..." : "";
|
|
185
|
+
sections.push(` <tr><td><code>${escapeHtml(sub.name + suffix)}</code></td><td>${aliases?.length ? aliases.map((a) => `<code>${escapeHtml(a)}</code>`).join(", ") : ""}</td><td>${escapeHtml(desc)}</td></tr>`);
|
|
186
|
+
}
|
|
187
|
+
sections.push(" </tbody>");
|
|
188
|
+
sections.push(" </table>");
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (info.positionals?.length) {
|
|
192
|
+
sections.push(" <h2>Arguments</h2>");
|
|
193
|
+
sections.push(" <dl>");
|
|
194
|
+
for (const arg of info.positionals) {
|
|
195
|
+
sections.push(` <dt><code>${escapeHtml(arg.name)}</code>${arg.type ? ` <span class="type">${escapeHtml(arg.type)}</span>` : ""}${arg.optional ? " <em>(optional)</em>" : ""}</dt>`);
|
|
196
|
+
if (arg.description) sections.push(` <dd>${escapeHtml(arg.description)}</dd>`);
|
|
197
|
+
if (arg.default !== void 0) sections.push(` <dd>Default: <code>${escapeHtml(String(arg.default))}</code></dd>`);
|
|
198
|
+
}
|
|
199
|
+
sections.push(" </dl>");
|
|
200
|
+
}
|
|
201
|
+
if (info.arguments?.length) {
|
|
202
|
+
sections.push(" <h2>Options</h2>");
|
|
203
|
+
sections.push(" <dl>");
|
|
204
|
+
for (const arg of info.arguments) {
|
|
205
|
+
const flagName = arg.negatable ? `--[no-]${arg.name}` : `--${arg.name}`;
|
|
206
|
+
const aliases = arg.aliases?.length ? `${arg.aliases.map((a) => `-${a}`).join(", ")}, ` : "";
|
|
207
|
+
sections.push(` <dt><code>${escapeHtml(aliases + flagName)}</code>${arg.type ? ` <span class="type">${escapeHtml(arg.type)}</span>` : ""}</dt>`);
|
|
208
|
+
if (arg.description) sections.push(` <dd>${escapeHtml(arg.description)}</dd>`);
|
|
209
|
+
const meta = [];
|
|
210
|
+
if (arg.optional) meta.push("Optional");
|
|
211
|
+
else meta.push("Required");
|
|
212
|
+
if (arg.default !== void 0) meta.push(`Default: <code>${escapeHtml(String(arg.default))}</code>`);
|
|
213
|
+
if (arg.enum) meta.push(`Choices: ${arg.enum.map((v) => `<code>${escapeHtml(v)}</code>`).join(", ")}`);
|
|
214
|
+
if (arg.variadic) meta.push("Repeatable");
|
|
215
|
+
if (arg.deprecated) {
|
|
216
|
+
const msg = typeof arg.deprecated === "string" ? escapeHtml(arg.deprecated) : "";
|
|
217
|
+
meta.push(`Deprecated${msg ? `: ${msg}` : ""}`);
|
|
218
|
+
}
|
|
219
|
+
if (meta.length > 0) sections.push(` <dd class="meta">${meta.join(" · ")}</dd>`);
|
|
220
|
+
if (arg.env) {
|
|
221
|
+
const envVars = typeof arg.env === "string" ? [arg.env] : arg.env;
|
|
222
|
+
sections.push(` <dd>Environment: ${envVars.map((v) => `<code>${escapeHtml(v)}</code>`).join(", ")}</dd>`);
|
|
223
|
+
}
|
|
224
|
+
if (arg.configKey) sections.push(` <dd>Config key: <code>${escapeHtml(arg.configKey)}</code></dd>`);
|
|
225
|
+
}
|
|
226
|
+
sections.push(" </dl>");
|
|
227
|
+
}
|
|
228
|
+
sections.push("</article>");
|
|
229
|
+
return `${sections.join("\n")}\n`;
|
|
230
|
+
}
|
|
231
|
+
function escapeMan(text) {
|
|
232
|
+
return text.replace(/\\/g, "\\\\").replace(/-/g, "\\-").replace(/'/g, "\\(aq");
|
|
233
|
+
}
|
|
234
|
+
function generateManPage(info, _depth, programName) {
|
|
235
|
+
const commandName = info.name === "<root>" || !info.name ? programName : info.name;
|
|
236
|
+
const manName = commandName.replace(/\s+/g, "-");
|
|
237
|
+
const lines = [];
|
|
238
|
+
lines.push(`.TH "${escapeMan(manName.toUpperCase())}" "1" "" "" ""`);
|
|
239
|
+
lines.push(".SH NAME");
|
|
240
|
+
const desc = info.title ?? info.description ?? "";
|
|
241
|
+
lines.push(`${escapeMan(manName)}${desc ? ` \\- ${escapeMan(desc)}` : ""}`);
|
|
242
|
+
lines.push(".SH SYNOPSIS");
|
|
243
|
+
const usageParts = [`\\fB${escapeMan(commandName)}\\fR`];
|
|
244
|
+
if (info.usage.hasSubcommands) usageParts.push("[\\fIcommand\\fR]");
|
|
245
|
+
if (info.positionals?.length) for (const arg of info.positionals) usageParts.push(arg.optional ? `[\\fI${escapeMan(arg.name)}\\fR]` : `\\fI${escapeMan(arg.name)}\\fR`);
|
|
246
|
+
if (info.usage.hasArguments) usageParts.push("[\\fIoptions\\fR]");
|
|
247
|
+
lines.push(usageParts.join(" "));
|
|
248
|
+
if (info.description) {
|
|
249
|
+
lines.push(".SH DESCRIPTION");
|
|
250
|
+
lines.push(escapeMan(info.description));
|
|
251
|
+
}
|
|
252
|
+
if (info.subcommands?.length) {
|
|
253
|
+
const visibleSubs = info.subcommands.filter((s) => !s.hidden);
|
|
254
|
+
if (visibleSubs.length > 0) {
|
|
255
|
+
lines.push(".SH COMMANDS");
|
|
256
|
+
for (const sub of visibleSubs) {
|
|
257
|
+
const suffix = sub.hasSubcommands ? " ..." : "";
|
|
258
|
+
lines.push(`.TP`);
|
|
259
|
+
lines.push(`\\fB${escapeMan(sub.name + suffix)}\\fR`);
|
|
260
|
+
const subDesc = sub.title ?? sub.description;
|
|
261
|
+
if (subDesc) lines.push(escapeMan(subDesc));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (info.positionals?.length) {
|
|
266
|
+
lines.push(".SH ARGUMENTS");
|
|
267
|
+
for (const arg of info.positionals) {
|
|
268
|
+
lines.push(".TP");
|
|
269
|
+
lines.push(`\\fI${escapeMan(arg.name)}\\fR`);
|
|
270
|
+
const parts = [];
|
|
271
|
+
if (arg.description) parts.push(escapeMan(arg.description));
|
|
272
|
+
if (arg.optional) parts.push("(optional)");
|
|
273
|
+
if (arg.default !== void 0) parts.push(`Default: ${escapeMan(String(arg.default))}`);
|
|
274
|
+
if (parts.length > 0) lines.push(parts.join(". "));
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (info.arguments?.length) {
|
|
278
|
+
lines.push(".SH OPTIONS");
|
|
279
|
+
for (const arg of info.arguments) {
|
|
280
|
+
const flagName = arg.negatable ? `\\-\\-[no\\-]${escapeMan(arg.name)}` : `\\-\\-${escapeMan(arg.name)}`;
|
|
281
|
+
const aliases = arg.aliases?.length ? `${arg.aliases.map((a) => `\\-${escapeMan(a)}`).join(", ")}, ` : "";
|
|
282
|
+
lines.push(".TP");
|
|
283
|
+
lines.push(`\\fB${aliases}${flagName}\\fR${arg.type ? ` \\fI${escapeMan(arg.type)}\\fR` : ""}`);
|
|
284
|
+
const parts = [];
|
|
285
|
+
if (arg.description) parts.push(escapeMan(arg.description));
|
|
286
|
+
if (arg.default !== void 0) parts.push(`Default: ${escapeMan(String(arg.default))}`);
|
|
287
|
+
if (arg.enum) parts.push(`Choices: ${arg.enum.map((v) => escapeMan(v)).join(", ")}`);
|
|
288
|
+
if (parts.length > 0) lines.push(parts.join(". "));
|
|
289
|
+
if (arg.env) {
|
|
290
|
+
const envVars = typeof arg.env === "string" ? [arg.env] : arg.env;
|
|
291
|
+
lines.push(`.br`);
|
|
292
|
+
lines.push(`Environment: ${envVars.map((v) => escapeMan(v)).join(", ")}`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return `${lines.join("\n")}\n`;
|
|
297
|
+
}
|
|
298
|
+
function commandToPath(info, ext, isRoot) {
|
|
299
|
+
if (isRoot) return `index${ext}`;
|
|
300
|
+
return info.name.split(/\s+/).map((s) => s || "_default").join("/") + ext;
|
|
301
|
+
}
|
|
302
|
+
function generateMarkdownIndex(rootInfo, allInfos) {
|
|
303
|
+
const lines = [];
|
|
304
|
+
lines.push(`# ${rootInfo.title ?? rootInfo.name ?? "CLI"} Reference`);
|
|
305
|
+
lines.push("");
|
|
306
|
+
if (rootInfo.description) {
|
|
307
|
+
lines.push(rootInfo.description);
|
|
308
|
+
lines.push("");
|
|
309
|
+
}
|
|
310
|
+
if (allInfos.length > 1) {
|
|
311
|
+
lines.push("## Commands");
|
|
312
|
+
lines.push("");
|
|
313
|
+
for (const info of allInfos) {
|
|
314
|
+
const path = commandToPath(info, ".md", info === rootInfo);
|
|
315
|
+
const name = info === rootInfo ? info.name || "root" : info.name;
|
|
316
|
+
const desc = info.title ?? info.description ?? "";
|
|
317
|
+
lines.push(`- [${name}](${path})${desc ? ` — ${desc}` : ""}`);
|
|
318
|
+
}
|
|
319
|
+
lines.push("");
|
|
320
|
+
}
|
|
321
|
+
return `${lines.join("\n").trimEnd()}\n`;
|
|
322
|
+
}
|
|
323
|
+
function resolveCommand(programOrCommand) {
|
|
324
|
+
if (commandSymbol in programOrCommand) return programOrCommand[commandSymbol];
|
|
325
|
+
return programOrCommand;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Generate documentation for a Padrone CLI program or command tree.
|
|
329
|
+
* Accepts either a PadroneProgram (from createPadrone()) or a raw AnyPadroneCommand.
|
|
330
|
+
*/
|
|
331
|
+
function generateDocs(program, options = {}) {
|
|
332
|
+
const { format = "markdown", output, includeHidden = false, frontmatter, overwrite = true, dryRun = false } = options;
|
|
333
|
+
const cmd = resolveCommand(program);
|
|
334
|
+
const allInfos = collectAllHelpInfo(cmd, includeHidden);
|
|
335
|
+
const rootInfo = allInfos[0];
|
|
336
|
+
const programName = cmd.name || "program";
|
|
337
|
+
const pages = [];
|
|
338
|
+
const ext = format === "markdown" ? ".md" : format === "html" ? ".html" : format === "man" ? ".1" : ".json";
|
|
339
|
+
for (let i = 0; i < allInfos.length; i++) {
|
|
340
|
+
const info = allInfos[i];
|
|
341
|
+
const isRoot = i === 0;
|
|
342
|
+
const depth = isRoot ? 0 : info.name.split(/\s+/).length;
|
|
343
|
+
const path = commandToPath(info, ext, isRoot);
|
|
344
|
+
let content;
|
|
345
|
+
switch (format) {
|
|
346
|
+
case "markdown":
|
|
347
|
+
content = generateMarkdownPage(info, depth, frontmatter);
|
|
348
|
+
break;
|
|
349
|
+
case "html":
|
|
350
|
+
content = generateHtmlPage(info, depth);
|
|
351
|
+
break;
|
|
352
|
+
case "man":
|
|
353
|
+
content = generateManPage(info, depth, programName);
|
|
354
|
+
break;
|
|
355
|
+
case "json":
|
|
356
|
+
content = `${JSON.stringify(info, null, 2)}\n`;
|
|
357
|
+
break;
|
|
358
|
+
}
|
|
359
|
+
pages.push({
|
|
360
|
+
path,
|
|
361
|
+
content,
|
|
362
|
+
command: info.name
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
if (format === "markdown" && allInfos.length > 1) {
|
|
366
|
+
const rootPage = pages[0];
|
|
367
|
+
rootPage.content = generateMarkdownIndex(rootInfo, allInfos);
|
|
368
|
+
}
|
|
369
|
+
const result = {
|
|
370
|
+
pages,
|
|
371
|
+
written: [],
|
|
372
|
+
skipped: [],
|
|
373
|
+
errors: []
|
|
374
|
+
};
|
|
375
|
+
if (output) {
|
|
376
|
+
const outDir = resolve(output);
|
|
377
|
+
for (const page of pages) {
|
|
378
|
+
const fullPath = join(outDir, page.path);
|
|
379
|
+
try {
|
|
380
|
+
if (existsSync(fullPath) && !overwrite) {
|
|
381
|
+
result.skipped.push(page.path);
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
if (dryRun) {
|
|
385
|
+
result.written.push(page.path);
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
mkdirSync(dirname(fullPath), { recursive: true });
|
|
389
|
+
writeFileSync(fullPath, page.content, "utf-8");
|
|
390
|
+
result.written.push(page.path);
|
|
391
|
+
} catch (err) {
|
|
392
|
+
result.errors.push({
|
|
393
|
+
file: page.path,
|
|
394
|
+
error: err instanceof Error ? err : new Error(String(err))
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return result;
|
|
400
|
+
}
|
|
401
|
+
//#endregion
|
|
402
|
+
export { generateDocs };
|
|
403
|
+
|
|
404
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/docs/index.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { commandSymbol } from '../command-utils.ts';\nimport type { HelpArgumentInfo, HelpInfo, HelpPositionalInfo, HelpSubcommandInfo } from '../formatter.ts';\nimport { getHelpInfo } from '../help.ts';\nimport type { AnyPadroneCommand } from '../types.ts';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type DocsFormat = 'markdown' | 'html' | 'man' | 'json';\n\nexport type DocsOptions = {\n /** Output format. Defaults to 'markdown'. */\n format?: DocsFormat;\n /** Output directory. If not set, docs are returned but not written. */\n output?: string;\n /** Include hidden commands and options. Defaults to false. */\n includeHidden?: boolean;\n /** Frontmatter generator for markdown files (VitePress, Starlight, etc.). */\n frontmatter?: (info: HelpInfo, depth: number) => Record<string, unknown>;\n /** Whether to overwrite existing files. Defaults to true. */\n overwrite?: boolean;\n /** Print what would be written without writing. */\n dryRun?: boolean;\n};\n\nexport type DocsPage = {\n /** File path relative to output directory (e.g., \"deploy.md\", \"index.md\"). */\n path: string;\n /** Generated content for this page. */\n content: string;\n /** The command name this page documents. */\n command: string;\n};\n\nexport type DocsResult = {\n /** All generated pages. */\n pages: DocsPage[];\n /** Files that were written (empty if no output dir). */\n written: string[];\n /** Files that were skipped (already exist, no overwrite). */\n skipped: string[];\n /** Files that failed to write. */\n errors: { file: string; error: Error }[];\n};\n\n// ============================================================================\n// Help Info Collection\n// ============================================================================\n\nfunction collectAllHelpInfo(cmd: AnyPadroneCommand, includeHidden: boolean): HelpInfo[] {\n const info = getHelpInfo(cmd, 'standard');\n const result: HelpInfo[] = [info];\n\n if (cmd.commands) {\n for (const sub of cmd.commands) {\n if (!includeHidden && sub.hidden) continue;\n result.push(...collectAllHelpInfo(sub, includeHidden));\n }\n }\n\n return result;\n}\n\n// ============================================================================\n// Markdown Generator\n// ============================================================================\n\nfunction generateFrontmatter(data: Record<string, unknown>): string {\n const lines: string[] = ['---'];\n for (const [key, value] of Object.entries(data)) {\n if (typeof value === 'string') {\n lines.push(`${key}: \"${value.replace(/\"/g, '\\\\\"')}\"`);\n } else if (typeof value === 'number' || typeof value === 'boolean') {\n lines.push(`${key}: ${value}`);\n } else if (Array.isArray(value)) {\n lines.push(`${key}:`);\n for (const item of value) {\n lines.push(` - \"${String(item).replace(/\"/g, '\\\\\"')}\"`);\n }\n }\n }\n lines.push('---');\n return lines.join('\\n');\n}\n\nfunction formatMarkdownPositional(arg: HelpPositionalInfo): string {\n const parts: string[] = [];\n parts.push(`- \\`${arg.name}\\``);\n if (arg.type) parts.push(`*(${arg.type})*`);\n if (arg.optional) parts.push('*(optional)*');\n if (arg.default !== undefined) parts.push(`— default: \\`${String(arg.default)}\\``);\n if (arg.description) parts.push(`— ${arg.description}`);\n return parts.join(' ');\n}\n\nfunction formatMarkdownArgument(arg: HelpArgumentInfo): string[] {\n const lines: string[] = [];\n\n const flagName = arg.negatable ? `--[no-]${arg.name}` : `--${arg.name}`;\n const aliases = arg.aliases?.length ? `${arg.aliases.map((a) => `-${a}`).join(', ')}, ` : '';\n const header = `#### \\`${aliases}${flagName}\\``;\n lines.push(header);\n lines.push('');\n\n if (arg.description) {\n lines.push(arg.description);\n lines.push('');\n }\n\n const meta: string[] = [];\n if (arg.type) meta.push(`**Type:** \\`${arg.type}\\``);\n if (arg.optional) meta.push('**Optional**');\n else meta.push('**Required**');\n if (arg.default !== undefined) meta.push(`**Default:** \\`${String(arg.default)}\\``);\n if (arg.enum) meta.push(`**Choices:** ${arg.enum.map((v) => `\\`${v}\\``).join(', ')}`);\n if (arg.variadic) meta.push('**Repeatable**');\n if (arg.deprecated) {\n const msg = typeof arg.deprecated === 'string' ? arg.deprecated : '';\n meta.push(`**Deprecated**${msg ? `: ${msg}` : ''}`);\n }\n\n if (meta.length > 0) {\n lines.push(meta.join(' | '));\n lines.push('');\n }\n\n if (arg.env) {\n const envVars = typeof arg.env === 'string' ? [arg.env] : arg.env;\n lines.push(`**Environment:** ${envVars.map((v) => `\\`${v}\\``).join(', ')}`);\n lines.push('');\n }\n\n if (arg.configKey) {\n lines.push(`**Config key:** \\`${arg.configKey}\\``);\n lines.push('');\n }\n\n if (arg.examples?.length) {\n lines.push(`**Examples:** ${arg.examples.map((e) => `\\`${typeof e === 'string' ? e : JSON.stringify(e)}\\``).join(', ')}`);\n lines.push('');\n }\n\n return lines;\n}\n\nfunction formatMarkdownSubcommand(sub: HelpSubcommandInfo): string {\n const parts: string[] = [];\n const suffix = sub.hasSubcommands ? ' ...' : '';\n parts.push(`| \\`${sub.name}${suffix}\\``);\n\n const aliases = sub.aliases?.filter((a) => a !== '[default]');\n parts.push(`| ${aliases?.length ? aliases.map((a) => `\\`${a}\\``).join(', ') : ''}`);\n\n const desc = sub.title ?? sub.description ?? '';\n parts.push(`| ${desc}`);\n parts.push('|');\n\n return parts.join(' ');\n}\n\nfunction generateMarkdownPage(info: HelpInfo, depth: number, frontmatterFn?: DocsOptions['frontmatter']): string {\n const lines: string[] = [];\n\n if (frontmatterFn) {\n const fm = frontmatterFn(info, depth);\n if (Object.keys(fm).length > 0) {\n lines.push(generateFrontmatter(fm));\n lines.push('');\n }\n }\n\n // Title\n const displayName = info.name === '<root>' || !info.name ? 'CLI Reference' : info.name;\n lines.push(`# ${displayName}`);\n lines.push('');\n\n // Deprecation warning\n if (info.deprecated) {\n const msg = typeof info.deprecated === 'string' ? info.deprecated : 'This command is deprecated.';\n lines.push(`> **Deprecated:** ${msg}`);\n lines.push('');\n }\n\n // Description\n if (info.title) {\n lines.push(`> ${info.title}`);\n lines.push('');\n }\n if (info.description) {\n lines.push(info.description);\n lines.push('');\n }\n\n // Aliases\n if (info.aliases?.length) {\n const realAliases = info.aliases.filter((a) => a !== '[default]');\n if (realAliases.length > 0) {\n lines.push(`**Aliases:** ${realAliases.map((a) => `\\`${a}\\``).join(', ')}`);\n lines.push('');\n }\n }\n\n // Usage\n const usageParts: string[] = [info.usage.command];\n if (info.usage.hasSubcommands) usageParts.push('[command]');\n if (info.positionals?.length) {\n for (const arg of info.positionals) {\n usageParts.push(arg.optional ? `[${arg.name}]` : `<${arg.name}>`);\n }\n }\n if (info.usage.hasArguments) usageParts.push('[options]');\n\n lines.push('## Usage');\n lines.push('');\n lines.push('```');\n lines.push(usageParts.join(' '));\n lines.push('```');\n lines.push('');\n\n // Subcommands\n if (info.subcommands?.length) {\n const visibleSubs = info.subcommands.filter((s) => !s.hidden);\n if (visibleSubs.length > 0) {\n lines.push('## Commands');\n lines.push('');\n lines.push('| Command | Aliases | Description |');\n lines.push('| --- | --- | --- |');\n for (const sub of visibleSubs) {\n lines.push(formatMarkdownSubcommand(sub));\n }\n lines.push('');\n }\n }\n\n // Positional arguments\n if (info.positionals?.length) {\n lines.push('## Arguments');\n lines.push('');\n for (const arg of info.positionals) {\n lines.push(formatMarkdownPositional(arg));\n }\n lines.push('');\n }\n\n // Options\n if (info.arguments?.length) {\n lines.push('## Options');\n lines.push('');\n for (const arg of info.arguments) {\n lines.push(...formatMarkdownArgument(arg));\n }\n }\n\n return `${lines.join('\\n').trimEnd()}\\n`;\n}\n\n// ============================================================================\n// HTML Generator\n// ============================================================================\n\nfunction escapeHtml(text: string): string {\n return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n}\n\nfunction generateHtmlPage(info: HelpInfo, depth: number): string {\n const displayName = info.name === '<root>' || !info.name ? 'CLI Reference' : escapeHtml(info.name);\n\n const sections: string[] = [];\n\n // Header\n sections.push(`<article class=\"padrone-docs-page\" data-command=\"${escapeHtml(info.name)}\" data-depth=\"${depth}\">`);\n sections.push(` <h1>${displayName}</h1>`);\n\n if (info.deprecated) {\n const msg = typeof info.deprecated === 'string' ? escapeHtml(info.deprecated) : 'This command is deprecated.';\n sections.push(` <div class=\"deprecated-warning\"><strong>Deprecated:</strong> ${msg}</div>`);\n }\n\n if (info.title) {\n sections.push(` <p class=\"command-title\">${escapeHtml(info.title)}</p>`);\n }\n if (info.description) {\n sections.push(` <p class=\"command-description\">${escapeHtml(info.description)}</p>`);\n }\n\n // Aliases\n if (info.aliases?.length) {\n const realAliases = info.aliases.filter((a) => a !== '[default]');\n if (realAliases.length > 0) {\n sections.push(` <p><strong>Aliases:</strong> ${realAliases.map((a) => `<code>${escapeHtml(a)}</code>`).join(', ')}</p>`);\n }\n }\n\n // Usage\n const usageParts: string[] = [info.usage.command];\n if (info.usage.hasSubcommands) usageParts.push('[command]');\n if (info.positionals?.length) {\n for (const arg of info.positionals) {\n usageParts.push(arg.optional ? `[${arg.name}]` : `<${arg.name}>`);\n }\n }\n if (info.usage.hasArguments) usageParts.push('[options]');\n\n sections.push(' <h2>Usage</h2>');\n sections.push(` <pre><code>${escapeHtml(usageParts.join(' '))}</code></pre>`);\n\n // Subcommands\n if (info.subcommands?.length) {\n const visibleSubs = info.subcommands.filter((s) => !s.hidden);\n if (visibleSubs.length > 0) {\n sections.push(' <h2>Commands</h2>');\n sections.push(' <table>');\n sections.push(' <thead><tr><th>Command</th><th>Aliases</th><th>Description</th></tr></thead>');\n sections.push(' <tbody>');\n for (const sub of visibleSubs) {\n const aliases = sub.aliases?.filter((a) => a !== '[default]');\n const desc = sub.title ?? sub.description ?? '';\n const suffix = sub.hasSubcommands ? ' ...' : '';\n sections.push(\n ` <tr><td><code>${escapeHtml(sub.name + suffix)}</code></td><td>${aliases?.length ? aliases.map((a) => `<code>${escapeHtml(a)}</code>`).join(', ') : ''}</td><td>${escapeHtml(desc)}</td></tr>`,\n );\n }\n sections.push(' </tbody>');\n sections.push(' </table>');\n }\n }\n\n // Positional arguments\n if (info.positionals?.length) {\n sections.push(' <h2>Arguments</h2>');\n sections.push(' <dl>');\n for (const arg of info.positionals) {\n sections.push(\n ` <dt><code>${escapeHtml(arg.name)}</code>${arg.type ? ` <span class=\"type\">${escapeHtml(arg.type)}</span>` : ''}${arg.optional ? ' <em>(optional)</em>' : ''}</dt>`,\n );\n if (arg.description) sections.push(` <dd>${escapeHtml(arg.description)}</dd>`);\n if (arg.default !== undefined) sections.push(` <dd>Default: <code>${escapeHtml(String(arg.default))}</code></dd>`);\n }\n sections.push(' </dl>');\n }\n\n // Options\n if (info.arguments?.length) {\n sections.push(' <h2>Options</h2>');\n sections.push(' <dl>');\n for (const arg of info.arguments) {\n const flagName = arg.negatable ? `--[no-]${arg.name}` : `--${arg.name}`;\n const aliases = arg.aliases?.length ? `${arg.aliases.map((a) => `-${a}`).join(', ')}, ` : '';\n sections.push(\n ` <dt><code>${escapeHtml(aliases + flagName)}</code>${arg.type ? ` <span class=\"type\">${escapeHtml(arg.type)}</span>` : ''}</dt>`,\n );\n if (arg.description) sections.push(` <dd>${escapeHtml(arg.description)}</dd>`);\n\n const meta: string[] = [];\n if (arg.optional) meta.push('Optional');\n else meta.push('Required');\n if (arg.default !== undefined) meta.push(`Default: <code>${escapeHtml(String(arg.default))}</code>`);\n if (arg.enum) meta.push(`Choices: ${arg.enum.map((v) => `<code>${escapeHtml(v)}</code>`).join(', ')}`);\n if (arg.variadic) meta.push('Repeatable');\n if (arg.deprecated) {\n const msg = typeof arg.deprecated === 'string' ? escapeHtml(arg.deprecated) : '';\n meta.push(`Deprecated${msg ? `: ${msg}` : ''}`);\n }\n if (meta.length > 0) sections.push(` <dd class=\"meta\">${meta.join(' · ')}</dd>`);\n\n if (arg.env) {\n const envVars = typeof arg.env === 'string' ? [arg.env] : arg.env;\n sections.push(` <dd>Environment: ${envVars.map((v) => `<code>${escapeHtml(v)}</code>`).join(', ')}</dd>`);\n }\n if (arg.configKey) {\n sections.push(` <dd>Config key: <code>${escapeHtml(arg.configKey)}</code></dd>`);\n }\n }\n sections.push(' </dl>');\n }\n\n sections.push('</article>');\n return `${sections.join('\\n')}\\n`;\n}\n\n// ============================================================================\n// Man Page Generator\n// ============================================================================\n\nfunction escapeMan(text: string): string {\n return text.replace(/\\\\/g, '\\\\\\\\').replace(/-/g, '\\\\-').replace(/'/g, '\\\\(aq');\n}\n\nfunction generateManPage(info: HelpInfo, _depth: number, programName: string): string {\n const commandName = info.name === '<root>' || !info.name ? programName : info.name;\n const manName = commandName.replace(/\\s+/g, '-');\n const lines: string[] = [];\n\n lines.push(`.TH \"${escapeMan(manName.toUpperCase())}\" \"1\" \"\" \"\" \"\"`);\n\n // NAME\n lines.push('.SH NAME');\n const desc = info.title ?? info.description ?? '';\n lines.push(`${escapeMan(manName)}${desc ? ` \\\\- ${escapeMan(desc)}` : ''}`);\n\n // SYNOPSIS\n lines.push('.SH SYNOPSIS');\n const usageParts: string[] = [`\\\\fB${escapeMan(commandName)}\\\\fR`];\n if (info.usage.hasSubcommands) usageParts.push('[\\\\fIcommand\\\\fR]');\n if (info.positionals?.length) {\n for (const arg of info.positionals) {\n usageParts.push(arg.optional ? `[\\\\fI${escapeMan(arg.name)}\\\\fR]` : `\\\\fI${escapeMan(arg.name)}\\\\fR`);\n }\n }\n if (info.usage.hasArguments) usageParts.push('[\\\\fIoptions\\\\fR]');\n lines.push(usageParts.join(' '));\n\n // DESCRIPTION\n if (info.description) {\n lines.push('.SH DESCRIPTION');\n lines.push(escapeMan(info.description));\n }\n\n // COMMANDS\n if (info.subcommands?.length) {\n const visibleSubs = info.subcommands.filter((s) => !s.hidden);\n if (visibleSubs.length > 0) {\n lines.push('.SH COMMANDS');\n for (const sub of visibleSubs) {\n const suffix = sub.hasSubcommands ? ' ...' : '';\n lines.push(`.TP`);\n lines.push(`\\\\fB${escapeMan(sub.name + suffix)}\\\\fR`);\n const subDesc = sub.title ?? sub.description;\n if (subDesc) lines.push(escapeMan(subDesc));\n }\n }\n }\n\n // ARGUMENTS\n if (info.positionals?.length) {\n lines.push('.SH ARGUMENTS');\n for (const arg of info.positionals) {\n lines.push('.TP');\n lines.push(`\\\\fI${escapeMan(arg.name)}\\\\fR`);\n const parts: string[] = [];\n if (arg.description) parts.push(escapeMan(arg.description));\n if (arg.optional) parts.push('(optional)');\n if (arg.default !== undefined) parts.push(`Default: ${escapeMan(String(arg.default))}`);\n if (parts.length > 0) lines.push(parts.join('. '));\n }\n }\n\n // OPTIONS\n if (info.arguments?.length) {\n lines.push('.SH OPTIONS');\n for (const arg of info.arguments) {\n const flagName = arg.negatable ? `\\\\-\\\\-[no\\\\-]${escapeMan(arg.name)}` : `\\\\-\\\\-${escapeMan(arg.name)}`;\n const aliases = arg.aliases?.length ? `${arg.aliases.map((a) => `\\\\-${escapeMan(a)}`).join(', ')}, ` : '';\n lines.push('.TP');\n lines.push(`\\\\fB${aliases}${flagName}\\\\fR${arg.type ? ` \\\\fI${escapeMan(arg.type)}\\\\fR` : ''}`);\n const parts: string[] = [];\n if (arg.description) parts.push(escapeMan(arg.description));\n if (arg.default !== undefined) parts.push(`Default: ${escapeMan(String(arg.default))}`);\n if (arg.enum) parts.push(`Choices: ${arg.enum.map((v) => escapeMan(v)).join(', ')}`);\n if (parts.length > 0) lines.push(parts.join('. '));\n\n if (arg.env) {\n const envVars = typeof arg.env === 'string' ? [arg.env] : arg.env;\n lines.push(`.br`);\n lines.push(`Environment: ${envVars.map((v) => escapeMan(v)).join(', ')}`);\n }\n }\n }\n\n return `${lines.join('\\n')}\\n`;\n}\n\n// ============================================================================\n// Page Path Helpers\n// ============================================================================\n\nfunction commandToPath(info: HelpInfo, ext: string, isRoot: boolean): string {\n if (isRoot) return `index${ext}`;\n // Split on whitespace and replace empty segments (from empty-name default commands) with \"_default\"\n const segments = info.name.split(/\\s+/).map((s) => s || '_default');\n return segments.join('/') + ext;\n}\n\n// ============================================================================\n// Index Page Generators\n// ============================================================================\n\nfunction generateMarkdownIndex(rootInfo: HelpInfo, allInfos: HelpInfo[]): string {\n const lines: string[] = [];\n lines.push(`# ${rootInfo.title ?? rootInfo.name ?? 'CLI'} Reference`);\n lines.push('');\n\n if (rootInfo.description) {\n lines.push(rootInfo.description);\n lines.push('');\n }\n\n if (allInfos.length > 1) {\n lines.push('## Commands');\n lines.push('');\n for (const info of allInfos) {\n const path = commandToPath(info, '.md', info === rootInfo);\n const name = info === rootInfo ? info.name || 'root' : info.name;\n const desc = info.title ?? info.description ?? '';\n lines.push(`- [${name}](${path})${desc ? ` — ${desc}` : ''}`);\n }\n lines.push('');\n }\n\n return `${lines.join('\\n').trimEnd()}\\n`;\n}\n\n// ============================================================================\n// Main Entry Point\n// ============================================================================\n\nfunction resolveCommand(programOrCommand: object): AnyPadroneCommand {\n if (commandSymbol in programOrCommand) return (programOrCommand as any)[commandSymbol] as AnyPadroneCommand;\n return programOrCommand as AnyPadroneCommand;\n}\n\n/**\n * Generate documentation for a Padrone CLI program or command tree.\n * Accepts either a PadroneProgram (from createPadrone()) or a raw AnyPadroneCommand.\n */\nexport function generateDocs(program: object, options: DocsOptions = {}): DocsResult {\n const { format = 'markdown', output, includeHidden = false, frontmatter, overwrite = true, dryRun = false } = options;\n\n const cmd = resolveCommand(program);\n const allInfos = collectAllHelpInfo(cmd, includeHidden);\n const rootInfo = allInfos[0]!;\n const programName = cmd.name || 'program';\n\n const pages: DocsPage[] = [];\n\n const ext = format === 'markdown' ? '.md' : format === 'html' ? '.html' : format === 'man' ? '.1' : '.json';\n\n for (let i = 0; i < allInfos.length; i++) {\n const info = allInfos[i]!;\n const isRoot = i === 0;\n const depth = isRoot ? 0 : info.name.split(/\\s+/).length;\n const path = commandToPath(info, ext, isRoot);\n\n let content: string;\n switch (format) {\n case 'markdown':\n content = generateMarkdownPage(info, depth, frontmatter);\n break;\n case 'html':\n content = generateHtmlPage(info, depth);\n break;\n case 'man':\n content = generateManPage(info, depth, programName);\n break;\n case 'json':\n content = `${JSON.stringify(info, null, 2)}\\n`;\n break;\n }\n\n pages.push({ path, content, command: info.name });\n }\n\n // Generate index page for markdown (when there are subcommands)\n if (format === 'markdown' && allInfos.length > 1) {\n // Replace the root page with a combined index\n const rootPage = pages[0]!;\n rootPage.content = generateMarkdownIndex(rootInfo, allInfos);\n }\n\n const result: DocsResult = { pages, written: [], skipped: [], errors: [] };\n\n // Write to disk if output dir specified\n if (output) {\n const outDir = resolve(output);\n\n for (const page of pages) {\n const fullPath = join(outDir, page.path);\n\n try {\n if (existsSync(fullPath) && !overwrite) {\n result.skipped.push(page.path);\n continue;\n }\n\n if (dryRun) {\n result.written.push(page.path);\n continue;\n }\n\n const dir = dirname(fullPath);\n mkdirSync(dir, { recursive: true });\n writeFileSync(fullPath, page.content, 'utf-8');\n result.written.push(page.path);\n } catch (err) {\n result.errors.push({\n file: page.path,\n error: err instanceof Error ? err : new Error(String(err)),\n });\n }\n }\n }\n\n return result;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
//#region src/formatter.d.ts
|
|
2
|
+
type HelpFormat = 'text' | 'ansi' | 'console' | 'markdown' | 'html' | 'json';
|
|
3
|
+
type HelpDetail = 'minimal' | 'standard' | 'full';
|
|
4
|
+
/**
|
|
5
|
+
* Information about a single positional argument.
|
|
6
|
+
*/
|
|
7
|
+
type HelpPositionalInfo = {
|
|
8
|
+
name: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
optional: boolean;
|
|
11
|
+
default?: unknown;
|
|
12
|
+
type?: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Information about a single argument/flag.
|
|
16
|
+
*/
|
|
17
|
+
type HelpArgumentInfo = {
|
|
18
|
+
name: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
optional: boolean;
|
|
21
|
+
default?: unknown;
|
|
22
|
+
type?: string;
|
|
23
|
+
enum?: string[];
|
|
24
|
+
aliases?: string[];
|
|
25
|
+
deprecated?: boolean | string;
|
|
26
|
+
hidden?: boolean;
|
|
27
|
+
examples?: unknown[]; /** Environment variable(s) this arg can be set from */
|
|
28
|
+
env?: string | string[]; /** Whether this arg is an array type (shown as <type...>) */
|
|
29
|
+
variadic?: boolean; /** Whether this arg is a boolean (shown as --[no-]arg) */
|
|
30
|
+
negatable?: boolean; /** Config file key that maps to this arg */
|
|
31
|
+
configKey?: string;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Information about a subcommand (minimal info for listing).
|
|
35
|
+
*/
|
|
36
|
+
type HelpSubcommandInfo = {
|
|
37
|
+
name: string;
|
|
38
|
+
title?: string;
|
|
39
|
+
description?: string;
|
|
40
|
+
aliases?: string[];
|
|
41
|
+
deprecated?: boolean | string;
|
|
42
|
+
hidden?: boolean;
|
|
43
|
+
hasSubcommands?: boolean;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Information about a built-in command/flag entry.
|
|
47
|
+
*/
|
|
48
|
+
type HelpBuiltinInfo = {
|
|
49
|
+
name: string;
|
|
50
|
+
description?: string;
|
|
51
|
+
sub?: {
|
|
52
|
+
name: string;
|
|
53
|
+
description?: string;
|
|
54
|
+
}[];
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Comprehensive JSON structure for help information.
|
|
58
|
+
* This is the single source of truth that all formatters use.
|
|
59
|
+
*/
|
|
60
|
+
type HelpInfo = {
|
|
61
|
+
/** The full command name (e.g., "cli serve" or "<root>") */name: string; /** Short title for the command */
|
|
62
|
+
title?: string; /** Command description */
|
|
63
|
+
description?: string; /** Alternative names/aliases for this command */
|
|
64
|
+
aliases?: string[]; /** Whether the command is deprecated */
|
|
65
|
+
deprecated?: boolean | string; /** Whether the command is hidden */
|
|
66
|
+
hidden?: boolean; /** Usage string parts for flexible formatting */
|
|
67
|
+
usage: {
|
|
68
|
+
command: string;
|
|
69
|
+
hasSubcommands: boolean;
|
|
70
|
+
hasPositionals: boolean;
|
|
71
|
+
hasArguments: boolean; /** The name of the field that reads from stdin, if any. Shown as `[stdin > field]` in usage. */
|
|
72
|
+
stdinField?: string;
|
|
73
|
+
}; /** List of subcommands */
|
|
74
|
+
subcommands?: HelpSubcommandInfo[]; /** Positional arguments */
|
|
75
|
+
positionals?: HelpPositionalInfo[]; /** Arguments/flags (only visible ones, hidden filtered out) */
|
|
76
|
+
arguments?: HelpArgumentInfo[]; /** Built-in commands and flags (shown only for root command) */
|
|
77
|
+
builtins?: HelpBuiltinInfo[]; /** Full help info for nested commands (used in 'full' detail mode) */
|
|
78
|
+
nestedCommands?: HelpInfo[];
|
|
79
|
+
};
|
|
80
|
+
//#endregion
|
|
81
|
+
export { HelpFormat as n, HelpInfo as r, HelpDetail as t };
|
|
82
|
+
//# sourceMappingURL=formatter-Dvx7jFXr.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatter-Dvx7jFXr.d.mts","names":[],"sources":["../src/formatter.ts"],"mappings":";KAEY,UAAA;AAAA,KACA,UAAA;;;;KASA,kBAAA;EACV,IAAA;EACA,WAAA;EACA,QAAA;EACA,OAAA;EACA,IAAA;AAAA;;;;KAMU,gBAAA;EACV,IAAA;EACA,WAAA;EACA,QAAA;EACA,OAAA;EACA,IAAA;EACA,IAAA;EACA,OAAA;EACA,UAAA;EACA,MAAA;EACA,QAAA,cATA;EAWA,GAAA,sBATA;EAWA,QAAA,YATA;EAWA,SAAA,YATA;EAWA,SAAA;AAAA;;;;KAMU,kBAAA;EACV,IAAA;EACA,KAAA;EACA,WAAA;EACA,OAAA;EACA,UAAA;EACA,MAAA;EACA,cAAA;AAAA;;;;KAMU,eAAA;EACV,IAAA;EACA,WAAA;EACA,GAAA;IAAQ,IAAA;IAAc,WAAA;EAAA;AAAA;;;;;KAOZ,QAAA;EAPY,4DAStB,IAAA,UATiC;EAWjC,KAAA,WAJkB;EAMlB,WAAA,WAiBc;EAfd,OAAA,aAmBY;EAjBZ,UAAA,qBAqBiB;EAnBjB,MAAA,YAmByB;EAjBzB,KAAA;IACE,OAAA;IACA,cAAA;IACA,cAAA;IACA,YAAA,WANF;IAQE,UAAA;EAAA,GAJA;EAOF,WAAA,GAAc,kBAAA,IALZ;EAOF,WAAA,GAAc,kBAAA,IAFd;EAIA,SAAA,GAAY,gBAAA,IAFZ;EAIA,QAAA,GAAW,eAAA,IAFX;EAIA,cAAA,GAAiB,QAAA;AAAA"}
|