alepha 0.22.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (869) hide show
  1. package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
  2. package/assets/swagger-ui/swagger-ui-standalone-preset.js +1 -1
  3. package/dist/api/audits/index.browser.js +49 -52
  4. package/dist/api/audits/index.browser.js.map +1 -1
  5. package/dist/api/audits/index.d.ts +629 -565
  6. package/dist/api/audits/index.d.ts.map +1 -1
  7. package/dist/api/audits/index.js +206 -98
  8. package/dist/api/audits/index.js.map +1 -1
  9. package/dist/api/files/index.browser.js +44 -44
  10. package/dist/api/files/index.browser.js.map +1 -1
  11. package/dist/api/files/index.d.ts +292 -293
  12. package/dist/api/files/index.d.ts.map +1 -1
  13. package/dist/api/files/index.js +61 -64
  14. package/dist/api/files/index.js.map +1 -1
  15. package/dist/api/jobs/index.browser.js +61 -59
  16. package/dist/api/jobs/index.browser.js.map +1 -1
  17. package/dist/api/jobs/index.d.ts +546 -347
  18. package/dist/api/jobs/index.d.ts.map +1 -1
  19. package/dist/api/jobs/index.js +165 -86
  20. package/dist/api/jobs/index.js.map +1 -1
  21. package/dist/api/keys/index.d.ts +242 -230
  22. package/dist/api/keys/index.d.ts.map +1 -1
  23. package/dist/api/keys/index.js +63 -66
  24. package/dist/api/keys/index.js.map +1 -1
  25. package/dist/api/notifications/index.browser.js +40 -38
  26. package/dist/api/notifications/index.browser.js.map +1 -1
  27. package/dist/api/notifications/index.d.ts +339 -209
  28. package/dist/api/notifications/index.d.ts.map +1 -1
  29. package/dist/api/notifications/index.js +108 -60
  30. package/dist/api/notifications/index.js.map +1 -1
  31. package/dist/api/oauth/index.d.ts +190 -78
  32. package/dist/api/oauth/index.d.ts.map +1 -1
  33. package/dist/api/oauth/index.js +290 -68
  34. package/dist/api/oauth/index.js.map +1 -1
  35. package/dist/api/organizations/index.browser.js +14 -14
  36. package/dist/api/organizations/index.browser.js.map +1 -1
  37. package/dist/api/organizations/index.d.ts +158 -134
  38. package/dist/api/organizations/index.d.ts.map +1 -1
  39. package/dist/api/organizations/index.js +18 -18
  40. package/dist/api/organizations/index.js.map +1 -1
  41. package/dist/api/parameters/index.browser.js +74 -53
  42. package/dist/api/parameters/index.browser.js.map +1 -1
  43. package/dist/api/parameters/index.d.ts +607 -513
  44. package/dist/api/parameters/index.d.ts.map +1 -1
  45. package/dist/api/parameters/index.js +205 -127
  46. package/dist/api/parameters/index.js.map +1 -1
  47. package/dist/api/payments/index.d.ts +652 -449
  48. package/dist/api/payments/index.d.ts.map +1 -1
  49. package/dist/api/payments/index.js +159 -93
  50. package/dist/api/payments/index.js.map +1 -1
  51. package/dist/api/subscriptions/index.d.ts +1032 -762
  52. package/dist/api/subscriptions/index.d.ts.map +1 -1
  53. package/dist/api/subscriptions/index.js +166 -185
  54. package/dist/api/subscriptions/index.js.map +1 -1
  55. package/dist/api/users/index.browser.js +48 -71
  56. package/dist/api/users/index.browser.js.map +1 -1
  57. package/dist/api/users/index.d.ts +1297 -1109
  58. package/dist/api/users/index.d.ts.map +1 -1
  59. package/dist/api/users/index.js +454 -369
  60. package/dist/api/users/index.js.map +1 -1
  61. package/dist/api/verifications/index.browser.js +17 -17
  62. package/dist/api/verifications/index.browser.js.map +1 -1
  63. package/dist/api/verifications/index.d.ts +169 -157
  64. package/dist/api/verifications/index.d.ts.map +1 -1
  65. package/dist/api/verifications/index.js +47 -95
  66. package/dist/api/verifications/index.js.map +1 -1
  67. package/dist/background/index.d.ts +0 -1
  68. package/dist/background/index.d.ts.map +1 -1
  69. package/dist/background/index.js.map +1 -1
  70. package/dist/background/index.workerd.js.map +1 -1
  71. package/dist/batch/index.d.ts +0 -1
  72. package/dist/batch/index.d.ts.map +1 -1
  73. package/dist/batch/index.js.map +1 -1
  74. package/dist/bin/index.js +1 -1
  75. package/dist/bin/index.js.map +1 -1
  76. package/dist/bucket/index.d.ts +27 -32
  77. package/dist/bucket/index.d.ts.map +1 -1
  78. package/dist/bucket/index.js +56 -26
  79. package/dist/bucket/index.js.map +1 -1
  80. package/dist/bucket/index.workerd.js +52 -24
  81. package/dist/bucket/index.workerd.js.map +1 -1
  82. package/dist/cache/core/index.d.ts +4 -6
  83. package/dist/cache/core/index.d.ts.map +1 -1
  84. package/dist/cache/core/index.js +4 -10
  85. package/dist/cache/core/index.js.map +1 -1
  86. package/dist/cache/core/index.workerd.js +4 -10
  87. package/dist/cache/core/index.workerd.js.map +1 -1
  88. package/dist/cache/database/index.d.ts +22 -23
  89. package/dist/cache/database/index.d.ts.map +1 -1
  90. package/dist/cache/database/index.js +11 -20
  91. package/dist/cache/database/index.js.map +1 -1
  92. package/dist/cache/redis/index.d.ts +3 -4
  93. package/dist/cache/redis/index.d.ts.map +1 -1
  94. package/dist/cache/redis/index.js +2 -2
  95. package/dist/cache/redis/index.js.map +1 -1
  96. package/dist/captcha/index.d.ts.map +1 -1
  97. package/dist/captcha/index.js +4 -4
  98. package/dist/captcha/index.js.map +1 -1
  99. package/dist/cli/config/index.d.ts +0 -1
  100. package/dist/cli/config/index.d.ts.map +1 -1
  101. package/dist/cli/core/index.d.ts +244 -475
  102. package/dist/cli/core/index.d.ts.map +1 -1
  103. package/dist/cli/core/index.js +308 -383
  104. package/dist/cli/core/index.js.map +1 -1
  105. package/dist/cli/devtools/index.d.ts +3 -9
  106. package/dist/cli/devtools/index.d.ts.map +1 -1
  107. package/dist/cli/devtools/index.js +3 -3
  108. package/dist/cli/devtools/index.js.map +1 -1
  109. package/dist/cli/i18n/index.d.ts +20 -39
  110. package/dist/cli/i18n/index.d.ts.map +1 -1
  111. package/dist/cli/i18n/index.js +51 -17
  112. package/dist/cli/i18n/index.js.map +1 -1
  113. package/dist/cli/platform/index.d.ts +89 -82
  114. package/dist/cli/platform/index.d.ts.map +1 -1
  115. package/dist/cli/platform/index.js +27 -33
  116. package/dist/cli/platform/index.js.map +1 -1
  117. package/dist/cli/platform-lib/index.d.ts +383 -410
  118. package/dist/cli/platform-lib/index.d.ts.map +1 -1
  119. package/dist/cli/platform-lib/index.js +300 -258
  120. package/dist/cli/platform-lib/index.js.map +1 -1
  121. package/dist/cli/vendor/index.d.ts +17 -41
  122. package/dist/cli/vendor/index.d.ts.map +1 -1
  123. package/dist/cli/vendor/index.js +10 -13
  124. package/dist/cli/vendor/index.js.map +1 -1
  125. package/dist/command/index.d.ts +82 -194
  126. package/dist/command/index.d.ts.map +1 -1
  127. package/dist/command/index.js +160 -563
  128. package/dist/command/index.js.map +1 -1
  129. package/dist/core/index.browser.js +845 -859
  130. package/dist/core/index.browser.js.map +1 -1
  131. package/dist/core/index.d.ts +787 -527
  132. package/dist/core/index.d.ts.map +1 -1
  133. package/dist/core/index.js +845 -859
  134. package/dist/core/index.js.map +1 -1
  135. package/dist/core/index.native.js +845 -859
  136. package/dist/core/index.native.js.map +1 -1
  137. package/dist/core/index.workerd.js +845 -859
  138. package/dist/core/index.workerd.js.map +1 -1
  139. package/dist/crypto/index.browser.js +1 -1
  140. package/dist/crypto/index.browser.js.map +1 -1
  141. package/dist/crypto/index.d.ts +3 -4
  142. package/dist/crypto/index.d.ts.map +1 -1
  143. package/dist/crypto/index.js +6 -3
  144. package/dist/crypto/index.js.map +1 -1
  145. package/dist/datetime/index.d.ts +12 -2
  146. package/dist/datetime/index.d.ts.map +1 -1
  147. package/dist/datetime/index.js +6 -1
  148. package/dist/datetime/index.js.map +1 -1
  149. package/dist/email/brevo/index.d.ts +0 -1
  150. package/dist/email/brevo/index.d.ts.map +1 -1
  151. package/dist/email/brevo/index.js +4 -4
  152. package/dist/email/brevo/index.js.map +1 -1
  153. package/dist/email/cloudflare/index.d.ts +0 -1
  154. package/dist/email/cloudflare/index.d.ts.map +1 -1
  155. package/dist/email/cloudflare/index.js +2 -2
  156. package/dist/email/cloudflare/index.js.map +1 -1
  157. package/dist/email/core/index.d.ts +15 -7
  158. package/dist/email/core/index.d.ts.map +1 -1
  159. package/dist/email/core/index.js +14 -5
  160. package/dist/email/core/index.js.map +1 -1
  161. package/dist/email/core/index.workerd.js +5 -1
  162. package/dist/email/core/index.workerd.js.map +1 -1
  163. package/dist/email/smtp/index.d.ts +8 -9
  164. package/dist/email/smtp/index.d.ts.map +1 -1
  165. package/dist/email/smtp/index.js +702 -479
  166. package/dist/email/smtp/index.js.map +1 -1
  167. package/dist/fake/index.d.ts +1580 -1238
  168. package/dist/fake/index.d.ts.map +1 -1
  169. package/dist/fake/index.js +11728 -32131
  170. package/dist/fake/index.js.map +1 -1
  171. package/dist/lock/core/index.d.ts +13 -9
  172. package/dist/lock/core/index.d.ts.map +1 -1
  173. package/dist/lock/core/index.js +5 -5
  174. package/dist/lock/core/index.js.map +1 -1
  175. package/dist/lock/redis/index.d.ts +0 -1
  176. package/dist/lock/redis/index.d.ts.map +1 -1
  177. package/dist/lock/redis/index.js.map +1 -1
  178. package/dist/logger/index.d.ts +81 -69
  179. package/dist/logger/index.d.ts.map +1 -1
  180. package/dist/logger/index.js +123 -56
  181. package/dist/logger/index.js.map +1 -1
  182. package/dist/mcp/index.d.ts +36 -90
  183. package/dist/mcp/index.d.ts.map +1 -1
  184. package/dist/mcp/index.js +65 -70
  185. package/dist/mcp/index.js.map +1 -1
  186. package/dist/orm/core/index.browser.js +54 -40
  187. package/dist/orm/core/index.browser.js.map +1 -1
  188. package/dist/orm/core/index.bun.js +140 -106
  189. package/dist/orm/core/index.bun.js.map +1 -1
  190. package/dist/orm/core/index.d.ts +145 -150
  191. package/dist/orm/core/index.d.ts.map +1 -1
  192. package/dist/orm/core/index.js +144 -109
  193. package/dist/orm/core/index.js.map +1 -1
  194. package/dist/orm/postgres/index.bun.js +64 -54
  195. package/dist/orm/postgres/index.bun.js.map +1 -1
  196. package/dist/orm/postgres/index.d.ts +36 -76
  197. package/dist/orm/postgres/index.d.ts.map +1 -1
  198. package/dist/orm/postgres/index.js +67 -57
  199. package/dist/orm/postgres/index.js.map +1 -1
  200. package/dist/queue/core/index.d.ts +62 -75
  201. package/dist/queue/core/index.d.ts.map +1 -1
  202. package/dist/queue/core/index.js +48 -71
  203. package/dist/queue/core/index.js.map +1 -1
  204. package/dist/queue/core/index.workerd.js +48 -71
  205. package/dist/queue/core/index.workerd.js.map +1 -1
  206. package/dist/queue/redis/index.d.ts +3 -4
  207. package/dist/queue/redis/index.d.ts.map +1 -1
  208. package/dist/queue/redis/index.js +2 -2
  209. package/dist/queue/redis/index.js.map +1 -1
  210. package/dist/react/auth/index.browser.js.map +1 -1
  211. package/dist/react/auth/index.d.ts +7 -4
  212. package/dist/react/auth/index.d.ts.map +1 -1
  213. package/dist/react/auth/index.js.map +1 -1
  214. package/dist/react/core/index.d.ts +87 -5
  215. package/dist/react/core/index.d.ts.map +1 -1
  216. package/dist/react/core/index.js +170 -23
  217. package/dist/react/core/index.js.map +1 -1
  218. package/dist/react/form/index.d.ts +4 -6
  219. package/dist/react/form/index.d.ts.map +1 -1
  220. package/dist/react/form/index.js +107 -71
  221. package/dist/react/form/index.js.map +1 -1
  222. package/dist/react/head/index.browser.js.map +1 -1
  223. package/dist/react/head/index.d.ts +0 -1
  224. package/dist/react/head/index.d.ts.map +1 -1
  225. package/dist/react/head/index.js.map +1 -1
  226. package/dist/react/i18n/index.d.ts +47 -5
  227. package/dist/react/i18n/index.d.ts.map +1 -1
  228. package/dist/react/i18n/index.js +116 -12
  229. package/dist/react/i18n/index.js.map +1 -1
  230. package/dist/react/intro/index.d.ts +1 -4
  231. package/dist/react/intro/index.d.ts.map +1 -1
  232. package/dist/react/intro/index.js.map +1 -1
  233. package/dist/react/router/index.browser.js +188 -29
  234. package/dist/react/router/index.browser.js.map +1 -1
  235. package/dist/react/router/index.d.ts +480 -372
  236. package/dist/react/router/index.d.ts.map +1 -1
  237. package/dist/react/router/index.js +261 -47
  238. package/dist/react/router/index.js.map +1 -1
  239. package/dist/react/sitemap/index.browser.js +35 -0
  240. package/dist/react/sitemap/index.browser.js.map +1 -0
  241. package/dist/react/sitemap/index.d.ts +91 -0
  242. package/dist/react/sitemap/index.d.ts.map +1 -0
  243. package/dist/react/sitemap/index.js +131 -0
  244. package/dist/react/sitemap/index.js.map +1 -0
  245. package/dist/react/testing/index.d.ts +4 -5
  246. package/dist/react/testing/index.d.ts.map +1 -1
  247. package/dist/react/testing/index.js +41 -15
  248. package/dist/react/testing/index.js.map +1 -1
  249. package/dist/react/testing/{chunk-BpyX8vjI.js → rolldown-runtime-Bl3dcgcQ.js} +1 -1
  250. package/dist/react/ui/index.d.ts +35 -34
  251. package/dist/react/ui/index.d.ts.map +1 -1
  252. package/dist/react/ui/index.js +12 -17
  253. package/dist/react/ui/index.js.map +1 -1
  254. package/dist/redis/index.bun.js +5 -5
  255. package/dist/redis/index.bun.js.map +1 -1
  256. package/dist/redis/index.d.ts +6 -7
  257. package/dist/redis/index.d.ts.map +1 -1
  258. package/dist/redis/index.js +6 -6
  259. package/dist/redis/index.js.map +1 -1
  260. package/dist/retry/index.d.ts +0 -1
  261. package/dist/retry/index.d.ts.map +1 -1
  262. package/dist/retry/index.js.map +1 -1
  263. package/dist/router/index.d.ts.map +1 -1
  264. package/dist/router/index.js.map +1 -1
  265. package/dist/scheduler/index.d.ts +4 -12
  266. package/dist/scheduler/index.d.ts.map +1 -1
  267. package/dist/scheduler/index.js +9 -4
  268. package/dist/scheduler/index.js.map +1 -1
  269. package/dist/scheduler/index.workerd.js +9 -4
  270. package/dist/scheduler/index.workerd.js.map +1 -1
  271. package/dist/security/index.browser.js +30 -28
  272. package/dist/security/index.browser.js.map +1 -1
  273. package/dist/security/index.d.ts +113 -44
  274. package/dist/security/index.d.ts.map +1 -1
  275. package/dist/security/index.js +452 -37
  276. package/dist/security/index.js.map +1 -1
  277. package/dist/server/auth/index.browser.js +19 -19
  278. package/dist/server/auth/index.browser.js.map +1 -1
  279. package/dist/server/auth/index.d.ts +215 -187
  280. package/dist/server/auth/index.d.ts.map +1 -1
  281. package/dist/server/auth/index.js +1145 -86
  282. package/dist/server/auth/index.js.map +1 -1
  283. package/dist/server/cookies/index.browser.js +103 -5
  284. package/dist/server/cookies/index.browser.js.map +1 -1
  285. package/dist/server/cookies/index.d.ts +86 -4
  286. package/dist/server/cookies/index.d.ts.map +1 -1
  287. package/dist/server/cookies/index.js +121 -8
  288. package/dist/server/cookies/index.js.map +1 -1
  289. package/dist/server/core/index.browser.js +22 -27
  290. package/dist/server/core/index.browser.js.map +1 -1
  291. package/dist/server/core/index.d.ts +134 -85
  292. package/dist/server/core/index.d.ts.map +1 -1
  293. package/dist/server/core/index.js +130 -118
  294. package/dist/server/core/index.js.map +1 -1
  295. package/dist/server/cors/index.d.ts +9 -10
  296. package/dist/server/cors/index.d.ts.map +1 -1
  297. package/dist/server/cors/index.js +14 -26
  298. package/dist/server/cors/index.js.map +1 -1
  299. package/dist/server/etag/index.d.ts +2 -3
  300. package/dist/server/etag/index.d.ts.map +1 -1
  301. package/dist/server/etag/index.js.map +1 -1
  302. package/dist/server/health/index.d.ts +18 -19
  303. package/dist/server/health/index.d.ts.map +1 -1
  304. package/dist/server/health/index.js +6 -6
  305. package/dist/server/health/index.js.map +1 -1
  306. package/dist/server/links/index.browser.js +15 -18
  307. package/dist/server/links/index.browser.js.map +1 -1
  308. package/dist/server/links/index.d.ts +66 -67
  309. package/dist/server/links/index.d.ts.map +1 -1
  310. package/dist/server/links/index.js +29 -32
  311. package/dist/server/links/index.js.map +1 -1
  312. package/dist/server/metrics/index.d.ts +0 -1
  313. package/dist/server/metrics/index.d.ts.map +1 -1
  314. package/dist/server/metrics/index.js +10 -3
  315. package/dist/server/metrics/index.js.map +1 -1
  316. package/dist/server/proxy/index.d.ts +0 -1
  317. package/dist/server/proxy/index.d.ts.map +1 -1
  318. package/dist/server/proxy/index.js.map +1 -1
  319. package/dist/server/rate-limit/index.d.ts +8 -9
  320. package/dist/server/rate-limit/index.d.ts.map +1 -1
  321. package/dist/server/rate-limit/index.js +6 -12
  322. package/dist/server/rate-limit/index.js.map +1 -1
  323. package/dist/server/static/index.d.ts +0 -1
  324. package/dist/server/static/index.d.ts.map +1 -1
  325. package/dist/server/static/index.js.map +1 -1
  326. package/dist/server/swagger/index.d.ts +4 -4
  327. package/dist/server/swagger/index.d.ts.map +1 -1
  328. package/dist/server/swagger/index.js +37 -25
  329. package/dist/server/swagger/index.js.map +1 -1
  330. package/dist/sms/index.d.ts +0 -1
  331. package/dist/sms/index.d.ts.map +1 -1
  332. package/dist/sms/index.js.map +1 -1
  333. package/dist/system/index.browser.js.map +1 -1
  334. package/dist/system/index.d.ts +0 -1
  335. package/dist/system/index.d.ts.map +1 -1
  336. package/dist/system/index.js +2 -1
  337. package/dist/system/index.js.map +1 -1
  338. package/dist/system/index.workerd.js.map +1 -1
  339. package/dist/topic/core/index.d.ts +19 -20
  340. package/dist/topic/core/index.d.ts.map +1 -1
  341. package/dist/topic/core/index.js +8 -8
  342. package/dist/topic/core/index.js.map +1 -1
  343. package/dist/topic/redis/index.d.ts +3 -4
  344. package/dist/topic/redis/index.d.ts.map +1 -1
  345. package/dist/topic/redis/index.js +2 -2
  346. package/dist/topic/redis/index.js.map +1 -1
  347. package/package.json +36 -36
  348. package/src/api/audits/__tests__/AuditJobs.spec.ts +83 -0
  349. package/src/api/audits/__tests__/AuditService.spec.ts +139 -1
  350. package/src/api/audits/controllers/AdminAuditController.ts +41 -41
  351. package/src/api/audits/entities/audits.ts +22 -22
  352. package/src/api/audits/index.ts +6 -1
  353. package/src/api/audits/jobs/AuditJobs.ts +29 -0
  354. package/src/api/audits/parameters/AuditParameters.ts +51 -0
  355. package/src/api/audits/primitives/$audit.ts +24 -0
  356. package/src/api/audits/schemas/auditQuerySchema.ts +13 -13
  357. package/src/api/audits/schemas/createAuditSchema.ts +18 -18
  358. package/src/api/audits/services/AuditService.ts +79 -7
  359. package/src/api/files/__tests__/FileController.spec.ts +5 -5
  360. package/src/api/files/__tests__/FileJobs.spec.ts +6 -0
  361. package/src/api/files/controllers/FileController.ts +25 -25
  362. package/src/api/files/entities/files.ts +15 -15
  363. package/src/api/files/schemas/fileCreatorSummarySchema.ts +7 -7
  364. package/src/api/files/schemas/fileQuerySchema.ts +9 -9
  365. package/src/api/files/schemas/fileResourceSchema.ts +7 -9
  366. package/src/api/files/schemas/storageStatsSchema.ts +13 -13
  367. package/src/api/jobs/__tests__/$job-hardening.spec.ts +289 -0
  368. package/src/api/jobs/__tests__/$job.spec.ts +18 -18
  369. package/src/api/jobs/controllers/AdminJobController.ts +8 -8
  370. package/src/api/jobs/entities/jobExecutionEntity.ts +29 -19
  371. package/src/api/jobs/providers/JobProvider.ts +128 -12
  372. package/src/api/jobs/providers/JobQueueProvider.ts +2 -2
  373. package/src/api/jobs/schemas/jobConfigAtom.ts +22 -22
  374. package/src/api/jobs/schemas/jobExecutionQuerySchema.ts +6 -6
  375. package/src/api/jobs/schemas/jobExecutionResourceSchema.ts +11 -15
  376. package/src/api/jobs/schemas/jobRegistrationSchema.ts +20 -19
  377. package/src/api/jobs/schemas/triggerJobSchema.ts +3 -3
  378. package/src/api/jobs/services/JobService.ts +6 -6
  379. package/src/api/keys/__tests__/ApiKeyService.spec.ts +2 -2
  380. package/src/api/keys/controllers/AdminApiKeyController.ts +10 -10
  381. package/src/api/keys/entities/apiKeyEntity.ts +15 -15
  382. package/src/api/keys/schemas/adminApiKeyQuerySchema.ts +4 -4
  383. package/src/api/keys/schemas/adminApiKeyResourceSchema.ts +15 -15
  384. package/src/api/keys/schemas/createApiKeyBodySchema.ts +5 -5
  385. package/src/api/keys/schemas/createApiKeyResponseSchema.ts +9 -9
  386. package/src/api/keys/schemas/listApiKeyResponseSchema.ts +13 -13
  387. package/src/api/keys/schemas/revokeApiKeyParamsSchema.ts +3 -3
  388. package/src/api/keys/schemas/revokeApiKeyResponseSchema.ts +3 -3
  389. package/src/api/notifications/__tests__/AlephaApiNotifications.spec.ts +2 -2
  390. package/src/api/notifications/controllers/AdminNotificationController.ts +38 -14
  391. package/src/api/notifications/jobs/NotificationJobs.ts +7 -6
  392. package/src/api/notifications/primitives/$notification.ts +43 -4
  393. package/src/api/notifications/schemas/notificationContactPreferencesSchema.ts +4 -4
  394. package/src/api/notifications/schemas/notificationContactSchema.ts +7 -7
  395. package/src/api/notifications/schemas/notificationDetailResourceSchema.ts +9 -11
  396. package/src/api/notifications/schemas/notificationPayloadSchema.ts +11 -9
  397. package/src/api/notifications/schemas/notificationQuerySchema.ts +6 -6
  398. package/src/api/notifications/schemas/notificationResourceSchema.ts +14 -14
  399. package/src/api/notifications/services/NotificationSenderService.ts +38 -2
  400. package/src/api/oauth/__tests__/OAuthClientService.spec.ts +42 -0
  401. package/src/api/oauth/__tests__/OAuthController.spec.ts +128 -0
  402. package/src/api/oauth/controllers/OAuthController.ts +132 -12
  403. package/src/api/oauth/entities/oauthClientEntity.ts +29 -12
  404. package/src/api/oauth/helpers/oauthMetadata.ts +1 -0
  405. package/src/api/oauth/helpers/oidcMetadata.ts +19 -0
  406. package/src/api/oauth/index.ts +1 -0
  407. package/src/api/oauth/schemas/authorizeDecisionBodySchema.ts +12 -11
  408. package/src/api/oauth/schemas/authorizeQuerySchema.ts +12 -10
  409. package/src/api/oauth/schemas/registerClientBodySchema.ts +10 -11
  410. package/src/api/oauth/schemas/tokenRequestBodySchema.ts +9 -8
  411. package/src/api/oauth/services/OAuthClientService.ts +228 -15
  412. package/src/api/organizations/controllers/AdminOrganizationController.ts +8 -8
  413. package/src/api/organizations/entities/organizations.ts +6 -6
  414. package/src/api/organizations/schemas/createOrganizationSchema.ts +5 -5
  415. package/src/api/organizations/schemas/organizationQuerySchema.ts +4 -4
  416. package/src/api/organizations/schemas/updateOrganizationSchema.ts +1 -2
  417. package/src/api/parameters/__tests__/$parameter.spec.ts +229 -50
  418. package/src/api/parameters/controllers/AdminParameterController.ts +9 -12
  419. package/src/api/parameters/entities/parameters.ts +29 -16
  420. package/src/api/parameters/primitives/$parameter.ts +3 -3
  421. package/src/api/parameters/schemas/activateParameterBodySchema.ts +4 -4
  422. package/src/api/parameters/schemas/createParameterVersionBodySchema.ts +15 -15
  423. package/src/api/parameters/schemas/parameterCreatorSummarySchema.ts +7 -7
  424. package/src/api/parameters/schemas/parameterCurrentResponseSchema.ts +7 -7
  425. package/src/api/parameters/schemas/parameterHistoryResponseSchema.ts +3 -3
  426. package/src/api/parameters/schemas/parameterNameParamSchema.ts +2 -3
  427. package/src/api/parameters/schemas/parameterNamesResponseSchema.ts +3 -3
  428. package/src/api/parameters/schemas/parameterResponseSchema.ts +3 -3
  429. package/src/api/parameters/schemas/parameterStatusSchema.ts +2 -2
  430. package/src/api/parameters/schemas/parameterTreeNodeSchema.ts +6 -6
  431. package/src/api/parameters/schemas/parameterVersionParamSchema.ts +5 -6
  432. package/src/api/parameters/schemas/parameterVersionResponseSchema.ts +3 -3
  433. package/src/api/parameters/schemas/rollbackParameterBodySchema.ts +6 -9
  434. package/src/api/parameters/services/ParameterProvider.ts +152 -65
  435. package/src/api/payments/controllers/AdminPaymentController.ts +7 -7
  436. package/src/api/payments/controllers/MockCheckoutController.ts +79 -28
  437. package/src/api/payments/controllers/PaymentController.ts +4 -4
  438. package/src/api/payments/entities/paymentIntents.ts +11 -11
  439. package/src/api/payments/entities/paymentMethods.ts +11 -11
  440. package/src/api/payments/entities/refunds.ts +9 -9
  441. package/src/api/payments/providers/PaymentProvider.ts +18 -0
  442. package/src/api/payments/schemas/intentSchemas.ts +25 -25
  443. package/src/api/payments/schemas/paymentMethodSchemas.ts +3 -3
  444. package/src/api/payments/services/PaymentService.ts +60 -3
  445. package/src/api/subscriptions/__tests__/SubscriptionService.spec.ts +14 -0
  446. package/src/api/subscriptions/controllers/AdminSubscriptionController.ts +11 -11
  447. package/src/api/subscriptions/controllers/SubscriptionController.ts +5 -4
  448. package/src/api/subscriptions/entities/subscriptionEvents.ts +15 -15
  449. package/src/api/subscriptions/entities/subscriptions.ts +22 -22
  450. package/src/api/subscriptions/notifications/SubscriptionNotifications.ts +22 -22
  451. package/src/api/subscriptions/schemas/cancelSubscriptionSchema.ts +4 -4
  452. package/src/api/subscriptions/schemas/changePlanSchema.ts +5 -5
  453. package/src/api/subscriptions/schemas/createSubscriptionSchema.ts +14 -7
  454. package/src/api/subscriptions/schemas/entitlementsSchema.ts +10 -10
  455. package/src/api/subscriptions/schemas/mrrSchema.ts +9 -9
  456. package/src/api/subscriptions/schemas/planDefinitionSchema.ts +21 -21
  457. package/src/api/subscriptions/schemas/planResourceSchema.ts +19 -19
  458. package/src/api/subscriptions/schemas/subscriptionQuerySchema.ts +8 -8
  459. package/src/api/subscriptions/schemas/subscriptionSettingsSchema.ts +7 -7
  460. package/src/api/subscriptions/schemas/subscriptionStatsSchema.ts +17 -17
  461. package/src/api/subscriptions/services/SubscriptionConfig.ts +2 -2
  462. package/src/api/users/__tests__/ApiKeys-integration.spec.ts +11 -11
  463. package/src/api/users/atoms/realmAuthSettingsAtom.ts +111 -119
  464. package/src/api/users/controllers/AdminIdentityController.ts +29 -19
  465. package/src/api/users/controllers/AdminSessionController.ts +37 -27
  466. package/src/api/users/controllers/AdminUserController.ts +75 -53
  467. package/src/api/users/controllers/MySessionController.ts +125 -0
  468. package/src/api/users/controllers/RealmController.ts +9 -9
  469. package/src/api/users/controllers/UserController.ts +55 -55
  470. package/src/api/users/entities/identities.ts +8 -8
  471. package/src/api/users/entities/sessions.ts +17 -17
  472. package/src/api/users/entities/users.ts +17 -17
  473. package/src/api/users/index.ts +3 -0
  474. package/src/api/users/notifications/UserNotifications.ts +76 -24
  475. package/src/api/users/primitives/$realm.ts +12 -0
  476. package/src/api/users/schemas/completePasswordResetRequestSchema.ts +8 -12
  477. package/src/api/users/schemas/completeRegistrationRequestSchema.ts +17 -20
  478. package/src/api/users/schemas/createUserSchema.ts +2 -2
  479. package/src/api/users/schemas/identityQuerySchema.ts +4 -4
  480. package/src/api/users/schemas/identityResourceSchema.ts +3 -2
  481. package/src/api/users/schemas/loginSchema.ts +4 -4
  482. package/src/api/users/schemas/passwordResetIntentResponseSchema.ts +6 -8
  483. package/src/api/users/schemas/realmConfigSchema.ts +10 -10
  484. package/src/api/users/schemas/registerQuerySchema.ts +6 -6
  485. package/src/api/users/schemas/registerRequestSchema.ts +21 -43
  486. package/src/api/users/schemas/registerResponseSchema.ts +2 -2
  487. package/src/api/users/schemas/registerSchema.ts +13 -31
  488. package/src/api/users/schemas/registrationIntentResponseSchema.ts +19 -23
  489. package/src/api/users/schemas/resetPasswordSchema.ts +10 -17
  490. package/src/api/users/schemas/sessionQuerySchema.ts +3 -3
  491. package/src/api/users/schemas/sessionResourceSchema.ts +25 -25
  492. package/src/api/users/schemas/updateUserSchema.ts +3 -4
  493. package/src/api/users/schemas/userQuerySchema.ts +7 -7
  494. package/src/api/users/services/RegistrationService.ts +25 -11
  495. package/src/api/users/services/UserService.ts +12 -6
  496. package/src/api/verifications/__tests__/CodeVerification.spec.ts +63 -101
  497. package/src/api/verifications/__tests__/LinkVerification.spec.ts +23 -92
  498. package/src/api/verifications/controllers/VerificationController.ts +13 -27
  499. package/src/api/verifications/entities/verifications.ts +13 -14
  500. package/src/api/verifications/schemas/requestVerificationCodeResponseSchema.ts +17 -14
  501. package/src/api/verifications/schemas/validateVerificationCodeResponseSchema.ts +9 -10
  502. package/src/api/verifications/schemas/verificationSettingsSchema.ts +65 -66
  503. package/src/api/verifications/schemas/verificationTypeEnumSchema.ts +2 -2
  504. package/src/api/verifications/services/VerificationService.ts +12 -0
  505. package/src/background/__tests__/BackgroundTaskProvider.spec.ts +36 -0
  506. package/src/batch/__tests__/$batch.spec.ts +22 -22
  507. package/src/batch/__tests__/startup-buffering.spec.ts +9 -9
  508. package/src/bin/index.ts +1 -1
  509. package/src/bucket/__tests__/TenantScopedBucket.spec.ts +60 -0
  510. package/src/bucket/providers/LocalFileStorageProvider.ts +14 -6
  511. package/src/bucket/providers/MemoryFileStorageProvider.ts +18 -7
  512. package/src/bucket/providers/R2FileStorageProvider.ts +14 -6
  513. package/src/bucket/providers/S3FileStorageProvider.ts +31 -15
  514. package/src/cache/core/primitives/$cache.ts +7 -10
  515. package/src/cache/database/entities/cacheEntries.ts +16 -27
  516. package/src/cache/database/providers/DatabaseCacheProvider.ts +15 -13
  517. package/src/cache/redis/providers/RedisCacheProvider.ts +6 -6
  518. package/src/captcha/providers/TurnstileCaptchaProvider.ts +4 -4
  519. package/src/cli/core/__tests__/BuildCloudflareTask.spec.ts +178 -0
  520. package/src/cli/core/__tests__/BuildDockerTask.spec.ts +0 -2
  521. package/src/cli/core/__tests__/DbCommand.spec.ts +108 -0
  522. package/src/cli/core/atoms/appEntryOptions.ts +5 -5
  523. package/src/cli/core/atoms/buildOptions.ts +76 -88
  524. package/src/cli/core/atoms/changelogOptions.ts +3 -3
  525. package/src/cli/core/atoms/devOptions.ts +3 -3
  526. package/src/cli/core/commands/build.ts +36 -49
  527. package/src/cli/core/commands/db.ts +171 -83
  528. package/src/cli/core/commands/dev.ts +8 -8
  529. package/src/cli/core/commands/gen/changelog.ts +12 -14
  530. package/src/cli/core/commands/gen/env.ts +6 -6
  531. package/src/cli/core/commands/gen/openapi.ts +6 -6
  532. package/src/cli/core/commands/init.ts +28 -33
  533. package/src/cli/core/commands/pack.ts +10 -10
  534. package/src/cli/core/commands/root.ts +7 -8
  535. package/src/cli/core/commands/test.ts +17 -20
  536. package/src/cli/core/index.ts +0 -3
  537. package/src/cli/core/tasks/BuildCloudflareTask.ts +138 -245
  538. package/src/cli/core/tasks/BuildPrerenderTask.ts +44 -7
  539. package/src/cli/core/templates/apiHelloResponseSchemaTs.ts +4 -4
  540. package/src/cli/devtools/atoms/devtoolsOptions.ts +6 -6
  541. package/src/cli/i18n/__tests__/I18nCheckService.spec.ts +48 -0
  542. package/src/cli/i18n/atoms/i18nOptions.ts +8 -8
  543. package/src/cli/i18n/services/I18nCheckService.ts +65 -11
  544. package/src/cli/platform/commands/SecretsCommand.ts +24 -25
  545. package/src/cli/platform/commands/platform.ts +40 -46
  546. package/src/cli/platform/index.ts +1 -1
  547. package/src/cli/platform-lib/__tests__/CloudflareAdapter.spec.ts +0 -4
  548. package/src/cli/platform-lib/__tests__/PlatformInspector.spec.ts +10 -3
  549. package/src/cli/platform-lib/__tests__/VercelAdapter.spec.ts +0 -2
  550. package/src/cli/platform-lib/adapters/CloudflareAdapter.ts +141 -50
  551. package/src/cli/platform-lib/adapters/VercelAdapter.ts +6 -11
  552. package/src/cli/platform-lib/atoms/platformOptions.ts +46 -25
  553. package/src/cli/platform-lib/schemas/cloudflare.ts +87 -87
  554. package/src/cli/platform-lib/schemas/platform.ts +51 -51
  555. package/src/cli/platform-lib/schemas/vercel.ts +28 -28
  556. package/src/cli/platform-lib/services/CloudflareApi.ts +5 -5
  557. package/src/cli/platform-lib/services/VercelApi.ts +4 -4
  558. package/src/cli/platform-lib/services/VercelCli.ts +6 -15
  559. package/src/cli/platform-lib/services/WranglerApi.ts +6 -15
  560. package/src/cli/vendor/atoms/vendorOptions.ts +9 -9
  561. package/src/cli/vendor/commands/VendorCommand.ts +11 -12
  562. package/src/command/__tests__/$command.spec.ts +82 -83
  563. package/src/command/__tests__/Asker.spec.ts +6 -13
  564. package/src/command/__tests__/CliProvider.spec.ts +136 -149
  565. package/src/command/__tests__/Runner.spec.ts +86 -110
  566. package/src/command/helpers/Asker.ts +23 -58
  567. package/src/command/helpers/Runner.ts +34 -110
  568. package/src/command/index.ts +4 -9
  569. package/src/command/primitives/$command.ts +10 -10
  570. package/src/command/providers/CliProvider.ts +183 -161
  571. package/src/core/Alepha.ts +62 -13
  572. package/src/core/__tests__/$atom.spec.ts +52 -3
  573. package/src/core/__tests__/$computed.spec.ts +129 -0
  574. package/src/core/__tests__/$env.spec.ts +13 -13
  575. package/src/core/__tests__/$inject.spec.ts +4 -4
  576. package/src/core/__tests__/$module.spec.ts +1 -1
  577. package/src/core/__tests__/Alepha-graph.spec.ts +1 -1
  578. package/src/core/__tests__/Alepha-parseEnv.spec.ts +32 -32
  579. package/src/core/__tests__/Alepha-start.spec.ts +3 -3
  580. package/src/core/__tests__/CodecManager.spec.ts +113 -94
  581. package/src/core/__tests__/KeylessJsonSchemaCodec.spec.ts +138 -138
  582. package/src/core/__tests__/SchemaValidator.spec.ts +43 -44
  583. package/src/core/__tests__/StateManager.persist.browser.spec.ts +87 -0
  584. package/src/core/__tests__/StateManager.spec.ts +423 -0
  585. package/src/core/__tests__/TypeBox-usecases.spec.ts +8 -8
  586. package/src/core/__tests__/TypeProvider.spec.ts +314 -309
  587. package/src/core/__tests__/dump.spec.ts +6 -6
  588. package/src/core/__tests__/pagination.spec.ts +4 -4
  589. package/src/core/__tests__/scoped-after-start.spec.ts +43 -0
  590. package/src/core/errors/TypeBoxError.ts +10 -4
  591. package/src/core/helpers/FileLike.ts +5 -5
  592. package/src/core/helpers/coerceStrings.ts +70 -0
  593. package/src/core/helpers/jsonSchemaToZod.ts +112 -0
  594. package/src/core/index.shared.ts +4 -1
  595. package/src/core/primitives/$atom.ts +95 -27
  596. package/src/core/primitives/$computed.ts +148 -0
  597. package/src/core/primitives/$env.ts +5 -5
  598. package/src/core/primitives/$state.ts +1 -1
  599. package/src/core/providers/AlsProvider.ts +26 -0
  600. package/src/core/providers/CodecManager.ts +1 -2
  601. package/src/core/providers/JsonSchemaCodec.ts +1 -2
  602. package/src/core/providers/KeylessJsonSchemaCodec.ts +82 -57
  603. package/src/core/providers/SchemaValidator.ts +48 -158
  604. package/src/core/providers/StateManager.ts +383 -9
  605. package/src/core/providers/TypeProvider.ts +80 -734
  606. package/src/core/providers/ZodProvider.ts +380 -0
  607. package/src/core/providers/zodAugment.ts +69 -0
  608. package/src/core/schemas/pageQuerySchema.ts +19 -21
  609. package/src/core/schemas/pageSchema.ts +47 -57
  610. package/src/crypto/__tests__/SecretProvider.spec.ts +31 -0
  611. package/src/crypto/providers/SecretProvider.ts +16 -10
  612. package/src/datetime/primitives/$throttle.ts +6 -1
  613. package/src/email/brevo/providers/BrevoEmailProvider.ts +4 -4
  614. package/src/email/cloudflare/providers/CloudflareEmailProvider.ts +6 -6
  615. package/src/email/core/index.ts +7 -2
  616. package/src/email/core/primitives/$email.ts +5 -1
  617. package/src/email/core/providers/LocalEmailProvider.ts +5 -5
  618. package/src/email/smtp/providers/NodemailerEmailProvider.ts +41 -52
  619. package/src/fake/__tests__/FakeProvider.spec.ts +110 -110
  620. package/src/fake/__tests__/keyName.example.ts +21 -21
  621. package/src/fake/__tests__/keyName.spec.ts +41 -41
  622. package/src/fake/__tests__/module.example.ts +8 -8
  623. package/src/fake/providers/FakeProvider.ts +122 -121
  624. package/src/lock/core/__tests__/lock-mutual-exclusion.spec.ts +44 -0
  625. package/src/lock/core/index.ts +1 -0
  626. package/src/lock/core/primitives/$lock.ts +13 -6
  627. package/src/logger/__tests__/CliFormatterProvider.spec.ts +76 -0
  628. package/src/logger/__tests__/Logger.spec.ts +49 -0
  629. package/src/logger/index.ts +25 -18
  630. package/src/logger/providers/CliFormatterProvider.ts +75 -0
  631. package/src/logger/schemas/logEntrySchema.ts +10 -10
  632. package/src/logger/services/Logger.ts +18 -0
  633. package/src/mcp/__tests__/$prompt.spec.ts +21 -23
  634. package/src/mcp/__tests__/$tool.spec.ts +22 -22
  635. package/src/mcp/__tests__/McpServerProvider.spec.ts +82 -11
  636. package/src/mcp/__tests__/StreamableHttpMcpTransport.spec.ts +2 -2
  637. package/src/mcp/__tests__/integration.spec.ts +33 -33
  638. package/src/mcp/primitives/$prompt.ts +11 -9
  639. package/src/mcp/primitives/$tool.ts +27 -86
  640. package/src/mcp/providers/McpServerProvider.ts +55 -0
  641. package/src/mcp/transports/StreamableHttpMcpTransport.ts +7 -7
  642. package/src/orm/__tests__/$repository-tests.ts +133 -27
  643. package/src/orm/__tests__/$repository.spec.ts +23 -0
  644. package/src/orm/__tests__/$transactional-tests.ts +4 -4
  645. package/src/orm/__tests__/ModelBuilder-tests.ts +28 -28
  646. package/src/orm/__tests__/ModelBuilder.spec.ts +124 -106
  647. package/src/orm/__tests__/QueryManager.spec.ts +5 -5
  648. package/src/orm/__tests__/delete-returning-tests.ts +11 -11
  649. package/src/orm/__tests__/deletedAt-tests.ts +3 -3
  650. package/src/orm/__tests__/enums.spec.ts +29 -25
  651. package/src/orm/__tests__/execute-tests.ts +8 -8
  652. package/src/orm/__tests__/fixtures/bigEntitySchema.ts +48 -48
  653. package/src/orm/__tests__/fixtures/userEntitySchema.ts +6 -6
  654. package/src/orm/__tests__/joins-tests.ts +30 -30
  655. package/src/orm/__tests__/organization-tests.ts +105 -3
  656. package/src/orm/__tests__/organization.spec.ts +46 -0
  657. package/src/orm/__tests__/orm-errors.spec.ts +10 -10
  658. package/src/orm/__tests__/orm-next-tests.ts +29 -29
  659. package/src/orm/__tests__/orm-showcase-tests.ts +9 -9
  660. package/src/orm/__tests__/primaryKey.spec.ts +4 -4
  661. package/src/orm/__tests__/query-date-encoding-tests.ts +17 -17
  662. package/src/orm/__tests__/ref-auto-onDelete.spec.ts +14 -14
  663. package/src/orm/__tests__/references.spec.ts +7 -7
  664. package/src/orm/__tests__/security.spec.ts +17 -17
  665. package/src/orm/__tests__/string-operators-tests.ts +5 -5
  666. package/src/orm/__tests__/timestamps-tests.ts +14 -14
  667. package/src/orm/__tests__/validation-tests.ts +5 -5
  668. package/src/orm/core/__tests__/BunSqliteProvider.bun.spec.ts +8 -8
  669. package/src/orm/core/constants/PG_SYMBOLS.ts +13 -1
  670. package/src/orm/core/entities/alephaSequences.ts +8 -8
  671. package/src/orm/core/helpers/pgAttr.ts +4 -4
  672. package/src/orm/core/primitives/$entity.ts +10 -6
  673. package/src/orm/core/providers/DatabaseTypeProvider.ts +46 -53
  674. package/src/orm/core/providers/drivers/BunSqliteProvider.ts +8 -8
  675. package/src/orm/core/providers/drivers/CloudflareD1Provider.ts +3 -5
  676. package/src/orm/core/providers/drivers/NodeSqliteProvider.ts +8 -8
  677. package/src/orm/core/schemas/databaseEnvSchema.ts +4 -4
  678. package/src/orm/core/schemas/insertSchema.ts +14 -18
  679. package/src/orm/core/schemas/legacyIdSchema.ts +2 -2
  680. package/src/orm/core/schemas/updateSchema.ts +10 -16
  681. package/src/orm/core/services/PgRelationManager.ts +2 -2
  682. package/src/orm/core/services/QueryManager.ts +13 -2
  683. package/src/orm/core/services/Repository.ts +88 -33
  684. package/src/orm/core/services/SqliteModelBuilder.ts +38 -45
  685. package/src/orm/postgres/__tests__/BunPostgresProvider.bun.spec.ts +4 -4
  686. package/src/orm/postgres/providers/CloudflareHyperdriveProvider.ts +4 -6
  687. package/src/orm/postgres/schemas/postgresEnvSchema.ts +6 -6
  688. package/src/orm/postgres/services/PostgresModelBuilder.ts +127 -114
  689. package/src/queue/core/__tests__/$consumer.spec.ts +4 -4
  690. package/src/queue/core/__tests__/WorkerProvider.spec.ts +4 -4
  691. package/src/queue/core/__tests__/shared.ts +6 -6
  692. package/src/queue/core/primitives/$consumer.ts +5 -5
  693. package/src/queue/core/primitives/$queue.ts +44 -61
  694. package/src/queue/core/providers/CloudflareQueueProvider.ts +6 -0
  695. package/src/queue/core/providers/WorkerProvider.ts +17 -14
  696. package/src/queue/redis/providers/RedisQueueProvider.ts +3 -3
  697. package/src/react/core/__tests__/ErrorBoundary.browser.spec.tsx +92 -0
  698. package/src/react/core/__tests__/Router.spec.tsx +4 -4
  699. package/src/react/core/__tests__/useComputed.browser.spec.tsx +192 -0
  700. package/src/react/core/__tests__/useQuery.browser.spec.tsx +48 -0
  701. package/src/react/core/__tests__/useSelector.browser.spec.tsx +105 -0
  702. package/src/react/core/__tests__/useStore.browser.spec.tsx +113 -0
  703. package/src/react/core/components/ErrorBoundary.tsx +42 -0
  704. package/src/react/core/hooks/useAction.ts +56 -19
  705. package/src/react/core/hooks/useComputed.ts +91 -0
  706. package/src/react/core/hooks/useSelector.ts +67 -0
  707. package/src/react/core/hooks/useStore.ts +36 -17
  708. package/src/react/core/index.ts +3 -0
  709. package/src/react/core/utils/shallowEqual.ts +36 -0
  710. package/src/react/form/__tests__/FormModel-submit-loading.spec.ts +71 -0
  711. package/src/react/form/__tests__/form-submitting-reactive.browser.spec.tsx +96 -0
  712. package/src/react/form/__tests__/useForm.browser.spec.tsx +54 -54
  713. package/src/react/form/errors/FormValidationError.ts +0 -2
  714. package/src/react/form/hooks/useForm.ts +19 -4
  715. package/src/react/form/hooks/useFormQuerySync.ts +0 -0
  716. package/src/react/form/services/FormModel.ts +124 -86
  717. package/src/react/form/services/parseField.ts +66 -27
  718. package/src/react/i18n/__tests__/I18nProvider.spec.ts +89 -0
  719. package/src/react/i18n/__tests__/Localize.spec.tsx +1 -1
  720. package/src/react/i18n/__tests__/locale-routing.spec.ts +107 -0
  721. package/src/react/i18n/providers/I18nProvider.ts +173 -14
  722. package/src/react/router/__tests__/$page.browser.spec.tsx +19 -19
  723. package/src/react/router/__tests__/$page.spec.tsx +21 -21
  724. package/src/react/router/__tests__/ReactBrowserProvider.browser.spec.ts +87 -1
  725. package/src/react/router/__tests__/RouterLocaleProvider.spec.ts +127 -0
  726. package/src/react/router/atoms/ssrManifestAtom.ts +16 -16
  727. package/src/react/router/components/NestedView.tsx +11 -3
  728. package/src/react/router/hooks/useQueryParams.ts +1 -1
  729. package/src/react/router/index.browser.ts +4 -0
  730. package/src/react/router/index.shared.ts +1 -0
  731. package/src/react/router/index.ts +9 -0
  732. package/src/react/router/primitives/$page.ts +2 -2
  733. package/src/react/router/providers/ReactBrowserProvider.ts +64 -13
  734. package/src/react/router/providers/ReactBrowserRouterProvider.ts +15 -1
  735. package/src/react/router/providers/ReactPageProvider.ts +38 -13
  736. package/src/react/router/providers/ReactServerProvider.ts +105 -16
  737. package/src/react/router/providers/RootComponentsProvider.ts +13 -0
  738. package/src/react/router/providers/RouterLocaleProvider.ts +125 -0
  739. package/src/react/router/providers/__tests__/RootComponentsProvider.spec.ts +15 -0
  740. package/src/react/router/providers/__tests__/rootComponents.ssr.browser.spec.tsx +67 -0
  741. package/src/react/sitemap/__tests__/$sitemap.spec.ts +131 -0
  742. package/src/react/sitemap/index.browser.ts +21 -0
  743. package/src/react/sitemap/index.ts +25 -0
  744. package/src/react/sitemap/primitives/$sitemap.browser.ts +26 -0
  745. package/src/react/sitemap/primitives/$sitemap.ts +196 -0
  746. package/src/react/ui/atoms/uiAtom.ts +6 -6
  747. package/src/react/ui/atoms/uiThemeListAtom.ts +7 -7
  748. package/src/react/ui/hooks/useColorMode.ts +11 -4
  749. package/src/react/ui/services/SchemaControl.ts +4 -4
  750. package/src/redis/providers/BunRedisProvider.ts +19 -11
  751. package/src/redis/providers/NodeRedisProvider.ts +3 -3
  752. package/src/scheduler/primitives/$scheduler.ts +21 -8
  753. package/src/security/__tests__/assertRealmScope.spec.ts +29 -0
  754. package/src/security/atoms/currentTenantAtom.ts +6 -6
  755. package/src/security/atoms/currentUserAtom.ts +2 -2
  756. package/src/security/primitives/$issuer.ts +24 -2
  757. package/src/security/providers/JwtProvider.ts +100 -0
  758. package/src/security/providers/SecurityProvider.ts +43 -2
  759. package/src/security/schemas/permissionSchema.ts +19 -19
  760. package/src/security/schemas/roleSchema.ts +22 -28
  761. package/src/security/schemas/userAccountInfoSchema.ts +47 -37
  762. package/src/server/auth/__tests__/appleClientSecret.spec.ts +34 -0
  763. package/src/server/auth/__tests__/federationRedirectReplay.spec.ts +44 -0
  764. package/src/server/auth/helpers/appleClientSecret.ts +24 -0
  765. package/src/server/auth/helpers/jtiReplayGuard.ts +41 -0
  766. package/src/server/auth/helpers/safeRedirectPath.ts +19 -0
  767. package/src/server/auth/index.ts +1 -0
  768. package/src/server/auth/primitives/$auth.ts +6 -6
  769. package/src/server/auth/primitives/$authApple.ts +10 -10
  770. package/src/server/auth/primitives/$authFacebook.ts +10 -10
  771. package/src/server/auth/primitives/$authFranceConnect.ts +10 -10
  772. package/src/server/auth/primitives/$authGithub.ts +10 -10
  773. package/src/server/auth/primitives/$authGoogle.ts +10 -10
  774. package/src/server/auth/primitives/$authMicrosoft.ts +14 -14
  775. package/src/server/auth/providers/ServerAuthProvider.ts +67 -52
  776. package/src/server/auth/schemas/authenticationProviderSchema.ts +9 -12
  777. package/src/server/auth/schemas/tokenResponseSchema.ts +2 -2
  778. package/src/server/auth/schemas/tokensSchema.ts +16 -16
  779. package/src/server/auth/schemas/userinfoResponseSchema.ts +3 -3
  780. package/src/server/cookies/__tests__/AtomCookieBinding.spec.ts +80 -0
  781. package/src/server/cookies/__tests__/AtomCookiePersistence.browser.spec.ts +169 -0
  782. package/src/server/cookies/__tests__/AtomCookiePersistence.spec.ts +294 -0
  783. package/src/server/cookies/__tests__/ServerCookiesProvider.spec.ts +82 -12
  784. package/src/server/cookies/index.browser.ts +4 -1
  785. package/src/server/cookies/index.ts +8 -1
  786. package/src/server/cookies/primitives/$cookie.browser.ts +1 -1
  787. package/src/server/cookies/primitives/$cookie.ts +16 -0
  788. package/src/server/cookies/providers/AtomCookiePersistence.browser.ts +133 -0
  789. package/src/server/cookies/providers/AtomCookiePersistence.ts +148 -0
  790. package/src/server/cookies/providers/ServerCookiesProvider.ts +32 -4
  791. package/src/server/cookies/services/CookieParser.ts +6 -1
  792. package/src/server/core/__tests__/$action.spec.ts +13 -13
  793. package/src/server/core/__tests__/$middleware.spec.ts +10 -10
  794. package/src/server/core/__tests__/$route.spec.ts +9 -9
  795. package/src/server/core/__tests__/$sse.spec.ts +26 -26
  796. package/src/server/core/__tests__/BunHttpServerProvider.bun.spec.ts +6 -6
  797. package/src/server/core/__tests__/HttpClient.spec.ts +2 -2
  798. package/src/server/core/__tests__/NodeHttpServerProvider.spec.ts +15 -3
  799. package/src/server/core/__tests__/ServerBodyParserProvider.spec.ts +14 -14
  800. package/src/server/core/__tests__/ServerMultipartProvider.spec.ts +33 -33
  801. package/src/server/core/__tests__/ServerRouterProvider-errorHandler.spec.ts +5 -1
  802. package/src/server/core/__tests__/ServerRouterProvider-getRoutes.spec.ts +25 -25
  803. package/src/server/core/__tests__/ServerRouterProvider-serializationError.spec.ts +9 -5
  804. package/src/server/core/__tests__/ServerRouterProvider-validationError.spec.ts +56 -24
  805. package/src/server/core/errors/ValidationError.ts +6 -3
  806. package/src/server/core/helpers/isMultipart.ts +2 -1
  807. package/src/server/core/index.ts +5 -2
  808. package/src/server/core/interfaces/ServerRequest.ts +14 -14
  809. package/src/server/core/primitives/$action.ts +26 -36
  810. package/src/server/core/primitives/$route.ts +27 -0
  811. package/src/server/core/primitives/$sse.ts +3 -3
  812. package/src/server/core/providers/BunHttpServerProvider.ts +8 -9
  813. package/src/server/core/providers/NodeHttpServerProvider.ts +8 -9
  814. package/src/server/core/providers/ServerBodyParserProvider.ts +20 -12
  815. package/src/server/core/providers/ServerCompressProvider.ts +9 -10
  816. package/src/server/core/providers/ServerHelmetProvider.ts +26 -27
  817. package/src/server/core/providers/ServerMultipartProvider.ts +19 -19
  818. package/src/server/core/providers/ServerRouterProvider.ts +44 -15
  819. package/src/server/core/schemas/errorSchema.ts +20 -25
  820. package/src/server/core/schemas/okSchema.ts +9 -14
  821. package/src/server/core/services/HttpClient.ts +13 -1
  822. package/src/server/core/services/ServerRequestParser.ts +6 -6
  823. package/src/server/cors/providers/ServerCorsProvider.ts +26 -28
  824. package/src/server/health/schemas/healthSchema.ts +6 -6
  825. package/src/server/links/__tests__/$remote.spec.ts +3 -3
  826. package/src/server/links/__tests__/BatchEndpoint.spec.ts +9 -9
  827. package/src/server/links/__tests__/LinkProvider.spec.ts +9 -9
  828. package/src/server/links/__tests__/ServerLinksProvider.spec.ts +23 -23
  829. package/src/server/links/__tests__/fixtures/CrudApp.ts +21 -21
  830. package/src/server/links/atoms/apiLinksAtom.ts +2 -2
  831. package/src/server/links/atoms/linkOptionsAtom.ts +6 -6
  832. package/src/server/links/primitives/$remote.ts +3 -3
  833. package/src/server/links/providers/LinkProvider.ts +3 -3
  834. package/src/server/links/providers/ServerLinksProvider.ts +20 -20
  835. package/src/server/links/schemas/apiLinksResponseSchema.ts +23 -23
  836. package/src/server/proxy/__tests__/$proxy.spec.ts +9 -9
  837. package/src/server/proxy/providers/ServerProxyProvider.ts +5 -0
  838. package/src/server/rate-limit/providers/ServerRateLimitProvider.ts +18 -20
  839. package/src/server/swagger/__tests__/$swagger.spec.ts +91 -94
  840. package/src/server/swagger/__tests__/ui.spec.ts +3 -3
  841. package/src/server/swagger/providers/ServerSwaggerProvider.ts +66 -43
  842. package/src/system/__tests__/NodeShellProvider.spec.ts +46 -0
  843. package/src/system/providers/NodeShellProvider.ts +4 -1
  844. package/src/topic/core/__tests__/$subscriber.spec.ts +4 -4
  845. package/src/topic/core/__tests__/shared.ts +8 -8
  846. package/src/topic/core/primitives/$subscriber.ts +5 -5
  847. package/src/topic/core/primitives/$topic.ts +14 -14
  848. package/src/topic/redis/providers/RedisTopicProvider.ts +3 -3
  849. package/dist/container/core/index.d.ts +0 -236
  850. package/dist/container/core/index.d.ts.map +0 -1
  851. package/dist/container/core/index.js +0 -231
  852. package/dist/container/core/index.js.map +0 -1
  853. package/dist/container/core/index.workerd.js +0 -192
  854. package/dist/container/core/index.workerd.js.map +0 -1
  855. package/src/cli/core/tasks/BuildSitemapTask.ts +0 -130
  856. package/src/command/helpers/PrettyAsker.ts +0 -256
  857. package/src/command/helpers/PrettyPrint.ts +0 -332
  858. package/src/container/core/__tests__/$container.spec.ts +0 -83
  859. package/src/container/core/index.ts +0 -50
  860. package/src/container/core/index.workerd.ts +0 -53
  861. package/src/container/core/interfaces/ContainerOptions.ts +0 -69
  862. package/src/container/core/primitives/$container.ts +0 -100
  863. package/src/container/core/providers/CloudflareContainerProvider.ts +0 -70
  864. package/src/container/core/providers/ContainerProvider.ts +0 -92
  865. package/src/container/core/providers/MockContainerProvider.ts +0 -62
  866. package/src/container/core/providers/NodeContainerProvider.ts +0 -53
  867. package/src/core/__tests__/jsonSchemaToTypeBox.spec.ts +0 -771
  868. package/src/core/helpers/jsonSchemaToTypeBox.ts +0 -359
  869. /package/dist/orm/core/{chunk-B4FMCO8f.js → rolldown-runtime-B4FMCO8f.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/react/form/hooks/useFormState.ts","../../../src/react/form/components/FormState.tsx","../../../src/react/form/errors/FormValidationError.ts","../../../src/react/form/hooks/useFieldValue.ts","../../../src/react/form/services/FormModel.ts","../../../src/react/form/hooks/useForm.ts","../../../src/react/form/hooks/useFormQuerySync.ts","../../../src/react/form/hooks/useFormValues.ts","../../../src/react/form/services/prettyName.ts","../../../src/react/form/services/parseField.ts","../../../src/react/form/index.ts"],"sourcesContent":["import { type TObject, TypeBoxError } from \"alepha\";\nimport { useAlepha } from \"alepha/react\";\nimport { useEffect, useState } from \"react\";\nimport type { FormModel } from \"../services/FormModel.ts\";\n\nexport interface UseFormStateReturn {\n loading: boolean;\n dirty: boolean;\n values?: Record<string, any>;\n error?: Error;\n}\n\nexport const useFormState = <\n T extends TObject,\n Keys extends keyof UseFormStateReturn,\n>(\n target: FormModel<T> | { form: FormModel<T>; path: string },\n _events: Keys[] = [\"loading\", \"dirty\", \"error\"] as Keys[],\n): Pick<UseFormStateReturn, Keys> => {\n const alepha = useAlepha();\n const events = _events as string[];\n\n const [dirty, setDirty] = useState(false);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | undefined>(undefined);\n const [values, setValues] = useState<Record<string, any> | undefined>(\n undefined,\n );\n\n const form = \"form\" in target ? target.form : target;\n const path = \"path\" in target ? target.path : undefined;\n\n const hasValues = events.includes(\"values\");\n const hasErrors = events.includes(\"error\");\n const hasDirty = events.includes(\"dirty\");\n const hasLoading = events.includes(\"loading\");\n\n useEffect(() => {\n const listeners: Function[] = [];\n\n if (hasErrors || hasValues || hasDirty) {\n listeners.push(\n alepha.events.on(\"form:change\", (event) => {\n if (event.id === form.id) {\n if (!path || event.path === path) {\n // `initial: true` marks a programmatic reset (e.g. parent\n // re-rendering with fresh data via `setInitialValues`). Treat\n // it like a reset: clear dirty, don't mark dirty.\n if (hasDirty) {\n if (event.initial) {\n setDirty(false);\n } else {\n setDirty(true);\n }\n }\n if (hasErrors) {\n setError(undefined);\n }\n }\n if (hasValues) {\n setValues(form.currentValues);\n }\n }\n }),\n );\n }\n\n if (hasLoading) {\n listeners.push(\n alepha.events.on(\"form:submit:begin\", (event) => {\n if (event.id === form.id) {\n setLoading(true);\n }\n }),\n alepha.events.on(\"form:submit:end\", (event) => {\n if (event.id === form.id) {\n setLoading(false);\n }\n }),\n );\n }\n\n if (hasValues || hasDirty) {\n listeners.push(\n alepha.events.on(\"form:submit:success\", (event) => {\n if (event.id === form.id) {\n if (hasValues) {\n setValues(event.values);\n }\n if (hasDirty) {\n setDirty(false);\n }\n }\n }),\n );\n }\n\n if (hasDirty) {\n listeners.push(\n alepha.events.on(\"form:reset\", (event) => {\n if (event.id === form.id) {\n setDirty(false);\n }\n }),\n );\n }\n\n if (hasErrors) {\n listeners.push(\n alepha.events.on(\"form:submit:error\", (event) => {\n if (event.id === form.id) {\n if (\n !path ||\n (event.error instanceof TypeBoxError &&\n event.error.value.path === path)\n ) {\n setError(event.error);\n }\n }\n }),\n );\n }\n\n return () => {\n for (const unsub of listeners) {\n unsub();\n }\n };\n }, []);\n\n return {\n dirty,\n loading,\n error,\n values,\n } as Pick<UseFormStateReturn, Keys>;\n};\n","import type { TObject } from \"alepha\";\nimport type { ReactNode } from \"react\";\nimport { useFormState } from \"../hooks/useFormState.ts\";\nimport type { FormModel } from \"../services/FormModel.ts\";\n\nconst FormState = <T extends TObject>(props: {\n form: FormModel<T>;\n children: (state: { loading: boolean; dirty: boolean }) => ReactNode;\n}) => {\n const formState = useFormState(props.form);\n return props.children({\n loading: formState.loading,\n dirty: formState.dirty,\n });\n};\n\nexport default FormState;\n","import { TypeBoxError } from \"alepha\";\n\nexport class FormValidationError extends TypeBoxError {\n readonly name = \"ValidationError\";\n\n constructor(options: {\n message: string;\n path: string;\n }) {\n super({\n message: options.message,\n instancePath: options.path,\n schemaPath: \"\",\n keyword: \"not\",\n params: {},\n });\n }\n}\n","import { useAlepha } from \"alepha/react\";\nimport { useEffect, useState } from \"react\";\nimport type { BaseInputField } from \"../services/FormModel.ts\";\n\n/**\n * Hook to subscribe to a single form field's value.\n * Only re-renders when this specific field changes.\n *\n * @returns A tuple of [value, setValue] similar to useState.\n */\nexport const useFieldValue = (\n input: BaseInputField,\n): [any, (value: any) => void] => {\n const alepha = useAlepha();\n const [value, setValue] = useState(input?.initialValue);\n\n useEffect(() => {\n if (!input?.form || !alepha.isBrowser()) {\n return;\n }\n\n return alepha.events.on(\"form:change\", (ev) => {\n if (ev.id === input.form.id && ev.path === input.path) {\n setValue(ev.value);\n }\n });\n }, []);\n\n const setFieldValue = (newValue: any) => {\n input.set(newValue);\n };\n\n return [value, setFieldValue];\n};\n","import type { TArray } from \"alepha\";\nimport {\n $inject,\n Alepha,\n type Static,\n type TObject,\n type TSchema,\n t,\n} from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport type { InputHTMLAttributes } from \"react\";\n\n/**\n * FormModel is a dynamic form handler that generates form inputs based on a provided TypeBox schema.\n * It manages form state, handles input changes, and processes form submissions with validation.\n *\n * It means to be injected and used within React components to provide a structured way to create and manage forms.\n *\n * @see {@link useForm}\n */\nexport class FormModel<T extends TObject> {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n protected readonly values: Record<string, any> = {};\n protected readonly initialValues: Record<string, any> = {};\n protected submitInProgress = false;\n\n public input: SchemaToInput<T>;\n\n public get submitting(): boolean {\n return this.submitInProgress;\n }\n\n constructor(\n public readonly id: string,\n public readonly options: FormCtrlOptions<T>,\n ) {\n this.options = options;\n\n // Initialize with schema defaults first, then override with initialValues\n const schemaDefaults = this.extractSchemaDefaults(options.schema);\n if (Object.keys(schemaDefaults).length > 0) {\n Object.assign(this.values, schemaDefaults);\n }\n\n if (options.initialValues) {\n // Decode against a partial of the schema so callers can supply incomplete\n // initial values (the form's whole job is to collect them). Codecs still\n // run on whatever's provided; missing fields stay undefined and only the\n // full schema is enforced at submit time.\n const decoded = this.alepha.codec.decode(\n t.partial(options.schema),\n options.initialValues,\n ) as Record<string, any>;\n Object.assign(this.values, decoded);\n }\n\n this.initialValues = { ...this.values };\n\n this.input = this.createProxyFromSchema(options, options.schema, {\n store: this.values,\n parent: \"\",\n });\n }\n\n /**\n * Extract default values from a TypeBox schema.\n * Recursively handles nested objects.\n */\n protected extractSchemaDefaults(\n schema: TObject,\n prefix: string = \"\",\n ): Record<string, any> {\n const defaults: Record<string, any> = {};\n\n if (!schema.properties) {\n return defaults;\n }\n\n for (const [key, propSchema] of Object.entries(schema.properties)) {\n const fullKey = prefix ? `${prefix}.${key}` : key;\n\n if (\"default\" in propSchema && propSchema.default !== undefined) {\n defaults[fullKey] = propSchema.default;\n } else if (\n propSchema &&\n \"type\" in propSchema &&\n propSchema.type === \"object\" &&\n \"properties\" in propSchema\n ) {\n // Recursively extract defaults from nested objects\n const nestedDefaults = this.extractSchemaDefaults(\n propSchema as TObject,\n fullKey,\n );\n Object.assign(defaults, nestedDefaults);\n }\n }\n\n return defaults;\n }\n\n public get currentValues(): Record<string, any> {\n return this.restructureValues(this.values);\n }\n\n public get props() {\n return {\n id: this.id,\n noValidate: true,\n onSubmit: (ev?: FormEventLike) => {\n ev?.preventDefault?.();\n this.submit();\n },\n onReset: (event: FormEventLike) => this.reset(event),\n };\n }\n\n public readonly setInitialValues = (values: Record<string, any>) => {\n // Same partial-decode rationale as the constructor — initial values may be\n // incomplete; full schema is enforced only at submit time.\n const decoded = this.alepha.codec.decode(\n t.partial(this.options.schema),\n values,\n ) as Record<string, any>;\n\n // Snapshot the OLD keys before we wipe — without this, fields that\n // had a value but are absent from the new initialValues never emit\n // form:change and useFieldValue subscribers keep showing the stale\n // value. Mirrors the union-of-keys pattern in reset() below.\n const oldKeys = new Set(Object.keys(this.values));\n\n for (const key in this.initialValues) {\n delete (this.initialValues as Record<string, any>)[key];\n }\n Object.assign(this.initialValues, decoded);\n\n for (const key in this.values) {\n delete this.values[key];\n }\n Object.assign(this.values, { ...this.initialValues });\n\n const keys = new Set<string>([...oldKeys, ...Object.keys(this.values)]);\n for (const key of keys) {\n const path = `/${key.replaceAll(\".\", \"/\")}`;\n this.alepha.events.emit(\n \"form:change\",\n { id: this.id, path, value: this.values[key], initial: true },\n { catch: true },\n );\n }\n };\n\n public readonly reset = (event?: FormEventLike) => {\n event?.preventDefault?.();\n // Snapshot all keys that need notification — both keys present\n // before reset (so subscribers learn the cleared value) and keys\n // restored from initialValues. Without the union, fields that were\n // typed but absent from initialValues stay visually stale.\n const keys = new Set<string>([\n ...Object.keys(this.values),\n ...Object.keys(this.initialValues),\n ]);\n for (const key in this.values) {\n delete this.values[key];\n }\n Object.assign(this.values, { ...this.initialValues });\n for (const key of keys) {\n const path = `/${key.replaceAll(\".\", \"/\")}`;\n this.alepha.events.emit(\n \"form:change\",\n { id: this.id, path, value: this.values[key] },\n { catch: true },\n );\n }\n this.alepha.events.emit(\"form:reset\", { id: this.id }, { catch: true });\n this.options.onReset?.();\n };\n\n public readonly submit = async () => {\n if (this.submitInProgress) {\n this.log.warn(\n \"Form submission already in progress, ignoring duplicate submit.\",\n );\n return;\n }\n\n // emit both action and form events\n await this.alepha.events.emit(\"react:action:begin\", {\n type: \"form\",\n id: this.id,\n });\n await this.alepha.events.emit(\"form:submit:begin\", {\n id: this.id,\n });\n\n this.submitInProgress = true;\n\n const options = this.options;\n\n try {\n let values: Record<string, any> = this.restructureValues(this.values);\n\n if (t.schema.isSchema(options.schema)) {\n values = this.alepha.codec.decode(options.schema, values) as Record<\n string,\n any\n >;\n }\n\n await options.handler(values as any);\n\n await this.alepha.events.emit(\"react:action:success\", {\n type: \"form\",\n id: this.id,\n });\n await this.alepha.events.emit(\"form:submit:success\", {\n id: this.id,\n values,\n });\n } catch (error) {\n this.log.error(\"Form submission error:\", error);\n\n options.onError?.(error as Error);\n\n await this.alepha.events.emit(\"react:action:error\", {\n type: \"form\",\n id: this.id,\n error: error as Error,\n });\n await this.alepha.events.emit(\"form:submit:error\", {\n error: error as Error,\n id: this.id,\n });\n } finally {\n this.submitInProgress = false;\n }\n\n await this.alepha.events.emit(\"react:action:end\", {\n type: \"form\",\n id: this.id,\n });\n await this.alepha.events.emit(\"form:submit:end\", {\n id: this.id,\n });\n };\n\n /**\n * Restructures flat keys like \"address.city\" into nested objects like { address: { city: ... } }\n * Values are already typed from onChange, so no conversion is needed.\n */\n protected restructureValues(store: Record<string, any>): Record<string, any> {\n const values: Record<string, any> = {};\n\n for (const [key, value] of Object.entries(store)) {\n if (key.includes(\".\")) {\n // nested object: restructure flat key to nested structure\n this.restructureNestedValue(values, key, value);\n } else {\n // value is already typed, just copy it\n values[key] = value;\n }\n }\n\n return values;\n }\n\n /**\n * Helper to restructure a flat key like \"address.city\" into nested object structure.\n * The value is already typed, so we just assign it to the nested path.\n */\n protected restructureNestedValue(\n values: Record<string, any>,\n key: string,\n value: any,\n ) {\n const pathSegments = key.split(\".\");\n const finalPropertyKey = pathSegments.pop();\n if (!finalPropertyKey) {\n return;\n }\n\n let currentObjectLevel = values;\n\n // traverse/create the nested structure\n for (const segment of pathSegments) {\n currentObjectLevel[segment] ??= {};\n currentObjectLevel = currentObjectLevel[segment];\n }\n\n // value is already typed from onChange, just assign it\n currentObjectLevel[finalPropertyKey] = value;\n }\n\n protected createProxyFromSchema<T extends TObject>(\n options: FormCtrlOptions<T>,\n schema: TSchema,\n context: {\n parent: string;\n store: Record<string, any>;\n },\n ): SchemaToInput<T> {\n const parent = context.parent || \"\";\n return new Proxy<SchemaToInput<T>>({} as SchemaToInput<T>, {\n get: (_, prop: string) => {\n if (!options.schema || !t.schema.isObject(schema)) {\n return {};\n }\n\n if (prop in schema.properties) {\n // // it's a nested object, create another proxy\n // if (t.schema.isObject(schema.properties[prop])) {\n // return this.createProxyFromSchema(\n // options,\n // schema.properties[prop],\n // {\n // parent: parent ? `${parent}.${prop}` : prop,\n // store: context.store,\n // },\n // );\n // }\n\n return this.createInputFromSchema<T>(\n prop as keyof Static<T> & string,\n options,\n schema,\n schema.required?.includes(prop as string) || false,\n context,\n );\n }\n },\n });\n }\n\n protected createInputFromSchema<T extends TObject>(\n name: keyof Static<T> & string,\n options: FormCtrlOptions<T>,\n schema: TObject,\n required: boolean,\n context: {\n parent: string;\n store: Record<string, any>;\n },\n ): BaseInputField {\n const parent = context.parent || \"\";\n const field = schema.properties?.[name];\n if (!field) {\n return {\n path: \"\",\n required,\n initialValue: undefined,\n props: {} as InputHTMLAttributes<unknown>,\n schema: schema,\n set: () => {},\n form: this,\n };\n }\n\n const isRequired = schema.required?.includes(name) ?? false;\n const key = parent ? `${parent}.${name}` : name;\n const path = `/${key.replaceAll(\".\", \"/\")}`;\n\n const set = (value: any) => {\n const typedValue = this.getValueFromInput(value, field);\n context.store[key] = typedValue;\n if (options.onChange) {\n options.onChange(key, typedValue, context.store);\n }\n this.alepha.events.emit(\n \"form:change\",\n { id: this.id, path: path, value: typedValue },\n { catch: true },\n );\n };\n\n const attr: InputHTMLAttributesLike = {\n name: key,\n };\n\n // Use the form's runtime id (always set — comes from `useId()` when\n // no explicit `options.id` was provided). This guarantees stable\n // per-field DOM ids without forcing callers to pass `id`.\n attr.id = `${this.id}-${key}`;\n (attr as any)[\"data-testid\"] = attr.id;\n\n if (t.schema.isString(field)) {\n if (field.maxLength != null) {\n attr.maxLength = Number(field.maxLength);\n }\n\n if (field.minLength != null) {\n attr.minLength = Number(field.minLength);\n }\n }\n\n if (isRequired) {\n attr.required = true;\n }\n\n if (\"description\" in field && typeof field.description === \"string\") {\n attr[\"aria-label\"] = field.description;\n }\n\n if (t.schema.isInteger(field) || t.schema.isNumber(field)) {\n attr.type = \"number\";\n } else if (name === \"password\") {\n attr.type = \"password\";\n } else if (name === \"email\") {\n attr.type = \"email\";\n } else if (name === \"url\") {\n attr.type = \"url\";\n } else if (t.schema.isString(field)) {\n if (field.format === \"binary\") {\n attr.type = \"file\";\n } else if (field.format === \"date\") {\n attr.type = \"date\";\n } else if (field.format === \"time\") {\n attr.type = \"time\";\n } else if (field.format === \"date-time\") {\n attr.type = \"datetime-local\";\n } else {\n attr.type = \"text\";\n }\n } else if (t.schema.isBoolean(field)) {\n attr.type = \"checkbox\";\n }\n\n if (options.onCreateField) {\n const customAttr = options.onCreateField(name, field);\n Object.assign(attr, customAttr);\n }\n\n // if type = object, add items: { [key: string]: InputField }\n if (t.schema.isObject(field)) {\n return {\n path,\n props: attr,\n schema: field,\n set,\n form: this,\n required,\n initialValue: context.store[key],\n items: this.createProxyFromSchema(options, field, {\n parent: key,\n store: context.store,\n }),\n } as ObjectInputField<any>;\n }\n\n // if type = array, add items: InputField[]\n if (t.schema.isArray(field)) {\n return {\n path,\n props: attr,\n schema: field,\n set,\n form: this,\n required,\n initialValue: context.store[key],\n items: [], // <- will be populated dynamically in the UI\n } as ArrayInputField<any>;\n }\n\n return {\n path,\n props: attr,\n schema: field,\n set,\n form: this,\n required,\n initialValue: context.store[key],\n };\n }\n\n /**\n * Convert an input value to the correct type based on the schema.\n * Handles raw DOM values (strings, booleans from checkboxes, Files, etc.)\n */\n protected getValueFromInput(input: any, schema: TSchema): any {\n // Treat null/undefined as \"unset\" for every schema. Without this the\n // string branch below stringifies them to \"null\"/\"undefined\" (and\n // the date branches throw on `new Date(undefined)`), which then\n // round-trips into controlled inputs as literal text — most\n // visible after the Clear (X) affordance in Control sets\n // value=undefined and the input promptly displays \"undefined\".\n if (input === null || input === undefined) {\n return undefined;\n }\n if (input instanceof File) {\n // for file inputs, return the File object directly\n if (t.schema.isString(schema) && schema.format === \"binary\") {\n return input;\n }\n // for now, ignore other formats\n return null;\n }\n\n if (t.schema.isBoolean(schema)) {\n // Handle string representations from Select components (Yes/No dropdown)\n if (input === \"true\") return true;\n if (input === \"false\") return false;\n if (input === \"\" || input === null || input === undefined)\n return undefined;\n // Handle actual boolean values\n return !!input;\n }\n\n if (t.schema.isNumber(schema)) {\n const num = Number(input);\n return Number.isNaN(num) ? null : num;\n }\n\n if (t.schema.isString(schema)) {\n if (schema.format === \"date\") {\n return new Date(input).toISOString().slice(0, 10); // For date input\n }\n if (schema.format === \"time\") {\n return new Date(`1970-01-01T${input}`).toISOString().slice(11, 16); // For time input\n }\n if (schema.format === \"date-time\") {\n return new Date(input).toISOString(); // For datetime-local input\n }\n return String(input);\n }\n\n return input; // fallback for other types\n }\n}\n\nexport type SchemaToInput<T extends TObject> = {\n [K in keyof T[\"properties\"]]: InputField<T[\"properties\"][K]>;\n};\n\nexport interface FormEventLike {\n preventDefault?: () => void;\n stopPropagation?: () => void;\n}\n\nexport type InputField<T extends TSchema> = T extends TObject\n ? ObjectInputField<T>\n : T extends TArray<infer U>\n ? ArrayInputField<U>\n : BaseInputField;\n\nexport interface BaseInputField {\n path: string;\n required: boolean;\n initialValue: any;\n props: InputHTMLAttributesLike;\n schema: TSchema;\n set: (value: any) => void;\n form: FormModel<any>;\n items?: any;\n}\n\nexport interface ObjectInputField<T extends TObject> extends BaseInputField {\n items: SchemaToInput<T>;\n}\n\nexport interface ArrayInputField<T extends TSchema> extends BaseInputField {\n items: Array<InputField<T>>;\n}\n\nexport type InputHTMLAttributesLike = Pick<\n InputHTMLAttributes<unknown>,\n | \"id\"\n | \"name\"\n | \"type\"\n | \"value\"\n | \"required\"\n | \"maxLength\"\n | \"minLength\"\n | \"aria-label\"\n> & {\n value?: any;\n};\n\nexport type FormCtrlOptions<T extends TObject> = {\n /**\n * The schema defining the structure and validation rules for the form.\n * This should be a TypeBox schema object.\n */\n schema: T;\n\n /**\n * Callback function to handle form submission.\n * This function will receive the parsed and validated form values.\n */\n handler: (values: Static<T>) => unknown;\n\n /**\n * Optional initial values for the form fields.\n * This can be used to pre-populate the form with existing data.\n */\n initialValues?: Partial<Static<T>>;\n\n /**\n * Optional function to create custom field attributes.\n * This can be used to add custom validation, styles, or other attributes.\n */\n onCreateField?: (\n name: keyof Static<T> & string,\n schema: TSchema,\n ) => InputHTMLAttributes<unknown>;\n\n /**\n * If defined, this will generate a unique ID for each field, prefixed with this string.\n *\n * > \"username\" with id=\"form-123\" will become \"form-123-username\".\n *\n * If omitted, IDs will not be generated.\n */\n id?: string;\n\n onError?: (error: Error) => void;\n\n onChange?: (key: string, value: any, store: Record<string, any>) => void;\n\n onReset?: () => void;\n};\n","import type { TObject } from \"alepha\";\nimport { useAlepha } from \"alepha/react\";\nimport { useEffect, useId, useMemo, useRef } from \"react\";\nimport { type FormCtrlOptions, FormModel } from \"../services/FormModel.ts\";\n\n/**\n * Custom hook to create a form with validation and field management.\n * This hook uses TypeBox schemas to define the structure and validation rules for the form.\n * It provides a way to handle form submission, field creation, and value management.\n *\n * @example\n * ```tsx\n * import { t } from \"alepha\";\n *\n * const form = useForm({\n * schema: t.object({\n * username: t.text(),\n * password: t.text(),\n * }),\n * handler: (values) => {\n * console.log(\"Form submitted with values:\", values);\n * },\n * });\n *\n * return (\n * <form {...form.props}>\n * <input {...form.input.username.props} />\n * <input {...form.input.password.props} />\n * <button type=\"submit\">Submit</button>\n * </form>\n * );\n * ```\n */\n/**\n * Shallow / structural equality for form initial-value objects. Form values\n * are plain data (strings, numbers, arrays, plain objects) so JSON.stringify\n * is both fast enough and exact. Wrapped in try/catch to fall back to\n * reference equality if anything exotic sneaks in (e.g. circular refs).\n */\nconst stableEqual = (a: unknown, b: unknown): boolean => {\n if (a === b) return true;\n if (a == null || b == null) return false;\n try {\n return JSON.stringify(a) === JSON.stringify(b);\n } catch {\n return false;\n }\n};\n\nexport const useForm = <T extends TObject>(\n options: FormCtrlOptions<T>,\n deps: any[] = [],\n): FormModel<T> => {\n const alepha = useAlepha();\n const formId = useId();\n const initialValuesRef = useRef(options.initialValues);\n\n const form = useMemo(() => {\n return alepha.inject(FormModel<T>, {\n lifetime: \"transient\",\n args: [options.id || formId, options],\n });\n }, deps);\n\n useEffect(() => {\n // Reference inequality alone is unsafe: callers commonly build the\n // `initialValues` object inline at the top of their render, which yields\n // a fresh reference every commit. Reinitializing on every render wipes\n // user-typed values via `setInitialValues` while leaving the DOM stale,\n // producing the \"I filled the form but submit says it's empty\" bug.\n //\n // Deep-equality (JSON-compare) catches the common case where the inline\n // literal is rebuilt with the same content. Callers who legitimately\n // need to swap initial values mid-edit (e.g. editing quest A → quest B)\n // still see a different JSON shape and trigger the reinit.\n if (stableEqual(initialValuesRef.current, options.initialValues)) {\n return;\n }\n initialValuesRef.current = options.initialValues;\n if (options.initialValues) {\n form.setInitialValues(options.initialValues as Record<string, any>);\n }\n }, [options.initialValues]);\n\n return form;\n};\n","import type { TObject } from \"alepha\";\nimport { useAlepha } from \"alepha/react\";\nimport { useRouter, useRouterState } from \"alepha/react/router\";\nimport { useEffect, useRef } from \"react\";\nimport type { FormModel } from \"../services/FormModel.ts\";\n\nexport interface UseFormQuerySyncOptions<TKey extends string> {\n /**\n * Form field keys to mirror to/from the URL query. Fields not listed\n * here stay local to the form and never leak into the address bar.\n */\n keys: readonly TKey[];\n}\n\n/**\n * Two-way bind a `useForm` instance to the URL query params, keyed\n * per-field (so the URL stays human-readable: `?status=new&zone=ops`).\n *\n * Direction 1 — URL → form:\n * - On mount AND every time one of the watched query keys changes\n * (typically via browser back/forward or external `router.push`),\n * call `form.input[key].set(value)` for each listed key. Missing /\n * empty params clear the field (set to `undefined`).\n *\n * Direction 2 — form → URL:\n * - Subscribe to the form's `form:change` event for the listed keys.\n * Each emission writes the current values for all listed keys to the\n * URL via `router.setQueryParams` (replace-state, no history spam).\n * Empty values (`undefined` / `\"\"`) are stripped from the URL so the\n * address bar stays clean.\n *\n * Replaces ad-hoc `localStorage` filter persistence: the URL becomes\n * the canonical store, so the view is shareable via copy-paste and\n * navigable via back/forward.\n *\n * @example\n * const form = useForm({ schema: t.object({ status: t.string(), q: t.string() }) });\n * useFormQuerySync(form, { keys: [\"status\", \"q\"] });\n */\nexport const useFormQuerySync = <T extends TObject, TKey extends string>(\n form: FormModel<T>,\n options: UseFormQuerySyncOptions<TKey>,\n): void => {\n const alepha = useAlepha();\n const router = useRouter();\n const state = useRouterState();\n const keys = options.keys;\n\n // URL → form. Recompute a stable signature of the watched slice of\n // router.query so the effect fires precisely when it changes.\n const querySig = keys\n .map((k) => {\n const raw = state.query?.[k];\n return typeof raw === \"string\" ? raw : \"\";\n })\n .join(\"\u0000\");\n\n // First-mount semantics differ from later URL changes: when the URL\n // is empty AND the form has an initial value (e.g. status: \"new\"),\n // preserve that initial value — and write it back to the URL so the\n // URL becomes the source of truth from then on. Without this guard\n // the mount would clear the form's defaults, defeating the whole\n // \"default lane\" pattern.\n const initialized = useRef(false);\n useEffect(() => {\n const isFirstRun = !initialized.current;\n initialized.current = true;\n const values = (form as unknown as { currentValues: Record<string, any> })\n .currentValues;\n const missingInitials: Record<string, string> = {};\n for (const key of keys) {\n const raw = state.query?.[key];\n const next = typeof raw === \"string\" && raw !== \"\" ? raw : undefined;\n const current = values[key];\n if (\n isFirstRun &&\n next === undefined &&\n current != null &&\n current !== \"\"\n ) {\n // URL missing this key on first mount but the form has a\n // default — keep the default, queue it to be written below.\n missingInitials[key] = String(current);\n continue;\n }\n // Skip when already in sync — avoids bouncing form:change ↔\n // setQueryParams and re-triggering subscribers.\n if ((current ?? undefined) !== next) {\n const input = (form.input as Record<string, any>)[key];\n if (input && typeof input.set === \"function\") {\n input.set(next);\n }\n }\n }\n if (isFirstRun && Object.keys(missingInitials).length > 0) {\n // Merge with whatever URL params ARE present so we don't clobber\n // unrelated keys the page also uses.\n const merged: Record<string, string> = {};\n for (const key of keys) {\n const raw = state.query?.[key];\n if (typeof raw === \"string\" && raw !== \"\") {\n merged[key] = raw;\n }\n }\n for (const [k, v] of Object.entries(missingInitials)) {\n merged[k] = v;\n }\n router.setQueryParams(merged);\n }\n // querySig is the meaningful trigger; form/keys/router are stable.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [querySig]);\n\n // form → URL. Listen for changes on the watched keys only.\n useEffect(() => {\n if (!alepha.isBrowser()) return;\n const off = alepha.events.on(\"form:change\", (e: any) => {\n if (e.id !== form.id) return;\n if (!keys.includes(e.path)) return;\n const next: Record<string, string> = {};\n const values = (form as unknown as { currentValues: Record<string, any> })\n .currentValues;\n for (const key of keys) {\n const value = values[key];\n if (value != null && value !== \"\") {\n next[key] = String(value);\n }\n }\n // Replace-state (default) — filters shouldn't pollute history.\n router.setQueryParams(next);\n });\n return off;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [alepha, form, router]);\n};\n","import type { TObject } from \"alepha\";\nimport { useAlepha } from \"alepha/react\";\nimport { useEffect, useState } from \"react\";\nimport type { FormModel } from \"../services/FormModel.ts\";\n\n/**\n * Hook to subscribe to all form values.\n * Re-renders on every field change — use only when needed (debug panels, live previews).\n */\nexport const useFormValues = <T extends TObject>(\n form: FormModel<T>,\n): Record<string, any> => {\n const alepha = useAlepha();\n const [values, setValues] = useState<Record<string, any>>(form.currentValues);\n\n useEffect(() => {\n if (!alepha.isBrowser()) {\n return;\n }\n\n return alepha.events.on(\"form:change\", (ev) => {\n if (ev.id === form.id) {\n setValues(form.currentValues);\n }\n });\n }, []);\n\n return values;\n};\n","/**\n * Converts a path or identifier string into a pretty display name.\n * For paths like \"/contacts/0/name\", extracts just the field name \"Name\".\n * Handles camelCase and snake_case conversion to Title Case.\n *\n * @example\n * prettyName(\"/userName\") // \"User Name\"\n * prettyName(\"/contacts/0/email\") // \"Email\"\n * prettyName(\"/address/streetName\") // \"Street Name\"\n * prettyName(\"first_name\") // \"First Name\"\n */\nexport const prettyName = (name: string): string => {\n const segments = name.split(\"/\").filter((s) => s && !/^\\d+$/.test(s));\n const fieldName = segments[segments.length - 1] || name.replaceAll(\"/\", \"\");\n return fieldName\n .replace(/([a-z])([A-Z])/g, \"$1 $2\")\n .replace(/_/g, \" \")\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n};\n","import { type TSchema, TypeBoxError } from \"alepha\";\nimport type { BaseInputField } from \"./FormModel.ts\";\nimport { prettyName } from \"./prettyName.ts\";\n\n/**\n * Semantic icon hint derived from schema metadata. UI layers map this\n * to their own icon set — this module is headless and ships no JSX.\n */\nexport type IconHint =\n | \"email\"\n | \"password\"\n | \"phone\"\n | \"url\"\n | \"number\"\n | \"calendar\"\n | \"clock\"\n | \"list\"\n | \"text\"\n | \"user\"\n | \"file\"\n | \"switch\";\n\nexport interface FieldConstraints {\n minLength?: number;\n maxLength?: number;\n minimum?: number;\n maximum?: number;\n pattern?: string;\n}\n\nexport interface FieldMeta {\n id?: string;\n label: string;\n description?: string;\n error?: string;\n required: boolean;\n type?: string;\n format?: string;\n isEnum: boolean;\n isArray: boolean;\n isObject: boolean;\n isArrayOfObjects: boolean;\n enum?: readonly unknown[];\n iconHint?: IconHint;\n constraints: FieldConstraints;\n testId?: string;\n schema: TSchema;\n /**\n * Raw `$control` value from the schema, untyped here. The UI layer\n * (`alepha/react/ui`) provides the strict {@link SchemaControl} type and\n * a `resolveSchemaControl` helper to evaluate the function form.\n */\n control?: unknown;\n}\n\nexport interface ParseFieldOptions {\n label?: string;\n description?: string;\n error?: Error;\n}\n\n/**\n * Derives a {@link FieldMeta} from an `InputField` (from `useForm`) plus\n * optional overrides. Pure — no React, no JSX, no UI library coupling.\n *\n * UI components consume this metadata to render labels, descriptions,\n * error messages, icons, and validation constraints.\n */\nexport const parseField = (\n input: BaseInputField,\n options: ParseFieldOptions = {},\n): FieldMeta => {\n const schema = input.schema as TSchema & {\n type?: string;\n format?: string;\n title?: string;\n description?: string;\n enum?: readonly unknown[];\n minLength?: number;\n maxLength?: number;\n minimum?: number;\n maximum?: number;\n pattern?: string;\n properties?: unknown;\n items?: { properties?: unknown };\n $control?: unknown;\n };\n\n const label =\n options.label ??\n (typeof schema.title === \"string\" ? schema.title : undefined) ??\n prettyName(input.path);\n\n const description =\n options.description ??\n (typeof schema.description === \"string\" ? schema.description : undefined);\n\n const error =\n options.error instanceof TypeBoxError\n ? (options.error as TypeBoxError).value?.message\n : undefined;\n\n const type = schema.type;\n const format = typeof schema.format === \"string\" ? schema.format : undefined;\n const isEnum = Array.isArray(schema.enum);\n const isArray = type === \"array\";\n const isObject = type === \"object\" && Boolean(schema.properties);\n const isArrayOfObjects =\n isArray && Boolean(schema.items && (schema.items as any).properties);\n\n const name = input.props.name;\n const iconHint = inferIconHint({ type, format, name, isEnum, isArray });\n\n const constraints: FieldConstraints = {};\n if (typeof schema.minLength === \"number\")\n constraints.minLength = schema.minLength;\n if (typeof schema.maxLength === \"number\")\n constraints.maxLength = schema.maxLength;\n if (typeof schema.minimum === \"number\") constraints.minimum = schema.minimum;\n if (typeof schema.maximum === \"number\") constraints.maximum = schema.maximum;\n if (typeof schema.pattern === \"string\") constraints.pattern = schema.pattern;\n\n return {\n id: input.props.id,\n label,\n description,\n error,\n required: input.required,\n type,\n format,\n isEnum,\n isArray,\n isObject,\n isArrayOfObjects,\n enum: schema.enum,\n iconHint,\n constraints,\n testId: (input.props as Record<string, unknown>)[\"data-testid\"] as\n | string\n | undefined,\n schema: input.schema,\n control: schema.$control,\n };\n};\n\nconst inferIconHint = (params: {\n type?: string;\n format?: string;\n name?: string;\n isEnum: boolean;\n isArray: boolean;\n}): IconHint | undefined => {\n const { type, format, name, isEnum, isArray } = params;\n\n if (format === \"email\") return \"email\";\n if (format === \"url\" || format === \"uri\") return \"url\";\n if (format === \"tel\" || format === \"phone\") return \"phone\";\n if (format === \"date\" || format === \"date-time\") return \"calendar\";\n if (format === \"time\") return \"clock\";\n\n if (name?.toLowerCase().includes(\"password\")) return \"password\";\n if (name?.toLowerCase().includes(\"email\")) return \"email\";\n if (name?.toLowerCase().includes(\"phone\")) return \"phone\";\n\n if (type === \"boolean\") return \"switch\";\n if (type === \"number\" || type === \"integer\") return \"number\";\n if (isEnum || isArray) return \"list\";\n if (type === \"string\") return \"text\";\n\n return undefined;\n};\n","import { $module } from \"alepha\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport { default as FormState } from \"./components/FormState.tsx\";\nexport * from \"./errors/FormValidationError.ts\";\nexport * from \"./hooks/useFieldValue.ts\";\nexport * from \"./hooks/useForm.ts\";\nexport * from \"./hooks/useFormQuerySync.ts\";\nexport * from \"./hooks/useFormState.ts\";\nexport * from \"./hooks/useFormValues.ts\";\nexport * from \"./services/FormModel.ts\";\nexport * from \"./services/parseField.ts\";\nexport * from \"./services/prettyName.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\ndeclare module \"alepha\" {\n interface Hooks {\n \"form:change\": {\n id: string;\n path: string;\n value: any;\n /**\n * Programmatic reset (e.g. `setInitialValues` after the parent updates\n * its state). Subscribers tracking dirty state should ignore these.\n */\n initial?: boolean;\n };\n \"form:submit:begin\": { id: string };\n \"form:submit:success\": { id: string; values: Record<string, any> };\n \"form:submit:error\": { id: string; error: Error };\n \"form:submit:end\": { id: string };\n \"form:reset\": { id: string };\n }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Type-safe forms with validation.\n *\n * **Features:**\n * - Form state management\n * - TypeBox schema validation\n * - Field-level error handling\n * - Submit handling with loading state\n * - Form reset\n *\n * @module alepha.react.form\n */\nexport const AlephaReactForm = $module({\n name: \"alepha.react.form\",\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/react/form/hooks/useFormState.ts","../../../src/react/form/components/FormState.tsx","../../../src/react/form/errors/FormValidationError.ts","../../../src/react/form/hooks/useFieldValue.ts","../../../src/react/form/services/FormModel.ts","../../../src/react/form/hooks/useForm.ts","../../../src/react/form/hooks/useFormQuerySync.ts","../../../src/react/form/hooks/useFormValues.ts","../../../src/react/form/services/prettyName.ts","../../../src/react/form/services/parseField.ts","../../../src/react/form/index.ts"],"sourcesContent":["import { type TObject, TypeBoxError } from \"alepha\";\nimport { useAlepha } from \"alepha/react\";\nimport { useEffect, useState } from \"react\";\nimport type { FormModel } from \"../services/FormModel.ts\";\n\nexport interface UseFormStateReturn {\n loading: boolean;\n dirty: boolean;\n values?: Record<string, any>;\n error?: Error;\n}\n\nexport const useFormState = <\n T extends TObject,\n Keys extends keyof UseFormStateReturn,\n>(\n target: FormModel<T> | { form: FormModel<T>; path: string },\n _events: Keys[] = [\"loading\", \"dirty\", \"error\"] as Keys[],\n): Pick<UseFormStateReturn, Keys> => {\n const alepha = useAlepha();\n const events = _events as string[];\n\n const [dirty, setDirty] = useState(false);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | undefined>(undefined);\n const [values, setValues] = useState<Record<string, any> | undefined>(\n undefined,\n );\n\n const form = \"form\" in target ? target.form : target;\n const path = \"path\" in target ? target.path : undefined;\n\n const hasValues = events.includes(\"values\");\n const hasErrors = events.includes(\"error\");\n const hasDirty = events.includes(\"dirty\");\n const hasLoading = events.includes(\"loading\");\n\n useEffect(() => {\n const listeners: Function[] = [];\n\n if (hasErrors || hasValues || hasDirty) {\n listeners.push(\n alepha.events.on(\"form:change\", (event) => {\n if (event.id === form.id) {\n if (!path || event.path === path) {\n // `initial: true` marks a programmatic reset (e.g. parent\n // re-rendering with fresh data via `setInitialValues`). Treat\n // it like a reset: clear dirty, don't mark dirty.\n if (hasDirty) {\n if (event.initial) {\n setDirty(false);\n } else {\n setDirty(true);\n }\n }\n if (hasErrors) {\n setError(undefined);\n }\n }\n if (hasValues) {\n setValues(form.currentValues);\n }\n }\n }),\n );\n }\n\n if (hasLoading) {\n listeners.push(\n alepha.events.on(\"form:submit:begin\", (event) => {\n if (event.id === form.id) {\n setLoading(true);\n }\n }),\n alepha.events.on(\"form:submit:end\", (event) => {\n if (event.id === form.id) {\n setLoading(false);\n }\n }),\n );\n }\n\n if (hasValues || hasDirty) {\n listeners.push(\n alepha.events.on(\"form:submit:success\", (event) => {\n if (event.id === form.id) {\n if (hasValues) {\n setValues(event.values);\n }\n if (hasDirty) {\n setDirty(false);\n }\n }\n }),\n );\n }\n\n if (hasDirty) {\n listeners.push(\n alepha.events.on(\"form:reset\", (event) => {\n if (event.id === form.id) {\n setDirty(false);\n }\n }),\n );\n }\n\n if (hasErrors) {\n listeners.push(\n alepha.events.on(\"form:submit:error\", (event) => {\n if (event.id === form.id) {\n if (\n !path ||\n (event.error instanceof TypeBoxError &&\n event.error.value.path === path)\n ) {\n setError(event.error);\n }\n }\n }),\n );\n }\n\n return () => {\n for (const unsub of listeners) {\n unsub();\n }\n };\n }, []);\n\n return {\n dirty,\n loading,\n error,\n values,\n } as Pick<UseFormStateReturn, Keys>;\n};\n","import type { TObject } from \"alepha\";\nimport type { ReactNode } from \"react\";\nimport { useFormState } from \"../hooks/useFormState.ts\";\nimport type { FormModel } from \"../services/FormModel.ts\";\n\nconst FormState = <T extends TObject>(props: {\n form: FormModel<T>;\n children: (state: { loading: boolean; dirty: boolean }) => ReactNode;\n}) => {\n const formState = useFormState(props.form);\n return props.children({\n loading: formState.loading,\n dirty: formState.dirty,\n });\n};\n\nexport default FormState;\n","import { TypeBoxError } from \"alepha\";\n\nexport class FormValidationError extends TypeBoxError {\n readonly name = \"ValidationError\";\n\n constructor(options: {\n message: string;\n path: string;\n }) {\n super({\n message: options.message,\n instancePath: options.path,\n params: {},\n });\n }\n}\n","import { useAlepha } from \"alepha/react\";\nimport { useEffect, useState } from \"react\";\nimport type { BaseInputField } from \"../services/FormModel.ts\";\n\n/**\n * Hook to subscribe to a single form field's value.\n * Only re-renders when this specific field changes.\n *\n * @returns A tuple of [value, setValue] similar to useState.\n */\nexport const useFieldValue = (\n input: BaseInputField,\n): [any, (value: any) => void] => {\n const alepha = useAlepha();\n const [value, setValue] = useState(input?.initialValue);\n\n useEffect(() => {\n if (!input?.form || !alepha.isBrowser()) {\n return;\n }\n\n return alepha.events.on(\"form:change\", (ev) => {\n if (ev.id === input.form.id && ev.path === input.path) {\n setValue(ev.value);\n }\n });\n }, []);\n\n const setFieldValue = (newValue: any) => {\n input.set(newValue);\n };\n\n return [value, setFieldValue];\n};\n","import type { TArray } from \"alepha\";\nimport {\n $inject,\n Alepha,\n coerceObject,\n type Static,\n type TObject,\n type TSchema,\n z,\n} from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport type { InputHTMLAttributes } from \"react\";\n\n/**\n * FormModel is a dynamic form handler that generates form inputs based on a provided TypeBox schema.\n * It manages form state, handles input changes, and processes form submissions with validation.\n *\n * It means to be injected and used within React components to provide a structured way to create and manage forms.\n *\n * @see {@link useForm}\n */\nexport class FormModel<T extends TObject> {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n protected readonly values: Record<string, any> = {};\n protected readonly initialValues: Record<string, any> = {};\n protected submitInProgress = false;\n\n public input: SchemaToInput<T>;\n\n constructor(\n public readonly id: string,\n public readonly options: FormCtrlOptions<T>,\n ) {\n this.options = options;\n\n // Initialize with schema defaults first, then override with initialValues\n const schemaDefaults = this.extractSchemaDefaults(options.schema);\n if (Object.keys(schemaDefaults).length > 0) {\n Object.assign(this.values, schemaDefaults);\n }\n\n if (options.initialValues) {\n // Decode against a partial of the schema so callers can supply incomplete\n // initial values (the form's whole job is to collect them). Codecs still\n // run on whatever's provided; missing fields stay undefined and only the\n // full schema is enforced at submit time.\n const decoded = this.alepha.codec.decode(\n options.schema.partial(),\n options.initialValues,\n ) as Record<string, any>;\n Object.assign(this.values, decoded);\n }\n\n this.initialValues = { ...this.values };\n\n this.input = this.createProxyFromSchema(options, options.schema, {\n store: this.values,\n parent: \"\",\n });\n }\n\n /**\n * Extract default values from a zod object schema.\n * Recursively handles nested objects, unwrapping optional/nullable/default.\n */\n protected extractSchemaDefaults(\n schema: TObject,\n prefix: string = \"\",\n ): Record<string, any> {\n const defaults: Record<string, any> = {};\n const shape = (schema as any).shape as Record<string, any> | undefined;\n\n if (!shape) {\n return defaults;\n }\n\n for (const [key, propSchema] of Object.entries(shape)) {\n const fullKey = prefix ? `${prefix}.${key}` : key;\n\n // Unwrap optional / nullable / default wrappers to surface a default\n // value and any nested object schema.\n let inner: any = propSchema;\n let defaultValue: unknown;\n while (inner) {\n if (z.schema.isDefault(inner)) {\n const dv = inner._zod.def.defaultValue;\n defaultValue = typeof dv === \"function\" ? dv() : dv;\n break;\n }\n if (z.schema.isOptional(inner) || z.schema.isNullable(inner)) {\n inner = inner.unwrap();\n continue;\n }\n break;\n }\n\n if (defaultValue !== undefined) {\n defaults[fullKey] = defaultValue;\n } else if (z.schema.isObject(inner)) {\n // Recursively extract defaults from nested objects\n Object.assign(\n defaults,\n this.extractSchemaDefaults(inner as TObject, fullKey),\n );\n }\n }\n\n return defaults;\n }\n\n public get currentValues(): Record<string, any> {\n return this.restructureValues(this.values);\n }\n\n public get props() {\n return {\n id: this.id,\n noValidate: true,\n onSubmit: (ev?: FormEventLike) => {\n ev?.preventDefault?.();\n this.submit();\n },\n onReset: (event: FormEventLike) => this.reset(event),\n };\n }\n\n public readonly setInitialValues = (values: Record<string, any>) => {\n // Same partial-decode rationale as the constructor — initial values may be\n // incomplete; full schema is enforced only at submit time.\n const decoded = this.alepha.codec.decode(\n this.options.schema.partial(),\n values,\n ) as Record<string, any>;\n\n // Snapshot the OLD keys before we wipe — without this, fields that\n // had a value but are absent from the new initialValues never emit\n // form:change and useFieldValue subscribers keep showing the stale\n // value. Mirrors the union-of-keys pattern in reset() below.\n const oldKeys = new Set(Object.keys(this.values));\n\n for (const key in this.initialValues) {\n delete (this.initialValues as Record<string, any>)[key];\n }\n Object.assign(this.initialValues, decoded);\n\n for (const key in this.values) {\n delete this.values[key];\n }\n Object.assign(this.values, { ...this.initialValues });\n\n const keys = new Set<string>([...oldKeys, ...Object.keys(this.values)]);\n for (const key of keys) {\n const path = `/${key.replaceAll(\".\", \"/\")}`;\n this.alepha.events.emit(\n \"form:change\",\n { id: this.id, path, value: this.values[key], initial: true },\n { catch: true },\n );\n }\n };\n\n public readonly reset = (event?: FormEventLike) => {\n event?.preventDefault?.();\n // Snapshot all keys that need notification — both keys present\n // before reset (so subscribers learn the cleared value) and keys\n // restored from initialValues. Without the union, fields that were\n // typed but absent from initialValues stay visually stale.\n const keys = new Set<string>([\n ...Object.keys(this.values),\n ...Object.keys(this.initialValues),\n ]);\n for (const key in this.values) {\n delete this.values[key];\n }\n Object.assign(this.values, { ...this.initialValues });\n for (const key of keys) {\n const path = `/${key.replaceAll(\".\", \"/\")}`;\n this.alepha.events.emit(\n \"form:change\",\n { id: this.id, path, value: this.values[key] },\n { catch: true },\n );\n }\n this.alepha.events.emit(\"form:reset\", { id: this.id }, { catch: true });\n this.options.onReset?.();\n };\n\n public readonly submit = async () => {\n if (this.submitInProgress) {\n this.log.warn(\n \"Form submission already in progress, ignoring duplicate submit.\",\n );\n return;\n }\n\n // Lifecycle events are best-effort NOTIFICATIONS (loading spinners, toasts,\n // analytics). A misbehaving listener must never break form state or reject\n // submit() — hence `{ catch: true }` on every emit below. Without it, a\n // throwing `react:action:error`/`form:submit:error` listener would skip the\n // `form:submit:end` \"loading off\" signal and leave submit buttons stuck in\n // their loading state forever.\n await this.alepha.events.emit(\n \"react:action:begin\",\n { type: \"form\", id: this.id },\n { catch: true },\n );\n await this.alepha.events.emit(\n \"form:submit:begin\",\n { id: this.id },\n { catch: true },\n );\n\n this.submitInProgress = true;\n\n const options = this.options;\n\n try {\n let values: Record<string, any> = this.restructureValues(this.values);\n\n if (z.schema.isSchema(options.schema)) {\n // HTML form controls produce strings; coerce them to the schema's\n // scalar types (number/boolean) at this string boundary before strict\n // decoding — otherwise a `z.number()` field would reject its \"42\" input.\n values = this.alepha.codec.decode(\n options.schema,\n coerceObject(options.schema, values),\n ) as Record<string, any>;\n }\n\n await options.handler(values as any);\n\n await this.alepha.events.emit(\n \"react:action:success\",\n { type: \"form\", id: this.id },\n { catch: true },\n );\n await this.alepha.events.emit(\n \"form:submit:success\",\n { id: this.id, values },\n { catch: true },\n );\n } catch (error) {\n this.log.error(\"Form submission error:\", error);\n\n // A throwing onError callback must not abort the lifecycle either.\n try {\n options.onError?.(error as Error);\n } catch (handlerError) {\n this.log.error(\"Form onError handler threw:\", handlerError);\n }\n\n await this.alepha.events.emit(\n \"react:action:error\",\n { type: \"form\", id: this.id, error: error as Error },\n { catch: true },\n );\n await this.alepha.events.emit(\n \"form:submit:error\",\n { error: error as Error, id: this.id },\n { catch: true },\n );\n } finally {\n this.submitInProgress = false;\n\n // The \"loading off\" signals live in `finally` so they ALWAYS fire,\n // even if something above threw — guaranteeing the begin/end pairing\n // that drives submit-button loading state.\n await this.alepha.events.emit(\n \"react:action:end\",\n { type: \"form\", id: this.id },\n { catch: true },\n );\n await this.alepha.events.emit(\n \"form:submit:end\",\n { id: this.id },\n { catch: true },\n );\n }\n };\n\n /**\n * Restructures flat keys like \"address.city\" into nested objects like { address: { city: ... } }\n * Values are already typed from onChange, so no conversion is needed.\n */\n protected restructureValues(store: Record<string, any>): Record<string, any> {\n const values: Record<string, any> = {};\n\n for (const [key, value] of Object.entries(store)) {\n if (key.includes(\".\")) {\n // nested object: restructure flat key to nested structure\n this.restructureNestedValue(values, key, value);\n } else {\n // value is already typed, just copy it\n values[key] = value;\n }\n }\n\n return values;\n }\n\n /**\n * Helper to restructure a flat key like \"address.city\" into nested object structure.\n * The value is already typed, so we just assign it to the nested path.\n */\n protected restructureNestedValue(\n values: Record<string, any>,\n key: string,\n value: any,\n ) {\n const pathSegments = key.split(\".\");\n const finalPropertyKey = pathSegments.pop();\n if (!finalPropertyKey) {\n return;\n }\n\n let currentObjectLevel = values;\n\n // traverse/create the nested structure\n for (const segment of pathSegments) {\n currentObjectLevel[segment] ??= {};\n currentObjectLevel = currentObjectLevel[segment];\n }\n\n // value is already typed from onChange, just assign it\n currentObjectLevel[finalPropertyKey] = value;\n }\n\n protected createProxyFromSchema<T extends TObject>(\n options: FormCtrlOptions<T>,\n schema: TSchema,\n context: {\n parent: string;\n store: Record<string, any>;\n },\n ): SchemaToInput<T> {\n const parent = context.parent || \"\";\n return new Proxy<SchemaToInput<T>>({} as SchemaToInput<T>, {\n get: (_, prop: string) => {\n if (!options.schema || !z.schema.isObject(schema)) {\n return {};\n }\n\n if (prop in schema.properties) {\n // // it's a nested object, create another proxy\n // if (z.schema.isObject(schema.properties[prop])) {\n // return this.createProxyFromSchema(\n // options,\n // schema.properties[prop],\n // {\n // parent: parent ? `${parent}.${prop}` : prop,\n // store: context.store,\n // },\n // );\n // }\n\n return this.createInputFromSchema<T>(\n prop as keyof Static<T> & string,\n options,\n schema,\n z.schema.requiredKeys(schema).includes(prop as string) || false,\n context,\n );\n }\n },\n });\n }\n\n protected createInputFromSchema<T extends TObject>(\n name: keyof Static<T> & string,\n options: FormCtrlOptions<T>,\n schema: TObject,\n required: boolean,\n context: {\n parent: string;\n store: Record<string, any>;\n },\n ): BaseInputField {\n const parent = context.parent || \"\";\n const rawField = schema.properties?.[name];\n if (!rawField) {\n return {\n path: \"\",\n required,\n initialValue: undefined,\n props: {} as InputHTMLAttributes<unknown>,\n schema: schema,\n set: () => {},\n form: this,\n };\n }\n // Peel optional/nullable/default wrappers so the structural guards below\n // (`isObject`/`isArray`/`isString`/…, `.maxLength`, format) see the real\n // schema. Optionality is tracked separately via `isRequired`/`required`.\n const field = z.schema.unwrap(rawField) as typeof rawField;\n\n const isRequired = z.schema.requiredKeys(schema).includes(name) ?? false;\n const key = parent ? `${parent}.${name}` : name;\n const path = `/${key.replaceAll(\".\", \"/\")}`;\n\n const set = (value: any) => {\n const typedValue = this.getValueFromInput(value, field);\n context.store[key] = typedValue;\n if (options.onChange) {\n options.onChange(key, typedValue, context.store);\n }\n this.alepha.events.emit(\n \"form:change\",\n { id: this.id, path: path, value: typedValue },\n { catch: true },\n );\n };\n\n const attr: InputHTMLAttributesLike = {\n name: key,\n };\n\n // Use the form's runtime id (always set — comes from `useId()` when\n // no explicit `options.id` was provided). This guarantees stable\n // per-field DOM ids without forcing callers to pass `id`.\n attr.id = `${this.id}-${key}`;\n (attr as any)[\"data-testid\"] = attr.id;\n\n if (z.schema.isString(field)) {\n if (field.maxLength != null) {\n attr.maxLength = Number(field.maxLength);\n }\n\n if (field.minLength != null) {\n attr.minLength = Number(field.minLength);\n }\n }\n\n if (isRequired) {\n attr.required = true;\n }\n\n if (\"description\" in field && typeof field.description === \"string\") {\n attr[\"aria-label\"] = field.description;\n }\n\n if (z.schema.isInteger(field) || z.schema.isNumber(field)) {\n attr.type = \"number\";\n } else if (name === \"password\") {\n attr.type = \"password\";\n } else if (name === \"email\") {\n attr.type = \"email\";\n } else if (name === \"url\") {\n attr.type = \"url\";\n } else if (z.schema.isString(field)) {\n if (z.schema.format(field) === \"binary\") {\n attr.type = \"file\";\n } else if (z.schema.format(field) === \"date\") {\n attr.type = \"date\";\n } else if (z.schema.format(field) === \"time\") {\n attr.type = \"time\";\n } else if (z.schema.format(field) === \"date-time\") {\n attr.type = \"datetime-local\";\n } else {\n attr.type = \"text\";\n }\n } else if (z.schema.isBoolean(field)) {\n attr.type = \"checkbox\";\n }\n\n if (options.onCreateField) {\n const customAttr = options.onCreateField(name, field);\n Object.assign(attr, customAttr);\n }\n\n // if type = object, add items: { [key: string]: InputField }\n if (z.schema.isObject(field)) {\n return {\n path,\n props: attr,\n schema: field,\n set,\n form: this,\n required,\n initialValue: context.store[key],\n items: this.createProxyFromSchema(options, field, {\n parent: key,\n store: context.store,\n }),\n } as ObjectInputField<any>;\n }\n\n // if type = array, add items: InputField[]\n if (z.schema.isArray(field)) {\n return {\n path,\n props: attr,\n schema: field,\n set,\n form: this,\n required,\n initialValue: context.store[key],\n items: [], // <- will be populated dynamically in the UI\n } as ArrayInputField<any>;\n }\n\n return {\n path,\n props: attr,\n schema: field,\n set,\n form: this,\n required,\n initialValue: context.store[key],\n };\n }\n\n /**\n * Convert an input value to the correct type based on the schema.\n * Handles raw DOM values (strings, booleans from checkboxes, Files, etc.)\n */\n protected getValueFromInput(input: any, schema: TSchema): any {\n // Treat null/undefined as \"unset\" for every schema. Without this the\n // string branch below stringifies them to \"null\"/\"undefined\" (and\n // the date branches throw on `new Date(undefined)`), which then\n // round-trips into controlled inputs as literal text — most\n // visible after the Clear (X) affordance in Control sets\n // value=undefined and the input promptly displays \"undefined\".\n if (input === null || input === undefined) {\n return undefined;\n }\n if (input instanceof File) {\n // for file inputs, return the File object directly\n if (z.schema.isString(schema) && z.schema.format(schema) === \"binary\") {\n return input;\n }\n // for now, ignore other formats\n return null;\n }\n\n if (z.schema.isBoolean(schema)) {\n // Handle string representations from Select components (Yes/No dropdown)\n if (input === \"true\") return true;\n if (input === \"false\") return false;\n if (input === \"\" || input === null || input === undefined)\n return undefined;\n // Handle actual boolean values\n return !!input;\n }\n\n if (z.schema.isNumber(schema)) {\n const num = Number(input);\n return Number.isNaN(num) ? null : num;\n }\n\n if (z.schema.isString(schema)) {\n if (z.schema.format(schema) === \"date\") {\n return new Date(input).toISOString().slice(0, 10); // For date input\n }\n if (z.schema.format(schema) === \"time\") {\n return new Date(`1970-01-01T${input}`).toISOString().slice(11, 16); // For time input\n }\n if (z.schema.format(schema) === \"date-time\") {\n return new Date(input).toISOString(); // For datetime-local input\n }\n return String(input);\n }\n\n return input; // fallback for other types\n }\n}\n\nexport type SchemaToInput<T extends TObject> = {\n [K in keyof T[\"properties\"]]: InputField<T[\"properties\"][K]>;\n};\n\nexport interface FormEventLike {\n preventDefault?: () => void;\n stopPropagation?: () => void;\n}\n\nexport type InputField<T extends TSchema> = T extends TObject\n ? ObjectInputField<T>\n : T extends TArray<infer U>\n ? ArrayInputField<U>\n : BaseInputField;\n\nexport interface BaseInputField {\n path: string;\n required: boolean;\n initialValue: any;\n props: InputHTMLAttributesLike;\n schema: TSchema;\n set: (value: any) => void;\n form: FormModel<any>;\n items?: any;\n}\n\nexport interface ObjectInputField<T extends TObject> extends BaseInputField {\n items: SchemaToInput<T>;\n}\n\nexport interface ArrayInputField<T extends TSchema> extends BaseInputField {\n items: Array<InputField<T>>;\n}\n\nexport type InputHTMLAttributesLike = Pick<\n InputHTMLAttributes<unknown>,\n | \"id\"\n | \"name\"\n | \"type\"\n | \"value\"\n | \"required\"\n | \"maxLength\"\n | \"minLength\"\n | \"aria-label\"\n> & {\n value?: any;\n};\n\nexport type FormCtrlOptions<T extends TObject> = {\n /**\n * The schema defining the structure and validation rules for the form.\n * This should be a TypeBox schema object.\n */\n schema: T;\n\n /**\n * Callback function to handle form submission.\n * This function will receive the parsed and validated form values.\n */\n handler: (values: Static<T>) => unknown;\n\n /**\n * Optional initial values for the form fields.\n * This can be used to pre-populate the form with existing data.\n */\n initialValues?: Partial<Static<T>>;\n\n /**\n * Optional function to create custom field attributes.\n * This can be used to add custom validation, styles, or other attributes.\n */\n onCreateField?: (\n name: keyof Static<T> & string,\n schema: TSchema,\n ) => InputHTMLAttributes<unknown>;\n\n /**\n * If defined, this will generate a unique ID for each field, prefixed with this string.\n *\n * > \"username\" with id=\"form-123\" will become \"form-123-username\".\n *\n * If omitted, IDs will not be generated.\n */\n id?: string;\n\n onError?: (error: Error) => void;\n\n onChange?: (key: string, value: any, store: Record<string, any>) => void;\n\n onReset?: () => void;\n};\n","import type { TObject } from \"alepha\";\nimport { useAlepha } from \"alepha/react\";\nimport { useEffect, useId, useMemo, useRef } from \"react\";\nimport { type FormCtrlOptions, FormModel } from \"../services/FormModel.ts\";\n\n/**\n * Custom hook to create a form with validation and field management.\n * This hook uses TypeBox schemas to define the structure and validation rules for the form.\n * It provides a way to handle form submission, field creation, and value management.\n *\n * @example\n * ```tsx\n * import { z } from \"alepha\";\n *\n * const form = useForm({\n * schema: z.object({\n * username: z.text(),\n * password: z.text(),\n * }),\n * handler: (values) => {\n * console.log(\"Form submitted with values:\", values);\n * },\n * });\n *\n * return (\n * <form {...form.props}>\n * <input {...form.input.username.props} />\n * <input {...form.input.password.props} />\n * <button type=\"submit\">Submit</button>\n * </form>\n * );\n * ```\n */\n/**\n * Shallow / structural equality for form initial-value objects. Form values\n * are plain data (strings, numbers, arrays, plain objects) so JSON.stringify\n * is both fast enough and exact. Wrapped in try/catch to fall back to\n * reference equality if anything exotic sneaks in (e.g. circular refs).\n */\nconst stableEqual = (a: unknown, b: unknown): boolean => {\n if (a === b) return true;\n if (a == null || b == null) return false;\n try {\n return JSON.stringify(a) === JSON.stringify(b);\n } catch {\n return false;\n }\n};\n\nexport const useForm = <T extends TObject>(\n options: FormCtrlOptions<T>,\n deps: any[] = [],\n): FormModel<T> => {\n const alepha = useAlepha();\n const formId = useId();\n const initialValuesRef = useRef(options.initialValues);\n\n const form = useMemo(() => {\n return alepha.inject(FormModel<T>, {\n lifetime: \"transient\",\n args: [options.id || formId, options],\n });\n }, deps);\n\n // The model is memoized once, but callers' handlers close over\n // render-scoped state (\"const [rows, setRows] = useState(...)\" then\n // \"handler: () => onNext(rows)\"). Invoking the mount-time closure submits\n // the INITIAL state — edits silently vanish. Keep the callbacks fresh on\n // every commit so submit always sees the latest render's closures.\n useEffect(() => {\n Object.assign(form.options, {\n handler: options.handler,\n onError: options.onError,\n onChange: options.onChange,\n onReset: options.onReset,\n onCreateField: options.onCreateField,\n });\n });\n\n useEffect(() => {\n // Reference inequality alone is unsafe: callers commonly build the\n // `initialValues` object inline at the top of their render, which yields\n // a fresh reference every commit. Reinitializing on every render wipes\n // user-typed values via `setInitialValues` while leaving the DOM stale,\n // producing the \"I filled the form but submit says it's empty\" bug.\n //\n // Deep-equality (JSON-compare) catches the common case where the inline\n // literal is rebuilt with the same content. Callers who legitimately\n // need to swap initial values mid-edit (e.g. editing quest A → quest B)\n // still see a different JSON shape and trigger the reinit.\n if (stableEqual(initialValuesRef.current, options.initialValues)) {\n return;\n }\n initialValuesRef.current = options.initialValues;\n if (options.initialValues) {\n form.setInitialValues(options.initialValues as Record<string, any>);\n }\n }, [options.initialValues]);\n\n return form;\n};\n","import type { TObject } from \"alepha\";\nimport { useAlepha } from \"alepha/react\";\nimport { useRouter, useRouterState } from \"alepha/react/router\";\nimport { useEffect, useRef } from \"react\";\nimport type { FormModel } from \"../services/FormModel.ts\";\n\nexport interface UseFormQuerySyncOptions<TKey extends string> {\n /**\n * Form field keys to mirror to/from the URL query. Fields not listed\n * here stay local to the form and never leak into the address bar.\n */\n keys: readonly TKey[];\n}\n\n/**\n * Two-way bind a `useForm` instance to the URL query params, keyed\n * per-field (so the URL stays human-readable: `?status=new&zone=ops`).\n *\n * Direction 1 — URL → form:\n * - On mount AND every time one of the watched query keys changes\n * (typically via browser back/forward or external `router.push`),\n * call `form.input[key].set(value)` for each listed key. Missing /\n * empty params clear the field (set to `undefined`).\n *\n * Direction 2 — form → URL:\n * - Subscribe to the form's `form:change` event for the listed keys.\n * Each emission writes the current values for all listed keys to the\n * URL via `router.setQueryParams` (replace-state, no history spam).\n * Empty values (`undefined` / `\"\"`) are stripped from the URL so the\n * address bar stays clean.\n *\n * Replaces ad-hoc `localStorage` filter persistence: the URL becomes\n * the canonical store, so the view is shareable via copy-paste and\n * navigable via back/forward.\n *\n * @example\n * const form = useForm({ schema: z.object({ status: z.string(), q: z.string() }) });\n * useFormQuerySync(form, { keys: [\"status\", \"q\"] });\n */\nexport const useFormQuerySync = <T extends TObject, TKey extends string>(\n form: FormModel<T>,\n options: UseFormQuerySyncOptions<TKey>,\n): void => {\n const alepha = useAlepha();\n const router = useRouter();\n const state = useRouterState();\n const keys = options.keys;\n\n // URL → form. Recompute a stable signature of the watched slice of\n // router.query so the effect fires precisely when it changes.\n const querySig = keys\n .map((k) => {\n const raw = state.query?.[k];\n return typeof raw === \"string\" ? raw : \"\";\n })\n .join(\"\u0000\");\n\n // First-mount semantics differ from later URL changes: when the URL\n // is empty AND the form has an initial value (e.g. status: \"new\"),\n // preserve that initial value — and write it back to the URL so the\n // URL becomes the source of truth from then on. Without this guard\n // the mount would clear the form's defaults, defeating the whole\n // \"default lane\" pattern.\n const initialized = useRef(false);\n useEffect(() => {\n const isFirstRun = !initialized.current;\n initialized.current = true;\n const values = (form as unknown as { currentValues: Record<string, any> })\n .currentValues;\n const missingInitials: Record<string, string> = {};\n for (const key of keys) {\n const raw = state.query?.[key];\n const next = typeof raw === \"string\" && raw !== \"\" ? raw : undefined;\n const current = values[key];\n if (\n isFirstRun &&\n next === undefined &&\n current != null &&\n current !== \"\"\n ) {\n // URL missing this key on first mount but the form has a\n // default — keep the default, queue it to be written below.\n missingInitials[key] = String(current);\n continue;\n }\n // Skip when already in sync — avoids bouncing form:change ↔\n // setQueryParams and re-triggering subscribers.\n if ((current ?? undefined) !== next) {\n const input = (form.input as Record<string, any>)[key];\n if (input && typeof input.set === \"function\") {\n input.set(next);\n }\n }\n }\n if (isFirstRun && Object.keys(missingInitials).length > 0) {\n // Merge with whatever URL params ARE present so we don't clobber\n // unrelated keys the page also uses.\n const merged: Record<string, string> = {};\n for (const key of keys) {\n const raw = state.query?.[key];\n if (typeof raw === \"string\" && raw !== \"\") {\n merged[key] = raw;\n }\n }\n for (const [k, v] of Object.entries(missingInitials)) {\n merged[k] = v;\n }\n router.setQueryParams(merged);\n }\n // querySig is the meaningful trigger; form/keys/router are stable.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [querySig]);\n\n // form → URL. Listen for changes on the watched keys only.\n useEffect(() => {\n if (!alepha.isBrowser()) return;\n const off = alepha.events.on(\"form:change\", (e: any) => {\n if (e.id !== form.id) return;\n if (!keys.includes(e.path)) return;\n const next: Record<string, string> = {};\n const values = (form as unknown as { currentValues: Record<string, any> })\n .currentValues;\n for (const key of keys) {\n const value = values[key];\n if (value != null && value !== \"\") {\n next[key] = String(value);\n }\n }\n // Replace-state (default) — filters shouldn't pollute history.\n router.setQueryParams(next);\n });\n return off;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [alepha, form, router]);\n};\n","import type { TObject } from \"alepha\";\nimport { useAlepha } from \"alepha/react\";\nimport { useEffect, useState } from \"react\";\nimport type { FormModel } from \"../services/FormModel.ts\";\n\n/**\n * Hook to subscribe to all form values.\n * Re-renders on every field change — use only when needed (debug panels, live previews).\n */\nexport const useFormValues = <T extends TObject>(\n form: FormModel<T>,\n): Record<string, any> => {\n const alepha = useAlepha();\n const [values, setValues] = useState<Record<string, any>>(form.currentValues);\n\n useEffect(() => {\n if (!alepha.isBrowser()) {\n return;\n }\n\n return alepha.events.on(\"form:change\", (ev) => {\n if (ev.id === form.id) {\n setValues(form.currentValues);\n }\n });\n }, []);\n\n return values;\n};\n","/**\n * Converts a path or identifier string into a pretty display name.\n * For paths like \"/contacts/0/name\", extracts just the field name \"Name\".\n * Handles camelCase and snake_case conversion to Title Case.\n *\n * @example\n * prettyName(\"/userName\") // \"User Name\"\n * prettyName(\"/contacts/0/email\") // \"Email\"\n * prettyName(\"/address/streetName\") // \"Street Name\"\n * prettyName(\"first_name\") // \"First Name\"\n */\nexport const prettyName = (name: string): string => {\n const segments = name.split(\"/\").filter((s) => s && !/^\\d+$/.test(s));\n const fieldName = segments[segments.length - 1] || name.replaceAll(\"/\", \"\");\n return fieldName\n .replace(/([a-z])([A-Z])/g, \"$1 $2\")\n .replace(/_/g, \" \")\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n};\n","import { type TSchema, TypeBoxError, z } from \"alepha\";\nimport type { BaseInputField } from \"./FormModel.ts\";\nimport { prettyName } from \"./prettyName.ts\";\n\n/**\n * Semantic icon hint derived from schema metadata. UI layers map this\n * to their own icon set — this module is headless and ships no JSX.\n */\nexport type IconHint =\n | \"email\"\n | \"password\"\n | \"phone\"\n | \"url\"\n | \"number\"\n | \"calendar\"\n | \"clock\"\n | \"list\"\n | \"text\"\n | \"user\"\n | \"file\"\n | \"switch\";\n\nexport interface FieldConstraints {\n minLength?: number;\n maxLength?: number;\n minimum?: number;\n maximum?: number;\n pattern?: string;\n}\n\nexport interface FieldMeta {\n id?: string;\n label: string;\n description?: string;\n error?: string;\n required: boolean;\n type?: string;\n format?: string;\n isEnum: boolean;\n isArray: boolean;\n isObject: boolean;\n isArrayOfObjects: boolean;\n enum?: readonly unknown[];\n iconHint?: IconHint;\n constraints: FieldConstraints;\n testId?: string;\n schema: TSchema;\n /**\n * Raw `$control` value from the schema, untyped here. The UI layer\n * (`alepha/react/ui`) provides the strict {@link SchemaControl} type and\n * a `resolveSchemaControl` helper to evaluate the function form.\n */\n control?: unknown;\n}\n\nexport interface ParseFieldOptions {\n label?: string;\n description?: string;\n error?: Error;\n}\n\n/**\n * Derives a {@link FieldMeta} from an `InputField` (from `useForm`) plus\n * optional overrides. Pure — no React, no JSX, no UI library coupling.\n *\n * UI components consume this metadata to render labels, descriptions,\n * error messages, icons, and validation constraints.\n */\nexport const parseField = (\n input: BaseInputField,\n options: ParseFieldOptions = {},\n): FieldMeta => {\n // Peel optional/nullable/default wrappers: structure, `.meta()`, format and\n // constraints all live on the inner schema, not the wrapper. `required` is\n // tracked separately via `input.required`.\n const schema = z.schema.unwrap(input.schema) as TSchema & {\n minLength?: number;\n maxLength?: number;\n minValue?: number;\n maxValue?: number;\n };\n\n // Title / description / `$control` ride on zod's `.meta()` registry now\n // (typebox kept them as plain schema properties). Read them from there.\n const meta = (\n typeof (schema as any).meta === \"function\" ? (schema as any).meta() : null\n ) as Record<string, unknown> | null;\n\n const label =\n options.label ??\n (typeof meta?.title === \"string\" ? meta.title : undefined) ??\n prettyName(input.path);\n\n const description =\n options.description ??\n (typeof meta?.description === \"string\" ? meta.description : undefined);\n\n const error =\n options.error instanceof TypeBoxError\n ? (options.error as TypeBoxError).value?.message\n : undefined;\n\n // Structural classification via zod guards (the schema is a real zod schema,\n // not a JSON-Schema object — `schema.type`/`schema.enum` no longer apply).\n const isEnum = z.schema.isEnum(schema);\n const isArray = z.schema.isArray(schema);\n const isObject = z.schema.isObject(schema);\n const isInteger = z.schema.isInteger(schema);\n const isNumber = !isInteger && z.schema.isNumber(schema);\n const isBoolean = z.schema.isBoolean(schema);\n const type = isObject\n ? \"object\"\n : isArray\n ? \"array\"\n : isEnum\n ? \"string\"\n : isInteger\n ? \"integer\"\n : isNumber\n ? \"number\"\n : isBoolean\n ? \"boolean\"\n : z.schema.isString(schema)\n ? \"string\"\n : undefined;\n\n const format =\n typeof z.schema.format(schema) === \"string\"\n ? z.schema.format(schema)\n : undefined;\n const element = (schema as any).element ?? (schema as any).items;\n const isArrayOfObjects = isArray && z.schema.isObject(element);\n\n const name = input.props.name;\n const iconHint = inferIconHint({ type, format, name, isEnum, isArray });\n\n const constraints: FieldConstraints = {};\n if (typeof schema.minLength === \"number\")\n constraints.minLength = schema.minLength;\n if (typeof schema.maxLength === \"number\")\n constraints.maxLength = schema.maxLength;\n if (typeof schema.minValue === \"number\")\n constraints.minimum = schema.minValue;\n if (typeof schema.maxValue === \"number\")\n constraints.maximum = schema.maxValue;\n const pattern = readPattern(schema);\n if (pattern) constraints.pattern = pattern;\n\n return {\n id: input.props.id,\n label,\n description,\n error,\n required: input.required,\n type,\n format,\n isEnum,\n isArray,\n isObject,\n isArrayOfObjects,\n enum: isEnum ? z.schema.enumValues(schema) : undefined,\n iconHint,\n constraints,\n testId: (input.props as Record<string, unknown>)[\"data-testid\"] as\n | string\n | undefined,\n schema: input.schema,\n control: meta?.$control,\n };\n};\n\n/** Best-effort read of a `ZodString` regex pattern from its check list. */\nconst readPattern = (schema: unknown): string | undefined => {\n const checks = (schema as any)?._zod?.def?.checks as\n | Array<{ _zod?: { def?: { pattern?: RegExp; format?: string } } }>\n | undefined;\n if (!Array.isArray(checks)) return undefined;\n for (const check of checks) {\n const pattern = check?._zod?.def?.pattern;\n if (pattern instanceof RegExp) return pattern.source;\n }\n return undefined;\n};\n\nconst inferIconHint = (params: {\n type?: string;\n format?: string;\n name?: string;\n isEnum: boolean;\n isArray: boolean;\n}): IconHint | undefined => {\n const { type, format, name, isEnum, isArray } = params;\n\n if (format === \"email\") return \"email\";\n if (format === \"url\" || format === \"uri\") return \"url\";\n if (format === \"tel\" || format === \"phone\") return \"phone\";\n if (format === \"date\" || format === \"date-time\") return \"calendar\";\n if (format === \"time\") return \"clock\";\n\n if (name?.toLowerCase().includes(\"password\")) return \"password\";\n if (name?.toLowerCase().includes(\"email\")) return \"email\";\n if (name?.toLowerCase().includes(\"phone\")) return \"phone\";\n\n if (type === \"boolean\") return \"switch\";\n if (type === \"number\" || type === \"integer\") return \"number\";\n if (isEnum || isArray) return \"list\";\n if (type === \"string\") return \"text\";\n\n return undefined;\n};\n","import { $module } from \"alepha\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport { default as FormState } from \"./components/FormState.tsx\";\nexport * from \"./errors/FormValidationError.ts\";\nexport * from \"./hooks/useFieldValue.ts\";\nexport * from \"./hooks/useForm.ts\";\nexport * from \"./hooks/useFormQuerySync.ts\";\nexport * from \"./hooks/useFormState.ts\";\nexport * from \"./hooks/useFormValues.ts\";\nexport * from \"./services/FormModel.ts\";\nexport * from \"./services/parseField.ts\";\nexport * from \"./services/prettyName.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\ndeclare module \"alepha\" {\n interface Hooks {\n \"form:change\": {\n id: string;\n path: string;\n value: any;\n /**\n * Programmatic reset (e.g. `setInitialValues` after the parent updates\n * its state). Subscribers tracking dirty state should ignore these.\n */\n initial?: boolean;\n };\n \"form:submit:begin\": { id: string };\n \"form:submit:success\": { id: string; values: Record<string, any> };\n \"form:submit:error\": { id: string; error: Error };\n \"form:submit:end\": { id: string };\n \"form:reset\": { id: string };\n }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Type-safe forms with validation.\n *\n * **Features:**\n * - Form state management\n * - TypeBox schema validation\n * - Field-level error handling\n * - Submit handling with loading state\n * - Form reset\n *\n * @module alepha.react.form\n */\nexport const AlephaReactForm = $module({\n name: \"alepha.react.form\",\n});\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.browser.js","names":[],"sources":["../../../src/react/head/helpers/SeoExpander.ts","../../../src/react/head/providers/HeadProvider.ts","../../../src/react/head/primitives/$head.ts","../../../src/react/head/providers/BrowserHeadProvider.ts","../../../src/react/head/hooks/useHead.ts","../../../src/react/head/index.browser.ts"],"sourcesContent":["import type { Head, HeadMeta } from \"../interfaces/Head.ts\";\n\n/**\n * Expands Head configuration into SEO meta tags.\n *\n * Generates:\n * - `<meta name=\"description\">` from head.description\n * - `<meta property=\"og:*\">` OpenGraph tags\n * - `<meta name=\"twitter:*\">` Twitter Card tags\n *\n * @example\n * ```ts\n * const helper = new SeoExpander();\n * const { meta, link } = helper.expand({\n * title: \"My App\",\n * description: \"Build amazing apps\",\n * image: \"https://example.com/og.png\",\n * url: \"https://example.com/\",\n * });\n * ```\n */\nexport class SeoExpander {\n public expand(head: Head): {\n meta: HeadMeta[];\n link: Array<{ rel: string; href: string }>;\n } {\n const meta: HeadMeta[] = [];\n const link: Array<{ rel: string; href: string }> = [];\n\n // Only expand SEO if there's meaningful content beyond just title\n const hasSeoContent =\n head.description ||\n head.image ||\n head.url ||\n head.siteName ||\n head.locale ||\n head.type ||\n head.og ||\n head.twitter;\n\n if (!hasSeoContent) {\n return { meta, link };\n }\n\n // Base description\n if (head.description) {\n meta.push({ name: \"description\", content: head.description });\n }\n\n // Canonical URL\n if (head.url) {\n link.push({ rel: \"canonical\", href: head.url });\n }\n\n // OpenGraph tags\n this.expandOpenGraph(head, meta);\n\n // Twitter Card tags\n this.expandTwitter(head, meta);\n\n return { meta, link };\n }\n\n protected expandOpenGraph(head: Head, meta: HeadMeta[]): void {\n const ogTitle = head.og?.title ?? head.title;\n const ogDescription = head.og?.description ?? head.description;\n const ogImage = head.og?.image ?? head.image;\n\n if (head.type || ogTitle) {\n meta.push({ property: \"og:type\", content: head.type ?? \"website\" });\n }\n if (head.url) {\n meta.push({ property: \"og:url\", content: head.url });\n }\n if (ogTitle) {\n meta.push({ property: \"og:title\", content: ogTitle });\n }\n if (ogDescription) {\n meta.push({ property: \"og:description\", content: ogDescription });\n }\n if (ogImage) {\n meta.push({ property: \"og:image\", content: ogImage });\n if (head.imageWidth) {\n meta.push({\n property: \"og:image:width\",\n content: String(head.imageWidth),\n });\n }\n if (head.imageHeight) {\n meta.push({\n property: \"og:image:height\",\n content: String(head.imageHeight),\n });\n }\n if (head.imageAlt) {\n meta.push({ property: \"og:image:alt\", content: head.imageAlt });\n }\n }\n if (head.siteName) {\n meta.push({ property: \"og:site_name\", content: head.siteName });\n }\n if (head.locale) {\n meta.push({ property: \"og:locale\", content: head.locale });\n }\n }\n\n protected expandTwitter(head: Head, meta: HeadMeta[]): void {\n const twitterTitle = head.twitter?.title ?? head.title;\n const twitterDescription = head.twitter?.description ?? head.description;\n const twitterImage = head.twitter?.image ?? head.image;\n\n if (head.twitter?.card || twitterTitle || twitterImage) {\n meta.push({\n name: \"twitter:card\",\n content:\n head.twitter?.card ??\n (twitterImage ? \"summary_large_image\" : \"summary\"),\n });\n }\n if (head.url) {\n meta.push({ name: \"twitter:url\", content: head.url });\n }\n if (twitterTitle) {\n meta.push({ name: \"twitter:title\", content: twitterTitle });\n }\n if (twitterDescription) {\n meta.push({ name: \"twitter:description\", content: twitterDescription });\n }\n if (twitterImage) {\n meta.push({ name: \"twitter:image\", content: twitterImage });\n if (head.imageAlt) {\n meta.push({ name: \"twitter:image:alt\", content: head.imageAlt });\n }\n }\n if (head.twitter?.site) {\n meta.push({ name: \"twitter:site\", content: head.twitter.site });\n }\n if (head.twitter?.creator) {\n meta.push({ name: \"twitter:creator\", content: head.twitter.creator });\n }\n }\n}\n","import { $inject } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { SeoExpander } from \"../helpers/SeoExpander.ts\";\nimport type { Head } from \"../interfaces/Head.ts\";\n\n/**\n * Provides methods to fill and merge head information into the application state.\n *\n * Used both on server and client side to manage document head.\n *\n * @see {@link SeoExpander}\n * @see {@link ServerHeadProvider}\n * @see {@link BrowserHeadProvider}\n */\nexport class HeadProvider {\n protected readonly log = $logger();\n protected readonly seoExpander = $inject(SeoExpander);\n\n public global?: Array<Head | (() => Head)> = [];\n\n /**\n * Track if we've warned about page-level htmlAttributes to avoid spam.\n */\n protected warnedAboutHtmlAttributes = false;\n\n /**\n * Resolve global head configuration (from $head primitives only).\n *\n * This is used to get htmlAttributes early, before page loaders run.\n * Only htmlAttributes from global $head are allowed; page-level htmlAttributes\n * are ignored for early streaming optimization.\n *\n * @returns Merged global head with htmlAttributes\n */\n public resolveGlobalHead(): Head {\n const head: Head = {\n htmlAttributes: { lang: \"en\" },\n };\n\n for (const h of this.global ?? []) {\n const resolved = typeof h === \"function\" ? h() : h;\n if (resolved.htmlAttributes) {\n head.htmlAttributes = {\n ...head.htmlAttributes,\n ...resolved.htmlAttributes,\n };\n }\n }\n\n return head;\n }\n\n /**\n * Fully resolve all global $head entries (functions re-evaluated, objects kept as-is).\n *\n * Unlike resolveGlobalHead() which only extracts htmlAttributes for streaming,\n * this resolves all head properties (meta, link, script, htmlAttributes, etc.).\n *\n * Used by BrowserHeadProvider.refreshGlobalHead() to re-apply global head to the DOM.\n */\n public resolveGlobal(): Head {\n let head: Head = {};\n\n for (const h of this.global ?? []) {\n const resolved = typeof h === \"function\" ? h() : h;\n const { meta, link } = this.seoExpander.expand(resolved);\n head = {\n ...head,\n ...resolved,\n meta: [...(head.meta ?? []), ...meta, ...(resolved.meta ?? [])],\n link: [...(head.link ?? []), ...link, ...(resolved.link ?? [])],\n script: [...(head.script ?? []), ...(resolved.script ?? [])],\n };\n }\n\n return head;\n }\n\n public fillHead(state: HeadState) {\n state.head = {\n ...state.head,\n };\n\n for (const h of this.global ?? []) {\n const head = typeof h === \"function\" ? h() : h;\n this.mergeHead(state, head);\n }\n\n for (const layer of state.layers) {\n if (layer.route?.head && !layer.error) {\n this.fillHeadByPage(layer.route, state, layer.props ?? {});\n }\n }\n\n // Defaults if none were set by global $head or page head\n state.head.title ??= \"App\";\n state.head.htmlAttributes = {\n lang: \"en\",\n ...state.head.htmlAttributes,\n };\n }\n\n protected mergeHead(state: HeadState, head: Head): void {\n // Expand SEO fields into meta tags\n const { meta, link } = this.seoExpander.expand(head);\n state.head = {\n ...state.head,\n ...head,\n meta: [...(state.head.meta ?? []), ...meta, ...(head.meta ?? [])],\n link: [...(state.head.link ?? []), ...link, ...(head.link ?? [])],\n script: [...(state.head.script ?? []), ...(head.script ?? [])],\n };\n }\n\n protected fillHeadByPage(\n page: HeadRoute,\n state: HeadState,\n props: Record<string, any>,\n ): void {\n if (!page.head) {\n return;\n }\n\n state.head ??= {};\n\n const head =\n typeof page.head === \"function\"\n ? page.head(props, state.head)\n : page.head;\n\n // Expand SEO fields into meta tags\n const { meta, link } = this.seoExpander.expand(head);\n state.head.meta = [...(state.head.meta ?? []), ...meta];\n state.head.link = [...(state.head.link ?? []), ...link];\n\n if (head.title) {\n state.head ??= {};\n\n if (state.head.titleSeparator) {\n state.head.title = `${head.title}${state.head.titleSeparator}${state.head.title}`;\n } else {\n state.head.title = head.title;\n }\n\n state.head.titleSeparator = head.titleSeparator;\n }\n\n // htmlAttributes from pages are ignored for early streaming optimization.\n // Only global $head can set htmlAttributes.\n if (head.htmlAttributes && !this.warnedAboutHtmlAttributes) {\n this.warnedAboutHtmlAttributes = true;\n this.log.warn(\n \"Page-level htmlAttributes are ignored. Use global $head() for htmlAttributes instead, \" +\n \"as they are sent before page loaders run for early streaming optimization.\",\n );\n }\n\n if (head.bodyAttributes) {\n state.head.bodyAttributes = {\n ...state.head.bodyAttributes,\n ...head.bodyAttributes,\n };\n }\n\n if (head.meta) {\n state.head.meta = [...(state.head.meta ?? []), ...(head.meta ?? [])];\n }\n\n if (head.link) {\n state.head.link = [...(state.head.link ?? []), ...(head.link ?? [])];\n }\n\n if (head.script) {\n state.head.script = [\n ...(state.head.script ?? []),\n ...(head.script ?? []),\n ];\n }\n }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Minimal route interface for head processing.\n * Avoids circular dependency with alepha/react/router.\n */\ninterface HeadRoute {\n head?: Head | ((props: Record<string, any>, previous?: Head) => Head);\n}\n\n/**\n * Minimal state interface for head processing.\n * Avoids circular dependency with alepha/react/router.\n */\ninterface HeadState {\n head: Head;\n layers: Array<{\n route?: HeadRoute;\n props?: Record<string, any>;\n error?: Error;\n }>;\n}\n","import { $inject, createPrimitive, KIND, Primitive } from \"alepha\";\nimport type { Head } from \"../interfaces/Head.ts\";\nimport { HeadProvider } from \"../providers/HeadProvider.ts\";\n\n/**\n * Set global `<head>` options for the application.\n */\nexport const $head = (options: HeadPrimitiveOptions) => {\n return createPrimitive(HeadPrimitive, options);\n};\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport type HeadPrimitiveOptions = Head | (() => Head);\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class HeadPrimitive extends Primitive<HeadPrimitiveOptions> {\n protected readonly provider = $inject(HeadProvider);\n protected onInit() {\n this.provider.global = [...(this.provider.global ?? []), this.options];\n }\n}\n\n$head[KIND] = HeadPrimitive;\n","import { $inject, Alepha } from \"alepha\";\nimport type { Head, HeadMeta } from \"../interfaces/Head.ts\";\nimport { HeadProvider } from \"./HeadProvider.ts\";\n\n/**\n * Browser-side head provider that manages document head elements.\n *\n * Used by ReactBrowserProvider and ReactBrowserRouterProvider to update\n * document title, meta tags, and other head elements during client-side\n * navigation.\n */\nexport class BrowserHeadProvider {\n protected readonly alepha = $inject(Alepha);\n protected readonly headProvider = $inject(HeadProvider);\n\n protected get document(): Document {\n return window.document;\n }\n\n /**\n * Fill head state from route configurations and render to document.\n * Combines fillHead from HeadProvider with renderHead to the DOM.\n *\n * Only runs in browser environment - no-op on server.\n */\n public fillAndRenderHead(state: { head: Head; layers: Array<any> }): void {\n // Skip on server-side\n if (!this.alepha.isBrowser()) {\n return;\n }\n\n this.headProvider.fillHead(state as any);\n if (state.head) {\n this.renderHead(this.document, state.head);\n }\n }\n\n /**\n * Re-evaluate all global $head entries and apply the result to the DOM.\n *\n * Call this when something that affects global $head output changes at runtime\n * (e.g., theme switch). Page-level head (title, meta from routes) is not touched.\n */\n public refreshGlobalHead(): void {\n const head = this.headProvider.resolveGlobal();\n this.renderHead(this.document, head);\n }\n\n public getHead(document: Document): Head {\n return {\n get title() {\n return document.title;\n },\n get htmlAttributes() {\n const attrs: Record<string, string> = {};\n for (const attr of document.documentElement.attributes) {\n attrs[attr.name] = attr.value;\n }\n return attrs;\n },\n get bodyAttributes() {\n const attrs: Record<string, string> = {};\n for (const attr of document.body.attributes) {\n attrs[attr.name] = attr.value;\n }\n return attrs;\n },\n get meta() {\n const metas: HeadMeta[] = [];\n // Get meta tags with name attribute\n for (const meta of document.head.querySelectorAll(\"meta[name]\")) {\n const name = meta.getAttribute(\"name\");\n const content = meta.getAttribute(\"content\");\n if (name && content) {\n metas.push({ name, content });\n }\n }\n // Get meta tags with property attribute (OpenGraph)\n for (const meta of document.head.querySelectorAll(\"meta[property]\")) {\n const property = meta.getAttribute(\"property\");\n const content = meta.getAttribute(\"content\");\n if (property && content) {\n metas.push({ property, content });\n }\n }\n return metas;\n },\n };\n }\n\n public renderHead(document: Document, head: Head): void {\n if (head.title) {\n document.title = head.title;\n }\n\n if (head.bodyAttributes) {\n for (const [key, value] of Object.entries(head.bodyAttributes)) {\n if (value) {\n document.body.setAttribute(key, value);\n } else {\n document.body.removeAttribute(key);\n }\n }\n }\n\n if (head.htmlAttributes) {\n for (const [key, value] of Object.entries(head.htmlAttributes)) {\n if (value) {\n document.documentElement.setAttribute(key, value);\n } else {\n document.documentElement.removeAttribute(key);\n }\n }\n }\n\n if (head.meta) {\n for (const it of head.meta) {\n this.renderMetaTag(document, it);\n }\n }\n\n if (head.link) {\n for (const it of head.link) {\n const { rel, href } = it;\n let link = document.querySelector(`link[rel=\"${rel}\"][href=\"${href}\"]`);\n if (!link) {\n link = document.createElement(\"link\");\n link.setAttribute(\"rel\", rel);\n link.setAttribute(\"href\", href);\n if (it.type) {\n link.setAttribute(\"type\", it.type);\n }\n if (it.as) {\n link.setAttribute(\"as\", it.as);\n }\n if (it.crossorigin != null) {\n link.setAttribute(\"crossorigin\", \"\");\n }\n if (it.media) {\n link.setAttribute(\"media\", it.media);\n }\n if (it.sizes) {\n link.setAttribute(\"sizes\", it.sizes);\n }\n if (it.hreflang) {\n link.setAttribute(\"hreflang\", it.hreflang);\n }\n document.head.appendChild(link);\n }\n }\n }\n\n if (head.script) {\n for (const it of head.script) {\n this.renderScriptTag(document, it);\n }\n }\n }\n\n protected renderScriptTag(\n document: Document,\n script:\n | string\n | (Record<string, string | boolean | undefined> & { content?: string }),\n ): void {\n // Plain string → inline script. Dedupe by exact content match against\n // any existing inline script (handles SSR-emitted globals that would\n // otherwise be re-appended on hydration).\n if (typeof script === \"string\") {\n if (this.findInlineScriptByContent(document, script)) return;\n const el = document.createElement(\"script\");\n el.textContent = script;\n document.head.appendChild(el);\n return;\n }\n\n const { content, ...attrs } = script;\n\n // src-based scripts: dedupe by src attribute (existing behaviour).\n if (attrs.src) {\n if (document.querySelector(`script[src=\"${attrs.src}\"]`)) return;\n } else if (typeof attrs.id === \"string\") {\n // id-based dedupe — single source of truth per id.\n if (document.querySelector(`script#${CSS.escape(attrs.id)}`)) return;\n } else if (content) {\n // Inline scripts with `content` and no src/id: fall back to content match.\n if (this.findInlineScriptByContent(document, content)) return;\n }\n\n const el = document.createElement(\"script\");\n for (const [key, value] of Object.entries(attrs)) {\n if (value === true) {\n el.setAttribute(key, \"\");\n } else if (value !== undefined && value !== false) {\n el.setAttribute(key, String(value));\n }\n }\n if (content) {\n el.textContent = content;\n }\n document.head.appendChild(el);\n }\n\n /**\n * Find an existing inline `<script>` tag (no `src`) with matching textContent.\n * Used to make `renderScriptTag` idempotent across hydration + navigation,\n * so SSR-emitted global scripts aren't re-appended client-side.\n */\n protected findInlineScriptByContent(\n document: Document,\n content: string,\n ): Element | null {\n for (const existing of document.head.querySelectorAll(\n \"script:not([src])\",\n )) {\n if (existing.textContent === content) return existing;\n }\n return null;\n }\n\n protected renderMetaTag(document: Document, meta: HeadMeta): void {\n const { content } = meta;\n\n // Handle OpenGraph tags (property attribute)\n if (meta.property) {\n const existing = document.querySelector(\n `meta[property=\"${meta.property}\"]`,\n );\n if (existing) {\n existing.setAttribute(\"content\", content);\n } else {\n const newMeta = document.createElement(\"meta\");\n newMeta.setAttribute(\"property\", meta.property);\n newMeta.setAttribute(\"content\", content);\n document.head.appendChild(newMeta);\n }\n return;\n }\n\n // Handle standard meta tags (name attribute)\n if (meta.name) {\n const existing = document.querySelector(`meta[name=\"${meta.name}\"]`);\n if (existing) {\n existing.setAttribute(\"content\", content);\n } else {\n const newMeta = document.createElement(\"meta\");\n newMeta.setAttribute(\"name\", meta.name);\n newMeta.setAttribute(\"content\", content);\n document.head.appendChild(newMeta);\n }\n }\n }\n}\n","import { Alepha } from \"alepha\";\nimport { useInject } from \"alepha/react\";\nimport { useCallback, useEffect, useMemo } from \"react\";\nimport type { Head } from \"../interfaces/Head.ts\";\nimport { BrowserHeadProvider } from \"../providers/BrowserHeadProvider.ts\";\n\n/**\n * ```tsx\n * const App = () => {\n * const [head, setHead] = useHead({\n * // will set the document title on the first render\n * title: \"My App\",\n * });\n *\n * return (\n * // This will update the document title when the button is clicked\n * <button onClick={() => setHead({ title: \"Change Title\" })}>\n * Change Title {head.title}\n * </button>\n * );\n * }\n * ```\n */\nexport const useHead = (options?: UseHeadOptions): UseHeadReturn => {\n const alepha = useInject(Alepha);\n\n const current = useMemo(() => {\n if (!alepha.isBrowser()) {\n return {};\n }\n\n return alepha.inject(BrowserHeadProvider).getHead(window.document);\n }, []);\n\n const setHead = useCallback((head?: Head | ((previous?: Head) => Head)) => {\n if (!alepha.isBrowser()) {\n return;\n }\n\n const headProvider = alepha.inject(BrowserHeadProvider);\n const resolved =\n typeof head === \"function\"\n ? head(headProvider.getHead(window.document))\n : head || {};\n headProvider.renderHead(window.document, resolved);\n }, []);\n\n useEffect(() => {\n if (options) {\n setHead(options);\n }\n }, []);\n\n return [current, setHead];\n};\n\nexport type UseHeadOptions = Head | ((previous?: Head) => Head);\n\nexport type UseHeadReturn = [\n Head,\n (head?: Head | ((previous?: Head) => Head)) => void,\n];\n","import { $module } from \"alepha\";\nimport { AlephaReact } from \"alepha/react\";\nimport { $head } from \"./primitives/$head.ts\";\nimport { BrowserHeadProvider } from \"./providers/BrowserHeadProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./helpers/SeoExpander.ts\";\nexport * from \"./hooks/useHead.ts\";\nexport * from \"./interfaces/Head.ts\";\nexport * from \"./primitives/$head.ts\";\nexport * from \"./providers/BrowserHeadProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Alepha React Head Module\n *\n * @see {@link BrowserHeadProvider}\n * @module alepha.react.head\n */\nexport const AlephaReactHead = $module({\n name: \"alepha.react.head\",\n primitives: [$head],\n services: [AlephaReact, BrowserHeadProvider],\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.browser.js","names":[],"sources":["../../../src/react/head/helpers/SeoExpander.ts","../../../src/react/head/providers/HeadProvider.ts","../../../src/react/head/primitives/$head.ts","../../../src/react/head/providers/BrowserHeadProvider.ts","../../../src/react/head/hooks/useHead.ts","../../../src/react/head/index.browser.ts"],"sourcesContent":["import type { Head, HeadMeta } from \"../interfaces/Head.ts\";\n\n/**\n * Expands Head configuration into SEO meta tags.\n *\n * Generates:\n * - `<meta name=\"description\">` from head.description\n * - `<meta property=\"og:*\">` OpenGraph tags\n * - `<meta name=\"twitter:*\">` Twitter Card tags\n *\n * @example\n * ```ts\n * const helper = new SeoExpander();\n * const { meta, link } = helper.expand({\n * title: \"My App\",\n * description: \"Build amazing apps\",\n * image: \"https://example.com/og.png\",\n * url: \"https://example.com/\",\n * });\n * ```\n */\nexport class SeoExpander {\n public expand(head: Head): {\n meta: HeadMeta[];\n link: Array<{ rel: string; href: string }>;\n } {\n const meta: HeadMeta[] = [];\n const link: Array<{ rel: string; href: string }> = [];\n\n // Only expand SEO if there's meaningful content beyond just title\n const hasSeoContent =\n head.description ||\n head.image ||\n head.url ||\n head.siteName ||\n head.locale ||\n head.type ||\n head.og ||\n head.twitter;\n\n if (!hasSeoContent) {\n return { meta, link };\n }\n\n // Base description\n if (head.description) {\n meta.push({ name: \"description\", content: head.description });\n }\n\n // Canonical URL\n if (head.url) {\n link.push({ rel: \"canonical\", href: head.url });\n }\n\n // OpenGraph tags\n this.expandOpenGraph(head, meta);\n\n // Twitter Card tags\n this.expandTwitter(head, meta);\n\n return { meta, link };\n }\n\n protected expandOpenGraph(head: Head, meta: HeadMeta[]): void {\n const ogTitle = head.og?.title ?? head.title;\n const ogDescription = head.og?.description ?? head.description;\n const ogImage = head.og?.image ?? head.image;\n\n if (head.type || ogTitle) {\n meta.push({ property: \"og:type\", content: head.type ?? \"website\" });\n }\n if (head.url) {\n meta.push({ property: \"og:url\", content: head.url });\n }\n if (ogTitle) {\n meta.push({ property: \"og:title\", content: ogTitle });\n }\n if (ogDescription) {\n meta.push({ property: \"og:description\", content: ogDescription });\n }\n if (ogImage) {\n meta.push({ property: \"og:image\", content: ogImage });\n if (head.imageWidth) {\n meta.push({\n property: \"og:image:width\",\n content: String(head.imageWidth),\n });\n }\n if (head.imageHeight) {\n meta.push({\n property: \"og:image:height\",\n content: String(head.imageHeight),\n });\n }\n if (head.imageAlt) {\n meta.push({ property: \"og:image:alt\", content: head.imageAlt });\n }\n }\n if (head.siteName) {\n meta.push({ property: \"og:site_name\", content: head.siteName });\n }\n if (head.locale) {\n meta.push({ property: \"og:locale\", content: head.locale });\n }\n }\n\n protected expandTwitter(head: Head, meta: HeadMeta[]): void {\n const twitterTitle = head.twitter?.title ?? head.title;\n const twitterDescription = head.twitter?.description ?? head.description;\n const twitterImage = head.twitter?.image ?? head.image;\n\n if (head.twitter?.card || twitterTitle || twitterImage) {\n meta.push({\n name: \"twitter:card\",\n content:\n head.twitter?.card ??\n (twitterImage ? \"summary_large_image\" : \"summary\"),\n });\n }\n if (head.url) {\n meta.push({ name: \"twitter:url\", content: head.url });\n }\n if (twitterTitle) {\n meta.push({ name: \"twitter:title\", content: twitterTitle });\n }\n if (twitterDescription) {\n meta.push({ name: \"twitter:description\", content: twitterDescription });\n }\n if (twitterImage) {\n meta.push({ name: \"twitter:image\", content: twitterImage });\n if (head.imageAlt) {\n meta.push({ name: \"twitter:image:alt\", content: head.imageAlt });\n }\n }\n if (head.twitter?.site) {\n meta.push({ name: \"twitter:site\", content: head.twitter.site });\n }\n if (head.twitter?.creator) {\n meta.push({ name: \"twitter:creator\", content: head.twitter.creator });\n }\n }\n}\n","import { $inject } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { SeoExpander } from \"../helpers/SeoExpander.ts\";\nimport type { Head } from \"../interfaces/Head.ts\";\n\n/**\n * Provides methods to fill and merge head information into the application state.\n *\n * Used both on server and client side to manage document head.\n *\n * @see {@link SeoExpander}\n * @see {@link ServerHeadProvider}\n * @see {@link BrowserHeadProvider}\n */\nexport class HeadProvider {\n protected readonly log = $logger();\n protected readonly seoExpander = $inject(SeoExpander);\n\n public global?: Array<Head | (() => Head)> = [];\n\n /**\n * Track if we've warned about page-level htmlAttributes to avoid spam.\n */\n protected warnedAboutHtmlAttributes = false;\n\n /**\n * Resolve global head configuration (from $head primitives only).\n *\n * This is used to get htmlAttributes early, before page loaders run.\n * Only htmlAttributes from global $head are allowed; page-level htmlAttributes\n * are ignored for early streaming optimization.\n *\n * @returns Merged global head with htmlAttributes\n */\n public resolveGlobalHead(): Head {\n const head: Head = {\n htmlAttributes: { lang: \"en\" },\n };\n\n for (const h of this.global ?? []) {\n const resolved = typeof h === \"function\" ? h() : h;\n if (resolved.htmlAttributes) {\n head.htmlAttributes = {\n ...head.htmlAttributes,\n ...resolved.htmlAttributes,\n };\n }\n }\n\n return head;\n }\n\n /**\n * Fully resolve all global $head entries (functions re-evaluated, objects kept as-is).\n *\n * Unlike resolveGlobalHead() which only extracts htmlAttributes for streaming,\n * this resolves all head properties (meta, link, script, htmlAttributes, etc.).\n *\n * Used by BrowserHeadProvider.refreshGlobalHead() to re-apply global head to the DOM.\n */\n public resolveGlobal(): Head {\n let head: Head = {};\n\n for (const h of this.global ?? []) {\n const resolved = typeof h === \"function\" ? h() : h;\n const { meta, link } = this.seoExpander.expand(resolved);\n head = {\n ...head,\n ...resolved,\n meta: [...(head.meta ?? []), ...meta, ...(resolved.meta ?? [])],\n link: [...(head.link ?? []), ...link, ...(resolved.link ?? [])],\n script: [...(head.script ?? []), ...(resolved.script ?? [])],\n };\n }\n\n return head;\n }\n\n public fillHead(state: HeadState) {\n state.head = {\n ...state.head,\n };\n\n for (const h of this.global ?? []) {\n const head = typeof h === \"function\" ? h() : h;\n this.mergeHead(state, head);\n }\n\n for (const layer of state.layers) {\n if (layer.route?.head && !layer.error) {\n this.fillHeadByPage(layer.route, state, layer.props ?? {});\n }\n }\n\n // Defaults if none were set by global $head or page head\n state.head.title ??= \"App\";\n state.head.htmlAttributes = {\n lang: \"en\",\n ...state.head.htmlAttributes,\n };\n }\n\n protected mergeHead(state: HeadState, head: Head): void {\n // Expand SEO fields into meta tags\n const { meta, link } = this.seoExpander.expand(head);\n state.head = {\n ...state.head,\n ...head,\n meta: [...(state.head.meta ?? []), ...meta, ...(head.meta ?? [])],\n link: [...(state.head.link ?? []), ...link, ...(head.link ?? [])],\n script: [...(state.head.script ?? []), ...(head.script ?? [])],\n };\n }\n\n protected fillHeadByPage(\n page: HeadRoute,\n state: HeadState,\n props: Record<string, any>,\n ): void {\n if (!page.head) {\n return;\n }\n\n state.head ??= {};\n\n const head =\n typeof page.head === \"function\"\n ? page.head(props, state.head)\n : page.head;\n\n // Expand SEO fields into meta tags\n const { meta, link } = this.seoExpander.expand(head);\n state.head.meta = [...(state.head.meta ?? []), ...meta];\n state.head.link = [...(state.head.link ?? []), ...link];\n\n if (head.title) {\n state.head ??= {};\n\n if (state.head.titleSeparator) {\n state.head.title = `${head.title}${state.head.titleSeparator}${state.head.title}`;\n } else {\n state.head.title = head.title;\n }\n\n state.head.titleSeparator = head.titleSeparator;\n }\n\n // htmlAttributes from pages are ignored for early streaming optimization.\n // Only global $head can set htmlAttributes.\n if (head.htmlAttributes && !this.warnedAboutHtmlAttributes) {\n this.warnedAboutHtmlAttributes = true;\n this.log.warn(\n \"Page-level htmlAttributes are ignored. Use global $head() for htmlAttributes instead, \" +\n \"as they are sent before page loaders run for early streaming optimization.\",\n );\n }\n\n if (head.bodyAttributes) {\n state.head.bodyAttributes = {\n ...state.head.bodyAttributes,\n ...head.bodyAttributes,\n };\n }\n\n if (head.meta) {\n state.head.meta = [...(state.head.meta ?? []), ...(head.meta ?? [])];\n }\n\n if (head.link) {\n state.head.link = [...(state.head.link ?? []), ...(head.link ?? [])];\n }\n\n if (head.script) {\n state.head.script = [\n ...(state.head.script ?? []),\n ...(head.script ?? []),\n ];\n }\n }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Minimal route interface for head processing.\n * Avoids circular dependency with alepha/react/router.\n */\ninterface HeadRoute {\n head?: Head | ((props: Record<string, any>, previous?: Head) => Head);\n}\n\n/**\n * Minimal state interface for head processing.\n * Avoids circular dependency with alepha/react/router.\n */\ninterface HeadState {\n head: Head;\n layers: Array<{\n route?: HeadRoute;\n props?: Record<string, any>;\n error?: Error;\n }>;\n}\n","import { $inject, createPrimitive, KIND, Primitive } from \"alepha\";\nimport type { Head } from \"../interfaces/Head.ts\";\nimport { HeadProvider } from \"../providers/HeadProvider.ts\";\n\n/**\n * Set global `<head>` options for the application.\n */\nexport const $head = (options: HeadPrimitiveOptions) => {\n return createPrimitive(HeadPrimitive, options);\n};\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport type HeadPrimitiveOptions = Head | (() => Head);\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class HeadPrimitive extends Primitive<HeadPrimitiveOptions> {\n protected readonly provider = $inject(HeadProvider);\n protected onInit() {\n this.provider.global = [...(this.provider.global ?? []), this.options];\n }\n}\n\n$head[KIND] = HeadPrimitive;\n","import { $inject, Alepha } from \"alepha\";\nimport type { Head, HeadMeta } from \"../interfaces/Head.ts\";\nimport { HeadProvider } from \"./HeadProvider.ts\";\n\n/**\n * Browser-side head provider that manages document head elements.\n *\n * Used by ReactBrowserProvider and ReactBrowserRouterProvider to update\n * document title, meta tags, and other head elements during client-side\n * navigation.\n */\nexport class BrowserHeadProvider {\n protected readonly alepha = $inject(Alepha);\n protected readonly headProvider = $inject(HeadProvider);\n\n protected get document(): Document {\n return window.document;\n }\n\n /**\n * Fill head state from route configurations and render to document.\n * Combines fillHead from HeadProvider with renderHead to the DOM.\n *\n * Only runs in browser environment - no-op on server.\n */\n public fillAndRenderHead(state: { head: Head; layers: Array<any> }): void {\n // Skip on server-side\n if (!this.alepha.isBrowser()) {\n return;\n }\n\n this.headProvider.fillHead(state as any);\n if (state.head) {\n this.renderHead(this.document, state.head);\n }\n }\n\n /**\n * Re-evaluate all global $head entries and apply the result to the DOM.\n *\n * Call this when something that affects global $head output changes at runtime\n * (e.g., theme switch). Page-level head (title, meta from routes) is not touched.\n */\n public refreshGlobalHead(): void {\n const head = this.headProvider.resolveGlobal();\n this.renderHead(this.document, head);\n }\n\n public getHead(document: Document): Head {\n return {\n get title() {\n return document.title;\n },\n get htmlAttributes() {\n const attrs: Record<string, string> = {};\n for (const attr of document.documentElement.attributes) {\n attrs[attr.name] = attr.value;\n }\n return attrs;\n },\n get bodyAttributes() {\n const attrs: Record<string, string> = {};\n for (const attr of document.body.attributes) {\n attrs[attr.name] = attr.value;\n }\n return attrs;\n },\n get meta() {\n const metas: HeadMeta[] = [];\n // Get meta tags with name attribute\n for (const meta of document.head.querySelectorAll(\"meta[name]\")) {\n const name = meta.getAttribute(\"name\");\n const content = meta.getAttribute(\"content\");\n if (name && content) {\n metas.push({ name, content });\n }\n }\n // Get meta tags with property attribute (OpenGraph)\n for (const meta of document.head.querySelectorAll(\"meta[property]\")) {\n const property = meta.getAttribute(\"property\");\n const content = meta.getAttribute(\"content\");\n if (property && content) {\n metas.push({ property, content });\n }\n }\n return metas;\n },\n };\n }\n\n public renderHead(document: Document, head: Head): void {\n if (head.title) {\n document.title = head.title;\n }\n\n if (head.bodyAttributes) {\n for (const [key, value] of Object.entries(head.bodyAttributes)) {\n if (value) {\n document.body.setAttribute(key, value);\n } else {\n document.body.removeAttribute(key);\n }\n }\n }\n\n if (head.htmlAttributes) {\n for (const [key, value] of Object.entries(head.htmlAttributes)) {\n if (value) {\n document.documentElement.setAttribute(key, value);\n } else {\n document.documentElement.removeAttribute(key);\n }\n }\n }\n\n if (head.meta) {\n for (const it of head.meta) {\n this.renderMetaTag(document, it);\n }\n }\n\n if (head.link) {\n for (const it of head.link) {\n const { rel, href } = it;\n let link = document.querySelector(`link[rel=\"${rel}\"][href=\"${href}\"]`);\n if (!link) {\n link = document.createElement(\"link\");\n link.setAttribute(\"rel\", rel);\n link.setAttribute(\"href\", href);\n if (it.type) {\n link.setAttribute(\"type\", it.type);\n }\n if (it.as) {\n link.setAttribute(\"as\", it.as);\n }\n if (it.crossorigin != null) {\n link.setAttribute(\"crossorigin\", \"\");\n }\n if (it.media) {\n link.setAttribute(\"media\", it.media);\n }\n if (it.sizes) {\n link.setAttribute(\"sizes\", it.sizes);\n }\n if (it.hreflang) {\n link.setAttribute(\"hreflang\", it.hreflang);\n }\n document.head.appendChild(link);\n }\n }\n }\n\n if (head.script) {\n for (const it of head.script) {\n this.renderScriptTag(document, it);\n }\n }\n }\n\n protected renderScriptTag(\n document: Document,\n script:\n | string\n | (Record<string, string | boolean | undefined> & { content?: string }),\n ): void {\n // Plain string → inline script. Dedupe by exact content match against\n // any existing inline script (handles SSR-emitted globals that would\n // otherwise be re-appended on hydration).\n if (typeof script === \"string\") {\n if (this.findInlineScriptByContent(document, script)) return;\n const el = document.createElement(\"script\");\n el.textContent = script;\n document.head.appendChild(el);\n return;\n }\n\n const { content, ...attrs } = script;\n\n // src-based scripts: dedupe by src attribute (existing behaviour).\n if (attrs.src) {\n if (document.querySelector(`script[src=\"${attrs.src}\"]`)) return;\n } else if (typeof attrs.id === \"string\") {\n // id-based dedupe — single source of truth per id.\n if (document.querySelector(`script#${CSS.escape(attrs.id)}`)) return;\n } else if (content) {\n // Inline scripts with `content` and no src/id: fall back to content match.\n if (this.findInlineScriptByContent(document, content)) return;\n }\n\n const el = document.createElement(\"script\");\n for (const [key, value] of Object.entries(attrs)) {\n if (value === true) {\n el.setAttribute(key, \"\");\n } else if (value !== undefined && value !== false) {\n el.setAttribute(key, String(value));\n }\n }\n if (content) {\n el.textContent = content;\n }\n document.head.appendChild(el);\n }\n\n /**\n * Find an existing inline `<script>` tag (no `src`) with matching textContent.\n * Used to make `renderScriptTag` idempotent across hydration + navigation,\n * so SSR-emitted global scripts aren't re-appended client-side.\n */\n protected findInlineScriptByContent(\n document: Document,\n content: string,\n ): Element | null {\n for (const existing of document.head.querySelectorAll(\n \"script:not([src])\",\n )) {\n if (existing.textContent === content) return existing;\n }\n return null;\n }\n\n protected renderMetaTag(document: Document, meta: HeadMeta): void {\n const { content } = meta;\n\n // Handle OpenGraph tags (property attribute)\n if (meta.property) {\n const existing = document.querySelector(\n `meta[property=\"${meta.property}\"]`,\n );\n if (existing) {\n existing.setAttribute(\"content\", content);\n } else {\n const newMeta = document.createElement(\"meta\");\n newMeta.setAttribute(\"property\", meta.property);\n newMeta.setAttribute(\"content\", content);\n document.head.appendChild(newMeta);\n }\n return;\n }\n\n // Handle standard meta tags (name attribute)\n if (meta.name) {\n const existing = document.querySelector(`meta[name=\"${meta.name}\"]`);\n if (existing) {\n existing.setAttribute(\"content\", content);\n } else {\n const newMeta = document.createElement(\"meta\");\n newMeta.setAttribute(\"name\", meta.name);\n newMeta.setAttribute(\"content\", content);\n document.head.appendChild(newMeta);\n }\n }\n }\n}\n","import { Alepha } from \"alepha\";\nimport { useInject } from \"alepha/react\";\nimport { useCallback, useEffect, useMemo } from \"react\";\nimport type { Head } from \"../interfaces/Head.ts\";\nimport { BrowserHeadProvider } from \"../providers/BrowserHeadProvider.ts\";\n\n/**\n * ```tsx\n * const App = () => {\n * const [head, setHead] = useHead({\n * // will set the document title on the first render\n * title: \"My App\",\n * });\n *\n * return (\n * // This will update the document title when the button is clicked\n * <button onClick={() => setHead({ title: \"Change Title\" })}>\n * Change Title {head.title}\n * </button>\n * );\n * }\n * ```\n */\nexport const useHead = (options?: UseHeadOptions): UseHeadReturn => {\n const alepha = useInject(Alepha);\n\n const current = useMemo(() => {\n if (!alepha.isBrowser()) {\n return {};\n }\n\n return alepha.inject(BrowserHeadProvider).getHead(window.document);\n }, []);\n\n const setHead = useCallback((head?: Head | ((previous?: Head) => Head)) => {\n if (!alepha.isBrowser()) {\n return;\n }\n\n const headProvider = alepha.inject(BrowserHeadProvider);\n const resolved =\n typeof head === \"function\"\n ? head(headProvider.getHead(window.document))\n : head || {};\n headProvider.renderHead(window.document, resolved);\n }, []);\n\n useEffect(() => {\n if (options) {\n setHead(options);\n }\n }, []);\n\n return [current, setHead];\n};\n\nexport type UseHeadOptions = Head | ((previous?: Head) => Head);\n\nexport type UseHeadReturn = [\n Head,\n (head?: Head | ((previous?: Head) => Head)) => void,\n];\n","import { $module } from \"alepha\";\nimport { AlephaReact } from \"alepha/react\";\nimport { $head } from \"./primitives/$head.ts\";\nimport { BrowserHeadProvider } from \"./providers/BrowserHeadProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./helpers/SeoExpander.ts\";\nexport * from \"./hooks/useHead.ts\";\nexport * from \"./interfaces/Head.ts\";\nexport * from \"./primitives/$head.ts\";\nexport * from \"./providers/BrowserHeadProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Alepha React Head Module\n *\n * @see {@link BrowserHeadProvider}\n * @module alepha.react.head\n */\nexport const AlephaReactHead = $module({\n name: \"alepha.react.head\",\n primitives: [$head],\n services: [AlephaReact, BrowserHeadProvider],\n});\n"],"mappings":"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"}
@@ -1,5 +1,4 @@
1
1
  import { Alepha, KIND, Primitive } from "alepha";
2
-
3
2
  //#region ../../src/react/head/interfaces/Head.d.ts
4
3
  /**
5
4
  * Complete head configuration combining basic head elements with SEO fields.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/react/head/interfaces/Head.ts","../../../src/react/head/helpers/SeoExpander.ts","../../../src/react/head/hooks/useHead.ts","../../../src/react/head/providers/HeadProvider.ts","../../../src/react/head/primitives/$head.ts","../../../src/react/head/providers/BrowserHeadProvider.ts","../../../src/react/head/providers/ServerHeadProvider.ts","../../../src/react/head/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/react/head/interfaces/Head.ts","../../../src/react/head/helpers/SeoExpander.ts","../../../src/react/head/hooks/useHead.ts","../../../src/react/head/providers/HeadProvider.ts","../../../src/react/head/primitives/$head.ts","../../../src/react/head/providers/BrowserHeadProvider.ts","../../../src/react/head/providers/ServerHeadProvider.ts","../../../src/react/head/index.ts"],"mappings":";;;;;;;;;;;;;;;;;UAeiB,aAAa,YAAY;;;;;UAMzB;;;;EAIf;;;;EAIA;;;;EAIA;;;;EAIA;;;;EAIA;;;;EAIA;;;;EAIA;;;;EAIA;;;;EAIA;;;;EAKA;;;;IAIE;;;;IAIA;;;;IAIA;;;;IAIA;;;;IAIA;;;;IAIA;;;;;EAMF;;;;IAIE;;;;IAIA;;;;IAIA;;;UAIa;EACf;EACA;;;;EAIA;;;;EAIA;EACA,iBAAiB;EACjB,iBAAiB;;;;EAIjB,OAAO,MAAM;;;;EAIb,OAAO;IACL;IACA;IACA;IACA;IACA;;;;;IAKA;;;;IAIA;;;;IAIA;;;;;EAKF,SAAS,gBAEJ;;;;IAIC;;;UAKS;;;;EAIf;;;;EAIA;;;;EAIA;;;;;;;;;;;;;;;;;;;;;;;cCzJW;EACJ,OAAO,MAAM;IAClB,MAAM;IACN,MAAM;MAAQ;MAAa;;;YAuCnB,gBAAgB,MAAM,MAAM,MAAM;YA2ClC,cAAc,MAAM,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;cCnF/B,UAAO,UAAc,mBAAiB;KAiCvC,iBAAiB,SAAS,WAAW,SAAS;KAE9C,iBACV,OACC,OAAO,SAAS,WAAW,SAAS;;;;;;;;;;;;cC9C1B;qBACQ,6BAAG;qBACH,aAAW;EAEvB,SAAS,MAAM,cAAc;;;;YAK1B;;;;;;;;;;EAWH,qBAAqB;;;;;;;;;EA0BrB,iBAAiB;EAkBjB,SAAS,OAAO;YAwBb,UAAU,OAAO,WAAW,MAAM;YAYlC,eACR,MAAM,WACN,OAAO,WACP,OAAO;;;;;;UAsED;EACR,OAAO,SAAS,OAAO,qBAAqB,WAAW,SAAS;;;;;;UAOxD;EACR,MAAM;EACN,QAAQ;IACN,QAAQ;IACR,QAAQ;IACR,QAAQ;;;;;;;;cCjMC;YAAkB,uBAAoB;;;KAMvC,uBAAuB,cAAc;cAIpC,sBAAsB,UAAU;qBACxB,UAAQ;YACjB;;;;;;;;;;;cCRC;qBACQ,QAAM;qBACN,cAAY;gBAEjB,YAAY;;;;;;;EAUnB,kBAAkB;IAAS,MAAM;IAAM,QAAQ;;;;;;;;EAkB/C;EAKA,QAAQ,UAAU,WAAW;EA0C7B,WAAW,UAAU,UAAU,MAAM;YAqElC,gBACR,UAAU,UACV,kBAEK;IAAiD;;;;;;;YA6C9C,0BACR,UAAU,UACV,kBACC;YASO,cAAc,UAAU,UAAU,MAAM;;;;;;;;;;cClNvC;qBACQ,cAAY;;;;;;;EAQxB,qBAAqB;;;;;EAQrB,SAAS;IAAS,MAAM;IAAY,QAAQ;;;;;;;;;;;;;;;cCExC,kCAAe,yBAAA"}