undocs 0.3.6 → 0.3.8
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/components/SocialButtons.vue +12 -20
- package/app/content.config.ts +1 -1
- package/app/layouts/docs.vue +1 -7
- package/app/modules/content/hooks.ts +47 -26
- package/app/nuxt.config.ts +1 -1
- package/package.json +3 -2
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
const appConfig = useAppConfig()
|
|
3
3
|
|
|
4
|
-
// const props = defineProps({
|
|
5
|
-
// socials: {
|
|
6
|
-
// type: Array,
|
|
7
|
-
// required: false,
|
|
8
|
-
// default: () => ['github', 'twitter', 'discord'],
|
|
9
|
-
// },
|
|
10
|
-
// })
|
|
11
|
-
|
|
12
4
|
const socialLinks = computed(() => {
|
|
13
5
|
return (
|
|
14
6
|
Object.entries({ github: appConfig.docs.github, ...appConfig.docs.socials })
|
|
@@ -22,7 +14,7 @@ const socialLinks = computed(() => {
|
|
|
22
14
|
return {
|
|
23
15
|
// Workaround: i-simple-icons-x i-simple-icons-github
|
|
24
16
|
icon: `i-simple-icons-${key}`,
|
|
25
|
-
label:
|
|
17
|
+
label: titleCase(key),
|
|
26
18
|
to: /^https?:\/\//.test(value) ? value : `https://${key}.com/${value}`,
|
|
27
19
|
}
|
|
28
20
|
}
|
|
@@ -33,15 +25,15 @@ const socialLinks = computed(() => {
|
|
|
33
25
|
})
|
|
34
26
|
</script>
|
|
35
27
|
<template>
|
|
36
|
-
<
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
28
|
+
<UTooltip v-for="link of socialLinks" :key="link.label" :text="link.label">
|
|
29
|
+
<UButton
|
|
30
|
+
:aria-label="link.label"
|
|
31
|
+
:icon="link.icon"
|
|
32
|
+
:to="link.to"
|
|
33
|
+
target="_blank"
|
|
34
|
+
rel="noopener noreferrer"
|
|
35
|
+
color="neutral"
|
|
36
|
+
variant="ghost"
|
|
37
|
+
/>
|
|
38
|
+
</UTooltip>
|
|
47
39
|
</template>
|
package/app/content.config.ts
CHANGED
package/app/layouts/docs.vue
CHANGED
|
@@ -9,13 +9,7 @@ const docsNav = useDocsNav()
|
|
|
9
9
|
<UPageAside>
|
|
10
10
|
<UPageAnchors :links="docsNav.links.filter((l) => l.title !== 'Blog')" />
|
|
11
11
|
<USeparator v-if="docsNav.activeLinks?.length" type="dashed" class="py-6" />
|
|
12
|
-
<UContentNavigation
|
|
13
|
-
:navigation="docsNav.activeLinks"
|
|
14
|
-
default-open
|
|
15
|
-
trailing-icon="i-lucide-chevron-right"
|
|
16
|
-
:ui="{ linkTrailingIcon: 'group-data-[state=open]:rotate-90' }"
|
|
17
|
-
highlight
|
|
18
|
-
/>
|
|
12
|
+
<UContentNavigation :navigation="docsNav.activeLinks" :collapsible="false" />
|
|
19
13
|
</UPageAside>
|
|
20
14
|
</template>
|
|
21
15
|
<slot />
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { MarkdownRoot,
|
|
1
|
+
import type { MarkdownRoot, MinimarkNode, MinimarkElement } from '@nuxt/content'
|
|
2
2
|
import type { Nuxt } from 'nuxt/schema'
|
|
3
3
|
import { CommonIcons } from './icons'
|
|
4
4
|
import type { DocsConfig } from '../../../schema/config'
|
|
@@ -13,6 +13,9 @@ interface ParsedContentFile extends Record<string, unknown> {
|
|
|
13
13
|
meta?: {
|
|
14
14
|
icon?: string
|
|
15
15
|
}
|
|
16
|
+
body?: {
|
|
17
|
+
icon?: string
|
|
18
|
+
}
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
export async function setupContentHooks(nuxt: Nuxt, docsConfig: DocsConfig) {
|
|
@@ -59,13 +62,14 @@ export async function setupContentHooks(nuxt: Nuxt, docsConfig: DocsConfig) {
|
|
|
59
62
|
})
|
|
60
63
|
|
|
61
64
|
nuxt.hooks.hook('content:file:afterParse', ({ content }) => {
|
|
65
|
+
// Infer icon for top level navigation
|
|
66
|
+
inferIcons(content)
|
|
67
|
+
|
|
62
68
|
// Filter out non-markdown files
|
|
63
69
|
if (content.extension !== 'md') {
|
|
64
70
|
return
|
|
65
71
|
}
|
|
66
72
|
|
|
67
|
-
resolveFileIcon(content)
|
|
68
|
-
|
|
69
73
|
const body = content.body as MarkdownRoot
|
|
70
74
|
removeFirstH1AndBlockquote(body, content)
|
|
71
75
|
body.value = mergeCodeGroups(body.value)
|
|
@@ -84,7 +88,7 @@ export async function setupContentHooks(nuxt: Nuxt, docsConfig: DocsConfig) {
|
|
|
84
88
|
|
|
85
89
|
// Handle GitHub flavoured markdown blockquotes
|
|
86
90
|
// https://github.com/orgs/community/discussions/16925
|
|
87
|
-
function transformGithubAlert(node:
|
|
91
|
+
function transformGithubAlert(node: MinimarkNode) {
|
|
88
92
|
if (
|
|
89
93
|
node[0] === 'blockquote' &&
|
|
90
94
|
Array.isArray(node[2]) &&
|
|
@@ -97,17 +101,17 @@ function transformGithubAlert(node: MinimalNode) {
|
|
|
97
101
|
// @ts-expect-error read-only
|
|
98
102
|
node[0] = node[2][2][2].slice(1).toLowerCase()
|
|
99
103
|
// @ts-expect-error read-only
|
|
100
|
-
node[2] = ['p', {}, ...node[2].slice(3)] as
|
|
104
|
+
node[2] = ['p', {}, ...node[2].slice(3)] as MinimarkElement
|
|
101
105
|
}
|
|
102
106
|
}
|
|
103
107
|
|
|
104
108
|
// --- transform steps list ---
|
|
105
109
|
|
|
106
|
-
function transformStepsList(node:
|
|
110
|
+
function transformStepsList(node: MinimarkNode) {
|
|
107
111
|
// CONVERT OL->LI to Steps
|
|
108
112
|
if (Array.isArray(node) && node[0] === 'ol' && node.length > 3 && Array.isArray(node[2]) && node[2][0] === 'li') {
|
|
109
|
-
const stepsChildren = node.slice(2).map((li:
|
|
110
|
-
return ['h4', {}, ...li.slice(2)] as
|
|
113
|
+
const stepsChildren = node.slice(2).map((li: MinimarkNode) => {
|
|
114
|
+
return ['h4', {}, ...li.slice(2)] as MinimarkElement
|
|
111
115
|
})
|
|
112
116
|
node.splice(0, Infinity, 'steps', { level: '4' }, ...stepsChildren)
|
|
113
117
|
}
|
|
@@ -143,17 +147,34 @@ function removeFirstH1AndBlockquote(body: MarkdownRoot, content: ParsedContentFi
|
|
|
143
147
|
|
|
144
148
|
// --- resolve icon ---
|
|
145
149
|
|
|
146
|
-
function
|
|
147
|
-
|
|
148
|
-
|
|
150
|
+
function inferIcons(content: ParsedContentFile) {
|
|
151
|
+
const icon = content.meta?.icon || content.navigation?.icon || content.body?.icon || _resolveIcon(content.path)
|
|
152
|
+
|
|
153
|
+
if (content.navigation && !content.navigation.icon) {
|
|
154
|
+
content.navigation.icon = icon
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (content.body && !content.body.icon) {
|
|
158
|
+
content.body.icon = icon
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (content.meta && !content.meta.icon) {
|
|
162
|
+
content.meta.icon = icon
|
|
149
163
|
}
|
|
150
|
-
content.navigation ||= {}
|
|
151
|
-
content.navigation.icon = content.meta.icon || _resolveIcon(content.path)
|
|
152
164
|
}
|
|
153
165
|
|
|
154
166
|
function _resolveIcon(path: string = '') {
|
|
155
167
|
// Split the path into parts and reverse it
|
|
156
|
-
const paths = path
|
|
168
|
+
const paths = path
|
|
169
|
+
.slice(1)
|
|
170
|
+
.split('/')
|
|
171
|
+
.reverse()
|
|
172
|
+
.filter((p) => p && !p.startsWith('.'))
|
|
173
|
+
|
|
174
|
+
// Skip 2+ levels of directories
|
|
175
|
+
if (paths.length > 2) {
|
|
176
|
+
return
|
|
177
|
+
}
|
|
157
178
|
|
|
158
179
|
// Search for icons in reverse order
|
|
159
180
|
for (const p of paths) {
|
|
@@ -167,10 +188,10 @@ function _resolveIcon(path: string = '') {
|
|
|
167
188
|
|
|
168
189
|
// --- Merge code groups ---
|
|
169
190
|
|
|
170
|
-
function mergeCodeGroups(children:
|
|
171
|
-
const newChildren:
|
|
191
|
+
function mergeCodeGroups(children: MinimarkNode[] = []): MinimarkNode[] {
|
|
192
|
+
const newChildren: MinimarkNode[] = []
|
|
172
193
|
|
|
173
|
-
let codeBlocks:
|
|
194
|
+
let codeBlocks: MinimarkNode[] = []
|
|
174
195
|
|
|
175
196
|
for (let i = 0; i < children.length; i++) {
|
|
176
197
|
if (_isNamedCodeBlock(children[i])) {
|
|
@@ -187,20 +208,20 @@ function mergeCodeGroups(children: MinimalNode[] = []): MinimalNode[] {
|
|
|
187
208
|
return newChildren
|
|
188
209
|
}
|
|
189
210
|
|
|
190
|
-
function _isNamedCodeBlock(node:
|
|
211
|
+
function _isNamedCodeBlock(node: MinimarkNode): boolean {
|
|
191
212
|
return node[0] === 'pre' && (node[1] as any)?.filename && node[2]?.[0] === 'code'
|
|
192
213
|
}
|
|
193
214
|
|
|
194
215
|
// --- transform automd jsdocs ---
|
|
195
216
|
|
|
196
|
-
export function transformJSDocs(currChildIdx: number, children:
|
|
217
|
+
export function transformJSDocs(currChildIdx: number, children: MinimarkNode[] = []) {
|
|
197
218
|
if (!children?.length || !_isJSDocBlock(children[currChildIdx])) {
|
|
198
219
|
return
|
|
199
220
|
}
|
|
200
221
|
|
|
201
|
-
const fields:
|
|
222
|
+
const fields: MinimarkNode[] = []
|
|
202
223
|
|
|
203
|
-
const generateFields = (i: number):
|
|
224
|
+
const generateFields = (i: number): MinimarkNode => {
|
|
204
225
|
const name = _parseJSDocName(children[i])
|
|
205
226
|
const type = _parseJSDocType(children[i + 1])
|
|
206
227
|
|
|
@@ -212,7 +233,7 @@ export function transformJSDocs(currChildIdx: number, children: MinimalNode[] =
|
|
|
212
233
|
type,
|
|
213
234
|
}
|
|
214
235
|
|
|
215
|
-
const content:
|
|
236
|
+
const content: MinimarkNode[] = []
|
|
216
237
|
|
|
217
238
|
i++
|
|
218
239
|
|
|
@@ -263,17 +284,17 @@ export function transformJSDocs(currChildIdx: number, children: MinimalNode[] =
|
|
|
263
284
|
}
|
|
264
285
|
}
|
|
265
286
|
|
|
266
|
-
function _isJSDocBlock(children:
|
|
287
|
+
function _isJSDocBlock(children: MinimarkNode): boolean {
|
|
267
288
|
return (
|
|
268
289
|
children?.tag === 'h3' && children?.children?.[0]?.tag === 'code' && children?.children?.[0]?.type === 'element'
|
|
269
290
|
)
|
|
270
291
|
}
|
|
271
292
|
|
|
272
|
-
function _parseJSDocName(node:
|
|
293
|
+
function _parseJSDocName(node: MinimarkNode): string {
|
|
273
294
|
// Code block || id prop || empty string
|
|
274
295
|
return node.children?.[0]?.children?.[0]?.value || node?.props?.id || ''
|
|
275
296
|
}
|
|
276
|
-
function _parseJSDocType(node:
|
|
297
|
+
function _parseJSDocType(node: MinimarkNode): string {
|
|
277
298
|
const hasType = !!node?.children?.[0]?.children?.[0]?.children?.[0]?.value
|
|
278
299
|
if (!hasType) {
|
|
279
300
|
return ''
|
|
@@ -284,7 +305,7 @@ function _parseJSDocType(node: MinimalNode): string {
|
|
|
284
305
|
|
|
285
306
|
// --- internal utils ---
|
|
286
307
|
|
|
287
|
-
function _getTextContent(node:
|
|
308
|
+
function _getTextContent(node: MinimarkNode): string {
|
|
288
309
|
if (!node) {
|
|
289
310
|
return ''
|
|
290
311
|
}
|
package/app/nuxt.config.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "undocs",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8",
|
|
4
4
|
"repository": "unjs/undocs",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -33,12 +33,13 @@
|
|
|
33
33
|
"@headlessui/vue": "^1.7.23",
|
|
34
34
|
"@iconify-json/logos": "^1.2.4",
|
|
35
35
|
"@iconify-json/simple-icons": "^1.2.37",
|
|
36
|
-
"@nuxt/content": "https://pkg.pr.new/@nuxt/content@3390",
|
|
36
|
+
"@nuxt/content": "https://pkg.pr.new/@nuxt/content@3390?c5a9c95",
|
|
37
37
|
"@nuxt/fonts": "^0.11.4",
|
|
38
38
|
"@nuxt/ui-pro": "^3.1.3",
|
|
39
39
|
"@nuxtjs/plausible": "^1.2.0",
|
|
40
40
|
"@resvg/resvg-wasm": "^2.6.2",
|
|
41
41
|
"automd": "^0.4.0",
|
|
42
|
+
"better-sqlite3": "^11.10.0",
|
|
42
43
|
"c12": "^3.0.4",
|
|
43
44
|
"citty": "^0.1.6",
|
|
44
45
|
"consola": "^3.4.2",
|