@axerity/cli 0.1.2 → 0.1.4
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/bin/axerity.js +29 -5
- 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 +25 -4
package/bin/axerity.js
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
readdirSync,
|
|
11
11
|
rmSync,
|
|
12
12
|
symlinkSync,
|
|
13
|
+
watch,
|
|
13
14
|
writeFileSync
|
|
14
15
|
} from 'node:fs';
|
|
15
16
|
import { basename, dirname, join, relative, resolve } from 'node:path';
|
|
@@ -67,6 +68,11 @@ function mountSpecs(config) {
|
|
|
67
68
|
return { ...config, openapi };
|
|
68
69
|
}
|
|
69
70
|
|
|
71
|
+
function writeConfig() {
|
|
72
|
+
const config = JSON.parse(readFileSync(join(userRoot, 'axerity.json'), 'utf8'));
|
|
73
|
+
writeFileSync(ENGINE_CONFIG, JSON.stringify(mountSpecs(config), null, '\t'));
|
|
74
|
+
}
|
|
75
|
+
|
|
70
76
|
function mount(contentDir) {
|
|
71
77
|
rmSync(ENGINE_DOCS, { recursive: true, force: true });
|
|
72
78
|
mkdirSync(ENGINE_DOCS, { recursive: true });
|
|
@@ -74,8 +80,7 @@ function mount(contentDir) {
|
|
|
74
80
|
symlinkSync(join(contentDir, entry), join(ENGINE_DOCS, entry), symlinkType);
|
|
75
81
|
}
|
|
76
82
|
|
|
77
|
-
|
|
78
|
-
writeFileSync(ENGINE_CONFIG, JSON.stringify(mountSpecs(config), null, '\t'));
|
|
83
|
+
writeConfig();
|
|
79
84
|
|
|
80
85
|
rmSync(ASSETS_DIR, { recursive: true, force: true });
|
|
81
86
|
cpSync(ENGINE_STATIC, ASSETS_DIR, { recursive: true });
|
|
@@ -102,7 +107,9 @@ const strip = (s) => s.replace(/\x1b\[[0-9;]*m/g, '');
|
|
|
102
107
|
const banner = (sub) => process.stdout.write(`\n ${mark} ${bold('axerity')} ${dim(sub)}\n\n`);
|
|
103
108
|
|
|
104
109
|
const NOISE =
|
|
105
|
-
/^\s*(VITE v|➜|press h|ready in|Local:|Network
|
|
110
|
+
/^\s*(VITE v|➜|press h|ready in|Local:|Network:|use --host|watching for file changes)/i;
|
|
111
|
+
const VITE_CHATTER =
|
|
112
|
+
/\[optimizer\]|\[vite\].*(re-?optimiz|optimized dependencies|new dependencies|page reload|hmr update|dependencies because)/i;
|
|
106
113
|
|
|
107
114
|
function streamServer(child) {
|
|
108
115
|
let shown = false;
|
|
@@ -120,7 +127,7 @@ function streamServer(child) {
|
|
|
120
127
|
process.stdout.write(` ${dim('Ctrl+C to stop')}\n\n`);
|
|
121
128
|
continue;
|
|
122
129
|
}
|
|
123
|
-
if (!clean.trim() || NOISE.test(clean.trim())) continue;
|
|
130
|
+
if (!clean.trim() || NOISE.test(clean.trim()) || VITE_CHATTER.test(clean)) continue;
|
|
124
131
|
process.stdout.write(` ${line}\n`);
|
|
125
132
|
}
|
|
126
133
|
};
|
|
@@ -163,10 +170,27 @@ function runEngine(sub, extra, { mounted, onSuccess }) {
|
|
|
163
170
|
banner(sub);
|
|
164
171
|
const build = sub === 'build' ? streamBuild(child) : (streamServer(child), null);
|
|
165
172
|
|
|
173
|
+
let configWatcher = null;
|
|
174
|
+
if (mounted && sub === 'dev') {
|
|
175
|
+
let timer = null;
|
|
176
|
+
configWatcher = watch(userRoot, (_event, filename) => {
|
|
177
|
+
if (filename !== 'axerity.json') return;
|
|
178
|
+
clearTimeout(timer);
|
|
179
|
+
timer = setTimeout(() => {
|
|
180
|
+
try {
|
|
181
|
+
writeConfig();
|
|
182
|
+
} catch {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
}, 80);
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
166
189
|
let cleaned = false;
|
|
167
190
|
const cleanup = () => {
|
|
168
191
|
if (cleaned || !mounted) return;
|
|
169
192
|
cleaned = true;
|
|
193
|
+
configWatcher?.close();
|
|
170
194
|
tidy();
|
|
171
195
|
};
|
|
172
196
|
|
|
@@ -233,7 +257,7 @@ function init() {
|
|
|
233
257
|
const files = {
|
|
234
258
|
'axerity.json': `${JSON.stringify(
|
|
235
259
|
{
|
|
236
|
-
$schema: 'https://
|
|
260
|
+
$schema: 'https://unpkg.com/@axerity/cli/axerity.schema.json',
|
|
237
261
|
name: 'My Docs',
|
|
238
262
|
description: 'Documentation built with Axerity.',
|
|
239
263
|
theme: 'neutral',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axerity/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
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
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs';
|
|
1
|
+
import { existsSync, readFileSync, watch } from 'node:fs';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
3
|
import tailwindcss from '@tailwindcss/vite';
|
|
4
4
|
import { sveltekit } from '@sveltejs/kit/vite';
|
|
5
5
|
import { defineConfig } from 'vite';
|
|
6
6
|
import { generateApiDocs } from './src/lib/openapi/generate';
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const mounted = !!process.env.AXERITY_FS_ALLOW;
|
|
9
9
|
|
|
10
10
|
function openapi() {
|
|
11
11
|
const localSpecs: string[] = [];
|
|
@@ -40,7 +40,28 @@ function openapi() {
|
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
function configReload() {
|
|
44
|
+
const file = resolve('axerity.json');
|
|
45
|
+
let watcher: ReturnType<typeof watch> | null = null;
|
|
46
|
+
return {
|
|
47
|
+
name: 'axerity:config-reload',
|
|
48
|
+
configureServer(server: import('vite').ViteDevServer) {
|
|
49
|
+
if (!existsSync(file)) return;
|
|
50
|
+
let timer: ReturnType<typeof setTimeout> | null = null;
|
|
51
|
+
watcher = watch(file, () => {
|
|
52
|
+
if (timer) clearTimeout(timer);
|
|
53
|
+
timer = setTimeout(() => server.watcher.emit('change', file), 50);
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
closeBundle() {
|
|
57
|
+
watcher?.close();
|
|
58
|
+
watcher = null;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
43
63
|
export default defineConfig({
|
|
44
|
-
plugins: [openapi(), tailwindcss(), sveltekit()],
|
|
45
|
-
server:
|
|
64
|
+
plugins: [openapi(), ...(mounted ? [configReload()] : []), tailwindcss(), sveltekit()],
|
|
65
|
+
server: mounted ? { fs: { strict: false } } : undefined,
|
|
66
|
+
optimizeDeps: mounted ? { noDiscovery: true, include: ['@orama/orama', 'mermaid'] } : undefined
|
|
46
67
|
});
|