alepha 0.14.2 → 0.14.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. package/dist/api/audits/index.browser.js +5 -5
  2. package/dist/api/audits/index.browser.js.map +1 -1
  3. package/dist/api/audits/index.d.ts +784 -784
  4. package/dist/api/audits/index.d.ts.map +1 -1
  5. package/dist/api/audits/index.js +13 -13
  6. package/dist/api/audits/index.js.map +1 -1
  7. package/dist/api/files/index.browser.js +5 -5
  8. package/dist/api/files/index.browser.js.map +1 -1
  9. package/dist/api/files/index.d.ts +57 -57
  10. package/dist/api/files/index.d.ts.map +1 -1
  11. package/dist/api/files/index.js +71 -71
  12. package/dist/api/files/index.js.map +1 -1
  13. package/dist/api/jobs/index.browser.js +5 -5
  14. package/dist/api/jobs/index.browser.js.map +1 -1
  15. package/dist/api/jobs/index.d.ts +165 -165
  16. package/dist/api/jobs/index.d.ts.map +1 -1
  17. package/dist/api/jobs/index.js +10 -10
  18. package/dist/api/jobs/index.js.map +1 -1
  19. package/dist/api/notifications/index.browser.js +10 -10
  20. package/dist/api/notifications/index.browser.js.map +1 -1
  21. package/dist/api/notifications/index.d.ts +583 -171
  22. package/dist/api/notifications/index.d.ts.map +1 -1
  23. package/dist/api/notifications/index.js +12 -12
  24. package/dist/api/notifications/index.js.map +1 -1
  25. package/dist/api/parameters/index.browser.js +163 -10
  26. package/dist/api/parameters/index.browser.js.map +1 -1
  27. package/dist/api/parameters/index.d.ts +281 -276
  28. package/dist/api/parameters/index.d.ts.map +1 -1
  29. package/dist/api/parameters/index.js +196 -91
  30. package/dist/api/parameters/index.js.map +1 -1
  31. package/dist/api/users/index.browser.js +19 -19
  32. package/dist/api/users/index.browser.js.map +1 -1
  33. package/dist/api/users/index.d.ts +1137 -1123
  34. package/dist/api/users/index.d.ts.map +1 -1
  35. package/dist/api/users/index.js +827 -596
  36. package/dist/api/users/index.js.map +1 -1
  37. package/dist/api/verifications/index.browser.js +6 -6
  38. package/dist/api/verifications/index.browser.js.map +1 -1
  39. package/dist/api/verifications/index.d.ts +13 -13
  40. package/dist/api/verifications/index.d.ts.map +1 -1
  41. package/dist/api/verifications/index.js +6 -6
  42. package/dist/api/verifications/index.js.map +1 -1
  43. package/dist/bin/index.d.ts +1 -2
  44. package/dist/bin/index.js +0 -1
  45. package/dist/bin/index.js.map +1 -1
  46. package/dist/cli/index.d.ts +137 -112
  47. package/dist/cli/index.d.ts.map +1 -1
  48. package/dist/cli/index.js +371 -259
  49. package/dist/cli/index.js.map +1 -1
  50. package/dist/command/index.d.ts +45 -5
  51. package/dist/command/index.d.ts.map +1 -1
  52. package/dist/command/index.js +97 -17
  53. package/dist/command/index.js.map +1 -1
  54. package/dist/core/index.browser.js +14 -18
  55. package/dist/core/index.browser.js.map +1 -1
  56. package/dist/core/index.d.ts +29 -0
  57. package/dist/core/index.d.ts.map +1 -1
  58. package/dist/core/index.js +14 -18
  59. package/dist/core/index.js.map +1 -1
  60. package/dist/core/index.native.js +14 -18
  61. package/dist/core/index.native.js.map +1 -1
  62. package/dist/fake/index.js +195 -168
  63. package/dist/fake/index.js.map +1 -1
  64. package/dist/file/index.d.ts +8 -0
  65. package/dist/file/index.d.ts.map +1 -1
  66. package/dist/file/index.js +3 -0
  67. package/dist/file/index.js.map +1 -1
  68. package/dist/mcp/index.d.ts.map +1 -1
  69. package/dist/orm/index.d.ts +32 -32
  70. package/dist/orm/index.d.ts.map +1 -1
  71. package/dist/orm/index.js +12 -12
  72. package/dist/orm/index.js.map +1 -1
  73. package/dist/security/index.d.ts +1 -1
  74. package/dist/security/index.d.ts.map +1 -1
  75. package/dist/security/index.js +1 -1
  76. package/dist/security/index.js.map +1 -1
  77. package/dist/server/auth/index.d.ts +171 -155
  78. package/dist/server/auth/index.d.ts.map +1 -1
  79. package/dist/server/auth/index.js +0 -1
  80. package/dist/server/auth/index.js.map +1 -1
  81. package/dist/server/compress/index.d.ts.map +1 -1
  82. package/dist/server/compress/index.js +2 -0
  83. package/dist/server/compress/index.js.map +1 -1
  84. package/dist/server/core/index.d.ts.map +1 -1
  85. package/dist/server/core/index.js +1 -1
  86. package/dist/server/core/index.js.map +1 -1
  87. package/dist/server/links/index.browser.js +22 -6
  88. package/dist/server/links/index.browser.js.map +1 -1
  89. package/dist/server/links/index.d.ts +46 -44
  90. package/dist/server/links/index.d.ts.map +1 -1
  91. package/dist/server/links/index.js +24 -41
  92. package/dist/server/links/index.js.map +1 -1
  93. package/dist/server/security/index.d.ts +9 -9
  94. package/dist/server/swagger/index.d.ts +2 -1
  95. package/dist/server/swagger/index.d.ts.map +1 -1
  96. package/dist/server/swagger/index.js +8 -3
  97. package/dist/server/swagger/index.js.map +1 -1
  98. package/dist/vite/index.d.ts.map +1 -1
  99. package/dist/vite/index.js +12 -4
  100. package/dist/vite/index.js.map +1 -1
  101. package/dist/websocket/index.d.ts +7 -7
  102. package/package.json +7 -7
  103. package/src/api/audits/controllers/{AuditController.ts → AdminAuditController.ts} +5 -6
  104. package/src/api/audits/entities/audits.ts +5 -5
  105. package/src/api/audits/index.browser.ts +1 -1
  106. package/src/api/audits/index.ts +3 -3
  107. package/src/api/audits/primitives/$audit.spec.ts +276 -0
  108. package/src/api/audits/services/AuditService.spec.ts +495 -0
  109. package/src/api/files/__tests__/$bucket.spec.ts +91 -0
  110. package/src/api/files/controllers/AdminFileStatsController.spec.ts +166 -0
  111. package/src/api/files/controllers/{StorageStatsController.ts → AdminFileStatsController.ts} +2 -2
  112. package/src/api/files/controllers/FileController.spec.ts +558 -0
  113. package/src/api/files/controllers/FileController.ts +4 -5
  114. package/src/api/files/entities/files.ts +5 -5
  115. package/src/api/files/index.browser.ts +1 -1
  116. package/src/api/files/index.ts +4 -4
  117. package/src/api/files/jobs/FileJobs.spec.ts +52 -0
  118. package/src/api/files/services/FileService.spec.ts +109 -0
  119. package/src/api/jobs/__tests__/JobController.spec.ts +343 -0
  120. package/src/api/jobs/controllers/{JobController.ts → AdminJobController.ts} +2 -2
  121. package/src/api/jobs/entities/jobExecutions.ts +5 -5
  122. package/src/api/jobs/index.ts +3 -3
  123. package/src/api/jobs/primitives/$job.spec.ts +476 -0
  124. package/src/api/notifications/controllers/{NotificationController.ts → AdminNotificationController.ts} +4 -5
  125. package/src/api/notifications/entities/notifications.ts +5 -5
  126. package/src/api/notifications/index.browser.ts +1 -1
  127. package/src/api/notifications/index.ts +4 -4
  128. package/src/api/parameters/controllers/{ConfigController.ts → AdminConfigController.ts} +46 -107
  129. package/src/api/parameters/entities/parameters.ts +7 -17
  130. package/src/api/parameters/index.ts +3 -3
  131. package/src/api/parameters/primitives/$config.spec.ts +356 -0
  132. package/src/api/parameters/schemas/activateConfigBodySchema.ts +12 -0
  133. package/src/api/parameters/schemas/checkScheduledResponseSchema.ts +8 -0
  134. package/src/api/parameters/schemas/configCurrentResponseSchema.ts +13 -0
  135. package/src/api/parameters/schemas/configHistoryResponseSchema.ts +9 -0
  136. package/src/api/parameters/schemas/configNameParamSchema.ts +10 -0
  137. package/src/api/parameters/schemas/configNamesResponseSchema.ts +8 -0
  138. package/src/api/parameters/schemas/configTreeNodeSchema.ts +13 -0
  139. package/src/api/parameters/schemas/configVersionParamSchema.ts +9 -0
  140. package/src/api/parameters/schemas/configVersionResponseSchema.ts +9 -0
  141. package/src/api/parameters/schemas/configsByStatusResponseSchema.ts +9 -0
  142. package/src/api/parameters/schemas/createConfigVersionBodySchema.ts +24 -0
  143. package/src/api/parameters/schemas/index.ts +15 -0
  144. package/src/api/parameters/schemas/parameterResponseSchema.ts +26 -0
  145. package/src/api/parameters/schemas/parameterStatusSchema.ts +13 -0
  146. package/src/api/parameters/schemas/rollbackConfigBodySchema.ts +15 -0
  147. package/src/api/parameters/schemas/statusParamSchema.ts +9 -0
  148. package/src/api/users/__tests__/EmailVerification.spec.ts +369 -0
  149. package/src/api/users/__tests__/PasswordReset.spec.ts +550 -0
  150. package/src/api/users/controllers/AdminIdentityController.spec.ts +365 -0
  151. package/src/api/users/controllers/{IdentityController.ts → AdminIdentityController.ts} +3 -4
  152. package/src/api/users/controllers/AdminSessionController.spec.ts +274 -0
  153. package/src/api/users/controllers/{SessionController.ts → AdminSessionController.ts} +3 -4
  154. package/src/api/users/controllers/AdminUserController.spec.ts +372 -0
  155. package/src/api/users/controllers/AdminUserController.ts +116 -0
  156. package/src/api/users/controllers/UserController.ts +4 -107
  157. package/src/api/users/controllers/UserRealmController.ts +3 -0
  158. package/src/api/users/entities/identities.ts +6 -6
  159. package/src/api/users/entities/sessions.ts +6 -6
  160. package/src/api/users/entities/users.ts +9 -9
  161. package/src/api/users/index.ts +9 -6
  162. package/src/api/users/primitives/$userRealm.ts +13 -8
  163. package/src/api/users/services/CredentialService.spec.ts +509 -0
  164. package/src/api/users/services/CredentialService.ts +46 -0
  165. package/src/api/users/services/IdentityService.ts +15 -0
  166. package/src/api/users/services/RegistrationService.spec.ts +630 -0
  167. package/src/api/users/services/RegistrationService.ts +18 -0
  168. package/src/api/users/services/SessionService.spec.ts +301 -0
  169. package/src/api/users/services/SessionService.ts +110 -1
  170. package/src/api/users/services/UserService.ts +67 -2
  171. package/src/api/verifications/__tests__/CodeVerification.spec.ts +318 -0
  172. package/src/api/verifications/__tests__/LinkVerification.spec.ts +279 -0
  173. package/src/api/verifications/entities/verifications.ts +6 -6
  174. package/src/api/verifications/jobs/VerificationJobs.spec.ts +50 -0
  175. package/src/batch/__tests__/startup-buffering.spec.ts +458 -0
  176. package/src/batch/primitives/$batch.spec.ts +766 -0
  177. package/src/batch/providers/BatchProvider.spec.ts +786 -0
  178. package/src/bin/index.ts +0 -1
  179. package/src/bucket/__tests__/shared.ts +194 -0
  180. package/src/bucket/primitives/$bucket.spec.ts +104 -0
  181. package/src/bucket/providers/FileStorageProvider.spec.ts +13 -0
  182. package/src/bucket/providers/LocalFileStorageProvider.spec.ts +77 -0
  183. package/src/bucket/providers/MemoryFileStorageProvider.spec.ts +82 -0
  184. package/src/cache/core/__tests__/shared.ts +377 -0
  185. package/src/cache/core/primitives/$cache.spec.ts +111 -0
  186. package/src/cache/redis/__tests__/cache-redis.spec.ts +70 -0
  187. package/src/cli/apps/AlephaCli.ts +25 -4
  188. package/src/cli/commands/dev.ts +19 -7
  189. package/src/cli/commands/gen/changelog.spec.ts +315 -0
  190. package/src/cli/commands/{changelog.ts → gen/changelog.ts} +9 -9
  191. package/src/cli/commands/gen/openapi.ts +71 -0
  192. package/src/cli/commands/gen.ts +18 -0
  193. package/src/cli/commands/init.ts +2 -0
  194. package/src/cli/commands/root.ts +12 -3
  195. package/src/cli/commands/typecheck.ts +5 -0
  196. package/src/cli/index.ts +2 -1
  197. package/src/cli/services/AlephaCliUtils.ts +71 -32
  198. package/src/cli/services/GitMessageParser.ts +1 -1
  199. package/src/command/helpers/Asker.spec.ts +127 -0
  200. package/src/command/helpers/Runner.spec.ts +126 -0
  201. package/src/command/primitives/$command.spec.ts +1588 -0
  202. package/src/command/providers/CliProvider.ts +74 -24
  203. package/src/core/Alepha.ts +45 -0
  204. package/src/core/__tests__/Alepha-emit.spec.ts +22 -0
  205. package/src/core/__tests__/Alepha-graph.spec.ts +93 -0
  206. package/src/core/__tests__/Alepha-has.spec.ts +41 -0
  207. package/src/core/__tests__/Alepha-inject.spec.ts +93 -0
  208. package/src/core/__tests__/Alepha-register.spec.ts +81 -0
  209. package/src/core/__tests__/Alepha-start.spec.ts +176 -0
  210. package/src/core/__tests__/Alepha-with.spec.ts +14 -0
  211. package/src/core/__tests__/TypeBox-usecases.spec.ts +35 -0
  212. package/src/core/__tests__/TypeBoxLocale.spec.ts +15 -0
  213. package/src/core/__tests__/descriptor.spec.ts +34 -0
  214. package/src/core/__tests__/fixtures/A.ts +5 -0
  215. package/src/core/__tests__/pagination.spec.ts +77 -0
  216. package/src/core/helpers/jsonSchemaToTypeBox.ts +2 -2
  217. package/src/core/primitives/$atom.spec.ts +43 -0
  218. package/src/core/primitives/$hook.spec.ts +130 -0
  219. package/src/core/primitives/$inject.spec.ts +175 -0
  220. package/src/core/primitives/$module.spec.ts +115 -0
  221. package/src/core/providers/CodecManager.spec.ts +740 -0
  222. package/src/core/providers/EventManager.spec.ts +762 -0
  223. package/src/core/providers/EventManager.ts +4 -0
  224. package/src/core/providers/StateManager.spec.ts +365 -0
  225. package/src/core/providers/TypeProvider.spec.ts +1607 -0
  226. package/src/core/providers/TypeProvider.ts +20 -26
  227. package/src/datetime/primitives/$interval.spec.ts +103 -0
  228. package/src/datetime/providers/DateTimeProvider.spec.ts +86 -0
  229. package/src/email/primitives/$email.spec.ts +175 -0
  230. package/src/email/providers/LocalEmailProvider.spec.ts +341 -0
  231. package/src/fake/__tests__/keyName.example.ts +40 -0
  232. package/src/fake/__tests__/keyName.spec.ts +152 -0
  233. package/src/fake/__tests__/module.example.ts +32 -0
  234. package/src/fake/providers/FakeProvider.spec.ts +438 -0
  235. package/src/file/providers/FileSystemProvider.ts +8 -0
  236. package/src/file/providers/NodeFileSystemProvider.spec.ts +418 -0
  237. package/src/file/providers/NodeFileSystemProvider.ts +5 -0
  238. package/src/file/services/FileDetector.spec.ts +591 -0
  239. package/src/lock/core/__tests__/shared.ts +190 -0
  240. package/src/lock/core/providers/MemoryLockProvider.spec.ts +25 -0
  241. package/src/lock/redis/providers/RedisLockProvider.spec.ts +25 -0
  242. package/src/logger/__tests__/SimpleFormatterProvider.spec.ts +109 -0
  243. package/src/logger/primitives/$logger.spec.ts +108 -0
  244. package/src/logger/services/Logger.spec.ts +295 -0
  245. package/src/mcp/__tests__/errors.spec.ts +175 -0
  246. package/src/mcp/__tests__/integration.spec.ts +450 -0
  247. package/src/mcp/helpers/jsonrpc.spec.ts +380 -0
  248. package/src/mcp/primitives/$prompt.spec.ts +468 -0
  249. package/src/mcp/primitives/$resource.spec.ts +390 -0
  250. package/src/mcp/primitives/$tool.spec.ts +406 -0
  251. package/src/mcp/providers/McpServerProvider.spec.ts +797 -0
  252. package/src/orm/__tests__/$repository-crud.spec.ts +276 -0
  253. package/src/orm/__tests__/$repository-hooks.spec.ts +325 -0
  254. package/src/orm/__tests__/$repository-orderBy.spec.ts +128 -0
  255. package/src/orm/__tests__/$repository-pagination-sort.spec.ts +149 -0
  256. package/src/orm/__tests__/$repository-save.spec.ts +37 -0
  257. package/src/orm/__tests__/ModelBuilder-integration.spec.ts +490 -0
  258. package/src/orm/__tests__/ModelBuilder-types.spec.ts +186 -0
  259. package/src/orm/__tests__/PostgresProvider.spec.ts +46 -0
  260. package/src/orm/__tests__/delete-returning.spec.ts +256 -0
  261. package/src/orm/__tests__/deletedAt.spec.ts +80 -0
  262. package/src/orm/__tests__/enums.spec.ts +315 -0
  263. package/src/orm/__tests__/execute.spec.ts +72 -0
  264. package/src/orm/__tests__/fixtures/bigEntitySchema.ts +65 -0
  265. package/src/orm/__tests__/fixtures/userEntitySchema.ts +27 -0
  266. package/src/orm/__tests__/joins.spec.ts +1114 -0
  267. package/src/orm/__tests__/page.spec.ts +287 -0
  268. package/src/orm/__tests__/primaryKey.spec.ts +87 -0
  269. package/src/orm/__tests__/query-date-encoding.spec.ts +402 -0
  270. package/src/orm/__tests__/ref-auto-onDelete.spec.ts +156 -0
  271. package/src/orm/__tests__/references.spec.ts +102 -0
  272. package/src/orm/__tests__/security.spec.ts +710 -0
  273. package/src/orm/__tests__/sqlite.spec.ts +111 -0
  274. package/src/orm/__tests__/string-operators.spec.ts +429 -0
  275. package/src/orm/__tests__/timestamps.spec.ts +388 -0
  276. package/src/orm/__tests__/validation.spec.ts +183 -0
  277. package/src/orm/__tests__/version.spec.ts +64 -0
  278. package/src/orm/helpers/parseQueryString.spec.ts +196 -0
  279. package/src/orm/primitives/$repository.spec.ts +137 -0
  280. package/src/orm/primitives/$sequence.spec.ts +29 -0
  281. package/src/orm/primitives/$transaction.spec.ts +82 -0
  282. package/src/orm/providers/drivers/BunPostgresProvider.ts +3 -3
  283. package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -1
  284. package/src/orm/providers/drivers/CloudflareD1Provider.ts +1 -1
  285. package/src/orm/providers/drivers/DatabaseProvider.ts +1 -1
  286. package/src/orm/providers/drivers/NodePostgresProvider.ts +3 -3
  287. package/src/orm/providers/drivers/NodeSqliteProvider.ts +1 -1
  288. package/src/orm/providers/drivers/PglitePostgresProvider.ts +2 -2
  289. package/src/orm/services/ModelBuilder.spec.ts +575 -0
  290. package/src/orm/services/Repository.spec.ts +137 -0
  291. package/src/queue/core/__tests__/shared.ts +143 -0
  292. package/src/queue/core/providers/MemoryQueueProvider.spec.ts +23 -0
  293. package/src/queue/core/providers/WorkerProvider.spec.ts +378 -0
  294. package/src/queue/redis/providers/RedisQueueProvider.spec.ts +23 -0
  295. package/src/redis/__tests__/redis.spec.ts +58 -0
  296. package/src/retry/primitives/$retry.spec.ts +234 -0
  297. package/src/retry/providers/RetryProvider.spec.ts +438 -0
  298. package/src/router/__tests__/match.spec.ts +252 -0
  299. package/src/router/providers/RouterProvider.spec.ts +197 -0
  300. package/src/scheduler/__tests__/$scheduler-cron.spec.ts +25 -0
  301. package/src/scheduler/__tests__/$scheduler-interval.spec.ts +25 -0
  302. package/src/scheduler/__tests__/shared.ts +77 -0
  303. package/src/security/__tests__/bug-1-wildcard-after-start.spec.ts +229 -0
  304. package/src/security/__tests__/bug-2-password-validation.spec.ts +245 -0
  305. package/src/security/__tests__/bug-3-regex-vulnerability.spec.ts +407 -0
  306. package/src/security/__tests__/bug-4-oauth2-validation.spec.ts +439 -0
  307. package/src/security/__tests__/multi-layer-permissions.spec.ts +522 -0
  308. package/src/security/primitives/$permission.spec.ts +30 -0
  309. package/src/security/primitives/$permission.ts +2 -2
  310. package/src/security/primitives/$realm.spec.ts +101 -0
  311. package/src/security/primitives/$role.spec.ts +52 -0
  312. package/src/security/primitives/$serviceAccount.spec.ts +61 -0
  313. package/src/security/providers/SecurityProvider.spec.ts +350 -0
  314. package/src/server/auth/providers/ServerAuthProvider.ts +0 -2
  315. package/src/server/cache/providers/ServerCacheProvider.spec.ts +942 -0
  316. package/src/server/compress/providers/ServerCompressProvider.spec.ts +31 -0
  317. package/src/server/compress/providers/ServerCompressProvider.ts +2 -0
  318. package/src/server/cookies/providers/ServerCookiesProvider.spec.ts +253 -0
  319. package/src/server/core/__tests__/ServerRouterProvider-getRoutes.spec.ts +334 -0
  320. package/src/server/core/__tests__/ServerRouterProvider-requestId.spec.ts +129 -0
  321. package/src/server/core/primitives/$action.spec.ts +191 -0
  322. package/src/server/core/primitives/$route.spec.ts +65 -0
  323. package/src/server/core/providers/ServerBodyParserProvider.spec.ts +93 -0
  324. package/src/server/core/providers/ServerLoggerProvider.spec.ts +100 -0
  325. package/src/server/core/providers/ServerProvider.ts +3 -1
  326. package/src/server/core/services/HttpClient.spec.ts +123 -0
  327. package/src/server/core/services/UserAgentParser.spec.ts +111 -0
  328. package/src/server/cors/providers/ServerCorsProvider.spec.ts +481 -0
  329. package/src/server/health/providers/ServerHealthProvider.spec.ts +22 -0
  330. package/src/server/helmet/providers/ServerHelmetProvider.spec.ts +105 -0
  331. package/src/server/links/__tests__/$action.spec.ts +238 -0
  332. package/src/server/links/__tests__/fixtures/CrudApp.ts +122 -0
  333. package/src/server/links/__tests__/requestId.spec.ts +120 -0
  334. package/src/server/links/primitives/$remote.spec.ts +228 -0
  335. package/src/server/links/providers/LinkProvider.spec.ts +54 -0
  336. package/src/server/links/providers/LinkProvider.ts +49 -3
  337. package/src/server/links/providers/ServerLinksProvider.ts +1 -53
  338. package/src/server/links/schemas/apiLinksResponseSchema.ts +7 -0
  339. package/src/server/metrics/providers/ServerMetricsProvider.spec.ts +25 -0
  340. package/src/server/multipart/providers/ServerMultipartProvider.spec.ts +528 -0
  341. package/src/server/proxy/primitives/$proxy.spec.ts +87 -0
  342. package/src/server/rate-limit/__tests__/ActionRateLimit.spec.ts +211 -0
  343. package/src/server/rate-limit/providers/ServerRateLimitProvider.spec.ts +344 -0
  344. package/src/server/security/__tests__/BasicAuth.spec.ts +684 -0
  345. package/src/server/security/__tests__/ServerSecurityProvider-realm.spec.ts +388 -0
  346. package/src/server/security/providers/ServerSecurityProvider.spec.ts +123 -0
  347. package/src/server/static/primitives/$serve.spec.ts +193 -0
  348. package/src/server/swagger/__tests__/ui.spec.ts +52 -0
  349. package/src/server/swagger/primitives/$swagger.spec.ts +193 -0
  350. package/src/server/swagger/providers/ServerSwaggerProvider.ts +18 -8
  351. package/src/sms/primitives/$sms.spec.ts +165 -0
  352. package/src/sms/providers/LocalSmsProvider.spec.ts +224 -0
  353. package/src/sms/providers/MemorySmsProvider.spec.ts +193 -0
  354. package/src/thread/primitives/$thread.spec.ts +186 -0
  355. package/src/topic/core/__tests__/shared.ts +144 -0
  356. package/src/topic/core/providers/MemoryTopicProvider.spec.ts +23 -0
  357. package/src/topic/redis/providers/RedisTopicProvider.spec.ts +23 -0
  358. package/src/vite/plugins/viteAlephaDev.ts +16 -4
  359. package/src/vite/tasks/runAlepha.ts +7 -1
  360. package/src/websocket/__tests__/$websocket-new.spec.ts +195 -0
  361. package/src/websocket/primitives/$channel.spec.ts +30 -0
