@life-and-dev/mdsite 0.0.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 +228 -0
- package/bin/mdsite.js +3 -0
- package/dist/commands/commands.test.d.ts +1 -0
- package/dist/commands/commands.test.js +302 -0
- package/dist/commands/commands.test.js.map +1 -0
- package/dist/commands/generate.d.ts +1 -0
- package/dist/commands/generate.js +20 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +16 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/prepare.d.ts +1 -0
- package/dist/commands/prepare.js +111 -0
- package/dist/commands/prepare.js.map +1 -0
- package/dist/commands/prepare.test.d.ts +1 -0
- package/dist/commands/prepare.test.js +131 -0
- package/dist/commands/prepare.test.js.map +1 -0
- package/dist/commands/preview.d.ts +5 -0
- package/dist/commands/preview.js +62 -0
- package/dist/commands/preview.js.map +1 -0
- package/dist/commands/start.d.ts +5 -0
- package/dist/commands/start.js +50 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/stop.d.ts +1 -0
- package/dist/commands/stop.js +26 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/commands/workflows.test.d.ts +1 -0
- package/dist/commands/workflows.test.js +183 -0
- package/dist/commands/workflows.test.js.map +1 -0
- package/dist/config/default-mdsite-config.d.ts +2 -0
- package/dist/config/default-mdsite-config.js +82 -0
- package/dist/config/default-mdsite-config.js.map +1 -0
- package/dist/config/default-mdsite-config.test.d.ts +1 -0
- package/dist/config/default-mdsite-config.test.js +42 -0
- package/dist/config/default-mdsite-config.test.js.map +1 -0
- package/dist/config/mdsite-config.d.ts +42 -0
- package/dist/config/mdsite-config.js +74 -0
- package/dist/config/mdsite-config.js.map +1 -0
- package/dist/config/mdsite-config.test.d.ts +1 -0
- package/dist/config/mdsite-config.test.js +115 -0
- package/dist/config/mdsite-config.test.js.map +1 -0
- package/dist/config/menu.d.ts +3 -0
- package/dist/config/menu.js +58 -0
- package/dist/config/menu.js.map +1 -0
- package/dist/config/menu.test.d.ts +1 -0
- package/dist/config/menu.test.js +53 -0
- package/dist/config/menu.test.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +99 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +1 -0
- package/dist/index.test.js +133 -0
- package/dist/index.test.js.map +1 -0
- package/dist/process/child-process.d.ts +9 -0
- package/dist/process/child-process.js +142 -0
- package/dist/process/child-process.js.map +1 -0
- package/dist/process/child-process.test.d.ts +1 -0
- package/dist/process/child-process.test.js +131 -0
- package/dist/process/child-process.test.js.map +1 -0
- package/dist/process/runtime-state.d.ts +16 -0
- package/dist/process/runtime-state.js +42 -0
- package/dist/process/runtime-state.js.map +1 -0
- package/dist/process/runtime-state.test.d.ts +1 -0
- package/dist/process/runtime-state.test.js +57 -0
- package/dist/process/runtime-state.test.js.map +1 -0
- package/dist/renderer/mdsite-nuxt.d.ts +22 -0
- package/dist/renderer/mdsite-nuxt.js +194 -0
- package/dist/renderer/mdsite-nuxt.js.map +1 -0
- package/dist/renderer/mdsite-nuxt.test.d.ts +1 -0
- package/dist/renderer/mdsite-nuxt.test.js +226 -0
- package/dist/renderer/mdsite-nuxt.test.js.map +1 -0
- package/mdsite-nuxt/app/app.vue +7 -0
- package/mdsite-nuxt/app/assets/css/bible-tooltips.css +87 -0
- package/mdsite-nuxt/app/assets/css/markdown.css +195 -0
- package/mdsite-nuxt/app/assets/css/print.css +133 -0
- package/mdsite-nuxt/app/components/AppBar.vue +138 -0
- package/mdsite-nuxt/app/components/AppFooter.vue +88 -0
- package/mdsite-nuxt/app/components/AppNavigation.vue +162 -0
- package/mdsite-nuxt/app/components/AppTableOfContents.vue +149 -0
- package/mdsite-nuxt/app/components/BreadcrumbNav.vue +139 -0
- package/mdsite-nuxt/app/components/NavigationTree.vue +169 -0
- package/mdsite-nuxt/app/components/SearchBox.vue +212 -0
- package/mdsite-nuxt/app/components/TocItem.vue +75 -0
- package/mdsite-nuxt/app/components/TreeNode.vue +264 -0
- package/mdsite-nuxt/app/components/content/MarkdownAlert.vue +42 -0
- package/mdsite-nuxt/app/components/content/Mermaid.vue +103 -0
- package/mdsite-nuxt/app/components/content/ProseA.vue +57 -0
- package/mdsite-nuxt/app/components/content/ProseBlockquote.vue +14 -0
- package/mdsite-nuxt/app/components/content/ProsePre.vue +49 -0
- package/mdsite-nuxt/app/components/content/ProseTable.vue +143 -0
- package/mdsite-nuxt/app/composables/useAppTheme.ts +89 -0
- package/mdsite-nuxt/app/composables/useBibleTooltips.ts +21 -0
- package/mdsite-nuxt/app/composables/useBreadcrumbs.ts +70 -0
- package/mdsite-nuxt/app/composables/useContentPostProcessing.ts +89 -0
- package/mdsite-nuxt/app/composables/useNavigationTree.ts +174 -0
- package/mdsite-nuxt/app/composables/useSearchIndex.ts +47 -0
- package/mdsite-nuxt/app/composables/useSearchRelevance.test.ts +255 -0
- package/mdsite-nuxt/app/composables/useSearchRelevance.ts +207 -0
- package/mdsite-nuxt/app/composables/useSidebarState.ts +62 -0
- package/mdsite-nuxt/app/composables/useSiteConfig.ts +37 -0
- package/mdsite-nuxt/app/composables/useSourceEdit.ts +69 -0
- package/mdsite-nuxt/app/composables/useTableOfContents.ts +141 -0
- package/mdsite-nuxt/app/composables/useTableParser.ts +106 -0
- package/mdsite-nuxt/app/composables/useTooltipConfig.ts +20 -0
- package/mdsite-nuxt/app/config/themes.ts +17 -0
- package/mdsite-nuxt/app/layouts/default.vue +376 -0
- package/mdsite-nuxt/app/pages/[...slug].vue +56 -0
- package/mdsite-nuxt/app/pages/index.vue +54 -0
- package/mdsite-nuxt/app/plugins/bible-tooltips.client.ts +401 -0
- package/mdsite-nuxt/app/plugins/bible-tooltips.test.ts +284 -0
- package/mdsite-nuxt/app/types/content.d.ts +10 -0
- package/mdsite-nuxt/app/types/table.ts +57 -0
- package/mdsite-nuxt/app/utils/bible-book-names.ts +37 -0
- package/mdsite-nuxt/app/utils/bible-verse-utils.test.ts +148 -0
- package/mdsite-nuxt/app/utils/bible-verse-utils.ts +236 -0
- package/mdsite-nuxt/content.config.ts +18 -0
- package/mdsite-nuxt/example.config.yml +67 -0
- package/mdsite-nuxt/nuxt.config.ts +247 -0
- package/mdsite-nuxt/package-lock.json +15922 -0
- package/mdsite-nuxt/package.json +50 -0
- package/mdsite-nuxt/playwright.config.js +47 -0
- package/mdsite-nuxt/public/robots.txt +2 -0
- package/mdsite-nuxt/scripts/generate-favicons.ts +192 -0
- package/mdsite-nuxt/scripts/generate-indices.ts +508 -0
- package/mdsite-nuxt/scripts/renderer-hooks.test.ts +277 -0
- package/mdsite-nuxt/scripts/renderer-hooks.ts +141 -0
- package/mdsite-nuxt/scripts/start.test.ts +164 -0
- package/mdsite-nuxt/scripts/start.ts +55 -0
- package/mdsite-nuxt/scripts/sync-content.ts +504 -0
- package/mdsite-nuxt/tsconfig.json +18 -0
- package/mdsite-nuxt/utils/mdsite-config.ts +240 -0
- package/mdsite-nuxt/vitest.config.ts +7 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
# MDsite
|
|
4
|
+
|
|
5
|
+
## Current workflow
|
|
6
|
+
|
|
7
|
+
Use the CLI from the root package, then operate on your markdown project directory:
|
|
8
|
+
|
|
9
|
+
1. Build the local CLI in this repository.
|
|
10
|
+
2. Change into the markdown/content directory you want to serve.
|
|
11
|
+
3. Invoke the built CLI from this repository path, or use a local alias/link that points to it.
|
|
12
|
+
4. Run `init` once to create `mdsite.yml`.
|
|
13
|
+
5. Run `start` for foreground local development, or `start -d` for a tracked background process that opens the browser after the server is ready.
|
|
14
|
+
6. Run `generate` to build static output.
|
|
15
|
+
7. Run `preview` after `generate` for a foreground local preview, or `preview -d` for a tracked background preview.
|
|
16
|
+
8. Run `stop` to stop tracked detached `start` and `preview` processes.
|
|
17
|
+
|
|
18
|
+
## Documentation location
|
|
19
|
+
|
|
20
|
+
[Primary project documentation](docs/index.md) and demo content belong in this repository root, such as this `README.md` and `docs/`. Keep `mdsite-nuxt/` documentation limited to renderer internals.
|
|
21
|
+
|
|
22
|
+
## Implemented commands
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
mdsite help
|
|
26
|
+
mdsite version
|
|
27
|
+
mdsite init
|
|
28
|
+
mdsite start
|
|
29
|
+
mdsite generate
|
|
30
|
+
mdsite preview
|
|
31
|
+
mdsite stop
|
|
32
|
+
mdsite prepare github
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
All commands operate on the **current working directory** as the content/project directory.
|
|
36
|
+
`version` prints the CLI version from the root `package.json`; run it as `mdsite version` or `node /path/to/md-site/dist/index.js version`.
|
|
37
|
+
`prepare github` also requires `mdsite.yml` and writes a GitHub Pages workflow for that content directory.
|
|
38
|
+
|
|
39
|
+
## Local Development Setup
|
|
40
|
+
|
|
41
|
+
This repository currently documents a **local-only** workflow:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# in this repository
|
|
45
|
+
npm install
|
|
46
|
+
npm run build
|
|
47
|
+
npm run install-alias
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Restart CLI terminal session.
|
|
51
|
+
|
|
52
|
+
Then run the `mdsite-dev` alias from any directory containing `mdsite.yml`:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
mdsite-dev start
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Open http://localhost:3000/. The command runs in the foreground and writes renderer output to the terminal; closing the terminal or interrupting the command stops the process.
|
|
59
|
+
|
|
60
|
+
To run the demo as a tracked background process instead, use `mdsite-dev start -d` or `mdsite-dev start --detached`. Detached start logs to `.mdsite-runtime/start.log` in the content directory and opens the browser automatically after the server is ready.
|
|
61
|
+
|
|
62
|
+
To stop a detached local preview:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
mdsite-dev stop
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
> [!NOTE] When using `mdsite-dev` locally (e.g. `npm run install-alias`), the CLI utility is called `mdsite-dev`. When installed globally via npm registry, the CLI utility is called `mdsite` instead.
|
|
69
|
+
|
|
70
|
+
## Supported CLI flow
|
|
71
|
+
|
|
72
|
+
### Check the CLI version
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
mdsite version
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`version` prints the CLI version from the root `package.json`.
|
|
79
|
+
|
|
80
|
+
### 1. Initialize a content directory
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
mdsite init
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`init` creates `mdsite.yml` in the current directory and derives defaults from local markdown files.
|
|
87
|
+
|
|
88
|
+
### 2. Start local development
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
mdsite start
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`start` requires `mdsite.yml`, prepares renderer compatibility files, installs renderer dependencies when `node_modules` is missing, and runs the renderer in the foreground with terminal output. Closing the terminal or interrupting the command stops the foreground process.
|
|
95
|
+
|
|
96
|
+
Use `mdsite start -d` or `mdsite start --detached` to run a tracked background renderer instead. Detached start logs to `.mdsite-runtime/start.log` in the content directory and opens the browser automatically after the server is ready.
|
|
97
|
+
|
|
98
|
+
### 3. Generate static output
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
mdsite generate
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`generate` requires `mdsite.yml` and writes the generated site to `server.output` under the content directory.
|
|
105
|
+
|
|
106
|
+
### 4. Preview generated output
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
mdsite preview
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`preview` is a **post-generate** local preview step. It requires `mdsite.yml` and an existing generated renderer build.
|
|
113
|
+
By default, it runs in the foreground with terminal output. Closing the terminal or interrupting the command stops the foreground preview.
|
|
114
|
+
|
|
115
|
+
Use `mdsite preview -d` or `mdsite preview --detached` to run a tracked background preview instead. Detached preview logs to `mdsite.log` in the content directory and writes runtime state under `.mdsite-runtime/`.
|
|
116
|
+
|
|
117
|
+
### 5. Stop background processes
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
mdsite stop
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`stop` is intended for initialized content directories and stops tracked detached `start` and `preview` background processes for the current content directory, not foreground processes.
|
|
124
|
+
|
|
125
|
+
### 6. Prepare a GitHub Pages workflow
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
mdsite prepare github
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
`prepare github` requires `mdsite.yml`, prepares the configured local renderer, and writes `.github/workflows/deploy.yml` in the current content directory. The generated workflow uses the configured local `server.path` during GitHub Actions; it does not add a renderer clone or pull workflow.
|
|
132
|
+
|
|
133
|
+
## Renderer resolution
|
|
134
|
+
|
|
135
|
+
Renderer resolution is currently **local-only**:
|
|
136
|
+
|
|
137
|
+
- If `mdsite.yml` sets `server.path`, the CLI first looks for that path **relative to the content directory**.
|
|
138
|
+
- If that directory is not present, the CLI falls back to the checked-in repository renderer at `mdsite-nuxt/`.
|
|
139
|
+
- If the renderer's `node_modules` directory is missing, the CLI runs `npm install` in the renderer directory.
|
|
140
|
+
- `prepare github` requires the configured `server.path` renderer directory to exist; unlike `start`, `generate`, and `preview`, it does not fall back to the checked-in renderer when that configured path is absent.
|
|
141
|
+
|
|
142
|
+
Current documentation does **not** describe clone/pull behavior as active usage.
|
|
143
|
+
|
|
144
|
+
## Expected content project layout
|
|
145
|
+
|
|
146
|
+
Before initialization:
|
|
147
|
+
|
|
148
|
+
```text
|
|
149
|
+
your-content/
|
|
150
|
+
├── index.md
|
|
151
|
+
└── other-pages.md
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
After `mdsite init`, `mdsite generate`, and optional tracked background commands:
|
|
155
|
+
|
|
156
|
+
```text
|
|
157
|
+
your-content/
|
|
158
|
+
├── mdsite.yml
|
|
159
|
+
├── _menu.yml # orchestration/compatibility artifact
|
|
160
|
+
├── .mdsite-runtime/ # created when tracked background processes are started
|
|
161
|
+
├── .output/ # created by mdsite generate, or server.output
|
|
162
|
+
├── index.md
|
|
163
|
+
└── other-pages.md
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
The CLI also writes renderer compatibility files such as `_menu.yml`, `mdsite-nuxt/.env`, and `mdsite-nuxt/content.config.yml` as part of orchestration. Tracked background commands write runtime files under `.mdsite-runtime/`.
|
|
167
|
+
|
|
168
|
+
## Migration notes for existing users
|
|
169
|
+
|
|
170
|
+
If you previously used the legacy root workflow:
|
|
171
|
+
|
|
172
|
+
- Replace `npm start` with `node /path/to/md-site/dist/index.js start`.
|
|
173
|
+
- Replace `npm run generate` with `node /path/to/md-site/dist/index.js generate`.
|
|
174
|
+
- Replace `npm run preview` with `node /path/to/md-site/dist/index.js preview` after `node /path/to/md-site/dist/index.js generate`.
|
|
175
|
+
- Replace legacy root/domain config assumptions with a single `mdsite.yml` in the content directory.
|
|
176
|
+
- Treat `content.config.yml` and domain-specific `*.config.yml` files as legacy reference, not current setup.
|
|
177
|
+
- Keep custom markdown content, menus, and theme values, but move current configuration intent into `mdsite.yml`.
|
|
178
|
+
|
|
179
|
+
## Troubleshooting
|
|
180
|
+
|
|
181
|
+
### `mdsite.yml` is missing
|
|
182
|
+
|
|
183
|
+
If `start`, `generate`, `preview`, or `stop` are not behaving as expected, first confirm you are in the intended content directory and that `mdsite.yml` exists there:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
mdsite init
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Renderer directory issues
|
|
190
|
+
|
|
191
|
+
- If `server.path` is set, confirm it points to a renderer directory relative to the content directory.
|
|
192
|
+
- If that path does not exist, the CLI falls back to the checked-in `mdsite-nuxt` directory in this repository.
|
|
193
|
+
- If neither renderer location exists, the CLI cannot run.
|
|
194
|
+
- For `prepare github`, the configured `server.path` must exist because workflow generation uses the configured renderer path directly.
|
|
195
|
+
|
|
196
|
+
### Renderer dependencies missing
|
|
197
|
+
|
|
198
|
+
If the renderer has no `node_modules`, the CLI runs `npm install` in the renderer directory automatically. If that install fails, fix the renderer dependency issue and rerun the command.
|
|
199
|
+
|
|
200
|
+
### Preview fails
|
|
201
|
+
|
|
202
|
+
Run `mdsite generate` first. `preview` requires an existing generated renderer build.
|
|
203
|
+
|
|
204
|
+
### Config problems
|
|
205
|
+
|
|
206
|
+
- `mdsite.yml` must be valid YAML.
|
|
207
|
+
- `server.output` is resolved under the content directory.
|
|
208
|
+
- `server.path` is resolved relative to the content directory.
|
|
209
|
+
- If `favicon` is configured, the referenced file must exist.
|
|
210
|
+
|
|
211
|
+
## Configuration reference
|
|
212
|
+
|
|
213
|
+
`mdsite.yml` is the only active content-directory configuration file. `mdsite init` creates it and fills defaults from local markdown files where possible.
|
|
214
|
+
|
|
215
|
+
| Key | Default | Description |
|
|
216
|
+
| ------------------------ | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
217
|
+
| `favicon` | empty string | Optional favicon path relative to the content directory. |
|
|
218
|
+
| `features.bibleTooltips` | `true` | Enables renderer Bible tooltip support. |
|
|
219
|
+
| `features.sourceEdit` | `true` | Enables renderer source-edit support. |
|
|
220
|
+
| `menu` | derived from markdown files | Menu structure used to generate `_menu.yml`. |
|
|
221
|
+
| `server.output` | `.output` | Static output path under the content directory. |
|
|
222
|
+
| `server.path` | `.mdsite` | Renderer path relative to the content directory. Local commands fall back to checked-in `mdsite-nuxt/` when this path is absent, except `prepare github`. |
|
|
223
|
+
| `server.repo` | `https://github.com/life-and-dev/mdsite` | Stored for compatibility and generated renderer config. It is not used for active clone/pull behaviour. |
|
|
224
|
+
| `site.canonical` | empty string | Canonical site URL passed to the renderer. |
|
|
225
|
+
| `site.name` | derived from `index.md` or directory | Site name passed to the renderer. |
|
|
226
|
+
| `themes.light.colors` | built-in palette | Light theme colour overrides. |
|
|
227
|
+
| `themes.dark.colors` | built-in palette | Dark theme colour overrides. |
|
|
228
|
+
|
package/bin/mdsite.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
vi.mock('node:fs/promises', () => ({
|
|
3
|
+
access: vi.fn(),
|
|
4
|
+
cp: vi.fn(),
|
|
5
|
+
rm: vi.fn(),
|
|
6
|
+
writeFile: vi.fn()
|
|
7
|
+
}));
|
|
8
|
+
vi.mock('../config/mdsite-config.js', () => ({
|
|
9
|
+
buildDefaultMdsiteConfig: vi.fn(),
|
|
10
|
+
loadMdsiteConfig: vi.fn(),
|
|
11
|
+
resolveContentOutputPath: vi.fn(),
|
|
12
|
+
serializeMdsiteConfig: vi.fn()
|
|
13
|
+
}));
|
|
14
|
+
vi.mock('../process/runtime-state.js', () => ({
|
|
15
|
+
clearRuntimeState: vi.fn(),
|
|
16
|
+
getRuntimeLogPath: vi.fn(),
|
|
17
|
+
isProcessRunning: vi.fn(),
|
|
18
|
+
readRuntimeState: vi.fn(),
|
|
19
|
+
writeRuntimeState: vi.fn()
|
|
20
|
+
}));
|
|
21
|
+
vi.mock('../process/child-process.js', () => ({
|
|
22
|
+
openUrlInBrowser: vi.fn(),
|
|
23
|
+
stopProcess: vi.fn(),
|
|
24
|
+
waitForTcpPort: vi.fn()
|
|
25
|
+
}));
|
|
26
|
+
vi.mock('../renderer/mdsite-nuxt.js', () => ({
|
|
27
|
+
ensurePreviewArtifacts: vi.fn(),
|
|
28
|
+
ensureRendererDependencies: vi.fn(),
|
|
29
|
+
generateRenderer: vi.fn(),
|
|
30
|
+
getRendererGeneratedOutputPath: vi.fn(),
|
|
31
|
+
prepareRenderer: vi.fn(),
|
|
32
|
+
previewRendererForeground: vi.fn(),
|
|
33
|
+
previewRendererInBackground: vi.fn(),
|
|
34
|
+
startRendererForeground: vi.fn(),
|
|
35
|
+
startRendererInBackground: vi.fn()
|
|
36
|
+
}));
|
|
37
|
+
import { access, cp, rm, writeFile } from 'node:fs/promises';
|
|
38
|
+
import { buildDefaultMdsiteConfig, loadMdsiteConfig, resolveContentOutputPath, serializeMdsiteConfig } from '../config/mdsite-config.js';
|
|
39
|
+
import { openUrlInBrowser, stopProcess, waitForTcpPort } from '../process/child-process.js';
|
|
40
|
+
import { clearRuntimeState, getRuntimeLogPath, isProcessRunning, readRuntimeState, writeRuntimeState } from '../process/runtime-state.js';
|
|
41
|
+
import { ensurePreviewArtifacts, ensureRendererDependencies, generateRenderer, getRendererGeneratedOutputPath, prepareRenderer, previewRendererForeground, previewRendererInBackground, startRendererForeground, startRendererInBackground } from '../renderer/mdsite-nuxt.js';
|
|
42
|
+
import { runGenerateCommand } from './generate.js';
|
|
43
|
+
import { runInitCommand } from './init.js';
|
|
44
|
+
import { runPreviewCommand } from './preview.js';
|
|
45
|
+
import { runStartCommand } from './start.js';
|
|
46
|
+
import { runStopCommand } from './stop.js';
|
|
47
|
+
const accessMock = vi.mocked(access);
|
|
48
|
+
const cpMock = vi.mocked(cp);
|
|
49
|
+
const rmMock = vi.mocked(rm);
|
|
50
|
+
const writeFileMock = vi.mocked(writeFile);
|
|
51
|
+
const buildDefaultConfigMock = vi.mocked(buildDefaultMdsiteConfig);
|
|
52
|
+
const loadConfigMock = vi.mocked(loadMdsiteConfig);
|
|
53
|
+
const resolveOutputMock = vi.mocked(resolveContentOutputPath);
|
|
54
|
+
const serializeConfigMock = vi.mocked(serializeMdsiteConfig);
|
|
55
|
+
const clearRuntimeStateMock = vi.mocked(clearRuntimeState);
|
|
56
|
+
const getRuntimeLogPathMock = vi.mocked(getRuntimeLogPath);
|
|
57
|
+
const isProcessRunningMock = vi.mocked(isProcessRunning);
|
|
58
|
+
const readRuntimeStateMock = vi.mocked(readRuntimeState);
|
|
59
|
+
const writeRuntimeStateMock = vi.mocked(writeRuntimeState);
|
|
60
|
+
const ensurePreviewArtifactsMock = vi.mocked(ensurePreviewArtifacts);
|
|
61
|
+
const ensureRendererDependenciesMock = vi.mocked(ensureRendererDependencies);
|
|
62
|
+
const generateRendererMock = vi.mocked(generateRenderer);
|
|
63
|
+
const getRendererGeneratedOutputPathMock = vi.mocked(getRendererGeneratedOutputPath);
|
|
64
|
+
const prepareRendererMock = vi.mocked(prepareRenderer);
|
|
65
|
+
const previewRendererForegroundMock = vi.mocked(previewRendererForeground);
|
|
66
|
+
const previewRendererInBackgroundMock = vi.mocked(previewRendererInBackground);
|
|
67
|
+
const startRendererForegroundMock = vi.mocked(startRendererForeground);
|
|
68
|
+
const startRendererInBackgroundMock = vi.mocked(startRendererInBackground);
|
|
69
|
+
const stopProcessMock = vi.mocked(stopProcess);
|
|
70
|
+
const openUrlInBrowserMock = vi.mocked(openUrlInBrowser);
|
|
71
|
+
const waitForTcpPortMock = vi.mocked(waitForTcpPort);
|
|
72
|
+
const loadedConfig = {
|
|
73
|
+
config: {
|
|
74
|
+
favicon: '',
|
|
75
|
+
features: { bibleTooltips: true, sourceEdit: true },
|
|
76
|
+
menu: [],
|
|
77
|
+
server: { output: '.output', path: '.renderer', repo: 'repo' },
|
|
78
|
+
site: { canonical: '', name: 'Docs' },
|
|
79
|
+
themes: { light: { colors: {} }, dark: { colors: {} } }
|
|
80
|
+
},
|
|
81
|
+
configDir: '/content',
|
|
82
|
+
configPath: '/content/mdsite.yml',
|
|
83
|
+
contentDir: '/content'
|
|
84
|
+
};
|
|
85
|
+
describe('command helpers', () => {
|
|
86
|
+
beforeEach(() => {
|
|
87
|
+
vi.clearAllMocks();
|
|
88
|
+
vi.useRealTimers();
|
|
89
|
+
loadConfigMock.mockResolvedValue(loadedConfig);
|
|
90
|
+
prepareRendererMock.mockResolvedValue({ rendererDir: '/renderer', rendererEnv: { TEST: '1' } });
|
|
91
|
+
getRuntimeLogPathMock.mockImplementation((contentDir, kind) => {
|
|
92
|
+
if (kind === 'preview') {
|
|
93
|
+
return `${contentDir}/mdsite.log`;
|
|
94
|
+
}
|
|
95
|
+
return `${contentDir}/.mdsite-runtime/${kind}.log`;
|
|
96
|
+
});
|
|
97
|
+
resolveOutputMock.mockReturnValue('/content/public');
|
|
98
|
+
getRendererGeneratedOutputPathMock.mockReturnValue('/renderer/.output/public');
|
|
99
|
+
openUrlInBrowserMock.mockResolvedValue(true);
|
|
100
|
+
waitForTcpPortMock.mockResolvedValue(true);
|
|
101
|
+
});
|
|
102
|
+
it('runInitCommand creates mdsite.yml only when it does not already exist', async () => {
|
|
103
|
+
accessMock.mockRejectedValueOnce(new Error('missing'));
|
|
104
|
+
buildDefaultConfigMock.mockResolvedValue(loadedConfig.config);
|
|
105
|
+
serializeConfigMock.mockReturnValue('serialized-config');
|
|
106
|
+
await expect(runInitCommand('/content')).resolves.toBeUndefined();
|
|
107
|
+
expect(buildDefaultConfigMock).toHaveBeenCalledWith('/content');
|
|
108
|
+
expect(writeFileMock).toHaveBeenCalledWith('/content/mdsite.yml', 'serialized-config', 'utf8');
|
|
109
|
+
accessMock.mockResolvedValueOnce(undefined);
|
|
110
|
+
await expect(runInitCommand('/content')).rejects.toThrow('mdsite.yml already exists at /content/mdsite.yml.');
|
|
111
|
+
});
|
|
112
|
+
it('runStartCommand starts the renderer in the foreground by default without runtime metadata', async () => {
|
|
113
|
+
await expect(runStartCommand('/content')).resolves.toBeUndefined();
|
|
114
|
+
expect(readRuntimeStateMock).not.toHaveBeenCalled();
|
|
115
|
+
expect(getRuntimeLogPathMock).not.toHaveBeenCalled();
|
|
116
|
+
expect(startRendererInBackgroundMock).not.toHaveBeenCalled();
|
|
117
|
+
expect(writeRuntimeStateMock).not.toHaveBeenCalled();
|
|
118
|
+
expect(ensureRendererDependenciesMock).toHaveBeenCalledWith('/renderer');
|
|
119
|
+
expect(startRendererForegroundMock).toHaveBeenCalledWith('/renderer', { TEST: '1' });
|
|
120
|
+
});
|
|
121
|
+
it('runStartCommand rejects detached mode when an active start process is already running', async () => {
|
|
122
|
+
readRuntimeStateMock.mockResolvedValueOnce({ kind: 'start', pid: 44 });
|
|
123
|
+
isProcessRunningMock.mockReturnValueOnce(true);
|
|
124
|
+
await expect(runStartCommand('/content', { detached: true })).rejects.toThrow('mdsite start is already running with PID 44.');
|
|
125
|
+
expect(loadConfigMock).not.toHaveBeenCalled();
|
|
126
|
+
});
|
|
127
|
+
it('runStartCommand starts detached renderer for stale state and persists fresh runtime metadata', async () => {
|
|
128
|
+
vi.useFakeTimers();
|
|
129
|
+
vi.setSystemTime(new Date('2026-04-10T12:34:56.000Z'));
|
|
130
|
+
readRuntimeStateMock.mockResolvedValueOnce({ kind: 'start', pid: 44 });
|
|
131
|
+
isProcessRunningMock.mockReturnValueOnce(false);
|
|
132
|
+
startRendererInBackgroundMock.mockResolvedValueOnce(777);
|
|
133
|
+
await expect(runStartCommand('/content', { detached: true })).resolves.toBe('mdsite start running in background (PID 777). Log: /content/.mdsite-runtime/start.log');
|
|
134
|
+
expect(ensureRendererDependenciesMock).toHaveBeenCalledWith('/renderer');
|
|
135
|
+
expect(waitForTcpPortMock).toHaveBeenCalledWith('localhost', 3000);
|
|
136
|
+
expect(waitForTcpPortMock.mock.invocationCallOrder[0]).toBeGreaterThan(writeRuntimeStateMock.mock.invocationCallOrder[0] ?? 0);
|
|
137
|
+
expect(openUrlInBrowserMock.mock.invocationCallOrder[0]).toBeGreaterThan(waitForTcpPortMock.mock.invocationCallOrder[0] ?? 0);
|
|
138
|
+
expect(openUrlInBrowserMock).toHaveBeenCalledWith('http://localhost:3000');
|
|
139
|
+
expect(writeRuntimeStateMock).toHaveBeenCalledWith('/content', expect.objectContaining({
|
|
140
|
+
kind: 'start',
|
|
141
|
+
pid: 777,
|
|
142
|
+
rendererDir: '/renderer',
|
|
143
|
+
command: ['npm', 'run', 'dev'],
|
|
144
|
+
startedAt: '2026-04-10T12:34:56.000Z'
|
|
145
|
+
}));
|
|
146
|
+
});
|
|
147
|
+
it('runStartCommand uses the configured start host and port when opening detached start', async () => {
|
|
148
|
+
readRuntimeStateMock.mockResolvedValueOnce(null);
|
|
149
|
+
prepareRendererMock.mockResolvedValueOnce({
|
|
150
|
+
rendererDir: '/renderer',
|
|
151
|
+
rendererEnv: { HOST: '127.0.0.1', PORT: '4173', NUXT_HOST: 'start.local', NUXT_PORT: '4321' }
|
|
152
|
+
});
|
|
153
|
+
startRendererInBackgroundMock.mockResolvedValueOnce(778);
|
|
154
|
+
await expect(runStartCommand('/content', { detached: true })).resolves.toBe('mdsite start running in background (PID 778). Log: /content/.mdsite-runtime/start.log');
|
|
155
|
+
expect(waitForTcpPortMock).toHaveBeenCalledWith('start.local', 4321);
|
|
156
|
+
expect(openUrlInBrowserMock).toHaveBeenCalledWith('http://start.local:4321');
|
|
157
|
+
});
|
|
158
|
+
it('runStartCommand does not open the browser when detached start readiness times out', async () => {
|
|
159
|
+
readRuntimeStateMock.mockResolvedValueOnce(null);
|
|
160
|
+
startRendererInBackgroundMock.mockResolvedValueOnce(779);
|
|
161
|
+
waitForTcpPortMock.mockResolvedValueOnce(false);
|
|
162
|
+
await expect(runStartCommand('/content', { detached: true })).resolves.toBe('mdsite start running in background (PID 779). Log: /content/.mdsite-runtime/start.log');
|
|
163
|
+
expect(waitForTcpPortMock).toHaveBeenCalledWith('localhost', 3000);
|
|
164
|
+
expect(openUrlInBrowserMock).not.toHaveBeenCalled();
|
|
165
|
+
});
|
|
166
|
+
it('runStartCommand keeps succeeding when detached start readiness checks fail', async () => {
|
|
167
|
+
readRuntimeStateMock.mockResolvedValueOnce(null);
|
|
168
|
+
startRendererInBackgroundMock.mockResolvedValueOnce(780);
|
|
169
|
+
waitForTcpPortMock.mockRejectedValueOnce(new Error('connect failed'));
|
|
170
|
+
await expect(runStartCommand('/content', { detached: true })).resolves.toBe('mdsite start running in background (PID 780). Log: /content/.mdsite-runtime/start.log');
|
|
171
|
+
expect(openUrlInBrowserMock).not.toHaveBeenCalled();
|
|
172
|
+
});
|
|
173
|
+
it('runPreviewCommand previews in the foreground by default without runtime metadata', async () => {
|
|
174
|
+
await expect(runPreviewCommand('/content')).resolves.toBeUndefined();
|
|
175
|
+
expect(readRuntimeStateMock).not.toHaveBeenCalled();
|
|
176
|
+
expect(getRuntimeLogPathMock).not.toHaveBeenCalled();
|
|
177
|
+
expect(previewRendererInBackgroundMock).not.toHaveBeenCalled();
|
|
178
|
+
expect(writeRuntimeStateMock).not.toHaveBeenCalled();
|
|
179
|
+
expect(waitForTcpPortMock).not.toHaveBeenCalled();
|
|
180
|
+
expect(openUrlInBrowserMock).not.toHaveBeenCalled();
|
|
181
|
+
expect(ensureRendererDependenciesMock).toHaveBeenCalledWith('/renderer');
|
|
182
|
+
expect(ensurePreviewArtifactsMock).toHaveBeenCalledWith('/renderer');
|
|
183
|
+
expect(previewRendererForegroundMock).toHaveBeenCalledWith('/renderer', expect.objectContaining({
|
|
184
|
+
TEST: '1',
|
|
185
|
+
NUXT_HOST: 'localhost',
|
|
186
|
+
NUXT_PORT: '3000',
|
|
187
|
+
HOST: 'localhost',
|
|
188
|
+
PORT: '3000',
|
|
189
|
+
NITRO_HOST: 'localhost',
|
|
190
|
+
NITRO_PORT: '3000'
|
|
191
|
+
}));
|
|
192
|
+
});
|
|
193
|
+
it('runPreviewCommand rejects detached mode when an active preview process is already running', async () => {
|
|
194
|
+
readRuntimeStateMock.mockResolvedValueOnce({ kind: 'preview', pid: 55 });
|
|
195
|
+
isProcessRunningMock.mockReturnValueOnce(true);
|
|
196
|
+
await expect(runPreviewCommand('/content', { detached: true })).rejects.toThrow('mdsite preview is already running with PID 55.');
|
|
197
|
+
expect(loadConfigMock).not.toHaveBeenCalled();
|
|
198
|
+
});
|
|
199
|
+
it('runPreviewCommand enforces preview artifacts and persists preview runtime state in detached mode', async () => {
|
|
200
|
+
vi.useFakeTimers();
|
|
201
|
+
vi.setSystemTime(new Date('2026-04-10T13:00:00.000Z'));
|
|
202
|
+
readRuntimeStateMock.mockResolvedValueOnce(null);
|
|
203
|
+
previewRendererInBackgroundMock.mockResolvedValueOnce(888);
|
|
204
|
+
await expect(runPreviewCommand('/content', { detached: true })).resolves.toBe('mdsite preview running in background (PID 888). URL: http://localhost:3000 Log: /content/mdsite.log');
|
|
205
|
+
expect(ensurePreviewArtifactsMock).toHaveBeenCalledWith('/renderer');
|
|
206
|
+
expect(ensurePreviewArtifactsMock.mock.invocationCallOrder[0]).toBeGreaterThan(ensureRendererDependenciesMock.mock.invocationCallOrder[0] ?? 0);
|
|
207
|
+
expect(previewRendererInBackgroundMock).toHaveBeenCalledWith('/renderer', expect.objectContaining({
|
|
208
|
+
TEST: '1',
|
|
209
|
+
NUXT_HOST: 'localhost',
|
|
210
|
+
NUXT_PORT: '3000',
|
|
211
|
+
HOST: 'localhost',
|
|
212
|
+
PORT: '3000',
|
|
213
|
+
NITRO_HOST: 'localhost',
|
|
214
|
+
NITRO_PORT: '3000'
|
|
215
|
+
}), '/content/mdsite.log');
|
|
216
|
+
expect(waitForTcpPortMock).toHaveBeenCalledWith('localhost', 3000);
|
|
217
|
+
expect(waitForTcpPortMock.mock.invocationCallOrder[0]).toBeGreaterThan(writeRuntimeStateMock.mock.invocationCallOrder[0] ?? 0);
|
|
218
|
+
expect(openUrlInBrowserMock.mock.invocationCallOrder[0]).toBeGreaterThan(waitForTcpPortMock.mock.invocationCallOrder[0] ?? 0);
|
|
219
|
+
expect(openUrlInBrowserMock).toHaveBeenCalledWith('http://localhost:3000');
|
|
220
|
+
expect(writeRuntimeStateMock).toHaveBeenCalledWith('/content', expect.objectContaining({
|
|
221
|
+
kind: 'preview',
|
|
222
|
+
pid: 888,
|
|
223
|
+
command: ['npm', 'run', 'preview'],
|
|
224
|
+
startedAt: '2026-04-10T13:00:00.000Z'
|
|
225
|
+
}));
|
|
226
|
+
});
|
|
227
|
+
it('runPreviewCommand prefers inherited preview host and port values for the detached preview URL', async () => {
|
|
228
|
+
readRuntimeStateMock.mockResolvedValueOnce(null);
|
|
229
|
+
prepareRendererMock.mockResolvedValueOnce({
|
|
230
|
+
rendererDir: '/renderer',
|
|
231
|
+
rendererEnv: { HOST: '127.0.0.1', PORT: '4173', NUXT_HOST: 'preview.local', NUXT_PORT: '4321' }
|
|
232
|
+
});
|
|
233
|
+
previewRendererInBackgroundMock.mockResolvedValueOnce(999);
|
|
234
|
+
await expect(runPreviewCommand('/content', { detached: true })).resolves.toBe('mdsite preview running in background (PID 999). URL: http://preview.local:4321 Log: /content/mdsite.log');
|
|
235
|
+
expect(previewRendererInBackgroundMock).toHaveBeenCalledWith('/renderer', expect.objectContaining({
|
|
236
|
+
HOST: 'preview.local',
|
|
237
|
+
PORT: '4321',
|
|
238
|
+
NUXT_HOST: 'preview.local',
|
|
239
|
+
NUXT_PORT: '4321',
|
|
240
|
+
NITRO_HOST: 'preview.local',
|
|
241
|
+
NITRO_PORT: '4321'
|
|
242
|
+
}), '/content/mdsite.log');
|
|
243
|
+
expect(waitForTcpPortMock).toHaveBeenCalledWith('preview.local', 4321);
|
|
244
|
+
expect(openUrlInBrowserMock).toHaveBeenCalledWith('http://preview.local:4321');
|
|
245
|
+
});
|
|
246
|
+
it('runPreviewCommand falls back to HOST and PORT when NUXT preview values are unset in detached mode', async () => {
|
|
247
|
+
readRuntimeStateMock.mockResolvedValueOnce(null);
|
|
248
|
+
prepareRendererMock.mockResolvedValueOnce({
|
|
249
|
+
rendererDir: '/renderer',
|
|
250
|
+
rendererEnv: { HOST: '127.0.0.1', PORT: '4173' }
|
|
251
|
+
});
|
|
252
|
+
previewRendererInBackgroundMock.mockResolvedValueOnce(1000);
|
|
253
|
+
await expect(runPreviewCommand('/content', { detached: true })).resolves.toBe('mdsite preview running in background (PID 1000). URL: http://127.0.0.1:4173 Log: /content/mdsite.log');
|
|
254
|
+
expect(previewRendererInBackgroundMock).toHaveBeenCalledWith('/renderer', expect.objectContaining({
|
|
255
|
+
HOST: '127.0.0.1',
|
|
256
|
+
PORT: '4173',
|
|
257
|
+
NUXT_HOST: '127.0.0.1',
|
|
258
|
+
NUXT_PORT: '4173',
|
|
259
|
+
NITRO_HOST: '127.0.0.1',
|
|
260
|
+
NITRO_PORT: '4173'
|
|
261
|
+
}), '/content/mdsite.log');
|
|
262
|
+
expect(waitForTcpPortMock).toHaveBeenCalledWith('127.0.0.1', 4173);
|
|
263
|
+
expect(openUrlInBrowserMock).toHaveBeenCalledWith('http://127.0.0.1:4173');
|
|
264
|
+
});
|
|
265
|
+
it('runPreviewCommand does not open the browser when detached preview readiness times out', async () => {
|
|
266
|
+
readRuntimeStateMock.mockResolvedValueOnce(null);
|
|
267
|
+
previewRendererInBackgroundMock.mockResolvedValueOnce(1001);
|
|
268
|
+
waitForTcpPortMock.mockResolvedValueOnce(false);
|
|
269
|
+
await expect(runPreviewCommand('/content', { detached: true })).resolves.toBe('mdsite preview running in background (PID 1001). URL: http://localhost:3000 Log: /content/mdsite.log');
|
|
270
|
+
expect(waitForTcpPortMock).toHaveBeenCalledWith('localhost', 3000);
|
|
271
|
+
expect(openUrlInBrowserMock).not.toHaveBeenCalled();
|
|
272
|
+
});
|
|
273
|
+
it('runPreviewCommand keeps succeeding when detached preview readiness checks fail', async () => {
|
|
274
|
+
readRuntimeStateMock.mockResolvedValueOnce(null);
|
|
275
|
+
previewRendererInBackgroundMock.mockResolvedValueOnce(1002);
|
|
276
|
+
waitForTcpPortMock.mockRejectedValueOnce(new Error('connect failed'));
|
|
277
|
+
await expect(runPreviewCommand('/content', { detached: true })).resolves.toBe('mdsite preview running in background (PID 1002). URL: http://localhost:3000 Log: /content/mdsite.log');
|
|
278
|
+
expect(openUrlInBrowserMock).not.toHaveBeenCalled();
|
|
279
|
+
});
|
|
280
|
+
it('runGenerateCommand syncs renderer output to the configured destination', async () => {
|
|
281
|
+
await expect(runGenerateCommand('/content')).resolves.toBe('Generated site synced to /content/public');
|
|
282
|
+
expect(generateRendererMock).toHaveBeenCalledWith('/renderer', { TEST: '1' });
|
|
283
|
+
expect(rmMock).toHaveBeenCalledWith('/content/public', { recursive: true, force: true });
|
|
284
|
+
expect(cpMock).toHaveBeenCalledWith('/renderer/.output/public', '/content/public', { recursive: true, force: true });
|
|
285
|
+
});
|
|
286
|
+
it('runGenerateCommand surfaces sync failures with the destination path', async () => {
|
|
287
|
+
cpMock.mockRejectedValueOnce(new Error('permission denied'));
|
|
288
|
+
await expect(runGenerateCommand('/content')).rejects.toThrow('Failed to sync generated output to /content/public: permission denied');
|
|
289
|
+
});
|
|
290
|
+
it('runStopCommand handles nothing-running, stopped, and stale-state cases', async () => {
|
|
291
|
+
readRuntimeStateMock.mockResolvedValueOnce(null).mockResolvedValueOnce(null);
|
|
292
|
+
await expect(runStopCommand('/content')).resolves.toBe('Nothing is running.');
|
|
293
|
+
readRuntimeStateMock
|
|
294
|
+
.mockResolvedValueOnce({ kind: 'start', pid: 11 })
|
|
295
|
+
.mockResolvedValueOnce({ kind: 'preview', pid: 22 });
|
|
296
|
+
stopProcessMock.mockResolvedValueOnce(true).mockResolvedValueOnce(false);
|
|
297
|
+
await expect(runStopCommand('/content')).resolves.toBe('Stopped start process 11. Removed stale preview state for PID 22.');
|
|
298
|
+
expect(clearRuntimeStateMock).toHaveBeenNthCalledWith(1, '/content', 'start');
|
|
299
|
+
expect(clearRuntimeStateMock).toHaveBeenNthCalledWith(2, '/content', 'preview');
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
//# sourceMappingURL=commands.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.test.js","sourceRoot":"","sources":["../../src/commands/commands.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runGenerateCommand(contentDir: string): Promise<string>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { cp, rm } from 'node:fs/promises';
|
|
2
|
+
import { loadMdsiteConfig, resolveContentOutputPath } from '../config/mdsite-config.js';
|
|
3
|
+
import { ensureRendererDependencies, generateRenderer, getRendererGeneratedOutputPath, prepareRenderer } from '../renderer/mdsite-nuxt.js';
|
|
4
|
+
export async function runGenerateCommand(contentDir) {
|
|
5
|
+
const loaded = await loadMdsiteConfig(contentDir);
|
|
6
|
+
const { rendererDir, rendererEnv } = await prepareRenderer(loaded.contentDir, loaded.config, loaded);
|
|
7
|
+
await ensureRendererDependencies(rendererDir);
|
|
8
|
+
await generateRenderer(rendererDir, rendererEnv);
|
|
9
|
+
const rendererOutputPath = getRendererGeneratedOutputPath(rendererDir);
|
|
10
|
+
const destinationOutputPath = resolveContentOutputPath(loaded.configDir, loaded.config);
|
|
11
|
+
try {
|
|
12
|
+
await rm(destinationOutputPath, { recursive: true, force: true });
|
|
13
|
+
await cp(rendererOutputPath, destinationOutputPath, { recursive: true, force: true });
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
throw new Error(`Failed to sync generated output to ${destinationOutputPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
17
|
+
}
|
|
18
|
+
return `Generated site synced to ${destinationOutputPath}`;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAA;AAEzC,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AACvF,OAAO,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,8BAA8B,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAE1I,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,UAAkB;IACzD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAA;IACjD,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEpG,MAAM,0BAA0B,CAAC,WAAW,CAAC,CAAA;IAC7C,MAAM,gBAAgB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;IAEhD,MAAM,kBAAkB,GAAG,8BAA8B,CAAC,WAAW,CAAC,CAAA;IACtE,MAAM,qBAAqB,GAAG,wBAAwB,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;IAEvF,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,qBAAqB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QACjE,MAAM,EAAE,CAAC,kBAAkB,EAAE,qBAAqB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IACvF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,sCAAsC,qBAAqB,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IAC3I,CAAC;IAED,OAAO,4BAA4B,qBAAqB,EAAE,CAAA;AAC5D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runInitCommand(contentDir: string): Promise<void>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { access, writeFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { buildDefaultMdsiteConfig, serializeMdsiteConfig } from '../config/mdsite-config.js';
|
|
4
|
+
export async function runInitCommand(contentDir) {
|
|
5
|
+
const configPath = path.join(contentDir, 'mdsite.yml');
|
|
6
|
+
try {
|
|
7
|
+
await access(configPath);
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
const config = await buildDefaultMdsiteConfig(contentDir);
|
|
11
|
+
await writeFile(configPath, serializeMdsiteConfig(config), 'utf8');
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
throw new Error(`mdsite.yml already exists at ${configPath}.`);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAE5F,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,UAAkB;IACrD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;IAEtD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,UAAU,CAAC,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,MAAM,GAAG,MAAM,wBAAwB,CAAC,UAAU,CAAC,CAAA;QACzD,MAAM,SAAS,CAAC,UAAU,EAAE,qBAAqB,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAA;QAClE,OAAM;IACR,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,gCAAgC,UAAU,GAAG,CAAC,CAAA;AAChE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runPrepareGithubCommand(contentDir: string): Promise<string>;
|