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
@@ -27,81 +27,81 @@ declare class DateTimeProvider {
27
27
  setLocale(locale: string): void;
28
28
  isDateTime(value: unknown): value is DateTime;
29
29
  /**
30
- * Create a new UTC DateTime instance.
31
- */
30
+ * Create a new UTC DateTime instance.
31
+ */
32
32
  utc(date: string | number | Date | Dayjs | null | undefined): DateTime;
33
33
  /**
34
- * Create a new DateTime instance.
35
- */
34
+ * Create a new DateTime instance.
35
+ */
36
36
  of(date: string | number | Date | Dayjs | null | undefined): DateTime;
37
37
  /**
38
- * Get the current date as a string.
39
- */
38
+ * Get the current date as a string.
39
+ */
40
40
  toISOString(date?: Date | string | DateTime): string;
41
41
  /**
42
- * Get the current date.
43
- */
42
+ * Get the current date.
43
+ */
44
44
  now(): DateTime;
45
45
  /**
46
- * Get the current date as a string.
47
- *
48
- * This is much faster than `DateTimeProvider.now().toISOString()` as it avoids creating a DateTime instance.
49
- */
46
+ * Get the current date as a string.
47
+ *
48
+ * This is much faster than `DateTimeProvider.now().toISOString()` as it avoids creating a DateTime instance.
49
+ */
50
50
  nowISOString(): string;
51
51
  /**
52
- * Get the current date as milliseconds since epoch.
53
- *
54
- * This is much faster than `DateTimeProvider.now().valueOf()` as it avoids creating a DateTime instance.
55
- */
52
+ * Get the current date as milliseconds since epoch.
53
+ *
54
+ * This is much faster than `DateTimeProvider.now().valueOf()` as it avoids creating a DateTime instance.
55
+ */
56
56
  nowMillis(): number;
57
57
  /**
58
- * Get the current date as a string.
59
- *
60
- * @protected
61
- */
58
+ * Get the current date as a string.
59
+ *
60
+ * @protected
61
+ */
62
62
  protected getCurrentDate(): DateTime;
63
63
  /**
64
- * Create a new Duration instance.
65
- */
64
+ * Create a new Duration instance.
65
+ */
66
66
  duration: (duration: DurationLike, unit?: ManipulateType) => Duration;
67
67
  isDurationLike(value: unknown): value is DurationLike;
68
68
  /**
69
- * Return a promise that resolves after the next tick.
70
- * It uses `setTimeout` with 0 ms delay.
71
- */
69
+ * Return a promise that resolves after the next tick.
70
+ * It uses `setTimeout` with 0 ms delay.
71
+ */
72
72
  tick(): Promise<void>;
73
73
  /**
74
- * Wait for a certain duration.
75
- *
76
- * You can clear the timeout by using the `AbortSignal` API.
77
- * Aborted signal will resolve the promise immediately, it does not reject it.
78
- */
74
+ * Wait for a certain duration.
75
+ *
76
+ * You can clear the timeout by using the `AbortSignal` API.
77
+ * Aborted signal will resolve the promise immediately, it does not reject it.
78
+ */
79
79
  wait(duration: DurationLike, options?: {
80
80
  signal?: AbortSignal;
81
81
  now?: number;
82
82
  }): Promise<void>;
83
83
  createInterval(run: () => unknown, duration: DurationLike, start?: boolean): Interval;
84
84
  /**
85
- * Run a callback after a certain duration.
86
- */
85
+ * Run a callback after a certain duration.
86
+ */
87
87
  createTimeout(callback: () => void, duration: DurationLike, now?: number): Timeout;
88
88
  clearTimeout(timeout: Timeout): void;
89
89
  clearInterval(interval: Interval): void;
90
90
  /**
91
- * Run a function with a deadline.
92
- */
91
+ * Run a function with a deadline.
92
+ */
93
93
  deadline<T>(fn: (signal: AbortSignal) => Promise<T>, duration: DurationLike): Promise<T>;
94
94
  /**
95
- * Add time to the current date.
96
- */
95
+ * Add time to the current date.
96
+ */
97
97
  travel(duration: DurationLike, unit?: ManipulateType): Promise<void>;
98
98
  /**
99
- * Stop the time.
100
- */
99
+ * Stop the time.
100
+ */
101
101
  pause(): DateTime;
102
102
  /**
103
- * Reset the reference date.
104
- */
103
+ * Reset the reference date.
104
+ */
105
105
  reset(): void;
106
106
  }
