alepha 0.14.3 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (317) hide show
  1. package/README.md +2 -5
  2. package/dist/api/audits/index.d.ts +620 -811
  3. package/dist/api/audits/index.d.ts.map +1 -1
  4. package/dist/api/files/index.d.ts +185 -377
  5. package/dist/api/files/index.d.ts.map +1 -1
  6. package/dist/api/files/index.js +0 -1
  7. package/dist/api/files/index.js.map +1 -1
  8. package/dist/api/jobs/index.d.ts +245 -435
  9. package/dist/api/jobs/index.d.ts.map +1 -1
  10. package/dist/api/notifications/index.d.ts +238 -429
  11. package/dist/api/notifications/index.d.ts.map +1 -1
  12. package/dist/api/parameters/index.d.ts +236 -427
  13. package/dist/api/parameters/index.d.ts.map +1 -1
  14. package/dist/api/users/index.browser.js +1 -2
  15. package/dist/api/users/index.browser.js.map +1 -1
  16. package/dist/api/users/index.d.ts +1010 -1196
  17. package/dist/api/users/index.d.ts.map +1 -1
  18. package/dist/api/users/index.js +178 -151
  19. package/dist/api/users/index.js.map +1 -1
  20. package/dist/api/verifications/index.d.ts +17 -17
  21. package/dist/api/verifications/index.d.ts.map +1 -1
  22. package/dist/batch/index.d.ts +122 -122
  23. package/dist/batch/index.d.ts.map +1 -1
  24. package/dist/batch/index.js +1 -2
  25. package/dist/batch/index.js.map +1 -1
  26. package/dist/bucket/index.d.ts +163 -163
  27. package/dist/bucket/index.d.ts.map +1 -1
  28. package/dist/cache/core/index.d.ts +46 -46
  29. package/dist/cache/core/index.d.ts.map +1 -1
  30. package/dist/cache/redis/index.d.ts.map +1 -1
  31. package/dist/cli/index.d.ts +384 -285
  32. package/dist/cli/index.d.ts.map +1 -1
  33. package/dist/cli/index.js +1113 -623
  34. package/dist/cli/index.js.map +1 -1
  35. package/dist/command/index.d.ts +299 -300
  36. package/dist/command/index.d.ts.map +1 -1
  37. package/dist/command/index.js +13 -9
  38. package/dist/command/index.js.map +1 -1
  39. package/dist/core/index.browser.js +445 -103
  40. package/dist/core/index.browser.js.map +1 -1
  41. package/dist/core/index.d.ts +733 -625
  42. package/dist/core/index.d.ts.map +1 -1
  43. package/dist/core/index.js +446 -103
  44. package/dist/core/index.js.map +1 -1
  45. package/dist/core/index.native.js +445 -103
  46. package/dist/core/index.native.js.map +1 -1
  47. package/dist/datetime/index.d.ts +44 -44
  48. package/dist/datetime/index.d.ts.map +1 -1
  49. package/dist/datetime/index.js +4 -4
  50. package/dist/datetime/index.js.map +1 -1
  51. package/dist/email/index.d.ts +97 -50
  52. package/dist/email/index.d.ts.map +1 -1
  53. package/dist/email/index.js +129 -33
  54. package/dist/email/index.js.map +1 -1
  55. package/dist/fake/index.d.ts +7981 -14
  56. package/dist/fake/index.d.ts.map +1 -1
  57. package/dist/file/index.d.ts +523 -390
  58. package/dist/file/index.d.ts.map +1 -1
  59. package/dist/file/index.js +253 -1
  60. package/dist/file/index.js.map +1 -1
  61. package/dist/lock/core/index.d.ts +208 -208
  62. package/dist/lock/core/index.d.ts.map +1 -1
  63. package/dist/lock/redis/index.d.ts.map +1 -1
  64. package/dist/logger/index.d.ts +25 -26
  65. package/dist/logger/index.d.ts.map +1 -1
  66. package/dist/logger/index.js +12 -2
  67. package/dist/logger/index.js.map +1 -1
  68. package/dist/mcp/index.d.ts +197 -197
  69. package/dist/mcp/index.d.ts.map +1 -1
  70. package/dist/mcp/index.js +1 -1
  71. package/dist/mcp/index.js.map +1 -1
  72. package/dist/orm/chunk-DtkW-qnP.js +38 -0
  73. package/dist/orm/index.browser.js.map +1 -1
  74. package/dist/orm/index.bun.js +2814 -0
  75. package/dist/orm/index.bun.js.map +1 -0
  76. package/dist/orm/index.d.ts +1228 -1216
  77. package/dist/orm/index.d.ts.map +1 -1
  78. package/dist/orm/index.js +2041 -1967
  79. package/dist/orm/index.js.map +1 -1
  80. package/dist/queue/core/index.d.ts +248 -248
  81. package/dist/queue/core/index.d.ts.map +1 -1
  82. package/dist/queue/redis/index.d.ts.map +1 -1
  83. package/dist/redis/index.bun.js +285 -0
  84. package/dist/redis/index.bun.js.map +1 -0
  85. package/dist/redis/index.d.ts +118 -136
  86. package/dist/redis/index.d.ts.map +1 -1
  87. package/dist/redis/index.js +18 -38
  88. package/dist/redis/index.js.map +1 -1
  89. package/dist/retry/index.d.ts +69 -69
  90. package/dist/retry/index.d.ts.map +1 -1
  91. package/dist/router/index.d.ts +6 -6
  92. package/dist/router/index.d.ts.map +1 -1
  93. package/dist/scheduler/index.d.ts +25 -25
  94. package/dist/scheduler/index.d.ts.map +1 -1
  95. package/dist/security/index.browser.js +5 -1
  96. package/dist/security/index.browser.js.map +1 -1
  97. package/dist/security/index.d.ts +417 -254
  98. package/dist/security/index.d.ts.map +1 -1
  99. package/dist/security/index.js +386 -86
  100. package/dist/security/index.js.map +1 -1
  101. package/dist/server/auth/index.d.ts +110 -110
  102. package/dist/server/auth/index.d.ts.map +1 -1
  103. package/dist/server/auth/index.js +20 -20
  104. package/dist/server/auth/index.js.map +1 -1
  105. package/dist/server/cache/index.d.ts +62 -47
  106. package/dist/server/cache/index.d.ts.map +1 -1
  107. package/dist/server/cache/index.js +56 -3
  108. package/dist/server/cache/index.js.map +1 -1
  109. package/dist/server/compress/index.d.ts +6 -0
  110. package/dist/server/compress/index.d.ts.map +1 -1
  111. package/dist/server/compress/index.js +36 -1
  112. package/dist/server/compress/index.js.map +1 -1
  113. package/dist/server/cookies/index.d.ts +6 -6
  114. package/dist/server/cookies/index.d.ts.map +1 -1
  115. package/dist/server/cookies/index.js +3 -3
  116. package/dist/server/cookies/index.js.map +1 -1
  117. package/dist/server/core/index.browser.js +2 -2
  118. package/dist/server/core/index.browser.js.map +1 -1
  119. package/dist/server/core/index.d.ts +242 -150
  120. package/dist/server/core/index.d.ts.map +1 -1
  121. package/dist/server/core/index.js +294 -125
  122. package/dist/server/core/index.js.map +1 -1
  123. package/dist/server/cors/index.d.ts +11 -12
  124. package/dist/server/cors/index.d.ts.map +1 -1
  125. package/dist/server/health/index.d.ts +0 -1
  126. package/dist/server/health/index.d.ts.map +1 -1
  127. package/dist/server/helmet/index.d.ts +2 -2
  128. package/dist/server/helmet/index.d.ts.map +1 -1
  129. package/dist/server/links/index.browser.js.map +1 -1
  130. package/dist/server/links/index.d.ts +123 -124
  131. package/dist/server/links/index.d.ts.map +1 -1
  132. package/dist/server/links/index.js +1 -2
  133. package/dist/server/links/index.js.map +1 -1
  134. package/dist/server/metrics/index.d.ts.map +1 -1
  135. package/dist/server/multipart/index.d.ts +6 -6
  136. package/dist/server/multipart/index.d.ts.map +1 -1
  137. package/dist/server/proxy/index.d.ts +102 -103
  138. package/dist/server/proxy/index.d.ts.map +1 -1
  139. package/dist/server/rate-limit/index.d.ts +16 -16
  140. package/dist/server/rate-limit/index.d.ts.map +1 -1
  141. package/dist/server/static/index.d.ts +44 -44
  142. package/dist/server/static/index.d.ts.map +1 -1
  143. package/dist/server/static/index.js +4 -0
  144. package/dist/server/static/index.js.map +1 -1
  145. package/dist/server/swagger/index.d.ts +48 -49
  146. package/dist/server/swagger/index.d.ts.map +1 -1
  147. package/dist/server/swagger/index.js +3 -5
  148. package/dist/server/swagger/index.js.map +1 -1
  149. package/dist/sms/index.d.ts +13 -11
  150. package/dist/sms/index.d.ts.map +1 -1
  151. package/dist/sms/index.js +7 -7
  152. package/dist/sms/index.js.map +1 -1
  153. package/dist/thread/index.d.ts +71 -72
  154. package/dist/thread/index.d.ts.map +1 -1
  155. package/dist/topic/core/index.d.ts +318 -318
  156. package/dist/topic/core/index.d.ts.map +1 -1
  157. package/dist/topic/redis/index.d.ts +6 -6
  158. package/dist/topic/redis/index.d.ts.map +1 -1
  159. package/dist/vite/index.d.ts +5805 -249
  160. package/dist/vite/index.d.ts.map +1 -1
  161. package/dist/vite/index.js +599 -513
  162. package/dist/vite/index.js.map +1 -1
  163. package/dist/websocket/index.browser.js +6 -6
  164. package/dist/websocket/index.browser.js.map +1 -1
  165. package/dist/websocket/index.d.ts +247 -247
  166. package/dist/websocket/index.d.ts.map +1 -1
  167. package/dist/websocket/index.js +6 -6
  168. package/dist/websocket/index.js.map +1 -1
  169. package/package.json +9 -14
  170. package/src/api/files/controllers/AdminFileStatsController.ts +0 -1
  171. package/src/api/users/atoms/realmAuthSettingsAtom.ts +5 -0
  172. package/src/api/users/controllers/{UserRealmController.ts → RealmController.ts} +11 -11
  173. package/src/api/users/entities/users.ts +1 -1
  174. package/src/api/users/index.ts +8 -8
  175. package/src/api/users/primitives/{$userRealm.ts → $realm.ts} +17 -19
  176. package/src/api/users/providers/{UserRealmProvider.ts → RealmProvider.ts} +26 -30
  177. package/src/api/users/schemas/{userRealmConfigSchema.ts → realmConfigSchema.ts} +2 -2
  178. package/src/api/users/services/CredentialService.ts +7 -7
  179. package/src/api/users/services/IdentityService.ts +4 -4
  180. package/src/api/users/services/RegistrationService.spec.ts +25 -27
  181. package/src/api/users/services/RegistrationService.ts +38 -27
  182. package/src/api/users/services/SessionCrudService.ts +3 -3
  183. package/src/api/users/services/SessionService.spec.ts +3 -3
  184. package/src/api/users/services/SessionService.ts +28 -9
  185. package/src/api/users/services/UserService.ts +7 -7
  186. package/src/batch/providers/BatchProvider.ts +1 -2
  187. package/src/cli/apps/AlephaCli.ts +0 -2
  188. package/src/cli/apps/AlephaPackageBuilderCli.ts +38 -19
  189. package/src/cli/assets/apiHelloControllerTs.ts +18 -0
  190. package/src/cli/assets/apiIndexTs.ts +16 -0
  191. package/src/cli/assets/claudeMd.ts +303 -0
  192. package/src/cli/assets/mainBrowserTs.ts +2 -2
  193. package/src/cli/assets/mainServerTs.ts +24 -0
  194. package/src/cli/assets/webAppRouterTs.ts +15 -0
  195. package/src/cli/assets/webHelloComponentTsx.ts +16 -0
  196. package/src/cli/assets/webIndexTs.ts +16 -0
  197. package/src/cli/atoms/buildOptions.ts +88 -0
  198. package/src/cli/commands/build.ts +70 -87
  199. package/src/cli/commands/db.ts +21 -22
  200. package/src/cli/commands/deploy.ts +17 -5
  201. package/src/cli/commands/dev.ts +22 -14
  202. package/src/cli/commands/format.ts +8 -2
  203. package/src/cli/commands/gen/env.ts +53 -0
  204. package/src/cli/commands/gen/openapi.ts +1 -1
  205. package/src/cli/commands/gen/resource.ts +15 -0
  206. package/src/cli/commands/gen.ts +7 -1
  207. package/src/cli/commands/init.ts +74 -30
  208. package/src/cli/commands/lint.ts +8 -2
  209. package/src/cli/commands/test.ts +8 -3
  210. package/src/cli/commands/typecheck.ts +5 -1
  211. package/src/cli/commands/verify.ts +5 -3
  212. package/src/cli/defineConfig.ts +49 -7
  213. package/src/cli/index.ts +0 -1
  214. package/src/cli/services/AlephaCliUtils.ts +39 -589
  215. package/src/cli/services/PackageManagerUtils.ts +301 -0
  216. package/src/cli/services/ProjectScaffolder.ts +306 -0
  217. package/src/command/helpers/Runner.spec.ts +2 -2
  218. package/src/command/helpers/Runner.ts +16 -4
  219. package/src/command/primitives/$command.ts +0 -6
  220. package/src/command/providers/CliProvider.ts +1 -3
  221. package/src/core/Alepha.ts +42 -0
  222. package/src/core/__tests__/Alepha-graph.spec.ts +4 -0
  223. package/src/core/index.shared.ts +1 -0
  224. package/src/core/index.ts +2 -0
  225. package/src/core/primitives/$hook.ts +6 -2
  226. package/src/core/primitives/$module.spec.ts +4 -0
  227. package/src/core/providers/AlsProvider.ts +1 -1
  228. package/src/core/providers/CodecManager.spec.ts +12 -6
  229. package/src/core/providers/CodecManager.ts +26 -6
  230. package/src/core/providers/EventManager.ts +169 -13
  231. package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +621 -0
  232. package/src/core/providers/KeylessJsonSchemaCodec.ts +407 -0
  233. package/src/core/providers/StateManager.spec.ts +27 -16
  234. package/src/email/providers/LocalEmailProvider.spec.ts +111 -87
  235. package/src/email/providers/LocalEmailProvider.ts +52 -15
  236. package/src/email/providers/NodemailerEmailProvider.ts +167 -56
  237. package/src/file/errors/FileError.ts +7 -0
  238. package/src/file/index.ts +9 -1
  239. package/src/file/providers/MemoryFileSystemProvider.ts +393 -0
  240. package/src/logger/index.ts +15 -3
  241. package/src/mcp/transports/StdioMcpTransport.ts +1 -1
  242. package/src/orm/index.browser.ts +1 -19
  243. package/src/orm/index.bun.ts +77 -0
  244. package/src/orm/index.shared-server.ts +22 -0
  245. package/src/orm/index.shared.ts +15 -0
  246. package/src/orm/index.ts +13 -39
  247. package/src/orm/providers/drivers/BunPostgresProvider.ts +3 -5
  248. package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -1
  249. package/src/orm/providers/drivers/CloudflareD1Provider.ts +4 -0
  250. package/src/orm/providers/drivers/DatabaseProvider.ts +4 -0
  251. package/src/orm/providers/drivers/PglitePostgresProvider.ts +4 -0
  252. package/src/orm/services/Repository.ts +8 -0
  253. package/src/queue/core/providers/WorkerProvider.spec.ts +48 -32
  254. package/src/redis/index.bun.ts +35 -0
  255. package/src/redis/providers/BunRedisProvider.ts +12 -43
  256. package/src/redis/providers/BunRedisSubscriberProvider.ts +2 -3
  257. package/src/redis/providers/NodeRedisProvider.ts +16 -34
  258. package/src/{server/security → security}/__tests__/BasicAuth.spec.ts +11 -11
  259. package/src/{server/security → security}/__tests__/ServerSecurityProvider-realm.spec.ts +21 -16
  260. package/src/{server/security/providers → security/__tests__}/ServerSecurityProvider.spec.ts +5 -5
  261. package/src/security/index.browser.ts +5 -0
  262. package/src/security/index.ts +90 -7
  263. package/src/security/primitives/{$realm.spec.ts → $issuer.spec.ts} +11 -11
  264. package/src/security/primitives/{$realm.ts → $issuer.ts} +20 -17
  265. package/src/security/primitives/$role.ts +5 -5
  266. package/src/security/primitives/$serviceAccount.spec.ts +5 -5
  267. package/src/security/primitives/$serviceAccount.ts +3 -3
  268. package/src/{server/security → security}/providers/ServerSecurityProvider.ts +5 -7
  269. package/src/server/auth/primitives/$auth.ts +10 -10
  270. package/src/server/auth/primitives/$authCredentials.ts +3 -3
  271. package/src/server/auth/primitives/$authGithub.ts +3 -3
  272. package/src/server/auth/primitives/$authGoogle.ts +3 -3
  273. package/src/server/auth/providers/ServerAuthProvider.ts +13 -13
  274. package/src/server/cache/providers/ServerCacheProvider.spec.ts +183 -0
  275. package/src/server/cache/providers/ServerCacheProvider.ts +95 -10
  276. package/src/server/compress/providers/ServerCompressProvider.ts +61 -2
  277. package/src/server/cookies/providers/ServerCookiesProvider.ts +3 -3
  278. package/src/server/core/helpers/ServerReply.ts +2 -2
  279. package/src/server/core/providers/NodeHttpServerProvider.ts +25 -6
  280. package/src/server/core/providers/ServerBodyParserProvider.ts +19 -23
  281. package/src/server/core/providers/ServerLoggerProvider.ts +23 -19
  282. package/src/server/core/providers/ServerProvider.ts +155 -22
  283. package/src/server/core/providers/ServerRouterProvider.ts +259 -115
  284. package/src/server/core/providers/ServerTimingProvider.ts +2 -2
  285. package/src/server/links/index.ts +1 -1
  286. package/src/server/links/providers/LinkProvider.ts +1 -1
  287. package/src/server/static/providers/ServerStaticProvider.ts +10 -0
  288. package/src/server/swagger/index.ts +1 -1
  289. package/src/server/swagger/providers/ServerSwaggerProvider.ts +5 -8
  290. package/src/sms/providers/LocalSmsProvider.spec.ts +153 -111
  291. package/src/sms/providers/LocalSmsProvider.ts +8 -7
  292. package/src/vite/helpers/boot.ts +28 -17
  293. package/src/vite/helpers/importViteReact.ts +13 -0
  294. package/src/vite/index.ts +1 -21
  295. package/src/vite/plugins/viteAlephaDev.ts +16 -1
  296. package/src/vite/plugins/viteAlephaSsrPreload.ts +222 -0
  297. package/src/vite/tasks/buildClient.ts +11 -0
  298. package/src/vite/tasks/buildServer.ts +59 -4
  299. package/src/vite/tasks/devServer.ts +71 -0
  300. package/src/vite/tasks/generateCloudflare.ts +7 -0
  301. package/src/vite/tasks/index.ts +2 -1
  302. package/dist/server/security/index.browser.js +0 -13
  303. package/dist/server/security/index.browser.js.map +0 -1
  304. package/dist/server/security/index.d.ts +0 -173
  305. package/dist/server/security/index.d.ts.map +0 -1
  306. package/dist/server/security/index.js +0 -311
  307. package/dist/server/security/index.js.map +0 -1
  308. package/src/cli/assets/appRouterTs.ts +0 -9
  309. package/src/cli/assets/mainTs.ts +0 -13
  310. package/src/cli/assets/viteConfigTs.ts +0 -14
  311. package/src/cli/commands/run.ts +0 -24
  312. package/src/server/security/index.browser.ts +0 -10
  313. package/src/server/security/index.ts +0 -94
  314. package/src/vite/plugins/viteAlepha.ts +0 -37
  315. package/src/vite/plugins/viteAlephaBuild.ts +0 -281
  316. /package/src/{server/security → security}/primitives/$basicAuth.ts +0 -0
  317. /package/src/{server/security → security}/providers/ServerBasicAuthProvider.ts +0 -0
