@lupinum/ginko-docs 0.4.0-rc.9 → 0.5.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 (304) hide show
  1. package/CHANGELOG.md +141 -0
  2. package/LICENSE +1 -1
  3. package/README.md +300 -53
  4. package/app/app.config.ts +44 -55
  5. package/app/assets/docs.css +619 -0
  6. package/app/components/DocsBanner.vue +29 -0
  7. package/app/components/DocsExample.vue +43 -0
  8. package/app/components/DocsFooter.vue +19 -0
  9. package/app/components/DocsHeader.vue +113 -0
  10. package/app/components/DocsIcon.vue +12 -0
  11. package/app/components/DocsLanding.vue +58 -0
  12. package/app/components/DocsLanguage.vue +40 -0
  13. package/app/components/DocsNavSheet.vue +37 -0
  14. package/app/components/DocsNavTree.vue +38 -0
  15. package/app/components/DocsPage.vue +88 -0
  16. package/app/components/DocsPageActions.vue +47 -0
  17. package/app/components/DocsPageEnd.ts +12 -0
  18. package/app/components/DocsPost.vue +58 -0
  19. package/app/components/DocsSearch.vue +136 -0
  20. package/app/components/DocsShell.vue +36 -0
  21. package/app/components/DocsSidebar.vue +19 -0
  22. package/app/components/DocsSidebarEnd.ts +4 -0
  23. package/app/components/DocsTable.vue +11 -0
  24. package/app/components/DocsThemeToggle.vue +45 -0
  25. package/app/components/DocsToc.vue +73 -0
  26. package/app/composables/useDocs.ts +53 -0
  27. package/app/composables/useDocsBlog.ts +33 -0
  28. package/app/composables/useDocsCopy.ts +17 -0
  29. package/app/composables/useDocsFrame.ts +11 -0
  30. package/app/composables/useDocsPopover.ts +36 -0
  31. package/app/composables/useDocsSite.ts +31 -0
  32. package/app/docs-pages/blog.vue +55 -0
  33. package/app/docs-pages/changelog.vue +35 -0
  34. package/app/docs-pages/doc.vue +16 -0
  35. package/app/docs-pages/docs.vue +9 -0
  36. package/app/docs-pages/index.vue +12 -0
  37. package/app/docs-pages/post.vue +8 -0
  38. package/app/error.vue +38 -115
  39. package/app/layouts/default.vue +29 -7
  40. package/app/lib/blogTypes.ts +8 -0
  41. package/app/lib/docsFirst.ts +11 -0
  42. package/app/lib/docsInit.ts +18 -0
  43. package/app/lib/docsNav.ts +36 -0
  44. package/app/lib/docsPage.ts +84 -0
  45. package/app/lib/markdownComponents.ts +15 -0
  46. package/app/lib/previewToc.ts +18 -0
  47. package/dist/config.d.mts +252 -0
  48. package/dist/config.d.ts +252 -0
  49. package/dist/config.mjs +83 -0
  50. package/dist/icons.d.mts +38 -0
  51. package/dist/icons.d.ts +38 -0
  52. package/dist/icons.mjs +175 -0
  53. package/dist/pages.d.mts +5 -0
  54. package/dist/pages.d.ts +5 -0
  55. package/dist/pages.mjs +68 -0
  56. package/i18n/de.json +1 -0
  57. package/i18n/en.json +1 -0
  58. package/i18n/fr.json +1 -0
  59. package/icons/README.md +2 -0
  60. package/icons/bluesky.svg +1 -0
  61. package/icons/claude.svg +1 -0
  62. package/icons/discord.svg +1 -0
  63. package/icons/github.svg +1 -0
  64. package/icons/linkedin.svg +1 -0
  65. package/icons/mastodon.svg +1 -0
  66. package/icons/openai.svg +1 -0
  67. package/icons/x.svg +1 -0
  68. package/icons/youtube.svg +1 -0
  69. package/nuxt.config.ts +22 -212
  70. package/package.json +44 -76
  71. package/public/_docs/fonts/LICENSE +188 -0
  72. package/public/_docs/fonts/inter-latin-wght-normal.woff2 +0 -0
  73. package/public/_docs/fonts/jetbrains-mono-latin-400-normal.woff2 +0 -0
  74. package/public/_docs/fonts/jetbrains-mono-latin-500-normal.woff2 +0 -0
  75. package/server/feeds/blog-locale.get.ts +9 -0
  76. package/server/feeds/blog.get.ts +4 -0
  77. package/server/lib/blogFeed.ts +35 -0
  78. package/server/mcp/handler.ts +108 -0
  79. package/server/routes/__ginko/docs-mcp.ts +35 -0
  80. package/shared/layerRoutes.ts +66 -0
  81. package/shared/paths.ts +4 -0
  82. package/app/app.vue +0 -98
  83. package/app/assets/css/prose.css +0 -3240
  84. package/app/assets/css/tailwind.css +0 -394
  85. package/app/assets/css/theme-palettes.css +0 -309
  86. package/app/assets/css/theme-presets.css +0 -141
  87. package/app/components/OgImage/GinkoDocs.satori.vue +0 -238
  88. package/app/components/content/DocumentPageShell.vue +0 -55
  89. package/app/components/content/Feedback.vue +0 -102
  90. package/app/components/content/ImageZoomDialog.vue +0 -84
  91. package/app/components/content/PageMarkdownCopy.vue +0 -104
  92. package/app/components/content/imageZoom.ts +0 -25
  93. package/app/components/mdc/MdcAccordion.vue +0 -67
  94. package/app/components/mdc/MdcAccordionItem.vue +0 -42
  95. package/app/components/mdc/MdcApi.vue +0 -159
  96. package/app/components/mdc/MdcAside.vue +0 -23
  97. package/app/components/mdc/MdcCallout.vue +0 -61
  98. package/app/components/mdc/MdcCard.vue +0 -175
  99. package/app/components/mdc/MdcCards.vue +0 -30
  100. package/app/components/mdc/MdcCenter.vue +0 -71
  101. package/app/components/mdc/MdcCodeGroup.vue +0 -197
  102. package/app/components/mdc/MdcCodeTree.vue +0 -234
  103. package/app/components/mdc/MdcCollapse.vue +0 -61
  104. package/app/components/mdc/MdcColumn.vue +0 -70
  105. package/app/components/mdc/MdcDropcap.vue +0 -84
  106. package/app/components/mdc/MdcError.vue +0 -23
  107. package/app/components/mdc/MdcExcerpt.vue +0 -26
  108. package/app/components/mdc/MdcFigure.vue +0 -85
  109. package/app/components/mdc/MdcFiles.vue +0 -120
  110. package/app/components/mdc/MdcIdea.vue +0 -17
  111. package/app/components/mdc/MdcInfo.vue +0 -17
  112. package/app/components/mdc/MdcInlineToc.vue +0 -51
  113. package/app/components/mdc/MdcKbd.vue +0 -10
  114. package/app/components/mdc/MdcLayout.vue +0 -57
  115. package/app/components/mdc/MdcNote.vue +0 -17
  116. package/app/components/mdc/MdcQuiz.vue +0 -241
  117. package/app/components/mdc/MdcQuizQuestion.vue +0 -221
  118. package/app/components/mdc/MdcReadMore.vue +0 -70
  119. package/app/components/mdc/MdcSteps.vue +0 -59
  120. package/app/components/mdc/MdcSuccess.vue +0 -23
  121. package/app/components/mdc/MdcTab.vue +0 -17
  122. package/app/components/mdc/MdcTabs.vue +0 -150
  123. package/app/components/mdc/MdcTimeline.vue +0 -17
  124. package/app/components/mdc/MdcTimelineItem.vue +0 -40
  125. package/app/components/mdc/MdcWarning.vue +0 -23
  126. package/app/components/mdc/api.utils.ts +0 -132
  127. package/app/components/mdc/code-tree.utils.ts +0 -22
  128. package/app/components/mdc/icons.ts +0 -10
  129. package/app/components/mdc/quiz.utils.ts +0 -38
  130. package/app/components/prose/ProseA.vue +0 -27
  131. package/app/components/prose/ProseBlockquote.vue +0 -30
  132. package/app/components/prose/ProseCode.vue +0 -14
  133. package/app/components/prose/ProseEm.vue +0 -14
  134. package/app/components/prose/ProseH1.vue +0 -18
  135. package/app/components/prose/ProseH2.vue +0 -29
  136. package/app/components/prose/ProseH3.vue +0 -29
  137. package/app/components/prose/ProseH4.vue +0 -29
  138. package/app/components/prose/ProseH5.vue +0 -15
  139. package/app/components/prose/ProseH6.vue +0 -15
  140. package/app/components/prose/ProseHr.vue +0 -12
  141. package/app/components/prose/ProseImg.vue +0 -55
  142. package/app/components/prose/ProseLi.vue +0 -14
  143. package/app/components/prose/ProseOl.vue +0 -14
  144. package/app/components/prose/ProseP.vue +0 -14
  145. package/app/components/prose/ProsePre.vue +0 -180
  146. package/app/components/prose/ProseStrong.vue +0 -14
  147. package/app/components/prose/ProseTable.vue +0 -18
  148. package/app/components/prose/ProseTbody.vue +0 -14
  149. package/app/components/prose/ProseTd.vue +0 -14
  150. package/app/components/prose/ProseTh.vue +0 -14
  151. package/app/components/prose/ProseThead.vue +0 -14
  152. package/app/components/prose/ProseTr.vue +0 -14
  153. package/app/components/prose/ProseUl.vue +0 -14
  154. package/app/components/site/ModeToggle.vue +0 -81
  155. package/app/components/site/SiteBanner.vue +0 -97
  156. package/app/components/site/SiteFooter.vue +0 -90
  157. package/app/components/site/SiteHeader.vue +0 -371
  158. package/app/components/site/SiteHeroCode.vue +0 -173
  159. package/app/components/site/SiteInteractionLayer.vue +0 -42
  160. package/app/components/site/SiteLocaleSwitcher.vue +0 -190
  161. package/app/components/site/SiteLogoMark.vue +0 -12
  162. package/app/components/site/SiteSkipLink.vue +0 -14
  163. package/app/components/site/SiteSocialLinks.vue +0 -33
  164. package/app/components/site/header-utils.ts +0 -3
  165. package/app/components/site/mode-toggle.utils.ts +0 -18
  166. package/app/components/ui/badge/Badge.vue +0 -28
  167. package/app/components/ui/badge/index.ts +0 -24
  168. package/app/components/ui/button/Button.vue +0 -31
  169. package/app/components/ui/button/index.ts +0 -35
  170. package/app/components/ui/collapsible/Collapsible.vue +0 -15
  171. package/app/components/ui/collapsible/CollapsibleContent.vue +0 -25
  172. package/app/components/ui/collapsible/CollapsibleTrigger.vue +0 -12
  173. package/app/components/ui/collapsible/index.ts +0 -3
  174. package/app/components/ui/dropdown-menu/DropdownMenu.vue +0 -15
  175. package/app/components/ui/dropdown-menu/DropdownMenuContent.vue +0 -50
  176. package/app/components/ui/dropdown-menu/DropdownMenuItem.vue +0 -41
  177. package/app/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +0 -15
  178. package/app/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +0 -37
  179. package/app/components/ui/dropdown-menu/DropdownMenuSeparator.vue +0 -23
  180. package/app/components/ui/dropdown-menu/DropdownMenuTrigger.vue +0 -14
  181. package/app/components/ui/dropdown-menu/index.ts +0 -7
  182. package/app/components/ui/kbd/Kbd.vue +0 -23
  183. package/app/components/ui/kbd/index.ts +0 -21
  184. package/app/components/ui/scroll-area/ScrollArea.vue +0 -39
  185. package/app/components/ui/scroll-area/ScrollBar.vue +0 -33
  186. package/app/components/ui/scroll-area/index.ts +0 -2
  187. package/app/components/ui/separator/Separator.vue +0 -27
  188. package/app/components/ui/separator/index.ts +0 -1
  189. package/app/components/ui/sheet/Sheet.vue +0 -15
  190. package/app/components/ui/sheet/SheetContent.vue +0 -59
  191. package/app/components/ui/sheet/SheetDescription.vue +0 -21
  192. package/app/components/ui/sheet/SheetOverlay.vue +0 -26
  193. package/app/components/ui/sheet/SheetTitle.vue +0 -21
  194. package/app/components/ui/sheet/SheetTrigger.vue +0 -12
  195. package/app/components/ui/sheet/index.ts +0 -5
  196. package/app/components/ui/tabs/Tabs.vue +0 -24
  197. package/app/components/ui/tabs/TabsList.vue +0 -26
  198. package/app/components/ui/tabs/TabsTrigger.vue +0 -28
  199. package/app/components/ui/tabs/index.ts +0 -3
  200. package/app/composables/site-navigation.utils.ts +0 -133
  201. package/app/composables/useCanonicalUrl.ts +0 -9
  202. package/app/composables/useContentRouteAlternates.ts +0 -35
  203. package/app/composables/useGinkoAnalytics.ts +0 -52
  204. package/app/composables/useGinkoDocsConfig.ts +0 -6
  205. package/app/composables/useGinkoOgImage.ts +0 -20
  206. package/app/composables/useLocalizedPath.ts +0 -12
  207. package/app/composables/useLocalizedRouteSwitch.ts +0 -31
  208. package/app/composables/useMetaKey.ts +0 -18
  209. package/app/composables/usePageMarkdownActions.ts +0 -79
  210. package/app/composables/useProseAppearance.ts +0 -24
  211. package/app/composables/useSchemaJsonLd.ts +0 -25
  212. package/app/composables/useSiteNavigation.ts +0 -64
  213. package/app/config/site.utils.ts +0 -36
  214. package/app/features/docs/components/DocsBreadcrumb.vue +0 -37
  215. package/app/features/docs/components/DocsContributeLinks.vue +0 -75
  216. package/app/features/docs/components/DocsMobileToc.vue +0 -108
  217. package/app/features/docs/components/DocsPageContent.vue +0 -234
  218. package/app/features/docs/components/DocsPageNav.vue +0 -57
  219. package/app/features/docs/components/DocsSidebar.vue +0 -145
  220. package/app/features/docs/components/DocsSidebarDropdown.vue +0 -70
  221. package/app/features/docs/components/DocsSidebarItem.vue +0 -122
  222. package/app/features/docs/components/DocsSidebarList.vue +0 -35
  223. package/app/features/docs/components/DocsSidebarRow.vue +0 -27
  224. package/app/features/docs/components/DocsSidebarTabs.vue +0 -59
  225. package/app/features/docs/components/DocsToc.vue +0 -106
  226. package/app/features/docs/composables/useDocsNavigation.ts +0 -29
  227. package/app/features/docs/composables/useDocsNavigationData.ts +0 -18
  228. package/app/features/docs/composables/useRevealActive.ts +0 -58
  229. package/app/features/docs/composables/useScrollspy.ts +0 -135
  230. package/app/features/docs/docs-navigation.ts +0 -157
  231. package/app/features/docs/toc-context.ts +0 -6
  232. package/app/features/search/command-center.ts +0 -110
  233. package/app/features/search/components/SiteCommandCenter.vue +0 -359
  234. package/app/features/search/components/SiteSearchPageHighlight.vue +0 -126
  235. package/app/features/search/useCommandCenter.ts +0 -292
  236. package/app/layouts/blog.vue +0 -15
  237. package/app/layouts/docs.vue +0 -20
  238. package/app/lib/errors.ts +0 -37
  239. package/app/lib/schema-org.ts +0 -38
  240. package/app/pages/blog/[slug].vue +0 -228
  241. package/app/pages/blog/index.vue +0 -130
  242. package/app/pages/docs/[...slug].vue +0 -10
  243. package/app/pages/docs/index.vue +0 -19
  244. package/app/pages/index.vue +0 -278
  245. package/app/plugins/ginko-docs-theme.ts +0 -14
  246. package/app/plugins/ssr-width.ts +0 -6
  247. package/app/utils/content.ts +0 -67
  248. package/app/utils/file-icons.ts +0 -90
  249. package/app/utils/index.ts +0 -7
  250. package/app/utils/repository.ts +0 -20
  251. package/components.ts +0 -9
  252. package/content-collections.ts +0 -89
  253. package/content.js +0 -200
  254. package/content.ts +0 -104
  255. package/i18n/i18n.config.ts +0 -10
  256. package/i18n/locales.ts +0 -81
  257. package/i18n/messages/global/banner.ts +0 -8
  258. package/i18n/messages/global/blog.ts +0 -18
  259. package/i18n/messages/global/command.ts +0 -49
  260. package/i18n/messages/global/docs.ts +0 -36
  261. package/i18n/messages/global/errors.ts +0 -36
  262. package/i18n/messages/global/feedback.ts +0 -11
  263. package/i18n/messages/global/index.ts +0 -21
  264. package/i18n/messages/global/nav.ts +0 -26
  265. package/i18n/messages/global/site.ts +0 -4
  266. package/i18n/messages/global/theme.ts +0 -9
  267. package/i18n/messages/index.ts +0 -20
  268. package/i18n/messages/localize.ts +0 -35
  269. package/i18n/routes.ts +0 -33
  270. package/icon-bundle.ts +0 -116
  271. package/index.d.ts +0 -37
  272. package/modules/analytics-boundary.ts +0 -23
  273. package/modules/feature-routing.ts +0 -68
  274. package/modules/syntax-highlighting.ts +0 -120
  275. package/public/fonts/public-sans/LICENSE +0 -93
  276. package/public/fonts/public-sans/README.md +0 -12
  277. package/public/fonts/public-sans/public-sans-400-normal-latin.woff +0 -0
  278. package/public/fonts/public-sans/public-sans-500-normal-latin.woff +0 -0
  279. package/public/fonts/public-sans/public-sans-600-normal-latin.woff +0 -0
  280. package/public/fonts/public-sans/public-sans-700-normal-latin.woff +0 -0
  281. package/runtime/generate-favicons.mjs +0 -124
  282. package/runtime/server/agent-markdown.ts +0 -19
  283. package/server/api/_ginko-docs/redirects.get.ts +0 -28
  284. package/server/mcp/tools/get-page.ts +0 -14
  285. package/server/mcp/tools/list-pages.ts +0 -10
  286. package/server/middleware/redirects.ts +0 -22
  287. package/server/plugins/agent-markdown.ts +0 -6
  288. package/server/plugins/sitemap-policy.ts +0 -12
  289. package/server/routes/.well-known/ai-catalog.json.get.ts +0 -10
  290. package/server/routes/[locale]/blog/rss.xml.get.ts +0 -13
  291. package/server/routes/blog/rss.xml.get.ts +0 -5
  292. package/server/routes/mcp/server-card.get.ts +0 -14
  293. package/server/utils/blog-feed.ts +0 -51
  294. package/server/utils/feed.ts +0 -70
  295. package/server/utils/mcp-server-card.ts +0 -45
  296. package/server/utils/redirects.ts +0 -38
  297. package/server/utils/redirects.utils.ts +0 -58
  298. package/server/utils/sitemap.ts +0 -45
  299. package/shared/route-slugs.ts +0 -5
  300. package/shared/theme-palettes.ts +0 -37
  301. package/shared/theme-presets.ts +0 -3
  302. package/shared/types/app-config.ts +0 -172
  303. package/shared/types/nuxt-config.ts +0 -14
  304. package/tags.ts +0 -192
