alepha 0.18.2 → 0.18.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 (397) hide show
  1. package/assets/devtools-ui/200.html +2 -2
  2. package/assets/devtools-ui/200.html.br +0 -0
  3. package/assets/devtools-ui/404.html +2 -2
  4. package/assets/devtools-ui/404.html.br +0 -0
  5. package/assets/devtools-ui/{asset.BfSBZ5Dd.css → asset.hG_f8HuK.css} +1 -1
  6. package/assets/devtools-ui/asset.hG_f8HuK.css.br +0 -0
  7. package/assets/devtools-ui/chunk.B3au4Lhg.js +1 -0
  8. package/assets/devtools-ui/chunk.B3au4Lhg.js.br +0 -0
  9. package/assets/devtools-ui/chunk.BLOrlnMB.js +1 -0
  10. package/assets/devtools-ui/chunk.BLOrlnMB.js.br +0 -0
  11. package/assets/devtools-ui/chunk.BLR01ljW.js +1 -0
  12. package/assets/devtools-ui/chunk.BLR01ljW.js.br +0 -0
  13. package/assets/devtools-ui/chunk.BTXaIUlA.js +1 -0
  14. package/assets/devtools-ui/chunk.BTXaIUlA.js.br +0 -0
  15. package/assets/devtools-ui/{chunk.lJL-lgnW.js → chunk.BhJaxmm8.js} +1 -1
  16. package/assets/devtools-ui/chunk.BhJaxmm8.js.br +0 -0
  17. package/assets/devtools-ui/chunk.BtoNxFuL.js +1 -0
  18. package/assets/devtools-ui/chunk.BtoNxFuL.js.br +0 -0
  19. package/assets/devtools-ui/chunk.C8YUV2Wd.js +1 -0
  20. package/assets/devtools-ui/chunk.C8YUV2Wd.js.br +0 -0
  21. package/assets/devtools-ui/{chunk.M6wyKO_3.js → chunk.CBbIgDzE.js} +2 -2
  22. package/assets/devtools-ui/chunk.CBbIgDzE.js.br +0 -0
  23. package/assets/devtools-ui/chunk.CFqIniwA.js +1 -0
  24. package/assets/devtools-ui/chunk.CFqIniwA.js.br +0 -0
  25. package/assets/devtools-ui/chunk.CLFF7f7-.js +1 -0
  26. package/assets/devtools-ui/chunk.CLFF7f7-.js.br +0 -0
  27. package/assets/devtools-ui/chunk.CRsBbA10.js +1 -0
  28. package/assets/devtools-ui/chunk.CRsBbA10.js.br +0 -0
  29. package/assets/devtools-ui/{chunk.DbEH1oOB.js → chunk.CZPo6v95.js} +1 -1
  30. package/assets/devtools-ui/chunk.CZPo6v95.js.br +0 -0
  31. package/assets/devtools-ui/chunk.D0fWgNos.js +1 -0
  32. package/assets/devtools-ui/chunk.D0fWgNos.js.br +1 -0
  33. package/assets/devtools-ui/chunk.D7-0ziQ6.js +1 -0
  34. package/assets/devtools-ui/chunk.D7-0ziQ6.js.br +0 -0
  35. package/assets/devtools-ui/chunk.DAewe0vm.js +1 -0
  36. package/assets/devtools-ui/chunk.DAewe0vm.js.br +0 -0
  37. package/assets/devtools-ui/chunk.DJRQEYqK.js +1 -0
  38. package/assets/devtools-ui/chunk.DJRQEYqK.js.br +0 -0
  39. package/assets/devtools-ui/{chunk.CZl6J9DF.js → chunk.DMAxv14p.js} +1 -1
  40. package/assets/devtools-ui/chunk.DMAxv14p.js.br +0 -0
  41. package/assets/devtools-ui/{chunk.BT2IiBkZ.js → chunk.DMImnNjU.js} +1 -1
  42. package/assets/devtools-ui/chunk.DMImnNjU.js.br +0 -0
  43. package/assets/devtools-ui/chunk.DeeQsidk.js +9 -0
  44. package/assets/devtools-ui/chunk.DeeQsidk.js.br +0 -0
  45. package/assets/devtools-ui/chunk.DqEwn9Vj.js +7 -0
  46. package/assets/devtools-ui/chunk.DqEwn9Vj.js.br +0 -0
  47. package/assets/devtools-ui/chunk.Dt8OsQey.js +1 -0
  48. package/assets/devtools-ui/chunk.Dt8OsQey.js.br +0 -0
  49. package/assets/devtools-ui/{chunk.B9pX3zit.js → chunk.Dtp8oa_f.js} +1 -1
  50. package/assets/devtools-ui/chunk.Dtp8oa_f.js.br +0 -0
  51. package/assets/devtools-ui/chunk.Dx3JzAYM.js +1 -0
  52. package/assets/devtools-ui/chunk.Dx3JzAYM.js.br +0 -0
  53. package/assets/devtools-ui/chunk.GCOj1-5E.js +1 -0
  54. package/assets/devtools-ui/chunk.GCOj1-5E.js.br +0 -0
  55. package/assets/devtools-ui/chunk.IC1LD8BH.js +1 -0
  56. package/assets/devtools-ui/chunk.IC1LD8BH.js.br +0 -0
  57. package/assets/devtools-ui/chunk.IwuB_TqW.js +1 -0
  58. package/assets/devtools-ui/chunk.IwuB_TqW.js.br +0 -0
  59. package/assets/devtools-ui/chunk.Qqapj2zq.js +1 -0
  60. package/assets/devtools-ui/chunk.Qqapj2zq.js.br +0 -0
  61. package/assets/devtools-ui/{chunk.C79YouPp.js → chunk.TKKKndOy.js} +1 -1
  62. package/assets/devtools-ui/chunk.TKKKndOy.js.br +0 -0
  63. package/assets/devtools-ui/chunk.YHTVhFQT.js +1 -0
  64. package/assets/devtools-ui/chunk.YHTVhFQT.js.br +0 -0
  65. package/assets/devtools-ui/chunk.fnod6uEi.js +1 -0
  66. package/assets/devtools-ui/chunk.fnod6uEi.js.br +0 -0
  67. package/assets/devtools-ui/chunk.mOCRmXjo.js +1 -0
  68. package/assets/devtools-ui/chunk.mOCRmXjo.js.br +0 -0
  69. package/assets/devtools-ui/chunk.qZTNEAK0.js +1 -0
  70. package/assets/devtools-ui/chunk.qZTNEAK0.js.br +0 -0
  71. package/assets/devtools-ui/chunk.rc9m0y4-.js +1 -0
  72. package/assets/devtools-ui/chunk.rc9m0y4-.js.br +0 -0
  73. package/assets/devtools-ui/entry.Cxc5QLCU.js +80 -0
  74. package/assets/devtools-ui/entry.Cxc5QLCU.js.br +0 -0
  75. package/assets/devtools-ui/index.html +2 -2
  76. package/assets/devtools-ui/index.html.br +0 -0
  77. package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
  78. package/assets/swagger-ui/swagger-ui.css +1 -1
  79. package/dist/api/audits/index.d.ts +61 -5
  80. package/dist/api/audits/index.d.ts.map +1 -1
  81. package/dist/api/files/index.d.ts +61 -5
  82. package/dist/api/files/index.d.ts.map +1 -1
  83. package/dist/api/jobs/index.d.ts +61 -5
  84. package/dist/api/jobs/index.d.ts.map +1 -1
  85. package/dist/api/jobs/index.js +4 -2
  86. package/dist/api/jobs/index.js.map +1 -1
  87. package/dist/api/keys/index.d.ts +5 -5
  88. package/dist/api/notifications/index.browser.js +44 -1
  89. package/dist/api/notifications/index.browser.js.map +1 -1
  90. package/dist/api/notifications/index.d.ts +187 -2
  91. package/dist/api/notifications/index.d.ts.map +1 -1
  92. package/dist/api/notifications/index.js +143 -8
  93. package/dist/api/notifications/index.js.map +1 -1
  94. package/dist/api/parameters/index.d.ts +61 -5
  95. package/dist/api/parameters/index.d.ts.map +1 -1
  96. package/dist/api/users/index.d.ts +330 -93
  97. package/dist/api/users/index.d.ts.map +1 -1
  98. package/dist/api/users/index.js +27 -36
  99. package/dist/api/users/index.js.map +1 -1
  100. package/dist/cli/config/index.d.ts +46 -0
  101. package/dist/cli/config/index.d.ts.map +1 -0
  102. package/dist/cli/config/index.js +20 -0
  103. package/dist/cli/config/index.js.map +1 -0
  104. package/dist/cli/core/index.d.ts +69 -66
  105. package/dist/cli/core/index.d.ts.map +1 -1
  106. package/dist/cli/core/index.js +329 -196
  107. package/dist/cli/core/index.js.map +1 -1
  108. package/dist/cli/platform/index.d.ts +302 -63
  109. package/dist/cli/platform/index.d.ts.map +1 -1
  110. package/dist/cli/platform/index.js +455 -25
  111. package/dist/cli/platform/index.js.map +1 -1
  112. package/dist/core/index.browser.js +125 -87
  113. package/dist/core/index.browser.js.map +1 -1
  114. package/dist/core/index.d.ts +62 -53
  115. package/dist/core/index.d.ts.map +1 -1
  116. package/dist/core/index.js +125 -87
  117. package/dist/core/index.js.map +1 -1
  118. package/dist/core/index.native.js +125 -87
  119. package/dist/core/index.native.js.map +1 -1
  120. package/dist/core/index.workerd.js +125 -87
  121. package/dist/core/index.workerd.js.map +1 -1
  122. package/dist/crypto/index.d.ts +18 -1
  123. package/dist/crypto/index.d.ts.map +1 -1
  124. package/dist/crypto/index.js +29 -3
  125. package/dist/crypto/index.js.map +1 -1
  126. package/dist/devtools/index.js +3 -12
  127. package/dist/devtools/index.js.map +1 -1
  128. package/dist/logger/index.d.ts +10 -1
  129. package/dist/logger/index.d.ts.map +1 -1
  130. package/dist/logger/index.js +19 -9
  131. package/dist/logger/index.js.map +1 -1
  132. package/dist/orm/core/index.browser.js +57 -1
  133. package/dist/orm/core/index.browser.js.map +1 -1
  134. package/dist/orm/core/index.bun.js +378 -19
  135. package/dist/orm/core/index.bun.js.map +1 -1
  136. package/dist/orm/core/index.d.ts +328 -9
  137. package/dist/orm/core/index.d.ts.map +1 -1
  138. package/dist/orm/core/index.js +384 -21
  139. package/dist/orm/core/index.js.map +1 -1
  140. package/dist/orm/postgres/index.bun.js +49 -17
  141. package/dist/orm/postgres/index.bun.js.map +1 -1
  142. package/dist/orm/postgres/index.d.ts +47 -21
  143. package/dist/orm/postgres/index.d.ts.map +1 -1
  144. package/dist/orm/postgres/index.js +52 -17
  145. package/dist/orm/postgres/index.js.map +1 -1
  146. package/dist/react/core/index.d.ts +1 -1
  147. package/dist/react/core/index.d.ts.map +1 -1
  148. package/dist/react/core/index.js +6 -1
  149. package/dist/react/core/index.js.map +1 -1
  150. package/dist/react/form/index.d.ts +28 -18
  151. package/dist/react/form/index.d.ts.map +1 -1
  152. package/dist/react/form/index.js +92 -56
  153. package/dist/react/form/index.js.map +1 -1
  154. package/dist/react/router/index.browser.js +448 -116
  155. package/dist/react/router/index.browser.js.map +1 -1
  156. package/dist/react/router/index.d.ts +102 -40
  157. package/dist/react/router/index.d.ts.map +1 -1
  158. package/dist/react/router/index.js +453 -92
  159. package/dist/react/router/index.js.map +1 -1
  160. package/dist/security/index.d.ts +3 -11
  161. package/dist/security/index.d.ts.map +1 -1
  162. package/dist/security/index.js +6 -11
  163. package/dist/security/index.js.map +1 -1
  164. package/dist/server/auth/index.d.ts +22 -24
  165. package/dist/server/auth/index.d.ts.map +1 -1
  166. package/dist/server/auth/index.js +102 -82
  167. package/dist/server/auth/index.js.map +1 -1
  168. package/dist/server/cookies/index.d.ts +7 -4
  169. package/dist/server/cookies/index.d.ts.map +1 -1
  170. package/dist/server/cookies/index.js +13 -12
  171. package/dist/server/cookies/index.js.map +1 -1
  172. package/dist/server/core/index.d.ts +288 -4
  173. package/dist/server/core/index.d.ts.map +1 -1
  174. package/dist/server/core/index.js +375 -2
  175. package/dist/server/core/index.js.map +1 -1
  176. package/dist/server/links/index.browser.js +10 -71
  177. package/dist/server/links/index.browser.js.map +1 -1
  178. package/dist/server/links/index.d.ts +32 -49
  179. package/dist/server/links/index.d.ts.map +1 -1
  180. package/dist/server/links/index.js +73 -100
  181. package/dist/server/links/index.js.map +1 -1
  182. package/dist/system/index.browser.js +221 -2
  183. package/dist/system/index.browser.js.map +1 -1
  184. package/dist/system/index.d.ts +63 -1
  185. package/dist/system/index.d.ts.map +1 -1
  186. package/dist/system/index.js +221 -1
  187. package/dist/system/index.js.map +1 -1
  188. package/dist/system/index.workerd.js +224 -4
  189. package/dist/system/index.workerd.js.map +1 -1
  190. package/package.json +10 -5
  191. package/src/api/jobs/providers/JobProvider.ts +6 -3
  192. package/src/api/notifications/controllers/AdminNotificationController.ts +83 -0
  193. package/src/api/notifications/index.browser.ts +3 -0
  194. package/src/api/notifications/index.ts +14 -2
  195. package/src/api/notifications/jobs/NotificationJobs.ts +11 -2
  196. package/src/api/notifications/schemas/notificationDetailResourceSchema.ts +20 -0
  197. package/src/api/notifications/schemas/notificationQuerySchema.ts +19 -0
  198. package/src/api/notifications/schemas/notificationResourceSchema.ts +18 -0
  199. package/src/api/notifications/services/NotificationSenderService.ts +15 -2
  200. package/src/api/users/atoms/realmAuthSettingsAtom.ts +28 -32
  201. package/src/api/users/buckets/UserBuckets.ts +1 -1
  202. package/src/api/users/jobs/UserJobs.ts +1 -1
  203. package/src/api/users/primitives/$realm.ts +8 -49
  204. package/src/api/users/providers/RealmProvider.ts +2 -3
  205. package/src/api/users/services/RegistrationService.spec.ts +7 -7
  206. package/src/api/users/services/RegistrationService.ts +3 -3
  207. package/src/api/users/services/SessionService.spec.ts +4 -4
  208. package/src/api/users/services/SessionService.ts +3 -3
  209. package/src/cli/{core → config}/defineConfig.ts +14 -20
  210. package/src/cli/config/index.ts +1 -0
  211. package/src/cli/core/commands/db.ts +65 -1
  212. package/src/cli/core/commands/dev.ts +1 -0
  213. package/src/cli/core/commands/init.ts +2 -192
  214. package/src/cli/core/index.ts +34 -11
  215. package/src/cli/core/providers/ViteDevServerProvider.ts +52 -13
  216. package/src/cli/core/services/PackageManagerUtils.ts +43 -21
  217. package/src/cli/core/services/ProjectScaffolder.ts +214 -2
  218. package/src/cli/core/services/ViteUtils.ts +57 -0
  219. package/src/cli/core/tasks/BuildClientTask.ts +7 -2
  220. package/src/cli/core/tasks/BuildCloudflareTask.ts +4 -12
  221. package/src/cli/core/tasks/BuildServerTask.ts +2 -0
  222. package/src/cli/core/tasks/BuildVercelTask.ts +165 -168
  223. package/src/cli/core/templates/alephaConfigTs.ts +1 -1
  224. package/src/cli/core/templates/apiAppSecurityTs.ts +5 -8
  225. package/src/cli/core/templates/tsconfigJson.ts +6 -1
  226. package/src/cli/platform/adapters/CloudflareAdapter.spec.ts +1 -1
  227. package/src/cli/platform/adapters/CloudflareAdapter.ts +30 -29
  228. package/src/cli/platform/atoms/platformOptions.ts +21 -0
  229. package/src/cli/platform/commands/SecretsCommand.spec.ts +298 -0
  230. package/src/cli/platform/commands/SecretsCommand.ts +283 -0
  231. package/src/cli/platform/commands/platform.ts +12 -0
  232. package/src/cli/platform/index.ts +14 -28
  233. package/src/cli/platform/providers/GitHubSecretStore.spec.ts +153 -0
  234. package/src/cli/platform/providers/GitHubSecretStore.ts +112 -0
  235. package/src/cli/platform/providers/MemorySecretStore.ts +114 -0
  236. package/src/cli/platform/providers/SecretStoreProvider.ts +39 -0
  237. package/src/cli/platform/schemas/cloudflare.ts +2 -0
  238. package/src/cli/platform/services/CloudflareApi.ts +5 -2
  239. package/src/cli/platform/services/DockerComposeGenerator.spec.ts +115 -0
  240. package/src/cli/platform/services/DockerComposeGenerator.ts +46 -1
  241. package/src/cli/platform/services/SecretFilterService.spec.ts +111 -0
  242. package/src/cli/platform/services/SecretFilterService.ts +54 -0
  243. package/src/core/Alepha.ts +94 -25
  244. package/src/core/__tests__/Alepha-parseEnv.spec.ts +20 -0
  245. package/src/core/primitives/$memoize.ts +38 -26
  246. package/src/core/providers/AlsProvider.ts +2 -0
  247. package/src/core/providers/EventManager.ts +4 -0
  248. package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +1 -4
  249. package/src/core/providers/KeylessJsonSchemaCodec.ts +19 -125
  250. package/src/core/providers/SchemaValidator.spec.ts +36 -0
  251. package/src/core/providers/SchemaValidator.ts +9 -0
  252. package/src/crypto/index.ts +6 -1
  253. package/src/crypto/providers/SecretProvider.ts +36 -0
  254. package/src/devtools/providers/DevToolsProvider.ts +3 -12
  255. package/src/logger/index.ts +33 -6
  256. package/src/logger/providers/PrettyFormatterProvider.ts +5 -3
  257. package/src/orm/__tests__/orm-next-tests.ts +492 -0
  258. package/src/orm/__tests__/orm-next.spec.ts +140 -0
  259. package/src/orm/core/constants/PG_SYMBOLS.ts +17 -0
  260. package/src/orm/core/index.bun.ts +3 -6
  261. package/src/orm/core/index.shared-server.ts +2 -0
  262. package/src/orm/core/index.shared.ts +2 -0
  263. package/src/orm/core/index.ts +5 -7
  264. package/src/orm/core/interfaces/AggregateQuery.ts +103 -0
  265. package/src/orm/core/interfaces/PgQueryWhere.ts +7 -0
  266. package/src/orm/core/primitives/$entity.ts +8 -0
  267. package/src/orm/core/primitives/$repository.ts +6 -3
  268. package/src/orm/core/primitives/$view.ts +88 -0
  269. package/src/orm/core/providers/DbCacheProvider.ts +66 -0
  270. package/src/orm/core/providers/DrizzleKitProvider.ts +42 -0
  271. package/src/orm/core/providers/drivers/BunSqliteProvider.ts +2 -3
  272. package/src/orm/core/providers/drivers/CloudflareD1Provider.ts +12 -0
  273. package/src/orm/core/providers/drivers/DatabaseProvider.ts +39 -0
  274. package/src/orm/core/providers/drivers/NodeSqliteProvider.ts +2 -3
  275. package/src/orm/core/schemas/databaseEnvSchema.ts +31 -0
  276. package/src/orm/core/schemas/insertSchema.ts +13 -3
  277. package/src/orm/core/schemas/updateSchema.ts +14 -3
  278. package/src/orm/core/services/ModelBuilder.ts +26 -14
  279. package/src/orm/core/services/QueryManager.ts +13 -0
  280. package/src/orm/core/services/Repository.ts +307 -5
  281. package/src/orm/core/services/SqliteModelBuilder.ts +38 -0
  282. package/src/orm/postgres/index.bun.ts +4 -7
  283. package/src/orm/postgres/index.ts +4 -7
  284. package/src/orm/postgres/providers/BunPostgresProvider.ts +12 -2
  285. package/src/orm/postgres/providers/NodePostgresProvider.ts +7 -0
  286. package/src/orm/postgres/providers/PglitePostgresProvider.ts +10 -17
  287. package/src/orm/postgres/providers/PostgresProvider.ts +7 -36
  288. package/src/orm/postgres/schemas/postgresEnvSchema.ts +32 -0
  289. package/src/orm/postgres/services/PostgresModelBuilder.ts +40 -0
  290. package/src/react/core/components/ErrorBoundary.tsx +5 -2
  291. package/src/react/form/hooks/useFieldValue.ts +34 -0
  292. package/src/react/form/hooks/useForm.browser.spec.tsx +94 -9
  293. package/src/react/form/hooks/useForm.ts +14 -2
  294. package/src/react/form/hooks/useFormState.ts +10 -10
  295. package/src/react/form/hooks/useFormValues.ts +29 -0
  296. package/src/react/form/index.ts +3 -1
  297. package/src/react/form/services/FormModel.ts +53 -122
  298. package/src/react/router/components/ErrorViewer.tsx +333 -34
  299. package/src/react/router/components/NestedView.tsx +10 -3
  300. package/src/react/router/primitives/$page.browser.spec.tsx +34 -0
  301. package/src/react/router/primitives/$page.spec.tsx +20 -0
  302. package/src/react/router/primitives/$page.ts +24 -0
  303. package/src/react/router/providers/ReactBrowserRouterProvider.ts +14 -2
  304. package/src/react/router/providers/ReactPageProvider.ts +156 -73
  305. package/src/react/router/providers/ReactServerProvider.ts +40 -2
  306. package/src/react/router/providers/ReactServerTemplateProvider.ts +13 -1
  307. package/src/security/providers/SecurityProvider.ts +5 -27
  308. package/src/server/auth/primitives/$auth.ts +52 -19
  309. package/src/server/auth/providers/ServerAuthProvider.ts +145 -139
  310. package/src/server/cookies/providers/ServerCookiesProvider.ts +12 -24
  311. package/src/server/core/index.ts +3 -1
  312. package/src/server/core/primitives/$sse.spec.ts +315 -0
  313. package/src/server/core/primitives/$sse.ts +715 -0
  314. package/src/server/links/index.browser.ts +1 -3
  315. package/src/server/links/index.ts +0 -3
  316. package/src/server/links/providers/LinkProvider.spec.ts +12 -21
  317. package/src/server/links/providers/LinkProvider.ts +20 -52
  318. package/src/server/links/providers/ServerLinksProvider.spec.ts +106 -0
  319. package/src/server/links/providers/ServerLinksProvider.ts +113 -73
  320. package/src/server/links/schemas/apiLinksResponseSchema.ts +4 -21
  321. package/src/server/links/services/BatchCollector.ts +5 -3
  322. package/src/system/index.browser.ts +1 -0
  323. package/src/system/index.ts +3 -0
  324. package/src/system/index.workerd.ts +39 -1
  325. package/src/system/providers/WorkerdFileSystemProvider.ts +365 -0
  326. package/assets/devtools-ui/asset.BfSBZ5Dd.css.br +0 -0
  327. package/assets/devtools-ui/chunk.2NYaoqWt.js +0 -1
  328. package/assets/devtools-ui/chunk.2NYaoqWt.js.br +0 -0
  329. package/assets/devtools-ui/chunk.B052Z_xQ.js +0 -1
  330. package/assets/devtools-ui/chunk.B052Z_xQ.js.br +0 -0
  331. package/assets/devtools-ui/chunk.B4kVY90C.js +0 -1
  332. package/assets/devtools-ui/chunk.B4kVY90C.js.br +0 -0
  333. package/assets/devtools-ui/chunk.B7QJXctB.js +0 -1
  334. package/assets/devtools-ui/chunk.B7QJXctB.js.br +0 -0
  335. package/assets/devtools-ui/chunk.B9pX3zit.js.br +0 -0
  336. package/assets/devtools-ui/chunk.BKF9JxIo.js +0 -1
  337. package/assets/devtools-ui/chunk.BKF9JxIo.js.br +0 -0
  338. package/assets/devtools-ui/chunk.BOHgdTP-.js +0 -1
  339. package/assets/devtools-ui/chunk.BOHgdTP-.js.br +0 -0
  340. package/assets/devtools-ui/chunk.BOVFxkYC.js +0 -1
  341. package/assets/devtools-ui/chunk.BOVFxkYC.js.br +0 -0
  342. package/assets/devtools-ui/chunk.BR842zj5.js +0 -1
  343. package/assets/devtools-ui/chunk.BR842zj5.js.br +0 -0
  344. package/assets/devtools-ui/chunk.BT2IiBkZ.js.br +0 -0
  345. package/assets/devtools-ui/chunk.C79YouPp.js.br +0 -0
  346. package/assets/devtools-ui/chunk.C8mlBrjW.js +0 -9
  347. package/assets/devtools-ui/chunk.C8mlBrjW.js.br +0 -0
  348. package/assets/devtools-ui/chunk.CK0ow3AZ.js +0 -1
  349. package/assets/devtools-ui/chunk.CK0ow3AZ.js.br +0 -0
  350. package/assets/devtools-ui/chunk.CZl6J9DF.js.br +0 -0
  351. package/assets/devtools-ui/chunk.CdNr0YzS.js +0 -1
  352. package/assets/devtools-ui/chunk.CdNr0YzS.js.br +0 -0
  353. package/assets/devtools-ui/chunk.Ce6_6iIF.js +0 -1
  354. package/assets/devtools-ui/chunk.Ce6_6iIF.js.br +0 -0
  355. package/assets/devtools-ui/chunk.CpyDMr6O.js +0 -1
  356. package/assets/devtools-ui/chunk.CpyDMr6O.js.br +0 -0
  357. package/assets/devtools-ui/chunk.CyPmvPnY.js +0 -1
  358. package/assets/devtools-ui/chunk.CyPmvPnY.js.br +0 -0
  359. package/assets/devtools-ui/chunk.DTI_geWu.js +0 -1
  360. package/assets/devtools-ui/chunk.DTI_geWu.js.br +0 -0
  361. package/assets/devtools-ui/chunk.DbEH1oOB.js.br +0 -0
  362. package/assets/devtools-ui/chunk.Ddeqj5gv.js +0 -1
  363. package/assets/devtools-ui/chunk.Ddeqj5gv.js.br +0 -0
  364. package/assets/devtools-ui/chunk.DpRnB4vJ.js +0 -1
  365. package/assets/devtools-ui/chunk.DpRnB4vJ.js.br +0 -0
  366. package/assets/devtools-ui/chunk.DxPGTlsg.js +0 -1
  367. package/assets/devtools-ui/chunk.DxPGTlsg.js.br +0 -0
  368. package/assets/devtools-ui/chunk.G7_MMBJS.js +0 -1
  369. package/assets/devtools-ui/chunk.G7_MMBJS.js.br +0 -0
  370. package/assets/devtools-ui/chunk.M6wyKO_3.js.br +0 -0
  371. package/assets/devtools-ui/chunk.OUxNGmQ6.js +0 -1
  372. package/assets/devtools-ui/chunk.OUxNGmQ6.js.br +0 -0
  373. package/assets/devtools-ui/chunk.T1kle-fF.js +0 -1
  374. package/assets/devtools-ui/chunk.T1kle-fF.js.br +0 -0
  375. package/assets/devtools-ui/chunk.WjpsbQAv.js +0 -1
  376. package/assets/devtools-ui/chunk.WjpsbQAv.js.br +0 -0
  377. package/assets/devtools-ui/chunk.c6YgVx86.js +0 -1
  378. package/assets/devtools-ui/chunk.c6YgVx86.js.br +0 -0
  379. package/assets/devtools-ui/chunk.dwU3E_MU.js +0 -1
  380. package/assets/devtools-ui/chunk.dwU3E_MU.js.br +0 -0
  381. package/assets/devtools-ui/chunk.lJL-lgnW.js.br +0 -0
  382. package/assets/devtools-ui/chunk.lPWRmvA-.js +0 -7
  383. package/assets/devtools-ui/chunk.lPWRmvA-.js.br +0 -0
  384. package/assets/devtools-ui/chunk.p3HJvugM.js +0 -1
  385. package/assets/devtools-ui/chunk.p3HJvugM.js.br +0 -0
  386. package/assets/devtools-ui/chunk.r_Xoa_CI.js +0 -1
  387. package/assets/devtools-ui/chunk.r_Xoa_CI.js.br +0 -0
  388. package/assets/devtools-ui/chunk.sRNuTYXb.js +0 -1
  389. package/assets/devtools-ui/chunk.sRNuTYXb.js.br +0 -0
  390. package/assets/devtools-ui/chunk.tUjcyX5C.js +0 -1
  391. package/assets/devtools-ui/chunk.tUjcyX5C.js.br +0 -0
  392. package/assets/devtools-ui/chunk.thjBxvCA.js +0 -1
  393. package/assets/devtools-ui/chunk.thjBxvCA.js.br +0 -0
  394. package/assets/devtools-ui/entry.GYhBVRpC.js +0 -78
  395. package/assets/devtools-ui/entry.GYhBVRpC.js.br +0 -0
  396. package/src/server/links/services/DefinitionsPool.spec.ts +0 -86
  397. package/src/server/links/services/DefinitionsPool.ts +0 -43
