alepha 0.14.4 → 0.15.1

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 (322) hide show
  1. package/README.md +44 -102
  2. package/dist/api/audits/index.d.ts +331 -443
  3. package/dist/api/audits/index.d.ts.map +1 -1
  4. package/dist/api/audits/index.js +2 -2
  5. package/dist/api/audits/index.js.map +1 -1
  6. package/dist/api/files/index.d.ts +0 -113
  7. package/dist/api/files/index.d.ts.map +1 -1
  8. package/dist/api/files/index.js +2 -3
  9. package/dist/api/files/index.js.map +1 -1
  10. package/dist/api/jobs/index.d.ts +151 -262
  11. package/dist/api/jobs/index.d.ts.map +1 -1
  12. package/dist/api/notifications/index.browser.js +4 -4
  13. package/dist/api/notifications/index.browser.js.map +1 -1
  14. package/dist/api/notifications/index.d.ts +164 -276
  15. package/dist/api/notifications/index.d.ts.map +1 -1
  16. package/dist/api/notifications/index.js +4 -4
  17. package/dist/api/notifications/index.js.map +1 -1
  18. package/dist/api/parameters/index.d.ts +265 -377
  19. package/dist/api/parameters/index.d.ts.map +1 -1
  20. package/dist/api/users/index.browser.js +1 -2
  21. package/dist/api/users/index.browser.js.map +1 -1
  22. package/dist/api/users/index.d.ts +195 -301
  23. package/dist/api/users/index.d.ts.map +1 -1
  24. package/dist/api/users/index.js +203 -184
  25. package/dist/api/users/index.js.map +1 -1
  26. package/dist/api/verifications/index.d.ts.map +1 -1
  27. package/dist/batch/index.d.ts.map +1 -1
  28. package/dist/batch/index.js +1 -2
  29. package/dist/batch/index.js.map +1 -1
  30. package/dist/bucket/index.d.ts.map +1 -1
  31. package/dist/cache/core/index.d.ts.map +1 -1
  32. package/dist/cache/redis/index.d.ts.map +1 -1
  33. package/dist/cache/redis/index.js +2 -2
  34. package/dist/cache/redis/index.js.map +1 -1
  35. package/dist/cli/index.d.ts +5900 -165
  36. package/dist/cli/index.d.ts.map +1 -1
  37. package/dist/cli/index.js +1481 -639
  38. package/dist/cli/index.js.map +1 -1
  39. package/dist/command/index.d.ts +8 -4
  40. package/dist/command/index.d.ts.map +1 -1
  41. package/dist/command/index.js +29 -25
  42. package/dist/command/index.js.map +1 -1
  43. package/dist/core/index.browser.js +563 -54
  44. package/dist/core/index.browser.js.map +1 -1
  45. package/dist/core/index.d.ts +175 -8
  46. package/dist/core/index.d.ts.map +1 -1
  47. package/dist/core/index.js +564 -54
  48. package/dist/core/index.js.map +1 -1
  49. package/dist/core/index.native.js +563 -54
  50. package/dist/core/index.native.js.map +1 -1
  51. package/dist/datetime/index.d.ts.map +1 -1
  52. package/dist/datetime/index.js +4 -4
  53. package/dist/datetime/index.js.map +1 -1
  54. package/dist/email/index.d.ts +89 -42
  55. package/dist/email/index.d.ts.map +1 -1
  56. package/dist/email/index.js +129 -33
  57. package/dist/email/index.js.map +1 -1
  58. package/dist/fake/index.d.ts +7969 -2
  59. package/dist/fake/index.d.ts.map +1 -1
  60. package/dist/fake/index.js +22 -22
  61. package/dist/fake/index.js.map +1 -1
  62. package/dist/file/index.d.ts +134 -1
  63. package/dist/file/index.d.ts.map +1 -1
  64. package/dist/file/index.js +253 -1
  65. package/dist/file/index.js.map +1 -1
  66. package/dist/lock/core/index.d.ts.map +1 -1
  67. package/dist/lock/redis/index.d.ts.map +1 -1
  68. package/dist/logger/index.d.ts +1 -2
  69. package/dist/logger/index.d.ts.map +1 -1
  70. package/dist/logger/index.js +1 -5
  71. package/dist/logger/index.js.map +1 -1
  72. package/dist/mcp/index.d.ts +19 -1
  73. package/dist/mcp/index.d.ts.map +1 -1
  74. package/dist/mcp/index.js +28 -4
  75. package/dist/mcp/index.js.map +1 -1
  76. package/dist/orm/chunk-DH6iiROE.js +38 -0
  77. package/dist/orm/index.browser.js +9 -9
  78. package/dist/orm/index.browser.js.map +1 -1
  79. package/dist/orm/index.bun.js +2821 -0
  80. package/dist/orm/index.bun.js.map +1 -0
  81. package/dist/orm/index.d.ts +318 -169
  82. package/dist/orm/index.d.ts.map +1 -1
  83. package/dist/orm/index.js +2086 -1776
  84. package/dist/orm/index.js.map +1 -1
  85. package/dist/queue/core/index.d.ts +4 -4
  86. package/dist/queue/core/index.d.ts.map +1 -1
  87. package/dist/queue/redis/index.d.ts.map +1 -1
  88. package/dist/redis/index.bun.js +285 -0
  89. package/dist/redis/index.bun.js.map +1 -0
  90. package/dist/redis/index.d.ts +13 -31
  91. package/dist/redis/index.d.ts.map +1 -1
  92. package/dist/redis/index.js +18 -38
  93. package/dist/redis/index.js.map +1 -1
  94. package/dist/retry/index.d.ts.map +1 -1
  95. package/dist/router/index.d.ts.map +1 -1
  96. package/dist/scheduler/index.d.ts +83 -1
  97. package/dist/scheduler/index.d.ts.map +1 -1
  98. package/dist/scheduler/index.js +393 -1
  99. package/dist/scheduler/index.js.map +1 -1
  100. package/dist/security/index.browser.js +5 -1
  101. package/dist/security/index.browser.js.map +1 -1
  102. package/dist/security/index.d.ts +598 -112
  103. package/dist/security/index.d.ts.map +1 -1
  104. package/dist/security/index.js +1808 -97
  105. package/dist/security/index.js.map +1 -1
  106. package/dist/server/auth/index.d.ts +1200 -175
  107. package/dist/server/auth/index.d.ts.map +1 -1
  108. package/dist/server/auth/index.js +1268 -37
  109. package/dist/server/auth/index.js.map +1 -1
  110. package/dist/server/cache/index.d.ts +6 -3
  111. package/dist/server/cache/index.d.ts.map +1 -1
  112. package/dist/server/cache/index.js +1 -1
  113. package/dist/server/cache/index.js.map +1 -1
  114. package/dist/server/compress/index.d.ts.map +1 -1
  115. package/dist/server/cookies/index.d.ts.map +1 -1
  116. package/dist/server/cookies/index.js +3 -3
  117. package/dist/server/cookies/index.js.map +1 -1
  118. package/dist/server/core/index.d.ts +115 -13
  119. package/dist/server/core/index.d.ts.map +1 -1
  120. package/dist/server/core/index.js +321 -139
  121. package/dist/server/core/index.js.map +1 -1
  122. package/dist/server/cors/index.d.ts +0 -1
  123. package/dist/server/cors/index.d.ts.map +1 -1
  124. package/dist/server/health/index.d.ts +0 -1
  125. package/dist/server/health/index.d.ts.map +1 -1
  126. package/dist/server/helmet/index.d.ts.map +1 -1
  127. package/dist/server/links/index.browser.js +9 -1
  128. package/dist/server/links/index.browser.js.map +1 -1
  129. package/dist/server/links/index.d.ts +1 -2
  130. package/dist/server/links/index.d.ts.map +1 -1
  131. package/dist/server/links/index.js +14 -7
  132. package/dist/server/links/index.js.map +1 -1
  133. package/dist/server/metrics/index.d.ts +514 -1
  134. package/dist/server/metrics/index.d.ts.map +1 -1
  135. package/dist/server/metrics/index.js +4462 -4
  136. package/dist/server/metrics/index.js.map +1 -1
  137. package/dist/server/multipart/index.d.ts.map +1 -1
  138. package/dist/server/proxy/index.d.ts +0 -1
  139. package/dist/server/proxy/index.d.ts.map +1 -1
  140. package/dist/server/rate-limit/index.d.ts.map +1 -1
  141. package/dist/server/static/index.d.ts.map +1 -1
  142. package/dist/server/swagger/index.d.ts +1 -2
  143. package/dist/server/swagger/index.d.ts.map +1 -1
  144. package/dist/server/swagger/index.js +1 -2
  145. package/dist/server/swagger/index.js.map +1 -1
  146. package/dist/sms/index.d.ts +3 -1
  147. package/dist/sms/index.d.ts.map +1 -1
  148. package/dist/sms/index.js +10 -10
  149. package/dist/sms/index.js.map +1 -1
  150. package/dist/thread/index.d.ts +0 -1
  151. package/dist/thread/index.d.ts.map +1 -1
  152. package/dist/thread/index.js +2 -2
  153. package/dist/thread/index.js.map +1 -1
  154. package/dist/topic/core/index.d.ts.map +1 -1
  155. package/dist/topic/redis/index.d.ts.map +1 -1
  156. package/dist/vite/index.d.ts +6315 -149
  157. package/dist/vite/index.d.ts.map +1 -1
  158. package/dist/vite/index.js +140 -469
  159. package/dist/vite/index.js.map +1 -1
  160. package/dist/websocket/index.browser.js +9 -9
  161. package/dist/websocket/index.browser.js.map +1 -1
  162. package/dist/websocket/index.d.ts +28 -28
  163. package/dist/websocket/index.d.ts.map +1 -1
  164. package/dist/websocket/index.js +9 -9
  165. package/dist/websocket/index.js.map +1 -1
  166. package/package.json +13 -18
  167. package/src/api/files/controllers/AdminFileStatsController.ts +0 -1
  168. package/src/api/users/atoms/realmAuthSettingsAtom.ts +5 -0
  169. package/src/api/users/controllers/{UserRealmController.ts → RealmController.ts} +11 -11
  170. package/src/api/users/entities/users.ts +1 -1
  171. package/src/api/users/index.ts +8 -8
  172. package/src/api/users/primitives/{$userRealm.ts → $realm.ts} +17 -19
  173. package/src/api/users/providers/{UserRealmProvider.ts → RealmProvider.ts} +26 -30
  174. package/src/api/users/schemas/{userRealmConfigSchema.ts → realmConfigSchema.ts} +2 -2
  175. package/src/api/users/services/CredentialService.ts +7 -7
  176. package/src/api/users/services/IdentityService.ts +4 -4
  177. package/src/api/users/services/RegistrationService.spec.ts +25 -27
  178. package/src/api/users/services/RegistrationService.ts +38 -27
  179. package/src/api/users/services/SessionCrudService.ts +3 -3
  180. package/src/api/users/services/SessionService.spec.ts +3 -3
  181. package/src/api/users/services/SessionService.ts +27 -18
  182. package/src/api/users/services/UserService.ts +7 -7
  183. package/src/batch/providers/BatchProvider.ts +1 -2
  184. package/src/cli/apps/AlephaCli.ts +2 -2
  185. package/src/cli/apps/AlephaPackageBuilderCli.ts +47 -20
  186. package/src/cli/assets/apiHelloControllerTs.ts +19 -0
  187. package/src/cli/assets/apiIndexTs.ts +16 -0
  188. package/src/cli/assets/biomeJson.ts +2 -1
  189. package/src/cli/assets/claudeMd.ts +308 -0
  190. package/src/cli/assets/dummySpecTs.ts +2 -1
  191. package/src/cli/assets/editorconfig.ts +2 -1
  192. package/src/cli/assets/mainBrowserTs.ts +4 -3
  193. package/src/cli/assets/mainCss.ts +24 -0
  194. package/src/cli/assets/mainServerTs.ts +24 -0
  195. package/src/cli/assets/tsconfigJson.ts +2 -1
  196. package/src/cli/assets/webAppRouterTs.ts +16 -0
  197. package/src/cli/assets/webHelloComponentTsx.ts +20 -0
  198. package/src/cli/assets/webIndexTs.ts +16 -0
  199. package/src/cli/atoms/appEntryOptions.ts +13 -0
  200. package/src/cli/atoms/buildOptions.ts +1 -1
  201. package/src/cli/atoms/changelogOptions.ts +1 -1
  202. package/src/cli/commands/build.ts +97 -61
  203. package/src/cli/commands/db.ts +21 -18
  204. package/src/cli/commands/deploy.ts +17 -5
  205. package/src/cli/commands/dev.ts +26 -47
  206. package/src/cli/commands/gen/env.ts +1 -1
  207. package/src/cli/commands/init.ts +79 -25
  208. package/src/cli/commands/lint.ts +9 -3
  209. package/src/cli/commands/test.ts +8 -2
  210. package/src/cli/commands/typecheck.ts +5 -1
  211. package/src/cli/commands/verify.ts +4 -2
  212. package/src/cli/defineConfig.ts +9 -0
  213. package/src/cli/index.ts +2 -1
  214. package/src/cli/providers/AppEntryProvider.ts +131 -0
  215. package/src/cli/providers/ViteBuildProvider.ts +82 -0
  216. package/src/cli/providers/ViteDevServerProvider.ts +350 -0
  217. package/src/cli/providers/ViteTemplateProvider.ts +27 -0
  218. package/src/cli/services/AlephaCliUtils.ts +72 -602
  219. package/src/cli/services/PackageManagerUtils.ts +308 -0
  220. package/src/cli/services/ProjectScaffolder.ts +329 -0
  221. package/src/command/helpers/Runner.ts +15 -3
  222. package/src/core/Alepha.ts +2 -8
  223. package/src/core/__tests__/Alepha-graph.spec.ts +4 -0
  224. package/src/core/index.shared.ts +1 -0
  225. package/src/core/index.ts +2 -0
  226. package/src/core/primitives/$hook.ts +6 -2
  227. package/src/core/primitives/$module.spec.ts +4 -0
  228. package/src/core/primitives/$module.ts +12 -0
  229. package/src/core/providers/AlsProvider.ts +1 -1
  230. package/src/core/providers/CodecManager.spec.ts +12 -6
  231. package/src/core/providers/CodecManager.ts +26 -6
  232. package/src/core/providers/EventManager.ts +169 -13
  233. package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +878 -0
  234. package/src/core/providers/KeylessJsonSchemaCodec.ts +789 -0
  235. package/src/core/providers/SchemaValidator.spec.ts +236 -0
  236. package/src/core/providers/StateManager.spec.ts +27 -16
  237. package/src/email/providers/LocalEmailProvider.spec.ts +111 -87
  238. package/src/email/providers/LocalEmailProvider.ts +52 -15
  239. package/src/email/providers/NodemailerEmailProvider.ts +167 -56
  240. package/src/file/errors/FileError.ts +7 -0
  241. package/src/file/index.ts +9 -1
  242. package/src/file/providers/MemoryFileSystemProvider.ts +393 -0
  243. package/src/logger/providers/PrettyFormatterProvider.ts +0 -9
  244. package/src/mcp/errors/McpError.ts +30 -0
  245. package/src/mcp/index.ts +3 -0
  246. package/src/mcp/transports/SseMcpTransport.ts +16 -6
  247. package/src/orm/index.browser.ts +1 -19
  248. package/src/orm/index.bun.ts +77 -0
  249. package/src/orm/index.shared-server.ts +22 -0
  250. package/src/orm/index.shared.ts +15 -0
  251. package/src/orm/index.ts +19 -39
  252. package/src/orm/providers/DrizzleKitProvider.ts +3 -5
  253. package/src/orm/providers/drivers/BunPostgresProvider.ts +3 -5
  254. package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -1
  255. package/src/orm/providers/drivers/CloudflareD1Provider.ts +4 -0
  256. package/src/orm/providers/drivers/DatabaseProvider.ts +4 -0
  257. package/src/orm/providers/drivers/PglitePostgresProvider.ts +4 -0
  258. package/src/orm/services/Repository.ts +19 -0
  259. package/src/redis/index.bun.ts +35 -0
  260. package/src/redis/providers/BunRedisProvider.ts +12 -43
  261. package/src/redis/providers/BunRedisSubscriberProvider.ts +2 -3
  262. package/src/redis/providers/NodeRedisProvider.ts +16 -34
  263. package/src/{server/security → security}/__tests__/BasicAuth.spec.ts +11 -11
  264. package/src/{server/security → security}/__tests__/ServerSecurityProvider-realm.spec.ts +21 -16
  265. package/src/{server/security/providers → security/__tests__}/ServerSecurityProvider.spec.ts +5 -5
  266. package/src/security/index.browser.ts +5 -0
  267. package/src/security/index.ts +90 -7
  268. package/src/security/primitives/{$realm.spec.ts → $issuer.spec.ts} +11 -11
  269. package/src/security/primitives/{$realm.ts → $issuer.ts} +20 -17
  270. package/src/security/primitives/$role.ts +5 -5
  271. package/src/security/primitives/$serviceAccount.spec.ts +5 -5
  272. package/src/security/primitives/$serviceAccount.ts +3 -3
  273. package/src/{server/security → security}/providers/ServerSecurityProvider.ts +5 -7
  274. package/src/server/auth/primitives/$auth.ts +10 -10
  275. package/src/server/auth/primitives/$authCredentials.ts +3 -3
  276. package/src/server/auth/primitives/$authGithub.ts +3 -3
  277. package/src/server/auth/primitives/$authGoogle.ts +3 -3
  278. package/src/server/auth/providers/ServerAuthProvider.ts +13 -13
  279. package/src/server/cache/providers/ServerCacheProvider.ts +1 -1
  280. package/src/server/cookies/providers/ServerCookiesProvider.ts +3 -3
  281. package/src/server/core/index.ts +1 -1
  282. package/src/server/core/providers/BunHttpServerProvider.ts +1 -1
  283. package/src/server/core/providers/NodeHttpServerProvider.spec.ts +125 -0
  284. package/src/server/core/providers/NodeHttpServerProvider.ts +92 -24
  285. package/src/server/core/providers/ServerBodyParserProvider.ts +19 -23
  286. package/src/server/core/providers/ServerLoggerProvider.ts +23 -19
  287. package/src/server/core/providers/ServerProvider.ts +144 -24
  288. package/src/server/core/providers/ServerRouterProvider.ts +259 -115
  289. package/src/server/core/providers/ServerTimingProvider.ts +2 -2
  290. package/src/server/links/atoms/apiLinksAtom.ts +7 -0
  291. package/src/server/links/index.browser.ts +2 -0
  292. package/src/server/links/index.ts +3 -1
  293. package/src/server/links/providers/LinkProvider.ts +1 -1
  294. package/src/server/swagger/index.ts +1 -1
  295. package/src/sms/providers/LocalSmsProvider.spec.ts +153 -111
  296. package/src/sms/providers/LocalSmsProvider.ts +8 -7
  297. package/src/vite/index.ts +3 -2
  298. package/src/vite/tasks/buildClient.ts +0 -1
  299. package/src/vite/tasks/buildServer.ts +80 -22
  300. package/src/vite/tasks/copyAssets.ts +5 -4
  301. package/src/vite/tasks/generateCloudflare.ts +7 -0
  302. package/src/vite/tasks/generateSitemap.ts +64 -23
  303. package/src/vite/tasks/index.ts +0 -2
  304. package/src/vite/tasks/prerenderPages.ts +49 -24
  305. package/dist/server/security/index.browser.js +0 -13
  306. package/dist/server/security/index.browser.js.map +0 -1
  307. package/dist/server/security/index.d.ts +0 -173
  308. package/dist/server/security/index.d.ts.map +0 -1
  309. package/dist/server/security/index.js +0 -311
  310. package/dist/server/security/index.js.map +0 -1
  311. package/src/cli/assets/appRouterTs.ts +0 -9
  312. package/src/cli/assets/indexHtml.ts +0 -15
  313. package/src/cli/assets/mainTs.ts +0 -13
  314. package/src/cli/commands/format.ts +0 -17
  315. package/src/server/security/index.browser.ts +0 -10
  316. package/src/server/security/index.ts +0 -94
  317. package/src/vite/helpers/boot.ts +0 -106
  318. package/src/vite/plugins/viteAlephaDev.ts +0 -177
  319. package/src/vite/tasks/devServer.ts +0 -69
  320. package/src/vite/tasks/runAlepha.ts +0 -270
  321. /package/src/{server/security → security}/primitives/$basicAuth.ts +0 -0
  322. /package/src/{server/security → security}/providers/ServerBasicAuthProvider.ts +0 -0
