@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,324 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
|
|
3
|
+
<title>duxt — Search</title><style>
|
|
4
|
+
:root {
|
|
5
|
+
color-scheme: light dark;
|
|
6
|
+
--bg: #fff;
|
|
7
|
+
--fg: #12141a;
|
|
8
|
+
--muted: #6b7280;
|
|
9
|
+
--faint: #9ca3af;
|
|
10
|
+
--line: #e8e8ea;
|
|
11
|
+
--raised: #f6f6f7;
|
|
12
|
+
--accent: #00a86b;
|
|
13
|
+
--accent-soft: #e6f7f0;
|
|
14
|
+
--warn: #b45309;
|
|
15
|
+
--error: #b91c1c;
|
|
16
|
+
--ok: #15803d;
|
|
17
|
+
--radius: 7px;
|
|
18
|
+
}
|
|
19
|
+
@media (prefers-color-scheme: dark) {
|
|
20
|
+
:root:not([data-theme='light']) {
|
|
21
|
+
--bg: #0f1115;
|
|
22
|
+
--fg: #e8e8ea;
|
|
23
|
+
--muted: #9099a8;
|
|
24
|
+
--faint: #5b6472;
|
|
25
|
+
--line: #23262d;
|
|
26
|
+
--raised: #171a20;
|
|
27
|
+
--accent: #00dc82;
|
|
28
|
+
--accent-soft: #10291f;
|
|
29
|
+
--warn: #f59e0b;
|
|
30
|
+
--error: #f87171;
|
|
31
|
+
--ok: #4ade80;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
:root[data-theme='dark'] {
|
|
35
|
+
--bg: #0f1115;
|
|
36
|
+
--fg: #e8e8ea;
|
|
37
|
+
--muted: #9099a8;
|
|
38
|
+
--faint: #5b6472;
|
|
39
|
+
--line: #23262d;
|
|
40
|
+
--raised: #171a20;
|
|
41
|
+
--accent: #00dc82;
|
|
42
|
+
--accent-soft: #10291f;
|
|
43
|
+
--warn: #f59e0b;
|
|
44
|
+
--error: #f87171;
|
|
45
|
+
--ok: #4ade80;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
* { box-sizing: border-box; }
|
|
49
|
+
body {
|
|
50
|
+
margin: 0;
|
|
51
|
+
padding: 0 0 40px;
|
|
52
|
+
font: 13px/1.55 ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
|
|
53
|
+
color: var(--fg);
|
|
54
|
+
background: var(--bg);
|
|
55
|
+
-webkit-font-smoothing: antialiased;
|
|
56
|
+
}
|
|
57
|
+
a { color: inherit; }
|
|
58
|
+
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
|
|
59
|
+
|
|
60
|
+
header.bar {
|
|
61
|
+
position: sticky; top: 0; z-index: 2;
|
|
62
|
+
background: color-mix(in srgb, var(--bg) 88%, transparent);
|
|
63
|
+
backdrop-filter: blur(8px);
|
|
64
|
+
border-bottom: 1px solid var(--line);
|
|
65
|
+
padding: 10px 16px 0;
|
|
66
|
+
}
|
|
67
|
+
nav { display: flex; gap: 1px; flex-wrap: wrap; }
|
|
68
|
+
nav a {
|
|
69
|
+
padding: 5px 10px; border-radius: var(--radius) var(--radius) 0 0;
|
|
70
|
+
text-decoration: none; color: var(--muted); font-weight: 500;
|
|
71
|
+
border-bottom: 2px solid transparent; line-height: 1.4;
|
|
72
|
+
}
|
|
73
|
+
nav a:hover { color: var(--fg); background: var(--raised); }
|
|
74
|
+
nav a[aria-current] { color: var(--fg); border-bottom-color: var(--accent); font-weight: 600; }
|
|
75
|
+
|
|
76
|
+
main { padding: 18px 16px 0; max-width: 1400px; }
|
|
77
|
+
h1 { margin: 0 0 3px; font-size: 15px; font-weight: 650; letter-spacing: -0.01em; }
|
|
78
|
+
h2 {
|
|
79
|
+
margin: 26px 0 8px; font-size: 12px; font-weight: 600;
|
|
80
|
+
text-transform: uppercase; letter-spacing: .05em; color: var(--muted);
|
|
81
|
+
}
|
|
82
|
+
p.hint { margin: 0 0 16px; color: var(--muted); max-width: 78ch; }
|
|
83
|
+
|
|
84
|
+
.stats { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
|
|
85
|
+
.stat {
|
|
86
|
+
display: flex; flex-direction: column; gap: 1px;
|
|
87
|
+
padding: 7px 12px; min-width: 78px;
|
|
88
|
+
border: 1px solid var(--line); border-radius: var(--radius); background: var(--raised);
|
|
89
|
+
}
|
|
90
|
+
.stat b { font-size: 16px; font-weight: 650; font-variant-numeric: tabular-nums; line-height: 1.2; }
|
|
91
|
+
.stat span { font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
|
|
92
|
+
.stat.ok b { color: var(--ok); }
|
|
93
|
+
.stat.warn b { color: var(--warn); }
|
|
94
|
+
.stat.error b { color: var(--error); }
|
|
95
|
+
|
|
96
|
+
.scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: 10px; }
|
|
97
|
+
table { width: 100%; border-collapse: collapse; }
|
|
98
|
+
th, td { padding: 7px 11px; text-align: left; vertical-align: top; }
|
|
99
|
+
/* Offset zero, not the height of the tab bar. .scroll sets overflow-x, which
|
|
100
|
+
computes overflow-y to auto as well, so the box — not the page — is what a
|
|
101
|
+
sticky heading offsets against. At 41px the heading sat 41px down from the
|
|
102
|
+
box's top edge, leaving a blank band above it AND covering the first row:
|
|
103
|
+
the Redirects panel counted eight rules and showed seven. */
|
|
104
|
+
thead th {
|
|
105
|
+
position: sticky; top: 0; z-index: 1;
|
|
106
|
+
background: var(--raised);
|
|
107
|
+
font-weight: 600; color: var(--muted);
|
|
108
|
+
font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em;
|
|
109
|
+
white-space: nowrap; border-bottom: 1px solid var(--line);
|
|
110
|
+
}
|
|
111
|
+
tbody tr { border-top: 1px solid var(--line); }
|
|
112
|
+
tbody tr:first-child { border-top: 0; }
|
|
113
|
+
tbody tr:hover { background: var(--raised); }
|
|
114
|
+
td.empty { color: var(--muted); padding: 16px 11px; text-align: center; }
|
|
115
|
+
|
|
116
|
+
code {
|
|
117
|
+
font: 11.5px/1.5 ui-monospace, 'SF Mono', Menlo, monospace;
|
|
118
|
+
background: var(--raised); border: 1px solid var(--line);
|
|
119
|
+
padding: 0 4px; border-radius: 4px; white-space: nowrap;
|
|
120
|
+
}
|
|
121
|
+
a.file { text-decoration: none; border-bottom: 1px dashed var(--faint); }
|
|
122
|
+
a.file:hover { border-bottom-style: solid; color: var(--accent); }
|
|
123
|
+
.dim { color: var(--faint); }
|
|
124
|
+
.trunc {
|
|
125
|
+
display: inline-block; max-width: 34ch; overflow: hidden;
|
|
126
|
+
text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom;
|
|
127
|
+
}
|
|
128
|
+
td.wide { min-width: 32ch; }
|
|
129
|
+
|
|
130
|
+
.tag {
|
|
131
|
+
display: inline-block; border-radius: 999px; padding: 1px 7px;
|
|
132
|
+
font-size: 10px; font-weight: 600; white-space: nowrap;
|
|
133
|
+
background: var(--accent-soft); color: var(--accent);
|
|
134
|
+
border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
|
|
135
|
+
}
|
|
136
|
+
.tag.warn { background: transparent; color: var(--warn); border-color: color-mix(in srgb, var(--warn) 40%, transparent); }
|
|
137
|
+
.tag.error { background: transparent; color: var(--error); border-color: color-mix(in srgb, var(--error) 40%, transparent); }
|
|
138
|
+
.tag.ok { background: transparent; color: var(--ok); border-color: color-mix(in srgb, var(--ok) 40%, transparent); }
|
|
139
|
+
.tag.muted { background: var(--raised); color: var(--muted); border-color: var(--line); }
|
|
140
|
+
|
|
141
|
+
form { display: flex; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; align-items: center; }
|
|
142
|
+
input[type=text], input[type=search] {
|
|
143
|
+
flex: 1; min-width: 240px; padding: 6px 11px;
|
|
144
|
+
border: 1px solid var(--line); border-radius: var(--radius);
|
|
145
|
+
font: inherit; background: var(--bg); color: inherit;
|
|
146
|
+
}
|
|
147
|
+
.filterbar { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
|
|
148
|
+
.filterbar .count {
|
|
149
|
+
color: var(--muted); font-size: 11.5px;
|
|
150
|
+
font-variant-numeric: tabular-nums; white-space: nowrap;
|
|
151
|
+
}
|
|
152
|
+
input.filter {
|
|
153
|
+
flex: 0 1 340px; min-width: 0; margin: 0; padding-left: 31px;
|
|
154
|
+
background: var(--bg) no-repeat 10px 50% / 14px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239099a8' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.6-3.6'/%3E%3C/svg%3E");
|
|
155
|
+
}
|
|
156
|
+
input.filter:focus { border-color: var(--accent); }
|
|
157
|
+
input.filter::-webkit-search-cancel-button { cursor: pointer; }
|
|
158
|
+
input::placeholder { color: var(--faint); }
|
|
159
|
+
button {
|
|
160
|
+
padding: 6px 14px; border: 1px solid var(--line); border-radius: var(--radius);
|
|
161
|
+
background: var(--raised); font: inherit; font-weight: 500; cursor: pointer; color: inherit;
|
|
162
|
+
}
|
|
163
|
+
button:hover { border-color: var(--accent); color: var(--accent); }
|
|
164
|
+
|
|
165
|
+
ol.steps { margin: 0 0 18px; padding: 0; list-style: none; counter-reset: step; }
|
|
166
|
+
ol.steps li {
|
|
167
|
+
position: relative; counter-increment: step;
|
|
168
|
+
padding: 8px 0 8px 30px; border-left: 2px solid var(--line); margin-left: 9px;
|
|
169
|
+
}
|
|
170
|
+
ol.steps li::before {
|
|
171
|
+
content: counter(step);
|
|
172
|
+
position: absolute; left: -10px; top: 8px;
|
|
173
|
+
width: 18px; height: 18px; border-radius: 999px;
|
|
174
|
+
background: var(--raised); border: 1px solid var(--line);
|
|
175
|
+
font-size: 10px; font-weight: 600; color: var(--muted);
|
|
176
|
+
display: flex; align-items: center; justify-content: center;
|
|
177
|
+
}
|
|
178
|
+
ol.steps li:last-child { border-left-color: transparent; }
|
|
179
|
+
|
|
180
|
+
.note {
|
|
181
|
+
padding: 10px 13px; border-radius: var(--radius);
|
|
182
|
+
background: var(--raised); border: 1px solid var(--line);
|
|
183
|
+
color: var(--muted); margin-bottom: 16px; max-width: 90ch;
|
|
184
|
+
}
|
|
185
|
+
.note code { background: var(--bg); }
|
|
186
|
+
|
|
187
|
+
details { margin-bottom: 10px; }
|
|
188
|
+
details > summary {
|
|
189
|
+
cursor: pointer; padding: 7px 11px; border-radius: var(--radius);
|
|
190
|
+
background: var(--raised); border: 1px solid var(--line);
|
|
191
|
+
font-weight: 600; list-style-position: inside;
|
|
192
|
+
}
|
|
193
|
+
details > summary:hover { border-color: var(--accent); }
|
|
194
|
+
details[open] > summary { border-radius: var(--radius) var(--radius) 0 0; margin-bottom: -1px; }
|
|
195
|
+
details[open] > summary + .scroll { border-radius: 0 0 var(--radius) var(--radius); }
|
|
196
|
+
details[open] > summary + .filterbar {
|
|
197
|
+
margin: 0; padding: 8px 11px;
|
|
198
|
+
background: var(--raised); border: 1px solid var(--line); border-top: 0;
|
|
199
|
+
}
|
|
200
|
+
details[open] > .filterbar + .scroll {
|
|
201
|
+
border-radius: 0 0 var(--radius) var(--radius); margin-top: -1px;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/* A disclosure inside a table cell is not the panel-sized one above: no bar,
|
|
205
|
+
no border, no weight — just a triangle in front of the preview. */
|
|
206
|
+
details.json { margin: 0; }
|
|
207
|
+
details.json > summary {
|
|
208
|
+
padding: 0; background: none; border: 0; border-radius: 0; font-weight: inherit;
|
|
209
|
+
list-style-position: outside; margin-left: 12px;
|
|
210
|
+
}
|
|
211
|
+
details.json > summary::marker { color: var(--faint); }
|
|
212
|
+
details.json > summary:hover { border: 0; }
|
|
213
|
+
details.json[open] > summary { margin-bottom: 6px; border-radius: 0; }
|
|
214
|
+
details.json[open] > summary .peek { display: none; }
|
|
215
|
+
pre.json {
|
|
216
|
+
margin: 0 0 2px; padding: 9px 11px; max-height: 320px; overflow: auto;
|
|
217
|
+
background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius);
|
|
218
|
+
font: 11.5px/1.6 ui-monospace, 'SF Mono', Menlo, monospace;
|
|
219
|
+
white-space: pre; tab-size: 2;
|
|
220
|
+
}
|
|
221
|
+
.j-key { color: var(--accent); }
|
|
222
|
+
.j-num { color: var(--warn); }
|
|
223
|
+
.j-word { color: var(--muted); font-style: italic; }
|
|
224
|
+
|
|
225
|
+
.matrix th:first-child, .matrix td:first-child {
|
|
226
|
+
position: sticky; left: 0; background: var(--bg);
|
|
227
|
+
border-right: 1px solid var(--line);
|
|
228
|
+
}
|
|
229
|
+
.matrix thead th:first-child { background: var(--raised); }
|
|
230
|
+
.matrix tbody tr:hover td:first-child { background: var(--raised); }
|
|
231
|
+
.matrix td.mark { text-align: center; }
|
|
232
|
+
.matrix td.yes { color: var(--ok); font-weight: 700; }
|
|
233
|
+
.matrix td.no { color: var(--faint); }
|
|
234
|
+
</style></head><body>
|
|
235
|
+
|
|
236
|
+
<main>
|
|
237
|
+
<h1>Search</h1>
|
|
238
|
+
<p class="hint">Ask the search index what it actually holds.</p>
|
|
239
|
+
<form method="get">
|
|
240
|
+
<input type="search" name="q" value="install" placeholder="A word as a reader would type it" autofocus>
|
|
241
|
+
<button type="submit">Search</button>
|
|
242
|
+
</form><div class="stats"><div class="stat "><b>5</b><span>sections indexed</span></div><div class="stat "><b>2</b><span>matching</span></div></div><div class="note">One row per heading — which is what the dialog groups back into pages. The text column is exactly what FTS5 matches against.</div><div class="scroll"><table>
|
|
243
|
+
<thead><tr><th scope="col">Collection</th><th scope="col">Id</th><th scope="col">Heading</th><th scope="col">Under</th><th scope="col">Indexed text</th></tr></thead>
|
|
244
|
+
<tbody><tr>
|
|
245
|
+
<td><code>docs_sdk</code></td>
|
|
246
|
+
<td><code class="trunc" title="docs_sdk/1.getting-started/1.install.md#install">docs_sdk/1.getting-started/1.install.md#install</code></td>
|
|
247
|
+
<td>Install</td>
|
|
248
|
+
<td>Getting started</td>
|
|
249
|
+
<td class="wide">Add the package with your package manager of choice. The SDK ships types, so nothing else is needed to get autocompletion in an editor.</td>
|
|
250
|
+
</tr><tr>
|
|
251
|
+
<td><code>docs_de_sdk</code></td>
|
|
252
|
+
<td><code class="trunc" title="docs_de_sdk/de/1.getting-started/1.install.md#installation">docs_de_sdk/de/1.getting-started/1.install.md#installation</code></td>
|
|
253
|
+
<td>Installation</td>
|
|
254
|
+
<td>Erste Schritte</td>
|
|
255
|
+
<td class="wide">Das Paket wird mit dem Paketmanager der Wahl hinzugefügt. Typen liegen bei, mehr braucht ein Editor nicht.</td>
|
|
256
|
+
</tr></tbody>
|
|
257
|
+
</table></div>
|
|
258
|
+
</main>
|
|
259
|
+
<script>
|
|
260
|
+
document.addEventListener('input', (event) => {
|
|
261
|
+
const input = event.target;
|
|
262
|
+
if (!input.matches('[data-filter]')) return;
|
|
263
|
+
|
|
264
|
+
const term = input.value.trim().toLowerCase();
|
|
265
|
+
const scope = input.closest('details') ?? document;
|
|
266
|
+
const rows = scope.querySelectorAll('tbody tr');
|
|
267
|
+
let shown = 0;
|
|
268
|
+
|
|
269
|
+
for (const row of rows) {
|
|
270
|
+
row.hidden = Boolean(term) && !row.textContent.toLowerCase().includes(term);
|
|
271
|
+
if (!row.hidden) shown += 1;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const count = input.parentElement.querySelector('[data-filter-count]');
|
|
275
|
+
if (count) {
|
|
276
|
+
count.textContent = term
|
|
277
|
+
? shown ? shown + ' of ' + rows.length : 'no matches'
|
|
278
|
+
: '';
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// EVERY link and button, with no exception for the tab row — a preview has
|
|
283
|
+
// no tab row. Embedded in a documentation page, a reader who clicked one
|
|
284
|
+
// would land on another panel inside the frame while the prose around it went
|
|
285
|
+
// on explaining this one.
|
|
286
|
+
document.addEventListener('click', (event) => {
|
|
287
|
+
if (event.target.closest('a, button')) event.preventDefault();
|
|
288
|
+
});
|
|
289
|
+
document.addEventListener('submit', (event) => event.preventDefault());
|
|
290
|
+
|
|
291
|
+
// The page that framed this one owns the theme and the height: it knows
|
|
292
|
+
// which mode the reader picked, and only this document knows how tall it
|
|
293
|
+
// turned out. Two messages, one each way.
|
|
294
|
+
const theme = new URLSearchParams(location.search).get('theme');
|
|
295
|
+
if (theme) document.documentElement.dataset.theme = theme;
|
|
296
|
+
|
|
297
|
+
// Only from the frame that embedded this one, and only from its own origin.
|
|
298
|
+
// Both halves are needed: the origin alone would still accept a message from
|
|
299
|
+
// a sibling frame on the same site, and `event.source` alone would accept one
|
|
300
|
+
// from a parent on another origin. This document is served from `public/`, so
|
|
301
|
+
// the page framing it is always same-origin — a message from anywhere else is
|
|
302
|
+
// not a theme change, it is somebody else talking.
|
|
303
|
+
addEventListener('message', (event) => {
|
|
304
|
+
if (event.origin !== location.origin || event.source !== parent) return;
|
|
305
|
+
|
|
306
|
+
if (event.data && typeof event.data.duxtTheme === 'string') {
|
|
307
|
+
document.documentElement.dataset.theme = event.data.duxtTheme;
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// Addressed rather than broadcast, for the same reason. `'*'` hands the
|
|
312
|
+
// height to whatever ends up framing this page, which on a consumer's site is
|
|
313
|
+
// not necessarily the page that asked for it.
|
|
314
|
+
const measure = () => parent.postMessage(
|
|
315
|
+
{ duxtHeight: document.documentElement.scrollHeight },
|
|
316
|
+
location.origin
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
addEventListener('load', measure);
|
|
320
|
+
addEventListener('resize', measure);
|
|
321
|
+
document.addEventListener('toggle', measure, true);
|
|
322
|
+
document.addEventListener('input', () => setTimeout(measure, 0));
|
|
323
|
+
</script>
|
|
324
|
+
</body></html>
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
|
|
3
|
+
<title>duxt — Sources</title><style>
|
|
4
|
+
:root {
|
|
5
|
+
color-scheme: light dark;
|
|
6
|
+
--bg: #fff;
|
|
7
|
+
--fg: #12141a;
|
|
8
|
+
--muted: #6b7280;
|
|
9
|
+
--faint: #9ca3af;
|
|
10
|
+
--line: #e8e8ea;
|
|
11
|
+
--raised: #f6f6f7;
|
|
12
|
+
--accent: #00a86b;
|
|
13
|
+
--accent-soft: #e6f7f0;
|
|
14
|
+
--warn: #b45309;
|
|
15
|
+
--error: #b91c1c;
|
|
16
|
+
--ok: #15803d;
|
|
17
|
+
--radius: 7px;
|
|
18
|
+
}
|
|
19
|
+
@media (prefers-color-scheme: dark) {
|
|
20
|
+
:root:not([data-theme='light']) {
|
|
21
|
+
--bg: #0f1115;
|
|
22
|
+
--fg: #e8e8ea;
|
|
23
|
+
--muted: #9099a8;
|
|
24
|
+
--faint: #5b6472;
|
|
25
|
+
--line: #23262d;
|
|
26
|
+
--raised: #171a20;
|
|
27
|
+
--accent: #00dc82;
|
|
28
|
+
--accent-soft: #10291f;
|
|
29
|
+
--warn: #f59e0b;
|
|
30
|
+
--error: #f87171;
|
|
31
|
+
--ok: #4ade80;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
:root[data-theme='dark'] {
|
|
35
|
+
--bg: #0f1115;
|
|
36
|
+
--fg: #e8e8ea;
|
|
37
|
+
--muted: #9099a8;
|
|
38
|
+
--faint: #5b6472;
|
|
39
|
+
--line: #23262d;
|
|
40
|
+
--raised: #171a20;
|
|
41
|
+
--accent: #00dc82;
|
|
42
|
+
--accent-soft: #10291f;
|
|
43
|
+
--warn: #f59e0b;
|
|
44
|
+
--error: #f87171;
|
|
45
|
+
--ok: #4ade80;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
* { box-sizing: border-box; }
|
|
49
|
+
body {
|
|
50
|
+
margin: 0;
|
|
51
|
+
padding: 0 0 40px;
|
|
52
|
+
font: 13px/1.55 ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
|
|
53
|
+
color: var(--fg);
|
|
54
|
+
background: var(--bg);
|
|
55
|
+
-webkit-font-smoothing: antialiased;
|
|
56
|
+
}
|
|
57
|
+
a { color: inherit; }
|
|
58
|
+
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
|
|
59
|
+
|
|
60
|
+
header.bar {
|
|
61
|
+
position: sticky; top: 0; z-index: 2;
|
|
62
|
+
background: color-mix(in srgb, var(--bg) 88%, transparent);
|
|
63
|
+
backdrop-filter: blur(8px);
|
|
64
|
+
border-bottom: 1px solid var(--line);
|
|
65
|
+
padding: 10px 16px 0;
|
|
66
|
+
}
|
|
67
|
+
nav { display: flex; gap: 1px; flex-wrap: wrap; }
|
|
68
|
+
nav a {
|
|
69
|
+
padding: 5px 10px; border-radius: var(--radius) var(--radius) 0 0;
|
|
70
|
+
text-decoration: none; color: var(--muted); font-weight: 500;
|
|
71
|
+
border-bottom: 2px solid transparent; line-height: 1.4;
|
|
72
|
+
}
|
|
73
|
+
nav a:hover { color: var(--fg); background: var(--raised); }
|
|
74
|
+
nav a[aria-current] { color: var(--fg); border-bottom-color: var(--accent); font-weight: 600; }
|
|
75
|
+
|
|
76
|
+
main { padding: 18px 16px 0; max-width: 1400px; }
|
|
77
|
+
h1 { margin: 0 0 3px; font-size: 15px; font-weight: 650; letter-spacing: -0.01em; }
|
|
78
|
+
h2 {
|
|
79
|
+
margin: 26px 0 8px; font-size: 12px; font-weight: 600;
|
|
80
|
+
text-transform: uppercase; letter-spacing: .05em; color: var(--muted);
|
|
81
|
+
}
|
|
82
|
+
p.hint { margin: 0 0 16px; color: var(--muted); max-width: 78ch; }
|
|
83
|
+
|
|
84
|
+
.stats { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
|
|
85
|
+
.stat {
|
|
86
|
+
display: flex; flex-direction: column; gap: 1px;
|
|
87
|
+
padding: 7px 12px; min-width: 78px;
|
|
88
|
+
border: 1px solid var(--line); border-radius: var(--radius); background: var(--raised);
|
|
89
|
+
}
|
|
90
|
+
.stat b { font-size: 16px; font-weight: 650; font-variant-numeric: tabular-nums; line-height: 1.2; }
|
|
91
|
+
.stat span { font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
|
|
92
|
+
.stat.ok b { color: var(--ok); }
|
|
93
|
+
.stat.warn b { color: var(--warn); }
|
|
94
|
+
.stat.error b { color: var(--error); }
|
|
95
|
+
|
|
96
|
+
.scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: 10px; }
|
|
97
|
+
table { width: 100%; border-collapse: collapse; }
|
|
98
|
+
th, td { padding: 7px 11px; text-align: left; vertical-align: top; }
|
|
99
|
+
/* Offset zero, not the height of the tab bar. .scroll sets overflow-x, which
|
|
100
|
+
computes overflow-y to auto as well, so the box — not the page — is what a
|
|
101
|
+
sticky heading offsets against. At 41px the heading sat 41px down from the
|
|
102
|
+
box's top edge, leaving a blank band above it AND covering the first row:
|
|
103
|
+
the Redirects panel counted eight rules and showed seven. */
|
|
104
|
+
thead th {
|
|
105
|
+
position: sticky; top: 0; z-index: 1;
|
|
106
|
+
background: var(--raised);
|
|
107
|
+
font-weight: 600; color: var(--muted);
|
|
108
|
+
font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em;
|
|
109
|
+
white-space: nowrap; border-bottom: 1px solid var(--line);
|
|
110
|
+
}
|
|
111
|
+
tbody tr { border-top: 1px solid var(--line); }
|
|
112
|
+
tbody tr:first-child { border-top: 0; }
|
|
113
|
+
tbody tr:hover { background: var(--raised); }
|
|
114
|
+
td.empty { color: var(--muted); padding: 16px 11px; text-align: center; }
|
|
115
|
+
|
|
116
|
+
code {
|
|
117
|
+
font: 11.5px/1.5 ui-monospace, 'SF Mono', Menlo, monospace;
|
|
118
|
+
background: var(--raised); border: 1px solid var(--line);
|
|
119
|
+
padding: 0 4px; border-radius: 4px; white-space: nowrap;
|
|
120
|
+
}
|
|
121
|
+
a.file { text-decoration: none; border-bottom: 1px dashed var(--faint); }
|
|
122
|
+
a.file:hover { border-bottom-style: solid; color: var(--accent); }
|
|
123
|
+
.dim { color: var(--faint); }
|
|
124
|
+
.trunc {
|
|
125
|
+
display: inline-block; max-width: 34ch; overflow: hidden;
|
|
126
|
+
text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom;
|
|
127
|
+
}
|
|
128
|
+
td.wide { min-width: 32ch; }
|
|
129
|
+
|
|
130
|
+
.tag {
|
|
131
|
+
display: inline-block; border-radius: 999px; padding: 1px 7px;
|
|
132
|
+
font-size: 10px; font-weight: 600; white-space: nowrap;
|
|
133
|
+
background: var(--accent-soft); color: var(--accent);
|
|
134
|
+
border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
|
|
135
|
+
}
|
|
136
|
+
.tag.warn { background: transparent; color: var(--warn); border-color: color-mix(in srgb, var(--warn) 40%, transparent); }
|
|
137
|
+
.tag.error { background: transparent; color: var(--error); border-color: color-mix(in srgb, var(--error) 40%, transparent); }
|
|
138
|
+
.tag.ok { background: transparent; color: var(--ok); border-color: color-mix(in srgb, var(--ok) 40%, transparent); }
|
|
139
|
+
.tag.muted { background: var(--raised); color: var(--muted); border-color: var(--line); }
|
|
140
|
+
|
|
141
|
+
form { display: flex; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; align-items: center; }
|
|
142
|
+
input[type=text], input[type=search] {
|
|
143
|
+
flex: 1; min-width: 240px; padding: 6px 11px;
|
|
144
|
+
border: 1px solid var(--line); border-radius: var(--radius);
|
|
145
|
+
font: inherit; background: var(--bg); color: inherit;
|
|
146
|
+
}
|
|
147
|
+
.filterbar { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
|
|
148
|
+
.filterbar .count {
|
|
149
|
+
color: var(--muted); font-size: 11.5px;
|
|
150
|
+
font-variant-numeric: tabular-nums; white-space: nowrap;
|
|
151
|
+
}
|
|
152
|
+
input.filter {
|
|
153
|
+
flex: 0 1 340px; min-width: 0; margin: 0; padding-left: 31px;
|
|
154
|
+
background: var(--bg) no-repeat 10px 50% / 14px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239099a8' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.6-3.6'/%3E%3C/svg%3E");
|
|
155
|
+
}
|
|
156
|
+
input.filter:focus { border-color: var(--accent); }
|
|
157
|
+
input.filter::-webkit-search-cancel-button { cursor: pointer; }
|
|
158
|
+
input::placeholder { color: var(--faint); }
|
|
159
|
+
button {
|
|
160
|
+
padding: 6px 14px; border: 1px solid var(--line); border-radius: var(--radius);
|
|
161
|
+
background: var(--raised); font: inherit; font-weight: 500; cursor: pointer; color: inherit;
|
|
162
|
+
}
|
|
163
|
+
button:hover { border-color: var(--accent); color: var(--accent); }
|
|
164
|
+
|
|
165
|
+
ol.steps { margin: 0 0 18px; padding: 0; list-style: none; counter-reset: step; }
|
|
166
|
+
ol.steps li {
|
|
167
|
+
position: relative; counter-increment: step;
|
|
168
|
+
padding: 8px 0 8px 30px; border-left: 2px solid var(--line); margin-left: 9px;
|
|
169
|
+
}
|
|
170
|
+
ol.steps li::before {
|
|
171
|
+
content: counter(step);
|
|
172
|
+
position: absolute; left: -10px; top: 8px;
|
|
173
|
+
width: 18px; height: 18px; border-radius: 999px;
|
|
174
|
+
background: var(--raised); border: 1px solid var(--line);
|
|
175
|
+
font-size: 10px; font-weight: 600; color: var(--muted);
|
|
176
|
+
display: flex; align-items: center; justify-content: center;
|
|
177
|
+
}
|
|
178
|
+
ol.steps li:last-child { border-left-color: transparent; }
|
|
179
|
+
|
|
180
|
+
.note {
|
|
181
|
+
padding: 10px 13px; border-radius: var(--radius);
|
|
182
|
+
background: var(--raised); border: 1px solid var(--line);
|
|
183
|
+
color: var(--muted); margin-bottom: 16px; max-width: 90ch;
|
|
184
|
+
}
|
|
185
|
+
.note code { background: var(--bg); }
|
|
186
|
+
|
|
187
|
+
details { margin-bottom: 10px; }
|
|
188
|
+
details > summary {
|
|
189
|
+
cursor: pointer; padding: 7px 11px; border-radius: var(--radius);
|
|
190
|
+
background: var(--raised); border: 1px solid var(--line);
|
|
191
|
+
font-weight: 600; list-style-position: inside;
|
|
192
|
+
}
|
|
193
|
+
details > summary:hover { border-color: var(--accent); }
|
|
194
|
+
details[open] > summary { border-radius: var(--radius) var(--radius) 0 0; margin-bottom: -1px; }
|
|
195
|
+
details[open] > summary + .scroll { border-radius: 0 0 var(--radius) var(--radius); }
|
|
196
|
+
details[open] > summary + .filterbar {
|
|
197
|
+
margin: 0; padding: 8px 11px;
|
|
198
|
+
background: var(--raised); border: 1px solid var(--line); border-top: 0;
|
|
199
|
+
}
|
|
200
|
+
details[open] > .filterbar + .scroll {
|
|
201
|
+
border-radius: 0 0 var(--radius) var(--radius); margin-top: -1px;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/* A disclosure inside a table cell is not the panel-sized one above: no bar,
|
|
205
|
+
no border, no weight — just a triangle in front of the preview. */
|
|
206
|
+
details.json { margin: 0; }
|
|
207
|
+
details.json > summary {
|
|
208
|
+
padding: 0; background: none; border: 0; border-radius: 0; font-weight: inherit;
|
|
209
|
+
list-style-position: outside; margin-left: 12px;
|
|
210
|
+
}
|
|
211
|
+
details.json > summary::marker { color: var(--faint); }
|
|
212
|
+
details.json > summary:hover { border: 0; }
|
|
213
|
+
details.json[open] > summary { margin-bottom: 6px; border-radius: 0; }
|
|
214
|
+
details.json[open] > summary .peek { display: none; }
|
|
215
|
+
pre.json {
|
|
216
|
+
margin: 0 0 2px; padding: 9px 11px; max-height: 320px; overflow: auto;
|
|
217
|
+
background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius);
|
|
218
|
+
font: 11.5px/1.6 ui-monospace, 'SF Mono', Menlo, monospace;
|
|
219
|
+
white-space: pre; tab-size: 2;
|
|
220
|
+
}
|
|
221
|
+
.j-key { color: var(--accent); }
|
|
222
|
+
.j-num { color: var(--warn); }
|
|
223
|
+
.j-word { color: var(--muted); font-style: italic; }
|
|
224
|
+
|
|
225
|
+
.matrix th:first-child, .matrix td:first-child {
|
|
226
|
+
position: sticky; left: 0; background: var(--bg);
|
|
227
|
+
border-right: 1px solid var(--line);
|
|
228
|
+
}
|
|
229
|
+
.matrix thead th:first-child { background: var(--raised); }
|
|
230
|
+
.matrix tbody tr:hover td:first-child { background: var(--raised); }
|
|
231
|
+
.matrix td.mark { text-align: center; }
|
|
232
|
+
.matrix td.yes { color: var(--ok); font-weight: 700; }
|
|
233
|
+
.matrix td.no { color: var(--faint); }
|
|
234
|
+
</style></head><body>
|
|
235
|
+
|
|
236
|
+
<main>
|
|
237
|
+
<h1>Sources</h1>
|
|
238
|
+
<p class="hint">What <code>duxt.sources</code> became: one collection per source and version, and the URL prefix each serves.</p>
|
|
239
|
+
<div class="stats"><div class="stat "><b>6</b><span>collections</span></div><div class="stat "><b>2</b><span>repositories</span></div><div class="stat "><b>2</b><span>versions</span></div><div class="stat "><b>1</b><span>generated section</span></div><div class="stat warn"><b>2</b><span>not current</span></div></div><div class="scroll"><table>
|
|
240
|
+
<thead><tr><th scope="col">Prefix</th><th scope="col">Collection</th><th scope="col">Repository</th><th scope="col">Folder / artefact</th><th scope="col">Ref</th><th scope="col">Version</th><th scope="col">Status</th><th scope="col">Reserved segments</th></tr></thead>
|
|
241
|
+
<tbody><tr><td><code>/sdk</code></td><td><code>docs_sdk</code></td><td><a class="file" href="https://github.com/acme/sdk" target="_blank">acme/sdk</a></td><td><code>docs</code></td><td>main <span class="dim">(branch)</span></td><td>v2 <span class="tag">default</span></td><td><span class="tag ok">current</span></td><td><code>v1.9</code> <code>releases</code></td></tr><tr><td><code>/sdk</code></td><td><code>docs_de_sdk</code></td><td><a class="file" href="https://github.com/acme/sdk" target="_blank">acme/sdk</a></td><td><code>docs/de</code></td><td>main <span class="dim">(branch)</span></td><td>v2 <span class="tag">default</span></td><td><span class="tag ok">current</span></td><td><code>v1.9</code> <code>releases</code></td></tr><tr><td><code>/sdk/v1.9</code></td><td><code>docs_sdk_v1_9</code></td><td><a class="file" href="https://github.com/acme/sdk" target="_blank">acme/sdk</a></td><td><code>docs</code></td><td>v1.9.4 <span class="dim">(tag)</span></td><td>v1.9</td><td><span class="tag warn">deprecated</span></td><td><span class="dim">—</span></td></tr><tr><td><code>/sdk/v1.9</code></td><td><code>docs_de_sdk_v1_9</code></td><td><a class="file" href="https://github.com/acme/sdk" target="_blank">acme/sdk</a></td><td><code>docs/de</code></td><td>v1.9.4 <span class="dim">(tag)</span></td><td>v1.9</td><td><span class="tag warn">deprecated</span></td><td><span class="dim">—</span></td></tr><tr><td><code>/cli</code></td><td><code>docs_cli</code></td><td><a class="file" href="https://github.com/acme/cli" target="_blank">acme/cli</a></td><td><code>docs</code></td><td><span class="dim">checkout</span></td><td>— <span class="tag">default</span></td><td><span class="tag ok">current</span></td><td><span class="dim">—</span></td></tr><tr><td><code>/sdk/releases</code></td><td><code>docs_sdk_releases</code> <span class="tag">changelog</span></td><td><a class="file" href="https://github.com/acme/sdk" target="_blank">acme/sdk</a></td><td><code>CHANGELOG.md</code></td><td>main <span class="dim">(branch)</span></td><td>— <span class="tag">default</span></td><td><span class="tag ok">current</span></td><td><span class="dim">—</span></td></tr></tbody>
|
|
242
|
+
</table></div><p class="hint">Configured in /srv/acme-docs/app/app.config.ts.</p>
|
|
243
|
+
</main>
|
|
244
|
+
<script>
|
|
245
|
+
document.addEventListener('input', (event) => {
|
|
246
|
+
const input = event.target;
|
|
247
|
+
if (!input.matches('[data-filter]')) return;
|
|
248
|
+
|
|
249
|
+
const term = input.value.trim().toLowerCase();
|
|
250
|
+
const scope = input.closest('details') ?? document;
|
|
251
|
+
const rows = scope.querySelectorAll('tbody tr');
|
|
252
|
+
let shown = 0;
|
|
253
|
+
|
|
254
|
+
for (const row of rows) {
|
|
255
|
+
row.hidden = Boolean(term) && !row.textContent.toLowerCase().includes(term);
|
|
256
|
+
if (!row.hidden) shown += 1;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const count = input.parentElement.querySelector('[data-filter-count]');
|
|
260
|
+
if (count) {
|
|
261
|
+
count.textContent = term
|
|
262
|
+
? shown ? shown + ' of ' + rows.length : 'no matches'
|
|
263
|
+
: '';
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
// EVERY link and button, with no exception for the tab row — a preview has
|
|
268
|
+
// no tab row. Embedded in a documentation page, a reader who clicked one
|
|
269
|
+
// would land on another panel inside the frame while the prose around it went
|
|
270
|
+
// on explaining this one.
|
|
271
|
+
document.addEventListener('click', (event) => {
|
|
272
|
+
if (event.target.closest('a, button')) event.preventDefault();
|
|
273
|
+
});
|
|
274
|
+
document.addEventListener('submit', (event) => event.preventDefault());
|
|
275
|
+
|
|
276
|
+
// The page that framed this one owns the theme and the height: it knows
|
|
277
|
+
// which mode the reader picked, and only this document knows how tall it
|
|
278
|
+
// turned out. Two messages, one each way.
|
|
279
|
+
const theme = new URLSearchParams(location.search).get('theme');
|
|
280
|
+
if (theme) document.documentElement.dataset.theme = theme;
|
|
281
|
+
|
|
282
|
+
// Only from the frame that embedded this one, and only from its own origin.
|
|
283
|
+
// Both halves are needed: the origin alone would still accept a message from
|
|
284
|
+
// a sibling frame on the same site, and `event.source` alone would accept one
|
|
285
|
+
// from a parent on another origin. This document is served from `public/`, so
|
|
286
|
+
// the page framing it is always same-origin — a message from anywhere else is
|
|
287
|
+
// not a theme change, it is somebody else talking.
|
|
288
|
+
addEventListener('message', (event) => {
|
|
289
|
+
if (event.origin !== location.origin || event.source !== parent) return;
|
|
290
|
+
|
|
291
|
+
if (event.data && typeof event.data.duxtTheme === 'string') {
|
|
292
|
+
document.documentElement.dataset.theme = event.data.duxtTheme;
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
// Addressed rather than broadcast, for the same reason. `'*'` hands the
|
|
297
|
+
// height to whatever ends up framing this page, which on a consumer's site is
|
|
298
|
+
// not necessarily the page that asked for it.
|
|
299
|
+
const measure = () => parent.postMessage(
|
|
300
|
+
{ duxtHeight: document.documentElement.scrollHeight },
|
|
301
|
+
location.origin
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
addEventListener('load', measure);
|
|
305
|
+
addEventListener('resize', measure);
|
|
306
|
+
document.addEventListener('toggle', measure, true);
|
|
307
|
+
document.addEventListener('input', () => setTimeout(measure, 0));
|
|
308
|
+
</script>
|
|
309
|
+
</body></html>
|