polen 0.9.1-next.2 → 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 (460) 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.js +1 -1
  47. package/build/api/schema/data-sources/schema-directory/schema-directory.js.map +1 -1
  48. package/build/api/static/index.d.ts +2 -0
  49. package/build/api/static/index.d.ts.map +1 -0
  50. package/build/api/static/index.js +2 -0
  51. package/build/api/static/index.js.map +1 -0
  52. package/build/api/static/manifest.d.ts +18 -0
  53. package/build/api/static/manifest.d.ts.map +1 -0
  54. package/build/api/static/manifest.js +13 -0
  55. package/build/api/static/manifest.js.map +1 -0
  56. package/build/api/static/rebase.d.ts +14 -0
  57. package/build/api/static/rebase.d.ts.map +1 -0
  58. package/build/api/static/rebase.js +110 -0
  59. package/build/api/static/rebase.js.map +1 -0
  60. package/build/api/static/static.d.ts +3 -0
  61. package/build/api/static/static.d.ts.map +1 -0
  62. package/build/api/static/static.js +3 -0
  63. package/build/api/static/static.js.map +1 -0
  64. package/build/api/vite/plugins/branding/index.d.ts +4 -0
  65. package/build/api/vite/plugins/branding/index.d.ts.map +1 -0
  66. package/build/api/vite/plugins/branding/index.js +80 -0
  67. package/build/api/vite/plugins/branding/index.js.map +1 -0
  68. package/build/api/vite/plugins/build.d.ts.map +1 -1
  69. package/build/api/vite/plugins/build.js +22 -1
  70. package/build/api/vite/plugins/build.js.map +1 -1
  71. package/build/api/vite/plugins/core.d.ts +2 -2
  72. package/build/api/vite/plugins/core.d.ts.map +1 -1
  73. package/build/api/vite/plugins/core.js +4 -5
  74. package/build/api/vite/plugins/core.js.map +1 -1
  75. package/build/api/vite/plugins/main.d.ts.map +1 -1
  76. package/build/api/vite/plugins/main.js +2 -1
  77. package/build/api/vite/plugins/main.js.map +1 -1
  78. package/build/api/vite/plugins/pages.d.ts +8 -14
  79. package/build/api/vite/plugins/pages.d.ts.map +1 -1
  80. package/build/api/vite/plugins/pages.js +110 -183
  81. package/build/api/vite/plugins/pages.js.map +1 -1
  82. package/build/api/vite/plugins/serve.js +5 -5
  83. package/build/api/vite/plugins/serve.js.map +1 -1
  84. package/build/cli/_/self-contained-mode.js +5 -5
  85. package/build/cli/_/self-contained-mode.js.map +1 -1
  86. package/build/cli/commands/static/$default.d.ts +3 -0
  87. package/build/cli/commands/static/$default.d.ts.map +1 -0
  88. package/build/cli/commands/static/$default.js +38 -0
  89. package/build/cli/commands/static/$default.js.map +1 -0
  90. package/build/cli/commands/static/rebase.d.ts +2 -0
  91. package/build/cli/commands/static/rebase.d.ts.map +1 -0
  92. package/build/cli/commands/static/rebase.js +26 -0
  93. package/build/cli/commands/static/rebase.js.map +1 -0
  94. package/build/cli/commands/static.d.ts +3 -0
  95. package/build/cli/commands/static.d.ts.map +1 -0
  96. package/build/cli/commands/static.js +5 -0
  97. package/build/cli/commands/static.js.map +1 -0
  98. package/build/exports/components.d.ts +2 -0
  99. package/build/exports/components.d.ts.map +1 -0
  100. package/build/exports/components.js +2 -0
  101. package/build/exports/components.js.map +1 -0
  102. package/build/lib/demos/builder.d.ts +83 -0
  103. package/build/lib/demos/builder.d.ts.map +1 -0
  104. package/build/lib/demos/builder.js +237 -0
  105. package/build/lib/demos/builder.js.map +1 -0
  106. package/build/lib/demos/config-schema.d.ts +243 -0
  107. package/build/lib/demos/config-schema.d.ts.map +1 -0
  108. package/build/lib/demos/config-schema.js +52 -0
  109. package/build/lib/demos/config-schema.js.map +1 -0
  110. package/build/lib/demos/config.d.ts +40 -0
  111. package/build/lib/demos/config.d.ts.map +1 -0
  112. package/build/lib/demos/config.js +180 -0
  113. package/build/lib/demos/config.js.map +1 -0
  114. package/build/lib/demos/index.d.ts +9 -0
  115. package/build/lib/demos/index.d.ts.map +1 -0
  116. package/build/lib/demos/index.js +8 -0
  117. package/build/lib/demos/index.js.map +1 -0
  118. package/build/lib/demos/ui/components.d.ts +33 -0
  119. package/build/lib/demos/ui/components.d.ts.map +1 -0
  120. package/build/lib/demos/ui/components.js +699 -0
  121. package/build/lib/demos/ui/components.js.map +1 -0
  122. package/build/lib/demos/ui/data-collector.d.ts +88 -0
  123. package/build/lib/demos/ui/data-collector.d.ts.map +1 -0
  124. package/build/lib/demos/ui/data-collector.js +174 -0
  125. package/build/lib/demos/ui/data-collector.js.map +1 -0
  126. package/build/lib/demos/ui/landing-page-cli.d.ts +3 -0
  127. package/build/lib/demos/ui/landing-page-cli.d.ts.map +1 -0
  128. package/build/lib/demos/ui/landing-page-cli.js +21 -0
  129. package/build/lib/demos/ui/landing-page-cli.js.map +1 -0
  130. package/build/lib/demos/ui/landing-page.d.ts +32 -0
  131. package/build/lib/demos/ui/landing-page.d.ts.map +1 -0
  132. package/build/lib/demos/ui/landing-page.js +83 -0
  133. package/build/lib/demos/ui/landing-page.js.map +1 -0
  134. package/build/lib/demos/ui/page-renderer.d.ts +26 -0
  135. package/build/lib/demos/ui/page-renderer.d.ts.map +1 -0
  136. package/build/lib/demos/ui/page-renderer.js +104 -0
  137. package/build/lib/demos/ui/page-renderer.js.map +1 -0
  138. package/build/lib/demos/utils.d.ts +14 -0
  139. package/build/lib/demos/utils.d.ts.map +1 -0
  140. package/build/lib/demos/utils.js +37 -0
  141. package/build/lib/demos/utils.js.map +1 -0
  142. package/build/lib/deployment/$$.d.ts +3 -0
  143. package/build/lib/deployment/$$.d.ts.map +1 -0
  144. package/build/lib/deployment/$$.js +3 -0
  145. package/build/lib/deployment/$$.js.map +1 -0
  146. package/build/lib/deployment/$.d.ts +2 -0
  147. package/build/lib/deployment/$.d.ts.map +1 -0
  148. package/build/lib/deployment/$.js +2 -0
  149. package/build/lib/deployment/$.js.map +1 -0
  150. package/build/lib/deployment/metadata.d.ts +32 -0
  151. package/build/lib/deployment/metadata.d.ts.map +1 -0
  152. package/build/lib/deployment/metadata.js +37 -0
  153. package/build/lib/deployment/metadata.js.map +1 -0
  154. package/build/lib/deployment/path-manager.d.ts +41 -0
  155. package/build/lib/deployment/path-manager.d.ts.map +1 -0
  156. package/build/lib/deployment/path-manager.js +157 -0
  157. package/build/lib/deployment/path-manager.js.map +1 -0
  158. package/build/lib/file-router/file-router.d.ts +0 -2
  159. package/build/lib/file-router/file-router.d.ts.map +1 -1
  160. package/build/lib/file-router/file-router.js +0 -2
  161. package/build/lib/file-router/file-router.js.map +1 -1
  162. package/build/lib/file-router/route.d.ts +2 -0
  163. package/build/lib/file-router/route.d.ts.map +1 -1
  164. package/build/lib/file-router/route.js.map +1 -1
  165. package/build/lib/file-router/scan.d.ts.map +1 -1
  166. package/build/lib/file-router/scan.js +22 -13
  167. package/build/lib/file-router/scan.js.map +1 -1
  168. package/build/lib/github-actions/git-controller.d.ts +50 -0
  169. package/build/lib/github-actions/git-controller.d.ts.map +1 -0
  170. package/build/lib/github-actions/git-controller.js +90 -0
  171. package/build/lib/github-actions/git-controller.js.map +1 -0
  172. package/build/lib/github-actions/github-actions.d.ts +7 -0
  173. package/build/lib/github-actions/github-actions.d.ts.map +1 -0
  174. package/build/lib/github-actions/github-actions.js +7 -0
  175. package/build/lib/github-actions/github-actions.js.map +1 -0
  176. package/build/lib/github-actions/index.d.ts +2 -0
  177. package/build/lib/github-actions/index.d.ts.map +1 -0
  178. package/build/lib/github-actions/index.js +2 -0
  179. package/build/lib/github-actions/index.js.map +1 -0
  180. package/build/lib/github-actions/lib/get-pr-deployments.d.ts +12 -0
  181. package/build/lib/github-actions/lib/get-pr-deployments.d.ts.map +1 -0
  182. package/build/lib/github-actions/lib/get-pr-deployments.js +51 -0
  183. package/build/lib/github-actions/lib/get-pr-deployments.js.map +1 -0
  184. package/build/lib/github-actions/pr-controller.d.ts +39 -0
  185. package/build/lib/github-actions/pr-controller.d.ts.map +1 -0
  186. package/build/lib/github-actions/pr-controller.js +122 -0
  187. package/build/lib/github-actions/pr-controller.js.map +1 -0
  188. package/build/lib/github-actions/run-step-cli.d.ts +9 -0
  189. package/build/lib/github-actions/run-step-cli.d.ts.map +1 -0
  190. package/build/lib/github-actions/run-step-cli.js +71 -0
  191. package/build/lib/github-actions/run-step-cli.js.map +1 -0
  192. package/build/lib/github-actions/runner.d.ts +17 -0
  193. package/build/lib/github-actions/runner.d.ts.map +1 -0
  194. package/build/lib/github-actions/runner.js +195 -0
  195. package/build/lib/github-actions/runner.js.map +1 -0
  196. package/build/lib/github-actions/schemas/context.d.ts +933 -0
  197. package/build/lib/github-actions/schemas/context.d.ts.map +1 -0
  198. package/build/lib/github-actions/schemas/context.js +407 -0
  199. package/build/lib/github-actions/schemas/context.js.map +1 -0
  200. package/build/lib/github-actions/schemas/index.d.ts +5 -0
  201. package/build/lib/github-actions/schemas/index.d.ts.map +1 -0
  202. package/build/lib/github-actions/schemas/index.js +5 -0
  203. package/build/lib/github-actions/schemas/index.js.map +1 -0
  204. package/build/lib/github-actions/search-module.d.ts +38 -0
  205. package/build/lib/github-actions/search-module.d.ts.map +1 -0
  206. package/build/lib/github-actions/search-module.js +40 -0
  207. package/build/lib/github-actions/search-module.js.map +1 -0
  208. package/build/lib/github-actions/step.d.ts +163 -0
  209. package/build/lib/github-actions/step.d.ts.map +1 -0
  210. package/build/lib/github-actions/step.js +121 -0
  211. package/build/lib/github-actions/step.js.map +1 -0
  212. package/build/lib/helpers.d.ts.map +1 -1
  213. package/build/lib/helpers.js +5 -3
  214. package/build/lib/helpers.js.map +1 -1
  215. package/build/lib/kit-temp.d.ts +54 -0
  216. package/build/lib/kit-temp.d.ts.map +1 -1
  217. package/build/lib/kit-temp.js +82 -14
  218. package/build/lib/kit-temp.js.map +1 -1
  219. package/build/lib/kit-temp.test-d.d.ts +2 -0
  220. package/build/lib/kit-temp.test-d.d.ts.map +1 -0
  221. package/build/lib/kit-temp.test-d.js +75 -0
  222. package/build/lib/kit-temp.test-d.js.map +1 -0
  223. package/build/lib/mask/$$.d.ts +3 -0
  224. package/build/lib/mask/$$.d.ts.map +1 -0
  225. package/build/lib/mask/$$.js +3 -0
  226. package/build/lib/mask/$$.js.map +1 -0
  227. package/build/lib/mask/$.d.ts +2 -0
  228. package/build/lib/mask/$.d.ts.map +1 -0
  229. package/build/lib/mask/$.js +2 -0
  230. package/build/lib/mask/$.js.map +1 -0
  231. package/build/lib/mask/apply.d.ts +86 -0
  232. package/build/lib/mask/apply.d.ts.map +1 -0
  233. package/build/lib/mask/apply.js +86 -0
  234. package/build/lib/mask/apply.js.map +1 -0
  235. package/build/lib/mask/mask.d.ts +124 -0
  236. package/build/lib/mask/mask.d.ts.map +1 -0
  237. package/build/lib/mask/mask.js +137 -0
  238. package/build/lib/mask/mask.js.map +1 -0
  239. package/build/lib/mask/mask.test-d.d.ts +2 -0
  240. package/build/lib/mask/mask.test-d.d.ts.map +1 -0
  241. package/build/lib/mask/mask.test-d.js +102 -0
  242. package/build/lib/mask/mask.test-d.js.map +1 -0
  243. package/build/lib/mutation-type.d.ts +18 -0
  244. package/build/lib/mutation-type.d.ts.map +1 -0
  245. package/build/lib/mutation-type.js +16 -0
  246. package/build/lib/mutation-type.js.map +1 -0
  247. package/build/lib/task/$$.d.ts +3 -0
  248. package/build/lib/task/$$.d.ts.map +1 -0
  249. package/build/lib/task/$$.js +3 -0
  250. package/build/lib/task/$$.js.map +1 -0
  251. package/build/lib/task/$.d.ts +2 -0
  252. package/build/lib/task/$.d.ts.map +1 -0
  253. package/build/lib/task/$.js +2 -0
  254. package/build/lib/task/$.js.map +1 -0
  255. package/build/lib/task/report.d.ts +28 -0
  256. package/build/lib/task/report.d.ts.map +1 -0
  257. package/build/lib/task/report.js +33 -0
  258. package/build/lib/task/report.js.map +1 -0
  259. package/build/lib/task/task.d.ts +44 -0
  260. package/build/lib/task/task.d.ts.map +1 -0
  261. package/build/lib/task/task.js +63 -0
  262. package/build/lib/task/task.js.map +1 -0
  263. package/build/lib/version-history/index.d.ts +3 -0
  264. package/build/lib/version-history/index.d.ts.map +1 -0
  265. package/build/lib/version-history/index.js +2 -0
  266. package/build/lib/version-history/index.js.map +1 -0
  267. package/build/lib/version-history/types.d.ts +64 -0
  268. package/build/lib/version-history/types.d.ts.map +1 -0
  269. package/build/lib/version-history/types.js +5 -0
  270. package/build/lib/version-history/types.js.map +1 -0
  271. package/build/lib/version-history/version-history.d.ts +85 -0
  272. package/build/lib/version-history/version-history.d.ts.map +1 -0
  273. package/build/lib/version-history/version-history.js +248 -0
  274. package/build/lib/version-history/version-history.js.map +1 -0
  275. package/build/project-data.d.ts +0 -1
  276. package/build/project-data.d.ts.map +1 -1
  277. package/build/sandbox.d.ts +2 -0
  278. package/build/sandbox.d.ts.map +1 -0
  279. package/build/sandbox.js +18 -0
  280. package/build/sandbox.js.map +1 -0
  281. package/build/singletons/debug.d.ts +1 -1
  282. package/build/singletons/debug.d.ts.map +1 -1
  283. package/build/singletons/debug.js +1 -1
  284. package/build/singletons/debug.js.map +1 -1
  285. package/build/template/components/HamburgerMenu.d.ts +9 -0
  286. package/build/template/components/HamburgerMenu.d.ts.map +1 -0
  287. package/build/template/components/HamburgerMenu.jsx +53 -0
  288. package/build/template/components/HamburgerMenu.jsx.map +1 -0
  289. package/build/template/components/Link.jsx +1 -1
  290. package/build/template/components/Logo.d.ts +9 -0
  291. package/build/template/components/Logo.d.ts.map +1 -0
  292. package/build/template/components/Logo.jsx +29 -0
  293. package/build/template/components/Logo.jsx.map +1 -0
  294. package/build/template/components/NotFound.d.ts +2 -0
  295. package/build/template/components/NotFound.d.ts.map +1 -0
  296. package/build/template/components/NotFound.jsx +26 -0
  297. package/build/template/components/NotFound.jsx.map +1 -0
  298. package/build/template/components/ThemeToggle.d.ts +3 -0
  299. package/build/template/components/ThemeToggle.d.ts.map +1 -0
  300. package/build/template/components/ThemeToggle.jsx +10 -0
  301. package/build/template/components/ThemeToggle.jsx.map +1 -0
  302. package/build/template/components/content/$$.d.ts +2 -0
  303. package/build/template/components/content/$$.d.ts.map +1 -0
  304. package/build/template/components/content/$$.js +2 -0
  305. package/build/template/components/content/$$.js.map +1 -0
  306. package/build/template/components/sidebar/Sidebar.d.ts +2 -2
  307. package/build/template/components/sidebar/Sidebar.d.ts.map +1 -1
  308. package/build/template/components/sidebar/SidebarItem.d.ts +3 -3
  309. package/build/template/components/sidebar/SidebarItem.d.ts.map +1 -1
  310. package/build/template/components/sidebar/SidebarItem.jsx +1 -1
  311. package/build/template/components/sidebar/SidebarItem.jsx.map +1 -1
  312. package/build/template/contexts/ThemeContext.d.ts +12 -0
  313. package/build/template/contexts/ThemeContext.d.ts.map +1 -0
  314. package/build/template/contexts/ThemeContext.jsx +41 -0
  315. package/build/template/contexts/ThemeContext.jsx.map +1 -0
  316. package/build/template/routes/root.d.ts.map +1 -1
  317. package/build/template/routes/root.jsx +66 -53
  318. package/build/template/routes/root.jsx.map +1 -1
  319. package/build/template/server/app.d.ts.map +1 -1
  320. package/build/template/server/app.js +2 -21
  321. package/build/template/server/app.js.map +1 -1
  322. package/package.json +27 -13
  323. package/src/api/api.ts +1 -0
  324. package/src/api/config/configurator.ts +28 -6
  325. package/src/api/config/load.ts +5 -5
  326. package/src/api/config-resolver/resolve.ts +2 -2
  327. package/src/api/content/$$.ts +6 -0
  328. package/src/api/content/$.test.ts +72 -0
  329. package/src/api/content/$.ts +1 -0
  330. package/src/api/content/metadata.ts +11 -0
  331. package/src/api/content/navbar.test.ts +55 -0
  332. package/src/api/content/navbar.ts +61 -0
  333. package/src/api/content/page.ts +12 -0
  334. package/src/api/content/scan.ts +117 -0
  335. package/src/api/content/sidebar.test.ts +297 -0
  336. package/src/api/content/sidebar.ts +283 -0
  337. package/src/api/content/utils.ts +7 -0
  338. package/src/api/schema/data-sources/schema-directory/schema-directory.ts +1 -1
  339. package/src/api/singletons/markdown/markdown.test.ts +1 -1
  340. package/src/api/static/index.ts +1 -0
  341. package/src/api/static/manifest.test.ts +106 -0
  342. package/src/api/static/manifest.ts +16 -0
  343. package/src/api/static/rebase.test.ts +229 -0
  344. package/src/api/static/rebase.ts +140 -0
  345. package/src/api/static/static.ts +2 -0
  346. package/src/api/utils/asset-url/asset-url.test.ts +4 -4
  347. package/src/api/vite/plugins/branding/index.ts +108 -0
  348. package/src/api/vite/plugins/build.ts +25 -1
  349. package/src/api/vite/plugins/core.ts +6 -7
  350. package/src/api/vite/plugins/main.ts +2 -0
  351. package/src/api/vite/plugins/pages.ts +131 -207
  352. package/src/api/vite/plugins/serve.ts +5 -5
  353. package/src/cli/_/self-contained-mode.ts +5 -5
  354. package/src/cli/commands/static/$default.ts +43 -0
  355. package/src/cli/commands/static/rebase.ts +37 -0
  356. package/src/cli/commands/static.ts +6 -0
  357. package/src/exports/components.ts +1 -0
  358. package/src/lib/demos/builder.ts +298 -0
  359. package/src/lib/demos/config-schema.ts +56 -0
  360. package/src/lib/demos/config.test.ts +193 -0
  361. package/src/lib/demos/config.ts +205 -0
  362. package/src/lib/demos/index.ts +9 -0
  363. package/src/lib/demos/ui/components.ts +739 -0
  364. package/src/lib/demos/ui/data-collector.ts +246 -0
  365. package/src/lib/demos/ui/landing-page-cli.ts +23 -0
  366. package/src/lib/demos/ui/landing-page.ts +126 -0
  367. package/src/lib/demos/ui/page-renderer.ts +124 -0
  368. package/src/lib/demos/utils.ts +43 -0
  369. package/src/lib/deployment/$$.ts +2 -0
  370. package/src/lib/deployment/$.test.ts +53 -0
  371. package/src/lib/deployment/$.ts +1 -0
  372. package/src/lib/deployment/metadata.ts +40 -0
  373. package/src/lib/deployment/path-manager.ts +186 -0
  374. package/src/lib/file-router/file-router.ts +0 -2
  375. package/src/lib/file-router/linter.test.ts +2 -0
  376. package/src/lib/file-router/route.ts +2 -0
  377. package/src/lib/file-router/scan.ts +26 -14
  378. package/src/lib/github-actions/git-controller.ts +151 -0
  379. package/src/lib/github-actions/github-actions.ts +6 -0
  380. package/src/lib/github-actions/index.ts +1 -0
  381. package/src/lib/github-actions/lib/get-pr-deployments.ts +76 -0
  382. package/src/lib/github-actions/pr-controller.test.ts +172 -0
  383. package/src/lib/github-actions/pr-controller.ts +183 -0
  384. package/src/lib/github-actions/run-step-cli.ts +84 -0
  385. package/src/lib/github-actions/runner.test.ts +192 -0
  386. package/src/lib/github-actions/runner.ts +226 -0
  387. package/src/lib/github-actions/schemas/context.ts +424 -0
  388. package/src/lib/github-actions/schemas/index.ts +5 -0
  389. package/src/lib/github-actions/search-module.test.ts +110 -0
  390. package/src/lib/github-actions/search-module.ts +76 -0
  391. package/src/lib/github-actions/step.test.ts +149 -0
  392. package/src/lib/github-actions/step.ts +232 -0
  393. package/src/lib/helpers.ts +4 -3
  394. package/src/lib/kit-temp.test-d.ts +115 -0
  395. package/src/lib/kit-temp.test.ts +127 -0
  396. package/src/lib/kit-temp.ts +128 -14
  397. package/src/lib/mask/$$.ts +2 -0
  398. package/src/lib/mask/$.test.ts +248 -0
  399. package/src/lib/mask/$.ts +1 -0
  400. package/src/lib/mask/apply.ts +134 -0
  401. package/src/lib/mask/mask.test-d.ts +144 -0
  402. package/src/lib/mask/mask.ts +244 -0
  403. package/src/lib/mutation-type.ts +20 -0
  404. package/src/lib/shiki/shiki.test.ts +1 -1
  405. package/src/lib/task/$$.ts +2 -0
  406. package/src/lib/task/$.test.ts +209 -0
  407. package/src/lib/task/$.ts +1 -0
  408. package/src/lib/task/report.ts +72 -0
  409. package/src/lib/task/task.ts +112 -0
  410. package/src/lib/version-history/index.test.ts +196 -0
  411. package/src/lib/version-history/index.ts +4 -0
  412. package/src/lib/version-history/types.ts +68 -0
  413. package/src/lib/version-history/version-history.ts +293 -0
  414. package/src/project-data.ts +0 -1
  415. package/src/sandbox.ts +20 -0
  416. package/src/singletons/debug.ts +1 -1
  417. package/src/template/components/HamburgerMenu.tsx +96 -0
  418. package/src/template/components/Link.tsx +1 -1
  419. package/src/template/components/Logo.tsx +46 -0
  420. package/src/template/components/NotFound.tsx +28 -0
  421. package/src/template/components/ThemeToggle.tsx +21 -0
  422. package/src/template/components/content/$$.ts +1 -0
  423. package/src/template/components/sidebar/Sidebar.tsx +2 -2
  424. package/src/template/components/sidebar/SidebarItem.tsx +8 -8
  425. package/src/template/contexts/ThemeContext.tsx +60 -0
  426. package/src/template/routes/root.tsx +85 -74
  427. package/src/template/server/app.ts +2 -27
  428. package/build/lib/file-router/scan-tree.d.ts +0 -20
  429. package/build/lib/file-router/scan-tree.d.ts.map +0 -1
  430. package/build/lib/file-router/scan-tree.js +0 -158
  431. package/build/lib/file-router/scan-tree.js.map +0 -1
  432. package/build/lib/file-router/sidebar/index.d.ts +0 -3
  433. package/build/lib/file-router/sidebar/index.d.ts.map +0 -1
  434. package/build/lib/file-router/sidebar/index.js +0 -4
  435. package/build/lib/file-router/sidebar/index.js.map +0 -1
  436. package/build/lib/file-router/sidebar/sidebar-tree.d.ts +0 -9
  437. package/build/lib/file-router/sidebar/sidebar-tree.d.ts.map +0 -1
  438. package/build/lib/file-router/sidebar/sidebar-tree.js +0 -85
  439. package/build/lib/file-router/sidebar/sidebar-tree.js.map +0 -1
  440. package/build/lib/file-router/sidebar/types.d.ts +0 -17
  441. package/build/lib/file-router/sidebar/types.d.ts.map +0 -1
  442. package/build/lib/file-router/sidebar/types.js +0 -2
  443. package/build/lib/file-router/sidebar/types.js.map +0 -1
  444. package/build/lib/tree/index.d.ts +0 -3
  445. package/build/lib/tree/index.d.ts.map +0 -1
  446. package/build/lib/tree/index.js +0 -2
  447. package/build/lib/tree/index.js.map +0 -1
  448. package/build/lib/tree/tree.d.ts +0 -62
  449. package/build/lib/tree/tree.d.ts.map +0 -1
  450. package/build/lib/tree/tree.js +0 -134
  451. package/build/lib/tree/tree.js.map +0 -1
  452. package/src/lib/file-router/scan-tree.test.ts +0 -189
  453. package/src/lib/file-router/scan-tree.ts +0 -205
  454. package/src/lib/file-router/sidebar/index.ts +0 -3
  455. package/src/lib/file-router/sidebar/sidebar-tree.test.ts +0 -123
  456. package/src/lib/file-router/sidebar/sidebar-tree.ts +0 -110
  457. package/src/lib/file-router/sidebar/types.ts +0 -19
  458. package/src/lib/tree/index.ts +0 -2
  459. package/src/lib/tree/tree.test.ts +0 -117
  460. package/src/lib/tree/tree.ts +0 -183
