alepha 0.15.3 → 0.15.5

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 (318) hide show
  1. package/README.md +26 -11
  2. package/dist/api/audits/index.d.ts +335 -335
  3. package/dist/api/audits/index.d.ts.map +1 -1
  4. package/dist/api/audits/index.js +11 -3
  5. package/dist/api/audits/index.js.map +1 -1
  6. package/dist/api/files/index.d.ts +3 -3
  7. package/dist/api/files/index.js +4 -3
  8. package/dist/api/files/index.js.map +1 -1
  9. package/dist/api/jobs/index.d.ts +198 -155
  10. package/dist/api/jobs/index.d.ts.map +1 -1
  11. package/dist/api/jobs/index.js +103 -5
  12. package/dist/api/jobs/index.js.map +1 -1
  13. package/dist/api/keys/index.d.ts +198 -198
  14. package/dist/api/keys/index.d.ts.map +1 -1
  15. package/dist/api/keys/index.js +3 -3
  16. package/dist/api/keys/index.js.map +1 -1
  17. package/dist/api/notifications/index.browser.js +1 -0
  18. package/dist/api/notifications/index.browser.js.map +1 -1
  19. package/dist/api/notifications/index.d.ts +3 -3
  20. package/dist/api/notifications/index.js +4 -3
  21. package/dist/api/notifications/index.js.map +1 -1
  22. package/dist/api/parameters/index.d.ts +263 -263
  23. package/dist/api/parameters/index.d.ts.map +1 -1
  24. package/dist/api/parameters/index.js +41 -30
  25. package/dist/api/parameters/index.js.map +1 -1
  26. package/dist/api/users/index.d.ts +383 -77
  27. package/dist/api/users/index.d.ts.map +1 -1
  28. package/dist/api/users/index.js +284 -72
  29. package/dist/api/users/index.js.map +1 -1
  30. package/dist/api/verifications/index.d.ts +131 -131
  31. package/dist/api/verifications/index.d.ts.map +1 -1
  32. package/dist/api/verifications/index.js +3 -3
  33. package/dist/api/verifications/index.js.map +1 -1
  34. package/dist/batch/index.d.ts +3 -3
  35. package/dist/batch/index.js +3 -3
  36. package/dist/batch/index.js.map +1 -1
  37. package/dist/bucket/index.d.ts +3 -3
  38. package/dist/bucket/index.js +6 -6
  39. package/dist/bucket/index.js.map +1 -1
  40. package/dist/cache/core/index.d.ts +3 -3
  41. package/dist/cache/core/index.js +3 -3
  42. package/dist/cache/core/index.js.map +1 -1
  43. package/dist/cli/index.d.ts +5612 -20
  44. package/dist/cli/index.d.ts.map +1 -1
  45. package/dist/cli/index.js +122 -91
  46. package/dist/cli/index.js.map +1 -1
  47. package/dist/command/index.d.ts +11 -4
  48. package/dist/command/index.d.ts.map +1 -1
  49. package/dist/command/index.js +8 -6
  50. package/dist/command/index.js.map +1 -1
  51. package/dist/core/index.browser.js.map +1 -1
  52. package/dist/core/index.d.ts +4 -8
  53. package/dist/core/index.d.ts.map +1 -1
  54. package/dist/core/index.js +3 -3
  55. package/dist/core/index.js.map +1 -1
  56. package/dist/core/index.native.js.map +1 -1
  57. package/dist/datetime/index.d.ts +3 -3
  58. package/dist/datetime/index.js +3 -3
  59. package/dist/datetime/index.js.map +1 -1
  60. package/dist/email/index.d.ts +16 -16
  61. package/dist/email/index.d.ts.map +1 -1
  62. package/dist/email/index.js +10562 -10
  63. package/dist/email/index.js.map +1 -1
  64. package/dist/fake/index.d.ts +3 -3
  65. package/dist/fake/index.js +3 -3
  66. package/dist/fake/index.js.map +1 -1
  67. package/dist/lock/core/index.d.ts +9 -4
  68. package/dist/lock/core/index.d.ts.map +1 -1
  69. package/dist/lock/core/index.js +12 -4
  70. package/dist/lock/core/index.js.map +1 -1
  71. package/dist/logger/index.d.ts +3 -3
  72. package/dist/logger/index.js +6 -3
  73. package/dist/logger/index.js.map +1 -1
  74. package/dist/mcp/index.d.ts +3 -3
  75. package/dist/mcp/index.js +3 -3
  76. package/dist/mcp/index.js.map +1 -1
  77. package/dist/orm/index.d.ts +12 -12
  78. package/dist/orm/index.js +4 -4
  79. package/dist/orm/index.js.map +1 -1
  80. package/dist/queue/core/index.d.ts +3 -3
  81. package/dist/queue/core/index.js +3 -3
  82. package/dist/queue/core/index.js.map +1 -1
  83. package/dist/react/auth/index.browser.js +2 -1
  84. package/dist/react/auth/index.browser.js.map +1 -1
  85. package/dist/react/auth/index.d.ts +3 -3
  86. package/dist/react/auth/index.js +5 -4
  87. package/dist/react/auth/index.js.map +1 -1
  88. package/dist/react/core/index.d.ts +6 -6
  89. package/dist/react/core/index.js +3 -3
  90. package/dist/react/core/index.js.map +1 -1
  91. package/dist/react/form/index.d.ts +3 -3
  92. package/dist/react/form/index.js +3 -3
  93. package/dist/react/form/index.js.map +1 -1
  94. package/dist/react/head/index.d.ts +3 -3
  95. package/dist/react/head/index.js +3 -3
  96. package/dist/react/head/index.js.map +1 -1
  97. package/dist/react/i18n/index.d.ts +3 -3
  98. package/dist/react/i18n/index.js +3 -3
  99. package/dist/react/i18n/index.js.map +1 -1
  100. package/dist/react/intro/index.css +337 -0
  101. package/dist/react/intro/index.css.map +1 -0
  102. package/dist/react/intro/index.d.ts +10 -0
  103. package/dist/react/intro/index.d.ts.map +1 -0
  104. package/dist/react/intro/index.js +222 -0
  105. package/dist/react/intro/index.js.map +1 -0
  106. package/dist/react/router/index.browser.js +2 -2
  107. package/dist/react/router/index.browser.js.map +1 -1
  108. package/dist/react/router/index.d.ts +11 -1
  109. package/dist/react/router/index.d.ts.map +1 -1
  110. package/dist/react/router/index.js +21 -11
  111. package/dist/react/router/index.js.map +1 -1
  112. package/dist/redis/index.d.ts +22 -22
  113. package/dist/redis/index.js +3 -3
  114. package/dist/redis/index.js.map +1 -1
  115. package/dist/retry/index.d.ts +3 -3
  116. package/dist/retry/index.js +3 -3
  117. package/dist/retry/index.js.map +1 -1
  118. package/dist/scheduler/index.d.ts +16 -4
  119. package/dist/scheduler/index.d.ts.map +1 -1
  120. package/dist/scheduler/index.js +45 -7
  121. package/dist/scheduler/index.js.map +1 -1
  122. package/dist/security/index.d.ts +3 -3
  123. package/dist/security/index.js +5 -5
  124. package/dist/security/index.js.map +1 -1
  125. package/dist/server/auth/index.d.ts +3 -3
  126. package/dist/server/auth/index.js +3 -3
  127. package/dist/server/auth/index.js.map +1 -1
  128. package/dist/server/cache/index.d.ts +3 -3
  129. package/dist/server/cache/index.js +3 -3
  130. package/dist/server/cache/index.js.map +1 -1
  131. package/dist/server/compress/index.d.ts +3 -3
  132. package/dist/server/compress/index.d.ts.map +1 -1
  133. package/dist/server/compress/index.js +4 -3
  134. package/dist/server/compress/index.js.map +1 -1
  135. package/dist/server/cookies/index.d.ts +3 -3
  136. package/dist/server/cookies/index.js +3 -3
  137. package/dist/server/cookies/index.js.map +1 -1
  138. package/dist/server/core/index.d.ts +14 -25
  139. package/dist/server/core/index.d.ts.map +1 -1
  140. package/dist/server/core/index.js +13 -29
  141. package/dist/server/core/index.js.map +1 -1
  142. package/dist/server/cors/index.d.ts +3 -3
  143. package/dist/server/cors/index.js +3 -3
  144. package/dist/server/cors/index.js.map +1 -1
  145. package/dist/server/health/index.d.ts +20 -20
  146. package/dist/server/health/index.js +3 -3
  147. package/dist/server/health/index.js.map +1 -1
  148. package/dist/server/helmet/index.d.ts +3 -3
  149. package/dist/server/helmet/index.js +3 -3
  150. package/dist/server/helmet/index.js.map +1 -1
  151. package/dist/server/links/index.d.ts +42 -42
  152. package/dist/server/links/index.d.ts.map +1 -1
  153. package/dist/server/links/index.js +4 -4
  154. package/dist/server/links/index.js.map +1 -1
  155. package/dist/server/metrics/index.d.ts +3 -3
  156. package/dist/server/metrics/index.js +3 -3
  157. package/dist/server/metrics/index.js.map +1 -1
  158. package/dist/server/multipart/index.d.ts +3 -3
  159. package/dist/server/multipart/index.js +3 -3
  160. package/dist/server/multipart/index.js.map +1 -1
  161. package/dist/server/proxy/index.d.ts +3 -3
  162. package/dist/server/proxy/index.js +3 -3
  163. package/dist/server/proxy/index.js.map +1 -1
  164. package/dist/server/rate-limit/index.d.ts +3 -3
  165. package/dist/server/rate-limit/index.js +3 -3
  166. package/dist/server/rate-limit/index.js.map +1 -1
  167. package/dist/server/static/index.d.ts +3 -3
  168. package/dist/server/static/index.js +6 -6
  169. package/dist/server/static/index.js.map +1 -1
  170. package/dist/server/swagger/index.d.ts +3 -3
  171. package/dist/server/swagger/index.js +6 -6
  172. package/dist/server/swagger/index.js.map +1 -1
  173. package/dist/sms/index.d.ts +3 -3
  174. package/dist/sms/index.js +6 -6
  175. package/dist/sms/index.js.map +1 -1
  176. package/dist/system/index.d.ts +3 -3
  177. package/dist/system/index.js +3 -3
  178. package/dist/system/index.js.map +1 -1
  179. package/dist/thread/index.d.ts +3 -3
  180. package/dist/thread/index.js +3 -3
  181. package/dist/thread/index.js.map +1 -1
  182. package/dist/topic/core/index.d.ts +3 -3
  183. package/dist/topic/core/index.js +3 -3
  184. package/dist/topic/core/index.js.map +1 -1
  185. package/dist/vite/index.d.ts +6286 -4
  186. package/dist/vite/index.d.ts.map +1 -1
  187. package/dist/vite/index.js +28 -2
  188. package/dist/vite/index.js.map +1 -1
  189. package/dist/websocket/index.d.ts +37 -37
  190. package/dist/websocket/index.d.ts.map +1 -1
  191. package/dist/websocket/index.js +3 -3
  192. package/dist/websocket/index.js.map +1 -1
  193. package/package.json +12 -4
  194. package/src/api/audits/controllers/AdminAuditController.ts +8 -0
  195. package/src/api/audits/index.ts +3 -3
  196. package/src/api/files/controllers/AdminFileStatsController.ts +1 -0
  197. package/src/api/files/index.ts +3 -3
  198. package/src/api/jobs/controllers/AdminJobController.ts +18 -2
  199. package/src/api/jobs/index.ts +4 -3
  200. package/src/api/jobs/services/JobAudits.spec.ts +89 -0
  201. package/src/api/jobs/services/JobAudits.ts +101 -0
  202. package/src/api/keys/index.ts +3 -3
  203. package/src/api/notifications/controllers/AdminNotificationController.ts +1 -0
  204. package/src/api/notifications/index.ts +3 -3
  205. package/src/api/parameters/controllers/AdminConfigController.ts +10 -0
  206. package/src/api/parameters/index.ts +5 -3
  207. package/src/api/users/__tests__/ApiKeys-integration.spec.ts +1 -1
  208. package/src/api/users/__tests__/ApiKeys.spec.ts +1 -1
  209. package/src/api/users/__tests__/EmailVerification.spec.ts +16 -1
  210. package/src/api/users/__tests__/PasswordReset.spec.ts +11 -0
  211. package/src/api/users/atoms/realmAuthSettingsAtom.ts +10 -0
  212. package/src/api/users/controllers/AdminIdentityController.ts +3 -0
  213. package/src/api/users/controllers/AdminSessionController.ts +3 -0
  214. package/src/api/users/controllers/AdminUserController.ts +5 -0
  215. package/src/api/users/index.ts +8 -9
  216. package/src/api/users/primitives/$realm.ts +117 -19
  217. package/src/api/users/providers/RealmProvider.ts +15 -7
  218. package/src/api/users/services/CredentialService.spec.ts +11 -0
  219. package/src/api/users/services/CredentialService.ts +47 -24
  220. package/src/api/users/services/IdentityService.ts +12 -4
  221. package/src/api/users/services/RegistrationService.spec.ts +11 -0
  222. package/src/api/users/services/RegistrationService.ts +33 -12
  223. package/src/api/users/services/SessionService.ts +83 -12
  224. package/src/api/users/services/UserAudits.ts +47 -0
  225. package/src/api/users/services/UserFiles.ts +19 -0
  226. package/src/api/users/services/UserJobs.spec.ts +107 -0
  227. package/src/api/users/services/UserJobs.ts +62 -0
  228. package/src/api/users/services/UserParameters.ts +23 -0
  229. package/src/api/users/services/UserService.ts +34 -17
  230. package/src/api/verifications/index.ts +3 -3
  231. package/src/batch/index.ts +3 -3
  232. package/src/bucket/index.ts +3 -3
  233. package/src/cache/core/index.ts +3 -3
  234. package/src/cli/commands/build.ts +1 -0
  235. package/src/cli/commands/db.ts +9 -0
  236. package/src/cli/commands/init.spec.ts +2 -17
  237. package/src/cli/commands/init.ts +37 -1
  238. package/src/cli/providers/ViteDevServerProvider.ts +36 -2
  239. package/src/cli/services/AlephaCliUtils.ts +17 -0
  240. package/src/cli/services/PackageManagerUtils.ts +15 -1
  241. package/src/cli/services/ProjectScaffolder.ts +8 -13
  242. package/src/cli/templates/agentMd.ts +2 -25
  243. package/src/cli/templates/apiAppSecurityTs.ts +37 -2
  244. package/src/cli/templates/mainCss.ts +2 -32
  245. package/src/cli/templates/webAppRouterTs.ts +5 -5
  246. package/src/cli/templates/webHomeComponentTsx.ts +10 -0
  247. package/src/command/helpers/Runner.ts +14 -1
  248. package/src/command/index.ts +3 -3
  249. package/src/core/helpers/primitive.ts +0 -5
  250. package/src/core/index.ts +3 -3
  251. package/src/datetime/index.ts +3 -3
  252. package/src/email/index.ts +3 -3
  253. package/src/email/index.workerd.ts +36 -0
  254. package/src/email/providers/LocalEmailProvider.ts +2 -2
  255. package/src/email/providers/WorkermailerEmailProvider.ts +221 -0
  256. package/src/fake/index.ts +3 -3
  257. package/src/lock/core/index.ts +3 -3
  258. package/src/lock/core/primitives/$lock.ts +13 -1
  259. package/src/logger/index.ts +3 -3
  260. package/src/logger/providers/PrettyFormatterProvider.ts +7 -0
  261. package/src/mcp/index.ts +3 -3
  262. package/src/orm/index.ts +3 -3
  263. package/src/orm/providers/drivers/NodeSqliteProvider.ts +1 -1
  264. package/src/queue/core/index.ts +3 -3
  265. package/src/react/auth/index.ts +3 -3
  266. package/src/react/auth/services/ReactAuth.ts +3 -1
  267. package/src/react/core/index.ts +3 -3
  268. package/src/react/form/index.ts +3 -3
  269. package/src/react/head/index.ts +3 -3
  270. package/src/react/i18n/index.ts +3 -3
  271. package/src/react/intro/components/GettingStarted.css +334 -0
  272. package/src/react/intro/components/GettingStarted.tsx +276 -0
  273. package/src/react/intro/index.ts +1 -0
  274. package/src/react/router/atoms/ssrManifestAtom.ts +7 -0
  275. package/src/react/router/index.browser.ts +2 -0
  276. package/src/react/router/index.ts +2 -0
  277. package/src/react/router/providers/ReactServerProvider.ts +14 -4
  278. package/src/react/router/providers/SSRManifestProvider.ts +7 -0
  279. package/src/redis/index.ts +3 -3
  280. package/src/retry/index.ts +3 -3
  281. package/src/router/index.ts +3 -3
  282. package/src/scheduler/index.ts +3 -3
  283. package/src/scheduler/index.workerd.ts +43 -0
  284. package/src/scheduler/providers/CronProvider.ts +53 -6
  285. package/src/scheduler/providers/WorkerdCronProvider.ts +102 -0
  286. package/src/security/index.ts +3 -3
  287. package/src/security/providers/JwtProvider.ts +2 -2
  288. package/src/server/auth/index.ts +3 -3
  289. package/src/server/cache/index.ts +3 -3
  290. package/src/server/compress/index.ts +3 -3
  291. package/src/server/compress/providers/ServerCompressProvider.ts +6 -0
  292. package/src/server/cookies/index.ts +3 -3
  293. package/src/server/core/index.ts +3 -3
  294. package/src/server/core/primitives/$action.spec.ts +3 -2
  295. package/src/server/core/primitives/$action.ts +6 -2
  296. package/src/server/core/providers/NodeHttpServerProvider.ts +2 -15
  297. package/src/server/core/providers/ServerProvider.ts +4 -2
  298. package/src/server/core/providers/ServerRouterProvider.ts +5 -27
  299. package/src/server/cors/index.ts +3 -3
  300. package/src/server/health/index.ts +3 -3
  301. package/src/server/helmet/index.ts +3 -3
  302. package/src/server/links/index.ts +3 -3
  303. package/src/server/links/providers/ServerLinksProvider.spec.ts +332 -0
  304. package/src/server/links/providers/ServerLinksProvider.ts +1 -1
  305. package/src/server/metrics/index.ts +3 -3
  306. package/src/server/multipart/index.ts +3 -3
  307. package/src/server/proxy/index.ts +3 -3
  308. package/src/server/rate-limit/index.ts +3 -3
  309. package/src/server/static/index.ts +3 -3
  310. package/src/server/swagger/index.ts +3 -3
  311. package/src/sms/index.ts +3 -3
  312. package/src/system/index.ts +3 -3
  313. package/src/thread/index.ts +3 -3
  314. package/src/topic/core/index.ts +3 -3
  315. package/src/vite/tasks/generateCloudflare.ts +38 -2
  316. package/src/websocket/index.ts +3 -3
  317. package/src/cli/templates/webHelloComponentTsx.ts +0 -30
  318. /package/src/api/users/{notifications → services}/UserNotifications.ts +0 -0
