@beignet/core 0.0.1 → 0.0.2

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 (274) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +149 -4
  3. package/dist/application/index.d.ts +93 -9
  4. package/dist/application/index.d.ts.map +1 -1
  5. package/dist/application/index.js +11 -11
  6. package/dist/application/index.js.map +1 -1
  7. package/dist/client/client.d.ts +73 -12
  8. package/dist/client/client.d.ts.map +1 -1
  9. package/dist/client/client.js +37 -12
  10. package/dist/client/client.js.map +1 -1
  11. package/dist/client/index.d.ts +12 -0
  12. package/dist/client/index.d.ts.map +1 -1
  13. package/dist/client/index.js +6 -0
  14. package/dist/client/index.js.map +1 -1
  15. package/dist/client/types.d.ts +69 -8
  16. package/dist/client/types.d.ts.map +1 -1
  17. package/dist/config/index.d.ts +84 -0
  18. package/dist/config/index.d.ts.map +1 -1
  19. package/dist/config/index.js +36 -0
  20. package/dist/config/index.js.map +1 -1
  21. package/dist/contracts/contract-builder.d.ts +49 -22
  22. package/dist/contracts/contract-builder.d.ts.map +1 -1
  23. package/dist/contracts/contract-builder.js +48 -21
  24. package/dist/contracts/contract-builder.js.map +1 -1
  25. package/dist/contracts/contract-group.d.ts +35 -19
  26. package/dist/contracts/contract-group.d.ts.map +1 -1
  27. package/dist/contracts/contract-group.js +35 -19
  28. package/dist/contracts/contract-group.js.map +1 -1
  29. package/dist/contracts/contract-like.d.ts +4 -4
  30. package/dist/contracts/contract-like.d.ts.map +1 -1
  31. package/dist/contracts/contract-like.js +2 -1
  32. package/dist/contracts/contract-like.js.map +1 -1
  33. package/dist/contracts/index.d.ts +28 -0
  34. package/dist/contracts/index.d.ts.map +1 -1
  35. package/dist/contracts/index.js +12 -0
  36. package/dist/contracts/index.js.map +1 -1
  37. package/dist/contracts/openapi-meta.d.ts +8 -8
  38. package/dist/contracts/openapi-meta.d.ts.map +1 -1
  39. package/dist/contracts/path-template.d.ts +27 -0
  40. package/dist/contracts/path-template.d.ts.map +1 -1
  41. package/dist/contracts/path-template.js +6 -0
  42. package/dist/contracts/path-template.js.map +1 -1
  43. package/dist/contracts/types.d.ts +104 -10
  44. package/dist/contracts/types.d.ts.map +1 -1
  45. package/dist/contracts/types.js +15 -0
  46. package/dist/contracts/types.js.map +1 -1
  47. package/dist/contracts/utils.d.ts +6 -0
  48. package/dist/contracts/utils.d.ts.map +1 -1
  49. package/dist/contracts/utils.js +6 -0
  50. package/dist/contracts/utils.js.map +1 -1
  51. package/dist/domain/entity.d.ts +22 -11
  52. package/dist/domain/entity.d.ts.map +1 -1
  53. package/dist/domain/entity.js +5 -1
  54. package/dist/domain/entity.js.map +1 -1
  55. package/dist/domain/events.d.ts +5 -2
  56. package/dist/domain/events.d.ts.map +1 -1
  57. package/dist/domain/events.js +4 -1
  58. package/dist/domain/events.js.map +1 -1
  59. package/dist/domain/value-object.d.ts +19 -9
  60. package/dist/domain/value-object.d.ts.map +1 -1
  61. package/dist/domain/value-object.js +5 -1
  62. package/dist/domain/value-object.js.map +1 -1
  63. package/dist/errors/catalog.d.ts +40 -16
  64. package/dist/errors/catalog.d.ts.map +1 -1
  65. package/dist/errors/catalog.js +18 -7
  66. package/dist/errors/catalog.js.map +1 -1
  67. package/dist/errors/response.d.ts +16 -4
  68. package/dist/errors/response.d.ts.map +1 -1
  69. package/dist/errors/response.js +3 -3
  70. package/dist/errors/response.js.map +1 -1
  71. package/dist/errors/validation.d.ts +10 -1
  72. package/dist/errors/validation.d.ts.map +1 -1
  73. package/dist/errors/validation.js +3 -0
  74. package/dist/errors/validation.js.map +1 -1
  75. package/dist/events/index.d.ts +133 -0
  76. package/dist/events/index.d.ts.map +1 -1
  77. package/dist/events/index.js +30 -0
  78. package/dist/events/index.js.map +1 -1
  79. package/dist/idempotency/index.d.ts +355 -0
  80. package/dist/idempotency/index.d.ts.map +1 -0
  81. package/dist/idempotency/index.js +360 -0
  82. package/dist/idempotency/index.js.map +1 -0
  83. package/dist/jobs/index.d.ts +110 -0
  84. package/dist/jobs/index.d.ts.map +1 -1
  85. package/dist/jobs/index.js +22 -0
  86. package/dist/jobs/index.js.map +1 -1
  87. package/dist/mail/index.d.ts +149 -0
  88. package/dist/mail/index.d.ts.map +1 -1
  89. package/dist/mail/index.js +30 -0
  90. package/dist/mail/index.js.map +1 -1
  91. package/dist/notifications/index.d.ts +369 -0
  92. package/dist/notifications/index.d.ts.map +1 -0
  93. package/dist/notifications/index.js +310 -0
  94. package/dist/notifications/index.js.map +1 -0
  95. package/dist/openapi/index.d.ts +132 -16
  96. package/dist/openapi/index.d.ts.map +1 -1
  97. package/dist/openapi/index.js +1 -1
  98. package/dist/openapi/index.js.map +1 -1
  99. package/dist/outbox/index.d.ts +469 -0
  100. package/dist/outbox/index.d.ts.map +1 -0
  101. package/dist/outbox/index.js +482 -0
  102. package/dist/outbox/index.js.map +1 -0
  103. package/dist/pagination/index.d.ts +166 -0
  104. package/dist/pagination/index.d.ts.map +1 -0
  105. package/dist/pagination/index.js +96 -0
  106. package/dist/pagination/index.js.map +1 -0
  107. package/dist/ports/audit.d.ts +271 -0
  108. package/dist/ports/audit.d.ts.map +1 -1
  109. package/dist/ports/audit.js +128 -0
  110. package/dist/ports/audit.js.map +1 -1
  111. package/dist/ports/auth.d.ts +70 -0
  112. package/dist/ports/auth.d.ts.map +1 -1
  113. package/dist/ports/auth.js +30 -0
  114. package/dist/ports/auth.js.map +1 -1
  115. package/dist/ports/cache.d.ts +41 -0
  116. package/dist/ports/cache.d.ts.map +1 -1
  117. package/dist/ports/cache.js +10 -0
  118. package/dist/ports/cache.js.map +1 -1
  119. package/dist/ports/clock.d.ts +38 -0
  120. package/dist/ports/clock.d.ts.map +1 -1
  121. package/dist/ports/clock.js +20 -0
  122. package/dist/ports/clock.js.map +1 -1
  123. package/dist/ports/id-generator.d.ts +37 -0
  124. package/dist/ports/id-generator.d.ts.map +1 -1
  125. package/dist/ports/id-generator.js +22 -0
  126. package/dist/ports/id-generator.js.map +1 -1
  127. package/dist/ports/index.d.ts +83 -0
  128. package/dist/ports/index.d.ts.map +1 -1
  129. package/dist/ports/index.js +41 -5
  130. package/dist/ports/index.js.map +1 -1
  131. package/dist/ports/logger.d.ts +56 -0
  132. package/dist/ports/logger.d.ts.map +1 -1
  133. package/dist/ports/logger.js +17 -0
  134. package/dist/ports/logger.js.map +1 -1
  135. package/dist/ports/policy.d.ts +132 -0
  136. package/dist/ports/policy.d.ts.map +1 -1
  137. package/dist/ports/policy.js +45 -0
  138. package/dist/ports/policy.js.map +1 -1
  139. package/dist/ports/rate-limit.d.ts +25 -0
  140. package/dist/ports/rate-limit.d.ts.map +1 -1
  141. package/dist/ports/rate-limit.js +10 -0
  142. package/dist/ports/rate-limit.js.map +1 -1
  143. package/dist/ports/redaction.d.ts +101 -0
  144. package/dist/ports/redaction.d.ts.map +1 -1
  145. package/dist/ports/redaction.js +59 -0
  146. package/dist/ports/redaction.js.map +1 -1
  147. package/dist/ports/storage.d.ts +100 -0
  148. package/dist/ports/storage.d.ts.map +1 -1
  149. package/dist/ports/storage.js +10 -0
  150. package/dist/ports/storage.js.map +1 -1
  151. package/dist/ports/testing.d.ts +47 -0
  152. package/dist/ports/testing.d.ts.map +1 -1
  153. package/dist/ports/testing.js +23 -0
  154. package/dist/ports/testing.js.map +1 -1
  155. package/dist/ports/unit-of-work.d.ts +60 -3
  156. package/dist/ports/unit-of-work.d.ts.map +1 -1
  157. package/dist/ports/unit-of-work.js +11 -2
  158. package/dist/ports/unit-of-work.js.map +1 -1
  159. package/dist/providers/instrumentation.d.ts +204 -0
  160. package/dist/providers/instrumentation.d.ts.map +1 -1
  161. package/dist/providers/instrumentation.js +14 -0
  162. package/dist/providers/instrumentation.js.map +1 -1
  163. package/dist/providers/provider.d.ts +14 -1
  164. package/dist/providers/provider.d.ts.map +1 -1
  165. package/dist/providers/provider.js.map +1 -1
  166. package/dist/schedules/index.d.ts +246 -0
  167. package/dist/schedules/index.d.ts.map +1 -1
  168. package/dist/schedules/index.js +27 -0
  169. package/dist/schedules/index.js.map +1 -1
  170. package/dist/server/health.d.ts +14 -5
  171. package/dist/server/health.d.ts.map +1 -1
  172. package/dist/server/health.js +5 -2
  173. package/dist/server/health.js.map +1 -1
  174. package/dist/server/hooks/auth.d.ts +57 -0
  175. package/dist/server/hooks/auth.d.ts.map +1 -1
  176. package/dist/server/hooks/auth.js.map +1 -1
  177. package/dist/server/hooks/cors.d.ts +27 -0
  178. package/dist/server/hooks/cors.d.ts.map +1 -1
  179. package/dist/server/hooks/cors.js +12 -0
  180. package/dist/server/hooks/cors.js.map +1 -1
  181. package/dist/server/hooks/errors.d.ts +15 -6
  182. package/dist/server/hooks/errors.d.ts.map +1 -1
  183. package/dist/server/hooks/errors.js.map +1 -1
  184. package/dist/server/hooks/index.d.ts +3 -0
  185. package/dist/server/hooks/index.d.ts.map +1 -1
  186. package/dist/server/hooks/index.js +3 -0
  187. package/dist/server/hooks/index.js.map +1 -1
  188. package/dist/server/hooks/logging.d.ts +36 -0
  189. package/dist/server/hooks/logging.d.ts.map +1 -1
  190. package/dist/server/hooks/logging.js +6 -0
  191. package/dist/server/hooks/logging.js.map +1 -1
  192. package/dist/server/hooks/rate-limit.d.ts +33 -0
  193. package/dist/server/hooks/rate-limit.d.ts.map +1 -1
  194. package/dist/server/hooks/rate-limit.js +11 -0
  195. package/dist/server/hooks/rate-limit.js.map +1 -1
  196. package/dist/server/http.d.ts +170 -0
  197. package/dist/server/http.d.ts.map +1 -1
  198. package/dist/server/index.d.ts +18 -0
  199. package/dist/server/index.d.ts.map +1 -1
  200. package/dist/server/index.js +6 -0
  201. package/dist/server/index.js.map +1 -1
  202. package/dist/server/openapi.d.ts +5 -3
  203. package/dist/server/openapi.d.ts.map +1 -1
  204. package/dist/server/openapi.js +4 -2
  205. package/dist/server/openapi.js.map +1 -1
  206. package/dist/server/providers/loadProviderConfig.d.ts +9 -0
  207. package/dist/server/providers/loadProviderConfig.d.ts.map +1 -1
  208. package/dist/server/providers/loadProviderConfig.js +9 -0
  209. package/dist/server/providers/loadProviderConfig.js.map +1 -1
  210. package/dist/server/server.d.ts +107 -8
  211. package/dist/server/server.d.ts.map +1 -1
  212. package/dist/server/server.js +27 -7
  213. package/dist/server/server.js.map +1 -1
  214. package/dist/testing/index.d.ts +167 -0
  215. package/dist/testing/index.d.ts.map +1 -0
  216. package/dist/testing/index.js +119 -0
  217. package/dist/testing/index.js.map +1 -0
  218. package/package.json +21 -1
  219. package/src/application/index.ts +85 -22
  220. package/src/client/client.ts +73 -12
  221. package/src/client/index.ts +12 -0
  222. package/src/client/types.ts +70 -9
  223. package/src/config/index.ts +86 -0
  224. package/src/contracts/contract-builder.ts +49 -22
  225. package/src/contracts/contract-group.ts +35 -19
  226. package/src/contracts/contract-like.ts +4 -4
  227. package/src/contracts/index.ts +28 -1
  228. package/src/contracts/openapi-meta.ts +8 -8
  229. package/src/contracts/path-template.ts +27 -0
  230. package/src/contracts/types.ts +111 -10
  231. package/src/contracts/utils.ts +6 -0
  232. package/src/domain/entity.ts +22 -11
  233. package/src/domain/events.ts +5 -2
  234. package/src/domain/value-object.ts +19 -9
  235. package/src/errors/catalog.ts +40 -16
  236. package/src/errors/response.ts +16 -4
  237. package/src/errors/validation.ts +10 -1
  238. package/src/events/index.ts +134 -0
  239. package/src/idempotency/index.ts +767 -0
  240. package/src/jobs/index.ts +111 -0
  241. package/src/mail/index.ts +149 -0
  242. package/src/notifications/index.ts +771 -0
  243. package/src/openapi/index.ts +133 -16
  244. package/src/outbox/index.ts +1024 -0
  245. package/src/pagination/index.ts +278 -0
  246. package/src/ports/audit.ts +271 -0
  247. package/src/ports/auth.ts +70 -0
  248. package/src/ports/cache.ts +41 -0
  249. package/src/ports/clock.ts +38 -0
  250. package/src/ports/id-generator.ts +37 -0
  251. package/src/ports/index.ts +106 -11
  252. package/src/ports/logger.ts +56 -0
  253. package/src/ports/policy.ts +133 -0
  254. package/src/ports/rate-limit.ts +25 -0
  255. package/src/ports/redaction.ts +101 -0
  256. package/src/ports/storage.ts +100 -0
  257. package/src/ports/testing.ts +47 -0
  258. package/src/ports/unit-of-work.ts +60 -3
  259. package/src/providers/instrumentation.ts +204 -0
  260. package/src/providers/provider.ts +14 -1
  261. package/src/schedules/index.ts +247 -0
  262. package/src/server/health.ts +14 -5
  263. package/src/server/hooks/auth.ts +58 -0
  264. package/src/server/hooks/cors.ts +27 -0
  265. package/src/server/hooks/errors.ts +15 -6
  266. package/src/server/hooks/index.ts +3 -0
  267. package/src/server/hooks/logging.ts +36 -0
  268. package/src/server/hooks/rate-limit.ts +33 -0
  269. package/src/server/http.ts +170 -1
  270. package/src/server/index.ts +18 -1
  271. package/src/server/openapi.ts +5 -3
  272. package/src/server/providers/loadProviderConfig.ts +9 -0
  273. package/src/server/server.ts +107 -9
  274. package/src/testing/index.ts +337 -0
