alepha 0.15.0 → 0.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (551) hide show
  1. package/README.md +43 -98
  2. package/dist/api/audits/index.d.ts +630 -653
  3. package/dist/api/audits/index.d.ts.map +1 -1
  4. package/dist/api/audits/index.js +12 -35
  5. package/dist/api/audits/index.js.map +1 -1
  6. package/dist/api/files/index.d.ts +365 -358
  7. package/dist/api/files/index.d.ts.map +1 -1
  8. package/dist/api/files/index.js +12 -5
  9. package/dist/api/files/index.js.map +1 -1
  10. package/dist/api/jobs/index.d.ts +255 -248
  11. package/dist/api/jobs/index.d.ts.map +1 -1
  12. package/dist/api/jobs/index.js +10 -3
  13. package/dist/api/jobs/index.js.map +1 -1
  14. package/dist/api/keys/index.d.ts +413 -0
  15. package/dist/api/keys/index.d.ts.map +1 -0
  16. package/dist/api/keys/index.js +476 -0
  17. package/dist/api/keys/index.js.map +1 -0
  18. package/dist/api/notifications/index.browser.js +4 -4
  19. package/dist/api/notifications/index.browser.js.map +1 -1
  20. package/dist/api/notifications/index.d.ts +84 -78
  21. package/dist/api/notifications/index.d.ts.map +1 -1
  22. package/dist/api/notifications/index.js +14 -8
  23. package/dist/api/notifications/index.js.map +1 -1
  24. package/dist/api/parameters/index.d.ts +528 -535
  25. package/dist/api/parameters/index.d.ts.map +1 -1
  26. package/dist/api/parameters/index.js +30 -37
  27. package/dist/api/parameters/index.js.map +1 -1
  28. package/dist/api/users/index.d.ts +1221 -910
  29. package/dist/api/users/index.d.ts.map +1 -1
  30. package/dist/api/users/index.js +2556 -248
  31. package/dist/api/users/index.js.map +1 -1
  32. package/dist/api/verifications/index.d.ts +142 -136
  33. package/dist/api/verifications/index.d.ts.map +1 -1
  34. package/dist/api/verifications/index.js +12 -4
  35. package/dist/api/verifications/index.js.map +1 -1
  36. package/dist/batch/index.d.ts +142 -162
  37. package/dist/batch/index.d.ts.map +1 -1
  38. package/dist/batch/index.js +31 -44
  39. package/dist/batch/index.js.map +1 -1
  40. package/dist/bucket/index.d.ts +595 -171
  41. package/dist/bucket/index.d.ts.map +1 -1
  42. package/dist/bucket/index.js +1856 -12
  43. package/dist/bucket/index.js.map +1 -1
  44. package/dist/cache/core/index.d.ts +225 -53
  45. package/dist/cache/core/index.d.ts.map +1 -1
  46. package/dist/cache/core/index.js +213 -7
  47. package/dist/cache/core/index.js.map +1 -1
  48. package/dist/cache/redis/index.d.ts +1 -0
  49. package/dist/cache/redis/index.d.ts.map +1 -1
  50. package/dist/cache/redis/index.js +6 -2
  51. package/dist/cache/redis/index.js.map +1 -1
  52. package/dist/cli/index.d.ts +834 -226
  53. package/dist/cli/index.d.ts.map +1 -1
  54. package/dist/cli/index.js +2872 -417
  55. package/dist/cli/index.js.map +1 -1
  56. package/dist/command/index.d.ts +458 -310
  57. package/dist/command/index.d.ts.map +1 -1
  58. package/dist/command/index.js +2011 -76
  59. package/dist/command/index.js.map +1 -1
  60. package/dist/core/index.browser.js +309 -97
  61. package/dist/core/index.browser.js.map +1 -1
  62. package/dist/core/index.d.ts +796 -701
  63. package/dist/core/index.d.ts.map +1 -1
  64. package/dist/core/index.js +329 -97
  65. package/dist/core/index.js.map +1 -1
  66. package/dist/core/index.native.js +309 -97
  67. package/dist/core/index.native.js.map +1 -1
  68. package/dist/datetime/index.d.ts +59 -44
  69. package/dist/datetime/index.d.ts.map +1 -1
  70. package/dist/datetime/index.js +15 -0
  71. package/dist/datetime/index.js.map +1 -1
  72. package/dist/email/index.d.ts +314 -19
  73. package/dist/email/index.d.ts.map +1 -1
  74. package/dist/email/index.js +1852 -7
  75. package/dist/email/index.js.map +1 -1
  76. package/dist/fake/index.d.ts +5500 -5418
  77. package/dist/fake/index.d.ts.map +1 -1
  78. package/dist/fake/index.js +113 -42
  79. package/dist/fake/index.js.map +1 -1
  80. package/dist/lock/core/index.d.ts +219 -212
  81. package/dist/lock/core/index.d.ts.map +1 -1
  82. package/dist/lock/core/index.js +11 -4
  83. package/dist/lock/core/index.js.map +1 -1
  84. package/dist/lock/redis/index.d.ts.map +1 -1
  85. package/dist/logger/index.d.ts +41 -90
  86. package/dist/logger/index.d.ts.map +1 -1
  87. package/dist/logger/index.js +15 -68
  88. package/dist/logger/index.js.map +1 -1
  89. package/dist/mcp/index.d.ts +228 -230
  90. package/dist/mcp/index.d.ts.map +1 -1
  91. package/dist/mcp/index.js +32 -31
  92. package/dist/mcp/index.js.map +1 -1
  93. package/dist/orm/index.browser.js +12 -12
  94. package/dist/orm/index.browser.js.map +1 -1
  95. package/dist/orm/index.bun.js +90 -80
  96. package/dist/orm/index.bun.js.map +1 -1
  97. package/dist/orm/index.d.ts +1434 -1459
  98. package/dist/orm/index.d.ts.map +1 -1
  99. package/dist/orm/index.js +112 -130
  100. package/dist/orm/index.js.map +1 -1
  101. package/dist/queue/core/index.d.ts +262 -254
  102. package/dist/queue/core/index.d.ts.map +1 -1
  103. package/dist/queue/core/index.js +14 -6
  104. package/dist/queue/core/index.js.map +1 -1
  105. package/dist/queue/redis/index.d.ts.map +1 -1
  106. package/dist/react/auth/index.browser.js +108 -0
  107. package/dist/react/auth/index.browser.js.map +1 -0
  108. package/dist/react/auth/index.d.ts +100 -0
  109. package/dist/react/auth/index.d.ts.map +1 -0
  110. package/dist/react/auth/index.js +145 -0
  111. package/dist/react/auth/index.js.map +1 -0
  112. package/dist/react/core/index.d.ts +469 -0
  113. package/dist/react/core/index.d.ts.map +1 -0
  114. package/dist/react/core/index.js +464 -0
  115. package/dist/react/core/index.js.map +1 -0
  116. package/dist/react/form/index.d.ts +232 -0
  117. package/dist/react/form/index.d.ts.map +1 -0
  118. package/dist/react/form/index.js +432 -0
  119. package/dist/react/form/index.js.map +1 -0
  120. package/dist/react/head/index.browser.js +423 -0
  121. package/dist/react/head/index.browser.js.map +1 -0
  122. package/dist/react/head/index.d.ts +288 -0
  123. package/dist/react/head/index.d.ts.map +1 -0
  124. package/dist/react/head/index.js +465 -0
  125. package/dist/react/head/index.js.map +1 -0
  126. package/dist/react/i18n/index.d.ts +175 -0
  127. package/dist/react/i18n/index.d.ts.map +1 -0
  128. package/dist/react/i18n/index.js +224 -0
  129. package/dist/react/i18n/index.js.map +1 -0
  130. package/dist/react/router/index.browser.js +1980 -0
  131. package/dist/react/router/index.browser.js.map +1 -0
  132. package/dist/react/router/index.d.ts +2068 -0
  133. package/dist/react/router/index.d.ts.map +1 -0
  134. package/dist/react/router/index.js +4932 -0
  135. package/dist/react/router/index.js.map +1 -0
  136. package/dist/react/websocket/index.d.ts +117 -0
  137. package/dist/react/websocket/index.d.ts.map +1 -0
  138. package/dist/react/websocket/index.js +107 -0
  139. package/dist/react/websocket/index.js.map +1 -0
  140. package/dist/redis/index.bun.js +4 -0
  141. package/dist/redis/index.bun.js.map +1 -1
  142. package/dist/redis/index.d.ts +127 -130
  143. package/dist/redis/index.d.ts.map +1 -1
  144. package/dist/redis/index.js +16 -25
  145. package/dist/redis/index.js.map +1 -1
  146. package/dist/retry/index.d.ts +80 -71
  147. package/dist/retry/index.d.ts.map +1 -1
  148. package/dist/retry/index.js +11 -2
  149. package/dist/retry/index.js.map +1 -1
  150. package/dist/router/index.d.ts +6 -6
  151. package/dist/router/index.d.ts.map +1 -1
  152. package/dist/scheduler/index.d.ts +119 -28
  153. package/dist/scheduler/index.d.ts.map +1 -1
  154. package/dist/scheduler/index.js +404 -3
  155. package/dist/scheduler/index.js.map +1 -1
  156. package/dist/security/index.d.ts +642 -228
  157. package/dist/security/index.d.ts.map +1 -1
  158. package/dist/security/index.js +1579 -37
  159. package/dist/security/index.js.map +1 -1
  160. package/dist/server/auth/index.d.ts +1141 -111
  161. package/dist/server/auth/index.d.ts.map +1 -1
  162. package/dist/server/auth/index.js +1261 -25
  163. package/dist/server/auth/index.js.map +1 -1
  164. package/dist/server/cache/index.d.ts +63 -78
  165. package/dist/server/cache/index.d.ts.map +1 -1
  166. package/dist/server/cache/index.js +7 -22
  167. package/dist/server/cache/index.js.map +1 -1
  168. package/dist/server/compress/index.d.ts +13 -5
  169. package/dist/server/compress/index.d.ts.map +1 -1
  170. package/dist/server/compress/index.js +10 -2
  171. package/dist/server/compress/index.js.map +1 -1
  172. package/dist/server/cookies/index.d.ts +46 -22
  173. package/dist/server/cookies/index.d.ts.map +1 -1
  174. package/dist/server/cookies/index.js +7 -5
  175. package/dist/server/cookies/index.js.map +1 -1
  176. package/dist/server/core/index.d.ts +307 -196
  177. package/dist/server/core/index.d.ts.map +1 -1
  178. package/dist/server/core/index.js +271 -38
  179. package/dist/server/core/index.js.map +1 -1
  180. package/dist/server/cors/index.d.ts +24 -34
  181. package/dist/server/cors/index.d.ts.map +1 -1
  182. package/dist/server/cors/index.js +7 -21
  183. package/dist/server/cors/index.js.map +1 -1
  184. package/dist/server/health/index.d.ts +25 -19
  185. package/dist/server/health/index.d.ts.map +1 -1
  186. package/dist/server/health/index.js +8 -2
  187. package/dist/server/health/index.js.map +1 -1
  188. package/dist/server/helmet/index.d.ts +13 -5
  189. package/dist/server/helmet/index.d.ts.map +1 -1
  190. package/dist/server/helmet/index.js +11 -3
  191. package/dist/server/helmet/index.js.map +1 -1
  192. package/dist/server/links/index.browser.js +9 -1
  193. package/dist/server/links/index.browser.js.map +1 -1
  194. package/dist/server/links/index.d.ts +133 -128
  195. package/dist/server/links/index.d.ts.map +1 -1
  196. package/dist/server/links/index.js +24 -11
  197. package/dist/server/links/index.js.map +1 -1
  198. package/dist/server/metrics/index.d.ts +524 -4
  199. package/dist/server/metrics/index.d.ts.map +1 -1
  200. package/dist/server/metrics/index.js +4472 -7
  201. package/dist/server/metrics/index.js.map +1 -1
  202. package/dist/server/multipart/index.d.ts +15 -9
  203. package/dist/server/multipart/index.d.ts.map +1 -1
  204. package/dist/server/multipart/index.js +9 -3
  205. package/dist/server/multipart/index.js.map +1 -1
  206. package/dist/server/proxy/index.d.ts +110 -104
  207. package/dist/server/proxy/index.d.ts.map +1 -1
  208. package/dist/server/proxy/index.js +8 -2
  209. package/dist/server/proxy/index.js.map +1 -1
  210. package/dist/server/rate-limit/index.d.ts +46 -51
  211. package/dist/server/rate-limit/index.d.ts.map +1 -1
  212. package/dist/server/rate-limit/index.js +18 -55
  213. package/dist/server/rate-limit/index.js.map +1 -1
  214. package/dist/server/static/index.d.ts +181 -48
  215. package/dist/server/static/index.d.ts.map +1 -1
  216. package/dist/server/static/index.js +1848 -5
  217. package/dist/server/static/index.js.map +1 -1
  218. package/dist/server/swagger/index.d.ts +348 -53
  219. package/dist/server/swagger/index.d.ts.map +1 -1
  220. package/dist/server/swagger/index.js +1849 -6
  221. package/dist/server/swagger/index.js.map +1 -1
  222. package/dist/sms/index.d.ts +312 -18
  223. package/dist/sms/index.d.ts.map +1 -1
  224. package/dist/sms/index.js +1854 -10
  225. package/dist/sms/index.js.map +1 -1
  226. package/dist/system/index.browser.js +496 -0
  227. package/dist/system/index.browser.js.map +1 -0
  228. package/dist/system/index.d.ts +1158 -0
  229. package/dist/system/index.d.ts.map +1 -0
  230. package/dist/{file → system}/index.js +412 -20
  231. package/dist/system/index.js.map +1 -0
  232. package/dist/thread/index.d.ts +82 -73
  233. package/dist/thread/index.d.ts.map +1 -1
  234. package/dist/thread/index.js +13 -4
  235. package/dist/thread/index.js.map +1 -1
  236. package/dist/topic/core/index.d.ts +330 -323
  237. package/dist/topic/core/index.d.ts.map +1 -1
  238. package/dist/topic/core/index.js +12 -5
  239. package/dist/topic/core/index.js.map +1 -1
  240. package/dist/topic/redis/index.d.ts +6 -6
  241. package/dist/topic/redis/index.d.ts.map +1 -1
  242. package/dist/vite/index.d.ts +163 -5825
  243. package/dist/vite/index.d.ts.map +1 -1
  244. package/dist/vite/index.js +130 -477
  245. package/dist/vite/index.js.map +1 -1
  246. package/dist/websocket/index.browser.js +3 -3
  247. package/dist/websocket/index.browser.js.map +1 -1
  248. package/dist/websocket/index.d.ts +287 -283
  249. package/dist/websocket/index.d.ts.map +1 -1
  250. package/dist/websocket/index.js +15 -11
  251. package/dist/websocket/index.js.map +1 -1
  252. package/package.json +86 -17
  253. package/src/api/audits/index.ts +10 -33
  254. package/src/api/files/__tests__/$bucket.spec.ts +1 -1
  255. package/src/api/files/controllers/AdminFileStatsController.spec.ts +1 -1
  256. package/src/api/files/controllers/FileController.spec.ts +1 -1
  257. package/src/api/files/index.ts +10 -3
  258. package/src/api/files/jobs/FileJobs.spec.ts +1 -1
  259. package/src/api/files/services/FileService.spec.ts +1 -1
  260. package/src/api/jobs/index.ts +10 -3
  261. package/src/api/keys/controllers/AdminApiKeyController.ts +75 -0
  262. package/src/api/keys/controllers/ApiKeyController.ts +103 -0
  263. package/src/api/keys/entities/apiKeyEntity.ts +41 -0
  264. package/src/api/keys/index.ts +49 -0
  265. package/src/api/keys/schemas/adminApiKeyQuerySchema.ts +7 -0
  266. package/src/api/keys/schemas/adminApiKeyResourceSchema.ts +17 -0
  267. package/src/api/keys/schemas/createApiKeyBodySchema.ts +7 -0
  268. package/src/api/keys/schemas/createApiKeyResponseSchema.ts +11 -0
  269. package/src/api/keys/schemas/listApiKeyResponseSchema.ts +15 -0
  270. package/src/api/keys/schemas/revokeApiKeyParamsSchema.ts +5 -0
  271. package/src/api/keys/schemas/revokeApiKeyResponseSchema.ts +5 -0
  272. package/src/api/keys/services/ApiKeyService.spec.ts +553 -0
  273. package/src/api/keys/services/ApiKeyService.ts +306 -0
  274. package/src/api/logs/TODO.md +52 -0
  275. package/src/api/notifications/index.ts +10 -4
  276. package/src/api/parameters/index.ts +9 -30
  277. package/src/api/parameters/primitives/$config.ts +12 -4
  278. package/src/api/parameters/services/ConfigStore.ts +9 -3
  279. package/src/api/users/__tests__/ApiKeys-integration.spec.ts +1035 -0
  280. package/src/api/users/__tests__/ApiKeys.spec.ts +401 -0
  281. package/src/api/users/index.ts +14 -3
  282. package/src/api/users/primitives/$realm.ts +33 -5
  283. package/src/api/users/providers/RealmProvider.ts +1 -12
  284. package/src/api/users/services/SessionService.ts +1 -11
  285. package/src/api/verifications/controllers/VerificationController.ts +2 -0
  286. package/src/api/verifications/index.ts +10 -4
  287. package/src/batch/index.ts +9 -36
  288. package/src/batch/primitives/$batch.ts +0 -8
  289. package/src/batch/providers/BatchProvider.ts +29 -2
  290. package/src/bucket/__tests__/shared.ts +1 -1
  291. package/src/bucket/index.ts +13 -6
  292. package/src/bucket/primitives/$bucket.ts +1 -1
  293. package/src/bucket/providers/LocalFileStorageProvider.ts +1 -1
  294. package/src/bucket/providers/MemoryFileStorageProvider.ts +1 -1
  295. package/src/cache/core/__tests__/shared.ts +30 -0
  296. package/src/cache/core/index.ts +11 -6
  297. package/src/cache/core/primitives/$cache.spec.ts +5 -0
  298. package/src/cache/core/providers/CacheProvider.ts +17 -0
  299. package/src/cache/core/providers/MemoryCacheProvider.ts +300 -1
  300. package/src/cache/redis/__tests__/cache-redis.spec.ts +5 -0
  301. package/src/cache/redis/providers/RedisCacheProvider.ts +9 -0
  302. package/src/cli/apps/AlephaCli.ts +3 -16
  303. package/src/cli/apps/AlephaPackageBuilderCli.ts +10 -2
  304. package/src/cli/atoms/appEntryOptions.ts +13 -0
  305. package/src/cli/atoms/buildOptions.ts +1 -1
  306. package/src/cli/atoms/changelogOptions.ts +1 -1
  307. package/src/cli/commands/build.ts +64 -52
  308. package/src/cli/commands/db.ts +17 -11
  309. package/src/cli/commands/deploy.ts +1 -1
  310. package/src/cli/commands/dev.ts +13 -49
  311. package/src/cli/commands/gen/env.ts +6 -3
  312. package/src/cli/commands/gen/openapi.ts +5 -2
  313. package/src/cli/commands/init.spec.ts +544 -0
  314. package/src/cli/commands/init.ts +101 -58
  315. package/src/cli/commands/lint.ts +8 -2
  316. package/src/cli/commands/typecheck.ts +11 -0
  317. package/src/cli/defineConfig.ts +9 -0
  318. package/src/cli/index.ts +2 -1
  319. package/src/cli/providers/AppEntryProvider.ts +131 -0
  320. package/src/cli/providers/ViteBuildProvider.ts +40 -0
  321. package/src/cli/providers/ViteDevServerProvider.ts +378 -0
  322. package/src/cli/services/AlephaCliUtils.ts +39 -93
  323. package/src/cli/services/PackageManagerUtils.ts +140 -17
  324. package/src/cli/services/ProjectScaffolder.ts +169 -101
  325. package/src/cli/services/ViteUtils.ts +82 -0
  326. package/src/cli/{assets/claudeMd.ts → templates/agentMd.ts} +41 -28
  327. package/src/cli/{assets → templates}/apiHelloControllerTs.ts +2 -1
  328. package/src/cli/{assets → templates}/biomeJson.ts +2 -1
  329. package/src/cli/{assets → templates}/dummySpecTs.ts +2 -1
  330. package/src/cli/{assets → templates}/editorconfig.ts +2 -1
  331. package/src/cli/templates/gitignore.ts +39 -0
  332. package/src/cli/{assets → templates}/mainBrowserTs.ts +2 -1
  333. package/src/cli/templates/mainCss.ts +33 -0
  334. package/src/cli/templates/mainServerTs.ts +33 -0
  335. package/src/cli/{assets → templates}/tsconfigJson.ts +2 -1
  336. package/src/cli/templates/webAppRouterTs.ts +50 -0
  337. package/src/cli/templates/webHelloComponentTsx.ts +20 -0
  338. package/src/command/helpers/Runner.spec.ts +4 -0
  339. package/src/command/helpers/Runner.ts +3 -21
  340. package/src/command/index.ts +12 -4
  341. package/src/command/providers/CliProvider.spec.ts +1067 -0
  342. package/src/command/providers/CliProvider.ts +203 -40
  343. package/src/core/Alepha.ts +3 -9
  344. package/src/core/__tests__/Alepha-start.spec.ts +4 -4
  345. package/src/core/helpers/jsonSchemaToTypeBox.spec.ts +771 -0
  346. package/src/core/helpers/jsonSchemaToTypeBox.ts +62 -10
  347. package/src/core/index.shared.ts +1 -0
  348. package/src/core/index.ts +20 -0
  349. package/src/core/primitives/$module.ts +12 -0
  350. package/src/core/providers/EventManager.spec.ts +0 -71
  351. package/src/core/providers/EventManager.ts +3 -15
  352. package/src/core/providers/Json.ts +2 -14
  353. package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +257 -0
  354. package/src/core/providers/KeylessJsonSchemaCodec.ts +396 -14
  355. package/src/core/providers/SchemaValidator.spec.ts +236 -0
  356. package/src/datetime/index.ts +15 -0
  357. package/src/email/index.ts +10 -5
  358. package/src/email/providers/LocalEmailProvider.spec.ts +1 -1
  359. package/src/email/providers/LocalEmailProvider.ts +1 -1
  360. package/src/fake/__tests__/keyName.example.ts +1 -1
  361. package/src/fake/__tests__/keyName.spec.ts +5 -5
  362. package/src/fake/index.ts +9 -6
  363. package/src/fake/providers/FakeProvider.spec.ts +258 -40
  364. package/src/fake/providers/FakeProvider.ts +133 -19
  365. package/src/lock/core/index.ts +11 -4
  366. package/src/logger/index.ts +17 -66
  367. package/src/logger/providers/PrettyFormatterProvider.ts +0 -9
  368. package/src/mcp/errors/McpError.ts +30 -0
  369. package/src/mcp/index.ts +13 -27
  370. package/src/mcp/transports/SseMcpTransport.ts +6 -7
  371. package/src/orm/__tests__/PostgresProvider.spec.ts +2 -2
  372. package/src/orm/index.browser.ts +2 -2
  373. package/src/orm/index.bun.ts +4 -2
  374. package/src/orm/index.ts +21 -47
  375. package/src/orm/providers/DrizzleKitProvider.ts +3 -5
  376. package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -0
  377. package/src/orm/services/Repository.ts +18 -3
  378. package/src/queue/core/index.ts +14 -6
  379. package/src/react/auth/__tests__/$auth.spec.ts +202 -0
  380. package/src/react/auth/hooks/useAuth.ts +32 -0
  381. package/src/react/auth/index.browser.ts +13 -0
  382. package/src/react/auth/index.shared.ts +2 -0
  383. package/src/react/auth/index.ts +48 -0
  384. package/src/react/auth/providers/ReactAuthProvider.ts +16 -0
  385. package/src/react/auth/services/ReactAuth.ts +135 -0
  386. package/src/react/core/__tests__/Router.spec.tsx +169 -0
  387. package/src/react/core/components/ClientOnly.tsx +49 -0
  388. package/src/react/core/components/ErrorBoundary.tsx +73 -0
  389. package/src/react/core/contexts/AlephaContext.ts +7 -0
  390. package/src/react/core/contexts/AlephaProvider.tsx +42 -0
  391. package/src/react/core/hooks/useAction.browser.spec.tsx +569 -0
  392. package/src/react/core/hooks/useAction.ts +480 -0
  393. package/src/react/core/hooks/useAlepha.ts +26 -0
  394. package/src/react/core/hooks/useClient.ts +17 -0
  395. package/src/react/core/hooks/useEvents.ts +51 -0
  396. package/src/react/core/hooks/useInject.ts +12 -0
  397. package/src/react/core/hooks/useStore.ts +52 -0
  398. package/src/react/core/index.ts +90 -0
  399. package/src/react/form/components/FormState.tsx +17 -0
  400. package/src/react/form/errors/FormValidationError.ts +18 -0
  401. package/src/react/form/hooks/useForm.browser.spec.tsx +366 -0
  402. package/src/react/form/hooks/useForm.ts +47 -0
  403. package/src/react/form/hooks/useFormState.ts +130 -0
  404. package/src/react/form/index.ts +44 -0
  405. package/src/react/form/services/FormModel.ts +614 -0
  406. package/src/react/head/helpers/SeoExpander.spec.ts +203 -0
  407. package/src/react/head/helpers/SeoExpander.ts +142 -0
  408. package/src/react/head/hooks/useHead.spec.tsx +288 -0
  409. package/src/react/head/hooks/useHead.ts +62 -0
  410. package/src/react/head/index.browser.ts +26 -0
  411. package/src/react/head/index.ts +44 -0
  412. package/src/react/head/interfaces/Head.ts +105 -0
  413. package/src/react/head/primitives/$head.ts +25 -0
  414. package/src/react/head/providers/BrowserHeadProvider.browser.spec.ts +196 -0
  415. package/src/react/head/providers/BrowserHeadProvider.ts +212 -0
  416. package/src/react/head/providers/HeadProvider.ts +168 -0
  417. package/src/react/head/providers/ServerHeadProvider.ts +31 -0
  418. package/src/react/i18n/__tests__/integration.spec.tsx +239 -0
  419. package/src/react/i18n/components/Localize.spec.tsx +357 -0
  420. package/src/react/i18n/components/Localize.tsx +35 -0
  421. package/src/react/i18n/hooks/useI18n.browser.spec.tsx +438 -0
  422. package/src/react/i18n/hooks/useI18n.ts +18 -0
  423. package/src/react/i18n/index.ts +41 -0
  424. package/src/react/i18n/primitives/$dictionary.ts +69 -0
  425. package/src/react/i18n/providers/I18nProvider.spec.ts +389 -0
  426. package/src/react/i18n/providers/I18nProvider.ts +278 -0
  427. package/src/react/router/__tests__/page-head-browser.browser.spec.ts +95 -0
  428. package/src/react/router/__tests__/page-head.spec.ts +48 -0
  429. package/src/react/router/__tests__/seo-head.spec.ts +125 -0
  430. package/src/react/router/atoms/ssrManifestAtom.ts +58 -0
  431. package/src/react/router/components/ErrorViewer.tsx +872 -0
  432. package/src/react/router/components/Link.tsx +23 -0
  433. package/src/react/router/components/NestedView.tsx +223 -0
  434. package/src/react/router/components/NotFound.tsx +30 -0
  435. package/src/react/router/constants/PAGE_PRELOAD_KEY.ts +6 -0
  436. package/src/react/router/contexts/RouterLayerContext.ts +12 -0
  437. package/src/react/router/errors/Redirection.ts +28 -0
  438. package/src/react/router/hooks/useActive.ts +52 -0
  439. package/src/react/router/hooks/useQueryParams.ts +63 -0
  440. package/src/react/router/hooks/useRouter.ts +20 -0
  441. package/src/react/router/hooks/useRouterState.ts +11 -0
  442. package/src/react/router/index.browser.ts +45 -0
  443. package/src/react/router/index.shared.ts +19 -0
  444. package/src/react/router/index.ts +142 -0
  445. package/src/react/router/primitives/$page.browser.spec.tsx +851 -0
  446. package/src/react/router/primitives/$page.spec.tsx +708 -0
  447. package/src/react/router/primitives/$page.ts +497 -0
  448. package/src/react/router/providers/ReactBrowserProvider.ts +309 -0
  449. package/src/react/router/providers/ReactBrowserRendererProvider.ts +25 -0
  450. package/src/react/router/providers/ReactBrowserRouterProvider.ts +168 -0
  451. package/src/react/router/providers/ReactPageProvider.ts +726 -0
  452. package/src/react/router/providers/ReactServerProvider.spec.tsx +316 -0
  453. package/src/react/router/providers/ReactServerProvider.ts +558 -0
  454. package/src/react/router/providers/ReactServerTemplateProvider.ts +979 -0
  455. package/src/react/router/providers/SSRManifestProvider.ts +334 -0
  456. package/src/react/router/services/ReactPageServerService.ts +48 -0
  457. package/src/react/router/services/ReactPageService.ts +27 -0
  458. package/src/react/router/services/ReactRouter.ts +262 -0
  459. package/src/react/websocket/hooks/useRoom.tsx +242 -0
  460. package/src/react/websocket/index.ts +7 -0
  461. package/src/redis/__tests__/redis.spec.ts +13 -0
  462. package/src/redis/index.ts +9 -25
  463. package/src/redis/providers/BunRedisProvider.ts +9 -0
  464. package/src/redis/providers/NodeRedisProvider.ts +8 -0
  465. package/src/redis/providers/RedisProvider.ts +16 -0
  466. package/src/retry/index.ts +11 -2
  467. package/src/router/index.ts +15 -0
  468. package/src/scheduler/index.ts +11 -2
  469. package/src/security/__tests__/BasicAuth.spec.ts +2 -0
  470. package/src/security/__tests__/ServerSecurityProvider.spec.ts +13 -5
  471. package/src/security/index.ts +15 -10
  472. package/src/security/interfaces/IssuerResolver.ts +27 -0
  473. package/src/security/primitives/$issuer.ts +55 -0
  474. package/src/security/providers/SecurityProvider.ts +179 -0
  475. package/src/security/providers/ServerBasicAuthProvider.ts +6 -2
  476. package/src/security/providers/ServerSecurityProvider.ts +36 -22
  477. package/src/server/auth/index.ts +12 -7
  478. package/src/server/cache/index.ts +7 -22
  479. package/src/server/compress/index.ts +10 -2
  480. package/src/server/cookies/index.ts +7 -5
  481. package/src/server/cookies/primitives/$cookie.ts +33 -11
  482. package/src/server/core/index.ts +17 -7
  483. package/src/server/core/interfaces/ServerRequest.ts +83 -1
  484. package/src/server/core/primitives/$action.spec.ts +1 -1
  485. package/src/server/core/primitives/$action.ts +8 -3
  486. package/src/server/core/providers/BunHttpServerProvider.ts +1 -1
  487. package/src/server/core/providers/NodeHttpServerProvider.spec.ts +125 -0
  488. package/src/server/core/providers/NodeHttpServerProvider.ts +77 -22
  489. package/src/server/core/providers/ServerLoggerProvider.ts +2 -2
  490. package/src/server/core/providers/ServerProvider.ts +9 -12
  491. package/src/server/core/services/ServerRequestParser.spec.ts +520 -0
  492. package/src/server/core/services/ServerRequestParser.ts +306 -13
  493. package/src/server/cors/index.ts +7 -21
  494. package/src/server/cors/primitives/$cors.ts +6 -2
  495. package/src/server/health/index.ts +8 -2
  496. package/src/server/helmet/index.ts +11 -3
  497. package/src/server/links/atoms/apiLinksAtom.ts +7 -0
  498. package/src/server/links/index.browser.ts +2 -0
  499. package/src/server/links/index.ts +13 -6
  500. package/src/server/metrics/index.ts +10 -3
  501. package/src/server/multipart/index.ts +9 -3
  502. package/src/server/proxy/index.ts +8 -2
  503. package/src/server/rate-limit/index.ts +21 -25
  504. package/src/server/rate-limit/primitives/$rateLimit.ts +6 -2
  505. package/src/server/rate-limit/providers/ServerRateLimitProvider.spec.ts +38 -14
  506. package/src/server/rate-limit/providers/ServerRateLimitProvider.ts +22 -56
  507. package/src/server/static/index.ts +8 -2
  508. package/src/server/static/providers/ServerStaticProvider.ts +1 -1
  509. package/src/server/swagger/index.ts +9 -4
  510. package/src/server/swagger/providers/ServerSwaggerProvider.ts +1 -1
  511. package/src/sms/index.ts +9 -5
  512. package/src/sms/providers/LocalSmsProvider.spec.ts +1 -1
  513. package/src/sms/providers/LocalSmsProvider.ts +1 -1
  514. package/src/system/index.browser.ts +11 -0
  515. package/src/system/index.ts +62 -0
  516. package/src/{file → system}/providers/FileSystemProvider.ts +16 -0
  517. package/src/{file → system}/providers/MemoryFileSystemProvider.ts +116 -3
  518. package/src/system/providers/MemoryShellProvider.ts +164 -0
  519. package/src/{file → system}/providers/NodeFileSystemProvider.spec.ts +2 -2
  520. package/src/{file → system}/providers/NodeFileSystemProvider.ts +36 -0
  521. package/src/system/providers/NodeShellProvider.ts +184 -0
  522. package/src/system/providers/ShellProvider.ts +74 -0
  523. package/src/{file → system}/services/FileDetector.spec.ts +2 -2
  524. package/src/thread/index.ts +11 -2
  525. package/src/topic/core/index.ts +12 -5
  526. package/src/vite/index.ts +3 -2
  527. package/src/vite/tasks/buildClient.ts +2 -8
  528. package/src/vite/tasks/buildServer.ts +84 -21
  529. package/src/vite/tasks/copyAssets.ts +5 -4
  530. package/src/vite/tasks/generateSitemap.ts +64 -23
  531. package/src/vite/tasks/index.ts +0 -2
  532. package/src/vite/tasks/prerenderPages.ts +49 -24
  533. package/src/websocket/index.ts +12 -8
  534. package/dist/file/index.d.ts +0 -839
  535. package/dist/file/index.d.ts.map +0 -1
  536. package/dist/file/index.js.map +0 -1
  537. package/src/cli/assets/indexHtml.ts +0 -15
  538. package/src/cli/assets/mainServerTs.ts +0 -24
  539. package/src/cli/assets/webAppRouterTs.ts +0 -15
  540. package/src/cli/assets/webHelloComponentTsx.ts +0 -16
  541. package/src/cli/commands/format.ts +0 -23
  542. package/src/file/index.ts +0 -43
  543. package/src/vite/helpers/boot.ts +0 -117
  544. package/src/vite/plugins/viteAlephaDev.ts +0 -177
  545. package/src/vite/tasks/devServer.ts +0 -71
  546. package/src/vite/tasks/runAlepha.ts +0 -270
  547. /package/dist/orm/{chunk-DtkW-qnP.js → chunk-DH6iiROE.js} +0 -0
  548. /package/src/cli/{assets → templates}/apiIndexTs.ts +0 -0
  549. /package/src/cli/{assets → templates}/webIndexTs.ts +0 -0
  550. /package/src/{file → system}/errors/FileError.ts +0 -0
  551. /package/src/{file → system}/services/FileDetector.ts +0 -0
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "alepha",
3
3
  "description": "Easy-to-use modern TypeScript framework for building many kind of applications.",
