+1
.ocamlformat
+1
.ocamlformat
···
+99
CLAUDE.md
+99
CLAUDE.md
···+I wish to generate a set of OCaml module signatures and types (no implementations) that will type check, for an implementation of the JMAP protocol (RFC8620) and the associated email extensions (RFC8621). The code you generate should have ocamldoc that references the relevant sections of the RFC it is implementing, using <https://www.rfc-editor.org/rfc/rfc8620.html#section-1.2> as a template for the hyperlinks (replace the fragment with the appropriate section identifier). There are local copy of the specifications in the `spec/` directory in this repository. The `spec/rfc8620.txt` is the core JMAP protocol, which we are aiming to implement in OCaml code in this project. We must accurately capture the specification in the OCaml interface and never violate it without clear indication.+The architecture of the modules should be one portable set that implement core JMAP (RFC8620) as an OCaml module called `Jmap` (with module aliases to the submodules that implement that). Then generate another set of modules that implement the email-specific extensions (RFC8621) including flag handling for (e.g.) Apple Mail under a module called `Jmap_email`. These should all be portable OCaml type signatures (the mli files), and then generate another module that implements the interface for a Unix implementation that uses the Unix module to perform real connections. You do not need to implement TLS support for this first iteration of the code interfaces.+You should also generate a module index file called jmap.mli that explains how all the generated modules fit together, along with a sketch of some example OCaml code that uses it to connect to a JMAP server and list recent unread emails from a particular sender.+When selecting dependencies, ONLY use Yojson, Uri and Unix in your type signatures aside from the OCaml standard library. The standard Hashtbl is fine for any k/v datastructures and do not use Maps or other functor applications for this. DO NOT generate any AST attributes, and do not use any PPX derivers or other syntax extensions. Just generate clean, conventional OCaml type signatures. DO NOT generate any references to Lwt or Async, and only use the Unix module to access basic network and storage functions if the standard library does not suffice.+- build while ignoring warnings: add `--profile=release` to the CLI to activate the profile that ignores warnings+Then examine the HTML docs built for that module. You will see that there are module references with __ in them, e.g. "Jmap__.Jmap_email_types.Email_address.t" which indicate that the module is being accessed directly instead of via the module aliases defined.+When adding OCaml documentation comments, be careful about ambiguous documentation comments. If you see errors like:+This usually means there isn't enough whitespace between the documentation comment and the code element it's documenting. Always:+3. When documenting record fields or variant constructors, place the comment after the field with at least one space+If in doubt, add more whitespace lines than needed - you can always clean this up later with `dune build @fmt` to get ocamlformat to sort out the whitespace properly.+IMPORTANT: For all modules, use a nested module structure with a canonical `type t` inside each submodule. This approach ensures consistent type naming and logical grouping of related functionality.+1. Top-level files should define their main types directly (e.g., `jmap_identity.mli` should define identity-related types at the top level).+2. Related operations or specialized subtypes should be defined in nested modules within the file:+5. When a file is named after a concept (e.g., `jmap_identity.mli`), there's no need to have a matching nested module inside the file (e.g., `module Identity : sig...`), as the file itself represents that namespace.+This structured approach promotes encapsulation, consistent type naming, and clearer organization of related functionality.+1) we will generate OCaml interface files only, and no module implementations. The purpose here is to write and document the necessary type signatures. Once we generate these, we can check that they work with "dune build @check". Once that succeeds, we will build HTML documentation with "dune build @doc" in order to ensure the interfaces are reasonable.+2) once these interface files exist, we will build a series of sample binaries that will attempt to implement the JMAP protocol for some sample usecases, using only the Unix module. This binary will not fully link, but it should type check. The only linking error that we get should be from the missing Jmap library implementation.+3) we will calculate the dependency order for each module in the Jmap library, and work through an implementation of each one in increasing dependency order (that is, the module with the fewest dependencies should be handled first). For each module interface, we will generate a corresponding module implementation. We will also add test cases for this specific module, and update the dune files. Before proceeding to the next module, a `dune build` should be done to ensure the implementation builds and type checks as far as is possible.
+72
README.md
+72
README.md
···+This project implements OCaml libraries for the JMAP protocol, following the specifications in RFC 8620 (Core) and RFC 8621 (Mail).+let (ctx, session) = Jmap_unix.quick_connect ~host:"jmap.example.com" ~username:"user" ~password:"pass" in+- [RFC 8620: The JSON Meta Application Protocol (JMAP)](https://www.rfc-editor.org/rfc/rfc8620.html)+- [RFC 8621: The JSON Meta Application Protocol (JMAP) for Mail](https://www.rfc-editor.org/rfc/rfc8621.html)
+61
-4
bin/dune
+61
-4
bin/dune
···
-298
bin/fastmail_list.ml
-298
bin/fastmail_list.ml
···-(** Example function demonstrating how to use higher-level library functions for JMAP requests *)-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
-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.
-114
bin/flag_color_test.ml
-114
bin/flag_color_test.ml
···
+245
bin/jmap_blob_downloader.ml
+245
bin/jmap_blob_downloader.ml
···+`P " $(mname) -h jmap.example.com -u user@example.com -p secret123 -e email123 -o downloads/";
+429
bin/jmap_email_composer.ml
+429
bin/jmap_email_composer.ml
···+Printf.printf " Simulating upload of %s (%s, %d bytes)...\n" filename mime_type (String.length content);+Printf.eprintf "Error: Must provide email body (--body, --body-file, --html, or --html-file)\n";
+436
bin/jmap_email_search.ml
+436
bin/jmap_email_search.ml
···+(* Create a filter based on command-line arguments - this function uses the actual JMAP API *)+let filters = if args.has_attachment then Jmap_email.Email_filter.has_attachment () :: filters else filters in+let filters = if args.is_unread then Jmap_email.Email_filter.unread () :: filters else filters in+let thread_id = Option.value (Jmap_email.Types.Email.thread_id email) ~default:"(no thread)" in+`P " $(mname) -h jmap.example.com -u user@example.com -p secret123 --from boss@company.com --after 2023-01-01";
+706
bin/jmap_flag_manager.ml
+706
bin/jmap_flag_manager.ml
···+let before date = Filter.condition (`Assoc [("receivedAt", `Assoc [("before", `Float date)])])+let has_keyword kw = Filter.condition (`Assoc [("hasKeyword", `String (string_of_keyword kw))])+let not_has_keyword kw = Filter.condition (`Assoc [("notHasKeyword", `String (string_of_keyword kw))])+| `Gray -> [Types.Keywords.MailFlagBit0; Types.Keywords.MailFlagBit1; Types.Keywords.MailFlagBit2]+`P " $(mname) -h jmap.example.com -u user@example.com -p secret123 --add flagged --from boss@example.com";+`P " $(mname) -h jmap.example.com -u user@example.com -p secret123 --color red --mailbox Inbox --has-flag seen --missing-flag flagged";
+620
bin/jmap_identity_monitor.ml
+620
bin/jmap_identity_monitor.ml
···+let send_at = String.sub (ISO8601.string_of_datetime (Unix.gmtime submission.send_at)) 0 19 in+let send_at = String.sub (ISO8601.string_of_datetime (Unix.gmtime submission.send_at)) 0 19 in+let send_at_str = String.sub (ISO8601.string_of_datetime (Unix.gmtime submission.send_at)) 0 19 in+Printf.printf "sub1: [Final] Sent at 2023-01-15 10:30:45 (Email ID: email1, Recipients: 3)\n";+Printf.printf "sub2: [Final] Sent at 2023-01-14 08:15:22 (Email ID: email2, Recipients: 1)\n";+Printf.printf "sub3: [Pending] Sent at 2023-01-13 16:45:10 (Email ID: email3, Recipients: 5)\n"+Printf.printf "Tracking delivery status for submission: %s\n\n" (Option.get track_submission);+`P " $(mname) -h jmap.example.com -u user@example.com -p secret123 --create-identity backup@example.com --name \"Backup Account\"";+`P " $(mname) -h jmap.example.com -u user@example.com -p secret123 --list-submissions --days 3";+`P " $(mname) -h jmap.example.com -u user@example.com -p secret123 --track sub12345 --format status-only";
+420
bin/jmap_mailbox_explorer.ml
+420
bin/jmap_mailbox_explorer.ml
···+`P " $(mname) -h jmap.example.com -u user@example.com -p secret123 --create \"Work/Project X\" --parent Work";
+238
bin/jmap_push_listener.ml
+238
bin/jmap_push_listener.ml
···
-141
bin/jmap_test.ml
-141
bin/jmap_test.ml
···
+533
bin/jmap_thread_analyzer.ml
+533
bin/jmap_thread_analyzer.ml
···+let last_date = Option.value (Types.Email.received_at (List.hd (List.rev sorted_emails))) ~default:0.0 in+let position = int_of_float (float_of_int timeline_width *. (date -. first_date) /. total_duration) in+Printf.printf "%s [%s] %s: %s\n" date_str marker from (get_snippet (Option.value (Types.Email.id email) ~default:""))+`P " $(mname) -h jmap.example.com -u user@example.com -p secret123 --search \"project update\" --format timeline";
+406
bin/jmap_vacation_manager.ml
+406
bin/jmap_vacation_manager.ml
···+(if Jmap_email.Vacation.Vacation_response.is_enabled vacation then "ENABLED" else "DISABLED");+~using:[Jmap.capability_core; Jmap_email.capability_mail; Jmap_email.capability_vacationresponse]+~using:[Jmap.capability_core; Jmap_email.capability_mail; Jmap_email.capability_vacationresponse]
-164
bin/tutorial_examples.ml
-164
bin/tutorial_examples.ml
···
+1
-37
dune-project
+1
-37
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
···
+15
jmap/dune
+15
jmap/dune
···
+136
jmap/jmap.mli
+136
jmap/jmap.mli
···+val get_primary_account : Jmap_session.Session.t -> string -> (Jmap_types.id, Error.error) result
+60
jmap/jmap_binary.mli
+60
jmap/jmap_binary.mli
···
+189
jmap/jmap_error.mli
+189
jmap/jmap_error.mli
···+| SetItem of id * set_error_type * string option (** Error for a specific item in a /set operation *)
+417
jmap/jmap_methods.mli
+417
jmap/jmap_methods.mli
···
+230
jmap/jmap_push.mli
+230
jmap/jmap_push.mli
···
+98
jmap/jmap_session.mli
+98
jmap/jmap_session.mli
···
+38
jmap/jmap_types.mli
+38
jmap/jmap_types.mli
···
+80
jmap/jmap_wire.mli
+80
jmap/jmap_wire.mli
···
-35
jmap-eio.opam
-35
jmap-eio.opam
···
+15
jmap-email/dune
+15
jmap-email/dune
···
+503
jmap-email/jmap_email.mli
+503
jmap-email/jmap_email.mli
···+~arguments:(* Yojson conversion of get_args, with ids replaced by a ResultReference to q1 needed here *)+val color_flags : [`Red | `Orange | `Yellow | `Green | `Blue | `Purple | `Gray] -> string list+val set_color_flags : Types.Email.t -> red:bool -> orange:bool -> yellow:bool -> Types.Email.t
+519
jmap-email/jmap_email_types.mli
+519
jmap-email/jmap_email_types.mli
···+@see <https://www.rfc-editor.org/rfc/rfc8621.html#section-4.1.2.4> RFC 8621, Section 4.1.2.4 *)+(* Apple Mail and other vendor extension keywords from draft-ietf-mailmaint-messageflag-mailboxattribute *)
+114
jmap-email/jmap_identity.mli
+114
jmap-email/jmap_identity.mli
···
+187
jmap-email/jmap_mailbox.mli
+187
jmap-email/jmap_mailbox.mli
···+| Snoozed (** Messages snoozed for later notification/reappearance, from draft-ietf-mailmaint-messageflag-mailboxattribute *)+| Scheduled (** Messages scheduled for sending at a later time, from draft-ietf-mailmaint-messageflag-mailboxattribute *)+| Memos (** Messages containing memos or notes, from draft-ietf-mailmaint-messageflag-mailboxattribute *)
+89
jmap-email/jmap_search_snippet.mli
+89
jmap-email/jmap_search_snippet.mli
···
+136
jmap-email/jmap_submission.mli
+136
jmap-email/jmap_submission.mli
···+type email_submission_updated_info = email_submission (* Contains only changed server-set props *)+(** EmailSubmission/queryChanges: Response type (specialized from [Query_changes_response.t]). *)
+131
jmap-email/jmap_thread.mli
+131
jmap-email/jmap_thread.mli
···
+102
jmap-email/jmap_vacation.mli
+102
jmap-email/jmap_vacation.mli
···
+35
jmap-email.opam
+35
jmap-email.opam
···
+62
jmap-unix/README.md
+62
jmap-unix/README.md
···
+6
jmap-unix/dune
+6
jmap-unix/dune
+359
jmap-unix/jmap_unix.mli
+359
jmap-unix/jmap_unix.mli
···+([`State of Jmap.Push.State_change.t | `Ping of Jmap.Push.Event_source_ping_data.t ] Seq.t)) Jmap.Error.result
+21
jmap-unix.opam
+21
jmap-unix.opam
···
-33
jmap.opam
-33
jmap.opam
···-"A complete implementation of the JSON Meta Application Protocol (JMAP) as specified in RFC 8620 (core) and RFC 8621 (mail)."
-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" ()