@rocket/js 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (340) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +224 -2
  3. package/dist-types/exports/MainMenu.d.ts +2 -0
  4. package/dist-types/exports/MainMenu.d.ts.map +1 -0
  5. package/dist-types/exports/PageData.d.ts +2 -0
  6. package/dist-types/exports/PageData.d.ts.map +1 -0
  7. package/dist-types/exports/RocketCodeBlock.d.ts +2 -0
  8. package/dist-types/exports/RocketCodeBlock.d.ts.map +1 -0
  9. package/dist-types/exports/RocketIcon.d.ts +2 -0
  10. package/dist-types/exports/RocketIcon.d.ts.map +1 -0
  11. package/dist-types/exports/RocketJsDemo.d.ts +2 -0
  12. package/dist-types/exports/RocketJsDemo.d.ts.map +1 -0
  13. package/dist-types/exports/RocketRequestDemo.d.ts +2 -0
  14. package/dist-types/exports/RocketRequestDemo.d.ts.map +1 -0
  15. package/dist-types/exports/SocialPreviewPlayground.d.ts +2 -0
  16. package/dist-types/exports/SocialPreviewPlayground.d.ts.map +1 -0
  17. package/dist-types/exports/adapters/netlify.d.ts +2 -0
  18. package/dist-types/exports/adapters/netlify.d.ts.map +1 -0
  19. package/dist-types/exports/asyncMessage.d.ts +2 -0
  20. package/dist-types/exports/asyncMessage.d.ts.map +1 -0
  21. package/dist-types/exports/component-hydration.d.ts +2 -0
  22. package/dist-types/exports/component-hydration.d.ts.map +1 -0
  23. package/dist-types/exports/components/web-awesome.d.ts +3 -0
  24. package/dist-types/exports/components/web-awesome.d.ts.map +1 -0
  25. package/dist-types/exports/components.d.ts +2 -0
  26. package/dist-types/exports/components.d.ts.map +1 -0
  27. package/dist-types/exports/config.d.ts +2 -0
  28. package/dist-types/exports/config.d.ts.map +1 -0
  29. package/dist-types/exports/debounce.d.ts +2 -0
  30. package/dist-types/exports/debounce.d.ts.map +1 -0
  31. package/dist-types/exports/define/RocketCodeBlock.d.ts +2 -0
  32. package/dist-types/exports/define/RocketCodeBlock.d.ts.map +1 -0
  33. package/dist-types/exports/define/RocketIcon.d.ts +2 -0
  34. package/dist-types/exports/define/RocketIcon.d.ts.map +1 -0
  35. package/dist-types/exports/define/RocketJsDemo.d.ts +2 -0
  36. package/dist-types/exports/define/RocketJsDemo.d.ts.map +1 -0
  37. package/dist-types/exports/define/RocketRequestDemo.d.ts +2 -0
  38. package/dist-types/exports/define/RocketRequestDemo.d.ts.map +1 -0
  39. package/dist-types/exports/define/menus.d.ts +2 -0
  40. package/dist-types/exports/define/menus.d.ts.map +1 -0
  41. package/dist-types/exports/extractCode.d.ts +2 -0
  42. package/dist-types/exports/extractCode.d.ts.map +1 -0
  43. package/dist-types/exports/globalData.d.ts +2 -0
  44. package/dist-types/exports/globalData.d.ts.map +1 -0
  45. package/dist-types/exports/hydration/hydrationLoader.d.ts +2 -0
  46. package/dist-types/exports/hydration/hydrationLoader.d.ts.map +1 -0
  47. package/dist-types/exports/icons.d.ts +2 -0
  48. package/dist-types/exports/icons.d.ts.map +1 -0
  49. package/dist-types/exports/layout-helper.d.ts +2 -0
  50. package/dist-types/exports/layout-helper.d.ts.map +1 -0
  51. package/dist-types/exports/layout.d.ts +2 -0
  52. package/dist-types/exports/layout.d.ts.map +1 -0
  53. package/dist-types/exports/layouts/atlasDoc.d.ts +2 -0
  54. package/dist-types/exports/layouts/atlasDoc.d.ts.map +1 -0
  55. package/dist-types/exports/layouts/atlasHero.d.ts +2 -0
  56. package/dist-types/exports/layouts/atlasHero.d.ts.map +1 -0
  57. package/dist-types/exports/layouts/atlasNotFound.d.ts +2 -0
  58. package/dist-types/exports/layouts/atlasNotFound.d.ts.map +1 -0
  59. package/dist-types/exports/loaded-page-module.d.ts +2 -0
  60. package/dist-types/exports/loaded-page-module.d.ts.map +1 -0
  61. package/dist-types/exports/markdownHook.d.ts +2 -0
  62. package/dist-types/exports/markdownHook.d.ts.map +1 -0
  63. package/dist-types/exports/menu.d.ts +2 -0
  64. package/dist-types/exports/menu.d.ts.map +1 -0
  65. package/dist-types/exports/menus.d.ts +6 -0
  66. package/dist-types/exports/menus.d.ts.map +1 -0
  67. package/dist-types/exports/page-runtime.d.ts +2 -0
  68. package/dist-types/exports/page-runtime.d.ts.map +1 -0
  69. package/dist-types/exports/pages.d.ts +2 -0
  70. package/dist-types/exports/pages.d.ts.map +1 -0
  71. package/dist-types/exports/resolve.d.ts +2 -0
  72. package/dist-types/exports/resolve.d.ts.map +1 -0
  73. package/dist-types/exports/ssr.d.ts +2 -0
  74. package/dist-types/exports/ssr.d.ts.map +1 -0
  75. package/dist-types/exports/standalone-demo-url.d.ts +2 -0
  76. package/dist-types/exports/standalone-demo-url.d.ts.map +1 -0
  77. package/dist-types/exports/transform.d.ts +2 -0
  78. package/dist-types/exports/transform.d.ts.map +1 -0
  79. package/dist-types/exports/types/hydration.d.ts +23 -0
  80. package/dist-types/exports/types/hydration.d.ts.map +1 -0
  81. package/dist-types/exports/types/rocket.d.ts +504 -0
  82. package/dist-types/exports/types/rocket.d.ts.map +1 -0
  83. package/dist-types/exports/types.d.ts +3 -0
  84. package/dist-types/exports/types.d.ts.map +1 -0
  85. package/dist-types/exports/wds-plugin.d.ts +2 -0
  86. package/dist-types/exports/wds-plugin.d.ts.map +1 -0
  87. package/dist-types/src/PageData.d.ts +82 -0
  88. package/dist-types/src/PageData.d.ts.map +1 -0
  89. package/dist-types/src/RocketCodeBlock.d.ts +64 -0
  90. package/dist-types/src/RocketCodeBlock.d.ts.map +1 -0
  91. package/dist-types/src/RocketIcon.d.ts +35 -0
  92. package/dist-types/src/RocketIcon.d.ts.map +1 -0
  93. package/dist-types/src/RocketJsDemo.d.ts +59 -0
  94. package/dist-types/src/RocketJsDemo.d.ts.map +1 -0
  95. package/dist-types/src/RocketJsDemo.test-browser.d.ts +3 -0
  96. package/dist-types/src/RocketJsDemo.test-browser.d.ts.map +1 -0
  97. package/dist-types/src/RocketRequestDemo.d.ts +57 -0
  98. package/dist-types/src/RocketRequestDemo.d.ts.map +1 -0
  99. package/dist-types/src/RocketRequestDemo.test-browser.d.ts +3 -0
  100. package/dist-types/src/RocketRequestDemo.test-browser.d.ts.map +1 -0
  101. package/dist-types/src/SocialPreviewPlayground.d.ts +102 -0
  102. package/dist-types/src/SocialPreviewPlayground.d.ts.map +1 -0
  103. package/dist-types/src/adapters/netlify.d.ts +54 -0
  104. package/dist-types/src/adapters/netlify.d.ts.map +1 -0
  105. package/dist-types/src/asyncMessage.d.ts +14 -0
  106. package/dist-types/src/asyncMessage.d.ts.map +1 -0
  107. package/dist-types/src/cli/RocketBuild.d.ts +78 -0
  108. package/dist-types/src/cli/RocketBuild.d.ts.map +1 -0
  109. package/dist-types/src/cli/RocketCli.d.ts +17 -0
  110. package/dist-types/src/cli/RocketCli.d.ts.map +1 -0
  111. package/dist-types/src/cli/RocketInit.d.ts +22 -0
  112. package/dist-types/src/cli/RocketInit.d.ts.map +1 -0
  113. package/dist-types/src/cli/RocketStart.d.ts +13 -0
  114. package/dist-types/src/cli/RocketStart.d.ts.map +1 -0
  115. package/dist-types/src/cli/cli.d.ts +3 -0
  116. package/dist-types/src/cli/cli.d.ts.map +1 -0
  117. package/dist-types/src/component-hydration.d.ts +26 -0
  118. package/dist-types/src/component-hydration.d.ts.map +1 -0
  119. package/dist-types/src/components/FeatureList.d.ts +15 -0
  120. package/dist-types/src/components/FeatureList.d.ts.map +1 -0
  121. package/dist-types/src/components/Footer.d.ts +17 -0
  122. package/dist-types/src/components/Footer.d.ts.map +1 -0
  123. package/dist-types/src/components/Header.d.ts +6 -0
  124. package/dist-types/src/components/Header.d.ts.map +1 -0
  125. package/dist-types/src/components/RocketDrawer.d.ts +20 -0
  126. package/dist-types/src/components/RocketDrawer.d.ts.map +1 -0
  127. package/dist-types/src/components/RocketSocialLink.d.ts +30 -0
  128. package/dist-types/src/components/RocketSocialLink.d.ts.map +1 -0
  129. package/dist-types/src/components.d.ts +5 -0
  130. package/dist-types/src/components.d.ts.map +1 -0
  131. package/dist-types/src/config.d.ts +6 -0
  132. package/dist-types/src/config.d.ts.map +1 -0
  133. package/dist-types/src/debounce.d.ts +8 -0
  134. package/dist-types/src/debounce.d.ts.map +1 -0
  135. package/dist-types/src/defaultSocialPreviewTemplate.d.ts +31 -0
  136. package/dist-types/src/defaultSocialPreviewTemplate.d.ts.map +1 -0
  137. package/dist-types/src/development-page-module-loader.d.ts +15 -0
  138. package/dist-types/src/development-page-module-loader.d.ts.map +1 -0
  139. package/dist-types/src/extractCode.d.ts +5 -0
  140. package/dist-types/src/extractCode.d.ts.map +1 -0
  141. package/dist-types/src/hydration/evaluate.d.ts +20 -0
  142. package/dist-types/src/hydration/evaluate.d.ts.map +1 -0
  143. package/dist-types/src/hydration/extractStrategies.d.ts +5 -0
  144. package/dist-types/src/hydration/extractStrategies.d.ts.map +1 -0
  145. package/dist-types/src/hydration/hydrationLoader.d.ts +64 -0
  146. package/dist-types/src/hydration/hydrationLoader.d.ts.map +1 -0
  147. package/dist-types/src/icons.d.ts +170 -0
  148. package/dist-types/src/icons.d.ts.map +1 -0
  149. package/dist-types/src/layouts/atlas/atlasDocLayout.d.ts +45 -0
  150. package/dist-types/src/layouts/atlas/atlasDocLayout.d.ts.map +1 -0
  151. package/dist-types/src/layouts/atlas/atlasHeroLayout.d.ts +7 -0
  152. package/dist-types/src/layouts/atlas/atlasHeroLayout.d.ts.map +1 -0
  153. package/dist-types/src/layouts/atlas/atlasNotFoundLayout.d.ts +5 -0
  154. package/dist-types/src/layouts/atlas/atlasNotFoundLayout.d.ts.map +1 -0
  155. package/dist-types/src/layouts/layout-helper.d.ts +16 -0
  156. package/dist-types/src/layouts/layout-helper.d.ts.map +1 -0
  157. package/dist-types/src/layouts/layout.d.ts +9 -0
  158. package/dist-types/src/layouts/layout.d.ts.map +1 -0
  159. package/dist-types/src/loaded-page-module.d.ts +51 -0
  160. package/dist-types/src/loaded-page-module.d.ts.map +1 -0
  161. package/dist-types/src/main.d.ts +2 -0
  162. package/dist-types/src/main.d.ts.map +1 -0
  163. package/dist-types/src/markdownCompiler.d.ts +22 -0
  164. package/dist-types/src/markdownCompiler.d.ts.map +1 -0
  165. package/dist-types/src/markdownHook.d.ts +6 -0
  166. package/dist-types/src/markdownHook.d.ts.map +1 -0
  167. package/dist-types/src/menu.d.ts +22 -0
  168. package/dist-types/src/menu.d.ts.map +1 -0
  169. package/dist-types/src/menus/MainMenu.d.ts +23 -0
  170. package/dist-types/src/menus/MainMenu.d.ts.map +1 -0
  171. package/dist-types/src/menus/RocketMenu.d.ts +23 -0
  172. package/dist-types/src/menus/RocketMenu.d.ts.map +1 -0
  173. package/dist-types/src/menus/RocketNextPage.d.ts +18 -0
  174. package/dist-types/src/menus/RocketNextPage.d.ts.map +1 -0
  175. package/dist-types/src/menus/RocketPreviousPage.d.ts +18 -0
  176. package/dist-types/src/menus/RocketPreviousPage.d.ts.map +1 -0
  177. package/dist-types/src/menus/RocketToc.d.ts +54 -0
  178. package/dist-types/src/menus/RocketToc.d.ts.map +1 -0
  179. package/dist-types/src/menus/pageNavigation.d.ts +41 -0
  180. package/dist-types/src/menus/pageNavigation.d.ts.map +1 -0
  181. package/dist-types/src/page-pagination.d.ts +69 -0
  182. package/dist-types/src/page-pagination.d.ts.map +1 -0
  183. package/dist-types/src/page-runtime.d.ts +110 -0
  184. package/dist-types/src/page-runtime.d.ts.map +1 -0
  185. package/dist-types/src/pages.d.ts +10 -0
  186. package/dist-types/src/pages.d.ts.map +1 -0
  187. package/dist-types/src/publicAssets.d.ts +70 -0
  188. package/dist-types/src/publicAssets.d.ts.map +1 -0
  189. package/dist-types/src/requestDemoMetadata.d.ts +19 -0
  190. package/dist-types/src/requestDemoMetadata.d.ts.map +1 -0
  191. package/dist-types/src/resolve.d.ts +7 -0
  192. package/dist-types/src/resolve.d.ts.map +1 -0
  193. package/dist-types/src/siteDiscoverability.d.ts +33 -0
  194. package/dist-types/src/siteDiscoverability.d.ts.map +1 -0
  195. package/dist-types/src/siteHeadMetadata.d.ts +20 -0
  196. package/dist-types/src/siteHeadMetadata.d.ts.map +1 -0
  197. package/dist-types/src/socialPreviewImages.d.ts +186 -0
  198. package/dist-types/src/socialPreviewImages.d.ts.map +1 -0
  199. package/dist-types/src/socialPreviewTemplatePreview.d.ts +22 -0
  200. package/dist-types/src/socialPreviewTemplatePreview.d.ts.map +1 -0
  201. package/dist-types/src/ssr.d.ts +6 -0
  202. package/dist-types/src/ssr.d.ts.map +1 -0
  203. package/dist-types/src/standalone-demo-url.d.ts +60 -0
  204. package/dist-types/src/standalone-demo-url.d.ts.map +1 -0
  205. package/dist-types/src/static-page-module-loader.d.ts +15 -0
  206. package/dist-types/src/static-page-module-loader.d.ts.map +1 -0
  207. package/dist-types/src/transform.d.ts +10 -0
  208. package/dist-types/src/transform.d.ts.map +1 -0
  209. package/dist-types/src/urlLifecycle.d.ts +23 -0
  210. package/dist-types/src/urlLifecycle.d.ts.map +1 -0
  211. package/dist-types/src/wds-plugin.d.ts +14 -0
  212. package/dist-types/src/wds-plugin.d.ts.map +1 -0
  213. package/docs/assets/home-background.svg +1 -0
  214. package/docs/assets/prism-one-light.css +368 -0
  215. package/docs/assets/rocket-logo-dark-with-text-below.svg +8 -0
  216. package/docs/assets/rocket-logo-dark-with-text.svg +7 -0
  217. package/docs/assets/rocket-logo-dark.svg +7 -0
  218. package/docs/assets/rocket-logo-light-with-text-below.svg +14 -0
  219. package/docs/assets/rocket-logo-light-with-text.svg +13 -0
  220. package/docs/assets/rocket-logo-light.svg +12 -0
  221. package/docs/assets/rocket-text-no-logo.svg +3 -0
  222. package/exports/MainMenu.js +1 -0
  223. package/exports/PageData.js +1 -0
  224. package/exports/RocketCodeBlock.js +1 -0
  225. package/exports/RocketIcon.js +1 -0
  226. package/exports/RocketJsDemo.js +1 -0
  227. package/exports/RocketRequestDemo.js +1 -0
  228. package/exports/SocialPreviewPlayground.js +1 -0
  229. package/exports/adapters/netlify.js +1 -0
  230. package/exports/asyncMessage.js +1 -0
  231. package/exports/component-hydration.js +1 -0
  232. package/exports/components/web-awesome.js +63 -0
  233. package/exports/components.js +1 -0
  234. package/exports/config.js +1 -0
  235. package/exports/debounce.js +1 -0
  236. package/exports/define/RocketCodeBlock.js +2 -0
  237. package/exports/define/RocketIcon.js +3 -0
  238. package/exports/define/RocketJsDemo.js +5 -0
  239. package/exports/define/RocketRequestDemo.js +5 -0
  240. package/exports/define/menus.js +14 -0
  241. package/exports/extractCode.js +1 -0
  242. package/exports/globalData.js +1 -0
  243. package/exports/hydration/hydrationLoader.js +1 -0
  244. package/exports/icons.js +8 -0
  245. package/exports/layout-helper.js +1 -0
  246. package/exports/layout.js +1 -0
  247. package/exports/layouts/_atlas.css +3 -0
  248. package/exports/layouts/atlasDoc.js +5 -0
  249. package/exports/layouts/atlasHero.js +1 -0
  250. package/exports/layouts/atlasNotFound.js +4 -0
  251. package/exports/loaded-page-module.js +5 -0
  252. package/exports/markdownHook.js +4 -0
  253. package/exports/menu.js +4 -0
  254. package/exports/menus.js +5 -0
  255. package/exports/page-runtime.js +5 -0
  256. package/exports/pages.js +1 -0
  257. package/exports/resolve.js +1 -0
  258. package/exports/ssr.js +1 -0
  259. package/exports/standalone-demo-url.js +10 -0
  260. package/exports/transform.js +1 -0
  261. package/exports/types/hydration.ts +26 -0
  262. package/exports/types/rocket.ts +598 -0
  263. package/exports/types.ts +71 -0
  264. package/exports/wds-plugin.js +1 -0
  265. package/package.json +192 -9
  266. package/src/PageData.js +244 -0
  267. package/src/RocketCodeBlock.js +516 -0
  268. package/src/RocketIcon.js +291 -0
  269. package/src/RocketJsDemo.js +397 -0
  270. package/src/RocketJsDemo.test-browser.js +228 -0
  271. package/src/RocketRequestDemo.js +439 -0
  272. package/src/RocketRequestDemo.test-browser.js +301 -0
  273. package/src/SocialPreviewPlayground.js +573 -0
  274. package/src/adapters/netlify.js +814 -0
  275. package/src/asyncMessage.js +21 -0
  276. package/src/cli/RocketBuild.js +545 -0
  277. package/src/cli/RocketCli.js +47 -0
  278. package/src/cli/RocketInit.js +323 -0
  279. package/src/cli/RocketStart.js +79 -0
  280. package/src/cli/cli.js +7 -0
  281. package/src/component-hydration.js +86 -0
  282. package/src/components/FeatureList.js +114 -0
  283. package/src/components/Footer.js +116 -0
  284. package/src/components/Header.js +122 -0
  285. package/src/components/RocketDrawer.js +193 -0
  286. package/src/components/RocketSocialLink.js +128 -0
  287. package/src/components/assets/discord.svg +7 -0
  288. package/src/components/assets/github.svg +4 -0
  289. package/src/components/assets/gitlab.svg +1 -0
  290. package/src/components/assets/info.txt +1 -0
  291. package/src/components/assets/license.svg +3 -0
  292. package/src/components/assets/npm.svg +5 -0
  293. package/src/components/assets/slack.svg +5 -0
  294. package/src/components/assets/telegram.svg +4 -0
  295. package/src/components/assets/twitter.svg +1 -0
  296. package/src/components.js +15 -0
  297. package/src/config.js +319 -0
  298. package/src/debounce.js +21 -0
  299. package/src/defaultSocialPreviewTemplate.js +118 -0
  300. package/src/development-page-module-loader.js +29 -0
  301. package/src/extractCode.js +41 -0
  302. package/src/hydration/evaluate.js +54 -0
  303. package/src/hydration/extractStrategies.js +91 -0
  304. package/src/hydration/hydrationLoader.js +330 -0
  305. package/src/icons.js +883 -0
  306. package/src/layouts/atlas/atlasDoc.css +877 -0
  307. package/src/layouts/atlas/atlasDocLayout.js +288 -0
  308. package/src/layouts/atlas/atlasHero.css +774 -0
  309. package/src/layouts/atlas/atlasHeroLayout.js +346 -0
  310. package/src/layouts/atlas/atlasNotFound.css +365 -0
  311. package/src/layouts/atlas/atlasNotFoundLayout.js +69 -0
  312. package/src/layouts/layout-helper.js +92 -0
  313. package/src/layouts/layout.js +62 -0
  314. package/src/loaded-page-module.js +97 -0
  315. package/src/main.js +55 -0
  316. package/src/markdownCompiler.js +303 -0
  317. package/src/markdownHook.js +148 -0
  318. package/src/menu.js +210 -0
  319. package/src/menus/MainMenu.js +58 -0
  320. package/src/menus/RocketMenu.js +191 -0
  321. package/src/menus/RocketNextPage.js +25 -0
  322. package/src/menus/RocketPreviousPage.js +29 -0
  323. package/src/menus/RocketToc.js +309 -0
  324. package/src/menus/pageNavigation.js +285 -0
  325. package/src/page-pagination.js +241 -0
  326. package/src/page-runtime.js +481 -0
  327. package/src/pages.js +537 -0
  328. package/src/publicAssets.js +336 -0
  329. package/src/requestDemoMetadata.js +97 -0
  330. package/src/resolve.js +15 -0
  331. package/src/siteDiscoverability.js +184 -0
  332. package/src/siteHeadMetadata.js +69 -0
  333. package/src/socialPreviewImages.js +482 -0
  334. package/src/socialPreviewTemplatePreview.js +352 -0
  335. package/src/ssr.js +14 -0
  336. package/src/standalone-demo-url.js +134 -0
  337. package/src/static-page-module-loader.js +29 -0
  338. package/src/transform.js +633 -0
  339. package/src/urlLifecycle.js +57 -0
  340. package/src/wds-plugin.js +302 -0
