alepha 0.15.0 → 0.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (551) hide show
  1. package/README.md +43 -98
  2. package/dist/api/audits/index.d.ts +630 -653
  3. package/dist/api/audits/index.d.ts.map +1 -1
  4. package/dist/api/audits/index.js +12 -35
  5. package/dist/api/audits/index.js.map +1 -1
  6. package/dist/api/files/index.d.ts +365 -358
  7. package/dist/api/files/index.d.ts.map +1 -1
  8. package/dist/api/files/index.js +12 -5
  9. package/dist/api/files/index.js.map +1 -1
  10. package/dist/api/jobs/index.d.ts +255 -248
  11. package/dist/api/jobs/index.d.ts.map +1 -1
  12. package/dist/api/jobs/index.js +10 -3
  13. package/dist/api/jobs/index.js.map +1 -1
  14. package/dist/api/keys/index.d.ts +413 -0
  15. package/dist/api/keys/index.d.ts.map +1 -0
  16. package/dist/api/keys/index.js +476 -0
  17. package/dist/api/keys/index.js.map +1 -0
  18. package/dist/api/notifications/index.browser.js +4 -4
  19. package/dist/api/notifications/index.browser.js.map +1 -1
  20. package/dist/api/notifications/index.d.ts +84 -78
  21. package/dist/api/notifications/index.d.ts.map +1 -1
  22. package/dist/api/notifications/index.js +14 -8
  23. package/dist/api/notifications/index.js.map +1 -1
  24. package/dist/api/parameters/index.d.ts +528 -535
  25. package/dist/api/parameters/index.d.ts.map +1 -1
  26. package/dist/api/parameters/index.js +30 -37
  27. package/dist/api/parameters/index.js.map +1 -1
  28. package/dist/api/users/index.d.ts +1221 -910
  29. package/dist/api/users/index.d.ts.map +1 -1
  30. package/dist/api/users/index.js +2556 -248
  31. package/dist/api/users/index.js.map +1 -1
  32. package/dist/api/verifications/index.d.ts +142 -136
  33. package/dist/api/verifications/index.d.ts.map +1 -1
  34. package/dist/api/verifications/index.js +12 -4
  35. package/dist/api/verifications/index.js.map +1 -1
  36. package/dist/batch/index.d.ts +142 -162
  37. package/dist/batch/index.d.ts.map +1 -1
  38. package/dist/batch/index.js +31 -44
  39. package/dist/batch/index.js.map +1 -1
  40. package/dist/bucket/index.d.ts +595 -171
  41. package/dist/bucket/index.d.ts.map +1 -1
  42. package/dist/bucket/index.js +1856 -12
  43. package/dist/bucket/index.js.map +1 -1
  44. package/dist/cache/core/index.d.ts +225 -53
  45. package/dist/cache/core/index.d.ts.map +1 -1
  46. package/dist/cache/core/index.js +213 -7
  47. package/dist/cache/core/index.js.map +1 -1
  48. package/dist/cache/redis/index.d.ts +1 -0
  49. package/dist/cache/redis/index.d.ts.map +1 -1
  50. package/dist/cache/redis/index.js +6 -2
  51. package/dist/cache/redis/index.js.map +1 -1
  52. package/dist/cli/index.d.ts +834 -226
  53. package/dist/cli/index.d.ts.map +1 -1
  54. package/dist/cli/index.js +2872 -417
  55. package/dist/cli/index.js.map +1 -1
  56. package/dist/command/index.d.ts +458 -310
  57. package/dist/command/index.d.ts.map +1 -1
  58. package/dist/command/index.js +2011 -76
  59. package/dist/command/index.js.map +1 -1
  60. package/dist/core/index.browser.js +309 -97
  61. package/dist/core/index.browser.js.map +1 -1
  62. package/dist/core/index.d.ts +796 -701
  63. package/dist/core/index.d.ts.map +1 -1
  64. package/dist/core/index.js +329 -97
  65. package/dist/core/index.js.map +1 -1
  66. package/dist/core/index.native.js +309 -97
  67. package/dist/core/index.native.js.map +1 -1
  68. package/dist/datetime/index.d.ts +59 -44
  69. package/dist/datetime/index.d.ts.map +1 -1
  70. package/dist/datetime/index.js +15 -0
  71. package/dist/datetime/index.js.map +1 -1
  72. package/dist/email/index.d.ts +314 -19
  73. package/dist/email/index.d.ts.map +1 -1
  74. package/dist/email/index.js +1852 -7
  75. package/dist/email/index.js.map +1 -1
  76. package/dist/fake/index.d.ts +5500 -5418
  77. package/dist/fake/index.d.ts.map +1 -1
  78. package/dist/fake/index.js +113 -42
  79. package/dist/fake/index.js.map +1 -1
  80. package/dist/lock/core/index.d.ts +219 -212
  81. package/dist/lock/core/index.d.ts.map +1 -1
  82. package/dist/lock/core/index.js +11 -4
  83. package/dist/lock/core/index.js.map +1 -1
  84. package/dist/lock/redis/index.d.ts.map +1 -1
  85. package/dist/logger/index.d.ts +41 -90
  86. package/dist/logger/index.d.ts.map +1 -1
  87. package/dist/logger/index.js +15 -68
  88. package/dist/logger/index.js.map +1 -1
  89. package/dist/mcp/index.d.ts +228 -230
  90. package/dist/mcp/index.d.ts.map +1 -1
  91. package/dist/mcp/index.js +32 -31
  92. package/dist/mcp/index.js.map +1 -1
  93. package/dist/orm/index.browser.js +12 -12
  94. package/dist/orm/index.browser.js.map +1 -1
  95. package/dist/orm/index.bun.js +90 -80
  96. package/dist/orm/index.bun.js.map +1 -1
  97. package/dist/orm/index.d.ts +1434 -1459
  98. package/dist/orm/index.d.ts.map +1 -1
  99. package/dist/orm/index.js +112 -130
  100. package/dist/orm/index.js.map +1 -1
  101. package/dist/queue/core/index.d.ts +262 -254
  102. package/dist/queue/core/index.d.ts.map +1 -1
  103. package/dist/queue/core/index.js +14 -6
  104. package/dist/queue/core/index.js.map +1 -1
  105. package/dist/queue/redis/index.d.ts.map +1 -1
  106. package/dist/react/auth/index.browser.js +108 -0
  107. package/dist/react/auth/index.browser.js.map +1 -0
  108. package/dist/react/auth/index.d.ts +100 -0
  109. package/dist/react/auth/index.d.ts.map +1 -0
  110. package/dist/react/auth/index.js +145 -0
  111. package/dist/react/auth/index.js.map +1 -0
  112. package/dist/react/core/index.d.ts +469 -0
  113. package/dist/react/core/index.d.ts.map +1 -0
  114. package/dist/react/core/index.js +464 -0
  115. package/dist/react/core/index.js.map +1 -0
  116. package/dist/react/form/index.d.ts +232 -0
  117. package/dist/react/form/index.d.ts.map +1 -0
  118. package/dist/react/form/index.js +432 -0
  119. package/dist/react/form/index.js.map +1 -0
  120. package/dist/react/head/index.browser.js +423 -0
  121. package/dist/react/head/index.browser.js.map +1 -0
  122. package/dist/react/head/index.d.ts +288 -0
  123. package/dist/react/head/index.d.ts.map +1 -0
  124. package/dist/react/head/index.js +465 -0
  125. package/dist/react/head/index.js.map +1 -0
  126. package/dist/react/i18n/index.d.ts +175 -0
  127. package/dist/react/i18n/index.d.ts.map +1 -0
  128. package/dist/react/i18n/index.js +224 -0
  129. package/dist/react/i18n/index.js.map +1 -0
  130. package/dist/react/router/index.browser.js +1980 -0
  131. package/dist/react/router/index.browser.js.map +1 -0
  132. package/dist/react/router/index.d.ts +2068 -0
  133. package/dist/react/router/index.d.ts.map +1 -0
  134. package/dist/react/router/index.js +4932 -0
  135. package/dist/react/router/index.js.map +1 -0
  136. package/dist/react/websocket/index.d.ts +117 -0
  137. package/dist/react/websocket/index.d.ts.map +1 -0
  138. package/dist/react/websocket/index.js +107 -0
  139. package/dist/react/websocket/index.js.map +1 -0
  140. package/dist/redis/index.bun.js +4 -0
  141. package/dist/redis/index.bun.js.map +1 -1
  142. package/dist/redis/index.d.ts +127 -130
  143. package/dist/redis/index.d.ts.map +1 -1
  144. package/dist/redis/index.js +16 -25
  145. package/dist/redis/index.js.map +1 -1
  146. package/dist/retry/index.d.ts +80 -71
  147. package/dist/retry/index.d.ts.map +1 -1
  148. package/dist/retry/index.js +11 -2
  149. package/dist/retry/index.js.map +1 -1
  150. package/dist/router/index.d.ts +6 -6
  151. package/dist/router/index.d.ts.map +1 -1
  152. package/dist/scheduler/index.d.ts +119 -28
  153. package/dist/scheduler/index.d.ts.map +1 -1
  154. package/dist/scheduler/index.js +404 -3
  155. package/dist/scheduler/index.js.map +1 -1
  156. package/dist/security/index.d.ts +642 -228
  157. package/dist/security/index.d.ts.map +1 -1
  158. package/dist/security/index.js +1579 -37
  159. package/dist/security/index.js.map +1 -1
  160. package/dist/server/auth/index.d.ts +1141 -111
  161. package/dist/server/auth/index.d.ts.map +1 -1
  162. package/dist/server/auth/index.js +1261 -25
  163. package/dist/server/auth/index.js.map +1 -1
  164. package/dist/server/cache/index.d.ts +63 -78
  165. package/dist/server/cache/index.d.ts.map +1 -1
  166. package/dist/server/cache/index.js +7 -22
  167. package/dist/server/cache/index.js.map +1 -1
  168. package/dist/server/compress/index.d.ts +13 -5
  169. package/dist/server/compress/index.d.ts.map +1 -1
  170. package/dist/server/compress/index.js +10 -2
  171. package/dist/server/compress/index.js.map +1 -1
  172. package/dist/server/cookies/index.d.ts +46 -22
  173. package/dist/server/cookies/index.d.ts.map +1 -1
  174. package/dist/server/cookies/index.js +7 -5
  175. package/dist/server/cookies/index.js.map +1 -1
  176. package/dist/server/core/index.d.ts +307 -196
  177. package/dist/server/core/index.d.ts.map +1 -1
  178. package/dist/server/core/index.js +271 -38
  179. package/dist/server/core/index.js.map +1 -1
  180. package/dist/server/cors/index.d.ts +24 -34
  181. package/dist/server/cors/index.d.ts.map +1 -1
  182. package/dist/server/cors/index.js +7 -21
  183. package/dist/server/cors/index.js.map +1 -1
  184. package/dist/server/health/index.d.ts +25 -19
  185. package/dist/server/health/index.d.ts.map +1 -1
  186. package/dist/server/health/index.js +8 -2
  187. package/dist/server/health/index.js.map +1 -1
  188. package/dist/server/helmet/index.d.ts +13 -5
  189. package/dist/server/helmet/index.d.ts.map +1 -1
  190. package/dist/server/helmet/index.js +11 -3
  191. package/dist/server/helmet/index.js.map +1 -1
  192. package/dist/server/links/index.browser.js +9 -1
  193. package/dist/server/links/index.browser.js.map +1 -1
  194. package/dist/server/links/index.d.ts +133 -128
  195. package/dist/server/links/index.d.ts.map +1 -1
  196. package/dist/server/links/index.js +24 -11
  197. package/dist/server/links/index.js.map +1 -1
  198. package/dist/server/metrics/index.d.ts +524 -4
  199. package/dist/server/metrics/index.d.ts.map +1 -1
  200. package/dist/server/metrics/index.js +4472 -7
  201. package/dist/server/metrics/index.js.map +1 -1
  202. package/dist/server/multipart/index.d.ts +15 -9
  203. package/dist/server/multipart/index.d.ts.map +1 -1
  204. package/dist/server/multipart/index.js +9 -3
  205. package/dist/server/multipart/index.js.map +1 -1
  206. package/dist/server/proxy/index.d.ts +110 -104
  207. package/dist/server/proxy/index.d.ts.map +1 -1
  208. package/dist/server/proxy/index.js +8 -2
  209. package/dist/server/proxy/index.js.map +1 -1
  210. package/dist/server/rate-limit/index.d.ts +46 -51
  211. package/dist/server/rate-limit/index.d.ts.map +1 -1
  212. package/dist/server/rate-limit/index.js +18 -55
  213. package/dist/server/rate-limit/index.js.map +1 -1
  214. package/dist/server/static/index.d.ts +181 -48
  215. package/dist/server/static/index.d.ts.map +1 -1
  216. package/dist/server/static/index.js +1848 -5
  217. package/dist/server/static/index.js.map +1 -1
  218. package/dist/server/swagger/index.d.ts +348 -53
  219. package/dist/server/swagger/index.d.ts.map +1 -1
  220. package/dist/server/swagger/index.js +1849 -6
  221. package/dist/server/swagger/index.js.map +1 -1
  222. package/dist/sms/index.d.ts +312 -18
  223. package/dist/sms/index.d.ts.map +1 -1
  224. package/dist/sms/index.js +1854 -10
  225. package/dist/sms/index.js.map +1 -1
  226. package/dist/system/index.browser.js +496 -0
  227. package/dist/system/index.browser.js.map +1 -0
  228. package/dist/system/index.d.ts +1158 -0
  229. package/dist/system/index.d.ts.map +1 -0
  230. package/dist/{file → system}/index.js +412 -20
  231. package/dist/system/index.js.map +1 -0
  232. package/dist/thread/index.d.ts +82 -73
  233. package/dist/thread/index.d.ts.map +1 -1
  234. package/dist/thread/index.js +13 -4
  235. package/dist/thread/index.js.map +1 -1
  236. package/dist/topic/core/index.d.ts +330 -323
  237. package/dist/topic/core/index.d.ts.map +1 -1
  238. package/dist/topic/core/index.js +12 -5
  239. package/dist/topic/core/index.js.map +1 -1
  240. package/dist/topic/redis/index.d.ts +6 -6
  241. package/dist/topic/redis/index.d.ts.map +1 -1
  242. package/dist/vite/index.d.ts +163 -5825
  243. package/dist/vite/index.d.ts.map +1 -1
  244. package/dist/vite/index.js +130 -477
  245. package/dist/vite/index.js.map +1 -1
  246. package/dist/websocket/index.browser.js +3 -3
  247. package/dist/websocket/index.browser.js.map +1 -1
  248. package/dist/websocket/index.d.ts +287 -283
  249. package/dist/websocket/index.d.ts.map +1 -1
  250. package/dist/websocket/index.js +15 -11
  251. package/dist/websocket/index.js.map +1 -1
  252. package/package.json +86 -17
  253. package/src/api/audits/index.ts +10 -33
  254. package/src/api/files/__tests__/$bucket.spec.ts +1 -1
  255. package/src/api/files/controllers/AdminFileStatsController.spec.ts +1 -1
  256. package/src/api/files/controllers/FileController.spec.ts +1 -1
  257. package/src/api/files/index.ts +10 -3
  258. package/src/api/files/jobs/FileJobs.spec.ts +1 -1
  259. package/src/api/files/services/FileService.spec.ts +1 -1
  260. package/src/api/jobs/index.ts +10 -3
  261. package/src/api/keys/controllers/AdminApiKeyController.ts +75 -0
  262. package/src/api/keys/controllers/ApiKeyController.ts +103 -0
  263. package/src/api/keys/entities/apiKeyEntity.ts +41 -0
  264. package/src/api/keys/index.ts +49 -0
  265. package/src/api/keys/schemas/adminApiKeyQuerySchema.ts +7 -0
  266. package/src/api/keys/schemas/adminApiKeyResourceSchema.ts +17 -0
  267. package/src/api/keys/schemas/createApiKeyBodySchema.ts +7 -0
  268. package/src/api/keys/schemas/createApiKeyResponseSchema.ts +11 -0
  269. package/src/api/keys/schemas/listApiKeyResponseSchema.ts +15 -0
  270. package/src/api/keys/schemas/revokeApiKeyParamsSchema.ts +5 -0
  271. package/src/api/keys/schemas/revokeApiKeyResponseSchema.ts +5 -0
  272. package/src/api/keys/services/ApiKeyService.spec.ts +553 -0
  273. package/src/api/keys/services/ApiKeyService.ts +306 -0
  274. package/src/api/logs/TODO.md +52 -0
  275. package/src/api/notifications/index.ts +10 -4
  276. package/src/api/parameters/index.ts +9 -30
  277. package/src/api/parameters/primitives/$config.ts +12 -4
  278. package/src/api/parameters/services/ConfigStore.ts +9 -3
  279. package/src/api/users/__tests__/ApiKeys-integration.spec.ts +1035 -0
  280. package/src/api/users/__tests__/ApiKeys.spec.ts +401 -0
  281. package/src/api/users/index.ts +14 -3
  282. package/src/api/users/primitives/$realm.ts +33 -5
  283. package/src/api/users/providers/RealmProvider.ts +1 -12
  284. package/src/api/users/services/SessionService.ts +1 -11
  285. package/src/api/verifications/controllers/VerificationController.ts +2 -0
  286. package/src/api/verifications/index.ts +10 -4
  287. package/src/batch/index.ts +9 -36
  288. package/src/batch/primitives/$batch.ts +0 -8
  289. package/src/batch/providers/BatchProvider.ts +29 -2
  290. package/src/bucket/__tests__/shared.ts +1 -1
  291. package/src/bucket/index.ts +13 -6
  292. package/src/bucket/primitives/$bucket.ts +1 -1
  293. package/src/bucket/providers/LocalFileStorageProvider.ts +1 -1
  294. package/src/bucket/providers/MemoryFileStorageProvider.ts +1 -1
  295. package/src/cache/core/__tests__/shared.ts +30 -0
  296. package/src/cache/core/index.ts +11 -6
  297. package/src/cache/core/primitives/$cache.spec.ts +5 -0
  298. package/src/cache/core/providers/CacheProvider.ts +17 -0
  299. package/src/cache/core/providers/MemoryCacheProvider.ts +300 -1
  300. package/src/cache/redis/__tests__/cache-redis.spec.ts +5 -0
  301. package/src/cache/redis/providers/RedisCacheProvider.ts +9 -0
  302. package/src/cli/apps/AlephaCli.ts +3 -16
  303. package/src/cli/apps/AlephaPackageBuilderCli.ts +10 -2
  304. package/src/cli/atoms/appEntryOptions.ts +13 -0
  305. package/src/cli/atoms/buildOptions.ts +1 -1
  306. package/src/cli/atoms/changelogOptions.ts +1 -1
  307. package/src/cli/commands/build.ts +64 -52
  308. package/src/cli/commands/db.ts +17 -11
  309. package/src/cli/commands/deploy.ts +1 -1
  310. package/src/cli/commands/dev.ts +13 -49
  311. package/src/cli/commands/gen/env.ts +6 -3
  312. package/src/cli/commands/gen/openapi.ts +5 -2
  313. package/src/cli/commands/init.spec.ts +544 -0
  314. package/src/cli/commands/init.ts +101 -58
  315. package/src/cli/commands/lint.ts +8 -2
  316. package/src/cli/commands/typecheck.ts +11 -0
  317. package/src/cli/defineConfig.ts +9 -0
  318. package/src/cli/index.ts +2 -1
  319. package/src/cli/providers/AppEntryProvider.ts +131 -0
  320. package/src/cli/providers/ViteBuildProvider.ts +40 -0
  321. package/src/cli/providers/ViteDevServerProvider.ts +378 -0
  322. package/src/cli/services/AlephaCliUtils.ts +39 -93
  323. package/src/cli/services/PackageManagerUtils.ts +140 -17
  324. package/src/cli/services/ProjectScaffolder.ts +169 -101
  325. package/src/cli/services/ViteUtils.ts +82 -0
  326. package/src/cli/{assets/claudeMd.ts → templates/agentMd.ts} +41 -28
  327. package/src/cli/{assets → templates}/apiHelloControllerTs.ts +2 -1
  328. package/src/cli/{assets → templates}/biomeJson.ts +2 -1
  329. package/src/cli/{assets → templates}/dummySpecTs.ts +2 -1
  330. package/src/cli/{assets → templates}/editorconfig.ts +2 -1
  331. package/src/cli/templates/gitignore.ts +39 -0
  332. package/src/cli/{assets → templates}/mainBrowserTs.ts +2 -1
  333. package/src/cli/templates/mainCss.ts +33 -0
  334. package/src/cli/templates/mainServerTs.ts +33 -0
  335. package/src/cli/{assets → templates}/tsconfigJson.ts +2 -1
  336. package/src/cli/templates/webAppRouterTs.ts +50 -0
  337. package/src/cli/templates/webHelloComponentTsx.ts +20 -0
  338. package/src/command/helpers/Runner.spec.ts +4 -0
  339. package/src/command/helpers/Runner.ts +3 -21
  340. package/src/command/index.ts +12 -4
  341. package/src/command/providers/CliProvider.spec.ts +1067 -0
  342. package/src/command/providers/CliProvider.ts +203 -40
  343. package/src/core/Alepha.ts +3 -9
  344. package/src/core/__tests__/Alepha-start.spec.ts +4 -4
  345. package/src/core/helpers/jsonSchemaToTypeBox.spec.ts +771 -0
  346. package/src/core/helpers/jsonSchemaToTypeBox.ts +62 -10
  347. package/src/core/index.shared.ts +1 -0
  348. package/src/core/index.ts +20 -0
  349. package/src/core/primitives/$module.ts +12 -0
  350. package/src/core/providers/EventManager.spec.ts +0 -71
  351. package/src/core/providers/EventManager.ts +3 -15
  352. package/src/core/providers/Json.ts +2 -14
  353. package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +257 -0
  354. package/src/core/providers/KeylessJsonSchemaCodec.ts +396 -14
  355. package/src/core/providers/SchemaValidator.spec.ts +236 -0
  356. package/src/datetime/index.ts +15 -0
  357. package/src/email/index.ts +10 -5
  358. package/src/email/providers/LocalEmailProvider.spec.ts +1 -1
  359. package/src/email/providers/LocalEmailProvider.ts +1 -1
  360. package/src/fake/__tests__/keyName.example.ts +1 -1
  361. package/src/fake/__tests__/keyName.spec.ts +5 -5
  362. package/src/fake/index.ts +9 -6
  363. package/src/fake/providers/FakeProvider.spec.ts +258 -40
  364. package/src/fake/providers/FakeProvider.ts +133 -19
  365. package/src/lock/core/index.ts +11 -4
  366. package/src/logger/index.ts +17 -66
  367. package/src/logger/providers/PrettyFormatterProvider.ts +0 -9
  368. package/src/mcp/errors/McpError.ts +30 -0
  369. package/src/mcp/index.ts +13 -27
  370. package/src/mcp/transports/SseMcpTransport.ts +6 -7
  371. package/src/orm/__tests__/PostgresProvider.spec.ts +2 -2
  372. package/src/orm/index.browser.ts +2 -2
  373. package/src/orm/index.bun.ts +4 -2
  374. package/src/orm/index.ts +21 -47
  375. package/src/orm/providers/DrizzleKitProvider.ts +3 -5
  376. package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -0
  377. package/src/orm/services/Repository.ts +18 -3
  378. package/src/queue/core/index.ts +14 -6
  379. package/src/react/auth/__tests__/$auth.spec.ts +202 -0
  380. package/src/react/auth/hooks/useAuth.ts +32 -0
  381. package/src/react/auth/index.browser.ts +13 -0
  382. package/src/react/auth/index.shared.ts +2 -0
  383. package/src/react/auth/index.ts +48 -0
  384. package/src/react/auth/providers/ReactAuthProvider.ts +16 -0
  385. package/src/react/auth/services/ReactAuth.ts +135 -0
  386. package/src/react/core/__tests__/Router.spec.tsx +169 -0
  387. package/src/react/core/components/ClientOnly.tsx +49 -0
  388. package/src/react/core/components/ErrorBoundary.tsx +73 -0
  389. package/src/react/core/contexts/AlephaContext.ts +7 -0
  390. package/src/react/core/contexts/AlephaProvider.tsx +42 -0
  391. package/src/react/core/hooks/useAction.browser.spec.tsx +569 -0
  392. package/src/react/core/hooks/useAction.ts +480 -0
  393. package/src/react/core/hooks/useAlepha.ts +26 -0
  394. package/src/react/core/hooks/useClient.ts +17 -0
  395. package/src/react/core/hooks/useEvents.ts +51 -0
  396. package/src/react/core/hooks/useInject.ts +12 -0
  397. package/src/react/core/hooks/useStore.ts +52 -0
  398. package/src/react/core/index.ts +90 -0
  399. package/src/react/form/components/FormState.tsx +17 -0
  400. package/src/react/form/errors/FormValidationError.ts +18 -0
  401. package/src/react/form/hooks/useForm.browser.spec.tsx +366 -0
  402. package/src/react/form/hooks/useForm.ts +47 -0
  403. package/src/react/form/hooks/useFormState.ts +130 -0
  404. package/src/react/form/index.ts +44 -0
  405. package/src/react/form/services/FormModel.ts +614 -0
  406. package/src/react/head/helpers/SeoExpander.spec.ts +203 -0
  407. package/src/react/head/helpers/SeoExpander.ts +142 -0
  408. package/src/react/head/hooks/useHead.spec.tsx +288 -0
  409. package/src/react/head/hooks/useHead.ts +62 -0
  410. package/src/react/head/index.browser.ts +26 -0
  411. package/src/react/head/index.ts +44 -0
  412. package/src/react/head/interfaces/Head.ts +105 -0
  413. package/src/react/head/primitives/$head.ts +25 -0
  414. package/src/react/head/providers/BrowserHeadProvider.browser.spec.ts +196 -0
  415. package/src/react/head/providers/BrowserHeadProvider.ts +212 -0
  416. package/src/react/head/providers/HeadProvider.ts +168 -0
  417. package/src/react/head/providers/ServerHeadProvider.ts +31 -0
  418. package/src/react/i18n/__tests__/integration.spec.tsx +239 -0
  419. package/src/react/i18n/components/Localize.spec.tsx +357 -0
  420. package/src/react/i18n/components/Localize.tsx +35 -0
  421. package/src/react/i18n/hooks/useI18n.browser.spec.tsx +438 -0
  422. package/src/react/i18n/hooks/useI18n.ts +18 -0
  423. package/src/react/i18n/index.ts +41 -0
  424. package/src/react/i18n/primitives/$dictionary.ts +69 -0
  425. package/src/react/i18n/providers/I18nProvider.spec.ts +389 -0
  426. package/src/react/i18n/providers/I18nProvider.ts +278 -0
  427. package/src/react/router/__tests__/page-head-browser.browser.spec.ts +95 -0
  428. package/src/react/router/__tests__/page-head.spec.ts +48 -0
  429. package/src/react/router/__tests__/seo-head.spec.ts +125 -0
  430. package/src/react/router/atoms/ssrManifestAtom.ts +58 -0
  431. package/src/react/router/components/ErrorViewer.tsx +872 -0
  432. package/src/react/router/components/Link.tsx +23 -0
  433. package/src/react/router/components/NestedView.tsx +223 -0
  434. package/src/react/router/components/NotFound.tsx +30 -0
  435. package/src/react/router/constants/PAGE_PRELOAD_KEY.ts +6 -0
  436. package/src/react/router/contexts/RouterLayerContext.ts +12 -0
  437. package/src/react/router/errors/Redirection.ts +28 -0
  438. package/src/react/router/hooks/useActive.ts +52 -0
  439. package/src/react/router/hooks/useQueryParams.ts +63 -0
  440. package/src/react/router/hooks/useRouter.ts +20 -0
  441. package/src/react/router/hooks/useRouterState.ts +11 -0
  442. package/src/react/router/index.browser.ts +45 -0
  443. package/src/react/router/index.shared.ts +19 -0
  444. package/src/react/router/index.ts +142 -0
  445. package/src/react/router/primitives/$page.browser.spec.tsx +851 -0
  446. package/src/react/router/primitives/$page.spec.tsx +708 -0
  447. package/src/react/router/primitives/$page.ts +497 -0
  448. package/src/react/router/providers/ReactBrowserProvider.ts +309 -0
  449. package/src/react/router/providers/ReactBrowserRendererProvider.ts +25 -0
  450. package/src/react/router/providers/ReactBrowserRouterProvider.ts +168 -0
  451. package/src/react/router/providers/ReactPageProvider.ts +726 -0
  452. package/src/react/router/providers/ReactServerProvider.spec.tsx +316 -0
  453. package/src/react/router/providers/ReactServerProvider.ts +558 -0
  454. package/src/react/router/providers/ReactServerTemplateProvider.ts +979 -0
  455. package/src/react/router/providers/SSRManifestProvider.ts +334 -0
  456. package/src/react/router/services/ReactPageServerService.ts +48 -0
  457. package/src/react/router/services/ReactPageService.ts +27 -0
  458. package/src/react/router/services/ReactRouter.ts +262 -0
  459. package/src/react/websocket/hooks/useRoom.tsx +242 -0
  460. package/src/react/websocket/index.ts +7 -0
  461. package/src/redis/__tests__/redis.spec.ts +13 -0
  462. package/src/redis/index.ts +9 -25
  463. package/src/redis/providers/BunRedisProvider.ts +9 -0
  464. package/src/redis/providers/NodeRedisProvider.ts +8 -0
  465. package/src/redis/providers/RedisProvider.ts +16 -0
  466. package/src/retry/index.ts +11 -2
  467. package/src/router/index.ts +15 -0
  468. package/src/scheduler/index.ts +11 -2
  469. package/src/security/__tests__/BasicAuth.spec.ts +2 -0
  470. package/src/security/__tests__/ServerSecurityProvider.spec.ts +13 -5
  471. package/src/security/index.ts +15 -10
  472. package/src/security/interfaces/IssuerResolver.ts +27 -0
  473. package/src/security/primitives/$issuer.ts +55 -0
  474. package/src/security/providers/SecurityProvider.ts +179 -0
  475. package/src/security/providers/ServerBasicAuthProvider.ts +6 -2
  476. package/src/security/providers/ServerSecurityProvider.ts +36 -22
  477. package/src/server/auth/index.ts +12 -7
  478. package/src/server/cache/index.ts +7 -22
  479. package/src/server/compress/index.ts +10 -2
  480. package/src/server/cookies/index.ts +7 -5
  481. package/src/server/cookies/primitives/$cookie.ts +33 -11
  482. package/src/server/core/index.ts +17 -7
  483. package/src/server/core/interfaces/ServerRequest.ts +83 -1
  484. package/src/server/core/primitives/$action.spec.ts +1 -1
  485. package/src/server/core/primitives/$action.ts +8 -3
  486. package/src/server/core/providers/BunHttpServerProvider.ts +1 -1
  487. package/src/server/core/providers/NodeHttpServerProvider.spec.ts +125 -0
  488. package/src/server/core/providers/NodeHttpServerProvider.ts +77 -22
  489. package/src/server/core/providers/ServerLoggerProvider.ts +2 -2
  490. package/src/server/core/providers/ServerProvider.ts +9 -12
  491. package/src/server/core/services/ServerRequestParser.spec.ts +520 -0
  492. package/src/server/core/services/ServerRequestParser.ts +306 -13
  493. package/src/server/cors/index.ts +7 -21
  494. package/src/server/cors/primitives/$cors.ts +6 -2
  495. package/src/server/health/index.ts +8 -2
  496. package/src/server/helmet/index.ts +11 -3
  497. package/src/server/links/atoms/apiLinksAtom.ts +7 -0
  498. package/src/server/links/index.browser.ts +2 -0
  499. package/src/server/links/index.ts +13 -6
  500. package/src/server/metrics/index.ts +10 -3
  501. package/src/server/multipart/index.ts +9 -3
  502. package/src/server/proxy/index.ts +8 -2
  503. package/src/server/rate-limit/index.ts +21 -25
  504. package/src/server/rate-limit/primitives/$rateLimit.ts +6 -2
  505. package/src/server/rate-limit/providers/ServerRateLimitProvider.spec.ts +38 -14
  506. package/src/server/rate-limit/providers/ServerRateLimitProvider.ts +22 -56
  507. package/src/server/static/index.ts +8 -2
  508. package/src/server/static/providers/ServerStaticProvider.ts +1 -1
  509. package/src/server/swagger/index.ts +9 -4
  510. package/src/server/swagger/providers/ServerSwaggerProvider.ts +1 -1
  511. package/src/sms/index.ts +9 -5
  512. package/src/sms/providers/LocalSmsProvider.spec.ts +1 -1
  513. package/src/sms/providers/LocalSmsProvider.ts +1 -1
  514. package/src/system/index.browser.ts +11 -0
  515. package/src/system/index.ts +62 -0
  516. package/src/{file → system}/providers/FileSystemProvider.ts +16 -0
  517. package/src/{file → system}/providers/MemoryFileSystemProvider.ts +116 -3
  518. package/src/system/providers/MemoryShellProvider.ts +164 -0
  519. package/src/{file → system}/providers/NodeFileSystemProvider.spec.ts +2 -2
  520. package/src/{file → system}/providers/NodeFileSystemProvider.ts +36 -0
  521. package/src/system/providers/NodeShellProvider.ts +184 -0
  522. package/src/system/providers/ShellProvider.ts +74 -0
  523. package/src/{file → system}/services/FileDetector.spec.ts +2 -2
  524. package/src/thread/index.ts +11 -2
  525. package/src/topic/core/index.ts +12 -5
  526. package/src/vite/index.ts +3 -2
  527. package/src/vite/tasks/buildClient.ts +2 -8
  528. package/src/vite/tasks/buildServer.ts +84 -21
  529. package/src/vite/tasks/copyAssets.ts +5 -4
  530. package/src/vite/tasks/generateSitemap.ts +64 -23
  531. package/src/vite/tasks/index.ts +0 -2
  532. package/src/vite/tasks/prerenderPages.ts +49 -24
  533. package/src/websocket/index.ts +12 -8
  534. package/dist/file/index.d.ts +0 -839
  535. package/dist/file/index.d.ts.map +0 -1
  536. package/dist/file/index.js.map +0 -1
  537. package/src/cli/assets/indexHtml.ts +0 -15
  538. package/src/cli/assets/mainServerTs.ts +0 -24
  539. package/src/cli/assets/webAppRouterTs.ts +0 -15
  540. package/src/cli/assets/webHelloComponentTsx.ts +0 -16
  541. package/src/cli/commands/format.ts +0 -23
  542. package/src/file/index.ts +0 -43
  543. package/src/vite/helpers/boot.ts +0 -117
  544. package/src/vite/plugins/viteAlephaDev.ts +0 -177
  545. package/src/vite/tasks/devServer.ts +0 -71
  546. package/src/vite/tasks/runAlepha.ts +0 -270
  547. /package/dist/orm/{chunk-DtkW-qnP.js → chunk-DH6iiROE.js} +0 -0
  548. /package/src/cli/{assets → templates}/apiIndexTs.ts +0 -0
  549. /package/src/cli/{assets → templates}/webIndexTs.ts +0 -0
  550. /package/src/{file → system}/errors/FileError.ts +0 -0
  551. /package/src/{file → system}/services/FileDetector.ts +0 -0
