@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
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* The language switcher, built like DuxtVersion beside it: nothing at all when
|
|
4
|
+
* there is only one choice, a dropdown when there are several. A single-locale
|
|
5
|
+
* consumer therefore never sees that duxt speaks seven languages.
|
|
6
|
+
*
|
|
7
|
+
* `switchLocalePath` rather than a link to the locale's root — switching
|
|
8
|
+
* language on a page about deploying should land on that same page in the new
|
|
9
|
+
* language, not throw the reader back to the front door.
|
|
10
|
+
*/
|
|
11
|
+
const { locale, locales } = useI18n();
|
|
12
|
+
const switchLocalePath = useSwitchLocalePath();
|
|
13
|
+
|
|
14
|
+
const available = computed(() =>
|
|
15
|
+
locales.value.map((entry) => ({
|
|
16
|
+
code: entry.code,
|
|
17
|
+
// Falls back to the code so a consumer's own locale still reads as
|
|
18
|
+
// something rather than rendering blank when it declares no `name`.
|
|
19
|
+
label: entry.name ?? entry.code,
|
|
20
|
+
flag: flagFor(entry.code)
|
|
21
|
+
}))
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const current = computed(() =>
|
|
25
|
+
available.value.find((entry) => entry.code === locale.value)
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* `flag:xx-4x3`, from the region half of the code — the same derivation the
|
|
30
|
+
* icon client bundle in nuxt.config.ts uses, so every flag this renders is one
|
|
31
|
+
* that was inlined at build time.
|
|
32
|
+
*
|
|
33
|
+
* Null for a locale that names no region (`ja`, `he`): there is no country to
|
|
34
|
+
* show, and a flag guessed from a language is wrong more often than it is
|
|
35
|
+
* right. The dropdown then simply shows the name.
|
|
36
|
+
*/
|
|
37
|
+
function flagFor(code: string): string | null {
|
|
38
|
+
const region = code.split('-')[1];
|
|
39
|
+
return region && /^[a-z]{2}$/i.test(region)
|
|
40
|
+
? `flag:${region.toLowerCase()}-4x3`
|
|
41
|
+
: null;
|
|
42
|
+
}
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<template>
|
|
46
|
+
<UiDropdownMenu v-if="available.length > 1">
|
|
47
|
+
<UiDropdownMenuTrigger as-child>
|
|
48
|
+
<UiButton
|
|
49
|
+
variant="ghost"
|
|
50
|
+
size="icon"
|
|
51
|
+
:aria-label="$t('duxt.locale.switch')"
|
|
52
|
+
>
|
|
53
|
+
<Icon
|
|
54
|
+
v-if="current?.flag"
|
|
55
|
+
:name="current.flag"
|
|
56
|
+
class="size-4 rounded-[2px]"
|
|
57
|
+
/>
|
|
58
|
+
<Icon v-else name="lucide:languages" class="size-4" />
|
|
59
|
+
</UiButton>
|
|
60
|
+
</UiDropdownMenuTrigger>
|
|
61
|
+
|
|
62
|
+
<UiDropdownMenuContent
|
|
63
|
+
align="end"
|
|
64
|
+
class="max-h-[min(20rem,var(--reka-dropdown-menu-content-available-height))] w-48"
|
|
65
|
+
>
|
|
66
|
+
<UiDropdownMenuItem v-for="entry in available" :key="entry.code" as-child>
|
|
67
|
+
<NuxtLink
|
|
68
|
+
:to="switchLocalePath(entry.code)"
|
|
69
|
+
class="flex items-center gap-2"
|
|
70
|
+
>
|
|
71
|
+
<Icon
|
|
72
|
+
v-if="entry.flag"
|
|
73
|
+
:name="entry.flag"
|
|
74
|
+
class="size-4 shrink-0 rounded-[2px]"
|
|
75
|
+
/>
|
|
76
|
+
<span class="truncate text-sm">{{ entry.label }}</span>
|
|
77
|
+
<Icon
|
|
78
|
+
name="lucide:check"
|
|
79
|
+
class="ml-auto size-3.5 shrink-0"
|
|
80
|
+
:class="entry.code === locale ? '' : 'opacity-0'"
|
|
81
|
+
/>
|
|
82
|
+
</NuxtLink>
|
|
83
|
+
</UiDropdownMenuItem>
|
|
84
|
+
</UiDropdownMenuContent>
|
|
85
|
+
</UiDropdownMenu>
|
|
86
|
+
</template>
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* The small block under a page: a few actions, a few facts, one spacing rule.
|
|
4
|
+
*
|
|
5
|
+
* It exists because the rule kept being written by hand and kept coming out
|
|
6
|
+
* differently — two links sat line on line with no gap at all while the note
|
|
7
|
+
* under them was pushed away by a margin of its own, so the same block read as
|
|
8
|
+
* cramped and loose at once. One container owns the gap here, and every item in
|
|
9
|
+
* it is spaced the same whatever it is.
|
|
10
|
+
*
|
|
11
|
+
* ACTIONS are links with an icon; NOTES are lines of text. Anything that is
|
|
12
|
+
* neither — a list of contributors, say — goes in the slot and is spaced as one
|
|
13
|
+
* more item, because the container spaces its children rather than its content.
|
|
14
|
+
*
|
|
15
|
+
* TWO LAYOUTS, one gap. The column is what the aside gets; `row` is what a page
|
|
16
|
+
* with no aside gets, where a stack hanging off the left edge under a
|
|
17
|
+
* full-width rule reads as leftovers.
|
|
18
|
+
*
|
|
19
|
+
* It draws NOTHING when it is handed nothing — no rule across a page whose
|
|
20
|
+
* source cannot be linked and whose history git could not be asked for.
|
|
21
|
+
*/
|
|
22
|
+
const props = withDefaults(
|
|
23
|
+
defineProps<{
|
|
24
|
+
/** Laid out as a row rather than a stack — see above. */
|
|
25
|
+
row?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* A link with an icon beside it. `external` opens a new tab and is the only
|
|
28
|
+
* reason this component knows what a target is: the caller decides whether
|
|
29
|
+
* the link leaves the site.
|
|
30
|
+
*/
|
|
31
|
+
actions?: {
|
|
32
|
+
icon?: string;
|
|
33
|
+
label: string;
|
|
34
|
+
to: string;
|
|
35
|
+
external?: boolean;
|
|
36
|
+
}[];
|
|
37
|
+
/** A line of text — already formatted, already translated. */
|
|
38
|
+
notes?: string[];
|
|
39
|
+
}>(),
|
|
40
|
+
{ actions: () => [], notes: () => [] }
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const slots = useSlots();
|
|
44
|
+
|
|
45
|
+
const empty = computed(
|
|
46
|
+
() => !props.actions.length && !props.notes.length && !slots.default
|
|
47
|
+
);
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<template>
|
|
51
|
+
<div
|
|
52
|
+
v-if="!empty"
|
|
53
|
+
class="mt-6 border-t pt-4 text-xs text-muted-foreground"
|
|
54
|
+
:class="
|
|
55
|
+
row
|
|
56
|
+
? 'flex flex-wrap items-center justify-end gap-x-6 gap-y-2'
|
|
57
|
+
: 'space-y-2.5'
|
|
58
|
+
"
|
|
59
|
+
>
|
|
60
|
+
<a
|
|
61
|
+
v-for="action in actions"
|
|
62
|
+
:key="action.to"
|
|
63
|
+
:href="action.to"
|
|
64
|
+
:target="action.external ? '_blank' : undefined"
|
|
65
|
+
:rel="action.external ? 'noopener' : undefined"
|
|
66
|
+
class="flex items-center gap-1.5 transition-colors hover:text-foreground"
|
|
67
|
+
>
|
|
68
|
+
<Icon v-if="action.icon" :name="action.icon" class="size-3.5 shrink-0" />
|
|
69
|
+
{{ action.label }}
|
|
70
|
+
</a>
|
|
71
|
+
|
|
72
|
+
<p v-for="note in notes" :key="note">{{ note }}</p>
|
|
73
|
+
|
|
74
|
+
<slot />
|
|
75
|
+
</div>
|
|
76
|
+
</template>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { ContentNavigationItem } from '@nuxt/content';
|
|
3
|
+
|
|
4
|
+
// The docs tree. Groups collapse, and the group holding the current page opens
|
|
5
|
+
// on every navigation — not only on first render.
|
|
6
|
+
//
|
|
7
|
+
// `label` decides whether this instance is a LANDMARK. Only the outermost one
|
|
8
|
+
// is: the component recurses into itself for nested folders, and the mobile
|
|
9
|
+
// sheet renders a second copy of the whole tree, so a `<nav>` on every instance
|
|
10
|
+
// put several landmarks with one name on the page — an axe `landmark-unique`
|
|
11
|
+
// failure, and a screen-reader landmark list with the same entry three times.
|
|
12
|
+
// Without a label it renders the list alone, which is what a nested group and a
|
|
13
|
+
// sheet that already names itself both want.
|
|
14
|
+
const props = defineProps<{
|
|
15
|
+
items: ContentNavigationItem[];
|
|
16
|
+
label?: string;
|
|
17
|
+
}>();
|
|
18
|
+
|
|
19
|
+
const path = useDuxtPath();
|
|
20
|
+
|
|
21
|
+
// A page's own icon, else the section's `pageIcon`, else the site's — see
|
|
22
|
+
// `resolvePageIcon`.
|
|
23
|
+
const duxt = useDuxtConfig();
|
|
24
|
+
const iconOf = (item: ContentNavigationItem) =>
|
|
25
|
+
resolvePageIcon(item, duxt.sections, duxt.pageIcon);
|
|
26
|
+
|
|
27
|
+
const contains = (item: ContentNavigationItem): boolean =>
|
|
28
|
+
path.value === item.path ||
|
|
29
|
+
Boolean(item.children?.some((child) => contains(child)));
|
|
30
|
+
|
|
31
|
+
// `default-open` is the INITIAL state of an uncontrolled collapsible: read once
|
|
32
|
+
// and never again, so arriving in a collapsed group by search, a deep link or
|
|
33
|
+
// the back button left it shut. The open state therefore belongs to the route —
|
|
34
|
+
// but a group the reader closes by hand must stay closed, so the route only
|
|
35
|
+
// forces it open when it moves into that group.
|
|
36
|
+
const open = ref<Record<string, boolean>>({});
|
|
37
|
+
|
|
38
|
+
watchEffect(() => {
|
|
39
|
+
for (const item of props.items) {
|
|
40
|
+
if (item.path && contains(item)) open.value[item.path] = true;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
function isOpen(item: ContentNavigationItem) {
|
|
45
|
+
return open.value[item.path ?? ''] ?? false;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function setOpen(item: ContentNavigationItem, value: boolean) {
|
|
49
|
+
open.value[item.path ?? ''] = value;
|
|
50
|
+
}
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
<template>
|
|
54
|
+
<component
|
|
55
|
+
:is="label ? 'nav' : 'div'"
|
|
56
|
+
class="text-[13px]"
|
|
57
|
+
:aria-label="label || undefined"
|
|
58
|
+
>
|
|
59
|
+
<ul class="space-y-0.5">
|
|
60
|
+
<li v-for="item in items" :key="item.path">
|
|
61
|
+
<UiCollapsible
|
|
62
|
+
v-if="item.children?.length"
|
|
63
|
+
:open="isOpen(item)"
|
|
64
|
+
@update:open="(value) => setOpen(item, value)"
|
|
65
|
+
>
|
|
66
|
+
<UiCollapsibleTrigger
|
|
67
|
+
class="group flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 font-medium text-foreground transition-colors hover:bg-accent"
|
|
68
|
+
>
|
|
69
|
+
<Icon
|
|
70
|
+
v-if="iconOf(item)"
|
|
71
|
+
:name="iconOf(item)!"
|
|
72
|
+
class="size-4 text-muted-foreground"
|
|
73
|
+
/>
|
|
74
|
+
<span class="truncate">{{ item.title }}</span>
|
|
75
|
+
<Icon
|
|
76
|
+
name="lucide:chevron-right"
|
|
77
|
+
class="ml-auto size-3.5 text-muted-foreground transition-transform group-data-[state=open]:rotate-90"
|
|
78
|
+
/>
|
|
79
|
+
</UiCollapsibleTrigger>
|
|
80
|
+
|
|
81
|
+
<UiCollapsibleContent>
|
|
82
|
+
<ul class="mt-0.5 ml-3.5 space-y-0.5 border-l pl-2.5">
|
|
83
|
+
<li v-for="child in item.children" :key="child.path">
|
|
84
|
+
<DuxtNavigationLink :item="child" />
|
|
85
|
+
</li>
|
|
86
|
+
</ul>
|
|
87
|
+
</UiCollapsibleContent>
|
|
88
|
+
</UiCollapsible>
|
|
89
|
+
|
|
90
|
+
<DuxtNavigationLink v-else :item="item" />
|
|
91
|
+
</li>
|
|
92
|
+
</ul>
|
|
93
|
+
</component>
|
|
94
|
+
</template>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { ContentNavigationItem } from '@nuxt/content';
|
|
3
|
+
|
|
4
|
+
// A leaf in the docs tree. Nested groups recurse back into DuxtNavigation, so
|
|
5
|
+
// a folder inside a folder keeps working without a second component.
|
|
6
|
+
defineProps<{ item: ContentNavigationItem }>();
|
|
7
|
+
|
|
8
|
+
const path = useDuxtPath();
|
|
9
|
+
const localeLink = useDuxtLink();
|
|
10
|
+
|
|
11
|
+
// A page's own icon, else the section's `pageIcon`, else the site's — see
|
|
12
|
+
// `resolvePageIcon`.
|
|
13
|
+
const duxt = useDuxtConfig();
|
|
14
|
+
const iconOf = (item: ContentNavigationItem) =>
|
|
15
|
+
resolvePageIcon(item, duxt.sections, duxt.pageIcon);
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<template>
|
|
19
|
+
<DuxtNavigation v-if="item.children?.length" :items="[item]" />
|
|
20
|
+
|
|
21
|
+
<NuxtLink
|
|
22
|
+
v-else
|
|
23
|
+
:to="localeLink(item.path)"
|
|
24
|
+
:aria-current="path === item.path ? 'page' : undefined"
|
|
25
|
+
class="flex items-center gap-2 rounded-md px-2 py-1.5 leading-5 transition-colors"
|
|
26
|
+
:class="
|
|
27
|
+
path === item.path
|
|
28
|
+
? 'bg-primary/10 font-medium text-primary'
|
|
29
|
+
: 'text-muted-foreground hover:bg-accent hover:text-foreground'
|
|
30
|
+
"
|
|
31
|
+
>
|
|
32
|
+
<Icon v-if="iconOf(item)" :name="iconOf(item)!" class="size-4 shrink-0" />
|
|
33
|
+
<!-- Truncated, not wrapped, and the reason is the active state: `font-medium`
|
|
34
|
+
is wider than the same string at normal weight, so an entry that fitted
|
|
35
|
+
on one line reflowed onto two the moment it became the current page and
|
|
36
|
+
the whole sidebar shifted under the pointer. One line per entry makes the
|
|
37
|
+
weight change invisible to the layout. The `title` keeps the full text
|
|
38
|
+
reachable for the handful of entries long enough to be cut. -->
|
|
39
|
+
<span class="truncate" :title="item.title">{{ item.title }}</span>
|
|
40
|
+
</NuxtLink>
|
|
41
|
+
</template>
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { DuxtOpenApiCallback } from '../../openapi-model';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The requests the API sends BACK, and where it sends them.
|
|
6
|
+
*
|
|
7
|
+
* A callback inverts the direction: the reader becomes the server. So it gets a
|
|
8
|
+
* section of its own rather than being folded in beside the responses, and the
|
|
9
|
+
* runtime expression — `{$request.body#/callbackUrl}` — is shown verbatim,
|
|
10
|
+
* because it is the literal string the document uses to say which field of the
|
|
11
|
+
* original request holds the URL.
|
|
12
|
+
*
|
|
13
|
+
* No try-it client here, and that is not an omission: nothing in a browser can
|
|
14
|
+
* receive one.
|
|
15
|
+
*/
|
|
16
|
+
defineProps<{ callbacks?: DuxtOpenApiCallback[] }>();
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<template>
|
|
20
|
+
<section v-if="callbacks?.length" class="mt-8">
|
|
21
|
+
<h2 class="duxt-label">
|
|
22
|
+
{{ $t('duxt.openapi.callbacks') }}
|
|
23
|
+
</h2>
|
|
24
|
+
|
|
25
|
+
<div v-for="callback in callbacks" :key="callback.name" class="mt-4">
|
|
26
|
+
<h3 class="font-mono text-sm font-medium">{{ callback.name }}</h3>
|
|
27
|
+
|
|
28
|
+
<div
|
|
29
|
+
v-for="(operation, index) in callback.operations ?? []"
|
|
30
|
+
:key="index"
|
|
31
|
+
class="mt-3 border-t border-border/60"
|
|
32
|
+
>
|
|
33
|
+
<div class="flex flex-wrap items-center gap-2 pt-3">
|
|
34
|
+
<DuxtOpenApiMethod :method="operation.method" />
|
|
35
|
+
<code class="font-mono text-sm break-all">
|
|
36
|
+
{{ operation.expression }}
|
|
37
|
+
</code>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<div class="mt-3 space-y-4">
|
|
41
|
+
<p v-if="operation.summary" class="text-sm">
|
|
42
|
+
{{ operation.summary }}
|
|
43
|
+
</p>
|
|
44
|
+
<p v-if="operation.description" class="text-sm text-muted-foreground">
|
|
45
|
+
{{ operation.description }}
|
|
46
|
+
</p>
|
|
47
|
+
|
|
48
|
+
<!-- A callback is a request the SERVER sends, so its body travels
|
|
49
|
+
the same way any request body does. Its responses are drawn as
|
|
50
|
+
status chips here, with no schema to give a direction to. -->
|
|
51
|
+
<DuxtOpenApiMedia
|
|
52
|
+
v-if="operation.requestBody?.content?.length"
|
|
53
|
+
:content="operation.requestBody.content"
|
|
54
|
+
direction="request"
|
|
55
|
+
/>
|
|
56
|
+
|
|
57
|
+
<!-- NAMED, because the direction is inverted and a bare status chip
|
|
58
|
+
under a request body reads as one of the operation's own answers.
|
|
59
|
+
It is the opposite: what the API expects the READER's endpoint to
|
|
60
|
+
reply with. The document's own description of it is drawn beside
|
|
61
|
+
the status, which is the whole of what it says. -->
|
|
62
|
+
<div v-if="operation.responses?.length">
|
|
63
|
+
<p class="text-xs font-medium text-foreground/80">
|
|
64
|
+
{{ $t('duxt.openapi.expects') }}
|
|
65
|
+
</p>
|
|
66
|
+
|
|
67
|
+
<ul class="mt-2 space-y-1.5">
|
|
68
|
+
<li
|
|
69
|
+
v-for="response in operation.responses"
|
|
70
|
+
:key="response.status"
|
|
71
|
+
class="flex flex-wrap items-center gap-3"
|
|
72
|
+
>
|
|
73
|
+
<UiBadge
|
|
74
|
+
:class="[
|
|
75
|
+
'h-5 px-1.5 font-mono text-[0.6875rem] leading-none font-semibold tabular-nums',
|
|
76
|
+
openApiStatusTone(response.status)
|
|
77
|
+
]"
|
|
78
|
+
>
|
|
79
|
+
{{ response.status }}
|
|
80
|
+
</UiBadge>
|
|
81
|
+
|
|
82
|
+
<span v-if="response.description" class="text-sm">
|
|
83
|
+
{{ response.description }}
|
|
84
|
+
</span>
|
|
85
|
+
</li>
|
|
86
|
+
</ul>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
</section>
|
|
92
|
+
</template>
|