@axium/email 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/LICENSE.md +157 -0
  2. package/README.md +40 -0
  3. package/db.json +83 -0
  4. package/dist/client/index.d.ts +1 -0
  5. package/dist/client/index.js +1 -0
  6. package/dist/client/web_hook.d.ts +8 -0
  7. package/dist/client/web_hook.js +11 -0
  8. package/dist/common.d.ts +454 -0
  9. package/dist/common.js +127 -0
  10. package/dist/index.d.ts +1 -0
  11. package/dist/index.js +1 -0
  12. package/dist/server/api.d.ts +1 -0
  13. package/dist/server/api.js +138 -0
  14. package/dist/server/cli.d.ts +1 -0
  15. package/dist/server/cli.js +69 -0
  16. package/dist/server/db.d.ts +17 -0
  17. package/dist/server/db.js +2 -0
  18. package/dist/server/hooks.d.ts +4 -0
  19. package/dist/server/hooks.js +13 -0
  20. package/dist/server/index.d.ts +4 -0
  21. package/dist/server/index.js +4 -0
  22. package/dist/server/send.d.ts +45 -0
  23. package/dist/server/send.js +221 -0
  24. package/dist/server/smtp.d.ts +2 -0
  25. package/dist/server/smtp.js +128 -0
  26. package/lib/AddressChips.svelte +107 -0
  27. package/lib/Composer.svelte +245 -0
  28. package/lib/MessageRow.svelte +160 -0
  29. package/lib/ThreadMessage.svelte +218 -0
  30. package/lib/index.ts +4 -0
  31. package/lib/tsconfig.json +13 -0
  32. package/locales/en.json +57 -0
  33. package/package.json +83 -0
  34. package/routes/email/+layout.svelte +59 -0
  35. package/routes/email/+layout.ts +17 -0
  36. package/routes/email/+page.ts +5 -0
  37. package/routes/email/[folder]/+page.svelte +53 -0
  38. package/routes/email/[folder]/+page.ts +16 -0
  39. package/routes/email/[folder]/[id]/+page.svelte +133 -0
  40. package/routes/email/[folder]/[id]/+page.ts +12 -0
  41. package/routes/email/context.ts +10 -0
  42. package/routes/email/email.css +143 -0
  43. package/routes/tsconfig.json +13 -0