@@ -0,0 +1,378 @@
1
+ import { $inject, type Alepha, AlephaError } from "alepha";
2
+ import { $logger } from "alepha/logger";
3
+ import { FileSystemProvider } from "alepha/system";
4
+ import { importVite, importViteReact, viteAlephaSsrPreload } from "alepha/vite";
5
+ import type { InlineConfig, Plugin, ViteDevServer } from "vite";
6
+ import { ViteUtils } from "../services/ViteUtils.ts";
7
+ import type { AppEntry } from "./AppEntryProvider.ts";
8
+
9
+ export interface ViteDevServerOptions {
10
+ /**
11
+ * Root directory of the project.
12
+ */
13
+ root: string;
14
+
15
+ /**
16
+ * Path to the server entry file.
17
+ */
18
+ entry: AppEntry;
19
+
20
+ /**
21
+ * Port to run the dev server on.
22
+ */
23
+ port?: number;
24
+
25
+ /**
26
+ * Host to bind the dev server to.
27
+ */
28
+ host?: string | boolean;
29
+ }
30
+
31
+ /**
32
+ * Vite development server with Alepha integration.
33
+ *
34
+ * Architecture:
35
+ * - Vite runs in middleware mode (no HTTP server)
36
+ * - Alepha is the HTTP server via server:onRequest event
37
+ * - Request flow: Page requests → Alepha SSR, Assets → Vite middleware
38
+ *
39
+ * HMR Strategy:
40
+ * - Browser-only changes (CSS, client components) → Vite HMR (React Fast Refresh)
41
+ * - Server-only changes → Restart Alepha → Full browser reload
42
+ * - Shared changes → Restart Alepha → Let Vite HMR propagate
43
+ *
44
+ * Features:
45
+ * - Automatic .env reload detection
46
+ * - Error recovery on next file change
47
+ * - Optimized module invalidation (only changed files + importers)
48
+ */
49
+ export class ViteDevServerProvider {
50
+ protected readonly log = $logger();
51
+ protected readonly fs = $inject(FileSystemProvider);
52
+ protected readonly templateProvider = $inject(ViteUtils);
53
+ protected server!: ViteDevServer;
54
+ protected options!: ViteDevServerOptions;
55
+ protected alepha: Alepha | null = null;
56
+ protected hasError = false;
57
+ protected changedFiles = new Set<string>();
58
+
59
+ public async init(options: ViteDevServerOptions): Promise<Alepha> {
60
+ this.options = options;
61
+ await this.createViteServer();
62
+ return await this.loadAlepha(true);
63
+ }
64
+
65
+ public async start(): Promise<void> {
66
+ await this.alepha?.start();
67
+ }
68
+
69
+ /**
70
+ * Create the Vite server in middleware mode.
71
+ */
72
+ protected async createViteServer(): Promise<void> {
73
+ const { createServer } = await importVite();
74
+ const viteReact = await importViteReact();
75
+
76
+ const plugins: Plugin[] = [];
77
+ if (viteReact) plugins.push(viteReact());
78
+ plugins.push(viteAlephaSsrPreload());
79
+ plugins.push(this.createHmrPlugin());
80
+
81
+ this.server = await createServer({
82
+ root: this.options.root,
83
+ plugins,
84
+ server: { middlewareMode: true },
85
+ appType: "custom",
86
+ customLogger: {
87
+ info: () => {},
88
+ warn: this.log.warn.bind(this.log),
89
+ error: this.log.error.bind(this.log),
90
+ warnOnce: this.log.warn.bind(this.log),
91
+ clearScreen: () => {},
92
+ hasWarned: false,
93
+ hasErrorLogged: () => false,
94
+ },
95
+ } satisfies InlineConfig);
96
+
97
+ // Intercept .env changes (Vite calls restart() for .env files)
98
+ this.server.restart = async () => {
99
+ const startTime = Date.now();
100
+ try {
101
+ this.hasError = true; // Force full invalidation for env changes
102
+ await this.loadAlepha(false);
103
+ await this.alepha?.start();
104
+ this.log.debug(`Env reloaded in ${Date.now() - startTime}ms`);
105
+ this.sendBrowserReload();
106
+ } catch (err) {
107
+ this.hasError = true;
108
+ this.log.error("Reload failed", err);
109
+ this.log.warn("Waiting for file changes to retry...");
110
+ this.alepha = null;
111
+ }
112
+ };
113
+ }
114
+
115
+ /**
116
+ * Vite plugin to handle HMR for Alepha.
117
+ */
118
+ protected createHmrPlugin(): Plugin {
119
+ return {
120
+ name: "alepha-hmr",
121
+ handleHotUpdate: async (ctx) => {
122
+ if (ctx.file.includes("/.idea/")) return [];
123
+
124
+ const firstModule = ctx.modules[0] as any;
125
+ const isBrowserOnly = firstModule && !firstModule._ssrModule;
126
+ const isServerOnly = firstModule && !firstModule._clientModule;
127
+
128
+ // Browser-only: let Vite HMR handle it (React Fast Refresh)
129
+ if (isBrowserOnly) return;
130
+
131
+ // Server or shared change: restart Alepha
132
+ const startTime = Date.now();
133
+
134
+ try {
135
+ this.changedFiles.add(ctx.file);
136
+ await this.loadAlepha(false);
137
+ await this.alepha?.start();
138
+ this.log.debug(`Reloaded in ${Date.now() - startTime}ms`);
139
+
140
+ // Server-only: full browser reload
141
+ if (isServerOnly) {
142
+ this.sendBrowserReload();
143
+ return [];
144
+ }
145
+
146
+ // Shared: let HMR propagate to browser
147
+ return;
148
+ } catch (err) {
149
+ this.hasError = true;
150
+ this.log.error("Reload failed", err);
151
+ this.log.warn("Waiting for file changes to retry...");
152
+ this.alepha = null;
153
+ return [];
154
+ }
155
+ },
156
+ };
157
+ }
158
+
159
+ /**
160
+ * Send browser reload signal via custom event.
161
+ * Browser listens for 'alepha:reload' and does window.location.reload()
162
+ */
163
+ protected sendBrowserReload(): void {
164
+ this.server.ws.send({
165
+ type: "custom",
166
+ event: "alepha:reload",
167
+ data: {},
168
+ });
169
+ }
170
+
171
+ /**
172
+ * Setup environment variables for dev mode.
173
+ */
174
+ protected async setupEnvironment(): Promise<void> {
175
+ const { loadEnv } = await importVite();
176
+ const mode = process.env.NODE_ENV || "development";
177
+ const env = loadEnv(mode, this.options.root, "");
178
+
179
+ // Merge into process.env (only set if not already defined)
180
+ for (const [key, value] of Object.entries(env)) {
181
+ process.env[key] ??= value;
182
+ }
183
+
184
+ process.env.NODE_ENV ??= "development";
185
+ process.env.VITE_ALEPHA_DEV = "true";
186
+ process.env.SERVER_HOST ??= this.options.host?.toString() ?? "localhost";
187
+ process.env.SERVER_PORT ??= String(
188
+ this.options.port ??
189
+ (process.env.SERVER_PORT ? Number(process.env.SERVER_PORT) : 3000),
190
+ );
191
+ }
192
+
193
+ /**
194
+ * Load or reload the Alepha instance.
195
+ */
196
+ protected async loadAlepha(isInitialLoad = false): Promise<Alepha> {
197
+ if (this.alepha) {
198
+ await this.alepha
199
+ .stop()
200
+ .catch((err) => this.log.warn("Error stopping Alepha", err));
201
+ this.alepha = null;
202
+ }
203
+
204
+ if (isInitialLoad || this.hasError) {
205
+ this.server.moduleGraph.invalidateAll();
206
+ } else {
207
+ this.invalidateModulesWithImporters();
208
+ }
209
+ this.changedFiles.clear();
210
+
211
+ // Snapshot and restore process.env to isolate each reload
212
+ const envSnapshot = { ...process.env };
213
+ await this.setupEnvironment();
214
+
215
+ await this.server.ssrLoadModule(this.options.entry.server);
216
+
217
+ const alepha: Alepha = (globalThis as any).__alepha;
218
+ if (!alepha) {
219
+ throw new AlephaError(
220
+ "Alepha instance not found after loading entry module",
221
+ );
222
+ }
223
+
224
+ this.alepha = alepha;
225
+ await this.setupAlepha();
226
+
227
+ this.hasError = false;
228
+ process.env = envSnapshot;
229
+
230
+ return alepha;
231
+ }
232
+
233
+ public hasReact(): boolean {
234
+ try {
235
+ this.alepha?.inject("ReactServerProvider");
236
+ return true;
237
+ } catch {
238
+ return false;
239
+ }
240
+ }
241
+
242
+ /**
243
+ * Setup Alepha instance with Vite middleware and template.
244
+ */
245
+ protected async setupAlepha(): Promise<void> {
246
+ if (!this.alepha || !this.hasReact()) {
247
+ return;
248
+ }
249
+
250
+ const template = await this.server.transformIndexHtml(
251
+ "/",
252
+ this.templateProvider.generateIndexHtml(this.options.entry),
253
+ );
254
+
255
+ this.alepha.store.set("alepha.react.server.template", template);
256
+
257
+ this.alepha.events.on("server:onRequest", {
258
+ priority: "first",
259
+ callback: async ({ request }) => {
260
+ const node = request.raw.node;
261
+ if (!node || this.isPageRequest(node.req)) return;
262
+
263
+ const handled = await this.runViteMiddleware(
264
+ node.req,
265
+ node.res,
266
+ request,
267
+ );
268
+ if (handled) {
269
+ request.reply.status = node.res.statusCode || 200;
270
+ request.reply.body = null;
271
+ }
272
+ },
273
+ });
274
+ }
275
+
276
+ /**
277
+ * Check if request is for an HTML page (not an asset).
278
+ */
279
+ protected isPageRequest(req: any): boolean {
280
+ const url = req.url || "/";
281
+
282
+ // Root and index.html are page requests
283
+ if (url === "/" || url === "/index.html") return true;
284
+
285
+ // Vite internal routes
286
+ if (url.startsWith("/@") || url.startsWith("/__vite")) return false;
287
+
288
+ // Files with extensions are assets
289
+ if (/\.\w+$/.test(url.split("?")[0])) return false;
290
+
291
+ return true;
292
+ }
293
+
294
+ /**
295
+ * Run Vite middleware and detect if it handled the request.
296
+ */
297
+ protected async runViteMiddleware(
298
+ req: any,
299
+ res: any,
300
+ ctx: { metadata: any },
301
+ ): Promise<boolean> {
302
+ // Skip if response already started
303
+ if (res.headersSent || res.writableEnded) {
304
+ return false;
305
+ }
306
+
307
+ return new Promise((resolve) => {
308
+ let resolved = false;
309
+
310
+ const done = (handled: boolean) => {
311
+ if (resolved) return;
312
+ resolved = true;
313
+ if (handled) ctx.metadata.vite = true;
314
+ resolve(handled);
315
+ };
316
+
317
+ // Wrap response to prevent writes after we've resolved
318
+ const originalSetHeader = res.setHeader.bind(res);
319
+ const originalWriteHead = res.writeHead?.bind(res);
320
+ const originalWrite = res.write.bind(res);
321
+ const originalEnd = res.end.bind(res);
322
+
323
+ const guardedCall = <T>(fn: (...args: any[]) => T, ...args: any[]): T => {
324
+ if (resolved && !ctx.metadata.vite) {
325
+ // Vite didn't handle this request, silently ignore late writes
326
+ return undefined as T;
327
+ }
328
+ return fn(...args);
329
+ };
330
+
331
+ res.setHeader = (...args: any[]) =>
332
+ guardedCall(originalSetHeader, ...args);
333
+ if (originalWriteHead) {
334
+ res.writeHead = (...args: any[]) =>
335
+ guardedCall(originalWriteHead, ...args);
336
+ }
337
+ res.write = (...args: any[]) => guardedCall(originalWrite, ...args);
338
+ res.end = (...args: any[]) => guardedCall(originalEnd, ...args);
339
+
340
+ res.on("finish", () => done(true));
341
+ res.on("close", () => res.headersSent && done(true));
342
+
343
+ this.server.middlewares(req, res, () => done(false));
344
+
345
+ // Check after microtask if Vite started writing (for async handlers)
346
+ setImmediate(() => {
347
+ if (res.headersSent || res.writableEnded) {
348
+ done(true);
349
+ }
350
+ });
351
+ });
352
+ }
353
+
354
+ /**
355
+ * Invalidate modules and all their importers.
356
+ */
357
+ protected invalidateModulesWithImporters(): void {
358
+ const invalidated = new Set<string>();
359
+ const queue: string[] = [...this.changedFiles];
360
+
361
+ while (queue.length > 0) {
362
+ const file = queue.pop()!;
363
+ if (invalidated.has(file)) continue;
364
+
365
+ const mod = this.server.moduleGraph.getModuleById(file);
366
+ if (!mod) continue;
367
+
368
+ this.server.moduleGraph.invalidateModule(mod);
369
+ invalidated.add(file);
370
+
371
+ for (const importer of mod.importers) {
372
+ if (importer.id && !invalidated.has(importer.id)) {
373
+ queue.push(importer.id);
374
+ }
375
+ }
376
+ }
377
+ }
378
+ }
@@ -1,9 +1,12 @@
1
- import { spawn } from "node:child_process";
2
- import { $inject, Alepha, AlephaError } from "alepha";
1
+ import { $inject, type Alepha } from "alepha";
3
2
  import { EnvUtils } from "alepha/command";
