@axerity/cli 0.1.1 → 0.1.3
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 +12 -18
- package/package.json +2 -1
- package/src/content/demo/configuration/cli.md +10 -8
- package/src/content/demo/configuration/deployment.md +3 -3
- package/src/content/demo/installation.md +31 -14
- package/src/lib/components/DynamicIcon.svelte +21 -6
- 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
|
@@ -29,9 +29,6 @@ function viteBin() {
|
|
|
29
29
|
return resolve(dirname(pkgPath), rel);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
// The engine runs in place, from its own install with its real node_modules. The
|
|
33
|
-
// user's project is mounted into a handful of gitignored paths for a single run,
|
|
34
|
-
// so nothing the engine tracks is ever touched — clean exit, Ctrl-C, or crash.
|
|
35
32
|
const ENGINE_DOCS = join(engineRoot, 'src', 'content', 'docs');
|
|
36
33
|
const ENGINE_CONFIG = join(engineRoot, 'axerity.json');
|
|
37
34
|
const ENGINE_STATIC = join(engineRoot, 'static');
|
|
@@ -47,16 +44,12 @@ function findContentDir() {
|
|
|
47
44
|
return null;
|
|
48
45
|
}
|
|
49
46
|
|
|
50
|
-
/** Reset the engine's own demo site into the mount points (for `axerity` runs
|
|
51
|
-
* from inside the engine repo). `pnpm dev` does this via its pre-scripts. */
|
|
52
47
|
function prepareEngine() {
|
|
53
48
|
spawnSync(process.execPath, [join(engineRoot, 'scripts', 'prepare-engine.mjs')], {
|
|
54
49
|
stdio: 'inherit'
|
|
55
50
|
});
|
|
56
51
|
}
|
|
57
52
|
|
|
58
|
-
/** Copy local specs into a gitignored folder and rewrite the config to point at
|
|
59
|
-
* them, so the user's spec paths resolve without touching the engine tree. */
|
|
60
53
|
function mountSpecs(config) {
|
|
61
54
|
const rewrite = (source) => {
|
|
62
55
|
const spec = typeof source === 'string' ? source : source.spec;
|
|
@@ -75,19 +68,15 @@ function mountSpecs(config) {
|
|
|
75
68
|
}
|
|
76
69
|
|
|
77
70
|
function mount(contentDir) {
|
|
78
|
-
// Content -> the path the engine globs, as symlinks so generated pages (an API
|
|
79
|
-
// reference) can sit alongside without touching the user's repo.
|
|
80
71
|
rmSync(ENGINE_DOCS, { recursive: true, force: true });
|
|
81
72
|
mkdirSync(ENGINE_DOCS, { recursive: true });
|
|
82
73
|
for (const entry of readdirSync(contentDir)) {
|
|
83
74
|
symlinkSync(join(contentDir, entry), join(ENGINE_DOCS, entry), symlinkType);
|
|
84
75
|
}
|
|
85
76
|
|
|
86
|
-
// Config (with local spec paths rewritten into the gitignored specs folder).
|
|
87
77
|
const config = JSON.parse(readFileSync(join(userRoot, 'axerity.json'), 'utf8'));
|
|
88
78
|
writeFileSync(ENGINE_CONFIG, JSON.stringify(mountSpecs(config), null, '\t'));
|
|
89
79
|
|
|
90
|
-
// Assets: engine defaults overlaid with the user's public/ folder.
|
|
91
80
|
rmSync(ASSETS_DIR, { recursive: true, force: true });
|
|
92
81
|
cpSync(ENGINE_STATIC, ASSETS_DIR, { recursive: true });
|
|
93
82
|
const userPublic = join(userRoot, 'public');
|
|
@@ -115,7 +104,7 @@ const banner = (sub) => process.stdout.write(`\n ${mark} ${bold('axerity')} ${d
|
|
|
115
104
|
const NOISE =
|
|
116
105
|
/^\s*(VITE v|➜|press h|ready in|Local:|Network:|\[vite\].*(optimiz|dependencies)|\[optimizer\]|Forced re-opt|watching for file changes|use --host)/i;
|
|
117
106
|
|
|
118
|
-
function streamServer(child
|
|
107
|
+
function streamServer(child) {
|
|
119
108
|
let shown = false;
|
|
120
109
|
let buffer = '';
|
|
121
110
|
const onData = (chunk) => {
|
|
@@ -139,7 +128,6 @@ function streamServer(child, sub) {
|
|
|
139
128
|
child.stderr.on('data', onData);
|
|
140
129
|
}
|
|
141
130
|
|
|
142
|
-
/** A build: silent spinner on success, full captured output only on failure. */
|
|
143
131
|
function streamBuild(child) {
|
|
144
132
|
const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
145
133
|
let i = 0;
|
|
@@ -173,7 +161,7 @@ function runEngine(sub, extra, { mounted, onSuccess }) {
|
|
|
173
161
|
});
|
|
174
162
|
|
|
175
163
|
banner(sub);
|
|
176
|
-
const build = sub === 'build' ? streamBuild(child) : (streamServer(child
|
|
164
|
+
const build = sub === 'build' ? streamBuild(child) : (streamServer(child), null);
|
|
177
165
|
|
|
178
166
|
let cleaned = false;
|
|
179
167
|
const cleanup = () => {
|
|
@@ -198,7 +186,6 @@ function runEngine(sub, extra, { mounted, onSuccess }) {
|
|
|
198
186
|
}
|
|
199
187
|
|
|
200
188
|
function run(sub, extra) {
|
|
201
|
-
// Inside the engine repo: serve its own demo site.
|
|
202
189
|
if (isEngineRepo) {
|
|
203
190
|
prepareEngine();
|
|
204
191
|
return runEngine(sub, extra, { mounted: false });
|
|
@@ -246,7 +233,7 @@ function init() {
|
|
|
246
233
|
const files = {
|
|
247
234
|
'axerity.json': `${JSON.stringify(
|
|
248
235
|
{
|
|
249
|
-
$schema: 'https://
|
|
236
|
+
$schema: 'https://unpkg.com/@axerity/cli/axerity.schema.json',
|
|
250
237
|
name: 'My Docs',
|
|
251
238
|
description: 'Documentation built with Axerity.',
|
|
252
239
|
theme: 'neutral',
|
|
@@ -279,9 +266,11 @@ function init() {
|
|
|
279
266
|
console.log(' axerity dev');
|
|
280
267
|
}
|
|
281
268
|
|
|
269
|
+
const pkgVersion = () =>
|
|
270
|
+
JSON.parse(readFileSync(join(engineRoot, 'package.json'), 'utf8')).version;
|
|
271
|
+
|
|
282
272
|
function help() {
|
|
283
|
-
|
|
284
|
-
console.log(`Axerity ${version} — a documentation site generator\n`);
|
|
273
|
+
console.log(`Axerity ${pkgVersion()} — a documentation site generator\n`);
|
|
285
274
|
console.log('Usage: axerity <command>\n');
|
|
286
275
|
console.log('Commands:');
|
|
287
276
|
console.log(' init [dir] Scaffold a new docs site');
|
|
@@ -295,6 +284,11 @@ const command = process.argv[2];
|
|
|
295
284
|
const extra = process.argv.slice(3);
|
|
296
285
|
|
|
297
286
|
switch (command) {
|
|
287
|
+
case '--version':
|
|
288
|
+
case '-v':
|
|
289
|
+
case 'version':
|
|
290
|
+
console.log(pkgVersion());
|
|
291
|
+
break;
|
|
298
292
|
case 'init':
|
|
299
293
|
init();
|
|
300
294
|
break;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axerity/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "A documentation site generator built with Svelte.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"@tailwindcss/forms": "^0.5.11",
|
|
60
60
|
"@tailwindcss/typography": "^0.5.19",
|
|
61
61
|
"@tailwindcss/vite": "^4.3.0",
|
|
62
|
+
"lucide": "^1.17.0",
|
|
62
63
|
"mdsvex": "^0.12.7",
|
|
63
64
|
"mermaid": "^11.15.0",
|
|
64
65
|
"rehype-slug": "^6.0.0",
|
|
@@ -18,8 +18,8 @@ axerity build # build the static site
|
|
|
18
18
|
axerity preview # preview the production build
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
Run them with `
|
|
22
|
-
|
|
21
|
+
Run them with `pnpm dlx @axerity/cli <command>` (or `npx @axerity/cli <command>`),
|
|
22
|
+
or add `@axerity/cli` as a dev dependency and call `axerity` through your scripts.
|
|
23
23
|
|
|
24
24
|
## init
|
|
25
25
|
|
|
@@ -35,12 +35,14 @@ example `axerity dev --port 4000`.
|
|
|
35
35
|
|
|
36
36
|
## build
|
|
37
37
|
|
|
38
|
-
`axerity build` produces a static site
|
|
39
|
-
the search index, `llms.txt`, sitemap, RSS feed, and OpenGraph images
|
|
40
|
-
written out, ready to host anywhere.
|
|
38
|
+
`axerity build` produces a static site in `build/`. Every page is prerendered to
|
|
39
|
+
HTML, and the search index, `llms.txt`, sitemap, RSS feed, and OpenGraph images
|
|
40
|
+
are all written out, ready to host anywhere.
|
|
41
41
|
|
|
42
42
|
## How it works
|
|
43
43
|
|
|
44
|
-
The
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
The engine runs from its own install, not from your repo. When you run a command,
|
|
45
|
+
Axerity reads your `docs/` and `axerity.json` and renders against them, then
|
|
46
|
+
writes the result to `build/` in your project. Your content is the source of
|
|
47
|
+
truth and nothing else in your folder is touched, so there is no workspace to
|
|
48
|
+
gitignore beyond `build/`.
|
|
@@ -40,7 +40,7 @@ Settings and set the Framework Preset to **Other**.
|
|
|
40
40
|
|
|
41
41
|
In the Pages project settings:
|
|
42
42
|
|
|
43
|
-
- **Build command:** `npx axerity build`
|
|
43
|
+
- **Build command:** `npx @axerity/cli build`
|
|
44
44
|
- **Build output directory:** `build`
|
|
45
45
|
- **Framework preset:** None
|
|
46
46
|
|
|
@@ -50,7 +50,7 @@ Cloudflare serves clean URLs automatically.
|
|
|
50
50
|
|
|
51
51
|
```toml title="netlify.toml"
|
|
52
52
|
[build]
|
|
53
|
-
command = "npx axerity build"
|
|
53
|
+
command = "npx @axerity/cli build"
|
|
54
54
|
publish = "build"
|
|
55
55
|
```
|
|
56
56
|
|
|
@@ -59,7 +59,7 @@ Netlify serves clean URLs (pretty URLs) by default.
|
|
|
59
59
|
## GitHub Pages
|
|
60
60
|
|
|
61
61
|
Build, then publish the `build/` folder (for example with a GitHub Action that
|
|
62
|
-
runs `npx axerity build` and uploads `build/` as the Pages artifact).
|
|
62
|
+
runs `npx @axerity/cli build` and uploads `build/` as the Pages artifact).
|
|
63
63
|
|
|
64
64
|
Project sites are served from `https://<user>.github.io/<repo>/`, a sub-path, so
|
|
65
65
|
set the base in `axerity.json`:
|
|
@@ -6,35 +6,52 @@ icon: download
|
|
|
6
6
|
|
|
7
7
|
# Installation
|
|
8
8
|
|
|
9
|
-
Axerity is a CLI. You do not clone or fork anything.
|
|
10
|
-
|
|
9
|
+
Axerity is a CLI. You do not clone or fork anything. Run it, scaffold a site, and
|
|
10
|
+
start writing Markdown.
|
|
11
11
|
|
|
12
12
|
## Requirements
|
|
13
13
|
|
|
14
|
-
- Node.js
|
|
14
|
+
- Node.js 24 or newer
|
|
15
15
|
|
|
16
16
|
## Create a site
|
|
17
17
|
|
|
18
18
|
Scaffold a new site with `init`, then start the dev server:
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
|
|
21
|
+
pnpm dlx @axerity/cli init my-docs
|
|
22
22
|
cd my-docs
|
|
23
|
-
|
|
23
|
+
pnpm dlx @axerity/cli dev
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
Your site is running at `http://localhost:5173`.
|
|
27
|
-
|
|
26
|
+
Your site is running at `http://localhost:5173`. `pnpm dlx` runs the CLI without
|
|
27
|
+
installing it. `npx @axerity/cli <command>` works the same way.
|
|
28
|
+
|
|
29
|
+
## Install it
|
|
30
|
+
|
|
31
|
+
For a project you build often, add it as a dev dependency so the version is
|
|
32
|
+
pinned:
|
|
28
33
|
|
|
29
34
|
```bash
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
pnpm add -D @axerity/cli
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Then wire up scripts in your `package.json`:
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"scripts": {
|
|
43
|
+
"dev": "axerity dev",
|
|
44
|
+
"build": "axerity build",
|
|
45
|
+
"preview": "axerity preview"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
32
48
|
```
|
|
33
49
|
|
|
50
|
+
Now `pnpm dev` and `pnpm build` just work, no global install or PATH setup.
|
|
51
|
+
|
|
34
52
|
## Project layout
|
|
35
53
|
|
|
36
|
-
A site is
|
|
37
|
-
package:
|
|
54
|
+
A site is your content and one config file:
|
|
38
55
|
|
|
39
56
|
```
|
|
40
57
|
my-docs/
|
|
@@ -44,6 +61,6 @@ my-docs/
|
|
|
44
61
|
```
|
|
45
62
|
|
|
46
63
|
Write Markdown in `docs/`, order pages with `meta.json`, and configure the site
|
|
47
|
-
in [`axerity.json`](/configuration). The
|
|
48
|
-
|
|
49
|
-
|
|
64
|
+
in [`axerity.json`](/configuration). The engine runs from its own install, so the
|
|
65
|
+
only thing Axerity ever creates in your project is the `build/` folder. The
|
|
66
|
+
scaffold adds it to your `.gitignore` for you.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
|
-
import
|
|
3
|
-
import * as icons from '@lucide/svelte';
|
|
2
|
+
import { icons } from 'lucide';
|
|
4
3
|
|
|
5
|
-
|
|
4
|
+
type IconNode = [string, Record<string, string | number>][];
|
|
5
|
+
const registry = icons as unknown as Record<string, IconNode>;
|
|
6
6
|
|
|
7
7
|
const pascal = (name: string) =>
|
|
8
8
|
name
|
|
@@ -18,9 +18,24 @@
|
|
|
18
18
|
class: className = ''
|
|
19
19
|
}: { name?: string; size?: number; class?: string } = $props();
|
|
20
20
|
|
|
21
|
-
const
|
|
21
|
+
const node = $derived(name ? registry[pascal(name)] : undefined);
|
|
22
22
|
</script>
|
|
23
23
|
|
|
24
|
-
{#if
|
|
25
|
-
<
|
|
24
|
+
{#if node}
|
|
25
|
+
<svg
|
|
26
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
27
|
+
width={size}
|
|
28
|
+
height={size}
|
|
29
|
+
viewBox="0 0 24 24"
|
|
30
|
+
fill="none"
|
|
31
|
+
stroke="currentColor"
|
|
32
|
+
stroke-width="2"
|
|
33
|
+
stroke-linecap="round"
|
|
34
|
+
stroke-linejoin="round"
|
|
35
|
+
class={`lucide ${className}`}
|
|
36
|
+
>
|
|
37
|
+
{#each node as [tag, attrs], i (i)}
|
|
38
|
+
<svelte:element this={tag} {...attrs} />
|
|
39
|
+
{/each}
|
|
40
|
+
</svg>
|
|
26
41
|
{/if}
|
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
|
});
|