undocs 0.4.10 → 0.4.12
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/app/app.config.ts +2 -0
- package/app/app.vue +3 -0
- package/app/components/AppHeader.vue +12 -5
- package/app/components/AppHeaderVersionsMenu.vue +47 -0
- package/app/components/PageHeaderLinks.vue +70 -0
- package/app/modules/content/hooks.ts +2 -2
- package/app/modules/md-rewrite.ts +32 -0
- package/app/nuxt.config.ts +1 -1
- package/app/pages/[...slug].vue +25 -1
- package/app/server/routes/raw/[...slug].md.get.ts +26 -0
- package/cli/cli.mjs +8 -4
- package/cli/setup.mjs +16 -0
- package/package.json +28 -28
- package/schema/config.d.ts +10 -0
- package/schema/config.json +197 -0
package/app/app.config.ts
CHANGED
package/app/app.vue
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import type { BannerProps } from '@nuxt/ui'
|
|
3
|
+
|
|
2
4
|
const appConfig = useAppConfig()
|
|
3
5
|
|
|
4
6
|
const { data: navigation } = await useAsyncData('navigation', () => queryCollectionNavigation('content'))
|
|
@@ -52,6 +54,7 @@ provide('navigation', navigation)
|
|
|
52
54
|
<template>
|
|
53
55
|
<UApp>
|
|
54
56
|
<NuxtLoadingIndicator color="var(--ui-primary)" />
|
|
57
|
+
<UBanner v-if="appConfig.docs.banner?.title" v-bind="appConfig.docs.banner as BannerProps" />
|
|
55
58
|
<AppHeader />
|
|
56
59
|
|
|
57
60
|
<UMain>
|
|
@@ -41,11 +41,18 @@ const mobileLinks = computed(() => {
|
|
|
41
41
|
|
|
42
42
|
<template>
|
|
43
43
|
<UHeader to="/">
|
|
44
|
-
<template #
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
<template #left>
|
|
45
|
+
<NuxtLink
|
|
46
|
+
to="/"
|
|
47
|
+
class="focus-visible:outline-primary shrink-0 font-bold text-xl text-highlighted flex items-end gap-1.5"
|
|
48
|
+
:aria-label="appConfig.site.name"
|
|
49
|
+
>
|
|
50
|
+
<img :src="appConfig.docs.logo" :alt="`${appConfig.site.name} logo`" class="h-7 w-7" />
|
|
51
|
+
<span>
|
|
52
|
+
{{ appConfig.site.name }}
|
|
53
|
+
</span>
|
|
54
|
+
</NuxtLink>
|
|
55
|
+
<AppHeaderVersionsMenu v-if="appConfig.docs.versions?.length" />
|
|
49
56
|
</template>
|
|
50
57
|
|
|
51
58
|
<UNavigationMenu v-if="headerLinks.length > 1" :items="headerLinks" variant="link" />
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const appConfig = useAppConfig()
|
|
3
|
+
|
|
4
|
+
const activeVersion = computed(() => {
|
|
5
|
+
return appConfig.docs.versions.find((version) => version.active) || appConfig.docs.versions[0]
|
|
6
|
+
})
|
|
7
|
+
const items = computed(() => {
|
|
8
|
+
return appConfig.docs.versions.map((version) => {
|
|
9
|
+
if (activeVersion.value === version) {
|
|
10
|
+
return {
|
|
11
|
+
label: version.label,
|
|
12
|
+
type: 'checkbox' as const,
|
|
13
|
+
color: 'primary' as const,
|
|
14
|
+
checked: true,
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
label: version.label,
|
|
19
|
+
to: version.to,
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
})
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<template>
|
|
26
|
+
<UDropdownMenu
|
|
27
|
+
v-slot="{ open }"
|
|
28
|
+
:modal="false"
|
|
29
|
+
:items="items"
|
|
30
|
+
:content="{ align: 'start' }"
|
|
31
|
+
:ui="{ content: 'min-w-fit' }"
|
|
32
|
+
size="xs"
|
|
33
|
+
class="ml-1"
|
|
34
|
+
>
|
|
35
|
+
<UButton
|
|
36
|
+
:label="activeVersion?.label"
|
|
37
|
+
variant="subtle"
|
|
38
|
+
trailing-icon="i-lucide-chevron-down"
|
|
39
|
+
size="xs"
|
|
40
|
+
class="-mb-[6px] font-semibold rounded-full truncate"
|
|
41
|
+
:class="[open && 'bg-primary/15']"
|
|
42
|
+
:ui="{
|
|
43
|
+
trailingIcon: ['transition-transform duration-200', open ? 'rotate-180' : undefined].filter(Boolean).join(' '),
|
|
44
|
+
}"
|
|
45
|
+
/>
|
|
46
|
+
</UDropdownMenu>
|
|
47
|
+
</template>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useClipboard } from '@vueuse/core'
|
|
3
|
+
import { useRuntimeConfig } from '#imports'
|
|
4
|
+
|
|
5
|
+
const route = useRoute()
|
|
6
|
+
const appBaseURL = useRuntimeConfig().app?.baseURL || '/'
|
|
7
|
+
|
|
8
|
+
const { copy, copied } = useClipboard()
|
|
9
|
+
|
|
10
|
+
const markdownLink = computed(() => `${window?.location?.origin}${appBaseURL}raw${route.path}.md`)
|
|
11
|
+
const items = [
|
|
12
|
+
{
|
|
13
|
+
label: 'Copy Markdown Link',
|
|
14
|
+
icon: 'i-lucide-link',
|
|
15
|
+
onSelect() {
|
|
16
|
+
copy(markdownLink.value)
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
label: 'View as Markdown',
|
|
21
|
+
icon: 'i-simple-icons:markdown',
|
|
22
|
+
target: '_blank',
|
|
23
|
+
to: markdownLink.value,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
label: 'Open in ChatGPT',
|
|
27
|
+
icon: 'i-simple-icons:openai',
|
|
28
|
+
target: '_blank',
|
|
29
|
+
to: `https://chatgpt.com/?hints=search&q=${encodeURIComponent(`Read ${markdownLink.value} so I can ask questions about it.`)}`,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
label: 'Open in Claude',
|
|
33
|
+
icon: 'i-simple-icons:anthropic',
|
|
34
|
+
target: '_blank',
|
|
35
|
+
to: `https://claude.ai/new?q=${encodeURIComponent(`Read ${markdownLink.value} so I can ask questions about it.`)}`,
|
|
36
|
+
},
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
async function copyPage() {
|
|
40
|
+
const page = await $fetch<string>(`/raw${route.path}.md`)
|
|
41
|
+
copy(page)
|
|
42
|
+
}
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<template>
|
|
46
|
+
<UFieldGroup size="sm">
|
|
47
|
+
<UButton
|
|
48
|
+
label="Copy Page"
|
|
49
|
+
:icon="copied ? 'i-lucide-check' : 'i-lucide-copy'"
|
|
50
|
+
color="neutral"
|
|
51
|
+
variant="soft"
|
|
52
|
+
:ui="{
|
|
53
|
+
leadingIcon: 'text-neutral size-3.5',
|
|
54
|
+
}"
|
|
55
|
+
@click="copyPage"
|
|
56
|
+
/>
|
|
57
|
+
|
|
58
|
+
<UDropdownMenu
|
|
59
|
+
size="sm"
|
|
60
|
+
:items="items"
|
|
61
|
+
:content="{
|
|
62
|
+
align: 'end',
|
|
63
|
+
side: 'bottom',
|
|
64
|
+
sideOffset: 8,
|
|
65
|
+
}"
|
|
66
|
+
>
|
|
67
|
+
<UButton icon="i-lucide-chevron-down" color="neutral" variant="soft" class="border-l border-muted" />
|
|
68
|
+
</UDropdownMenu>
|
|
69
|
+
</UFieldGroup>
|
|
70
|
+
</template>
|
|
@@ -116,8 +116,8 @@ function transformMermaid(node: MinimarkNode) {
|
|
|
116
116
|
node[0] = 'mermaid'
|
|
117
117
|
// @ts-expect-error
|
|
118
118
|
node[1] = { code: node[1].code || '' }
|
|
119
|
-
//
|
|
120
|
-
node
|
|
119
|
+
// Remove all children (splice instead of node[2] = [] which would create an invalid empty array child)
|
|
120
|
+
node.splice(2)
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { NitroModule } from 'nitropack'
|
|
2
|
+
import { resolve } from 'node:path'
|
|
3
|
+
import { readFile, writeFile } from 'node:fs/promises'
|
|
4
|
+
|
|
5
|
+
import { defineNuxtModule } from 'nuxt/kit'
|
|
6
|
+
|
|
7
|
+
export default defineNuxtModule((_options, nuxt) => {
|
|
8
|
+
nuxt.options.nitro.modules ??= []
|
|
9
|
+
nuxt.options.nitro.modules.push(mdRewrite())
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
function mdRewrite(): NitroModule {
|
|
13
|
+
return {
|
|
14
|
+
name: 'markdown-rewrite',
|
|
15
|
+
setup(nitro) {
|
|
16
|
+
if (nitro.options.dev || !nitro.options.preset.includes('vercel')) {
|
|
17
|
+
return
|
|
18
|
+
}
|
|
19
|
+
nitro.hooks.hook('compiled', async () => {
|
|
20
|
+
const vcJSON = resolve(nitro.options.output.dir, 'config.json')
|
|
21
|
+
const vcConfig = JSON.parse(await readFile(vcJSON, 'utf8'))
|
|
22
|
+
vcConfig.routes.unshift({
|
|
23
|
+
src: '^/(.*)$',
|
|
24
|
+
dest: '/raw/$1.md',
|
|
25
|
+
has: [{ type: 'header', key: 'accept', value: '(.*)text/markdown(.*)' }],
|
|
26
|
+
check: true,
|
|
27
|
+
})
|
|
28
|
+
await writeFile(vcJSON, JSON.stringify(vcConfig, null, 2), 'utf8')
|
|
29
|
+
})
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
}
|
package/app/nuxt.config.ts
CHANGED
|
@@ -16,7 +16,7 @@ export default defineNuxtConfig({
|
|
|
16
16
|
name: 'undocs',
|
|
17
17
|
},
|
|
18
18
|
ssr,
|
|
19
|
-
modules: ['@nuxt/ui', '@nuxt/content', isProd && '@nuxtjs/plausible'],
|
|
19
|
+
modules: ['@nuxt/ui', '@nuxt/content', isProd && '@nuxtjs/plausible', 'nuxt-llms'],
|
|
20
20
|
css: [resolve('./assets/main.css')],
|
|
21
21
|
ui: {
|
|
22
22
|
theme: {
|
package/app/pages/[...slug].vue
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { joinURL } from 'ufo'
|
|
2
3
|
import { kebabCase } from 'scule'
|
|
3
4
|
import type { ContentNavigationItem } from '@nuxt/content'
|
|
4
5
|
|
|
@@ -56,14 +57,37 @@ usePageSEO({
|
|
|
56
57
|
ogTitle: page.value?.title,
|
|
57
58
|
description: page.value?.description,
|
|
58
59
|
})
|
|
60
|
+
|
|
61
|
+
const path = computed(() => route.path.replace(/\/$/, ''))
|
|
62
|
+
prerenderRoutes([joinURL('/raw', `${path.value}.md`)])
|
|
63
|
+
useHead({
|
|
64
|
+
link: [
|
|
65
|
+
{
|
|
66
|
+
rel: 'alternate',
|
|
67
|
+
href: joinURL(appConfig.site.url, 'raw', `${path.value}.md`),
|
|
68
|
+
type: 'text/markdown',
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
})
|
|
59
72
|
</script>
|
|
60
73
|
|
|
61
74
|
<template>
|
|
62
75
|
<UPage v-if="page">
|
|
63
|
-
<UPageHeader
|
|
76
|
+
<UPageHeader
|
|
77
|
+
:title="page.title"
|
|
78
|
+
:description="page.description"
|
|
79
|
+
:ui="{
|
|
80
|
+
wrapper: 'flex-row items-center flex-wrap justify-between',
|
|
81
|
+
}"
|
|
82
|
+
>
|
|
64
83
|
<template #headline>
|
|
65
84
|
<UBreadcrumb :items="breadcrumb" />
|
|
66
85
|
</template>
|
|
86
|
+
<template #links>
|
|
87
|
+
<UButton v-for="(link, index) in page.links" :key="index" size="sm" v-bind="link" />
|
|
88
|
+
|
|
89
|
+
<PageHeaderLinks />
|
|
90
|
+
</template>
|
|
67
91
|
</UPageHeader>
|
|
68
92
|
|
|
69
93
|
<template v-if="page.body?.toc?.links?.length" #right>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { queryCollection } from '@nuxt/content/server'
|
|
2
|
+
import { stringify } from 'minimark/stringify'
|
|
3
|
+
import { withLeadingSlash } from 'ufo'
|
|
4
|
+
|
|
5
|
+
export default eventHandler(async (event) => {
|
|
6
|
+
const slug = getRouterParams(event)['slug.md']
|
|
7
|
+
if (!slug?.endsWith('.md')) {
|
|
8
|
+
throw createError({ statusCode: 404, statusMessage: 'Page not found', fatal: true })
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const path = withLeadingSlash(slug.replace('.md', ''))
|
|
12
|
+
|
|
13
|
+
const page = await queryCollection(event, 'content').path(path).first()
|
|
14
|
+
if (!page) {
|
|
15
|
+
throw createError({ statusCode: 404, statusMessage: 'Page not found', fatal: true })
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Add title and description to the top of the page if missing
|
|
19
|
+
if (page.body.value[0]?.[0] !== 'h1') {
|
|
20
|
+
page.body.value.unshift(['blockquote', {}, page.description])
|
|
21
|
+
page.body.value.unshift(['h1', {}, page.title])
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
setHeader(event, 'Content-Type', 'text/markdown; charset=utf-8')
|
|
25
|
+
return stringify({ ...page.body, type: 'minimark' }, { format: 'markdown/html' })
|
|
26
|
+
})
|
package/cli/cli.mjs
CHANGED
|
@@ -58,8 +58,11 @@ export function createCLI(opts) {
|
|
|
58
58
|
process.chdir(appDir)
|
|
59
59
|
process.on('exit', () => unwatch())
|
|
60
60
|
|
|
61
|
-
const { runCommand } = await import('nuxi')
|
|
62
|
-
|
|
61
|
+
const { runCommand, main } = await import('nuxi')
|
|
62
|
+
const cmd = await main.subCommands.dev()
|
|
63
|
+
await runCommand(cmd, [appDir, '--no-fork', '--port', process.env.PORT || '4000'], {
|
|
64
|
+
overrides: nuxtConfig,
|
|
65
|
+
})
|
|
63
66
|
},
|
|
64
67
|
})
|
|
65
68
|
|
|
@@ -74,8 +77,9 @@ export function createCLI(opts) {
|
|
|
74
77
|
|
|
75
78
|
process.chdir(appDir)
|
|
76
79
|
|
|
77
|
-
const { runCommand } = await import('nuxi')
|
|
78
|
-
|
|
80
|
+
const { runCommand, main } = await import('nuxi')
|
|
81
|
+
const cmd = await main.subCommands.generate()
|
|
82
|
+
await runCommand(cmd, [appDir], { overrides: nuxtConfig })
|
|
79
83
|
},
|
|
80
84
|
})
|
|
81
85
|
|
package/cli/setup.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { resolve } from 'node:path'
|
|
|
3
3
|
import { existsSync } from 'node:fs'
|
|
4
4
|
import { execSync } from 'node:child_process'
|
|
5
5
|
import { loadConfig, watchConfig } from 'c12'
|
|
6
|
+
import { defu } from 'defu'
|
|
6
7
|
|
|
7
8
|
const appDir = fileURLToPath(new URL('../app', import.meta.url))
|
|
8
9
|
|
|
@@ -80,6 +81,16 @@ export async function setupDocs(docsDir, opts = {}) {
|
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
// Prepare loadNuxt overrides
|
|
84
|
+
const llmsConfig = defu(docsconfig.llms, {
|
|
85
|
+
domain: docsconfig.url,
|
|
86
|
+
title: docsconfig.name || '',
|
|
87
|
+
description: docsconfig.description || '',
|
|
88
|
+
full: {
|
|
89
|
+
title: docsconfig.name || '',
|
|
90
|
+
description: docsconfig.description || '',
|
|
91
|
+
},
|
|
92
|
+
})
|
|
93
|
+
|
|
83
94
|
const nuxtConfig = {
|
|
84
95
|
compatibilityDate: 'latest',
|
|
85
96
|
rootDir: docsSrcDir,
|
|
@@ -95,6 +106,8 @@ export async function setupDocs(docsDir, opts = {}) {
|
|
|
95
106
|
description: docsconfig.description || '',
|
|
96
107
|
url: docsconfig.url,
|
|
97
108
|
},
|
|
109
|
+
// @ts-ignore
|
|
110
|
+
llms: llmsConfig,
|
|
98
111
|
appConfig: {
|
|
99
112
|
site: {
|
|
100
113
|
name: docsconfig.name || '',
|
|
@@ -120,6 +133,9 @@ export async function setupDocs(docsDir, opts = {}) {
|
|
|
120
133
|
dir: resolve(docsDir, '.docs/public'),
|
|
121
134
|
},
|
|
122
135
|
],
|
|
136
|
+
prerender: {
|
|
137
|
+
routes: ['/llms.txt', '/llms-full.txt'],
|
|
138
|
+
},
|
|
123
139
|
},
|
|
124
140
|
routeRules: {
|
|
125
141
|
...Object.fromEntries(Object.entries(docsconfig.redirects || {}).map(([from, to]) => [from, { redirect: to }])),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "undocs",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.12",
|
|
4
4
|
"repository": "unjs/undocs",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -31,47 +31,47 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@headlessui/vue": "^1.7.23",
|
|
34
|
-
"@iconify-json/logos": "^1.2.
|
|
35
|
-
"@iconify-json/simple-icons": "^1.2.
|
|
36
|
-
"@nuxt/content": "^3.
|
|
37
|
-
"@nuxt/fonts": "^0.
|
|
38
|
-
"@nuxt/ui": "4.
|
|
34
|
+
"@iconify-json/logos": "^1.2.10",
|
|
35
|
+
"@iconify-json/simple-icons": "^1.2.66",
|
|
36
|
+
"@nuxt/content": "^3.10.0",
|
|
37
|
+
"@nuxt/fonts": "^0.12.1",
|
|
38
|
+
"@nuxt/ui": "4.2.0",
|
|
39
39
|
"@nuxtjs/plausible": "^2.0.1",
|
|
40
40
|
"@resvg/resvg-wasm": "^2.6.2",
|
|
41
41
|
"automd": "^0.4.2",
|
|
42
|
-
"c12": "^3.3.
|
|
42
|
+
"c12": "^3.3.3",
|
|
43
43
|
"citty": "^0.1.6",
|
|
44
44
|
"consola": "^3.4.2",
|
|
45
45
|
"defu": "^6.1.4",
|
|
46
46
|
"is-buffer": "^2.0.5",
|
|
47
47
|
"md4w": "^0.2.7",
|
|
48
|
-
"mermaid": "^11.12.
|
|
49
|
-
"motion-v": "^1.
|
|
50
|
-
"nitropack": "^2.
|
|
51
|
-
"nuxi": "^3.
|
|
52
|
-
"nuxt": "^4.
|
|
48
|
+
"mermaid": "^11.12.2",
|
|
49
|
+
"motion-v": "^1.9.0",
|
|
50
|
+
"nitropack": "^2.13.1",
|
|
51
|
+
"nuxi": "^3.32.0",
|
|
52
|
+
"nuxt": "^4.2.2",
|
|
53
53
|
"nuxt-build-cache": "^0.1.1",
|
|
54
54
|
"nuxt-llms": "^0.1.3",
|
|
55
55
|
"pkg-types": "^2.3.0",
|
|
56
56
|
"scule": "^1.3.0",
|
|
57
|
-
"shiki": "^3.
|
|
58
|
-
"tailwindcss": "^4.1.
|
|
59
|
-
"unctx": "^2.
|
|
60
|
-
"unstorage": "^1.17.
|
|
61
|
-
"vue": "^3.5.
|
|
62
|
-
"vue-router": "^4.
|
|
57
|
+
"shiki": "^3.21.0",
|
|
58
|
+
"tailwindcss": "^4.1.18",
|
|
59
|
+
"unctx": "^2.5.0",
|
|
60
|
+
"unstorage": "^1.17.4",
|
|
61
|
+
"vue": "^3.5.26",
|
|
62
|
+
"vue-router": "^4.6.4"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
|
-
"@nuxt/eslint-config": "^1.
|
|
66
|
-
"@nuxt/image": "^
|
|
67
|
-
"@types/node": "^
|
|
65
|
+
"@nuxt/eslint-config": "^1.12.1",
|
|
66
|
+
"@nuxt/image": "^2.0.0",
|
|
67
|
+
"@types/node": "^25.0.8",
|
|
68
68
|
"changelogen": "^0.6.2",
|
|
69
|
-
"eslint": "^9.
|
|
70
|
-
"eslint-config-unjs": "^0.
|
|
71
|
-
"jiti": "^2.
|
|
72
|
-
"prettier": "^3.
|
|
73
|
-
"typescript": "^5.9.
|
|
74
|
-
"vue-tsc": "^3.
|
|
69
|
+
"eslint": "^9.39.2",
|
|
70
|
+
"eslint-config-unjs": "^0.6.2",
|
|
71
|
+
"jiti": "^2.6.1",
|
|
72
|
+
"prettier": "^3.8.0",
|
|
73
|
+
"typescript": "^5.9.3",
|
|
74
|
+
"vue-tsc": "^3.2.2"
|
|
75
75
|
},
|
|
76
|
-
"packageManager": "pnpm@10.
|
|
76
|
+
"packageManager": "pnpm@10.28.0"
|
|
77
77
|
}
|
package/schema/config.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { BannerProps } from '@nuxt/ui'
|
|
2
|
+
|
|
1
3
|
export interface DocsConfig {
|
|
2
4
|
dir?: string
|
|
3
5
|
name?: string
|
|
@@ -6,7 +8,15 @@ export interface DocsConfig {
|
|
|
6
8
|
url?: string
|
|
7
9
|
github?: string
|
|
8
10
|
socials?: Record<string, string>
|
|
11
|
+
llms?: {
|
|
12
|
+
full?: {
|
|
13
|
+
title?: string
|
|
14
|
+
description?: string
|
|
15
|
+
}
|
|
16
|
+
}
|
|
9
17
|
branch?: string
|
|
18
|
+
banner?: BannerProps
|
|
19
|
+
versions?: { label: string; to: string; active?: boolean }[]
|
|
10
20
|
themeColor?: string
|
|
11
21
|
redirects?: Record<string, string>
|
|
12
22
|
automd?: unknown
|
package/schema/config.json
CHANGED
|
@@ -35,6 +35,40 @@
|
|
|
35
35
|
"type": "string",
|
|
36
36
|
"description": "The GitHub repository for the documentation site."
|
|
37
37
|
},
|
|
38
|
+
"llms": {
|
|
39
|
+
"type": "object",
|
|
40
|
+
"description": "Configuration for `nuxt-llms` generation (`/llms.txt` and `/llms-full.txt`).",
|
|
41
|
+
"additionalProperties": false,
|
|
42
|
+
"properties": {
|
|
43
|
+
"domain": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"description": "Public site domain (e.g. https://example.com)."
|
|
46
|
+
},
|
|
47
|
+
"title": {
|
|
48
|
+
"type": "string",
|
|
49
|
+
"description": "Title used in `/llms.txt`."
|
|
50
|
+
},
|
|
51
|
+
"description": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"description": "Description used in `/llms.txt`."
|
|
54
|
+
},
|
|
55
|
+
"full": {
|
|
56
|
+
"type": "object",
|
|
57
|
+
"description": "Metadata for `/llms-full.txt`.",
|
|
58
|
+
"additionalProperties": false,
|
|
59
|
+
"properties": {
|
|
60
|
+
"title": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"description": "Title used in `/llms-full.txt`."
|
|
63
|
+
},
|
|
64
|
+
"description": {
|
|
65
|
+
"type": "string",
|
|
66
|
+
"description": "Description used in `/llms-full.txt`."
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
},
|
|
38
72
|
"socials": {
|
|
39
73
|
"type": "object",
|
|
40
74
|
"description": "Social media links for the documentation site.",
|
|
@@ -55,6 +89,169 @@
|
|
|
55
89
|
"type": "string",
|
|
56
90
|
"description": "The branch of the GitHub repository for the documentation site."
|
|
57
91
|
},
|
|
92
|
+
"banner": {
|
|
93
|
+
"type": "object",
|
|
94
|
+
"description": "Banner configuration",
|
|
95
|
+
"additionalProperties": false,
|
|
96
|
+
"properties": {
|
|
97
|
+
"id": {
|
|
98
|
+
"type": "string",
|
|
99
|
+
"description": "A unique id saved to local storage to remember if the banner has been dismissed. Change this value to show the banner again."
|
|
100
|
+
},
|
|
101
|
+
"icon": {
|
|
102
|
+
"type": "string",
|
|
103
|
+
"description": "The icon displayed next to the title (e.g., 'i-lucide-info')."
|
|
104
|
+
},
|
|
105
|
+
"title": {
|
|
106
|
+
"type": "string",
|
|
107
|
+
"description": "The banner title text."
|
|
108
|
+
},
|
|
109
|
+
"actions": {
|
|
110
|
+
"type": "array",
|
|
111
|
+
"description": "Display a list of action buttons next to the title.",
|
|
112
|
+
"items": {
|
|
113
|
+
"type": "object",
|
|
114
|
+
"properties": {
|
|
115
|
+
"label": {
|
|
116
|
+
"type": "string",
|
|
117
|
+
"description": "Button label text"
|
|
118
|
+
},
|
|
119
|
+
"icon": {
|
|
120
|
+
"type": "string",
|
|
121
|
+
"description": "Button icon"
|
|
122
|
+
},
|
|
123
|
+
"to": {
|
|
124
|
+
"type": "string",
|
|
125
|
+
"description": "Button link destination"
|
|
126
|
+
},
|
|
127
|
+
"target": {
|
|
128
|
+
"type": "string",
|
|
129
|
+
"enum": ["_blank", "_parent", "_self", "_top"],
|
|
130
|
+
"description": "Link target attribute"
|
|
131
|
+
},
|
|
132
|
+
"color": {
|
|
133
|
+
"type": "string",
|
|
134
|
+
"enum": ["primary", "secondary", "success", "info", "warning", "error", "neutral"],
|
|
135
|
+
"description": "Button color"
|
|
136
|
+
},
|
|
137
|
+
"size": {
|
|
138
|
+
"type": "string",
|
|
139
|
+
"enum": ["xs", "sm", "md", "lg", "xl"],
|
|
140
|
+
"description": "Button size"
|
|
141
|
+
},
|
|
142
|
+
"variant": {
|
|
143
|
+
"type": "string",
|
|
144
|
+
"enum": ["solid", "outline", "soft", "subtle", "ghost", "link"],
|
|
145
|
+
"description": "Button variant"
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
"to": {
|
|
151
|
+
"type": "string",
|
|
152
|
+
"description": "Link destination URL or route path."
|
|
153
|
+
},
|
|
154
|
+
"target": {
|
|
155
|
+
"type": "string",
|
|
156
|
+
"enum": ["_blank", "_parent", "_self", "_top"],
|
|
157
|
+
"description": "Link target attribute."
|
|
158
|
+
},
|
|
159
|
+
"color": {
|
|
160
|
+
"type": "string",
|
|
161
|
+
"enum": ["primary", "secondary", "success", "info", "warning", "error", "neutral"],
|
|
162
|
+
"description": "Banner color theme.",
|
|
163
|
+
"default": "primary"
|
|
164
|
+
},
|
|
165
|
+
"close": {
|
|
166
|
+
"oneOf": [
|
|
167
|
+
{
|
|
168
|
+
"type": "boolean",
|
|
169
|
+
"description": "Display a close button to dismiss the banner."
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"type": "object",
|
|
173
|
+
"description": "Close button configuration.",
|
|
174
|
+
"properties": {
|
|
175
|
+
"size": {
|
|
176
|
+
"type": "string",
|
|
177
|
+
"enum": ["xs", "sm", "md", "lg", "xl"],
|
|
178
|
+
"description": "Close button size"
|
|
179
|
+
},
|
|
180
|
+
"color": {
|
|
181
|
+
"type": "string",
|
|
182
|
+
"enum": ["primary", "secondary", "success", "info", "warning", "error", "neutral"],
|
|
183
|
+
"description": "Close button color"
|
|
184
|
+
},
|
|
185
|
+
"variant": {
|
|
186
|
+
"type": "string",
|
|
187
|
+
"enum": ["solid", "outline", "soft", "subtle", "ghost", "link"],
|
|
188
|
+
"description": "Close button variant"
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
]
|
|
193
|
+
},
|
|
194
|
+
"closeIcon": {
|
|
195
|
+
"type": "string",
|
|
196
|
+
"description": "The icon displayed in the close button (e.g., 'i-lucide-x').",
|
|
197
|
+
"default": "i-lucide-x"
|
|
198
|
+
},
|
|
199
|
+
"ui": {
|
|
200
|
+
"type": "object",
|
|
201
|
+
"description": "UI customization classes for banner components.",
|
|
202
|
+
"properties": {
|
|
203
|
+
"root": {
|
|
204
|
+
"description": "Root element classes"
|
|
205
|
+
},
|
|
206
|
+
"container": {
|
|
207
|
+
"description": "Container element classes"
|
|
208
|
+
},
|
|
209
|
+
"left": {
|
|
210
|
+
"description": "Left section classes"
|
|
211
|
+
},
|
|
212
|
+
"center": {
|
|
213
|
+
"description": "Center section classes"
|
|
214
|
+
},
|
|
215
|
+
"right": {
|
|
216
|
+
"description": "Right section classes"
|
|
217
|
+
},
|
|
218
|
+
"icon": {
|
|
219
|
+
"description": "Icon element classes"
|
|
220
|
+
},
|
|
221
|
+
"title": {
|
|
222
|
+
"description": "Title element classes"
|
|
223
|
+
},
|
|
224
|
+
"actions": {
|
|
225
|
+
"description": "Actions container classes"
|
|
226
|
+
},
|
|
227
|
+
"close": {
|
|
228
|
+
"description": "Close button classes"
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
"versions": {
|
|
235
|
+
"type": "array",
|
|
236
|
+
"description": "The versions of the documentation site.",
|
|
237
|
+
"items": {
|
|
238
|
+
"type": "object",
|
|
239
|
+
"properties": {
|
|
240
|
+
"label": {
|
|
241
|
+
"type": "string",
|
|
242
|
+
"description": "The label of the version."
|
|
243
|
+
},
|
|
244
|
+
"to": {
|
|
245
|
+
"type": "string",
|
|
246
|
+
"description": "The URL to the version."
|
|
247
|
+
},
|
|
248
|
+
"active": {
|
|
249
|
+
"type": "boolean",
|
|
250
|
+
"description": "Whether the version is active on this documentation site."
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
},
|
|
58
255
|
"themeColor": {
|
|
59
256
|
"type": "string",
|
|
60
257
|
"description": "The theme color of the documentation site.\nIt will be used as the `theme-color` meta tag and a full palette of colors will be generated from it."
|