My agentic slop goes here. Not intended for anyone else!
1(** High-level Email query interface for JMAP Email.
2
3 This module provides a fluent, type-safe API for constructing
4 and executing Email queries with automatic result chaining.
5
6 @see <https://www.rfc-editor.org/rfc/rfc8621.html#section-4.4> RFC 8621 Section 4.4 *)
7
8(** {1 Email Properties} *)
9
10(** Type-safe email property selectors.
11
12 Uses the canonical polymorphic variant property system from [property].
13 This provides full compatibility with all JMAP Email properties including
14 header and custom extension properties.
15*)
16type property = Property.t
17
18
19
20(** {1 Sort Options} *)
21
22(** Common sort configurations *)
23module Sort : sig
24 type t
25
26 (** Sort by received date, newest first *)
27 val by_date_desc : t
28
29 (** Sort by received date, oldest first *)
30 val by_date_asc : t
31
32 (** Sort by size, largest first *)
33 val by_size_desc : t
34
35 (** Sort by sender name *)
36 val by_from : t
37
38 (** Sort by subject *)
39 val by_subject : t
40
41 (** Create custom sort *)
42 val custom : property:string -> is_ascending:bool -> t
43
44 (** Combine multiple sort criteria *)
45 val combine : t list -> t list
46end
47
48(** {1 Query Filters} *)
49
50(** Email filter conditions.
51 Uses the core JMAP Filter utilities for type-safe filter construction. *)
52module Filter : sig
53 type t = Jmap.Methods.Filter.t
54
55 (** Filter by mailbox *)
56 val in_mailbox : Jmap.Id.t -> t
57
58 (** Filter by mailbox role (e.g., "inbox", "sent", "drafts") *)
59 val in_mailbox_role : string -> t
60
61 (** Filter for unread emails *)
62 val unread : t
63
64 (** Filter for flagged/starred emails *)
65 val flagged : t
66
67 (** Filter for emails with attachments *)
68 val has_attachment : t
69
70 (** Filter by sender *)
71 val from : string -> t
72
73 (** Filter by recipient (to, cc, or bcc) *)
74 val to_ : string -> t
75
76 (** Filter by subject containing text *)
77 val subject_contains : string -> t
78
79 (** Filter by body text *)
80 val body_contains : string -> t
81
82 (** Filter by date range *)
83 val after : Jmap.Date.t -> t
84 val before : Jmap.Date.t -> t
85 val between : Jmap.Date.t -> Jmap.Date.t -> t
86
87 (** Filter by size *)
88 val min_size : int -> t
89 val max_size : int -> t
90
91 (** Combine filters *)
92 val and_ : t list -> t
93 val or_ : t list -> t
94 val not_ : t -> t
95
96 (** Convert filter to JSON for wire protocol *)
97 val to_json : t -> Yojson.Safe.t
98end
99
100(** {1 Query Builder} *)
101
102(** Fluent query builder *)
103type query_builder
104
105(** Create a new query builder *)
106val query : unit -> query_builder
107
108(** Set the account ID (uses primary mail account if not set) *)
109val with_account : Jmap.Id.t -> query_builder -> query_builder
110
111(** Add a filter condition *)
112val where : Filter.t -> query_builder -> query_builder
113
114(** Set sort order *)
115val order_by : Sort.t -> query_builder -> query_builder
116
117(** Limit the number of results *)
118val limit : int -> query_builder -> query_builder
119
120(** Set position/offset for pagination *)
121val offset : int -> query_builder -> query_builder
122
123(** Select which properties to fetch *)
124val select : property list -> query_builder -> query_builder
125
126(** Use a predefined property set *)
127val select_preset : [`ListV | `Preview | `Full | `Threading] -> query_builder -> query_builder
128
129(** Enable thread collapsing *)
130val collapse_threads : bool -> query_builder -> query_builder
131
132(** Enable total result count calculation *)
133val calculate_total : bool -> query_builder -> query_builder
134
135(** {1 JSON Generation} *)
136
137(** Convert query builder to core JMAP Query_args.
138
139 Creates a properly typed Query_args object that can be used with
140 the core JMAP methods. This enables type-safe query construction.
141
142 @param query_builder The query to convert
143 @return Core JMAP Query_args object
144 @raise Failure if account_id is not set *)
145val to_core_query_args : query_builder -> Jmap.Methods.Query_args.t
146
147(** Build JSON for Email/query method call.
148
149 Converts a query_builder into the JSON format expected by the
150 JMAP Email/query method. This uses the core Query_args internally
151 for proper JSON generation.
152
153 @param query_builder The query to convert
154 @return JSON object for Email/query method arguments *)
155val build_email_query : query_builder -> Yojson.Safe.t
156
157(** Convert property presets to string lists.
158
159 Maps property preset enums to their corresponding string lists
160 for use in Email/get requests. Used internally by jmap-unix
161 for building method arguments.
162
163 @param preset Property preset to convert
164 @return List of property strings *)
165val property_preset_to_strings : [`ListV | `Preview | `Full | `Threading] -> string list
166
167(** Build JSON for Email/get method call with result references.
168
169 Creates the JSON for Email/get calls that reference the results of a previous
170 Email/query call. This is the standard pattern for chained JMAP requests.
171
172 @param account_id Account identifier
173 @param properties List of property strings to fetch
174 @param result_of Method call ID to reference (e.g., "q1")
175 @return JSON object for Email/get method arguments *)
176val build_email_get_with_ref :
177 account_id:Jmap.Id.t ->
178 properties:property list ->
179 result_of:string ->
180 Yojson.Safe.t
181
182(** Convert property list to string list for Email/get requests.
183
184 Maps property variants to their JMAP protocol string representations.
185 Used to prepare property lists for Email/get method calls.
186
187 @param properties List of property variants
188 @return List of property strings *)
189val properties_to_strings : property list -> string list
190
191(** {1 Execution} *)
192
193(** Query result containing email IDs *)
194type query_result = {
195 ids : Jmap.Id.t list;
196 total : int option;
197 position : int;
198 can_calculate_changes : bool;
199}
200
201(** Query result with full email data *)
202type 'email fetch_result = {
203 emails : 'email list;
204 total : int option;
205}
206
207(** {1 Common Queries} *)
208
209(** Inbox emails, newest first *)
210val inbox : ?limit:int -> unit -> query_builder
211
212(** Unread emails across all mailboxes *)
213val unread : ?limit:int -> unit -> query_builder
214
215(** Recent emails (last 24 hours) *)
216val recent : ?limit:int -> unit -> query_builder
217
218(** Emails from a specific sender *)
219val from_sender : string -> ?limit:int -> unit -> query_builder
220
221(** Search emails by text across subject and body *)
222val search : string -> ?limit:int -> unit -> query_builder
223
224(** Flagged/starred emails *)
225val flagged : ?limit:int -> unit -> query_builder
226
227(** Emails with attachments *)
228val with_attachments : ?limit:int -> unit -> query_builder
229
230(** {1 Pretty Printing} *)
231
232(** Pretty-print an email for display *)
233val pp_email : Format.formatter -> 'email -> unit
234
235(** Pretty-print a list of emails as a summary *)
236val pp_email_list : Format.formatter -> 'email list -> unit