@@ -0,0 +1,454 @@
1
+ import * as z from 'zod';
2
+ /** A single address in a message header, e.g. `"James" <james@example.com>` */
3
+ export declare const Mailbox: z.ZodObject<{
4
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
5
+ address: z.ZodEmail;
6
+ }, z.core.$strip>;
7
+ export interface Mailbox extends z.infer<typeof Mailbox> {
8
+ }
9
+ export declare const emailFolders: readonly ["inbox", "sent", "drafts", "spam", "trash", "archive"];
10
+ export declare const EmailFolder: z.ZodLiteral<"inbox" | "sent" | "drafts" | "spam" | "trash" | "archive">;
11
+ export type EmailFolder = z.infer<typeof EmailFolder>;
12
+ export declare const Attachment: z.ZodObject<{
13
+ id: z.ZodUUID;
14
+ emailId: z.ZodUUID;
15
+ filename: z.ZodString;
16
+ contentType: z.ZodString;
17
+ size: z.ZodCoercedBigInt<unknown>;
18
+ }, z.core.$strip>;
19
+ export interface Attachment extends z.infer<typeof Attachment> {
20
+ }
21
+ /** The body of a message being composed (sent or saved as a draft) */
22
+ export declare const EmailInit: z.ZodObject<{
23
+ to: z.ZodDefault<z.ZodArray<z.ZodObject<{
24
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
25
+ address: z.ZodEmail;
26
+ }, z.core.$strip>>>;
27
+ cc: z.ZodDefault<z.ZodArray<z.ZodObject<{
28
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
29
+ address: z.ZodEmail;
30
+ }, z.core.$strip>>>;
31
+ bcc: z.ZodDefault<z.ZodArray<z.ZodObject<{
32
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
33
+ address: z.ZodEmail;
34
+ }, z.core.$strip>>>;
35
+ subject: z.ZodDefault<z.ZodString>;
36
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
37
+ inReplyTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
38
+ isDraft: z.ZodDefault<z.ZodBoolean>;
39
+ draftId: z.ZodOptional<z.ZodNullable<z.ZodUUID>>;
40
+ }, z.core.$strip>;
41
+ export interface EmailInit extends z.infer<typeof EmailInit> {
42
+ }
43
+ export declare const Email: z.ZodObject<{
44
+ id: z.ZodUUID;
45
+ userId: z.ZodUUID;
46
+ messageId: z.ZodString;
47
+ inReplyTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
48
+ references: z.ZodArray<z.ZodString>;
49
+ threadId: z.ZodUUID;
50
+ from: z.ZodObject<{
51
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
52
+ address: z.ZodEmail;
53
+ }, z.core.$strip>;
54
+ to: z.ZodArray<z.ZodObject<{
55
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
56
+ address: z.ZodEmail;
57
+ }, z.core.$strip>>;
58
+ cc: z.ZodArray<z.ZodObject<{
59
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
60
+ address: z.ZodEmail;
61
+ }, z.core.$strip>>;
62
+ bcc: z.ZodArray<z.ZodObject<{
63
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
64
+ address: z.ZodEmail;
65
+ }, z.core.$strip>>;
66
+ subject: z.ZodString;
67
+ snippet: z.ZodOptional<z.ZodNullable<z.ZodString>>;
68
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
69
+ html: z.ZodOptional<z.ZodNullable<z.ZodString>>;
70
+ date: z.ZodCoercedDate<unknown>;
71
+ received: z.ZodCoercedDate<unknown>;
72
+ folder: z.ZodLiteral<"inbox" | "sent" | "drafts" | "spam" | "trash" | "archive">;
73
+ read: z.ZodBoolean;
74
+ starred: z.ZodBoolean;
75
+ labels: z.ZodArray<z.ZodString>;
76
+ size: z.ZodInt;
77
+ attachments: z.ZodArray<z.ZodObject<{
78
+ id: z.ZodUUID;
79
+ emailId: z.ZodUUID;
80
+ filename: z.ZodString;
81
+ contentType: z.ZodString;
82
+ size: z.ZodCoercedBigInt<unknown>;
83
+ }, z.core.$strip>>;
84
+ }, z.core.$strip>;
85
+ export interface Email extends z.infer<typeof Email> {
86
+ }
87
+ /** Flag and draft changes */
88
+ export declare const EmailChangeable: z.ZodObject<{
89
+ folder: z.ZodOptional<z.ZodLiteral<"inbox" | "sent" | "drafts" | "spam" | "trash" | "archive">>;
90
+ read: z.ZodOptional<z.ZodBoolean>;
91
+ starred: z.ZodOptional<z.ZodBoolean>;
92
+ labels: z.ZodOptional<z.ZodArray<z.ZodString>>;
93
+ to: z.ZodOptional<z.ZodArray<z.ZodObject<{
94
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
95
+ address: z.ZodEmail;
96
+ }, z.core.$strip>>>;
97
+ cc: z.ZodOptional<z.ZodArray<z.ZodObject<{
98
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
99
+ address: z.ZodEmail;
100
+ }, z.core.$strip>>>;
101
+ bcc: z.ZodOptional<z.ZodArray<z.ZodObject<{
102
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
103
+ address: z.ZodEmail;
104
+ }, z.core.$strip>>>;
105
+ subject: z.ZodOptional<z.ZodString>;
106
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
107
+ }, z.core.$strip>;
108
+ export interface EmailChangeable extends z.infer<typeof EmailChangeable> {
109
+ }
110
+ export declare const EmailListQuery: z.ZodObject<{
111
+ folder: z.ZodOptional<z.ZodLiteral<"inbox" | "sent" | "drafts" | "spam" | "trash" | "archive">>;
112
+ starred: z.ZodOptional<z.ZodBoolean>;
113
+ limit: z.ZodDefault<z.ZodInt>;
114
+ offset: z.ZodDefault<z.ZodInt>;
115
+ }, z.core.$strip>;
116
+ export interface EmailListQuery extends z.infer<typeof EmailListQuery> {
117
+ }
118
+ export declare const EmailConfig: z.ZodObject<{
119
+ inbound: z.ZodObject<{
120
+ enabled: z.ZodBoolean;
121
+ port: z.ZodInt;
122
+ max_size: z.ZodNumber;
123
+ ssl_key: z.ZodOptional<z.ZodString>;
124
+ ssl_cert: z.ZodOptional<z.ZodString>;
125
+ }, z.core.$strip>;
126
+ }, z.core.$strip>;
127
+ export interface EmailConfig extends z.infer<typeof EmailConfig> {
128
+ }
129
+ declare module '@axium/core/plugins' {
130
+ interface $PluginConfigs {
131
+ '@axium/email': EmailConfig;
132
+ }
133
+ }
134
+ /**
135
+ * Split a plain text body into new content and the quoted ("nested") part of top-posted replies.
136
+ * Note this only handles plain text; quotes in HTML bodies are not detected.
137
+ */
138
+ export declare function splitQuoted(text: string): {
139
+ content: string;
140
+ quoted: string | null;
141
+ };
142
+ declare module '@axium/core/socket' {
143
+ interface ServerToClient {
144
+ 'email.received': z.ZodFunction<z.ZodTuple<[typeof Email]>, z.ZodVoid>;
145
+ }
146
+ }
147
+ declare const EmailAPI: {
148
+ readonly 'users/:id/email': {
149
+ readonly GET: readonly [z.ZodObject<{
150
+ folder: z.ZodOptional<z.ZodLiteral<"inbox" | "sent" | "drafts" | "spam" | "trash" | "archive">>;
151
+ starred: z.ZodOptional<z.ZodBoolean>;
152
+ limit: z.ZodDefault<z.ZodInt>;
153
+ offset: z.ZodDefault<z.ZodInt>;
154
+ }, z.core.$strip>, z.ZodArray<z.ZodObject<{
155
+ id: z.ZodUUID;
156
+ userId: z.ZodUUID;
157
+ messageId: z.ZodString;
158
+ inReplyTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
159
+ references: z.ZodArray<z.ZodString>;
160
+ threadId: z.ZodUUID;
161
+ from: z.ZodObject<{
162
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
163
+ address: z.ZodEmail;
164
+ }, z.core.$strip>;
165
+ to: z.ZodArray<z.ZodObject<{
166
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
167
+ address: z.ZodEmail;
168
+ }, z.core.$strip>>;
169
+ cc: z.ZodArray<z.ZodObject<{
170
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
171
+ address: z.ZodEmail;
172
+ }, z.core.$strip>>;
173
+ bcc: z.ZodArray<z.ZodObject<{
174
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
175
+ address: z.ZodEmail;
176
+ }, z.core.$strip>>;
177
+ subject: z.ZodString;
178
+ snippet: z.ZodOptional<z.ZodNullable<z.ZodString>>;
179
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
180
+ html: z.ZodOptional<z.ZodNullable<z.ZodString>>;
181
+ date: z.ZodCoercedDate<unknown>;
182
+ received: z.ZodCoercedDate<unknown>;
183
+ folder: z.ZodLiteral<"inbox" | "sent" | "drafts" | "spam" | "trash" | "archive">;
184
+ read: z.ZodBoolean;
185
+ starred: z.ZodBoolean;
186
+ labels: z.ZodArray<z.ZodString>;
187
+ size: z.ZodInt;
188
+ attachments: z.ZodArray<z.ZodObject<{
189
+ id: z.ZodUUID;
190
+ emailId: z.ZodUUID;
191
+ filename: z.ZodString;
192
+ contentType: z.ZodString;
193
+ size: z.ZodCoercedBigInt<unknown>;
194
+ }, z.core.$strip>>;
195
+ }, z.core.$strip>>];
196
+ readonly PUT: readonly [z.ZodObject<{
197
+ to: z.ZodDefault<z.ZodArray<z.ZodObject<{
198
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
199
+ address: z.ZodEmail;
200
+ }, z.core.$strip>>>;
201
+ cc: z.ZodDefault<z.ZodArray<z.ZodObject<{
202
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
203
+ address: z.ZodEmail;
204
+ }, z.core.$strip>>>;
205
+ bcc: z.ZodDefault<z.ZodArray<z.ZodObject<{
206
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
207
+ address: z.ZodEmail;
208
+ }, z.core.$strip>>>;
209
+ subject: z.ZodDefault<z.ZodString>;
210
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
211
+ inReplyTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
212
+ isDraft: z.ZodDefault<z.ZodBoolean>;
213
+ draftId: z.ZodOptional<z.ZodNullable<z.ZodUUID>>;
214
+ }, z.core.$strip>, z.ZodObject<{
215
+ id: z.ZodUUID;
216
+ userId: z.ZodUUID;
217
+ messageId: z.ZodString;
218
+ inReplyTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
219
+ references: z.ZodArray<z.ZodString>;
220
+ threadId: z.ZodUUID;
221
+ from: z.ZodObject<{
222
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
223
+ address: z.ZodEmail;
224
+ }, z.core.$strip>;
225
+ to: z.ZodArray<z.ZodObject<{
226
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
227
+ address: z.ZodEmail;
228
+ }, z.core.$strip>>;
229
+ cc: z.ZodArray<z.ZodObject<{
230
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
231
+ address: z.ZodEmail;
232
+ }, z.core.$strip>>;
233
+ bcc: z.ZodArray<z.ZodObject<{
234
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
235
+ address: z.ZodEmail;
236
+ }, z.core.$strip>>;
237
+ subject: z.ZodString;
238
+ snippet: z.ZodOptional<z.ZodNullable<z.ZodString>>;
239
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
240
+ html: z.ZodOptional<z.ZodNullable<z.ZodString>>;
241
+ date: z.ZodCoercedDate<unknown>;
242
+ received: z.ZodCoercedDate<unknown>;
243
+ folder: z.ZodLiteral<"inbox" | "sent" | "drafts" | "spam" | "trash" | "archive">;
244
+ read: z.ZodBoolean;
245
+ starred: z.ZodBoolean;
246
+ labels: z.ZodArray<z.ZodString>;
247
+ size: z.ZodInt;
248
+ attachments: z.ZodArray<z.ZodObject<{
249
+ id: z.ZodUUID;
250
+ emailId: z.ZodUUID;
251
+ filename: z.ZodString;
252
+ contentType: z.ZodString;
253
+ size: z.ZodCoercedBigInt<unknown>;
254
+ }, z.core.$strip>>;
255
+ }, z.core.$strip>];
256
+ };
257
+ readonly 'email/:id': {
258
+ readonly GET: z.ZodObject<{
259
+ id: z.ZodUUID;
260
+ userId: z.ZodUUID;
261
+ messageId: z.ZodString;
262
+ inReplyTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
263
+ references: z.ZodArray<z.ZodString>;
264
+ threadId: z.ZodUUID;
265
+ from: z.ZodObject<{
266
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
267
+ address: z.ZodEmail;
268
+ }, z.core.$strip>;
269
+ to: z.ZodArray<z.ZodObject<{
270
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
271
+ address: z.ZodEmail;
272
+ }, z.core.$strip>>;
273
+ cc: z.ZodArray<z.ZodObject<{
274
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
275
+ address: z.ZodEmail;
276
+ }, z.core.$strip>>;
277
+ bcc: z.ZodArray<z.ZodObject<{
278
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
279
+ address: z.ZodEmail;
280
+ }, z.core.$strip>>;
281
+ subject: z.ZodString;
282
+ snippet: z.ZodOptional<z.ZodNullable<z.ZodString>>;
283
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
284
+ html: z.ZodOptional<z.ZodNullable<z.ZodString>>;
285
+ date: z.ZodCoercedDate<unknown>;
286
+ received: z.ZodCoercedDate<unknown>;
287
+ folder: z.ZodLiteral<"inbox" | "sent" | "drafts" | "spam" | "trash" | "archive">;
288
+ read: z.ZodBoolean;
289
+ starred: z.ZodBoolean;
290
+ labels: z.ZodArray<z.ZodString>;
291
+ size: z.ZodInt;
292
+ attachments: z.ZodArray<z.ZodObject<{
293
+ id: z.ZodUUID;
294
+ emailId: z.ZodUUID;
295
+ filename: z.ZodString;
296
+ contentType: z.ZodString;
297
+ size: z.ZodCoercedBigInt<unknown>;
298
+ }, z.core.$strip>>;
299
+ }, z.core.$strip>;
300
+ readonly PATCH: readonly [z.ZodObject<{
301
+ folder: z.ZodOptional<z.ZodLiteral<"inbox" | "sent" | "drafts" | "spam" | "trash" | "archive">>;
302
+ read: z.ZodOptional<z.ZodBoolean>;
303
+ starred: z.ZodOptional<z.ZodBoolean>;
304
+ labels: z.ZodOptional<z.ZodArray<z.ZodString>>;
305
+ to: z.ZodOptional<z.ZodArray<z.ZodObject<{
306
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
307
+ address: z.ZodEmail;
308
+ }, z.core.$strip>>>;
309
+ cc: z.ZodOptional<z.ZodArray<z.ZodObject<{
310
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
311
+ address: z.ZodEmail;
312
+ }, z.core.$strip>>>;
313
+ bcc: z.ZodOptional<z.ZodArray<z.ZodObject<{
314
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
315
+ address: z.ZodEmail;
316
+ }, z.core.$strip>>>;
317
+ subject: z.ZodOptional<z.ZodString>;
318
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
319
+ }, z.core.$strip>, z.ZodObject<{
320
+ id: z.ZodUUID;
321
+ userId: z.ZodUUID;
322
+ messageId: z.ZodString;
323
+ inReplyTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
324
+ references: z.ZodArray<z.ZodString>;
325
+ threadId: z.ZodUUID;
326
+ from: z.ZodObject<{
327
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
328
+ address: z.ZodEmail;
329
+ }, z.core.$strip>;
330
+ to: z.ZodArray<z.ZodObject<{
331
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
332
+ address: z.ZodEmail;
333
+ }, z.core.$strip>>;
334
+ cc: z.ZodArray<z.ZodObject<{
335
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
336
+ address: z.ZodEmail;
337
+ }, z.core.$strip>>;
338
+ bcc: z.ZodArray<z.ZodObject<{
339
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
340
+ address: z.ZodEmail;
341
+ }, z.core.$strip>>;
342
+ subject: z.ZodString;
343
+ snippet: z.ZodOptional<z.ZodNullable<z.ZodString>>;
344
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
345
+ html: z.ZodOptional<z.ZodNullable<z.ZodString>>;
346
+ date: z.ZodCoercedDate<unknown>;
347
+ received: z.ZodCoercedDate<unknown>;
348
+ folder: z.ZodLiteral<"inbox" | "sent" | "drafts" | "spam" | "trash" | "archive">;
349
+ read: z.ZodBoolean;
350
+ starred: z.ZodBoolean;
351
+ labels: z.ZodArray<z.ZodString>;
352
+ size: z.ZodInt;
353
+ attachments: z.ZodArray<z.ZodObject<{
354
+ id: z.ZodUUID;
355
+ emailId: z.ZodUUID;
356
+ filename: z.ZodString;
357
+ contentType: z.ZodString;
358
+ size: z.ZodCoercedBigInt<unknown>;
359
+ }, z.core.$strip>>;
360
+ }, z.core.$strip>];
361
+ readonly DELETE: z.ZodObject<{
362
+ id: z.ZodUUID;
363
+ userId: z.ZodUUID;
364
+ messageId: z.ZodString;
365
+ inReplyTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
366
+ references: z.ZodArray<z.ZodString>;
367
+ threadId: z.ZodUUID;
368
+ from: z.ZodObject<{
369
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
370
+ address: z.ZodEmail;
371
+ }, z.core.$strip>;
372
+ to: z.ZodArray<z.ZodObject<{
373
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
374
+ address: z.ZodEmail;
375
+ }, z.core.$strip>>;
376
+ cc: z.ZodArray<z.ZodObject<{
377
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
378
+ address: z.ZodEmail;
379
+ }, z.core.$strip>>;
380
+ bcc: z.ZodArray<z.ZodObject<{
381
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
382
+ address: z.ZodEmail;
383
+ }, z.core.$strip>>;
384
+ subject: z.ZodString;
385
+ snippet: z.ZodOptional<z.ZodNullable<z.ZodString>>;
386
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
387
+ html: z.ZodOptional<z.ZodNullable<z.ZodString>>;
388
+ date: z.ZodCoercedDate<unknown>;
389
+ received: z.ZodCoercedDate<unknown>;
390
+ folder: z.ZodLiteral<"inbox" | "sent" | "drafts" | "spam" | "trash" | "archive">;
391
+ read: z.ZodBoolean;
392
+ starred: z.ZodBoolean;
393
+ labels: z.ZodArray<z.ZodString>;
394
+ size: z.ZodInt;
395
+ attachments: z.ZodArray<z.ZodObject<{
396
+ id: z.ZodUUID;
397
+ emailId: z.ZodUUID;
398
+ filename: z.ZodString;
399
+ contentType: z.ZodString;
400
+ size: z.ZodCoercedBigInt<unknown>;
401
+ }, z.core.$strip>>;
402
+ }, z.core.$strip>;
403
+ };
404
+ readonly 'email/:id/thread': {
405
+ readonly GET: z.ZodArray<z.ZodObject<{
406
+ id: z.ZodUUID;
407
+ userId: z.ZodUUID;
408
+ messageId: z.ZodString;
409
+ inReplyTo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
410
+ references: z.ZodArray<z.ZodString>;
411
+ threadId: z.ZodUUID;
412
+ from: z.ZodObject<{
413
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
414
+ address: z.ZodEmail;
415
+ }, z.core.$strip>;
416
+ to: z.ZodArray<z.ZodObject<{
417
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
418
+ address: z.ZodEmail;
419
+ }, z.core.$strip>>;
420
+ cc: z.ZodArray<z.ZodObject<{
421
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
422
+ address: z.ZodEmail;
423
+ }, z.core.$strip>>;
424
+ bcc: z.ZodArray<z.ZodObject<{
425
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
426
+ address: z.ZodEmail;
427
+ }, z.core.$strip>>;
428
+ subject: z.ZodString;
429
+ snippet: z.ZodOptional<z.ZodNullable<z.ZodString>>;
430
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
431
+ html: z.ZodOptional<z.ZodNullable<z.ZodString>>;
432
+ date: z.ZodCoercedDate<unknown>;
433
+ received: z.ZodCoercedDate<unknown>;
434
+ folder: z.ZodLiteral<"inbox" | "sent" | "drafts" | "spam" | "trash" | "archive">;
435
+ read: z.ZodBoolean;
436
+ starred: z.ZodBoolean;
437
+ labels: z.ZodArray<z.ZodString>;
438
+ size: z.ZodInt;
439
+ attachments: z.ZodArray<z.ZodObject<{
440
+ id: z.ZodUUID;
441
+ emailId: z.ZodUUID;
442
+ filename: z.ZodString;
443
+ contentType: z.ZodString;
444
+ size: z.ZodCoercedBigInt<unknown>;
445
+ }, z.core.$strip>>;
446
+ }, z.core.$strip>>;
447
+ };
448
+ };
449
+ type EmailAPI = typeof EmailAPI;
450
+ declare module '@axium/core/api' {
451
+ interface $API extends EmailAPI {
452
+ }
453
+ }
454
+ export {};
package/dist/common.js ADDED
@@ -0,0 +1,127 @@
1
+ import { serverConfigs } from '@axium/core';
2
+ import { $API } from '@axium/core/api';
3
+ import { addServerToClient } from '@axium/core/socket';
4
+ import * as z from 'zod';
5
+ /** A single address in a message header, e.g. `"James" <james@example.com>` */
6
+ export const Mailbox = z.object({
7
+ name: z.string().max(255).nullish(),
8
+ address: z.email().max(255),
9
+ });
10
+ export const emailFolders = ['inbox', 'sent', 'drafts', 'spam', 'trash', 'archive'];
11
+ export const EmailFolder = z.literal(emailFolders);
12
+ export const Attachment = z.object({
13
+ id: z.uuid(),
14
+ emailId: z.uuid(),
15
+ filename: z.string().max(255),
16
+ contentType: z.string().max(255),
17
+ size: z.coerce.bigint().nonnegative(),
18
+ });
19
+ /** The body of a message being composed (sent or saved as a draft) */
20
+ export const EmailInit = z.object({
21
+ to: Mailbox.array().max(100).default([]),
22
+ cc: Mailbox.array().max(100).default([]),
23
+ bcc: Mailbox.array().max(100).default([]),
24
+ subject: z.string().max(998).default(''),
25
+ text: z.string().max(1_000_000).nullish(),
26
+ inReplyTo: z.string().max(998).nullish(),
27
+ /** Save as a draft instead of sending */
28
+ isDraft: z.boolean().default(false),
29
+ /** When sending a previously saved draft, its ID */
30
+ draftId: z.uuid().nullish(),
31
+ });
32
+ export const Email = z.object({
33
+ id: z.uuid(),
34
+ userId: z.uuid(),
35
+ messageId: z.string().max(998),
36
+ inReplyTo: z.string().max(998).nullish(),
37
+ references: z.string().array(),
38
+ threadId: z.uuid(),
39
+ from: Mailbox,
40
+ to: Mailbox.array(),
41
+ cc: Mailbox.array(),
42
+ bcc: Mailbox.array(),
43
+ subject: z.string(),
44
+ snippet: z.string().nullish(),
45
+ text: z.string().nullish(),
46
+ html: z.string().nullish(),
47
+ /** From the Date header */
48
+ date: z.coerce.date(),
49
+ /** When the message was stored */
50
+ received: z.coerce.date(),
51
+ folder: EmailFolder,
52
+ read: z.boolean(),
53
+ starred: z.boolean(),
54
+ labels: z.string().array(),
55
+ /** Size of the raw message in bytes */
56
+ size: z.int().nonnegative(),
57
+ attachments: Attachment.array(),
58
+ });
59
+ /** Flag and draft changes */
60
+ export const EmailChangeable = z
61
+ .object({
62
+ folder: EmailFolder,
63
+ read: z.boolean(),
64
+ starred: z.boolean(),
65
+ labels: z.string().max(100).array().max(100),
66
+ // these can only be changed on drafts
67
+ to: Mailbox.array().max(100),
68
+ cc: Mailbox.array().max(100),
69
+ bcc: Mailbox.array().max(100),
70
+ subject: z.string().max(998),
71
+ text: z.string().max(1_000_000).nullable(),
72
+ })
73
+ .partial();
74
+ export const EmailListQuery = z.object({
75
+ folder: EmailFolder.optional(),
76
+ starred: z.boolean().optional(),
77
+ limit: z.int().min(1).max(200).default(50),
78
+ offset: z.int().nonnegative().default(0),
79
+ });
80
+ export const EmailConfig = z.object({
81
+ inbound: z.object({
82
+ enabled: z.boolean(),
83
+ port: z.int().min(1).max(65535),
84
+ /** Max inbound message size in KB */
85
+ max_size: z.number().min(0),
86
+ /** Override the web SSL certificate for STARTTLS */
87
+ ssl_key: z.string().optional(),
88
+ ssl_cert: z.string().optional(),
89
+ }),
90
+ });
91
+ serverConfigs.set('@axium/email', EmailConfig);
92
+ /**
93
+ * Split a plain text body into new content and the quoted ("nested") part of top-posted replies.
94
+ * Note this only handles plain text; quotes in HTML bodies are not detected.
95
+ */
96
+ export function splitQuoted(text) {
97
+ const lines = text.split('\n');
98
+ let start = lines.findIndex(line => /^\s*>/.test(line) || /^-{2,}\s*Original Message\s*-{2,}$/i.test(line));
99
+ if (start == -1)
100
+ return { content: text, quoted: null };
101
+ // include the attribution line (e.g. "On <date>, <name> wrote:") and blank lines directly above
102
+ let above = start - 1;
103
+ while (above >= 0 && !lines[above].trim())
104
+ above--;
105
+ if (above >= 0 && /wrote:\s*$/.test(lines[above]))
106
+ start = above;
107
+ const content = lines.slice(0, start).join('\n').trimEnd();
108
+ if (!content.trim())
109
+ return { content: text, quoted: null };
110
+ return { content, quoted: lines.slice(start).join('\n') };
111
+ }
112
+ addServerToClient({ 'email.received': [Email] });
113
+ const EmailAPI = {
114
+ 'users/:id/email': {
115
+ GET: [EmailListQuery, Email.array()],
116
+ PUT: [EmailInit, Email],
117
+ },
118
+ 'email/:id': {
119
+ GET: Email,
120
+ PATCH: [EmailChangeable, Email],
121
+ DELETE: Email,
122
+ },
123
+ 'email/:id/thread': {
124
+ GET: Email.array(),
125
+ },
126
+ };
127
+ Object.assign($API, EmailAPI);
@@ -0,0 +1 @@
1
+ export * from './common.js';
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from './common.js';
@@ -0,0 +1 @@
1
+ import './db.js';