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,11 +1,29 @@
1
1
  import { type Static, t } from "alepha";
2
2
  import { $atom } from "../../core/primitives/$atom.ts";
3
3
 
4
+ /**
5
+ * Deployment target for the build output.
6
+ *
7
+ * - `docker` - Generate Dockerfile for containerized deployment
8
+ * - `vercel` - Generate Vercel deployment configuration (forces node runtime)
9
+ * - `cloudflare` - Generate Cloudflare Workers configuration (forces workerd runtime)
10
+ */
11
+ export type BuildTarget = "bare" | "docker" | "vercel" | "cloudflare";
12
+
13
+ /**
14
+ * JavaScript runtime for the build output.
15
+ *
16
+ * - `node` - Node.js runtime (default)
17
+ * - `bun` - Bun runtime (uses bun export conditions)
18
+ * - `workerd` - Cloudflare Workers runtime (auto-set with cloudflare target)
19
+ */
20
+ export type BuildRuntime = "node" | "bun" | "workerd";
21
+
4
22
  /**
5
23
  * Build options atom for CLI build command.
6
24
  *
7
25
  * Defines the available build configuration options with their defaults.
8
- * Options can be overridden via vite.config.ts or CLI flags.
26
+ * Options can be overridden via alepha.config.ts or CLI flags.
9
27
  */