4
- import { FileSystemProvider } from "alepha/file";
5
3
  import { $logger } from "alepha/logger";
6
- import { boot } from "alepha/vite";
4
+ import { FileSystemProvider, ShellProvider } from "alepha/system";
5
+ import {
6
+ type AppEntry,
7
+ AppEntryProvider,
8
+ } from "../providers/AppEntryProvider.ts";
9
+ import { ViteUtils } from "./ViteUtils.ts";
7
10
 
8
11
  /**
9
12
  * Core utility service for CLI commands.
@@ -18,6 +21,9 @@ export class AlephaCliUtils {
18
21
  protected readonly log = $logger();
19
22
  protected readonly fs = $inject(FileSystemProvider);
20
23
  protected readonly envUtils = $inject(EnvUtils);
24
+ protected readonly boot = $inject(AppEntryProvider);
25
+ protected readonly shell = $inject(ShellProvider);
26
+ protected readonly viteUtils = $inject(ViteUtils);
21
27
 
22
28
  // ===========================================
23
29
  // Command Execution
@@ -25,6 +31,11 @@ export class AlephaCliUtils {
25
31
 
26
32
  /**
27
33
  * Execute a command with inherited stdio.
34
+ *
35
+ * @param command - The command to execute
36
+ * @param options.root - Working directory
37
+ * @param options.env - Additional environment variables
38
+ * @param options.global - If true, run command directly without resolving from node_modules
28
39
  */
