mordoc 0.1.13 → 1.0.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 (431) hide show
  1. package/LICENSE +7 -0
  2. package/bin/cli.js +24 -71
  3. package/dist/cli/asset-rewrite.d.ts +40 -0
  4. package/dist/cli/asset-rewrite.d.ts.map +1 -0
  5. package/dist/cli/asset-rewrite.js +67 -0
  6. package/dist/cli/asset-rewrite.js.map +1 -0
  7. package/dist/cli/build.d.ts +45 -15
  8. package/dist/cli/build.d.ts.map +1 -1
  9. package/dist/cli/build.js +186 -101
  10. package/dist/cli/build.js.map +1 -1
  11. package/dist/cli/dev.d.ts +26 -14
  12. package/dist/cli/dev.d.ts.map +1 -1
  13. package/dist/cli/dev.js +116 -159
  14. package/dist/cli/dev.js.map +1 -1
  15. package/dist/cli/pagefind-indexer.d.ts +15 -0
  16. package/dist/cli/pagefind-indexer.d.ts.map +1 -0
  17. package/dist/cli/pagefind-indexer.js +68 -0
  18. package/dist/cli/pagefind-indexer.js.map +1 -0
  19. package/dist/cli/paths.d.ts +26 -0
  20. package/dist/cli/paths.d.ts.map +1 -0
  21. package/dist/cli/paths.js +32 -0
  22. package/dist/cli/paths.js.map +1 -0
  23. package/dist/cli/ssg-runner.d.ts +58 -0
  24. package/dist/cli/ssg-runner.d.ts.map +1 -0
  25. package/dist/cli/ssg-runner.js +126 -0
  26. package/dist/cli/ssg-runner.js.map +1 -0
  27. package/dist/config/assets-loader.d.ts +11 -0
  28. package/dist/config/assets-loader.d.ts.map +1 -0
  29. package/dist/config/assets-loader.js +46 -0
  30. package/dist/config/assets-loader.js.map +1 -0
  31. package/dist/config/language-loader.d.ts +11 -0
  32. package/dist/config/language-loader.d.ts.map +1 -0
  33. package/dist/config/language-loader.js +61 -0
  34. package/dist/config/language-loader.js.map +1 -0
  35. package/dist/config/language.d.ts +11 -0
  36. package/dist/config/language.d.ts.map +1 -0
  37. package/dist/config/language.js +61 -0
  38. package/dist/config/language.js.map +1 -0
  39. package/dist/config/sidenav-loader.d.ts +14 -0
  40. package/dist/config/sidenav-loader.d.ts.map +1 -0
  41. package/dist/config/sidenav-loader.js +78 -0
  42. package/dist/config/sidenav-loader.js.map +1 -0
  43. package/dist/config/site-loader.d.ts +11 -0
  44. package/dist/config/site-loader.d.ts.map +1 -0
  45. package/dist/config/site-loader.js +72 -0
  46. package/dist/config/site-loader.js.map +1 -0
  47. package/dist/config/site.d.ts +11 -0
  48. package/dist/config/site.d.ts.map +1 -0
  49. package/dist/config/site.js +72 -0
  50. package/dist/config/site.js.map +1 -0
  51. package/dist/config/topnav-loader.d.ts +10 -0
  52. package/dist/config/topnav-loader.d.ts.map +1 -0
  53. package/dist/config/topnav-loader.js +78 -0
  54. package/dist/config/topnav-loader.js.map +1 -0
  55. package/dist/config/translations-loader.d.ts +7 -0
  56. package/dist/config/translations-loader.d.ts.map +1 -0
  57. package/dist/config/translations-loader.js +51 -0
  58. package/dist/config/translations-loader.js.map +1 -0
  59. package/dist/content/content-loader.d.ts +16 -0
  60. package/dist/content/content-loader.d.ts.map +1 -0
  61. package/dist/content/content-loader.js +126 -0
  62. package/dist/content/content-loader.js.map +1 -0
  63. package/dist/content/content-parser.d.ts +12 -0
  64. package/dist/content/content-parser.d.ts.map +1 -0
  65. package/dist/content/content-parser.js +54 -0
  66. package/dist/content/content-parser.js.map +1 -0
  67. package/dist/content/content-transformer.d.ts +17 -0
  68. package/dist/content/content-transformer.d.ts.map +1 -0
  69. package/dist/content/content-transformer.js +94 -0
  70. package/dist/content/content-transformer.js.map +1 -0
  71. package/dist/content/markdoc-config.d.ts +13 -0
  72. package/dist/content/markdoc-config.d.ts.map +1 -0
  73. package/dist/content/markdoc-config.js +210 -0
  74. package/dist/content/markdoc-config.js.map +1 -0
  75. package/dist/content/slug.d.ts +26 -0
  76. package/dist/content/slug.d.ts.map +1 -0
  77. package/dist/content/slug.js +31 -0
  78. package/dist/content/slug.js.map +1 -0
  79. package/dist/pipeline.d.ts +61 -0
  80. package/dist/pipeline.d.ts.map +1 -0
  81. package/dist/pipeline.js +123 -0
  82. package/dist/pipeline.js.map +1 -0
  83. package/dist/types/assets.d.ts +15 -0
  84. package/dist/types/assets.d.ts.map +1 -0
  85. package/dist/types/assets.js +2 -0
  86. package/dist/types/assets.js.map +1 -0
  87. package/dist/types/content.d.ts +114 -32
  88. package/dist/types/content.d.ts.map +1 -1
  89. package/dist/types/content.js +1 -6
  90. package/dist/types/content.js.map +1 -1
  91. package/dist/types/language.d.ts +9 -0
  92. package/dist/types/language.d.ts.map +1 -0
  93. package/dist/types/language.js +2 -0
  94. package/dist/types/language.js.map +1 -0
  95. package/dist/types/navigation.d.ts +24 -36
  96. package/dist/types/navigation.d.ts.map +1 -1
  97. package/dist/types/navigation.js +1 -6
  98. package/dist/types/navigation.js.map +1 -1
  99. package/dist/types/pipeline.d.ts +70 -0
  100. package/dist/types/pipeline.d.ts.map +1 -0
  101. package/dist/types/pipeline.js +2 -0
  102. package/dist/types/pipeline.js.map +1 -0
  103. package/dist/types/site.d.ts +20 -0
  104. package/dist/types/site.d.ts.map +1 -0
  105. package/dist/types/site.js +2 -0
  106. package/dist/types/site.js.map +1 -0
  107. package/dist/utils/lang-utils.d.ts +23 -0
  108. package/dist/utils/lang-utils.d.ts.map +1 -0
  109. package/dist/utils/lang-utils.js +40 -0
  110. package/dist/utils/lang-utils.js.map +1 -0
  111. package/dist/utils/paths.d.ts +25 -0
  112. package/dist/utils/paths.d.ts.map +1 -0
  113. package/dist/utils/paths.js +31 -0
  114. package/dist/utils/paths.js.map +1 -0
  115. package/dist/vite/plugin.d.ts +93 -0
  116. package/dist/vite/plugin.d.ts.map +1 -0
  117. package/dist/vite/plugin.js +435 -0
  118. package/dist/vite/plugin.js.map +1 -0
  119. package/package.json +46 -61
  120. package/src/app/App.module.css +82 -0
  121. package/src/app/App.tsx +95 -0
  122. package/src/app/content/Content.module.css +357 -0
  123. package/src/app/content/Content.tsx +212 -0
  124. package/src/app/content/callout/Callout.module.css +110 -0
  125. package/src/app/content/callout/Callout.tsx +82 -0
  126. package/src/app/content/card/Card.module.css +146 -0
  127. package/src/app/content/card/Card.tsx +110 -0
  128. package/src/app/content/card/CardGrid.module.css +22 -0
  129. package/src/app/content/card/CardGrid.tsx +34 -0
  130. package/src/app/content/code-block/CodeBlock.module.css +237 -0
  131. package/src/app/content/code-block/CodeBlock.tsx +123 -0
  132. package/src/app/content/heading/Heading.module.css +52 -0
  133. package/src/app/content/heading/Heading.tsx +75 -0
  134. package/src/app/content/image/Image.module.css +113 -0
  135. package/src/app/content/image/Image.tsx +98 -0
  136. package/src/app/content/link/ContentLink.tsx +46 -0
  137. package/src/app/data-context.tsx +39 -0
  138. package/src/app/entry-server.tsx +58 -0
  139. package/src/app/footer/Footer.module.css +36 -0
  140. package/src/app/footer/Footer.tsx +28 -0
  141. package/src/app/globals.d.ts +40 -0
  142. package/src/app/header/Header.module.css +205 -0
  143. package/src/app/header/Header.tsx +188 -0
  144. package/src/app/header/LanguagePicker.module.css +97 -0
  145. package/src/app/header/LanguagePicker.tsx +174 -0
  146. package/src/app/header/SearchBar.module.css +92 -0
  147. package/src/app/header/SearchBar.tsx +37 -0
  148. package/src/app/header/SearchModal.module.css +185 -0
  149. package/src/app/header/SearchModal.tsx +245 -0
  150. package/src/app/header/Topnav.module.css +37 -0
  151. package/src/app/header/Topnav.tsx +30 -0
  152. package/src/app/index.css +119 -0
  153. package/src/app/index.html +13 -0
  154. package/src/app/landing/LandingPage.module.css +14 -0
  155. package/src/app/landing/LandingPage.tsx +62 -0
  156. package/src/app/landing/button/Button.module.css +37 -0
  157. package/src/app/landing/button/Button.tsx +50 -0
  158. package/src/app/landing/hero/Hero.module.css +108 -0
  159. package/src/app/landing/hero/Hero.tsx +81 -0
  160. package/src/app/landing/section/Section.module.css +100 -0
  161. package/src/app/landing/section/Section.tsx +61 -0
  162. package/src/app/lang-utils.ts +11 -0
  163. package/src/app/main.tsx +67 -0
  164. package/src/app/not-found/NotFound.module.css +92 -0
  165. package/src/app/not-found/NotFound.tsx +34 -0
  166. package/src/app/routes.tsx +86 -0
  167. package/src/app/sidenav/Sidenav.module.css +239 -0
  168. package/src/app/sidenav/Sidenav.tsx +182 -0
  169. package/src/app/skeleton/Skeleton.module.css +100 -0
  170. package/src/app/skeleton/Skeleton.tsx +75 -0
  171. package/src/app/toc/Toc.module.css +59 -0
  172. package/src/app/toc/Toc.tsx +77 -0
  173. package/src/app/tsconfig.json +18 -0
  174. package/src/app/virtual-modules.d.ts +74 -0
  175. package/dist/assets/fonts/inter/Inter-Italic-VariableFont_opsz,wght.ttf +0 -0
  176. package/dist/assets/fonts/inter/Inter-VariableFont_opsz,wght.ttf +0 -0
  177. package/dist/assets/fonts/inter/OFL.txt +0 -93
  178. package/dist/build/Builder.d.ts +0 -92
  179. package/dist/build/Builder.d.ts.map +0 -1
  180. package/dist/build/Builder.js +0 -394
  181. package/dist/build/Builder.js.map +0 -1
  182. package/dist/build/ClientBundler.d.ts +0 -48
  183. package/dist/build/ClientBundler.d.ts.map +0 -1
  184. package/dist/build/ClientBundler.js +0 -169
  185. package/dist/build/ClientBundler.js.map +0 -1
  186. package/dist/build/HtmlGenerator.d.ts +0 -46
  187. package/dist/build/HtmlGenerator.d.ts.map +0 -1
  188. package/dist/build/HtmlGenerator.js +0 -190
  189. package/dist/build/HtmlGenerator.js.map +0 -1
  190. package/dist/build/SearchIndexer.d.ts +0 -31
  191. package/dist/build/SearchIndexer.d.ts.map +0 -1
  192. package/dist/build/SearchIndexer.js +0 -116
  193. package/dist/build/SearchIndexer.js.map +0 -1
  194. package/dist/bundles/client.js +0 -126
  195. package/dist/cli/create-app.d.ts +0 -14
  196. package/dist/cli/create-app.d.ts.map +0 -1
  197. package/dist/cli/create-app.js +0 -241
  198. package/dist/cli/create-app.js.map +0 -1
  199. package/dist/client/App.d.ts +0 -17
  200. package/dist/client/App.d.ts.map +0 -1
  201. package/dist/client/App.js +0 -91
  202. package/dist/client/App.js.map +0 -1
  203. package/dist/client/contexts/ConfigContext.d.ts +0 -22
  204. package/dist/client/contexts/ConfigContext.d.ts.map +0 -1
  205. package/dist/client/contexts/ConfigContext.js +0 -27
  206. package/dist/client/contexts/ConfigContext.js.map +0 -1
  207. package/dist/client/contexts/ContentContext.d.ts +0 -31
  208. package/dist/client/contexts/ContentContext.d.ts.map +0 -1
  209. package/dist/client/contexts/ContentContext.js +0 -46
  210. package/dist/client/contexts/ContentContext.js.map +0 -1
  211. package/dist/client/contexts/SearchContext.d.ts +0 -38
  212. package/dist/client/contexts/SearchContext.d.ts.map +0 -1
  213. package/dist/client/contexts/SearchContext.js +0 -185
  214. package/dist/client/contexts/SearchContext.js.map +0 -1
  215. package/dist/client/contexts/ThemeContext.d.ts +0 -23
  216. package/dist/client/contexts/ThemeContext.d.ts.map +0 -1
  217. package/dist/client/contexts/ThemeContext.js +0 -53
  218. package/dist/client/contexts/ThemeContext.js.map +0 -1
  219. package/dist/client/hooks/useContent.d.ts +0 -12
  220. package/dist/client/hooks/useContent.d.ts.map +0 -1
  221. package/dist/client/hooks/useContent.js +0 -74
  222. package/dist/client/hooks/useContent.js.map +0 -1
  223. package/dist/client/hooks/useNavigation.d.ts +0 -15
  224. package/dist/client/hooks/useNavigation.d.ts.map +0 -1
  225. package/dist/client/hooks/useNavigation.js +0 -101
  226. package/dist/client/hooks/useNavigation.js.map +0 -1
  227. package/dist/client/hooks/useSearch.d.ts +0 -22
  228. package/dist/client/hooks/useSearch.d.ts.map +0 -1
  229. package/dist/client/hooks/useSearch.js +0 -64
  230. package/dist/client/hooks/useSearch.js.map +0 -1
  231. package/dist/client/main.d.ts +0 -5
  232. package/dist/client/main.d.ts.map +0 -1
  233. package/dist/client/main.js +0 -66
  234. package/dist/client/main.js.map +0 -1
  235. package/dist/components/Callout.d.ts +0 -9
  236. package/dist/components/Callout.d.ts.map +0 -1
  237. package/dist/components/Callout.js +0 -24
  238. package/dist/components/Callout.js.map +0 -1
  239. package/dist/components/Card.d.ts +0 -10
  240. package/dist/components/Card.d.ts.map +0 -1
  241. package/dist/components/Card.js +0 -15
  242. package/dist/components/Card.js.map +0 -1
  243. package/dist/components/CardGrid.d.ts +0 -8
  244. package/dist/components/CardGrid.d.ts.map +0 -1
  245. package/dist/components/CardGrid.js +0 -9
  246. package/dist/components/CardGrid.js.map +0 -1
  247. package/dist/components/CodeBlock.d.ts +0 -28
  248. package/dist/components/CodeBlock.d.ts.map +0 -1
  249. package/dist/components/CodeBlock.js +0 -80
  250. package/dist/components/CodeBlock.js.map +0 -1
  251. package/dist/components/ContentPage.d.ts +0 -9
  252. package/dist/components/ContentPage.d.ts.map +0 -1
  253. package/dist/components/ContentPage.js +0 -102
  254. package/dist/components/ContentPage.js.map +0 -1
  255. package/dist/components/Header.d.ts +0 -14
  256. package/dist/components/Header.d.ts.map +0 -1
  257. package/dist/components/Header.js +0 -30
  258. package/dist/components/Header.js.map +0 -1
  259. package/dist/components/Heading.d.ts +0 -16
  260. package/dist/components/Heading.d.ts.map +0 -1
  261. package/dist/components/Heading.js +0 -31
  262. package/dist/components/Heading.js.map +0 -1
  263. package/dist/components/Image.d.ts +0 -8
  264. package/dist/components/Image.d.ts.map +0 -1
  265. package/dist/components/Image.js +0 -24
  266. package/dist/components/Image.js.map +0 -1
  267. package/dist/components/Layout.d.ts +0 -14
  268. package/dist/components/Layout.d.ts.map +0 -1
  269. package/dist/components/Layout.js +0 -32
  270. package/dist/components/Layout.js.map +0 -1
  271. package/dist/components/MarkdocRenderer.d.ts +0 -15
  272. package/dist/components/MarkdocRenderer.d.ts.map +0 -1
  273. package/dist/components/MarkdocRenderer.js +0 -73
  274. package/dist/components/MarkdocRenderer.js.map +0 -1
  275. package/dist/components/MobileMenu.d.ts +0 -14
  276. package/dist/components/MobileMenu.d.ts.map +0 -1
  277. package/dist/components/MobileMenu.js +0 -45
  278. package/dist/components/MobileMenu.js.map +0 -1
  279. package/dist/components/PageNavigation.d.ts +0 -9
  280. package/dist/components/PageNavigation.d.ts.map +0 -1
  281. package/dist/components/PageNavigation.js +0 -23
  282. package/dist/components/PageNavigation.js.map +0 -1
  283. package/dist/components/SearchModal.d.ts +0 -9
  284. package/dist/components/SearchModal.d.ts.map +0 -1
  285. package/dist/components/SearchModal.js +0 -74
  286. package/dist/components/SearchModal.js.map +0 -1
  287. package/dist/components/SideNav.d.ts +0 -9
  288. package/dist/components/SideNav.d.ts.map +0 -1
  289. package/dist/components/SideNav.js +0 -66
  290. package/dist/components/SideNav.js.map +0 -1
  291. package/dist/components/TableOfContents.d.ts +0 -10
  292. package/dist/components/TableOfContents.d.ts.map +0 -1
  293. package/dist/components/TableOfContents.js +0 -151
  294. package/dist/components/TableOfContents.js.map +0 -1
  295. package/dist/config/ConfigLoader.d.ts +0 -50
  296. package/dist/config/ConfigLoader.d.ts.map +0 -1
  297. package/dist/config/ConfigLoader.js +0 -214
  298. package/dist/config/ConfigLoader.js.map +0 -1
  299. package/dist/config/StyleCompiler.d.ts +0 -17
  300. package/dist/config/StyleCompiler.d.ts.map +0 -1
  301. package/dist/config/StyleCompiler.js +0 -116
  302. package/dist/config/StyleCompiler.js.map +0 -1
  303. package/dist/config/ThemeGenerator.d.ts +0 -14
  304. package/dist/config/ThemeGenerator.d.ts.map +0 -1
  305. package/dist/config/ThemeGenerator.js +0 -129
  306. package/dist/config/ThemeGenerator.js.map +0 -1
  307. package/dist/content/ContentLoader.d.ts +0 -70
  308. package/dist/content/ContentLoader.d.ts.map +0 -1
  309. package/dist/content/ContentLoader.js +0 -146
  310. package/dist/content/ContentLoader.js.map +0 -1
  311. package/dist/content/ContentProcessor.d.ts +0 -84
  312. package/dist/content/ContentProcessor.d.ts.map +0 -1
  313. package/dist/content/ContentProcessor.js +0 -380
  314. package/dist/content/ContentProcessor.js.map +0 -1
  315. package/dist/content/RouteManager.d.ts +0 -69
  316. package/dist/content/RouteManager.d.ts.map +0 -1
  317. package/dist/content/RouteManager.js +0 -143
  318. package/dist/content/RouteManager.js.map +0 -1
  319. package/dist/styles/components/callout.d.ts +0 -11
  320. package/dist/styles/components/callout.d.ts.map +0 -1
  321. package/dist/styles/components/callout.js +0 -87
  322. package/dist/styles/components/callout.js.map +0 -1
  323. package/dist/styles/components/card.d.ts +0 -11
  324. package/dist/styles/components/card.d.ts.map +0 -1
  325. package/dist/styles/components/card.js +0 -179
  326. package/dist/styles/components/card.js.map +0 -1
  327. package/dist/styles/components/codeblock.d.ts +0 -11
  328. package/dist/styles/components/codeblock.d.ts.map +0 -1
  329. package/dist/styles/components/codeblock.js +0 -251
  330. package/dist/styles/components/codeblock.js.map +0 -1
  331. package/dist/styles/components/content.d.ts +0 -11
  332. package/dist/styles/components/content.d.ts.map +0 -1
  333. package/dist/styles/components/content.js +0 -197
  334. package/dist/styles/components/content.js.map +0 -1
  335. package/dist/styles/components/fonts.d.ts +0 -11
  336. package/dist/styles/components/fonts.d.ts.map +0 -1
  337. package/dist/styles/components/fonts.js +0 -34
  338. package/dist/styles/components/fonts.js.map +0 -1
  339. package/dist/styles/components/header.d.ts +0 -11
  340. package/dist/styles/components/header.d.ts.map +0 -1
  341. package/dist/styles/components/header.js +0 -293
  342. package/dist/styles/components/header.js.map +0 -1
  343. package/dist/styles/components/heading.d.ts +0 -11
  344. package/dist/styles/components/heading.d.ts.map +0 -1
  345. package/dist/styles/components/heading.js +0 -115
  346. package/dist/styles/components/heading.js.map +0 -1
  347. package/dist/styles/components/layout.d.ts +0 -11
  348. package/dist/styles/components/layout.d.ts.map +0 -1
  349. package/dist/styles/components/layout.js +0 -79
  350. package/dist/styles/components/layout.js.map +0 -1
  351. package/dist/styles/components/mobilemenu.d.ts +0 -11
  352. package/dist/styles/components/mobilemenu.d.ts.map +0 -1
  353. package/dist/styles/components/mobilemenu.js +0 -112
  354. package/dist/styles/components/mobilemenu.js.map +0 -1
  355. package/dist/styles/components/reset.d.ts +0 -11
  356. package/dist/styles/components/reset.d.ts.map +0 -1
  357. package/dist/styles/components/reset.js +0 -131
  358. package/dist/styles/components/reset.js.map +0 -1
  359. package/dist/styles/components/searchmodal.d.ts +0 -11
  360. package/dist/styles/components/searchmodal.d.ts.map +0 -1
  361. package/dist/styles/components/searchmodal.js +0 -333
  362. package/dist/styles/components/searchmodal.js.map +0 -1
  363. package/dist/styles/components/sidenav.d.ts +0 -11
  364. package/dist/styles/components/sidenav.d.ts.map +0 -1
  365. package/dist/styles/components/sidenav.js +0 -212
  366. package/dist/styles/components/sidenav.js.map +0 -1
  367. package/dist/styles/components/toc.d.ts +0 -11
  368. package/dist/styles/components/toc.d.ts.map +0 -1
  369. package/dist/styles/components/toc.js +0 -120
  370. package/dist/styles/components/toc.js.map +0 -1
  371. package/dist/styles/components/typography.d.ts +0 -11
  372. package/dist/styles/components/typography.d.ts.map +0 -1
  373. package/dist/styles/components/typography.js +0 -248
  374. package/dist/styles/components/typography.js.map +0 -1
  375. package/dist/styles/components/utility.d.ts +0 -11
  376. package/dist/styles/components/utility.d.ts.map +0 -1
  377. package/dist/styles/components/utility.js +0 -231
  378. package/dist/styles/components/utility.js.map +0 -1
  379. package/dist/styles/types.d.ts +0 -79
  380. package/dist/styles/types.d.ts.map +0 -1
  381. package/dist/styles/types.js +0 -7
  382. package/dist/styles/types.js.map +0 -1
  383. package/dist/styles/utils.d.ts +0 -21
  384. package/dist/styles/utils.d.ts.map +0 -1
  385. package/dist/styles/utils.js +0 -50
  386. package/dist/styles/utils.js.map +0 -1
  387. package/dist/styles/variables/main.d.ts +0 -15
  388. package/dist/styles/variables/main.d.ts.map +0 -1
  389. package/dist/styles/variables/main.js +0 -116
  390. package/dist/styles/variables/main.js.map +0 -1
  391. package/dist/types/config.d.ts +0 -43
  392. package/dist/types/config.d.ts.map +0 -1
  393. package/dist/types/config.js +0 -7
  394. package/dist/types/config.js.map +0 -1
  395. package/dist/utils/language-utils.d.ts +0 -41
  396. package/dist/utils/language-utils.d.ts.map +0 -1
  397. package/dist/utils/language-utils.js +0 -79
  398. package/dist/utils/language-utils.js.map +0 -1
  399. package/dist/utils/slugify.d.ts +0 -20
  400. package/dist/utils/slugify.d.ts.map +0 -1
  401. package/dist/utils/slugify.js +0 -44
  402. package/dist/utils/slugify.js.map +0 -1
  403. package/templates/default/config/favicon.ico +0 -0
  404. package/templates/default/config/logo-dark.png +0 -0
  405. package/templates/default/config/logo.png +0 -0
  406. package/templates/default/config/sidenav.yaml +0 -36
  407. package/templates/default/config/site.json +0 -16
  408. package/templates/default/config/styles/main.json +0 -6
  409. package/templates/default/config/styles/typography.json +0 -6
  410. package/templates/default/content/en/changelog.md +0 -35
  411. package/templates/default/content/en/faq.md +0 -50
  412. package/templates/default/content/en/field-manual/engines.md +0 -59
  413. package/templates/default/content/en/field-manual/relativity.md +0 -46
  414. package/templates/default/content/en/field-manual/safety.md +0 -44
  415. package/templates/default/content/en/field-manual.md +0 -22
  416. package/templates/default/content/en/flight-school/navigation.md +0 -61
  417. package/templates/default/content/en/flight-school/primer.md +0 -64
  418. package/templates/default/content/en/flight-school.md +0 -48
  419. package/templates/default/content/en/index.md +0 -83
  420. package/templates/default/content/en/ship-systems/flux-sails.md +0 -33
  421. package/templates/default/content/en/ship-systems/photonic-core.md +0 -39
  422. package/templates/default/content/en/ship-systems.md +0 -25
  423. package/templates/default/package.json +0 -21
  424. package/templates/default/public/icons/academy.svg +0 -15
  425. package/templates/default/public/icons/manual.svg +0 -16
  426. package/templates/default/public/icons/relativity.svg +0 -16
  427. package/templates/default/public/icons/systems.svg +0 -14
  428. package/templates/default/public/icons/warning.svg +0 -14
  429. package/templates/default/public/images/flux-sails.svg +0 -33
  430. package/templates/default/public/images/photonic-core.svg +0 -44
  431. package/templates/default/public/images/starwake.svg +0 -49
