@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,441 @@
1
+ <script setup lang="ts">
2
+ const { collection, source, fallbacks, translates } = useDuxtCollection();
3
+
4
+ definePageMeta({ layout: 'docs' });
5
+
6
+ const path = useDuxtPath();
7
+ const duxt = useDuxtConfig();
8
+ const localeLink = useDuxtLink();
9
+ const { absolute } = useDuxtSiteUrl();
10
+ const { locale } = useI18n();
11
+
12
+ /**
13
+ * The page, in the best language this site has it in.
14
+ *
15
+ * A translated tree is rarely complete, and a reader who followed a link into
16
+ * one should not be punished for the gap with a 404 — Starlight is the only
17
+ * one of the comparable generators that says so out loud, and it is right.
18
+ * `fallbacks` is empty on a site without translations, so this is one query
19
+ * there, exactly as before.
20
+ */
21
+ const { data: found } = await useAsyncData(
22
+ () => `docs-${locale.value}-${path.value}`,
23
+ async () => {
24
+ // Source OBJECTS, not names: the language each one carries is what the
25
+ // banner compares against, and the first entry has one too.
26
+ const chain = [source.value, ...fallbacks.value].filter(Boolean);
27
+
28
+ // The manifest can be absent for a tick after a hot reload, and a page that
29
+ // exists must not 404 over that: the collection name carries its own
30
+ // fallback, so query that rather than nothing at all.
31
+ const entries = chain.length
32
+ ? chain
33
+ : [{ collection: collection.value, locale: undefined }];
34
+
35
+ for (const entry of entries) {
36
+ const hit = await queryCollection(entry!.collection as DuxtCollectionArg)
37
+ .path(path.value)
38
+ .first();
39
+
40
+ // The language actually delivered, which is what the banner compares
41
+ // against — NOT the position in the chain. A locale the sources do not
42
+ // translate at all has the original as its first entry, and a reader
43
+ // asking for Spanish and getting English has to be told so even though
44
+ // nothing fell back.
45
+ //
46
+ // `asked` travels WITH the hit. `locale` changes the instant the reader
47
+ // picks a language, while this query — and therefore `from` — is still
48
+ // the previous language's result, so comparing the delivered language
49
+ // against the LIVE locale reports every switch as untranslated for the
50
+ // tick between the two. Freezing the language that was asked for into
51
+ // the same object keeps the pair consistent at every moment.
52
+ if (hit) return { page: hit, from: entry!.locale, asked: locale.value };
53
+ }
54
+
55
+ return undefined;
56
+ },
57
+ { watch: [collection, path] }
58
+ );
59
+
60
+ const page = computed(() => found.value?.page);
61
+
62
+ /** True when the reader is being shown a language they did not ask for. */
63
+ const untranslated = computed(() => {
64
+ if (!translates.value || !found.value) return false;
65
+
66
+ // Compared by LANGUAGE, not by code: a `de/` folder serves `de-DE`, and a
67
+ // reader there is not looking at a foreign language just because the folder
68
+ // names no region. Same rule as the locale files, and as `localeChain`.
69
+ const delivered = found.value.from;
70
+ if (!delivered) return true;
71
+
72
+ return delivered.split('-')[0] !== found.value.asked.split('-')[0];
73
+ });
74
+
75
+ if (!page.value) {
76
+ throw createError({
77
+ statusCode: 404,
78
+ statusMessage: 'Page not found',
79
+ fatal: true
80
+ });
81
+ }
82
+
83
+ // Feeds the search dialog's empty state.
84
+ const { remember } = useRecentPages();
85
+ onMounted(() =>
86
+ remember({ path: path.value, title: page.value?.title ?? path.value })
87
+ );
88
+
89
+ // After a client-side navigation the focus is still on whatever link was
90
+ // clicked. Move it to the heading of the page that arrived.
91
+ const heading = useDuxtPageFocus();
92
+
93
+ const { current, shouldIndex, preferredPath } = useDuxtVersion();
94
+
95
+ /**
96
+ * Does the page draw its own header?
97
+ *
98
+ * A generated section whose TYPE NAMES A LAYOUT has replaced the docs shell
99
+ * around this page, and the two halves cannot both draw a header: an API
100
+ * reference wants its title beside a method chip and its right-hand column
101
+ * filled with a request client, not with a table of contents. So the rule is
102
+ * one line — a type that names a layout owns its page — and everything below
103
+ * that belongs to the docs shell drops out: the breadcrumb, the title block,
104
+ * the article's reading width and the prev/next pair. The contents column is
105
+ * the one part that stayed, because it is the one part a generated page still
106
+ * has an outline for — see `generated` below.
107
+ *
108
+ * The BANNERS stay. "You are reading an old version" and "this page is not
109
+ * translated" are true of a generated page exactly as they are of a written
110
+ * one, and a type cannot be expected to redraw them.
111
+ *
112
+ * `generatedLayout` is the same lookup `middleware/duxt-section-layout.global`
113
+ * makes to choose the layout, so the two cannot disagree about which pages are
114
+ * in one.
115
+ */
116
+ const owned = computed(() =>
117
+ Boolean(generatedLayout(path.value, duxt?.resolvedSources ?? []))
118
+ );
119
+
120
+ /**
121
+ * The contents of a page whose headings a component draws.
122
+ *
123
+ * `body.toc` is Content's outline of the MARKDOWN it parsed, and a generated
124
+ * page's headings are not in it: a release page's are the group names
125
+ * `ChangelogGroup` renders from a prop, so Content saw a component call and
126
+ * found nothing to list. Reading them back off the AST the page ships anyway is
127
+ * what gives a generated section the same right-hand column every written page
128
+ * has — and it stays empty, so the column drops out, for a type whose pages
129
+ * genuinely have no outline.
130
+ */
131
+ const generated = computed(() =>
132
+ owned.value ? generatedToc(page.value?.body) : []
133
+ );
134
+
135
+ /**
136
+ * A layout can refuse the column outright — see `DUXT_ASIDE`. The reference
137
+ * does, because an operation fills that side with its request client.
138
+ */
139
+ const allowed = inject(DUXT_ASIDE, true);
140
+
141
+ /**
142
+ * Is there a right-hand column to draw at all?
143
+ *
144
+ * The outline is not the only thing in it: `DuxtToc` also carries the aside's
145
+ * fixed links, and `DuxtPageInfo` sits underneath. So the release OVERVIEW —
146
+ * which deliberately contributes no outline, because its versions are the
147
+ * visible page — still gets the column every other page has, rather than
148
+ * losing the community links and the provenance with it.
149
+ */
150
+ /**
151
+ * Does the type draw its own title, or does the shell?
152
+ *
153
+ * See `generatedTitle`. A changelog writes no `<h1>`, so its pages take the
154
+ * same header every written page has; an API reference writes one, and keeps
155
+ * the compact row — the breadcrumb and the copy control, which are facts about
156
+ * the URL and the source rather than about the type.
157
+ */
158
+ const titled = computed(() => owned.value && generatedTitle(page.value?.body));
159
+
160
+ /**
161
+ * Does the shell draw the description, or has the body already said it?
162
+ *
163
+ * See `generatedLeadsWith`.
164
+ */
165
+ const described = computed(() => {
166
+ const description = page.value?.description;
167
+ if (!owned.value || !description) return false;
168
+
169
+ return !generatedLeadsWith(description, page.value?.body);
170
+ });
171
+
172
+ const aside = computed(
173
+ () =>
174
+ allowed &&
175
+ (generated.value.length > 0 || (duxt.aside?.links?.length ?? 0) > 0)
176
+ );
177
+
178
+ // The social card. Rendered from the layer's own template unless the consumer
179
+ // ships a component of the same name — see `OgImage/Duxt.satori.vue`.
180
+ //
181
+ // `defineOgImage`, not `defineOgImageComponent`: the latter is deprecated in
182
+ // nuxt-og-image v6 and warns once per render. Same arguments, same behaviour.
183
+ defineOgImage('Duxt', {
184
+ title: page.value.title,
185
+ description: page.value.description,
186
+ site: duxt.title,
187
+ version: current.value?.version ?? ''
188
+ });
189
+ const trail = await useDuxtBreadcrumb(() => path.value);
190
+
191
+ /**
192
+ * The half nuxt-seo-utils cannot infer.
193
+ *
194
+ * It derives `og:title`, `og:description` and the Twitter pair from the title
195
+ * and description below, so those are gone from here — what is left is what
196
+ * only this page knows. `og:url` is THIS page; the canonical below is the page
197
+ * a crawler should keep, and on an old version those are deliberately not the
198
+ * same URL.
199
+ *
200
+ * `robots` is the version half: an older or dead version of a page asks not to
201
+ * be indexed, so a search engine stops offering v0.7.0 where the reader wanted
202
+ * today's docs. An untranslated page is the SAME page under another URL, and
203
+ * indexing it once per locale is duplicate content.
204
+ */
205
+ useSeoMeta({
206
+ title: () => page.value?.title,
207
+ description: () => page.value?.description,
208
+ ogType: 'article',
209
+ ogUrl: () => absolute(localeLink(path.value) ?? path.value),
210
+ robots: () =>
211
+ shouldIndex.value && !untranslated.value ? undefined : 'noindex, follow'
212
+ });
213
+
214
+ /**
215
+ * THE CANONICAL IS OURS, not the module's.
216
+ *
217
+ * nuxt-seo-utils writes a canonical pointing at the page being rendered, which
218
+ * is right for every site that has one version of a page and wrong for this
219
+ * one: an old version has to point at the current one, or a search engine keeps
220
+ * serving v0.7.0. unhead deduplicates `link[rel=canonical]`, and this call runs
221
+ * after the module's, so this is the tag that ships — asserted over the built
222
+ * HTML by `scripts/check-seo.ts`, because it is a rule that would break
223
+ * silently.
224
+ */
225
+ useHead(() => ({
226
+ link: [
227
+ {
228
+ rel: 'canonical',
229
+ href: absolute(localeLink(preferredPath.value) ?? preferredPath.value)
230
+ }
231
+ ]
232
+ }));
233
+
234
+ /**
235
+ * The page, as schema.org — a `TechArticle` and the trail that reaches it.
236
+ *
237
+ * This used to be a hand-written `@graph` in a script tag. nuxt-schema-org
238
+ * keeps one graph per document and resolves the references inside it, so the
239
+ * `WebSite` and `Organization` declared once in `app.vue` are what these nodes
240
+ * hang off, rather than a second copy of the site inlined per page.
241
+ *
242
+ * The trail comes from the same composable the breadcrumb draws, so the two
243
+ * cannot disagree.
244
+ */
245
+ useSchemaOrg([
246
+ defineArticle({
247
+ '@type': 'TechArticle',
248
+ headline: () => page.value?.title,
249
+ description: () => page.value?.description,
250
+ inLanguage: () => locale.value
251
+ }),
252
+ /**
253
+ * The WHOLE NODE is the computed, not the field inside it.
254
+ *
255
+ * `DeepResolvableProperties` makes a string field resolvable but maps an
256
+ * array by its own keys, so `itemListElement` takes a plain array and neither
257
+ * a ref nor a getter. Wrapping the definer instead keeps the trail reactive
258
+ * across a client-side navigation, which is the only reason it has to be.
259
+ */
260
+ computed(() =>
261
+ defineBreadcrumb({
262
+ itemListElement: trail.value.map((item) => ({
263
+ name: item.title,
264
+ item: absolute(localeLink(item.path ?? '/') ?? '/')
265
+ }))
266
+ })
267
+ )
268
+ ]);
269
+ </script>
270
+
271
+ <template>
272
+ <!-- The type's own layout owns the page: no reading width and no header of
273
+ ours — see `owned`. The CONTENTS COLUMN is drawn here rather than left to
274
+ the layout, because only the page holds the body it is read from. -->
275
+ <div v-if="owned" class="flex min-w-0 flex-1 gap-10">
276
+ <div class="min-w-0 flex-1 py-8">
277
+ <DuxtVersionBanner />
278
+
279
+ <DuxtTranslationBanner v-if="untranslated" :from="found?.from" />
280
+
281
+ <!-- THE SAME HEADER A WRITTEN PAGE GETS, for a type that draws no title
282
+ of its own. A release page has a title, a description and a trail
283
+ like any other, and the only reason it ever drew its own heading was
284
+ that the layout drew none — which left the copy control floating in a
285
+ row above a title it belongs beside. -->
286
+ <!-- As wide as the page below it. The reading measure is the LAYOUT's
287
+ to set — `changelog` caps its own column, `reference` deliberately
288
+ does not — and a header narrower than the parameter tables under it
289
+ draws a rule that stops halfway across the page. -->
290
+ <header v-if="!titled" class="mb-8 border-b pb-8">
291
+ <DuxtBreadcrumb
292
+ v-if="duxt?.breadcrumb !== false"
293
+ :path="path"
294
+ class="mb-3"
295
+ />
296
+
297
+ <div class="flex items-start justify-between gap-4">
298
+ <h1
299
+ ref="heading"
300
+ tabindex="-1"
301
+ class="text-4xl font-semibold tracking-tight text-balance outline-none"
302
+ >
303
+ {{ page?.title }}
304
+ </h1>
305
+
306
+ <DuxtCopyPage
307
+ class="mt-1"
308
+ :path="path"
309
+ :title="page?.title"
310
+ :rawbody="(page as { rawbody?: string })?.rawbody"
311
+ />
312
+ </div>
313
+
314
+ <!-- THE DESCRIPTION, unless the body already opens with it — see
315
+ `generatedLead`. A page whose description Content derived from its
316
+ own first paragraph would print that sentence twice, three lines
317
+ apart; one whose type WROTE a description (an API document's
318
+ `summary`, which appears nowhere in its prose) reads like every
319
+ written page instead, with the lead under the title rather than
320
+ below the rule. -->
321
+ <p
322
+ v-if="described"
323
+ class="mt-3 text-lg text-muted-foreground text-pretty"
324
+ >
325
+ {{ page?.description }}
326
+ </p>
327
+ </header>
328
+
329
+ <!-- A type that DOES draw its own title keeps the compact row: where the
330
+ reader is, and what they can do with the page. -->
331
+ <div v-else class="mb-6 flex items-start justify-between gap-4">
332
+ <DuxtBreadcrumb v-if="duxt?.breadcrumb !== false" :path="path" />
333
+
334
+ <DuxtCopyPage
335
+ class="-mt-1 ml-auto"
336
+ :path="path"
337
+ :title="page?.title"
338
+ :rawbody="(page as { rawbody?: string })?.rawbody"
339
+ />
340
+ </div>
341
+
342
+ <div class="typeset typeset-docs">
343
+ <ContentRenderer v-if="page" :value="page" />
344
+ </div>
345
+
346
+ <!-- The SECTION's own order, which is what a generated section has: the
347
+ releases newest to oldest, the endpoints as the artefact listed them.
348
+ `DuxtPageNav` walks the same navigation the sidebar draws and stops
349
+ at the section's edge, so the links can only be siblings — and a
350
+ release page that ended in whitespace now ends in the release before
351
+ it, which is how a history is read. -->
352
+ <DuxtPageNav :path="path" />
353
+
354
+ <!-- Provenance survives the header, because it is the one part of it that
355
+ is still true: every page of a generated section came out of one
356
+ artefact, and `DuxtPageInfo` already links at that artefact rather
357
+ than at a file named after the URL. It moves into the column beside
358
+ the contents wherever there is one, exactly as in the docs shell. -->
359
+ <!-- As a row, and as wide as the page: with no column to sit in it is a
360
+ footer, and a rule that stopped at the reading measure under a page
361
+ set wider than that ended halfway across. -->
362
+ <DuxtPageInfo v-if="!aside" row :page="page" />
363
+ </div>
364
+
365
+ <div v-if="aside" class="hidden w-56 shrink-0 xl:block">
366
+ <div
367
+ class="sticky top-[var(--duxt-header-offset)] max-h-[calc(100vh-var(--duxt-header-offset)-1.5rem)] overflow-y-auto py-8"
368
+ >
369
+ <DuxtToc :links="generated" />
370
+
371
+ <DuxtPageInfo :page="page" />
372
+ </div>
373
+ </div>
374
+ </div>
375
+
376
+ <div v-else class="flex min-w-0 flex-1 justify-center gap-10">
377
+ <article class="min-w-0 max-w-3xl flex-1 py-8">
378
+ <DuxtVersionBanner />
379
+
380
+ <DuxtTranslationBanner v-if="untranslated" :from="found?.from" />
381
+
382
+ <header class="mb-8 border-b pb-8">
383
+ <DuxtBreadcrumb
384
+ v-if="duxt?.breadcrumb !== false"
385
+ :path="path"
386
+ class="mb-3"
387
+ />
388
+ <!-- The copy action sits with the title, not under the article: it is
389
+ what a reader does with the page BEFORE reading it, and a control
390
+ for that at the bottom is a control nobody finds. -->
391
+ <div class="flex items-start justify-between gap-4">
392
+ <h1
393
+ ref="heading"
394
+ tabindex="-1"
395
+ class="text-4xl font-semibold tracking-tight text-balance outline-none"
396
+ >
397
+ {{ page?.title }}
398
+ </h1>
399
+
400
+ <DuxtCopyPage
401
+ class="mt-1"
402
+ :path="path"
403
+ :title="page?.title"
404
+ :rawbody="(page as { rawbody?: string })?.rawbody"
405
+ />
406
+ </div>
407
+ <p
408
+ v-if="page?.description"
409
+ class="mt-3 text-lg text-muted-foreground text-pretty"
410
+ >
411
+ {{ page.description }}
412
+ </p>
413
+ </header>
414
+
415
+ <div class="typeset typeset-docs">
416
+ <ContentRenderer v-if="page" :value="page" />
417
+ </div>
418
+
419
+ <DuxtPageNav :path="path" />
420
+
421
+ <DuxtPageFeedback />
422
+ </article>
423
+
424
+ <!-- A div for the same reason as the sidebar's: DuxtToc's two <nav>s are
425
+ the landmarks, and both are labelled. -->
426
+ <div class="hidden w-56 shrink-0 xl:block">
427
+ <div
428
+ class="sticky top-[var(--duxt-header-offset)] max-h-[calc(100vh-var(--duxt-header-offset)-1.5rem)] overflow-y-auto py-8"
429
+ >
430
+ <DuxtToc :links="page?.body?.toc?.links ?? []" />
431
+
432
+ <!-- Provenance under the contents: where this page came from, when it
433
+ last changed and who wrote it. On the right rather than under the
434
+ article, where it read as an afterthought below the prev/next
435
+ links — this column is already the one answering what a page IS
436
+ rather than what it says. -->
437
+ <DuxtPageInfo :page="page" />
438
+ </div>
439
+ </div>
440
+ </div>
441
+ </template>