4
4
  "author": "Nicolas Foures",
5
- "version": "0.15.0",
5
+ "version": "0.15.2",
6
6
  "type": "module",
7
7
  "engines": {
8
8
  "node": ">=22.0.0"
@@ -19,30 +19,51 @@
19
19
  ],
20
20
  "dependencies": {
21
21
  "@redis/client": "^5.10.0",
22
- "cron-schedule": "^6.0.0",
22
+ "@vitejs/plugin-react": "^5.1.2",
23
23
  "dayjs": "^1.11.19",
24
24
  "drizzle-kit": "^0.31.8",
25
25
  "drizzle-orm": "^0.45.1",
26
- "jose": "^6.1.3",
27
- "nodemailer": "^7.0.12",
28
- "openid-client": "^6.8.1",
26
+ "nodemailer": "^7.0.13",
29
27
  "postgres": "^3.4.8",
30
- "prom-client": "^15.1.3",
31
28
  "tsx": "^4.21.0",
32
- "typebox": "^1.0.78",
29
+ "typebox": "^1.0.80",
30
+ "vite": "^7.3.1",
33
31
  "vite-bundle-analyzer": "^1.3.2",
34
32
  "ws": "^8.19.0"
35
33
  },
36
34
  "devDependencies": {
35
+ "@biomejs/biome": "^2.3.13",
37
36
  "@electric-sql/pglite": "^0.3.15",
38
37
  "@faker-js/faker": "^10.2.0",
39
- "@types/node": "^25.0.9",
40
- "@types/nodemailer": "^7.0.5",
38
+ "@testing-library/dom": "^10.4.1",
39
+ "@testing-library/react": "^16.3.2",
40
+ "@types/node": "^25.1.0",
41
+ "@types/nodemailer": "^7.0.9",
42
+ "@types/react": "^19.2.10",
43
+ "@types/react-dom": "^19.2.3",
41
44
  "@types/ws": "^8.18.1",
45
+ "cron-schedule": "^6.0.0",
46
+ "jose": "^6.1.3",
47
+ "jsdom": "^27.4.0",
48
+ "openid-client": "^6.8.1",
49
+ "prom-client": "^15.1.3",
50
+ "react": "^19.2.4",
51
+ "react-dom": "^19.2.4",
42
52
  "swagger-ui-dist": "^5.31.0",
43
- "tsdown": "^0.20.0-beta.3",
44
- "vite": "^7.3.1",
45
- "vitest": "^4.0.17"
53
+ "tsdown": "^0.20.1",
54
+ "vitest": "^4.0.18"
55
+ },
56
+ "peerDependencies": {
57
+ "react": "^19",
58
+ "react-dom": "^19"
59
+ },
60
+ "peerDependenciesMeta": {
61
+ "react": {
62
+ "optional": true
63
+ },
64
+ "react-dom": {
65
+ "optional": true
66
+ }
46
67
  },
