@wrikka/create-docs 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 (380) hide show
  1. package/README.md +137 -0
  2. package/bin/cli.js +408 -0
  3. package/dist/index.cjs +20 -0
  4. package/dist/index.d.cts +475 -0
  5. package/dist/index.d.ts +475 -0
  6. package/dist/index.js +20 -0
  7. package/docs/_dir.yml +2 -0
  8. package/docs/config.md +75 -0
  9. package/docs/data-sources.md +88 -0
  10. package/docs/deploy.md +38 -0
  11. package/docs/features.md +51 -0
  12. package/docs/getting-started.md +42 -0
  13. package/docs/index.md +34 -0
  14. package/docs/markdown.md +154 -0
  15. package/docs/theming.md +53 -0
  16. package/package.json +142 -0
  17. package/scripts/generate-docs-index.ts +111 -0
  18. package/scripts/github-pull.ts +124 -0
  19. package/src/adapters/config/index.ts +1 -0
  20. package/src/adapters/config/node-config-loader.ts +36 -0
  21. package/src/adapters/fs/fs-docs-loader.ts +31 -0
  22. package/src/adapters/fs/index.ts +12 -0
  23. package/src/adapters/fs/memory-fs.ts +60 -0
  24. package/src/adapters/fs/node-fs.ts +116 -0
  25. package/src/adapters/git/index.ts +164 -0
  26. package/src/adapters/github/github-pull.ts +340 -0
  27. package/src/adapters/index.ts +6 -0
  28. package/src/adapters/velite.ts +112 -0
  29. package/src/adapters/vite/docs-watcher.ts +36 -0
  30. package/src/adapters/vite/index.ts +2 -0
  31. package/src/adapters/vite/polling-watcher.ts +89 -0
  32. package/src/code-block-enhancements/index.ts +3 -0
  33. package/src/config/index.ts +15 -0
  34. package/src/content/index.ts +11 -0
  35. package/src/content-validation/index.ts +5 -0
  36. package/src/index.ts +174 -0
  37. package/src/live-editor/index.ts +7 -0
  38. package/src/modules/analytics/application/plausible-adapter.ts +103 -0
  39. package/src/modules/analytics/application/umami-adapter.ts +109 -0
  40. package/src/modules/analytics/domain/events/index.ts +37 -0
  41. package/src/modules/analytics/domain/models/index.ts +35 -0
  42. package/src/modules/analytics/domain/operations/analytics-operations.ts +67 -0
  43. package/src/modules/analytics/domain/validators/index.ts +50 -0
  44. package/src/modules/analytics/index.ts +9 -0
  45. package/src/modules/analytics/ports/analytics-port.ts +17 -0
  46. package/src/modules/analytics/types/analytics.ts +16 -0
  47. package/src/modules/api-docs/application/type-docs-adapter.ts +34 -0
  48. package/src/modules/api-docs/domain/events/index.ts +42 -0
  49. package/src/modules/api-docs/domain/models/index.ts +40 -0
  50. package/src/modules/api-docs/domain/operations/api-docs-operations.ts +59 -0
  51. package/src/modules/api-docs/domain/validators/index.ts +56 -0
  52. package/src/modules/api-docs/index.ts +8 -0
  53. package/src/modules/api-docs/ports/api-docs-port.ts +21 -0
  54. package/src/modules/api-docs/types/api-docs.ts +15 -0
  55. package/src/modules/api-reference/openapi.ts +166 -0
  56. package/src/modules/api-reference/orpc.ts +94 -0
  57. package/src/modules/code-block-enhancements/application/usecases/index.ts +39 -0
  58. package/src/modules/code-block-enhancements/domain/code-operations.ts +72 -0
  59. package/src/modules/code-block-enhancements/domain/events/index.ts +58 -0
  60. package/src/modules/code-block-enhancements/domain/index.ts +11 -0
  61. package/src/modules/code-block-enhancements/domain/models/index.ts +36 -0
  62. package/src/modules/code-block-enhancements/domain/validators/index.ts +50 -0
  63. package/src/modules/code-block-enhancements/index.ts +10 -0
  64. package/src/modules/code-block-enhancements/ports/index.ts +18 -0
  65. package/src/modules/code-block-enhancements/types/index.ts +37 -0
  66. package/src/modules/code-execution/application/sandbox-adapter.ts +44 -0
  67. package/src/modules/code-execution/domain/events/index.ts +58 -0
  68. package/src/modules/code-execution/domain/models/index.ts +33 -0
  69. package/src/modules/code-execution/domain/operations/execution-operations.ts +60 -0
  70. package/src/modules/code-execution/domain/validators/index.ts +50 -0
  71. package/src/modules/code-execution/index.ts +8 -0
  72. package/src/modules/code-execution/ports/execution-port.ts +15 -0
  73. package/src/modules/code-execution/types/execution.ts +15 -0
  74. package/src/modules/comments/application/giscus-adapter.ts +55 -0
  75. package/src/modules/comments/domain/events/index.ts +55 -0
  76. package/src/modules/comments/domain/models/index.ts +30 -0
  77. package/src/modules/comments/domain/operations/comment-operations.ts +46 -0
  78. package/src/modules/comments/domain/validators/index.ts +50 -0
  79. package/src/modules/comments/index.ts +8 -0
  80. package/src/modules/comments/ports/comment-port.ts +18 -0
  81. package/src/modules/comments/types/comments.ts +19 -0
  82. package/src/modules/config/application/usecases/index.ts +1 -0
  83. package/src/modules/config/application/usecases/loadConfig.ts +38 -0
  84. package/src/modules/config/application/workflows/index.ts +1 -0
  85. package/src/modules/config/application/workflows/validateConfig.ts +14 -0
  86. package/src/modules/config/domain/events/index.ts +50 -0
  87. package/src/modules/config/domain/models/index.ts +9 -0
  88. package/src/modules/config/domain/operations/defaults.ts +74 -0
  89. package/src/modules/config/domain/operations/index.ts +2 -0
  90. package/src/modules/config/domain/operations/resolve.ts +40 -0
  91. package/src/modules/config/domain/validators/index.ts +152 -0
  92. package/src/modules/config/index.ts +23 -0
  93. package/src/modules/config/ports/index.ts +15 -0
  94. package/src/modules/config/types/index.ts +113 -0
  95. package/src/modules/config/types/public.ts +19 -0
  96. package/src/modules/content/application/cache/index.ts +6 -0
  97. package/src/modules/content/application/cache/parse-cache.ts +6 -0
  98. package/src/modules/content/application/cache/parseCache.ts +56 -0
  99. package/src/modules/content/application/usecases/index.ts +2 -0
  100. package/src/modules/content/application/usecases/load-doc-page.ts +1 -0
  101. package/src/modules/content/application/usecases/loadDocPage.ts +111 -0
  102. package/src/modules/content/application/usecases/scanDocsDir.ts +105 -0
  103. package/src/modules/content/application/workflows/index.ts +1 -0
  104. package/src/modules/content/application/workflows/processDocs.ts +51 -0
  105. package/src/modules/content/domain/events/index.ts +61 -0
  106. package/src/modules/content/domain/models/index.ts +13 -0
  107. package/src/modules/content/domain/operations/build-page.ts +146 -0
  108. package/src/modules/content/domain/operations/buildPage.ts +93 -0
  109. package/src/modules/content/domain/operations/index.ts +17 -0
  110. package/src/modules/content/domain/operations/parse.ts +241 -0
  111. package/src/modules/content/domain/validators/frontmatter.ts +82 -0
  112. package/src/modules/content/domain/validators/index.ts +6 -0
  113. package/src/modules/content/index.ts +27 -0
  114. package/src/modules/content/ports/index.ts +45 -0
  115. package/src/modules/content/ports/velite.ts +134 -0
  116. package/src/modules/content/types/index.ts +76 -0
  117. package/src/modules/content/types/public.ts +1 -0
  118. package/src/modules/content-linting/application/builtin-linting-adapter.ts +82 -0
  119. package/src/modules/content-linting/domain/events/index.ts +58 -0
  120. package/src/modules/content-linting/domain/models/index.ts +46 -0
  121. package/src/modules/content-linting/domain/operations/linting-operations.ts +82 -0
  122. package/src/modules/content-linting/domain/validators/index.ts +50 -0
  123. package/src/modules/content-linting/index.ts +8 -0
  124. package/src/modules/content-linting/ports/linting-port.ts +21 -0
  125. package/src/modules/content-linting/types/linting.ts +18 -0
  126. package/src/modules/content-validation/application/usecases/index.ts +18 -0
  127. package/src/modules/content-validation/domain/events/index.ts +7 -0
  128. package/src/modules/content-validation/domain/index.ts +16 -0
  129. package/src/modules/content-validation/domain/models/index.ts +33 -0
  130. package/src/modules/content-validation/domain/operations/index.ts +157 -0
  131. package/src/modules/content-validation/domain/types/index.ts +17 -0
  132. package/src/modules/content-validation/domain/validators/index.ts +8 -0
  133. package/src/modules/content-validation/index.ts +9 -0
  134. package/src/modules/content-validation/ports/index.ts +15 -0
  135. package/src/modules/content-validation/types/index.ts +5 -0
  136. package/src/modules/export/application/puppeteer-export-adapter.ts +63 -0
  137. package/src/modules/export/domain/events/index.ts +55 -0
  138. package/src/modules/export/domain/models/index.ts +38 -0
  139. package/src/modules/export/domain/operations/export-operations.ts +56 -0
  140. package/src/modules/export/domain/validators/index.ts +52 -0
  141. package/src/modules/export/index.ts +8 -0
  142. package/src/modules/export/ports/export-port.ts +15 -0
  143. package/src/modules/export/types/export.ts +15 -0
  144. package/src/modules/external-search/application/algolia-adapter.ts +182 -0
  145. package/src/modules/external-search/application/meilisearch-adapter.ts +161 -0
  146. package/src/modules/external-search/domain/events/index.ts +42 -0
  147. package/src/modules/external-search/domain/models/index.ts +42 -0
  148. package/src/modules/external-search/domain/operations/search-operations.ts +53 -0
  149. package/src/modules/external-search/domain/validators/index.ts +55 -0
  150. package/src/modules/external-search/index.ts +9 -0
  151. package/src/modules/external-search/ports/external-search-port.ts +23 -0
  152. package/src/modules/external-search/types/search.ts +19 -0
  153. package/src/modules/git-history/application/simple-git-adapter.ts +46 -0
  154. package/src/modules/git-history/domain/events/index.ts +34 -0
  155. package/src/modules/git-history/domain/models/index.ts +25 -0
  156. package/src/modules/git-history/domain/operations/git-history-operations.ts +56 -0
  157. package/src/modules/git-history/domain/validators/index.ts +52 -0
  158. package/src/modules/git-history/index.ts +8 -0
  159. package/src/modules/git-history/ports/git-history-port.ts +21 -0
  160. package/src/modules/git-history/types/git-history.ts +15 -0
  161. package/src/modules/i18n/application/fs-locale-loader.ts +39 -0
  162. package/src/modules/i18n/domain/events/index.ts +34 -0
  163. package/src/modules/i18n/domain/models/index.ts +34 -0
  164. package/src/modules/i18n/domain/operations/locale-operations.ts +74 -0
  165. package/src/modules/i18n/domain/validators/index.ts +52 -0
  166. package/src/modules/i18n/index.ts +8 -0
  167. package/src/modules/i18n/ports/locale-loader-port.ts +18 -0
  168. package/src/modules/i18n/types/locale.ts +17 -0
  169. package/src/modules/image-optimization/application/sharp-adapter.ts +58 -0
  170. package/src/modules/image-optimization/domain/events/index.ts +39 -0
  171. package/src/modules/image-optimization/domain/models/index.ts +27 -0
  172. package/src/modules/image-optimization/domain/operations/image-operations.ts +65 -0
  173. package/src/modules/image-optimization/domain/validators/index.ts +52 -0
  174. package/src/modules/image-optimization/index.ts +8 -0
  175. package/src/modules/image-optimization/ports/image-optimizer-port.ts +15 -0
  176. package/src/modules/image-optimization/types/image.ts +17 -0
  177. package/src/modules/live-editor/application/usecases/index.ts +60 -0
  178. package/src/modules/live-editor/domain/events/index.ts +37 -0
  179. package/src/modules/live-editor/domain/gitOperations.ts +110 -0
  180. package/src/modules/live-editor/domain/index.ts +15 -0
  181. package/src/modules/live-editor/domain/models/index.ts +21 -0
  182. package/src/modules/live-editor/domain/validators/index.ts +55 -0
  183. package/src/modules/live-editor/index.ts +14 -0
  184. package/src/modules/live-editor/ports/index.ts +49 -0
  185. package/src/modules/live-editor/types/index.ts +80 -0
  186. package/src/modules/live-preview/application/vite-preview-adapter.ts +20 -0
  187. package/src/modules/live-preview/domain/operations/preview-operations.ts +56 -0
  188. package/src/modules/live-preview/index.ts +8 -0
  189. package/src/modules/live-preview/ports/preview-port.ts +20 -0
  190. package/src/modules/live-preview/types/preview.ts +16 -0
  191. package/src/modules/mdx/application/mdx-js-adapter.ts +38 -0
  192. package/src/modules/mdx/domain/operations/parse-mdx.ts +43 -0
  193. package/src/modules/mdx/index.ts +8 -0
  194. package/src/modules/mdx/ports/mdx-parser-port.ts +15 -0
  195. package/src/modules/mdx/types/mdx.ts +14 -0
  196. package/src/modules/navigation/application/usecases/buildNav.ts +15 -0
  197. package/src/modules/navigation/application/usecases/buildSidebar.ts +45 -0
  198. package/src/modules/navigation/application/usecases/index.ts +2 -0
  199. package/src/modules/navigation/domain/events/index.ts +30 -0
  200. package/src/modules/navigation/domain/models/index.ts +7 -0
  201. package/src/modules/navigation/domain/operations/group.ts +79 -0
  202. package/src/modules/navigation/domain/operations/index.ts +10 -0
  203. package/src/modules/navigation/domain/operations/sort.ts +27 -0
  204. package/src/modules/navigation/domain/shared/utils/array.ts +39 -0
  205. package/src/modules/navigation/domain/validators/index.ts +88 -0
  206. package/src/modules/navigation/index.ts +15 -0
  207. package/src/modules/navigation/ports/index.ts +9 -0
  208. package/src/modules/navigation/types/index.ts +38 -0
  209. package/src/modules/navigation/types/public.ts +9 -0
  210. package/src/modules/openapi/application/swagger-parser-adapter.ts +178 -0
  211. package/src/modules/openapi/domain/operations/parse-openapi.ts +46 -0
  212. package/src/modules/openapi/index.ts +8 -0
  213. package/src/modules/openapi/ports/openapi-parser-port.ts +15 -0
  214. package/src/modules/openapi/types/openapi.ts +37 -0
  215. package/src/modules/plugin/application/usecases/build-virtual-modules.ts +53 -0
  216. package/src/modules/plugin/application/usecases/index.ts +1 -0
  217. package/src/modules/plugin/application/workflows/build-docs.ts +79 -0
  218. package/src/modules/plugin/application/workflows/index.ts +1 -0
  219. package/src/modules/plugin/domain/events/index.ts +62 -0
  220. package/src/modules/plugin/domain/models/index.ts +1 -0
  221. package/src/modules/plugin/domain/operations/build-virtual.ts +76 -0
  222. package/src/modules/plugin/domain/operations/index.ts +11 -0
  223. package/src/modules/plugin/domain/validators/index.ts +30 -0
  224. package/src/modules/plugin/index.ts +14 -0
  225. package/src/modules/plugin/ports/index.ts +21 -0
  226. package/src/modules/plugin/types/index.ts +27 -0
  227. package/src/modules/plugin/types/public.ts +1 -0
  228. package/src/modules/search/application/usecases/index.ts +1 -0
  229. package/src/modules/search/application/usecases/indexPages.ts +15 -0
  230. package/src/modules/search/domain/events/index.ts +32 -0
  231. package/src/modules/search/domain/models/index.ts +1 -0
  232. package/src/modules/search/domain/operations/build-index.ts +6 -0
  233. package/src/modules/search/domain/operations/buildIndex.ts +70 -0
  234. package/src/modules/search/domain/operations/index.ts +7 -0
  235. package/src/modules/search/domain/operations/query.ts +186 -0
  236. package/src/modules/search/domain/validators/index.ts +32 -0
  237. package/src/modules/search/index.ts +9 -0
  238. package/src/modules/search/types/index.ts +22 -0
  239. package/src/modules/search/types/public.ts +1 -0
  240. package/src/modules/search-analytics/application/local-storage-adapter.ts +68 -0
  241. package/src/modules/search-analytics/domain/operations/search-analytics-operations.ts +74 -0
  242. package/src/modules/search-analytics/index.ts +8 -0
  243. package/src/modules/search-analytics/ports/search-analytics-port.ts +20 -0
  244. package/src/modules/search-analytics/types/search-analytics.ts +16 -0
  245. package/src/modules/search-highlighting/application/dom-highlighting-adapter.ts +36 -0
  246. package/src/modules/search-highlighting/domain/operations/highlighting-operations.ts +72 -0
  247. package/src/modules/search-highlighting/index.ts +8 -0
  248. package/src/modules/search-highlighting/ports/highlighting-port.ts +14 -0
  249. package/src/modules/search-highlighting/types/highlighting.ts +15 -0
  250. package/src/modules/seo-optimization/application/usecases/index.ts +18 -0
  251. package/src/modules/seo-optimization/domain/index.ts +12 -0
  252. package/src/modules/seo-optimization/domain/seoOperations.ts +92 -0
  253. package/src/modules/seo-optimization/index.ts +8 -0
  254. package/src/modules/seo-optimization/ports/index.ts +18 -0
  255. package/src/modules/seo-optimization/types/index.ts +41 -0
  256. package/src/modules/theme/application/css-theme-adapter.ts +50 -0
  257. package/src/modules/theme/domain/operations/theme-operations.ts +68 -0
  258. package/src/modules/theme/index.ts +8 -0
  259. package/src/modules/theme/ports/theme-port.ts +8 -0
  260. package/src/modules/theme/types/theme.ts +12 -0
  261. package/src/modules/toc/application/markdown-toc-adapter.ts +106 -0
  262. package/src/modules/toc/domain/operations/toc-operations.ts +92 -0
  263. package/src/modules/toc/index.ts +8 -0
  264. package/src/modules/toc/ports/toc-port.ts +21 -0
  265. package/src/modules/toc/types/toc.ts +17 -0
  266. package/src/modules/toc-generator/application/usecases/index.ts +30 -0
  267. package/src/modules/toc-generator/domain/index.ts +12 -0
  268. package/src/modules/toc-generator/domain/tocOperations.ts +104 -0
  269. package/src/modules/toc-generator/index.ts +9 -0
  270. package/src/modules/toc-generator/ports/index.ts +20 -0
  271. package/src/modules/toc-generator/types/index.ts +50 -0
  272. package/src/modules/version-control/domain/events/index.ts +39 -0
  273. package/src/modules/version-control/domain/models/index.ts +25 -0
  274. package/src/modules/version-control/domain/validators/index.ts +50 -0
  275. package/src/modules/versioning/application/fs-version-loader.ts +44 -0
  276. package/src/modules/versioning/domain/operations/versioning-operations.ts +80 -0
  277. package/src/modules/versioning/index.ts +8 -0
  278. package/src/modules/versioning/ports/version-loader-port.ts +18 -0
  279. package/src/modules/versioning/types/versioning.ts +17 -0
  280. package/src/modules/workflow/domain/events/index.ts +55 -0
  281. package/src/modules/workflow/domain/models/index.ts +40 -0
  282. package/src/modules/workflow/domain/validators/index.ts +50 -0
  283. package/src/modules/yaml-parser/application/js-yaml-adapter.ts +34 -0
  284. package/src/modules/yaml-parser/domain/operations/parse-yaml.ts +58 -0
  285. package/src/modules/yaml-parser/index.ts +7 -0
  286. package/src/modules/yaml-parser/ports/yaml-parser-port.ts +18 -0
  287. package/src/navigation/index.ts +9 -0
  288. package/src/plugin/index.ts +4 -0
  289. package/src/presentation/index.ts +1 -0
  290. package/src/presentation/live-editor/index.ts +22 -0
  291. package/src/presentation/live-editor/live-editor-component.ts +219 -0
  292. package/src/presentation/live-editor/virtual-module.ts +16 -0
  293. package/src/presentation/solid/CodeBlock.tsx +120 -0
  294. package/src/presentation/solid/Toc.tsx +58 -0
  295. package/src/presentation/solid/index.ts +11 -0
  296. package/src/presentation/vite-plugin/docs-plugin.ts +212 -0
  297. package/src/presentation/vite-plugin/index.ts +9 -0
  298. package/src/presentation/vite-plugin/transform-markdown.ts +26 -0
  299. package/src/runtime/analytics.ts +59 -0
  300. package/src/runtime/api-diff.ts +115 -0
  301. package/src/runtime/app.tsx +32 -0
  302. package/src/runtime/components/AccentPicker.tsx +114 -0
  303. package/src/runtime/components/ApiPlayground.tsx +332 -0
  304. package/src/runtime/components/AskAiDialog.tsx +127 -0
  305. package/src/runtime/components/BackToTop.tsx +38 -0
  306. package/src/runtime/components/Banner.tsx +75 -0
  307. package/src/runtime/components/Breadcrumbs.tsx +42 -0
  308. package/src/runtime/components/CollectionDropdown.tsx +85 -0
  309. package/src/runtime/components/CustomizeDrawer.tsx +195 -0
  310. package/src/runtime/components/DocMarkdown.tsx +579 -0
  311. package/src/runtime/components/DocPrevNext.tsx +54 -0
  312. package/src/runtime/components/DocToc.tsx +147 -0
  313. package/src/runtime/components/DocsDropdown.tsx +184 -0
  314. package/src/runtime/components/Footer.tsx +52 -0
  315. package/src/runtime/components/GitHubAuth.tsx +82 -0
  316. package/src/runtime/components/GitHubStats.tsx +73 -0
  317. package/src/runtime/components/Head.tsx +225 -0
  318. package/src/runtime/components/LocaleDropdown.tsx +75 -0
  319. package/src/runtime/components/MobileBottomNav.tsx +111 -0
  320. package/src/runtime/components/NotFound.tsx +139 -0
  321. package/src/runtime/components/PageActions.tsx +144 -0
  322. package/src/runtime/components/RelatedDocs.tsx +50 -0
  323. package/src/runtime/components/ScrollProgress.tsx +32 -0
  324. package/src/runtime/components/SearchPalette.tsx +333 -0
  325. package/src/runtime/components/ShowcaseCard.tsx +87 -0
  326. package/src/runtime/components/SidebarNav.tsx +237 -0
  327. package/src/runtime/components/Skeleton.tsx +39 -0
  328. package/src/runtime/components/ThemeToggle.tsx +26 -0
  329. package/src/runtime/components/TopNav.tsx +270 -0
  330. package/src/runtime/components/VersionDropdown.tsx +189 -0
  331. package/src/runtime/components/markdown/components.ts +280 -0
  332. package/src/runtime/config.ts +225 -0
  333. package/src/runtime/content.ts +451 -0
  334. package/src/runtime/context.tsx +30 -0
  335. package/src/runtime/data.ts +93 -0
  336. package/src/runtime/github.ts +226 -0
  337. package/src/runtime/icons.ts +32 -0
  338. package/src/runtime/index.ts +153 -0
  339. package/src/runtime/layouts/DocsLayout.tsx +144 -0
  340. package/src/runtime/markdown-content.css +996 -0
  341. package/src/runtime/pages/AbTestPage.tsx +88 -0
  342. package/src/runtime/pages/AnalyticsPage.tsx +90 -0
  343. package/src/runtime/pages/ApiDiffPage.tsx +86 -0
  344. package/src/runtime/pages/ApiEndpointPage.tsx +248 -0
  345. package/src/runtime/pages/BuilderPage.tsx +150 -0
  346. package/src/runtime/pages/ChangelogPage.tsx +210 -0
  347. package/src/runtime/pages/CollectionPage.tsx +140 -0
  348. package/src/runtime/pages/CommunityPage.tsx +384 -0
  349. package/src/runtime/pages/CreatePage.tsx +448 -0
  350. package/src/runtime/pages/DocPage.tsx +193 -0
  351. package/src/runtime/pages/EditPage.tsx +201 -0
  352. package/src/runtime/pages/HomePage.tsx +187 -0
  353. package/src/runtime/pages/IssuesPage.tsx +140 -0
  354. package/src/runtime/pages/OAuthCallbackPage.tsx +80 -0
  355. package/src/runtime/pages/PluginsPage.tsx +249 -0
  356. package/src/runtime/pages/ShowcasePage.tsx +202 -0
  357. package/src/runtime/pwa.ts +39 -0
  358. package/src/runtime/router.tsx +192 -0
  359. package/src/runtime/seo.ts +192 -0
  360. package/src/runtime/theme.css +175 -0
  361. package/src/runtime/theme.ts +224 -0
  362. package/src/runtime/types.ts +217 -0
  363. package/src/search/index.ts +6 -0
  364. package/src/seo-optimization/index.ts +4 -0
  365. package/src/shared/constants/index.ts +26 -0
  366. package/src/shared/errors/index.ts +195 -0
  367. package/src/shared/index.ts +27 -0
  368. package/src/shared/types/brand.ts +14 -0
  369. package/src/shared/types/client.d.ts +45 -0
  370. package/src/shared/types/either.ts +38 -0
  371. package/src/shared/types/index.ts +42 -0
  372. package/src/shared/types/option.ts +52 -0
  373. package/src/shared/types/result.ts +81 -0
  374. package/src/shared/utils/array.ts +97 -0
  375. package/src/shared/utils/index.ts +46 -0
  376. package/src/shared/utils/object.ts +47 -0
  377. package/src/shared/utils/string.ts +74 -0
  378. package/src/toc-generator/index.ts +1 -0
  379. package/src/types/js-yaml.d.ts +42 -0
  380. package/src/worker.ts +462 -0
