@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.
Files changed (401) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +151 -0
  3. package/app/app.config.ts +13 -0
  4. package/app/app.vue +122 -0
  5. package/app/assets/css/duxt.css +555 -0
  6. package/app/assets/css/typeset.css +498 -0
  7. package/app/components/DuxtBrand.vue +53 -0
  8. package/app/components/DuxtBreadcrumb.vue +37 -0
  9. package/app/components/DuxtCodeBlock.vue +143 -0
  10. package/app/components/DuxtCopyPage.vue +117 -0
  11. package/app/components/DuxtFooter.vue +86 -0
  12. package/app/components/DuxtHeader.vue +496 -0
  13. package/app/components/DuxtJsonEditor.vue +359 -0
  14. package/app/components/DuxtLandingProse.vue +90 -0
  15. package/app/components/DuxtLandingShowcase.vue +295 -0
  16. package/app/components/DuxtLiveWindow.vue +343 -0
  17. package/app/components/DuxtLocale.vue +86 -0
  18. package/app/components/DuxtMetaList.vue +76 -0
  19. package/app/components/DuxtNavigation.vue +94 -0
  20. package/app/components/DuxtNavigationLink.vue +41 -0
  21. package/app/components/DuxtOpenApiCallbacks.vue +92 -0
  22. package/app/components/DuxtOpenApiClient.vue +1339 -0
  23. package/app/components/DuxtOpenApiMedia.vue +108 -0
  24. package/app/components/DuxtOpenApiMethod.vue +59 -0
  25. package/app/components/DuxtOpenApiParameters.vue +114 -0
  26. package/app/components/DuxtOpenApiResponses.vue +109 -0
  27. package/app/components/DuxtOpenApiSchema.vue +365 -0
  28. package/app/components/DuxtOpenApiSecurity.vue +115 -0
  29. package/app/components/DuxtPageFeedback.vue +56 -0
  30. package/app/components/DuxtPageInfo.vue +194 -0
  31. package/app/components/DuxtPageNav.vue +93 -0
  32. package/app/components/DuxtPreviewSkeleton.vue +262 -0
  33. package/app/components/DuxtProgress.vue +45 -0
  34. package/app/components/DuxtSearch.vue +271 -0
  35. package/app/components/DuxtSections.vue +65 -0
  36. package/app/components/DuxtShortcuts.vue +46 -0
  37. package/app/components/DuxtSkipLink.vue +34 -0
  38. package/app/components/DuxtToc.vue +86 -0
  39. package/app/components/DuxtTranslationBanner.vue +64 -0
  40. package/app/components/DuxtVersion.vue +168 -0
  41. package/app/components/DuxtVersionBanner.vue +109 -0
  42. package/app/components/OgImage/Duxt.satori.vue +82 -0
  43. package/app/components/content/Accordion.vue +37 -0
  44. package/app/components/content/AccordionItem.vue +46 -0
  45. package/app/components/content/Callout.vue +58 -0
  46. package/app/components/content/ChangelogGroup.vue +91 -0
  47. package/app/components/content/ChangelogReleases.vue +520 -0
  48. package/app/components/content/CodeGroup.vue +183 -0
  49. package/app/components/content/DevtoolsPanel.vue +107 -0
  50. package/app/components/content/Field.vue +50 -0
  51. package/app/components/content/FieldGroup.vue +8 -0
  52. package/app/components/content/FileTree.vue +92 -0
  53. package/app/components/content/Mermaid.vue +70 -0
  54. package/app/components/content/OpenApiOperation.vue +185 -0
  55. package/app/components/content/OpenApiOperations.vue +72 -0
  56. package/app/components/content/OpenApiOverview.vue +302 -0
  57. package/app/components/content/PackageManagers.vue +187 -0
  58. package/app/components/content/PageCards.vue +48 -0
  59. package/app/components/content/Partial.vue +65 -0
  60. package/app/components/content/Preview.vue +173 -0
  61. package/app/components/content/ProseA.vue +55 -0
  62. package/app/components/content/ProseH2.vue +53 -0
  63. package/app/components/content/ProseH3.vue +53 -0
  64. package/app/components/content/ProseH4.vue +53 -0
  65. package/app/components/content/ProseImg.vue +87 -0
  66. package/app/components/content/ProsePre.vue +58 -0
  67. package/app/components/content/ProseTable.vue +11 -0
  68. package/app/components/content/Since.vue +21 -0
  69. package/app/components/content/Steps.vue +20 -0
  70. package/app/components/content/Tab.vue +23 -0
  71. package/app/components/content/TabGroup.vue +58 -0
  72. package/app/components/ui/alert/Alert.vue +21 -0
  73. package/app/components/ui/alert/AlertDescription.vue +22 -0
  74. package/app/components/ui/alert/AlertTitle.vue +22 -0
  75. package/app/components/ui/alert/index.ts +24 -0
  76. package/app/components/ui/badge/Badge.vue +28 -0
  77. package/app/components/ui/badge/index.ts +52 -0
  78. package/app/components/ui/breadcrumb/Breadcrumb.vue +13 -0
  79. package/app/components/ui/breadcrumb/BreadcrumbEllipsis.vue +22 -0
  80. package/app/components/ui/breadcrumb/BreadcrumbItem.vue +17 -0
  81. package/app/components/ui/breadcrumb/BreadcrumbLink.vue +24 -0
  82. package/app/components/ui/breadcrumb/BreadcrumbList.vue +22 -0
  83. package/app/components/ui/breadcrumb/BreadcrumbPage.vue +20 -0
  84. package/app/components/ui/breadcrumb/BreadcrumbSeparator.vue +21 -0
  85. package/app/components/ui/breadcrumb/index.ts +7 -0
  86. package/app/components/ui/button/Button.vue +31 -0
  87. package/app/components/ui/button/index.ts +39 -0
  88. package/app/components/ui/card/Card.vue +22 -0
  89. package/app/components/ui/card/CardAction.vue +22 -0
  90. package/app/components/ui/card/CardContent.vue +14 -0
  91. package/app/components/ui/card/CardDescription.vue +17 -0
  92. package/app/components/ui/card/CardFooter.vue +17 -0
  93. package/app/components/ui/card/CardHeader.vue +22 -0
  94. package/app/components/ui/card/CardTitle.vue +17 -0
  95. package/app/components/ui/card/index.ts +7 -0
  96. package/app/components/ui/collapsible/Collapsible.vue +19 -0
  97. package/app/components/ui/collapsible/CollapsibleContent.vue +12 -0
  98. package/app/components/ui/collapsible/CollapsibleTrigger.vue +12 -0
  99. package/app/components/ui/collapsible/index.ts +3 -0
  100. package/app/components/ui/command/Command.vue +98 -0
  101. package/app/components/ui/command/CommandDialog.vue +42 -0
  102. package/app/components/ui/command/CommandEmpty.vue +31 -0
  103. package/app/components/ui/command/CommandGroup.vue +52 -0
  104. package/app/components/ui/command/CommandInput.vue +45 -0
  105. package/app/components/ui/command/CommandItem.vue +85 -0
  106. package/app/components/ui/command/CommandList.vue +32 -0
  107. package/app/components/ui/command/CommandSeparator.vue +23 -0
  108. package/app/components/ui/command/CommandShortcut.vue +19 -0
  109. package/app/components/ui/command/index.ts +29 -0
  110. package/app/components/ui/dialog/Dialog.vue +15 -0
  111. package/app/components/ui/dialog/DialogClose.vue +12 -0
  112. package/app/components/ui/dialog/DialogContent.vue +61 -0
  113. package/app/components/ui/dialog/DialogDescription.vue +25 -0
  114. package/app/components/ui/dialog/DialogFooter.vue +30 -0
  115. package/app/components/ui/dialog/DialogHeader.vue +17 -0
  116. package/app/components/ui/dialog/DialogOverlay.vue +28 -0
  117. package/app/components/ui/dialog/DialogScrollContent.vue +65 -0
  118. package/app/components/ui/dialog/DialogTitle.vue +25 -0
  119. package/app/components/ui/dialog/DialogTrigger.vue +12 -0
  120. package/app/components/ui/dialog/index.ts +10 -0
  121. package/app/components/ui/dropdown-menu/DropdownMenu.vue +19 -0
  122. package/app/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +47 -0
  123. package/app/components/ui/dropdown-menu/DropdownMenuContent.vue +47 -0
  124. package/app/components/ui/dropdown-menu/DropdownMenuGroup.vue +12 -0
  125. package/app/components/ui/dropdown-menu/DropdownMenuItem.vue +41 -0
  126. package/app/components/ui/dropdown-menu/DropdownMenuLabel.vue +27 -0
  127. package/app/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +21 -0
  128. package/app/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +48 -0
  129. package/app/components/ui/dropdown-menu/DropdownMenuSeparator.vue +23 -0
  130. package/app/components/ui/dropdown-menu/DropdownMenuShortcut.vue +19 -0
  131. package/app/components/ui/dropdown-menu/DropdownMenuSub.vue +19 -0
  132. package/app/components/ui/dropdown-menu/DropdownMenuSubContent.vue +34 -0
  133. package/app/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +34 -0
  134. package/app/components/ui/dropdown-menu/DropdownMenuTrigger.vue +17 -0
  135. package/app/components/ui/dropdown-menu/index.ts +16 -0
  136. package/app/components/ui/input/Input.vue +35 -0
  137. package/app/components/ui/input/index.ts +1 -0
  138. package/app/components/ui/navigation-menu/NavigationMenu.vue +42 -0
  139. package/app/components/ui/navigation-menu/NavigationMenuContent.vue +35 -0
  140. package/app/components/ui/navigation-menu/NavigationMenuIndicator.vue +32 -0
  141. package/app/components/ui/navigation-menu/NavigationMenuItem.vue +23 -0
  142. package/app/components/ui/navigation-menu/NavigationMenuLink.vue +30 -0
  143. package/app/components/ui/navigation-menu/NavigationMenuList.vue +30 -0
  144. package/app/components/ui/navigation-menu/NavigationMenuTrigger.vue +31 -0
  145. package/app/components/ui/navigation-menu/NavigationMenuViewport.vue +30 -0
  146. package/app/components/ui/navigation-menu/index.ts +14 -0
  147. package/app/components/ui/scroll-area/ScrollArea.vue +31 -0
  148. package/app/components/ui/scroll-area/ScrollBar.vue +38 -0
  149. package/app/components/ui/scroll-area/index.ts +2 -0
  150. package/app/components/ui/select/Select.vue +15 -0
  151. package/app/components/ui/select/SelectContent.vue +59 -0
  152. package/app/components/ui/select/SelectGroup.vue +19 -0
  153. package/app/components/ui/select/SelectItem.vue +42 -0
  154. package/app/components/ui/select/SelectItemText.vue +12 -0
  155. package/app/components/ui/select/SelectLabel.vue +16 -0
  156. package/app/components/ui/select/SelectScrollDownButton.vue +28 -0
  157. package/app/components/ui/select/SelectScrollUpButton.vue +28 -0
  158. package/app/components/ui/select/SelectSeparator.vue +20 -0
  159. package/app/components/ui/select/SelectTrigger.vue +32 -0
  160. package/app/components/ui/select/SelectValue.vue +12 -0
  161. package/app/components/ui/select/index.ts +11 -0
  162. package/app/components/ui/separator/Separator.vue +30 -0
  163. package/app/components/ui/separator/index.ts +1 -0
  164. package/app/components/ui/sheet/Sheet.vue +15 -0
  165. package/app/components/ui/sheet/SheetClose.vue +12 -0
  166. package/app/components/ui/sheet/SheetContent.vue +68 -0
  167. package/app/components/ui/sheet/SheetDescription.vue +23 -0
  168. package/app/components/ui/sheet/SheetFooter.vue +15 -0
  169. package/app/components/ui/sheet/SheetHeader.vue +15 -0
  170. package/app/components/ui/sheet/SheetOverlay.vue +28 -0
  171. package/app/components/ui/sheet/SheetTitle.vue +23 -0
  172. package/app/components/ui/sheet/SheetTrigger.vue +12 -0
  173. package/app/components/ui/sheet/index.ts +8 -0
  174. package/app/components/ui/sidebar/Sidebar.vue +110 -0
  175. package/app/components/ui/sidebar/SidebarContent.vue +23 -0
  176. package/app/components/ui/sidebar/SidebarFooter.vue +18 -0
  177. package/app/components/ui/sidebar/SidebarGroup.vue +18 -0
  178. package/app/components/ui/sidebar/SidebarGroupAction.vue +31 -0
  179. package/app/components/ui/sidebar/SidebarGroupContent.vue +18 -0
  180. package/app/components/ui/sidebar/SidebarGroupLabel.vue +30 -0
  181. package/app/components/ui/sidebar/SidebarHeader.vue +18 -0
  182. package/app/components/ui/sidebar/SidebarInput.vue +19 -0
  183. package/app/components/ui/sidebar/SidebarInset.vue +23 -0
  184. package/app/components/ui/sidebar/SidebarMenu.vue +18 -0
  185. package/app/components/ui/sidebar/SidebarMenuAction.vue +42 -0
  186. package/app/components/ui/sidebar/SidebarMenuBadge.vue +28 -0
  187. package/app/components/ui/sidebar/SidebarMenuButton.vue +60 -0
  188. package/app/components/ui/sidebar/SidebarMenuButtonChild.vue +36 -0
  189. package/app/components/ui/sidebar/SidebarMenuItem.vue +18 -0
  190. package/app/components/ui/sidebar/SidebarMenuSkeleton.vue +35 -0
  191. package/app/components/ui/sidebar/SidebarMenuSub.vue +24 -0
  192. package/app/components/ui/sidebar/SidebarMenuSubButton.vue +43 -0
  193. package/app/components/ui/sidebar/SidebarMenuSubItem.vue +18 -0
  194. package/app/components/ui/sidebar/SidebarProvider.vue +109 -0
  195. package/app/components/ui/sidebar/SidebarRail.vue +35 -0
  196. package/app/components/ui/sidebar/SidebarSeparator.vue +19 -0
  197. package/app/components/ui/sidebar/SidebarTrigger.vue +26 -0
  198. package/app/components/ui/sidebar/index.ts +62 -0
  199. package/app/components/ui/sidebar/utils.ts +19 -0
  200. package/app/components/ui/skeleton/Skeleton.vue +17 -0
  201. package/app/components/ui/skeleton/index.ts +1 -0
  202. package/app/components/ui/sonner/Sonner.vue +67 -0
  203. package/app/components/ui/sonner/index.ts +1 -0
  204. package/app/components/ui/tabs/Tabs.vue +26 -0
  205. package/app/components/ui/tabs/TabsContent.vue +23 -0
  206. package/app/components/ui/tabs/TabsList.vue +28 -0
  207. package/app/components/ui/tabs/TabsTrigger.vue +30 -0
  208. package/app/components/ui/tabs/index.ts +4 -0
  209. package/app/components/ui/textarea/Textarea.vue +32 -0
  210. package/app/components/ui/textarea/index.ts +1 -0
  211. package/app/components/ui/tooltip/Tooltip.vue +15 -0
  212. package/app/components/ui/tooltip/TooltipContent.vue +49 -0
  213. package/app/components/ui/tooltip/TooltipProvider.vue +14 -0
  214. package/app/components/ui/tooltip/TooltipTrigger.vue +12 -0
  215. package/app/components/ui/tooltip/index.ts +4 -0
  216. package/app/composables/useActiveHeading.ts +90 -0
  217. package/app/composables/useDuxtAnimatedHeight.ts +155 -0
  218. package/app/composables/useDuxtBreadcrumb.ts +60 -0
  219. package/app/composables/useDuxtChoice.ts +28 -0
  220. package/app/composables/useDuxtCollection.ts +89 -0
  221. package/app/composables/useDuxtConfig.ts +47 -0
  222. package/app/composables/useDuxtNavigation.ts +87 -0
  223. package/app/composables/useDuxtPageFocus.ts +30 -0
  224. package/app/composables/useDuxtPath.ts +42 -0
  225. package/app/composables/useDuxtSearch.ts +208 -0
  226. package/app/composables/useDuxtSection.ts +44 -0
  227. package/app/composables/useDuxtSectionRow.ts +49 -0
  228. package/app/composables/useDuxtShortcuts.ts +58 -0
  229. package/app/composables/useDuxtSiteUrl.ts +27 -0
  230. package/app/composables/useDuxtToast.ts +25 -0
  231. package/app/composables/useDuxtVersion.ts +138 -0
  232. package/app/composables/useFuzzySearch.ts +83 -0
  233. package/app/composables/usePackageManager.ts +4 -0
  234. package/app/composables/useRecentPages.ts +52 -0
  235. package/app/error.vue +133 -0
  236. package/app/layouts/changelog.vue +85 -0
  237. package/app/layouts/default.vue +23 -0
  238. package/app/layouts/docs.vue +62 -0
  239. package/app/layouts/reference.vue +85 -0
  240. package/app/lib/utils.ts +7 -0
  241. package/app/middleware/duxt-section-layout.global.ts +57 -0
  242. package/app/pages/[...slug].vue +441 -0
  243. package/app/pages/index.vue +479 -0
  244. package/app/types/duxt.d.ts +955 -0
  245. package/app/utils/aside.ts +16 -0
  246. package/app/utils/changelog.ts +182 -0
  247. package/app/utils/code-highlight.ts +116 -0
  248. package/app/utils/duxt-config.ts +185 -0
  249. package/app/utils/duxt-text.ts +135 -0
  250. package/app/utils/file-icons.ts +62 -0
  251. package/app/utils/generated-sections.ts +190 -0
  252. package/app/utils/generated-toc.ts +216 -0
  253. package/app/utils/heading-link.ts +32 -0
  254. package/app/utils/locale-path.ts +45 -0
  255. package/app/utils/navigation-tree.ts +206 -0
  256. package/app/utils/nearest-page.ts +72 -0
  257. package/app/utils/openapi.ts +1028 -0
  258. package/app/utils/package-command.ts +162 -0
  259. package/app/utils/request-samples.ts +635 -0
  260. package/app/utils/section-scope.ts +97 -0
  261. package/app/utils/sheet-navigation.ts +100 -0
  262. package/app/utils/source-file.ts +84 -0
  263. package/app/utils/version-choices.ts +68 -0
  264. package/app/utils/version-paths.ts +65 -0
  265. package/bin/duxt-report.mjs +45 -0
  266. package/components.json +19 -0
  267. package/content-cache.ts +193 -0
  268. package/content.config.ts +38 -0
  269. package/duxt-app-config.ts +124 -0
  270. package/highlight-langs.ts +68 -0
  271. package/i18n/i18n.config.ts +16 -0
  272. package/i18n/locales/de/duxt/changelog.json +17 -0
  273. package/i18n/locales/de/duxt/code.json +13 -0
  274. package/i18n/locales/de/duxt/defaults.json +22 -0
  275. package/i18n/locales/de/duxt/devtools.json +7 -0
  276. package/i18n/locales/de/duxt/error.json +10 -0
  277. package/i18n/locales/de/duxt/footer.json +7 -0
  278. package/i18n/locales/de/duxt/locale.json +7 -0
  279. package/i18n/locales/de/duxt/nav.json +17 -0
  280. package/i18n/locales/de/duxt/openapi.json +89 -0
  281. package/i18n/locales/de/duxt/page.json +34 -0
  282. package/i18n/locales/de/duxt/search.json +12 -0
  283. package/i18n/locales/de/duxt/shortcuts.json +11 -0
  284. package/i18n/locales/de/duxt/theme.json +7 -0
  285. package/i18n/locales/de/duxt/toc.json +7 -0
  286. package/i18n/locales/de/duxt/version.json +25 -0
  287. package/i18n/locales/en/duxt/changelog.json +17 -0
  288. package/i18n/locales/en/duxt/code.json +13 -0
  289. package/i18n/locales/en/duxt/defaults.json +22 -0
  290. package/i18n/locales/en/duxt/devtools.json +7 -0
  291. package/i18n/locales/en/duxt/error.json +10 -0
  292. package/i18n/locales/en/duxt/footer.json +7 -0
  293. package/i18n/locales/en/duxt/locale.json +7 -0
  294. package/i18n/locales/en/duxt/nav.json +17 -0
  295. package/i18n/locales/en/duxt/openapi.json +89 -0
  296. package/i18n/locales/en/duxt/page.json +34 -0
  297. package/i18n/locales/en/duxt/search.json +12 -0
  298. package/i18n/locales/en/duxt/shortcuts.json +11 -0
  299. package/i18n/locales/en/duxt/theme.json +7 -0
  300. package/i18n/locales/en/duxt/toc.json +7 -0
  301. package/i18n/locales/en/duxt/version.json +25 -0
  302. package/i18n/locales/es/duxt/changelog.json +17 -0
  303. package/i18n/locales/es/duxt/code.json +13 -0
  304. package/i18n/locales/es/duxt/defaults.json +22 -0
  305. package/i18n/locales/es/duxt/devtools.json +7 -0
  306. package/i18n/locales/es/duxt/error.json +10 -0
  307. package/i18n/locales/es/duxt/footer.json +7 -0
  308. package/i18n/locales/es/duxt/locale.json +7 -0
  309. package/i18n/locales/es/duxt/nav.json +17 -0
  310. package/i18n/locales/es/duxt/openapi.json +89 -0
  311. package/i18n/locales/es/duxt/page.json +34 -0
  312. package/i18n/locales/es/duxt/search.json +12 -0
  313. package/i18n/locales/es/duxt/shortcuts.json +11 -0
  314. package/i18n/locales/es/duxt/theme.json +7 -0
  315. package/i18n/locales/es/duxt/toc.json +7 -0
  316. package/i18n/locales/es/duxt/version.json +25 -0
  317. package/i18n/locales/fr/duxt/changelog.json +17 -0
  318. package/i18n/locales/fr/duxt/code.json +13 -0
  319. package/i18n/locales/fr/duxt/defaults.json +22 -0
  320. package/i18n/locales/fr/duxt/devtools.json +7 -0
  321. package/i18n/locales/fr/duxt/error.json +10 -0
  322. package/i18n/locales/fr/duxt/footer.json +7 -0
  323. package/i18n/locales/fr/duxt/locale.json +7 -0
  324. package/i18n/locales/fr/duxt/nav.json +17 -0
  325. package/i18n/locales/fr/duxt/openapi.json +89 -0
  326. package/i18n/locales/fr/duxt/page.json +34 -0
  327. package/i18n/locales/fr/duxt/search.json +12 -0
  328. package/i18n/locales/fr/duxt/shortcuts.json +11 -0
  329. package/i18n/locales/fr/duxt/theme.json +7 -0
  330. package/i18n/locales/fr/duxt/toc.json +7 -0
  331. package/i18n/locales/fr/duxt/version.json +25 -0
  332. package/i18n/locales/pt/duxt/changelog.json +17 -0
  333. package/i18n/locales/pt/duxt/code.json +13 -0
  334. package/i18n/locales/pt/duxt/defaults.json +22 -0
  335. package/i18n/locales/pt/duxt/devtools.json +7 -0
  336. package/i18n/locales/pt/duxt/error.json +10 -0
  337. package/i18n/locales/pt/duxt/footer.json +7 -0
  338. package/i18n/locales/pt/duxt/locale.json +7 -0
  339. package/i18n/locales/pt/duxt/nav.json +17 -0
  340. package/i18n/locales/pt/duxt/openapi.json +89 -0
  341. package/i18n/locales/pt/duxt/page.json +34 -0
  342. package/i18n/locales/pt/duxt/search.json +12 -0
  343. package/i18n/locales/pt/duxt/shortcuts.json +11 -0
  344. package/i18n/locales/pt/duxt/theme.json +7 -0
  345. package/i18n/locales/pt/duxt/toc.json +7 -0
  346. package/i18n/locales/pt/duxt/version.json +25 -0
  347. package/i18n/locales/pt-BR/duxt/error.json +8 -0
  348. package/i18n/locales/pt-BR/duxt/nav.json +10 -0
  349. package/i18n/locales/pt-BR/duxt/page.json +10 -0
  350. package/i18n/locales/pt-BR/duxt/search.json +11 -0
  351. package/i18n/locales/pt-BR/duxt/version.json +13 -0
  352. package/mdc.config.ts +28 -0
  353. package/modules/config.ts +440 -0
  354. package/modules/devtools.ts +126 -0
  355. package/modules/git-meta.ts +349 -0
  356. package/modules/redirects.ts +152 -0
  357. package/modules/validate.ts +137 -0
  358. package/nuxt.config.ts +530 -0
  359. package/openapi-model.ts +358 -0
  360. package/openapi-parse.ts +1052 -0
  361. package/package.json +161 -0
  362. package/public/devtools/cache.html +318 -0
  363. package/public/devtools/checks.html +309 -0
  364. package/public/devtools/config.html +461 -0
  365. package/public/devtools/i18n.html +309 -0
  366. package/public/devtools/pages.html +348 -0
  367. package/public/devtools/paths.html +315 -0
  368. package/public/devtools/redirects.html +309 -0
  369. package/public/devtools/search.html +324 -0
  370. package/public/devtools/sources.html +309 -0
  371. package/public/devtools/versions.html +318 -0
  372. package/report.ts +303 -0
  373. package/repository-root.ts +26 -0
  374. package/section-reports.ts +55 -0
  375. package/sections-changelog.ts +644 -0
  376. package/sections-openapi.ts +450 -0
  377. package/sections-resolve.ts +711 -0
  378. package/sections.ts +157 -0
  379. package/server/devtools/content.ts +120 -0
  380. package/server/devtools/context.ts +38 -0
  381. package/server/devtools/entry-path.ts +30 -0
  382. package/server/devtools/handler.ts +104 -0
  383. package/server/devtools/preview.ts +461 -0
  384. package/server/devtools/render/content.ts +233 -0
  385. package/server/devtools/render/sources.ts +414 -0
  386. package/server/devtools/render/system.ts +352 -0
  387. package/server/devtools/shell.ts +611 -0
  388. package/server/devtools/sources.ts +122 -0
  389. package/server/devtools/system.ts +178 -0
  390. package/server/mcp/tools/list-pages.ts +52 -0
  391. package/server/mcp/tools/read-page.ts +57 -0
  392. package/server/mcp/tools/search-docs.ts +74 -0
  393. package/server/middleware/raw-markdown.ts +86 -0
  394. package/server/routes/llms-full.txt.get.ts +75 -0
  395. package/server/routes/llms.txt.get.ts +63 -0
  396. package/server/routes/rss.xml.get.ts +125 -0
  397. package/server/utils/duxt-server-text.ts +46 -0
  398. package/sources-git.ts +113 -0
  399. package/sources-resolve.ts +908 -0
  400. package/sources.ts +287 -0
  401. package/validate-report.ts +494 -0