@@ -0,0 +1,126 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs/promises';
3
+ import { pathToFileURL } from 'node:url';
4
+ import { toShellData } from '../pipeline.js';
5
+ import { detectCurrentLang } from '../utils/lang-utils.js';
6
+ /** Markers in `index.html` substituted at SSG time. */
7
+ const SSR_LANG_MARKER = '<!--ssr-lang-->';
8
+ const SSR_HEAD_MARKER = '<!--ssr-head-->';
9
+ const SSR_OUTLET_MARKER = '<!--ssr-outlet-->';
10
+ function escapeHtml(value) {
11
+ return value
12
+ .replace(/&/g, '&amp;')
13
+ .replace(/</g, '&lt;')
14
+ .replace(/>/g, '&gt;')
15
+ .replace(/"/g, '&quot;')
16
+ .replace(/'/g, '&#39;');
17
+ }
18
+ /**
19
+ * Builds the per-route `<head>` HTML injected at `<!--ssr-head-->`.
20
+ *
21
+ * Title format matches `Content.tsx`'s `document.title` assignment so
22
+ * dev and prod are consistent: `Page Title — Site Name`.
23
+ * `<meta name="description">` is omitted when frontmatter has no description.
24
+ * `<link rel="icon">` is omitted when no favicon asset is configured.
25
+ */
26
+ function buildHeadHtml(page, siteName, faviconUrl) {
27
+ const pageTitle = page.frontmatter.title;
28
+ const title = pageTitle
29
+ ? `${escapeHtml(pageTitle)} — ${escapeHtml(siteName)}`
30
+ : escapeHtml(siteName);
31
+ const parts = [`<title>${title}</title>`];
32
+ if (page.frontmatter.description) {
33
+ parts.push(`<meta name="description" content="${escapeHtml(page.frontmatter.description)}">`);
34
+ }
35
+ if (faviconUrl) {
36
+ parts.push(`<link rel="icon" href="${escapeHtml(faviconUrl)}">`);
37
+ }
38
+ return parts.join('\n ');
39
+ }
40
+ /**
41
+ * Maps a routePath to its on-disk output file inside `clientOutDir`.
42
+ *
43
+ * Pretty-URL layout: every route gets its own folder with an
44
+ * `index.html` inside, except the root which writes directly to
45
+ * `dist/index.html`. This is what every static host serves cleanly:
46
+ * a request for `/flight-manual` resolves to
47
+ * `dist/flight-manual/index.html` whether the URL has a trailing slash
48
+ * or not.
49
+ *
50
+ * Trailing slashes on routePaths would break the `slice(1)` arithmetic
51
+ * (e.g. `/foo/` → `dist/foo/` + `index.html` → `dist/foo//index.html`).
52
+ * The pipeline doesn't emit them today, but a future regression is
53
+ * cheap to guard against here.
54
+ */
55
+ function toOutputPath(routePath, clientOutDir) {
56
+ if (routePath === '/')
57
+ return path.join(clientOutDir, 'index.html');
58
+ if (!routePath.startsWith('/') || routePath.endsWith('/')) {
59
+ throw new Error(`mordoc build: invalid routePath "${routePath}". ` +
60
+ `Expected an absolute, slashless path like "/flight-manual".`);
61
+ }
62
+ return path.join(clientOutDir, routePath.slice(1), 'index.html');
63
+ }
64
+ /**
65
+ * Renders every route to a static HTML file in `clientOutDir`.
66
+ *
67
+ * Flow per route:
68
+ * 1. Build a synthetic `Request` from the routePath. The SSR `render`
69
+ * function only consults the URL's pathname for routing, so the
70
+ * `http://localhost` origin is filler — it just has to parse as a
71
+ * valid URL.
72
+ * 2. Call `render(request, shellData)` from the SSR bundle. This
73
+ * runs `createStaticHandler.query()`, which resolves the route's
74
+ * loader, which dynamically imports the lazy page module from the
75
+ * same SSR bundle. React Router's `<StaticRouterProvider>` then
76
+ * renders the matched tree to a string AND emits a `<script>` tag
77
+ * carrying the loader data, both inside the returned `html`.
78
+ * 3. Substitute `<!--ssr-head-->` and `<!--ssr-outlet-->` in the
79
+ * transformed-by-Vite `index.html` template using the
80
+ * replacement-FUNCTION form. The string form of `String.replace`
81
+ * honours `$` patterns (`$$` → `$`), and the hydration `<script>`
82
+ * from step 2 contains Markdoc's `$$mdtype` markers — the string
83
+ * form would mangle them, breaking `Tag.isTag()` on the client and
84
+ * surfacing as "Objects are not valid as a React child" the moment
85
+ * hydration tries to re-render. Function form bypasses pattern
86
+ * processing entirely.
87
+ * 4. Write to the route's `index.html`, creating parent directories
88
+ * as needed (e.g. `/flight-manual/safety` requires
89
+ * `dist/flight-manual/safety/`).
90
+ *
91
+ * The template is read once. Vite's client build has already produced
92
+ * `dist/index.html` with the hashed entry `<script>` tag in place, so
93
+ * every per-route file inherits the correct script reference for free.
94
+ *
95
+ * The SSR bundle import uses `pathToFileURL` because Node's ESM loader
96
+ * rejects raw absolute Windows paths in `import()` ("ERR_UNSUPPORTED_ESM_URL_SCHEME").
97
+ */
98
+ export async function runSsg(options) {
99
+ const { data, clientOutDir, ssrOutDir } = options;
100
+ const templatePath = path.join(clientOutDir, 'index.html');
101
+ const template = await fs.readFile(templatePath, 'utf-8');
102
+ const ssrEntryPath = path.join(ssrOutDir, 'entry-server.js');
103
+ const ssrEntryUrl = pathToFileURL(ssrEntryPath).href;
104
+ const ssrModule = (await import(ssrEntryUrl));
105
+ if (typeof ssrModule.render !== 'function') {
106
+ throw new Error(`mordoc build: SSR bundle at ${ssrEntryPath} did not export a render() function.`);
107
+ }
108
+ const shellData = toShellData(data);
109
+ for (const page of data.pages) {
110
+ const routePath = page.entry.routePath;
111
+ const request = new Request(`http://localhost${routePath}`);
112
+ const { html: appHtml } = await ssrModule.render(request, shellData);
113
+ const pageLang = detectCurrentLang(routePath, data.language, data.site.defaultLanguage);
114
+ const headHtml = buildHeadHtml(page, data.site.name, data.assets.favicon);
115
+ // lang is a plain ASCII code — string-form replace is safe (no $-patterns)
116
+ const withLang = template.replace(SSR_LANG_MARKER, pageLang);
117
+ const withHead = withLang.replace(SSR_HEAD_MARKER, () => headHtml);
118
+ const finalHtml = withHead.replace(SSR_OUTLET_MARKER, () => appHtml);
119
+ const outPath = toOutputPath(routePath, clientOutDir);
120
+ await fs.mkdir(path.dirname(outPath), { recursive: true });
121
+ await fs.writeFile(outPath, finalHtml, 'utf-8');
122
+ const relOut = path.relative(clientOutDir, outPath).replace(/\\/g, '/');
123
+ console.log(` ${routePath.padEnd(40)} → ${relOut}`);
124
+ }
125
+ }
126
+ //# sourceMappingURL=ssg-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssg-runner.js","sourceRoot":"","sources":["../../src/cli/ssg-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { ResolvedAssets } from '../types/assets.js';
2
+ /**
3
+ * Scans config/assets/ for known asset files by convention.
4
+ * All assets are optional — missing files result in null, never errors.
5
+ * If logo-dark is not found, it falls back to the light logo.
6
+ *
7
+ * @param projectRoot - Absolute path to the project's root directory.
8
+ * @returns Discovered asset paths.
9
+ */
10
+ export declare function loadAssets(projectRoot: string): Promise<ResolvedAssets>;
11
+ //# sourceMappingURL=assets-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets-loader.d.ts","sourceRoot":"","sources":["../../src/config/assets-loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AA8BzD;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAS7E"}
@@ -0,0 +1,46 @@
1
+ import { access } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ const ASSETS_DIR = join('config', 'assets');
4
+ const LOGO_EXTENSIONS = ['svg', 'png', 'jpg'];
5
+ /**
6
+ * Returns the absolute path if the file exists, or null otherwise.
7
+ */
8
+ async function findFile(filePath) {
9
+ try {
10
+ await access(filePath);
11
+ return filePath;
12
+ }
13
+ catch {
14
+ return null;
15
+ }
16
+ }
17
+ /**
18
+ * Searches for a file by base name across supported image extensions.
19
+ * Returns the absolute path of the first match, or null if none found.
20
+ * Priority order: svg → png → jpg.
21
+ */
22
+ async function findFileByBaseName(dir, baseName) {
23
+ for (const ext of LOGO_EXTENSIONS) {
24
+ const result = await findFile(join(dir, `${baseName}.${ext}`));
25
+ if (result)
26
+ return result;
27
+ }
28
+ return null;
29
+ }
30
+ /**
31
+ * Scans config/assets/ for known asset files by convention.
32
+ * All assets are optional — missing files result in null, never errors.
33
+ * If logo-dark is not found, it falls back to the light logo.
34
+ *
35
+ * @param projectRoot - Absolute path to the project's root directory.
36
+ * @returns Discovered asset paths.
37
+ */
38
+ export async function loadAssets(projectRoot) {
39
+ const assetsDir = join(projectRoot, ASSETS_DIR);
40
+ const favicon = await findFile(join(assetsDir, 'favicon.ico'));
41
+ const logo = await findFileByBaseName(assetsDir, 'logo');
42
+ const logoDarkFile = await findFileByBaseName(assetsDir, 'logo-dark');
43
+ const logoDark = logoDarkFile ?? logo;
44
+ return { favicon, logo, logoDark };
45
+ }
46
+ //# sourceMappingURL=assets-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets-loader.js","sourceRoot":"","sources":["../../src/config/assets-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC5C,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAE9C;;GAEG;AACH,KAAK,UAAU,QAAQ,CAAC,QAAgB;IACtC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QACvB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,kBAAkB,CAAC,GAAW,EAAE,QAAgB;IAC7D,KAAK,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;QAC/D,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;IAC5B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,WAAmB;IAClD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAEhD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACzD,MAAM,YAAY,GAAG,MAAM,kBAAkB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACtE,MAAM,QAAQ,GAAG,YAAY,IAAI,IAAI,CAAC;IAEtC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AACrC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { LanguageConfig } from '../types/language.js';
2
+ /**
3
+ * Reads and validates config/language.json for a Mordoc project.
4
+ * Returns null if the file does not exist (single-language project).
5
+ *
6
+ * @param projectRoot - Absolute path to the project's root directory.
7
+ * @param defaultLanguage - The defaultLanguage value from site.json.
8
+ * @returns The validated language configuration, or null if the file is absent.
9
+ */
10
+ export declare function loadLanguageConfig(projectRoot: string, defaultLanguage: string): Promise<LanguageConfig | null>;
11
+ //# sourceMappingURL=language-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"language-loader.d.ts","sourceRoot":"","sources":["../../src/config/language-loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AA4C3D;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAqBhC"}
@@ -0,0 +1,61 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ const LANGUAGE_CONFIG_PATH = join('config', 'language.json');
4
+ function validateLanguageConfig(raw, defaultLanguage) {
5
+ if (typeof raw !== 'object' || raw === null) {
6
+ throw new Error('language.json must contain a JSON object.');
7
+ }
8
+ const obj = raw;
9
+ if (!Array.isArray(obj['languages'])) {
10
+ throw new Error('language.json: "languages" must be an array.');
11
+ }
12
+ if (obj['languages'].length === 0) {
13
+ throw new Error('language.json: "languages" array must not be empty.');
14
+ }
15
+ const seen = new Set();
16
+ for (const [index, entry] of obj['languages'].entries()) {
17
+ if (typeof entry !== 'string' || entry === '') {
18
+ throw new Error(`language.json: languages[${index}] must be a non-empty string.`);
19
+ }
20
+ if (seen.has(entry)) {
21
+ throw new Error(`language.json: duplicate language code "${entry}".`);
22
+ }
23
+ seen.add(entry);
24
+ }
25
+ const config = raw;
26
+ if (!config.languages.includes(defaultLanguage)) {
27
+ throw new Error(`language.json: the defaultLanguage "${defaultLanguage}" from site.json ` +
28
+ `is not listed in the languages array. Add it or update site.json.`);
29
+ }
30
+ return config;
31
+ }
32
+ /**
33
+ * Reads and validates config/language.json for a Mordoc project.
34
+ * Returns null if the file does not exist (single-language project).
35
+ *
36
+ * @param projectRoot - Absolute path to the project's root directory.
37
+ * @param defaultLanguage - The defaultLanguage value from site.json.
38
+ * @returns The validated language configuration, or null if the file is absent.
39
+ */
40
+ export async function loadLanguageConfig(projectRoot, defaultLanguage) {
41
+ const filePath = join(projectRoot, LANGUAGE_CONFIG_PATH);
42
+ let content;
43
+ try {
44
+ content = await readFile(filePath, 'utf-8');
45
+ }
46
+ catch (err) {
47
+ if (err.code === 'ENOENT') {
48
+ return null;
49
+ }
50
+ throw new Error(`Failed to read ${filePath}: ${err.message}`);
51
+ }
52
+ let parsed;
53
+ try {
54
+ parsed = JSON.parse(content);
55
+ }
56
+ catch {
57
+ throw new Error(`Failed to parse ${filePath}: Invalid JSON.`);
58
+ }
59
+ return validateLanguageConfig(parsed, defaultLanguage);
60
+ }
61
+ //# sourceMappingURL=language-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"language-loader.js","sourceRoot":"","sources":["../../src/config/language-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,MAAM,oBAAoB,GAAG,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;AAE7D,SAAS,sBAAsB,CAAC,GAAY,EAAE,eAAuB;IACnE,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,GAAG,GAAG,GAA8B,CAAC;IAE3C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAK,GAAG,CAAC,WAAW,CAAe,CAAC,OAAO,EAAE,EAAE,CAAC;QACvE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,+BAA+B,CAAC,CAAC;QACpF,CAAC;QAED,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,2CAA2C,KAAK,IAAI,CAAC,CAAC;QACxE,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,GAAqB,CAAC;IAErC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CACb,uCAAuC,eAAe,mBAAmB;YACzE,mEAAmE,CACpE,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,WAAmB,EACnB,eAAuB;IAEvB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC;IAEzD,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,kBAAkB,QAAQ,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,iBAAiB,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,sBAAsB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { LanguageConfig } from '../types/language.js';
2
+ /**
3
+ * Reads and validates config/language.json for a Mordoc project.
4
+ * Returns null if the file does not exist (single-language project).
5
+ *
6
+ * @param projectRoot - Absolute path to the project's root directory.
7
+ * @param defaultLanguage - The defaultLanguage value from site.json.
8
+ * @returns The validated language configuration, or null if the file is absent.
9
+ */
10
+ export declare function loadLanguageConfig(projectRoot: string, defaultLanguage: string): Promise<LanguageConfig | null>;
11
+ //# sourceMappingURL=language.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"language.d.ts","sourceRoot":"","sources":["../../src/config/language.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AA4C3D;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAqBhC"}
@@ -0,0 +1,61 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ const LANGUAGE_CONFIG_PATH = join('config', 'language.json');
4
+ function validateLanguageConfig(raw, defaultLanguage) {
5
+ if (typeof raw !== 'object' || raw === null) {
6
+ throw new Error('language.json must contain a JSON object.');
7
+ }
8
+ const obj = raw;
9
+ if (!Array.isArray(obj['languages'])) {
10
+ throw new Error('language.json: "languages" must be an array.');
11
+ }
12
+ if (obj['languages'].length === 0) {
13
+ throw new Error('language.json: "languages" array must not be empty.');
14
+ }
15
+ const seen = new Set();
16
+ for (const [index, entry] of obj['languages'].entries()) {
17
+ if (typeof entry !== 'string' || entry === '') {
18
+ throw new Error(`language.json: languages[${index}] must be a non-empty string.`);
19
+ }
20
+ if (seen.has(entry)) {
21
+ throw new Error(`language.json: duplicate language code "${entry}".`);
22
+ }
23
+ seen.add(entry);
24
+ }
25
+ const config = raw;
26
+ if (!config.languages.includes(defaultLanguage)) {
27
+ throw new Error(`language.json: the defaultLanguage "${defaultLanguage}" from site.json ` +
28
+ `is not listed in the languages array. Add it or update site.json.`);
29
+ }
30
+ return config;
31
+ }
32
+ /**
33
+ * Reads and validates config/language.json for a Mordoc project.
34
+ * Returns null if the file does not exist (single-language project).
35
+ *
36
+ * @param projectRoot - Absolute path to the project's root directory.
37
+ * @param defaultLanguage - The defaultLanguage value from site.json.
38
+ * @returns The validated language configuration, or null if the file is absent.
39
+ */
40
+ export async function loadLanguageConfig(projectRoot, defaultLanguage) {
41
+ const filePath = join(projectRoot, LANGUAGE_CONFIG_PATH);
42
+ let content;
43
+ try {
44
+ content = await readFile(filePath, 'utf-8');
45
+ }
46
+ catch (err) {
47
+ if (err.code === 'ENOENT') {
48
+ return null;
49
+ }
50
+ throw new Error(`Failed to read ${filePath}: ${err.message}`);
51
+ }
52
+ let parsed;
53
+ try {
54
+ parsed = JSON.parse(content);
55
+ }
56
+ catch {
57
+ throw new Error(`Failed to parse ${filePath}: Invalid JSON.`);
58
+ }
59
+ return validateLanguageConfig(parsed, defaultLanguage);
60
+ }
61
+ //# sourceMappingURL=language.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"language.js","sourceRoot":"","sources":["../../src/config/language.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,MAAM,oBAAoB,GAAG,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;AAE7D,SAAS,sBAAsB,CAAC,GAAY,EAAE,eAAuB;IACnE,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,GAAG,GAAG,GAA8B,CAAC;IAE3C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAK,GAAG,CAAC,WAAW,CAAe,CAAC,OAAO,EAAE,EAAE,CAAC;QACvE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,+BAA+B,CAAC,CAAC;QACpF,CAAC;QAED,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,2CAA2C,KAAK,IAAI,CAAC,CAAC;QACxE,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,GAAqB,CAAC;IAErC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CACb,uCAAuC,eAAe,mBAAmB;YACzE,mEAAmE,CACpE,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,WAAmB,EACnB,eAAuB;IAEvB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC;IAEzD,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,kBAAkB,QAAQ,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,iBAAiB,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,sBAAsB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { SidenavConfig } from '../types/navigation.js';
2
+ /**
3
+ * Reads and validates a sidenav YAML file at the given absolute path.
4
+ * Shared by both the standalone sidenav loader and the topnav loader.
5
+ */
6
+ export declare function loadSidenavFile(filePath: string): Promise<SidenavConfig>;
7
+ /**
8
+ * Loads the default config/navigation/sidenav.yaml for projects without topnav.
9
+ *
10
+ * @param projectRoot - Absolute path to the project's root directory.
11
+ * @returns The validated side navigation configuration.
12
+ */
13
+ export declare function loadSidenavConfig(projectRoot: string): Promise<SidenavConfig>;
14
+ //# sourceMappingURL=sidenav-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidenav-loader.d.ts","sourceRoot":"","sources":["../../src/config/sidenav-loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,wBAAwB,CAAC;AAuDzE;;;GAGG;AACH,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAsB9E;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAGnF"}
@@ -0,0 +1,78 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import yaml from 'js-yaml';
4
+ const NAV_DIR = join('config', 'navigation');
5
+ const DEFAULT_SIDENAV = 'sidenav.yaml';
6
+ function validateItem(item, location, fileName) {
7
+ if (typeof item !== 'object' || item === null) {
8
+ throw new Error(`${fileName}: ${location} must be an object.`);
9
+ }
10
+ const obj = item;
11
+ if (typeof obj['label'] !== 'string' || obj['label'] === '') {
12
+ throw new Error(`${fileName}: ${location}.label is required and must be a non-empty string.`);
13
+ }
14
+ if (obj['path'] !== undefined && (typeof obj['path'] !== 'string' || obj['path'] === '')) {
15
+ throw new Error(`${fileName}: ${location}.path must be a non-empty string when provided.`);
16
+ }
17
+ if (obj['children'] !== undefined) {
18
+ if (!Array.isArray(obj['children'])) {
19
+ throw new Error(`${fileName}: ${location}.children must be an array.`);
20
+ }
21
+ if (obj['children'].length === 0) {
22
+ throw new Error(`${fileName}: ${location}.children must not be empty when provided.`);
23
+ }
24
+ for (const [i, child] of obj['children'].entries()) {
25
+ validateItem(child, `${location}.children[${i}]`, fileName);
26
+ }
27
+ }
28
+ if (obj['path'] === undefined && obj['children'] === undefined) {
29
+ throw new Error(`${fileName}: ${location} must have either "path", "children", or both.`);
30
+ }
31
+ return item;
32
+ }
33
+ function validateSidenavArray(raw, fileName) {
34
+ if (!Array.isArray(raw)) {
35
+ throw new Error(`${fileName}: file must contain a YAML array at the top level.`);
36
+ }
37
+ if (raw.length === 0) {
38
+ throw new Error(`${fileName}: navigation array must not be empty.`);
39
+ }
40
+ return raw.map((item, index) => validateItem(item, `items[${index}]`, fileName));
41
+ }
42
+ /**
43
+ * Reads and validates a sidenav YAML file at the given absolute path.
44
+ * Shared by both the standalone sidenav loader and the topnav loader.
45
+ */
46
+ export async function loadSidenavFile(filePath) {
47
+ const fileName = filePath.split(/[\\/]/).pop();
48
+ let content;
49
+ try {
50
+ content = await readFile(filePath, 'utf-8');
51
+ }
52
+ catch (err) {
53
+ const code = err.code;
54
+ if (code === 'ENOENT') {
55
+ throw new Error(`Sidenav file not found: ${filePath}`);
56
+ }
57
+ throw new Error(`Failed to read ${filePath}: ${err.message}`);
58
+ }
59
+ let parsed;
60
+ try {
61
+ parsed = yaml.load(content);
62
+ }
63
+ catch (err) {
64
+ throw new Error(`Failed to parse ${filePath}: ${err.message}`);
65
+ }
66
+ return validateSidenavArray(parsed, fileName);
67
+ }
68
+ /**
69
+ * Loads the default config/navigation/sidenav.yaml for projects without topnav.
70
+ *
71
+ * @param projectRoot - Absolute path to the project's root directory.
72
+ * @returns The validated side navigation configuration.
73
+ */
74
+ export async function loadSidenavConfig(projectRoot) {
75
+ const filePath = join(projectRoot, NAV_DIR, DEFAULT_SIDENAV);
76
+ return loadSidenavFile(filePath);
77
+ }
78
+ //# sourceMappingURL=sidenav-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidenav-loader.js","sourceRoot":"","sources":["../../src/config/sidenav-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { SiteConfig } from '../types/site.js';
2
+ /**
3
+ * Reads and validates the site.json config file for a Mordoc project.
4
+ *
5
+ * @param projectRoot - Absolute path to the project's root directory.
6
+ * @returns The validated site configuration object.
7
+ * @throws If the file is missing, unreadable, contains invalid JSON,
8
+ * or fails field validation.
9
+ */
10
+ export declare function loadSiteConfig(projectRoot: string): Promise<SiteConfig>;
11
+ //# sourceMappingURL=site-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"site-loader.d.ts","sourceRoot":"","sources":["../../src/config/site-loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAgDnD;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAsB7E"}
@@ -0,0 +1,72 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ // Relative path to the site config file within any Mordoc project root.
4
+ const SITE_CONFIG_PATH = join('config', 'site.json');
5
+ // Fields that must be present and non-empty for a config to be considered valid.
6
+ const REQUIRED_FIELDS = [
7
+ 'name',
8
+ 'description',
9
+ 'baseUrl',
10
+ 'defaultLanguage',
11
+ ];
12
+ /**
13
+ * Validates the raw parsed JSON from site.json and narrows it to SiteConfig.
14
+ * Throws a descriptive error if any required field is missing or malformed,
15
+ * so the user gets actionable feedback rather than a cryptic runtime crash.
16
+ */
17
+ function validateSiteConfig(raw) {
18
+ if (typeof raw !== 'object' || raw === null) {
19
+ throw new Error('site.json must contain a JSON object.');
20
+ }
21
+ const obj = raw;
22
+ for (const field of REQUIRED_FIELDS) {
23
+ if (typeof obj[field] !== 'string' || obj[field] === '') {
24
+ throw new Error(`site.json: "${field}" is required and must be a non-empty string.`);
25
+ }
26
+ }
27
+ // Validate baseUrl with the built-in URL parser — it handles all the edge
28
+ // cases (missing protocol, invalid characters, etc.) so we don't have to.
29
+ const baseUrl = obj['baseUrl'];
30
+ try {
31
+ new URL(baseUrl);
32
+ }
33
+ catch {
34
+ throw new Error(`site.json: "baseUrl" must be a valid URL. Got: "${baseUrl}"`);
35
+ }
36
+ // A trailing slash on baseUrl would cause double-slashes when paths are appended.
37
+ if (baseUrl.endsWith('/')) {
38
+ throw new Error(`site.json: "baseUrl" must not end with a trailing slash. Got: "${baseUrl}"`);
39
+ }
40
+ return raw;
41
+ }
42
+ /**
43
+ * Reads and validates the site.json config file for a Mordoc project.
44
+ *
45
+ * @param projectRoot - Absolute path to the project's root directory.
46
+ * @returns The validated site configuration object.
47
+ * @throws If the file is missing, unreadable, contains invalid JSON,
48
+ * or fails field validation.
49
+ */
50
+ export async function loadSiteConfig(projectRoot) {
51
+ const filePath = join(projectRoot, SITE_CONFIG_PATH);
52
+ let content;
53
+ try {
54
+ content = await readFile(filePath, 'utf-8');
55
+ }
56
+ catch (err) {
57
+ const code = err.code;
58
+ if (code === 'ENOENT') {
59
+ throw new Error(`Config file not found: ${filePath}\nEvery Mordoc project requires a config/site.json file.`);
60
+ }
61
+ throw new Error(`Failed to read ${filePath}: ${err.message}`);
62
+ }
63
+ let parsed;
64
+ try {
65
+ parsed = JSON.parse(content);
66
+ }
67
+ catch {
68
+ throw new Error(`Failed to parse ${filePath}: Invalid JSON.`);
69
+ }
70
+ return validateSiteConfig(parsed);
71
+ }
72
+ //# sourceMappingURL=site-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"site-loader.js","sourceRoot":"","sources":["../../src/config/site-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,wEAAwE;AACxE,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AAErD,iFAAiF;AACjF,MAAM,eAAe,GAAyB;IAC5C,MAAM;IACN,aAAa;IACb,SAAS;IACT,iBAAiB;CAClB,CAAC;AAEF;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,GAAY;IACtC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,GAAG,GAAG,GAA8B,CAAC;IAE3C,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;QACpC,IAAI,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CAAC,eAAe,KAAK,+CAA+C,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,0EAA0E;IAC1E,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAW,CAAC;IACzC,IAAI,CAAC;QACH,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,mDAAmD,OAAO,GAAG,CAAC,CAAC;IACjF,CAAC;IAED,kFAAkF;IAClF,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,kEAAkE,OAAO,GAAG,CAAC,CAAC;IAChG,CAAC;IAED,OAAO,GAAiB,CAAC;AAC3B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,WAAmB;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAErD,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;QACjD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,0BAA0B,QAAQ,0DAA0D,CAAC,CAAC;QAChH,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,kBAAkB,QAAQ,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,iBAAiB,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { SiteConfig } from '../types/site.js';
2
+ /**
3
+ * Reads and validates the site.json config file for a Mordoc project.
4
+ *
5
+ * @param projectRoot - Absolute path to the project's root directory.
6
+ * @returns The validated site configuration object.
7
+ * @throws If the file is missing, unreadable, contains invalid JSON,
8
+ * or fails field validation.
9
+ */
10
+ export declare function loadSiteConfig(projectRoot: string): Promise<SiteConfig>;
11
+ //# sourceMappingURL=site.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"site.d.ts","sourceRoot":"","sources":["../../src/config/site.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAgDnD;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAsB7E"}