@@ -0,0 +1,149 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest'
2
+ import { z } from 'zod/v4'
3
+ import { createStep } from './step.ts'
4
+
5
+ describe('defineWorkflowStep', () => {
6
+ const mockCore = {
7
+ startGroup: vi.fn(),
8
+ endGroup: vi.fn(),
9
+ debug: vi.fn(),
10
+ info: vi.fn(),
11
+ warning: vi.fn(),
12
+ error: vi.fn(),
13
+ setOutput: vi.fn(),
14
+ } as any
15
+
16
+ const mockContext = {
17
+ core: mockCore,
18
+ github: {} as any,
19
+ context: {} as any,
20
+ $: {} as any,
21
+ fs: {} as any,
22
+ } as any
23
+
24
+ beforeEach(() => {
25
+ vi.clearAllMocks()
26
+ })
27
+
28
+ it('executes step with validated inputs', async () => {
29
+ const TestStep = createStep({
30
+ name: 'test-step',
31
+ description: 'Test step',
32
+ inputs: z.object({
33
+ required: z.string(),
34
+ optional: z.string().optional(),
35
+ }),
36
+ outputs: z.object({ result: z.string() }),
37
+ async run({ inputs }) {
38
+ return { result: `Got ${inputs.required}` }
39
+ },
40
+ })
41
+
42
+ // Create context with PR controller
43
+ const contextWithPR = {
44
+ ...mockContext,
45
+ pr: {
46
+ number: 0,
47
+ isActive: false,
48
+ comment: vi.fn(),
49
+ deleteComment: vi.fn(),
50
+ getComments: vi.fn(),
51
+ },
52
+ }
53
+
54
+ const result = await TestStep.run({
55
+ ...contextWithPR,
56
+ inputs: {
57
+ required: 'value',
58
+ optional: 'optional-value',
59
+ },
60
+ })
61
+
62
+ expect(result).toEqual({ result: 'Got value' })
63
+ })
64
+
65
+ it('validates output types', async () => {
66
+ const TestStep = createStep({
67
+ name: 'test-step',
68
+ description: 'Test step',
69
+ inputs: z.object({
70
+ required: z.string(),
71
+ }),
72
+ outputs: z.object({ result: z.string() }),
73
+ async run({ inputs }) {
74
+ return { result: inputs.required }
75
+ },
76
+ })
77
+
78
+ // Outputs are validated in the runner, not in execute
79
+ expect(TestStep.definition.outputsSchema).toBeDefined()
80
+ expect(TestStep.definition.inputsSchema).toBeDefined()
81
+ })
82
+
83
+ it('step definition contains all metadata', async () => {
84
+ const TestStep = createStep({
85
+ name: 'test-step',
86
+ description: 'Test step',
87
+ inputs: z.object({
88
+ number: z.number(),
89
+ }),
90
+ outputs: z.object({ result: z.string() }),
91
+ async run() {
92
+ return { result: 'ok' }
93
+ },
94
+ })
95
+
96
+ expect(TestStep.definition.name).toBe('test-step')
97
+ expect(TestStep.definition.description).toBe('Test step')
98
+ expect(TestStep.definition.inputsSchema).toBeDefined()
99
+ expect(TestStep.definition.outputsSchema).toBeDefined()
100
+ })
101
+
102
+ // todo: this test is now a static type error, update to refelct that
103
+ // it('does not warn for non-object schemas', async () => {
104
+ // const TestStep = defineStep({
105
+ // name: 'test-step',
106
+ // description: 'Test step',
107
+ // inputs: z.string(),
108
+ // outputs: z.object({ result: z.string() }),
109
+ // async run({ inputs }) {
110
+ // return { result: inputs }
111
+ // },
112
+ // })
113
+
114
+ // await TestStep(mockContext, 'just-a-string')
115
+
116
+ // expect(mockCore.warning).not.toHaveBeenCalled()
117
+ // })
118
+
119
+ it('always provides PR controller', async () => {
120
+ const mockPR = {
121
+ number: 123,
122
+ isActive: true,
123
+ comment: vi.fn(),
124
+ deleteComment: vi.fn(),
125
+ getComments: vi.fn(),
126
+ }
127
+
128
+ const contextWithPR = {
129
+ ...mockContext,
130
+ pr: mockPR,
131
+ }
132
+
133
+ const TestStep = createStep({
134
+ name: 'test-step',
135
+ description: 'Test step with PR',
136
+ inputs: z.object({}),
137
+ outputs: z.object({ isActive: z.boolean() }),
138
+ async run({ pr }) {
139
+ return { isActive: pr.isActive }
140
+ },
141
+ })
142
+
143
+ const result = await TestStep.run({
144
+ ...contextWithPR,
145
+ inputs: {},
146
+ })
147
+ expect(result).toEqual({ isActive: true })
148
+ })
149
+ })
@@ -0,0 +1,232 @@
1
+ /**
2
+ * Type-safe workflow step framework for GitHub Actions
3
+ */
4
+
5
+ // import type { Context } from '@actions/github/lib/context.ts'
6
+ import type { GitHub } from '@actions/github/lib/utils.ts'
7
+ import { z } from 'zod/v4'
8
+ import type { GitController } from './git-controller.ts'
9
+ import type { PullRequestController } from './pr-controller.ts'
10
+ import type { Context, ContextSchema as RealContextSchema } from './schemas/context.ts'
11
+
12
+ /**
13
+ * Arguments passed to the step's run function.
14
+ *
15
+ * @template $Inputs - The validated input values based on your inputs schema
16
+ * @template $Context - The GitHub Actions context (validated if context schema provided)
17
+ */
18
+ export interface Args<$Inputs extends Inputs = Inputs, $Context = Context> {
19
+ /** GitHub Actions core utilities for logging, setting outputs, etc. */
20
+ core: typeof import('@actions/core')
21
+
22
+ /** GitHub Actions context containing event payload, repo info, etc. */
23
+ context: $Context
24
+
25
+ /** Validated input values passed to the step */
26
+ inputs: $Inputs
27
+
28
+ /** Authenticated Octokit instance for GitHub API operations */
29
+ github: InstanceType<typeof GitHub>
30
+
31
+ /** zx's $ function for executing shell commands */
32
+ $: typeof import('zx').$
33
+
34
+ /** Node.js fs/promises module for file operations */
35
+ fs: typeof import('node:fs/promises')
36
+
37
+ /** PR controller for pull request operations (comment, review, etc.) */
38
+ pr: PullRequestController
39
+
40
+ /** Git controller for git operations (commit, push, etc.) without subprocess details */
41
+ git: GitController
42
+ }
43
+
44
+ export type Outputs = object
45
+
46
+ export type Inputs = object
47
+
48
+ type InputsSchema = z.ZodObject
49
+
50
+ type OutputsSchema = z.ZodObject
51
+
52
+ // This is a loose type because working with sub/sup schema types is complex, maybe not even workable, unclear, and not worth the effort
53
+ type ContextSchema = z.Schema
54
+
55
+ // Export the full step definition for runner
56
+ export interface Step<
57
+ $InputsSchema extends InputsSchema = InputsSchema,
58
+ $OutputsSchema extends OutputsSchema = OutputsSchema,
59
+ $ContextSchema extends ContextSchema = ContextSchema,
60
+ > {
61
+ definition: Definition<
62
+ $InputsSchema,
63
+ $OutputsSchema,
64
+ $ContextSchema
65
+ >
66
+ run: Runner<
67
+ z.output<$InputsSchema>,
68
+ z.output<$OutputsSchema>,
69
+ z.output<$ContextSchema>
70
+ >
71
+ }
72
+
73
+ export type Runner<
74
+ $Inputs extends Inputs = Inputs,
75
+ $Outputs extends Outputs = Outputs,
76
+ $Context = Context,
77
+ > = (
78
+ context: Args<$Inputs, $Context>,
79
+ ) => Promise<$Outputs>
80
+
81
+ // Generic workflow step definition
82
+ export interface Definition<
83
+ $InputsSchema extends InputsSchema,
84
+ $OutputsSchema extends OutputsSchema,
85
+ $ContextSchema extends ContextSchema,
86
+ > {
87
+ description?: string
88
+ name?: string
89
+ inputsSchema?: $InputsSchema
90
+ outputsSchema?: $OutputsSchema
91
+ contextSchema?: $ContextSchema
92
+ }
93
+
94
+ // Generic workflow step definition
95
+ export interface CreateInput<
96
+ $InputsSchema extends InputsSchema,
97
+ $OutputsSchema extends OutputsSchema,
98
+ $ContextSchema extends z.Schema,
99
+ > {
100
+ description?: string
101
+ name?: string
102
+ inputs?: $InputsSchema
103
+ outputs?: $OutputsSchema
104
+ context?: $ContextSchema
105
+ run: (
106
+ args: Args<z.output<$InputsSchema>, z.output<$ContextSchema>>,
107
+ // todo: Obj.isEmpty ...
108
+ ) => Promise<{} extends z.Infer<$OutputsSchema> ? void : z.Infer<$OutputsSchema>>
109
+ }
110
+
111
+ /**
112
+ * Create a type-safe GitHub Actions workflow step with runtime validation.
113
+ *
114
+ * This is the main entry point for defining custom workflow steps that can be executed
115
+ * by the GitHub Actions runner. It provides:
116
+ * - Type-safe inputs/outputs with Zod schema validation
117
+ * - Automatic GitHub Actions output handling (both individual outputs and bundled JSON)
118
+ * - Context validation to ensure steps run in the correct workflow events
119
+ * - Integration with GitHub API via Octokit
120
+ * - Built-in error handling and logging
121
+ *
122
+ * @example Basic step with inputs and outputs
123
+ * ```typescript
124
+ * import { z } from 'zod'
125
+ * import { GitHubActions } from '#lib/github-actions'
126
+ *
127
+ * export default GitHubActions.createStep({
128
+ * name: 'my-step',
129
+ * description: 'Processes some data and returns results',
130
+ * inputs: z.object({
131
+ * message: z.string(),
132
+ * count: z.number().optional().default(1),
133
+ * }),
134
+ * outputs: z.object({
135
+ * result: z.string(),
136
+ * processed: z.boolean(),
137
+ * }),
138
+ * async run({ inputs, core }) {
139
+ * core.info(`Processing: ${inputs.message}`)
140
+ *
141
+ * return {
142
+ * result: inputs.message.toUpperCase(),
143
+ * processed: true,
144
+ * }
145
+ * }
146
+ * })
147
+ * ```
148
+ *
149
+ * @example Step with specific context requirements
150
+ * ```typescript
151
+ * export default GitHubActions.createStep({
152
+ * name: 'pr-only-step',
153
+ * description: 'This step only runs on pull requests',
154
+ * context: GitHubActions.PullRequestContext,
155
+ * outputs: z.object({
156
+ * pr_number: z.number(),
157
+ * }),
158
+ * async run({ context, core }) {
159
+ * const prNumber = context.payload.pull_request.number
160
+ * core.info(`Running on PR #${prNumber}`)
161
+ *
162
+ * return { pr_number: prNumber }
163
+ * }
164
+ * })
165
+ * ```
166
+ *
167
+ * @example Using the GitHub API
168
+ * ```typescript
169
+ * export default GitHubActions.createStep({
170
+ * name: 'create-issue',
171
+ * description: 'Creates a GitHub issue',
172
+ * inputs: z.object({
173
+ * title: z.string(),
174
+ * body: z.string(),
175
+ * }),
176
+ * outputs: z.object({
177
+ * issue_number: z.number(),
178
+ * issue_url: z.string(),
179
+ * }),
180
+ * async run({ inputs, github, context }) {
181
+ * const issue = await github.rest.issues.create({
182
+ * owner: context.repo.owner,
183
+ * repo: context.repo.repo,
184
+ * title: inputs.title,
185
+ * body: inputs.body,
186
+ * })
187
+ *
188
+ * return {
189
+ * issue_number: issue.data.number,
190
+ * issue_url: issue.data.html_url,
191
+ * }
192
+ * }
193
+ * })
194
+ * ```
195
+ *
196
+ * @param input - Step configuration object
197
+ * @param input.name - Unique identifier for the step (used in logging and debugging)
198
+ * @param input.description - Human-readable description of what the step does
199
+ * @param input.inputs - Optional Zod schema for validating step inputs
200
+ * @param input.outputs - Optional Zod schema for validating step outputs
201
+ * @param input.context - Optional Zod schema for validating GitHub Actions context (event type)
202
+ * @param input.run - Async function that implements the step logic
203
+ *
204
+ * @returns A Step object that can be executed by the GitHub Actions runner
205
+ *
206
+ * @remarks
207
+ * - All outputs are automatically set as GitHub Actions outputs
208
+ * - Boolean outputs are properly handled (use fromJSON in workflows)
209
+ * - A special 'json' output contains all outputs bundled together
210
+ * - The runner provides extensive logging and error handling
211
+ * - Steps can access PR controller for pull request operations
212
+ * - The `$` from zx is available for shell commands
213
+ */
214
+ export function createStep<
215
+ $InputsSchema extends InputsSchema,
216
+ $OutputsSchema extends OutputsSchema,
217
+ $ContextSchema extends ContextSchema = RealContextSchema,
218
+ >(
219
+ input: CreateInput<$InputsSchema, $OutputsSchema, $ContextSchema>,
220
+ ): Step<$InputsSchema, $OutputsSchema, $ContextSchema> {
221
+ const { run, inputs, outputs, context, ...rest } = input
222
+ const definition: Definition<$InputsSchema, $OutputsSchema, $ContextSchema> = {
223
+ ...rest,
224
+ inputsSchema: inputs,
225
+ outputsSchema: outputs,
226
+ contextSchema: context,
227
+ }
228
+ return {
229
+ definition,
230
+ run,
231
+ } as any
232
+ }
@@ -1,4 +1,4 @@
1
- import { Manifest } from '@wollybeard/kit'
1
+ import { Err, Manifest } from '@wollybeard/kit'
2
2
 
