alepha 0.15.0 → 0.15.2

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 (551) hide show
  1. package/README.md +43 -98
  2. package/dist/api/audits/index.d.ts +630 -653
  3. package/dist/api/audits/index.d.ts.map +1 -1
  4. package/dist/api/audits/index.js +12 -35
  5. package/dist/api/audits/index.js.map +1 -1
  6. package/dist/api/files/index.d.ts +365 -358
  7. package/dist/api/files/index.d.ts.map +1 -1
  8. package/dist/api/files/index.js +12 -5
  9. package/dist/api/files/index.js.map +1 -1
  10. package/dist/api/jobs/index.d.ts +255 -248
  11. package/dist/api/jobs/index.d.ts.map +1 -1
  12. package/dist/api/jobs/index.js +10 -3
  13. package/dist/api/jobs/index.js.map +1 -1
  14. package/dist/api/keys/index.d.ts +413 -0
  15. package/dist/api/keys/index.d.ts.map +1 -0
  16. package/dist/api/keys/index.js +476 -0
  17. package/dist/api/keys/index.js.map +1 -0
  18. package/dist/api/notifications/index.browser.js +4 -4
  19. package/dist/api/notifications/index.browser.js.map +1 -1
  20. package/dist/api/notifications/index.d.ts +84 -78
  21. package/dist/api/notifications/index.d.ts.map +1 -1
  22. package/dist/api/notifications/index.js +14 -8
  23. package/dist/api/notifications/index.js.map +1 -1
  24. package/dist/api/parameters/index.d.ts +528 -535
  25. package/dist/api/parameters/index.d.ts.map +1 -1
  26. package/dist/api/parameters/index.js +30 -37
  27. package/dist/api/parameters/index.js.map +1 -1
  28. package/dist/api/users/index.d.ts +1221 -910
  29. package/dist/api/users/index.d.ts.map +1 -1
  30. package/dist/api/users/index.js +2556 -248
  31. package/dist/api/users/index.js.map +1 -1
  32. package/dist/api/verifications/index.d.ts +142 -136
  33. package/dist/api/verifications/index.d.ts.map +1 -1
  34. package/dist/api/verifications/index.js +12 -4
  35. package/dist/api/verifications/index.js.map +1 -1
  36. package/dist/batch/index.d.ts +142 -162
  37. package/dist/batch/index.d.ts.map +1 -1
  38. package/dist/batch/index.js +31 -44
  39. package/dist/batch/index.js.map +1 -1
  40. package/dist/bucket/index.d.ts +595 -171
  41. package/dist/bucket/index.d.ts.map +1 -1
  42. package/dist/bucket/index.js +1856 -12
  43. package/dist/bucket/index.js.map +1 -1
  44. package/dist/cache/core/index.d.ts +225 -53
  45. package/dist/cache/core/index.d.ts.map +1 -1
  46. package/dist/cache/core/index.js +213 -7
  47. package/dist/cache/core/index.js.map +1 -1
  48. package/dist/cache/redis/index.d.ts +1 -0
  49. package/dist/cache/redis/index.d.ts.map +1 -1
  50. package/dist/cache/redis/index.js +6 -2
  51. package/dist/cache/redis/index.js.map +1 -1
  52. package/dist/cli/index.d.ts +834 -226
  53. package/dist/cli/index.d.ts.map +1 -1
  54. package/dist/cli/index.js +2872 -417
  55. package/dist/cli/index.js.map +1 -1
  56. package/dist/command/index.d.ts +458 -310
  57. package/dist/command/index.d.ts.map +1 -1
  58. package/dist/command/index.js +2011 -76
  59. package/dist/command/index.js.map +1 -1
  60. package/dist/core/index.browser.js +309 -97
  61. package/dist/core/index.browser.js.map +1 -1
  62. package/dist/core/index.d.ts +796 -701
  63. package/dist/core/index.d.ts.map +1 -1
  64. package/dist/core/index.js +329 -97
  65. package/dist/core/index.js.map +1 -1
  66. package/dist/core/index.native.js +309 -97
  67. package/dist/core/index.native.js.map +1 -1
  68. package/dist/datetime/index.d.ts +59 -44
  69. package/dist/datetime/index.d.ts.map +1 -1
  70. package/dist/datetime/index.js +15 -0
  71. package/dist/datetime/index.js.map +1 -1
  72. package/dist/email/index.d.ts +314 -19
  73. package/dist/email/index.d.ts.map +1 -1
  74. package/dist/email/index.js +1852 -7
  75. package/dist/email/index.js.map +1 -1
  76. package/dist/fake/index.d.ts +5500 -5418
  77. package/dist/fake/index.d.ts.map +1 -1
  78. package/dist/fake/index.js +113 -42
  79. package/dist/fake/index.js.map +1 -1
  80. package/dist/lock/core/index.d.ts +219 -212
  81. package/dist/lock/core/index.d.ts.map +1 -1
  82. package/dist/lock/core/index.js +11 -4
  83. package/dist/lock/core/index.js.map +1 -1
  84. package/dist/lock/redis/index.d.ts.map +1 -1
  85. package/dist/logger/index.d.ts +41 -90
  86. package/dist/logger/index.d.ts.map +1 -1
  87. package/dist/logger/index.js +15 -68
  88. package/dist/logger/index.js.map +1 -1
  89. package/dist/mcp/index.d.ts +228 -230
  90. package/dist/mcp/index.d.ts.map +1 -1
  91. package/dist/mcp/index.js +32 -31
  92. package/dist/mcp/index.js.map +1 -1
  93. package/dist/orm/index.browser.js +12 -12
  94. package/dist/orm/index.browser.js.map +1 -1
  95. package/dist/orm/index.bun.js +90 -80
  96. package/dist/orm/index.bun.js.map +1 -1
  97. package/dist/orm/index.d.ts +1434 -1459
  98. package/dist/orm/index.d.ts.map +1 -1
  99. package/dist/orm/index.js +112 -130
  100. package/dist/orm/index.js.map +1 -1
  101. package/dist/queue/core/index.d.ts +262 -254
  102. package/dist/queue/core/index.d.ts.map +1 -1
  103. package/dist/queue/core/index.js +14 -6
  104. package/dist/queue/core/index.js.map +1 -1
  105. package/dist/queue/redis/index.d.ts.map +1 -1
  106. package/dist/react/auth/index.browser.js +108 -0
  107. package/dist/react/auth/index.browser.js.map +1 -0
  108. package/dist/react/auth/index.d.ts +100 -0
  109. package/dist/react/auth/index.d.ts.map +1 -0
  110. package/dist/react/auth/index.js +145 -0
  111. package/dist/react/auth/index.js.map +1 -0
  112. package/dist/react/core/index.d.ts +469 -0
  113. package/dist/react/core/index.d.ts.map +1 -0
  114. package/dist/react/core/index.js +464 -0
  115. package/dist/react/core/index.js.map +1 -0
  116. package/dist/react/form/index.d.ts +232 -0
  117. package/dist/react/form/index.d.ts.map +1 -0
  118. package/dist/react/form/index.js +432 -0
  119. package/dist/react/form/index.js.map +1 -0
  120. package/dist/react/head/index.browser.js +423 -0
  121. package/dist/react/head/index.browser.js.map +1 -0
  122. package/dist/react/head/index.d.ts +288 -0
  123. package/dist/react/head/index.d.ts.map +1 -0
  124. package/dist/react/head/index.js +465 -0
  125. package/dist/react/head/index.js.map +1 -0
  126. package/dist/react/i18n/index.d.ts +175 -0
  127. package/dist/react/i18n/index.d.ts.map +1 -0
  128. package/dist/react/i18n/index.js +224 -0
  129. package/dist/react/i18n/index.js.map +1 -0
  130. package/dist/react/router/index.browser.js +1980 -0
  131. package/dist/react/router/index.browser.js.map +1 -0
  132. package/dist/react/router/index.d.ts +2068 -0
  133. package/dist/react/router/index.d.ts.map +1 -0
  134. package/dist/react/router/index.js +4932 -0
  135. package/dist/react/router/index.js.map +1 -0
  136. package/dist/react/websocket/index.d.ts +117 -0
  137. package/dist/react/websocket/index.d.ts.map +1 -0
  138. package/dist/react/websocket/index.js +107 -0
  139. package/dist/react/websocket/index.js.map +1 -0
  140. package/dist/redis/index.bun.js +4 -0
  141. package/dist/redis/index.bun.js.map +1 -1
  142. package/dist/redis/index.d.ts +127 -130
  143. package/dist/redis/index.d.ts.map +1 -1
  144. package/dist/redis/index.js +16 -25
  145. package/dist/redis/index.js.map +1 -1
  146. package/dist/retry/index.d.ts +80 -71
  147. package/dist/retry/index.d.ts.map +1 -1
  148. package/dist/retry/index.js +11 -2
  149. package/dist/retry/index.js.map +1 -1
  150. package/dist/router/index.d.ts +6 -6
  151. package/dist/router/index.d.ts.map +1 -1
  152. package/dist/scheduler/index.d.ts +119 -28
  153. package/dist/scheduler/index.d.ts.map +1 -1
  154. package/dist/scheduler/index.js +404 -3
  155. package/dist/scheduler/index.js.map +1 -1
  156. package/dist/security/index.d.ts +642 -228
  157. package/dist/security/index.d.ts.map +1 -1
  158. package/dist/security/index.js +1579 -37
  159. package/dist/security/index.js.map +1 -1
  160. package/dist/server/auth/index.d.ts +1141 -111
  161. package/dist/server/auth/index.d.ts.map +1 -1
  162. package/dist/server/auth/index.js +1261 -25
  163. package/dist/server/auth/index.js.map +1 -1
  164. package/dist/server/cache/index.d.ts +63 -78
  165. package/dist/server/cache/index.d.ts.map +1 -1
  166. package/dist/server/cache/index.js +7 -22
  167. package/dist/server/cache/index.js.map +1 -1
  168. package/dist/server/compress/index.d.ts +13 -5
  169. package/dist/server/compress/index.d.ts.map +1 -1
  170. package/dist/server/compress/index.js +10 -2
  171. package/dist/server/compress/index.js.map +1 -1
  172. package/dist/server/cookies/index.d.ts +46 -22
  173. package/dist/server/cookies/index.d.ts.map +1 -1
  174. package/dist/server/cookies/index.js +7 -5
  175. package/dist/server/cookies/index.js.map +1 -1
  176. package/dist/server/core/index.d.ts +307 -196
  177. package/dist/server/core/index.d.ts.map +1 -1
  178. package/dist/server/core/index.js +271 -38
  179. package/dist/server/core/index.js.map +1 -1
  180. package/dist/server/cors/index.d.ts +24 -34
  181. package/dist/server/cors/index.d.ts.map +1 -1
  182. package/dist/server/cors/index.js +7 -21
  183. package/dist/server/cors/index.js.map +1 -1
  184. package/dist/server/health/index.d.ts +25 -19
  185. package/dist/server/health/index.d.ts.map +1 -1
  186. package/dist/server/health/index.js +8 -2
  187. package/dist/server/health/index.js.map +1 -1
  188. package/dist/server/helmet/index.d.ts +13 -5
  189. package/dist/server/helmet/index.d.ts.map +1 -1
  190. package/dist/server/helmet/index.js +11 -3
  191. package/dist/server/helmet/index.js.map +1 -1
  192. package/dist/server/links/index.browser.js +9 -1
  193. package/dist/server/links/index.browser.js.map +1 -1
  194. package/dist/server/links/index.d.ts +133 -128
  195. package/dist/server/links/index.d.ts.map +1 -1
  196. package/dist/server/links/index.js +24 -11
  197. package/dist/server/links/index.js.map +1 -1
  198. package/dist/server/metrics/index.d.ts +524 -4
  199. package/dist/server/metrics/index.d.ts.map +1 -1
  200. package/dist/server/metrics/index.js +4472 -7
  201. package/dist/server/metrics/index.js.map +1 -1
  202. package/dist/server/multipart/index.d.ts +15 -9
  203. package/dist/server/multipart/index.d.ts.map +1 -1
  204. package/dist/server/multipart/index.js +9 -3
  205. package/dist/server/multipart/index.js.map +1 -1
  206. package/dist/server/proxy/index.d.ts +110 -104
  207. package/dist/server/proxy/index.d.ts.map +1 -1
  208. package/dist/server/proxy/index.js +8 -2
  209. package/dist/server/proxy/index.js.map +1 -1
  210. package/dist/server/rate-limit/index.d.ts +46 -51
  211. package/dist/server/rate-limit/index.d.ts.map +1 -1
  212. package/dist/server/rate-limit/index.js +18 -55
  213. package/dist/server/rate-limit/index.js.map +1 -1
  214. package/dist/server/static/index.d.ts +181 -48
  215. package/dist/server/static/index.d.ts.map +1 -1
  216. package/dist/server/static/index.js +1848 -5
  217. package/dist/server/static/index.js.map +1 -1
  218. package/dist/server/swagger/index.d.ts +348 -53
  219. package/dist/server/swagger/index.d.ts.map +1 -1
  220. package/dist/server/swagger/index.js +1849 -6
  221. package/dist/server/swagger/index.js.map +1 -1
  222. package/dist/sms/index.d.ts +312 -18
  223. package/dist/sms/index.d.ts.map +1 -1
  224. package/dist/sms/index.js +1854 -10
  225. package/dist/sms/index.js.map +1 -1
  226. package/dist/system/index.browser.js +496 -0
  227. package/dist/system/index.browser.js.map +1 -0
  228. package/dist/system/index.d.ts +1158 -0
  229. package/dist/system/index.d.ts.map +1 -0
  230. package/dist/{file → system}/index.js +412 -20
  231. package/dist/system/index.js.map +1 -0
  232. package/dist/thread/index.d.ts +82 -73
  233. package/dist/thread/index.d.ts.map +1 -1
  234. package/dist/thread/index.js +13 -4
  235. package/dist/thread/index.js.map +1 -1
  236. package/dist/topic/core/index.d.ts +330 -323
  237. package/dist/topic/core/index.d.ts.map +1 -1
  238. package/dist/topic/core/index.js +12 -5
  239. package/dist/topic/core/index.js.map +1 -1
  240. package/dist/topic/redis/index.d.ts +6 -6
  241. package/dist/topic/redis/index.d.ts.map +1 -1
  242. package/dist/vite/index.d.ts +163 -5825
  243. package/dist/vite/index.d.ts.map +1 -1
  244. package/dist/vite/index.js +130 -477
  245. package/dist/vite/index.js.map +1 -1
  246. package/dist/websocket/index.browser.js +3 -3
  247. package/dist/websocket/index.browser.js.map +1 -1
  248. package/dist/websocket/index.d.ts +287 -283
  249. package/dist/websocket/index.d.ts.map +1 -1
  250. package/dist/websocket/index.js +15 -11
  251. package/dist/websocket/index.js.map +1 -1
  252. package/package.json +86 -17
  253. package/src/api/audits/index.ts +10 -33
  254. package/src/api/files/__tests__/$bucket.spec.ts +1 -1
  255. package/src/api/files/controllers/AdminFileStatsController.spec.ts +1 -1
  256. package/src/api/files/controllers/FileController.spec.ts +1 -1
  257. package/src/api/files/index.ts +10 -3
  258. package/src/api/files/jobs/FileJobs.spec.ts +1 -1
  259. package/src/api/files/services/FileService.spec.ts +1 -1
  260. package/src/api/jobs/index.ts +10 -3
  261. package/src/api/keys/controllers/AdminApiKeyController.ts +75 -0
  262. package/src/api/keys/controllers/ApiKeyController.ts +103 -0
  263. package/src/api/keys/entities/apiKeyEntity.ts +41 -0
  264. package/src/api/keys/index.ts +49 -0
  265. package/src/api/keys/schemas/adminApiKeyQuerySchema.ts +7 -0
  266. package/src/api/keys/schemas/adminApiKeyResourceSchema.ts +17 -0
  267. package/src/api/keys/schemas/createApiKeyBodySchema.ts +7 -0
  268. package/src/api/keys/schemas/createApiKeyResponseSchema.ts +11 -0
  269. package/src/api/keys/schemas/listApiKeyResponseSchema.ts +15 -0
  270. package/src/api/keys/schemas/revokeApiKeyParamsSchema.ts +5 -0
  271. package/src/api/keys/schemas/revokeApiKeyResponseSchema.ts +5 -0
  272. package/src/api/keys/services/ApiKeyService.spec.ts +553 -0
  273. package/src/api/keys/services/ApiKeyService.ts +306 -0
  274. package/src/api/logs/TODO.md +52 -0
  275. package/src/api/notifications/index.ts +10 -4
  276. package/src/api/parameters/index.ts +9 -30
  277. package/src/api/parameters/primitives/$config.ts +12 -4
  278. package/src/api/parameters/services/ConfigStore.ts +9 -3
  279. package/src/api/users/__tests__/ApiKeys-integration.spec.ts +1035 -0
  280. package/src/api/users/__tests__/ApiKeys.spec.ts +401 -0
  281. package/src/api/users/index.ts +14 -3
  282. package/src/api/users/primitives/$realm.ts +33 -5
  283. package/src/api/users/providers/RealmProvider.ts +1 -12
  284. package/src/api/users/services/SessionService.ts +1 -11
  285. package/src/api/verifications/controllers/VerificationController.ts +2 -0
  286. package/src/api/verifications/index.ts +10 -4
  287. package/src/batch/index.ts +9 -36
  288. package/src/batch/primitives/$batch.ts +0 -8
  289. package/src/batch/providers/BatchProvider.ts +29 -2
  290. package/src/bucket/__tests__/shared.ts +1 -1
  291. package/src/bucket/index.ts +13 -6
  292. package/src/bucket/primitives/$bucket.ts +1 -1
  293. package/src/bucket/providers/LocalFileStorageProvider.ts +1 -1
  294. package/src/bucket/providers/MemoryFileStorageProvider.ts +1 -1
  295. package/src/cache/core/__tests__/shared.ts +30 -0
  296. package/src/cache/core/index.ts +11 -6
  297. package/src/cache/core/primitives/$cache.spec.ts +5 -0
  298. package/src/cache/core/providers/CacheProvider.ts +17 -0
  299. package/src/cache/core/providers/MemoryCacheProvider.ts +300 -1
  300. package/src/cache/redis/__tests__/cache-redis.spec.ts +5 -0
  301. package/src/cache/redis/providers/RedisCacheProvider.ts +9 -0
  302. package/src/cli/apps/AlephaCli.ts +3 -16
  303. package/src/cli/apps/AlephaPackageBuilderCli.ts +10 -2
  304. package/src/cli/atoms/appEntryOptions.ts +13 -0
  305. package/src/cli/atoms/buildOptions.ts +1 -1
  306. package/src/cli/atoms/changelogOptions.ts +1 -1
  307. package/src/cli/commands/build.ts +64 -52
  308. package/src/cli/commands/db.ts +17 -11
  309. package/src/cli/commands/deploy.ts +1 -1
  310. package/src/cli/commands/dev.ts +13 -49
  311. package/src/cli/commands/gen/env.ts +6 -3
  312. package/src/cli/commands/gen/openapi.ts +5 -2
  313. package/src/cli/commands/init.spec.ts +544 -0
  314. package/src/cli/commands/init.ts +101 -58
  315. package/src/cli/commands/lint.ts +8 -2
  316. package/src/cli/commands/typecheck.ts +11 -0
  317. package/src/cli/defineConfig.ts +9 -0
  318. package/src/cli/index.ts +2 -1
  319. package/src/cli/providers/AppEntryProvider.ts +131 -0
  320. package/src/cli/providers/ViteBuildProvider.ts +40 -0
  321. package/src/cli/providers/ViteDevServerProvider.ts +378 -0
  322. package/src/cli/services/AlephaCliUtils.ts +39 -93
  323. package/src/cli/services/PackageManagerUtils.ts +140 -17
  324. package/src/cli/services/ProjectScaffolder.ts +169 -101
  325. package/src/cli/services/ViteUtils.ts +82 -0
  326. package/src/cli/{assets/claudeMd.ts → templates/agentMd.ts} +41 -28
  327. package/src/cli/{assets → templates}/apiHelloControllerTs.ts +2 -1
  328. package/src/cli/{assets → templates}/biomeJson.ts +2 -1
  329. package/src/cli/{assets → templates}/dummySpecTs.ts +2 -1
  330. package/src/cli/{assets → templates}/editorconfig.ts +2 -1
  331. package/src/cli/templates/gitignore.ts +39 -0
  332. package/src/cli/{assets → templates}/mainBrowserTs.ts +2 -1
  333. package/src/cli/templates/mainCss.ts +33 -0
  334. package/src/cli/templates/mainServerTs.ts +33 -0
  335. package/src/cli/{assets → templates}/tsconfigJson.ts +2 -1
  336. package/src/cli/templates/webAppRouterTs.ts +50 -0
  337. package/src/cli/templates/webHelloComponentTsx.ts +20 -0
  338. package/src/command/helpers/Runner.spec.ts +4 -0
  339. package/src/command/helpers/Runner.ts +3 -21
  340. package/src/command/index.ts +12 -4
  341. package/src/command/providers/CliProvider.spec.ts +1067 -0
  342. package/src/command/providers/CliProvider.ts +203 -40
  343. package/src/core/Alepha.ts +3 -9
  344. package/src/core/__tests__/Alepha-start.spec.ts +4 -4
  345. package/src/core/helpers/jsonSchemaToTypeBox.spec.ts +771 -0
  346. package/src/core/helpers/jsonSchemaToTypeBox.ts +62 -10
  347. package/src/core/index.shared.ts +1 -0
  348. package/src/core/index.ts +20 -0
  349. package/src/core/primitives/$module.ts +12 -0
  350. package/src/core/providers/EventManager.spec.ts +0 -71
  351. package/src/core/providers/EventManager.ts +3 -15
  352. package/src/core/providers/Json.ts +2 -14
  353. package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +257 -0
  354. package/src/core/providers/KeylessJsonSchemaCodec.ts +396 -14
  355. package/src/core/providers/SchemaValidator.spec.ts +236 -0
  356. package/src/datetime/index.ts +15 -0
  357. package/src/email/index.ts +10 -5
  358. package/src/email/providers/LocalEmailProvider.spec.ts +1 -1
  359. package/src/email/providers/LocalEmailProvider.ts +1 -1
  360. package/src/fake/__tests__/keyName.example.ts +1 -1
  361. package/src/fake/__tests__/keyName.spec.ts +5 -5
  362. package/src/fake/index.ts +9 -6
  363. package/src/fake/providers/FakeProvider.spec.ts +258 -40
  364. package/src/fake/providers/FakeProvider.ts +133 -19
  365. package/src/lock/core/index.ts +11 -4
  366. package/src/logger/index.ts +17 -66
  367. package/src/logger/providers/PrettyFormatterProvider.ts +0 -9
  368. package/src/mcp/errors/McpError.ts +30 -0
  369. package/src/mcp/index.ts +13 -27
  370. package/src/mcp/transports/SseMcpTransport.ts +6 -7
  371. package/src/orm/__tests__/PostgresProvider.spec.ts +2 -2
  372. package/src/orm/index.browser.ts +2 -2
  373. package/src/orm/index.bun.ts +4 -2
  374. package/src/orm/index.ts +21 -47
  375. package/src/orm/providers/DrizzleKitProvider.ts +3 -5
  376. package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -0
  377. package/src/orm/services/Repository.ts +18 -3
  378. package/src/queue/core/index.ts +14 -6
  379. package/src/react/auth/__tests__/$auth.spec.ts +202 -0
  380. package/src/react/auth/hooks/useAuth.ts +32 -0
  381. package/src/react/auth/index.browser.ts +13 -0
  382. package/src/react/auth/index.shared.ts +2 -0
  383. package/src/react/auth/index.ts +48 -0
  384. package/src/react/auth/providers/ReactAuthProvider.ts +16 -0
  385. package/src/react/auth/services/ReactAuth.ts +135 -0
  386. package/src/react/core/__tests__/Router.spec.tsx +169 -0
  387. package/src/react/core/components/ClientOnly.tsx +49 -0
  388. package/src/react/core/components/ErrorBoundary.tsx +73 -0
  389. package/src/react/core/contexts/AlephaContext.ts +7 -0
  390. package/src/react/core/contexts/AlephaProvider.tsx +42 -0
  391. package/src/react/core/hooks/useAction.browser.spec.tsx +569 -0
  392. package/src/react/core/hooks/useAction.ts +480 -0
  393. package/src/react/core/hooks/useAlepha.ts +26 -0
  394. package/src/react/core/hooks/useClient.ts +17 -0
  395. package/src/react/core/hooks/useEvents.ts +51 -0
  396. package/src/react/core/hooks/useInject.ts +12 -0
  397. package/src/react/core/hooks/useStore.ts +52 -0
  398. package/src/react/core/index.ts +90 -0
  399. package/src/react/form/components/FormState.tsx +17 -0
  400. package/src/react/form/errors/FormValidationError.ts +18 -0
  401. package/src/react/form/hooks/useForm.browser.spec.tsx +366 -0
  402. package/src/react/form/hooks/useForm.ts +47 -0
  403. package/src/react/form/hooks/useFormState.ts +130 -0
  404. package/src/react/form/index.ts +44 -0
  405. package/src/react/form/services/FormModel.ts +614 -0
  406. package/src/react/head/helpers/SeoExpander.spec.ts +203 -0
  407. package/src/react/head/helpers/SeoExpander.ts +142 -0
  408. package/src/react/head/hooks/useHead.spec.tsx +288 -0
  409. package/src/react/head/hooks/useHead.ts +62 -0
  410. package/src/react/head/index.browser.ts +26 -0
  411. package/src/react/head/index.ts +44 -0
  412. package/src/react/head/interfaces/Head.ts +105 -0
  413. package/src/react/head/primitives/$head.ts +25 -0
  414. package/src/react/head/providers/BrowserHeadProvider.browser.spec.ts +196 -0
  415. package/src/react/head/providers/BrowserHeadProvider.ts +212 -0
  416. package/src/react/head/providers/HeadProvider.ts +168 -0
  417. package/src/react/head/providers/ServerHeadProvider.ts +31 -0
  418. package/src/react/i18n/__tests__/integration.spec.tsx +239 -0
  419. package/src/react/i18n/components/Localize.spec.tsx +357 -0
  420. package/src/react/i18n/components/Localize.tsx +35 -0
  421. package/src/react/i18n/hooks/useI18n.browser.spec.tsx +438 -0
  422. package/src/react/i18n/hooks/useI18n.ts +18 -0
  423. package/src/react/i18n/index.ts +41 -0
  424. package/src/react/i18n/primitives/$dictionary.ts +69 -0
  425. package/src/react/i18n/providers/I18nProvider.spec.ts +389 -0
  426. package/src/react/i18n/providers/I18nProvider.ts +278 -0
  427. package/src/react/router/__tests__/page-head-browser.browser.spec.ts +95 -0
  428. package/src/react/router/__tests__/page-head.spec.ts +48 -0
  429. package/src/react/router/__tests__/seo-head.spec.ts +125 -0
  430. package/src/react/router/atoms/ssrManifestAtom.ts +58 -0
  431. package/src/react/router/components/ErrorViewer.tsx +872 -0
  432. package/src/react/router/components/Link.tsx +23 -0
  433. package/src/react/router/components/NestedView.tsx +223 -0
  434. package/src/react/router/components/NotFound.tsx +30 -0
  435. package/src/react/router/constants/PAGE_PRELOAD_KEY.ts +6 -0
  436. package/src/react/router/contexts/RouterLayerContext.ts +12 -0
  437. package/src/react/router/errors/Redirection.ts +28 -0
  438. package/src/react/router/hooks/useActive.ts +52 -0
  439. package/src/react/router/hooks/useQueryParams.ts +63 -0
  440. package/src/react/router/hooks/useRouter.ts +20 -0
  441. package/src/react/router/hooks/useRouterState.ts +11 -0
  442. package/src/react/router/index.browser.ts +45 -0
  443. package/src/react/router/index.shared.ts +19 -0
  444. package/src/react/router/index.ts +142 -0
  445. package/src/react/router/primitives/$page.browser.spec.tsx +851 -0
  446. package/src/react/router/primitives/$page.spec.tsx +708 -0
  447. package/src/react/router/primitives/$page.ts +497 -0
  448. package/src/react/router/providers/ReactBrowserProvider.ts +309 -0
  449. package/src/react/router/providers/ReactBrowserRendererProvider.ts +25 -0
  450. package/src/react/router/providers/ReactBrowserRouterProvider.ts +168 -0
  451. package/src/react/router/providers/ReactPageProvider.ts +726 -0
  452. package/src/react/router/providers/ReactServerProvider.spec.tsx +316 -0
  453. package/src/react/router/providers/ReactServerProvider.ts +558 -0
  454. package/src/react/router/providers/ReactServerTemplateProvider.ts +979 -0
  455. package/src/react/router/providers/SSRManifestProvider.ts +334 -0
  456. package/src/react/router/services/ReactPageServerService.ts +48 -0
  457. package/src/react/router/services/ReactPageService.ts +27 -0
  458. package/src/react/router/services/ReactRouter.ts +262 -0
  459. package/src/react/websocket/hooks/useRoom.tsx +242 -0
  460. package/src/react/websocket/index.ts +7 -0
  461. package/src/redis/__tests__/redis.spec.ts +13 -0
  462. package/src/redis/index.ts +9 -25
  463. package/src/redis/providers/BunRedisProvider.ts +9 -0
  464. package/src/redis/providers/NodeRedisProvider.ts +8 -0
  465. package/src/redis/providers/RedisProvider.ts +16 -0
  466. package/src/retry/index.ts +11 -2
  467. package/src/router/index.ts +15 -0
  468. package/src/scheduler/index.ts +11 -2
  469. package/src/security/__tests__/BasicAuth.spec.ts +2 -0
  470. package/src/security/__tests__/ServerSecurityProvider.spec.ts +13 -5
  471. package/src/security/index.ts +15 -10
  472. package/src/security/interfaces/IssuerResolver.ts +27 -0
  473. package/src/security/primitives/$issuer.ts +55 -0
  474. package/src/security/providers/SecurityProvider.ts +179 -0
  475. package/src/security/providers/ServerBasicAuthProvider.ts +6 -2
  476. package/src/security/providers/ServerSecurityProvider.ts +36 -22
  477. package/src/server/auth/index.ts +12 -7
  478. package/src/server/cache/index.ts +7 -22
  479. package/src/server/compress/index.ts +10 -2
  480. package/src/server/cookies/index.ts +7 -5
  481. package/src/server/cookies/primitives/$cookie.ts +33 -11
  482. package/src/server/core/index.ts +17 -7
  483. package/src/server/core/interfaces/ServerRequest.ts +83 -1
  484. package/src/server/core/primitives/$action.spec.ts +1 -1
  485. package/src/server/core/primitives/$action.ts +8 -3
  486. package/src/server/core/providers/BunHttpServerProvider.ts +1 -1
  487. package/src/server/core/providers/NodeHttpServerProvider.spec.ts +125 -0
  488. package/src/server/core/providers/NodeHttpServerProvider.ts +77 -22
  489. package/src/server/core/providers/ServerLoggerProvider.ts +2 -2
  490. package/src/server/core/providers/ServerProvider.ts +9 -12
  491. package/src/server/core/services/ServerRequestParser.spec.ts +520 -0
  492. package/src/server/core/services/ServerRequestParser.ts +306 -13
  493. package/src/server/cors/index.ts +7 -21
  494. package/src/server/cors/primitives/$cors.ts +6 -2
  495. package/src/server/health/index.ts +8 -2
  496. package/src/server/helmet/index.ts +11 -3
  497. package/src/server/links/atoms/apiLinksAtom.ts +7 -0
  498. package/src/server/links/index.browser.ts +2 -0
  499. package/src/server/links/index.ts +13 -6
  500. package/src/server/metrics/index.ts +10 -3
  501. package/src/server/multipart/index.ts +9 -3
  502. package/src/server/proxy/index.ts +8 -2
  503. package/src/server/rate-limit/index.ts +21 -25
  504. package/src/server/rate-limit/primitives/$rateLimit.ts +6 -2
  505. package/src/server/rate-limit/providers/ServerRateLimitProvider.spec.ts +38 -14
  506. package/src/server/rate-limit/providers/ServerRateLimitProvider.ts +22 -56
  507. package/src/server/static/index.ts +8 -2
  508. package/src/server/static/providers/ServerStaticProvider.ts +1 -1
  509. package/src/server/swagger/index.ts +9 -4
  510. package/src/server/swagger/providers/ServerSwaggerProvider.ts +1 -1
  511. package/src/sms/index.ts +9 -5
  512. package/src/sms/providers/LocalSmsProvider.spec.ts +1 -1
  513. package/src/sms/providers/LocalSmsProvider.ts +1 -1
  514. package/src/system/index.browser.ts +11 -0
  515. package/src/system/index.ts +62 -0
  516. package/src/{file → system}/providers/FileSystemProvider.ts +16 -0
  517. package/src/{file → system}/providers/MemoryFileSystemProvider.ts +116 -3
  518. package/src/system/providers/MemoryShellProvider.ts +164 -0
  519. package/src/{file → system}/providers/NodeFileSystemProvider.spec.ts +2 -2
  520. package/src/{file → system}/providers/NodeFileSystemProvider.ts +36 -0
  521. package/src/system/providers/NodeShellProvider.ts +184 -0
  522. package/src/system/providers/ShellProvider.ts +74 -0
  523. package/src/{file → system}/services/FileDetector.spec.ts +2 -2
  524. package/src/thread/index.ts +11 -2
  525. package/src/topic/core/index.ts +12 -5
  526. package/src/vite/index.ts +3 -2
  527. package/src/vite/tasks/buildClient.ts +2 -8
  528. package/src/vite/tasks/buildServer.ts +84 -21
  529. package/src/vite/tasks/copyAssets.ts +5 -4
  530. package/src/vite/tasks/generateSitemap.ts +64 -23
  531. package/src/vite/tasks/index.ts +0 -2
  532. package/src/vite/tasks/prerenderPages.ts +49 -24
  533. package/src/websocket/index.ts +12 -8
  534. package/dist/file/index.d.ts +0 -839
  535. package/dist/file/index.d.ts.map +0 -1
  536. package/dist/file/index.js.map +0 -1
  537. package/src/cli/assets/indexHtml.ts +0 -15
  538. package/src/cli/assets/mainServerTs.ts +0 -24
  539. package/src/cli/assets/webAppRouterTs.ts +0 -15
  540. package/src/cli/assets/webHelloComponentTsx.ts +0 -16
  541. package/src/cli/commands/format.ts +0 -23
  542. package/src/file/index.ts +0 -43
  543. package/src/vite/helpers/boot.ts +0 -117
  544. package/src/vite/plugins/viteAlephaDev.ts +0 -177
  545. package/src/vite/tasks/devServer.ts +0 -71
  546. package/src/vite/tasks/runAlepha.ts +0 -270
  547. /package/dist/orm/{chunk-DtkW-qnP.js → chunk-DH6iiROE.js} +0 -0
  548. /package/src/cli/{assets → templates}/apiIndexTs.ts +0 -0
  549. /package/src/cli/{assets → templates}/webIndexTs.ts +0 -0
  550. /package/src/{file → system}/errors/FileError.ts +0 -0
  551. /package/src/{file → system}/services/FileDetector.ts +0 -0
