My agentic slop goes here. Not intended for anyone else!
1(** Eio-based JMAP client implementation interface.
2
3 This module provides functions to interact with a JMAP server using
4 Eio for structured concurrency and network communication.
5
6 @see <https://www.rfc-editor.org/rfc/rfc8620.html#section-4> RFC 8620, Section 4
7*)
8
9(** TLS configuration options *)
10type tls_config = {
11 authenticator : X509.Authenticator.t option; (** Custom TLS authenticator *)
12 certificates : Tls.Config.own_cert list; (** Client certificates for mutual TLS *)
13 ciphers : Tls.Ciphersuite.ciphersuite list option; (** Allowed cipher suites *)
14 version : (Tls.Core.tls_version * Tls.Core.tls_version) option; (** Min and max TLS versions *)
15 alpn_protocols : string list option; (** ALPN protocol list *)
16}
17
18(** Configuration options for a JMAP client context *)
19type client_config = {
20 connect_timeout : float option; (** Connection timeout in seconds *)
21 request_timeout : float option; (** Request timeout in seconds *)
22 max_concurrent_requests : int option; (** Maximum concurrent requests *)
23 max_request_size : int option; (** Maximum request size in bytes *)
24 user_agent : string option; (** User-Agent header value *)
25 authentication_header : string option; (** Custom Authentication header name *)
26 tls : tls_config option; (** TLS configuration *)
27}
28
29(** Authentication method options *)
30type auth_method =
31 | Basic of string * string (** Basic auth with username and password *)
32 | Bearer of string (** Bearer token auth *)
33 | Custom of (string * string) (** Custom header name and value *)
34 | Session_cookie of (string * string) (** Session cookie name and value *)
35 | No_auth (** No authentication *)
36
37(** Represents an active JMAP connection context. Opaque type. *)
38type context
39
40(** Represents an active EventSource connection. Opaque type. *)
41type event_source_connection
42
43(** A request builder for constructing and sending JMAP requests *)
44type request_builder
45
46(** Create default TLS configuration with system CA certificates *)
47val default_tls_config : unit -> tls_config
48
49(** Create default configuration options *)
50val default_config : unit -> client_config
51
52(** {1 Session Discovery and Authentication} *)
53
54(** Authentication types for session retrieval. *)
55type session_auth =
56 | Bearer_token of string (** OAuth2 bearer token *)
57 | Basic_auth of string * string (** Username and password *)
58 | No_session_auth (** No authentication *)
59
60(** Service discovery for JMAP.
61
62 Attempts to discover the JMAP session endpoint using well-known URIs.
63 Follows RFC 8620 service discovery process.
64
65 @param env Eio environment for network operations
66 @param domain The domain to discover JMAP service for
67 @return The session URL if discovery succeeds, None otherwise
68 @see <https://www.rfc-editor.org/rfc/rfc8620.html#section-2.2> RFC 8620, Section 2.2 *)
69val discover_session :
70 env:< net : 'a Eio.Net.t ; clock : 'b Eio.Time.clock ; .. > ->
71 domain:string ->
72 Uri.t option
73
74(** Fetch a session object from a given URL with authentication.
75
76 Retrieves and parses the session resource from the server using cohttp-eio.
77
78 @param env Eio environment for network operations
79 @param url The session endpoint URL
80 @param auth Authentication credentials to use
81 @return The parsed session object or error message *)
82val get_session :
83 env:< net : 'a Eio.Net.t ; clock : 'b Eio.Time.clock ; .. > ->
84 url:Uri.t ->
85 auth:session_auth ->
86 (Jmap.Session.Session.t, string) result
87
88(** Extract domain from email address for discovery.
89
90 Utility function to extract the domain part from an email address.
91
92 @param email Email address to extract domain from
93 @return Domain string or error message *)
94val extract_domain_from_email : email:string -> (string, string) result
95
96(** Create a client context with the specified configuration
97 @return The context object used for JMAP API calls
98*)
99val create_client :
100 ?config:client_config ->
101 unit ->
102 context
103
104(** Enable connection pooling on a client context.
105 @param ctx The client context to enable pooling for
106 @param sw Eio switch for resource management
107 @param pool_config Optional pool configuration
108 @return The connection pool instance *)
109val enable_connection_pooling :
110 context ->
111 sw:Eio.Switch.t ->
112 ?pool_config:Connection_pool.pool_config ->
113 unit ->
114 Connection_pool.t
115
116(** Get connection pool statistics if pooling is enabled.
117 @param ctx The client context
118 @return Pool statistics or None if pooling not enabled *)
119val get_connection_stats :
120 context ->
121 Connection_pool.pool_stats option
122
123(** Connect to a JMAP server and retrieve the session.
124 This handles discovery (if needed) and authentication.
125 @param env The Eio environment for network operations.
126 @param ctx The client context.
127 @param ?session_url Optional direct URL to the Session resource.
128 @param ?username Optional username (e.g., email address) for discovery.
129 @param ?use_tls Whether to use TLS for the connection (default true).
130 @param ?auth_method Authentication method to use (default Basic).
131 @param credentials Authentication credentials.
132 @return A result with either (context, session) or an error.
133*)
134val connect :
135 < net : 'a Eio.Net.t ; .. > ->
136 context ->
137 ?session_url:Uri.t ->
138 ?username:string ->
139 host:string ->
140 ?port:int ->
141 ?use_tls:bool ->
142 ?auth_method:auth_method ->
143 unit ->
144 (context * Jmap.Session.Session.t) Jmap.Error.result
145
146(** Create a request builder for constructing a JMAP request.
147 @param ctx The client context.
148 @return A request builder object.
149*)
150val build : context -> request_builder
151
152(** Specify capabilities to use with type-safe variants.
153 @param builder The request builder.
154 @param capabilities List of capability variants to use.
155 @return The updated request builder.
156*)
157val using : request_builder -> Jmap.Capability.t list -> request_builder
158
159(** Add a method call to a request builder.
160 @param builder The request builder.
161 @param method_name Typed method name variant.
162 @param args Method arguments.
163 @param id Method call ID.
164 @return The updated request builder.
165*)
166val add_method_call :
167 request_builder ->
168 Jmap.Method_names.jmap_method ->
169 Yojson.Safe.t ->
170 string ->
171 request_builder
172
173(** Create a reference to a previous method call result.
174 @param result_of Method call ID to reference.
175 @param name Path in the response.
176 @return A ResultReference to use in another method call.
177*)
178val create_reference : string -> string -> Jmap.Wire.Result_reference.t
179
180(** Execute a request and return the response.
181 @param env The Eio environment for network operations.
182 @param builder The request builder to execute.
183 @return The JMAP response from the server.
184*)
185val execute : < net : 'a Eio.Net.t ; .. > -> request_builder -> Jmap.Wire.Response.t Jmap.Error.result
186
187(** Perform a JMAP API request.
188 @param env The Eio environment for network operations.
189 @param ctx The connection context.
190 @param request The JMAP request object.
191 @return The JMAP response from the server.
192*)
193val request : < net : 'a Eio.Net.t ; .. > -> context -> Jmap.Wire.Request.t -> Jmap.Wire.Response.t Jmap.Error.result
194
195(** Upload binary data.
196 @param env The Eio environment for network operations.
197 @param ctx The connection context.
198 @param account_id The target account ID.
199 @param content_type The MIME type of the data.
200 @param data_stream A stream providing the binary data chunks.
201 @return A result with either an upload response or an error.
202*)
203val upload :
204 < net : 'a Eio.Net.t ; .. > ->
205 context ->
206 account_id:string ->
207 content_type:string ->
208 data_stream:string Seq.t ->
209 Jmap.Binary.Upload_response.t Jmap.Error.result
210
211(** Download binary data.
212 @param env The Eio environment for network operations.
213 @param ctx The connection context.
214 @param account_id The account ID.
215 @param blob_id The blob ID to download.
216 @param ?content_type The desired Content-Type for the download response.
217 @param ?name The desired filename for the download response.
218 @return A result with either a stream of data chunks or an error.
219*)
220val download :
221 < net : 'a Eio.Net.t ; .. > ->
222 context ->
223 account_id:string ->
224 blob_id:string ->
225 ?content_type:string ->
226 ?name:string ->
227 unit ->
228 (string Seq.t) Jmap.Error.result
229
230(** Copy blobs between accounts.
231 @param env The Eio environment for network operations.
232 @param ctx The connection context.
233 @param from_account_id Source account ID.
234 @param account_id Destination account ID.
235 @param blob_ids List of blob IDs to copy.
236 @return A result with either the copy response or an error.
237*)
238val copy_blobs :
239 < net : 'a Eio.Net.t ; .. > ->
240 context ->
241 from_account_id:string ->
242 account_id:string ->
243 blob_ids:string list ->
244 Jmap.Binary.Blob_copy_response.t Jmap.Error.result
245
246(** Connect to the EventSource for push notifications.
247 @param env The Eio environment for network operations.
248 @param ctx The connection context.
249 @param ?types List of types to subscribe to (default "*").
250 @param ?close_after Request server to close after first state event.
251 @param ?ping Request ping interval in seconds (default 0).
252 @return A result with either a tuple of connection handle and event stream, or an error.
253 @see <https://www.rfc-editor.org/rfc/rfc8620.html#section-7.3> RFC 8620, Section 7.3 *)
254val connect_event_source :
255 < net : 'a Eio.Net.t ; .. > ->
256 context ->
257 ?types:string list ->
258 ?close_after:[`State | `No] ->
259 ?ping:Jmap.UInt.t ->
260 unit ->
261 (event_source_connection *
262 ([`State of Jmap.Push.State_change.t | `Ping of Jmap.Push.Event_source_ping_data.t ] Seq.t)) Jmap.Error.result
263
264(** Create a websocket connection for JMAP over WebSocket.
265 @param env The Eio environment for network operations.
266 @param ctx The connection context.
267 @return A result with either a websocket connection or an error.
268 @see <https://www.rfc-editor.org/rfc/rfc8887.html> RFC 8887 *)
269val connect_websocket :
270 < net : 'a Eio.Net.t ; .. > ->
271 context ->
272 event_source_connection Jmap.Error.result
273
274(** Send a message over a websocket connection.
275 @param env The Eio environment for network operations.
276 @param conn The websocket connection.
277 @param request The JMAP request to send.
278 @return A result with either the response or an error.
279*)
280val websocket_send :
281 < net : 'a Eio.Net.t ; .. > ->
282 event_source_connection ->
283 Jmap.Wire.Request.t ->
284 Jmap.Wire.Response.t Jmap.Error.result
285
286(** Close an EventSource or WebSocket connection.
287 @param conn The connection handle.
288 @return A result with either unit or an error.
289*)
290val close_connection : event_source_connection -> unit Jmap.Error.result
291
292(** Close the JMAP connection context.
293 @return A result with either unit or an error.
294*)
295val close : context -> unit Jmap.Error.result
296
297(** {2 Helper Methods for Common Tasks} *)
298
299(** Helper to get a single object by ID.
300 @param env The Eio environment for network operations.
301 @param ctx The context.
302 @param method_name The get method (e.g., "Email/get").
303 @param account_id The account ID.
304 @param object_id The ID of the object to get.
305 @param ?properties Optional list of properties to fetch.
306 @return A result with either the object as JSON or an error.
307*)
308val get_object :
309 < net : 'a Eio.Net.t ; .. > ->
310 context ->
311 method_name:Jmap.Method_names.jmap_method ->
312 account_id:string ->
313 object_id:string ->
314 ?properties:string list ->
315 unit ->
316 Yojson.Safe.t Jmap.Error.result
317
318(** Helper to set up the connection with minimal options.
319 @param env The Eio environment for network operations.
320 @param host The JMAP server hostname.
321 @param username Username for basic auth.
322 @param password Password for basic auth.
323 @param ?use_tls Whether to use TLS (default true).
324 @param ?port Port number (default 443 for TLS, 80 for plain).
325 @return A result with either (context, session) or an error.
326*)
327val quick_connect :
328 < net : 'a Eio.Net.t ; .. > ->
329 host:string ->
330 username:string ->
331 password:string ->
332 ?use_tls:bool ->
333 ?port:int ->
334 unit ->
335 (context * Jmap.Session.Session.t) Jmap.Error.result
336
337(** Perform a Core/echo request to test connectivity.
338 @param env The Eio environment for network operations.
339 @param ctx The JMAP connection context.
340 @param ?data Optional data to echo back.
341 @return A result with either the response or an error.
342*)
343val echo :
344 < net : 'a Eio.Net.t ; .. > ->
345 context ->
346 ?data:Yojson.Safe.t ->
347 unit ->
348 Yojson.Safe.t Jmap.Error.result
349
350(** {2 Request Builder Pattern} *)
351
352(** High-level request builder for constructing JMAP requests in a type-safe manner.
353 This provides convenience functions that eliminate manual JSON construction. *)
354module Request_builder : sig
355 type t = request_builder
356
357 (** Create a new request builder with specified capabilities.
358 @param using List of capability variants to use in the request
359 @return A new request builder with the specified capabilities *)
360 val create : using:Jmap.Capability.t list -> context -> t
361
362 (** Add a query method call to the request builder.
363 @param t The request builder
364 @param method_name The JMAP method name (e.g., "Email/query")
365 @param args The query arguments, already converted to JSON
366 @param method_call_id Unique identifier for this method call
367 @return Updated request builder *)
368 val add_query :
369 t ->
370 method_name:Jmap.Method_names.jmap_method ->
371 args:Yojson.Safe.t ->
372 method_call_id:string ->
373 t
374
375 (** Add a get method call to the request builder.
376 @param t The request builder
377 @param method_name The JMAP method name variant
378 @param args The get arguments, already converted to JSON
379 @param method_call_id Unique identifier for this method call
380 @return Updated request builder *)
381 val add_get :
382 t ->
383 method_name:Jmap.Method_names.jmap_method ->
384 args:Yojson.Safe.t ->
385 method_call_id:string ->
386 t
387
388 (** Add a get method call with result reference to the request builder.
389 @param t The request builder
390 @param method_name The JMAP method name variant
391 @param account_id The account ID to use
392 @param result_reference Reference to a previous method call result
393 @param ?properties Optional list of properties to fetch
394 @param method_call_id Unique identifier for this method call
395 @return Updated request builder *)
396 val add_get_with_reference :
397 t ->
398 method_name:Jmap.Method_names.jmap_method ->
399 account_id:string ->
400 result_reference:Jmap.Wire.Result_reference.t ->
401 ?properties:string list ->
402 method_call_id:string ->
403 unit ->
404 t
405
406 (** Convert the request builder to a JMAP Request object.
407 @param t The request builder
408 @return A JMAP Request ready to be sent *)
409 val to_request : t -> Jmap.Wire.Request.t
410end
411
412(** {2 Email Operations} *)
413
414(** High-level email operations that map to JMAP email methods *)
415module Email : sig
416
417 (** Arguments for Email/query method calls.
418
419 This type eliminates manual JSON construction for Email/query requests.
420 It follows the JMAP Email/query specification exactly.
421
422 @see <https://www.rfc-editor.org/rfc/rfc8621.html#section-4.4> RFC 8621, Section 4.4 *)
423 module Query_args : sig
424 type t
425
426 (** Create Email/query arguments.
427 @param account_id The account ID to query in
428 @param ?filter Optional filter to apply (None = no filter)
429 @param ?sort Optional sort order (None = server default)
430 @param ?position Starting position in results (None = start from beginning)
431 @param ?limit Maximum number of results (None = server default)
432 @param ?calculate_total Whether to calculate total result count (None = false)
433 @param ?collapse_threads Whether to collapse threads (None = false)
434 @return Email query arguments object *)
435 val create :
436 account_id:string ->
437 ?filter:Jmap.Methods.Filter.t ->
438 ?sort:Jmap.Methods.Comparator.t list ->
439 ?position:int ->
440 ?limit:Jmap.UInt.t ->
441 ?calculate_total:bool ->
442 ?collapse_threads:bool ->
443 unit ->
444 t
445
446 (** Convert query arguments to JSON for JMAP requests.
447 @param t The query arguments to serialize
448 @return JSON representation suitable for Email/query method calls *)
449 val to_json : t -> Yojson.Safe.t
450 end
451
452 (** Arguments for Email/get method calls.
453
454 This type eliminates manual JSON construction for Email/get requests
455 and properly handles result references from previous method calls.
456
457 @see <https://www.rfc-editor.org/rfc/rfc8621.html#section-4.2> RFC 8621, Section 4.2 *)
458 module Get_args : sig
459 type t
460
461 (** Create Email/get arguments with specific IDs.
462 @param account_id The account ID to get emails from
463 @param ids List of email IDs to fetch
464 @param ?properties Optional list of properties to return (None = all properties)
465 @return Email get arguments object *)
466 val create :
467 account_id:string ->
468 ids:string list ->
469 ?properties:string list ->
470 unit ->
471 t
472
473 (** Create Email/get arguments with result reference to another method.
474 This is used when the IDs come from a previous method call result.
475 @param account_id The account ID to get emails from
476 @param result_of Method call ID that produced the IDs
477 @param name Method name that produced the IDs (e.g., "Email/query")
478 @param path JSON pointer to the IDs in the result (e.g., "/ids")
479 @param ?properties Optional list of properties to return (None = all properties)
480 @return Email get arguments object *)
481 val create_with_reference :
482 account_id:string ->
483 result_of:string ->
484 name:string ->
485 path:string ->
486 ?properties:string list ->
487 unit ->
488 t
489
490 (** Convert get arguments to JSON for JMAP requests.
491 @param t The get arguments to serialize
492 @return JSON representation suitable for Email/get method calls *)
493 val to_json : t -> Yojson.Safe.t
494 end
495
496 (** Get an email by ID
497 @param env The Eio environment for network operations
498 @param ctx The JMAP client context
499 @param account_id The account ID
500 @param email_id The email ID to fetch
501 @param ?properties Optional list of properties to fetch
502 @return The email object or an error
503 *)
504 val get_email :
505 < net : 'a Eio.Net.t ; .. > ->
506 context ->
507 account_id:string ->
508 email_id:string ->
509 ?properties:string list ->
510 unit ->
511 Jmap_email.Email.t Jmap.Error.result
512
513 (** Search for emails using a filter
514 @param env The Eio environment for network operations
515 @param ctx The JMAP client context
516 @param account_id The account ID
517 @param filter The search filter
518 @param ?sort Optional sort criteria (default received date newest first)
519 @param ?limit Optional maximum number of results
520 @param ?properties Optional properties to fetch for the matching emails
521 @return The list of matching email IDs and optionally the email objects
522 *)
523 val search_emails :
524 < net : 'a Eio.Net.t ; .. > ->
525 context ->
526 account_id:string ->
527 filter:Jmap.Methods.Filter.t ->
528 ?sort:Jmap.Methods.Comparator.t list ->
529 ?limit:Jmap.UInt.t ->
530 ?position:int ->
531 ?properties:string list ->
532 unit ->
533 (string list * Jmap_email.Email.t list option) Jmap.Error.result
534
535 (** Mark multiple emails with a keyword
536 @param env The Eio environment for network operations
537 @param ctx The JMAP client context
538 @param account_id The account ID
539 @param email_ids List of email IDs to update
540 @param keyword The keyword to add
541 @return The result of the operation
542 *)
543 val mark_emails :
544 < net : 'a Eio.Net.t ; .. > ->
545 context ->
546 account_id:string ->
547 email_ids:string list ->
548 keyword:Jmap_email.Keywords.keyword ->
549 unit ->
550 unit Jmap.Error.result
551
552 (** Mark emails as seen/read
553 @param env The Eio environment for network operations
554 @param ctx The JMAP client context
555 @param account_id The account ID
556 @param email_ids List of email IDs to mark
557 @return The result of the operation
558 *)
559 val mark_as_seen :
560 < net : 'a Eio.Net.t ; .. > ->
561 context ->
562 account_id:string ->
563 email_ids:string list ->
564 unit ->
565 unit Jmap.Error.result
566
567 (** Mark emails as unseen/unread
568 @param env The Eio environment for network operations
569 @param ctx The JMAP client context
570 @param account_id The account ID
571 @param email_ids List of email IDs to mark
572 @return The result of the operation
573 *)
574 val mark_as_unseen :
575 < net : 'a Eio.Net.t ; .. > ->
576 context ->
577 account_id:string ->
578 email_ids:string list ->
579 unit ->
580 unit Jmap.Error.result
581
582 (** Move emails to a different mailbox
583 @param env The Eio environment for network operations
584 @param ctx The JMAP client context
585 @param account_id The account ID
586 @param email_ids List of email IDs to move
587 @param mailbox_id Destination mailbox ID
588 @param ?remove_from_mailboxes Optional list of source mailbox IDs to remove from
589 @return The result of the operation
590 *)
591 val move_emails :
592 < net : 'a Eio.Net.t ; .. > ->
593 context ->
594 account_id:string ->
595 email_ids:string list ->
596 mailbox_id:string ->
597 ?remove_from_mailboxes:string list ->
598 unit ->
599 unit Jmap.Error.result
600
601 (** Import an RFC822 message
602 @param env The Eio environment for network operations
603 @param ctx The JMAP client context
604 @param account_id The account ID
605 @param rfc822 Raw message content
606 @param mailbox_ids Mailboxes to add the message to
607 @param ?keywords Optional keywords to set
608 @param ?received_at Optional received timestamp
609 @return The ID of the imported email
610 *)
611 val import_email :
612 < net : 'a Eio.Net.t ; .. > ->
613 context ->
614 account_id:string ->
615 rfc822:string ->
616 mailbox_ids:string list ->
617 ?keywords:Jmap_email.Keywords.t ->
618 ?received_at:Jmap.Date.t ->
619 unit ->
620 string Jmap.Error.result
621
622 (** {2 JSON Parsing Functions} *)
623
624 (** Parse an Email object from JSON representation.
625
626 This function eliminates the need for manual JSON parsing with Yojson.Safe.Util.
627 It properly handles all standard Email fields from RFC 8621 and provides
628 descriptive error messages for malformed JSON.
629
630 @param json JSON object representing an email as returned by Email/get
631 @return Parsed Email object
632
633 @see <https://www.rfc-editor.org/rfc/rfc8621.html#section-4.1> RFC 8621, Section 4.1 *)
634 (* val from_json : Yojson.Safe.t -> t
635
636 (** Parse an EmailAddress object from JSON representation.
637
638 @param json JSON object with 'email' and optional 'name' fields
639 @return Parsed EmailAddress object
640
641 @see <https://www.rfc-editor.org/rfc/rfc8621.html#section-4.1.2.3> RFC 8621, Section 4.1.2.3 *)
642 val from_json_address : Yojson.Safe.t -> Email_address.t
643
644 (** Parse Keywords from JSON representation.
645
646 @param json JSON object mapping keyword strings to boolean values
647 @return Parsed Keywords set
648
649 @see <https://www.rfc-editor.org/rfc/rfc8621.html#section-4.1.1> RFC 8621, Section 4.1.1 *)
650 val from_json_keywords : Yojson.Safe.t -> Jmap_email.Keywords.t *)
651end
652
653(** {2 Utility Functions} *)
654
655(** Authentication utilities for handling credential files and tokens *)
656module Auth : sig
657 (** Read an API key from a file.
658 @param filename Path to the file containing the API key
659 @return The API key as a string, with whitespace trimmed *)
660 val read_api_key : string -> string
661
662 (** Read an API key from the default ".api-key" file in the current directory.
663 @return The API key as a string, with whitespace trimmed *)
664 val read_api_key_default : unit -> string
665end
666
667(** Session utilities for common session operations *)
668module Session_utils : sig
669 (** Print detailed session information to stdout for debugging.
670 @param session The JMAP session to display *)
671 val print_session_info : Jmap.Session.Session.t -> unit
672
673 (** Get the primary mail account ID from a session.
674 Falls back to the first available account if no primary mail account is found.
675 @param session The JMAP session
676 @return The account ID to use for mail operations *)
677 val get_primary_mail_account : Jmap.Session.Session.t -> string
678end
679
680(** Response utilities for extracting data from JMAP responses *)
681module Response : sig
682 (** Extract a specific method response from a JMAP Response.
683 @param method_name Typed method name to search for
684 @param method_call_id The method call ID to match
685 @param response The JMAP response to search
686 @return The method response arguments or an error *)
687 val extract_method :
688 method_name:Jmap.Method_names.jmap_method ->
689 method_call_id:string ->
690 Jmap.Wire.Response.t ->
691 Yojson.Safe.t Jmap.Error.result
692
693 (** Extract the first method response with a given name, ignoring call ID.
694 @param method_name Typed method name to search for
695 @param response The JMAP response to search
696 @return The method response arguments or an error *)
697 val extract_method_by_name :
698 method_name:Jmap.Method_names.jmap_method ->
699 Jmap.Wire.Response.t ->
700 Yojson.Safe.t Jmap.Error.result
701end
702
703(** {2 Email High-Level Operations} *)
704
705(** High-level email method operations that combine builders from jmap-email with I/O *)
706module Email_methods : sig
707
708 (** Request builder for email method chaining *)
709 module RequestBuilder : sig
710 type t
711
712 (** Create a new request builder with jmap-unix context *)
713 val create : context -> t
714
715 (** Add Email/query method *)
716 val email_query :
717 ?account_id:string ->
718 ?filter:Yojson.Safe.t ->
719 ?sort:Jmap.Methods.Comparator.t list ->
720 ?limit:int ->
721 ?position:int ->
722 t -> t
723
724 (** Add Email/get method with automatic result reference *)
725 val email_get :
726 ?account_id:string ->
727 ?ids:Jmap.Id.t list ->
728 ?properties:string list ->
729 ?reference_from:string -> (* Call ID to reference *)
730 t -> t
731
732 (** Add Email/set method *)
733 val email_set :
734 ?account_id:string ->
735 ?create:(string * Yojson.Safe.t) list ->
736 ?update:(Jmap.Id.t * Jmap.Patch.t) list ->
737 ?destroy:Jmap.Id.t list ->
738 t -> t
739
740 (** Add Thread/get method *)
741 val thread_get :
742 ?account_id:string ->
743 ?ids:Jmap.Id.t list ->
744 t -> t
745
746 (** Add Mailbox/query method *)
747 val mailbox_query :
748 ?account_id:string ->
749 ?filter:Yojson.Safe.t ->
750 ?sort:Jmap.Methods.Comparator.t list ->
751 t -> t
752
753 (** Add Mailbox/get method *)
754 val mailbox_get :
755 ?account_id:string ->
756 ?ids:Jmap.Id.t list ->
757 t -> t
758
759 (** Execute the built request *)
760 val execute :
761 < net : 'a Eio.Net.t ; .. > ->
762 session:Jmap.Session.Session.t ->
763 t ->
764 (Jmap.Wire.Response.t, Jmap.Error.error) result
765
766 (** Get specific method response by type *)
767 val get_response :
768 method_:Jmap.Method_names.jmap_method ->
769 ?call_id:string ->
770 Jmap.Wire.Response.t ->
771 (Yojson.Safe.t, Jmap.Error.error) result
772 end
773
774 (** Response parsing functions *)
775 module Response : sig
776 (** Extract and parse Email/query response *)
777 val parse_email_query :
778 ?call_id:string ->
779 Jmap.Wire.Response.t ->
780 (Yojson.Safe.t, Jmap.Error.error) result
781
782 (** Extract and parse Email/get response *)
783 val parse_email_get :
784 ?call_id:string ->
785 Jmap.Wire.Response.t ->
786 (Yojson.Safe.t list, Jmap.Error.error) result
787
788 (** Extract and parse Thread/get response *)
789 val parse_thread_get :
790 ?call_id:string ->
791 Jmap.Wire.Response.t ->
792 (Yojson.Safe.t list, Jmap.Error.error) result
793
794 (** Extract and parse Mailbox/get response *)
795 val parse_mailbox_get :
796 ?call_id:string ->
797 Jmap.Wire.Response.t ->
798 (Yojson.Safe.t list, Jmap.Error.error) result
799 end
800
801 (** Common email operation patterns *)
802
803 (** Execute Email/query and automatically chain Email/get *)
804 val query_and_fetch :
805 < net : 'a Eio.Net.t ; .. > ->
806 ctx:context ->
807 session:Jmap.Session.Session.t ->
808 ?account_id:string ->
809 ?filter:Yojson.Safe.t ->
810 ?sort:Jmap.Methods.Comparator.t list ->
811 ?limit:int ->
812 ?properties:string list ->
813 unit ->
814 (Yojson.Safe.t list, Jmap.Error.error) result
815
816 (** Get emails by IDs *)
817 val get_emails_by_ids :
818 < net : 'a Eio.Net.t ; .. > ->
819 ctx:context ->
820 session:Jmap.Session.Session.t ->
821 ?account_id:string ->
822 ?properties:string list ->
823 Jmap.Id.t list ->
824 (Yojson.Safe.t list, Jmap.Error.error) result
825
826 (** Get all mailboxes *)
827 val get_mailboxes :
828 < net : 'a Eio.Net.t ; .. > ->
829 ctx:context ->
830 session:Jmap.Session.Session.t ->
831 ?account_id:string ->
832 unit ->
833 (Yojson.Safe.t list, Jmap.Error.error) result
834
835 (** Find mailbox by role (e.g., "inbox", "sent", "drafts") *)
836 val find_mailbox_by_role :
837 < net : 'a Eio.Net.t ; .. > ->
838 ctx:context ->
839 session:Jmap.Session.Session.t ->
840 ?account_id:string ->
841 string ->
842 (Yojson.Safe.t option, Jmap.Error.error) result
843end
844
845(** {2 Email Query Operations} *)
846
847(** High-level email query operations using Eio *)
848module Email_query : sig
849
850 (** Execute just the query (returns IDs only) *)
851 val execute_query :
852 < net : 'a Eio.Net.t ; .. > ->
853 ctx:context ->
854 session:Jmap.Session.Session.t ->
855 Yojson.Safe.t ->
856 (Yojson.Safe.t, Jmap.Error.error) result
857
858 (** Execute query and automatically fetch email data *)
859 val execute_with_fetch :
860 < net : 'a Eio.Net.t ; .. > ->
861 ctx:context ->
862 session:Jmap.Session.Session.t ->
863 Yojson.Safe.t ->
864 (Yojson.Safe.t, Jmap.Error.error) result
865
866end
867
868(** {2 Email Batch Operations} *)
869
870(** High-level batch email operations using Eio *)
871module Email_batch : sig
872
873 (** Execute batch operations *)
874 val execute :
875 < net : 'a Eio.Net.t ; .. > ->
876 ctx:context ->
877 session:Jmap.Session.Session.t ->
878 ?account_id:string ->
879 Yojson.Safe.t ->
880 (Yojson.Safe.t, Jmap.Error.error) result
881
882 (** Common batch workflow operations *)
883
884 (** Process inbox - mark as read and archive *)
885 val process_inbox :
886 < net : 'a Eio.Net.t ; .. > ->
887 ctx:context ->
888 session:Jmap.Session.Session.t ->
889 email_ids:Jmap.Id.t list ->
890 (Yojson.Safe.t, Jmap.Error.error) result
891
892 (** Bulk delete spam/trash emails older than N days *)
893 val cleanup_old_emails :
894 < net : 'a Eio.Net.t ; .. > ->
895 ctx:context ->
896 session:Jmap.Session.Session.t ->
897 mailbox_role:string -> (* "spam" or "trash" *)
898 older_than_days:int ->
899 (Yojson.Safe.t, Jmap.Error.error) result
900
901 (** Organize emails by sender into mailboxes *)
902 val organize_by_sender :
903 < net : 'a Eio.Net.t ; .. > ->
904 ctx:context ->
905 session:Jmap.Session.Session.t ->
906 rules:(string * string) list -> (* sender email -> mailbox name *)
907 (Yojson.Safe.t, Jmap.Error.error) result
908
909 (** Progress callback for long operations *)
910 type progress = {
911 current : int;
912 total : int;
913 message : string;
914 }
915
916 (** Execute with progress reporting *)
917 val execute_with_progress :
918 < net : 'a Eio.Net.t ; .. > ->
919 ctx:context ->
920 session:Jmap.Session.Session.t ->
921 ?account_id:string ->
922 progress_fn:(progress -> unit) ->
923 Yojson.Safe.t ->
924 (Yojson.Safe.t, Jmap.Error.error) result
925end
926
927(** High-level email submission API.
928
929 Provides ergonomic functions for submitting emails via JMAP,
930 including envelope management and delivery tracking.
931
932 @see <https://www.rfc-editor.org/rfc/rfc8621.html#section-7> RFC 8621, Section 7 *)
933module Email_submission : module type of Email_submission