package/src/jobs/index.ts CHANGED
@@ -1,35 +1,84 @@
1
1
  import type { StandardSchemaV1 } from "@standard-schema/spec";
2
2
 
3
+ /**
4
+ * Any Standard Schema compatible validator.
5
+ */
3
6
  export type StandardSchema = StandardSchemaV1<unknown, unknown>;
7
+
8
+ /**
9
+ * Value or promise of that value.
10
+ */
4
11
  export type MaybePromise<T> = T | Promise<T>;
5
12
 
13
+ /**
14
+ * Infer the parsed output type from a Standard Schema.
15
+ */
6
16
  export type InferSchemaOutput<T extends StandardSchemaV1> =
7
17
  StandardSchemaV1.InferOutput<T>;
8
18
 
19
+ /**
20
+ * Job definition created by `defineJob(...)`.
21
+ */
9
22
  export interface JobDef<
10
23
  Name extends string = string,
11
24
  Payload extends StandardSchema = StandardSchema,
12
25
  Ctx = unknown,
13
26
  > {
27
+ /**
28
+ * Discriminator for job definitions.
29
+ */
14
30
  readonly kind: "job";
31
+ /**
32
+ * Stable job name used by dispatchers and provider adapters.
33
+ */
15
34
  readonly name: Name;
35
+ /**
36
+ * Standard Schema payload validator.
37
+ */
16
38
  readonly payload: Payload;
39
+ /**
40
+ * Optional human-readable description for docs and tooling.
41
+ */
17
42
  readonly description?: string;
43
+ /**
44
+ * Retry metadata for durable job providers.
45
+ */
18
46
  readonly retry?: JobRetryOptions;
47
+ /**
48
+ * Handle a parsed job payload.
49
+ */
19
50
  handle(
20
51
  args: JobHandleArgs<JobDef<Name, Payload, Ctx>, Ctx>,
21
52
  ): MaybePromise<void>;
22
53
  }
