@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/sources.ts
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { defineCollection, z } from '@nuxt/content';
|
|
3
|
+
import { defineSitemapSchema } from '@nuxtjs/sitemap/content';
|
|
4
|
+
import type { DuxtSource, DuxtSourcesOptions } from './sources-resolve';
|
|
5
|
+
import {
|
|
6
|
+
expandSources,
|
|
7
|
+
refIsTag,
|
|
8
|
+
refName,
|
|
9
|
+
repoUrl,
|
|
10
|
+
resolveSources
|
|
11
|
+
} from './sources-resolve';
|
|
12
|
+
import { resolveLatestRefs } from './sources-git';
|
|
13
|
+
// Re-exported under the name it has always had here: it moved out so a Nuxt
|
|
14
|
+
// module could reach it without this file's imports coming with it.
|
|
15
|
+
import { repositoryRoot } from './repository-root';
|
|
16
|
+
export { repositoryRoot };
|
|
17
|
+
export type {
|
|
18
|
+
DuxtResolvedSource,
|
|
19
|
+
DuxtSource,
|
|
20
|
+
DuxtSourcesOptions
|
|
21
|
+
} from './sources-resolve';
|
|
22
|
+
export { duxtSourceManifest } from './sources-resolve';
|
|
23
|
+
// Named beside the resolver, not here: the app reads it to pick a partial's
|
|
24
|
+
// language, and this file imports `@nuxt/content` — which the bundler refuses
|
|
25
|
+
// to follow out of client code.
|
|
26
|
+
import { PARTIALS_COLLECTION, partialsCollection } from './sources-resolve';
|
|
27
|
+
export { PARTIALS_COLLECTION, partialsCollection };
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Frontmatter the theme reads beyond Content's own fields.
|
|
31
|
+
*
|
|
32
|
+
* Without a schema Content neither stores these nor types them, so `icon:` in a
|
|
33
|
+
* page's frontmatter was silently dropped before the sidebar ever saw it.
|
|
34
|
+
*/
|
|
35
|
+
export const pageSchema = z.object({
|
|
36
|
+
/** Shown beside the entry in the sidebar, the section row and page cards. */
|
|
37
|
+
icon: z.string().optional(),
|
|
38
|
+
/** `landing` renders the page without the docs chrome. */
|
|
39
|
+
layout: z.string().optional(),
|
|
40
|
+
/** false hides the page from the navigation. */
|
|
41
|
+
navigation: z.boolean().optional(),
|
|
42
|
+
/**
|
|
43
|
+
* URLs this page used to be served at. The layer turns them into redirects,
|
|
44
|
+
* because it is the only thing that knows which prefixes exist — the
|
|
45
|
+
* alternative is the same rule written into every consumer's web server.
|
|
46
|
+
*/
|
|
47
|
+
redirectFrom: z.array(z.string()).optional(),
|
|
48
|
+
/**
|
|
49
|
+
* The Markdown as it was written.
|
|
50
|
+
*
|
|
51
|
+
* Content only stores it when the schema asks for it — the key is what the
|
|
52
|
+
* `collectionKeys.includes('rawbody')` check looks for. Two things need it:
|
|
53
|
+
* the button that hands a page to a model, and `llms-full.txt`.
|
|
54
|
+
*/
|
|
55
|
+
rawbody: z.string().optional(),
|
|
56
|
+
/**
|
|
57
|
+
* When this page is dated, for a feed. A changelog entry has one; a
|
|
58
|
+
* reference page does not, and falls back to its last commit.
|
|
59
|
+
*/
|
|
60
|
+
date: z.string().optional(),
|
|
61
|
+
/**
|
|
62
|
+
* The diff this page was cut from — a changelog release links the commits it
|
|
63
|
+
* carries, taken off the heading release-please wrapped the version in.
|
|
64
|
+
*
|
|
65
|
+
* Beside `date` because it answers the other half of the same question, and
|
|
66
|
+
* it is drawn in the same place: the provenance block under the contents,
|
|
67
|
+
* where "Edit this page" already sends a reader at the repository.
|
|
68
|
+
*/
|
|
69
|
+
compare: z.string().optional(),
|
|
70
|
+
/** Filled in by `modules/git-meta.ts`; not written by hand. */
|
|
71
|
+
lastUpdated: z.string().optional(),
|
|
72
|
+
/** Filled in by `modules/git-meta.ts`; not written by hand. */
|
|
73
|
+
contributors: z
|
|
74
|
+
.array(
|
|
75
|
+
z.object({
|
|
76
|
+
name: z.string(),
|
|
77
|
+
commits: z.number(),
|
|
78
|
+
username: z.string().optional()
|
|
79
|
+
})
|
|
80
|
+
)
|
|
81
|
+
.optional(),
|
|
82
|
+
/**
|
|
83
|
+
* What puts these pages in the sitemap at all.
|
|
84
|
+
*
|
|
85
|
+
* @nuxtjs/sitemap does not walk Content's collections uninvited — a
|
|
86
|
+
* collection has to declare the field, and without it the sitemap lists the
|
|
87
|
+
* site's routes and not one documentation page. Which versions are listed is
|
|
88
|
+
* a separate decision, taken in `modules/config.ts` from the manifest.
|
|
89
|
+
*/
|
|
90
|
+
//
|
|
91
|
+
// `z` is handed in on purpose: @nuxtjs/sitemap bundles a zod of its own, and
|
|
92
|
+
// Content reads a schema by inspecting zod's internals. A field built by the
|
|
93
|
+
// foreign copy is not recognised, silently dropped from the collection, and
|
|
94
|
+
// the sitemap module's own guard — "is `sitemap` among this collection's
|
|
95
|
+
// fields?" — then answers no and nulls the field it just asked for. The
|
|
96
|
+
// symptom is a sitemap with one entry on a site with sixty pages.
|
|
97
|
+
sitemap: defineSitemapSchema({ z })
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* A draft is a file, not a flag.
|
|
102
|
+
*
|
|
103
|
+
* `draft: true` in frontmatter is the obvious spelling and the one that cannot
|
|
104
|
+
* be honoured: a collection's contents are declared before Content has read a
|
|
105
|
+
* single file, and for a remote source before it has even been downloaded, so
|
|
106
|
+
* nothing at declaration time knows what the frontmatter says. A file NAME is
|
|
107
|
+
* known — and Content already strips `.draft` out of the URL, so
|
|
108
|
+
* `deploying.draft.md` serves `/deploying` in the dev server and is simply
|
|
109
|
+
* absent from the build.
|
|
110
|
+
*/
|
|
111
|
+
const DRAFTS = '**/*.draft.md';
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Reusable blocks, shared across every source.
|
|
115
|
+
*
|
|
116
|
+
* Content ships no include directive, and across several repositories that is a
|
|
117
|
+
* gap with no workaround at all: an install note or a support matrix that has
|
|
118
|
+
* to read the same in three projects is copied into three projects and drifts.
|
|
119
|
+
* So `_partials/` in ANY source's docs folder feeds one collection, and
|
|
120
|
+
* `:partial{name="install"}` in any page of any source renders it.
|
|
121
|
+
*
|
|
122
|
+
* Excluded from the page collections themselves, or every partial would also
|
|
123
|
+
* be a page — in the sidebar, in the search, in llms.txt.
|
|
124
|
+
*/
|
|
125
|
+
const PARTIALS = '**/_partials/**';
|
|
126
|
+
|
|
127
|
+
/** The dev server shows drafts; a build does not. */
|
|
128
|
+
const includeDrafts = () => process.env.NODE_ENV !== 'production';
|
|
129
|
+
|
|
130
|
+
const excluded = () => (includeDrafts() ? [PARTIALS] : [PARTIALS, DRAFTS]);
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Turn a compact source list into Content collections.
|
|
134
|
+
*
|
|
135
|
+
* Three versions across fourteen repositories is 42 collections written by
|
|
136
|
+
* hand; this is the whole reason the shorthand exists. Naming and prefixes come
|
|
137
|
+
* from `resolveSources`, which the app reads too — see `duxtSourceManifest`.
|
|
138
|
+
*/
|
|
139
|
+
export function duxtSources(
|
|
140
|
+
input: DuxtSource[],
|
|
141
|
+
options: DuxtSourcesOptions = {}
|
|
142
|
+
) {
|
|
143
|
+
// `latest` is a shorthand for a tag git has to be asked about, and both the
|
|
144
|
+
// collections here and the manifest the module resolves must land on the
|
|
145
|
+
// same one — so it is settled before either reads the list.
|
|
146
|
+
const sources = resolveLatestRefs(input);
|
|
147
|
+
const resolved = resolveSources(sources, options);
|
|
148
|
+
const collections: Record<string, ReturnType<typeof defineCollection>> = {};
|
|
149
|
+
|
|
150
|
+
// The SAME expansion the manifest is built from, so entry `n` here and entry
|
|
151
|
+
// `n` there are the same source, ref and language. See `expandSources`.
|
|
152
|
+
const expanded = expandSources(sources, options);
|
|
153
|
+
|
|
154
|
+
resolved.forEach((entry, index) => {
|
|
155
|
+
const { source, ref, effective } = expanded[index]!;
|
|
156
|
+
|
|
157
|
+
// A locale entry may carry a ref of its own — a translation repository
|
|
158
|
+
// that tags on its own schedule.
|
|
159
|
+
const usedRef = effective.ref ?? ref;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* The translations living INSIDE this source's own folder.
|
|
163
|
+
*
|
|
164
|
+
* The default locale reads `docs/` with `**\/*.md`, and that glob happily
|
|
165
|
+
* swallows `docs/de-DE/` — the original collection would carry every
|
|
166
|
+
* translated page a second time, under a path beginning with the locale,
|
|
167
|
+
* and the sidebar would show both. So each folder a sibling language
|
|
168
|
+
* occupies is excluded from the language that contains it.
|
|
169
|
+
*/
|
|
170
|
+
const nested = expanded
|
|
171
|
+
.filter(
|
|
172
|
+
(other) =>
|
|
173
|
+
other.source === source &&
|
|
174
|
+
other.effective.repo === effective.repo &&
|
|
175
|
+
other.effective.path !== effective.path &&
|
|
176
|
+
other.effective.path.startsWith(`${effective.path}/`)
|
|
177
|
+
)
|
|
178
|
+
.map(
|
|
179
|
+
(other) => `${other.effective.path.slice(effective.path.length + 1)}/**`
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
collections[entry.collection] = defineCollection({
|
|
183
|
+
type: 'page',
|
|
184
|
+
schema: pageSchema,
|
|
185
|
+
source: effective.repo
|
|
186
|
+
? {
|
|
187
|
+
exclude: [
|
|
188
|
+
...excluded(),
|
|
189
|
+
...nested.map((glob) => `${effective.path}/${glob}`)
|
|
190
|
+
],
|
|
191
|
+
// A tag lives outside refs/heads, so it has to be passed as a tag —
|
|
192
|
+
// asking git for a branch by that name fails the build outright.
|
|
193
|
+
repository: usedRef
|
|
194
|
+
? refIsTag(usedRef)
|
|
195
|
+
? { url: repoUrl(effective.repo), tag: refName(usedRef) }
|
|
196
|
+
: { url: repoUrl(effective.repo), branch: refName(usedRef) }
|
|
197
|
+
: repoUrl(effective.repo),
|
|
198
|
+
include: `${effective.path}/**/*.md`,
|
|
199
|
+
prefix: entry.prefix
|
|
200
|
+
}
|
|
201
|
+
: {
|
|
202
|
+
exclude: [...excluded(), ...nested],
|
|
203
|
+
include: '**/*.md',
|
|
204
|
+
cwd: join(repositoryRoot(), effective.path),
|
|
205
|
+
prefix: entry.prefix
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// One partials collection per LANGUAGE, named the way the page collections
|
|
211
|
+
// are — see `partialsCollection`.
|
|
212
|
+
for (const [locale, entries] of partialFolders(resolved, expanded)) {
|
|
213
|
+
collections[partialsCollection(locale)] = definePartials(entries);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return collections;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** One folder list per language: where that language's `_partials/` live. */
|
|
220
|
+
function partialFolders(
|
|
221
|
+
resolved: DuxtResolvedSource[],
|
|
222
|
+
expanded: ReturnType<typeof expandSources>
|
|
223
|
+
): Map<string | undefined, { repo?: string; path: string }[]> {
|
|
224
|
+
const byLocale = new Map<
|
|
225
|
+
string | undefined,
|
|
226
|
+
{ repo?: string; path: string }[]
|
|
227
|
+
>();
|
|
228
|
+
const seen = new Set<string>();
|
|
229
|
+
|
|
230
|
+
resolved.forEach((entry, index) => {
|
|
231
|
+
const { effective } = expanded[index]!;
|
|
232
|
+
const key = entry.isDefaultLocale ? undefined : entry.locale;
|
|
233
|
+
|
|
234
|
+
// One entry per REPOSITORY AND FOLDER, not per version: a partial is a
|
|
235
|
+
// block of prose, and reading three versions of it into one collection
|
|
236
|
+
// would give three blocks under one name.
|
|
237
|
+
const claim = `${key ?? ''}|${effective.repo ?? ''}:${effective.path}`;
|
|
238
|
+
if (seen.has(claim)) return;
|
|
239
|
+
seen.add(claim);
|
|
240
|
+
|
|
241
|
+
const list = byLocale.get(key) ?? [];
|
|
242
|
+
list.push({ repo: effective.repo, path: effective.path });
|
|
243
|
+
byLocale.set(key, list);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
return byLocale;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* One collection over every source's `_partials/` folder.
|
|
251
|
+
*
|
|
252
|
+
* A page collection rather than a data one: partials are Markdown with MDC in
|
|
253
|
+
* them, and `type: 'page'` is what gets them a parsed `body` a
|
|
254
|
+
* `<ContentRenderer>` can draw. They are routable in principle, at
|
|
255
|
+
* `/_partials/…`, and nothing routes there — the catch-all page queries the
|
|
256
|
+
* source collection for its own prefix, so the URL 404s like any other.
|
|
257
|
+
*
|
|
258
|
+
* Given no prefix, so a partial is addressed by NAME and not by which
|
|
259
|
+
* repository happens to hold it — which is the whole point of sharing them.
|
|
260
|
+
* Two sources defining the same name is a collision the build reports rather
|
|
261
|
+
* than resolves; see `modules/validate.ts`.
|
|
262
|
+
*/
|
|
263
|
+
function definePartials(folders: { repo?: string; path: string }[]) {
|
|
264
|
+
const entries = folders.map((folder) =>
|
|
265
|
+
folder.repo
|
|
266
|
+
? {
|
|
267
|
+
repository: repoUrl(folder.repo),
|
|
268
|
+
include: `${folder.path}/_partials/**/*.md`
|
|
269
|
+
}
|
|
270
|
+
: {
|
|
271
|
+
include: '_partials/**/*.md',
|
|
272
|
+
cwd: join(repositoryRoot(), folder.path)
|
|
273
|
+
}
|
|
274
|
+
) as NonNullable<Parameters<typeof defineCollection>[0]['source']>[];
|
|
275
|
+
|
|
276
|
+
// The SAME schema as the pages, not a smaller one. Content types a query by
|
|
277
|
+
// the fields every collection has in common, so a partials collection with
|
|
278
|
+
// its own thin schema narrows that union to the standard fields and every
|
|
279
|
+
// `select('rawbody')` in the layer stops compiling. The cost is that partials
|
|
280
|
+
// carry a `sitemap` field too, which is why `/_partials/**` is excluded in
|
|
281
|
+
// `nuxt.config.ts`.
|
|
282
|
+
return defineCollection({
|
|
283
|
+
type: 'page',
|
|
284
|
+
source: entries,
|
|
285
|
+
schema: pageSchema
|
|
286
|
+
});
|
|
287
|
+
}
|