alepha 0.14.3 → 0.15.0

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 (317) hide show
  1. package/README.md +2 -5
  2. package/dist/api/audits/index.d.ts +620 -811
  3. package/dist/api/audits/index.d.ts.map +1 -1
  4. package/dist/api/files/index.d.ts +185 -377
  5. package/dist/api/files/index.d.ts.map +1 -1
  6. package/dist/api/files/index.js +0 -1
  7. package/dist/api/files/index.js.map +1 -1
  8. package/dist/api/jobs/index.d.ts +245 -435
  9. package/dist/api/jobs/index.d.ts.map +1 -1
  10. package/dist/api/notifications/index.d.ts +238 -429
  11. package/dist/api/notifications/index.d.ts.map +1 -1
  12. package/dist/api/parameters/index.d.ts +236 -427
  13. package/dist/api/parameters/index.d.ts.map +1 -1
  14. package/dist/api/users/index.browser.js +1 -2
  15. package/dist/api/users/index.browser.js.map +1 -1
  16. package/dist/api/users/index.d.ts +1010 -1196
  17. package/dist/api/users/index.d.ts.map +1 -1
  18. package/dist/api/users/index.js +178 -151
  19. package/dist/api/users/index.js.map +1 -1
  20. package/dist/api/verifications/index.d.ts +17 -17
  21. package/dist/api/verifications/index.d.ts.map +1 -1
  22. package/dist/batch/index.d.ts +122 -122
  23. package/dist/batch/index.d.ts.map +1 -1
  24. package/dist/batch/index.js +1 -2
  25. package/dist/batch/index.js.map +1 -1
  26. package/dist/bucket/index.d.ts +163 -163
  27. package/dist/bucket/index.d.ts.map +1 -1
  28. package/dist/cache/core/index.d.ts +46 -46
  29. package/dist/cache/core/index.d.ts.map +1 -1
  30. package/dist/cache/redis/index.d.ts.map +1 -1
  31. package/dist/cli/index.d.ts +384 -285
  32. package/dist/cli/index.d.ts.map +1 -1
  33. package/dist/cli/index.js +1113 -623
  34. package/dist/cli/index.js.map +1 -1
  35. package/dist/command/index.d.ts +299 -300
  36. package/dist/command/index.d.ts.map +1 -1
  37. package/dist/command/index.js +13 -9
  38. package/dist/command/index.js.map +1 -1
  39. package/dist/core/index.browser.js +445 -103
  40. package/dist/core/index.browser.js.map +1 -1
  41. package/dist/core/index.d.ts +733 -625
  42. package/dist/core/index.d.ts.map +1 -1
  43. package/dist/core/index.js +446 -103
  44. package/dist/core/index.js.map +1 -1
  45. package/dist/core/index.native.js +445 -103
  46. package/dist/core/index.native.js.map +1 -1
  47. package/dist/datetime/index.d.ts +44 -44
  48. package/dist/datetime/index.d.ts.map +1 -1
  49. package/dist/datetime/index.js +4 -4
  50. package/dist/datetime/index.js.map +1 -1
  51. package/dist/email/index.d.ts +97 -50
  52. package/dist/email/index.d.ts.map +1 -1
  53. package/dist/email/index.js +129 -33
  54. package/dist/email/index.js.map +1 -1
  55. package/dist/fake/index.d.ts +7981 -14
  56. package/dist/fake/index.d.ts.map +1 -1
  57. package/dist/file/index.d.ts +523 -390
  58. package/dist/file/index.d.ts.map +1 -1
  59. package/dist/file/index.js +253 -1
  60. package/dist/file/index.js.map +1 -1
  61. package/dist/lock/core/index.d.ts +208 -208
  62. package/dist/lock/core/index.d.ts.map +1 -1
  63. package/dist/lock/redis/index.d.ts.map +1 -1
  64. package/dist/logger/index.d.ts +25 -26
  65. package/dist/logger/index.d.ts.map +1 -1
  66. package/dist/logger/index.js +12 -2
  67. package/dist/logger/index.js.map +1 -1
  68. package/dist/mcp/index.d.ts +197 -197
  69. package/dist/mcp/index.d.ts.map +1 -1
  70. package/dist/mcp/index.js +1 -1
  71. package/dist/mcp/index.js.map +1 -1
  72. package/dist/orm/chunk-DtkW-qnP.js +38 -0
  73. package/dist/orm/index.browser.js.map +1 -1
  74. package/dist/orm/index.bun.js +2814 -0
  75. package/dist/orm/index.bun.js.map +1 -0
  76. package/dist/orm/index.d.ts +1228 -1216
  77. package/dist/orm/index.d.ts.map +1 -1
  78. package/dist/orm/index.js +2041 -1967
  79. package/dist/orm/index.js.map +1 -1
  80. package/dist/queue/core/index.d.ts +248 -248
  81. package/dist/queue/core/index.d.ts.map +1 -1
  82. package/dist/queue/redis/index.d.ts.map +1 -1
  83. package/dist/redis/index.bun.js +285 -0
  84. package/dist/redis/index.bun.js.map +1 -0
  85. package/dist/redis/index.d.ts +118 -136
  86. package/dist/redis/index.d.ts.map +1 -1
  87. package/dist/redis/index.js +18 -38
  88. package/dist/redis/index.js.map +1 -1
  89. package/dist/retry/index.d.ts +69 -69
  90. package/dist/retry/index.d.ts.map +1 -1
  91. package/dist/router/index.d.ts +6 -6
  92. package/dist/router/index.d.ts.map +1 -1
  93. package/dist/scheduler/index.d.ts +25 -25
  94. package/dist/scheduler/index.d.ts.map +1 -1
  95. package/dist/security/index.browser.js +5 -1
  96. package/dist/security/index.browser.js.map +1 -1
  97. package/dist/security/index.d.ts +417 -254
  98. package/dist/security/index.d.ts.map +1 -1
  99. package/dist/security/index.js +386 -86
  100. package/dist/security/index.js.map +1 -1
  101. package/dist/server/auth/index.d.ts +110 -110
  102. package/dist/server/auth/index.d.ts.map +1 -1
  103. package/dist/server/auth/index.js +20 -20
  104. package/dist/server/auth/index.js.map +1 -1
  105. package/dist/server/cache/index.d.ts +62 -47
  106. package/dist/server/cache/index.d.ts.map +1 -1
  107. package/dist/server/cache/index.js +56 -3
  108. package/dist/server/cache/index.js.map +1 -1
  109. package/dist/server/compress/index.d.ts +6 -0
  110. package/dist/server/compress/index.d.ts.map +1 -1
  111. package/dist/server/compress/index.js +36 -1
  112. package/dist/server/compress/index.js.map +1 -1
  113. package/dist/server/cookies/index.d.ts +6 -6
  114. package/dist/server/cookies/index.d.ts.map +1 -1
  115. package/dist/server/cookies/index.js +3 -3
  116. package/dist/server/cookies/index.js.map +1 -1
  117. package/dist/server/core/index.browser.js +2 -2
  118. package/dist/server/core/index.browser.js.map +1 -1
  119. package/dist/server/core/index.d.ts +242 -150
  120. package/dist/server/core/index.d.ts.map +1 -1
  121. package/dist/server/core/index.js +294 -125
  122. package/dist/server/core/index.js.map +1 -1
  123. package/dist/server/cors/index.d.ts +11 -12
  124. package/dist/server/cors/index.d.ts.map +1 -1
  125. package/dist/server/health/index.d.ts +0 -1
  126. package/dist/server/health/index.d.ts.map +1 -1
  127. package/dist/server/helmet/index.d.ts +2 -2
  128. package/dist/server/helmet/index.d.ts.map +1 -1
  129. package/dist/server/links/index.browser.js.map +1 -1
  130. package/dist/server/links/index.d.ts +123 -124
  131. package/dist/server/links/index.d.ts.map +1 -1
  132. package/dist/server/links/index.js +1 -2
  133. package/dist/server/links/index.js.map +1 -1
  134. package/dist/server/metrics/index.d.ts.map +1 -1
  135. package/dist/server/multipart/index.d.ts +6 -6
  136. package/dist/server/multipart/index.d.ts.map +1 -1
  137. package/dist/server/proxy/index.d.ts +102 -103
  138. package/dist/server/proxy/index.d.ts.map +1 -1
  139. package/dist/server/rate-limit/index.d.ts +16 -16
  140. package/dist/server/rate-limit/index.d.ts.map +1 -1
  141. package/dist/server/static/index.d.ts +44 -44
  142. package/dist/server/static/index.d.ts.map +1 -1
  143. package/dist/server/static/index.js +4 -0
  144. package/dist/server/static/index.js.map +1 -1
  145. package/dist/server/swagger/index.d.ts +48 -49
  146. package/dist/server/swagger/index.d.ts.map +1 -1
  147. package/dist/server/swagger/index.js +3 -5
  148. package/dist/server/swagger/index.js.map +1 -1
  149. package/dist/sms/index.d.ts +13 -11
  150. package/dist/sms/index.d.ts.map +1 -1
  151. package/dist/sms/index.js +7 -7
  152. package/dist/sms/index.js.map +1 -1
  153. package/dist/thread/index.d.ts +71 -72
  154. package/dist/thread/index.d.ts.map +1 -1
  155. package/dist/topic/core/index.d.ts +318 -318
  156. package/dist/topic/core/index.d.ts.map +1 -1
  157. package/dist/topic/redis/index.d.ts +6 -6
  158. package/dist/topic/redis/index.d.ts.map +1 -1
  159. package/dist/vite/index.d.ts +5805 -249
  160. package/dist/vite/index.d.ts.map +1 -1
  161. package/dist/vite/index.js +599 -513
  162. package/dist/vite/index.js.map +1 -1
  163. package/dist/websocket/index.browser.js +6 -6
  164. package/dist/websocket/index.browser.js.map +1 -1
  165. package/dist/websocket/index.d.ts +247 -247
  166. package/dist/websocket/index.d.ts.map +1 -1
  167. package/dist/websocket/index.js +6 -6
  168. package/dist/websocket/index.js.map +1 -1
  169. package/package.json +9 -14
  170. package/src/api/files/controllers/AdminFileStatsController.ts +0 -1
  171. package/src/api/users/atoms/realmAuthSettingsAtom.ts +5 -0
  172. package/src/api/users/controllers/{UserRealmController.ts → RealmController.ts} +11 -11
  173. package/src/api/users/entities/users.ts +1 -1
  174. package/src/api/users/index.ts +8 -8
  175. package/src/api/users/primitives/{$userRealm.ts → $realm.ts} +17 -19
  176. package/src/api/users/providers/{UserRealmProvider.ts → RealmProvider.ts} +26 -30
  177. package/src/api/users/schemas/{userRealmConfigSchema.ts → realmConfigSchema.ts} +2 -2
  178. package/src/api/users/services/CredentialService.ts +7 -7
  179. package/src/api/users/services/IdentityService.ts +4 -4
  180. package/src/api/users/services/RegistrationService.spec.ts +25 -27
  181. package/src/api/users/services/RegistrationService.ts +38 -27
  182. package/src/api/users/services/SessionCrudService.ts +3 -3
  183. package/src/api/users/services/SessionService.spec.ts +3 -3
  184. package/src/api/users/services/SessionService.ts +28 -9
  185. package/src/api/users/services/UserService.ts +7 -7
  186. package/src/batch/providers/BatchProvider.ts +1 -2
  187. package/src/cli/apps/AlephaCli.ts +0 -2
  188. package/src/cli/apps/AlephaPackageBuilderCli.ts +38 -19
  189. package/src/cli/assets/apiHelloControllerTs.ts +18 -0
  190. package/src/cli/assets/apiIndexTs.ts +16 -0
  191. package/src/cli/assets/claudeMd.ts +303 -0
  192. package/src/cli/assets/mainBrowserTs.ts +2 -2
  193. package/src/cli/assets/mainServerTs.ts +24 -0
  194. package/src/cli/assets/webAppRouterTs.ts +15 -0
  195. package/src/cli/assets/webHelloComponentTsx.ts +16 -0
  196. package/src/cli/assets/webIndexTs.ts +16 -0
  197. package/src/cli/atoms/buildOptions.ts +88 -0
  198. package/src/cli/commands/build.ts +70 -87
  199. package/src/cli/commands/db.ts +21 -22
  200. package/src/cli/commands/deploy.ts +17 -5
  201. package/src/cli/commands/dev.ts +22 -14
  202. package/src/cli/commands/format.ts +8 -2
  203. package/src/cli/commands/gen/env.ts +53 -0
  204. package/src/cli/commands/gen/openapi.ts +1 -1
  205. package/src/cli/commands/gen/resource.ts +15 -0
  206. package/src/cli/commands/gen.ts +7 -1
  207. package/src/cli/commands/init.ts +74 -30
  208. package/src/cli/commands/lint.ts +8 -2
  209. package/src/cli/commands/test.ts +8 -3
  210. package/src/cli/commands/typecheck.ts +5 -1
  211. package/src/cli/commands/verify.ts +5 -3
  212. package/src/cli/defineConfig.ts +49 -7
  213. package/src/cli/index.ts +0 -1
  214. package/src/cli/services/AlephaCliUtils.ts +39 -589
  215. package/src/cli/services/PackageManagerUtils.ts +301 -0
  216. package/src/cli/services/ProjectScaffolder.ts +306 -0
  217. package/src/command/helpers/Runner.spec.ts +2 -2
  218. package/src/command/helpers/Runner.ts +16 -4
  219. package/src/command/primitives/$command.ts +0 -6
  220. package/src/command/providers/CliProvider.ts +1 -3
  221. package/src/core/Alepha.ts +42 -0
  222. package/src/core/__tests__/Alepha-graph.spec.ts +4 -0
  223. package/src/core/index.shared.ts +1 -0
  224. package/src/core/index.ts +2 -0
  225. package/src/core/primitives/$hook.ts +6 -2
  226. package/src/core/primitives/$module.spec.ts +4 -0
  227. package/src/core/providers/AlsProvider.ts +1 -1
  228. package/src/core/providers/CodecManager.spec.ts +12 -6
  229. package/src/core/providers/CodecManager.ts +26 -6
  230. package/src/core/providers/EventManager.ts +169 -13
  231. package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +621 -0
  232. package/src/core/providers/KeylessJsonSchemaCodec.ts +407 -0
  233. package/src/core/providers/StateManager.spec.ts +27 -16
  234. package/src/email/providers/LocalEmailProvider.spec.ts +111 -87
  235. package/src/email/providers/LocalEmailProvider.ts +52 -15
  236. package/src/email/providers/NodemailerEmailProvider.ts +167 -56
  237. package/src/file/errors/FileError.ts +7 -0
  238. package/src/file/index.ts +9 -1
  239. package/src/file/providers/MemoryFileSystemProvider.ts +393 -0
  240. package/src/logger/index.ts +15 -3
  241. package/src/mcp/transports/StdioMcpTransport.ts +1 -1
  242. package/src/orm/index.browser.ts +1 -19
  243. package/src/orm/index.bun.ts +77 -0
  244. package/src/orm/index.shared-server.ts +22 -0
  245. package/src/orm/index.shared.ts +15 -0
  246. package/src/orm/index.ts +13 -39
  247. package/src/orm/providers/drivers/BunPostgresProvider.ts +3 -5
  248. package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -1
  249. package/src/orm/providers/drivers/CloudflareD1Provider.ts +4 -0
  250. package/src/orm/providers/drivers/DatabaseProvider.ts +4 -0
  251. package/src/orm/providers/drivers/PglitePostgresProvider.ts +4 -0
  252. package/src/orm/services/Repository.ts +8 -0
  253. package/src/queue/core/providers/WorkerProvider.spec.ts +48 -32
  254. package/src/redis/index.bun.ts +35 -0
  255. package/src/redis/providers/BunRedisProvider.ts +12 -43
  256. package/src/redis/providers/BunRedisSubscriberProvider.ts +2 -3
  257. package/src/redis/providers/NodeRedisProvider.ts +16 -34
  258. package/src/{server/security → security}/__tests__/BasicAuth.spec.ts +11 -11
  259. package/src/{server/security → security}/__tests__/ServerSecurityProvider-realm.spec.ts +21 -16
  260. package/src/{server/security/providers → security/__tests__}/ServerSecurityProvider.spec.ts +5 -5
  261. package/src/security/index.browser.ts +5 -0
  262. package/src/security/index.ts +90 -7
  263. package/src/security/primitives/{$realm.spec.ts → $issuer.spec.ts} +11 -11
  264. package/src/security/primitives/{$realm.ts → $issuer.ts} +20 -17
  265. package/src/security/primitives/$role.ts +5 -5
  266. package/src/security/primitives/$serviceAccount.spec.ts +5 -5
  267. package/src/security/primitives/$serviceAccount.ts +3 -3
  268. package/src/{server/security → security}/providers/ServerSecurityProvider.ts +5 -7
  269. package/src/server/auth/primitives/$auth.ts +10 -10
  270. package/src/server/auth/primitives/$authCredentials.ts +3 -3
  271. package/src/server/auth/primitives/$authGithub.ts +3 -3
  272. package/src/server/auth/primitives/$authGoogle.ts +3 -3
  273. package/src/server/auth/providers/ServerAuthProvider.ts +13 -13
  274. package/src/server/cache/providers/ServerCacheProvider.spec.ts +183 -0
  275. package/src/server/cache/providers/ServerCacheProvider.ts +95 -10
  276. package/src/server/compress/providers/ServerCompressProvider.ts +61 -2
  277. package/src/server/cookies/providers/ServerCookiesProvider.ts +3 -3
  278. package/src/server/core/helpers/ServerReply.ts +2 -2
  279. package/src/server/core/providers/NodeHttpServerProvider.ts +25 -6
  280. package/src/server/core/providers/ServerBodyParserProvider.ts +19 -23
  281. package/src/server/core/providers/ServerLoggerProvider.ts +23 -19
  282. package/src/server/core/providers/ServerProvider.ts +155 -22
  283. package/src/server/core/providers/ServerRouterProvider.ts +259 -115
  284. package/src/server/core/providers/ServerTimingProvider.ts +2 -2
  285. package/src/server/links/index.ts +1 -1
  286. package/src/server/links/providers/LinkProvider.ts +1 -1
  287. package/src/server/static/providers/ServerStaticProvider.ts +10 -0
  288. package/src/server/swagger/index.ts +1 -1
  289. package/src/server/swagger/providers/ServerSwaggerProvider.ts +5 -8
  290. package/src/sms/providers/LocalSmsProvider.spec.ts +153 -111
  291. package/src/sms/providers/LocalSmsProvider.ts +8 -7
  292. package/src/vite/helpers/boot.ts +28 -17
  293. package/src/vite/helpers/importViteReact.ts +13 -0
  294. package/src/vite/index.ts +1 -21
  295. package/src/vite/plugins/viteAlephaDev.ts +16 -1
  296. package/src/vite/plugins/viteAlephaSsrPreload.ts +222 -0
  297. package/src/vite/tasks/buildClient.ts +11 -0
  298. package/src/vite/tasks/buildServer.ts +59 -4
  299. package/src/vite/tasks/devServer.ts +71 -0
  300. package/src/vite/tasks/generateCloudflare.ts +7 -0
  301. package/src/vite/tasks/index.ts +2 -1
  302. package/dist/server/security/index.browser.js +0 -13
  303. package/dist/server/security/index.browser.js.map +0 -1
  304. package/dist/server/security/index.d.ts +0 -173
  305. package/dist/server/security/index.d.ts.map +0 -1
  306. package/dist/server/security/index.js +0 -311
  307. package/dist/server/security/index.js.map +0 -1
  308. package/src/cli/assets/appRouterTs.ts +0 -9
  309. package/src/cli/assets/mainTs.ts +0 -13
  310. package/src/cli/assets/viteConfigTs.ts +0 -14
  311. package/src/cli/commands/run.ts +0 -24
  312. package/src/server/security/index.browser.ts +0 -10
  313. package/src/server/security/index.ts +0 -94
  314. package/src/vite/plugins/viteAlepha.ts +0 -37
  315. package/src/vite/plugins/viteAlephaBuild.ts +0 -281
  316. /package/src/{server/security → security}/primitives/$basicAuth.ts +0 -0
  317. /package/src/{server/security → security}/providers/ServerBasicAuthProvider.ts +0 -0