@@ -0,0 +1,451 @@
1
+ import { type Type, type } from "arktype";
2
+ import { load as loadYaml } from "js-yaml";
3
+ import MiniSearch from "minisearch";
4
+ import type {
5
+ CollectionMeta,
6
+ DocContent,
7
+ DocEntry,
8
+ DocFrontmatter,
9
+ DocQuery,
10
+ DocsDataSource,
11
+ SearchResult,
12
+ } from "./types";
13
+
14
+ const FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
15
+
16
+ /** Parse YAML frontmatter from raw markdown. Returns `{}` when absent. */
17
+ export function parseFrontmatter(raw: string): {
18
+ data: DocFrontmatter;
19
+ content: string;
20
+ } {
21
+ const m = raw.match(FRONTMATTER_RE);
22
+ if (!m) return { data: {}, content: raw };
23
+ let data: DocFrontmatter = {};
24
+ try {
25
+ const parsed = loadYaml(m[1] ?? "");
26
+ if (parsed && typeof parsed === "object") data = parsed as DocFrontmatter;
27
+ } catch {
28
+ // Malformed frontmatter — render the body anyway.
29
+ }
30
+ return { data, content: raw.slice(m[0].length) };
31
+ }
32
+
33
+ function isVisible(fm: DocFrontmatter, now: Date, includeDrafts: boolean) {
34
+ if (includeDrafts) return true;
35
+ if (fm.draft === true) return false;
36
+ if (fm.publishedAt) {
37
+ const t = Date.parse(fm.publishedAt);
38
+ if (!Number.isNaN(t) && t > now.getTime()) return false;
39
+ }
40
+ return true;
41
+ }
42
+
43
+ function stripMarkdown(md: string): string {
44
+ return md
45
+ .replace(/```[\s\S]*?```/g, " ")
46
+ .replace(/`[^`]*`/g, " ")
47
+ .replace(/!\[[^\]]*\]\([^)]*\)/g, " ")
48
+ .replace(/\[([^\]]*)\]\([^)]*\)/g, "$1")
49
+ .replace(/^#{1,6}\s+/gm, "")
50
+ .replace(/[*_~|>-]/g, " ")
51
+ .replace(/\s+/g, " ")
52
+ .trim();
53
+ }
54
+
55
+ function docIdFromPath(path: string): string {
56
+ return path
57
+ .replace(/^\.{0,2}\//, "")
58
+ .replace(/\.(md|mdx)$/i, "")
59
+ .replace(/[/\\]/g, "--");
60
+ }
61
+
62
+ /** Per-directory sidebar config from `_dir.yml` / `_dir.yaml`. */
63
+ export interface DirMeta {
64
+ title?: string;
65
+ icon?: string;
66
+ order?: number;
67
+ collapsed?: boolean;
68
+ }
69
+
70
+ interface LoadedDoc {
71
+ entry: DocEntry;
72
+ frontmatter: DocFrontmatter;
73
+ content: string;
74
+ dirKey: string;
75
+ }
76
+
77
+ /** Pure filter+sort — also usable by other data sources. */
78
+ export function queryDocs(entries: DocEntry[], q: DocQuery): DocEntry[] {
79
+ let out = entries;
80
+ if (q.where?.category) {
81
+ out = out.filter((d) => d.category === q.where?.category);
82
+ }
83
+ if (q.where?.tag) {
84
+ out = out.filter((d) => (d.tags ?? []).includes(q.where?.tag as string));
85
+ }
86
+ if (q.where?.draft !== undefined) {
87
+ out = out.filter((d) => (d.draft ?? false) === q.where?.draft);
88
+ }
89
+ const dir = q.order === "desc" ? -1 : 1;
90
+ const sorter: Record<
91
+ NonNullable<DocQuery["sort"]>,
92
+ (a: DocEntry, b: DocEntry) => number
93
+ > = {
94
+ title: (a, b) => a.label.localeCompare(b.label),
95
+ order: (a, b) => (a.order ?? 0) - (b.order ?? 0),
96
+ lastUpdated: (a, b) =>
97
+ (a.lastUpdated ?? "").localeCompare(b.lastUpdated ?? ""),
98
+ id: (a, b) => a.id.localeCompare(b.id),
99
+ };
100
+ if (q.sort)
101
+ out = [...out].sort(
102
+ (a, b) => sorter[q.sort as keyof typeof sorter](a, b) * dir,
103
+ );
104
+ if (q.limit && q.limit > 0) out = out.slice(0, q.limit);
105
+ return out;
106
+ }
107
+
108
+ export interface StaticCollectionInput {
109
+ meta: CollectionMeta;
110
+ /**
111
+ * `import.meta.glob("…/docs/**\/*.{md,yml,yaml}", { query: "?raw", import: "default", eager: true })`
112
+ * Keys are file paths; values are raw file contents.
113
+ */
114
+ files: Record<string, string>;
115
+ /** Optional ArkType schema for frontmatter validation. */
116
+ schema?: Type<DocFrontmatter, unknown>;
117
+ }
118
+
119
+ export interface StaticSourceOptions {
120
+ collections: StaticCollectionInput[];
121
+ /** Include `draft: true` / future `publishedAt` docs (e.g. in dev). */
122
+ drafts?: boolean;
123
+ /** Overrides "now" for scheduled publishing tests. */
124
+ now?: Date;
125
+ }
126
+
127
+ /**
128
+ * Nuxt Content-style filesystem data source driven by `import.meta.glob`.
129
+ * Supports frontmatter, `_dir.yml` category config, draft/scheduled docs,
130
+ * MiniSearch full-text search, and the `query()` API.
131
+ */
132
+ export function createStaticDataSource(
133
+ options: StaticSourceOptions,
134
+ ): DocsDataSource {
135
+ const now = options.now ?? new Date();
136
+ const byCollection = new Map<string, LoadedDoc[]>();
137
+ const dirMeta = new Map<string, Map<string, DirMeta>>();
138
+
139
+ for (const col of options.collections) {
140
+ const docs: LoadedDoc[] = [];
141
+ const dirs = new Map<string, DirMeta>();
142
+
143
+ const stripPrefix = `../${col.meta.id}/`;
144
+
145
+ function normalizePath(p: string): string {
146
+ let norm = p.replace(/\\/g, "/");
147
+ if (norm.startsWith(stripPrefix)) {
148
+ norm = norm.slice(stripPrefix.length);
149
+ }
150
+ return norm;
151
+ }
152
+
153
+ // First pass: collect _dir.yml metadata so titles apply to every doc.
154
+ for (const [path, raw] of Object.entries(col.files)) {
155
+ const norm = normalizePath(path);
156
+ const parts = norm.split("/");
157
+ const file = parts[parts.length - 1] ?? "";
158
+ if (!/^_dir\.ya?ml$/i.test(file)) continue;
159
+ try {
160
+ dirs.set(
161
+ parts.slice(0, -1).join("/"),
162
+ (loadYaml(raw) ?? {}) as DirMeta,
163
+ );
164
+ } catch {
165
+ // ignore malformed _dir.yml
166
+ }
167
+ }
168
+
169
+ for (const [path, raw] of Object.entries(col.files)) {
170
+ const norm = normalizePath(path);
171
+ const parts = norm.split("/");
172
+ const file = parts.pop() ?? "";
173
+ const dirKey = parts.join("/");
174
+
175
+ if (!/\.(md|mdx)$/i.test(file)) continue;
176
+
177
+ const { data: fm, content } = parseFrontmatter(raw);
178
+ if (col.schema) {
179
+ const result = col.schema(fm);
180
+ if (result instanceof type.errors) {
181
+ throw new Error(
182
+ `Frontmatter validation failed for ${norm}: ${result.summary}`,
183
+ );
184
+ }
185
+ }
186
+ const id = docIdFromPath(norm);
187
+ const dirMetaForDoc = dirs.get(dirKey);
188
+ const category =
189
+ fm.category ??
190
+ dirMetaForDoc?.title ??
191
+ parts[parts.length - 1] ??
192
+ "Docs";
193
+ docs.push({
194
+ entry: {
195
+ id,
196
+ label: fm.title ?? file.replace(/\.(md|mdx)$/i, ""),
197
+ category,
198
+ description: fm.description ?? "",
199
+ path: norm,
200
+ lastUpdated: fm.lastUpdated,
201
+ publishedAt: fm.publishedAt,
202
+ order: fm.order,
203
+ tags: fm.tags,
204
+ badge: fm.badge,
205
+ icon: fm.icon,
206
+ draft: fm.draft === true,
207
+ seo: fm.seo,
208
+ type: "md",
209
+ },
210
+ frontmatter: fm,
211
+ content,
212
+ dirKey,
213
+ });
214
+ }
215
+ byCollection.set(col.meta.id, docs);
216
+ dirMeta.set(col.meta.id, dirs);
217
+ }
218
+
219
+ const visible = (colId: string) =>
220
+ (byCollection.get(colId) ?? []).filter((d) =>
221
+ isVisible(d.frontmatter, now, options.drafts ?? false),
222
+ );
223
+
224
+ const sortEntries = (docs: LoadedDoc[]): LoadedDoc[] =>
225
+ [...docs].sort(
226
+ (a, b) =>
227
+ (a.entry.order ?? Number.MAX_SAFE_INTEGER) -
228
+ (b.entry.order ?? Number.MAX_SAFE_INTEGER) ||
229
+ a.entry.label.localeCompare(b.entry.label),
230
+ );
231
+
232
+ // MiniSearch index over visible docs
233
+ const mini = new MiniSearch<LoadedDoc>({
234
+ fields: ["label", "description", "body"],
235
+ storeFields: ["entry"],
236
+ });
237
+ const allDocs: (LoadedDoc & {
238
+ collection: string;
239
+ body: string;
240
+ label: string;
241
+ description: string;
242
+ })[] = [];
243
+ for (const col of options.collections) {
244
+ for (const d of visible(col.meta.id)) {
245
+ allDocs.push({
246
+ ...d,
247
+ collection: col.meta.id,
248
+ label: d.entry.label,
249
+ description: d.entry.description,
250
+ body: stripMarkdown(d.content).slice(0, 8000),
251
+ });
252
+ }
253
+ }
254
+ mini.addAll(
255
+ allDocs.map((d) => ({ ...d, id: `${d.collection}::${d.entry.id}` })),
256
+ );
257
+
258
+ return {
259
+ async collections(): Promise<CollectionMeta[]> {
260
+ return options.collections.map((c) => {
261
+ const dirs = dirMeta.get(c.meta.id);
262
+ if (!dirs?.size) return c.meta;
263
+ const sections = [...dirs.entries()]
264
+ .map(([dirKey, m]) => ({
265
+ id: dirKey.split("/").pop() ?? dirKey,
266
+ label: m.title ?? dirKey.split("/").pop() ?? dirKey,
267
+ icon: m.icon,
268
+ order: m.order,
269
+ collapsed: m.collapsed,
270
+ }))
271
+ .sort(
272
+ (a, b) =>
273
+ (a.order ?? Number.MAX_SAFE_INTEGER) -
274
+ (b.order ?? Number.MAX_SAFE_INTEGER),
275
+ );
276
+ return { ...c.meta, sections };
277
+ });
278
+ },
279
+
280
+ async list(collection: string): Promise<DocEntry[]> {
281
+ return sortEntries(visible(collection)).map((d) => d.entry);
282
+ },
283
+
284
+ async get(collection: string, id: string): Promise<DocContent> {
285
+ const doc = (byCollection.get(collection) ?? []).find(
286
+ (d) => d.entry.id === id,
287
+ );
288
+ if (!doc) throw new Error(`Document not found: ${collection}/${id}`);
289
+ if (!isVisible(doc.frontmatter, now, options.drafts ?? false)) {
290
+ throw new Error(`Document is not published: ${id}`);
291
+ }
292
+ return {
293
+ id: doc.entry.id,
294
+ label: doc.entry.label,
295
+ content: doc.content,
296
+ frontmatter: doc.frontmatter,
297
+ path: doc.entry.path,
298
+ };
299
+ },
300
+
301
+ async search(q: string, collection?: string): Promise<SearchResult[]> {
302
+ return mini
303
+ .search(q, { prefix: true, fuzzy: 0.2 })
304
+ .filter((r) => {
305
+ const doc = allDocs.find(
306
+ (d) => `${d.collection}::${d.entry.id}` === r.id,
307
+ );
308
+ return doc && (!collection || doc.collection === collection);
309
+ })
310
+ .slice(0, 20)
311
+ .map((r) => {
312
+ const doc = allDocs.find(
313
+ (d) => `${d.collection}::${d.entry.id}` === r.id,
314
+ );
315
+ return {
316
+ collection: doc?.collection ?? "",
317
+ id: doc?.entry.id ?? "",
318
+ title: doc?.entry.label ?? "",
319
+ snippet: doc?.body.slice(0, 160) ?? "",
320
+ score: r.score,
321
+ };
322
+ });
323
+ },
324
+
325
+ async query(q: DocQuery): Promise<DocEntry[]> {
326
+ const cols = q.collection
327
+ ? [q.collection]
328
+ : options.collections.map((c) => c.meta.id);
329
+ const entries = cols.flatMap((c) => visible(c).map((d) => d.entry));
330
+ return queryDocs(entries, q);
331
+ },
332
+ };
333
+ }
334
+
335
+ export interface RemoteDataSourceOptions {
336
+ baseUrl: string;
337
+ /** Name of the collection this remote source serves. */
338
+ collection: string;
339
+ /** Optional fetch init options. */
340
+ fetchOptions?: RequestInit;
341
+ }
342
+
343
+ export function createRemoteDataSource(
344
+ options: RemoteDataSourceOptions,
345
+ ): DocsDataSource {
346
+ const manifestUrl = `${options.baseUrl.replace(/\/$/, "")}/manifest.json`;
347
+
348
+ async function fetchJson<T>(url: string): Promise<T> {
349
+ const res = await fetch(url, options.fetchOptions);
350
+ if (!res.ok) throw new Error(`Remote fetch failed: ${res.status} ${url}`);
351
+ return res.json() as Promise<T>;
352
+ }
353
+
354
+ let cachedList: DocEntry[] | undefined;
355
+ let cachedMeta: CollectionMeta | undefined;
356
+
357
+ return {
358
+ async collections(): Promise<CollectionMeta[]> {
359
+ if (cachedMeta) return [cachedMeta];
360
+ const meta = await fetchJson<CollectionMeta>(manifestUrl);
361
+ cachedMeta = { ...meta, id: options.collection };
362
+ return [cachedMeta];
363
+ },
364
+ async list(): Promise<DocEntry[]> {
365
+ if (cachedList) return cachedList;
366
+ const list = await fetchJson<DocEntry[]>(
367
+ `${options.baseUrl.replace(/\/$/, "")}/docs.json`,
368
+ );
369
+ cachedList = list;
370
+ return list;
371
+ },
372
+ async get(collection: string, id: string): Promise<DocContent> {
373
+ const url = `${options.baseUrl.replace(/\/$/, "")}/${collection}/${id}.json`;
374
+ return fetchJson<DocContent>(url);
375
+ },
376
+ async search(): Promise<SearchResult[]> {
377
+ return [];
378
+ },
379
+ async query(q: DocQuery): Promise<DocEntry[]> {
380
+ const entries = await this.list(options.collection);
381
+ return queryDocs(entries, q);
382
+ },
383
+ };
384
+ }
385
+
386
+ export function createCompositeDataSource(
387
+ sources: DocsDataSource[],
388
+ ): DocsDataSource {
389
+ const cache = new Map<string, DocsDataSource>();
390
+ async function sourceFor(collection: string) {
391
+ if (cache.has(collection)) return cache.get(collection);
392
+ for (const s of sources) {
393
+ const cols = await s.collections();
394
+ if (cols.some((c) => c.id === collection)) {
395
+ cache.set(collection, s);
396
+ return s;
397
+ }
398
+ }
399
+ return undefined;
400
+ }
401
+
402
+ return {
403
+ async collections(): Promise<CollectionMeta[]> {
404
+ const all = await Promise.all(sources.map((s) => s.collections()));
405
+ return all.flat();
406
+ },
407
+ async list(collection: string): Promise<DocEntry[]> {
408
+ const s = await sourceFor(collection);
409
+ if (!s) throw new Error(`No data source for collection: ${collection}`);
410
+ return s.list(collection);
411
+ },
412
+ async get(collection: string, id: string): Promise<DocContent> {
413
+ const s = await sourceFor(collection);
414
+ if (!s) throw new Error(`No data source for collection: ${collection}`);
415
+ return s.get(collection, id);
416
+ },
417
+ async search(q: string, collection?: string): Promise<SearchResult[]> {
418
+ const results = await Promise.all(
419
+ sources.map((s) => (s.search ? s.search(q, collection) : [])),
420
+ );
421
+ return results.flat().slice(0, 20);
422
+ },
423
+ async query(q: DocQuery): Promise<DocEntry[]> {
424
+ if (q.collection) {
425
+ const s = await sourceFor(q.collection);
426
+ if (!s)
427
+ throw new Error(`No data source for collection: ${q.collection}`);
428
+ return s.query ? s.query(q) : [];
429
+ }
430
+ const results = await Promise.all(
431
+ sources.map((s) => (s.query ? s.query(q) : [])),
432
+ );
433
+ return results.flat();
434
+ },
435
+ };
436
+ }
437
+
438
+ /** Related docs: same collection sharing at least one tag. */
439
+ export function relatedDocs(
440
+ entries: DocEntry[],
441
+ current: DocEntry,
442
+ limit = 4,
443
+ ): DocEntry[] {
444
+ const tags = new Set(current.tags ?? []);
445
+ if (!tags.size) return [];
446
+ return entries
447
+ .filter(
448
+ (d) => d.id !== current.id && (d.tags ?? []).some((t) => tags.has(t)),
449
+ )
450
+ .slice(0, limit);
451
+ }
@@ -0,0 +1,30 @@
1
+ import { createContext, useContext } from "solid-js";
2
+ import type { ApiCollection, DocsAppConfig } from "./config";
3
+ import type { CollectionMeta } from "./types";
4
+
5
+ const DocsCtx = createContext<DocsAppConfig>();
6
+
7
+ export const DocsProvider = (props: {
8
+ config: DocsAppConfig;
9
+ children: import("solid-js").JSX.Element;
10
+ }) => (
11
+ <DocsCtx.Provider value={props.config}>{props.children}</DocsCtx.Provider>
12
+ );
13
+
14
+ export const useDocs = (): DocsAppConfig => {
15
+ const ctx = useContext(DocsCtx);
16
+ if (!ctx) throw new Error("useDocs must be used inside <DocsProvider>");
17
+ return ctx;
18
+ };
19
+
20
+ /** Resolved collection metadata: dataSource collections + api collections. */
21
+ export const resolveCollections = (
22
+ config: DocsAppConfig,
23
+ loaded: CollectionMeta[] | undefined,
24
+ ): CollectionMeta[] => [...(loaded ?? []), ...(config.apiCollections ?? [])];
25
+
26
+ export const findApiCollection = (
27
+ config: DocsAppConfig,
28
+ id: string | undefined,
29
+ ): ApiCollection | undefined =>
30
+ (config.apiCollections ?? []).find((c) => c.id === id);
@@ -0,0 +1,93 @@
1
+ import MiniSearch from "minisearch";
2
+ import { createResource } from "solid-js";
3
+ import type { DocsAppConfig } from "./config";
4
+ import { useDocs } from "./context";
5
+ import type { CollectionMeta, DocEntry, SearchResult } from "./types";
6
+
7
+ /** Reactive collection list: dataSource collections merged with apiCollections. */
8
+ export function useCollections() {
9
+ const config = useDocs();
10
+ const [remote] = createResource(() => config.dataSource.collections());
11
+ return (): CollectionMeta[] => [
12
+ ...(remote() ?? []),
13
+ ...(config.apiCollections ?? []),
14
+ ];
15
+ }
16
+
17
+ export function createDocsList(collection: () => string) {
18
+ const config = useDocs();
19
+ return createResource(collection, async (id) => {
20
+ if (!id) return [] as DocEntry[];
21
+ // API collections expose endpoints through the same list() shape.
22
+ const api = (config.apiCollections ?? []).find((c) => c.id === id);
23
+ if (api) {
24
+ return api.endpoints.map(
25
+ (e): DocEntry => ({
26
+ id: e.id,
27
+ label: e.summary ?? `${e.method} ${e.path}`,
28
+ category: e.tag ?? "Endpoints",
29
+ description: e.description ?? "",
30
+ path: e.path,
31
+ type: "api",
32
+ }),
33
+ );
34
+ }
35
+ return config.dataSource.list(id);
36
+ });
37
+ }
38
+
39
+ interface SearchDoc extends SearchResult {
40
+ content: string;
41
+ }
42
+
43
+ let cachedSearch: MiniSearch<SearchDoc> | undefined;
44
+
45
+ export async function buildSearchIndex(
46
+ config: DocsAppConfig,
47
+ ): Promise<MiniSearch<SearchDoc>> {
48
+ if (cachedSearch) return cachedSearch;
49
+ const collections = await config.dataSource.collections();
50
+ const docs: SearchDoc[] = [];
51
+ for (const collection of collections) {
52
+ const entries = await config.dataSource.list(collection.id);
53
+ for (const entry of entries) {
54
+ const c = await config.dataSource.get(collection.id, entry.id);
55
+ docs.push({
56
+ collection: collection.id,
57
+ id: entry.id,
58
+ title: entry.label,
59
+ snippet:
60
+ entry.description ||
61
+ (c.content ?? "").slice(0, 160).replace(/\s+/g, " "),
62
+ score: 0,
63
+ content: c.content ?? "",
64
+ });
65
+ }
66
+ }
67
+
68
+ cachedSearch = new MiniSearch<SearchDoc>({
69
+ fields: ["title", "snippet", "content"],
70
+ storeFields: ["collection", "id", "title", "snippet"],
71
+ searchOptions: {
72
+ prefix: true,
73
+ fuzzy: 0.2,
74
+ },
75
+ });
76
+ cachedSearch.addAll(docs);
77
+ return cachedSearch;
78
+ }
79
+
80
+ export async function searchDocs(
81
+ config: DocsAppConfig,
82
+ query: string,
83
+ ): Promise<SearchResult[]> {
84
+ const index = await buildSearchIndex(config);
85
+ const raw = index.search(query, { prefix: true, fuzzy: 0.2 });
86
+ return raw.map((r) => ({
87
+ collection: r.collection as string,
88
+ id: r.id as string,
89
+ title: r.title as string,
90
+ snippet: r.snippet as string,
91
+ score: r.score,
92
+ }));
93
+ }