alepha 0.15.1 → 0.15.3

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 (523) hide show
  1. package/README.md +68 -80
  2. package/dist/api/audits/index.d.ts +10 -33
  3. package/dist/api/audits/index.d.ts.map +1 -1
  4. package/dist/api/audits/index.js +10 -33
  5. package/dist/api/audits/index.js.map +1 -1
  6. package/dist/api/files/index.d.ts +10 -3
  7. package/dist/api/files/index.d.ts.map +1 -1
  8. package/dist/api/files/index.js +10 -3
  9. package/dist/api/files/index.js.map +1 -1
  10. package/dist/api/jobs/index.d.ts +162 -155
  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.d.ts +10 -4
  19. package/dist/api/notifications/index.d.ts.map +1 -1
  20. package/dist/api/notifications/index.js +10 -4
  21. package/dist/api/notifications/index.js.map +1 -1
  22. package/dist/api/parameters/index.d.ts +43 -50
  23. package/dist/api/parameters/index.d.ts.map +1 -1
  24. package/dist/api/parameters/index.js +30 -37
  25. package/dist/api/parameters/index.js.map +1 -1
  26. package/dist/api/users/index.d.ts +1081 -760
  27. package/dist/api/users/index.d.ts.map +1 -1
  28. package/dist/api/users/index.js +2539 -218
  29. package/dist/api/users/index.js.map +1 -1
  30. package/dist/api/verifications/index.d.ts +138 -132
  31. package/dist/api/verifications/index.d.ts.map +1 -1
  32. package/dist/api/verifications/index.js +12 -4
  33. package/dist/api/verifications/index.js.map +1 -1
  34. package/dist/batch/index.d.ts +20 -40
  35. package/dist/batch/index.d.ts.map +1 -1
  36. package/dist/batch/index.js +31 -44
  37. package/dist/batch/index.js.map +1 -1
  38. package/dist/bucket/index.d.ts +440 -8
  39. package/dist/bucket/index.d.ts.map +1 -1
  40. package/dist/bucket/index.js +1861 -12
  41. package/dist/bucket/index.js.map +1 -1
  42. package/dist/cache/core/index.d.ts +179 -7
  43. package/dist/cache/core/index.d.ts.map +1 -1
  44. package/dist/cache/core/index.js +213 -7
  45. package/dist/cache/core/index.js.map +1 -1
  46. package/dist/cache/redis/index.d.ts +1 -0
  47. package/dist/cache/redis/index.d.ts.map +1 -1
  48. package/dist/cache/redis/index.js +4 -0
  49. package/dist/cache/redis/index.js.map +1 -1
  50. package/dist/cli/index.d.ts +638 -5645
  51. package/dist/cli/index.d.ts.map +1 -1
  52. package/dist/cli/index.js +2550 -368
  53. package/dist/cli/index.js.map +1 -1
  54. package/dist/command/index.d.ts +203 -45
  55. package/dist/command/index.d.ts.map +1 -1
  56. package/dist/command/index.js +2060 -71
  57. package/dist/command/index.js.map +1 -1
  58. package/dist/core/index.browser.js +70 -40
  59. package/dist/core/index.browser.js.map +1 -1
  60. package/dist/core/index.d.ts +34 -13
  61. package/dist/core/index.d.ts.map +1 -1
  62. package/dist/core/index.js +90 -40
  63. package/dist/core/index.js.map +1 -1
  64. package/dist/core/index.native.js +70 -40
  65. package/dist/core/index.native.js.map +1 -1
  66. package/dist/datetime/index.d.ts +15 -0
  67. package/dist/datetime/index.d.ts.map +1 -1
  68. package/dist/datetime/index.js +15 -0
  69. package/dist/datetime/index.js.map +1 -1
  70. package/dist/email/index.d.ts +323 -20
  71. package/dist/email/index.d.ts.map +1 -1
  72. package/dist/email/index.js +1857 -7
  73. package/dist/email/index.js.map +1 -1
  74. package/dist/fake/index.d.ts +90 -8
  75. package/dist/fake/index.d.ts.map +1 -1
  76. package/dist/fake/index.js +91 -20
  77. package/dist/fake/index.js.map +1 -1
  78. package/dist/lock/core/index.d.ts +11 -4
  79. package/dist/lock/core/index.d.ts.map +1 -1
  80. package/dist/lock/core/index.js +11 -4
  81. package/dist/lock/core/index.js.map +1 -1
  82. package/dist/logger/index.d.ts +17 -66
  83. package/dist/logger/index.d.ts.map +1 -1
  84. package/dist/logger/index.js +14 -63
  85. package/dist/logger/index.js.map +1 -1
  86. package/dist/mcp/index.d.ts +10 -30
  87. package/dist/mcp/index.d.ts.map +1 -1
  88. package/dist/mcp/index.js +12 -35
  89. package/dist/mcp/index.js.map +1 -1
  90. package/dist/orm/index.browser.js +3 -3
  91. package/dist/orm/index.browser.js.map +1 -1
  92. package/dist/orm/index.bun.js +39 -20
  93. package/dist/orm/index.bun.js.map +1 -1
  94. package/dist/orm/index.d.ts +517 -540
  95. package/dist/orm/index.d.ts.map +1 -1
  96. package/dist/orm/index.js +58 -71
  97. package/dist/orm/index.js.map +1 -1
  98. package/dist/queue/core/index.d.ts +18 -10
  99. package/dist/queue/core/index.d.ts.map +1 -1
  100. package/dist/queue/core/index.js +14 -6
  101. package/dist/queue/core/index.js.map +1 -1
  102. package/dist/react/auth/index.browser.js +108 -0
  103. package/dist/react/auth/index.browser.js.map +1 -0
  104. package/dist/react/auth/index.d.ts +100 -0
  105. package/dist/react/auth/index.d.ts.map +1 -0
  106. package/dist/react/auth/index.js +145 -0
  107. package/dist/react/auth/index.js.map +1 -0
  108. package/dist/react/core/index.d.ts +469 -0
  109. package/dist/react/core/index.d.ts.map +1 -0
  110. package/dist/react/core/index.js +464 -0
  111. package/dist/react/core/index.js.map +1 -0
  112. package/dist/react/form/index.d.ts +232 -0
  113. package/dist/react/form/index.d.ts.map +1 -0
  114. package/dist/react/form/index.js +432 -0
  115. package/dist/react/form/index.js.map +1 -0
  116. package/dist/react/head/index.browser.js +423 -0
  117. package/dist/react/head/index.browser.js.map +1 -0
  118. package/dist/react/head/index.d.ts +288 -0
  119. package/dist/react/head/index.d.ts.map +1 -0
  120. package/dist/react/head/index.js +465 -0
  121. package/dist/react/head/index.js.map +1 -0
  122. package/dist/react/i18n/index.d.ts +175 -0
  123. package/dist/react/i18n/index.d.ts.map +1 -0
  124. package/dist/react/i18n/index.js +224 -0
  125. package/dist/react/i18n/index.js.map +1 -0
  126. package/dist/react/router/index.browser.js +1974 -0
  127. package/dist/react/router/index.browser.js.map +1 -0
  128. package/dist/react/router/index.d.ts +1956 -0
  129. package/dist/react/router/index.d.ts.map +1 -0
  130. package/dist/react/router/index.js +4722 -0
  131. package/dist/react/router/index.js.map +1 -0
  132. package/dist/react/websocket/index.d.ts +117 -0
  133. package/dist/react/websocket/index.d.ts.map +1 -0
  134. package/dist/react/websocket/index.js +107 -0
  135. package/dist/react/websocket/index.js.map +1 -0
  136. package/dist/redis/index.bun.js +4 -0
  137. package/dist/redis/index.bun.js.map +1 -1
  138. package/dist/redis/index.d.ts +41 -44
  139. package/dist/redis/index.d.ts.map +1 -1
  140. package/dist/redis/index.js +16 -25
  141. package/dist/redis/index.js.map +1 -1
  142. package/dist/retry/index.d.ts +11 -2
  143. package/dist/retry/index.d.ts.map +1 -1
  144. package/dist/retry/index.js +11 -2
  145. package/dist/retry/index.js.map +1 -1
  146. package/dist/scheduler/index.d.ts +11 -2
  147. package/dist/scheduler/index.d.ts.map +1 -1
  148. package/dist/scheduler/index.js +11 -2
  149. package/dist/scheduler/index.js.map +1 -1
  150. package/dist/security/index.d.ts +140 -49
  151. package/dist/security/index.d.ts.map +1 -1
  152. package/dist/security/index.js +164 -32
  153. package/dist/security/index.js.map +1 -1
  154. package/dist/server/auth/index.d.ts +12 -7
  155. package/dist/server/auth/index.d.ts.map +1 -1
  156. package/dist/server/auth/index.js +12 -7
  157. package/dist/server/auth/index.js.map +1 -1
  158. package/dist/server/cache/index.d.ts +7 -22
  159. package/dist/server/cache/index.d.ts.map +1 -1
  160. package/dist/server/cache/index.js +7 -22
  161. package/dist/server/cache/index.js.map +1 -1
  162. package/dist/server/compress/index.d.ts +10 -2
  163. package/dist/server/compress/index.d.ts.map +1 -1
  164. package/dist/server/compress/index.js +10 -2
  165. package/dist/server/compress/index.js.map +1 -1
  166. package/dist/server/cookies/index.d.ts +40 -16
  167. package/dist/server/cookies/index.d.ts.map +1 -1
  168. package/dist/server/cookies/index.js +7 -5
  169. package/dist/server/cookies/index.js.map +1 -1
  170. package/dist/server/core/index.d.ts +124 -23
  171. package/dist/server/core/index.d.ts.map +1 -1
  172. package/dist/server/core/index.js +231 -14
  173. package/dist/server/core/index.js.map +1 -1
  174. package/dist/server/cors/index.d.ts +13 -23
  175. package/dist/server/cors/index.d.ts.map +1 -1
  176. package/dist/server/cors/index.js +7 -21
  177. package/dist/server/cors/index.js.map +1 -1
  178. package/dist/server/health/index.d.ts +8 -2
  179. package/dist/server/health/index.d.ts.map +1 -1
  180. package/dist/server/health/index.js +8 -2
  181. package/dist/server/health/index.js.map +1 -1
  182. package/dist/server/helmet/index.d.ts +11 -3
  183. package/dist/server/helmet/index.d.ts.map +1 -1
  184. package/dist/server/helmet/index.js +11 -3
  185. package/dist/server/helmet/index.js.map +1 -1
  186. package/dist/server/links/index.d.ts +11 -6
  187. package/dist/server/links/index.d.ts.map +1 -1
  188. package/dist/server/links/index.js +11 -6
  189. package/dist/server/links/index.js.map +1 -1
  190. package/dist/server/metrics/index.d.ts +10 -3
  191. package/dist/server/metrics/index.d.ts.map +1 -1
  192. package/dist/server/metrics/index.js +10 -3
  193. package/dist/server/metrics/index.js.map +1 -1
  194. package/dist/server/multipart/index.d.ts +9 -3
  195. package/dist/server/multipart/index.d.ts.map +1 -1
  196. package/dist/server/multipart/index.js +9 -3
  197. package/dist/server/multipart/index.js.map +1 -1
  198. package/dist/server/proxy/index.d.ts +8 -2
  199. package/dist/server/proxy/index.d.ts.map +1 -1
  200. package/dist/server/proxy/index.js +8 -2
  201. package/dist/server/proxy/index.js.map +1 -1
  202. package/dist/server/rate-limit/index.d.ts +30 -35
  203. package/dist/server/rate-limit/index.d.ts.map +1 -1
  204. package/dist/server/rate-limit/index.js +18 -55
  205. package/dist/server/rate-limit/index.js.map +1 -1
  206. package/dist/server/static/index.d.ts +137 -4
  207. package/dist/server/static/index.d.ts.map +1 -1
  208. package/dist/server/static/index.js +1853 -5
  209. package/dist/server/static/index.js.map +1 -1
  210. package/dist/server/swagger/index.d.ts +309 -6
  211. package/dist/server/swagger/index.d.ts.map +1 -1
  212. package/dist/server/swagger/index.js +1854 -6
  213. package/dist/server/swagger/index.js.map +1 -1
  214. package/dist/sms/index.d.ts +309 -7
  215. package/dist/sms/index.d.ts.map +1 -1
  216. package/dist/sms/index.js +1856 -7
  217. package/dist/sms/index.js.map +1 -1
  218. package/dist/system/index.browser.js +1218 -0
  219. package/dist/system/index.browser.js.map +1 -0
  220. package/dist/{file → system}/index.d.ts +343 -16
  221. package/dist/system/index.d.ts.map +1 -0
  222. package/dist/{file → system}/index.js +419 -22
  223. package/dist/system/index.js.map +1 -0
  224. package/dist/thread/index.d.ts +11 -2
  225. package/dist/thread/index.d.ts.map +1 -1
  226. package/dist/thread/index.js +11 -2
  227. package/dist/thread/index.js.map +1 -1
  228. package/dist/topic/core/index.d.ts +12 -5
  229. package/dist/topic/core/index.d.ts.map +1 -1
  230. package/dist/topic/core/index.js +12 -5
  231. package/dist/topic/core/index.js.map +1 -1
  232. package/dist/vite/index.d.ts +5 -6272
  233. package/dist/vite/index.d.ts.map +1 -1
  234. package/dist/vite/index.js +23 -10
  235. package/dist/vite/index.js.map +1 -1
  236. package/dist/websocket/index.d.ts +12 -8
  237. package/dist/websocket/index.d.ts.map +1 -1
  238. package/dist/websocket/index.js +12 -8
  239. package/dist/websocket/index.js.map +1 -1
  240. package/package.json +82 -11
  241. package/src/api/audits/index.ts +10 -33
  242. package/src/api/files/__tests__/$bucket.spec.ts +1 -1
  243. package/src/api/files/controllers/AdminFileStatsController.spec.ts +1 -1
  244. package/src/api/files/controllers/FileController.spec.ts +1 -1
  245. package/src/api/files/index.ts +10 -3
  246. package/src/api/files/jobs/FileJobs.spec.ts +1 -1
  247. package/src/api/files/services/FileService.spec.ts +1 -1
  248. package/src/api/jobs/index.ts +10 -3
  249. package/src/api/keys/controllers/AdminApiKeyController.ts +75 -0
  250. package/src/api/keys/controllers/ApiKeyController.ts +103 -0
  251. package/src/api/keys/entities/apiKeyEntity.ts +41 -0
  252. package/src/api/keys/index.ts +49 -0
  253. package/src/api/keys/schemas/adminApiKeyQuerySchema.ts +7 -0
  254. package/src/api/keys/schemas/adminApiKeyResourceSchema.ts +17 -0
  255. package/src/api/keys/schemas/createApiKeyBodySchema.ts +7 -0
  256. package/src/api/keys/schemas/createApiKeyResponseSchema.ts +11 -0
  257. package/src/api/keys/schemas/listApiKeyResponseSchema.ts +15 -0
  258. package/src/api/keys/schemas/revokeApiKeyParamsSchema.ts +5 -0
  259. package/src/api/keys/schemas/revokeApiKeyResponseSchema.ts +5 -0
  260. package/src/api/keys/services/ApiKeyService.spec.ts +553 -0
  261. package/src/api/keys/services/ApiKeyService.ts +306 -0
  262. package/src/api/logs/TODO.md +55 -0
  263. package/src/api/notifications/index.ts +10 -4
  264. package/src/api/parameters/index.ts +9 -30
  265. package/src/api/parameters/primitives/$config.ts +12 -4
  266. package/src/api/parameters/services/ConfigStore.ts +9 -3
  267. package/src/api/users/__tests__/ApiKeys-integration.spec.ts +1035 -0
  268. package/src/api/users/__tests__/ApiKeys.spec.ts +401 -0
  269. package/src/api/users/index.ts +14 -3
  270. package/src/api/users/primitives/$realm.ts +33 -5
  271. package/src/api/users/providers/RealmProvider.ts +1 -12
  272. package/src/api/users/services/SessionService.ts +1 -1
  273. package/src/api/verifications/controllers/VerificationController.ts +2 -0
  274. package/src/api/verifications/index.ts +10 -4
  275. package/src/batch/index.ts +9 -36
  276. package/src/batch/primitives/$batch.ts +0 -8
  277. package/src/batch/providers/BatchProvider.ts +29 -2
  278. package/src/bucket/__tests__/shared.ts +1 -1
  279. package/src/bucket/index.ts +13 -6
  280. package/src/bucket/primitives/$bucket.ts +1 -1
  281. package/src/bucket/providers/LocalFileStorageProvider.ts +1 -1
  282. package/src/bucket/providers/MemoryFileStorageProvider.ts +1 -1
  283. package/src/cache/core/__tests__/shared.ts +30 -0
  284. package/src/cache/core/index.ts +11 -6
  285. package/src/cache/core/primitives/$cache.spec.ts +5 -0
  286. package/src/cache/core/providers/CacheProvider.ts +17 -0
  287. package/src/cache/core/providers/MemoryCacheProvider.ts +300 -1
  288. package/src/cache/redis/__tests__/cache-redis.spec.ts +5 -0
  289. package/src/cache/redis/providers/RedisCacheProvider.ts +9 -0
  290. package/src/cli/apps/AlephaCli.ts +1 -14
  291. package/src/cli/apps/AlephaPackageBuilderCli.ts +10 -1
  292. package/src/cli/atoms/buildOptions.ts +99 -9
  293. package/src/cli/commands/build.ts +150 -37
  294. package/src/cli/commands/db.ts +22 -18
  295. package/src/cli/commands/deploy.ts +1 -1
  296. package/src/cli/commands/dev.ts +1 -20
  297. package/src/cli/commands/gen/env.ts +5 -2
  298. package/src/cli/commands/gen/openapi.ts +5 -2
  299. package/src/cli/commands/init.spec.ts +588 -0
  300. package/src/cli/commands/init.ts +115 -58
  301. package/src/cli/commands/lint.ts +7 -1
  302. package/src/cli/commands/typecheck.ts +11 -0
  303. package/src/cli/providers/AppEntryProvider.ts +1 -1
  304. package/src/cli/providers/ViteBuildProvider.ts +8 -50
  305. package/src/cli/providers/ViteDevServerProvider.ts +35 -16
  306. package/src/cli/services/AlephaCliUtils.ts +52 -121
  307. package/src/cli/services/PackageManagerUtils.ts +129 -11
  308. package/src/cli/services/ProjectScaffolder.spec.ts +97 -0
  309. package/src/cli/services/ProjectScaffolder.ts +148 -81
  310. package/src/cli/services/ViteUtils.ts +82 -0
  311. package/src/cli/{assets/claudeMd.ts → templates/agentMd.ts} +37 -24
  312. package/src/cli/templates/apiAppSecurityTs.ts +11 -0
  313. package/src/cli/templates/apiIndexTs.ts +30 -0
  314. package/src/cli/templates/gitignore.ts +39 -0
  315. package/src/cli/{assets → templates}/mainCss.ts +11 -2
  316. package/src/cli/templates/mainServerTs.ts +33 -0
  317. package/src/cli/templates/webAppRouterTs.ts +74 -0
  318. package/src/cli/templates/webHelloComponentTsx.ts +30 -0
  319. package/src/command/helpers/Runner.spec.ts +139 -0
  320. package/src/command/helpers/Runner.ts +7 -22
  321. package/src/command/index.ts +12 -4
  322. package/src/command/providers/CliProvider.spec.ts +1392 -0
  323. package/src/command/providers/CliProvider.ts +320 -47
  324. package/src/core/Alepha.ts +34 -27
  325. package/src/core/__tests__/Alepha-start.spec.ts +4 -4
  326. package/src/core/helpers/jsonSchemaToTypeBox.spec.ts +771 -0
  327. package/src/core/helpers/jsonSchemaToTypeBox.ts +62 -10
  328. package/src/core/index.shared.ts +1 -0
  329. package/src/core/index.ts +20 -0
  330. package/src/core/providers/EventManager.spec.ts +0 -71
  331. package/src/core/providers/EventManager.ts +3 -15
  332. package/src/core/providers/Json.ts +2 -14
  333. package/src/datetime/index.ts +15 -0
  334. package/src/email/index.ts +10 -5
  335. package/src/email/providers/LocalEmailProvider.spec.ts +1 -1
  336. package/src/email/providers/LocalEmailProvider.ts +1 -1
  337. package/src/fake/__tests__/keyName.example.ts +1 -1
  338. package/src/fake/__tests__/keyName.spec.ts +5 -5
  339. package/src/fake/index.ts +9 -6
  340. package/src/fake/providers/FakeProvider.spec.ts +258 -40
  341. package/src/fake/providers/FakeProvider.ts +133 -19
  342. package/src/lock/core/index.ts +11 -4
  343. package/src/logger/index.ts +17 -66
  344. package/src/mcp/index.ts +10 -27
  345. package/src/mcp/transports/SseMcpTransport.ts +0 -11
  346. package/src/orm/__tests__/PostgresProvider.spec.ts +2 -2
  347. package/src/orm/index.browser.ts +2 -2
  348. package/src/orm/index.bun.ts +5 -3
  349. package/src/orm/index.ts +23 -53
  350. package/src/orm/providers/drivers/BunSqliteProvider.ts +5 -1
  351. package/src/orm/providers/drivers/CloudflareD1Provider.ts +57 -30
  352. package/src/orm/providers/drivers/DatabaseProvider.ts +9 -1
  353. package/src/orm/providers/drivers/NodeSqliteProvider.ts +4 -1
  354. package/src/orm/services/Repository.ts +7 -3
  355. package/src/queue/core/index.ts +14 -6
  356. package/src/react/auth/__tests__/$auth.spec.ts +202 -0
  357. package/src/react/auth/hooks/useAuth.ts +32 -0
  358. package/src/react/auth/index.browser.ts +13 -0
  359. package/src/react/auth/index.shared.ts +2 -0
  360. package/src/react/auth/index.ts +48 -0
  361. package/src/react/auth/providers/ReactAuthProvider.ts +16 -0
  362. package/src/react/auth/services/ReactAuth.ts +135 -0
  363. package/src/react/core/__tests__/Router.spec.tsx +169 -0
  364. package/src/react/core/components/ClientOnly.tsx +49 -0
  365. package/src/react/core/components/ErrorBoundary.tsx +73 -0
  366. package/src/react/core/contexts/AlephaContext.ts +7 -0
  367. package/src/react/core/contexts/AlephaProvider.tsx +42 -0
  368. package/src/react/core/hooks/useAction.browser.spec.tsx +569 -0
  369. package/src/react/core/hooks/useAction.ts +480 -0
  370. package/src/react/core/hooks/useAlepha.ts +26 -0
  371. package/src/react/core/hooks/useClient.ts +17 -0
  372. package/src/react/core/hooks/useEvents.ts +51 -0
  373. package/src/react/core/hooks/useInject.ts +12 -0
  374. package/src/react/core/hooks/useStore.ts +52 -0
  375. package/src/react/core/index.ts +90 -0
  376. package/src/react/form/components/FormState.tsx +17 -0
  377. package/src/react/form/errors/FormValidationError.ts +18 -0
  378. package/src/react/form/hooks/useForm.browser.spec.tsx +366 -0
  379. package/src/react/form/hooks/useForm.ts +47 -0
  380. package/src/react/form/hooks/useFormState.ts +130 -0
  381. package/src/react/form/index.ts +44 -0
  382. package/src/react/form/services/FormModel.ts +614 -0
  383. package/src/react/head/helpers/SeoExpander.spec.ts +203 -0
  384. package/src/react/head/helpers/SeoExpander.ts +142 -0
  385. package/src/react/head/hooks/useHead.spec.tsx +288 -0
  386. package/src/react/head/hooks/useHead.ts +62 -0
  387. package/src/react/head/index.browser.ts +26 -0
  388. package/src/react/head/index.ts +44 -0
  389. package/src/react/head/interfaces/Head.ts +105 -0
  390. package/src/react/head/primitives/$head.ts +25 -0
  391. package/src/react/head/providers/BrowserHeadProvider.browser.spec.ts +196 -0
  392. package/src/react/head/providers/BrowserHeadProvider.ts +212 -0
  393. package/src/react/head/providers/HeadProvider.ts +168 -0
  394. package/src/react/head/providers/ServerHeadProvider.ts +31 -0
  395. package/src/react/i18n/__tests__/integration.spec.tsx +239 -0
  396. package/src/react/i18n/components/Localize.spec.tsx +357 -0
  397. package/src/react/i18n/components/Localize.tsx +35 -0
  398. package/src/react/i18n/hooks/useI18n.browser.spec.tsx +438 -0
  399. package/src/react/i18n/hooks/useI18n.ts +18 -0
  400. package/src/react/i18n/index.ts +41 -0
  401. package/src/react/i18n/primitives/$dictionary.ts +69 -0
  402. package/src/react/i18n/providers/I18nProvider.spec.ts +389 -0
  403. package/src/react/i18n/providers/I18nProvider.ts +278 -0
  404. package/src/react/router/__tests__/page-head-browser.browser.spec.ts +95 -0
  405. package/src/react/router/__tests__/page-head.spec.ts +48 -0
  406. package/src/react/router/__tests__/seo-head.spec.ts +125 -0
  407. package/src/react/router/atoms/ssrManifestAtom.ts +58 -0
  408. package/src/react/router/components/ErrorViewer.tsx +872 -0
  409. package/src/react/router/components/Link.tsx +23 -0
  410. package/src/react/router/components/NestedView.tsx +223 -0
  411. package/src/react/router/components/NotFound.tsx +30 -0
  412. package/src/react/router/constants/PAGE_PRELOAD_KEY.ts +6 -0
  413. package/src/react/router/contexts/RouterLayerContext.ts +12 -0
  414. package/src/react/router/errors/Redirection.ts +28 -0
  415. package/src/react/router/hooks/useActive.ts +52 -0
  416. package/src/react/router/hooks/useQueryParams.ts +63 -0
  417. package/src/react/router/hooks/useRouter.ts +20 -0
  418. package/src/react/router/hooks/useRouterState.ts +11 -0
  419. package/src/react/router/index.browser.ts +45 -0
  420. package/src/react/router/index.shared.ts +19 -0
  421. package/src/react/router/index.ts +146 -0
  422. package/src/react/router/primitives/$page.browser.spec.tsx +851 -0
  423. package/src/react/router/primitives/$page.spec.tsx +676 -0
  424. package/src/react/router/primitives/$page.ts +489 -0
  425. package/src/react/router/providers/ReactBrowserProvider.ts +312 -0
  426. package/src/react/router/providers/ReactBrowserRendererProvider.ts +25 -0
  427. package/src/react/router/providers/ReactBrowserRouterProvider.ts +168 -0
  428. package/src/react/router/providers/ReactPageProvider.ts +726 -0
  429. package/src/react/router/providers/ReactPreloadProvider.spec.ts +142 -0
  430. package/src/react/router/providers/ReactPreloadProvider.ts +85 -0
  431. package/src/react/router/providers/ReactServerProvider.spec.tsx +316 -0
  432. package/src/react/router/providers/ReactServerProvider.ts +487 -0
  433. package/src/react/router/providers/ReactServerTemplateProvider.spec.ts +210 -0
  434. package/src/react/router/providers/ReactServerTemplateProvider.ts +542 -0
  435. package/src/react/router/providers/SSRManifestProvider.ts +334 -0
  436. package/src/react/router/services/ReactPageServerService.ts +48 -0
  437. package/src/react/router/services/ReactPageService.ts +27 -0
  438. package/src/react/router/services/ReactRouter.ts +262 -0
  439. package/src/react/websocket/hooks/useRoom.tsx +242 -0
  440. package/src/react/websocket/index.ts +7 -0
  441. package/src/redis/__tests__/redis.spec.ts +13 -0
  442. package/src/redis/index.ts +9 -25
  443. package/src/redis/providers/BunRedisProvider.ts +9 -0
  444. package/src/redis/providers/NodeRedisProvider.ts +8 -0
  445. package/src/redis/providers/RedisProvider.ts +16 -0
  446. package/src/retry/index.ts +11 -2
  447. package/src/router/index.ts +15 -0
  448. package/src/scheduler/index.ts +11 -2
  449. package/src/security/__tests__/BasicAuth.spec.ts +2 -0
  450. package/src/security/__tests__/ServerSecurityProvider.spec.ts +90 -5
  451. package/src/security/index.ts +15 -10
  452. package/src/security/interfaces/IssuerResolver.ts +27 -0
  453. package/src/security/primitives/$issuer.ts +55 -0
  454. package/src/security/providers/SecurityProvider.ts +179 -0
  455. package/src/security/providers/ServerBasicAuthProvider.ts +6 -2
  456. package/src/security/providers/ServerSecurityProvider.ts +63 -41
  457. package/src/server/auth/index.ts +12 -7
  458. package/src/server/cache/index.ts +7 -22
  459. package/src/server/compress/index.ts +10 -2
  460. package/src/server/cookies/index.ts +7 -5
  461. package/src/server/cookies/primitives/$cookie.ts +33 -11
  462. package/src/server/core/index.ts +16 -6
  463. package/src/server/core/interfaces/ServerRequest.ts +83 -1
  464. package/src/server/core/primitives/$action.spec.ts +1 -1
  465. package/src/server/core/primitives/$action.ts +8 -3
  466. package/src/server/core/providers/NodeHttpServerProvider.spec.ts +9 -3
  467. package/src/server/core/providers/NodeHttpServerProvider.ts +9 -3
  468. package/src/server/core/services/ServerRequestParser.spec.ts +520 -0
  469. package/src/server/core/services/ServerRequestParser.ts +306 -13
  470. package/src/server/cors/index.ts +7 -21
  471. package/src/server/cors/primitives/$cors.ts +6 -2
  472. package/src/server/health/index.ts +8 -2
  473. package/src/server/helmet/index.ts +11 -3
  474. package/src/server/links/index.ts +11 -6
  475. package/src/server/metrics/index.ts +10 -3
  476. package/src/server/multipart/index.ts +9 -3
  477. package/src/server/proxy/index.ts +8 -2
  478. package/src/server/rate-limit/index.ts +21 -25
  479. package/src/server/rate-limit/primitives/$rateLimit.ts +6 -2
  480. package/src/server/rate-limit/providers/ServerRateLimitProvider.spec.ts +38 -14
  481. package/src/server/rate-limit/providers/ServerRateLimitProvider.ts +22 -56
  482. package/src/server/static/index.ts +8 -2
  483. package/src/server/static/providers/ServerStaticProvider.ts +1 -1
  484. package/src/server/swagger/index.ts +9 -4
  485. package/src/server/swagger/providers/ServerSwaggerProvider.ts +1 -1
  486. package/src/sms/index.ts +9 -5
  487. package/src/sms/providers/LocalSmsProvider.spec.ts +1 -1
  488. package/src/sms/providers/LocalSmsProvider.ts +1 -1
  489. package/src/system/index.browser.ts +36 -0
  490. package/src/system/index.ts +62 -0
  491. package/src/system/index.workerd.ts +1 -0
  492. package/src/{file → system}/providers/FileSystemProvider.ts +24 -0
  493. package/src/{file → system}/providers/MemoryFileSystemProvider.ts +116 -3
  494. package/src/system/providers/MemoryShellProvider.ts +164 -0
  495. package/src/{file → system}/providers/NodeFileSystemProvider.spec.ts +2 -2
  496. package/src/{file → system}/providers/NodeFileSystemProvider.ts +47 -2
  497. package/src/system/providers/NodeShellProvider.ts +184 -0
  498. package/src/system/providers/ShellProvider.ts +74 -0
  499. package/src/{file → system}/services/FileDetector.spec.ts +2 -2
  500. package/src/thread/index.ts +11 -2
  501. package/src/topic/core/index.ts +12 -5
  502. package/src/vite/tasks/buildClient.ts +2 -7
  503. package/src/vite/tasks/buildServer.ts +19 -13
  504. package/src/vite/tasks/generateCloudflare.ts +10 -7
  505. package/src/vite/tasks/generateDocker.ts +4 -0
  506. package/src/websocket/index.ts +12 -8
  507. package/dist/file/index.d.ts.map +0 -1
  508. package/dist/file/index.js.map +0 -1
  509. package/src/cli/assets/apiIndexTs.ts +0 -16
  510. package/src/cli/assets/mainServerTs.ts +0 -24
  511. package/src/cli/assets/webAppRouterTs.ts +0 -16
  512. package/src/cli/assets/webHelloComponentTsx.ts +0 -20
  513. package/src/cli/providers/ViteTemplateProvider.ts +0 -27
  514. package/src/file/index.ts +0 -43
  515. /package/src/cli/{assets → templates}/apiHelloControllerTs.ts +0 -0
  516. /package/src/cli/{assets → templates}/biomeJson.ts +0 -0
  517. /package/src/cli/{assets → templates}/dummySpecTs.ts +0 -0
  518. /package/src/cli/{assets → templates}/editorconfig.ts +0 -0
  519. /package/src/cli/{assets → templates}/mainBrowserTs.ts +0 -0
  520. /package/src/cli/{assets → templates}/tsconfigJson.ts +0 -0
  521. /package/src/cli/{assets → templates}/webIndexTs.ts +0 -0
  522. /package/src/{file → system}/errors/FileError.ts +0 -0
  523. /package/src/{file → system}/services/FileDetector.ts +0 -0