47
68
  "scarfSettings": {
48
69
  "enabled": false
@@ -89,6 +110,11 @@
89
110
  "import": "./dist/api/jobs/index.js",
90
111
  "default": "./dist/api/jobs/index.js"
91
112
  },
113
+ "./api/keys": {
114
+ "types": "./dist/api/keys/index.d.ts",
115
+ "import": "./dist/api/keys/index.js",
116
+ "default": "./dist/api/keys/index.js"
117
+ },
92
118
  "./api/notifications": {
93
119
  "types": "./dist/api/notifications/index.d.ts",
94
120
  "react-native": "./dist/api/notifications/index.browser.js",
@@ -174,11 +200,6 @@
174
200
  "import": "./dist/fake/index.js",
175
201
  "default": "./dist/fake/index.js"
176
202
  },
177
- "./file": {
178
- "types": "./dist/file/index.d.ts",
179
- "import": "./dist/file/index.js",
180
- "default": "./dist/file/index.js"
181
- },
182
203
  "./lock": {
183
204
  "types": "./dist/lock/core/index.d.ts",
184
205
  "import": "./dist/lock/core/index.js",
@@ -217,6 +238,47 @@
217
238
  "import": "./dist/queue/redis/index.js",
218
239
  "default": "./dist/queue/redis/index.js"
219
240
  },
