@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
package/nuxt.config.ts ADDED
@@ -0,0 +1,530 @@
1
+ import { createRequire } from 'node:module';
2
+ import { dirname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { defineNuxtConfig } from 'nuxt/config';
5
+ import tailwindcss from '@tailwindcss/vite';
6
+ import { highlightLangs } from './highlight-langs';
7
+
8
+ /** Resolve against this layer, not the project extending it. */
9
+ const layer = (path: string) => fileURLToPath(new URL(path, import.meta.url));
10
+
11
+ /**
12
+ * The one file Nitro's tracer cannot see.
13
+ *
14
+ * satori shapes text with harfbuzz, which is a WebAssembly module read at
15
+ * runtime with `fs.readFile` — not imported. Nothing in the module graph
16
+ * mentions it, so the build copies `harfbuzzjs`'s JavaScript and leaves
17
+ * `hb.wasm` behind, and the first request for an OG image dies with ENOENT on a
18
+ * path inside `.output`. Naming the file explicitly is the whole fix.
19
+ *
20
+ * Resolved rather than hard-coded, and optional: a consumer who has replaced
21
+ * the renderer, or pruned satori, must not have the build fail over a file
22
+ * nothing reads.
23
+ */
24
+ const require_ = createRequire(import.meta.url);
25
+
26
+ function harfbuzzWasm(): string | undefined {
27
+ try {
28
+ return join(
29
+ dirname(require_.resolve('harfbuzzjs/package.json')),
30
+ 'hb.wasm'
31
+ );
32
+ } catch {
33
+ return undefined;
34
+ }
35
+ }
36
+
37
+ const wasm = harfbuzzWasm();
38
+
39
+ /**
40
+ * The locales the layer ships strings for.
41
+ *
42
+ * Kept out of the config object so the icon client bundle below can derive the
43
+ * country flags from it, exactly as gildstone does. `code` needs `as const`:
44
+ * outside the literal TypeScript widens it to `string`, which no longer
45
+ * satisfies i18n's `LocaleObject<…>`.
46
+ *
47
+ * THE LANGUAGE CARRIES THE STRINGS, THE REGION ONLY ITS DEVIATIONS. i18n loads
48
+ * every file in `files` and deep-merges them in order, so `pt-BR` reads the
49
+ * European Portuguese set and then overwrites the handful of words Brazil
50
+ * spells differently. That is why there is no `en-GB/` or `en-US/` directory at
51
+ * all: nothing in this vocabulary differs between them, and a directory that
52
+ * would only duplicate `en/` is a directory that drifts from it.
53
+ *
54
+ * `name` is the endonym — each language written in itself, which is what a
55
+ * language switcher must show. It lives here rather than in the message files
56
+ * because it is the same string in every locale.
57
+ */
58
+ const locales = [
59
+ {
60
+ code: 'en-GB' as const,
61
+ language: 'en-GB',
62
+ name: 'English (UK)',
63
+ files: [
64
+ 'en/duxt/changelog.json',
65
+ 'en/duxt/code.json',
66
+ 'en/duxt/devtools.json',
67
+ 'en/duxt/defaults.json',
68
+ 'en/duxt/error.json',
69
+ 'en/duxt/footer.json',
70
+ 'en/duxt/locale.json',
71
+ 'en/duxt/nav.json',
72
+ 'en/duxt/openapi.json',
73
+ 'en/duxt/page.json',
74
+ 'en/duxt/search.json',
75
+ 'en/duxt/shortcuts.json',
76
+ 'en/duxt/theme.json',
77
+ 'en/duxt/toc.json',
78
+ 'en/duxt/version.json'
79
+ ]
80
+ },
81
+ {
82
+ code: 'en-US' as const,
83
+ language: 'en-US',
84
+ name: 'English (US)',
85
+ files: [
86
+ 'en/duxt/changelog.json',
87
+ 'en/duxt/code.json',
88
+ 'en/duxt/devtools.json',
89
+ 'en/duxt/defaults.json',
90
+ 'en/duxt/error.json',
91
+ 'en/duxt/footer.json',
92
+ 'en/duxt/locale.json',
93
+ 'en/duxt/nav.json',
94
+ 'en/duxt/openapi.json',
95
+ 'en/duxt/page.json',
96
+ 'en/duxt/search.json',
97
+ 'en/duxt/shortcuts.json',
98
+ 'en/duxt/theme.json',
99
+ 'en/duxt/toc.json',
100
+ 'en/duxt/version.json'
101
+ ]
102
+ },
103
+ {
104
+ code: 'de-DE' as const,
105
+ language: 'de-DE',
106
+ name: 'Deutsch',
107
+ files: [
108
+ 'de/duxt/changelog.json',
109
+ 'de/duxt/code.json',
110
+ 'de/duxt/devtools.json',
111
+ 'de/duxt/defaults.json',
112
+ 'de/duxt/error.json',
113
+ 'de/duxt/footer.json',
114
+ 'de/duxt/locale.json',
115
+ 'de/duxt/nav.json',
116
+ 'de/duxt/openapi.json',
117
+ 'de/duxt/page.json',
118
+ 'de/duxt/search.json',
119
+ 'de/duxt/shortcuts.json',
120
+ 'de/duxt/theme.json',
121
+ 'de/duxt/toc.json',
122
+ 'de/duxt/version.json'
123
+ ]
124
+ },
125
+ {
126
+ code: 'es-ES' as const,
127
+ language: 'es-ES',
128
+ name: 'Español',
129
+ files: [
130
+ 'es/duxt/changelog.json',
131
+ 'es/duxt/code.json',
132
+ 'es/duxt/devtools.json',
133
+ 'es/duxt/defaults.json',
134
+ 'es/duxt/error.json',
135
+ 'es/duxt/footer.json',
136
+ 'es/duxt/locale.json',
137
+ 'es/duxt/nav.json',
138
+ 'es/duxt/openapi.json',
139
+ 'es/duxt/page.json',
140
+ 'es/duxt/search.json',
141
+ 'es/duxt/shortcuts.json',
142
+ 'es/duxt/theme.json',
143
+ 'es/duxt/toc.json',
144
+ 'es/duxt/version.json'
145
+ ]
146
+ },
147
+ {
148
+ code: 'fr-FR' as const,
149
+ language: 'fr-FR',
150
+ name: 'Français',
151
+ files: [
152
+ 'fr/duxt/changelog.json',
153
+ 'fr/duxt/code.json',
154
+ 'fr/duxt/devtools.json',
155
+ 'fr/duxt/defaults.json',
156
+ 'fr/duxt/error.json',
157
+ 'fr/duxt/footer.json',
158
+ 'fr/duxt/locale.json',
159
+ 'fr/duxt/nav.json',
160
+ 'fr/duxt/openapi.json',
161
+ 'fr/duxt/page.json',
162
+ 'fr/duxt/search.json',
163
+ 'fr/duxt/shortcuts.json',
164
+ 'fr/duxt/theme.json',
165
+ 'fr/duxt/toc.json',
166
+ 'fr/duxt/version.json'
167
+ ]
168
+ },
169
+ {
170
+ code: 'pt-PT' as const,
171
+ language: 'pt-PT',
172
+ name: 'Português',
173
+ files: [
174
+ 'pt/duxt/changelog.json',
175
+ 'pt/duxt/code.json',
176
+ 'pt/duxt/devtools.json',
177
+ 'pt/duxt/defaults.json',
178
+ 'pt/duxt/error.json',
179
+ 'pt/duxt/footer.json',
180
+ 'pt/duxt/locale.json',
181
+ 'pt/duxt/nav.json',
182
+ 'pt/duxt/openapi.json',
183
+ 'pt/duxt/page.json',
184
+ 'pt/duxt/search.json',
185
+ 'pt/duxt/shortcuts.json',
186
+ 'pt/duxt/theme.json',
187
+ 'pt/duxt/toc.json',
188
+ 'pt/duxt/version.json'
189
+ ]
190
+ },
191
+ {
192
+ code: 'pt-BR' as const,
193
+ language: 'pt-BR',
194
+ name: 'Português (Brasil)',
195
+ files: [
196
+ 'pt/duxt/changelog.json',
197
+ 'pt/duxt/code.json',
198
+ 'pt/duxt/devtools.json',
199
+ 'pt/duxt/defaults.json',
200
+ 'pt/duxt/error.json',
201
+ 'pt/duxt/footer.json',
202
+ 'pt/duxt/locale.json',
203
+ 'pt/duxt/nav.json',
204
+ 'pt/duxt/openapi.json',
205
+ 'pt/duxt/page.json',
206
+ 'pt/duxt/search.json',
207
+ 'pt/duxt/shortcuts.json',
208
+ 'pt/duxt/theme.json',
209
+ 'pt/duxt/toc.json',
210
+ 'pt/duxt/version.json',
211
+ 'pt-BR/duxt/error.json',
212
+ 'pt-BR/duxt/nav.json',
213
+ 'pt-BR/duxt/page.json',
214
+ 'pt-BR/duxt/search.json',
215
+ 'pt-BR/duxt/version.json'
216
+ ]
217
+ }
218
+ ];
219
+
220
+ // The layer itself. A consumer gets all of this by extending '@kirchdev/duxt',
221
+ // which resolves through package.json's `main` to this file.
222
+ export default defineNuxtConfig({
223
+ modules: [
224
+ // First: it narrows the locale list before @nuxtjs/i18n reads it, and
225
+ // resolves the source manifest before anything queries a collection.
226
+ layer('./modules/config.ts'),
227
+
228
+ // Reads what Content parses and reports what the build would otherwise
229
+ // swallow — an empty collection, a folder shadowed by a prefix, a link
230
+ // pointing nowhere, a page with no title.
231
+ layer('./modules/validate.ts'),
232
+
233
+ // A devtools tab showing the resolved sources — dev only, and a no-op
234
+ // outside it.
235
+ layer('./modules/devtools.ts'),
236
+
237
+ // "Last updated" and the contributor list, read off each page's own git
238
+ // history at parse time.
239
+ layer('./modules/git-meta.ts'),
240
+
241
+ // `redirectFrom:` in a page's frontmatter, under every prefix the site
242
+ // serves that page at.
243
+ layer('./modules/redirects.ts'),
244
+
245
+ /**
246
+ * The SEO half, BEFORE Content on purpose.
247
+ *
248
+ * @nuxtjs/sitemap wires itself into Content's collections, and it says so
249
+ * out loud when it is loaded second — "this may cause issues with the
250
+ * integration". It does: the sitemap then lists the site's routes and not
251
+ * one documentation page. The bundle loads its modules in its own order,
252
+ * so the whole bundle goes here rather than three named modules.
253
+ *
254
+ * `@nuxtjs/seo` is an ALIAS, not a wrapper — its own documentation says it
255
+ * "contains no logic of its own". What it buys is the four modules this
256
+ * layer used to do by hand: schema.org from `nuxt-schema-org`, the
257
+ * automatic canonical and og/twitter tags from `nuxt-seo-utils`, the link
258
+ * check, and `nuxt-site-config` as the one place `site.url` is read from.
259
+ * It also completes the shared devtools panel, which every one of these
260
+ * modules feeds and which lists the ones that are missing.
261
+ *
262
+ * They all read `site.url`, which the duxt module fills in from
263
+ * `i18n.baseUrl` so a consumer states its origin once rather than five
264
+ * times; without one they degrade to relative output rather than inventing
265
+ * a domain.
266
+ */
267
+ '@nuxtjs/seo',
268
+ '@nuxt/image',
269
+
270
+ '@nuxt/content',
271
+ '@nuxt/icon',
272
+ '@nuxtjs/color-mode',
273
+ 'shadcn-nuxt',
274
+ '@nuxtjs/mcp-toolkit',
275
+ '@nuxtjs/i18n'
276
+ ],
277
+
278
+ /**
279
+ * NO `hooks` KEY, AND NO `serverDir`. The layer's own `server/` is found by
280
+ * Nitro without either.
281
+ *
282
+ * These routes used to be pushed by hand from a `nitro:config` hook, on the
283
+ * belief that only the consumer's server directory is scanned. The
284
+ * production bundle disproves it: its handler list carried every one of them
285
+ * TWICE — once lazily, in alphabetical order, from a filesystem scan of this
286
+ * layer's `server/routes/`, and once eagerly in the order the hook pushed
287
+ * them. The middleware too.
288
+ *
289
+ * So Nitro scans `server/routes/` and `server/middleware/` in EVERY layer,
290
+ * derives the route from the file name and the method from its `.get`
291
+ * suffix, and loads each handler on demand. A consumer's own `server/` is
292
+ * merged rather than replaced, which is what the hook was there to protect
293
+ * and never had to.
294
+ *
295
+ * Left as a comment rather than deleted: the next person to add a route here
296
+ * will look for the place it is registered, and the answer is that there
297
+ * isn't one.
298
+ */
299
+
300
+ // A real MCP server at /mcp, through the official SDK, instead of a JSON
301
+ // endpoint someone else has to wrap. Tools live in server/mcp/tools.
302
+ // No `name`: the module's own default is the empty string, so
303
+ // `modules/config.ts` derives one from the site's own title instead. Left as
304
+ // a literal here it published duxt's name from every downstream site.
305
+ mcp: {
306
+ description: 'The documentation this site publishes, readable by an agent.',
307
+ instructions:
308
+ 'Call list_pages for the table of contents, search_docs to find a page by ' +
309
+ 'term, and read_page for the full text of one page.'
310
+ },
311
+
312
+ nitro: wasm ? { externals: { traceInclude: [wasm] } } : {},
313
+
314
+ css: [layer('./app/assets/css/duxt.css')],
315
+
316
+ // '@' belongs to whoever extends the layer. Imports inside the layer use
317
+ // '@duxt' so they resolve here regardless of the consumer's own aliases.
318
+ alias: {
319
+ '@duxt': layer('./app')
320
+ },
321
+
322
+ content: {
323
+ build: {
324
+ markdown: {
325
+ // Without an explicit theme Content ships no highlighter at all, and
326
+ // every fence renders as flat text. Two themes so the switch follows
327
+ // the site's own light/dark class rather than a media query.
328
+ highlight: {
329
+ theme: {
330
+ default: 'github-light',
331
+ dark: 'github-dark'
332
+ },
333
+ langs: highlightLangs
334
+ }
335
+ }
336
+ },
337
+
338
+ // Content's default driver, better-sqlite3, is a native addon compiled
339
+ // through node-gyp. Node 24 ships node:sqlite, so no driver package is
340
+ // needed — see CLAUDE.md for the fallback if this flag ever goes away.
341
+ experimental: {
342
+ nativeSqlite: true
343
+ }
344
+ },
345
+
346
+ /**
347
+ * The sitemap lists pages, not versions of pages.
348
+ *
349
+ * `exclude` is filled in by the duxt module from the resolved manifest — a
350
+ * version that is not the default carries `noindex` and a canonical pointing
351
+ * elsewhere, so listing it here would ask a crawler to fetch exactly what the
352
+ * page then tells it to drop. Same for an `eol` version, which is excluded
353
+ * whether or not it is the default.
354
+ */
355
+ // The devtools previews in `public/` are fixtures for one reference page, not
356
+ // pages of anybody's site. Every consumer serves them, because Nuxt serves
357
+ // every layer's `public/` — and none of them wants ten documents titled
358
+ // "duxt — Sources" indexed against their own domain.
359
+ //
360
+ // defu concatenates the list across layers, so a consumer's own `disallow`
361
+ // is added to this rather than replacing it.
362
+ robots: {
363
+ disallow: ['/devtools/']
364
+ },
365
+
366
+ sitemap: {
367
+ // Content pages reach the sitemap through the module's own Content
368
+ // integration; the duxt module adds what the version rules exclude.
369
+ //
370
+ // Partials are the one entry written by hand: they share the pages' schema
371
+ // (see `definePartials`), so the sitemap module treats them as pages, and
372
+ // a block of prose meant to be included in three places is not a page a
373
+ // crawler should be offered.
374
+ exclude: ['/_partials/**', '/*/_partials/**']
375
+ },
376
+
377
+ /**
378
+ * nuxt-seo-utils, whose defaults are written for a site that sets no head
379
+ * tags of its own. Three of them are wrong HERE, and each for a reason this
380
+ * layer cannot design away.
381
+ */
382
+ seo: {
383
+ /**
384
+ * A LOCALE PREFIX IS CASE-SENSITIVE. i18n routes this site's locales under
385
+ * their own codes — `/de-DE/guides`, `/pt-BR/guides` — and lowercasing a
386
+ * canonical would point every translated page at a URL that 404s. The
387
+ * option exists for sites whose paths differ only in case; ours do not.
388
+ */
389
+ canonicalLowercase: false,
390
+
391
+ /**
392
+ * A title invented from the last slug segment is a title nobody wrote.
393
+ * Every page here carries one from its frontmatter, and `modules/validate`
394
+ * fails the build over a page that does not — so the fallback can only ever
395
+ * mask that check.
396
+ */
397
+ fallbackTitle: false,
398
+
399
+ /**
400
+ * `app.vue` owns the title template — it appends the site's own name, which
401
+ * is what a tab and a search result need. Letting site config inject a
402
+ * second one leaves two templates competing over one title.
403
+ */
404
+ mergeWithSiteConfig: false
405
+ },
406
+
407
+ /**
408
+ * The link check REPORTS, it does not fail the build: `modules/validate.ts`
409
+ * already fails it over a link pointing nowhere, and it is the one that knows
410
+ * about versions and locale fallbacks. Two gates over one rule means the
411
+ * looser one decides when a build breaks, which is the wrong way round.
412
+ *
413
+ * What the module adds over that is the devtools panel and the live check
414
+ * while writing, which is where a broken link is cheapest to fix.
415
+ */
416
+ linkChecker: {
417
+ failOnError: false,
418
+ excludeLinks: ['/devtools/**']
419
+ },
420
+
421
+ colorMode: {
422
+ // shadcn switches on a `dark` class, not a data attribute or a media query.
423
+ classSuffix: '',
424
+ preference: 'system',
425
+ fallback: 'light'
426
+ },
427
+
428
+ shadcn: {
429
+ // PREFIXED, and deliberately. Without one the layer auto-imports `Button`,
430
+ // `Input`, `Card` and a hundred more into every site that extends it —
431
+ // ordinary words a consumer is likely to want for a component of their own,
432
+ // and a collision resolves silently in favour of whichever Nuxt registered
433
+ // last. `Ui` says where a component comes from at the call site and keeps
434
+ // the plain names free for the site being built.
435
+ prefix: 'Ui',
436
+ componentDir: layer('./app/components/ui')
437
+ },
438
+
439
+ icon: {
440
+ // SVG mode, not the default span: shadcn's Alert, Button and Sidebar all
441
+ // style their icon slot with `>svg` selectors, which never match a span.
442
+ mode: 'svg',
443
+
444
+ // Inline the icons actually used into the client bundle instead of fetching
445
+ // them per collection after hydration — no roundtrip, no icon flash.
446
+ clientBundle: {
447
+ // Vue and TS files, plus the MARKDOWN a docs site is made of. Without the
448
+ // second glob an icon named only in a page's frontmatter — which is where
449
+ // a documentation tree names most of its icons — is missing from the
450
+ // bundle, so it is absent from the server-rendered HTML and arrives, if
451
+ // at all, over the network after hydration. `**/*.md` reaches the pages
452
+ // of the consumer's own repository; a source downloaded from another one
453
+ // is cached outside the scan and still falls back to the API.
454
+ scan: {
455
+ globInclude: ['**/*.{vue,jsx,tsx,ts,js,mjs}', '**/*.md']
456
+ },
457
+ sizeLimitKb: 512,
458
+
459
+ // The locale switcher names its flags at runtime (`flag:${code}-4x3`), so
460
+ // the scanner above cannot see them and they would be fetched over the
461
+ // network after hydration instead. Derived from `locales` rather than
462
+ // listed by hand: a new locale brings its flag along by itself.
463
+ icons: locales.map(
464
+ (locale) => `flag:${locale.code.split('-')[1]!.toLowerCase()}-4x3`
465
+ )
466
+ }
467
+ },
468
+
469
+ /**
470
+ * The layer's own interface, translated. NOT the Markdown — that is a
471
+ * separate question and deliberately untouched here.
472
+ *
473
+ * `strategy: 'prefix_except_default'` is the load-bearing choice. duxt serves
474
+ * `/getting-started` today, and `prefix` would move that to
475
+ * `/en-GB/getting-started` for every consumer that has one — a breaking
476
+ * change to the URLs docs are reached by, paid by the many single-locale
477
+ * consumers to benefit the few multilingual ones. It is also what VitePress,
478
+ * Starlight and Docusaurus all do. A consumer whose site has no leading
479
+ * language writes `i18n: { strategy: 'prefix' }` and gets the symmetric
480
+ * scheme in one line.
481
+ *
482
+ * The price: `defaultLocale` becomes URL-relevant. Changing it later moves
483
+ * every page in both directions at once. Set it once, then leave it.
484
+ *
485
+ * `langDir` stays RELATIVE on purpose, against this layer's own i18n/
486
+ * directory. Everything else layer-relative in this file goes through
487
+ * `layer()`, but i18n resolves langDir per layer itself — that is what its
488
+ * layers support is — and handing it an absolute path opts out of the
489
+ * merging that lets a consumer override a single string.
490
+ */
491
+ i18n: {
492
+ locales,
493
+ defaultLocale: 'en-GB',
494
+ langDir: 'locales',
495
+ strategy: 'prefix_except_default',
496
+ vueI18n: 'i18n.config.ts',
497
+ detectBrowserLanguage: {
498
+ fallbackLocale: 'en-GB',
499
+ useCookie: true,
500
+ cookieKey: 'duxt_locale',
501
+ cookieSecure: true,
502
+ // An explicit URL stays authoritative: /de-DE/guide shared into a chat
503
+ // must still be German for whoever opens it. Only '/' follows the
504
+ // browser's preference.
505
+ redirectOn: 'root',
506
+ alwaysRedirect: false
507
+ }
508
+ },
509
+
510
+ vite: {
511
+ plugins: [tailwindcss()],
512
+
513
+ ssr: {
514
+ // reka-ui is a dependency of the LAYER, so Nitro externalises it for SSR
515
+ // and the server imports a different copy than the client bundle uses.
516
+ // Its provide/inject then never matches and SSR dies with a null
517
+ // instance. Inlining it keeps one copy on both sides.
518
+ noExternal: ['reka-ui', 'vue-sonner']
519
+ },
520
+
521
+ resolve: {
522
+ // Force singleton resolution. The layer and the project extending it can
523
+ // each resolve their own copy of these, and reka-ui's provide/inject then
524
+ // stops matching across the two — which only fails in a production build,
525
+ // where dev's shared module graph is gone. gildstone carries the same
526
+ // dedupe for the same class of bug.
527
+ dedupe: ['vue', 'reka-ui', 'vue-sonner']
528
+ }
529
+ }
530
+ });