@kirchdev/duxt 0.1.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/LICENSE +21 -0
- package/README.md +151 -0
- package/app/app.config.ts +13 -0
- package/app/app.vue +122 -0
- package/app/assets/css/duxt.css +555 -0
- package/app/assets/css/typeset.css +498 -0
- package/app/components/DuxtBrand.vue +53 -0
- package/app/components/DuxtBreadcrumb.vue +37 -0
- package/app/components/DuxtCodeBlock.vue +143 -0
- package/app/components/DuxtCopyPage.vue +117 -0
- package/app/components/DuxtFooter.vue +86 -0
- package/app/components/DuxtHeader.vue +496 -0
- package/app/components/DuxtJsonEditor.vue +359 -0
- package/app/components/DuxtLandingProse.vue +90 -0
- package/app/components/DuxtLandingShowcase.vue +295 -0
- package/app/components/DuxtLiveWindow.vue +343 -0
- package/app/components/DuxtLocale.vue +86 -0
- package/app/components/DuxtMetaList.vue +76 -0
- package/app/components/DuxtNavigation.vue +94 -0
- package/app/components/DuxtNavigationLink.vue +41 -0
- package/app/components/DuxtOpenApiCallbacks.vue +92 -0
- package/app/components/DuxtOpenApiClient.vue +1339 -0
- package/app/components/DuxtOpenApiMedia.vue +108 -0
- package/app/components/DuxtOpenApiMethod.vue +59 -0
- package/app/components/DuxtOpenApiParameters.vue +114 -0
- package/app/components/DuxtOpenApiResponses.vue +109 -0
- package/app/components/DuxtOpenApiSchema.vue +365 -0
- package/app/components/DuxtOpenApiSecurity.vue +115 -0
- package/app/components/DuxtPageFeedback.vue +56 -0
- package/app/components/DuxtPageInfo.vue +194 -0
- package/app/components/DuxtPageNav.vue +93 -0
- package/app/components/DuxtPreviewSkeleton.vue +262 -0
- package/app/components/DuxtProgress.vue +45 -0
- package/app/components/DuxtSearch.vue +271 -0
- package/app/components/DuxtSections.vue +65 -0
- package/app/components/DuxtShortcuts.vue +46 -0
- package/app/components/DuxtSkipLink.vue +34 -0
- package/app/components/DuxtToc.vue +86 -0
- package/app/components/DuxtTranslationBanner.vue +64 -0
- package/app/components/DuxtVersion.vue +168 -0
- package/app/components/DuxtVersionBanner.vue +109 -0
- package/app/components/OgImage/Duxt.satori.vue +82 -0
- package/app/components/content/Accordion.vue +37 -0
- package/app/components/content/AccordionItem.vue +46 -0
- package/app/components/content/Callout.vue +58 -0
- package/app/components/content/ChangelogGroup.vue +91 -0
- package/app/components/content/ChangelogReleases.vue +520 -0
- package/app/components/content/CodeGroup.vue +183 -0
- package/app/components/content/DevtoolsPanel.vue +107 -0
- package/app/components/content/Field.vue +50 -0
- package/app/components/content/FieldGroup.vue +8 -0
- package/app/components/content/FileTree.vue +92 -0
- package/app/components/content/Mermaid.vue +70 -0
- package/app/components/content/OpenApiOperation.vue +185 -0
- package/app/components/content/OpenApiOperations.vue +72 -0
- package/app/components/content/OpenApiOverview.vue +302 -0
- package/app/components/content/PackageManagers.vue +187 -0
- package/app/components/content/PageCards.vue +48 -0
- package/app/components/content/Partial.vue +65 -0
- package/app/components/content/Preview.vue +173 -0
- package/app/components/content/ProseA.vue +55 -0
- package/app/components/content/ProseH2.vue +53 -0
- package/app/components/content/ProseH3.vue +53 -0
- package/app/components/content/ProseH4.vue +53 -0
- package/app/components/content/ProseImg.vue +87 -0
- package/app/components/content/ProsePre.vue +58 -0
- package/app/components/content/ProseTable.vue +11 -0
- package/app/components/content/Since.vue +21 -0
- package/app/components/content/Steps.vue +20 -0
- package/app/components/content/Tab.vue +23 -0
- package/app/components/content/TabGroup.vue +58 -0
- package/app/components/ui/alert/Alert.vue +21 -0
- package/app/components/ui/alert/AlertDescription.vue +22 -0
- package/app/components/ui/alert/AlertTitle.vue +22 -0
- package/app/components/ui/alert/index.ts +24 -0
- package/app/components/ui/badge/Badge.vue +28 -0
- package/app/components/ui/badge/index.ts +52 -0
- package/app/components/ui/breadcrumb/Breadcrumb.vue +13 -0
- package/app/components/ui/breadcrumb/BreadcrumbEllipsis.vue +22 -0
- package/app/components/ui/breadcrumb/BreadcrumbItem.vue +17 -0
- package/app/components/ui/breadcrumb/BreadcrumbLink.vue +24 -0
- package/app/components/ui/breadcrumb/BreadcrumbList.vue +22 -0
- package/app/components/ui/breadcrumb/BreadcrumbPage.vue +20 -0
- package/app/components/ui/breadcrumb/BreadcrumbSeparator.vue +21 -0
- package/app/components/ui/breadcrumb/index.ts +7 -0
- package/app/components/ui/button/Button.vue +31 -0
- package/app/components/ui/button/index.ts +39 -0
- package/app/components/ui/card/Card.vue +22 -0
- package/app/components/ui/card/CardAction.vue +22 -0
- package/app/components/ui/card/CardContent.vue +14 -0
- package/app/components/ui/card/CardDescription.vue +17 -0
- package/app/components/ui/card/CardFooter.vue +17 -0
- package/app/components/ui/card/CardHeader.vue +22 -0
- package/app/components/ui/card/CardTitle.vue +17 -0
- package/app/components/ui/card/index.ts +7 -0
- package/app/components/ui/collapsible/Collapsible.vue +19 -0
- package/app/components/ui/collapsible/CollapsibleContent.vue +12 -0
- package/app/components/ui/collapsible/CollapsibleTrigger.vue +12 -0
- package/app/components/ui/collapsible/index.ts +3 -0
- package/app/components/ui/command/Command.vue +98 -0
- package/app/components/ui/command/CommandDialog.vue +42 -0
- package/app/components/ui/command/CommandEmpty.vue +31 -0
- package/app/components/ui/command/CommandGroup.vue +52 -0
- package/app/components/ui/command/CommandInput.vue +45 -0
- package/app/components/ui/command/CommandItem.vue +85 -0
- package/app/components/ui/command/CommandList.vue +32 -0
- package/app/components/ui/command/CommandSeparator.vue +23 -0
- package/app/components/ui/command/CommandShortcut.vue +19 -0
- package/app/components/ui/command/index.ts +29 -0
- package/app/components/ui/dialog/Dialog.vue +15 -0
- package/app/components/ui/dialog/DialogClose.vue +12 -0
- package/app/components/ui/dialog/DialogContent.vue +61 -0
- package/app/components/ui/dialog/DialogDescription.vue +25 -0
- package/app/components/ui/dialog/DialogFooter.vue +30 -0
- package/app/components/ui/dialog/DialogHeader.vue +17 -0
- package/app/components/ui/dialog/DialogOverlay.vue +28 -0
- package/app/components/ui/dialog/DialogScrollContent.vue +65 -0
- package/app/components/ui/dialog/DialogTitle.vue +25 -0
- package/app/components/ui/dialog/DialogTrigger.vue +12 -0
- package/app/components/ui/dialog/index.ts +10 -0
- package/app/components/ui/dropdown-menu/DropdownMenu.vue +19 -0
- package/app/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +47 -0
- package/app/components/ui/dropdown-menu/DropdownMenuContent.vue +47 -0
- package/app/components/ui/dropdown-menu/DropdownMenuGroup.vue +12 -0
- package/app/components/ui/dropdown-menu/DropdownMenuItem.vue +41 -0
- package/app/components/ui/dropdown-menu/DropdownMenuLabel.vue +27 -0
- package/app/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +21 -0
- package/app/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +48 -0
- package/app/components/ui/dropdown-menu/DropdownMenuSeparator.vue +23 -0
- package/app/components/ui/dropdown-menu/DropdownMenuShortcut.vue +19 -0
- package/app/components/ui/dropdown-menu/DropdownMenuSub.vue +19 -0
- package/app/components/ui/dropdown-menu/DropdownMenuSubContent.vue +34 -0
- package/app/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +34 -0
- package/app/components/ui/dropdown-menu/DropdownMenuTrigger.vue +17 -0
- package/app/components/ui/dropdown-menu/index.ts +16 -0
- package/app/components/ui/input/Input.vue +35 -0
- package/app/components/ui/input/index.ts +1 -0
- package/app/components/ui/navigation-menu/NavigationMenu.vue +42 -0
- package/app/components/ui/navigation-menu/NavigationMenuContent.vue +35 -0
- package/app/components/ui/navigation-menu/NavigationMenuIndicator.vue +32 -0
- package/app/components/ui/navigation-menu/NavigationMenuItem.vue +23 -0
- package/app/components/ui/navigation-menu/NavigationMenuLink.vue +30 -0
- package/app/components/ui/navigation-menu/NavigationMenuList.vue +30 -0
- package/app/components/ui/navigation-menu/NavigationMenuTrigger.vue +31 -0
- package/app/components/ui/navigation-menu/NavigationMenuViewport.vue +30 -0
- package/app/components/ui/navigation-menu/index.ts +14 -0
- package/app/components/ui/scroll-area/ScrollArea.vue +31 -0
- package/app/components/ui/scroll-area/ScrollBar.vue +38 -0
- package/app/components/ui/scroll-area/index.ts +2 -0
- package/app/components/ui/select/Select.vue +15 -0
- package/app/components/ui/select/SelectContent.vue +59 -0
- package/app/components/ui/select/SelectGroup.vue +19 -0
- package/app/components/ui/select/SelectItem.vue +42 -0
- package/app/components/ui/select/SelectItemText.vue +12 -0
- package/app/components/ui/select/SelectLabel.vue +16 -0
- package/app/components/ui/select/SelectScrollDownButton.vue +28 -0
- package/app/components/ui/select/SelectScrollUpButton.vue +28 -0
- package/app/components/ui/select/SelectSeparator.vue +20 -0
- package/app/components/ui/select/SelectTrigger.vue +32 -0
- package/app/components/ui/select/SelectValue.vue +12 -0
- package/app/components/ui/select/index.ts +11 -0
- package/app/components/ui/separator/Separator.vue +30 -0
- package/app/components/ui/separator/index.ts +1 -0
- package/app/components/ui/sheet/Sheet.vue +15 -0
- package/app/components/ui/sheet/SheetClose.vue +12 -0
- package/app/components/ui/sheet/SheetContent.vue +68 -0
- package/app/components/ui/sheet/SheetDescription.vue +23 -0
- package/app/components/ui/sheet/SheetFooter.vue +15 -0
- package/app/components/ui/sheet/SheetHeader.vue +15 -0
- package/app/components/ui/sheet/SheetOverlay.vue +28 -0
- package/app/components/ui/sheet/SheetTitle.vue +23 -0
- package/app/components/ui/sheet/SheetTrigger.vue +12 -0
- package/app/components/ui/sheet/index.ts +8 -0
- package/app/components/ui/sidebar/Sidebar.vue +110 -0
- package/app/components/ui/sidebar/SidebarContent.vue +23 -0
- package/app/components/ui/sidebar/SidebarFooter.vue +18 -0
- package/app/components/ui/sidebar/SidebarGroup.vue +18 -0
- package/app/components/ui/sidebar/SidebarGroupAction.vue +31 -0
- package/app/components/ui/sidebar/SidebarGroupContent.vue +18 -0
- package/app/components/ui/sidebar/SidebarGroupLabel.vue +30 -0
- package/app/components/ui/sidebar/SidebarHeader.vue +18 -0
- package/app/components/ui/sidebar/SidebarInput.vue +19 -0
- package/app/components/ui/sidebar/SidebarInset.vue +23 -0
- package/app/components/ui/sidebar/SidebarMenu.vue +18 -0
- package/app/components/ui/sidebar/SidebarMenuAction.vue +42 -0
- package/app/components/ui/sidebar/SidebarMenuBadge.vue +28 -0
- package/app/components/ui/sidebar/SidebarMenuButton.vue +60 -0
- package/app/components/ui/sidebar/SidebarMenuButtonChild.vue +36 -0
- package/app/components/ui/sidebar/SidebarMenuItem.vue +18 -0
- package/app/components/ui/sidebar/SidebarMenuSkeleton.vue +35 -0
- package/app/components/ui/sidebar/SidebarMenuSub.vue +24 -0
- package/app/components/ui/sidebar/SidebarMenuSubButton.vue +43 -0
- package/app/components/ui/sidebar/SidebarMenuSubItem.vue +18 -0
- package/app/components/ui/sidebar/SidebarProvider.vue +109 -0
- package/app/components/ui/sidebar/SidebarRail.vue +35 -0
- package/app/components/ui/sidebar/SidebarSeparator.vue +19 -0
- package/app/components/ui/sidebar/SidebarTrigger.vue +26 -0
- package/app/components/ui/sidebar/index.ts +62 -0
- package/app/components/ui/sidebar/utils.ts +19 -0
- package/app/components/ui/skeleton/Skeleton.vue +17 -0
- package/app/components/ui/skeleton/index.ts +1 -0
- package/app/components/ui/sonner/Sonner.vue +67 -0
- package/app/components/ui/sonner/index.ts +1 -0
- package/app/components/ui/tabs/Tabs.vue +26 -0
- package/app/components/ui/tabs/TabsContent.vue +23 -0
- package/app/components/ui/tabs/TabsList.vue +28 -0
- package/app/components/ui/tabs/TabsTrigger.vue +30 -0
- package/app/components/ui/tabs/index.ts +4 -0
- package/app/components/ui/textarea/Textarea.vue +32 -0
- package/app/components/ui/textarea/index.ts +1 -0
- package/app/components/ui/tooltip/Tooltip.vue +15 -0
- package/app/components/ui/tooltip/TooltipContent.vue +49 -0
- package/app/components/ui/tooltip/TooltipProvider.vue +14 -0
- package/app/components/ui/tooltip/TooltipTrigger.vue +12 -0
- package/app/components/ui/tooltip/index.ts +4 -0
- package/app/composables/useActiveHeading.ts +90 -0
- package/app/composables/useDuxtAnimatedHeight.ts +155 -0
- package/app/composables/useDuxtBreadcrumb.ts +60 -0
- package/app/composables/useDuxtChoice.ts +28 -0
- package/app/composables/useDuxtCollection.ts +89 -0
- package/app/composables/useDuxtConfig.ts +47 -0
- package/app/composables/useDuxtNavigation.ts +87 -0
- package/app/composables/useDuxtPageFocus.ts +30 -0
- package/app/composables/useDuxtPath.ts +42 -0
- package/app/composables/useDuxtSearch.ts +208 -0
- package/app/composables/useDuxtSection.ts +44 -0
- package/app/composables/useDuxtSectionRow.ts +49 -0
- package/app/composables/useDuxtShortcuts.ts +58 -0
- package/app/composables/useDuxtSiteUrl.ts +27 -0
- package/app/composables/useDuxtToast.ts +25 -0
- package/app/composables/useDuxtVersion.ts +138 -0
- package/app/composables/useFuzzySearch.ts +83 -0
- package/app/composables/usePackageManager.ts +4 -0
- package/app/composables/useRecentPages.ts +52 -0
- package/app/error.vue +133 -0
- package/app/layouts/changelog.vue +85 -0
- package/app/layouts/default.vue +23 -0
- package/app/layouts/docs.vue +62 -0
- package/app/layouts/reference.vue +85 -0
- package/app/lib/utils.ts +7 -0
- package/app/middleware/duxt-section-layout.global.ts +57 -0
- package/app/pages/[...slug].vue +441 -0
- package/app/pages/index.vue +479 -0
- package/app/types/duxt.d.ts +955 -0
- package/app/utils/aside.ts +16 -0
- package/app/utils/changelog.ts +182 -0
- package/app/utils/code-highlight.ts +116 -0
- package/app/utils/duxt-config.ts +185 -0
- package/app/utils/duxt-text.ts +135 -0
- package/app/utils/file-icons.ts +62 -0
- package/app/utils/generated-sections.ts +190 -0
- package/app/utils/generated-toc.ts +216 -0
- package/app/utils/heading-link.ts +32 -0
- package/app/utils/locale-path.ts +45 -0
- package/app/utils/navigation-tree.ts +206 -0
- package/app/utils/nearest-page.ts +72 -0
- package/app/utils/openapi.ts +1028 -0
- package/app/utils/package-command.ts +162 -0
- package/app/utils/request-samples.ts +635 -0
- package/app/utils/section-scope.ts +97 -0
- package/app/utils/sheet-navigation.ts +100 -0
- package/app/utils/source-file.ts +84 -0
- package/app/utils/version-choices.ts +68 -0
- package/app/utils/version-paths.ts +65 -0
- package/bin/duxt-report.mjs +45 -0
- package/components.json +19 -0
- package/content-cache.ts +193 -0
- package/content.config.ts +38 -0
- package/duxt-app-config.ts +124 -0
- package/highlight-langs.ts +68 -0
- package/i18n/i18n.config.ts +16 -0
- package/i18n/locales/de/duxt/changelog.json +17 -0
- package/i18n/locales/de/duxt/code.json +13 -0
- package/i18n/locales/de/duxt/defaults.json +22 -0
- package/i18n/locales/de/duxt/devtools.json +7 -0
- package/i18n/locales/de/duxt/error.json +10 -0
- package/i18n/locales/de/duxt/footer.json +7 -0
- package/i18n/locales/de/duxt/locale.json +7 -0
- package/i18n/locales/de/duxt/nav.json +17 -0
- package/i18n/locales/de/duxt/openapi.json +89 -0
- package/i18n/locales/de/duxt/page.json +34 -0
- package/i18n/locales/de/duxt/search.json +12 -0
- package/i18n/locales/de/duxt/shortcuts.json +11 -0
- package/i18n/locales/de/duxt/theme.json +7 -0
- package/i18n/locales/de/duxt/toc.json +7 -0
- package/i18n/locales/de/duxt/version.json +25 -0
- package/i18n/locales/en/duxt/changelog.json +17 -0
- package/i18n/locales/en/duxt/code.json +13 -0
- package/i18n/locales/en/duxt/defaults.json +22 -0
- package/i18n/locales/en/duxt/devtools.json +7 -0
- package/i18n/locales/en/duxt/error.json +10 -0
- package/i18n/locales/en/duxt/footer.json +7 -0
- package/i18n/locales/en/duxt/locale.json +7 -0
- package/i18n/locales/en/duxt/nav.json +17 -0
- package/i18n/locales/en/duxt/openapi.json +89 -0
- package/i18n/locales/en/duxt/page.json +34 -0
- package/i18n/locales/en/duxt/search.json +12 -0
- package/i18n/locales/en/duxt/shortcuts.json +11 -0
- package/i18n/locales/en/duxt/theme.json +7 -0
- package/i18n/locales/en/duxt/toc.json +7 -0
- package/i18n/locales/en/duxt/version.json +25 -0
- package/i18n/locales/es/duxt/changelog.json +17 -0
- package/i18n/locales/es/duxt/code.json +13 -0
- package/i18n/locales/es/duxt/defaults.json +22 -0
- package/i18n/locales/es/duxt/devtools.json +7 -0
- package/i18n/locales/es/duxt/error.json +10 -0
- package/i18n/locales/es/duxt/footer.json +7 -0
- package/i18n/locales/es/duxt/locale.json +7 -0
- package/i18n/locales/es/duxt/nav.json +17 -0
- package/i18n/locales/es/duxt/openapi.json +89 -0
- package/i18n/locales/es/duxt/page.json +34 -0
- package/i18n/locales/es/duxt/search.json +12 -0
- package/i18n/locales/es/duxt/shortcuts.json +11 -0
- package/i18n/locales/es/duxt/theme.json +7 -0
- package/i18n/locales/es/duxt/toc.json +7 -0
- package/i18n/locales/es/duxt/version.json +25 -0
- package/i18n/locales/fr/duxt/changelog.json +17 -0
- package/i18n/locales/fr/duxt/code.json +13 -0
- package/i18n/locales/fr/duxt/defaults.json +22 -0
- package/i18n/locales/fr/duxt/devtools.json +7 -0
- package/i18n/locales/fr/duxt/error.json +10 -0
- package/i18n/locales/fr/duxt/footer.json +7 -0
- package/i18n/locales/fr/duxt/locale.json +7 -0
- package/i18n/locales/fr/duxt/nav.json +17 -0
- package/i18n/locales/fr/duxt/openapi.json +89 -0
- package/i18n/locales/fr/duxt/page.json +34 -0
- package/i18n/locales/fr/duxt/search.json +12 -0
- package/i18n/locales/fr/duxt/shortcuts.json +11 -0
- package/i18n/locales/fr/duxt/theme.json +7 -0
- package/i18n/locales/fr/duxt/toc.json +7 -0
- package/i18n/locales/fr/duxt/version.json +25 -0
- package/i18n/locales/pt/duxt/changelog.json +17 -0
- package/i18n/locales/pt/duxt/code.json +13 -0
- package/i18n/locales/pt/duxt/defaults.json +22 -0
- package/i18n/locales/pt/duxt/devtools.json +7 -0
- package/i18n/locales/pt/duxt/error.json +10 -0
- package/i18n/locales/pt/duxt/footer.json +7 -0
- package/i18n/locales/pt/duxt/locale.json +7 -0
- package/i18n/locales/pt/duxt/nav.json +17 -0
- package/i18n/locales/pt/duxt/openapi.json +89 -0
- package/i18n/locales/pt/duxt/page.json +34 -0
- package/i18n/locales/pt/duxt/search.json +12 -0
- package/i18n/locales/pt/duxt/shortcuts.json +11 -0
- package/i18n/locales/pt/duxt/theme.json +7 -0
- package/i18n/locales/pt/duxt/toc.json +7 -0
- package/i18n/locales/pt/duxt/version.json +25 -0
- package/i18n/locales/pt-BR/duxt/error.json +8 -0
- package/i18n/locales/pt-BR/duxt/nav.json +10 -0
- package/i18n/locales/pt-BR/duxt/page.json +10 -0
- package/i18n/locales/pt-BR/duxt/search.json +11 -0
- package/i18n/locales/pt-BR/duxt/version.json +13 -0
- package/mdc.config.ts +28 -0
- package/modules/config.ts +440 -0
- package/modules/devtools.ts +126 -0
- package/modules/git-meta.ts +349 -0
- package/modules/redirects.ts +152 -0
- package/modules/validate.ts +137 -0
- package/nuxt.config.ts +530 -0
- package/openapi-model.ts +358 -0
- package/openapi-parse.ts +1052 -0
- package/package.json +161 -0
- package/public/devtools/cache.html +318 -0
- package/public/devtools/checks.html +309 -0
- package/public/devtools/config.html +461 -0
- package/public/devtools/i18n.html +309 -0
- package/public/devtools/pages.html +348 -0
- package/public/devtools/paths.html +315 -0
- package/public/devtools/redirects.html +309 -0
- package/public/devtools/search.html +324 -0
- package/public/devtools/sources.html +309 -0
- package/public/devtools/versions.html +318 -0
- package/report.ts +303 -0
- package/repository-root.ts +26 -0
- package/section-reports.ts +55 -0
- package/sections-changelog.ts +644 -0
- package/sections-openapi.ts +450 -0
- package/sections-resolve.ts +711 -0
- package/sections.ts +157 -0
- package/server/devtools/content.ts +120 -0
- package/server/devtools/context.ts +38 -0
- package/server/devtools/entry-path.ts +30 -0
- package/server/devtools/handler.ts +104 -0
- package/server/devtools/preview.ts +461 -0
- package/server/devtools/render/content.ts +233 -0
- package/server/devtools/render/sources.ts +414 -0
- package/server/devtools/render/system.ts +352 -0
- package/server/devtools/shell.ts +611 -0
- package/server/devtools/sources.ts +122 -0
- package/server/devtools/system.ts +178 -0
- package/server/mcp/tools/list-pages.ts +52 -0
- package/server/mcp/tools/read-page.ts +57 -0
- package/server/mcp/tools/search-docs.ts +74 -0
- package/server/middleware/raw-markdown.ts +86 -0
- package/server/routes/llms-full.txt.get.ts +75 -0
- package/server/routes/llms.txt.get.ts +63 -0
- package/server/routes/rss.xml.get.ts +125 -0
- package/server/utils/duxt-server-text.ts +46 -0
- package/sources-git.ts +113 -0
- package/sources-resolve.ts +908 -0
- package/sources.ts +287 -0
- package/validate-report.ts +494 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Titus Kirch
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<picture>
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset=".github/assets/wordmark-dark.svg">
|
|
5
|
+
<img src=".github/assets/wordmark-light.svg" alt="duxt" width="200" />
|
|
6
|
+
</picture>
|
|
7
|
+
|
|
8
|
+
**Versioned, multi-repo documentation for Nuxt โ one line to extend, no collection boilerplate**
|
|
9
|
+
|
|
10
|
+
[](https://www.npmjs.com/package/@kirchdev/duxt)
|
|
11
|
+
[](https://www.npmjs.com/package/@kirchdev/duxt)
|
|
12
|
+
[](https://github.com/kirchDev/duxt/actions/workflows/ci.yml)
|
|
13
|
+
[](https://www.npmjs.com/package/@kirchdev/duxt)
|
|
14
|
+
[](LICENSE)
|
|
15
|
+
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
export default defineNuxtConfig({
|
|
22
|
+
extends: ['@kirchdev/duxt'],
|
|
23
|
+
})
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
That's it. Put your Markdown in `docs/` and you have a themed documentation site โ search, navigation, table of contents, dark mode, `llms.txt` and an MCP server โ with no collection, no layout and no config written by hand.
|
|
27
|
+
|
|
28
|
+
## ๐ค Why
|
|
29
|
+
|
|
30
|
+
Nuxt Content v3 already downloads and caches a git repository, at a branch or at a tag, private ones included โ so nothing here rebuilds that. What it does not give you is the part that gets retyped in every documentation repo: one collection per version ร repository, a URL scheme that carries them, a version switcher that knows which page exists where, and a theme on top.
|
|
31
|
+
|
|
32
|
+
duxt turns all of it into one list. Sources are declared once, and the collections, the prefixes, the switcher, the redirects and the sitemap are generated from that declaration.
|
|
33
|
+
|
|
34
|
+
## ๐ฆ Install & run
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pnpm add -D @kirchdev/duxt
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The `extends` line above is the whole of the single-folder case. Everything beyond it is one file โ `app/app.config.ts`, which both halves of the layer read:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
export default defineAppConfig({
|
|
44
|
+
duxt: {
|
|
45
|
+
title: 'Acme',
|
|
46
|
+
sources: [
|
|
47
|
+
{ path: 'docs', slug: 'acme' }, // this repository
|
|
48
|
+
{ repo: 'acme/api', path: 'docs', refs: ['main', 'v2.0.0', 'v1.4.0'] },
|
|
49
|
+
],
|
|
50
|
+
sourceOptions: { defaultRef: 'v2.0.0' },
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Two repositories and three refs become five collections, the URL prefixes that serve them, and a version switcher โ none of which you write.
|
|
56
|
+
|
|
57
|
+
## โจ Features
|
|
58
|
+
|
|
59
|
+
- **๐ฆ Extend, don't scaffold** โ a Nuxt layer: theme, pages, components and `app.config` defaults arrive with `extends` and are overridden file by file where you disagree.
|
|
60
|
+
- **๐๏ธ Sources as a list** โ one compact entry per source instead of one Content collection per version ร repository.
|
|
61
|
+
- **๐งญ Version switcher and URL scheme** โ `/[repo]/[version]/[...slug]`, collapsing cleanly when there is one source and no versions, with a lifecycle per version that decides the banner a reader gets.
|
|
62
|
+
- **๐ฟ Git-native sourcing** โ branches, tags, private repositories and hash-based caching come straight from Content v3's own `repository` support; `'latest'` resolves to the newest semver tag at build time.
|
|
63
|
+
- **๐ค Machine-readable by default** โ `llms.txt`, `llms-full.txt` and a real MCP server at `/mcp`, generated from the same collections the pages render from.
|
|
64
|
+
- **๐จ shadcn-vue theme, owned not vendored** โ Tailwind 4 with the components in `app/components/ui/`, MDC components in `app/components/content/`.
|
|
65
|
+
- **๐ Search, TOC, breadcrumb, prev/next** โ โK fuzzy search across every source, active-heading tracking, section landing pages, feedback and "Edit this page" links.
|
|
66
|
+
- **๐งฏ A build that fails loudly** โ a validator walks the parse cache for URL collisions, empty collections, broken links and missing titles, because every bug this layer actually had was a silent one.
|
|
67
|
+
|
|
68
|
+
<details>
|
|
69
|
+
<summary>Full feature list</summary>
|
|
70
|
+
|
|
71
|
+
### Sources & versions
|
|
72
|
+
|
|
73
|
+
- **๐๏ธ Sources as a list** โ one compact entry per source instead of one Content collection per version ร repository. The single unversioned folder is the default and needs no config at all.
|
|
74
|
+
- **๐งญ Version switcher and URL scheme** โ `/[repo]/[version]/[...slug]`, collapsing cleanly when there is one source and no versions, with a lifecycle per version (`upcoming`, `current`, `maintained`, `deprecated`, `eol`) that decides the banner a reader gets.
|
|
75
|
+
- **๐ฟ Git-native sourcing** โ branches, tags, private repositories and hash-based caching come straight from Content v3's own `repository` support; `'latest'` resolves to the newest semver tag at build time.
|
|
76
|
+
- **๐ Redirects from frontmatter** โ `redirectFrom` on a moved page becomes route rules under every repository, version and locale prefix it is served at.
|
|
77
|
+
|
|
78
|
+
### Theme & reading experience
|
|
79
|
+
|
|
80
|
+
- **๐จ shadcn-vue theme, owned not vendored** โ Tailwind 4 with the components in `app/components/ui/`, MDC components (`::callout`, `::steps`, `::code-group`, file trees, Mermaid) in `app/components/content/`.
|
|
81
|
+
- **๐ Search, TOC, breadcrumb, prev/next** โ โK fuzzy search across every source, active-heading tracking, section landing pages, feedback and "Edit this page" links.
|
|
82
|
+
- **๐ Seven locales out of the box** โ `en-GB`, `en-US`, `de-DE`, `es-ES`, `fr-FR`, `pt-PT` and `pt-BR`; a site picks which of them it serves, and its own strings take a literal, a key or a per-locale record.
|
|
83
|
+
|
|
84
|
+
### Machine-readable & SEO
|
|
85
|
+
|
|
86
|
+
- **๐ค Machine-readable by default** โ `llms.txt`, `llms-full.txt` and a real MCP server at `/mcp` (list pages, read a page, search), generated from the same collections the pages render from.
|
|
87
|
+
- **๐ SEO and feeds included** โ sitemap, robots, generated OG images, and an optional `/rss.xml` over a section you nominate.
|
|
88
|
+
|
|
89
|
+
### Layer & build
|
|
90
|
+
|
|
91
|
+
- **๐ฆ Extend, don't scaffold** โ a Nuxt layer: theme, pages, components and `app.config` defaults arrive with `extends` and are overridden file by file where you disagree.
|
|
92
|
+
- **๐งฏ A build that fails loudly** โ a validator walks the parse cache for URL collisions, empty collections, broken links and missing titles, because every bug this layer actually had was a silent one.
|
|
93
|
+
- **๐ DevTools tab** โ the resolved sources, collections, prefixes, message catalogues and download cache, in dev, where guessing used to be the only option.
|
|
94
|
+
|
|
95
|
+
</details>
|
|
96
|
+
|
|
97
|
+
## โ๏ธ Configuration
|
|
98
|
+
|
|
99
|
+
Everything lives under the `duxt` key of `app.config.ts`. The keys most sites touch:
|
|
100
|
+
|
|
101
|
+
| Key | What it controls |
|
|
102
|
+
| :-------------- | :------------------------------------------------------------------------ |
|
|
103
|
+
| `sources` | The documentation sources โ folder, repository, refs, lifecycle, history. |
|
|
104
|
+
| `sourceOptions` | How those become URL prefixes (`defaultRef`, `showRepo`, `showVersion`). |
|
|
105
|
+
| `title` | The site name, in the navbar and every generated document. |
|
|
106
|
+
| `locales` | Which of the layer's locales this site serves. Read at build time. |
|
|
107
|
+
|
|
108
|
+
Every text field takes a literal, an i18n key, or a per-locale record โ a single-language site never sees the other two.
|
|
109
|
+
|
|
110
|
+
> [!TIP]
|
|
111
|
+
> The full surface โ `navigation`, `sections`, `landing`, `feed`, `footer` and the rest โ is typed, and the types are the documentation: [`app/types/duxt.d.ts`](app/types/duxt.d.ts) carries a comment per key explaining what it costs and when it is read.
|
|
112
|
+
|
|
113
|
+
## ๐งช Development
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
git clone https://github.com/kirchDev/duxt.git
|
|
117
|
+
cd duxt
|
|
118
|
+
pnpm install # wires the husky hooks
|
|
119
|
+
pnpm check # lint + format + typecheck + tests + policy parity + build + a11y
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The repo root **is** the layer โ `nuxt.config.ts`, `content.config.ts`, `app/`, `modules/` and `server/` live there, and `package.json` points at them. `www/` beside it is the site that consumes the layer, and the development target: it deliberately carries the awkward cases โ two repositories, four refs, one version of each lifecycle. It is not a template; the exemplary starting point lives in [`kirchDev/duxt-starter`](https://github.com/kirchDev/duxt-starter).
|
|
123
|
+
|
|
124
|
+
## ๐จ Assets & branding
|
|
125
|
+
|
|
126
|
+
The mark is the package name with its first letter bracketed โ `[d]uxt` โ because that is how the package is written where it is used: `extends: ['@kirchdev/duxt']`, an array with one entry. It is set in [IBM Plex Mono](https://github.com/IBM/plex) SemiBold and converted to outlines, so no asset depends on the font being installed anywhere.
|
|
127
|
+
|
|
128
|
+
> [!NOTE]
|
|
129
|
+
> The wordmark is **AI-assisted placeholder artwork** โ a stand-in to be replaced at some point, with no fixed timeline. No image generator was involved: it is typeset, not drawn.
|
|
130
|
+
|
|
131
|
+
Every asset, the colour values, why the icon's brackets are redrawn and the font licensing are in [Conventions โ Branding](https://duxt.app/conventions/branding).
|
|
132
|
+
|
|
133
|
+
> [!IMPORTANT]
|
|
134
|
+
> The layer ships **no** branding. `duxt.logo` is unset by default, so `DuxtBrand` falls back to the consumer's own `duxt.title` beside a generic icon: a site extending duxt shows its own name in the header and footer and its own icon in the tab, never this one. These assets belong to this repository and to `www/`, not to the published package.
|
|
135
|
+
|
|
136
|
+
## ๐ค Contributing
|
|
137
|
+
|
|
138
|
+
PRs welcome. Conventional Commits are enforced via commitlint, and husky runs the linters on `git commit`. Branch off `dev`.
|
|
139
|
+
|
|
140
|
+
> [!TIP]
|
|
141
|
+
> Run `pnpm check:fix` before pushing โ CI will catch what husky missed.
|
|
142
|
+
|
|
143
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for the full workflow.
|
|
144
|
+
|
|
145
|
+
## ๐ฃ๏ธ Versioning
|
|
146
|
+
|
|
147
|
+
[Semantic Versioning](https://semver.org/) via [release-please](https://github.com/googleapis/release-please) โ see the [releases](https://github.com/kirchDev/duxt/releases).
|
|
148
|
+
|
|
149
|
+
## ๐ License
|
|
150
|
+
|
|
151
|
+
[MIT](LICENSE) ยฉ [Titus Kirch](https://github.com/TitusKirch/) / [IT-Dienstleistungen Titus Kirch](https://kirch.dev)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// The layer ships NO app.config values.
|
|
2
|
+
//
|
|
3
|
+
// Its defaults live in app/utils/duxt-config.ts, because Nuxt merges app.config
|
|
4
|
+
// with defu and defu concatenates arrays โ a consumer overriding `navigation`
|
|
5
|
+
// would get the layer's entries appended to its own. `useDuxtConfig()` merges
|
|
6
|
+
// them itself, replacing arrays rather than adding to them.
|
|
7
|
+
//
|
|
8
|
+
// The resolved source manifest used to be the one exception that had to sit
|
|
9
|
+
// here. It no longer does: the duxt module resolves it from the site's own
|
|
10
|
+
// `app.config.ts` and writes it back as `resolvedSources`.
|
|
11
|
+
export default defineAppConfig({
|
|
12
|
+
duxt: {}
|
|
13
|
+
});
|
package/app/app.vue
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* The locale's head tags.
|
|
4
|
+
*
|
|
5
|
+
* `lang` and `dir` are set by hand rather than through `useLocaleHead`, because
|
|
6
|
+
* that composable warns ONCE PER RENDER when the site has no `baseUrl` โ and it
|
|
7
|
+
* does so from `createHeadContext`, before it ever looks at whether alternate
|
|
8
|
+
* links were asked for. Passing `seo: false` does not quiet it; not calling it
|
|
9
|
+
* does.
|
|
10
|
+
*
|
|
11
|
+
* So the alternate links โ the ones telling a search engine these pages are
|
|
12
|
+
* translations of one another rather than duplicates โ are emitted only when
|
|
13
|
+
* the site knows its own origin. That is also the honest way round: a relative
|
|
14
|
+
* `hreflang` is not a valid one, and telling a crawler nothing beats telling it
|
|
15
|
+
* something untrue.
|
|
16
|
+
*
|
|
17
|
+
* Set `NUXT_PUBLIC_I18N_BASE_URL` in the deployment, or `i18n.baseUrl` in the
|
|
18
|
+
* consumer's config; duxt cannot guess it.
|
|
19
|
+
*/
|
|
20
|
+
const { locale, locales } = useI18n();
|
|
21
|
+
const duxt = useDuxtConfig();
|
|
22
|
+
|
|
23
|
+
const baseUrl = (useRuntimeConfig().public as { i18n?: { baseUrl?: string } })
|
|
24
|
+
.i18n?.baseUrl;
|
|
25
|
+
|
|
26
|
+
const direction = computed(() => {
|
|
27
|
+
const current = locales.value.find(
|
|
28
|
+
(entry) => (typeof entry === 'string' ? entry : entry.code) === locale.value
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
return (typeof current === 'object' && current?.dir) || 'ltr';
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
useHead(() => ({
|
|
35
|
+
htmlAttrs: { lang: locale.value, dir: direction.value },
|
|
36
|
+
|
|
37
|
+
// Every page said only its own title, so a tab, a bookmark and a search
|
|
38
|
+
// result all read "Deploying" with nothing saying whose documentation it is.
|
|
39
|
+
// A page setting no title of its own gets the site name alone rather than a
|
|
40
|
+
// dangling separator.
|
|
41
|
+
titleTemplate: (title?: string) =>
|
|
42
|
+
title ? `${title} ยท ${duxt.title}` : duxt.title,
|
|
43
|
+
|
|
44
|
+
// A feed a reader's client can find without being told where it is. Only
|
|
45
|
+
// when there is one โ see `duxt.feed`.
|
|
46
|
+
link: duxt.feed?.path
|
|
47
|
+
? [
|
|
48
|
+
{
|
|
49
|
+
rel: 'alternate',
|
|
50
|
+
type: 'application/rss+xml',
|
|
51
|
+
title: duxt.feed.title ?? duxt.title,
|
|
52
|
+
href: '/rss.xml'
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
: []
|
|
56
|
+
}));
|
|
57
|
+
|
|
58
|
+
if (baseUrl) {
|
|
59
|
+
const localeHead = useLocaleHead({ dir: false, lang: false, seo: true });
|
|
60
|
+
useHead(() => localeHead.value);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* `og:locale`, which nuxt-seo-utils does not derive from i18n.
|
|
65
|
+
*
|
|
66
|
+
* Open Graph spells a locale with an underscore โ `de_DE`, not `de-DE` โ and
|
|
67
|
+
* the alternates are the OTHER locales this site serves, so a share card comes
|
|
68
|
+
* back in the reader's language where the network offers the choice. Only where
|
|
69
|
+
* the site has more than one; a single-locale site listing no alternates is
|
|
70
|
+
* correct, not incomplete.
|
|
71
|
+
*/
|
|
72
|
+
const ogLocale = (code: string) => code.replace('-', '_');
|
|
73
|
+
|
|
74
|
+
useSeoMeta({
|
|
75
|
+
ogSiteName: () => duxt.title,
|
|
76
|
+
ogLocale: () => ogLocale(locale.value),
|
|
77
|
+
ogLocaleAlternate: () =>
|
|
78
|
+
locales.value
|
|
79
|
+
.map((entry) => (typeof entry === 'string' ? entry : entry.code))
|
|
80
|
+
.filter((code) => code !== locale.value)
|
|
81
|
+
.map(ogLocale)
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* WHAT THE SITE IS, once, for every page under it.
|
|
86
|
+
*
|
|
87
|
+
* nuxt-schema-org keeps one `@graph` per document and merges into it, so this
|
|
88
|
+
* node and the per-page `Article` in `[...slug].vue` end up in the same script
|
|
89
|
+
* tag with the references between them resolved โ which is the whole reason the
|
|
90
|
+
* hand-written JSON-LD that used to live there could go.
|
|
91
|
+
*
|
|
92
|
+
* The `Organization` is conditional and stays that way: duxt renders somebody
|
|
93
|
+
* else's documentation and must not name a publisher it invented. A consumer
|
|
94
|
+
* fills in `duxt.organization`; until then the site describes itself and no
|
|
95
|
+
* more.
|
|
96
|
+
*/
|
|
97
|
+
useSchemaOrg([
|
|
98
|
+
defineWebSite({
|
|
99
|
+
name: duxt.title,
|
|
100
|
+
inLanguage: locale.value
|
|
101
|
+
}),
|
|
102
|
+
...(duxt.organization?.name
|
|
103
|
+
? [
|
|
104
|
+
defineOrganization({
|
|
105
|
+
name: duxt.organization.name,
|
|
106
|
+
url: duxt.organization.url,
|
|
107
|
+
logo: duxt.organization.logo
|
|
108
|
+
})
|
|
109
|
+
]
|
|
110
|
+
: [])
|
|
111
|
+
]);
|
|
112
|
+
</script>
|
|
113
|
+
|
|
114
|
+
<template>
|
|
115
|
+
<!-- Reads the new page's title into a live region after a client-side
|
|
116
|
+
navigation; the focus half of the same problem is useDuxtPageFocus. -->
|
|
117
|
+
<NuxtRouteAnnouncer />
|
|
118
|
+
|
|
119
|
+
<NuxtLayout>
|
|
120
|
+
<NuxtPage />
|
|
121
|
+
</NuxtLayout>
|
|
122
|
+
</template>
|