docus 5.5.1 → 5.6.1
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.vue +2 -5
- package/app/components/app/AppHeaderLogo.vue +12 -7
- package/app/composables/useLogoAssets.ts +246 -0
- package/app/error.vue +2 -5
- package/app/types/index.d.ts +8 -0
- package/app/utils/navigation.ts +19 -0
- package/content.config.ts +28 -16
- package/i18n/locales/ar.json +14 -1
- package/i18n/locales/be.json +13 -1
- package/i18n/locales/bg.json +14 -1
- package/i18n/locales/bn.json +14 -1
- package/i18n/locales/ca.json +14 -1
- package/i18n/locales/ckb.json +14 -1
- package/i18n/locales/cs.json +14 -1
- package/i18n/locales/da.json +14 -1
- package/i18n/locales/de.json +13 -0
- package/i18n/locales/el.json +14 -1
- package/i18n/locales/en.json +13 -0
- package/i18n/locales/es.json +13 -0
- package/i18n/locales/et.json +14 -1
- package/i18n/locales/fi.json +14 -1
- package/i18n/locales/fr.json +13 -0
- package/i18n/locales/he.json +14 -1
- package/i18n/locales/hi.json +14 -1
- package/i18n/locales/hy.json +14 -1
- package/i18n/locales/id.json +36 -23
- package/i18n/locales/it.json +13 -0
- package/i18n/locales/ja.json +14 -1
- package/i18n/locales/kk.json +14 -1
- package/i18n/locales/km.json +14 -1
- package/i18n/locales/ko.json +14 -1
- package/i18n/locales/ky.json +14 -1
- package/i18n/locales/lb.json +14 -1
- package/i18n/locales/ms.json +14 -1
- package/i18n/locales/nb.json +14 -1
- package/i18n/locales/nl.json +15 -2
- package/i18n/locales/pl.json +13 -1
- package/i18n/locales/pt-BR.json +14 -1
- package/i18n/locales/ro.json +13 -0
- package/i18n/locales/ru.json +13 -1
- package/i18n/locales/si.json +14 -1
- package/i18n/locales/sl.json +14 -1
- package/i18n/locales/sv.json +14 -1
- package/i18n/locales/tr.json +34 -21
- package/i18n/locales/uk.json +14 -1
- package/i18n/locales/ur.json +14 -1
- package/i18n/locales/vi.json +14 -1
- package/i18n/locales/zh-CN.json +13 -0
- package/modules/assistant/runtime/components/AssistantFloatingInput.vue +4 -4
- package/modules/routing.ts +21 -17
- package/nuxt.config.ts +9 -6
- package/nuxt.schema.ts +49 -0
- package/package.json +9 -9
- package/utils/pages.ts +22 -0
package/app/app.vue
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { ContentNavigationItem, PageCollections } from '@nuxt/content'
|
|
3
3
|
import * as nuxtUiLocales from '@nuxt/ui/locale'
|
|
4
|
+
import { transformNavigation } from './utils/navigation'
|
|
4
5
|
|
|
5
6
|
const { seo } = useAppConfig()
|
|
6
7
|
const site = useSiteConfig()
|
|
@@ -45,11 +46,7 @@ if (isEnabled.value) {
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
const { data: navigation } = await useAsyncData(() => `navigation_${collectionName.value}`, () => queryCollectionNavigation(collectionName.value as keyof PageCollections), {
|
|
48
|
-
transform: (data: ContentNavigationItem[]) =>
|
|
49
|
-
const rootResult = data.find(item => item.path === '/docs')?.children || data || []
|
|
50
|
-
|
|
51
|
-
return rootResult.find((item: ContentNavigationItem) => item.path === `/${locale.value}`)?.children || rootResult
|
|
52
|
-
},
|
|
49
|
+
transform: (data: ContentNavigationItem[]) => transformNavigation(data, isEnabled.value, locale.value),
|
|
53
50
|
watch: [locale],
|
|
54
51
|
})
|
|
55
52
|
const { data: files } = useLazyAsyncData(`search_${collectionName.value}`, () => queryCollectionSearchSections(collectionName.value as keyof PageCollections), {
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
const appConfig = useAppConfig()
|
|
3
|
+
const { hasLogo, headerLightUrl, headerDarkUrl, contextMenuItems } = useLogoAssets()
|
|
3
4
|
</script>
|
|
4
5
|
|
|
5
6
|
<template>
|
|
6
|
-
<
|
|
7
|
-
v-if="
|
|
8
|
-
:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
<UContextMenu
|
|
8
|
+
v-if="hasLogo"
|
|
9
|
+
:items="contextMenuItems"
|
|
10
|
+
>
|
|
11
|
+
<UColorModeImage
|
|
12
|
+
:light="headerLightUrl"
|
|
13
|
+
:dark="headerDarkUrl"
|
|
14
|
+
:alt="appConfig.header?.logo?.alt || appConfig.header?.title"
|
|
15
|
+
:class="['h-6 w-auto shrink-0', appConfig.header?.logo?.class]"
|
|
16
|
+
/>
|
|
17
|
+
</UContextMenu>
|
|
13
18
|
<span v-else>
|
|
14
19
|
{{ appConfig.header?.title || '{appConfig.header.title}' }}
|
|
15
20
|
</span>
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import type { ContextMenuItem } from '@nuxt/ui'
|
|
2
|
+
|
|
3
|
+
function isSvgUrl(url: string): boolean {
|
|
4
|
+
return url.toLowerCase().endsWith('.svg')
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function getExtension(url: string): string {
|
|
8
|
+
const match = url.match(/\.([a-z0-9]+)(?:\?|$)/i)
|
|
9
|
+
return match?.[1] ? `.${match[1].toLowerCase()}` : '.png'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function normalizeSvg(svg: string, name: string): string {
|
|
13
|
+
let result = svg.replace(/fill="(black|white|#[0-9a-fA-F]{3,8}|rgba?\([^)]+\))"/g, 'fill="currentColor"')
|
|
14
|
+
|
|
15
|
+
if (name) {
|
|
16
|
+
result = result.replace(/<svg\b/, `<svg id="${name}"`)
|
|
17
|
+
result = result.replace(/(<svg[^>]*>)/, `$1<title>${name}</title>`)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return result
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function fetchSvgContent(url: string, name: string): Promise<string | null> {
|
|
24
|
+
try {
|
|
25
|
+
const absoluteUrl = new URL(url, window.location.origin).href
|
|
26
|
+
const response = await fetch(absoluteUrl)
|
|
27
|
+
if (!response.ok) return null
|
|
28
|
+
const text = await response.text()
|
|
29
|
+
return normalizeSvg(text, name)
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function copyTextToClipboard(text: string): Promise<boolean> {
|
|
37
|
+
try {
|
|
38
|
+
await navigator.clipboard.writeText(text)
|
|
39
|
+
return true
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return false
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function triggerDownload(blob: Blob, filename: string) {
|
|
47
|
+
const url = URL.createObjectURL(blob)
|
|
48
|
+
const link = document.createElement('a')
|
|
49
|
+
link.href = url
|
|
50
|
+
link.download = filename
|
|
51
|
+
document.body.appendChild(link)
|
|
52
|
+
link.click()
|
|
53
|
+
document.body.removeChild(link)
|
|
54
|
+
URL.revokeObjectURL(url)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function triggerLinkDownload(url: string, filename: string) {
|
|
58
|
+
const link = document.createElement('a')
|
|
59
|
+
link.href = url
|
|
60
|
+
link.download = filename
|
|
61
|
+
document.body.appendChild(link)
|
|
62
|
+
link.click()
|
|
63
|
+
document.body.removeChild(link)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export const useLogoAssets = () => {
|
|
67
|
+
const appConfig = useAppConfig()
|
|
68
|
+
const colorMode = useColorMode()
|
|
69
|
+
const toast = useToast()
|
|
70
|
+
const { t } = useDocusI18n()
|
|
71
|
+
|
|
72
|
+
const hasLogo = computed(() => !!(appConfig.header?.logo?.light || appConfig.header?.logo?.dark))
|
|
73
|
+
|
|
74
|
+
const displayMode = computed(() => appConfig.header?.logo?.display || 'logo')
|
|
75
|
+
|
|
76
|
+
const currentLogoUrl = computed(() => {
|
|
77
|
+
const logo = appConfig.header?.logo
|
|
78
|
+
if (!logo) return ''
|
|
79
|
+
if (colorMode.value === 'dark') return logo.dark || logo.light || ''
|
|
80
|
+
return logo.light || logo.dark || ''
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
const hasWordmark = computed(() => {
|
|
84
|
+
const wm = appConfig.header?.logo?.wordmark
|
|
85
|
+
return !!(wm?.light || wm?.dark)
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
const currentWordmarkUrl = computed(() => {
|
|
89
|
+
const wm = appConfig.header?.logo?.wordmark
|
|
90
|
+
if (!wm) return ''
|
|
91
|
+
if (colorMode.value === 'dark') return wm.dark || wm.light || ''
|
|
92
|
+
return wm.light || wm.dark || ''
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
const headerLightUrl = computed(() => {
|
|
96
|
+
const logo = appConfig.header?.logo
|
|
97
|
+
if (!logo) return ''
|
|
98
|
+
if (displayMode.value === 'wordmark' && hasWordmark.value) {
|
|
99
|
+
return logo.wordmark?.light || logo.wordmark?.dark || logo.light || logo.dark || ''
|
|
100
|
+
}
|
|
101
|
+
return logo.light || logo.dark || ''
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
const headerDarkUrl = computed(() => {
|
|
105
|
+
const logo = appConfig.header?.logo
|
|
106
|
+
if (!logo) return ''
|
|
107
|
+
if (displayMode.value === 'wordmark' && hasWordmark.value) {
|
|
108
|
+
return logo.wordmark?.dark || logo.wordmark?.light || logo.dark || logo.light || ''
|
|
109
|
+
}
|
|
110
|
+
return logo.dark || logo.light || ''
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
const faviconUrl = computed(() => appConfig.header?.logo?.favicon || '/favicon.ico')
|
|
114
|
+
|
|
115
|
+
const logoAlt = computed(() => appConfig.header?.logo?.alt || appConfig.header?.title || '')
|
|
116
|
+
|
|
117
|
+
const brandName = computed(() => appConfig.header?.title || logoAlt.value || '')
|
|
118
|
+
|
|
119
|
+
const prefix = computed(() => {
|
|
120
|
+
const name = brandName.value
|
|
121
|
+
return name ? name.toLowerCase().replace(/\s+/g, '-') : 'logo'
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
const logoName = computed(() => {
|
|
125
|
+
const name = brandName.value
|
|
126
|
+
return name ? `${name} Logo` : 'Logo'
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
const wordmarkName = computed(() => {
|
|
130
|
+
const name = brandName.value
|
|
131
|
+
return name ? `${name} Wordmark` : 'Wordmark'
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
const logoIsSvg = computed(() => isSvgUrl(currentLogoUrl.value))
|
|
135
|
+
const wordmarkIsSvg = computed(() => isSvgUrl(currentWordmarkUrl.value))
|
|
136
|
+
|
|
137
|
+
async function copyLogo() {
|
|
138
|
+
if (!logoIsSvg.value) return
|
|
139
|
+
const svg = await fetchSvgContent(currentLogoUrl.value, logoName.value)
|
|
140
|
+
if (!svg) {
|
|
141
|
+
toast.add({ title: t('logo.copyLogoFailed'), icon: 'i-lucide-circle-x', color: 'error' })
|
|
142
|
+
return
|
|
143
|
+
}
|
|
144
|
+
const ok = await copyTextToClipboard(svg)
|
|
145
|
+
toast.add(ok
|
|
146
|
+
? { title: t('logo.logoCopied'), icon: 'i-lucide-circle-check', color: 'success' }
|
|
147
|
+
: { title: t('logo.copyLogoFailed'), icon: 'i-lucide-circle-x', color: 'error' },
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function copyWordmark() {
|
|
152
|
+
if (!wordmarkIsSvg.value) return
|
|
153
|
+
const svg = await fetchSvgContent(currentWordmarkUrl.value, wordmarkName.value)
|
|
154
|
+
if (!svg) {
|
|
155
|
+
toast.add({ title: t('logo.copyWordmarkFailed'), icon: 'i-lucide-circle-x', color: 'error' })
|
|
156
|
+
return
|
|
157
|
+
}
|
|
158
|
+
const ok = await copyTextToClipboard(svg)
|
|
159
|
+
toast.add(ok
|
|
160
|
+
? { title: t('logo.wordmarkCopied'), icon: 'i-lucide-circle-check', color: 'success' }
|
|
161
|
+
: { title: t('logo.copyWordmarkFailed'), icon: 'i-lucide-circle-x', color: 'error' },
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async function downloadLogo() {
|
|
166
|
+
const url = currentLogoUrl.value
|
|
167
|
+
if (logoIsSvg.value) {
|
|
168
|
+
const svg = await fetchSvgContent(url, logoName.value)
|
|
169
|
+
if (!svg) return
|
|
170
|
+
triggerDownload(new Blob([svg], { type: 'image/svg+xml' }), `${prefix.value}-logo.svg`)
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
triggerLinkDownload(url, `${prefix.value}-logo${getExtension(url)}`)
|
|
174
|
+
}
|
|
175
|
+
toast.add({ title: t('logo.logoDownloaded'), icon: 'i-lucide-download', color: 'success' })
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async function downloadWordmark() {
|
|
179
|
+
const url = currentWordmarkUrl.value
|
|
180
|
+
if (wordmarkIsSvg.value) {
|
|
181
|
+
const svg = await fetchSvgContent(url, wordmarkName.value)
|
|
182
|
+
if (!svg) return
|
|
183
|
+
triggerDownload(new Blob([svg], { type: 'image/svg+xml' }), `${prefix.value}-wordmark.svg`)
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
triggerLinkDownload(url, `${prefix.value}-wordmark${getExtension(url)}`)
|
|
187
|
+
}
|
|
188
|
+
toast.add({ title: t('logo.wordmarkDownloaded'), icon: 'i-lucide-download', color: 'success' })
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const brandAssetsUrl = computed(() => appConfig.header?.logo?.brandAssetsUrl || '')
|
|
192
|
+
|
|
193
|
+
const contextMenuItems = computed(() => {
|
|
194
|
+
if (!hasLogo.value) return []
|
|
195
|
+
|
|
196
|
+
const copyGroup: ContextMenuItem[] = []
|
|
197
|
+
if (logoIsSvg.value) {
|
|
198
|
+
copyGroup.push({ label: t('logo.copyLogo'), icon: 'i-lucide-copy', onSelect: copyLogo })
|
|
199
|
+
}
|
|
200
|
+
if (hasWordmark.value && wordmarkIsSvg.value) {
|
|
201
|
+
copyGroup.push({ label: t('logo.copyWordmark'), icon: 'i-lucide-copy', onSelect: copyWordmark })
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const downloadGroup: ContextMenuItem[] = [
|
|
205
|
+
{ label: t('logo.downloadLogo'), icon: 'i-lucide-download', onSelect: downloadLogo },
|
|
206
|
+
]
|
|
207
|
+
if (hasWordmark.value) {
|
|
208
|
+
downloadGroup.push({ label: t('logo.downloadWordmark'), icon: 'i-lucide-download', onSelect: downloadWordmark })
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const items: ContextMenuItem[][] = []
|
|
212
|
+
if (copyGroup.length) items.push(copyGroup)
|
|
213
|
+
items.push(downloadGroup)
|
|
214
|
+
|
|
215
|
+
if (brandAssetsUrl.value) {
|
|
216
|
+
items.push([{
|
|
217
|
+
label: t('logo.brandAssets'),
|
|
218
|
+
icon: 'i-lucide-palette',
|
|
219
|
+
onSelect() {
|
|
220
|
+
window.open(brandAssetsUrl.value, '_blank')
|
|
221
|
+
},
|
|
222
|
+
}])
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return items
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
hasLogo,
|
|
230
|
+
displayMode,
|
|
231
|
+
currentLogoUrl,
|
|
232
|
+
headerLightUrl,
|
|
233
|
+
headerDarkUrl,
|
|
234
|
+
hasWordmark,
|
|
235
|
+
currentWordmarkUrl,
|
|
236
|
+
faviconUrl,
|
|
237
|
+
logoAlt,
|
|
238
|
+
contextMenuItems,
|
|
239
|
+
copyLogo,
|
|
240
|
+
downloadLogo,
|
|
241
|
+
copyWordmark,
|
|
242
|
+
downloadWordmark,
|
|
243
|
+
copyTextToClipboard,
|
|
244
|
+
fetchSvgContent,
|
|
245
|
+
}
|
|
246
|
+
}
|
package/app/error.vue
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import type { NuxtError } from '#app'
|
|
3
3
|
import type { ContentNavigationItem, PageCollections } from '@nuxt/content'
|
|
4
4
|
import * as nuxtUiLocales from '@nuxt/ui/locale'
|
|
5
|
+
import { transformNavigation } from './utils/navigation'
|
|
5
6
|
|
|
6
7
|
const props = defineProps<{
|
|
7
8
|
error: NuxtError
|
|
@@ -47,11 +48,7 @@ if (isEnabled.value) {
|
|
|
47
48
|
const collectionName = computed(() => isEnabled.value ? `docs_${locale.value}` : 'docs')
|
|
48
49
|
|
|
49
50
|
const { data: navigation } = await useAsyncData(`navigation_${collectionName.value}`, () => queryCollectionNavigation(collectionName.value as keyof PageCollections), {
|
|
50
|
-
transform: (data: ContentNavigationItem[]) =>
|
|
51
|
-
const rootResult = data.find(item => item.path === '/docs')?.children || data || []
|
|
52
|
-
|
|
53
|
-
return rootResult.find(item => item.path === `/${locale.value}`)?.children || rootResult
|
|
54
|
-
},
|
|
51
|
+
transform: (data: ContentNavigationItem[]) => transformNavigation(data, isEnabled.value, locale.value),
|
|
55
52
|
watch: [locale],
|
|
56
53
|
})
|
|
57
54
|
const { data: files } = useLazyAsyncData(`search_${collectionName.value}`, () => queryCollectionSearchSections(collectionName.value as keyof PageCollections), {
|
package/app/types/index.d.ts
CHANGED
|
@@ -18,6 +18,14 @@ declare module 'nuxt/schema' {
|
|
|
18
18
|
light: string
|
|
19
19
|
dark: string
|
|
20
20
|
alt: string
|
|
21
|
+
class?: string
|
|
22
|
+
display?: 'logo' | 'wordmark'
|
|
23
|
+
wordmark?: {
|
|
24
|
+
light?: string
|
|
25
|
+
dark?: string
|
|
26
|
+
}
|
|
27
|
+
favicon?: string
|
|
28
|
+
brandAssetsUrl?: string
|
|
21
29
|
}
|
|
22
30
|
}
|
|
23
31
|
socials: Record<string, string>
|
package/app/utils/navigation.ts
CHANGED
|
@@ -6,6 +6,25 @@ export const flattenNavigation = (items?: ContentNavigationItem[]): ContentNavig
|
|
|
6
6
|
: [item],
|
|
7
7
|
) || []
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Transform navigation data by stripping locale and docs levels
|
|
11
|
+
*/
|
|
12
|
+
export function transformNavigation(
|
|
13
|
+
data: ContentNavigationItem[],
|
|
14
|
+
isI18nEnabled: boolean,
|
|
15
|
+
locale?: string,
|
|
16
|
+
): ContentNavigationItem[] {
|
|
17
|
+
if (isI18nEnabled && locale) {
|
|
18
|
+
// i18n: first strip locale level, then check for docs level
|
|
19
|
+
const localeResult = data.find(item => item.path === `/${locale}`)?.children || data
|
|
20
|
+
return localeResult.find(item => item.path === `/${locale}/docs`)?.children || localeResult
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
// non-i18n: strip docs level if exists
|
|
24
|
+
return data.find(item => item.path === '/docs')?.children || data
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
9
28
|
export interface BreadcrumbItem {
|
|
10
29
|
title: string
|
|
11
30
|
path: string
|
package/content.config.ts
CHANGED
|
@@ -2,11 +2,15 @@ import type { DefinedCollection } from '@nuxt/content'
|
|
|
2
2
|
import { defineContentConfig, defineCollection, z } from '@nuxt/content'
|
|
3
3
|
import { useNuxt } from '@nuxt/kit'
|
|
4
4
|
import { joinURL } from 'ufo'
|
|
5
|
+
import { landingPageExists, docsFolderExists } from './utils/pages'
|
|
5
6
|
|
|
6
7
|
const { options } = useNuxt()
|
|
7
8
|
const cwd = joinURL(options.rootDir, 'content')
|
|
8
9
|
const locales = options.i18n?.locales
|
|
9
10
|
|
|
11
|
+
const hasLandingPage = landingPageExists(options.rootDir)
|
|
12
|
+
const hasDocsFolder = docsFolderExists(options.rootDir)
|
|
13
|
+
|
|
10
14
|
const createDocsSchema = () => z.object({
|
|
11
15
|
links: z.array(z.object({
|
|
12
16
|
label: z.string(),
|
|
@@ -22,21 +26,24 @@ if (locales && Array.isArray(locales)) {
|
|
|
22
26
|
collections = {}
|
|
23
27
|
for (const locale of locales) {
|
|
24
28
|
const code = (typeof locale === 'string' ? locale : locale.code).replace('-', '_')
|
|
29
|
+
const hasLocaleDocs = docsFolderExists(options.rootDir, code)
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
if (!hasLandingPage) {
|
|
32
|
+
collections[`landing_${code}`] = defineCollection({
|
|
33
|
+
type: 'page',
|
|
34
|
+
source: {
|
|
35
|
+
cwd,
|
|
36
|
+
include: `${code}/index.md`,
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
}
|
|
33
40
|
|
|
34
41
|
collections[`docs_${code}`] = defineCollection({
|
|
35
42
|
type: 'page',
|
|
36
43
|
source: {
|
|
37
44
|
cwd,
|
|
38
|
-
include: `${code}/**/*`,
|
|
39
|
-
prefix: `/${code}`,
|
|
45
|
+
include: hasLocaleDocs ? `${code}/docs/**` : `${code}/**/*`,
|
|
46
|
+
prefix: hasLocaleDocs ? `/${code}/docs` : `/${code}`,
|
|
40
47
|
exclude: [`${code}/index.md`],
|
|
41
48
|
},
|
|
42
49
|
schema: createDocsSchema(),
|
|
@@ -45,22 +52,27 @@ if (locales && Array.isArray(locales)) {
|
|
|
45
52
|
}
|
|
46
53
|
else {
|
|
47
54
|
collections = {
|
|
48
|
-
|
|
55
|
+
docs: defineCollection({
|
|
49
56
|
type: 'page',
|
|
50
57
|
source: {
|
|
51
58
|
cwd,
|
|
52
|
-
include: '
|
|
59
|
+
include: hasDocsFolder ? 'docs/**' : '**',
|
|
60
|
+
prefix: hasDocsFolder ? '/docs' : '/',
|
|
61
|
+
exclude: ['index.md'],
|
|
53
62
|
},
|
|
63
|
+
schema: createDocsSchema(),
|
|
54
64
|
}),
|
|
55
|
-
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Only define landing collection if user doesn't have their own index.vue
|
|
68
|
+
if (!hasLandingPage) {
|
|
69
|
+
collections.landing = defineCollection({
|
|
56
70
|
type: 'page',
|
|
57
71
|
source: {
|
|
58
72
|
cwd,
|
|
59
|
-
include: '
|
|
60
|
-
exclude: ['index.md'],
|
|
73
|
+
include: 'index.md',
|
|
61
74
|
},
|
|
62
|
-
|
|
63
|
-
}),
|
|
75
|
+
})
|
|
64
76
|
}
|
|
65
77
|
}
|
|
66
78
|
|
package/i18n/locales/ar.json
CHANGED
|
@@ -18,5 +18,18 @@
|
|
|
18
18
|
"toc": "في هذه الصفحة",
|
|
19
19
|
"report": "الإبلاغ عن مشكلة",
|
|
20
20
|
"edit": "تحرير هذه الصفحة"
|
|
21
|
+
},
|
|
22
|
+
"logo": {
|
|
23
|
+
"copyLogo": "نسخ الشعار",
|
|
24
|
+
"copyWordmark": "نسخ العلامة النصية",
|
|
25
|
+
"downloadLogo": "تحميل الشعار",
|
|
26
|
+
"downloadWordmark": "تحميل العلامة النصية",
|
|
27
|
+
"brandAssets": "أصول العلامة التجارية",
|
|
28
|
+
"logoCopied": "تم نسخ الشعار",
|
|
29
|
+
"wordmarkCopied": "تم نسخ العلامة النصية",
|
|
30
|
+
"logoDownloaded": "تم تحميل الشعار",
|
|
31
|
+
"wordmarkDownloaded": "تم تحميل العلامة النصية",
|
|
32
|
+
"copyLogoFailed": "فشل نسخ الشعار",
|
|
33
|
+
"copyWordmarkFailed": "فشل نسخ العلامة النصية"
|
|
21
34
|
}
|
|
22
|
-
}
|
|
35
|
+
}
|
package/i18n/locales/be.json
CHANGED
|
@@ -18,6 +18,18 @@
|
|
|
18
18
|
"toc": "На гэтай старонцы",
|
|
19
19
|
"report": "Паведаміць пра праблему",
|
|
20
20
|
"edit": "Рэдагаваць гэтую старонку"
|
|
21
|
+
},
|
|
22
|
+
"logo": {
|
|
23
|
+
"copyLogo": "Капіяваць лагатып",
|
|
24
|
+
"copyWordmark": "Капіяваць словесны знак",
|
|
25
|
+
"downloadLogo": "Спампаваць лагатып",
|
|
26
|
+
"downloadWordmark": "Спампаваць словесны знак",
|
|
27
|
+
"brandAssets": "Матэрыялы брэнда",
|
|
28
|
+
"logoCopied": "Лагатып скапіяваны",
|
|
29
|
+
"wordmarkCopied": "Словесны знак скапіяваны",
|
|
30
|
+
"logoDownloaded": "Лагатып спампаваны",
|
|
31
|
+
"wordmarkDownloaded": "Словесны знак спампаваны",
|
|
32
|
+
"copyLogoFailed": "Не ўдалося скапіяваць лагатып",
|
|
33
|
+
"copyWordmarkFailed": "Не ўдалося скапіяваць словесны знак"
|
|
21
34
|
}
|
|
22
35
|
}
|
|
23
|
-
|
package/i18n/locales/bg.json
CHANGED
|
@@ -18,5 +18,18 @@
|
|
|
18
18
|
"toc": "На тази страница",
|
|
19
19
|
"report": "Докладване на проблем",
|
|
20
20
|
"edit": "Редактиране на тази страница"
|
|
21
|
+
},
|
|
22
|
+
"logo": {
|
|
23
|
+
"copyLogo": "Копиране на логото",
|
|
24
|
+
"copyWordmark": "Копиране на словната марка",
|
|
25
|
+
"downloadLogo": "Изтегляне на логото",
|
|
26
|
+
"downloadWordmark": "Изтегляне на словната марка",
|
|
27
|
+
"brandAssets": "Брандови материали",
|
|
28
|
+
"logoCopied": "Логото е копирано",
|
|
29
|
+
"wordmarkCopied": "Словната марка е копирана",
|
|
30
|
+
"logoDownloaded": "Логото е изтеглено",
|
|
31
|
+
"wordmarkDownloaded": "Словната марка е изтеглена",
|
|
32
|
+
"copyLogoFailed": "Неуспешно копиране на логото",
|
|
33
|
+
"copyWordmarkFailed": "Неуспешно копиране на словната марка"
|
|
21
34
|
}
|
|
22
|
-
}
|
|
35
|
+
}
|
package/i18n/locales/bn.json
CHANGED
|
@@ -18,5 +18,18 @@
|
|
|
18
18
|
"toc": "এই পেজে",
|
|
19
19
|
"report": "সমস্যা রিপোর্ট করুন",
|
|
20
20
|
"edit": "এই পেজ সম্পাদনা করুন"
|
|
21
|
+
},
|
|
22
|
+
"logo": {
|
|
23
|
+
"copyLogo": "লোগো কপি করুন",
|
|
24
|
+
"copyWordmark": "ওয়ার্ডমার্ক কপি করুন",
|
|
25
|
+
"downloadLogo": "লোগো ডাউনলোড করুন",
|
|
26
|
+
"downloadWordmark": "ওয়ার্ডমার্ক ডাউনলোড করুন",
|
|
27
|
+
"brandAssets": "ব্র্যান্ড অ্যাসেট",
|
|
28
|
+
"logoCopied": "লোগো কপি হয়েছে",
|
|
29
|
+
"wordmarkCopied": "ওয়ার্ডমার্ক কপি হয়েছে",
|
|
30
|
+
"logoDownloaded": "লোগো ডাউনলোড হয়েছে",
|
|
31
|
+
"wordmarkDownloaded": "ওয়ার্ডমার্ক ডাউনলোড হয়েছে",
|
|
32
|
+
"copyLogoFailed": "লোগো কপি করা যায়নি",
|
|
33
|
+
"copyWordmarkFailed": "ওয়ার্ডমার্ক কপি করা যায়নি"
|
|
21
34
|
}
|
|
22
|
-
}
|
|
35
|
+
}
|
package/i18n/locales/ca.json
CHANGED
|
@@ -18,5 +18,18 @@
|
|
|
18
18
|
"toc": "En aquesta pàgina",
|
|
19
19
|
"report": "Informar d'un problema",
|
|
20
20
|
"edit": "Editar aquesta pàgina"
|
|
21
|
+
},
|
|
22
|
+
"logo": {
|
|
23
|
+
"copyLogo": "Copiar el logotip",
|
|
24
|
+
"copyWordmark": "Copiar el wordmark",
|
|
25
|
+
"downloadLogo": "Descarregar el logotip",
|
|
26
|
+
"downloadWordmark": "Descarregar el wordmark",
|
|
27
|
+
"brandAssets": "Recursos de marca",
|
|
28
|
+
"logoCopied": "Logotip copiat",
|
|
29
|
+
"wordmarkCopied": "Wordmark copiat",
|
|
30
|
+
"logoDownloaded": "Logotip descarregat",
|
|
31
|
+
"wordmarkDownloaded": "Wordmark descarregat",
|
|
32
|
+
"copyLogoFailed": "No s'ha pogut copiar el logotip",
|
|
33
|
+
"copyWordmarkFailed": "No s'ha pogut copiar el wordmark"
|
|
21
34
|
}
|
|
22
|
-
}
|
|
35
|
+
}
|
package/i18n/locales/ckb.json
CHANGED
|
@@ -14,5 +14,18 @@
|
|
|
14
14
|
"toc": "لەم پەڕەدا",
|
|
15
15
|
"report": "ڕاپۆرتکردنی کێشە",
|
|
16
16
|
"edit": "دەستکاریکردنی ئەم پەڕەیە"
|
|
17
|
+
},
|
|
18
|
+
"logo": {
|
|
19
|
+
"copyLogo": "کۆپیکردنی لۆگۆ",
|
|
20
|
+
"copyWordmark": "کۆپیکردنی وشەنیشان",
|
|
21
|
+
"downloadLogo": "داگرتنی لۆگۆ",
|
|
22
|
+
"downloadWordmark": "داگرتنی وشەنیشان",
|
|
23
|
+
"brandAssets": "سامانەکانی براند",
|
|
24
|
+
"logoCopied": "لۆگۆ کۆپی کرا",
|
|
25
|
+
"wordmarkCopied": "وشەنیشان کۆپی کرا",
|
|
26
|
+
"logoDownloaded": "لۆگۆ دابەزێنرا",
|
|
27
|
+
"wordmarkDownloaded": "وشەنیشان دابەزێنرا",
|
|
28
|
+
"copyLogoFailed": "کۆپیکردنی لۆگۆ سەرکەوتوو نەبوو",
|
|
29
|
+
"copyWordmarkFailed": "کۆپیکردنی وشەنیشان سەرکەوتوو نەبوو"
|
|
17
30
|
}
|
|
18
|
-
}
|
|
31
|
+
}
|
package/i18n/locales/cs.json
CHANGED
|
@@ -18,5 +18,18 @@
|
|
|
18
18
|
"toc": "Na této stránce",
|
|
19
19
|
"report": "Nahlásit problém",
|
|
20
20
|
"edit": "Upravit tuto stránku"
|
|
21
|
+
},
|
|
22
|
+
"logo": {
|
|
23
|
+
"copyLogo": "Kopírovat logo",
|
|
24
|
+
"copyWordmark": "Kopírovat wordmark",
|
|
25
|
+
"downloadLogo": "Stáhnout logo",
|
|
26
|
+
"downloadWordmark": "Stáhnout wordmark",
|
|
27
|
+
"brandAssets": "Materiály značky",
|
|
28
|
+
"logoCopied": "Logo zkopírováno",
|
|
29
|
+
"wordmarkCopied": "Wordmark zkopírován",
|
|
30
|
+
"logoDownloaded": "Logo staženo",
|
|
31
|
+
"wordmarkDownloaded": "Wordmark stažen",
|
|
32
|
+
"copyLogoFailed": "Kopírování loga selhalo",
|
|
33
|
+
"copyWordmarkFailed": "Kopírování wordmarku selhalo"
|
|
21
34
|
}
|
|
22
|
-
}
|
|
35
|
+
}
|
package/i18n/locales/da.json
CHANGED
|
@@ -18,5 +18,18 @@
|
|
|
18
18
|
"toc": "På denne side",
|
|
19
19
|
"report": "Rapporter et problem",
|
|
20
20
|
"edit": "Rediger denne side"
|
|
21
|
+
},
|
|
22
|
+
"logo": {
|
|
23
|
+
"copyLogo": "Kopiér logo",
|
|
24
|
+
"copyWordmark": "Kopiér wordmark",
|
|
25
|
+
"downloadLogo": "Download logo",
|
|
26
|
+
"downloadWordmark": "Download wordmark",
|
|
27
|
+
"brandAssets": "Brandmaterialer",
|
|
28
|
+
"logoCopied": "Logo kopieret",
|
|
29
|
+
"wordmarkCopied": "Wordmark kopieret",
|
|
30
|
+
"logoDownloaded": "Logo downloadet",
|
|
31
|
+
"wordmarkDownloaded": "Wordmark downloadet",
|
|
32
|
+
"copyLogoFailed": "Kunne ikke kopiere logo",
|
|
33
|
+
"copyWordmarkFailed": "Kunne ikke kopiere wordmark"
|
|
21
34
|
}
|
|
22
|
-
}
|
|
35
|
+
}
|
package/i18n/locales/de.json
CHANGED
|
@@ -18,5 +18,18 @@
|
|
|
18
18
|
"toc": "Auf dieser Seite",
|
|
19
19
|
"report": "Problem melden",
|
|
20
20
|
"edit": "Diese Seite bearbeiten"
|
|
21
|
+
},
|
|
22
|
+
"logo": {
|
|
23
|
+
"copyLogo": "Logo kopieren",
|
|
24
|
+
"copyWordmark": "Wortmarke kopieren",
|
|
25
|
+
"downloadLogo": "Logo herunterladen",
|
|
26
|
+
"downloadWordmark": "Wortmarke herunterladen",
|
|
27
|
+
"brandAssets": "Markenmaterialien",
|
|
28
|
+
"logoCopied": "Logo kopiert",
|
|
29
|
+
"wordmarkCopied": "Wortmarke kopiert",
|
|
30
|
+
"logoDownloaded": "Logo heruntergeladen",
|
|
31
|
+
"wordmarkDownloaded": "Wortmarke heruntergeladen",
|
|
32
|
+
"copyLogoFailed": "Logo konnte nicht kopiert werden",
|
|
33
|
+
"copyWordmarkFailed": "Wortmarke konnte nicht kopiert werden"
|
|
21
34
|
}
|
|
22
35
|
}
|
package/i18n/locales/el.json
CHANGED
|
@@ -18,5 +18,18 @@
|
|
|
18
18
|
"toc": "Σε αυτή τη σελίδα",
|
|
19
19
|
"report": "Αναφορά προβλήματος",
|
|
20
20
|
"edit": "Επεξεργασία αυτής της σελίδας"
|
|
21
|
+
},
|
|
22
|
+
"logo": {
|
|
23
|
+
"copyLogo": "Αντιγραφή λογοτύπου",
|
|
24
|
+
"copyWordmark": "Αντιγραφή wordmark",
|
|
25
|
+
"downloadLogo": "Λήψη λογοτύπου",
|
|
26
|
+
"downloadWordmark": "Λήψη wordmark",
|
|
27
|
+
"brandAssets": "Υλικά επωνυμίας",
|
|
28
|
+
"logoCopied": "Το λογότυπο αντιγράφηκε",
|
|
29
|
+
"wordmarkCopied": "Το wordmark αντιγράφηκε",
|
|
30
|
+
"logoDownloaded": "Το λογότυπο κατέβηκε",
|
|
31
|
+
"wordmarkDownloaded": "Το wordmark κατέβηκε",
|
|
32
|
+
"copyLogoFailed": "Αποτυχία αντιγραφής λογοτύπου",
|
|
33
|
+
"copyWordmarkFailed": "Αποτυχία αντιγραφής wordmark"
|
|
21
34
|
}
|
|
22
|
-
}
|
|
35
|
+
}
|
package/i18n/locales/en.json
CHANGED
|
@@ -19,6 +19,19 @@
|
|
|
19
19
|
"report": "Report an issue",
|
|
20
20
|
"edit": "Edit this page"
|
|
21
21
|
},
|
|
22
|
+
"logo": {
|
|
23
|
+
"copyLogo": "Copy logo",
|
|
24
|
+
"copyWordmark": "Copy wordmark",
|
|
25
|
+
"downloadLogo": "Download logo",
|
|
26
|
+
"downloadWordmark": "Download wordmark",
|
|
27
|
+
"brandAssets": "Brand assets",
|
|
28
|
+
"logoCopied": "Logo copied",
|
|
29
|
+
"wordmarkCopied": "Wordmark copied",
|
|
30
|
+
"logoDownloaded": "Logo downloaded",
|
|
31
|
+
"wordmarkDownloaded": "Wordmark downloaded",
|
|
32
|
+
"copyLogoFailed": "Failed to copy logo",
|
|
33
|
+
"copyWordmarkFailed": "Failed to copy wordmark"
|
|
34
|
+
},
|
|
22
35
|
"assistant": {
|
|
23
36
|
"title": "Ask AI",
|
|
24
37
|
"placeholder": "Ask a question...",
|