package/dist/cli/index.js CHANGED
@@ -1814,9 +1814,9 @@ var ShellProvider = class {};
1814
1814
  //#endregion
1815
1815
  //#region ../../src/system/index.ts
1816
1816
  /**
1817
- * | type | quality | stability |
1818
- * |------|---------|-----------|
1819
- * | tooling | standard | stable |
1817
+ * | Stability | Since | Runtime |
1818
+ * |-----------|-------|---------|
1819
+ * | 3 - stable | 0.14.0 | node, bun, browser|
1820
1820
  *
1821
1821
  * System-level abstractions for portable code across runtimes.
1822
1822
  *
@@ -2238,6 +2238,18 @@ ${models.map((it) => `export const ${it} = models["${it}"];`).join("\n")}
2238
2238
  return "unknown";
2239
2239
  }
2240
2240
  }
2241
+ /**
2242
+ * Get the user's email from git config.
2243
+ *
2244
+ * @returns The git user email or undefined if not configured
2245
+ */
2246
+ async getGitEmail() {
2247
+ try {
2248
+ return (await this.shell.run("git config user.email", { capture: true })).trim() || void 0;
2249
+ } catch {
2250
+ return;
2251
+ }
2252
+ }
2241
2253
  };
2242
2254
 
2243
2255
  //#endregion
