@kamod-ch/preactpress 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 (546) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +165 -0
  3. package/assets/favicon-32.png +0 -0
  4. package/assets/favicon.png +0 -0
  5. package/assets/favicon.svg +28 -0
  6. package/assets/logo-dark.svg +5 -0
  7. package/assets/logo-light.svg +5 -0
  8. package/assets/logo.svg +5 -0
  9. package/bin/preactpress.mjs +13 -0
  10. package/dist/client/app.d.ts +6 -0
  11. package/dist/client/app.d.ts.map +1 -0
  12. package/dist/client/app.js +168 -0
  13. package/dist/client/app.js.map +1 -0
  14. package/dist/client/entry-client.d.ts +2 -0
  15. package/dist/client/entry-client.d.ts.map +1 -0
  16. package/dist/client/entry-client.js +27 -0
  17. package/dist/client/entry-client.js.map +1 -0
  18. package/dist/client/entry-ssr.d.ts +14 -0
  19. package/dist/client/entry-ssr.d.ts.map +1 -0
  20. package/dist/client/entry-ssr.js +59 -0
  21. package/dist/client/entry-ssr.js.map +1 -0
  22. package/dist/client/index.d.ts +3 -0
  23. package/dist/client/index.d.ts.map +1 -0
  24. package/dist/client/index.js +2 -0
  25. package/dist/client/index.js.map +1 -0
  26. package/dist/client/loadPage.d.ts +5 -0
  27. package/dist/client/loadPage.d.ts.map +1 -0
  28. package/dist/client/loadPage.js +62 -0
  29. package/dist/client/loadPage.js.map +1 -0
  30. package/dist/client/prefetchLinks.d.ts +2 -0
  31. package/dist/client/prefetchLinks.d.ts.map +1 -0
  32. package/dist/client/prefetchLinks.js +55 -0
  33. package/dist/client/prefetchLinks.js.map +1 -0
  34. package/dist/client/theme-default/AlgoliaSearch.d.ts +12 -0
  35. package/dist/client/theme-default/AlgoliaSearch.d.ts.map +1 -0
  36. package/dist/client/theme-default/AlgoliaSearch.js +66 -0
  37. package/dist/client/theme-default/AlgoliaSearch.js.map +1 -0
  38. package/dist/client/theme-default/Features.d.ts +9 -0
  39. package/dist/client/theme-default/Features.d.ts.map +1 -0
  40. package/dist/client/theme-default/Features.js +25 -0
  41. package/dist/client/theme-default/Features.js.map +1 -0
  42. package/dist/client/theme-default/Hero.d.ts +9 -0
  43. package/dist/client/theme-default/Hero.d.ts.map +1 -0
  44. package/dist/client/theme-default/Hero.js +23 -0
  45. package/dist/client/theme-default/Hero.js.map +1 -0
  46. package/dist/client/theme-default/Layout.d.ts +6 -0
  47. package/dist/client/theme-default/Layout.d.ts.map +1 -0
  48. package/dist/client/theme-default/Layout.js +224 -0
  49. package/dist/client/theme-default/Layout.js.map +1 -0
  50. package/dist/client/theme-default/Logo.d.ts +16 -0
  51. package/dist/client/theme-default/Logo.d.ts.map +1 -0
  52. package/dist/client/theme-default/Logo.js +30 -0
  53. package/dist/client/theme-default/Logo.js.map +1 -0
  54. package/dist/client/theme-default/NavLinks.d.ts +12 -0
  55. package/dist/client/theme-default/NavLinks.d.ts.map +1 -0
  56. package/dist/client/theme-default/NavLinks.js +18 -0
  57. package/dist/client/theme-default/NavLinks.js.map +1 -0
  58. package/dist/client/theme-default/SidebarNav.d.ts +12 -0
  59. package/dist/client/theme-default/SidebarNav.d.ts.map +1 -0
  60. package/dist/client/theme-default/SidebarNav.js +21 -0
  61. package/dist/client/theme-default/SidebarNav.js.map +1 -0
  62. package/dist/client/theme-default/SocialLinks.d.ts +8 -0
  63. package/dist/client/theme-default/SocialLinks.d.ts.map +1 -0
  64. package/dist/client/theme-default/SocialLinks.js +13 -0
  65. package/dist/client/theme-default/SocialLinks.js.map +1 -0
  66. package/dist/client/theme-default/ThemeToggle.d.ts +4 -0
  67. package/dist/client/theme-default/ThemeToggle.d.ts.map +1 -0
  68. package/dist/client/theme-default/ThemeToggle.js +31 -0
  69. package/dist/client/theme-default/ThemeToggle.js.map +1 -0
  70. package/dist/client/theme-default/index.d.ts +2 -0
  71. package/dist/client/theme-default/index.d.ts.map +1 -0
  72. package/dist/client/theme-default/index.js +2 -0
  73. package/dist/client/theme-default/index.js.map +1 -0
  74. package/dist/client/types.d.ts +36 -0
  75. package/dist/client/types.d.ts.map +1 -0
  76. package/dist/client/types.js +2 -0
  77. package/dist/client/types.js.map +1 -0
  78. package/dist/client/usePageHead.d.ts +10 -0
  79. package/dist/client/usePageHead.d.ts.map +1 -0
  80. package/dist/client/usePageHead.js +182 -0
  81. package/dist/client/usePageHead.js.map +1 -0
  82. package/dist/client/useSiteSearch.d.ts +10 -0
  83. package/dist/client/useSiteSearch.d.ts.map +1 -0
  84. package/dist/client/useSiteSearch.js +54 -0
  85. package/dist/client/useSiteSearch.js.map +1 -0
  86. package/dist/node/build.d.ts +15 -0
  87. package/dist/node/build.d.ts.map +1 -0
  88. package/dist/node/build.js +310 -0
  89. package/dist/node/build.js.map +1 -0
  90. package/dist/node/buildCache.d.ts +15 -0
  91. package/dist/node/buildCache.d.ts.map +1 -0
  92. package/dist/node/buildCache.js +41 -0
  93. package/dist/node/buildCache.js.map +1 -0
  94. package/dist/node/check.d.ts +11 -0
  95. package/dist/node/check.d.ts.map +1 -0
  96. package/dist/node/check.js +228 -0
  97. package/dist/node/check.js.map +1 -0
  98. package/dist/node/cli.d.ts +2 -0
  99. package/dist/node/cli.d.ts.map +1 -0
  100. package/dist/node/cli.js +157 -0
  101. package/dist/node/cli.js.map +1 -0
  102. package/dist/node/config-helpers.d.ts +8 -0
  103. package/dist/node/config-helpers.d.ts.map +1 -0
  104. package/dist/node/config-helpers.js +5 -0
  105. package/dist/node/config-helpers.js.map +1 -0
  106. package/dist/node/config.d.ts +13 -0
  107. package/dist/node/config.d.ts.map +1 -0
  108. package/dist/node/config.js +167 -0
  109. package/dist/node/config.js.map +1 -0
  110. package/dist/node/content.d.ts +16 -0
  111. package/dist/node/content.d.ts.map +1 -0
  112. package/dist/node/content.js +72 -0
  113. package/dist/node/content.js.map +1 -0
  114. package/dist/node/createContentLoader.d.ts +19 -0
  115. package/dist/node/createContentLoader.d.ts.map +1 -0
  116. package/dist/node/createContentLoader.js +11 -0
  117. package/dist/node/createContentLoader.js.map +1 -0
  118. package/dist/node/devCss.d.ts +7 -0
  119. package/dist/node/devCss.d.ts.map +1 -0
  120. package/dist/node/devCss.js +70 -0
  121. package/dist/node/devCss.js.map +1 -0
  122. package/dist/node/devSsr.d.ts +6 -0
  123. package/dist/node/devSsr.d.ts.map +1 -0
  124. package/dist/node/devSsr.js +112 -0
  125. package/dist/node/devSsr.js.map +1 -0
  126. package/dist/node/dynamicRoutes.d.ts +21 -0
  127. package/dist/node/dynamicRoutes.d.ts.map +1 -0
  128. package/dist/node/dynamicRoutes.js +120 -0
  129. package/dist/node/dynamicRoutes.js.map +1 -0
  130. package/dist/node/favicon.d.ts +9 -0
  131. package/dist/node/favicon.d.ts.map +1 -0
  132. package/dist/node/favicon.js +71 -0
  133. package/dist/node/favicon.js.map +1 -0
  134. package/dist/node/feed.d.ts +7 -0
  135. package/dist/node/feed.d.ts.map +1 -0
  136. package/dist/node/feed.js +37 -0
  137. package/dist/node/feed.js.map +1 -0
  138. package/dist/node/hooks.d.ts +9 -0
  139. package/dist/node/hooks.d.ts.map +1 -0
  140. package/dist/node/hooks.js +20 -0
  141. package/dist/node/hooks.js.map +1 -0
  142. package/dist/node/html.d.ts +56 -0
  143. package/dist/node/html.d.ts.map +1 -0
  144. package/dist/node/html.js +222 -0
  145. package/dist/node/html.js.map +1 -0
  146. package/dist/node/index.d.ts +12 -0
  147. package/dist/node/index.d.ts.map +1 -0
  148. package/dist/node/index.js +9 -0
  149. package/dist/node/index.js.map +1 -0
  150. package/dist/node/init.d.ts +12 -0
  151. package/dist/node/init.d.ts.map +1 -0
  152. package/dist/node/init.js +93 -0
  153. package/dist/node/init.js.map +1 -0
  154. package/dist/node/lastUpdated.d.ts +3 -0
  155. package/dist/node/lastUpdated.d.ts.map +1 -0
  156. package/dist/node/lastUpdated.js +24 -0
  157. package/dist/node/lastUpdated.js.map +1 -0
  158. package/dist/node/loadSiteModule.d.ts +2 -0
  159. package/dist/node/loadSiteModule.d.ts.map +1 -0
  160. package/dist/node/loadSiteModule.js +10 -0
  161. package/dist/node/loadSiteModule.js.map +1 -0
  162. package/dist/node/markdown.d.ts +31 -0
  163. package/dist/node/markdown.d.ts.map +1 -0
  164. package/dist/node/markdown.js +508 -0
  165. package/dist/node/markdown.js.map +1 -0
  166. package/dist/node/markdownHeadings.d.ts +12 -0
  167. package/dist/node/markdownHeadings.d.ts.map +1 -0
  168. package/dist/node/markdownHeadings.js +70 -0
  169. package/dist/node/markdownHeadings.js.map +1 -0
  170. package/dist/node/markdownInclude.d.ts +6 -0
  171. package/dist/node/markdownInclude.d.ts.map +1 -0
  172. package/dist/node/markdownInclude.js +74 -0
  173. package/dist/node/markdownInclude.js.map +1 -0
  174. package/dist/node/markdownSnippets.d.ts +32 -0
  175. package/dist/node/markdownSnippets.d.ts.map +1 -0
  176. package/dist/node/markdownSnippets.js +172 -0
  177. package/dist/node/markdownSnippets.js.map +1 -0
  178. package/dist/node/mdx.d.ts +3 -0
  179. package/dist/node/mdx.d.ts.map +1 -0
  180. package/dist/node/mdx.js +9 -0
  181. package/dist/node/mdx.js.map +1 -0
  182. package/dist/node/packageRoot.d.ts +4 -0
  183. package/dist/node/packageRoot.d.ts.map +1 -0
  184. package/dist/node/packageRoot.js +7 -0
  185. package/dist/node/packageRoot.js.map +1 -0
  186. package/dist/node/pageDataLoaders.d.ts +6 -0
  187. package/dist/node/pageDataLoaders.d.ts.map +1 -0
  188. package/dist/node/pageDataLoaders.js +68 -0
  189. package/dist/node/pageDataLoaders.js.map +1 -0
  190. package/dist/node/paths.d.ts +5 -0
  191. package/dist/node/paths.d.ts.map +1 -0
  192. package/dist/node/paths.js +12 -0
  193. package/dist/node/paths.js.map +1 -0
  194. package/dist/node/plugin.d.ts +7 -0
  195. package/dist/node/plugin.d.ts.map +1 -0
  196. package/dist/node/plugin.js +282 -0
  197. package/dist/node/plugin.js.map +1 -0
  198. package/dist/node/resolveDeps.d.ts +5 -0
  199. package/dist/node/resolveDeps.d.ts.map +1 -0
  200. package/dist/node/resolveDeps.js +25 -0
  201. package/dist/node/resolveDeps.js.map +1 -0
  202. package/dist/node/serve.d.ts +6 -0
  203. package/dist/node/serve.d.ts.map +1 -0
  204. package/dist/node/serve.js +41 -0
  205. package/dist/node/serve.js.map +1 -0
  206. package/dist/node/server.d.ts +7 -0
  207. package/dist/node/server.d.ts.map +1 -0
  208. package/dist/node/server.js +55 -0
  209. package/dist/node/server.js.map +1 -0
  210. package/dist/node/siteConfig.d.ts +206 -0
  211. package/dist/node/siteConfig.d.ts.map +1 -0
  212. package/dist/node/siteConfig.js +2 -0
  213. package/dist/node/siteConfig.js.map +1 -0
  214. package/dist/node/tagIndex.d.ts +27 -0
  215. package/dist/node/tagIndex.d.ts.map +1 -0
  216. package/dist/node/tagIndex.js +84 -0
  217. package/dist/node/tagIndex.js.map +1 -0
  218. package/dist/shared/contentChunk.d.ts +4 -0
  219. package/dist/shared/contentChunk.d.ts.map +1 -0
  220. package/dist/shared/contentChunk.js +14 -0
  221. package/dist/shared/contentChunk.js.map +1 -0
  222. package/dist/shared/contentSchema.d.ts +43 -0
  223. package/dist/shared/contentSchema.d.ts.map +1 -0
  224. package/dist/shared/contentSchema.js +44 -0
  225. package/dist/shared/contentSchema.js.map +1 -0
  226. package/dist/shared/deadLinks.d.ts +9 -0
  227. package/dist/shared/deadLinks.d.ts.map +1 -0
  228. package/dist/shared/deadLinks.js +27 -0
  229. package/dist/shared/deadLinks.js.map +1 -0
  230. package/dist/shared/escapeHtml.d.ts +3 -0
  231. package/dist/shared/escapeHtml.d.ts.map +1 -0
  232. package/dist/shared/escapeHtml.js +11 -0
  233. package/dist/shared/escapeHtml.js.map +1 -0
  234. package/dist/shared/index.d.ts +15 -0
  235. package/dist/shared/index.d.ts.map +1 -0
  236. package/dist/shared/index.js +15 -0
  237. package/dist/shared/index.js.map +1 -0
  238. package/dist/shared/locale.d.ts +11 -0
  239. package/dist/shared/locale.d.ts.map +1 -0
  240. package/dist/shared/locale.js +84 -0
  241. package/dist/shared/locale.js.map +1 -0
  242. package/dist/shared/pageChrome.d.ts +80 -0
  243. package/dist/shared/pageChrome.d.ts.map +1 -0
  244. package/dist/shared/pageChrome.js +160 -0
  245. package/dist/shared/pageChrome.js.map +1 -0
  246. package/dist/shared/pageHead.d.ts +3 -0
  247. package/dist/shared/pageHead.d.ts.map +1 -0
  248. package/dist/shared/pageHead.js +28 -0
  249. package/dist/shared/pageHead.js.map +1 -0
  250. package/dist/shared/pageMeta.d.ts +60 -0
  251. package/dist/shared/pageMeta.d.ts.map +1 -0
  252. package/dist/shared/pageMeta.js +72 -0
  253. package/dist/shared/pageMeta.js.map +1 -0
  254. package/dist/shared/rewrites.d.ts +5 -0
  255. package/dist/shared/rewrites.d.ts.map +1 -0
  256. package/dist/shared/rewrites.js +23 -0
  257. package/dist/shared/rewrites.js.map +1 -0
  258. package/dist/shared/route.d.ts +5 -0
  259. package/dist/shared/route.d.ts.map +1 -0
  260. package/dist/shared/route.js +15 -0
  261. package/dist/shared/route.js.map +1 -0
  262. package/dist/shared/search.d.ts +39 -0
  263. package/dist/shared/search.d.ts.map +1 -0
  264. package/dist/shared/search.js +63 -0
  265. package/dist/shared/search.js.map +1 -0
  266. package/dist/shared/sidebar.d.ts +18 -0
  267. package/dist/shared/sidebar.d.ts.map +1 -0
  268. package/dist/shared/sidebar.js +51 -0
  269. package/dist/shared/sidebar.js.map +1 -0
  270. package/dist/shared/slug.d.ts +4 -0
  271. package/dist/shared/slug.d.ts.map +1 -0
  272. package/dist/shared/slug.js +21 -0
  273. package/dist/shared/slug.js.map +1 -0
  274. package/dist/shared/socialIcons.d.ts +13 -0
  275. package/dist/shared/socialIcons.d.ts.map +1 -0
  276. package/dist/shared/socialIcons.js +27 -0
  277. package/dist/shared/socialIcons.js.map +1 -0
  278. package/dist/shared/tags.d.ts +6 -0
  279. package/dist/shared/tags.d.ts.map +1 -0
  280. package/dist/shared/tags.js +39 -0
  281. package/dist/shared/tags.js.map +1 -0
  282. package/dist/shared/theme.d.ts +8 -0
  283. package/dist/shared/theme.d.ts.map +1 -0
  284. package/dist/shared/theme.js +25 -0
  285. package/dist/shared/theme.js.map +1 -0
  286. package/dist/shared/themeLabels.d.ts +18 -0
  287. package/dist/shared/themeLabels.d.ts.map +1 -0
  288. package/dist/shared/themeLabels.js +51 -0
  289. package/dist/shared/themeLabels.js.map +1 -0
  290. package/dist/shared/url.d.ts +7 -0
  291. package/dist/shared/url.d.ts.map +1 -0
  292. package/dist/shared/url.js +10 -0
  293. package/dist/shared/url.js.map +1 -0
  294. package/package.json +108 -0
  295. package/src/client/app.tsx +194 -0
  296. package/src/client/entry-client.tsx +27 -0
  297. package/src/client/entry-ssr.tsx +77 -0
  298. package/src/client/index.ts +2 -0
  299. package/src/client/loadPage.ts +68 -0
  300. package/src/client/prefetchLinks.ts +60 -0
  301. package/src/client/theme-default/AlgoliaSearch.tsx +89 -0
  302. package/src/client/theme-default/Features.tsx +75 -0
  303. package/src/client/theme-default/Hero.tsx +60 -0
  304. package/src/client/theme-default/Layout.tsx +525 -0
  305. package/src/client/theme-default/Logo.tsx +104 -0
  306. package/src/client/theme-default/NavLinks.tsx +65 -0
  307. package/src/client/theme-default/SidebarNav.tsx +103 -0
  308. package/src/client/theme-default/SocialLinks.tsx +41 -0
  309. package/src/client/theme-default/ThemeToggle.tsx +79 -0
  310. package/src/client/theme-default/index.ts +1 -0
  311. package/src/client/theme-default/styles.css +1450 -0
  312. package/src/client/types.ts +37 -0
  313. package/src/client/usePageHead.ts +212 -0
  314. package/src/client/useSiteSearch.ts +57 -0
  315. package/src/client/virtual.d.ts +103 -0
  316. package/src/shared/contentChunk.ts +14 -0
  317. package/src/shared/contentSchema.ts +85 -0
  318. package/src/shared/deadLinks.ts +33 -0
  319. package/src/shared/escapeHtml.ts +11 -0
  320. package/src/shared/index.ts +83 -0
  321. package/src/shared/locale.ts +116 -0
  322. package/src/shared/pageChrome.ts +244 -0
  323. package/src/shared/pageHead.ts +26 -0
  324. package/src/shared/pageMeta.ts +136 -0
  325. package/src/shared/rewrites.ts +35 -0
  326. package/src/shared/route.ts +14 -0
  327. package/src/shared/search.ts +105 -0
  328. package/src/shared/sidebar.ts +67 -0
  329. package/src/shared/slug.ts +23 -0
  330. package/src/shared/socialIcons.ts +44 -0
  331. package/src/shared/tags.ts +36 -0
  332. package/src/shared/theme.ts +26 -0
  333. package/src/shared/themeLabels.ts +72 -0
  334. package/src/shared/url.ts +14 -0
  335. package/templates/default/.preactpress/config.ts +31 -0
  336. package/templates/default/README.md +45 -0
  337. package/templates/default/about.md +11 -0
  338. package/templates/default/guide/first-five-minutes.md +83 -0
  339. package/templates/default/index.html +18 -0
  340. package/templates/default/index.md +55 -0
  341. package/templates/default/package.json +15 -0
  342. package/templates/default/pnpm-lock.yaml +2917 -0
  343. package/templates/docs/.preactpress/config.ts +94 -0
  344. package/templates/docs/README.md +21 -0
  345. package/templates/docs/about.md +10 -0
  346. package/templates/docs/components/Counter.tsx +25 -0
  347. package/templates/docs/de/guide/getting-started.md +19 -0
  348. package/templates/docs/de/guide/what-is-preactpress.md +15 -0
  349. package/templates/docs/de/index.md +23 -0
  350. package/templates/docs/dist/404.html +29 -0
  351. package/templates/docs/dist/about/index.html +32 -0
  352. package/templates/docs/dist/assets/esm-DzlBxN5p.js +110 -0
  353. package/templates/docs/dist/assets/interactive-64o6YwrR.js +9 -0
  354. package/templates/docs/dist/assets/interactive-BedCloEw.js +9 -0
  355. package/templates/docs/dist/assets/main-BVLeh8GO.js +1 -0
  356. package/templates/docs/dist/assets/main-CreUBb3N.js +1 -0
  357. package/templates/docs/dist/assets/main-oodK-zZy.css +2 -0
  358. package/templates/docs/dist/de/guide/getting-started/index.html +36 -0
  359. package/templates/docs/dist/de/guide/what-is-preactpress/index.html +38 -0
  360. package/templates/docs/dist/de/index.html +29 -0
  361. package/templates/docs/dist/favicon-32.png +0 -0
  362. package/templates/docs/dist/favicon.png +0 -0
  363. package/templates/docs/dist/favicon.svg +28 -0
  364. package/templates/docs/dist/guide/advanced/index.html +53 -0
  365. package/templates/docs/dist/guide/commands/index.html +89 -0
  366. package/templates/docs/dist/guide/configuration/index.html +196 -0
  367. package/templates/docs/dist/guide/creating-pages/index.html +234 -0
  368. package/templates/docs/dist/guide/custom-themes/index.html +52 -0
  369. package/templates/docs/dist/guide/default-theme/index.html +53 -0
  370. package/templates/docs/dist/guide/deploy/index.html +195 -0
  371. package/templates/docs/dist/guide/first-five-minutes/index.html +99 -0
  372. package/templates/docs/dist/guide/getting-started/index.html +173 -0
  373. package/templates/docs/dist/guide/markdown-and-mdx/index.html +59 -0
  374. package/templates/docs/dist/guide/routing/index.html +192 -0
  375. package/templates/docs/dist/guide/what-is-preactpress/index.html +141 -0
  376. package/templates/docs/dist/index.html +30 -0
  377. package/templates/docs/dist/interactive/index.html +37 -0
  378. package/templates/docs/dist/markdown-examples/index.html +231 -0
  379. package/templates/docs/dist/preactpress-content/404.json +8 -0
  380. package/templates/docs/dist/preactpress-content/_index.json +50 -0
  381. package/templates/docs/dist/preactpress-content/about.json +15 -0
  382. package/templates/docs/dist/preactpress-content/de.json +45 -0
  383. package/templates/docs/dist/preactpress-content/de__guide__getting-started.json +26 -0
  384. package/templates/docs/dist/preactpress-content/de__guide__what-is-preactpress.json +21 -0
  385. package/templates/docs/dist/preactpress-content/guide__advanced.json +46 -0
  386. package/templates/docs/dist/preactpress-content/guide__commands.json +26 -0
  387. package/templates/docs/dist/preactpress-content/guide__configuration.json +51 -0
  388. package/templates/docs/dist/preactpress-content/guide__creating-pages.json +71 -0
  389. package/templates/docs/dist/preactpress-content/guide__custom-themes.json +15 -0
  390. package/templates/docs/dist/preactpress-content/guide__default-theme.json +36 -0
  391. package/templates/docs/dist/preactpress-content/guide__deploy.json +56 -0
  392. package/templates/docs/dist/preactpress-content/guide__first-five-minutes.json +36 -0
  393. package/templates/docs/dist/preactpress-content/guide__getting-started.json +51 -0
  394. package/templates/docs/dist/preactpress-content/guide__markdown-and-mdx.json +31 -0
  395. package/templates/docs/dist/preactpress-content/guide__routing.json +71 -0
  396. package/templates/docs/dist/preactpress-content/guide__what-is-preactpress.json +51 -0
  397. package/templates/docs/dist/preactpress-content/markdown-examples.json +71 -0
  398. package/templates/docs/dist/preactpress-content/tags__markdown.json +16 -0
  399. package/templates/docs/dist/preactpress-search.json +166 -0
  400. package/templates/docs/dist/preactpress-theme.js +1 -0
  401. package/templates/docs/dist/tags/markdown/index.html +32 -0
  402. package/templates/docs/guide/advanced.md +44 -0
  403. package/templates/docs/guide/commands.md +41 -0
  404. package/templates/docs/guide/configuration.md +130 -0
  405. package/templates/docs/guide/creating-pages.md +171 -0
  406. package/templates/docs/guide/custom-themes.md +39 -0
  407. package/templates/docs/guide/default-theme.md +41 -0
  408. package/templates/docs/guide/deploy.md +197 -0
  409. package/templates/docs/guide/first-five-minutes.md +82 -0
  410. package/templates/docs/guide/getting-started.md +146 -0
  411. package/templates/docs/guide/markdown-and-mdx.md +59 -0
  412. package/templates/docs/guide/routing.md +263 -0
  413. package/templates/docs/guide/what-is-preactpress.md +87 -0
  414. package/templates/docs/index.html +18 -0
  415. package/templates/docs/index.md +28 -0
  416. package/templates/docs/interactive.mdx +32 -0
  417. package/templates/docs/markdown-examples.md +72 -0
  418. package/templates/docs/package.json +15 -0
  419. package/templates/docs/partials/shared-note.md +3 -0
  420. package/templates/docs/parts/include-body.md +9 -0
  421. package/templates/docs/pnpm-lock.yaml +2917 -0
  422. package/templates/docs/snippets/greet.ts +3 -0
  423. package/templates/hono/.preactpress/config.ts +100 -0
  424. package/templates/hono/.preactpress/theme/CodeSnippet.tsx +41 -0
  425. package/templates/hono/.preactpress/theme/FeatureGrid.tsx +27 -0
  426. package/templates/hono/.preactpress/theme/Hero.tsx +45 -0
  427. package/templates/hono/.preactpress/theme/Layout.tsx +388 -0
  428. package/templates/hono/.preactpress/theme/Logo.tsx +26 -0
  429. package/templates/hono/.preactpress/theme/ThemeToggle.tsx +72 -0
  430. package/templates/hono/.preactpress/theme/hono.css +1058 -0
  431. package/templates/hono/README.md +41 -0
  432. package/templates/hono/about.md +10 -0
  433. package/templates/hono/components/Counter.tsx +25 -0
  434. package/templates/hono/de/about.md +10 -0
  435. package/templates/hono/de/guide/commands.md +44 -0
  436. package/templates/hono/de/guide/configuration.md +64 -0
  437. package/templates/hono/de/guide/deploy.md +197 -0
  438. package/templates/hono/de/guide/first-five-minutes.md +82 -0
  439. package/templates/hono/de/guide/getting-started.md +146 -0
  440. package/templates/hono/de/guide/routing.md +220 -0
  441. package/templates/hono/de/guide/seiten-erstellen.md +171 -0
  442. package/templates/hono/de/guide/what-is-preactpress.md +87 -0
  443. package/templates/hono/de/index.mdx +51 -0
  444. package/templates/hono/de/interactive.mdx +32 -0
  445. package/templates/hono/de/markdown-examples.md +142 -0
  446. package/templates/hono/de/parts/include-body.md +9 -0
  447. package/templates/hono/de/snippets/greet.ts +3 -0
  448. package/templates/hono/dist/404.html +29 -0
  449. package/templates/hono/dist/README/index.html +104 -0
  450. package/templates/hono/dist/about/index.html +32 -0
  451. package/templates/hono/dist/assets/Counter-CCEByS-J.js +1 -0
  452. package/templates/hono/dist/assets/Hero--o6WMNvm.js +2 -0
  453. package/templates/hono/dist/assets/de-D5r6Ye70.js +10 -0
  454. package/templates/hono/dist/assets/hono-BXWYYdyv.js +10 -0
  455. package/templates/hono/dist/assets/interactive-Bxo-WBpC.js +9 -0
  456. package/templates/hono/dist/assets/interactive-BznI4IQ3.js +9 -0
  457. package/templates/hono/dist/assets/main-Bqi-VFEk.js +2 -0
  458. package/templates/hono/dist/assets/main-DIIN7FO0.css +1 -0
  459. package/templates/hono/dist/de/about/index.html +32 -0
  460. package/templates/hono/dist/de/guide/commands/index.html +41 -0
  461. package/templates/hono/dist/de/guide/configuration/index.html +105 -0
  462. package/templates/hono/dist/de/guide/deploy/index.html +195 -0
  463. package/templates/hono/dist/de/guide/first-five-minutes/index.html +99 -0
  464. package/templates/hono/dist/de/guide/getting-started/index.html +173 -0
  465. package/templates/hono/dist/de/guide/routing/index.html +165 -0
  466. package/templates/hono/dist/de/guide/seiten-erstellen/index.html +234 -0
  467. package/templates/hono/dist/de/guide/what-is-preactpress/index.html +141 -0
  468. package/templates/hono/dist/de/index.html +30 -0
  469. package/templates/hono/dist/de/interactive/index.html +37 -0
  470. package/templates/hono/dist/de/markdown-examples/index.html +97 -0
  471. package/templates/hono/dist/de/parts/include-body/index.html +36 -0
  472. package/templates/hono/dist/de/tags/markdown/index.html +32 -0
  473. package/templates/hono/dist/favicon-32.png +0 -0
  474. package/templates/hono/dist/favicon.png +0 -0
  475. package/templates/hono/dist/favicon.svg +28 -0
  476. package/templates/hono/dist/guide/commands/index.html +41 -0
  477. package/templates/hono/dist/guide/configuration/index.html +158 -0
  478. package/templates/hono/dist/guide/creating-pages/index.html +234 -0
  479. package/templates/hono/dist/guide/deploy/index.html +195 -0
  480. package/templates/hono/dist/guide/first-five-minutes/index.html +99 -0
  481. package/templates/hono/dist/guide/getting-started/index.html +173 -0
  482. package/templates/hono/dist/guide/routing/index.html +165 -0
  483. package/templates/hono/dist/guide/what-is-preactpress/index.html +141 -0
  484. package/templates/hono/dist/index.html +30 -0
  485. package/templates/hono/dist/interactive/index.html +37 -0
  486. package/templates/hono/dist/markdown-examples/index.html +105 -0
  487. package/templates/hono/dist/partials/shared-note/index.html +30 -0
  488. package/templates/hono/dist/parts/include-body/index.html +36 -0
  489. package/templates/hono/dist/preactpress-content/404.json +8 -0
  490. package/templates/hono/dist/preactpress-content/README.json +26 -0
  491. package/templates/hono/dist/preactpress-content/about.json +15 -0
  492. package/templates/hono/dist/preactpress-content/de__about.json +15 -0
  493. package/templates/hono/dist/preactpress-content/de__guide__commands.json +36 -0
  494. package/templates/hono/dist/preactpress-content/de__guide__configuration.json +41 -0
  495. package/templates/hono/dist/preactpress-content/de__guide__deploy.json +56 -0
  496. package/templates/hono/dist/preactpress-content/de__guide__first-five-minutes.json +36 -0
  497. package/templates/hono/dist/preactpress-content/de__guide__getting-started.json +51 -0
  498. package/templates/hono/dist/preactpress-content/de__guide__routing.json +61 -0
  499. package/templates/hono/dist/preactpress-content/de__guide__seiten-erstellen.json +71 -0
  500. package/templates/hono/dist/preactpress-content/de__guide__what-is-preactpress.json +51 -0
  501. package/templates/hono/dist/preactpress-content/de__markdown-examples.json +131 -0
  502. package/templates/hono/dist/preactpress-content/de__parts__include-body.json +16 -0
  503. package/templates/hono/dist/preactpress-content/de__tags__markdown.json +16 -0
  504. package/templates/hono/dist/preactpress-content/guide__commands.json +36 -0
  505. package/templates/hono/dist/preactpress-content/guide__configuration.json +51 -0
  506. package/templates/hono/dist/preactpress-content/guide__creating-pages.json +71 -0
  507. package/templates/hono/dist/preactpress-content/guide__deploy.json +56 -0
  508. package/templates/hono/dist/preactpress-content/guide__first-five-minutes.json +36 -0
  509. package/templates/hono/dist/preactpress-content/guide__getting-started.json +51 -0
  510. package/templates/hono/dist/preactpress-content/guide__routing.json +61 -0
  511. package/templates/hono/dist/preactpress-content/guide__what-is-preactpress.json +51 -0
  512. package/templates/hono/dist/preactpress-content/markdown-examples.json +141 -0
  513. package/templates/hono/dist/preactpress-content/partials__shared-note.json +10 -0
  514. package/templates/hono/dist/preactpress-content/parts__include-body.json +16 -0
  515. package/templates/hono/dist/preactpress-content/tags__markdown.json +16 -0
  516. package/templates/hono/dist/preactpress-search.json +242 -0
  517. package/templates/hono/dist/preactpress-theme.js +1 -0
  518. package/templates/hono/dist/tags/markdown/index.html +32 -0
  519. package/templates/hono/guide/commands.md +44 -0
  520. package/templates/hono/guide/configuration.md +177 -0
  521. package/templates/hono/guide/creating-pages.md +171 -0
  522. package/templates/hono/guide/deploy.md +197 -0
  523. package/templates/hono/guide/first-five-minutes.md +82 -0
  524. package/templates/hono/guide/getting-started.md +146 -0
  525. package/templates/hono/guide/routing.md +263 -0
  526. package/templates/hono/guide/what-is-preactpress.md +87 -0
  527. package/templates/hono/index.html +18 -0
  528. package/templates/hono/index.mdx +51 -0
  529. package/templates/hono/interactive.mdx +32 -0
  530. package/templates/hono/markdown-examples.md +160 -0
  531. package/templates/hono/package.json +15 -0
  532. package/templates/hono/partials/shared-note.md +3 -0
  533. package/templates/hono/parts/include-body.md +9 -0
  534. package/templates/hono/pnpm-lock.yaml +2917 -0
  535. package/templates/hono/snippets/greet.ts +3 -0
  536. package/templates/magazine/.preactpress/config.ts +36 -0
  537. package/templates/magazine/.preactpress/theme/Layout.tsx +319 -0
  538. package/templates/magazine/.preactpress/theme/TeaserGrid.tsx +39 -0
  539. package/templates/magazine/.preactpress/theme/ThemeToggle.tsx +73 -0
  540. package/templates/magazine/.preactpress/theme/magazine.css +587 -0
  541. package/templates/magazine/article-markets.md +24 -0
  542. package/templates/magazine/article-tech.mdx +35 -0
  543. package/templates/magazine/index.data.ts +19 -0
  544. package/templates/magazine/index.html +14 -0
  545. package/templates/magazine/index.mdx +13 -0
  546. package/templates/magazine/package.json +15 -0