23
54
 
55
+ /**
56
+ * Infer the parsed payload type for a job definition.
57
+ */
24
58
  export type InferJobPayload<J extends JobDef> =
25
59
  J["payload"] extends StandardSchemaV1<unknown, infer Output> ? Output : never;
26
60
 
61
+ /**
62
+ * Arguments passed to a job handler.
63
+ */
27
64
  export interface JobHandleArgs<J extends JobDef, Ctx> {
65
+ /**
66
+ * Job definition being handled.
67
+ */
28
68
  job: J;
69
+ /**
70
+ * Parsed job payload.
71
+ */
29
72
  payload: InferJobPayload<J>;
73
+ /**
74
+ * Handler context.
75
+ */
30
76
  ctx: Ctx;
31
77
  }
32
78
 
79
+ /**
80
+ * Retry metadata that durable job providers can map to their own retry model.
81
+ */
33
82
  export interface JobRetryOptions {
34
83
  /**
35
84
  * Maximum number of retry attempts a durable job adapter should request.
@@ -40,43 +89,89 @@ export interface JobRetryOptions {
40
89
  attempts?: number;
41
90
  }
42
91
 
92
+ /**
93
+ * Options for declaring a typed job.
94
+ */
43
95
  export interface DefineJobOptions<
44
96
  Name extends string,
45
97
  Payload extends StandardSchema,
46
98
  Ctx,
47
99
  > {
100
+ /**
101
+ * Standard Schema payload validator.
102
+ */
48
103
  payload: Payload;
104
+ /**
105
+ * Optional human-readable description for docs and tooling.
106
+ */
49
107
  description?: string;
108
+ /**
109
+ * Retry metadata for durable job providers.
110
+ */
50
111
  retry?: JobRetryOptions;
112
+ /**
113
+ * Handle a parsed job payload.
114
+ */
51
115
  handle(
52
116
  args: JobHandleArgs<JobDef<Name, Payload, Ctx>, Ctx>,
53
117
  ): MaybePromise<void>;
54
118
  }
55
119
 
120
+ /**
121
+ * Options for the inline job dispatcher.
122
+ */
56
123
  export interface InlineJobDispatcherOptions<Ctx> {
124
+ /**
125
+ * Static job context or factory evaluated for each dispatched job.
126
+ */
57
127
  ctx?: Ctx | (() => MaybePromise<Ctx>);
128
+ /**
129
+ * Called when a dispatched inline job fails. When omitted, errors are
130
+ * rethrown to the caller.
131
+ */
58
132
  onError?: (error: unknown, job: JobDef<string, StandardSchema, Ctx>) => void;
59
133
  }
60
134
 
135
+ /**
136
+ * Local/test job dispatcher that executes job handlers inline.
137
+ */
61
138
  export interface InlineJobDispatcher<Ctx = unknown> {
139
+ /**
140
+ * Validate a payload and run the job handler immediately.
141
+ */
62
142
  dispatch<J extends JobDef<string, StandardSchema, Ctx>>(
63
143
  job: J,
64
144
  payload: InferJobPayload<J>,
65
145
  ): Promise<void>;
66
146
  }
67
147
 
148
+ /**
149
+ * Context-bound job helper factory.
150
+ */
68
151
  export interface JobHandlers<Ctx> {
152
+ /**
153
+ * Define a job with the bound context type.
154
+ */
69
155
  defineJob<Name extends string, Payload extends StandardSchema>(
70
156
  name: Name,
71
157
  options: DefineJobOptions<Name, Payload, Ctx>,
72
158
  ): JobDef<Name, Payload, Ctx>;
73
159
 
160
+ /**
161
+ * Create an inline dispatcher with the bound context type.
162
+ */
74
163
  createInlineJobDispatcher(
75
164
  options?: InlineJobDispatcherOptions<Ctx>,
76
165
  ): InlineJobDispatcher<Ctx>;
77
166
  }
78
167
 
168
+ /**
169
+ * Error thrown when job payload validation fails.
170
+ */
79
171
  export class JobValidationError extends Error {
172
+ /**
173
+ * Raw Standard Schema validation issues.
174
+ */
80
175
  readonly issues: readonly StandardSchemaV1.Issue[];
81
176
 
82
177
  constructor(args: {
@@ -143,6 +238,13 @@ async function resolveCtx<Ctx>(
143
238
  return ctx as Ctx;
144
239
  }
145
240
 
241
+ /**
242
+ * Define a typed job.
243
+ *
244
+ * Retry options are provider hints. Inline dispatchers validate payloads and
245
+ * call `handle(...)` immediately; durable providers may enqueue or schedule the
246
+ * job according to their own runtime.
247
+ */
146
248
  export function defineJob<
147
249
  Name extends string,
148
250
  Payload extends StandardSchema,
@@ -161,6 +263,9 @@ export function defineJob<
161
263
  };
162
264
  }
163
265
 
266
+ /**
267
+ * Validate and parse a job payload with the job's Standard Schema.
268
+ */
164
269
  export async function parseJobPayload<J extends JobDef>(
165
270
  job: J,
166
271
  payload: unknown,
@@ -170,6 +275,9 @@ export async function parseJobPayload<J extends JobDef>(
170
275
  })) as InferJobPayload<J>;
171
276
  }
