@crustjs/man 0.0.2
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/README.md +11 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.js +10 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# @crustjs/man
|
|
2
|
+
|
|
3
|
+
Generate **mdoc(7)** manual pages (section 1) from a Crust CLI definition.
|
|
4
|
+
|
|
5
|
+
See the [Man module docs](https://crustjs.com/docs/modules/man) for install steps, `writeManPage`, `crust build --man`, and packaging notes.
|
|
6
|
+
|
|
7
|
+
## Roadmap (v2+)
|
|
8
|
+
|
|
9
|
+
- Optional **one man page per subcommand** (or a mode switch)
|
|
10
|
+
- Extra **meta** or sidecar content for long **DESCRIPTION**, **EXAMPLES**, **SEE ALSO**
|
|
11
|
+
- **Subprocess**-based tree export when in-process `prepareCommandTree` is not enough
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { CommandNode } from "@crustjs/core";
|
|
2
|
+
interface RenderManPageMdocOptions {
|
|
3
|
+
/** Frozen root command node (e.g. from `prepareCommandTree()`). */
|
|
4
|
+
root: CommandNode;
|
|
5
|
+
/** Name shown in `man <name>` / `.Nm` (often matches the binary). */
|
|
6
|
+
name: string;
|
|
7
|
+
/** Manual section; user commands use `1`. */
|
|
8
|
+
section?: number;
|
|
9
|
+
/**
|
|
10
|
+
* Override the `.Dd` date (e.g. `"April 1, 2026"`). If omitted, uses
|
|
11
|
+
* `SOURCE_DATE_EPOCH` when set, otherwise today.
|
|
12
|
+
*/
|
|
13
|
+
date?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Render an mdoc(7) manual page (section 1) for the root command tree.
|
|
17
|
+
*/
|
|
18
|
+
declare function renderManPageMdoc(options: RenderManPageMdocOptions): string;
|
|
19
|
+
import { Crust } from "@crustjs/core";
|
|
20
|
+
interface WriteManPageOptions {
|
|
21
|
+
/** Root Crust builder for your CLI. */
|
|
22
|
+
app: Crust;
|
|
23
|
+
/** Name for `.Nm` / `man <name>` (usually the installed binary name). */
|
|
24
|
+
name: string;
|
|
25
|
+
/** Output path (e.g. `man/mycli.1`). Parent directories are created. */
|
|
26
|
+
outfile: string;
|
|
27
|
+
/** Manual section; defaults to `1`. */
|
|
28
|
+
section?: number;
|
|
29
|
+
/** Override `.Dd` in the mdoc output (see `renderManPageMdoc` `date`). */
|
|
30
|
+
date?: string;
|
|
31
|
+
/** Synthetic argv passed to plugin `setup()`; defaults to `[]`. */
|
|
32
|
+
argv?: readonly string[];
|
|
33
|
+
/**
|
|
34
|
+
* When `true` (default), print plugin-setup warnings to `console.warn`.
|
|
35
|
+
* Set to `false` in tests or CI if you handle warnings yourself.
|
|
36
|
+
*/
|
|
37
|
+
logWarnings?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Freeze and validate the command tree, render an mdoc(7) manual page, and
|
|
41
|
+
* write it to `outfile`.
|
|
42
|
+
*/
|
|
43
|
+
declare function writeManPage(options: WriteManPageOptions): Promise<void>;
|
|
44
|
+
export { writeManPage, renderManPageMdoc, WriteManPageOptions, RenderManPageMdocOptions };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var W=["January","February","March","April","May","June","July","August","September","October","November","December"];function Z(j){if(j.startsWith("."))return`\\&${j}`;return j}function E(j){if(typeof j==="number"&&!Number.isFinite(j))return String(j);if(Array.isArray(j))return j.map(String).join(", ");return JSON.stringify(j)}function M(j){return`[default: ${E(j)}]`}function _(j,P){if(P===void 0)return j??"";let q=M(P);if(!j)return q;return`${j} ${q}`}function k(j){let P=j.variadic?`${j.name}...`:j.name;return j.required?`<${P}>`:`[${P}]`}function A(j,P,q){if(j.usage)return j.usage;let G=[q.join(" ")];if(Object.keys(P.subCommands).length>0&&!P.run)G.push("<command>");if(P.args)for(let K of P.args)G.push(k(K));if(Object.keys(P.effectiveFlags).length>0)G.push("[options]");return G.join(" ")}function B(j,P){let q=[];if(P.short)q.push(`-${P.short}`);if(q.push(`--${j}`),P.type==="boolean"&&!P.noNegate)q.push(`--no-${j}`);return q.join(", ")}function D(j){return j.toUpperCase().replace(/[^A-Z0-9]+/g,"_").replace(/^_|_$/g,"")||"COMMAND"}function F(j){return j.replace(/\s+/g," ").trim()}function T(j){let P=F(j);if(P.startsWith("."))return`\\&${P}`;return P}function V(j){let P=8;for(let[q,G]of Object.entries(j))P=Math.max(P,B(q,G).length);return`${P}n`}function w(j){let P=8;for(let q of Object.keys(j.subCommands))P=Math.max(P,q.length);return`${P}n`}function S(j){if(j)return j;let P=process.env.SOURCE_DATE_EPOCH;if(P!==void 0){let G=Number.parseInt(P,10);if(!Number.isNaN(G)&&G>=0){let K=new Date(G*1000);return`${W[K.getUTCMonth()]} ${K.getUTCDate()}, ${K.getUTCFullYear()}`}}let q=new Date;return`${W[q.getMonth()]} ${q.getDate()}, ${q.getFullYear()}`}function U(j){let{root:P,name:q,section:G=1,date:K}=j,$=S(K),z=[P.meta.name],O=A(P.meta,P,z),Q=P.meta.description?.trim()||"No description provided.",C=[`.Dd ${$}`,`.Dt ${D(q)} ${G}`,".Os",".Sh NAME",`.Nm ${q}`,`.Nd ${T(Q)}`,".Sh SYNOPSIS",".Bd -literal",O,".Ed",".Sh DESCRIPTION"];for(let I of Q.split(`
|
|
3
|
+
`))C.push(Z(I));let R=Object.keys(P.subCommands);if(R.length>0){C.push(".Sh SUBCOMMANDS"),C.push(`.Bl -tag -width ${w(P)}`);for(let I of R.sort()){let J=P.subCommands[I];if(!J)continue;C.push(`.It Nm ${I}`);let Y=J.meta.description?.trim()||"";if(Y)C.push(Y.split(`
|
|
4
|
+
`).map(Z).join(`
|
|
5
|
+
`))}C.push(".El")}let X=Object.entries(P.effectiveFlags).sort(([I],[J])=>I.localeCompare(J));if(X.length>0){C.push(".Sh OPTIONS"),C.push(`.Bl -tag -width ${V(P.effectiveFlags)}`);for(let[I,J]of X){let Y=B(I,J);C.push(`.It Sy ${Y}`);let H=_(J.description,J.default).trim();if(H)C.push(H.split(`
|
|
6
|
+
`).map(Z).join(`
|
|
7
|
+
`))}C.push(".El")}if(P.args&&P.args.length>0){C.push(".Sh ARGUMENTS"),C.push(".Bl -tag -width 12n");for(let I of P.args){C.push(`.It Ql ${k(I)}`);let J=_(I.description,I.default).trim();if(J)C.push(J.split(`
|
|
8
|
+
`).map(Z).join(`
|
|
9
|
+
`))}C.push(".El")}return C.push(""),C.join(`
|
|
10
|
+
`)}import{mkdirSync as y,writeFileSync as L}from"fs";import{dirname as N}from"path";async function h(j){let{app:P,name:q,outfile:G,section:K=1,date:$,argv:z,logWarnings:O=!0}=j,{root:Q,warnings:C}=await P.prepareCommandTree({argv:z});if(O)for(let X of C)console.warn(`Warning: ${X}`);let R=U({root:Q,name:q,section:K,date:$});y(N(G),{recursive:!0}),L(G,R,"utf8")}export{h as writeManPage,U as renderManPageMdoc};
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@crustjs/man",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "Generate mdoc(7) manual pages from Crust CLI definitions",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "chenxin-yan",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/chenxin-yan/crust.git",
|
|
11
|
+
"directory": "packages/man"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://crustjs.com",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/chenxin-yan/crust/issues"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"cli",
|
|
19
|
+
"crust",
|
|
20
|
+
"man",
|
|
21
|
+
"mdoc",
|
|
22
|
+
"documentation",
|
|
23
|
+
"bun"
|
|
24
|
+
],
|
|
25
|
+
"files": [
|
|
26
|
+
"dist"
|
|
27
|
+
],
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"import": "./dist/index.js",
|
|
31
|
+
"types": "./dist/index.d.ts"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "bunup",
|
|
39
|
+
"dev": "bunup --watch",
|
|
40
|
+
"check:types": "tsc --noEmit",
|
|
41
|
+
"test": "bun test",
|
|
42
|
+
"publish": "bun publish --no-git-checks || true"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@crustjs/config": "0.0.0",
|
|
46
|
+
"@crustjs/core": "0.0.16",
|
|
47
|
+
"@crustjs/plugins": "0.0.21",
|
|
48
|
+
"bunup": "^0.16.31"
|
|
49
|
+
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"@crustjs/core": "0.0.16",
|
|
52
|
+
"typescript": "^6.0.2"
|
|
53
|
+
}
|
|
54
|
+
}
|