@karaoke-cms/module-docs 0.9.7 → 0.10.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 +41 -10
- package/package.json +8 -6
- package/src/css-contract.ts +26 -16
- package/src/index.ts +68 -24
- package/src/pages/doc.astro +2 -1
package/README.md
CHANGED
|
@@ -49,19 +49,50 @@ All routes are relative to `mount`:
|
|
|
49
49
|
|
|
50
50
|
```yaml
|
|
51
51
|
---
|
|
52
|
-
title: "Getting Started"
|
|
53
|
-
publish: true
|
|
54
|
-
date: 2026-01-15
|
|
55
|
-
author: "Name"
|
|
56
|
-
featured_image: "img/hero.jpg"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
title: "Getting Started" # required
|
|
53
|
+
publish: true # required to appear on site
|
|
54
|
+
date: 2026-01-15 # optional — YYYY-MM-DD
|
|
55
|
+
author: "Name" # optional — string or array
|
|
56
|
+
featured_image: "img/hero.jpg" # optional — relative path, absolute path, URL,
|
|
57
|
+
# or Obsidian wiki link: "[[hero.jpg]]"
|
|
58
|
+
description: "..." # optional — OG tags, AI-enriched
|
|
59
|
+
tags: [setup, guide] # optional — AI-enriched
|
|
60
|
+
reading_time: 3 # optional — AI-enriched, minutes
|
|
61
|
+
related: [slug-a, slug-b] # optional — AI-enriched, slugs
|
|
62
|
+
comments: false # optional — per-doc Giscus override (off by default)
|
|
62
63
|
---
|
|
63
64
|
```
|
|
64
65
|
|
|
66
|
+
### `featured_image` formats
|
|
67
|
+
|
|
68
|
+
All of the following work in `featured_image`:
|
|
69
|
+
|
|
70
|
+
```yaml
|
|
71
|
+
featured_image: "./images/hero.jpg" # relative to the note
|
|
72
|
+
featured_image: "/docs/hero.jpg" # vault-absolute path
|
|
73
|
+
featured_image: "https://example.com/x.jpg" # remote URL
|
|
74
|
+
featured_image: "[[hero.jpg]]" # Obsidian wiki link — resolved via vault lookup
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
When using a wiki link, the image is served from `/media/` during dev and copied to `dist/media/` at build.
|
|
78
|
+
|
|
79
|
+
## What's new in 0.10.3
|
|
80
|
+
|
|
81
|
+
- **Warning for `mount: '/'`** — calling `docs({ mount: '/' })` without an explicit `folder` now prints a warning, because the folder silently defaults to `"docs"` in this case. Pass `folder` explicitly to suppress it: `docs({ mount: '/', folder: 'docs' })`.
|
|
82
|
+
|
|
83
|
+
## What's new in 0.10.2
|
|
84
|
+
|
|
85
|
+
- **Multiple named docs sections** — call `docs()` multiple times with different `mount`, `folder`, and `label` values to create independent docs areas from separate vault folders.
|
|
86
|
+
- **`folder` option** — map a docs instance to any vault subfolder (defaults to the mount path without the leading slash).
|
|
87
|
+
- **`id` option** — override the Astro collection name (defaults to folder path, slashes replaced with hyphens).
|
|
88
|
+
- **`label` option** — set a human-readable section title shown in navigation and page headings (defaults to id in Title Case).
|
|
89
|
+
- **Section switcher** — when two or more sections are active, a nav row appears above the sidebar so readers can jump between sections.
|
|
90
|
+
- **Auto-registered collections** — pass your full karaoke config to `makeCollections({ config })` in `content.config.ts` and every docs instance registers automatically. No manual changes needed when adding a second section.
|
|
91
|
+
|
|
92
|
+
## What's new in 0.10.0
|
|
93
|
+
|
|
94
|
+
- **`[[wiki link]]` in `featured_image`** — `featured_image: "[[hero.jpg]]"` now works on doc pages; images are resolved via vault path lookup and served from `/media/`
|
|
95
|
+
|
|
65
96
|
## What's new in 0.9.5
|
|
66
97
|
|
|
67
98
|
- **`featured_image` support** added to the docs schema
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@karaoke-cms/module-docs",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.10.3",
|
|
5
5
|
"description": "Docs module for karaoke-cms — documentation pages with sidebar navigation",
|
|
6
6
|
"main": "./src/index.ts",
|
|
7
7
|
"exports": {
|
|
@@ -23,13 +23,15 @@
|
|
|
23
23
|
],
|
|
24
24
|
"peerDependencies": {
|
|
25
25
|
"astro": ">=6.0.0",
|
|
26
|
-
"@karaoke-cms/
|
|
26
|
+
"@karaoke-cms/contracts": "^0.10.3"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"
|
|
30
|
-
"
|
|
29
|
+
"astro": "^6.0.8",
|
|
30
|
+
"vitest": "^4.1.1",
|
|
31
|
+
"@karaoke-cms/astro": "0.10.3",
|
|
32
|
+
"@karaoke-cms/contracts": "0.10.3"
|
|
31
33
|
},
|
|
32
34
|
"scripts": {
|
|
33
|
-
"test": "
|
|
35
|
+
"test": "vitest run test/docs-factory.test.js"
|
|
34
36
|
}
|
|
35
|
-
}
|
|
37
|
+
}
|
package/src/css-contract.ts
CHANGED
|
@@ -1,20 +1,30 @@
|
|
|
1
|
+
import type { CssContract } from '@karaoke-cms/contracts';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* CSS class names the docs module promises to use in its markup.
|
|
3
5
|
* Themes implement these classes to style the docs section.
|
|
6
|
+
*
|
|
7
|
+
* `required: true` — the theme MUST implement this class.
|
|
8
|
+
* `required: false` — optional / progressive enhancement.
|
|
4
9
|
*/
|
|
5
|
-
export const cssContract =
|
|
6
|
-
|
|
7
|
-
'docs-home
|
|
8
|
-
'docs-home-
|
|
9
|
-
'docs-
|
|
10
|
-
|
|
11
|
-
'docs-
|
|
12
|
-
'docs-
|
|
13
|
-
|
|
14
|
-
'docs-article
|
|
15
|
-
'docs-
|
|
16
|
-
'docs-
|
|
17
|
-
'docs-
|
|
18
|
-
|
|
19
|
-
'docs-
|
|
20
|
-
|
|
10
|
+
export const cssContract: CssContract = {
|
|
11
|
+
// Home / overview
|
|
12
|
+
'docs-home': { description: 'Docs home page wrapper', required: true },
|
|
13
|
+
'docs-home-list': { description: 'List of doc links on the home page', required: true },
|
|
14
|
+
'docs-home-item': { description: 'Individual doc link on the home page', required: true },
|
|
15
|
+
// Full list page
|
|
16
|
+
'docs-list': { description: 'Full docs listing page wrapper', required: false },
|
|
17
|
+
'docs-list-item': { description: 'Individual row in the full docs list', required: false },
|
|
18
|
+
// Article page
|
|
19
|
+
'docs-article': { description: 'Individual doc article wrapper', required: true },
|
|
20
|
+
'docs-article-image': { description: 'Featured image inside a doc article', required: false },
|
|
21
|
+
'docs-article-title': { description: 'Doc article title', required: true },
|
|
22
|
+
'docs-article-meta': { description: 'Date/author meta row on a doc article', required: false },
|
|
23
|
+
// Tags
|
|
24
|
+
'docs-tag': { description: 'Tag chip on doc card or article', required: false },
|
|
25
|
+
'docs-tag-list': { description: 'Wrapper around a list of doc tag chips', required: false },
|
|
26
|
+
// Sidebar navigation
|
|
27
|
+
'docs-sidebar': { description: 'Sidebar nav wrapper', required: true },
|
|
28
|
+
'docs-sidebar-list': { description: 'List of nav links inside the sidebar', required: true },
|
|
29
|
+
'docs-sidebar-item': { description: 'Individual nav link in the sidebar', required: true },
|
|
30
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -1,40 +1,84 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ModuleInstance } from '@karaoke-cms/contracts';
|
|
2
2
|
import { cssContract } from './css-contract.js';
|
|
3
3
|
|
|
4
4
|
export { cssContract } from './css-contract.js';
|
|
5
5
|
// docsSchema is exported from '@karaoke-cms/module-docs/schema' to avoid
|
|
6
6
|
// pulling zod into the config-loading context.
|
|
7
7
|
|
|
8
|
+
export interface DocsConfig {
|
|
9
|
+
/** Mount path for this docs section. Default: '/docs'. */
|
|
10
|
+
mount?: string;
|
|
11
|
+
/** Vault subfolder containing the docs markdown files. Default: mount path without leading slash. */
|
|
12
|
+
folder?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Unique identifier for this docs instance. Used as the Astro collection name.
|
|
15
|
+
* Default: folder path with slashes replaced by hyphens.
|
|
16
|
+
*/
|
|
17
|
+
id?: string;
|
|
18
|
+
/** Human-readable label shown in navigation and page titles. Default: id in Title Case. */
|
|
19
|
+
label?: string;
|
|
20
|
+
/** When false, this instance is excluded from the build. Default: true. */
|
|
21
|
+
enabled?: boolean;
|
|
22
|
+
layout?: string;
|
|
23
|
+
sidebarStyle?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
8
26
|
/**
|
|
9
27
|
* Docs module — documentation pages with sidebar navigation.
|
|
10
28
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
29
|
+
* Returns a ModuleInstance that karaoke() uses to code-generate per-instance
|
|
30
|
+
* .astro page files and inject them as routes. Multiple instances may be
|
|
31
|
+
* configured to serve separate docs sections from different vault folders.
|
|
32
|
+
*
|
|
33
|
+
* Publishes three routes per instance:
|
|
34
|
+
* - `{mount}` — home page listing all doc titles
|
|
35
|
+
* - `{mount}/list` — standalone full docs list
|
|
36
|
+
* - `{mount}/[slug]` — individual doc with left-sidebar nav
|
|
15
37
|
*
|
|
16
38
|
* @example
|
|
17
|
-
* // karaoke.config.ts
|
|
39
|
+
* // karaoke.config.ts — default section
|
|
18
40
|
* import { docs } from '@karaoke-cms/module-docs';
|
|
19
41
|
* export default defineConfig({
|
|
20
|
-
* modules: [docs({ mount: '/docs' })],
|
|
21
42
|
* theme: themeDefault({ implements: [docs({ mount: '/docs' })] }),
|
|
22
43
|
* });
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* // karaoke.config.ts — two independent sections
|
|
47
|
+
* export default defineConfig({
|
|
48
|
+
* theme: themeDefault({ implements: [docs({ mount: '/docs' })] }),
|
|
49
|
+
* modules: [docs({ mount: '/api-docs', folder: 'api-reference', label: 'API Reference' })],
|
|
50
|
+
* });
|
|
23
51
|
*/
|
|
24
|
-
export
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
52
|
+
export function docs(config: DocsConfig = {}): ModuleInstance {
|
|
53
|
+
const mount = (config.mount ?? '/docs').replace(/\/$/, '');
|
|
54
|
+
const rawFolder = mount.replace(/^\//, '');
|
|
55
|
+
if (config.folder === undefined && rawFolder === '') {
|
|
56
|
+
console.warn(
|
|
57
|
+
'[karaoke-cms] docs({ mount: \'/\' }): folder defaults to "docs". ' +
|
|
58
|
+
'Pass folder explicitly (e.g. docs({ mount: \'/\', folder: \'docs\' })) to suppress this warning.',
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
const folder = config.folder ?? (rawFolder || 'docs');
|
|
62
|
+
const id = config.id ?? (folder.replace(/\//g, '-') || 'docs');
|
|
63
|
+
const label = config.label ?? (id.charAt(0).toUpperCase() + id.slice(1).replace(/-/g, ' '));
|
|
64
|
+
return {
|
|
65
|
+
_type: 'module-instance',
|
|
66
|
+
id,
|
|
67
|
+
mount,
|
|
68
|
+
enabled: config.enabled ?? true,
|
|
69
|
+
collection: {
|
|
70
|
+
name: id,
|
|
71
|
+
folder,
|
|
72
|
+
label,
|
|
73
|
+
layout: config.layout ?? 'default',
|
|
74
|
+
sidebarStyle: config.sidebarStyle ?? 'tree',
|
|
75
|
+
},
|
|
76
|
+
// routes is empty — karaoke() generates per-instance pages via codegen
|
|
77
|
+
routes: [],
|
|
78
|
+
menuEntries: [{ id, name: label, path: mount, section: 'main', weight: 20 }],
|
|
79
|
+
cssContract,
|
|
80
|
+
hasDefaultCss: false,
|
|
81
|
+
defaultCssPath: undefined,
|
|
82
|
+
scaffoldPages: undefined,
|
|
83
|
+
};
|
|
84
|
+
}
|
package/src/pages/doc.astro
CHANGED
|
@@ -5,6 +5,7 @@ import { getCollection, render } from 'astro:content';
|
|
|
5
5
|
import DefaultPage from '@karaoke-cms/astro/layouts/DefaultPage.astro';
|
|
6
6
|
import ModuleLoader from '@karaoke-cms/astro/components/ModuleLoader.astro';
|
|
7
7
|
import { siteTitle } from 'virtual:karaoke-cms/config';
|
|
8
|
+
import { resolveWikiImage } from '@karaoke-cms/astro';
|
|
8
9
|
|
|
9
10
|
export async function getStaticPaths() {
|
|
10
11
|
const docs = await getCollection('docs', ({ data }) => data.publish === true);
|
|
@@ -36,7 +37,7 @@ const allDocs = (await getCollection('docs', ({ data }) => data.publish === true
|
|
|
36
37
|
</nav>
|
|
37
38
|
<article class="docs-article">
|
|
38
39
|
{entry.data.featured_image && (
|
|
39
|
-
<img src={entry.data.featured_image} alt="" class="docs-article-image" />
|
|
40
|
+
<img src={resolveWikiImage(entry.data.featured_image)} alt="" class="docs-article-image" />
|
|
40
41
|
)}
|
|
41
42
|
<h1 class="docs-article-title">{entry.data.title}</h1>
|
|
42
43
|
{entry.data.tags && entry.data.tags.length > 0 && (
|