107
107
  interface Interval {
@@ -129,12 +129,12 @@ declare const $interval: {
129
129
  };
130
130
  interface IntervalPrimitiveOptions {
131
131
  /**
132
- * The interval handler.
133
- */
132
+ * The interval handler.
133
+ */
134
134
  handler: () => unknown;
135
135
  /**
136
- * The interval duration.
137
- */
136
+ * The interval duration.
137
+ */
138
138
  duration: DurationLike;
139
139
  }
140
140
  declare class IntervalPrimitive extends Primitive<IntervalPrimitiveOptions> {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/datetime/providers/DateTimeProvider.ts","../../src/datetime/primitives/$interval.ts","../../src/datetime/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;KAmBY,QAAA,GAAW,QAAA,CAAS;KACpB,QAAA,GAAW,aAAA,CAAc;AADzB,KAEA,YAAA,GAFW,MAAA,GAInB,aAAA,CAAc,QAJmB,GAAA,CAAA,MAAA,EAKxB,cALwB,CAAA;AACzB,cAMC,KANU,EAAA,OAML,QANmB;AACzB,cAMC,UAJT,EAAA,CAAA,KAAA,EAAA,OAAc,EAAA,GAAA,KACL,IAGwC,QAH1B;AAEd,cAKA,gBAAA,CALgB;EAChB,OAAA,OAEZ,EAGwB,KAHxB,CAG8B,UALsB,CAEpD,GAAA,CAAA,CAAA;EAEY,UAAA,MAAA,EASK,MATW;EACE,UAAA,GAAA,EASd,QATc,GAAA,IAAA;EAAN,mBAAA,QAAA,EAUM,OAVN,EAAA;EAQP,mBAAA,SAAA,EAGc,QAHd,EAAA;EACD,WAAA,CAAA;EACc,mBAAA,OAAA,EACS,OAAA,CAQZ,aATG,CAAA,OAAA,CAAA;EACC,mBAAA,MAAA,EAQJ,OAAA,CAgBD,aAxBK,CAAA,MAAA,CAAA;EAAQ,SAQZ,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,IAAA;EAAA,UAgBD,CAAA,KAAA,EAAA,OAAA,CAAA,EAAA,KAAA,IAmBmB,QAnBnB;EAmBmB;;;EASzC,GAAA,CAAA,IAAA,EAAA,MAAA,GAAA,MAAA,GADuB,IACvB,GAD8B,KAC9B,GAAA,IAAA,GAAA,SAAA,CAAA,EAAA,QAAA;EAO+B;;;EAOT,EAAA,CAAA,IAAA,EAAA,MAAA,GAAA,MAAA,GAPS,IAOT,GAPgB,KAOhB,GAAA,IAAA,GAAA,SAAA,CAAA,EAP2C,QAO3C;EAAgB;;;EAoD7B,WAAA,CAAA,IAAA,CAAA,EApDa,IAoDb,GAAA,MAAA,GApD6B,QAoD7B,CAAA,EAAA,MAAA;EACH;;;EAyBY,GAAA,CAAA,CAAA,EAvEP,QAuEO;EAWT;;;;;EAwDA,YAAA,CAAA,CAAA,EAAA,MAAA;EAET;;;;;EA8C4B,SAAA,CAAA,CAAA,EAAA,MAAA;EACnB;;;;;EAqBT,UAAA,cAAA,CAAA,CAAA,EA/KyB,QA+KzB;EA8Ca;;AAalB;EAMiB,QAAA,EAAO,CAAA,QAAA,EApOV,YAoOU,EAAA,IAAA,CAAA,EAnOb,cAmOa,EAAA,GAlOnB,QAkOmB;2CAtN0B;;;ACpKlD;;EAA2D,IAAA,CAAA,CAAA,EDgLpC,OChLoC,CAAA,IAAA,CAAA;;;;AAK3D;AAcA;;EACqC,IAAA,CAAA,QAAA,EDuKvB,YCvKuB,EAAA,QAAA,EAAA;IADE,MAAA,CAAA,ED0KxB,WC1KwB;IAAS,GAAA,CAAA,EAAA,MAAA;MD6K3C;+CA6BS,gCAET;;AEjOL;;gDFqPc,6BAET;wBA8B0B;0BAME;;;;2BAUhB,gBAAgB,QAAQ,cAC3B,eACT,QAAQ;;;;mBAkBC,qBACH,iBACN;;;;WA8Ca;;;;;;UAaD,QAAA;;;;;UAMA,OAAA;;;;;;;;;;;;;;cC1XJ;YAAsB,2BAAwB;;;UAK1C,wBAAA;EDGL;AACZ;AACA;EAKa,OAAA,EAAgB,GAAA,GAAA,OAAX;EACL;AAIb;;EACyB,QAAA,ECPb,YDOa;;AASR,cCXJ,iBAAA,SAA0B,SDWtB,CCXgC,wBDWhC,CAAA,CAAA;EACc,mBAAA,gBAAA,ECXM,gBDWN;EACC,MAAA,EAAA,MAAA;EAAQ,UAQZ,MAAA,CAAA,CAAA,EAAA,IAAA;;;;cE1Cf,gBAAc,OAAA,CAAA,QAIzB,OAAA,CAJyB,MAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/datetime/providers/DateTimeProvider.ts","../../src/datetime/primitives/$interval.ts","../../src/datetime/index.ts"],"mappings":";;;;;;;;;;;;KAmBY,QAAA,GAAW,QAAA,CAAS,KAAA;AAAA,KACpB,QAAA,GAAW,aAAA,CAAc,QAAA;AAAA,KACzB,YAAA,YAER,aAAA,CAAc,QAAA,YACL,cAAA;AAAA,cAEA,KAAA,SAAK,QAAA;AAAA,cACL,UAAA,GAAA,KAAA,cAAA,KAAA,IAAwC,QAAA;AAAA,cAIxC,gBAAA;EAAA,OAAA,OAAA,EACY,KAAA,CAAM,UAAA;EAAA,UAAA,MAAA,EAQb,MAAA;EAAA,UAAA,GAAA,EACD,QAAA;EAAA,mBAAA,QAAA,EACc,OAAA;EAAA,mBAAA,SAAA,EACC,QAAA;EAAA,YAAA;EAAA,mBAAA,OAAA,EAAQ,OAAA,CAQZ,aAAA;EAAA,mBAAA,MAAA,EAAA,OAAA,CAgBD,aAAA;EAAA,UAAA,MAAA;EAAA,WAAA,KAAA,YAAA,KAAA,IAmBmB,QAAA;EAAA;;;EAAA,IAAA,IAAA,oBAQlB,IAAA,GAAO,KAAA,sBAC9B,QAAA;EAAA;;;EAAA,GAAA,IAAA,oBAO+B,IAAA,GAAO,KAAA,sBAA2B,QAAA;EAAA;;;EAAA,YAAA,IAAA,GAO3C,IAAA,YAAgB,QAAA;EAAA;;;EAAA,IAAA,GAO3B,QAAA;EAAA;;;;;EAAA,aAAA;EAAA;;;;;EAAA,UAAA;EAAA;;;;;EAAA,UAAA,eAAA,GAiCc,QAAA;EAAA;;;EAAA,QAAA,GAAA,QAAA,EAYhB,YAAA,EAAA,IAAA,GACH,cAAA,KACN,QAAA;EAAA,eAAA,KAAA,YAAA,KAAA,IAY6C,YAAA;EAAA;;;;EAAA,KAAA,GAY3B,OAAA;EAAA;;;;;;EAAA,KAAA,QAAA,EAWT,YAAA,EAAA,OAAA;IAAA,MAAA,GAEC,WAAA;IAAA,GAAA;EAAA,IAGV,OAAA;EAAA,eAAA,GAAA,iBAAA,QAAA,EA6BS,YAAA,EAAA,KAAA,aAET,QAAA;EAAA;;;EAAA,cAAA,QAAA,cAAA,QAAA,EAoBS,YAAA,EAAA,GAAA,YAET,OAAA;EAAA,aAAA,OAAA,EA8B0B,OAAA;EAAA,cAAA,QAAA,EAME,QAAA;EAAA;;;EAAA,QAAA,GAAA,CAAA,EAAA,GAAA,MAAA,EAUhB,WAAA,KAAgB,OAAA,CAAQ,CAAA,GAAA,QAAA,EAC3B,YAAA,GACT,OAAA,CAAQ,CAAA;EAAA;;;EAAA,OAAA,QAAA,EAkBC,YAAA,EAAA,IAAA,GACH,cAAA,GACN,OAAA;EAAA;;;EAAA,MAAA,GA8Ca,QAAA;EAAA;;AAalB;EAbkB,MAAA;AAAA;AAAA,UAaD,QAAA;EAAA,KAAA;EAAA,QAAA;EAAA,GAAA;AAAA;AAAA,UAMA,OAAA;EAAA,GAAA;EAAA,KAAA;EAAA,QAAA;EAAA,QAAA;EAAA,KAAA;AAAA;;;;AC1XjB;;;;cAAa,SAAA;EAAA,CAAA,OAAA,EAAsB,wBAAA,GAAwB,iBAAA;EAAA;;UAK1C,wBAAA;EAAA;AAcjB;;EAdiB,OAAA;EAAA;AAcjB;;EAdiB,QAAA,EASL,YAAA;AAAA;AAAA,cAKC,iBAAA,SAA0B,SAAA,CAAU,wBAAA;EAAA,mBAAA,gBAAA,EACZ,gBAAA;EAAA,MAAA;EAAA,UAAA,OAAA;AAAA;;;cCtBxB,cAAA,EAAc,OAAA,CAAA,OAAA,CAIzB,OAAA,CAJyB,MAAA"}
@@ -132,16 +132,16 @@ var DateTimeProvider = class DateTimeProvider {
132
132
  */
133
133
  wait(duration, options = {}) {
134
134
  return new Promise((resolve) => {
135
- let clearTimeout$1;
135
+ let clearTimeout;
136
136
  let callback;
137
137
  const timeout = this.createTimeout(() => {
138
- if (options.signal && clearTimeout$1) options.signal.removeEventListener("abort", callback);
138
+ if (options.signal && clearTimeout) options.signal.removeEventListener("abort", callback);
139
139
  resolve();
140
140
  }, duration, options.now);
141
141
  if (options.signal) {
142
- clearTimeout$1 = () => this.clearTimeout(timeout);
142
+ clearTimeout = () => this.clearTimeout(timeout);
143
143
  callback = () => {
144
- clearTimeout$1();
144
+ clearTimeout();
145
145
  resolve();
146
146
  };
147
147
  options.signal.addEventListener("abort", callback);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["clearTimeout"],"sources":["../../src/datetime/providers/DateTimeProvider.ts","../../src/datetime/primitives/$interval.ts","../../src/datetime/index.ts"],"sourcesContent":["import \"dayjs/plugin/relativeTime.js\";\nimport \"dayjs/plugin/duration.js\";\nimport \"dayjs/plugin/utc.js\";\nimport \"dayjs/plugin/timezone.js\";\nimport \"dayjs/plugin/localizedFormat.js\";\nimport \"dayjs/locale/ar.js\";\nimport \"dayjs/locale/fr.js\";\nimport { $hook, $inject, Alepha } from \"alepha\";\nimport DayjsApi, {\n type Dayjs,\n type ManipulateType,\n type PluginFunc,\n} from \"dayjs\";\nimport dayjsDuration from \"dayjs/plugin/duration.js\";\nimport dayjsLocalizedFormat from \"dayjs/plugin/localizedFormat.js\";\nimport dayjsRelativeTime from \"dayjs/plugin/relativeTime.js\";\nimport dayjsTimezone from \"dayjs/plugin/timezone.js\";\nimport dayjsUtc from \"dayjs/plugin/utc.js\";\n\nexport type DateTime = DayjsApi.Dayjs;\nexport type Duration = dayjsDuration.Duration;\nexport type DurationLike =\n | number\n | dayjsDuration.Duration\n | [number, ManipulateType];\n\nexport const dayjs = DayjsApi;\nexport const isDateTime = (value: unknown): value is DateTime => {\n return dayjs.isDayjs(value);\n};\n\nexport class DateTimeProvider {\n public static PLUGINS: Array<PluginFunc<any>> = [\n dayjsDuration,\n dayjsRelativeTime,\n dayjsUtc,\n dayjsTimezone,\n dayjsLocalizedFormat,\n ];\n\n protected alepha = $inject(Alepha);\n protected ref: DateTime | null = null;\n protected readonly timeouts: Timeout[] = [];\n protected readonly intervals: Interval[] = [];\n\n constructor() {\n for (const plugin of DateTimeProvider.PLUGINS) {\n dayjs.extend(plugin);\n }\n }\n\n protected readonly onStart = $hook({\n on: \"start\",\n handler: async () => {\n // we start intervals now but first tick will be rejected as App is not ready yet\n await Promise.all(\n this.intervals.map(async (interval) => {\n if (interval.timer != null) {\n return;\n }\n await interval.run();\n interval.timer = setInterval(interval.run, interval.duration);\n }),\n );\n },\n });\n\n protected readonly onStop = $hook({\n on: \"stop\",\n handler: () => {\n for (const timeout of this.timeouts) {\n this.clearTimeout(timeout);\n }\n\n for (const interval of this.intervals) {\n clearInterval(interval.timer);\n interval.duration = 0;\n interval.timer = null;\n }\n },\n });\n\n public setLocale(locale: string): void {\n dayjs.locale(locale);\n }\n\n public isDateTime(value: unknown): value is DateTime {\n return dayjs.isDayjs(value);\n }\n\n /**\n * Create a new UTC DateTime instance.\n */\n public utc(\n date: string | number | Date | Dayjs | null | undefined,\n ): DateTime {\n return dayjs.utc(date);\n }\n\n /**\n * Create a new DateTime instance.\n */\n public of(date: string | number | Date | Dayjs | null | undefined): DateTime {\n return dayjs(date);\n }\n\n /**\n * Get the current date as a string.\n */\n public toISOString(date: Date | string | DateTime = this.now()): string {\n return this.of(date).toISOString();\n }\n\n /**\n * Get the current date.\n */\n public now(): DateTime {\n return this.getCurrentDate();\n }\n\n /**\n * Get the current date as a string.\n *\n * This is much faster than `DateTimeProvider.now().toISOString()` as it avoids creating a DateTime instance.\n */\n public nowISOString(): string {\n if (this.ref) {\n return this.ref.toISOString();\n }\n return new Date().toISOString();\n }\n\n /**\n * Get the current date as milliseconds since epoch.\n *\n * This is much faster than `DateTimeProvider.now().valueOf()` as it avoids creating a DateTime instance.\n */\n public nowMillis(): number {\n if (this.ref) {\n return this.ref.valueOf();\n }\n return Date.now();\n }\n\n /**\n * Get the current date as a string.\n *\n * @protected\n */\n protected getCurrentDate(): DateTime {\n if (this.ref) {\n return this.ref;\n }\n\n return dayjs();\n }\n\n /**\n * Create a new Duration instance.\n */\n public duration = (\n duration: DurationLike,\n unit?: ManipulateType,\n ): Duration => {\n if (Array.isArray(duration)) {\n return dayjs.duration(duration[0], duration[1]);\n }\n\n if (typeof duration === \"number\") {\n return dayjs.duration(duration, unit || \"milliseconds\");\n }\n\n return duration;\n };\n\n public isDurationLike(value: unknown): value is DurationLike {\n return dayjs.isDuration(this.duration(value as DurationLike));\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n // Timer Management\n\n /**\n * Return a promise that resolves after the next tick.\n * It uses `setTimeout` with 0 ms delay.\n */\n public async tick(): Promise<void> {\n await new Promise((resolve) => setTimeout(resolve, 0));\n }\n\n /**\n * Wait for a certain duration.\n *\n * You can clear the timeout by using the `AbortSignal` API.\n * Aborted signal will resolve the promise immediately, it does not reject it.\n */\n public wait(\n duration: DurationLike,\n options: {\n signal?: AbortSignal;\n now?: number;\n } = {},\n ): Promise<void> {\n return new Promise((resolve) => {\n let clearTimeout: any;\n let callback: any;\n\n const timeout = this.createTimeout(\n () => {\n if (options.signal && clearTimeout) {\n options.signal.removeEventListener(\"abort\", callback);\n }\n resolve();\n },\n duration,\n options.now,\n );\n\n if (options.signal) {\n clearTimeout = () => this.clearTimeout(timeout);\n callback = () => {\n clearTimeout();\n resolve();\n };\n options.signal.addEventListener(\"abort\", callback);\n }\n });\n }\n\n public createInterval(\n run: () => unknown,\n duration: DurationLike,\n start = false,\n ): Interval {\n const interval: Interval = {\n run,\n duration: this.duration(duration).asMilliseconds(),\n };\n\n this.intervals.push(interval);\n\n if (start) {\n interval.timer = setInterval(interval.run, interval.duration);\n }\n\n return interval;\n }\n\n /**\n * Run a callback after a certain duration.\n */\n public createTimeout(\n callback: () => void,\n duration: DurationLike,\n now?: number,\n ): Timeout {\n if (this.ref && now) {\n const next = this.of(now).add(this.duration(duration));\n if (next < this.now()) {\n callback();\n }\n return {\n now,\n duration: 0,\n callback: () => {},\n clear: () => {},\n };\n }\n\n const timeout: Timeout = {\n now: now ?? this.now().valueOf(),\n duration: this.duration(duration).asMilliseconds(),\n callback,\n clear: () => this.clearTimeout(timeout),\n };\n\n timeout.timer = setTimeout(() => {\n timeout.callback();\n }, timeout.duration);\n\n this.timeouts.push(timeout);\n\n return timeout;\n }\n\n public clearTimeout(timeout: Timeout): void {\n clearTimeout(timeout.timer);\n timeout.duration = 0;\n timeout.timer = null;\n }\n\n public clearInterval(interval: Interval): void {\n clearInterval(interval.timer);\n interval.duration = 0;\n interval.timer = null;\n }\n\n /**\n * Run a function with a deadline.\n */\n public async deadline<T>(\n fn: (signal: AbortSignal) => Promise<T>,\n duration: DurationLike,\n ): Promise<T> {\n const abort = new AbortController();\n const timeout = this.createTimeout(() => abort.abort(), duration);\n try {\n return await fn(abort.signal);\n } finally {\n this.clearTimeout(timeout);\n }\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n // Testing\n\n /**\n * Add time to the current date.\n */\n public async travel(\n duration: DurationLike,\n unit?: ManipulateType,\n ): Promise<void> {\n this.ref = this.ref || this.now();\n this.ref = this.ref.add(this.duration(duration, unit));\n const ms = this.duration(duration, unit).asMilliseconds();\n const now = Date.now();\n\n for (const timeout of this.timeouts) {\n if (!timeout.timer) {\n continue;\n }\n\n clearTimeout(timeout.timer);\n timeout.timer = null;\n\n const spent = now - timeout.now;\n timeout.duration = timeout.duration - spent - ms;\n\n if (timeout.duration <= 0) {\n timeout.callback();\n } else {\n timeout.timer = setTimeout(() => {\n timeout.callback();\n }, timeout.duration);\n }\n }\n\n for (const interval of this.intervals) {\n if (!interval.timer) {\n continue;\n }\n\n clearInterval(interval.timer);\n interval.timer = null;\n\n const repeat = Math.floor(ms / interval.duration);\n for (let i = 0; i < repeat; i++) {\n await interval.run();\n }\n }\n\n await this.tick();\n }\n\n /**\n * Stop the time.\n */\n public pause(): DateTime {\n this.ref = this.ref || this.now();\n return this.ref;\n }\n\n /**\n * Reset the reference date.\n */\n public reset(): void {\n this.ref = null;\n }\n}\n\nexport interface Interval {\n timer?: any;\n duration: number;\n run: () => unknown;\n}\n\nexport interface Timeout {\n now: number;\n timer?: any;\n duration: number;\n callback: () => void;\n clear: () => void;\n}\n","import { $inject, createPrimitive, KIND, Primitive } from \"alepha\";\nimport {\n DateTimeProvider,\n type DurationLike,\n} from \"../providers/DateTimeProvider.ts\";\n\n/**\n * Run a function periodically.\n * It uses the `setInterval` internally.\n * It starts by default when the context starts and stops when the context stops.\n */\nexport const $interval = (options: IntervalPrimitiveOptions) =>\n createPrimitive(IntervalPrimitive, options);\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface IntervalPrimitiveOptions {\n /**\n * The interval handler.\n */\n handler: () => unknown;\n\n /**\n * The interval duration.\n */\n duration: DurationLike;\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class IntervalPrimitive extends Primitive<IntervalPrimitiveOptions> {\n protected readonly dateTimeProvider = $inject(DateTimeProvider);\n\n public called = 0;\n\n protected onInit() {\n this.dateTimeProvider.createInterval(async () => {\n await this.options.handler();\n this.called += 1;\n }, this.options.duration);\n }\n}\n\n$interval[KIND] = IntervalPrimitive;\n","import { $module } from \"alepha\";\nimport { $interval } from \"./primitives/$interval.ts\";\nimport { DateTimeProvider } from \"./providers/DateTimeProvider.ts\";\n\nexport * from \"./primitives/$interval.ts\";\nexport * from \"./providers/DateTimeProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport const AlephaDateTime = $module({\n name: \"alepha.datetime\",\n primitives: [$interval],\n services: [DateTimeProvider],\n});\n"],"mappings":";;;;;;;;;;;AA0BA,MAAa,QAAQ;AACrB,MAAa,cAAc,UAAsC;AAC/D,QAAO,MAAM,QAAQ,MAAM;;AAG7B,IAAa,mBAAb,MAAa,iBAAiB;CAC5B,OAAc,UAAkC;EAC9C;EACA;EACA;EACA;EACA;EACD;CAED,AAAU,SAAS,QAAQ,OAAO;CAClC,AAAU,MAAuB;CACjC,AAAmB,WAAsB,EAAE;CAC3C,AAAmB,YAAwB,EAAE;CAE7C,cAAc;AACZ,OAAK,MAAM,UAAU,iBAAiB,QACpC,OAAM,OAAO,OAAO;;CAIxB,AAAmB,UAAU,MAAM;EACjC,IAAI;EACJ,SAAS,YAAY;AAEnB,SAAM,QAAQ,IACZ,KAAK,UAAU,IAAI,OAAO,aAAa;AACrC,QAAI,SAAS,SAAS,KACpB;AAEF,UAAM,SAAS,KAAK;AACpB,aAAS,QAAQ,YAAY,SAAS,KAAK,SAAS,SAAS;KAC7D,CACH;;EAEJ,CAAC;CAEF,AAAmB,SAAS,MAAM;EAChC,IAAI;EACJ,eAAe;AACb,QAAK,MAAM,WAAW,KAAK,SACzB,MAAK,aAAa,QAAQ;AAG5B,QAAK,MAAM,YAAY,KAAK,WAAW;AACrC,kBAAc,SAAS,MAAM;AAC7B,aAAS,WAAW;AACpB,aAAS,QAAQ;;;EAGtB,CAAC;CAEF,AAAO,UAAU,QAAsB;AACrC,QAAM,OAAO,OAAO;;CAGtB,AAAO,WAAW,OAAmC;AACnD,SAAO,MAAM,QAAQ,MAAM;;;;;CAM7B,AAAO,IACL,MACU;AACV,SAAO,MAAM,IAAI,KAAK;;;;;CAMxB,AAAO,GAAG,MAAmE;AAC3E,SAAO,MAAM,KAAK;;;;;CAMpB,AAAO,YAAY,OAAiC,KAAK,KAAK,EAAU;AACtE,SAAO,KAAK,GAAG,KAAK,CAAC,aAAa;;;;;CAMpC,AAAO,MAAgB;AACrB,SAAO,KAAK,gBAAgB;;;;;;;CAQ9B,AAAO,eAAuB;AAC5B,MAAI,KAAK,IACP,QAAO,KAAK,IAAI,aAAa;AAE/B,0BAAO,IAAI,MAAM,EAAC,aAAa;;;;;;;CAQjC,AAAO,YAAoB;AACzB,MAAI,KAAK,IACP,QAAO,KAAK,IAAI,SAAS;AAE3B,SAAO,KAAK,KAAK;;;;;;;CAQnB,AAAU,iBAA2B;AACnC,MAAI,KAAK,IACP,QAAO,KAAK;AAGd,SAAO,OAAO;;;;;CAMhB,AAAO,YACL,UACA,SACa;AACb,MAAI,MAAM,QAAQ,SAAS,CACzB,QAAO,MAAM,SAAS,SAAS,IAAI,SAAS,GAAG;AAGjD,MAAI,OAAO,aAAa,SACtB,QAAO,MAAM,SAAS,UAAU,QAAQ,eAAe;AAGzD,SAAO;;CAGT,AAAO,eAAe,OAAuC;AAC3D,SAAO,MAAM,WAAW,KAAK,SAAS,MAAsB,CAAC;;;;;;CAW/D,MAAa,OAAsB;AACjC,QAAM,IAAI,SAAS,YAAY,WAAW,SAAS,EAAE,CAAC;;;;;;;;CASxD,AAAO,KACL,UACA,UAGI,EAAE,EACS;AACf,SAAO,IAAI,SAAS,YAAY;GAC9B,IAAIA;GACJ,IAAI;GAEJ,MAAM,UAAU,KAAK,oBACb;AACJ,QAAI,QAAQ,UAAUA,eACpB,SAAQ,OAAO,oBAAoB,SAAS,SAAS;AAEvD,aAAS;MAEX,UACA,QAAQ,IACT;AAED,OAAI,QAAQ,QAAQ;AAClB,2BAAqB,KAAK,aAAa,QAAQ;AAC/C,qBAAiB;AACf,qBAAc;AACd,cAAS;;AAEX,YAAQ,OAAO,iBAAiB,SAAS,SAAS;;IAEpD;;CAGJ,AAAO,eACL,KACA,UACA,QAAQ,OACE;EACV,MAAM,WAAqB;GACzB;GACA,UAAU,KAAK,SAAS,SAAS,CAAC,gBAAgB;GACnD;AAED,OAAK,UAAU,KAAK,SAAS;AAE7B,MAAI,MACF,UAAS,QAAQ,YAAY,SAAS,KAAK,SAAS,SAAS;AAG/D,SAAO;;;;;CAMT,AAAO,cACL,UACA,UACA,KACS;AACT,MAAI,KAAK,OAAO,KAAK;AAEnB,OADa,KAAK,GAAG,IAAI,CAAC,IAAI,KAAK,SAAS,SAAS,CAAC,GAC3C,KAAK,KAAK,CACnB,WAAU;AAEZ,UAAO;IACL;IACA,UAAU;IACV,gBAAgB;IAChB,aAAa;IACd;;EAGH,MAAM,UAAmB;GACvB,KAAK,OAAO,KAAK,KAAK,CAAC,SAAS;GAChC,UAAU,KAAK,SAAS,SAAS,CAAC,gBAAgB;GAClD;GACA,aAAa,KAAK,aAAa,QAAQ;GACxC;AAED,UAAQ,QAAQ,iBAAiB;AAC/B,WAAQ,UAAU;KACjB,QAAQ,SAAS;AAEpB,OAAK,SAAS,KAAK,QAAQ;AAE3B,SAAO;;CAGT,AAAO,aAAa,SAAwB;AAC1C,eAAa,QAAQ,MAAM;AAC3B,UAAQ,WAAW;AACnB,UAAQ,QAAQ;;CAGlB,AAAO,cAAc,UAA0B;AAC7C,gBAAc,SAAS,MAAM;AAC7B,WAAS,WAAW;AACpB,WAAS,QAAQ;;;;;CAMnB,MAAa,SACX,IACA,UACY;EACZ,MAAM,QAAQ,IAAI,iBAAiB;EACnC,MAAM,UAAU,KAAK,oBAAoB,MAAM,OAAO,EAAE,SAAS;AACjE,MAAI;AACF,UAAO,MAAM,GAAG,MAAM,OAAO;YACrB;AACR,QAAK,aAAa,QAAQ;;;;;;CAW9B,MAAa,OACX,UACA,MACe;AACf,OAAK,MAAM,KAAK,OAAO,KAAK,KAAK;AACjC,OAAK,MAAM,KAAK,IAAI,IAAI,KAAK,SAAS,UAAU,KAAK,CAAC;EACtD,MAAM,KAAK,KAAK,SAAS,UAAU,KAAK,CAAC,gBAAgB;EACzD,MAAM,MAAM,KAAK,KAAK;AAEtB,OAAK,MAAM,WAAW,KAAK,UAAU;AACnC,OAAI,CAAC,QAAQ,MACX;AAGF,gBAAa,QAAQ,MAAM;AAC3B,WAAQ,QAAQ;GAEhB,MAAM,QAAQ,MAAM,QAAQ;AAC5B,WAAQ,WAAW,QAAQ,WAAW,QAAQ;AAE9C,OAAI,QAAQ,YAAY,EACtB,SAAQ,UAAU;OAElB,SAAQ,QAAQ,iBAAiB;AAC/B,YAAQ,UAAU;MACjB,QAAQ,SAAS;;AAIxB,OAAK,MAAM,YAAY,KAAK,WAAW;AACrC,OAAI,CAAC,SAAS,MACZ;AAGF,iBAAc,SAAS,MAAM;AAC7B,YAAS,QAAQ;GAEjB,MAAM,SAAS,KAAK,MAAM,KAAK,SAAS,SAAS;AACjD,QAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,IAC1B,OAAM,SAAS,KAAK;;AAIxB,QAAM,KAAK,MAAM;;;;;CAMnB,AAAO,QAAkB;AACvB,OAAK,MAAM,KAAK,OAAO,KAAK,KAAK;AACjC,SAAO,KAAK;;;;;CAMd,AAAO,QAAc;AACnB,OAAK,MAAM;;;;;;;;;;;AChXf,MAAa,aAAa,YACxB,gBAAgB,mBAAmB,QAAQ;AAkB7C,IAAa,oBAAb,cAAuC,UAAoC;CACzE,AAAmB,mBAAmB,QAAQ,iBAAiB;CAE/D,AAAO,SAAS;CAEhB,AAAU,SAAS;AACjB,OAAK,iBAAiB,eAAe,YAAY;AAC/C,SAAM,KAAK,QAAQ,SAAS;AAC5B,QAAK,UAAU;KACd,KAAK,QAAQ,SAAS;;;AAI7B,UAAU,QAAQ;;;;AClClB,MAAa,iBAAiB,QAAQ;CACpC,MAAM;CACN,YAAY,CAAC,UAAU;CACvB,UAAU,CAAC,iBAAiB;CAC7B,CAAC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/datetime/providers/DateTimeProvider.ts","../../src/datetime/primitives/$interval.ts","../../src/datetime/index.ts"],"sourcesContent":["import \"dayjs/plugin/relativeTime.js\";\nimport \"dayjs/plugin/duration.js\";\nimport \"dayjs/plugin/utc.js\";\nimport \"dayjs/plugin/timezone.js\";\nimport \"dayjs/plugin/localizedFormat.js\";\nimport \"dayjs/locale/ar.js\";\nimport \"dayjs/locale/fr.js\";\nimport { $hook, $inject, Alepha } from \"alepha\";\nimport DayjsApi, {\n type Dayjs,\n type ManipulateType,\n type PluginFunc,\n} from \"dayjs\";\nimport dayjsDuration from \"dayjs/plugin/duration.js\";\nimport dayjsLocalizedFormat from \"dayjs/plugin/localizedFormat.js\";\nimport dayjsRelativeTime from \"dayjs/plugin/relativeTime.js\";\nimport dayjsTimezone from \"dayjs/plugin/timezone.js\";\nimport dayjsUtc from \"dayjs/plugin/utc.js\";\n\nexport type DateTime = DayjsApi.Dayjs;\nexport type Duration = dayjsDuration.Duration;\nexport type DurationLike =\n | number\n | dayjsDuration.Duration\n | [number, ManipulateType];\n\nexport const dayjs = DayjsApi;\nexport const isDateTime = (value: unknown): value is DateTime => {\n return dayjs.isDayjs(value);\n};\n\nexport class DateTimeProvider {\n public static PLUGINS: Array<PluginFunc<any>> = [\n dayjsDuration,\n dayjsRelativeTime,\n dayjsUtc,\n dayjsTimezone,\n dayjsLocalizedFormat,\n ];\n\n protected alepha = $inject(Alepha);\n protected ref: DateTime | null = null;\n protected readonly timeouts: Timeout[] = [];\n protected readonly intervals: Interval[] = [];\n\n constructor() {\n for (const plugin of DateTimeProvider.PLUGINS) {\n dayjs.extend(plugin);\n }\n }\n\n protected readonly onStart = $hook({\n on: \"start\",\n handler: async () => {\n // we start intervals now but first tick will be rejected as App is not ready yet\n await Promise.all(\n this.intervals.map(async (interval) => {\n if (interval.timer != null) {\n return;\n }\n await interval.run();\n interval.timer = setInterval(interval.run, interval.duration);\n }),\n );\n },\n });\n\n protected readonly onStop = $hook({\n on: \"stop\",\n handler: () => {\n for (const timeout of this.timeouts) {\n this.clearTimeout(timeout);\n }\n\n for (const interval of this.intervals) {\n clearInterval(interval.timer);\n interval.duration = 0;\n interval.timer = null;\n }\n },\n });\n\n public setLocale(locale: string): void {\n dayjs.locale(locale);\n }\n\n public isDateTime(value: unknown): value is DateTime {\n return dayjs.isDayjs(value);\n }\n\n /**\n * Create a new UTC DateTime instance.\n */\n public utc(\n date: string | number | Date | Dayjs | null | undefined,\n ): DateTime {\n return dayjs.utc(date);\n }\n\n /**\n * Create a new DateTime instance.\n */\n public of(date: string | number | Date | Dayjs | null | undefined): DateTime {\n return dayjs(date);\n }\n\n /**\n * Get the current date as a string.\n */\n public toISOString(date: Date | string | DateTime = this.now()): string {\n return this.of(date).toISOString();\n }\n\n /**\n * Get the current date.\n */\n public now(): DateTime {\n return this.getCurrentDate();\n }\n\n /**\n * Get the current date as a string.\n *\n * This is much faster than `DateTimeProvider.now().toISOString()` as it avoids creating a DateTime instance.\n */\n public nowISOString(): string {\n if (this.ref) {\n return this.ref.toISOString();\n }\n return new Date().toISOString();\n }\n\n /**\n * Get the current date as milliseconds since epoch.\n *\n * This is much faster than `DateTimeProvider.now().valueOf()` as it avoids creating a DateTime instance.\n */\n public nowMillis(): number {\n if (this.ref) {\n return this.ref.valueOf();\n }\n return Date.now();\n }\n\n /**\n * Get the current date as a string.\n *\n * @protected\n */\n protected getCurrentDate(): DateTime {\n if (this.ref) {\n return this.ref;\n }\n\n return dayjs();\n }\n\n /**\n * Create a new Duration instance.\n */\n public duration = (\n duration: DurationLike,\n unit?: ManipulateType,\n ): Duration => {\n if (Array.isArray(duration)) {\n return dayjs.duration(duration[0], duration[1]);\n }\n\n if (typeof duration === \"number\") {\n return dayjs.duration(duration, unit || \"milliseconds\");\n }\n\n return duration;\n };\n\n public isDurationLike(value: unknown): value is DurationLike {\n return dayjs.isDuration(this.duration(value as DurationLike));\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n // Timer Management\n\n /**\n * Return a promise that resolves after the next tick.\n * It uses `setTimeout` with 0 ms delay.\n */\n public async tick(): Promise<void> {\n await new Promise((resolve) => setTimeout(resolve, 0));\n }\n\n /**\n * Wait for a certain duration.\n *\n * You can clear the timeout by using the `AbortSignal` API.\n * Aborted signal will resolve the promise immediately, it does not reject it.\n */\n public wait(\n duration: DurationLike,\n options: {\n signal?: AbortSignal;\n now?: number;\n } = {},\n ): Promise<void> {\n return new Promise((resolve) => {\n let clearTimeout: any;\n let callback: any;\n\n const timeout = this.createTimeout(\n () => {\n if (options.signal && clearTimeout) {\n options.signal.removeEventListener(\"abort\", callback);\n }\n resolve();\n },\n duration,\n options.now,\n );\n\n if (options.signal) {\n clearTimeout = () => this.clearTimeout(timeout);\n callback = () => {\n clearTimeout();\n resolve();\n };\n options.signal.addEventListener(\"abort\", callback);\n }\n });\n }\n\n public createInterval(\n run: () => unknown,\n duration: DurationLike,\n start = false,\n ): Interval {\n const interval: Interval = {\n run,\n duration: this.duration(duration).asMilliseconds(),\n };\n\n this.intervals.push(interval);\n\n if (start) {\n interval.timer = setInterval(interval.run, interval.duration);\n }\n\n return interval;\n }\n\n /**\n * Run a callback after a certain duration.\n */\n public createTimeout(\n callback: () => void,\n duration: DurationLike,\n now?: number,\n ): Timeout {\n if (this.ref && now) {\n const next = this.of(now).add(this.duration(duration));\n if (next < this.now()) {\n callback();\n }\n return {\n now,\n duration: 0,\n callback: () => {},\n clear: () => {},\n };\n }\n\n const timeout: Timeout = {\n now: now ?? this.now().valueOf(),\n duration: this.duration(duration).asMilliseconds(),\n callback,\n clear: () => this.clearTimeout(timeout),\n };\n\n timeout.timer = setTimeout(() => {\n timeout.callback();\n }, timeout.duration);\n\n this.timeouts.push(timeout);\n\n return timeout;\n }\n\n public clearTimeout(timeout: Timeout): void {\n clearTimeout(timeout.timer);\n timeout.duration = 0;\n timeout.timer = null;\n }\n\n public clearInterval(interval: Interval): void {\n clearInterval(interval.timer);\n interval.duration = 0;\n interval.timer = null;\n }\n\n /**\n * Run a function with a deadline.\n */\n public async deadline<T>(\n fn: (signal: AbortSignal) => Promise<T>,\n duration: DurationLike,\n ): Promise<T> {\n const abort = new AbortController();\n const timeout = this.createTimeout(() => abort.abort(), duration);\n try {\n return await fn(abort.signal);\n } finally {\n this.clearTimeout(timeout);\n }\n }\n\n // -------------------------------------------------------------------------------------------------------------------\n\n // Testing\n\n /**\n * Add time to the current date.\n */\n public async travel(\n duration: DurationLike,\n unit?: ManipulateType,\n ): Promise<void> {\n this.ref = this.ref || this.now();\n this.ref = this.ref.add(this.duration(duration, unit));\n const ms = this.duration(duration, unit).asMilliseconds();\n const now = Date.now();\n\n for (const timeout of this.timeouts) {\n if (!timeout.timer) {\n continue;\n }\n\n clearTimeout(timeout.timer);\n timeout.timer = null;\n\n const spent = now - timeout.now;\n timeout.duration = timeout.duration - spent - ms;\n\n if (timeout.duration <= 0) {\n timeout.callback();\n } else {\n timeout.timer = setTimeout(() => {\n timeout.callback();\n }, timeout.duration);\n }\n }\n\n for (const interval of this.intervals) {\n if (!interval.timer) {\n continue;\n }\n\n clearInterval(interval.timer);\n interval.timer = null;\n\n const repeat = Math.floor(ms / interval.duration);\n for (let i = 0; i < repeat; i++) {\n await interval.run();\n }\n }\n\n await this.tick();\n }\n\n /**\n * Stop the time.\n */\n public pause(): DateTime {\n this.ref = this.ref || this.now();\n return this.ref;\n }\n\n /**\n * Reset the reference date.\n */\n public reset(): void {\n this.ref = null;\n }\n}\n\nexport interface Interval {\n timer?: any;\n duration: number;\n run: () => unknown;\n}\n\nexport interface Timeout {\n now: number;\n timer?: any;\n duration: number;\n callback: () => void;\n clear: () => void;\n}\n","import { $inject, createPrimitive, KIND, Primitive } from \"alepha\";\nimport {\n DateTimeProvider,\n type DurationLike,\n} from \"../providers/DateTimeProvider.ts\";\n\n/**\n * Run a function periodically.\n * It uses the `setInterval` internally.\n * It starts by default when the context starts and stops when the context stops.\n */\nexport const $interval = (options: IntervalPrimitiveOptions) =>\n createPrimitive(IntervalPrimitive, options);\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface IntervalPrimitiveOptions {\n /**\n * The interval handler.\n */\n handler: () => unknown;\n\n /**\n * The interval duration.\n */\n duration: DurationLike;\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class IntervalPrimitive extends Primitive<IntervalPrimitiveOptions> {\n protected readonly dateTimeProvider = $inject(DateTimeProvider);\n\n public called = 0;\n\n protected onInit() {\n this.dateTimeProvider.createInterval(async () => {\n await this.options.handler();\n this.called += 1;\n }, this.options.duration);\n }\n}\n\n$interval[KIND] = IntervalPrimitive;\n","import { $module } from \"alepha\";\nimport { $interval } from \"./primitives/$interval.ts\";\nimport { DateTimeProvider } from \"./providers/DateTimeProvider.ts\";\n\nexport * from \"./primitives/$interval.ts\";\nexport * from \"./providers/DateTimeProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport const AlephaDateTime = $module({\n name: \"alepha.datetime\",\n primitives: [$interval],\n services: [DateTimeProvider],\n});\n"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import * as alepha1 from "alepha";
2
- import { InstantiableClass, KIND, Primitive } from "alepha";
2
+ import { InstantiableClass, KIND, Primitive, Static } from "alepha";
3
3
  import * as alepha_logger0 from "alepha/logger";
4
+ import { FileSystemProvider } from "alepha/file";
4
5
  import { Transporter } from "nodemailer";
5
6
 
6
7
  //#region ../../src/email/providers/EmailProvider.d.ts
@@ -11,10 +12,10 @@ import { Transporter } from "nodemailer";
11
12
  */
12
13
  declare abstract class EmailProvider {
13
14
  /**
14
- * Send an email.
15
- *
16
- * @return Promise that resolves when the email is sent.
17
- */
15
+ * Send an email.
16
+ *
17
+ * @return Promise that resolves when the email is sent.
18
+ */
18
19
  abstract send(options: EmailSendOptions): Promise<void>;
19
20
  }
20
21
  type EmailSendOptions = {
@@ -59,23 +60,33 @@ declare class EmailPrimitive extends Primitive<EmailPrimitiveOptions> {
59
60
  protected readonly provider: EmailProvider;
60
61
  get name(): string;
61
62
  /**
62
- * Send an email using the configured provider.
63
- */
63
+ * Send an email using the configured provider.
64
+ */
64
65
  send(options: EmailSendOptions): Promise<void>;
65
66
  protected $provider(): EmailProvider;
66
67
  }
67
68
  //#endregion
68
69
  //#region ../../src/email/providers/LocalEmailProvider.d.ts
69
- interface LocalEmailProviderOptions {
70
- /**
71
- * Directory to save email files.
72
- */
73
- directory?: string;
70
+ /**
71
+ * Local email provider configuration atom
72
+ */
73
+ declare const localEmailOptions: alepha1.Atom<alepha1.TObject<{
74
+ directory: alepha1.TString;
75
+ }>, "alepha.email.local.options">;
76
+ type LocalEmailProviderOptions = Static<typeof localEmailOptions.schema>;
77
+ declare module "alepha" {
78
+ interface State {
79
+ [localEmailOptions.key]: LocalEmailProviderOptions;
80
+ }
74
81
  }
75
82
  declare class LocalEmailProvider implements EmailProvider {
76
83
  protected readonly log: alepha_logger0.Logger;
77
- protected readonly directory: string;
78
- constructor(options?: LocalEmailProviderOptions);
84
+ protected readonly fs: FileSystemProvider;
85
+ protected readonly options: Readonly<{
86
+ directory: string;
87
+ }>;
88
+ protected get directory(): string;
89
+ protected onStart: alepha1.HookPrimitive<"start">;
79
90
  send(options: EmailSendOptions): Promise<void>;
80
91
  createEmailHtml(options: {
81
92
  to: string;
@@ -97,57 +108,93 @@ declare class MemoryEmailProvider implements EmailProvider {
97
108
  records: EmailRecord[];
98
109
  send(options: EmailSendOptions): Promise<void>;
99
110
  /**
100
- * Get the last email sent (for testing purposes).
101
- */
111
+ * Get the last email sent (for testing purposes).
112
+ */
102
113
  get last(): EmailRecord | undefined;
103
114
  }
104
115
  //#endregion
105
116
  //#region ../../src/email/providers/NodemailerEmailProvider.d.ts
106
- interface NodemailerEmailProviderOptions {
107
- /**
108
- * Custom transporter configuration.
109
- * If provided, will override environment variables.
110
- */
111
- transporter?: Transporter;
112
- /**
113
- * Custom from email address.
114
- * If not provided, will use EMAIL_FROM from environment.
115
- */
116
- from?: string;
117
- /**
118
- * Additional nodemailer options.
119
- */
120
- options?: {
121
- pool?: boolean;
122
- maxConnections?: number;
123
- maxMessages?: number;
124
- rateDelta?: number;
125
- rateLimit?: number;
126
- };
117
+ /**
118
+ * Nodemailer connection pooling and rate limiting options
119
+ */
120
+ declare const nodemailerEmailOptions: alepha1.Atom<alepha1.TObject<{
121
+ pool: alepha1.TOptional<alepha1.TBoolean>;
122
+ maxConnections: alepha1.TOptional<alepha1.TNumber>;
123
+ maxMessages: alepha1.TOptional<alepha1.TNumber>;
124
+ rateDelta: alepha1.TOptional<alepha1.TNumber>;
125
+ rateLimit: alepha1.TOptional<alepha1.TNumber>;
126
+ }>, "alepha.email.nodemailer.options">;
127
+ type NodemailerEmailProviderOptions = Static<typeof nodemailerEmailOptions.schema>;
128
+ declare module "alepha" {
129
+ interface State {
130
+ [nodemailerEmailOptions.key]: NodemailerEmailProviderOptions;
131
+ }
127
132
  }
133
+ /**
134
+ * Email provider using Nodemailer for SMTP transport.
135
+ *
136
+ * Configuration is provided via environment variables:
137
+ * - EMAIL_HOST: SMTP server host
138
+ * - EMAIL_PORT: SMTP server port (default: 587)
139
+ * - EMAIL_USER: SMTP authentication username
140
+ * - EMAIL_PASS: SMTP authentication password
141
+ * - EMAIL_FROM: Default from email address
142
+ * - EMAIL_SECURE: Use secure connection (default: false)
143
+ *
144
+ * Advanced pooling/rate limiting options can be configured via atom:
145
+ * @see {@link nodemailerEmailOptions}
146
+ *
147
+ * @example
148
+ * ```typescript
149
+ * // Configure via environment variables
150
+ * // EMAIL_HOST=smtp.example.com
151
+ * // EMAIL_PORT=587
152
+ * // EMAIL_USER=user@example.com
153
+ * // EMAIL_PASS=secret
154
+ * // EMAIL_FROM=noreply@example.com
155
+ *
156
+ * // Optionally configure pooling via atom
157
+ * alepha.state.set(nodemailerEmailOptions.key, {
158
+ * pool: true,
159
+ * maxConnections: 5,
160
+ * rateLimit: 10,
161
+ * });
162
+ * ```
163
+ */
128
164
  declare class NodemailerEmailProvider implements EmailProvider {
129
165
  protected readonly env: {
130
- EMAIL_HOST: string;
166
+ EMAIL_HOST?: string | undefined;
167
+ EMAIL_USER?: string | undefined;
168
+ EMAIL_PASS?: string | undefined;
169
+ EMAIL_FROM?: string | undefined;
131
170
  EMAIL_PORT: number;
132
- EMAIL_USER: string;
133
- EMAIL_PASS: string;
134
- EMAIL_FROM: string;
135
171
  EMAIL_SECURE: boolean;
136
172
  };
137
173
  protected readonly log: alepha_logger0.Logger;
138
- protected transporter: Transporter;
139
- protected fromAddress: string;
140
- readonly options: NodemailerEmailProviderOptions;
141
- constructor();
174
+ protected readonly options: Readonly<{
175
+ pool?: boolean | undefined;
176
+ maxConnections?: number | undefined;
177
+ maxMessages?: number | undefined;
178
+ rateDelta?: number | undefined;
179
+ rateLimit?: number | undefined;
180
+ }>;
181
+ protected transporter: Transporter | null;
182
+ protected get host(): string;
183
+ protected get port(): number;
184
+ protected get secure(): boolean;
185
+ protected get user(): string | undefined;
186
+ protected get pass(): string | undefined;
187
+ protected get fromAddress(): string;
188
+ protected getTransporter(): Transporter;
142
189
  send(options: EmailSendOptions): Promise<void>;
143
190
  protected createTransporter(): Transporter;
144
191
  /**
145
- * Verify the connection to the email server.
146
- */
192
+ * Verify the connection to the email server.
193
+ */
147
194
  verify(): Promise<boolean>;
148
195
  /**
149
- * Close the transporter connection.
150
- */
196
+ * Close the transporter connection.
197
+ */
151
198
  close(): void;
152
199
  protected readonly onStart: alepha1.HookPrimitive<"start">;
153
200
  protected readonly onStop: alepha1.HookPrimitive<"stop">;
@@ -182,5 +229,5 @@ declare module "alepha" {
182
229
  */
183
230
  declare const AlephaEmail: alepha1.Service<alepha1.Module>;
184
231
  //#endregion
185
- export { $email, AlephaEmail, EmailError, EmailPrimitive, EmailPrimitiveOptions, EmailProvider, EmailRecord, EmailSendOptions, LocalEmailProvider, LocalEmailProviderOptions, MemoryEmailProvider, NodemailerEmailProvider, NodemailerEmailProviderOptions };
232
+ export { $email, AlephaEmail, EmailError, EmailPrimitive, EmailPrimitiveOptions, EmailProvider, EmailRecord, EmailSendOptions, LocalEmailProvider, LocalEmailProviderOptions, MemoryEmailProvider, NodemailerEmailProvider, NodemailerEmailProviderOptions, localEmailOptions, nodemailerEmailOptions };
186
233
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/email/providers/EmailProvider.ts","../../src/email/errors/EmailError.ts","../../src/email/primitives/$email.ts","../../src/email/providers/LocalEmailProvider.ts","../../src/email/providers/MemoryEmailProvider.ts","../../src/email/providers/NodemailerEmailProvider.ts","../../src/email/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;uBAKsB,aAAA;EAAA;AAStB;;;;ECda,SAAA,IAAW,CAAA,OAAA,EDWQ,gBCXK,CAAA,EDWc,OCXd,CAAA,IAAA,CAAA;;KDczB,gBAAA;;EEFC,OAAA,EAC6B,MAAA;EADV,IAAA,EAAA,MAAA;CAAqB;;;cDZxC,UAAA,SAAmB,KAAA;uCACO;;;;cCW1B;aAAmB,wBAAqB;;AFPrD,CAAA;AASY,UEGK,qBAAA,CFHW;;aEKf,kBAAkB;;ADnB/B;;;;ACYA;;;;;;AAKA;AAyBA;;;;;;;AAA6C,cAAhC,cAAA,SAAuB,SAAS,CAAC,qBAAD,CAAA,CAAA;+BAChB;;;ACrC7B;AAOA;EAAgC,IAAA,CAAA,OACR,EDsCK,gBCtCL,CAAA,EDsCwB,OCtCxB,CAAA,IAAA,CAAA;EAGD,UAAA,SAAA,CAAA,CAAA,EDuDE,aCvDF;;;;UAXN,yBAAA;;;;;AHDjB;AASY,cGDC,kBAAA,YAA8B,aHCf,CAAA;0BGDI,cAAA,CACR;;wBAGD;EFjBV,IAAA,CAAA,OAAA,EEqBgB,gBFpBU,CADP,EEqBgB,OFrBX,CAAA,IAAA,CAAA;;;;ICYxB,IAAA,EAC6B,MAAA;EADV,CAAA,CAAA,EAAA,MAAA;EAAqB,UAAA,CAAA,IAAA,EAAA,MAAA,CAAA,EAAA,MAAA;;;;UETpC,WAAA;;;;UAIP;AJFV;AASY,cIJC,mBAAA,YAA+B,aJIhB,CAAA;0BIJK,cAAA,CACT;WACN;gBAEW,mBAAmB;EHdnC;;;cG+BQ;AFnBrB;;;UGkBiB,8BAAA;;;;ALzBjB;EASY,WAAA,CAAA,EKqBI,WLrBY;;;;ACd5B;;;;ACYA;EAAgC,OAAA,CAAA,EAAA;IAAqB,IAAA,CAAA,EAAA,OAAA;;;;IAKpC,SAAA,CAAA,EAAA,MAAA;EAyBJ,CAAA;;AACgB,cGYhB,uBAAA,YAAmC,aHZnB,CAAA;EASA,mBAAA,GAAA,EAAA;IAAmB,UAAA,EAAA,MAAA;IAoBvB,UAAA,EAAA,MAAA;IA9BW,UAAA,EAAA,MAAA;IAAS,UAAA,EAAA,MAAA;;;;ECpC5B,mBAAA,GAAA,EEiDoB,cAAA,CAEb,MFnDkB;EAO7B,UAAA,WAAmB,EE6CP,WF7CO;EAAA,UAAA,WACR,EAAA,MAAA;EAGD,SAAA,OAAA,EE4CI,8BF5CJ;EAIM,WAAA,CAAA;EAAmB,IAAA,CAAA,OAAA,EE+CnB,gBF/CmB,CAAA,EE+CA,OF/CA,CAAA,IAAA,CAAA;EARL,UAAA,iBAAA,CAAA,CAAA,EEgFV,WFhFU;EAAa;;;YE6G/B;EDvHR;AAOjB;;EAEkB,KAAA,CAAA,CAAA,EAAA,IAAA;EAEW,mBAAA,OAAA,EC4GG,OAAA,CAkBJ,aD9HC,CAAA,OAAA,CAAA;EAAmB,mBAAA,MAAA,EC8HpB,OAAA,CAKD,aDnIqB,CAAA,MAAA,CAAA;;;;AJAhD,eAAY,QAAgB,CAAA;;;;MCdf,QAAW,EAAA,MACe;iBKsBtB;gBACD;;IJZH,CAAA;IAAmB,YAAA,EAAA;MAAqB,EAAA,EAAA,MAAA,GAAA,MAAA,EAAA;;gBIkBrC;;EJbC;AAyBjB;;;;;;;;;;;ACpCiB,cGyCJ,WHzC6B,EGyClB,OAAA,CAAA,OHzCkB,CG+ExC,OAAA,CAtCsB,MAAA,CHzCkB"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/email/providers/EmailProvider.ts","../../src/email/errors/EmailError.ts","../../src/email/primitives/$email.ts","../../src/email/providers/LocalEmailProvider.ts","../../src/email/providers/MemoryEmailProvider.ts","../../src/email/providers/NodemailerEmailProvider.ts","../../src/email/index.ts"],"mappings":"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"}