@@ -1,20 +1,27 @@
1
1
  import { basename, dirname } from "node:path";
2
2
  import { $inject } from "alepha";
3
- import { FileSystemProvider } from "alepha/file";
4
3
  import { $logger } from "alepha/logger";
5
- import { apiHelloControllerTs } from "../assets/apiHelloControllerTs.ts";
6
- import { apiIndexTs } from "../assets/apiIndexTs.ts";
7
- import { biomeJson } from "../assets/biomeJson.ts";
8
- import { type ClaudeMdOptions, claudeMd } from "../assets/claudeMd.ts";
9
- import { dummySpecTs } from "../assets/dummySpecTs.ts";
10
- import { editorconfig } from "../assets/editorconfig.ts";
11
- import { mainBrowserTs } from "../assets/mainBrowserTs.ts";
12
- import { mainCss } from "../assets/mainCss.ts";
13
- import { mainServerTs } from "../assets/mainServerTs.ts";
14
- import { tsconfigJson } from "../assets/tsconfigJson.ts";
15
- import { webAppRouterTs } from "../assets/webAppRouterTs.ts";
16
- import { webHelloComponentTsx } from "../assets/webHelloComponentTsx.ts";
17
- import { webIndexTs } from "../assets/webIndexTs.ts";
4
+ import { FileSystemProvider } from "alepha/system";
5
+ import {
6
+ type AgentMdOptions,
7
+ type AgentMdType,
8
+ agentMd,
9
+ } from "../templates/agentMd.ts";
10
+ import { apiAppSecurityTs } from "../templates/apiAppSecurityTs.ts";
11
+ import { apiHelloControllerTs } from "../templates/apiHelloControllerTs.ts";
12
+ import { apiIndexTs } from "../templates/apiIndexTs.ts";
13
+ import { biomeJson } from "../templates/biomeJson.ts";
14
+ import { dummySpecTs } from "../templates/dummySpecTs.ts";
15
+ import { editorconfig } from "../templates/editorconfig.ts";
16
+ import { gitignore } from "../templates/gitignore.ts";
17
+ import { mainBrowserTs } from "../templates/mainBrowserTs.ts";
18
+ import { mainCss } from "../templates/mainCss.ts";
19
+ import { mainServerTs } from "../templates/mainServerTs.ts";
20
+ import { tsconfigJson } from "../templates/tsconfigJson.ts";
21
+ import { webAppRouterTs } from "../templates/webAppRouterTs.ts";
22
+ import { webHelloComponentTsx } from "../templates/webHelloComponentTsx.ts";
23
+ import { webIndexTs } from "../templates/webIndexTs.ts";
24
+ import { AlephaCliUtils } from "./AlephaCliUtils.ts";
18
25
  import {
19
26
  type DependencyModes,
20
27
  PackageManagerUtils,
@@ -33,6 +40,7 @@ export class ProjectScaffolder {
33
40
  protected readonly log = $logger();
34
41
  protected readonly fs = $inject(FileSystemProvider);
35
42
  protected readonly pm = $inject(PackageManagerUtils);
43
+ protected readonly utils = $inject(AlephaCliUtils);
36
44
 
37
45
  /**
38
46
  * Get the app name from the directory name.
@@ -44,7 +52,7 @@ export class ProjectScaffolder {
44
52
  */
45
53
  public getAppName(root: string): string {
46
54
  const dirName = basename(root);
47
- const appName = dirName.toLowerCase().replace(/[\s\-_]/g, "");
55
+ const appName = dirName.toLowerCase().replace(/[\s\-_.\d]/g, "");
48
56
  return appName || "app";
49
57
  }
50
58
 
@@ -55,16 +63,20 @@ export class ProjectScaffolder {
55
63
  root: string,
56
64
  opts: {
57
65
  force?: boolean;
66
+ /**
67
+ * Check workspace root for existing config files.
68
+ */
69
+ checkWorkspace?: boolean;
58
70
  packageJson?: boolean | DependencyModes;
59
71
  tsconfigJson?: boolean;
60
- indexHtml?: boolean;
61
72
  biomeJson?: boolean;
62
73
  editorconfig?: boolean;
63
- claudeMd?: boolean | ClaudeMdOptions;
74
+ agentMd?: false | (AgentMdOptions & { type: AgentMdType });
64
75
  },
65
76
  ): Promise<void> {
66
77
  const tasks: Promise<void>[] = [];
67
78
  const force = opts.force ?? false;
79
+ const checkWorkspace = opts.checkWorkspace ?? false;
68
80
 
69
81
  if (opts.packageJson) {
70
82
  tasks.push(
@@ -79,24 +91,14 @@ export class ProjectScaffolder {
79
91
  if (opts.tsconfigJson) {
80
92
  tasks.push(this.ensureTsConfig(root, { force }));
81
93
  }
82
- if (opts.indexHtml) {
83
- tasks.push(this.ensureReactProject(root, { force }));
84
- }
85
94
  if (opts.biomeJson) {
86
- tasks.push(this.ensureBiomeConfig(root, { force }));
95
+ tasks.push(this.ensureBiomeConfig(root, { force, checkWorkspace }));
87
96
  }
88
97
  if (opts.editorconfig) {
89
- tasks.push(this.ensureEditorConfig(root, { force }));
98
+ tasks.push(this.ensureEditorConfig(root, { force, checkWorkspace }));
90
99
  }
91
- if (opts.claudeMd) {
92
- tasks.push(
93
- this.ensureClaudeMd(
94
- root,
95
- typeof opts.claudeMd === "boolean"
96
- ? { force }
97
- : { ...opts.claudeMd, force },
98
- ),
99
- );
100
+ if (opts.agentMd) {
101
+ tasks.push(this.ensureAgentMd(root, { ...opts.agentMd, force }));
100
102
  }
101
103
 
102
104
  await Promise.all(tasks);
@@ -122,23 +124,95 @@ export class ProjectScaffolder {
122
124
 
123
125
  public async ensureBiomeConfig(
124
126
  root: string,
125
- opts: { force?: boolean } = {},
127
+ opts: { force?: boolean; checkWorkspace?: boolean } = {},
126
128
  ): Promise<void> {
129
+ if (
130
+ !opts.force &&
131
+ opts.checkWorkspace &&
132
+ (await this.existsInParents(root, "biome.json"))
133
+ ) {
134
+ return;
135
+ }
127
136
  await this.ensureFile(root, "biome.json", biomeJson(), opts.force);
128
137
  }
129
138
 
130
139
  public async ensureEditorConfig(
131
140
  root: string,
132
- opts: { force?: boolean } = {},
141
+ opts: { force?: boolean; checkWorkspace?: boolean } = {},
133
142
  ): Promise<void> {
143
+ if (
144
+ !opts.force &&
145
+ opts.checkWorkspace &&
146
+ (await this.existsInParents(root, ".editorconfig"))
147
+ ) {
148
+ return;
149
+ }
134
150
  await this.ensureFile(root, ".editorconfig", editorconfig(), opts.force);
135
151
  }
136
152
 
137
- public async ensureClaudeMd(
153
+ /**
154
+ * Ensure git repository is initialized with .gitignore.
155
+ *
156
+ * @returns true if git was initialized, false if already exists or git unavailable
157
+ */
158
+ public async ensureGitRepo(
159
+ root: string,
160
+ opts: { force?: boolean } = {},
161
+ ): Promise<boolean> {
162
+ const gitDir = this.fs.join(root, ".git");
163
+
164
+ // Skip if .git already exists
165
+ if (!opts.force && (await this.fs.exists(gitDir))) {
166
+ return false;
167
+ }
168
+
169
+ // Check if git is available
170
+ const hasGit = await this.utils.isInstalledAsync("git");
171
+ if (!hasGit) {
172
+ return false;
173
+ }
174
+
175
+ // Initialize git repository
176
+ await this.utils.exec("git init", { root, global: true });
177
+
178
+ // Write .gitignore
179
+ await this.ensureFile(root, ".gitignore", gitignore(), opts.force);
180
+
181
+ return true;
182
+ }
183
+
184
+ public async ensureAgentMd(
185
+ root: string,
186
+ options: AgentMdOptions & { type: AgentMdType; force?: boolean },
187
+ ): Promise<void> {
188
+ const filename = options.type === "claude" ? "CLAUDE.md" : "AGENTS.md";
189
+ await this.ensureFile(
190
+ root,
191
+ filename,
192
+ agentMd(options.type, options),
193
+ options.force,
194
+ );
195
+ }
196
+
197
+ // ===========================================
198
+ // Minimal Project Structure
199
+ // ===========================================
200
+
201
+ /**
202
+ * Ensure src/main.server.ts exists with correct module imports.
203
+ */
204
+ public async ensureMainServerTs(
138
205
  root: string,
139
- options: ClaudeMdOptions & { force?: boolean } = {},
206
+ opts: { api?: boolean; react?: boolean; force?: boolean } = {},
140
207
  ): Promise<void> {
141
- await this.ensureFile(root, "CLAUDE.md", claudeMd(options), options.force);
208
+ const srcDir = this.fs.join(root, "src");
209
+ await this.fs.mkdir(srcDir, { recursive: true });
210
+ await this.ensureFile(
211
+ srcDir,
212
+ "main.server.ts",
213
+ mainServerTs({ api: opts.api, react: opts.react }),
214
+ opts.force,
215
+ );
142
216
  }
143
217
 
144
218
  // ===========================================
@@ -146,25 +220,16 @@ export class ProjectScaffolder {
146
220
  // ===========================================
147
221
 
148
222
  /**
149
- * Ensure src/main.server.ts exists with full API structure.
223
+ * Ensure API module structure exists.
150
224
  *
151
225
  * Creates:
152
- * - src/main.server.ts (entry point)
153
226
  * - src/api/index.ts (API module)
154
227
  * - src/api/controllers/HelloController.ts (example controller)
155
228
  */
156
229
  public async ensureApiProject(
157
230
  root: string,
158
- opts: { force?: boolean } = {},
231
+ opts: { auth?: boolean; force?: boolean } = {},
159
232
  ): Promise<void> {
160
- const srcDir = this.fs.join(root, "src");
161
-
162
- // Don't overwrite existing content unless force is set
163
- if (!opts.force && (await this.fs.exists(srcDir))) {
164
- const files = await this.fs.ls(srcDir);
165
- if (files.length > 0) return;
166
- }
167
-
168
233
  const appName = this.getAppName(root);
169
234
 
170
235
  // Create directories
@@ -173,67 +238,64 @@ export class ProjectScaffolder {
173
238
  });
174
239
 
175
240
  // Create files
176
- await this.ensureFile(srcDir, "main.server.ts", mainServerTs(), opts.force);
177
241
  await this.ensureFile(
178
- srcDir,
179
- "api/index.ts",
180
- apiIndexTs({ appName }),
242
+ root,
243
+ "src/api/index.ts",
244
+ apiIndexTs({ appName, auth: opts.auth }),
181
245
  opts.force,
182
246
  );
183
247
  await this.ensureFile(
184
- srcDir,
185
- "api/controllers/HelloController.ts",
248
+ root,
249
+ "src/api/controllers/HelloController.ts",
186
250
  apiHelloControllerTs(),
187
251
  opts.force,
188
252
  );
253
+
254
+ // Create AppSecurity if auth is enabled
255
+ if (opts.auth) {
256
+ await this.ensureFile(
257
+ root,
258
+ "src/api/AppSecurity.ts",
259
+ apiAppSecurityTs(),
260
+ opts.force,
261
+ );
262
+ }
189
263
  }
190
264
 
191
265
  // ===========================================
192
- // React Project Structure
266
+ // Web Project Structure
193
267
  // ===========================================
194
268
 
195
269
  /**
196
- * Ensure full React project structure exists.
270
+ * Ensure web/React project structure exists.
197
271
  *
198
272
  * Creates:
199
- * - src/main.server.ts, src/main.browser.ts
200
- * - src/api/index.ts, src/api/controllers/HelloController.ts
273
+ * - src/main.browser.ts
274
+ * - src/main.css
201
275
  * - src/web/index.ts, src/web/AppRouter.ts, src/web/components/Hello.tsx
202
276
  */
203
- public async ensureReactProject(
277
+ public async ensureWebProject(
204
278
  root: string,
205
- opts: { force?: boolean } = {},
279
+ opts: {
280
+ api?: boolean;
281
+ ui?: boolean;
282
+ auth?: boolean;
283
+ admin?: boolean;
284
+ force?: boolean;
285
+ } = {},
206
286
  ): Promise<void> {
207
287
  const appName = this.getAppName(root);
208
288
 
209
289
  // Create directories
210
- await this.fs.mkdir(this.fs.join(root, "src/api/controllers"), {
211
- recursive: true,
212
- });
213
290
  await this.fs.mkdir(this.fs.join(root, "src/web/components"), {
214
291
  recursive: true,
215
292
  });
216
293
 
217
294
  // src/main.css
218
- await this.ensureFile(root, "src/main.css", mainCss(), opts.force);
219
-
220
- // API structure
221
- await this.ensureFile(
222
- root,
223
- "src/api/index.ts",
224
- apiIndexTs({ appName }),
225
- opts.force,
226
- );
227
- await this.ensureFile(
228
- root,
229
- "src/api/controllers/HelloController.ts",
230
- apiHelloControllerTs(),
231
- opts.force,
232
- );
233
295
  await this.ensureFile(
234
296
  root,
235
- "src/main.server.ts",
236
- mainServerTs({ react: true }),
297
+ "src/main.css",
298
+ mainCss({ ui: opts.ui }),
237
299
  opts.force,
238
300
  );
239
301
 
@@ -247,13 +309,18 @@ export class ProjectScaffolder {
247
309
  await this.ensureFile(
248
310
  root,
249
311
  "src/web/AppRouter.ts",
250
- webAppRouterTs(),
312
+ webAppRouterTs({
313
+ api: opts.api,
314
+ ui: opts.ui,
315
+ auth: opts.auth,
316
+ admin: opts.admin,
317
+ }),
251
318
  opts.force,
252
319
  );
253
320
  await this.ensureFile(
254
321
  root,
255
322
  "src/web/components/Hello.tsx",
256
- webHelloComponentTsx(),
323
+ webHelloComponentTsx({ auth: opts.auth }),
257
324
  opts.force,
258
325
  );
259
326
  await this.ensureFile(
@@ -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
@@ -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,10 +119,10 @@ 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
@@ -118,6 +130,7 @@ This is an **Alepha** project - a convention-driven TypeScript framework for typ
118
130
  - Import with file extensions: \`import { User } from "./User.ts"\`
119
131
  - Use \`t\` from Alepha for schemas (not Zod)
120
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)
121
134
 
122
135
  ## Project Structure
123
136
  ${projectStructure}
@@ -160,17 +173,12 @@ export const userEntity = $entity({
160
173
  id: db.primaryKey(),
161
174
  email: t.email(),
162
175
  createdAt: db.createdAt(),
163
- updatedAt: db.updatedAt(),
164
176
  }),
165
177
  indexes: [{ column: "email", unique: true }],
166
178
  });
167
179
 
168
180
  class UserService {
169
- repo = $repository(userEntity);
170
-
171
- async findById(id: string) {
172
- return this.repo.findById(id);
173
- }
181
+ userRepository = $repository(userEntity);
174
182
  }
175
183
  \`\`\`
176
184
 
@@ -180,11 +188,6 @@ import { $inject } from "alepha";
180
188
 
181
189
  class OrderService {
182
190
  userService = $inject(UserService); // Within same module
183
-
184
- async createOrder(userId: string) {
185
- const user = await this.userService.findById(userId);
186
- // ...
187
- }
188
191
  }
189
192
 
190
193
  // Cross-module: use $client instead of $inject
@@ -250,7 +253,7 @@ ${reactSection}
250
253
  | \`$command\` | \`alepha/command\` | CLI commands |${
251
254
  react
252
255
  ? `
253
- | \`$page\` | \`@alepha/react/router\` | React pages with SSR |
256
+ | \`$page\` | \`alepha/react/router\` | React pages with SSR |
254
257
  | \`$atom\` | \`alepha\` | Global state |`
255
258
  : ""
256
259
  }
@@ -304,5 +307,15 @@ alepha build # Build the project
304
307
 
305
308
  - Full docs: https://alepha.dev/llms.txt
306
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
+
315
+ **IMPORTANT:** When answering questions about Alepha primitives, APIs, or internals:
316
+ 1. ALWAYS read the local source code first at \`node_modules/alepha/src/\` or \`node_modules/@alepha/ui/src/\` for UI-related questions
317
+ 2. Use \`Glob\` to find relevant files: \`node_modules/alepha/src/**/primitives/$<name>.ts\`
318
+ 3. Read the implementation AND the \`.spec.ts\` test files for usage examples
319
+ 4. Use external documentation as a fallback if source code is insufficient
307
320
  `.trim();
308
321
  };
@@ -0,0 +1,11 @@
1
+ export const apiAppSecurityTs = () => {
2
+ return `
3
+ import { $realm } from "alepha/api/users";
4
+
5
+ export class AppSecurity {
6
+ users = $realm({
7
+ // configure your realm here
8
+ });
9
+ }
10
+ `.trim();
11
+ };
@@ -0,0 +1,30 @@
1
+ export interface ApiIndexTsOptions {
2
+ appName?: string;
3
+ auth?: boolean;
4
+ }
5
+
6
+ export const apiIndexTs = (options: ApiIndexTsOptions = {}) => {
7
+ const { appName = "app", auth = false } = options;
8
+
9
+ const imports: string[] = ['import { $module } from "alepha";'];
10
+ const services: string[] = [];
11
+
12
+ if (auth) {
13
+ imports.push('import { AppSecurity } from "./AppSecurity.ts";');
14
+ services.push("AppSecurity");
15
+ }
16
+
17
+ imports.push(
18
+ 'import { HelloController } from "./controllers/HelloController.ts";',
19
+ );
20
+ services.push("HelloController");
21
+
22
+ return `
23
+ ${imports.join("\n")}
24
+
25
+ export const ApiModule = $module({
26
+ name: "${appName}.api",
27
+ services: [${services.join(", ")}],
28
+ });
29
+ `.trim();
30
+ };
@@ -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,5 +1,13 @@
1
- export const mainCss = () =>
2
- `
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 `
3
11
  * {
4
12
  box-sizing: border-box;
5
13
  margin: 0;
@@ -22,3 +30,4 @@ body {
22
30
  height: 100%;
23
31
  }
24
32
  `.trim();
33
+ };