@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,352 @@
1
+ import { duxtDefaults, mergeDuxtConfig } from '../../../app/utils/duxt-config';
2
+ import {
3
+ code,
4
+ dim,
5
+ escape,
6
+ filter,
7
+ json,
8
+ row,
9
+ stat,
10
+ stats,
11
+ table,
12
+ tag
13
+ } from '../shell';
14
+
15
+ /**
16
+ * The panels about the machinery around the content: the merged config, the
17
+ * message catalogues, Content's download cache and the redirects that shipped.
18
+ *
19
+ * Each answers a question whose answer exists only as a side effect somewhere —
20
+ * inside a defu call, across seven JSON files, in a directory nobody opens, in
21
+ * a route-rule table generated at build time. The reading of those side effects
22
+ * lives in `../system.ts`; this half turns what was read into a table.
23
+ */
24
+
25
+ /* -------------------------------------------------------------------------- */
26
+ /* Config */
27
+ /* -------------------------------------------------------------------------- */
28
+
29
+ /**
30
+ * The merged config, with the side of the merge each value came from.
31
+ *
32
+ * `mergeDuxtConfig` replaces arrays and merges objects, which is the subtlest
33
+ * rule in the layer: a consumer's `navigation` is the navigation, but its
34
+ * `footer.note` leaves `footer.columns` alone. "Why is duxt's entry still in my
35
+ * navbar" takes one look here instead of a session.
36
+ */
37
+ export function renderConfig(consumer: Record<string, unknown>): string {
38
+ const merged = mergeDuxtConfig(
39
+ consumer as unknown as Partial<DuxtConfig>,
40
+ duxtDefaults
41
+ ) as unknown as Record<string, unknown>;
42
+
43
+ const rows: string[] = [];
44
+ const counted: Origins = { consumer: 0, layer: 0, build: 0 };
45
+ collect(
46
+ merged,
47
+ consumer,
48
+ duxtDefaults as unknown as Record<string, unknown>,
49
+ '',
50
+ rows,
51
+ counted
52
+ );
53
+
54
+ const summary = stats([
55
+ stat(rows.length, 'keys'),
56
+ stat(counted.consumer, 'from the site', 'ok'),
57
+ stat(counted.layer, 'from the layer'),
58
+ stat(counted.build, 'computed')
59
+ ]);
60
+
61
+ return `${summary}<div class="note">Arrays are replaced whole, objects merge key by key. A row marked ${tag(
62
+ 'build'
63
+ )} was computed by <code>modules/config.ts</code> and is written nowhere.</div>${filter(
64
+ 'Filter keys'
65
+ )}${table(['Key', 'From', 'Value'], rows)}`;
66
+ }
67
+
68
+ const BUILT = new Set(['resolvedSources']);
69
+
70
+ /**
71
+ * Tallied while the rows are built, not counted back out of them.
72
+ *
73
+ * The first version of this figure filtered the rendered rows for the string
74
+ * `>consumer<`, which is a search of the config's own VALUES as much as of its
75
+ * origin badges — a label reading "consumer" would have counted itself.
76
+ */
77
+ interface Origins {
78
+ consumer: number;
79
+ layer: number;
80
+ build: number;
81
+ }
82
+
83
+ /**
84
+ * A value the merge descends into: an object, and neither an array nor null.
85
+ *
86
+ * Checked on BOTH sides before recursing, not just for the merged value. The
87
+ * two sides of a key need not have the same shape — `aside.title` is a
88
+ * translation key in the layer's defaults and a per-locale object in a site
89
+ * that translates it — and the earlier version tested only whether the KEY was
90
+ * present, then walked into the string with `in`, which throws. A panel that
91
+ * crashes on a translated string is a panel nobody can open on the site that
92
+ * needs it most.
93
+ */
94
+ const branches = (value: unknown): value is Record<string, unknown> =>
95
+ Boolean(value) && typeof value === 'object' && !Array.isArray(value);
96
+
97
+ function collect(
98
+ merged: Record<string, unknown>,
99
+ consumer: Record<string, unknown> | undefined,
100
+ defaults: Record<string, unknown> | undefined,
101
+ prefix: string,
102
+ rows: string[],
103
+ counted: Origins
104
+ ): void {
105
+ for (const [key, value] of Object.entries(merged)) {
106
+ const path = prefix ? `${prefix}.${key}` : key;
107
+ const inConsumer = branches(consumer) ? key in consumer : false;
108
+
109
+ // Recurse only where both sides are objects: an array is a single value
110
+ // here, by the same rule the merge itself follows, and a key that is an
111
+ // object on one side and a string on the other is a REPLACED value — which
112
+ // is precisely what the reader opened this panel to see.
113
+ if (
114
+ branches(value) &&
115
+ branches(consumer?.[key]) &&
116
+ branches(defaults?.[key])
117
+ ) {
118
+ collect(
119
+ value as Record<string, unknown>,
120
+ consumer?.[key] as Record<string, unknown>,
121
+ defaults?.[key] as Record<string, unknown>,
122
+ path,
123
+ rows,
124
+ counted
125
+ );
126
+ continue;
127
+ }
128
+
129
+ const kind = BUILT.has(key) ? 'build' : inConsumer ? 'consumer' : 'layer';
130
+ counted[kind] += 1;
131
+
132
+ const origin =
133
+ kind === 'build'
134
+ ? tag('build')
135
+ : kind === 'consumer'
136
+ ? tag('consumer', 'ok')
137
+ : tag('layer', 'muted');
138
+
139
+ rows.push(row([code(path), origin, json(value)]));
140
+ }
141
+ }
142
+
143
+ /* -------------------------------------------------------------------------- */
144
+ /* i18n */
145
+ /* -------------------------------------------------------------------------- */
146
+
147
+ export interface LocaleFile {
148
+ /** The directory under `i18n/locales`, which is the locale's own name. */
149
+ dir: string;
150
+ /** Every message key it defines, flattened to `duxt.nav.open`. */
151
+ keys: string[];
152
+ }
153
+
154
+ export interface I18nData {
155
+ files: LocaleFile[];
156
+ /** The locales the site actually serves, which is a different list. */
157
+ locales: string[];
158
+ defaultLocale?: string;
159
+ }
160
+
161
+ /**
162
+ * Message keys per locale, against the base language.
163
+ *
164
+ * Seven locales and one JSON file per namespace make drift a matter of time,
165
+ * and i18n answers a missing key by printing the key — so a gap shows up as a
166
+ * label reading `duxt.nav.open` on a page nobody opened in that language.
167
+ */
168
+ export function renderI18n({
169
+ files,
170
+ locales,
171
+ defaultLocale
172
+ }: I18nData): string {
173
+ if (!files.length) return '<div class="note">No locales found.</div>';
174
+
175
+ const base = files.find((file) => file.dir === 'en') ?? files[0]!;
176
+ const baseKeys = new Set(base.keys);
177
+
178
+ const compared = files.map((file) => {
179
+ const keys = new Set(file.keys);
180
+
181
+ return {
182
+ dir: file.dir,
183
+ keys,
184
+ missing: [...baseKeys].filter((key) => !keys.has(key)),
185
+ extra: [...keys].filter((key) => !baseKeys.has(key))
186
+ };
187
+ });
188
+
189
+ const rows = compared.map(({ dir, keys, missing, extra }) =>
190
+ // A locale file may deliberately hold only its overrides — pt-BR against
191
+ // pt-PT is the case in this repo — so "missing" is a fact, not a verdict.
192
+ row([
193
+ code(dir) + (dir === base.dir ? ` ${tag('base')}` : ''),
194
+ String(keys.size),
195
+ missing.length
196
+ ? `${tag(String(missing.length), 'warn')} ${dim(truncate(missing.join(', '), 120))}`
197
+ : tag('complete', 'ok'),
198
+ extra.length
199
+ ? `${tag(String(extra.length), 'warn')} ${dim(truncate(extra.join(', '), 120))}`
200
+ : dim('—')
201
+ ])
202
+ );
203
+
204
+ const served = locales.length
205
+ ? `<p class="hint">Served locales: ${locales.map((locale) => code(locale)).join(' ')}${defaultLocale ? `, default ${code(defaultLocale)}` : ''}.</p>`
206
+ : '';
207
+
208
+ const gaps = compared.filter(
209
+ (entry) => entry.missing.length || entry.extra.length
210
+ ).length;
211
+
212
+ const summary = stats([
213
+ stat(files.length, 'locale files'),
214
+ stat(baseKeys.size, `keys in ${base.dir}`),
215
+ stat(gaps, 'with a gap', gaps ? 'warn' : 'ok')
216
+ ]);
217
+
218
+ return `${summary}${served}${table(
219
+ ['Directory', 'Keys', 'Missing vs base', 'Not in base'],
220
+ rows
221
+ )}`;
222
+ }
223
+
224
+ const truncate = (value: string, length: number) =>
225
+ value.length > length ? `${value.slice(0, length)}…` : value;
226
+
227
+ /* -------------------------------------------------------------------------- */
228
+ /* Cache */
229
+ /* -------------------------------------------------------------------------- */
230
+
231
+ export interface CacheEntry {
232
+ name: string;
233
+ /** Bytes on disk, summed over the directory. */
234
+ size: number;
235
+ modified: Date;
236
+ }
237
+
238
+ export interface CacheData {
239
+ dataDir: string;
240
+ /** `undefined` when the directory does not exist at all. */
241
+ entries?: CacheEntry[];
242
+ /** What the last drop did, if this render follows one. */
243
+ message?: string;
244
+ }
245
+
246
+ /**
247
+ * Content's download cache, and a way to drop one entry.
248
+ *
249
+ * A stale directory here cost real time once: a tag was fetched as a branch,
250
+ * failed, and the half-written `github.com-<owner>-<repo>-<ref>` folder kept
251
+ * answering for the fixed config until it was deleted by hand. Nothing in the
252
+ * build mentions this directory, so nothing suggests the fix.
253
+ */
254
+ export function renderCache({ dataDir, entries, message }: CacheData): string {
255
+ if (!entries) {
256
+ return '<div class="note">Nothing downloaded yet — <code>.data/content</code> does not exist.</div>';
257
+ }
258
+
259
+ const rows = entries.map((entry) =>
260
+ row([
261
+ code(entry.name),
262
+ megabytes(entry.size),
263
+ entry.modified.toISOString().replace('T', ' ').slice(0, 16),
264
+ `<form method="post" style="margin:0">
265
+ <input type="hidden" name="drop" value="${escape(entry.name)}">
266
+ <button type="submit">Drop</button>
267
+ </form>`
268
+ ])
269
+ );
270
+
271
+ const note = message ? `<div class="note">${escape(message)}</div>` : '';
272
+
273
+ const summary = stats([
274
+ stat(entries.length, 'cached sources'),
275
+ stat(
276
+ megabytes(entries.reduce((sum, entry) => sum + entry.size, 0)),
277
+ 'on disk'
278
+ )
279
+ ]);
280
+
281
+ return `${note}${summary}<p class="hint">${escape(dataDir)}</p>${table(
282
+ ['Entry', 'Size', 'Modified', ''],
283
+ rows,
284
+ 'The cache directory exists but holds no source. Nothing remote has been downloaded yet.'
285
+ )}<div class="note">Dropping an entry makes the next build download it again. Content keys a directory by repository <em>and</em> ref, so an entry for a ref you have renamed is never reused and never cleaned up either.</div>`;
286
+ }
287
+
288
+ const megabytes = (bytes: number) =>
289
+ bytes > 1024 * 1024
290
+ ? `${(bytes / 1024 / 1024).toFixed(1)} MB`
291
+ : `${Math.max(1, Math.round(bytes / 1024))} kB`;
292
+
293
+ /* -------------------------------------------------------------------------- */
294
+ /* Redirects */
295
+ /* -------------------------------------------------------------------------- */
296
+
297
+ export interface RedirectRule {
298
+ from: string;
299
+ to: string;
300
+ status: number | string;
301
+ /** True for a rule `redirectFrom` generated, false for another module's. */
302
+ mine: boolean;
303
+ }
304
+
305
+ /**
306
+ * The route rules that ship, and which of them are the layer's.
307
+ *
308
+ * Read rather than recomputed on purpose: a rule that was generated and a rule
309
+ * that shipped are different claims, and only the second one redirects
310
+ * anybody. Reading them back means reading EVERY module's — `@nuxtjs/sitemap`
311
+ * puts `/sitemap.xml` in the table on any multi-locale site — so the rules the
312
+ * layer wrote are marked as such, from the list `modules/redirects.ts` records
313
+ * beside them. Nothing in a route rule says who wrote it.
314
+ */
315
+ export function renderRedirects(rules?: RedirectRule[]): string {
316
+ if (!rules) {
317
+ return '<div class="note">Nitro exposed no route rules to read.</div>';
318
+ }
319
+
320
+ // The layer's own first: they are what this tab is opened for, and on a site
321
+ // with one moved page they would otherwise sit under a module's boilerplate.
322
+ const sorted = [...rules].sort(
323
+ (a, b) => Number(b.mine) - Number(a.mine) || a.from.localeCompare(b.from)
324
+ );
325
+
326
+ const rows = sorted.map((rule) =>
327
+ row([
328
+ code(rule.from),
329
+ code(rule.to),
330
+ typeof rule.status === 'string'
331
+ ? dim(rule.status)
332
+ : escape(String(rule.status)),
333
+ rule.mine ? tag('redirectFrom', 'ok') : tag('another module', 'muted')
334
+ ])
335
+ );
336
+
337
+ const mine = sorted.filter((rule) => rule.mine).length;
338
+
339
+ return `${stats([
340
+ stat(rows.length, 'rules'),
341
+ stat(mine, 'from redirectFrom', mine ? 'ok' : ''),
342
+ stat(rows.length - mine, 'from elsewhere')
343
+ ])}${table(
344
+ ['From', 'To', 'Status', 'Written by'],
345
+ rows,
346
+ 'The server shipped no redirect at all — not the layer’s, not a module’s.'
347
+ )}<div class="note">${
348
+ mine
349
+ ? 'One rule per prefix a page is served under — the repository segment, the version segment and every locale — because an old URL was bookmarked under exactly one of them and nothing says which.'
350
+ : 'No page carries <code>redirectFrom</code>, so the layer generated nothing; every rule above belongs to another module.'
351
+ }</div>`;
352
+ }