alepha 0.14.4 → 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 (277) hide show
  1. package/README.md +1 -4
  2. package/dist/api/audits/index.d.ts +619 -731
  3. package/dist/api/audits/index.d.ts.map +1 -1
  4. package/dist/api/files/index.d.ts +185 -298
  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 -356
  9. package/dist/api/jobs/index.d.ts.map +1 -1
  10. package/dist/api/notifications/index.d.ts +238 -350
  11. package/dist/api/notifications/index.d.ts.map +1 -1
  12. package/dist/api/parameters/index.d.ts +499 -611
  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 +1697 -1804
  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 +132 -132
  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 +302 -299
  32. package/dist/cli/index.d.ts.map +1 -1
  33. package/dist/cli/index.js +966 -564
  34. package/dist/cli/index.js.map +1 -1
  35. package/dist/command/index.d.ts +303 -299
  36. package/dist/command/index.d.ts.map +1 -1
  37. package/dist/command/index.js +11 -7
  38. package/dist/command/index.js.map +1 -1
  39. package/dist/core/index.browser.js +419 -99
  40. package/dist/core/index.browser.js.map +1 -1
  41. package/dist/core/index.d.ts +718 -625
  42. package/dist/core/index.d.ts.map +1 -1
  43. package/dist/core/index.js +420 -99
  44. package/dist/core/index.js.map +1 -1
  45. package/dist/core/index.native.js +419 -99
  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/mcp/index.d.ts +197 -197
  67. package/dist/mcp/index.d.ts.map +1 -1
  68. package/dist/orm/chunk-DtkW-qnP.js +38 -0
  69. package/dist/orm/index.browser.js.map +1 -1
  70. package/dist/orm/index.bun.js +2814 -0
  71. package/dist/orm/index.bun.js.map +1 -0
  72. package/dist/orm/index.d.ts +1205 -1057
  73. package/dist/orm/index.d.ts.map +1 -1
  74. package/dist/orm/index.js +2056 -1753
  75. package/dist/orm/index.js.map +1 -1
  76. package/dist/queue/core/index.d.ts +248 -248
  77. package/dist/queue/core/index.d.ts.map +1 -1
  78. package/dist/queue/redis/index.d.ts.map +1 -1
  79. package/dist/redis/index.bun.js +285 -0
  80. package/dist/redis/index.bun.js.map +1 -0
  81. package/dist/redis/index.d.ts +118 -136
  82. package/dist/redis/index.d.ts.map +1 -1
  83. package/dist/redis/index.js +18 -38
  84. package/dist/redis/index.js.map +1 -1
  85. package/dist/retry/index.d.ts +69 -69
  86. package/dist/retry/index.d.ts.map +1 -1
  87. package/dist/router/index.d.ts +6 -6
  88. package/dist/router/index.d.ts.map +1 -1
  89. package/dist/scheduler/index.d.ts +25 -25
  90. package/dist/scheduler/index.d.ts.map +1 -1
  91. package/dist/security/index.browser.js +5 -1
  92. package/dist/security/index.browser.js.map +1 -1
  93. package/dist/security/index.d.ts +417 -254
  94. package/dist/security/index.d.ts.map +1 -1
  95. package/dist/security/index.js +386 -86
  96. package/dist/security/index.js.map +1 -1
  97. package/dist/server/auth/index.d.ts +277 -277
  98. package/dist/server/auth/index.d.ts.map +1 -1
  99. package/dist/server/auth/index.js +20 -20
  100. package/dist/server/auth/index.js.map +1 -1
  101. package/dist/server/cache/index.d.ts +60 -57
  102. package/dist/server/cache/index.d.ts.map +1 -1
  103. package/dist/server/cache/index.js +1 -1
  104. package/dist/server/cache/index.js.map +1 -1
  105. package/dist/server/compress/index.d.ts +3 -3
  106. package/dist/server/compress/index.d.ts.map +1 -1
  107. package/dist/server/cookies/index.d.ts +6 -6
  108. package/dist/server/cookies/index.d.ts.map +1 -1
  109. package/dist/server/cookies/index.js +3 -3
  110. package/dist/server/cookies/index.js.map +1 -1
  111. package/dist/server/core/index.d.ts +242 -150
  112. package/dist/server/core/index.d.ts.map +1 -1
  113. package/dist/server/core/index.js +288 -122
  114. package/dist/server/core/index.js.map +1 -1
  115. package/dist/server/cors/index.d.ts +11 -12
  116. package/dist/server/cors/index.d.ts.map +1 -1
  117. package/dist/server/health/index.d.ts +0 -1
  118. package/dist/server/health/index.d.ts.map +1 -1
  119. package/dist/server/helmet/index.d.ts +2 -2
  120. package/dist/server/helmet/index.d.ts.map +1 -1
  121. package/dist/server/links/index.browser.js.map +1 -1
  122. package/dist/server/links/index.d.ts +84 -85
  123. package/dist/server/links/index.d.ts.map +1 -1
  124. package/dist/server/links/index.js +1 -2
  125. package/dist/server/links/index.js.map +1 -1
  126. package/dist/server/metrics/index.d.ts.map +1 -1
  127. package/dist/server/multipart/index.d.ts +6 -6
  128. package/dist/server/multipart/index.d.ts.map +1 -1
  129. package/dist/server/proxy/index.d.ts +102 -103
  130. package/dist/server/proxy/index.d.ts.map +1 -1
  131. package/dist/server/rate-limit/index.d.ts +16 -16
  132. package/dist/server/rate-limit/index.d.ts.map +1 -1
  133. package/dist/server/static/index.d.ts +44 -44
  134. package/dist/server/static/index.d.ts.map +1 -1
  135. package/dist/server/swagger/index.d.ts +48 -49
  136. package/dist/server/swagger/index.d.ts.map +1 -1
  137. package/dist/server/swagger/index.js +1 -2
  138. package/dist/server/swagger/index.js.map +1 -1
  139. package/dist/sms/index.d.ts +13 -11
  140. package/dist/sms/index.d.ts.map +1 -1
  141. package/dist/sms/index.js +7 -7
  142. package/dist/sms/index.js.map +1 -1
  143. package/dist/thread/index.d.ts +71 -72
  144. package/dist/thread/index.d.ts.map +1 -1
  145. package/dist/topic/core/index.d.ts +318 -318
  146. package/dist/topic/core/index.d.ts.map +1 -1
  147. package/dist/topic/redis/index.d.ts +6 -6
  148. package/dist/topic/redis/index.d.ts.map +1 -1
  149. package/dist/vite/index.d.ts +5720 -159
  150. package/dist/vite/index.d.ts.map +1 -1
  151. package/dist/vite/index.js +41 -18
  152. package/dist/vite/index.js.map +1 -1
  153. package/dist/websocket/index.browser.js +6 -6
  154. package/dist/websocket/index.browser.js.map +1 -1
  155. package/dist/websocket/index.d.ts +247 -247
  156. package/dist/websocket/index.d.ts.map +1 -1
  157. package/dist/websocket/index.js +6 -6
  158. package/dist/websocket/index.js.map +1 -1
  159. package/package.json +9 -14
  160. package/src/api/files/controllers/AdminFileStatsController.ts +0 -1
  161. package/src/api/users/atoms/realmAuthSettingsAtom.ts +5 -0
  162. package/src/api/users/controllers/{UserRealmController.ts → RealmController.ts} +11 -11
  163. package/src/api/users/entities/users.ts +1 -1
  164. package/src/api/users/index.ts +8 -8
  165. package/src/api/users/primitives/{$userRealm.ts → $realm.ts} +17 -19
  166. package/src/api/users/providers/{UserRealmProvider.ts → RealmProvider.ts} +26 -30
  167. package/src/api/users/schemas/{userRealmConfigSchema.ts → realmConfigSchema.ts} +2 -2
  168. package/src/api/users/services/CredentialService.ts +7 -7
  169. package/src/api/users/services/IdentityService.ts +4 -4
  170. package/src/api/users/services/RegistrationService.spec.ts +25 -27
  171. package/src/api/users/services/RegistrationService.ts +38 -27
  172. package/src/api/users/services/SessionCrudService.ts +3 -3
  173. package/src/api/users/services/SessionService.spec.ts +3 -3
  174. package/src/api/users/services/SessionService.ts +28 -9
  175. package/src/api/users/services/UserService.ts +7 -7
  176. package/src/batch/providers/BatchProvider.ts +1 -2
  177. package/src/cli/apps/AlephaPackageBuilderCli.ts +38 -19
  178. package/src/cli/assets/apiHelloControllerTs.ts +18 -0
  179. package/src/cli/assets/apiIndexTs.ts +16 -0
  180. package/src/cli/assets/claudeMd.ts +303 -0
  181. package/src/cli/assets/mainBrowserTs.ts +2 -2
  182. package/src/cli/assets/mainServerTs.ts +24 -0
  183. package/src/cli/assets/webAppRouterTs.ts +15 -0
  184. package/src/cli/assets/webHelloComponentTsx.ts +16 -0
  185. package/src/cli/assets/webIndexTs.ts +16 -0
  186. package/src/cli/commands/build.ts +41 -21
  187. package/src/cli/commands/db.ts +21 -18
  188. package/src/cli/commands/deploy.ts +17 -5
  189. package/src/cli/commands/dev.ts +13 -17
  190. package/src/cli/commands/format.ts +8 -2
  191. package/src/cli/commands/init.ts +74 -29
  192. package/src/cli/commands/lint.ts +8 -2
  193. package/src/cli/commands/test.ts +8 -2
  194. package/src/cli/commands/typecheck.ts +5 -1
  195. package/src/cli/commands/verify.ts +4 -2
  196. package/src/cli/services/AlephaCliUtils.ts +39 -600
  197. package/src/cli/services/PackageManagerUtils.ts +301 -0
  198. package/src/cli/services/ProjectScaffolder.ts +306 -0
  199. package/src/command/helpers/Runner.ts +15 -3
  200. package/src/core/__tests__/Alepha-graph.spec.ts +4 -0
  201. package/src/core/index.shared.ts +1 -0
  202. package/src/core/index.ts +2 -0
  203. package/src/core/primitives/$hook.ts +6 -2
  204. package/src/core/primitives/$module.spec.ts +4 -0
  205. package/src/core/providers/AlsProvider.ts +1 -1
  206. package/src/core/providers/CodecManager.spec.ts +12 -6
  207. package/src/core/providers/CodecManager.ts +26 -6
  208. package/src/core/providers/EventManager.ts +169 -13
  209. package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +621 -0
  210. package/src/core/providers/KeylessJsonSchemaCodec.ts +407 -0
  211. package/src/core/providers/StateManager.spec.ts +27 -16
  212. package/src/email/providers/LocalEmailProvider.spec.ts +111 -87
  213. package/src/email/providers/LocalEmailProvider.ts +52 -15
  214. package/src/email/providers/NodemailerEmailProvider.ts +167 -56
  215. package/src/file/errors/FileError.ts +7 -0
  216. package/src/file/index.ts +9 -1
  217. package/src/file/providers/MemoryFileSystemProvider.ts +393 -0
  218. package/src/orm/index.browser.ts +1 -19
  219. package/src/orm/index.bun.ts +77 -0
  220. package/src/orm/index.shared-server.ts +22 -0
  221. package/src/orm/index.shared.ts +15 -0
  222. package/src/orm/index.ts +19 -39
  223. package/src/orm/providers/drivers/BunPostgresProvider.ts +3 -5
  224. package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -1
  225. package/src/orm/providers/drivers/CloudflareD1Provider.ts +4 -0
  226. package/src/orm/providers/drivers/DatabaseProvider.ts +4 -0
  227. package/src/orm/providers/drivers/PglitePostgresProvider.ts +4 -0
  228. package/src/orm/services/Repository.ts +8 -0
  229. package/src/redis/index.bun.ts +35 -0
  230. package/src/redis/providers/BunRedisProvider.ts +12 -43
  231. package/src/redis/providers/BunRedisSubscriberProvider.ts +2 -3
  232. package/src/redis/providers/NodeRedisProvider.ts +16 -34
  233. package/src/{server/security → security}/__tests__/BasicAuth.spec.ts +11 -11
  234. package/src/{server/security → security}/__tests__/ServerSecurityProvider-realm.spec.ts +21 -16
  235. package/src/{server/security/providers → security/__tests__}/ServerSecurityProvider.spec.ts +5 -5
  236. package/src/security/index.browser.ts +5 -0
  237. package/src/security/index.ts +90 -7
  238. package/src/security/primitives/{$realm.spec.ts → $issuer.spec.ts} +11 -11
  239. package/src/security/primitives/{$realm.ts → $issuer.ts} +20 -17
  240. package/src/security/primitives/$role.ts +5 -5
  241. package/src/security/primitives/$serviceAccount.spec.ts +5 -5
  242. package/src/security/primitives/$serviceAccount.ts +3 -3
  243. package/src/{server/security → security}/providers/ServerSecurityProvider.ts +5 -7
  244. package/src/server/auth/primitives/$auth.ts +10 -10
  245. package/src/server/auth/primitives/$authCredentials.ts +3 -3
  246. package/src/server/auth/primitives/$authGithub.ts +3 -3
  247. package/src/server/auth/primitives/$authGoogle.ts +3 -3
  248. package/src/server/auth/providers/ServerAuthProvider.ts +13 -13
  249. package/src/server/cache/providers/ServerCacheProvider.ts +1 -1
  250. package/src/server/cookies/providers/ServerCookiesProvider.ts +3 -3
  251. package/src/server/core/providers/NodeHttpServerProvider.ts +25 -6
  252. package/src/server/core/providers/ServerBodyParserProvider.ts +19 -23
  253. package/src/server/core/providers/ServerLoggerProvider.ts +23 -19
  254. package/src/server/core/providers/ServerProvider.ts +144 -21
  255. package/src/server/core/providers/ServerRouterProvider.ts +259 -115
  256. package/src/server/core/providers/ServerTimingProvider.ts +2 -2
  257. package/src/server/links/index.ts +1 -1
  258. package/src/server/links/providers/LinkProvider.ts +1 -1
  259. package/src/server/swagger/index.ts +1 -1
  260. package/src/sms/providers/LocalSmsProvider.spec.ts +153 -111
  261. package/src/sms/providers/LocalSmsProvider.ts +8 -7
  262. package/src/vite/helpers/boot.ts +28 -17
  263. package/src/vite/tasks/buildServer.ts +12 -1
  264. package/src/vite/tasks/devServer.ts +3 -1
  265. package/src/vite/tasks/generateCloudflare.ts +7 -0
  266. package/dist/server/security/index.browser.js +0 -13
  267. package/dist/server/security/index.browser.js.map +0 -1
  268. package/dist/server/security/index.d.ts +0 -173
  269. package/dist/server/security/index.d.ts.map +0 -1
  270. package/dist/server/security/index.js +0 -311
  271. package/dist/server/security/index.js.map +0 -1
  272. package/src/cli/assets/appRouterTs.ts +0 -9
  273. package/src/cli/assets/mainTs.ts +0 -13
  274. package/src/server/security/index.browser.ts +0 -10
  275. package/src/server/security/index.ts +0 -94
  276. /package/src/{server/security → security}/primitives/$basicAuth.ts +0 -0
  277. /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