29
40
  public async exec(
30
41
  command: string,
@@ -34,56 +45,12 @@ export class AlephaCliUtils {
34
45
  global?: boolean;
35
46
  } = {},
36
47
  ): Promise<void> {
37
- const root = options.root ?? process.cwd();
38
- this.log.debug(`Executing command: ${command}`, { cwd: root });
39
-
40
- const runExec = async (app: string, args: string[]) => {
41
- const prog = spawn(app, args, {
42
- stdio: "inherit",
43
- cwd: root,
44
- env: {
45
- ...process.env,
46
- ...options.env,
47
- },
48
- });
49
-
50
- await new Promise<void>((resolve) =>
51
- prog.on("exit", () => {
52
- resolve();
53
- }),
54
- );
55
- };
56
-
57
- if (options.global) {
58
- const [app, ...args] = command.split(" ");
59
- await runExec(app, args);
60
- return;
61
- }
62
-
63
- const suffix = process.platform === "win32" ? ".cmd" : "";
64
- const [app, ...args] = command.split(" ");
65
-
66
- // find executable inside project node_modules
67
- let execPath = await this.checkFileExists(
68
- root,
69
- `node_modules/.bin/${app}${suffix}`,
70
- );
71
-
72
- // or, find executable inside alepha package node_modules (pnpm style)
73
- if (!execPath) {
74
- execPath = await this.checkFileExists(
75
- root,
76
- `node_modules/alepha/node_modules/.bin/${app}${suffix}`,
77
- );
78
- }
79
-
80
- if (!execPath) {
81
- throw new AlephaError(
82
- `Could not find executable for command '${app}'. Make sure the package is installed.`,
83
- );
84
- }
85
-
86
- await runExec(execPath, args);
48
+ await this.shell.run(command, {
49
+ root: options.root,
50
+ env: options.env,
51
+ resolve: !options.global,
52
+ capture: false,
53
+ });
87
54
  }