@@ -13,7 +13,7 @@ import {
13
13
  UserService,
14
14
  } from "../index.ts";
15
15
 
16
- const setup = async (options?: { usernameEnabled?: boolean }) => {
16
+ const setup = async (options?: { username?: "optional" | "required" }) => {
17
17
  const alepha = Alepha.create({
18
18
  env: { LOG_LEVEL: "error" },
19
19
  });
@@ -27,11 +27,11 @@ const setup = async (options?: { usernameEnabled?: boolean }) => {
27
27
  const sessionService = alepha.inject(SessionService);
28
28
 
29
29
  // Configure realm settings if provided
30
- if (options?.usernameEnabled) {
30
+ if (options?.username) {
31
31
  const realmProvider = alepha.inject(RealmProvider);
32
32
  realmProvider.register("default", {
33
33
  settings: {
34
- usernameEnabled: true,
34
+ username: options.username,
35
35
  } as never,
36
36
  });
37
37
  }
@@ -247,7 +247,7 @@ describe("alepha/api/users - SessionService.login", () => {
247
247
 
248
248
  it("should handle different providers correctly", async ({ expect }) => {
249
249
  const { sessionService, userService, cryptoProvider, identities } =
250
- await setup({ usernameEnabled: true });
250
+ await setup({ username: "optional" });
251
251
 
252
252
  const user = await userService.users().create({
253
253
  username: "multiprovideruser",
@@ -125,7 +125,7 @@ export class SessionService {
125
125
 
126
126
  where.realm = name;
127
127
 
128
- if (settings.usernameEnabled !== false && isUsername) {
128
+ if (settings.username !== "none" && isUsername) {
129
129
  // validate username format if regex is provided
130
130
  if (settings.usernameRegExp) {
131
131
  const regex = new RegExp(settings.usernameRegExp);
@@ -146,9 +146,9 @@ export class SessionService {
146
146
  }
147
147
  }
148
148
  where.username = username;
149
- } else if (settings.emailEnabled !== false && isEmail) {
149
+ } else if (settings.email !== "none" && isEmail) {
150
150
  where.email = username;
151
- } else if (settings.phoneEnabled === true && isPhone) {
151
+ } else if (settings.phoneNumber !== "none" && isPhone) {
152
152
  where.phoneNumber = username;
153
153
  } else {
154
154
  this.log.warn("Invalid login identifier format", {
@@ -1,11 +1,14 @@
1
1
  import type { Alepha } from "alepha";
2
- import type { CommandPrimitive } from "alepha/command";
3
2
  import {
4
3
  type AppEntryOptions,
5
4
  appEntryOptions,
6
- } from "./atoms/appEntryOptions.ts";
7
- import { type BuildOptions, buildOptions } from "./atoms/buildOptions.ts";
8
- import { type DevOptions, devOptions } from "./atoms/devOptions.ts";
5
+ type BuildOptions,
6
+ buildOptions,
7
+ type DevOptions,
8
+ devOptions,
9
+ } from "alepha/cli";
10
+ import { type PlatformOptions, platformOptions } from "alepha/cli/platform";
11
+ import type { CommandPrimitive } from "alepha/command";
9
12
 
10
13
  export interface AlephaCliConfig {
11
14
  entry?: AppEntryOptions;
@@ -38,24 +41,15 @@ export interface AlephaCliConfig {
38
41
  * Always use .env files by default, this is only for dynamic values.
39
42
  */
40
43
  env?: Record<string, unknown>;
44
+
45
+ /**
46
+ * Platform deployment configuration.
47
+ */
48
+ platform?: PlatformOptions;
41
49
  }
42
50
 
43
51
  export type AlephaCliConfigFn = (alepha: Alepha) => AlephaCliConfig;
44
52
 
45
- type ConfigProcessor = (alepha: Alepha, config: AlephaCliConfig) => void;
46
-
47
- const configProcessors: ConfigProcessor[] = [];
48
-
49
- /**
50
- * Register a processor that runs during config resolution.
51
- *
52
- * Used by submodules (e.g. platform) to handle their own config keys
53
- * without core needing to know about them.
54
- */
55
- export function registerConfigProcessor(processor: ConfigProcessor) {
56
- configProcessors.push(processor);
57
- }
58
-
59
53
  // ---------------------------------------------------------------------------------------------------------------------
60
54
 
61
55
  export const defineConfig = (
@@ -89,8 +83,8 @@ export const defineConfig = (
89
83
  alepha.set(appEntryOptions, config.entry);
90
84
  }
91
85
 
92
- for (const processor of configProcessors) {
93
- processor(alepha, config);
86
+ if (config.platform) {
87
+ alepha.set(platformOptions, config.platform);
94
88
  }
95
89
 
96
90
  return {
@@ -0,0 +1 @@
1
+ export * from "./defineConfig.ts";
@@ -179,8 +179,72 @@ export class DbCommand {
179
179
  description: "Path to the Alepha server entry file",
180
180
  }),
181
181
  ),
182
- flags: drizzleCommandFlags,
182
+ flags: t.extend(drizzleCommandFlags, {
183
+ dryRun: t.optional(
184
+ t.boolean({
185
+ description: "Preview SQL statements without executing them",
186
+ }),
187
+ ),
188
+ }),
183
189
  handler: async ({ root, args, flags }) => {
190
+ if (flags.dryRun) {
191
+ const entry = await this.entryProvider.getAppEntry(root);
192
+ const alepha = await this.utils.loadAlephaFromServerEntryFile({
193
+ mode: "development",
194
+ entry,
195
+ });
196
+
197
+ const drizzleKitProvider =
198
+ alepha.inject<DrizzleKitProvider>("DrizzleKitProvider");
199
+ const repositoryProvider =
200
+ alepha.inject<RepositoryProvider>("RepositoryProvider");
201
+ const accepted = new Set<string>([]);
202
+
203
+ for (const primitive of repositoryProvider.getRepositories()) {
204
+ const provider = primitive.provider;
205
+ const providerName = provider.name;
206
+
207
+ if (accepted.has(providerName)) continue;
208
+ accepted.add(providerName);
209
+
210
+ if (flags.provider && flags.provider !== providerName) continue;
211
+
212
+ this.log.info("");
213
+ this.log.info(
214
+ `Dry run for '${providerName}' (${provider.dialect}) ...`,
215
+ );
216
+
217
+ await (provider as any).connect();
218
+
219
+ try {
220
+ const result = await drizzleKitProvider.dryRunPush(provider);
221
+
222
+ if (result.statements.length === 0) {
223
+ this.log.info("No changes detected.");
224
+ } else {
225
+ if (result.hasDataLoss) {
226
+ this.log.warn("WARNING: These changes would cause data loss!");
227
+ for (const warning of result.warnings) {
228
+ this.log.warn(` ${warning}`);
229
+ }
230
+ }
231
+
232
+ this.log.info("");
233
+ this.log.info(
234
+ `${result.statements.length} statement(s) would be executed:`,
235
+ );
236
+ this.log.info("");
237
+ for (const stmt of result.statements) {
238
+ this.log.info(stmt);
239
+ }
240
+ }
241
+ } finally {
242
+ await (provider as any).close();
243
+ }
244
+ }
245
+ return;
246
+ }
247
+
184
248
  await this.runDrizzleKitCommand({
185
249
  root,
186
250
  args,
@@ -58,6 +58,7 @@ export class DevCommand {
58
58
  noViteReactPlugin:
59
59
  flags["no-vite-react-plugin"] ?? options.noViteReactPlugin ?? false,
60
60
  });
61
+
61
62
  await this.viteDevServer.start();
62
63
  },
63
64
  });
@@ -1,18 +1,9 @@
1
- import { $inject, AlephaError, t } from "alepha";
1
+ import { $inject, t } from "alepha";
2
2
  import { $command } from "alepha/command";
3
- import { $logger, ConsoleColorProvider } from "alepha/logger";
4
- import { FileSystemProvider } from "alepha/system";
5
- import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
6
- import { PackageManagerUtils } from "../services/PackageManagerUtils.ts";
7
3
  import { ProjectScaffolder } from "../services/ProjectScaffolder.ts";
8
4
 
9
5
  export class InitCommand {
10
- protected readonly log = $logger();
11
- protected readonly colors = $inject(ConsoleColorProvider);
12
- protected readonly utils = $inject(AlephaCliUtils);
13
- protected readonly pm = $inject(PackageManagerUtils);
14
6
  protected readonly scaffolder = $inject(ProjectScaffolder);
15
- protected readonly fs = $inject(FileSystemProvider);
16
7
 
17
8
  /**
18
9
  * Ensure the project has the necessary Alepha configuration files.
@@ -79,188 +70,7 @@ export class InitCommand {
79
70
  ),
80
71
  }),
81
72
  handler: async ({ run, flags, root, args }) => {
82
- if (args) {
83
- root = this.fs.join(root, args);
84
- await this.fs.mkdir(root, { force: true });
85
- }
86
-
87
- // Flag cascading: --admin → --auth → --ui → --react, --api
88
- if (flags.admin) {
89
- flags.auth = true;
90
- }
91
- if (flags.auth) {
92
- flags.api = true;
93
- flags.ui = true;
94
- }
95
- if (flags.ui) {
96
- flags.react = true;
97
- }
98
- if (flags.tailwind) {
99
- flags.react = true;
100
- }
101
-
102
- // When codegen flags are set, target directory must be empty (unless --force)
103
- const hasCodegenFlags =
104
- flags.admin ||
105
- flags.auth ||
106
- flags.api ||
107
- flags.ui ||
108
- flags.react ||
109
- flags.tailwind;
110
- if (hasCodegenFlags && !flags.force) {
111
- const files = await this.fs.ls(root);
112
- // Allow a directory that only has package.json (common for monorepo packages)
113
- const meaningful = files.filter((f) => f !== "package.json");
114
- if (meaningful.length > 0) {
115
- throw new AlephaError(
116
- `Target directory is not empty (${root}). Use --force to overwrite existing files.`,
117
- );
118
- }
119
- }
120
-
121
- // Detect workspace context (are we inside packages/ or apps/ of a monorepo?)
122
- const workspace = await this.pm.getWorkspaceContext(root);
123
-
124
- // Detect agent type: claude CLI → CLAUDE.md, else → AGENTS.md
125
- let agentType: "claude" | "agents" | false = false;
126
- if (!workspace.isPackage) {
127
- const hasClaudeCli = await this.utils.isInstalledAsync("claude");
128
- agentType = hasClaudeCli ? "claude" : "agents";
129
- }
130
-
131
- const isExpo = await this.pm.hasExpo(root);
132
-
133
- // Get git email for admin auto-promotion (if auth enabled)
134
- const adminEmail = flags.auth
135
- ? await this.utils.getGitEmail()
136
- : undefined;
137
-
138
- const force = !!flags.force;
139
-
140
- await run({
141
- name: "ensuring configuration files",
142
- handler: async () => {
143
- await this.scaffolder.ensureConfig(root, {
144
- force,
145
- packageJson: { ...flags, isPackage: workspace.isPackage },
146
- // Skip workspace-level configs if they exist at workspace root
147
- tsconfigJson: !workspace.config.tsconfigJson,
148
- biomeJson: !workspace.config.biomeJson,
149
- editorconfig: !workspace.config.editorconfig,
150
- agentMd: agentType ? { type: agentType } : false,
151
- });
152
-
153
- // Create alepha.config.ts with documented options
154
- await this.scaffolder.ensureAlephaConfig(root, { force });
155
-
156
- // Create project structure based on flags
157
- await this.scaffolder.ensureMainServerTs(root, {
158
- api: !!flags.api,
159
- react: !!flags.react && !isExpo,
160
- force,
161
- });
162
- if (flags.api) {
163
- await this.scaffolder.ensureApiProject(root, {
164
- auth: !!flags.auth,
165
- adminEmail,
166
- force,
167
- });
168
- }
169
- if (flags.react && !isExpo) {
170
- await this.scaffolder.ensureWebProject(root, {
171
- api: !!flags.api,
172
- ui: !!flags.ui,
173
- auth: !!flags.auth,
174
- admin: !!flags.admin,
175
- tailwind: !!flags.tailwind,
176
- force,
177
- });
178
- }
179
- },
180
- });
181
-
182
- // Use workspace PM if detected, otherwise detect from current root
183
- const pmName = await this.pm.getPackageManager(
184
- workspace.workspaceRoot ?? root,
185
- flags.pm ?? workspace.packageManager ?? undefined,
186
- );
187
-
188
- // Only setup PM files if not in a workspace package
189
- if (!workspace.isPackage) {
190
- if (pmName === "yarn") {
191
- await this.pm.ensureYarn(root);
192
- await run("yarn set version stable", { root });
193
- } else if (pmName === "bun") {
194
- await this.pm.ensureBun(root);
195
- } else if (pmName === "pnpm") {
196
- await this.pm.ensurePnpm(root);
197
- } else {
198
- await this.pm.ensureNpm(root);
199
- }
200
- }
201
-
202
- // Run install from workspace root if in a package, otherwise from current root
203
- const installRoot = workspace.workspaceRoot ?? root;
204
- await run(`${pmName} install`, {
205
- alias: `installing dependencies with ${pmName}`,
206
- root: installRoot,
207
- });
208
-
209
- // Create test directory if --test flag is set (vitest is in package.json)
210
- if (flags.test) {
211
- await this.scaffolder.ensureTestDir(root);
212
- }
213
-
214
- await run(`${pmName} run lint`, {
215
- alias: "running linter",
216
- root: installRoot,
217
- });
218
-
219
- // Initialize git repository if not in a workspace package
220
- if (!workspace.isPackage) {
221
- const gitInitialized = await this.scaffolder.ensureGitRepo(root, {
222
- force,
223
- });
224
- if (gitInitialized) {
225
- await run("git add .", {
226
- alias: "staging generated files",
227
- root,
228
- });
229
- }
230
- }
231
-
232
- // Don't show success message if no path arg, e.g. just "alepha init" to re-configure current dir
233
- if (!args) {
234
- return;
235
- }
236
-
237
- // We must end the run context in order to log success message
238
- run.end();
239
-
240
- // Success message
241
- const projectName = args || ".";
242
- const pmRun = pmName === "npm" ? "npm run" : pmName;
243
- const c = this.colors;
244
-
245
- this.log.info("");
246
- this.log.info(` ${c.set("GREEN", "✓")} Project ready!`);
247
- this.log.info("");
248
- this.log.info(
249
- ` ${c.set("GREY_DARK", "$")} cd ${c.set("CYAN", projectName)}`,
250
- );
251
- this.log.info(
252
- ` ${c.set("GREY_DARK", "$")} ${c.set("CYAN", `${pmRun} dev`)}`,
253
- );
254
-
255
- if (adminEmail) {
256
- this.log.info("");
257
- this.log.info(` Admin email: ${c.set("GREEN", adminEmail)}`);
258
- this.log.info(
259
- ` ${c.set("GREY_DARK", "(from git config, change in src/api/AppSecurity.ts)")}`,
260
- );
261
- }
262
-
263
- this.log.info("");
73
+ await this.scaffolder.init({ run, flags, root, args });
264
74
  },
265
75
  });
266
76
  }
@@ -1,9 +1,16 @@
1
1
  import { $module } from "alepha";
2
+ import { appEntryOptions } from "./atoms/appEntryOptions.ts";
3
+ import { buildOptions } from "./atoms/buildOptions.ts";
4
+ import { devOptions } from "./atoms/devOptions.ts";
2
5
  import { BuildCommand } from "./commands/build.ts";
3
6
  import { CleanCommand } from "./commands/clean.ts";
4
7
  import { DbCommand } from "./commands/db.ts";
5
8
  import { DevCommand } from "./commands/dev.ts";
6
- import { GitMessageParser, GitProvider } from "./commands/gen/changelog.ts";
9
+ import {
10
+ changelogOptions,
11
+ GitMessageParser,
12
+ GitProvider,
13
+ } from "./commands/gen/changelog.ts";
7
14
  import { GenCommand } from "./commands/gen.ts";
8
15
  import { InitCommand } from "./commands/init.ts";
9
16
  import { LintCommand } from "./commands/lint.ts";
@@ -48,7 +55,6 @@ export * from "./commands/root.ts";
48
55
  export * from "./commands/test.ts";
49
56
  export * from "./commands/typecheck.ts";
50
57
  export * from "./commands/verify.ts";
51
- export * from "./defineConfig.ts";
52
58
  export * from "./providers/AlephaCliExtensionProvider.ts";
53
59
  export * from "./providers/AppEntryProvider.ts";
54
60
  export * from "./providers/ViteBuildProvider.ts";
@@ -56,6 +62,7 @@ export * from "./providers/ViteDevServerProvider.ts";
56
62
  export * from "./services/AlephaCliUtils.ts";
57
63
  export * from "./services/GitMessageParser.ts";
58
64
  export * from "./services/PackageManagerUtils.ts";
65
+ export * from "./services/ProjectScaffolder.ts";
59
66
  export * from "./services/ViteUtils.ts";
60
67
  export * from "./tasks/BuildAssetsTask.ts";
61
68
  export * from "./tasks/BuildClientTask.ts";
@@ -72,13 +79,36 @@ export * from "./version.ts";
72
79
 
73
80
  // ---------------------------------------------------------------------------------------------------------------------
74
81
 
75
- export const AlephaCli = $module({
76
- name: "alepha.cli",
82
+ /**
83
+ * Services, providers, and build tasks — no commands.
84
+ * Use this module when you need CLI utilities without registering commands.
85
+ */
86
+ export const AlephaCliServices = $module({
87
+ name: "alepha.cli.services",
77
88
  services: [
89
+ // Services & providers
78
90
  AlephaCliUtils,
79
91
  PackageManagerUtils,
80
92
  ViteUtils,
81
93
  ProjectScaffolder,
94
+ AppEntryProvider,
95
+ GitMessageParser,
96
+ GitProvider,
97
+ ViteDevServerProvider,
98
+ ViteBuildProvider,
99
+ ],
100
+ });
101
+
102
+ // ---------------------------------------------------------------------------------------------------------------------
103
+
104
+ /**
105
+ * Full CLI module — all services and commands.
106
+ */
107
+ export const AlephaCli = $module({
108
+ name: "alepha.cli",
109
+ atoms: [appEntryOptions, buildOptions, changelogOptions, devOptions],
110
+ services: [
111
+ AlephaCliExtensionProvider,
82
112
  // Commands
83
113
  BuildCommand,
84
114
  CleanCommand,
@@ -91,13 +121,6 @@ export const AlephaCli = $module({
91
121
  TypecheckCommand,
92
122
  VerifyCommand,
93
123
  GenCommand,
94
- // Support services
95
- AlephaCliExtensionProvider,
96
- AppEntryProvider,
97
- GitMessageParser,
98
- GitProvider,
99
- ViteDevServerProvider,
100
- ViteBuildProvider,
101
124
  // Build tasks
102
125
  BuildAssetsTask,
103
126
  BuildClientTask,
@@ -51,7 +51,7 @@ export class ViteDevServerProvider {
51
51
 
52
52
  protected server!: ViteDevServer;
53
53
  protected options!: DevServerOptions;
54
- protected alepha: Alepha | null = null;
54
+ public alepha: Alepha | null = null;
55
55
  protected hasError = false;
56
56
  protected currentError: Error | null = null;
57
57
  protected changedFiles = new Set<string>();
@@ -59,6 +59,7 @@ export class ViteDevServerProvider {
59
59
  protected reloadDebounceTimer: ReturnType<typeof setTimeout> | null = null;
60
60
  protected isReloading = false;
61
61
  protected needsBrowserReload = false;
62
+ protected currentReloadPromise: Promise<void> | null = null;
62
63
 
63
64
  /**
64
65
  * Initialize the dev server and load Alepha.
@@ -122,6 +123,7 @@ export class ViteDevServerProvider {
122
123
 
123
124
  const plugins: Plugin[] = [];
124
125
  if (viteReact && !this.options.noViteReactPlugin) plugins.push(viteReact());
126
+ plugins.push(this.viteUtils.createTsconfigPathsPlugin());
125
127
  plugins.push(this.viteUtils.createSsrPreloadPlugin());
126
128
  plugins.push(this.createAlephaPlugin());
127
129
 
@@ -233,6 +235,13 @@ export class ViteDevServerProvider {
233
235
  });
234
236
  }
235
237
 
238
+ // Re-send error overlay when a new browser connects (e.g. page refresh during error state)
239
+ server.hot.on("connection", () => {
240
+ if (this.currentError) {
241
+ setTimeout(() => this.sendErrorOverlay(this.currentError!), 50);
242
+ }
243
+ });
244
+
236
245
  // Return function to run AFTER Vite's built-in middleware
237
246
  return () => {
238
247
  server.middlewares.use(async (req, res, next) => {
@@ -243,8 +252,16 @@ export class ViteDevServerProvider {
243
252
  return;
244
253
  }
245
254
 
246
- // In error state, let Vite serve its error overlay
255
+ // In error state, serve a minimal HTML shell so the browser
256
+ // can connect to Vite's HMR and display the error overlay
247
257
  if (this.hasError && !this.alepha) {
258
+ if (req.headers.accept?.includes("text/html")) {
259
+ res.writeHead(200, { "content-type": "text/html" });
260
+ res.end(
261
+ '<!DOCTYPE html><html><head><script type="module" src="/@vite/client"></script></head><body></body></html>',
262
+ );
263
+ return;
264
+ }
248
265
  next();
249
266
  return;
250
267
  }
@@ -287,10 +304,15 @@ export class ViteDevServerProvider {
287
304
  // Queue Alepha reload for server-side invalidation
288
305
  this.changedFiles.add(ctx.file);
289
306
 
290
- // React components (.tsx/.jsx): restart Alepha silently,
291
- // let Vite HMR handle the browser update (React Fast Refresh)
307
+ // React components (.tsx/.jsx): reload Alepha BEFORE letting
308
+ // Vite HMR reach the browser, to prevent 503 errors from
309
+ // components that fetch data on mount during server reload.
292
310
  if (/\.(tsx|jsx)$/.test(ctx.file)) {
293
- this.scheduleReload();
311
+ if (this.reloadDebounceTimer) {
312
+ clearTimeout(this.reloadDebounceTimer);
313
+ this.reloadDebounceTimer = null;
314
+ }
315
+ await this.performReload();
294
316
  return;
295
317
  }
296
318
 
@@ -350,19 +372,34 @@ export class ViteDevServerProvider {
350
372
  }
351
373
 
352
374
  /**
353
- * Perform the actual reload after debounce.
375
+ * Perform the actual reload.
376
+ * Returns a promise that callers can await to know when reload is done.
377
+ * If a reload is already in progress, returns that promise.
354
378
  */
355
- protected async performReload(): Promise<void> {
356
- if (this.isReloading || this.changedFiles.size === 0) {
357
- return;
379
+ protected performReload(): Promise<void> {
380
+ if (this.changedFiles.size === 0) {
381
+ return this.currentReloadPromise ?? Promise.resolve();
382
+ }
383
+
384
+ if (this.isReloading) {
385
+ return this.currentReloadPromise ?? Promise.resolve();
358
386
  }
359
387
 
388
+ this.currentReloadPromise = this.executeReload();
389
+ return this.currentReloadPromise;
390
+ }
391
+
392
+ /**
393
+ * Execute the reload work.
394
+ */
395
+ protected async executeReload(): Promise<void> {
360
396
  this.isReloading = true;
361
397
 
362
398
  // Snapshot files to process and clear immediately
363
399
  // New files arriving during reload will go to fresh set
364
400
  const filesToInvalidate = new Set(this.changedFiles);
365
401
  const sendReload = this.needsBrowserReload;
402
+ const wasInError = this.hasError;
366
403
  this.changedFiles.clear();
367
404
  this.needsBrowserReload = false;
368
405
 
@@ -375,7 +412,7 @@ export class ViteDevServerProvider {
375
412
  await this.alepha?.start();
376
413
 
377
414
  this.currentError = null;
378
- if (sendReload) {
415
+ if (sendReload || wasInError) {
379
416
  this.sendBrowserReload();
380
417
  }
381
418
  } catch (err) {
@@ -386,6 +423,7 @@ export class ViteDevServerProvider {
386
423
  this.sendErrorOverlay(this.currentError);
387
424
  } finally {
388
425
  this.isReloading = false;
426
+ this.currentReloadPromise = null;
389
427
 
390
428
  // If more files changed during reload, schedule another
391
429
  if (this.changedFiles.size > 0) {
@@ -597,6 +635,8 @@ export class ViteDevServerProvider {
597
635
  this.waitingForRetry = false;
598
636
  this.currentError = null;
599
637
  this.server.watcher.off("change", onFileChange);
638
+ this.server.watcher.off("add", onFileChange);
639
+ this.sendBrowserReload();
600
640
  resolve(alepha);
601
641
  } catch (err) {
602
642
  this.hasError = true;
@@ -609,6 +649,7 @@ export class ViteDevServerProvider {
609
649
  };
610
650
 
611
651
  this.server.watcher.on("change", onFileChange);
652
+ this.server.watcher.on("add", onFileChange);
612
653
  });
613
654
  }
614
655
 
@@ -657,13 +698,11 @@ export class ViteDevServerProvider {
657
698
  /**
658
699
  * Log a formatted error with stack trace.
659
700
  */
660
- protected logError(title: string, err: unknown): void {
701
+ protected logError(title: string, _err: unknown): void {
661
702
  const c = this.colors;
662
703
 
663
704
  console.log();
664
705
  console.log(c.set("RED", ` ✗ ${title}`));
665
- this.logErrorWithCause(err);
666
- console.log();
667
706
  console.log(c.set("GREY_DARK", " Waiting for file changes to retry..."));
668
707
  console.log();
669
708
  }