@xyd-js/opencli-remark 0.0.0-build-b7bd05c-20260701151111
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 +9 -0
- package/LICENSE +21 -0
- package/README.md +222 -0
- package/dist/index.cjs +290 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +36 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +271 -0
- package/dist/index.js.map +1 -0
- package/index.ts +4 -0
- package/opencli-spec.json +382 -0
- package/package.json +36 -0
- package/src/__fixtures__/1.code-block-format/input.md +15 -0
- package/src/__fixtures__/1.code-block-format/output.md +15 -0
- package/src/__fixtures__/10.variadic-arguments/input.md +5 -0
- package/src/__fixtures__/10.variadic-arguments/output.md +5 -0
- package/src/__fixtures__/11.no-matching-key/actual.md +30 -0
- package/src/__fixtures__/11.no-matching-key/input.md +30 -0
- package/src/__fixtures__/11.no-matching-key/output.md +30 -0
- package/src/__fixtures__/2.list-format/input.md +16 -0
- package/src/__fixtures__/2.list-format/output.md +19 -0
- package/src/__fixtures__/3.root-command/input.md +9 -0
- package/src/__fixtures__/3.root-command/output.md +9 -0
- package/src/__fixtures__/4.nested-command/input.md +14 -0
- package/src/__fixtures__/4.nested-command/output.md +17 -0
- package/src/__fixtures__/5.command-alias/input.md +7 -0
- package/src/__fixtures__/5.command-alias/output.md +7 -0
- package/src/__fixtures__/6.options-with-arguments/input.md +9 -0
- package/src/__fixtures__/6.options-with-arguments/output.md +10 -0
- package/src/__fixtures__/7.no-args-or-opts/input.md +13 -0
- package/src/__fixtures__/7.no-args-or-opts/output.md +13 -0
- package/src/__fixtures__/8.multiple-placeholders/input.md +11 -0
- package/src/__fixtures__/8.multiple-placeholders/output.md +12 -0
- package/src/__fixtures__/9.list-format-arguments/input.md +8 -0
- package/src/__fixtures__/9.list-format-arguments/output.md +9 -0
- package/src/__fixtures__/opencli-spec.json +81 -0
- package/src/__tests__/generate-types.ts +30 -0
- package/src/__tests__/remark-opencli.test.ts +100 -0
- package/src/__tests__/testHelpers.ts +110 -0
- package/src/__tests__/types.gen.ts +1 -0
- package/src/remark-opencli.ts +386 -0
- package/src/types.ts +269 -0
- package/tsconfig.json +18 -0
- package/tsup.config.ts +19 -0
- package/vitest.config.ts +8 -0
package/CHANGELOG.md
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) LiveSession Sp.z.o.o
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# xyd-opencli-remark
|
|
2
|
+
|
|
3
|
+
The package includes a remark plugin for generating OpenCLI documentation from variables in markdown files.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { remarkOpencliDocs } from '@xyd-js/opencli-remark';
|
|
9
|
+
import remarkFrontmatter from 'remark-frontmatter';
|
|
10
|
+
import remarkStringify from 'remark-stringify';
|
|
11
|
+
import { remark } from 'remark';
|
|
12
|
+
|
|
13
|
+
// Configure multiple CLI specs
|
|
14
|
+
remark()
|
|
15
|
+
.use(remarkFrontmatter)
|
|
16
|
+
.use(remarkOpencliDocs, {
|
|
17
|
+
xyd: { source: './xyd-cli.json' },
|
|
18
|
+
npm: { source: './npm-cli.json' },
|
|
19
|
+
// Add more CLIs as needed
|
|
20
|
+
})
|
|
21
|
+
.use(remarkStringify)
|
|
22
|
+
.process(markdown);
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Configuration
|
|
26
|
+
|
|
27
|
+
The plugin accepts an object where each key represents a CLI identifier, and the value contains the spec configuration:
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
{
|
|
31
|
+
[cliKey: string]: {
|
|
32
|
+
source: string; // Path to OpenCLI spec JSON file (relative to markdown file) or URL
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Example:**
|
|
38
|
+
```typescript
|
|
39
|
+
remarkOpencliDocs({
|
|
40
|
+
xyd: { source: './xyd-cli.json' },
|
|
41
|
+
npm: { source: 'https://example.com/npm-cli.json' }
|
|
42
|
+
})
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Frontmatter Configuration
|
|
46
|
+
|
|
47
|
+
In your markdown frontmatter, specify which CLI to use and the command path:
|
|
48
|
+
|
|
49
|
+
```yaml
|
|
50
|
+
---
|
|
51
|
+
xyd.opencli.xyd: "dev"
|
|
52
|
+
---
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The CLI key (e.g., `xyd`) must match a key in your plugin configuration. The command path is **relative to the CLI root** (no CLI name prefix needed).
|
|
56
|
+
|
|
57
|
+
### Command Path Examples
|
|
58
|
+
|
|
59
|
+
- **Root command**: Use an empty string `""`
|
|
60
|
+
```yaml
|
|
61
|
+
xyd.opencli.xyd: ""
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
- **Top-level command**: Just the command name
|
|
65
|
+
```yaml
|
|
66
|
+
xyd.opencli.xyd: "dev"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
- **Nested command**: Space-separated path
|
|
70
|
+
```yaml
|
|
71
|
+
xyd.opencli.xyd: "components install"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
- **Using aliases**: You can use command aliases
|
|
75
|
+
```yaml
|
|
76
|
+
xyd.opencli.xyd: "d" # if "d" is an alias for "dev"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Indent Style Configuration
|
|
80
|
+
|
|
81
|
+
You can configure the output format for arguments and options:
|
|
82
|
+
|
|
83
|
+
```yaml
|
|
84
|
+
---
|
|
85
|
+
xyd.opencli.xyd:
|
|
86
|
+
command: "dev"
|
|
87
|
+
indent: list # or "code" (default)
|
|
88
|
+
---
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
- **`code`** (default): Tab-indented CLI-style format, suitable for code blocks
|
|
92
|
+
- **`list`**: Markdown list format with backticks, suitable for regular markdown
|
|
93
|
+
|
|
94
|
+
## Example Markdown
|
|
95
|
+
|
|
96
|
+
### Code Block Format (default)
|
|
97
|
+
|
|
98
|
+
**Input:**
|
|
99
|
+
```markdown
|
|
100
|
+
---
|
|
101
|
+
xyd.opencli.xyd: "dev"
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
```sh
|
|
105
|
+
Usage: {opencli.current.usage}
|
|
106
|
+
|
|
107
|
+
{opencli.current.description}
|
|
108
|
+
|
|
109
|
+
Arguments:
|
|
110
|
+
{opencli.current.arguments}
|
|
111
|
+
|
|
112
|
+
Options:
|
|
113
|
+
{opencli.current.options}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Output:**
|
|
117
|
+
```markdown
|
|
118
|
+
---
|
|
119
|
+
xyd.opencli.xyd: "dev"
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
```sh
|
|
123
|
+
Usage: xyd dev [flags]
|
|
124
|
+
|
|
125
|
+
Run your docs locally in development mode
|
|
126
|
+
|
|
127
|
+
Options:
|
|
128
|
+
-p, --port <number> Port to run the dev server on
|
|
129
|
+
-l, --logLevel <string> Set logging level (e.g. info, debug)
|
|
130
|
+
--verbose Enable verbose output
|
|
131
|
+
--debug Enable debug output
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### List Format
|
|
135
|
+
|
|
136
|
+
**Input:**
|
|
137
|
+
```markdown
|
|
138
|
+
---
|
|
139
|
+
xyd.opencli.xyd:
|
|
140
|
+
command: "dev"
|
|
141
|
+
indent: list
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Usage
|
|
145
|
+
`{opencli.current.usage}`
|
|
146
|
+
|
|
147
|
+
{opencli.current.description}
|
|
148
|
+
|
|
149
|
+
## Arguments
|
|
150
|
+
{opencli.current.arguments}
|
|
151
|
+
|
|
152
|
+
## Options
|
|
153
|
+
{opencli.current.options}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Output:**
|
|
157
|
+
```markdown
|
|
158
|
+
---
|
|
159
|
+
xyd.opencli.xyd:
|
|
160
|
+
command: "dev"
|
|
161
|
+
indent: list
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Usage
|
|
165
|
+
|
|
166
|
+
`xyd dev [flags]`
|
|
167
|
+
|
|
168
|
+
Run your docs locally in development mode
|
|
169
|
+
|
|
170
|
+
## Arguments
|
|
171
|
+
|
|
172
|
+
## Options
|
|
173
|
+
|
|
174
|
+
- `-p`, `--port <number>` Port to run the dev server on
|
|
175
|
+
- `-l`, `--logLevel <string>` Set logging level (e.g. info, debug)
|
|
176
|
+
- `--verbose` Enable verbose output
|
|
177
|
+
- `--debug` Enable debug output
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Variables
|
|
181
|
+
|
|
182
|
+
The following Variables are supported:
|
|
183
|
+
|
|
184
|
+
| Variable | Description | Format Support |
|
|
185
|
+
|------------|-------------|----------------|
|
|
186
|
+
| `{opencli.current.usage}` | Generates usage line (e.g., `xyd dev [flags]`) | All formats |
|
|
187
|
+
| `{opencli.current.description}` | Command description | All formats |
|
|
188
|
+
| `{opencli.current.commands}` | List of available subcommands | All formats |
|
|
189
|
+
| `{opencli.current.arguments}` | Command arguments documentation | Code blocks, text (code style), or list nodes (list style) |
|
|
190
|
+
| `{opencli.current.options}` | Command options/flags documentation | Code blocks, text (code style), or list nodes (list style) |
|
|
191
|
+
|
|
192
|
+
**Note:**
|
|
193
|
+
- `{opencli.current.arguments}` and `{opencli.current.options}` work in:
|
|
194
|
+
- Code blocks (always code format)
|
|
195
|
+
- Text nodes (code format when `indent: 'code'`)
|
|
196
|
+
- List nodes (list format when `indent: 'list'` - automatically converted to markdown lists)
|
|
197
|
+
|
|
198
|
+
## Multiple CLIs
|
|
199
|
+
|
|
200
|
+
You can configure and use multiple CLI specs in the same project:
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
remarkOpencliDocs({
|
|
204
|
+
xyd: { source: './xyd-cli.json' },
|
|
205
|
+
npm: { source: './npm-cli.json' },
|
|
206
|
+
git: { source: './git-cli.json' }
|
|
207
|
+
})
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Then in different markdown files, reference the appropriate CLI:
|
|
211
|
+
|
|
212
|
+
```yaml
|
|
213
|
+
# File 1: xyd-dev.md
|
|
214
|
+
---
|
|
215
|
+
xyd.opencli.xyd: "dev"
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
# File 2: npm-install.md
|
|
219
|
+
---
|
|
220
|
+
xyd.opencli.npm: "install"
|
|
221
|
+
---
|
|
222
|
+
```
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// index.ts
|
|
22
|
+
var index_exports = {};
|
|
23
|
+
__export(index_exports, {
|
|
24
|
+
remarkOpencliDocs: () => remarkOpencliDocs
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(index_exports);
|
|
27
|
+
__reExport(index_exports, require("@xyd-js/opencli"), module.exports);
|
|
28
|
+
|
|
29
|
+
// src/remark-opencli.ts
|
|
30
|
+
var import_unist_util_visit = require("unist-util-visit");
|
|
31
|
+
var import_vfile_matter = require("vfile-matter");
|
|
32
|
+
var import_js_yaml = require("js-yaml");
|
|
33
|
+
var import_opencli = require("@xyd-js/opencli");
|
|
34
|
+
function remarkOpencliDocs(options) {
|
|
35
|
+
return async function transformer(tree, file) {
|
|
36
|
+
var _a;
|
|
37
|
+
if (!file) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (!file.data) {
|
|
41
|
+
file.data = {};
|
|
42
|
+
}
|
|
43
|
+
let hasOpencliKey = false;
|
|
44
|
+
let yamlContent = null;
|
|
45
|
+
(0, import_unist_util_visit.visit)(tree, "yaml", (node) => {
|
|
46
|
+
if (node.value && !yamlContent) {
|
|
47
|
+
const content = String(node.value);
|
|
48
|
+
yamlContent = content;
|
|
49
|
+
if (content.includes("xyd.opencli.")) {
|
|
50
|
+
hasOpencliKey = true;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
if (!yamlContent && file.value) {
|
|
55
|
+
const fileValue = typeof file.value === "string" ? file.value : new TextDecoder().decode(file.value);
|
|
56
|
+
const frontmatterMatch = fileValue.match(/^---\n([\s\S]*?)\n---/);
|
|
57
|
+
if (frontmatterMatch && frontmatterMatch[1].includes("xyd.opencli.")) {
|
|
58
|
+
hasOpencliKey = true;
|
|
59
|
+
yamlContent = frontmatterMatch[1];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (!hasOpencliKey) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
let frontmatter = file.data.matter;
|
|
66
|
+
if (!frontmatter && yamlContent) {
|
|
67
|
+
try {
|
|
68
|
+
frontmatter = (0, import_js_yaml.load)(yamlContent);
|
|
69
|
+
file.data.matter = frontmatter;
|
|
70
|
+
} catch (error) {
|
|
71
|
+
if (file.value) {
|
|
72
|
+
(0, import_vfile_matter.matter)(file);
|
|
73
|
+
frontmatter = file.data.matter;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (!frontmatter && file.value) {
|
|
78
|
+
(0, import_vfile_matter.matter)(file);
|
|
79
|
+
frontmatter = file.data.matter;
|
|
80
|
+
}
|
|
81
|
+
let cliKey = null;
|
|
82
|
+
let opencliConfig = null;
|
|
83
|
+
for (const key in frontmatter) {
|
|
84
|
+
if (key.startsWith("xyd.opencli.")) {
|
|
85
|
+
cliKey = key.substring("xyd.opencli.".length);
|
|
86
|
+
opencliConfig = frontmatter[key];
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (!cliKey || opencliConfig === void 0 || opencliConfig === null) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const cliConfig = options[cliKey];
|
|
94
|
+
if (!cliConfig || !cliConfig.source) {
|
|
95
|
+
console.warn(`No configuration found for CLI key "${cliKey}"`);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
let commandPath;
|
|
99
|
+
let indentStyle = "code";
|
|
100
|
+
if (typeof opencliConfig === "string") {
|
|
101
|
+
commandPath = opencliConfig;
|
|
102
|
+
} else if (typeof opencliConfig === "object" && opencliConfig !== null) {
|
|
103
|
+
commandPath = opencliConfig.command || "";
|
|
104
|
+
indentStyle = opencliConfig.indent === "list" ? "list" : "code";
|
|
105
|
+
} else {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const normalizedPath = (commandPath == null ? void 0 : commandPath.trim()) || "";
|
|
109
|
+
const spec = await (0, import_opencli.loadOpencliSpec)(cliConfig.source, { cwd: file.dirname });
|
|
110
|
+
if (!spec) {
|
|
111
|
+
console.warn(`Failed to load OpenCLI spec from ${cliConfig.source}`);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const command = (0, import_opencli.findCommand)(spec, normalizedPath);
|
|
115
|
+
if (!command) {
|
|
116
|
+
console.warn(`Command "${normalizedPath || "(root)"}" not found in OpenCLI spec`);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const cliTitle = ((_a = spec.info) == null ? void 0 : _a.title) || "";
|
|
120
|
+
const displayPath = normalizedPath ? `${cliTitle} ${normalizedPath}`.trim() : cliTitle || command.name;
|
|
121
|
+
const usage = (0, import_opencli.generateUsage)(spec, command, displayPath);
|
|
122
|
+
const description = (0, import_opencli.generateDescription)(command);
|
|
123
|
+
const subcommands = (0, import_opencli.generateCommands)(command);
|
|
124
|
+
const argsText = (0, import_opencli.generateArguments)(command, "code");
|
|
125
|
+
const optsText = (0, import_opencli.generateOptions)(command, "code");
|
|
126
|
+
const replaceSimplePlaceholders = (value) => {
|
|
127
|
+
return value.replace(/\{opencli\.current\.usage\}/g, usage).replace(/\{opencli\.current\.description\}/g, description).replace(/\{opencli\.current\.commands\}/g, subcommands);
|
|
128
|
+
};
|
|
129
|
+
(0, import_unist_util_visit.visit)(tree, "text", (node) => {
|
|
130
|
+
if (typeof node.value === "string") {
|
|
131
|
+
node.value = replaceSimplePlaceholders(node.value);
|
|
132
|
+
if (indentStyle === "code") {
|
|
133
|
+
node.value = node.value.replace(/\{opencli\.current\.arguments\}/g, argsText).replace(/\{opencli\.current\.options\}/g, optsText);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
(0, import_unist_util_visit.visit)(tree, "inlineCode", (node) => {
|
|
138
|
+
if (typeof node.value === "string") {
|
|
139
|
+
node.value = replaceSimplePlaceholders(node.value);
|
|
140
|
+
if (indentStyle === "code") {
|
|
141
|
+
node.value = node.value.replace(/\{opencli\.current\.arguments\}/g, argsText).replace(/\{opencli\.current\.options\}/g, optsText);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
(0, import_unist_util_visit.visit)(tree, "code", (node) => {
|
|
146
|
+
if (typeof node.value === "string") {
|
|
147
|
+
node.value = replaceSimplePlaceholders(node.value).replace(/\{opencli\.current\.arguments\}/g, argsText).replace(/\{opencli\.current\.options\}/g, optsText);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
const mdxExprValue = (expr) => {
|
|
151
|
+
switch (expr) {
|
|
152
|
+
case "opencli.current.usage":
|
|
153
|
+
return usage;
|
|
154
|
+
case "opencli.current.description":
|
|
155
|
+
return description;
|
|
156
|
+
case "opencli.current.commands":
|
|
157
|
+
return subcommands;
|
|
158
|
+
case "opencli.current.arguments":
|
|
159
|
+
return argsText;
|
|
160
|
+
case "opencli.current.options":
|
|
161
|
+
return optsText;
|
|
162
|
+
default:
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
(0, import_unist_util_visit.visit)(tree, ["mdxFlowExpression", "mdxTextExpression"], (node, index, parent) => {
|
|
167
|
+
if (!parent || index === void 0 || typeof node.value !== "string") return;
|
|
168
|
+
const expr = node.value.trim();
|
|
169
|
+
if (!expr.startsWith("opencli.current.")) return;
|
|
170
|
+
if (indentStyle === "list" && (expr === "opencli.current.arguments" || expr === "opencli.current.options")) {
|
|
171
|
+
const listNode = expr === "opencli.current.arguments" ? createArgumentsListNode(command) : createOptionsListNode(command);
|
|
172
|
+
parent.children[index] = listNode || { type: "text", value: "" };
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const value = mdxExprValue(expr);
|
|
176
|
+
if (value === null) return;
|
|
177
|
+
if (node.type === "mdxFlowExpression") {
|
|
178
|
+
parent.children[index] = expr === "opencli.current.description" ? { type: "paragraph", children: [{ type: "text", value }] } : { type: "code", value };
|
|
179
|
+
} else {
|
|
180
|
+
parent.children[index] = { type: "text", value };
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
if (indentStyle === "list") {
|
|
184
|
+
(0, import_unist_util_visit.visit)(tree, "paragraph", (node, index, parent) => {
|
|
185
|
+
var _a2;
|
|
186
|
+
if (!parent || index === void 0) return;
|
|
187
|
+
const textChild = (_a2 = node.children) == null ? void 0 : _a2.find(
|
|
188
|
+
(c) => {
|
|
189
|
+
var _a3;
|
|
190
|
+
return c.type === "text" && ((_a3 = c.value) == null ? void 0 : _a3.includes("{opencli.current.arguments}"));
|
|
191
|
+
}
|
|
192
|
+
);
|
|
193
|
+
if (textChild) {
|
|
194
|
+
const listNode = createArgumentsListNode(command);
|
|
195
|
+
if (listNode) {
|
|
196
|
+
parent.children[index] = listNode;
|
|
197
|
+
} else {
|
|
198
|
+
textChild.value = textChild.value.replace("{opencli.current.arguments}", "");
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
(0, import_unist_util_visit.visit)(tree, "paragraph", (node, index, parent) => {
|
|
203
|
+
var _a2;
|
|
204
|
+
if (!parent || index === void 0) return;
|
|
205
|
+
const textChild = (_a2 = node.children) == null ? void 0 : _a2.find(
|
|
206
|
+
(c) => {
|
|
207
|
+
var _a3;
|
|
208
|
+
return c.type === "text" && ((_a3 = c.value) == null ? void 0 : _a3.includes("{opencli.current.options}"));
|
|
209
|
+
}
|
|
210
|
+
);
|
|
211
|
+
if (textChild) {
|
|
212
|
+
const listNode = createOptionsListNode(command);
|
|
213
|
+
if (listNode) {
|
|
214
|
+
parent.children[index] = listNode;
|
|
215
|
+
} else {
|
|
216
|
+
textChild.value = textChild.value.replace("{opencli.current.options}", "");
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
function createArgumentsListNode(command) {
|
|
224
|
+
if (!command.arguments || command.arguments.length === 0) {
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
const visibleArgs = command.arguments.filter((arg) => !arg.hidden);
|
|
228
|
+
if (visibleArgs.length === 0) {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
type: "list",
|
|
233
|
+
ordered: false,
|
|
234
|
+
spread: false,
|
|
235
|
+
children: visibleArgs.map((arg) => ({
|
|
236
|
+
type: "listItem",
|
|
237
|
+
spread: false,
|
|
238
|
+
children: [{
|
|
239
|
+
type: "paragraph",
|
|
240
|
+
children: [
|
|
241
|
+
{ type: "inlineCode", value: arg.name.toLowerCase() },
|
|
242
|
+
{ type: "text", value: arg.description ? ` ${arg.description}` : "" }
|
|
243
|
+
]
|
|
244
|
+
}]
|
|
245
|
+
}))
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
function createOptionsListNode(command) {
|
|
249
|
+
if (!command.options || command.options.length === 0) {
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
const visibleOptions = command.options.filter((opt) => !opt.hidden);
|
|
253
|
+
if (visibleOptions.length === 0) {
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
type: "list",
|
|
258
|
+
ordered: false,
|
|
259
|
+
spread: false,
|
|
260
|
+
children: visibleOptions.map((option) => {
|
|
261
|
+
var _a;
|
|
262
|
+
const aliases = ((_a = option.aliases) == null ? void 0 : _a.filter((a) => a.length === 1)) || [];
|
|
263
|
+
const short = aliases.length > 0 ? `-${aliases[0]}` : "";
|
|
264
|
+
const long = `--${option.name}`;
|
|
265
|
+
const children = [];
|
|
266
|
+
if (short) {
|
|
267
|
+
children.push({ type: "inlineCode", value: short });
|
|
268
|
+
children.push({ type: "text", value: ", " });
|
|
269
|
+
}
|
|
270
|
+
children.push({ type: "inlineCode", value: long });
|
|
271
|
+
if (option.description) {
|
|
272
|
+
children.push({ type: "text", value: ` ${option.description}` });
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
type: "listItem",
|
|
276
|
+
spread: false,
|
|
277
|
+
children: [{
|
|
278
|
+
type: "paragraph",
|
|
279
|
+
children
|
|
280
|
+
}]
|
|
281
|
+
};
|
|
282
|
+
})
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
286
|
+
0 && (module.exports = {
|
|
287
|
+
remarkOpencliDocs,
|
|
288
|
+
...require("@xyd-js/opencli")
|
|
289
|
+
});
|
|
290
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../index.ts","../src/remark-opencli.ts"],"sourcesContent":["// The OpenCLI model + helpers now live in @xyd-js/opencli; re-export them so\n// existing consumers of @xyd-js/opencli-remark keep working.\nexport * from '@xyd-js/opencli';\nexport { remarkOpencliDocs, type OpencliDocsOptions } from './src/remark-opencli';\n","import { visit } from 'unist-util-visit';\nimport { VFile } from 'vfile';\nimport { Root } from 'mdast';\nimport { matter } from 'vfile-matter';\nimport { load } from 'js-yaml';\n\nimport {\n loadOpencliSpec,\n findCommand,\n generateUsage,\n generateDescription,\n generateArguments,\n generateOptions,\n generateCommands,\n type Command,\n} from '@xyd-js/opencli';\n\nexport interface OpencliDocsOptions {\n [cliKey: string]: {\n source: string; // File path or URL\n };\n}\n\n/**\n * Remark plugin for generating OpenCLI documentation from placeholders\n *\n * @example\n * ```md\n * ---\n * xyd.opencli.spice: \"install\"\n * ---\n *\n * ### Usage\n * {opencli.current.usage}\n *\n * ### Flags\n * {opencli.current.flags}\n * ```\n *\n * @example\n * ```ts\n * remarkOpencliDocs({\n * spice: { source: './spice-spec.json' },\n * npm: { source: './npm-spec.json' }\n * })\n * ```\n */\nexport function remarkOpencliDocs(options: OpencliDocsOptions) {\n return async function transformer(tree: Root, file?: VFile) {\n // Return early if no file is provided\n if (!file) {\n return;\n }\n\n // Ensure file.data exists\n if (!file.data) {\n file.data = {};\n }\n\n // Quick check: look for xyd.opencli.* pattern in YAML nodes before parsing\n let hasOpencliKey = false;\n let yamlContent: string | null = null;\n\n visit(tree, 'yaml', (node: any) => {\n if (node.value && !yamlContent) {\n const content = String(node.value);\n yamlContent = content;\n // Quick string check for xyd.opencli. pattern\n if (content.includes('xyd.opencli.')) {\n hasOpencliKey = true;\n }\n }\n });\n\n // If no YAML node found, check file.value directly\n if (!yamlContent && file.value) {\n const fileValue = typeof file.value === 'string' ? file.value : new TextDecoder().decode(file.value);\n const frontmatterMatch = fileValue.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (frontmatterMatch && frontmatterMatch[1].includes('xyd.opencli.')) {\n hasOpencliKey = true;\n yamlContent = frontmatterMatch[1];\n }\n }\n\n // If no xyd.opencli.* key found anywhere, return early without any processing\n if (!hasOpencliKey) {\n return;\n }\n\n // Now parse frontmatter since we know there's a potential match\n let frontmatter = file.data.matter as Record<string, any> | undefined;\n\n // If not parsed, parse from YAML content we found\n if (!frontmatter && yamlContent) {\n try {\n frontmatter = load(yamlContent) as Record<string, any>;\n file.data.matter = frontmatter;\n } catch (error) {\n // Failed to parse YAML, try parsing from file.value\n if (file.value) {\n matter(file as any);\n frontmatter = file.data.matter as Record<string, any> | undefined;\n }\n }\n }\n\n // Fallback: try to parse from file.value if YAML nodes weren't found\n if (!frontmatter && file.value) {\n matter(file as any);\n frontmatter = file.data.matter as Record<string, any> | undefined;\n }\n\n // Find xyd.opencli.{cliKey} pattern in frontmatter\n let cliKey: string | null = null;\n let opencliConfig: any = null;\n\n for (const key in frontmatter) {\n if (key.startsWith('xyd.opencli.')) {\n cliKey = key.substring('xyd.opencli.'.length);\n opencliConfig = frontmatter[key];\n break;\n }\n }\n\n // If no xyd.opencli.{cliKey} found, return early\n if (!cliKey || opencliConfig === undefined || opencliConfig === null) {\n return;\n }\n\n // Get the CLI config for this key\n const cliConfig = options[cliKey];\n if (!cliConfig || !cliConfig.source) {\n console.warn(`No configuration found for CLI key \"${cliKey}\"`);\n return;\n }\n\n // Parse xyd.opencli.{cliKey} - can be string or object\n let commandPath: string;\n let indentStyle: 'code' | 'list' = 'code'; // default\n\n if (typeof opencliConfig === 'string') {\n commandPath = opencliConfig;\n } else if (typeof opencliConfig === 'object' && opencliConfig !== null) {\n commandPath = opencliConfig.command || '';\n indentStyle = opencliConfig.indent === 'list' ? 'list' : 'code';\n } else {\n return;\n }\n\n const normalizedPath = commandPath?.trim() || '';\n\n // Load OpenCLI spec (resolve relative file paths from the markdown file's dir)\n const spec = await loadOpencliSpec(cliConfig.source, { cwd: file.dirname });\n if (!spec) {\n console.warn(`Failed to load OpenCLI spec from ${cliConfig.source}`);\n return;\n }\n\n // Find the command in the spec\n const command = findCommand(spec, normalizedPath);\n if (!command) {\n console.warn(`Command \"${normalizedPath || '(root)'}\" not found in OpenCLI spec`);\n return;\n }\n\n // Build display path: CLI title + command path (or just CLI title for root)\n const cliTitle = spec.info?.title || '';\n const displayPath = normalizedPath\n ? `${cliTitle} ${normalizedPath}`.trim()\n : cliTitle || command.name;\n\n // Generate documentation content\n const usage = generateUsage(spec, command, displayPath);\n const description = generateDescription(command);\n // const flags = generateFlags(command);\n const subcommands = generateCommands(command);\n\n // For code format, generate string content\n const argsText = generateArguments(command, 'code');\n const optsText = generateOptions(command, 'code');\n\n // Helper function to replace simple placeholders (usage, description)\n const replaceSimplePlaceholders = (value: string) => {\n return value\n .replace(/\\{opencli\\.current\\.usage\\}/g, usage)\n .replace(/\\{opencli\\.current\\.description\\}/g, description)\n // .replace(/\\{opencli\\.current\\.flags\\}/g, flags)\n .replace(/\\{opencli\\.current\\.commands\\}/g, subcommands);\n };\n\n // Replace placeholders in text nodes\n visit(tree, 'text', (node: any) => {\n if (typeof node.value === 'string') {\n node.value = replaceSimplePlaceholders(node.value);\n // For code style, also replace arguments/options as text\n if (indentStyle === 'code') {\n node.value = node.value\n .replace(/\\{opencli\\.current\\.arguments\\}/g, argsText)\n .replace(/\\{opencli\\.current\\.options\\}/g, optsText);\n }\n }\n });\n\n // Replace placeholders in inline code (backticks)\n visit(tree, 'inlineCode', (node: any) => {\n if (typeof node.value === 'string') {\n node.value = replaceSimplePlaceholders(node.value);\n if (indentStyle === 'code') {\n node.value = node.value\n .replace(/\\{opencli\\.current\\.arguments\\}/g, argsText)\n .replace(/\\{opencli\\.current\\.options\\}/g, optsText);\n }\n }\n });\n\n // Replace placeholders in code blocks\n visit(tree, 'code', (node: any) => {\n if (typeof node.value === 'string') {\n node.value = replaceSimplePlaceholders(node.value)\n .replace(/\\{opencli\\.current\\.arguments\\}/g, argsText)\n .replace(/\\{opencli\\.current\\.options\\}/g, optsText);\n }\n });\n\n // In an MDX pipeline `{opencli.current.*}` is parsed as a JS expression node\n // (mdxFlowExpression / mdxTextExpression), not literal text — so the visitors\n // above never see it (and it would throw at render since `opencli` is undefined).\n // Resolve those expression nodes here.\n const mdxExprValue = (expr: string): string | null => {\n switch (expr) {\n case 'opencli.current.usage': return usage;\n case 'opencli.current.description': return description;\n case 'opencli.current.commands': return subcommands;\n case 'opencli.current.arguments': return argsText;\n case 'opencli.current.options': return optsText;\n default: return null;\n }\n };\n visit(tree, ['mdxFlowExpression', 'mdxTextExpression'], (node: any, index: number | undefined, parent: any) => {\n if (!parent || index === undefined || typeof node.value !== 'string') return;\n const expr = node.value.trim();\n if (!expr.startsWith('opencli.current.')) return;\n\n if (indentStyle === 'list' && (expr === 'opencli.current.arguments' || expr === 'opencli.current.options')) {\n const listNode = expr === 'opencli.current.arguments'\n ? createArgumentsListNode(command)\n : createOptionsListNode(command);\n parent.children[index] = listNode || { type: 'text', value: '' };\n return;\n }\n\n const value = mdxExprValue(expr);\n if (value === null) return;\n\n if (node.type === 'mdxFlowExpression') {\n parent.children[index] = expr === 'opencli.current.description'\n ? { type: 'paragraph', children: [{ type: 'text', value }] }\n : { type: 'code', value };\n } else {\n parent.children[index] = { type: 'text', value };\n }\n });\n\n // For list format, replace argument/option placeholders with mdast list nodes\n if (indentStyle === 'list') {\n // Replace {opencli.current.arguments} with list node\n visit(tree, 'paragraph', (node: any, index: number | undefined, parent: any) => {\n if (!parent || index === undefined) return;\n\n const textChild = node.children?.find((c: any) =>\n c.type === 'text' && c.value?.includes('{opencli.current.arguments}')\n );\n\n if (textChild) {\n const listNode = createArgumentsListNode(command);\n if (listNode) {\n parent.children[index] = listNode;\n } else {\n // No arguments, just remove the placeholder\n textChild.value = textChild.value.replace('{opencli.current.arguments}', '');\n }\n }\n });\n\n // Replace {opencli.current.options} with list node\n visit(tree, 'paragraph', (node: any, index: number | undefined, parent: any) => {\n if (!parent || index === undefined) return;\n\n const textChild = node.children?.find((c: any) =>\n c.type === 'text' && c.value?.includes('{opencli.current.options}')\n );\n\n if (textChild) {\n const listNode = createOptionsListNode(command);\n if (listNode) {\n parent.children[index] = listNode;\n } else {\n // No options, just remove the placeholder\n textChild.value = textChild.value.replace('{opencli.current.options}', '');\n }\n }\n });\n }\n };\n}\n\n/**\n * Create mdast list node for arguments (for list indent style)\n */\nfunction createArgumentsListNode(command: Command): any | null {\n if (!command.arguments || command.arguments.length === 0) {\n return null;\n }\n\n const visibleArgs = command.arguments.filter(arg => !arg.hidden);\n if (visibleArgs.length === 0) {\n return null;\n }\n\n return {\n type: 'list',\n ordered: false,\n spread: false,\n children: visibleArgs.map(arg => ({\n type: 'listItem',\n spread: false,\n children: [{\n type: 'paragraph',\n children: [\n { type: 'inlineCode', value: arg.name.toLowerCase() },\n { type: 'text', value: arg.description ? ` ${arg.description}` : '' }\n ]\n }]\n }))\n };\n}\n\n/**\n * Create mdast list node for options (for list indent style)\n */\nfunction createOptionsListNode(command: Command): any | null {\n if (!command.options || command.options.length === 0) {\n return null;\n }\n\n const visibleOptions = command.options.filter(opt => !opt.hidden);\n if (visibleOptions.length === 0) {\n return null;\n }\n\n return {\n type: 'list',\n ordered: false,\n spread: false,\n children: visibleOptions.map(option => {\n const aliases = option.aliases?.filter(a => a.length === 1) || [];\n const short = aliases.length > 0 ? `-${aliases[0]}` : '';\n const long = `--${option.name}`;\n\n const children: any[] = [];\n\n // Add short alias if exists\n if (short) {\n children.push({ type: 'inlineCode', value: short });\n children.push({ type: 'text', value: ', ' });\n }\n\n // Add long option\n children.push({ type: 'inlineCode', value: long });\n\n // Add description\n if (option.description) {\n children.push({ type: 'text', value: ` ${option.description}` });\n }\n\n return {\n type: 'listItem',\n spread: false,\n children: [{\n type: 'paragraph',\n children\n }]\n };\n })\n };\n}\n"],"mappings":"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","names":["_a"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export * from '@xyd-js/opencli';
|
|
2
|
+
import { VFile } from 'vfile';
|
|
3
|
+
import { Root } from 'mdast';
|
|
4
|
+
|
|
5
|
+
interface OpencliDocsOptions {
|
|
6
|
+
[cliKey: string]: {
|
|
7
|
+
source: string;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Remark plugin for generating OpenCLI documentation from placeholders
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```md
|
|
15
|
+
* ---
|
|
16
|
+
* xyd.opencli.spice: "install"
|
|
17
|
+
* ---
|
|
18
|
+
*
|
|
19
|
+
* ### Usage
|
|
20
|
+
* {opencli.current.usage}
|
|
21
|
+
*
|
|
22
|
+
* ### Flags
|
|
23
|
+
* {opencli.current.flags}
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* remarkOpencliDocs({
|
|
29
|
+
* spice: { source: './spice-spec.json' },
|
|
30
|
+
* npm: { source: './npm-spec.json' }
|
|
31
|
+
* })
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
declare function remarkOpencliDocs(options: OpencliDocsOptions): (tree: Root, file?: VFile) => Promise<void>;
|
|
35
|
+
|
|
36
|
+
export { type OpencliDocsOptions, remarkOpencliDocs };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export * from '@xyd-js/opencli';
|
|
2
|
+
import { VFile } from 'vfile';
|
|
3
|
+
import { Root } from 'mdast';
|
|
4
|
+
|
|
5
|
+
interface OpencliDocsOptions {
|
|
6
|
+
[cliKey: string]: {
|
|
7
|
+
source: string;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Remark plugin for generating OpenCLI documentation from placeholders
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```md
|
|
15
|
+
* ---
|
|
16
|
+
* xyd.opencli.spice: "install"
|
|
17
|
+
* ---
|
|
18
|
+
*
|
|
19
|
+
* ### Usage
|
|
20
|
+
* {opencli.current.usage}
|
|
21
|
+
*
|
|
22
|
+
* ### Flags
|
|
23
|
+
* {opencli.current.flags}
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* remarkOpencliDocs({
|
|
29
|
+
* spice: { source: './spice-spec.json' },
|
|
30
|
+
* npm: { source: './npm-spec.json' }
|
|
31
|
+
* })
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
declare function remarkOpencliDocs(options: OpencliDocsOptions): (tree: Root, file?: VFile) => Promise<void>;
|
|
35
|
+
|
|
36
|
+
export { type OpencliDocsOptions, remarkOpencliDocs };
|