@@ -0,0 +1,496 @@
1
+ <script setup lang="ts">
2
+ const duxt = useDuxtConfig();
3
+ const colorMode = useColorMode();
4
+ const path = useDuxtPath();
5
+ const localeLink = useDuxtLink();
6
+
7
+ const { data: navigation } = await useDuxtNavigation();
8
+
9
+ // The mobile sheet shows the same branch the sidebar does.
10
+ const { items } = useDuxtSection(navigation);
11
+
12
+ function toggleTheme() {
13
+ colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark';
14
+ }
15
+
16
+ /**
17
+ * An entry with neither `to` nor children means "the documentation".
18
+ *
19
+ * The layer's own "Docs" entry ships without a `to` on purpose: where the
20
+ * documentation lives depends on the consumer's prefixes, which the layer
21
+ * cannot know. Resolving it to the first section here is what makes the default
22
+ * navbar work on a versioned site and on a flat one alike — and every place
23
+ * that renders a navigation entry has to go through this, or the entry renders
24
+ * as an anchor with no href.
25
+ */
26
+ function linkTarget(link: DuxtLink) {
27
+ return link.to ?? duxt.sections?.[0]?.to ?? '/';
28
+ }
29
+
30
+ function isActive(to?: string) {
31
+ return Boolean(to && to !== '/' && path.value.startsWith(to));
32
+ }
33
+
34
+ /**
35
+ * Whether a navbar entry owns the page — which for "the documentation" is not
36
+ * the same question as whether its href matches.
37
+ *
38
+ * A `to`-less entry resolves to the FIRST section so the link goes somewhere,
39
+ * and reusing that resolved href for the highlight was wrong: it lit "Docs"
40
+ * only inside section one and left the navbar showing nothing at all on every
41
+ * other section, which is exactly where a reader most needs to see where they
42
+ * are. Such an entry stands for the whole documentation, so it is active
43
+ * wherever ANY section is.
44
+ */
45
+ function entryActive(link: DuxtLink) {
46
+ if (link.to) return isActive(link.to);
47
+
48
+ // THE ROOT AREA'S sections, not every entry the site declared: a to-less
49
+ // entry stands for the documentation, and on a site with a second source the
50
+ // list also holds that source's parts — which would light "Docs" on a page
51
+ // that is not documentation at all, beside the entry that really owns it.
52
+ return sectionsForPath(
53
+ duxt.sections ?? [],
54
+ duxt.resolvedSources ?? [],
55
+ '/'
56
+ ).some((section) => isActive(section.to));
57
+ }
58
+
59
+ /**
60
+ * The sheet is controlled so that navigating closes it.
61
+ *
62
+ * Watching the route rather than binding a close to every link: the sheet holds
63
+ * four kinds of them — the navbar entries, their children, the sections, and
64
+ * `DuxtNavigation`'s whole tree — and that last one also renders in the desktop
65
+ * sidebar, where a `SheetClose` has no dialog to talk to. One watcher covers
66
+ * them all, and leaves an external link (which does not move the route) alone.
67
+ */
68
+ // Whether the version is something to pick or something to state — it decides
69
+ // where the sheet puts it, so the sheet has to ask before it renders either.
70
+ const { switchable } = useDuxtVersion();
71
+
72
+ const sheetOpen = ref(false);
73
+ const route = useRoute();
74
+
75
+ watch(
76
+ () => route.fullPath,
77
+ () => {
78
+ sheetOpen.value = false;
79
+ }
80
+ );
81
+
82
+ // One tree instead of two lists: the sections become children of the entry
83
+ // that stands for the documentation. See `buildSheetNavigation`.
84
+ const sheet = computed(() =>
85
+ buildSheetNavigation(duxt.navigation, duxt.sections, duxt.resolvedSources)
86
+ );
87
+
88
+ /** A group owns the page when any of its children does. */
89
+ function groupActive(link: DuxtLink) {
90
+ return (link.children ?? []).some((child) => isActive(child.to));
91
+ }
92
+
93
+ /**
94
+ * Which navigation groups in the sheet are open.
95
+ *
96
+ * Controlled rather than `default-open`, for the reason `DuxtNavigation`
97
+ * spells out: the initial value is read once, so a group the reader lands
98
+ * inside would stay shut. A group they close by hand stays closed, because the
99
+ * route only ever forces one open.
100
+ */
101
+ const openGroups = ref<Record<string, boolean>>({});
102
+
103
+ watchEffect(() => {
104
+ for (const entry of sheet.value.entries) {
105
+ const key = asText(entry.label);
106
+ if (key && entry.children?.length && groupActive(entry)) {
107
+ openGroups.value[key] = true;
108
+ }
109
+ }
110
+ });
111
+
112
+ function groupOpen(link: DuxtLink) {
113
+ return openGroups.value[asText(link.label) ?? ''] ?? false;
114
+ }
115
+
116
+ function setGroupOpen(link: DuxtLink, value: boolean) {
117
+ openGroups.value[asText(link.label) ?? ''] = value;
118
+ }
119
+
120
+ /** `page` for the page itself, `true` for the branch holding it. */
121
+ function current(to?: string) {
122
+ if (path.value === to) return 'page';
123
+ return isActive(to) ? 'true' : undefined;
124
+ }
125
+ </script>
126
+
127
+ <template>
128
+ <header
129
+ class="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur-md"
130
+ >
131
+ <!-- Row one: identity and global links. Row two carries the sections, the
132
+ way nuxt.com splits them — the docs tree never reaches this far up. -->
133
+ <div
134
+ class="mx-auto grid h-14 max-w-[90rem] grid-cols-[auto_1fr_auto] items-center gap-4 px-4 lg:grid-cols-[1fr_auto_1fr] lg:px-8"
135
+ >
136
+ <div class="flex items-center gap-2">
137
+ <UiSheet v-model:open="sheetOpen">
138
+ <UiSheetTrigger as-child>
139
+ <UiButton
140
+ variant="ghost"
141
+ size="icon"
142
+ class="lg:hidden"
143
+ :aria-label="$t('duxt.nav.open')"
144
+ >
145
+ <Icon name="lucide:menu" class="size-5" />
146
+ </UiButton>
147
+ </UiSheetTrigger>
148
+ <UiSheetContent side="left" class="flex w-80 flex-col gap-0 p-0">
149
+ <UiSheetHeader class="border-b pr-14">
150
+ <UiSheetTitle class="flex items-center gap-2">
151
+ <DuxtBrand />
152
+
153
+ <!-- One version and no choice: a fact about the project, so it
154
+ sits with the identity as a badge rather than filling a
155
+ strip of its own with a control that cannot be used. Only
156
+ text, so a heading may hold it. -->
157
+ <span v-if="!switchable" class="sm:hidden">
158
+ <DuxtVersion />
159
+ </span>
160
+ </UiSheetTitle>
161
+ </UiSheetHeader>
162
+
163
+ <!-- Its own strip under the header rather than beside the brand:
164
+ the close button owns that corner, and the version is a control
165
+ the reader operates, not part of the identity. -->
166
+ <div v-if="switchable" class="border-b p-4 sm:hidden">
167
+ <DuxtVersion variant="block" />
168
+ </div>
169
+
170
+ <!-- Everything the desktop header holds, in one scrollable column,
171
+ widest first: the navbar links, then the sections, then the
172
+ tree of the section you are in. On a phone the second navbar
173
+ row is hidden, so without this the sections are unreachable. -->
174
+ <div class="flex-1 overflow-y-auto p-4">
175
+ <template v-if="sheet.entries.length || duxt.links?.length">
176
+ <p
177
+ class="mb-2 px-2 text-[11px] font-semibold tracking-wider text-muted-foreground uppercase"
178
+ >
179
+ {{ $t('duxt.nav.menu') }}
180
+ </p>
181
+ <ul class="space-y-0.5 text-sm">
182
+ <li v-for="link in sheet.entries" :key="asText(link.label)">
183
+ <!-- A group opens in place rather than flattening into its
184
+ parent's list: on the desktop it is a dropdown, and
185
+ spilling its five links between "Docs" and "Credits"
186
+ lost both the grouping and its name. -->
187
+ <UiCollapsible
188
+ v-if="link.children?.length"
189
+ :open="groupOpen(link)"
190
+ @update:open="(value) => setGroupOpen(link, value)"
191
+ >
192
+ <UiCollapsibleTrigger
193
+ class="group flex items-center gap-2 rounded-md px-2 py-1.5 transition-colors w-full cursor-pointer hover:bg-accent"
194
+ :class="
195
+ groupActive(link)
196
+ ? 'font-medium text-foreground'
197
+ : 'text-muted-foreground hover:text-foreground'
198
+ "
199
+ >
200
+ <Icon
201
+ v-if="link.icon"
202
+ :name="link.icon"
203
+ class="size-4"
204
+ />
205
+ <span class="truncate">{{ link.label }}</span>
206
+ <Icon
207
+ name="lucide:chevron-right"
208
+ class="ml-auto size-3.5 transition-transform group-data-[state=open]:rotate-90"
209
+ />
210
+ </UiCollapsibleTrigger>
211
+
212
+ <UiCollapsibleContent>
213
+ <ul class="mt-0.5 ml-3.5 space-y-0.5 border-l pl-2.5">
214
+ <li
215
+ v-for="child in link.children"
216
+ :key="child.to ?? asText(child.label)"
217
+ >
218
+ <NuxtLink
219
+ :to="localeLink(child.to)"
220
+ :target="child.external ? '_blank' : undefined"
221
+ :aria-current="current(child.to)"
222
+ class="flex items-center gap-2 rounded-md px-2 py-1.5 transition-colors"
223
+ :class="
224
+ isActive(child.to)
225
+ ? 'bg-accent font-medium text-foreground'
226
+ : 'text-muted-foreground hover:bg-accent hover:text-foreground'
227
+ "
228
+ >
229
+ <Icon
230
+ v-if="child.icon"
231
+ :name="child.icon"
232
+ class="size-4"
233
+ />
234
+ {{ child.label }}
235
+ <Icon
236
+ v-if="child.external"
237
+ name="lucide:arrow-up-right"
238
+ class="size-3 opacity-50"
239
+ />
240
+ </NuxtLink>
241
+ </li>
242
+ </ul>
243
+ </UiCollapsibleContent>
244
+ </UiCollapsible>
245
+
246
+ <NuxtLink
247
+ v-else
248
+ :to="localeLink(linkTarget(link))"
249
+ :target="link.external ? '_blank' : undefined"
250
+ :aria-current="current(link.to)"
251
+ class="flex items-center gap-2 rounded-md px-2 py-1.5 transition-colors"
252
+ :class="
253
+ entryActive(link)
254
+ ? 'bg-accent font-medium text-foreground'
255
+ : 'text-muted-foreground hover:bg-accent hover:text-foreground'
256
+ "
257
+ >
258
+ <Icon v-if="link.icon" :name="link.icon" class="size-4" />
259
+ {{ link.label }}
260
+ <Icon
261
+ v-if="link.external"
262
+ name="lucide:arrow-up-right"
263
+ class="size-3 opacity-50"
264
+ />
265
+ </NuxtLink>
266
+ </li>
267
+
268
+ <!-- Hidden from the row below lg, so this is the only place
269
+ they are left. -->
270
+ <li v-for="link in duxt.links ?? []" :key="link.to">
271
+ <a
272
+ :href="link.to"
273
+ target="_blank"
274
+ rel="noopener"
275
+ class="flex items-center gap-2 rounded-md px-2 py-1.5 transition-colors text-muted-foreground hover:bg-accent hover:text-foreground"
276
+ >
277
+ <Icon v-if="link.icon" :name="link.icon" class="size-4" />
278
+ {{ link.label }}
279
+ <Icon
280
+ name="lucide:arrow-up-right"
281
+ class="size-3 opacity-50"
282
+ />
283
+ </a>
284
+ </li>
285
+ </ul>
286
+ </template>
287
+
288
+ <!-- Only what no entry took — see `buildSheetNavigation`. -->
289
+ <template v-if="sheet.sections.length">
290
+ <p
291
+ class="mt-6 mb-2 border-t px-2 pt-4 text-[11px] font-semibold tracking-wider text-muted-foreground uppercase first:mt-0 first:border-t-0 first:pt-0"
292
+ >
293
+ {{ $t('duxt.nav.sections') }}
294
+ </p>
295
+ <ul class="space-y-0.5 text-sm">
296
+ <!-- Keyed on the URL, as the desktop row is: two sources may
297
+ name a section the same, and a label is not unique. -->
298
+ <li
299
+ v-for="section in sheet.sections"
300
+ :key="section.to ?? asText(section.label)"
301
+ >
302
+ <NuxtLink
303
+ :to="localeLink(section.to)"
304
+ :aria-current="current(section.to)"
305
+ class="flex items-center gap-2 rounded-md px-2 py-1.5 transition-colors"
306
+ :class="
307
+ isActive(section.to)
308
+ ? 'bg-accent font-medium text-foreground'
309
+ : 'text-muted-foreground hover:bg-accent hover:text-foreground'
310
+ "
311
+ >
312
+ <Icon
313
+ v-if="section.icon"
314
+ :name="section.icon"
315
+ class="size-4"
316
+ />
317
+ {{ section.label }}
318
+ </NuxtLink>
319
+ </li>
320
+ </ul>
321
+ </template>
322
+
323
+ <template v-if="items.length">
324
+ <p
325
+ class="mt-6 mb-2 border-t px-2 pt-4 text-[11px] font-semibold tracking-wider text-muted-foreground uppercase first:mt-0 first:border-t-0 first:pt-0"
326
+ >
327
+ {{ $t('duxt.nav.pages') }}
328
+ </p>
329
+ <!-- No `label`, so no second "Documentation" landmark: the
330
+ sheet is a dialog with its own name, and the sidebar copy
331
+ of this tree already carries the one on the page. -->
332
+ <DuxtNavigation :items="items" />
333
+ </template>
334
+ </div>
335
+
336
+ <!-- Below sm the row keeps only the brand, the burger and the
337
+ search, so the two settings live here. `mt-auto` on SheetFooter
338
+ parks them at the bottom while the tree above scrolls. -->
339
+ <UiSheetFooter
340
+ class="flex-row items-center justify-center gap-2 border-t sm:hidden"
341
+ >
342
+ <DuxtLocale />
343
+
344
+ <UiButton
345
+ variant="ghost"
346
+ size="icon"
347
+ :aria-label="$t('duxt.theme.toggle')"
348
+ @click="toggleTheme"
349
+ >
350
+ <Icon
351
+ :name="
352
+ colorMode.value === 'dark' ? 'lucide:sun' : 'lucide:moon'
353
+ "
354
+ class="size-4"
355
+ />
356
+ </UiButton>
357
+ </UiSheetFooter>
358
+ </UiSheetContent>
359
+ </UiSheet>
360
+
361
+ <NuxtLink
362
+ :to="localeLink('/')"
363
+ class="flex items-center gap-2 text-[15px] font-semibold tracking-tight"
364
+ >
365
+ <DuxtBrand />
366
+ </NuxtLink>
367
+ </div>
368
+
369
+ <!-- One middle column, two occupants. The links go at the same width the
370
+ burger arrives at, so the sheet is never a second copy of a row that
371
+ is still on screen; the search takes the space they leave, because on
372
+ a narrow screen it is the navigation. -->
373
+ <div class="flex min-w-0 items-center justify-center">
374
+ <nav
375
+ class="hidden items-center gap-0.5 text-sm lg:flex"
376
+ :aria-label="$t('duxt.nav.main')"
377
+ >
378
+ <template v-for="link in duxt.navigation" :key="link.label">
379
+ <UiDropdownMenu v-if="link.children?.length">
380
+ <UiDropdownMenuTrigger as-child>
381
+ <UiButton
382
+ variant="ghost"
383
+ size="sm"
384
+ class="gap-1.5 font-medium text-muted-foreground"
385
+ >
386
+ {{ link.label }}
387
+ <Icon
388
+ name="lucide:chevron-down"
389
+ class="size-3.5 opacity-60"
390
+ />
391
+ </UiButton>
392
+ </UiDropdownMenuTrigger>
393
+ <UiDropdownMenuContent align="center" class="w-64">
394
+ <UiDropdownMenuItem
395
+ v-for="child in link.children"
396
+ :key="child.to"
397
+ as-child
398
+ >
399
+ <NuxtLink
400
+ :to="localeLink(child.to)"
401
+ :target="child.external ? '_blank' : undefined"
402
+ class="flex items-start gap-2.5"
403
+ >
404
+ <Icon
405
+ v-if="child.icon"
406
+ :name="child.icon"
407
+ class="mt-0.5 size-4 shrink-0"
408
+ />
409
+ <span class="min-w-0">
410
+ <span class="block font-medium">{{ child.label }}</span>
411
+ <span
412
+ v-if="child.description"
413
+ class="block text-xs text-muted-foreground"
414
+ >
415
+ {{ child.description }}
416
+ </span>
417
+ </span>
418
+ </NuxtLink>
419
+ </UiDropdownMenuItem>
420
+ </UiDropdownMenuContent>
421
+ </UiDropdownMenu>
422
+
423
+ <UiButton
424
+ v-else
425
+ as-child
426
+ variant="ghost"
427
+ size="sm"
428
+ class="font-medium"
429
+ :class="
430
+ entryActive(link) ? 'text-foreground' : 'text-muted-foreground'
431
+ "
432
+ >
433
+ <NuxtLink
434
+ :to="localeLink(linkTarget(link))"
435
+ :target="link.external ? '_blank' : undefined"
436
+ >
437
+ {{ link.label }}
438
+ </NuxtLink>
439
+ </UiButton>
440
+ </template>
441
+ </nav>
442
+
443
+ <div class="w-full max-w-md lg:hidden">
444
+ <DuxtSearch />
445
+ </div>
446
+ </div>
447
+
448
+ <div class="flex items-center justify-end gap-2">
449
+ <!-- Beside the search rather than the title, and rendered even where
450
+ there is nothing to choose — as a badge — so the icons to its right
451
+ keep their place. Below sm the sheet's header carries it instead;
452
+ `v-if` here because an empty wrapper would still eat a gap. -->
453
+ <div v-if="duxt.version" class="hidden sm:block">
454
+ <DuxtVersion />
455
+ </div>
456
+ <div class="hidden w-56 lg:block">
457
+ <DuxtSearch />
458
+ </div>
459
+
460
+ <!-- The project links give way first: they are the only icons here the
461
+ sheet can carry as ordinary rows, where the locale and the theme
462
+ are controls that have to stay reachable in one tap. -->
463
+ <UiButton
464
+ v-for="link in duxt.links ?? []"
465
+ :key="link.to"
466
+ as-child
467
+ variant="ghost"
468
+ size="icon"
469
+ class="hidden lg:inline-flex"
470
+ :aria-label="link.label"
471
+ >
472
+ <a :href="link.to" target="_blank" rel="noopener">
473
+ <Icon v-if="link.icon" :name="link.icon" class="size-4" />
474
+ </a>
475
+ </UiButton>
476
+
477
+ <div class="hidden sm:block">
478
+ <DuxtLocale />
479
+ </div>
480
+
481
+ <UiButton
482
+ variant="ghost"
483
+ size="icon"
484
+ class="hidden sm:inline-flex"
485
+ :aria-label="$t('duxt.theme.toggle')"
486
+ @click="toggleTheme"
487
+ >
488
+ <Icon
489
+ :name="colorMode.value === 'dark' ? 'lucide:sun' : 'lucide:moon'"
490
+ class="size-4"
491
+ />
492
+ </UiButton>
493
+ </div>
494
+ </div>
495
+ </header>
496
+ </template>