241
+ "./react/auth": {
242
+ "types": "./dist/react/auth/index.d.ts",
243
+ "react-native": "./dist/react/auth/index.browser.js",
244
+ "browser": "./dist/react/auth/index.browser.js",
245
+ "import": "./dist/react/auth/index.js",
246
+ "default": "./dist/react/auth/index.js"
247
+ },
248
+ "./react": {
249
+ "types": "./dist/react/core/index.d.ts",
250
+ "import": "./dist/react/core/index.js",
251
+ "default": "./dist/react/core/index.js"
252
+ },
253
+ "./react/form": {
254
+ "types": "./dist/react/form/index.d.ts",
255
+ "import": "./dist/react/form/index.js",
256
+ "default": "./dist/react/form/index.js"
257
+ },
258
+ "./react/head": {
259
+ "types": "./dist/react/head/index.d.ts",
260
+ "react-native": "./dist/react/head/index.browser.js",
261
+ "browser": "./dist/react/head/index.browser.js",
262
+ "import": "./dist/react/head/index.js",
263
+ "default": "./dist/react/head/index.js"
264
+ },
265
+ "./react/i18n": {
266
+ "types": "./dist/react/i18n/index.d.ts",
267
+ "import": "./dist/react/i18n/index.js",
268
+ "default": "./dist/react/i18n/index.js"
269
+ },
270
+ "./react/router": {
271
+ "types": "./dist/react/router/index.d.ts",
272
+ "react-native": "./dist/react/router/index.browser.js",
273
+ "browser": "./dist/react/router/index.browser.js",
274
+ "import": "./dist/react/router/index.js",
275
+ "default": "./dist/react/router/index.js"
276
+ },
277
+ "./react/websocket": {
278
+ "types": "./dist/react/websocket/index.d.ts",
279
+ "import": "./dist/react/websocket/index.js",
280
+ "default": "./dist/react/websocket/index.js"
281
+ },
220
282
  "./redis": {
221
283
  "types": "./dist/redis/index.d.ts",
222
284
  "bun": "./src/redis/index.bun.ts",
@@ -333,6 +395,13 @@
333
395
  "import": "./dist/sms/index.js",
334
396
  "default": "./dist/sms/index.js"
335
397
  },
