polen 0.9.1-next.1 → 0.10.0-next.10

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 (481) hide show
  1. package/README.md +49 -364
  2. package/build/api/api.d.ts +1 -0
  3. package/build/api/api.d.ts.map +1 -1
  4. package/build/api/api.js +1 -0
  5. package/build/api/api.js.map +1 -1
  6. package/build/api/config/configurator.d.ts +9 -1
  7. package/build/api/config/configurator.d.ts.map +1 -1
  8. package/build/api/config/configurator.js +18 -6
  9. package/build/api/config/configurator.js.map +1 -1
  10. package/build/api/config/load.js +5 -5
  11. package/build/api/config/load.js.map +1 -1
  12. package/build/api/config-resolver/resolve.js +2 -2
  13. package/build/api/config-resolver/resolve.js.map +1 -1
  14. package/build/api/content/$$.d.ts +7 -0
  15. package/build/api/content/$$.d.ts.map +1 -0
  16. package/build/api/content/$$.js +7 -0
  17. package/build/api/content/$$.js.map +1 -0
  18. package/build/api/content/$.d.ts +2 -0
  19. package/build/api/content/$.d.ts.map +1 -0
  20. package/build/api/content/$.js +2 -0
  21. package/build/api/content/$.js.map +1 -0
  22. package/build/api/content/metadata.d.ts +10 -0
  23. package/build/api/content/metadata.d.ts.map +1 -0
  24. package/build/api/content/metadata.js +9 -0
  25. package/build/api/content/metadata.js.map +1 -0
  26. package/build/api/content/navbar.d.ts +10 -0
  27. package/build/api/content/navbar.d.ts.map +1 -0
  28. package/build/api/content/navbar.js +45 -0
  29. package/build/api/content/navbar.js.map +1 -0
  30. package/build/api/content/page.d.ts +11 -0
  31. package/build/api/content/page.d.ts.map +1 -0
  32. package/build/api/content/page.js +2 -0
  33. package/build/api/content/page.js.map +1 -0
  34. package/build/api/content/scan.d.ts +19 -0
  35. package/build/api/content/scan.d.ts.map +1 -0
  36. package/build/api/content/scan.js +90 -0
  37. package/build/api/content/scan.js.map +1 -0
  38. package/build/api/content/sidebar.d.ts +104 -0
  39. package/build/api/content/sidebar.d.ts.map +1 -0
  40. package/build/api/content/sidebar.js +166 -0
  41. package/build/api/content/sidebar.js.map +1 -0
  42. package/build/api/content/utils.d.ts +5 -0
  43. package/build/api/content/utils.d.ts.map +1 -0
  44. package/build/api/content/utils.js +8 -0
  45. package/build/api/content/utils.js.map +1 -0
  46. package/build/api/schema/data-sources/schema-directory/schema-directory.d.ts.map +1 -1
  47. package/build/api/schema/data-sources/schema-directory/schema-directory.js +3 -2
  48. package/build/api/schema/data-sources/schema-directory/schema-directory.js.map +1 -1
  49. package/build/api/static/index.d.ts +2 -0
  50. package/build/api/static/index.d.ts.map +1 -0
  51. package/build/api/static/index.js +2 -0
  52. package/build/api/static/index.js.map +1 -0
  53. package/build/api/static/manifest.d.ts +18 -0
  54. package/build/api/static/manifest.d.ts.map +1 -0
  55. package/build/api/static/manifest.js +13 -0
  56. package/build/api/static/manifest.js.map +1 -0
  57. package/build/api/static/rebase.d.ts +14 -0
  58. package/build/api/static/rebase.d.ts.map +1 -0
  59. package/build/api/static/rebase.js +110 -0
  60. package/build/api/static/rebase.js.map +1 -0
  61. package/build/api/static/static.d.ts +3 -0
  62. package/build/api/static/static.d.ts.map +1 -0
  63. package/build/api/static/static.js +3 -0
  64. package/build/api/static/static.js.map +1 -0
  65. package/build/api/vite/plugins/branding/index.d.ts +4 -0
  66. package/build/api/vite/plugins/branding/index.d.ts.map +1 -0
  67. package/build/api/vite/plugins/branding/index.js +80 -0
  68. package/build/api/vite/plugins/branding/index.js.map +1 -0
  69. package/build/api/vite/plugins/build.d.ts.map +1 -1
  70. package/build/api/vite/plugins/build.js +22 -1
  71. package/build/api/vite/plugins/build.js.map +1 -1
  72. package/build/api/vite/plugins/core.d.ts +2 -2
  73. package/build/api/vite/plugins/core.d.ts.map +1 -1
  74. package/build/api/vite/plugins/core.js +4 -5
  75. package/build/api/vite/plugins/core.js.map +1 -1
  76. package/build/api/vite/plugins/main.d.ts.map +1 -1
  77. package/build/api/vite/plugins/main.js +2 -1
  78. package/build/api/vite/plugins/main.js.map +1 -1
  79. package/build/api/vite/plugins/pages.d.ts +8 -14
  80. package/build/api/vite/plugins/pages.d.ts.map +1 -1
  81. package/build/api/vite/plugins/pages.js +110 -183
  82. package/build/api/vite/plugins/pages.js.map +1 -1
  83. package/build/api/vite/plugins/serve.js +5 -5
  84. package/build/api/vite/plugins/serve.js.map +1 -1
  85. package/build/cli/_/self-contained-mode.js +5 -5
  86. package/build/cli/_/self-contained-mode.js.map +1 -1
  87. package/build/cli/commands/static/$default.d.ts +3 -0
  88. package/build/cli/commands/static/$default.d.ts.map +1 -0
  89. package/build/cli/commands/static/$default.js +38 -0
  90. package/build/cli/commands/static/$default.js.map +1 -0
  91. package/build/cli/commands/static/rebase.d.ts +2 -0
  92. package/build/cli/commands/static/rebase.d.ts.map +1 -0
  93. package/build/cli/commands/static/rebase.js +26 -0
  94. package/build/cli/commands/static/rebase.js.map +1 -0
  95. package/build/cli/commands/static.d.ts +3 -0
  96. package/build/cli/commands/static.d.ts.map +1 -0
  97. package/build/cli/commands/static.js +5 -0
  98. package/build/cli/commands/static.js.map +1 -0
  99. package/build/exports/components.d.ts +2 -0
  100. package/build/exports/components.d.ts.map +1 -0
  101. package/build/exports/components.js +2 -0
  102. package/build/exports/components.js.map +1 -0
  103. package/build/lib/demos/builder.d.ts +83 -0
  104. package/build/lib/demos/builder.d.ts.map +1 -0
  105. package/build/lib/demos/builder.js +237 -0
  106. package/build/lib/demos/builder.js.map +1 -0
  107. package/build/lib/demos/config-schema.d.ts +243 -0
  108. package/build/lib/demos/config-schema.d.ts.map +1 -0
  109. package/build/lib/demos/config-schema.js +52 -0
  110. package/build/lib/demos/config-schema.js.map +1 -0
  111. package/build/lib/demos/config.d.ts +40 -0
  112. package/build/lib/demos/config.d.ts.map +1 -0
  113. package/build/lib/demos/config.js +180 -0
  114. package/build/lib/demos/config.js.map +1 -0
  115. package/build/lib/demos/index.d.ts +9 -0
  116. package/build/lib/demos/index.d.ts.map +1 -0
  117. package/build/lib/demos/index.js +8 -0
  118. package/build/lib/demos/index.js.map +1 -0
  119. package/build/lib/demos/ui/components.d.ts +33 -0
  120. package/build/lib/demos/ui/components.d.ts.map +1 -0
  121. package/build/lib/demos/ui/components.js +699 -0
  122. package/build/lib/demos/ui/components.js.map +1 -0
  123. package/build/lib/demos/ui/data-collector.d.ts +88 -0
  124. package/build/lib/demos/ui/data-collector.d.ts.map +1 -0
  125. package/build/lib/demos/ui/data-collector.js +174 -0
  126. package/build/lib/demos/ui/data-collector.js.map +1 -0
  127. package/build/lib/demos/ui/landing-page-cli.d.ts +3 -0
  128. package/build/lib/demos/ui/landing-page-cli.d.ts.map +1 -0
  129. package/build/lib/demos/ui/landing-page-cli.js +21 -0
  130. package/build/lib/demos/ui/landing-page-cli.js.map +1 -0
  131. package/build/lib/demos/ui/landing-page.d.ts +32 -0
  132. package/build/lib/demos/ui/landing-page.d.ts.map +1 -0
  133. package/build/lib/demos/ui/landing-page.js +83 -0
  134. package/build/lib/demos/ui/landing-page.js.map +1 -0
  135. package/build/lib/demos/ui/page-renderer.d.ts +26 -0
  136. package/build/lib/demos/ui/page-renderer.d.ts.map +1 -0
  137. package/build/lib/demos/ui/page-renderer.js +104 -0
  138. package/build/lib/demos/ui/page-renderer.js.map +1 -0
  139. package/build/lib/demos/utils.d.ts +14 -0
  140. package/build/lib/demos/utils.d.ts.map +1 -0
  141. package/build/lib/demos/utils.js +37 -0
  142. package/build/lib/demos/utils.js.map +1 -0
  143. package/build/lib/deployment/$$.d.ts +3 -0
  144. package/build/lib/deployment/$$.d.ts.map +1 -0
  145. package/build/lib/deployment/$$.js +3 -0
  146. package/build/lib/deployment/$$.js.map +1 -0
  147. package/build/lib/deployment/$.d.ts +2 -0
  148. package/build/lib/deployment/$.d.ts.map +1 -0
  149. package/build/lib/deployment/$.js +2 -0
  150. package/build/lib/deployment/$.js.map +1 -0
  151. package/build/lib/deployment/metadata.d.ts +32 -0
  152. package/build/lib/deployment/metadata.d.ts.map +1 -0
  153. package/build/lib/deployment/metadata.js +37 -0
  154. package/build/lib/deployment/metadata.js.map +1 -0
  155. package/build/lib/deployment/path-manager.d.ts +41 -0
  156. package/build/lib/deployment/path-manager.d.ts.map +1 -0
  157. package/build/lib/deployment/path-manager.js +157 -0
  158. package/build/lib/deployment/path-manager.js.map +1 -0
  159. package/build/lib/file-router/file-router.d.ts +0 -2
  160. package/build/lib/file-router/file-router.d.ts.map +1 -1
  161. package/build/lib/file-router/file-router.js +0 -2
  162. package/build/lib/file-router/file-router.js.map +1 -1
  163. package/build/lib/file-router/route.d.ts +2 -0
  164. package/build/lib/file-router/route.d.ts.map +1 -1
  165. package/build/lib/file-router/route.js.map +1 -1
  166. package/build/lib/file-router/scan.d.ts.map +1 -1
  167. package/build/lib/file-router/scan.js +22 -13
  168. package/build/lib/file-router/scan.js.map +1 -1
  169. package/build/lib/github-actions/git-controller.d.ts +50 -0
  170. package/build/lib/github-actions/git-controller.d.ts.map +1 -0
  171. package/build/lib/github-actions/git-controller.js +90 -0
  172. package/build/lib/github-actions/git-controller.js.map +1 -0
  173. package/build/lib/github-actions/github-actions.d.ts +7 -0
  174. package/build/lib/github-actions/github-actions.d.ts.map +1 -0
  175. package/build/lib/github-actions/github-actions.js +7 -0
  176. package/build/lib/github-actions/github-actions.js.map +1 -0
  177. package/build/lib/github-actions/index.d.ts +2 -0
  178. package/build/lib/github-actions/index.d.ts.map +1 -0
  179. package/build/lib/github-actions/index.js +2 -0
  180. package/build/lib/github-actions/index.js.map +1 -0
  181. package/build/lib/github-actions/lib/get-pr-deployments.d.ts +12 -0
  182. package/build/lib/github-actions/lib/get-pr-deployments.d.ts.map +1 -0
  183. package/build/lib/github-actions/lib/get-pr-deployments.js +51 -0
  184. package/build/lib/github-actions/lib/get-pr-deployments.js.map +1 -0
  185. package/build/lib/github-actions/pr-controller.d.ts +39 -0
  186. package/build/lib/github-actions/pr-controller.d.ts.map +1 -0
  187. package/build/lib/github-actions/pr-controller.js +122 -0
  188. package/build/lib/github-actions/pr-controller.js.map +1 -0
  189. package/build/lib/github-actions/run-step-cli.d.ts +9 -0
  190. package/build/lib/github-actions/run-step-cli.d.ts.map +1 -0
  191. package/build/lib/github-actions/run-step-cli.js +71 -0
  192. package/build/lib/github-actions/run-step-cli.js.map +1 -0
  193. package/build/lib/github-actions/runner.d.ts +17 -0
  194. package/build/lib/github-actions/runner.d.ts.map +1 -0
  195. package/build/lib/github-actions/runner.js +195 -0
  196. package/build/lib/github-actions/runner.js.map +1 -0
  197. package/build/lib/github-actions/schemas/context.d.ts +933 -0
  198. package/build/lib/github-actions/schemas/context.d.ts.map +1 -0
  199. package/build/lib/github-actions/schemas/context.js +407 -0
  200. package/build/lib/github-actions/schemas/context.js.map +1 -0
  201. package/build/lib/github-actions/schemas/index.d.ts +5 -0
  202. package/build/lib/github-actions/schemas/index.d.ts.map +1 -0
  203. package/build/lib/github-actions/schemas/index.js +5 -0
  204. package/build/lib/github-actions/schemas/index.js.map +1 -0
  205. package/build/lib/github-actions/search-module.d.ts +38 -0
  206. package/build/lib/github-actions/search-module.d.ts.map +1 -0
  207. package/build/lib/github-actions/search-module.js +40 -0
  208. package/build/lib/github-actions/search-module.js.map +1 -0
  209. package/build/lib/github-actions/step.d.ts +163 -0
  210. package/build/lib/github-actions/step.d.ts.map +1 -0
  211. package/build/lib/github-actions/step.js +121 -0
  212. package/build/lib/github-actions/step.js.map +1 -0
  213. package/build/lib/helpers.d.ts.map +1 -1
  214. package/build/lib/helpers.js +5 -3
  215. package/build/lib/helpers.js.map +1 -1
  216. package/build/lib/kit-temp.d.ts +54 -0
  217. package/build/lib/kit-temp.d.ts.map +1 -1
  218. package/build/lib/kit-temp.js +82 -14
  219. package/build/lib/kit-temp.js.map +1 -1
  220. package/build/lib/kit-temp.test-d.d.ts +2 -0
  221. package/build/lib/kit-temp.test-d.d.ts.map +1 -0
  222. package/build/lib/kit-temp.test-d.js +75 -0
  223. package/build/lib/kit-temp.test-d.js.map +1 -0
  224. package/build/lib/mask/$$.d.ts +3 -0
  225. package/build/lib/mask/$$.d.ts.map +1 -0
  226. package/build/lib/mask/$$.js +3 -0
  227. package/build/lib/mask/$$.js.map +1 -0
  228. package/build/lib/mask/$.d.ts +2 -0
  229. package/build/lib/mask/$.d.ts.map +1 -0
  230. package/build/lib/mask/$.js +2 -0
  231. package/build/lib/mask/$.js.map +1 -0
  232. package/build/lib/mask/apply.d.ts +86 -0
  233. package/build/lib/mask/apply.d.ts.map +1 -0
  234. package/build/lib/mask/apply.js +86 -0
  235. package/build/lib/mask/apply.js.map +1 -0
  236. package/build/lib/mask/mask.d.ts +124 -0
  237. package/build/lib/mask/mask.d.ts.map +1 -0
  238. package/build/lib/mask/mask.js +137 -0
  239. package/build/lib/mask/mask.js.map +1 -0
  240. package/build/lib/mask/mask.test-d.d.ts +2 -0
  241. package/build/lib/mask/mask.test-d.d.ts.map +1 -0
  242. package/build/lib/mask/mask.test-d.js +102 -0
  243. package/build/lib/mask/mask.test-d.js.map +1 -0
  244. package/build/lib/mutation-type.d.ts +18 -0
  245. package/build/lib/mutation-type.d.ts.map +1 -0
  246. package/build/lib/mutation-type.js +16 -0
  247. package/build/lib/mutation-type.js.map +1 -0
  248. package/build/lib/task/$$.d.ts +3 -0
  249. package/build/lib/task/$$.d.ts.map +1 -0
  250. package/build/lib/task/$$.js +3 -0
  251. package/build/lib/task/$$.js.map +1 -0
  252. package/build/lib/task/$.d.ts +2 -0
  253. package/build/lib/task/$.d.ts.map +1 -0
  254. package/build/lib/task/$.js +2 -0
  255. package/build/lib/task/$.js.map +1 -0
  256. package/build/lib/task/report.d.ts +28 -0
  257. package/build/lib/task/report.d.ts.map +1 -0
  258. package/build/lib/task/report.js +33 -0
  259. package/build/lib/task/report.js.map +1 -0
  260. package/build/lib/task/task.d.ts +44 -0
  261. package/build/lib/task/task.d.ts.map +1 -0
  262. package/build/lib/task/task.js +63 -0
  263. package/build/lib/task/task.js.map +1 -0
  264. package/build/lib/version-history/index.d.ts +3 -0
  265. package/build/lib/version-history/index.d.ts.map +1 -0
  266. package/build/lib/version-history/index.js +2 -0
  267. package/build/lib/version-history/index.js.map +1 -0
  268. package/build/lib/version-history/types.d.ts +64 -0
  269. package/build/lib/version-history/types.d.ts.map +1 -0
  270. package/build/lib/version-history/types.js +5 -0
  271. package/build/lib/version-history/types.js.map +1 -0
  272. package/build/lib/version-history/version-history.d.ts +85 -0
  273. package/build/lib/version-history/version-history.d.ts.map +1 -0
  274. package/build/lib/version-history/version-history.js +248 -0
  275. package/build/lib/version-history/version-history.js.map +1 -0
  276. package/build/lib/vite-virtual/debug.d.ts +1 -1
  277. package/build/lib/vite-virtual/debug.d.ts.map +1 -1
  278. package/build/lib/vite-virtual/debug.js +1 -1
  279. package/build/lib/vite-virtual/debug.js.map +1 -1
  280. package/build/project-data.d.ts +0 -1
  281. package/build/project-data.d.ts.map +1 -1
  282. package/build/sandbox.d.ts +2 -0
  283. package/build/sandbox.d.ts.map +1 -0
  284. package/build/sandbox.js +18 -0
  285. package/build/sandbox.js.map +1 -0
  286. package/build/singletons/debug.d.ts +2 -2
  287. package/build/singletons/debug.d.ts.map +1 -1
  288. package/build/singletons/debug.js +2 -2
  289. package/build/singletons/debug.js.map +1 -1
  290. package/build/template/components/HamburgerMenu.d.ts +9 -0
  291. package/build/template/components/HamburgerMenu.d.ts.map +1 -0
  292. package/build/template/components/HamburgerMenu.jsx +53 -0
  293. package/build/template/components/HamburgerMenu.jsx.map +1 -0
  294. package/build/template/components/Link.jsx +1 -1
  295. package/build/template/components/Logo.d.ts +9 -0
  296. package/build/template/components/Logo.d.ts.map +1 -0
  297. package/build/template/components/Logo.jsx +29 -0
  298. package/build/template/components/Logo.jsx.map +1 -0
  299. package/build/template/components/NotFound.d.ts +2 -0
  300. package/build/template/components/NotFound.d.ts.map +1 -0
  301. package/build/template/components/NotFound.jsx +26 -0
  302. package/build/template/components/NotFound.jsx.map +1 -0
  303. package/build/template/components/ThemeToggle.d.ts +3 -0
  304. package/build/template/components/ThemeToggle.d.ts.map +1 -0
  305. package/build/template/components/ThemeToggle.jsx +10 -0
  306. package/build/template/components/ThemeToggle.jsx.map +1 -0
  307. package/build/template/components/content/$$.d.ts +2 -0
  308. package/build/template/components/content/$$.d.ts.map +1 -0
  309. package/build/template/components/content/$$.js +2 -0
  310. package/build/template/components/content/$$.js.map +1 -0
  311. package/build/template/components/sidebar/Sidebar.d.ts +2 -2
  312. package/build/template/components/sidebar/Sidebar.d.ts.map +1 -1
  313. package/build/template/components/sidebar/SidebarItem.d.ts +3 -3
  314. package/build/template/components/sidebar/SidebarItem.d.ts.map +1 -1
  315. package/build/template/components/sidebar/SidebarItem.jsx +1 -1
  316. package/build/template/components/sidebar/SidebarItem.jsx.map +1 -1
  317. package/build/template/contexts/ThemeContext.d.ts +12 -0
  318. package/build/template/contexts/ThemeContext.d.ts.map +1 -0
  319. package/build/template/contexts/ThemeContext.jsx +41 -0
  320. package/build/template/contexts/ThemeContext.jsx.map +1 -0
  321. package/build/template/routes/root.d.ts.map +1 -1
  322. package/build/template/routes/root.jsx +66 -53
  323. package/build/template/routes/root.jsx.map +1 -1
  324. package/build/template/server/app.d.ts.map +1 -1
  325. package/build/template/server/app.js +2 -21
  326. package/build/template/server/app.js.map +1 -1
  327. package/package.json +42 -28
  328. package/src/api/api.ts +1 -0
  329. package/src/api/config/configurator.ts +28 -6
  330. package/src/api/config/load.ts +5 -5
  331. package/src/api/config-resolver/resolve.ts +2 -2
  332. package/src/api/content/$$.ts +6 -0
  333. package/src/api/content/$.test.ts +72 -0
  334. package/src/api/content/$.ts +1 -0
  335. package/src/api/content/metadata.ts +11 -0
  336. package/src/api/content/navbar.test.ts +55 -0
  337. package/src/api/content/navbar.ts +61 -0
  338. package/src/api/content/page.ts +12 -0
  339. package/src/api/content/scan.ts +117 -0
  340. package/src/api/content/sidebar.test.ts +297 -0
  341. package/src/api/content/sidebar.ts +283 -0
  342. package/src/api/content/utils.ts +7 -0
  343. package/src/api/schema/data-sources/schema-directory/schema-directory.ts +3 -2
  344. package/src/api/singletons/markdown/markdown.test.ts +1 -1
  345. package/src/api/static/index.ts +1 -0
  346. package/src/api/static/manifest.test.ts +106 -0
  347. package/src/api/static/manifest.ts +16 -0
  348. package/src/api/static/rebase.test.ts +229 -0
  349. package/src/api/static/rebase.ts +140 -0
  350. package/src/api/static/static.ts +2 -0
  351. package/src/api/utils/asset-url/asset-url.test.ts +4 -4
  352. package/src/api/vite/plugins/branding/index.ts +108 -0
  353. package/src/api/vite/plugins/build.ts +25 -1
  354. package/src/api/vite/plugins/core.ts +6 -7
  355. package/src/api/vite/plugins/main.ts +2 -0
  356. package/src/api/vite/plugins/pages.ts +131 -207
  357. package/src/api/vite/plugins/serve.ts +5 -5
  358. package/src/cli/_/self-contained-mode.ts +5 -5
  359. package/src/cli/commands/static/$default.ts +43 -0
  360. package/src/cli/commands/static/rebase.ts +37 -0
  361. package/src/cli/commands/static.ts +6 -0
  362. package/src/exports/components.ts +1 -0
  363. package/src/lib/demos/builder.ts +298 -0
  364. package/src/lib/demos/config-schema.ts +56 -0
  365. package/src/lib/demos/config.test.ts +193 -0
  366. package/src/lib/demos/config.ts +205 -0
  367. package/src/lib/demos/index.ts +9 -0
  368. package/src/lib/demos/ui/components.ts +739 -0
  369. package/src/lib/demos/ui/data-collector.ts +246 -0
  370. package/src/lib/demos/ui/landing-page-cli.ts +23 -0
  371. package/src/lib/demos/ui/landing-page.ts +126 -0
  372. package/src/lib/demos/ui/page-renderer.ts +124 -0
  373. package/src/lib/demos/utils.ts +43 -0
  374. package/src/lib/deployment/$$.ts +2 -0
  375. package/src/lib/deployment/$.test.ts +53 -0
  376. package/src/lib/deployment/$.ts +1 -0
  377. package/src/lib/deployment/metadata.ts +40 -0
  378. package/src/lib/deployment/path-manager.ts +186 -0
  379. package/src/lib/file-router/file-router.ts +0 -2
  380. package/src/lib/file-router/linter.test.ts +2 -0
  381. package/src/lib/file-router/route.ts +2 -0
  382. package/src/lib/file-router/scan.ts +26 -14
  383. package/src/lib/github-actions/git-controller.ts +151 -0
  384. package/src/lib/github-actions/github-actions.ts +6 -0
  385. package/src/lib/github-actions/index.ts +1 -0
  386. package/src/lib/github-actions/lib/get-pr-deployments.ts +76 -0
  387. package/src/lib/github-actions/pr-controller.test.ts +172 -0
  388. package/src/lib/github-actions/pr-controller.ts +183 -0
  389. package/src/lib/github-actions/run-step-cli.ts +84 -0
  390. package/src/lib/github-actions/runner.test.ts +192 -0
  391. package/src/lib/github-actions/runner.ts +226 -0
  392. package/src/lib/github-actions/schemas/context.ts +424 -0
  393. package/src/lib/github-actions/schemas/index.ts +5 -0
  394. package/src/lib/github-actions/search-module.test.ts +110 -0
  395. package/src/lib/github-actions/search-module.ts +76 -0
  396. package/src/lib/github-actions/step.test.ts +149 -0
  397. package/src/lib/github-actions/step.ts +232 -0
  398. package/src/lib/helpers.ts +4 -3
  399. package/src/lib/kit-temp.test-d.ts +115 -0
  400. package/src/lib/kit-temp.test.ts +127 -0
  401. package/src/lib/kit-temp.ts +128 -14
  402. package/src/lib/mask/$$.ts +2 -0
  403. package/src/lib/mask/$.test.ts +248 -0
  404. package/src/lib/mask/$.ts +1 -0
  405. package/src/lib/mask/apply.ts +134 -0
  406. package/src/lib/mask/mask.test-d.ts +144 -0
  407. package/src/lib/mask/mask.ts +244 -0
  408. package/src/lib/mutation-type.ts +20 -0
  409. package/src/lib/shiki/shiki.test.ts +1 -1
  410. package/src/lib/task/$$.ts +2 -0
  411. package/src/lib/task/$.test.ts +209 -0
  412. package/src/lib/task/$.ts +1 -0
  413. package/src/lib/task/report.ts +72 -0
  414. package/src/lib/task/task.ts +112 -0
  415. package/src/lib/version-history/index.test.ts +196 -0
  416. package/src/lib/version-history/index.ts +4 -0
  417. package/src/lib/version-history/types.ts +68 -0
  418. package/src/lib/version-history/version-history.ts +293 -0
  419. package/src/lib/vite-virtual/debug.ts +1 -1
  420. package/src/project-data.ts +0 -1
  421. package/src/sandbox.ts +20 -0
  422. package/src/singletons/debug.ts +2 -2
  423. package/src/template/components/HamburgerMenu.tsx +96 -0
  424. package/src/template/components/Link.tsx +1 -1
  425. package/src/template/components/Logo.tsx +46 -0
  426. package/src/template/components/NotFound.tsx +28 -0
  427. package/src/template/components/ThemeToggle.tsx +21 -0
  428. package/src/template/components/content/$$.ts +1 -0
  429. package/src/template/components/sidebar/Sidebar.tsx +2 -2
  430. package/src/template/components/sidebar/SidebarItem.tsx +8 -8
  431. package/src/template/contexts/ThemeContext.tsx +60 -0
  432. package/src/template/routes/root.tsx +85 -74
  433. package/src/template/server/app.ts +2 -27
  434. package/build/lib/debug/debug.d.ts +0 -13
  435. package/build/lib/debug/debug.d.ts.map +0 -1
  436. package/build/lib/debug/debug.js +0 -86
  437. package/build/lib/debug/debug.js.map +0 -1
  438. package/build/lib/debug/environment-variable.d.ts +0 -6
  439. package/build/lib/debug/environment-variable.d.ts.map +0 -1
  440. package/build/lib/debug/environment-variable.js +0 -48
  441. package/build/lib/debug/environment-variable.js.map +0 -1
  442. package/build/lib/debug/index.d.ts +0 -2
  443. package/build/lib/debug/index.d.ts.map +0 -1
  444. package/build/lib/debug/index.js +0 -2
  445. package/build/lib/debug/index.js.map +0 -1
  446. package/build/lib/file-router/scan-tree.d.ts +0 -20
  447. package/build/lib/file-router/scan-tree.d.ts.map +0 -1
  448. package/build/lib/file-router/scan-tree.js +0 -158
  449. package/build/lib/file-router/scan-tree.js.map +0 -1
  450. package/build/lib/file-router/sidebar/index.d.ts +0 -3
  451. package/build/lib/file-router/sidebar/index.d.ts.map +0 -1
  452. package/build/lib/file-router/sidebar/index.js +0 -4
  453. package/build/lib/file-router/sidebar/index.js.map +0 -1
  454. package/build/lib/file-router/sidebar/sidebar-tree.d.ts +0 -9
  455. package/build/lib/file-router/sidebar/sidebar-tree.d.ts.map +0 -1
  456. package/build/lib/file-router/sidebar/sidebar-tree.js +0 -85
  457. package/build/lib/file-router/sidebar/sidebar-tree.js.map +0 -1
  458. package/build/lib/file-router/sidebar/types.d.ts +0 -17
  459. package/build/lib/file-router/sidebar/types.d.ts.map +0 -1
  460. package/build/lib/file-router/sidebar/types.js +0 -2
  461. package/build/lib/file-router/sidebar/types.js.map +0 -1
  462. package/build/lib/tree/index.d.ts +0 -3
  463. package/build/lib/tree/index.d.ts.map +0 -1
  464. package/build/lib/tree/index.js +0 -2
  465. package/build/lib/tree/index.js.map +0 -1
  466. package/build/lib/tree/tree.d.ts +0 -62
  467. package/build/lib/tree/tree.d.ts.map +0 -1
  468. package/build/lib/tree/tree.js +0 -134
  469. package/build/lib/tree/tree.js.map +0 -1
  470. package/src/lib/debug/debug.ts +0 -120
  471. package/src/lib/debug/environment-variable.ts +0 -56
  472. package/src/lib/debug/index.ts +0 -1
  473. package/src/lib/file-router/scan-tree.test.ts +0 -189
  474. package/src/lib/file-router/scan-tree.ts +0 -205
  475. package/src/lib/file-router/sidebar/index.ts +0 -3
  476. package/src/lib/file-router/sidebar/sidebar-tree.test.ts +0 -123
  477. package/src/lib/file-router/sidebar/sidebar-tree.ts +0 -110
  478. package/src/lib/file-router/sidebar/types.ts +0 -19
  479. package/src/lib/tree/index.ts +0 -2
  480. package/src/lib/tree/tree.test.ts +0 -117
  481. package/src/lib/tree/tree.ts +0 -183
