···
+
(** Implementation of the JMAP Mail extension, as defined in RFC8621 *)
+
(** {1 Mail capabilities} *)
+
(** Capability URI for JMAP Mail*)
+
let capability_mail = "urn:ietf:params:jmap:mail"
+
(** Capability URI for JMAP Submission *)
+
let capability_submission = "urn:ietf:params:jmap:submission"
+
(** Capability URI for JMAP Vacation Response *)
+
let capability_vacation_response = "urn:ietf:params:jmap:vacationresponse"
+
(** {1:mailbox Mailbox objects} *)
+
(** A role for a mailbox. See RFC8621 Section 2. *)
+
| Archive (** Archived mail *)
+
| Drafts (** Draft messages *)
+
| Flagged (** Starred/flagged mail *)
+
| Important (** Important mail *)
+
| Junk (** Spam/Junk mail *)
+
| Sent (** Sent mail *)
+
| Trash (** Deleted/Trash mail *)
+
| Unknown of string (** Server-specific roles *)
+
(** A mailbox (folder) in a mail account. See RFC8621 Section 2. *)
+
role : mailbox_role option;
+
sort_order : unsigned_int;
+
total_emails : unsigned_int;
+
unread_emails : unsigned_int;
+
total_threads : unsigned_int;
+
unread_threads : unsigned_int;
+
my_rights : mailbox_rights;
+
(** Rights for a mailbox. See RFC8621 Section 2. *)
+
may_remove_items : bool;
+
may_set_keywords : bool;
+
may_create_child : bool;
+
(** Filter condition for mailbox queries. See RFC8621 Section 2.3. *)
+
type mailbox_filter_condition = {
+
has_any_role : bool option;
+
is_subscribed : bool option;
+
type mailbox_query_filter = [
+
| `And of mailbox_query_filter list
+
| `Or of mailbox_query_filter list
+
| `Not of mailbox_query_filter
+
| `Condition of mailbox_filter_condition
+
(** Mailbox/get request arguments. See RFC8621 Section 2.1. *)
+
type mailbox_get_arguments = {
+
properties : string list option;
+
(** Mailbox/get response. See RFC8621 Section 2.1. *)
+
type mailbox_get_response = {
+
(** Mailbox/changes request arguments. See RFC8621 Section 2.2. *)
+
type mailbox_changes_arguments = {
+
max_changes : unsigned_int option;
+
(** Mailbox/changes response. See RFC8621 Section 2.2. *)
+
type mailbox_changes_response = {
+
has_more_changes : bool;
+
(** Mailbox/query request arguments. See RFC8621 Section 2.3. *)
+
type mailbox_query_arguments = {
+
filter : mailbox_query_filter option;
+
sort : [ `name | `role | `sort_order ] list option;
+
limit : unsigned_int option;
+
(** Mailbox/query response. See RFC8621 Section 2.3. *)
+
type mailbox_query_response = {
+
can_calculate_changes : bool;
+
position : unsigned_int;
+
total : unsigned_int option;
+
(** Mailbox/queryChanges request arguments. See RFC8621 Section 2.4. *)
+
type mailbox_query_changes_arguments = {
+
filter : mailbox_query_filter option;
+
sort : [ `name | `role | `sort_order ] list option;
+
since_query_state : string;
+
max_changes : unsigned_int option;
+
(** Mailbox/queryChanges response. See RFC8621 Section 2.4. *)
+
type mailbox_query_changes_response = {
+
old_query_state : string;
+
new_query_state : string;
+
total : unsigned_int option;
+
added : mailbox_query_changes_added list;
+
and mailbox_query_changes_added = {
+
(** Mailbox/set request arguments. See RFC8621 Section 2.5. *)
+
type mailbox_set_arguments = {
+
if_in_state : string option;
+
create : (id * mailbox_creation) list option;
+
update : (id * mailbox_update) list option;
+
destroy : id list option;
+
and mailbox_creation = {
+
sort_order : unsigned_int option;
+
is_subscribed : bool option;
+
sort_order : unsigned_int option;
+
is_subscribed : bool option;
+
(** Mailbox/set response. See RFC8621 Section 2.5. *)
+
type mailbox_set_response = {
+
old_state : string option;
+
created : (id * mailbox) list option;
+
updated : id list option;
+
destroyed : id list option;
+
not_created : (id * set_error) list option;
+
not_updated : (id * set_error) list option;
+
not_destroyed : (id * set_error) list option;
+
(** {1:thread Thread objects} *)
+
(** A thread in a mail account. See RFC8621 Section 3. *)
+
(** Thread/get request arguments. See RFC8621 Section 3.1. *)
+
type thread_get_arguments = {
+
properties : string list option;
+
(** Thread/get response. See RFC8621 Section 3.1. *)
+
type thread_get_response = {
+
(** Thread/changes request arguments. See RFC8621 Section 3.2. *)
+
type thread_changes_arguments = {
+
max_changes : unsigned_int option;
+
(** Thread/changes response. See RFC8621 Section 3.2. *)
+
type thread_changes_response = {
+
has_more_changes : bool;
+
(** {1:email Email objects} *)
+
(** Addressing (mailbox) information. See RFC8621 Section 4.1.1. *)
+
parameters : (string * string) list;
+
(** Message header field. See RFC8621 Section 4.1.2. *)
+
(** Email keyword (flag). See RFC8621 Section 4.3. *)
+
(** Email message. See RFC8621 Section 4. *)
+
mailbox_ids : (id * bool) list;
+
keywords : (keyword * bool) list;
+
received_at : utc_date;
+
message_id : string list;
+
in_reply_to : string list option;
+
references : string list option;
+
sender : email_address list option;
+
from : email_address list option;
+
to_ : email_address list option;
+
cc : email_address list option;
+
bcc : email_address list option;
+
reply_to : email_address list option;
+
subject : string option;
+
sent_at : utc_date option;
+
has_attachment : bool option;
+
preview : string option;
+
body_values : (string * string) list option;
+
text_body : email_body_part list option;
+
html_body : email_body_part list option;
+
attachments : email_body_part list option;
+
headers : header list option;
+
(** Email body part. See RFC8621 Section 4.1.4. *)
+
and email_body_part = {
+
part_id : string option;
+
size : unsigned_int option;
+
headers : header list option;
+
charset : string option;
+
disposition : string option;
+
language : string list option;
+
location : string option;
+
sub_parts : email_body_part list option;
+
header_parameter_name : string option;
+
header_parameter_value : string option;
+
(** Email query filter condition. See RFC8621 Section 4.4. *)
+
type email_filter_condition = {
+
in_mailbox : id option;
+
in_mailbox_other_than : id list option;
+
min_size : unsigned_int option;
+
max_size : unsigned_int option;
+
before : utc_date option;
+
after : utc_date option;
+
header : (string * string) option;
+
subject : string option;
+
has_keyword : string option;
+
not_keyword : string option;
+
has_attachment : bool option;
+
type email_query_filter = [
+
| `And of email_query_filter list
+
| `Or of email_query_filter list
+
| `Not of email_query_filter
+
| `Condition of email_filter_condition
+
(** Email/get request arguments. See RFC8621 Section 4.5. *)
+
type email_get_arguments = {
+
properties : string list option;
+
body_properties : string list option;
+
fetch_text_body_values : bool option;
+
fetch_html_body_values : bool option;
+
fetch_all_body_values : bool option;
+
max_body_value_bytes : unsigned_int option;
+
(** Email/get response. See RFC8621 Section 4.5. *)
+
type email_get_response = {
+
(** Email/changes request arguments. See RFC8621 Section 4.6. *)
+
type email_changes_arguments = {
+
max_changes : unsigned_int option;
+
(** Email/changes response. See RFC8621 Section 4.6. *)
+
type email_changes_response = {
+
has_more_changes : bool;
+
(** Email/query request arguments. See RFC8621 Section 4.4. *)
+
type email_query_arguments = {
+
filter : email_query_filter option;
+
sort : comparator list option;
+
collapse_threads : bool option;
+
position : unsigned_int option;
+
anchor_offset : int_t option;
+
limit : unsigned_int option;
+
calculate_total : bool option;
+
(** Email/query response. See RFC8621 Section 4.4. *)
+
type email_query_response = {
+
can_calculate_changes : bool;
+
position : unsigned_int;
+
total : unsigned_int option;
+
thread_ids : id list option;
+
(** Email/queryChanges request arguments. See RFC8621 Section 4.7. *)
+
type email_query_changes_arguments = {
+
filter : email_query_filter option;
+
sort : comparator list option;
+
collapse_threads : bool option;
+
since_query_state : string;
+
max_changes : unsigned_int option;
+
(** Email/queryChanges response. See RFC8621 Section 4.7. *)
+
type email_query_changes_response = {
+
old_query_state : string;
+
new_query_state : string;
+
total : unsigned_int option;
+
added : email_query_changes_added list;
+
and email_query_changes_added = {
+
(** Email/set request arguments. See RFC8621 Section 4.8. *)
+
type email_set_arguments = {
+
if_in_state : string option;
+
create : (id * email_creation) list option;
+
update : (id * email_update) list option;
+
destroy : id list option;
+
mailbox_ids : (id * bool) list;
+
keywords : (keyword * bool) list option;
+
received_at : utc_date option;
+
message_id : string list option;
+
in_reply_to : string list option;
+
references : string list option;
+
sender : email_address list option;
+
from : email_address list option;
+
to_ : email_address list option;
+
cc : email_address list option;
+
bcc : email_address list option;
+
reply_to : email_address list option;
+
subject : string option;
+
body_values : (string * string) list option;
+
text_body : email_body_part list option;
+
html_body : email_body_part list option;
+
attachments : email_body_part list option;
+
headers : header list option;
+
keywords : (keyword * bool) list option;
+
mailbox_ids : (id * bool) list option;
+
(** Email/set response. See RFC8621 Section 4.8. *)
+
type email_set_response = {
+
old_state : string option;
+
created : (id * email) list option;
+
updated : id list option;
+
destroyed : id list option;
+
not_created : (id * set_error) list option;
+
not_updated : (id * set_error) list option;
+
not_destroyed : (id * set_error) list option;
+
(** Email/copy request arguments. See RFC8621 Section 4.9. *)
+
type email_copy_arguments = {
+
create : (id * email_creation) list;
+
on_success_destroy_original : bool option;
+
(** Email/copy response. See RFC8621 Section 4.9. *)
+
type email_copy_response = {
+
created : (id * email) list option;
+
not_created : (id * set_error) list option;
+
(** Email/import request arguments. See RFC8621 Section 4.10. *)
+
type email_import_arguments = {
+
emails : (id * email_import) list;
+
mailbox_ids : (id * bool) list;
+
keywords : (keyword * bool) list option;
+
received_at : utc_date option;
+
(** Email/import response. See RFC8621 Section 4.10. *)
+
type email_import_response = {
+
created : (id * email) list option;
+
not_created : (id * set_error) list option;
+
(** {1:search_snippet Search snippets} *)
+
(** SearchSnippet/get request arguments. See RFC8621 Section 4.11. *)
+
type search_snippet_get_arguments = {
+
filter : email_filter_condition;
+
(** SearchSnippet/get response. See RFC8621 Section 4.11. *)
+
type search_snippet_get_response = {
+
list : (id * search_snippet) list;
+
subject : string option;
+
preview : string option;
+
(** {1:submission EmailSubmission objects} *)
+
(** EmailSubmission address. See RFC8621 Section 5.1. *)
+
type submission_address = {
+
parameters : (string * string) list option;
+
(** Email submission object. See RFC8621 Section 5.1. *)
+
type email_submission = {
+
envelope : envelope option;
+
send_at : utc_date option;
+
delivery_status : (string * submission_status) list option;
+
dsn_blob_ids : (string * id) list option;
+
mdn_blob_ids : (string * id) list option;
+
(** Envelope for mail submission. See RFC8621 Section 5.1. *)
+
mail_from : submission_address;
+
rcpt_to : submission_address list;
+
(** Delivery status for submitted email. See RFC8621 Section 5.1. *)
+
and submission_status = {
+
delivered : string option;
+
(** EmailSubmission/get request arguments. See RFC8621 Section 5.3. *)
+
type email_submission_get_arguments = {
+
properties : string list option;
+
(** EmailSubmission/get response. See RFC8621 Section 5.3. *)
+
type email_submission_get_response = {
+
list : email_submission list;
+
(** EmailSubmission/changes request arguments. See RFC8621 Section 5.4. *)
+
type email_submission_changes_arguments = {
+
max_changes : unsigned_int option;
+
(** EmailSubmission/changes response. See RFC8621 Section 5.4. *)
+
type email_submission_changes_response = {
+
has_more_changes : bool;
+
(** EmailSubmission/query filter condition. See RFC8621 Section 5.5. *)
+
type email_submission_filter_condition = {
+
identity_id : id option;
+
before : utc_date option;
+
after : utc_date option;
+
subject : string option;
+
type email_submission_query_filter = [
+
| `And of email_submission_query_filter list
+
| `Or of email_submission_query_filter list
+
| `Not of email_submission_query_filter
+
| `Condition of email_submission_filter_condition
+
(** EmailSubmission/query request arguments. See RFC8621 Section 5.5. *)
+
type email_submission_query_arguments = {
+
filter : email_submission_query_filter option;
+
sort : comparator list option;
+
position : unsigned_int option;
+
anchor_offset : int_t option;
+
limit : unsigned_int option;
+
calculate_total : bool option;
+
(** EmailSubmission/query response. See RFC8621 Section 5.5. *)
+
type email_submission_query_response = {
+
can_calculate_changes : bool;
+
position : unsigned_int;
+
total : unsigned_int option;
+
(** EmailSubmission/set request arguments. See RFC8621 Section 5.6. *)
+
type email_submission_set_arguments = {
+
if_in_state : string option;
+
create : (id * email_submission_creation) list option;
+
update : (id * email_submission_update) list option;
+
destroy : id list option;
+
on_success_update_email : (id * email_update) list option;
+
and email_submission_creation = {
+
envelope : envelope option;
+
send_at : utc_date option;
+
and email_submission_update = {
+
identity_id : id option;
+
envelope : envelope option;
+
undo_status : [`canceled] option;
+
(** EmailSubmission/set response. See RFC8621 Section 5.6. *)
+
type email_submission_set_response = {
+
old_state : string option;
+
created : (id * email_submission) list option;
+
updated : id list option;
+
destroyed : id list option;
+
not_created : (id * set_error) list option;
+
not_updated : (id * set_error) list option;
+
not_destroyed : (id * set_error) list option;
+
(** {1:identity Identity objects} *)
+
(** Identity for sending mail. See RFC8621 Section 6. *)
+
reply_to : email_address list option;
+
bcc : email_address list option;
+
text_signature : string option;
+
html_signature : string option;
+
(** Identity/get request arguments. See RFC8621 Section 6.1. *)
+
type identity_get_arguments = {
+
properties : string list option;
+
(** Identity/get response. See RFC8621 Section 6.1. *)
+
type identity_get_response = {
+
(** Identity/changes request arguments. See RFC8621 Section 6.2. *)
+
type identity_changes_arguments = {
+
max_changes : unsigned_int option;
+
(** Identity/changes response. See RFC8621 Section 6.2. *)
+
type identity_changes_response = {
+
has_more_changes : bool;
+
(** Identity/set request arguments. See RFC8621 Section 6.3. *)
+
type identity_set_arguments = {
+
if_in_state : string option;
+
create : (id * identity_creation) list option;
+
update : (id * identity_update) list option;
+
destroy : id list option;
+
and identity_creation = {
+
reply_to : email_address list option;
+
bcc : email_address list option;
+
text_signature : string option;
+
html_signature : string option;
+
and identity_update = {
+
reply_to : email_address list option;
+
bcc : email_address list option;
+
text_signature : string option;
+
html_signature : string option;
+
(** Identity/set response. See RFC8621 Section 6.3. *)
+
type identity_set_response = {
+
old_state : string option;
+
created : (id * identity) list option;
+
updated : id list option;
+
destroyed : id list option;
+
not_created : (id * set_error) list option;
+
not_updated : (id * set_error) list option;
+
not_destroyed : (id * set_error) list option;
+
(** {1:vacation_response VacationResponse objects} *)
+
(** Vacation auto-reply setting. See RFC8621 Section 7. *)
+
type vacation_response = {
+
from_date : utc_date option;
+
to_date : utc_date option;
+
subject : string option;
+
text_body : string option;
+
html_body : string option;
+
(** VacationResponse/get request arguments. See RFC8621 Section 7.2. *)
+
type vacation_response_get_arguments = {
+
properties : string list option;
+
(** VacationResponse/get response. See RFC8621 Section 7.2. *)
+
type vacation_response_get_response = {
+
list : vacation_response list;
+
(** VacationResponse/set request arguments. See RFC8621 Section 7.3. *)
+
type vacation_response_set_arguments = {
+
if_in_state : string option;
+
update : (id * vacation_response_update) list;
+
and vacation_response_update = {
+
is_enabled : bool option;
+
from_date : utc_date option;
+
to_date : utc_date option;
+
subject : string option;
+
text_body : string option;
+
html_body : string option;
+
(** VacationResponse/set response. See RFC8621 Section 7.3. *)
+
type vacation_response_set_response = {
+
old_state : string option;
+
updated : id list option;
+
not_updated : (id * set_error) list option;
+
(** {1 JSON serialization} *)
+
(** {2 Helper functions for serialization} *)
+
let string_of_mailbox_role = function
+
| Important -> "important"
+
let mailbox_role_of_string = function
+
| "important" -> Important
+
let string_of_keyword = function
+
| Flagged -> "$flagged"
+
| Answered -> "$answered"
+
| Forwarded -> "$forwarded"
+
| Phishing -> "$phishing"
+
| NotJunk -> "$notjunk"
+
let keyword_of_string = function
+
| "$flagged" -> Flagged
+
| "$answered" -> Answered
+
| "$forwarded" -> Forwarded
+
| "$phishing" -> Phishing
+
| "$notjunk" -> NotJunk
+
(** {2 Mailbox serialization} *)
+
(** TODO:claude - Need to implement all JSON serialization functions
+
for each type we've defined. This would be a substantial amount of
+
code and likely require additional understanding of the ezjsonm API.
+
For a full implementation, we would need functions to convert between
+
OCaml types and JSON for each of:
+
- mailbox, mailbox_rights, mailbox query/update operations
+
- email, email_address, header, email_body_part
+
- email query/update operations
+
- submission operations
+
- vacation response operations
+
(** {1 API functions} *)
+
(** TODO:claude - Need to implement API functions for interacting with the
+
mail-specific JMAP server endpoints. These would use the Jmap.Api module
+
to make HTTP requests and parse responses.
+
For a complete implementation, we would need functions for:
+
- Mailbox operations (get, query, changes, update)
+
- Email operations (get, query, changes, update, import, copy)
+
- Vacation response management