@axerity/cli 0.1.0 → 0.1.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 +96 -0
- package/bin/axerity.js +21 -19
- package/package.json +1 -1
- package/vite.config.ts +2 -2
package/README.md
CHANGED
|
@@ -1 +1,97 @@
|
|
|
1
1
|
# Axerity
|
|
2
|
+
|
|
3
|
+
A documentation site generator built with SvelteKit. Write Markdown, configure
|
|
4
|
+
one JSON file, and ship a fast static site.
|
|
5
|
+
|
|
6
|
+
## Quick start
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
pnpm dlx @axerity/cli init mydocs
|
|
10
|
+
cd mydocs
|
|
11
|
+
pnpm dlx @axerity/cli dev
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
That scaffolds a content-only project and starts a live dev server at
|
|
15
|
+
`http://localhost:5173`.
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
mydocs/
|
|
19
|
+
axerity.json # all configuration
|
|
20
|
+
docs/ # your Markdown
|
|
21
|
+
meta.json # ordering and icons per folder
|
|
22
|
+
index.md
|
|
23
|
+
quickstart.md
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
Run it without installing:
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
pnpm dlx @axerity/cli <command>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Or add it to a project so the version is pinned and reproducible:
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
pnpm add -D @axerity/cli
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"scripts": {
|
|
43
|
+
"dev": "axerity dev",
|
|
44
|
+
"build": "axerity build",
|
|
45
|
+
"preview": "axerity preview"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Commands
|
|
51
|
+
|
|
52
|
+
| Command | What it does |
|
|
53
|
+
| ----------------- | ------------------------------------- |
|
|
54
|
+
| `axerity init` | Scaffold a new docs site |
|
|
55
|
+
| `axerity dev` | Start the dev server with live reload |
|
|
56
|
+
| `axerity build` | Build a static site into `./build` |
|
|
57
|
+
| `axerity preview` | Serve the production build locally |
|
|
58
|
+
|
|
59
|
+
The build output is a plain static site you can host anywhere: Vercel, Netlify,
|
|
60
|
+
Cloudflare, GitHub Pages, nginx, or any static host.
|
|
61
|
+
|
|
62
|
+
## Features
|
|
63
|
+
|
|
64
|
+
- Markdown with a built in component kit: callouts, cards, tabs, steps,
|
|
65
|
+
accordions, code groups, badges, trees, frames, and more
|
|
66
|
+
- API references generated from an OpenAPI spec, plus webhook and WebSocket
|
|
67
|
+
components
|
|
68
|
+
- Versioned content with a switcher that follows the reader across versions
|
|
69
|
+
- Themes, custom brand colors, and full white labelling from `axerity.json`
|
|
70
|
+
- Build time search, an RSS feed, sitemap, `llms.txt`, and dynamic OpenGraph
|
|
71
|
+
images
|
|
72
|
+
- Mermaid diagrams, Twoslash type hovers, and syntax highlighting
|
|
73
|
+
|
|
74
|
+
## Configuration
|
|
75
|
+
|
|
76
|
+
Everything global lives in `axerity.json`. A few of the common keys:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"$schema": "https://axerity.com/axerity.schema.json",
|
|
81
|
+
"name": "My Docs",
|
|
82
|
+
"theme": "neutral",
|
|
83
|
+
"openapi": "./openapi.json",
|
|
84
|
+
"topNav": [{ "title": "Docs", "href": "/" }]
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Point `$schema` at the bundled JSON schema for autocomplete and validation in
|
|
89
|
+
your editor.
|
|
90
|
+
|
|
91
|
+
## Requirements
|
|
92
|
+
|
|
93
|
+
Node.js 24 or newer.
|
|
94
|
+
|
|
95
|
+
## License
|
|
96
|
+
|
|
97
|
+
MIT
|
package/bin/axerity.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { spawn, spawnSync } from 'node:child_process';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
3
4
|
import { fileURLToPath } from 'node:url';
|
|
4
5
|
import {
|
|
5
6
|
cpSync,
|
|
@@ -20,9 +21,14 @@ const isEngineRepo = userRoot === engineRoot;
|
|
|
20
21
|
|
|
21
22
|
const symlinkType = process.platform === 'win32' ? 'junction' : 'dir';
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
const require = createRequire(import.meta.url);
|
|
25
|
+
function viteBin() {
|
|
26
|
+
const pkgPath = require.resolve('vite/package.json');
|
|
27
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
28
|
+
const rel = typeof pkg.bin === 'string' ? pkg.bin : pkg.bin.vite;
|
|
29
|
+
return resolve(dirname(pkgPath), rel);
|
|
30
|
+
}
|
|
31
|
+
|
|
26
32
|
const ENGINE_DOCS = join(engineRoot, 'src', 'content', 'docs');
|
|
27
33
|
const ENGINE_CONFIG = join(engineRoot, 'axerity.json');
|
|
28
34
|
const ENGINE_STATIC = join(engineRoot, 'static');
|
|
@@ -38,16 +44,12 @@ function findContentDir() {
|
|
|
38
44
|
return null;
|
|
39
45
|
}
|
|
40
46
|
|
|
41
|
-
/** Reset the engine's own demo site into the mount points (for `axerity` runs
|
|
42
|
-
* from inside the engine repo). `pnpm dev` does this via its pre-scripts. */
|
|
43
47
|
function prepareEngine() {
|
|
44
48
|
spawnSync(process.execPath, [join(engineRoot, 'scripts', 'prepare-engine.mjs')], {
|
|
45
49
|
stdio: 'inherit'
|
|
46
50
|
});
|
|
47
51
|
}
|
|
48
52
|
|
|
49
|
-
/** Copy local specs into a gitignored folder and rewrite the config to point at
|
|
50
|
-
* them, so the user's spec paths resolve without touching the engine tree. */
|
|
51
53
|
function mountSpecs(config) {
|
|
52
54
|
const rewrite = (source) => {
|
|
53
55
|
const spec = typeof source === 'string' ? source : source.spec;
|
|
@@ -66,19 +68,15 @@ function mountSpecs(config) {
|
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
function mount(contentDir) {
|
|
69
|
-
// Content -> the path the engine globs, as symlinks so generated pages (an API
|
|
70
|
-
// reference) can sit alongside without touching the user's repo.
|
|
71
71
|
rmSync(ENGINE_DOCS, { recursive: true, force: true });
|
|
72
72
|
mkdirSync(ENGINE_DOCS, { recursive: true });
|
|
73
73
|
for (const entry of readdirSync(contentDir)) {
|
|
74
74
|
symlinkSync(join(contentDir, entry), join(ENGINE_DOCS, entry), symlinkType);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
// Config (with local spec paths rewritten into the gitignored specs folder).
|
|
78
77
|
const config = JSON.parse(readFileSync(join(userRoot, 'axerity.json'), 'utf8'));
|
|
79
78
|
writeFileSync(ENGINE_CONFIG, JSON.stringify(mountSpecs(config), null, '\t'));
|
|
80
79
|
|
|
81
|
-
// Assets: engine defaults overlaid with the user's public/ folder.
|
|
82
80
|
rmSync(ASSETS_DIR, { recursive: true, force: true });
|
|
83
81
|
cpSync(ENGINE_STATIC, ASSETS_DIR, { recursive: true });
|
|
84
82
|
const userPublic = join(userRoot, 'public');
|
|
@@ -106,7 +104,7 @@ const banner = (sub) => process.stdout.write(`\n ${mark} ${bold('axerity')} ${d
|
|
|
106
104
|
const NOISE =
|
|
107
105
|
/^\s*(VITE v|➜|press h|ready in|Local:|Network:|\[vite\].*(optimiz|dependencies)|\[optimizer\]|Forced re-opt|watching for file changes|use --host)/i;
|
|
108
106
|
|
|
109
|
-
function streamServer(child
|
|
107
|
+
function streamServer(child) {
|
|
110
108
|
let shown = false;
|
|
111
109
|
let buffer = '';
|
|
112
110
|
const onData = (chunk) => {
|
|
@@ -130,7 +128,6 @@ function streamServer(child, sub) {
|
|
|
130
128
|
child.stderr.on('data', onData);
|
|
131
129
|
}
|
|
132
130
|
|
|
133
|
-
/** A build: silent spinner on success, full captured output only on failure. */
|
|
134
131
|
function streamBuild(child) {
|
|
135
132
|
const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
136
133
|
let i = 0;
|
|
@@ -152,8 +149,7 @@ function streamBuild(child) {
|
|
|
152
149
|
}
|
|
153
150
|
|
|
154
151
|
function runEngine(sub, extra, { mounted, onSuccess }) {
|
|
155
|
-
const
|
|
156
|
-
const child = spawn(process.execPath, [viteEntry, sub, ...extra], {
|
|
152
|
+
const child = spawn(process.execPath, [viteBin(), sub, ...extra], {
|
|
157
153
|
cwd: engineRoot,
|
|
158
154
|
stdio: ['inherit', 'pipe', 'pipe'],
|
|
159
155
|
env: {
|
|
@@ -165,7 +161,7 @@ function runEngine(sub, extra, { mounted, onSuccess }) {
|
|
|
165
161
|
});
|
|
166
162
|
|
|
167
163
|
banner(sub);
|
|
168
|
-
const build = sub === 'build' ? streamBuild(child) : (streamServer(child
|
|
164
|
+
const build = sub === 'build' ? streamBuild(child) : (streamServer(child), null);
|
|
169
165
|
|
|
170
166
|
let cleaned = false;
|
|
171
167
|
const cleanup = () => {
|
|
@@ -190,7 +186,6 @@ function runEngine(sub, extra, { mounted, onSuccess }) {
|
|
|
190
186
|
}
|
|
191
187
|
|
|
192
188
|
function run(sub, extra) {
|
|
193
|
-
// Inside the engine repo: serve its own demo site.
|
|
194
189
|
if (isEngineRepo) {
|
|
195
190
|
prepareEngine();
|
|
196
191
|
return runEngine(sub, extra, { mounted: false });
|
|
@@ -271,9 +266,11 @@ function init() {
|
|
|
271
266
|
console.log(' axerity dev');
|
|
272
267
|
}
|
|
273
268
|
|
|
269
|
+
const pkgVersion = () =>
|
|
270
|
+
JSON.parse(readFileSync(join(engineRoot, 'package.json'), 'utf8')).version;
|
|
271
|
+
|
|
274
272
|
function help() {
|
|
275
|
-
|
|
276
|
-
console.log(`Axerity ${version} — a documentation site generator\n`);
|
|
273
|
+
console.log(`Axerity ${pkgVersion()} — a documentation site generator\n`);
|
|
277
274
|
console.log('Usage: axerity <command>\n');
|
|
278
275
|
console.log('Commands:');
|
|
279
276
|
console.log(' init [dir] Scaffold a new docs site');
|
|
@@ -287,6 +284,11 @@ const command = process.argv[2];
|
|
|
287
284
|
const extra = process.argv.slice(3);
|
|
288
285
|
|
|
289
286
|
switch (command) {
|
|
287
|
+
case '--version':
|
|
288
|
+
case '-v':
|
|
289
|
+
case 'version':
|
|
290
|
+
console.log(pkgVersion());
|
|
291
|
+
break;
|
|
290
292
|
case 'init':
|
|
291
293
|
init();
|
|
292
294
|
break;
|
package/package.json
CHANGED
package/vite.config.ts
CHANGED
|
@@ -22,7 +22,7 @@ function openapi() {
|
|
|
22
22
|
}
|
|
23
23
|
await generateApiDocs(openapi, 'src/content/docs');
|
|
24
24
|
} catch {
|
|
25
|
-
|
|
25
|
+
return;
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
28
|
return {
|
|
@@ -42,5 +42,5 @@ function openapi() {
|
|
|
42
42
|
|
|
43
43
|
export default defineConfig({
|
|
44
44
|
plugins: [openapi(), tailwindcss(), sveltekit()],
|
|
45
|
-
server: allow ? { fs: {
|
|
45
|
+
server: allow ? { fs: { strict: false } } : undefined
|
|
46
46
|
});
|