172
277
 
278
+ /**
279
+ * Create a local/test dispatcher that runs job handlers inline.
280
+ */
173
281
  export function createInlineJobDispatcher<Ctx>(
174
282
  options: InlineJobDispatcherOptions<Ctx> = {},
175
283
  ): InlineJobDispatcher<Ctx> {
@@ -193,6 +301,9 @@ export function createInlineJobDispatcher<Ctx>(
193
301
  };
194
302
  }
195
303
 
304
+ /**
305
+ * Create job helper methods bound to an application context type.
306
+ */
196
307
  export function createJobHandlers<Ctx>(): JobHandlers<Ctx> {
197
308
  return {
198
309
  defineJob<Name extends string, Payload extends StandardSchema>(
package/src/mail/index.ts CHANGED
@@ -4,27 +4,71 @@
4
4
  * Shared mail port and test adapters for Beignet applications.
5
5
  */
6
6
 
7
+ /**
8
+ * Value or promise of that value.
9
+ */
7
10
  export type MaybePromise<T> = T | Promise<T>;
8
11
 
12
+ /**
13
+ * Email address accepted by Beignet mail helpers.
14
+ */
9
15
  export type MailAddress =
10
16
  | string
11
17
  | {
18
+ /**
19
+ * Email address.
20
+ */
12
21
  email: string;
22
+ /**
23
+ * Optional display name.
24
+ */
13
25
  name?: string;
14
26
  };
15
27
 
28
+ /**
29
+ * Single address or address list.
30
+ */
16
31
  export type MailAddressList = MailAddress | readonly MailAddress[];
17
32
 
33
+ /**
34
+ * Common mail message fields shared by all send options.
35
+ */
18
36
  export interface MailBaseMessage {
37
+ /**
38
+ * Required recipients.
39
+ */
19
40
  to: MailAddressList;
41
+ /**
42
+ * Message subject.
43
+ */
20
44
  subject: string;
45
+ /**
46
+ * Sender address. Providers or adapters may supply a default.
47
+ */
21
48
  from?: MailAddress;
49
+ /**
50
+ * Carbon-copy recipients.
51
+ */
22
52
  cc?: MailAddressList;
53
+ /**
54
+ * Blind-carbon-copy recipients.
55
+ */
23
56
  bcc?: MailAddressList;
57
+ /**
58
+ * Reply-to recipients.
59
+ */
24
60
  replyTo?: MailAddressList;
61
+ /**
62
+ * Provider-specific message headers.
63
+ */
25
64
  headers?: Record<string, string>;
26
65
  }
27
66
 
67
+ /**
68
+ * Mail send options.
69
+ *
70
+ * A message must include at least one body format: `text` or `html`.
71
+ */
28
72
  export type SendMailOptions = MailBaseMessage &
29
73
  (
30
74
  | {
@@ -37,45 +81,129 @@ export type SendMailOptions = MailBaseMessage &
37
81
  }
38
82
  );
39
83
 
84
+ /**
85
+ * Normalized mail message with address fields converted to arrays.
86
+ */
40
87
  export interface NormalizedMailMessage extends MailBaseMessage {
88
+ /**
89
+ * Normalized recipients.
90
+ */
41
91
  to: readonly MailAddress[];
92
+ /**
93
+ * Sender address after applying any default.
94
+ */
42
95
  from?: MailAddress;
96
+ /**
97
+ * Normalized carbon-copy recipients.
98
+ */
43
99
  cc?: readonly MailAddress[];
100
+ /**
101
+ * Normalized blind-carbon-copy recipients.
102
+ */
44
103
  bcc?: readonly MailAddress[];
104
+ /**
105
+ * Normalized reply-to recipients.
106
+ */
45
107
  replyTo?: readonly MailAddress[];
108
+ /**
109
+ * Plain text body.
110
+ */
46
111
  text?: string;
112
+ /**
113
+ * HTML body.
114
+ */
47
115
  html?: string;
48
116
  }
49
117
 
118
+ /**
119
+ * Result returned by a mail provider.
120
+ */
50
121
  export interface SendMailResult {
122
+ /**
123
+ * Provider message ID when available.
124
+ */
51
125
  id?: string;
126
+ /**
127
+ * Provider name.
128
+ */
52
129
  provider?: string;
53
130
  }
54
131
 
132
+ /**
133
+ * App-facing mailer port.
134
+ */
55
135
  export interface MailerPort {
136
+ /**
137
+ * Send one mail message.
138
+ */
56
139
  send(message: SendMailOptions): Promise<SendMailResult>;
57
140
  }
58
141
 
142
+ /**
143
+ * Delivery captured by the memory mailer.
144
+ */
59
145
  export interface MemoryMailDelivery {
146
+ /**
147
+ * Generated delivery ID.
148
+ */
60
149
  id: string;
150
+ /**
151
+ * Normalized message that would have been sent.
152
+ */
61
153
  message: NormalizedMailMessage;
154
+ /**
155
+ * Timestamp assigned by the memory mailer.
156
+ */
62
157
  sentAt: Date;
63
158
  }
64
159
 
160
+ /**
161
+ * In-memory mailer port for tests and local examples.
162
+ */
65
163
  export interface MemoryMailerPort extends MailerPort {
164
+ /**
165
+ * Captured deliveries.
166
+ */
66
167
  readonly deliveries: readonly MemoryMailDelivery[];
168
+ /**
169
+ * Clear captured deliveries.
170
+ */
67
171
  clear(): void;
68
172
  }
69
173
 
174
+ /**
175
+ * Options for `createMemoryMailer(...)`.
176
+ */
70
177
  export interface CreateMemoryMailerOptions {
178
+ /**
179
+ * Sender used when a message does not specify `from`.
180
+ */
71
181
  defaultFrom?: MailAddress;
182
+ /**
183
+ * Clock used for captured deliveries.
184
+ */
72
185
  now?: () => Date;
186
+ /**
187
+ * ID factory used for captured deliveries.
188
+ */
73
189
  id?: () => string;
190
+ /**
191
+ * Observer called after a delivery is captured.
192
+ */
74
193
  onSend?: (delivery: MemoryMailDelivery) => MaybePromise<void>;
75
194
  }
76
195
 
196
+ /**
197
+ * Error thrown by mail helpers and provider adapters.
198
+ */
77
199
  export class MailDeliveryError extends Error {
200
+ /**
201
+ * Provider name when known.
202
+ */
78
203
  readonly provider?: string;
204
+ /**
205
+ * Original provider error when available.
206
+ */
79
207
  readonly cause?: unknown;
80
208
 
81
209
  constructor(args: { provider?: string; message: string; cause?: unknown }) {
@@ -86,6 +214,11 @@ export class MailDeliveryError extends Error {
86
214
  }
87
215
  }
88
216
 
217
+ /**
218
+ * Normalize a single address or address list into an array.
219
+ *
220
+ * This helper does not validate email syntax.
221
+ */
89
222
  export function normalizeMailAddressList(
90
223
  addresses: MailAddressList | undefined,
91
224
  ): readonly MailAddress[] | undefined {
@@ -100,6 +233,9 @@ function normalizeOptionalMailAddressList(
100
233
  return normalized && normalized.length > 0 ? normalized : undefined;
101
234
  }
102
235
 
236
+ /**
237
+ * Format one address for providers that accept RFC-like address strings.
238
+ */
103
239
  export function formatMailAddress(address: MailAddress): string {
104
240
  if (typeof address === "string") return address;
105
241
  if (!address.name) return address.email;
@@ -108,6 +244,9 @@ export function formatMailAddress(address: MailAddress): string {
108
244
  return `"${escapedName}" <${address.email}>`;
109
245
  }
110
246
 
247
+ /**
248
+ * Format one or more addresses for providers that accept string address fields.
249
+ */
111
250
  export function formatMailAddressList(
112
251
  addresses: MailAddressList,
113
252
  ): string | string[] {
@@ -116,6 +255,11 @@ export function formatMailAddressList(
116
255
  return formatted.length === 1 ? formatted[0] : formatted;
117
256
  }
118
257
 
258
+ /**
259
+ * Normalize a mail message and apply a default sender.
260
+ *
261
+ * Throws when the message has no recipients.
262
+ */
119
263
  export function normalizeMailMessage(
120
264
  message: SendMailOptions,
121
265
  options: { defaultFrom?: MailAddress } = {},
@@ -140,6 +284,11 @@ export function normalizeMailMessage(
140
284
  };
141
285
  }
142
286
 
287
+ /**
288
+ * Create an in-memory mailer for tests, local development, and examples.
289
+ *
290
+ * The memory mailer does not send real email or validate address syntax.
291
+ */
143
292
  export function createMemoryMailer(
144
293
  options: CreateMemoryMailerOptions = {},
145
294
  ): MemoryMailerPort {