@@ -0,0 +1,303 @@
1
+ export interface ClaudeMdOptions {
2
+ react?: boolean;
3
+ ui?: boolean;
4
+ projectName?: string;
5
+ }
6
+
7
+ export const claudeMd = (options: ClaudeMdOptions = {}) => {
8
+ const { react = false, projectName = "my-app" } = options;
9
+
10
+ const reactSection = react
11
+ ? `
12
+ ## React & Frontend
13
+
14
+ ### Pages with \`$page\`
15
+ \`\`\`tsx
16
+ import { $page } from "@alepha/react/router";
17
+ import { $client } from "alepha/server/links";
18
+ import type { UserController } from "./UserController.ts";
19
+
20
+ class AppRouter {
21
+ api = $client<UserController>();
22
+
23
+ users = $page({
24
+ path: "/users",
25
+ loader: async () => ({ users: await this.api.listUsers() }),
26
+ component: ({ users }) => (
27
+ <ul>{users.map(u => <li key={u.id}>{u.email}</li>)}</ul>
28
+ ),
29
+ });
30
+
31
+ userDetail = $page({
32
+ path: "/users/:id",
33
+ schema: { params: t.object({ id: t.uuid() }) },
34
+ loader: async ({ params }) => ({ user: await this.api.getUser({ params }) }),
35
+ lazy: () => import("./UserDetail.tsx"), // Code splitting
36
+ });
37
+ }
38
+ \`\`\`
39
+
40
+ ### React Hooks
41
+ \`\`\`typescript
42
+ import { useAlepha, useClient, useStore, useAction, useInject } from "@alepha/react";
43
+ import { useRouter, useActive } from "@alepha/react/router";
44
+ import { useForm } from "@alepha/react/form";
45
+ \`\`\`
46
+
47
+ - \`useClient<Controller>()\` - Type-safe API calls
48
+ - \`useStore(atom)\` - Global state (returns \`[value, setValue]\`)
49
+ - \`useAction({ handler })\` - Async operations with loading/error state
50
+ - \`useRouter<AppRouter>()\` - Type-safe navigation
51
+ - \`useForm({ schema, handler })\` - Type-safe forms with validation
52
+ `
53
+ : "";
54
+
55
+ const projectStructure = react
56
+ ? `
57
+ \`\`\`
58
+ ${projectName}/
59
+ ├── src/
60
+ │ ├── api/ # Backend
61
+ │ │ ├── controllers/ # API controllers with $action
62
+ │ │ ├── services/ # Business logic
63
+ │ │ ├── entities/ # Database entities with $entity
64
+ │ │ ├── providers/ # External service wrappers
65
+ │ │ └── index.ts # API module definition with $module
66
+ │ ├── web/ # Frontend (React only)
67
+ │ │ ├── components/ # React components
68
+ │ │ ├── atoms/ # State atoms with $atom
69
+ │ │ ├── AppRouter.ts # Routes with $page
70
+ │ │ └── index.ts # Web module definition with $module
71
+ │ ├── main.server.ts # Server entry
72
+ │ └── main.browser.ts # Browser entry (React only)
73
+ ├── index.html # (React only)
74
+ ├── package.json
75
+ └── tsconfig.json
76
+ \`\`\`
77
+ `
78
+ : `
79
+ \`\`\`
80
+ ${projectName}/
81
+ ├── src/
82
+ │ ├── api/ # Backend
83
+ │ │ ├── controllers/ # API controllers with $action
84
+ │ │ ├── services/ # Business logic
85
+ │ │ ├── entities/ # Database entities with $entity
86
+ │ │ ├── providers/ # External service wrappers
87
+ │ │ └── index.ts # API module definition with $module
88
+ │ └── main.server.ts # Server entry (always use main.server.ts)
89
+ ├── package.json
90
+ └── tsconfig.json
91
+ \`\`\`
92
+ `;
93
+
94
+ return `# CLAUDE.md
95
+
96
+ This file provides guidance to Claude Code when working with this Alepha project.
97
+
98
+ ## Overview
99
+
100
+ This is an **Alepha** project - a convention-driven TypeScript framework for type-safe full-stack applications.
101
+
102
+ **Key Concepts:**
103
+ - **Primitives**: Features defined with \`$\`-prefixed functions (\`$action\`, \`$entity\`, \`$page\`)
104
+ - **Class-Based**: Services are classes, primitives are class properties
105
+ - **Zero-Config**: Code structure IS the configuration
106
+ - **End-to-End Types**: Types flow from database → API → ${react ? "React" : "client"}
107
+
108
+ ## Rules
109
+
110
+ - Use TypeScript strict mode
111
+ - Use Biome for formatting (\`alepha lint\`)
112
+ - Use Vitest for testing
113
+ - One file = one class
114
+ - Primitives are class properties (except \`$entity\`, \`$atom\`)
115
+ - No decorators, no Express/Fastify patterns
116
+ - No manual instantiation - use dependency injection
117
+ - Use \`protected\` instead of \`private\` for class members
118
+ - Import with file extensions: \`import { User } from "./User.ts"\`
119
+ - Use \`t\` from Alepha for schemas (not Zod)
120
+
121
+ ## Project Structure
122
+ ${projectStructure}
123
+ ## Core Primitives
124
+
125
+ ### API with \`$action\`
126
+ \`\`\`typescript
127
+ import { t } from "alepha";
128
+ import { $action } from "alepha/server";
129
+
130
+ class UserController {
131
+ getUser = $action({
132
+ path: "/users/:id", // → GET /api/users/:id
133
+ schema: {
134
+ params: t.object({ id: t.uuid() }),
135
+ response: t.object({ id: t.uuid(), email: t.email() }),
136
+ },
137
+ handler: async ({ params }) => this.userRepo.findById(params.id),
138
+ });
139
+
140
+ createUser = $action({
141
+ // POST inferred from body schema
142
+ schema: {
143
+ body: t.object({ email: t.email() }),
144
+ response: userEntity.schema,
145
+ },
146
+ handler: async ({ body }) => this.userRepo.create(body),
147
+ });
148
+ }
149
+ \`\`\`
150
+
151
+ ### Database with \`$entity\` and \`$repository\`
152
+ \`\`\`typescript
153
+ import { $entity, $repository, db } from "alepha/orm";
154
+
155
+ // Entity defined at module level (for drizzle-kit compatibility)
156
+ export const userEntity = $entity({
157
+ name: "users",
158
+ schema: t.object({
159
+ id: db.primaryKey(),
160
+ email: t.email(),
161
+ createdAt: db.createdAt(),
162
+ updatedAt: db.updatedAt(),
163
+ }),
164
+ indexes: [{ column: "email", unique: true }],
165
+ });
166
+
167
+ class UserService {
168
+ repo = $repository(userEntity);
169
+
170
+ async findById(id: string) {
171
+ return this.repo.findById(id);
172
+ }
173
+ }
174
+ \`\`\`
175
+
176
+ ### Dependency Injection
177
+ \`\`\`typescript
178
+ import { $inject } from "alepha";
179
+
180
+ class OrderService {
181
+ userService = $inject(UserService); // Within same module
182
+
183
+ async createOrder(userId: string) {
184
+ const user = await this.userService.findById(userId);
185
+ // ...
186
+ }
187
+ }
188
+
189
+ // Cross-module: use $client instead of $inject
190
+ class AppRouter {
191
+ api = $client<OrderController>(); // Type-safe HTTP client
192
+ }
193
+ \`\`\`
194
+
195
+ ### Modules with \`$module\`
196
+ \`\`\`typescript
197
+ // src/api/index.ts - Groups all API services
198
+ import { $module } from "alepha";
199
+
200
+ export const ApiModule = $module({
201
+ name: "app.api",
202
+ services: [
203
+ UserController,
204
+ OrderController,
205
+ UserService,
206
+ ],
207
+ });
208
+
209
+ // src/web/index.ts - Groups all web services (React only)
210
+ export const WebModule = $module({
211
+ name: "app.web",
212
+ services: [AppRouter, Toaster],
213
+ register(alepha) {
214
+ // Optional: configure additional services
215
+ alepha.with(SomeLibrary);
216
+ },
217
+ });
218
+ \`\`\`
219
+
220
+ ### Environment Variables
221
+ \`\`\`typescript
222
+ import { $env, t } from "alepha";
223
+
224
+ class AppConfig {
225
+ env = $env(t.object({
226
+ DATABASE_URL: t.string(),
227
+ API_KEY: t.optional(t.string()),
228
+ }));
229
+ }
230
+ \`\`\`
231
+ ${reactSection}
232
+ ## Quick Reference
233
+
234
+ | Primitive | Import | Purpose |
235
+ |-----------|--------|---------|
236
+ | \`$inject\` | \`alepha\` | Dependency injection |
237
+ | \`$env\` | \`alepha\` | Environment variables |
238
+ | \`$hook\` | \`alepha\` | Lifecycle hooks |
239
+ | \`$logger\` | \`alepha/logger\` | Structured logging |
240
+ | \`$action\` | \`alepha/server\` | REST API endpoints |
241
+ | \`$route\` | \`alepha/server\` | Low-level HTTP routes |
242
+ | \`$entity\` | \`alepha/orm\` | Database tables |
243
+ | \`$repository\` | \`alepha/orm\` | Type-safe data access |
244
+ | \`$queue\` | \`alepha/queue\` | Background jobs |
245
+ | \`$scheduler\` | \`alepha/scheduler\` | Cron tasks |
246
+ | \`$cache\` | \`alepha/cache\` | Cached computations |
247
+ | \`$bucket\` | \`alepha/bucket\` | File storage |
248
+ | \`$issuer\` | \`alepha/security\` | JWT tokens |
249
+ | \`$command\` | \`alepha/command\` | CLI commands |${react ? `
250
+ | \`$page\` | \`@alepha/react/router\` | React pages with SSR |
251
+ | \`$atom\` | \`alepha\` | Global state |` : ""}
252
+
253
+ ## Testing
254
+
255
+ \`\`\`typescript
256
+ import { describe, it, expect } from "vitest";
257
+ import { Alepha } from "alepha";
258
+
259
+ describe("UserService", () => {
260
+ it("should create user", async () => {
261
+ const alepha = Alepha.create().with(UserService);
262
+ const service = alepha.inject(UserService);
263
+
264
+ const user = await service.create({ email: "test@example.com" });
265
+ expect(user.email).toBe("test@example.com");
266
+ });
267
+
268
+ it("should mock dependencies", async () => {
269
+ const alepha = Alepha.create()
270
+ .with(OrderService)
271
+ .with({ provide: PaymentGateway, use: MockPaymentGateway });
272
+
273
+ const service = alepha.inject(OrderService);
274
+ // PaymentGateway is now mocked
275
+ });
276
+ });
277
+ \`\`\`
278
+
279
+ ## Common Mistakes
280
+
281
+ 1. **DON'T use decorators** - Use primitives (\`$action\`, not \`@Get()\`)
282
+ 2. **DON'T use Zod** - Use TypeBox via \`t\` from Alepha
283
+ 3. **DON'T use Express patterns** - No \`app.get()\`, \`router.use()\`
284
+ 4. **DON'T inject across modules** - Use \`$client\` for cross-module calls
285
+ 5. **DON'T use async constructors** - Use \`$hook({ on: "start" })\`
286
+ 6. **DON'T instantiate manually** - Let DI container manage instances
287
+
288
+ ## After Code Changes
289
+
290
+ Always run:
291
+ \`\`\`bash
292
+ alepha lint # Format and lint
293
+ alepha typecheck # Type checking
294
+ alepha test # Run tests (if applicable)
295
+ alepha build # Build the project
296
+ \`\`\`
297
+
298
+ ## Documentation
299
+
300
+ - Full docs: https://alepha.dev/llms.txt
301
+ - Detailed docs: https://alepha.dev/llms-full.txt
302
+ `.trim();
303
+ };
@@ -1,10 +1,10 @@
1
1
  export const mainBrowserTs = () => `
2
2
  import { Alepha, run } from "alepha";
3
- import { AppRouter } from "./AppRouter.ts";
3
+ import { WebModule } from "./web/index.ts";
4
4
 
5
5
  const alepha = Alepha.create();
6
6
 
7
- alepha.with(AppRouter);
7
+ alepha.with(WebModule);
8
8
 
9
9
  run(alepha);
10
10
  `.trim();