@@ -1,89 +0,0 @@
1
- import { defineCollection, defineContentConfig, reference } from "@lupinum/ginko-content/config";
2
- import type { ContentAgentCollectionConfig } from "@lupinum/ginko-content/config";
3
- import { z } from "zod";
4
- import { routeSlugs } from "./shared/route-slugs";
5
-
6
- const isoDate = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Expected an ISO date (YYYY-MM-DD)");
7
- const nonEmptyString = z.string().trim().min(1);
8
- const redirectFrom = z
9
- .array(nonEmptyString.regex(/^\//, "redirectFrom entries must be absolute site paths"))
10
- .optional();
11
-
12
- const withSitemapLastmod = <T extends object>(data: T, lastmod: string | undefined) =>
13
- lastmod ? { ...data, sitemap: { lastmod: `${lastmod}T00:00:00.000Z` } } : data;
14
-
15
- const docsSchema = z.object({
16
- title: z.string(),
17
- description: z.string(),
18
- icon: z.string().optional(),
19
- badge: z.string().optional(),
20
- updated: isoDate.optional(),
21
- redirectFrom,
22
- sidebar: z.enum(["section", "group"]).optional(),
23
- navigation: z
24
- .object({
25
- title: z.string().optional(),
26
- icon: z.string().optional(),
27
- badge: z.string().optional(),
28
- sidebar: z.enum(["section", "group"]).optional(),
29
- })
30
- .optional(),
31
- });
32
- const docsSchemaWithLastmod = docsSchema.transform((data) =>
33
- withSitemapLastmod(data, data.updated),
34
- );
35
- const blogSchema = z.object({
36
- title: z.string(),
37
- description: z.string(),
38
- badge: z.string().optional(),
39
- date: isoDate,
40
- readingTime: nonEmptyString,
41
- author: reference("authors"),
42
- image: z.string().optional(),
43
- redirectFrom,
44
- });
45
- const blogSchemaWithLastmod = blogSchema.transform((data) => withSitemapLastmod(data, data.date));
46
- const authorsSchema = z.object({
47
- slug: z.string(),
48
- name: z.string(),
49
- role: z.string(),
50
- bio: z.string(),
51
- avatar: z.string(),
52
- links: z.array(z.object({ label: z.string(), href: z.string() })).optional(),
53
- });
54
-
55
- export function createGinkoDocsCollections(
56
- i18n: boolean,
57
- docsMarkdown: ContentAgentCollectionConfig["markdown"] = true,
58
- ) {
59
- return defineContentConfig({
60
- collections: {
61
- docs: defineCollection({
62
- type: "page",
63
- source: i18n ? "{1.docs,1.dokumentation}/**/*.md" : "docs/**/*.md",
64
- i18n: i18n ? true : undefined,
65
- route: i18n ? routeSlugs.docs : routeSlugs.docs.en,
66
- agent: { section: "optional", markdown: docsMarkdown },
67
- strict: true,
68
- schema: docsSchemaWithLastmod,
69
- }),
70
- blog: defineCollection({
71
- type: "page",
72
- source: "2.blog/*.md",
73
- i18n: i18n ? true : undefined,
74
- route: i18n ? routeSlugs.blog : routeSlugs.blog.en,
75
- agent: { section: "blog", markdown: true },
76
- strict: true,
77
- schema: blogSchemaWithLastmod,
78
- }),
79
- authors: defineCollection({
80
- type: "data",
81
- source: "authors/**/*.json",
82
- i18n: i18n ? true : undefined,
83
- strict: true,
84
- sitemap: false,
85
- schema: authorsSchema,
86
- }),
87
- },
88
- }).collections;
89
- }
package/content.js DELETED
@@ -1,200 +0,0 @@
1
- import {
2
- defineAgentMetadataFields,
3
- defineAgentSection,
4
- defineCollection,
5
- defineContentConfig,
6
- reference,
7
- } from "@lupinum/ginko-content/config";
8
- import { z } from "zod";
9
- //#region layer/shared/route-slugs.ts
10
- const routeSlugs = {
11
- home: {
12
- en: "/",
13
- de: "/",
14
- },
15
- docs: {
16
- en: "/docs",
17
- de: "/dokumentation",
18
- },
19
- blog: {
20
- en: "/blog",
21
- de: "/blog",
22
- },
23
- };
24
- //#endregion
25
- //#region layer/content-collections.ts
26
- const isoDate = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Expected an ISO date (YYYY-MM-DD)");
27
- const nonEmptyString = z.string().trim().min(1);
28
- const redirectFrom = z
29
- .array(nonEmptyString.regex(/^\//, "redirectFrom entries must be absolute site paths"))
30
- .optional();
31
- const withSitemapLastmod = (data, lastmod) =>
32
- lastmod
33
- ? {
34
- ...data,
35
- sitemap: { lastmod: `${lastmod}T00:00:00.000Z` },
36
- }
37
- : data;
38
- const docsSchemaWithLastmod = z
39
- .object({
40
- title: z.string(),
41
- description: z.string(),
42
- icon: z.string().optional(),
43
- badge: z.string().optional(),
44
- updated: isoDate.optional(),
45
- redirectFrom,
46
- sidebar: z.enum(["section", "group"]).optional(),
47
- navigation: z
48
- .object({
49
- title: z.string().optional(),
50
- icon: z.string().optional(),
51
- badge: z.string().optional(),
52
- sidebar: z.enum(["section", "group"]).optional(),
53
- })
54
- .optional(),
55
- })
56
- .transform((data) => withSitemapLastmod(data, data.updated));
57
- const blogSchemaWithLastmod = z
58
- .object({
59
- title: z.string(),
60
- description: z.string(),
61
- badge: z.string().optional(),
62
- date: isoDate,
63
- readingTime: nonEmptyString,
64
- author: reference("authors"),
65
- image: z.string().optional(),
66
- redirectFrom,
67
- })
68
- .transform((data) => withSitemapLastmod(data, data.date));
69
- const authorsSchema = z.object({
70
- slug: z.string(),
71
- name: z.string(),
72
- role: z.string(),
73
- bio: z.string(),
74
- avatar: z.string(),
75
- links: z
76
- .array(
77
- z.object({
78
- label: z.string(),
79
- href: z.string(),
80
- }),
81
- )
82
- .optional(),
83
- });
84
- function createGinkoDocsCollections(i18n, docsMarkdown = true) {
85
- return defineContentConfig({
86
- collections: {
87
- docs: defineCollection({
88
- type: "page",
89
- source: i18n ? "{1.docs,1.dokumentation}/**/*.md" : "docs/**/*.md",
90
- i18n: i18n ? true : void 0,
91
- route: i18n ? routeSlugs.docs : routeSlugs.docs.en,
92
- agent: {
93
- section: "optional",
94
- markdown: docsMarkdown,
95
- },
96
- strict: true,
97
- schema: docsSchemaWithLastmod,
98
- }),
99
- blog: defineCollection({
100
- type: "page",
101
- source: "2.blog/*.md",
102
- i18n: i18n ? true : void 0,
103
- route: i18n ? routeSlugs.blog : routeSlugs.blog.en,
104
- agent: {
105
- section: "blog",
106
- markdown: true,
107
- },
108
- strict: true,
109
- schema: blogSchemaWithLastmod,
110
- }),
111
- authors: defineCollection({
112
- type: "data",
113
- source: "authors/**/*.json",
114
- i18n: i18n ? true : void 0,
115
- strict: true,
116
- sitemap: false,
117
- schema: authorsSchema,
118
- }),
119
- },
120
- }).collections;
121
- }
122
- //#endregion
123
- //#region layer/content.ts
124
- function defineGinkoDocsConfig(options) {
125
- const locales = options.locales ?? ["en"];
126
- if (
127
- !(locales.length === 1
128
- ? locales[0] === "en"
129
- : locales.length === 2 && locales[0] === "en" && locales[1] === "de")
130
- )
131
- throw new TypeError('locales must be exactly ["en"] or ["en", "de"]');
132
- const i18n = locales.length === 2;
133
- const metadata = defineAgentMetadataFields([
134
- "title",
135
- "description",
136
- "url",
137
- "route",
138
- "locale",
139
- "section",
140
- "collection",
141
- "source",
142
- "updated",
143
- ]);
144
- const { docs, blog, authors } = createGinkoDocsCollections(i18n, options.agent?.documentation);
145
- const config = {
146
- agent: {
147
- site: {
148
- title: options.site.name,
149
- description: options.site.description,
150
- whenToUse: options.site.whenToUse,
151
- ...(options.site.whenNotToUse ? { whenNotToUse: options.site.whenNotToUse } : {}),
152
- },
153
- markdown: {
154
- metadata: {
155
- enabled: true,
156
- defaultFields: metadata,
157
- },
158
- },
159
- sections: [
160
- ...(options.agent?.sections ?? []),
161
- ...(options.blog
162
- ? [
163
- defineAgentSection({
164
- id: "blog",
165
- title: {
166
- en: "Blog",
167
- de: "Blog",
168
- },
169
- order: 40,
170
- }),
171
- ]
172
- : []),
173
- defineAgentSection({
174
- id: "optional",
175
- title: {
176
- en: "Documentation",
177
- de: "Dokumentation",
178
- },
179
- order: 100,
180
- }),
181
- ],
182
- ...(options.agent?.pages ? { pages: [...options.agent.pages] } : {}),
183
- },
184
- };
185
- if (options.blog)
186
- return defineContentConfig({
187
- ...config,
188
- collections: {
189
- docs,
190
- blog,
191
- authors,
192
- },
193
- });
194
- return defineContentConfig({
195
- ...config,
196
- collections: { docs },
197
- });
198
- }
199
- //#endregion
200
- export { defineGinkoDocsConfig };
package/content.ts DELETED
@@ -1,104 +0,0 @@
1
- import {
2
- defineAgentAppPage,
3
- defineAgentMetadataFields,
4
- defineAgentSection,
5
- defineContentConfig,
6
- } from "@lupinum/ginko-content/config";
7
- import type { ContentAgentMarkdownOptions, ContentConfig } from "@lupinum/ginko-content/config";
8
- import { createGinkoDocsCollections } from "./content-collections";
9
-
10
- type GinkoDocsAgentPage = Parameters<typeof defineAgentAppPage>[0];
11
- type GinkoDocsAgentSection = Parameters<typeof defineAgentSection>[0];
12
-
13
- export interface GinkoDocsAgentOptions {
14
- /** Control whether authored documentation appears in compact and full indexes. */
15
- documentation?: ContentAgentMarkdownOptions;
16
- /** Add compact index pages that point agents to canonical raw Markdown. */
17
- pages?: readonly GinkoDocsAgentPage[];
18
- /** Add sections before the built-in blog and optional documentation sections. */
19
- sections?: readonly GinkoDocsAgentSection[];
20
- }
21
-
22
- export interface GinkoDocsContentOptions {
23
- site: {
24
- name: string | { en: string; de: string };
25
- description: string | { en: string; de: string };
26
- whenToUse: string | { en: string; de: string };
27
- whenNotToUse?: string | { en: string; de: string };
28
- };
29
- agent?: GinkoDocsAgentOptions;
30
- locales?: readonly ["en"] | readonly ["en", "de"];
31
- blog?: boolean;
32
- }
33
-
34
- type Collections = ReturnType<typeof createGinkoDocsCollections>;
35
- type DocsCollection = Collections["docs"];
36
- type BlogCollection = Collections["blog"];
37
- type AuthorsCollection = Collections["authors"];
38
- type DocsContentConfig = ContentConfig<{ docs: DocsCollection }>;
39
- type DocsBlogContentConfig = ContentConfig<{
40
- docs: DocsCollection;
41
- blog: BlogCollection;
42
- authors: AuthorsCollection;
43
- }>;
44
-
45
- export function defineGinkoDocsConfig(
46
- options: GinkoDocsContentOptions & { blog: true },
47
- ): DocsBlogContentConfig;
48
- export function defineGinkoDocsConfig(options: GinkoDocsContentOptions): DocsContentConfig;
49
- export function defineGinkoDocsConfig(
50
- options: GinkoDocsContentOptions,
51
- ): DocsContentConfig | DocsBlogContentConfig {
52
- const locales = options.locales ?? ["en"];
53
- const validLocales =
54
- locales.length === 1
55
- ? locales[0] === "en"
56
- : locales.length === 2 && locales[0] === "en" && locales[1] === "de";
57
- if (!validLocales) {
58
- throw new TypeError('locales must be exactly ["en"] or ["en", "de"]');
59
- }
60
- const i18n = locales.length === 2;
61
- const metadata = defineAgentMetadataFields([
62
- "title",
63
- "description",
64
- "url",
65
- "route",
66
- "locale",
67
- "section",
68
- "collection",
69
- "source",
70
- "updated",
71
- ]);
72
- const { docs, blog, authors } = createGinkoDocsCollections(i18n, options.agent?.documentation);
73
- const config = {
74
- agent: {
75
- site: {
76
- title: options.site.name,
77
- description: options.site.description,
78
- whenToUse: options.site.whenToUse,
79
- ...(options.site.whenNotToUse ? { whenNotToUse: options.site.whenNotToUse } : {}),
80
- },
81
- markdown: { metadata: { enabled: true, defaultFields: metadata } },
82
- sections: [
83
- ...(options.agent?.sections ?? []),
84
- ...(options.blog
85
- ? [defineAgentSection({ id: "blog", title: { en: "Blog", de: "Blog" }, order: 40 })]
86
- : []),
87
- defineAgentSection({
88
- id: "optional",
89
- title: { en: "Documentation", de: "Dokumentation" },
90
- order: 100,
91
- }),
92
- ],
93
- ...(options.agent?.pages ? { pages: [...options.agent.pages] } : {}),
94
- },
95
- };
96
-
97
- if (options.blog) {
98
- return defineContentConfig({
99
- ...config,
100
- collections: { docs, blog, authors },
101
- }) as DocsBlogContentConfig;
102
- }
103
- return defineContentConfig({ ...config, collections: { docs } }) as DocsContentConfig;
104
- }
@@ -1,10 +0,0 @@
1
- import { defaultLocale } from "./locales";
2
- import { messages } from "./messages/index";
3
- import { defineI18nConfig } from "#imports";
4
-
5
- export default defineI18nConfig(() => ({
6
- legacy: false,
7
- locale: defaultLocale,
8
- fallbackLocale: defaultLocale,
9
- messages,
10
- }));
package/i18n/locales.ts DELETED
@@ -1,81 +0,0 @@
1
- export const defaultLocale = "en" as const;
2
-
3
- export const locales = [
4
- {
5
- code: "en",
6
- language: "en-US",
7
- name: "English",
8
- nativeName: "English",
9
- shortLabel: "EN",
10
- flagIcon: "circle-flags:us",
11
- },
12
- {
13
- code: "de",
14
- language: "de-DE",
15
- name: "Deutsch",
16
- nativeName: "Deutsch",
17
- shortLabel: "DE",
18
- flagIcon: "circle-flags:de",
19
- },
20
- ] as const;
21
-
22
- export type LocaleCode = (typeof locales)[number]["code"];
23
-
24
- export const localeCodes = locales.map((locale) => locale.code) as [LocaleCode, ...LocaleCode[]];
25
- export const nonDefaultLocaleCodes = localeCodes.filter((locale) => locale !== defaultLocale);
26
- export const localeIconNames = locales.map((locale) => locale.flagIcon);
27
-
28
- export function isLocaleCode(value: string): value is LocaleCode {
29
- return localeCodes.includes(value as LocaleCode);
30
- }
31
-
32
- export function isDefaultLocale(
33
- locale: LocaleCode,
34
- primaryLocale: LocaleCode = defaultLocale,
35
- ): boolean {
36
- return locale === primaryLocale;
37
- }
38
-
39
- export function localePrefix(
40
- locale: LocaleCode,
41
- primaryLocale: LocaleCode = defaultLocale,
42
- ): string {
43
- return isDefaultLocale(locale, primaryLocale) ? "" : `/${locale}`;
44
- }
45
-
46
- export function localizedPath(
47
- locale: LocaleCode,
48
- path: string,
49
- primaryLocale: LocaleCode = defaultLocale,
50
- ): string {
51
- const normalizedPath = path.startsWith("/") ? path : `/${path}`;
52
- const prefix = localePrefix(locale, primaryLocale);
53
-
54
- if (!prefix) return normalizedPath;
55
- if (normalizedPath === "/") return prefix;
56
- if (normalizedPath === prefix || normalizedPath.startsWith(`${prefix}/`)) return normalizedPath;
57
- return `${prefix}${normalizedPath}`;
58
- }
59
-
60
- export function localeFromPath(
61
- path: string,
62
- primaryLocale: LocaleCode = defaultLocale,
63
- supportedLocales: readonly LocaleCode[] = localeCodes,
64
- ): LocaleCode {
65
- const normalizedPath = path.replace(/\/{2,}/g, "/") || "/";
66
- const routeLocale = supportedLocales.find(
67
- (locale) => normalizedPath === `/${locale}` || normalizedPath.startsWith(`/${locale}/`),
68
- );
69
-
70
- return routeLocale ?? primaryLocale;
71
- }
72
-
73
- export function stripLocalePrefix(path: string, locale: LocaleCode): string {
74
- const normalizedPath = path.replace(/\/{2,}/g, "/") || "/";
75
- const prefix = `/${locale}`;
76
-
77
- if (isDefaultLocale(locale)) return normalizedPath;
78
- if (normalizedPath === prefix) return "/";
79
- if (normalizedPath.startsWith(`${prefix}/`)) return normalizedPath.slice(prefix.length) || "/";
80
- return normalizedPath;
81
- }
@@ -1,8 +0,0 @@
1
- export const banner = {
2
- text: {
3
- de: "Neu: die Ginko-Content-Dokumentationspipeline.",
4
- en: "Introducing the Ginko Content docs pipeline.",
5
- },
6
- linkLabel: { de: "Ankündigung lesen", en: "Read the announcement" },
7
- dismiss: { de: "Banner schließen", en: "Dismiss banner" },
8
- } as const;
@@ -1,18 +0,0 @@
1
- export const blog = {
2
- title: { de: "Blog", en: "Blog" },
3
- pageTitle: { de: "Blog", en: "Blog" },
4
- description: {
5
- de: "Neuigkeiten, Anleitungen und technische Einblicke.",
6
- en: "Updates, guides, and technical insights.",
7
- },
8
- fallbackTitle: { de: "Blog", en: "Blog" },
9
- fallbackDescription: { de: "Ein Dokumentationsartikel.", en: "A documentation article." },
10
- back: { de: "Zurück zum Blog", en: "Back to Blog" },
11
- toc: { de: "Im Artikel", en: "In this article" },
12
- readMore: { de: "Weiterlesen", en: "Read more" },
13
- moreArticles: { de: "Weitere Artikel", en: "More articles" },
14
- empty: {
15
- de: "Noch keine Artikel veröffentlicht.",
16
- en: "No articles have been published yet.",
17
- },
18
- } as const;
@@ -1,49 +0,0 @@
1
- export const command = {
2
- title: { de: "Command Center", en: "Command center" },
3
- description: {
4
- de: "Navigation, Dokumentation und Aktionen durchsuchen.",
5
- en: "Search navigation, documentation, and shortcuts.",
6
- },
7
- placeholder: { de: "Docs, Seiten, Aktionen suchen...", en: "Search docs, pages, actions..." },
8
- noResults: { de: 'Keine Ergebnisse für "{query}"', en: 'No results for "{query}"' },
9
- noResultsHelp: {
10
- de: "Suche nach einem Seitentitel, Docs-Bereich oder Stichwort.",
11
- en: "Try searching for a page title, doc section, or keyword.",
12
- },
13
- clear: { de: "Suche löschen", en: "Clear search" },
14
- navigate: { de: "Navigieren", en: "Navigate" },
15
- open: { de: "Öffnen", en: "Open" },
16
- close: { de: "Schließen", en: "Close" },
17
- closeHint: { de: "Esc schließen", en: "Esc closes" },
18
- groups: {
19
- recent: { de: "Zuletzt", en: "Recent" },
20
- pages: { de: "Navigation", en: "Navigation" },
21
- docs_nav: { de: "Docs-Navigation", en: "Docs Navigation" },
22
- search: { de: "Suchergebnisse", en: "Search results" },
23
- actions: { de: "Aktionen", en: "Actions" },
24
- },
25
- loading: { de: "Suche läuft …", en: "Searching…" },
26
- resultCount: { de: "{count} Treffer", en: "{count} results" },
27
- error: {
28
- de: "Die Suche ist gerade nicht verfügbar. Versuche es erneut.",
29
- en: "Search is temporarily unavailable. Please try again.",
30
- },
31
- pages: {
32
- home: {
33
- title: { de: "Start", en: "Home" },
34
- description: {
35
- de: "Landingpage und Produktüberblick",
36
- en: "Landing page and product overview",
37
- },
38
- },
39
- primary: { de: "Hauptnavigation", en: "Primary navigation" },
40
- secondary: { de: "Weitere Seite", en: "Secondary page" },
41
- documentation: { de: "Dokumentationsbereich", en: "Documentation section" },
42
- },
43
- actions: {
44
- github: {
45
- title: { de: "GitHub öffnen", en: "Open GitHub" },
46
- description: { de: "Zum Projekt-Repository springen", en: "Jump to the project repository" },
47
- },
48
- },
49
- } as const;
@@ -1,36 +0,0 @@
1
- export const docs = {
2
- label: { de: "Dokumentation", en: "Documentation" },
3
- fallbackTitle: { de: "Dokumentation", en: "Documentation" },
4
- fallbackDescription: { de: "Starter-Dokumentation.", en: "Starter documentation." },
5
- pageNavigation: { de: "Seitennavigation", en: "Page navigation" },
6
- breadcrumbs: { de: "Brotkrümelnavigation", en: "Breadcrumbs" },
7
- previous: { de: "Zurück", en: "Previous" },
8
- next: { de: "Weiter", en: "Next" },
9
- toc: { de: "Auf dieser Seite", en: "On this page" },
10
- mobileToc: { de: "Inhalt", en: "Docs" },
11
- copyMarkdown: { de: "Markdown kopieren", en: "Copy Markdown" },
12
- copyText: { de: "Text kopieren", en: "Copy text" },
13
- copied: { de: "Kopiert", en: "Copied" },
14
- copiedText: { de: "Text kopiert", en: "Copied text" },
15
- copyFailed: { de: "Kopieren fehlgeschlagen", en: "Copy failed" },
16
- codeSample: { de: "Codebeispiel", en: "Code sample" },
17
- showAllLines: { de: "Alle {count} Zeilen anzeigen", en: "Show all {count} lines" },
18
- showMore: { de: "Mehr anzeigen", en: "Show more" },
19
- zoomImage: { de: "Bild vergrößern", en: "Zoom image" },
20
- lastUpdated: { de: "Zuletzt aktualisiert", en: "Last updated" },
21
- moreActions: { de: "Weitere Seitenaktionen", en: "More page actions" },
22
- copyLink: { de: "Markdown-Link kopieren", en: "Copy Markdown link" },
23
- viewMarkdown: { de: "Als Markdown anzeigen", en: "View as Markdown" },
24
- askChatGpt: { de: "In ChatGPT öffnen", en: "Open in ChatGPT" },
25
- askClaude: { de: "In Claude öffnen", en: "Open in Claude" },
26
- copyMcpUrl: { de: "MCP-Server-URL kopieren", en: "Copy MCP server URL" },
27
- contribute: { de: "Zu dieser Seite beitragen", en: "Contribute to this page" },
28
- backToTop: { de: "Nach oben", en: "Back to top" },
29
- editPage: { de: "Diese Seite bearbeiten", en: "Edit this page" },
30
- reportIssue: { de: "Problem melden", en: "Report an issue" },
31
- issueTitle: { de: "Dokumentation: {title}", en: "Docs: {title}" },
32
- issueBody: {
33
- de: "Dokumentationsseite: {path}\n\nProblem beschreiben:",
34
- en: "Documentation page: {path}\n\nDescribe the issue:",
35
- },
36
- } as const;
@@ -1,36 +0,0 @@
1
- export const errors = {
2
- accessDenied: {
3
- title: { de: "Zugriff verweigert", en: "Access denied" },
4
- description: {
5
- de: "Diese Seite ist nicht fuer den oeffentlichen Zugriff freigegeben.",
6
- en: "This page is not available for public access.",
7
- },
8
- },
9
- actions: {
10
- contact: { de: "Kontakt aufnehmen", en: "Contact us" },
11
- docs: { de: "Dokumentation lesen", en: "Read the docs" },
12
- home: { de: "Zur Startseite", en: "Go home" },
13
- retry: { de: "Erneut versuchen", en: "Try again" },
14
- },
15
- notFound: {
16
- title: { de: "Seite nicht gefunden", en: "Page not found" },
17
- description: {
18
- de: "Die angeforderte Seite existiert nicht oder wurde verschoben.",
19
- en: "The requested page does not exist or has moved.",
20
- },
21
- },
22
- server: {
23
- title: { de: "Etwas ist schiefgelaufen", en: "Something went wrong" },
24
- description: {
25
- de: "Die Seite konnte gerade nicht geladen werden. Bitte versuche es spaeter erneut oder kontaktiere uns.",
26
- en: "The page could not be loaded right now. Please try again later or contact us.",
27
- },
28
- },
29
- unavailable: {
30
- title: { de: "Seite nicht verfuegbar", en: "Page unavailable" },
31
- description: {
32
- de: "Diese Anfrage konnte gerade nicht verarbeitet werden.",
33
- en: "This request could not be processed right now.",
34
- },
35
- },
36
- } as const;
@@ -1,11 +0,0 @@
1
- export const feedback = {
2
- label: { de: "War diese Seite hilfreich?", en: "Was this page helpful?" },
3
- articleLabel: { de: "War dieser Artikel hilfreich?", en: "Was this article helpful?" },
4
- yes: { de: "Ja", en: "Yes" },
5
- no: { de: "Nein", en: "No" },
6
- thanks: { de: "Danke für dein Feedback.", en: "Thanks for your feedback." },
7
- issueTitle: {
8
- de: "Feedback: {path}",
9
- en: "Feedback: {path}",
10
- },
11
- } as const;
@@ -1,21 +0,0 @@
1
- import { site } from "./site";
2
- import { banner } from "./banner";
3
- import { nav } from "./nav";
4
- import { docs } from "./docs";
5
- import { blog } from "./blog";
6
- import { theme } from "./theme";
7
- import { command } from "./command";
8
- import { feedback } from "./feedback";
9
- import { errors } from "./errors";
10
-
11
- export const globalMessages = {
12
- site,
13
- banner,
14
- nav,
15
- docs,
16
- blog,
17
- theme,
18
- command,
19
- feedback,
20
- errors,
21
- } as const;