@@ -2257,13 +2269,16 @@ var devDependencies = {
2257
2269
  "cron-schedule": "^6.0.0",
2258
2270
  "jose": "^6.1.3",
2259
2271
  "jsdom": "^27.4.0",
2272
+ "nodemailer": "^7.0.13",
2260
2273
  "openid-client": "^6.8.1",
2261
2274
  "prom-client": "^15.1.3",
2262
2275
  "react": "^19.2.4",
2263
2276
  "react-dom": "^19.2.4",
2264
2277
  "swagger-ui-dist": "^5.31.0",
2265
2278
  "tsdown": "^0.20.1",
2266
- "vitest": "^4.0.18"
2279
+ "vite": "^7.3.1",
2280
+ "vitest": "^4.0.18",
2281
+ "worker-mailer": "^1.2.1"
2267
2282
  };
2268
2283
 
2269
2284
  //#endregion
@@ -2288,6 +2303,7 @@ var PackageManagerUtils = class {
2288
2303
  alepha = $inject(Alepha);
2289
2304
  /**
2290
2305
  * Detect the package manager used in the project.
2306
+ * Checks current directory first, then workspace root if in a monorepo.
2291
2307
  */
2292
2308
  async getPackageManager(root, pm) {
2293
2309
  if (pm) return pm;
@@ -2295,6 +2311,9 @@ var PackageManagerUtils = class {
2295
2311
  if (await this.fs.exists(this.fs.join(root, "bun.lock"))) return "bun";
2296
2312
  if (await this.fs.exists(this.fs.join(root, "yarn.lock"))) return "yarn";
2297
2313
  if (await this.fs.exists(this.fs.join(root, "pnpm-lock.yaml"))) return "pnpm";
2314
+ if (await this.fs.exists(this.fs.join(root, "package-lock.json"))) return "npm";
2315
+ const workspace = await this.getWorkspaceContext(root);
2316
+ if (workspace.packageManager) return workspace.packageManager;
2298
2317
  return "npm";
2299
2318
  }
2300
2319
  /**
@@ -2491,7 +2510,7 @@ var PackageManagerUtils = class {
2491
2510
  generatePackageJsonContent(modes) {
2492
2511
  const alephaDeps = devDependencies;
2493
2512
  const dependencies = { alepha: `^${version}` };
2494
- const devDependencies$1 = {};
2513
+ const devDependencies$1 = { vite: alephaDeps.vite };
2495
2514
  if (!modes.isPackage) {
2496
2515
  devDependencies$1["@biomejs/biome"] = alephaDeps["@biomejs/biome"];
2497
2516
  if (modes.test) devDependencies$1.vitest = alephaDeps.vitest;
@@ -2543,6 +2562,7 @@ This file provides guidance to AI coding assistants when working with this Aleph
2543
2562
 
2544
2563
  ### Pages with \`$page\`
2545
2564
  \`\`\`tsx
2565
+ import { t } from "alepha";
2546
2566
  import { $page } from "alepha/react/router";
2547
2567
  import { $client } from "alepha/server/links";
2548
2568
  import type { UserController } from "./UserController.ts";
@@ -2707,31 +2727,6 @@ class AppRouter {
2707
2727
  }
2708
2728
  \`\`\`
2709
2729
 
2710
- ### Modules with \`$module\`
2711
- \`\`\`typescript
2712
- // src/api/index.ts - Groups all API services
2713
- import { $module } from "alepha";
2714
-
2715
- export const ApiModule = $module({
2716
- name: "app.api",
2717
- services: [
2718
- UserController,
2719
- OrderController,
2720
- UserService,
2721
- ],
2722
- });
2723
-
2724
- // src/web/index.ts - Groups all web services (React only)
2725
- export const WebModule = $module({
2726
- name: "app.web",
2727
- services: [AppRouter, Toaster],
2728
- register(alepha) {
2729
- // Optional: configure additional services
2730
- alepha.with(SomeLibrary);
2731
- },
2732
- });
2733
- \`\`\`
2734
-
2735
2730
  ### Environment Variables
2736
2731
  \`\`\`typescript
2737
2732
  import { $env, t } from "alepha";
@@ -2775,6 +2770,7 @@ describe("UserService", () => {
2775
2770
  it("should create user", async () => {
2776
2771
  const alepha = Alepha.create().with(UserService);
2777
2772
  const service = alepha.inject(UserService);
2773
+ await alepha.start();
2778
2774
 
2779
2775
  const user = await service.create({ email: "test@example.com" });
2780
2776
  expect(user.email).toBe("test@example.com");
@@ -2829,13 +2825,46 @@ Full framework source available at \`node_modules/alepha/src/\`.
2829
2825
 
2830
2826
  //#endregion
2831
2827
  //#region ../../src/cli/templates/apiAppSecurityTs.ts
2832
- const apiAppSecurityTs = () => {
2828
+ const apiAppSecurityTs = (opts = {}) => {
2833
2829
  return `
2834
2830
  import { $realm } from "alepha/api/users";
2835
2831
 
2836
2832
  export class AppSecurity {
2837
2833
  users = $realm({
2838
- // configure your realm here
2834
+ settings: {
2835
+ // Auto-promote these users to admin on login
2836
+ adminEmails: ${opts.adminEmail ? `["${opts.adminEmail}"]` : "[]"},
2837
+ adminUsernames: [],
2838
+
2839
+ // Registration & login options
2840
+ registrationAllowed: true,
2841
+ emailEnabled: true,
2842
+ emailRequired: true,
2843
+ usernameEnabled: false,
2844
+ usernameRequired: false,
2845
+ phoneEnabled: false,
2846
+ phoneRequired: false,
2847
+
2848
+ // Verification (requires notifications feature)
2849
+ verifyEmailRequired: false,
2850
+ verifyPhoneRequired: false,
2851
+ resetPasswordAllowed: false,
2852
+ },
2853
+ features: {
2854
+ // Enable additional features
2855
+ notifications: false,
2856
+ audits: false,
2857
+ apiKeys: false,
2858
+ jobs: false,
2859
+ files: false,
2860
+ parameters: false,
2861
+ },
2862
+ identities: {
2863
+ // Enable authentication providers
2864
+ credentials: true,
2865
+ // google: true,
2866
+ // github: true,
2867
+ },
2839
2868
  });
2840
2869
  }
2841
2870
  `.trim();
@@ -3002,31 +3031,8 @@ run(alepha);
3002
3031
 
3003
3032
  //#endregion
3004
3033
  //#region ../../src/cli/templates/mainCss.ts
3005
- const mainCss = (options = {}) => {
3006
- if (options.ui) return `@import "@alepha/ui/styles";`;
3007
- return `
3008
- * {
3009
- box-sizing: border-box;
3010
- margin: 0;
3011
- padding: 0;
3012
- }
3013
-
3014
- html,
3015
- body {
3016
- height: 100%;
3017
- }
3018
-
3019
- body {
3020
- font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
3021
- "Helvetica Neue", Arial, sans-serif;
3022
- line-height: 1.5;
3023
- -webkit-font-smoothing: antialiased;
3024
- }
3025
-
3026
- #root {
3027
- height: 100%;
3028
- }
3029
- `.trim();
3034
+ const mainCss = () => {
3035
+ return `@import "@alepha/ui/styles";`;
3030
3036
  };
3031
3037
 
3032
3038
  //#endregion
@@ -3080,18 +3086,18 @@ const webAppRouterTs = (options) => {
3080
3086
  if (options.auth) classMembers.push(" uiAuth = $uiAuth();");
3081
3087
  if (options.admin) classMembers.push(" uiAdmin = $uiAdmin();");
3082
3088
  classMembers.push(` layout = $page({
3083
- parent: this.ui.root,
3084
- children: () => [this.home],
3085
- });`);
3089
+ parent: this.ui.root,
3090
+ children: () => [this.home],
3091
+ });`);
3086
3092
  }
3087
3093
  if (options.api) classMembers.push(` home = $page({
3088
3094
  path: "/",
3089
- lazy: () => import("./components/Hello.tsx"),
3095
+ lazy: () => import("./components/Home.tsx"),
3090
3096
  loader: () => this.api.hello(),
3091
3097
  });`);
3092
3098
  else classMembers.push(` home = $page({
3093
3099
  path: "/",
3094
- lazy: () => import("./components/Hello.tsx"),
3100
+ lazy: () => import("./components/Home.tsx"),
3095
3101
  });`);
3096
3102
  return `${imports.join("\n")}
3097
3103
 
@@ -3101,30 +3107,15 @@ ${classMembers.join("\n\n")}
3101
3107
  };
3102
3108
 
3103
3109
  //#endregion
3104
- //#region ../../src/cli/templates/webHelloComponentTsx.ts
3105
- const webHelloComponentTsx = (options = {}) => {
3106
- const imports = [];
3107
- if (options.auth) imports.push("import { UserButton } from \"@alepha/ui/auth\";");
3108
- imports.push("import { useState } from \"react\";");
3109
- const userButton = options.auth ? "\n <UserButton />" : "";
3110
- return `${imports.join("\n")}
3111
-
3112
- interface Props {
3113
- message?: string;
3114
- }
3110
+ //#region ../../src/cli/templates/webHomeComponentTsx.ts
3111
+ const webHomeComponentTsx = () => {
3112
+ return `import { GettingStarted } from "alepha/react/intro";
3115
3113
 
3116
- const Hello = (props: Props) => {
3117
- const [message, setMessage] = useState(props.message ?? "");
3118
- return (
3119
- <div>
3120
- <h1>{message}</h1>
3121
- <input value={message} onChange={(e) => setMessage(e.target.value)} />
3122
- <p>Edit this component in src/web/components/Hello.tsx</p>${userButton}
3123
- </div>
3124
- );
3114
+ const Home = () => {
3115
+ return <GettingStarted />;
3125
3116
  };
3126
3117
 
3127
- export default Hello;
3118
+ export default Home;
3128
3119
  `;
3129
3120
  };
3130
3121
 
@@ -3152,7 +3143,7 @@ export const WebModule = $module({
3152
3143
  * - Project structure (src/api, src/web)
3153
3144
  * - Configuration files (tsconfig, biome, editorconfig)
3154
3145
  * - Entry points (main.server.ts, main.browser.ts)
3155
- * - Example code (HelloController, Hello component)
3146
+ * - Example code (HelloController, Home component)
3156
3147
  */
3157
3148
  var ProjectScaffolder = class {
3158
3149
  log = $logger();
@@ -3251,7 +3242,7 @@ var ProjectScaffolder = class {
3251
3242
  auth: opts.auth
3252
3243
  }), opts.force);
3253
3244
  await this.ensureFile(root, "src/api/controllers/HelloController.ts", apiHelloControllerTs(), opts.force);
3254
- if (opts.auth) await this.ensureFile(root, "src/api/AppSecurity.ts", apiAppSecurityTs(), opts.force);
3245
+ if (opts.auth) await this.ensureFile(root, "src/api/AppSecurity.ts", apiAppSecurityTs({ adminEmail: opts.adminEmail }), opts.force);
3255
3246
  }