10
28
  export const buildOptions = $atom({
11
29
  name: "alepha.cli.build.options",
@@ -17,7 +35,32 @@ export const buildOptions = $atom({
17
35
  stats: t.optional(t.boolean({ default: false })),
18
36
 
19
37
  /**
20
- * Vercel deployment configuration.
38
+ * Deployment target for the build output.
39
+ *
40
+ * - `docker` - Generate Dockerfile for containerized deployment
41
+ * - `vercel` - Generate Vercel deployment configuration (forces node runtime)
42
+ * - `cloudflare` - Generate Cloudflare Workers configuration (forces workerd runtime)
43
+ */
44
+ target: t.optional(t.enum(["bare", "docker", "vercel", "cloudflare"])),
45
+
46
+ /**
47
+ * JavaScript runtime for the build output.
48
+ *
49
+ * - `node` - Node.js runtime (default)
50
+ * - `bun` - Bun runtime (uses bun export conditions)
51
+ * - `workerd` - Cloudflare Workers runtime (auto-set with cloudflare target)
52
+ *
53
+ * Note: Some targets force a specific runtime:
54
+ * - `cloudflare` always uses `workerd`
55
+ * - `vercel` always uses `node`
56
+ */
57
+ runtime: t.optional(t.enum(["node", "bun", "workerd"])),
58
+
59
+ /**
60
+ * Vercel-specific deployment configuration.
61
+ *
62
+ * Note: Set `target: "vercel"` to enable Vercel deployment.
63
+ * This object is only for additional configuration.
21
64
  */
22
65
  vercel: t.optional(
23
66
  t.object({
@@ -40,7 +83,10 @@ export const buildOptions = $atom({
40
83
  ),
41
84
 
42
85
  /**
43
- * Cloudflare Workers deployment configuration.
86
+ * Cloudflare-specific deployment configuration.
87
+ *
88
+ * Note: Set `target: "cloudflare"` to enable Cloudflare deployment.
89
+ * This object is only for additional configuration.
44
90
  */
45
91
  cloudflare: t.optional(
46
92
  t.object({
@@ -49,21 +95,65 @@ export const buildOptions = $atom({
49
95
  ),
50
96
 
51
97
  /**
52
- * Docker deployment configuration.
98
+ * Docker-specific deployment configuration.
99
+ *
100
+ * Note: Set `target: "docker"` to enable Docker deployment.
101
+ * This object is only for additional configuration.
53
102
  */
54
103
  docker: t.optional(
55
104
  t.object({
56
105
  /**
57
- * Docker image name to use in the Dockerfile.
58
- * @default "node:24-alpine"
106
+ * Base image for the Dockerfile (FROM instruction).
107
+ *
108
+ * @default "node:24-alpine" for node runtime
109
+ * @default "oven/bun:alpine" for bun runtime
59
110
  */
60
- image: t.optional(t.string({ default: "node:24-alpine" })),
111
+ from: t.optional(t.string()),
61
112
 
62
113
  /**
63
114
  * Command to run in the Docker container.
64
- * @default "node"
115
+ *
116
+ * @default "node" for node runtime
117
+ * @default "bun" for bun runtime
118
+ */
119
+ command: t.optional(t.string()),
120
+
121
+ /**
122
+ * Docker build options (used when --image flag is passed).
65
123
  */
66
- command: t.optional(t.string({ default: "node" })),
124
+ image: t.optional(
125
+ t.object({
126
+ /**
127
+ * Default image tag (name without version).
128
+ *
129
+ * Used when --image is provided without a full override:
130
+ * - `--image` → `tag:latest`
131
+ * - `--image=1.3.4` → `tag:1.3.4`
132
+ * - `--image=other/img:v1` → `other/img:v1` (full override)
133
+ *
134
+ * @example "myproject/myapp"
135
+ * @example "ghcr.io/myorg/myapp"
136
+ */
137
+ tag: t.string(),
138
+
139
+ /**
140
+ * Additional arguments to pass to `docker build`.
141
+ *
142
+ * @example '--platform linux/amd64 --no-cache'
143
+ */
144
+ args: t.optional(t.string()),
145
+
146
+ /**
147
+ * Auto-add OCI standard labels (revision, created, version).
148
+ *
149
+ * Adds:
150
+ * - org.opencontainers.image.revision (git commit SHA)
151
+ * - org.opencontainers.image.created (build timestamp)
152
+ * - org.opencontainers.image.version (from image tag)
153
+ */
154
+ oci: t.optional(t.boolean()),
155
+ }),
156
+ ),
67
157
  }),
68
158
  ),
69
159
 
@@ -1,7 +1,7 @@
1
1
  import { $inject, $use, type Alepha, AlephaError, t } from "alepha";
2
2
  import { $command } from "alepha/command";
3
- import { FileSystemProvider } from "alepha/file";
4
3
  import { $logger } from "alepha/logger";
4
+ import { FileSystemProvider } from "alepha/system";
5
5
  import {
6
6
  buildClient,
7
7
  buildServer,
@@ -12,7 +12,11 @@ import {
12
12
  generateVercel,
13
13
  prerenderPages,
14
14
  } from "alepha/vite";
15
- import { buildOptions } from "../atoms/buildOptions.ts";
15
+ import {
16
+ type BuildRuntime,
17
+ type BuildTarget,
18
+ buildOptions,
19
+ } from "../atoms/buildOptions.ts";
16
20
  import { AppEntryProvider } from "../providers/AppEntryProvider.ts";
17
21
  import { ViteBuildProvider } from "../providers/ViteBuildProvider.ts";
18
22
  import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
@@ -29,6 +33,41 @@ export class BuildCommand {
29
33
  protected readonly viteBuildProvider = $inject(ViteBuildProvider);
30
34
  protected readonly options = $use(buildOptions);
31
35
 
36
+ /**
37
+ * Resolve the effective runtime based on target and explicit runtime flag.
38
+ *
39
+ * Some targets force a specific runtime:
40
+ * - `cloudflare` always uses `workerd`
41
+ * - `vercel` always uses `node`
42
+ * - `docker` and bare deployments respect the runtime flag
43
+ *
44
+ * @throws {AlephaError} If an incompatible runtime is specified for a target
45
+ */
46
+ protected resolveRuntime(
47
+ target: BuildTarget | undefined,
48
+ runtime: BuildRuntime | undefined,
49
+ ): BuildRuntime {
50
+ if (target === "cloudflare") {
51
+ if (runtime && runtime !== "workerd") {
52
+ throw new AlephaError(
53
+ `Target 'cloudflare' requires 'workerd' runtime, got '${runtime}'`,
54
+ );
55
+ }
56
+ return "workerd";
57
+ }
58
+
59
+ if (target === "vercel") {
60
+ if (runtime && runtime !== "node") {
61
+ throw new AlephaError(
62
+ `Target 'vercel' requires 'node' runtime, got '${runtime}'`,
63
+ );
64
+ }
65
+ return "node";
66
+ }
67
+
68
+ return runtime ?? "node";
69
+ }
70
+
32
71
  public readonly build = $command({
33
72
  name: "build",
34
73
  mode: "production",
@@ -39,19 +78,23 @@ export class BuildCommand {
39
78
  description: "Generate build stats report",
40
79
  }),
41
80
  ),
42
- vercel: t.optional(
43
- t.boolean({
44
- description: "Generate Vercel deployment configuration",
81
+ target: t.optional(
82
+ t.enum(["bare", "docker", "vercel", "cloudflare"], {
83
+ aliases: ["t"],
84
+ description: "Deployment target",
45
85
  }),
46
86
  ),
47
- cloudflare: t.optional(
48
- t.boolean({
49
- description: "Generate Cloudflare Workers configuration",
87
+ runtime: t.optional(
88
+ t.enum(["node", "bun", "workerd"], {
89
+ aliases: ["r"],
90
+ description: "JavaScript runtime",
50
91
  }),
51
92
  ),
52
- docker: t.optional(
53
- t.boolean({
54
- description: "Generate Docker configuration",
93
+ image: t.optional(
94
+ t.union([t.boolean(), t.text()], {
95
+ aliases: ["i"],
96
+ description:
97
+ "Build Docker image. Use -i for latest, -i=<version> for specific version",
55
98
  }),
56
99
  ),
57
100
  sitemap: t.optional(
@@ -59,11 +102,6 @@ export class BuildCommand {
59
102
  description: "Generate sitemap.xml with base URL",
60
103
  }),
61
104
  ),
62
- bun: t.optional(
63
- t.boolean({
64
- description: "Prioritize .bun.ts entry files for Bun runtime",
65
- }),
66
- ),
67
105
  }),
68
106
  handler: async ({ flags, run, root }) => {
69
107
  process.env.NODE_ENV = "production";
@@ -83,15 +121,27 @@ export class BuildCommand {
83
121
  const distDir = "dist";
84
122
  const publicDir = "public";
85
123
 
86
- await this.pm.ensureDependency(root, "vite", {
87
- run,
88
- exec: (cmd, opts) => this.utils.exec(cmd, opts),
89
- });
90
124
  await run.rm("dist", { alias: "clean dist" });
91
125
 
92
126
  const options = this.options;
93
127
  await this.utils.loadEnv(root, [".env", ".env.production"]);
94
128
 
129
+ // Resolve target and runtime
130
+ const target = flags.target ?? options.target;
131
+ const runtime = this.resolveRuntime(
132
+ target,
133
+ flags.runtime ?? options.runtime,
134
+ );
135
+
136
+ // Validate --image requires --target=docker
137
+ if (flags.image && target !== "docker") {
138
+ throw new AlephaError(
139
+ `Flag '--image' requires '--target=docker', got '${target ?? "bare"}'`,
140
+ );
141
+ }
142
+
143
+ this.log.trace("Build configuration", { target, runtime });
144
+
95
145
  const stats = flags.stats ?? options.stats ?? false;
96
146
  let template = "";
97
147
  let hasClient = false;
@@ -144,20 +194,11 @@ export class BuildCommand {
144
194
  const clientIndexPath = `${distDir}/${publicDir}/index.html`;
145
195
  const clientBuilt = await this.fs.exists(clientIndexPath);
146
196
 
197
+ // Set export conditions based on runtime
147
198
  const conditions: string[] = [];
148
-
149
- // bun:
150
- // - alepha
151
- // - react-dom
152
-
153
- if (flags.bun) {
199
+ if (runtime === "bun") {
154
200
  conditions.push("bun");
155
- }
156
-
157
- // workerd:
158
- // - react-dom
159
- // - postgres
160
- if (options.cloudflare) {
201
+ } else if (runtime === "workerd") {
161
202
  conditions.push("workerd");
162
203
  }
163
204
 
@@ -208,8 +249,8 @@ export class BuildCommand {
208
249
  });
209
250
  }
210
251
 
211
- // Generate deployment configurations
212
- if (flags.vercel || options.vercel) {
252
+ // Generate deployment configuration based on target
253
+ if (target === "vercel") {
213
254
  await run({
214
255
  name: "add Vercel config",
215
256
  handler: () =>
@@ -221,7 +262,7 @@ export class BuildCommand {
221
262
  });
222
263
  }
223
264
 
224
- if (flags.cloudflare || options.cloudflare) {
265
+ if (target === "cloudflare") {
225
266
  await run({
226
267
  name: "add Cloudflare config",
227
268
  handler: () =>
@@ -232,15 +273,87 @@ export class BuildCommand {
232
273
  });
233
274
  }
234
275
 
235
- if (flags.docker || options.docker) {
276
+ if (target === "docker") {
277
+ // Auto-configure Docker based on runtime
278
+ const dockerFrom =
279
+ options.docker?.from ??
280
+ (runtime === "bun" ? "oven/bun:alpine" : "node:24-alpine");
281
+ const dockerCommand =
282
+ options.docker?.command ?? (runtime === "bun" ? "bun" : "node");
283
+
236
284
  await run({
237
285
  name: "add Docker config",
238
286
  handler: () =>
239
287
  generateDocker({
240
288
  distDir,
241
- ...options.docker,
289
+ image: dockerFrom,
290
+ command: dockerCommand,
242
291
  }),
243
292
  });
293
+
294
+ // Build Docker image if --image flag is provided
295
+ if (flags.image) {
296
+ const imageConfig = options.docker?.image;
297
+ const flagValue =
298
+ typeof flags.image === "string" ? flags.image : null;
299
+
300
+ let imageTag: string;
301
+ let version: string;
302
+
303
+ if (!flagValue) {
304
+ // -i (no value) → use config tag:latest
305
+ if (!imageConfig?.tag) {
306
+ throw new AlephaError(
307
+ "Flag '--image' requires 'build.docker.image.tag' in config",
308
+ );
309
+ }
310
+ version = "latest";
311
+ imageTag = `${imageConfig.tag}:${version}`;
312
+ } else if (flagValue.startsWith(":")) {
313
+ // -i=:1.3.4 → version only, prepend config tag
314
+ if (!imageConfig?.tag) {
315
+ throw new AlephaError(
316
+ "Flag '--image=:version' requires 'build.docker.image.tag' in config",
317
+ );
318
+ }
319
+ version = flagValue.slice(1); // remove leading ":"
320
+ imageTag = `${imageConfig.tag}:${version}`;
321
+ } else if (flagValue.includes(":")) {
322
+ // -i=toto:1.3.4 → full image with version
323
+ imageTag = flagValue;
324
+ version = flagValue.split(":")[1];
325
+ } else {
326
+ // -i=toto → image name without version → add :latest
327
+ imageTag = `${flagValue}:latest`;
328
+ version = "latest";
329
+ }
330
+
331
+ const args: string[] = [];
332
+
333
+ // Add custom args
334
+ if (imageConfig?.args) {
335
+ args.push(imageConfig.args);
336
+ }
337
+
338
+ // Add OCI labels if enabled
339
+ if (imageConfig?.oci) {
340
+ const revision = await this.utils.getGitRevision();
341
+ const created = new Date().toISOString();
342
+
343
+ args.push(
344
+ `--label "org.opencontainers.image.revision=${revision}"`,
345
+ );
346
+ args.push(`--label "org.opencontainers.image.created=${created}"`);
347
+ args.push(`--label "org.opencontainers.image.version=${version}"`);
348
+ }
349
+
350
+ const argsStr = args.length > 0 ? `${args.join(" ")} ` : "";
351
+ const dockerCmd = `docker build ${argsStr}-t ${imageTag} ${distDir}`;
352
+
353
+ await run(dockerCmd, {
354
+ alias: `docker build ${imageTag}`,
355
+ });
356
+ }
244
357
  }
245
358
  },
246
359
  });
@@ -1,12 +1,13 @@
1
1
  import { $inject, AlephaError, t } from "alepha";
2
2
  import { $command } from "alepha/command";
3
- import { FileSystemProvider } from "alepha/file";
4
3
  import { $logger } from "alepha/logger";
5
4
  import type {
6
5
  DatabaseProvider,
7
6
  DrizzleKitProvider,
8
7
  RepositoryProvider,
9
8
  } from "alepha/orm";
9
+ import { FileSystemProvider } from "alepha/system";
10
+ import { AppEntryProvider } from "../providers/AppEntryProvider.ts";
10
11
  import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
11
12
 
12
13
  const drizzleCommandFlags = t.object({
@@ -28,6 +29,7 @@ export class DbCommand {
28
29
  protected readonly log = $logger();
29
30
  protected readonly fs = $inject(FileSystemProvider);
30
31
  protected readonly utils = $inject(AlephaCliUtils);
32
+ protected readonly entryProvider = $inject(AppEntryProvider);
31
33
 
32
34
  /**
33
35
  * Check if database migrations are up to date.
@@ -46,10 +48,11 @@ export class DbCommand {
46
48
  const rootDir = root;
47
49
  this.log.debug(`Using project root: ${rootDir}`);
48
50
 
49
- const { alepha } = await this.utils.loadAlephaFromServerEntryFile(
50
- rootDir,
51
- args,
52
- );
51
+ const entry = await this.entryProvider.getAppEntry(root);
52
+ const alepha = await this.utils.loadAlephaFromServerEntryFile({
53
+ mode: "development",
54
+ entry,
55
+ });
53
56
 
54
57
  const repositoryProvider =
55
58
  alepha.inject<RepositoryProvider>("RepositoryProvider");
@@ -276,10 +279,11 @@ export class DbCommand {
276
279
 
277
280
  this.log.debug(`Using project root: ${rootDir}`);
278
281
 
279
- const { alepha, entry } = await this.utils.loadAlephaFromServerEntryFile(
280
- rootDir,
281
- options.args,
282
- );
282
+ const entry = await this.entryProvider.getAppEntry(rootDir);
283
+ const alepha = await this.utils.loadAlephaFromServerEntryFile({
284
+ mode: "development",
285
+ entry,
286
+ });
283
287
 
284
288
  const drizzleKitProvider =
285
289
  alepha.inject<DrizzleKitProvider>("DrizzleKitProvider");
@@ -319,7 +323,7 @@ export class DbCommand {
319
323
  providerUrl: provider.url,
320
324
  providerDriver: provider.driver,
321
325
  dialect,
322
- entry,
326
+ entry: this.fs.join(rootDir, entry.server),
323
327
  rootDir,
324
328
  });
325
329
 
@@ -328,7 +332,9 @@ export class DbCommand {
328
332
  `drizzle-kit ${options.command} --config=${drizzleConfigJsPath}${flags}`,
329
333
  {
330
334
  env: {
331
- NODE_OPTIONS: "--import tsx",
335
+ NODE_OPTIONS: [process.env.NODE_OPTIONS, "--import tsx"]
336
+ .filter(Boolean)
337
+ .join(" "),
332
338
  },
333
339
  },
334
340
  );
@@ -399,20 +405,18 @@ export class DbCommand {
399
405
  }
400
406
 
401
407
  const url = options.providerUrl;
402
- if (!url.startsWith("cloudflare-d1://")) {
403
- throw new AlephaError(
404
- "D1 provider URL must start with 'cloudflare-d1://'.",
405
- );
408
+ if (!url.startsWith("d1://")) {
409
+ throw new AlephaError("D1 provider URL must start with 'd1://'.");
406
410
  }
407
411
 
408
412
  const [, databaseId] = url
409
- .replace("cloudflare-d1://", "")
410
- .replace("cloudflare-d1:", "")
413
+ .replace("d1://", "")
414
+ .replace("d1:", "")
411
415
  .split(":");
412
416
 
413
417
  if (!databaseId) {
414
418
  throw new AlephaError(
415
- "Database ID is missing in the D1 provider URL. Cloudflare D1 URL format: cloudflare-d1://<database_name>:<database_id>",
419
+ "Database ID is missing in the D1 provider URL. Cloudflare D1 URL format: d1://<database_name>:<database_id>",
416
420
  );
417
421
  }
418
422
 
@@ -1,7 +1,7 @@
1
1
  import { $inject, AlephaError, t } from "alepha";
2
2
  import { $command } from "alepha/command";
3
- import { FileSystemProvider } from "alepha/file";
4
3
  import { $logger } from "alepha/logger";
4
+ import { FileSystemProvider } from "alepha/system";
5
5
  import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
6
6
  import { PackageManagerUtils } from "../services/PackageManagerUtils.ts";
7
7
 
@@ -1,7 +1,7 @@
1
1
  import { $inject, Alepha } from "alepha";
2
2
  import { $command } from "alepha/command";
3
- import { FileSystemProvider } from "alepha/file";
4
3
  import { $logger } from "alepha/logger";
4
+ import { FileSystemProvider } from "alepha/system";
5
5
  import { AppEntryProvider } from "../providers/AppEntryProvider.ts";
6
6
  import { ViteDevServerProvider } from "../providers/ViteDevServerProvider.ts";
7
7
  import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
@@ -20,39 +20,20 @@ export class DevCommand {
20
20
 
21
21
  /**
22
22
  * Will run the project in watch mode.
23
- *
24
- * - If an index.html file is found in the project root, it will run Vite in dev mode.
25
- * - Otherwise, it will look for a server entry file and run it with tsx in watch mode.
26
23
  */
27
24
  public readonly dev = $command({
28
25
  name: "dev",
29
26
  description: "Run the project in development mode",
30
27
  handler: async ({ root }) => {
31
- const [expo, react] = await Promise.all([
32
- this.pm.hasExpo(root),
33
- this.pm.hasReact(root),
34
- ]);
35
-
36
28
  await this.scaffolder.ensureConfig(root, {
37
29
  tsconfigJson: true,
38
30
  });
39
31
 
40
- if (expo) {
41
- await this.utils.exec("expo start");
42
- return;
43
- }
44
-
45
32
  const entry = await this.boot.getAppEntry(root);
46
33
  this.log.debug("Entry file found", { entry });
47
34
 
48
35
  // -> here, we assume we use Vite as runner (api or fullstack)
49
36
  // but it's planned to support Bun runner in the future as well
50
-
51
- // Ensure vite is installed before running
52
- await this.pm.ensureDependency(root, "vite", {
53
- exec: (cmd, opts) => this.utils.exec(cmd, opts),
54
- });
55
-
56
37
  await this.viteDevServer.init({ root, entry });
57
38
  await this.viteDevServer.start();
58
39
  },
@@ -1,7 +1,7 @@
1
1
  import { $inject, t } from "alepha";
2
2
  import { $command } from "alepha/command";
3
- import { FileSystemProvider } from "alepha/file";
4
3
  import { $logger } from "alepha/logger";
4
+ import { FileSystemProvider } from "alepha/system";
5
5
  import { AlephaCliUtils } from "../../services/AlephaCliUtils.ts";
6
6
 
7
7
  export class GenEnvCommand {
@@ -21,7 +21,10 @@ export class GenEnvCommand {
21
21
  ),
22
22
  }),
23
23
  handler: async ({ root, flags }) => {
24
- const { alepha } = await this.utils.loadAlephaFromServerEntryFile(root);
24
+ const alepha = await this.utils.loadAlephaFromServerEntryFile({
25
+ root,
26
+ mode: "development",
27
+ });
25
28
 
26
29
  try {
27
30
  const { env } = alepha.dump();
@@ -1,8 +1,8 @@
1
1
  import { $inject, t } from "alepha";
2
2
  import { $command } from "alepha/command";
3
- import { FileSystemProvider } from "alepha/file";
4
3
  import { $logger } from "alepha/logger";
5
4
  import { ServerSwaggerProvider } from "alepha/server/swagger";
5
+ import { FileSystemProvider } from "alepha/system";
6
6
  import { AlephaCliUtils } from "../../services/AlephaCliUtils.ts";
7
7
 
8
8
  export class OpenApiCommand {
@@ -22,7 +22,10 @@ export class OpenApiCommand {
22
22
  ),
23
23
  }),
24
24
  handler: async ({ root, flags }) => {
25
- const { alepha } = await this.utils.loadAlephaFromServerEntryFile(root);
25
+ const alepha = await this.utils.loadAlephaFromServerEntryFile({
26
+ root,
27
+ mode: "development",
28
+ });
26
29
 
27
30
  try {
28
31
  const openapiProvider = alepha.inject(