@@ -0,0 +1,393 @@
1
+ import type { FileLike } from "alepha";
2
+ import type {
3
+ CpOptions,
4
+ CreateFileOptions,
5
+ FileSystemProvider,
6
+ LsOptions,
7
+ MkdirOptions,
8
+ RmOptions,
9
+ } from "./FileSystemProvider.ts";
10
+
11
+ // ---------------------------------------------------------------------------------------------------------------------
12
+
13
+ export interface MemoryFileSystemProviderOptions {
14
+ /**
15
+ * Error to throw on mkdir operations (for testing error handling)
16
+ */
17
+ mkdirError?: Error | null;
18
+ /**
19
+ * Error to throw on writeFile operations (for testing error handling)
20
+ */
21
+ writeFileError?: Error | null;
22
+ /**
23
+ * Error to throw on readFile operations (for testing error handling)
24
+ */
25
+ readFileError?: Error | null;
26
+ }
27
+
28
+ // ---------------------------------------------------------------------------------------------------------------------
29
+
30
+ /**
31
+ * In-memory implementation of FileSystemProvider for testing.
32
+ *
33
+ * This provider stores all files and directories in memory, making it ideal for
34
+ * unit tests that need to verify file operations without touching the real file system.
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * // In tests, substitute the real FileSystemProvider with MemoryFileSystemProvider
39
+ * const alepha = Alepha.create().with({
40
+ * provide: FileSystemProvider,
41
+ * use: MemoryFileSystemProvider,
42
+ * });
43
+ *
44
+ * // Run code that uses FileSystemProvider
45
+ * const service = alepha.inject(MyService);
46
+ * await service.saveFile("test.txt", "Hello World");
47
+ *
48
+ * // Verify the file was written
49
+ * const memoryFs = alepha.inject(MemoryFileSystemProvider);
50
+ * expect(memoryFs.files.get("test.txt")?.toString()).toBe("Hello World");
51
+ * ```
52
+ */
53
+ export class MemoryFileSystemProvider implements FileSystemProvider {
54
+ /**
55
+ * In-memory storage for files (path -> content)
56
+ */
57
+ public files = new Map<string, Buffer>();
58
+
59
+ /**
60
+ * In-memory storage for directories
61
+ */
62
+ public directories = new Set<string>();
63
+
64
+ /**
65
+ * Track mkdir calls for test assertions
66
+ */
67
+ public mkdirCalls: Array<{ path: string; options?: MkdirOptions }> = [];
68
+
69
+ /**
70
+ * Track writeFile calls for test assertions
71
+ */
72
+ public writeFileCalls: Array<{ path: string; data: string }> = [];
73
+
74
+ /**
75
+ * Track join calls for test assertions
76
+ */
77
+ public joinCalls: Array<string[]> = [];
78
+
79
+ /**
80
+ * Error to throw on mkdir (for testing error handling)
81
+ */
82
+ public mkdirError: Error | null = null;
83
+
84
+ /**
85
+ * Error to throw on writeFile (for testing error handling)
86
+ */
87
+ public writeFileError: Error | null = null;
88
+
89
+ /**
90
+ * Error to throw on readFile (for testing error handling)
91
+ */
92
+ public readFileError: Error | null = null;
93
+
94
+ constructor(options: MemoryFileSystemProviderOptions = {}) {
95
+ this.mkdirError = options.mkdirError ?? null;
96
+ this.writeFileError = options.writeFileError ?? null;
97
+ this.readFileError = options.readFileError ?? null;
98
+ }
99
+
100
+ /**
101
+ * Join path segments using forward slashes.
102
+ */
103
+ public join(...paths: string[]): string {
104
+ this.joinCalls.push(paths);
105
+ // Simple path join - normalize and join with /
106
+ return paths.filter(Boolean).join("/").replace(/\/+/g, "/");
107
+ }
108
+
109
+ /**
110
+ * Create a FileLike object from various sources.
111
+ */
112
+ public createFile(options: CreateFileOptions): FileLike {
113
+ if ("buffer" in options) {
114
+ const buffer = options.buffer;
115
+ return {
116
+ name: options.name ?? "file",
117
+ type: options.type ?? "application/octet-stream",
118
+ size: buffer.byteLength,
119
+ lastModified: Date.now(),
120
+ stream: () => {
121
+ throw new Error("Stream not implemented in MemoryFileSystemProvider");
122
+ },
123
+ arrayBuffer: async (): Promise<ArrayBuffer> =>
124
+ buffer.buffer.slice(
125
+ buffer.byteOffset,
126
+ buffer.byteOffset + buffer.byteLength,
127
+ ) as ArrayBuffer,
128
+ text: async () => buffer.toString("utf-8"),
129
+ };
130
+ }
131
+
132
+ if ("text" in options) {
133
+ const buffer = Buffer.from(options.text, "utf-8");
134
+ return {
135
+ name: options.name ?? "file.txt",
136
+ type: options.type ?? "text/plain",
137
+ size: buffer.byteLength,
138
+ lastModified: Date.now(),
139
+ stream: () => {
140
+ throw new Error("Stream not implemented in MemoryFileSystemProvider");
141
+ },
142
+ arrayBuffer: async (): Promise<ArrayBuffer> =>
143
+ buffer.buffer.slice(
144
+ buffer.byteOffset,
145
+ buffer.byteOffset + buffer.byteLength,
146
+ ) as ArrayBuffer,
147
+ text: async () => options.text,
148
+ };
149
+ }
150
+
151
+ throw new Error(
152
+ "MemoryFileSystemProvider.createFile: unsupported options. Only buffer and text are supported.",
153
+ );
154
+ }
155
+
156
+ /**
157
+ * Remove a file or directory from memory.
158
+ */
159
+ public async rm(path: string, options?: RmOptions): Promise<void> {
160
+ const exists = this.files.has(path) || this.directories.has(path);
161
+
162
+ if (!exists && !options?.force) {
163
+ throw new Error(`ENOENT: no such file or directory, rm '${path}'`);
164
+ }
165
+
166
+ if (this.directories.has(path)) {
167
+ if (options?.recursive) {
168
+ // Remove directory and all contents
169
+ this.directories.delete(path);
170
+ for (const filePath of this.files.keys()) {
171
+ if (filePath.startsWith(`${path}/`)) {
172
+ this.files.delete(filePath);
173
+ }
174
+ }
175
+ for (const dirPath of this.directories) {
176
+ if (dirPath.startsWith(`${path}/`)) {
177
+ this.directories.delete(dirPath);
178
+ }
179
+ }
180
+ } else {
181
+ throw new Error(
182
+ `EISDIR: illegal operation on a directory, rm '${path}'`,
183
+ );
184
+ }
185
+ } else {
186
+ this.files.delete(path);
187
+ }
188
+ }
189
+
190
+ /**
191
+ * Copy a file or directory in memory.
192
+ */
193
+ public async cp(
194
+ src: string,
195
+ dest: string,
196
+ options?: CpOptions,
197
+ ): Promise<void> {
198
+ if (this.directories.has(src)) {
199
+ if (!options?.recursive) {
200
+ throw new Error(
201
+ `Cannot copy directory without recursive option: ${src}`,
202
+ );
203
+ }
204
+ // Copy directory and contents
205
+ this.directories.add(dest);
206
+ for (const [filePath, content] of this.files) {
207
+ if (filePath.startsWith(`${src}/`)) {
208
+ const newPath = filePath.replace(src, dest);
209
+ this.files.set(newPath, Buffer.from(content));
210
+ }
211
+ }
212
+ } else if (this.files.has(src)) {
213
+ const content = this.files.get(src)!;
214
+ this.files.set(dest, Buffer.from(content));
215
+ } else {
216
+ throw new Error(`ENOENT: no such file or directory, cp '${src}'`);
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Move/rename a file or directory in memory.
222
+ */
223
+ public async mv(src: string, dest: string): Promise<void> {
224
+ if (this.directories.has(src)) {
225
+ // Move directory and contents
226
+ this.directories.delete(src);
227
+ this.directories.add(dest);
228
+ for (const [filePath, content] of this.files) {
229
+ if (filePath.startsWith(`${src}/`)) {
230
+ const newPath = filePath.replace(src, dest);
231
+ this.files.delete(filePath);
232
+ this.files.set(newPath, content);
233
+ }
234
+ }
235
+ } else if (this.files.has(src)) {
236
+ const content = this.files.get(src)!;
237
+ this.files.delete(src);
238
+ this.files.set(dest, content);
239
+ } else {
240
+ throw new Error(`ENOENT: no such file or directory, mv '${src}'`);
241
+ }
242
+ }
243
+
244
+ /**
245
+ * Create a directory in memory.
246
+ */
247
+ public async mkdir(path: string, options?: MkdirOptions): Promise<void> {
248
+ this.mkdirCalls.push({ path, options });
249
+
250
+ if (this.mkdirError) {
251
+ throw this.mkdirError;
252
+ }
253
+
254
+ if (this.directories.has(path) && !options?.recursive) {
255
+ throw new Error(`EEXIST: file already exists, mkdir '${path}'`);
256
+ }
257
+
258
+ this.directories.add(path);
259
+
260
+ // If recursive, create parent directories
261
+ if (options?.recursive) {
262
+ const parts = path.split("/").filter(Boolean);
263
+ let current = "";
264
+ for (const part of parts) {
265
+ current = current ? `${current}/${part}` : part;
266
+ this.directories.add(current);
267
+ }
268
+ }
269
+ }
270
+
271
+ /**
272
+ * List files in a directory.
273
+ */
274
+ public async ls(path: string, options?: LsOptions): Promise<string[]> {
275
+ const normalizedPath = path.replace(/\/$/, "");
276
+ const entries = new Set<string>();
277
+
278
+ // Find files in the directory
279
+ for (const filePath of this.files.keys()) {
280
+ if (filePath.startsWith(`${normalizedPath}/`)) {
281
+ const relativePath = filePath.slice(normalizedPath.length + 1);
282
+ const parts = relativePath.split("/");
283
+
284
+ if (options?.recursive) {
285
+ entries.add(relativePath);
286
+ } else {
287
+ entries.add(parts[0]);
288
+ }
289
+ }
290
+ }
291
+
292
+ // Find subdirectories
293
+ for (const dirPath of this.directories) {
294
+ if (
295
+ dirPath.startsWith(`${normalizedPath}/`) &&
296
+ dirPath !== normalizedPath
297
+ ) {
298
+ const relativePath = dirPath.slice(normalizedPath.length + 1);
299
+ const parts = relativePath.split("/");
300
+
301
+ if (options?.recursive) {
302
+ entries.add(relativePath);
303
+ } else if (parts.length === 1) {
304
+ entries.add(parts[0]);
305
+ }
306
+ }
307
+ }
308
+
309
+ let result = Array.from(entries);
310
+
311
+ // Filter hidden files unless requested
312
+ if (!options?.hidden) {
313
+ result = result.filter((entry) => !entry.startsWith("."));
314
+ }
315
+
316
+ return result.sort();
317
+ }
318
+
319
+ /**
320
+ * Check if a file or directory exists in memory.
321
+ */
322
+ public async exists(path: string): Promise<boolean> {
323
+ return this.files.has(path) || this.directories.has(path);
324
+ }
325
+
326
+ /**
327
+ * Read a file from memory.
328
+ */
329
+ public async readFile(path: string): Promise<Buffer> {
330
+ if (this.readFileError) {
331
+ throw this.readFileError;
332
+ }
333
+
334
+ const content = this.files.get(path);
335
+ if (!content) {
336
+ throw new Error(`ENOENT: no such file or directory, open '${path}'`);
337
+ }
338
+ return content;
339
+ }
340
+
341
+ /**
342
+ * Write a file to memory.
343
+ */
344
+ public async writeFile(
345
+ path: string,
346
+ data: Uint8Array | Buffer | string | FileLike,
347
+ ): Promise<void> {
348
+ const dataStr =
349
+ typeof data === "string"
350
+ ? data
351
+ : data instanceof Buffer || data instanceof Uint8Array
352
+ ? data.toString("utf-8")
353
+ : await data.text();
354
+
355
+ this.writeFileCalls.push({ path, data: dataStr });
356
+
357
+ if (this.writeFileError) {
358
+ throw this.writeFileError;
359
+ }
360
+
361
+ const buffer =
362
+ typeof data === "string"
363
+ ? Buffer.from(data, "utf-8")
364
+ : data instanceof Buffer
365
+ ? data
366
+ : data instanceof Uint8Array
367
+ ? Buffer.from(data)
368
+ : Buffer.from(await data.text(), "utf-8");
369
+
370
+ this.files.set(path, buffer);
371
+ }
372
+
373
+ /**
374
+ * Reset all in-memory state (useful between tests).
375
+ */
376
+ public reset(): void {
377
+ this.files.clear();
378
+ this.directories.clear();
379
+ this.mkdirCalls = [];
380
+ this.writeFileCalls = [];
381
+ this.joinCalls = [];
382
+ this.mkdirError = null;
383
+ this.writeFileError = null;
384
+ this.readFileError = null;
385
+ }
386
+
387
+ /**
388
+ * Get the content of a file as a string (convenience method for testing).
389
+ */
390
+ public getFileContent(path: string): string | undefined {
391
+ return this.files.get(path)?.toString("utf-8");
392
+ }
393
+ }
@@ -107,15 +107,6 @@ export class PrettyFormatterProvider extends LogFormatterProvider {
107
107
  return "";
108
108
  }
109
109
 
110
- if (this.alepha.isViteDev()) {
111
- // Node.js - try to fix stack trace with Vite SSR helper
112
- // Actually, it works only because we have a global helper in viteAlephaDev.ts
113
- const gl = globalThis as Record<string, unknown>;
114
- if (typeof gl === "object" && typeof gl.ssrFixStacktrace === "function") {
115
- gl.ssrFixStacktrace(error);
116
- }
117
- }
118
-
119
110
  let str = error.stack ?? error.message;
120
111
 
121
112
  const anyError = error as any;
@@ -2,6 +2,16 @@ import { JsonRpcErrorCodes } from "../helpers/jsonrpc.ts";
2
2
 
3
3
  // ---------------------------------------------------------------------------------------------------------------------
4
4
 
5
+ /**
6
+ * MCP-specific error codes (application-specific codes in the -32000 to -32099 range).
7
+ */
8
+ export const McpErrorCodes = {
9
+ UNAUTHORIZED: -32001,
10
+ FORBIDDEN: -32003,
11
+ } as const;
12
+
13
+ // ---------------------------------------------------------------------------------------------------------------------
14
+
5
15
  export class McpError extends Error {
6
16
  name = "McpError";
7
17
  code: number;
@@ -70,3 +80,23 @@ export class McpInvalidParamsError extends McpError {
70
80
  super(message, JsonRpcErrorCodes.INVALID_PARAMS);
71
81
  }
72
82
  }
83
+
84
+ // ---------------------------------------------------------------------------------------------------------------------
85
+
86
+ export class McpUnauthorizedError extends McpError {
87
+ name = "McpUnauthorizedError";
88
+
89
+ constructor(message = "Unauthorized") {
90
+ super(message, McpErrorCodes.UNAUTHORIZED);
91
+ }
92
+ }
93
+
94
+ // ---------------------------------------------------------------------------------------------------------------------
95
+
96
+ export class McpForbiddenError extends McpError {
97
+ name = "McpForbiddenError";
98
+
99
+ constructor(message = "Forbidden") {
100
+ super(message, McpErrorCodes.FORBIDDEN);
101
+ }
102
+ }
package/src/mcp/index.ts CHANGED
@@ -10,11 +10,14 @@ import { StdioMcpTransport } from "./transports/StdioMcpTransport.ts";
10
10
 
11
11
  export {
12
12
  McpError,
13
+ McpErrorCodes,
14
+ McpForbiddenError,
13
15
  McpInvalidParamsError,
14
16
  McpMethodNotFoundError,
15
17
  McpPromptNotFoundError,
16
18
  McpResourceNotFoundError,
17
19
  McpToolNotFoundError,
20
+ McpUnauthorizedError,
18
21
  } from "./errors/McpError.ts";
19
22
  export {
20
23
  createErrorResponse,
@@ -115,6 +115,11 @@ export class SseMcpTransport {
115
115
  secure: false,
116
116
  schema: {
117
117
  body: t.json(),
118
+ query: t.object({
119
+ token: t.optional(
120
+ t.text({ description: "API token for authentication" }),
121
+ ),
122
+ }),
118
123
  },
119
124
  handler: async (request) => {
120
125
  try {
@@ -131,12 +136,17 @@ export class SseMcpTransport {
131
136
  const rpcRequest = parseMessage(body);
132
137
 
133
138
  // Build context from request headers
134
- const context: McpContext = {
135
- headers: request.headers as Record<
136
- string,
137
- string | string[] | undefined
138
- >,
139
- };
139
+ const headers = { ...request.headers } as Record<
140
+ string,
141
+ string | string[] | undefined
142
+ >;
143
+
144
+ // Support token as query parameter (for clients that can't set headers)
145
+ if (request.query.token && !headers.authorization) {
146
+ headers.authorization = `Bearer ${request.query.token}`;
147
+ }
148
+
149
+ const context: McpContext = { headers };
140
150
 
141
151
  const response = await this.mcpServer.handleMessage(
142
152
  rpcRequest,
@@ -1,25 +1,7 @@
1
1
  import { $module } from "alepha";
2
2
  import { AlephaDateTime } from "alepha/datetime";
3
3
 
4
- // ---------------------------------------------------------------------------------------------------------------------
5
-
6
- export {
7
- type Page,
8
- type PageQuery,
9
- pageQuerySchema,
10
- pageSchema,
11
- } from "alepha";
12
- export * from "./errors/DbEntityNotFoundError.ts";
13
- export * from "./helpers/parseQueryString.ts";
14
- export * from "./helpers/pgAttr.ts";
15
- export * from "./interfaces/FilterOperators.ts";
16
- export * from "./interfaces/PgQuery.ts";
17
- export * from "./interfaces/PgQueryWhere.ts";
18
- export * from "./primitives/$entity.ts";
19
- export * from "./providers/DatabaseTypeProvider.ts";
20
- export * from "./schemas/legacyIdSchema.ts";
21
-
22
- // ---------------------------------------------------------------------------------------------------------------------
4
+ export * from "./index.shared.ts";
23
5
 
24
6
  export const AlephaPostgres = $module({
25
7
  name: "alepha.postgres",
@@ -0,0 +1,77 @@
1
+ import { $module, type Alepha, t } from "alepha";
2
+ import { AlephaDateTime } from "alepha/datetime";
3
+ import { $entity } from "./primitives/$entity.ts";
4
+ import { $sequence } from "./primitives/$sequence.ts";
5
+ import { DrizzleKitProvider } from "./providers/DrizzleKitProvider.ts";
6
+ import { BunPostgresProvider } from "./providers/drivers/BunPostgresProvider.ts";
7
+ import { BunSqliteProvider } from "./providers/drivers/BunSqliteProvider.ts";
8
+ import { CloudflareD1Provider } from "./providers/drivers/CloudflareD1Provider.ts";
9
+ import { DatabaseProvider } from "./providers/drivers/DatabaseProvider.ts";
10
+ import { PglitePostgresProvider } from "./providers/drivers/PglitePostgresProvider.ts";
11
+ import { RepositoryProvider } from "./providers/RepositoryProvider.ts";
12
+ import { PgRelationManager } from "./services/PgRelationManager.ts";
13
+ import { PostgresModelBuilder } from "./services/PostgresModelBuilder.ts";
14
+ import { QueryManager } from "./services/QueryManager.ts";
15
+ import { Repository } from "./services/Repository.ts";
16
+ import { SqliteModelBuilder } from "./services/SqliteModelBuilder.ts";
17
+
18
+ export * from "./index.shared-server.ts";
19
+ export * from "./providers/drivers/BunPostgresProvider.ts";
20
+ export * from "./providers/drivers/BunSqliteProvider.ts";
21
+
22
+ export const AlephaPostgres = $module({
23
+ name: "alepha.postgres",
24
+ primitives: [$sequence, $entity],
25
+ services: [
26
+ AlephaDateTime,
27
+ DatabaseProvider,
28
+ BunPostgresProvider,
29
+ BunSqliteProvider,
30
+ PglitePostgresProvider,
31
+ CloudflareD1Provider,
32
+ SqliteModelBuilder,
33
+ PostgresModelBuilder,
34
+ DrizzleKitProvider,
35
+ RepositoryProvider,
36
+ Repository,
37
+ PgRelationManager,
38
+ QueryManager,
39
+ ],
40
+ register: (alepha: Alepha) => {
41
+ const env = alepha.parseEnv(
42
+ t.object({
43
+ DATABASE_URL: t.optional(t.text()),
44
+ }),
45
+ );
46
+
47
+ alepha.with(DrizzleKitProvider);
48
+ alepha.with(RepositoryProvider);
49
+
50
+ const url = env.DATABASE_URL;
51
+ const isPostgres = url?.startsWith("postgres:");
52
+
53
+ if (url?.startsWith("cloudflare-d1:")) {
54
+ alepha.with({
55
+ optional: true,
56
+ provide: DatabaseProvider,
57
+ use: CloudflareD1Provider,
58
+ });
59
+ return;
60
+ }
61
+
62
+ if (isPostgres) {
63
+ alepha.with({
64
+ optional: true,
65
+ provide: DatabaseProvider,
66
+ use: BunPostgresProvider,
67
+ });
68
+ return;
69
+ }
70
+
71
+ alepha.with({
72
+ optional: true,
73
+ provide: DatabaseProvider,
74
+ use: BunSqliteProvider,
75
+ });
76
+ },
77
+ });
@@ -0,0 +1,22 @@
1
+ import * as drizzle from "drizzle-orm";
2
+
3
+ export { drizzle };
4
+ export { sql } from "drizzle-orm";
5
+ export * from "drizzle-orm/pg-core";
6
+ export * from "./constants/PG_SYMBOLS.ts";
7
+ export * from "./errors/DbConflictError.ts";
8
+ export * from "./errors/DbError.ts";
9
+ export * from "./errors/DbMigrationError.ts";
10
+ export * from "./errors/DbVersionMismatchError.ts";
11
+ export * from "./index.shared.ts";
12
+ export * from "./primitives/$repository.ts";
13
+ export * from "./primitives/$sequence.ts";
14
+ export * from "./primitives/$transaction.ts";
15
+ export * from "./providers/DrizzleKitProvider.ts";
16
+ export * from "./providers/drivers/CloudflareD1Provider.ts";
17
+ export * from "./providers/drivers/DatabaseProvider.ts";
18
+ export * from "./providers/RepositoryProvider.ts";
19
+ export * from "./schemas/insertSchema.ts";
20
+ export * from "./schemas/updateSchema.ts";
21
+ export * from "./services/Repository.ts";
22
+ export * from "./types/schema.ts";
@@ -0,0 +1,15 @@
1
+ export {
2
+ type Page,
3
+ type PageQuery,
4
+ pageQuerySchema,
5
+ pageSchema,
6
+ } from "alepha";
7
+ export * from "./errors/DbEntityNotFoundError.ts";
8
+ export * from "./helpers/parseQueryString.ts";
9
+ export * from "./helpers/pgAttr.ts";
10
+ export * from "./interfaces/FilterOperators.ts";
11
+ export * from "./interfaces/PgQuery.ts";
12
+ export * from "./interfaces/PgQueryWhere.ts";
13
+ export * from "./primitives/$entity.ts";
14
+ export * from "./providers/DatabaseTypeProvider.ts";
15
+ export * from "./schemas/legacyIdSchema.ts";