3256
3247
  /**
3257
3248
  * Ensure web/React project structure exists.
@@ -3259,12 +3250,12 @@ var ProjectScaffolder = class {
3259
3250
  * Creates:
3260
3251
  * - src/main.browser.ts
3261
3252
  * - src/main.css
3262
- * - src/web/index.ts, src/web/AppRouter.ts, src/web/components/Hello.tsx
3253
+ * - src/web/index.ts, src/web/AppRouter.ts, src/web/components/Home.tsx
3263
3254
  */
3264
3255
  async ensureWebProject(root, opts = {}) {
3265
3256
  const appName = this.getAppName(root);
3266
3257
  await this.fs.mkdir(this.fs.join(root, "src/web/components"), { recursive: true });
3267
- await this.ensureFile(root, "src/main.css", mainCss({ ui: opts.ui }), opts.force);
3258
+ await this.ensureFile(root, "src/main.css", mainCss(), opts.force);
3268
3259
  await this.ensureFile(root, "src/web/index.ts", webIndexTs({ appName }), opts.force);
3269
3260
  await this.ensureFile(root, "src/web/AppRouter.ts", webAppRouterTs({
3270
3261
  api: opts.api,
@@ -3272,7 +3263,7 @@ var ProjectScaffolder = class {
3272
3263
  auth: opts.auth,
3273
3264
  admin: opts.admin
3274
3265
  }), opts.force);
3275
- await this.ensureFile(root, "src/web/components/Hello.tsx", webHelloComponentTsx({ auth: opts.auth }), opts.force);
3266
+ await this.ensureFile(root, "src/web/components/Home.tsx", webHomeComponentTsx(), opts.force);
3276
3267
  await this.ensureFile(root, "src/main.browser.ts", mainBrowserTs(), opts.force);
3277
3268
  }
3278
3269
  /**
@@ -3473,7 +3464,8 @@ var BuildCommand = class {
3473
3464
  name: "add Cloudflare config",
3474
3465
  handler: () => generateCloudflare({
3475
3466
  distDir,
3476
- config: options.cloudflare?.config
3467
+ config: options.cloudflare?.config,
3468
+ alepha
3477
3469
  })
3478
3470
  });
3479
3471
  if (target === "docker") {
@@ -3548,6 +3540,7 @@ var DbCommand = class {
3548
3540
  log = $logger();
3549
3541
  fs = $inject(FileSystemProvider);
3550
3542
  utils = $inject(AlephaCliUtils);
3543
+ pm = $inject(PackageManagerUtils);
3551
3544
  entryProvider = $inject(AppEntryProvider);
3552
3545
  /**
3553
3546
  * Check if database migrations are up to date.
@@ -3752,6 +3745,10 @@ var DbCommand = class {
3752
3745
  }
3753
3746
  this.log.info("");
3754
3747
  this.log.info(options.logMessage(providerName, dialect));
3748
+ if (dialect === "sqlite") await this.pm.ensureDependency(options.root, "better-sqlite3", {
3749
+ dev: true,
3750
+ exec: (cmd, opts) => this.utils.exec(cmd, opts)
3751
+ });
3755
3752
  const drizzleConfigJsPath = await this.prepareDrizzleConfig({
3756
3753
  kit: drizzleKitProvider,
3757
3754
  provider,
@@ -4047,6 +4044,7 @@ var ViteDevServerProvider = class {
4047
4044
  await this.server.ssrLoadModule(this.options.entry.server);
4048
4045
  const alepha = globalThis.__alepha;
4049
4046
  if (!alepha) throw new AlephaError("Alepha instance not found after loading entry module");
4047
+ alepha.store.set("alepha.vite.server", this.server);
4050
4048
  this.alepha = alepha;
4051
4049
  await this.setupAlepha();
4052
4050
  this.hasError = false;
@@ -4066,6 +4064,8 @@ var ViteDevServerProvider = class {
4066
4064
  */
4067
4065
  async setupAlepha() {
4068
4066
  if (!this.alepha || !this.hasReact()) return;
4067
+ const devHead = await this.generateDevHead();
4068
+ this.alepha.store.set("alepha.react.ssr.manifest", { devHead });
4069
4069
  this.alepha.events.on("server:onRequest", {
4070
4070
  priority: "first",
4071
4071
  callback: async ({ request }) => {
@@ -4079,6 +4079,18 @@ var ViteDevServerProvider = class {
4079
4079
  });
4080
4080
  }
4081
4081
  /**
4082
+ * Generate dev head content by transforming a minimal HTML through Vite.
4083
+ * This lets Vite and all plugins inject their scripts (HMR client, React Fast Refresh, etc.).
4084
+ */
4085
+ async generateDevHead() {
4086
+ const { browser, style } = this.options.entry;
4087
+ const scripts = [];
4088
+ if (style) scripts.push(`<link rel="stylesheet" href="/${style}">`);
4089
+ if (browser) scripts.push(`<script type="module" src="/${browser}"><\/script>`);
4090
+ const minimalHtml = `<!DOCTYPE html><html><head>${scripts.join("\n")}</head><body></body></html>`;
4091
+ return (await this.server.transformIndexHtml("/", minimalHtml)).match(/<head>([\s\S]*?)<\/head>/i)?.[1]?.trim() ?? "";
4092
+ }
4093
+ /**
4082
4094
  * Check if request is for an HTML page (not an asset).
4083
4095
  */
4084
4096
  isPageRequest(req) {
@@ -4106,7 +4118,7 @@ var ViteDevServerProvider = class {
4106
4118
  const originalWrite = res.write.bind(res);
4107
4119
  const originalEnd = res.end.bind(res);
4108
4120
  const guardedCall = (fn, ...args) => {
4109
- if (resolved && !ctx.metadata.vite) return;
4121
+ if (resolved && ctx.metadata.vite) return;
4110
4122
  return fn(...args);
4111
4123
  };
4112
4124
  res.setHeader = (...args) => guardedCall(originalSetHeader, ...args);
@@ -4488,6 +4500,8 @@ var GenCommand = class {
4488
4500
  //#endregion
4489
4501
  //#region ../../src/cli/commands/init.ts
4490
4502
  var InitCommand = class {
4503
+ log = $logger();
4504
+ colors = $inject(ConsoleColorProvider);
4491
4505
  utils = $inject(AlephaCliUtils);
4492
4506
  pm = $inject(PackageManagerUtils);
4493
4507
  scaffolder = $inject(ProjectScaffolder);
@@ -4541,17 +4555,18 @@ var InitCommand = class {
4541
4555
  let agentType = false;
4542
4556
  if (flags.ai) agentType = await this.utils.isInstalledAsync("claude") ? "claude" : "agents";
4543
4557
  const isExpo = await this.pm.hasExpo(root);
4558
+ const adminEmail = flags.auth ? await this.utils.getGitEmail() : void 0;
4544
4559
  const force = !!flags.force;
4545
4560
  await run({
4546
4561
  name: "ensuring configuration files",
4547
4562
  handler: async () => {
4548
4563
  await this.scaffolder.ensureConfig(root, {
4549
4564
  force,
4550
- tsconfigJson: !workspace.config.tsconfigJson,
4551
4565
  packageJson: {
4552
4566
  ...flags,
4553
4567
  isPackage: workspace.isPackage
4554
4568
  },
4569
+ tsconfigJson: !workspace.config.tsconfigJson,
4555
4570
  biomeJson: !workspace.config.biomeJson,
4556
4571
  editorconfig: !workspace.config.editorconfig,
4557
4572
  agentMd: agentType ? {
@@ -4567,6 +4582,7 @@ var InitCommand = class {
4567
4582
  });
4568
4583
  if (flags.api) await this.scaffolder.ensureApiProject(root, {
4569
4584
  auth: !!flags.auth,
4585
+ adminEmail,
4570
4586
  force
4571
4587
  });
4572
4588
  if (flags.react && !isExpo) await this.scaffolder.ensureWebProject(root, {
@@ -4601,6 +4617,21 @@ var InitCommand = class {
4601
4617
  root
4602
4618
  });
4603
4619
  }
4620
+ run.end();
4621
+ const projectName = args || ".";
4622
+ const pmRun = pmName === "npm" ? "npm run" : pmName;
4623
+ const c = this.colors;
4624
+ this.log.info("");
4625
+ this.log.info(` ${c.set("GREEN", "✓")} Project ready!`);
4626
+ this.log.info("");
4627
+ this.log.info(` ${c.set("GREY_DARK", "$")} cd ${c.set("CYAN", projectName)}`);
4628
+ this.log.info(` ${c.set("GREY_DARK", "$")} ${c.set("CYAN", `${pmRun} dev`)}`);
4629
+ if (adminEmail) {
4630
+ this.log.info("");
4631
+ this.log.info(` Admin email: ${c.set("GREEN", adminEmail)}`);
4632
+ this.log.info(` ${c.set("GREY_DARK", "(from git config, change in src/api/AppSecurity.ts)")}`);
4633
+ }
4634
+ this.log.info("");
4604
4635
  }
4605
4636
  });
4606
4637
  };