@@ -0,0 +1,633 @@
1
+ /** Runs on: import-hook */
2
+ import markdown from 'remark-parse';
3
+ import { unified } from 'unified';
4
+ import gfm from 'remark-gfm';
5
+ import remark2rehype from 'remark-rehype';
6
+ import rehypePrism from 'rehype-prism-plus';
7
+ import rawHtml from 'rehype-raw';
8
+ import htmlStringify from 'rehype-stringify';
9
+ import rehypeSlug from 'rehype-slug';
10
+ import rehypeLinkHeadings from 'rehype-autolink-headings';
11
+ import { extractMdCode } from './extractCode.js';
12
+ import { visit } from 'unist-util-visit';
13
+ import { init, parse as parseExports } from 'es-module-lexer';
14
+ import { headLinesToTree } from './menu.js';
15
+ import { parseRequestDemoMetadata } from './requestDemoMetadata.js';
16
+
17
+ /** @type {import('rehype-autolink-headings').Options} */
18
+ const headingAnchorOptions = {
19
+ behavior: 'append',
20
+ properties: {
21
+ className: ['heading-anchor'],
22
+ ariaLabel: 'Link to this heading',
23
+ },
24
+ content: {
25
+ type: 'text',
26
+ value: '#',
27
+ },
28
+ };
29
+
30
+ /**
31
+ * @param {string} md
32
+ */
33
+ export async function mdToJs(md) {
34
+ const result = await unified()
35
+ .use(markdown)
36
+ .use(gfm)
37
+ .use(extractMdCode('server'))
38
+ .use(extractMdCode('client'))
39
+ .use(parseDemos)
40
+ .use(parseRequestDemos)
41
+ .use(captureCodeBlockData)
42
+ .use(escapeRocketMd)
43
+ .use(remark2rehype, { allowDangerousHtml: true })
44
+ // now html
45
+ .use(rawHtml)
46
+ .use(fixImageTags)
47
+ .use(rehypePrism)
48
+ .use(wrapCodeBlocks)
49
+ .use(escapeCodeBlocks)
50
+ .use(rehypeSlug)
51
+ .use(rehypeLinkHeadings, headingAnchorOptions)
52
+ .use(extractHeadings)
53
+
54
+ .use(htmlStringify)
55
+ .process(md);
56
+
57
+ const code = /** @type {{client: string; server: string}} */ (result.data.code);
58
+ const headlines = /** @type {import('@rocket/js/types.js').Headline[]} */ (result.data.headings);
59
+
60
+ const moduleCode = await makeJsFile(
61
+ code.server,
62
+ code.client || '',
63
+ result.value.toString(),
64
+ headlines,
65
+ );
66
+ return moduleCode;
67
+ }
68
+
69
+ /**
70
+ * @param {string} md
71
+ * @param {string} demo
72
+ */
73
+ export async function mdToJsSingleDemo(md, demo) {
74
+ const result = await unified()
75
+ .use(markdown)
76
+ .use(extractMdCode('server'))
77
+ .use(extractMdCode('client'))
78
+ .use(extractSingleDemo, demo)
79
+ .use(captureCodeBlockData)
80
+ .use(remark2rehype, { allowDangerousHtml: true })
81
+ // now html
82
+ .use(rawHtml)
83
+ .use(rehypePrism)
84
+ .use(wrapCodeBlocks)
85
+ .use(escapeCodeBlocks)
86
+
87
+ .use(htmlStringify)
88
+ .process(md);
89
+
90
+ const code = /** @type {{client: string; server: string}} */ (result.data.code);
91
+
92
+ let litImport = "import { html } from 'lit'";
93
+ if (/import\s*?{(?:\n|.)*?html(\n|.)*}.*/m.test(code.server)) {
94
+ litImport = '';
95
+ }
96
+ const moduleCode = `
97
+ import {render} from '@lit-labs/ssr';
98
+ ${litImport}
99
+ ${code.server}
100
+ export function contentFn(data, layout) {
101
+ data._clientCode = \`${code.client
102
+ .replace(/\\/g, '\\\\')
103
+ .replace(/\$/g, '\\$')
104
+ .replace(/`/g, '\\`')}\`;
105
+ data.content = html\`${result.value.toString()}\`;
106
+
107
+ const layoutResult = layout(data);
108
+ return render(layoutResult);
109
+ }`;
110
+ return moduleCode;
111
+ }
112
+
113
+ /**
114
+ * @param {string} serverCode
115
+ * @param {string} clientCode
116
+ * @param {string} markdown
117
+ * @param {import('@rocket/js/types.js').Headline[]} headlines
118
+ * @returns {Promise<string>}
119
+ */
120
+ async function makeJsFile(serverCode, clientCode, markdown, headlines) {
121
+ let litImport = "import { html } from 'lit'";
122
+ if (/import\s*?{(?:\n|.)*?html(\n|.)*}.*/m.test(serverCode)) {
123
+ litImport = '';
124
+ }
125
+ return `
126
+ import {render} from '@lit-labs/ssr';
127
+ ${litImport}
128
+ ${serverCode}
129
+ export function contentFn(data, defaultLayout) {
130
+ let renderLayout = defaultLayout;
131
+ if (typeof layout !== 'undefined') {
132
+ renderLayout = layout;
133
+ }
134
+ data._clientCode = \`${clientCode
135
+ .replace(/\\/g, '\\\\')
136
+ .replace(/\$/g, '\\$')
137
+ .replace(/`/g, '\\`')}\`;
138
+ data.content = html\`${markdown}\`;
139
+ data.toc = ${JSON.stringify(headLinesToTree(headlines))};
140
+
141
+ const layoutResult = renderLayout(data);
142
+ return render(layoutResult);
143
+ }`;
144
+ }
145
+
146
+ function parseDemos() {
147
+ /** @type {{name: string, code: string}[]} */
148
+ const demos = [];
149
+
150
+ /** @type {import('unist-util-visit').Visitor} */
151
+ const visitor = _node => {
152
+ const node = /** @type {import('mdast').Code & {visited: boolean}} */ (_node);
153
+ if (isDemoCodeNode(node) && typeof node.value === 'string' && !node.visited) {
154
+ const codePreview = structuredClone(node);
155
+ codePreview.visited = true;
156
+ codePreview.meta = demoCodeBlockMeta(node.meta);
157
+ const code = node.value;
158
+ const parsed = parseExports(code);
159
+ const name = parsed[1][0].ln || parsed[1][0].n;
160
+ // we transform a code node into a root node, so cast
161
+ const rootNode = /** @type {import('mdast').Root} */ (/** @type {unknown} */ (node));
162
+ rootNode.type = 'root';
163
+ rootNode.children = [
164
+ { type: 'html', value: `<rocket-js-demo demo-name="${name}">` },
165
+ { type: 'text', value: '\n\n' },
166
+ codePreview,
167
+ { type: 'text', value: '\n\n' },
168
+ { type: 'html', value: '</rocket-js-demo>' },
169
+ ];
170
+ // root nodes don't have values
171
+ // @ts-ignore
172
+ delete node.value;
173
+ delete node.lang;
174
+ delete node.meta;
175
+ demos.push({ name, code });
176
+ }
177
+ };
178
+
179
+ /**
180
+ * @param {import('unist').Node} tree
181
+ * @param {import('vfile').VFile} file
182
+ */
183
+ return async function (tree, file) {
184
+ await init;
185
+ visit(tree, 'code', visitor);
186
+ if (!file.data) {
187
+ file.data = {};
188
+ }
189
+
190
+ const code = /** @type {{client: string}} */ (file.data?.code);
191
+
192
+ if (demos.length) {
193
+ const demoCode = demos.map(demo => demo.code).join('\n');
194
+ const invokeDemosCode = demos
195
+ .map(demo => `{key: '${demo.name}', demo: ${demo.name}}`)
196
+ .join(', ');
197
+
198
+ // @ts-ignore
199
+ file.data.code.client = [
200
+ '// client code',
201
+ code.client + ';',
202
+ '// demo code',
203
+ demoCode,
204
+ '// demo setup code',
205
+ 'let needsElements = false;',
206
+ `for (const demo of [${invokeDemosCode}]) {`,
207
+ ' const element = document.querySelector(`rocket-js-demo[demo-name="${demo.key}"]`);',
208
+ ' if (element) {',
209
+ ' needsElements = true;',
210
+ ' element.demo = demo.demo;',
211
+ ' }',
212
+ '}',
213
+ 'if (needsElements) {',
214
+ ' import("@rocket/js/define/RocketJsDemo.js");',
215
+ '}',
216
+ ].join('\n');
217
+ }
218
+
219
+ return tree;
220
+ };
221
+ }
222
+
223
+ function parseRequestDemos() {
224
+ /** @type {import('unist-util-visit').Visitor} */
225
+ const visitor = _node => {
226
+ const node = /** @type {import('mdast').Code & {visited: boolean}} */ (_node);
227
+ if (!isRequestDemoCodeNode(node) || typeof node.value !== 'string' || node.visited) {
228
+ return;
229
+ }
230
+
231
+ const metadata = parseRequestDemoMetadata(node.meta);
232
+ const codePreview = structuredClone(node);
233
+ codePreview.visited = true;
234
+ codePreview.meta = metadata.label
235
+ ? `label="${escapeFenceAttribute(metadata.label)}"`
236
+ : undefined;
237
+
238
+ const rootNode = /** @type {import('mdast').Root} */ (/** @type {unknown} */ (node));
239
+ rootNode.type = 'root';
240
+ rootNode.children = [
241
+ { type: 'html', value: requestDemoFallbackStart(metadata) },
242
+ { type: 'text', value: '\n\n' },
243
+ codePreview,
244
+ { type: 'text', value: '\n\n' },
245
+ { type: 'html', value: requestDemoFallbackEnd() },
246
+ ];
247
+ // root nodes don't have values
248
+ // @ts-ignore
249
+ delete node.value;
250
+ delete node.lang;
251
+ delete node.meta;
252
+ };
253
+
254
+ /**
255
+ * @param {import('unist').Node} tree
256
+ */
257
+ return function (tree) {
258
+ visit(tree, 'code', visitor);
259
+ return tree;
260
+ };
261
+ }
262
+
263
+ /**
264
+ * @param {import('mdast').Code} node
265
+ */
266
+ function isRequestDemoCodeNode(node) {
267
+ return node.lang === 'js' && /^request-demo(?:\s|$)/.test(node.meta || '');
268
+ }
269
+
270
+ /**
271
+ * @param {import('mdast').Code} node
272
+ */
273
+ function isDemoCodeNode(node) {
274
+ return node.lang === 'js' && /(?:^|\s)demo(?:\s|$)/.test(node.meta || '');
275
+ }
276
+
277
+ /**
278
+ * @param {string | null | undefined} meta
279
+ */
280
+ function demoCodeBlockMeta(meta) {
281
+ const codeBlockMeta = (meta || '').replace(/(?:^|\s)demo(?=\s|$)/, ' ').trim();
282
+
283
+ return codeBlockMeta || undefined;
284
+ }
285
+
286
+ /**
287
+ * @param {import('./requestDemoMetadata.js').RequestDemoMetadata} metadata
288
+ */
289
+ function requestDemoFallbackStart(metadata) {
290
+ const urlAttribute = escapeHtmlAttribute(metadata.url);
291
+ const labelAttribute = metadata.label ? ` label="${escapeHtmlAttribute(metadata.label)}"` : '';
292
+ const heightAttribute = metadata.height !== undefined ? ` height="${metadata.height}"` : '';
293
+
294
+ return `<rocket-request-demo url="${urlAttribute}"${labelAttribute}${heightAttribute}>`;
295
+ }
296
+
297
+ function requestDemoFallbackEnd() {
298
+ return '</rocket-request-demo>';
299
+ }
300
+
301
+ /**
302
+ * @param {string} demoName
303
+ */
304
+ function extractSingleDemo(demoName) {
305
+ /** @type {{name: string, code: string, node: import('mdast').Root} | null} */
306
+ let demo = null;
307
+
308
+ /** @type {import('unist-util-visit').Visitor} */
309
+ const visitor = _node => {
310
+ const node = /** @type {import('mdast').Code & {visited: boolean}} */ (_node);
311
+ if (isDemoCodeNode(node) && typeof node.value === 'string' && !node.visited) {
312
+ const codePreview = structuredClone(node);
313
+ codePreview.visited = true;
314
+ codePreview.meta = demoCodeBlockMeta(node.meta);
315
+ const code = node.value;
316
+ const parsed = parseExports(code);
317
+ const name = parsed[1][0].ln || parsed[1][0].n;
318
+ if (name !== demoName) {
319
+ return;
320
+ }
321
+ // we transform a code node into a root node, so cast
322
+ const rootNode = /** @type {import('mdast').Root} */ (/** @type {unknown} */ (node));
323
+ rootNode.type = 'root';
324
+ rootNode.children = [
325
+ {
326
+ type: 'html',
327
+ value: `<rocket-js-demo demo-name="${name}" single-demo>`,
328
+ },
329
+ { type: 'text', value: '\n\n' },
330
+ codePreview,
331
+ { type: 'text', value: '\n\n' },
332
+ { type: 'html', value: '</rocket-js-demo>' },
333
+ ];
334
+ // root nodes don't have values
335
+ // @ts-ignore
336
+ delete node.value;
337
+ delete node.lang;
338
+ delete node.meta;
339
+ demo = { name, code, node: rootNode };
340
+ }
341
+ };
342
+
343
+ /**
344
+ * @param {import('unist').Node} tree
345
+ * @param {import('vfile').VFile} file
346
+ */
347
+ return async function (tree, file) {
348
+ await init;
349
+ visit(tree, 'code', visitor);
350
+ if (!file.data) {
351
+ file.data = {};
352
+ }
353
+
354
+ if (demo) {
355
+ Object.assign(tree, demo?.node);
356
+ const code = /** @type {{client: string}} */ (file.data?.code);
357
+ // @ts-ignore
358
+ file.data.code.client = [
359
+ '// client code',
360
+ code.client + ';',
361
+ '// demo code',
362
+ demo.code + ';',
363
+ '// demo setup code',
364
+ `const element = document.querySelector(\`rocket-js-demo[demo-name="${demo.name}"]\`);`,
365
+ `element.demo = ${demo.name};`,
366
+ 'import("@rocket/js/define/RocketJsDemo.js");',
367
+ ].join('\n');
368
+ }
369
+
370
+ return tree;
371
+ };
372
+ }
373
+
374
+ function captureCodeBlockData() {
375
+ /** @type {import('unist-util-visit').Visitor} */
376
+ const visitor = _node => {
377
+ const node = /** @type {import('mdast').Code} */ (_node);
378
+ const label = parseCodeBlockLabel(node.meta);
379
+ node.data = node.data || {};
380
+ node.data.hProperties = {
381
+ ...node.data.hProperties,
382
+ ...(node.meta ? { metastring: node.meta } : {}),
383
+ 'data-rocket-code-label': label || '',
384
+ 'data-rocket-code-language': node.lang || '',
385
+ 'data-rocket-code-encoded': Buffer.from(node.value, 'utf8').toString('base64'),
386
+ };
387
+ };
388
+
389
+ /**
390
+ * @param {import('unist').Node} tree
391
+ */
392
+ return function (tree) {
393
+ visit(tree, 'code', visitor);
394
+ return tree;
395
+ };
396
+ }
397
+
398
+ /**
399
+ * @param {string | null | undefined} meta
400
+ */
401
+ function parseCodeBlockLabel(meta) {
402
+ if (!meta) {
403
+ return undefined;
404
+ }
405
+ return /(?:^|\s)label="([^"]+)"/.exec(meta)?.[1];
406
+ }
407
+
408
+ /**
409
+ * @param {string} value
410
+ */
411
+ function escapeFenceAttribute(value) {
412
+ return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
413
+ }
414
+
415
+ /**
416
+ * @param {string} value
417
+ */
418
+ function escapeHtml(value) {
419
+ return value.replace(/[&<>"'`$\\]/g, char => htmlEscapes[char]);
420
+ }
421
+
422
+ /**
423
+ * @param {string} value
424
+ */
425
+ function escapeHtmlAttribute(value) {
426
+ return escapeHtml(value);
427
+ }
428
+
429
+ /** @type {Record<string, string>} */
430
+ const htmlEscapes = {
431
+ '&': '&amp;',
432
+ '<': '&lt;',
433
+ '>': '&gt;',
434
+ '"': '&quot;',
435
+ "'": '&#39;',
436
+ '`': '&#96;',
437
+ $: '&#36;',
438
+ '\\': '&#92;',
439
+ };
440
+
441
+ function wrapCodeBlocks() {
442
+ /** @type {import('unist-util-visit').Visitor} */
443
+ const visitor = (_node, index, _parent) => {
444
+ const pre = /** @type {import('hast').Element} */ (_node);
445
+ const parent = /** @type {import('hast').Element} */ (_parent);
446
+ const code = pre.children.find(child => child.type === 'element' && child.tagName === 'code');
447
+ if (!code || code.type !== 'element') {
448
+ return;
449
+ }
450
+
451
+ delete code.properties.metastring;
452
+ const label = readStringProperty(
453
+ code.properties['data-rocket-code-label'] ?? code.properties.dataRocketCodeLabel,
454
+ );
455
+ const encodedCode = readStringProperty(
456
+ code.properties['data-rocket-code-encoded'] ?? code.properties.dataRocketCodeEncoded,
457
+ );
458
+ if (encodedCode === undefined || index === undefined) {
459
+ return;
460
+ }
461
+
462
+ const language = readStringProperty(
463
+ code.properties['data-rocket-code-language'] ?? code.properties.dataRocketCodeLanguage,
464
+ );
465
+ delete code.properties['data-rocket-code-label'];
466
+ delete code.properties.dataRocketCodeLabel;
467
+ delete code.properties['data-rocket-code-language'];
468
+ delete code.properties.dataRocketCodeLanguage;
469
+ delete code.properties['data-rocket-code-encoded'];
470
+ delete code.properties.dataRocketCodeEncoded;
471
+
472
+ const properties = {
473
+ ...(label ? { label } : {}),
474
+ ...(language ? { language } : {}),
475
+ 'encoded-code': encodedCode,
476
+ };
477
+
478
+ parent.children[index] = {
479
+ type: 'element',
480
+ tagName: 'rocket-code-block',
481
+ properties,
482
+ children: [pre],
483
+ };
484
+ };
485
+
486
+ /**
487
+ * @param {import('unist').Node} tree
488
+ * @returns {import('unist').Node}
489
+ */
490
+ return function (tree) {
491
+ visit(tree, { type: 'element', tagName: 'pre' }, visitor);
492
+ return tree;
493
+ };
494
+ }
495
+
496
+ /**
497
+ * @param {unknown} value
498
+ */
499
+ function readStringProperty(value) {
500
+ if (Array.isArray(value)) {
501
+ return value.join(' ');
502
+ }
503
+ return typeof value === 'string' ? value : undefined;
504
+ }
505
+
506
+ /**
507
+ * @param {string} string
508
+ * @returns {string}
509
+ */
510
+ function escapeOutsideTemplates(string) {
511
+ let result = '';
512
+ let templateLevels = 0;
513
+ for (let i = 0; i < string.length; i++) {
514
+ if (string[i] === '$' && string[i + 1] === '{' && string[i - 1] !== '\\') {
515
+ templateLevels++;
516
+ } else if (templateLevels && string[i] === '}') {
517
+ templateLevels--;
518
+ }
519
+ if (templateLevels) {
520
+ result += string[i];
521
+ } else {
522
+ result += string[i].replace('\\', '\\\\').replace('`', '\\`');
523
+ }
524
+ }
525
+
526
+ return result;
527
+ }
528
+
529
+ function escapeRocketMd() {
530
+ /** @type {import('unist-util-visit').Visitor} */
531
+ const visitor = _node => {
532
+ const node = /** @type {import('mdast').Text} */ (_node);
533
+ if (node.type === 'text' && typeof node.value === 'string') {
534
+ node.value = escapeOutsideTemplates(node.value);
535
+ }
536
+ };
537
+
538
+ /**
539
+ * @param {import('unist').Node} tree
540
+ */
541
+ return function (tree) {
542
+ visit(tree, 'text', visitor);
543
+ return tree;
544
+ };
545
+ }
546
+
547
+ function fixImageTags() {
548
+ /** @type {import('unist-util-visit').Visitor} */
549
+ const visitor = _node => {
550
+ const node = /** @type {import('hast').Element} */ (_node);
551
+ if (node.type === 'element' && node.tagName === 'img') {
552
+ const props = node.properties || {};
553
+ const src = typeof props.src === 'string' ? decodeURIComponent(props.src) : props.src;
554
+
555
+ node.properties = { ...props, src };
556
+ }
557
+ };
558
+
559
+ /**
560
+ * @param {import('unist').Node} tree
561
+ */
562
+ return function (tree) {
563
+ visit(tree, 'element', visitor);
564
+ return tree;
565
+ };
566
+ }
567
+
568
+ /**
569
+ * visits all 'pre > code' elements and escapes any text inside
570
+ */
571
+ function escapeCodeBlocks() {
572
+ /** @type {import('unist-util-visit').Visitor} */
573
+ const visitor = (_node, _, _parent) => {
574
+ const node = /** @type {import('hast').Element} */ (_node);
575
+ const parent = /** @type {import('hast').Element} */ (_parent);
576
+ if (parent?.type === 'element' && parent.tagName === 'pre') {
577
+ visit(node, 'text', replacer);
578
+ }
579
+ };
580
+
581
+ /** @type {import('unist-util-visit').Visitor} */
582
+ const replacer = _node => {
583
+ const node = /** @type {import('hast').Text} */ (_node);
584
+ if (typeof node.value !== 'string') {
585
+ return;
586
+ }
587
+ node.value = node.value.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$/g, '\\$');
588
+ };
589
+
590
+ /**
591
+ * @param {import('unist').Node} tree
592
+ * @returns {import('unist').Node}
593
+ */
594
+ return function (tree) {
595
+ visit(tree, { type: 'element', tagName: 'code' }, visitor);
596
+ return tree;
597
+ };
598
+ }
599
+
600
+ function extractHeadings() {
601
+ /** @type {import('@rocket/js/types.js').Headline[]} */
602
+ const headings = [];
603
+
604
+ /** @type {import('unist-util-visit').Visitor} */
605
+ const visitor = _node => {
606
+ const node = /** @type {import('hast').Element} */ (_node);
607
+ if ('menu-exclude' in node.properties) {
608
+ return;
609
+ }
610
+ const match = node.tagName.match(/h([1-6])/);
611
+ const text = /** @type {string} */ (
612
+ node.properties['link-text'] ||
613
+ node.children.find(child => child.type === 'text')?.value ||
614
+ ''
615
+ );
616
+ if (match) {
617
+ const id = node.properties?.id;
618
+ if (typeof id === 'string') {
619
+ headings.push({ id, level: parseInt(match[1]), text });
620
+ }
621
+ }
622
+ };
623
+
624
+ /**
625
+ * @param {import('unist').Node} tree
626
+ * @param {import('vfile').VFile} file
627
+ */
628
+ return function (tree, file) {
629
+ visit(tree, { type: 'element' }, visitor);
630
+ file.data.headings = headings;
631
+ return tree;
632
+ };
633
+ }
@@ -0,0 +1,57 @@
1
+ import { paginatedArchivePaths } from './page-pagination.js';
2
+ import { standaloneDemoPaths } from './standalone-demo-url.js';
3
+
4
+ /**
5
+ * @param {{
6
+ * redirects?: import('@rocket/js/types.js').RedirectConfig[];
7
+ * pages: import('@rocket/js/types.js').PageRegistry;
8
+ * }} options
9
+ */
10
+ export function validateUrlLifecyclePageCollisions({ redirects = [], pages }) {
11
+ for (const redirect of redirects) {
12
+ const page = pages.get(redirect.source);
13
+ if (!page) {
14
+ continue;
15
+ }
16
+ throw new Error(
17
+ `Redirect source ${redirect.source} collides with configured Page ${page.file}. ` +
18
+ `Choose a Redirect source that is not already configured as a Page path.`,
19
+ );
20
+ }
21
+ }
22
+
23
+ /**
24
+ * @param {{
25
+ * redirects?: import('@rocket/js/types.js').RedirectConfig[];
26
+ * pages: import('@rocket/js/types.js').PageRegistry;
27
+ * staticPages: import('@rocket/js/types.js').PageRegistry;
28
+ * }} options
29
+ */
30
+ export function validateUrlLifecycleGeneratedOutputCollisions({
31
+ redirects = [],
32
+ pages,
33
+ staticPages,
34
+ }) {
35
+ if (!redirects.length) {
36
+ return;
37
+ }
38
+ const redirectSources = new Set(redirects.map(redirect => redirect.source));
39
+ for (const [pagePath, page] of staticPages) {
40
+ for (const demoPath of standaloneDemoPaths(pagePath, page)) {
41
+ if (redirectSources.has(demoPath)) {
42
+ throw new Error(
43
+ `Redirect source ${demoPath} collides with Standalone Demo URL ${demoPath} ` +
44
+ `for page ${page.file}. Choose a Redirect source that is not generated by Rocket.`,
45
+ );
46
+ }
47
+ }
48
+ for (const archivePath of paginatedArchivePaths({ pages, page, pagePath })) {
49
+ if (redirectSources.has(archivePath)) {
50
+ throw new Error(
51
+ `Redirect source ${archivePath} collides with generated archive Page ${archivePath} ` +
52
+ `for page ${page.file}. Choose a Redirect source that is not generated by Rocket.`,
53
+ );
54
+ }
55
+ }
56
+ }
57
+ }