+ }
@@ -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";
package/src/orm/index.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { $module, type Alepha, t } from "alepha";
2
2
  import { AlephaDateTime } from "alepha/datetime";
3
- import * as drizzle from "drizzle-orm";
4
3
  import { $entity } from "./primitives/$entity.ts";
5
- import { $repository } from "./primitives/$repository.ts";
6
4
  import { $sequence } from "./primitives/$sequence.ts";
7
5
  import { DrizzleKitProvider } from "./providers/DrizzleKitProvider.ts";
6
+ import { BunPostgresProvider } from "./providers/drivers/BunPostgresProvider.ts";
7
+ import { BunSqliteProvider } from "./providers/drivers/BunSqliteProvider.ts";
8
8
  import { CloudflareD1Provider } from "./providers/drivers/CloudflareD1Provider.ts";
9
9
  import { DatabaseProvider } from "./providers/drivers/DatabaseProvider.ts";
10
10
  import { NodePostgresProvider } from "./providers/drivers/NodePostgresProvider.ts";
@@ -88,48 +88,21 @@ declare module "alepha" {
88
88
 
89
89
  // ---------------------------------------------------------------------------------------------------------------------
90
90
 
91
- export { drizzle };
92
- export {
93
- type Page,
94
- type PageQuery,
95
- pageQuerySchema,
96
- pageSchema,
97
- } from "alepha";
98
- export { sql } from "drizzle-orm";
99
- export * from "drizzle-orm/pg-core";
100
- export * from "./constants/PG_SYMBOLS.ts";
101
- export * from "./errors/DbConflictError.ts";
102
- export * from "./errors/DbEntityNotFoundError.ts";
103
- export * from "./errors/DbError.ts";
104
- export * from "./errors/DbMigrationError.ts";
105
- export * from "./errors/DbVersionMismatchError.ts";
106
- export * from "./helpers/parseQueryString.ts";
107
- export * from "./helpers/pgAttr.ts";
108
- export * from "./interfaces/FilterOperators.ts";
109
- export * from "./interfaces/PgQuery.ts";
110
- export * from "./interfaces/PgQueryWhere.ts";
111
- export * from "./primitives/$entity.ts";
112
- export * from "./primitives/$repository.ts";
113
- export * from "./primitives/$sequence.ts";
114
- export * from "./primitives/$transaction.ts";
115
- export * from "./providers/DatabaseTypeProvider.ts";
116
- export * from "./providers/DrizzleKitProvider.ts";
117
- export * from "./providers/drivers/CloudflareD1Provider.ts";
118
- export * from "./providers/drivers/DatabaseProvider.ts";
91
+ export * from "./index.shared-server.ts";
92
+ export * from "./providers/drivers/BunPostgresProvider.ts";
93
+ export * from "./providers/drivers/BunSqliteProvider.ts";
119
94
  export * from "./providers/drivers/NodePostgresProvider.ts";
120
95
  export * from "./providers/drivers/NodeSqliteProvider.ts";
121
- export * from "./providers/RepositoryProvider.ts";
122
- export * from "./schemas/insertSchema.ts";
123
- export * from "./schemas/legacyIdSchema.ts";
124
- export * from "./schemas/updateSchema.ts";
125
- export * from "./services/Repository.ts";
126
- export * from "./types/schema.ts";
127
96
 
128
97
  // ---------------------------------------------------------------------------------------------------------------------
129
98
 
130
99
  /**
131
100
  * Postgres client based on Drizzle ORM, Alepha type-safe friendly.
132
101
  *
102
+ * Automatically selects the appropriate provider based on runtime:
103
+ * - Bun: Uses `BunPostgresProvider` or `BunSqliteProvider`
104
+ * - Node.js: Uses `NodePostgresProvider` or `NodeSqliteProvider`
105
+ *
133
106
  * ```ts
134
107
  * import { t } from "alepha";
135
108
  * import { $entity, $repository, db } from "alepha/postgres";
@@ -168,6 +141,10 @@ export * from "./types/schema.ts";
168
141
  * @see {@link $sequence}
169
142
  * @see {@link $repository}
170
143
  * @see {@link $transaction}
144
+ * @see {@link NodePostgresProvider} - Node.js Postgres implementation
145
+ * @see {@link NodeSqliteProvider} - Node.js SQLite implementation
146
+ * @see {@link BunPostgresProvider} - Bun Postgres implementation
147
+ * @see {@link BunSqliteProvider} - Bun SQLite implementation
171
148
  * @module alepha.postgres
172
149
  */
173
150
  export const AlephaPostgres = $module({
@@ -177,8 +154,10 @@ export const AlephaPostgres = $module({
177
154
  AlephaDateTime,
178
155
  DatabaseProvider,
179
156
  NodePostgresProvider,
180
- PglitePostgresProvider,
181
157
  NodeSqliteProvider,
158
+ BunPostgresProvider,
159
+ BunSqliteProvider,
160
+ PglitePostgresProvider,
182
161
  CloudflareD1Provider,
183
162
  SqliteModelBuilder,
184
163
  PostgresModelBuilder,
@@ -204,6 +183,7 @@ export const AlephaPostgres = $module({
204
183
  const isSqlite = url?.startsWith("sqlite:");
205
184
  const isMemory = url?.includes(":memory:");
206
185
  const isFile = !!url && !isPostgres && !isMemory;
186
+ const isBun = alepha.isBun();
207
187
 
208
188
  if (url?.startsWith("cloudflare-d1:")) {
209
189
  alepha.with({
@@ -227,7 +207,7 @@ export const AlephaPostgres = $module({
227
207
  alepha.with({
228
208
  optional: true,
229
209
  provide: DatabaseProvider,
230
- use: NodePostgresProvider,
210
+ use: isBun ? BunPostgresProvider : NodePostgresProvider,
231
211
  });
232
212
  return;
233
213
  }
@@ -235,7 +215,7 @@ export const AlephaPostgres = $module({
235
215
  alepha.with({
236
216
  optional: true,
237
217
  provide: DatabaseProvider,
238
- use: NodeSqliteProvider,
218
+ use: isBun ? BunSqliteProvider : NodeSqliteProvider,
239
219
  });
240
220
  },
241
221
  });