@@ -0,0 +1,283 @@
1
+ import { FileRouter } from '#lib/file-router/index'
2
+ import { Str } from '@wollybeard/kit'
3
+ import type { Page } from './page.ts'
4
+ import type { ScanResult } from './scan.ts'
5
+
6
+ /**
7
+ * Represents a complete sidebar structure with navigation items.
8
+ * This is the main data structure used to render sidebars in the UI.
9
+ */
10
+ export interface Sidebar {
11
+ /** Array of navigation items that can be either direct links or sections containing multiple links */
12
+ items: Item[]
13
+ }
14
+
15
+ /**
16
+ * A sidebar navigation item that can be either a direct link or a section containing multiple links.
17
+ * @see {@link ItemLink} for direct navigation links
18
+ * @see {@link ItemSection} for grouped navigation sections
19
+ */
20
+ export type Item = ItemLink | ItemSection
21
+
22
+ /**
23
+ * A direct navigation link in the sidebar.
24
+ * Used for pages that don't have child pages.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * const link: ItemLink = {
29
+ * type: 'ItemLink',
30
+ * title: 'Getting Started',
31
+ * pathExp: 'guide/getting-started'
32
+ * }
33
+ * ```
34
+ */
35
+ export interface ItemLink {
36
+ /** Discriminator for TypeScript union types */
37
+ type: `ItemLink`
38
+ /** Display title for the link (e.g., "Getting Started") */
39
+ title: string
40
+ /** Path expression relative to the base path, without leading slash (e.g., "guide/getting-started") */
41
+ pathExp: string
42
+ }
43
+
44
+ /**
45
+ * A collapsible section in the sidebar that groups related links.
46
+ * Used for directories that contain multiple pages.
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * const section: ItemSection = {
51
+ * type: 'ItemSection',
52
+ * title: 'Guide',
53
+ * pathExp: 'guide',
54
+ * isLinkToo: true, // Has an index page
55
+ * links: [
56
+ * { type: 'ItemLink', title: 'Installation', pathExp: 'guide/installation' },
57
+ * { type: 'ItemLink', title: 'Configuration', pathExp: 'guide/configuration' }
58
+ * ]
59
+ * }
60
+ * ```
61
+ */
62
+ export interface ItemSection {
63
+ /** Discriminator for TypeScript union types */
64
+ type: `ItemSection`
65
+ /** Display title for the section (e.g., "Guide", "API Reference") */
66
+ title: string
67
+ /** Path expression for the section's index page, if it exists (e.g., "guide") */
68
+ pathExp: string
69
+ /** Whether this section also acts as a link (true if the directory has an index page) */
70
+ isLinkToo: boolean
71
+ /** Child navigation links within this section */
72
+ links: ItemLink[]
73
+ }
74
+
75
+ /**
76
+ * A mapping of route paths to their corresponding sidebar structures.
77
+ * Used to store different sidebars for different sections of a site.
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * const sidebarIndex: SidebarIndex = {
82
+ * '/guide': { items: [...] }, // Sidebar for /guide section
83
+ * '/api': { items: [...] }, // Sidebar for /api section
84
+ * '/reference': { items: [...] } // Sidebar for /reference section
85
+ * }
86
+ * ```
87
+ */
88
+ export type SidebarIndex = Record<string, Sidebar>
89
+
90
+ /**
91
+ * Builds sidebars for all top-level directories that contain both an index page and nested content.
92
+ *
93
+ * This function analyzes a scan result to identify which directories should have sidebars.
94
+ * A directory gets a sidebar if it meets these criteria:
95
+ * 1. It's a top-level directory (e.g., /guide, /api, /docs)
96
+ * 2. It has an index page (e.g., /guide/index.md)
97
+ * 3. It has nested pages (e.g., /guide/getting-started.md, /guide/configuration.md)
98
+ *
99
+ * @param scanResult - The result of scanning pages, containing both a flat list and tree structure
100
+ * @returns A mapping of route paths to sidebar structures
101
+ *
102
+ * @example
103
+ * ```ts
104
+ * const scanResult = await Content.scan({ dir: './pages' })
105
+ * const sidebars = buildSidebarIndex(scanResult)
106
+ * // Returns: {
107
+ * // '/guide': { items: [...] },
108
+ * // '/api': { items: [...] }
109
+ * // }
110
+ * ```
111
+ */
112
+ export const buildSidebarIndex = (scanResult: ScanResult): SidebarIndex => {
113
+ const sidebarIndex: SidebarIndex = {}
114
+
115
+ // Group pages by their top-level directory
116
+ const pagesByTopLevelDir = new Map<string, Page[]>()
117
+
118
+ for (const page of scanResult.list) {
119
+ const topLevelDir = page.route.logical.path[0]
120
+
121
+ // Skip pages that are not in a directory or are hidden
122
+ if (!topLevelDir || page.metadata.hidden) continue
123
+
124
+ if (!pagesByTopLevelDir.has(topLevelDir)) {
125
+ pagesByTopLevelDir.set(topLevelDir, [])
126
+ }
127
+ pagesByTopLevelDir.get(topLevelDir)!.push(page)
128
+ }
129
+
130
+ // Build sidebar for each directory that has an index page
131
+ for (const [topLevelDir, pages] of pagesByTopLevelDir) {
132
+ const hasIndexPage = pages.some(page =>
133
+ page.route.logical.path.length === 1
134
+ && FileRouter.routeIsFromIndexFile(page.route)
135
+ )
136
+
137
+ // Skip directories without index pages
138
+ if (!hasIndexPage) continue
139
+
140
+ const pathExp = `/${topLevelDir}`
141
+ const sidebar = buildSidebarForDirectory(topLevelDir, pages)
142
+
143
+ if (sidebar.items.length > 0) {
144
+ sidebarIndex[pathExp] = sidebar
145
+ }
146
+ }
147
+
148
+ return sidebarIndex
149
+ }
150
+
151
+ /**
152
+ * Builds a sidebar for a specific directory from its pages
153
+ */
154
+ const buildSidebarForDirectory = (topLevelDir: string, pages: Page[]): Sidebar => {
155
+ const items: Item[] = []
156
+
157
+ // Group pages by their immediate parent path
158
+ const pagesByParent = new Map<string, Page[]>()
159
+
160
+ for (const page of pages) {
161
+ // Skip the index page at the top level directory
162
+ if (page.route.logical.path.length === 1 && FileRouter.routeIsFromIndexFile(page.route)) {
163
+ continue
164
+ }
165
+
166
+ // Get the immediate parent path (e.g., for ['guide', 'advanced', 'tips'], parent is ['guide', 'advanced'])
167
+ const parentPath = page.route.logical.path.slice(0, -1).join('/')
168
+
169
+ if (!pagesByParent.has(parentPath)) {
170
+ pagesByParent.set(parentPath, [])
171
+ }
172
+ pagesByParent.get(parentPath)!.push(page)
173
+ }
174
+
175
+ // Process top-level pages (direct children of the directory)
176
+ const topLevelPages = pagesByParent.get(topLevelDir) || []
177
+
178
+ // Sort pages by their directory order (extracted from file path)
179
+ const sortedTopLevelPages = [...topLevelPages].sort((a, b) => {
180
+ // For sections, we need to look at the directory name in the file path
181
+ const dirA = a.route.file.path.relative.dir.split('/').pop() || ''
182
+ const dirB = b.route.file.path.relative.dir.split('/').pop() || ''
183
+
184
+ // Extract order from directory names like "10_b", "20_c"
185
+ const orderMatchA = dirA.match(/^(\d+)[_-]/)
186
+ const orderMatchB = dirB.match(/^(\d+)[_-]/)
187
+
188
+ const orderA = orderMatchA ? parseInt(orderMatchA[1]!, 10) : Number.MAX_SAFE_INTEGER
189
+ const orderB = orderMatchB ? parseInt(orderMatchB[1]!, 10) : Number.MAX_SAFE_INTEGER
190
+
191
+ if (orderA !== orderB) return orderA - orderB
192
+
193
+ // Fall back to alphabetical order
194
+ return dirA.localeCompare(dirB)
195
+ })
196
+
197
+ for (const page of sortedTopLevelPages) {
198
+ const pageName = page.route.logical.path[page.route.logical.path.length - 1]!
199
+ const childPath = page.route.logical.path.join('/')
200
+ const childPages = pagesByParent.get(childPath) || []
201
+
202
+ if (childPages.length > 0 || FileRouter.routeIsFromIndexFile(page.route)) {
203
+ // This is a section (has children or is an index page for a subdirectory)
204
+ const hasIndex = FileRouter.routeIsFromIndexFile(page.route)
205
+
206
+ const section: ItemSection = {
207
+ type: 'ItemSection',
208
+ title: Str.titlizeSlug(pageName),
209
+ pathExp: childPath,
210
+ isLinkToo: hasIndex,
211
+ links: [],
212
+ }
213
+
214
+ // Add direct children as links (sorted by order)
215
+ const sortedChildPages = [...childPages].sort((a, b) => {
216
+ const orderA = a.route.logical.order ?? Number.MAX_SAFE_INTEGER
217
+ const orderB = b.route.logical.order ?? Number.MAX_SAFE_INTEGER
218
+ return orderA - orderB
219
+ })
220
+
221
+ for (const childPage of sortedChildPages) {
222
+ if (!FileRouter.routeIsFromIndexFile(childPage.route)) {
223
+ section.links.push({
224
+ type: 'ItemLink',
225
+ title: Str.titlizeSlug(childPage.route.logical.path[childPage.route.logical.path.length - 1]!),
226
+ pathExp: childPage.route.logical.path.join('/'),
227
+ })
228
+ }
229
+ }
230
+
231
+ // Also add any deeper descendants as flat links
232
+ const allDescendants: Page[] = []
233
+ for (const [parentPath, pagesInParent] of pagesByParent) {
234
+ // Check if this path is a descendant (but not direct child)
235
+ if (parentPath.startsWith(childPath + '/')) {
236
+ for (const descendantPage of pagesInParent) {
237
+ if (!FileRouter.routeIsFromIndexFile(descendantPage.route)) {
238
+ allDescendants.push(descendantPage)
239
+ }
240
+ }
241
+ }
242
+ }
243
+
244
+ // Sort all descendants by their full path order
245
+ allDescendants.sort((a, b) => {
246
+ // Compare paths segment by segment, considering order at each level
247
+ const pathA = a.route.logical.path
248
+ const pathB = b.route.logical.path
249
+ const minLength = Math.min(pathA.length, pathB.length)
250
+
251
+ for (let i = 0; i < minLength; i++) {
252
+ const segmentCompare = pathA[i]!.localeCompare(pathB[i]!)
253
+ if (segmentCompare !== 0) return segmentCompare
254
+ }
255
+
256
+ return pathA.length - pathB.length
257
+ })
258
+
259
+ for (const descendantPage of allDescendants) {
260
+ section.links.push({
261
+ type: 'ItemLink',
262
+ title: Str.titlizeSlug(
263
+ descendantPage.route.logical.path[descendantPage.route.logical.path.length - 1]!,
264
+ ),
265
+ pathExp: descendantPage.route.logical.path.join('/'),
266
+ })
267
+ }
268
+
269
+ if (section.links.length > 0 || section.isLinkToo) {
270
+ items.push(section)
271
+ }
272
+ } else {
273
+ // This is a simple link
274
+ items.push({
275
+ type: 'ItemLink',
276
+ title: Str.titlizeSlug(pageName),
277
+ pathExp: page.route.logical.path.join('/'),
278
+ })
279
+ }
280
+ }
281
+
282
+ return { items }
283
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Check if a file path represents a page file (markdown or MDX)
3
+ */
4
+ export const isPageFile = (filePath: string, pagesDirectory: string): boolean => {
5
+ return (filePath.endsWith(`.md`) || filePath.endsWith(`.mdx`))
6
+ && filePath.includes(pagesDirectory)
7
+ }
@@ -1,13 +1,14 @@
1
1
  import { Grafaid } from '#lib/grafaid/index'
2
2
  import { GraphqlChange } from '#lib/graphql-change/index'
3
3
  import type { GraphqlChangeset } from '#lib/graphql-changeset/index'
4
- import { debug as debugPolen } from '#singletons/debug'
4
+ import { debugPolen } from '#singletons/debug'
5
5
  import { Arr, Path } from '@wollybeard/kit'
6
6
  import { glob } from 'tinyglobby'
7
7
  import type { Schema } from '../../schema.ts'
8
8
  import { FileNameExpression } from './file-name-expression/index.ts'
9
9
 
10
- const debug = debugPolen.sub([`schema`, `data-source-schema-directory`])
10
+ // const debug = debugPolen.sub([`schema`, `data-source-schema-directory`])
11
+ const debug = debugPolen.sub(`schema:data-source-schema-directory`)
11
12
 
12
13
  const defaultPaths = {
13
14
  schemaDirectory: `./schema`,
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, test } from 'vitest'
2
- import { parse } from './markdown.js'
2
+ import { parse } from './markdown.ts'
3
3
 
4
4
  describe(`markdown parser with syntax highlighting`, () => {
5
5
  test(`parse highlights code blocks`, async () => {
@@ -0,0 +1 @@
1
+ export * as Static from './static.ts'
@@ -0,0 +1,106 @@
1
+ import { Err, Fs, Path } from '@wollybeard/kit'
2
+ import { afterEach, beforeEach, describe, expect, test } from 'vitest'
3
+ import { buildManifest, type PolenBuildManifest } from './manifest.ts'
4
+
5
+ describe('validate-build', () => {
6
+ let testDir: string
7
+ let manifestPath: string
8
+
9
+ beforeEach(async () => {
10
+ testDir = await Fs.makeTemporaryDirectory()
11
+ manifestPath = Path.join(testDir, '.polen', 'build.json')
12
+ })
13
+
14
+ afterEach(async () => {
15
+ if (testDir && await Fs.exists(testDir)) {
16
+ await Fs.remove(testDir)
17
+ }
18
+ })
19
+
20
+ describe('readBuildManifest', () => {
21
+ test('reads valid manifest', async () => {
22
+ const manifest: PolenBuildManifest = {
23
+ type: 'ssr',
24
+ version: '2.1.0',
25
+ basePath: '/docs/',
26
+ }
27
+ await Fs.write({
28
+ path: manifestPath,
29
+ content: JSON.stringify(manifest, null, 2),
30
+ })
31
+
32
+ const result = await buildManifest.read(testDir)
33
+ expect(Err.is(result)).toBe(false)
34
+ expect(result).toEqual(manifest)
35
+ })
36
+
37
+ test('returns error when manifest does not exist', async () => {
38
+ // Verify the file doesn't exist
39
+ const manifestExists = await Fs.exists(manifestPath)
40
+ expect(manifestExists).toBe(false)
41
+
42
+ const result = await buildManifest.read(testDir)
43
+ expect(Err.is(result)).toBe(true)
44
+ })
45
+
46
+ test('returns error for invalid manifest structure', async () => {
47
+ await Fs.write({
48
+ path: manifestPath,
49
+ content: JSON.stringify({ invalid: 'data' }, null, 2),
50
+ })
51
+ const result = await buildManifest.read(testDir)
52
+ expect(Err.is(result)).toBe(true)
53
+ })
54
+
55
+ test('returns error for invalid build type', async () => {
56
+ await Fs.write({
57
+ path: manifestPath,
58
+ content: JSON.stringify(
59
+ {
60
+ type: 'invalid',
61
+ version: '1.0.0',
62
+ basePath: '/',
63
+ },
64
+ null,
65
+ 2,
66
+ ),
67
+ })
68
+ const result = await buildManifest.read(testDir)
69
+ expect(Err.is(result)).toBe(true)
70
+ })
71
+
72
+ test('returns error when version is not a string', async () => {
73
+ await Fs.write({
74
+ path: manifestPath,
75
+ content: JSON.stringify(
76
+ {
77
+ type: 'ssg',
78
+ version: 123,
79
+ basePath: '/',
80
+ },
81
+ null,
82
+ 2,
83
+ ),
84
+ })
85
+ const result = await buildManifest.read(testDir)
86
+ expect(Err.is(result)).toBe(true)
87
+ })
88
+
89
+ test('returns error when basePath is not a string', async () => {
90
+ await Fs.write({
91
+ path: manifestPath,
92
+ content: JSON.stringify(
93
+ {
94
+ type: 'ssg',
95
+ version: '1.0.0',
96
+ basePath: null,
97
+ },
98
+ null,
99
+ 2,
100
+ ),
101
+ })
102
+ const result = await buildManifest.read(testDir)
103
+ expect(Err.is(result)).toBe(true)
104
+ })
105
+ })
106
+ })
@@ -0,0 +1,16 @@
1
+ import { Codec, Resource } from '@wollybeard/kit'
2
+ import { z } from 'zod/v4'
3
+
4
+ export const PolenBuildManifestSchema = z.object({
5
+ type: z.enum(['ssg', 'ssr']),
6
+ version: z.string(),
7
+ basePath: z.string(),
8
+ }).loose()
9
+
10
+ export type PolenBuildManifest = z.infer<typeof PolenBuildManifestSchema>
11
+
12
+ export const buildManifest = Resource.create({
13
+ name: 'polen-build-manifest',
14
+ path: '.polen/build.json',
15
+ codec: Codec.fromZod(PolenBuildManifestSchema),
16
+ })
@@ -0,0 +1,229 @@
1
+ import { Fs, Path } from '@wollybeard/kit'
2
+ import { afterEach, beforeEach, describe, expect, test } from 'vitest'
3
+ import { rebase, type RebasePlan } from './rebase.ts'
4
+
5
+ const testDir = 'temp/rebase-test'
6
+
7
+ const createTestBuild = async (dir: string, basePath: string = '/') => {
8
+ await Fs.makeDirectory(dir)
9
+
10
+ // Create Polen build manifest
11
+ const polenDir = Path.join(dir, '.polen')
12
+ await Fs.makeDirectory(polenDir)
13
+
14
+ const manifest = {
15
+ type: 'ssg' as const,
16
+ version: '1.0.0',
17
+ basePath,
18
+ }
19
+
20
+ await Fs.write({
21
+ path: Path.join(polenDir, 'build.json'),
22
+ content: JSON.stringify(manifest, null, 2),
23
+ })
24
+
25
+ // Create some HTML files
26
+ await Fs.write({
27
+ path: Path.join(dir, 'index.html'),
28
+ content: `<!DOCTYPE html>
29
+ <html>
30
+ <head>
31
+ <base href="${basePath}">
32
+ <title>Test</title>
33
+ </head>
34
+ <body>
35
+ <h1>Test Page</h1>
36
+ </body>
37
+ </html>`,
38
+ })
39
+
40
+ // Create nested HTML file
41
+ const nestedDir = Path.join(dir, 'docs')
42
+ await Fs.makeDirectory(nestedDir)
43
+
44
+ await Fs.write({
45
+ path: Path.join(nestedDir, 'page.html'),
46
+ content: `<!DOCTYPE html>
47
+ <html>
48
+ <head>
49
+ <title>Nested</title>
50
+ </head>
51
+ <body>
52
+ <h1>Nested Page</h1>
53
+ </body>
54
+ </html>`,
55
+ })
56
+ }
57
+
58
+ describe('rebase', () => {
59
+ beforeEach(async () => {
60
+ await Fs.remove(testDir)
61
+ })
62
+
63
+ afterEach(async () => {
64
+ await Fs.remove(testDir)
65
+ })
66
+
67
+ test('mutate mode updates base paths in place', async () => {
68
+ const buildDir = Path.join(testDir, 'build')
69
+ await createTestBuild(buildDir, '/old/')
70
+
71
+ const plan: RebasePlan = {
72
+ sourcePath: buildDir,
73
+ newBasePath: '/new/',
74
+ changeMode: 'mutate',
75
+ }
76
+
77
+ await rebase(plan)
78
+
79
+ // Check updated manifest
80
+ const manifest = await Fs.readJson(Path.join(buildDir, '.polen', 'build.json'))
81
+ expect(manifest).toMatchObject({
82
+ type: 'ssg',
83
+ version: '1.0.0',
84
+ basePath: '/new/',
85
+ })
86
+
87
+ // Check updated HTML file
88
+ const indexContent = await Fs.read(Path.join(buildDir, 'index.html'))
89
+ expect(indexContent).toContain('<base href="/new/">')
90
+
91
+ // Check nested HTML file (should have base tag inserted)
92
+ const nestedContent = await Fs.read(Path.join(buildDir, 'docs', 'page.html'))
93
+ expect(nestedContent).toContain('<base href="/new/">')
94
+ })
95
+
96
+ test('copy mode creates new build with updated base paths', async () => {
97
+ const buildDir = Path.join(testDir, 'build')
98
+ const copyDir = Path.join(testDir, 'copy')
99
+
100
+ await createTestBuild(buildDir, '/old/')
101
+
102
+ const plan: RebasePlan = {
103
+ sourcePath: buildDir,
104
+ targetPath: copyDir,
105
+ newBasePath: '/new/',
106
+ changeMode: 'copy',
107
+ }
108
+
109
+ await rebase(plan)
110
+
111
+ // Original should be unchanged
112
+ const originalManifest = await Fs.readJson(Path.join(buildDir, '.polen', 'build.json'))
113
+ expect(originalManifest).toMatchObject({
114
+ basePath: '/old/',
115
+ })
116
+
117
+ // Copy should be updated
118
+ const copyManifest = await Fs.readJson(Path.join(copyDir, '.polen', 'build.json'))
119
+ expect(copyManifest).toMatchObject({
120
+ basePath: '/new/',
121
+ })
122
+
123
+ const copyIndexContent = await Fs.read(Path.join(copyDir, 'index.html'))
124
+ expect(copyIndexContent).toContain('<base href="/new/">')
125
+ })
126
+
127
+ test('throws error for invalid base path', async () => {
128
+ const buildDir = Path.join(testDir, 'build')
129
+ await createTestBuild(buildDir)
130
+
131
+ const plan: RebasePlan = {
132
+ sourcePath: buildDir,
133
+ newBasePath: 'invalid-path',
134
+ changeMode: 'mutate',
135
+ }
136
+
137
+ await expect(rebase(plan)).rejects.toThrow('Invalid base path: invalid-path')
138
+ })
139
+
140
+ test('throws error when source is not a Polen build', async () => {
141
+ const buildDir = Path.join(testDir, 'not-polen')
142
+ await Fs.makeDirectory(buildDir)
143
+
144
+ const plan: RebasePlan = {
145
+ sourcePath: buildDir,
146
+ newBasePath: '/new/',
147
+ changeMode: 'mutate',
148
+ }
149
+
150
+ await expect(rebase(plan)).rejects.toThrow('Polen build manifest not found')
151
+ })
152
+
153
+ test('throws error when copy target exists and is not empty', async () => {
154
+ const buildDir = Path.join(testDir, 'build')
155
+ const copyDir = Path.join(testDir, 'copy')
156
+
157
+ await createTestBuild(buildDir)
158
+
159
+ // Create non-empty target
160
+ await Fs.makeDirectory(copyDir)
161
+ await Fs.write({
162
+ path: Path.join(copyDir, 'existing.txt'),
163
+ content: 'existing file',
164
+ })
165
+
166
+ const plan: RebasePlan = {
167
+ sourcePath: buildDir,
168
+ targetPath: copyDir,
169
+ newBasePath: '/new/',
170
+ changeMode: 'copy',
171
+ }
172
+
173
+ await expect(rebase(plan)).rejects.toThrow('Target path already exists and is not empty')
174
+ })
175
+
176
+ test('handles HTML file without existing base tag', async () => {
177
+ const buildDir = Path.join(testDir, 'build')
178
+ await createTestBuild(buildDir)
179
+
180
+ // Create HTML without base tag
181
+ await Fs.write({
182
+ path: Path.join(buildDir, 'no-base.html'),
183
+ content: `<!DOCTYPE html>
184
+ <html>
185
+ <head>
186
+ <title>No Base</title>
187
+ </head>
188
+ <body>
189
+ <h1>No Base Tag</h1>
190
+ </body>
191
+ </html>`,
192
+ })
193
+
194
+ const plan: RebasePlan = {
195
+ sourcePath: buildDir,
196
+ newBasePath: '/new/',
197
+ changeMode: 'mutate',
198
+ }
199
+
200
+ await rebase(plan)
201
+
202
+ const content = await Fs.read(Path.join(buildDir, 'no-base.html'))
203
+ expect(content).toContain('<base href="/new/">')
204
+ })
205
+
206
+ test('throws error for HTML file without head tag', async () => {
207
+ const buildDir = Path.join(testDir, 'build')
208
+ await createTestBuild(buildDir)
209
+
210
+ // Create invalid HTML without head
211
+ await Fs.write({
212
+ path: Path.join(buildDir, 'invalid.html'),
213
+ content: `<!DOCTYPE html>
214
+ <html>
215
+ <body>
216
+ <h1>Invalid HTML</h1>
217
+ </body>
218
+ </html>`,
219
+ })
220
+
221
+ const plan: RebasePlan = {
222
+ sourcePath: buildDir,
223
+ newBasePath: '/new/',
224
+ changeMode: 'mutate',
225
+ }
226
+
227
+ await expect(rebase(plan)).rejects.toThrow('Could not find <head> tag in HTML file')
228
+ })
229
+ })