@@ -0,0 +1,82 @@
1
+ import { $hook, $inject, type Alepha, AlephaError } from "alepha";
2
+ import { importVite } from "alepha/vite";
3
+ import type { InlineConfig, ViteDevServer } from "vite";
4
+ import { FileSystemProvider } from "../../system/index.ts";
5
+ import type { AppEntry } from "../providers/AppEntryProvider.ts";
6
+
7
+ export class ViteUtils {
8
+ protected readonly fs = $inject(FileSystemProvider);
9
+ protected viteDevServer?: ViteDevServer;
10
+
11
+ public generateIndexHtml(entry: AppEntry): string {
12
+ const style = entry.style;
13
+ const browser = entry.browser ?? entry.server;
14
+ return `
15
+ <!DOCTYPE html>
16
+ <html lang="en">
17
+ <head>
18
+ <meta charset="UTF-8" />
19
+ <title>App</title>
20
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
21
+ ${style ? `<link rel="stylesheet" href="/${style}" />` : ""}
22
+ </head>
23
+ <body>
24
+ <div id="root"></div>
25
+ <script type="module" src="/${browser}"></script>
26
+ </body>
27
+ </html>
28
+ `.trim();
29
+ }
30
+
31
+ /**
32
+ * We need to close the Vite dev server after build is done.
33
+ */
34
+ protected onReady = $hook({
35
+ on: "ready",
36
+ priority: "last",
37
+ handler: async () => {
38
+ await this.viteDevServer?.close();
39
+ },
40
+ });
41
+
42
+ protected onStop = $hook({
43
+ on: "stop",
44
+ handler: async () => {
45
+ await this.viteDevServer?.close();
46
+ },
47
+ });
48
+
49
+ public async runAlepha(opts: {
50
+ entry: AppEntry;
51
+ mode: "production" | "development";
52
+ }): Promise<Alepha> {
53
+ const { createServer } = await importVite();
54
+
55
+ process.env.NODE_ENV = opts.mode;
56
+ process.env.ALEPHA_CLI_IMPORT = "true"; // signal Alepha App about CLI import, run(alepha) won't start server
57
+ process.env.LOG_LEVEL ??= "warn"; // reduce log noise
58
+
59
+ /**
60
+ * 01/26 Vite 7
61
+ * "runnerImport" doesn't work as expected here. (e.g. build docs fail)
62
+ * -> We still use devServer and ssrLoadModule for now.
63
+ * -> This is clearly a bad stuff, we need to find better way.
64
+ */
65
+ this.viteDevServer = await createServer({
66
+ server: { middlewareMode: true },
67
+ appType: "custom",
68
+ logLevel: "silent",
69
+ } satisfies InlineConfig);
70
+
71
+ await this.viteDevServer.ssrLoadModule(opts.entry.server);
72
+
73
+ const alepha: Alepha = (globalThis as any).__alepha;
74
+ if (!alepha) {
75
+ throw new AlephaError(
76
+ "Alepha instance not found after loading entry module",
77
+ );
78
+ }
79
+
80
+ return alepha;
81
+ }
82
+ }
@@ -1,19 +1,33 @@
1
- export interface ClaudeMdOptions {
1
+ export interface AgentMdOptions {
2
2
  react?: boolean;
3
3
  ui?: boolean;
4
4
  projectName?: string;
5
5
  }
6
6
 
7
- export const claudeMd = (options: ClaudeMdOptions = {}) => {
7
+ export type AgentMdType = "claude" | "agents";
8
+
9
+ export const agentMd = (
10
+ type: AgentMdType,
11
+ options: AgentMdOptions = {},
12
+ ): string => {
8
13
  const { react = false, projectName = "my-app" } = options;
9
14
 
15
+ const header =
16
+ type === "claude"
17
+ ? `# CLAUDE.md
18
+
19
+ This file provides guidance to Claude Code when working with this Alepha project.`
20
+ : `# AGENTS.md
21
+
22
+ This file provides guidance to AI coding assistants when working with this Alepha project.`;
23
+
10
24
  const reactSection = react
11
25
  ? `
12
26
  ## React & Frontend
13
27
 
14
28
  ### Pages with \`$page\`
15
29
  \`\`\`tsx
16
- import { $page } from "@alepha/react/router";
30
+ import { $page } from "alepha/react/router";
17
31
  import { $client } from "alepha/server/links";
18
32
  import type { UserController } from "./UserController.ts";
19
33
 
@@ -39,9 +53,9 @@ class AppRouter {
39
53
 
40
54
  ### React Hooks
41
55
  \`\`\`typescript
42
- import { useAlepha, useClient, useStore, useAction, useInject } from "@alepha/react";
43
- import { useRouter, useActive } from "@alepha/react/router";
44
- import { useForm } from "@alepha/react/form";
56
+ import { useAlepha, useClient, useStore, useAction, useInject } from "alepha/react";
57
+ import { useRouter, useActive } from "alepha/react/router";
58
+ import { useForm } from "alepha/react/form";
45
59
  \`\`\`
46
60
 
47
61
  - \`useClient<Controller>()\` - Type-safe API calls
@@ -69,8 +83,8 @@ ${projectName}/
69
83
  │ │ ├── AppRouter.ts # Routes with $page
70
84
  │ │ └── index.ts # Web module definition with $module
71
85
  │ ├── main.server.ts # Server entry
72
- └── main.browser.ts # Browser entry (React only)
73
- ├── index.html # (React only)
86
+ ├── main.browser.ts # Browser entry (React only)
87
+ │ └── main.css # CSS entry (React only)
74
88
  ├── package.json
75
89
  └── tsconfig.json
76
90
  \`\`\`
@@ -91,9 +105,7 @@ ${projectName}/
91
105
  \`\`\`
92
106
  `;
93
107
 
94
- return `# CLAUDE.md
95
-
96
- This file provides guidance to Claude Code when working with this Alepha project.
108
+ return `${header}
97
109
 
98
110
  ## Overview
99
111
 
@@ -107,16 +119,18 @@ This is an **Alepha** project - a convention-driven TypeScript framework for typ
107
119
 
108
120
  ## Rules
109
121
 
110
- - Use TypeScript strict mode
122
+ - Use TypeScript strict mode, always check types (\`alepha typecheck\`)
111
123
  - Use Biome for formatting (\`alepha lint\`)
112
- - Use Vitest for testing
113
- - One file = one class
124
+ - Use Vitest for testing (\`alepha test\`)
125
+ - One file = one class, multiple interfaces/types allowed
114
126
  - Primitives are class properties (except \`$entity\`, \`$atom\`)
115
127
  - No decorators, no Express/Fastify patterns
116
128
  - No manual instantiation - use dependency injection
117
129
  - Use \`protected\` instead of \`private\` for class members
118
130
  - Import with file extensions: \`import { User } from "./User.ts"\`
119
131
  - Use \`t\` from Alepha for schemas (not Zod)
132
+ - Prefer \`t.text()\` over \`t.string()\` for user input (has default max length, auto-trim, supports lowercase option)
133
+ - One file = one schema (schemas/createUserSchema.ts)
120
134
 
121
135
  ## Project Structure
122
136
  ${projectStructure}
@@ -159,17 +173,12 @@ export const userEntity = $entity({
159
173
  id: db.primaryKey(),
160
174
  email: t.email(),
161
175
  createdAt: db.createdAt(),
162
- updatedAt: db.updatedAt(),
163
176
  }),
164
177
  indexes: [{ column: "email", unique: true }],
165
178
  });
166
179
 
167
180
  class UserService {
168
- repo = $repository(userEntity);
169
-
170
- async findById(id: string) {
171
- return this.repo.findById(id);
172
- }
181
+ userRepository = $repository(userEntity);
173
182
  }
174
183
  \`\`\`
175
184
 
@@ -179,11 +188,6 @@ import { $inject } from "alepha";
179
188
 
180
189
  class OrderService {
181
190
  userService = $inject(UserService); // Within same module
182
-
183
- async createOrder(userId: string) {
184
- const user = await this.userService.findById(userId);
185
- // ...
186
- }
187
191
  }
188
192
 
189
193
  // Cross-module: use $client instead of $inject
@@ -246,9 +250,13 @@ ${reactSection}
246
250
  | \`$cache\` | \`alepha/cache\` | Cached computations |
247
251
  | \`$bucket\` | \`alepha/bucket\` | File storage |
248
252
  | \`$issuer\` | \`alepha/security\` | JWT tokens |
249
- | \`$command\` | \`alepha/command\` | CLI commands |${react ? `
250
- | \`$page\` | \`@alepha/react/router\` | React pages with SSR |
251
- | \`$atom\` | \`alepha\` | Global state |` : ""}
253
+ | \`$command\` | \`alepha/command\` | CLI commands |${
254
+ react
255
+ ? `
256
+ | \`$page\` | \`alepha/react/router\` | React pages with SSR |
257
+ | \`$atom\` | \`alepha\` | Global state |`
258
+ : ""
259
+ }
252
260
 
253
261
  ## Testing
254
262
 
@@ -299,5 +307,10 @@ alepha build # Build the project
299
307
 
300
308
  - Full docs: https://alepha.dev/llms.txt
301
309
  - Detailed docs: https://alepha.dev/llms-full.txt
310
+
311
+ ## Source Code Access
312
+
313
+ Full framework source available at \`node_modules/alepha/src/\`.
314
+ Read primitives directly when you need implementation details.
302
315
  `.trim();
303
316
  };
@@ -1,4 +1,5 @@
1
- export const apiHelloControllerTs = () => `
1
+ export const apiHelloControllerTs = () =>
2
+ `
2
3
  import { t } from "alepha";
3
4
  import { $action } from "alepha/server";
4
5
 
@@ -1,4 +1,5 @@
1
- export const biomeJson = `
1
+ export const biomeJson = () =>
2
+ `
2
3
  {
3
4
  "$schema": "https://biomejs.dev/schemas/latest/schema.json",
4
5
  "vcs": {
@@ -1,4 +1,5 @@
1
- export const dummySpecTs = () => `
1
+ export const dummySpecTs = () =>
2
+ `
2
3
  import { test, expect } from "vitest";
3
4
 
4
5
  test("dummy test", () => {
@@ -1,4 +1,5 @@
1
- export const editorconfig = `
1
+ export const editorconfig = () =>
2
+ `
2
3
  # https://editorconfig.org
3
4
 
4
5
  root = true
@@ -0,0 +1,39 @@
1
+ export const gitignore = () =>
2
+ `
3
+ # Dependencies
4
+ node_modules/
5
+
6
+ # Build outputs
7
+ dist/
8
+ .vite/
9
+
10
+ # Environment files
11
+ .env
12
+ .env.*
13
+ !.env.example
14
+
15
+ # IDE
16
+ .idea/
17
+ *.swp
18
+ *.swo
19
+
20
+ # OS
21
+ .DS_Store
22
+ Thumbs.db
23
+
24
+ # Logs
25
+ *.log
26
+ logs/
27
+
28
+ # Test coverage
29
+ coverage/
30
+
31
+ # Yarn
32
+ .yarn/*
33
+ !.yarn/patches
34
+ !.yarn/plugins
35
+ !.yarn/releases
36
+ !.yarn/sdks
37
+ !.yarn/versions
38
+ .pnp.*
39
+ `.trim();
@@ -1,4 +1,5 @@
1
- export const mainBrowserTs = () => `
1
+ export const mainBrowserTs = () =>
2
+ `
2
3
  import { Alepha, run } from "alepha";
3
4
  import { WebModule } from "./web/index.ts";
4
5
 
@@ -0,0 +1,33 @@
1
+ export interface MainCssOptions {
2
+ ui?: boolean;
3
+ }
4
+
5
+ export const mainCss = (options: MainCssOptions = {}) => {
6
+ if (options.ui) {
7
+ return `@import "@alepha/ui/styles";`;
8
+ }
9
+
10
+ return `
11
+ * {
12
+ box-sizing: border-box;
13
+ margin: 0;
14
+ padding: 0;
15
+ }
16
+
17
+ html,
18
+ body {
19
+ height: 100%;
20
+ }
21
+
22
+ body {
23
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
24
+ "Helvetica Neue", Arial, sans-serif;
25
+ line-height: 1.5;
26
+ -webkit-font-smoothing: antialiased;
27
+ }
28
+
29
+ #root {
30
+ height: 100%;
31
+ }
32
+ `.trim();
33
+ };
@@ -0,0 +1,33 @@
1
+ export interface MainServerTsOptions {
2
+ api?: boolean;
3
+ react?: boolean;
4
+ }
5
+
6
+ export const mainServerTs = (options: MainServerTsOptions = {}) => {
7
+ const { api = false, react = false } = options;
8
+
9
+ const imports: string[] = [];
10
+ const withs: string[] = [];
11
+
12
+ if (api) {
13
+ imports.push(`import { ApiModule } from "./api/index.ts";`);
14
+ withs.push(`alepha.with(ApiModule);`);
15
+ }
16
+
17
+ if (react) {
18
+ imports.push(`import { WebModule } from "./web/index.ts";`);
19
+ withs.push(`alepha.with(WebModule);`);
20
+ }
21
+
22
+ const importsBlock = imports.length > 0 ? `${imports.join("\n")}\n` : "";
23
+ const withsBlock = withs.length > 0 ? `\n${withs.join("\n")}` : "";
24
+
25
+ return `
26
+ import { Alepha, run } from "alepha";
27
+ ${importsBlock}
28
+ const alepha = Alepha.create();
29
+ ${withsBlock}
30
+
31
+ run(alepha);
32
+ `.trim();
33
+ };
@@ -1,4 +1,5 @@
1
- export const tsconfigJson = `
1
+ export const tsconfigJson = () =>
2
+ `
2
3
  {
3
4
  "extends": "alepha/tsconfig.base"
4
5
  }
@@ -0,0 +1,50 @@
1
+ export const webAppRouterTs = (options: { api?: boolean; ui?: boolean }) => {
2
+ const imports: string[] = [];
3
+ const classMembers: string[] = [];
4
+
5
+ // UI import and setup
6
+ if (options.ui) {
7
+ imports.push('import { $ui } from "@alepha/ui";');
8
+ }
9
+
10
+ // Page import
11
+ imports.push('import { $page } from "alepha/react/router";');
12
+
13
+ // API imports (only if api flag is set)
14
+ if (options.api) {
15
+ imports.push('import { $client } from "alepha/server/links";');
16
+ imports.push(
17
+ 'import type { HelloController } from "../api/controllers/HelloController.ts";',
18
+ );
19
+ classMembers.push(" api = $client<HelloController>();");
20
+ }
21
+
22
+ // UI layout setup
23
+ if (options.ui) {
24
+ classMembers.push(" ui = $ui();");
25
+ classMembers.push(` layout = $page({
26
+ parent: this.ui.root,
27
+ children: () => [this.home],
28
+ });`);
29
+ }
30
+
31
+ // Home page - with or without loader
32
+ if (options.api) {
33
+ classMembers.push(` home = $page({
34
+ path: "/",
35
+ lazy: () => import("./components/Hello.tsx"),
36
+ loader: () => this.api.hello(),
37
+ });`);
38
+ } else {
39
+ classMembers.push(` home = $page({
40
+ path: "/",
41
+ lazy: () => import("./components/Hello.tsx"),
42
+ });`);
43
+ }
44
+
45
+ return `${imports.join("\n")}
46
+
47
+ export class AppRouter {
48
+ ${classMembers.join("\n\n")}
49
+ }`;
50
+ };
@@ -0,0 +1,20 @@
1
+ export const webHelloComponentTsx = () =>
2
+ `import { useState } from "react";
3
+
4
+ interface Props {
5
+ message?: string;
6
+ }
7
+
8
+ const Hello = (props: Props) => {
9
+ const [message, setMessage] = useState(props.message ?? "");
10
+ return (
11
+ <div>
12
+ <h1>{message}</h1>
13
+ <input value={message} onChange={e => setMessage(e.target.value)} />
14
+ <p>Edit this component in src/web/components/Hello.tsx</p>
15
+ </div>
16
+ );
17
+ };
18
+
19
+ export default Hello;
20
+ `.trim();
@@ -3,11 +3,13 @@ import {
3
3
  LogDestinationProvider,
4
4
  MemoryDestinationProvider,
5
5
  } from "alepha/logger";
6
+ import { MemoryShellProvider } from "alepha/system";
6
7
  import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
7
8
  import { Runner } from "../index.ts";
8
9
 
9
10
  describe("Runner", () => {
10
11
  let mockLogger: MemoryDestinationProvider;
12
+ let mockShell: MemoryShellProvider;
11
13
  let runner: Runner;
12
14
 
13
15
  beforeEach(async () => {
@@ -22,6 +24,7 @@ describe("Runner", () => {
22
24
  // Create a new MockLogger and Runner for each test to ensure isolation
23
25
  runner = alepha.inject(Runner);
24
26
  mockLogger = alepha.inject(MemoryDestinationProvider);
27
+ mockShell = alepha.inject(MemoryShellProvider);
25
28
  });
26
29
 
27
30
  afterEach(() => {
@@ -91,6 +94,7 @@ describe("Runner", () => {
91
94
  });
92
95
 
93
96
  test("should throw and log an error for a failing shell command", async () => {
97
+ mockShell.errors.set("exit 1", "Command failed with exit code 1");
94
98
  await expect(runner.run(`exit 1`)).rejects.toThrow("Task 'exit 1' failed");
95
99
  });
96
100
 
@@ -1,7 +1,7 @@
1
- import { exec } from "node:child_process";
2
1
  import { cp, glob, rm } from "node:fs/promises";
3
2
  import { $inject, Alepha } from "alepha";
4
3
  import { $logger } from "alepha/logger";
4
+ import { ShellProvider } from "alepha/system";
5
5
  import { CommandError } from "../errors/CommandError.ts";
6
6
  import { PrettyPrint } from "./PrettyPrint.ts";
7
7
 
@@ -42,6 +42,7 @@ export class Runner {
42
42
  protected readonly startTime: number = Date.now();
43
43
  protected readonly prettyPrint = $inject(PrettyPrint);
44
44
  protected readonly alepha = $inject(Alepha);
45
+ protected readonly shell = $inject(ShellProvider);
45
46
  public readonly run: RunnerMethod;
46
47
  protected cliName = "";
47
48
  protected commandName = "";
@@ -152,26 +153,7 @@ export class Runner {
152
153
  cmd: string,
153
154
  opts: { root?: string } = {},
154
155
  ): Promise<string> {
155
- return await new Promise<string>((resolve, reject) => {
156
- exec(
157
- cmd,
158
- {
159
- cwd: opts.root,
160
- env: {
161
- ...process.env,
162
- LOG_FORMAT: "pretty",
163
- },
164
- },
165
- (err, stdout) => {
166
- if (err) {
167
- err.stdout = stdout;
168
- reject(err);
169
- } else {
170
- resolve(stdout);
171
- }
172
- },
173
- );
174
- });
156
+ return this.shell.run(cmd, { root: opts.root, capture: true });
175
157
  }
176
158
 
177
159
  /**
@@ -19,12 +19,20 @@ export * from "./providers/CliProvider.ts";
19
19
  // ---------------------------------------------------------------------------------------------------------------------
20
20
 
21
21
  /**
22
- * This module provides a powerful way to build command-line interfaces
23
- * directly within your Alepha application, using declarative primitives.
22
+ * | type | quality | stability |
23
+ * |------|---------|-----------|
24
+ * | tooling | rare | stable |
24
25
  *
25
- * It allows you to define commands using the `$command` primitive.
26
+ * Declarative CLI command framework.
27
+ *
28
+ * **Features:**
29
+ * - CLI command definitions
30
+ * - Interactive CLI prompts
31
+ * - Command execution
32
+ * - Formatted colored output
33
+ * - Environment variable utilities
34
+ * - Schema validation for CLI arguments
26
35
  *
27
- * @see {@link $command}
28
36
  * @module alepha.command
29
37
  */
30
38
  export const AlephaCommand = $module({