package/src/file/index.ts CHANGED
@@ -1,11 +1,14 @@
1
1
  import { $module } from "alepha";
2
2
  import { FileSystemProvider } from "./providers/FileSystemProvider.ts";
3
+ import { MemoryFileSystemProvider } from "./providers/MemoryFileSystemProvider.ts";
3
4
  import { NodeFileSystemProvider } from "./providers/NodeFileSystemProvider.ts";
4
5
  import { FileDetector } from "./services/FileDetector.ts";
5
6
 
6
7
  // ---------------------------------------------------------------------------------------------------------------------
7
8
 
9
+ export * from "./errors/FileError.ts";
8
10
  export * from "./providers/FileSystemProvider.ts";
11
+ export * from "./providers/MemoryFileSystemProvider.ts";
9
12
  export * from "./providers/NodeFileSystemProvider.ts";
10
13
  export * from "./services/FileDetector.ts";
11
14
 
@@ -25,7 +28,12 @@ export * from "./services/FileDetector.ts";
25
28
  export const AlephaFile = $module({
26
29
  name: "alepha.file",
27
30
  primitives: [],
28
- services: [FileDetector, FileSystemProvider, NodeFileSystemProvider],
31
+ services: [
32
+ FileDetector,
33
+ FileSystemProvider,
34
+ MemoryFileSystemProvider,
35
+ NodeFileSystemProvider,
36
+ ],
29
37
  register: (alepha) =>
30
38
  alepha.with({
31
39
  optional: true,
@@ -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
+ }
@@ -199,16 +199,28 @@ const envSchema = t.object({
199
199
  * LOG_LEVEL=my.module.name:debug,info # Set debug level for my.module.name and info for all other modules
200
200
  * LOG_LEVEL=alepha:trace, info # Set trace level for all alepha modules and info for all other modules
201
201
  */
202
- LOG_LEVEL: t.optional(t.text({ lowercase: true })),
202
+ LOG_LEVEL: t.optional(
203
+ t.text({
204
+ description: `Application log level on startup.
205
+ Levels are: trace, debug, info, warn, error, silent
206
+ Level can be set for a specific module:
207
+ "my.module.name:debug,info" -> Set debug level for my.module.name and info for all other modules
208
+ "alepha:trace,info" -> Set trace level for all alepha modules and info for all other modules`,
209
+ lowercase: true,
210
+ }),
211
+ ),
203
212
 
204
213
  /**
205
214
  * Built-in log formats.
206
215
  * - "json" - JSON format, useful for structured logging and log aggregation. {@link JsonFormatterProvider}
207
216
  * - "pretty" - Simple text format, human-readable, with colors. {@link PrettyFormatterProvider}
208
- * - "raw" - Raw format, no formatting, just the message. {@link RawFormatterProvider}
217
+ * - "raw" - Raw format, no formatting, just the message. {@link RawFormatterProvider}
209
218
  */
210
219
  LOG_FORMAT: t.optional(
211
- t.enum(["json", "pretty", "raw"], { lowercase: true }),
220
+ t.enum(["json", "pretty", "raw"], {
221
+ description: "Default log format for the application.",
222
+ lowercase: true,
223
+ }),
212
224
  ),
213
225
  });
214
226
 
@@ -121,6 +121,6 @@ export class StdioMcpTransport {
121
121
  */
122
122
  protected send(message: object): void {
123
123
  const json = JSON.stringify(message);
124
- process.stdout.write(json + "\n");
124
+ process.stdout.write(`${json}\n`);
125
125
  }
126
126
  }
@@ -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";