@karaoke-cms/module-docs 0.15.1 → 0.16.0
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/package.json +4 -4
- package/src/index.ts +80 -31
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.16.0",
|
|
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,13 @@
|
|
|
23
23
|
],
|
|
24
24
|
"peerDependencies": {
|
|
25
25
|
"astro": ">=6.0.0",
|
|
26
|
-
"@karaoke-cms/contracts": "^0.
|
|
26
|
+
"@karaoke-cms/contracts": "^0.16.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"astro": "^6.0.8",
|
|
30
30
|
"vitest": "^4.1.1",
|
|
31
|
-
"@karaoke-cms/astro": "0.
|
|
32
|
-
"@karaoke-cms/contracts": "0.
|
|
31
|
+
"@karaoke-cms/astro": "0.16.0",
|
|
32
|
+
"@karaoke-cms/contracts": "0.16.0"
|
|
33
33
|
},
|
|
34
34
|
"scripts": {
|
|
35
35
|
"test": "vitest run test/docs-factory.test.js"
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { ModuleInstance } from '@karaoke-cms/contracts';
|
|
1
|
+
import type { DocsSection, ModuleInstance } from '@karaoke-cms/contracts';
|
|
2
2
|
import { cssContract } from './css-contract.js';
|
|
3
3
|
|
|
4
4
|
export { cssContract } from './css-contract.js';
|
|
5
|
+
export type { DocsSection } from '@karaoke-cms/contracts';
|
|
5
6
|
// docsSchema is exported from '@karaoke-cms/module-docs/schema' to avoid
|
|
6
7
|
// pulling zod into the config-loading context.
|
|
7
8
|
|
|
@@ -24,43 +25,26 @@ export interface DocsConfig {
|
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
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
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* // karaoke.config.ts — default section
|
|
40
|
-
* import { docs } from '@karaoke-cms/module-docs';
|
|
41
|
-
* export default defineConfig({
|
|
42
|
-
* theme: themeDefault({ implements: [docs({ mount: '/docs' })] }),
|
|
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
|
-
* });
|
|
28
|
+
* Shared helper: derive mount, folder, id, and label from config fields.
|
|
29
|
+
* Used by both docsFromSingle and docsFromSection to keep derivation in sync.
|
|
51
30
|
*/
|
|
52
|
-
|
|
53
|
-
const mount = (
|
|
31
|
+
function computeDocsMeta(cfg: { mount?: string; folder?: string; id?: string; label?: string }) {
|
|
32
|
+
const mount = (cfg.mount ?? '/docs').replace(/\/$/, '');
|
|
54
33
|
const rawFolder = mount.replace(/^\//, '');
|
|
55
|
-
if (
|
|
34
|
+
if (cfg.folder === undefined && rawFolder === '') {
|
|
56
35
|
console.warn(
|
|
57
36
|
'[karaoke-cms] docs({ mount: \'/\' }): folder defaults to "docs". ' +
|
|
58
37
|
'Pass folder explicitly (e.g. docs({ mount: \'/\', folder: \'docs\' })) to suppress this warning.',
|
|
59
38
|
);
|
|
60
39
|
}
|
|
61
|
-
const folder =
|
|
62
|
-
const id =
|
|
63
|
-
const label =
|
|
40
|
+
const folder = cfg.folder ?? (rawFolder || 'docs');
|
|
41
|
+
const id = cfg.id ?? (folder.replace(/\//g, '-') || 'docs');
|
|
42
|
+
const label = cfg.label ?? id.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
|
|
43
|
+
return { mount, folder, id, label };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function docsFromSingle(config: DocsConfig = {}): ModuleInstance {
|
|
47
|
+
const { mount, folder, id, label } = computeDocsMeta(config);
|
|
64
48
|
return {
|
|
65
49
|
_type: 'module-instance',
|
|
66
50
|
id,
|
|
@@ -82,3 +66,68 @@ export function docs(config: DocsConfig = {}): ModuleInstance {
|
|
|
82
66
|
scaffoldPages: undefined,
|
|
83
67
|
};
|
|
84
68
|
}
|
|
69
|
+
|
|
70
|
+
function docsFromSection(s: DocsSection): ModuleInstance {
|
|
71
|
+
const { mount, folder, id, label } = computeDocsMeta(s);
|
|
72
|
+
return {
|
|
73
|
+
_type: 'module-instance',
|
|
74
|
+
id,
|
|
75
|
+
mount,
|
|
76
|
+
enabled: true,
|
|
77
|
+
collection: {
|
|
78
|
+
name: id,
|
|
79
|
+
folder,
|
|
80
|
+
label,
|
|
81
|
+
layout: s.layout ?? 'default',
|
|
82
|
+
sidebarStyle: s.sidebarStyle ?? 'tree',
|
|
83
|
+
},
|
|
84
|
+
// routes is empty — karaoke() generates per-instance pages via codegen
|
|
85
|
+
routes: [],
|
|
86
|
+
menuEntries: [{
|
|
87
|
+
id,
|
|
88
|
+
name: label,
|
|
89
|
+
path: mount,
|
|
90
|
+
section: 'main',
|
|
91
|
+
weight: s.weight ?? 20,
|
|
92
|
+
...(s.parent !== undefined ? { parent: s.parent } : {}),
|
|
93
|
+
}],
|
|
94
|
+
cssContract,
|
|
95
|
+
hasDefaultCss: false,
|
|
96
|
+
defaultCssPath: undefined,
|
|
97
|
+
scaffoldPages: undefined,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Docs module — documentation pages with sidebar navigation.
|
|
103
|
+
*
|
|
104
|
+
* Single-form: returns one ModuleInstance.
|
|
105
|
+
* Array-form: accepts DocsSection[] and returns ModuleInstance[] (one per active section).
|
|
106
|
+
* Sections with `enabled: false` are excluded from the returned array.
|
|
107
|
+
*
|
|
108
|
+
* Publishes three routes per instance:
|
|
109
|
+
* - `{mount}` — home page listing all doc titles
|
|
110
|
+
* - `{mount}/list` — standalone full docs list
|
|
111
|
+
* - `{mount}/[slug]` — individual doc with left-sidebar nav
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* // karaoke.config.ts — single section
|
|
115
|
+
* modules: [docs({ mount: '/docs' })]
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* // karaoke.config.ts — multiple sections with menu ordering
|
|
119
|
+
* modules: [
|
|
120
|
+
* docs([
|
|
121
|
+
* { id: 'docs', mount: '/docs', label: 'Docs', weight: 20 },
|
|
122
|
+
* { id: 'api-docs', mount: '/api-docs', folder: 'api-reference', label: 'API Reference', weight: 25, parent: 'docs' },
|
|
123
|
+
* ]),
|
|
124
|
+
* ]
|
|
125
|
+
*/
|
|
126
|
+
export function docs(config: DocsSection[]): ModuleInstance[];
|
|
127
|
+
export function docs(config?: DocsConfig): ModuleInstance;
|
|
128
|
+
export function docs(config?: DocsConfig | DocsSection[]): ModuleInstance | ModuleInstance[] {
|
|
129
|
+
if (Array.isArray(config)) {
|
|
130
|
+
return config.filter(s => s.enabled !== false).map(s => docsFromSection(s));
|
|
131
|
+
}
|
|
132
|
+
return docsFromSingle(config);
|
|
133
|
+
}
|