@@ -0,0 +1,116 @@
1
+ import type {
2
+ LocaleConfig,
3
+ ResolvedI18n,
4
+ ResolvedLocale,
5
+ SiteData,
6
+ ThemeConfig
7
+ } from '../node/siteConfig.js'
8
+ import { normalizeRoute } from './route.js'
9
+
10
+ export function resolveLocales(
11
+ userLocales: Record<string, LocaleConfig> | undefined,
12
+ site: SiteData,
13
+ themeConfig: ThemeConfig
14
+ ): ResolvedI18n | undefined {
15
+ const entries = Object.entries(userLocales ?? {})
16
+ if (entries.length === 0) return undefined
17
+
18
+ const defaultLocaleKey = userLocales?.root ? 'root' : entries[0][0]
19
+ const locales = entries.map(([key, locale]) => {
20
+ const prefix = localePrefixForKey(key)
21
+ const link = locale.link ?? `${prefix || ''}/`
22
+ const lang = locale.lang ?? (key === 'root' ? site.lang : key)
23
+ const localeSite = {
24
+ ...site,
25
+ title: locale.title ?? site.title,
26
+ description: locale.description ?? site.description,
27
+ lang
28
+ }
29
+
30
+ return {
31
+ key,
32
+ label: locale.label,
33
+ lang,
34
+ link,
35
+ prefix,
36
+ site: localeSite,
37
+ themeConfig: {
38
+ ...themeConfig,
39
+ ...(locale.themeConfig ?? {})
40
+ }
41
+ }
42
+ })
43
+
44
+ return { defaultLocaleKey, locales }
45
+ }
46
+
47
+ export function localePrefixForKey(key: string): string {
48
+ return key === 'root' ? '' : normalizeRoute(`/${key}`)
49
+ }
50
+
51
+ export function localeFromRoute(
52
+ route: string,
53
+ i18n: ResolvedI18n | undefined
54
+ ): ResolvedLocale | undefined {
55
+ if (!i18n) return undefined
56
+ const normalized = normalizeRoute(route)
57
+ const prefixed = [...i18n.locales]
58
+ .filter((locale) => locale.prefix)
59
+ .sort((a, b) => b.prefix.length - a.prefix.length)
60
+ const match = prefixed.find(
61
+ (locale) => normalized === locale.prefix || normalized.startsWith(`${locale.prefix}/`)
62
+ )
63
+ if (match) return match
64
+ return i18n.locales.find((locale) => locale.key === i18n.defaultLocaleKey) ?? i18n.locales[0]
65
+ }
66
+
67
+ export function stripLocalePrefix(route: string, locale: ResolvedLocale | undefined): string {
68
+ const normalized = normalizeRoute(route)
69
+ if (!locale?.prefix) return normalized
70
+ if (normalized === locale.prefix) return '/'
71
+ if (normalized.startsWith(`${locale.prefix}/`)) {
72
+ return normalizeRoute(normalized.slice(locale.prefix.length))
73
+ }
74
+ return normalized
75
+ }
76
+
77
+ export function routePathKey(route: string, i18n: ResolvedI18n | undefined): string {
78
+ return stripLocalePrefix(route, localeFromRoute(route, i18n))
79
+ }
80
+
81
+ export function localizeRoute(pathKey: string, locale: ResolvedLocale): string {
82
+ const normalized = normalizeRoute(pathKey)
83
+ if (!locale.prefix) return normalized
84
+ return normalized === '/' ? locale.prefix : normalizeRoute(`${locale.prefix}${normalized}`)
85
+ }
86
+
87
+ export function localizedRouteForLocale(
88
+ route: string,
89
+ targetLocale: ResolvedLocale,
90
+ i18n: ResolvedI18n | undefined,
91
+ availableRoutes?: ReadonlySet<string>
92
+ ): string {
93
+ const pathKey = routePathKey(route, i18n)
94
+ const localized = localizeRoute(pathKey, targetLocale)
95
+ if (!availableRoutes || availableRoutes.has(localized)) return localized
96
+ return normalizeRoute(targetLocale.link)
97
+ }
98
+
99
+ export function siteForRoute(
100
+ site: SiteData,
101
+ route: string,
102
+ i18n: ResolvedI18n | undefined
103
+ ): SiteData {
104
+ const localeSite = localeFromRoute(route, i18n)?.site
105
+ if (!localeSite) return site
106
+ // `base` is a deployment setting; locale copies are resolved before CLI overrides.
107
+ return { ...localeSite, base: site.base }
108
+ }
109
+
110
+ export function themeConfigForRoute(
111
+ themeConfig: ThemeConfig,
112
+ route: string,
113
+ i18n: ResolvedI18n | undefined
114
+ ): ThemeConfig {
115
+ return localeFromRoute(route, i18n)?.themeConfig ?? themeConfig
116
+ }
@@ -0,0 +1,244 @@
1
+ import { pageLayoutFromMeta, type PageLayout } from './pageMeta.js'
2
+
3
+ export type PageAside = boolean | 'left'
4
+ export type PageOutlineConfig = number | [number, number] | 'deep' | false
5
+ export type PageOutlineLevels = [number, number] | false
6
+
7
+ export type ThemeableImage =
8
+ | string
9
+ | { src: string; alt?: string }
10
+ | { light: string; dark: string; alt?: string }
11
+
12
+ export interface HeroAction {
13
+ theme: 'brand' | 'alt'
14
+ text: string
15
+ link: string
16
+ target?: string
17
+ rel?: string
18
+ }
19
+
20
+ export interface Hero {
21
+ name?: string
22
+ text?: string
23
+ tagline?: string
24
+ image?: ThemeableImage
25
+ actions: HeroAction[]
26
+ }
27
+
28
+ export type FeatureIcon =
29
+ | string
30
+ | { src: string; alt?: string; width?: string; height?: string }
31
+ | { light: string; dark: string; alt?: string; width?: string; height?: string }
32
+
33
+ export interface Feature {
34
+ icon?: FeatureIcon
35
+ title: string
36
+ details: string
37
+ link?: string
38
+ linkText?: string
39
+ rel?: string
40
+ target?: string
41
+ }
42
+
43
+ export interface PageChromeThemeConfig {
44
+ outline?: boolean | PageOutlineConfig
45
+ footer?: string
46
+ editLink?: unknown
47
+ lastUpdated?: boolean
48
+ }
49
+
50
+ export interface ResolvedPageChrome {
51
+ layout: PageLayout
52
+ isHome: boolean
53
+ showNavbar: boolean
54
+ showSidebar: boolean
55
+ aside: PageAside
56
+ showAside: boolean
57
+ outlineLevels: PageOutlineLevels
58
+ showPager: boolean
59
+ showFooter: boolean
60
+ showEditLink: boolean
61
+ showLastUpdated: boolean
62
+ pageClass?: string
63
+ markdownStyles: boolean
64
+ hero?: Hero
65
+ features: Feature[]
66
+ }
67
+
68
+ export interface OutlineHeading {
69
+ id: string
70
+ text: string
71
+ level: number
72
+ }
73
+
74
+ export function resolvePageChrome(
75
+ meta: Record<string, unknown> | undefined,
76
+ themeConfig: PageChromeThemeConfig = {}
77
+ ): ResolvedPageChrome {
78
+ const layout = pageLayoutFromMeta(meta)
79
+ const isHome = layout === 'home' || meta?.isHome === true
80
+ const aside = resolveAside(meta?.aside, layout === 'doc')
81
+ const outlineLevels = resolveOutlineLevels(meta?.outline, themeConfig.outline)
82
+ const showAside = aside !== false && outlineLevels !== false
83
+
84
+ return {
85
+ layout,
86
+ isHome,
87
+ showNavbar: resolveBoolean(meta?.navbar, true),
88
+ showSidebar: resolveBoolean(meta?.sidebar, layout === 'doc'),
89
+ aside,
90
+ showAside,
91
+ outlineLevels,
92
+ showPager: layout === 'doc',
93
+ showFooter: Boolean(themeConfig.footer) && resolveBoolean(meta?.footer, true),
94
+ showEditLink: Boolean(themeConfig.editLink) && resolveBoolean(meta?.editLink, true),
95
+ showLastUpdated: Boolean(themeConfig.lastUpdated) && resolveBoolean(meta?.lastUpdated, true),
96
+ pageClass: resolveString(meta?.pageClass),
97
+ markdownStyles: layout !== 'page' && meta?.markdownStyles !== false,
98
+ hero: parseHero(meta?.hero),
99
+ features: parseFeatures(meta?.features)
100
+ }
101
+ }
102
+
103
+ export function filterHeadingsForOutline<T extends OutlineHeading>(
104
+ headings: T[],
105
+ levels: PageOutlineLevels
106
+ ): T[] {
107
+ if (levels === false) return []
108
+ const [min, max] = levels
109
+ return headings.filter((heading) => heading.level >= min && heading.level <= max)
110
+ }
111
+
112
+ export function parseHero(value: unknown): Hero | undefined {
113
+ if (!isRecord(value)) return undefined
114
+
115
+ const name = resolveString(value.name)
116
+ const text = resolveString(value.text)
117
+ const tagline = resolveString(value.tagline)
118
+ const image = parseThemeableImage(value.image)
119
+ const actions = Array.isArray(value.actions)
120
+ ? value.actions.map(parseHeroAction).filter((action): action is HeroAction => Boolean(action))
121
+ : []
122
+
123
+ if (!name && !text && !tagline && !image && actions.length === 0) return undefined
124
+
125
+ return { name, text, tagline, image, actions }
126
+ }
127
+
128
+ export function parseFeatures(value: unknown): Feature[] {
129
+ if (!Array.isArray(value)) return []
130
+ return value.map(parseFeature).filter((feature): feature is Feature => Boolean(feature))
131
+ }
132
+
133
+ function parseHeroAction(value: unknown): HeroAction | undefined {
134
+ if (!isRecord(value)) return undefined
135
+ const text = resolveString(value.text)
136
+ const link = resolveString(value.link)
137
+ if (!text || !link) return undefined
138
+
139
+ return {
140
+ theme: value.theme === 'alt' ? 'alt' : 'brand',
141
+ text,
142
+ link,
143
+ target: resolveString(value.target),
144
+ rel: resolveString(value.rel)
145
+ }
146
+ }
147
+
148
+ function parseFeature(value: unknown): Feature | undefined {
149
+ if (!isRecord(value)) return undefined
150
+ const title = resolveString(value.title)
151
+ const details = resolveString(value.details)
152
+ if (!title || !details) return undefined
153
+
154
+ return {
155
+ icon: parseFeatureIcon(value.icon),
156
+ title,
157
+ details,
158
+ link: resolveString(value.link),
159
+ linkText: resolveString(value.linkText),
160
+ rel: resolveString(value.rel),
161
+ target: resolveString(value.target)
162
+ }
163
+ }
164
+
165
+ function parseThemeableImage(value: unknown): ThemeableImage | undefined {
166
+ if (typeof value === 'string' && value.trim()) return value.trim()
167
+ if (!isRecord(value)) return undefined
168
+
169
+ const src = resolveString(value.src)
170
+ if (src) return { src, alt: resolveString(value.alt) }
171
+
172
+ const light = resolveString(value.light)
173
+ const dark = resolveString(value.dark)
174
+ if (light && dark) return { light, dark, alt: resolveString(value.alt) }
175
+
176
+ return undefined
177
+ }
178
+
179
+ function parseFeatureIcon(value: unknown): FeatureIcon | undefined {
180
+ if (typeof value === 'string' && value.trim()) return value.trim()
181
+ if (!isRecord(value)) return undefined
182
+
183
+ const width = resolveString(value.width)
184
+ const height = resolveString(value.height)
185
+ const src = resolveString(value.src)
186
+ if (src) return { src, alt: resolveString(value.alt), width, height }
187
+
188
+ const light = resolveString(value.light)
189
+ const dark = resolveString(value.dark)
190
+ if (light && dark) {
191
+ return { light, dark, alt: resolveString(value.alt), width, height }
192
+ }
193
+
194
+ return undefined
195
+ }
196
+
197
+ function resolveAside(value: unknown, defaultValue: boolean): PageAside {
198
+ if (value === 'left') return 'left'
199
+ if (typeof value === 'boolean') return value
200
+ return defaultValue
201
+ }
202
+
203
+ function resolveOutlineLevels(
204
+ pageValue: unknown,
205
+ siteValue: PageChromeThemeConfig['outline']
206
+ ): PageOutlineLevels {
207
+ const pageLevels = parseOutlineLevels(pageValue)
208
+ if (pageLevels !== undefined) return pageLevels
209
+
210
+ if (siteValue === false) return false
211
+ return parseOutlineLevels(siteValue) ?? [2, 3]
212
+ }
213
+
214
+ function parseOutlineLevels(value: unknown): PageOutlineLevels | undefined {
215
+ if (value === false) return false
216
+ if (value === 'deep') return [2, 6]
217
+ if (typeof value === 'number') return normalizeOutlineRange(value, value)
218
+ if (Array.isArray(value) && value.length === 2) {
219
+ const [min, max] = value
220
+ if (typeof min === 'number' && typeof max === 'number') {
221
+ return normalizeOutlineRange(min, max)
222
+ }
223
+ }
224
+ return undefined
225
+ }
226
+
227
+ function normalizeOutlineRange(min: number, max: number): PageOutlineLevels | undefined {
228
+ if (!Number.isFinite(min) || !Number.isFinite(max)) return undefined
229
+ const start = Math.max(1, Math.min(6, Math.trunc(min)))
230
+ const end = Math.max(1, Math.min(6, Math.trunc(max)))
231
+ return start <= end ? [start, end] : [end, start]
232
+ }
233
+
234
+ function resolveBoolean(value: unknown, defaultValue: boolean): boolean {
235
+ return typeof value === 'boolean' ? value : defaultValue
236
+ }
237
+
238
+ function resolveString(value: unknown): string | undefined {
239
+ return typeof value === 'string' && value.trim() ? value.trim() : undefined
240
+ }
241
+
242
+ function isRecord(value: unknown): value is Record<string, unknown> {
243
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
244
+ }
@@ -0,0 +1,26 @@
1
+ import type { HeadTag } from '../node/siteConfig.js'
2
+
3
+ export function headTagsFromMeta(meta: Record<string, unknown> | undefined): HeadTag[] {
4
+ const raw = meta?.head
5
+ if (!Array.isArray(raw)) return []
6
+
7
+ const tags: HeadTag[] = []
8
+ for (const entry of raw) {
9
+ const tag = parseHeadTag(entry)
10
+ if (tag) tags.push(tag)
11
+ }
12
+ return tags
13
+ }
14
+
15
+ function parseHeadTag(entry: unknown): HeadTag | undefined {
16
+ if (!Array.isArray(entry) || entry.length < 2) return undefined
17
+ const name = entry[0]
18
+ const attrs = entry[1]
19
+ if (name !== 'meta' && name !== 'link' && name !== 'script') return undefined
20
+ if (!attrs || typeof attrs !== 'object') return undefined
21
+ const record = attrs as Record<string, string | boolean | undefined>
22
+ if (entry.length >= 3 && name === 'script') {
23
+ return ['script', record, typeof entry[2] === 'string' ? entry[2] : '']
24
+ }
25
+ return [name, record]
26
+ }
@@ -0,0 +1,136 @@
1
+ import type { Feature, Hero, PageAside, PageOutlineConfig } from './pageChrome.js'
2
+
3
+ export const META_DESCRIPTION_MAX = 155
4
+ export const PAGE_LAYOUTS = ['doc', 'home', 'page'] as const
5
+ export type PageLayout = (typeof PAGE_LAYOUTS)[number]
6
+
7
+ export const DEFAULT_TITLE_TEMPLATE = ':title | :siteTitle'
8
+
9
+ /** Frontmatter and page metadata fields supported by PreactPress pages. */
10
+ export interface PageMetaInput {
11
+ meta?: Record<string, unknown>
12
+ title?: string
13
+ titleTemplate?: string | false
14
+ description?: string
15
+ tags?: string[]
16
+ image?: string
17
+ pageType?: 'website' | 'article'
18
+ layout?: PageLayout
19
+ navbar?: boolean
20
+ sidebar?: boolean
21
+ aside?: PageAside
22
+ outline?: PageOutlineConfig
23
+ footer?: boolean
24
+ editLink?: boolean
25
+ lastUpdated?: boolean
26
+ pageClass?: string
27
+ isHome?: boolean
28
+ markdownStyles?: boolean
29
+ hero?: Hero
30
+ features?: Feature[]
31
+ kind?: 'markdown' | 'mdx'
32
+ html?: string
33
+ }
34
+
35
+ /** Alias for {@link PageMetaInput} — use in themes, hooks, and custom frontmatter helpers. */
36
+ export type PageFrontmatter = PageMetaInput
37
+
38
+ export interface SiteMetaInput {
39
+ title: string
40
+ description: string
41
+ titleTemplate?: string | false
42
+ }
43
+
44
+ export function formatTitleTemplate(
45
+ template: string | false | undefined,
46
+ params: { title?: string; siteTitle: string }
47
+ ): string {
48
+ if (template === false) {
49
+ return params.title?.trim() || params.siteTitle
50
+ }
51
+ const pattern = template?.trim() || DEFAULT_TITLE_TEMPLATE
52
+ if (!params.title?.trim()) return params.siteTitle
53
+ return pattern
54
+ .replace(/:title/g, params.title.trim())
55
+ .replace(/:siteTitle/g, params.siteTitle)
56
+ }
57
+
58
+ export function titleTemplateFromMeta(meta: Record<string, unknown> | undefined): string | false | undefined {
59
+ const value = meta?.titleTemplate
60
+ if (value === false) return false
61
+ return typeof value === 'string' ? value : undefined
62
+ }
63
+
64
+ export function excerptFromHtml(html: string, maxLen = META_DESCRIPTION_MAX): string {
65
+ const text = html
66
+ .replace(/<[^>]+>/g, ' ')
67
+ .replace(/&[a-z0-9#]+;/gi, ' ')
68
+ .replace(/\s+/g, ' ')
69
+ .trim()
70
+ if (!text) return ''
71
+ if (text.length <= maxLen) return text
72
+ const cut = text.slice(0, maxLen)
73
+ const lastSpace = cut.lastIndexOf(' ')
74
+ const trimmed = (lastSpace > 40 ? cut.slice(0, lastSpace) : cut).trim()
75
+ return `${trimmed}…`
76
+ }
77
+
78
+ export function resolvePageMeta(
79
+ page: PageMetaInput | undefined,
80
+ site: SiteMetaInput
81
+ ): { title: string; description: string } {
82
+ const { title, description } = resolvePageHeadMeta(page, site)
83
+ return { title, description }
84
+ }
85
+
86
+ export function resolvePageHeadMeta(
87
+ page: PageMetaInput | undefined,
88
+ site: SiteMetaInput
89
+ ): {
90
+ title: string
91
+ description: string
92
+ tags: string[]
93
+ image?: string
94
+ pageType: 'website' | 'article'
95
+ } {
96
+ const template = page?.titleTemplate ?? site.titleTemplate
97
+ const title = formatTitleTemplate(template, {
98
+ title: page?.title,
99
+ siteTitle: site.title
100
+ })
101
+
102
+ let description =
103
+ (page?.description && String(page.description).trim()) || site.description.trim()
104
+
105
+ if (!description && page?.kind === 'markdown' && page.html) {
106
+ description = excerptFromHtml(page.html)
107
+ }
108
+
109
+ const tags = page?.tags?.filter((tag) => tag.trim()).map((tag) => tag.trim()) ?? []
110
+ const image = page?.image?.trim() || undefined
111
+ const pageType = page?.pageType === 'article' ? 'article' : 'website'
112
+
113
+ return { title, description, tags, image, pageType }
114
+ }
115
+
116
+ export function pageImageFromMeta(meta: Record<string, unknown>): string | undefined {
117
+ const value = meta.ogImage ?? meta.image
118
+ return typeof value === 'string' && value.trim() ? value.trim() : undefined
119
+ }
120
+
121
+ export function pageTypeFromMeta(meta: Record<string, unknown>): 'website' | 'article' {
122
+ return meta.type === 'article' ? 'article' : 'website'
123
+ }
124
+
125
+ export function pageLayoutFromMeta(meta: Record<string, unknown> | undefined): PageLayout {
126
+ const value = meta?.layout
127
+ return PAGE_LAYOUTS.includes(value as PageLayout) ? (value as PageLayout) : 'doc'
128
+ }
129
+
130
+ export function isPageLayout(value: unknown): value is PageLayout {
131
+ return PAGE_LAYOUTS.includes(value as PageLayout)
132
+ }
133
+
134
+ export function isDraftPage(meta: Record<string, unknown>): boolean {
135
+ return meta.draft === true
136
+ }
@@ -0,0 +1,35 @@
1
+ import type { ContentFile } from '../node/content.js'
2
+ import { normalizeRoute } from './route.js'
3
+
4
+ export type RouteRewrites = Record<string, string>
5
+
6
+ export function normalizeRewriteRoute(route: string): string {
7
+ return normalizeRoute(route)
8
+ }
9
+
10
+ export function applyRouteRewrites(
11
+ routeToFile: Map<string, ContentFile>,
12
+ rewrites: RouteRewrites
13
+ ): void {
14
+ for (const [aliasRaw, sourceRaw] of Object.entries(rewrites)) {
15
+ const alias = normalizeRewriteRoute(aliasRaw)
16
+ const source = normalizeRewriteRoute(sourceRaw)
17
+ const sourceFile = routeToFile.get(source)
18
+ if (!sourceFile) {
19
+ throw new Error(
20
+ `preactpress: rewrite source route not found: ${sourceRaw} (${source})`
21
+ )
22
+ }
23
+ const existing = routeToFile.get(alias)
24
+ if (existing && existing.file !== sourceFile.file) {
25
+ throw new Error(
26
+ `preactpress: rewrite collision for ${alias}: ${pathLabel(existing)} and ${pathLabel(sourceFile)}`
27
+ )
28
+ }
29
+ routeToFile.set(alias, { ...sourceFile, route: alias })
30
+ }
31
+ }
32
+
33
+ function pathLabel(file: ContentFile): string {
34
+ return file.route === '/' ? '/' : file.route
35
+ }
@@ -0,0 +1,14 @@
1
+ /** Normalize a path or route to a site route (no query/hash, leading slash, no trailing slash except `/`). */
2
+ export function normalizeRoute(route: string): string {
3
+ const clean = route.split(/[?#]/, 1)[0] || '/'
4
+ const prefixed = clean.startsWith('/') ? clean : `/${clean}`
5
+ return prefixed.replace(/\/$/, '') || '/'
6
+ }
7
+
8
+ /** Map a request pathname to a site route using the configured base. */
9
+ export function routeFromPathname(pathname: string, base: string): string {
10
+ const basePath = base === '/' ? '' : base.replace(/\/$/, '')
11
+ let p = pathname
12
+ if (basePath && p.startsWith(basePath)) p = p.slice(basePath.length) || '/'
13
+ return normalizeRoute(p)
14
+ }
@@ -0,0 +1,105 @@
1
+ export type SearchProvider = 'local' | 'algolia'
2
+
3
+ export interface LocalSearchConfig {
4
+ provider: 'local'
5
+ }
6
+
7
+ export interface AlgoliaSearchOptions {
8
+ appId?: string
9
+ apiKey?: string
10
+ indexName?: string
11
+ placeholder?: string
12
+ maxResultsPerGroup?: number
13
+ disableUserPersonalization?: boolean
14
+ initialQuery?: string
15
+ recentSearchesLimit?: number
16
+ recentSearchesWithFavoritesLimit?: number
17
+ insights?: boolean
18
+ searchParameters?: Record<string, unknown>
19
+ /** Locale-specific overrides (merged with root options). */
20
+ locales?: Record<string, Partial<AlgoliaSearchOptions>>
21
+ }
22
+
23
+ export interface AlgoliaSearchConfig {
24
+ provider: 'algolia'
25
+ options: AlgoliaSearchOptions
26
+ }
27
+
28
+ /** `true` keeps local sidebar search; use `{ provider }` for explicit providers. */
29
+ export type SearchConfig = boolean | LocalSearchConfig | AlgoliaSearchConfig
30
+
31
+ export function resolveSearchProvider(search?: SearchConfig): SearchProvider | false {
32
+ if (search === true) return 'local'
33
+ if (search === false || search == null) return false
34
+ return search.provider
35
+ }
36
+
37
+ export function isLocalSearchEnabled(search?: SearchConfig): boolean {
38
+ return resolveSearchProvider(search) === 'local'
39
+ }
40
+
41
+ export function isAlgoliaSearchEnabled(search?: SearchConfig): boolean {
42
+ return resolveSearchProvider(search) === 'algolia'
43
+ }
44
+
45
+ export function algoliaOptionsFromSearch(search?: SearchConfig): AlgoliaSearchOptions | undefined {
46
+ if (typeof search === 'object' && search.provider === 'algolia') return search.options
47
+ return undefined
48
+ }
49
+
50
+ export function resolveAlgoliaOptions(
51
+ options: AlgoliaSearchOptions,
52
+ localeKey?: string
53
+ ): AlgoliaSearchOptions {
54
+ const { locales, ...root } = options
55
+ const override = localeKey && locales?.[localeKey] ? locales[localeKey] : {}
56
+ return {
57
+ ...root,
58
+ ...override,
59
+ searchParameters: override.searchParameters ?? root.searchParameters
60
+ }
61
+ }
62
+
63
+ export function validateAlgoliaCredentials(options: AlgoliaSearchOptions): {
64
+ valid: boolean
65
+ appId?: string
66
+ apiKey?: string
67
+ indexName?: string
68
+ } {
69
+ const appId = options.appId?.trim()
70
+ const apiKey = options.apiKey?.trim()
71
+ const indexName = options.indexName?.trim()
72
+ return {
73
+ valid: Boolean(appId && apiKey && indexName),
74
+ appId,
75
+ apiKey,
76
+ indexName
77
+ }
78
+ }
79
+
80
+ export function getRelativeDocSearchUrl(url: string, base: string, cleanUrls = true): string {
81
+ const { pathname, hash } = new URL(url, 'http://preactpress.local')
82
+ const normalizedBase = base === '/' ? '' : base.replace(/\/$/, '')
83
+ let path = pathname
84
+ if (normalizedBase && path.startsWith(normalizedBase)) {
85
+ path = path.slice(normalizedBase.length) || '/'
86
+ }
87
+ const route = cleanUrls ? path.replace(/\.html$/, '').replace(/\/index$/, '/') || '/' : path
88
+ return `${route}${hash}`
89
+ }
90
+
91
+ export function navigateDocSearchResult(itemUrl: string, base: string): void {
92
+ const url = new URL(itemUrl, window.location.origin)
93
+ const normalizedBase = base === '/' ? '' : base.replace(/\/$/, '')
94
+ const href =
95
+ normalizedBase && !url.pathname.startsWith(normalizedBase)
96
+ ? itemUrl
97
+ : `${normalizedBase}${url.pathname.replace(normalizedBase, '') || '/'}${url.search}${url.hash}`
98
+ if (url.origin !== window.location.origin) {
99
+ window.location.assign(href)
100
+ return
101
+ }
102
+ window.history.pushState({}, '', href)
103
+ window.dispatchEvent(new PopStateEvent('popstate'))
104
+ window.scrollTo({ top: 0 })
105
+ }