@@ -0,0 +1,24 @@
1
+ export interface MainServerTsOptions {
2
+ react?: boolean;
3
+ }
4
+
5
+ export const mainServerTs = (options: MainServerTsOptions = {}) => {
6
+ const { react = false } = options;
7
+
8
+ const webImport = react
9
+ ? `import { WebModule } from "./web/index.ts";\n`
10
+ : "";
11
+
12
+ const webWith = react ? `alepha.with(WebModule);\n` : "";
13
+
14
+ return `
15
+ import { Alepha, run } from "alepha";
16
+ import { ApiModule } from "./api/index.ts";
17
+ ${webImport}
18
+ const alepha = Alepha.create();
19
+
20
+ alepha.with(ApiModule);
21
+ ${webWith}
22
+ run(alepha);
23
+ `.trim();
24
+ };
@@ -0,0 +1,15 @@
1
+ export const webAppRouterTs = () => `
2
+ import { $page } from "@alepha/react/router";
3
+ import { $client } from "alepha/server/links";
4
+ import type { HelloController } from "../api/controllers/HelloController.ts";
5
+
6
+ export class AppRouter {
7
+ api = $client<HelloController>();
8
+
9
+ home = $page({
10
+ path: "/",
11
+ lazy: () => import("./components/Hello.tsx"),
12
+ loader: () => this.api.hello(),
13
+ });
14
+ }
15
+ `.trim();
@@ -0,0 +1,16 @@
1
+ export const webHelloComponentTsx = () => `
2
+ interface Props {
3
+ message: string;
4
+ }
5
+
6
+ const Hello = (props: Props) => {
7
+ return (
8
+ <div>
9
+ <h1>{props.message}</h1>
10
+ <p>Edit this component in src/web/components/Hello.tsx</p>
11
+ </div>
12
+ );
13
+ };
14
+
15
+ export default Hello;
16
+ `.trim();
@@ -0,0 +1,16 @@
1
+ export interface WebIndexTsOptions {
2
+ appName?: string;
3
+ }
4
+
5
+ export const webIndexTs = (options: WebIndexTsOptions = {}) => {
6
+ const { appName = "app" } = options;
7
+ return `
8
+ import { $module } from "alepha";
9
+ import { AppRouter } from "./AppRouter.ts";
10
+
11
+ export const WebModule = $module({
12
+ name: "${appName}.web",
13
+ services: [AppRouter],
14
+ });
15
+ `.trim();
16
+ };
@@ -0,0 +1,88 @@
1
+ import { type Static, t } from "alepha";
2
+ import { $atom } from "../../core/primitives/$atom.ts";
3
+
4
+ /**
5
+ * Build options atom for CLI build command.
6
+ *
7
+ * Defines the available build configuration options with their defaults.
8
+ * Options can be overridden via vite.config.ts or CLI flags.
9
+ */
10
+ export const buildOptions = $atom({
11
+ name: "alepha.build.options",
12
+ description: "Build configuration options",
13
+ schema: t.object({
14
+ /**
15
+ * Generate build stats report.
16
+ */
17
+ stats: t.optional(t.boolean({ default: false })),
18
+
19
+ /**
20
+ * Vercel deployment configuration.
21
+ */
22
+ vercel: t.optional(
23
+ t.object({
24
+ projectName: t.optional(t.string()),
25
+ orgId: t.optional(t.string()),
26
+ projectId: t.optional(t.string()),
27
+ config: t.optional(
28
+ t.object({
29
+ crons: t.optional(
30
+ t.array(
31
+ t.object({
32
+ path: t.string(),
33
+ schedule: t.string(),
34
+ }),
35
+ ),
36
+ ),
37
+ }),
38
+ ),
39
+ }),
40
+ ),
41
+
42
+ /**
43
+ * Cloudflare Workers deployment configuration.
44
+ */
45
+ cloudflare: t.optional(
46
+ t.object({
47
+ config: t.optional(t.json()),
48
+ }),
49
+ ),
50
+
51
+ /**
52
+ * Docker deployment configuration.
53
+ */
54
+ docker: t.optional(
55
+ t.object({
56
+ /**
57
+ * Docker image name to use in the Dockerfile.
58
+ * @default "node:24-alpine"
59
+ */
60
+ image: t.optional(t.string({ default: "node:24-alpine" })),
61
+
62
+ /**
63
+ * Command to run in the Docker container.
64
+ * @default "node"
65
+ */
66
+ command: t.optional(t.string({ default: "node" })),
67
+ }),
68
+ ),
69
+
70
+ /**
71
+ * Sitemap generation configuration.
72
+ */
73
+ sitemap: t.optional(
74
+ t.object({
75
+ /**
76
+ * Base URL for sitemap entries.
77
+ */
78
+ hostname: t.string(),
79
+ }),
80
+ ),
81
+ }),
82
+ default: {},
83
+ });
84
+
85
+ /**
86
+ * Type for build options.
87
+ */
88
+ export type BuildOptions = Static<typeof buildOptions.schema>;