@@ -0,0 +1,797 @@
1
+ import { Alepha, t } from "alepha";
2
+ import { describe, expect, test } from "vitest";
3
+ import {
4
+ $prompt,
5
+ $resource,
6
+ $tool,
7
+ AlephaMcp,
8
+ MCP_PROTOCOL_VERSION,
9
+ type McpContext,
10
+ McpServerProvider,
11
+ } from "../index.ts";
12
+
13
+ // ---------------------------------------------------------------------------------------------------------------------
14
+
15
+ describe("McpServerProvider", () => {
16
+ describe("initialization", () => {
17
+ test("should handle initialize request", async () => {
18
+ const alepha = Alepha.create();
19
+
20
+ class Empty {}
21
+
22
+ alepha.with(AlephaMcp).with(Empty);
23
+ await alepha.start();
24
+
25
+ const provider = alepha.inject(McpServerProvider);
26
+ const response = await provider.handleMessage({
27
+ jsonrpc: "2.0",
28
+ id: 1,
29
+ method: "initialize",
30
+ params: {
31
+ protocolVersion: MCP_PROTOCOL_VERSION,
32
+ capabilities: {},
33
+ clientInfo: { name: "test-client", version: "1.0.0" },
34
+ },
35
+ });
36
+
37
+ expect(response).not.toBeNull();
38
+ expect(response?.result).toEqual({
39
+ protocolVersion: MCP_PROTOCOL_VERSION,
40
+ capabilities: {},
41
+ serverInfo: { name: "alepha-mcp", version: "1.0.0" },
42
+ });
43
+ });
44
+
45
+ test("should handle ping request", async () => {
46
+ const alepha = Alepha.create();
47
+ alepha.with(AlephaMcp);
48
+ await alepha.start();
49
+
50
+ const provider = alepha.inject(McpServerProvider);
51
+ const response = await provider.handleMessage({
52
+ jsonrpc: "2.0",
53
+ id: 1,
54
+ method: "ping",
55
+ });
56
+
57
+ expect(response?.result).toEqual({});
58
+ });
59
+ });
60
+
61
+ describe("capabilities", () => {
62
+ test("should report empty capabilities when no primitives registered", async () => {
63
+ const alepha = Alepha.create();
64
+ alepha.with(AlephaMcp);
65
+ await alepha.start();
66
+
67
+ const provider = alepha.inject(McpServerProvider);
68
+ const capabilities = provider.getCapabilities();
69
+
70
+ expect(capabilities).toEqual({
71
+ tools: undefined,
72
+ resources: undefined,
73
+ prompts: undefined,
74
+ });
75
+ });
76
+
77
+ test("should report tools capability when tools registered", async () => {
78
+ const alepha = Alepha.create();
79
+
80
+ class Tools {
81
+ tool = $tool({
82
+ description: "A tool",
83
+ handler: async () => "result",
84
+ });
85
+ }
86
+
87
+ alepha.with(AlephaMcp).with(Tools);
88
+ await alepha.start();
89
+
90
+ const provider = alepha.inject(McpServerProvider);
91
+ const capabilities = provider.getCapabilities();
92
+
93
+ expect(capabilities.tools).toEqual({});
94
+ expect(capabilities.resources).toBeUndefined();
95
+ expect(capabilities.prompts).toBeUndefined();
96
+ });
97
+
98
+ test("should report resources capability when resources registered", async () => {
99
+ const alepha = Alepha.create();
100
+
101
+ class Resources {
102
+ resource = $resource({
103
+ uri: "test://resource",
104
+ handler: async () => ({ text: "content" }),
105
+ });
106
+ }
107
+
108
+ alepha.with(AlephaMcp).with(Resources);
109
+ await alepha.start();
110
+
111
+ const provider = alepha.inject(McpServerProvider);
112
+ const capabilities = provider.getCapabilities();
113
+
114
+ expect(capabilities.resources).toEqual({});
115
+ });
116
+
117
+ test("should report prompts capability when prompts registered", async () => {
118
+ const alepha = Alepha.create();
119
+
120
+ class Prompts {
121
+ prompt = $prompt({
122
+ handler: async () => [{ role: "user", content: "test" }],
123
+ });
124
+ }
125
+
126
+ alepha.with(AlephaMcp).with(Prompts);
127
+ await alepha.start();
128
+
129
+ const provider = alepha.inject(McpServerProvider);
130
+ const capabilities = provider.getCapabilities();
131
+
132
+ expect(capabilities.prompts).toEqual({});
133
+ });
134
+
135
+ test("should report all capabilities when all primitives registered", async () => {
136
+ const alepha = Alepha.create();
137
+
138
+ class All {
139
+ tool = $tool({ description: "Tool", handler: async () => {} });
140
+ resource = $resource({
141
+ uri: "test://r",
142
+ handler: async () => ({ text: "" }),
143
+ });
144
+ prompt = $prompt({ handler: async () => [] });
145
+ }
146
+
147
+ alepha.with(AlephaMcp).with(All);
148
+ await alepha.start();
149
+
150
+ const provider = alepha.inject(McpServerProvider);
151
+ const capabilities = provider.getCapabilities();
152
+
153
+ expect(capabilities.tools).toEqual({});
154
+ expect(capabilities.resources).toEqual({});
155
+ expect(capabilities.prompts).toEqual({});
156
+ });
157
+ });
158
+
159
+ describe("tools/list", () => {
160
+ test("should list all registered tools", async () => {
161
+ const alepha = Alepha.create();
162
+
163
+ class Calculator {
164
+ add = $tool({
165
+ description: "Add numbers",
166
+ schema: { params: t.object({ a: t.number(), b: t.number() }) },
167
+ handler: async ({ params }) => params.a + params.b,
168
+ });
169
+
170
+ subtract = $tool({
171
+ description: "Subtract numbers",
172
+ schema: { params: t.object({ a: t.number(), b: t.number() }) },
173
+ handler: async ({ params }) => params.a - params.b,
174
+ });
175
+ }
176
+
177
+ alepha.with(AlephaMcp).with(Calculator);
178
+ await alepha.start();
179
+
180
+ const provider = alepha.inject(McpServerProvider);
181
+ const response = await provider.handleMessage({
182
+ jsonrpc: "2.0",
183
+ id: 1,
184
+ method: "tools/list",
185
+ });
186
+
187
+ const result = response?.result as {
188
+ tools: Array<{ name: string; description: string }>;
189
+ };
190
+ expect(result.tools).toHaveLength(2);
191
+ expect(result.tools.find((t) => t.name === "add")).toBeDefined();
192
+ expect(result.tools.find((t) => t.name === "subtract")).toBeDefined();
193
+ });
194
+ });
195
+
196
+ describe("tools/call", () => {
197
+ test("should call tool and return result", async () => {
198
+ const alepha = Alepha.create();
199
+
200
+ class Calculator {
201
+ multiply = $tool({
202
+ description: "Multiply",
203
+ schema: {
204
+ params: t.object({ a: t.number(), b: t.number() }),
205
+ result: t.number(),
206
+ },
207
+ handler: async ({ params }) => params.a * params.b,
208
+ });
209
+ }
210
+
211
+ alepha.with(AlephaMcp).with(Calculator);
212
+ await alepha.start();
213
+
214
+ const provider = alepha.inject(McpServerProvider);
215
+ const response = await provider.handleMessage({
216
+ jsonrpc: "2.0",
217
+ id: 1,
218
+ method: "tools/call",
219
+ params: {
220
+ name: "multiply",
221
+ arguments: { a: 6, b: 7 },
222
+ },
223
+ });
224
+
225
+ const result = response?.result as {
226
+ content: Array<{ type: string; text: string }>;
227
+ };
228
+ expect(result.content).toHaveLength(1);
229
+ expect(result.content[0].type).toBe("text");
230
+ expect(result.content[0].text).toBe("42");
231
+ });
232
+
233
+ test("should return error for unknown tool", async () => {
234
+ const alepha = Alepha.create();
235
+ alepha.with(AlephaMcp);
236
+ await alepha.start();
237
+
238
+ const provider = alepha.inject(McpServerProvider);
239
+ const response = await provider.handleMessage({
240
+ jsonrpc: "2.0",
241
+ id: 1,
242
+ method: "tools/call",
243
+ params: {
244
+ name: "unknown-tool",
245
+ arguments: {},
246
+ },
247
+ });
248
+
249
+ expect(response?.error).toBeDefined();
250
+ expect(response?.error?.message).toContain("unknown-tool");
251
+ });
252
+
253
+ test("should return isError for handler errors", async () => {
254
+ const alepha = Alepha.create();
255
+
256
+ class Tools {
257
+ failing = $tool({
258
+ description: "Failing tool",
259
+ handler: async () => {
260
+ throw new Error("Tool execution failed");
261
+ },
262
+ });
263
+ }
264
+
265
+ alepha.with(AlephaMcp).with(Tools);
266
+ await alepha.start();
267
+
268
+ const provider = alepha.inject(McpServerProvider);
269
+ const response = await provider.handleMessage({
270
+ jsonrpc: "2.0",
271
+ id: 1,
272
+ method: "tools/call",
273
+ params: { name: "failing", arguments: {} },
274
+ });
275
+
276
+ const result = response?.result as {
277
+ content: Array<{ text: string }>;
278
+ isError?: boolean;
279
+ };
280
+ expect(result.isError).toBe(true);
281
+ expect(result.content[0].text).toContain("Tool execution failed");
282
+ });
283
+ });
284
+
285
+ describe("resources/list", () => {
286
+ test("should list all registered resources", async () => {
287
+ const alepha = Alepha.create();
288
+
289
+ class Resources {
290
+ readme = $resource({
291
+ uri: "file:///readme",
292
+ name: "README",
293
+ description: "Project readme",
294
+ handler: async () => ({ text: "# README" }),
295
+ });
296
+
297
+ config = $resource({
298
+ uri: "config://app",
299
+ name: "Config",
300
+ mimeType: "application/json",
301
+ handler: async () => ({ text: "{}" }),
302
+ });
303
+ }
304
+
305
+ alepha.with(AlephaMcp).with(Resources);
306
+ await alepha.start();
307
+
308
+ const provider = alepha.inject(McpServerProvider);
309
+ const response = await provider.handleMessage({
310
+ jsonrpc: "2.0",
311
+ id: 1,
312
+ method: "resources/list",
313
+ });
314
+
315
+ const result = response?.result as {
316
+ resources: Array<{ uri: string; name: string }>;
317
+ };
318
+ expect(result.resources).toHaveLength(2);
319
+ expect(
320
+ result.resources.find((r) => r.uri === "file:///readme"),
321
+ ).toBeDefined();
322
+ expect(
323
+ result.resources.find((r) => r.uri === "config://app"),
324
+ ).toBeDefined();
325
+ });
326
+ });
327
+
328
+ describe("resources/read", () => {
329
+ test("should read resource content", async () => {
330
+ const alepha = Alepha.create();
331
+
332
+ class Resources {
333
+ text = $resource({
334
+ uri: "text://hello",
335
+ mimeType: "text/plain",
336
+ handler: async () => ({ text: "Hello, World!" }),
337
+ });
338
+ }
339
+
340
+ alepha.with(AlephaMcp).with(Resources);
341
+ await alepha.start();
342
+
343
+ const provider = alepha.inject(McpServerProvider);
344
+ const response = await provider.handleMessage({
345
+ jsonrpc: "2.0",
346
+ id: 1,
347
+ method: "resources/read",
348
+ params: { uri: "text://hello" },
349
+ });
350
+
351
+ const result = response?.result as {
352
+ contents: Array<{ uri: string; text: string }>;
353
+ };
354
+ expect(result.contents).toHaveLength(1);
355
+ expect(result.contents[0].uri).toBe("text://hello");
356
+ expect(result.contents[0].text).toBe("Hello, World!");
357
+ });
358
+
359
+ test("should return error for unknown resource", async () => {
360
+ const alepha = Alepha.create();
361
+ alepha.with(AlephaMcp);
362
+ await alepha.start();
363
+
364
+ const provider = alepha.inject(McpServerProvider);
365
+ const response = await provider.handleMessage({
366
+ jsonrpc: "2.0",
367
+ id: 1,
368
+ method: "resources/read",
369
+ params: { uri: "unknown://resource" },
370
+ });
371
+
372
+ expect(response?.error).toBeDefined();
373
+ expect(response?.error?.message).toContain("unknown://resource");
374
+ });
375
+
376
+ test("should handle binary content", async () => {
377
+ const alepha = Alepha.create();
378
+
379
+ const binaryData = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f]); // "Hello" in bytes
380
+
381
+ class Resources {
382
+ binary = $resource({
383
+ uri: "binary://data",
384
+ mimeType: "application/octet-stream",
385
+ handler: async () => ({ blob: binaryData }),
386
+ });
387
+ }
388
+
389
+ alepha.with(AlephaMcp).with(Resources);
390
+ await alepha.start();
391
+
392
+ const provider = alepha.inject(McpServerProvider);
393
+ const response = await provider.handleMessage({
394
+ jsonrpc: "2.0",
395
+ id: 1,
396
+ method: "resources/read",
397
+ params: { uri: "binary://data" },
398
+ });
399
+
400
+ const result = response?.result as { contents: Array<{ blob: string }> };
401
+ expect(result.contents[0].blob).toBe(
402
+ Buffer.from(binaryData).toString("base64"),
403
+ );
404
+ });
405
+ });
406
+
407
+ describe("prompts/list", () => {
408
+ test("should list all registered prompts", async () => {
409
+ const alepha = Alepha.create();
410
+
411
+ class Prompts {
412
+ greeting = $prompt({
413
+ description: "Generate greeting",
414
+ args: t.object({ name: t.text() }),
415
+ handler: async () => [],
416
+ });
417
+
418
+ review = $prompt({
419
+ description: "Code review",
420
+ handler: async () => [],
421
+ });
422
+ }
423
+
424
+ alepha.with(AlephaMcp).with(Prompts);
425
+ await alepha.start();
426
+
427
+ const provider = alepha.inject(McpServerProvider);
428
+ const response = await provider.handleMessage({
429
+ jsonrpc: "2.0",
430
+ id: 1,
431
+ method: "prompts/list",
432
+ });
433
+
434
+ const result = response?.result as { prompts: Array<{ name: string }> };
435
+ expect(result.prompts).toHaveLength(2);
436
+ expect(result.prompts.find((p) => p.name === "greeting")).toBeDefined();
437
+ expect(result.prompts.find((p) => p.name === "review")).toBeDefined();
438
+ });
439
+ });
440
+
441
+ describe("prompts/get", () => {
442
+ test("should get prompt messages", async () => {
443
+ const alepha = Alepha.create();
444
+
445
+ class Prompts {
446
+ greeting = $prompt({
447
+ description: "Generate greeting",
448
+ args: t.object({ name: t.text() }),
449
+ handler: async ({ args }) => [
450
+ { role: "user", content: `Say hello to ${args.name}` },
451
+ ],
452
+ });
453
+ }
454
+
455
+ alepha.with(AlephaMcp).with(Prompts);
456
+ await alepha.start();
457
+
458
+ const provider = alepha.inject(McpServerProvider);
459
+ const response = await provider.handleMessage({
460
+ jsonrpc: "2.0",
461
+ id: 1,
462
+ method: "prompts/get",
463
+ params: { name: "greeting", arguments: { name: "World" } },
464
+ });
465
+
466
+ const result = response?.result as {
467
+ messages: Array<{ role: string; content: { text: string } }>;
468
+ };
469
+ expect(result.messages).toHaveLength(1);
470
+ expect(result.messages[0].role).toBe("user");
471
+ expect(result.messages[0].content.text).toBe("Say hello to World");
472
+ });
473
+
474
+ test("should return error for unknown prompt", async () => {
475
+ const alepha = Alepha.create();
476
+ alepha.with(AlephaMcp);
477
+ await alepha.start();
478
+
479
+ const provider = alepha.inject(McpServerProvider);
480
+ const response = await provider.handleMessage({
481
+ jsonrpc: "2.0",
482
+ id: 1,
483
+ method: "prompts/get",
484
+ params: { name: "unknown-prompt" },
485
+ });
486
+
487
+ expect(response?.error).toBeDefined();
488
+ expect(response?.error?.message).toContain("unknown-prompt");
489
+ });
490
+ });
491
+
492
+ describe("notifications", () => {
493
+ test("should not return response for notifications", async () => {
494
+ const alepha = Alepha.create();
495
+ alepha.with(AlephaMcp);
496
+ await alepha.start();
497
+
498
+ const provider = alepha.inject(McpServerProvider);
499
+ const response = await provider.handleMessage({
500
+ jsonrpc: "2.0",
501
+ method: "notifications/initialized",
502
+ });
503
+
504
+ expect(response).toBeNull();
505
+ });
506
+ });
507
+
508
+ describe("unknown methods", () => {
509
+ test("should return method not found error", async () => {
510
+ const alepha = Alepha.create();
511
+ alepha.with(AlephaMcp);
512
+ await alepha.start();
513
+
514
+ const provider = alepha.inject(McpServerProvider);
515
+ const response = await provider.handleMessage({
516
+ jsonrpc: "2.0",
517
+ id: 1,
518
+ method: "unknown/method",
519
+ });
520
+
521
+ expect(response?.error).toBeDefined();
522
+ expect(response?.error?.code).toBe(-32601); // METHOD_NOT_FOUND
523
+ expect(response?.error?.message).toContain("unknown/method");
524
+ });
525
+ });
526
+
527
+ describe("getters", () => {
528
+ test("should return all tools", async () => {
529
+ const alepha = Alepha.create();
530
+
531
+ class Tools {
532
+ a = $tool({ description: "A", handler: async () => {} });
533
+ b = $tool({ description: "B", handler: async () => {} });
534
+ }
535
+
536
+ alepha.with(AlephaMcp).with(Tools);
537
+ await alepha.start();
538
+
539
+ const provider = alepha.inject(McpServerProvider);
540
+ const tools = provider.getTools();
541
+
542
+ expect(tools).toHaveLength(2);
543
+ });
544
+
545
+ test("should return all resources", async () => {
546
+ const alepha = Alepha.create();
547
+
548
+ class Resources {
549
+ a = $resource({ uri: "a://", handler: async () => ({ text: "" }) });
550
+ b = $resource({ uri: "b://", handler: async () => ({ text: "" }) });
551
+ }
552
+
553
+ alepha.with(AlephaMcp).with(Resources);
554
+ await alepha.start();
555
+
556
+ const provider = alepha.inject(McpServerProvider);
557
+ const resources = provider.getResources();
558
+
559
+ expect(resources).toHaveLength(2);
560
+ });
561
+
562
+ test("should return all prompts", async () => {
563
+ const alepha = Alepha.create();
564
+
565
+ class Prompts {
566
+ a = $prompt({ handler: async () => [] });
567
+ b = $prompt({ handler: async () => [] });
568
+ }
569
+
570
+ alepha.with(AlephaMcp).with(Prompts);
571
+ await alepha.start();
572
+
573
+ const provider = alepha.inject(McpServerProvider);
574
+ const prompts = provider.getPrompts();
575
+
576
+ expect(prompts).toHaveLength(2);
577
+ });
578
+ });
579
+
580
+ // -----------------------------------------------------------------------------------------------------------------
581
+ // Context tests
582
+ // -----------------------------------------------------------------------------------------------------------------
583
+
584
+ describe("context passing", () => {
585
+ test("should pass context to tools/call", async () => {
586
+ const alepha = Alepha.create();
587
+
588
+ let receivedContext: McpContext | undefined;
589
+
590
+ class Tools {
591
+ contextTool = $tool({
592
+ description: "Tool that receives context",
593
+ schema: {
594
+ params: t.object({ value: t.text() }),
595
+ result: t.text(),
596
+ },
597
+ handler: async ({ params, context }) => {
598
+ receivedContext = context;
599
+ return `Received: ${params.value}`;
600
+ },
601
+ });
602
+ }
603
+
604
+ alepha.with(AlephaMcp).with(Tools);
605
+ await alepha.start();
606
+
607
+ const provider = alepha.inject(McpServerProvider);
608
+ const context: McpContext = {
609
+ headers: { authorization: "Bearer test-token-123" },
610
+ data: { userId: "user-1", projectId: 42 },
611
+ };
612
+
613
+ await provider.handleMessage(
614
+ {
615
+ jsonrpc: "2.0",
616
+ id: 1,
617
+ method: "tools/call",
618
+ params: { name: "contextTool", arguments: { value: "test" } },
619
+ },
620
+ context,
621
+ );
622
+
623
+ expect(receivedContext).toBeDefined();
624
+ expect(receivedContext?.headers?.authorization).toBe(
625
+ "Bearer test-token-123",
626
+ );
627
+ expect(receivedContext?.data).toEqual({
628
+ userId: "user-1",
629
+ projectId: 42,
630
+ });
631
+ });
632
+
633
+ test("should pass context to resources/read", async () => {
634
+ const alepha = Alepha.create();
635
+
636
+ let receivedContext: McpContext | undefined;
637
+
638
+ class Resources {
639
+ contextResource = $resource({
640
+ uri: "context://test",
641
+ handler: async ({ context }) => {
642
+ receivedContext = context;
643
+ return { text: "content" };
644
+ },
645
+ });
646
+ }
647
+
648
+ alepha.with(AlephaMcp).with(Resources);
649
+ await alepha.start();
650
+
651
+ const provider = alepha.inject(McpServerProvider);
652
+ const context: McpContext = {
653
+ headers: { "x-custom-header": "custom-value" },
654
+ };
655
+
656
+ await provider.handleMessage(
657
+ {
658
+ jsonrpc: "2.0",
659
+ id: 1,
660
+ method: "resources/read",
661
+ params: { uri: "context://test" },
662
+ },
663
+ context,
664
+ );
665
+
666
+ expect(receivedContext).toBeDefined();
667
+ expect(receivedContext?.headers?.["x-custom-header"]).toBe(
668
+ "custom-value",
669
+ );
670
+ });
671
+
672
+ test("should pass context to prompts/get", async () => {
673
+ const alepha = Alepha.create();
674
+
675
+ let receivedContext: McpContext | undefined;
676
+
677
+ class Prompts {
678
+ contextPrompt = $prompt({
679
+ description: "Prompt that receives context",
680
+ args: t.object({ name: t.text() }),
681
+ handler: async ({ args, context }) => {
682
+ receivedContext = context;
683
+ return [{ role: "user", content: `Hello ${args.name}` }];
684
+ },
685
+ });
686
+ }
687
+
688
+ alepha.with(AlephaMcp).with(Prompts);
689
+ await alepha.start();
690
+
691
+ const provider = alepha.inject(McpServerProvider);
692
+ const context: McpContext = {
693
+ headers: { authorization: "Bearer prompt-token" },
694
+ data: { role: "admin" },
695
+ };
696
+
697
+ await provider.handleMessage(
698
+ {
699
+ jsonrpc: "2.0",
700
+ id: 1,
701
+ method: "prompts/get",
702
+ params: { name: "contextPrompt", arguments: { name: "World" } },
703
+ },
704
+ context,
705
+ );
706
+
707
+ expect(receivedContext).toBeDefined();
708
+ expect(receivedContext?.headers?.authorization).toBe(
709
+ "Bearer prompt-token",
710
+ );
711
+ expect(receivedContext?.data).toEqual({ role: "admin" });
712
+ });
713
+
714
+ test("should work without context (backward compatibility)", async () => {
715
+ const alepha = Alepha.create();
716
+
717
+ let contextWasUndefined = false;
718
+
719
+ class Tools {
720
+ noContextTool = $tool({
721
+ description: "Tool without context",
722
+ handler: async ({ context }) => {
723
+ contextWasUndefined = context === undefined;
724
+ return "done";
725
+ },
726
+ });
727
+ }
728
+
729
+ alepha.with(AlephaMcp).with(Tools);
730
+ await alepha.start();
731
+
732
+ const provider = alepha.inject(McpServerProvider);
733
+
734
+ // Call without context parameter
735
+ await provider.handleMessage({
736
+ jsonrpc: "2.0",
737
+ id: 1,
738
+ method: "tools/call",
739
+ params: { name: "noContextTool", arguments: {} },
740
+ });
741
+
742
+ expect(contextWasUndefined).toBe(true);
743
+ });
744
+
745
+ test("should use context for authentication in tools", async () => {
746
+ const alepha = Alepha.create();
747
+
748
+ class Tools {
749
+ protected = $tool({
750
+ description: "Protected tool",
751
+ schema: { result: t.text() },
752
+ handler: async ({ context }) => {
753
+ const auth = context?.headers?.authorization;
754
+ if (!auth || !auth.toString().startsWith("Bearer ")) {
755
+ throw new Error("Unauthorized");
756
+ }
757
+ return "Access granted";
758
+ },
759
+ });
760
+ }
761
+
762
+ alepha.with(AlephaMcp).with(Tools);
763
+ await alepha.start();
764
+
765
+ const provider = alepha.inject(McpServerProvider);
766
+
767
+ // Without auth - should return error in result
768
+ const response1 = await provider.handleMessage({
769
+ jsonrpc: "2.0",
770
+ id: 1,
771
+ method: "tools/call",
772
+ params: { name: "protected", arguments: {} },
773
+ });
774
+
775
+ expect((response1?.result as any)?.isError).toBe(true);
776
+ expect((response1?.result as any)?.content[0].text).toContain(
777
+ "Unauthorized",
778
+ );
779
+
780
+ // With auth - should succeed
781
+ const response2 = await provider.handleMessage(
782
+ {
783
+ jsonrpc: "2.0",
784
+ id: 2,
785
+ method: "tools/call",
786
+ params: { name: "protected", arguments: {} },
787
+ },
788
+ { headers: { authorization: "Bearer valid-token" } },
789
+ );
790
+
791
+ expect((response2?.result as any)?.isError).toBeUndefined();
792
+ expect((response2?.result as any)?.content[0].text).toBe(
793
+ "Access granted",
794
+ );
795
+ });
796
+ });
797
+ });