-61
AGENT.md
-61
AGENT.md
···-14. Add an ocamldoc-format tutorial on how to use the library to index.mld along with cross references-build tested and run as well. Assume the pattern of the JMAP_API_TOKEN environment variable being
+4
-19
bin/dune
+4
-19
bin/dune
···
+113
-177
bin/fastmail_list.ml
+113
-177
bin/fastmail_list.ml
······+(** Example function demonstrating how to use higher-level library functions for JMAP requests *)-("-debug", Arg.Int (fun level -> debug_level := level), "Set debug level (0-4, where 4 is most verbose)");-("-from", Arg.Set_string sender_filter, "Filter messages by sender email address (supports wildcards: * and ?)");-Printf.eprintf " -from PATTERN Filter messages by sender email address (supports wildcards: * and ?)\n";···-Printf.printf "4. Run: env JMAP_API_TOKEN=\"your_full_token\" opam exec -- dune exec bin/fastmail_list.exe [options]\n\n";Printf.printf "Note: This example is working correctly but needs a valid Fastmail token.\n\n";··················-let parts = if !sender_filter <> "" then ("from \"" ^ !sender_filter ^ "\"") :: parts else parts in+let parts = if sender_filter <> "" then ("from \"" ^ sender_filter ^ "\"") :: parts else parts in···
+177
bin/fastmail_send.ml
+177
bin/fastmail_send.ml
···+fastmail_send --to=recipient@example.com [--to=another@example.com ...] --subject="Email subject"+- JMAP_FROM_EMAIL: Optional. The sender's email address. If not provided, uses the first identity.
+141
bin/jmap_test.ml
+141
bin/jmap_test.ml
···
+29
-14
dune-project
+29
-14
dune-project
···+"A complete implementation of the JSON Meta Application Protocol (JMAP) as specified in RFC 8620 (core) and RFC 8621 (mail).")
+514
eio/client.ml
+514
eio/client.ml
···
+404
eio/client.mli
+404
eio/client.mli
···
+42
eio/codec.ml
+42
eio/codec.ml
···
+92
eio/codec.mli
+92
eio/codec.mli
···
+5
eio/dune
+5
eio/dune
+7
eio/jmap_eio.ml
+7
eio/jmap_eio.ml
···
+73
eio/jmap_eio.mli
+73
eio/jmap_eio.mli
···
-360
index.mld
-360
index.mld
···-This library provides a type-safe OCaml interface to the JMAP protocol (RFC8620) and JMAP Mail extension (RFC8621).-JMAP (JSON Meta Application Protocol) is a modern protocol for synchronizing email, calendars, and contacts designed as a replacement for legacy protocols like IMAP. This OCaml implementation provides:-- {{:https://datatracker.ietf.org/doc/html/rfc8620}} RFC8620: The JSON Meta Application Protocol (JMAP)-- {{:https://datatracker.ietf.org/doc/html/rfc8621}} RFC8621: The JSON Meta Application Protocol (JMAP) for Mail-- {{:https://datatracker.ietf.org/doc/html/draft-ietf-mailmaint-messageflag-mailboxattribute-02}} Message Flag and Mailbox Attribute Extension
+35
jmap-eio.opam
+35
jmap-eio.opam
···
+13
-15
jmap.opam
+13
-15
jmap.opam
···+"A complete implementation of the JSON Meta Application Protocol (JMAP) as specified in RFC 8620 (core) and RFC 8621 (mail)."···
-11
lib/dune
-11
lib/dune
-783
lib/jmap.ml
-783
lib/jmap.ml
···-(* Choose appropriate authorization header based on whether it's a bearer token or basic auth *)-"Basic " ^ redact_token (Base64.encode_string (config.username ^ ":" ^ config.authentication_token))-let upload_url = Str.global_replace (Str.regexp "{accountId}") account_id upload_url_template in-("Authorization", "Basic " ^ Base64.encode_string (config.username ^ ":" ^ config.authentication_token))-("Authorization", "Basic " ^ Base64.encode_string (config.username ^ ":" ^ config.authentication_token))
-651
lib/jmap.mli
-651
lib/jmap.mli
···-type patch_object = (string * Ezjsonm.value) list (** List of property/value pairs to update *)-account_capabilities: (string * Ezjsonm.value) list; (** Capabilities available for this account *)-on_success_destroy_original: bool option; (** Whether to destroy the original after copying *)-calculate_total: bool option; (** Whether to calculate the total number of matching objects *)
-2014
lib/jmap_mail.ml
-2014
lib/jmap_mail.ml
···-(** Flag color defined by the combination of MailFlagBit0, MailFlagBit1, and MailFlagBit2 keywords *)-(** Standard message keywords as defined in draft-ietf-mailmaint-messageflag-mailboxattribute-02 *)-(** Special mailbox attribute names as defined in draft-ietf-mailmaint-messageflag-mailboxattribute-02 *)
-1542
lib/jmap_mail.mli
-1542
lib/jmap_mail.mli
···-name : string option; (** Only include mailboxes with this name (case-insensitive substring match) *)-has_any_role : bool option; (** If true, only include mailboxes with a role, if false those without *)-is_subscribed : bool option; (** If true, only include subscribed mailboxes, if false unsubscribed *)-added : mailbox_query_changes_added list; (** IDs that are in the new results but not the old *)-create : (id * mailbox_creation) list option; (** Map of creation IDs to mailboxes to create *)-mailbox_ids : (id * bool) list; (** Map of mailbox IDs to boolean (whether message belongs to mailbox) *)-keywords : (keyword * bool) list; (** Map of keywords to boolean (whether message has keyword) *)-header_parameter_name : string option; (** Header parameter name (for headers with parameters) *)-header_parameter_value : string option; (** Header parameter value (for headers with parameters) *)-header : (string * string) option; (** Only include emails with header matching value (name, value) *)-calculate_total : bool option; (** Whether to calculate the total number of matching emails *)-added : email_query_changes_added list; (** IDs that are in the new results but not the old *)-mailbox_ids : (id * bool) list; (** Map of mailbox IDs to boolean (whether message belongs to mailbox) *)-keywords : (keyword * bool) list option; (** Map of keywords to boolean (whether message has keyword) *)-mailbox_ids : (id * bool) list; (** Map of mailbox IDs to boolean (whether message belongs to mailbox) *)-keywords : (keyword * bool) list option; (** Map of keywords to boolean (whether message has keyword) *)-delivery_status : (string * submission_status) list option; (** Map of recipient to delivery status *)-calculate_total : bool option; (** Whether to calculate the total number of matching submissions *)-create : (id * email_submission_creation) list option; (** Map of creation IDs to submissions to create *)-on_success_update_email : (id * email_update) list option; (** Emails to update if submissions succeed *)-created : (id * email_submission) list option; (** Map of creation IDs to created submissions *)-create : (id * identity_creation) list option; (** Map of creation IDs to identities to create *)-not_destroyed : (id * set_error) list option; (** Map of IDs to errors for failed destroys *)-@see <https://datatracker.ietf.org/doc/html/draft-ietf-mailmaint-messageflag-mailboxattribute>-(** Flag color defined by the combination of MailFlagBit0, MailFlagBit1, and MailFlagBit2 keywords-@see <https://datatracker.ietf.org/doc/html/draft-ietf-mailmaint-messageflag-mailboxattribute#section-3>-(** Standard message keywords as defined in draft-ietf-mailmaint-messageflag-mailboxattribute-02 Section 4.1.-@see <https://datatracker.ietf.org/doc/html/draft-ietf-mailmaint-messageflag-mailboxattribute#section-4.1>-(** Special mailbox attribute names as defined in draft-ietf-mailmaint-messageflag-mailboxattribute-02 Section 4.2.-@see <https://datatracker.ietf.org/doc/html/draft-ietf-mailmaint-messageflag-mailboxattribute#section-4.2>
+105
proto/blob.ml
+105
proto/blob.ml
···+|> Jsont.Object.opt_mem "notCopied" (Json_map.of_id Error.set_error_jsont) ~enc:(fun r -> r.not_copied)
+65
proto/blob.mli
+65
proto/blob.mli
···
+171
proto/capability.ml
+171
proto/capability.ml
···+|> Jsont.Object.opt_mem "maxMailboxesPerEmail" Int53.Unsigned.jsont ~enc:max_mailboxes_per_email+|> Jsont.Object.mem "maxSizeAttachmentsPerEmail" Int53.Unsigned.jsont ~enc:max_size_attachments_per_email+|> Jsont.Object.mem "emailQuerySortOptions" (Jsont.list Jsont.string) ~enc:email_query_sort_options+|> Jsont.Object.mem "submissionExtensions" submission_extensions_jsont ~enc:submission_extensions
+143
proto/capability.mli
+143
proto/capability.mli
···
+64
proto/date.ml
+64
proto/date.ml
···
+51
proto/date.mli
+51
proto/date.mli
···
+21
proto/dune
+21
proto/dune
···
+190
proto/error.ml
+190
proto/error.ml
···
+146
proto/error.mli
+146
proto/error.mli
···
+123
proto/filter.ml
+123
proto/filter.ml
···
+73
proto/filter.mli
+73
proto/filter.mli
···
+51
proto/id.ml
+51
proto/id.ml
···
+38
proto/id.mli
+38
proto/id.mli
···
+67
proto/int53.ml
+67
proto/int53.ml
···
+62
proto/int53.mli
+62
proto/int53.mli
···
+86
proto/invocation.ml
+86
proto/invocation.ml
···
+81
proto/invocation.mli
+81
proto/invocation.mli
···+(** [make_query ~method_call_id ~method_name ~filter_cond_jsont args] creates a /query invocation. *)
+24
proto/jmap_proto.ml
+24
proto/jmap_proto.ml
···
+40
proto/json_map.ml
+40
proto/json_map.ml
···
+23
proto/json_map.mli
+23
proto/json_map.mli
···
+17
proto/mail/dune
+17
proto/mail/dune
+216
proto/mail/email.ml
+216
proto/mail/email.ml
···+| Some v -> Jsont.Array ([Jsont.String (name, Jsont.Meta.none); Jsont.String (v, Jsont.Meta.none)], Jsont.Meta.none)+|> Jsont.Object.opt_mem "inMailboxOtherThan" (Jsont.list Jmap_proto.Id.jsont) ~enc:(fun f -> f.in_mailbox_other_than)+|> Jsont.Object.opt_mem "allInThreadHaveKeyword" Jsont.string ~enc:(fun f -> f.all_in_thread_have_keyword)+|> Jsont.Object.opt_mem "someInThreadHaveKeyword" Jsont.string ~enc:(fun f -> f.some_in_thread_have_keyword)+|> Jsont.Object.opt_mem "noneInThreadHaveKeyword" Jsont.string ~enc:(fun f -> f.none_in_thread_have_keyword)+|> Jsont.Object.opt_mem "bodyProperties" (Jsont.list Jsont.string) ~enc:(fun a -> a.body_properties)+|> Jsont.Object.opt_mem "maxBodyValueBytes" Jmap_proto.Int53.Unsigned.jsont ~enc:(fun a -> a.max_body_value_bytes)
+146
proto/mail/email.mli
+146
proto/mail/email.mli
···
+53
proto/mail/email_address.ml
+53
proto/mail/email_address.ml
···
+49
proto/mail/email_address.mli
+49
proto/mail/email_address.mli
···
+85
proto/mail/email_body.ml
+85
proto/mail/email_body.ml
···
+73
proto/mail/email_body.mli
+73
proto/mail/email_body.mli
···
+39
proto/mail/email_header.ml
+39
proto/mail/email_header.ml
···
+49
proto/mail/email_header.mli
+49
proto/mail/email_header.mli
···
+40
proto/mail/identity.ml
+40
proto/mail/identity.ml
···
+36
proto/mail/identity.mli
+36
proto/mail/identity.mli
···
+20
proto/mail/jmap_mail.ml
+20
proto/mail/jmap_mail.ml
···
+16
proto/mail/mail_filter.ml
+16
proto/mail/mail_filter.ml
···
+21
proto/mail/mail_filter.mli
+21
proto/mail/mail_filter.mli
···
+165
proto/mail/mailbox.ml
+165
proto/mail/mailbox.ml
···+|> Jsont.Object.mem "sortOrder" Jmap_proto.Int53.Unsigned.jsont ~dec_absent:0L ~enc:sort_order
+116
proto/mail/mailbox.mli
+116
proto/mail/mailbox.mli
···
+24
proto/mail/search_snippet.ml
+24
proto/mail/search_snippet.ml
···
+21
proto/mail/search_snippet.mli
+21
proto/mail/search_snippet.mli
···
+183
proto/mail/submission.ml
+183
proto/mail/submission.ml
···+|> Jsont.Object.opt_mem "parameters" (Jmap_proto.Json_map.of_string Jsont.string) ~enc:parameters+|> Jsont.Object.opt_mem "deliveryStatus" (Jmap_proto.Json_map.of_string Delivery_status.jsont) ~enc:delivery_status+|> Jsont.Object.mem "dsnBlobIds" (Jsont.list Jmap_proto.Id.jsont) ~dec_absent:[] ~enc:dsn_blob_ids+|> Jsont.Object.mem "mdnBlobIds" (Jsont.list Jmap_proto.Id.jsont) ~dec_absent:[] ~enc:mdn_blob_ids+|> Jsont.Object.opt_mem "identityIds" (Jsont.list Jmap_proto.Id.jsont) ~enc:(fun f -> f.identity_ids)+|> Jsont.Object.opt_mem "emailIds" (Jsont.list Jmap_proto.Id.jsont) ~enc:(fun f -> f.email_ids)+|> Jsont.Object.opt_mem "threadIds" (Jsont.list Jmap_proto.Id.jsont) ~enc:(fun f -> f.thread_ids)
+132
proto/mail/submission.mli
+132
proto/mail/submission.mli
···
+21
proto/mail/thread.ml
+21
proto/mail/thread.ml
···
+18
proto/mail/thread.mli
+18
proto/mail/thread.mli
···
+39
proto/mail/vacation.ml
+39
proto/mail/vacation.ml
···
+36
proto/mail/vacation.mli
+36
proto/mail/vacation.mli
···
+316
proto/method_.ml
+316
proto/method_.ml
···+|> Jsont.Object.opt_mem "notCreated" (Json_map.of_id Error.set_error_jsont) ~enc:(fun r -> r.not_created)+|> Jsont.Object.opt_mem "notUpdated" (Json_map.of_id Error.set_error_jsont) ~enc:(fun r -> r.not_updated)+|> Jsont.Object.opt_mem "notDestroyed" (Json_map.of_id Error.set_error_jsont) ~enc:(fun r -> r.not_destroyed)+|> Jsont.Object.opt_mem "destroyFromIfInState" Jsont.string ~enc:(fun a -> a.destroy_from_if_in_state)+|> Jsont.Object.opt_mem "notCreated" (Json_map.of_id Error.set_error_jsont) ~enc:(fun r -> r.not_created)+|> Jsont.Object.opt_mem "filter" (Filter.filter_jsont filter_cond_jsont) ~enc:(fun a -> a.filter)+|> Jsont.Object.mem "anchorOffset" Int53.Signed.jsont ~dec_absent:0L ~enc:(fun a -> a.anchor_offset)+|> Jsont.Object.mem "calculateTotal" Jsont.bool ~dec_absent:false ~enc:(fun a -> a.calculate_total)+let query_changes_args_jsont (type f) (filter_cond_jsont : f Jsont.t) : f query_changes_args Jsont.t =+|> Jsont.Object.opt_mem "filter" (Filter.filter_jsont filter_cond_jsont) ~enc:(fun a -> a.filter)+|> Jsont.Object.mem "calculateTotal" Jsont.bool ~dec_absent:false ~enc:(fun a -> a.calculate_total)+let query_changes_response_make account_id old_query_state new_query_state total removed added =
+215
proto/method_.mli
+215
proto/method_.mli
···
+132
proto/push.ml
+132
proto/push.ml
···
+96
proto/push.mli
+96
proto/push.mli
···
+34
proto/request.ml
+34
proto/request.ml
···
+45
proto/request.mli
+45
proto/request.mli
···
+46
proto/response.ml
+46
proto/response.ml
···
+37
proto/response.mli
+37
proto/response.mli
···
+96
proto/session.ml
+96
proto/session.ml
···+|> Jsont.Object.mem "accountCapabilities" (Json_map.of_string Jsont.json) ~enc:account_capabilities
+84
proto/session.mli
+84
proto/session.mli
···
+14
proto/unknown.ml
+14
proto/unknown.ml
···
+23
proto/unknown.mli
+23
proto/unknown.mli
···
+10
test/proto/capability/valid/core.json
+10
test/proto/capability/valid/core.json
+6
test/proto/capability/valid/mail.json
+6
test/proto/capability/valid/mail.json
+7
test/proto/capability/valid/submission.json
+7
test/proto/capability/valid/submission.json
+1
test/proto/date/edge/microseconds.json
+1
test/proto/date/edge/microseconds.json
···
+1
test/proto/date/edge/negative_offset.json
+1
test/proto/date/edge/negative_offset.json
···
+1
test/proto/date/invalid/bad_format.json
+1
test/proto/date/invalid/bad_format.json
···
+1
test/proto/date/invalid/invalid_date.json
+1
test/proto/date/invalid/invalid_date.json
···
+1
test/proto/date/invalid/lowercase_t.json
+1
test/proto/date/invalid/lowercase_t.json
···
+1
test/proto/date/invalid/lowercase_z.json
+1
test/proto/date/invalid/lowercase_z.json
···
+1
test/proto/date/invalid/missing_seconds.json
+1
test/proto/date/invalid/missing_seconds.json
···
+1
test/proto/date/invalid/no_timezone.json
+1
test/proto/date/invalid/no_timezone.json
···
+1
test/proto/date/invalid/not_string.json
+1
test/proto/date/invalid/not_string.json
···
+1
test/proto/date/valid/negative_offset.json
+1
test/proto/date/valid/negative_offset.json
···
+1
test/proto/date/valid/utc_z.json
+1
test/proto/date/valid/utc_z.json
···
+1
test/proto/date/valid/with_milliseconds.json
+1
test/proto/date/valid/with_milliseconds.json
···
+1
test/proto/date/valid/with_offset.json
+1
test/proto/date/valid/with_offset.json
···
+17
test/proto/dune
+17
test/proto/dune
···
+4
test/proto/error/valid/method_error.json
+4
test/proto/error/valid/method_error.json
+4
test/proto/error/valid/method_error_account_not_found.json
+4
test/proto/error/valid/method_error_account_not_found.json
+4
test/proto/error/valid/method_error_account_read_only.json
+4
test/proto/error/valid/method_error_account_read_only.json
+4
test/proto/error/valid/method_error_forbidden.json
+4
test/proto/error/valid/method_error_forbidden.json
+4
test/proto/error/valid/method_error_invalid_arguments.json
+4
test/proto/error/valid/method_error_invalid_arguments.json
+4
test/proto/error/valid/method_error_server_fail.json
+4
test/proto/error/valid/method_error_server_fail.json
+5
test/proto/error/valid/request_error.json
+5
test/proto/error/valid/request_error.json
+6
test/proto/error/valid/request_error_limit.json
+6
test/proto/error/valid/request_error_limit.json
+5
test/proto/error/valid/request_error_not_json.json
+5
test/proto/error/valid/request_error_not_json.json
+5
test/proto/error/valid/set_error.json
+5
test/proto/error/valid/set_error.json
+4
test/proto/error/valid/set_error_forbidden.json
+4
test/proto/error/valid/set_error_forbidden.json
+5
test/proto/error/valid/set_error_invalid_properties.json
+5
test/proto/error/valid/set_error_invalid_properties.json
+4
test/proto/error/valid/set_error_not_found.json
+4
test/proto/error/valid/set_error_not_found.json
+4
test/proto/error/valid/set_error_over_quota.json
+4
test/proto/error/valid/set_error_over_quota.json
+4
test/proto/error/valid/set_error_singleton.json
+4
test/proto/error/valid/set_error_singleton.json
+4
test/proto/filter/edge/empty_conditions.json
+4
test/proto/filter/edge/empty_conditions.json
+7
test/proto/filter/valid/and_operator.json
+7
test/proto/filter/valid/and_operator.json
+4
test/proto/filter/valid/comparator_descending.json
+4
test/proto/filter/valid/comparator_descending.json
+5
test/proto/filter/valid/comparator_with_collation.json
+5
test/proto/filter/valid/comparator_with_collation.json
+18
test/proto/filter/valid/deeply_nested.json
+18
test/proto/filter/valid/deeply_nested.json
+19
test/proto/filter/valid/nested.json
+19
test/proto/filter/valid/nested.json
···
+13
test/proto/filter/valid/nested_and_or.json
+13
test/proto/filter/valid/nested_and_or.json
+6
test/proto/filter/valid/not_operator.json
+6
test/proto/filter/valid/not_operator.json
+7
test/proto/filter/valid/or_operator.json
+7
test/proto/filter/valid/or_operator.json
+1
test/proto/id/edge/creation_ref.json
+1
test/proto/id/edge/creation_ref.json
···
+1
test/proto/id/edge/digits_only.json
+1
test/proto/id/edge/digits_only.json
···
+1
test/proto/id/edge/max_length_255.json
+1
test/proto/id/edge/max_length_255.json
···+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+1
test/proto/id/edge/nil_literal.json
+1
test/proto/id/edge/nil_literal.json
···
+1
test/proto/id/edge/over_max_length_256.json
+1
test/proto/id/edge/over_max_length_256.json
···+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+1
test/proto/id/edge/starts_with_dash.json
+1
test/proto/id/edge/starts_with_dash.json
···
+1
test/proto/id/edge/starts_with_digit.json
+1
test/proto/id/edge/starts_with_digit.json
···
test/proto/id/invalid/empty.json
test/proto/id/invalid/empty.json
This is a binary file and will not be displayed.
+1
test/proto/id/invalid/not_string.json
+1
test/proto/id/invalid/not_string.json
···
+1
test/proto/id/invalid/null.json
+1
test/proto/id/invalid/null.json
···
+1
test/proto/id/invalid/with_slash.json
+1
test/proto/id/invalid/with_slash.json
···
+1
test/proto/id/invalid/with_space.json
+1
test/proto/id/invalid/with_space.json
···
+1
test/proto/id/invalid/with_special.json
+1
test/proto/id/invalid/with_special.json
···
+1
test/proto/id/valid/alphanumeric.json
+1
test/proto/id/valid/alphanumeric.json
···
+1
test/proto/id/valid/base64_like.json
+1
test/proto/id/valid/base64_like.json
···
+1
test/proto/id/valid/simple.json
+1
test/proto/id/valid/simple.json
···
+1
test/proto/id/valid/single_char.json
+1
test/proto/id/valid/single_char.json
···
+1
test/proto/id/valid/uuid_style.json
+1
test/proto/id/valid/uuid_style.json
···
+1
test/proto/id/valid/with_hyphen.json
+1
test/proto/id/valid/with_hyphen.json
···
+1
test/proto/id/valid/with_underscore.json
+1
test/proto/id/valid/with_underscore.json
···
+1
test/proto/int53/edge/over_max_safe.json
+1
test/proto/int53/edge/over_max_safe.json
···
+1
test/proto/int53/edge/under_min_safe.json
+1
test/proto/int53/edge/under_min_safe.json
···
+1
test/proto/int53/invalid/float.json
+1
test/proto/int53/invalid/float.json
···
+1
test/proto/int53/invalid/leading_zero.json
+1
test/proto/int53/invalid/leading_zero.json
···
+1
test/proto/int53/invalid/null.json
+1
test/proto/int53/invalid/null.json
···
+1
test/proto/int53/invalid/scientific.json
+1
test/proto/int53/invalid/scientific.json
···
+1
test/proto/int53/invalid/string.json
+1
test/proto/int53/invalid/string.json
···
+1
test/proto/int53/valid/max_safe.json
+1
test/proto/int53/valid/max_safe.json
···
+1
test/proto/int53/valid/min_safe.json
+1
test/proto/int53/valid/min_safe.json
···
+1
test/proto/int53/valid/negative.json
+1
test/proto/int53/valid/negative.json
···
+1
test/proto/int53/valid/positive.json
+1
test/proto/int53/valid/positive.json
···
+1
test/proto/int53/valid/zero.json
+1
test/proto/int53/valid/zero.json
···
+1
test/proto/invocation/invalid/not_array.json
+1
test/proto/invocation/invalid/not_array.json
···
+1
test/proto/invocation/invalid/wrong_length.json
+1
test/proto/invocation/invalid/wrong_length.json
···
+1
test/proto/invocation/valid/get.json
+1
test/proto/invocation/valid/get.json
···
+1
test/proto/invocation/valid/query.json
+1
test/proto/invocation/valid/query.json
···+["Email/query", {"accountId": "acc1", "filter": {"inMailbox": "inbox"}, "sort": [{"property": "receivedAt", "isAscending": false}], "limit": 50}, "call-003"]
+1
test/proto/invocation/valid/set.json
+1
test/proto/invocation/valid/set.json
···
+11
test/proto/mail/email/edge/empty_keywords.json
+11
test/proto/mail/email/edge/empty_keywords.json
+14
test/proto/mail/email/valid/draft_email.json
+14
test/proto/mail/email/valid/draft_email.json
···
+30
test/proto/mail/email/valid/full.json
+30
test/proto/mail/email/valid/full.json
···+"1": {"value": "Thanks for the update.\n\nI'll review the documents.", "isEncodingProblem": false, "isTruncated": false}+{"partId": "2", "blobId": "attach1", "type": "application/pdf", "name": "document.pdf", "size": 12345}
+9
test/proto/mail/email/valid/minimal.json
+9
test/proto/mail/email/valid/minimal.json
+15
test/proto/mail/email/valid/multiple_mailboxes.json
+15
test/proto/mail/email/valid/multiple_mailboxes.json
···
+18
test/proto/mail/email/valid/with_all_system_keywords.json
+18
test/proto/mail/email/valid/with_all_system_keywords.json
···
+16
test/proto/mail/email/valid/with_headers.json
+16
test/proto/mail/email/valid/with_headers.json
···
+15
test/proto/mail/email/valid/with_keywords.json
+15
test/proto/mail/email/valid/with_keywords.json
···
+15
test/proto/mail/email/valid/with_message_ids.json
+15
test/proto/mail/email/valid/with_message_ids.json
···
+3
test/proto/mail/email_address/valid/email_only.json
+3
test/proto/mail/email_address/valid/email_only.json
+4
test/proto/mail/email_address/valid/full.json
+4
test/proto/mail/email_address/valid/full.json
+28
test/proto/mail/email_body/edge/deep_nesting.json
+28
test/proto/mail/email_body/edge/deep_nesting.json
···
+21
test/proto/mail/email_body/valid/multipart.json
+21
test/proto/mail/email_body/valid/multipart.json
···
+36
test/proto/mail/email_body/valid/multipart_mixed.json
+36
test/proto/mail/email_body/valid/multipart_mixed.json
···
+9
test/proto/mail/email_body/valid/text_part.json
+9
test/proto/mail/email_body/valid/text_part.json
+23
test/proto/mail/email_body/valid/with_inline_image.json
+23
test/proto/mail/email_body/valid/with_inline_image.json
···
+9
test/proto/mail/email_body/valid/with_language.json
+9
test/proto/mail/email_body/valid/with_language.json
+9
test/proto/mail/identity/valid/simple.json
+9
test/proto/mail/identity/valid/simple.json
···
+21
test/proto/mail/mailbox/edge/all_rights_false.json
+21
test/proto/mail/mailbox/edge/all_rights_false.json
···
+12
test/proto/mail/mailbox/valid/all_roles.json
+12
test/proto/mail/mailbox/valid/all_roles.json
···
+22
test/proto/mail/mailbox/valid/nested.json
+22
test/proto/mail/mailbox/valid/nested.json
···
+22
test/proto/mail/mailbox/valid/simple.json
+22
test/proto/mail/mailbox/valid/simple.json
···
+22
test/proto/mail/mailbox/valid/with_all_roles.json
+22
test/proto/mail/mailbox/valid/with_all_roles.json
···
+21
test/proto/mail/submission/valid/final_status.json
+21
test/proto/mail/submission/valid/final_status.json
···
+14
test/proto/mail/submission/valid/simple.json
+14
test/proto/mail/submission/valid/simple.json
···
+20
test/proto/mail/submission/valid/with_envelope.json
+20
test/proto/mail/submission/valid/with_envelope.json
···
+4
test/proto/mail/thread/valid/conversation.json
+4
test/proto/mail/thread/valid/conversation.json
+4
test/proto/mail/vacation/valid/disabled.json
+4
test/proto/mail/vacation/valid/disabled.json
+9
test/proto/mail/vacation/valid/enabled.json
+9
test/proto/mail/vacation/valid/enabled.json
···
+9
test/proto/method/valid/changes_response.json
+9
test/proto/method/valid/changes_response.json
+5
test/proto/method/valid/get_args.json
+5
test/proto/method/valid/get_args.json
+16
test/proto/method/valid/query_args.json
+16
test/proto/method/valid/query_args.json
···
+8
test/proto/method/valid/query_response.json
+8
test/proto/method/valid/query_response.json
+12
test/proto/method/valid/set_args.json
+12
test/proto/method/valid/set_args.json
+16
test/proto/method/valid/set_response.json
+16
test/proto/method/valid/set_response.json
···
+19
test/proto/method/valid/set_response_with_errors.json
+19
test/proto/method/valid/set_response_with_errors.json
···
+5
test/proto/request/invalid/missing_using.json
+5
test/proto/request/invalid/missing_using.json
+1
test/proto/request/invalid/not_object.json
+1
test/proto/request/invalid/not_object.json
···
+4
test/proto/request/valid/empty_methods.json
+4
test/proto/request/valid/empty_methods.json
+8
test/proto/request/valid/multiple_methods.json
+8
test/proto/request/valid/multiple_methods.json
···+["Email/get", {"accountId": "acc1", "#ids": {"resultOf": "c2", "name": "Email/query", "path": "/ids"}}, "c3"]
+6
test/proto/request/valid/single_method.json
+6
test/proto/request/valid/single_method.json
+9
test/proto/request/valid/with_created_ids.json
+9
test/proto/request/valid/with_created_ids.json
+20
test/proto/request/valid/with_creation_refs.json
+20
test/proto/request/valid/with_creation_refs.json
···
+7
test/proto/request/valid/with_result_reference.json
+7
test/proto/request/valid/with_result_reference.json
···+["Mailbox/get", {"accountId": "acc1", "#ids": {"resultOf": "0", "name": "Mailbox/query", "path": "/ids"}}, "1"]
+5
test/proto/response/invalid/missing_session_state.json
+5
test/proto/response/invalid/missing_session_state.json
+7
test/proto/response/valid/multiple_responses.json
+7
test/proto/response/valid/multiple_responses.json
···+["Email/query", {"accountId": "acc1", "queryState": "q1", "canCalculateChanges": true, "position": 0, "ids": ["e1", "e2", "e3"], "total": 100}, "c1"],+["Email/get", {"accountId": "acc1", "state": "s1", "list": [{"id": "e1", "blobId": "b1", "threadId": "t1", "mailboxIds": {"inbox": true}, "keywords": {"$seen": true}, "size": 1234, "receivedAt": "2024-01-15T10:30:00Z"}], "notFound": []}, "c2"]
+6
test/proto/response/valid/success.json
+6
test/proto/response/valid/success.json
+9
test/proto/response/valid/with_created_ids.json
+9
test/proto/response/valid/with_created_ids.json
+6
test/proto/response/valid/with_error.json
+6
test/proto/response/valid/with_error.json
+22
test/proto/session/edge/empty_accounts.json
+22
test/proto/session/edge/empty_accounts.json
···
+10
test/proto/session/invalid/missing_api_url.json
+10
test/proto/session/invalid/missing_api_url.json
···
+17
test/proto/session/invalid/missing_capabilities.json
+17
test/proto/session/invalid/missing_capabilities.json
···
+31
test/proto/session/valid/minimal.json
+31
test/proto/session/valid/minimal.json
···+"downloadUrl": "https://api.example.com/jmap/download/{accountId}/{blobId}/{name}?type={type}",
+44
test/proto/session/valid/with_accounts.json
+44
test/proto/session/valid/with_accounts.json
···+"eventSourceUrl": "https://api.example.com/eventsource/?types={types}&closeafter={closeafter}&ping={ping}",
+56
test/proto/session/valid/with_mail.json
+56
test/proto/session/valid/with_mail.json
···+"eventSourceUrl": "https://jmap.example.com/events/?types={types}&closeafter={closeafter}&ping={ping}",
+987
test/proto/test_proto.ml
+987
test/proto/test_proto.ml
···+Alcotest.(check int) "primary_accounts count" 2 (List.length (Session.primary_accounts session))+test_decode_success "with created ids" Response.jsont "response/valid/with_created_ids.json" ()+test_decode_success "multiple responses" Response.jsont "response/valid/multiple_responses.json" ()+Alcotest.(check int) "method responses count" 1 (List.length (Response.method_responses response))+test_decode_success "submission" Capability.Submission.jsont "capability/valid/submission.json" ()+Alcotest.(check bool) "mayCreateTopLevelMailbox" true (Capability.Mail.may_create_top_level_mailbox cap)+test_decode_success "get_args_minimal" Method.get_args_jsont "method/valid/get_args_minimal.json" ()+test_decode_success "query_response" Method.query_response_jsont "method/valid/query_response.json" ()+test_decode_success "changes_response" Method.changes_response_jsont "method/valid/changes_response.json" ()+Alcotest.(check (option (list string))) "properties" (Some ["id"; "name"; "role"]) args.properties+test_decode_success "method_error" Error.method_error_jsont "error/valid/method_error.json" ()+test_decode_success "request_error" Error.Request_error.jsont "error/valid/request_error.json" ()+test_decode_success "set_error_forbidden" Error.set_error_jsont "error/valid/set_error_forbidden.json" ()+test_decode_success "set_error_not_found" Error.set_error_jsont "error/valid/set_error_not_found.json" ()+test_decode_success "set_error_invalid_properties" Error.set_error_jsont "error/valid/set_error_invalid_properties.json" ()+test_decode_success "set_error_singleton" Error.set_error_jsont "error/valid/set_error_singleton.json" ()+test_decode_success "set_error_over_quota" Error.set_error_jsont "error/valid/set_error_over_quota.json" ()+test_decode_success "method_error_invalid_arguments" Error.method_error_jsont "error/valid/method_error_invalid_arguments.json" ()+test_decode_success "method_error_server_fail" Error.method_error_jsont "error/valid/method_error_server_fail.json" ()+test_decode_success "method_error_account_not_found" Error.method_error_jsont "error/valid/method_error_account_not_found.json" ()+test_decode_success "method_error_forbidden" Error.method_error_jsont "error/valid/method_error_forbidden.json" ()+test_decode_success "method_error_account_read_only" Error.method_error_jsont "error/valid/method_error_account_read_only.json" ()+test_decode_success "request_error_not_json" Error.Request_error.jsont "error/valid/request_error_not_json.json" ()+test_decode_success "request_error_limit" Error.Request_error.jsont "error/valid/request_error_limit.json" ()+test_decode_success "with all roles" Mailbox.jsont "mail/mailbox/valid/with_all_roles.json" ()+test_decode_success "all rights false" Mailbox.jsont "mail/mailbox/edge/all_rights_false.json" ()+Alcotest.(check (option string)) "subject" (Some "Re: Important meeting") (Email.subject email);+test_decode_success "multiple mailboxes" Email.jsont "mail/email/valid/multiple_mailboxes.json" ()+test_decode_success "all system keywords" Email.jsont "mail/email/valid/with_all_system_keywords.json" ()+test_decode_success "with message ids" Email.jsont "mail/email/valid/with_message_ids.json" ()+test_decode_success "email_only" Email_address.jsont "mail/email_address/valid/email_only.json" ()+test_decode_success "minimal" Filter.comparator_jsont "filter/valid/comparator_minimal.json" ()+test_decode_success "descending" Filter.comparator_jsont "filter/valid/comparator_descending.json" ()+test_decode_success "with collation" Filter.comparator_jsont "filter/valid/comparator_with_collation.json" ()+Alcotest.(check (option string)) "collation" (Some "i;unicode-casemap") (Filter.comparator_collation comp)+test_decode_success "text part" Email_body.Part.jsont "mail/email_body/valid/text_part.json" ()+test_decode_success "multipart" Email_body.Part.jsont "mail/email_body/valid/multipart.json" ()+test_decode_success "multipart mixed" Email_body.Part.jsont "mail/email_body/valid/multipart_mixed.json" ()+test_decode_success "with inline image" Email_body.Part.jsont "mail/email_body/valid/with_inline_image.json" ()+test_decode_success "with language" Email_body.Part.jsont "mail/email_body/valid/with_language.json" ()+test_decode_success "deep nesting" Email_body.Part.jsont "mail/email_body/edge/deep_nesting.json" ()+test_decode_success "with envelope" Submission.jsont "mail/submission/valid/with_envelope.json" ()+test_decode_success "final status" Submission.jsont "mail/submission/valid/final_status.json" ()