3
3
  /**
4
4
  * Check if a project has a package installed by examining its package.json
@@ -9,8 +9,9 @@ export async function checkIsProjectHasPackageInstalled(
9
9
  ): Promise<boolean> {
10
10
  const packageJson = await Manifest.resource.read(projectRoot)
11
11
 
12
- if (!packageJson) {
13
- return false
12
+ if (Err.is(packageJson)) {
13
+ if (packageJson._tag === 'ResourceErrorNotFound') return false
14
+ throw packageJson
14
15
  }
15
16
 
16
17
  // Check if React is in dependencies or devDependencies
@@ -0,0 +1,115 @@
1
+ import { Ts } from '@wollybeard/kit'
2
+ import { objFilter, ObjOmit, ObjPick, objPolicyFilter } from './kit-temp.js'
3
+ import type { ObjPolicyFilter } from './kit-temp.js'
4
+
5
+ // Test object for all tests
6
+ type TestObj = { a: string; b: number; c: boolean; d: string[] }
7
+ declare const testObj: TestObj
8
+
9
+ // Test 1: objPolicyFilter with allow mode
10
+ {
11
+ const result = objPolicyFilter('allow', testObj, ['a', 'c'] as const)
12
+ Ts.assertEqual<{ a: string; c: boolean }>()(result)
13
+ }
14
+
15
+ // Test 2: objPolicyFilter with deny mode
16
+ {
17
+ const result = objPolicyFilter('deny', testObj, ['a', 'c'] as const)
18
+ Ts.assertEqual<{ b: number; d: string[] }>()(result)
19
+ }
20
+
21
+ // Test 3: objFilter returns Partial<T>
22
+ {
23
+ const result = objFilter(testObj, (key, value) => value !== 'hello')
24
+ Ts.assertEqual<Partial<TestObj>>()(result)
25
+
26
+ // All properties are optional
27
+ Ts.assertSub<typeof result.a>()(undefined)
28
+ Ts.assertSub<typeof result.b>()(undefined)
29
+ Ts.assertSub<typeof result.c>()(undefined)
30
+ Ts.assertSub<typeof result.d>()(undefined)
31
+ }
32
+
33
+ // Test 4: ObjPick type inference
34
+ {
35
+ const result = ObjPick(testObj, ['a', 'c'] as const)
36
+ Ts.assertEqual<{ a: string; c: boolean }>()(result)
37
+ }
38
+
39
+ // Test 5: ObjOmit type inference
40
+ {
41
+ const result = ObjOmit(testObj, ['a', 'c'] as const)
42
+ Ts.assertEqual<{ b: number; d: string[] }>()(result)
43
+ }
44
+
45
+ // Test 6: ObjPolicyFilter type-level function
46
+ {
47
+ type Allow = ObjPolicyFilter<TestObj, 'a' | 'c', 'allow'>
48
+ type _TestAllow = Ts.AssertEqual<Allow, { a: string; c: boolean }>
49
+
50
+ type Deny = ObjPolicyFilter<TestObj, 'a' | 'c', 'deny'>
51
+ type _TestDeny = Ts.AssertEqual<Deny, { b: number; d: string[] }>
52
+
53
+ type AllowEmpty = ObjPolicyFilter<TestObj, never, 'allow'>
54
+ type _TestAllowEmpty = Ts.AssertEqual<AllowEmpty, {}>
55
+
56
+ type DenyEmpty = ObjPolicyFilter<TestObj, never, 'deny'>
57
+ type _TestDenyEmpty = Ts.AssertEqual<DenyEmpty, TestObj>
58
+ }
59
+
60
+ // Test 7: Edge cases
61
+ {
62
+ // Empty object
63
+ const empty = {}
64
+ const allowEmpty = objPolicyFilter('allow', empty, [])
65
+ const denyEmpty = objPolicyFilter('deny', empty, [])
66
+ const filterEmpty = objFilter(empty, () => true)
67
+
68
+ Ts.assertEqual<{}>()(allowEmpty)
69
+ Ts.assertEqual<{}>()(denyEmpty)
70
+ Ts.assertEqual<{}>()(filterEmpty)
71
+
72
+ // Single property object
73
+ const single = { a: 1 }
74
+ const allowSingle = objPolicyFilter('allow', single, ['a'] as const)
75
+ const denySingle = objPolicyFilter('deny', single, ['a'] as const)
76
+ const filterSingle = objFilter(single, () => true)
77
+
78
+ Ts.assertEqual<{ a: number }>()(allowSingle)
79
+ Ts.assertEqual<{}>()(denySingle)
80
+ Ts.assertEqual<{ a?: number }>()(filterSingle)
81
+ }
82
+
83
+ // Test 8: Complex nested object
84
+ {
85
+ type ComplexObj = {
86
+ nested: { a: string; b: number }
87
+ array: string[]
88
+ optional?: boolean
89
+ readonly ro: string
90
+ }
91
+ const complexObj = {} as ComplexObj
92
+
93
+ const picked = objPolicyFilter('allow', complexObj, ['nested', 'optional'] as const)
94
+ Ts.assertEqual<{ nested: { a: string; b: number }; optional?: boolean }>()(picked)
95
+
96
+ const omitted = objPolicyFilter('deny', complexObj, ['nested', 'optional'] as const)
97
+ Ts.assertEqual<{ array: string[]; readonly ro: string }>()(omitted)
98
+
99
+ const filtered = objFilter(complexObj, (key) => key !== 'array')
100
+ Ts.assertEqual<Partial<ComplexObj>>()(filtered)
101
+ }
102
+
103
+ // Test 9: Keys parameter type inference
104
+ {
105
+ // With const assertion
106
+ const keys1 = ['a', 'c'] as const
107
+ const result1 = objPolicyFilter('allow', testObj, keys1)
108
+ Ts.assertEqual<{ a: string; c: boolean }>()(result1)
109
+
110
+ // Without const assertion (wider type)
111
+ const keys2: (keyof TestObj)[] = ['a', 'c']
112
+ const result2 = objPolicyFilter('allow', testObj, keys2)
113
+ // Result is a union of all possible picks
114
+ type Result2 = typeof result2 // Pick<TestObj, keyof TestObj>
115
+ }
@@ -0,0 +1,127 @@
1
+ import * as fc from 'fast-check'
2
+ import { describe, expect, test } from 'vitest'
3
+ import { objFilter, ObjOmit, ObjPick, objPolicyFilter } from './kit-temp.js'
4
+
5
+ describe('objPolicyFilter', () => {
6
+ const testObj = { a: 1, b: 2, c: 3, d: 4 }
7
+
8
+ test('allow mode picks specified keys', () => {
9
+ expect(objPolicyFilter('allow', testObj, ['a', 'c'])).toEqual({ a: 1, c: 3 })
10
+ expect(objPolicyFilter('allow', testObj, [])).toEqual({})
11
+ expect(objPolicyFilter('allow', testObj, ['a', 'z'] as any)).toEqual({ a: 1 })
12
+ })
13
+
14
+ test('deny mode omits specified keys', () => {
15
+ expect(objPolicyFilter('deny', testObj, ['a', 'c'])).toEqual({ b: 2, d: 4 })
16
+ expect(objPolicyFilter('deny', testObj, [])).toEqual(testObj)
17
+ expect(objPolicyFilter('deny', testObj, ['z'] as any)).toEqual(testObj)
18
+ })
19
+
20
+ test('preserves undefined values', () => {
21
+ const obj = { a: 1, b: undefined, c: 3 }
22
+ expect(objPolicyFilter('allow', obj, ['a', 'b'])).toEqual({ a: 1, b: undefined })
23
+ })
24
+ })
25
+
26
+ describe('objFilter', () => {
27
+ const testObj = { a: 1, b: 2, c: 3, d: 4 }
28
+
29
+ test('filters by predicates', () => {
30
+ // By value
31
+ expect(objFilter(testObj, (k, v) => v > 2)).toEqual({ c: 3, d: 4 })
32
+
33
+ // By key
34
+ expect(objFilter(testObj, k => k === 'a' || k === 'c')).toEqual({ a: 1, c: 3 })
35
+
36
+ // By full object context
37
+ expect(objFilter(testObj, (k, v, obj) => {
38
+ const avg = Object.values(obj).reduce((a, b) => a + b, 0) / Object.keys(obj).length
39
+ return v < avg
40
+ })).toEqual({ a: 1, b: 2 })
41
+ })
42
+
43
+ test('edge cases', () => {
44
+ expect(objFilter(testObj, () => false)).toEqual({})
45
+ expect(objFilter(testObj, () => true)).toEqual(testObj)
46
+ expect(objFilter({}, () => true)).toEqual({})
47
+ })
48
+ })
49
+
50
+ describe('ObjPick and ObjOmit', () => {
51
+ test('are aliases for objPolicyFilter', () => {
52
+ const obj = { a: 1, b: 2, c: 3 }
53
+ const keys = ['a', 'c'] as const
54
+
55
+ expect(ObjPick(obj, keys)).toEqual(objPolicyFilter('allow', obj, keys))
56
+ expect(ObjOmit(obj, keys)).toEqual(objPolicyFilter('deny', obj, keys))
57
+ })
58
+ })
59
+
60
+ describe('property-based tests', () => {
61
+ test('objPolicyFilter allow/deny are complementary', () => {
62
+ fc.assert(
63
+ fc.property(
64
+ fc.object(),
65
+ fc.array(fc.string()),
66
+ (obj, keys) => {
67
+ const allowed = objPolicyFilter('allow', obj, keys)
68
+ const denied = objPolicyFilter('deny', obj, keys)
69
+
70
+ // Every key in obj is either in allowed or denied, never both
71
+ Object.keys(obj).forEach(key => {
72
+ const inAllowed = Object.prototype.hasOwnProperty.call(allowed, key)
73
+ const inDenied = Object.prototype.hasOwnProperty.call(denied, key)
74
+ expect(inAllowed).toBe(!inDenied)
75
+ })
76
+
77
+ // Combined they reconstruct the original object
78
+ expect({ ...allowed, ...denied }).toEqual(obj)
79
+ },
80
+ ),
81
+ )
82
+ })
83
+
84
+ test('objFilter preserves values unchanged', () => {
85
+ fc.assert(
86
+ fc.property(
87
+ fc.object(),
88
+ (obj) => {
89
+ const filtered = objFilter(obj, () => true)
90
+ expect(filtered).toEqual(obj)
91
+
92
+ // Values are the same reference
93
+ Object.keys(filtered).forEach(key => {
94
+ expect(filtered[key]).toBe(obj[key])
95
+ })
96
+ },
97
+ ),
98
+ )
99
+ })
100
+
101
+ test('objPolicyFilter is immutable', () => {
102
+ fc.assert(
103
+ fc.property(
104
+ fc.object(),
105
+ fc.array(fc.string()),
106
+ fc.oneof(fc.constant('allow' as const), fc.constant('deny' as const)),
107
+ (obj, keys, mode) => {
108
+ const original = { ...obj }
109
+ objPolicyFilter(mode, obj, keys)
110
+ expect(obj).toEqual(original)
111
+ },
112
+ ),
113
+ )
114
+ })
115
+
116
+ test('empty keys behavior', () => {
117
+ fc.assert(
118
+ fc.property(
119
+ fc.object(),
120
+ (obj) => {
121
+ expect(objPolicyFilter('allow', obj, [])).toEqual({})
122
+ expect(objPolicyFilter('deny', obj, [])).toEqual(obj)
123
+ },
124
+ ),
125
+ )
126
+ })
127
+ })