88
55
 
89
56
  /**
@@ -106,40 +73,22 @@ export class AlephaCliUtils {
106
73
  return path;
107
74
  }
108
75
 
109
- /**
110
- * Load Alepha instance from a server entry file.
111
- */
112
76
  public async loadAlephaFromServerEntryFile(
113
- rootDir?: string,
114
- explicitEntry?: string,
115
- ): Promise<{
116
- alepha: Alepha;
117
- entry: string;
118
- }> {
119
- process.env.ALEPHA_CLI_IMPORT = "true";
120
-
121
- const entry = await boot.getServerEntry(rootDir, explicitEntry);
122
-
123
- delete (global as any).__alepha;
124
-
125
- const mod = await import(entry);
126
-
127
- this.log.debug(`Load entry: ${entry}`);
128
-
129
- // check if alepha is correctly exported
130
- if (mod.default instanceof Alepha) {
131
- return { alepha: mod.default, entry };
132
- }
133
-
134
- // else, try with global variable
135
- const g: any = global;
136
- if (g.__alepha) {
137
- return { alepha: g.__alepha, entry };
77
+ opts: {
78
+ mode: "production" | "development";
79
+ } & ({ entry: AppEntry } | { root: string }),
80
+ ): Promise<Alepha> {
81
+ let entry: AppEntry;
82
+ if ("root" in opts) {
83
+ entry = await this.boot.getAppEntry(opts.root);
84
+ } else {
85
+ entry = opts.entry;
138
86
  }
139
87
 
140
- throw new AlephaError(
141
- `Could not find Alepha instance in entry file: ${entry}`,
142
- );
88
+ return await this.viteUtils.runAlepha({
89
+ entry,
90
+ mode: opts.mode,
91
+ });
143
92
  }
144
93
 
145
94
  // ===========================================
@@ -190,13 +139,10 @@ ${models.map((it: string) => `export const ${it} = models["${it}"];`).join("\n")
190
139
  return this.fs.exists(this.fs.join(root, path));
191
140
  }
192
141
 
193
- protected async checkFileExists(
194
- root: string,
195
- name: string,
196
- ): Promise<string | undefined> {
197
- const configPath = this.fs.join(root, name);
198
- if (await this.fs.exists(configPath)) {
199
- return configPath;
200
- }
142
+ /**
143
+ * Check if a command is installed and available in the system PATH.
144
+ */
145
+ public isInstalledAsync(cmd: string): Promise<boolean> {
146
+ return this.shell.isInstalled(cmd);
201
147
  }
202
148
  }