398
+ "./system": {
399
+ "types": "./dist/system/index.d.ts",
400
+ "react-native": "./dist/system/index.browser.js",
401
+ "browser": "./dist/system/index.browser.js",
402
+ "import": "./dist/system/index.js",
403
+ "default": "./dist/system/index.js"
404
+ },
336
405
  "./thread": {
337
406
  "types": "./dist/thread/index.d.ts",
338
407
  "import": "./dist/thread/index.js",
@@ -15,42 +15,19 @@ export * from "./services/AuditService.ts";
15
15
  // ---------------------------------------------------------------------------------------------------------------------
16
16
 
17
17
  /**
18
- * Provides audit logging API endpoints for Alepha applications.
18
+ * | type | quality | stability |
19
+ * |------|---------|-----------|
20
+ * | backend | standard | stable |
19
21
  *
20
- * This module includes:
21
- * - Audit log CRUD operations
22
- * - Filtering and searching audit events
23
- * - Audit statistics and analytics
24
- * - `$audit` primitive for domain-specific audit types
22
+ * Audit trail for compliance.
25
23
  *
26
- * @module alepha.api.audits
27
- *
28
- * @example
29
- * ```ts
30
- * // In your app module
31
- * import { AlephaApiAudits } from "alepha/api/audits";
32
- *
33
- * const App = $module({
34
- * name: "app",
35
- * services: [AlephaApiAudits, ...],
36
- * });
24
+ * **Features:**
25
+ * - Domain-specific audit types
26
+ * - Audit event logging
27
+ * - Filtering and searching
28
+ * - User action tracking
37
29
  *
38
- * // Create domain-specific audit types
39
- * class PaymentAudits {
40
- * audit = $audit({
41
- * type: "payment",
42
- * actions: ["create", "refund", "cancel"],
43
- * });
44
- *
45
- * async onPaymentCreated(paymentId: string, userId: string) {
46
- * await this.audit.log("create", {
47
- * userId,
48
- * resourceType: "payment",
49
- * resourceId: paymentId,
50
- * });
51
- * }
52
- * }
53
- * ```
30
+ * @module alepha.api.audits
54
31
  */
55
32
  export const AlephaApiAudits = $module({
56
33
  name: "alepha.api.audits",
@@ -7,7 +7,7 @@ import {
7
7
  LocalFileStorageProvider,
8
8
  MemoryFileStorageProvider,
9
9
  } from "alepha/bucket";
10
- import { FileSystemProvider } from "alepha/file";
10
+ import { FileSystemProvider } from "alepha/system";
11
11
  import { describe, expect, it } from "vitest";
12
12
  import { AlephaApiFiles } from "../index.ts";
13
13
 
@@ -1,6 +1,6 @@
1
1
  import { Alepha } from "alepha";
2
2
  import { $bucket } from "alepha/bucket";
3
- import { FileSystemProvider } from "alepha/file";
3
+ import { FileSystemProvider } from "alepha/system";
4
4
  import { describe, expect, it } from "vitest";
5
5
  import { AdminFileStatsController, FileService } from "../index.ts";
6
6
 
@@ -1,7 +1,7 @@
1
1
  import { Alepha } from "alepha";
2
2
  import { $bucket } from "alepha/bucket";
3
3
  import { DateTimeProvider } from "alepha/datetime";
4
- import { FileSystemProvider } from "alepha/file";
4
+ import { FileSystemProvider } from "alepha/system";
5
5
  import { describe, expect, it } from "vitest";
6
6
  import { FileController, FileService } from "../index.ts";
7
7
 
@@ -49,10 +49,17 @@ declare module "alepha/bucket" {
49
49
  // ---------------------------------------------------------------------------------------------------------------------
50
50
 
51
51
  /**
52
- * Provides file management API endpoints for Alepha applications.
52
+ * | type | quality | stability |
53
+ * |------|---------|-----------|
54
+ * | backend | standard | stable |
53
55
  *
54
- * This module includes file upload, download, storage management,
55
- * and file metadata operations.
56
+ * File management endpoints.
57
+ *
58
+ * **Features:**
59
+ * - Upload/download endpoints
60
+ * - File metadata storage
61
+ * - TTL-based expiration
62
+ * - Storage statistics
56
63
  *
57
64
  * @module alepha.api.files
58
65
  */
@@ -1,6 +1,6 @@
1
1
  import { Alepha } from "alepha";
2
2
  import { DateTimeProvider } from "alepha/datetime";
3
- import { FileSystemProvider } from "alepha/file";
3
+ import { FileSystemProvider } from "alepha/system";
4
4
  import { describe, expect, it } from "vitest";
5
5
  import { FileJobs, FileService } from "../index.ts";
6
6
 
@@ -6,7 +6,7 @@ import {
6
6
  LocalFileStorageProvider,
7
7
  MemoryFileStorageProvider,
8
8
  } from "alepha/bucket";
9
- import { FileSystemProvider } from "alepha/file";
9
+ import { FileSystemProvider } from "alepha/system";
10
10
  import { describe, expect, it } from "vitest";
11
11
  import { AlephaApiFiles, FileController } from "../index.ts";
12
12
 
@@ -17,10 +17,17 @@ export * from "./services/JobService.ts";
17
17
  // ---------------------------------------------------------------------------------------------------------------------
18
18
 
19
19
  /**
20
- * Provides job management API endpoints for Alepha applications.
20
+ * | type | quality | stability |
21
+ * |------|---------|-----------|
22
+ * | backend | standard | stable |
21
23
  *
22
- * This module includes job queue operations, job status monitoring,
23
- * and background task management capabilities.
24
+ * Job execution monitoring.
25
+ *
26
+ * **Features:**
27
+ * - Job definitions for tracking
28
+ * - Job status tracking
29
+ * - Execution history
30
+ * - Retry management
24
31
  *
25
32
  * @module alepha.api.jobs
26
33
  */
@@ -0,0 +1,75 @@
1
+ import { $inject, t } from "alepha";
2
+ import { $action, okSchema } from "alepha/server";
3
+ import { adminApiKeyQuerySchema } from "../schemas/adminApiKeyQuerySchema.ts";
4
+ import { adminApiKeyResourceSchema } from "../schemas/adminApiKeyResourceSchema.ts";
5
+ import { ApiKeyService } from "../services/ApiKeyService.ts";
6
+
7
+ /**
8
+ * REST API controller for admin API key management.
9
+ * Admins can list, view, and revoke any API key.
10
+ */
11
+ export class AdminApiKeyController {
12
+ protected readonly url = "/admin/api-keys";
13
+ protected readonly group = "admin:api-keys";
14
+ protected readonly apiKeyService = $inject(ApiKeyService);
15
+
16
+ /**
17
+ * Find all API keys with optional filtering.
18
+ */
19
+ public readonly findApiKeys = $action({
20
+ path: this.url,
21
+ group: this.group,
22
+ secure: true,
23
+ description: "Find API keys with pagination and filtering",
24
+ schema: {
25
+ query: adminApiKeyQuerySchema,
26
+ response: t.page(adminApiKeyResourceSchema),
27
+ },
28
+ handler: ({ query }) => {
29
+ const { userId, includeRevoked, ...pagination } = query;
30
+ return this.apiKeyService.findAll({
31
+ userId,
32
+ includeRevoked,
33
+ ...pagination,
34
+ });
35
+ },
36
+ });
37
+
38
+ /**
39
+ * Get an API key by ID.
40
+ */
41
+ public readonly getApiKey = $action({
42
+ path: `${this.url}/:id`,
43
+ group: this.group,
44
+ secure: true,
45
+ description: "Get an API key by ID",
46
+ schema: {
47
+ params: t.object({
48
+ id: t.uuid(),
49
+ }),
50
+ response: adminApiKeyResourceSchema,
51
+ },
52
+ handler: ({ params }) => this.apiKeyService.getById(params.id),
53
+ });
54
+
55
+ /**
56
+ * Revoke any API key.
57
+ */
58
+ public readonly revokeApiKey = $action({
59
+ method: "DELETE",
60
+ path: `${this.url}/:id`,
61
+ group: this.group,
62
+ secure: true,
63
+ description: "Revoke an API key",
64
+ schema: {
65
+ params: t.object({
66
+ id: t.uuid(),
67
+ }),
68
+ response: okSchema,
69
+ },
70
+ handler: async ({ params }) => {
71
+ await this.apiKeyService.revokeByAdmin(params.id);
72
+ return { ok: true, id: params.id };
73
+ },
74
+ });
75
+ }
@@ -0,0 +1,103 @@
1
+ import { $inject } from "alepha";
2
+ import { $action } from "alepha/server";
3
+ import { createApiKeyBodySchema } from "../schemas/createApiKeyBodySchema.ts";
4
+ import { createApiKeyResponseSchema } from "../schemas/createApiKeyResponseSchema.ts";
5
+ import { listApiKeyResponseSchema } from "../schemas/listApiKeyResponseSchema.ts";
6
+ import { revokeApiKeyParamsSchema } from "../schemas/revokeApiKeyParamsSchema.ts";
7
+ import { revokeApiKeyResponseSchema } from "../schemas/revokeApiKeyResponseSchema.ts";
8
+ import { ApiKeyService } from "../services/ApiKeyService.ts";
9
+
10
+ /**
11
+ * REST API controller for user's own API key management.
12
+ * Users can create, list, and revoke their own API keys.
13
+ */
14
+ export class ApiKeyController {
15
+ protected readonly url = "/api-keys";
16
+ protected readonly group = "api-keys";
17
+ protected readonly apiKeyService = $inject(ApiKeyService);
18
+
19
+ /**
20
+ * Create a new API key for the authenticated user.
21
+ * The token is only returned once upon creation.
22
+ */
23
+ public readonly createApiKey = $action({
24
+ method: "POST",
25
+ path: this.url,
26
+ group: this.group,
27
+ description: "Create a new API key",
28
+ secure: true,
29
+ schema: {
30
+ body: createApiKeyBodySchema,
31
+ response: createApiKeyResponseSchema,
32
+ },
33
+ handler: async (request) => {
34
+ const { apiKey, token } = await this.apiKeyService.create({
35
+ userId: request.user.id,
36
+ name: request.body.name,
37
+ description: request.body.description,
38
+ roles: request.user.roles ?? [],
39
+ expiresAt: request.body.expiresAt
40
+ ? new Date(request.body.expiresAt)
41
+ : undefined,
42
+ });
43
+
44
+ return {
45
+ id: apiKey.id,
46
+ name: apiKey.name,
47
+ token,
48
+ tokenSuffix: apiKey.tokenSuffix,
49
+ roles: apiKey.roles,
50
+ createdAt: apiKey.createdAt,
51
+ expiresAt: apiKey.expiresAt,
52
+ };
53
+ },
54
+ });
55
+
56
+ /**
57
+ * List all active API keys for the authenticated user.
58
+ * Does not return the actual tokens.
59
+ */
60
+ public readonly listApiKeys = $action({
61
+ path: this.url,
62
+ group: this.group,
63
+ description: "List your API keys",
64
+ secure: true,
65
+ schema: {
66
+ response: listApiKeyResponseSchema,
67
+ },
68
+ handler: async (request) => {
69
+ const apiKeys = await this.apiKeyService.list(request.user.id);
70
+
71
+ return apiKeys.map((apiKey) => ({
72
+ id: apiKey.id,
73
+ name: apiKey.name,
74
+ tokenPrefix: apiKey.tokenPrefix,
75
+ tokenSuffix: apiKey.tokenSuffix,
76
+ roles: apiKey.roles,
77
+ createdAt: apiKey.createdAt,
78
+ lastUsedAt: apiKey.lastUsedAt,
79
+ expiresAt: apiKey.expiresAt,
80
+ usageCount: apiKey.usageCount,
81
+ }));
82
+ },
83
+ });
84
+
85
+ /**
86
+ * Revoke an API key. Only the owner can revoke their own keys.
87
+ */
88
+ public readonly revokeApiKey = $action({
89
+ method: "DELETE",
90
+ path: `${this.url}/:id`,
91
+ group: this.group,
92
+ description: "Revoke an API key",
93
+ secure: true,
94
+ schema: {
95
+ params: revokeApiKeyParamsSchema,
96
+ response: revokeApiKeyResponseSchema,
97
+ },
98
+ handler: async (request) => {
99
+ await this.apiKeyService.revoke(request.params.id, request.user.id);
100
+ return { ok: true };
101
+ },
102
+ });
103
+ }
@@ -0,0 +1,41 @@
1
+ import { type Static, t } from "alepha";
2
+ import { $entity, db } from "alepha/orm";
3
+
4
+ export const apiKeyEntity = $entity({
5
+ name: "api_keys",
6
+ schema: t.object({
7
+ id: db.primaryKey(t.uuid()),
8
+ createdAt: db.createdAt(),
9
+ updatedAt: db.updatedAt(),
10
+
11
+ // Owner
12
+ userId: t.uuid(),
13
+
14
+ // Key metadata
15
+ name: t.text({ maxLength: 100 }),
16
+ description: t.optional(t.text({ maxLength: 500 })),
17
+
18
+ // Token (hashed) - internal, not user input
19
+ tokenHash: t.string({ maxLength: 256 }),
20
+ tokenPrefix: t.string({ maxLength: 10 }),
21
+ tokenSuffix: t.string({ maxLength: 8 }),
22
+
23
+ // Roles (snapshot from user at creation)
24
+ roles: db.default(t.array(t.string()), []),
25
+
26
+ // Tracking
27
+ lastUsedAt: t.optional(t.datetime()),
28
+ lastUsedIp: t.optional(t.string({ maxLength: 45 })),
29
+ usageCount: db.default(t.integer(), 0),
30
+
31
+ // Lifecycle
32
+ expiresAt: t.optional(t.datetime()),
33
+ revokedAt: t.optional(t.datetime()),
34
+ }),
35
+ indexes: [
36
+ { columns: ["userId", "name"], unique: true },
37
+ { columns: ["tokenHash"], unique: true },
38
+ ],
39
+ });
40
+
41
+ export type ApiKeyEntity = Static<typeof apiKeyEntity.schema>;
@@ -0,0 +1,49 @@
1
+ import { $module } from "alepha";
2
+ import { AdminApiKeyController } from "./controllers/AdminApiKeyController.ts";
3
+ import { ApiKeyController } from "./controllers/ApiKeyController.ts";
4
+ import { ApiKeyService } from "./services/ApiKeyService.ts";
5
+
6
+ export * from "./controllers/AdminApiKeyController.ts";
7
+ export * from "./controllers/ApiKeyController.ts";
8
+ export * from "./entities/apiKeyEntity.ts";
9
+ export * from "./schemas/adminApiKeyQuerySchema.ts";
10
+ export * from "./schemas/adminApiKeyResourceSchema.ts";
11
+ export * from "./schemas/createApiKeyBodySchema.ts";
12
+ export * from "./schemas/createApiKeyResponseSchema.ts";
13
+ export * from "./schemas/listApiKeyResponseSchema.ts";
14
+ export * from "./schemas/revokeApiKeyParamsSchema.ts";
15
+ export * from "./schemas/revokeApiKeyResponseSchema.ts";
16
+ export * from "./services/ApiKeyService.ts";
17
+
18
+ /**
19
+ * | type | quality | stability |
20
+ * |------|---------|--------------|
21
+ * | backend | good | experimental |
22
+ *
23
+ * API key management module for programmatic access.
24
+ *
25
+ * **Features:**
26
+ * - Create API keys with role snapshots
27
+ * - List and revoke API keys
28
+ * - 15-minute validation caching
29
+ * - Query param (?api_key=) and Bearer header support
30
+ *
31
+ * **Integration:**
32
+ * To enable API key authentication for an issuer, register the resolver:
33
+ *
34
+ * ```ts
35
+ * class MyApp {
36
+ * apiKeyService = $inject(ApiKeyService);
37
+ * issuer = $issuer({
38
+ * secret: env.APP_SECRET,
39
+ * resolvers: [this.apiKeyService.createResolver()],
40
+ * });
41
+ * }
42
+ * ```
43
+ *
44
+ * @module alepha.api.keys
45
+ */
46
+ export const AlephaApiKeys = $module({
47
+ name: "alepha.api.keys",
48
+ services: [ApiKeyService, ApiKeyController, AdminApiKeyController],
49
+ });
@@ -0,0 +1,7 @@
1
+ import { t } from "alepha";
2
+ import { pageQuerySchema } from "alepha/orm";
3
+
4
+ export const adminApiKeyQuerySchema = t.extend(pageQuerySchema, {
5
+ userId: t.optional(t.uuid()),
6
+ includeRevoked: t.optional(t.boolean()),
7
+ });
@@ -0,0 +1,17 @@
1
+ import { t } from "alepha";
2
+
3
+ export const adminApiKeyResourceSchema = t.object({
4
+ id: t.uuid(),
5
+ userId: t.uuid(),
6
+ name: t.string(),
7
+ description: t.optional(t.string()),
8
+ tokenPrefix: t.string(),
9
+ tokenSuffix: t.string(),
10
+ roles: t.array(t.string()),
11
+ createdAt: t.datetime(),
12
+ lastUsedAt: t.optional(t.datetime()),
13
+ lastUsedIp: t.optional(t.string()),
14
+ expiresAt: t.optional(t.datetime()),
15
+ revokedAt: t.optional(t.datetime()),
16
+ usageCount: t.integer(),
17
+ });
@@ -0,0 +1,7 @@
1
+ import { t } from "alepha";
2
+
3
+ export const createApiKeyBodySchema = t.object({
4
+ name: t.text({ minLength: 1, maxLength: 100 }),
5
+ description: t.optional(t.text({ maxLength: 500 })),
6
+ expiresAt: t.optional(t.datetime()),
7
+ });
@@ -0,0 +1,11 @@
1
+ import { t } from "alepha";
2
+
3
+ export const createApiKeyResponseSchema = t.object({
4
+ id: t.uuid(),
5
+ name: t.string(),
6
+ token: t.string(),
7
+ tokenSuffix: t.string(),
8
+ roles: t.array(t.string()),
9
+ createdAt: t.datetime(),
10
+ expiresAt: t.optional(t.datetime()),
11
+ });
@@ -0,0 +1,15 @@
1
+ import { t } from "alepha";
2
+
3
+ export const listApiKeyItemSchema = t.object({
4
+ id: t.uuid(),
5
+ name: t.string(),
6
+ tokenPrefix: t.string(),
7
+ tokenSuffix: t.string(),
8
+ roles: t.array(t.string()),
9
+ createdAt: t.datetime(),
10
+ lastUsedAt: t.optional(t.datetime()),
11
+ expiresAt: t.optional(t.datetime()),
12
+ usageCount: t.integer(),
13
+ });
14
+
15
+ export const listApiKeyResponseSchema = t.array(listApiKeyItemSchema);
@@ -0,0 +1,5 @@
1
+ import { t } from "alepha";
2
+
3
+ export const revokeApiKeyParamsSchema = t.object({
4
+ id: t.uuid(),
5
+ });
@@ -0,0 +1,5 @@
1
+ import { t } from "alepha";
2
+
3
+ export const revokeApiKeyResponseSchema = t.object({
4
+ ok: t.boolean(),
5
+ });